updated Cyclone not to use r9

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@417 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-04-09 19:48:28 +00:00
parent 651b1a25c2
commit 449ecf9257
8 changed files with 304 additions and 280 deletions

View file

@ -29,7 +29,7 @@ struct Cyclone
unsigned int osp; // [r7,#0x48] Other Stack Pointer (USP/SSP) unsigned int osp; // [r7,#0x48] Other Stack Pointer (USP/SSP)
unsigned int xc; // [r7,#0x4c] Extend flag (bit29: ??X? _) unsigned int xc; // [r7,#0x4c] Extend flag (bit29: ??X? _)
unsigned int prev_pc; // [r7,#0x50] Set to start address of currently executed opcode + 2 (if enabled in config.h) unsigned int prev_pc; // [r7,#0x50] Set to start address of currently executed opcode + 2 (if enabled in config.h)
unsigned int reserved;// [r7,#0x54] Reserved for possible future use unsigned int jumptab; // [r7,#0x54] Jump table pointer
int state_flags; // [r7,#0x58] bit: 0: stopped state, 1: trace state, 2: activity bit, 3: addr error, 4: fatal halt int state_flags; // [r7,#0x58] bit: 0: stopped state, 1: trace state, 2: activity bit, 3: addr error, 4: fatal halt
int cycles; // [r7,#0x5c] Number of cycles to execute - 1. Updates to cycles left after CycloneRun() int cycles; // [r7,#0x5c] Number of cycles to execute - 1. Updates to cycles left after CycloneRun()
int membase; // [r7,#0x60] Memory Base (ARM address minus 68000 address) int membase; // [r7,#0x60] Memory Base (ARM address minus 68000 address)

View file

@ -456,11 +456,12 @@ See source code for up to date of register usage, however a summary is here:
r6 : Pointer to Opcode Jump table r6 : Pointer to Opcode Jump table
r7 : Pointer to Cpu Context r7 : Pointer to Cpu Context
r8 : Current Opcode r8 : Current Opcode
r9 : Flags (NZCV) in highest four bits r10 : Flags (NZCV) in highest four bits
(r10 : Temporary source value or Memory Base)
(r11 : Temporary register) (r11 : Temporary register)
Flags are mapped onto ARM flags whenever possible, which speeds up the processing of opcode. Flags are mapped onto ARM flags whenever possible, which speeds up the processing of opcode.
r9 is not used intentionally, because AAPCS defines it as "platform register", so it's
reserved in some systems.
Thanks to... Thanks to...
@ -476,6 +477,10 @@ Thanks to...
What's New What's New
---------- ----------
v0.0099 notaz
* Cyclone no longer uses r9, because AAPCS defines it as "platform register",
so it's reserved in some systems.
v0.0088 notaz v0.0088 notaz
- Reduced amount of code in opcode handlers by ~23% by doing the following: - Reduced amount of code in opcode handlers by ~23% by doing the following:
- Removed duplicate opcode handlers - Removed duplicate opcode handlers

View file

