2013-07-06 05:44:57 +00:00
|
|
|
/*
|
2013-06-11 07:08:15 +00:00
|
|
|
* 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
|
2013-07-06 05:44:57 +00:00
|
|
|
* version 2 or later (your choice) as published by the Free Software
|
2013-06-11 07:08:15 +00:00
|
|
|
* Foundation.
|
|
|
|
*
|
2013-07-06 05:44:57 +00:00
|
|
|
* THERE ARE NO WARRANTIES WHATSOEVER.
|
2013-06-11 07:08:15 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-06-07 17:54:56 +00:00
|
|
|
#include "cpu-regs.h"
|
2014-06-07 20:08:01 +00:00
|
|
|
#include "apple2.h"
|
2013-06-11 07:08:15 +00:00
|
|
|
#include "misc.h"
|
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
#define DebugCurrEA SN(cpu65_debug)
|
|
|
|
#define DebugCurrByte SN(cpu65_debug)+2
|
2013-07-22 00:20:03 +00:00
|
|
|
#define DebugCurrRW SN(cpu65_debug)+3
|
2013-07-23 06:49:01 +00:00
|
|
|
#define DebugCurrOpcode SN(cpu65_debug)+4
|
2014-01-25 22:13:38 +00:00
|
|
|
#define DebugCycleCount SN(cpu65_debug)+5
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2013-06-11 07:08:15 +00:00
|
|
|
/* -------------------------------------------------------------------------
|
|
|
|
CPU (6502) Helper Routines
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetFromPC_B \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ PC_Reg_X, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
incw PC_Reg; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define GetFromPC_W \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ PC_Reg_X, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
incw EffectiveAddr; \
|
|
|
|
addw $2, PC_Reg; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR); \
|
2014-06-07 18:29:07 +00:00
|
|
|
decw EffectiveAddr; \
|
|
|
|
movb %al, %ah; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define JumpNextInstruction \
|
|
|
|
GetFromPC_B \
|
|
|
|
movb %al, DebugCurrOpcode; \
|
|
|
|
movb $0, DebugCycleCount; \
|
|
|
|
movb $0, DebugCurrRW; \
|
2014-06-07 19:06:29 +00:00
|
|
|
jmp *cpu65__opcodes(,_XAX,SZ_PTR);
|
2013-07-06 06:08:55 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetFromEA_B \
|
|
|
|
orb $1, DebugCurrRW; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define GetFromEA_W \
|
|
|
|
incw EffectiveAddr; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR); \
|
2014-06-07 18:29:07 +00:00
|
|
|
decw EffectiveAddr; \
|
|
|
|
movb %al, %ah; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define PutToEA_B \
|
|
|
|
orb $2, DebugCurrRW; \
|
|
|
|
movb %al, DebugCurrByte; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_w)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define GetFromMem_B(x) \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ x, EffectiveAddr_X; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define GetFromMem_W(x) \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ x, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
incw EffectiveAddr; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR); \
|
2014-06-07 18:29:07 +00:00
|
|
|
decw EffectiveAddr; \
|
|
|
|
movb %al, %ah; \
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_r)(,EffectiveAddr_X,SZ_PTR);
|
2014-06-07 18:29:07 +00:00
|
|
|
|
|
|
|
#define Continue \
|
2013-07-06 05:44:57 +00:00
|
|
|
jmp continue;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define BranchXCycles \
|
|
|
|
incb DebugCycleCount; /* +1 branch taken */ \
|
2014-06-07 22:05:29 +00:00
|
|
|
shlLQ $16, _XBX; \
|
2014-06-07 18:29:07 +00:00
|
|
|
movw PC_Reg, %bx; \
|
|
|
|
cbw; \
|
|
|
|
addw %bx, %ax; \
|
|
|
|
movw %ax, PC_Reg; \
|
|
|
|
cmpb %ah, %bh; \
|
|
|
|
je 9f; \
|
|
|
|
incb DebugCycleCount; /* +1 branch new page */ \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: shrLQ $16, _XBX;
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define FlagC lahf; \
|
|
|
|
andb $C_Flag, %ah; \
|
|
|
|
andb $~C_Flag, F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
orb %ah, F_Reg;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define FlagZ lahf; \
|
|
|
|
andb $Z_Flag, %ah; \
|
|
|
|
andb $~Z_Flag, F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
orb %ah, F_Reg;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define FlagN lahf; \
|
|
|
|
andb $N_Flag, %ah; \
|
|
|
|
andb $~N_Flag, F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
orb %ah, F_Reg;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define FlagNZ lahf; \
|
|
|
|
andb $(N_Flag|Z_Flag), %ah; \
|
|
|
|
andb $~(N_Flag|Z_Flag), F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
orb %ah, F_Reg;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define FlagNZC lahf; \
|
|
|
|
andb $(N_Flag|Z_Flag|C_Flag), %ah; \
|
|
|
|
andb $~(N_Flag|Z_Flag|C_Flag), F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
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.
|
|
|
|
*/
|
2014-06-07 18:29:07 +00:00
|
|
|
#define FlagNVZC \
|
2014-06-07 22:05:29 +00:00
|
|
|
pushfLQ; \
|
|
|
|
popLQ _XAX; \
|
|
|
|
andLQ $0x08C1,_XAX; \
|
2014-06-07 18:29:07 +00:00
|
|
|
andb $~(N_Flag|V_Flag|Z_Flag|C_Flag), F_Reg; \
|
|
|
|
orb %ah, F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
orb %al, F_Reg;
|
|
|
|
|
2014-06-07 18:40:36 +00:00
|
|
|
#define Push(x) movb x, SN(apple_ii_64k)(,SP_Reg_X,1); \
|
2013-07-06 05:44:57 +00:00
|
|
|
decb SP_Reg_L;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define Pop(x) incb SP_Reg_L; \
|
2014-06-07 18:40:36 +00:00
|
|
|
movb SN(apple_ii_64k)(,SP_Reg_X,1), x;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* Immediate Addressing - the operand is contained in the second byte of the
|
|
|
|
instruction. */
|
2014-06-07 22:05:29 +00:00
|
|
|
#define GetImm movLQ PC_Reg_X, EffectiveAddr_X; \
|
2013-07-06 05:44:57 +00:00
|
|
|
incw PC_Reg;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* Absolute Addressing - the second byte of the instruction is the low
|
|
|
|
order address, and the third byte is the high order byte. */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetAbs GetFromPC_W; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* Zero Page Addressing - the second byte of the instruction is an
|
|
|
|
address on the zero page */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetZPage \
|
|
|
|
GetFromPC_B; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetZPage_X \
|
|
|
|
GetFromPC_B; \
|
|
|
|
addb X_Reg, %al; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// HACK IS THIS EVER USED?
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetZPage_Y \
|
|
|
|
GetFromPC_B; \
|
|
|
|
addb Y_Reg, %al; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define _GetAbs_X \
|
|
|
|
GetFromPC_W; \
|
|
|
|
addb X_Reg, %al; \
|
|
|
|
jnc 9f; \
|
2013-11-22 05:06:31 +00:00
|
|
|
adcb $0, %ah;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetAbs_X \
|
|
|
|
_GetAbs_X \
|
|
|
|
incb DebugCycleCount; /* +1 cycle on page boundary */ \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: movLQ _XAX, EffectiveAddr_X;
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetAbs_X_STx \
|
|
|
|
_GetAbs_X \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: movLQ _XAX, EffectiveAddr_X;
|
2013-11-22 05:06:31 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define _GetAbs_Y \
|
|
|
|
GetFromPC_W; \
|
|
|
|
addb Y_Reg, %al; \
|
|
|
|
jnc 9f; \
|
2013-11-22 05:06:31 +00:00
|
|
|
adcb $0, %ah;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetAbs_Y \
|
|
|
|
_GetAbs_Y \
|
|
|
|
incb DebugCycleCount; /* +1 cycle on page boundary */ \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetAbs_Y_STA \
|
|
|
|
_GetAbs_Y \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: movLQ _XAX, EffectiveAddr_X;
|
2013-11-22 05:06:31 +00:00
|
|
|
|
2013-06-11 07:08:15 +00:00
|
|
|
/* 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)
|
|
|
|
*/
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetInd GetFromPC_W; \
|
2014-06-07 19:06:29 +00:00
|
|
|
GetFromMem_W(_XAX)
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetIndZPage \
|
|
|
|
GetFromPC_B; \
|
|
|
|
incb %al; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
GetFromEA_B; \
|
|
|
|
movb %al, %ah; \
|
2014-06-07 22:05:29 +00:00
|
|
|
decLQ EffectiveAddr_X; \
|
|
|
|
andLQ $0xFF, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
GetFromEA_B; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetIndZPage_X \
|
|
|
|
GetFromPC_B; \
|
|
|
|
addb X_Reg, %al; \
|
|
|
|
incb %al; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
GetFromEA_B; \
|
|
|
|
movb %al, %ah; \
|
2014-06-07 22:05:29 +00:00
|
|
|
decLQ EffectiveAddr_X; \
|
|
|
|
andLQ $0xFF, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
GetFromEA_B; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X;
|
2013-06-11 07:08:15 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define _GetIndZPage_Y \
|
|
|
|
GetFromPC_B; \
|
|
|
|
incb %al; \
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ _XAX, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
GetFromEA_B; \
|
|
|
|
movb %al, %ah; \
|
2014-06-07 22:05:29 +00:00
|
|
|
decLQ EffectiveAddr_X; \
|
|
|
|
andLQ $0xFF, EffectiveAddr_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
GetFromEA_B; \
|
|
|
|
addb Y_Reg, %al; \
|
2013-11-22 05:06:31 +00:00
|
|
|
jnc 9f;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetIndZPage_Y \
|
|
|
|
_GetIndZPage_Y \
|
|
|
|
adcb $0, %ah; \
|
|
|
|
incb DebugCycleCount; /* +1 cycle on page boundary */ \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: movLQ _XAX, EffectiveAddr_X;
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define GetIndZPage_Y_STA \
|
|
|
|
_GetIndZPage_Y \
|
|
|
|
adcb $0, %ah; \
|
2014-06-07 22:05:29 +00:00
|
|
|
9: movLQ _XAX, EffectiveAddr_X;
|
2013-11-22 05:06:31 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoADC_b GetFromEA_B \
|
2014-06-07 18:40:36 +00:00
|
|
|
bt $C_Flag_Bit, AF_Reg_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
adcb %al, A_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNVZC
|
|
|
|
|
2014-02-22 17:45:19 +00:00
|
|
|
#ifndef NDEBUG
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DebugBCDCheck \
|
|
|
|
testb $0x80, A_Reg; \
|
|
|
|
jz 6f; \
|
|
|
|
testb $0x60, A_Reg; \
|
|
|
|
jz 6f; \
|
|
|
|
call SN(c_debug_illegal_bcd); \
|
|
|
|
6: testb $0x08, A_Reg; \
|
|
|
|
jz 7f; \
|
|
|
|
testb $0x06, A_Reg; \
|
|
|
|
jz 7f; \
|
|
|
|
call SN(c_debug_illegal_bcd); \
|
|
|
|
7: testb $0x80, %al; \
|
|
|
|
jz 8f; \
|
|
|
|
testb $0x60, %al; \
|
|
|
|
jz 8f; \
|
|
|
|
call SN(c_debug_illegal_bcd); \
|
|
|
|
8: testb $0x08, %al; \
|
|
|
|
jz 9f; \
|
|
|
|
testb $0x06, %al; \
|
|
|
|
jz 9f; \
|
|
|
|
call SN(c_debug_illegal_bcd); \
|
2014-02-22 17:45:19 +00:00
|
|
|
9:
|
|
|
|
#else
|
|
|
|
#define DebugBCDCheck
|
|
|
|
#endif
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoAND GetFromEA_B \
|
|
|
|
andb %al, A_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoASL GetFromEA_B \
|
|
|
|
addb %al, %al; \
|
|
|
|
FlagNZC \
|
|
|
|
PutToEA_B \
|
2013-07-06 06:08:55 +00:00
|
|
|
|
|
|
|
/* SAR (and the following AND) effectively moves
|
2013-07-08 03:52:30 +00:00
|
|
|
* bit 6 to Bit 3 while leaving Bit 7 unchanged */
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoBIT GetFromEA_B \
|
|
|
|
testb %al, A_Reg; \
|
|
|
|
lahf; \
|
|
|
|
sarb $3, %al; \
|
|
|
|
andw $0x4088, %ax; \
|
|
|
|
andb $~(N_Flag|V_Flag|Z_Flag), F_Reg; \
|
|
|
|
orb %al, F_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
orb %ah, F_Reg;
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoCMP GetFromEA_B \
|
|
|
|
cmpb %al, A_Reg; \
|
|
|
|
cmc; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZC
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoCPX GetFromEA_B \
|
|
|
|
cmpb %al, X_Reg; \
|
|
|
|
cmc; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZC
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoCPY GetFromEA_B \
|
|
|
|
cmpb %al, Y_Reg; \
|
|
|
|
cmc; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZC
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoDEC GetFromEA_B \
|
|
|
|
decb %al; \
|
|
|
|
FlagNZ \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoEOR GetFromEA_B \
|
|
|
|
xorb %al, A_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoINC GetFromEA_B \
|
|
|
|
incb %al; \
|
|
|
|
FlagNZ \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoLDA GetFromEA_B \
|
|
|
|
movb %al, A_Reg; \
|
|
|
|
orb %al, %al; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoLDX GetFromEA_B \
|
|
|
|
movb %al, X_Reg; \
|
|
|
|
orb %al, %al; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoLDY GetFromEA_B \
|
|
|
|
movb %al, Y_Reg; \
|
|
|
|
orb %al, %al; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoLSR GetFromEA_B \
|
|
|
|
shrb $1, %al; \
|
|
|
|
FlagNZC \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoORA GetFromEA_B \
|
|
|
|
orb %al, A_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoROL GetFromEA_B \
|
2014-06-07 18:40:36 +00:00
|
|
|
bt $C_Flag_Bit, AF_Reg_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
adcb %al,%al; \
|
|
|
|
FlagNZC \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoROR GetFromEA_B \
|
|
|
|
movb F_Reg, %ah; \
|
2014-06-07 22:05:29 +00:00
|
|
|
rorLQ $1, _XAX; \
|
2014-06-07 18:29:07 +00:00
|
|
|
orb %al, %al; \
|
2014-06-08 20:12:12 +00:00
|
|
|
btr $ROR_BIT, _XAX; \
|
2014-06-07 18:29:07 +00:00
|
|
|
FlagNZC \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoSBC_b GetFromEA_B \
|
|
|
|
notb %al; \
|
2014-06-07 18:40:36 +00:00
|
|
|
bt $C_Flag_Bit, AF_Reg_X; \
|
2014-06-07 18:29:07 +00:00
|
|
|
adcb %al, A_Reg; \
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNVZC
|
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoSTA movb A_Reg, %al; \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoSTX movb X_Reg, %al; \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoSTY movb Y_Reg, %al; \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoSTZ movb $0x0, %al; \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoTRB GetFromEA_B \
|
|
|
|
testb A_Reg, %al; \
|
|
|
|
FlagZ \
|
|
|
|
notb A_Reg; \
|
|
|
|
andb A_Reg, %al; \
|
|
|
|
notb A_Reg; \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-06-07 18:29:07 +00:00
|
|
|
#define DoTSB GetFromEA_B \
|
|
|
|
testb A_Reg, %al; \
|
|
|
|
FlagZ \
|
|
|
|
orb A_Reg, %al; \
|
2013-07-08 03:52:30 +00:00
|
|
|
PutToEA_B
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------------------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
6502 routines and instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------------------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
ADC instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
ADd memory to accumulator with Carry
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// Decimal mode
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_dec)
|
2013-07-22 00:20:03 +00:00
|
|
|
incb DebugCycleCount // +1 cycle
|
2014-06-08 18:01:38 +00:00
|
|
|
GetFromEA_B
|
|
|
|
DebugBCDCheck
|
|
|
|
bt $C_Flag_Bit, AF_Reg_X
|
|
|
|
adcb A_Reg, %al
|
|
|
|
#ifdef __LP64__
|
|
|
|
#warning TODO FIXME das instruction
|
|
|
|
#else
|
|
|
|
daa
|
|
|
|
#endif
|
|
|
|
movb %al, A_Reg
|
|
|
|
FlagNVZC
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_imm) // 0x69
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_zpage) // 0x65
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_zpage_x) // 0x75
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_abs) // 0x6d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_abs_x) // 0x7d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_abs_y) // 0x79
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_ind_x) // 0x61
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_ind_y) // 0x71
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
|
|
|
DoADC_b
|
|
|
|
Continue
|
|
|
|
|
|
|
|
// 65c02 : 0x72
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ADC_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_ADC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoADC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
AND instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
logical AND memory with accumulator
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_imm) // 0x29
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_zpage) // 0x25
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_zpage_x) // 0x35
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_abs) // 0x2d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_abs_x) // 0x3d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_abs_y) // 0x39
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_ind_x) // 0x21
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_ind_y) // 0x31
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
|
|
|
DoAND
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x32
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_AND_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
DoAND
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
ASL instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
Arithmetic Shift one bit Left, memory or accumulator
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ASL_acc) // 0x0a
|
2013-07-06 05:44:57 +00:00
|
|
|
addb A_Reg, A_Reg
|
|
|
|
FlagNZC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ASL_zpage) // 0x06
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoASL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ASL_zpage_x) // 0x16
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoASL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ASL_abs) // 0x0e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoASL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ASL_abs_x) // 0x1e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoASL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
|
|
|
BBRx instructions
|
|
|
|
UNIMPLEMENTED : These are documented in the W65C02S datasheet ...
|
2013-11-22 05:06:31 +00:00
|
|
|
+ 1 cycle if branch within page
|
|
|
|
+ 2 cycles if branch across page boundary
|
2013-07-08 03:52:30 +00:00
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR0_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR1_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR2_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR3_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR4_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR5_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR6_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBR7_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
BBSx instructions
|
|
|
|
UNIMPLEMENTED : These are documented in the W65C02S datasheet ...
|
2013-11-22 05:06:31 +00:00
|
|
|
+ 1 cycle if branch within page
|
|
|
|
+ 2 cycles if branch across page boundary
|
2013-07-08 03:52:30 +00:00
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS0_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS1_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS2_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS3_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS4_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS5_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS6_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BBS7_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BCC instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on Carry Clear
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BCC) // 0x90
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb $C_Flag, F_Reg
|
2013-07-08 03:52:30 +00:00
|
|
|
jnz op_BCC_not // branch not taken
|
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BCC_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BCS instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on Carry Set
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BCS) // 0xB0
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb $C_Flag, F_Reg
|
2013-07-08 03:52:30 +00:00
|
|
|
jz op_BCS_not // branch not taken
|
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BCS_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BEQ instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch if EQual
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BEQ) // 0xF0
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb $Z_Flag, F_Reg
|
2013-07-08 03:52:30 +00:00
|
|
|
jz op_BEQ_not // branch not taken
|
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BEQ_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BIT instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
BIt Test
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BIT_zpage) // 0x24
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoBIT
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BIT_abs) // 0x2c
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoBIT
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x34
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BIT_zpage_x)
|
2014-02-23 03:19:51 +00:00
|
|
|
GetZPage_X
|
2013-07-08 03:52:30 +00:00
|
|
|
DoBIT
|
|
|
|
Continue
|
|
|
|
|
|
|
|
// 65c02 : 0x3C
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BIT_abs_x)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoBIT
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* BIT immediate is anomalous in that it does not affect the
|
|
|
|
* N and V flags, unlike in other addressing modes.
|
|
|
|
*/
|
|
|
|
// 65c02 : 0x89
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BIT_imm)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetImm
|
|
|
|
GetFromEA_B
|
|
|
|
testb %al, A_Reg
|
|
|
|
FlagZ
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BMI instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on result MInus
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BMI) // 0x30
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb F_Reg, F_Reg /* optimized check of N flag,
|
|
|
|
* which happens to be sign bit */
|
|
|
|
jns op_BMI_not
|
2013-07-08 03:52:30 +00:00
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BMI_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BNE instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on result Not Equal
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BNE) // 0xD0
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb $Z_Flag, F_Reg
|
|
|
|
jnz op_BNE_not
|
2013-07-08 03:52:30 +00:00
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BNE_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BPL instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on result PLus
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BPL) // 0x10
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb F_Reg, F_Reg /* optimized check of N flag,
|
|
|
|
* which happens to be sign bit */
|
|
|
|
js op_BPL_not
|
2013-07-08 03:52:30 +00:00
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BPL_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
BRA instruction
|
|
|
|
BRanch Always
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x80
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BRA)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetFromPC_B
|
|
|
|
BranchXCycles
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
BRK instruction
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_UNK) /* make undefined opcodes fault */
|
|
|
|
E(op_BRK)
|
2013-07-06 05:44:57 +00:00
|
|
|
incw PC_Reg
|
|
|
|
movw PC_Reg, %ax
|
|
|
|
Push(%ah)
|
|
|
|
Push(%al)
|
2013-11-06 06:11:27 +00:00
|
|
|
orb $(B_Flag|X_Flag), F_Reg
|
2014-06-08 18:01:38 +00:00
|
|
|
xorw %ax, %ax
|
|
|
|
movb F_Reg, %al
|
2014-06-07 19:06:29 +00:00
|
|
|
movb SN(cpu65_flags_encode)(,_XAX,1), %al
|
2013-07-06 05:44:57 +00:00
|
|
|
Push(%al)
|
2013-11-06 06:11:27 +00:00
|
|
|
orb $I_Flag, F_Reg
|
|
|
|
movw $0xFFFE, EffectiveAddr // ROM interrupt vector
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromEA_W
|
|
|
|
movw %ax, PC_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BVC instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on oVerflow Clear
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BVC) // 0x50
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb $V_Flag, F_Reg
|
|
|
|
jnz op_BVC_not
|
2013-07-08 03:52:30 +00:00
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BVC_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
BVS instruction
|
2013-07-08 03:52:30 +00:00
|
|
|
Branch on oVerflow Set
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_BVS) // 0x70
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromPC_B
|
|
|
|
testb $V_Flag, F_Reg
|
|
|
|
jz op_BVS_not
|
2013-07-08 03:52:30 +00:00
|
|
|
BranchXCycles
|
2013-06-11 07:08:15 +00:00
|
|
|
op_BVS_not:
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CLC instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CLC) // 0x18
|
2013-07-06 05:44:57 +00:00
|
|
|
andb $~C_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CLD instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CLD) // 0xd8
|
2013-07-06 05:44:57 +00:00
|
|
|
andb $~D_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CLI instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CLI) // 0x58
|
2013-07-06 05:44:57 +00:00
|
|
|
andb $~I_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CLV instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CLV) // 0xB8
|
2013-07-06 05:44:57 +00:00
|
|
|
andb $~V_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CMP instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
CoMPare memory and accumulator
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_imm) // 0xc9
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_zpage) // 0xc5
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_zpage_x) // 0xd5
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_abs) // 0xcd
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_abs_x) // 0xdd
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_abs_y) // 0xd9
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_ind_x) // 0xc1
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_ind_y) // 0xd1
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
|
|
|
DoCMP
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0xD2
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CMP_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
DoCMP
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CPX instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
ComPare memory and X register
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CPX_imm) // 0xe0
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoCPX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CPX_zpage) // 0xe4
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoCPX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CPX_abs) // 0xec
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoCPX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
CPY instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
ComPare memory and Y register
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CPY_imm) // 0xc0
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoCPY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CPY_zpage) // 0xc4
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoCPY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_CPY_abs) // 0xcc
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoCPY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
2014-05-11 21:48:52 +00:00
|
|
|
DEA: DEcrement Accumulator
|
2013-07-08 03:52:30 +00:00
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEC_acc)
|
|
|
|
E(op_DEA) // 0x3A
|
2013-07-08 03:52:30 +00:00
|
|
|
decb A_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
DEC instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
DECrement memory or accumulator by one
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEC_zpage) // 0xc6
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoDEC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEC_zpage_x) // 0xd6
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoDEC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEC_abs) // 0xce
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoDEC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEC_abs_x) // 0xde
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoDEC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
DEX instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEX) // 0xca
|
2013-07-06 05:44:57 +00:00
|
|
|
decb X_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
DEY instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_DEY) // 0x88
|
2013-07-06 05:44:57 +00:00
|
|
|
decb Y_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
EOR instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
Exclusive OR memory with accumulator
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_imm) // 0x49
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_zpage) // 0x45
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_zpage_x) // 0x55
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_abs) // 0x4d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_abs_x) // 0x5d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_abs_y) // 0x59
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_ind_x) // 0x41
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_ind_y) // 0x51
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
|
|
|
DoEOR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x52
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_EOR_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
DoEOR
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
INA : INcrement Accumulator
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INC_acc)
|
|
|
|
E(op_INA) // 0x1A
|
2013-07-08 03:52:30 +00:00
|
|
|
incb A_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
INC instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
INCrement memory
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INC_zpage) // 0xe6
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoINC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INC_zpage_x) // 0xf6
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoINC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INC_abs) // 0xee
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoINC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INC_abs_x) // 0xfe
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoINC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
INX instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INX) // 0xe8
|
2013-07-06 05:44:57 +00:00
|
|
|
incb X_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
INY instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_INY) // 0xc8
|
2013-07-06 05:44:57 +00:00
|
|
|
incb Y_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
JMP instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
JuMP to new location
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_JMP_abs)
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
2013-07-08 03:52:30 +00:00
|
|
|
movw EffectiveAddr, PC_Reg;
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_JMP_ind) // 0x6c
|
2014-03-16 03:52:15 +00:00
|
|
|
GetFromPC_B
|
2013-07-06 05:44:57 +00:00
|
|
|
xchgb %al, %ah
|
2014-03-16 03:52:15 +00:00
|
|
|
GetFromPC_B
|
2013-07-06 05:44:57 +00:00
|
|
|
xchgb %al, %ah
|
2014-03-16 03:52:15 +00:00
|
|
|
cmpb $0xFF, %al
|
|
|
|
je jmp_special
|
2014-06-07 19:06:29 +00:00
|
|
|
GetFromMem_W(_XAX)
|
2013-07-06 05:44:57 +00:00
|
|
|
movw %ax, PC_Reg
|
|
|
|
Continue
|
2014-03-16 03:52:15 +00:00
|
|
|
jmp_special: // see JMP indirect note in _Understanding the Apple IIe_ 4-25
|
2013-07-06 05:44:57 +00:00
|
|
|
movw %ax, PC_Reg
|
2014-03-16 03:52:15 +00:00
|
|
|
subw $0xff, PC_Reg
|
2014-06-07 18:40:36 +00:00
|
|
|
GetFromMem_B(PC_Reg_X)
|
2013-07-08 03:52:30 +00:00
|
|
|
xchgb %al, %ah
|
2014-03-16 03:52:15 +00:00
|
|
|
addw $0xff, PC_Reg
|
2014-06-07 18:40:36 +00:00
|
|
|
GetFromMem_B(PC_Reg_X)
|
2013-07-08 03:52:30 +00:00
|
|
|
movw %ax, PC_Reg
|
|
|
|
Continue
|
|
|
|
|
|
|
|
// 65c02 : 0x7C
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_JMP_abs_ind_x)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetFromPC_W
|
|
|
|
movw %ax, EffectiveAddr
|
2014-06-07 22:05:29 +00:00
|
|
|
movzbLQ X_Reg, _XAX
|
2013-07-08 03:52:30 +00:00
|
|
|
addw %ax, EffectiveAddr
|
2014-06-07 18:40:36 +00:00
|
|
|
GetFromMem_W(EffectiveAddr_X)
|
2013-07-08 03:52:30 +00:00
|
|
|
movw %ax, PC_Reg
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
JSR instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_JSR) // 0x20
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
2013-07-08 03:52:30 +00:00
|
|
|
movw PC_Reg, %ax
|
|
|
|
decw %ax
|
|
|
|
Push(%ah)
|
|
|
|
Push(%al)
|
|
|
|
movw EffectiveAddr, PC_Reg
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
LDA instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
LoaD Accumulator with memory
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_imm) // 0xa9
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_zpage) // 0xa5
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_zpage_x) // 0xb5
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_abs) // 0xad
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_abs_x) // 0xbd
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_abs_y) // 0xb9
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_ind_x) // 0xa1
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_ind_y) // 0xb1
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
|
|
|
DoLDA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0xB2
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDA_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
DoLDA
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
LDX instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDX_imm) // 0xa2
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoLDX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDX_zpage) // 0xa6
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoLDX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// HACK : is this used? need to study coverage ...
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDX_zpage_y) // 0xb6
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_Y
|
|
|
|
DoLDX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDX_abs) // 0xae
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoLDX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDX_abs_y) // 0xbe
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
|
|
|
DoLDX
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
LDY instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDY_imm) // 0xa0
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoLDY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDY_zpage) // 0xa4
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoLDY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDY_zpage_x) // 0xb4
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoLDY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDY_abs) // 0xac
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoLDY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LDY_abs_x) // 0xbc
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoLDY
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
LSR instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LSR_acc) // 0x4a
|
2013-07-06 05:44:57 +00:00
|
|
|
shrb $1, A_Reg
|
|
|
|
FlagNZC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LSR_zpage) // 0x46
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoLSR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LSR_zpage_x) // 0x56
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoLSR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LSR_abs) // 0x4e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoLSR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_LSR_abs_x) // 0x5e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoLSR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
NOP instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_NOP) // 0xea
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
ORA instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_imm) // 0x09
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_zpage) // 0x05
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_zpage_x) // 0x15
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_abs) // 0x0d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_abs_x) // 0x1d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_abs_y) // 0x19
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_ind_x) // 0x01
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_ind_y) // 0x11
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
|
|
|
DoORA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x12
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ORA_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
DoORA
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
PHA instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PHA) // 0x48
|
2013-07-06 05:44:57 +00:00
|
|
|
Push(A_Reg)
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
PHP instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PHP) // 0x08
|
2013-07-06 05:44:57 +00:00
|
|
|
movb F_Reg, %al
|
2014-06-07 19:06:29 +00:00
|
|
|
movb SN(cpu65_flags_encode)(,_XAX,1), %al
|
2013-07-06 05:44:57 +00:00
|
|
|
Push(%al)
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
|
|
|
PHX instruction
|
|
|
|
65c02 : 0xDA
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PHX)
|
2013-07-08 03:52:30 +00:00
|
|
|
Push(X_Reg)
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
PHY instruction
|
|
|
|
65c02 : 0x5A
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PHY)
|
2013-07-08 03:52:30 +00:00
|
|
|
Push(Y_Reg)
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
PLA instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PLA) // 0x68
|
2013-07-06 05:44:57 +00:00
|
|
|
Pop(A_Reg)
|
|
|
|
orb A_Reg, A_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
PLP instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PLP) // 0x28
|
2013-07-06 05:44:57 +00:00
|
|
|
Pop(%al)
|
2014-06-07 19:06:29 +00:00
|
|
|
movb SN(cpu65_flags_decode)(,_XAX,1), F_Reg
|
2013-07-06 05:44:57 +00:00
|
|
|
orb $(B_Flag|X_Flag), F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
|
|
|
PLX instruction
|
|
|
|
65c02 : 0xFA
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PLX)
|
2013-07-08 03:52:30 +00:00
|
|
|
Pop(X_Reg)
|
|
|
|
orb X_Reg, X_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
PLY instruction
|
|
|
|
65c02 : 0x7A
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_PLY)
|
2013-07-08 03:52:30 +00:00
|
|
|
Pop(Y_Reg)
|
|
|
|
orb Y_Reg, Y_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
ROL instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROL_acc) // 0x2a
|
2014-06-07 18:40:36 +00:00
|
|
|
bt $C_Flag_Bit, AF_Reg_X
|
2013-07-06 05:44:57 +00:00
|
|
|
adcb A_Reg, A_Reg
|
|
|
|
FlagNZC
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROL_zpage) // 0x26
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoROL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROL_zpage_x) // 0x36
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoROL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROL_abs) // 0x2e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoROL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROL_abs_x) // 0x3e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoROL
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
ROR instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-07-06 05:44:57 +00:00
|
|
|
/* NB: assumes A_Reg = %cl, F_Reg = %ch */
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROR_acc) // 0x6a
|
2013-07-06 05:44:57 +00:00
|
|
|
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
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROR_zpage) // 0x66
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoROR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROR_zpage_x) // 0x76
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoROR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROR_abs) // 0x6e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoROR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_ROR_abs_x) // 0x7e
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
|
|
|
DoROR
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
RTI instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RTI) // 0x40
|
2013-07-06 05:44:57 +00:00
|
|
|
Pop(%al)
|
2014-06-07 19:06:29 +00:00
|
|
|
movb SN(cpu65_flags_decode)(,_XAX,1), F_Reg
|
2013-07-06 05:44:57 +00:00
|
|
|
orb $(B_Flag|X_Flag), F_Reg
|
|
|
|
Pop(%al)
|
|
|
|
Pop(%ah)
|
|
|
|
movw %ax, PC_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
RTS instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RTS) // 0x60
|
2013-07-06 05:44:57 +00:00
|
|
|
Pop(%al)
|
|
|
|
Pop(%ah)
|
|
|
|
incw %ax
|
|
|
|
movw %ax, PC_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
SBC instructions
|
2014-02-22 17:45:19 +00:00
|
|
|
SuBtract memory from accumulator with Borrow
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_dec)
|
2013-07-22 00:20:03 +00:00
|
|
|
incb DebugCycleCount // +1 cycle
|
2014-06-08 18:01:38 +00:00
|
|
|
GetFromEA_B
|
|
|
|
DebugBCDCheck
|
|
|
|
bt $C_Flag_Bit, AF_Reg_X
|
|
|
|
cmc
|
|
|
|
xchgb A_Reg, %al
|
|
|
|
sbbb A_Reg, %al
|
|
|
|
#ifdef __LP64__
|
|
|
|
#warning TODO FIXME das instruction
|
|
|
|
#else
|
|
|
|
das
|
|
|
|
#endif
|
|
|
|
movb %al, A_Reg
|
|
|
|
cmc
|
|
|
|
FlagNVZC
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_imm) // 0xe9
|
2013-07-06 05:44:57 +00:00
|
|
|
GetImm
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_zpage) // 0xe5
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_zpage_x) // 0xf5
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_abs) // 0xed
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_abs_x) // 0xfd
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_X
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_abs_y) // 0xf9
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs_Y
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_ind_x) // 0xe1
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_ind_y) // 0xf1
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_Y
|
2013-07-08 03:52:30 +00:00
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
|
|
|
DoSBC_b
|
|
|
|
Continue
|
|
|
|
|
|
|
|
// 65c02 : 0xF2
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SBC_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
testb $D_Flag, F_Reg // Decimal mode?
|
|
|
|
jnz op_SBC_dec // Yes, jump to decimal version
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSBC_b
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
SEC instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SEC) // 0x38
|
2013-07-06 05:44:57 +00:00
|
|
|
orb $C_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
SED instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SED) // 0xf8
|
2013-07-06 05:44:57 +00:00
|
|
|
orb $D_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
SEI instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SEI) // 0x78
|
2013-07-06 05:44:57 +00:00
|
|
|
orb $I_Flag, F_Reg
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
2013-11-22 05:06:31 +00:00
|
|
|
SMBx instructions -- Available in Rockwell 65C02 but not NCR 65C02
|
2013-07-08 03:52:30 +00:00
|
|
|
UNIMPLEMENTED : These are documented in the W65C02S datasheet ...
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB0_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB1_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB2_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB3_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB4_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB5_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB6_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_SMB7_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
STA instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_zpage) // 0x85
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_zpage_x) // 0x95
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// UNIMPLEMENTED : W65C02S datasheet
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_zpage_y)
|
2014-01-26 06:10:33 +00:00
|
|
|
jmp op_NOP
|
2013-07-08 03:52:30 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_abs) // 0x8d
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_abs_x) // 0x9d
|
2013-11-22 05:06:31 +00:00
|
|
|
GetAbs_X_STx
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_abs_y) // 0x99
|
2013-11-22 05:06:31 +00:00
|
|
|
GetAbs_Y_STA
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_ind_x) // 0x81
|
2013-07-06 05:44:57 +00:00
|
|
|
GetIndZPage_X
|
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_ind_y) // 0x91
|
2013-11-22 05:06:31 +00:00
|
|
|
GetIndZPage_Y_STA
|
2013-07-06 05:44:57 +00:00
|
|
|
DoSTA
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x92
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STA_ind_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetIndZPage
|
|
|
|
DoSTA
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
STP instruction
|
|
|
|
UNIMPLEMENTED : This is documented in the W65C02S datasheet ...
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STP_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-11-22 05:06:31 +00:00
|
|
|
RMBx instructions -- Available in Rockwell 65C02 but not NCR 65C02
|
2013-07-08 03:52:30 +00:00
|
|
|
UNIMPLEMENTED : These are documented in the W65C02S datasheet ...
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB0_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB1_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB2_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB3_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB4_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB5_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB6_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_RMB7_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
STX instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STX_zpage) // 0x86
|
2013-07-08 03:52:30 +00:00
|
|
|
GetZPage
|
|
|
|
DoSTX
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// HACK : is this used? need to study coverage ...
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STX_zpage_y) // 0x96
|
2013-07-08 03:52:30 +00:00
|
|
|
GetZPage_Y
|
|
|
|
DoSTX
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STX_abs) // 0x8e
|
2013-07-08 03:52:30 +00:00
|
|
|
GetAbs
|
|
|
|
DoSTX
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
STY instructions
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STY_zpage) // 0x84
|
2013-07-08 03:52:30 +00:00
|
|
|
GetZPage
|
|
|
|
DoSTY
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STY_zpage_x) // 0x94
|
2013-07-08 03:52:30 +00:00
|
|
|
GetZPage_X
|
|
|
|
DoSTY
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STY_abs) // 0x8c
|
2013-07-08 03:52:30 +00:00
|
|
|
GetAbs
|
|
|
|
DoSTY
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
STZ instructions
|
|
|
|
65c02 only
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x64
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STZ_zpage)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetZPage
|
|
|
|
DoSTZ
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x74
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STZ_zpage_x)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetZPage_X
|
2014-03-16 21:48:22 +00:00
|
|
|
DoSTZ
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x9C
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STZ_abs)
|
2013-07-08 03:52:30 +00:00
|
|
|
GetAbs
|
|
|
|
DoSTZ
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x9E
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_STZ_abs_x)
|
2013-11-22 05:06:31 +00:00
|
|
|
GetAbs_X_STx
|
2013-07-08 03:52:30 +00:00
|
|
|
DoSTZ
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
TAX instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TAX) // 0xaa
|
2013-07-08 03:52:30 +00:00
|
|
|
movb A_Reg, X_Reg
|
|
|
|
orb X_Reg, X_Reg
|
2013-07-06 05:44:57 +00:00
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-07-08 03:52:30 +00:00
|
|
|
TAY instruction
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TAY) // 0xa8
|
2013-07-08 03:52:30 +00:00
|
|
|
movb A_Reg, Y_Reg
|
|
|
|
orb Y_Reg, Y_Reg
|
|
|
|
FlagNZ
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
TRB instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
65c02 only
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x1C
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TRB_abs)
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoTRB
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
// 65c02 : 0x14
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TRB_zpage)
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoTRB
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
TSB instructions
|
2013-07-08 03:52:30 +00:00
|
|
|
65c02 only
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-03-20 03:07:36 +00:00
|
|
|
// 65c02 : 0x0C
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TSB_abs)
|
2013-07-06 05:44:57 +00:00
|
|
|
GetAbs
|
|
|
|
DoTSB
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-03-20 03:07:36 +00:00
|
|
|
// 65c02 : 0x04
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TSB_zpage)
|
2013-07-06 05:44:57 +00:00
|
|
|
GetZPage
|
|
|
|
DoTSB
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
|
|
|
TSX instruction
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TSX) // 0xba
|
2013-07-08 03:52:30 +00:00
|
|
|
movb SP_Reg_L, X_Reg
|
|
|
|
orb X_Reg, X_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
TXA instruction
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TXA) // 0x8a
|
2013-07-08 03:52:30 +00:00
|
|
|
movb X_Reg, A_Reg
|
|
|
|
orb A_Reg, A_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
TXS instruction
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TXS) // 0x9a
|
2013-07-08 03:52:30 +00:00
|
|
|
movb X_Reg, SP_Reg_L
|
|
|
|
Continue
|
|
|
|
|
|
|
|
/* ----------------------------------
|
|
|
|
TYA instruction
|
|
|
|
---------------------------------- */
|
|
|
|
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_TYA) // 0x98
|
2013-07-08 03:52:30 +00:00
|
|
|
movb Y_Reg, A_Reg
|
|
|
|
orb A_Reg, A_Reg
|
|
|
|
FlagNZ
|
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-06 06:08:55 +00:00
|
|
|
/* ----------------------------------
|
2013-06-11 07:08:15 +00:00
|
|
|
??? instruction - 65c02
|
2013-07-08 03:52:30 +00:00
|
|
|
Defined as NOPs by spec
|
2013-07-06 06:08:55 +00:00
|
|
|
---------------------------------- */
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_UNK_65c02)
|
2013-07-06 05:44:57 +00:00
|
|
|
Continue
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* ----------------------------------
|
|
|
|
WAI instruction - 65c02
|
|
|
|
UNIMPLEMENTED : This is documented in the W65C02S datasheet ...
|
|
|
|
---------------------------------- */
|
2014-05-11 21:48:52 +00:00
|
|
|
E(op_WAI_65c02)
|
2013-07-08 03:52:30 +00:00
|
|
|
Continue
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark cpu main entry
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------
|
2013-10-06 06:22:08 +00:00
|
|
|
CPU continue
|
|
|
|
Keep executing until we've executed >= cpu65_cycles_to_execute
|
2013-07-08 03:52:30 +00:00
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
2013-10-07 04:01:00 +00:00
|
|
|
continue:
|
2014-06-07 22:05:29 +00:00
|
|
|
movzbLQ DebugCurrOpcode, _XAX
|
2014-06-07 19:06:29 +00:00
|
|
|
movb SN(cpu65__opcycles)(,_XAX,1), %al
|
2013-10-06 06:22:08 +00:00
|
|
|
addb DebugCycleCount, %al
|
2014-01-25 22:13:38 +00:00
|
|
|
movb %al, DebugCycleCount
|
|
|
|
addw %ax, SN(cpu65_cycle_count)
|
2014-06-08 22:46:59 +00:00
|
|
|
subl %eax, SN(gc_cycles_timer_0)
|
|
|
|
subl %eax, SN(gc_cycles_timer_1)
|
2014-01-25 22:13:38 +00:00
|
|
|
subw %ax, SN(cpu65_cycles_to_execute)
|
2013-11-06 06:11:27 +00:00
|
|
|
jle exit_cpu65_run
|
2014-06-07 22:05:29 +00:00
|
|
|
continue1: xorLQ _XAX, _XAX
|
2013-11-06 06:11:27 +00:00
|
|
|
orb SN(cpu65__signal), %al
|
2013-10-07 04:01:00 +00:00
|
|
|
jnz exception
|
2013-11-06 06:11:27 +00:00
|
|
|
1: JumpNextInstruction
|
2013-10-06 06:22:08 +00:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------
|
2013-11-06 06:11:27 +00:00
|
|
|
Exception handlers
|
2013-10-06 06:22:08 +00:00
|
|
|
------------------------------------------------------------------------- */
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2013-11-30 22:14:22 +00:00
|
|
|
exception: testb $ResetSig, %al
|
|
|
|
jnz ex_reset0
|
2013-11-06 06:11:27 +00:00
|
|
|
jmp ex_irq
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2013-11-30 22:14:22 +00:00
|
|
|
ex_reset0: testb $0xff, SN(joy_button0) // OpenApple
|
|
|
|
jnz emul_reinit
|
|
|
|
testb $0xff, SN(joy_button1) // ClosedApple
|
|
|
|
jnz emul_reinit
|
2013-11-06 06:11:27 +00:00
|
|
|
ex_reset: movb $0, SN(cpu65__signal)
|
|
|
|
movw $0xFFFC, EffectiveAddr // ROM reset vector
|
|
|
|
GetFromEA_W
|
|
|
|
movw %ax, PC_Reg
|
|
|
|
xorb %ah, %ah
|
2013-10-06 06:22:08 +00:00
|
|
|
JumpNextInstruction
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2013-11-06 06:11:27 +00:00
|
|
|
ex_irq: testb $I_Flag, F_Reg // Already interrupted?
|
|
|
|
jz 1f
|
|
|
|
JumpNextInstruction // Yes (ignored) ...
|
|
|
|
1: movw PC_Reg, %ax // No (handle IRQ) ...
|
|
|
|
Push(%ah)
|
|
|
|
Push(%al)
|
|
|
|
orb $X_Flag, F_Reg
|
2014-06-08 18:01:38 +00:00
|
|
|
xorw %ax, %ax
|
|
|
|
movb F_Reg, %al
|
2014-06-07 19:06:29 +00:00
|
|
|
movb SN(cpu65_flags_encode)(,_XAX,1), %al
|
2013-11-06 06:11:27 +00:00
|
|
|
Push(%al)
|
|
|
|
orb $(B_Flag | I_Flag), F_Reg
|
|
|
|
//andb $~D_Flag, F_Reg // AppleWin clears Decimal bit?
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ $0xFFFE, EffectiveAddr_X// HACK FIXME : there is a bug somewhere that is occasionally corrupting EffectiveAddr_X
|
2013-07-06 05:44:57 +00:00
|
|
|
GetFromEA_W
|
|
|
|
movw %ax, PC_Reg
|
|
|
|
xorb %ah, %ah
|
2013-10-06 06:22:08 +00:00
|
|
|
JumpNextInstruction
|
2013-07-06 05:44:57 +00:00
|
|
|
|
2013-07-08 03:52:30 +00:00
|
|
|
/* -------------------------------------------------------------------------
|
2013-11-06 06:11:27 +00:00
|
|
|
CPU thread main entry and exit points
|
2013-07-08 03:52:30 +00:00
|
|
|
------------------------------------------------------------------------- */
|
2014-06-08 20:12:48 +00:00
|
|
|
|
2013-06-11 07:08:15 +00:00
|
|
|
E(cpu65_run)
|
2014-06-08 20:12:48 +00:00
|
|
|
#ifdef __LP64__
|
|
|
|
pushq %rbx
|
|
|
|
// NOTE: should we be also preserving r12-r15?
|
|
|
|
#endif
|
2014-06-08 18:01:38 +00:00
|
|
|
pushLQ _XBP
|
|
|
|
movLQ _XSP, _XBP
|
2013-11-06 06:11:27 +00:00
|
|
|
cmpb $0, SN(emul_reinitialize)
|
2013-10-06 06:22:08 +00:00
|
|
|
jnz 1f
|
2014-06-07 20:08:01 +00:00
|
|
|
|
|
|
|
// Restore CPU state when being called from C.
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ $0x0100, SP_Reg_X
|
|
|
|
movzwLQ DebugCurrEA, EffectiveAddr_X
|
|
|
|
movzwLQ SN(cpu65_current), PC_Reg_X
|
|
|
|
movzbLQ SN(cpu65_current)+2, AF_Reg_X
|
|
|
|
movzbLQ SN(cpu65_current)+3, _XAX
|
2014-06-07 20:08:01 +00:00
|
|
|
movb SN(cpu65_flags_decode)(,_XAX,1), F_Reg
|
2014-06-07 22:05:29 +00:00
|
|
|
movzbLQ SN(cpu65_current)+4, XY_Reg_X
|
2014-06-07 20:08:01 +00:00
|
|
|
movb SN(cpu65_current)+5, Y_Reg
|
|
|
|
movb SN(cpu65_current)+6, SP_Reg_L
|
|
|
|
#ifdef __APPLE2_VM__
|
|
|
|
// Apple //e machine specific set stack point to ALTZP (or not)
|
2014-06-07 22:05:29 +00:00
|
|
|
movLQ SN(base_stackzp), _XAX
|
|
|
|
subLQ $SN(apple_ii_64k), _XAX
|
|
|
|
orLQ _XAX, SP_Reg_X
|
2014-06-07 20:08:01 +00:00
|
|
|
#endif
|
2014-03-22 17:37:04 +00:00
|
|
|
jmp continue1
|
2014-06-07 20:08:01 +00:00
|
|
|
|
2013-11-06 06:11:27 +00:00
|
|
|
1: movb $0, SN(emul_reinitialize)
|
2014-06-07 20:44:14 +00:00
|
|
|
// Zero all used registers
|
2014-06-07 22:05:29 +00:00
|
|
|
xorLQ _XAX, _XAX
|
|
|
|
xorLQ XY_Reg_X, XY_Reg_X
|
|
|
|
xorLQ AF_Reg_X, AF_Reg_X
|
|
|
|
xorLQ PC_Reg_X, PC_Reg_X
|
|
|
|
xorLQ EffectiveAddr_X, EffectiveAddr_X
|
|
|
|
movLQ $0x1FF, SP_Reg_X
|
2013-07-06 05:44:57 +00:00
|
|
|
jmp ex_reset
|
2013-06-11 07:08:15 +00:00
|
|
|
|
2014-06-07 20:44:14 +00:00
|
|
|
exit_cpu65_run:
|
2014-06-07 20:08:01 +00:00
|
|
|
// Save CPU state when returning from being called from C
|
|
|
|
movw EffectiveAddr, DebugCurrEA
|
|
|
|
movw PC_Reg, SN(cpu65_current)
|
|
|
|
movb A_Reg, SN(cpu65_current)+2
|
2014-06-08 18:01:38 +00:00
|
|
|
xorw %ax, %ax
|
|
|
|
movb F_Reg, %al
|
2014-06-07 20:08:01 +00:00
|
|
|
movb SN(cpu65_flags_encode)(,_XAX,1), %al
|
|
|
|
movb %al, 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
|
2014-06-08 20:12:48 +00:00
|
|
|
jmp exit_frame
|
2013-11-06 06:11:27 +00:00
|
|
|
|
2014-06-07 20:44:14 +00:00
|
|
|
emul_reinit: movb $0, SN(cpu65__signal)
|
2013-11-06 06:11:27 +00:00
|
|
|
movb $1, SN(emul_reinitialize)
|
2014-06-08 20:12:48 +00:00
|
|
|
|
|
|
|
exit_frame: popLQ _XBP
|
|
|
|
#ifdef __LP64__
|
|
|
|
popq %rbx
|
|
|
|
#endif
|
2013-11-06 06:11:27 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------
|
|
|
|
Debugger hooks
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
2013-10-06 06:22:08 +00:00
|
|
|
E(cpu65_direct_write)
|
2014-06-07 22:05:29 +00:00
|
|
|
pushLQ EffectiveAddr_X
|
|
|
|
movLQ 8(_XSP),EffectiveAddr_X
|
|
|
|
movLQ 12(_XSP),_XAX
|
2014-06-07 23:05:38 +00:00
|
|
|
call *SN(cpu65_vmem_w)(,EffectiveAddr_X,SZ_PTR)
|
2014-06-07 22:05:29 +00:00
|
|
|
popLQ EffectiveAddr_X
|
2013-07-06 05:44:57 +00:00
|
|
|
ret
|
2013-06-11 07:08:15 +00:00
|
|
|
|