Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .686
- .mmx
- .xmm
- .model flat, c
- option casemap :none
- ;; mmu read/write
- ;; internal will set arm7tdmi::waitState
- extrn agb_mbus_rb@8:proc ;; prototype uint8_t __stdcall agb_mbus_rb (struct gameboy_adv *agb, uint16_t addresss)
- extrn agb_mbus_rhw@8:proc ;; prototype uint16_t __stdcall agb_mbus_rhw (struct gameboy_adv *agb, uint16_t addresss)
- extrn agb_mbus_rw@8:proc ;; prototype uint32_t __stdcall agb_mbus_rw (struct gameboy_adv *agb, uint16_t addresss)
- extrn agb_mbus_wb@12:proc ;; prototype void __stdcall agb_mbus_wb (struct gameboy_adv *agb, uint16_t addresss, uint8_t value)
- extrn agb_mbus_whw@12:proc ;; prototype void __stdcall agb_mbus_whw (struct gameboy_adv *agb, uint16_t addresss, uint16_t value)
- extrn agb_mbus_ww@12:proc ;; prototype void __stdcall agb_mbus_ww (struct gameboy_adv *agb, uint16_t addresss, uint32_t value)
- extrn agb_code_rhw@8:proc ;; prototype uint16_t __stdcall agb_code_rhw (struct gameboy_adv *agb, uint16_t addresss)
- extrn agb_code_rw@8:proc ;; prototype uint32_t __stdcall agb_code_rw (struct gameboy_adv *agb, uint16_t addresss)
- ;; ARM7 Exceptions Address
- ;; In GBA, We just need to care about RESET, IRQ and BIOS software interrupts.
- ARM7_VECTOR_RESET equ 000h
- ARM7_VECTOR_UNDEF equ 004h
- ARM7_VECTOR_SOFTWARE equ 008h
- ARM7_VECTOR_PREFETCH_ABORT equ 00Ch
- ARM7_VECTOR_DATA_ABORT equ 010h
- ARM7_VECTOR_IRQ equ 018h
- ARM7_VECTOR_FIQ equ 01Ch
- ARM7_DEBUG equ 1
- GBA_IE_IF_MASK equ 00EFFFh
- ARM7_MODE_CLR_MASK equ 0E0FFFFFFh
- ARM7_MODE_IRQ_MASK equ 012000000h
- ARM7_MODE_MGR_MASK equ 013000000h
- ARM7_MODE_USER_MASK equ 010000000h
- ARM7_MODE_FIQ_MASK equ 011000000h
- ARM7_MODE_UNDEF_MASK equ 01B000000h
- ARM7_MODE_SYS_MASK equ 01F000000h
- ARM7_MODE_ABT_MASK equ 017000000h
- ARM7_MODE_GET_MASK equ 01F000000h
- ARM7_THUMB_BIT equ 29
- ARM7_MODE_SFT_BIT equ 24
- ERRORS_ASSERT equ MOECMKS_DONE
- ALIGN_Z equ align 16
- .data
- s_ModeUser__ db 'MODE:USER', 0
- s_ModeSys__ db 'MODE:SYS', 0
- s_ModeUdef__ db 'MODE:Undef', 0
- s_ModeABT__ db 'MODE:Abort', 0
- s_ModeIRQ__ db 'MODE:IRQ', 0
- s_ModeFIQ__ db 'MODE:FIQ', 0
- s_ModeMGR__ db 'MODE:MGR', 0
- s_ModeTabs dd s_ModeUser__, s_ModeFIQ__, s_ModeIRQ__, s_ModeMGR__
- dd s_ModeUser__, s_ModeUser__, s_ModeUser__, s_ModeABT__
- dd s_ModeUser__, s_ModeUser__, s_ModeUser__, s_ModeUdef__
- dd s_ModeUser__, s_ModeUser__, s_ModeUser__, s_ModeSys__
- IF ARM7_DEBUG eq 0
- DEBUG_OUT macro format, arglist:vararg
- ;; nodone in non-debug mode
- endm
- ELSEIF ARM7_DEBUG eq 1
- printf PROTO C :DWORD,:VARARG
- ;; input : "content"
- rdata_mak macro format
- LOCAL mID ;; loop's iterator
- LOCAL mLEN
- LOCAL mCHSET ; eg. "Hello World", 00Ah, "Goddbyte word", 0
- LOCAL mN ;; Pos init left.
- LOCAL mTAIL_COMP ;; :BOOL init tail comp ,
- LOCAL mT1 ;; fro calc temp
- LOCAL mT2 ;; fro calc temp
- mN = 1
- mID = 0
- mTAIL_COMP = 0
- mLEN = @SizeStr (format)
- mCHSET TEXTEQU <>
- ;; mCHSET CATSTR mCHSET, <ccc db >
- ;; echo format
- FORC CHS, <format>
- IFIDN <CHS>, <\>
- IF mID ne (mLEN-2)
- CHR_N TEXTEQU @SubStr (format, mID+2, 1)
- %FORC CHS_N, CHR_N
- IFIDN <CHS_N>, <n>
- IF mID eq (mLEN-3)
- mTAIL_COMP = 1
- ENDIF
- IF mID ne 1
- IF (mID-mN) ne 0
- mT1 = mN+1
- mT2 = mID - mN
- mCHSET CATSTR mCHSET, <!">, @SubStr (format, mT1, mT2), <!"!,>
- ENDIF
- ENDIF
- mN = mID + 2
- mCHSET CATSTR mCHSET, <00Ah>, <!,>
- ENDIF
- ENDM
- ENDIF
- ENDIF
- mID = mID + 1
- ENDM
- ;; add tail
- IF mTAIL_COMP ne 1
- ;; echo <mTAIL_INCOMP>
- mLEN = mLEN - mN - 1
- mN = mN + 1
- mCHSET CATSTR mCHSET, <!">, @SubStr (format, mN, mLEN), <!"!, 0>
- ELSEIF mTAIL_COMP eq 1
- ;; echo <mTAIL_COMP>
- mCHSET CATSTR mCHSET, <0>
- ENDIF
- ;; %echo mCHSET
- EXITM <mCHSET>
- endm
- tem_rev_arg macro arg1, arglist:vararg
- LOCAL mCHSET
- mCHSET TEXTEQU <arg1>
- FOR ARG, <arglist>
- mCHSET CATSTR <ARG>, <!,>, mCHSET
- ENDM
- EXITM <mCHSET>
- endm
- tem_alphatoint macro arg
- IFIDNI <arg>, <0>
- EXITM <0>
- ELSEIFIDNI <arg>, <1>
- EXITM <1>
- ELSEIFIDNI <arg>, <2>
- EXITM <2>
- ELSEIFIDNI <arg>, <3>
- EXITM <3>
- ELSEIFIDNI <arg>, <4>
- EXITM <4>
- ELSEIFIDNI <arg>, <5>
- EXITM <5>
- ELSEIFIDNI <arg>, <6>
- EXITM <6>
- ELSEIFIDNI <arg>, <7>
- EXITM <7>
- ELSEIFIDNI <arg>, <8>
- EXITM <8>
- ELSEIFIDNI <arg>, <9>
- EXITM <9>
- ELSEIFIDNI <arg>, <A>
- EXITM <10>
- ELSEIFIDNI <arg>, <B>
- EXITM <11>
- ELSEIFIDNI <arg>, <C>
- EXITM <12>
- ELSEIFIDNI <arg>, <D>
- EXITM <13>
- ELSEIFIDNI <arg>, <E>
- EXITM <14>
- ELSEIFIDNI <arg>, <F>
- EXITM <15>
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- tem_push_arg macro arglist0:vararg
- ;; e.g. "eax>7&00Ah", "ecx<5&ecx"
- ;; op } shift right 0
- ;; op { shift left 1
- ;; op + add 2
- ;; op - sub 3
- ;; op & and 4
- ;; op ^ xor 5
- ;; op | or 6
- ;; op ~ ror right 7
- ;; op ? 8 lhs rhs link sym, after ?, must offer a op symbol
- ;; src/dst : reg or imm (e.g. 0A00h, 1, 2, 3)
- ;;
- ;; Z0-ZF Mapper register 0-15 (current)
- ;; U0-UF Mapper register 0-15 (sys/user)
- ;; Q0-QF Mapper register 0-15 (irq) F:=SPSR
- ;; M0-MF Mapper register 0-15 (mgr) F:=SPSR
- ;; O0-O1 pipeline opcode
- ;;
- ;; $alu, get value register index, outval
- LOCAL mRSC_POS ;; lhs's end pos
- LOCAL mLEN
- LOCAL mID
- LOCAL mOP
- LOCAL mT
- LOCAL mT2
- LOCAL mT3
- LOCAL mSET_TYPE ;;
- LOCAL mTEMP
- LOCAL mID2
- LOCAL mTEMP2
- LOCAL mSIGJ
- LOCAL mACRG
- LOCAL mCC
- LOCAL mDIS
- LOCAL mLINK
- LOCAL mAGQ
- FOR arg, <arglist0>
- mRSC_POS = 1
- mLEN = @SizeStr (arg)
- mID = 0
- mOP = -1
- mSIGJ = 0
- mACRG = 0
- mDIS = 0
- mLINK = 0
- mAGQ TEXTEQU <!?>
- FORC CHS, <arg>
- IFIDN <CHS>, <!#>
- mDIS =1
- ENDIF
- ENDM
- IF mDIS eq 1
- GOTO IBGS
- ENDIF
- ;; %echo arg
- FORC CHS, <arg>
- ; echo CHS
- mSET_TYPE = -1
- mT = 0
- mT2 = 0
- mACRG = 0
- IF mLINK ne 0
- mLINK = mLINK - 1 ;; skip n.
- GOTO IBGA
- ENDIF
- IFIDN <CHS>, <!">
- IF mID eq (mLEN-1)
- mSET_TYPE = 0
- ENDIF
- ELSEIFIDN <CHS>, < >
- ;; Skip it.
- ELSEIFIDN <CHS>, <!?>
- ;; adjust pos, to rhs
- mT = mID + 2
- mAGQ SUBSTR <arg>, mT, 1
- mACRG = 1
- mSET_TYPE = 0
- ELSEIFIDN <CHS>, <!$> ;; set reg
- mSIGJ = 1
- mRSC_POS = mRSC_POS + 1
- ELSEIFIDN <CHS>, <!{>
- mSET_TYPE = 0
- ELSEIFIDN <CHS>, <!}>
- mSET_TYPE = 1
- ELSEIFIDN <CHS>, <!+>
- mSET_TYPE = 2
- ELSEIFIDN <CHS>, <!->
- mSET_TYPE = 3
- ELSEIFIDN <CHS>, <!&>
- mSET_TYPE = 4
- ELSEIFIDN <CHS>, <!^>
- mSET_TYPE = 5
- ELSEIFIDN <CHS>, <!|>
- mSET_TYPE = 6
- ELSEIFIDN <CHS>, <!~>
- mSET_TYPE = 7
- ENDIF
- IF mSET_TYPE ne -1
- ;; Check MAPPER
- mT = mRSC_POS + 1
- mT2 = mID - 1 - mRSC_POS + 1
- mTEMP TEXTEQU @SubStr (<arg>, mT, mT2)
- mT = 0
- mT2= 1
- mID2 = 0
- %FORC CHS_N, mTEMP
- IFIDNI <CHS_N>, <Z>
- mT = mID2+2
- mCC SubStr mTEMP, mT, 1
- mTEMP2 CATSTR <![SC_ARM7!].Regs![0>, mCC, <h*4!]>
- mT2 = 0
- ELSEIFIDNI <CHS_N>, <O>
- mT = mID2+2
- mCC SubStr mTEMP, mT, 1
- mTEMP2 CATSTR <![SC_ARM7!].Opcode![>, <0>, mCC, <h*4!]>
- mT2 = 0
- ELSEIFIDNI <CHS_N>, <U> ;;sys/user
- mT = mID2+2
- mCC SubStr mTEMP, mT, 1
- mT3 = tem_alphatoint (%mCC)
- mT2 = 0
- mT3 = mT3 + 1
- mT3 = mT3 and 15
- mTEMP2 CATSTR <![SC_ARM7!].Regs![>, <0>, mCC, <h*4!]>
- IF mT3 GE 14
- mTEMP2 TEXTEQU <>
- mTEMP2 CATSTR <![SC_ARM7!].R1314_T![R1314b_SYSUSER>, <!(0>, mCC, <h-13!)*4!]>
- ENDIF
- ELSEIFIDNI <CHS_N>, <Q> ;;IRQ
- mT = mID2+2
- mCC SubStr mTEMP, mT, 1
- mT3 = tem_alphatoint (%mCC)
- mT3 = mT3 + 1
- mT3 = mT3 and 15
- mT2 = 0
- mTEMP2 CATSTR <![SC_ARM7!].Regs![>, <0>, mCC, <h*4!]>
- IF mT3 GE 14
- mTEMP2 CATSTR <![SC_ARM7!].R1314_T![R1314b_IRQ>, <!(0>, mCC, <h-13!)*4!]>
- ELSEIF mT3 EQ 0
- mTEMP2 TEXTEQU <>
- mTEMP2 CATSTR <![SC_ARM7!].SPSR_T![SPSRb_IRQ]>
- ENDIF
- ELSEIFIDNI <CHS_N>, <M> ;;MGR
- mT = mID2+2
- mCC SubStr mTEMP, mT, 1
- mT3 = tem_alphatoint (%mCC)
- mT3 = mT3 + 1
- mT2 = 0
- mT3 = mT3 and 15
- mTEMP2 CATSTR <![SC_ARM7!].Regs![>, <0>, mCC, <h*4!]>
- IF mT3 GE 14
- mTEMP2 TEXTEQU <>
- mTEMP2 CATSTR <![SC_ARM7!].R1314_T![R1314b_MGR>, <!(0>, mCC, <h-13!)*4!]>
- ELSEIF mT3 EQ 0
- mTEMP2 TEXTEQU <>
- mTEMP2 CATSTR <![SC_ARM7!].SPSR_T![SPSRb_MGR]>
- ENDIF
- ENDIF
- mID2 = mID2 +1
- ENDM
- IF mT2 eq 0
- mTEMP TEXTEQU mTEMP2
- ENDIF
- movd xmm7, eax
- mov eax, mTEMP
- movd xmm1, eax
- movd eax, xmm7
- IF mOP eq -1 ;; mem/imm/reg.
- movdqa xmm0, xmm1
- ELSEIF mOP eq 0
- movd xmm7, eax
- movd xmm6, ecx
- movd ecx, xmm1
- movd eax, xmm0
- shl eax, cl
- movd xmm0, eax
- movd eax, xmm7
- movd ecx, xmm6
- ELSEIF mOP eq 1
- movd xmm7, eax
- movd xmm6, ecx
- movd ecx, xmm1
- movd eax, xmm0
- shr eax, cl
- movd xmm0, eax
- movd eax, xmm7
- movd ecx, xmm6
- ELSEIF mOP eq 2 ;; + mem/imm/reg.
- paddd xmm0, xmm1
- ELSEIF mOP eq 3
- psubd xmm0, xmm1
- ELSEIF mOP eq 4 ;; &
- pand xmm0, xmm1
- ELSEIF mOP eq 5
- pxor xmm0, xmm1
- ELSEIF mOP eq 6
- por xmm0, xmm1
- ELSEIF mOP eq 7 ;; ror it.
- movd xmm7, eax
- movd xmm6, ecx
- movd ecx, xmm1
- movd eax, xmm0
- ror eax, cl
- movd xmm0, eax
- movd eax, xmm7
- movd ecx, xmm6
- ELSE
- ERRORS_ASSERT
- ENDIF
- mOP = mSET_TYPE
- mRSC_POS = mID+1
- IF mACRG ne 0
- mACRG = 0
- mLINK = 1
- mOP = -1
- mRSC_POS = mID + 2
- mSIGJ = 0
- movdqa xmm5, xmm0
- ENDIF
- ENDIF
- :IBGA
- mID = mID + 1
- ENDM
- %FORC CHS_N, mAGQ
- IFIDNI <CHS_N>, <!?>
- IF mSIGJ eq 1
- movd xmm1, eax
- movd eax, xmm0
- and eax, 15
- push dword ptr[SC_ARM7].Regs[eax*4]
- movd eax, xmm1
- ELSE
- movd xmm1, eax
- movd eax, xmm0
- push eax
- movd eax, xmm1
- ENDIF
- ELSE
- IFIDN <CHS_N>, <!{>
- movd xmm7, eax
- movd xmm6, ecx
- movd ecx, xmm0
- movd eax, xmm5
- shl eax, cl
- movd xmm5, eax
- movd eax, xmm7
- movd ecx, xmm6
- ELSEIFIDN <CHS_N>, <!}>
- movd xmm7, eax
- movd xmm6, ecx
- movd ecx, xmm0
- movd eax, xmm5
- shr eax, cl
- movd xmm5, eax
- movd eax, xmm7
- movd ecx, xmm6
- ELSEIFIDN <CHS_N>, <!+>
- paddd xmm5, xmm0
- ELSEIFIDN <CHS_N>, <!->
- psubd xmm5, xmm0
- ELSEIFIDN <CHS_N>, <!&>
- pand xmm5, xmm0
- ELSEIFIDN <CHS_N>, <!^>
- pxor xmm5, xmm0
- ELSEIFIDN <CHS_N>, <!|>
- por xmm5, xmm0
- ELSEIFIDN <CHS_N>, <!~>
- movd xmm7, eax
- movd xmm6, ecx
- movd ecx, xmm0
- movd eax, xmm5
- ror eax, cl
- movd xmm5, eax
- movd eax, xmm7
- movd ecx, xmm6
- ELSE
- ENDIF
- movd xmm7, eax
- movd eax, xmm5
- push eax
- movd eax, xmm7
- ENDIF
- ENDM
- :IBGS
- IF mDIS eq 1
- ;; MAKE DISPLAY.
- movd xmm0, eax
- movd xmm1, ebx
- mov eax, SC_CPSR
- shr eax, ARM7_MODE_SFT_BIT
- and eax, 01Fh
- sub eax, 16
- push dword ptr [s_ModeTabs+eax*4]
- movd eax, xmm0
- movd ebx, xmm1
- .code
- ENDIF
- :IBGC
- ENDM
- endm
- tem_print macro format, arglist:vararg
- LOCAL cstr
- ARGLIST_EMPTY = 0
- FOR ARG,<arglist>
- ARGLIST_EMPTY = ARGLIST_EMPTY + 4
- ENDM
- .data
- cstr db rdata_mak (format)
- .code
- push eax
- push edx
- push ecx
- %tem_push_arg tem_rev_arg (arglist)
- push offset cstr
- CALLIt printf
- add esp, 4
- add esp, ARGLIST_EMPTY
- pop ecx
- pop edx
- pop eax
- endm
- DEBUG_OUT equ tem_print
- ENDIF
- ;; GBA Mmu Operate
- MmuReadByte equ agb_mbus_rb@8
- MmuReadHalfWord equ agb_mbus_rhw@8
- MmuReadWord equ agb_mbus_rw@8
- MmuWriteByte equ agb_mbus_wb@12
- MmuWriteHalfWord equ agb_mbus_whw@12
- MmuWriteWord equ agb_mbus_ww@12
- FetchARM7Code equ agb_code_rw@8
- FetchThumbCode equ agb_code_rhw@8
- IF 1
- CALLIt macro Symbol
- call Symbol
- endm
- ELSE
- CALLIt macro Symbol
- CALLIt dword ptr[Symbol]
- endm
- ENDIF
- CallMemOrIO macro Symbol
- push [SC_ARM7].agb
- CALLIt Symbol
- endm
- CallMemOrIOAddWaitState macro Symbol
- push [SC_ARM7].agb
- CALLIt Symbol
- add SC_GOAL_COUNT, [SC_ARM7].waitState
- endm
- Add_WaitStateClks equ add SC_GOAL_COUNT, [SC_ARM7].waitState
- ;; XXX:memory order indep
- arm7tdmi struct
- SZ_STACK equ 13
- SZ_LRLINK equ 14
- SZ_PC equ 15
- SZ_CPSR equ 16
- Regs dd 17 dup (?)
- R812_T dd 10 dup (?)
- R1314_T dd 12 dup (?)
- SPSR_T dd 6 dup (?)
- Opcode dd 2 dup (?)
- IME dd ?
- IFS dd ?
- IE dd ?
- waitState dd ?
- waitStateTemp dd ?
- agb dd ?
- ;; owiBank dd ? ;; for opcode cache switch, always pointer to next empty opcode
- arm7tdmi ends
- IRQ_INHIBI_MASK equ 080000000h
- FIQ_INHIBI_MASK equ 040000000h
- MODE_SYS equ 001Fh
- MODE_USER equ 00010h
- MODE_SFT_BASE_PSR equ 24
- FLAG_THUMB equ 020000000H
- FLAG_CZ equ (FLAG_C or FLAG_Z)
- FLAG_NZ equ (FLAG_N or FLAG_Z)
- FLAG_C equ 000100H
- FLAG_V equ 000001H
- FLAG_N equ 008000H
- FLAG_Z equ 004000H
- FLAG_N_TOLSB_BIT equ 15
- FLAG_N_TO_V_ALIGN_BIT equ 15
- FLAG_N_TO_V_ALIGN_SHIFT equ shr
- FLAG_V_TOLSB_BIT equ 0
- FLAG_Z_TOLSB_BIT equ 14
- FLAG_C_TOLSB_BIT equ 8
- FLAG_CHECK_C_X86_BT equ 8
- FLAG_MSR_FLAGS equ 00080000h
- FLAG_MSR_CTL equ 00010000h
- R812b_BLOCK equ 20
- R812b_FIQ equ R812b_BLOCK *0
- R812b_OTHER equ R812b_BLOCK *1
- R1314b_BLOCK equ 8
- R1314b_SYSUSER equ R1314b_BLOCK*0
- R1314b_FIQ equ R1314b_BLOCK*1
- R1314b_IRQ equ R1314b_BLOCK*2
- R1314b_UNDEF equ R1314b_BLOCK*3
- R1314b_MGR equ R1314b_BLOCK*4
- R1314b_ABORT equ R1314b_BLOCK*5
- SPSRb_BLOCK equ 4
- SPSRb_FIQ equ SPSRb_BLOCK*0
- SPSRb_SYSUSER equ SPSRb_BLOCK*1
- SPSRb_IRQ equ SPSRb_BLOCK*2
- SPSRb_UNDEF equ SPSRb_BLOCK*3
- SPSRb_MGR equ SPSRb_BLOCK*4
- SPSRb_ABORT equ SPSRb_BLOCK*5
- XRFI equ dword ptr[SC_ARM7].Regs
- XRFI16 equ word ptr[SC_ARM7].Regs
- XRFI8 equ byte ptr[SC_ARM7].Regs
- SetNZCV_A macro sub_bit ;; 1 indicate sub otherwise 0
- lahf
- seto al
- xor ah, sub_bit
- mov SC_CPSR16, ax
- endm
- SetNZC_A macro sub_bit ;; 1 indicate sub otherwise 0
- lahf
- mov SC_CPSR16H, ah
- endm
- ClrNZ_SetC_A macro
- lahf
- and SC_CPSR, not (FLAG_N or FLAG_Z or FLAG_C)
- and eax, FLAG_C
- or SC_CPSR, eax
- endm
- SetNZ_A macro
- lahf
- and SC_CPSR, not (FLAG_N or FLAG_Z) ;; nz clear
- and eax, FLAG_NZ ;; save nz
- or SC_CPSR, eax ;;nz reset
- endm
- Set_NZmul32 macro out_reg
- sub out_reg, 0
- SetNZ_A
- endm
- Set_NZmul64 macro out_lo, out_hi
- and SC_CPSR, not (FLAG_N or FLAG_Z) ;; nz clear
- test out_hi, 080000000H
- jne @F
- or SC_CPSR, FLAG_N
- @@: or out_hi, out_lo
- jne @F
- or SC_CPSR, FLAG_Z
- @@:
- endm
- ;; ToStandCPSR
- ;; destroy : ecx, eax
- ToStandCPSR macro _PostRegs, _REC, TRegs1_Alpha, TRegs2_Alpha
- ;; 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (MINE)
- ;; I F T M M M M M R R R R R R R R N Z R R R R R C R R R R R R R V
- ;; 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (STD)
- ;; N Z C V R R R R R R R R R R R R R R R R R R R R I F T M M M M M
- epx equ e&TRegs1_Alpha&x
- px equ TRegs1_Alpha&x
- emx equ e&TRegs2_Alpha&x
- mx equ TRegs2_Alpha&x
- pl equ TRegs1_Alpha&l
- ph equ TRegs1_Alpha&h
- ml equ TRegs2_Alpha&l
- mh equ TRegs2_Alpha&h
- mov epx, _PostRegs
- mov emx, _PostRegs
- ror epx, 16
- ror px, 8
- shl mh, 1
- and ml, 1
- or mh, ml
- and emx, 3
- and epx, 0CFFFFFFFH
- shl emx, 28
- or epx, emx
- or epx, 00FFFFF00H
- mov _REC, epx
- endm
- ;; ToFastCPSR
- ;; destroy : ecx, eax
- ToFastCPSR macro _PostRegs, _REC, TRegs1_Alpha, TRegs2_Alpha
- ;; 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (MINE)
- ;; I F T M M M M M R R R R R R R R N Z R R R R R C R R R R R R R V
- ;; 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (STD)
- ;; N Z C V R R R R R R R R R R R R R R R R R R R R I F T M M M M M
- epx equ e&TRegs1_Alpha&x
- px equ TRegs1_Alpha&x
- emx equ e&TRegs2_Alpha&x
- mx equ TRegs2_Alpha&x
- pl equ TRegs1_Alpha&l
- ph equ TRegs1_Alpha&h
- ml equ TRegs2_Alpha&l
- mh equ TRegs2_Alpha&h
- mov epx, _PostRegs
- mov emx, _PostRegs
- ror epx, 8
- ror emx, 20
- mov pl, mh
- mov ph, mh
- shr ph, 1
- shl emx, 4
- and emx, 00000C000h
- and epx, 0FFFF3FFFh
- or epx, emx
- or epx, 000FF3EFEh
- mov _REC, epx
- endm
- ;; destroy eax, ecx
- Imm8BitmapSft_AC macro Sft4Imm8, REC
- mov eax, Sft4Imm8
- mov ecx, Sft4Imm8
- and eax, 0FFh
- and ecx, 0F00h
- shr ecx, 7
- ror eax, cl
- mov REC, eax
- endm
- C_op_Care equ 0
- C_op_NOCare equ 1
- ;; XXX: better case
- ShiftRegImm5 macro Post, REC, tr1c, tr2, lSym, C_op
- mov tr1c, Post
- mov tr2, Post
- shr tr1c, 5
- and tr1c, 3
- IF C_op eq C_op_NOCare
- mov [esp-8], SC_CPSR
- IF ARM7_DEBUG ne 0
- sub esp, 32
- ENDIF
- ENDIF
- jmp si5TAB&lSym[tr1c*4]
- Si5SftOp macro X86Sft
- mov tr1c, tr2
- and tr2, 15
- mov tr2, XRFI[tr2*4] ;; Get Rm.
- shr tr1c, 7
- and tr1c, 31
- je @F
- and SC_CPSR, not FLAG_C
- X86Sft tr2, cl ;; check c
- sbb tr1c, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp si5fi&lSym
- endm
- ;; tr1c := 0
- si5LSL&lSym:
- DEBUG_OUT "LSL #%d ", "SC_INVOLATILE}6 & 31"
- Si5SftOp shl
- @@:
- mov REC, tr2
- jmp si5fi&lSym
- si5LSR&lSym:
- DEBUG_OUT "LSR #%d ", "SC_INVOLATILE}6 & 31"
- Si5SftOp shr
- @@:
- and SC_CPSR, not FLAG_C
- xor tr1c, tr1c
- bt tr2, 31 ;; check c[31]
- sbb tr2, tr2
- and tr2, FLAG_C
- or SC_CPSR, tr2
- mov REC, tr1c
- jmp si5fi&lSym
- si5ASR&lSym:
- DEBUG_OUT "ASR #%d ", "SC_INVOLATILE}6 & 31"
- Si5SftOp sar
- @@:
- and SC_CPSR, not FLAG_C
- bt tr2, 31
- sbb tr1c, tr1c
- mov tr2, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp si5fi&lSym
- si5ROR&lSym:
- DEBUG_OUT "ROR #%d ", "SC_INVOLATILE}6 & 31"
- Si5SftOp ror
- @@: ;; RRX.
- DEBUG_OUT "...RRX "
- and SC_CPSR, not FLAG_C
- rcr tr2, 1 ;; check c
- sbb tr1c, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp si5fi&lSym
- si5TAB&lSym dd si5LSL&lSym, si5LSR&lSym, si5ASR&lSym, si5ROR&lSym
- si5fi&lSym:
- IF C_op eq C_op_NOCare
- IF ARM7_DEBUG ne 0
- add esp, 32
- ENDIF
- mov SC_CPSR, [esp-8]
- ENDIF
- DEBUG_OUT "Sft Result:%08X ", "&REC&"
- endm
- ;; XXX: better case
- ShiftRegRs macro Post, REC, tr1c, tr2, lSym, C_op
- mov tr1c, Post
- mov tr2, Post
- shr tr1c, 5
- and tr1c, 3
- IF C_op eq C_op_NOCare
- mov [esp-8], SC_CPSR
- IF ARM7_DEBUG ne 0
- sub esp, 32
- ENDIF
- ENDIF
- jmp rsTABcc&lSym[tr1c*4]
- Rs_SftOp macro X86Sft
- and SC_CPSR, not FLAG_C
- X86Sft tr2, cl ;; check c
- sbb tr1c, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp rsfi&lSym
- endm
- Rs_Stiff macro
- mov tr1c, tr2
- and tr2, 15
- mov tr2, XRFI[tr2*4] ;; Get Rm.
- shr tr1c, 8
- and tr1c, 15
- movzx tr1c, XRFI8[tr1c*4]
- ;; TODO:better case ?
- cmp tr1c, 32
- jl @F
- endm
- rsLSL&lSym:
- DEBUG_OUT "LSL R%d ", "SC_INVOLATILE}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- sete cl
- and ecx, 1
- and SC_CPSR, not FLAG_C
- and tr1c, tr2
- shl tr1c, FLAG_CHECK_C_X86_BT
- or SC_CPSR, tr1c
- xor REC, REC
- jmp rsfi&lSym
- @@:
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp rsfi&lSym
- @@:
- Rs_SftOp shl
- rsLSR&lSym:
- DEBUG_OUT "LSR R%d ", "SC_INVOLATILE}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- sete cl
- and ecx, 1
- and SC_CPSR, not FLAG_C
- bt tr2, 31
- sbb tr2, tr2
- and tr1c, tr2
- shl tr1c, FLAG_CHECK_C_X86_BT
- or SC_CPSR, tr1c
- xor REC, REC
- jmp rsfi&lSym
- @@:
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp rsfi&lSym
- @@:
- Rs_SftOp shr
- rsASR&lSym:
- DEBUG_OUT "ASR R%d ", "SC_INVOLATILE}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- and SC_CPSR, not FLAG_C
- shl tr2, 1
- sbb tr2, tr2
- mov tr1c, tr2
- and tr2, 1
- shl tr2, FLAG_CHECK_C_X86_BT
- or SC_CPSR, tr2
- mov REC, tr1c
- jmp rsfi&lSym
- @@:
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp rsfi&lSym
- @@:
- Rs_SftOp sar
- rsROR&lSym:
- DEBUG_OUT "ROR R%d ", "SC_INVOLATILE}8 & 15"
- mov tr1c, Post
- shr tr1c, 8
- and tr1c, 15
- movzx tr1c, XRFI8[tr1c*4]
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp rsfi&lSym
- @@:
- and tr1c, 31
- jne @F
- and SC_CPSR, not FLAG_C
- bt tr1c, 31
- sbb tr1c, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp rsfi&lSym
- @@:
- Rs_SftOp ror
- rsTABcc&lSym dd rsLSL&lSym, rsLSR&lSym, rsASR&lSym, rsROR&lSym
- rsfi&lSym:
- IF C_op eq C_op_NOCare
- IF ARM7_DEBUG ne 0
- add esp, 32
- ENDIF
- mov SC_CPSR, [esp-8]
- ENDIF
- DEBUG_OUT "Sft Result:%08X ", "&REC&"
- endm
- SPSRToCPSR macro tr
- ;; Copy SPSR to CPSR.
- GetCurSPSRP tr
- mov tr, [tr]
- ;; Switch CPU mode.
- SwitchMode tr
- endm
- SC_CPSR8 equ bl
- SC_CPSR16 equ bx
- SC_CPSR16H equ bh
- SC_CPSR equ ebx
- SC_GOAL_COUNT equ ebp
- SC_GOAL_COUNT16 equ bp
- SC_ARM7 equ esi
- SC_INVOLATILE equ edi
- ;; std fetch .
- arm7ClksFetch1 macro
- add SC_GOAL_COUNT, 1
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- mov eax, SC_INVOLATILE
- and eax, -4
- push eax
- CallMemOrIOAddWaitState FetchARM7Code
- mov [SC_ARM7].Opcode[4], eax
- add SC_INVOLATILE, 4
- mov XRFI[SZ_PC*4], SC_INVOLATILE
- jmp clksloop
- endm
- arm7ClksFetchN macro Clks
- add SC_GOAL_COUNT, Clks
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- mov eax, SC_INVOLATILE
- and eax, -4
- push eax
- CallMemOrIOAddWaitState FetchARM7Code
- mov [SC_ARM7].Opcode[4], eax
- add SC_INVOLATILE, 4
- mov XRFI[SZ_PC*4], SC_INVOLATILE
- jmp clksloop
- endm
- tbClksFetch1 macro
- add SC_GOAL_COUNT, 1
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- mov eax, SC_INVOLATILE
- and eax, -2
- push eax
- CallMemOrIOAddWaitState FetchThumbCode
- mov [SC_ARM7].Opcode[4], eax
- add SC_INVOLATILE, 2
- mov XRFI[SZ_PC*4], SC_INVOLATILE
- jmp clksloop
- endm
- tbClksFetchN macro Clks
- add SC_GOAL_COUNT, Clks
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- mov eax, SC_INVOLATILE
- and eax, -2
- push eax
- CallMemOrIOAddWaitState FetchThumbCode
- mov [SC_ARM7].Opcode[4], eax
- add SC_INVOLATILE, 2
- mov XRFI[SZ_PC*4], SC_INVOLATILE
- jmp clksloop
- endm
- arm7PipelineFlush macro Clks
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- add SC_GOAL_COUNT, Clks
- mov eax, SC_INVOLATILE
- add SC_INVOLATILE, 4
- and eax, -4
- push eax
- CallMemOrIOAddWaitState FetchThumbCode
- mov ecx, SC_INVOLATILE
- add SC_INVOLATILE, 4
- and ecx, -4
- push ecx
- mov dword ptr[SC_ARM7].Opcode[0], eax
- CallMemOrIOAddWaitState FetchThumbCode
- mov dword ptr[SC_ARM7].Opcode[4], eax
- mov XRFI[SZ_PC*4], SC_INVOLATILE
- jmp clksloop
- endm
- tbPipelineFlush macro Clks
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- add SC_GOAL_COUNT, Clks
- mov eax, SC_INVOLATILE
- add SC_INVOLATILE, 2
- and eax, -2
- push eax
- CallMemOrIOAddWaitState FetchThumbCode
- mov ecx, SC_INVOLATILE
- add SC_INVOLATILE, 2
- and ecx, -2
- push ecx
- mov dword ptr[SC_ARM7].Opcode[0], eax
- CallMemOrIOAddWaitState FetchThumbCode
- mov dword ptr[SC_ARM7].Opcode[4], eax
- mov XRFI[SZ_PC*4], SC_INVOLATILE
- jmp clksloop
- endm
- GetRFI macro Post, BitStart, REC
- mov REC, Post
- shr REC, BitStart
- and REC, 00Fh
- endm
- GetRFIV macro Post, BitStart, REC
- GetRFI Post, BitStart, REC
- mov REC, XRFI[REC*4]
- endm
- GetRFI_T macro Post, BitStart, REC
- mov REC, Post
- shr REC, BitStart
- and REC, 07h
- endm
- GetRFIV_T macro Post, BitStart, REC
- GetRFI Post, BitStart, REC
- mov REC, XRFI[REC*4]
- endm
- GetCurSPSRP macro REC
- LOCAL FIQ
- LOCAL IRQ
- LOCAL UDEF
- LOCAL SYS
- LOCAL USER
- LOCAL SVC
- LOCAL ABT
- LOCAL FINAL
- LOCAL SPSR_TABLE
- mov REC, SC_CPSR
- and REC, 01F000000h
- shr REC, 24
- jmp dword ptr [SPSR_TABLE+REC*4]
- ;; ---------------------------------------------------------------------------------
- SYS:
- USER:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_SYSUSER]
- jmp FINAL
- FIQ:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_FIQ]
- jmp FINAL
- UDEF:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_UNDEF]
- jmp FINAL
- ABT:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_FIQ]
- jmp FINAL
- SVC:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_MGR]
- jmp FINAL
- IRQ:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_IRQ]
- jmp FINAL
- .data
- ALIGN_Z
- SPSR_TABLE dd USER, FIQ, IRQ, SVC
- dd USER, USER, USER, ABT
- dd USER, USER, USER, UDEF
- dd USER, USER, USER, SYS
- .code
- FINAL:
- endm
- ;; switch SC_ARM7 mode
- ;; destroy: eax, ecx, edx
- SwitchMode macro SG_PSR, CPSR_Copy_dis:=<0>
- LOCAL FIQ
- LOCAL IRQ
- LOCAL UDEF
- LOCAL USER
- LOCAL SVC
- LOCAL ABT
- LOCAL SPSR_TABLE
- LOCAL FIQ2
- LOCAL IRQ2
- LOCAL UDEF2
- LOCAL USER2
- LOCAL SVC2
- LOCAL ABT2
- LOCAL SPSR2_TABLE
- LOCAL FINAL
- mov eax, SG_PSR
- mov edx, SC_CPSR
- mov ecx, SC_CPSR
- mov SC_CPSR, eax
- and eax, 01F000000h
- and edx, 01F000000h
- shr eax, 24
- shr edx, 24
- cmp eax, edx ;; edx:old mode. eax:new mode ecx: old full
- je FINAL
- sub eax, 16
- sub edx, 16
- jmp dword ptr [SPSR_TABLE+edx*4]
- saveR8_12 macro R812Bank, Post
- mov Post, XRFI[8*4]
- mov [SC_ARM7].R812_T[R812Bank+0*4], Post
- mov Post, XRFI[9*4]
- mov [SC_ARM7].R812_T[R812Bank+1*4], Post
- mov Post, XRFI[10*4]
- mov [SC_ARM7].R812_T[R812Bank+2*4], Post
- mov Post, XRFI[11*4]
- mov [SC_ARM7].R812_T[R812Bank+3*4], Post
- mov Post, XRFI[12*4]
- mov [SC_ARM7].R812_T[R812Bank+4*4], Post
- endm
- saveR13_14 macro R1314Bank, Post
- mov Post, XRFI[13*4]
- mov [SC_ARM7].R1314_T[R1314Bank+0*4], Post
- mov Post, XRFI[14*4]
- mov [SC_ARM7].R1314_T[R1314Bank+1*4], Post
- endm
- loadR8_12 macro R812Bank, Post
- mov Post, [SC_ARM7].R812_T[R812Bank+0*4]
- mov XRFI[8*4], Post
- mov Post, [SC_ARM7].R812_T[R812Bank+1*4]
- mov XRFI[9*4] , Post
- mov Post, [SC_ARM7].R812_T[R812Bank+2*4]
- mov XRFI[10*4], Post
- mov Post, [SC_ARM7].R812_T[R812Bank+3*4]
- mov XRFI[11*4], Post
- mov Post, [SC_ARM7].R812_T[R812Bank+4*4]
- mov XRFI[12*4], Post
- endm
- loadR13_14 macro R1314Bank, Post
- mov Post, [SC_ARM7].R1314_T[R1314Bank+0*4]
- mov XRFI[13*4] , Post
- mov Post, [SC_ARM7].R1314_T[R1314Bank+1*4]
- mov XRFI[14*4] , Post
- endm
- ;; -------------------------------------- Mode Current Check Save to banklk --------------------------------------------
- USER:
- saveR8_12 R812b_OTHER, edx
- saveR13_14 R1314b_SYSUSER, edx
- jmp dword ptr [SPSR2_TABLE+eax*4]
- FIQ:
- saveR8_12 R812b_FIQ, edx
- saveR13_14 R1314b_FIQ, edx
- jmp dword ptr [SPSR2_TABLE+eax*4]
- UDEF:
- saveR8_12 R812b_OTHER, edx
- saveR13_14 R1314b_UNDEF, edx
- jmp dword ptr [SPSR2_TABLE+eax*4]
- ABT:
- saveR8_12 R812b_OTHER, edx
- saveR13_14 R1314b_ABORT, edx
- jmp dword ptr [SPSR2_TABLE+eax*4]
- SVC:
- saveR8_12 R812b_OTHER, edx
- saveR13_14 R1314b_MGR, edx
- jmp dword ptr [SPSR2_TABLE+eax*4]
- IRQ:
- saveR8_12 R812b_OTHER, edx
- saveR13_14 R1314b_IRQ, edx
- jmp dword ptr [SPSR2_TABLE+eax*4]
- ;; -------------------------------------- Mode New Check Store to runtime regs group --------------------------------------------
- USER2:
- loadR8_12 R812b_OTHER, eax
- loadR13_14 R1314b_SYSUSER, eax
- jmp FINAL
- FIQ2:
- loadR8_12 R812b_FIQ, eax
- loadR13_14 R1314b_FIQ, eax
- IF CPSR_Copy_dis eq 0
- mov [SC_ARM7].SPSR_T[SPSRb_FIQ], ecx
- ENDIF
- jmp FINAL
- UDEF2:
- loadR8_12 R812b_OTHER, eax
- loadR13_14 R1314b_UNDEF, eax
- IF CPSR_Copy_dis eq 0
- mov [SC_ARM7].SPSR_T[SPSRb_UNDEF], ecx
- ENDIF
- jmp FINAL
- ABT2:
- loadR8_12 R812b_OTHER, eax
- loadR13_14 R1314b_ABORT, eax
- IF CPSR_Copy_dis eq 0
- mov [SC_ARM7].SPSR_T[SPSRb_ABORT], ecx
- ENDIF
- jmp FINAL
- SVC2:
- loadR8_12 R812b_OTHER, eax
- loadR13_14 R1314b_MGR, eax
- IF CPSR_Copy_dis eq 0
- mov [SC_ARM7].SPSR_T[SPSRb_MGR], ecx
- ENDIF
- jmp FINAL
- IRQ2:
- loadR8_12 R812b_OTHER, eax
- loadR13_14 R1314b_IRQ, eax
- IF CPSR_Copy_dis eq 0
- mov [SC_ARM7].SPSR_T[SPSRb_IRQ], ecx
- ENDIF
- jmp FINAL
- .data
- ALIGN_Z
- SPSR_TABLE dd USER, FIQ, IRQ, SVC
- dd USER, USER, USER, ABT
- dd USER, USER, USER, UDEF
- dd USER, USER, USER, USER
- SPSR2_TABLE dd USER2, FIQ2, IRQ2, SVC2
- dd USER2, USER2, USER2, ABT2
- dd USER2, USER2, USER2, UDEF2
- dd USER2, USER2, USER2, USER2
- .code
- FINAL:
- endm
- .code
- ;; arm7tdmi_ticks c prototype
- ;; uint16_t arm7tdmi_ticks (struct arm7tdmi *arm7, int16_t runticks)
- ;; runticks < 0?exec one instruction : exec ticks.
- ;; ret: real exec ticks.
- arm7tdmi_ticks proc c
- option prologue:none, epilogue:none
- push edi
- push esi
- push ebp
- push ebx
- STACK_PUSH equ 16
- assume SC_ARM7:ptr arm7tdmi
- mov SC_ARM7, [esp+4+STACK_PUSH]
- mov SC_GOAL_COUNT, [esp+8+STACK_PUSH]
- mov SC_CPSR, XRFI[SZ_CPSR*4]
- shl SC_GOAL_COUNT, 16
- ;; DEBUG_OUT 'HelloWorld:%d'
- ;; Instruction parsing main loop
- ALIGN_Z
- @@:
- ;; Check IRQ Interrpt
- test [SC_ARM7].IME, -1
- je dec_op
- ;; IRQ Interrupt Gen, resume GBA's halt status
- test SC_CPSR, IRQ_INHIBI_MASK
- jne dec_op
- ;; Check IE, IF Mask
- mov eax, [SC_ARM7].IFS
- and eax, [SC_ARM7].IE
- and eax, GBA_IE_IF_MASK
- test eax, eax
- je dec_op
- mov eax, XRFI[SZ_PC*4]
- mov ecx, SC_CPSR
- and ecx, ARM7_MODE_CLR_MASK
- or ecx, ARM7_MODE_IRQ_MASK ;; Set IRQ mode.
- and ecx, not FLAG_THUMB ;; Clear Thumb exec flag
- or ecx, IRQ_INHIBI_MASK ;; Set IRQ inhibit mask
- ;; PC to IRQ's LR, LR:= Current Instruction +4
- bt SC_CPSR, ARM7_THUMB_BIT
- sbb edx, edx
- xor edx, -1
- and edx, -4
- add edx, eax
- mov [SC_ARM7].R1314_T[R1314b_IRQ +1*4], edx
- ;; Adjust PC Pointer to IRQ Interrupt vector address
- mov XRFI[SZ_PC*4], ARM7_VECTOR_IRQ
- ;; switch Mode
- SwitchMode ecx
- ;; Prefetch Opcode pipeline
- arm7PipelineFlush 5 ;; minimum interrupt cycle delay
- clksloop:
- mov eax, SC_GOAL_COUNT
- shr eax, 16
- cmp SC_GOAL_COUNT16, ax
- jl @B
- mov XRFI[SZ_CPSR*4], SC_CPSR
- movzx eax, SC_GOAL_COUNT16
- pop ebx
- pop ebp
- pop esi
- pop edi
- ret
- ;; CPU simulation.
- ;; According to the order section of the official manual DDI0210B.pdf of ARM7TDMI,
- ;; Because of the pipeline relationship, the PC pointer always points to the two instructions
- ;; after the current execution address before each instruction is executed by SC_ARM7.
- ;; This implicitly points out the following points.
- ;;
- ;; (1) Instruction execution is always in pipeline cycle >= 2 execution, which means
- ;; (2) Previous and at least two Fetch scripts (this operation may be included with specific implementation instructions)
- ;; (3) The first instruction code has been decoded, the second instruction code has been pushed to the first instruction code
- dec_op:
- mov eax, [SC_ARM7].Opcode[0]
- mov ecx, [SC_ARM7].Opcode[4]
- mov [SC_ARM7].Opcode[0], ecx
- mov SC_INVOLATILE, eax ;; XCC: SC_INVOLATILE:init opcode.
- shr eax, 8
- nop
- test SC_CPSR, FLAG_THUMB
- je @F
- DEBUG_OUT "\n------------------------%08X------------------------\n", "ZF-4"
- DEBUG_OUT "R0:%08X R1:%08X R2:%08X R3:%08X \n", "Z0", "Z1", "Z2", "Z3"
- DEBUG_OUT "R4:%08X R5:%08X R6:%08X R7:%08X \n", "Z4", "Z5", "Z6", "Z7"
- DEBUG_OUT "R8:%08X R9:%08X R10:%08X R11:%08X R12:%08X \n", "Z8", "Z9", "ZA", "ZB", "ZC"
- DEBUG_OUT "SP:%08X LR:%08X \n", "ZD", "ZE"
- DEBUG_OUT "OP:%04X M:%s \n", "O0&0FFFFh", "#"
- DEBUG_OUT "IRQ:%d N:%d Z:%d C:%d V:%d\n", "SC_CPSR}31 & 1", "SC_CPSR}15 & 1", "SC_CPSR}14 & 1", "SC_CPSR}8 & 1", "SC_CPSR & 1"
- and eax, 0FFh
- jmp sTAB[eax*4]
- ALIGN_Z
- @@:
- DEBUG_OUT "\n------------------------%08X------------------------\n", "ZF-8"
- DEBUG_OUT "R0:%08X R1:%08X R2:%08X R3:%08X \n", "Z0", "Z1", "Z2", "Z3"
- DEBUG_OUT "R4:%08X R5:%08X R6:%08X R7:%08X \n", "Z4", "Z5", "Z6", "Z7"
- DEBUG_OUT "R8:%08X R9:%08X R10:%08X R11:%08X R12:%08X \n", "Z8", "Z9", "ZA", "ZB", "ZC"
- DEBUG_OUT "SP:%08X LR:%08X \n", "ZD", "ZE"
- DEBUG_OUT "OP:%08X M:%s \n", "O0", "#"
- DEBUG_OUT "IRQ:%d N:%d Z:%d C:%d V:%d\n", "SC_CPSR}31 & 1", "SC_CPSR}15 & 1", "SC_CPSR}14 & 1", "SC_CPSR}8 & 1", "SC_CPSR & 1"
- shr eax, 20
- jmp fTAB[eax*4]
- fEQ:
- DEBUG_OUT "Cond:EQ "
- test SC_CPSR, FLAG_Z
- jne fAL
- fNV:
- DEBUG_OUT ":Skip "
- arm7ClksFetch1
- fNE:
- DEBUG_OUT "Cond:NE "
- test SC_CPSR, FLAG_Z
- je fAL
- arm7ClksFetch1
- fCS:
- DEBUG_OUT "Cond:CS "
- test SC_CPSR, FLAG_C
- jne fAL
- jmp fNV
- fCC:
- DEBUG_OUT "Cond:CC "
- test SC_CPSR, FLAG_C
- je fAL
- jmp fNV
- fMI:
- DEBUG_OUT "Cond:MI "
- test SC_CPSR, FLAG_N
- jne fAL
- jmp fNV
- fPL:
- DEBUG_OUT "Cond:PL "
- test SC_CPSR, FLAG_N
- je fAL
- jmp fNV
- fVS:
- DEBUG_OUT "Cond:VS "
- test SC_CPSR, FLAG_V
- jne fAL
- jmp fNV
- fVC:
- DEBUG_OUT "Cond:VC "
- test SC_CPSR, FLAG_V
- je fAL
- jmp fNV
- fHI: ;; C = 1 && Z = 0
- DEBUG_OUT "Cond:HI "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- cmp ecx, FLAG_C
- je fAL
- jmp fNV
- fLS: ;; C = 0 || Z = 1
- DEBUG_OUT "Cond:LS "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- xor ecx, FLAG_C
- jne fAL
- jmp fNV
- fGE: ;; N = V
- DEBUG_OUT "Cond:GE "
- mov eax, SC_CPSR
- mov ecx, SC_CPSR
- shr eax, FLAG_V_TOLSB_BIT
- shr ecx, FLAG_N_TOLSB_BIT
- and eax, 1
- and ecx, 1
- xor eax, ecx
- je fAL
- jmp fNV
- fLT: ;; N != V
- DEBUG_OUT "Cond:LT "
- mov eax, SC_CPSR
- mov ecx, SC_CPSR
- shr eax, FLAG_V_TOLSB_BIT
- shr ecx, FLAG_N_TOLSB_BIT
- and eax, 1
- and ecx, 1
- xor eax, ecx
- jne fAL
- jmp fNV
- fGT: ;; N = V && Z= 0
- DEBUG_OUT "Cond:GT "
- mov eax, SC_CPSR
- mov ecx, SC_CPSR
- shr eax, FLAG_V_TOLSB_BIT
- shr ecx, FLAG_N_TOLSB_BIT
- and eax, 1
- and ecx, 1
- xor eax, ecx
- mov ecx, SC_CPSR
- shr ecx, FLAG_Z_TOLSB_BIT
- and ecx, 1
- or eax, ecx
- je fAL
- jmp fNV
- fLE: ;; Z = 1 || N!=V
- DEBUG_OUT "Cond:LE "
- mov eax, SC_CPSR
- mov ecx, SC_CPSR
- shr eax, FLAG_V_TOLSB_BIT
- shr ecx, FLAG_N_TOLSB_BIT
- and eax, 1
- and ecx, 1
- xor eax, ecx
- mov ecx, SC_CPSR
- shr ecx, FLAG_Z_TOLSB_BIT
- and ecx, 1
- or eax, ecx
- je fNV
- fAL: ;; 1110
- mov ecx, SC_INVOLATILE
- mov eax, SC_INVOLATILE
- mov edx, SC_INVOLATILE
- and edx, -1
- rol ecx, 8
- nop
- rol cx, 4
- nop
- and ecx, 0FFh
- nop
- jmp jTAB[ecx*4]
- AND_OP equ 0
- EOR_OP equ 1
- SUB_OP equ 2
- RSB_OP equ 3
- ADD_OP equ 4
- ADC_OP equ 5
- SBC_OP equ 6
- RSC_OP equ 7
- TST_OP equ 8
- TEQ_OP equ 9
- CMP_OP equ 10
- CMN_OP equ 11
- ORR_OP equ 12
- MOV_OP equ 13
- BIC_OP equ 14
- MVN_OP equ 15
- i8r4TAB dd i8r4AND, i8r4ANDS, i8r4EOR, i8r4EORS
- dd i8r4SUB, i8r4SUBS, i8r4RSB, i8r4RSBS
- dd i8r4ADD, i8r4ADDS, i8r4ADC, i8r4ADCS
- dd i8r4SBC, i8r4SBCS, i8r4RSC, i8r4RSCS
- dd i8r4UB, i8r4TST, i8r4ToCPSR, i8r4TEQ
- dd i8r4UB, i8r4CMP, i8r4ToSPSR, i8r4CMN
- dd i8r4ORR, i8r4ORRS, i8r4MOV, i8r4MOVS
- dd i8r4BIC, i8r4BICS, i8r4MVN, i8r4MVNS
- si5TAB dd si5AND, si5ANDS, si5EOR, si5EORS
- dd si5SUB, si5SUBS, si5RSB, si5RSBS
- dd si5ADD, si5ADDS, si5ADC, si5ADCS
- dd si5SBC, si5SBCS, si5RSC, si5RSCS
- dd si5PSR1, si5TST, si5PSR2, si5TEQ
- dd si5PSR3, si5CMP, si5PSR4, si5CMN
- dd si5ORR, si5ORRS, si5MOV, si5MOVS
- dd si5BIC, si5BICS, si5MVN, si5MVNS
- rsTAB dd rsAND, rsANDS, rsEOR, rsEORS ;; 0 0 0 0 0
- dd rsSUB, rsSUBS, rsRSB, rsRSBS ;; 0 0 1 0 0
- dd rsADD, rsADDS, rsADC, rsADCS ;; 0 1 0 0 0
- dd rsSBC, rsSBCS, rsRSC, rsRSCS ;; 0 1 1 0 0
- dd rsUB, rsTST, rsBX, rsTEQ ;; 1 0 0 0 0
- dd rsUB, rsCMP, rsUB, rsCMN ;; 1 0 1 0 0
- dd rsORR, rsORRS, rsMOV, rsMOVS ;; 1 1 0 0 0
- dd rsBIC, rsBICS, rsMVN, rsMVNS ;; 1 1 1 0 0
- ;; LDR/STR Word/Byte Imm12
- ;; P U B W L
- nTAB dd n0, n1, n2, n3 ;; 0 0 0 0 0
- dd n4, n5, n6, n7 ;; 0 0 1 0 0
- dd n8, n9, n10, n11 ;; 0 1 0 0 0
- dd n12, n13, n14, n15 ;; 0 1 1 0 0
- dd n16, n17, n18, n19 ;; 1 0 0 0 0
- dd n20, n21, n22, n23 ;; 1 0 1 0 0
- dd n24, n25, n26, n27 ;; 1 1 0 0 0
- dd n28, n29, n30, n31 ;; 1 1 1 0 0
- ;; LDR/STR Word/Byte Scaled
- ;; P U B W L
- eTAB dd e0, e1, e2, e3 ;; 0 0 0 0 0
- dd e4, e5, e6, e7 ;; 0 0 1 0 0
- dd e8, e9, e10, e11 ;; 0 1 0 0 0
- dd e12, e13, e14, e15 ;; 0 1 1 0 0
- dd e16, e17, e18, e19 ;; 1 0 0 0 0
- dd e20, e21, e22, e23 ;; 1 0 1 0 0
- dd e24, e25, e26, e27 ;; 1 1 0 0 0
- dd e28, e29, e30, e31 ;; 1 1 1 0 0
- ;; LDR/STR HalfWord/SByte Imm8 Hash
- ;; P U X1 W X2
- cTAB dd c0, c1, c2, c3 ;; 0 0 0 0 0
- dd c4, c5, c6, c7 ;; 0 0 1 0 0
- dd c8, c9, c10, c11 ;; 0 1 0 0 0
- dd c12, c13, c14, c15 ;; 0 1 1 0 0
- dd c16, c17, c18, c19 ;; 1 0 0 0 0
- dd c20, c21, c22, c23 ;; 1 0 1 0 0
- dd c24, c25, c26, c27 ;; 1 1 0 0 0
- dd c28, c29, c30, c31 ;; 1 1 1 0 0
- ;; LDR/STR HalfWord/SByte Rm, Rn Hash
- ;; P U X1 W X2
- pTAB dd p0, p1, p2, p3 ;; 0 0 0 0 0
- dd p4, p5, p6, p7 ;; 0 0 1 0 0
- dd p8, p9, p10, p11 ;; 0 1 0 0 0
- dd p12, p13, p14, p15 ;; 0 1 1 0 0
- dd p16, p17, p18, p19 ;; 1 0 0 0 0
- dd p20, p21, p22, p23 ;; 1 0 1 0 0
- dd p24, p25, p26, p27 ;; 1 1 0 0 0
- dd p28, p29, p30, p31 ;; 1 1 1 0 0
- ;; P U X1 W X2
- ;; X1 X2 3:= LDRSH (7)
- ;; 2:= STRHW (1)
- ;; 1:= LDRSB (6)
- ;; 0:= LDRUH (5)
- ;; LDM/STM Hash
- ;; P U S W L
- zTAB dd z0, z1, z2, z3 ;; 0 0 0 0 0
- dd z4, z5, z6, z7 ;; 0 0 1 0 0
- dd z8, z9, z10, z11 ;; 0 1 0 0 0
- dd z12, z13, z14, z15 ;; 0 1 1 0 0
- dd z16, z17, z18, z19 ;; 1 0 0 0 0
- dd z20, z21, z22, z23 ;; 1 0 1 0 0
- dd z24, z25, z26, z27 ;; 1 1 0 0 0
- dd z28, z29, z30, z31 ;; 1 1 1 0 0
- fTAB dd fEQ, fNE, fCS, fCC
- dd fMI, fPL, fVS, fVC
- dd fHI, fLS, fGE, fLT
- dd fGT, fLE, fAL, fNV
- pcMTAB dd 000h, 100h ;; 0 0 0
- dd 000h, 000h ;; 0 1 0
- dd 000h, 000h ;; 0 0 0
- dd 0001h, 0101h ;; 0 1 0
- MUL_OP equ 0
- MLA_OP equ 1
- UMUL64_OP equ 2
- UMLA64_OP equ 3
- SMUL64_OP equ 4
- SMLA64_OP equ 5
- ARM7_MUL_TAB dd mMUL, mMULS, mMLA, mMLAS
- dd mUB, mUB, mUB, mUB
- dd mUMUL64, mUMUL64S, mUMLA64, mUMLA64S
- dd mSMUL64, mSMUL64S, mSMLA64, mSMLA64S
- ;; ARM7 Instruction Entry -----------------------------------------------------------------------------------
- AS_I8:
- DEBUG_OUT "I:AS_I8 **** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp i8r4TAB[eax*4]
- SF_RS:
- DEBUG_OUT "I:SF_RS **** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp rsTAB[eax*4]
- SF_I5:
- DEBUG_OUT "I:SF_I5 **** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp si5TAB[eax*4]
- A7MUL:
- DEBUG_OUT "I:A7MUL **** "
- mov eax, edx
- and eax, 000F00000h
- shr eax, 20
- jmp ARM7_MUL_TAB[eax*4]
- LDI12:
- DEBUG_OUT "I:LDI12 **** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp nTAB[eax*4]
- LDIRS:
- DEBUG_OUT "I:LDIRS **** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp eTAB[eax*4]
- LDRHW: ;; FIXME
- DEBUG_OUT "I:LDRHW **** "
- mov eax, edx
- mov ecx, edx
- and ecx, 060h
- and eax, 010000h
- shr eax, 18
- shr ecx, 5
- or ecx, eax ;;
- and ecx, 7
- mov eax, SC_INVOLATILE
- and eax, 01a00000h
- shr eax, 20
- or eax, pcMTAB[ecx*4]
- test edx, 0400000h
- je @F
- jmp cTAB[eax*4]
- @@:jmp pTAB[eax*4]
- RGSET:
- DEBUG_OUT "I:RGSET **** "
- mov eax, SC_INVOLATILE
- shr eax, 20
- and eax, 31
- jmp zTAB[eax*4]
- ARM7_ALU_BASE macro lSym, OPID
- IF OPID eq AND_OP
- and ecx, eax
- ELSEIF OPID eq EOR_OP
- xor ecx, eax
- ELSEIF OPID eq ORR_OP
- or ecx, eax
- ELSEIF OPID eq SUB_OP
- sub ecx, eax
- ELSEIF OPID eq ADD_OP
- add ecx, eax
- ELSEIF OPID eq MOV_OP
- mov ecx, eax
- ELSEIF OPID eq MVN_OP
- not eax
- mov ecx, eax
- ELSEIF OPID eq BIC_OP
- not eax
- and ecx, eax
- ELSEIF OPID eq RSB_OP
- sub eax, ecx
- mov ecx, eax
- ELSEIF OPID eq SBC_OP
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb ecx, eax
- xor SC_CPSR, FLAG_C
- ELSEIF OPID eq RSC_OP
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb eax, ecx
- xor SC_CPSR, FLAG_C
- mov ecx, eax
- ELSEIF OPID eq ADC_OP
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc ecx, eax
- ELSEIF OPID eq TST_OP
- and ecx, eax
- SetNZ_A
- ELSEIF OPID eq TEQ_OP
- xor ecx, eax
- SetNZ_A
- ELSEIF OPID eq CMP_OP
- cmp ecx, eax
- SetNZCV_A 1
- ELSEIF OPID eq CMN_OP
- add ecx, eax
- SetNZCV_A 0
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_SIGN_BASE macro lSym, OPID
- IF OPID eq AND_OP
- and ecx, eax
- SetNZ_A
- ELSEIF OPID eq EOR_OP
- xor ecx, eax
- SetNZ_A
- ELSEIF OPID eq ORR_OP
- or ecx, eax
- SetNZ_A
- ELSEIF OPID eq SUB_OP
- sub ecx, eax
- SetNZCV_A 1
- ELSEIF OPID eq ADD_OP
- add ecx, eax
- SetNZCV_A 0
- ELSEIF OPID eq MOV_OP
- mov ecx, eax
- add ecx, 0
- SetNZ_A
- ELSEIF OPID eq MVN_OP
- not eax
- mov ecx, eax
- add ecx, 0
- SetNZ_A
- ELSEIF OPID eq BIC_OP
- not eax
- and ecx, eax
- SetNZ_A
- ELSEIF OPID eq RSB_OP
- sub eax, ecx
- mov ecx, eax
- SetNZCV_A 1
- ELSEIF OPID eq SBC_OP
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb ecx, eax
- SetNZCV_A 1
- ELSEIF OPID eq RSC_OP
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb eax, ecx
- mov ecx, eax
- SetNZCV_A 1
- ELSEIF OPID eq ADC_OP
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc ecx, eax
- SetNZCV_A 0
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_bba1 macro
- DEBUG_OUT " #%08X (IMM8:%02X, ROR:%d)", "SC_INVOLATILE & 255 ?~ SC_INVOLATILE}8 & 15 { 1", "SC_INVOLATILE & 255", "SC_INVOLATILE}8 & 15 { 1"
- endm
- ARM7_ALU_BASE_1 macro OPID
- IF OPID eq AND_OP
- DEBUG_OUT "AND R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq EOR_OP
- DEBUG_OUT "EOR R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ORR_OP
- DEBUG_OUT "ORR R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SUB_OP
- DEBUG_OUT "SUB R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADD_OP
- DEBUG_OUT "ADD R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq MOV_OP
- DEBUG_OUT "MOV R%d", "SC_INVOLATILE}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq MVN_OP
- DEBUG_OUT "MVN R%d", "SC_INVOLATILE}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq BIC_OP
- DEBUG_OUT "BIC R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSB_OP
- DEBUG_OUT "RSB R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SBC_OP
- DEBUG_OUT "SBC R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSC_OP
- DEBUG_OUT "RSC R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADC_OP
- DEBUG_OUT "ADC R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq TST_OP
- ELSEIF OPID eq TEQ_OP
- ELSEIF OPID eq CMP_OP
- ELSEIF OPID eq CMN_OP
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_SIGN_BASE_1 macro OPID
- IF OPID eq AND_OP
- DEBUG_OUT "ANDS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq EOR_OP
- DEBUG_OUT "EORS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ORR_OP
- DEBUG_OUT "ORRS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SUB_OP
- DEBUG_OUT "SUBS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADD_OP
- DEBUG_OUT "ADDS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq MOV_OP
- DEBUG_OUT "MOVS R%d", "SC_INVOLATILE}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq MVN_OP
- DEBUG_OUT "MVNS R%d", "SC_INVOLATILE}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq BIC_OP
- DEBUG_OUT "BICS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSB_OP
- DEBUG_OUT "RSBS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SBC_OP
- DEBUG_OUT "SBCS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSC_OP
- DEBUG_OUT "RSCS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADC_OP
- DEBUG_OUT "ADCS R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq TST_OP
- DEBUG_OUT "TST R%d", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq TEQ_OP
- DEBUG_OUT "TEQ R%d", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq CMP_OP
- DEBUG_OUT "CMP R%d", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq CMN_OP
- DEBUG_OUT "CMN R%d", "SC_INVOLATILE}16 & 15"
- ARM7_bba1
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_BASE_2 macro OPID
- IF OPID eq AND_OP ;; LSL #2
- DEBUG_OUT "AND R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq EOR_OP
- DEBUG_OUT "EOR R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq ORR_OP
- DEBUG_OUT "ORR R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq SUB_OP
- DEBUG_OUT "SUB R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq ADD_OP
- DEBUG_OUT "ADD R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq MOV_OP
- DEBUG_OUT "MOV R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq MVN_OP
- DEBUG_OUT "MVN R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq BIC_OP
- DEBUG_OUT "BIC R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq RSB_OP
- DEBUG_OUT "RSB R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq SBC_OP
- DEBUG_OUT "SBC R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq RSC_OP
- DEBUG_OUT "RSC R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq ADC_OP
- DEBUG_OUT "ADC R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq TST_OP
- ELSEIF OPID eq TEQ_OP
- ELSEIF OPID eq CMP_OP
- ELSEIF OPID eq CMN_OP
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_SIGN_BASE_2 macro OPID
- IF OPID eq AND_OP ;; LSL #2
- DEBUG_OUT "ANDS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq EOR_OP
- DEBUG_OUT "EORS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq ORR_OP
- DEBUG_OUT "ORRS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq SUB_OP
- DEBUG_OUT "SUBS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq ADD_OP
- DEBUG_OUT "ADDS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq MOV_OP
- DEBUG_OUT "MOVS R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq MVN_OP
- DEBUG_OUT "MVNS R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq BIC_OP
- DEBUG_OUT "BICS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq RSB_OP
- DEBUG_OUT "RSBS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq SBC_OP
- DEBUG_OUT "SBCS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq RSC_OP
- DEBUG_OUT "RSCS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq ADC_OP
- DEBUG_OUT "ADCS R%d, R%d, R%d, ", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq TST_OP
- DEBUG_OUT "TST R%d, R%d, ", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq TEQ_OP
- DEBUG_OUT "TEQ R%d, R%d, ", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq CMP_OP
- DEBUG_OUT "CMP R%d, R%d, ", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSEIF OPID eq CMN_OP
- DEBUG_OUT "CMN R%d, R%d, ", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15"
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- i8r4_interpret macro lSym, OPID
- i8r4&lSym:
- Imm8BitmapSft_AC SC_INVOLATILE, eax ;; Rm
- GetRFIV SC_INVOLATILE, 16, ecx ;; Rn
- GetRFI SC_INVOLATILE, 12, edx ;; RdIs
- ARM7_ALU_BASE lSym, OPID
- ARM7_ALU_BASE_1 OPID
- IF (OPID and 1100b) ne 1000b
- ;; Write Back, Check R15.
- mov XRFI[edx*4], ecx
- cmp edx, 15
- jne @F
- arm7PipelineFlush 3 ;; +1S +1N
- @@:
- ENDIF
- arm7ClksFetch1 ;; 1 clks
- IF (OPID and 1100b) ne 1000b
- i8r4&lSym&S:
- ARM7_ALU_SIGN_BASE_1 OPID
- Imm8BitmapSft_AC SC_INVOLATILE, eax ;; Rm
- GetRFIV SC_INVOLATILE, 16, ecx ;; Rn
- GetRFI SC_INVOLATILE, 12, edx ;; RdIs
- mov SC_INVOLATILE, SC_CPSR ;; save old CPSR.
- ARM7_ALU_SIGN_BASE lSym, OPID
- mov XRFI[edx*4], ecx
- cmp edx, 15
- je @F
- arm7ClksFetch1 ;; 1 clks
- @@:
- ;; R15 resume old CPSR.
- mov SC_CPSR, SC_INVOLATILE
- SPSRToCPSR edx
- test SC_CPSR, FLAG_THUMB
- je @F
- tbPipelineFlush 2
- @@:
- arm7PipelineFlush 3 ;; +1S +1N
- ENDIF
- endm
- ;; ------------------------- ALU+Imm8+Sft
- ;; 27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 0 0 1 Opcode S Rn Rd Imm8+Sft
- ;; 0 0 1 1 0 R 1 0 fmask SBO Imm8+Sft
- i8r4_interpret AND, AND_OP
- i8r4_interpret EOR, EOR_OP
- i8r4_interpret SUB, SUB_OP
- i8r4_interpret RSB, RSB_OP
- i8r4_interpret ADD, ADD_OP
- i8r4_interpret ADC, ADC_OP
- i8r4_interpret SBC, SBC_OP
- i8r4_interpret RSC, RSC_OP
- i8r4_interpret TST, TST_OP
- i8r4_interpret TEQ, TEQ_OP
- i8r4_interpret CMP, CMP_OP
- i8r4_interpret CMN, CMN_OP
- i8r4_interpret ORR, ORR_OP
- i8r4_interpret MOV, MOV_OP
- i8r4_interpret BIC, BIC_OP
- i8r4_interpret MVN, MVN_OP
- mUB:
- i8r4UB:
- int 3
- si5_interpret macro lSym, OPID
- si5&lSym:
- ARM7_ALU_BASE_2 OPID
- ShiftRegImm5 edx, eax, ecx, eax, lSym, C_op_NOCare
- GetRFIV edx, 16, ecx ;; Rn
- GetRFI edx, 12, edx ;; RdIs
- ARM7_ALU_BASE lSym, OPID
- IF (OPID and 1100b) ne 1000b
- ;; Write Back, Check R15.
- mov XRFI[edx*4], ecx
- cmp edx, 15
- jne @F
- arm7PipelineFlush 3 ;; +1S +1N
- @@:
- ENDIF
- arm7ClksFetch1 ;; 1 clks
- IF (OPID and 1100b) ne 1000b
- si5&lSym&S:
- ARM7_ALU_SIGN_BASE_2 OPID
- mov SC_INVOLATILE, SC_CPSR ;; save old .
- ShiftRegImm5 edx, eax, ecx, eax, lSym&S, C_op_Care ;; Rm
- GetRFIV edx, 16, ecx ;; Rn
- GetRFI edx, 12, edx ;; RdIs
- ARM7_ALU_SIGN_BASE lSym, OPID
- mov XRFI[edx*4], ecx
- cmp edx, 15
- je @F
- arm7ClksFetch1 ;; 1 clks
- @@:
- ;; R15 resume old CPSR.
- mov SC_CPSR, SC_INVOLATILE
- SPSRToCPSR edx
- test SC_CPSR, FLAG_THUMB
- je @F
- tbPipelineFlush 2
- @@:
- arm7PipelineFlush 3 ;; +1S +1N
- ENDIF
- endm
- ;; ------------------------- ALU+Imm5
- ;; 27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 0 0 0 Opcode S Rn Rd Imm5 T T 0 Rm
- ;; 0 0 0 1 0 R 1 0 fmask SBO SBZ 0 0 0 0 Rm MSR PSR, Rm
- si5_interpret AND, AND_OP
- si5_interpret EOR, EOR_OP
- si5_interpret SUB, SUB_OP
- si5_interpret RSB, RSB_OP
- si5_interpret ADD, ADD_OP
- si5_interpret ADC, ADC_OP
- si5_interpret SBC, SBC_OP
- si5_interpret RSC, RSC_OP
- si5_interpret TST, TST_OP
- si5_interpret TEQ, TEQ_OP
- si5_interpret CMP, CMP_OP
- si5_interpret CMN, CMN_OP
- si5_interpret ORR, ORR_OP
- si5_interpret MOV, MOV_OP
- si5_interpret BIC, BIC_OP
- si5_interpret MVN, MVN_OP
- rs_interpret macro lSym, OPID
- rs&lSym:
- ShiftRegRs SC_INVOLATILE, eax, ecx, edx, lSym, C_op_NOCare
- GetRFIV SC_INVOLATILE, 16, ecx ;; Rn
- GetRFI SC_INVOLATILE, 12, edx ;; RdIs
- ARM7_ALU_BASE_2 OPID
- ARM7_ALU_BASE lSym, OPID
- IF (OPID and 1100b) ne 1000b
- ;; Write Back, Check R15.
- mov XRFI[edx*4], ecx
- cmp edx, 15
- jne @F
- arm7PipelineFlush 3 ;; +1S +1N
- @@:
- ENDIF
- arm7ClksFetch1 ;; 1 clks
- IF (OPID and 1100b) ne 1000b
- rs&lSym&S:
- mov SC_INVOLATILE, SC_CPSR ;; save old .
- ShiftRegRs SC_INVOLATILE, eax, ecx, edx, lSym&S, C_op_Care
- GetRFIV edx, 16, ecx ;; Rn
- GetRFI edx, 12, edx ;; RdIs
- ARM7_ALU_SIGN_BASE_2 OPID
- ARM7_ALU_SIGN_BASE lSym, OPID
- mov XRFI[edx*4], ecx
- cmp edx, 15
- je @F
- arm7ClksFetch1 ;; 1 clks
- @@:
- ;; R15 resume old CPSR.
- mov SC_CPSR, SC_INVOLATILE
- SPSRToCPSR edx
- test SC_CPSR, FLAG_THUMB
- je @F
- tbPipelineFlush 2
- @@:
- arm7PipelineFlush 3 ;; +1S +1N
- ENDIF
- endm
- ;; ------------------------- ALU+RegSft
- ;; 27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 0 0 0 Opcode S Rn Rd Rs 0 T T 1 Rm
- ;; 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 Rn branch exchange
- rs_interpret AND, AND_OP
- rs_interpret EOR, EOR_OP
- rs_interpret SUB, SUB_OP
- rs_interpret RSB, RSB_OP
- rs_interpret ADD, ADD_OP
- rs_interpret ADC, ADC_OP
- rs_interpret SBC, SBC_OP
- rs_interpret RSC, RSC_OP
- rs_interpret TST, TST_OP
- rs_interpret TEQ, TEQ_OP
- rs_interpret CMP, CMP_OP
- rs_interpret CMN, CMN_OP
- rs_interpret ORR, ORR_OP
- rs_interpret MOV, MOV_OP
- rs_interpret BIC, BIC_OP
- rs_interpret MVN, MVN_OP
- i8r4ToCPSR: ;; !!!!!!!!!!
- Imm8BitmapSft_AC edx, eax
- DEBUG_OUT "MSR #%08X(org)", "eax"
- ToFastCPSR eax, eax, a, c
- DEBUG_OUT " #%08X(fast) to spsr_", "eax"
- mov ecx, SC_CPSR ;; ecx : old
- test edx, FLAG_MSR_FLAGS
- je @F
- mov SC_CPSR16, ax ;; XXX:bitfield indep
- DEBUG_OUT "f"
- @@:
- mov ax, SC_CPSR16
- test edx, FLAG_MSR_CTL
- je @F
- DEBUG_OUT "c"
- SwitchMode eax
- IF 1
- ;;'Cehck Thumb flags .
- test SC_CPSR, FLAG_THUMB
- je @F
- sub XRFI[SZ_PC*4], 4 ;; backup to next instruction
- tbPipelineFlush 2
- ENDIF
- @@:
- arm7ClksFetch1
- i8r4ToSPSR:
- Imm8BitmapSft_AC edx, eax
- DEBUG_OUT "MSR #%08X(org)", "eax"
- ToFastCPSR eax, eax, a, c
- DEBUG_OUT " #%08X(fast) to spsr_", "eax"
- GetCurSPSRP ecx
- test edx, FLAG_MSR_FLAGS
- je @F
- mov [ecx], ax ;; XXX:bitfield indep
- DEBUG_OUT "f"
- @@:
- test edx, FLAG_MSR_CTL
- je @F
- DEBUG_OUT "c"
- shr eax, 24
- mov [ecx+3], al ;; XXX:bitfield indep
- @@:
- arm7ClksFetch1
- MUL_CLKS_M_S3 macro Post, TReg, Recv ;; XXX: TReg ^ Post ^ Recv
- LOCAL MClks3
- LOCAL MClks2
- LOCAL MClks1
- ;; multiplier's clks, m
- ;; see ARM7TDMI Technical Reference Manual's 6.20 Instruction speed summary
- ;; m is:
- ;; 1 if bits [31:8] of the multiplier operand are all zero or one, else
- ;; 2 if bits [31:16] of the multiplier operand are all zero or one, else
- ;; 3 if bits [31:24] of the multiplier operand are all zero or all one, else
- ;; 4.
- ;;
- ;; Check multiplier's Mod Shift bit
- ;; if NEG, not it. else nodone.
- bt Post, 31
- sbb TReg, TReg
- xor TReg, Post
- xor Recv, Recv
- test TReg, 0FFFFFF00h
- je MClks1
- test TReg, 0FFFF0000h
- je MClks2
- test TReg, 0FF000000h
- je MClks3
- add Recv, 1
- MClks3:
- add Recv, 1
- MClks2:
- add Recv, 1
- MClks1:
- add Recv, 1
- endm
- mul_interpret_b macro OPID
- GetRFIV SC_INVOLATILE, 0, eax ;; Rm.
- GetRFIV SC_INVOLATILE, 8, ecx ;; Rs.
- IF OPID eq MUL_OP
- DEBUG_OUT "MUL R%d, R%d, R%d", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}8 & 15"
- mul ecx
- GetRFI SC_INVOLATILE, 16, edx ;; Rd
- mov XRFI[edx*4], eax
- ELSEIF OPID eq MLA_OP
- DEBUG_OUT "MLA R%d, R%d, R%d, R%d", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}8 & 15", "SC_INVOLATILE}12 & 15"
- mul ecx
- GetRFIV SC_INVOLATILE, 12, edx ;; Rn
- add eax, edx
- GetRFI SC_INVOLATILE, 16, edx ;; Rd
- mov XRFI[edx*4], eax
- ELSEIF OPID eq UMUL64_OP
- DEBUG_OUT "UMULL R%d, R%d, R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}8 & 15"
- movd xmm0, ecx
- mul ecx
- GetRFI SC_INVOLATILE, 12, ecx ;; RdLO
- GetRFI SC_INVOLATILE, 16, SC_INVOLATILE ;; RdHI
- mov XRFI[ecx*4], eax
- mov XRFI[SC_INVOLATILE*4], edx
- movd ecx, xmm0
- ELSEIF OPID eq UMLA64_OP
- DEBUG_OUT "UMLAL R%d, R%d, R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}8 & 15"
- movd xmm0, ecx
- mul ecx
- GetRFI SC_INVOLATILE, 12, ecx ;; RdLO
- GetRFI SC_INVOLATILE, 16, SC_INVOLATILE ;; RdHI
- add eax, XRFI[ecx*4]
- adc edx, XRFI[SC_INVOLATILE*4]
- mov XRFI[ecx*4], eax
- mov XRFI[SC_INVOLATILE*4], edx
- movd ecx, xmm0
- ELSEIF OPID eq SMUL64_OP
- DEBUG_OUT "SMULL R%d, R%d, R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}8 & 15"
- movd xmm0, ecx
- imul ecx
- GetRFI SC_INVOLATILE, 12, ecx ;; RdLO
- GetRFI SC_INVOLATILE, 16, SC_INVOLATILE ;; RdHI
- mov XRFI[ecx*4], eax
- mov XRFI[SC_INVOLATILE*4], edx
- movd ecx, xmm0
- ELSEIF OPID eq SMLA64_OP
- DEBUG_OUT "SMLAL R%d, R%d, R%d, R%d", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE}16 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}8 & 15"
- movd xmm0, ecx
- imul ecx
- GetRFI SC_INVOLATILE, 12, ecx ;; RdLO
- GetRFI SC_INVOLATILE, 16, SC_INVOLATILE ;; RdHI
- add eax, XRFI[ecx*4]
- adc edx, XRFI[SC_INVOLATILE*4]
- mov XRFI[ecx*4], eax
- mov XRFI[SC_INVOLATILE*4], edx
- movd ecx, xmm0
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- mul_interpret macro lSym, OPID
- ;;LOCAL StdLink
- ;;LOCAL StdLinkWithSymbol
- LOCAL SetMClks
- m&lSym:
- DEBUG_OUT "NOSET_SIGN "
- mul_interpret_b OPID
- jmp SetMClks
- m&lSym&S:
- DEBUG_OUT "SET_SIGN "
- mul_interpret_b OPID
- IF OPID eq MUL_OP
- Set_NZmul32 eax
- ELSEIF OPID eq MLA_OP
- Set_NZmul32 eax
- ELSEIF OPID eq UMUL64_OP
- Set_NZmul64 eax, edx
- ELSEIF OPID eq UMLA64_OP
- Set_NZmul64 eax, edx
- ELSEIF OPID eq SMUL64_OP
- Set_NZmul64 eax, edx
- ELSEIF OPID eq SMLA64_OP
- Set_NZmul64 eax, edx
- ELSE
- ERRORS_ASSERT
- ENDIF
- SetMClks:
- MUL_CLKS_M_S3 ecx, edx, eax
- IF OPID eq MUL_OP
- ;; MUL := M Clks.
- ELSEIF OPID eq MLA_OP
- ;; MLA := M+1 Clks
- add eax, 1
- ELSEIF OPID eq UMUL64_OP
- ;; UMULL := M+1 Clks
- add eax, 1
- ELSEIF OPID eq UMLA64_OP
- ;; UMLAL := M+2 Clks
- add eax, 2
- ELSEIF OPID eq SMUL64_OP
- ;; SMULL := M+1 Clks
- add eax, 1
- ELSEIF OPID eq SMLA64_OP
- ;; SMLAL := M+2 Clks
- add eax, 2
- ELSE
- ERRORS_ASSERT
- ENDIF
- add SC_GOAL_COUNT, eax
- arm7ClksFetch1
- endm
- ALIGN_Z
- mul_interpret MUL, MUL_OP
- mul_interpret MLA, MLA_OP
- mul_interpret UMUL64, UMUL64_OP
- mul_interpret UMLA64, UMLA64_OP
- mul_interpret SMUL64, SMUL64_OP
- mul_interpret SMLA64, SMLA64_OP
- ;; 27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 0 0 0 Opcode S Rn Rd Imm5 T T 0 Rm
- ;; 0 0 0 1 0 R 1 0 fmask SBO SBZ 0 0 0 0 Rm MSR PSR, Rm
- ALIGN_Z
- si5PSR2: ;; 0 1 MSR Rs CPSR TODO:Check d4-d7 := 0
- DEBUG_OUT "MSR R%d to cpsr_", "SC_INVOLATILE & 15"
- GetRFIV edx, 0, eax
- ToFastCPSR eax, eax, a, c
- mov ecx, SC_CPSR ;; ecx : old
- test edx, FLAG_MSR_FLAGS
- je @F
- mov SC_CPSR16, ax ;; XXX:bitfield indep
- DEBUG_OUT "f"
- @@:
- mov ax, SC_CPSR16
- test edx, FLAG_MSR_CTL
- je @F
- ;; mode equal ??
- DEBUG_OUT "c"
- SwitchMode eax
- IF 1
- ;;'Cehck Thumb flags .
- test SC_CPSR, FLAG_THUMB
- je @F
- sub XRFI[SZ_PC*4], 4 ;; backup to next instruction
- tbPipelineFlush 2
- ENDIF
- @@:
- arm7ClksFetch1
- ;; TODO: assert mode, flags
- si5PSR4: ;; 1 1 MSR Rs SPSR
- DEBUG_OUT "MSR R%d to spsr_", "SC_INVOLATILE & 15"
- GetRFIV edx, 0, eax
- ToFastCPSR eax, eax, a, c
- GetCurSPSRP ecx
- test edx, FLAG_MSR_FLAGS
- je @F
- mov [ecx], ax ;; XXX:bitfield indep
- DEBUG_OUT "f"
- @@:
- test edx, FLAG_MSR_CTL
- je @F
- shr eax, 24
- mov [ecx+3], al ;; XXX:bitfield indep
- DEBUG_OUT "c"
- @@:
- arm7ClksFetch1
- si5PSR1: ;; 0 0 MRS Rs CPSR
- DEBUG_OUT "MRS R%d, CPSR", "SC_INVOLATILE}12 & 15"
- ToStandCPSR SC_CPSR, ecx, a, c
- GetRFI edx, 12, eax
- mov [eax], ecx
- arm7ClksFetch1
- si5PSR3: ;; 1 0 MRS Rs SPSR, TODO: Check SBO/SBZ
- DEBUG_OUT "MRS R%d, SPSR", "SC_INVOLATILE}12 & 15"
- GetCurSPSRP eax
- mov eax, [eax]
- ToStandCPSR eax, ecx, a, c
- GetRFI edx, 12, eax
- mov [eax], ecx
- arm7ClksFetch1
- ;; ------------------------- branch clks:3 2Seq + 1N Cycles
- ;; 27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 1 0 1 L Sign Offset 24
- JPL_BASE macro
- and edx, 0FFFFFFh
- bt edx, 23
- sbb ecx, ecx
- and ecx, 03F000000h ;; save 30 bit
- or ecx, edx
- shl ecx, 2 ;; shift 2
- DEBUG_OUT "%06X- (%d)", ecx, ecx
- add XRFI[SZ_PC*4], ecx
- endm
- JMP24: ;; without LR
- DEBUG_OUT "B "
- JPL_BASE
- arm7PipelineFlush 3
- JMPLR: ;; with LR
- DEBUG_OUT "BL "
- mov SC_INVOLATILE, XRFI[SZ_PC*4]
- JPL_BASE
- lea eax, [SC_INVOLATILE-4]
- DEBUG_OUT "LINK %08X- (%d) ", "eax", "eax"
- mov XRFI[SZ_LRLINK*4], eax ;; next pc save to LR.
- arm7PipelineFlush 3
- ;; ---------------------------------------------------------------------------------------------
- ;; 27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 Rn branch exchange
- ALIGN_Z
- rsBX: ;; BX Rn
- ;; Adjust PC. Check Rn's d0
- GetRFIV edx, 0, eax
- DEBUG_OUT "BX R%d %08X- (%d) ", "SC_INVOLATILE & 15", "eax", "eax"
- test eax, 1
- jne @F
- mov XRFI[SZ_PC*4], eax
- arm7PipelineFlush 3
- @@:
- and eax, -2
- or SC_CPSR, FLAG_THUMB ;; set thumb flag
- mov XRFI[SZ_PC*4], eax
- tbPipelineFlush 4 ;; thumb prefetch maybe slow.
- rsUB:
- int 3
- A7SWP: ;; SWAP. S+2N+1
- GetRFIV SC_INVOLATILE, 16, eax ;; Rn:= Address
- GetRFIV SC_INVOLATILE, 0, ecx ;; Rm:
- push ecx
- push eax
- push [SC_ARM7].agb
- push eax
- push [SC_ARM7].agb
- test SC_INVOLATILE, 00400000h
- je @F
- CALLIt MmuReadByte
- DEBUG_OUT "SWPB R%d, R%d, [R%d]", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}16 & 15"
- GetRFI SC_INVOLATILE, 12, SC_INVOLATILE ;; Rd:= Rd.
- mov XRFI8[SC_INVOLATILE*4], al
- Add_WaitStateClks
- CALLIt MmuWriteByte
- add SC_GOAL_COUNT, 3
- arm7ClksFetch1
- ;; Word.
- @@:
- CALLIt MmuReadWord
- DEBUG_OUT "SWP R%d, R%d, [R%d]", "SC_INVOLATILE}12 & 15", "SC_INVOLATILE & 15", "SC_INVOLATILE}16 & 15"
- GetRFI SC_INVOLATILE, 12, SC_INVOLATILE ;; Rd:= Rd.
- mov XRFI[SC_INVOLATILE*4], eax
- ;; Read/Write Same Cache Region. Add one waitState
- Add_WaitStateClks
- CALLIt MmuWriteWord
- add SC_GOAL_COUNT, 3
- arm7ClksFetch1
- LDR_SET macro ldrtype, pre, link
- LDR_L equ 1
- LDR_W equ 2
- LDR_B equ 4
- LDR_U equ 8
- LDR_P equ 16
- LDR_STD_IMM12 equ 0 ;;->
- LDR_STD_SCALED equ 1 ;;->
- LDR_EXT_LOHI8BIT equ 2 ;;->
- LDR_EXT_RNMD equ 3 ;; :: ldrtype
- IF ldrtype eq LDR_STD_IMM12 or (ldrtype eq LDR_STD_SCALED)
- IF (link and LDR_L) eq 0
- DEBUG_OUT "STR"
- ELSEIF (link and LDR_L) ne 0
- DEBUG_OUT "LDR"
- ENDIF
- IF (link and LDR_B) ne 0
- DEBUG_OUT "B"
- ENDIF
- IF ((link and LDR_W) eq 0) and ((link and LDR_P) eq 0)
- DEBUG_OUT "T"
- ENDIF
- ELSEIF ldrtype eq LDR_EXT_LOHI8BIT or (ldrtype eq LDR_EXT_RNMD)
- IF (link and 5) eq 4
- DEBUG_OUT "STRH"
- ELSEIF (link and 5) ne 4
- DEBUG_OUT "LDR"
- IF (link and 5) eq 0
- DEBUG_OUT "H"
- ELSEIF (link and 5) eq 1
- DEBUG_OUT "SB"
- ELSEIF (link and 5) eq 5
- DEBUG_OUT "SH"
- ELSE
- ERRORS_ASSERT
- ENDIF
- ELSE
- ERRORS_ASSERT
- ENDIF
- ELSE
- ERRORS_ASSERT
- ENDIF
- IF (link and LDR_U) eq 0
- DEBUG_OUT "-"
- ENDIF
- IF (link and LDR_P) ne 0
- DEBUG_OUT " R%d, [R%d, ", "SC_INVOLATILE } 12 & 15", "SC_INVOLATILE } 16 & 15"
- ELSEIF (link and LDR_P) eq 0
- DEBUG_OUT " R%d, [R%d], ", "SC_INVOLATILE } 12 & 15", "SC_INVOLATILE } 16 & 15"
- ENDIF
- pre&link:
- ;; Fetch Source .
- ;; P U X1 W X2
- ;; X1 X2 3:= LDRSH (7)
- ;; 2:= STRHW (1)
- ;; 1:= LDRSB (6)
- ;; 0:= LDRUH (5)
- ;; eax:temp value, ecx:rn
- IF ldrtype eq LDR_STD_IMM12
- mov eax, SC_INVOLATILE
- and eax, 0FFFh ;; GetImm12
- DEBUG_OUT "#%03X", "eax"
- ELSEIF ldrtype eq LDR_STD_SCALED
- DEBUG_OUT "R%d, ", "SC_INVOLATILE & 15"
- ShiftRegImm5 SC_INVOLATILE, eax, ecx, edx, pre&link, C_op_NOCare ;; Rm Sft.
- ELSEIF ldrtype eq LDR_EXT_LOHI8BIT
- mov eax, SC_INVOLATILE
- shl al, 4
- shr eax, 4
- and eax, 255 ;; LO|HI
- DEBUG_OUT "#%02X", "eax"
- ELSEIF ldrtype eq LDR_EXT_RNMD
- DEBUG_OUT "R%d", "eax & 15"
- GetRFIV SC_INVOLATILE, 0, eax ;; GetRm
- ELSE
- ERRORS_ASSERT
- ENDIF
- IF (link and LDR_P) ne 0
- DEBUG_OUT "]"
- IF (link and LDR_P) ne 0
- DEBUG_OUT "!"
- ENDIF
- ENDIF
- GetRFI SC_INVOLATILE, 16, ecx ;; GetRn
- IF (link and LDR_U) eq 0
- neg eax
- ENDIF
- ;; Post-Index??
- IF (link and LDR_P) ne 0
- mov edx, XRFI[ecx*4]
- add eax, edx
- ELSEIF (link and LDR_P) eq 0
- mov edx, eax
- add edx, XRFI[ecx*4]
- mov eax, edx
- ENDIF
- IF (((link and LDR_P) eq 0) or ((link and LDR_W) ne 0))
- mov XRFI[ecx*4], eax
- ENDIF
- mov eax, SC_INVOLATILE
- GetRFI SC_INVOLATILE, 12, SC_INVOLATILE ;; GetRd
- ;; Check Access type
- IF ldrtype eq LDR_STD_IMM12 or (ldrtype eq LDR_STD_SCALED)
- IF (link and LDR_L) eq 0
- ;; STR. STRB
- push XRFI[SC_INVOLATILE*4]
- push edx
- push [SC_ARM7].agb
- IF (link and LDR_B) ne 0
- CALLIt MmuWriteByte
- ELSEIF (link and LDR_B) eq 0
- CALLIt MmuWriteWord
- ENDIF
- Add_WaitStateClks
- arm7ClksFetchN 2 ;; 2 noSEQ clks.
- ELSEIF (link and LDR_L) ne 0
- ;; LDR. LDRB
- push edx
- push [SC_ARM7].agb
- IF (link and LDR_B) ne 0
- CALLIt MmuReadByte
- movzx eax, al
- ELSEIF (link and LDR_B) eq 0
- CALLIt MmuReadWord
- ENDIF
- Add_WaitStateClks
- mov XRFI[SC_INVOLATILE* 4], eax
- cmp SC_INVOLATILE, 15
- je @F
- arm7ClksFetchN 3 ;; S+N+1 3Clks.
- @@:
- and XRFI[SC_INVOLATILE *4], -4
- arm7PipelineFlush 5
- ENDIF
- ELSEIF ldrtype eq LDR_EXT_LOHI8BIT or (ldrtype eq LDR_EXT_RNMD)
- IF (link and 5) eq 4
- push XRFI[SC_INVOLATILE*4]
- push edx
- CallMemOrIOAddWaitState MmuWriteHalfWord
- arm7ClksFetchN 2 ;; 2 noSEQ clks.
- ELSEIF (link and 5) ne 4
- push edx
- push [SC_ARM7].agb
- IF (link and 5) eq 0
- CALLIt MmuReadHalfWord
- movzx eax, ax
- ELSEIF (link and 5) eq 1
- CALLIt MmuReadByte
- movsx eax, al
- ELSEIF (link and 5) eq 5
- CALLIt MmuReadHalfWord
- movsx eax, ax
- ENDIF
- Add_WaitStateClks
- mov XRFI[SC_INVOLATILE* 4], eax
- cmp SC_INVOLATILE, 15
- je @F
- arm7ClksFetchN 3 ;; S+N+1 3Clks.
- @@:
- and XRFI[SC_INVOLATILE *4], -4
- arm7PipelineFlush 5
- ENDIF
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- IRL_PUSH_b macro num
- LDR_SET LDR_STD_IMM12, n, num
- LDR_SET LDR_STD_SCALED, e, num
- LDR_SET LDR_EXT_LOHI8BIT, c, num
- LDR_SET LDR_EXT_RNMD, p, num
- REGS_SET_OP num
- endm
- IRL_PUSH macro
- ID = 0
- WHILE ID ne 32
- IRL_PUSH_b %ID
- ID = ID + 1
- ENDM
- endm
- ;; XXX: This macro branch is actually terrible to write.
- REGS_SET_OP macro link
- z&link:
- ;; have to use variables.
- RSO_STACK_REQUIRE equ 128
- RSO_L equ 1
- RSO_W equ 2
- RSO_S equ 4
- RSO_U equ 8
- RSO_P equ 16
- IF (link and RSO_L) eq 0
- DEBUG_OUT "STM"
- ELSEIF (link and RSO_L) ne 0
- DEBUG_OUT "LDM"
- ENDIF
- IF (link and RSO_U) eq 0
- DEBUG_OUT "D"
- ELSEIF (link and RSO_U) ne 0
- DEBUG_OUT "I"
- ENDIF
- IF (link and RSO_P) eq 0
- DEBUG_OUT "A"
- ELSEIF (link and RSO_P) ne 0
- DEBUG_OUT "B"
- ENDIF
- DEBUG_OUT " R%d", "SC_INVOLATILE } 16 & 15"
- IF (link and RSO_W) ne 0
- DEBUG_OUT "!"
- ENDIF
- DEBUG_OUT ", "
- DEBUG_OUT "[ R15-R12:%01X, R11-R8:%01X ", "SC_INVOLATILE } 12 & 15", "SC_INVOLATILE } 8 & 15"
- DEBUG_OUT " R7-R4:%01X, R3-R0:%01X ]", "SC_INVOLATILE } 4 & 15", "SC_INVOLATILE & 15"
- IF (link and RSO_S) ne 0
- DEBUG_OUT "^"
- ENDIF
- sub esp, RSO_STACK_REQUIRE
- RnTemp equ dword ptr[esp+16]
- RnIndex equ dword ptr[esp+20]
- RnCount equ dword ptr[esp+28]
- RegList equ dword ptr[esp+32]
- RnTempG equ dword ptr[esp+36]
- RnAdjust equ dword ptr[esp+40]
- ;; Reset Context
- xor eax, eax
- mov RnIndex, eax
- mov RnCount, eax
- GetRFI SC_INVOLATILE, 16, eax ;;Rn.
- mov ecx, SC_INVOLATILE
- mov edx, XRFI[eax*4] ;;GetRn
- and ecx, 0FFFFh
- mov RnIndex, eax
- mov RnTemp, edx
- mov RnAdjust, eax
- IF (link and RSO_U) ne 0
- mov SC_INVOLATILE, 4
- ELSEIF (link and RSO_U) eq 0
- mov SC_INVOLATILE, -4
- ENDIF
- mov RegList, ecx
- mov eax, ecx
- xor ecx, ecx
- mov edx, 16
- @@:
- shr ax, 1
- adc cx, 0
- dec dx
- jne @B
- ;; TODO: assert 0
- shl ecx, 2
- mov edx, RnTemp
- IF (link and RSO_U) ne 0
- add edx, ecx
- ELSEIF (link and RSO_U) eq 0
- sub edx, ecx
- lea eax, [edx+4]
- mov RnTemp, eax
- ENDIF
- mov RnTempG, edx
- IF (link and RSO_P) ne 0
- add RnTemp, SC_INVOLATILE
- ENDIF
- mov SC_INVOLATILE, RnTemp
- ;; STM-------------------------------------------------------
- IF (link and RSO_L) eq 0
- ;; Check Rn's adjust
- mov ecx, RnIndex
- bt RegList, ecx
- jnc @F
- sbb edx, edx
- ;; Check is First Vailed bit
- mov eax, edx
- shl eax, cl
- xor eax, edx
- test RegList, eax
- je @F
- ;; Dirty register, write directly
- mov eax, RnIndex
- mov ecx, RnTempG
- mov XRFI[eax*4], ecx
- @@:
- IF (link and RSO_S) ne 0
- ;; In User mode, Check Current is user/sys mode
- ;; If hit, use std copy . (Because the user-mode cache register may not have been updated)
- mov eax, SC_CPSR
- and eax, ARM7_MODE_GET_MASK
- cmp eax, ARM7_MODE_SYS_MASK
- je rsgStdPush&link
- cmp eax, ARM7_MODE_USER_MASK
- je rsgStdPush&link
- cmp eax, ARM7_MODE_FIQ_MASK
- je rsgFIQPush&link
- jmp rsgUserPush&link
- ELSEIF (link and RSO_S) eq 0
- jmp rsgStdPush&link
- ENDIF
- ;; STM User Mode -------------------------------------------------------
- rsgUserPush&link:
- shr RegList, 1
- jnc @F
- mov eax, RnCount
- mov ecx, XRFI[eax*4]
- add eax, 1
- and eax, 15
- cmp eax, 14
- jb rsgUserPushSkip&link
- sub eax, 14
- mov ecx, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
- rsgUserPushSkip&link:
- push ecx
- mov eax, SC_INVOLATILE
- and eax, -4
- push eax
- CallMemOrIOAddWaitState MmuWriteWord
- add SC_INVOLATILE, 4
- @@:
- add RnCount, 1
- cmp RnCount, 16
- jb rsgUserPush&link
- jmp rspushOut&link
- ;; STM FIQ Mode -------------------------------------------------------
- rsgFIQPush&link:
- shr RegList, 1
- jnc @F
- mov eax, RnCount
- mov ecx, XRFI[eax*4]
- add eax, 1
- and eax, 15
- cmp eax, 9
- jb rsgFIQPushSkip&link
- cmp eax, 13
- jb rsgFIQPushSkip&link
- mov ecx, [SC_ARM7].R812_T[R812b_FIQ+ eax*4]
- jmp rsgFIQPushSkip&link
- sub eax, 14
- mov ecx, [SC_ARM7].R1314_T[R1314b_FIQ+ eax*4]
- rsgFIQPushSkip&link:
- push ecx
- mov eax, SC_INVOLATILE
- and eax, -4
- push eax
- CallMemOrIOAddWaitState MmuWriteWord
- add SC_INVOLATILE, 4
- @@:
- add RnCount, 1
- cmp RnCount, 16
- jb rsgFIQPush&link
- jmp rspushOut&link
- ;; STM Std Mode --------------------------------------------------------
- rsgStdPush&link:
- shr RegList, 1
- jnc @F
- mov eax, RnCount
- push XRFI[eax*4]
- mov eax, SC_INVOLATILE
- and eax, -4
- push eax
- CallMemOrIOAddWaitState MmuWriteWord
- add SC_INVOLATILE, 4
- @@:
- add RnCount, 1
- cmp RnCount, 16
- jb rsgStdPush&link
- rspushOut&link:
- IF (link and RSO_W) ne 0
- mov eax, RnIndex
- mov ecx, RnTempG
- mov XRFI[eax*4], ecx ;; TODO: RnCheck with Reglist
- ENDIF
- add esp, RSO_STACK_REQUIRE
- arm7ClksFetch1
- ELSEIF (link and RSO_L) ne 0
- ;; LDM ----------------------------------------------------------------------
- ;; Check Rn's adjust
- mov ecx, RnIndex
- bt RegList, ecx
- jnc @F
- mov RnAdjust, 1 ;; NoAdjust Base Register.
- @@:
- IF (link and RSO_S) ne 0
- test RegList, 08000h
- jne rspop&link
- mov eax, SC_CPSR
- and eax, ARM7_MODE_GET_MASK
- cmp eax, ARM7_MODE_SYS_MASK
- je rspop&link
- cmp eax, ARM7_MODE_USER_MASK
- je rspop&link
- cmp eax, ARM7_MODE_FIQ_MASK
- je rsgFIQPop&link
- jmp rsgUserPop&link
- ELSEIF (link and RSO_S) eq 0
- jmp rspop&link
- ENDIF
- ;; LDM User Mode -------------------------------------------------------
- rsgUserPop&link:
- shr RegList, 1
- jnc @F
- mov eax, RnCount
- lea SC_INVOLATILE, XRFI[eax*4]
- add eax, 1
- and eax, 15
- cmp eax, 14
- jb rsgUserPopSkip&link
- sub eax, 14
- lea SC_INVOLATILE, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
- rsgUserPopSkip&link:
- mov eax, RnTemp
- and eax, -4
- push eax
- CallMemOrIOAddWaitState MmuReadWord
- mov [SC_INVOLATILE], eax
- add RnTemp, 4
- @@:
- add RnCount, 1
- cmp RnCount, 16
- jb rsgUserPop&link
- jmp rsgPopOut&link
- ;; LDM FIQ Mode -------------------------------------------------------
- rsgFIQPop&link:
- shr RegList, 1
- jnc @F
- mov eax, RnCount
- lea SC_INVOLATILE, XRFI[eax*4]
- add eax, 1
- and eax, 15
- cmp eax, 9
- jb rsgFIQPopSkip&link
- cmp eax, 13
- jb rsgFIQPopSkip&link
- lea SC_INVOLATILE, [SC_ARM7].R812_T[R812b_FIQ+ eax*4]
- jmp rsgFIQPopSkip&link
- sub eax, 14
- lea SC_INVOLATILE, [SC_ARM7].R1314_T[R1314b_FIQ+ eax*4]
- rsgFIQPopSkip&link:
- mov eax, RnTemp
- and eax, -4
- push eax
- CallMemOrIOAddWaitState MmuReadWord
- add RnTemp, 4
- @@:
- add RnCount, 1
- cmp RnCount, 16
- jb rsgFIQPop&link
- jmp rsgPopOut&link
- ;; LDM Std Mode --------------------------------------------------------
- rspop&link:
- shr RegList, 1
- jnc @F
- mov eax, RnCount
- lea SC_INVOLATILE, XRFI[eax*4]
- mov eax, RnTemp
- and eax, -4
- push eax
- CallMemOrIOAddWaitState MmuReadWord
- mov [SC_INVOLATILE], eax
- add RnTemp, 4
- mov [SC_INVOLATILE], eax
- ;; Check is finial??
- cmp RnCount, 15
- jne @F
- IF (link and RSO_W) ne 0
- cmp RnAdjust, 1
- je RnAdjustSkip&link
- mov eax, RnIndex
- mov ecx, RnTempG
- mov XRFI[eax*4], ecx
- RnAdjustSkip&link:
- ENDIF
- IF (link and RSO_S) ne 0
- SPSRToCPSR eax
- ENDIF
- add esp, RSO_STACK_REQUIRE
- test SC_CPSR, FLAG_THUMB
- jne rspopTFetch&link
- arm7PipelineFlush 2
- rspopTFetch&link:
- tbPipelineFlush 2
- @@:
- add RnCount, 1
- cmp RnCount, 16
- jb rspop&link
- rsgPopOut&link:
- IF (link and RSO_W) ne 0
- cmp RnAdjust, 1
- je @F
- mov eax, RnIndex
- mov ecx, RnTempG
- mov XRFI[eax*4], ecx
- @@:
- ENDIF
- add esp, RSO_STACK_REQUIRE
- arm7ClksFetch1
- ENDIF
- endm
- IRL_PUSH
- SWINT:
- DEBUG_OUT "Software Interrupt "
- mov eax, XRFI[SZ_PC*4]
- mov ecx, SC_CPSR
- and ecx, ARM7_MODE_CLR_MASK
- or ecx, ARM7_MODE_MGR_MASK ;; Set SVC mode.
- and ecx, not FLAG_THUMB ;; Clear Thumb exec flag
- or ecx, IRQ_INHIBI_MASK ;; Set IRQ inhibit mask
- ;; PC to SVC's LR, LR:= Current Instruction +4
- lea edx, [eax-4]
- mov [SC_ARM7].R1314_T[R1314b_MGR+1*4], edx
- ;; Adjust PC Pointer to IRQ Interrupt vector address
- mov XRFI[SZ_PC*4], ARM7_VECTOR_SOFTWARE
- ;; switch Mode
- SwitchMode ecx
- ;; Prefetch Opcode pipeline
- arm7PipelineFlush 3
- COPMO:
- COPDT:
- UDEFI: ;; undef opcode abnormal
- int 3
- ;; ALU Shift Imm5 / Shift Rs / MUL / MISC
- jTAB dd SF_I5, SF_RS, SF_I5, SF_RS, SF_I5, SF_RS, SF_I5, SF_RS, SF_I5, A7MUL, SF_I5, LDRHW, SF_I5, LDRHW, SF_I5, LDRHW
- dd SF_I5, SF_RS, SF_I5, SF_RS, SF_I5, SF_RS, SF_I5, SF_RS, SF_I5, A7SWP, SF_I5, LDRHW, SF_I5, LDRHW, SF_I5, LDRHW
- ;; ALU Imm8 Bitmap + 4bit Even Shift
- dd AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8
- dd AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8, AS_I8
- ;; LDR/ STR Imm
- dd LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12 ;;post index
- dd LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12 ;;preindex or std index
- ;; LDR/ STR Shift Rm
- dd LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI
- dd LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI
- ;; Negtive --------------------------------------------------------------------------------------------------------------------------------
- ;; Load/Stroe Multi
- dd RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET
- dd RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET
- ;; Branch Sign Imm24 Without LRLINK
- dd JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24
- ;; Branch Sign Imm24 With LRLINK
- dd JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR
- ;; FPU, GBA doesn't have to deal with these things, For Simple, Link it to int 3
- dd COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT
- dd COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT
- dd COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO
- ;; GBA Bios Software Interrupt.
- dd SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT
- ;; Thumb Instruction Entry -----------------------------------------------------------------------------------
- INSFT_DEPLOY macro lSym
- lSym:
- mov ecx, SC_INVOLATILE
- GetRFIV_T SC_INVOLATILE, 3, edx ;;Rm.
- GetRFI_T SC_INVOLATILE, 0, eax ;;Rd's Index .
- shr ecx, 6
- endm
- INSFT_DEPLOY2 macro Op
- and ecx, 31
- jne @B
- tbClksFetch1
- @@:
- Op edx, cl
- mov XRFI[eax*4], edx
- SetNZC_A
- tbClksFetch1
- endm
- INSFT_DEPLOY INLSL
- DEBUG_OUT "LSL R%d, R%d, #%d", "SC_INVOLATILE & 7", "SC_INVOLATILE }3 & 7", "SC_INVOLATILE } 6 & 31"
- or edx, edx
- mov XRFI[eax*4], edx
- SetNZ_A
- INSFT_DEPLOY2 shl
- INSFT_DEPLOY INLSR
- DEBUG_OUT "LSR R%d, R%d, #%d", "SC_INVOLATILE & 7", "SC_INVOLATILE }3 & 7", "SC_INVOLATILE } 6 & 31"
- shl edx, 1
- mov XRFI[eax*4], ecx
- ClrNZ_SetC_A
- INSFT_DEPLOY2 shr
- INSFT_DEPLOY INASR
- DEBUG_OUT "ASR R%d, R%d, #%d", "SC_INVOLATILE & 7", "SC_INVOLATILE }3 & 7", "SC_INVOLATILE } 6 & 31"
- shl edx, 1
- sbb ecx, ecx ;; 0 or -1
- mov XRFI[eax*4], ecx
- SetNZC_A
- INSFT_DEPLOY2 sar
- ADDI3:
- DEBUG_OUT "ADD R%d, R%d, #%d", "SC_INVOLATILE & 7", "SC_INVOLATILE }3 & 7", "SC_INVOLATILE } 6 & 7"
- GetRFIV_T SC_INVOLATILE, 3, edx ;;Rn.
- GetRFI_T SC_INVOLATILE, 0, eax ;;Rd's Index .
- GetRFI_T SC_INVOLATILE, 6, ecx ;;Imm3
- add edx, ecx
- mov XRFI[eax*4], edx
- SetNZCV_A 0
- tbClksFetch1
- SUBI3:
- DEBUG_OUT "SUB R%d, R%d, #%d", "SC_INVOLATILE & 7", "SC_INVOLATILE }3 & 7", "SC_INVOLATILE } 6 & 7"
- GetRFIV_T SC_INVOLATILE, 3, edx ;;Rn.
- GetRFI_T SC_INVOLATILE, 0, eax ;;Rd's Index .
- GetRFI_T SC_INVOLATILE, 6, ecx ;;Imm3
- sub edx, ecx
- mov XRFI[eax*4], edx
- SetNZCV_A 1
- tbClksFetch1
- MOVI8:
- DEBUG_OUT "MOV R%d, #%d", "SC_INVOLATILE }8 & 7", "SC_INVOLATILE & 255"
- GetRFI_T SC_INVOLATILE, 8, ecx ;;Rd's Index .
- and SC_INVOLATILE, 255
- mov XRFI[ecx*4], SC_INVOLATILE
- SetNZ_A
- tbClksFetch1
- CMPI8:
- DEBUG_OUT "CMP R%d, #%d", "SC_INVOLATILE }8 & 7", "SC_INVOLATILE & 255"
- GetRFIV_T SC_INVOLATILE, 8, ecx ;;Rn's Value .
- and SC_INVOLATILE, 255
- cmp ecx, SC_INVOLATILE
- SetNZCV_A 1
- tbClksFetch1
- ADDI8:
- DEBUG_OUT "ADD R%d, #%d", "SC_INVOLATILE }8 & 7", "SC_INVOLATILE & 255"
- GetRFI_T SC_INVOLATILE, 8, ecx ;;Rd's Index .
- and SC_INVOLATILE, 255
- add XRFI[ecx*4], SC_INVOLATILE
- SetNZCV_A 0
- tbClksFetch1
- SUBI8:
- DEBUG_OUT "SUB R%d, #%d", "SC_INVOLATILE }8 & 7", "SC_INVOLATILE & 255"
- GetRFI_T SC_INVOLATILE, 8, ecx ;;Rd's Index .
- and SC_INVOLATILE, 255
- sub XRFI[ecx*4], SC_INVOLATILE
- SetNZCV_A 0
- tbClksFetch1
- ALUOP:
- ;; ALU Unwind ------------------------
- GetRFI_T SC_INVOLATILE, 0, edx ;;Rd's Index .
- GetRFIV_T SC_INVOLATILE, 3, ecx ;;Rs/Rm/Rn
- mov eax, SC_INVOLATILE
- shr eax, 6
- and eax, 15
- jmp taTAB[eax*4]
- taAND:
- DEBUG_OUT "AND R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- and XRFI[eax*4], ecx
- SetNZ_A
- tbClksFetch1
- taEOR:
- DEBUG_OUT "EOR R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- xor XRFI[eax*4], ecx
- SetNZ_A
- tbClksFetch1
- taORR:
- DEBUG_OUT "ORR R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- or XRFI[eax*4], ecx
- SetNZ_A
- tbClksFetch1
- taLSL:
- DEBUG_OUT "LSL R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- and ecx, 255
- jne @F
- ;; ZERO.
- xor ecx, ecx
- or XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- @@:
- xor eax, eax
- xor SC_INVOLATILE, SC_INVOLATILE
- cmp ecx, 32
- jb @F
- sete al
- and SC_CPSR, not FLAG_C
- bt XRFI[edx*4], eax
- mov XRFI[edx*4], SC_INVOLATILE
- sbb SC_INVOLATILE, SC_INVOLATILE ;; -1 OR 0
- shl eax, FLAG_CHECK_C_X86_BT
- or eax, SC_INVOLATILE
- or SC_CPSR, eax
- or SC_CPSR, FLAG_Z
- and SC_CPSR, not FLAG_N
- tbClksFetch1
- @@:
- shl XRFI[edx*4], cl
- SetNZC_A
- tbClksFetch1
- taLSR:
- DEBUG_OUT "LSR R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- and ecx, 255
- jne @F
- ;; ZERO.
- xor ecx, ecx
- or XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- @@:
- xor eax, eax
- xor SC_INVOLATILE, SC_INVOLATILE
- cmp ecx, 32
- jb @F
- sete al
- and SC_CPSR, not FLAG_C
- bt XRFI[edx*4], 31
- mov XRFI[edx*4], SC_INVOLATILE
- sbb SC_INVOLATILE, SC_INVOLATILE ;; -1 OR 0
- shl eax, FLAG_CHECK_C_X86_BT
- or eax, SC_INVOLATILE
- or SC_CPSR, eax
- or SC_CPSR, FLAG_Z
- and SC_CPSR, not FLAG_N
- tbClksFetch1
- @@:
- shr XRFI[edx*4], cl
- SetNZC_A
- tbClksFetch1
- taASR:
- DEBUG_OUT "ASR R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- and ecx, 255
- jne @F
- ;; ZERO.
- xor ecx, ecx
- or XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- @@:
- xor eax, eax
- xor SC_INVOLATILE, SC_INVOLATILE
- cmp ecx, 32
- jb @F
- bt XRFI[edx*4], 31
- sbb ecx, ecx
- mov XRFI[edx*4], ecx
- SetNZC_A
- tbClksFetch1
- @@:
- sar XRFI[edx*4], cl
- SetNZC_A
- tbClksFetch1
- taROR:
- DEBUG_OUT "ROR R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- and ecx, 255
- jne @F
- ;; ZERO.
- xor ecx, ecx
- or XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- @@:
- xor eax, eax
- xor SC_INVOLATILE, SC_INVOLATILE
- test ecx, 31
- jne @F
- and SC_CPSR, not FLAG_C
- bt XRFI[edx*4], 31
- sbb ecx, ecx
- shl ecx, FLAG_CHECK_C_X86_BT
- and ecx, FLAG_C
- or SC_CPSR, FLAG_C
- or XRFI[edx*4], eax
- SetNZ_A
- tbClksFetch1
- @@:
- and ecx, 31
- ror XRFI[edx*4], cl
- SetNZC_A
- tbClksFetch1
- taADC:
- DEBUG_OUT "ADC R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc XRFI[edx*4], ecx
- SetNZCV_A 0
- tbClksFetch1
- taSBC:
- DEBUG_OUT "SBC R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc XRFI[edx*4], ecx
- SetNZCV_A 1
- tbClksFetch1
- taCMP:
- DEBUG_OUT "CMP R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- cmp XRFI[edx*4], ecx
- SetNZCV_A 1
- tbClksFetch1
- taCMN:
- DEBUG_OUT "CMN R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- mov eax, XRFI[edx*4]
- add eax, ecx
- SetNZCV_A 0
- tbClksFetch1
- taTST:
- DEBUG_OUT "TST R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- test XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- taNEG:
- DEBUG_OUT "NEG R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- xor eax, eax
- sub eax, ecx
- mov XRFI[edx*4], eax
- SetNZCV_A 1
- tbClksFetch1
- taBIC:
- DEBUG_OUT "BIC R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- not ecx
- and XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- taMVN:
- DEBUG_OUT "MVN R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- not ecx
- or ecx, ecx
- mov XRFI[edx*4], ecx
- SetNZ_A
- tbClksFetch1
- taMUL:
- DEBUG_OUT "MUL R%d, R%d", "SC_INVOLATILE & 7", "SC_INVOLATILE } 3 & 7"
- mov eax, ecx
- mul XRFI[edx*4]
- mov XRFI[edx*4], eax
- MUL_CLKS_M_S3 eax, ecx, edx
- or eax, eax
- SetNZ_A
- tbClksFetchN edx
- taTAB dd taAND, taEOR, taLSL, taLSR
- dd taASR, taADC, taSBC, taROR
- dd taTST, taNEG, taCMP, taCMN
- dd taORR, taMUL, taBIC, taMVN
- ih1h2Get macro Post, RdRev, RmRev
- mov RmRev, Post
- bt Post, 7
- sbb RdRev, RdRev
- and RdRev, 8
- and RmRev, 7
- or RdRev, RmRev
- mov RmRev, Post
- and RmRev, 078h
- shr RmRev, 3 ;; TODO: Check LO-LO Trans UB.
- endm
- ADD16:
- ih1h2Get SC_INVOLATILE, ecx, edx
- DEBUG_OUT "ADD R%d, R%d", "ecx", "edx"
- mov edx, XRFI[edx*4]
- add XRFI[ecx*4], edx
- cmp ecx, 15
- jne @B
- and XRFI[ecx*4], -2
- tbPipelineFlush 2
- @@:
- tbClksFetch1
- MOV16:
- ih1h2Get SC_INVOLATILE, ecx, edx
- DEBUG_OUT "MOV R%d, R%d", "ecx", "edx"
- mov edx, XRFI[edx*4]
- mov XRFI[ecx*4], edx
- cmp ecx, 15
- jne @B
- and XRFI[ecx*4], -2
- tbPipelineFlush 2
- @@:
- tbClksFetch1
- CMP16:
- ih1h2Get SC_INVOLATILE, ecx, edx
- DEBUG_OUT "CMP R%d, R%d", "ecx", "edx"
- mov edx, XRFI[edx*4]
- cmp XRFI[ecx*4], edx
- SetNZCV_A 1
- tbClksFetch1
- BX_TB:
- mov eax, SC_INVOLATILE
- and eax, 078h
- shr eax, 3
- DEBUG_OUT "BX R%d", "eax"
- mov ecx, XRFI[eax*4]
- test ecx, 1
- je @F
- or SC_CPSR, FLAG_THUMB
- and ecx, -2
- mov XRFI[SZ_PC*4], ecx
- tbPipelineFlush 3
- @@:
- and SC_CPSR, not FLAG_THUMB
- and ecx, -2
- mov XRFI[SZ_PC*4], ecx
- tbPipelineFlush 3
- STRsc macro Routine
- mov eax, SC_INVOLATILE
- mov ecx, SC_INVOLATILE
- mov edx, SC_INVOLATILE
- and eax, 7
- shr ecx, 3
- and ecx, 7
- shr edx, 6
- and edx, 7
- DEBUG_OUT "R%d, [R%d, R%d]", "eax", "ecx", "edx"
- mov ecx, XRFI[ecx*4]
- mov eax, XRFI[eax*4]
- add ecx, XRFI[edx*4]
- push eax
- push ecx
- CallMemOrIOAddWaitState Routine
- tbClksFetchN 2
- endm
- LDRsc macro Routine, MovSt, rhs
- mov eax, SC_INVOLATILE
- mov ecx, SC_INVOLATILE
- mov edx, SC_INVOLATILE
- and eax, 7
- shr ecx, 3
- and ecx, 7
- shr edx, 6
- and edx, 7
- DEBUG_OUT "R%d, [R%d, R%d]", "eax", "ecx", "edx"
- mov ecx, XRFI[ecx*4]
- mov SC_INVOLATILE, eax
- add ecx, XRFI[edx*4]
- push ecx
- CallMemOrIOAddWaitState Routine
- MovSt eax, rhs
- mov XRFI[SC_INVOLATILE*4], eax
- tbClksFetchN 3
- endm
- STRWD:
- DEBUG_OUT "STR "
- STRsc MmuWriteWord
- STRHW:
- DEBUG_OUT "STRH "
- STRsc MmuWriteHalfWord
- STRUB:
- DEBUG_OUT "STRB "
- STRsc MmuWriteByte
- LDRWD:
- DEBUG_OUT "LDR "
- LDRsc MmuReadWord, mov, eax
- LDHW2:
- DEBUG_OUT "LDRH "
- LDRsc MmuReadHalfWord, movzx, ax
- LDRSW:
- DEBUG_OUT "LDRSH "
- LDRsc MmuReadHalfWord, movsx, ax
- LDRUB:
- DEBUG_OUT "LDRB "
- LDRsc MmuReadByte, movzx, al
- LDRSB:
- DEBUG_OUT "LDRSB "
- LDRsc MmuReadByte, movsx, al
- ;; encode: d0-d2 rd, d3-d5 rn, r6-r10 imm5*sizeof(bitdepth/8)
- ADR5 macro SftBit ;; eax:rdi, edx:address
- mov eax, SC_INVOLATILE
- mov ecx, SC_INVOLATILE
- mov edx, SC_INVOLATILE
- and eax, 7 ;; Rd
- shr ecx, 3
- and ecx, 7 ;; Rn
- shr edx, 6
- and edx, 31 ;; Imm5
- shl edx, SftBit
- DEBUG_OUT "R%d, [R%d, %d]", "eax", "ecx", "edx"
- add edx, XRFI[ecx*4]
- endm
- STR5 macro SftBit, CallRoutine
- ADR5 SftBit
- push XRFI[eax*4]
- push edx
- CallMemOrIOAddWaitState CallRoutine
- tbClksFetchN 2
- endm
- LDR5 macro SftBit, BitLimit, CallRoutine
- ADR5 SftBit
- mov SC_INVOLATILE, eax
- push edx
- CallMemOrIOAddWaitState CallRoutine
- and eax, BitLimit
- mov [SC_INVOLATILE*4], eax
- tbClksFetchN 2
- endm
- SIM08 macro lSym, SZ_BODY
- lSym:
- mov eax, SC_INVOLATILE
- mov ecx, SC_INVOLATILE
- mov edx, XRFI[SZ_BODY*4] ;; edx:PC or SP
- and eax, 255 ;; Imm8
- shr ecx, 8
- and ecx, 7 ;; ecx: RdI
- shl eax, 2 ;; eax: address temp
- IF SZ_BODY eq SZ_STACK
- DEBUG_OUT "ADD R%d, SP, %d-%03X", "ecx", "eax", "eax"
- ELSEIF SZ_BODY eq SZ_PC
- DEBUG_OUT "ADD R%d, PC, %d-%03X", "ecx", "eax", "eax"
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- LDSTR1315 macro lSym
- lSym:
- mov eax, SC_INVOLATILE
- mov ecx, SC_INVOLATILE
- mov edx, SC_INVOLATILE
- and eax, 255 ;; Imm8
- shr ecx, 8
- and ecx, 7 ;; Rd
- shl eax, 2 ;; *4 address temp
- endm
- STRW5:
- DEBUG_OUT "STR "
- STR5 2, MmuWriteWord
- STRH5:
- DEBUG_OUT "STRH "
- STR5 1, MmuWriteHalfWord
- STRB5:
- DEBUG_OUT "STRB "
- STR5 0, MmuWriteByte
- LDRW5:
- DEBUG_OUT "LDR "
- LDR5 2, 0FFFFFFFFh, MmuReadWord
- LDRH5:
- DEBUG_OUT "LDRH "
- LDR5 1, 0FFFFh, MmuReadHalfWord
- LDRB5:
- DEBUG_OUT "LDRB "
- LDR5 0, 0FFh, MmuReadByte
- LDSTR1315 LDRPC
- DEBUG_OUT "LDR R%d, [PC, #%d-%03X]", "ecx", "eax", "eax"
- mov edx, XRFI[SZ_PC*4]
- and edx, -4
- add eax, edx
- mov SC_INVOLATILE, ecx
- push eax
- CallMemOrIOAddWaitState MmuReadWord
- mov XRFI[SC_INVOLATILE*4], eax
- tbClksFetchN 3
- LDSTR1315 LDRSP
- DEBUG_OUT "LDR R%d, [SP, #%d-%03X]", "ecx", "eax", "eax"
- add eax, XRFI[SZ_LRLINK*4]
- mov SC_INVOLATILE, ecx
- push eax
- CallMemOrIOAddWaitState MmuReadWord
- mov XRFI[SC_INVOLATILE*4], eax
- tbClksFetchN 3
- LDSTR1315 STRSP
- DEBUG_OUT "STR R%d, [SP, #%d-%03X]", "ecx", "eax", "eax"
- add eax, XRFI[SZ_LRLINK*4]
- push XRFI[ecx*4]
- push eax
- CallMemOrIOAddWaitState MmuWriteWord
- tbClksFetchN 2
- SIM08 PCI08, SZ_PC
- and edx, -4
- add edx, eax
- mov XRFI[ecx*4], edx
- tbClksFetch1
- SIM08 SPI08, SZ_STACK
- add edx, eax
- mov XRFI[ecx*4], edx
- tbClksFetch1
- STKS7:
- bt SC_INVOLATILE, 7
- sbb eax, eax
- and SC_INVOLATILE, 127
- xor SC_INVOLATILE, eax
- and eax, 1
- add SC_INVOLATILE, eax
- shl SC_INVOLATILE, 2
- DEBUG_OUT "ADD SP, #%d", "SC_INVOLATILE"
- add XRFI[SZ_STACK*4], SC_INVOLATILE
- tbClksFetch1
- ;; Thumb PUSH/POP RegSet.
- ;; ------------------------------------------------------------------------------------------
- PUSHR: ;; PUSH is DB stack opreate type, if R spec, Push LRLINK to stack.
- TCount equ dword ptr[esp+12]
- RnTemp equ dword ptr[esp+16]
- RnTempi equ dword ptr[esp+20]
- DEBUG_OUT "PUSH R:%d R7-R4:%01X R3-R0:%01X", "SC_INVOLATILE } 8 & 1", "SC_INVOLATILE } 4 & 15", "SC_INVOLATILE & 15"
- sub esp, 32
- sub XRFI[SZ_STACK*4], 4
- mov TCount, 8
- shl SC_INVOLATILE, 23
- @@:
- shl SC_INVOLATILE, 1
- jnc PUSHR_c
- mov eax, TCount
- bt eax, 3 ;; Check R Spec
- sbb ecx, ecx
- and ecx, SZ_LRLINK
- or eax, ecx ;; XXX: LRLINK must be 14
- push XRFI[eax*4]
- push XRFI[SZ_STACK*4]
- CallMemOrIOAddWaitState MmuWriteWord
- add SC_GOAL_COUNT, 1
- sub XRFI[SZ_STACK*4], 4
- PUSHR_c:
- sub TCount, 1
- jge @B
- add XRFI[SZ_STACK*4], 4
- add esp, 32
- tbClksFetchN 1 ;; clks: (n-1)S+2N
- POPRP: ;; POP is IA stack opreate type, if R spec, Pop PC from stack.
- DEBUG_OUT "POP R:%d R7-R4:%01X R3-R0:%01X", "SC_INVOLATILE } 8 & 1", "SC_INVOLATILE } 4 & 15", "SC_INVOLATILE & 15"
- sub esp, 32
- mov TCount, 0
- @@:
- shr SC_INVOLATILE, 1
- jnc POPRP_c
- push XRFI[SZ_STACK*4]
- CallMemOrIOAddWaitState MmuReadWord
- mov edx, TCount
- bt edx, 3 ;; Check R Spec
- sbb ecx, ecx
- and ecx, SZ_PC
- or edx, ecx ;; XXX: PC must be 15
- mov XRFI[edx*4], eax
- add SC_GOAL_COUNT, 1
- add XRFI[SZ_STACK*4], 4
- cmp edx, SZ_PC ;; PC Flush? Flush Pipeline : nodone.
- jne POPRP_c2
- POPRP_c:
- add TCount, 1
- cmp TCount, 9
- jne @B
- add esp, 32
- tbClksFetchN 2
- POPRP_c2: ;; pc calc in final list
- add esp, 32
- tbPipelineFlush 4 ;; clks: nS+N+I HitPC +S+N
- STMIA: ;;!!!!!!!!!!!!!!SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
- DEBUG_OUT "STMIA [R%d]!, R7-R4:%01X R3-R0:%01X", "SC_INVOLATILE } 8 & 7", "SC_INVOLATILE } 4 & 15", "SC_INVOLATILE & 15"
- sub esp, 32
- mov TCount, 0
- mov eax, SC_INVOLATILE
- shr eax, 8
- and eax, 7
- mov RnTempi, eax
- mov eax, XRFI[eax*4]
- mov RnTemp, eax
- @@:
- shr SC_INVOLATILE, 1
- jnc STMIA_c
- mov eax, TCount
- push XRFI[eax*4]
- push RnTemp
- CallMemOrIOAddWaitState MmuWriteWord
- add SC_GOAL_COUNT, 1
- add RnTemp, 4
- STMIA_c:
- add TCount, 1
- cmp TCount, 8
- jne @B
- mov ecx, RnTemp
- mov eax, RnTempi
- mov XRFI[eax*4], ecx
- add esp, 32
- tbClksFetchN 1
- LDMIA:
- DEBUG_OUT "LDMIA [R%d]!, R7-R4:%01X R3-R0:%01X", "SC_INVOLATILE } 8 & 7", "SC_INVOLATILE } 4 & 15", "SC_INVOLATILE & 15"
- sub esp, 32
- mov TCount, 0
- mov eax, SC_INVOLATILE
- shr eax, 8
- and eax, 7
- mov RnTempi, eax
- mov eax, XRFI[eax*4]
- mov RnTemp, eax
- @@:
- shr SC_INVOLATILE, 1
- jnc LDMIA_c
- push RnTemp
- CallMemOrIOAddWaitState MmuReadWord
- mov ecx, TCount
- mov XRFI[ecx*4], eax
- add SC_GOAL_COUNT, 1
- add RnTemp, 4
- LDMIA_c:
- add TCount, 1
- cmp TCount, 8
- jne @B
- mov ecx, RnTemp
- mov eax, RnTempi
- mov XRFI[eax*4], ecx
- add esp, 32
- tbClksFetchN 2
- ;; Thumb JCC -----------------------------------------------------------------
- JCCEQ:
- DEBUG_OUT "JCC EQ "
- test SC_CPSR, FLAG_Z
- jne JCCAL
- JCCNV:
- DEBUG_OUT "Never exec "
- tbClksFetch1
- JCCNE:
- DEBUG_OUT "JCC NE "
- test SC_CPSR, FLAG_Z
- je JCCAL
- tbClksFetch1
- JCCCS:
- DEBUG_OUT "JCC CS "
- test SC_CPSR, FLAG_C
- jne JCCAL
- jmp JCCNV
- JCCCC:
- DEBUG_OUT "JCC CC "
- test SC_CPSR, FLAG_C
- je JCCAL
- jmp JCCNV
- JCCMI:
- DEBUG_OUT "JCC MI "
- test SC_CPSR, FLAG_N
- jne JCCAL
- jmp JCCNV
- JCCPL:
- DEBUG_OUT "JCC PL "
- test SC_CPSR, FLAG_N
- je JCCAL
- jmp JCCNV
- JCCVS:
- DEBUG_OUT "JCC VS "
- test SC_CPSR, FLAG_V
- jne JCCAL
- jmp JCCNV
- JCCVC:
- DEBUG_OUT "JCC VC "
- test SC_CPSR, FLAG_V
- je JCCAL
- jmp JCCNV
- JCCHI: ;; C = 1 && Z = 0
- DEBUG_OUT "JCC HI "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- cmp ecx, FLAG_C
- je JCCAL
- jmp JCCNV
- JCCLS: ;; C = 0 || Z = 1
- DEBUG_OUT "JCC LS "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- xor ecx, FLAG_C
- jne JCCAL
- jmp JCCNV
- JCCGE: ;; N = V
- DEBUG_OUT "JCC GE "
- mov eax, SC_CPSR
- FLAG_N_TO_V_ALIGN_SHIFT eax, FLAG_N_TO_V_ALIGN_BIT
- xor eax, SC_CPSR
- and eax, FLAG_V
- je JCCAL
- jmp JCCNV
- JCCLT: ;; N != V
- DEBUG_OUT "JCC LT "
- mov eax, SC_CPSR
- FLAG_N_TO_V_ALIGN_SHIFT eax, FLAG_N_TO_V_ALIGN_BIT
- xor eax, SC_CPSR
- and eax, FLAG_V
- jne JCCAL
- jmp JCCNV
- JCCGT: ;; N = V && Z= 0
- DEBUG_OUT "JCC GT "
- mov eax, SC_CPSR
- mov edx, SC_CPSR
- FLAG_N_TO_V_ALIGN_SHIFT eax, FLAG_N_TO_V_ALIGN_BIT
- and edx, FLAG_Z
- xor eax, SC_CPSR
- and eax, FLAG_V
- or eax, edx
- je JCCAL
- jmp JCCNV
- JCCLE: ;; Z = 1 || N!=V
- DEBUG_OUT "JCC LE "
- mov eax, SC_CPSR
- mov edx, SC_CPSR
- FLAG_N_TO_V_ALIGN_SHIFT eax, FLAG_N_TO_V_ALIGN_BIT
- and edx, FLAG_Z
- xor eax, SC_CPSR
- and eax, FLAG_V
- or eax, edx
- jne JCCAL
- jmp JCCNV
- JCCAL: ;; 1110
- DEBUG_OUT "Exec It.:"
- mov eax, SC_INVOLATILE
- and eax, 255
- mov [esp-8], eax
- movsx eax, byte ptr [esp-8]
- DEBUG_OUT ":Offset %d-%08X ", "eax", "eax"
- shl eax, 1
- add XRFI[SZ_PC*4], eax
- DEBUG_OUT ":CurrentPC %d-%08X", "ZF", "ZF"
- tbPipelineFlush 2
- SWI08: ;; Thumb Software Interrupt
- DEBUG_OUT "Thumb Software Interrupt "
- mov eax, XRFI[SZ_PC*4]
- mov ecx, SC_CPSR
- and ecx, ARM7_MODE_CLR_MASK
- or ecx, ARM7_MODE_MGR_MASK ;; Set SVC mode.
- and ecx, not FLAG_THUMB ;; Clear Thumb exec flag
- or ecx, IRQ_INHIBI_MASK ;; Set IRQ inhibit mask
- ;; PC to SVC's LR, LR:= Current Instruction next ins
- lea edx, [eax-2]
- mov [SC_ARM7].R1314_T[R1314b_MGR+1*4], edx
- ;; Adjust PC Pointer to IRQ Interrupt vector address
- mov XRFI[SZ_PC*4], ARM7_VECTOR_SOFTWARE
- ;; switch Mode
- SwitchMode ecx
- ;; Prefetch Opcode pipeline
- arm7PipelineFlush 3
- ;; JMP Sign Offset 11bit. @!SMARK.
- JMP11:
- and SC_INVOLATILE, 07FFh
- bt SC_INVOLATILE, 10
- sbb eax, eax
- shl eax, 10
- or SC_INVOLATILE, eax
- shl SC_INVOLATILE, 1
- DEBUG_OUT ":JMP 11 Offset %d-%08X ", "SC_INVOLATILE", "SC_INVOLATILE"
- add XRFI[SZ_PC*4], SC_INVOLATILE
- DEBUG_OUT ":CurrentPC %d-%08X", "ZF", "ZF"
- tbPipelineFlush 2
- ;; BL Ext
- BLEXT:
- ;; Fetch Ext High
- and SC_INVOLATILE, 07FFh
- bt SC_INVOLATILE, 10
- sbb eax, eax
- shl eax, 10
- or SC_INVOLATILE, eax
- shl SC_INVOLATILE, 12
- mov XRFI[SZ_LRLINK*4], SC_INVOLATILE
- ;; Fetch Next Opcode Must be BLSTD (TODO: Opcode Check)
- mov eax, [SC_ARM7].Opcode[4]
- and eax, 07FFh
- shl eax, 1
- add eax, XRFI[SZ_LRLINK*4]
- DEBUG_OUT ":BL Offset %d-%08X ", "ZE", "ZE"
- mov ecx, XRFI[SZ_PC*4]
- mov XRFI[SZ_PC*4], eax
- DEBUG_OUT ":CurrentPC %d-%08X ", "ZF", "ZF"
- sub ecx, 0 ;; backup to next instruction base current instruction
- or ecx, 1 ;; With Thumb flags, for BX
- DEBUG_OUT ":LINK %d-%08X ", "ecx", "ecx"
- mov XRFI[SZ_LRLINK*4] ,ecx
- ;; prefetch opcode .
- tbPipelineFlush 3
- BLSTD: ;;(in fact, with BLEXT).
- UNDEF:
- int 3
- sTAB dd INLSL, INLSL, INLSL, INLSL, INLSL, INLSL, INLSL, INLSL, INLSR, INLSR, INLSR, INLSR, INLSR, INLSR, INLSR, INLSR
- dd INASR, INASR, INASR, INASR, INASR, INASR, INASR, INASR, UNDEF, UNDEF, UNDEF, UNDEF, ADDI3, ADDI3, SUBI3, SUBI3
- dd MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8
- dd ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8
- dd ALUOP, ALUOP, ALUOP, ALUOP, ADD16, CMP16, MOV16, BX_TB, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC
- dd STRWD, STRWD, STRHW, STRHW, STRUB, STRUB, LDRSB, LDRSB, LDRWD, LDRWD, LDHW2, LDHW2, LDRUB, LDRUB, LDRSW, LDRSW
- dd STRW5, STRW5, STRW5, STRW5, STRW5, STRW5, STRW5, STRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5
- dd STRB5, STRB5, STRB5, STRB5, STRB5, STRB5, STRB5, STRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5
- ;; Negtive --------------------------------------------------------------------------------------------------------------------------------
- dd STRH5, STRH5, STRH5, STRH5, STRH5, STRH5, STRH5, STRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5
- dd STRSP, STRSP, STRSP, STRSP, STRSP, STRSP, STRSP, STRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP
- dd PCI08, PCI08, PCI08, PCI08, PCI08, PCI08, PCI08, PCI08, SPI08, SPI08, SPI08, SPI08, SPI08, SPI08, SPI08, SPI08
- dd STKS7, UNDEF, UNDEF, UNDEF, PUSHR, PUSHR, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, POPRP, POPRP, UNDEF, UNDEF
- dd STMIA, STMIA, STMIA, STMIA, STMIA, STMIA, STMIA, STMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA
- dd JCCEQ, JCCNE, JCCCS, JCCCC, JCCMI, JCCPL, JCCVS, JCCVC, JCCHI, JCCLS, JCCGE, JCCLT, JCCGT, JCCLE, JCCAL, SWI08
- dd JMP11, JMP11, JMP11, JMP11, JMP11, JMP11, JMP11, JMP11, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF
- dd BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD
- arm7tdmi_ticks endp
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement