2 /*****************************************************************/
3 /* Offset in SCPUState structure */
4 /*****************************************************************/
6 #define BranchSkip_ofs 4
7 #define NMIActive_ofs 5
8 #define IRQActive_ofs 6
9 #define WaitingForInterrupt_ofs 7
12 #define SRAMModified_ofs 10
13 #define BRKTriggered_ofs 11
17 #define PCAtOpcodeStart_ofs 20
19 #define WaitAddress_ofs 24
21 #define WaitCounter_ofs 28
23 #define NextEvent_ofs 36
24 #define V_Counter_ofs 40
25 #define MemSpeed_ofs 44
26 #define MemSpeedx2_ofs 48
27 #define FastROMSpeed_ofs 52
28 #define AutoSaveTimer_ofs 56
29 #define NMITriggerPoint_ofs 60
30 #define NMICycleCount_ofs 64
31 #define IRQCycleCount_ofs 68
37 #define RAH_ofs RA_ofs+1
45 #define asm_OPTABLE_ofs 88
46 #define TriedInterleavedMode2_ofs 92
51 #define WriteMap_ofs 100
52 #define MemorySpeed_ofs 104
53 #define BlockIsRAM_ofs 108
58 #define APUExecuting_ofs 122
60 #define PALMOS_R9_ofs 124
61 #define PALMOS_R10_ofs 128
62 /*****************************************************************/
68 STMFD R13!,{R9,R10,R12,R14}
69 LDR R9,[regCPUvar,#PALMOS_R9_ofs]
70 LDR R10,[regCPUvar,#PALMOS_R10_ofs]
72 .macro PREPARE_C_CALL_R0
73 STMFD R13!,{R0,R9,R10,R12,R14}
74 LDR R9,[regCPUvar,#PALMOS_R9_ofs]
75 LDR R10,[regCPUvar,#PALMOS_R10_ofs]
77 .macro PREPARE_C_CALL_R0R1
78 STMFD R13!,{R0,R1,R9,R10,R12,R14}
79 LDR R9,[regCPUvar,#PALMOS_R9_ofs]
80 LDR R10,[regCPUvar,#PALMOS_R10_ofs]
82 .macro PREPARE_C_CALL_LIGHT
84 LDR R9,[regCPUvar,#PALMOS_R9_ofs]
85 LDR R10,[regCPUvar,#PALMOS_R10_ofs]
87 .macro PREPARE_C_CALL_LIGHTR12
88 STMFD R13!,{R9,R10,R12,R14}
89 LDR R9,[regCPUvar,#PALMOS_R9_ofs]
90 LDR R10,[regCPUvar,#PALMOS_R10_ofs]
94 LDMFD R13!,{R9,R10,R12,R14}
97 .macro RESTORE_C_CALL_R0
98 LDMFD R13!,{R0,R9,R10,R12,R14}
100 .macro RESTORE_C_CALL_R1
101 LDMFD R13!,{R1,R9,R10,R12,R14}
103 .macro RESTORE_C_CALL_LIGHT
106 .macro RESTORE_C_CALL_LIGHTR12
107 LDMFD R13!,{R9,R10,R12,R14}
111 .macro PREPARE_C_CALL
114 .macro PREPARE_C_CALL_R0
115 STMFD R13!,{R0,R12,R14}
117 .macro PREPARE_C_CALL_R0R1
118 STMFD R13!,{R0,R1,R12,R14}
120 .macro PREPARE_C_CALL_LIGHT
123 .macro PREPARE_C_CALL_LIGHTR12
127 .macro RESTORE_C_CALL
130 .macro RESTORE_C_CALL_R0
131 LDMFD R13!,{R0,R12,R14}
133 .macro RESTORE_C_CALL_R1
134 LDMFD R13!,{R1,R12,R14}
136 .macro RESTORE_C_CALL_LIGHT
139 .macro RESTORE_C_CALL_LIGHTR12
146 //regD & regPBank share the same register
147 LDRB regPBank,[regCPUvar,#RPB_ofs]
148 LDRH rscratch,[regCPUvar,#RD_ofs]
149 ORR regD,regD,rscratch, LSL #16
150 //rstatus & regDBank share the same register
151 LDRB regDBank,[regCPUvar,#RDB_ofs]
152 LDRH rscratch,[regCPUvar,#RP_ofs]
153 ORRS rstatus, rstatus, rscratch,LSL #STATUS_SHIFTER
154 //if Carry set, then EMULATION bit was set
155 ORRCS rstatus,rstatus,#MASK_EMUL
157 LDRH regA,[regCPUvar,#RA_ofs]
158 LDRH regX,[regCPUvar,#RX_ofs]
159 LDRH regY,[regCPUvar,#RY_ofs]
160 LDRH regS,[regCPUvar,#RS_ofs]
161 //Shift X,Y & A according to the current mode (INDEX, MEMORY bits)
162 TST rstatus,#MASK_INDEX
163 MOVNE regX,regX,LSL #24
164 MOVNE regY,regY,LSL #24
165 MOVEQ regX,regX,LSL #16
166 MOVEQ regY,regY,LSL #16
167 TST rstatus,#MASK_MEM
168 MOVNE regA,regA,LSL #24
169 MOVEQ regA,regA,LSL #16
171 LDR regpcbase,[regCPUvar,#PCBase_ofs]
172 LDR rpc,[regCPUvar,#PC_ofs]
173 LDR regCycles,[regCPUvar,#Cycles_ofs]
178 //regD & regPBank is same register
179 STRB regPBank,[regCPUvar,#RPB_ofs]
180 MOV rscratch,regD, LSR #16
181 STRH rscratch,[regCPUvar,#RD_ofs]
182 //rstatus & regDBank is same register
183 STRB regDBank,[regCPUvar,#RDB_ofs]
184 MOVS rscratch, rstatus, LSR #STATUS_SHIFTER
185 ORRCS rscratch,rscratch,#0x100 //EMULATION bit
186 STRH rscratch,[regCPUvar,#RP_ofs]
188 //Shift X,Y & A according to the current mode (INDEX, MEMORY bits)
189 TST rstatus,#MASK_INDEX
190 MOVNE rscratch,regX,LSR #24
191 MOVNE rscratch2,regY,LSR #24
192 MOVEQ rscratch,regX,LSR #16
193 MOVEQ rscratch2,regY,LSR #16
194 STRH rscratch,[regCPUvar,#RX_ofs]
195 STRH rscratch2,[regCPUvar,#RY_ofs]
196 TST rstatus,#MASK_MEM
197 LDRNEH rscratch,[regCPUvar,#RA_ofs]
198 BICNE rscratch,rscratch,#0xFF
199 ORRNE rscratch,rscratch,regA,LSR #24
200 MOVEQ rscratch,regA,LSR #16
201 STRH rscratch,[regCPUvar,#RA_ofs]
203 STRH regS,[regCPUvar,#RS_ofs]
204 STR regpcbase,[regCPUvar,#PCBase_ofs]
205 STR rpc,[regCPUvar,#PC_ofs]
207 STR regCycles,[regCPUvar,#Cycles_ofs]
210 /*****************************************************************/
212 add regCycles,regCycles, #ONE_CYCLE
215 addne regCycles,regCycles, #ONE_CYCLE
218 addeq regCycles,regCycles, #ONE_CYCLE
222 add regCycles,regCycles, #(ONE_CYCLE*2)
225 addne regCycles,regCycles, #(ONE_CYCLE*2)
228 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
229 add regCycles,regCycles, #(ONE_CYCLE*2)
230 add regCycles, regCycles, rscratch, LSL #1
233 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
234 add regCycles,regCycles, #(ONE_CYCLE*2)
235 add regCycles, regCycles, rscratch
239 add regCycles,regCycles, #(ONE_CYCLE*3)
243 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
244 add regCycles,regCycles, #ONE_CYCLE
245 add regCycles, regCycles, rscratch
249 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
250 add regCycles,regCycles, #ONE_CYCLE
251 add regCycles, regCycles, rscratch, lsl #1
255 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
256 add regCycles, regCycles, rscratch
260 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
261 add regCycles, regCycles, rscratch, lsl #1
265 ldr rscratch,[regCPUvar,#MemSpeed_ofs]
266 add regCycles, rscratch, regCycles
267 add regCycles, regCycles, rscratch, lsl #1
272 BIC rstatus,rstatus,#MASK_DECIMAL
275 ORR rstatus,rstatus,#MASK_DECIMAL
278 ORR rstatus,rstatus,#MASK_IRQ
281 BIC rstatus,rstatus,#MASK_IRQ
285 //if (Settings.Shutdown && CPU.PC == CPU.WaitAddress)
286 LDR rscratch,[regCPUvar,#WaitAddress_ofs]
289 //if (CPU.WaitCounter == 0 && !(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG)))
290 LDR rscratch,[regCPUvar,#Flags_ofs]
291 LDR rscratch2,[regCPUvar,#WaitCounter_ofs]
292 TST rscratch,#(IRQ_PENDING_FLAG|NMI_FLAG)
294 MOVS rscratch2,rscratch2
296 //CPU.WaitAddress = NULL;
298 STR rscratch,[regCPUvar,#WaitAddress_ofs]
300 // S9xSA1ExecuteDuringSleep (); : TODO
302 // CPU.Cycles = CPU.NextEvent;
303 LDR regCycles,[regCPUvar,#NextEvent_ofs]
304 LDRB r0,[regCPUvar,#APUExecuting_ofs]
307 // if (IAPU.APUExecuting)
309 ICPU.CPUExecuting = FALSE;
313 } while (APU.Cycles < CPU.NextEvent);
314 ICPU.CPUExecuting = TRUE;
322 if (CPU.WaitCounter >= 2)
329 //SUBLS rscratch2,rscratch2,#1
331 STR rscratch2,[regCPUvar,#WaitCounter_ofs]
336 /*in rsctach : OpAddress
337 /*destroy rscratch2*/
338 LDRB rscratch2,[regCPUvar,#BranchSkip_ofs]
339 MOVS rscratch2,rscratch2
342 STRB rscratch2,[regCPUvar,#BranchSkip_ofs]
343 SUB rscratch2,rpc,regpcbase
344 //if( CPU.PC - CPU.PCBase > OpAddress) return;
345 CMP rscratch2,rscratch
350 /*in rsctach : OpAddress
351 /*destroy rscratch2*/
352 LDRB rscratch2,[regCPUvar,#BranchSkip_ofs]
353 MOVS rscratch2,rscratch2
356 STRB rscratch2,[regCPUvar,#BranchSkip_ofs]
357 SUB rscratch2,rpc,regpcbase
358 //if( CPU.PC - CPU.PCBase > OpAddress) return;
359 CMP rscratch2,rscratch
364 /*in rsctach : OpAddress
365 /*destroy rscratch2*/
366 LDRB rscratch2,[regCPUvar,#BranchSkip_ofs]
367 MOVS rscratch2,rscratch2
370 STRB rscratch2,[regCPUvar,#BranchSkip_ofs]
371 SUB rscratch2,rpc,regpcbase
372 //if( CPU.PC - CPU.PCBase > OpAddress) return;
373 CMP rscratch2,rscratch
379 // in : rscratch (0x00hhmmll)
383 LDR rpc,[regCPUvar,#PC_ofs]
384 LDR regpcbase,[regCPUvar,#PCBase_ofs]
389 LDR rscratch2,[regCPUvar,#PALMOS_R10_ofs]
391 TST rstatus,#MASK_EMUL
392 LDRNE rscratch, = jumptable1 //Mode 0 : M=1,X=1
395 TST rstatus,#MASK_MEM
398 TST rstatus,#MASK_INDEX
399 //INDEX=1 //Mode 0 : M=1,X=1
400 LDRNE rscratch, = jumptable1
401 //INDEX=0 //Mode 1 : M=1,X=0
402 LDREQ rscratch, = jumptable2
405 TST rstatus,#MASK_INDEX
406 //INDEX=1 //Mode 3 : M=0,X=1
407 LDRNE rscratch, = jumptable4
408 //INDEX=0 //Mode 2 : M=0,X=0
409 LDREQ rscratch, = jumptable3
412 ADD rscratch,rscratch,rscratch2
414 STR rscratch,[regCPUvar,#asm_OPTABLE_ofs]
430 .macro S9xDoHBlankProcessing
433 BL asm_S9xDoHBlankProcessing
438 /********************************/
440 LDR R1,[regCPUvar,#asm_OPTABLE_ofs]
441 STR rpc,[regCPUvar,#PCAtOpcodeStart_ofs]
446 LDR R2,[regCPUvar,#PALMOS_R10_ofs]
447 LDR R3,[R1,R0,LSL #2]
450 LDR PC, [R1,R0, LSL #2]
457 LDR rscratch,[regCPUvar,#NextEvent_ofs]
458 CMP regCycles,rscratch
460 S9xDoHBlankProcessing
464 .macro asmAPU_EXECUTE
465 LDRB R0,[regCPUvar,#APUExecuting_ofs]
469 STR regCycles,[regCPUvar,#Cycles_ofs]
470 PREPARE_C_CALL_LIGHTR12
472 RESTORE_C_CALL_LIGHTR12
473 LDR regCycles,[regCPUvar,#Cycles_ofs]
479 .macro asmAPU_EXECUTE2
481 STR regCycles,[regCPUvar,#Cycles_ofs]
482 PREPARE_C_CALL_LIGHTR12
484 RESTORE_C_CALL_LIGHTR12
485 LDR regCycles,[regCPUvar,#Cycles_ofs]
490 //void asmMainLoop(asm_cpu_var_t *asmcpuPtr);
493 STMFD R13!,{R4-R11,LR}
494 //init pointer to CPUvar structure
498 //get cpu mode from flag and init jump table
505 LDR rscratch,[regCPUvar,#Flags_ofs]
506 MOVS rscratch,rscratch
507 BNE CPUFlags_set //If flags => check for irq/nmi/scan_keys...
509 EXEC_OP //Execute next opcode
511 CPUFlags_set: //Check flags (!=0)
512 TST rscratch,#NMI_FLAG //Check NMI
513 BEQ CPUFlagsNMI_FLAG_cleared
514 LDR rscratch2,[regCPUvar,#NMICycleCount_ofs]
515 SUBS rscratch2,rscratch2,#1
516 STR rscratch2,[regCPUvar,#NMICycleCount_ofs]
517 BNE CPUFlagsNMI_FLAG_cleared
518 BIC rscratch,rscratch,#NMI_FLAG
519 STR rscratch,[regCPUvar,#Flags_ofs]
520 LDRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs]
521 MOVS rscratch2,rscratch2
522 BEQ NotCPUaitingForInterruptNMI
525 STRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs]
526 NotCPUaitingForInterruptNMI:
528 LDR rscratch,[regCPUvar,#Flags_ofs]
529 CPUFlagsNMI_FLAG_cleared:
530 TST rscratch,#IRQ_PENDING_FLAG //Check IRQ_PENDING_FLAG
531 BEQ CPUFlagsIRQ_PENDING_FLAG_cleared
532 LDR rscratch2,[regCPUvar,#IRQCycleCount_ofs]
533 MOVS rscratch2,rscratch2
534 BNE CPUIRQCycleCount_NotZero
535 LDRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs]
536 MOVS rscratch2,rscratch2
537 BEQ NotCPUaitingForInterruptIRQ
540 STRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs]
541 NotCPUaitingForInterruptIRQ:
542 LDRB rscratch2,[regCPUvar,#IRQActive_ofs]
543 MOVS rscratch2,rscratch2
544 BEQ CPUIRQActive_cleared
545 TST rstatus,#MASK_IRQ
546 BNE CPUFlagsIRQ_PENDING_FLAG_cleared
548 LDR rscratch,[regCPUvar,#Flags_ofs]
549 B CPUFlagsIRQ_PENDING_FLAG_cleared
550 CPUIRQActive_cleared:
551 BIC rscratch,rscratch,#IRQ_PENDING_FLAG
552 STR rscratch,[regCPUvar,#Flags_ofs]
553 B CPUFlagsIRQ_PENDING_FLAG_cleared
554 CPUIRQCycleCount_NotZero:
555 SUB rscratch2,rscratch2,#1
556 STR rscratch2,[regCPUvar,#IRQCycleCount_ofs]
557 CPUFlagsIRQ_PENDING_FLAG_cleared:
559 TST rscratch,#SCAN_KEYS_FLAG //Check SCAN_KEYS_FLAG
562 EXEC_OP //Execute next opcode
565 /*Registers.PC = CPU.PC - CPU.PCBase;
567 APURegisters.PC = IAPU.PC - IAPU.RAM;
570 if (CPU.Flags & SCAN_KEYS_FLAG)
573 CPU.Flags &= ~SCAN_KEYS_FLAG;
577 LDMFD R13!,{R4-R11,LR}
583 //void test_opcode(struct asm_cpu_var *asm_var);
586 STMFD R13!,{R4-R11,LR}
587 //init pointer to CPUvar structure
591 //get cpu mode from flag and init jump table