mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
6502: nmi is edge triggered
This commit is contained in:
parent
5716df3b90
commit
8bfa5a599f
@ -31,7 +31,7 @@ m6502_device::m6502_device(const machine_config &mconfig, device_type type, cons
|
|||||||
sync_w(*this),
|
sync_w(*this),
|
||||||
program_config("program", ENDIANNESS_LITTLE, 8, 16),
|
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),
|
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(irq_state));
|
||||||
save_item(NAME(apu_irq_state));
|
save_item(NAME(apu_irq_state));
|
||||||
save_item(NAME(v_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_state));
|
||||||
save_item(NAME(inst_substate));
|
save_item(NAME(inst_substate));
|
||||||
save_item(NAME(inst_state_base));
|
save_item(NAME(inst_state_base));
|
||||||
save_item(NAME(irq_taken));
|
|
||||||
save_item(NAME(inhibit_interrupts));
|
save_item(NAME(inhibit_interrupts));
|
||||||
|
|
||||||
set_icountptr(icount);
|
set_icountptr(icount);
|
||||||
@ -103,8 +104,9 @@ void m6502_device::init()
|
|||||||
nmi_state = false;
|
nmi_state = false;
|
||||||
irq_state = false;
|
irq_state = false;
|
||||||
apu_irq_state = false;
|
apu_irq_state = false;
|
||||||
irq_taken = false;
|
|
||||||
v_state = false;
|
v_state = false;
|
||||||
|
nmi_pending = false;
|
||||||
|
irq_taken = false;
|
||||||
inst_state = STATE_RESET;
|
inst_state = STATE_RESET;
|
||||||
inst_substate = 0;
|
inst_substate = 0;
|
||||||
inst_state_base = 0;
|
inst_state_base = 0;
|
||||||
@ -118,11 +120,12 @@ void m6502_device::device_reset()
|
|||||||
inst_state = STATE_RESET;
|
inst_state = STATE_RESET;
|
||||||
inst_substate = 0;
|
inst_substate = 0;
|
||||||
inst_state_base = 0;
|
inst_state_base = 0;
|
||||||
nmi_state = false;
|
|
||||||
irq_state = false;
|
irq_state = false;
|
||||||
|
nmi_state = false;
|
||||||
apu_irq_state = false;
|
apu_irq_state = false;
|
||||||
irq_taken = false;
|
|
||||||
v_state = false;
|
v_state = false;
|
||||||
|
nmi_pending = false;
|
||||||
|
irq_taken = false;
|
||||||
sync = false;
|
sync = false;
|
||||||
sync_w(CLEAR_LINE);
|
sync_w(CLEAR_LINE);
|
||||||
inhibit_interrupts = false;
|
inhibit_interrupts = false;
|
||||||
@ -410,7 +413,11 @@ void m6502_device::execute_set_input(int inputnum, int state)
|
|||||||
switch(inputnum) {
|
switch(inputnum) {
|
||||||
case IRQ_LINE: irq_state = state == ASSERT_LINE; break;
|
case IRQ_LINE: irq_state = state == ASSERT_LINE; break;
|
||||||
case APU_IRQ_LINE: apu_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:
|
case V_LINE:
|
||||||
if(!v_state && state == ASSERT_LINE)
|
if(!v_state && state == ASSERT_LINE)
|
||||||
P |= F_V;
|
P |= F_V;
|
||||||
@ -484,7 +491,7 @@ void m6502_device::prefetch()
|
|||||||
sync = false;
|
sync = false;
|
||||||
sync_w(CLEAR_LINE);
|
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;
|
irq_taken = true;
|
||||||
IR = 0x00;
|
IR = 0x00;
|
||||||
} else
|
} else
|
||||||
|
@ -122,7 +122,7 @@ protected:
|
|||||||
int inst_state, inst_substate;
|
int inst_state, inst_substate;
|
||||||
int icount, bcount, count_before_instruction_step;
|
int icount, bcount, count_before_instruction_step;
|
||||||
bool nmi_state, irq_state, apu_irq_state, v_state;
|
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(uint16_t adr) { return mintf->read(adr); }
|
||||||
uint8_t read_9(uint16_t adr) { return mintf->read_9(adr); }
|
uint8_t read_9(uint16_t adr) { return mintf->read_9(adr); }
|
||||||
|
@ -52,6 +52,7 @@ void m740_device::device_reset()
|
|||||||
m_irq_vector = 0xfffc;
|
m_irq_vector = 0xfffc;
|
||||||
apu_irq_state = false;
|
apu_irq_state = false;
|
||||||
irq_taken = false;
|
irq_taken = false;
|
||||||
|
nmi_pending = false;
|
||||||
v_state = false;
|
v_state = false;
|
||||||
sync = false;
|
sync = false;
|
||||||
inhibit_interrupts = false;
|
inhibit_interrupts = false;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# copyright-holders:Olivier Galibert
|
# copyright-holders:Olivier Galibert
|
||||||
# deco 16 opcodes
|
# deco 16 opcodes
|
||||||
brk_16_imp
|
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) {
|
if(irq_taken) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
@ -14,10 +14,10 @@ brk_16_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, irq_taken ? P & ~F_B : P);
|
write(SP, irq_taken ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
if(nmi_state) {
|
if(nmi_pending) {
|
||||||
PC = read_arg(0xfff7);
|
PC = read_arg(0xfff7);
|
||||||
PC = set_h(PC, read_arg(0xfff6));
|
PC = set_h(PC, read_arg(0xfff6));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
standard_irq_callback(NMI_LINE);
|
standard_irq_callback(NMI_LINE);
|
||||||
} else {
|
} else {
|
||||||
PC = read_arg(0xfff3);
|
PC = read_arg(0xfff3);
|
||||||
|
@ -259,7 +259,7 @@ bpl_rel
|
|||||||
prefetch();
|
prefetch();
|
||||||
|
|
||||||
brk_imp
|
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) {
|
if(irq_taken) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
@ -271,10 +271,10 @@ brk_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, irq_taken ? P & ~F_B : P);
|
write(SP, irq_taken ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
if(nmi_state) {
|
if(nmi_pending) {
|
||||||
PC = read_arg(0xfffa);
|
PC = read_arg(0xfffa);
|
||||||
PC = set_h(PC, read_arg(0xfffb));
|
PC = set_h(PC, read_arg(0xfffb));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
standard_irq_callback(NMI_LINE);
|
standard_irq_callback(NMI_LINE);
|
||||||
} else {
|
} else {
|
||||||
PC = read_arg(0xfffe);
|
PC = read_arg(0xfffe);
|
||||||
|
@ -220,7 +220,7 @@ bra_rel
|
|||||||
prefetch();
|
prefetch();
|
||||||
|
|
||||||
brk_c_imp
|
brk_c_imp
|
||||||
if(irq_taken || nmi_state) {
|
if(irq_taken || nmi_pending) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
read_pc();
|
read_pc();
|
||||||
@ -229,12 +229,12 @@ brk_c_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, PC);
|
write(SP, PC);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, irq_taken || nmi_state ? P & ~F_B : P);
|
write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
if(irq_taken && nmi_state) {
|
if(irq_taken && nmi_pending) {
|
||||||
PC = read_arg(0xfffa);
|
PC = read_arg(0xfffa);
|
||||||
PC = set_h(PC, read_arg(0xfffb));
|
PC = set_h(PC, read_arg(0xfffb));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
standard_irq_callback(NMI_LINE);
|
standard_irq_callback(NMI_LINE);
|
||||||
} else {
|
} else {
|
||||||
PC = read_arg(0xfffe);
|
PC = read_arg(0xfffe);
|
||||||
@ -766,7 +766,7 @@ tsb_zpg
|
|||||||
wai_imp
|
wai_imp
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
while(!nmi_state && !irq_state) {
|
while(!nmi_pending && !irq_state) {
|
||||||
eat-all-cycles;
|
eat-all-cycles;
|
||||||
}
|
}
|
||||||
prefetch();
|
prefetch();
|
||||||
|
@ -359,12 +359,12 @@ brk_ce_imp
|
|||||||
dec_SP_ce();
|
dec_SP_ce();
|
||||||
write(SP, PC);
|
write(SP, PC);
|
||||||
dec_SP_ce();
|
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();
|
dec_SP_ce();
|
||||||
if(nmi_state) {
|
if(nmi_pending) {
|
||||||
PC = read_arg(0xfffa);
|
PC = read_arg(0xfffa);
|
||||||
PC = set_h(PC, read_arg(0xfffb));
|
PC = set_h(PC, read_arg(0xfffb));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
} else {
|
} else {
|
||||||
PC = read_arg(0xfffe);
|
PC = read_arg(0xfffe);
|
||||||
PC = set_h(PC, read_arg(0xffff));
|
PC = set_h(PC, read_arg(0xffff));
|
||||||
|
@ -120,7 +120,7 @@ reset740
|
|||||||
inst_state = -1;
|
inst_state = -1;
|
||||||
|
|
||||||
brk740_imp
|
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) {
|
if(irq_taken) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
@ -132,10 +132,10 @@ brk740_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, irq_taken ? P & ~F_B : P);
|
write(SP, irq_taken ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
if(nmi_state) {
|
if(nmi_pending) {
|
||||||
PC = read_arg(0xfffa);
|
PC = read_arg(0xfffa);
|
||||||
PC = set_h(PC, read_arg(0xfffb));
|
PC = set_h(PC, read_arg(0xfffb));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
standard_irq_callback(NMI_LINE);
|
standard_irq_callback(NMI_LINE);
|
||||||
} else {
|
} else {
|
||||||
PC = read_arg(m_irq_vector);
|
PC = read_arg(m_irq_vector);
|
||||||
|
@ -95,7 +95,7 @@ bas_amr
|
|||||||
prefetch();
|
prefetch();
|
||||||
|
|
||||||
brk_r_imp
|
brk_r_imp
|
||||||
if(irq_taken || nmi_state) {
|
if(irq_taken || nmi_pending) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
read_pc();
|
read_pc();
|
||||||
@ -104,12 +104,12 @@ brk_r_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, PC);
|
write(SP, PC);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, irq_taken || nmi_state ? P & ~F_B : P);
|
write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
if(irq_taken && nmi_state) {
|
if(irq_taken && nmi_pending) {
|
||||||
PC = read_arg(0xfffc);
|
PC = read_arg(0xfffc);
|
||||||
PC = set_h(PC, read_arg(0xfffd));
|
PC = set_h(PC, read_arg(0xfffd));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
standard_irq_callback(NMI_LINE);
|
standard_irq_callback(NMI_LINE);
|
||||||
} else {
|
} else {
|
||||||
TMP = get_irq_vector();
|
TMP = get_irq_vector();
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# m65c02 opcodes, with a twist
|
# m65c02 opcodes, with a twist
|
||||||
|
|
||||||
brk_st_imp
|
brk_st_imp
|
||||||
if(irq_taken || nmi_state) {
|
if(irq_taken || nmi_pending) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
read_pc();
|
read_pc();
|
||||||
@ -12,13 +12,13 @@ brk_st_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, PC);
|
write(SP, PC);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
write(SP, irq_taken || nmi_state ? P & ~F_B : P);
|
write(SP, irq_taken || nmi_pending ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
set_irq_service(true);
|
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 = read_vector(0x7ffa);
|
||||||
PC = set_h(PC, read_vector(0x7ffb));
|
PC = set_h(PC, read_vector(0x7ffb));
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
} else if(irq_taken) {
|
} else if(irq_taken) {
|
||||||
TMP = acknowledge_irq();
|
TMP = acknowledge_irq();
|
||||||
PC = read_vector(0x7ff8 - (TMP << 1));
|
PC = read_vector(0x7ff8 - (TMP << 1));
|
||||||
|
@ -40,8 +40,8 @@ retf_imp
|
|||||||
prefetch();
|
prefetch();
|
||||||
|
|
||||||
brk_xav_imp
|
brk_xav_imp
|
||||||
// there is code in soem games to indicate this doesn't always push the far bank to the stack..
|
// 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_state)
|
// The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_pending)
|
||||||
if(irq_taken) {
|
if(irq_taken) {
|
||||||
read_pc_noinc();
|
read_pc_noinc();
|
||||||
} else {
|
} else {
|
||||||
@ -56,7 +56,7 @@ brk_xav_imp
|
|||||||
dec_SP();
|
dec_SP();
|
||||||
write_stack(SP, irq_taken ? P & ~F_B : P);
|
write_stack(SP, irq_taken ? P & ~F_B : P);
|
||||||
dec_SP();
|
dec_SP();
|
||||||
if(nmi_state) {
|
if(nmi_pending) {
|
||||||
if (m_vector_callback.isnull())
|
if (m_vector_callback.isnull())
|
||||||
{
|
{
|
||||||
PC = read_arg(0xfffa);
|
PC = read_arg(0xfffa);
|
||||||
@ -76,7 +76,7 @@ brk_xav_imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nmi_state = false;
|
nmi_pending = false;
|
||||||
standard_irq_callback(NMI_LINE);
|
standard_irq_callback(NMI_LINE);
|
||||||
} else {
|
} else {
|
||||||
if (m_vector_callback.isnull())
|
if (m_vector_callback.isnull())
|
||||||
|
@ -18,8 +18,6 @@ Hardware notes:
|
|||||||
- 4-digit 7seg display
|
- 4-digit 7seg display
|
||||||
|
|
||||||
TODO:
|
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
|
- colors are estimated from photos (black and white are obvious, but the green
|
||||||
and cyan are not standard 0x00ff00 / 0x00ffff)
|
and cyan are not standard 0x00ff00 / 0x00ffff)
|
||||||
- video timing is unknown, sprite offsets are estimated from photos
|
- video timing is unknown, sprite offsets are estimated from photos
|
||||||
@ -101,7 +99,6 @@ private:
|
|||||||
|
|
||||||
u8 m_select = 0;
|
u8 m_select = 0;
|
||||||
u8 m_7seg_data = 0;
|
u8 m_7seg_data = 0;
|
||||||
bool m_nmistate = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void intchess_state::machine_start()
|
void intchess_state::machine_start()
|
||||||
@ -109,7 +106,6 @@ void intchess_state::machine_start()
|
|||||||
// register for savestates
|
// register for savestates
|
||||||
save_item(NAME(m_select));
|
save_item(NAME(m_select));
|
||||||
save_item(NAME(m_7seg_data));
|
save_item(NAME(m_7seg_data));
|
||||||
save_item(NAME(m_nmistate));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INPUT_CHANGED_MEMBER(intchess_state::reset_button)
|
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
|
// cassette input is tied to NMI
|
||||||
bool state = ((m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) && (m_cass->input() < -0.04);
|
bool state = ((m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) && (m_cass->input() < -0.04);
|
||||||
|
m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE);
|
||||||
if (state != m_nmistate)
|
|
||||||
{
|
|
||||||
m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE);
|
|
||||||
m_nmistate = state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user