mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
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:
parent
651b1a25c2
commit
449ecf9257
8 changed files with 304 additions and 280 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,22 +361,22 @@ 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(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\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");
|
||||
ot("\n");
|
||||
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(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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?"":":");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue