diff --git a/AtomCpuMon.xise b/AtomCpuMon.xise
index 002c5f6..4ec1fa1 100644
--- a/AtomCpuMon.xise
+++ b/AtomCpuMon.xise
@@ -20,242 +20,242 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/firmware/AtomBusMon.c b/firmware/AtomBusMon.c
index a0b5bbe..f82bb31 100644
--- a/firmware/AtomBusMon.c
+++ b/firmware/AtomBusMon.c
@@ -6,28 +6,32 @@
#include "hd44780.h"
#include "status.h"
-#define CTRL_PORT PORTB
-#define CTRL_DDR DDRB
-#define CTRL_DIN PINB
+#ifdef EMBEDDED_6502
+#include "disassembler.h"
+#endif
-#define MUXSEL_PORT PORTD
+#define CTRL_PORT PORTB
+#define CTRL_DDR DDRB
+#define CTRL_DIN PINB
-#define STATUS_PORT PORTD
-#define STATUS_DDR DDRD
-#define STATUS_DIN PIND
+#define MUXSEL_PORT PORTD
-#define MUX_PORT PORTE
-#define MUX_DDR DDRE
-#define MUX_DIN PINE
+#define STATUS_PORT PORTD
+#define STATUS_DDR DDRD
+#define STATUS_DIN PIND
-#define OFFSET_IAL 0
-#define OFFSET_IAH 1
-#define OFFSET_BW_IAL 2
-#define OFFSET_BW_IAH 3
-#define OFFSET_BW_BAL 4
-#define OFFSET_BW_BAH 5
-#define OFFSET_BW_M 6
+#define MUX_PORT PORTE
+#define MUX_DDR DDRE
+#define MUX_DIN PINE
+#define OFFSET_IAL 0
+#define OFFSET_IAH 1
+#define OFFSET_BW_IAL 2
+#define OFFSET_BW_IAH 3
+#define OFFSET_BW_BAL 4
+#define OFFSET_BW_BAH 5
+#define OFFSET_BW_M 6
+#define OFFSET_DATA 7
#define OFFSET_REG_A 8
#define OFFSET_REG_X 9
#define OFFSET_REG_Y 10
@@ -46,11 +50,14 @@
#define CMD_SINGLE_ENABLE 0x00
#define CMD_BRKPT_ENABLE 0x02
-#define CMD_LOAD_REG 0x04
+#define CMD_LOAD_BRKPT 0x04
#define CMD_RESET 0x06
#define CMD_STEP 0x08
#define CMD_WATCH_READ 0x09
#define CMD_FIFO_RST 0x0A
+#define CMD_LOAD_MEM 0x0C
+#define CMD_RD_MEM 0x0E
+#define CMD_WR_MEM 0x0F
// Control bits
#define CMD_MASK 0x1F
@@ -109,7 +116,7 @@ char *triggerStrings[NUM_TRIGGERS] = {
#define VERSION "0.23"
#ifdef EMBEDDED_6502
-#define NUM_CMDS 20
+#define NUM_CMDS 23
#else
#define NUM_CMDS 19
#endif
@@ -122,6 +129,8 @@ int single;
long trace;
long instructions = 1;
+unsigned int memAddr = 0;
+
unsigned int breakpoints[MAXBKPTS] = {
0,
0,
@@ -160,6 +169,9 @@ char *cmdStrings[NUM_CMDS] = {
"help",
#ifdef EMBEDDED_6502
"regs",
+ "mem",
+ "dis",
+ "write",
#endif
"reset",
"step",
@@ -340,7 +352,7 @@ int logDetails() {
int lookupBreakpoint(char *params) {
int i;
- int n = 0;
+ int n = -1;
sscanf(params, "%x", &n);
// First, look assume n is an address, and try to map to an index
for (i = 0; i < numbkpts; i++) {
@@ -357,6 +369,37 @@ int lookupBreakpoint(char *params) {
}
+#ifdef EMBEDDED_6502
+unsigned int readMem(unsigned int addr) {
+ int i;
+ for (i = 0; i <= 15; i++) {
+ hwCmd(CMD_LOAD_MEM, addr & 1);
+ addr >>= 1;
+ }
+ hwCmd(CMD_RD_MEM, 0);
+ Delay_us(10);
+ return hwRead8(OFFSET_DATA);
+}
+
+void writeMem(unsigned int addr, unsigned int data) {
+ int i;
+ for (i = 0; i <= 7; i++) {
+ hwCmd(CMD_LOAD_MEM, data & 1);
+ data >>= 1;
+ }
+ for (i = 0; i <= 15; i++) {
+ hwCmd(CMD_LOAD_MEM, addr & 1);
+ addr >>= 1;
+ }
+ hwCmd(CMD_WR_MEM, 0);
+}
+
+unsigned int disMem(unsigned int addr) {
+ return disassemble(addr, readMem(addr), readMem(addr + 1), readMem(addr + 2));
+}
+
+#endif
+
/*******************************************
* Commands
*******************************************/
@@ -368,20 +411,22 @@ void doCmdHelp(char *params) {
for (i = 0; i < NUM_CMDS; i++) {
log0(" %s\n", cmdStrings[i]);
}
- log0("Trigger Codes:\n");
- for (i = 0; i < NUM_TRIGGERS; i++) {
- log0(" %X = %s\n", i, triggerStrings[i]);
- }
}
void doCmdAddr() {
- unsigned int i_addr = hwRead16(OFFSET_IAL);
+ memAddr = hwRead16(OFFSET_IAL);
// Update the LCD display
#ifdef LCD
- lcdAddr(i_addr);
+ lcdAddr(memAddr);
#endif
// Update the serial console
- log0("%04X\n", i_addr);
+#ifdef EMBEDDED_6502
+ //log0("%04X\n", i_addr);
+ disMem(memAddr);
+#else
+ log0("%04X\n", memAddr);
+#endif
+ return;
}
void doCmdStep(char *params) {
@@ -430,6 +475,38 @@ void doCmdRegs(char *params) {
log0("PC=%04x; ", hwRead16(OFFSET_REG_PCL));
log0("\n");
}
+
+void doCmdMem(char *params) {
+ int i;
+ sscanf(params, "%x", &memAddr);
+ for (i = 0; i < 0x100; i++) {
+ if ((i & 15) == 0) {
+ log0("%04X ", memAddr + i);
+ }
+ log0("%02X ", readMem(memAddr + i));
+ if ((i & 15) == 15) {
+ log0("\n");
+ }
+ }
+ memAddr += 0x100;
+}
+
+void doCmdDis(char *params) {
+ int i;
+ sscanf(params, "%x", &memAddr);
+ for (i = 0; i < 10; i++) {
+ memAddr = disMem(memAddr);
+ }
+}
+
+void doCmdWrite(char *params) {
+ unsigned int addr;
+ unsigned int data;
+ sscanf(params, "%x %x", &addr, &data);
+ log0("Wr: %04X = %X\n", addr, data);
+ writeMem(addr, data);
+}
+
#endif
void doCmdTrace(char *params) {
@@ -576,9 +653,13 @@ void doCmdWClearW(char *params) {
}
void doCmdTrigger(char *params) {
- unsigned int trigger = -1;
+ int trigger = -1;
int n = lookupBreakpoint(params);
if (n < 0) {
+ log0("Trigger Codes:\n");
+ for (trigger = 0; trigger < NUM_TRIGGERS; trigger++) {
+ log0(" %X = %s\n", trigger, triggerStrings[trigger]);
+ }
return;
}
sscanf(params, "%*x %x", &trigger);
@@ -601,7 +682,7 @@ void shiftBreakpointRegister(unsigned int addr, unsigned int mode, unsigned int
reg |= addr;
// Total size is 26 bits
for (i = 0; i <= 25; i++) {
- hwCmd(CMD_LOAD_REG, reg & 1);
+ hwCmd(CMD_LOAD_BRKPT, reg & 1);
reg >>= 1;
}
}
@@ -609,7 +690,9 @@ void shiftBreakpointRegister(unsigned int addr, unsigned int mode, unsigned int
void doCmdContinue(char *params) {
int i;
int status;
+#ifdef LCD
unsigned int i_addr;
+#endif
// Step the 6502, otherwise the breakpoint happends again immediately
hwCmd(CMD_STEP, 0);
@@ -636,8 +719,8 @@ void doCmdContinue(char *params) {
int cont = 1;
do {
// Update the LCD display
- i_addr = hwRead16(OFFSET_IAL);
#ifdef LCD
+ i_addr = hwRead16(OFFSET_IAL);
lcdAddr(i_addr);
#endif
@@ -647,8 +730,7 @@ void doCmdContinue(char *params) {
hwCmd(CMD_WATCH_READ, 0);
}
if (status & INTERRUPTED_MASK || Serial_ByteRecieved0()) {
- log0("Interrupted at ");
- doCmdAddr();
+ log0("Interrupted\n");
cont = 0;
}
Delay_us(10);
@@ -664,6 +746,9 @@ void doCmdContinue(char *params) {
// Disable breakpoints
hwCmd(CMD_BRKPT_ENABLE, 0);
+
+ // Show current instruction
+ doCmdAddr();
}
@@ -688,6 +773,9 @@ void (*cmdFuncs[NUM_CMDS])(char *params) = {
doCmdHelp,
#ifdef EMBEDDED_6502
doCmdRegs,
+ doCmdMem,
+ doCmdDis,
+ doCmdWrite,
#endif
doCmdReset,
doCmdStep,
diff --git a/firmware/Makefile.cpu b/firmware/Makefile.cpu
index 9df9d23..38f6542 100644
--- a/firmware/Makefile.cpu
+++ b/firmware/Makefile.cpu
@@ -25,7 +25,7 @@ OBJCOPY=avr-objcopy
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
+OBJECTS=AtomBusMon.o hd44780.o status.o disassembler.o
load: avr.bit
# sudo $(PROG) -v -f avr.bit
diff --git a/firmware/disassembler.c b/firmware/disassembler.c
new file mode 100644
index 0000000..3de7009
--- /dev/null
+++ b/firmware/disassembler.c
@@ -0,0 +1,118 @@
+#include "status.h"
+
+enum
+{
+ IMP, IMPA, IMM, ZP, ZPX, ZPY, INDX, INDY, IND, ABS, ABSX, ABSY, IND16, IND1X, BRA
+};
+
+char dopname[256][6] =
+{
+/*00*/ "BRK", "ORA", "---", "---", "TSB", "ORA", "ASL", "---", "PHP", "ORA", "ASL", "---", "TSB", "ORA", "ASL", "---",
+/*10*/ "BPL", "ORA", "ORA", "---", "TRB", "ORA", "ASL", "---", "CLC", "ORA", "INC", "---", "TRB", "ORA", "ASL", "---",
+/*20*/ "JSR", "AND", "---", "---", "BIT", "AND", "ROL", "---", "PLP", "AND", "ROL", "---", "BIT", "AND", "ROL", "---",
+/*30*/ "BMI", "AND", "AND", "---", "BIT", "AND", "ROL", "---", "SEC", "AND", "DEC", "---", "BIT", "AND", "ROL", "---",
+/*40*/ "RTI", "EOR", "---", "---", "---", "EOR", "LSR", "---", "PHA", "EOR", "LSR", "---", "JMP", "EOR", "LSR", "---",
+/*50*/ "BVC", "EOR", "EOR", "---", "---", "EOR", "LSR", "---", "CLI", "EOR", "PHY", "---", "---", "EOR", "LSR", "---",
+/*60*/ "RTS", "ADC", "---", "---", "STZ", "ADC", "ROR", "---", "PLA", "ADC", "ROR", "---", "JMP", "ADC", "ROR", "---",
+/*70*/ "BVS", "ADC", "ADC", "---", "STZ", "ADC", "ROR", "---", "SEI", "ADC", "PLY", "---", "JMP", "ADC", "ROR", "---",
+/*80*/ "BRA", "STA", "---", "---", "STY", "STA", "STX", "---", "DEY", "BIT", "TXA", "---", "STY", "STA", "STX", "---",
+/*90*/ "BCC", "STA", "STA", "---", "STY", "STA", "STX", "---", "TYA", "STA", "TXS", "---", "STZ", "STA", "STZ", "---",
+/*A0*/ "LDY", "LDA", "LDX", "---", "LDY", "LDA", "LDX", "---", "TAY", "LDA", "TAX", "---", "LDY", "LDA", "LDX", "---",
+/*B0*/ "BCS", "LDA", "LDA", "---", "LDY", "LDA", "LDX", "---", "CLV", "LDA", "TSX", "---", "LDY", "LDA", "LDX", "---",
+/*C0*/ "CPY", "CMP", "---", "---", "CPY", "CMP", "DEC", "---", "INY", "CMP", "DEX", "WAI", "CPY", "CMP", "DEC", "---",
+/*D0*/ "BNE", "CMP", "CMP", "---", "---", "CMP", "DEC", "---", "CLD", "CMP", "PHX", "STP", "---", "CMP", "DEC", "---",
+/*E0*/ "CPX", "SBC", "---", "---", "CPX", "SBC", "INC", "---", "INX", "SBC", "NOP", "---", "CPX", "SBC", "INC", "---",
+/*F0*/ "BEQ", "SBC", "SBC", "---", "---", "SBC", "INC", "---", "SED", "SBC", "PLX", "---", "---", "SBC", "INC", "---",
+};
+
+int dopaddr[256] =
+{
+/*00*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
+/*10*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMPA, IMP, ABS, ABSX, ABSX, IMP,
+/*20*/ ABS, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
+/*30*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABSY, IMPA, IMP, ABSX, ABSX, ABSX, IMP,
+/*40*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
+/*50*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
+/*60*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, IND16, ABS, ABS, IMP,
+/*70*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, IND1X, ABSX, ABSX, IMP,
+/*80*/ BRA, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
+/*90*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
+/*A0*/ IMM, INDX, IMM, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
+/*B0*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABSY, IMP, IMP, ABSX, ABSX, ABSY, IMP,
+/*C0*/ IMM, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
+/*D0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
+/*E0*/ IMM, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
+/*F0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
+};
+
+unsigned int disassemble(unsigned int addr, unsigned int op, unsigned int p1, unsigned int p2)
+{
+ unsigned int temp;
+
+ log0("%04X : %s ", addr, dopname[op]);
+ switch (dopaddr[op])
+ {
+ case IMP:
+ log0(" ");
+ break;
+ case IMPA:
+ log0("A ");
+ break;
+ case IMM:
+ log0("#%02X ", p1);
+ addr++;
+ break;
+ case ZP:
+ log0("%02X ", p1);
+ addr++;
+ break;
+ case ZPX:
+ log0("%02X,X ", p1);
+ addr++;
+ break;
+ case ZPY:
+ log0("%02X,Y ", p1);
+ addr++;
+ break;
+ case IND:
+ log0("(%02X) ", p1);
+ addr++;
+ break;
+ case INDX:
+ log0("(%02X,X) ", p1);
+ addr++;
+ break;
+ case INDY:
+ log0("(%02X),Y ", p1);
+ addr++;
+ break;
+ case ABS:
+ log0("%02X%02X ", p2, p1);
+ addr += 2;
+ break;
+ case ABSX:
+ log0("%02X%02X,X ", p2, p1);
+ addr += 2;
+ break;
+ case ABSY:
+ log0("%02X%02X,Y ", p2, p1);
+ addr += 2;
+ break;
+ case IND16:
+ log0("(%02X%02X) ", p2, p1);
+ addr += 2;
+ break;
+ case IND1X:
+ log0("(%02X%02X,X)", p2, p1);
+ addr += 2;
+ break;
+ case BRA:
+ temp = addr + 2 + (signed char)p1;
+ log0("%04X ", temp);
+ addr++;
+ break;
+ }
+ log0("\n");
+ addr++;
+ return addr;
+}
diff --git a/firmware/disassembler.h b/firmware/disassembler.h
new file mode 100644
index 0000000..8afdc26
--- /dev/null
+++ b/firmware/disassembler.h
@@ -0,0 +1,6 @@
+#ifndef __DISASSEMBLE_DEFINES__
+#define __DISASSEMBLE_DEFINES__
+
+unsigned int disassemble(unsigned int addr, unsigned int op, unsigned int p1, unsigned int p2);
+
+#endif
diff --git a/src/AtomCpuMon.vhd b/src/AtomCpuMon.vhd
index 0368ad8..8f702f6 100644
--- a/src/AtomCpuMon.vhd
+++ b/src/AtomCpuMon.vhd
@@ -79,15 +79,21 @@ architecture behavioral of AtomCpuMon is
signal Phi0_c : std_logic;
signal Phi0_d : std_logic;
signal cpu_clk : std_logic;
+ signal busmon_clk : std_logic;
signal Regs : std_logic_vector(63 downto 0);
+ signal memory_rd : std_logic;
+ signal memory_wr : std_logic;
+ signal memory_addr : std_logic_vector(15 downto 0);
+ signal memory_dout : std_logic_vector(7 downto 0);
+ signal memory_din : std_logic_vector(7 downto 0);
begin
mon : entity work.BusMonCore port map (
clock49 => clock49,
Addr => Addr_int,
- Phi2 => Phi0,
+ Phi2 => busmon_clk,
RNW => R_W_n_int,
Sync => Sync_int,
Rdy => Rdy_int,
@@ -107,7 +113,12 @@ begin
tmosi => tmosi,
tdin => tdin,
tcclk => tcclk,
- Regs => Regs
+ Regs => Regs,
+ RdOut => memory_rd,
+ WrOut => memory_wr,
+ AddrOut => memory_addr,
+ DataOut => memory_dout,
+ DataIn => memory_din
);
cpu_t65 : entity work.T65 port map (
@@ -140,12 +151,15 @@ begin
end if;
end process;
- R_W_n <= R_W_n_int;
- Addr <= Addr_int;
+ R_W_n <= '1' when memory_rd = '1' else '0' when memory_wr = '1' else R_W_n_int;
+ Addr <= memory_addr when (memory_rd = '1' or memory_wr = '1') else Addr_int;
Sync <= Sync_int;
- Din <= Data;
- Data <= Dout when Phi0_d = '1' and R_W_n_int = '0' else (others => 'Z');
+ Din <= Data;
+ memory_din <= Data;
+ Data <= memory_dout when cpu_clk = '0' and memory_wr = '1' else
+ Dout when cpu_clk = '0' and R_W_n_int = '0' and memory_rd = '0' else
+ (others => 'Z');
clk_gen : process(clock49)
begin
@@ -157,11 +171,10 @@ begin
end if;
end process;
- Phi1 <= not (Phi0_b or Phi0_d);
- Phi2 <= Phi0_b and Phi0_d;
-
- cpu_clk <= not Phi0_d;
-
+ Phi1 <= not (Phi0_b or Phi0_d);
+ Phi2 <= Phi0_b and Phi0_d;
+ cpu_clk <= not Phi0_d;
+ busmon_clk <= Phi0_d;
end behavioral;
diff --git a/src/BusMonCore.vhd b/src/BusMonCore.vhd
new file mode 100644
index 0000000..c356c22
--- /dev/null
+++ b/src/BusMonCore.vhd
@@ -0,0 +1,447 @@
+--------------------------------------------------------------------------------
+-- Copyright (c) 2015 David Banks
+--
+--------------------------------------------------------------------------------
+-- ____ ____
+-- / /\/ /
+-- /___/ \ /
+-- \ \ \/
+-- \ \
+-- / / Filename : BusMonCore.vhd
+-- /___/ /\ Timestamp : 30/05/2015
+-- \ \ / \
+-- \___\/\___\
+--
+--Design Name: AtomBusMon
+--Device: XC3S250E
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.OhoPack.all ;
+
+
+entity BusMonCore is
+ generic (
+ num_comparators : integer := 8;
+ reg_width : integer := 26;
+ fifo_width : integer := 36
+ );
+ port (
+ clock49 : in std_logic;
+
+ -- 6502 Signals
+ Addr : in std_logic_vector(15 downto 0);
+ Phi2 : in std_logic;
+ RNW : in std_logic;
+ Sync : in std_logic;
+ Rdy : out std_logic;
+ nRST : inout std_logic;
+
+ -- 6502 Registers
+ Regs : in std_logic_vector(63 downto 0);
+
+ -- 6502 Memory Read/Write
+ RdOut : out std_logic;
+ WrOut : 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);
+
+ -- External trigger inputs
+ trig : in std_logic_vector(1 downto 0);
+
+ -- HD44780 LCD
+ lcd_rs : out std_logic;
+ lcd_rw : out std_logic;
+ lcd_e : out std_logic;
+ lcd_db : inout std_logic_vector(7 downto 4);
+
+ -- AVR Serial Port
+ avr_RxD : in std_logic;
+ avr_TxD : out std_logic;
+
+ -- GODIL Switches
+ sw1 : in std_logic;
+ nsw2 : in std_logic;
+
+ -- GODIL LEDs
+ led3 : out std_logic;
+ led6 : out std_logic;
+ led8 : out std_logic;
+
+ -- OHO_DY1 connected to test connector
+ tmosi : out std_logic;
+ tdin : out std_logic;
+ tcclk : out std_logic
+ );
+end BusMonCore;
+
+architecture behavioral of BusMonCore 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(3 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;
+
+ signal memory_rd : std_logic;
+ signal memory_wr : std_logic;
+ signal addr_dout_reg : std_logic_vector(23 downto 0);
+ signal din_reg : std_logic_vector(7 downto 0);
+
+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
+ );
+
+
+ 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) => open,
+ portbout(6) => open,
+ portbout(7) => open,
+
+ -- 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(0) => muxsel(0),
+ portdout(1) => muxsel(1),
+ portdout(2) => muxsel(2),
+ portdout(3) => muxsel(3),
+ portdout(4) => open,
+ portdout(5) => open,
+ portdout(6) => open,
+ portdout(7) => 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
+ din_reg when muxsel = 7 else
+ Regs(7 downto 0) when muxsel = 8 else
+ Regs(15 downto 8) when muxsel = 9 else
+ Regs(23 downto 16) when muxsel = 10 else
+ Regs(31 downto 24) when muxsel = 11 else
+ Regs(39 downto 32) when muxsel = 12 else
+ Regs(47 downto 40) when muxsel = 13 else
+ Regs(55 downto 48) when muxsel = 14 else
+ Regs(63 downto 56) when muxsel = 15 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 stepping
+ -- 001x Enable/Disable breakpoints / watches
+ -- 010x Load breakpoint register
+ -- 011x Reset
+ -- 1000 Single Step
+ -- 1001 FIFO Read
+ -- 1010 FIFO Reset
+ -- 110x Load memory address/data register
+ -- 1110 Read memory
+ -- 1111 Write memory
+
+ risingProcess: 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';
+ memory_rd <= '0';
+ memory_wr <= '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) = "110") then
+ addr_dout_reg <= cmd(0) & addr_dout_reg(addr_dout_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;
+
+ if (cmd(3 downto 0) = "1110") then
+ memory_rd <= '1';
+ end if;
+
+ if (cmd(3 downto 0) = "1111") then
+ memory_wr <= '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;
+
+ fallingProcess: process (Phi2)
+ begin
+ if falling_edge(Phi2) then
+ -- Latch memory read in response to a read command
+ if (memory_rd = '1') then
+ din_reg <= DataIn;
+ end if;
+ end if;
+ end process;
+
+ RdOut <= memory_rd;
+ WrOut <= memory_wr;
+ AddrOut <= addr_dout_reg(23 downto 8);
+ DataOut <= addr_dout_reg(7 downto 0);
+
+end behavioral;
+
+