avr: initial commit
[z80.git] / avr / bus.c
diff --git a/avr/bus.c b/avr/bus.c
new file mode 100644 (file)
index 0000000..06d8557
--- /dev/null
+++ b/avr/bus.c
@@ -0,0 +1,68 @@
+/* BUS arbitration */
+
+#include <avr/io.h>
+#include <util/delay.h>
+
+#include "bus.h"
+
+/* initialize bus arbitration pins */
+void bus_init(void)
+{
+       /* /INT, /RESET, /BUSREQ, /WAIT, CLOCK as HIGH outputs */
+       BUSDDR  |= (1 << INT) | (1 << RESET) | (1 << BUSREQ) | (1 << WAIT) | (1 << CLOCK);
+       BUSPORT |= (1 << INT) | (1 << RESET) | (1 << BUSREQ) | (1 << WAIT) | (1 << CLOCK);
+
+       /* /BUSACK as input with pullups */
+       BUSDDR  &= ~(1 << BUSACK);
+       BUSPORT |=  (1 << BUSACK);
+
+       /* initialize clock on OC0B */
+       TCNT0  = 0;
+//     OCR0A  = 2;
+       OCR0A  = 15;
+//     OCR0A  = 254;
+       TCCR0A = (1 << COM0B0) | (1 << WGM01);
+       TCCR0B = (1 << CS00);
+
+       /* reset Z80, get bus, wait until we got it */
+       BUSPORT &= ~((1 << RESET) | (1 << BUSREQ));
+       _delay_ms(50);
+       BUSPORT |= (1 << RESET);
+       while(BUSPIN & (1 << BUSACK));
+}
+
+/* acquire memory bus from Z80, blocking */
+/* NOTE: disables DRAM refresh! */
+void bus_lock(void)
+{
+       BUSPORT &= ~(1 << BUSREQ);      /* request bus */
+       while(BUSPIN & (1 << BUSACK));  /* wait until acquired */
+}
+
+/* return memory bus to Z80, blocking */
+void bus_unlock(void)
+{
+       BUSPORT |= (1 << BUSREQ);       /* release bus */
+       while(!(BUSPIN & (1 << BUSACK))); /* wait until released */
+}
+
+/* activate autowait: /WAIT activates on /SEL0 */
+void bus_wait(void)
+{
+       BUSPORT |= (1 << WAIT);
+       return;
+}
+
+/* release autowait: /WAIT gets released immediately */
+void bus_nowait(void)
+{
+       BUSPORT &= ~(1 << WAIT);
+}
+
+/* reset Z80 and devices */
+void bus_reset(void)
+{
+       BUSPORT &= ~(1 << RESET);
+       _delay_ms(50);
+       BUSPORT |= (1 << RESET);
+}