Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;; arm7.asm
- ;; arm7 chip for gba
- ;;
- ;; Copyripht 2019 moecmks (agalis01@outlook.com)
- ;; This file is part of ArchBoyAdvance.
- ;;
- ;; This program is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 2, or (at your option)
- ;; any later version.
- ;;
- ;; This program is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;;
- ;; You should have received a copy of the GNU General Public License
- ;; along with this program; if not, write to the Free Software Foundation,
- ;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- ;; TODO:
- ;; GamePak Prfetch Timing Problem.
- .686
- .mmx
- .xmm
- .model flat, c
- option casemap :none
- ;; mmu read/write
- ;; internal will set arm7tdmi::waitState
- extrn agb_mbus_rw_seq@8:proc
- extrn agb_mbus_ww_seq@12:proc
- extrn agb_code_rhw_seq@8:proc
- extrn agb_code_rw_seq@8:proc
- extrn agb_mbus_rb_noseq@8:proc
- extrn agb_mbus_rhw_noseq@8:proc
- extrn agb_mbus_rw_noseq@8:proc
- extrn agb_mbus_wb_noseq@12:proc
- extrn agb_mbus_whw_noseq@12:proc
- extrn agb_mbus_ww_noseq@12:proc
- extrn agb_code_rhw_noseq@8:proc
- extrn agb_code_rw_noseq@8:proc
- extrn agb_gamepak_prefetch@12:proc
- extrn agb_irq_hook@4:proc
- extrn agb_stack_ww_seq@20:proc
- extrn agb_stack_ww_noseq@20:proc
- extrn agb_stack_rw_seq@8:proc
- extrn agb_stack_rw_noseq@8:proc
- STACK_PUSH_STATUS_INIT equ 0
- STACK_PUSH_STATUS_PUSH equ 1
- StackWriteSeq equ agb_stack_ww_seq@20
- StackWriteNoSeq equ agb_stack_ww_noseq@20
- StackReadSeq equ agb_stack_rw_seq@8
- StackReadNoSeq equ agb_stack_rw_noseq@8
- MmuReadWordSeq equ agb_mbus_rw_seq@8
- MmuWriteWordSeq equ agb_mbus_ww_seq@12
- MmuReadByteNoSeq equ agb_mbus_rb_noseq@8
- MmuReadHalfWordNoSeq equ agb_mbus_rhw_noseq@8
- MmuReadWordNoSeq equ agb_mbus_rw_noseq@8
- MmuWriteByteNoSeq equ agb_mbus_wb_noseq@12
- MmuWriteHalfWordNoSeq equ agb_mbus_whw_noseq@12
- MmuWriteWordNoSeq equ agb_mbus_ww_noseq@12
- tb_FetchSeq equ agb_code_rhw_seq@8
- tb_FetchNoSeq equ agb_code_rhw_noseq@8
- ARM7_FetchSeq equ agb_code_rw_seq@8
- ARM7_FetchNoSeq equ agb_code_rw_noseq@8
- AGB_GamePakPrefetch equ agb_gamepak_prefetch@12
- AGB_IRQ_Hook equ agb_irq_hook@4
- ;; 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 dw ?
- IE dw ?
- waitState dd ?
- nextNoSeqFetch dd ?
- agb dd ?
- calc dd ?
- arm7tdmi ends
- ;;==================================================================================
- ;; My CPSR IRQ-I FIQ-I THUMB-F MODE-MASK, PSW. for ARM. same as X86's PSW.
- ARM7_DEBUG equ 0
- GBA_IE_IF_MASK equ 003FFFh
- 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_MSB_BIT_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_PSR_FLAG_MASK equ 00000C101H
- ARM7_PSR_MODE4BIT_MASK equ 00F000000H
- ARM7_PSR_MODE8BIT_MASK equ 0DF000000H
- ARM7_PSR_STATE_MASK equ 020000000H
- ARM7_THUMB_BIT equ 29
- ARM7_MODE_BLOCK_SUB_TOF equ 16
- ARM7_MODE_SFT_BIT equ 24
- 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_STD_FLAGS_N equ 080000000h
- ARM7_STD_FLAGS_Z equ 040000000h
- ARM7_STD_FLAGS_C equ 020000000h
- ARM7_STD_FLAGS_V equ 010000000h
- ERRORS_ASSERT equ MOECMKS_DONE
- @ALIGN_Z equ align 16
- PTR32 equ dword ptr
- IRQ_INHIBI_MASK equ 080000000h
- IRQ_INHIBI_MASK_BIT equ 31
- 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_EXCEPT_FIQ equ R812b_BLOCK*0
- R812b_FIQ equ R812b_BLOCK*1
- R1314b_BLOCK equ 8
- R1314b_SYSUSER equ R1314b_BLOCK*0
- R1314b_MGR equ R1314b_BLOCK*1
- R1314b_IRQ equ R1314b_BLOCK*2
- R1314b_FIQ equ R1314b_BLOCK*3
- R1314b_ABT equ R1314b_BLOCK*4
- R1314b_UDEF equ R1314b_BLOCK*5
- SPSRb_BLOCK equ 4
- SPSRb_SYSUSER equ SPSRb_BLOCK*0
- SPSRb_MGR equ SPSRb_BLOCK*1
- SPSRb_IRQ equ SPSRb_BLOCK*2
- SPSRb_FIQ equ SPSRb_BLOCK*3
- SPSRb_ABT equ SPSRb_BLOCK*4
- SPSRb_UDEF equ SPSRb_BLOCK*5
- SC_CPSR8 equ bl
- SC_CPSR16 equ bx
- SC_CPSR16H equ bh
- SC_CPSR equ ebx
- SC_ARM7 equ esi
- SC_INVOL equ edi
- SC_WAIT equ ebp
- ARM7_bba1 macro
- OUTd " #%08X (IMM8:%02X, ROR:%d)", "SC_INVOL & 255 ?~ SC_INVOL}8 & 15 { 1", "SC_INVOL & 255", "SC_INVOL}8 & 15 { 1"
- endm
- ARM7_ALU_BASE_OUTd1 macro OPID
- IF OPID eq AND_OP
- OUTd "AND R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq EOR_OP
- OUTd "EOR R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ORR_OP
- OUTd "ORR R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SUB_OP
- OUTd "SUB R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADD_OP
- OUTd "ADD R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq MOV_OP
- OUTd "MOV R%d", "SC_INVOL}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq MVN_OP
- OUTd "MVN R%d", "SC_INVOL}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq BIC_OP
- OUTd "BIC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSB_OP
- OUTd "RSB R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SBC_OP
- OUTd "SBC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSC_OP
- OUTd "RSC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADC_OP
- OUTd "ADC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}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_OUTd1 macro OPID
- IF OPID eq AND_OP
- OUTd "ANDS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq EOR_OP
- OUTd "EORS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ORR_OP
- OUTd "ORRS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SUB_OP
- OUTd "SUBS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADD_OP
- OUTd "ADDS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq MOV_OP
- OUTd "MOVS R%d", "SC_INVOL}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq MVN_OP
- OUTd "MVNS R%d", "SC_INVOL}12 & 15"
- ARM7_bba1
- ELSEIF OPID eq BIC_OP
- OUTd "BICS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSB_OP
- OUTd "RSBS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq SBC_OP
- OUTd "SBCS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq RSC_OP
- OUTd "RSCS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq ADC_OP
- OUTd "ADCS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq TST_OP
- OUTd "TST R%d", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq TEQ_OP
- OUTd "TEQ R%d", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq CMP_OP
- OUTd "CMP R%d", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSEIF OPID eq CMN_OP
- OUTd "CMN R%d", "SC_INVOL}16 & 15"
- ARM7_bba1
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_BASE_OUTd2 macro OPID
- IF OPID eq AND_OP ;; LSL #2
- OUTd "AND R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq EOR_OP
- OUTd "EOR R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq ORR_OP
- OUTd "ORR R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq SUB_OP
- OUTd "SUB R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq ADD_OP
- OUTd "ADD R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq MOV_OP
- OUTd "MOV R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq MVN_OP
- OUTd "MVN R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq BIC_OP
- OUTd "BIC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq RSB_OP
- OUTd "RSB R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq SBC_OP
- OUTd "SBC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq RSC_OP
- OUTd "RSC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq ADC_OP
- OUTd "ADC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq TST_OP
- OUTd "TST R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq TEQ_OP
- OUTd "TEQ R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq CMP_OP
- OUTd "CMP R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq CMN_OP
- OUTd "CMN R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_SIGN_BASE_OUTd2 macro OPID
- IF OPID eq AND_OP ;; LSL #2
- OUTd "ANDS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq EOR_OP
- OUTd "EORS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq ORR_OP
- OUTd "ORRS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq SUB_OP
- OUTd "SUBS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq ADD_OP
- OUTd "ADDS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq MOV_OP
- OUTd "MOVS R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq MVN_OP
- OUTd "MVNS R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq BIC_OP
- OUTd "BICS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq RSB_OP
- OUTd "RSBS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq SBC_OP
- OUTd "SBCS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq RSC_OP
- OUTd "RSCS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq ADC_OP
- OUTd "ADCS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq TST_OP
- OUTd "TST R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq TEQ_OP
- OUTd "TEQ R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq CMP_OP
- OUTd "CMP R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSEIF OPID eq CMN_OP
- OUTd "CMN R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- .data
- ;; TODO: Bad Code .
- ;;
- ;; Macros assembled by MASM are difficult to debug in VS2012's embedded environment,
- ;; especially because ehco macros do not work.
- @ModeUser@ db 'MODE:USER', 0
- @ModeSys@ db 'MODE:SYS', 0
- @ModeUdef@ db 'MODE:Undef', 0
- @ModeABT@ db 'MODE:Abort', 0
- @ModeIRQ@ db 'MODE:IRQ', 0
- @ModeFIQ@ db 'MODE:FIQ', 0
- @ModeMGR@ db 'MODE:MGR', 0
- @ModeTabs dd @ModeUser@, @ModeFIQ@, @ModeIRQ@, @ModeMGR@
- dd @ModeUser@, @ModeUser@, @ModeUser@, @ModeABT@
- dd @ModeUser@, @ModeUser@, @ModeUser@, @ModeUdef@
- dd @ModeUser@, @ModeUser@, @ModeUser@, @ModeSys@
- printf PROTO C :DWORD,:VARARG
- DEBUG_OUT equ printf
- ;; 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 LhsOut 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 ;; LhsOut'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
- ;; Compile code
- 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 PTR32[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 PTR32 [@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 DEBUG_OUT
- add esp, 4
- add esp, ARGLIST_EMPTY
- pop ecx
- pop edx
- pop eax
- endm
- IF ARM7_DEBUG ne 0
- OUTd equ tem_print
- ELSE
- ;; non-debug mode
- OUTd macro arglist:vararg
- endm
- ENDIF
- OUTc equ tem_print
- DEBUG_BREAK equ int 3
- ;; GBA Mmu Operate
- IF 1
- CALLIt macro Symbol
- call Symbol
- endm
- ELSE
- CALLIt macro Symbol
- call PTR32[Symbol]
- endm
- ENDIF
- CallMemOrIO macro Symbol
- push [SC_ARM7].agb
- CALLIt Symbol
- endm
- CallMemOrIOAddWaitState macro Symbol
- push [SC_ARM7].agb
- CALLIt Symbol
- add SC_WAIT, [SC_ARM7].waitState
- endm
- CallMemOrIOAddWaitState2 macro Symbol, Addr2
- push Addr2
- push [SC_ARM7].agb
- CALLIt Symbol
- add SC_WAIT, [SC_ARM7].waitState
- endm
- Call_IRQ_Hook macro
- push eax
- push ecx
- push edx
- push [SC_ARM7].agb
- CALLIt AGB_IRQ_Hook
- pop edx
- pop ecx
- pop eax
- endm
- Add_WaitStateClks equ add SC_WAIT, [SC_ARM7].waitState
- GamePAK_Prefetch macro InternalCycle:REQ
- push InternalCycle
- push ZRS (SZ_PC)
- push [SC_ARM7].agb
- CALLIt AGB_GamePakPrefetch
- endm
- STA macro offsets
- EXITM <dword ptr[esp+offsets]>
- endm
- ZRS macro offsets
- EXITM <PTR32[SC_ARM7].Regs[(offsets)*4]>
- endm
- SetNZCV_A macro sub_bit:REQ ;; 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
- SetC_A macro
- lahf
- and SC_CPSR, not FLAG_C ;; c clear
- and eax, FLAG_C ;; save c
- or SC_CPSR, eax ;;c reset
- 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
- and out_reg, out_reg
- SetNZ_A
- endm
- Set_NZmul64 macro out_lo, out_hi
- LOCAL SkipN
- LOCAL SkipZ
- and SC_CPSR, not (FLAG_N or FLAG_Z) ;; nz clear
- bt out_hi, 31
- jnc SkipN
- or SC_CPSR, FLAG_N
- jmp SkipZ
- SkipN:
- or out_hi, out_lo
- jne SkipZ
- or SC_CPSR, FLAG_Z
- SkipZ:
- endm
- ;; ToStandPSR
- ;; destroy : ecx, eax
- ToStandPSR macro Post, REC, epx, emx
- LOCAL @setZ
- LOCAL @setC
- LOCAL @setV
- LOCAL @setOver
- mov epx, Post
- mov emx, Post
- rol epx, 8
- and epx, 0000000FFh
- test emx, FLAG_N
- je @setZ
- or epx, ARM7_STD_FLAGS_N
- @setZ:
- test emx, FLAG_Z
- je @setC
- or epx, ARM7_STD_FLAGS_Z
- @setC:
- test emx, FLAG_C
- je @setV
- or epx, ARM7_STD_FLAGS_C
- @setV:
- test emx, FLAG_V
- je @setOver
- or epx, ARM7_STD_FLAGS_V
- @setOver:
- mov REC, epx
- endm
- ;; ToFastPSR
- ;; destroy : ecx, eax
- ToFastPSR macro Post, REC, epx, emx
- LOCAL @setZ
- LOCAL @setC
- LOCAL @setV
- LOCAL @setOver
- mov epx, Post
- mov emx, Post
- ror epx, 8
- and epx, 0FF000000h
- test emx, ARM7_STD_FLAGS_N
- je @setZ
- or epx, FLAG_N
- @setZ:
- test emx, ARM7_STD_FLAGS_Z
- je @setC
- or epx, FLAG_Z
- @setC:
- test emx, ARM7_STD_FLAGS_C
- je @setV
- or epx, FLAG_C
- @setV:
- test emx, ARM7_STD_FLAGS_V
- je @setOver
- or epx, FLAG_V
- @setOver:
- 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
- Imm8BitmapSft_AC_SetC macro Sft4Imm8, REC
- LOCAL @Skip
- mov eax, Sft4Imm8
- mov ecx, Sft4Imm8
- and eax, 0FFh
- and ecx, 0F00h
- shr ecx, 7
- je @Skip
- ror eax, cl
- mov ecx, eax
- SetC_A
- mov eax, ecx
- @Skip:
- mov REC, eax
- endm
- C_op_Care equ 0
- C_op_NOCare equ 1
- ;; XXX: better case
- ShiftRegImm5 macro Post, REC, tr1c, tr2, C_op
- LOCAL @END
- LOCAL @HASH
- LOCAL @LSL
- LOCAL @LSR
- LOCAL @ASR
- LOCAL @ROR
- LOCAL @LSL_0
- LOCAL @LSR_0
- LOCAL @ASR_0
- LOCAL @ROR_0
- mov tr1c, Post
- mov tr2, Post
- shr tr1c, 5
- and tr1c, 3
- jmp @HASH[tr1c*4]
- Si5SftOp macro X86Sft, lSym
- mov tr1c, tr2
- and tr2, 15
- mov tr2, ZRS (tr2) ;; Get Rm.
- shr tr1c, 7
- and tr1c, 31
- je lSym
- 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 @END
- endm
- @LSR:
- OUTd "LSR #%d ", "SC_INVOL}7 & 31"
- Si5SftOp shr, @LSR_0
- @LSR_0:
- 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 @END
- @ASR:
- OUTd "ASR #%d ", "SC_INVOL}7 & 31"
- Si5SftOp sar, @ASR_0
- @ASR_0:
- 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 @END
- @ROR:
- OUTd "ROR #%d ", "SC_INVOL}7 & 31"
- Si5SftOp ror, @ROR_0
- @ROR_0: ;; RRX
- OUTd "...RRX "
- btr SC_CPSR, FLAG_CHECK_C_X86_BT
- rcr tr2, 1 ;; check c
- sbb tr1c, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp @END
- @ALIGN_Z
- @HASH dd @LSL, @LSR, @ASR, @ROR
- @LSL:
- OUTd "LSL #%d ", "SC_INVOL}7 & 31"
- Si5SftOp shl, @LSL_0
- @LSL_0:
- mov REC, tr2
- @END:
- OUTd "Sft Result:%08X ", "&REC&"
- endm
- ;; XXX: better case
- ShiftRegImm5_WithOutC macro Post, REC, tr1c, tr2
- LOCAL @END
- LOCAL @HASH
- LOCAL @LSL
- LOCAL @LSR
- LOCAL @ASR
- LOCAL @ROR
- LOCAL @LSL_0
- LOCAL @LSR_0
- LOCAL @ASR_0
- LOCAL @ROR_0
- mov tr1c, Post
- mov tr2, Post
- shr tr1c, 5
- and tr2, 15
- mov tr2, ZRS (tr2) ;; Get Rm.
- and tr1c, 3
- jmp @HASH[tr1c*4]
- Si5SftOp_WithOutC macro X86Sft, lSym
- mov tr1c, Post
- shr tr1c, 7
- and tr1c, 31
- je lSym
- X86Sft tr2, cl ;; check c
- mov REC, tr2
- jmp @END
- endm
- @LSR:
- OUTd "LSR #%d ", "SC_INVOL}7 & 31"
- Si5SftOp_WithOutC shr, @LSR_0
- @LSR_0:
- xor REC, REC
- jmp @END
- @ASR:
- OUTd "ASR #%d ", "SC_INVOL}7 & 31"
- Si5SftOp_WithOutC sar, @ASR_0
- @ASR_0:
- bt tr2, 31
- sbb REC, REC
- jmp @END
- @ROR:
- OUTd "ROR #%d ", "SC_INVOL}7 & 31"
- Si5SftOp_WithOutC ror, @ROR_0
- @ROR_0: ;; RRX
- OUTd "...RRX "
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- rcr tr2, 1 ;; check c
- mov REC, tr2
- jmp @END
- @ALIGN_Z
- @HASH dd @LSL, @LSR, @ASR, @ROR
- @LSL:
- OUTd "LSL #%d ", "SC_INVOL}7 & 31"
- Si5SftOp_WithOutC shl, @LSL_0
- @LSL_0:
- mov REC, tr2
- @END:
- OUTd "Sft Result:%08X ", "&REC&"
- endm
- ;; XXX: better case, use inline label.
- ShiftRegRs macro Post, REC, tr1c, tr2, C_op
- LOCAL @END
- LOCAL @HASH
- LOCAL @LSL
- LOCAL @LSR
- LOCAL @ASR
- LOCAL @ROR
- LOCAL @ROR_ep
- 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 @HASH[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 @END
- endm
- Rs_Stiff macro
- LOCAL locSym
- mov tr1c, tr2
- and tr2, 15
- cmp tr2, SZ_PC
- mov tr2, ZRS (tr2) ;; Get Rm.
- jne locSym
- add tr2, 4 ;; PC + 12, if rm in rorate shift.
- locSym:
- shr tr1c, 8
- and tr1c, 15
- mov tr1c, ZRS (tr1c) ;; Get Rs
- and tr1c, 255
- ;; TODO:better case ?
- cmp tr1c, 32
- jl @F
- endm
- @LSL:
- OUTd "LSL R%d ", "SC_INVOL}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- ;; ;; DEBUG_BREAK
- 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 @END
- @@:
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp @END
- @@:
- Rs_SftOp shl
- @LSR:
- OUTd "LSR R%d ", "SC_INVOL}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- ;; DEBUG_BREAK
- 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 @END
- @@:
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp @END
- @@:
- Rs_SftOp shr
- @ASR:
- OUTd "ASR R%d ", "SC_INVOL}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- ;; DEBUG_BREAK
- 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 @END
- @@:
- test tr1c, tr1c
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp @END
- @@:
- Rs_SftOp sar
- @ROR:
- OUTd "ROR R%d ", "SC_INVOL}8 & 15"
- mov tr1c, tr2
- and tr2, 15
- cmp tr2, SZ_PC
- mov tr2, ZRS (tr2) ;; Get Rm.
- jne @ROR_ep
- add tr2, 4
- @ROR_ep:
- shr tr1c, 8
- and tr1c, 15
- mov tr1c, ZRS (tr1c) ;; Get Rs
- and tr1c, 255
- jne @F
- ;; Rs := 0
- mov REC, tr2
- jmp @END
- @@:
- and tr1c, 31
- jne @F
- and SC_CPSR, not FLAG_C
- bt tr2, 31
- sbb tr1c, tr1c
- and tr1c, FLAG_C
- or SC_CPSR, tr1c
- mov REC, tr2
- jmp @END
- @@:
- Rs_SftOp ror
- @HASH dd @LSL, @LSR, @ASR, @ROR
- @END:
- IF C_op eq C_op_NOCare
- IF ARM7_DEBUG ne 0
- add esp, 32
- ENDIF
- mov SC_CPSR, [esp-8]
- ENDIF
- OUTd "Sft Result:%08X ", "&REC&"
- endm
- ;; XXX: better case, use inline label.
- ShiftRegRs_WithOutC macro Post, REC, tr1c, tr2, C_op
- LOCAL @END
- LOCAL @HASH
- LOCAL @LSL
- LOCAL @LSR
- LOCAL @ASR
- LOCAL @ROR
- LOCAL @ZERO
- mov tr1c, Post
- mov tr2, Post
- shr tr1c, 5
- and tr1c, 3
- jmp @HASH[tr1c*4]
- Rs_SftOp macro X86Sft
- X86Sft tr2, cl ;; check c
- mov REC, tr2
- jmp @END
- endm
- Rs_Stiff macro
- mov tr1c, tr2
- and tr2, 15
- mov tr2, ZRS (tr2) ;; Get Rm.
- shr tr1c, 8
- and tr1c, 15
- mov tr1c, ZRS (tr1c) ;; Get Rs
- and tr1c, 255
- ;; TODO:better case ?
- cmp tr1c, 32
- jl @F
- endm
- @LSR:
- OUTd "LSR R%d ", "SC_INVOL}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- ;; ;; DEBUG_BREAK
- xor REC, REC
- jmp @END
- @@:
- test tr1c, tr1c
- je @ZERO
- Rs_SftOp shr
- @ASR:
- OUTd "ASR R%d ", "SC_INVOL}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- ;; DEBUG_BREAK
- shl tr2, 1
- sbb REC, REC
- jmp @END
- @@:
- test tr1c, tr1c
- je @ZERO
- Rs_SftOp sar
- @ROR:
- OUTd "ROR R%d ", "SC_INVOL}8 & 15"
- mov tr1c, Post
- shr tr1c, 8
- and tr1c, 15
- mov tr1c, ZRS (tr1c)
- and tr1c, 31
- je @ZERO
- Rs_SftOp ror
- @HASH dd @LSL, @LSR, @ASR, @ROR
- @LSL:
- OUTd "LSL R%d ", "SC_INVOL}8 & 15"
- Rs_Stiff
- ;; Rs >= 32
- ;; DEBUG_BREAK
- xor REC, REC
- jmp @END
- @@:
- test tr1c, tr1c
- je @ZERO
- shl tr2, cl ;; check c
- @ZERO:
- mov REC, tr2
- @END:
- OUTd "Sft Result:%08X ", "&REC&"
- endm
- ;; Resume CPSR from current mode's SPSR.
- ;; destroy: eax, ecx, edx
- SPSRToCPSR macro tr
- ;; Copy SPSR to CPSR.
- GetCurSPSRP tr
- mov tr, [tr]
- ;; Switch CPU mode.
- SwitchMode tr, 1
- endm
- SC_CPSR8 equ bl
- SC_CPSR16 equ bx
- SC_CPSR16H equ bh
- SC_CPSR equ ebx
- SC_ARM7 equ esi
- SC_INVOL equ edi
- SC_WAIT equ ebp
- ;; FETCH ---------------------------------------------------------------
- ARM7_ExitAddPC macro Clks:REQ
- mov ecx, ZRS (SZ_PC)
- mov ZRS (SZ_CPSR), SC_CPSR
- add ecx, 4
- and ecx,-4
- lea eax, [SC_WAIT+Clks]
- mov ZRS (SZ_PC), ecx
- pop ebx
- pop ebp
- pop esi
- pop edi
- ret
- endm
- tb_ExitAddPC macro Clks:REQ
- mov ecx, ZRS (SZ_PC)
- mov ZRS (SZ_CPSR), SC_CPSR
- add ecx, 2
- and ecx,-2
- lea eax, [SC_WAIT+Clks]
- mov ZRS (SZ_PC), ecx
- pop ebx
- pop ebp
- pop esi
- pop edi
- ret
- endm
- arm7_FlushPipeline macro Clks:REQ
- mov SC_INVOL, ZRS (SZ_PC)
- push SC_INVOL
- CallMemOrIOAddWaitState ARM7_FetchNoSeq
- add SC_INVOL, 4 ;; ++PC
- mov [SC_ARM7].Opcode[0], eax
- push SC_INVOL
- CallMemOrIOAddWaitState ARM7_FetchSeq
- add SC_INVOL, 4 ;; ++PC
- and SC_INVOL, -4
- mov [SC_ARM7].Opcode[4], eax
- mov ZRS (SZ_PC), SC_INVOL
- mov ZRS (SZ_CPSR), SC_CPSR
- lea eax, [SC_WAIT+Clks]
- pop ebx
- pop ebp
- pop esi
- pop edi
- ret
- endm
- tb_FlushPipeline macro Clks:REQ
- mov SC_INVOL, ZRS (SZ_PC)
- push SC_INVOL
- CallMemOrIOAddWaitState tb_FetchNoSeq
- add SC_INVOL, 2 ;; ++PC
- mov [SC_ARM7].Opcode[0], eax
- push SC_INVOL
- CallMemOrIOAddWaitState tb_FetchSeq
- add SC_INVOL, 2 ;; ++PC
- and SC_INVOL, -2
- mov [SC_ARM7].Opcode[4], eax
- mov ZRS (SZ_PC), SC_INVOL
- mov ZRS (SZ_CPSR), SC_CPSR
- lea eax, [SC_WAIT+Clks]
- pop ebx
- pop ebp
- pop esi
- pop edi
- ret
- endm
- GetRFI macro Post, BitScanStart, REC
- mov REC, Post
- shr REC, BitScanStart
- and REC, 15
- endm
- GetRFIV macro Post, BitScanStart, REC
- GetRFI Post, BitScanStart, REC
- mov REC, ZRS (REC)
- endm
- GetRFI_T macro Post, BitScanStart, REC
- mov REC, Post
- shr REC, BitScanStart
- and REC, 7
- endm
- GetRFIV_T macro Post, BitScanStart, REC
- GetRFI_T Post, BitScanStart, REC
- mov REC, ZRS (REC)
- endm
- GetCurSPSRP macro REC
- LOCAL @FIQ
- LOCAL @IRQ
- LOCAL @UDEF
- LOCAL @USYS
- LOCAL @UNUSED
- LOCAL @SVC
- LOCAL @ABT
- LOCAL @END
- LOCAL @HASH
- mov REC, SC_CPSR
- and REC, 00F000000h
- shr REC, 24
- jmp PTR32 @HASH [REC*4]
- ;; ---------------------------------------------------------------------------------
- @USYS:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_SYSUSER]
- jmp @END
- @IRQ:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_IRQ]
- jmp @END
- .data
- @ALIGN_Z
- @HASH dd @USYS, @FIQ, @IRQ, @SVC
- dd @UNUSED, @UNUSED, @UNUSED, @ABT
- dd @UNUSED, @UNUSED, @UNUSED, @UDEF
- dd @UNUSED, @UNUSED, @UNUSED, @USYS
- .code
- @FIQ:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_FIQ]
- jmp @END
- @UDEF:
- @ABT:
- @UNUSED:
- int 3
- @SVC:
- lea REC, [SC_ARM7].SPSR_T[SPSRb_MGR]
- @END:
- endm
- ;; switch 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 @UNUSED
- LOCAL @SPSR_TABLE
- LOCAL @FIQ2
- LOCAL @IRQ2
- LOCAL @UDEF2
- LOCAL @USER2
- LOCAL @SVC2
- LOCAL @ABT2
- LOCAL @UNUSED2
- LOCAL @SPSR2_TABLE
- LOCAL @END
- push SC_WAIT
- mov eax, SG_PSR
- mov edx, SC_CPSR
- xor ecx, ecx
- mov [SC_ARM7].calc, SC_CPSR ;; save old CPSR
- mov SC_CPSR, eax
- and eax, ARM7_MODE_GET_MASK
- and edx, ARM7_MODE_GET_MASK
- ;; Check FIQ r8_r12 bank store
- cmp eax, ARM7_MODE_FIQ_MASK
- sete cl
- cmp edx, ARM7_MODE_FIQ_MASK
- sete ch
- or cl, ch
- movzx SC_WAIT, cl
- xor ecx, ecx
- cmp eax, ARM7_MODE_USER_MASK
- sete ch
- cmp eax, ARM7_MODE_SYS_MASK
- sete cl
- or cl, ch
- shl ecx, 24
- cmp edx, ARM7_MODE_USER_MASK
- sete ch
- cmp edx, ARM7_MODE_SYS_MASK
- sete cl
- or cl, ch
- rol ecx, 8
- and ch, cl
- jne @END
- mov ecx, [SC_ARM7].calc
- shr eax, ARM7_MODE_SFT_BIT
- shr edx, ARM7_MODE_SFT_BIT
- sub eax, ARM7_MODE_BLOCK_SUB_TOF
- sub edx, ARM7_MODE_BLOCK_SUB_TOF
- jmp PTR32 @SPSR_TABLE[edx*4]
- saveR8_12 macro R812Bank, Post
- mov Post, ZRS (8)
- mov [SC_ARM7].R812_T[R812Bank], Post
- mov Post, ZRS (9)
- mov [SC_ARM7].R812_T[R812Bank+4], Post
- mov Post, ZRS (10)
- mov [SC_ARM7].R812_T[R812Bank+8], Post
- mov Post, ZRS (11)
- mov [SC_ARM7].R812_T[R812Bank+12], Post
- mov Post, ZRS (12)
- mov [SC_ARM7].R812_T[R812Bank+16], Post
- endm
- loadR8_12 macro R812Bank, Post
- mov Post, [SC_ARM7].R812_T[R812Bank]
- mov ZRS (8), Post
- mov Post, [SC_ARM7].R812_T[R812Bank+4]
- mov ZRS (9), Post
- mov Post, [SC_ARM7].R812_T[R812Bank+8]
- mov ZRS (10), Post
- mov Post, [SC_ARM7].R812_T[R812Bank+12]
- mov ZRS (11), Post
- mov Post, [SC_ARM7].R812_T[R812Bank+16]
- mov ZRS (12), Post
- endm
- saveR13_14 macro R1314Bank, Post
- mov Post, ZRS (13)
- mov [SC_ARM7].R1314_T[R1314Bank], Post
- mov Post, ZRS (14)
- mov [SC_ARM7].R1314_T[R1314Bank+4], Post
- endm
- loadR13_14 macro R1314Bank, Post
- mov Post, [SC_ARM7].R1314_T[R1314Bank]
- mov ZRS (13), Post
- mov Post, [SC_ARM7].R1314_T[R1314Bank+4]
- mov ZRS (14), Post
- endm
- markBankSave macro lSym, R812Bank, R1314Bank
- LOCAL locSym
- lSym:
- test SC_WAIT, SC_WAIT
- je locSym
- saveR8_12 R812Bank, edx
- locSym:
- saveR13_14 R1314Bank, edx
- jmp PTR32 @SPSR2_TABLE[eax*4]
- endm
- ;; -------- Mode Current Check Save to bank --------
- markBankSave @USER, R812b_EXCEPT_FIQ, R1314b_SYSUSER
- markBankSave @FIQ, R812b_FIQ, R1314b_FIQ
- markBankSave @IRQ, R812b_EXCEPT_FIQ, R1314b_IRQ
- markBankSave @SVC, R812b_EXCEPT_FIQ, R1314b_MGR
- markBankSave @ABT, R812b_EXCEPT_FIQ, R1314b_ABT
- markBankSave @UDEF, R812b_EXCEPT_FIQ, R1314b_UDEF
- markBankLoad macro lSym, R812Bank, R1314Bank, SPSRBank
- LOCAL locSym
- lSym:
- test SC_WAIT, SC_WAIT
- je locSym
- loadR8_12 R812Bank, eax
- locSym:
- loadR13_14 R1314Bank, eax
- IF R1314Bank ne R1314b_SYSUSER
- IF CPSR_Copy_dis eq 0
- mov [SC_ARM7].SPSR_T[SPSRBank], ecx
- ENDIF
- ENDIF
- jmp @END
- endm
- ;; -------- Mode New Check Store to runtime regs group --------
- markBankLoad @USER2, R812b_EXCEPT_FIQ, R1314b_SYSUSER, SPSRb_SYSUSER
- markBankLoad @FIQ2, R812b_FIQ, R1314b_FIQ, SPSRb_FIQ
- markBankLoad @IRQ2, R812b_EXCEPT_FIQ, R1314b_IRQ, SPSRb_IRQ
- markBankLoad @SVC2, R812b_EXCEPT_FIQ, R1314b_MGR, SPSRb_MGR
- markBankLoad @ABT2, R812b_EXCEPT_FIQ, R1314b_ABT, SPSRb_ABT
- markBankLoad @UDEF2, R812b_EXCEPT_FIQ, R1314b_UDEF, SPSRb_UDEF
- @UNUSED:
- @UNUSED2:
- int 3
- .data
- @ALIGN_Z
- @SPSR_TABLE dd @USER, @FIQ, @IRQ, @SVC
- dd @UNUSED, @UNUSED, @UNUSED, @ABT
- dd @UNUSED, @UNUSED, @UNUSED, @UDEF
- dd @UNUSED, @UNUSED, @UNUSED, @USER
- @SPSR2_TABLE dd @USER2, @FIQ2, @IRQ2, @SVC2
- dd @UNUSED2, @UNUSED2, @UNUSED2, @ABT2
- dd @UNUSED2, @UNUSED2, @UNUSED2, @UDEF2
- dd @UNUSED2, @UNUSED2, @UNUSED2, @USER2
- .code
- @END:
- pop SC_WAIT
- endm
- .code
- ;;=====================================================================================
- ;; arm7tdmi_ticks c prototype
- ;; uint16_t arm7tdmi_ticks (struct arm7tdmi *arm7)
- ;; 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
- xor SC_WAIT, SC_WAIT
- mov SC_ARM7, STA (4+STACK_PUSH)
- mov SC_CPSR, ZRS (SZ_CPSR)
- ;; prefetcht0 [SC_ARM7]
- mov ax, [SC_ARM7].IFS
- and ax, [SC_ARM7].IE
- and eax, GBA_IE_IF_MASK
- bt dword ptr[SC_ARM7].IME, 0
- sbb edx, edx
- and eax, edx ;; GBA_IE_IF_MASK.
- bt SC_CPSR, IRQ_INHIBI_MASK_BIT
- sbb edx, edx
- not edx
- and eax, edx
- je e_step
- IF 0
- Call_IRQ_Hook
- ENDIF
- mov eax, ZRS (SZ_PC)
- 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 +4], edx
- ;; Adjust PC Pointer to IRQ Interrupt vector address
- mov ZRS (SZ_PC), ARM7_VECTOR_IRQ
- mov SC_INVOL, SC_CPSR
- and SC_INVOL, ARM7_MODE_GET_MASK
- cmp SC_INVOL, ARM7_MODE_IRQ_MASK
- je @Nest_IRQ
- ;; switch Mode
- SwitchMode ecx, 0
- ;; Prefetch Opcode pipeline
- arm7_FlushPipeline 5 ;; minimum interrupt cycle delay
- @Nest_IRQ:
- mov ZRS (SZ_LRLINK), edx
- mov [SC_ARM7].SPSR_T[SPSRb_IRQ], SC_CPSR
- mov eax, ZRS (SZ_STACK)
- mov [SC_ARM7].R1314_T[R1314b_IRQ], eax
- mov eax, ZRS (SZ_LRLINK)
- mov [SC_ARM7].R1314_T[R1314b_IRQ+4], eax
- mov SC_CPSR, ecx
- ;; Prefetch Opcode pipeline
- arm7_FlushPipeline 5
- ;; 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
- @ALIGN_Z
- DEBUG_TICK macro Address
- local dm
- push eax
- mov eax, ZRS(SZ_PC)
- cmp eax, Address+8
- jne dm
- int 3
- dm:
- pop eax
- endm
- DEBUG_TICK2 macro Address
- local dm
- push eax
- mov eax, ZRS(SZ_PC)
- cmp eax, Address+4
- jne dm
- int 3
- dm:
- pop eax
- endm
- e_step:
- xor SC_WAIT, SC_WAIT
- mov eax, [SC_ARM7].nextNoSeqFetch
- mov [SC_ARM7].nextNoSeqFetch, SC_WAIT
- test SC_CPSR, FLAG_THUMB
- jne @F
- ;; ARM7 Code, do next instruction's first seq/noseq read cycle
- push ZRS (SZ_PC)
- test eax, eax
- je aaf7
- CallMemOrIOAddWaitState ARM7_FetchNoSeq
- jmp nn
- aaf7:
- CallMemOrIOAddWaitState ARM7_FetchSeq
- nn:
- mov SC_INVOL, [SC_ARM7].Opcode[0]
- mov ecx, [SC_ARM7].Opcode[4]
- mov [SC_ARM7].Opcode[4], eax
- mov [SC_ARM7].Opcode[0], ecx
- mov eax, SC_INVOL
- OUTd "\n\nPC:%08X-OP:%08X-SP:%08X LR:%08X -M:%s-\n", "ZF-8", "SC_INVOL", "ZD", "ZE", "#"
- OUTd "R0:%08X R1:%08X R2:%08X R3:%08X \n", "Z0", "Z1", "Z2", "Z3"
- OUTd "R4:%08X R5:%08X R6:%08X R7:%08X \n", "Z4", "Z5", "Z6", "Z7"
- OUTd "R8:%08X R9:%08X R10:%08X R11:%08X R12:%08X \n", "Z8", "Z9", "ZA", "ZB", "ZC"
- OUTd "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, 28
- jmp fTAB[eax*4]
- @@:
- ;; Thumb Code, do next instruction's first seq/noseq read cycle
- push ZRS (SZ_PC)
- test eax, eax
- je uaf7
- CallMemOrIOAddWaitState tb_FetchNoSeq
- jmp cc
- uaf7:
- CallMemOrIOAddWaitState tb_FetchSeq
- cc:
- mov SC_INVOL, [SC_ARM7].Opcode[0]
- mov ecx, [SC_ARM7].Opcode[4]
- mov [SC_ARM7].Opcode[4], eax
- mov [SC_ARM7].Opcode[0], ecx
- OUTd "\n\nPC:%08X-OP:%04X-SP:%08X LR:%08X -M:%s-\n", "ZF-4", "SC_INVOL & 0FFFFh","ZD", "ZE" , "#"
- OUTd "R0:%08X R1:%08X R2:%08X R3:%08X \n", "Z0", "Z1", "Z2", "Z3"
- OUTd "R4:%08X R5:%08X R6:%08X R7:%08X \n", "Z4", "Z5", "Z6", "Z7"
- OUTd "R8:%08X R9:%08X R10:%08X R11:%08X R12:%08X \n", "Z8", "Z9", "ZA", "ZB", "ZC"
- OUTd "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 SC_INVOL, 0FFFFh
- mov eax, SC_INVOL
- mov edx, SC_INVOL
- mov ecx, SC_INVOL
- shr ecx, 8
- and ecx, 255
- jmp sTAB[ecx*4]
- ;; ARM7 Instruction Entry -----------------------------------------------------------------------------------
- AS_I8:
- OUTd "I:AS_I8;;*** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp i8r4TAB[eax*4]
- SF_RS:
- OUTd "I:SF_RS;;*** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp rsTAB[eax*4]
- SF_I5:
- OUTd "I:SF_I5;;*** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp si5TAB[eax*4]
- A7MUL:
- OUTd "I:A7MUL;;*** "
- mov eax, edx
- and eax, 000F00000h
- shr eax, 20
- jmp ARM7_MUL_TAB[eax*4]
- LDI12:
- OUTd "I:LDI12;;*** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp nTAB[eax*4]
- LDIRS:
- OUTd "I:LDIRS;;*** "
- mov eax, edx
- and eax, 001F00000h
- shr eax, 20
- jmp eTAB[eax*4]
- LDRHW: ;; FIXME
- OUTd "I:LDRHW;;*** "
- mov eax, edx
- mov ecx, edx
- and ecx, 060h
- and eax, 0100000h
- shr eax, 18
- shr ecx, 5
- or ecx, eax ;;
- and ecx, 7
- mov eax, SC_INVOL
- 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:
- OUTd "I:RGSET;;*** "
- mov eax, SC_INVOL
- shr eax, 20
- and eax, 31
- jmp zTAB[eax*4]
- ;; ARM7 Instruction Entry -----------------------------------------------------------------------------------
- fEQ:
- OUTd "Cond:EQ "
- test SC_CPSR, FLAG_Z
- jne fAL
- fNV:
- OUTd ":Skip "
- ARM7_ExitAddPC 1
- fNE:
- OUTd "Cond:NE "
- test SC_CPSR, FLAG_Z
- je fAL
- ARM7_ExitAddPC 1
- fCS:
- OUTd "Cond:CS "
- test SC_CPSR, FLAG_C
- jne fAL
- jmp fNV
- fCC:
- OUTd "Cond:CC "
- test SC_CPSR, FLAG_C
- je fAL
- jmp fNV
- fMI:
- OUTd "Cond:MI "
- test SC_CPSR, FLAG_N
- jne fAL
- jmp fNV
- fPL:
- OUTd "Cond:PL "
- test SC_CPSR, FLAG_N
- je fAL
- jmp fNV
- fVS:
- OUTd "Cond:VS "
- test SC_CPSR, FLAG_V
- jne fAL
- jmp fNV
- fVC:
- OUTd "Cond:VC "
- test SC_CPSR, FLAG_V
- je fAL
- jmp fNV
- fHI: ;; C = 1 && Z = 0
- OUTd "Cond:HI "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- cmp ecx, FLAG_C
- je fAL
- jmp fNV
- fLS: ;; C = 0 || Z = 1
- OUTd "Cond:LS "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- ;; C0Z1 ^ C1Z0 -> C1Z1
- ;; C1Z1 ^ C1Z0 -> C0Z1
- ;; C0Z0 ^ C1Z0 -> C1Z0
- ;; C1Z0 ^ C1Z0 -> ZERO.
- xor ecx, FLAG_C
- jne fAL
- jmp fNV
- fGE: ;; N = V
- OUTd "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
- OUTd "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
- OUTd "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
- OUTd "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_INVOL
- mov eax, SC_INVOL
- mov edx, SC_INVOL
- 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 ;; With C
- RSB_OP equ 3 ;; With C
- ADD_OP equ 4 ;; With C
- ADC_OP equ 5 ;; With C
- SBC_OP equ 6 ;; With C
- RSC_OP equ 7 ;; With C
- TST_OP equ 8 ;; NORMAL SET-
- TEQ_OP equ 9 ;; NORMAL SET-
- CMP_OP equ 10 ;; With C
- CMN_OP equ 11 ;; With C
- ORR_OP equ 12
- MOV_OP equ 13
- BIC_OP equ 14
- MVN_OP equ 15
- ARM7_ALU_BASE macro OPID, LhsOut, Rhs
- IF OPID eq AND_OP
- and LhsOut, Rhs
- ELSEIF OPID eq EOR_OP
- xor LhsOut, Rhs
- ELSEIF OPID eq ORR_OP
- or LhsOut, Rhs
- ELSEIF OPID eq SUB_OP
- sub LhsOut, Rhs
- ELSEIF OPID eq ADD_OP
- add LhsOut, Rhs
- ELSEIF OPID eq MOV_OP
- mov LhsOut, Rhs
- ELSEIF OPID eq MVN_OP
- not Rhs
- mov LhsOut, Rhs
- ELSEIF OPID eq BIC_OP
- not Rhs
- and LhsOut, Rhs
- ELSEIF OPID eq RSB_OP
- sub Rhs, LhsOut
- mov LhsOut, Rhs
- ELSEIF OPID eq SBC_OP
- xor SC_CPSR, FLAG_C
- btc SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb LhsOut, Rhs
- ELSEIF OPID eq RSC_OP
- xor SC_CPSR, FLAG_C
- btc SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb Rhs, LhsOut
- mov LhsOut, Rhs
- ELSEIF OPID eq ADC_OP
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc LhsOut, Rhs
- ELSEIF OPID eq TST_OP
- and LhsOut, Rhs
- SetNZ_A
- ELSEIF OPID eq TEQ_OP
- xor LhsOut, Rhs
- SetNZ_A
- ELSEIF OPID eq CMP_OP
- cmp LhsOut, Rhs
- SetNZCV_A 1
- ELSEIF OPID eq CMN_OP
- add LhsOut, Rhs
- SetNZCV_A 0
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- endm
- ARM7_ALU_SIGN_BASE macro OPID, LhsOut, Rhs ;; LhsOut Must not eax!
- IF OPID eq AND_OP
- and LhsOut, Rhs
- SetNZ_A
- ELSEIF OPID eq EOR_OP
- xor LhsOut, Rhs
- SetNZ_A
- ELSEIF OPID eq ORR_OP
- or LhsOut, Rhs
- SetNZ_A
- ELSEIF OPID eq SUB_OP
- sub LhsOut, Rhs
- SetNZCV_A 1
- ELSEIF OPID eq ADD_OP
- add LhsOut, Rhs
- SetNZCV_A 0
- ELSEIF OPID eq MOV_OP
- mov LhsOut, Rhs
- test LhsOut, LhsOut
- SetNZ_A
- ELSEIF OPID eq MVN_OP
- not Rhs
- mov LhsOut, Rhs
- test LhsOut, LhsOut
- SetNZ_A
- ELSEIF OPID eq BIC_OP
- not Rhs
- and LhsOut, Rhs
- SetNZ_A
- ELSEIF OPID eq RSB_OP
- sub Rhs, LhsOut
- mov LhsOut, Rhs
- SetNZCV_A 1
- ELSEIF OPID eq SBC_OP
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb LhsOut, Rhs
- SetNZCV_A 1
- ELSEIF OPID eq RSC_OP
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb Rhs, LhsOut
- mov LhsOut, Rhs
- SetNZCV_A 1
- ELSEIF OPID eq ADC_OP
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc LhsOut, Rhs
- SetNZCV_A 0
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- endm
- i8r4_ALU macro lSym, OPID
- @ALIGN_Z
- i8r4&lSym:
- ;; Clks 1: ALU Operate, and MemAccess Seq Read Next Opcode, indicate next mREQ:0 Seq:0
- IF (OPID and 1100b) ne 1000b
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSEIF (OPID and 1100b) eq 1000b
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ENDIF
- GetRFIV SC_INVOL, 16, ecx ;; Rn
- GetRFI SC_INVOL, 12, edx ;; RdIs
- ARM7_ALU_BASE_OUTd1 OPID
- ARM7_ALU_BASE OPID, ecx, eax
- IF (OPID and 1100b) ne 1000b
- ;; Write Back, Check R15.
- mov ZRS (edx), ecx
- cmp edx, 15
- jne @F
- ;; dest := pc
- ;; Clks 2: MemAccess, NoSeq Read. (because current is new pc read first), indicate next mREQ:0 Seq:1
- ;; Clks 3: MemAccess (new pc read, second), Seq Read.
- arm7_FlushPipeline 3
- @@:
- ENDIF
- ARM7_ExitAddPC 1
- IF (OPID and 1100b) ne 1000b
- @ALIGN_Z
- i8r4&lSym&S:
- ;; Save Old CPSR
- mov [SC_ARM7].calc, SC_CPSR
- IF OPID eq AND_OP
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq EOR_OP
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq ORR_OP
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq SUB_OP ;; with C
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq ADD_OP ;; with C
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq MOV_OP
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq MVN_OP
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq BIC_OP
- Imm8BitmapSft_AC_SetC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq RSB_OP ;; with C
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq SBC_OP ;; with C
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq RSC_OP ;; with C
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSEIF OPID eq ADC_OP ;; with C
- Imm8BitmapSft_AC SC_INVOL, eax ;; Rm
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- GetRFIV SC_INVOL, 16, ecx ;; Rn
- GetRFI SC_INVOL, 12, edx ;; RdIs
- ARM7_ALU_SIGN_BASE_OUTd1 OPID
- ARM7_ALU_SIGN_BASE OPID, ecx, eax
- mov ZRS (edx), ecx
- cmp edx, 15
- je @F
- ARM7_ExitAddPC 1
- @@:
- ;; R15 resume old CPSR.
- mov SC_CPSR, [SC_ARM7].calc
- SPSRToCPSR edx
- test SC_CPSR, FLAG_THUMB
- je @F
- tb_FlushPipeline 3
- @@:
- arm7_FlushPipeline 3
- ENDIF
- endm
- si5_ALU macro lSym, OPID
- si5&lSym:
- ARM7_ALU_BASE_OUTd2 OPID
- IF (OPID and 1100b) ne 1000b
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax
- ELSEIF (OPID and 1100b) eq 1000b
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care
- ENDIF
- GetRFIV edx, 16, ecx ;; Rn
- GetRFI edx, 12, edx ;; RdIs
- ARM7_ALU_BASE OPID, ecx, eax
- IF (OPID and 1100b) ne 1000b
- ;; Write Back, Check R15.
- mov ZRS (edx), ecx
- cmp edx, 15
- jne @F
- arm7_FlushPipeline 3;; +1S +1N
- @@:
- ENDIF
- ARM7_ExitAddPC 1
- IF (OPID and 1100b) ne 1000b
- si5&lSym&S:
- ;; Save Old CPSR
- mov [SC_ARM7].calc, SC_CPSR
- IF OPID eq AND_OP
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care ;; Rm
- ELSEIF OPID eq EOR_OP
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care ;; Rm
- ELSEIF OPID eq ORR_OP
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care ;; Rm
- ELSEIF OPID eq SUB_OP ;; with C
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax ;; Rm
- ELSEIF OPID eq ADD_OP ;; with C
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax ;; Rm
- ELSEIF OPID eq MOV_OP
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care ;; Rm
- ELSEIF OPID eq MVN_OP
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care ;; Rm
- ELSEIF OPID eq BIC_OP
- ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care ;; Rm
- ELSEIF OPID eq RSB_OP ;; with C
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax ;; Rm
- ELSEIF OPID eq SBC_OP ;; with C
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax ;; Rm
- ELSEIF OPID eq RSC_OP ;; with C
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax ;; Rm
- ELSEIF OPID eq ADC_OP ;; with C
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax ;; Rm
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- ARM7_ALU_SIGN_BASE_OUTd2 OPID
- GetRFIV SC_INVOL, 16, ecx ;; Rn
- GetRFI SC_INVOL, 12, edx ;; RdIs
- ARM7_ALU_SIGN_BASE OPID, ecx, eax
- mov ZRS (edx), ecx
- cmp edx, 15
- je @F
- ARM7_ExitAddPC 1
- @@:
- ;; R15 resume old CPSR.
- mov SC_CPSR, [SC_ARM7].calc
- SPSRToCPSR edx
- test SC_CPSR, FLAG_THUMB
- je @F
- tb_FlushPipeline 3
- @@:
- arm7_FlushPipeline 3
- ENDIF
- endm
- rs_ALU macro lSym, OPID
- LOCAL locSym
- LOCAL locSym_S
- rs&lSym:
- GamePAK_Prefetch 1
- IF (OPID and 1100b) ne 1000b
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare
- ELSEIF (OPID and 1100b) eq 1000b
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care
- ENDIF
- GetRFI SC_INVOL, 16, ecx ;; RnI
- cmp ecx, SZ_PC
- mov ecx, ZRS (ecx)
- jne locSym
- add ecx, 4
- locSym:
- GetRFI SC_INVOL, 12, edx ;; RdIs
- ARM7_ALU_BASE_OUTd2 OPID
- ARM7_ALU_BASE OPID, ecx, eax
- ;; In Rs Shift. Add I (Internal) Clk
- ;; In AGB, I Clk can access GamePAK Cache. (I cycle does not access memory)
- IF (OPID and 1100b) ne 1000b
- ;; Write Back, Check R15.
- mov ZRS (edx), ecx
- cmp edx, 15
- jne @F
- arm7_FlushPipeline 4
- @@:
- ENDIF
- ARM7_ExitAddPC 2
- IF (OPID and 1100b) ne 1000b
- rs&lSym&S:
- GamePAK_Prefetch 1
- mov [SC_ARM7].calc, SC_CPSR
- IF OPID eq AND_OP
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care ;; Rm
- ELSEIF OPID eq EOR_OP
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care ;; Rm
- ELSEIF OPID eq ORR_OP
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care ;; Rm
- ELSEIF OPID eq SUB_OP ;; with C
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare ;; Rm
- ELSEIF OPID eq ADD_OP ;; with C
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare ;; Rm
- ELSEIF OPID eq MOV_OP
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care ;; Rm
- ELSEIF OPID eq MVN_OP
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care ;; Rm
- ELSEIF OPID eq BIC_OP
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care ;; Rm
- ELSEIF OPID eq RSB_OP ;; with C
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare ;; Rm
- ELSEIF OPID eq SBC_OP ;; with C
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare ;; Rm
- ELSEIF OPID eq RSC_OP ;; with C
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare ;; Rm
- ELSEIF OPID eq ADC_OP ;; with C
- ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare ;; Rm
- ELSE
- ;; never reach here, make a simple syntax errors
- ERRORS_ASSERT
- ENDIF
- GetRFI SC_INVOL, 16, ecx ;; RnI
- cmp ecx, SZ_PC
- mov ecx, ZRS (ecx)
- jne locSym_S
- add ecx, 4
- locSym_S:
- GetRFI SC_INVOL, 12, edx ;; RdIs
- ARM7_ALU_SIGN_BASE_OUTd2 OPID
- ARM7_ALU_SIGN_BASE OPID, ecx, eax
- mov ZRS (edx), ecx
- cmp edx, 15
- je @F
- ARM7_ExitAddPC 2
- @@:
- ;; R15 resume old CPSR.
- mov SC_CPSR, [SC_ARM7].calc
- SPSRToCPSR edx
- test SC_CPSR, FLAG_THUMB
- je @F
- tb_FlushPipeline 4
- @@:
- arm7_FlushPipeline 4
- 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_ALU AND, AND_OP
- i8r4_ALU EOR, EOR_OP
- i8r4_ALU SUB, SUB_OP
- i8r4_ALU RSB, RSB_OP
- i8r4_ALU ADD, ADD_OP
- i8r4_ALU ADC, ADC_OP
- i8r4_ALU SBC, SBC_OP
- i8r4_ALU RSC, RSC_OP
- i8r4_ALU TST, TST_OP
- i8r4_ALU TEQ, TEQ_OP
- i8r4_ALU CMP, CMP_OP
- i8r4_ALU CMN, CMN_OP
- i8r4_ALU ORR, ORR_OP
- i8r4_ALU MOV, MOV_OP
- i8r4_ALU BIC, BIC_OP
- i8r4_ALU MVN, MVN_OP
- mUB:
- i8r4UB:
- int 3
- ;; ------------------------- 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_ALU AND, AND_OP
- si5_ALU EOR, EOR_OP
- si5_ALU SUB, SUB_OP
- si5_ALU RSB, RSB_OP
- si5_ALU ADD, ADD_OP
- si5_ALU ADC, ADC_OP
- si5_ALU SBC, SBC_OP
- si5_ALU RSC, RSC_OP
- si5_ALU TST, TST_OP
- si5_ALU TEQ, TEQ_OP
- si5_ALU CMP, CMP_OP
- si5_ALU CMN, CMN_OP
- si5_ALU ORR, ORR_OP
- si5_ALU MOV, MOV_OP
- si5_ALU BIC, BIC_OP
- si5_ALU MVN, MVN_OP
- ;; ------------------------- 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
- rs_ALU AND, AND_OP
- rs_ALU EOR, EOR_OP
- rs_ALU SUB, SUB_OP
- rs_ALU RSB, RSB_OP
- rs_ALU ADD, ADD_OP
- rs_ALU ADC, ADC_OP
- rs_ALU SBC, SBC_OP
- rs_ALU RSC, RSC_OP
- rs_ALU TST, TST_OP
- rs_ALU TEQ, TEQ_OP
- rs_ALU CMP, CMP_OP
- rs_ALU CMN, CMN_OP
- rs_ALU ORR, ORR_OP
- rs_ALU MOV, MOV_OP
- rs_ALU BIC, BIC_OP
- rs_ALU MVN, MVN_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 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
- GetRFIV SC_INVOL, 0, eax
- OUTd "BX R%d:%08X- PC:%08X \n", "SC_INVOL & 15", "eax","ZF-8"
- test eax, 1
- jne @F
- and eax, -4
- mov ZRS (SZ_PC), eax
- arm7_FlushPipeline 3
- @@:
- and eax, -2
- or SC_CPSR, FLAG_THUMB ;; set thumb flag
- and eax, -2
- mov ZRS (SZ_PC), eax
- tb_FlushPipeline 3
- rsUB:
- int 3
- ;; ------------------------- 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
- JMP24: ;; without LR
- and edx, 0FFFFFFh
- bt edx, 23
- sbb ecx, ecx
- and ecx, 03F000000h ;; save 30 bit
- or ecx, edx
- shl ecx, 2 ;; shift 2
- OUTd "B %06X- PC:%08X LR:%08X \n", "ZF+ecx", "ZF-8" , "ZE"
- add ZRS (SZ_PC), ecx
- arm7_FlushPipeline 3
- JMPLR: ;; with LR
- mov SC_INVOL, ZRS (SZ_PC)
- and edx, 0FFFFFFh
- bt edx, 23
- sbb ecx, ecx
- and ecx, 03F000000h ;; save 30 bit
- or ecx, edx
- shl ecx, 2 ;; shift 2
- OUTd "BL %06X- PC:%08X LR:%08X ", "ZF+ecx", "ZF-8" , "ZE"
- add ZRS (SZ_PC), ecx
- lea eax, [SC_INVOL-4]
- OUTd "NEW-LR:%08X \n", "eax"
- mov ZRS (SZ_LRLINK), eax ;; next pc save to LR.
- arm7_FlushPipeline 3
- 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
- pre&link:
- IF ldrtype eq LDR_STD_IMM12 or (ldrtype eq LDR_STD_SCALED)
- IF (link and LDR_L) eq 0
- OUTd "STR"
- ELSEIF (link and LDR_L) ne 0
- OUTd "LDR"
- ENDIF
- IF (link and LDR_B) ne 0
- OUTd "B"
- ENDIF
- IF ((link and LDR_W) ne 0) and ((link and LDR_P) eq 0)
- OUTd "T"
- ENDIF
- ELSEIF ldrtype eq LDR_EXT_LOHI8BIT or (ldrtype eq LDR_EXT_RNMD)
- IF (link and 5) eq 4
- OUTd "STRH"
- ELSEIF (link and 5) ne 4
- OUTd "LDR"
- IF (link and 5) eq 0
- OUTd "H"
- ELSEIF (link and 5) eq 1
- OUTd "SB"
- ELSEIF (link and 5) eq 5
- OUTd "SH"
- ELSE
- ERRORS_ASSERT
- ENDIF
- ELSE
- ERRORS_ASSERT
- ENDIF
- ELSE
- ERRORS_ASSERT
- ENDIF
- IF (link and LDR_P) ne 0
- OUTd " R%d, [R%d, ", "SC_INVOL } 12 & 15", "SC_INVOL } 16 & 15"
- ELSEIF (link and LDR_P) eq 0
- OUTd " R%d, [R%d], ", "SC_INVOL } 12 & 15", "SC_INVOL } 16 & 15"
- ENDIF
- IF (link and LDR_U) eq 0
- OUTd "-"
- ENDIF
- ;; 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_INVOL
- and eax, 0FFFh ;; GetImm12
- OUTd "#%03X", "eax"
- ELSEIF ldrtype eq LDR_STD_SCALED
- OUTd "R%d, ", "SC_INVOL & 15"
- ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, edx ;; Rm Sft.
- ELSEIF ldrtype eq LDR_EXT_LOHI8BIT
- mov eax, SC_INVOL
- shl al, 4
- shr eax, 4
- and eax, 255 ;; LO|HI
- OUTd "#%02X", "eax"
- ELSEIF ldrtype eq LDR_EXT_RNMD
- GetRFIV SC_INVOL, 0, eax ;; GetRm
- OUTd "R%d", "SC_INVOL & 15"
- ELSE
- ERRORS_ASSERT
- ENDIF
- IF (link and LDR_P) ne 0
- OUTd "]"
- IF (link and LDR_W) ne 0
- OUTd "!"
- ENDIF
- ENDIF
- GetRFI SC_INVOL, 16, ecx ;; GetRn
- GetRFI SC_INVOL, 12, SC_INVOL ;; GetRd
- IF (link and LDR_U) eq 0
- neg eax
- ENDIF
- ;; Post-Index??
- IF (link and LDR_P) eq 0
- mov edx, ZRS (ecx)
- add eax, edx
- ELSEIF (link and LDR_P) ne 0
- mov edx, eax
- add edx, ZRS (ecx)
- mov eax, edx
- ENDIF
- IF (((link and LDR_P) eq 0) or ((link and LDR_W) ne 0))
- mov ZRS (ecx), eax
- ENDIF
- ;; 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 ZRS (SC_INVOL)
- push edx
- push [SC_ARM7].agb
- IF (link and LDR_B) ne 0
- CALLIt MmuWriteByteNoSeq
- ELSEIF (link and LDR_B) eq 0
- ;; Is R15?? + PCSTOREOFFSET - 8
- cmp SC_INVOL, 15
- jne @F
- add PTR32[esp+8], 4
- @@:
- CALLIt MmuWriteWordNoSeq
- ENDIF
- mov [SC_ARM7].nextNoSeqFetch, 1
- Add_WaitStateClks
- ARM7_ExitAddPC 2 ;; 2 noSEQ clks.
- ELSEIF (link and LDR_L) ne 0
- ;; LDR. LDRB
- GamePAK_Prefetch 1
- push edx
- push [SC_ARM7].agb
- IF (link and LDR_B) ne 0
- CALLIt MmuReadByteNoSeq
- movzx eax, al
- ELSEIF (link and LDR_B) eq 0
- mov [SC_ARM7].calc, edx
- CALLIt MmuReadWordNoSeq
- mov ecx, [SC_ARM7].calc
- and ecx, 3
- shl ecx, 3
- ror eax, cl
- ENDIF
- Add_WaitStateClks
- mov ZRS (SC_INVOL), eax
- cmp SC_INVOL, 15
- je @F
- ARM7_ExitAddPC 3 ;; S+N+1 3Clks.
- @@:
- and ZRS (SC_INVOL), -4
- arm7_FlushPipeline 5
- ENDIF
- ELSEIF ldrtype eq LDR_EXT_LOHI8BIT or (ldrtype eq LDR_EXT_RNMD)
- IF (link and 5) eq 4
- push ZRS (SC_INVOL)
- push edx
- CallMemOrIOAddWaitState MmuWriteHalfWordNoSeq
- mov [SC_ARM7].nextNoSeqFetch, 1
- ARM7_ExitAddPC 2 ;; 2 noSEQ clks.
- ELSEIF (link and 5) ne 4
- push edx
- push [SC_ARM7].agb
- GamePAK_Prefetch 1
- IF (link and 5) eq 0
- mov [SC_ARM7].calc, edx
- CALLIt MmuReadHalfWordNoSeq
- mov ecx, [SC_ARM7].calc
- and eax, 0FFFFh
- and ecx, 1
- shl ecx, 3
- ror eax, cl
- ELSEIF (link and 5) eq 1
- CALLIt MmuReadByteNoSeq
- movsx eax, al
- ELSEIF (link and 5) eq 5
- mov [SC_ARM7].calc, edx
- CALLIt MmuReadHalfWordNoSeq
- mov ecx, [SC_ARM7].calc
- mov edx, eax
- movsx eax, ax
- and ecx, 1
- je @F
- movsx eax, dh
- @@:
- ELSE
- ERRORS_ASSERT
- ENDIF
- Add_WaitStateClks
- mov ZRS (SC_INVOL), eax
- cmp SC_INVOL, 15
- je @F
- ARM7_ExitAddPC 3 ;; S+N+1 3Clks.
- @@:
- and ZRS (SC_INVOL), -4
- arm7_FlushPipeline 5
- ENDIF
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- SWINT: ;; ARM7 Software Interrupt
- OUTd "SWI-ARM7 FUNC:%02X R0 %08X R1 %08X R2 %08X\n", "SC_INVOL & 0FFFFFFh", "Z0", "Z1", "Z2"
- mov eax, ZRS (SZ_PC)
- 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+4], edx
- ;; Adjust PC Pointer to IRQ Interrupt vector address
- mov ZRS (SZ_PC), ARM7_VECTOR_SOFTWARE
- mov SC_INVOL, SC_CPSR
- and SC_INVOL, ARM7_MODE_GET_MASK
- cmp SC_INVOL, ARM7_MODE_MGR_MASK
- je @NestSwi_ARM7
- ;; switch Mode
- SwitchMode ecx, 0
- ;; Prefetch Opcode pipeline
- arm7_FlushPipeline 3
- @NestSwi_ARM7:
- mov ZRS (SZ_LRLINK), edx
- mov [SC_ARM7].SPSR_T[SPSRb_MGR], SC_CPSR
- mov eax, ZRS (SZ_STACK)
- mov [SC_ARM7].R1314_T[R1314b_MGR], eax
- mov eax, ZRS (SZ_LRLINK)
- mov [SC_ARM7].R1314_T[R1314b_MGR+4], eax
- mov SC_CPSR, ecx
- ;; Prefetch Opcode pipeline
- arm7_FlushPipeline 3
- ;; PSR MASK In V4T Version , UseMask 0xF0000000, PrivMask 0x0000000F, State Mask 0x00000020
- ;; This means that in any case you can't control the interrupt shielding bit field through MSR.
- ;; That sounds really incredible!
- ;; Many books and software examples show that it can be controlled by MSR.
- ;; I really don't know who to trust.
- ;; See ARM Architecture Reference Manual::A4.1.39 MSR
- IFDEF STRICT_MODE_PSR
- ARM7_PSR_CTL_MASK equ ARM7_PSR_MODE4BIT_MASK
- ELSE
- ARM7_PSR_CTL_MASK equ ARM7_PSR_MODE8BIT_MASK
- ENDIF
- i8r4ToCPSR:
- Imm8BitmapSft_AC SC_INVOL, eax
- OUTd "MSR #%08X(org)", "eax"
- jmp @F
- si5ToCPSR: ;; 0 1 MSR Rs CPSR TODO:Check d4-d7 := 0
- OUTd "MSR R%d to cpsr_", "SC_INVOL & 15"
- GetRFIV edx, 0, eax
- @@:
- ToFastPSR eax, eax, eax, ecx
- ;; Limit MASK, in fact write will only affect flag and cpu mode's low 4bit in std arm7.
- OUTd " #%08X(fast) to spsr_", "eax"
- mov [SC_ARM7].calc, SC_CPSR ;;;; FIXME:
- mov ecx, SC_CPSR
- and ecx, ARM7_MODE_GET_MASK
- cmp ecx, ARM7_MODE_USER_MASK
- jne @Privilege_MSR
- ;; USER Mode MSR.
- ;; Only Affect Flag Bit.
- @ChkSetFLags:
- test edx, FLAG_MSR_FLAGS
- je @F
- and SC_CPSR, not ARM7_PSR_FLAG_MASK
- and eax, ARM7_PSR_FLAG_MASK
- or SC_CPSR, eax
- @@:
- test SC_CPSR, FLAG_THUMB
- je @F
- int 3
- @@:
- ARM7_ExitAddPC 1
- @Privilege_MSR:
- test edx, FLAG_MSR_CTL
- je @ChkSetFLags
- IF 1
- ;; PriMode MSR.
- test edx, FLAG_MSR_FLAGS
- jne @F
- mov edx, SC_CPSR
- and edx, not ARM7_PSR_CTL_MASK
- and eax, ARM7_PSR_CTL_MASK
- or eax, edx
- or eax, ARM7_MODE_MSB_BIT_MASK
- SwitchMode eax, 1
- test SC_CPSR, FLAG_THUMB
- je @Skip
- int 3
- @Skip:
- ARM7_ExitAddPC 1
- @@:
- mov SC_INVOL, eax
- mov edx, SC_CPSR
- and edx, not ARM7_PSR_CTL_MASK
- and eax, ARM7_PSR_CTL_MASK
- or eax, edx
- or eax, ARM7_MODE_MSB_BIT_MASK
- SwitchMode eax, 1
- and SC_CPSR, not ARM7_PSR_FLAG_MASK
- and SC_INVOL, ARM7_PSR_FLAG_MASK
- or SC_CPSR, SC_INVOL
- test SC_CPSR, FLAG_THUMB
- je @F
- int 3
- @@:
- ARM7_ExitAddPC 1
- ELSE
- ENDIF
- ;; TODO: assert mode, flags
- si5PSR4: ;; 1 1 MSR Rs SPSR
- OUTd "MSR R%d to spsr_", "SC_INVOL & 15"
- GetRFIV edx, 0, eax
- ToFastPSR eax, eax, eax, ecx
- jmp toSPSR_main
- i8r4ToSPSR:
- Imm8BitmapSft_AC SC_INVOL, eax
- OUTd "MSR #%08X(org)", "eax"
- ToFastPSR eax, eax, eax, ecx
- OUTd " #%08X(fast) to spsr_", "eax"
- toSPSR_main:
- GetCurSPSRP ecx
- test edx, FLAG_MSR_FLAGS
- je @F
- mov SC_INVOL, eax
- and PTR32[ecx], not ARM7_PSR_FLAG_MASK
- and SC_INVOL, ARM7_PSR_FLAG_MASK
- or [ecx], SC_INVOL
- OUTd "f"
- @@:
- test edx, FLAG_MSR_CTL
- je @F
- OUTd "c"
- and PTR32[ecx], not (ARM7_PSR_CTL_MASK or ARM7_PSR_STATE_MASK)
- and eax, (ARM7_PSR_CTL_MASK or ARM7_PSR_STATE_MASK)
- or [ecx], eax
- or PTR32[ecx], ARM7_MODE_MSB_BIT_MASK
- @@:
- ARM7_ExitAddPC 1
- si5PSR1: ;; 0 0 MRS Rs CPSR
- OUTd "MRS R%d, CPSR", "SC_INVOL}12 & 15"
- ToStandPSR SC_CPSR, ecx, eax, ecx
- jmp @F
- si5PSR3: ;; 1 0 MRS Rs SPSR, TODO: Check SBO/SBZ
- OUTd "MRS R%d, SPSR", "SC_INVOL}12 & 15"
- GetCurSPSRP eax
- mov eax, [eax]
- ToStandPSR eax, ecx, eax, ecx
- @@:
- GetRFI edx, 12, eax
- and ecx, 00F00000FFh
- or ecx, 010h
- mov ZRS (eax), ecx
- ARM7_ExitAddPC 1
- ;; XXX: This macro branch is actually terrible to write.
- REGS_SET_OP macro link
- LOCAL stdPush
- LOCAL fiqPush
- LOCAL usrPush
- LOCAL usrPushFiq
- LOCAL usrPushFiq_R8_12
- LOCAL usrPushFiq_R13_14
- LOCAL usrPushFiq_next
- LOCAL usrPushFiq_next2
- LOCAL stdPush_Q
- LOCAL usrPush_Q
- LOCAL stdPush_Q2
- LOCAL usrPush_Q2
- LOCAL outPush
- LOCAL stdPop
- LOCAL fiqPop
- LOCAL usrPop
- LOCAL usrPopFiq
- LOCAL usrPopFiq_R8_12
- LOCAL usrPopFiq_R13_14
- LOCAL usrPopFiq_next
- LOCAL usrPopFiq_next2
- LOCAL usrPopFiqFirst
- LOCAL stdPop_Q
- LOCAL usrPop_Q
- LOCAL stdPop_Q2
- LOCAL stdPop_HitR15
- LOCAL usrPop_Q2
- LOCAL outPop
- LOCAL stdPushFirst
- LOCAL usrPushFirst
- LOCAL usrPushFiqFirst
- LOCAL stdPopFirst
- LOCAL usrPopFirst
- LOCAL usrPopFiqFirst
- LOCAL LDM_empty
- LOCAL STM_empty
- z&link:
- ;; have to use variables.
- LDM_STACK_REQUIRE equ 128
- RSO_L equ 1
- RSO_W equ 2
- RSO_S equ 4
- RSO_U equ 8
- RSO_P equ 16
- RnAddress equ 16
- RnIndex equ 20
- RnCount equ 28
- Reglist equ 32
- RnWriteBack equ 36
- RnAdjust equ 40
- RnFirst equ 44
- RnTemp equ 52
- RnTempi equ 56
- IF (link and RSO_L) eq 0
- OUTd "STM"
- ELSEIF (link and RSO_L) ne 0
- OUTd "LDM"
- GamePAK_Prefetch 1 ;; I cycle before fetch new opcode.
- ENDIF
- IF (link and RSO_U) eq 0
- OUTd "D"
- ELSEIF (link and RSO_U) ne 0
- OUTd "I"
- ENDIF
- IF (link and RSO_P) eq 0
- OUTd "A"
- ELSEIF (link and RSO_P) ne 0
- OUTd "B"
- ENDIF
- OUTd " R%d", "SC_INVOL } 16 & 15"
- IF (link and RSO_W) ne 0
- OUTd "!"
- ENDIF
- OUTd ", "
- OUTd "[ R15-R12:%01X, R11-R8:%01X ", "SC_INVOL } 12 & 15", "SC_INVOL } 8 & 15"
- OUTd " R7-R4:%01X, R3-R0:%01X ]", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
- IF (link and RSO_S) ne 0
- OUTd "^"
- ENDIF
- sub esp, LDM_STACK_REQUIRE
- xor eax, eax
- mov STA (RnAddress), eax
- mov STA (RnIndex), eax
- mov STA (RnAdjust), eax
- mov STA (RnFirst), eax
- mov STA (RnCount), eax
- GetRFI SC_INVOL, 16, eax ;;Rn.
- mov ecx, SC_INVOL
- mov edx, ZRS (eax) ;;GetRn
- and ecx, 0FFFFh
- mov STA (RnIndex), eax
- mov STA (RnAddress), edx
- IF (link and RSO_U) ne 0
- mov SC_INVOL, 4
- ELSEIF (link and RSO_U) eq 0
- mov SC_INVOL, -4
- ENDIF
- mov STA (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, STA (RnAddress)
- 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 STA (RnAddress), eax
- ENDIF
- mov STA (RnWriteBack), edx
- IF (link and RSO_P) ne 0
- add STA (RnAddress), SC_INVOL
- ENDIF
- mov SC_INVOL, STA (RnAddress)
- ;; STM-------------------------------------------------------
- ;; STM-------------------------------------------------------
- ;; STM-------------------------------------------------------
- IF (link and RSO_L) eq 0
- test STA (Reglist), 0FFFFh
- je STM_empty
- IF (link and RSO_W) ne 0
- ;; Check Rn's adjust
- mov ecx, STA (RnIndex)
- bt STA (Reglist), ecx
- jnc @F
- sbb edx, edx
- ;; Check is First Vailed bit
- mov eax, edx
- shl eax, cl
- xor eax, edx
- test STA (Reglist), eax
- je @F ;; TODO: error.
- ;; Dirty register, write directly
- mov eax, STA (RnIndex)
- mov ecx, STA (RnWriteBack)
- mov ZRS (eax), ecx
- @@:
- ENDIF
- 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 stdPush
- cmp eax, ARM7_MODE_USER_MASK
- je stdPush
- cmp eax, ARM7_MODE_FIQ_MASK
- je usrPushFiq
- jmp usrPush
- ELSEIF (link and RSO_S) eq 0
- jmp stdPush
- ENDIF
- ;; STM empty -------------------------------------------------------
- STM_empty:
- mov edx, STA (RnIndex)
- push STACK_PUSH_STATUS_PUSH
- push SZ_PC
- mov eax, ZRS (SZ_PC)
- add eax, 4
- push eax
- push ZRS (edx)
- IF (link and RSO_W) ne 0
- IF (link and RSO_U) ne 0
- add ZRS (edx), 64
- ELSE
- sub ZRS (edx), 64
- ENDIF
- ENDIF
- and ZRS (edx), -4
- CallMemOrIOAddWaitState StackWriteNoSeq
- add esp, LDM_STACK_REQUIRE
- mov [SC_ARM7].nextNoSeqFetch, 1
- ARM7_ExitAddPC 2
- ;; STM User Mode -------------------------------------------------------
- usrPush:
- shr STA (Reglist), 1
- jnc @F
- inc SC_WAIT ;; + 1 S or N cycle
- mov eax, STA (RnCount)
- mov ecx, ZRS (eax)
- add eax, 1
- and eax, 15
- push STACK_PUSH_STATUS_PUSH
- push eax
- cmp eax, 14
- jb usrPush_Q
- sub eax, 14
- mov ecx, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
- usrPush_Q:
- test eax, eax
- jne usrPush_Q2
- add ecx, 4
- usrPush_Q2:
- push ecx
- mov eax, SC_INVOL
- add SC_INVOL, 4
- ;;and eax, -4
- push eax
- cmp STA (RnFirst+16), 0
- mov STA (RnFirst+16), 1
- je usrPushFirst
- CallMemOrIOAddWaitState StackWriteSeq
- jmp @F
- usrPushFirst:
- CallMemOrIOAddWaitState StackWriteNoSeq
- @@:
- add STA (RnCount), 1
- cmp STA (RnCount), 16
- jb usrPush
- jmp outPush
- ;; STM User Mode FIQ ----------------Will this happen to GBA?---------------------------------------
- usrPushFiq:
- shr STA (Reglist), 1
- jnc @F
- inc SC_WAIT ;; + 1 S or N cycle
- mov eax, STA (RnCount)
- mov ecx, ZRS (eax)
- add eax, 1
- and eax, 15
- push STACK_PUSH_STATUS_PUSH
- push eax
- cmp eax, 9
- jb usrPushFiq_next
- cmp eax, 14
- jb usrPushFiq_R8_12
- usrPushFiq_R8_12:
- sub eax, 9
- mov ecx, [SC_ARM7].R812_T[R812b_EXCEPT_FIQ+ eax*4]
- jmp usrPushFiq_next2
- usrPushFiq_R13_14:
- sub eax, 14
- mov ecx, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
- jmp usrPushFiq_next2
- usrPushFiq_next:
- test eax, eax
- jne usrPushFiq_next2
- add ecx, 4
- usrPushFiq_next2:
- push ecx
- mov eax, SC_INVOL
- add SC_INVOL, 4
- ;;and eax, -4
- push eax
- cmp STA (RnFirst+16), 0
- mov STA (RnFirst+16), 1
- je usrPushFiqFirst
- CallMemOrIOAddWaitState StackWriteSeq
- jmp @F
- usrPushFiqFirst:
- CallMemOrIOAddWaitState StackWriteNoSeq
- @@:
- add STA (RnCount), 1
- cmp STA (RnCount), 16
- jb usrPushFiq
- jmp outPush
- ;; STM Std Mode --------------------------------------------------------
- stdPush:
- shr STA (Reglist), 1
- jnc @F
- inc SC_WAIT ;; + 1 S or N cycle
- mov eax, STA (RnCount)
- push STACK_PUSH_STATUS_PUSH
- push eax
- push ZRS (eax)
- cmp eax, 15
- jne stdPush_Q2
- add PTR32[esp], 4
- stdPush_Q2:
- mov eax, SC_INVOL
- ;;and eax, -4
- push eax
- add SC_INVOL, 4
- cmp STA (RnFirst+16), 0
- mov STA (RnFirst+16), 1
- je stdPushFirst
- CallMemOrIOAddWaitState StackWriteSeq
- jmp @F
- stdPushFirst:
- CallMemOrIOAddWaitState StackWriteNoSeq
- @@:
- add STA (RnCount), 1
- cmp STA (RnCount), 16
- jb stdPush
- outPush:
- IF (link and RSO_W) ne 0
- mov eax, STA (RnIndex)
- mov ecx, STA (RnWriteBack)
- mov ZRS (eax), ecx ;; TODO: RnCheck with Reglist
- ENDIF
- mov [SC_ARM7].nextNoSeqFetch, 1
- add esp, LDM_STACK_REQUIRE
- ARM7_ExitAddPC 1
- ELSEIF (link and RSO_L) ne 0
- ;; LDM ----------------------------------------------------------------------
- ;; LDM ----------------------------------------------------------------------
- ;; LDM ----------------------------------------------------------------------
- test STA (Reglist), 0FFFFh
- je LDM_empty
- ;; Check Rn's adjust
- mov ecx, STA (RnIndex)
- bt STA (Reglist), ecx
- jnc @F
- mov STA (RnAdjust), 1
- @@:
- IF (link and RSO_S) ne 0
- test STA (Reglist), 08000h
- jne stdPop
- mov eax, SC_CPSR
- and eax, ARM7_MODE_GET_MASK
- cmp eax, ARM7_MODE_SYS_MASK
- je stdPop
- cmp eax, ARM7_MODE_USER_MASK
- je stdPop
- cmp eax, ARM7_MODE_FIQ_MASK
- je usrPopFiq
- jmp usrPop
- ELSEIF (link and RSO_S) eq 0
- jmp stdPop
- ENDIF
- ;; LDM reglist empty -------------------------------------------------------
- LDM_empty:
- mov ecx, STA (RnIndex)
- push ZRS(ecx)
- IF (link and RSO_W) ne 0
- IF (link and RSO_U) ne 0
- add ZRS(ecx), 64
- ELSE
- sub ZRS(ecx), 64
- ENDIF
- ENDIF
- and ZRS(ecx), -4
- CallMemOrIOAddWaitState StackReadNoSeq
- mov ZRS (SZ_PC), eax
- add esp, LDM_STACK_REQUIRE
- arm7_FlushPipeline 3
- ;; LDM User Mode -------------------------------------------------------
- usrPop:
- shr STA (Reglist), 1
- jnc @F
- inc SC_WAIT ;; + 1 S or N cycle
- mov eax, STA (RnCount)
- lea SC_INVOL, ZRS (eax)
- add eax, 1
- and eax, 15
- cmp eax, 14
- jb @F
- sub eax, 14
- lea SC_INVOL, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
- @@:
- mov eax, STA (RnAddress)
- add STA (RnAddress), 4
- ;;and eax, -4
- push eax
- cmp STA (RnFirst+4), 0
- mov STA (RnFirst+4), 1
- je usrPopFirst
- CallMemOrIOAddWaitState StackReadSeq
- mov [SC_INVOL], eax
- jmp @F
- usrPopFirst:
- CallMemOrIOAddWaitState StackReadNoSeq
- mov [SC_INVOL], eax
- @@:
- add STA (RnCount), 1
- cmp STA (RnCount), 16
- jb usrPop
- jmp outPop
- ;; LDM FIQ Mode ----------------Will this happen to GBA?---------------------------------------
- usrPopFiq:
- shr STA (Reglist), 1
- jnc @F
- inc SC_WAIT ;; + 1 S or N cycle
- mov eax, STA (RnCount)
- lea SC_INVOL, ZRS (eax)
- add eax, 1
- and eax, 15
- cmp eax, 14
- jb usrPopFiq_next
- sub eax, 14
- lea SC_INVOL, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
- jmp usrPopFiq_next2
- usrPopFiq_next:
- cmp eax, 9
- jb usrPopFiq_next2
- sub eax, 9
- lea SC_INVOL, [SC_ARM7].R812_T[R812b_EXCEPT_FIQ+ eax*4]
- usrPopFiq_next2:
- mov eax, STA (RnAddress)
- add STA (RnAddress), 4
- ;;and eax, -4
- push eax
- cmp STA (RnFirst+4), 0
- mov STA (RnFirst+4), 1
- je usrPopFiqFirst
- CallMemOrIOAddWaitState StackReadSeq
- mov [SC_INVOL], eax
- jmp @F
- usrPopFiqFirst:
- CallMemOrIOAddWaitState StackReadNoSeq
- mov [SC_INVOL], eax
- @@:
- add STA (RnCount), 1
- cmp STA (RnCount), 16
- jb usrPopFiq
- jmp outPop
- ;; LDM Std Mode --------------------------------------------------------
- stdPop:
- shr STA (Reglist), 1
- jnc @F
- inc SC_WAIT ;; + 1 S or N cycle
- mov eax, STA (RnCount)
- lea SC_INVOL, ZRS (eax)
- mov eax, STA (RnAddress)
- add STA (RnAddress), 4
- ;;and eax, -4
- push eax
- cmp STA (RnFirst+4), 0
- mov STA (RnFirst+4), 1
- je stdPopFirst
- CallMemOrIOAddWaitState StackReadSeq
- mov [SC_INVOL], eax
- ;; Check is finial??
- cmp STA (RnCount), 15
- jne @F
- jmp stdPop_HitR15
- stdPopFirst:
- CallMemOrIOAddWaitState StackReadNoSeq
- mov [SC_INVOL], eax
- ;; Check is finial??
- cmp STA (RnCount), 15
- jne @F
- stdPop_HitR15:
- IF (link and RSO_W) ne 0
- cmp STA (RnAdjust), 1
- je stdPop_Q
- mov eax, STA (RnIndex)
- mov ecx, STA (RnWriteBack)
- mov ZRS (eax), ecx
- stdPop_Q:
- ENDIF
- IF (link and RSO_S) ne 0
- SPSRToCPSR eax
- ENDIF
- add esp, LDM_STACK_REQUIRE
- test SC_CPSR, FLAG_THUMB
- jne stdPop_Q2
- arm7_FlushPipeline 4
- stdPop_Q2:
- tb_FlushPipeline 4
- @@:
- add STA (RnCount), 1
- cmp STA (RnCount), 16
- jb stdPop
- outPop:
- IF (link and RSO_W) ne 0
- cmp STA (RnAdjust), 1
- je @F
- mov eax, STA (RnIndex)
- mov ecx, STA (RnWriteBack)
- mov ZRS (eax), ecx
- @@:
- ENDIF
- add esp, LDM_STACK_REQUIRE
- ARM7_ExitAddPC 2
- ENDIF
- endm
- ;; TODO: one unit for LDM/STM
- ;; TODO: other Bank Rn!^ ?
- ;; TODO: empty load/ store
- A7SWP: ;; SWAP. S+2N+I
- GetRFIV SC_INVOL, 16, eax ;; Rn:= Address
- GetRFIV SC_INVOL, 0, ecx ;; Rm:
- mov [SC_ARM7].calc, eax
- push ecx
- push eax
- push [SC_ARM7].agb
- push eax
- push [SC_ARM7].agb
- test SC_INVOL, 00400000h
- je @F
- A7SWP_INLINE macro rd, wr, msk
- CALLIt rd
- add SC_WAIT, [SC_ARM7].waitState
- GetRFI SC_INVOL, 12, SC_INVOL ;; Rd:= Rd.
- and eax, msk
- if msk eq 0FFFFFFFFh
- ;; test align rot.
- mov ecx, [SC_ARM7].calc
- and ecx, 3
- shl ecx, 3
- ror eax, cl
- endif
- mov ZRS (SC_INVOL), eax
- CALLIt wr
- add SC_WAIT, [SC_ARM7].waitState
- GamePAK_Prefetch 1
- ARM7_ExitAddPC 4
- endm
- OUTd "SWPB R%d, R%d, [R%d]", "SC_INVOL}12 & 15", "SC_INVOL & 15", "SC_INVOL}16 & 15"
- A7SWP_INLINE MmuReadByteNoSeq, MmuWriteByteNoSeq, 0FFh
- @@:
- OUTd "SWP R%d, R%d, [R%d]", "SC_INVOL}12 & 15", "SC_INVOL & 15", "SC_INVOL}16 & 15"
- A7SWP_INLINE MmuReadWordNoSeq, MmuWriteWordNoSeq, 0FFFFFFFFh
- MUL_OP equ 0
- MLA_OP equ 1
- UMUL64_OP equ 2
- UMLA64_OP equ 3
- SMUL64_OP equ 4
- SMLA64_OP equ 5
- mulClks macro Post, TReg, Recv ;; XXX: TReg ^ Post ^ Recv
- ;; XXX: better case
- ;; 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 (Rs) are all zero or one, else
- ;; 2 if bits [31:16] of the multiplier operand (Rs) are all zero or one, else
- ;; 3 if bits [31:24] of the multiplier operand (Rs) are all zero or all one, else
- ;; 4.
- bt Post, 31
- sbb TReg, TReg
- xor TReg, Post
- movd xmm0, TReg
- pxor xmm1, xmm1
- pcmpeqb xmm1, xmm0
- pmovmskb TReg, xmm1
- shl TReg, 29
- sbb Recv, Recv
- shl TReg, 1
- sbb Post, Post
- shl TReg, 1
- sbb TReg, TReg
- and Post, Recv
- and TReg, Post
- add Recv, TReg
- lea Recv, [Recv+Post+4]
- endm
- mul_interp_b macro OPID
- GetRFIV SC_INVOL, 0, eax ;; Rm.
- GetRFIV SC_INVOL, 8, ecx ;; Rs.
- IF OPID eq MUL_OP
- OUTd "MUL R%d, R%d, R%d", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15"
- mul ecx
- GetRFI SC_INVOL, 16, edx ;; Rd
- mov ZRS (edx), eax
- ELSEIF OPID eq MLA_OP
- OUTd "MLA R%d, R%d, R%d, R%d", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15", "SC_INVOL}12 & 15"
- mul ecx
- GetRFIV SC_INVOL, 12, edx ;; Rn
- add eax, edx
- GetRFI SC_INVOL, 16, edx ;; Rd
- mov ZRS (edx), eax
- ELSEIF OPID eq UMUL64_OP
- OUTd "UMULL R%d, R%d, R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15"
- movd xmm0, ecx
- mul ecx
- GetRFI SC_INVOL, 12, ecx ;; RdLO
- GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI
- mov ZRS (ecx), eax
- mov ZRS (SC_INVOL), edx
- movd ecx, xmm0
- ELSEIF OPID eq UMLA64_OP
- OUTd "UMLAL R%d, R%d, R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15"
- movd xmm0, ecx
- mul ecx
- GetRFI SC_INVOL, 12, ecx ;; RdLO
- GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI
- add eax, ZRS (ecx)
- adc edx, ZRS (SC_INVOL)
- mov ZRS (ecx), eax
- mov ZRS (SC_INVOL), edx
- movd ecx, xmm0
- ELSEIF OPID eq SMUL64_OP
- OUTd "SMULL R%d, R%d, R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15"
- movd xmm0, ecx
- imul ecx
- GetRFI SC_INVOL, 12, ecx ;; RdLO
- GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI
- mov ZRS (ecx), eax
- mov ZRS (SC_INVOL), edx
- movd ecx, xmm0
- ELSEIF OPID eq SMLA64_OP
- OUTd "SMLAL R%d, R%d, R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15"
- movd xmm0, ecx
- imul ecx
- GetRFI SC_INVOL, 12, ecx ;; RdLO
- GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI
- add eax, ZRS (ecx)
- adc edx, ZRS (SC_INVOL)
- mov ZRS (ecx), eax
- mov ZRS (SC_INVOL), edx
- movd ecx, xmm0
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- mul_interp macro lSym, OPID
- ;;LOCAL StdLink
- ;;LOCAL StdLinkWithSymbol
- LOCAL SetMClks
- m&lSym:
- OUTd "NOSET_SIGN "
- mul_interp_b OPID
- jmp SetMClks
- m&lSym&S:
- OUTd "SET_SIGN "
- mul_interp_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:
- mulClks ecx, edx, eax
- IF OPID eq MUL_OP
- ;; MUL := M I Clks.
- ELSEIF OPID eq MLA_OP
- ;; MLA := M+1 I Clks
- add eax, 1
- ELSEIF OPID eq UMUL64_OP
- ;; UMULL := M+1 I Clks
- add eax, 1
- ELSEIF OPID eq UMLA64_OP
- ;; UMLAL := M+2 I Clks
- add eax, 2
- ELSEIF OPID eq SMUL64_OP
- ;; SMULL := M+1 I Clks
- add eax, 1
- ELSEIF OPID eq SMLA64_OP
- ;; SMLAL := M+2 I Clks
- add eax, 2
- ELSE
- ERRORS_ASSERT
- ENDIF
- add SC_WAIT, eax
- GamePAK_Prefetch eax
- ARM7_ExitAddPC 1
- endm
- @ALIGN_Z
- mul_interp MUL, MUL_OP
- mul_interp MLA, MLA_OP
- mul_interp UMUL64, UMUL64_OP
- mul_interp UMLA64, UMLA64_OP
- mul_interp SMUL64, SMUL64_OP
- mul_interp SMLA64, SMLA64_OP
- 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
- IRL_PUSH
- int 3
- COPMO:
- COPDT:
- UDEFI: ;; undef opcode abnormal
- int 3
- ;; Thumb Instruction Entry -----------------------------------------------------------------------------------
- ALUOP:
- SRC_cx equ ecx
- DST_i equ edx
- DST equ ZRS (DST_i)
- TMPR equ eax
- TMPR8 equ al
- ;; ALU Unwind ------------------------
- GetRFI_T SC_INVOL, 0, DST_i ;;Rd's Index .
- GetRFIV_T SC_INVOL, 3, SRC_cx ;;Rs/Rm/Rn
- mov TMPR, SC_INVOL
- shr TMPR, 6
- and TMPR, 15
- jmp taTAB[TMPR*4]
- taAND:
- OUTd "AND R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- and DST, SRC_cx
- SetNZ_A
- tb_ExitAddPC 1
- taEOR:
- OUTd "EOR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- xor DST, SRC_cx
- SetNZ_A
- tb_ExitAddPC 1
- taORR:
- OUTd "ORR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- or DST, SRC_cx
- SetNZ_A
- tb_ExitAddPC 1
- taADC:
- OUTd "ADC R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- adc DST, SRC_cx
- SetNZCV_A 0
- tb_ExitAddPC 1
- taSBC:
- OUTd "SBC R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- xor SC_CPSR, FLAG_C
- bt SC_CPSR, FLAG_CHECK_C_X86_BT
- sbb DST, SRC_cx
- SetNZCV_A 1
- tb_ExitAddPC 1
- taCMP:
- OUTd "CMP R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- cmp DST, SRC_cx
- SetNZCV_A 1
- tb_ExitAddPC 1
- taCMN:
- OUTd "CMN R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- add SRC_cx, DST
- SetNZCV_A 0
- tb_ExitAddPC 1
- taTST:
- OUTd "TST R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- test DST, SRC_cx
- SetNZ_A
- tb_ExitAddPC 1
- taNEG:
- mov DST, 0
- sub DST, SRC_cx
- SetNZCV_A 1
- tb_ExitAddPC 1
- taBIC:
- OUTd "BIC R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- not SRC_cx
- and DST, SRC_cx
- SetNZ_A
- tb_ExitAddPC 1
- taMVN:
- OUTd "MVN R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- xor SRC_cx, -1
- mov DST, SRC_cx
- SetNZ_A
- tb_ExitAddPC 1
- taMUL:
- OUTd "MUL R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- movd xmm0, SRC_cx
- movd xmm1, DST
- pmuludq xmm0, xmm1
- movd TMPR, xmm0
- mov DST, TMPR
- or TMPR, TMPR
- SetNZ_A
- mulClks SRC_cx, DST_i, TMPR ;; @FIXME
- lea SC_INVOL, [TMPR+1]
- GamePAK_Prefetch TMPR
- tb_ExitAddPC SC_INVOL
- taLSL:
- OUTd "LSL R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- and SRC_cx, 255
- jne @F
- ;; ZERO.
- mov TMPR, DST
- or TMPR, TMPR
- SetNZ_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- xor TMPR, TMPR
- cmp SRC_cx, 32
- jb @F
- ;; >= 32
- mov SRC_cx, DST
- mov DST, TMPR ;; Rd:= 0
- sete TMPR8 ;; 32 1
- and SC_CPSR, not (FLAG_C or FLAG_N)
- and SRC_cx, 1
- and SRC_cx, TMPR ;; and it.
- shl SRC_cx, FLAG_CHECK_C_X86_BT
- or SC_CPSR, SRC_cx
- or SC_CPSR, FLAG_Z
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- shl DST, cl
- SetNZC_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- taLSR:
- OUTd "LSR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- and SRC_cx, 255
- jne @F
- ;; ZERO.
- mov TMPR, DST
- or TMPR, TMPR
- SetNZ_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- xor TMPR, TMPR
- cmp SRC_cx, 32
- jb @F
- ;; >= 32
- mov SRC_cx, DST
- mov DST, TMPR ;; Rd:= 0
- sete TMPR8 ;; 32 1
- and SC_CPSR, not (FLAG_C or FLAG_N)
- shr SRC_cx, 31
- and SRC_cx, TMPR ;; and it.
- shl SRC_cx, FLAG_CHECK_C_X86_BT
- or SC_CPSR, SRC_cx
- or SC_CPSR, FLAG_Z
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- shr DST, cl
- SetNZC_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- taASR:
- OUTd "ASR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- and SRC_cx, 255
- jne @F
- ;; ZERO.
- mov TMPR, DST
- or TMPR, TMPR
- SetNZ_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- cmp SRC_cx, 32
- jb @F
- bt DST, 31
- sbb SRC_cx, SRC_cx
- mov DST, SRC_cx
- SetNZC_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- sar DST, cl
- SetNZC_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- taROR:
- OUTd "ROR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
- and SRC_cx, 255
- jne @F
- ;; ZERO.
- mov TMPR, DST
- or TMPR, TMPR
- SetNZ_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- test SRC_cx, 31
- jne @F
- mov SC_INVOL, DST
- or SC_INVOL, SC_INVOL
- rol SC_INVOL, 1
- SetNZC_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- @@:
- and SRC_cx, 31
- ror DST, cl
- SetC_A
- mov eax, DST
- or eax, eax
- SetNZ_A
- GamePAK_Prefetch 1
- tb_ExitAddPC 2
- INLSL:
- OUTd "LSL R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 31"
- mov ecx, SC_INVOL
- GetRFIV_T SC_INVOL, 3, edx ;;Rm.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- shr ecx, 6
- and ecx, 31
- jne @F
- or edx, edx
- mov ZRS (eax), edx
- SetNZ_A
- tb_ExitAddPC 1
- @@:
- shl edx, cl
- mov ZRS (eax), edx
- SetNZC_A
- tb_ExitAddPC 1
- INLSR:
- OUTd "LSR R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 31"
- mov ecx, SC_INVOL
- GetRFIV_T SC_INVOL, 3, edx ;;Rm.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- shr ecx, 6
- and ecx, 31
- jne @F
- and SC_CPSR, not (FLAG_Z or FLAG_N or FLAG_C)
- or SC_CPSR, FLAG_Z
- shl edx, 1
- mov ZRS (eax), 0
- SetC_A
- tb_ExitAddPC 1
- @@:
- shr edx, cl
- mov ZRS (eax), edx
- SetNZC_A
- tb_ExitAddPC 1
- INASR:
- OUTd "ASR R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 31"
- mov ecx, SC_INVOL
- GetRFIV_T SC_INVOL, 3, edx ;;Rm.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- shr ecx, 6
- and ecx, 31
- jne @F
- shl edx, 1
- sbb ecx, ecx ;; 0 or -1
- mov ZRS (eax), ecx
- SetNZC_A
- tb_ExitAddPC 1
- @@:
- sar edx, cl
- mov ZRS (eax), edx
- SetNZC_A
- tb_ExitAddPC 1
- ADDI3:
- OUTd "ADD R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
- GetRFIV_T SC_INVOL, 3, edx ;;Rn.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- GetRFI_T SC_INVOL, 6, ecx ;;Imm3
- add edx, ecx
- mov ZRS (eax), edx
- SetNZCV_A 0
- tb_ExitAddPC 1
- SUBI3:
- OUTd "SUB R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
- GetRFIV_T SC_INVOL, 3, edx ;;Rn.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- GetRFI_T SC_INVOL, 6, ecx ;;Imm3
- sub edx, ecx
- mov ZRS (eax), edx
- SetNZCV_A 1
- tb_ExitAddPC 1
- ADDRT:
- OUTd "ADD R%d, R%d, R%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
- GetRFIV_T SC_INVOL, 3, edx ;;Rn.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- GetRFIV_T SC_INVOL, 6, ecx ;;Rm
- add edx, ecx
- mov ZRS (eax), edx
- SetNZCV_A 0
- tb_ExitAddPC 1
- SUBRT:
- OUTd "SUB R%d, R%d, R%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
- GetRFIV_T SC_INVOL, 3, edx ;;Rn.
- GetRFI_T SC_INVOL, 0, eax ;;Rd's Index .
- GetRFIV_T SC_INVOL, 6, ecx ;;Rm
- sub edx, ecx
- mov ZRS (eax), edx
- SetNZCV_A 1
- tb_ExitAddPC 1
- MOVI8:
- OUTd "MOV R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
- GetRFI_T SC_INVOL, 8, ecx ;;Rd's Index .
- and SC_INVOL, 255
- mov ZRS (ecx), SC_INVOL
- SetNZ_A
- tb_ExitAddPC 1
- CMPI8:
- OUTd "CMP R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
- GetRFIV_T SC_INVOL, 8, ecx ;;Rn's Value .
- and SC_INVOL, 255
- cmp ecx, SC_INVOL
- SetNZCV_A 1
- tb_ExitAddPC 1
- ADDI8:
- OUTd "ADD R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
- GetRFI_T SC_INVOL, 8, ecx ;;Rd's Index .
- and SC_INVOL, 255
- add ZRS (ecx), SC_INVOL
- SetNZCV_A 0
- tb_ExitAddPC 1
- SUBI8:
- OUTd "SUB R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
- GetRFI_T SC_INVOL, 8, ecx ;;Rd's Index .
- and SC_INVOL, 255
- sub ZRS (ecx), SC_INVOL
- SetNZCV_A 1
- tb_ExitAddPC 1
- 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_INVOL, ecx, edx
- OUTd "ADD R%d, R%d", "ecx", "edx"
- mov edx, ZRS (edx)
- add ZRS (ecx), edx
- cmp ecx, 15
- jne @F
- and ZRS (ecx), -2
- tb_FlushPipeline 3
- @@:
- tb_ExitAddPC 1
- MOV16:
- ih1h2Get SC_INVOL, ecx, edx
- OUTd "MOV R%d, R%d", "ecx", "edx"
- mov edx, ZRS (edx)
- mov ZRS (ecx), edx
- cmp ecx, 15
- jne @F
- and ZRS (ecx), -2
- tb_FlushPipeline 3
- @@:
- tb_ExitAddPC 1
- CMP16:
- ih1h2Get SC_INVOL, ecx, edx
- OUTd "CMP R%d, R%d", "ecx", "edx"
- mov edx, ZRS (edx)
- cmp ZRS (ecx), edx
- SetNZCV_A 1
- tb_ExitAddPC 1
- SIM08 macro lSym, SZ_BODY
- lSym:
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- mov edx, ZRS (SZ_BODY) ;; 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
- OUTd "ADD R%d, SP, %d-%03X", "ecx", "eax", "eax"
- ELSEIF SZ_BODY eq SZ_PC
- OUTd "ADD R%d, PC, %d-%03X", "ecx", "eax", "eax"
- ELSE
- ERRORS_ASSERT
- ENDIF
- endm
- SIM08 PCI08, SZ_PC
- and edx, -4
- add edx, eax
- mov ZRS (ecx), edx
- tb_ExitAddPC 1
- SIM08 SPI08, SZ_STACK
- add edx, eax
- mov ZRS (ecx), edx
- tb_ExitAddPC 1
- STKS7:
- test SC_INVOL, 080h
- je @F
- and SC_INVOL, 07Fh
- shl SC_INVOL, 2
- OUTd "SUB SP, #%d", "SC_INVOL"
- sub ZRS (SZ_STACK), SC_INVOL
- tb_ExitAddPC 1
- @@:
- and SC_INVOL, 07Fh
- shl SC_INVOL, 2
- OUTd "ADD SP, #%d", "SC_INVOL"
- add ZRS (SZ_STACK), SC_INVOL
- tb_ExitAddPC 1
- SWI08: ;; Thumb Software Interrupt
- OUTd "SWI-THUMB FUNC:%02X R0 %08X R1 %08X R2 %08X\n", "SC_INVOL & 255", "Z0", "Z1", "Z2"
- mov eax, ZRS (SZ_PC)
- 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+4], edx
- ;; Adjust PC Pointer to IRQ Interrupt vector address
- mov ZRS (SZ_PC), ARM7_VECTOR_SOFTWARE
- mov SC_INVOL, SC_CPSR
- and SC_INVOL, ARM7_MODE_GET_MASK
- cmp SC_INVOL, ARM7_MODE_MGR_MASK
- je @NestSwi_thumb
- ;; switch Mode
- SwitchMode ecx, 0
- ;; Prefetch Opcode pipeline
- arm7_FlushPipeline 3
- @NestSwi_thumb:
- mov ZRS (SZ_LRLINK), edx
- mov [SC_ARM7].SPSR_T[SPSRb_MGR], SC_CPSR
- mov eax, ZRS (SZ_STACK)
- mov [SC_ARM7].R1314_T[R1314b_MGR], eax
- mov eax, ZRS (SZ_LRLINK)
- mov [SC_ARM7].R1314_T[R1314b_MGR+4], eax
- mov SC_CPSR, ecx
- ;; Prefetch Opcode pipeline
- arm7_FlushPipeline 3
- PUSHR: ;; PUSH is DB stack opreate type, if R spec, Push LRLINK to stack.
- OUTd "PUSH R:%d R7-R4:%01X R3-R0:%01X", "SC_INVOL } 8 & 1", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
- sub esp, LDM_STACK_REQUIRE
- mov STA (RnFirst), 0
- sub ZRS (SZ_STACK), 4
- mov STA (RnCount), 8
- shl SC_INVOL, 23
- @@:
- shl SC_INVOL, 1
- jnc PUSHR_c
- add SC_WAIT, 1
- mov eax, STA (RnCount)
- bt eax, 3 ;; Check R Spec
- sbb ecx, ecx
- and ecx, SZ_LRLINK
- or eax, ecx ;; XXX: LRLINK must be 14
- push STACK_PUSH_STATUS_PUSH
- push eax
- push ZRS (eax)
- push ZRS (SZ_STACK)
- sub ZRS (SZ_STACK), 4
- cmp STA (RnFirst+16), 0
- mov STA (RnFirst+16), 1
- je PUSHR_first
- CallMemOrIOAddWaitState StackWriteSeq
- jmp PUSHR_c
- PUSHR_first:
- CallMemOrIOAddWaitState StackWriteNoSeq
- PUSHR_c:
- sub STA (RnCount), 1
- jge @B
- add ZRS (SZ_STACK), 4
- add esp, LDM_STACK_REQUIRE
- mov [SC_ARM7].nextNoSeqFetch, 1
- tb_ExitAddPC 1
- POPRP: ;; POP is IA stack opreate type, if R spec, Pop PC from stack.
- OUTd "POP R:%d R7-R4:%01X R3-R0:%01X", "SC_INVOL } 8 & 1", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
- GamePAK_Prefetch 1
- xor eax, eax
- sub esp, LDM_STACK_REQUIRE
- mov STA (RnFirst), eax
- mov STA (RnCount), eax
- @@:
- shr SC_INVOL, 1
- jnc POPRP_c
- inc SC_WAIT
- push ZRS (SZ_STACK)
- cmp STA (RnFirst+4), 0
- mov STA (RnFirst+4), 1
- je POPRP_first
- CallMemOrIOAddWaitState StackReadSeq
- jmp POPRP_continue
- POPRP_first:
- CallMemOrIOAddWaitState StackReadNoSeq
- POPRP_continue:
- mov edx, STA (RnCount)
- bt edx, 3 ;; Check R Spec
- sbb ecx, ecx
- and ecx, SZ_PC
- or edx, ecx ;; XXX: PC must be 15
- mov ZRS (edx), eax
- add ZRS (SZ_STACK), 4
- cmp edx, SZ_PC ;; PC Flush? Flush Pipeline : nodone.
- je @F
- POPRP_c:
- add STA (RnCount), 1
- cmp STA (RnCount), 9
- jne @B
- add esp, LDM_STACK_REQUIRE
- tb_ExitAddPC 2
- @@:
- add esp, LDM_STACK_REQUIRE
- tb_FlushPipeline 4
- TB_LDR equ 0
- TB_LDRH equ 1
- TB_LDRSH equ 2
- TB_RESET equ 7
- STRsc macro Routine
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- mov edx, SC_INVOL
- and eax, 7
- shr ecx, 3
- and ecx, 7
- shr edx, 6
- and edx, 7
- OUTd "R%d, [R%d, R%d]", "eax", "ecx", "edx"
- mov ecx, ZRS (ecx)
- mov eax, ZRS (eax)
- add ecx, ZRS (edx)
- push eax
- push ecx
- CallMemOrIOAddWaitState Routine
- mov [SC_ARM7].nextNoSeqFetch, 1 ;; STR always NoSeq fetch in next fetch.
- tb_ExitAddPC 2
- endm
- LDRsc macro MemAccessType, Routine, MovSt, rhs, alignBlk
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- mov edx, SC_INVOL
- and eax, 7
- shr ecx, 3
- and ecx, 7
- shr edx, 6
- and edx, 7
- OUTd "R%d, [R%d, R%d]", "eax", "ecx", "edx"
- mov ecx, ZRS (ecx)
- mov SC_INVOL, eax
- add ecx, ZRS (edx)
- mov [SC_ARM7].calc, ecx
- ;; and ecx, alignBlk
- push ecx
- CallMemOrIOAddWaitState Routine
- mov ecx, [SC_ARM7].calc
- IF MemAccessType eq TB_RESET
- MovSt eax, rhs
- ELSEIF MemAccessType eq TB_LDR
- and ecx, 3
- shl ecx, 3
- ror eax, cl
- ELSEIF MemAccessType eq TB_LDRH
- and eax, 0FFFFh
- and ecx, 1
- shl ecx, 3
- ror eax, cl
- ELSEIF MemAccessType eq TB_LDRSH
- mov edx, eax
- movsx eax, ax
- and ecx, 1
- je @F
- movsx eax, dh
- @@:
- ELSE
- ERRORS_ASSERT
- ENDIF
- mov ZRS (SC_INVOL), eax
- GamePAK_Prefetch 1
- tb_ExitAddPC 3
- endm
- STRWD:
- OUTd "STR "
- STRsc MmuWriteWordNoSeq
- STRHW:
- OUTd "STRH "
- STRsc MmuWriteHalfWordNoSeq
- STRUB:
- OUTd "STRB "
- STRsc MmuWriteByteNoSeq
- LDRWD:
- OUTd "LDR "
- LDRsc TB_LDR, MmuReadWordNoSeq, mov, eax, 0FFFFFFFCh
- LDHW2:
- OUTd "LDRH "
- LDRsc TB_LDRH, MmuReadHalfWordNoSeq, movzx, ax, 0FFFFFFFEh
- LDRSW:
- OUTd "LDRSH "
- LDRsc TB_LDRSH, MmuReadHalfWordNoSeq, movsx, ax, 0FFFFFFFEh
- LDRUB:
- OUTd "LDRB "
- LDRsc TB_RESET, MmuReadByteNoSeq, movzx, al, 0FFFFFFFFh
- LDRSB:
- OUTd "LDRSB "
- LDRsc TB_RESET, MmuReadByteNoSeq, movsx, al, 0FFFFFFFFh
- ;; encode: d0-d2 rd, d3-d5 rn, r6-r10 imm5*sizeof(bitdepth/8)
- ADR5 macro SftBit ;; eax:rdi, edx:address
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- mov edx, SC_INVOL
- and eax, 7 ;; Rd
- shr ecx, 3
- and ecx, 7 ;; Rn
- shr edx, 6
- and edx, 31 ;; Imm5
- shl edx, SftBit
- OUTd "R%d, [R%d, %d]", "eax", "ecx", "edx"
- add edx, ZRS (ecx)
- mov [SC_ARM7].calc, edx
- endm
- STR5 macro SftBit, CallRoutine
- ADR5 SftBit
- push ZRS (eax)
- push edx
- CallMemOrIOAddWaitState CallRoutine
- mov [SC_ARM7].nextNoSeqFetch, 1
- tb_ExitAddPC 2
- endm
- LDR5 macro MemAccessType, SftBit, BitLimit, CallRoutine
- ADR5 SftBit
- mov SC_INVOL, eax
- push edx
- CallMemOrIOAddWaitState CallRoutine
- mov ecx, [SC_ARM7].calc
- IF MemAccessType eq TB_LDR
- and ecx, 3
- shl ecx, 3
- ror eax, cl
- ELSEIF MemAccessType eq TB_LDRH
- and eax, 0FFFFh
- and ecx, 1
- shl ecx, 3
- ror eax, cl
- ELSEIF MemAccessType eq TB_RESET
- movzx eax, al
- ENDIF
- mov ZRS (SC_INVOL), eax
- GamePAK_Prefetch 1
- tb_ExitAddPC 3
- endm
- LDSTR1315 macro lSym
- lSym:
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- mov edx, SC_INVOL
- and eax, 255 ;; Imm8
- shr ecx, 8
- and ecx, 7 ;; Rd
- shl eax, 2 ;;;;4 address temp
- endm
- STRW5:
- OUTd "STR "
- STR5 2, MmuWriteWordNoSeq
- STRH5:
- OUTd "STRH "
- STR5 1, MmuWriteHalfWordNoSeq
- STRB5:
- OUTd "STRB "
- STR5 0, MmuWriteByteNoSeq
- LDRW5: ;;=======================DEBUG
- OUTd "LDR "
- LDR5 TB_LDR, 2, 0FFFFFFFFh, MmuReadWordNoSeq
- LDRH5:
- OUTd "LDRH "
- LDR5 TB_LDRH, 1, 0FFFFh, MmuReadHalfWordNoSeq
- LDRB5:
- OUTd "LDRB "
- LDR5 TB_RESET, 0, 0FFh, MmuReadByteNoSeq
- LDSTR1315 LDRPC
- OUTd "LDR R%d, [PC, #%d-%03X]", "ecx", "eax", "eax"
- mov edx, ZRS (SZ_PC)
- and edx, -4
- add eax, edx
- mov SC_INVOL, ecx
- push eax
- mov [SC_ARM7].calc, eax
- CallMemOrIOAddWaitState MmuReadWordNoSeq
- mov ecx, [SC_ARM7].calc
- and ecx, 3
- shl ecx, 3
- ror eax, cl
- mov ZRS (SC_INVOL), eax
- GamePAK_Prefetch 1
- tb_ExitAddPC 3
- LDSTR1315 LDRSP
- OUTd "LDR R%d, [SP, #%d-%03X]", "ecx", "eax", "eax"
- add eax, ZRS (SZ_STACK)
- mov SC_INVOL, ecx
- push eax
- mov [SC_ARM7].calc, eax
- CallMemOrIOAddWaitState MmuReadWordNoSeq
- mov ecx, [SC_ARM7].calc
- and ecx, 3
- shl ecx, 3
- ror eax, cl
- mov ZRS (SC_INVOL), eax
- GamePAK_Prefetch 1
- tb_ExitAddPC 3
- LDSTR1315 STRSP
- OUTd "STR R%d, [SP, #%d-%03X]", "ecx", "eax", "eax"
- add eax, ZRS (SZ_STACK)
- push ZRS (ecx)
- push eax
- CallMemOrIOAddWaitState MmuWriteWordNoSeq
- mov [SC_ARM7].nextNoSeqFetch, 1
- tb_ExitAddPC 2
- ;; A7.1.57 - STMIA (INC, AFTER)
- ;;
- ;; Codec: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 1 1 1 0 0 Rn Reglist.
- ;;
- STMIA:
- OUTd "T-STMIA [R%d]!, R7-R4:%01X R3-R0:%01X ", "SC_INVOL } 8 & 7", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
- sub esp, LDM_STACK_REQUIRE
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- and eax, 255
- shr ecx, 8
- and ecx, 7
- ;; Get Rn's index and Rn's init value.
- mov edx, ZRS (ecx)
- mov STA (RnTempi), ecx
- mov STA (RnTemp), edx
- mov STA (RnFirst), 0
- mov STA (RnCount), 0
- ;; Check Reglist is empty ?
- ;; ================================= NO$GBA doc =================================
- ;; Strange Effects on Invalid Rlist's
- ;; Empty Rlist: R15 loaded/stored (ARMv4 only), and Rb=Rb+40h (ARMv4-v5).
- ;; Writeback with Rb included in Rlist: Store OLD base if Rb is FIRST entry in
- ;; Rlist, otherwise store NEW base (STM/ARMv4), always store OLD base (STM/ARMv5),
- ;; no writeback (LDM/ARMv4/ARMv5; at this point, THUMB opcodes work different than ARM opcodes).
- test eax, eax
- jne @F
- push STACK_PUSH_STATUS_PUSH
- push SZ_PC
- mov eax, ZRS (SZ_PC)
- add eax, 2
- push eax
- push edx
- add ZRS (ecx), 64
- and ZRS (ecx), -4
- CallMemOrIOAddWaitState StackWriteNoSeq
- add esp, LDM_STACK_REQUIRE
- mov [SC_ARM7].nextNoSeqFetch, 1
- tb_ExitAddPC 2
- ;; Check Rn with Reglist ?
- @@:
- bt eax, ecx
- jnc @F
- DEBUG_BREAK
- OUTd "R%d in reglist! FIRST-V:", "ecx"
- xor edx, edx
- not edx
- ;; Check First Vailed bit
- ;; IF Done, write inital value to stack
- ;; ELSE. write final Rn's value to stack (this is UB. but i test on AXD Debugger 1.2 is final Rn)
- ;; See ARM Developer Suite Assembler Guide:: Thumb Instruction Reference::5.1.5 LDMIA and STMIA
- ;;
- shl edx, cl
- not edx
- test edx, eax
- je STMIA_k
- OUTd "NO"
- ;; Calc write back's Rn in end.
- IF 1
- mov ecx, 8
- xor edx, edx
- STMIA0:
- shr eax, 1
- adc edx, 0
- dec ecx
- jne STMIA0
- ELSE
- and eax, 255
- popcnt edx, eax
- ENDIF
- ;; Write back Rn.
- lea edx, [edx*4]
- mov ecx, SC_INVOL
- shr ecx, 8
- and ecx, 7
- add ZRS (ecx), edx
- and ZRS (ecx), -4
- STMIA_k:
- OUTd "YES"
- @@:
- shr SC_INVOL, 1
- jnc STMIA_c
- inc SC_WAIT
- mov eax, STA (RnCount)
- push STACK_PUSH_STATUS_PUSH
- push eax
- push ZRS (eax)
- mov eax, STA (RnTemp+12)
- add STA (RnTemp+12), 4
- ;; and eax, -4
- push eax
- cmp STA (RnFirst+16), 0
- mov STA (RnFirst+16), 1
- je STMIA_first
- CallMemOrIOAddWaitState StackWriteSeq
- jmp STMIA_c
- STMIA_first:
- CallMemOrIOAddWaitState StackWriteNoSeq
- STMIA_c:
- add STA (RnCount), 1
- cmp STA (RnCount), 8
- jne @B
- cmp STA (RnFirst), 0
- jne @F
- @@:
- mov ecx, STA (RnTemp)
- mov eax, STA (RnTempi)
- mov ZRS (eax), ecx
- and ZRS (eax), -4
- add esp, LDM_STACK_REQUIRE
- mov [SC_ARM7].nextNoSeqFetch, 1
- tb_ExitAddPC 1
- ;; A7.1.27 LDMIA
- ;;
- ;; Codec: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- ;; 1 1 1 0 1 Rn Reglist.
- ;;
- LDMIA:
- GamePAK_Prefetch 1
- OUTd "T-LDMIA [R%d]!, R7-R4:%01X R3-R0:%01X ", "SC_INVOL } 8 & 7", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
- sub esp, LDM_STACK_REQUIRE
- mov eax, SC_INVOL
- mov ecx, SC_INVOL
- and eax, 255
- shr ecx, 8
- and ecx, 7
- ;; Get Rn's index and Rn's init value.
- mov edx, ZRS (ecx)
- mov STA (RnTempi), ecx
- mov STA (RnTemp), edx
- mov STA (RnFirst), 0
- mov STA (RnCount), 0
- mov STA (RnAdjust), 1
- ;; Check empty reglist
- test eax, eax
- jne @F
- push edx
- add ZRS (ecx), 64
- and ZRS (ecx), -4
- CallMemOrIOAddWaitState StackReadNoSeq
- mov ZRS (SZ_PC), eax
- add esp, LDM_STACK_REQUIRE
- tb_FlushPipeline 3
- @@:
- bt eax, ecx
- jnc @F
- ;; Rn with Reglist
- ;; Rn WriteBack will miss in thumb-LDMIA.
- ;; DEBUG_BREAK
- OUTd "R%d in reglist!"
- mov STA (RnAdjust), 0
- @@:
- shr SC_INVOL, 1
- jnc LDMIA_c
- inc SC_WAIT
- mov eax, STA (RnTemp)
- add STA (RnTemp), 4
- ;; and eax, -4
- push eax
- cmp STA (RnFirst+4), 0
- mov STA (RnFirst+4), 1
- je LDMIA_first
- CallMemOrIOAddWaitState StackReadSeq
- jmp LDMIA_a
- LDMIA_first:
- CallMemOrIOAddWaitState StackReadNoSeq
- LDMIA_a:
- mov ecx, STA (RnCount)
- mov ZRS (ecx), eax
- LDMIA_c:
- add STA (RnCount), 1
- cmp STA (RnCount), 8
- jne @B
- cmp STA (RnFirst), 0
- jne @F
- ;; FIXME: No Reglist mask exist stuff..
- DEBUG_BREAK
- @@:
- cmp STA (RnAdjust), 0
- je @F
- mov ecx, STA (RnTemp)
- mov eax, STA (RnTempi)
- mov ZRS (eax), ecx
- and ZRS (eax), -4
- @@:
- add esp, LDM_STACK_REQUIRE
- tb_ExitAddPC 2
- ;; JMP Sign Offset 11bit. @!SMARK.
- JMP11:
- and SC_INVOL, 07FFh
- bt SC_INVOL, 10
- sbb eax, eax
- shl eax, 10
- or SC_INVOL, eax
- shl SC_INVOL, 1
- OUTd ":JMP 11 Offset %d-%08X ", "SC_INVOL", "SC_INVOL"
- add ZRS (SZ_PC), SC_INVOL
- OUTd ":CurrentPC %d-%08X", "ZF", "ZF"
- tb_FlushPipeline 2
- IF 0
- ;; BL Ext
- BLEXT:
- ;; Fetch Ext High
- ;; int 3
- and SC_INVOL, 07FFh
- bt SC_INVOL, 10
- sbb eax, eax
- shl eax, 10
- or SC_INVOL, eax
- shl SC_INVOL, 12
- add SC_INVOL, ZRS(SZ_PC)
- mov ZRS (SZ_LRLINK), SC_INVOL
- ;; Fetch Next Opcode Must be BLSTD (TODO: Opcode Check)
- mov eax, [SC_ARM7].Opcode[0]
- and eax, 07FFh
- shl eax, 1
- add eax, ZRS (SZ_LRLINK)
- OUTd ":BL Offset %d-%08X ", "ZE", "ZE"
- mov ecx, ZRS (SZ_PC)
- mov ZRS (SZ_PC), eax
- OUTd ":CurrentPC %d-%08X ", "ZF", "ZF"
- sub ecx, 0 ;; backup to next instruction base current instruction
- or ecx, 1 ;; With Thumb flags, for BX
- OUTd ":LINK %d-%08X ", "ecx", "ecx"
- mov ZRS (SZ_LRLINK) ,ecx
- ;; prefetch opcode .
- tb_FlushPipeline 3
- BLSTD: ;;(in fact, with BLEXT).
- ELSE
- ;; BL Ext
- BLEXT:
- ;; Fetch Ext High
- ;; int 3
- and SC_INVOL, 07FFh
- bt SC_INVOL, 10
- sbb eax, eax
- shl eax, 10
- or SC_INVOL, eax
- shl SC_INVOL, 12
- add SC_INVOL, ZRS(SZ_PC)
- mov ZRS (SZ_LRLINK), SC_INVOL
- tb_ExitAddPC 1
- BLSTD: ;;(in fact, with BLEXT).
- mov eax, SC_INVOL
- and eax, 07FFh
- shl eax, 1
- add eax, ZRS (SZ_LRLINK)
- OUTd ":BL Offset %d-%08X ", "ZE", "ZE"
- mov ecx, ZRS (SZ_PC)
- mov ZRS (SZ_PC), eax
- OUTd ":CurrentPC %d-%08X ", "ZF", "ZF"
- sub ecx, 2 ;; backup to next instruction base current instruction
- or ecx, 1 ;; With Thumb flags, for BX
- OUTd ":LINK %d-%08X ", "ecx", "ecx"
- mov ZRS (SZ_LRLINK) ,ecx
- ;; prefetch opcode .
- tb_FlushPipeline 3
- ENDIF
- UNDEF:
- int 3
- BX_TB:
- mov eax, SC_INVOL
- and eax, 078h
- shr eax, 3
- OUTd "BX R%d", "eax"
- mov ecx, ZRS (eax)
- test ecx, 1
- je @F
- or SC_CPSR, FLAG_THUMB
- and ecx, -2
- mov ZRS (SZ_PC), ecx
- tb_FlushPipeline 3
- @@:
- and SC_CPSR, not FLAG_THUMB
- and ecx, -4
- mov ZRS (SZ_PC), ecx
- arm7_FlushPipeline 3
- ;; Thumb JCC -----------------------------------------------------------------
- JCCEQ:
- OUTd "JCC:EQ "
- test SC_CPSR, FLAG_Z
- jne JCCAL
- JCCNV:
- OUTd ":Skip "
- tb_ExitAddPC 1
- JCCNE:
- OUTd "JCC:NE "
- test SC_CPSR, FLAG_Z
- je JCCAL
- tb_ExitAddPC 1
- JCCCS:
- OUTd "JCC:CS "
- test SC_CPSR, FLAG_C
- jne JCCAL
- jmp JCCNV
- JCCCC:
- OUTd "JCC:CC "
- test SC_CPSR, FLAG_C
- je JCCAL
- jmp JCCNV
- JCCMI:
- OUTd "JCC:MI "
- test SC_CPSR, FLAG_N
- jne JCCAL
- jmp JCCNV
- JCCPL:
- OUTd "JCC:PL "
- test SC_CPSR, FLAG_N
- je JCCAL
- jmp JCCNV
- JCCVS:
- OUTd "JCC:VS "
- test SC_CPSR, FLAG_V
- jne JCCAL
- jmp JCCNV
- JCCVC:
- OUTd "JCC:VC "
- test SC_CPSR, FLAG_V
- je JCCAL
- jmp JCCNV
- JCCHI: ;; C = 1 && Z = 0
- OUTd "JCC:HI "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- cmp ecx, FLAG_C
- je JCCAL
- jmp JCCNV
- JCCLS: ;; C = 0 || Z = 1
- OUTd "JCC:LS "
- mov ecx, SC_CPSR
- and ecx, FLAG_CZ
- ;; C0Z1 ^ C1Z0 -> C1Z1
- ;; C1Z1 ^ C1Z0 -> C0Z1
- ;; C0Z0 ^ C1Z0 -> C1Z0
- ;; C1Z0 ^ C1Z0 -> ZERO.
- xor ecx, FLAG_C
- jne JCCAL
- jmp JCCNV
- JCCGE: ;; N = V
- OUTd "JCC: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 JCCAL
- jmp JCCNV
- JCCLT: ;; N != V
- OUTd "JCC: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 JCCAL
- jmp JCCNV
- JCCGT: ;; N = V && Z= 0
- OUTd "JCC: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 JCCAL
- jmp JCCNV
- JCCLE: ;; Z = 1 || N!=V
- OUTd "JCC: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 JCCNV
- JCCAL: ;; 1110
- OUTd "Exec It.:"
- mov eax, SC_INVOL
- and eax, 255
- mov [esp-8], eax
- movsx eax, byte ptr [esp-8]
- OUTd ":Offset %d-%08X ", "eax", "eax"
- shl eax, 1
- add ZRS (SZ_PC), eax
- OUTd ":CurrentPC %d-%08X", "ZF", "ZF"
- tb_FlushPipeline 2
- ; Instruction Hash Entry -----------------------------------------------------------------------------------
- .data
- 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, si5ToCPSR, 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, 100b ;; 0 0 0
- dd 000b, 000b ;; 0 1 0
- dd 000b, 000b ;; 0 0 0
- dd 0001b, 0101b ;; 0 1 0
- ARM7_MUL_TAB dd mMUL, mMULS, mMLA, mMLAS
- dd mUB, mUB, mUB, mUB
- dd mUMUL64, mUMUL64S, mUMLA64, mUMLA64S
- dd mSMUL64, mSMUL64S, mSMLA64, mSMLA64S
- ;; thumb alu
- taTAB dd taAND, taEOR, taLSL, taLSR
- dd taASR, taADC, taSBC, taROR
- dd taTST, taNEG, taCMP, taCMN
- dd taORR, taMUL, taBIC, taMVN
- ;; 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
- 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, ADDRT, ADDRT, SUBRT, SUBRT, 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
- .code
- arm7tdmi_ticks endp
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement