mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-12 06:29:58 +00:00
Get some CPU tests passing on ARM/Android
This commit is contained in:
parent
43fa9c9357
commit
3149914741
@ -24,10 +24,10 @@
|
|||||||
#define Y_Reg r6 /* 8bit 6502 Y register */
|
#define Y_Reg r6 /* 8bit 6502 Y register */
|
||||||
#define X_Reg r7 /* 8bit 6502 X register */
|
#define X_Reg r7 /* 8bit 6502 X register */
|
||||||
#define A_Reg r8 /* 8bit 6502 A register */
|
#define A_Reg r8 /* 8bit 6502 A register */
|
||||||
// r9 is another scratch variable
|
// r9 is "ARM platform register" ... used as a scratch register
|
||||||
#define reg_64k r10 /* apple_ii_64k table address */
|
// r10 is another scratch variable
|
||||||
#define reg_vmem_r r11 /* cpu65_vmem_r table address */
|
#define reg_vmem_r r11 /* cpu65_vmem_r table address */
|
||||||
// r12 unused
|
// r12 is "ARM Intra-Procedure-call scratch register" ... used as a scratch register
|
||||||
// r13 ARM SP
|
// r13 ARM SP
|
||||||
// r14 ARM return addr
|
// r14 ARM return addr
|
||||||
// r15 ARM PC
|
// r15 ARM PC
|
||||||
@ -36,10 +36,6 @@
|
|||||||
#define ARM_AF_Bit ...
|
#define ARM_AF_Bit ...
|
||||||
|
|
||||||
|
|
||||||
// x86-ish instruction macros for legibility =P
|
|
||||||
#define ret mov pc, r14
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
# error 20150205 ARM 64bit untested!!!
|
# error 20150205 ARM 64bit untested!!!
|
||||||
# define PTR_SHIFT #4 // 4<<1 = 8
|
# define PTR_SHIFT #4 // 4<<1 = 8
|
||||||
|
132
src/arm/cpu.S
132
src/arm/cpu.S
@ -17,11 +17,6 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
// debugging is necessary for running CPU test suite and to use the 65c02 debugger
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define CPU_DEBUGGING 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DecodeFlags \
|
#define DecodeFlags \
|
||||||
ldr r1, SYM(cpu65_flags_decode); \
|
ldr r1, SYM(cpu65_flags_decode); \
|
||||||
ldrb F_Reg, [r1, r0];
|
ldrb F_Reg, [r1, r0];
|
||||||
@ -51,7 +46,6 @@
|
|||||||
ldr r1, SYM(cpu65_f); \
|
ldr r1, SYM(cpu65_f); \
|
||||||
strb r0, [r1]
|
strb r0, [r1]
|
||||||
|
|
||||||
|
|
||||||
// Tracing is necessary for some CPU tests and to verify operation against other emulators
|
// Tracing is necessary for some CPU tests and to verify operation against other emulators
|
||||||
#if CPU_TRACING
|
#if CPU_TRACING
|
||||||
# define TRACE_PROLOGUE \
|
# define TRACE_PROLOGUE \
|
||||||
@ -65,10 +59,10 @@
|
|||||||
# define TRACE_ARG2 \
|
# define TRACE_ARG2 \
|
||||||
bl CALL(cpu65_trace_arg2);
|
bl CALL(cpu65_trace_arg2);
|
||||||
# define TRACE_EPILOGUE \
|
# define TRACE_EPILOGUE \
|
||||||
push {r0}; \
|
|
||||||
CommonSaveCPUState; \
|
CommonSaveCPUState; \
|
||||||
|
push {r0, EffectiveAddr, PC_Reg, lr}; \
|
||||||
bl CALL(cpu65_trace_epilogue); \
|
bl CALL(cpu65_trace_epilogue); \
|
||||||
pop {r0};
|
pop {r0, EffectiveAddr, PC_Reg, lr};
|
||||||
#else
|
#else
|
||||||
# define TRACE_PROLOGUE
|
# define TRACE_PROLOGUE
|
||||||
# define TRACE_ARG
|
# define TRACE_ARG
|
||||||
@ -78,50 +72,57 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if CPU_DEBUGGING
|
#define CPUStatsReset \
|
||||||
# define CPU_DEBUGGING_RESET \
|
|
||||||
ldr r1, SYM(cpu65_opcode); \
|
ldr r1, SYM(cpu65_opcode); \
|
||||||
strb r0, [r1]; /* r0 should be next opcode */ \
|
strb r0, [r1]; /* r0 should be next opcode */ \
|
||||||
eor r9, r9, r9; \
|
eor r9, r9, r9; \
|
||||||
ldr r1, SYM(cpu65_opcycles); \
|
ldr r1, SYM(cpu65_opcycles); \
|
||||||
strb r9, [r1]; \
|
strb r9, [r1]; \
|
||||||
/*ldr r1, SYM(cpu65_rw);*/ \
|
ldr r1, SYM(cpu65_rw); \
|
||||||
strb r9, [r1];
|
strb r9, [r1];
|
||||||
# define CPU_DEBUGGING_SET_READ \
|
#define CPUStatsSetRead \
|
||||||
/*ldr r1, SYM(cpu65_rw);*/ \
|
ldr r1, SYM(cpu65_rw); \
|
||||||
ldrb r9, [r1]; \
|
ldrb r9, [r1]; \
|
||||||
orr r9, r9, #1; \
|
orr r9, r9, #1; \
|
||||||
strb r9, [r1];
|
strb r9, [r1];
|
||||||
# define CPU_DEBUGGING_SET_WRITE \
|
|
||||||
/*ldr r1, SYM(cpu65_rw);*/ \
|
#define CPUStatsSetWrite \
|
||||||
|
ldr r1, SYM(cpu65_rw); \
|
||||||
ldrb r9, [r1]; \
|
ldrb r9, [r1]; \
|
||||||
orr r9, r9, #2; \
|
orr r9, r9, #2; \
|
||||||
strb r9, [r1]; \
|
strb r9, [r1]; \
|
||||||
ldr r1, SYM(cpu65_d); \
|
ldr r1, SYM(cpu65_d); \
|
||||||
strb r0, [r1];
|
strb r0, [r1];
|
||||||
#else
|
|
||||||
# define CPU_DEBUGGING_SET_READ
|
|
||||||
# define CPU_DEBUGGING_RESET
|
|
||||||
# define CPU_DEBUGGING_SET_WRITE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// CPU (6502) helper macros
|
// CPU (6502) helper macros
|
||||||
|
|
||||||
|
// Add 16bit x with <=16bit amt
|
||||||
#define AddUint16(x, amt) \
|
#define AddUint16(x, amt) \
|
||||||
add x, x, amt; \
|
add x, x, amt; \
|
||||||
bic x, #0x10000;
|
bic x, #0x10000;
|
||||||
|
|
||||||
|
// Increment 16bit x
|
||||||
#define IncUint16(x) \
|
#define IncUint16(x) \
|
||||||
AddUint16(x, #1)
|
AddUint16(x, #1)
|
||||||
|
|
||||||
#define SubUint16(x, amt) \
|
// Add 8bit x with <=8bit amt
|
||||||
sub x, x, amt; \
|
#define AddUint8(x, amt) \
|
||||||
mov x, x, LSL #16; \
|
add x, x, amt; \
|
||||||
mov x, x, LSR #16;
|
bic SP_Reg, #0x0100;
|
||||||
|
|
||||||
#define DecUint16(x) \
|
// Increment 8bit x
|
||||||
SubUint16(x, #1)
|
#define IncUint8(x) \
|
||||||
|
AddUint8(x, #1)
|
||||||
|
|
||||||
|
// Subtract 8bit x by <=8bit amt
|
||||||
|
#define SubUint8(x, amt) \
|
||||||
|
subs x, x, amt; \
|
||||||
|
movmi x, #0xFF;
|
||||||
|
|
||||||
|
// Decrement 8bit x
|
||||||
|
#define DecUint8(x) \
|
||||||
|
SubUint8(x, #1)
|
||||||
|
|
||||||
#define GetFromPC_B \
|
#define GetFromPC_B \
|
||||||
mov EffectiveAddr, PC_Reg; \
|
mov EffectiveAddr, PC_Reg; \
|
||||||
@ -150,13 +151,13 @@
|
|||||||
#define JumpNextInstruction \
|
#define JumpNextInstruction \
|
||||||
TRACE_PROLOGUE \
|
TRACE_PROLOGUE \
|
||||||
GetFromPC_B \
|
GetFromPC_B \
|
||||||
CPU_DEBUGGING_RESET \
|
CPUStatsReset \
|
||||||
ldr r1, SYM(cpu65__opcodes); \
|
ldr r1, SYM(cpu65__opcodes); \
|
||||||
ldr r1, [r1, r0, LSL PTR_SHIFT]; \
|
ldr r1, [r1, r0, LSL PTR_SHIFT]; \
|
||||||
bx r1;
|
bx r1;
|
||||||
|
|
||||||
#define GetFromEA_B \
|
#define GetFromEA_B \
|
||||||
CPU_DEBUGGING_SET_READ \
|
CPUStatsSetRead \
|
||||||
ldr r1, [reg_vmem_r, EffectiveAddr, LSL PTR_SHIFT]; \
|
ldr r1, [reg_vmem_r, EffectiveAddr, LSL PTR_SHIFT]; \
|
||||||
blx r1;
|
blx r1;
|
||||||
|
|
||||||
@ -171,7 +172,7 @@
|
|||||||
orr r0, hi_byte, lo_byte;
|
orr r0, hi_byte, lo_byte;
|
||||||
|
|
||||||
#define PutToEA_B \
|
#define PutToEA_B \
|
||||||
CPU_DEBUGGING_SET_WRITE \
|
CPUStatsSetWrite \
|
||||||
ldr r1, SYM(cpu65_vmem_w); \
|
ldr r1, SYM(cpu65_vmem_w); \
|
||||||
ldr r1, [r1, EffectiveAddr, LSL PTR_SHIFT]; \
|
ldr r1, [r1, EffectiveAddr, LSL PTR_SHIFT]; \
|
||||||
blx r1;
|
blx r1;
|
||||||
@ -200,15 +201,14 @@
|
|||||||
#define pc_hi_next r0
|
#define pc_hi_next r0
|
||||||
#define BranchXCycles \
|
#define BranchXCycles \
|
||||||
ldr mem_cycle_count, SYM(cpu65_opcycles); \
|
ldr mem_cycle_count, SYM(cpu65_opcycles); \
|
||||||
eor scratch_count, scratch_count, scratch_count; /* HACK FIXME TODO VERIFY IN GDB : is this necessary? */ \
|
|
||||||
ldrb scratch_count, [mem_cycle_count]; \
|
ldrb scratch_count, [mem_cycle_count]; \
|
||||||
add scratch_count, scratch_count, #1; /* +1 branch taken */ \
|
add scratch_count, scratch_count, #1; /* +1 branch taken */ \
|
||||||
mov pc_hi_prev, PC_Reg; \
|
mov pc_hi_prev, PC_Reg; \
|
||||||
mov pc_hi_prev, pc_hi_prev, LSR #8; \
|
mov pc_hi_prev, pc_hi_prev, LSR #8; \
|
||||||
cbw; \
|
cbw; \
|
||||||
add PC_Reg, PC_Reg, r0; /* branch PC */ \
|
add PC_Reg, PC_Reg, r0; /* branch PC */ \
|
||||||
mov PC_Reg, PC_Reg, LSL #24; /* 16bit under/overflow protection */ \
|
mov PC_Reg, PC_Reg, LSL #16; /* 16bit under/overflow protection */ \
|
||||||
mov PC_Reg, PC_Reg, LSR #24; \
|
mov PC_Reg, PC_Reg, LSR #16; \
|
||||||
mov pc_hi_next, PC_Reg; \
|
mov pc_hi_next, PC_Reg; \
|
||||||
mov pc_hi_next, pc_hi_next, LSR #8; \
|
mov pc_hi_next, pc_hi_next, LSR #8; \
|
||||||
teq pc_hi_next, pc_hi_prev; \
|
teq pc_hi_next, pc_hi_prev; \
|
||||||
@ -266,6 +266,7 @@
|
|||||||
#ifdef APPLE2_VM
|
#ifdef APPLE2_VM
|
||||||
#define RestoreAltZP \
|
#define RestoreAltZP \
|
||||||
ldr stack_loc, SYM(base_stackzp); \
|
ldr stack_loc, SYM(base_stackzp); \
|
||||||
|
ldr stack_loc, [stack_loc]; \
|
||||||
add stack_loc, stack_loc, #0x100; \
|
add stack_loc, stack_loc, #0x100; \
|
||||||
add stack_loc, stack_loc, SP_Reg;
|
add stack_loc, stack_loc, SP_Reg;
|
||||||
#else
|
#else
|
||||||
@ -275,16 +276,14 @@
|
|||||||
#define Push(x) \
|
#define Push(x) \
|
||||||
RestoreAltZP \
|
RestoreAltZP \
|
||||||
strb x, [stack_loc]; \
|
strb x, [stack_loc]; \
|
||||||
subs SP_Reg, SP_Reg, #1; \
|
DecUint8(SP_Reg)
|
||||||
movmi SP_Reg, #0xFF;
|
#warning TODO FIXME ... need to write a 65c02 stack underflow vm test ... also how does AppleWin handle 65c02 underflow?
|
||||||
#warning TODO FIXME ... need to write a 65c02 stack_loc underflow vm test ... also how does AppleWin handle 65c02 underflow?
|
|
||||||
|
|
||||||
#define Pop(x) \
|
#define Pop(x) \
|
||||||
add SP_Reg, SP_Reg, #1; \
|
IncUint8(SP_Reg) \
|
||||||
bic SP_Reg, #0x0100; \
|
|
||||||
RestoreAltZP \
|
RestoreAltZP \
|
||||||
ldrb x, [stack_loc];
|
ldrb x, [stack_loc];
|
||||||
#warning TODO FIXME ... need to write a 65c02 stack overflow vm test ... also how does AppleWin handle 65c02 underflow?
|
#warning TODO FIXME ... need to write a 65c02 stack overflow vm test ... also how does AppleWin handle 65c02 overflow?
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// addressing macros
|
// addressing macros
|
||||||
@ -799,9 +798,6 @@ ENTRY(op_ADC_ind_zpage)
|
|||||||
DoADC_b
|
DoADC_b
|
||||||
Continue
|
Continue
|
||||||
|
|
||||||
mask_FFFF: .hword 0xFFFF
|
|
||||||
interrupt_vector: .hword 0xFFFE
|
|
||||||
reset_vector: .hword 0xFFFC
|
|
||||||
.ltorg
|
.ltorg
|
||||||
|
|
||||||
/* ----------------------------------
|
/* ----------------------------------
|
||||||
@ -1088,7 +1084,6 @@ ENTRY(op_BRA)
|
|||||||
|
|
||||||
ENTRY(op_UNK) /* make undefined opcodes fault */
|
ENTRY(op_UNK) /* make undefined opcodes fault */
|
||||||
ENTRY(op_BRK)
|
ENTRY(op_BRK)
|
||||||
#warning TODO FIXME ... write test for overflow in op_BRK
|
|
||||||
IncUint16(PC_Reg)
|
IncUint16(PC_Reg)
|
||||||
mov r0, PC_Reg
|
mov r0, PC_Reg
|
||||||
mov r0, r0, ROR #8
|
mov r0, r0, ROR #8
|
||||||
@ -1465,7 +1460,6 @@ ENTRY(op_JMP_abs_ind_x)
|
|||||||
add EffectiveAddr, r0
|
add EffectiveAddr, r0
|
||||||
mov EffectiveAddr, EffectiveAddr, LSL #24 // 16bit under/overflow protection
|
mov EffectiveAddr, EffectiveAddr, LSL #24 // 16bit under/overflow protection
|
||||||
mov EffectiveAddr, EffectiveAddr, LSR #24
|
mov EffectiveAddr, EffectiveAddr, LSR #24
|
||||||
#warning FIXME TODO write test for op_JMP_abs_ind_x under/overflow protection
|
|
||||||
GetFromMem_W(EffectiveAddr)
|
GetFromMem_W(EffectiveAddr)
|
||||||
mov PC_Reg, r0
|
mov PC_Reg, r0
|
||||||
Continue
|
Continue
|
||||||
@ -1475,11 +1469,10 @@ ENTRY(op_JMP_abs_ind_x)
|
|||||||
---------------------------------- */
|
---------------------------------- */
|
||||||
|
|
||||||
ENTRY(op_JSR) // 0x20
|
ENTRY(op_JSR) // 0x20
|
||||||
#warning TODO FIXME write test for op_JSR underflow ...
|
|
||||||
GetAbs
|
GetAbs
|
||||||
mov r0, PC_Reg
|
mov r0, PC_Reg
|
||||||
subs r0, r0, #1
|
sub r0, r0, #1
|
||||||
mov r0, r0, LSL #16 // handle underflow
|
mov r0, r0, LSL #16 // handle underflow -- can this happen in second mem page?
|
||||||
mov r0, r0, ROR #24
|
mov r0, r0, ROR #24
|
||||||
Push(r0) // push hi_byte
|
Push(r0) // push hi_byte
|
||||||
mov r0, r0, LSR #24
|
mov r0, r0, LSR #24
|
||||||
@ -1849,7 +1842,6 @@ ENTRY(op_RTI) // 0x40
|
|||||||
---------------------------------- */
|
---------------------------------- */
|
||||||
|
|
||||||
ENTRY(op_RTS) // 0x60
|
ENTRY(op_RTS) // 0x60
|
||||||
#warning TODO FIXME write test for this overflow ...
|
|
||||||
Pop(lo_byte)
|
Pop(lo_byte)
|
||||||
Pop(hi_byte)
|
Pop(hi_byte)
|
||||||
mov hi_byte, hi_byte, LSL #8
|
mov hi_byte, hi_byte, LSL #8
|
||||||
@ -2323,37 +2315,36 @@ continue:
|
|||||||
ldrb r0, [r0]
|
ldrb r0, [r0]
|
||||||
ldrb cycles_exe, [r1, r0]
|
ldrb cycles_exe, [r1, r0]
|
||||||
ldr r1, SYM(cpu65_opcycles)
|
ldr r1, SYM(cpu65_opcycles)
|
||||||
ldrb r2, [r1]
|
ldrb r9, [r1]
|
||||||
add cycles_exe, cycles_exe, r2
|
add cycles_exe, cycles_exe, r9
|
||||||
strb cycles_exe, [r1]
|
strb cycles_exe, [r1]
|
||||||
TRACE_EPILOGUE
|
TRACE_EPILOGUE
|
||||||
|
|
||||||
ldr r1, SYM(gc_cycles_timer_0)
|
ldr r1, SYM(gc_cycles_timer_0)
|
||||||
ldr r2, [r1]
|
ldr r9, [r1]
|
||||||
sub r2, r2, cycles_exe
|
sub r9, r9, cycles_exe
|
||||||
str r2, [r1]
|
str r9, [r1]
|
||||||
|
|
||||||
ldr r1, SYM(gc_cycles_timer_1)
|
ldr r1, SYM(gc_cycles_timer_1)
|
||||||
ldr r2, [r1]
|
ldr r9, [r1]
|
||||||
sub r2, r2, cycles_exe
|
sub r9, r9, cycles_exe
|
||||||
str r2, [r1]
|
str r9, [r1]
|
||||||
|
|
||||||
ldr r1, SYM(cpu65_cycle_count)
|
ldr r1, SYM(cpu65_cycle_count)
|
||||||
ldr r2, [r1]
|
ldr r9, [r1]
|
||||||
add r2, r2, cycles_exe
|
add r9, r9, cycles_exe
|
||||||
str r2, [r1]
|
str r9, [r1]
|
||||||
|
|
||||||
ldr r1, SYM(cpu65_cycles_to_execute)
|
ldr r1, SYM(cpu65_cycles_to_execute)
|
||||||
ldr r2, [r1]
|
ldr r9, [r1]
|
||||||
subs r2, r2, cycles_exe
|
subs r9, r9, cycles_exe
|
||||||
str r2, [r1]
|
str r9, [r1]
|
||||||
bmi exit_cpu65_run
|
bmi exit_cpu65_run
|
||||||
beq exit_cpu65_run
|
beq exit_cpu65_run
|
||||||
|
|
||||||
continue1: eor r0, r0, r0
|
continue1: ldr r1, SYM(cpu65__signal)
|
||||||
ldr r1, SYM(cpu65__signal)
|
|
||||||
ldrb r0, [r1]
|
ldrb r0, [r1]
|
||||||
orr r0, r0, r0
|
orrs r0, r0, r0
|
||||||
bne exception
|
bne exception
|
||||||
JumpNextInstruction
|
JumpNextInstruction
|
||||||
|
|
||||||
@ -2405,8 +2396,9 @@ ex_irq: tst F_Reg, #I_Flag // Already interrupt
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
ENTRY(cpu65_run)
|
ENTRY(cpu65_run)
|
||||||
|
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||||
// Restore CPU state when being called from C.
|
// Restore CPU state when being called from C.
|
||||||
#warning FIXME TODO ... do all the ldrb's zero-out the high-24bits of the destination reg?
|
ldr reg_vmem_r, SYM(cpu65_vmem_r)
|
||||||
ldr r1, SYM(cpu65_ea)
|
ldr r1, SYM(cpu65_ea)
|
||||||
ldrh EffectiveAddr, [r1]
|
ldrh EffectiveAddr, [r1]
|
||||||
ldr r1, SYM(cpu65_pc)
|
ldr r1, SYM(cpu65_pc)
|
||||||
@ -2439,7 +2431,7 @@ exit_cpu65_run:
|
|||||||
ldr r1, SYM(cpu65_pc)
|
ldr r1, SYM(cpu65_pc)
|
||||||
strh PC_Reg, [r1]
|
strh PC_Reg, [r1]
|
||||||
CommonSaveCPUState
|
CommonSaveCPUState
|
||||||
ret
|
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||||
|
|
||||||
exit_reinit: ldr r1, SYM(cpu65__signal)
|
exit_reinit: ldr r1, SYM(cpu65__signal)
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
@ -2447,7 +2439,7 @@ exit_reinit: ldr r1, SYM(cpu65__signal)
|
|||||||
ldr r1, SYM(emul_reinitialize)
|
ldr r1, SYM(emul_reinitialize)
|
||||||
mov r0, #1
|
mov r0, #1
|
||||||
strb r0, [r1]
|
strb r0, [r1]
|
||||||
ret
|
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Debugger hooks
|
Debugger hooks
|
||||||
@ -2457,5 +2449,9 @@ ENTRY(cpu65_direct_write)
|
|||||||
#warning FIXME TODO implement cpu65_direct_write ...
|
#warning FIXME TODO implement cpu65_direct_write ...
|
||||||
mov r0, #42
|
mov r0, #42
|
||||||
ldr r0, [r0] // segfault
|
ldr r0, [r0] // segfault
|
||||||
ret
|
mov pc, lr
|
||||||
|
|
||||||
|
interrupt_vector: .hword 0xFFFE
|
||||||
|
reset_vector: .hword 0xFFFC
|
||||||
|
.ltorg
|
||||||
|
|
||||||
|
@ -16,49 +16,49 @@
|
|||||||
ENTRY(func) ldr r1, SYM(softswitches); \
|
ENTRY(func) ldr r1, SYM(softswitches); \
|
||||||
ldr r0, [r1]; \
|
ldr r0, [r1]; \
|
||||||
tst r0, $SS_CXROM; \
|
tst r0, $SS_CXROM; \
|
||||||
bne 1f; \
|
beq 1f; \
|
||||||
ldr r1, SYM(pointer); \
|
ldr r1, SYM(pointer); \
|
||||||
blx r1; \
|
ldr r1, [r1]; \
|
||||||
ret; \
|
|
||||||
1: ldr r1, SYM(pointer); \
|
|
||||||
ldrb r0, [r1, EffectiveAddr]; \
|
ldrb r0, [r1, EffectiveAddr]; \
|
||||||
ret;
|
mov pc, lr; \
|
||||||
|
1: ldr r1, SYM(pointer); \
|
||||||
|
push {lr}; \
|
||||||
|
blx r1; \
|
||||||
|
pop {pc}; \
|
||||||
|
|
||||||
#define GLUE_BANK_READ(func,pointer) \
|
#define GLUE_BANK_READ(func,pointer) \
|
||||||
ENTRY(func) ldr r1, SYM(pointer); \
|
ENTRY(func) ldr r1, SYM(pointer); \
|
||||||
|
ldr r1, [r1]; \
|
||||||
ldrb r0, [r1, EffectiveAddr]; \
|
ldrb r0, [r1, EffectiveAddr]; \
|
||||||
ret;
|
mov pc, lr;
|
||||||
|
|
||||||
#define GLUE_BANK_WRITE(func,pointer) \
|
#define GLUE_BANK_WRITE(func,pointer) \
|
||||||
ENTRY(func) ldr r1, SYM(pointer); \
|
ENTRY(func) ldr r1, SYM(pointer); \
|
||||||
|
ldr r1, [r1]; \
|
||||||
strb r0, [r1, EffectiveAddr]; \
|
strb r0, [r1, EffectiveAddr]; \
|
||||||
ret;
|
mov pc, lr;
|
||||||
|
|
||||||
#define GLUE_BANK_MAYBEWRITE(func,pointer) \
|
#define GLUE_BANK_MAYBEWRITE(func,pointer) \
|
||||||
ENTRY(func) ldr r1, SYM(pointer); \
|
ENTRY(func) ldr r1, SYM(pointer); \
|
||||||
cmp r1, #0; \
|
ldr r1, [r1]; \
|
||||||
beq 1f; \
|
tst r1, #0; \
|
||||||
strb r0, [r1, EffectiveAddr]; \
|
strneb r0, [r1, EffectiveAddr]; \
|
||||||
1: ret;
|
mov pc, lr;
|
||||||
|
|
||||||
|
|
||||||
#define GLUE_C_WRITE(func) \
|
#define GLUE_C_WRITE(func) \
|
||||||
ENTRY(func) push {r0, PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg}; \
|
ENTRY(func) push {r0, PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg, lr}; \
|
||||||
and r0, #0xff; \
|
and r0, #0xff; \
|
||||||
mov r1, r0; \
|
mov r1, r0; \
|
||||||
mov r0, EffectiveAddr; \
|
mov r0, EffectiveAddr; \
|
||||||
bl CALL(c_##func); \
|
bl CALL(c_##func); \
|
||||||
pop {r0, PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg}; \
|
pop {r0, PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg, pc};
|
||||||
ret;
|
|
||||||
|
|
||||||
#define _GLUE_C_READ(func, ...) \
|
#define GLUE_C_READ(func) \
|
||||||
ENTRY(func) push {PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg}; \
|
ENTRY(func) push {PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg, lr}; \
|
||||||
mov r0, EffectiveAddr; \
|
mov r0, EffectiveAddr; \
|
||||||
bl CALL(c_##func); \
|
bl CALL(c_##func); \
|
||||||
pop {PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg}; \
|
pop {PC_Reg, SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg, pc};
|
||||||
__VA_ARGS__ \
|
|
||||||
ret;
|
|
||||||
|
|
||||||
#define GLUE_C_READ(FUNC) _GLUE_C_READ(FUNC)
|
#define GLUE_C_READ_ALTZP(FUNC) GLUE_C_READ(FUNC)
|
||||||
#define GLUE_C_READ_ALTZP(FUNC) _GLUE_C_READ(FUNC)
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user