mirror of
https://github.com/holub/mame
synced 2025-07-03 17:08:39 +03:00
add undocumented instructions and dissasembler (#11050)
This commit is contained in:
parent
2a1ba144a5
commit
5dc861b772
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,8 @@
|
||||
#ifndef MAME_CPU_M6809_6X09DASM_H
|
||||
#define MAME_CPU_M6809_6X09DASM_H
|
||||
|
||||
#include <set>
|
||||
|
||||
#pragma once
|
||||
|
||||
class m6x09_base_disassembler : public util::disasm_interface
|
||||
@ -37,22 +39,21 @@ protected:
|
||||
class opcodeinfo;
|
||||
|
||||
public:
|
||||
// General, or 6309 only?
|
||||
enum m6x09_instruction_level
|
||||
// General, undocumented, or 6309 only?
|
||||
enum m6x09_instruction_level : uint8_t
|
||||
{
|
||||
M6x09_GENERAL,
|
||||
HD6309_EXCLUSIVE
|
||||
M6x09_GENERAL = 1,
|
||||
M6809_UNDOCUMENTED = 2,
|
||||
HD6309_EXCLUSIVE = 4
|
||||
};
|
||||
|
||||
m6x09_base_disassembler(const opcodeinfo *opcodes, size_t opcode_count, m6x09_instruction_level level)
|
||||
: m_opcodes(opcodes, opcode_count), m_level(level)
|
||||
{
|
||||
}
|
||||
m6x09_base_disassembler(const opcodeinfo *opcodes, size_t opcode_count, uint32_t level);
|
||||
|
||||
virtual u32 opcode_alignment() const override;
|
||||
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
|
||||
|
||||
protected:
|
||||
enum m6x09_addressing_mode
|
||||
enum m6x09_addressing_mode : uint8_t
|
||||
{
|
||||
INH, // Inherent
|
||||
PSHS, PSHU, // Push
|
||||
@ -67,33 +68,41 @@ protected:
|
||||
IMM_RR, // Register-to-register
|
||||
IMM_BW, // Bitwise operations (6309 only)
|
||||
IMM_TFM, // Transfer from memory (6309 only)
|
||||
PG1, // Switch to page 1 opcodes
|
||||
PG2 // Switch to page 2 opcodes
|
||||
PG2, // Switch to page 2 opcodes
|
||||
PG3 // Switch to page 3 opcodes
|
||||
};
|
||||
|
||||
// Opcode structure
|
||||
class opcodeinfo
|
||||
{
|
||||
public:
|
||||
constexpr opcodeinfo(uint16_t opcode, uint8_t length, const char *name, m6x09_addressing_mode mode, m6x09_instruction_level level, unsigned flags = 0)
|
||||
: m_opcode(opcode), m_length(length), m_mode(mode), m_level(level), m_flags(flags), m_name(name)
|
||||
constexpr opcodeinfo(uint16_t opcode, uint8_t operand_length, const char *name, m6x09_addressing_mode mode, uint32_t level, unsigned flags = 0)
|
||||
: m_opcode(opcode), m_operand_length(operand_length), m_mode(mode), m_level(level), m_flags(flags), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t opcode() const { return m_opcode; }
|
||||
uint8_t length() const { return m_length; }
|
||||
uint8_t operand_length() const { return m_operand_length; }
|
||||
m6x09_addressing_mode mode() const { return m_mode; }
|
||||
m6x09_instruction_level level() const { return m_level; }
|
||||
uint32_t level() const { return m_level; }
|
||||
unsigned flags() const { return m_flags; }
|
||||
const char *name() const { return m_name; }
|
||||
|
||||
struct compare
|
||||
{
|
||||
using is_transparent = void;
|
||||
bool operator()(opcodeinfo const& lhs, opcodeinfo const& rhs) const;
|
||||
bool operator()(uint16_t opcode, opcodeinfo const& rhs) const;
|
||||
bool operator()(opcodeinfo const& lhs, uint16_t opcode) const;
|
||||
};
|
||||
|
||||
private:
|
||||
uint16_t m_opcode; // 8-bit opcode value
|
||||
uint8_t m_length; // Opcode length in bytes
|
||||
m6x09_addressing_mode m_mode : 6; // Addressing mode
|
||||
m6x09_instruction_level m_level : 2; // General, or 6309 only?
|
||||
unsigned m_flags; // Disassembly flags
|
||||
const char * m_name; // Opcode name
|
||||
uint16_t m_opcode; // 8-bit opcode value
|
||||
uint8_t m_operand_length; // Opcode length in bytes
|
||||
m6x09_addressing_mode m_mode; // Addressing mode
|
||||
uint8_t m_level; // General, or 6309 only?
|
||||
unsigned m_flags; // Disassembly flags
|
||||
const char * m_name; // Opcode name
|
||||
};
|
||||
|
||||
static const char *const m6x09_regs[5];
|
||||
@ -105,14 +114,16 @@ protected:
|
||||
virtual void register_register(std::ostream &stream, uint8_t pb) = 0;
|
||||
|
||||
private:
|
||||
util::contiguous_sequence_wrapper<const opcodeinfo> m_opcodes;
|
||||
m6x09_instruction_level m_level;
|
||||
std::set<opcodeinfo, opcodeinfo::compare> m_opcodes;
|
||||
|
||||
uint32_t m_level;
|
||||
uint16_t m_page;
|
||||
|
||||
const opcodeinfo *fetch_opcode(const data_buffer &opcodes, offs_t &p);
|
||||
|
||||
void assert_hd6309_exclusive()
|
||||
{
|
||||
if (m_level < HD6309_EXCLUSIVE)
|
||||
if (!(m_level & HD6309_EXCLUSIVE))
|
||||
throw false;
|
||||
}
|
||||
};
|
||||
@ -120,7 +131,7 @@ private:
|
||||
class m6x09_disassembler : public m6x09_base_disassembler
|
||||
{
|
||||
public:
|
||||
m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]);
|
||||
m6x09_disassembler(uint32_t level, const char teregs[16][4]);
|
||||
|
||||
protected:
|
||||
virtual void indexed(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) override;
|
||||
|
@ -22,6 +22,10 @@
|
||||
|
||||
History:
|
||||
|
||||
January 2023 tlindner:
|
||||
Add 6809 undocumented opcodes as described here:
|
||||
https://github.com/hoglet67/6809Decoder/wiki/Undocumented-6809-Behaviours
|
||||
|
||||
July 2016 ErikGav:
|
||||
Unify with 6309 pairs and quads (A+B=D, E+F=W, D+W=Q)
|
||||
|
||||
@ -214,6 +218,7 @@ void m6809_base_device::device_start()
|
||||
save_item(NAME(m_addressing_mode));
|
||||
save_item(NAME(m_reg));
|
||||
save_item(NAME(m_cond));
|
||||
save_item(NAME(m_free_run));
|
||||
|
||||
// set our instruction counter
|
||||
set_icountptr(m_icount);
|
||||
@ -233,6 +238,7 @@ void m6809_base_device::device_reset()
|
||||
m_firq_line = false;
|
||||
m_irq_line = false;
|
||||
m_lds_encountered = false;
|
||||
m_free_run = false;
|
||||
|
||||
m_dp = 0x00; // reset direct page register
|
||||
|
||||
|
@ -279,6 +279,7 @@ private:
|
||||
// other state
|
||||
uint32_t m_state;
|
||||
bool m_cond;
|
||||
bool m_free_run;
|
||||
|
||||
// incidentals
|
||||
int m_clock_divider;
|
||||
|
@ -13,22 +13,27 @@ MAIN:
|
||||
m_ppc = m_pc;
|
||||
debugger_instruction_hook(m_pc.w);
|
||||
|
||||
DISPATCH01:
|
||||
// opcode fetch
|
||||
m_lic_func(ASSERT_LINE);
|
||||
@m_opcode = read_opcode();
|
||||
m_lic_func(CLEAR_LINE);
|
||||
|
||||
if (m_free_run) goto FREERUN;
|
||||
|
||||
// dispatch opcode
|
||||
switch(m_opcode)
|
||||
{
|
||||
case 0x00: case 0x01: %DIRECT; %NEG8; return;
|
||||
case 0x03: case 0x02: %DIRECT; %COM8; return;
|
||||
case 0x02: %DIRECT; %XNC8; return;
|
||||
case 0x03: %DIRECT; %COM8; return;
|
||||
case 0x04: case 0x05: %DIRECT; %LSR8; return;
|
||||
case 0x06: %DIRECT; %ROR8; return;
|
||||
case 0x07: %DIRECT; %ASR8; return;
|
||||
case 0x08: %DIRECT; %ASL8; return;
|
||||
case 0x09: %DIRECT; %ROL8; return;
|
||||
case 0x0A: case 0x0B: %DIRECT; %DEC8; return;
|
||||
case 0x0A: %DIRECT; %DEC8; return;
|
||||
case 0x0B: %DIRECT; %XDEC8; return;
|
||||
case 0x0C: %DIRECT; %INC8; return;
|
||||
case 0x0D: %DIRECT; %TST8; return;
|
||||
case 0x0E: %DIRECT; %JMP; return;
|
||||
@ -38,10 +43,13 @@ MAIN:
|
||||
case 0x11: %DISPATCH11; return;
|
||||
case 0x12: %NOP; return;
|
||||
case 0x13: %SYNC; return;
|
||||
case 0x14: case 0x15: %FREERUN; return;
|
||||
case 0x16: set_cond(true); %LBRANCH; return;
|
||||
case 0x17: %LBSR; return;
|
||||
case 0x18: %X18; return;
|
||||
case 0x19: %DAA; return;
|
||||
case 0x1A: set_imm(); %ORCC; return;
|
||||
case 0x1B: %NOP; return;
|
||||
case 0x1C: set_imm(); %ANDCC; return;
|
||||
case 0x1D: %SEX; return;
|
||||
case 0x1E: %EXG; return;
|
||||
@ -72,60 +80,70 @@ MAIN:
|
||||
case 0x35: %PULS; return;
|
||||
case 0x36: %PSHU; return;
|
||||
case 0x37: %PULU; return;
|
||||
case 0x38: set_imm(); %XANDCC; return;
|
||||
case 0x39: %RTS; return;
|
||||
case 0x3A: %ABX; return;
|
||||
case 0x3B: %RTI; return;
|
||||
case 0x3C: %CWAI; return;
|
||||
case 0x3D: %MUL; return;
|
||||
case 0x3E: %XRES; return;
|
||||
case 0x3F: %SWI; return;
|
||||
|
||||
case 0x40: case 0x41: set_a(); %NEG8; return;
|
||||
case 0x43: case 0x42: set_a(); %COM8; return;
|
||||
case 0x42: set_a(); %XNC8; return;
|
||||
case 0x43: set_a(); %COM8; return;
|
||||
case 0x44: case 0x45: set_a(); %LSR8; return;
|
||||
case 0x46: set_a(); %ROR8; return;
|
||||
case 0x47: set_a(); %ASR8; return;
|
||||
case 0x48: set_a(); %ASL8; return;
|
||||
case 0x49: set_a(); %ROL8; return;
|
||||
case 0x4A: case 0x4B: set_a(); %DEC8; return;
|
||||
case 0x4A: set_a(); %DEC8; return;
|
||||
case 0x4B: set_a(); %XDEC8; return;
|
||||
case 0x4C: set_a(); %INC8; return;
|
||||
case 0x4D: set_a(); %TST8; return;
|
||||
case 0x4E: set_a(); %JMP; return;
|
||||
case 0x4E: set_a(); %XCLR8; return;
|
||||
case 0x4F: set_a(); %CLR8; return;
|
||||
|
||||
case 0x50: case 0x51: set_b(); %NEG8; return;
|
||||
case 0x53: case 0x52: set_b(); %COM8; return;
|
||||
case 0x52: set_b(); %XNC8; return;
|
||||
case 0x53: set_b(); %COM8; return;
|
||||
case 0x54: case 0x55: set_b(); %LSR8; return;
|
||||
case 0x56: set_b(); %ROR8; return;
|
||||
case 0x57: set_b(); %ASR8; return;
|
||||
case 0x58: set_b(); %ASL8; return;
|
||||
case 0x59: set_b(); %ROL8; return;
|
||||
case 0x5A: case 0x5B: set_b(); %DEC8; return;
|
||||
case 0x5A: set_b(); %DEC8; return;
|
||||
case 0x5B: set_b(); %XDEC8; return;
|
||||
case 0x5C: set_b(); %INC8; return;
|
||||
case 0x5D: set_b(); %TST8; return;
|
||||
case 0x5E: set_b(); %JMP; return;
|
||||
case 0x5E: set_b(); %XCLR8; return;
|
||||
case 0x5F: set_b(); %CLR8; return;
|
||||
|
||||
case 0x60: case 0x61: %INDEXED; %NEG8; return;
|
||||
case 0x63: case 0x62: %INDEXED; %COM8; return;
|
||||
case 0x62: %INDEXED; %XNC8; return;
|
||||
case 0x63: %INDEXED; %COM8; return;
|
||||
case 0x64: case 0x65: %INDEXED; %LSR8; return;
|
||||
case 0x66: %INDEXED; %ROR8; return;
|
||||
case 0x67: %INDEXED; %ASR8; return;
|
||||
case 0x68: %INDEXED; %ASL8; return;
|
||||
case 0x69: %INDEXED; %ROL8; return;
|
||||
case 0x6A: case 0x6B: %INDEXED; %DEC8; return;
|
||||
case 0x6A: %INDEXED; %DEC8; return;
|
||||
case 0x6B: %INDEXED; %XDEC8; return;
|
||||
case 0x6C: %INDEXED; %INC8; return;
|
||||
case 0x6D: %INDEXED; %TST8; return;
|
||||
case 0x6E: %INDEXED; %JMP; return;
|
||||
case 0x6F: %INDEXED; %CLR8; return;
|
||||
|
||||
case 0x70: case 0x71: %EXTENDED; %NEG8; return;
|
||||
case 0x73: case 0x72: %EXTENDED; %COM8; return;
|
||||
case 0x72: %EXTENDED; %XNC8; return;
|
||||
case 0x73: %EXTENDED; %COM8; return;
|
||||
case 0x74: case 0x75: %EXTENDED; %LSR8; return;
|
||||
case 0x76: %EXTENDED; %ROR8; return;
|
||||
case 0x77: %EXTENDED; %ASR8; return;
|
||||
case 0x78: %EXTENDED; %ASL8; return;
|
||||
case 0x79: %EXTENDED; %ROL8; return;
|
||||
case 0x7A: case 0x7B: %EXTENDED; %DEC8; return;
|
||||
case 0x7A: %EXTENDED; %DEC8; return;
|
||||
case 0x7B: %EXTENDED; %XDEC8; return;
|
||||
case 0x7C: %EXTENDED; %INC8; return;
|
||||
case 0x7D: %EXTENDED; %TST8; return;
|
||||
case 0x7E: %EXTENDED; %JMP; return;
|
||||
@ -138,7 +156,7 @@ MAIN:
|
||||
case 0x84: set_regop8(m_q.r.a); set_imm(); %AND8; return;
|
||||
case 0x85: set_regop8(m_q.r.a); set_imm(); %BIT8; return;
|
||||
case 0x86: set_regop8(m_q.r.a); set_imm(); %LD8; return;
|
||||
case 0x87: set_regop8(m_q.r.a); set_imm(); %ST8; return;
|
||||
case 0x87: set_regop8(m_q.r.a); set_imm(); %XST8; return;
|
||||
case 0x88: set_regop8(m_q.r.a); set_imm(); %EOR8; return;
|
||||
case 0x89: set_regop8(m_q.r.a); set_imm(); %ADC8; return;
|
||||
case 0x8A: set_regop8(m_q.r.a); set_imm(); %OR8; return;
|
||||
@ -146,7 +164,7 @@ MAIN:
|
||||
case 0x8C: set_regop16(m_x); set_imm(); %CMP16; return;
|
||||
case 0x8D: %BSR; return;
|
||||
case 0x8E: set_regop16(m_x); set_imm(); %LD16; return;
|
||||
case 0x8F: set_regop16(m_x); set_imm(); %ST16; return;
|
||||
case 0x8F: set_regop16(m_x); set_imm(); %XST16; return;
|
||||
|
||||
case 0x90: set_regop8(m_q.r.a); %DIRECT; %SUB8; return;
|
||||
case 0x91: set_regop8(m_q.r.a); %DIRECT; %CMP8; return;
|
||||
@ -206,15 +224,15 @@ MAIN:
|
||||
case 0xC4: set_regop8(m_q.r.b); set_imm(); %AND8; return;
|
||||
case 0xC5: set_regop8(m_q.r.b); set_imm(); %BIT8; return;
|
||||
case 0xC6: set_regop8(m_q.r.b); set_imm(); %LD8; return;
|
||||
case 0xC7: set_regop8(m_q.r.b); set_imm(); %ST8; return;
|
||||
case 0xC7: set_regop8(m_q.r.b); set_imm(); %XST8; return;
|
||||
case 0xC8: set_regop8(m_q.r.b); set_imm(); %EOR8; return;
|
||||
case 0xC9: set_regop8(m_q.r.b); set_imm(); %ADC8; return;
|
||||
case 0xCA: set_regop8(m_q.r.b); set_imm(); %OR8; return;
|
||||
case 0xCB: set_regop8(m_q.r.b); set_imm(); %ADD8; return;
|
||||
case 0xCC: set_regop16(m_q.p.d); set_imm(); %LD16; return;
|
||||
case 0xCD: set_regop16(m_q.p.d); set_imm(); %ST16; return;
|
||||
case 0xCD: %FREERUN; return;
|
||||
case 0xCE: set_regop16(m_u); set_imm(); %LD16; return;
|
||||
case 0xCF: set_regop16(m_u); set_imm(); %ST16; return;
|
||||
case 0xCF: set_regop16(m_u); set_imm(); %XST16; return;
|
||||
|
||||
case 0xD0: set_regop8(m_q.r.b); %DIRECT; %SUB8; return;
|
||||
case 0xD1: set_regop8(m_q.r.b); %DIRECT; %CMP8; return;
|
||||
@ -274,6 +292,9 @@ DISPATCH10:
|
||||
@m_opcode = read_opcode();
|
||||
switch(m_opcode)
|
||||
{
|
||||
case 0x10: %DISPATCH10; return;
|
||||
case 0x11: %DISPATCH10; return;
|
||||
|
||||
case 0x20: set_cond(true); %LBRANCH; return;
|
||||
case 0x21: set_cond(false); %LBRANCH; return;
|
||||
case 0x22: set_cond(cond_hi()); %LBRANCH; return;
|
||||
@ -291,35 +312,48 @@ DISPATCH10:
|
||||
case 0x2E: set_cond(cond_gt()); %LBRANCH; return;
|
||||
case 0x2F: set_cond(!cond_gt()); %LBRANCH; return;
|
||||
|
||||
case 0x3E: %XSWI2; return;
|
||||
case 0x3F: %SWI2; return;
|
||||
|
||||
case 0x83: set_regop16(m_q.p.d); set_imm(); %CMP16; return;
|
||||
case 0x87: set_regop8(m_q.r.a); set_imm(); %XST8; return;
|
||||
case 0x8C: set_regop16(m_y); set_imm(); %CMP16; return;
|
||||
case 0x8E: set_regop16(m_y); set_imm(); %LD16; return;
|
||||
case 0x8F: set_regop16(m_y); set_imm(); %ST16; return;
|
||||
case 0x8F: set_regop16(m_y); set_imm(); %XST16; return;
|
||||
|
||||
case 0x93: set_regop16(m_q.p.d); %DIRECT; %CMP16; return;
|
||||
case 0x9C: set_regop16(m_y); %DIRECT; %CMP16; return;
|
||||
case 0x9E: set_regop16(m_y); %DIRECT; %LD16; return;
|
||||
case 0x9F: set_regop16(m_y); %DIRECT; %ST16; return;
|
||||
|
||||
case 0xA3: set_regop16(m_q.p.d); %INDEXED; %CMP16; return;
|
||||
case 0xAC: set_regop16(m_y); %INDEXED; %CMP16; return;
|
||||
case 0xAE: set_regop16(m_y); %INDEXED; %LD16; return;
|
||||
case 0xAF: set_regop16(m_y); %INDEXED; %ST16; return;
|
||||
|
||||
case 0xB3: set_regop16(m_q.p.d); %EXTENDED; %CMP16; return;
|
||||
case 0xBC: set_regop16(m_y); %EXTENDED; %CMP16; return;
|
||||
case 0xBE: set_regop16(m_y); %EXTENDED; %LD16; return;
|
||||
case 0xBF: set_regop16(m_y); %EXTENDED; %ST16; return;
|
||||
|
||||
case 0xC3: set_regop16(m_q.p.d); set_imm(); %XADD16; return;
|
||||
case 0xC7: set_regop8(m_q.r.b); set_imm(); %XST8; return;
|
||||
case 0xCE: set_regop16(m_s); set_imm(); %LD16; return;
|
||||
case 0xCF: set_regop16(m_s); set_imm(); %ST16; return;
|
||||
case 0xCF: set_regop16(m_s); set_imm(); %XST16; return;
|
||||
|
||||
case 0xD3: set_regop16(m_q.p.d); %DIRECT; %XADD16; return;
|
||||
case 0xDE: set_regop16(m_s); %DIRECT; %LD16; return;
|
||||
case 0xDF: set_regop16(m_s); %DIRECT; %ST16; return;
|
||||
|
||||
case 0xE3: set_regop16(m_q.p.d); %INDEXED; %XADD16; return;
|
||||
case 0xEE: set_regop16(m_s); %INDEXED; %LD16; return;
|
||||
case 0xEF: set_regop16(m_s); %INDEXED; %ST16; return;
|
||||
|
||||
case 0xF3: set_regop16(m_q.p.d); %EXTENDED; %XADD16; return;
|
||||
case 0xFE: set_regop16(m_s); %EXTENDED; %LD16; return;
|
||||
case 0xFF: set_regop16(m_s); %EXTENDED; %ST16; return;
|
||||
|
||||
default: %ILLEGAL; return;
|
||||
default: %DISPATCH01; return;
|
||||
}
|
||||
return;
|
||||
|
||||
@ -327,16 +361,28 @@ DISPATCH11:
|
||||
@m_opcode = read_opcode();
|
||||
switch(m_opcode)
|
||||
{
|
||||
case 0x10: %DISPATCH11; return;
|
||||
case 0x11: %DISPATCH11; return;
|
||||
|
||||
case 0x3E: %XFIRQ; return;
|
||||
case 0x3F: %SWI3; return;
|
||||
case 0x83: set_regop16(m_u); set_imm(); %CMP16; return;
|
||||
case 0x8C: set_regop16(m_s); set_imm(); %CMP16; return;
|
||||
case 0x87: set_regop8(m_q.r.a); set_imm(); %XST8; return;
|
||||
case 0x8F: set_regop16(m_x); set_imm(); %XST16; return;
|
||||
case 0x93: set_regop16(m_u); %DIRECT; %CMP16; return;
|
||||
case 0x9C: set_regop16(m_s); %DIRECT; %CMP16; return;
|
||||
case 0xC3: set_regop16(m_u); set_imm(); %XADD16; return;
|
||||
case 0xC7: set_regop8(m_q.r.b); set_imm(); %XST8; return;
|
||||
case 0xCF: set_regop16(m_u); set_imm(); %XST16; return;
|
||||
case 0xA3: set_regop16(m_u); %INDEXED; %CMP16; return;
|
||||
case 0xAC: set_regop16(m_s); %INDEXED; %CMP16; return;
|
||||
case 0xB3: set_regop16(m_u); %EXTENDED; %CMP16; return;
|
||||
case 0xBC: set_regop16(m_s); %EXTENDED; %CMP16; return;
|
||||
default: %ILLEGAL; return;
|
||||
case 0xD3: set_regop16(m_u); %DIRECT; %XADD16; return;
|
||||
case 0xE3: set_regop16(m_u); %INDEXED; %XADD16; return;
|
||||
case 0xF3: set_regop16(m_u); %EXTENDED; %XADD16; return;
|
||||
default: %DISPATCH01; return;
|
||||
}
|
||||
return;
|
||||
|
||||
@ -600,6 +646,113 @@ TFR:
|
||||
@dummy_vma(hd6309_native_mode() ? 2 : 4);
|
||||
return;
|
||||
|
||||
FREERUN:
|
||||
// A CPU test mode that increments the address bus until reset.
|
||||
m_free_run = true;
|
||||
return;
|
||||
|
||||
X18:
|
||||
@m_temp.b.l = read_opcode_arg(m_pc.w);
|
||||
m_temp.b.l = (m_cc & m_temp.b.l) << 1;
|
||||
m_cc = m_temp.b.l | ((m_cc & 0x04) >> 1);
|
||||
return;
|
||||
|
||||
XANDCC:
|
||||
@eat(1);
|
||||
goto ANDCC;
|
||||
|
||||
XRES:
|
||||
set_ea(VECTOR_RESET_FFFE);
|
||||
standard_irq_callback(M6809_SWI, m_pc.w);
|
||||
set_regop16(m_s);
|
||||
m_temp.w = entire_state_registers();
|
||||
@dummy_read_opcode_arg(0);
|
||||
@dummy_vma(1);
|
||||
%PUSH_REGISTERS;
|
||||
goto INTERRUPT_VECTOR;
|
||||
|
||||
XNC8:
|
||||
if (m_cc & CC_C)
|
||||
goto COM8;
|
||||
else
|
||||
goto NEG8;
|
||||
|
||||
XDEC8:
|
||||
@m_temp.b.l = read_operand();
|
||||
if (m_temp.b.l)
|
||||
m_cc |= CC_C;
|
||||
else
|
||||
m_cc &= ~CC_C;
|
||||
|
||||
m_temp.b.l = set_flags<uint8_t>(CC_NZ, m_temp.b.l, 1, m_temp.b.l - 1);
|
||||
if(!hd6309_native_mode() || !is_register_addressing_mode())
|
||||
{
|
||||
@dummy_read_opcode_arg(0);
|
||||
;
|
||||
}
|
||||
@write_operand(m_temp.b.l);
|
||||
return;
|
||||
|
||||
XCLR8:
|
||||
@read_operand();
|
||||
m_cc &= ~CC_NZV;
|
||||
m_cc |= CC_Z;
|
||||
if(!hd6309_native_mode() || !is_register_addressing_mode())
|
||||
{
|
||||
@dummy_read_opcode_arg(0);
|
||||
;
|
||||
}
|
||||
@write_operand(0);
|
||||
return;
|
||||
|
||||
XST8:
|
||||
// TODO: Flag setting is much more complex, see:
|
||||
// https://github.com/hoglet67/6809Decoder/wiki/Undocumented-6809-Behaviours#store-immediate
|
||||
|
||||
@read_operand();
|
||||
set_flags(CC_NZV, regop8());
|
||||
return;
|
||||
|
||||
XST16:
|
||||
// TODO: Flag setting is much more complex, see:
|
||||
// https://github.com/hoglet67/6809Decoder/wiki/Undocumented-6809-Behaviours#store-immediate
|
||||
|
||||
m_temp.b.h = read_operand(0);
|
||||
write_memory(m_pc.w++, regop16().b.l);
|
||||
set_flags(CC_NZV, regop16().w);
|
||||
return;
|
||||
|
||||
XSWI2:
|
||||
set_ea(VECTOR_SWI2);
|
||||
standard_irq_callback(M6809_SWI, m_pc.w);
|
||||
set_regop16(m_s);
|
||||
m_temp.w = entire_state_registers();
|
||||
@dummy_read_opcode_arg(0);
|
||||
@dummy_vma(1);
|
||||
%PUSH_REGISTERS;
|
||||
goto INTERRUPT_VECTOR;
|
||||
|
||||
XADD16:
|
||||
@m_temp.b.h = read_operand(0);
|
||||
@m_temp.b.l = read_operand(1);
|
||||
set_flags(CC_NZVC, regop16().w, m_temp.w, regop16().w + m_temp.w);
|
||||
if(!hd6309_native_mode())
|
||||
{
|
||||
@dummy_read_opcode_arg(0);
|
||||
;
|
||||
}
|
||||
return;
|
||||
|
||||
XFIRQ:
|
||||
set_ea(VECTOR_FIRQ);
|
||||
standard_irq_callback(M6809_SWI, m_pc.w);
|
||||
set_regop16(m_s);
|
||||
m_temp.w = entire_state_registers();
|
||||
@dummy_read_opcode_arg(0);
|
||||
@dummy_vma(1);
|
||||
%PUSH_REGISTERS;
|
||||
goto INTERRUPT_VECTOR;
|
||||
|
||||
ILLEGAL:
|
||||
log_illegal();
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user