Merge pull request #5238 from DavidHaywood/140619

xavix - store the extra codebank byte in a private stack when making long calls etc.
This commit is contained in:
R. Belmont 2019-06-14 20:32:50 -04:00 committed by GitHub
commit ed7265984f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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 {