@ -3,7 +3,7 @@
static FILE *AsmFile=NULL; static FILE *AsmFile=NULL;
static int CycloneVer=0x0088; // Version number of library static int CycloneVer=0x0099; // Version number of library
int *CyJump=NULL; // Jump table int *CyJump=NULL; // Jump table
int ms=USE_MS_SYNTAX; // If non-zero, output in Microsoft ARMASM format int ms=USE_MS_SYNTAX; // If non-zero, output in Microsoft ARMASM format
char *Narm[4]={ "b", "h","",""}; // Normal ARM Extensions for operand sizes 0,1,2 char *Narm[4]={ "b", "h","",""}; // Normal ARM Extensions for operand sizes 0,1,2
@ -87,10 +87,10 @@ static void AddressErrorWrapper(char rw, char *dataprg, int iw)
{ {
ot("ExceptionAddressError_%c_%s%s\n", rw, dataprg, ms?"":":"); ot("ExceptionAddressError_%c_%s%s\n", rw, dataprg, ms?"":":");
ot(" ldr r1,[r7,#0x44]\n"); ot(" ldr r1,[r7,#0x44]\n");
ot(" mov r10,#0x%02x\n", iw); ot(" mov r6,#0x%02x\n", iw);
ot(" mov r11,r0\n"); ot(" mov r11,r0\n");
ot(" tst r1,#0x20\n"); ot(" tst r1,#0x20\n");
ot(" orrne r10,r10,#4\n"); ot(" orrne r6,r6,#4\n");
ot(" b ExceptionAddressError\n"); ot(" b ExceptionAddressError\n");
ot("\n"); ot("\n");
} }
@ -119,18 +119,19 @@ static void PrintFramework()
if (ms) ot("CycloneRun\n"); if (ms) ot("CycloneRun\n");
else ot("CycloneRun:\n"); else ot("CycloneRun:\n");
ot(" stmdb sp!,{r4-r11,lr}\n"); ot(" stmdb sp!,{r4-r8,r10,r11,lr}\n");
ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n"); ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n");
ot(" ;@ r0-3 = Temporary registers\n"); ot(" ;@ r0-3 = Temporary registers\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Flags (NZCV)\n");
ot(" ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n"); ot(" ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n");
ot(" ldr r5,[r7,#0x5c] ;@ r5 = Cycles\n"); ot(" ldr r5,[r7,#0x5c] ;@ r5 = Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n"); ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n");
ot(" ;@ r8 = Current Opcode\n"); ot(" ;@ r8 = Current Opcode\n");
ot(" ldr r1,[r7,#0x44] ;@ Get SR high T_S__III and irq level\n"); ot(" ldr r1,[r7,#0x44] ;@ Get SR high T_S__III and irq level\n");
ot(" mov r9,r9,lsl #28 ;@ r9 = Flags 0xf0000000, cpsr format\n"); ot(" mov r10,r10,lsl #28;@ r10 = Flags 0xf0000000, cpsr format\n");
ot(" ;@ r10 = Source value / Memory Base\n"); ot(" ;@ r11 = Source value / Memory Base\n");
ot(" str r6,[r7,#0x54] ;@ make a copy to avoid literal pools\n");
ot("\n"); ot("\n");
#if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE #if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE
ot(" mov r2,#0\n"); ot(" mov r2,#0\n");
@ -160,7 +161,7 @@ static void PrintFramework()
ot(";@ stopped or halted\n"); ot(";@ stopped or halted\n");
ot(" mov r5,#0\n"); ot(" mov r5,#0\n");
ot(" str r5,[r7,#0x5C] ;@ eat all cycles\n"); ot(" str r5,[r7,#0x5C] ;@ eat all cycles\n");
ot(" ldmia sp!,{r4-r11,pc} ;@ we are stopped, do nothing!\n"); ot(" ldmia sp!,{r4-r8,r10,r11,pc} ;@ we are stopped, do nothing!\n");
ot("\n"); ot("\n");
ot("\n"); ot("\n");
@ -170,16 +171,16 @@ static void PrintFramework()
ot("CycloneEndNoBack%s\n", ms?"":":"); ot("CycloneEndNoBack%s\n", ms?"":":");
#if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE #if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE
ot(" ldr r1,[r7,#0x98]\n"); ot(" ldr r1,[r7,#0x98]\n");
ot(" mov r9,r9,lsr #28\n"); ot(" mov r10,r10,lsr #28\n");
ot(" tst r1,r1\n"); ot(" tst r1,r1\n");
ot(" bxne r1 ;@ jump to alternative CycloneEnd\n"); ot(" bxne r1 ;@ jump to alternative CycloneEnd\n");
#else #else
ot(" mov r9,r9,lsr #28\n"); ot(" mov r10,r10,lsr #28\n");
#endif #endif
ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n"); ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r10,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" ldmia sp!,{r4-r11,pc}\n"); ot(" ldmia sp!,{r4-r8,r10,r11,pc}\n");
ltorg(); ltorg();
ot("\n"); ot("\n");
ot("\n"); ot("\n");
@ -360,22 +361,22 @@ static void PrintFramework()
ot(" movle r0,#0\n"); ot(" movle r0,#0\n");
ot(" bxle lr ;@ no ints\n"); ot(" bxle lr ;@ no ints\n");
ot("\n"); ot("\n");
ot(" stmdb sp!,{r4,r5,r7-r11,lr}\n"); ot(" stmdb sp!,{r4,r5,r7,r8,r10,r11,lr}\n");
ot(" mov r7,r0\n"); ot(" mov r7,r0\n");
ot(" mov r0,r2\n"); ot(" mov r0,r2\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Flags (NZCV)\n");
ot(" mov r5,#0\n"); ot(" mov r5,#0\n");
ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n"); ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n");
ot(" mov r9,r9,lsl #28 ;@ r9 = Flags 0xf0000000, cpsr format\n"); ot(" mov r10,r10,lsl #28 ;@ r10 = Flags 0xf0000000, cpsr format\n");
ot(" adr r2,CycloneFlushIrqEnd\n"); ot(" adr r2,CycloneFlushIrqEnd\n");
ot(" str r2,[r7,#0x98] ;@ set custom CycloneEnd\n"); ot(" str r2,[r7,#0x98] ;@ set custom CycloneEnd\n");
ot(" b CycloneDoInterrupt\n"); ot(" b CycloneDoInterrupt\n");
ot("\n"); ot("\n");
ot("CycloneFlushIrqEnd%s\n", ms?"":":"); ot("CycloneFlushIrqEnd%s\n", ms?"":":");
ot(" rsb r0,r5,#0\n"); ot(" rsb r0,r5,#0\n");
ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n"); ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n");
ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r10,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" ldmia sp!,{r4,r5,r7-r11,lr}\n"); ot(" ldmia sp!,{r4,r5,r7,r8,r10,r11,lr}\n");
ot(" bx lr\n"); ot(" bx lr\n");
ot("\n"); ot("\n");
ot("\n"); ot("\n");
@ -418,14 +419,14 @@ static void PrintFramework()
ot(" orr r2,r2,#4 ;@ set activity bit: 'not processing instruction'\n"); ot(" orr r2,r2,#4 ;@ set activity bit: 'not processing instruction'\n");
#endif #endif
ot(" str r2,[r7,#0x58]\n"); ot(" str r2,[r7,#0x58]\n");
ot(" ldrb r10,[r7,#0x44] ;@ Get old SR high\n"); ot(" ldrb r6,[r7,#0x44] ;@ Get old SR high, abuse r6\n");
ot(" strb r3,[r7,#0x44] ;@ Put new SR high\n"); ot(" strb r3,[r7,#0x44] ;@ Put new SR high\n");
ot("\n"); ot("\n");
// 3. Save the current processor context. // 3. Save the current processor context.
ot(" ldr r1,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r1,[r7,#0x60] ;@ Get Memory base\n");
ot(" ldr r11,[r7,#0x3c] ;@ Get A7\n"); ot(" ldr r11,[r7,#0x3c] ;@ Get A7\n");
ot(" tst r10,#0x20\n"); ot(" tst r6,#0x20\n");
ot(";@ get our SP:\n"); ot(";@ get our SP:\n");
ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n"); ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n");
ot(" streq r11,[r7,#0x48]\n"); ot(" streq r11,[r7,#0x48]\n");
@ -436,13 +437,13 @@ static void PrintFramework()
MemHandler(1,2); MemHandler(1,2);
ot(";@ Push old SR:\n"); ot(";@ Push old SR:\n");
ot(" ldr r0,[r7,#0x4c] ;@ X bit\n"); ot(" ldr r0,[r7,#0x4c] ;@ X bit\n");
ot(" mov r1,r9,lsr #28 ;@ ____NZCV\n"); ot(" mov r1,r10,lsr #28 ;@ ____NZCV\n");
ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n"); ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n");
ot(" tst r2,#1 ;@ 1 if C!=V\n"); ot(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n"); ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
ot(" and r0,r0,#0x20000000\n"); ot(" and r0,r0,#0x20000000\n");
ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\n"); ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\n");
ot(" orr r1,r1,r10,lsl #8 ;@ Include old SR high\n"); ot(" orr r1,r1,r6,lsl #8 ;@ Include old SR high\n");
ot(" sub r0,r11,#6 ;@ Predecrement A7\n"); ot(" sub r0,r11,#6 ;@ Predecrement A7\n");
ot(" str r0,[r7,#0x3c] ;@ Save A7\n"); ot(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0); // already checked for address error by prev MemHandler MemHandler(1,1,0,0); // already checked for address error by prev MemHandler
@ -455,7 +456,7 @@ static void PrintFramework()
ot(";@ call IrqCallback if it is defined\n"); ot(";@ call IrqCallback if it is defined\n");
#if INT_ACK_NEEDS_STUFF #if INT_ACK_NEEDS_STUFF
ot(" str r4,[r7,#0x40] ;@ Save PC\n"); ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n"); ot(" mov r1,r10,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
#endif #endif
@ -481,7 +482,7 @@ static void PrintFramework()
#endif #endif
ot(" mov r0,r0,lsl #2 ;@ get vector address\n"); ot(" mov r0,r0,lsl #2 ;@ get vector address\n");
ot("\n"); ot("\n");
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r11,[r7,#0x60] ;@ Get Memory base\n");
ot(";@ Read IRQ Vector:\n"); ot(";@ Read IRQ Vector:\n");
MemHandler(0,2,0,0); MemHandler(0,2,0,0);
ot(" tst r0,r0 ;@ uninitialized int vector?\n"); ot(" tst r0,r0 ;@ uninitialized int vector?\n");
@ -490,7 +491,7 @@ static void PrintFramework()
ot(" ldreq pc,[r7,#0x70] ;@ Call read32(r0) handler\n"); ot(" ldreq pc,[r7,#0x70] ;@ Call read32(r0) handler\n");
#if USE_CHECKPC_CALLBACK #if USE_CHECKPC_CALLBACK
ot(" add lr,pc,#4\n"); ot(" add lr,pc,#4\n");
ot(" add r0,r0,r10 ;@ r0 = Memory Base + New PC\n"); ot(" add r0,r0,r11 ;@ r0 = Memory Base + New PC\n");
ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n"); ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n");
#if EMULATE_ADDRESS_ERRORS_JUMP #if EMULATE_ADDRESS_ERRORS_JUMP
ot(" mov r4,r0\n"); ot(" mov r4,r0\n");
@ -498,7 +499,7 @@ static void PrintFramework()
ot(" bic r4,r0,#1\n"); ot(" bic r4,r0,#1\n");
#endif #endif
#else #else
ot(" add r4,r0,r10 ;@ r4 = Memory Base + New PC\n"); ot(" add r4,r0,r11 ;@ r4 = Memory Base + New PC\n");
#if EMULATE_ADDRESS_ERRORS_JUMP #if EMULATE_ADDRESS_ERRORS_JUMP
ot(" bic r4,r4,#1\n"); ot(" bic r4,r4,#1\n");
#endif #endif
@ -511,6 +512,7 @@ static void PrintFramework()
ot(" tst r4,#1\n"); ot(" tst r4,#1\n");
ot(" bne ExceptionAddressError_r_prg_r4\n"); ot(" bne ExceptionAddressError_r_prg_r4\n");
#endif #endif
ot(" ldr r6,[r7,#0x54]\n");
ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n"); ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n");
ot(" subs r5,r5,#44 ;@ Subtract cycles\n"); ot(" subs r5,r5,#44 ;@ Subtract cycles\n");
ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n");
@ -526,9 +528,9 @@ static void PrintFramework()
ot(" orr r8,r8,r0,lsl #24 ;@ abuse r8\n"); ot(" orr r8,r8,r0,lsl #24 ;@ abuse r8\n");
// 1. Make a temporary copy of the status register and set the status register for exception processing. // 1. Make a temporary copy of the status register and set the status register for exception processing.
ot(" ldr r10,[r7,#0x44] ;@ Get old SR high\n"); ot(" ldr r6,[r7,#0x44] ;@ Get old SR high, abuse r6\n");
ot(" ldr r2,[r7,#0x58] ;@ state flags\n"); ot(" ldr r2,[r7,#0x58] ;@ state flags\n");
ot(" and r3,r10,#0x27 ;@ clear trace and unused flags\n"); ot(" and r3,r6,#0x27 ;@ clear trace and unused flags\n");
ot(" orr r3,r3,#0x20 ;@ set supervisor mode\n"); ot(" orr r3,r3,#0x20 ;@ set supervisor mode\n");
ot(" bic r2,r2,#3 ;@ clear stopped and trace states\n"); ot(" bic r2,r2,#3 ;@ clear stopped and trace states\n");
ot(" str r2,[r7,#0x58]\n"); ot(" str r2,[r7,#0x58]\n");
@ -537,7 +539,7 @@ static void PrintFramework()
// 3. Save the current processor context. // 3. Save the current processor context.
ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n"); ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n");
ot(" tst r10,#0x20\n"); ot(" tst r6,#0x20\n");
ot(";@ get our SP:\n"); ot(";@ get our SP:\n");
ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n"); ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n");
ot(" streq r0,[r7,#0x48]\n"); ot(" streq r0,[r7,#0x48]\n");
@ -550,14 +552,14 @@ static void PrintFramework()
MemHandler(1,2); MemHandler(1,2);
ot(";@ Push old SR:\n"); ot(";@ Push old SR:\n");
ot(" ldr r0,[r7,#0x4c] ;@ X bit\n"); ot(" ldr r0,[r7,#0x4c] ;@ X bit\n");
ot(" mov r1,r9,lsr #28 ;@ ____NZCV\n"); ot(" mov r1,r10,lsr #28 ;@ ____NZCV\n");
ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n"); ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n");
ot(" tst r2,#1 ;@ 1 if C!=V\n"); ot(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n"); ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
ot(" and r0,r0,#0x20000000\n"); ot(" and r0,r0,#0x20000000\n");
ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\n"); ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\n");
ot(" ldr r0,[r7,#0x3c] ;@ A7\n"); ot(" ldr r0,[r7,#0x3c] ;@ A7\n");
ot(" orr r1,r1,r10,lsl #8 ;@ Include SR high\n"); ot(" orr r1,r1,r6,lsl #8 ;@ Include SR high\n");
ot(" sub r0,r0,#2 ;@ Predecrement A7\n"); ot(" sub r0,r0,#2 ;@ Predecrement A7\n");
ot(" str r0,[r7,#0x3c] ;@ Save A7\n"); ot(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0); MemHandler(1,1,0,0);
@ -591,6 +593,7 @@ static void PrintFramework()
ot(" tst r4,#1\n"); ot(" tst r4,#1\n");
ot(" bne ExceptionAddressError_r_prg_r4\n"); ot(" bne ExceptionAddressError_r_prg_r4\n");
#endif #endif
ot(" ldr r6,[r7,#0x54]\n");
ot(" bx r11 ;@ Return\n"); ot(" bx r11 ;@ Return\n");
ot("\n"); ot("\n");
@ -606,14 +609,14 @@ static void PrintFramework()
ot("ExceptionAddressError_r_prg_r4%s\n", ms?"":":"); ot("ExceptionAddressError_r_prg_r4%s\n", ms?"":":");
ot(" ldr r1,[r7,#0x44]\n"); ot(" ldr r1,[r7,#0x44]\n");
ot(" ldr r3,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r3,[r7,#0x60] ;@ Get Memory base\n");
ot(" mov r10,#0x12\n"); ot(" mov r6,#0x12\n");
ot(" sub r11,r4,r3\n"); ot(" sub r11,r4,r3\n");
ot(" tst r1,#0x20\n"); ot(" tst r1,#0x20\n");
ot(" orrne r10,r10,#4\n"); ot(" orrne r6,r6,#4\n");
ot("\n"); ot("\n");
ot("ExceptionAddressError%s\n", ms?"":":"); ot("ExceptionAddressError%s\n", ms?"":":");
ot(";@ r10 - info word (without instruction/not bit), r11 - faulting address\n"); ot(";@ r6 - info word (without instruction/not bit), r11 - faulting address\n");
// 1. Make a temporary copy of the status register and set the status register for exception processing. // 1. Make a temporary copy of the status register and set the status register for exception processing.
ot(" ldrb r0,[r7,#0x44] ;@ Get old SR high\n"); ot(" ldrb r0,[r7,#0x44] ;@ Get old SR high\n");
@ -623,7 +626,7 @@ static void PrintFramework()
ot(" strb r3,[r7,#0x44] ;@ Put new SR high\n"); ot(" strb r3,[r7,#0x44] ;@ Put new SR high\n");
ot(" bic r2,r2,#3 ;@ clear stopped and trace states\n"); ot(" bic r2,r2,#3 ;@ clear stopped and trace states\n");
ot(" tst r2,#4\n"); ot(" tst r2,#4\n");
ot(" orrne r10,r10,#8 ;@ complete info word\n"); ot(" orrne r6,r6,#8 ;@ complete info word\n");
ot(" orr r2,r2,#4 ;@ set activity bit: 'not processing instruction'\n"); ot(" orr r2,r2,#4 ;@ set activity bit: 'not processing instruction'\n");
#if EMULATE_HALT #if EMULATE_HALT
ot(" tst r2,#8\n"); ot(" tst r2,#8\n");
@ -635,13 +638,13 @@ static void PrintFramework()
#else #else
ot(" str r2,[r7,#0x58]\n"); ot(" str r2,[r7,#0x58]\n");
#endif #endif
ot(" and r9,r9,#0xf0000000\n"); ot(" and r10,r10,#0xf0000000\n");
ot(" orr r9,r9,r0,lsl #4 ;@ some preparations for SR push\n"); ot(" orr r10,r10,r0,lsl #4 ;@ some preparations for SR push\n");
ot("\n"); ot("\n");
// 3. Save the current processor context + additional information. // 3. Save the current processor context + additional information.
ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n"); ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n");
ot(" tst r9,#0x200\n"); ot(" tst r10,#0x200\n");
ot(";@ get our SP:\n"); ot(";@ get our SP:\n");
ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n"); ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n");
ot(" streq r0,[r7,#0x48]\n"); ot(" streq r0,[r7,#0x48]\n");
@ -656,14 +659,14 @@ static void PrintFramework()
// SR // SR
ot(";@ Push old SR:\n"); ot(";@ Push old SR:\n");
ot(" ldr r0,[r7,#0x4c] ;@ X bit\n"); ot(" ldr r0,[r7,#0x4c] ;@ X bit\n");
ot(" mov r1,r9,ror #28 ;@ ____NZCV\n"); ot(" mov r1,r10,ror #28 ;@ ____NZCV\n");
ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n"); ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n");
ot(" tst r2,#1 ;@ 1 if C!=V\n"); ot(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n"); ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
ot(" and r0,r0,#0x20000000\n"); ot(" and r0,r0,#0x20000000\n");
ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\n"); ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\n");
ot(" ldr r0,[r7,#0x3c] ;@ A7\n"); ot(" ldr r0,[r7,#0x3c] ;@ A7\n");
ot(" and r9,r9,#0xf0000000\n"); ot(" and r10,r10,#0xf0000000\n");
ot(" sub r0,r0,#2 ;@ Predecrement A7\n"); ot(" sub r0,r0,#2 ;@ Predecrement A7\n");
ot(" str r0,[r7,#0x3c] ;@ Save A7\n"); ot(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0); MemHandler(1,1,0,0);
@ -684,7 +687,7 @@ static void PrintFramework()
// information word // information word
ot(";@ Push info word:\n"); ot(";@ Push info word:\n");
ot(" ldr r0,[r7,#0x3c] ;@ A7\n"); ot(" ldr r0,[r7,#0x3c] ;@ A7\n");
ot(" mov r1,r10\n"); ot(" mov r1,r6\n");
ot(" sub r0,r0,#2 ;@ Predecrement A7\n"); ot(" sub r0,r0,#2 ;@ Predecrement A7\n");
ot(" str r0,[r7,#0x3c] ;@ Save A7\n"); ot(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0); MemHandler(1,1,0,0);
@ -713,6 +716,7 @@ static void PrintFramework()
#endif #endif
// 4. Resume execution. // 4. Resume execution.
ot(" ldr r6,[r7,#0x54]\n");
ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n"); ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n");
ot(" subs r5,r5,#50 ;@ Subtract cycles\n"); ot(" subs r5,r5,#50 ;@ Subtract cycles\n");
ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n");
@ -753,7 +757,7 @@ static void PrintFramework()
ot(" ldr r2,[r7,#0x58]\n"); ot(" ldr r2,[r7,#0x58]\n");
ot(" ldr r0,[r7,#0x9c] ;@ restore cycles\n"); ot(" ldr r0,[r7,#0x9c] ;@ restore cycles\n");
ot(" ldr r1,[r7,#0xa0] ;@ old CycloneEnd handler\n"); ot(" ldr r1,[r7,#0xa0] ;@ old CycloneEnd handler\n");
ot(" mov r9,r9,lsl #28\n"); ot(" mov r10,r10,lsl #28\n");
ot(" add r5,r0,r5\n"); ot(" add r5,r0,r5\n");
ot(" str r1,[r7,#0x98]\n"); ot(" str r1,[r7,#0x98]\n");
ot(";@ still tracing?\n"); // exception might have happend ot(";@ still tracing?\n"); // exception might have happend
@ -792,7 +796,7 @@ int MemHandler(int type,int size,int addrreg,int need_addrerr_check)
func=0x68+type*0xc+(size<<2); // Find correct offset func=0x68+type*0xc+(size<<2); // Find correct offset
#if MEMHANDLERS_NEED_FLAGS #if MEMHANDLERS_NEED_FLAGS
ot(" mov r3,r9,lsr #28\n"); ot(" mov r3,r10,lsr #28\n");
ot(" strb r3,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r3,[r7,#0x46] ;@ Save Flags (NZCV)\n");
#endif #endif
FlushPC(); FlushPC();
@ -847,8 +851,8 @@ int MemHandler(int type,int size,int addrreg,int need_addrerr_check)
ot(" handler\n"); ot(" handler\n");
#if MEMHANDLERS_CHANGE_FLAGS #if MEMHANDLERS_CHANGE_FLAGS
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Load Flags (NZCV)\n");
ot(" mov r9,r9,lsl #28\n"); ot(" mov r10,r10,lsl #28\n");
#endif #endif
#if MEMHANDLERS_CHANGE_PC #if MEMHANDLERS_CHANGE_PC
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n"); ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
@ -877,17 +881,17 @@ static void PrintOpcodes()
#endif #endif
#if USE_UNRECOGNIZED_CALLBACK #if USE_UNRECOGNIZED_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n"); ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n"); ot(" mov r1,r10,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n"); ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n"); ot(" tst r11,r11\n");
ot(" movne lr,pc\n"); ot(" movne lr,pc\n");
ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n"); ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Load Flags (NZCV)\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n"); ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n"); ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" mov r9,r9,lsl #28\n"); ot(" mov r10,r10,lsl #28\n");
ot(" tst r0,r0\n"); ot(" tst r0,r0\n");
ot(" moveq r0,#4\n"); ot(" moveq r0,#4\n");
ot(" bleq Exception\n"); ot(" bleq Exception\n");
@ -904,17 +908,17 @@ static void PrintOpcodes()
ot(" sub r4,r4,#2\n"); ot(" sub r4,r4,#2\n");
#if USE_AFLINE_CALLBACK #if USE_AFLINE_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n"); ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n"); ot(" mov r1,r10,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n"); ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n"); ot(" tst r11,r11\n");
ot(" movne lr,pc\n"); ot(" movne lr,pc\n");
ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n"); ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Load Flags (NZCV)\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n"); ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n"); ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" mov r9,r9,lsl #28\n"); ot(" mov r10,r10,lsl #28\n");
ot(" tst r0,r0\n"); ot(" tst r0,r0\n");
ot(" moveq r0,#0x0a\n"); ot(" moveq r0,#0x0a\n");
ot(" bleq Exception\n"); ot(" bleq Exception\n");
@ -930,17 +934,17 @@ static void PrintOpcodes()
ot(" sub r4,r4,#2\n"); ot(" sub r4,r4,#2\n");
#if USE_AFLINE_CALLBACK #if USE_AFLINE_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n"); ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n"); ot(" mov r1,r10,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n"); ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n"); ot(" tst r11,r11\n");
ot(" movne lr,pc\n"); ot(" movne lr,pc\n");
ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n"); ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Load Flags (NZCV)\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n"); ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n"); ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" mov r9,r9,lsl #28\n"); ot(" mov r10,r10,lsl #28\n");
ot(" tst r0,r0\n"); ot(" tst r0,r0\n");
ot(" moveq r0,#0x0b\n"); ot(" moveq r0,#0x0b\n");
ot(" bleq Exception\n"); ot(" bleq Exception\n");

