mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
konami cpu: corrections to EXG/TFR opcode [hap, Jim Westfall]
This commit is contained in:
parent
c6e93c06f3
commit
456d6b7619
@ -16,6 +16,11 @@
|
||||
|
||||
Thanks to Franklin Bowen for bug fixes, ideas
|
||||
|
||||
TODO:
|
||||
- KONAMI EXG/TFR isn't disassembled accurately:
|
||||
0x3E/0x3F + param bit 7 clear = EXG
|
||||
0x3E/0x3F + param bit 7 set = TFR
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -1513,11 +1518,12 @@ void konami_disassembler::indexed(std::ostream &stream, uint8_t mode, const data
|
||||
|
||||
void konami_disassembler::register_register(std::ostream &stream, uint8_t pb)
|
||||
{
|
||||
static const char konami_teregs[8] =
|
||||
const char *const konami_teregs[8] =
|
||||
{
|
||||
'A', 'B', 'X', 'Y', 'S', 'U', '?', '?'
|
||||
// B: D when reading, B when writing
|
||||
"A", "B", "X", "Y", "DP", "U", "S", "PC"
|
||||
};
|
||||
util::stream_format(stream, "%c,%c",
|
||||
util::stream_format(stream, "%s,%s",
|
||||
konami_teregs[(pb >> 0) & 0x7],
|
||||
konami_teregs[(pb >> 4) & 0x7]);
|
||||
}
|
||||
|
@ -10,6 +10,9 @@
|
||||
TODO:
|
||||
- verify cycle timing
|
||||
- verify status flag handling
|
||||
- EXG/TFR DP: DP here is apparently part of a 16-bit register. DP is
|
||||
the high byte, and the low byte is an unknown hidden register? It
|
||||
doesn't look like any game uses this. See MAME issue #13544.
|
||||
|
||||
References:
|
||||
|
||||
@ -184,15 +187,15 @@ inline uint16_t &konami_cpu_device::ireg()
|
||||
{
|
||||
switch(m_opcode & 0x70)
|
||||
{
|
||||
case 0x20: return m_x.w;
|
||||
case 0x30: return m_y.w;
|
||||
case 0x50: return m_u.w;
|
||||
case 0x60: return m_s.w;
|
||||
case 0x70: return m_pc.w;
|
||||
case 0x20: return m_x.w; // X
|
||||
case 0x30: return m_y.w; // Y
|
||||
case 0x50: return m_u.w; // U
|
||||
case 0x60: return m_s.w; // S
|
||||
case 0x70: return m_pc.w; // PC
|
||||
|
||||
default:
|
||||
fatalerror("Should not get here");
|
||||
// never executed
|
||||
//return m_x.w;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,11 +211,13 @@ inline uint16_t konami_cpu_device::read_exgtfr_register(uint8_t reg)
|
||||
switch(reg & 0x07)
|
||||
{
|
||||
case 0: result = m_q.r.a; break; // A
|
||||
case 1: result = m_q.r.b; break; // B
|
||||
case 1: result = m_q.r.d; break; // D
|
||||
case 2: result = m_x.w; break; // X
|
||||
case 3: result = m_y.w; break; // Y
|
||||
case 4: result = m_s.w; break; // S
|
||||
case 4: logerror("EXG/TFR unemulated DP reg\n"); break; // DP
|
||||
case 5: result = m_u.w; break; // U
|
||||
case 6: result = m_s.w; break; // S
|
||||
case 7: result = m_pc.w; break; // PC
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -231,8 +236,10 @@ inline void konami_cpu_device::write_exgtfr_register(uint8_t reg, uint16_t value
|
||||
case 1: m_q.r.b = value; break; // B
|
||||
case 2: m_x.w = value; break; // X
|
||||
case 3: m_y.w = value; break; // Y
|
||||
case 4: m_s.w = value; break; // S
|
||||
case 4: logerror("EXG/TFR unemulated DP reg\n"); break; // DP
|
||||
case 5: m_u.w = value; break; // U
|
||||
case 6: m_s.w = value; break; // S
|
||||
case 7: m_pc.w = value; break; // PC
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,7 @@ MAIN:
|
||||
case 0x3B: set_regop8(m_q.r.b); %INDEXED; %ST8; return;
|
||||
case 0x3C: set_imm(); %ANDCC; return;
|
||||
case 0x3D: set_imm(); %ORCC; return;
|
||||
case 0x3E: %EXG; return;
|
||||
case 0x3F: %TFR; return;
|
||||
case 0x3E: case 0x3F: %EXGTFR; return;
|
||||
|
||||
case 0x40: set_regop16(m_q.p.d); set_imm(); %LD16; return;
|
||||
case 0x41: set_regop16(m_q.p.d); %INDEXED; %LD16; return;
|
||||
@ -434,24 +433,24 @@ INDEXED:
|
||||
set_ea(m_temp.w);
|
||||
return;
|
||||
|
||||
EXG:
|
||||
EXGTFR:
|
||||
{
|
||||
// konami's EXG instruction differs enough from 6809 to fork the code
|
||||
uint8_t param = read_opcode_arg();
|
||||
uint16_t reg1 = read_exgtfr_register(param >> 0);
|
||||
uint16_t reg2 = read_exgtfr_register(param >> 4);
|
||||
write_exgtfr_register(param >> 0, reg2);
|
||||
write_exgtfr_register(param >> 4, reg1);
|
||||
}
|
||||
eat(3);
|
||||
return;
|
||||
|
||||
TFR:
|
||||
{
|
||||
// konami's TFR instruction differs enough from 6809 to fork the code
|
||||
// konami's EXG/TFR instruction differs enough from HD6309 to fork the code
|
||||
uint8_t param = read_opcode_arg();
|
||||
uint16_t reg = read_exgtfr_register(param >> 0);
|
||||
|
||||
// Opcodes 0x3E and 0x3F are the same! The bit that distinguishes between EXG and TFR
|
||||
// is actually opcode_arg bit 7. Although Konami software behaves as expected.
|
||||
if (!BIT(param, 7))
|
||||
{
|
||||
uint16_t reg2 = read_exgtfr_register(param >> 4);
|
||||
write_exgtfr_register(param >> 0, reg2);
|
||||
eat(1);
|
||||
}
|
||||
write_exgtfr_register(param >> 4, reg);
|
||||
|
||||
//if (BIT(m_opcode, 0) != BIT(param, 7))
|
||||
// logerror("KONAMI: Malformed EXG/TFR opcode\n");
|
||||
}
|
||||
eat(2);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user