From 6d0ec41db0882def15dda275b8d69d60a9d4faf1 Mon Sep 17 00:00:00 2001 From: David Banks Date: Mon, 29 Jun 2015 14:43:20 +0100 Subject: [PATCH] Added commands to read/write/dump Z80 IO space; version now 0.45 Change-Id: I85e99f8c19bd285f2dd69ea46b0e662499a5d9e2 --- firmware/AtomBusMon.c | 199 ++++++++++++++++++++++++------------------ src/BusMonCore.vhd | 58 ++++++++---- src/Z80CpuMon.vhd | 84 ++++++++++-------- 3 files changed, 204 insertions(+), 137 deletions(-) diff --git a/firmware/AtomBusMon.c b/firmware/AtomBusMon.c index 711d92a..7ceaeff 100644 --- a/firmware/AtomBusMon.c +++ b/firmware/AtomBusMon.c @@ -6,10 +6,22 @@ #include "AtomBusMon.h" +#define VERSION "0.45" + #if (CPU == Z80) -#define NAME "ICE-T80" + #define NAME "ICE-T80" #else -#define NAME "ICE-T65" + #define NAME "ICE-T65" +#endif + +#ifdef CPUEMBEDDED + #if (CPU == Z80) + #define NUM_CMDS 24 + #else + #define NUM_CMDS 22 + #endif +#else + #define NUM_CMDS 14 #endif #define CRC_POLY 0x002d @@ -179,20 +191,6 @@ char *triggerStrings[NUM_TRIGGERS] = { "Always", }; - -#define VERSION "0.44" - -#ifdef CPUEMBEDDED - #if (CPU != Z80) - #define NUM_CMDS 22 - #else - #define NUM_CMDS 21 - #endif -#else - #define NUM_CMDS 14 -#endif - - long trace; long instructions = 1; @@ -222,13 +220,17 @@ char *cmdStrings[NUM_CMDS] = { "continue", #ifdef CPUEMBEDDED "regs", - "mem", "dis", - "read", - "write", "fill", "crc", -#if (CPU != Z80) + "mem", + "readmem", + "writemem", +#if (CPU == Z80) + "io", + "readio", + "writeio", +#else "test", #endif #endif @@ -620,32 +622,6 @@ void doCmdRegs(char *params) { log0("\n"); } -void doCmdMem(char *params) { - int i, j; - unsigned int row[16]; - sscanf(params, "%x", &memAddr); - loadAddr(memAddr); - for (i = 0; i < 0x100; i+= 16) { - for (j = 0; j < 16; j++) { - row[j] = readMemByteInc(); - } - log0("%04X ", memAddr + i); - for (j = 0; j < 16; j++) { - log0("%02X ", row[j]); - } - log0(" "); - for (j = 0; j < 16; j++) { - unsigned int c = row[j]; - if (c < 32 || c > 126) { - c = '.'; - } - log0("%c", c); - } - log0("\n"); - } - memAddr += 0x100; -} - void doCmdDis(char *params) { int i; sscanf(params, "%x", &memAddr); @@ -655,44 +631,13 @@ void doCmdDis(char *params) { } } -void doCmdWrite(char *params) { - unsigned int addr; - unsigned int data; - long count = 1; - sscanf(params, "%x %x %ld", &addr, &data, &count); - log0("Wr: %04X = %X\n", addr, data); - loadData(data); - loadAddr(addr); - while (count-- > 0) { - writeMemByte(); - } -} - -void doCmdRead(char *params) { - unsigned int addr; - unsigned int data; - unsigned int data2; - long count = 1; - sscanf(params, "%x %ld", &addr, &count); - loadAddr(addr); - data = readMemByte(); - log0("Rd: %04X = %X\n", addr, data); - while (count-- > 1) { - data2 = readMemByte(); - if (data2 != data) { - log0("Inconsistent Rd: %02X <> %02X\n", data2, data); - } - data = data2; - } -} - void doCmdFill(char *params) { long i; unsigned int start; unsigned int end; unsigned int data; sscanf(params, "%x %x %x", &start, &end, &data); - log0("Wr: %04X to %04X = %X\n", start, end, data); + log0("Wr: %04X to %04X = %02X\n", start, end, data); loadData(data); loadAddr(start); for (i = start; i <= end; i++) { @@ -722,7 +667,91 @@ void doCmdCrc(char *params) { log0("crc: %04X\n", crc); } -#if (CPU != Z80) +void genericDump(char *params, unsigned int (*readFunc)()) { + int i, j; + unsigned int row[16]; + sscanf(params, "%x", &memAddr); + loadAddr(memAddr); + for (i = 0; i < 0x100; i+= 16) { + for (j = 0; j < 16; j++) { + row[j] = (*readFunc)(); + } + log0("%04X ", memAddr + i); + for (j = 0; j < 16; j++) { + log0("%02X ", row[j]); + } + log0(" "); + for (j = 0; j < 16; j++) { + unsigned int c = row[j]; + if (c < 32 || c > 126) { + c = '.'; + } + log0("%c", c); + } + log0("\n"); + } + memAddr += 0x100; +} + +void genericWrite(char *params, void (*writeFunc)()) { + unsigned int addr; + unsigned int data; + long count = 1; + sscanf(params, "%x %x %ld", &addr, &data, &count); + log0("Wr: %04X = %02X\n", addr, data); + loadData(data); + loadAddr(addr); + while (count-- > 0) { + (*writeFunc)(); + } +} + +void genericRead(char *params, unsigned int (*readFunc)()) { + unsigned int addr; + unsigned int data; + unsigned int data2; + long count = 1; + sscanf(params, "%x %ld", &addr, &count); + loadAddr(addr); + data = (*readFunc)(); + log0("Rd: %04X = %02X\n", addr, data); + while (count-- > 1) { + data2 = (*readFunc)(); + if (data2 != data) { + log0("Inconsistent Rd: %02X <> %02X\n", data2, data); + } + data = data2; + } +} + +void doCmdMem(char *params) { + genericDump(params, readMemByteInc); +} + +void doCmdReadMem(char *params) { + genericRead(params, readMemByte); +} + +void doCmdWriteMem(char *params) { + genericWrite(params, writeMemByte); +} + +#if (CPU == Z80) + +void doCmdIO(char *params) { + genericDump(params, readIOByteInc); +} + +void doCmdReadIO(char *params) { + genericRead(params, readIOByte); +} + +void doCmdWriteIO(char *params) { + genericWrite(params, writeIOByte); +} + +#else + unsigned int getData(unsigned int addr, int data) { if (data == -1) { // checkerboard @@ -1058,13 +1087,17 @@ void (*cmdFuncs[NUM_CMDS])(char *params) = { doCmdContinue, #ifdef CPUEMBEDDED doCmdRegs, - doCmdMem, doCmdDis, - doCmdRead, - doCmdWrite, doCmdFill, doCmdCrc, -#if (CPU != Z80) + doCmdMem, + doCmdReadMem, + doCmdWriteMem, +#if (CPU == Z80) + doCmdIO, + doCmdReadIO, + doCmdWriteIO, +#else doCmdTest, #endif #endif diff --git a/src/BusMonCore.vhd b/src/BusMonCore.vhd index 3f75dc7..4615183 100644 --- a/src/BusMonCore.vhd +++ b/src/BusMonCore.vhd @@ -50,8 +50,10 @@ entity BusMonCore is -- 6502 Memory Read/Write -- unused in pure bus monitor mode - RdOut : out std_logic; - WrOut : out std_logic; + RdMemOut : out std_logic; + WrMemOut : out std_logic; + RdIOOut : out std_logic; + WrIOOut : out std_logic; AddrOut : out std_logic_vector(15 downto 0); DataOut : out std_logic_vector(7 downto 0); DataIn : in std_logic_vector(7 downto 0); @@ -139,6 +141,8 @@ architecture behavioral of BusMonCore is signal memory_rd : std_logic; signal memory_wr : std_logic; + signal io_rd : std_logic; + signal io_wr : std_logic; signal addr_dout_reg : std_logic_vector(23 downto 0); signal din_reg : std_logic_vector(7 downto 0); @@ -399,20 +403,28 @@ begin bw_status <= status; end process; - -- 6502 Control Commands - -- 0000x Enable/Disable single stepping + -- CPU Control Commands + -- 0000x Enable/Disable single strpping -- 0001x Enable/Disable breakpoints / watches - -- 0010x Load breakpoint register - -- 0011x Reset - -- 01000 Single Step - -- 01001 FIFO Read - -- 01010 FIFO Reset - -- 0110x Load memory address/data register - -- 0111x Unused - -- 1000x Read memory - -- 1001x Write memory - -- 101xx Unused + -- 0010x Load breakpoint / watch register + -- 0011x Reset CPU + -- 01000 Singe Step CPU + -- 01001 Read FIFO + -- 01010 Reset FIFO + -- 01011 Unused + -- 0110x Load address/data register + -- 0111x Unused + -- 10000 Read Memory + -- 10001 Read Memory and Auto Inc Address + -- 10010 Write Memory + -- 10011 Write Memory and Auto Inc Address + -- 10000 Read Memory + -- 10001 Read Memory and Auto Inc Address + -- 10010 Write Memory + -- 10011 Write Memory and Auto Inc Address + -- 1x1xx Unused -- 11xxx Unused + risingProcess: process (Phi2) begin if rising_edge(Phi2) then @@ -432,6 +444,8 @@ begin fifo_rst <= '0'; memory_rd <= '0'; memory_wr <= '0'; + io_rd <= '0'; + io_wr <= '0'; SS_Step <= '0'; if (cmd_edge2 = '0' and cmd_edge1 = '1') then if (cmd(4 downto 1) = "0000") then @@ -471,6 +485,16 @@ begin memory_wr <= '1'; auto_inc <= cmd(0); end if; + + if (cmd(4 downto 1) = "1010") then + io_rd <= '1'; + auto_inc <= cmd(0); + end if; + + if (cmd(4 downto 1) = "1011") then + io_wr <= '1'; + auto_inc <= cmd(0); + end if; end if; @@ -528,8 +552,10 @@ begin end process; Rdy <= Rdy_int; - RdOut <= memory_rd; - WrOut <= memory_wr; + RdMemOut <= memory_rd; + WrMemOut <= memory_wr; + RdIOOut <= io_rd; + WrIOOut <= io_wr; AddrOut <= addr_dout_reg(23 downto 8); DataOut <= addr_dout_reg(7 downto 0); SS_Single <= single; diff --git a/src/Z80CpuMon.vhd b/src/Z80CpuMon.vhd index 581fe7a..9cc64ae 100644 --- a/src/Z80CpuMon.vhd +++ b/src/Z80CpuMon.vhd @@ -100,6 +100,9 @@ signal SS_Step_held : std_logic; signal CountCycle : std_logic; signal Regs : std_logic_vector(255 downto 0); +signal io_not_mem : std_logic; +signal io_rd : std_logic; +signal io_wr : std_logic; signal memory_rd : std_logic; signal memory_wr : std_logic; signal memory_addr : std_logic_vector(15 downto 0); @@ -136,41 +139,43 @@ begin num_comparators => 4 ) port map ( - clock49 => clock49, - Addr => Addr_int, - Data => mon_data, - Phi2 => busmon_clk, - Rd_n => Read_n, - Wr_n => Write_n, - Sync => Sync, - Rdy => Rdy, - nRSTin => RESET_n_int, - nRSTout => nRST, + clock49 => clock49, + Addr => Addr_int, + Data => mon_data, + Phi2 => busmon_clk, + Rd_n => Read_n, + Wr_n => Write_n, + Sync => Sync, + Rdy => Rdy, + nRSTin => RESET_n_int, + nRSTout => nRST, CountCycle => CountCycle, - trig => trig, - lcd_rs => open, - lcd_rw => open, - lcd_e => open, - lcd_db => open, - avr_RxD => avr_RxD, - avr_TxD => avr_TxD, - sw1 => '0', - nsw2 => nsw2, - led3 => led3, - led6 => led6, - led8 => led8, - tmosi => tmosi, - tdin => tdin, - tcclk => tcclk, - Regs => Regs, - RdOut => memory_rd, - WrOut => memory_wr, - AddrOut => memory_addr, - DataOut => memory_dout, - DataIn => memory_din, - Done => memory_done, - SS_Single => SS_Single, - SS_Step => SS_Step + trig => trig, + lcd_rs => open, + lcd_rw => open, + lcd_e => open, + lcd_db => open, + avr_RxD => avr_RxD, + avr_TxD => avr_TxD, + sw1 => '0', + nsw2 => nsw2, + led3 => led3, + led6 => led6, + led8 => led8, + tmosi => tmosi, + tdin => tdin, + tcclk => tcclk, + Regs => Regs, + RdMemOut => memory_rd, + WrMemOut => memory_wr, + RdIOOut => io_rd, + WrIOOut => io_wr, + AddrOut => memory_addr, + DataOut => memory_dout, + DataIn => memory_din, + Done => memory_done, + SS_Single => SS_Single, + SS_Step => SS_Step ); GenT80Core: if UseT80Core generate @@ -273,9 +278,10 @@ begin Addr <= memory_addr when (state /= idle) else Addr_int; MREQ_n <= '1' when (state = rd_init or state = wr_init or state = release) else - '0' when (state /= idle) else MREQ_n_int; + '0' when (state /= idle and io_not_mem = '0') else MREQ_n_int; - IORQ_n <= '1' when (state /= idle) else IORQ_n_int; + IORQ_n <= '1' when (state = rd_init or state = wr_init or state = release) else + '0' when (state /= idle and io_not_mem = '1') else IORQ_n_int; WR_n <= '0' when (state = wr) else '1' when (state /= idle) else WR_n_int; @@ -304,10 +310,12 @@ begin elsif falling_edge(CLK_n) then case state IS when idle => - if (memory_wr = '1') then + if (memory_wr = '1' or io_wr = '1') then state <= wr_init; - elsif (memory_rd = '1') then + io_not_mem <= io_wr; + elsif (memory_rd = '1' or io_rd = '1') then state <= rd_init; + io_not_mem <= io_rd; end if; when rd_init => state <= rd_setup;