xavix - store the extra codebank byte in a private stack when making long calls etc. (fixes crash on calibration screen in rad_hnt2)

this seems feasible as it's an extension to the CPU, so keeping it in a private stack would maintain better compatibility with 6502 code
This commit is contained in:
DavidHaywood 2019-06-14 21:22:24 +01:00
parent ab6d6e06ea
commit 10e3dba1d0
3 changed files with 54 additions and 10 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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 {