]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/z80-if.c
Programmable Z180 clock, clock command
[z180-stamp.git] / avr / z80-if.c
index 20efa9ebcd1ae798137255f2573149ab12c8c920..c0f128e1a4870005d543becf1adf5a47b1c8776b 100644 (file)
@@ -157,8 +157,87 @@ static zstate_t zstate;
 
 /*--------------------------------------------------------------------------*/
 
+static
+void z80_setup_clock(void)
+{
+       /* ZCLK: Output and low */
+       DDR_ZCLK |= _BV(ZCLK);
+       Z80_O_ZCLK = 0;
+
+       DDRB  |= _BV(6);        /* Debug */
+       PORTB |= _BV(6);        /* Debug */
+
+       PRR0 &= ~_BV(PRTIM1);
+
+       /* Timer1: CTC: Toggle OC1C on compare match */
+       OCR1A =  0;
+       OCR1C =  0;
+       TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+       TCCR1B = (0b01 << WGM12)  | (0b001 << CS10);
+}
+
+
+int z80_clock_set(unsigned long freq)
+{
+       unsigned long ocrval = F_CPU  / freq / 2;
+       uint8_t prescale = 0;
+
+       while (ocrval > (1L<<16)) {
+               prescale++;
+               if (prescale < 3)
+                       ocrval = ocrval / 8;
+               else
+                       ocrval = ocrval /  4;
+       }
+
+       if ((ocrval == 0) || (prescale > 4))
+               return -1;
+
+       ocrval -= 1;
+
+       PINB |= _BV(6);         /* Debug */
+
+       /* Stop Timer */
+       TCCR1B = (0b01 << WGM12)  | (0b000 << CS10);
+       TCNT1 = 0;
+
+       OCR1A =  ocrval;
+       OCR1CL =  ocrval;
+       TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+       TCCR1B = (0b01 << WGM12)  | ((prescale+1) << CS10);
+
+       if (ocrval == 0) {
+//             TCCR1C |= _BV(FOC1C);
+               ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+                       TCNT1 = 0xFFFF;
+               }
+       }
+
+       PINB |= _BV(6);         /* Debug */
+
+       return 0;
+}
 
-static void z80_setup_addrbus_tristate(void)
+uint32_t z80_clock_get(void)
+{
+       uint32_t count = (OCR1A + 1L) * 2;
+       uint8_t pre = (TCCR1B & 7) - 1;
+
+       while (pre) {
+               if (pre > 2)
+                       count *= 4;
+               else
+                       count *= 8;
+               pre--;
+
+       }
+
+       return F_CPU/count;
+}
+
+
+
+static void z80_addrbus_set_tristate(void)
 {
        /* /MREQ, /RD, /WR: Input, no pullup */
        DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
@@ -175,7 +254,7 @@ static void z80_setup_addrbus_tristate(void)
 }
 
 
-static void z80_setup_addrbus_active(void)
+static void z80_addrbus_set_active(void)
 {
        /* /MREQ, /RD, /WR: Output and high */
        Z80_O_MREQ = 1;
@@ -189,14 +268,14 @@ static void z80_setup_addrbus_active(void)
 }
 
 
-static void z80_setup_dbus_in(void)
+static void z80_dbus_set_in(void)
 {
        DDR_DB = 0;
        P_DB = 0;
 }
 
 
-static void z80_setup_dbus_out(void)
+static void z80_dbus_set_out(void)
 {
        DDR_DB = 0xff;
 }
@@ -209,19 +288,6 @@ static void z80_reset_pulse(void)
        Z80_O_RST = 1;
 }
 
-static
-void z80_setup_clock(void)
-{
-       /* ZCLK: Output and low */
-       DDR_ZCLK |= _BV(ZCLK);
-       Z80_O_ZCLK = 0;
-
-       /* Timer0: CTC: Toggle OC0A on compare match */
-       PRR0 &= ~_BV(PRTIM0);
-       TCCR0A = _BV(COM0A0) | _BV(WGM01);
-       OCR0A =  0;
-       TCCR0B = (0x01 << CS00);
-}
 
 void z80_setup_bus(void)
 {
@@ -243,8 +309,8 @@ void z80_setup_bus(void)
        DDR_IOCS1 &= ~_BV(IOCS1);
        P_IOCS1 &= ~_BV(IOCS1);
 
-       z80_setup_addrbus_tristate();
-       z80_setup_dbus_in();
+       z80_addrbus_set_tristate();
+       z80_dbus_set_in();
 
        zstate = RESET;
 }
