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 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 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 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)

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
r7 : Pointer to Cpu Context
r8 : Current Opcode
r9 : Flags (NZCV) in highest four bits
(r10 : Temporary source value or Memory Base)
r10 : Flags (NZCV) in highest four bits
(r11 : Temporary register)
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...
@ -476,6 +477,10 @@ Thanks to...
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
- Reduced amount of code in opcode handlers by ~23% by doing the following:
- Removed duplicate opcode handlers

View file

@ -3,7 +3,7 @@
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 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
@ -87,10 +87,10 @@ static void AddressErrorWrapper(char rw, char *dataprg, int iw)
{
ot("ExceptionAddressError_%c_%s%s\n", rw, dataprg, ms?"":":");
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(" tst r1,#0x20\n");
ot(" orrne r10,r10,#4\n");
ot(" orrne r6,r6,#4\n");
ot(" b ExceptionAddressError\n");
ot("\n");
}
@ -119,18 +119,19 @@ static void PrintFramework()
if (ms) 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(" ;@ 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 r5,[r7,#0x5c] ;@ r5 = Cycles\n");
ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n");
ot(" ;@ r8 = Current Opcode\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(" ;@ r10 = Source value / Memory Base\n");
ot(" mov r10,r10,lsl #28;@ r10 = Flags 0xf0000000, cpsr format\n");
ot(" ;@ r11 = Source value / Memory Base\n");
ot(" str r6,[r7,#0x54] ;@ make a copy to avoid literal pools\n");
ot("\n");
#if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE
ot(" mov r2,#0\n");
@ -160,7 +161,7 @@ static void PrintFramework()
ot(";@ stopped or halted\n");
ot(" mov r5,#0\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");
@ -170,16 +171,16 @@ static void PrintFramework()
ot("CycloneEndNoBack%s\n", ms?"":":");
#if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE
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(" bxne r1 ;@ jump to alternative CycloneEnd\n");
#else
ot(" mov r9,r9,lsr #28\n");
ot(" mov r10,r10,lsr #28\n");
#endif
ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" ldmia sp!,{r4-r11,pc}\n");
ot(" strb r10,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" ldmia sp!,{r4-r8,r10,r11,pc}\n");
ltorg();
ot("\n");
ot("\n");
@ -360,13 +361,13 @@ static void PrintFramework()
ot(" movle r0,#0\n");
ot(" bxle lr ;@ no ints\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 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(" 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(" str r2,[r7,#0x98] ;@ set custom CycloneEnd\n");
ot(" b CycloneDoInterrupt\n");
@ -374,8 +375,8 @@ static void PrintFramework()
ot("CycloneFlushIrqEnd%s\n", ms?"":":");
ot(" rsb r0,r5,#0\n");
ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n");
ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" ldmia sp!,{r4,r5,r7-r11,lr}\n");
ot(" strb r10,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" ldmia sp!,{r4,r5,r7,r8,r10,r11,lr}\n");
ot(" bx lr\n");
ot("\n");
ot("\n");
@ -418,14 +419,14 @@ static void PrintFramework()
ot(" orr r2,r2,#4 ;@ set activity bit: 'not processing instruction'\n");
#endif
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("\n");
// 3. Save the current processor context.
ot(" ldr r1,[r7,#0x60] ;@ Get Memory base\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(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n");
ot(" streq r11,[r7,#0x48]\n");
@ -436,13 +437,13 @@ static void PrintFramework()
MemHandler(1,2);
ot(";@ Push old SR:\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(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
ot(" and r0,r0,#0x20000000\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(" str r0,[r7,#0x3c] ;@ Save A7\n");
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");
#if INT_ACK_NEEDS_STUFF
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(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
#endif
@ -481,7 +482,7 @@ static void PrintFramework()
#endif
ot(" mov r0,r0,lsl #2 ;@ get vector address\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");
MemHandler(0,2,0,0);
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");
#if USE_CHECKPC_CALLBACK
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");
#if EMULATE_ADDRESS_ERRORS_JUMP
ot(" mov r4,r0\n");
@ -498,7 +499,7 @@ static void PrintFramework()
ot(" bic r4,r0,#1\n");
#endif
#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
ot(" bic r4,r4,#1\n");
#endif
@ -511,6 +512,7 @@ static void PrintFramework()
ot(" tst r4,#1\n");
ot(" bne ExceptionAddressError_r_prg_r4\n");
#endif
ot(" ldr r6,[r7,#0x54]\n");
ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n");
ot(" subs r5,r5,#44 ;@ Subtract cycles\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");
// 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(" 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(" bic r2,r2,#3 ;@ clear stopped and trace states\n");
ot(" str r2,[r7,#0x58]\n");
@ -537,7 +539,7 @@ static void PrintFramework()
// 3. Save the current processor context.
ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n");
ot(" tst r10,#0x20\n");
ot(" tst r6,#0x20\n");
ot(";@ get our SP:\n");
ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n");
ot(" streq r0,[r7,#0x48]\n");
@ -550,14 +552,14 @@ static void PrintFramework()
MemHandler(1,2);
ot(";@ Push old SR:\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(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
ot(" and r0,r0,#0x20000000\n");
ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\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(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0);
@ -591,6 +593,7 @@ static void PrintFramework()
ot(" tst r4,#1\n");
ot(" bne ExceptionAddressError_r_prg_r4\n");
#endif
ot(" ldr r6,[r7,#0x54]\n");
ot(" bx r11 ;@ Return\n");
ot("\n");
@ -606,14 +609,14 @@ static void PrintFramework()
ot("ExceptionAddressError_r_prg_r4%s\n", ms?"":":");
ot(" ldr r1,[r7,#0x44]\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(" tst r1,#0x20\n");
ot(" orrne r10,r10,#4\n");
ot(" orrne r6,r6,#4\n");
ot("\n");
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.
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(" bic r2,r2,#3 ;@ clear stopped and trace states\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");
#if EMULATE_HALT
ot(" tst r2,#8\n");
@ -635,13 +638,13 @@ static void PrintFramework()
#else
ot(" str r2,[r7,#0x58]\n");
#endif
ot(" and r9,r9,#0xf0000000\n");
ot(" orr r9,r9,r0,lsl #4 ;@ some preparations for SR push\n");
ot(" and r10,r10,#0xf0000000\n");
ot(" orr r10,r10,r0,lsl #4 ;@ some preparations for SR push\n");
ot("\n");
// 3. Save the current processor context + additional information.
ot(" ldr r0,[r7,#0x3c] ;@ Get A7\n");
ot(" tst r9,#0x200\n");
ot(" tst r10,#0x200\n");
ot(";@ get our SP:\n");
ot(" ldreq r2,[r7,#0x48] ;@ ...or OSP as our stack pointer\n");
ot(" streq r0,[r7,#0x48]\n");
@ -656,14 +659,14 @@ static void PrintFramework()
// SR
ot(";@ Push old SR:\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(" tst r2,#1 ;@ 1 if C!=V\n");
ot(" eorne r1,r1,#3 ;@ ____NZVC\n");
ot(" and r0,r0,#0x20000000\n");
ot(" orr r1,r1,r0,lsr #25 ;@ ___XNZVC\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(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0);
@ -684,7 +687,7 @@ static void PrintFramework()
// information word
ot(";@ Push info word:\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(" str r0,[r7,#0x3c] ;@ Save A7\n");
MemHandler(1,1,0,0);
@ -713,6 +716,7 @@ static void PrintFramework()
#endif
// 4. Resume execution.
ot(" ldr r6,[r7,#0x54]\n");
ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n");
ot(" subs r5,r5,#50 ;@ Subtract cycles\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 r0,[r7,#0x9c] ;@ restore cycles\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(" str r1,[r7,#0x98]\n");
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
#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");
#endif
FlushPC();
@ -847,8 +851,8 @@ int MemHandler(int type,int size,int addrreg,int need_addrerr_check)
ot(" handler\n");
#if MEMHANDLERS_CHANGE_FLAGS
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n");
ot(" mov r9,r9,lsl #28\n");
ot(" ldrb r10,[r7,#0x46] ;@ r10 = Load Flags (NZCV)\n");
ot(" mov r10,r10,lsl #28\n");
#endif
#if MEMHANDLERS_CHANGE_PC
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
@ -877,17 +881,17 @@ static void PrintOpcodes()
#endif
#if USE_UNRECOGNIZED_CALLBACK
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(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\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 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(" moveq r0,#4\n");
ot(" bleq Exception\n");
@ -904,17 +908,17 @@ static void PrintOpcodes()
ot(" sub r4,r4,#2\n");
#if USE_AFLINE_CALLBACK
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(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\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 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(" moveq r0,#0x0a\n");
ot(" bleq Exception\n");
@ -930,17 +934,17 @@ static void PrintOpcodes()
ot(" sub r4,r4,#2\n");
#if USE_AFLINE_CALLBACK
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(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\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 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(" moveq r0,#0x0b\n");
ot(" bleq Exception\n");

View file

@ -133,17 +133,17 @@ int OpBase(int op,int size,int sepa)
// Get flags, trashes r2
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)
{
ot(" str r9,[r7,#0x4c] ;@ Save X bit\n");
ot(" str r10,[r7,#0x4c] ;@ Save X bit\n");
}
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
EaCalcReadNoSE(10,0,ea,size,0x003f);
EaCalcReadNoSE(11,0,ea,size,0x003f);
shift=32-(8<<size);
@ -131,7 +131,7 @@ int OpAddq(int op)
if ((ea&0x38)!=0x08) OpGetFlags(type,1);
ot("\n");
EaWrite(10, 1, ea,size,0x003f,1);
EaWrite(11, 1, ea,size,0x003f,1);
OpEnd(ea);
@ -166,9 +166,9 @@ int OpArithReg(int op)
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");
if (type==0) strop = "orr";
@ -189,8 +189,8 @@ int OpArithReg(int op)
ot(";@ Save result:\n");
if (size<2) ot(" mov r1,r1,asr #%d\n",size?16:24);
if (dir) EaWrite(10, 1, ea,size,0x003f,0,0);
else EaWrite(10, 1,rea,size,0x0e00,0,0);
if (dir) EaWrite(11, 1, ea,size,0x003f,0,0);
else EaWrite(11, 1,rea,size,0x0e00,0,0);
if(rea==ea) {
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);
EaCalc(10,0x0e00,rea, 2);
EaRead(10, 2,rea, 2,0x0e00);
EaCalc(11,0x0e00,rea, 2);
EaRead(11, 2,rea, 2,0x0e00);
ot(" movs r1,r0,asl #16\n");
if (type==0) // div
{
// 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("\n");
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(" orrmi r11,r11,#2\n");
ot(" orrmi r12,r12,#2\n");
ot(" rsbmi r2,r2,#0 ;@ Make r2 positive\n");
ot("\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("\n");
ot(";@ detect the nasty 0x80000000 / -1 situation\n");
@ -292,17 +292,17 @@ int OpMul(int op)
if (sign)
{
// sign correction
ot(" and r1,r11,#1\n");
ot(" teq r1,r11,lsr #1\n");
ot(" and r1,r12,#1\n");
ot(" teq r1,r12,lsr #1\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("\n");
// signed overflow check
ot(" mov r1,r3,asl #16\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("\n");
ot("wrendofop%.4x%s\n",op,ms?"":":");
@ -311,7 +311,7 @@ int OpMul(int op)
{
// overflow check
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("\n");
}
@ -338,7 +338,7 @@ int OpMul(int op)
}
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?"":":");
OpEnd(ea);
@ -392,19 +392,19 @@ int OpAbcd(int op)
{
ot(";@ Get src/dest EA vals\n");
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);
}
else
{
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);
ot(" mov r10,r10,asl #24\n");
ot(" mov r6,r6,asl #24\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)
{
@ -412,59 +412,61 @@ int OpAbcd(int op)
ot(" mov r3,#0x00f00000\n");
ot(" and r2,r3,r1,lsr #4\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(" addne r0,r0,#0x00100000\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(" addhi r0,r0,#0x00600000 ;@ Decimal adjust units\n");
ot(" mov r2,r1,lsr #28\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(" 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(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n");
// ot(" orr r9,r9,r3,lsl #4 ;@ V\n");
// ot(" and r3,r10,r0,lsr #3 ;@ Undefined V behavior part II\n");
// ot(" orr r10,r10,r3,lsl #4 ;@ V\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(" bicne r9,r9,#0x40000000 ;@ Z flag\n");
ot(" orrmi r10,r10,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does
ot(" bicne r10,r10,#0x40000000 ;@ Z flag\n");
}
else
{
ot(" ldr r0,[r7,#0x4c] ;@ Get X bit\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(" and r0,r3,r1,lsr #4\n");
ot(" sub r0,r0,r2\n");
ot(" subne r0,r0,#0x00100000\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(" subhi r0,r0,#0x00600000 ;@ Decimal adjust units\n");
ot(" mov r2,r1,lsr #28\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(" 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(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n");
// ot(" orr r9,r9,r3,lsl #4 ;@ V\n");
// ot(" and r3,r10,r0,lsr #3 ;@ Undefined V behavior part II\n");
// ot(" orr r10,r10,r3,lsl #4 ;@ V\n");
ot(" movs r0,r0,lsl #4\n");
// ot(" orrmi r9,r9,#0x80000000 ;@ Undefined N behavior\n");
ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n");
// ot(" orrmi r10,r10,#0x80000000 ;@ Undefined N behavior\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");
EaWrite(11, 0, dea,0,0x0e00,1);
ot(" ldr r6,[r7,#0x54]\n");
OpEnd(sea,dea);
return 0;
@ -486,11 +488,11 @@ int OpNbcd(int op)
OpStart(op,ea); Cycles=6;
if(ea >= 8) Cycles+=2;
EaCalcReadNoSE(10,0,ea,0,0x003f);
EaCalcReadNoSE(6,0,ea,0,0x003f);
// this is rewrite of Musashi's code
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(" and r2,r2,#0x20000000\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(" and r3,r3,r11,lsr #31 ;@ Undefined V behavior part II\n",op);
ot(" movs r1,r11,asr #24\n");
ot(" bicne r9,r9,#0x40000000 ;@ Z\n");
ot(" orr r9,r9,r3,lsl #28 ;@ save V\n",op);
ot(" orr r9,r9,#0x20000000 ;@ C\n");
ot(" bicne r10,r10,#0x40000000 ;@ Z\n");
ot(" orr r10,r10,r3,lsl #28 ;@ save V\n",op);
ot(" orr r10,r10,#0x20000000 ;@ C\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(" tst r11,r11\n");
ot(" orrmi r9,r9,#0x80000000 ;@ N\n");
ot(" str r9,[r7,#0x4c] ;@ Save X\n");
ot(" orrmi r10,r10,#0x80000000 ;@ N\n");
ot(" str r10,[r7,#0x4c] ;@ Save X\n");
ot("\n");
ot(" ldr r6,[r7,#0x54]\n");
OpEnd(ea);
return 0;
@ -556,12 +559,12 @@ int OpAritha(int op)
//if (type == 1)
{
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
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);
}
#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) asr=(char *)(size?",asr #16":",asr #24");
if (type==0) ot(" sub r11,r11,r0%s\n",asr);
if (type==1) ot(" cmp r11,r0%s ;@ Defines NZCV\n",asr);
if (type==0) ot(" sub r1,r1,r0%s\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==2) ot(" add r11,r11,r0%s\n",asr);
if (type==2) ot(" add r1,r1,r0%s\n",asr);
ot("\n");
if (type!=1) EaWrite(10, 11, dea,2,0x0e00);
if (type!=1) EaWrite(11, 1, dea,2,0x0e00);
OpEnd(sea);
@ -600,7 +603,7 @@ int OpAddx(int op)
if (EaCanRead(sea,size)==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
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");
EaCalc (0,0x000f, sea,size,1);
EaRead (0, 11, sea,size,0x000f,1);
EaCalcReadNoSE(10,0,dea,size,0x0e00);
EaRead (0, 6, sea,size,0x000f,1);
EaCalcReadNoSE(11,0,dea,size,0x0e00);
}
else
{
ot(";@ Get src/dest reg vals\n");
EaCalcReadNoSE(-1,11,sea,size,0x0007);
EaCalcReadNoSE(10,0,dea,size,0x0e00);
if (size<2) ot(" mov r11,r11,asl #%d\n\n",size?16:24);
EaCalcReadNoSE(-1,6,sea,size,0x0007);
EaCalcReadNoSE(11,0,dea,size,0x0e00);
if (size<2) ot(" mov r6,r6,asl #%d\n\n",size?16: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(" 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");
}
if (type==0) ot(" rscs r1,r11,r0%s\n",asl);
if (type==1) ot(" adcs r1,r11,r0%s\n",asl);
ot(" orr r3,r9,#0xb0000000 ;@ for old Z\n");
if (type==0) ot(" rscs r1,r6,r0%s\n",asl);
if (type==1) ot(" adcs r1,r6,r0%s\n",asl);
ot(" orr r3,r10,#0xb0000000 ;@ for old Z\n");
OpGetFlags(type==0,1,0); // subtract
if (size<2) {
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(";@ 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);
return 0;
@ -691,8 +695,8 @@ int OpCmpEor(int op)
if(size>=2) Cycles+=2;
}
ot(";@ Get EA into r10 and value into r0:\n");
EaCalcReadNoSE(eor?10:-1,0,ea,size,0x003f);
ot(";@ Get EA into r11 and value into r0:\n");
EaCalcReadNoSE(eor?11:-1,0,ea,size,0x003f);
ot(";@ Get register operand into r1:\n");
EaCalcReadNoSE(-1,1,rea,size,0x0e00);
@ -711,7 +715,7 @@ int OpCmpEor(int op)
OpGetFlags(eor==0,0); // Cmp like subtract
ot("\n");
if (eor) EaWrite(10, 1,ea,size,0x003f,1);
if (eor) EaWrite(11, 1,ea,size,0x003f,1);
OpEnd(ea);
return 0;
@ -735,16 +739,16 @@ int OpCmpm(int op)
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);
EaRead (0, 10, sea,size,0x0007,1);
EaRead (0, 11, sea,size,0x0007,1);
ot(";@ Get dst operand into r0:\n");
EaCalcReadNoSE(-1,0,dea,size,0x0e00);
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
ot("\n");
@ -778,7 +782,7 @@ int OpChk(int op)
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);
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);
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");
OpGetFlags(0,0);
@ -796,12 +800,12 @@ int OpChk(int op)
ot(" bmi chktrap%.4x\n",op);
ot(";@ Do arithmetic:\n");
ot(" bic r9,r9,#0x80000000 ;@ N\n");
ot(" bic r10,r10,#0x80000000 ;@ N\n");
ot(" cmp r1,r0\n");
ot(" bgt chktrap%.4x\n",op);
ot(";@ old N remains\n");
ot(" orr r9,r9,r3\n");
ot(" orr r10,r10,r3\n");
OpEnd(ea);
ot("chktrap%.4x%s ;@ CHK exception:\n",op,ms?"":":");

View file

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

View file

@ -36,28 +36,28 @@ int OpBtstReg(int op)
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)
ot(" and r10,r10,#7 ;@ mem - do mod 8\n"); // size always 0
else ot(" and r10,r10,#31 ;@ reg - do mod 32\n"); // size always 2
if (tea>=0x11)
ot(" and r11,r11,#7 ;@ mem - do mod 8\n"); // size always 0
else ot(" and r11,r11,#31 ;@ reg - do mod 32\n"); // size always 2
ot("\n");
ot(" mov r1,#1\n");
ot(" tst r0,r1,lsl r10 ;@ Do arithmetic\n");
ot(" bicne r9,r9,#0x40000000\n");
ot(" orreq r9,r9,#0x40000000 ;@ Get Z flag\n");
ot(" tst r0,r1,lsl r11 ;@ Do arithmetic\n");
ot(" bicne r10,r10,#0x40000000\n");
ot(" orreq r10,r10,#0x40000000 ;@ Get Z flag\n");
ot("\n");
if (type>0)
{
if (type==1) ot(" eor r1,r0,r1,lsl r10 ;@ Toggle bit\n");
if (type==2) ot(" bic r1,r0,r1,lsl r10 ;@ Clear bit\n");
if (type==3) ot(" orr r1,r0,r1,lsl r10 ;@ Set bit\n");
if (type==1) ot(" eor r1,r0,r1,lsl r11 ;@ Toggle bit\n");
if (type==2) ot(" bic r1,r0,r1,lsl r11 ;@ Clear bit\n");
if (type==3) ot(" orr r1,r0,r1,lsl r11 ;@ Set bit\n");
ot("\n");
EaWrite(11, 1,tea,size,0x003f,0,0);
EaWrite(8,1,tea,size,0x003f,0,0);
}
OpEnd(tea);
@ -92,12 +92,12 @@ int OpBtstImm(int op)
ot("\n");
EaCalcReadNoSE(-1,0,sea,0,0);
ot(" mov r10,#1\n");
ot(" bic r9,r9,#0x40000000 ;@ Blank Z flag\n");
if (tea>=0x10)
ot(" mov r11,#1\n");
ot(" bic r10,r10,#0x40000000 ;@ Blank Z flag\n");
if (tea>=0x11)
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
ot(" mov r10,r10,lsl r0 ;@ Make bit mask\n");
ot(" mov r11,r11,lsl r0 ;@ Make bit mask\n");
ot("\n");
if(type==1||type==3) {
@ -107,18 +107,18 @@ int OpBtstImm(int op)
if(size>=2) Cycles+=2;
}
EaCalcReadNoSE((type>0)?11:-1,0,tea,size,0x003f);
ot(" tst r0,r10 ;@ Do arithmetic\n");
ot(" orreq r9,r9,#0x40000000 ;@ Get Z flag\n");
EaCalcReadNoSE((type>0)?8:-1,0,tea,size,0x003f);
ot(" tst r0,r11 ;@ Do arithmetic\n");
ot(" orreq r10,r10,#0x40000000 ;@ Get Z flag\n");
ot("\n");
if (type>0)
{
if (type==1) ot(" eor r1,r0,r10 ;@ Toggle bit\n");
if (type==2) ot(" bic r1,r0,r10 ;@ Clear bit\n");
if (type==3) ot(" orr r1,r0,r10 ;@ Set bit\n");
if (type==1) ot(" eor r1,r0,r11 ;@ Toggle bit\n");
if (type==2) ot(" bic r1,r0,r11 ;@ Clear bit\n");
if (type==3) ot(" orr r1,r0,r11 ;@ Set bit\n");
ot("\n");
EaWrite(11, 1,tea,size,0x003f,0,0);
EaWrite(8, 1,tea,size,0x003f,0,0);
}
OpEnd(sea,tea);
@ -146,9 +146,9 @@ int OpNeg(int op)
OpStart(op,ea); Cycles=size<2?4:6;
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==0)
@ -157,13 +157,13 @@ int OpNeg(int op)
GetXBit(1);
if(size!=2) ot(" mov r0,r0,asl #%i\n",size?16:24);
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);
if(size!=2) {
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");
}
@ -171,7 +171,7 @@ int OpNeg(int op)
{
ot(";@ Clear:\n");
ot(" mov r1,#0\n");
ot(" mov r9,#0x40000000 ;@ NZCV=0100\n");
ot(" mov r10,#0x40000000 ;@ NZCV=0100\n");
ot("\n");
}
@ -200,7 +200,7 @@ int OpNeg(int op)
}
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);
@ -220,14 +220,14 @@ int OpSwap(int op)
OpStart(op); Cycles=4;
EaCalc (10,0x0007,ea,2,1);
EaRead (10, 0,ea,2,0x0007,1);
EaCalc (11,0x0007,ea,2,1);
EaRead (11, 0,ea,2,0x0007,1);
ot(" mov r1,r0,ror #16\n");
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0);
EaWrite(10, 1,8,2,0x0007,1);
EaWrite(11, 1,8,2,0x0007,1);
OpEnd();
@ -256,7 +256,7 @@ int OpTst(int op)
EaRead ( 0, 0,sea,size,0x003f,1);
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");
OpEnd(sea);
@ -280,16 +280,16 @@ int OpExt(int op)
OpStart(op); Cycles=4;
EaCalc (10,0x0007,ea,size+1,0,0);
EaRead (10, 0,ea,size+1,0x0007,0,0);
EaCalc (11,0x0007,ea,size+1,0,0);
EaRead (11, 0,ea,size+1,0x0007,0,0);
ot(" mov r0,r0,asl #%d\n",shift);
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("\n");
EaWrite(10, 1,ea,size+1,0x0007,0,0);
EaWrite(11, 1,ea,size+1,0x0007,0,0);
OpEnd();
return 0;
@ -334,18 +334,18 @@ int OpSet(int op)
case 1: // F
break;
case 2: // hi
ot(" tst r9,#0x60000000 ;@ hi: !C && !Z\n");
ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n");
ot(" mvneq r1,r1\n");
if (ea<8) ot(" subeq r5,r5,#2 ;@ Extra cycles\n");
break;
case 3: // ls
ot(" tst r9,#0x60000000 ;@ ls: C || Z\n");
ot(" tst r10,#0x60000000 ;@ ls: C || Z\n");
ot(" mvnne r1,r1\n");
if (ea<8) ot(" subne r5,r5,#2 ;@ Extra cycles\n");
break;
default:
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]);
if (ea<8) ot(" sub%s r5,r5,#2 ;@ Extra cycles\n",cond[cc]);
break;
@ -408,11 +408,11 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
OpGetFlags(0,0);
if (usereg) { // store X only if count is not 0
ot(" cmp %s,#0 ;@ shifting by 0?\n",pct);
ot(" biceq r9,r9,#0x20000000 ;@ if so, clear carry\n");
ot(" strne r9,[r7,#0x4c] ;@ else Save X bit\n");
ot(" biceq r10,r10,#0x20000000 ;@ if so, clear carry\n");
ot(" strne r10,[r7,#0x4c] ;@ else Save X bit\n");
} else {
// 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");
@ -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(" movs r0,r0,lsl #%d\n",32-(8<<size));
if (type)
ot(" orrmi r9,r9,#0x80000000 ;@ Potentially missed N flag\n");
ot(" orrmi r10,r10,#0x80000000 ;@ Potentially missed N flag\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(" eoreq r1,r0,r3\n"); // above check doesn't catch (-1)<<(32+), so we need this
ot(" tsteq r1,#0x80000000\n");
ot(" orrne r9,r9,#0x10000000\n");
ot(" orrne r10,r10,#0x10000000\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;
// Roxr
if(count == 1) {
if(count == 1)
{
if(dir==0) {
if(size!=2) {
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);
ot(" tst r3,#0x20000000\n");
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;
}
@ -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);
OpGetFlags(0,!usereg);
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("norotx_%.4x%s\n",op,ms?"":":");
ot(" ldr r2,[r7,#0x4c]\n");
ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0);
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?"":":");
}
@ -555,7 +556,7 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
OpGetFlags(0,0);
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");
if (usereg)
{
@ -564,7 +565,7 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg)
}
else
ot(" tst r0,#1\n");
ot(" orrne r9,r9,#0x20000000\n");
ot(" orrne r10,r10,#0x20000000\n");
}
ot("\n");
@ -602,12 +603,12 @@ int OpAsr(int op)
OpStart(op,ea,0,count<0); Cycles=size<2?6:8;
EaCalc(10,0x0007, ea,size,1);
EaRead(10, 0, ea,size,0x0007,1);
EaCalc(11,0x0007, ea,size,1);
EaRead(11, 0, ea,size,0x0007,1);
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(ea,0);
@ -634,12 +635,12 @@ int OpAsrEa(int op)
OpStart(op,ea); Cycles=6; // EmitAsr() will add 2
EaCalc (10,0x003f,ea,size,1);
EaRead (10, 0,ea,size,0x003f,1);
EaCalc (11,0x003f,ea,size,1);
EaRead (11, 0,ea,size,0x003f,1);
EmitAsr(op,type,dir,1,size,0);
EaWrite(10, 0,ea,size,0x003f,1);
EaWrite(11, 0,ea,size,0x003f,1);
OpEnd(ea);
return 0;
@ -665,8 +666,8 @@ int OpTas(int op, int gen_special)
Cycles=4;
if(ea>=8) Cycles+=10;
EaCalc (10,0x003f,ea,0,1);
EaRead (10, 1,ea,0,0x003f,1);
EaCalc (11,0x003f,ea,0,1);
EaRead (11, 1,ea,0,0x003f,1);
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");
OpGetFlags(0,0);
@ -678,7 +679,7 @@ int OpTas(int op, int gen_special)
#endif
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
}
#endif

View file

@ -7,7 +7,7 @@
void OpFlagsToReg(int high)
{
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(" tst r2,#1 ;@ 1 if C!=V\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(" eorne r0,r0,#3 ;@ ___XNZCV\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)
{
@ -126,7 +126,7 @@ int OpMove(int op)
if (movea==0)
{
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");
}
@ -135,11 +135,11 @@ int OpMove(int op)
eawrite_check_addrerr=1;
#if SPLIT_MOVEL_PD
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(" add r0,r10,#2\n");
ot(" add r0,r8,#2\n");
EaWrite(0, 1,tea,1,0x0e00,0,0);
EaWrite(10, 11,tea,1,0x0e00,1);
EaWrite(8, 11,tea,1,0x0e00,1);
}
else
#endif
@ -276,7 +276,7 @@ int OpArithSr(int op)
// note: old srh is already in r11 (done by OpStart)
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");
if (size!=0) {
ot(" orr r1,r11,r0,lsr #8\n");
@ -284,13 +284,13 @@ int OpArithSr(int op)
}
}
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");
if (size!=0)
ot(" and r1,r11,r0,lsr #8\n");
}
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");
if (size!=0) {
ot(" eor r1,r11,r0,lsr #8\n");
@ -333,10 +333,10 @@ int OpPea(int op)
OpStart(op,ea);
ot(" ldr r10,[r7,#0x3c]\n");
ot(" ldr r11,[r7,#0x3c]\n");
EaCalc (1,0x003f, ea,0);
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("\n");
MemHandler(1,2); // Write 32-bit
@ -376,11 +376,18 @@ int OpMovem(int op)
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(";@ r10=Register Index*4:\n");
if (decr) ot(" mov r10,#0x40 ;@ order reversed for -(An)\n");
else ot(" mov r10,#-4\n");
ot(";@ r4=Register Index*4:\n");
if (decr) ot(" mov r4,#0x40 ;@ order reversed for -(An)\n");
else ot(" mov r4,#-4\n");
ot("\n");
ot(";@ Get the address into r6:\n");
@ -399,7 +406,7 @@ int OpMovem(int op)
ot("\n");
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(" bcc Movemloop%.4x\n",op);
ot("\n");
@ -411,17 +418,17 @@ int OpMovem(int op)
ot(" ;@ Copy memory to register:\n",1<<size);
earead_check_addrerr=0; // already checked
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
{
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 (decr && size==2) { // -(An)
ot(" add r0,r6,#2\n");
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");
EaWrite(0,1,ea,1,0x003f,1);
}
@ -447,7 +454,8 @@ int OpMovem(int op)
}
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");
if(dir) { // er
@ -462,7 +470,6 @@ int OpMovem(int op)
opend_op_changes_cycles = 1;
OpEnd(ea);
ltorg();
ot("\n");
return 0;
@ -514,7 +521,7 @@ int OpMoveq(int op)
ot(" movs r0,r8,asl #24\n");
ot(" and r1,r8,#0x0e00\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("\n");
@ -541,15 +548,15 @@ int OpExg(int op)
OpStart(op); Cycles=6;
ot(" and r10,r8,#0x0e00 ;@ Find T register\n");
ot(" and r11,r8,#0x000f ;@ Find S register\n");
if (type==0x48) ot(" orr r10,r10,#0x1000 ;@ T is an address register\n");
ot(" and r2,r8,#0x0e00 ;@ Find T register\n");
ot(" and r3,r8,#0x000f ;@ Find S register\n");
if (type==0x48) ot(" orr r2,r2,#0x1000 ;@ T is an address register\n");
ot("\n");
ot(" ldr r0,[r7,r10,lsr #7] ;@ Get T\n");
ot(" ldr r1,[r7,r11,lsl #2] ;@ Get S\n");
ot(" ldr r0,[r7,r2,lsr #7] ;@ Get T\n");
ot(" ldr r1,[r7,r3,lsl #2] ;@ Get S\n");
ot("\n");
ot(" str r0,[r7,r11,lsl #2] ;@ T->S\n");
ot(" str r1,[r7,r10,lsr #7] ;@ S->T\n");
ot(" str r0,[r7,r3,lsl #2] ;@ T->S\n");
ot(" str r1,[r7,r2,lsr #7] ;@ S->T\n");
ot("\n");
OpEnd();
@ -578,44 +585,48 @@ int OpMovep(int op)
OpStart(op,ea);
if(dir) { // reg to mem
if(dir) // reg to mem
{
EaCalcReadNoSE(-1,11,rea,size,0x0e00);
EaCalc(10,0x000f,ea,size);
EaCalc(8,0x000f,ea,size);
if(size==2) { // if operand is long
ot(" mov r1,r11,lsr #24 ;@ first byte\n");
EaWrite(10,1,ea,0,0x000f); // store first byte
ot(" add r0,r10,#%i\n",(aadd+=2));
EaWrite(8,1,ea,0,0x000f); // store first byte
ot(" add r0,r8,#%i\n",(aadd+=2));
ot(" mov r1,r11,lsr #16 ;@ second byte\n");
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 {
ot(" mov r0,r10\n");
ot(" mov r0,r8\n");
}
ot(" mov r1,r11,lsr #8 ;@ first or third byte\n");
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");
EaWrite(0,1,ea,0,0x000f);
} else { // mem to reg
EaCalc(10,0x000f,ea,size,1);
EaRead(10,11,ea,0,0x000f,1); // read first byte
ot(" add r0,r10,#2\n");
}
else // mem to reg
{
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
if(size==2) { // if operand is long
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);
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);
ot(" orr r1,r11,r1,lsr #24 ;@ fourth byte\n");
} else {
ot(" orr r1,r11,r1,lsr #8 ;@ second byte\n");
}
// store the result
EaCalc(11,0x0e00,rea,size,1); // reg number -> r11
EaWrite(11,1,rea,size,0x0e00,1);
EaCalc(0,0x0e00,rea,size,1);
EaWrite(0,1,rea,size,0x0e00,1);
ot(" ldr r6,[r7,#0x54]\n");
}
Cycles=(size==2)?24:16;
@ -653,17 +664,17 @@ int OpStopReset(int op)
Cycles = 132;
#if USE_RESET_CALLBACK
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(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x90] ;@ ResetCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\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 r4,[r7,#0x40] ;@ Load PC\n");
ot(" mov r9,r9,lsl #28\n");
ot(" mov r10,r10,lsl #28\n");
ot("\n");
#endif
}