summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2020-07-18 20:58:31 +0200
committer hap <happppp@users.noreply.github.com>2020-07-18 20:58:31 +0200
commit8bfa5a599fb8942bdaaeda59bcd9a8d56132ea9b (patch)
tree10d6411c9811405b0293cada8c9edf77f2bd9c72
parent5716df3b90022ff46abed1a8e6e24dc4f6a70908 (diff)
6502: nmi is edge triggered
-rw-r--r--src/devices/cpu/m6502/m6502.cpp21
-rw-r--r--src/devices/cpu/m6502/m6502.h2
-rw-r--r--src/devices/cpu/m6502/m740.cpp1
-rw-r--r--src/devices/cpu/m6502/odeco16.lst6
-rw-r--r--src/devices/cpu/m6502/om6502.lst6
-rw-r--r--src/devices/cpu/m6502/om65c02.lst10
-rw-r--r--src/devices/cpu/m6502/om65ce02.lst6
-rw-r--r--src/devices/cpu/m6502/om740.lst6
-rw-r--r--src/devices/cpu/m6502/or65c19.lst8
-rw-r--r--src/devices/cpu/m6502/ost2xxx.lst8
-rw-r--r--src/devices/cpu/m6502/oxavix.lst8
-rw-r--r--src/mame/drivers/saitek_intchess.cpp11
12 files changed, 46 insertions, 47 deletions
diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp
index 7999749153f..f69e672ed31 100644
--- a/src/devices/cpu/m6502/m6502.cpp
+++ b/src/devices/cpu/m6502/m6502.cpp
@@ -31,7 +31,7 @@ m6502_device::m6502_device(const machine_config &mconfig, device_type type, cons
sync_w(*this),
program_config("program", ENDIANNESS_LITTLE, 8, 16),
sprogram_config("decrypted_opcodes", ENDIANNESS_LITTLE, 8, 16), PPC(0), NPC(0), PC(0), SP(0), TMP(0), TMP2(0), A(0), X(0), Y(0), P(0), IR(0), inst_state_base(0), mintf(nullptr),
- inst_state(0), inst_substate(0), icount(0), nmi_state(false), irq_state(false), apu_irq_state(false), v_state(false), irq_taken(false), sync(false), inhibit_interrupts(false)
+ inst_state(0), inst_substate(0), icount(0), nmi_state(false), irq_state(false), apu_irq_state(false), v_state(false), nmi_pending(false), irq_taken(false), sync(false), inhibit_interrupts(false)
{
}
@@ -82,10 +82,11 @@ void m6502_device::init()
save_item(NAME(irq_state));
save_item(NAME(apu_irq_state));
save_item(NAME(v_state));
+ save_item(NAME(nmi_pending));
+ save_item(NAME(irq_taken));
save_item(NAME(inst_state));
save_item(NAME(inst_substate));
save_item(NAME(inst_state_base));
- save_item(NAME(irq_taken));
save_item(NAME(inhibit_interrupts));
set_icountptr(icount);
@@ -103,8 +104,9 @@ void m6502_device::init()
nmi_state = false;
irq_state = false;
apu_irq_state = false;
- irq_taken = false;
v_state = false;
+ nmi_pending = false;
+ irq_taken = false;
inst_state = STATE_RESET;
inst_substate = 0;
inst_state_base = 0;
@@ -118,11 +120,12 @@ void m6502_device::device_reset()
inst_state = STATE_RESET;
inst_substate = 0;
inst_state_base = 0;
- nmi_state = false;
irq_state = false;
+ nmi_state = false;
apu_irq_state = false;
- irq_taken = false;
v_state = false;
+ nmi_pending = false;
+ irq_taken = false;
sync = false;
sync_w(CLEAR_LINE);
inhibit_interrupts = false;
@@ -410,7 +413,11 @@ void m6502_device::execute_set_input(int inputnum, int state)
switch(inputnum) {
case IRQ_LINE: irq_state = state == ASSERT_LINE; break;
case APU_IRQ_LINE: apu_irq_state = state == ASSERT_LINE; break;
- case NMI_LINE: nmi_state = nmi_state || (state == ASSERT_LINE); break;
+ case NMI_LINE:
+ if(!nmi_state && state == ASSERT_LINE)
+ nmi_pending = true;
+ nmi_state = state == ASSERT_LINE;
+ break;
case V_LINE:
if(!v_state && state == ASSERT_LINE)
P |= F_V;
@@ -484,7 +491,7 @@ void m6502_device::prefetch()
sync = false;
sync_w(CLEAR_LINE);
- if((nmi_state || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) {
+ if((nmi_pending || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) {
irq_taken = true;
IR = 0x00;
} else
diff --git a/src/devices/cpu/m6502/m6502.h b/src/devices/cpu/m6502/m6502.h
index 413925efa0d..077de2920ac 100644
--- a/src/devices/cpu/m6502/m6502.h
+++ b/src/devices/cpu/m6502/m6502.h
@@ -122,7 +122,7 @@ protected:
int inst_state, inst_substate;
int icount, bcount, count_before_instruction_step;
bool nmi_state, irq_state, apu_irq_state, v_state;
- bool irq_taken, sync, inhibit_interrupts;
+ bool nmi_pending, irq_taken, sync, inhibit_interrupts;
uint8_t read(uint16_t adr) { return mintf->read(adr); }
uint8_t read_9(uint16_t adr) { return mintf->read_9(adr); }
diff --git a/src/devices/cpu/m6502/m740.cpp b/src/devices/cpu/m6502/m740.cpp
index 684bff6773b..748c48e79cb 100644
--- a/src/devices/cpu/m6502/m740.cpp
+++ b/src/devices/cpu/m6502/m740.cpp
@@ -52,6 +52,7 @@ void m740_device::device_reset()
m_irq_vector = 0xfffc;
apu_irq_state = false;
irq_taken = false;
+ nmi_pending = false;
v_state = false;
sync = false;
inhibit_interrupts = false;
diff --git a/src/devices/cpu/m6502/odeco16.lst b/src/devices/cpu/m6502/odeco16.lst
index 694eb2f3613..53f9e1b1977 100644
--- a/src/devices/cpu/m6502/odeco16.lst
+++ b/src/devices/cpu/m6502/odeco16.lst
@@ -2,7 +2,7 @@
# copyright-holders:Olivier Galibert
# deco 16 opcodes
brk_16_imp
- // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state)
+ // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_pending)
if(irq_taken) {
read_pc_noinc();
} else {
@@ -14,10 +14,10 @@ brk_16_imp
dec_SP();
write(SP, irq_taken ? P & ~F_B : P);
dec_SP();
- if(nmi_state) {
+ if(nmi_pending) {
PC = read_arg(0xfff7);
PC = set_h(PC, read_arg(0xfff6));
- nmi_state = false;
+ nmi_pending = false;
standard_irq_callback(NMI_LINE);
} else {
PC = read_arg(0xfff3);
diff --git a/src/devices/cpu/m6502/om6502.lst b/src/devices/cpu/m6502/om6502.lst
index d34e63c1d81..4026965ffa0 100644
--- a/src/devices/cpu/m6502/om6502.lst
+++ b/src/devices/cpu/m6502/om6502.lst
@@ -259,7 +259,7 @@ bpl_rel
prefetch();
brk_imp
- // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state)
+ // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_pending)
if(irq_taken) {
read_pc_noinc();
} else {
@@ -271,10 +271,10 @@ brk_imp
dec_SP();
write(SP, irq_taken ? P & ~F_B : P);
dec_SP();
- if(nmi_state) {
+ if(nmi_pending) {
PC = read_arg(0xfffa);
PC = set_h(PC, read_arg(0xfffb));
- nmi_state = false;
+ nmi_pending = false;
standard_irq_callback(NMI_LINE);
} else {
PC = read_arg(0xfffe);
diff --git a/src/devices/cpu/m6502/om65c02.lst b/src/devices/cpu/m6502/om65c02.lst
index 3e414cd7bfd..34cc070b6f1 100644
--- a/src/devices/cpu/m6502/om65c02.lst
+++ b/src/devices/cpu/m6502/om65c02.lst
@@ -220,7 +220,7 @@ bra_rel
prefetch();
brk_c_imp
- if(irq_taken || nmi_state) {
+ if(irq_taken || nmi_pending) {
read_pc_noinc();
} else {
read_pc();
@@ -229,12 +229,12 @@ brk_c_imp
dec_SP();
write(SP, PC);
dec_SP();
- write(SP, irq_taken || nmi_state ? P & ~F_B : P);
+ write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
dec_SP();
- if(irq_taken && nmi_state) {
+ if(irq_taken && nmi_pending) {
PC = read_arg(0xfffa);
PC = set_h(PC, read_arg(0xfffb));
- nmi_state = false;
+ nmi_pending = false;
standard_irq_callback(NMI_LINE);
} else {
PC = read_arg(0xfffe);
@@ -766,7 +766,7 @@ tsb_zpg
wai_imp
read_pc_noinc();
read_pc_noinc();
- while(!nmi_state && !irq_state) {
+ while(!nmi_pending && !irq_state) {
eat-all-cycles;
}
prefetch();
diff --git a/src/devices/cpu/m6502/om65ce02.lst b/src/devices/cpu/m6502/om65ce02.lst
index 85648fd610d..e836b45a150 100644
--- a/src/devices/cpu/m6502/om65ce02.lst
+++ b/src/devices/cpu/m6502/om65ce02.lst
@@ -359,12 +359,12 @@ brk_ce_imp
dec_SP_ce();
write(SP, PC);
dec_SP_ce();
- write(SP, irq_taken || nmi_state ? P & ~F_B : P);
+ write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
dec_SP_ce();
- if(nmi_state) {
+ if(nmi_pending) {
PC = read_arg(0xfffa);
PC = set_h(PC, read_arg(0xfffb));
- nmi_state = false;
+ nmi_pending = false;
} else {
PC = read_arg(0xfffe);
PC = set_h(PC, read_arg(0xffff));
diff --git a/src/devices/cpu/m6502/om740.lst b/src/devices/cpu/m6502/om740.lst
index 34652361335..342d224131d 100644
--- a/src/devices/cpu/m6502/om740.lst
+++ b/src/devices/cpu/m6502/om740.lst
@@ -120,7 +120,7 @@ reset740
inst_state = -1;
brk740_imp
- // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state)
+ // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_pending)
if(irq_taken) {
read_pc_noinc();
} else {
@@ -132,10 +132,10 @@ brk740_imp
dec_SP();
write(SP, irq_taken ? P & ~F_B : P);
dec_SP();
- if(nmi_state) {
+ if(nmi_pending) {
PC = read_arg(0xfffa);
PC = set_h(PC, read_arg(0xfffb));
- nmi_state = false;
+ nmi_pending = false;
standard_irq_callback(NMI_LINE);
} else {
PC = read_arg(m_irq_vector);
diff --git a/src/devices/cpu/m6502/or65c19.lst b/src/devices/cpu/m6502/or65c19.lst
index e8314033b9d..47f24f57329 100644
--- a/src/devices/cpu/m6502/or65c19.lst
+++ b/src/devices/cpu/m6502/or65c19.lst
@@ -95,7 +95,7 @@ bas_amr
prefetch();
brk_r_imp
- if(irq_taken || nmi_state) {
+ if(irq_taken || nmi_pending) {
read_pc_noinc();
} else {
read_pc();
@@ -104,12 +104,12 @@ brk_r_imp
dec_SP();
write(SP, PC);
dec_SP();
- write(SP, irq_taken || nmi_state ? P & ~F_B : P);
+ write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
dec_SP();
- if(irq_taken && nmi_state) {
+ if(irq_taken && nmi_pending) {
PC = read_arg(0xfffc);
PC = set_h(PC, read_arg(0xfffd));
- nmi_state = false;
+ nmi_pending = false;
standard_irq_callback(NMI_LINE);
} else {
TMP = get_irq_vector();
diff --git a/src/devices/cpu/m6502/ost2xxx.lst b/src/devices/cpu/m6502/ost2xxx.lst
index 9b30c2e9b05..4468fe14476 100644
--- a/src/devices/cpu/m6502/ost2xxx.lst
+++ b/src/devices/cpu/m6502/ost2xxx.lst
@@ -3,7 +3,7 @@
# m65c02 opcodes, with a twist
brk_st_imp
- if(irq_taken || nmi_state) {
+ if(irq_taken || nmi_pending) {
read_pc_noinc();
} else {
read_pc();
@@ -12,13 +12,13 @@ brk_st_imp
dec_SP();
write(SP, PC);
dec_SP();
- write(SP, irq_taken || nmi_state ? P & ~F_B : P);
+ write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
dec_SP();
set_irq_service(true);
- if(irq_taken && nmi_state) { // NMI is not present on actual parts
+ if(irq_taken && nmi_pending) { // NMI is not present on actual parts
PC = read_vector(0x7ffa);
PC = set_h(PC, read_vector(0x7ffb));
- nmi_state = false;
+ nmi_pending = false;
} else if(irq_taken) {
TMP = acknowledge_irq();
PC = read_vector(0x7ff8 - (TMP << 1));
diff --git a/src/devices/cpu/m6502/oxavix.lst b/src/devices/cpu/m6502/oxavix.lst
index 0f1f60e4221..c45e89e0a61 100644
--- a/src/devices/cpu/m6502/oxavix.lst
+++ b/src/devices/cpu/m6502/oxavix.lst
@@ -40,8 +40,8 @@ retf_imp
prefetch();
brk_xav_imp
- // there is code in soem games to indicate this doesn't always push the far bank to the stack..
- // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state)
+ // there is code in some games to indicate this doesn't always push the far bank to the stack..
+ // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_pending)
if(irq_taken) {
read_pc_noinc();
} else {
@@ -56,7 +56,7 @@ brk_xav_imp
dec_SP();
write_stack(SP, irq_taken ? P & ~F_B : P);
dec_SP();
- if(nmi_state) {
+ if(nmi_pending) {
if (m_vector_callback.isnull())
{
PC = read_arg(0xfffa);
@@ -76,7 +76,7 @@ brk_xav_imp
}
}
- nmi_state = false;
+ nmi_pending = false;
standard_irq_callback(NMI_LINE);
} else {
if (m_vector_callback.isnull())
diff --git a/src/mame/drivers/saitek_intchess.cpp b/src/mame/drivers/saitek_intchess.cpp
index c49b4a4f3f1..faff4fe2fb9 100644
--- a/src/mame/drivers/saitek_intchess.cpp
+++ b/src/mame/drivers/saitek_intchess.cpp
@@ -18,8 +18,6 @@ Hardware notes:
- 4-digit 7seg display
TODO:
-- 6502 CPU core NMI isn't working properly at the moment, it acts like a hold_line,
- m_nmistate can be removed once that is fixed
- colors are estimated from photos (black and white are obvious, but the green
and cyan are not standard 0x00ff00 / 0x00ffff)
- video timing is unknown, sprite offsets are estimated from photos
@@ -101,7 +99,6 @@ private:
u8 m_select = 0;
u8 m_7seg_data = 0;
- bool m_nmistate = false;
};
void intchess_state::machine_start()
@@ -109,7 +106,6 @@ void intchess_state::machine_start()
// register for savestates
save_item(NAME(m_select));
save_item(NAME(m_7seg_data));
- save_item(NAME(m_nmistate));
}
INPUT_CHANGED_MEMBER(intchess_state::reset_button)
@@ -209,12 +205,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(intchess_state::cass_input)
{
// cassette input is tied to NMI
bool state = ((m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) && (m_cass->input() < -0.04);
-
- if (state != m_nmistate)
- {
- m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE);
- m_nmistate = state;
- }
+ m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE);
}