Replace special command with x interrupt control commands

Change-Id: I991171d6923cdc928dd9dbb9823c43aee71661be
This commit is contained in:
David Banks 2021-11-18 14:45:05 +00:00
parent 1244eaf607
commit 3e7bda697c
6 changed files with 206 additions and 78 deletions

View File

@ -16,14 +16,33 @@
#define VERSION "0.996" #define VERSION "0.996"
// The X commands allows the various interrupt inputs to be overridded
// They are named after the data sheet pin name
#if defined(CPU_Z80) #if defined(CPU_Z80)
#define NAME "ICE-Z80" #define NAME "ICE-Z80"
#define XCMD0 "xbusrq"
#define XCMD1 "xint"
#define XCMD2 "xnmi"
#define XCMD3 "xres"
#elif defined(CPU_6502) #elif defined(CPU_6502)
#define NAME "ICE-6502" #define NAME "ICE-6502"
#define XCMD0 "xirq"
#define XCMD1 "xnmi"
#define XCMD2 "xres"
#define XCMD3 "xso "
#elif defined(CPU_65C02) #elif defined(CPU_65C02)
#define NAME "ICE-65C02" #define NAME "ICE-65C02"
#define XCMD0 "xirq"
#define XCMD1 "xnmi"
#define XCMD2 "xres"
#define XCMD3 "xso "
#elif defined(CPU_6809) #elif defined(CPU_6809)
#define NAME "ICE-6809" #define NAME "ICE-6809"
#define XCMD0 "xfiq"
#define XCMD1 "xirq"
#define XCMD2 "xnmi"
#define XCMD3 "xres"
#else #else
#error "Unsupported CPU type" #error "Unsupported CPU type"
#endif #endif
@ -70,7 +89,6 @@ char *cmdStrings[] = {
"load", "load",
"save", "save",
"srec", "srec",
"special",
"reset", "reset",
"trace", "trace",
"blist", "blist",
@ -89,7 +107,11 @@ char *cmdStrings[] = {
"clear", "clear",
"trigger", "trigger",
"timermode", "timermode",
"timeout" "timeout",
XCMD0,
XCMD1,
XCMD2,
XCMD3
}; };
// Must be kept in step with cmdStrings (just above) // Must be kept in step with cmdStrings (just above)
@ -125,7 +147,6 @@ void (*cmdFuncs[])(char *params) = {
doCmdLoad, doCmdLoad,
doCmdSave, doCmdSave,
doCmdSRec, doCmdSRec,
doCmdSpecial,
doCmdReset, doCmdReset,
doCmdTrace, doCmdTrace,
doCmdList, doCmdList,
@ -144,7 +165,11 @@ void (*cmdFuncs[])(char *params) = {
doCmdClear, doCmdClear,
doCmdTrigger, doCmdTrigger,
doCmdTimerMode, doCmdTimerMode,
doCmdTimeout doCmdTimeout,
doCmdXCmd0,
doCmdXCmd1,
doCmdXCmd2,
doCmdXCmd3
}; };
#if defined(EXTENDED_HELP) #if defined(EXTENDED_HELP)
@ -167,6 +192,7 @@ static const char ARGS14[] PROGMEM = "[ <value> ]";
static const char ARGS15[] PROGMEM = "[ <command> ]"; static const char ARGS15[] PROGMEM = "[ <command> ]";
static const char ARGS16[] PROGMEM = "<op1> [ <op2> [ <op3> ] ]"; static const char ARGS16[] PROGMEM = "<op1> [ <op2> [ <op3> ] ]";
static const char ARGS17[] PROGMEM = "[ <source> [ <prescale> [ <reset address> ] ] ]"; static const char ARGS17[] PROGMEM = "[ <source> [ <prescale> [ <reset address> ] ] ]";
static const char ARGS18[] PROGMEM = "e|c|d|f";
static const char * const argsStrings[] PROGMEM = { static const char * const argsStrings[] PROGMEM = {
ARGS00, ARGS00,
@ -187,6 +213,7 @@ static const char * const argsStrings[] PROGMEM = {
ARGS15, ARGS15,
ARGS16, ARGS16,
ARGS17, ARGS17,
ARGS18
}; };
// Must be kept in step with cmdStrings (just above) // Must be kept in step with cmdStrings (just above)
@ -197,7 +224,7 @@ static const uint8_t helpMeta[] PROGMEM = {
17, 15, // help 17, 15, // help
9, 8, // continue 9, 8, // continue
24, 1, // next 24, 1, // next
32, 6, // step 31, 6, // step
27, 7, // regs 27, 7, // regs
12, 10, // dis 12, 10, // dis
16, 7, // flush 16, 7, // flush
@ -207,7 +234,7 @@ static const uint8_t helpMeta[] PROGMEM = {
8, 13, // compare 8, 13, // compare
22, 1, // mem 22, 1, // mem
26, 2, // rd 26, 2, // rd
43, 3, // wr 42, 3, // wr
#if defined(CPU_Z80) #if defined(CPU_Z80)
20, 1, // io 20, 1, // io
19, 2, // in 19, 2, // in
@ -218,30 +245,33 @@ static const uint8_t helpMeta[] PROGMEM = {
15, 16, // exec 15, 16, // exec
23, 14, // mode 23, 14, // mode
#endif #endif
33, 12, // test 32, 12, // test
21, 0, // load 21, 0, // load
29, 9, // save 29, 9, // save
31, 7, // srec 30, 7, // srec
30, 14, // special
28, 7, // reset 28, 7, // reset
36, 6, // trace 35, 6, // trace
1, 7, // blist 1, 7, // blist
6, 4, // breakx 6, 4, // breakx
42, 4, // watchx 41, 4, // watchx
4, 4, // breakr 4, 4, // breakr
40, 4, // watchr 39, 4, // watchr
5, 4, // breakw 5, 4, // breakw
41, 4, // watchw 40, 4, // watchw
#if defined(CPU_Z80) #if defined(CPU_Z80)
2, 4, // breaki 2, 4, // breaki
38, 4, // watchi 37, 4, // watchi
3, 4, // breako 3, 4, // breako
39, 4, // watcho 38, 4, // watcho
#endif #endif
7, 0, // clear 7, 0, // clear
37, 5, // trigger 36, 5, // trigger
35, 17, // timermode 34, 17, // timermode
34, 14, // timeout 33, 14, // timeout
43, 18, // xcmd0
44, 18, // xcmd1
45, 18, // xcmd2
46, 18, // xcmd3
0, 0 0, 0
}; };
@ -286,8 +316,8 @@ static const uint8_t helpMeta[] PROGMEM = {
// 011xx1 Unused // 011xx1 Unused
// 011x1x Unused // 011x1x Unused
// 0111xx Unused // 0111xx Unused
// 100xxx Special // 10xxxx Int Ctrl
// 1010xx Timer Mode // 1100xx Timer Mode
// 00 - count cpu cycles where clken = 1 and CountCycle = 1 // 00 - count cpu cycles where clken = 1 and CountCycle = 1
// 01 - count cpu cycles where clken = 1 (ignoring CountCycle) // 01 - count cpu cycles where clken = 1 (ignoring CountCycle)
// 10 - free running timer, using busmon_clk as the source // 10 - free running timer, using busmon_clk as the source
@ -310,8 +340,8 @@ static const uint8_t helpMeta[] PROGMEM = {
#define CMD_WR_IO 0x16 #define CMD_WR_IO 0x16
#define CMD_WR_IO_INC 0x17 #define CMD_WR_IO_INC 0x17
#define CMD_EXEC_GO 0x18 #define CMD_EXEC_GO 0x18
#define CMD_SPECIAL 0x20 #define CMD_INT_CTRL 0x20
#define CMD_TIMER_MODE 0x28 #define CMD_TIMER_MODE 0x30
/******************************************************** /********************************************************
* AVR Status Register Definitions * AVR Status Register Definitions
@ -609,6 +639,24 @@ static const char * triggerStrings[NUM_TRIGGERS] = {
#define TRIGGER_UNDEFINED 31 #define TRIGGER_UNDEFINED 31
/********************************************************
* Interrupt controls
********************************************************/
static const uint8_t cmd_map[] = { 1, 3, 0, 2 };
static const char INTCTRL0[] PROGMEM = "Enabled";
static const char INTCTRL1[] PROGMEM = "Conditional";
static const char INTCTRL2[] PROGMEM = "Forced";
static const char INTCTRL3[] PROGMEM = "Disabled";
static const char *int_ctrl_strings[] = {
INTCTRL0,
INTCTRL1,
INTCTRL2,
INTCTRL3
};
/******************************************************** /********************************************************
* Other global variables * Other global variables
********************************************************/ ********************************************************/
@ -637,15 +685,16 @@ uint8_t cmd_id = 0xff;
#define MASK_CLOCK_ERROR 1 #define MASK_CLOCK_ERROR 1
#define MASK_TIMEOUT_ERROR 2 #define MASK_TIMEOUT_ERROR 2
// Current special setting
uint8_t special = 0x00;
// Current timer mode setting // Current timer mode setting
uint8_t timer_mode = 0x00; uint8_t timer_mode = 0x00;
uint8_t timer_prescale = 0x01; uint8_t timer_prescale = 0x01;
addr_t timer_resetaddr = 0xffff; addr_t timer_resetaddr = 0xffff;
unsigned long timer_offset = 0; unsigned long timer_offset = 0;
// Current interrupts controls
uint8_t int_ctrl = 0;
/******************************************************** /********************************************************
* User Command Processor * User Command Processor
********************************************************/ ********************************************************/
@ -2032,31 +2081,50 @@ void doCmdSRec(char *params) {
} }
} }
void logSpecial(char *function, uint8_t value) { void set_int_ctrl(uint8_t offset, char *params) {
logs(function); // (C) 01 Conditional
if (value) { // (D) 11 Disabled
logstr(" inhibited\n"); // (E) 00 Enabled
} else { // (F) 10 Forced
logstr(" enabled\n"); while (*params == ' ') {
} params++;
}
if (!*params) {
uint8_t tmp = int_ctrl;
for (int i = 0; i < 4; i++) {
logs(cmdStrings[NUM_CMDS - 4 + i]);
logstr(" = ");
logpgmstr(int_ctrl_strings[tmp & 3]);
logc('\n');
tmp >>= 2;
}
} else {
*params &= 0xdf;
if (*params >= 'C' && *params <= 'F') {
uint8_t val = cmd_map[*params - 'C'];
hwCmd(CMD_INT_CTRL, (offset << 1) | val);
int_ctrl &= (0x03 << offset) ^ 0xFF;
int_ctrl |= (val << offset);
} else {
logstr("Illegal option\n");
}
}
} }
void doCmdSpecial(char *params) { void doCmdXCmd0(char *params) {
uint8_t tmp = 0xff; set_int_ctrl(0, params);
parsehex2(params, &tmp); }
#if defined(CPU_6809)
if (tmp <= 7) { void doCmdXCmd1(char *params) {
#else set_int_ctrl(2, params);
if (tmp <= 3) { }
#endif
special = tmp; void doCmdXCmd2(char *params) {
hwCmd(CMD_SPECIAL, special); set_int_ctrl(4, params);
} }
#if defined(CPU_6809)
logSpecial("FIRQ", special & 4); void doCmdXCmd3(char *params) {
#endif set_int_ctrl(6, params);
logSpecial("NMI", special & 2);
logSpecial("IRQ", special & 1);
} }
void doCmdTimerMode(char *params) { void doCmdTimerMode(char *params) {

View File

@ -76,7 +76,6 @@ void doCmdStep(char *params);
void doCmdTest(char *params); void doCmdTest(char *params);
void doCmdSave(char *params); void doCmdSave(char *params);
void doCmdSRec(char *params); void doCmdSRec(char *params);
void doCmdSpecial(char *params);
void doCmdTimerMode(char *params); void doCmdTimerMode(char *params);
void doCmdTimeout(char *params); void doCmdTimeout(char *params);
void doCmdTrace(char *params); void doCmdTrace(char *params);
@ -88,5 +87,9 @@ void doCmdWatchWrIO(char *params);
void doCmdWatchWrMem(char *params); void doCmdWatchWrMem(char *params);
void doCmdWriteIO(char *params); void doCmdWriteIO(char *params);
void doCmdWriteMem(char *params); void doCmdWriteMem(char *params);
void doCmdXCmd0(char *params);
void doCmdXCmd1(char *params);
void doCmdXCmd2(char *params);
void doCmdXCmd3(char *params);
#endif #endif

View File

@ -71,8 +71,8 @@ entity BusMonCore is
DataIn : in std_logic_vector(7 downto 0); DataIn : in std_logic_vector(7 downto 0);
Done : in std_logic; Done : in std_logic;
-- Special outputs (function is CPU specific) -- External Interrupt Control
Special : out std_logic_vector(2 downto 0); int_ctrl : out std_logic_vector(7 downto 0) := x"00";
-- Single Step interface -- Single Step interface
SS_Single : out std_logic; SS_Single : out std_logic;
@ -459,8 +459,8 @@ begin
-- 0111xx Unused -- 0111xx Unused
-- 011x1x Unused -- 011x1x Unused
-- 011xx1 Unused -- 011xx1 Unused
-- 100xxx Special -- 10xxxx Int Ctrl
-- 1010xx Timer Mode -- 1100xx Timer Mode
-- 00 - count cpu cycles where clken = 1 and CountCycle = 1 -- 00 - count cpu cycles where clken = 1 and CountCycle = 1
-- 01 - count cpu cycles where clken = 1 (ignoring CountCycle) -- 01 - count cpu cycles where clken = 1 (ignoring CountCycle)
-- 10 - free running timer, using busmon_clk as the source -- 10 - free running timer, using busmon_clk as the source
@ -551,11 +551,11 @@ begin
exec <= '1'; exec <= '1';
end if; end if;
if (cmd(5 downto 3) = "100") then if (cmd(5 downto 4) = "10") then
Special <= cmd(2 downto 0); int_ctrl(to_integer(unsigned(cmd(3 downto 2))) * 2 + 1 downto to_integer(unsigned(cmd(3 downto 2))) * 2) <= cmd(1 downto 0);
end if; end if;
if (cmd(5 downto 2) = "1010") then if (cmd(5 downto 2) = "1100") then
timer_mode <= cmd(1 downto 0); timer_mode <= cmd(1 downto 0);
end if; end if;

View File

@ -124,7 +124,7 @@ architecture behavioral of MC6809CpuMon is
signal SS_Single : std_logic; signal SS_Single : std_logic;
signal SS_Step : std_logic; signal SS_Step : std_logic;
signal CountCycle : std_logic; signal CountCycle : std_logic;
signal special : std_logic_vector(2 downto 0); signal int_ctrl : std_logic_vector(7 downto 0);
signal LIC_int : std_logic; signal LIC_int : std_logic;
@ -140,9 +140,10 @@ architecture behavioral of MC6809CpuMon is
signal data_wr : std_logic; signal data_wr : std_logic;
signal nRSTout : std_logic; signal nRSTout : std_logic;
signal NMI_n_masked : std_logic;
signal IRQ_n_masked : std_logic;
signal FIRQ_n_masked : std_logic; signal FIRQ_n_masked : std_logic;
signal IRQ_n_masked : std_logic;
signal NMI_n_masked : std_logic;
signal RES_n_masked : std_logic;
begin begin
@ -184,7 +185,7 @@ begin
WrIO_n => '1', WrIO_n => '1',
Sync => Sync_int, Sync => Sync_int,
Rdy => open, Rdy => open,
nRSTin => RES_n, nRSTin => RES_n_masked,
nRSTout => cpu_reset_n, nRSTout => cpu_reset_n,
CountCycle => CountCycle, CountCycle => CountCycle,
trig => trig, trig => trig,
@ -207,14 +208,28 @@ begin
DataOut => memory_dout, DataOut => memory_dout,
DataIn => memory_din, DataIn => memory_din,
Done => memory_done, Done => memory_done,
Special => special, int_ctrl => int_ctrl,
SS_Step => SS_Step, SS_Step => SS_Step,
SS_Single => SS_Single SS_Single => SS_Single
); );
FIRQ_n_masked <= FIRQ_n or special(2); -- The two int control bits work as follows
NMI_n_masked <= NMI_n or special(1); -- 00 -> IRQ_n (enabled)
IRQ_n_masked <= IRQ_n or special(0); -- 01 -> IRQ_n or SS_Single (enabled when free-running)
-- 10 -> 0 (forced)
-- 11 -> 1 (disabled)
FIRQ_n_masked <= int_ctrl(0) when int_ctrl(1) = '1' else
FIRQ_n or (int_ctrl(0) and SS_single);
IRQ_n_masked <= int_ctrl(2) when int_ctrl(3) = '1' else
IRQ_n or (int_ctrl(2) and SS_single);
NMI_n_masked <= int_ctrl(4) when int_ctrl(5) = '1' else
NMI_n or (int_ctrl(4) and SS_single);
RES_n_masked <= int_ctrl(6) when int_ctrl(7) = '1' else
RES_n or (int_ctrl(6) and SS_single);
-- The CPU is slightly pipelined and the register update of the last -- The CPU is slightly pipelined and the register update of the last
-- instruction overlaps with the opcode fetch of the next instruction. -- instruction overlaps with the opcode fetch of the next instruction.

View File

@ -100,7 +100,7 @@ architecture behavioral of MOS6502CpuMonCore is
signal SS_Step : std_logic; signal SS_Step : std_logic;
signal SS_Step_held : std_logic; signal SS_Step_held : std_logic;
signal CountCycle : std_logic; signal CountCycle : std_logic;
signal special : std_logic_vector(2 downto 0); signal int_ctrl : std_logic_vector(7 downto 0);
signal memory_rd : std_logic; signal memory_rd : std_logic;
signal memory_rd1 : std_logic; signal memory_rd1 : std_logic;
@ -111,8 +111,11 @@ architecture behavioral of MOS6502CpuMonCore is
signal memory_din : std_logic_vector(7 downto 0); signal memory_din : std_logic_vector(7 downto 0);
signal memory_done : std_logic; signal memory_done : std_logic;
signal NMI_n_masked : std_logic;
signal IRQ_n_masked : std_logic; signal IRQ_n_masked : std_logic;
signal NMI_n_masked : std_logic;
signal Res_n_masked : std_logic;
signal SO_n_masked : std_logic;
signal exec : std_logic; signal exec : std_logic;
signal exec_held : std_logic; signal exec_held : std_logic;
@ -139,7 +142,7 @@ begin
WrIO_n => '1', WrIO_n => '1',
Sync => Sync_mon, Sync => Sync_mon,
Rdy => open, Rdy => open,
nRSTin => Res_n, nRSTin => Res_n_masked,
nRSTout => cpu_reset_n, nRSTout => cpu_reset_n,
CountCycle => CountCycle, CountCycle => CountCycle,
trig => trig, trig => trig,
@ -163,7 +166,7 @@ begin
DataOut => memory_dout, DataOut => memory_dout,
DataIn => memory_din, DataIn => memory_din,
Done => Done_mon, Done => Done_mon,
Special => special, int_ctrl => int_ctrl,
SS_Step => SS_Step, SS_Step => SS_Step,
SS_Single => SS_Single SS_Single => SS_Single
); );
@ -173,8 +176,24 @@ begin
Done_mon <= Rdy and memory_done; Done_mon <= Rdy and memory_done;
Data <= Din when R_W_n_int = '1' else Dout_int; Data <= Din when R_W_n_int = '1' else Dout_int;
NMI_n_masked <= NMI_n or special(1);
IRQ_n_masked <= IRQ_n or special(0); -- The two int control bits work as follows
-- 00 -> IRQ_n (enabled)
-- 01 -> IRQ_n or SS_Single (enabled when free-running)
-- 10 -> 0 (forced)
-- 11 -> 1 (disabled)
IRQ_n_masked <= int_ctrl(0) when int_ctrl(1) = '1' else
IRQ_n or (int_ctrl(0) and SS_single);
NMI_n_masked <= int_ctrl(2) when int_ctrl(3) = '1' else
NMI_n or (int_ctrl(2) and SS_single);
Res_n_masked <= int_ctrl(4) when int_ctrl(5) = '1' else
Res_n or (int_ctrl(4) and SS_single);
SO_n_masked <= int_ctrl(6) when int_ctrl(7) = '1' else
SO_n or (int_ctrl(6) and SS_single);
-- The CPU is slightly pipelined and the register update of the last -- The CPU is slightly pipelined and the register update of the last
-- instruction overlaps with the opcode fetch of the next instruction. -- instruction overlaps with the opcode fetch of the next instruction.
@ -209,7 +228,7 @@ begin
inst_t65: entity work.T65 port map ( inst_t65: entity work.T65 port map (
mode => "00", mode => "00",
Abort_n => '1', Abort_n => '1',
SO_n => SO_n, SO_n => SO_n_masked,
Res_n => cpu_reset_n, Res_n => cpu_reset_n,
Enable => cpu_clken_ss, Enable => cpu_clken_ss,
Clk => cpu_clk, Clk => cpu_clk,

View File

@ -116,7 +116,7 @@ type state_type is (idle, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa, rd_t2, r
signal SS_Step : std_logic; signal SS_Step : std_logic;
signal SS_Step_held : std_logic; signal SS_Step_held : std_logic;
signal CountCycle : std_logic; signal CountCycle : std_logic;
signal special : std_logic_vector(2 downto 0); signal int_ctrl : std_logic_vector(7 downto 0);
signal skipNextOpcode : std_logic; signal skipNextOpcode : std_logic;
signal Regs : std_logic_vector(255 downto 0); signal Regs : std_logic_vector(255 downto 0);
@ -150,6 +150,7 @@ type state_type is (idle, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa, rd_t2, r
signal BUSRQ_n_sync : std_logic; signal BUSRQ_n_sync : std_logic;
signal INT_n_sync : std_logic; signal INT_n_sync : std_logic;
signal NMI_n_sync : std_logic; signal NMI_n_sync : std_logic;
signal RESET_n_sync : std_logic;
signal Read_n : std_logic; signal Read_n : std_logic;
signal Read_n0 : std_logic; signal Read_n0 : std_logic;
@ -218,7 +219,7 @@ begin
WrIO_n => WriteIO_n, WrIO_n => WriteIO_n,
Sync => Sync, Sync => Sync,
Rdy => open, Rdy => open,
nRSTin => RESET_n, nRSTin => RESET_n_sync,
nRSTout => cpu_reset_n, nRSTout => cpu_reset_n,
CountCycle => CountCycle, CountCycle => CountCycle,
trig => trig, trig => trig,
@ -242,7 +243,7 @@ begin
DataOut => memory_dout, DataOut => memory_dout,
DataIn => memory_din, DataIn => memory_din,
Done => memory_done, Done => memory_done,
Special => special, int_ctrl => int_ctrl,
SS_Single => SS_Single, SS_Single => SS_Single,
SS_Step => SS_Step SS_Step => SS_Step
); );
@ -283,9 +284,31 @@ begin
int_gen : process(CLK_n) int_gen : process(CLK_n)
begin begin
if rising_edge(CLK_n) then if rising_edge(CLK_n) then
BUSRQ_n_sync <= BUSRQ_n;
NMI_n_sync <= NMI_n or special(1); if int_ctrl(1) = '1' then
INT_n_sync <= INT_n or special(0); BUSRQ_n_sync <= int_ctrl(0);
else
BUSRQ_n_sync <= BUSRQ_n or (int_ctrl(0) and SS_single);
end if;
if int_ctrl(3) = '1' then
INT_n_sync <= int_ctrl(2);
else
INT_n_sync <= INT_n or (int_ctrl(2) and SS_single);
end if;
if int_ctrl(5) = '1' then
NMI_n_sync <= int_ctrl(4);
else
NMI_n_sync <= NMI_n or (int_ctrl(4) and SS_single);
end if;
if int_ctrl(7) = '1' then
RESET_n_sync <= int_ctrl(6);
else
RESET_n_sync <= RESET_n or (int_ctrl(6) and SS_single);
end if;
end if; end if;
end process; end process;
@ -401,7 +424,7 @@ begin
BUSAK_n <= BUSAK_n_int when state = idle else mon_busak_n; BUSAK_n <= BUSAK_n_int when state = idle else mon_busak_n;
-- Force the address and databus to tristate when reset is asserted -- Force the address and databus to tristate when reset is asserted
tristate_ad_n <= '0' when RESET_n = '0' else tristate_ad_n <= '0' when RESET_n_sync = '0' else
BUSAK_n_int when state = idle else BUSAK_n_int when state = idle else
mon_busak_n1; mon_busak_n1;