mirror of
https://github.com/dschmenk/Appalm.git
synced 2024-10-11 11:23:40 +00:00
2123 lines
39 KiB
NASM
Executable File
2123 lines
39 KiB
NASM
Executable File
/********************************************************************************\
|
|
* *
|
|
* 6502 emulation *
|
|
* *
|
|
\********************************************************************************/
|
|
|
|
/*
|
|
* STRICT_IND_EMU tries to enforce exact addressing rules as it applies to zero page
|
|
* access. Disabling should improve performance and still work in 99.9% of the case.
|
|
*/
|
|
#define STRICT_IND_EMU 0
|
|
/*
|
|
* Define some macros for memory model specific 4addresses.
|
|
*/
|
|
#define GLOBAL %a5
|
|
#define OPTABLE(o) (opTable6502+(o))@END.w
|
|
#define STATE_6502 state6502@END.w
|
|
#define STATE_6502_1 (state6502+4)@END.w
|
|
#define STATE_6502_2 (state6502+8)@END.w
|
|
#define STATUS_6502 status6502@END.w
|
|
#define CC_68K_TO_6502 cc_68k_to_6502@END.w
|
|
#define CC_6502_TO_68K cc_6502_to_68k@END.w
|
|
/*
|
|
* Register allocations.
|
|
* Note: SP and CC share the same register.
|
|
* Use SWAP to get access to the seperate 16 bit halves.
|
|
*/
|
|
#define DATA %d0
|
|
#define INSTRNS %d1
|
|
#define ACC %d2
|
|
#define X %d3
|
|
#define Y %d4
|
|
#define SP_CC %d5
|
|
#define CC %d5
|
|
#define SP %d5
|
|
#define EA %d6
|
|
#define PAGE %d7
|
|
#define PC %a0
|
|
#define OPBASE %a1
|
|
#define MEMBASE %a2
|
|
#define WRMEM %a3
|
|
#define RDMEM %a4
|
|
#define ADDR %a6
|
|
/*
|
|
* Condition code bits.
|
|
*/
|
|
#define CC_C_68K 0x01
|
|
#define CC_V_68K 0x02
|
|
#define CC_Z_68K 0x04
|
|
#define CC_N_68K 0x08
|
|
#define CC_X_68K 0x10
|
|
#define CC_C_6502 0x01
|
|
#define CC_Z_6502 0x02
|
|
#define CC_I_6502 0x04
|
|
#define CC_D_6502 0x08
|
|
#define CC_B_6502 0x10
|
|
#define CC_1_6502 0x20
|
|
#define CC_V_6502 0x40
|
|
#define CC_N_6502 0x80
|
|
/*
|
|
* Effective address calculations.
|
|
*/
|
|
#define EA_IMM \
|
|
move.b (PC)+, DATA
|
|
|
|
#define EA_ZP \
|
|
clr.w EA; \
|
|
mov.b (PC)+, EA
|
|
|
|
#define EA_ZP_X \
|
|
move.w X, EA; \
|
|
add.b (PC)+, EA
|
|
|
|
#define EA_ZP_Y \
|
|
move.w Y, EA; \
|
|
add.b (PC)+, EA
|
|
|
|
#if STRICT_IND_EMU
|
|
#define EA_ZP_IND \
|
|
clr.w PAGE; \
|
|
move.b (PC)+, PAGE; \
|
|
move.b (MEMBASE,PAGE.w), DATA; \
|
|
addq.b #1, PAGE; \
|
|
move.b (MEMBASE,PAGE.w), PAGE; \
|
|
lsl.w #2, PAGE; \
|
|
move.w PAGE, EA; \
|
|
lsl.w #6, EA; \
|
|
move.b DATA, EA
|
|
|
|
#define EA_IND_X \
|
|
move.w X, PAGE; \
|
|
add.b (PC)+, PAGE; \
|
|
move.b (MEMBASE,PAGE.w), DATA; \
|
|
addq.b #1, PAGE; \
|
|
move.b (MEMBASE,PAGE.w), PAGE; \
|
|
lsl.w #2, PAGE; \
|
|
move.w PAGE, EA; \
|
|
lsl.w #6, EA; \
|
|
move.b DATA, EA
|
|
|
|
#define EA_IND_Y \
|
|
clr.w PAGE; \
|
|
move.b (PC)+, PAGE; \
|
|
move.b (MEMBASE,PAGE.w), DATA; \
|
|
addq.b #1, PAGE; \
|
|
move.b (MEMBASE,PAGE.w), EA; \
|
|
lsl.w #8, EA; \
|
|
move.b DATA, EA; \
|
|
add.w Y, EA; \
|
|
move.w EA, PAGE; \
|
|
clr.b PAGE; \
|
|
lsr.w #6, PAGE
|
|
#else
|
|
#define EA_ZP_IND \
|
|
clr.w PAGE; \
|
|
move.b (PC)+, PAGE; \
|
|
lea 1(MEMBASE,PAGE.w), ADDR; \
|
|
move.b (ADDR), PAGE; \
|
|
lsl.w #2, PAGE; \
|
|
move.w PAGE, EA; \
|
|
lsl.w #6, EA; \
|
|
move.b -(ADDR), EA
|
|
|
|
#define EA_IND_X \
|
|
move.w X, PAGE; \
|
|
add.b (PC)+, PAGE; \
|
|
lea 1(MEMBASE,PAGE.w), ADDR; \
|
|
move.b (ADDR), PAGE; \
|
|
lsl.w #2, PAGE; \
|
|
move.w PAGE, EA; \
|
|
lsl.w #6, EA; \
|
|
move.b -(ADDR), EA
|
|
|
|
#define EA_IND_Y \
|
|
clr.w PAGE; \
|
|
move.b (PC)+, PAGE; \
|
|
lea 1(MEMBASE,PAGE.w), ADDR; \
|
|
move.b (ADDR), EA; \
|
|
lsl.w #8, EA; \
|
|
move.b -(ADDR), EA; \
|
|
add.w Y, EA; \
|
|
move.w EA, PAGE; \
|
|
clr.b PAGE; \
|
|
lsr.w #6, PAGE
|
|
#endif
|
|
|
|
#define EA_ABS \
|
|
clr.w PAGE; \
|
|
move.b (PC)+, DATA; \
|
|
move.b (PC)+, PAGE; \
|
|
lsl.w #2, PAGE; \
|
|
move.w PAGE, EA; \
|
|
lsl.w #6, EA; \
|
|
move.b DATA, EA
|
|
|
|
#define EA_ABS_X \
|
|
move.b (PC)+, DATA; \
|
|
move.b (PC)+, EA; \
|
|
lsl.w #8, EA; \
|
|
move.b DATA, EA; \
|
|
add.w X, EA; \
|
|
move.w EA, PAGE; \
|
|
clr.b PAGE; \
|
|
lsr.w #6, PAGE
|
|
|
|
#define EA_ABS_Y \
|
|
move.b (PC)+, DATA; \
|
|
move.b (PC)+, EA; \
|
|
lsl.w #8, EA; \
|
|
move.b DATA, EA; \
|
|
add.w Y, EA; \
|
|
move.w EA, PAGE; \
|
|
clr.b PAGE; \
|
|
lsr.w #6, PAGE
|
|
|
|
/*
|
|
* Basic memory read.
|
|
*/
|
|
#define RD_MEM \
|
|
move.w (RDMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(RDMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
jsr (ADDR); \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b (MEMBASE,EA.l), DATA; \
|
|
1:
|
|
|
|
#define LDA_MEM \
|
|
move.w (RDMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(RDMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
jsr (ADDR); \
|
|
move.b DATA, ACC; \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b (MEMBASE,EA.l), ACC; \
|
|
1:
|
|
|
|
#define LDX_MEM \
|
|
move.w (RDMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(RDMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
jsr (ADDR); \
|
|
move.b DATA, X; \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b (MEMBASE,EA.l), X; \
|
|
1:
|
|
|
|
#define LDY_MEM \
|
|
move.w (RDMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(RDMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
jsr (ADDR); \
|
|
move.b DATA, Y; \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b (MEMBASE,EA.l), Y; \
|
|
1:
|
|
|
|
/*
|
|
* Basic memory write.
|
|
*/
|
|
#define WR_MEM \
|
|
move.w DATA, ADDR; \
|
|
move.w (WRMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(WRMEM, PAGE.w), DATA; \
|
|
exg ADDR, DATA; \
|
|
and.l #0xFF, DATA; \
|
|
jsr (ADDR); \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.w ADDR, DATA; \
|
|
move.b DATA, (MEMBASE, EA.l); \
|
|
1:
|
|
|
|
#define STA_MEM \
|
|
move.w (WRMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(WRMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
clr.l DATA; \
|
|
move.b ACC, DATA; \
|
|
jsr (ADDR); \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b ACC, (MEMBASE, EA.l); \
|
|
1:
|
|
|
|
#define STX_MEM \
|
|
move.w (WRMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(WRMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
clr.l DATA; \
|
|
move.b X, DATA; \
|
|
jsr (ADDR); \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b X, (MEMBASE, EA.l); \
|
|
1:
|
|
|
|
#define STY_MEM \
|
|
move.w (WRMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(WRMEM, PAGE.w), DATA; \
|
|
move.l DATA, ADDR; \
|
|
clr.l DATA; \
|
|
move.b Y, DATA; \
|
|
jsr (ADDR); \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.b Y, (MEMBASE, EA.l); \
|
|
1:
|
|
|
|
/*
|
|
* Memory write when the data is already in the ADDR register.
|
|
*/
|
|
#define WRA_MEM \
|
|
move.w (WRMEM, PAGE.w), DATA; \
|
|
beq.b 0f; \
|
|
swap DATA; \
|
|
move.w 2(WRMEM, PAGE.w), DATA; \
|
|
exg ADDR, DATA; \
|
|
and.l #0xFF, DATA; \
|
|
jsr (ADDR); \
|
|
bra.b 1f; \
|
|
0:; \
|
|
move.w ADDR, DATA; \
|
|
move.b DATA, (MEMBASE, EA.l); \
|
|
1:
|
|
/*
|
|
* Decrement instruction count and fetch next instruction.
|
|
*/
|
|
#define NEXT_OP \
|
|
dbf.w INSTRNS, opfetch; \
|
|
bra.w exit6502
|
|
/*
|
|
* Update CC flags.
|
|
*/
|
|
#define UPDATE_Z_STATUS \
|
|
move.w %sr, DATA; \
|
|
and.b #0x04, DATA; \
|
|
and.b #0x1D, CC; \
|
|
or.b DATA, CC
|
|
|
|
#define UPDATE_NZ_STATUS \
|
|
move.w %sr, DATA; \
|
|
and.b #0x0C, DATA; \
|
|
and.b #0x13, CC; \
|
|
or.b DATA, CC
|
|
|
|
#define UPDATE_NZC_STATUS \
|
|
move.w %sr, DATA; \
|
|
and.b #0x1D, DATA; \
|
|
and.b #0x02, CC; \
|
|
or.b DATA, CC
|
|
|
|
/*
|
|
* Opcodes.
|
|
*/
|
|
#define OP_BIT \
|
|
and.b #0x11, CC; \
|
|
move.w CC, ADDR; \
|
|
btst #7, DATA; \
|
|
sne CC; \
|
|
and.b #0x08, CC; \
|
|
add.w CC, ADDR; \
|
|
btst #6, DATA; \
|
|
sne CC; \
|
|
and.b #0x02, CC; \
|
|
add.w CC, ADDR; \
|
|
and.b ACC, DATA; \
|
|
move.w %sr, CC; \
|
|
and.b #0x04, CC; \
|
|
add.w ADDR, CC
|
|
|
|
#define OP_TRB \
|
|
and.b #0x11, CC; \
|
|
move.w CC, ADDR; \
|
|
btst #7, DATA; \
|
|
sne CC; \
|
|
and.b #0x08, CC; \
|
|
add.w CC, ADDR; \
|
|
btst #6, DATA; \
|
|
sne CC; \
|
|
and.b #0x02, CC; \
|
|
add.w CC, ADDR; \
|
|
not.b ACC; \
|
|
and.b ACC, DATA; \
|
|
move.w %sr, CC; \
|
|
and.b #0x04, CC; \
|
|
add.w ADDR, CC; \
|
|
not.b ACC
|
|
|
|
#define OP_TSB \
|
|
and.b #0x11, CC; \
|
|
btst #7, DATA; \
|
|
sne CC; \
|
|
and.b #0x08, CC; \
|
|
add.w CC, ADDR; \
|
|
btst #6, DATA; \
|
|
sne CC; \
|
|
and.b #0x02, CC; \
|
|
add.w CC, ADDR; \
|
|
or.b ACC, DATA; \
|
|
move.w %sr, CC; \
|
|
and.b #0x04, CC; \
|
|
add.w ADDR, CC
|
|
|
|
#define OP_ADC_BIN \
|
|
or.b #0x04, CC; \
|
|
move.w CC, %ccr; \
|
|
addx.b DATA, ACC; \
|
|
move.w %sr, CC
|
|
|
|
#define OP_ADC_BCD \
|
|
or.b #0x04, CC; \
|
|
move.w CC, %ccr; \
|
|
abcd DATA, ACC; \
|
|
move.w %sr, CC
|
|
|
|
#define OP_SBC_BIN \
|
|
eor.b #0x11, CC; \
|
|
or.b #0x04, CC; \
|
|
move.w CC, %ccr; \
|
|
subx.b DATA, ACC; \
|
|
move.w %sr, CC; \
|
|
eor.b #0x11, CC
|
|
|
|
#define OP_SBC_BCD \
|
|
eor.b #0x11, CC; \
|
|
or.b #0x04, CC; \
|
|
move.w CC, %ccr; \
|
|
sbcd DATA, ACC; \
|
|
move.w %sr, CC; \
|
|
eor.b #0x11, CC
|
|
|
|
.data
|
|
.even
|
|
/*
|
|
* Condition Code/Status Register translation tables.
|
|
*/
|
|
cc_6502_to_68k:
|
|
.byte 0x00; .byte 0x02; .byte 0x08; .byte 0x0A;
|
|
.byte 0x11; .byte 0x13; .byte 0x19; .byte 0x1B;
|
|
.byte 0x04; .byte 0x06; .byte 0x0C; .byte 0x0E;
|
|
.byte 0x15; .byte 0x17; .byte 0x1D; .byte 0x1F;
|
|
cc_68k_to_6502:
|
|
.byte 0x00; .byte 0x01; .byte 0x40; .byte 0x41;
|
|
.byte 0x02; .byte 0x03; .byte 0x42; .byte 0x43;
|
|
.byte 0x80; .byte 0x81; .byte 0xC0; .byte 0xC1;
|
|
.byte 0x82; .byte 0x83; .byte 0xC2; .byte 0xC3;
|
|
.text
|
|
.even
|
|
/*
|
|
* uCode.
|
|
*/
|
|
UNIMPLEMENTED:
|
|
move.l PC, DATA
|
|
subq.l #1, DATA
|
|
move.l DATA, PC
|
|
sub.l MEMBASE, DATA
|
|
swap DATA
|
|
move.b (PC), DATA
|
|
movem.l #0x1FFC, STATE_6502_2(GLOBAL) /* Save 6502 state */
|
|
movem.l (%sp)+, #0x7FFE /* Restore all registers */
|
|
rts
|
|
NOP:
|
|
NEXT_OP
|
|
CLD:
|
|
and.b #~CC_D_6502, STATUS_6502(GLOBAL)
|
|
bsr.w set_bcd_ops
|
|
NEXT_OP
|
|
SED:
|
|
or.b #CC_D_6502, STATUS_6502(GLOBAL)
|
|
bsr.w set_bcd_ops
|
|
NEXT_OP
|
|
CLC:
|
|
and.b #0xEE, CC
|
|
NEXT_OP
|
|
SEC:
|
|
or.b #0x11, CC
|
|
NEXT_OP
|
|
CLV:
|
|
and.b #0xFD, CC
|
|
NEXT_OP
|
|
SEI:
|
|
or.b #CC_I_6502, STATUS_6502(GLOBAL)
|
|
NEXT_OP
|
|
CLI:
|
|
and.b #~CC_I_6502, STATUS_6502(GLOBAL)
|
|
NEXT_OP
|
|
PHP:
|
|
move.b CC, DATA
|
|
and.w #0x0F, DATA
|
|
lea CC_68K_TO_6502(GLOBAL), ADDR
|
|
move.b (ADDR,DATA.w), DATA
|
|
or.b STATUS_6502(GLOBAL), DATA
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
NEXT_OP
|
|
PHA:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b ACC, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
NEXT_OP
|
|
PHX:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b X, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
NEXT_OP
|
|
PLP:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
swap SP_CC
|
|
clr.w CC
|
|
move.b DATA, CC
|
|
and.b #0x3C, DATA /* Mask out mapped state */
|
|
and.b #0xC3, CC
|
|
move.b DATA, STATUS_6502(GLOBAL)
|
|
rol.b #2, CC
|
|
lea CC_6502_TO_68K(GLOBAL), ADDR
|
|
move.b (ADDR,CC.w), CC
|
|
bsr.w set_bcd_ops
|
|
NEXT_OP
|
|
PLA:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.w SP, ADDR
|
|
swap SP_CC
|
|
move.b (MEMBASE,ADDR.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
PLX:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.w SP, ADDR
|
|
swap SP_CC
|
|
move.b (MEMBASE,ADDR.w), X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
BRK:
|
|
sub.l MEMBASE, PC /* Push PC + 2 */
|
|
move.w PC, DATA
|
|
addq #1, DATA
|
|
ror.w #8, DATA
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
lsr.w #8, DATA
|
|
subq.b #1, SP
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
or.b #CC_B_6502, STATUS_6502(GLOBAL) /* Set BRK flag */
|
|
move.b CC, DATA /* Push P */
|
|
and.w #0x0F, DATA
|
|
lea CC_68K_TO_6502(GLOBAL), ADDR
|
|
move.b (ADDR,DATA.w), DATA
|
|
or.b STATUS_6502(GLOBAL), DATA
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
or.b #CC_I_6502, STATUS_6502(GLOBAL) /* Set INT flag */
|
|
move.l #0xFFFE, DATA /* Load PC from 0xFFFE */
|
|
move.w (MEMBASE,DATA.l), DATA
|
|
ror.w #8, DATA
|
|
move.l DATA, PC
|
|
add.l MEMBASE, PC
|
|
NEXT_OP
|
|
JMP_ABS:
|
|
move.b 1(PC), DATA
|
|
lsl.w #8, DATA
|
|
move.b (PC), DATA
|
|
lea (MEMBASE,DATA.l), PC
|
|
NEXT_OP
|
|
JMP_IND: /* 65C02 version */
|
|
move.b 1(PC), DATA
|
|
lsl.w #8, DATA
|
|
move.b (PC), DATA
|
|
lea 1(MEMBASE,DATA.l), ADDR
|
|
move.b (ADDR), DATA
|
|
lsl.w #8, DATA
|
|
move.b -(ADDR), DATA
|
|
lea (MEMBASE,DATA.l), PC
|
|
NEXT_OP
|
|
JSR:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b 1(PC), DATA
|
|
lsl.w #8, DATA
|
|
move.b (PC)+, DATA
|
|
move.l DATA, ADDR
|
|
sub.l MEMBASE, PC
|
|
move.w PC, DATA
|
|
move.l ADDR, PC
|
|
add.l MEMBASE, PC
|
|
ror.w #8, DATA
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
lsr.w #8, DATA
|
|
subq.b #1, SP
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
NEXT_OP
|
|
RTS:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
addq.b #1, SP
|
|
lsl.w #8, DATA
|
|
move.b (MEMBASE,SP.w), DATA
|
|
rol.w #8, DATA
|
|
lea 1(MEMBASE,DATA.l), PC
|
|
swap SP_CC
|
|
NEXT_OP
|
|
RTI:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
swap SP_CC
|
|
clr.w CC
|
|
move.b DATA, CC
|
|
and.b #0x3C, DATA /* Mask out mapped state */
|
|
move.b DATA, STATUS_6502(GLOBAL)
|
|
and.b #0xC3, CC
|
|
rol.b #2, CC
|
|
lea CC_6502_TO_68K(GLOBAL), ADDR
|
|
move.b (ADDR,CC.w), CC
|
|
bsr.w set_bcd_ops
|
|
swap SP_CC
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
addq.b #1, SP
|
|
lsl.w #8, DATA
|
|
move.b (MEMBASE,SP.w), DATA
|
|
rol.w #8, DATA
|
|
lea (MEMBASE,DATA.l), PC
|
|
swap SP_CC
|
|
NEXT_OP
|
|
/*
|
|
* Special version of PC adjustment routines that check for specific ranges.
|
|
* Very Apple ][ specific :-(
|
|
*/
|
|
BRK_CHK:
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
sub.l MEMBASE, PC /* Push PC + 2 */
|
|
move.w PC, DATA
|
|
addq #1, DATA
|
|
ror.w #8, DATA
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
lsr.w #8, DATA
|
|
subq.b #1, SP
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
or.b #CC_B_6502, STATUS_6502(GLOBAL) /* Set BRK flag */
|
|
move.b CC, DATA /* Push P */
|
|
and.w #0x0F, DATA
|
|
lea CC_68K_TO_6502(GLOBAL), ADDR
|
|
move.b (ADDR,DATA.w), DATA
|
|
or.b STATUS_6502(GLOBAL), DATA
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
or.b #CC_I_6502, STATUS_6502(GLOBAL) /* Set INT flag */
|
|
move.l #0xFFFE, DATA /* Load PC from 0xFFFE */
|
|
move.w (MEMBASE,DATA.l), DATA
|
|
ror.w #8, DATA
|
|
move.l DATA, PC
|
|
add.l MEMBASE, PC
|
|
NEXT_OP
|
|
JMP_ABS_CHK:
|
|
move.b 1(PC), DATA
|
|
lsl.w #8, DATA
|
|
move.b (PC), DATA
|
|
cmp.w #0xD000, DATA
|
|
bcs.b 0f
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
0:
|
|
lea (MEMBASE,DATA.l), PC
|
|
NEXT_OP
|
|
JMP_IND_CHK: /* 65C02 version */
|
|
move.b 1(PC), DATA
|
|
lsl.w #8, DATA
|
|
move.b (PC), DATA
|
|
cmp.w #0xD000, DATA
|
|
bcs.b 0f
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
0:
|
|
lea 1(MEMBASE,DATA.l), ADDR
|
|
move.b (ADDR), DATA
|
|
lsl.w #8, DATA
|
|
move.b -(ADDR), DATA
|
|
cmp.w #0xD000, DATA
|
|
bcs.b 1f
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
1:
|
|
lea (MEMBASE,DATA.l), PC
|
|
NEXT_OP
|
|
JSR_CHK:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
move.b 1(PC), DATA
|
|
lsl.w #8, DATA
|
|
move.b (PC)+, DATA
|
|
cmp.w #0xD000, DATA
|
|
bcs.b 0f
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
0:
|
|
move.l DATA, ADDR
|
|
sub.l MEMBASE, PC
|
|
move.w PC, DATA
|
|
move.l ADDR, PC
|
|
add.l MEMBASE, PC
|
|
ror.w #8, DATA
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
lsr.w #8, DATA
|
|
subq.b #1, SP
|
|
move.b DATA, (MEMBASE,SP.w)
|
|
subq.b #1, SP
|
|
swap SP_CC
|
|
NEXT_OP
|
|
RTS_CHK:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
addq.b #1, SP
|
|
lsl.w #8, DATA
|
|
move.b (MEMBASE,SP.w), DATA
|
|
rol.w #8, DATA
|
|
cmp.w #0xEFFF, DATA
|
|
bcs.b 0f
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
0:
|
|
lea 1(MEMBASE,DATA.l), PC
|
|
swap SP_CC
|
|
NEXT_OP
|
|
RTI_CHK:
|
|
swap SP_CC /* SP is high 16 bits of SP_CC */
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
swap SP_CC
|
|
clr.w CC
|
|
move.b DATA, CC
|
|
and.b #0x3C, DATA /* Mask out mapped state */
|
|
move.b DATA, STATUS_6502(GLOBAL)
|
|
and.b #0xC3, CC
|
|
rol.b #2, CC
|
|
lea CC_6502_TO_68K(GLOBAL), ADDR
|
|
move.b (ADDR,CC.w), CC
|
|
bsr.w set_bcd_ops
|
|
swap SP_CC
|
|
addq.b #1, SP
|
|
move.b (MEMBASE,SP.w), DATA
|
|
addq.b #1, SP
|
|
lsl.w #8, DATA
|
|
move.b (MEMBASE,SP.w), DATA
|
|
rol.w #8, DATA
|
|
cmp.w #0xD000, DATA
|
|
bcs.b 0f
|
|
movem.l #0x1FFF, STATE_6502(GLOBAL)
|
|
bsr.w updateLanguageCardMapping
|
|
movem.l STATE_6502(GLOBAL), #0x1FFF
|
|
0:
|
|
lea (MEMBASE,DATA.l), PC
|
|
swap SP_CC
|
|
NEXT_OP
|
|
BRA:
|
|
move.b (PC)+, DATA
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BCS:
|
|
move.b (PC)+, DATA
|
|
btst #0, CC
|
|
beq.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BCC:
|
|
move.b (PC)+, DATA
|
|
btst #0, CC
|
|
bne.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BEQ:
|
|
move.b (PC)+, DATA
|
|
btst #2, CC
|
|
beq.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BNE:
|
|
move.b (PC)+, DATA
|
|
btst #2, CC
|
|
bne.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BMI:
|
|
move.b (PC)+, DATA
|
|
btst #3, CC
|
|
beq.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BPL:
|
|
move.b (PC)+, DATA
|
|
btst #3, CC
|
|
bne.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BVS:
|
|
move.b (PC)+, DATA
|
|
btst #1, CC
|
|
beq.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
BVC:
|
|
move.b (PC)+, DATA
|
|
btst #1, CC
|
|
bne.b .+6
|
|
ext.w DATA
|
|
add.w DATA, PC
|
|
NEXT_OP
|
|
LDA_IMM:
|
|
move.b (PC)+, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_ZP_IND:
|
|
EA_ZP_IND
|
|
LDA_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_IND_Y:
|
|
EA_IND_Y
|
|
LDA_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_IND_X:
|
|
EA_IND_X
|
|
LDA_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_ABS:
|
|
EA_ABS
|
|
LDA_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_ABS_Y:
|
|
EA_ABS_Y
|
|
LDA_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDA_ABS_X:
|
|
EA_ABS_X
|
|
LDA_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDY_IMM:
|
|
move.b (PC)+, Y
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDY_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), Y
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDY_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), Y
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDY_ABS:
|
|
EA_ABS
|
|
LDY_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDY_ABS_X:
|
|
EA_ABS_X
|
|
LDY_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDX_IMM:
|
|
move.b (PC)+, X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDX_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDX_ZP_Y:
|
|
EA_ZP_Y
|
|
move.b (MEMBASE,EA.w), X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDX_ABS:
|
|
EA_ABS
|
|
LDX_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
LDX_ABS_Y:
|
|
EA_ABS_Y
|
|
LDX_MEM
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
STA_ZP:
|
|
EA_ZP
|
|
move.b ACC, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STA_ZP_X:
|
|
EA_ZP_X
|
|
move.b ACC, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STA_IND_Y:
|
|
EA_IND_Y
|
|
STA_MEM
|
|
NEXT_OP
|
|
STA_IND_X:
|
|
EA_IND_X
|
|
STA_MEM
|
|
NEXT_OP
|
|
STA_ABS:
|
|
EA_ABS
|
|
STA_MEM
|
|
NEXT_OP
|
|
STA_ABS_Y:
|
|
EA_ABS_Y
|
|
STA_MEM
|
|
NEXT_OP
|
|
STA_ABS_X:
|
|
EA_ABS_X
|
|
STA_MEM
|
|
NEXT_OP
|
|
STY_ZP:
|
|
EA_ZP
|
|
move.b Y, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STY_ZP_X:
|
|
EA_ZP_X
|
|
move.b Y, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STY_ABS:
|
|
EA_ABS
|
|
STY_MEM
|
|
NEXT_OP
|
|
STX_ZP_Y:
|
|
EA_ZP_Y
|
|
move.b X, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STX_ZP:
|
|
EA_ZP
|
|
move.b X, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STX_ABS:
|
|
EA_ABS
|
|
STX_MEM
|
|
NEXT_OP
|
|
STZ_ZP:
|
|
EA_ZP
|
|
move.b #0, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
STZ_ABS:
|
|
EA_ABS
|
|
clr.w DATA
|
|
WR_MEM
|
|
NEXT_OP
|
|
STZ_ABS_X:
|
|
EA_ABS_X
|
|
clr.w DATA
|
|
WR_MEM
|
|
NEXT_OP
|
|
TAY:
|
|
move.b ACC, Y
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
TYA:
|
|
move.b Y, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
TAX:
|
|
move.b ACC, X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
TXA:
|
|
move.b X, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
TXS:
|
|
swap SP_CC
|
|
move.b X, SP
|
|
swap SP_CC
|
|
NEXT_OP
|
|
TSX:
|
|
swap SP_CC
|
|
move.b SP, DATA
|
|
swap SP_CC
|
|
move.b DATA, X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
BIT_IMM:
|
|
EA_IMM
|
|
OP_BIT
|
|
NEXT_OP
|
|
BIT_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_BIT
|
|
NEXT_OP
|
|
BIT_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_BIT
|
|
NEXT_OP
|
|
TRB_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_TRB
|
|
WR_MEM
|
|
NEXT_OP
|
|
TSB_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_TSB
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
TSB_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_TSB
|
|
WR_MEM
|
|
NEXT_OP
|
|
AND_IMM:
|
|
and.b (PC)+, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_ZP:
|
|
EA_ZP
|
|
and.b (MEMBASE,EA.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_ZP_X:
|
|
EA_ZP_X
|
|
and.b (MEMBASE,EA.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
and.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
and.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
and.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
and.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
AND_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
and.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_IMM:
|
|
or.b (PC)+, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_ZP:
|
|
EA_ZP
|
|
or.b (MEMBASE,EA.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_ZP_X:
|
|
EA_ZP_X
|
|
or.b (MEMBASE,EA.w), ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
or.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
or.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
or.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
or.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ORA_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
or.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_IMM:
|
|
EA_IMM
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
EOR_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
eor.b DATA, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
INC_ZP:
|
|
EA_ZP
|
|
addq.b #1, (MEMBASE,EA.w)
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
INC_ZP_X:
|
|
EA_ZP_X
|
|
addq.b #1, (MEMBASE,EA.w)
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
INC_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
addq.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZ_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
INC_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
addq.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZ_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
INA:
|
|
addq.b #1, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
INY:
|
|
addq.b #1, Y
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
INX:
|
|
addq.b #1, X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
DEC_ZP:
|
|
EA_ZP
|
|
subq.b #1, (MEMBASE,EA.w)
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
DEC_ZP_X:
|
|
EA_ZP_X
|
|
subq.b #1, (MEMBASE,EA.w)
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
DEC_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
subq.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZ_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
DEC_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
subq.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZ_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
DEA:
|
|
subq.b #1, ACC
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
DEY:
|
|
subq.b #1, Y
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
DEX:
|
|
subq.b #1, X
|
|
UPDATE_NZ_STATUS
|
|
NEXT_OP
|
|
ADC_BIN_IMM:
|
|
EA_IMM
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BIN_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
OP_ADC_BIN
|
|
NEXT_OP
|
|
ADC_BCD_IMM:
|
|
EA_IMM
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
ADC_BCD_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
OP_ADC_BCD
|
|
NEXT_OP
|
|
SBC_BIN_IMM:
|
|
EA_IMM
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BIN_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
OP_SBC_BIN
|
|
NEXT_OP
|
|
SBC_BCD_IMM:
|
|
EA_IMM
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
SBC_BCD_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
OP_SBC_BCD
|
|
NEXT_OP
|
|
CMP_IMM:
|
|
move.w ACC, DATA
|
|
sub.b (PC)+, DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CMP_ZP:
|
|
EA_ZP
|
|
move.w ACC, DATA
|
|
sub.b (MEMBASE,EA.w), DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CMP_ZP_IND:
|
|
EA_ZP_IND
|
|
RD_MEM
|
|
move.w ACC, ADDR
|
|
sub.b DATA, ACC
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, ACC
|
|
NEXT_OP
|
|
CMP_ZP_X:
|
|
EA_ZP_X
|
|
move.w ACC, DATA
|
|
sub.b (MEMBASE,EA.w), DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CMP_IND_Y:
|
|
EA_IND_Y
|
|
RD_MEM
|
|
move.w ACC, ADDR
|
|
sub.b DATA, ACC
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, ACC
|
|
NEXT_OP
|
|
CMP_IND_X:
|
|
EA_IND_X
|
|
RD_MEM
|
|
move.w ACC, ADDR
|
|
sub.b DATA, ACC
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, ACC
|
|
NEXT_OP
|
|
CMP_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
move.w ACC, ADDR
|
|
sub.b DATA, ACC
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, ACC
|
|
NEXT_OP
|
|
CMP_ABS_Y:
|
|
EA_ABS_Y
|
|
RD_MEM
|
|
move.w ACC, ADDR
|
|
sub.b DATA, ACC
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, ACC
|
|
NEXT_OP
|
|
CMP_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
move.w ACC, ADDR
|
|
sub.b DATA, ACC
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, ACC
|
|
NEXT_OP
|
|
CPY_IMM:
|
|
move.w Y, DATA
|
|
sub.b (PC)+, DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CPY_ZP:
|
|
EA_ZP
|
|
move.w Y, DATA
|
|
sub.b (MEMBASE,EA.w), DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CPY_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
move.w Y, ADDR
|
|
sub.b DATA, Y
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, Y
|
|
NEXT_OP
|
|
CPX_IMM:
|
|
move.w X, DATA
|
|
sub.b (PC)+, DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CPX_ZP:
|
|
EA_ZP
|
|
move.w X, DATA
|
|
sub.b (MEMBASE,EA.w), DATA
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
NEXT_OP
|
|
CPX_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
move.w X, ADDR
|
|
sub.b DATA, X
|
|
UPDATE_NZC_STATUS
|
|
eor.b #0x11, CC
|
|
move.w ADDR, X
|
|
NEXT_OP
|
|
ASL_ACC:
|
|
asl.b #1, ACC
|
|
UPDATE_NZC_STATUS
|
|
NEXT_OP
|
|
ASL_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
asl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
ASL_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
asl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
ASL_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
asl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
ASL_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
asl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
LSR_ACC:
|
|
lsr.b #1, ACC
|
|
UPDATE_NZC_STATUS
|
|
NEXT_OP
|
|
LSR_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
lsr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
LSR_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
lsr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
LSR_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
lsr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
LSR_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
lsr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
ROL_ACC:
|
|
move.w CC, %ccr
|
|
roxl.b #1, ACC
|
|
UPDATE_NZC_STATUS
|
|
NEXT_OP
|
|
ROL_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
move.w CC, %ccr
|
|
roxl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
ROL_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
move.w CC, %ccr
|
|
roxl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
ROL_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
move.w CC, %ccr
|
|
roxl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
ROL_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
move.w CC, %ccr
|
|
roxl.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
ROR_ACC:
|
|
move.w CC, %ccr
|
|
roxr.b #1, ACC
|
|
UPDATE_NZC_STATUS
|
|
NEXT_OP
|
|
ROR_ZP:
|
|
EA_ZP
|
|
move.b (MEMBASE,EA.w), DATA
|
|
move.w CC, %ccr
|
|
roxr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
ROR_ZP_X:
|
|
EA_ZP_X
|
|
move.b (MEMBASE,EA.w), DATA
|
|
move.w CC, %ccr
|
|
roxr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
move.w ADDR, DATA
|
|
move.b DATA, (MEMBASE,EA.w)
|
|
NEXT_OP
|
|
ROR_ABS:
|
|
EA_ABS
|
|
RD_MEM
|
|
move.w CC, %ccr
|
|
roxr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
ROR_ABS_X:
|
|
EA_ABS_X
|
|
RD_MEM
|
|
move.w CC, %ccr
|
|
roxr.b #1, DATA
|
|
move.w DATA, ADDR
|
|
UPDATE_NZC_STATUS
|
|
WRA_MEM
|
|
NEXT_OP
|
|
/*
|
|
* Execute 6502 instructions for # of clocks.
|
|
*/
|
|
.global run6502
|
|
run6502:
|
|
movem.l #0x7FFE, -(%sp) /* Save all registers */
|
|
movem.l STATE_6502_2(GLOBAL), #0x1FFC /* Load 6502 state */
|
|
clr.l DATA
|
|
sub.l ADDR, ADDR
|
|
move.l 60(%sp), INSTRNS /* Load instruction count */
|
|
NEXT_OP
|
|
opfetch:
|
|
clr.w DATA
|
|
move.b (PC)+, DATA /* Load opcode */
|
|
add.w DATA, DATA
|
|
move.w (OPBASE, DATA.w), ADDR
|
|
jmp 2(%pc,ADDR.w)
|
|
exit6502: /* This MUST follow the previous*/
|
|
movem.l #0x1FFC, STATE_6502_2(GLOBAL) /* jmp from opfetch */
|
|
movem.l (%sp)+, #0x7FFE
|
|
clr.l %d0
|
|
rts
|
|
|
|
#define OP_OFFSET(op) ((op)-exit6502)
|
|
|
|
/*
|
|
* Initialize the CPU state and opcode arrays.
|
|
*/
|
|
.globl reset6502
|
|
reset6502:
|
|
movem.l #0xFFFA, -(%sp) /* Save all registers */
|
|
/*
|
|
* Init CPU state.
|
|
*/
|
|
move.l 60(%sp), MEMBASE /* Load Pointer to memory */
|
|
move.l #0xFFFC, %d0
|
|
move.w (MEMBASE,%d0.l), %d0
|
|
rol.w #8, %d0
|
|
move.l %d0, PC
|
|
add.l MEMBASE, PC
|
|
lea OPTABLE(0)(GLOBAL), OPBASE
|
|
move.l 64(%sp), WRMEM
|
|
move.l 68(%sp), RDMEM
|
|
move.b #CC_1_6502, STATUS_6502(GLOBAL)
|
|
clr.l ACC
|
|
clr.l X
|
|
clr.l Y
|
|
move.l #0x01FF0000, SP_CC
|
|
clr.l EA
|
|
clr.l PAGE
|
|
movem.l #0x1FFC, STATE_6502_2(GLOBAL) /* Save 6502 state */
|
|
lea OPTABLE(0)(GLOBAL), %a0
|
|
/*
|
|
* Set ADC and SBC based on DECIMAL flag.
|
|
*/
|
|
bsr set_bcd_ops
|
|
movem.l (%sp)+, #0x5FFF /* Restore all registers */
|
|
rts
|
|
/*
|
|
* Update the opcode pointers based on the BCD decimal flag.
|
|
*/
|
|
set_bcd_ops:
|
|
btst #3, STATUS_6502(GLOBAL)
|
|
bne bcd_ops
|
|
move.w #OP_OFFSET(ADC_BIN_IMM), 0x69*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_ZP), 0x65*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_ZP_X), 0x75*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_ABS), 0x6D*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_ABS_X), 0x7D*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_ABS_Y), 0x79*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_IND_X), 0x61*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BIN_IND_Y), 0x71*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_IMM), 0xE9*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_ZP), 0xE5*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_ZP_X), 0xF5*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_ABS), 0xED*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_ABS_X), 0xFD*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_ABS_Y), 0xF9*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_IND_X), 0xE1*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BIN_IND_Y), 0xF1*2(OPBASE)
|
|
rts
|
|
bcd_ops:
|
|
move.w #OP_OFFSET(ADC_BCD_IMM), 0x69*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_ZP), 0x65*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_ZP_X), 0x75*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_ABS), 0x6D*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_ABS_X), 0x7D*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_ABS_Y), 0x79*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_IND_X), 0x61*2(OPBASE)
|
|
move.w #OP_OFFSET(ADC_BCD_IND_Y), 0x71*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_IMM), 0xE9*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_ZP), 0xE5*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_ZP_X), 0xF5*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_ABS), 0xED*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_ABS_X), 0xFD*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_ABS_Y), 0xF9*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_IND_X), 0xE1*2(OPBASE)
|
|
move.w #OP_OFFSET(SBC_BCD_IND_Y), 0xF1*2(OPBASE)
|
|
rts
|
|
/*
|
|
* Update to checked Program Counter range.
|
|
*/
|
|
.global setPcCheckFuncs
|
|
setPcCheckFuncs:
|
|
move.w #OP_OFFSET(BRK_CHK), OPTABLE(0x00*2)(GLOBAL)
|
|
move.w #OP_OFFSET(JSR_CHK), OPTABLE(0x20*2)(GLOBAL)
|
|
move.w #OP_OFFSET(RTI_CHK), OPTABLE(0x40*2)(GLOBAL)
|
|
move.w #OP_OFFSET(JMP_ABS_CHK), OPTABLE(0x4C*2)(GLOBAL)
|
|
move.w #OP_OFFSET(RTS_CHK), OPTABLE(0x60*2)(GLOBAL)
|
|
move.w #OP_OFFSET(JMP_IND_CHK), OPTABLE(0x6C*2)(GLOBAL)
|
|
rts
|
|
/*
|
|
* Update to unchecked Program Counter range.
|
|
*/
|
|
.global clrPcCheckFuncs
|
|
clrPcCheckFuncs:
|
|
move.w #OP_OFFSET(BRK), OPTABLE(0x00*2)(GLOBAL)
|
|
move.w #OP_OFFSET(JSR), OPTABLE(0x20*2)(GLOBAL)
|
|
move.w #OP_OFFSET(RTI), OPTABLE(0x40*2)(GLOBAL)
|
|
move.w #OP_OFFSET(JMP_ABS), OPTABLE(0x4C*2)(GLOBAL)
|
|
move.w #OP_OFFSET(RTS), OPTABLE(0x60*2)(GLOBAL)
|
|
move.w #OP_OFFSET(JMP_IND), OPTABLE(0x6C*2)(GLOBAL)
|
|
rts
|
|
|
|
.data
|
|
.even
|
|
.global opTable6502
|
|
opTable6502:
|
|
/*
|
|
* 0x00 - 0x0F
|
|
*/
|
|
.word OP_OFFSET(BRK)
|
|
.word OP_OFFSET(ORA_IND_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(TSB_ZP)
|
|
.word OP_OFFSET(ORA_ZP)
|
|
.word OP_OFFSET(ASL_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(PHP)
|
|
.word OP_OFFSET(ORA_IMM)
|
|
.word OP_OFFSET(ASL_ACC)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(TSB_ABS)
|
|
.word OP_OFFSET(ORA_ABS)
|
|
.word OP_OFFSET(ASL_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x10 - 0x1F
|
|
*/
|
|
.word OP_OFFSET(BPL)
|
|
.word OP_OFFSET(ORA_IND_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(ORA_ZP_X)
|
|
.word OP_OFFSET(ASL_ZP_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CLC)
|
|
.word OP_OFFSET(ORA_ABS_Y)
|
|
.word OP_OFFSET(INA)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(TRB_ABS)
|
|
.word OP_OFFSET(ORA_ABS_X)
|
|
.word OP_OFFSET(ASL_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x20 - 0x2F
|
|
*/
|
|
.word OP_OFFSET(JSR)
|
|
.word OP_OFFSET(AND_IND_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(BIT_ZP)
|
|
.word OP_OFFSET(AND_ZP)
|
|
.word OP_OFFSET(ROL_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(PLP)
|
|
.word OP_OFFSET(AND_IMM)
|
|
.word OP_OFFSET(ROL_ACC)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(BIT_ABS)
|
|
.word OP_OFFSET(AND_ABS)
|
|
.word OP_OFFSET(ROL_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x30 - 0x3F
|
|
*/
|
|
.word OP_OFFSET(BMI)
|
|
.word OP_OFFSET(AND_IND_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(AND_ZP_X)
|
|
.word OP_OFFSET(ROL_ZP_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(SEC)
|
|
.word OP_OFFSET(AND_ABS_Y)
|
|
.word OP_OFFSET(DEA)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(AND_ABS_X)
|
|
.word OP_OFFSET(ROL_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x40 - 0x4F
|
|
*/
|
|
.word OP_OFFSET(RTI)
|
|
.word OP_OFFSET(EOR_IND_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(EOR_ZP)
|
|
.word OP_OFFSET(LSR_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(PHA)
|
|
.word OP_OFFSET(EOR_IMM)
|
|
.word OP_OFFSET(LSR_ACC)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(JMP_ABS)
|
|
.word OP_OFFSET(EOR_ABS)
|
|
.word OP_OFFSET(LSR_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x50 - 0x5F
|
|
*/
|
|
.word OP_OFFSET(BVC)
|
|
.word OP_OFFSET(EOR_IND_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(EOR_ZP_X)
|
|
.word OP_OFFSET(LSR_ZP_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CLI)
|
|
.word OP_OFFSET(EOR_ABS_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(EOR_ABS_X)
|
|
.word OP_OFFSET(LSR_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x60 - 0x6F
|
|
*/
|
|
.word OP_OFFSET(RTS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(STZ_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(ROR_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(PLA)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(ROR_ACC)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(JMP_IND)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(ROR_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x70 - 0x7F
|
|
*/
|
|
.word OP_OFFSET(BVS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(ROR_ZP_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(SEI)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(ROR_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x80 - 0x8F
|
|
*/
|
|
.word OP_OFFSET(BRA)
|
|
.word OP_OFFSET(STA_IND_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(STY_ZP)
|
|
.word OP_OFFSET(STA_ZP)
|
|
.word OP_OFFSET(STX_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(DEY)
|
|
.word OP_OFFSET(BIT_IMM)
|
|
.word OP_OFFSET(TXA)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(STY_ABS)
|
|
.word OP_OFFSET(STA_ABS)
|
|
.word OP_OFFSET(STX_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0x90 - 0x9F
|
|
*/
|
|
.word OP_OFFSET(BCC)
|
|
.word OP_OFFSET(STA_IND_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(STY_ZP_X)
|
|
.word OP_OFFSET(STA_ZP_X)
|
|
.word OP_OFFSET(STX_ZP_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(TYA)
|
|
.word OP_OFFSET(STA_ABS_Y)
|
|
.word OP_OFFSET(TXS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(STZ_ABS)
|
|
.word OP_OFFSET(STA_ABS_X)
|
|
.word OP_OFFSET(STZ_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0xA0 - 0xAF
|
|
*/
|
|
.word OP_OFFSET(LDY_IMM)
|
|
.word OP_OFFSET(LDA_IND_X)
|
|
.word OP_OFFSET(LDX_IMM)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(LDY_ZP)
|
|
.word OP_OFFSET(LDA_ZP)
|
|
.word OP_OFFSET(LDX_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(TAY)
|
|
.word OP_OFFSET(LDA_IMM)
|
|
.word OP_OFFSET(TAX)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(LDY_ABS)
|
|
.word OP_OFFSET(LDA_ABS)
|
|
.word OP_OFFSET(LDX_ABS)
|
|
.word exit6502-UNIMPLEMENTED
|
|
/*
|
|
* 0xB0 - 0xBF
|
|
*/
|
|
.word OP_OFFSET(BCS)
|
|
.word OP_OFFSET(LDA_IND_Y)
|
|
.word OP_OFFSET(LDA_ZP_IND)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(LDY_ZP_X)
|
|
.word OP_OFFSET(LDA_ZP_X)
|
|
.word OP_OFFSET(LDX_ZP_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CLV)
|
|
.word OP_OFFSET(LDA_ABS_Y)
|
|
.word OP_OFFSET(TSX)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(LDY_ABS_X)
|
|
.word OP_OFFSET(LDA_ABS_X)
|
|
.word OP_OFFSET(LDX_ABS_Y)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0xC0 - 0xCF
|
|
*/
|
|
.word OP_OFFSET(CPY_IMM)
|
|
.word OP_OFFSET(CMP_IND_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CPY_ZP)
|
|
.word OP_OFFSET(CMP_ZP)
|
|
.word OP_OFFSET(DEC_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(INY)
|
|
.word OP_OFFSET(CMP_IMM)
|
|
.word OP_OFFSET(DEX)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CPY_ABS)
|
|
.word OP_OFFSET(CMP_ABS)
|
|
.word OP_OFFSET(DEC_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0xD0 - 0xDF
|
|
*/
|
|
.word OP_OFFSET(BNE)
|
|
.word OP_OFFSET(CMP_IND_Y)
|
|
.word OP_OFFSET(CMP_ZP_IND)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CMP_ZP_X)
|
|
.word OP_OFFSET(DEC_ZP_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CLD)
|
|
.word OP_OFFSET(CMP_ABS_Y)
|
|
.word OP_OFFSET(PHX)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CMP_ABS_X)
|
|
.word OP_OFFSET(DEC_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0xE0 - 0xEF
|
|
*/
|
|
.word OP_OFFSET(CPX_IMM)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CPX_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(INC_ZP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(INX)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(NOP)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(CPX_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(INC_ABS)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
/*
|
|
* 0xF0 - 0xFF
|
|
*/
|
|
.word OP_OFFSET(BEQ)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(INC_ZP_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(SED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(PLX)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.word OP_OFFSET(INC_ABS_X)
|
|
.word OP_OFFSET(UNIMPLEMENTED)
|
|
.even
|
|
.comm state6502, 13*4
|
|
.comm status6502, 1
|
|
|