/***************************************************************** *****************************************************************/ //#define _C_GB_ //#define _C_GW_ //#define _C_SB_ //#define _C_SW_ .macro S9xGetWord // in : rscratch (0x00hhmmll) // out : rscratch (0xhhll0000) #ifdef _C_GW_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL BL asm_S9xGetWord RESTORE_C_CALL MOV R0, R0, LSL #16 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address B asmS9xGetWord MOV R0,R0 MOV R0, R0, LSL #16 #endif .endm .macro S9xGetWordLow // in : rscratch (0x00hhmmll) // out : rscratch (0x0000hhll) #ifdef _C_GW_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL BL asm_S9xGetWord RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address B asmS9xGetWord MOV R0,R0 #endif .endm .macro S9xGetWordRegStatus reg // in : rscratch (0x00hhmmll) // out : reg (0xhhll0000) // flags have to be updated with read value #ifdef _C_GW_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL BL asm_S9xGetWord RESTORE_C_CALL MOVS \reg, R0, LSL #16 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address B asmS9xGetWord MOV R0,R0 MOVS \reg, R0, LSL #16 #endif .endm .macro S9xGetWordRegNS reg // in : rscratch (0x00hhmmll) // out : reg (0xhhll0000) // DOES NOT DESTROY rscratch (R0) #ifdef _C_GW_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL_R0 BL asm_S9xGetWord MOV \reg, R0, LSL #16 RESTORE_C_CALL_R0 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{R0} STMFD R13!,{PC} //Push return address B asmS9xGetWord MOV R0,R0 MOV \reg, R0, LSL #16 LDMFD R13!,{R0} #endif .endm .macro S9xGetWordLowRegNS reg // in : rscratch (0x00hhmmll) // out : reg (0xhhll0000) // DOES NOT DESTROY rscratch (R0) #ifdef _C_GW_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL_R0 BL asm_S9xGetWord MOV \reg, R0 RESTORE_C_CALL_R0 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{R0} STMFD R13!,{PC} //Push return address B asmS9xGetWord MOV R0,R0 MOV \reg, R0 LDMFD R13!,{R0} #endif .endm .macro S9xGetByte // in : rscratch (0x00hhmmll) // out : rscratch (0xll000000) #ifdef _C_GB_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL BL asm_S9xGetByte RESTORE_C_CALL MOV R0, R0, LSL #24 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address B asmS9xGetByte MOV R0,R0 MOV R0, R0, LSL #24 #endif .endm .macro S9xGetByteLow // in : rscratch (0x00hhmmll) // out : rscratch (0x000000ll) #ifdef _C_GB_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL BL asm_S9xGetByte RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} B asmS9xGetByte MOV R0,R0 #endif .endm .macro S9xGetByteRegStatus reg // in : rscratch (0x00hhmmll) // out : reg (0xll000000) // flags have to be updated with read value #ifdef _C_GB_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL BL asm_S9xGetByte RESTORE_C_CALL MOVS \reg, R0, LSL #24 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address B asmS9xGetByte MOV R0,R0 MOVS \reg, R0, LSL #24 #endif .endm .macro S9xGetByteRegNS reg // in : rscratch (0x00hhmmll) // out : reg (0xll000000) // DOES NOT DESTROY rscratch (R0) #ifdef _C_GB_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL_R0 BL asm_S9xGetByte MOV \reg, R0, LSL #24 RESTORE_C_CALL_R0 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{R0} STMFD R13!,{PC} //Push return address B asmS9xGetByte MOV R0,R0 MOVS \reg, R0, LSL #24 LDMFD R13!,{R0} #endif .endm .macro S9xGetByteLowRegNS reg // in : rscratch (0x00hhmmll) // out : reg (0x000000ll) // DOES NOT DESTROY rscratch (R0) #ifdef _C_GB_ STR regCycles,[regCPUvar,#Cycles_ofs] PREPARE_C_CALL_R0 BL asm_S9xGetByte MOV \reg, R0, LSL #24 RESTORE_C_CALL_R0 LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{R0} STMFD R13!,{PC} //Push return address B asmS9xGetByte MOV R0,R0 MOVS \reg, R0 LDMFD R13!,{R0} #endif .endm .macro S9xSetWord regValue // in : regValue (0xhhll0000) // in : rscratch=address (0x00hhmmll) #ifdef _C_SW_ STR regCycles,[regCPUvar,#Cycles_ofs] MOV R1,\regValue, LSR #16 PREPARE_C_CALL BL asm_S9xSetWord RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address MOV R1,\regValue, LSR #16 B asmS9xSetWord MOV R0,R0 #endif .endm .macro S9xSetWordZero // in : rscratch=address (0x00hhmmll) #ifdef _C_SW_ STR regCycles,[regCPUvar,#Cycles_ofs] MOV R1,#0 PREPARE_C_CALL BL asm_S9xSetWord RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address MOV R1,#0 B asmS9xSetWord MOV R0,R0 #endif .endm .macro S9xSetWordLow regValue // in : regValue (0x0000hhll) // in : rscratch=address (0x00hhmmll) #ifdef _C_SW_ STR regCycles,[regCPUvar,#Cycles_ofs] MOV R1,\regValue PREPARE_C_CALL BL asm_S9xSetWord RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address MOV R1,\regValue B asmS9xSetWord MOV R0,R0 #endif .endm .macro S9xSetByte regValue // in : regValue (0xll000000) // in : rscratch=address (0x00hhmmll) #ifdef _C_SB_ STR regCycles,[regCPUvar,#Cycles_ofs] MOV R1,\regValue, LSR #24 PREPARE_C_CALL BL asm_S9xSetByte RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address MOV R1,\regValue, LSR #24 B asmS9xSetByte MOV R0,R0 #endif .endm .macro S9xSetByteZero // in : rscratch=address (0x00hhmmll) #ifdef _C_SB_ STR regCycles,[regCPUvar,#Cycles_ofs] MOV R1,#0 PREPARE_C_CALL BL asm_S9xSetByte RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address MOV R1,#0 B asmS9xSetByte MOV R0,R0 #endif .endm .macro S9xSetByteLow regValue // in : regValue (0x000000ll) // in : rscratch=address (0x00hhmmll) #ifdef _C_SB_ STR regCycles,[regCPUvar,#Cycles_ofs] MOV R1,\regValue PREPARE_C_CALL BL asm_S9xSetByte RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] #else STMFD R13!,{PC} //Push return address MOV R1,\regValue B asmS9xSetByte MOV R0,R0 #endif .endm // =========================================== // =========================================== // Adressing mode // =========================================== // =========================================== .macro Absolute ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc],#2 ORR rscratch , rscratch, rscratch2, LSL #8 ORR rscratch , rscratch, regDBank, LSL #16 .endm .macro AbsoluteIndexedIndirectX0 ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 ADD rscratch , regX, rscratch, LSL #16 MOV rscratch , rscratch, LSR #16 ORR rscratch , rscratch, regPBank, LSL #16 S9xGetWordLow .endm .macro AbsoluteIndexedIndirectX1 ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 ADD rscratch , rscratch, regX, LSR #24 BIC rscratch , rscratch, #0x00FF0000 ORR rscratch , rscratch, regPBank, LSL #16 S9xGetWordLow .endm .macro AbsoluteIndirectLong ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 S9xGetWordLowRegNS rscratch2 ADD rscratch , rscratch, #2 STMFD r13!,{rscratch2} S9xGetByteLow LDMFD r13!,{rscratch2} ORR rscratch , rscratch2, rscratch, LSL #16 .endm .macro AbsoluteIndirect ADD2MEM LDRB rscratch2 , [rpc,#1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 S9xGetWordLow ORR rscratch , rscratch, regPBank, LSL #16 .endm .macro AbsoluteIndexedX0 ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 ORR rscratch , rscratch, regDBank, LSL #16 ADD rscratch , rscratch, regX, LSR #16 .endm .macro AbsoluteIndexedX1 ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 ORR rscratch , rscratch, regDBank, LSL #16 ADD rscratch , rscratch, regX, LSR #24 .endm .macro AbsoluteIndexedY0 ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 ORR rscratch , rscratch, regDBank, LSL #16 ADD rscratch , rscratch, regY, LSR #16 .endm .macro AbsoluteIndexedY1 ADD2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 ORR rscratch , rscratch, regDBank, LSL #16 ADD rscratch , rscratch, regY, LSR #24 .endm .macro AbsoluteLong ADD3MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 LDRB rscratch2 , [rpc], #1 ORR rscratch , rscratch, rscratch2, LSL #16 .endm .macro AbsoluteLongIndexedX0 ADD3MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 LDRB rscratch2 , [rpc], #1 ORR rscratch , rscratch, rscratch2, LSL #16 ADD rscratch , rscratch, regX, LSR #16 BIC rscratch, rscratch, #0xFF000000 .endm .macro AbsoluteLongIndexedX1 ADD3MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 LDRB rscratch2 , [rpc], #1 ORR rscratch , rscratch, rscratch2, LSL #16 ADD rscratch , rscratch, regX, LSR #24 BIC rscratch, rscratch, #0xFF000000 .endm .macro Direct ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 .endm .macro DirectIndirect ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLow ORR rscratch , rscratch, regDBank, LSL #16 .endm .macro DirectIndirectLong ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLowRegNS rscratch2 ADD rscratch , rscratch,#2 STMFD r13!,{rscratch2} S9xGetByteLow LDMFD r13!,{rscratch2} ORR rscratch , rscratch2, rscratch, LSL #16 .endm .macro DirectIndirectIndexed0 ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLow ORR rscratch, rscratch,regDBank, LSL #16 ADD rscratch, rscratch,regY, LSR #16 .endm .macro DirectIndirectIndexed1 ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLow ORR rscratch, rscratch,regDBank, LSL #16 ADD rscratch, rscratch,regY, LSR #24 .endm .macro DirectIndirectIndexedLong0 ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLowRegNS rscratch2 ADD rscratch , rscratch,#2 STMFD r13!,{rscratch2} S9xGetByteLow LDMFD r13!,{rscratch2} ORR rscratch , rscratch2, rscratch, LSL #16 ADD rscratch, rscratch,regY, LSR #16 .endm .macro DirectIndirectIndexedLong1 ADD1MEM LDRB rscratch , [rpc], #1 ADD rscratch , regD, rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLowRegNS rscratch2 ADD rscratch , rscratch,#2 STMFD r13!,{rscratch2} S9xGetByteLow LDMFD r13!,{rscratch2} ORR rscratch , rscratch2, rscratch, LSL #16 ADD rscratch, rscratch,regY, LSR #24 .endm .macro DirectIndexedIndirect0 ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch2 , regD , regX ADD rscratch , rscratch2 , rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLow ORR rscratch , rscratch , regDBank, LSL #16 .endm .macro DirectIndexedIndirect1 ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch2 , regD , regX, LSR #8 ADD rscratch , rscratch2 , rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 S9xGetWordLow ORR rscratch , rscratch , regDBank, LSL #16 .endm .macro DirectIndexedX0 ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch2 , regD , regX ADD rscratch , rscratch2 , rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 .endm .macro DirectIndexedX1 ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch2 , regD , regX, LSR #8 ADD rscratch , rscratch2 , rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 .endm .macro DirectIndexedY0 ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch2 , regD , regY ADD rscratch , rscratch2 , rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 .endm .macro DirectIndexedY1 ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch2 , regD , regY, LSR #8 ADD rscratch , rscratch2 , rscratch, LSL #16 MOV rscratch, rscratch, LSR #16 .endm .macro Immediate8 ADD rscratch, rpc, regPBank, LSL #16 SUB rscratch, rscratch, regpcbase ADD rpc, rpc, #1 .endm .macro Immediate16 ADD rscratch, rpc, regPBank, LSL #16 SUB rscratch, rscratch, regpcbase ADD rpc, rpc, #2 .endm .macro asmRelative ADD1MEM LDRSB rscratch , [rpc],#1 ADD rscratch , rscratch , rpc SUB rscratch , rscratch, regpcbase BIC rscratch,rscratch,#0x00FF0000 BIC rscratch,rscratch,#0xFF000000 .endm .macro asmRelativeLong ADD1CYCLE2MEM LDRB rscratch2 , [rpc, #1] LDRB rscratch , [rpc], #2 ORR rscratch , rscratch, rscratch2, LSL #8 SUB rscratch2 , rpc, regpcbase ADD rscratch , rscratch2, rscratch BIC rscratch,rscratch,#0x00FF0000 .endm .macro StackasmRelative ADD1CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch , rscratch, regS BIC rscratch,rscratch,#0x00FF0000 .endm .macro StackasmRelativeIndirectIndexed0 ADD2CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch , rscratch, regS BIC rscratch,rscratch,#0x00FF0000 S9xGetWordLow ORR rscratch , rscratch, regDBank, LSL #16 ADD rscratch , rscratch, regY, LSR #16 BIC rscratch, rscratch, #0xFF000000 .endm .macro StackasmRelativeIndirectIndexed1 ADD2CYCLE1MEM LDRB rscratch , [rpc], #1 ADD rscratch , rscratch, regS BIC rscratch,rscratch,#0x00FF0000 S9xGetWordLow ORR rscratch , rscratch, regDBank, LSL #16 ADD rscratch , rscratch, regY, LSR #24 BIC rscratch, rscratch, #0xFF000000 .endm /****************************************/ .macro PushB reg MOV rscratch,regS S9xSetByte \reg SUB regS,regS,#1 .endm .macro PushBLow reg MOV rscratch,regS S9xSetByteLow \reg SUB regS,regS,#1 .endm .macro PushWLow reg SUB rscratch,regS,#1 S9xSetWordLow \reg SUB regS,regS,#2 .endm .macro PushWrLow MOV rscratch2,rscratch SUB rscratch,regS,#1 S9xSetWordLow rscratch2 SUB regS,regS,#2 .endm .macro PushW reg SUB rscratch,regS,#1 S9xSetWord \reg SUB regS,regS,#2 .endm /********/ .macro PullB reg ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 MOV \reg,rscratch,LSL #24 .endm .macro PullBr ADD rscratch,regS,#1 S9xGetByte ADD regS,regS,#1 .endm .macro PullBLow reg ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 MOV \reg,rscratch .endm .macro PullBrLow ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 .endm .macro PullW reg ADD rscratch,regS,#1 S9xGetWordLow ADD regS,regS,#2 MOV \reg,rscratch,LSL #16 .endm .macro PullWLow reg ADD rscratch,regS,#1 S9xGetWordLow ADD regS,regS,#2 MOV \reg,rscratch .endm /*****************/ .macro PullBS reg ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 MOVS \reg,rscratch,LSL #24 .endm .macro PullBrS ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 MOVS rscratch,rscratch,LSL #24 .endm .macro PullBLowS reg ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 MOVS \reg,rscratch .endm .macro PullBrLowS ADD rscratch,regS,#1 S9xGetByteLow ADD regS,regS,#1 MOVS rscratch,rscratch .endm .macro PullWS reg ADD rscratch,regS,#1 S9xGetWordLow ADD regS,regS,#2 MOVS \reg,rscratch, LSL #16 .endm .macro PullWrS ADD rscratch,regS,#1 S9xGetWordLow ADD regS,regS,#2 MOVS rscratch,rscratch, LSL #16 .endm .macro PullWLowS reg ADD rscratch,regS,#1 S9xGetWordLow ADD regS,regS,#2 MOVS \reg,rscratch .endm .macro PullWrLowS ADD rscratch,regS,#1 S9xGetWordLow ADD regS,regS,#2 MOVS rscratch,rscratch .endm .globl asmS9xGetByte .globl asmS9xGetWord .globl asmS9xSetByte .globl asmS9xSetWord //uint8 aaS9xGetByte(uint32 address); asmS9xGetByte: // in : R0 = 0x00hhmmll // out : R0 = 0x000000ll // DESTROYED : R1,R2,R3 // UPDATE : regCycles //R1 <= block MOV R1,R0,LSR #MEMMAP_SHIFT //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so //R1 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF //so AND MEMMAP_MASK is BIC 0xFF000 BIC R1,R1,#0xFF000 //R2 <= Map[block] (GetAddress) LDR R2,[regCPUvar,#Map_ofs] LDR R2,[R2,R1,LSL #2] CMP R2,#MAP_LAST BLO GBSpecial //special // Direct ROM/RAM acess //R2 <= GetAddress + Address & 0xFFFF //R3 <= MemorySpeed[block] LDR R3,[regCPUvar,#MemorySpeed_ofs] MOV R0,R0,LSL #16 LDRB R3,[R3,R1] ADD R2,R2,R0,LSR #16 //Update CPU.Cycles ADD regCycles,regCycles,R3 //R3 = BlockIsRAM[block] LDR R3,[regCPUvar,#BlockIsRAM_ofs] //Get value to return LDRB R0,[R2] LDRB R3,[R3,R1] MOVS R3,R3 // if BlockIsRAM => update for CPUShutdown LDRNE R1,[regCPUvar,#PCAtOpcodeStart_ofs] STRNE R1,[regCPUvar,#WaitAddress_ofs] LDMFD R13!,{PC} //Return GBSpecial: #ifdef __PALMOS__ LDR R3,[regCPUvar,#PALMOS_R10_ofs] LDR R2,[PC,R2,LSL #2] ADD PC,R2,R3 #else LDR PC,[PC,R2,LSL #2] MOV R0,R0 //nop, for align #endif .long GBPPU .long GBCPU .long GBDSP .long GBLSRAM .long GBHSRAM .long GBNONE .long GBDEBUG .long GBC4 .long GBBWRAM .long GBNONE .long GBNONE .long GBNONE /*.long GB7ROM .long GB7RAM .long GB7SRM*/ GBPPU: //InDMA ? LDRB R1,[regCPUvar,#InDMA_ofs] MOVS R1,R1 ADDEQ regCycles,regCycles,#ONE_CYCLE //No -> update Cycles MOV R0,R0,LSL #16 //S9xGetPPU(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL BL S9xGetPPU RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GBCPU: ADD regCycles,regCycles,#ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL BL S9xGetCPU RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GBDSP: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL BL S9xGetDSP RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GBLSRAM: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles LDRH R2,[regCPUvar,#SRAMMask] LDR R1,[regCPUvar,#SRAM] AND R0,R2,R0 //Address&SRAMMask LDRB R0,[R1,R0] //*Memory.SRAM + Address&SRAMMask LDMFD R13!,{PC} GB7SRM: GBHSRAM: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R1,R0,LSL #17 AND R2,R0,#0xF0000 MOV R1,R1,LSR #17 //Address&0x7FFF MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) ADD R0,R2,R1 LDRH R2,[regCPUvar,#SRAMMask] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) LDR R1,[regCPUvar,#SRAM] AND R0,R2,R0 //Address&SRAMMask LDRB R0,[R1,R0] //*Memory.SRAM + Address&SRAMMask LDMFD R13!,{PC} //return GB7ROM: GB7RAM: GBNONE: MOV R0,R0,LSR #8 ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles AND R0,R0,#0xFF LDMFD R13!,{PC} //GBDEBUG: /*ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,#0 LDMFD R13!,{PC}*/ GBC4: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 //S9xGetC4(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL BL S9xGetC4 RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GBDEBUG: GBBWRAM: MOV R0,R0,LSL #17 ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSR #17 //Address&0x7FFF LDR R1,[regCPUvar,#BWRAM] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) LDRB R0,[R0,R1] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) LDMFD R13!,{PC} //uint16 aaS9xGetWord(uint32 address); asmS9xGetWord: // in : R0 = 0x00hhmmll // out : R0 = 0x000000ll // DESTROYED : R1,R2,R3 // UPDATE : regCycles MOV R1,R0,LSL #19 ADDS R1,R1,#0x80000 //if = 0x1FFF => 0 BNE GW_NotBoundary STMFD R13!,{R0} STMFD R13!,{PC} B asmS9xGetByte MOV R0,R0 LDMFD R13!,{R1} STMFD R13!,{R0} ADD R0,R1,#1 STMFD R13!,{PC} B asmS9xGetByte MOV R0,R0 LDMFD R13!,{R1} ORR R0,R1,R0,LSL #8 LDMFD R13!,{PC} GW_NotBoundary: //R1 <= block MOV R1,R0,LSR #MEMMAP_SHIFT //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so //R1 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF //so AND MEMMAP_MASK is BIC 0xFF000 BIC R1,R1,#0xFF000 //R2 <= Map[block] (GetAddress) LDR R2,[regCPUvar,#Map_ofs] LDR R2,[R2,R1,LSL #2] CMP R2,#MAP_LAST BLO GWSpecial //special // Direct ROM/RAM acess TST R0,#1 BNE GW_Not_Aligned1 //R2 <= GetAddress + Address & 0xFFFF //R3 <= MemorySpeed[block] LDR R3,[regCPUvar,#MemorySpeed_ofs] MOV R0,R0,LSL #16 LDRB R3,[R3,R1] MOV R0,R0,LSR #16 //Update CPU.Cycles ADD regCycles,regCycles,R3, LSL #1 //R3 = BlockIsRAM[block] LDR R3,[regCPUvar,#BlockIsRAM_ofs] //Get value to return LDRH R0,[R2,R0] LDRB R3,[R3,R1] MOVS R3,R3 // if BlockIsRAM => update for CPUShutdown LDRNE R1,[regCPUvar,#PCAtOpcodeStart_ofs] STRNE R1,[regCPUvar,#WaitAddress_ofs] LDMFD R13!,{PC} //Return GW_Not_Aligned1: MOV R0,R0,LSL #16 ADD R3,R0,#0x10000 LDRB R3,[R2,R3,LSR #16] //GetAddress+ (Address+1)&0xFFFF LDRB R0,[R2,R0,LSR #16] //GetAddress+ Address&0xFFFF ORR R0,R0,R3,LSL #8 // if BlockIsRAM => update for CPUShutdown LDR R3,[regCPUvar,#BlockIsRAM_ofs] LDR R2,[regCPUvar,#MemorySpeed_ofs] LDRB R3,[R3,R1] //R3 = BlockIsRAM[block] LDRB R2,[R2,R1] //R2 <= MemorySpeed[block] MOVS R3,R3 //IsRAM ? CPUShutdown stuff LDRNE R1,[regCPUvar,#PCAtOpcodeStart_ofs] STRNE R1,[regCPUvar,#WaitAddress_ofs] ADD regCycles,regCycles,R2, LSL #1 //Update CPU.Cycles LDMFD R13!,{PC} //Return GWSpecial: #ifdef __PALMOS__ LDR R3,[regCPUvar,#PALMOS_R10_ofs] LDR R2,[PC,R2,LSL #2] ADD PC,R2,R3 #else LDR PC,[PC,R2,LSL #2] MOV R0,R0 //nop, for align #endif .long GWPPU .long GWCPU .long GWDSP .long GWLSRAM .long GWHSRAM .long GWNONE .long GWDEBUG .long GWC4 .long GWBWRAM .long GWNONE .long GWNONE .long GWNONE /*.long GW7ROM .long GW7RAM .long GW7SRM*/ /* MAP_PPU, MAP_CPU, MAP_DSP, MAP_LOROM_SRAM, MAP_HIROM_SRAM, MAP_NONE, MAP_DEBUG, MAP_C4, MAP_BWRAM, MAP_BWRAM_BITMAP, MAP_BWRAM_BITMAP2, MAP_SA1RAM, MAP_LAST*/ GWPPU: //InDMA ? LDRB R1,[regCPUvar,#InDMA_ofs] MOVS R1,R1 ADDEQ regCycles,regCycles,#(ONE_CYCLE*2) //No -> update Cycles MOV R0,R0,LSL #16 //S9xGetPPU(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL_R0 BL S9xGetPPU LDMFD R13!,{R1} STMFD R13!,{R0} ADD R0,R1,#1 //BIC R0,R0,#0x10000 BL S9xGetPPU RESTORE_C_CALL_R1 ORR R0,R1,R0,LSL #8 LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GWCPU: ADD regCycles,regCycles,#(ONE_CYCLE*2) //update Cycles MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL_R0 BL S9xGetCPU LDMFD R13!,{R1} STMFD R13!,{R0} ADD R0,R1,#1 //BIC R0,R0,#0x10000 BL S9xGetCPU RESTORE_C_CALL_R1 ORR R0,R1,R0,LSL #8 LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GWDSP: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL_R0 BL S9xGetDSP LDMFD R13!,{R1} STMFD R13!,{R0} ADD R0,R1,#1 //BIC R0,R0,#0x10000 BL S9xGetDSP RESTORE_C_CALL_R1 ORR R0,R1,R0,LSL #8 LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GWLSRAM: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles TST R0,#1 BNE GW_Not_Aligned2 LDRH R2,[regCPUvar,#SRAMMask] LDR R1,[regCPUvar,#SRAM] AND R3,R2,R0 //Address&SRAMMask LDRH R0,[R3,R1] //*Memory.SRAM + Address&SRAMMask LDMFD R13!,{PC} //return GW_Not_Aligned2: LDRH R2,[regCPUvar,#SRAMMask] LDR R1,[regCPUvar,#SRAM] AND R3,R2,R0 //Address&SRAMMask ADD R0,R0,#1 AND R2,R0,R2 //Address&SRAMMask LDRB R3,[R1,R3] //*Memory.SRAM + Address&SRAMMask LDRB R2,[R1,R2] //*Memory.SRAM + Address&SRAMMask ORR R0,R3,R2,LSL #8 LDMFD R13!,{PC} //return GW7SRM: GWHSRAM: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles TST R0,#1 BNE GW_Not_Aligned3 MOV R1,R0,LSL #17 AND R2,R0,#0xF0000 MOV R1,R1,LSR #17 //Address&0x7FFF MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) ADD R0,R2,R1 LDRH R2,[regCPUvar,#SRAMMask] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) LDR R1,[regCPUvar,#SRAM] AND R0,R2,R0 //Address&SRAMMask LDRH R0,[R1,R0] //*Memory.SRAM + Address&SRAMMask LDMFD R13!,{PC} //return GW_Not_Aligned3: MOV R3,R0,LSL #17 AND R2,R0,#0xF0000 MOV R3,R3,LSR #17 //Address&0x7FFF MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) ADD R2,R2,R3 ADD R0,R0,#1 SUB R2,R2,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) MOV R3,R0,LSL #17 AND R0,R0,#0xF0000 MOV R3,R3,LSR #17 //(Address+1)&0x7FFF MOV R0,R0,LSR #3 //((Address+1)&0xF0000 >> 3) ADD R0,R0,R3 LDRH R3,[regCPUvar,#SRAMMask] //reload mask SUB R0,R0,#0x6000 //(((Address+1) & 0x7fff) - 0x6000 + (((Address+1) & 0xf0000) >> 3)) AND R2,R3,R2 //Address...&SRAMMask AND R0,R3,R0 //(Address+1...)&SRAMMask LDR R3,[regCPUvar,#SRAM] LDRB R0,[R0,R3] //*Memory.SRAM + (Address...)&SRAMMask LDRB R2,[R2,R3] //*Memory.SRAM + (Address+1...)&SRAMMask ORR R0,R2,R0,LSL #8 LDMFD R13!,{PC} //return GW7ROM: GW7RAM: GWNONE: MOV R0,R0,LSL #16 ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles MOV R0,R0,LSR #24 ORR R0,R0,R0,LSL #8 LDMFD R13!,{PC} GWDEBUG: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles MOV R0,#0 LDMFD R13!,{PC} GWC4: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles MOV R0,R0,LSL #16 //S9xGetC4(Address&0xFFFF); STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL_R0 BL S9xGetC4 LDMFD R13!,{R1} STMFD R13!,{R0} ADD R0,R1,#1 //BIC R0,R0,#0x10000 BL S9xGetC4 RESTORE_C_CALL_R1 ORR R0,R1,R0,LSL #8 LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return GWBWRAM: TST R0,#1 BNE GW_Not_Aligned4 MOV R0,R0,LSL #17 ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles MOV R0,R0,LSR #17 //Address&0x7FFF LDR R1,[regCPUvar,#BWRAM] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) LDRH R0,[R1,R0] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) LDMFD R13!,{PC} //return GW_Not_Aligned4: MOV R0,R0,LSL #17 ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles ADD R3,R0,#0x20000 MOV R0,R0,LSR #17 //Address&0x7FFF MOV R3,R3,LSR #17 //(Address+1)&0x7FFF LDR R1,[regCPUvar,#BWRAM] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) SUB R3,R3,#0x6000 //(((Address+1) & 0x7fff) - 0x6000) LDRB R0,[R1,R0] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) LDRB R3,[R1,R3] //*Memory.BWRAM + (((Address+1) & 0x7fff) - 0x6000) ORR R0,R0,R3,LSL #8 LDMFD R13!,{PC} //return .pool //void aaS9xSetByte(uint32 address,uint8 val); asmS9xSetByte: // in : R0=0x00hhmmll R1=0x000000ll // DESTROYED : R0,R1,R2,R3 // UPDATE : regCycles //cpu shutdown MOV R2,#0 STR R2,[regCPUvar,#WaitAddress_ofs] // //R3 <= block MOV R3,R0,LSR #MEMMAP_SHIFT //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so //R0 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF //so AND MEMMAP_MASK is BIC 0xFF000 BIC R3,R3,#0xFF000 //R2 <= Map[block] (SetAddress) LDR R2,[regCPUvar,#WriteMap_ofs] LDR R2,[R2,R3,LSL #2] CMP R2,#MAP_LAST BLO SBSpecial //special // Direct ROM/RAM acess //R2 <= SetAddress + Address & 0xFFFF MOV R0,R0,LSL #16 ADD R2,R2,R0,LSR #16 LDR R0,[regCPUvar,#MemorySpeed_ofs] //Set byte STRB R1,[R2] //R0 <= MemorySpeed[block] LDRB R0,[R0,R3] //Update CPU.Cycles ADD regCycles,regCycles,R0 //CPUShutdown //only SA1 here : TODO //Return LDMFD R13!,{PC} SBSpecial: #ifdef __PALMOS__ LDR R3,[regCPUvar,#PALMOS_R10_ofs] LDR R2,[PC,R2,LSL #2] ADD PC,R2,R3 #else LDR PC,[PC,R2,LSL #2] MOV R0,R0 //nop, for align #endif .long SBPPU .long SBCPU .long SBDSP .long SBLSRAM .long SBHSRAM .long SBNONE .long SBDEBUG .long SBC4 .long SBBWRAM .long SBNONE .long SBNONE .long SBNONE /*.long SB7ROM .long SB7RAM .long SB7SRM*/ SBPPU: //InDMA ? LDRB R2,[regCPUvar,#InDMA_ofs] MOVS R2,R2 ADDEQ regCycles,regCycles,#ONE_CYCLE //No -> update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 PREPARE_C_CALL MOV R12,R0 MOV R0,R1 MOV R1,R12 BL S9xSetPPU RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SBCPU: ADD regCycles,regCycles,#ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 //Address&0xFFFF PREPARE_C_CALL MOV R12,R0 MOV R0,R1 MOV R1,R12 BL S9xSetCPU RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SBDSP: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 //Address&0xFFFF PREPARE_C_CALL MOV R12,R0 MOV R0,R1 MOV R1,R12 BL S9xSetDSP RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SBLSRAM: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles LDRH R2,[regCPUvar,#SRAMMask] MOVS R2,R2 LDMEQFD R13!,{PC} //return if SRAMMask=0 LDR R3,[regCPUvar,#SRAM] AND R0,R2,R0 //Address&SRAMMask STRB R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SB7SRM: SBHSRAM: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R3,R0,LSL #17 AND R2,R0,#0xF0000 MOV R3,R3,LSR #17 //Address&0x7FFF MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) ADD R0,R2,R3 LDRH R2,[regCPUvar,#SRAMMask] MOVS R2,R2 LDMEQFD R13!,{PC} //return if SRAMMask=0 SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) LDR R3,[regCPUvar,#SRAM] AND R0,R2,R0 //Address&SRAMMask STRB R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SB7ROM: SB7RAM: SBNONE: SBDEBUG: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles LDMFD R13!,{PC} SBC4: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 //Address&0xFFFF PREPARE_C_CALL MOV R12,R0 MOV R0,R1 MOV R1,R12 BL S9xSetC4 RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SBBWRAM: MOV R0,R0,LSL #17 ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSR #17 //Address&0x7FFF LDR R2,[regCPUvar,#BWRAM] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) STRB R1,[R0,R2] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //void aaS9xSetWord(uint32 address,uint16 val); asmS9xSetWord: // in : R0 = 0x00hhmmll R1=0x0000hhll // DESTROYED : R0,R1,R2,R3 // UPDATE : regCycles //R1 <= block MOV R2,R0,LSL #19 ADDS R2,R2,#0x80000 //if = 0x1FFF => 0 BNE SW_NotBoundary STMFD R13!,{R0,R1} STMFD R13!,{PC} B asmS9xSetByte MOV R0,R0 LDMFD R13!,{R0,R1} ADD R0,R0,#1 MOV R1,R1,LSR #8 STMFD R13!,{PC} B asmS9xSetByte MOV R0,R0 LDMFD R13!,{PC} SW_NotBoundary: MOV R2,#0 STR R2,[regCPUvar,#WaitAddress_ofs] // //R3 <= block MOV R3,R0,LSR #MEMMAP_SHIFT //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so //R1 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF //so AND MEMMAP_MASK is BIC 0xFF000 BIC R3,R3,#0xFF000 //R2 <= Map[block] (SetAddress) LDR R2,[regCPUvar,#WriteMap_ofs] LDR R2,[R2,R3,LSL #2] CMP R2,#MAP_LAST BLO SWSpecial //special // Direct ROM/RAM acess //check if address is 16bits aligned or not TST R0,#1 BNE SW_not_aligned1 //aligned MOV R0,R0,LSL #16 ADD R2,R2,R0,LSR #16 //address & 0xFFFF + SetAddress LDR R0,[regCPUvar,#MemorySpeed_ofs] //Set word STRH R1,[R2] //R1 <= MemorySpeed[block] LDRB R0,[R0,R3] //Update CPU.Cycles ADD regCycles,regCycles,R0, LSL #1 //CPUShutdown //only SA1 here : TODO //Return LDMFD R13!,{PC} SW_not_aligned1: //R1 = (Address&0xFFFF)<<16 MOV R0,R0,LSL #16 //First write @address STRB R1,[R2,R0,LSR #16] ADD R0,R0,#0x10000 MOV R1,R1,LSR #8 //Second write @address+1 STRB R1,[R2,R0,LSR #16] //R1 <= MemorySpeed[block] LDR R0,[regCPUvar,#MemorySpeed_ofs] LDRB R0,[R0,R3] //Update CPU.Cycles ADD regCycles,regCycles,R0,LSL #1 //CPUShutdown //only SA1 here : TODO //Return LDMFD R13!,{PC} SWSpecial: #ifdef __PALMOS__ LDR R3,[regCPUvar,#PALMOS_R10_ofs] LDR R2,[PC,R2,LSL #2] ADD PC,R2,R3 #else LDR PC,[PC,R2,LSL #2] MOV R0,R0 //nop, for align #endif .long SWPPU .long SWCPU .long SWDSP .long SWLSRAM .long SWHSRAM .long SWNONE .long SWDEBUG .long SWC4 .long SWBWRAM .long SWNONE .long SWNONE .long SWNONE /*.long SW7ROM .long SW7RAM .long SW7SRM*/ SWPPU: //InDMA ? LDRB R2,[regCPUvar,#InDMA_ofs] MOVS R2,R2 ADDEQ regCycles,regCycles,#(ONE_CYCLE*2) //No -> update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 MOV R2,R1 MOV R1,R0 MOV R0,R2 PREPARE_C_CALL_R0R1 BL S9xSetPPU LDMFD R13!,{R0,R1} ADD R1,R1,#1 MOV R0,R0,LSR #8 BIC R1,R1,#0x10000 BL S9xSetPPU RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SWCPU: ADD regCycles,regCycles,#(ONE_CYCLE*2) //update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 //Address&0xFFFF MOV R2,R1 MOV R1,R0 MOV R0,R2 PREPARE_C_CALL_R0R1 BL S9xSetCPU LDMFD R13!,{R0,R1} ADD R1,R1,#1 MOV R0,R0,LSR #8 BIC R1,R1,#0x10000 BL S9xSetCPU RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SWDSP: ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 //Address&0xFFFF MOV R2,R1 MOV R1,R0 MOV R0,R2 PREPARE_C_CALL_R0R1 BL S9xSetDSP LDMFD R13!,{R0,R1} ADD R1,R1,#1 MOV R0,R0,LSR #8 BIC R1,R1,#0x10000 BL S9xSetDSP RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SWLSRAM: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles LDRH R2,[regCPUvar,#SRAMMask] MOVS R2,R2 LDMEQFD R13!,{PC} //return if SRAMMask=0 AND R3,R2,R0 //Address&SRAMMask TST R0,#1 BNE SW_not_aligned2 //aligned LDR R0,[regCPUvar,#SRAM] STRH R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SW_not_aligned2: ADD R0,R0,#1 AND R2,R2,R0 //(Address+1)&SRAMMask LDR R0,[regCPUvar,#SRAM] STRB R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask MOV R1,R1,LSR #8 STRB R1,[R0,R2] //*Memory.SRAM + (Address+1)&SRAMMask MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SW7SRM: SWHSRAM: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles LDRH R2,[regCPUvar,#SRAMMask] MOVS R2,R2 LDMEQFD R13!,{PC} //return if SRAMMask=0 TST R0,#1 BNE SW_not_aligned3 //aligned MOV R3,R0,LSL #17 AND R2,R0,#0xF0000 MOV R3,R3,LSR #17 //Address&0x7FFF MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) ADD R0,R2,R3 SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) LDRH R2,[regCPUvar,#SRAMMask] LDR R3,[regCPUvar,#SRAM] AND R0,R2,R0 //Address&SRAMMask STRH R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SW_not_aligned3: MOV R3,R0,LSL #17 AND R2,R0,#0xF0000 MOV R3,R3,LSR #17 //Address&0x7FFF MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) ADD R2,R2,R3 SUB R2,R2,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) ADD R0,R0,#1 MOV R3,R0,LSL #17 AND R0,R0,#0xF0000 MOV R3,R3,LSR #17 //(Address+1)&0x7FFF MOV R0,R0,LSR #3 //((Address+1)&0xF0000 >> 3) ADD R0,R0,R3 LDRH R3,[regCPUvar,#SRAMMask] //reload mask SUB R0,R0,#0x6000 //(((Address+1) & 0x7fff) - 0x6000 + (((Address+1) & 0xf0000) >> 3)) AND R2,R3,R2 //Address...&SRAMMask AND R0,R3,R0 //(Address+1...)&SRAMMask LDR R3,[regCPUvar,#SRAM] STRB R1,[R2,R3] //*Memory.SRAM + (Address...)&SRAMMask MOV R1,R1,LSR #8 STRB R1,[R0,R3] //*Memory.SRAM + (Address+1...)&SRAMMask MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SW7ROM: SW7RAM: SWNONE: SWDEBUG: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles LDMFD R13!,{PC} //return SWC4: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles MOV R0,R0,LSL #16 STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles MOV R0,R0,LSR #16 //Address&0xFFFF MOV R2,R1 MOV R1,R0 MOV R0,R2 PREPARE_C_CALL_R0R1 BL S9xSetC4 LDMFD R13!,{R0,R1} ADD R1,R1,#1 MOV R0,R0,LSR #8 BIC R1,R1,#0x10000 BL S9xSetC4 RESTORE_C_CALL LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles LDMFD R13!,{PC} //Return SWBWRAM: ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles TST R0,#1 BNE SW_not_aligned4 //aligned MOV R0,R0,LSL #17 LDR R2,[regCPUvar,#BWRAM] MOV R0,R0,LSR #17 //Address&0x7FFF SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) MOV R3,#1 STRH R1,[R0,R2] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) STRB R3,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return SW_not_aligned4: MOV R0,R0,LSL #17 ADD R3,R0,#0x20000 MOV R0,R0,LSR #17 //Address&0x7FFF MOV R3,R3,LSR #17 //(Address+1)&0x7FFF LDR R2,[regCPUvar,#BWRAM] SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) SUB R3,R3,#0x6000 //(((Address+1) & 0x7fff) - 0x6000) STRB R1,[R2,R0] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) MOV R1,R1,LSR #8 STRB R1,[R2,R3] //*Memory.BWRAM + (((Address+1) & 0x7fff) - 0x6000) MOV R0,#1 STRB R0,[regCPUvar,#SRAMModified_ofs] LDMFD R13!,{PC} //return .pool