View file

@ -133,17 +133,17 @@ int OpBase(int op,int size,int sepa)
// Get flags, trashes r2 // Get flags, trashes r2
int OpGetFlags(int subtract,int xbit,int specialz) int OpGetFlags(int subtract,int xbit,int specialz)
{ {
if (specialz) ot(" orr r2,r9,#0xb0000000 ;@ for old Z\n"); if (specialz) ot(" orr r2,r10,#0xb0000000 ;@ for old Z\n");
ot(" mrs r9,cpsr ;@ r9=flags\n"); ot(" mrs r10,cpsr ;@ r10=flags\n");
if (specialz) ot(" andeq r9,r9,r2 ;@ fix Z\n"); if (specialz) ot(" andeq r10,r10,r2 ;@ fix Z\n");
if (subtract) ot(" eor r9,r9,#0x20000000 ;@ Invert carry\n"); if (subtract) ot(" eor r10,r10,#0x20000000 ;@ Invert carry\n");
if (xbit) if (xbit)
{ {
ot(" str r9,[r7,#0x4c] ;@ Save X bit\n"); ot(" str r10,[r7,#0x4c] ;@ Save X bit\n");
} }
return 0; return 0;
} }

View file

@ -103,7 +103,7 @@ int OpAddq(int op)
if (size>0 && (ea&0x38)==0x08) size=2; // addq.w #n,An is also 32-bit if (size>0 && (ea&0x38)==0x08) size=2; // addq.w #n,An is also 32-bit
EaCalcReadNoSE(10,0,ea,size,0x003f); EaCalcReadNoSE(11,0,ea,size,0x003f);
shift=32-(8<<size); shift=32-(8<<size);
@ -131,7 +131,7 @@ int OpAddq(int op)
if ((ea&0x38)!=0x08) OpGetFlags(type,1); if ((ea&0x38)!=0x08) OpGetFlags(type,1);
ot("\n"); ot("\n");
EaWrite(10, 1, ea,size,0x003f,1); EaWrite(11, 1, ea,size,0x003f,1);
OpEnd(ea); OpEnd(ea);
@ -166,9 +166,9 @@ int OpArithReg(int op)
OpStart(op,ea); Cycles=4; OpStart(op,ea); Cycles=4;
EaCalcReadNoSE(dir?10:-1,0,ea,size,0x003f); EaCalcReadNoSE(dir?11:-1,0,ea,size,0x003f);
EaCalcReadNoSE(dir?-1:10,1,rea,size,0x0e00); EaCalcReadNoSE(dir?-1:11,1,rea,size,0x0e00);
ot(";@ Do arithmetic:\n"); ot(";@ Do arithmetic:\n");
if (type==0) strop = "orr"; if (type==0) strop = "orr";
@ -189,8 +189,8 @@ int OpArithReg(int op)
ot(";@ Save result:\n"); ot(";@ Save result:\n");
if (size<2) ot(" mov r1,r1,asr #%d\n",size?16:24); if (size<2) ot(" mov r1,r1,asr #%d\n",size?16:24);
if (dir) EaWrite(10, 1, ea,size,0x003f,0,0); if (dir) EaWrite(11, 1, ea,size,0x003f,0,0);
else EaWrite(10, 1,rea,size,0x0e00,0,0); else EaWrite(11, 1,rea,size,0x0e00,0,0);
if(rea==ea) { if(rea==ea) {
if(ea<8) Cycles=(size>=2)?8:4; else Cycles+=(size>=2)?26:14; if(ea<8) Cycles=(size>=2)?8:4; else Cycles+=(size>=2)?26:14;
@ -234,27 +234,27 @@ int OpMul(int op)
EaCalcReadNoSE(-1,0,ea,1,0x003f); EaCalcReadNoSE(-1,0,ea,1,0x003f);
EaCalc(10,0x0e00,rea, 2); EaCalc(11,0x0e00,rea, 2);
EaRead(10, 2,rea, 2,0x0e00); EaRead(11, 2,rea, 2,0x0e00);
ot(" movs r1,r0,asl #16\n"); ot(" movs r1,r0,asl #16\n");
if (type==0) // div if (type==0) // div
{ {
// the manual says C is always cleared, but neither Musashi nor FAME do that // the manual says C is always cleared, but neither Musashi nor FAME do that
//ot(" bic r9,r9,#0x20000000 ;@ always clear C\n"); //ot(" bic r10,r10,#0x20000000 ;@ always clear C\n");
ot(" beq divzero%.4x ;@ division by zero\n",op); ot(" beq divzero%.4x ;@ division by zero\n",op);
ot("\n"); ot("\n");
if (sign) if (sign)
{ {
ot(" mov r11,#0 ;@ r11 = 1 or 2 if the result is negative\n"); ot(" mov r12,#0 ;@ r12 = 1 or 2 if the result is negative\n");
ot(" tst r2,r2\n"); ot(" tst r2,r2\n");
ot(" orrmi r11,r11,#2\n"); ot(" orrmi r12,r12,#2\n");
ot(" rsbmi r2,r2,#0 ;@ Make r2 positive\n"); ot(" rsbmi r2,r2,#0 ;@ Make r2 positive\n");
ot("\n"); ot("\n");
ot(" movs r0,r1,asr #16\n"); ot(" movs r0,r1,asr #16\n");
ot(" orrmi r11,r11,#1\n"); ot(" orrmi r12,r12,#1\n");
ot(" rsbmi r0,r0,#0 ;@ Make r0 positive\n"); ot(" rsbmi r0,r0,#0 ;@ Make r0 positive\n");
ot("\n"); ot("\n");
ot(";@ detect the nasty 0x80000000 / -1 situation\n"); ot(";@ detect the nasty 0x80000000 / -1 situation\n");
@ -292,17 +292,17 @@ int OpMul(int op)
if (sign) if (sign)
{ {
// sign correction // sign correction
ot(" and r1,r11,#1\n"); ot(" and r1,r12,#1\n");
ot(" teq r1,r11,lsr #1\n"); ot(" teq r1,r12,lsr #1\n");
ot(" rsbne r3,r3,#0 ;@ negate if quotient is negative\n"); ot(" rsbne r3,r3,#0 ;@ negate if quotient is negative\n");
ot(" tst r11,#2\n"); ot(" tst r12,#2\n");
ot(" rsbne r2,r2,#0 ;@ negate the remainder if divident was negative\n"); ot(" rsbne r2,r2,#0 ;@ negate the remainder if divident was negative\n");
ot("\n"); ot("\n");
// signed overflow check // signed overflow check
ot(" mov r1,r3,asl #16\n"); ot(" mov r1,r3,asl #16\n");
ot(" cmp r3,r1,asr #16 ;@ signed overflow?\n"); ot(" cmp r3,r1,asr #16 ;@ signed overflow?\n");
ot(" orrne r9,r9,#0x10000000 ;@ set overflow flag\n"); ot(" orrne r10,r10,#0x10000000 ;@ set overflow flag\n");
ot(" bne endofop%.4x ;@ overflow!\n",op); ot(" bne endofop%.4x ;@ overflow!\n",op);
ot("\n"); ot("\n");
ot("wrendofop%.4x%s\n",op,ms?"":":"); ot("wrendofop%.4x%s\n",op,ms?"":":");
@ -311,7 +311,7 @@ int OpMul(int op)
{ {
// overflow check // overflow check
ot(" movs r1,r3,lsr #16 ;@ check for overflow condition\n"); ot(" movs r1,r3,lsr #16 ;@ check for overflow condition\n");
ot(" orrne r9,r9,#0x10000000 ;@ set overflow flag\n"); ot(" orrne r10,r10,#0x10000000 ;@ set overflow flag\n");
ot(" bne endofop%.4x ;@ overflow!\n",op); ot(" bne endofop%.4x ;@ overflow!\n",op);
ot("\n"); ot("\n");
} }
@ -338,7 +338,7 @@ int OpMul(int op)
} }
ot("\n"); ot("\n");
EaWrite(10, 1,rea, 2,0x0e00,1); EaWrite(11, 1,rea, 2,0x0e00,1);
if (type==0) ot("endofop%.4x%s\n",op,ms?"":":"); if (type==0) ot("endofop%.4x%s\n",op,ms?"":":");
OpEnd(ea); OpEnd(ea);
@ -392,19 +392,19 @@ int OpAbcd(int op)
{ {
ot(";@ Get src/dest EA vals\n"); ot(";@ Get src/dest EA vals\n");
EaCalc (0,0x000f, sea,0,1); EaCalc (0,0x000f, sea,0,1);
EaRead (0, 10, sea,0,0x000f,1); EaRead (0, 6, sea,0,0x000f,1);
EaCalcReadNoSE(11,0,dea,0,0x0e00); EaCalcReadNoSE(11,0,dea,0,0x0e00);
} }
else else
{ {
ot(";@ Get src/dest reg vals\n"); ot(";@ Get src/dest reg vals\n");
EaCalcReadNoSE(-1,10,sea,0,0x0007); EaCalcReadNoSE(-1,6,sea,0,0x0007);
EaCalcReadNoSE(11,0,dea,0,0x0e00); EaCalcReadNoSE(11,0,dea,0,0x0e00);
ot(" mov r10,r10,asl #24\n"); ot(" mov r6,r6,asl #24\n");
} }
ot(" mov r1,r0,asl #24\n\n"); ot(" mov r1,r0,asl #24\n\n");
ot(" bic r9,r9,#0xb1000000 ;@ clear all flags except old Z\n"); ot(" bic r10,r10,#0xb1000000 ;@ clear all flags except old Z\n");
if (type) if (type)
{ {
@ -412,59 +412,61 @@ int OpAbcd(int op)
ot(" mov r3,#0x00f00000\n"); ot(" mov r3,#0x00f00000\n");
ot(" and r2,r3,r1,lsr #4\n"); ot(" and r2,r3,r1,lsr #4\n");
ot(" tst r0,#0x20000000\n"); ot(" tst r0,#0x20000000\n");
ot(" and r0,r3,r10,lsr #4\n"); ot(" and r0,r3,r6,lsr #4\n");
ot(" add r0,r0,r2\n"); ot(" add r0,r0,r2\n");
ot(" addne r0,r0,#0x00100000\n"); ot(" addne r0,r0,#0x00100000\n");
// ot(" tst r0,#0x00800000\n"); // ot(" tst r0,#0x00800000\n");
// ot(" orreq r9,r9,#0x01000000 ;@ Undefined V behavior\n"); // ot(" orreq r10,r10,#0x01000000 ;@ Undefined V behavior\n");
ot(" cmp r0,#0x00900000\n"); ot(" cmp r0,#0x00900000\n");
ot(" addhi r0,r0,#0x00600000 ;@ Decimal adjust units\n"); ot(" addhi r0,r0,#0x00600000 ;@ Decimal adjust units\n");
ot(" mov r2,r1,lsr #28\n"); ot(" mov r2,r1,lsr #28\n");
ot(" add r0,r0,r2,lsl #24\n"); ot(" add r0,r0,r2,lsl #24\n");
ot(" mov r2,r10,lsr #28\n"); ot(" mov r2,r6,lsr #28\n");
ot(" add r0,r0,r2,lsl #24\n"); ot(" add r0,r0,r2,lsl #24\n");
ot(" cmp r0,#0x09900000\n"); ot(" cmp r0,#0x09900000\n");
ot(" orrhi r9,r9,#0x20000000 ;@ C\n"); ot(" orrhi r10,r10,#0x20000000 ;@ C\n");
ot(" subhi r0,r0,#0x0a000000\n"); ot(" subhi r0,r0,#0x0a000000\n");
// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n"); // ot(" and r3,r10,r0,lsr #3 ;@ Undefined V behavior part II\n");
// ot(" orr r9,r9,r3,lsl #4 ;@ V\n"); // ot(" orr r10,r10,r3,lsl #4 ;@ V\n");
ot(" movs r0,r0,lsl #4\n"); ot(" movs r0,r0,lsl #4\n");
ot(" orrmi r9,r9,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does ot(" orrmi r10,r10,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does
ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n"); ot(" bicne r10,r10,#0x40000000 ;@ Z flag\n");
} }
else else
{ {
ot(" ldr r0,[r7,#0x4c] ;@ Get X bit\n"); ot(" ldr r0,[r7,#0x4c] ;@ Get X bit\n");
ot(" mov r3,#0x00f00000\n"); ot(" mov r3,#0x00f00000\n");
ot(" and r2,r3,r10,lsr #4\n"); ot(" and r2,r3,r6,lsr #4\n");
ot(" tst r0,#0x20000000\n"); ot(" tst r0,#0x20000000\n");
ot(" and r0,r3,r1,lsr #4\n"); ot(" and r0,r3,r1,lsr #4\n");
ot(" sub r0,r0,r2\n"); ot(" sub r0,r0,r2\n");
ot(" subne r0,r0,#0x00100000\n"); ot(" subne r0,r0,#0x00100000\n");
// ot(" tst r0,#0x00800000\n"); // ot(" tst r0,#0x00800000\n");
// ot(" orreq r9,r9,#0x01000000 ;@ Undefined V behavior\n"); // ot(" orreq r10,r10,#0x01000000 ;@ Undefined V behavior\n");
ot(" cmp r0,#0x00900000\n"); ot(" cmp r0,#0x00900000\n");
ot(" subhi r0,r0,#0x00600000 ;@ Decimal adjust units\n"); ot(" subhi r0,r0,#0x00600000 ;@ Decimal adjust units\n");
ot(" mov r2,r1,lsr #28\n"); ot(" mov r2,r1,lsr #28\n");
ot(" add r0,r0,r2,lsl #24\n"); ot(" add r0,r0,r2,lsl #24\n");
ot(" mov r2,r10,lsr #28\n"); ot(" mov r2,r6,lsr #28\n");
ot(" sub r0,r0,r2,lsl #24\n"); ot(" sub r0,r0,r2,lsl #24\n");
ot(" cmp r0,#0x09900000\n"); ot(" cmp r0,#0x09900000\n");
ot(" orrhi r9,r9,#0xa0000000 ;@ N and C\n"); ot(" orrhi r10,r10,#0xa0000000 ;@ N and C\n");
ot(" addhi r0,r0,#0x0a000000\n"); ot(" addhi r0,r0,#0x0a000000\n");
// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n"); // ot(" and r3,r10,r0,lsr #3 ;@ Undefined V behavior part II\n");
// ot(" orr r9,r9,r3,lsl #4 ;@ V\n"); // ot(" orr r10,r10,r3,lsl #4 ;@ V\n");
ot(" movs r0,r0,lsl #4\n"); ot(" movs r0,r0,lsl #4\n");
// ot(" orrmi r9,r9,#0x80000000 ;@ Undefined N behavior\n"); // ot(" orrmi r10,r10,#0x80000000 ;@ Undefined N behavior\n");
ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n"); ot(" bicne r10,r10,#0x40000000 ;@ Z flag\n");
} }
ot(" str r9,[r7,#0x4c] ;@ Save X bit\n"); ot(" str r10,[r7,#0x4c] ;@ Save X bit\n");
ot("\n"); ot("\n");
EaWrite(11, 0, dea,0,0x0e00,1); EaWrite(11, 0, dea,0,0x0e00,1);
ot(" ldr r6,[r7,#0x54]\n");
OpEnd(sea,dea); OpEnd(sea,dea);
return 0; return 0;
@ -486,11 +488,11 @@ int OpNbcd(int op)
OpStart(op,ea); Cycles=6; OpStart(op,ea); Cycles=6;
if(ea >= 8) Cycles+=2; if(ea >= 8) Cycles+=2;
EaCalcReadNoSE(10,0,ea,0,0x003f); EaCalcReadNoSE(6,0,ea,0,0x003f);
// this is rewrite of Musashi's code // this is rewrite of Musashi's code
ot(" ldr r2,[r7,#0x4c]\n"); ot(" ldr r2,[r7,#0x4c]\n");
ot(" bic r9,r9,#0xb0000000 ;@ clear all flags, except Z\n"); ot(" bic r10,r10,#0xb0000000 ;@ clear all flags, except Z\n");
ot(" mov r0,r0,asl #24\n"); ot(" mov r0,r0,asl #24\n");
ot(" and r2,r2,#0x20000000\n"); ot(" and r2,r2,#0x20000000\n");
ot(" add r2,r0,r2,lsr #5 ;@ add X\n"); ot(" add r2,r0,r2,lsr #5 ;@ add X\n");
@ -507,19 +509,20 @@ int OpNbcd(int op)
ot(" addeq r11,r11,#0x10000000\n"); ot(" addeq r11,r11,#0x10000000\n");
ot(" and r3,r3,r11,lsr #31 ;@ Undefined V behavior part II\n",op); ot(" and r3,r3,r11,lsr #31 ;@ Undefined V behavior part II\n",op);
ot(" movs r1,r11,asr #24\n"); ot(" movs r1,r11,asr #24\n");
ot(" bicne r9,r9,#0x40000000 ;@ Z\n"); ot(" bicne r10,r10,#0x40000000 ;@ Z\n");
ot(" orr r9,r9,r3,lsl #28 ;@ save V\n",op); ot(" orr r10,r10,r3,lsl #28 ;@ save V\n",op);
ot(" orr r9,r9,#0x20000000 ;@ C\n"); ot(" orr r10,r10,#0x20000000 ;@ C\n");
ot("\n"); ot("\n");
EaWrite(10, 1, ea,0,0x3f,0,0); EaWrite(6, 1, ea,0,0x3f,0,0);
ot("finish%.4x%s\n",op,ms?"":":"); ot("finish%.4x%s\n",op,ms?"":":");
ot(" tst r11,r11\n"); ot(" tst r11,r11\n");
ot(" orrmi r9,r9,#0x80000000 ;@ N\n"); ot(" orrmi r10,r10,#0x80000000 ;@ N\n");
ot(" str r9,[r7,#0x4c] ;@ Save X\n"); ot(" str r10,[r7,#0x4c] ;@ Save X\n");
ot("\n"); ot("\n");
ot(" ldr r6,[r7,#0x54]\n");
OpEnd(ea); OpEnd(ea);
return 0; return 0;
@ -556,12 +559,12 @@ int OpAritha(int op)
//if (type == 1) //if (type == 1)
{ {
EaCalcReadNoSE(-1,0,sea,size,0x003f); EaCalcReadNoSE(-1,0,sea,size,0x003f);
EaCalcReadNoSE(type!=1?10:-1,11,dea,2,0x0e00); EaCalcReadNoSE(type!=1?11:-1,1,dea,2,0x0e00);
} }
#if 0 #if 0
else else
{ {
EaCalcReadNoSE(type!=1?10:-1,11,dea,2,0x0e00); EaCalcReadNoSE(type!=1?11:-1,1,dea,2,0x0e00);
EaCalcReadNoSE(-1,0,sea,size,0x003f); EaCalcReadNoSE(-1,0,sea,size,0x003f);
} }
#endif #endif
@ -569,13 +572,13 @@ int OpAritha(int op)
if (size<2) ot(" mov r0,r0,asl #%d\n\n",size?16:24); if (size<2) ot(" mov r0,r0,asl #%d\n\n",size?16:24);
if (size<2) asr=(char *)(size?",asr #16":",asr #24"); if (size<2) asr=(char *)(size?",asr #16":",asr #24");
if (type==0) ot(" sub r11,r11,r0%s\n",asr); if (type==0) ot(" sub r1,r1,r0%s\n",asr);
if (type==1) ot(" cmp r11,r0%s ;@ Defines NZCV\n",asr); if (type==1) ot(" cmp r1,r0%s ;@ Defines NZCV\n",asr);
if (type==1) OpGetFlags(1,0); // Get Cmp flags if (type==1) OpGetFlags(1,0); // Get Cmp flags
if (type==2) ot(" add r11,r11,r0%s\n",asr); if (type==2) ot(" add r1,r1,r0%s\n",asr);
ot("\n"); ot("\n");
if (type!=1) EaWrite(10, 11, dea,2,0x0e00); if (type!=1) EaWrite(11, 1, dea,2,0x0e00);
OpEnd(sea); OpEnd(sea);
@ -600,7 +603,7 @@ int OpAddx(int op)
if (EaCanRead(sea,size)==0) return 1; if (EaCanRead(sea,size)==0) return 1;
if (EaCanWrite(dea)==0) return 1; if (EaCanWrite(dea)==0) return 1;
if(mem) { sea+=0x20; dea+=0x20; } if (mem) { sea+=0x20; dea+=0x20; }
use=op&~0x0e07; // Use same opcode for Dn use=op&~0x0e07; // Use same opcode for Dn
if (size==0&&sea==0x27) use|=0x0007; // ___x.b -(a7) if (size==0&&sea==0x27) use|=0x0007; // ___x.b -(a7)
@ -615,15 +618,15 @@ int OpAddx(int op)
{ {
ot(";@ Get src/dest EA vals\n"); ot(";@ Get src/dest EA vals\n");
EaCalc (0,0x000f, sea,size,1); EaCalc (0,0x000f, sea,size,1);
EaRead (0, 11, sea,size,0x000f,1); EaRead (0, 6, sea,size,0x000f,1);
EaCalcReadNoSE(10,0,dea,size,0x0e00); EaCalcReadNoSE(11,0,dea,size,0x0e00);
} }
else else
{ {
ot(";@ Get src/dest reg vals\n"); ot(";@ Get src/dest reg vals\n");
EaCalcReadNoSE(-1,11,sea,size,0x0007); EaCalcReadNoSE(-1,6,sea,size,0x0007);
EaCalcReadNoSE(10,0,dea,size,0x0e00); EaCalcReadNoSE(11,0,dea,size,0x0e00);
if (size<2) ot(" mov r11,r11,asl #%d\n\n",size?16:24); if (size<2) ot(" mov r6,r6,asl #%d\n\n",size?16:24);
} }
if (size<2) asl=(char *)(size?",asl #16":",asl #24"); if (size<2) asl=(char *)(size?",asl #16":",asl #24");
@ -635,24 +638,25 @@ int OpAddx(int op)
{ {
ot(";@ Make sure the carry bit will tip the balance:\n"); ot(";@ Make sure the carry bit will tip the balance:\n");
ot(" mvn r2,#0\n"); ot(" mvn r2,#0\n");
ot(" orr r11,r11,r2,lsr #%i\n",(size==0)?8:16); ot(" orr r6,r6,r2,lsr #%i\n",(size==0)?8:16);
ot("\n"); ot("\n");
} }
if (type==0) ot(" rscs r1,r11,r0%s\n",asl); if (type==0) ot(" rscs r1,r6,r0%s\n",asl);
if (type==1) ot(" adcs r1,r11,r0%s\n",asl); if (type==1) ot(" adcs r1,r6,r0%s\n",asl);
ot(" orr r3,r9,#0xb0000000 ;@ for old Z\n"); ot(" orr r3,r10,#0xb0000000 ;@ for old Z\n");
OpGetFlags(type==0,1,0); // subtract OpGetFlags(type==0,1,0); // subtract
if (size<2) { if (size<2) {
ot(" movs r2,r1,lsr #%i\n", size?16:24); ot(" movs r2,r1,lsr #%i\n", size?16:24);
ot(" orreq r9,r9,#0x40000000 ;@ add potentially missed Z\n"); ot(" orreq r10,r10,#0x40000000 ;@ add potentially missed Z\n");
} }
ot(" andeq r9,r9,r3 ;@ fix Z\n"); ot(" andeq r10,r10,r3 ;@ fix Z\n");
ot("\n"); ot("\n");
ot(";@ Save result:\n"); ot(";@ Save result:\n");
EaWrite(10, 1, dea,size,0x0e00,1); EaWrite(11, 1, dea,size,0x0e00,1);
ot(" ldr r6,[r7,#0x54]\n");
OpEnd(sea,dea); OpEnd(sea,dea);
return 0; return 0;
@ -691,8 +695,8 @@ int OpCmpEor(int op)
if(size>=2) Cycles+=2; if(size>=2) Cycles+=2;
} }
ot(";@ Get EA into r10 and value into r0:\n"); ot(";@ Get EA into r11 and value into r0:\n");
EaCalcReadNoSE(eor?10:-1,0,ea,size,0x003f); EaCalcReadNoSE(eor?11:-1,0,ea,size,0x003f);
ot(";@ Get register operand into r1:\n"); ot(";@ Get register operand into r1:\n");
EaCalcReadNoSE(-1,1,rea,size,0x0e00); EaCalcReadNoSE(-1,1,rea,size,0x0e00);
@ -711,7 +715,7 @@ int OpCmpEor(int op)
OpGetFlags(eor==0,0); // Cmp like subtract OpGetFlags(eor==0,0); // Cmp like subtract
ot("\n"); ot("\n");
if (eor) EaWrite(10, 1,ea,size,0x003f,1); if (eor) EaWrite(11, 1,ea,size,0x003f,1);
OpEnd(ea); OpEnd(ea);
return 0; return 0;
@ -735,16 +739,16 @@ int OpCmpm(int op)
OpStart(op,sea); Cycles=4; OpStart(op,sea); Cycles=4;
ot(";@ Get src operand into r10:\n"); ot(";@ Get src operand into r11:\n");
EaCalc (0,0x0007, sea,size,1); EaCalc (0,0x0007, sea,size,1);
EaRead (0, 10, sea,size,0x0007,1); EaRead (0, 11, sea,size,0x0007,1);
ot(";@ Get dst operand into r0:\n"); ot(";@ Get dst operand into r0:\n");
EaCalcReadNoSE(-1,0,dea,size,0x0e00); EaCalcReadNoSE(-1,0,dea,size,0x0e00);
if (size<2) asl=(char *)(size?",asl #16":",asl #24"); if (size<2) asl=(char *)(size?",asl #16":",asl #24");
ot(" rsbs r0,r10,r0%s\n",asl); ot(" rsbs r0,r11,r0%s\n",asl);
OpGetFlags(1,0); // Cmp like subtract OpGetFlags(1,0); // Cmp like subtract
ot("\n"); ot("\n");
@ -778,7 +782,7 @@ int OpChk(int op)
OpStart(op,ea); Cycles=10; OpStart(op,ea); Cycles=10;
ot(";@ Get EA into r10 and value into r0:\n"); ot(";@ Get value into r0:\n");
EaCalcReadNoSE(-1,0,ea,size,0x003f); EaCalcReadNoSE(-1,0,ea,size,0x003f);
ot(";@ Get register operand into r1:\n"); ot(";@ Get register operand into r1:\n");
@ -788,7 +792,7 @@ int OpChk(int op)
if (size<2) ot(" mov r1,r1,asl #%d\n\n",size?16:24); if (size<2) ot(" mov r1,r1,asl #%d\n\n",size?16:24);
ot(";@ get flags, including undocumented ones\n"); ot(";@ get flags, including undocumented ones\n");
ot(" and r3,r9,#0x80000000\n"); ot(" and r3,r10,#0x80000000\n");
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0); OpGetFlags(0,0);
@ -796,12 +800,12 @@ int OpChk(int op)
ot(" bmi chktrap%.4x\n",op); ot(" bmi chktrap%.4x\n",op);
ot(";@ Do arithmetic:\n"); ot(";@ Do arithmetic:\n");
ot(" bic r9,r9,#0x80000000 ;@ N\n"); ot(" bic r10,r10,#0x80000000 ;@ N\n");
ot(" cmp r1,r0\n"); ot(" cmp r1,r0\n");
ot(" bgt chktrap%.4x\n",op); ot(" bgt chktrap%.4x\n",op);
ot(";@ old N remains\n"); ot(";@ old N remains\n");
ot(" orr r9,r9,r3\n"); ot(" orr r10,r10,r3\n");
OpEnd(ea); OpEnd(ea);
ot("chktrap%.4x%s ;@ CHK exception:\n",op,ms?"":":"); ot("chktrap%.4x%s ;@ CHK exception:\n",op,ms?"":":");

View file

@ -47,7 +47,7 @@ static void PopSr(int high)
OpRegToFlags(high); OpRegToFlags(high);
} }
// Pop PC - assumes r10=Memory Base - trashes r0-r3 // Pop PC - assumes r11=Memory Base - trashes r0-r3
static void PopPc() static void PopPc()
{ {
ot(";@ Pop PC:\n"); ot(";@ Pop PC:\n");
@ -55,7 +55,7 @@ static void PopPc()
ot(" add r1,r0,#4 ;@ Postincrement A7\n"); ot(" add r1,r0,#4 ;@ Postincrement A7\n");
ot(" str r1,[r7,#0x3c] ;@ Save A7\n"); ot(" str r1,[r7,#0x3c] ;@ Save A7\n");
MemHandler(0,2); MemHandler(0,2);
ot(" add r0,r0,r10 ;@ Memory Base+PC\n"); ot(" add r0,r0,r11 ;@ Memory Base+PC\n");
ot("\n"); ot("\n");
CheckPc(); CheckPc();
#if EMULATE_ADDRESS_ERRORS_JUMP #if EMULATE_ADDRESS_ERRORS_JUMP
@ -97,13 +97,13 @@ int OpLink(int op)
if(reg!=7) { if(reg!=7) {
ot(";@ Get An\n"); ot(";@ Get An\n");
EaCalc(10, 7, 8, 2, 1); EaCalc(11, 7, 8, 2, 1);
EaRead(10, 1, 8, 2, 7, 1); EaRead(11, 1, 8, 2, 7, 1);
} }
ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n"); ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n");
ot(" sub r0,r0,#4 ;@ A7-=4\n"); ot(" sub r0,r0,#4 ;@ A7-=4\n");
ot(" mov r11,r0\n"); ot(" mov r8,r0 ;@ abuse r8\n");
if(reg==7) ot(" mov r1,r0\n"); if(reg==7) ot(" mov r1,r0\n");
ot("\n"); ot("\n");
@ -112,14 +112,14 @@ int OpLink(int op)
ot(";@ Save to An\n"); ot(";@ Save to An\n");
if(reg!=7) if(reg!=7)
EaWrite(10,11, 8, 2, 7, 1); EaWrite(11,8, 8, 2, 7, 1);
ot(";@ Get offset:\n"); ot(";@ Get offset:\n");
EaCalc(0,0,0x3c,1); EaCalc(0,0,0x3c,1); // abused r8 is ok because of imm EA
EaRead(0,0,0x3c,1,0); EaRead(0,0,0x3c,1,0);
ot(" add r11,r11,r0 ;@ Add offset to A7\n"); ot(" add r8,r8,r0 ;@ Add offset to A7\n");
ot(" str r11,[r7,#0x3c]\n"); ot(" str r8,[r7,#0x3c]\n");
ot("\n"); ot("\n");
Cycles=16; Cycles=16;
@ -138,18 +138,18 @@ int OpUnlk(int op)
OpStart(op,0x10); OpStart(op,0x10);
ot(";@ Get An\n"); ot(";@ Get An\n");
EaCalc(10, 0xf, 8, 2, 1); EaCalc(11, 0xf, 8, 2, 1);
EaRead(10, 0, 8, 2, 0xf, 1); EaRead(11, 0, 8, 2, 0xf, 1);
ot(" add r11,r0,#4 ;@ A7+=4\n"); ot(" add r8,r0,#4 ;@ A7+=4, abuse r8\n");
ot("\n"); ot("\n");
ot(";@ Pop An from stack:\n"); ot(";@ Pop An from stack:\n");
MemHandler(0,2); MemHandler(0,2);
ot("\n"); ot("\n");
ot(" str r11,[r7,#0x3c] ;@ Save A7\n"); ot(" str r8,[r7,#0x3c] ;@ Save A7\n");
ot("\n"); ot("\n");
ot(";@ An = value from stack:\n"); ot(";@ An = value from stack:\n");
EaWrite(10, 0, 8, 2, 7, 1); EaWrite(11, 0, 8, 2, 7, 1);
Cycles=12; Cycles=12;
OpEnd(0x10); OpEnd(0x10);
@ -175,7 +175,7 @@ int Op4E70(int op)
case 3: // rte case 3: // rte
OpStart(op,0x10,0,0,1); Cycles=20; OpStart(op,0x10,0,0,1); Cycles=20;
PopSr(1); PopSr(1);
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r11,[r7,#0x60] ;@ Get Memory base\n");
PopPc(); PopPc();
ot(" ldr r1,[r7,#0x44] ;@ reload SR high\n"); ot(" ldr r1,[r7,#0x44] ;@ reload SR high\n");
SuperChange(op,1); SuperChange(op,1);
@ -195,7 +195,7 @@ int Op4E70(int op)
case 5: // rts case 5: // rts
OpStart(op,0x10); Cycles=16; OpStart(op,0x10); Cycles=16;
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r11,[r7,#0x60] ;@ Get Memory base\n");
PopPc(); PopPc();
#if EMULATE_ADDRESS_ERRORS_JUMP #if EMULATE_ADDRESS_ERRORS_JUMP
ot(" tst r4,#1 ;@ address error?\n"); ot(" tst r4,#1 ;@ address error?\n");
@ -206,7 +206,7 @@ int Op4E70(int op)
case 6: // trapv case 6: // trapv
OpStart(op,0x10,0,1); Cycles=4; OpStart(op,0x10,0,1); Cycles=4;
ot(" tst r9,#0x10000000\n"); ot(" tst r10,#0x10000000\n");
ot(" subne r5,r5,#%i\n",34); ot(" subne r5,r5,#%i\n",34);
ot(" movne r0,#7 ;@ TRAPV exception\n"); ot(" movne r0,#7 ;@ TRAPV exception\n");
ot(" blne Exception\n"); ot(" blne Exception\n");
@ -217,7 +217,7 @@ int Op4E70(int op)
case 7: // rtr case 7: // rtr
OpStart(op,0x10); Cycles=20; OpStart(op,0x10); Cycles=20;
PopSr(0); PopSr(0);
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r11,[r7,#0x60] ;@ Get Memory base\n");
PopPc(); PopPc();
#if EMULATE_ADDRESS_ERRORS_JUMP #if EMULATE_ADDRESS_ERRORS_JUMP
ot(" tst r4,#1 ;@ address error?\n"); ot(" tst r4,#1 ;@ address error?\n");
@ -248,18 +248,18 @@ int OpJsr(int op)
OpStart(op,(op&0x40)?0:0x10); OpStart(op,(op&0x40)?0:0x10);
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n"); ot(" ldr r11,[r7,#0x60] ;@ Get Memory base\n");
ot("\n"); ot("\n");
EaCalc(11,0x003f,sea,0); EaCalc(12,0x003f,sea,0);
ot(";@ Jump - Get new PC from r11\n"); ot(";@ Jump - Get new PC from r12\n");
ot(" add r0,r11,r10 ;@ Memory Base + New PC\n"); ot(" add r0,r12,r11 ;@ Memory Base + New PC\n");
ot("\n"); ot("\n");
CheckPc(); CheckPc();
if (!(op&0x40)) if (!(op&0x40))
{ {
ot(" ldr r2,[r7,#0x3c]\n"); ot(" ldr r2,[r7,#0x3c]\n");
ot(" sub r1,r4,r10 ;@ r1 = Old PC\n"); ot(" sub r1,r4,r11 ;@ r1 = Old PC\n");
} }
#if EMULATE_ADDRESS_ERRORS_JUMP #if EMULATE_ADDRESS_ERRORS_JUMP
// jsr prefetches next instruction before pushing old PC, // jsr prefetches next instruction before pushing old PC,
@ -314,16 +314,16 @@ int OpDbra(int op)
case 1: // F case 1: // F
break; break;
case 2: // hi case 2: // hi
ot(" tst r9,#0x60000000 ;@ hi: !C && !Z\n"); ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n");
ot(" beq DbraTrue\n\n"); ot(" beq DbraTrue\n\n");
break; break;
case 3: // ls case 3: // ls
ot(" tst r9,#0x60000000 ;@ ls: C || Z\n"); ot(" tst r10,#0x60000000 ;@ ls: C || Z\n");
ot(" bne DbraTrue\n\n"); ot(" bne DbraTrue\n\n");
break; break;
default: default:
ot(";@ Is the condition true?\n"); ot(";@ Is the condition true?\n");
ot(" msr cpsr_flg,r9 ;@ ARM flags = 68000 flags\n"); ot(" msr cpsr_flg,r10 ;@ ARM flags = 68000 flags\n");
ot(";@ If so, don't dbra\n"); ot(";@ If so, don't dbra\n");
ot(" b%s DbraTrue\n\n",Cond[cc]); ot(" b%s DbraTrue\n\n",Cond[cc]);
break; break;
@ -421,24 +421,22 @@ int OpBranch(int op)
OpStart(op,size?0x10:0); OpStart(op,size?0x10:0);
Cycles=10; // Assume branch taken Cycles=10; // Assume branch taken
if (cc==1) ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");
switch (cc) switch (cc)
{ {
case 0: // T case 0: // T
case 1: // F case 1: // F
break; break;
case 2: // hi case 2: // hi
ot(" tst r9,#0x60000000 ;@ hi: !C && !Z\n"); ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n");
ot(" bne BccDontBranch%i\n\n",8<<size); ot(" bne BccDontBranch%i\n\n",8<<size);
break; break;
case 3: // ls case 3: // ls
ot(" tst r9,#0x60000000 ;@ ls: C || Z\n"); ot(" tst r10,#0x60000000 ;@ ls: C || Z\n");
ot(" beq BccDontBranch%i\n\n",8<<size); ot(" beq BccDontBranch%i\n\n",8<<size);
break; break;
default: default:
ot(";@ Is the condition true?\n"); ot(";@ Is the condition true?\n");
ot(" msr cpsr_flg,r9 ;@ ARM flags = 68000 flags\n"); ot(" msr cpsr_flg,r10 ;@ ARM flags = 68000 flags\n");
ot(" b%s BccDontBranch%i\n\n",Cond[cc^1],8<<size); ot(" b%s BccDontBranch%i\n\n",Cond[cc^1],8<<size);
break; break;
} }
@ -467,8 +465,9 @@ int OpBranch(int op)
if (cc==1) if (cc==1)
{ {
ot(";@ Bsr - remember old PC\n"); ot(";@ Bsr - remember old PC\n");
ot(" ldr r12,[r7,#0x60] ;@ Get Memory base\n");
ot(" ldr r2,[r7,#0x3c]\n"); ot(" ldr r2,[r7,#0x3c]\n");
ot(" sub r1,r4,r10 ;@ r1 = Old PC\n"); ot(" sub r1,r4,r12 ;@ r1 = Old PC\n");
if (size) ot(" add r1,r1,#%d\n",1<<size); if (size) ot(" add r1,r1,#%d\n",1<<size);
ot("\n"); ot("\n");
ot(";@ Push r1 onto stack\n"); ot(";@ Push r1 onto stack\n");

View file

@ -36,28 +36,28 @@ int OpBtstReg(int op)
if(size>=2) Cycles+=2; if(size>=2) Cycles+=2;
} }
EaCalcReadNoSE(-1,10,sea,0,0x0e00); EaCalcReadNoSE(-1,11,sea,0,0x0e00);
EaCalcReadNoSE((type>0)?11:-1,0,tea,size,0x003f); EaCalcReadNoSE((type>0)?8:-1,0,tea,size,0x003f);
if (tea>=0x10) if (tea>=0x11)
ot(" and r10,r10,#7 ;@ mem - do mod 8\n"); // size always 0 ot(" and r11,r11,#7 ;@ mem - do mod 8\n"); // size always 0
else ot(" and r10,r10,#31 ;@ reg - do mod 32\n"); // size always 2 else ot(" and r11,r11,#31 ;@ reg - do mod 32\n"); // size always 2
ot("\n"); ot("\n");
ot(" mov r1,#1\n"); ot(" mov r1,#1\n");
ot(" tst r0,r1,lsl r10 ;@ Do arithmetic\n"); ot(" tst r0,r1,lsl r11 ;@ Do arithmetic\n");
ot(" bicne r9,r9,#0x40000000\n"); ot(" bicne r10,r10,#0x40000000\n");
ot(" orreq r9,r9,#0x40000000 ;@ Get Z flag\n"); ot(" orreq r10,r10,#0x40000000 ;@ Get Z flag\n");
ot("\n"); ot("\n");
if (type>0) if (type>0)
{ {
if (type==1) ot(" eor r1,r0,r1,lsl r10 ;@ Toggle bit\n"); if (type==1) ot(" eor r1,r0,r1,lsl r11 ;@ Toggle bit\n");
if (type==2) ot(" bic r1,r0,r1,lsl r10 ;@ Clear bit\n"); if (type==2) ot(" bic r1,r0,r1,lsl r11 ;@ Clear bit\n");
if (type==3) ot(" orr r1,r0,r1,lsl r10 ;@ Set bit\n"); if (type==3) ot(" orr r1,r0,r1,lsl r11 ;@ Set bit\n");
ot("\n"); ot("\n");
EaWrite(11, 1,tea,size,0x003f,0,0); EaWrite(8,1,tea,size,0x003f,0,0);
} }
OpEnd(tea); OpEnd(tea);
@ -92,12 +92,12 @@ int OpBtstImm(int op)
ot("\n"); ot("\n");
EaCalcReadNoSE(-1,0,sea,0,0); EaCalcReadNoSE(-1,0,sea,0,0);
ot(" mov r10,#1\n"); ot(" mov r11,#1\n");
ot(" bic r9,r9,#0x40000000 ;@ Blank Z flag\n"); ot(" bic r10,r10,#0x40000000 ;@ Blank Z flag\n");
if (tea>=0x10) if (tea>=0x11)
ot(" and r0,r0,#7 ;@ mem - do mod 8\n"); // size always 0 ot(" and r0,r0,#7 ;@ mem - do mod 8\n"); // size always 0
else ot(" and r0,r0,#0x1F ;@ reg - do mod 32\n"); // size always 2 else ot(" and r0,r0,#0x1F ;@ reg - do mod 32\n"); // size always 2
ot(" mov r10,r10,lsl r0 ;@ Make bit mask\n"); ot(" mov r11,r11,lsl r0 ;@ Make bit mask\n");
ot("\n"); ot("\n");
if(type==1||type==3) { if(type==1||type==3) {
@ -107,18 +107,18 @@ int OpBtstImm(int op)
if(size>=2) Cycles+=2; if(size>=2) Cycles+=2;
} }
EaCalcReadNoSE((type>0)?11:-1,0,tea,size,0x003f); EaCalcReadNoSE((type>0)?8:-1,0,tea,size,0x003f);
ot(" tst r0,r10 ;@ Do arithmetic\n"); ot(" tst r0,r11 ;@ Do arithmetic\n");
ot(" orreq r9,r9,#0x40000000 ;@ Get Z flag\n"); ot(" orreq r10,r10,#0x40000000 ;@ Get Z flag\n");
ot("\n"); ot("\n");
if (type>0) if (type>0)
{ {
if (type==1) ot(" eor r1,r0,r10 ;@ Toggle bit\n"); if (type==1) ot(" eor r1,r0,r11 ;@ Toggle bit\n");
if (type==2) ot(" bic r1,r0,r10 ;@ Clear bit\n"); if (type==2) ot(" bic r1,r0,r11 ;@ Clear bit\n");
if (type==3) ot(" orr r1,r0,r10 ;@ Set bit\n"); if (type==3) ot(" orr r1,r0,r11 ;@ Set bit\n");
ot("\n"); ot("\n");
EaWrite(11, 1,tea,size,0x003f,0,0); EaWrite(8, 1,tea,size,0x003f,0,0);
} }
OpEnd(sea,tea); OpEnd(sea,tea);
@ -146,9 +146,9 @@ int OpNeg(int op)
OpStart(op,ea); Cycles=size<2?4:6; OpStart(op,ea); Cycles=size<2?4:6;
if(ea >= 0x10) Cycles*=2; if(ea >= 0x10) Cycles*=2;
EaCalc (10,0x003f,ea,size,0,0); EaCalc (11,0x003f,ea,size,0,0);
if (type!=1) EaRead (10,0,ea,size,0x003f,0,0); // Don't need to read for 'clr' (or do we, for a dummy read?) if (type!=1) EaRead (11,0,ea,size,0x003f,0,0); // Don't need to read for 'clr' (or do we, for a dummy read?)
if (type==1) ot("\n"); if (type==1) ot("\n");
if (type==0) if (type==0)
@ -157,13 +157,13 @@ int OpNeg(int op)
GetXBit(1); GetXBit(1);
if(size!=2) ot(" mov r0,r0,asl #%i\n",size?16:24); if(size!=2) ot(" mov r0,r0,asl #%i\n",size?16:24);
ot(" rscs r1,r0,#0 ;@ do arithmetic\n"); ot(" rscs r1,r0,#0 ;@ do arithmetic\n");
ot(" orr r3,r9,#0xb0000000 ;@ for old Z\n"); ot(" orr r3,r10,#0xb0000000 ;@ for old Z\n");
OpGetFlags(1,1,0); OpGetFlags(1,1,0);
if(size!=2) { if(size!=2) {
ot(" movs r1,r1,asr #%i\n",size?16:24); ot(" movs r1,r1,asr #%i\n",size?16:24);
ot(" orreq r9,r9,#0x40000000 ;@ possily missed Z\n"); ot(" orreq r10,r10,#0x40000000 ;@ possily missed Z\n");
} }
ot(" andeq r9,r9,r3 ;@ fix Z\n"); ot(" andeq r10,r10,r3 ;@ fix Z\n");
ot("\n"); ot("\n");
} }
@ -171,7 +171,7 @@ int OpNeg(int op)
{ {
ot(";@ Clear:\n"); ot(";@ Clear:\n");
ot(" mov r1,#0\n"); ot(" mov r1,#0\n");
ot(" mov r9,#0x40000000 ;@ NZCV=0100\n"); ot(" mov r10,#0x40000000 ;@ NZCV=0100\n");
ot("\n"); ot("\n");
} }
@ -200,7 +200,7 @@ int OpNeg(int op)
} }
if (type==1) eawrite_check_addrerr=1; if (type==1) eawrite_check_addrerr=1;
EaWrite(10, 1,ea,size,0x003f,0,0); EaWrite(11, 1,ea,size,0x003f,0,0);
OpEnd(ea); OpEnd(ea);
@ -220,14 +220,14 @@ int OpSwap(int op)
OpStart(op); Cycles=4; OpStart(op); Cycles=4;
EaCalc (10,0x0007,ea,2,1); EaCalc (11,0x0007,ea,2,1);
EaRead (10, 0,ea,2,0x0007,1); EaRead (11, 0,ea,2,0x0007,1);
ot(" mov r1,r0,ror #16\n"); ot(" mov r1,r0,ror #16\n");
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0); OpGetFlags(0,0);
EaWrite(10, 1,8,2,0x0007,1); EaWrite(11, 1,8,2,0x0007,1);
OpEnd(); OpEnd();
@ -256,7 +256,7 @@ int OpTst(int op)
EaRead ( 0, 0,sea,size,0x003f,1); EaRead ( 0, 0,sea,size,0x003f,1);
ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");
ot(" mrs r9,cpsr ;@ r9=flags\n"); ot(" mrs r10,cpsr ;@ r10=flags\n");
ot("\n"); ot("\n");
OpEnd(sea); OpEnd(sea);
@ -280,16 +280,16 @@ int OpExt(int op)
OpStart(op); Cycles=4; OpStart(op); Cycles=4;
EaCalc (10,0x0007,ea,size+1,0,0); EaCalc (11,0x0007,ea,size+1,0,0);
EaRead (10, 0,ea,size+1,0x0007,0,0); EaRead (11, 0,ea,size+1,0x0007,0,0);
ot(" mov r0,r0,asl #%d\n",shift); ot(" mov r0,r0,asl #%d\n",shift);
ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");
ot(" mrs r9,cpsr ;@ r9=flags\n"); ot(" mrs r10,cpsr ;@ r10=flags\n");
ot(" mov r1,r0,asr #%d\n",shift); ot(" mov r1,r0,asr #%d\n",shift);
ot("\n"); ot("\n");
EaWrite(10, 1,ea,size+1,0x0007,0,0); EaWrite(11, 1,ea,size+1,0x0007,0,0);
OpEnd(); OpEnd();
return 0; return 0;
@ -334,18 +334,18 @@ int OpSet(int op)
case 1: // F case 1: // F
break; break;
case 2: // hi case 2: // hi
ot(" tst r9,#0x60000000 ;@ hi: !C && !Z\n"); ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n");
ot(" mvneq r1,r1\n"); ot(" mvneq r1,r1\n");
if (ea<8) ot(" subeq r5,r5,#2 ;@ Extra cycles\n"); if (ea<8) ot(" subeq r5,r5,#2 ;@ Extra cycles\n");
break; break;
case 3: // ls case 3: // ls
ot(" tst r9,#0x60000000 ;@ ls: C || Z\n"); ot(" tst r10,#0x60000000 ;@ ls: C || Z\n");
ot(" mvnne r1,r1\n"); ot(" mvnne r1,r1\n");
if (ea<8) ot(" subne r5,r5,#2 ;@ Extra cycles\n"); if (ea<8) ot(" subne r5,r5,#2 ;@ Extra cycles\n");
break; break;
default: default:
ot(";@ Is the condition true?\n"); ot(";@ Is the condition true?\n");
ot(" msr cpsr_flg,r9 ;@ ARM flags = 68000 flags\n"); ot(" msr cpsr_flg,r10 ;@ ARM flags = 68000 flags\n");
ot(" mvn%s r1,r1\n",cond[cc]); ot(" mvn%s r1,r1\n",cond[cc]);
if (ea<8) ot(" sub%s r5,r5,#2 ;@ Extra cycles\n",cond[cc]); if (ea<8) ot(" sub%s r5,r5,#2 ;@ Extra cycles\n",cond[cc]);
break; break;
@ -408,11 +408,11 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
OpGetFlags(0,0); OpGetFlags(0,0);
if (usereg) { // store X only if count is not 0 if (usereg) { // store X only if count is not 0
ot(" cmp %s,#0 ;@ shifting by 0?\n",pct); ot(" cmp %s,#0 ;@ shifting by 0?\n",pct);
ot(" biceq r9,r9,#0x20000000 ;@ if so, clear carry\n"); ot(" biceq r10,r10,#0x20000000 ;@ if so, clear carry\n");
ot(" strne r9,[r7,#0x4c] ;@ else Save X bit\n"); ot(" strne r10,[r7,#0x4c] ;@ else Save X bit\n");
} else { } else {
// count will never be 0 if we use immediate // count will never be 0 if we use immediate
ot(" str r9,[r7,#0x4c] ;@ Save X bit\n"); ot(" str r10,[r7,#0x4c] ;@ Save X bit\n");
} }
ot("\n"); ot("\n");
@ -421,7 +421,7 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
ot(";@ restore after right shift:\n"); ot(";@ restore after right shift:\n");
ot(" movs r0,r0,lsl #%d\n",32-(8<<size)); ot(" movs r0,r0,lsl #%d\n",32-(8<<size));
if (type) if (type)
ot(" orrmi r9,r9,#0x80000000 ;@ Potentially missed N flag\n"); ot(" orrmi r10,r10,#0x80000000 ;@ Potentially missed N flag\n");
ot("\n"); ot("\n");
} }
@ -432,7 +432,7 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
ot(" cmpne r3,r1,asr %s\n", pct); ot(" cmpne r3,r1,asr %s\n", pct);
ot(" eoreq r1,r0,r3\n"); // above check doesn't catch (-1)<<(32+), so we need this ot(" eoreq r1,r0,r3\n"); // above check doesn't catch (-1)<<(32+), so we need this
ot(" tsteq r1,#0x80000000\n"); ot(" tsteq r1,#0x80000000\n");
ot(" orrne r9,r9,#0x10000000\n"); ot(" orrne r10,r10,#0x10000000\n");
ot("\n"); ot("\n");
} }
} }
@ -443,7 +443,8 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
int wide=8<<size; int wide=8<<size;
// Roxr // Roxr
if(count == 1) { if(count == 1)
{
if(dir==0) { if(dir==0) {
if(size!=2) { if(size!=2) {
ot(" orr r0,r0,r0,lsr #%i\n", size?16:24); ot(" orr r0,r0,r0,lsr #%i\n", size?16:24);
@ -458,9 +459,9 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
OpGetFlags(0,1); OpGetFlags(0,1);
ot(" tst r3,#0x20000000\n"); ot(" tst r3,#0x20000000\n");
ot(" orrne r0,r0,#0x%x\n", 1<<(32-wide)); ot(" orrne r0,r0,#0x%x\n", 1<<(32-wide));
ot(" bicne r9,r9,#0x40000000 ;@ clear Z in case it got there\n"); ot(" bicne r10,r10,#0x40000000 ;@ clear Z in case it got there\n");
} }
ot(" bic r9,r9,#0x10000000 ;@ make suve V is clear\n"); ot(" bic r10,r10,#0x10000000 ;@ make suve V is clear\n");
return 0; return 0;
} }
@ -512,14 +513,14 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
if (shift) ot(" movs r0,r0,lsl #%d ;@ Shift up and get correct NC flags\n",shift); if (shift) ot(" movs r0,r0,lsl #%d ;@ Shift up and get correct NC flags\n",shift);
OpGetFlags(0,!usereg); OpGetFlags(0,!usereg);
if (usereg) { // store X only if count is not 0 if (usereg) { // store X only if count is not 0
ot(" str r9,[r7,#0x4c] ;@ if not 0, Save X bit\n"); ot(" str r10,[r7,#0x4c] ;@ if not 0, Save X bit\n");
ot(" b nozerox%.4x\n",op); ot(" b nozerox%.4x\n",op);
ot("norotx_%.4x%s\n",op,ms?"":":"); ot("norotx_%.4x%s\n",op,ms?"":":");
ot(" ldr r2,[r7,#0x4c]\n"); ot(" ldr r2,[r7,#0x4c]\n");
ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0); OpGetFlags(0,0);
ot(" and r2,r2,#0x20000000\n"); ot(" and r2,r2,#0x20000000\n");
ot(" orr r9,r9,r2 ;@ C = old_X\n"); ot(" orr r10,r10,r2 ;@ C = old_X\n");
ot("nozerox%.4x%s\n",op,ms?"":":"); ot("nozerox%.4x%s\n",op,ms?"":":");
} }
@ -555,7 +556,7 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
OpGetFlags(0,0); OpGetFlags(0,0);
if (dir) if (dir)
{ {
ot(" bic r9,r9,#0x30000000 ;@ clear CV\n"); ot(" bic r10,r10,#0x30000000 ;@ clear CV\n");
ot(";@ Get carry bit from bit 0:\n"); ot(";@ Get carry bit from bit 0:\n");
if (usereg) if (usereg)
{ {
@ -564,7 +565,7 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
} }
else else
ot(" tst r0,#1\n"); ot(" tst r0,#1\n");
ot(" orrne r9,r9,#0x20000000\n"); ot(" orrne r10,r10,#0x20000000\n");
} }
ot("\n"); ot("\n");
@ -602,12 +603,12 @@ int OpAsr(int op)
OpStart(op,ea,0,count<0); Cycles=size<2?6:8; OpStart(op,ea,0,count<0); Cycles=size<2?6:8;
EaCalc(10,0x0007, ea,size,1); EaCalc(11,0x0007, ea,size,1);
EaRead(10, 0, ea,size,0x0007,1); EaRead(11, 0, ea,size,0x0007,1);
EmitAsr(op,type,dir,count, size,usereg); EmitAsr(op,type,dir,count, size,usereg);
EaWrite(10, 0, ea,size,0x0007,1); EaWrite(11, 0, ea,size,0x0007,1);
opend_op_changes_cycles = (count<0); opend_op_changes_cycles = (count<0);
OpEnd(ea,0); OpEnd(ea,0);
@ -634,12 +635,12 @@ int OpAsrEa(int op)
OpStart(op,ea); Cycles=6; // EmitAsr() will add 2 OpStart(op,ea); Cycles=6; // EmitAsr() will add 2
EaCalc (10,0x003f,ea,size,1); EaCalc (11,0x003f,ea,size,1);
EaRead (10, 0,ea,size,0x003f,1); EaRead (11, 0,ea,size,0x003f,1);
EmitAsr(op,type,dir,1,size,0); EmitAsr(op,type,dir,1,size,0);
EaWrite(10, 0,ea,size,0x003f,1); EaWrite(11, 0,ea,size,0x003f,1);
OpEnd(ea); OpEnd(ea);
return 0; return 0;
@ -665,8 +666,8 @@ int OpTas(int op, int gen_special)
Cycles=4; Cycles=4;
if(ea>=8) Cycles+=10; if(ea>=8) Cycles+=10;
EaCalc (10,0x003f,ea,0,1); EaCalc (11,0x003f,ea,0,1);
EaRead (10, 1,ea,0,0x003f,1); EaRead (11, 1,ea,0,0x003f,1);
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0); OpGetFlags(0,0);
@ -678,7 +679,7 @@ int OpTas(int op, int gen_special)
#endif #endif
ot(" orr r1,r1,#0x80000000 ;@ set bit7\n"); ot(" orr r1,r1,#0x80000000 ;@ set bit7\n");
EaWrite(10, 1,ea,0,0x003f,1); EaWrite(11, 1,ea,0,0x003f,1);
#if CYCLONE_FOR_GENESIS #if CYCLONE_FOR_GENESIS
} }
#endif #endif

