6502: Implemented go command (#12)

Change-Id: I35f3e02c54f87f19e9479985d2783e91fc681e40
This commit is contained in:
David Banks 2019-11-14 16:27:19 +00:00
parent 0035e124cd
commit e8c34bbed7
4 changed files with 98 additions and 35 deletions

View File

@ -50,6 +50,9 @@ char *cmdStrings[] = {
"dis",
"flush",
"fill",
#if defined(CPU_6502) || defined(CPU_65C02)
"go",
#endif
"crc",
"copy",
"compare",
@ -98,6 +101,9 @@ void (*cmdFuncs[])(char *params) = {
doCmdDis,
doCmdFlush,
doCmdFill,
#if defined(CPU_6502) || defined(CPU_65C02)
doCmdGo,
#endif
doCmdCrc,
doCmdCopy,
doCmdCompare,
@ -174,49 +180,52 @@ static const char * const argsStrings[] PROGMEM = {
// Must be kept in step with cmdStrings (just above)
static const uint8_t helpMeta[] PROGMEM = {
#if defined(COMMAND_HISTORY)
16, 7, // history
17, 7, // history
#endif
15, 15, // help
16, 15, // help
9, 8, // continue
21, 7, // next
29, 6, // step
24, 7, // regs
22, 7, // next
30, 6, // step
25, 7, // regs
12, 10, // dis
14, 7, // flush
15, 7, // flush
13, 11, // fill
#if defined(CPU_6502) || defined(CPU_65C02)
14, 0, // go
#endif
11, 9, // crc
10, 13, // copy
8, 13, // compare
20, 1, // mem
23, 2, // rd
38, 3, // wr
21, 1, // mem
24, 2, // rd
39, 3, // wr
#if defined(CPU_Z80)
18, 1, // io
17, 2, // in
22, 3, // out
19, 1, // io
18, 2, // in
23, 3, // out
#endif
30, 12, // test
19, 0, // load
26, 9, // save
28, 7, // srec
27, 14, // special
25, 7, // reset
31, 6, // trace
31, 12, // test
20, 0, // load
27, 9, // save
29, 7, // srec
28, 14, // special
26, 7, // reset
32, 6, // trace
1, 7, // blist
6, 4, // breakx
37, 4, // watchx
38, 4, // watchx
4, 4, // breakr
35, 4, // watchr
36, 4, // watchr
5, 4, // breakw
36, 4, // watchw
37, 4, // watchw
#if defined(CPU_Z80)
2, 4, // breaki
33, 4, // watchi
3, 4, // breako
34, 4, // watcho
35, 4, // watcho
#endif
7, 0, // clear
32, 5, // trigger
33, 5, // trigger
0, 0
};
@ -263,7 +272,10 @@ static const uint8_t helpMeta[] PROGMEM = {
// 10101 Read IO and Auto Inc Address
// 10110 Write IO
// 10111 Write IO and Auto Inc Address
// 11xxx Unused
// 11000 Exec Go
// 11xx1 Unused
// 11x1x Unused
// 111xx Unused
#define CMD_SINGLE_ENABLE 0x00
#define CMD_BRKPT_ENABLE 0x02
@ -281,6 +293,7 @@ static const uint8_t helpMeta[] PROGMEM = {
#define CMD_RD_IO_INC 0x15
#define CMD_WR_IO 0x16
#define CMD_WR_IO_INC 0x17
#define CMD_EXEC_GO 0x18
/********************************************************
* AVR Status Register Definitions
@ -1451,6 +1464,19 @@ void doCmdFill(char *params) {
}
}
#if defined(CPU_6502) || defined(CPU_65C02)
void doCmdGo(char *params) {
addr_t addr;
params = parsehex4(params, &addr);
loadData(0x4C);
loadAddr(addr);
hwCmd(CMD_EXEC_GO, 0);
logAddr();
}
#endif
void doCmdCrc(char *params) {
long i;
uint8_t j;

View File

@ -55,6 +55,7 @@ void doCmdCrc(char *params);
void doCmdDis(char *params);
void doCmdFlush(char *params);
void doCmdFill(char *params);
void doCmdGo(char *params);
void doCmdHelp(char *params);
#if defined(COMMAND_HISTORY)
void doCmdHistory(char *params);

View File

@ -65,6 +65,7 @@ entity BusMonCore is
WrMemOut : out std_logic;
RdIOOut : out std_logic;
WrIOOut : out std_logic;
ExecOut : 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);
@ -164,6 +165,7 @@ architecture behavioral of BusMonCore is
signal memory_wr : std_logic;
signal io_rd : std_logic;
signal io_wr : std_logic;
signal exec : std_logic;
signal addr_dout_reg : std_logic_vector(23 downto 0);
signal din_reg : std_logic_vector(7 downto 0);
@ -448,7 +450,10 @@ begin
-- 10101 Read IO and Auto Inc Address
-- 10110 Write IO
-- 10111 Write IO and Auto Inc Address
-- 11xxx Unused
-- 11000 Exec Go
-- 111xx Unused
-- 11x1x Unused
-- 11xx1 Unused
cpuProcess: process (busmon_clk)
begin
@ -471,6 +476,7 @@ begin
memory_wr <= '0';
io_rd <= '0';
io_wr <= '0';
exec <= '0';
SS_Step <= '0';
if (cmd_edge2 /= cmd_edge1) then
if (cmd(4 downto 1) = "0000") then
@ -521,6 +527,10 @@ begin
auto_inc <= cmd(0);
end if;
if (cmd(4 downto 0) = "11000") then
exec <= '1';
end if;
-- Acknowlege certain commands immediately
if cmd(4) = '0' then
cmd_ack <= not cmd_ack;
@ -595,6 +605,7 @@ begin
AddrOut <= addr_dout_reg(23 downto 8);
DataOut <= addr_dout_reg(7 downto 0);
SS_Single <= single;
ExecOut <= exec;
-- Reset Logic
-- Generate a short (~1ms @ 1MHz) power up reset pulse

View File

@ -73,12 +73,13 @@ end MOS6502CpuMonCore;
architecture behavioral of MOS6502CpuMonCore is
type state_type is (idle, nop0, nop1, rd, wr);
type state_type is (idle, nop0, nop1, rd, wr, exec1, exec2);
signal state : state_type;
signal cpu_clken_ss : std_logic;
signal Data : std_logic_vector(7 downto 0);
signal Din_int : std_logic_vector(7 downto 0);
signal Dout_int : std_logic_vector(7 downto 0);
signal R_W_n_int : std_logic;
signal Rd_n_int : std_logic;
@ -111,6 +112,9 @@ architecture behavioral of MOS6502CpuMonCore is
signal NMI_n_masked : std_logic;
signal IRQ_n_masked : std_logic;
signal exec : std_logic;
signal exec_held : std_logic;
begin
mon : entity work.BusMonCore
@ -151,6 +155,7 @@ begin
WrMemOut => memory_wr,
RdIOOut => open,
WrIOOut => open,
ExecOut => exec,
AddrOut => memory_addr,
DataOut => memory_dout,
DataIn => memory_din,
@ -192,7 +197,7 @@ begin
Regs1( 63 downto 48) <= last_PC;
Regs1(255 downto 64) <= (others => '0');
cpu_clken_ss <= '1' when Rdy = '1' and (state = idle) and cpu_clken = '1' else '0';
cpu_clken_ss <= '1' when Rdy = '1' and (state = idle or state = exec1 or state = exec2) and cpu_clken = '1' else '0';
GenT65Core: if UseT65Core generate
inst_t65: entity work.T65 port map (
@ -208,7 +213,7 @@ begin
R_W_n => R_W_n_int,
Sync => Sync_int,
A => Addr_int,
DI => Din,
DI => Din_int,
DO => Dout_int,
Regs => Regs
);
@ -221,7 +226,7 @@ begin
enable => cpu_clken_ss,
nmi_n => NMI_n_masked,
irq_n => IRQ_n_masked,
di => unsigned(Din),
di => unsigned(Din_int),
do => cpu_dout_us,
addr => cpu_addr_us,
nwe => R_W_n_int,
@ -233,6 +238,11 @@ begin
Addr_int(15 downto 0) <= std_logic_vector(cpu_addr_us);
end generate;
Din_int <= memory_dout( 7 downto 0) when state = idle and Sync_int = '1' and exec_held = '1' else
memory_addr( 7 downto 0) when state = exec1 else
memory_addr(15 downto 8) when state = exec2 else
Din;
men_access_machine : process(cpu_clk, cpu_reset_n)
begin
if cpu_reset_n = '0' then
@ -255,12 +265,21 @@ begin
elsif state = wr then
memory_wr1 <= '0';
end if;
if exec = '1' then
exec_held <= '1';
elsif state = exec1 then
exec_held <= '0';
end if;
if cpu_clken = '1' and Rdy = '1' then
case state is
-- idle is when the CPU is running normally
when idle =>
if Sync_int = '1' and SS_Single = '1' then
state <= nop0;
if Sync_int = '1' then
if exec_held = '1' then
state <= exec1;
elsif SS_Single = '1' then
state <= nop0;
end if;
end if;
-- nop0 is the first state entered when the CPU is paused
when nop0 =>
@ -268,7 +287,7 @@ begin
state <= rd;
elsif memory_wr1 = '1' then
state <= wr;
elsif SS_Step_held = '1' then
elsif SS_Step_held = '1' or exec_held = '1' then
state <= idle;
else
state <= nop1;
@ -282,6 +301,12 @@ begin
-- wr is a monitor initiated write cycle
when wr =>
state <= nop0;
-- exec1 is the LSB of a forced JMP
when exec1 =>
state <= exec2;
-- exec2 is the MSB of a forced JMP
when exec2 =>
state <= idle;
end case;
end if;
end if;
@ -289,7 +314,7 @@ begin
-- Only count cycles when the 6502 is actually running
-- TODO: Should this be qualified with cpu_clken and rdy?
CountCycle <= '1' when state = idle else '0';
CountCycle <= '1' when state = idle or state = exec1 or state = exec2 else '0';
R_W_n <= R_W_n_int when state = idle else
'0' when state = wr else
@ -308,7 +333,7 @@ begin
-- Data is captured by the bus monitor on the rising edge of cpu_clk
-- that sees done = 1.
memory_done <= '1' when state = rd or state = wr else '0';
memory_done <= '1' when state = rd or state = wr or state = exec2 else '0';
memory_din <= Din;