mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-27 08:31:03 +00:00
Fix x86 and x86_64 __PIC__ code for Linux and Mac
This commit is contained in:
parent
da4e5eb75a
commit
7b3eabb12f
@ -41,7 +41,7 @@ APPLE2_MAIN_SRC = \
|
|||||||
|
|
||||||
APPLE2_OPTIM_CFLAGS := -O2
|
APPLE2_OPTIM_CFLAGS := -O2
|
||||||
APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DINTERFACE_TOUCH=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -DDEBUGGER=1 -DAUDIO_ENABLED=1 -std=gnu11 -fPIC $(APPLE2_OPTIM_CFLAGS) -I$(APPLE2_SRC_PATH)
|
APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DINTERFACE_TOUCH=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -DDEBUGGER=1 -DAUDIO_ENABLED=1 -std=gnu11 -fPIC $(APPLE2_OPTIM_CFLAGS) -I$(APPLE2_SRC_PATH)
|
||||||
APPLE2_BASE_LDLIBS := -llog -landroid -lGLESv2 -lz -lOpenSLES -latomic
|
APPLE2_BASE_LDLIBS := -Wl,-z,text -Wl,-z,noexecstack -llog -landroid -lGLESv2 -lz -lOpenSLES -latomic
|
||||||
|
|
||||||
LOCAL_WHOLE_STATIC_LIBRARIES += cpufeatures
|
LOCAL_WHOLE_STATIC_LIBRARIES += cpufeatures
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ apple2ix_SOURCES = src/font.c src/rom.c src/misc.c src/display.c src/vm.c \
|
|||||||
|
|
||||||
apple2ix_CFLAGS = @AM_CFLAGS@ @X_CFLAGS@
|
apple2ix_CFLAGS = @AM_CFLAGS@ @X_CFLAGS@
|
||||||
apple2ix_CCASFLAGS = $(apple2ix_CFLAGS)
|
apple2ix_CCASFLAGS = $(apple2ix_CFLAGS)
|
||||||
apple2ix_LDFLAGS =
|
apple2ix_LDFLAGS = -Wl,-z,noexecstack
|
||||||
apple2ix_LDADD = @ASM_O@ @VIDEO_O@ @AUDIO_O@ @META_O@ @X_LIBS@
|
apple2ix_LDADD = @ASM_O@ @VIDEO_O@ @AUDIO_O@ @META_O@ @X_LIBS@
|
||||||
apple2ix_DEPENDENCIES = @ASM_O@ @VIDEO_O@ @AUDIO_O@ @META_O@
|
apple2ix_DEPENDENCIES = @ASM_O@ @VIDEO_O@ @AUDIO_O@ @META_O@
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
|
|
||||||
#define RestoreAltZP \
|
#define RestoreAltZP \
|
||||||
/* Apple //e set stack point to ALTZP (or not) */ \
|
/* Apple //e set stack point to ALTZP (or not) */ \
|
||||||
movLQ SYM(base_stackzp), _XAX; \
|
MEM2REG(movLQ, base_stackzp, _XAX); \
|
||||||
subLQ SYM(base_vmem), _XAX; \
|
MEM2REG(subLQ, base_vmem, _XAX); \
|
||||||
orLQ $0x0100, SP_Reg_X; \
|
orLQ $0x0100, SP_Reg_X; \
|
||||||
orLQ _XAX, SP_Reg_X;
|
orLQ _XAX, SP_Reg_X;
|
||||||
|
|
||||||
@ -84,6 +84,7 @@
|
|||||||
# define ROR_BIT 31
|
# define ROR_BIT 31
|
||||||
// x86 registers
|
// x86 registers
|
||||||
# define _XBP %ebp /* x86 base pointer */
|
# define _XBP %ebp /* x86 base pointer */
|
||||||
|
# define _PICREG %ebp /* used for accessing GOT */
|
||||||
# define _XSP %esp /* x86 stack pointer */
|
# define _XSP %esp /* x86 stack pointer */
|
||||||
# define _XDI %edi
|
# define _XDI %edi
|
||||||
# define _XSI %esi
|
# define _XSI %esi
|
||||||
@ -128,31 +129,83 @@
|
|||||||
|
|
||||||
#define ENTRY(x) .globl _UNDER(x); .balign 16; _UNDER(x)##:
|
#define ENTRY(x) .globl _UNDER(x); .balign 16; _UNDER(x)##:
|
||||||
|
|
||||||
#if __APPLE__
|
|
||||||
# define _AT_PLT()
|
|
||||||
# define _AT_GOTPCREL(x) (x)
|
|
||||||
#else
|
|
||||||
# define _AT_PLT() @PLT
|
|
||||||
# define _AT_GOTPCREL(x) @GOTPCREL(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !__PIC__
|
#if !__PIC__
|
||||||
# define CALL(x) _UNDER(x)
|
|
||||||
# define SYM(x) _UNDER(x)
|
// For non-Position Independent Code, the assembly is relatively simple...
|
||||||
# define SYMX_PROLOGUE(x)
|
|
||||||
# define SYMX(x, IDX, SCALE) _UNDER(x)(,IDX,SCALE)
|
# define CALL_FN(op,fn,stk) op _UNDER(fn)
|
||||||
|
# define JUMP_FN(op,fn) op _UNDER(fn)
|
||||||
|
# define CALL_IND0(sym) callLQ *_UNDER(sym)
|
||||||
|
# define CALL_IND(sym,off,sz) callLQ *_UNDER(sym)(,off,sz)
|
||||||
|
# define JUMP_IND(sym,off,sz) jmp *_UNDER(sym)(,off,sz)
|
||||||
|
# define MEM2REG_IND(op,sym,off,sz,x) op _UNDER(sym)(,off,sz), x
|
||||||
|
# define REG2MEM_IND(op,x,sym,off,sz) op x, _UNDER(sym)(,off,sz)
|
||||||
|
# define _2MEM(op,sym) op _UNDER(sym) // op to-memory
|
||||||
|
# define REG2MEM(op,x,sym) op x, _UNDER(sym) // op register-to-memory
|
||||||
|
# define MEM2REG(op,sym,x) op _UNDER(sym), x // op memory-to-register
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// For PIC code, the assembly is more convoluted, because we have to access symbols only indirectly through the Global
|
||||||
|
// Offset Table and the Procedure Linkage Table. There is some redundancy in the codegen from these macros (e.g.,
|
||||||
|
// access to the same symbol back-to-back results in duplicate register loads, when we could keep using the previously
|
||||||
|
// calculated value).
|
||||||
|
|
||||||
|
# if __APPLE__
|
||||||
|
# if !__LP64__
|
||||||
|
# error unsure of __PIC__ code on i386 Mac
|
||||||
|
# endif
|
||||||
|
# define _AT_PLT
|
||||||
|
# define _LEA(sym) leaq _UNDER(sym)(%rip), _X8
|
||||||
|
# define CALL_IND0(fn) callq *_UNDER(fn)(%rip)
|
||||||
|
# define _2MEM(op,sym) op _UNDER(sym)(%rip) // op to-memory
|
||||||
|
# define REG2MEM(op,x,sym) op x, _UNDER(sym)(%rip) // op register-to-memory
|
||||||
|
# define MEM2REG(op,sym,x) op _UNDER(sym)(%rip), x // op memory-to-register
|
||||||
|
# elif __LP64__
|
||||||
|
# define _AT_PLT @PLT
|
||||||
|
# define _LEA(sym) movq _UNDER(sym)@GOTPCREL(%rip), _X8
|
||||||
|
# define CALL_IND0(fn) callq *_UNDER(fn)_AT_PLT
|
||||||
|
# define _2MEM(op,sym) _LEA(sym); op (_X8) // op to-memory
|
||||||
|
# define REG2MEM(op,x,sym) _LEA(sym); op x, (_X8) // op register-to-memory
|
||||||
|
# define MEM2REG(op,sym,x) _LEA(sym); op (_X8), x // op memory-to-register
|
||||||
|
# endif
|
||||||
|
|
||||||
# if __LP64__
|
# if __LP64__
|
||||||
# define CALL(x) _UNDER(x)_AT_PLT()
|
# define CALL_FN(op,fn,stk) op _UNDER(fn)_AT_PLT
|
||||||
# define SYM(x) _UNDER(x)_AT_GOTPCREL(%rip)
|
# define JUMP_FN(op,fn) op _UNDER(fn)_AT_PLT
|
||||||
# define SYMX_PROLOGUE(x) leaLQ _UNDER(x)_AT_GOTPCREL(%rip), _X8;
|
# define CALL_IND(sym,off,sz) _LEA(sym); callq *(_X8,off,sz)
|
||||||
# define SYMX(x, IDX, SCALE) (_X8,IDX,SCALE)
|
# define JUMP_IND(sym,off,sz) _LEA(sym); jmp *(_X8,off,sz)
|
||||||
|
# define MEM2REG_IND(op,sym,off,sz,x) _LEA(sym); op (_X8,off,sz), x
|
||||||
|
# define REG2MEM_IND(op,x,sym,off,sz) _LEA(sym); op x, (_X8,off,sz)
|
||||||
# else
|
# else
|
||||||
# warning FIXME ... this is not PIC!
|
|
||||||
# define CALL(x) _UNDER(x)
|
# if !__i386__
|
||||||
# define SYM(x) _UNDER(x)
|
# error what architecture is this?!
|
||||||
# define SYMX_PROLOGUE(x)
|
# endif
|
||||||
# define SYMX(x, IDX, SCALE) _UNDER(x)(,IDX,SCALE)
|
|
||||||
|
// http://ewontfix.com/18/ -- "32-bit x86 Position Independent Code - It's that bad"
|
||||||
|
|
||||||
|
// 2016/05/01 : Strategy here is to (ab)use _PICREG in cpu65_run() to contain the offset to the GOT for symbol access.
|
||||||
|
// %ebx is used only for actual calls to the fn@PLT (per ABI convention). Similar to x64 PIC, use of these macros does
|
||||||
|
// result in some code duplication...
|
||||||
|
|
||||||
|
# define CALL_FN(op,fn,stk) movl stk(%esp), %ebx; \
|
||||||
|
op _UNDER(fn)@PLT;
|
||||||
|
|
||||||
|
# define _GOT_PRE(sym,reg) movl _A2_PIC_GOT(%esp), reg; \
|
||||||
|
movl _UNDER(sym)@GOT(reg), reg;
|
||||||
|
|
||||||
|
# define CALL_IND0(fn) _GOT_PRE(fn, _PICREG); calll *_PICREG;
|
||||||
|
|
||||||
|
# define CALL_IND(sym,off,sz) _GOT_PRE(sym,_PICREG); calll *(_PICREG,off,sz);
|
||||||
|
|
||||||
|
# define JUMP_FN(op,fn) op _UNDER(fn)
|
||||||
|
|
||||||
|
# define JUMP_IND(sym,off,sz) _GOT_PRE(sym,_PICREG); jmp *(_PICREG,off,sz);
|
||||||
|
# define MEM2REG_IND(op,sym,off,sz,x) _GOT_PRE(sym,_PICREG); op (_PICREG,off,sz), x;
|
||||||
|
# define REG2MEM_IND(op,x,sym,off,sz) _GOT_PRE(sym,_PICREG); op x, (_PICREG,off,sz);
|
||||||
|
# define _2MEM(op,sym) _GOT_PRE(sym,_PICREG); op (_PICREG); // op to-memory
|
||||||
|
# define REG2MEM(op,x,sym) _GOT_PRE(sym,_PICREG); op x, (_PICREG); // op register-to-memory
|
||||||
|
# define MEM2REG(op,sym,x) _GOT_PRE(sym,_PICREG); op (_PICREG), x; // op memory-to-register
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
223
src/x86/cpu.S
223
src/x86/cpu.S
@ -16,33 +16,48 @@
|
|||||||
#include "cpu-regs.h"
|
#include "cpu-regs.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
|
#if !__PIC__
|
||||||
|
# define SAVE_Y_REG() \
|
||||||
|
REG2MEM(movb, Y_Reg, cpu65_y)
|
||||||
|
# define _POP_PICREG()
|
||||||
|
#else
|
||||||
|
# define SAVE_Y_REG() \
|
||||||
|
movb Y_Reg, %al; \
|
||||||
|
REG2MEM(movb, %al, cpu65_y)
|
||||||
|
# if __i386__
|
||||||
|
# define _A2_PIC_GOT(reg) 0x0(reg) // Assumes GOT pointer is at head of stack
|
||||||
|
# define _POP_PICREG() popl _PICREG
|
||||||
|
# else
|
||||||
|
# define _POP_PICREG()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CommonSaveCPUState \
|
#define CommonSaveCPUState \
|
||||||
movw EffectiveAddr, SYM(cpu65_ea); \
|
REG2MEM(movw, EffectiveAddr, cpu65_ea); \
|
||||||
movb A_Reg, SYM(cpu65_a); \
|
REG2MEM(movb, A_Reg, cpu65_a); \
|
||||||
xorw %ax, %ax; \
|
xorw %ax, %ax; \
|
||||||
movb F_Reg, %al; \
|
movb F_Reg, %al; \
|
||||||
SYMX_PROLOGUE(cpu65_flags_encode); \
|
MEM2REG_IND(movb,cpu65_flags_encode,_XAX,1,%al); \
|
||||||
movb SYMX(cpu65_flags_encode,_XAX,1), %al; \
|
REG2MEM(movb, %al, cpu65_f); \
|
||||||
movb %al, SYM(cpu65_f); \
|
REG2MEM(movb, X_Reg, cpu65_x); \
|
||||||
movb X_Reg, SYM(cpu65_x); \
|
SAVE_Y_REG(); \
|
||||||
movb Y_Reg, SYM(cpu65_y); \
|
REG2MEM(movb, SP_Reg_L, cpu65_sp)
|
||||||
movb SP_Reg_L, SYM(cpu65_sp)
|
|
||||||
|
|
||||||
#if CPU_TRACING
|
#if CPU_TRACING
|
||||||
# define TRACE_PROLOGUE \
|
# define TRACE_PROLOGUE \
|
||||||
movw PC_Reg, SYM(cpu65_pc); \
|
REG2MEM(movw, PC_Reg, cpu65_pc); \
|
||||||
callLQ CALL(cpu65_trace_prologue);
|
CALL_FN(callLQ, cpu65_trace_prologue, 0x4);
|
||||||
# define TRACE_ARG \
|
# define TRACE_ARG \
|
||||||
callLQ CALL(cpu65_trace_arg);
|
CALL_FN(callLQ, cpu65_trace_arg, 0x4);
|
||||||
# define TRACE_ARG1 \
|
# define TRACE_ARG1 \
|
||||||
callLQ CALL(cpu65_trace_arg1);
|
CALL_FN(callLQ, cpu65_trace_arg1, 0x4);
|
||||||
# define TRACE_ARG2 \
|
# define TRACE_ARG2 \
|
||||||
callLQ CALL(cpu65_trace_arg2);
|
CALL_FN(callLQ, cpu65_trace_arg2, 0x4);
|
||||||
# define TRACE_EPILOGUE \
|
# define TRACE_EPILOGUE \
|
||||||
pushLQ _XAX; \
|
pushLQ _XAX; \
|
||||||
CommonSaveCPUState; \
|
CommonSaveCPUState; \
|
||||||
popLQ _XAX; \
|
popLQ _XAX; \
|
||||||
callLQ CALL(cpu65_trace_epilogue);
|
CALL_FN(callLQ, cpu65_trace_epilogue, 0x4);
|
||||||
#else
|
#else
|
||||||
# define TRACE_PROLOGUE
|
# define TRACE_PROLOGUE
|
||||||
# define TRACE_ARG
|
# define TRACE_ARG
|
||||||
@ -58,56 +73,47 @@
|
|||||||
#define GetFromPC_B \
|
#define GetFromPC_B \
|
||||||
movLQ PC_Reg_X, EffectiveAddr_X; \
|
movLQ PC_Reg_X, EffectiveAddr_X; \
|
||||||
incw PC_Reg; \
|
incw PC_Reg; \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
|
||||||
TRACE_ARG;
|
TRACE_ARG;
|
||||||
|
|
||||||
#define GetFromPC_W \
|
#define GetFromPC_W \
|
||||||
movLQ PC_Reg_X, EffectiveAddr_X; \
|
movLQ PC_Reg_X, EffectiveAddr_X; \
|
||||||
incw EffectiveAddr; \
|
incw EffectiveAddr; \
|
||||||
addw $2, PC_Reg; \
|
addw $2, PC_Reg; \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
|
||||||
decw EffectiveAddr; \
|
decw EffectiveAddr; \
|
||||||
TRACE_ARG2; \
|
TRACE_ARG2; \
|
||||||
movb %al, %ah; \
|
movb %al, %ah; \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
|
||||||
TRACE_ARG1;
|
TRACE_ARG1;
|
||||||
|
|
||||||
#define JumpNextInstruction \
|
#define JumpNextInstruction \
|
||||||
TRACE_PROLOGUE; \
|
TRACE_PROLOGUE; \
|
||||||
GetFromPC_B \
|
GetFromPC_B \
|
||||||
movb %al, SYM(cpu65_opcode); \
|
REG2MEM(movb, %al, cpu65_opcode); \
|
||||||
movb $0, SYM(cpu65_opcycles); \
|
REG2MEM(movb, $0, cpu65_opcycles); \
|
||||||
movb $0, SYM(cpu65_rw); \
|
REG2MEM(movb, $0, cpu65_rw); \
|
||||||
SYMX_PROLOGUE(cpu65__opcodes); \
|
JUMP_IND(cpu65__opcodes,_XAX,SZ_PTR);
|
||||||
jmp *SYMX(cpu65__opcodes,_XAX,SZ_PTR);
|
|
||||||
|
|
||||||
#define GetFromEA_B \
|
#define GetFromEA_B \
|
||||||
orb $1, SYM(cpu65_rw); \
|
REG2MEM(orb, $1, cpu65_rw); \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR);
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR);
|
|
||||||
|
|
||||||
#define GetFromEA_W \
|
#define GetFromEA_W \
|
||||||
incw EffectiveAddr; \
|
incw EffectiveAddr; \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
|
||||||
decw EffectiveAddr; \
|
decw EffectiveAddr; \
|
||||||
movb %al, %ah; \
|
movb %al, %ah; \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR);
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR);
|
|
||||||
|
|
||||||
#define PutToEA_B \
|
#define PutToEA_B \
|
||||||
orb $2, SYM(cpu65_rw); \
|
REG2MEM(orb, $2, cpu65_rw); \
|
||||||
movb %al, SYM(cpu65_d); \
|
REG2MEM(movb, %al, cpu65_d); \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_w); \
|
CALL_IND(cpu65_vmem_w,EffectiveAddr_X,SZ_PTR);
|
||||||
callLQ *SYMX(cpu65_vmem_w,EffectiveAddr_X,SZ_PTR);
|
|
||||||
|
|
||||||
#define GetFromMem_B(x) \
|
#define GetFromMem_B(x) \
|
||||||
movLQ x, EffectiveAddr_X; \
|
movLQ x, EffectiveAddr_X; \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR);
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR);
|
|
||||||
|
|
||||||
#define GetFromMem_W(x) \
|
#define GetFromMem_W(x) \
|
||||||
movLQ x, EffectiveAddr_X; \
|
movLQ x, EffectiveAddr_X; \
|
||||||
@ -117,7 +123,7 @@
|
|||||||
jmp continue;
|
jmp continue;
|
||||||
|
|
||||||
#define BranchXCycles \
|
#define BranchXCycles \
|
||||||
incb SYM(cpu65_opcycles); /* +1 branch taken */ \
|
_2MEM(incb, cpu65_opcycles); /* +1 branch taken */ \
|
||||||
shlLQ $16, _XBX; \
|
shlLQ $16, _XBX; \
|
||||||
movw PC_Reg, %bx; \
|
movw PC_Reg, %bx; \
|
||||||
cbw; \
|
cbw; \
|
||||||
@ -125,7 +131,7 @@
|
|||||||
movw %ax, PC_Reg; \
|
movw %ax, PC_Reg; \
|
||||||
cmpb %ah, %bh; \
|
cmpb %ah, %bh; \
|
||||||
je 9f; \
|
je 9f; \
|
||||||
incb SYM(cpu65_opcycles); /* +1 branch new page */ \
|
_2MEM(incb, cpu65_opcycles); /* +1 branch new page */ \
|
||||||
9: shrLQ $16, _XBX;
|
9: shrLQ $16, _XBX;
|
||||||
|
|
||||||
#define FlagC \
|
#define FlagC \
|
||||||
@ -174,14 +180,12 @@
|
|||||||
orb %al, F_Reg;
|
orb %al, F_Reg;
|
||||||
|
|
||||||
#define Push(x) \
|
#define Push(x) \
|
||||||
SYMX_PROLOGUE(apple_ii_64k); \
|
REG2MEM_IND(movb,x,apple_ii_64k,SP_Reg_X,1); \
|
||||||
movb x, SYMX(apple_ii_64k,SP_Reg_X,1); \
|
|
||||||
decb SP_Reg_L;
|
decb SP_Reg_L;
|
||||||
|
|
||||||
#define Pop(x) \
|
#define Pop(x) \
|
||||||
incb SP_Reg_L; \
|
incb SP_Reg_L; \
|
||||||
SYMX_PROLOGUE(apple_ii_64k); \
|
MEM2REG_IND(movb,apple_ii_64k,SP_Reg_X,1,x);
|
||||||
movb SYMX(apple_ii_64k,SP_Reg_X,1), x;
|
|
||||||
|
|
||||||
/* Immediate Addressing - the operand is contained in the second byte of the
|
/* Immediate Addressing - the operand is contained in the second byte of the
|
||||||
instruction. */
|
instruction. */
|
||||||
@ -191,8 +195,7 @@
|
|||||||
#if CPU_TRACING
|
#if CPU_TRACING
|
||||||
#define GetImm \
|
#define GetImm \
|
||||||
_GetImm \
|
_GetImm \
|
||||||
SYMX_PROLOGUE(cpu65_vmem_r); \
|
CALL_IND(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
||||||
callLQ *SYMX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
|
|
||||||
TRACE_ARG;
|
TRACE_ARG;
|
||||||
#else
|
#else
|
||||||
#define GetImm \
|
#define GetImm \
|
||||||
@ -237,7 +240,7 @@
|
|||||||
|
|
||||||
#define GetAbs_X \
|
#define GetAbs_X \
|
||||||
_GetAbs_X \
|
_GetAbs_X \
|
||||||
incb SYM(cpu65_opcycles); /* +1 cycle on page boundary */ \
|
_2MEM(incb, cpu65_opcycles); /* +1 cycle on page boundary */ \
|
||||||
9: movLQ _XAX, EffectiveAddr_X;
|
9: movLQ _XAX, EffectiveAddr_X;
|
||||||
|
|
||||||
#define GetAbs_X_STx \
|
#define GetAbs_X_STx \
|
||||||
@ -252,7 +255,7 @@
|
|||||||
|
|
||||||
#define GetAbs_Y \
|
#define GetAbs_Y \
|
||||||
_GetAbs_Y \
|
_GetAbs_Y \
|
||||||
incb SYM(cpu65_opcycles); /* +1 cycle on page boundary */ \
|
_2MEM(incb, cpu65_opcycles); /* +1 cycle on page boundary */ \
|
||||||
9: movLQ _XAX, EffectiveAddr_X;
|
9: movLQ _XAX, EffectiveAddr_X;
|
||||||
|
|
||||||
#define GetAbs_Y_STA \
|
#define GetAbs_Y_STA \
|
||||||
@ -315,7 +318,7 @@
|
|||||||
#define GetIndZPage_Y \
|
#define GetIndZPage_Y \
|
||||||
_GetIndZPage_Y \
|
_GetIndZPage_Y \
|
||||||
adcb $0, %ah; \
|
adcb $0, %ah; \
|
||||||
incb SYM(cpu65_opcycles); /* +1 cycle on page boundary */ \
|
_2MEM(incb, cpu65_opcycles); /* +1 cycle on page boundary */ \
|
||||||
9: movLQ _XAX, EffectiveAddr_X;
|
9: movLQ _XAX, EffectiveAddr_X;
|
||||||
|
|
||||||
#define GetIndZPage_Y_STA \
|
#define GetIndZPage_Y_STA \
|
||||||
@ -334,22 +337,22 @@
|
|||||||
jz 6f; \
|
jz 6f; \
|
||||||
testb $0x60, A_Reg; \
|
testb $0x60, A_Reg; \
|
||||||
jz 6f; \
|
jz 6f; \
|
||||||
callLQ CALL(debug_illegal_bcd); \
|
CALL_FN(callLQ, debug_illegal_bcd, 0x4); \
|
||||||
6: testb $0x08, A_Reg; \
|
6: testb $0x08, A_Reg; \
|
||||||
jz 7f; \
|
jz 7f; \
|
||||||
testb $0x06, A_Reg; \
|
testb $0x06, A_Reg; \
|
||||||
jz 7f; \
|
jz 7f; \
|
||||||
callLQ CALL(debug_illegal_bcd); \
|
CALL_FN(callLQ, debug_illegal_bcd, 0x4); \
|
||||||
7: testb $0x80, %al; \
|
7: testb $0x80, %al; \
|
||||||
jz 8f; \
|
jz 8f; \
|
||||||
testb $0x60, %al; \
|
testb $0x60, %al; \
|
||||||
jz 8f; \
|
jz 8f; \
|
||||||
callLQ CALL(debug_illegal_bcd); \
|
CALL_FN(callLQ, debug_illegal_bcd, 0x4); \
|
||||||
8: testb $0x08, %al; \
|
8: testb $0x08, %al; \
|
||||||
jz 9f; \
|
jz 9f; \
|
||||||
testb $0x06, %al; \
|
testb $0x06, %al; \
|
||||||
jz 9f; \
|
jz 9f; \
|
||||||
callLQ CALL(debug_illegal_bcd); \
|
CALL_FN(callLQ, debug_illegal_bcd, 0x4); \
|
||||||
9:
|
9:
|
||||||
#else
|
#else
|
||||||
#define DebugBCDCheck
|
#define DebugBCDCheck
|
||||||
@ -526,7 +529,7 @@
|
|||||||
|
|
||||||
// Decimal mode
|
// Decimal mode
|
||||||
ENTRY(op_ADC_dec)
|
ENTRY(op_ADC_dec)
|
||||||
incb SYM(cpu65_opcycles) // +1 cycle
|
_2MEM(incb, cpu65_opcycles) // +1 cycle
|
||||||
GetFromEA_B
|
GetFromEA_B
|
||||||
DebugBCDCheck
|
DebugBCDCheck
|
||||||
bt $C_Flag_Bit, AF_Reg_X
|
bt $C_Flag_Bit, AF_Reg_X
|
||||||
@ -579,7 +582,7 @@ _daa_finish: popq _XBX
|
|||||||
|
|
||||||
#define maybe_DoADC_d \
|
#define maybe_DoADC_d \
|
||||||
testb $D_Flag, F_Reg; /* Decimal mode? */ \
|
testb $D_Flag, F_Reg; /* Decimal mode? */ \
|
||||||
jnz CALL(op_ADC_dec) /* Yes, jump to decimal version */
|
JUMP_FN(jnz, op_ADC_dec) /* Yes, jump to decimal version */
|
||||||
|
|
||||||
ENTRY(op_ADC_imm) // 0x69
|
ENTRY(op_ADC_imm) // 0x69
|
||||||
GetImm
|
GetImm
|
||||||
@ -601,7 +604,7 @@ ENTRY(op_ADC_zpage_x) // 0x75
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_ADC_zpage_y)
|
ENTRY(op_ADC_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_ADC_abs) // 0x6d
|
ENTRY(op_ADC_abs) // 0x6d
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -662,7 +665,7 @@ ENTRY(op_AND_zpage_x) // 0x35
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_AND_zpage_y)
|
ENTRY(op_AND_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_AND_abs) // 0x2d
|
ENTRY(op_AND_abs) // 0x2d
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -931,8 +934,7 @@ ENTRY(op_BRK)
|
|||||||
orb $(B_Flag|X_Flag), F_Reg
|
orb $(B_Flag|X_Flag), F_Reg
|
||||||
xorw %ax, %ax
|
xorw %ax, %ax
|
||||||
movb F_Reg, %al
|
movb F_Reg, %al
|
||||||
SYMX_PROLOGUE(cpu65_flags_encode)
|
MEM2REG_IND(movb,cpu65_flags_encode,_XAX,1,%al)
|
||||||
movb SYMX(cpu65_flags_encode,_XAX,1), %al
|
|
||||||
Push(%al)
|
Push(%al)
|
||||||
orb $I_Flag, F_Reg
|
orb $I_Flag, F_Reg
|
||||||
movw $0xFFFE, EffectiveAddr // ROM interrupt vector
|
movw $0xFFFE, EffectiveAddr // ROM interrupt vector
|
||||||
@ -1020,7 +1022,7 @@ ENTRY(op_CMP_zpage_x) // 0xd5
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_CMP_zpage_y)
|
ENTRY(op_CMP_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_CMP_abs) // 0xcd
|
ENTRY(op_CMP_abs) // 0xcd
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -1165,7 +1167,7 @@ ENTRY(op_EOR_zpage_x) // 0x55
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_EOR_zpage_y)
|
ENTRY(op_EOR_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_EOR_abs) // 0x4d
|
ENTRY(op_EOR_abs) // 0x4d
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -1328,7 +1330,7 @@ ENTRY(op_LDA_zpage_x) // 0xb5
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_LDA_zpage_y)
|
ENTRY(op_LDA_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_LDA_abs) // 0xad
|
ENTRY(op_LDA_abs) // 0xad
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -1475,7 +1477,7 @@ ENTRY(op_ORA_zpage_x) // 0x15
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_ORA_zpage_y)
|
ENTRY(op_ORA_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_ORA_abs) // 0x0d
|
ENTRY(op_ORA_abs) // 0x0d
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -1522,8 +1524,7 @@ ENTRY(op_PHA) // 0x48
|
|||||||
|
|
||||||
ENTRY(op_PHP) // 0x08
|
ENTRY(op_PHP) // 0x08
|
||||||
movb F_Reg, %al
|
movb F_Reg, %al
|
||||||
SYMX_PROLOGUE(cpu65_flags_encode)
|
MEM2REG_IND(movb,cpu65_flags_encode,_XAX,1,%al)
|
||||||
movb SYMX(cpu65_flags_encode,_XAX,1), %al
|
|
||||||
Push(%al)
|
Push(%al)
|
||||||
Continue
|
Continue
|
||||||
|
|
||||||
@ -1566,12 +1567,11 @@ ENTRY(op_PLA) // 0x68
|
|||||||
|
|
||||||
ENTRY(op_PLP) // 0x28
|
ENTRY(op_PLP) // 0x28
|
||||||
Pop(%al)
|
Pop(%al)
|
||||||
SYMX_PROLOGUE(cpu65_flags_decode)
|
|
||||||
#if __PIC__
|
#if __PIC__
|
||||||
movb SYMX(cpu65_flags_decode,_XAX,1), %al
|
MEM2REG_IND(movb,cpu65_flags_decode,_XAX,1,%al)
|
||||||
movb %al, F_Reg
|
movb %al, F_Reg
|
||||||
#else
|
#else
|
||||||
movb SYMX(cpu65_flags_decode,_XAX,1), F_Reg
|
MEM2REG_IND(movb,cpu65_flags_decode,_XAX,1,F_Reg)
|
||||||
#endif
|
#endif
|
||||||
orb $(B_Flag|X_Flag), F_Reg
|
orb $(B_Flag|X_Flag), F_Reg
|
||||||
Continue
|
Continue
|
||||||
@ -1668,12 +1668,11 @@ ENTRY(op_ROR_abs_x) // 0x7e
|
|||||||
|
|
||||||
ENTRY(op_RTI) // 0x40
|
ENTRY(op_RTI) // 0x40
|
||||||
Pop(%al)
|
Pop(%al)
|
||||||
SYMX_PROLOGUE(cpu65_flags_decode)
|
|
||||||
#if __PIC__
|
#if __PIC__
|
||||||
movb SYMX(cpu65_flags_decode,_XAX,1), %al
|
MEM2REG_IND(movb,cpu65_flags_decode,_XAX,1,%al)
|
||||||
movb %al, F_Reg
|
movb %al, F_Reg
|
||||||
#else
|
#else
|
||||||
movb SYMX(cpu65_flags_decode,_XAX,1), F_Reg
|
MEM2REG_IND(movb,cpu65_flags_decode,_XAX,1,F_Reg)
|
||||||
#endif
|
#endif
|
||||||
orb $(B_Flag|X_Flag), F_Reg
|
orb $(B_Flag|X_Flag), F_Reg
|
||||||
Pop(%al)
|
Pop(%al)
|
||||||
@ -1710,7 +1709,7 @@ ENTRY(op_RTS) // 0x60
|
|||||||
---------------------------------- */
|
---------------------------------- */
|
||||||
|
|
||||||
ENTRY(op_SBC_dec)
|
ENTRY(op_SBC_dec)
|
||||||
incb SYM(cpu65_opcycles) // +1 cycle
|
_2MEM(incb, cpu65_opcycles) // +1 cycle
|
||||||
GetFromEA_B
|
GetFromEA_B
|
||||||
DebugBCDCheck
|
DebugBCDCheck
|
||||||
bt $C_Flag_Bit, AF_Reg_X
|
bt $C_Flag_Bit, AF_Reg_X
|
||||||
@ -1768,7 +1767,7 @@ _das_finish: popq _XBX
|
|||||||
|
|
||||||
#define maybe_DoSBC_d \
|
#define maybe_DoSBC_d \
|
||||||
testb $D_Flag, F_Reg; /* Decimal mode? */ \
|
testb $D_Flag, F_Reg; /* Decimal mode? */ \
|
||||||
jnz CALL(op_SBC_dec) /* Yes, jump to decimal version */
|
JUMP_FN(jnz, op_SBC_dec) /* Yes, jump to decimal version */
|
||||||
|
|
||||||
ENTRY(op_SBC_imm) // 0xe9
|
ENTRY(op_SBC_imm) // 0xe9
|
||||||
GetImm
|
GetImm
|
||||||
@ -1790,7 +1789,7 @@ ENTRY(op_SBC_zpage_x) // 0xf5
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_SBC_zpage_y)
|
ENTRY(op_SBC_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_SBC_abs) // 0xed
|
ENTRY(op_SBC_abs) // 0xed
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -1898,7 +1897,7 @@ ENTRY(op_STA_zpage_x) // 0x95
|
|||||||
|
|
||||||
// UNIMPLEMENTED : W65C02S datasheet
|
// UNIMPLEMENTED : W65C02S datasheet
|
||||||
ENTRY(op_STA_zpage_y)
|
ENTRY(op_STA_zpage_y)
|
||||||
jmp CALL(op_NOP)
|
JUMP_FN(jmp, op_NOP)
|
||||||
|
|
||||||
ENTRY(op_STA_abs) // 0x8d
|
ENTRY(op_STA_abs) // 0x8d
|
||||||
GetAbs
|
GetAbs
|
||||||
@ -2150,20 +2149,19 @@ ENTRY(op_WAI_65c02)
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
continue:
|
continue:
|
||||||
movzbLQ SYM(cpu65_opcode), _XAX
|
MEM2REG(movzbLQ, cpu65_opcode, _XAX)
|
||||||
SYMX_PROLOGUE(cpu65__opcycles)
|
MEM2REG_IND(movb,cpu65__opcycles,_XAX,1,%al)
|
||||||
movb SYMX(cpu65__opcycles,_XAX,1), %al
|
MEM2REG(addb, cpu65_opcycles, %al)
|
||||||
addb SYM(cpu65_opcycles), %al
|
REG2MEM(movb, %al, cpu65_opcycles)
|
||||||
movb %al, SYM(cpu65_opcycles)
|
|
||||||
TRACE_EPILOGUE
|
TRACE_EPILOGUE
|
||||||
addl %eax, SYM(cpu65_cycle_count)
|
REG2MEM(addl, %eax, cpu65_cycle_count)
|
||||||
subl %eax, SYM(gc_cycles_timer_0)
|
REG2MEM(subl, %eax, gc_cycles_timer_0)
|
||||||
subl %eax, SYM(gc_cycles_timer_1)
|
REG2MEM(subl, %eax, gc_cycles_timer_1)
|
||||||
subl %eax, SYM(cpu65_cycles_to_execute)
|
REG2MEM(subl, %eax, cpu65_cycles_to_execute)
|
||||||
jle exit_cpu65_run
|
jle exit_cpu65_run
|
||||||
|
|
||||||
continue1: xorLQ _XAX, _XAX
|
continue1: xorLQ _XAX, _XAX
|
||||||
orb SYM(cpu65__signal), %al
|
MEM2REG(orb, cpu65__signal, %al)
|
||||||
jnz exception
|
jnz exception
|
||||||
JumpNextInstruction
|
JumpNextInstruction
|
||||||
|
|
||||||
@ -2173,12 +2171,12 @@ continue1: xorLQ _XAX, _XAX
|
|||||||
|
|
||||||
exception: testb $ResetSig, %al
|
exception: testb $ResetSig, %al
|
||||||
jz ex_irq
|
jz ex_irq
|
||||||
testb $0xff, SYM(joy_button0) // OpenApple
|
REG2MEM(testb, $0xff, joy_button0) // OpenApple
|
||||||
jnz exit_reinit
|
jnz exit_reinit
|
||||||
testb $0xff, SYM(joy_button1) // ClosedApple
|
REG2MEM(testb, $0xff, joy_button1) // ClosedApple
|
||||||
jnz exit_reinit
|
jnz exit_reinit
|
||||||
|
|
||||||
ex_reset: movb $0, SYM(cpu65__signal)
|
ex_reset: REG2MEM(movb, $0, cpu65__signal)
|
||||||
movw $0xFFFC, EffectiveAddr // ROM reset vector
|
movw $0xFFFC, EffectiveAddr // ROM reset vector
|
||||||
GetFromEA_W
|
GetFromEA_W
|
||||||
movw %ax, PC_Reg
|
movw %ax, PC_Reg
|
||||||
@ -2200,8 +2198,7 @@ ex_irq: testb $I_Flag, F_Reg // Already interrupt
|
|||||||
orb $X_Flag, F_Reg
|
orb $X_Flag, F_Reg
|
||||||
xorw %ax, %ax
|
xorw %ax, %ax
|
||||||
movb F_Reg, %al
|
movb F_Reg, %al
|
||||||
SYMX_PROLOGUE(cpu65_flags_encode)
|
MEM2REG_IND(movb,cpu65_flags_encode,_XAX,1,%al)
|
||||||
movb SYMX(cpu65_flags_encode,_XAX,1), %al
|
|
||||||
Push(%al)
|
Push(%al)
|
||||||
orb $(B_Flag | I_Flag), F_Reg
|
orb $(B_Flag | I_Flag), F_Reg
|
||||||
//andb $~D_Flag, F_Reg // AppleWin clears Decimal bit?
|
//andb $~D_Flag, F_Reg // AppleWin clears Decimal bit?
|
||||||
@ -2221,34 +2218,43 @@ ENTRY(cpu65_run)
|
|||||||
pushLQ _XDI
|
pushLQ _XDI
|
||||||
pushLQ _XSI
|
pushLQ _XSI
|
||||||
pushLQ _XBX
|
pushLQ _XBX
|
||||||
#ifdef __LP64__
|
#if __LP64__
|
||||||
// NOTE: should we be also preserving r12-r15?
|
// NOTE: should we be also preserving r12-r15?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __PIC__ && __i386__
|
||||||
|
calll .Lget_pc_thunk0
|
||||||
|
.Lget_pc_thunk0:
|
||||||
|
_POP_PICREG()
|
||||||
|
.Lget_pc_thunk1:
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_+(.Lget_pc_thunk1 - .Lget_pc_thunk0), _PICREG
|
||||||
|
pushl _PICREG
|
||||||
|
#endif
|
||||||
|
|
||||||
// Restore CPU state when being called from C.
|
// Restore CPU state when being called from C.
|
||||||
movzwLQ SYM(cpu65_ea), EffectiveAddr_X
|
MEM2REG(movzwLQ, cpu65_ea, EffectiveAddr_X)
|
||||||
movzwLQ SYM(cpu65_pc), PC_Reg_X
|
MEM2REG(movzwLQ, cpu65_pc, PC_Reg_X)
|
||||||
movzbLQ SYM(cpu65_a), AF_Reg_X
|
MEM2REG(movzbLQ, cpu65_a, AF_Reg_X)
|
||||||
movzbLQ SYM(cpu65_f), _XAX
|
MEM2REG(movzbLQ, cpu65_x, XY_Reg_X)
|
||||||
SYMX_PROLOGUE(cpu65_flags_decode)
|
MEM2REG(movzbLQ, cpu65_f, _XAX)
|
||||||
#if __PIC__
|
#if __PIC__
|
||||||
movb SYMX(cpu65_flags_decode,_XAX,1), %al
|
MEM2REG_IND(movb,cpu65_flags_decode,_XAX,1,%al)
|
||||||
movb %al, F_Reg
|
movb %al, F_Reg
|
||||||
|
MEM2REG(movb, cpu65_y, %al)
|
||||||
|
movb %al, Y_Reg
|
||||||
#else
|
#else
|
||||||
movb SYMX(cpu65_flags_decode,_XAX,1), F_Reg
|
MEM2REG_IND(movb,cpu65_flags_decode,_XAX,1,F_Reg)
|
||||||
|
MEM2REG(movb, cpu65_y, Y_Reg)
|
||||||
#endif
|
#endif
|
||||||
movzbLQ SYM(cpu65_x), XY_Reg_X
|
MEM2REG(movzbLQ, cpu65_sp, SP_Reg_X)
|
||||||
movb SYM(cpu65_y), Y_Reg
|
|
||||||
movzbLQ SYM(cpu65_sp), SP_Reg_X
|
|
||||||
#ifdef APPLE2_VM
|
#ifdef APPLE2_VM
|
||||||
RestoreAltZP
|
RestoreAltZP
|
||||||
#endif
|
#endif
|
||||||
cmpb $0, SYM(emul_reinitialize)
|
REG2MEM(cmpb, $0, emul_reinitialize)
|
||||||
jnz enter_reinit
|
jnz enter_reinit
|
||||||
jmp continue1
|
jmp continue1
|
||||||
|
|
||||||
enter_reinit: movb $0, SYM(emul_reinitialize)
|
enter_reinit: REG2MEM(movb, $0, emul_reinitialize)
|
||||||
jmp ex_reset
|
jmp ex_reset
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
@ -2257,16 +2263,18 @@ enter_reinit: movb $0, SYM(emul_reinitialize)
|
|||||||
|
|
||||||
exit_cpu65_run:
|
exit_cpu65_run:
|
||||||
// Save CPU state when returning from being called from C
|
// Save CPU state when returning from being called from C
|
||||||
movw PC_Reg, SYM(cpu65_pc)
|
REG2MEM(movw, PC_Reg, cpu65_pc)
|
||||||
CommonSaveCPUState
|
CommonSaveCPUState
|
||||||
|
_POP_PICREG()
|
||||||
popLQ _XBX
|
popLQ _XBX
|
||||||
popLQ _XSI
|
popLQ _XSI
|
||||||
popLQ _XDI
|
popLQ _XDI
|
||||||
popLQ _XBP
|
popLQ _XBP
|
||||||
ret
|
ret
|
||||||
|
|
||||||
exit_reinit: movb $0, SYM(cpu65__signal)
|
exit_reinit: REG2MEM(movb, $0, cpu65__signal)
|
||||||
movb $1, SYM(emul_reinitialize)
|
REG2MEM(movb, $1, emul_reinitialize)
|
||||||
|
_POP_PICREG()
|
||||||
popLQ _XBX
|
popLQ _XBX
|
||||||
popLQ _XSI
|
popLQ _XSI
|
||||||
popLQ _XDI
|
popLQ _XDI
|
||||||
@ -2281,8 +2289,7 @@ ENTRY(cpu65_direct_write)
|
|||||||
pushLQ EffectiveAddr_X
|
pushLQ EffectiveAddr_X
|
||||||
movLQ 8(_XSP),EffectiveAddr_X
|
movLQ 8(_XSP),EffectiveAddr_X
|
||||||
movLQ 12(_XSP),_XAX
|
movLQ 12(_XSP),_XAX
|
||||||
SYMX_PROLOGUE(cpu65_vmem_w)
|
CALL_IND(cpu65_vmem_w,EffectiveAddr_X,SZ_PTR)
|
||||||
callLQ *SYMX(cpu65_vmem_w,EffectiveAddr_X,SZ_PTR)
|
|
||||||
popLQ EffectiveAddr_X
|
popLQ EffectiveAddr_X
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -16,36 +16,46 @@
|
|||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "cpu-regs.h"
|
#include "cpu-regs.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These "glue" macros code become auto-generated trampoline functions for the exclusive use of cpu65_run() CPU module
|
||||||
|
* to make calls back into C that conform with the x86 and x86_64 calling ABIs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if __PIC__ && __i386__
|
||||||
|
# define _A2_PIC_GOT(reg) 0x4(reg) // Stack offset assumes a CALL has been made that pushed %eip
|
||||||
|
#endif
|
||||||
|
#define _PUSH_COUNT ((/*args:*/7+/*ret:*/1) * SZ_PTR)
|
||||||
|
|
||||||
#define GLUE_EXTERN_C_READ(func)
|
#define GLUE_EXTERN_C_READ(func)
|
||||||
|
|
||||||
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
||||||
ENTRY(func) testLQ $SS_CXROM, SYM(softswitches); \
|
ENTRY(func) REG2MEM(testLQ, $SS_CXROM, softswitches); \
|
||||||
jnz 1f; \
|
jnz 1f; \
|
||||||
callLQ *SYM(pointer); \
|
CALL_IND0(pointer); \
|
||||||
ret; \
|
ret; \
|
||||||
1: addLQ SYM(pointer),EffectiveAddr_X; \
|
1: MEM2REG(addLQ, pointer, EffectiveAddr_X); \
|
||||||
movb (EffectiveAddr_X),%al; \
|
movb (EffectiveAddr_X),%al; \
|
||||||
subLQ SYM(pointer),EffectiveAddr_X; \
|
MEM2REG(subLQ, pointer, EffectiveAddr_X); \
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
#define GLUE_BANK_READ(func,pointer) \
|
#define GLUE_BANK_READ(func,pointer) \
|
||||||
ENTRY(func) addLQ SYM(pointer),EffectiveAddr_X; \
|
ENTRY(func) MEM2REG(addLQ, pointer, EffectiveAddr_X); \
|
||||||
movb (EffectiveAddr_X),%al; \
|
movb (EffectiveAddr_X),%al; \
|
||||||
subLQ SYM(pointer),EffectiveAddr_X; \
|
MEM2REG(subLQ, pointer, EffectiveAddr_X); \
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
#define GLUE_BANK_WRITE(func,pointer) \
|
#define GLUE_BANK_WRITE(func,pointer) \
|
||||||
ENTRY(func) addLQ SYM(pointer),EffectiveAddr_X; \
|
ENTRY(func) MEM2REG(addLQ, pointer, EffectiveAddr_X); \
|
||||||
movb %al,(EffectiveAddr_X); \
|
movb %al,(EffectiveAddr_X); \
|
||||||
subLQ SYM(pointer),EffectiveAddr_X; \
|
MEM2REG(subLQ, pointer, EffectiveAddr_X); \
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
#define GLUE_BANK_MAYBEWRITE(func,pointer) \
|
#define GLUE_BANK_MAYBEWRITE(func,pointer) \
|
||||||
ENTRY(func) addLQ SYM(pointer),EffectiveAddr_X; \
|
ENTRY(func) MEM2REG(addLQ, pointer, EffectiveAddr_X); \
|
||||||
cmpl $0,SYM(pointer); \
|
REG2MEM(cmpl, $0, pointer); \
|
||||||
jz 1f; \
|
jz 1f; \
|
||||||
movb %al,(EffectiveAddr_X); \
|
movb %al,(EffectiveAddr_X); \
|
||||||
1: subLQ SYM(pointer),EffectiveAddr_X; \
|
1: MEM2REG(subLQ, pointer, EffectiveAddr_X); \
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +78,7 @@ ENTRY(func) pushLQ _XAX; \
|
|||||||
pushLQ PC_Reg_X; \
|
pushLQ PC_Reg_X; \
|
||||||
andLQ $0xff,_XAX; \
|
andLQ $0xff,_XAX; \
|
||||||
_PUSH_ARGS \
|
_PUSH_ARGS \
|
||||||
callLQ CALL(c_##func); \
|
CALL_FN(callLQ, c_##func, _PUSH_COUNT); \
|
||||||
_POP_ARGS \
|
_POP_ARGS \
|
||||||
popLQ PC_Reg_X; \
|
popLQ PC_Reg_X; \
|
||||||
popLQ SP_Reg_X; \
|
popLQ SP_Reg_X; \
|
||||||
@ -77,6 +87,15 @@ ENTRY(func) pushLQ _XAX; \
|
|||||||
popLQ _XAX; \
|
popLQ _XAX; \
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
|
#if __PIC__ && __i386__
|
||||||
|
# define _PUSH_GOT() movl _A2_PIC_GOT(%esp), _PICREG; \
|
||||||
|
pushl _PICREG;
|
||||||
|
# define _POP_GOT() addl $4, %esp
|
||||||
|
#else
|
||||||
|
# define _PUSH_GOT()
|
||||||
|
# define _POP_GOT()
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO FIXME : implement CDECL prologue/epilogues...
|
// TODO FIXME : implement CDECL prologue/epilogues...
|
||||||
#define _GLUE_C_READ(func, ...) \
|
#define _GLUE_C_READ(func, ...) \
|
||||||
ENTRY(func) pushLQ XY_Reg_X; \
|
ENTRY(func) pushLQ XY_Reg_X; \
|
||||||
@ -85,7 +104,7 @@ ENTRY(func) pushLQ XY_Reg_X; \
|
|||||||
pushLQ PC_Reg_X; \
|
pushLQ PC_Reg_X; \
|
||||||
pushLQ _XAX; /* HACK: works around mysterious issue with generated mov(_XAX), _XAX ... */ \
|
pushLQ _XAX; /* HACK: works around mysterious issue with generated mov(_XAX), _XAX ... */ \
|
||||||
pushLQ EffectiveAddr_X; /* ea is arg0 (and preserved) */ \
|
pushLQ EffectiveAddr_X; /* ea is arg0 (and preserved) */ \
|
||||||
callLQ CALL(c_##func); \
|
CALL_FN(callLQ, c_##func, _PUSH_COUNT); \
|
||||||
popLQ EffectiveAddr_X; /* restore ea */ \
|
popLQ EffectiveAddr_X; /* restore ea */ \
|
||||||
movb %al, %dl; \
|
movb %al, %dl; \
|
||||||
popLQ _XAX; /* ... ugh */ \
|
popLQ _XAX; /* ... ugh */ \
|
||||||
@ -94,7 +113,9 @@ ENTRY(func) pushLQ XY_Reg_X; \
|
|||||||
popLQ SP_Reg_X; \
|
popLQ SP_Reg_X; \
|
||||||
popLQ AF_Reg_X; \
|
popLQ AF_Reg_X; \
|
||||||
popLQ XY_Reg_X; \
|
popLQ XY_Reg_X; \
|
||||||
|
_PUSH_GOT(); \
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
|
_POP_GOT(); \
|
||||||
ret;
|
ret;
|
||||||
|
|
||||||
// TODO FIXME : implement CDECL prologue/epilogues...
|
// TODO FIXME : implement CDECL prologue/epilogues...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user