mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-11-19 11:31:13 +00:00
First cut at 65c02 implemented on aarch64
This commit is contained in:
parent
4e27c1a322
commit
43d99ec9f4
@ -1,4 +1,4 @@
|
||||
APP_ABI := armeabi-v7a x86 x86_64
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
|
||||
|
||||
# Do not change APP_PLATFORM if we care about Gingerbread (2.3.3) devices! We must compile against android-10,
|
||||
# otherwise we may encounter runtime load-library errors from symbols that should have been inlined against older
|
||||
|
@ -148,7 +148,7 @@ if test "x$do_build" = "x1" -o "x$do_release" = "x1" ; then
|
||||
# Symbolicate and move symbols file into location to be deployed on device
|
||||
|
||||
SYMFILE=libapple2ix.so.sym
|
||||
ARCHES_TO_SYMBOLICATE='armeabi-v7a x86 x86_64'
|
||||
ARCHES_TO_SYMBOLICATE='armeabi-v7a arm64-v8a x86 x86_64'
|
||||
|
||||
for arch in $ARCHES_TO_SYMBOLICATE ; do
|
||||
SYMDIR=../assets/symbols/$arch/libapple2ix.so
|
||||
|
@ -63,7 +63,7 @@ APPLE2_MAIN_SRC = \
|
||||
$(APPLE2_SRC_PATH)/zlib-helpers.c \
|
||||
$(APPLE2_SRC_PATH)/../externals/jsmn/jsmn.c
|
||||
|
||||
APPLE2_OPTIM_CFLAGS := -Os
|
||||
APPLE2_OPTIM_CFLAGS := -O2 # match the same optimization level as BUILD_MODE=release for ndk-build
|
||||
APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DINTERFACE_TOUCH=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -std=gnu11 -fPIC $(APPLE2_OPTIM_CFLAGS) -I$(APPLE2_SRC_PATH)
|
||||
APPLE2_BASE_LDLIBS := -Wl,-z,text -Wl,-z,noexecstack -llog -landroid -lGLESv2 -lz -lOpenSLES -latomic
|
||||
|
||||
|
@ -15,45 +15,107 @@
|
||||
#include "cpu.h"
|
||||
#include "glue-offsets.h"
|
||||
|
||||
// ARM register mappings
|
||||
|
||||
// r0, r1 are scratch regs, with r0 generally as the "important byte"
|
||||
#define EffectiveAddr r2 /* 16bit Effective address */
|
||||
#define PC_Reg r3 /* 16bit 6502 Program Counter */
|
||||
#define SP_Reg r4 /* 16bit 6502 Stack pointer */
|
||||
#define F_Reg r5 /* 8bit 6502 flags */
|
||||
#define Y_Reg r6 /* 8bit 6502 Y register */
|
||||
#define X_Reg r7 /* 8bit 6502 X register */
|
||||
#define A_Reg r8 /* 8bit 6502 A register */
|
||||
// r9 is "ARM platform register" ... used as a scratch register
|
||||
#define reg_args r10 /* cpu65_run() args register */
|
||||
#define reg_vmem_r r11 /* cpu65_vmem_r table address */
|
||||
// r12 is "ARM Intra-Procedure-call scratch register" ... used as a scratch register
|
||||
// r13 ARM SP
|
||||
// r14 ARM return addr
|
||||
// r15 ARM PC
|
||||
|
||||
#ifdef __aarch64__
|
||||
# error 20150205 ARM 64bit untested!!!
|
||||
# define PTR_SHIFT #4 // 4<<1 = 8
|
||||
# define ROR_BIT 0x8000000000000000
|
||||
#else
|
||||
# define PTR_SHIFT #2 // 2<<1 = 4
|
||||
# define ROR_BIT 0x80000000
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
# define NO_UNDERSCORES 1
|
||||
# define STRBNE strneb
|
||||
#endif
|
||||
|
||||
// ARM register mappings
|
||||
|
||||
#define bz beq
|
||||
#define bnz bne
|
||||
|
||||
#define ROR_BIT 0x80000000
|
||||
|
||||
#ifdef __aarch64__
|
||||
|
||||
# define DOT_ARM
|
||||
# define ALIGN .align 2;
|
||||
# define PTR_SHIFT #3 // 1<<3 = 8
|
||||
# define BLX blr
|
||||
# define BX br
|
||||
|
||||
// x: 64bit addressing mode
|
||||
// w: 32bit addressing mode
|
||||
|
||||
# define xr0 x0 /* scratch/"important byte" */
|
||||
# define wr0 w0 /* scratch/"important byte" */
|
||||
# define xr1 x1 /* scratch */
|
||||
# define wr1 w1 /* scratch */
|
||||
|
||||
# define wr9 w2
|
||||
|
||||
// NOTE: ARMv8 Procedure Call Standard indicates that x19-x28 are callee saved ... so we can call back into C without needing to
|
||||
// first save these ...
|
||||
# define xEffectiveAddr x19 /* 16bit Effective address */
|
||||
# define EffectiveAddr w19 /* 16bit Effective address */
|
||||
# define PC_Reg w20 /* 16bit 6502 Program Counter */
|
||||
# define xSP_Reg x21 /* 16bit 6502 Stack pointer */
|
||||
# define SP_Reg w21 /* 16bit 6502 Stack pointer */
|
||||
# define xF_Reg x22 /* 8bit 6502 flags */
|
||||
# define F_Reg w22 /* 8bit 6502 flags */
|
||||
# define Y_Reg w23 /* 8bit 6502 Y register */
|
||||
# define X_Reg w24 /* 8bit 6502 X register */
|
||||
# define A_Reg w25 /* 8bit 6502 A register */
|
||||
# define xA_Reg x25 /* 8bit 6502 A register */
|
||||
# define reg_args x26 /* cpu65_run() args register */
|
||||
# define reg_vmem_r x27 /* cpu65_vmem_r table address */
|
||||
|
||||
# define xr12 x28 /* scratch */
|
||||
# define wr12 w28 /* scratch */
|
||||
// x29 : frame pointer (callee-saved)
|
||||
// x30 : return address
|
||||
// xzr/wzr : zero register
|
||||
// sp : stack pointer
|
||||
// pc : instruction pointer
|
||||
|
||||
#else
|
||||
# define STRBNE strbne
|
||||
|
||||
# define DOT_ARM .arm;
|
||||
# define ALIGN .balign 4;
|
||||
# define PTR_SHIFT #2 // 1<<2 = 4
|
||||
# define BLX blx
|
||||
# define BX bx
|
||||
|
||||
// r0, r1 are scratch regs, with r0 generally as the "important byte"
|
||||
# define xr0 r0 /* scratch/"important byte" */
|
||||
# define wr0 r0 /* scratch/"important byte" */
|
||||
# define xr1 r1 /* scratch */
|
||||
# define wr1 r1 /* scratch */
|
||||
# define wr9 r9 /* scratch */
|
||||
// r12 is "ARM Intra-Procedure-call scratch register" ... used as a scratch register
|
||||
# define xr12 r12 /* scratch */
|
||||
# define wr12 r12 /* scratch */
|
||||
|
||||
// NOTE: these need to be preserved in subroutine (C) invocations ... */
|
||||
# define EffectiveAddr r2 /* 16bit Effective address */
|
||||
# define xEffectiveAddr r2 /* 16bit Effective address */
|
||||
# define PC_Reg r3 /* 16bit 6502 Program Counter */
|
||||
|
||||
// NOTE: ARMv7 PCS states : "A subroutine must preserve the contents of the registers r4-r8, r10, r11 and SP [...]"
|
||||
# define xSP_Reg r4 /* 16bit 6502 Stack pointer */
|
||||
# define SP_Reg r4 /* 16bit 6502 Stack pointer */
|
||||
# define xF_Reg r5 /* 8bit 6502 flags */
|
||||
# define F_Reg r5 /* 8bit 6502 flags */
|
||||
# define Y_Reg r6 /* 8bit 6502 Y register */
|
||||
# define X_Reg r7 /* 8bit 6502 X register */
|
||||
# define A_Reg r8 /* 8bit 6502 A register */
|
||||
# define xA_Reg r8 /* 8bit 6502 A register */
|
||||
|
||||
// r9 is "ARM platform register" ... used as a scratch register
|
||||
# define reg_args r10 /* cpu65_run() args register */
|
||||
# define reg_vmem_r r11 /* cpu65_vmem_r table address */
|
||||
// r13 ARM SP
|
||||
// r14 ARM LR (return addr)
|
||||
// r15 ARM PC
|
||||
|
||||
#endif
|
||||
|
||||
#if NO_UNDERSCORES
|
||||
# define ENTRY(x) .globl x; .arm; .balign 4; x##:
|
||||
# define ENTRY(x) .global x; DOT_ARM ALIGN x##:
|
||||
# define CALL(x) x
|
||||
#else
|
||||
# define ENTRY(x) .globl _##x; .arm; .balign 4; _##x##:
|
||||
# define ENTRY(x) .global _##x; DOT_ARM ALIGN _##x##:
|
||||
# define CALL(x) _##x
|
||||
#endif
|
||||
|
||||
|
1072
src/arm/cpu.S
1072
src/arm/cpu.S
File diff suppressed because it is too large
Load Diff
53
src/arm/glue-offsets64.h
Normal file
53
src/arm/glue-offsets64.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* This file is auto-generated for a specific architecture ABI */
|
||||
#define UNUSED0 0
|
||||
#define CPU65_TRACE_PROLOGUE 8
|
||||
#define CPU65_TRACE_ARG 16
|
||||
#define UNUSED1 24
|
||||
#define UNUSED2 32
|
||||
#define CPU65_TRACE_EPILOGUE 40
|
||||
#define CPU65_TRACE_IRQ 48
|
||||
#define DEBUG_ILLEGAL_BCD 56
|
||||
#define CPU65_VMEM_R 64
|
||||
#define CPU65_VMEM_W 72
|
||||
#define CPU65_FLAGS_ENCODE 80
|
||||
#define CPU65_FLAGS_DECODE 88
|
||||
#define CPU65__OPCODES 96
|
||||
#define CPU65__OPCYCLES 104
|
||||
#define BASE_RAMRD 112
|
||||
#define BASE_RAMWRT 120
|
||||
#define BASE_TEXTRD 128
|
||||
#define BASE_TEXTWRT 136
|
||||
#define BASE_HGRRD 144
|
||||
#define BASE_HGRWRT 152
|
||||
#define BASE_STACKZP 160
|
||||
#define BASE_D000_RD 168
|
||||
#define BASE_E000_RD 176
|
||||
#define BASE_D000_WRT 184
|
||||
#define BASE_E000_WRT 192
|
||||
#define BASE_C3ROM 200
|
||||
#define BASE_C4ROM 208
|
||||
#define BASE_C5ROM 216
|
||||
#define BASE_CXROM 224
|
||||
#define SOFTSWITCHES 232
|
||||
#define GC_CYCLES_TIMER_0 236
|
||||
#define GC_CYCLES_TIMER_1 240
|
||||
#define CPU65_CYCLES_TO_EXECUTE 244
|
||||
#define CPU65_CYCLE_COUNT 248
|
||||
#define UNUSED3 252
|
||||
#define INTERRUPT_VECTOR 256
|
||||
#define RESET_VECTOR 258
|
||||
#define CPU65_PC 260
|
||||
#define CPU65_EA 262
|
||||
#define CPU65_A 264
|
||||
#define CPU65_F 265
|
||||
#define CPU65_X 266
|
||||
#define CPU65_Y 267
|
||||
#define CPU65_SP 268
|
||||
#define CPU65_D 269
|
||||
#define CPU65_RW 270
|
||||
#define CPU65_OPCODE 271
|
||||
#define CPU65_OPCYCLES 272
|
||||
#define CPU65__SIGNAL 273
|
||||
#define JOY_BUTTON0 274
|
||||
#define JOY_BUTTON1 275
|
||||
#define EMUL_REINITIALIZE 276
|
@ -12,79 +12,120 @@
|
||||
#include "vm.h"
|
||||
#include "cpu-regs.h"
|
||||
|
||||
#if __aarch64__
|
||||
|
||||
# define _GLUE_REG_SAVE \
|
||||
stp x29, x30, [sp, -16]!;
|
||||
|
||||
# define _GLUE_REG_RESTORE \
|
||||
ldp x29, x30, [sp], 16; \
|
||||
ret
|
||||
|
||||
# define _GLUE_REG_SAVE0 \
|
||||
stp x0, x30, [sp, -16]!;
|
||||
|
||||
# define _GLUE_REG_RESTORE0 \
|
||||
ldp x0, x30, [sp], 16; \
|
||||
ret
|
||||
|
||||
# define _GLUE_RET \
|
||||
ret
|
||||
|
||||
#else
|
||||
|
||||
# define _GLUE_REG_SAVE \
|
||||
push {EffectiveAddr, PC_Reg, lr};
|
||||
|
||||
# define _GLUE_REG_RESTORE \
|
||||
pop {EffectiveAddr, PC_Reg, pc};
|
||||
|
||||
# define _GLUE_REG_SAVE0 \
|
||||
push {r0, EffectiveAddr, PC_Reg, lr};
|
||||
|
||||
# define _GLUE_REG_RESTORE0 \
|
||||
pop {r0, EffectiveAddr, PC_Reg, pc};
|
||||
|
||||
# define _GLUE_RET \
|
||||
mov pc, lr;
|
||||
|
||||
#endif
|
||||
|
||||
#define GLUE_EXTERN_C_READ(func)
|
||||
|
||||
#define _GLUE_BANK_MAYBE_READ_CX(func,x,pointer) \
|
||||
ENTRY(func) ldr r0, [reg_args, #SOFTSWITCHES]; \
|
||||
ldr r1, [reg_args, x ## pointer]; \
|
||||
tst r0, $SS_CXROM; \
|
||||
bne 1f; \
|
||||
push {EffectiveAddr, PC_Reg, lr}; \
|
||||
blx r1; \
|
||||
pop {EffectiveAddr, PC_Reg, pc}; \
|
||||
1: ldrb r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
ENTRY(func) ldr wr0, [reg_args, #SOFTSWITCHES]; \
|
||||
ldr xr1, [reg_args, x ## pointer]; \
|
||||
tst wr0, #SS_CXROM; \
|
||||
bnz 1f; \
|
||||
_GLUE_REG_SAVE; \
|
||||
BLX xr1; \
|
||||
_GLUE_REG_RESTORE; \
|
||||
1: ldrb wr0, [xr1, xEffectiveAddr]; \
|
||||
_GLUE_RET
|
||||
|
||||
#define GLUE_BANK_MAYBE_READ_CX(func,pointer) _GLUE_BANK_MAYBE_READ_CX(func,#,pointer)
|
||||
|
||||
|
||||
#define _GLUE_BANK_MAYBE_READ_C3(func,x,pointer) \
|
||||
ENTRY(func) ldr r0, [reg_args, #SOFTSWITCHES]; \
|
||||
ldr r1, [reg_args, x ## pointer]; \
|
||||
tst r0, $SS_CXROM; \
|
||||
bne 1f; \
|
||||
tst r0, $SS_C3ROM; \
|
||||
bne 1f; \
|
||||
push {EffectiveAddr, PC_Reg, lr}; \
|
||||
blx r1; \
|
||||
pop {EffectiveAddr, PC_Reg, pc}; \
|
||||
1: ldrb r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
ENTRY(func) ldr wr0, [reg_args, #SOFTSWITCHES]; \
|
||||
ldr xr1, [reg_args, x ## pointer]; \
|
||||
tst wr0, #SS_CXROM; \
|
||||
bnz 1f; \
|
||||
tst wr0, #SS_C3ROM; \
|
||||
bnz 1f; \
|
||||
_GLUE_REG_SAVE; \
|
||||
BLX xr1; \
|
||||
_GLUE_REG_RESTORE; \
|
||||
1: ldrb wr0, [xr1, xEffectiveAddr]; \
|
||||
_GLUE_RET
|
||||
#define GLUE_BANK_MAYBE_READ_C3(func,pointer) _GLUE_BANK_MAYBE_READ_C3(func,#,pointer)
|
||||
|
||||
|
||||
#define _GLUE_BANK_READ(func,x,pointer) \
|
||||
ENTRY(func) ldr r1, [reg_args, x ## pointer]; \
|
||||
ldrb r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
ENTRY(func) ldr xr1, [reg_args, x ## pointer]; \
|
||||
ldrb wr0, [xr1, xEffectiveAddr]; \
|
||||
_GLUE_RET
|
||||
#define GLUE_BANK_READ(func,pointer) _GLUE_BANK_READ(func,#,pointer)
|
||||
|
||||
|
||||
#define _GLUE_BANK_WRITE(func,x,pointer) \
|
||||
ENTRY(func) ldr r1, [reg_args, x ## pointer]; \
|
||||
strb r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
ENTRY(func) ldr xr1, [reg_args, x ## pointer]; \
|
||||
strb wr0, [xr1, xEffectiveAddr]; \
|
||||
_GLUE_RET
|
||||
#define GLUE_BANK_WRITE(func,pointer) _GLUE_BANK_WRITE(func,#,pointer)
|
||||
|
||||
|
||||
#define _GLUE_BANK_MAYBEWRITE(func,x,pointer) \
|
||||
ENTRY(func) ldr r1, [reg_args, x ## pointer]; \
|
||||
teq r1, #0; \
|
||||
STRBNE r0, [r1, EffectiveAddr]; \
|
||||
mov pc, lr;
|
||||
ENTRY(func) ldr xr1, [reg_args, x ## pointer]; \
|
||||
eor xr12, xr12, xr12; \
|
||||
eor xr1, xr1, xr12; \
|
||||
cmp xr1, #0; \
|
||||
bz 1f; \
|
||||
strb wr0, [xr1, xEffectiveAddr]; \
|
||||
1: _GLUE_RET
|
||||
#define GLUE_BANK_MAYBEWRITE(func,pointer) _GLUE_BANK_MAYBEWRITE(func,#,pointer)
|
||||
|
||||
|
||||
#define _GLUE_INLINE_READ(func,x,off) \
|
||||
ENTRY(func) ldrb r0, [reg_args, x ## off]; \
|
||||
mov pc, lr;
|
||||
ENTRY(func) ldrb wr0, [reg_args, x ## off]; \
|
||||
_GLUE_RET
|
||||
#define GLUE_INLINE_READ(func,off) _GLUE_INLINE_READ(func,#,off)
|
||||
|
||||
|
||||
#define GLUE_C_WRITE(func) \
|
||||
ENTRY(func) push {r0, EffectiveAddr, PC_Reg, lr}; \
|
||||
and r0, r0, #0xff; \
|
||||
mov r1, r0; \
|
||||
mov r0, EffectiveAddr; \
|
||||
ENTRY(func) _GLUE_REG_SAVE0; \
|
||||
and wr0, wr0, #0xff; \
|
||||
mov wr1, wr0; \
|
||||
mov wr0, EffectiveAddr; \
|
||||
bl CALL(c_##func); \
|
||||
pop {r0, EffectiveAddr, PC_Reg, pc};
|
||||
_GLUE_REG_RESTORE0;
|
||||
|
||||
|
||||
#define GLUE_C_READ(func) \
|
||||
ENTRY(func) push {EffectiveAddr, PC_Reg, lr}; \
|
||||
mov r0, EffectiveAddr; \
|
||||
ENTRY(func) _GLUE_REG_SAVE; \
|
||||
mov wr0, EffectiveAddr; \
|
||||
bl CALL(c_##func); \
|
||||
pop {EffectiveAddr, PC_Reg, pc};
|
||||
_GLUE_REG_RESTORE;
|
||||
|
||||
|
||||
#define GLUE_C_READ_ALTZP(FUNC) GLUE_C_READ(FUNC)
|
||||
|
@ -87,7 +87,7 @@ void cpu65_trace_checkpoint(void);
|
||||
# define D_Flag 0x20 /* 6502 Decimal mode */
|
||||
# define Z_Flag 0x40 /* 6502 Zero */
|
||||
# define N_Flag 0x80 /* 6502 Negative */
|
||||
#elif defined(__arm__)
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
// VCZN positions match positions of shifted status register
|
||||
# define V_Flag 0x1
|
||||
# define C_Flag 0x2
|
||||
@ -101,10 +101,7 @@ void cpu65_trace_checkpoint(void);
|
||||
# define I_Flag 0x20
|
||||
# define B_Flag 0x40
|
||||
# define D_Flag 0x80
|
||||
# define BX_Flags 0x50
|
||||
# define BI_Flags 0x60
|
||||
#elif defined(__aarch64__)
|
||||
# error soon ...
|
||||
#else
|
||||
# error unknown machine architecture
|
||||
#endif
|
||||
|
@ -186,7 +186,7 @@ typedef struct cpu65_run_args_s {
|
||||
#define OUTPUT_CPU65_RW() printf("#define CPU65_RW %ld\n", offsetof(cpu65_run_args_s, cpu65_rw))
|
||||
uint8_t cpu65_opcode; // Last opcode
|
||||
#define OUTPUT_CPU65_OPCODE() printf("#define CPU65_OPCODE %ld\n", offsetof(cpu65_run_args_s, cpu65_opcode))
|
||||
uint8_t cpu65_opcycles; // Last opcode extra cycles
|
||||
uint8_t cpu65_opcycles; // Last opcode cycles
|
||||
#define OUTPUT_CPU65_OPCYCLES() printf("#define CPU65_OPCYCLES %ld\n", offsetof(cpu65_run_args_s, cpu65_opcycles))
|
||||
|
||||
uint8_t cpu65__signal;
|
||||
|
Loading…
Reference in New Issue
Block a user