]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
Programmable Z180 clock, clock command hexrel-2
authorLeo C <erbl259-lmu@yahoo.de>
Mon, 8 Sep 2014 17:54:08 +0000 (19:54 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Mon, 8 Sep 2014 17:54:08 +0000 (19:54 +0200)
avr/cmd_boot.c
avr/cmd_mem.c
avr/command_tbl.c
avr/z80-if.c
include/z80-if.h

index 3e2dcdb103281709a383072138f7329ba75a9821..58c4f569e276199ed0a1dc7240f61d654972c0f2 100644 (file)
@@ -44,13 +44,13 @@ command_ret_t do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 {
        (void) cmdtp; (void) flag; (void) argc; (void) argv;
 
-       if (z80_bus_state() & ZST_RUNNING) {    
+       if (z80_bus_state() & ZST_RUNNING) {
                printf_P(PSTR("## Can't load while CPU is running!\n"));
-               return CMD_RET_FAILURE; 
+               return CMD_RET_FAILURE;
        }
 
        z80_load_mem();
-       
+
        return CMD_RET_SUCCESS;
 }
 
@@ -61,7 +61,7 @@ command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const
 
        (void) cmdtp; (void) flag;
 
-       if (!(z80_bus_state() & ZST_RUNNING)) { 
+       if (!(z80_bus_state() & ZST_RUNNING)) {
                printf_P(PSTR("## CPU is not running!\n"));
                return CMD_RET_FAILURE;
        }
@@ -82,7 +82,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        uint32_t addr;
 
        (void) cmdtp; (void) flag;
-       
+
        if (argc < 2)
                return CMD_RET_USAGE;
        addr = strtoul(argv[1], NULL, 16);
@@ -91,9 +91,9 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        "   (Out of logical address space (0x00000-0x0ffff))\n"),
                        addr);
                return CMD_RET_FAILURE;
-       } 
+       }
 
-       if (z80_bus_state() & ZST_RUNNING) {    
+       if (z80_bus_state() & ZST_RUNNING) {
                printf_P(PSTR("## CPU allready running!\n"));
                return CMD_RET_FAILURE;
        }
@@ -103,7 +103,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (addr != 0) {
                uint8_t tmp[3];
                uint_fast8_t i;
-               
+
                z80_bus_cmd(Request);
                for (i = 0; i < 3; i++)
                        tmp[i] = z80_read(i);
@@ -118,7 +118,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        z80_write(i, tmp[i]);
        } else
                z80_bus_cmd(Run);
-               
+
        z80_bus_cmd(Release);
 
        return CMD_RET_SUCCESS;
@@ -143,3 +143,34 @@ command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
        return CMD_RET_SUCCESS;
 }
 
+
+command_ret_t do_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       uint32_t freq;
+
+       (void) cmdtp; (void) flag;
+
+       if (argc == 2) {
+               freq = strtoul(argv[1], NULL, 10);
+               if (freq == 0) {
+                       printf_P(PSTR("CPU clock cannot be 0\n"));
+                       return CMD_RET_USAGE;
+               }
+
+               if (freq > F_CPU / 2) {
+                       printf_P(PSTR("Max CPU clock freq. is: %luHz\n"), F_CPU/2);
+                       return CMD_RET_USAGE;
+               }
+
+               if (z80_clock_set(freq) < 0) {
+                       printf_P(PSTR("Setting CPU clock freq. to %luHz failed.\n"),
+                                               freq);
+               }
+       }
+
+       printf_P(PSTR("CPU clock: %luHz\n"), z80_clock_get());
+
+
+       return CMD_RET_SUCCESS;
+}
+
index 91668bdf819a2e7bc0c9b4dc9eb9b84833a4242a..f1f34c05a030519ec152a458ac61706093222888 100644 (file)
@@ -22,9 +22,6 @@
 #include "con-utils.h"
 #include "z80-if.h"
 
-/* 
- * TODO: printf() --> printf_P() 
- */
 
 #ifndef CONFIG_SYS_MEMTEST_SCRATCH
 #define CONFIG_SYS_MEMTEST_SCRATCH 0
@@ -55,10 +52,10 @@ int z180_dump_mem(uint32_t startaddr, uint32_t len, const char *title)
        uint32_t addr = startaddr & ~0x0f;
        len += pre;
        uint8_t i;
-       
+
        if (title && *title)
                printf_P(PSTR("%s\n"),title);
