mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +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),
|
||||
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
|
||||
|
@ -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); }
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
|
@ -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())
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user