From 2fc7485d9cbf8238405a68107c2fb10c9153182e Mon Sep 17 00:00:00 2001 From: David Banks Date: Tue, 16 Jun 2015 11:57:32 +0100 Subject: [PATCH] Implemented 6502 register access functionality with the embedded core Change-Id: I0edaa48ddfb4b7057e1dde25895513bcaf395b07 --- AtomBusMon.xise | 6 +- AtomCpuMon.xise | 125 ++++++++-------- firmware/AtomBusMon.c | 70 +++++++-- firmware/Makefile | 2 +- firmware/Makefile.cpu | 2 +- src/AtomBusMon.bmm | 16 +- src/AtomBusMon.vhd | 332 +++--------------------------------------- src/AtomCpuMon.vhd | 11 +- src/T6502/T65.vhd | 6 +- 9 files changed, 173 insertions(+), 397 deletions(-) diff --git a/AtomBusMon.xise b/AtomBusMon.xise index 09d9849..1441108 100644 --- a/AtomBusMon.xise +++ b/AtomBusMon.xise @@ -17,7 +17,7 @@ - + @@ -237,6 +237,10 @@ + + + + diff --git a/AtomCpuMon.xise b/AtomCpuMon.xise index bcf217d..002c5f6 100644 --- a/AtomCpuMon.xise +++ b/AtomCpuMon.xise @@ -20,243 +20,243 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - + - + - + + + + + @@ -536,6 +536,7 @@ + diff --git a/firmware/AtomBusMon.c b/firmware/AtomBusMon.c index 8523175..a0b5bbe 100644 --- a/firmware/AtomBusMon.c +++ b/firmware/AtomBusMon.c @@ -10,6 +10,8 @@ #define CTRL_DDR DDRB #define CTRL_DIN PINB +#define MUXSEL_PORT PORTD + #define STATUS_PORT PORTD #define STATUS_DDR DDRD #define STATUS_DIN PIND @@ -26,6 +28,15 @@ #define OFFSET_BW_BAH 5 #define OFFSET_BW_M 6 +#define OFFSET_REG_A 8 +#define OFFSET_REG_X 9 +#define OFFSET_REG_Y 10 +#define OFFSET_REG_P 11 +#define OFFSET_REG_SPL 12 +#define OFFSET_REG_SPH 13 +#define OFFSET_REG_PCL 14 +#define OFFSET_REG_PCH 15 + // Commands // 000x Enable/Disable single strpping // 001x Enable/Disable breakpoints / watches @@ -44,8 +55,8 @@ // Control bits #define CMD_MASK 0x1F #define CMD_EDGE 0x10 -#define MUX_SEL_MASK 0xE0 -#define MUX_SEL_BIT 5 +#define MUXSEL_MASK 0x0F +#define MUXSEL_BIT 0 // Status bits #define INTERRUPTED_MASK 0x40 @@ -95,9 +106,14 @@ char *triggerStrings[NUM_TRIGGERS] = { }; -#define VERSION "0.22" +#define VERSION "0.23" +#ifdef EMBEDDED_6502 +#define NUM_CMDS 20 +#else #define NUM_CMDS 19 +#endif + #define MAXBKPTS 8 int numbkpts = 0; @@ -142,6 +158,9 @@ unsigned int triggers[MAXBKPTS] = { char *cmdStrings[NUM_CMDS] = { "help", +#ifdef EMBEDDED_6502 + "regs", +#endif "reset", "step", "trace", @@ -220,19 +239,19 @@ void hwCmd(unsigned int cmd, unsigned int param) { } unsigned int hwRead8(unsigned int offset) { - CTRL_PORT &= ~MUX_SEL_MASK; - CTRL_PORT |= offset << MUX_SEL_BIT; + MUXSEL_PORT &= ~MUXSEL_MASK; + MUXSEL_PORT |= offset << MUXSEL_BIT; Delay_us(1); return MUX_DIN; } unsigned int hwRead16(unsigned int offset) { unsigned int lsb; - CTRL_PORT &= ~MUX_SEL_MASK; - CTRL_PORT |= offset << MUX_SEL_BIT; + MUXSEL_PORT &= ~MUXSEL_MASK; + MUXSEL_PORT |= offset << MUXSEL_BIT; Delay_us(1); lsb = MUX_DIN; - CTRL_PORT |= 1 << MUX_SEL_BIT; + MUXSEL_PORT |= 1 << MUXSEL_BIT; Delay_us(1); return (MUX_DIN << 8) | lsb; } @@ -257,6 +276,7 @@ void version() { } +#ifdef LCD void lcdAddr(unsigned int addr) { int i; int nibble; @@ -271,8 +291,9 @@ void lcdAddr(unsigned int addr) { } lcd_putc(nibble); } - } +#endif + void logMode(unsigned int mode) { int i; @@ -356,7 +377,9 @@ void doCmdHelp(char *params) { void doCmdAddr() { unsigned int i_addr = hwRead16(OFFSET_IAL); // Update the LCD display +#ifdef LCD lcdAddr(i_addr); +#endif // Update the serial console log0("%04X\n", i_addr); } @@ -397,6 +420,18 @@ void doCmdReset(char *params) { hwCmd(CMD_RESET, 0); } +#ifdef EMBEDDED_6502 +void doCmdRegs(char *params) { + log0("A=%02x; ", hwRead8(OFFSET_REG_A)); + log0("X=%02x; ", hwRead8(OFFSET_REG_X)); + log0("Y=%02x; ", hwRead8(OFFSET_REG_Y)); + log0("P=%02x; ", hwRead8(OFFSET_REG_P)); + log0("SP=%04x; ", hwRead16(OFFSET_REG_SPL)); + log0("PC=%04x; ", hwRead16(OFFSET_REG_PCL)); + log0("\n"); +} +#endif + void doCmdTrace(char *params) { long i; sscanf(params, "%ld", &i); @@ -602,14 +637,16 @@ void doCmdContinue(char *params) { do { // Update the LCD display i_addr = hwRead16(OFFSET_IAL); +#ifdef LCD lcdAddr(i_addr); +#endif status = STATUS_DIN; if (status & BW_ACTIVE_MASK) { cont = logDetails(); hwCmd(CMD_WATCH_READ, 0); } - if (status & INTERRUPTED_MASK) { + if (status & INTERRUPTED_MASK || Serial_ByteRecieved0()) { log0("Interrupted at "); doCmdAddr(); cont = 0; @@ -617,6 +654,11 @@ void doCmdContinue(char *params) { Delay_us(10); } while (cont); + // Junk the interrupt character + if (Serial_ByteRecieved0()) { + Serial_RxByte0(); + } + // Enable single stepping setSingle(1); @@ -627,12 +669,14 @@ void doCmdContinue(char *params) { void initialize() { CTRL_DDR = 255; - STATUS_DDR = 0; + STATUS_DDR = MUXSEL_MASK; MUX_DDR = 0; CTRL_PORT = 0; Serial_Init(57600,57600); +#ifdef LCD lcd_init(); lcd_puts("Addr: xxxx"); +#endif version(); hwCmd(CMD_RESET, 0); hwCmd(CMD_FIFO_RST, 0); @@ -642,6 +686,9 @@ void initialize() { void (*cmdFuncs[NUM_CMDS])(char *params) = { doCmdHelp, +#ifdef EMBEDDED_6502 + doCmdRegs, +#endif doCmdReset, doCmdStep, doCmdTrace, @@ -662,7 +709,6 @@ void (*cmdFuncs[NUM_CMDS])(char *params) = { doCmdContinue }; - void dispatchCmd(char *cmd) { int i; char *cmdString; diff --git a/firmware/Makefile b/firmware/Makefile index 3b6e512..a8333d8 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -23,7 +23,7 @@ F_CPU=15855484 CC=avr-gcc OBJCOPY=avr-objcopy -CFLAGS=-DF_CPU=${F_CPU}UL -DSERIAL_STATUS -DCOOKED_SERIAL -DNOUSART1 -mmcu=$(MCU) -Wall -Os -mcall-prologues +CFLAGS=-DLCD=1 -DF_CPU=${F_CPU}UL -DSERIAL_STATUS -DCOOKED_SERIAL -DNOUSART1 -mmcu=$(MCU) -Wall -Os -mcall-prologues OBJECTS=AtomBusMon.o hd44780.o status.o diff --git a/firmware/Makefile.cpu b/firmware/Makefile.cpu index 61b32d1..9df9d23 100644 --- a/firmware/Makefile.cpu +++ b/firmware/Makefile.cpu @@ -23,7 +23,7 @@ F_CPU=15855484 CC=avr-gcc OBJCOPY=avr-objcopy -CFLAGS=-DF_CPU=${F_CPU}UL -DSERIAL_STATUS -DCOOKED_SERIAL -DNOUSART1 -mmcu=$(MCU) -Wall -Os -mcall-prologues +CFLAGS=-DEMBEDDED_6502=1 -DF_CPU=${F_CPU}UL -DSERIAL_STATUS -DCOOKED_SERIAL -DNOUSART1 -mmcu=$(MCU) -Wall -Os -mcall-prologues OBJECTS=AtomBusMon.o hd44780.o status.o diff --git a/src/AtomBusMon.bmm b/src/AtomBusMon.bmm index 2f309ed..3b0f272 100644 --- a/src/AtomBusMon.bmm +++ b/src/AtomBusMon.bmm @@ -2,35 +2,35 @@ ADDRESS_MAP avrmap PPC405 0 ADDRESS_SPACE rom_code RAMB16 [0x00000000:0x00003fff] BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word0 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word0 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word1 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word1 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word2 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word2 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word3 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word3 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word4 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word4 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word5 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word5 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word6 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word6 [15:0]; END_BUS_BLOCK; BUS_BLOCK - Inst_AVR8/PM_Inst/RAM_Word7 [15:0]; + mon/Inst_AVR8/PM_Inst/RAM_Word7 [15:0]; END_BUS_BLOCK; END_ADDRESS_SPACE; diff --git a/src/AtomBusMon.vhd b/src/AtomBusMon.vhd index e4088a8..61728d1 100644 --- a/src/AtomBusMon.vhd +++ b/src/AtomBusMon.vhd @@ -19,15 +19,8 @@ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; -use work.OhoPack.all ; - entity AtomBusMon is - generic ( - num_comparators : integer := 8; - reg_width : integer := 26; - fifo_width : integer := 36 - ); port ( clock49 : in std_logic; @@ -70,311 +63,34 @@ end AtomBusMon; architecture behavioral of AtomBusMon is - signal clock_avr : std_logic; - signal nrst_avr : std_logic; - signal lcd_rw_int : std_logic; - signal lcd_db_in : std_logic_vector(7 downto 4); - signal lcd_db_out : std_logic_vector(7 downto 4); - signal dy_counter : std_logic_vector(31 downto 0); - signal dy_data : y2d_type ; - - signal mux : std_logic_vector(7 downto 0); - signal muxsel : std_logic_vector(2 downto 0); - signal cmd_edge : std_logic; - signal cmd_edge1 : std_logic; - signal cmd_edge2 : std_logic; - signal cmd : std_logic_vector(3 downto 0); - - signal addr_sync : std_logic_vector(15 downto 0); - signal addr_inst : std_logic_vector(15 downto 0); - - signal single : std_logic; - signal reset : std_logic; - signal step : std_logic; - - signal bw_status : std_logic_vector(fifo_width - 16 - 1 downto 0); - signal bw_status1 : std_logic_vector(fifo_width - 16 - 1 downto 0); - - signal brkpt_reg : std_logic_vector(num_comparators * reg_width - 1 downto 0); - signal brkpt_enable : std_logic; - signal brkpt_active : std_logic; - signal brkpt_active1 : std_logic; - signal watch_active : std_logic; - - signal fifo_din : std_logic_vector(fifo_width - 1 downto 0); - signal fifo_dout : std_logic_vector(fifo_width - 1 downto 0); - signal fifo_empty : std_logic; - signal fifo_rd : std_logic; - signal fifo_wr : std_logic; - signal fifo_rst : std_logic; - begin - inst_dcm5 : entity work.DCM0 port map( - CLKIN_IN => clock49, - CLK0_OUT => clock_avr, - CLK0_OUT1 => open, - CLK2X_OUT => open - ); - - inst_oho_dy1 : entity work.Oho_Dy1 port map ( - dy_clock => clock49, - dy_rst_n => '1', - dy_data => dy_data, - dy_update => '1', - dy_frame => open, - dy_frameend => open, - dy_frameend_c => open, - dy_pwm => "1010", - dy_counter => dy_counter, - dy_sclk => tdin, - dy_ser => tcclk, - dy_rclk => tmosi + mon : entity work.BusMonCore port map ( + clock49 => clock49, + Addr => Addr, + Phi2 => Phi2, + RNW => RNW, + Sync => Sync, + Rdy => Rdy, + nRST => nRST, + trig => trig, + lcd_rs => lcd_rs, + lcd_rw => lcd_rw, + lcd_e => lcd_e, + lcd_db => lcd_db, + avr_RxD => avr_RxD, + avr_TxD => avr_TxD, + sw1 => sw1, + nsw2 => nsw2, + led3 => led3, + led6 => led6, + led8 => led8, + tmosi => tmosi, + tdin => tdin, + tcclk => tcclk, + Regs => (others => '0') ); - - Inst_AVR8: entity work.AVR8 port map( - clk16M => clock_avr, - nrst => nrst_avr, - - portain(0) => '0', - portain(1) => '0', - portain(2) => '0', - portain(3) => '0', - portain(4) => lcd_db_in(4), - portain(5) => lcd_db_in(5), - portain(6) => lcd_db_in(6), - portain(7) => lcd_db_in(7), - - portaout(0) => lcd_rs, - portaout(1) => lcd_rw_int, - portaout(2) => lcd_e, - portaout(3) => open, - portaout(4) => lcd_db_out(4), - portaout(5) => lcd_db_out(5), - portaout(6) => lcd_db_out(6), - portaout(7) => lcd_db_out(7), - - -- Command Port - portbin(0) => '0', - portbin(1) => '0', - portbin(2) => '0', - portbin(3) => '0', - portbin(4) => '0', - portbin(5) => '0', - portbin(6) => '0', - portbin(7) => '0', - portbout(0) => cmd(0), - portbout(1) => cmd(1), - portbout(2) => cmd(2), - portbout(3) => cmd(3), - portbout(4) => cmd_edge, - portbout(5) => muxsel(0), - portbout(6) => muxsel(1), - portbout(7) => muxsel(2), - - -- Status Port - portdin(0) => '0', - portdin(1) => '0', - portdin(2) => '0', - portdin(3) => '0', - portdin(4) => '0', - portdin(5) => '0', - portdin(6) => sw1, - portdin(7) => not fifo_empty, - portdout => open, - - -- Mux Port - portein => mux, - porteout => open, - - spi_mosio => open, - spi_scko => open, - spi_misoi => '0', - - rxd => avr_RxD, - txd => avr_TxD - ); - - WatchEvents_inst : entity work.WatchEvents port map( - clk => Phi2, - srst => fifo_rst, - din => fifo_din, - wr_en => fifo_wr, - rd_en => fifo_rd, - dout => fifo_dout, - full => open, - empty => fifo_empty - ); - - - fifo_din <= bw_status1 & addr_inst; - - lcd_rw <= lcd_rw_int; - lcd_db <= lcd_db_out when lcd_rw_int = '0' else (others => 'Z'); - lcd_db_in <= lcd_db; - - led3 <= not trig(0); -- red - led6 <= not trig(1); -- red - led8 <= not brkpt_active; -- green - - nrst_avr <= nsw2; - - -- OHO DY1 Display for Testing - dy_data(0) <= hex & "0000" & Addr(3 downto 0); - dy_data(1) <= hex & "0000" & Addr(7 downto 4); - dy_data(2) <= hex & "0000" & "00" & (not nsw2) & sw1; - - mux <= addr_inst(7 downto 0) when muxsel = 0 else - addr_inst(15 downto 8) when muxsel = 1 else - fifo_dout(7 downto 0) when muxsel = 2 else - fifo_dout(15 downto 8) when muxsel = 3 else - fifo_dout(23 downto 16) when muxsel = 4 else - fifo_dout(31 downto 24) when muxsel = 5 else - "0000" & fifo_dout(35 downto 32) when muxsel = 6 else - "10101010"; - - -- Combinatorial set of comparators to decode breakpoint/watch addresses - brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync) - variable i : integer; - variable reg_addr : std_logic_vector(15 downto 0); - variable reg_mode_bi : std_logic; - variable reg_mode_bar : std_logic; - variable reg_mode_baw : std_logic; - variable reg_mode_wi : std_logic; - variable reg_mode_war : std_logic; - variable reg_mode_waw : std_logic; - variable bactive : std_logic; - variable wactive : std_logic; - variable status : std_logic_vector(19 downto 0); - variable trigval : std_logic; - begin - bactive := '0'; - wactive := '0'; - status := "00001010101010101010"; - if (brkpt_enable = '1') then - for i in 0 to num_comparators - 1 loop - reg_addr := brkpt_reg(i * reg_width + 15 downto i * reg_width); - reg_mode_bi := brkpt_reg(i * reg_width + 16); - reg_mode_bar := brkpt_reg(i * reg_width + 17); - reg_mode_baw := brkpt_reg(i * reg_width + 18); - reg_mode_wi := brkpt_reg(i * reg_width + 19); - reg_mode_war := brkpt_reg(i * reg_width + 20); - reg_mode_waw := brkpt_reg(i * reg_width + 21); - trigval := brkpt_reg(i * reg_width + 22 + to_integer(unsigned(trig))); - if (trigval = '1' and (Addr = reg_addr or - (reg_mode_bi = '0' and reg_mode_bar = '0' and reg_mode_baw = '0' and - (reg_mode_wi = '0' and reg_mode_war = '0' and reg_mode_waw = '0')))) then - if (Sync = '1') then - if (reg_mode_bi = '1') then - bactive := '1'; - status := "0001" & reg_addr; - end if; - if (reg_mode_wi = '1') then - wactive := '1'; - status := "1001" & reg_addr; - end if; - else - if (RNW = '1') then - if (reg_mode_bar = '1') then - bactive := '1'; - status := "0010" & reg_addr; - end if; - if (reg_mode_war = '1') then - wactive := '1'; - status := "1010" & reg_addr; - end if; - else - if (reg_mode_baw = '1') then - bactive := '1'; - status := "0100" & reg_addr; - end if; - if (reg_mode_waw = '1') then - wactive := '1'; - status := "1100" & reg_addr; - end if; - end if; - end if; - end if; - end loop; - end if; - watch_active <= wactive; - brkpt_active <= bactive; - bw_status <= status; - end process; - - -- 6502 Control Commands - -- 000x Enable/Disable single strpping - -- 001x Enable/Disable breakpoints / watches - -- 010x Load register - -- 011x Reset - -- 1000 Single Step - -- 1001 FIFO Read - -- 1010 FIFO Reset - syncProcess: process (Phi2) - begin - if rising_edge(Phi2) then - - -- Command processing - cmd_edge1 <= cmd_edge; - cmd_edge2 <= cmd_edge1; - fifo_rd <= '0'; - fifo_wr <= '0'; - fifo_rst <= '0'; - if (cmd_edge2 = '0' and cmd_edge1 = '1') then - if (cmd(3 downto 1) = "000") then - single <= cmd(0); - end if; - - if (cmd(3 downto 1) = "001") then - brkpt_enable <= cmd(0); - end if; - - if (cmd(3 downto 1) = "010") then - brkpt_reg <= cmd(0) & brkpt_reg(brkpt_reg'length - 1 downto 1); - end if; - - if (cmd(3 downto 1) = "011") then - reset <= cmd(0); - end if; - - if (cmd(3 downto 0) = "1001") then - fifo_rd <= '1'; - end if; - - if (cmd(3 downto 0) = "1010") then - fifo_rst <= '1'; - end if; - end if; - - -- Single Stepping - if ((single = '0') or (cmd_edge2 = '0' and cmd_edge1 = '1' and cmd = "1000")) then - Rdy <= (not brkpt_active); - else - Rdy <= (not Sync); - end if; - - -- 6502 Reset needs to be open collector - if (reset = '1') then - nRST <= '0'; - else - nRST <= 'Z'; - end if; - - -- Latch instruction address for the whole cycle - if (Sync = '1') then - addr_inst <= Addr; - end if; - - -- Breakpoints and Watches written to the FIFO - brkpt_active1 <= brkpt_active; - bw_status1 <= bw_status; - if watch_active = '1' or (brkpt_active = '1' and brkpt_active1 = '0') then - fifo_wr <= '1'; - end if; - end if; - end process; - end behavioral; diff --git a/src/AtomCpuMon.vhd b/src/AtomCpuMon.vhd index d2fb47e..0368ad8 100644 --- a/src/AtomCpuMon.vhd +++ b/src/AtomCpuMon.vhd @@ -80,9 +80,11 @@ architecture behavioral of AtomCpuMon is signal Phi0_d : std_logic; signal cpu_clk : std_logic; + signal Regs : std_logic_vector(63 downto 0); + begin - mon : entity work.AtomBusMon port map ( + mon : entity work.BusMonCore port map ( clock49 => clock49, Addr => Addr_int, Phi2 => Phi0, @@ -104,7 +106,8 @@ begin led8 => led8, tmosi => tmosi, tdin => tdin, - tcclk => tcclk + tcclk => tcclk, + Regs => Regs ); cpu_t65 : entity work.T65 port map ( @@ -122,7 +125,8 @@ begin A(23 downto 16) => open, A(15 downto 0) => Addr_int, DI => Din, - DO => Dout + DO => Dout, + Regs => Regs ); sync_gen : process(cpu_clk, Res_n) @@ -155,6 +159,7 @@ begin Phi1 <= not (Phi0_b or Phi0_d); Phi2 <= Phi0_b and Phi0_d; + cpu_clk <= not Phi0_d; diff --git a/src/T6502/T65.vhd b/src/T6502/T65.vhd index 2e784db..a01a9ab 100755 --- a/src/T6502/T65.vhd +++ b/src/T6502/T65.vhd @@ -90,7 +90,9 @@ entity T65 is VPA : out std_logic; A : out std_logic_vector(23 downto 0); DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) + DO : out std_logic_vector(7 downto 0); + -- 6502 registers (MSB) PC, SP, P, Y, X, A (LSB) + Regs : out std_logic_vector(63 downto 0) ); end T65; @@ -185,6 +187,8 @@ begin VDA <= '1' when Set_Addr_To_r /= "00" else '0'; -- Incorrect !!!!!!!!!!!! VPA <= '1' when Jump(1) = '0' else '0'; -- Incorrect !!!!!!!!!!!! + Regs <= std_logic_vector(PC) & std_logic_vector(S)& P & Y(7 downto 0) & X(7 downto 0) & ABC(7 downto 0); + mcode : T65_MCode port map( Mode => Mode_r,