-               
+
        while (len) {
                if (len < 16)
                        llen = len;
@@ -117,10 +114,10 @@ int z180_dump_mem(uint32_t startaddr, uint32_t len, const char *title)
 command_ret_t do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        uint32_t addr, length;
-       
+
        (void) cmdtp;
 
-#if 0  
+#if 0
        printf_P(PSTR("flag: %d, argc: %d"), flag, argc);
        for (int i = 0; i < argc; i++) {
                printf_P(PSTR(", argv[%d]: %s"), i, argv[i] ? argv[i] : "<NULL>");
@@ -264,7 +261,7 @@ command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
        z80_bus_cmd(Request);
        while (count-- > 0) {
                z80_write(addr, writeval);
-               ++addr; 
+               ++addr;
        }
        z80_bus_cmd(Release);
 
@@ -354,8 +351,8 @@ command_ret_t do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
                byte2 = z80_read(addr2);
                z80_bus_cmd(Release);
                if (byte1 != byte2) {
-                       printf"byte at 0x%05lx (%#02x) != "
-                               "byte at 0x%05lx (%#02x)\n",
+                       printf_P(PSTR("byte at 0x%05lx (%#02x) != "
+                               "byte at 0x%05lx (%#02x)\n"),
                                addr1, byte1, addr2, byte2);
                        rcode = CMD_RET_FAILURE;
                        break;
@@ -395,7 +392,7 @@ command_ret_t do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
                my_puts_P(PSTR("Zero length?\n"));
                return CMD_RET_FAILURE;
        }
-       
+
        if (dest > src) {
                src += count - 1;
                dest += count - 1;
@@ -875,4 +872,3 @@ command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
        return ret;     /* not reached */
 }
 #endif /* CONFIG_CMD_MEMTEST */
-
index 6e8a91b5fa67541221b42afb8816c10f3e3c86fb..c721d536e9febe1fac0534bb28be87c3ad937965 100644 (file)
@@ -18,6 +18,7 @@ extern command_ret_t do_dump_mem(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_eep_cp(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_busreq_pulse(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_date(cmd_tbl_t *, int, int, char * const []);
+extern command_ret_t do_clock(cmd_tbl_t *, int, int, char * const []);
 
 
 cmd_tbl_t cmd_tbl[] = {
@@ -119,6 +120,11 @@ CMD_TBL_ITEM(
        "Perform RESET of the CPU",
        ""
 ),
+CMD_TBL_ITEM(
+       clock, 2, 0,    do_clock,
+       "Set or get CPU frequency",
+       ""
+),
 
 CMD_TBL_ITEM(
        md,     3,      1,      do_mem_md,
index 726e50b280c0c3bebd58169bd48d9c339017cf9a..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);
+}
 
-static void z80_setup_addrbus_tristate(void)
+
+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;
+}
+
+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,20 +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;
-
-       /* Timer1: CTC: Toggle OC1C on compare match */
-       PRR0 &= ~_BV(PRTIM1);
-       OCR1A =  0;
-       OCR1C =  0;
-       TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
-       TCCR1B = (0b01 << WGM12)  | (0b001 << CS10);
-}
 
 void z80_setup_bus(void)
 {
@@ -244,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;
 }
@@ -259,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;
@@ -271,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();
        }
 }
 
@@ -310,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;
@@ -324,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;
 
@@ -332,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;
 
@@ -344,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;
@@ -369,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:
@@ -421,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;
@@ -436,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;
@@ -450,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++);
@@ -467,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++);
index b02fe230c68eaec191c99f5650c23434b17074c2..5153f37974c412e1102477da5a8626ae52c91d99 100644 (file)
@@ -2,14 +2,14 @@
 #define ZST_ACQUIRED   0x01
 #define ZST_RUNNING    0x02
 
-typedef enum { 
+typedef enum {
        RESET           = 0x00,
        RESET_AQRD      = ZST_ACQUIRED,
        RUNNING         = ZST_RUNNING,
        RUNNING_AQRD    = ZST_RUNNING | ZST_ACQUIRED,
 } zstate_t;
 
-typedef enum { 
+typedef enum {
        Reset,
        Request,
        Release,
@@ -26,6 +26,9 @@ void z80_setup_bus(void);
 int z80_stat_reset(void);
 //void z80_busreq(level_t level);
 int z80_stat_halt(void);
+uint32_t z80_clock_get(void);
+int z80_clock_set(unsigned long freq);
+
 
 void z80_write(uint32_t addr, uint8_t data);
 uint8_t z80_read(uint32_t addr);