@@ -258,8 +324,8 @@ zstate_t z80_bus_state(void)
 
 static void z80_busreq_hpulse(void)
 {
-       z80_setup_dbus_in();
-       z80_setup_addrbus_tristate();
+       z80_dbus_set_in();
+       z80_addrbus_set_tristate();
 
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
                Z80_O_BUSREQ = 1;
@@ -270,7 +336,7 @@ static void z80_busreq_hpulse(void)
        if (zstate & ZST_ACQUIRED) {
                while(Z80_I_BUSACK == 1)
                        ;
-               z80_setup_addrbus_active();
+               z80_addrbus_set_active();
        }
 }
 
@@ -309,8 +375,8 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
        switch (cmd) {
 
        case Reset:
-               z80_setup_dbus_in();
-               z80_setup_addrbus_tristate();
+               z80_dbus_set_in();
+               z80_addrbus_set_tristate();
                Z80_O_RST = 0;
                Z80_O_BUSREQ = 1;
                zstate = RESET;
@@ -323,7 +389,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
                        Z80_O_RST = 1;
                        while(Z80_I_BUSACK == 1)
                                ;
-                       z80_setup_addrbus_active();
+                       z80_addrbus_set_active();
                        zstate = RESET_AQRD;
                        break;
 
@@ -331,7 +397,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
                        Z80_O_BUSREQ = 0;
                        while(Z80_I_BUSACK == 1)
                                ;
-                       z80_setup_addrbus_active();
+                       z80_addrbus_set_active();
                        zstate = RUNNING_AQRD;
                        break;
 
@@ -343,15 +409,15 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
        case Release:
                switch (zstate) {
                case RESET_AQRD:
-                       z80_setup_dbus_in();
-                       z80_setup_addrbus_tristate();
+                       z80_dbus_set_in();
+                       z80_addrbus_set_tristate();
                        Z80_O_RST = 0;
                        Z80_O_BUSREQ = 1;
                        zstate = RESET;
                        break;
                case RUNNING_AQRD:
-                       z80_setup_dbus_in();
-                       z80_setup_addrbus_tristate();
+                       z80_dbus_set_in();
+                       z80_addrbus_set_tristate();
                        Z80_O_BUSREQ = 1;
                        zstate = RUNNING;
                        break;
@@ -368,10 +434,10 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
                        break;
 
                case RESET_AQRD:
-                       z80_setup_dbus_in();
-                       z80_setup_addrbus_tristate();
+                       z80_dbus_set_in();
+                       z80_addrbus_set_tristate();
                        z80_reset_pulse();
-                       z80_setup_addrbus_active();
+                       z80_addrbus_set_active();
                        zstate = RUNNING_AQRD;
                        break;
                default:
@@ -420,7 +486,7 @@ void z80_write(uint32_t addr, uint8_t data)
 {
        z80_setaddress(addr);
        Z80_O_MREQ = 0;
-       z80_setup_dbus_out();
+       z80_dbus_set_out();
        P_DB = data;
        P_DB = data;
        Z80_O_WR = 0;
@@ -435,7 +501,7 @@ uint8_t z80_read(uint32_t addr)
 
        z80_setaddress(addr);
        Z80_O_MREQ = 0;
-       z80_setup_dbus_in();
+       z80_dbus_set_in();
        Z80_O_RD = 0;
        Z80_O_RD = 0;
        Z80_O_RD = 0;
@@ -449,7 +515,7 @@ uint8_t z80_read(uint32_t addr)
 
 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
 {
-       z80_setup_dbus_out();
+       z80_dbus_set_out();
        Z80_O_MREQ = 0;
        while(length--) {
                z80_setaddress(addr++);
@@ -466,7 +532,7 @@ void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
 {
        uint8_t data;
 
-       z80_setup_dbus_out();
+       z80_dbus_set_out();
        Z80_O_MREQ = 0;
        while(length--) {
                z80_setaddress(dest++);