apple2ix/src/cpu.S
2013-06-11 00:08:15 -07:00

3349 lines
61 KiB
ArmAsm

/*
* Apple // emulator for Linux: Virtual 6502/65C02
*
* Copyright 1994 Alexander Jean-Claude Bottema
* Copyright 1995 Stephen Lee
* Copyright 1997, 1998 Aaron Culliney
* Copyright 1998, 1999, 2000 Michael Deutschmann
*
* This software package is subject to the GNU General Public License
* version 2 or later (your choice) as published by the Free Software
* Foundation.
*
* THERE ARE NO WARRANTIES WHATSOEVER.
*
*/
#include "apple2.h"
#include "cpu.h"
#include "misc.h"
.comm SN(cpu65_vmem),524288,4096
.comm SN(cpu65_flags_encode),256
.comm SN(cpu65_flags_decode),256
.comm SN(cpu65_delay),4
.comm SN(cpu65__opcodes),1024
.comm SN(cpu65__signal),1
.comm SN(cpu65_debug),4
.comm SN(cpu65_current),7
/* -------------------------------------------------------------------------
CPU (6502) Helper Routines
------------------------------------------------------------------------- */
#define GetFromPC_B movl PC_Reg_E, EffectiveAddr_E; \
incw PC_Reg; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8);
#define GetFromPC_W movl PC_Reg_E, EffectiveAddr_E; \
incw EffectiveAddr; \
addw $2, PC_Reg; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8); \
decw EffectiveAddr; \
movb %al, %ah; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8); \
#define GetFromEA_B call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8);
#define GetFromEA_W incw EffectiveAddr; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8); \
decw EffectiveAddr; \
movb %al, %ah; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8);
#define PutToEA_B call *SN(cpu65_vmem)+4\
(,EffectiveAddr_E,8);
#define GetFromMem_B(x) \
movl x, EffectiveAddr_E; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8);
#define GetFromMem_W(x) \
movl x, EffectiveAddr_E; \
incw EffectiveAddr; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8); \
decw EffectiveAddr; \
movb %al, %ah; \
call *SN(cpu65_vmem) \
(,EffectiveAddr_E,8); \
/* h means hooked */
#ifdef DEBUGGER
#define GetFromEA_Bh orb $1, SN(cpu65_debug)+3; \
GetFromEA_B
#define PutToEA_Bh orb $2, SN(cpu65_debug)+3; \
orb %al, SN(cpu65_debug)+2; \
PutToEA_B
/* reset operation code before each instruction. This assumes %al
* is zero, and is inserted into Continue */
#define ZeroOp mov %al, SN(cpu65_debug)+3;
#else /* !DEBUGGER */
#define GetFromEA_Bh GetFromEA_B
#define PutToEA_Bh PutToEA_B
#define ZeroOp
#endif /* !DEBUGGER */
/* The OR actually functions as a move, but we
* want to set the flags and we know %ah is zero */
#define Continue movl SN(cpu65_delay), %eax; \
0: decl %eax; \
jnz 0b; \
orb SN(cpu65__signal), %ah; \
jnz exception; \
ZeroOp \
GetFromPC_B \
jmp *cpu65__opcodes(,%eax,4);
#define SaveState movw EffectiveAddr, SN(cpu65_debug); \
movw PC_Reg, SN(cpu65_current); \
movb A_Reg, SN(cpu65_current)+2; \
movb F_Reg, SN(cpu65_current)+3; \
movb X_Reg, SN(cpu65_current)+4; \
movb Y_Reg, SN(cpu65_current)+5; \
movb SP_Reg_L, SN(cpu65_current)+6;
/* The xorls clear the high parts of the registers
* Note: dependent on register assignment
*
* The extra bit at the end points the stack pointer at the alternate
* stack in ALTZP mode. (Note, this is not good -- I'd prefer to avoid
* polluting this module with Apple-specific stuff. But we need to do
* it, else aux-stack using programs will crash when debugged.)
*/
#define ReplaceState xorl %eax, %eax; \
xorl %ebx, %ebx; \
xorl %ecx, %ecx; \
movl $0x0100, %edx; \
xorl %esi, %esi; \
xorl %edi, %edi; \
movw SN(cpu65_debug), EffectiveAddr; \
movw SN(cpu65_current), PC_Reg; \
movb SN(cpu65_current)+2, A_Reg; \
movb SN(cpu65_current)+3, F_Reg; \
movb SN(cpu65_current)+4, X_Reg; \
movb SN(cpu65_current)+5, Y_Reg; \
movb SN(cpu65_current)+6, SP_Reg_L; \
testl $SS_ALTZP, SN(softswitches); \
jz 9f; \
orl $0x10000, %edx; \
9:
#define FlagC lahf; \
andb $C_Flag, %ah; \
andb $~C_Flag, F_Reg; \
orb %ah, F_Reg;
#define FlagZ lahf; \
andb $Z_Flag, %ah; \
andb $~Z_Flag, F_Reg; \
orb %ah, F_Reg;
#define FlagN lahf; \
andb $N_Flag, %ah; \
andb $~N_Flag, F_Reg; \
orb %ah, F_Reg;
#define FlagNZ lahf; \
andb $(N_Flag|Z_Flag), %ah; \
andb $~(N_Flag|Z_Flag), F_Reg; \
orb %ah, F_Reg;
#define FlagNZC lahf; \
andb $(N_Flag|Z_Flag|C_Flag), %ah; \
andb $~(N_Flag|Z_Flag|C_Flag), F_Reg; \
orb %ah, F_Reg;
/* Have to do things a little differently since
* overflow is not read by the LAHF instruction
*
* Use of long operands wastes two bytes on the AND
* constant, but saves three instruction prefixes.
* This doesn't affect the cycle count.
*/
#define FlagNVZC pushfl; \
popl %eax; \
andl $0x08C1,%eax; \
andb $~(N_Flag|V_Flag|Z_Flag|C_Flag), F_Reg; \
orb %ah, F_Reg; \
orb %al, F_Reg;
#define Push(x) movb x, SN(apple_ii_64k)(,SP_Reg,1); \
decb SP_Reg_L;
#define Pop(x) incb SP_Reg_L; \
movb SN(apple_ii_64k)(,SP_Reg,1), x;
/* Immediate Addressing - the operand is contained in the second byte of the
instruction. */
#define GetImm movl PC_Reg_E, EffectiveAddr_E; \
incw PC_Reg;
/* Absolute Addressing - the second byte of the instruction is the low
order address, and the third byte is the high order byte. */
#define GetAbs GetFromPC_W; \
movl %eax, EffectiveAddr_E;
/* Zero Page Addressing - the second byte of the instruction is an
address on the zero page */
#define GetZPage GetFromPC_B; \
movl %eax, EffectiveAddr_E;
/* Zero Page Indexed Addressing - The effective address is calculated by
adding the second byte to the contents of the index register. Due
to the zero page addressing nature of this mode, no carry is added
to the high address byte, and the crossing of page boundaries does
not occur. */
#define GetZPage_X GetFromPC_B; \
addb X_Reg, %al; \
movl %eax, EffectiveAddr_E;
#define GetZPage_Y GetFromPC_B; \
addb Y_Reg, %al; \
movl %eax, EffectiveAddr_E;
/* Absolute Indexed Addressing - The effective address is formed by
adding the contents of X or Y to the address contained in the
second and third bytes of the instruction. */
#define GetAbs_X GetFromPC_W; \
addb X_Reg, %al; \
adcb $0, %ah; \
movl %eax, EffectiveAddr_E;
#define GetAbs_Y GetFromPC_W; \
addb Y_Reg, %al; \
adcb $0, %ah; \
movl %eax, EffectiveAddr_E;
/* Absolute Indirect Addressing - The second and third bytes of the
instruction are the low and high bytes of an address, respectively.
The contents of the fully specified memory location is the
low-order byte of the effective address. The next memory location
contains the high order byte of the effective address. */
/* (unused at the moment. It applies to JMP, but JMP's addressing is done
* without the macro)
*/
#define GetInd GetFromPC_W; \
GetFromMem_W(%eax)
/* Zero Page Indirect Addressing (65c02) - The second byte of the
instruction points to a memory location on page zero containing the
low order byte of the effective address. The next location on page
zero contains the high order byte of the address. */
#define GetIndZPage GetFromPC_B; \
incb %al; \
movl %eax, EffectiveAddr_E; \
GetFromEA_B; \
movb %al, %ah; \
decl EffectiveAddr_E; \
andl $0xFF, EffectiveAddr_E; \
GetFromEA_B; \
movl %eax, EffectiveAddr_E;
/* Zero Page Indexed Indirect Addressing - The second byte is added to
the contents of the X index register; the carry is discarded. The
result of this addition points to a memory location on page zero
whose contents is the low order byte of the effective address. The
next memory location in page zero contains the high-order byte of
the effective address. Both memory locations specifying the high
and low-order bytes must be in page zero. */
#define GetIndZPage_X GetFromPC_B; \
addb X_Reg, %al; \
incb %al; \
movl %eax, EffectiveAddr_E; \
GetFromEA_B; \
movb %al, %ah; \
decl EffectiveAddr_E; \
andl $0xFF, EffectiveAddr_E; \
GetFromEA_B; \
movl %eax, EffectiveAddr_E;
/* Indirect Indexed Addressing - The second byte of the instruction
points to a memory location in page zero. The contents of this
memory location are added to the contents of the Y index register,
the result being the low order byte of the effective address. The
carry from this addition is added to the contents of the next page
zero memory location, the result being the high order byte of the
effective address. */
#define GetIndZPage_Y GetFromPC_B; \
incb %al; \
movl %eax, EffectiveAddr_E; \
GetFromEA_B; \
movb %al, %ah; \
decl EffectiveAddr_E; \
andl $0xFF, EffectiveAddr_E; \
GetFromEA_B; \
addb Y_Reg, %al; \
adcb $0, %ah; \
movl %eax, EffectiveAddr_E;
#define DoADC_b GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
adcb %al, A_Reg; \
FlagNVZC
#define DoADC_d GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
adcb A_Reg, %al; \
daa; \
movb %al, A_Reg; \
FlagNVZC
#define DoAND GetFromEA_Bh \
andb %al, A_Reg; \
FlagNZ
#define DoASL GetFromEA_Bh \
addb %al, %al; \
FlagNZC \
PutToEA_Bh \
/* SAR (and the following AND) effectively moves
* bit 6 to Bit 3 while leaving Bit 7 unchanged */
#define DoBIT GetFromEA_Bh \
testb %al, A_Reg; \
lahf; \
sarb $3, %al; \
andw $0x4088, %ax; \
andb $~(N_Flag|V_Flag|Z_Flag), F_Reg; \
orb %al, F_Reg; \
orb %ah, F_Reg;
#define DoCMP GetFromEA_Bh \
cmpb %al, A_Reg; \
cmc; \
FlagNZC
#define DoCPX GetFromEA_Bh \
cmpb %al, X_Reg; \
cmc; \
FlagNZC
#define DoCPY GetFromEA_Bh \
cmpb %al, Y_Reg; \
cmc; \
FlagNZC
#define DoDEC GetFromEA_Bh \
decb %al; \
FlagNZ \
PutToEA_Bh
#define DoEOR GetFromEA_Bh \
xorb %al, A_Reg; \
FlagNZ
#define DoINC GetFromEA_Bh \
incb %al; \
FlagNZ \
PutToEA_Bh
#define DoJMP movw EffectiveAddr, PC_Reg;
#define DoJSR movw PC_Reg, %ax; \
decw %ax; \
Push(%ah) \
Push(%al) \
movw EffectiveAddr, PC_Reg;
#define DoLDA GetFromEA_Bh \
movb %al, A_Reg; \
orb %al, %al; \
FlagNZ
#define DoLDX GetFromEA_Bh \
movb %al, X_Reg; \
orb %al, %al; \
FlagNZ
#define DoLDY GetFromEA_Bh \
movb %al, Y_Reg; \
orb %al, %al; \
FlagNZ
#define DoLSR GetFromEA_Bh \
shrb $1, %al; \
FlagNZC \
PutToEA_Bh
#define DoORA GetFromEA_Bh \
orb %al, A_Reg; \
FlagNZ
#define DoROL GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
adcb %al,%al; \
FlagNZC \
PutToEA_Bh
#define DoROR GetFromEA_Bh \
movb F_Reg, %ah; \
rorl $1, %eax; \
orb %al, %al; \
btr $31, %eax; \
FlagNZC \
PutToEA_Bh
#define DoSBC_b GetFromEA_Bh \
notb %al; \
bt $C_Flag_Bit, FF_Reg; \
adcb %al, A_Reg; \
FlagNVZC
#define DoSBC_d GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
cmc; \
xchgb A_Reg, %al; \
sbbb A_Reg, %al; \
das; \
movb %al, A_Reg; \
cmc; \
FlagNVZC
#define DoSTA movb A_Reg, %al; \
PutToEA_Bh
#define DoSTX movb X_Reg, %al; \
PutToEA_Bh
#define DoSTY movb Y_Reg, %al; \
PutToEA_Bh
/* -------------------------------------------------------------------------
65c02 instructions
------------------------------------------------------------------------- */
#define DoSTZ movb $0x0, %al; \
PutToEA_Bh
#define DoTRB GetFromEA_Bh \
testb A_Reg, %al; \
FlagZ \
notb A_Reg; \
andb A_Reg, %al; \
notb A_Reg; \
PutToEA_Bh
#define DoTSB GetFromEA_Bh \
testb A_Reg, %al; \
FlagZ \
orb A_Reg, %al; \
PutToEA_Bh
/* -------------------------------------------------------------------------
Undocumented 6502 (Illegal instructions)
------------------------------------------------------------------------- */
/* AAX = A AND X -> M */
#define DoAAX movb A_Reg, %al; \
andb X_Reg, %al; \
FlagNZ \
PutToEA_Bh
/* AMA = ORA 238, AND M, TAX */
#define DoAMA orb $238, A_Reg; \
GetFromEA_Bh \
andb %al, A_Reg; \
movb A_Reg, X_Reg; \
FlagNZ
/* ANA = AND M, Carry = BIT 7 */
/* NB: assumes A_Reg = %cl */
#define DoANA GetFromEA_Bh \
andb %al, A_Reg; \
bt $7, %ecx; \
FlagNZC
/* ANB = same as ANA */
#define DoANB DoANA
/* AXM = (A AND X) - M -> X */
#define DoAXM GetFromEA_Bh \
andb A_Reg, X_Reg; \
notb %al; \
bt $C_Flag_Bit, FF_Reg; \
adcb %al, X_Reg; \
FlagNVZC
/* AXS = (A AND X) -> S, A AND X AND 17 -> M */
/* HACK!!!!!!!!!!!!!!! */
#define DoAXS movb A_Reg, SP_Reg_L; \
andb X_Reg, SP_Reg_L; \
movb SP_Reg_L, %al; \
andb $17, %al; \
FlagNZ /* \ wasn't here */ \
PutToEA_Bh
/* DCP = DEC M, CMP M */
#define DoDCP GetFromEA_Bh \
decb %al; \
PutToEA_Bh \
negb %al; \
addb A_Reg, %al; \
FlagNZC
/* ISB = INC M, SBC M */
#define DoISB_b GetFromEA_Bh \
incb %al; \
PutToEA_Bh \
notb %al; \
bt $C_Flag_Bit, FF_Reg; \
adcb %al, A_Reg; \
FlagNVZC
#define DoISB_d GetFromEA_Bh \
incb %al; \
PutToEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
cmc; \
xchgb A_Reg, %al; \
sbbb A_Reg, %al; \
das; \
movb %al, A_Reg; \
cmc; \
FlagNVZC
/* LAN = ROL M, AND M */
#define DoLAN GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
adcl %eax, %eax; \
andb %al, A_Reg; \
bt $8, %eax; \
FlagNZC \
PutToEA_Bh
/* LAS = LDA M, TAX, TXS */
#define DoLAS GetFromEA_Bh \
movb %al, A_Reg; \
movb %al, X_Reg; \
movb %al, SP_Reg_L; \
orb %al, %al; \
FlagNZ
/* LAX = LDA M, TAX */
#define DoLAX GetFromEA_Bh \
movb %al, A_Reg; \
movb %al, X_Reg; \
orb %al, %al; \
FlagNZ
/* LOR = ASL M, ORA M */
#define DoLOR GetFromEA_Bh \
addb %al, %al; \
FlagC \
PutToEA_Bh \
orb %al, A_Reg; \
FlagNZ
/* RAD = ROR M, ADC M */
#define DoRAD_b GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
rcrb $1, %al; \
adcb %al, A_Reg; \
pushl %eax; \
FlagNVZC \
popl %eax; \
PutToEA_Bh
#define DoRAD_d GetFromEA_Bh \
bt $C_Flag_Bit, FF_Reg; \
rcrb $1, %al; \
pushfl; \
PutToEA_Bh \
popfl; \
adcb A_Reg, %al; \
daa; \
movb %al, A_Reg; \
FlagNVZC
/* RAM = AND M, LSR A */
#define DoRAM GetFromEA_Bh \
andb %al, A_Reg; \
shrb $1, A_Reg; \
FlagNZC
/* RBM = same as RAM */
#define DoRBM DoRAM
/* REO = LSR M, EOR M */
#define DoREO GetFromEA_Bh \
shrb $1, %al; \
xorb %al, A_Reg; \
FlagNZC \
PutToEA_Bh \
/* DoZBC = same as SBC */
#define DoZBC_b DoSBC_b
#define DoZBC_d DoSBC_d
/* TEA = (A AND X AND (OP+2)+1) -> M */
#define DoTEA pushl EffectiveAddr_E; \
movw PC_Reg, EffectiveAddr; \
decw EffectiveAddr; \
GetFromEA_Bh \
popl EffectiveAddr_E; \
incb %al; \
andb A_Reg, %al; \
andb X_Reg, %al; \
FlagNZ \
PutToEA_Bh
/* TEX = (X AND (OP+2)+1) -> M */
#define DoTEX pushl EffectiveAddr_E; \
movw PC_Reg, EffectiveAddr; \
decw EffectiveAddr; \
GetFromEA_Bh \
popl EffectiveAddr_E; \
incb %al; \
andb X_Reg, %al; \
FlagNZ \
PutToEA_Bh
/* TEY = (Y AND 1) -> M */
#define DoTEY movb Y_Reg, %al; \
andb $1, %al; \
FlagNZ \
PutToEA_Bh
/* XMA = (X AND M) AND (A OR 238) -> A */
/* HACK!!!!!!!!!!!!!!! */
#define DoXMA /* the \ wasn't here before */ \
GetFromEA_Bh \
andb X_Reg, %al; \
orb $238, A_Reg; \
andb %al, A_Reg; \
FlagNZ
/* ----------------------------------------------------------------------
6502 routines and instructions
---------------------------------------------------------------------- */
/* ----------------------------------
ADC instructions
---------------------------------- */
op_ADC_dec: DoADC_d
Continue
op_ADC_imm:
GetImm
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_zpage:
GetZPage
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_zpage_x:
GetZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_abs:
GetAbs
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_abs_x:
GetAbs_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_abs_y:
GetAbs_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_ind_x:
GetIndZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_ind_y:
GetIndZPage_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
/* ----------------------------------
AND instructions
---------------------------------- */
op_AND_imm:
GetImm
DoAND
Continue
op_AND_zpage:
GetZPage
DoAND
Continue
op_AND_zpage_x:
GetZPage_X
DoAND
Continue
op_AND_abs:
GetAbs
DoAND
Continue
op_AND_abs_x:
GetAbs_X
DoAND
Continue
op_AND_abs_y:
GetAbs_Y
DoAND
Continue
op_AND_ind_x:
GetIndZPage_X
DoAND
Continue
op_AND_ind_y:
GetIndZPage_Y
DoAND
Continue
/* ----------------------------------
ASL instructions
---------------------------------- */
op_ASL_acc:
addb A_Reg, A_Reg
FlagNZC
Continue
op_ASL_zpage:
GetZPage
DoASL
Continue
op_ASL_zpage_x:
GetZPage_X
DoASL
Continue
op_ASL_abs:
GetAbs
DoASL
Continue
op_ASL_abs_x:
GetAbs_X
DoASL
Continue
/* ----------------------------------
BCC instruction
---------------------------------- */
op_BCC:
GetFromPC_B
testb $C_Flag, F_Reg
jnz op_BCC_not
cbw
addw %ax, PC_Reg
op_BCC_not:
Continue
/* ----------------------------------
BCS instruction
---------------------------------- */
op_BCS:
GetFromPC_B
testb $C_Flag, F_Reg
jz op_BCS_not
cbw
addw %ax, PC_Reg
op_BCS_not:
Continue
/* ----------------------------------
BEQ instruction
---------------------------------- */
op_BEQ:
GetFromPC_B
testb $Z_Flag, F_Reg
jz op_BEQ_not
cbw
addw %ax, PC_Reg
op_BEQ_not:
Continue
/* ----------------------------------
BIT instructions
---------------------------------- */
op_BIT_zpage:
GetZPage
DoBIT
Continue
op_BIT_abs:
GetAbs
DoBIT
Continue
/* ----------------------------------
BMI instruction
---------------------------------- */
op_BMI:
GetFromPC_B
testb F_Reg, F_Reg /* optimized check of N flag,
* which happens to be sign bit */
jns op_BMI_not
cbw
addw %ax, PC_Reg
op_BMI_not:
Continue
/* ----------------------------------
BNE instruction
---------------------------------- */
op_BNE:
GetFromPC_B
testb $Z_Flag, F_Reg
jnz op_BNE_not
cbw
addw %ax, PC_Reg
op_BNE_not:
Continue
/* ----------------------------------
BPL instruction
---------------------------------- */
op_BPL:
GetFromPC_B
testb F_Reg, F_Reg /* optimized check of N flag,
* which happens to be sign bit */
js op_BPL_not
cbw
addw %ax, PC_Reg
op_BPL_not:
Continue
/* ----------------------------------
BRK instruction
---------------------------------- */
op_UNK: /* make undefined opcodes fault */
op_BRK:
incw PC_Reg
movw PC_Reg, %ax
Push(%ah)
Push(%al)
xorl %eax,%eax
movb F_Reg, %al
orb $I_Flag, F_Reg
movb SN(cpu65_flags_encode)(,%eax,1), %al
Push(%al)
movw $0xFFFE, EffectiveAddr
GetFromEA_W
movw %ax, PC_Reg
Continue
/* ----------------------------------
BVC instruction
---------------------------------- */
op_BVC:
GetFromPC_B
testb $V_Flag, F_Reg
jnz op_BVC_not
cbw
addw %ax, PC_Reg
op_BVC_not:
Continue
/* ----------------------------------
BVS instruction
---------------------------------- */
op_BVS:
GetFromPC_B
testb $V_Flag, F_Reg
jz op_BVS_not
cbw
addw %ax, PC_Reg
op_BVS_not:
Continue
/* ----------------------------------
CLC instruction
---------------------------------- */
op_CLC:
andb $~C_Flag, F_Reg
Continue
/* ----------------------------------
CLD instruction
---------------------------------- */
op_CLD:
andb $~D_Flag, F_Reg
Continue
/* ----------------------------------
CLI instruction
---------------------------------- */
op_CLI:
andb $~I_Flag, F_Reg
Continue
/* ----------------------------------
CLV instruction
---------------------------------- */
op_CLV:
andb $~V_Flag, F_Reg
Continue
/* ----------------------------------
CMP instructions
---------------------------------- */
op_CMP_imm:
GetImm
DoCMP
Continue
op_CMP_zpage:
GetZPage
DoCMP
Continue
op_CMP_zpage_x:
GetZPage_X
DoCMP
Continue
op_CMP_abs:
GetAbs
DoCMP
Continue
op_CMP_abs_x:
GetAbs_X
DoCMP
Continue
op_CMP_abs_y:
GetAbs_Y
DoCMP
Continue
op_CMP_ind_x:
GetIndZPage_X
DoCMP
Continue
op_CMP_ind_y:
GetIndZPage_Y
DoCMP
Continue
/* ----------------------------------
CPX instructions
---------------------------------- */
op_CPX_imm:
GetImm
DoCPX
Continue
op_CPX_zpage:
GetZPage
DoCPX
Continue
op_CPX_abs:
GetAbs
DoCPX
Continue
/* ----------------------------------
CPY instructions
---------------------------------- */
op_CPY_imm:
GetImm
DoCPY
Continue
op_CPY_zpage:
GetZPage
DoCPY
Continue
op_CPY_abs:
GetAbs
DoCPY
Continue
/* ----------------------------------
DEC instructions
---------------------------------- */
op_DEC_zpage:
GetZPage
DoDEC
Continue
op_DEC_zpage_x:
GetZPage_X
DoDEC
Continue
op_DEC_abs:
GetAbs
DoDEC
Continue
op_DEC_abs_x:
GetAbs_X
DoDEC
Continue
/* ----------------------------------
DEX instruction
---------------------------------- */
op_DEX:
decb X_Reg
FlagNZ
Continue
/* ----------------------------------
DEY instruction
---------------------------------- */
op_DEY:
decb Y_Reg
FlagNZ
Continue
/* ----------------------------------
EOR instructions
---------------------------------- */
op_EOR_imm:
GetImm
DoEOR
Continue
op_EOR_zpage:
GetZPage
DoEOR
Continue
op_EOR_zpage_x:
GetZPage_X
DoEOR
Continue
op_EOR_abs:
GetAbs
DoEOR
Continue
op_EOR_abs_x:
GetAbs_X
DoEOR
Continue
op_EOR_abs_y:
GetAbs_Y
DoEOR
Continue
op_EOR_ind_x:
GetIndZPage_X
DoEOR
Continue
op_EOR_ind_y:
GetIndZPage_Y
DoEOR
Continue
/* ----------------------------------
INC instructions
---------------------------------- */
op_INC_zpage:
GetZPage
DoINC
Continue
op_INC_zpage_x:
GetZPage_X
DoINC
Continue
op_INC_abs:
GetAbs
DoINC
Continue
op_INC_abs_x:
GetAbs_X
DoINC
Continue
/* ----------------------------------
INX instruction
---------------------------------- */
op_INX:
incb X_Reg
FlagNZ
Continue
/* ----------------------------------
INY instruction
---------------------------------- */
op_INY:
incb Y_Reg
FlagNZ
Continue
/* ----------------------------------
JMP instructions
---------------------------------- */
op_JMP_abs:
GetAbs
DoJMP
Continue
op_JMP_ind:
xorl %eax, %eax
GetFromMem_B(PC_Reg_E)
xchgb %al, %ah
cmpb $0xFF, %ah
je special_case
incw PC_Reg
GetFromMem_B(PC_Reg_E)
xchgb %al, %ah
GetFromMem_W(%eax)
movw %ax, PC_Reg
Continue
special_case: /*?*/
incw PC_Reg
subw $0x100, PC_Reg
GetFromMem_B(PC_Reg_E)
xchgb %al, %ah
GetFromMem_W(%eax)
movw %ax, PC_Reg
Continue
/* ----------------------------------
JSR instruction
---------------------------------- */
op_JSR:
GetAbs
DoJSR
Continue
/* ----------------------------------
LDA instructions
---------------------------------- */
op_LDA_imm:
GetImm
DoLDA
Continue
op_LDA_zpage:
GetZPage
DoLDA
Continue
op_LDA_zpage_x:
GetZPage_X
DoLDA
Continue
op_LDA_abs:
GetAbs
DoLDA
Continue
op_LDA_abs_x:
GetAbs_X
DoLDA
Continue
op_LDA_abs_y:
GetAbs_Y
DoLDA
Continue
op_LDA_ind_x:
GetIndZPage_X
DoLDA
Continue
op_LDA_ind_y:
GetIndZPage_Y
DoLDA
Continue
/* ----------------------------------
LDX instructions
---------------------------------- */
op_LDX_imm:
GetImm
DoLDX
Continue
op_LDX_zpage:
GetZPage
DoLDX
Continue
op_LDX_zpage_y:
GetZPage_Y
DoLDX
Continue
op_LDX_abs:
GetAbs
DoLDX
Continue
op_LDX_abs_y:
GetAbs_Y
DoLDX
Continue
/* ----------------------------------
LDY instructions
---------------------------------- */
op_LDY_imm:
GetImm
DoLDY
Continue
op_LDY_zpage:
GetZPage
DoLDY
Continue
op_LDY_zpage_x:
GetZPage_X
DoLDY
Continue
op_LDY_abs:
GetAbs
DoLDY
Continue
op_LDY_abs_x:
GetAbs_X
DoLDY
Continue
/* ----------------------------------
LSR instructions
---------------------------------- */
op_LSR_acc:
shrb $1, A_Reg
FlagNZC
Continue
op_LSR_zpage:
GetZPage
DoLSR
Continue
op_LSR_zpage_x:
GetZPage_X
DoLSR
Continue
op_LSR_abs:
GetAbs
DoLSR
Continue
op_LSR_abs_x:
GetAbs_X
DoLSR
Continue
/* ----------------------------------
NOP instruction
---------------------------------- */
op_NOP:
Continue
/* ----------------------------------
ORA instructions
---------------------------------- */
op_ORA_imm:
GetImm
DoORA
Continue
op_ORA_zpage:
GetZPage
DoORA
Continue
op_ORA_zpage_x:
GetZPage_X
DoORA
Continue
op_ORA_abs:
GetAbs
DoORA
Continue
op_ORA_abs_x:
GetAbs_X
DoORA
Continue
op_ORA_abs_y:
GetAbs_Y
DoORA
Continue
op_ORA_ind_x:
GetIndZPage_X
DoORA
Continue
op_ORA_ind_y:
GetIndZPage_Y
DoORA
Continue
/* ----------------------------------
PHA instruction
---------------------------------- */
op_PHA:
Push(A_Reg)
Continue
/* ----------------------------------
PHP instruction
---------------------------------- */
op_PHP:
movb F_Reg, %al
movb SN(cpu65_flags_encode)(,%eax,1), %al
Push(%al)
Continue
/* ----------------------------------
PLA instruction
---------------------------------- */
op_PLA:
Pop(A_Reg)
orb A_Reg, A_Reg
FlagNZ
Continue
/* ----------------------------------
PLP instruction
---------------------------------- */
op_PLP:
xorl %eax, %eax
Pop(%al)
movb SN(cpu65_flags_decode)(,%eax,1), F_Reg
orb $(B_Flag|X_Flag), F_Reg
Continue
/* ----------------------------------
ROL instructions
---------------------------------- */
op_ROL_acc: bt $C_Flag_Bit, FF_Reg
adcb A_Reg, A_Reg
FlagNZC
Continue
op_ROL_zpage:
GetZPage
DoROL
Continue
op_ROL_zpage_x:
GetZPage_X
DoROL
Continue
op_ROL_abs:
GetAbs
DoROL
Continue
op_ROL_abs_x:
GetAbs_X
DoROL
Continue
/* ----------------------------------
ROR instructions
---------------------------------- */
/* NB: assumes A_Reg = %cl, F_Reg = %ch */
op_ROR_acc:
rorw $1, %cx /* Roll flags into accum */
adcb F_Reg, F_Reg /* Roll carry into flags */
orb A_Reg, A_Reg
FlagNZ /* implied C */
Continue
op_ROR_zpage:
GetZPage
DoROR
Continue
op_ROR_zpage_x:
GetZPage_X
DoROR
Continue
op_ROR_abs:
GetAbs
DoROR
Continue
op_ROR_abs_x:
GetAbs_X
DoROR
Continue
/* ----------------------------------
RTI instruction
---------------------------------- */
op_RTI:
xorl %eax, %eax
Pop(%al)
movb SN(cpu65_flags_decode)(,%eax,1), F_Reg
orb $(B_Flag|X_Flag), F_Reg
Pop(%al)
Pop(%ah)
movw %ax, PC_Reg
Continue
/* ----------------------------------
RTS instruction
---------------------------------- */
op_RTS:
Pop(%al)
Pop(%ah)
incw %ax
movw %ax, PC_Reg
Continue
/* ----------------------------------
SBC instructions
---------------------------------- */
op_SBC_dec:
DoSBC_d
Continue
op_SBC_imm:
GetImm
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_zpage:
GetZPage
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_zpage_x:
GetZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_abs:
GetAbs
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_abs_x:
GetAbs_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_abs_y:
GetAbs_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_ind_x:
GetIndZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_ind_y:
GetIndZPage_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
/* ----------------------------------
SEC instruction
---------------------------------- */
op_SEC:
orb $C_Flag, F_Reg
Continue
/* ----------------------------------
SED instruction
---------------------------------- */
op_SED:
orb $D_Flag, F_Reg
Continue
/* ----------------------------------
SEI instruction
---------------------------------- */
op_SEI:
orb $I_Flag, F_Reg
Continue
/* ----------------------------------
STA instructions
---------------------------------- */
op_STA_imm:
GetImm
DoSTA
Continue
op_STA_zpage:
GetZPage
DoSTA
Continue
op_STA_zpage_x:
GetZPage_X
DoSTA
Continue
op_STA_abs:
GetAbs
DoSTA
Continue
op_STA_abs_x:
GetAbs_X
DoSTA
Continue
op_STA_abs_y:
GetAbs_Y
DoSTA
Continue
op_STA_ind_x:
GetIndZPage_X
DoSTA
Continue
op_STA_ind_y:
GetIndZPage_Y
DoSTA
Continue
/* ----------------------------------
STX instructions
---------------------------------- */
op_STX_zpage:
GetZPage
DoSTX
Continue
op_STX_zpage_y:
GetZPage_Y
DoSTX
Continue
op_STX_abs:
GetAbs
DoSTX
Continue
/* ----------------------------------
STY instructions
---------------------------------- */
op_STY_zpage:
GetZPage
DoSTY
Continue
op_STY_zpage_x:
GetZPage_X
DoSTY
Continue
op_STY_abs:
GetAbs
DoSTY
Continue
/* ----------------------------------
TAX instruction
---------------------------------- */
op_TAX:
movb A_Reg, X_Reg
orb X_Reg, X_Reg
FlagNZ
Continue
/* ----------------------------------
TAY instruction
---------------------------------- */
op_TAY:
movb A_Reg, Y_Reg
orb Y_Reg, Y_Reg
FlagNZ
Continue
/* ----------------------------------
TSX instruction
---------------------------------- */
op_TSX:
movb SP_Reg_L, X_Reg
orb X_Reg, X_Reg
FlagNZ
Continue
/* ----------------------------------
TXA instruction
---------------------------------- */
op_TXA:
movb X_Reg, A_Reg
orb A_Reg, A_Reg
FlagNZ
Continue
/* ----------------------------------
TXS instruction
---------------------------------- */
op_TXS:
movb X_Reg, SP_Reg_L
Continue
/* ----------------------------------
TYA instruction
---------------------------------- */
op_TYA:
movb Y_Reg, A_Reg
orb A_Reg, A_Reg
FlagNZ
Continue
#ifdef APPLE_IIE
/* ----------------------------------------------------------------------
65c02 routines and instructions
---------------------------------------------------------------------- */
/* ----------------------------------
ADC instruction
---------------------------------- */
op_ADC_ind_zpage: # 72
GetIndZPage
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ADC_dec # Yes, jump to decimal version
DoADC_b
Continue
op_ADC_ind_zpage_dec:
DoADC_d
Continue
/* ----------------------------------
AND instruction
---------------------------------- */
op_AND_ind_zpage: # 32
GetIndZPage
DoAND
Continue
/* ----------------------------------
BIT instructions
---------------------------------- */
op_BIT_zpage_x: # 34
GetIndZPage
DoBIT
Continue
op_BIT_abs_x: # 3C
GetAbs_X
DoBIT
Continue
/* BIT immediate is anomalous in that it does not affect the
* N and V flags, unlike in other addressing modes.
*/
op_BIT_imm: # 89
GetImm
GetFromEA_Bh
testb %al, A_Reg
FlagZ
Continue
/* ----------------------------------
BRA instruction
---------------------------------- */
op_BRA: # 80
GetFromPC_B
cbw
addw %ax, PC_Reg
Continue
/* ----------------------------------
CMP instruction
---------------------------------- */
op_CMP_ind_zpage: # D2
GetIndZPage
DoCMP
Continue
/* ----------------------------------
DEA instruction
---------------------------------- */
op_DEA: # 3A
decb A_Reg
FlagNZ
Continue
/* ----------------------------------
EOR instruction
---------------------------------- */
op_EOR_ind_zpage: # 52
GetIndZPage
DoEOR
Continue
/* ----------------------------------
INA instruction
---------------------------------- */
op_INA: # 1A
incb A_Reg
FlagNZ
Continue
/* ----------------------------------
JMP instructions
---------------------------------- */
op_JMP_ind_65c02: # 6C - different from 6502
xorl %eax, %eax
GetFromMem_B(PC_Reg_E)
xchgb %al, %ah
incw PC_Reg
GetFromMem_B(PC_Reg_E)
xchgb %al, %ah
GetFromMem_W(%eax)
movw %ax, PC_Reg
Continue
op_JMP_abs_ind_x: # 7C
GetFromPC_W
movw %ax, EffectiveAddr
movzbl X_Reg, %eax
addw %ax, EffectiveAddr
GetFromMem_W(EffectiveAddr_E)
movw %ax, PC_Reg
Continue
/* ----------------------------------
LDA instruction
---------------------------------- */
op_LDA_ind_zpage: # B2
GetIndZPage
DoLDA
Continue
/* ----------------------------------
ORA instruction
---------------------------------- */
op_ORA_ind_zpage: # 12
GetIndZPage
DoORA
Continue
/* ----------------------------------
PHX instruction
---------------------------------- */
op_PHX: # DA
Push(X_Reg)
Continue
/* ----------------------------------
PHY instruction
---------------------------------- */
op_PHY: # 5A
Push(Y_Reg)
Continue
/* ----------------------------------
PLX instruction
---------------------------------- */
op_PLX: # FA
Pop(X_Reg)
orb X_Reg, X_Reg
FlagNZ
Continue
/* ----------------------------------
PLY instruction
---------------------------------- */
op_PLY: # 7A
Pop(Y_Reg)
orb Y_Reg, Y_Reg
FlagNZ
Continue
/* ----------------------------------
STA instruction
---------------------------------- */
op_STA_ind_zpage: # 92
GetIndZPage
DoSTA
Continue
/* ----------------------------------
SBC instruction
---------------------------------- */
op_SBC_ind_zpage: # F2
GetIndZPage
testb $D_Flag, F_Reg # Decimal mode?
jnz op_SBC_dec # Yes, jump to decimal version
DoSBC_b
Continue
op_SBC_ind_zpage_dec:
DoSBC_d
Continue
/* ----------------------------------
STZ instructions
---------------------------------- */
op_STZ_zpage: # 64
GetZPage
DoSTZ
Continue
op_STZ_zpage_x: # 74
GetZPage_X
Continue
op_STZ_abs: # 9C
GetAbs
DoSTZ
Continue
op_STZ_abs_x: # 9E
GetAbs_X
DoSTZ
Continue
/* ----------------------------------
TRB instructions
---------------------------------- */
op_TRB_abs: # 1C
GetAbs
DoTRB
Continue
op_TRB_zpage: # 14
GetZPage
DoTRB
Continue
/* ----------------------------------
TSB instructions
---------------------------------- */
op_TSB_abs: # 0C
GetAbs
DoTSB
Continue
op_TSB_zpage: # 04
GetZPage
DoTSB
Continue
/* ----------------------------------
??? instruction - 65c02
---------------------------------- */
op_UNK_65c02:
Continue
#endif /* APPLE_IIE */
/* ----------------------------------------------------------------------
Undocumented 6502 (Illegal instructions)
---------------------------------------------------------------------- */
/* ----------------------------------
HANG instruction
---------------------------------- */
op_HANG:
decw PC_Reg
Continue
/* ----------------------------------
NOP_2 instruction
---------------------------------- */
op_NOP_2:
incw PC_Reg
Continue
/* ----------------------------------
NOP_3 instruction
---------------------------------- */
op_NOP_3:
addw $2, PC_Reg
Continue
/* ----------------------------------
AAX instructions
---------------------------------- */
op_AAX_abs:
GetAbs
DoAAX
Continue
op_AAX_zpage:
GetZPage
DoAAX
Continue
op_AAX_zpage_y:
GetZPage_Y
DoAAX
Continue
op_AAX_ind_x:
GetIndZPage_X
DoAAX
Continue
op_AAX_ind_y:
GetIndZPage_Y
DoAAX
Continue
/* ----------------------------------
AMA instruction
---------------------------------- */
op_AMA_imm:
GetImm
DoAMA
Continue
/* ----------------------------------
ANA instruction
---------------------------------- */
op_ANA_imm:
GetImm
DoANA
Continue
/* ----------------------------------
ANB instruction
---------------------------------- */
op_ANB_imm:
GetImm
DoANB
Continue
/* ----------------------------------
AXM instruction
---------------------------------- */
op_AXM_imm:
GetImm
DoAXM
Continue
/* ----------------------------------
AXS instruction
---------------------------------- */
op_AXS_abs_y:
GetAbs_Y
DoAXS
Continue
/* ----------------------------------
DCP instructions
---------------------------------- */
op_DCP_zpage:
GetZPage
DoDCP
Continue
op_DCP_zpage_x:
GetZPage_X
DoDCP
Continue
op_DCP_abs:
GetAbs
DoDCP
Continue
op_DCP_abs_x:
GetAbs_X
DoDCP
Continue
op_DCP_abs_y:
GetAbs_Y
DoDCP
Continue
op_DCP_ind_x:
GetIndZPage_X
DoDCP
Continue
op_DCP_ind_y:
GetIndZPage_Y
DoDCP
Continue
/* ----------------------------------
ISB instructions
---------------------------------- */
op_ISB_dec:
DoISB_d
Continue
op_ISB_zpage:
GetZPage
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
op_ISB_zpage_x:
GetZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
op_ISB_abs:
GetAbs
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
op_ISB_abs_x:
GetAbs_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
op_ISB_abs_y:
GetAbs_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
op_ISB_ind_x:
GetIndZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
op_ISB_ind_y:
GetIndZPage_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ISB_dec # Yes, jump to decimal version
DoISB_b
Continue
/* ----------------------------------
LAN instructions
---------------------------------- */
op_LAN_zpage:
GetZPage
DoLAN
Continue
op_LAN_zpage_x:
GetZPage_X
DoLAN
Continue
op_LAN_abs:
GetAbs
DoLAN
Continue
op_LAN_abs_x:
GetAbs_X
DoLAN
Continue
op_LAN_abs_y:
GetAbs_Y
DoLAN
Continue
op_LAN_ind_x:
GetIndZPage_X
DoLAN
Continue
op_LAN_ind_y:
GetIndZPage_Y
DoLAN
Continue
/* ----------------------------------
LAS instruction
---------------------------------- */
op_LAS_abs_y:
GetAbs_Y
DoLAS
Continue
/* ----------------------------------
LAX instructions
---------------------------------- */
op_LAX_zpage:
GetZPage
DoLAX
Continue
op_LAX_zpage_y:
GetZPage_Y
DoLAX
Continue
op_LAX_abs:
GetAbs
DoLAX
Continue
op_LAX_abs_y:
GetAbs_Y
DoLAX
Continue
op_LAX_ind_x:
GetIndZPage_X
DoLAX
Continue
op_LAX_ind_y:
GetIndZPage_Y
DoLAX
Continue
/* ----------------------------------
LOR instructions
---------------------------------- */
op_LOR_zpage:
GetZPage
DoLOR
Continue
op_LOR_zpage_x:
GetZPage_X
DoLOR
Continue
op_LOR_abs:
GetAbs
DoLOR
Continue
op_LOR_abs_x:
GetAbs_X
DoLOR
Continue
op_LOR_abs_y:
GetAbs_Y
DoLOR
Continue
op_LOR_ind_x:
GetIndZPage_X
DoLOR
Continue
op_LOR_ind_y:
GetIndZPage_Y
DoLOR
Continue
/* ----------------------------------
RAD instructions
---------------------------------- */
op_RAD_dec:
DoRAD_d
Continue
op_RAD_zpage:
GetZPage
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
op_RAD_zpage_x:
GetZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
op_RAD_abs:
GetAbs
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
op_RAD_abs_x:
GetAbs_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
op_RAD_abs_y:
GetAbs_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
op_RAD_ind_x:
GetIndZPage_X
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
op_RAD_ind_y:
GetIndZPage_Y
testb $D_Flag, F_Reg # Decimal mode?
jnz op_RAD_dec # Yes, jump to decimal version
DoRAD_b
Continue
/* ----------------------------------
RAM instruction
---------------------------------- */
op_RAM_imm:
GetImm
DoRAM
Continue
/* ----------------------------------
RBM instruction
---------------------------------- */
op_RBM_imm:
GetImm
DoRBM
Continue
/* ----------------------------------
REO instructions
---------------------------------- */
op_REO_zpage:
GetZPage
DoREO
Continue
op_REO_zpage_x:
GetZPage_X
DoREO
Continue
op_REO_abs:
GetAbs
DoREO
Continue
op_REO_abs_x:
GetAbs_X
DoREO
Continue
op_REO_abs_y:
GetAbs_Y
DoREO
Continue
op_REO_ind_x:
GetIndZPage_X
DoREO
Continue
op_REO_ind_y:
GetIndZPage_Y
DoREO
Continue
/* ----------------------------------
ZBC instruction
---------------------------------- */
op_ZBC_imm:
GetImm
testb $D_Flag, F_Reg # Decimal mode?
jnz op_ZBC_dec # Yes, jump to decimal version
DoZBC_b
Continue
op_ZBC_dec:
DoZBC_d
Continue
/* ----------------------------------
TEA instruction
---------------------------------- */
op_TEA_abs_y:
GetAbs_Y
DoTEA
Continue
/* ----------------------------------
TEX instruction
---------------------------------- */
op_TEX_abs_y:
GetAbs_Y
DoTEX
Continue
/* ----------------------------------
TEY instruction
---------------------------------- */
op_TEY_abs_x:
GetAbs_X
DoTEY
Continue
/* ----------------------------------
XMA instruction
---------------------------------- */
op_XMA_imm:
GetImm
DoXMA
Continue
/* Exception handler */
#ifdef DEBUGGER
exception: cmpb $RebootSig, %ah
jz ex_reboot
cmpb $ResetSig, %ah
jz ex_reset
cmpb $DebugStepSig, %ah
jz ex_step
jmp ex_enter
ex_step: SaveState
movb $0, SN(cpu65__signal)
popal
ret
ex_enter: SaveState
movb $0, SN(cpu65__signal)
pushal
call SN(enter_debugger)
popal
ReplaceState
xorb %ah, %ah
GetFromPC_B
jmp *cpu65__opcodes(,%eax,4)
ex_reboot: popal
movb $0, SN(cpu65__signal)
ret
ex_reset: movb $0, SN(cpu65__signal)
movw $0xfffc, EffectiveAddr
GetFromEA_W
movw %ax, PC_Reg
xorb %ah, %ah
GetFromPC_B
jmp *cpu65__opcodes(,%eax,4)
#else /* !DEBUGGER */
exception: cmpb $RebootSig, %ah
jz ex_reboot
ex_reset: movb $0, SN(cpu65__signal)
movw $0xfffc, EffectiveAddr
GetFromEA_W
movw %ax, PC_Reg
xorb %ah, %ah
GetFromPC_B
jmp *cpu65__opcodes(,%eax,4)
ex_reboot: popal
movb $0, SN(cpu65__signal)
ret;
#endif /* !DEBUGGER */
/* -----------------------------------------------------------------
* Begin emulation.
* ----------------------------------------------------------------- */
E(cpu65_run)
pushal
/* Zero all registers, as well as the unused 32-bit parts
* of variables. (which may need to be kept 0)
*
* Note: dependent on assignment of registers */
xorl %eax, %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %esi, %esi
xorl %edi, %edi
movl $0x1FF, %edx # Stack pointer
jmp ex_reset
#ifdef DEBUGGER
E (cpu65_direct_write)
/* NB: dependent on register choices */
pushl %edi
movl 8(%esp),%edi
movl 12(%esp),%eax
call * SN(cpu65_vmem)+4(,EffectiveAddr_E,8)
popl %edi
ret
/* -------------------------------------------------------------------------
steps the simulation while remaining in the debugger's control
------------------------------------------------------------------------- */
E(cpu65_step)
pushal
movb $DebugStepSig,SN(cpu65__signal)
ReplaceState
GetFromPC_B
jmp *cpu65__opcodes(,%eax,4)
#endif
/* Tables */
.align 4
E(cpu65__nmosbrk)
.long op_BRK
.long op_ORA_ind_x
.long op_UNK
.long op_UNK
.long op_UNK
.long op_ORA_zpage
.long op_ASL_zpage
.long op_UNK
.long op_PHP
.long op_ORA_imm
.long op_ASL_acc
.long op_UNK
.long op_UNK
.long op_ORA_abs
.long op_ASL_abs
.long op_UNK
.long op_BPL
.long op_ORA_ind_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_ORA_zpage_x
.long op_ASL_zpage_x
.long op_UNK
.long op_CLC
.long op_ORA_abs_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_ORA_abs_x
.long op_ASL_abs_x
.long op_UNK
.long op_JSR
.long op_AND_ind_x
.long op_UNK
.long op_UNK
.long op_BIT_zpage
.long op_AND_zpage
.long op_ROL_zpage
.long op_UNK
.long op_PLP
.long op_AND_imm
.long op_ROL_acc
.long op_UNK
.long op_BIT_abs
.long op_AND_abs
.long op_ROL_abs
.long op_UNK
.long op_BMI
.long op_AND_ind_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_AND_zpage_x
.long op_ROL_zpage_x
.long op_UNK
.long op_SEC
.long op_AND_abs_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_AND_abs_x
.long op_ROL_abs_x
.long op_UNK
.long op_RTI
.long op_EOR_ind_x
.long op_UNK
.long op_UNK
.long op_UNK
.long op_EOR_zpage
.long op_LSR_zpage
.long op_UNK
.long op_PHA
.long op_EOR_imm
.long op_LSR_acc
.long op_UNK
.long op_JMP_abs
.long op_EOR_abs
.long op_LSR_abs
.long op_UNK
.long op_BVC
.long op_EOR_ind_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_EOR_zpage_x
.long op_LSR_zpage_x
.long op_UNK
.long op_CLI
.long op_EOR_abs_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_EOR_abs_x
.long op_LSR_abs_x
.long op_UNK
.long op_RTS
.long op_ADC_ind_x
.long op_UNK
.long op_UNK
.long op_UNK
.long op_ADC_zpage
.long op_ROR_zpage
.long op_UNK
.long op_PLA
.long op_ADC_imm
.long op_ROR_acc
.long op_UNK
.long op_JMP_ind
.long op_ADC_abs
.long op_ROR_abs
.long op_UNK
.long op_BVS
.long op_ADC_ind_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_ADC_zpage_x
.long op_ROR_zpage_x
.long op_UNK
.long op_SEI
.long op_ADC_abs_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_ADC_abs_x
.long op_ROR_abs_x
.long op_UNK
.long op_UNK
.long op_STA_ind_x
.long op_UNK
.long op_UNK
.long op_STY_zpage
.long op_STA_zpage
.long op_STX_zpage
.long op_UNK
.long op_DEY
.long op_UNK
.long op_TXA
.long op_UNK
.long op_STY_abs
.long op_STA_abs
.long op_STX_abs
.long op_UNK
.long op_BCC
.long op_STA_ind_y
.long op_UNK
.long op_UNK
.long op_STY_zpage_x
.long op_STA_zpage_x
.long op_STX_zpage_y
.long op_UNK
.long op_TYA
.long op_STA_abs_y
.long op_TXS
.long op_UNK
.long op_UNK
.long op_STA_abs_x
.long op_UNK
.long op_UNK
.long op_LDY_imm
.long op_LDA_ind_x
.long op_LDX_imm
.long op_UNK
.long op_LDY_zpage
.long op_LDA_zpage
.long op_LDX_zpage
.long op_UNK
.long op_TAY
.long op_LDA_imm
.long op_TAX
.long op_UNK
.long op_LDY_abs
.long op_LDA_abs
.long op_LDX_abs
.long op_UNK
.long op_BCS
.long op_LDA_ind_y
.long op_UNK
.long op_UNK
.long op_LDY_zpage_x
.long op_LDA_zpage_x
.long op_LDX_zpage_y
.long op_UNK
.long op_CLV
.long op_LDA_abs_y
.long op_TSX
.long op_UNK
.long op_LDY_abs_x
.long op_LDA_abs_x
.long op_LDX_abs_y
.long op_UNK
.long op_CPY_imm
.long op_CMP_ind_x
.long op_UNK
.long op_UNK
.long op_CPY_zpage
.long op_CMP_zpage
.long op_DEC_zpage
.long op_UNK
.long op_INY
.long op_CMP_imm
.long op_DEX
.long op_UNK
.long op_CPY_abs
.long op_CMP_abs
.long op_DEC_abs
.long op_UNK
.long op_BNE
.long op_CMP_ind_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_CMP_zpage_x
.long op_DEC_zpage_x
.long op_UNK
.long op_CLD
.long op_CMP_abs_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_CMP_abs_x
.long op_DEC_abs_x
.long op_UNK
.long op_CPX_imm
.long op_SBC_ind_x
.long op_UNK
.long op_UNK
.long op_CPX_zpage
.long op_SBC_zpage
.long op_INC_zpage
.long op_UNK
.long op_INX
.long op_SBC_imm
.long op_NOP
.long op_UNK
.long op_CPX_abs
.long op_SBC_abs
.long op_INC_abs
.long op_UNK
.long op_BEQ
.long op_SBC_ind_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_SBC_zpage_x
.long op_INC_zpage_x
.long op_UNK
.long op_SED
.long op_SBC_abs_y
.long op_UNK
.long op_UNK
.long op_UNK
.long op_SBC_abs_x
.long op_INC_abs_x
.long op_UNK
#ifdef APPLE_IIE
E(cpu65__cmos)
.long op_BRK
.long op_ORA_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_TSB_zpage
.long op_ORA_zpage
.long op_ASL_zpage
.long op_UNK_65c02
.long op_PHP
.long op_ORA_imm
.long op_ASL_acc
.long op_UNK_65c02
.long op_TSB_abs
.long op_ORA_abs
.long op_ASL_abs
.long op_UNK_65c02
.long op_BPL
.long op_ORA_ind_y
.long op_ORA_ind_zpage
.long op_UNK_65c02
.long op_TRB_zpage
.long op_ORA_zpage_x
.long op_ASL_zpage_x
.long op_UNK_65c02
.long op_CLC
.long op_ORA_abs_y
.long op_INA
.long op_UNK_65c02
.long op_TRB_abs
.long op_ORA_abs_x
.long op_ASL_abs_x
.long op_UNK_65c02
.long op_JSR
.long op_AND_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_BIT_zpage
.long op_AND_zpage
.long op_ROL_zpage
.long op_UNK_65c02
.long op_PLP
.long op_AND_imm
.long op_ROL_acc
.long op_UNK_65c02
.long op_BIT_abs
.long op_AND_abs
.long op_ROL_abs
.long op_UNK_65c02
.long op_BMI
.long op_AND_ind_y
.long op_AND_ind_zpage
.long op_UNK_65c02
.long op_BIT_zpage_x
.long op_AND_zpage_x
.long op_ROL_zpage_x
.long op_UNK_65c02
.long op_SEC
.long op_AND_abs_y
.long op_DEA
.long op_UNK_65c02
.long op_BIT_abs_x
.long op_AND_abs_x
.long op_ROL_abs_x
.long op_UNK_65c02
.long op_RTI
.long op_EOR_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_UNK_65c02
.long op_EOR_zpage
.long op_LSR_zpage
.long op_UNK_65c02
.long op_PHA
.long op_EOR_imm
.long op_LSR_acc
.long op_UNK_65c02
.long op_JMP_abs
.long op_EOR_abs
.long op_LSR_abs
.long op_UNK_65c02
.long op_BVC
.long op_EOR_ind_y
.long op_EOR_ind_zpage
.long op_UNK_65c02
.long op_UNK_65c02
.long op_EOR_zpage_x
.long op_LSR_zpage_x
.long op_UNK_65c02
.long op_CLI
.long op_EOR_abs_y
.long op_PHY
.long op_UNK_65c02
.long op_UNK_65c02
.long op_EOR_abs_x
.long op_LSR_abs_x
.long op_UNK_65c02
.long op_RTS
.long op_ADC_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_STZ_zpage
.long op_ADC_zpage
.long op_ROR_zpage
.long op_UNK_65c02
.long op_PLA
.long op_ADC_imm
.long op_ROR_acc
.long op_UNK_65c02
.long op_JMP_ind_65c02
.long op_ADC_abs
.long op_ROR_abs
.long op_UNK_65c02
.long op_BVS
.long op_ADC_ind_y
.long op_ADC_ind_zpage
.long op_UNK_65c02
.long op_STZ_zpage_x
.long op_ADC_zpage_x
.long op_ROR_zpage_x
.long op_UNK_65c02
.long op_SEI
.long op_ADC_abs_y
.long op_PLY
.long op_UNK_65c02
.long op_JMP_abs_ind_x
.long op_ADC_abs_x
.long op_ROR_abs_x
.long op_UNK_65c02
.long op_BRA
.long op_STA_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_STY_zpage
.long op_STA_zpage
.long op_STX_zpage
.long op_UNK_65c02
.long op_DEY
.long op_BIT_imm
.long op_TXA
.long op_UNK_65c02
.long op_STY_abs
.long op_STA_abs
.long op_STX_abs
.long op_UNK_65c02
.long op_BCC
.long op_STA_ind_y
.long op_STA_ind_zpage
.long op_UNK_65c02
.long op_STY_zpage_x
.long op_STA_zpage_x
.long op_STX_zpage_y
.long op_UNK_65c02
.long op_TYA
.long op_STA_abs_y
.long op_TXS
.long op_UNK_65c02
.long op_STZ_abs
.long op_STA_abs_x
.long op_STZ_abs_x
.long op_UNK_65c02
.long op_LDY_imm
.long op_LDA_ind_x
.long op_LDX_imm
.long op_UNK_65c02
.long op_LDY_zpage
.long op_LDA_zpage
.long op_LDX_zpage
.long op_UNK_65c02
.long op_TAY
.long op_LDA_imm
.long op_TAX
.long op_UNK_65c02
.long op_LDY_abs
.long op_LDA_abs
.long op_LDX_abs
.long op_UNK_65c02
.long op_BCS
.long op_LDA_ind_y
.long op_LDA_ind_zpage
.long op_UNK_65c02
.long op_LDY_zpage_x
.long op_LDA_zpage_x
.long op_LDX_zpage_y
.long op_UNK_65c02
.long op_CLV
.long op_LDA_abs_y
.long op_TSX
.long op_UNK_65c02
.long op_LDY_abs_x
.long op_LDA_abs_x
.long op_LDX_abs_y
.long op_UNK_65c02
.long op_CPY_imm
.long op_CMP_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_CPY_zpage
.long op_CMP_zpage
.long op_DEC_zpage
.long op_UNK_65c02
.long op_INY
.long op_CMP_imm
.long op_DEX
.long op_UNK_65c02
.long op_CPY_abs
.long op_CMP_abs
.long op_DEC_abs
.long op_UNK_65c02
.long op_BNE
.long op_CMP_ind_y
.long op_CMP_ind_zpage
.long op_UNK_65c02
.long op_UNK_65c02
.long op_CMP_zpage_x
.long op_DEC_zpage_x
.long op_UNK_65c02
.long op_CLD
.long op_CMP_abs_y
.long op_PHX
.long op_UNK_65c02
.long op_UNK_65c02
.long op_CMP_abs_x
.long op_DEC_abs_x
.long op_UNK_65c02
.long op_CPX_imm
.long op_SBC_ind_x
.long op_UNK_65c02
.long op_UNK_65c02
.long op_CPX_zpage
.long op_SBC_zpage
.long op_INC_zpage
.long op_UNK_65c02
.long op_INX
.long op_SBC_imm
.long op_NOP
.long op_UNK_65c02
.long op_CPX_abs
.long op_SBC_abs
.long op_INC_abs
.long op_UNK_65c02
.long op_BEQ
.long op_SBC_ind_y
.long op_SBC_ind_zpage
.long op_UNK_65c02
.long op_UNK_65c02
.long op_SBC_zpage_x
.long op_INC_zpage_x
.long op_UNK_65c02
.long op_SED
.long op_SBC_abs_y
.long op_PLX
.long op_UNK_65c02
.long op_UNK_65c02
.long op_SBC_abs_x
.long op_INC_abs_x
.long op_UNK_65c02
#endif /* HAVE_IIE */
E(cpu65__nmos)
.long op_BRK
.long op_ORA_ind_x
.long op_HANG
.long op_LOR_ind_x
.long op_NOP_2
.long op_ORA_zpage
.long op_ASL_zpage
.long op_LOR_zpage
.long op_PHP
.long op_ORA_imm
.long op_ASL_acc
.long op_ANA_imm
.long op_NOP_3
.long op_ORA_abs
.long op_ASL_abs
.long op_LOR_abs
.long op_BPL
.long op_ORA_ind_y
.long op_HANG
.long op_LOR_ind_y
.long op_NOP_2
.long op_ORA_zpage_x
.long op_ASL_zpage_x
.long op_LOR_zpage_x
.long op_CLC
.long op_ORA_abs_y
.long op_NOP
.long op_LOR_abs_y
.long op_NOP_3
.long op_ORA_abs_x
.long op_ASL_abs_x
.long op_LOR_abs_x
.long op_JSR
.long op_AND_ind_x
.long op_HANG
.long op_LAN_ind_x
.long op_BIT_zpage
.long op_AND_zpage
.long op_ROL_zpage
.long op_LAN_zpage
.long op_PLP
.long op_AND_imm
.long op_ROL_acc
.long op_ANB_imm
.long op_BIT_abs
.long op_AND_abs
.long op_ROL_abs
.long op_LAN_abs
.long op_BMI
.long op_AND_ind_y
.long op_HANG
.long op_LAN_ind_y
.long op_NOP_2
.long op_AND_zpage_x
.long op_ROL_zpage_x
.long op_LAN_zpage_x
.long op_SEC
.long op_AND_abs_y
.long op_NOP
.long op_LAN_abs_y
.long op_NOP_3
.long op_AND_abs_x
.long op_ROL_abs_x
.long op_LAN_abs_x
.long op_RTI
.long op_EOR_ind_x
.long op_HANG
.long op_REO_ind_x
.long op_NOP_2
.long op_EOR_zpage
.long op_LSR_zpage
.long op_REO_zpage
.long op_PHA
.long op_EOR_imm
.long op_LSR_acc
.long op_RAM_imm
.long op_JMP_abs
.long op_EOR_abs
.long op_LSR_abs
.long op_REO_abs
.long op_BVC
.long op_EOR_ind_y
.long op_HANG
.long op_REO_ind_y
.long op_NOP_2
.long op_EOR_zpage_x
.long op_LSR_zpage_x
.long op_REO_zpage_x
.long op_CLI
.long op_EOR_abs_y
.long op_NOP
.long op_REO_abs_y
.long op_NOP_3
.long op_EOR_abs_x
.long op_LSR_abs_x
.long op_REO_abs_x
.long op_RTS
.long op_ADC_ind_x
.long op_HANG
.long op_RAD_ind_x
.long op_NOP_2
.long op_ADC_zpage
.long op_ROR_zpage
.long op_RAD_zpage
.long op_PLA
.long op_ADC_imm
.long op_ROR_acc
.long op_RBM_imm
.long op_JMP_ind
.long op_ADC_abs
.long op_ROR_abs
.long op_RAD_abs
.long op_BVS
.long op_ADC_ind_y
.long op_HANG
.long op_RAD_ind_y
.long op_NOP_2
.long op_ADC_zpage_x
.long op_ROR_zpage_x
.long op_RAD_zpage_x
.long op_SEI
.long op_ADC_abs_y
.long op_NOP
.long op_RAD_abs_y
.long op_NOP_3
.long op_ADC_abs_x
.long op_ROR_abs_x
.long op_RAD_abs_x
.long op_NOP_2
.long op_STA_ind_x
.long op_NOP_2
.long op_AAX_ind_x
.long op_STY_zpage
.long op_STA_zpage
.long op_STX_zpage
.long op_AAX_zpage
.long op_DEY
.long op_NOP_2
.long op_TXA
.long op_XMA_imm
.long op_STY_abs
.long op_STA_abs
.long op_STX_abs
.long op_AAX_abs
.long op_BCC
.long op_STA_ind_y
.long op_HANG
.long op_AAX_ind_y
.long op_STY_zpage_x
.long op_STA_zpage_x
.long op_STX_zpage_y
.long op_AAX_zpage_y
.long op_TYA
.long op_STA_abs_y
.long op_TXS
.long op_AXS_abs_y
.long op_TEY_abs_x
.long op_STA_abs_x
.long op_TEX_abs_y
.long op_TEA_abs_y
.long op_LDY_imm
.long op_LDA_ind_x
.long op_LDX_imm
.long op_LAX_ind_x
.long op_LDY_zpage
.long op_LDA_zpage
.long op_LDX_zpage
.long op_LAX_zpage
.long op_TAY
.long op_LDA_imm
.long op_TAX
.long op_AMA_imm
.long op_LDY_abs
.long op_LDA_abs
.long op_LDX_abs
.long op_LAX_abs
.long op_BCS
.long op_LDA_ind_y
.long op_HANG
.long op_LAX_ind_y
.long op_LDY_zpage_x
.long op_LDA_zpage_x
.long op_LDX_zpage_y
.long op_LAX_zpage_y
.long op_CLV
.long op_LDA_abs_y
.long op_TSX
.long op_LAS_abs_y
.long op_LDY_abs_x
.long op_LDA_abs_x
.long op_LDX_abs_y
.long op_LAX_abs_y
.long op_CPY_imm
.long op_CMP_ind_x
.long op_NOP_2
.long op_DCP_ind_x
.long op_CPY_zpage
.long op_CMP_zpage
.long op_DEC_zpage
.long op_DCP_zpage
.long op_INY
.long op_CMP_imm
.long op_DEX
.long op_AXM_imm
.long op_CPY_abs
.long op_CMP_abs
.long op_DEC_abs
.long op_DCP_abs
.long op_BNE
.long op_CMP_ind_y
.long op_HANG
.long op_DCP_ind_y
.long op_NOP_2
.long op_CMP_zpage_x
.long op_DEC_zpage_x
.long op_DCP_zpage_x
.long op_CLD
.long op_CMP_abs_y
.long op_NOP
.long op_DCP_abs_y
.long op_NOP_3
.long op_CMP_abs_x
.long op_DEC_abs_x
.long op_DCP_abs_x
.long op_CPX_imm
.long op_SBC_ind_x
.long op_NOP_2
.long op_ISB_ind_x
.long op_CPX_zpage
.long op_SBC_zpage
.long op_INC_zpage
.long op_ISB_zpage
.long op_INX
.long op_SBC_imm
.long op_NOP
.long op_ZBC_imm
.long op_CPX_abs
.long op_SBC_abs
.long op_INC_abs
.long op_ISB_abs
.long op_BEQ
.long op_SBC_ind_y
.long op_HANG
.long op_ISB_ind_y
.long op_NOP_2
.long op_SBC_zpage_x
.long op_INC_zpage_x
.long op_ISB_zpage_x
.long op_SED
.long op_SBC_abs_y
.long op_NOP
.long op_ISB_abs_y
.long op_NOP_3
.long op_SBC_abs_x
.long op_INC_abs_x
.long op_ISB_abs_x