View file

@ -7,7 +7,7 @@
void OpFlagsToReg(int high) void OpFlagsToReg(int high)
{ {
ot(" ldr r0,[r7,#0x4c] ;@ X bit\n"); ot(" ldr r0,[r7,#0x4c] ;@ X bit\n");
ot(" mov r1,r9,lsr #28 ;@ ____NZCV\n"); ot(" mov r1,r10,lsr #28 ;@ ____NZCV\n");
ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n"); ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n");
ot(" tst r2,#1 ;@ 1 if C!=V\n"); ot(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n"); ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
@ -28,7 +28,7 @@ void OpRegToFlags(int high, int srh_reg)
ot(" tst r1,#1 ;@ 1 if C!=V\n"); ot(" tst r1,#1 ;@ 1 if C!=V\n");
ot(" eorne r0,r0,#3 ;@ ___XNZCV\n"); ot(" eorne r0,r0,#3 ;@ ___XNZCV\n");
ot(" str r2,[r7,#0x4c] ;@ Store X bit\n"); ot(" str r2,[r7,#0x4c] ;@ Store X bit\n");
ot(" mov r9,r0,lsl #28 ;@ r9=NZCV...\n"); ot(" mov r10,r0,lsl #28 ;@ r10=NZCV...\n");
if (high) if (high)
{ {
@ -126,7 +126,7 @@ int OpMove(int op)
if (movea==0) if (movea==0)
{ {
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");
ot(" mrs r9,cpsr ;@ r9=NZCV flags\n"); ot(" mrs r10,cpsr ;@ r10=NZCV flags\n");
ot("\n"); ot("\n");
} }
@ -135,11 +135,11 @@ int OpMove(int op)
eawrite_check_addrerr=1; eawrite_check_addrerr=1;
#if SPLIT_MOVEL_PD #if SPLIT_MOVEL_PD
if ((tea&0x38)==0x20 && size==2) { // -(An) if ((tea&0x38)==0x20 && size==2) { // -(An)
EaCalc (10,0x0e00,tea,size,0,0); EaCalc (8,0x0e00,tea,size,0,0);
ot(" mov r11,r1\n"); ot(" mov r11,r1\n");
ot(" add r0,r10,#2\n"); ot(" add r0,r8,#2\n");
EaWrite(0, 1,tea,1,0x0e00,0,0); EaWrite(0, 1,tea,1,0x0e00,0,0);
EaWrite(10, 11,tea,1,0x0e00,1); EaWrite(8, 11,tea,1,0x0e00,1);
} }
else else
#endif #endif
@ -276,7 +276,7 @@ int OpArithSr(int op)
// note: old srh is already in r11 (done by OpStart) // note: old srh is already in r11 (done by OpStart)
if (type==0) { if (type==0) {
ot(" orr r9,r9,r0,lsl #28\n"); ot(" orr r10,r10,r0,lsl #28\n");
ot(" orr r2,r2,r0,lsl #25 ;@ X bit\n"); ot(" orr r2,r2,r0,lsl #25 ;@ X bit\n");
if (size!=0) { if (size!=0) {
ot(" orr r1,r11,r0,lsr #8\n"); ot(" orr r1,r11,r0,lsr #8\n");
@ -284,13 +284,13 @@ int OpArithSr(int op)
} }
} }
if (type==1) { if (type==1) {
ot(" and r9,r9,r0,lsl #28\n"); ot(" and r10,r10,r0,lsl #28\n");
ot(" and r2,r2,r0,lsl #25 ;@ X bit\n"); ot(" and r2,r2,r0,lsl #25 ;@ X bit\n");
if (size!=0) if (size!=0)
ot(" and r1,r11,r0,lsr #8\n"); ot(" and r1,r11,r0,lsr #8\n");
} }
if (type==5) { if (type==5) {
ot(" eor r9,r9,r0,lsl #28\n"); ot(" eor r10,r10,r0,lsl #28\n");
ot(" eor r2,r2,r0,lsl #25 ;@ X bit\n"); ot(" eor r2,r2,r0,lsl #25 ;@ X bit\n");
if (size!=0) { if (size!=0) {
ot(" eor r1,r11,r0,lsr #8\n"); ot(" eor r1,r11,r0,lsr #8\n");
@ -333,10 +333,10 @@ int OpPea(int op)
OpStart(op,ea); OpStart(op,ea);
ot(" ldr r10,[r7,#0x3c]\n"); ot(" ldr r11,[r7,#0x3c]\n");
EaCalc (1,0x003f, ea,0); EaCalc (1,0x003f, ea,0);
ot("\n"); ot("\n");
ot(" sub r0,r10,#4 ;@ Predecrement A7\n"); ot(" sub r0,r11,#4 ;@ Predecrement A7\n");
ot(" str r0,[r7,#0x3c] ;@ Save A7\n"); ot(" str r0,[r7,#0x3c] ;@ Save A7\n");
ot("\n"); ot("\n");
MemHandler(1,2); // Write 32-bit MemHandler(1,2); // Write 32-bit
@ -376,11 +376,18 @@ int OpMovem(int op)
OpStart(op,ea,0,1); OpStart(op,ea,0,1);
#if !MEMHANDLERS_NEED_PREV_PC
// must save PC, need a spare register
ot(" str r4,[r7,#0x40] ;@ Save PC\n");
#endif
#if !MEMHANDLERS_NEED_CYCLES
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
#endif
ot(" ldrh r11,[r4],#2 ;@ r11=register mask\n"); ot(" ldrh r11,[r4],#2 ;@ r11=register mask\n");
ot(";@ r10=Register Index*4:\n"); ot(";@ r4=Register Index*4:\n");
if (decr) ot(" mov r10,#0x40 ;@ order reversed for -(An)\n"); if (decr) ot(" mov r4,#0x40 ;@ order reversed for -(An)\n");
else ot(" mov r10,#-4\n"); else ot(" mov r4,#-4\n");
ot("\n"); ot("\n");
ot(";@ Get the address into r6:\n"); ot(";@ Get the address into r6:\n");
@ -399,7 +406,7 @@ int OpMovem(int op)
ot("\n"); ot("\n");
ot("Movemloop%.4x%s\n",op, ms?"":":"); ot("Movemloop%.4x%s\n",op, ms?"":":");
ot(" add r10,r10,#%d ;@ r10=Next Register\n",decr?-4:4); ot(" add r4,r4,#%d ;@ r4=Next Register\n",decr?-4:4);
ot(" movs r11,r11,lsr #1\n"); ot(" movs r11,r11,lsr #1\n");
ot(" bcc Movemloop%.4x\n",op); ot(" bcc Movemloop%.4x\n",op);
ot("\n"); ot("\n");
@ -411,17 +418,17 @@ int OpMovem(int op)
ot(" ;@ Copy memory to register:\n",1<<size); ot(" ;@ Copy memory to register:\n",1<<size);
earead_check_addrerr=0; // already checked earead_check_addrerr=0; // already checked
EaRead (6,0,ea,size,0x003f); EaRead (6,0,ea,size,0x003f);
ot(" str r0,[r7,r10] ;@ Save value into Dn/An\n"); ot(" str r0,[r7,r4] ;@ Save value into Dn/An\n");
} }
else else
{ {
ot(" ;@ Copy register to memory:\n",1<<size); ot(" ;@ Copy register to memory:\n",1<<size);
ot(" ldr r1,[r7,r10] ;@ Load value from Dn/An\n"); ot(" ldr r1,[r7,r4] ;@ Load value from Dn/An\n");
#if SPLIT_MOVEL_PD #if SPLIT_MOVEL_PD
if (decr && size==2) { // -(An) if (decr && size==2) { // -(An)
ot(" add r0,r6,#2\n"); ot(" add r0,r6,#2\n");
EaWrite(0,1,ea,1,0x003f,0,0); EaWrite(0,1,ea,1,0x003f,0,0);
ot(" ldr r1,[r7,r10] ;@ Load value from Dn/An\n"); ot(" ldr r1,[r7,r4] ;@ Load value from Dn/An\n");
ot(" mov r0,r6\n"); ot(" mov r0,r6\n");
EaWrite(0,1,ea,1,0x003f,1); EaWrite(0,1,ea,1,0x003f,1);
} }
@ -447,7 +454,8 @@ int OpMovem(int op)
} }
ot("NoRegs%.4x%s\n",op, ms?"":":"); ot("NoRegs%.4x%s\n",op, ms?"":":");
ot(" ldr r6,=CycloneJumpTab ;@ restore Opcode Jump table\n"); ot(" ldr r4,[r7,#0x40]\n");
ot(" ldr r6,[r7,#0x54] ;@ restore Opcode Jump table\n");
ot("\n"); ot("\n");
if(dir) { // er if(dir) { // er
@ -462,7 +470,6 @@ int OpMovem(int op)
opend_op_changes_cycles = 1; opend_op_changes_cycles = 1;
OpEnd(ea); OpEnd(ea);
ltorg();
ot("\n"); ot("\n");
return 0; return 0;
@ -514,7 +521,7 @@ int OpMoveq(int op)
ot(" movs r0,r8,asl #24\n"); ot(" movs r0,r8,asl #24\n");
ot(" and r1,r8,#0x0e00\n"); ot(" and r1,r8,#0x0e00\n");
ot(" mov r0,r0,asr #24 ;@ Sign extended Quick value\n"); ot(" mov r0,r0,asr #24 ;@ Sign extended Quick value\n");
ot(" mrs r9,cpsr ;@ r9=NZ flags\n"); ot(" mrs r10,cpsr ;@ r10=NZ flags\n");
ot(" str r0,[r7,r1,lsr #7] ;@ Store into Dn\n"); ot(" str r0,[r7,r1,lsr #7] ;@ Store into Dn\n");
ot("\n"); ot("\n");
@ -541,15 +548,15 @@ int OpExg(int op)
OpStart(op); Cycles=6; OpStart(op); Cycles=6;
ot(" and r10,r8,#0x0e00 ;@ Find T register\n"); ot(" and r2,r8,#0x0e00 ;@ Find T register\n");
ot(" and r11,r8,#0x000f ;@ Find S register\n"); ot(" and r3,r8,#0x000f ;@ Find S register\n");
if (type==0x48) ot(" orr r10,r10,#0x1000 ;@ T is an address register\n"); if (type==0x48) ot(" orr r2,r2,#0x1000 ;@ T is an address register\n");
ot("\n"); ot("\n");
ot(" ldr r0,[r7,r10,lsr #7] ;@ Get T\n"); ot(" ldr r0,[r7,r2,lsr #7] ;@ Get T\n");
ot(" ldr r1,[r7,r11,lsl #2] ;@ Get S\n"); ot(" ldr r1,[r7,r3,lsl #2] ;@ Get S\n");
ot("\n"); ot("\n");
ot(" str r0,[r7,r11,lsl #2] ;@ T->S\n"); ot(" str r0,[r7,r3,lsl #2] ;@ T->S\n");
ot(" str r1,[r7,r10,lsr #7] ;@ S->T\n"); ot(" str r1,[r7,r2,lsr #7] ;@ S->T\n");
ot("\n"); ot("\n");
OpEnd(); OpEnd();
@ -578,44 +585,48 @@ int OpMovep(int op)
OpStart(op,ea); OpStart(op,ea);
if(dir) { // reg to mem if(dir) // reg to mem
{
EaCalcReadNoSE(-1,11,rea,size,0x0e00); EaCalcReadNoSE(-1,11,rea,size,0x0e00);
EaCalc(10,0x000f,ea,size); EaCalc(8,0x000f,ea,size);
if(size==2) { // if operand is long if(size==2) { // if operand is long
ot(" mov r1,r11,lsr #24 ;@ first byte\n"); ot(" mov r1,r11,lsr #24 ;@ first byte\n");
EaWrite(10,1,ea,0,0x000f); // store first byte EaWrite(8,1,ea,0,0x000f); // store first byte
ot(" add r0,r10,#%i\n",(aadd+=2)); ot(" add r0,r8,#%i\n",(aadd+=2));
ot(" mov r1,r11,lsr #16 ;@ second byte\n"); ot(" mov r1,r11,lsr #16 ;@ second byte\n");
EaWrite(0,1,ea,0,0x000f); // store second byte EaWrite(0,1,ea,0,0x000f); // store second byte
ot(" add r0,r10,#%i\n",(aadd+=2)); ot(" add r0,r8,#%i\n",(aadd+=2));
} else { } else {
ot(" mov r0,r10\n"); ot(" mov r0,r8\n");
} }
ot(" mov r1,r11,lsr #8 ;@ first or third byte\n"); ot(" mov r1,r11,lsr #8 ;@ first or third byte\n");
EaWrite(0,1,ea,0,0x000f); EaWrite(0,1,ea,0,0x000f);
ot(" add r0,r10,#%i\n",(aadd+=2)); ot(" add r0,r8,#%i\n",(aadd+=2));
ot(" and r1,r11,#0xff\n"); ot(" and r1,r11,#0xff\n");
EaWrite(0,1,ea,0,0x000f); EaWrite(0,1,ea,0,0x000f);
} else { // mem to reg }
EaCalc(10,0x000f,ea,size,1); else // mem to reg
EaRead(10,11,ea,0,0x000f,1); // read first byte {
ot(" add r0,r10,#2\n"); EaCalc(6,0x000f,ea,size,1);
EaRead(6,11,ea,0,0x000f,1); // read first byte
ot(" add r0,r6,#2\n");
EaRead(0,1,ea,0,0x000f,1); // read second byte EaRead(0,1,ea,0,0x000f,1); // read second byte
if(size==2) { // if operand is long if(size==2) { // if operand is long
ot(" orr r11,r11,r1,lsr #8 ;@ second byte\n"); ot(" orr r11,r11,r1,lsr #8 ;@ second byte\n");
ot(" add r0,r10,#4\n"); ot(" add r0,r6,#4\n");
EaRead(0,1,ea,0,0x000f,1); EaRead(0,1,ea,0,0x000f,1);
ot(" orr r11,r11,r1,lsr #16 ;@ third byte\n"); ot(" orr r11,r11,r1,lsr #16 ;@ third byte\n");
ot(" add r0,r10,#6\n"); ot(" add r0,r6,#6\n");
EaRead(0,1,ea,0,0x000f,1); EaRead(0,1,ea,0,0x000f,1);
ot(" orr r1,r11,r1,lsr #24 ;@ fourth byte\n"); ot(" orr r1,r11,r1,lsr #24 ;@ fourth byte\n");
} else { } else {
ot(" orr r1,r11,r1,lsr #8 ;@ second byte\n"); ot(" orr r1,r11,r1,lsr #8 ;@ second byte\n");
} }
// store the result // store the result
EaCalc(11,0x0e00,rea,size,1); // reg number -> r11 EaCalc(0,0x0e00,rea,size,1);
EaWrite(11,1,rea,size,0x0e00,1); EaWrite(0,1,rea,size,0x0e00,1);
ot(" ldr r6,[r7,#0x54]\n");
} }
Cycles=(size==2)?24:16; Cycles=(size==2)?24:16;
@ -653,17 +664,17 @@ int OpStopReset(int op)
Cycles = 132; Cycles = 132;
#if USE_RESET_CALLBACK #if USE_RESET_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n"); ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n"); ot(" mov r1,r10,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n"); ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x90] ;@ ResetCallback\n"); ot(" ldr r11,[r7,#0x90] ;@ ResetCallback\n");
ot(" tst r11,r11\n"); ot(" tst r11,r11\n");
ot(" movne lr,pc\n"); ot(" movne lr,pc\n");
ot(" bxne r11 ;@ call ResetCallback if it is defined\n"); ot(" bxne r11 ;@ call ResetCallback if it is defined\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Load Flags (NZCV)\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n"); ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n"); ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" mov r9,r9,lsl #28\n"); ot(" mov r10,r10,lsl #28\n");
ot("\n"); ot("\n");
#endif #endif
} }