diff --git a/src/devices/cpu/m6502/oxavix.lst b/src/devices/cpu/m6502/oxavix.lst index 437a86ffc5f..6b6de61a585 100644 --- a/src/devices/cpu/m6502/oxavix.lst +++ b/src/devices/cpu/m6502/oxavix.lst @@ -4,8 +4,8 @@ callf_xa3 read(SP); - write(SP, get_codebank()); - dec_SP(); + write_special_stack(get_codebank()); + dec_special_stack(); TMP2 = read_pc(); TMP = read_pc(); //read(SP); @@ -33,8 +33,8 @@ retf_imp PC = read(SP); inc_SP(); PC = set_h(PC, read(SP)); - inc_SP(); - TMP2 = read(SP); + inc_special_stack(); + TMP2 = read_special_stack(); set_codebank(TMP2); read_pc(); prefetch(); @@ -47,9 +47,9 @@ brk_xav_imp } else { read_pc(); } - write(SP, get_codebank()); + write_special_stack(get_codebank()); set_codebank(0x00); // epo_efdx, rad_ping and rad_mtrk strongly suggest that interrupts must force bank 0 as code jumps to a ROM pointer stored earlier / a fixed pointer to a rom address in bank 0 - dec_SP(); + dec_special_stack(); write(SP, PC >> 8); dec_SP(); write(SP, PC); @@ -115,8 +115,8 @@ rti_xav_imp PC = read(SP); inc_SP(); PC = set_h(PC, read(SP)); - inc_SP(); - TMP2 = read(SP); + inc_special_stack(); + TMP2 = read_special_stack(); set_codebank(TMP2); prefetch(); diff --git a/src/devices/cpu/m6502/xavix.cpp b/src/devices/cpu/m6502/xavix.cpp index ddf7f5562ed..901e1c0c975 100644 --- a/src/devices/cpu/m6502/xavix.cpp +++ b/src/devices/cpu/m6502/xavix.cpp @@ -93,12 +93,19 @@ void xavix_device::device_start() m_lowbus_space = &space(5); m_extbus_space = &space(6); - state_add(XAVIX_DATABANK, "DATBNK", m_databank).callimport().formatstr("%2s");; + state_add(XAVIX_DATABANK, "DATBNK", m_databank).callimport().formatstr("%2s"); state_add(XAVIX_CODEBANK, "CODBNK", m_codebank).callimport().formatstr("%2s"); + + save_item(NAME(m_special_stack)); + save_item(NAME(m_special_stackpos)); } void xavix_device::device_reset() { + m_special_stackpos = 0xff; + for (int i = 0; i < 0x100; i++) + m_special_stack[i] = 0x00; + set_codebank(0); set_databank(0); m6502_device::device_reset(); @@ -126,6 +133,28 @@ xavix_device::mi_xavix_normal::mi_xavix_normal(xavix_device *_base) base = _base; } +void xavix_device::write_special_stack(uint8_t data) +{ + m_special_stack[m_special_stackpos&0xff] = data; +} + +void xavix_device::dec_special_stack() +{ + m_special_stackpos--; +} + +void xavix_device::inc_special_stack() +{ + m_special_stackpos++; +} + +uint8_t xavix_device::read_special_stack() +{ + return m_special_stack[m_special_stackpos&0xff]; +} + + + inline uint8_t xavix_device::read_full_data(uint32_t addr) { return read_full_data((addr & 0xff0000)>>16, addr & 0xffff); @@ -194,7 +223,7 @@ inline uint8_t xavix_device::read_full_data_sp(uint8_t databank, uint16_t adr) if (adr == 0xfe) return m_codebank; else if (adr == 0xff) - return databank; + return m_databank; return m_lowbus_space->read_byte(adr); } @@ -275,6 +304,9 @@ inline void xavix_device::write_full_data(uint8_t databank, uint16_t adr, uint8_ return; } + // actually it is more likely that all zero page and stack operations should go through their own handlers, and never reach here + // there is code that explicitly uses pull/push opcodes when in the high banks indicating that the stack area likely isn't + // mapped normally if ((adr & 0x7fff) >= 0x200) { m_extbus_space->write_byte((databank << 16) | adr, val); diff --git a/src/devices/cpu/m6502/xavix.h b/src/devices/cpu/m6502/xavix.h index 3e20ec8a899..61d51655b8f 100644 --- a/src/devices/cpu/m6502/xavix.h +++ b/src/devices/cpu/m6502/xavix.h @@ -131,6 +131,18 @@ protected: void set_databank(uint8_t bank); uint8_t get_databank(); + void write_special_stack(uint8_t data); + void dec_special_stack(); + void inc_special_stack(); + uint8_t read_special_stack(); + + /* we store the additional 'codebank' used for far calls in a different, private stack + this seems to be neccessary for 'rad_hnt2' not to crash when bringing up the calibration / score table screens + and also for ekara 'a1' cart not to crash shortly after going ingame + it's possible however the stack format is just incorrect, so the exact reason for this being needed does + need further research */ + uint8_t m_special_stack[0x100]; + uint8_t m_special_stackpos; }; enum {