Advertisement
xiahanlu

汇编核心

Jul 24th, 2019
488
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;; arm7.asm
  2. ;; arm7 chip for gba
  3. ;;
  4. ;; Copyripht 2019 moecmks (agalis01@outlook.com)
  5. ;; This file is part of ArchBoyAdvance.
  6. ;;
  7. ;; This program is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11. ;;
  12. ;; This program is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16. ;;
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with this program; if not, write to the Free Software Foundation,
  19. ;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  20.  
  21. ;; TODO:
  22. ;; GamePak Prfetch Timing Problem.
  23.  
  24.   .686            
  25.   .mmx
  26.   .xmm  
  27.   .model flat, c    
  28.   option casemap :none
  29.  
  30. ;; mmu read/write
  31. ;; internal will set arm7tdmi::waitState
  32.  
  33. extrn agb_mbus_rw_seq@8:proc  
  34. extrn agb_mbus_ww_seq@12:proc
  35. extrn agb_code_rhw_seq@8:proc
  36. extrn agb_code_rw_seq@8:proc  
  37. extrn agb_mbus_rb_noseq@8:proc
  38. extrn agb_mbus_rhw_noseq@8:proc  
  39. extrn agb_mbus_rw_noseq@8:proc
  40. extrn agb_mbus_wb_noseq@12:proc
  41. extrn agb_mbus_whw_noseq@12:proc
  42. extrn agb_mbus_ww_noseq@12:proc
  43. extrn agb_code_rhw_noseq@8:proc
  44. extrn agb_code_rw_noseq@8:proc  
  45. extrn agb_gamepak_prefetch@12:proc
  46. extrn agb_irq_hook@4:proc
  47. extrn agb_stack_ww_seq@20:proc
  48. extrn agb_stack_ww_noseq@20:proc
  49. extrn agb_stack_rw_seq@8:proc
  50. extrn agb_stack_rw_noseq@8:proc  
  51.  
  52. STACK_PUSH_STATUS_INIT equ 0
  53. STACK_PUSH_STATUS_PUSH equ 1
  54.  
  55. StackWriteSeq equ agb_stack_ww_seq@20
  56. StackWriteNoSeq equ agb_stack_ww_noseq@20
  57. StackReadSeq equ agb_stack_rw_seq@8
  58. StackReadNoSeq equ agb_stack_rw_noseq@8
  59. MmuReadWordSeq equ agb_mbus_rw_seq@8
  60. MmuWriteWordSeq equ agb_mbus_ww_seq@12
  61. MmuReadByteNoSeq equ agb_mbus_rb_noseq@8
  62. MmuReadHalfWordNoSeq equ agb_mbus_rhw_noseq@8
  63. MmuReadWordNoSeq equ agb_mbus_rw_noseq@8
  64. MmuWriteByteNoSeq equ agb_mbus_wb_noseq@12
  65. MmuWriteHalfWordNoSeq equ agb_mbus_whw_noseq@12
  66. MmuWriteWordNoSeq equ agb_mbus_ww_noseq@12
  67. tb_FetchSeq equ agb_code_rhw_seq@8
  68. tb_FetchNoSeq equ agb_code_rhw_noseq@8
  69. ARM7_FetchSeq equ agb_code_rw_seq@8
  70. ARM7_FetchNoSeq equ agb_code_rw_noseq@8
  71. AGB_GamePakPrefetch equ agb_gamepak_prefetch@12
  72. AGB_IRQ_Hook equ agb_irq_hook@4
  73.  
  74. ;;  XXX:memory order indep
  75. arm7tdmi struct
  76.  
  77. SZ_STACK equ 13
  78. SZ_LRLINK equ 14
  79. SZ_PC equ 15
  80. SZ_CPSR equ 16
  81.  
  82.   Regs dd 17 dup (?)
  83.   R812_T dd 10 dup (?)
  84.   R1314_T dd 12 dup (?)
  85.   SPSR_T dd 6 dup (?)
  86.   Opcode dd 2 dup (?)
  87.   IME dd ?
  88.   IFS dw ?
  89.   IE dw ?
  90.   waitState dd ?
  91.   nextNoSeqFetch dd ?
  92.   agb dd ?
  93.   calc dd ?
  94.  
  95. arm7tdmi ends
  96.  
  97. ;;==================================================================================
  98. ;; My CPSR IRQ-I FIQ-I THUMB-F MODE-MASK, PSW. for ARM. same as X86's PSW.
  99. ARM7_DEBUG equ 0
  100. GBA_IE_IF_MASK equ 003FFFh
  101. ARM7_MODE_CLR_MASK equ 0E0FFFFFFh
  102. ARM7_MODE_IRQ_MASK equ 012000000h
  103. ARM7_MODE_MGR_MASK equ 013000000h
  104. ARM7_MODE_USER_MASK equ 010000000h
  105. ARM7_MODE_MSB_BIT_MASK equ 010000000h
  106. ARM7_MODE_FIQ_MASK equ 011000000h
  107. ARM7_MODE_UNDEF_MASK equ 01B000000h
  108. ARM7_MODE_SYS_MASK equ 01F000000h
  109. ARM7_MODE_ABT_MASK equ 017000000h
  110. ARM7_MODE_GET_MASK equ 01F000000h
  111. ARM7_PSR_FLAG_MASK equ 00000C101H
  112. ARM7_PSR_MODE4BIT_MASK equ 00F000000H
  113. ARM7_PSR_MODE8BIT_MASK equ 0DF000000H
  114. ARM7_PSR_STATE_MASK equ 020000000H
  115. ARM7_THUMB_BIT equ 29
  116. ARM7_MODE_BLOCK_SUB_TOF equ 16
  117. ARM7_MODE_SFT_BIT equ 24
  118. ARM7_VECTOR_RESET equ 000h
  119. ARM7_VECTOR_UNDEF equ  004h
  120. ARM7_VECTOR_SOFTWARE equ 008h
  121. ARM7_VECTOR_PREFETCH_ABORT equ 00Ch
  122. ARM7_VECTOR_DATA_ABORT equ 010h
  123. ARM7_VECTOR_IRQ equ 018h
  124. ARM7_VECTOR_FIQ equ 01Ch
  125. ARM7_STD_FLAGS_N equ 080000000h
  126. ARM7_STD_FLAGS_Z equ 040000000h
  127. ARM7_STD_FLAGS_C equ 020000000h
  128. ARM7_STD_FLAGS_V equ 010000000h
  129. ERRORS_ASSERT equ MOECMKS_DONE
  130. @ALIGN_Z equ align 16
  131. PTR32 equ dword ptr
  132.  
  133. IRQ_INHIBI_MASK equ 080000000h
  134. IRQ_INHIBI_MASK_BIT equ 31
  135. FIQ_INHIBI_MASK equ 040000000h
  136.  
  137. MODE_SYS equ 001Fh
  138. MODE_USER equ 00010h
  139. MODE_SFT_BASE_PSR equ 24
  140. FLAG_THUMB equ 020000000H
  141. FLAG_CZ equ (FLAG_C or FLAG_Z)
  142. FLAG_NZ equ (FLAG_N or FLAG_Z)
  143. FLAG_C equ 000100H
  144. FLAG_V equ 000001H
  145. FLAG_N equ 008000H
  146. FLAG_Z equ 004000H
  147. FLAG_N_TOLSB_BIT equ 15
  148. FLAG_N_TO_V_ALIGN_BIT equ 15
  149. FLAG_N_TO_V_ALIGN_SHIFT equ shr
  150. FLAG_V_TOLSB_BIT equ 0
  151. FLAG_Z_TOLSB_BIT equ 14
  152. FLAG_C_TOLSB_BIT equ 8
  153. FLAG_CHECK_C_X86_BT equ 8
  154. FLAG_MSR_FLAGS equ 00080000h
  155. FLAG_MSR_CTL equ 00010000h
  156.  
  157. R812b_BLOCK equ 20
  158. R812b_EXCEPT_FIQ equ R812b_BLOCK*0
  159. R812b_FIQ equ R812b_BLOCK*1
  160.  
  161. R1314b_BLOCK equ 8
  162. R1314b_SYSUSER equ R1314b_BLOCK*0
  163. R1314b_MGR equ R1314b_BLOCK*1
  164. R1314b_IRQ equ R1314b_BLOCK*2
  165. R1314b_FIQ equ R1314b_BLOCK*3
  166. R1314b_ABT equ R1314b_BLOCK*4
  167. R1314b_UDEF equ R1314b_BLOCK*5
  168.  
  169. SPSRb_BLOCK equ 4
  170. SPSRb_SYSUSER equ SPSRb_BLOCK*0
  171. SPSRb_MGR equ SPSRb_BLOCK*1
  172. SPSRb_IRQ equ SPSRb_BLOCK*2
  173. SPSRb_FIQ equ SPSRb_BLOCK*3
  174. SPSRb_ABT equ SPSRb_BLOCK*4
  175. SPSRb_UDEF equ SPSRb_BLOCK*5
  176.  
  177. SC_CPSR8 equ bl
  178. SC_CPSR16 equ bx
  179. SC_CPSR16H equ bh
  180. SC_CPSR equ ebx
  181. SC_ARM7 equ esi
  182. SC_INVOL equ edi
  183. SC_WAIT equ ebp
  184.  
  185.  
  186. ARM7_bba1 macro
  187.   OUTd " #%08X (IMM8:%02X, ROR:%d)", "SC_INVOL & 255 ?~ SC_INVOL}8 & 15 { 1", "SC_INVOL & 255", "SC_INVOL}8 & 15 { 1"
  188. endm
  189.  
  190. ARM7_ALU_BASE_OUTd1 macro OPID
  191.   IF OPID eq AND_OP
  192.     OUTd "AND R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  193.     ARM7_bba1
  194.   ELSEIF OPID eq EOR_OP
  195.     OUTd "EOR R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  196.     ARM7_bba1
  197.   ELSEIF OPID eq ORR_OP
  198.     OUTd "ORR R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  199.     ARM7_bba1  
  200.   ELSEIF OPID eq SUB_OP
  201.     OUTd "SUB R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  202.     ARM7_bba1
  203.   ELSEIF OPID eq ADD_OP
  204.     OUTd "ADD R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  205.     ARM7_bba1
  206.   ELSEIF OPID eq MOV_OP    
  207.     OUTd "MOV R%d", "SC_INVOL}12 & 15"
  208.     ARM7_bba1          
  209.   ELSEIF OPID eq MVN_OP
  210.     OUTd "MVN R%d", "SC_INVOL}12 & 15"
  211.     ARM7_bba1    
  212.   ELSEIF OPID eq BIC_OP
  213.     OUTd "BIC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  214.     ARM7_bba1  
  215.   ELSEIF OPID eq RSB_OP
  216.     OUTd "RSB R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  217.     ARM7_bba1
  218.   ELSEIF OPID eq SBC_OP
  219.     OUTd "SBC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  220.     ARM7_bba1
  221.   ELSEIF OPID eq RSC_OP  
  222.     OUTd "RSC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  223.     ARM7_bba1
  224.   ELSEIF OPID eq ADC_OP  
  225.     OUTd "ADC R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  226.     ARM7_bba1
  227.   ELSEIF OPID eq TST_OP            
  228.   ELSEIF OPID eq TEQ_OP      
  229.   ELSEIF OPID eq CMP_OP              
  230.   ELSEIF OPID eq CMN_OP            
  231.   ELSE  
  232.     ERRORS_ASSERT
  233.   ENDIF
  234. endm
  235.  
  236. ARM7_ALU_SIGN_BASE_OUTd1 macro OPID
  237.   IF OPID eq AND_OP
  238.     OUTd "ANDS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  239.     ARM7_bba1
  240.   ELSEIF OPID eq EOR_OP
  241.     OUTd "EORS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  242.     ARM7_bba1
  243.   ELSEIF OPID eq ORR_OP
  244.     OUTd "ORRS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  245.     ARM7_bba1  
  246.   ELSEIF OPID eq SUB_OP
  247.     OUTd "SUBS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  248.     ARM7_bba1
  249.   ELSEIF OPID eq ADD_OP
  250.     OUTd "ADDS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  251.     ARM7_bba1
  252.   ELSEIF OPID eq MOV_OP    
  253.     OUTd "MOVS R%d", "SC_INVOL}12 & 15"
  254.     ARM7_bba1          
  255.   ELSEIF OPID eq MVN_OP
  256.     OUTd "MVNS R%d", "SC_INVOL}12 & 15"
  257.     ARM7_bba1    
  258.   ELSEIF OPID eq BIC_OP
  259.     OUTd "BICS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  260.     ARM7_bba1  
  261.   ELSEIF OPID eq RSB_OP
  262.     OUTd "RSBS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  263.     ARM7_bba1
  264.   ELSEIF OPID eq SBC_OP
  265.     OUTd "SBCS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  266.     ARM7_bba1
  267.   ELSEIF OPID eq RSC_OP  
  268.     OUTd "RSCS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  269.     ARM7_bba1
  270.   ELSEIF OPID eq ADC_OP  
  271.     OUTd "ADCS R%d, R%d", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15"
  272.     ARM7_bba1      
  273.   ELSEIF OPID eq TST_OP  
  274.     OUTd "TST R%d", "SC_INVOL}16 & 15"
  275.     ARM7_bba1          
  276.   ELSEIF OPID eq TEQ_OP
  277.     OUTd "TEQ R%d", "SC_INVOL}16 & 15"
  278.     ARM7_bba1        
  279.   ELSEIF OPID eq CMP_OP  
  280.     OUTd "CMP R%d", "SC_INVOL}16 & 15"
  281.     ARM7_bba1            
  282.   ELSEIF OPID eq CMN_OP  
  283.     OUTd "CMN R%d", "SC_INVOL}16 & 15"
  284.     ARM7_bba1
  285.   ELSE
  286.     ERRORS_ASSERT
  287.   ENDIF
  288. endm
  289. ARM7_ALU_BASE_OUTd2 macro OPID
  290.   IF OPID eq AND_OP  ;; LSL #2
  291.     OUTd "AND R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  292.   ELSEIF OPID eq EOR_OP
  293.     OUTd "EOR R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  294.   ELSEIF OPID eq ORR_OP
  295.     OUTd "ORR R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  296.   ELSEIF OPID eq SUB_OP
  297.     OUTd "SUB R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  298.   ELSEIF OPID eq ADD_OP
  299.     OUTd "ADD R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  300.   ELSEIF OPID eq MOV_OP    
  301.     OUTd "MOV R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"          
  302.   ELSEIF OPID eq MVN_OP
  303.     OUTd "MVN R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"  
  304.   ELSEIF OPID eq BIC_OP
  305.     OUTd "BIC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  306.   ELSEIF OPID eq RSB_OP
  307.     OUTd "RSB R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  308.   ELSEIF OPID eq SBC_OP
  309.     OUTd "SBC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  310.   ELSEIF OPID eq RSC_OP  
  311.     OUTd "RSC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  312.   ELSEIF OPID eq ADC_OP  
  313.     OUTd "ADC R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  314.   ELSEIF OPID eq TST_OP      
  315.     OUTd "TST R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"              
  316.   ELSEIF OPID eq TEQ_OP  
  317.     OUTd "TEQ R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"          
  318.   ELSEIF OPID eq CMP_OP  
  319.     OUTd "CMP R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"          
  320.   ELSEIF OPID eq CMN_OP
  321.     OUTd "CMN R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"              
  322.   ELSE  
  323.     ERRORS_ASSERT
  324.   ENDIF
  325. endm
  326.  
  327. ARM7_ALU_SIGN_BASE_OUTd2 macro OPID
  328.   IF OPID eq AND_OP  ;; LSL #2
  329.     OUTd "ANDS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  330.   ELSEIF OPID eq EOR_OP
  331.     OUTd "EORS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  332.   ELSEIF OPID eq ORR_OP
  333.     OUTd "ORRS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  334.   ELSEIF OPID eq SUB_OP
  335.     OUTd "SUBS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  336.   ELSEIF OPID eq ADD_OP
  337.     OUTd "ADDS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  338.   ELSEIF OPID eq MOV_OP    
  339.     OUTd "MOVS R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"          
  340.   ELSEIF OPID eq MVN_OP
  341.     OUTd "MVNS R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL & 15"  
  342.   ELSEIF OPID eq BIC_OP
  343.     OUTd "BICS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  344.   ELSEIF OPID eq RSB_OP
  345.     OUTd "RSBS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  346.   ELSEIF OPID eq SBC_OP
  347.     OUTd "SBCS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  348.   ELSEIF OPID eq RSC_OP  
  349.     OUTd "RSCS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  350.   ELSEIF OPID eq ADC_OP  
  351.     OUTd "ADCS R%d, R%d, R%d, ", "SC_INVOL}12 & 15", "SC_INVOL}16 & 15", "SC_INVOL & 15"
  352.   ELSEIF OPID eq TST_OP      
  353.     OUTd "TST R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"              
  354.   ELSEIF OPID eq TEQ_OP  
  355.     OUTd "TEQ R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"          
  356.   ELSEIF OPID eq CMP_OP  
  357.     OUTd "CMP R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"          
  358.   ELSEIF OPID eq CMN_OP
  359.     OUTd "CMN R%d, R%d, ", "SC_INVOL}16 & 15", "SC_INVOL & 15"          
  360.   ELSE  
  361.     ERRORS_ASSERT
  362.   ENDIF  
  363. endm
  364.        
  365.  
  366. .data
  367.  
  368. ;; TODO: Bad Code .
  369. ;;
  370. ;; Macros assembled by MASM are difficult to debug in VS2012's embedded environment,
  371. ;; especially because ehco macros do not work.
  372.  
  373. @ModeUser@ db 'MODE:USER', 0
  374. @ModeSys@ db 'MODE:SYS', 0
  375. @ModeUdef@ db 'MODE:Undef', 0
  376. @ModeABT@ db 'MODE:Abort', 0
  377. @ModeIRQ@ db 'MODE:IRQ', 0
  378. @ModeFIQ@ db 'MODE:FIQ', 0
  379. @ModeMGR@ db 'MODE:MGR', 0
  380.  
  381. @ModeTabs       dd @ModeUser@, @ModeFIQ@, @ModeIRQ@, @ModeMGR@
  382.                 dd @ModeUser@, @ModeUser@, @ModeUser@, @ModeABT@
  383.                 dd @ModeUser@, @ModeUser@, @ModeUser@, @ModeUdef@
  384.                 dd @ModeUser@, @ModeUser@, @ModeUser@, @ModeSys@
  385.                
  386. printf PROTO C :DWORD,:VARARG
  387. DEBUG_OUT equ printf
  388.  
  389.  
  390. ;; input : "content"
  391. rdata_mak macro format
  392.  
  393.  LOCAL mID  ;; loop's iterator
  394.  LOCAL mLEN
  395.  LOCAL mCHSET ; eg. "Hello World", 00Ah, "Goddbyte word", 0
  396.  LOCAL mN ;; Pos init left.
  397.  LOCAL mTAIL_COMP ;; :BOOL init tail comp ,
  398.  LOCAL mT1 ;; fro calc temp
  399.  LOCAL mT2  ;; fro calc temp
  400.  
  401.  mN = 1
  402.  mID = 0
  403.  mTAIL_COMP = 0
  404.  mLEN = @SizeStr (format)
  405.  mCHSET TEXTEQU <>
  406.  ;; mCHSET CATSTR mCHSET, <ccc db >
  407.  
  408.  ;; echo format
  409.  FORC CHS, <format>
  410.    IFIDN <CHS>, <\>
  411.      IF mID ne (mLEN-2)
  412.        CHR_N TEXTEQU @SubStr (format, mID+2, 1)
  413.        %FORC CHS_N, CHR_N
  414.          IFIDN <CHS_N>, <n>
  415.            IF mID eq (mLEN-3)
  416.              mTAIL_COMP = 1
  417.            ENDIF  
  418.            IF mID ne 1
  419.              IF (mID-mN) ne 0
  420.                mT1 = mN+1
  421.                mT2 = mID - mN
  422.                mCHSET CATSTR mCHSET,  <!">, @SubStr (format, mT1, mT2), <!"!,>
  423.              ENDIF          
  424.            ENDIF  
  425.            mN = mID + 2          
  426.            mCHSET CATSTR mCHSET, <00Ah>, <!,>
  427.          ENDIF
  428.        ENDM
  429.      ENDIF
  430.    ENDIF  
  431.    mID = mID + 1
  432.  ENDM
  433.  ;; add tail
  434.  IF mTAIL_COMP ne 1
  435. ;; echo <mTAIL_INCOMP>
  436.            mLEN = mLEN - mN - 1
  437.            mN = mN + 1
  438.            mCHSET CATSTR mCHSET, <!">, @SubStr (format, mN, mLEN), <!"!, 0>
  439.  ELSEIF mTAIL_COMP eq 1
  440.   ;; echo <mTAIL_COMP>
  441.            mCHSET CATSTR mCHSET, <0>
  442.  ENDIF
  443.  ;; %echo mCHSET
  444.  EXITM <mCHSET>
  445. endm
  446.  
  447. tem_rev_arg macro arg1,  arglist:vararg
  448.   LOCAL mCHSET
  449.   mCHSET TEXTEQU <arg1>
  450.  
  451.   FOR ARG, <arglist>
  452.   mCHSET CATSTR <ARG>, <!,>, mCHSET
  453.   ENDM
  454.  
  455.   EXITM <mCHSET>
  456. endm
  457.  
  458. tem_alphatoint macro arg
  459.  
  460.     IFIDNI <arg>, <0>
  461.       EXITM <0>
  462.     ELSEIFIDNI <arg>, <1>
  463.       EXITM <1>
  464.     ELSEIFIDNI <arg>, <2>  
  465.       EXITM <2>
  466.     ELSEIFIDNI <arg>, <3>
  467.       EXITM <3>
  468.     ELSEIFIDNI <arg>, <4>  
  469.       EXITM <4>
  470.      ELSEIFIDNI <arg>, <5>
  471.       EXITM <5>
  472.     ELSEIFIDNI <arg>, <6>
  473.       EXITM <6>
  474.     ELSEIFIDNI <arg>, <7>
  475.       EXITM <7>
  476.     ELSEIFIDNI <arg>, <8>
  477.       EXITM <8>
  478.     ELSEIFIDNI <arg>, <9>
  479.       EXITM <9>
  480.     ELSEIFIDNI <arg>, <A>  
  481.       EXITM <10>
  482.     ELSEIFIDNI <arg>, <B>
  483.       EXITM <11>
  484.     ELSEIFIDNI <arg>, <C>  
  485.       EXITM <12>
  486.      ELSEIFIDNI <arg>, <D>
  487.       EXITM <13>
  488.     ELSEIFIDNI <arg>, <E>
  489.       EXITM <14>
  490.     ELSEIFIDNI <arg>, <F>
  491.       EXITM <15>
  492.     ELSE
  493.       ERRORS_ASSERT
  494.     ENDIF
  495. endm
  496.  
  497. tem_push_arg macro arglist0:vararg
  498.  
  499.   ;; e.g. "eax>7&00Ah", "ecx<5&ecx"
  500.   ;; op } shift right 0
  501.   ;; op { shift left 1
  502.   ;; op + add 2
  503.   ;; op - sub 3
  504.   ;; op & and 4
  505.   ;; op ^ xor 5
  506.   ;; op | or 6
  507.   ;; op ~ ror right 7
  508.   ;; op ? 8 LhsOut rhs link sym, after ?, must offer a op symbol
  509.  
  510.   ;; src/dst : reg or imm (e.g. 0A00h, 1, 2, 3)
  511.   ;;
  512.   ;; Z0-ZF Mapper register 0-15 (current)
  513.   ;; U0-UF Mapper register 0-15 (sys/user)
  514.   ;; Q0-QF Mapper register 0-15 (irq) F:=SPSR
  515.   ;; M0-MF Mapper register 0-15 (mgr) F:=SPSR
  516.   ;; O0-O1 pipeline opcode
  517.   ;;
  518.   ;; $alu, get value register index, outval
  519.  
  520.   LOCAL mRSC_POS  ;; LhsOut's end pos
  521.   LOCAL mLEN
  522.   LOCAL mID
  523.   LOCAL mOP
  524.   LOCAL mT
  525.   LOCAL mT2
  526.   LOCAL mT3
  527.   LOCAL mSET_TYPE ;;
  528.   LOCAL mTEMP
  529.   LOCAL mID2
  530.   LOCAL mTEMP2
  531.   LOCAL mSIGJ
  532.   LOCAL mACRG
  533.   LOCAL mCC
  534.   LOCAL mDIS
  535.   LOCAL mLINK
  536.   LOCAL mAGQ
  537.  
  538.   FOR arg, <arglist0>
  539.  
  540.     mRSC_POS = 1
  541.     mLEN  = @SizeStr (arg)
  542.     mID = 0
  543.     mOP = -1
  544.     mSIGJ = 0
  545.     mACRG = 0
  546.     mDIS = 0
  547.     mLINK = 0
  548.     mAGQ TEXTEQU <!?>
  549.    
  550.     FORC CHS, <arg>
  551.       IFIDN <CHS>, <!#>
  552.         mDIS =1
  553.       ENDIF
  554.     ENDM
  555.     IF mDIS eq 1
  556.       GOTO IBGS
  557.     ENDIF
  558.  
  559.     ;; %echo arg
  560.     FORC CHS, <arg>
  561.      ; echo CHS
  562.       mSET_TYPE = -1
  563.       mT = 0
  564.       mT2 = 0
  565.       mACRG = 0
  566.       IF mLINK ne 0
  567.         mLINK = mLINK - 1 ;; skip n.
  568.         GOTO IBGA
  569.       ENDIF
  570.       IFIDN <CHS>, <!">
  571.        IF mID eq (mLEN-1)
  572.          mSET_TYPE = 0      
  573.        ENDIF
  574.      ELSEIFIDN <CHS>, < >
  575.        ;; Skip it.  
  576.      ELSEIFIDN <CHS>, <!?>
  577.        ;; adjust pos, to rhs
  578.        mT =  mID + 2
  579.        mAGQ SUBSTR <arg>, mT, 1
  580.        mACRG = 1
  581.        mSET_TYPE = 0
  582.      ELSEIFIDN <CHS>, <!$> ;; set reg
  583.        mSIGJ = 1  
  584.        mRSC_POS = mRSC_POS + 1              
  585.      ELSEIFIDN <CHS>, <!{>
  586.        mSET_TYPE = 0
  587.      ELSEIFIDN <CHS>, <!}>  
  588.        mSET_TYPE = 1
  589.      ELSEIFIDN <CHS>, <!+>  
  590.        mSET_TYPE = 2    
  591.      ELSEIFIDN <CHS>, <!->  
  592.        mSET_TYPE = 3    
  593.      ELSEIFIDN <CHS>, <!&>  
  594.        mSET_TYPE = 4      
  595.      ELSEIFIDN <CHS>, <!^>  
  596.        mSET_TYPE = 5    
  597.      ELSEIFIDN <CHS>, <!|>    
  598.        mSET_TYPE = 6  
  599.      ELSEIFIDN <CHS>, <!~>    
  600.        mSET_TYPE = 7        
  601.      ENDIF
  602.  
  603.      IF mSET_TYPE ne -1
  604.        ;; Check MAPPER
  605.        mT =  mRSC_POS + 1
  606.        mT2 = mID - 1 - mRSC_POS + 1
  607.        mTEMP TEXTEQU @SubStr (<arg>, mT, mT2)
  608.        mT = 0
  609.        mT2= 1
  610.        mID2 = 0
  611.        %FORC CHS_N, mTEMP
  612.          IFIDNI <CHS_N>, <Z>  
  613.            mT = mID2+2
  614.            mCC SubStr mTEMP, mT, 1
  615.            mTEMP2 CATSTR <![SC_ARM7!].Regs![0>, mCC, <h*4!]>  
  616.            mT2 = 0
  617.          ELSEIFIDNI <CHS_N>, <O>
  618.            mT = mID2+2
  619.            mCC SubStr mTEMP, mT, 1
  620.            mTEMP2 CATSTR <![SC_ARM7!].Opcode![>, <0>, mCC, <h*4!]>    
  621.            mT2 = 0
  622.          ELSEIFIDNI <CHS_N>, <U> ;;sys/user
  623.            mT = mID2+2          
  624.            mCC SubStr mTEMP, mT, 1
  625.            mT3 = tem_alphatoint (%mCC)
  626.            mT2 = 0
  627.            mT3 = mT3 + 1  
  628.            mT3 = mT3 and 15    
  629.            mTEMP2 CATSTR <![SC_ARM7!].Regs![>, <0>, mCC, <h*4!]>              
  630.            IF mT3 GE 14
  631.              mTEMP2 TEXTEQU <>
  632.              mTEMP2 CATSTR <![SC_ARM7!].R1314_T![R1314b_SYSUSER>, <!(0>, mCC, <h-13!)*4!]>  
  633.            ENDIF
  634.          ELSEIFIDNI <CHS_N>, <Q> ;;IRQ  
  635.            mT = mID2+2
  636.            mCC SubStr mTEMP, mT, 1
  637.            mT3 = tem_alphatoint (%mCC)
  638.            mT3 = mT3 + 1  
  639.            mT3 = mT3 and 15    
  640.            mT2 = 0
  641.            mTEMP2 CATSTR <![SC_ARM7!].Regs![>, <0>, mCC, <h*4!]>              
  642.            IF mT3 GE 14
  643.              mTEMP2 CATSTR <![SC_ARM7!].R1314_T![R1314b_IRQ>, <!(0>, mCC, <h-13!)*4!]>  
  644.            ELSEIF mT3 EQ 0
  645.              mTEMP2 TEXTEQU <>
  646.              mTEMP2 CATSTR <![SC_ARM7!].SPSR_T![SPSRb_IRQ]>      
  647.            ENDIF        
  648.          ELSEIFIDNI <CHS_N>, <M> ;;MGR  
  649.            mT = mID2+2
  650.            mCC SubStr mTEMP, mT, 1
  651.            mT3 = tem_alphatoint (%mCC)
  652.            mT3 = mT3 + 1  
  653.            mT2 = 0
  654.            mT3 = mT3 and 15    
  655.            mTEMP2 CATSTR <![SC_ARM7!].Regs![>, <0>, mCC, <h*4!]>              
  656.            IF mT3 GE 14
  657.              mTEMP2 TEXTEQU <>
  658.              mTEMP2 CATSTR <![SC_ARM7!].R1314_T![R1314b_MGR>, <!(0>, mCC, <h-13!)*4!]>  
  659.            ELSEIF mT3 EQ 0
  660.              mTEMP2 TEXTEQU <>
  661.              mTEMP2 CATSTR <![SC_ARM7!].SPSR_T![SPSRb_MGR]>      
  662.            ENDIF
  663.          ENDIF
  664.          mID2 = mID2 +1
  665.        ENDM
  666.        IF mT2 eq 0
  667.          mTEMP TEXTEQU  mTEMP2        
  668.        ENDIF
  669.        
  670.        ;; Compile code
  671.        movd xmm7, eax
  672.        mov eax, mTEMP
  673.        movd xmm1, eax
  674.        movd eax, xmm7
  675.        
  676.        IF mOP eq -1 ;; mem/imm/reg.
  677.          movdqa xmm0, xmm1
  678.        ELSEIF mOP eq 0
  679.          movd xmm7, eax
  680.          movd xmm6, ecx
  681.          movd ecx, xmm1
  682.          movd eax, xmm0
  683.          shl eax, cl
  684.          movd xmm0, eax
  685.          movd eax, xmm7
  686.          movd ecx, xmm6
  687.        ELSEIF mOP eq 1
  688.          movd xmm7, eax
  689.          movd xmm6, ecx
  690.          movd ecx, xmm1
  691.          movd eax, xmm0
  692.          shr eax, cl
  693.          movd xmm0, eax
  694.          movd eax, xmm7
  695.          movd ecx, xmm6      
  696.        ELSEIF mOP eq 2 ;; +  mem/imm/reg.  
  697.          paddd  xmm0, xmm1          
  698.        ELSEIF mOP eq 3
  699.          psubd  xmm0, xmm1    
  700.        ELSEIF mOP eq 4 ;; &
  701.          pand  xmm0, xmm1  
  702.        ELSEIF mOP eq 5
  703.          pxor  xmm0, xmm1  
  704.        ELSEIF mOP eq 6
  705.          por  xmm0, xmm1  
  706.        ELSEIF mOP eq 7 ;; ror it.
  707.          movd xmm7, eax
  708.          movd xmm6, ecx
  709.          movd ecx, xmm1
  710.          movd eax, xmm0
  711.          ror eax, cl
  712.          movd xmm0, eax
  713.          movd eax, xmm7
  714.          movd ecx, xmm6
  715.        ELSE
  716.          ERRORS_ASSERT        
  717.        ENDIF  
  718.        mOP = mSET_TYPE
  719.        mRSC_POS = mID+1
  720.        
  721.        IF mACRG ne 0
  722.          mACRG = 0
  723.          mLINK = 1
  724.          mOP = -1
  725.          mRSC_POS = mID + 2
  726.          mSIGJ = 0
  727.          movdqa xmm5, xmm0
  728.        ENDIF
  729.      ENDIF
  730.      :IBGA
  731.      mID = mID + 1
  732.    ENDM
  733.    
  734.    %FORC CHS_N, mAGQ
  735.      IFIDNI <CHS_N>, <!?>
  736.        IF mSIGJ eq 1
  737.            movd xmm1, eax
  738.            movd eax, xmm0
  739.            and eax, 15
  740.            push PTR32[SC_ARM7].Regs[eax*4]
  741.            movd eax, xmm1
  742.        ELSE
  743.            movd xmm1, eax
  744.            movd eax, xmm0
  745.            push eax
  746.            movd eax, xmm1
  747.        ENDIF  
  748.      ELSE  
  749.        IFIDN <CHS_N>, <!{>
  750.          movd xmm7, eax
  751.          movd xmm6, ecx
  752.          movd ecx, xmm0
  753.          movd eax, xmm5
  754.          shl eax, cl
  755.          movd xmm5, eax
  756.          movd eax, xmm7
  757.          movd ecx, xmm6
  758.        ELSEIFIDN <CHS_N>, <!}>  
  759.          movd xmm7, eax
  760.          movd xmm6, ecx
  761.          movd ecx, xmm0
  762.          movd eax, xmm5
  763.          shr eax, cl
  764.          movd xmm5, eax
  765.          movd eax, xmm7
  766.          movd ecx, xmm6
  767.        ELSEIFIDN <CHS_N>, <!+>  
  768.          paddd xmm5, xmm0  
  769.        ELSEIFIDN <CHS_N>, <!->  
  770.          psubd xmm5, xmm0      
  771.        ELSEIFIDN <CHS_N>, <!&>  
  772.          pand xmm5, xmm0      
  773.        ELSEIFIDN <CHS_N>, <!^>  
  774.          pxor xmm5, xmm0    
  775.        ELSEIFIDN <CHS_N>, <!|>    
  776.          por xmm5, xmm0
  777.        ELSEIFIDN <CHS_N>, <!~>    
  778.          movd xmm7, eax
  779.          movd xmm6, ecx
  780.          movd ecx, xmm0
  781.          movd eax, xmm5
  782.          ror eax, cl
  783.          movd xmm5, eax
  784.          movd eax, xmm7
  785.          movd ecx, xmm6
  786.        ELSE      
  787.        ENDIF
  788.        movd xmm7, eax
  789.        movd eax, xmm5
  790.        push eax
  791.        movd eax, xmm7      
  792.      ENDIF
  793.    ENDM
  794.    
  795.    :IBGS
  796.    IF mDIS eq 1
  797.      ;; MAKE DISPLAY.
  798.      movd xmm0, eax
  799.      movd xmm1, ebx
  800.      mov eax, SC_CPSR
  801.      shr eax, ARM7_MODE_SFT_BIT
  802.      and eax, 01Fh
  803.      sub eax, 16
  804.      push PTR32 [@ModeTabs+eax*4]
  805.      movd eax, xmm0
  806.      movd ebx, xmm1
  807.      .code
  808.    ENDIF
  809.    
  810.    :IBGC
  811.  ENDM
  812. endm
  813.  
  814.  
  815. tem_print macro format, arglist:vararg
  816.  LOCAL cstr
  817.  ARGLIST_EMPTY = 0
  818.  FOR ARG,<arglist>
  819.      ARGLIST_EMPTY = ARGLIST_EMPTY + 4
  820.  ENDM
  821.  
  822.  .data
  823.  cstr db rdata_mak (format)
  824.     .code
  825.  push eax
  826.  push edx
  827.  push ecx
  828.  
  829.  %tem_push_arg tem_rev_arg (arglist)
  830.  
  831.  push offset cstr
  832.  CALLIt DEBUG_OUT
  833.  add esp, 4
  834.  add esp, ARGLIST_EMPTY
  835.  
  836.  pop ecx
  837.  pop edx
  838.  pop eax
  839. endm
  840.  
  841. IF ARM7_DEBUG ne 0
  842. OUTd equ tem_print
  843.  
  844. ELSE
  845. ;; non-debug mode
  846. OUTd macro arglist:vararg
  847. endm
  848. ENDIF
  849. OUTc equ tem_print
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856. DEBUG_BREAK equ int 3
  857.  
  858. ;; GBA Mmu Operate
  859. IF 1
  860. CALLIt macro Symbol
  861.  call Symbol
  862. endm
  863. ELSE
  864. CALLIt macro Symbol
  865.  call PTR32[Symbol]
  866. endm
  867. ENDIF
  868.  
  869. CallMemOrIO macro Symbol
  870.  push [SC_ARM7].agb
  871.  CALLIt Symbol
  872. endm
  873. CallMemOrIOAddWaitState macro Symbol
  874.  push [SC_ARM7].agb
  875.  CALLIt Symbol
  876.  add SC_WAIT, [SC_ARM7].waitState
  877. endm
  878. CallMemOrIOAddWaitState2 macro Symbol, Addr2
  879.  push Addr2
  880.  push [SC_ARM7].agb
  881.  CALLIt Symbol
  882.  add SC_WAIT, [SC_ARM7].waitState
  883. endm
  884.  
  885. Call_IRQ_Hook macro
  886.  push eax
  887.  push ecx
  888.  push edx
  889.  push [SC_ARM7].agb
  890.  CALLIt AGB_IRQ_Hook
  891.  pop edx
  892.  pop ecx
  893.  pop eax
  894. endm
  895.  
  896. Add_WaitStateClks equ add SC_WAIT, [SC_ARM7].waitState
  897.  
  898. GamePAK_Prefetch macro InternalCycle:REQ
  899.  push  InternalCycle
  900.  push  ZRS (SZ_PC)
  901.  push  [SC_ARM7].agb
  902.  CALLIt AGB_GamePakPrefetch
  903. endm
  904.  
  905. STA macro offsets
  906.  EXITM <dword ptr[esp+offsets]>
  907. endm
  908. ZRS macro offsets
  909.  EXITM <PTR32[SC_ARM7].Regs[(offsets)*4]>
  910. endm
  911.  
  912.  
  913.  
  914. SetNZCV_A macro sub_bit:REQ ;; 1 indicate sub otherwise 0
  915.  lahf
  916.  seto al
  917.  xor ah, sub_bit
  918.  mov SC_CPSR16, ax
  919. endm
  920. SetNZC_A macro sub_bit ;; 1 indicate sub otherwise 0
  921.  lahf
  922.  mov SC_CPSR16H, ah
  923. endm
  924. SetC_A macro
  925.  lahf
  926.  and SC_CPSR, not FLAG_C ;; c clear
  927.  and eax, FLAG_C ;; save c
  928.  or SC_CPSR, eax ;;c reset  
  929. endm
  930. SetNZ_A macro
  931.  lahf
  932.  and SC_CPSR, not (FLAG_N or FLAG_Z) ;; nz clear
  933.  and eax, FLAG_NZ ;; save nz
  934.  or SC_CPSR, eax ;;nz reset  
  935. endm
  936. Set_NZmul32 macro out_reg
  937.  and out_reg, out_reg
  938.  SetNZ_A
  939. endm
  940. Set_NZmul64 macro out_lo, out_hi
  941.  LOCAL SkipN
  942.  LOCAL SkipZ
  943.  
  944.  and SC_CPSR, not (FLAG_N or FLAG_Z) ;; nz clear
  945.  bt out_hi, 31
  946.  jnc SkipN
  947.  or SC_CPSR, FLAG_N
  948.  jmp SkipZ
  949. SkipN:
  950.  or out_hi, out_lo
  951.  jne SkipZ
  952.  or SC_CPSR, FLAG_Z
  953. SkipZ:
  954. endm  
  955.  
  956. ;; ToStandPSR
  957. ;; destroy :  ecx, eax
  958. ToStandPSR macro Post, REC, epx, emx
  959.  LOCAL @setZ
  960.  LOCAL @setC
  961.  LOCAL @setV
  962.  LOCAL @setOver
  963.  
  964.  mov epx, Post
  965.  mov emx, Post
  966.  rol epx, 8
  967.  and epx, 0000000FFh
  968.  test emx, FLAG_N
  969.  je @setZ
  970.  or epx, ARM7_STD_FLAGS_N
  971. @setZ:
  972.  test emx,  FLAG_Z
  973.  je @setC
  974.  or epx, ARM7_STD_FLAGS_Z
  975. @setC:
  976.  test emx,  FLAG_C
  977.  je @setV
  978.  or epx, ARM7_STD_FLAGS_C
  979. @setV:
  980.  test emx,  FLAG_V
  981.  je @setOver
  982.  or epx, ARM7_STD_FLAGS_V
  983. @setOver:
  984.  mov REC, epx
  985. endm
  986.  
  987. ;; ToFastPSR
  988. ;; destroy :  ecx, eax
  989. ToFastPSR macro Post, REC, epx, emx
  990.  
  991.  LOCAL @setZ
  992.  LOCAL @setC
  993.  LOCAL @setV
  994.  LOCAL @setOver
  995.  
  996.  mov epx, Post
  997.  mov emx, Post
  998.  ror epx, 8
  999.  and epx, 0FF000000h
  1000.  test emx, ARM7_STD_FLAGS_N
  1001.  je @setZ
  1002.  or epx, FLAG_N
  1003. @setZ:
  1004.  test emx, ARM7_STD_FLAGS_Z
  1005.  je @setC
  1006.  or epx, FLAG_Z
  1007. @setC:
  1008.  test emx, ARM7_STD_FLAGS_C
  1009.  je @setV
  1010.  or epx, FLAG_C
  1011. @setV:
  1012.  test emx, ARM7_STD_FLAGS_V
  1013.  je @setOver
  1014.  or epx, FLAG_V
  1015. @setOver:
  1016.  mov REC, epx
  1017. endm
  1018.  
  1019. ;; destroy eax, ecx
  1020. Imm8BitmapSft_AC macro Sft4Imm8, REC
  1021.  mov eax, Sft4Imm8
  1022.  mov ecx, Sft4Imm8
  1023.  and eax, 0FFh
  1024.  and ecx, 0F00h
  1025.  shr ecx, 7
  1026.  ror eax, cl
  1027.  mov REC, eax
  1028. endm
  1029.  
  1030. Imm8BitmapSft_AC_SetC macro Sft4Imm8, REC  
  1031.  LOCAL @Skip
  1032.  
  1033.  mov eax, Sft4Imm8
  1034.  mov ecx, Sft4Imm8
  1035.  and eax, 0FFh
  1036.  and ecx, 0F00h
  1037.  shr ecx, 7
  1038.  je @Skip
  1039.  ror eax, cl
  1040.  mov ecx, eax
  1041.  SetC_A
  1042.  mov eax, ecx
  1043. @Skip:
  1044.  mov REC, eax
  1045. endm
  1046.  
  1047. C_op_Care equ 0
  1048. C_op_NOCare equ 1
  1049.  
  1050. ;; XXX: better case
  1051. ShiftRegImm5 macro Post, REC, tr1c, tr2, C_op
  1052.  
  1053.  LOCAL  @END
  1054.  LOCAL @HASH
  1055.  LOCAL @LSL
  1056.  LOCAL  @LSR
  1057.  LOCAL @ASR
  1058.  LOCAL @ROR
  1059.  LOCAL @LSL_0
  1060.  LOCAL  @LSR_0
  1061.  LOCAL @ASR_0
  1062.  LOCAL @ROR_0
  1063.  
  1064.  mov tr1c, Post
  1065.  mov tr2,   Post
  1066.  shr tr1c, 5
  1067.  and tr1c, 3
  1068.  jmp @HASH[tr1c*4]
  1069.  
  1070.  Si5SftOp macro X86Sft, lSym
  1071.    mov tr1c, tr2
  1072.    and tr2, 15
  1073.    mov tr2, ZRS (tr2) ;; Get Rm.
  1074.    shr tr1c, 7
  1075.    and tr1c, 31
  1076.    je lSym
  1077.    and SC_CPSR, not FLAG_C
  1078.    X86Sft tr2, cl ;; check c
  1079.    sbb tr1c, tr1c
  1080.    and tr1c, FLAG_C
  1081.    or SC_CPSR, tr1c
  1082.    mov REC, tr2
  1083.    jmp @END
  1084.  endm
  1085.  
  1086.  @LSR:
  1087.    OUTd "LSR #%d ", "SC_INVOL}7 & 31"
  1088.    Si5SftOp shr, @LSR_0
  1089.  @LSR_0:
  1090.    and SC_CPSR, not FLAG_C
  1091.    xor tr1c, tr1c
  1092.    bt tr2, 31 ;; check c[31]
  1093.    sbb tr2, tr2
  1094.    and tr2, FLAG_C
  1095.    or SC_CPSR, tr2
  1096.    mov REC, tr1c
  1097.    jmp @END
  1098.    
  1099.  @ASR:
  1100.    OUTd "ASR #%d ", "SC_INVOL}7 & 31"
  1101.    Si5SftOp sar, @ASR_0
  1102.  @ASR_0:
  1103.    and SC_CPSR, not FLAG_C
  1104.    bt tr2, 31
  1105.    sbb tr1c, tr1c
  1106.    mov tr2, tr1c
  1107.    and tr1c, FLAG_C
  1108.    or SC_CPSR, tr1c
  1109.    mov REC, tr2
  1110.    jmp @END
  1111.    
  1112.  @ROR:
  1113.    OUTd "ROR #%d ", "SC_INVOL}7 & 31"
  1114.    Si5SftOp ror, @ROR_0
  1115.  @ROR_0: ;; RRX
  1116.    OUTd "...RRX "
  1117.    btr SC_CPSR, FLAG_CHECK_C_X86_BT
  1118.    rcr tr2,  1 ;; check c
  1119.    sbb tr1c, tr1c
  1120.    and tr1c,  FLAG_C
  1121.    or SC_CPSR, tr1c
  1122.    mov REC, tr2
  1123.    jmp @END
  1124.  
  1125.  @ALIGN_Z
  1126.  @HASH  dd @LSL, @LSR, @ASR, @ROR
  1127.  @LSL:
  1128.    OUTd "LSL #%d ", "SC_INVOL}7 & 31"
  1129.    Si5SftOp shl, @LSL_0
  1130.  @LSL_0:
  1131.    mov REC, tr2
  1132.  @END:
  1133.  OUTd "Sft Result:%08X  ", "&REC&"
  1134. endm
  1135.  
  1136. ;; XXX: better case
  1137. ShiftRegImm5_WithOutC macro Post, REC, tr1c, tr2
  1138.  
  1139.  LOCAL @END
  1140.  LOCAL @HASH
  1141.  LOCAL @LSL
  1142.  LOCAL @LSR
  1143.  LOCAL @ASR
  1144.  LOCAL @ROR
  1145.  LOCAL @LSL_0
  1146.  LOCAL @LSR_0
  1147.  LOCAL @ASR_0
  1148.  LOCAL @ROR_0
  1149.  
  1150.  mov tr1c, Post
  1151.  mov tr2, Post
  1152.  shr tr1c, 5
  1153.  and tr2, 15
  1154.  mov tr2, ZRS (tr2) ;; Get Rm.
  1155.  and tr1c, 3
  1156.  jmp @HASH[tr1c*4]
  1157.  
  1158.  Si5SftOp_WithOutC macro X86Sft, lSym
  1159.    mov tr1c, Post
  1160.    shr tr1c, 7
  1161.    and tr1c, 31
  1162.    je lSym
  1163.    X86Sft tr2, cl ;; check c
  1164.    mov REC, tr2
  1165.    jmp @END
  1166.  endm
  1167.  
  1168.  @LSR:
  1169.    OUTd "LSR #%d ", "SC_INVOL}7 & 31"
  1170.    Si5SftOp_WithOutC shr, @LSR_0
  1171.  @LSR_0:
  1172.    xor REC, REC
  1173.    jmp @END
  1174.    
  1175.  @ASR:
  1176.    OUTd "ASR #%d ", "SC_INVOL}7 & 31"
  1177.    Si5SftOp_WithOutC sar, @ASR_0
  1178.  @ASR_0:
  1179.    bt tr2, 31
  1180.    sbb REC, REC
  1181.    jmp @END
  1182.    
  1183.  @ROR:
  1184.    OUTd "ROR #%d ", "SC_INVOL}7 & 31"
  1185.    Si5SftOp_WithOutC ror, @ROR_0
  1186.  @ROR_0: ;; RRX
  1187.    OUTd "...RRX "
  1188.    bt SC_CPSR, FLAG_CHECK_C_X86_BT
  1189.    rcr tr2,  1 ;; check c
  1190.    mov REC, tr2
  1191.    jmp @END
  1192.  
  1193.  @ALIGN_Z
  1194.  @HASH  dd @LSL, @LSR, @ASR, @ROR
  1195.  
  1196.  @LSL:  
  1197.    OUTd "LSL #%d ", "SC_INVOL}7 & 31"
  1198.    Si5SftOp_WithOutC shl, @LSL_0
  1199.  @LSL_0:
  1200.    mov REC, tr2
  1201.  @END:
  1202.  OUTd "Sft Result:%08X  ", "&REC&"
  1203. endm
  1204.  
  1205. ;; XXX: better case, use inline label.
  1206. ShiftRegRs macro Post, REC, tr1c, tr2, C_op
  1207.  
  1208.  LOCAL  @END
  1209.  LOCAL @HASH
  1210.  LOCAL @LSL
  1211.  LOCAL  @LSR
  1212.  LOCAL @ASR
  1213.  LOCAL @ROR
  1214.  LOCAL @ROR_ep
  1215.  
  1216.  mov tr1c, Post
  1217.  mov tr2,   Post
  1218.  shr tr1c, 5
  1219.  and tr1c, 3
  1220. IF C_op eq C_op_NOCare
  1221.  mov [esp-8], SC_CPSR
  1222.  IF ARM7_DEBUG ne 0
  1223.    sub esp, 32
  1224.  ENDIF
  1225. ENDIF
  1226.  jmp @HASH[tr1c*4]
  1227.  
  1228.  Rs_SftOp macro X86Sft
  1229.    and SC_CPSR, not FLAG_C
  1230.    X86Sft tr2, cl ;; check c
  1231.    sbb tr1c, tr1c
  1232.    and tr1c,  FLAG_C
  1233.    or SC_CPSR, tr1c
  1234.    mov REC, tr2
  1235.    jmp @END
  1236.  endm  
  1237.  Rs_Stiff macro
  1238.    LOCAL locSym
  1239.    mov tr1c, tr2
  1240.    and tr2, 15
  1241.    cmp tr2, SZ_PC
  1242.    mov tr2, ZRS (tr2) ;; Get Rm.
  1243.    jne locSym
  1244.    add tr2, 4 ;; PC + 12, if rm in rorate shift.
  1245.  locSym:
  1246.    shr tr1c, 8
  1247.    and tr1c, 15
  1248.    mov tr1c, ZRS (tr1c) ;; Get Rs
  1249.    and tr1c, 255
  1250.    ;; TODO:better case ?
  1251.    cmp tr1c, 32
  1252.    jl @F
  1253.  endm
  1254.  
  1255.  @LSL:
  1256.    OUTd "LSL R%d ", "SC_INVOL}8 & 15"
  1257.    Rs_Stiff
  1258.    ;; Rs >= 32
  1259.    ;; ;; DEBUG_BREAK    
  1260.    sete cl
  1261.    and ecx, 1
  1262.    and SC_CPSR, not FLAG_C  
  1263.    and tr1c, tr2
  1264.    shl tr1c, FLAG_CHECK_C_X86_BT
  1265.    or SC_CPSR, tr1c
  1266.    xor REC, REC
  1267.    jmp @END
  1268.  @@:
  1269.    test tr1c, tr1c
  1270.    jne @F
  1271.    ;; Rs := 0
  1272.    mov REC, tr2
  1273.    jmp @END
  1274.  @@:
  1275.    Rs_SftOp shl
  1276.    
  1277.  @LSR:
  1278.    OUTd "LSR R%d ", "SC_INVOL}8 & 15"
  1279.    Rs_Stiff
  1280.    ;; Rs >= 32
  1281.    ;; DEBUG_BREAK
  1282.    sete cl
  1283.    and ecx, 1
  1284.    and SC_CPSR, not FLAG_C
  1285.    bt tr2, 31
  1286.    sbb tr2, tr2      
  1287.    and tr1c, tr2
  1288.    shl tr1c, FLAG_CHECK_C_X86_BT
  1289.    or SC_CPSR, tr1c
  1290.    xor REC, REC
  1291.    jmp @END
  1292.  @@:
  1293.    test tr1c, tr1c
  1294.    jne @F
  1295.    ;; Rs := 0
  1296.    mov REC, tr2
  1297.    jmp @END
  1298.  @@:
  1299.    Rs_SftOp shr  
  1300.    
  1301.  @ASR:
  1302.    OUTd "ASR R%d ", "SC_INVOL}8 & 15"
  1303.    Rs_Stiff
  1304.    ;; Rs >= 32
  1305.    ;; DEBUG_BREAK
  1306.    and SC_CPSR, not FLAG_C
  1307.    shl tr2, 1
  1308.    sbb tr2, tr2
  1309.    mov tr1c, tr2
  1310.    and tr2, 1
  1311.    shl tr2, FLAG_CHECK_C_X86_BT
  1312.    or SC_CPSR, tr2
  1313.    mov REC, tr1c
  1314.    jmp @END  
  1315.  @@:
  1316.    test tr1c, tr1c
  1317.    jne @F
  1318.    ;; Rs := 0
  1319.    mov REC, tr2
  1320.    jmp @END
  1321.  @@:
  1322.    Rs_SftOp sar  
  1323.    
  1324.  @ROR:
  1325.    OUTd "ROR R%d ", "SC_INVOL}8 & 15"
  1326.    mov tr1c, tr2
  1327.    and tr2, 15
  1328.    cmp tr2, SZ_PC
  1329.    mov tr2, ZRS (tr2) ;; Get Rm.
  1330.    jne @ROR_ep
  1331.    add tr2, 4  
  1332.  @ROR_ep:
  1333.    shr tr1c, 8
  1334.    and tr1c, 15
  1335.    mov tr1c, ZRS (tr1c) ;; Get Rs
  1336.    and tr1c, 255
  1337.    jne @F
  1338.    ;; Rs := 0
  1339.    mov REC, tr2
  1340.    jmp @END
  1341.  @@:
  1342.    and tr1c, 31
  1343.    jne @F
  1344.    and SC_CPSR, not FLAG_C
  1345.    bt tr2, 31
  1346.    sbb tr1c, tr1c
  1347.    and tr1c, FLAG_C
  1348.    or SC_CPSR, tr1c
  1349.    mov REC, tr2
  1350.    jmp @END
  1351.  @@:
  1352.    Rs_SftOp ror  
  1353.    
  1354.  @HASH  dd @LSL, @LSR, @ASR, @ROR
  1355.  @END:
  1356. IF C_op eq C_op_NOCare
  1357.  IF ARM7_DEBUG ne 0
  1358.    add esp, 32
  1359.  ENDIF
  1360.  mov SC_CPSR, [esp-8]
  1361. ENDIF
  1362.  OUTd "Sft Result:%08X  ", "&REC&"
  1363. endm
  1364.  
  1365. ;; XXX: better case, use inline label.
  1366. ShiftRegRs_WithOutC macro Post, REC, tr1c, tr2, C_op
  1367.  
  1368.  LOCAL  @END
  1369.  LOCAL @HASH
  1370.  LOCAL @LSL
  1371.  LOCAL  @LSR
  1372.  LOCAL @ASR
  1373.  LOCAL @ROR
  1374.  LOCAL @ZERO
  1375.  
  1376.  mov tr1c, Post
  1377.  mov tr2,   Post
  1378.  shr tr1c, 5
  1379.  and tr1c, 3
  1380.  jmp @HASH[tr1c*4]
  1381.  
  1382.  Rs_SftOp macro X86Sft
  1383.    X86Sft tr2, cl ;; check c
  1384.    mov REC, tr2
  1385.    jmp @END
  1386.  endm  
  1387.  Rs_Stiff macro
  1388.    mov tr1c, tr2
  1389.    and tr2, 15
  1390.    mov tr2, ZRS (tr2) ;; Get Rm.
  1391.    shr tr1c, 8
  1392.    and tr1c, 15
  1393.    mov tr1c, ZRS (tr1c) ;; Get Rs
  1394.    and tr1c, 255
  1395.    ;; TODO:better case ?
  1396.    cmp tr1c, 32
  1397.    jl @F
  1398.  endm
  1399.  
  1400.  @LSR:
  1401.    OUTd "LSR R%d ", "SC_INVOL}8 & 15"
  1402.    Rs_Stiff
  1403.    ;; Rs >= 32
  1404.    ;; ;; DEBUG_BREAK
  1405.    xor REC, REC
  1406.    jmp @END
  1407.  @@:
  1408.    test tr1c, tr1c
  1409.    je @ZERO
  1410.    Rs_SftOp shr  
  1411.    
  1412.  @ASR:
  1413.    OUTd "ASR R%d ", "SC_INVOL}8 & 15"
  1414.    Rs_Stiff
  1415.    ;; Rs >= 32
  1416.    ;; DEBUG_BREAK
  1417.    shl tr2, 1
  1418.    sbb REC, REC
  1419.    jmp @END  
  1420.  @@:
  1421.    test tr1c, tr1c
  1422.    je @ZERO
  1423.    Rs_SftOp sar  
  1424.    
  1425.  @ROR:
  1426.    OUTd "ROR R%d ", "SC_INVOL}8 & 15"
  1427.    mov tr1c, Post
  1428.    shr tr1c, 8
  1429.    and tr1c, 15
  1430.    mov tr1c, ZRS (tr1c)
  1431.    and tr1c, 31
  1432.    je @ZERO
  1433.    Rs_SftOp ror  
  1434.    
  1435.  @HASH  dd @LSL, @LSR, @ASR, @ROR
  1436.  
  1437.  @LSL:
  1438.    OUTd "LSL R%d ", "SC_INVOL}8 & 15"
  1439.    Rs_Stiff
  1440.    ;; Rs >= 32
  1441.    ;; DEBUG_BREAK
  1442.    xor REC, REC
  1443.    jmp @END
  1444.  @@:
  1445.    test tr1c, tr1c
  1446.    je @ZERO
  1447.    shl tr2, cl ;; check c
  1448.  @ZERO:
  1449.    mov REC, tr2
  1450.  @END:
  1451.  OUTd "Sft Result:%08X  ", "&REC&"
  1452. endm
  1453.  
  1454. ;; Resume CPSR from current mode's SPSR.
  1455. ;; destroy: eax, ecx, edx
  1456. SPSRToCPSR macro tr
  1457.  ;; Copy SPSR to CPSR.
  1458.  GetCurSPSRP tr
  1459.  mov tr, [tr]
  1460.  ;; Switch CPU mode.
  1461.  SwitchMode tr, 1
  1462. endm
  1463.  
  1464. SC_CPSR8 equ bl
  1465. SC_CPSR16 equ bx
  1466. SC_CPSR16H equ bh
  1467. SC_CPSR equ ebx
  1468. SC_ARM7 equ esi
  1469. SC_INVOL equ edi
  1470. SC_WAIT equ ebp
  1471.  
  1472. ;; FETCH ---------------------------------------------------------------
  1473. ARM7_ExitAddPC macro Clks:REQ
  1474.  mov ecx, ZRS (SZ_PC)
  1475.  mov ZRS (SZ_CPSR), SC_CPSR
  1476.  add ecx, 4
  1477.  and ecx,-4
  1478.  lea eax, [SC_WAIT+Clks]
  1479.  mov ZRS (SZ_PC), ecx
  1480.  pop ebx
  1481.  pop ebp
  1482.  pop esi
  1483.  pop edi
  1484.  ret
  1485. endm
  1486. tb_ExitAddPC macro Clks:REQ
  1487.  mov ecx, ZRS (SZ_PC)
  1488.  mov ZRS (SZ_CPSR), SC_CPSR
  1489.  add ecx, 2
  1490.  and ecx,-2
  1491.  lea eax, [SC_WAIT+Clks]
  1492.  mov ZRS (SZ_PC), ecx
  1493.  pop ebx
  1494.  pop ebp
  1495.  pop esi
  1496.  pop edi
  1497.  ret
  1498. endm
  1499.  
  1500. arm7_FlushPipeline macro Clks:REQ
  1501.  mov SC_INVOL, ZRS (SZ_PC)
  1502.  push SC_INVOL
  1503.  CallMemOrIOAddWaitState ARM7_FetchNoSeq
  1504.  add SC_INVOL, 4 ;; ++PC
  1505.  mov [SC_ARM7].Opcode[0], eax
  1506.  push SC_INVOL
  1507.  CallMemOrIOAddWaitState ARM7_FetchSeq
  1508.  add SC_INVOL, 4 ;; ++PC
  1509.  and SC_INVOL, -4
  1510.  mov [SC_ARM7].Opcode[4], eax          
  1511.  mov ZRS (SZ_PC), SC_INVOL
  1512.  mov ZRS (SZ_CPSR), SC_CPSR
  1513.  lea eax, [SC_WAIT+Clks]
  1514.  pop ebx
  1515.  pop ebp
  1516.  pop esi
  1517.  pop edi
  1518.  ret
  1519. endm
  1520. tb_FlushPipeline macro Clks:REQ
  1521.  mov SC_INVOL, ZRS (SZ_PC)
  1522.  push SC_INVOL
  1523.  CallMemOrIOAddWaitState tb_FetchNoSeq
  1524.  add SC_INVOL, 2 ;; ++PC
  1525.  mov [SC_ARM7].Opcode[0], eax
  1526.  push SC_INVOL
  1527.  CallMemOrIOAddWaitState tb_FetchSeq
  1528.  add SC_INVOL, 2 ;; ++PC
  1529.  and SC_INVOL, -2
  1530.  mov [SC_ARM7].Opcode[4], eax          
  1531.  mov ZRS (SZ_PC), SC_INVOL
  1532.  mov ZRS (SZ_CPSR), SC_CPSR
  1533.  lea eax, [SC_WAIT+Clks]
  1534.  pop ebx
  1535.  pop ebp
  1536.  pop esi
  1537.  pop edi
  1538.  ret
  1539. endm
  1540.  
  1541. GetRFI macro Post, BitScanStart, REC
  1542.  mov REC, Post
  1543.  shr REC, BitScanStart
  1544.  and REC, 15  
  1545. endm
  1546. GetRFIV macro Post, BitScanStart, REC
  1547.  GetRFI  Post, BitScanStart, REC
  1548.  mov REC, ZRS (REC)
  1549. endm
  1550. GetRFI_T macro Post, BitScanStart, REC
  1551.  mov REC, Post
  1552.  shr REC, BitScanStart
  1553.  and REC, 7  
  1554. endm
  1555. GetRFIV_T macro Post, BitScanStart, REC
  1556.  GetRFI_T  Post, BitScanStart, REC
  1557.  mov REC, ZRS (REC)
  1558. endm
  1559.  
  1560. GetCurSPSRP macro REC
  1561.  
  1562.  LOCAL @FIQ
  1563.  LOCAL @IRQ
  1564.  LOCAL @UDEF
  1565.  LOCAL @USYS
  1566.  LOCAL @UNUSED
  1567.  LOCAL @SVC
  1568.  LOCAL @ABT
  1569.  LOCAL @END
  1570.  LOCAL @HASH
  1571.  
  1572.  mov REC, SC_CPSR
  1573.  and REC, 00F000000h
  1574.  shr REC, 24
  1575.  jmp PTR32 @HASH [REC*4]
  1576.  
  1577.  ;; ---------------------------------------------------------------------------------
  1578.  @USYS:  
  1579.    lea REC, [SC_ARM7].SPSR_T[SPSRb_SYSUSER]
  1580.    jmp @END
  1581.  @IRQ:
  1582.    lea REC, [SC_ARM7].SPSR_T[SPSRb_IRQ]
  1583.    jmp @END
  1584.  .data
  1585.  @ALIGN_Z
  1586.  @HASH        dd @USYS, @FIQ, @IRQ, @SVC
  1587.                    dd @UNUSED, @UNUSED, @UNUSED, @ABT
  1588.                    dd @UNUSED, @UNUSED, @UNUSED, @UDEF
  1589.                    dd @UNUSED, @UNUSED, @UNUSED, @USYS
  1590.  .code
  1591.  @FIQ:
  1592.    lea REC, [SC_ARM7].SPSR_T[SPSRb_FIQ]
  1593.    jmp @END
  1594.  @UDEF:
  1595.  @ABT:
  1596.  @UNUSED:
  1597.    int 3
  1598.  @SVC:
  1599.    lea REC, [SC_ARM7].SPSR_T[SPSRb_MGR]
  1600.  @END:
  1601. endm
  1602.  
  1603. ;; switch ARM7 mode
  1604. ;; destroy: eax, ecx, edx
  1605. SwitchMode macro SG_PSR, CPSR_Copy_dis:=<0>
  1606.  
  1607.  LOCAL @FIQ
  1608.  LOCAL @IRQ
  1609.  LOCAL @UDEF
  1610.  LOCAL @USER
  1611.  LOCAL @SVC
  1612.  LOCAL @ABT
  1613.  LOCAL @UNUSED
  1614.  
  1615.  LOCAL @SPSR_TABLE
  1616.  
  1617.  LOCAL @FIQ2
  1618.  LOCAL @IRQ2  
  1619.  LOCAL @UDEF2  
  1620.  LOCAL @USER2  
  1621.  LOCAL @SVC2
  1622.  LOCAL @ABT2
  1623.  LOCAL @UNUSED2
  1624.  
  1625.  LOCAL @SPSR2_TABLE
  1626.  
  1627.  LOCAL @END
  1628.  
  1629.  push SC_WAIT  
  1630.  mov eax, SG_PSR
  1631.  mov edx, SC_CPSR
  1632.  xor ecx, ecx
  1633.  mov [SC_ARM7].calc, SC_CPSR ;; save old CPSR
  1634.  mov SC_CPSR, eax
  1635.  and eax, ARM7_MODE_GET_MASK
  1636.  and edx, ARM7_MODE_GET_MASK
  1637.  ;; Check FIQ r8_r12 bank store
  1638.  cmp eax, ARM7_MODE_FIQ_MASK
  1639.  sete cl
  1640.  cmp edx, ARM7_MODE_FIQ_MASK
  1641.  sete ch
  1642.  or cl, ch
  1643.  movzx SC_WAIT, cl
  1644.  xor ecx, ecx
  1645.  cmp eax, ARM7_MODE_USER_MASK
  1646.  sete ch
  1647.  cmp eax, ARM7_MODE_SYS_MASK
  1648.  sete cl
  1649.  or cl, ch  
  1650.  shl ecx, 24
  1651.  cmp edx, ARM7_MODE_USER_MASK
  1652.  sete ch
  1653.  cmp edx, ARM7_MODE_SYS_MASK
  1654.  sete cl
  1655.  or cl, ch
  1656.  rol ecx, 8
  1657.  and ch, cl
  1658.  jne @END
  1659.  mov ecx, [SC_ARM7].calc
  1660.  shr eax, ARM7_MODE_SFT_BIT
  1661.  shr edx, ARM7_MODE_SFT_BIT
  1662.  sub eax, ARM7_MODE_BLOCK_SUB_TOF
  1663.  sub edx, ARM7_MODE_BLOCK_SUB_TOF
  1664.  jmp PTR32 @SPSR_TABLE[edx*4]
  1665.  
  1666.  saveR8_12 macro R812Bank, Post
  1667.    mov Post, ZRS (8)
  1668.    mov [SC_ARM7].R812_T[R812Bank], Post
  1669.    mov Post, ZRS (9)
  1670.    mov [SC_ARM7].R812_T[R812Bank+4], Post
  1671.    mov Post, ZRS (10)
  1672.    mov [SC_ARM7].R812_T[R812Bank+8], Post
  1673.    mov Post, ZRS (11)
  1674.    mov [SC_ARM7].R812_T[R812Bank+12], Post
  1675.    mov Post, ZRS (12)
  1676.    mov [SC_ARM7].R812_T[R812Bank+16], Post  
  1677.  endm  
  1678.  
  1679.  loadR8_12 macro R812Bank, Post
  1680.    mov Post,  [SC_ARM7].R812_T[R812Bank]
  1681.    mov ZRS (8), Post
  1682.    mov Post,  [SC_ARM7].R812_T[R812Bank+4]
  1683.    mov ZRS (9), Post
  1684.    mov Post,  [SC_ARM7].R812_T[R812Bank+8]
  1685.    mov ZRS (10), Post
  1686.    mov Post,  [SC_ARM7].R812_T[R812Bank+12]
  1687.    mov ZRS (11), Post
  1688.    mov Post,  [SC_ARM7].R812_T[R812Bank+16]
  1689.    mov ZRS (12), Post
  1690.  endm  
  1691.  
  1692.  saveR13_14 macro R1314Bank, Post
  1693.    mov Post, ZRS (13)
  1694.    mov [SC_ARM7].R1314_T[R1314Bank], Post
  1695.    mov Post, ZRS (14)
  1696.    mov [SC_ARM7].R1314_T[R1314Bank+4], Post
  1697.  endm  
  1698.  
  1699.  loadR13_14 macro R1314Bank, Post
  1700.    mov Post,  [SC_ARM7].R1314_T[R1314Bank]
  1701.    mov ZRS (13), Post
  1702.    mov Post,  [SC_ARM7].R1314_T[R1314Bank+4]
  1703.    mov ZRS (14), Post
  1704.  endm  
  1705.  
  1706.  markBankSave macro lSym, R812Bank, R1314Bank
  1707.   LOCAL locSym
  1708.   lSym:
  1709.     test SC_WAIT, SC_WAIT
  1710.     je locSym
  1711.     saveR8_12 R812Bank, edx
  1712.   locSym:
  1713.     saveR13_14 R1314Bank, edx
  1714.     jmp PTR32 @SPSR2_TABLE[eax*4]
  1715.  endm
  1716.  
  1717.  ;; -------- Mode Current Check Save to bank --------
  1718.  markBankSave @USER, R812b_EXCEPT_FIQ, R1314b_SYSUSER
  1719.  markBankSave @FIQ, R812b_FIQ, R1314b_FIQ  
  1720.  markBankSave @IRQ, R812b_EXCEPT_FIQ, R1314b_IRQ
  1721.  markBankSave @SVC, R812b_EXCEPT_FIQ, R1314b_MGR
  1722.  markBankSave @ABT, R812b_EXCEPT_FIQ, R1314b_ABT
  1723.  markBankSave @UDEF, R812b_EXCEPT_FIQ, R1314b_UDEF  
  1724.  
  1725.  markBankLoad macro lSym, R812Bank, R1314Bank, SPSRBank
  1726.   LOCAL locSym
  1727.   lSym:
  1728.    test SC_WAIT, SC_WAIT
  1729.    je locSym
  1730.    loadR8_12 R812Bank, eax
  1731.   locSym:
  1732.    loadR13_14 R1314Bank, eax
  1733.    IF R1314Bank ne R1314b_SYSUSER
  1734.      IF CPSR_Copy_dis eq 0
  1735.        mov [SC_ARM7].SPSR_T[SPSRBank], ecx
  1736.      ENDIF
  1737.    ENDIF
  1738.    jmp @END
  1739.  endm
  1740.  
  1741.  ;; -------- Mode New Check Store to runtime regs group --------  
  1742.  markBankLoad @USER2, R812b_EXCEPT_FIQ, R1314b_SYSUSER, SPSRb_SYSUSER
  1743.  markBankLoad @FIQ2, R812b_FIQ, R1314b_FIQ, SPSRb_FIQ
  1744.  markBankLoad @IRQ2, R812b_EXCEPT_FIQ, R1314b_IRQ, SPSRb_IRQ
  1745.  markBankLoad @SVC2, R812b_EXCEPT_FIQ, R1314b_MGR, SPSRb_MGR
  1746.  markBankLoad @ABT2, R812b_EXCEPT_FIQ, R1314b_ABT, SPSRb_ABT
  1747.  markBankLoad @UDEF2, R812b_EXCEPT_FIQ, R1314b_UDEF, SPSRb_UDEF
  1748.  
  1749.  @UNUSED:
  1750.  @UNUSED2:
  1751.    int 3
  1752.  .data
  1753.  @ALIGN_Z
  1754.  @SPSR_TABLE       dd @USER, @FIQ, @IRQ, @SVC
  1755.                    dd @UNUSED, @UNUSED, @UNUSED, @ABT
  1756.                    dd @UNUSED, @UNUSED, @UNUSED, @UDEF
  1757.                    dd @UNUSED, @UNUSED, @UNUSED, @USER
  1758.  @SPSR2_TABLE       dd @USER2, @FIQ2, @IRQ2, @SVC2
  1759.                    dd @UNUSED2, @UNUSED2, @UNUSED2, @ABT2
  1760.                    dd @UNUSED2, @UNUSED2, @UNUSED2, @UDEF2
  1761.                    dd @UNUSED2, @UNUSED2, @UNUSED2, @USER2                  
  1762.  .code
  1763.  @END:
  1764.  pop SC_WAIT
  1765. endm
  1766.  
  1767. .code
  1768. ;;=====================================================================================
  1769. ;; arm7tdmi_ticks c prototype
  1770. ;; uint16_t arm7tdmi_ticks (struct arm7tdmi *arm7)
  1771. ;; ret: real exec ticks.
  1772. arm7tdmi_ticks proc c
  1773.             option prologue:none, epilogue:none
  1774.  
  1775.  push edi
  1776.  push esi
  1777.  push ebp
  1778.  push ebx
  1779.  
  1780.  STACK_PUSH equ 16
  1781.    assume SC_ARM7:ptr arm7tdmi
  1782.      xor SC_WAIT, SC_WAIT
  1783.      mov SC_ARM7, STA (4+STACK_PUSH)  
  1784.      mov SC_CPSR, ZRS (SZ_CPSR)
  1785.      ;; prefetcht0 [SC_ARM7]
  1786.      mov ax, [SC_ARM7].IFS
  1787.      and ax, [SC_ARM7].IE
  1788.      and eax, GBA_IE_IF_MASK
  1789.      bt dword ptr[SC_ARM7].IME, 0
  1790.      sbb edx, edx
  1791.      and eax, edx ;; GBA_IE_IF_MASK.
  1792.      bt SC_CPSR, IRQ_INHIBI_MASK_BIT
  1793.      sbb edx, edx
  1794.      not edx
  1795.      and eax, edx
  1796.      je e_step  
  1797. IF 0
  1798.      Call_IRQ_Hook
  1799. ENDIF
  1800.      mov eax, ZRS (SZ_PC)
  1801.      mov ecx, SC_CPSR
  1802.      and ecx, ARM7_MODE_CLR_MASK
  1803.      or ecx, ARM7_MODE_IRQ_MASK  ;; Set IRQ mode.
  1804.      and ecx, not FLAG_THUMB ;; Clear Thumb exec flag
  1805.      or ecx, IRQ_INHIBI_MASK ;; Set IRQ inhibit mask
  1806.      ;; PC to IRQ's LR, LR:= Current Instruction +4
  1807.      bt SC_CPSR, ARM7_THUMB_BIT
  1808.      sbb edx, edx
  1809.      xor edx, -1
  1810.      and edx, -4
  1811.      add edx, eax  
  1812.      mov [SC_ARM7].R1314_T[R1314b_IRQ +4], edx
  1813.      ;; Adjust PC Pointer to IRQ Interrupt vector address
  1814.      mov ZRS (SZ_PC), ARM7_VECTOR_IRQ
  1815.      mov SC_INVOL, SC_CPSR
  1816.      and SC_INVOL, ARM7_MODE_GET_MASK
  1817.      cmp SC_INVOL, ARM7_MODE_IRQ_MASK
  1818.      je @Nest_IRQ
  1819.      ;; switch Mode
  1820.      SwitchMode ecx, 0
  1821.      ;; Prefetch Opcode pipeline
  1822.      arm7_FlushPipeline 5 ;; minimum interrupt cycle delay
  1823.  @Nest_IRQ:
  1824.      mov ZRS (SZ_LRLINK), edx
  1825.      mov [SC_ARM7].SPSR_T[SPSRb_IRQ], SC_CPSR
  1826.      mov eax, ZRS (SZ_STACK)
  1827.      mov [SC_ARM7].R1314_T[R1314b_IRQ], eax
  1828.      mov eax, ZRS (SZ_LRLINK)
  1829.      mov [SC_ARM7].R1314_T[R1314b_IRQ+4], eax
  1830.      mov SC_CPSR, ecx
  1831.      ;; Prefetch Opcode pipeline
  1832.      arm7_FlushPipeline 5
  1833.        
  1834.      ;; CPU simulation.
  1835.      ;; According to the order section of the official manual DDI0210B.pdf of ARM7TDMI,
  1836.      ;; Because of the pipeline relationship, the PC pointer always points to the two instructions
  1837.      ;; after the current execution address before each instruction is executed by SC_ARM7.
  1838.      ;; This implicitly points out the following points.
  1839.      ;;
  1840.      ;; (1) Instruction execution is always in pipeline cycle >= 2 execution, which means
  1841.      ;; (2) Previous and at least two Fetch scripts (this operation may be included with specific implementation instructions)
  1842.      ;; (3) The first instruction code has been decoded, the second instruction code has been pushed to the first instruction code
  1843.    @ALIGN_Z
  1844. DEBUG_TICK macro Address
  1845.   local dm
  1846.   push eax
  1847.   mov eax, ZRS(SZ_PC)
  1848.   cmp eax, Address+8
  1849.   jne dm
  1850.   int 3
  1851. dm:
  1852.   pop eax
  1853. endm
  1854. DEBUG_TICK2 macro Address
  1855.   local dm
  1856.   push eax
  1857.   mov eax, ZRS(SZ_PC)
  1858.   cmp eax, Address+4
  1859.   jne dm
  1860.   int 3
  1861. dm:
  1862.   pop eax
  1863. endm
  1864.    e_step:
  1865.      xor SC_WAIT, SC_WAIT
  1866.      mov eax, [SC_ARM7].nextNoSeqFetch
  1867.      mov [SC_ARM7].nextNoSeqFetch, SC_WAIT
  1868.      test SC_CPSR, FLAG_THUMB
  1869.      jne @F
  1870.      ;; ARM7 Code, do next instruction's first seq/noseq read cycle
  1871.      push ZRS (SZ_PC)
  1872.      test eax, eax
  1873.      je aaf7
  1874.      CallMemOrIOAddWaitState ARM7_FetchNoSeq
  1875.      jmp nn
  1876.      aaf7:
  1877.      CallMemOrIOAddWaitState ARM7_FetchSeq
  1878.    nn:
  1879.      mov SC_INVOL, [SC_ARM7].Opcode[0]
  1880.      mov ecx, [SC_ARM7].Opcode[4]
  1881.      mov [SC_ARM7].Opcode[4], eax
  1882.      mov [SC_ARM7].Opcode[0], ecx
  1883.      mov eax, SC_INVOL
  1884.      OUTd "\n\nPC:%08X-OP:%08X-SP:%08X LR:%08X  -M:%s-\n", "ZF-8", "SC_INVOL", "ZD", "ZE", "#"
  1885.      OUTd "R0:%08X R1:%08X R2:%08X R3:%08X \n", "Z0", "Z1", "Z2", "Z3"
  1886.      OUTd "R4:%08X R5:%08X R6:%08X R7:%08X \n", "Z4", "Z5", "Z6", "Z7"
  1887.      OUTd "R8:%08X R9:%08X R10:%08X R11:%08X R12:%08X \n", "Z8", "Z9", "ZA", "ZB", "ZC"
  1888.      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"
  1889.      shr eax, 28  
  1890.      jmp fTAB[eax*4]
  1891.    @@:
  1892.      ;; Thumb Code, do next instruction's first seq/noseq read cycle
  1893.      push ZRS (SZ_PC)
  1894.      test eax, eax
  1895.      je uaf7
  1896.      CallMemOrIOAddWaitState tb_FetchNoSeq
  1897.      jmp cc
  1898.      uaf7:
  1899.      CallMemOrIOAddWaitState tb_FetchSeq
  1900.    cc:
  1901.      mov SC_INVOL, [SC_ARM7].Opcode[0]
  1902.      mov ecx, [SC_ARM7].Opcode[4]
  1903.      mov [SC_ARM7].Opcode[4], eax
  1904.      mov [SC_ARM7].Opcode[0], ecx
  1905.      OUTd "\n\nPC:%08X-OP:%04X-SP:%08X LR:%08X  -M:%s-\n", "ZF-4", "SC_INVOL & 0FFFFh","ZD", "ZE" , "#"
  1906.      OUTd "R0:%08X R1:%08X R2:%08X R3:%08X \n", "Z0", "Z1", "Z2", "Z3"
  1907.      OUTd "R4:%08X R5:%08X R6:%08X R7:%08X \n", "Z4", "Z5", "Z6", "Z7"
  1908.      OUTd "R8:%08X R9:%08X R10:%08X R11:%08X R12:%08X \n", "Z8", "Z9", "ZA", "ZB", "ZC"
  1909.      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"
  1910.      and SC_INVOL, 0FFFFh
  1911.      mov eax, SC_INVOL
  1912.      mov edx, SC_INVOL
  1913.      mov ecx, SC_INVOL
  1914.      shr ecx, 8
  1915.      and ecx, 255
  1916.      jmp sTAB[ecx*4]  
  1917.  
  1918.        ;; ARM7 Instruction Entry -----------------------------------------------------------------------------------
  1919.      AS_I8:
  1920.        OUTd "I:AS_I8;;*** "
  1921.         mov eax, edx
  1922.         and eax, 001F00000h
  1923.         shr eax, 20
  1924.         jmp i8r4TAB[eax*4]  
  1925.       SF_RS:
  1926.         OUTd "I:SF_RS;;*** "
  1927.         mov eax, edx
  1928.         and eax, 001F00000h
  1929.         shr eax, 20  
  1930.         jmp rsTAB[eax*4]
  1931.       SF_I5:
  1932.         OUTd "I:SF_I5;;*** "
  1933.         mov eax, edx
  1934.         and eax, 001F00000h
  1935.         shr eax, 20  
  1936.         jmp si5TAB[eax*4]
  1937.       A7MUL:
  1938.         OUTd "I:A7MUL;;*** "
  1939.         mov eax, edx
  1940.         and eax, 000F00000h
  1941.         shr eax, 20
  1942.         jmp ARM7_MUL_TAB[eax*4]        
  1943.       LDI12:    
  1944.         OUTd "I:LDI12;;*** "
  1945.         mov eax, edx
  1946.         and eax, 001F00000h
  1947.         shr eax, 20    
  1948.         jmp nTAB[eax*4]  
  1949.       LDIRS:
  1950.         OUTd "I:LDIRS;;*** "
  1951.         mov eax, edx
  1952.         and eax, 001F00000h
  1953.         shr eax, 20
  1954.         jmp eTAB[eax*4]          
  1955.       LDRHW: ;; FIXME
  1956.         OUTd "I:LDRHW;;*** "
  1957.         mov eax, edx
  1958.         mov ecx, edx
  1959.         and ecx, 060h
  1960.         and eax, 0100000h
  1961.         shr eax, 18
  1962.         shr ecx, 5
  1963.         or ecx,  eax ;;
  1964.         and ecx, 7
  1965.         mov eax, SC_INVOL
  1966.         and eax, 01a00000h
  1967.         shr eax, 20
  1968.         or eax, pcMTAB[ecx*4]
  1969.         test edx, 0400000h
  1970.         je @F    
  1971.         jmp cTAB[eax*4]    
  1972.      @@:jmp pTAB[eax*4]    
  1973.       RGSET:
  1974.         OUTd "I:RGSET;;*** "
  1975.         mov eax,  SC_INVOL
  1976.         shr eax, 20
  1977.         and eax, 31
  1978.         jmp zTAB[eax*4]  
  1979.        
  1980.       ;; ARM7 Instruction Entry -----------------------------------------------------------------------------------  
  1981.  
  1982.       fEQ:
  1983.         OUTd "Cond:EQ "
  1984.         test SC_CPSR, FLAG_Z
  1985.         jne fAL
  1986.       fNV:
  1987.         OUTd  ":Skip "
  1988.         ARM7_ExitAddPC 1
  1989.       fNE:  
  1990.         OUTd "Cond:NE "
  1991.         test SC_CPSR, FLAG_Z
  1992.         je fAL
  1993.         ARM7_ExitAddPC 1    
  1994.       fCS:
  1995.         OUTd "Cond:CS "
  1996.         test SC_CPSR, FLAG_C
  1997.         jne fAL
  1998.         jmp fNV
  1999.       fCC:
  2000.         OUTd "Cond:CC "
  2001.         test SC_CPSR, FLAG_C
  2002.         je fAL
  2003.         jmp fNV
  2004.       fMI:      
  2005.         OUTd "Cond:MI "
  2006.         test SC_CPSR, FLAG_N
  2007.         jne fAL  
  2008.         jmp fNV      
  2009.       fPL:
  2010.         OUTd "Cond:PL "
  2011.         test SC_CPSR, FLAG_N
  2012.         je fAL
  2013.         jmp fNV
  2014.       fVS:
  2015.         OUTd "Cond:VS "
  2016.         test SC_CPSR, FLAG_V
  2017.         jne fAL
  2018.         jmp fNV
  2019.       fVC:
  2020.         OUTd "Cond:VC "
  2021.         test SC_CPSR, FLAG_V
  2022.         je fAL
  2023.         jmp fNV
  2024.       fHI: ;; C = 1 && Z = 0
  2025.         OUTd "Cond:HI "
  2026.         mov ecx, SC_CPSR
  2027.         and ecx, FLAG_CZ
  2028.         cmp ecx, FLAG_C
  2029.         je fAL
  2030.         jmp fNV
  2031.       fLS: ;; C = 0 || Z = 1
  2032.         OUTd "Cond:LS "
  2033.         mov ecx, SC_CPSR
  2034.         and ecx, FLAG_CZ
  2035.         ;; C0Z1 ^ C1Z0 -> C1Z1
  2036.         ;; C1Z1 ^ C1Z0 -> C0Z1
  2037.         ;; C0Z0 ^ C1Z0 -> C1Z0
  2038.         ;; C1Z0 ^ C1Z0 -> ZERO.
  2039.         xor ecx, FLAG_C
  2040.         jne fAL
  2041.         jmp fNV
  2042.        
  2043.       fGE: ;; N = V
  2044.         OUTd "Cond:GE "
  2045.         mov eax, SC_CPSR
  2046.         mov ecx, SC_CPSR
  2047.         shr eax, FLAG_V_TOLSB_BIT
  2048.         shr ecx, FLAG_N_TOLSB_BIT  
  2049.         and eax, 1
  2050.         and ecx, 1
  2051.         xor eax, ecx
  2052.         je fAL
  2053.         jmp fNV
  2054.       fLT:  ;; N != V
  2055.         OUTd "Cond:LT "
  2056.         mov eax, SC_CPSR
  2057.         mov ecx, SC_CPSR
  2058.         shr eax, FLAG_V_TOLSB_BIT
  2059.         shr ecx, FLAG_N_TOLSB_BIT  
  2060.         and eax, 1
  2061.         and ecx, 1
  2062.         xor eax, ecx
  2063.         jne fAL
  2064.         jmp fNV  
  2065.       fGT: ;;    N = V  && Z= 0
  2066.         OUTd "Cond:GT "
  2067.         mov eax, SC_CPSR
  2068.         mov ecx, SC_CPSR
  2069.         shr eax, FLAG_V_TOLSB_BIT
  2070.         shr ecx, FLAG_N_TOLSB_BIT  
  2071.         and eax, 1
  2072.         and ecx, 1
  2073.         xor eax, ecx
  2074.         mov ecx, SC_CPSR
  2075.         shr ecx, FLAG_Z_TOLSB_BIT
  2076.         and ecx, 1
  2077.         or eax, ecx
  2078.         je fAL
  2079.         jmp fNV
  2080.       fLE: ;;  Z = 1 || N!=V
  2081.         OUTd "Cond:LE "
  2082.         mov eax, SC_CPSR
  2083.         mov ecx, SC_CPSR
  2084.         shr eax, FLAG_V_TOLSB_BIT
  2085.         shr ecx, FLAG_N_TOLSB_BIT  
  2086.         and eax, 1
  2087.         and ecx, 1
  2088.         xor eax, ecx
  2089.         mov ecx, SC_CPSR
  2090.         shr ecx, FLAG_Z_TOLSB_BIT
  2091.         and ecx, 1
  2092.         or eax, ecx
  2093.         je fNV  
  2094.       fAL: ;; 1110
  2095.         mov ecx, SC_INVOL
  2096.         mov eax, SC_INVOL
  2097.         mov edx, SC_INVOL
  2098.         and edx, -1
  2099.         rol ecx,  8
  2100.         nop
  2101.         rol cx, 4
  2102.         nop
  2103.         and ecx, 0FFh
  2104.         nop
  2105.         jmp jTAB[ecx*4]
  2106.        
  2107.         AND_OP equ 0
  2108.         EOR_OP equ 1
  2109.         SUB_OP equ 2 ;; With C
  2110.         RSB_OP equ 3 ;; With C
  2111.         ADD_OP equ 4 ;; With C
  2112.         ADC_OP equ 5 ;; With C
  2113.         SBC_OP equ 6 ;; With C
  2114.         RSC_OP equ 7 ;; With C
  2115.         TST_OP equ 8 ;; NORMAL SET-
  2116.         TEQ_OP equ 9 ;; NORMAL SET-
  2117.         CMP_OP equ 10 ;; With C
  2118.         CMN_OP equ 11 ;; With C
  2119.         ORR_OP equ 12
  2120.         MOV_OP equ 13
  2121.         BIC_OP equ 14
  2122.         MVN_OP equ 15
  2123.  
  2124.         ARM7_ALU_BASE macro OPID, LhsOut, Rhs
  2125.           IF OPID eq AND_OP
  2126.             and LhsOut, Rhs
  2127.           ELSEIF OPID eq EOR_OP
  2128.             xor LhsOut, Rhs
  2129.           ELSEIF OPID eq ORR_OP
  2130.             or LhsOut, Rhs  
  2131.           ELSEIF OPID eq SUB_OP
  2132.             sub LhsOut, Rhs
  2133.           ELSEIF OPID eq ADD_OP        
  2134.             add LhsOut, Rhs
  2135.           ELSEIF OPID eq MOV_OP            
  2136.             mov LhsOut, Rhs            
  2137.           ELSEIF OPID eq MVN_OP          
  2138.             not Rhs          
  2139.             mov LhsOut, Rhs    
  2140.           ELSEIF OPID eq BIC_OP          
  2141.             not Rhs                      
  2142.             and LhsOut, Rhs  
  2143.           ELSEIF OPID eq RSB_OP
  2144.             sub Rhs, LhsOut
  2145.             mov LhsOut, Rhs
  2146.           ELSEIF OPID eq SBC_OP  
  2147.             xor SC_CPSR, FLAG_C
  2148.             btc SC_CPSR, FLAG_CHECK_C_X86_BT            
  2149.             sbb LhsOut, Rhs
  2150.           ELSEIF OPID eq RSC_OP  
  2151.             xor SC_CPSR, FLAG_C
  2152.             btc SC_CPSR, FLAG_CHECK_C_X86_BT            
  2153.             sbb Rhs, LhsOut        
  2154.             mov LhsOut, Rhs  
  2155.           ELSEIF OPID eq ADC_OP  
  2156.             bt SC_CPSR, FLAG_CHECK_C_X86_BT            
  2157.             adc LhsOut, Rhs        
  2158.           ELSEIF OPID eq TST_OP  
  2159.             and LhsOut, Rhs
  2160.             SetNZ_A            
  2161.           ELSEIF OPID eq TEQ_OP        
  2162.             xor LhsOut, Rhs
  2163.             SetNZ_A        
  2164.           ELSEIF OPID eq CMP_OP  
  2165.             cmp LhsOut, Rhs
  2166.             SetNZCV_A 1            
  2167.           ELSEIF OPID eq CMN_OP  
  2168.             add LhsOut, Rhs
  2169.             SetNZCV_A 0
  2170.           ELSE
  2171.             ;;  never reach here, make a simple syntax errors
  2172.             ERRORS_ASSERT
  2173.           ENDIF
  2174.         endm
  2175.         ARM7_ALU_SIGN_BASE macro OPID, LhsOut, Rhs ;; LhsOut Must not eax!
  2176.           IF OPID eq AND_OP
  2177.             and LhsOut, Rhs
  2178.             SetNZ_A
  2179.           ELSEIF OPID eq EOR_OP
  2180.             xor LhsOut, Rhs
  2181.             SetNZ_A
  2182.           ELSEIF OPID eq ORR_OP
  2183.             or LhsOut, Rhs  
  2184.             SetNZ_A
  2185.           ELSEIF OPID eq SUB_OP
  2186.             sub LhsOut, Rhs
  2187.             SetNZCV_A 1
  2188.           ELSEIF OPID eq ADD_OP            
  2189.             add LhsOut, Rhs
  2190.             SetNZCV_A 0
  2191.           ELSEIF OPID eq MOV_OP              
  2192.             mov LhsOut, Rhs
  2193.             test LhsOut, LhsOut              
  2194.             SetNZ_A              
  2195.           ELSEIF OPID eq MVN_OP  
  2196.             not Rhs          
  2197.             mov LhsOut, Rhs  
  2198.             test LhsOut, LhsOut
  2199.             SetNZ_A              
  2200.           ELSEIF OPID eq BIC_OP  
  2201.             not Rhs                      
  2202.             and LhsOut, Rhs  
  2203.             SetNZ_A
  2204.           ELSEIF OPID eq RSB_OP
  2205.             sub Rhs, LhsOut
  2206.             mov LhsOut, Rhs
  2207.             SetNZCV_A 1
  2208.           ELSEIF OPID eq SBC_OP  
  2209.             xor SC_CPSR, FLAG_C
  2210.             bt SC_CPSR, FLAG_CHECK_C_X86_BT            
  2211.             sbb LhsOut, Rhs
  2212.             SetNZCV_A 1
  2213.           ELSEIF OPID eq RSC_OP  
  2214.             xor SC_CPSR, FLAG_C
  2215.             bt SC_CPSR, FLAG_CHECK_C_X86_BT            
  2216.             sbb Rhs, LhsOut        
  2217.             mov LhsOut, Rhs
  2218.             SetNZCV_A 1
  2219.           ELSEIF OPID eq ADC_OP  
  2220.             bt SC_CPSR, FLAG_CHECK_C_X86_BT            
  2221.             adc LhsOut, Rhs    
  2222.             SetNZCV_A 0            
  2223.           ELSE
  2224.             ;;  never reach here, make a simple syntax errors
  2225.             ERRORS_ASSERT
  2226.           ENDIF
  2227.         endm  
  2228.        
  2229.         i8r4_ALU macro lSym, OPID
  2230.           @ALIGN_Z
  2231.           i8r4&lSym:    
  2232.           ;; Clks 1: ALU Operate, and MemAccess Seq Read Next Opcode, indicate next mREQ:0 Seq:0
  2233.           IF (OPID and 1100b) ne 1000b
  2234.             Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm  
  2235.           ELSEIF (OPID and 1100b) eq 1000b
  2236.             Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm  
  2237.           ENDIF
  2238.           GetRFIV SC_INVOL, 16, ecx        ;; Rn
  2239.           GetRFI SC_INVOL, 12, edx       ;; RdIs  
  2240.           ARM7_ALU_BASE_OUTd1 OPID      
  2241.           ARM7_ALU_BASE OPID, ecx, eax
  2242.           IF (OPID and 1100b) ne 1000b    
  2243.             ;; Write Back, Check R15.
  2244.             mov ZRS (edx), ecx
  2245.             cmp edx, 15
  2246.             jne  @F
  2247.             ;; dest := pc
  2248.             ;; Clks 2: MemAccess, NoSeq Read. (because current is new pc read first), indicate next mREQ:0 Seq:1
  2249.             ;; Clks 3: MemAccess (new pc read, second), Seq Read.
  2250.             arm7_FlushPipeline 3
  2251.             @@:    
  2252.           ENDIF
  2253.           ARM7_ExitAddPC 1
  2254.           IF (OPID and 1100b) ne 1000b
  2255.             @ALIGN_Z
  2256.             i8r4&lSym&S:
  2257.             ;; Save Old CPSR
  2258.             mov [SC_ARM7].calc, SC_CPSR
  2259.             IF OPID eq AND_OP
  2260.               Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm  
  2261.             ELSEIF OPID eq EOR_OP  
  2262.               Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm  
  2263.             ELSEIF OPID eq ORR_OP  
  2264.               Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm  
  2265.             ELSEIF OPID eq SUB_OP ;; with C
  2266.               Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm  
  2267.             ELSEIF OPID eq ADD_OP ;; with C    
  2268.               Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm            
  2269.             ELSEIF OPID eq MOV_OP    
  2270.               Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm            
  2271.             ELSEIF OPID eq MVN_OP    
  2272.               Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm            
  2273.             ELSEIF OPID eq BIC_OP        
  2274.               Imm8BitmapSft_AC_SetC SC_INVOL, eax   ;; Rm            
  2275.             ELSEIF OPID eq RSB_OP ;; with C
  2276.               Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm  
  2277.             ELSEIF OPID eq SBC_OP ;; with C
  2278.               Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm  
  2279.             ELSEIF OPID eq RSC_OP ;; with C  
  2280.               Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm  
  2281.             ELSEIF OPID eq ADC_OP ;; with C
  2282.               Imm8BitmapSft_AC SC_INVOL, eax   ;; Rm          
  2283.             ELSE
  2284.               ;;  never reach here, make a simple syntax errors
  2285.               ERRORS_ASSERT
  2286.             ENDIF
  2287.             GetRFIV SC_INVOL, 16, ecx        ;; Rn
  2288.             GetRFI SC_INVOL, 12, edx       ;; RdIs
  2289.             ARM7_ALU_SIGN_BASE_OUTd1 OPID
  2290.             ARM7_ALU_SIGN_BASE OPID, ecx, eax  
  2291.             mov ZRS (edx), ecx  
  2292.             cmp edx, 15
  2293.             je @F
  2294.             ARM7_ExitAddPC 1  
  2295.           @@:
  2296.             ;; R15 resume old CPSR.
  2297.             mov SC_CPSR, [SC_ARM7].calc
  2298.             SPSRToCPSR edx
  2299.             test SC_CPSR, FLAG_THUMB
  2300.             je @F
  2301.             tb_FlushPipeline 3
  2302.           @@:
  2303.             arm7_FlushPipeline 3          
  2304.           ENDIF
  2305.         endm
  2306.  
  2307.         si5_ALU macro lSym, OPID
  2308.           si5&lSym:  
  2309.           ARM7_ALU_BASE_OUTd2 OPID
  2310.           IF (OPID and 1100b) ne 1000b
  2311.             ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax
  2312.           ELSEIF (OPID and 1100b) eq 1000b
  2313.             ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care
  2314.           ENDIF
  2315.          
  2316.           GetRFIV edx, 16, ecx        ;; Rn
  2317.           GetRFI edx, 12, edx       ;; RdIs  
  2318.           ARM7_ALU_BASE OPID, ecx, eax  
  2319.           IF (OPID and 1100b) ne 1000b
  2320.             ;; Write Back, Check R15.
  2321.             mov ZRS (edx), ecx
  2322.             cmp edx, 15
  2323.             jne  @F
  2324.             arm7_FlushPipeline 3;; +1S +1N    
  2325.             @@:    
  2326.           ENDIF
  2327.           ARM7_ExitAddPC 1
  2328.          
  2329.           IF (OPID and 1100b) ne 1000b
  2330.             si5&lSym&S:
  2331.             ;; Save Old CPSR
  2332.             mov [SC_ARM7].calc, SC_CPSR
  2333.             IF OPID eq AND_OP
  2334.               ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care   ;; Rm  
  2335.             ELSEIF OPID eq EOR_OP  
  2336.               ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care   ;; Rm  
  2337.             ELSEIF OPID eq ORR_OP  
  2338.               ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care   ;; Rm  
  2339.             ELSEIF OPID eq SUB_OP ;; with C
  2340.               ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax   ;; Rm  
  2341.             ELSEIF OPID eq ADD_OP ;; with C    
  2342.               ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax   ;; Rm            
  2343.             ELSEIF OPID eq MOV_OP    
  2344.               ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care   ;; Rm            
  2345.             ELSEIF OPID eq MVN_OP    
  2346.               ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care   ;; Rm            
  2347.             ELSEIF OPID eq BIC_OP        
  2348.               ShiftRegImm5 SC_INVOL, eax, ecx, eax, C_op_Care   ;; Rm            
  2349.             ELSEIF OPID eq RSB_OP ;; with C
  2350.               ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax   ;; Rm  
  2351.             ELSEIF OPID eq SBC_OP ;; with C
  2352.               ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax   ;; Rm  
  2353.             ELSEIF OPID eq RSC_OP ;; with C  
  2354.               ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax   ;; Rm  
  2355.             ELSEIF OPID eq ADC_OP ;; with C
  2356.               ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, eax   ;; Rm          
  2357.             ELSE
  2358.               ;;  never reach here, make a simple syntax errors
  2359.               ERRORS_ASSERT
  2360.             ENDIF
  2361.            
  2362.             ARM7_ALU_SIGN_BASE_OUTd2 OPID        
  2363.             GetRFIV SC_INVOL, 16, ecx        ;; Rn
  2364.             GetRFI SC_INVOL, 12, edx       ;; RdIs
  2365.             ARM7_ALU_SIGN_BASE OPID, ecx, eax  
  2366.             mov ZRS (edx), ecx  
  2367.             cmp edx, 15
  2368.             je @F
  2369.             ARM7_ExitAddPC 1
  2370.           @@:
  2371.             ;; R15 resume old CPSR.
  2372.             mov SC_CPSR, [SC_ARM7].calc
  2373.             SPSRToCPSR edx
  2374.             test SC_CPSR, FLAG_THUMB
  2375.             je @F
  2376.             tb_FlushPipeline 3
  2377.           @@:
  2378.             arm7_FlushPipeline 3      
  2379.           ENDIF
  2380.         endm  
  2381.  
  2382.         rs_ALU macro lSym, OPID
  2383.           LOCAL locSym
  2384.           LOCAL locSym_S
  2385.          
  2386.           rs&lSym:    
  2387.           GamePAK_Prefetch 1
  2388.           IF (OPID and 1100b) ne 1000b
  2389.             ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare
  2390.           ELSEIF (OPID and 1100b) eq 1000b
  2391.             ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care
  2392.           ENDIF
  2393.           GetRFI SC_INVOL, 16, ecx        ;; RnI
  2394.           cmp ecx, SZ_PC
  2395.           mov ecx, ZRS (ecx)
  2396.           jne locSym
  2397.           add ecx, 4
  2398.           locSym:
  2399.           GetRFI SC_INVOL, 12, edx       ;; RdIs
  2400.           ARM7_ALU_BASE_OUTd2 OPID
  2401.           ARM7_ALU_BASE OPID, ecx, eax  
  2402.           ;; In Rs Shift. Add I (Internal) Clk
  2403.           ;; In AGB, I Clk can access GamePAK Cache. (I cycle does not access memory)
  2404.           IF (OPID and 1100b) ne 1000b
  2405.             ;; Write Back, Check R15.  
  2406.             mov ZRS (edx), ecx
  2407.             cmp edx, 15
  2408.             jne  @F
  2409.             arm7_FlushPipeline 4
  2410.             @@:    
  2411.           ENDIF        
  2412.           ARM7_ExitAddPC 2
  2413.            
  2414.           IF (OPID and 1100b) ne 1000b
  2415.             rs&lSym&S:
  2416.             GamePAK_Prefetch 1
  2417.             mov [SC_ARM7].calc, SC_CPSR
  2418.             IF OPID eq AND_OP
  2419.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care   ;; Rm  
  2420.             ELSEIF OPID eq EOR_OP  
  2421.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care   ;; Rm  
  2422.             ELSEIF OPID eq ORR_OP  
  2423.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care   ;; Rm  
  2424.             ELSEIF OPID eq SUB_OP ;; with C
  2425.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare   ;; Rm  
  2426.             ELSEIF OPID eq ADD_OP ;; with C    
  2427.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare   ;; Rm            
  2428.             ELSEIF OPID eq MOV_OP    
  2429.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care   ;; Rm            
  2430.             ELSEIF OPID eq MVN_OP    
  2431.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care   ;; Rm            
  2432.             ELSEIF OPID eq BIC_OP        
  2433.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_Care   ;; Rm            
  2434.             ELSEIF OPID eq RSB_OP ;; with C
  2435.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare   ;; Rm  
  2436.             ELSEIF OPID eq SBC_OP ;; with C
  2437.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare   ;; Rm  
  2438.             ELSEIF OPID eq RSC_OP ;; with C  
  2439.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare   ;; Rm  
  2440.             ELSEIF OPID eq ADC_OP ;; with C
  2441.               ShiftRegRs SC_INVOL, eax, ecx, edx, C_op_NOCare   ;; Rm          
  2442.             ELSE
  2443.               ;;  never reach here, make a simple syntax errors
  2444.               ERRORS_ASSERT
  2445.             ENDIF
  2446.             GetRFI SC_INVOL, 16, ecx        ;; RnI
  2447.             cmp ecx, SZ_PC
  2448.             mov ecx, ZRS (ecx)
  2449.             jne locSym_S
  2450.             add ecx, 4
  2451.             locSym_S:
  2452.             GetRFI SC_INVOL, 12, edx       ;; RdIs
  2453.             ARM7_ALU_SIGN_BASE_OUTd2 OPID
  2454.             ARM7_ALU_SIGN_BASE OPID, ecx, eax  
  2455.             mov ZRS (edx), ecx  
  2456.             cmp edx, 15
  2457.             je @F
  2458.             ARM7_ExitAddPC 2
  2459.           @@:
  2460.             ;; R15 resume old CPSR.
  2461.             mov SC_CPSR, [SC_ARM7].calc
  2462.             SPSRToCPSR edx
  2463.             test SC_CPSR, FLAG_THUMB
  2464.             je @F
  2465.             tb_FlushPipeline 4
  2466.           @@:
  2467.             arm7_FlushPipeline 4    
  2468.           ENDIF
  2469.         endm
  2470.        
  2471.         ;; ------------------------- ALU+Imm8+Sft            
  2472.         ;;  27 26 25 24 23 22 21 20   19 - 16     15 - 12       11 10 9 8  7 6 5 4  3 2 1 0
  2473.         ;;   0  0  1    Opcode    S      Rn          Rd             Imm8+Sft
  2474.         ;;   0  0  1  1  0  R  1  0    fmask        SBO             Imm8+Sft  
  2475.         i8r4_ALU AND, AND_OP
  2476.         i8r4_ALU EOR, EOR_OP      
  2477.         i8r4_ALU SUB, SUB_OP    
  2478.         i8r4_ALU RSB, RSB_OP  
  2479.         i8r4_ALU ADD, ADD_OP
  2480.         i8r4_ALU ADC, ADC_OP      
  2481.         i8r4_ALU SBC, SBC_OP    
  2482.         i8r4_ALU RSC, RSC_OP
  2483.         i8r4_ALU TST, TST_OP
  2484.         i8r4_ALU TEQ, TEQ_OP      
  2485.         i8r4_ALU CMP, CMP_OP    
  2486.         i8r4_ALU CMN, CMN_OP  
  2487.         i8r4_ALU ORR, ORR_OP
  2488.         i8r4_ALU MOV, MOV_OP      
  2489.         i8r4_ALU BIC, BIC_OP    
  2490.         i8r4_ALU MVN, MVN_OP
  2491.         mUB:  
  2492.         i8r4UB:  
  2493.           int 3  
  2494.          
  2495.         ;;  ------------------------- ALU+Imm5            
  2496.         ;;  27 26 25 24 23 22 21 20   19 - 16     15 - 12       11 10 9 8  7 6 5 4  3 2 1 0
  2497.         ;;   0  0  0    Opcode    S      Rn          Rd             Imm5     T T 0    Rm
  2498.         ;;   0  0  0  1  0  R  1  0    fmask        SBO             SBZ    0 0 0 0    Rm  MSR PSR,  Rm    
  2499.         si5_ALU AND, AND_OP
  2500.         si5_ALU EOR, EOR_OP      
  2501.         si5_ALU SUB, SUB_OP    
  2502.         si5_ALU RSB, RSB_OP  
  2503.         si5_ALU ADD, ADD_OP
  2504.         si5_ALU ADC, ADC_OP      
  2505.         si5_ALU SBC, SBC_OP    
  2506.         si5_ALU RSC, RSC_OP
  2507.         si5_ALU TST, TST_OP
  2508.         si5_ALU TEQ, TEQ_OP      
  2509.         si5_ALU CMP, CMP_OP    
  2510.         si5_ALU CMN, CMN_OP  
  2511.         si5_ALU ORR, ORR_OP
  2512.         si5_ALU MOV, MOV_OP      
  2513.         si5_ALU BIC, BIC_OP    
  2514.         si5_ALU MVN, MVN_OP
  2515.        
  2516.         ;;  ------------------------- ALU+RegSft            
  2517.         ;;  27 26 25 24 23 22 21 20   19 - 16     15 - 12       11 10 9 8  7 6 5 4  3 2 1 0
  2518.         ;;   0  0  0    Opcode    S      Rn          Rd             Rs     0 T T 1    Rm    
  2519.         rs_ALU AND, AND_OP
  2520.         rs_ALU EOR, EOR_OP      
  2521.         rs_ALU SUB, SUB_OP    
  2522.         rs_ALU RSB, RSB_OP  
  2523.         rs_ALU ADD, ADD_OP
  2524.         rs_ALU ADC, ADC_OP      
  2525.         rs_ALU SBC, SBC_OP    
  2526.         rs_ALU RSC, RSC_OP
  2527.         rs_ALU TST, TST_OP
  2528.         rs_ALU TEQ, TEQ_OP      
  2529.         rs_ALU CMP, CMP_OP    
  2530.         rs_ALU CMN, CMN_OP  
  2531.         rs_ALU ORR, ORR_OP
  2532.         rs_ALU MOV, MOV_OP      
  2533.         rs_ALU BIC, BIC_OP    
  2534.         rs_ALU MVN, MVN_OP
  2535.        
  2536.         ;;  ---------------------------------------------------------------------------------------------        
  2537.         ;;  27 26 25 24 23 22 21 20   19 - 16     15 - 12       11 10 9 8  7 6 5 4  3 2 1 0    
  2538.         ;;   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
  2539.         @ALIGN_Z
  2540.         rsBX: ;; BX Rn    
  2541.           GetRFIV SC_INVOL, 0, eax
  2542.           OUTd "BX R%d:%08X- PC:%08X  \n", "SC_INVOL & 15", "eax","ZF-8"
  2543.           test eax, 1
  2544.           jne @F
  2545.           and eax, -4
  2546.           mov ZRS (SZ_PC), eax
  2547.           arm7_FlushPipeline 3
  2548.         @@:
  2549.           and eax, -2
  2550.           or SC_CPSR, FLAG_THUMB ;; set thumb flag
  2551.           and eax, -2
  2552.           mov ZRS (SZ_PC), eax
  2553.           tb_FlushPipeline 3
  2554.         rsUB:  
  2555.           int 3  
  2556.         ;;  ------------------------- branch clks:3 2Seq + 1N Cycles
  2557.         ;;  27 26 25 24 23 22 21 20   19 - 16     15 - 12       11 10 9 8  7 6 5 4  3 2 1 0
  2558.         ;;   1  0  1  L          Sign Offset 24  
  2559.         JMP24: ;; without LR
  2560.           and edx, 0FFFFFFh
  2561.           bt edx, 23
  2562.           sbb ecx, ecx
  2563.           and ecx, 03F000000h  ;; save 30 bit
  2564.           or ecx, edx
  2565.           shl ecx, 2 ;; shift 2  
  2566.           OUTd "B %06X- PC:%08X LR:%08X \n", "ZF+ecx",      "ZF-8" , "ZE"
  2567.           add ZRS (SZ_PC), ecx      
  2568.           arm7_FlushPipeline 3      
  2569.         JMPLR: ;; with LR
  2570.           mov SC_INVOL, ZRS (SZ_PC)
  2571.           and edx, 0FFFFFFh
  2572.           bt edx, 23
  2573.           sbb ecx, ecx
  2574.           and ecx, 03F000000h  ;; save 30 bit
  2575.           or ecx, edx
  2576.           shl ecx, 2 ;; shift 2  
  2577.           OUTd "BL %06X- PC:%08X LR:%08X ", "ZF+ecx",      "ZF-8" , "ZE"
  2578.           add ZRS (SZ_PC), ecx  
  2579.           lea eax, [SC_INVOL-4]
  2580.           OUTd "NEW-LR:%08X \n", "eax"
  2581.           mov ZRS (SZ_LRLINK), eax ;; next pc save to LR.
  2582.           arm7_FlushPipeline 3
  2583.          
  2584.         LDR_SET macro ldrtype, pre, link  
  2585.        
  2586.           LDR_L equ 1
  2587.           LDR_W equ 2
  2588.           LDR_B equ 4
  2589.           LDR_U equ 8
  2590.           LDR_P equ 16      
  2591.          
  2592.           LDR_STD_IMM12 equ 0 ;;->
  2593.           LDR_STD_SCALED equ 1  ;;->
  2594.           LDR_EXT_LOHI8BIT equ 2 ;;->
  2595.           LDR_EXT_RNMD equ 3 ;; :: ldrtype
  2596.        
  2597.           pre&link:
  2598.          
  2599.           IF ldrtype eq LDR_STD_IMM12 or (ldrtype eq LDR_STD_SCALED)
  2600.             IF (link and LDR_L) eq 0
  2601.               OUTd "STR"        
  2602.             ELSEIF (link and LDR_L) ne 0
  2603.               OUTd "LDR"
  2604.             ENDIF
  2605.             IF (link and LDR_B) ne 0
  2606.               OUTd "B"
  2607.             ENDIF
  2608.             IF  ((link and LDR_W) ne 0) and ((link and LDR_P) eq 0)
  2609.               OUTd "T"
  2610.             ENDIF  
  2611.           ELSEIF ldrtype eq LDR_EXT_LOHI8BIT or (ldrtype eq LDR_EXT_RNMD)
  2612.             IF (link and 5) eq 4
  2613.               OUTd "STRH"
  2614.             ELSEIF  (link and 5) ne 4
  2615.               OUTd "LDR"
  2616.               IF (link and 5) eq 0
  2617.                 OUTd "H"
  2618.               ELSEIF  (link and 5) eq 1
  2619.                 OUTd "SB"              
  2620.               ELSEIF  (link and 5) eq 5
  2621.                 OUTd "SH"
  2622.               ELSE
  2623.                 ERRORS_ASSERT
  2624.               ENDIF  
  2625.             ELSE
  2626.               ERRORS_ASSERT
  2627.             ENDIF    
  2628.           ELSE
  2629.             ERRORS_ASSERT
  2630.           ENDIF    
  2631.          
  2632.           IF  (link and LDR_P) ne 0
  2633.             OUTd " R%d, [R%d, ", "SC_INVOL } 12 & 15", "SC_INVOL } 16 & 15"          
  2634.           ELSEIF (link and LDR_P) eq 0
  2635.             OUTd " R%d, [R%d], ", "SC_INVOL } 12 & 15", "SC_INVOL } 16 & 15"        
  2636.           ENDIF  
  2637.          
  2638.           IF (link and LDR_U) eq 0
  2639.             OUTd "-"
  2640.           ENDIF  
  2641.           ;; Fetch Source .
  2642.                                                   ;; P  U  X1 W X2  
  2643.                                                    ;; X1 X2     3:= LDRSH (7)
  2644.                                                    ;;        2:= STRHW (1)  
  2645.                                                    ;;        1:= LDRSB (6)
  2646.                                                    ;;        0:= LDRUH (5)
  2647.           ;; eax:temp value, ecx:rn                                      
  2648.           IF ldrtype eq LDR_STD_IMM12
  2649.             mov eax, SC_INVOL
  2650.             and eax, 0FFFh ;; GetImm12
  2651.             OUTd "#%03X", "eax"
  2652.           ELSEIF ldrtype eq LDR_STD_SCALED
  2653.             OUTd "R%d, ", "SC_INVOL & 15"
  2654.             ShiftRegImm5_WithOutC SC_INVOL, eax, ecx, edx ;; Rm Sft.
  2655.           ELSEIF ldrtype eq LDR_EXT_LOHI8BIT
  2656.             mov eax, SC_INVOL
  2657.             shl al, 4
  2658.             shr eax, 4
  2659.             and eax, 255                   ;; LO|HI
  2660.             OUTd "#%02X", "eax"    
  2661.           ELSEIF ldrtype eq LDR_EXT_RNMD      
  2662.             GetRFIV SC_INVOL,  0, eax ;; GetRm
  2663.             OUTd "R%d", "SC_INVOL & 15"
  2664.           ELSE
  2665.             ERRORS_ASSERT
  2666.           ENDIF
  2667.          
  2668.           IF  (link and LDR_P) ne 0
  2669.             OUTd "]"          
  2670.             IF  (link and LDR_W) ne 0
  2671.               OUTd "!"
  2672.             ENDIF      
  2673.           ENDIF
  2674.          
  2675.           GetRFI SC_INVOL,  16, ecx ;; GetRn
  2676.           GetRFI SC_INVOL,  12, SC_INVOL ;; GetRd
  2677.          
  2678.           IF (link and LDR_U) eq 0
  2679.             neg eax
  2680.           ENDIF
  2681.            
  2682.           ;; Post-Index??
  2683.           IF (link and LDR_P) eq 0
  2684.             mov edx, ZRS (ecx)
  2685.             add eax, edx
  2686.           ELSEIF (link and LDR_P) ne 0
  2687.             mov edx, eax
  2688.             add edx, ZRS (ecx)
  2689.             mov eax, edx
  2690.           ENDIF
  2691.          
  2692.           IF (((link and LDR_P) eq 0) or ((link and LDR_W) ne 0))
  2693.             mov ZRS (ecx), eax
  2694.           ENDIF
  2695.          
  2696.           ;; Check Access type
  2697.           IF ldrtype eq LDR_STD_IMM12 or (ldrtype eq LDR_STD_SCALED)
  2698.             IF (link and LDR_L) eq 0
  2699.               ;; STR. STRB
  2700.               push ZRS (SC_INVOL)
  2701.               push edx
  2702.               push [SC_ARM7].agb
  2703.               IF (link and LDR_B) ne 0              
  2704.                 CALLIt MmuWriteByteNoSeq            
  2705.               ELSEIF  (link and LDR_B) eq 0
  2706.                 ;; Is R15?? + PCSTOREOFFSET - 8
  2707.                 cmp SC_INVOL, 15
  2708.                 jne @F
  2709.                 add PTR32[esp+8], 4
  2710.               @@:
  2711.                 CALLIt MmuWriteWordNoSeq
  2712.               ENDIF  
  2713.               mov [SC_ARM7].nextNoSeqFetch, 1
  2714.               Add_WaitStateClks
  2715.               ARM7_ExitAddPC 2 ;; 2 noSEQ clks.
  2716.             ELSEIF  (link and LDR_L) ne 0
  2717.               ;; LDR. LDRB
  2718.               GamePAK_Prefetch 1
  2719.               push edx
  2720.               push [SC_ARM7].agb
  2721.               IF (link and LDR_B) ne 0  
  2722.                 CALLIt MmuReadByteNoSeq  
  2723.                 movzx eax, al
  2724.               ELSEIF  (link and LDR_B) eq 0
  2725.                 mov [SC_ARM7].calc, edx
  2726.                 CALLIt MmuReadWordNoSeq
  2727.                 mov ecx, [SC_ARM7].calc
  2728.                 and ecx, 3
  2729.                 shl ecx, 3
  2730.                 ror eax, cl
  2731.               ENDIF  
  2732.               Add_WaitStateClks
  2733.               mov ZRS (SC_INVOL), eax
  2734.               cmp SC_INVOL, 15
  2735.               je @F
  2736.              
  2737.               ARM7_ExitAddPC 3 ;; S+N+1 3Clks.
  2738.             @@:
  2739.               and ZRS (SC_INVOL), -4
  2740.               arm7_FlushPipeline 5      
  2741.             ENDIF
  2742.           ELSEIF ldrtype eq LDR_EXT_LOHI8BIT or (ldrtype eq LDR_EXT_RNMD)
  2743.             IF (link and 5) eq 4
  2744.               push ZRS (SC_INVOL)
  2745.               push edx
  2746.               CallMemOrIOAddWaitState MmuWriteHalfWordNoSeq
  2747.               mov [SC_ARM7].nextNoSeqFetch, 1
  2748.               ARM7_ExitAddPC 2 ;; 2 noSEQ clks.
  2749.             ELSEIF  (link and 5) ne 4
  2750.               push edx
  2751.               push [SC_ARM7].agb
  2752.               GamePAK_Prefetch 1
  2753.               IF (link and 5) eq 0
  2754.                 mov [SC_ARM7].calc, edx
  2755.                 CALLIt MmuReadHalfWordNoSeq
  2756.                 mov ecx, [SC_ARM7].calc
  2757.                 and eax, 0FFFFh
  2758.                 and ecx, 1
  2759.                 shl ecx, 3
  2760.                 ror eax, cl
  2761.               ELSEIF  (link and 5) eq 1
  2762.                 CALLIt MmuReadByteNoSeq
  2763.                 movsx eax, al              
  2764.               ELSEIF  (link and 5) eq 5
  2765.                 mov [SC_ARM7].calc, edx
  2766.                 CALLIt MmuReadHalfWordNoSeq
  2767.                 mov ecx, [SC_ARM7].calc  
  2768.                 mov edx, eax
  2769.                 movsx eax, ax
  2770.                 and ecx, 1      
  2771.                 je @F
  2772.                 movsx eax, dh
  2773.               @@:      
  2774.               ELSE
  2775.                 ERRORS_ASSERT
  2776.               ENDIF
  2777.               Add_WaitStateClks
  2778.               mov ZRS (SC_INVOL), eax
  2779.               cmp SC_INVOL, 15
  2780.               je @F
  2781.               ARM7_ExitAddPC 3 ;; S+N+1 3Clks.
  2782.             @@:
  2783.               and ZRS (SC_INVOL), -4
  2784.               arm7_FlushPipeline 5  
  2785.             ENDIF    
  2786.           ELSE
  2787.             ERRORS_ASSERT
  2788.           ENDIF      
  2789.         endm
  2790.        
  2791.         SWINT: ;; ARM7 Software Interrupt
  2792.           OUTd "SWI-ARM7 FUNC:%02X R0 %08X R1 %08X R2 %08X\n", "SC_INVOL & 0FFFFFFh", "Z0", "Z1", "Z2"
  2793.           mov eax, ZRS (SZ_PC)
  2794.           mov ecx, SC_CPSR
  2795.           and ecx, ARM7_MODE_CLR_MASK
  2796.           or ecx, ARM7_MODE_MGR_MASK  ;; Set SVC mode.
  2797.           and ecx, not FLAG_THUMB ;; Clear Thumb exec flag
  2798.           or ecx, IRQ_INHIBI_MASK ;; Set IRQ inhibit mask
  2799.           ;; PC to SVC's LR, LR:= Current Instruction +4
  2800.           lea edx, [eax-4]
  2801.           mov [SC_ARM7].R1314_T[R1314b_MGR+4], edx  
  2802.           ;; Adjust PC Pointer to IRQ Interrupt vector address
  2803.           mov ZRS (SZ_PC), ARM7_VECTOR_SOFTWARE
  2804.           mov SC_INVOL, SC_CPSR
  2805.           and SC_INVOL, ARM7_MODE_GET_MASK
  2806.           cmp SC_INVOL, ARM7_MODE_MGR_MASK
  2807.           je @NestSwi_ARM7
  2808.           ;; switch Mode
  2809.           SwitchMode ecx, 0
  2810.           ;; Prefetch Opcode pipeline
  2811.           arm7_FlushPipeline 3
  2812.       @NestSwi_ARM7:
  2813.           mov ZRS (SZ_LRLINK), edx
  2814.           mov [SC_ARM7].SPSR_T[SPSRb_MGR], SC_CPSR
  2815.           mov eax, ZRS (SZ_STACK)
  2816.           mov [SC_ARM7].R1314_T[R1314b_MGR], eax
  2817.           mov eax, ZRS (SZ_LRLINK)
  2818.           mov [SC_ARM7].R1314_T[R1314b_MGR+4], eax
  2819.           mov SC_CPSR, ecx
  2820.           ;; Prefetch Opcode pipeline
  2821.           arm7_FlushPipeline 3
  2822.            
  2823.            
  2824.         ;; PSR MASK In V4T Version , UseMask 0xF0000000, PrivMask 0x0000000F, State Mask 0x00000020
  2825.         ;; This means that in any case you can't control the interrupt shielding bit field through MSR.
  2826.         ;; That sounds really incredible!
  2827.         ;; Many books and software examples show that it can be controlled by MSR.
  2828.         ;; I really don't know who to trust.
  2829.         ;; See ARM Architecture Reference Manual::A4.1.39 MSR  
  2830.        
  2831.         IFDEF STRICT_MODE_PSR
  2832.           ARM7_PSR_CTL_MASK equ ARM7_PSR_MODE4BIT_MASK
  2833.         ELSE
  2834.           ARM7_PSR_CTL_MASK equ ARM7_PSR_MODE8BIT_MASK
  2835.         ENDIF
  2836.         i8r4ToCPSR:      
  2837.           Imm8BitmapSft_AC SC_INVOL, eax
  2838.           OUTd "MSR #%08X(org)", "eax"
  2839.           jmp @F
  2840.         si5ToCPSR: ;; 0   1 MSR Rs  CPSR  TODO:Check d4-d7 := 0
  2841.           OUTd "MSR R%d to cpsr_", "SC_INVOL & 15"
  2842.           GetRFIV edx, 0, eax  
  2843.          @@:
  2844.           ToFastPSR eax, eax, eax,  ecx
  2845.           ;; Limit MASK, in fact write will only affect flag and cpu mode's low 4bit in std arm7.
  2846.           OUTd " #%08X(fast) to spsr_", "eax"
  2847.           mov [SC_ARM7].calc, SC_CPSR ;;;; FIXME:
  2848.           mov ecx, SC_CPSR
  2849.           and ecx, ARM7_MODE_GET_MASK
  2850.           cmp ecx, ARM7_MODE_USER_MASK
  2851.           jne @Privilege_MSR  
  2852.           ;; USER Mode MSR.
  2853.           ;; Only Affect Flag Bit.
  2854.         @ChkSetFLags:
  2855.           test edx, FLAG_MSR_FLAGS
  2856.           je @F  
  2857.           and SC_CPSR, not ARM7_PSR_FLAG_MASK
  2858.           and eax, ARM7_PSR_FLAG_MASK
  2859.           or SC_CPSR, eax
  2860.         @@:
  2861.           test SC_CPSR, FLAG_THUMB
  2862.           je @F
  2863.           int 3
  2864.         @@:          
  2865.           ARM7_ExitAddPC 1
  2866.         @Privilege_MSR:  
  2867.           test edx, FLAG_MSR_CTL
  2868.           je @ChkSetFLags
  2869.       IF 1
  2870.          ;; PriMode MSR.
  2871.           test edx, FLAG_MSR_FLAGS
  2872.           jne @F
  2873.           mov edx, SC_CPSR        
  2874.           and edx, not ARM7_PSR_CTL_MASK
  2875.           and eax, ARM7_PSR_CTL_MASK
  2876.           or eax, edx
  2877.           or eax, ARM7_MODE_MSB_BIT_MASK
  2878.           SwitchMode eax, 1
  2879.           test SC_CPSR, FLAG_THUMB
  2880.           je @Skip
  2881.           int 3
  2882.         @Skip:          
  2883.           ARM7_ExitAddPC 1
  2884.         @@:
  2885.           mov SC_INVOL, eax
  2886.           mov edx, SC_CPSR        
  2887.           and edx, not ARM7_PSR_CTL_MASK
  2888.           and eax, ARM7_PSR_CTL_MASK
  2889.           or eax, edx
  2890.           or eax, ARM7_MODE_MSB_BIT_MASK
  2891.           SwitchMode eax, 1
  2892.           and SC_CPSR, not ARM7_PSR_FLAG_MASK
  2893.           and SC_INVOL, ARM7_PSR_FLAG_MASK
  2894.           or SC_CPSR, SC_INVOL
  2895.           test SC_CPSR, FLAG_THUMB
  2896.           je @F
  2897.           int 3
  2898.         @@:          
  2899.           ARM7_ExitAddPC 1
  2900.       ELSE
  2901.       ENDIF
  2902.         ;; TODO: assert mode, flags
  2903.         si5PSR4: ;; 1   1 MSR Rs  SPSR
  2904.           OUTd "MSR R%d to spsr_", "SC_INVOL & 15"
  2905.           GetRFIV edx, 0, eax
  2906.           ToFastPSR eax, eax, eax,  ecx
  2907.           jmp toSPSR_main
  2908.         i8r4ToSPSR:
  2909.           Imm8BitmapSft_AC SC_INVOL, eax
  2910.           OUTd "MSR #%08X(org)", "eax"
  2911.           ToFastPSR eax, eax, eax,  ecx
  2912.           OUTd " #%08X(fast) to spsr_", "eax"
  2913.         toSPSR_main:
  2914.           GetCurSPSRP ecx
  2915.           test edx, FLAG_MSR_FLAGS
  2916.           je @F
  2917.           mov SC_INVOL, eax
  2918.           and PTR32[ecx], not ARM7_PSR_FLAG_MASK
  2919.           and SC_INVOL, ARM7_PSR_FLAG_MASK
  2920.           or [ecx], SC_INVOL
  2921.           OUTd "f"
  2922.           @@:          
  2923.           test edx, FLAG_MSR_CTL
  2924.           je @F  
  2925.           OUTd "c"
  2926.           and PTR32[ecx], not (ARM7_PSR_CTL_MASK or ARM7_PSR_STATE_MASK)
  2927.           and eax, (ARM7_PSR_CTL_MASK or ARM7_PSR_STATE_MASK)
  2928.           or [ecx], eax
  2929.           or PTR32[ecx], ARM7_MODE_MSB_BIT_MASK
  2930.           @@:
  2931.           ARM7_ExitAddPC 1  
  2932.          
  2933.         si5PSR1: ;; 0   0 MRS Rs  CPSR
  2934.           OUTd "MRS R%d, CPSR", "SC_INVOL}12 & 15"
  2935.           ToStandPSR SC_CPSR, ecx, eax,  ecx
  2936.           jmp @F
  2937.          
  2938.         si5PSR3: ;; 1   0 MRS Rs  SPSR, TODO: Check SBO/SBZ
  2939.           OUTd "MRS R%d, SPSR", "SC_INVOL}12 & 15"
  2940.           GetCurSPSRP eax
  2941.           mov eax, [eax]
  2942.           ToStandPSR eax, ecx, eax,  ecx
  2943.         @@:
  2944.           GetRFI edx, 12, eax
  2945.           and ecx, 00F00000FFh
  2946.           or ecx, 010h
  2947.           mov ZRS (eax), ecx      
  2948.           ARM7_ExitAddPC 1  
  2949.          
  2950.         ;; XXX: This macro branch is actually terrible to write.
  2951.         REGS_SET_OP macro link
  2952.        
  2953.           LOCAL stdPush
  2954.           LOCAL fiqPush
  2955.           LOCAL usrPush
  2956.           LOCAL usrPushFiq
  2957.           LOCAL usrPushFiq_R8_12
  2958.           LOCAL usrPushFiq_R13_14
  2959.           LOCAL usrPushFiq_next
  2960.           LOCAL usrPushFiq_next2      
  2961.          
  2962.           LOCAL stdPush_Q
  2963.          
  2964.           LOCAL usrPush_Q
  2965.           LOCAL stdPush_Q2
  2966.          
  2967.           LOCAL usrPush_Q2
  2968.          
  2969.           LOCAL outPush
  2970.          
  2971.           LOCAL stdPop
  2972.           LOCAL fiqPop
  2973.           LOCAL usrPop
  2974.           LOCAL usrPopFiq
  2975.           LOCAL usrPopFiq_R8_12
  2976.           LOCAL usrPopFiq_R13_14
  2977.           LOCAL usrPopFiq_next
  2978.           LOCAL usrPopFiq_next2      
  2979.           LOCAL usrPopFiqFirst
  2980.           LOCAL stdPop_Q
  2981.          
  2982.           LOCAL usrPop_Q
  2983.           LOCAL stdPop_Q2
  2984.           LOCAL stdPop_HitR15
  2985.          
  2986.           LOCAL usrPop_Q2
  2987.          
  2988.           LOCAL outPop
  2989.          
  2990.           LOCAL stdPushFirst
  2991.           LOCAL usrPushFirst
  2992.           LOCAL usrPushFiqFirst
  2993.           LOCAL stdPopFirst
  2994.           LOCAL usrPopFirst      
  2995.           LOCAL usrPopFiqFirst
  2996.          
  2997.          
  2998.           LOCAL LDM_empty
  2999.          
  3000.           LOCAL STM_empty
  3001.          
  3002.          
  3003.         z&link:
  3004.           ;; have to use variables.
  3005.         LDM_STACK_REQUIRE equ 128
  3006.         RSO_L equ 1
  3007.         RSO_W equ 2
  3008.         RSO_S equ 4
  3009.         RSO_U equ 8
  3010.         RSO_P equ 16
  3011.         RnAddress equ 16
  3012.         RnIndex equ 20
  3013.         RnCount  equ 28
  3014.         Reglist equ 32
  3015.         RnWriteBack equ 36
  3016.         RnAdjust  equ 40
  3017.         RnFirst equ 44
  3018.         RnTemp equ 52
  3019.         RnTempi equ 56
  3020.            
  3021.           IF  (link and RSO_L) eq 0
  3022.             OUTd "STM"
  3023.           ELSEIF (link and RSO_L) ne 0
  3024.             OUTd "LDM"
  3025.             GamePAK_Prefetch 1 ;; I cycle before fetch new opcode.
  3026.           ENDIF
  3027.          
  3028.           IF (link and RSO_U) eq 0
  3029.             OUTd "D"
  3030.           ELSEIF (link and RSO_U) ne 0
  3031.             OUTd "I"
  3032.           ENDIF
  3033.          
  3034.           IF  (link and RSO_P)  eq 0
  3035.             OUTd "A"
  3036.           ELSEIF  (link and RSO_P)  ne 0
  3037.             OUTd "B"
  3038.           ENDIF        
  3039.          
  3040.           OUTd " R%d", "SC_INVOL } 16 & 15"
  3041.          
  3042.           IF (link and RSO_W)  ne 0
  3043.             OUTd "!"
  3044.           ENDIF
  3045.          
  3046.           OUTd ", "
  3047.           OUTd "[ R15-R12:%01X, R11-R8:%01X ", "SC_INVOL } 12 & 15", "SC_INVOL } 8 & 15"
  3048.           OUTd "  R7-R4:%01X, R3-R0:%01X ]", "SC_INVOL } 4 & 15", "SC_INVOL & 15"      
  3049.          
  3050.           IF (link and RSO_S) ne 0
  3051.             OUTd "^"
  3052.           ENDIF
  3053.          
  3054.           sub esp, LDM_STACK_REQUIRE    
  3055.           xor eax, eax                  
  3056.           mov STA (RnAddress), eax          
  3057.           mov STA (RnIndex), eax
  3058.           mov STA (RnAdjust), eax
  3059.           mov STA (RnFirst), eax
  3060.           mov STA (RnCount), eax
  3061.          
  3062.           GetRFI SC_INVOL, 16, eax ;;Rn.
  3063.           mov ecx, SC_INVOL
  3064.           mov edx, ZRS (eax) ;;GetRn
  3065.           and ecx, 0FFFFh
  3066.           mov STA (RnIndex), eax
  3067.           mov STA (RnAddress), edx    
  3068.           IF (link and RSO_U) ne 0
  3069.             mov  SC_INVOL, 4
  3070.           ELSEIF (link and RSO_U) eq 0
  3071.             mov  SC_INVOL, -4
  3072.           ENDIF
  3073.           mov STA (Reglist), ecx
  3074.           mov eax, ecx
  3075.           xor ecx, ecx
  3076.           mov edx, 16
  3077.           @@:
  3078.           shr ax, 1
  3079.           adc cx, 0  
  3080.           dec dx
  3081.           jne @B
  3082.           ;; TODO: assert 0
  3083.           shl ecx, 2
  3084.           mov edx, STA (RnAddress)
  3085.         IF (link and RSO_U) ne 0
  3086.           add  edx, ecx
  3087.         ELSEIF (link and RSO_U) eq 0
  3088.           sub  edx, ecx
  3089.           lea  eax, [edx+4]
  3090.           mov  STA (RnAddress), eax
  3091.         ENDIF
  3092.           mov STA (RnWriteBack), edx    
  3093.         IF (link and RSO_P) ne 0
  3094.           add  STA (RnAddress), SC_INVOL
  3095.         ENDIF  
  3096.         mov SC_INVOL, STA (RnAddress)
  3097.        
  3098.       ;; STM-------------------------------------------------------
  3099.       ;; STM-------------------------------------------------------    
  3100.       ;; STM-------------------------------------------------------
  3101.       IF (link and RSO_L) eq 0
  3102.         test STA (Reglist), 0FFFFh
  3103.         je STM_empty
  3104.         IF (link and RSO_W) ne 0
  3105.           ;; Check Rn's adjust
  3106.           mov ecx, STA (RnIndex)
  3107.           bt STA (Reglist), ecx
  3108.           jnc @F
  3109.           sbb edx, edx  
  3110.           ;; Check is First Vailed bit
  3111.           mov eax, edx
  3112.           shl eax, cl
  3113.           xor eax, edx
  3114.           test STA (Reglist), eax
  3115.           je @F ;; TODO: error.
  3116.           ;; Dirty register, write directly
  3117.           mov eax, STA (RnIndex)
  3118.           mov ecx, STA (RnWriteBack)
  3119.           mov ZRS (eax), ecx
  3120.           @@:
  3121.         ENDIF      
  3122.         IF (link and RSO_S) ne 0
  3123.           ;; In User mode, Check Current is user/sys mode
  3124.           ;; If hit, use std copy . (Because the user-mode cache register may not have been updated)
  3125.           mov eax, SC_CPSR
  3126.           and eax, ARM7_MODE_GET_MASK
  3127.           cmp eax, ARM7_MODE_SYS_MASK
  3128.           je stdPush
  3129.           cmp eax, ARM7_MODE_USER_MASK
  3130.           je stdPush
  3131.           cmp eax, ARM7_MODE_FIQ_MASK
  3132.           je usrPushFiq
  3133.          
  3134.           jmp usrPush              
  3135.         ELSEIF (link and RSO_S) eq 0
  3136.           jmp stdPush
  3137.         ENDIF
  3138.         ;; STM  empty -------------------------------------------------------
  3139.         STM_empty:
  3140.           mov edx, STA (RnIndex)
  3141.           push STACK_PUSH_STATUS_PUSH
  3142.           push SZ_PC    
  3143.           mov eax, ZRS (SZ_PC)
  3144.           add eax, 4
  3145.           push eax
  3146.           push ZRS (edx)
  3147.         IF (link and RSO_W) ne 0
  3148.           IF (link and RSO_U) ne 0
  3149.             add ZRS (edx), 64
  3150.           ELSE
  3151.             sub ZRS (edx), 64
  3152.           ENDIF
  3153.         ENDIF
  3154.           and ZRS (edx), -4
  3155.           CallMemOrIOAddWaitState StackWriteNoSeq
  3156.           add esp, LDM_STACK_REQUIRE
  3157.           mov [SC_ARM7].nextNoSeqFetch, 1
  3158.           ARM7_ExitAddPC 2
  3159.        
  3160.         ;; STM  User Mode -------------------------------------------------------
  3161.         usrPush:
  3162.           shr STA (Reglist), 1
  3163.           jnc @F          
  3164.           inc SC_WAIT     ;; + 1 S or N cycle    
  3165.           mov eax, STA (RnCount)
  3166.           mov ecx, ZRS (eax)
  3167.           add eax, 1
  3168.           and eax, 15
  3169.           push STACK_PUSH_STATUS_PUSH
  3170.           push eax
  3171.           cmp eax, 14
  3172.           jb usrPush_Q
  3173.           sub eax, 14
  3174.           mov ecx, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
  3175.         usrPush_Q:
  3176.           test eax, eax
  3177.           jne usrPush_Q2
  3178.           add ecx, 4
  3179.         usrPush_Q2:  
  3180.           push ecx
  3181.           mov eax, SC_INVOL
  3182.           add SC_INVOL, 4
  3183.           ;;and eax, -4
  3184.           push eax
  3185.           cmp STA (RnFirst+16), 0
  3186.           mov STA (RnFirst+16), 1
  3187.           je usrPushFirst
  3188.           CallMemOrIOAddWaitState StackWriteSeq        
  3189.           jmp @F
  3190.         usrPushFirst:
  3191.           CallMemOrIOAddWaitState StackWriteNoSeq          
  3192.         @@:
  3193.           add STA (RnCount), 1            
  3194.           cmp STA (RnCount), 16
  3195.           jb usrPush
  3196.           jmp outPush
  3197.          
  3198.         ;; STM  User Mode FIQ ----------------Will this happen to GBA?---------------------------------------
  3199.         usrPushFiq:
  3200.           shr STA (Reglist), 1
  3201.           jnc @F          
  3202.           inc SC_WAIT     ;; + 1 S or N cycle    
  3203.           mov eax, STA (RnCount)
  3204.           mov ecx, ZRS (eax)
  3205.           add eax, 1
  3206.           and eax, 15
  3207.           push STACK_PUSH_STATUS_PUSH
  3208.           push eax
  3209.           cmp eax, 9
  3210.           jb usrPushFiq_next
  3211.           cmp eax, 14  
  3212.           jb usrPushFiq_R8_12
  3213.         usrPushFiq_R8_12:
  3214.           sub eax, 9
  3215.           mov ecx, [SC_ARM7].R812_T[R812b_EXCEPT_FIQ+ eax*4]
  3216.           jmp usrPushFiq_next2
  3217.         usrPushFiq_R13_14:
  3218.           sub eax, 14
  3219.           mov ecx, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]
  3220.           jmp usrPushFiq_next2
  3221.         usrPushFiq_next:
  3222.           test eax, eax
  3223.           jne usrPushFiq_next2
  3224.           add ecx, 4
  3225.         usrPushFiq_next2:  
  3226.           push ecx
  3227.           mov eax, SC_INVOL
  3228.           add SC_INVOL, 4
  3229.           ;;and eax, -4
  3230.           push eax
  3231.           cmp STA (RnFirst+16), 0
  3232.           mov STA (RnFirst+16), 1
  3233.           je usrPushFiqFirst
  3234.           CallMemOrIOAddWaitState StackWriteSeq        
  3235.           jmp @F
  3236.         usrPushFiqFirst:
  3237.           CallMemOrIOAddWaitState StackWriteNoSeq          
  3238.         @@:
  3239.           add STA (RnCount), 1            
  3240.           cmp STA (RnCount), 16
  3241.           jb usrPushFiq
  3242.           jmp outPush
  3243.          
  3244.         ;; STM  Std Mode --------------------------------------------------------
  3245.         stdPush:
  3246.           shr STA (Reglist), 1
  3247.           jnc @F            
  3248.           inc SC_WAIT     ;; + 1 S or N cycle  
  3249.           mov eax, STA (RnCount)
  3250.           push STACK_PUSH_STATUS_PUSH
  3251.           push eax
  3252.           push ZRS (eax)
  3253.           cmp eax, 15
  3254.           jne stdPush_Q2
  3255.           add PTR32[esp], 4
  3256.         stdPush_Q2:
  3257.           mov eax, SC_INVOL
  3258.           ;;and eax, -4
  3259.           push eax
  3260.           add SC_INVOL, 4
  3261.           cmp STA (RnFirst+16), 0
  3262.           mov STA (RnFirst+16), 1
  3263.           je stdPushFirst
  3264.           CallMemOrIOAddWaitState StackWriteSeq
  3265.           jmp @F
  3266.         stdPushFirst:
  3267.           CallMemOrIOAddWaitState StackWriteNoSeq    
  3268.         @@:  
  3269.           add STA (RnCount), 1            
  3270.           cmp STA (RnCount), 16
  3271.           jb  stdPush
  3272.         outPush:  
  3273.         IF (link and RSO_W) ne 0
  3274.           mov eax, STA (RnIndex)
  3275.           mov ecx, STA (RnWriteBack)
  3276.           mov ZRS (eax), ecx  ;; TODO: RnCheck with Reglist
  3277.         ENDIF  
  3278.         mov [SC_ARM7].nextNoSeqFetch, 1
  3279.         add esp, LDM_STACK_REQUIRE
  3280.         ARM7_ExitAddPC 1
  3281.       ELSEIF (link and RSO_L) ne 0
  3282.         ;; LDM ----------------------------------------------------------------------    
  3283.         ;; LDM ----------------------------------------------------------------------
  3284.         ;; LDM ----------------------------------------------------------------------      
  3285.         test STA (Reglist), 0FFFFh
  3286.         je LDM_empty
  3287.         ;; Check Rn's adjust
  3288.         mov ecx, STA (RnIndex)
  3289.         bt STA (Reglist), ecx
  3290.         jnc @F
  3291.         mov STA (RnAdjust), 1
  3292.         @@:        
  3293.         IF (link and RSO_S) ne 0      
  3294.           test STA (Reglist), 08000h
  3295.           jne stdPop
  3296.           mov eax, SC_CPSR
  3297.           and eax, ARM7_MODE_GET_MASK
  3298.           cmp eax, ARM7_MODE_SYS_MASK
  3299.           je stdPop
  3300.           cmp eax, ARM7_MODE_USER_MASK
  3301.           je stdPop
  3302.           cmp eax, ARM7_MODE_FIQ_MASK
  3303.           je usrPopFiq
  3304.           jmp usrPop              
  3305.         ELSEIF (link and RSO_S) eq 0
  3306.           jmp stdPop
  3307.         ENDIF
  3308.         ;; LDM  reglist empty -------------------------------------------------------
  3309.         LDM_empty:
  3310.           mov ecx, STA (RnIndex)
  3311.           push ZRS(ecx)
  3312.         IF (link and RSO_W) ne 0
  3313.           IF (link and RSO_U) ne 0
  3314.             add ZRS(ecx), 64
  3315.           ELSE
  3316.             sub ZRS(ecx), 64
  3317.           ENDIF
  3318.         ENDIF
  3319.           and ZRS(ecx), -4
  3320.           CallMemOrIOAddWaitState StackReadNoSeq
  3321.           mov ZRS (SZ_PC), eax
  3322.           add esp, LDM_STACK_REQUIRE
  3323.           arm7_FlushPipeline 3
  3324.          
  3325.         ;; LDM  User Mode -------------------------------------------------------
  3326.         usrPop:
  3327.           shr STA (Reglist), 1
  3328.           jnc @F            
  3329.           inc SC_WAIT     ;; + 1 S or N cycle  
  3330.           mov eax, STA (RnCount)
  3331.           lea SC_INVOL, ZRS (eax)
  3332.           add eax, 1
  3333.           and eax, 15
  3334.           cmp eax, 14
  3335.           jb @F
  3336.           sub eax, 14
  3337.           lea SC_INVOL, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]          
  3338.         @@:
  3339.           mov eax, STA (RnAddress)
  3340.           add STA (RnAddress), 4
  3341.           ;;and eax, -4
  3342.           push eax
  3343.           cmp STA (RnFirst+4), 0
  3344.           mov STA (RnFirst+4), 1
  3345.           je usrPopFirst
  3346.           CallMemOrIOAddWaitState StackReadSeq
  3347.           mov [SC_INVOL], eax
  3348.           jmp @F
  3349.         usrPopFirst:
  3350.           CallMemOrIOAddWaitState StackReadNoSeq
  3351.           mov [SC_INVOL], eax          
  3352.         @@:      
  3353.           add STA (RnCount), 1            
  3354.           cmp STA (RnCount), 16
  3355.           jb usrPop
  3356.           jmp outPop
  3357.          
  3358.         ;; LDM  FIQ Mode ----------------Will this happen to GBA?---------------------------------------
  3359.         usrPopFiq:
  3360.           shr STA (Reglist), 1
  3361.           jnc @F            
  3362.           inc SC_WAIT     ;; + 1 S or N cycle  
  3363.           mov eax, STA (RnCount)
  3364.           lea SC_INVOL, ZRS (eax)
  3365.           add eax, 1
  3366.           and eax, 15
  3367.           cmp eax, 14
  3368.           jb usrPopFiq_next
  3369.           sub eax, 14
  3370.           lea SC_INVOL, [SC_ARM7].R1314_T[R1314b_SYSUSER+ eax*4]  
  3371.           jmp usrPopFiq_next2    
  3372.         usrPopFiq_next:
  3373.           cmp eax, 9
  3374.           jb usrPopFiq_next2
  3375.           sub eax, 9
  3376.           lea SC_INVOL, [SC_ARM7].R812_T[R812b_EXCEPT_FIQ+ eax*4]      
  3377.         usrPopFiq_next2:
  3378.           mov eax, STA (RnAddress)
  3379.           add STA (RnAddress), 4
  3380.           ;;and eax, -4
  3381.           push eax
  3382.           cmp STA (RnFirst+4), 0
  3383.           mov STA (RnFirst+4), 1
  3384.           je usrPopFiqFirst
  3385.           CallMemOrIOAddWaitState StackReadSeq
  3386.           mov [SC_INVOL], eax
  3387.           jmp @F
  3388.         usrPopFiqFirst:
  3389.           CallMemOrIOAddWaitState StackReadNoSeq  
  3390.           mov [SC_INVOL], eax
  3391.         @@:    
  3392.           add STA (RnCount), 1            
  3393.           cmp STA (RnCount), 16
  3394.           jb usrPopFiq
  3395.           jmp outPop
  3396.  
  3397.         ;; LDM  Std Mode --------------------------------------------------------
  3398.         stdPop:
  3399.           shr STA (Reglist), 1
  3400.           jnc @F            
  3401.           inc SC_WAIT     ;; + 1 S or N cycle  
  3402.           mov eax, STA (RnCount)
  3403.           lea SC_INVOL, ZRS (eax)
  3404.           mov eax, STA (RnAddress)
  3405.           add STA (RnAddress), 4
  3406.           ;;and eax, -4
  3407.           push eax
  3408.           cmp STA (RnFirst+4), 0
  3409.           mov STA (RnFirst+4), 1
  3410.           je stdPopFirst
  3411.           CallMemOrIOAddWaitState StackReadSeq
  3412.           mov [SC_INVOL], eax
  3413.           ;; Check is finial??
  3414.           cmp STA (RnCount), 15
  3415.           jne @F
  3416.           jmp stdPop_HitR15
  3417.         stdPopFirst:
  3418.           CallMemOrIOAddWaitState StackReadNoSeq
  3419.           mov [SC_INVOL], eax
  3420.           ;; Check is finial??
  3421.           cmp STA (RnCount), 15
  3422.           jne @F
  3423.         stdPop_HitR15:
  3424.           IF (link and RSO_W) ne 0
  3425.             cmp STA (RnAdjust), 1
  3426.             je stdPop_Q
  3427.             mov eax, STA (RnIndex)
  3428.             mov ecx, STA (RnWriteBack)
  3429.             mov ZRS (eax), ecx
  3430.             stdPop_Q:
  3431.           ENDIF
  3432.           IF (link and RSO_S) ne 0
  3433.             SPSRToCPSR eax  
  3434.           ENDIF
  3435.           add esp, LDM_STACK_REQUIRE
  3436.           test SC_CPSR, FLAG_THUMB
  3437.           jne stdPop_Q2
  3438.           arm7_FlushPipeline 4
  3439.         stdPop_Q2:
  3440.           tb_FlushPipeline 4
  3441.         @@:
  3442.           add STA (RnCount), 1            
  3443.           cmp STA (RnCount), 16
  3444.           jb  stdPop
  3445.         outPop:  
  3446.         IF (link and RSO_W) ne 0
  3447.           cmp STA (RnAdjust), 1
  3448.           je @F
  3449.           mov eax, STA (RnIndex)
  3450.           mov ecx, STA (RnWriteBack)
  3451.           mov ZRS (eax), ecx  
  3452.         @@:
  3453.         ENDIF  
  3454.         add esp, LDM_STACK_REQUIRE
  3455.         ARM7_ExitAddPC 2    
  3456.       ENDIF
  3457.       endm
  3458.       ;; TODO: one unit for LDM/STM
  3459.       ;; TODO: other Bank Rn!^ ?
  3460.       ;; TODO: empty load/ store
  3461.      
  3462.       A7SWP: ;; SWAP. S+2N+I
  3463.         GetRFIV SC_INVOL, 16, eax ;; Rn:= Address
  3464.         GetRFIV SC_INVOL, 0, ecx ;; Rm:    
  3465.         mov [SC_ARM7].calc, eax        
  3466.         push ecx
  3467.         push eax
  3468.         push [SC_ARM7].agb
  3469.         push eax
  3470.         push [SC_ARM7].agb
  3471.         test SC_INVOL, 00400000h
  3472.         je @F
  3473.        
  3474.         A7SWP_INLINE macro rd, wr, msk
  3475.           CALLIt rd
  3476.           add SC_WAIT, [SC_ARM7].waitState  
  3477.           GetRFI SC_INVOL, 12, SC_INVOL ;; Rd:= Rd.
  3478.           and eax, msk
  3479.           if msk eq 0FFFFFFFFh
  3480.             ;; test align rot.
  3481.             mov ecx, [SC_ARM7].calc
  3482.             and ecx, 3
  3483.             shl ecx, 3
  3484.             ror eax, cl
  3485.           endif
  3486.           mov ZRS (SC_INVOL), eax                  
  3487.           CALLIt wr    
  3488.           add SC_WAIT, [SC_ARM7].waitState
  3489.           GamePAK_Prefetch 1
  3490.           ARM7_ExitAddPC 4      
  3491.         endm
  3492.        
  3493.         OUTd "SWPB R%d, R%d, [R%d]", "SC_INVOL}12 & 15", "SC_INVOL & 15", "SC_INVOL}16 & 15"
  3494.         A7SWP_INLINE MmuReadByteNoSeq, MmuWriteByteNoSeq, 0FFh
  3495.       @@:
  3496.         OUTd "SWP R%d, R%d, [R%d]", "SC_INVOL}12 & 15", "SC_INVOL & 15", "SC_INVOL}16 & 15"
  3497.         A7SWP_INLINE MmuReadWordNoSeq, MmuWriteWordNoSeq, 0FFFFFFFFh
  3498.        
  3499.           MUL_OP equ 0
  3500.           MLA_OP equ 1
  3501.           UMUL64_OP equ 2
  3502.           UMLA64_OP equ 3  
  3503.           SMUL64_OP equ 4
  3504.           SMLA64_OP equ 5
  3505.  
  3506.           mulClks macro Post, TReg, Recv ;; XXX: TReg ^  Post ^ Recv
  3507.                                          ;; XXX: better case
  3508.          
  3509.             ;; multiplier's clks, m
  3510.             ;; see ARM7TDMI Technical Reference Manual's 6.20 Instruction speed summary
  3511.             ;; m is:
  3512.             ;; 1 if bits [31:8] of the multiplier operand (Rs) are all zero or one, else
  3513.             ;; 2 if bits [31:16] of the multiplier operand (Rs) are all zero or one, else
  3514.             ;; 3 if bits [31:24] of the multiplier operand (Rs) are all zero or all one, else
  3515.             ;; 4.
  3516.            
  3517.             bt Post, 31
  3518.             sbb TReg, TReg
  3519.             xor TReg, Post      
  3520.             movd xmm0, TReg
  3521.             pxor xmm1, xmm1
  3522.             pcmpeqb xmm1, xmm0
  3523.             pmovmskb TReg, xmm1
  3524.             shl TReg, 29  
  3525.             sbb Recv, Recv
  3526.             shl TReg, 1
  3527.             sbb Post, Post
  3528.             shl TReg, 1          
  3529.             sbb TReg, TReg
  3530.             and Post, Recv
  3531.             and TReg, Post
  3532.             add Recv, TReg
  3533.             lea Recv, [Recv+Post+4]
  3534.           endm
  3535.          
  3536.           mul_interp_b macro OPID
  3537.             GetRFIV SC_INVOL, 0, eax ;; Rm.      
  3538.             GetRFIV SC_INVOL, 8, ecx ;; Rs.                  
  3539.             IF OPID eq MUL_OP
  3540.               OUTd "MUL R%d, R%d, R%d", "SC_INVOL}16 & 15", "SC_INVOL & 15", "SC_INVOL}8 & 15"
  3541.               mul ecx
  3542.               GetRFI SC_INVOL, 16, edx ;; Rd
  3543.               mov ZRS (edx), eax  
  3544.             ELSEIF  OPID eq MLA_OP
  3545.               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"
  3546.               mul ecx        
  3547.               GetRFIV SC_INVOL, 12, edx ;; Rn
  3548.               add eax, edx
  3549.               GetRFI SC_INVOL, 16, edx ;; Rd
  3550.               mov ZRS (edx), eax              
  3551.             ELSEIF  OPID eq UMUL64_OP
  3552.               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"
  3553.               movd xmm0, ecx
  3554.               mul ecx
  3555.               GetRFI SC_INVOL, 12, ecx ;; RdLO
  3556.               GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI          
  3557.               mov ZRS (ecx), eax        
  3558.               mov ZRS (SC_INVOL), edx
  3559.               movd ecx, xmm0
  3560.             ELSEIF  OPID eq UMLA64_OP
  3561.               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"
  3562.               movd xmm0, ecx
  3563.               mul ecx
  3564.               GetRFI SC_INVOL, 12, ecx ;; RdLO
  3565.               GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI          
  3566.               add eax, ZRS (ecx)
  3567.               adc edx, ZRS (SC_INVOL)
  3568.               mov ZRS (ecx), eax        
  3569.               mov ZRS (SC_INVOL), edx
  3570.               movd ecx, xmm0            
  3571.             ELSEIF  OPID eq SMUL64_OP  
  3572.               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"            
  3573.               movd xmm0, ecx
  3574.               imul ecx
  3575.               GetRFI SC_INVOL, 12, ecx ;; RdLO
  3576.               GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI          
  3577.               mov ZRS (ecx), eax        
  3578.               mov ZRS (SC_INVOL), edx
  3579.               movd ecx, xmm0        
  3580.             ELSEIF  OPID eq SMLA64_OP
  3581.               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"
  3582.               movd xmm0, ecx
  3583.               imul ecx
  3584.               GetRFI SC_INVOL, 12, ecx ;; RdLO
  3585.               GetRFI SC_INVOL, 16, SC_INVOL ;; RdHI          
  3586.               add eax, ZRS (ecx)
  3587.               adc edx, ZRS (SC_INVOL)
  3588.               mov ZRS (ecx), eax        
  3589.               mov ZRS (SC_INVOL), edx
  3590.               movd ecx, xmm0            
  3591.             ELSE
  3592.               ERRORS_ASSERT
  3593.             ENDIF    
  3594.           endm
  3595.           mul_interp macro lSym, OPID  
  3596.            ;;LOCAL StdLink
  3597.            ;;LOCAL StdLinkWithSymbol
  3598.            LOCAL SetMClks
  3599.            
  3600.            m&lSym:
  3601.              OUTd "NOSET_SIGN "
  3602.              mul_interp_b  OPID
  3603.              jmp SetMClks
  3604.            m&lSym&S:
  3605.             OUTd "SET_SIGN "
  3606.             mul_interp_b OPID              
  3607.             IF OPID eq MUL_OP
  3608.               Set_NZmul32 eax              
  3609.             ELSEIF  OPID eq MLA_OP
  3610.               Set_NZmul32 eax                    
  3611.             ELSEIF  OPID eq UMUL64_OP
  3612.               Set_NZmul64 eax, edx
  3613.             ELSEIF  OPID eq UMLA64_OP
  3614.               Set_NZmul64 eax, edx            
  3615.             ELSEIF  OPID eq SMUL64_OP  
  3616.               Set_NZmul64 eax, edx  
  3617.             ELSEIF  OPID eq SMLA64_OP
  3618.               Set_NZmul64 eax, edx            
  3619.             ELSE
  3620.               ERRORS_ASSERT
  3621.             ENDIF    
  3622.           SetMClks:
  3623.             mulClks ecx, edx, eax
  3624.            
  3625.             IF OPID eq MUL_OP
  3626.               ;; MUL := M I Clks.  
  3627.             ELSEIF  OPID eq MLA_OP
  3628.               ;; MLA := M+1 I Clks
  3629.               add eax, 1              
  3630.             ELSEIF  OPID eq UMUL64_OP
  3631.               ;; UMULL := M+1 I Clks
  3632.               add eax, 1  
  3633.             ELSEIF  OPID eq UMLA64_OP
  3634.               ;; UMLAL := M+2 I Clks    
  3635.               add eax, 2              
  3636.             ELSEIF  OPID eq SMUL64_OP  
  3637.               ;; SMULL := M+1 I Clks  
  3638.               add eax, 1                
  3639.             ELSEIF  OPID eq SMLA64_OP
  3640.               ;; SMLAL := M+2 I Clks  
  3641.               add eax, 2              
  3642.             ELSE
  3643.               ERRORS_ASSERT
  3644.             ENDIF    
  3645.             add SC_WAIT, eax
  3646.             GamePAK_Prefetch eax
  3647.             ARM7_ExitAddPC 1
  3648.           endm  
  3649.         @ALIGN_Z                                                  
  3650.  
  3651.         mul_interp MUL, MUL_OP
  3652.         mul_interp MLA, MLA_OP      
  3653.         mul_interp UMUL64, UMUL64_OP      
  3654.         mul_interp UMLA64, UMLA64_OP
  3655.         mul_interp SMUL64, SMUL64_OP      
  3656.         mul_interp SMLA64, SMLA64_OP
  3657.        
  3658.         IRL_PUSH_b macro num
  3659.           LDR_SET LDR_STD_IMM12, n, num
  3660.           LDR_SET LDR_STD_SCALED, e, num
  3661.           LDR_SET LDR_EXT_LOHI8BIT, c, num
  3662.           LDR_SET LDR_EXT_RNMD, p, num
  3663.           REGS_SET_OP num
  3664.         endm          
  3665.        
  3666.         IRL_PUSH macro
  3667.           ID = 0
  3668.           WHILE ID ne 32
  3669.             IRL_PUSH_b %ID
  3670.             ID = ID + 1
  3671.           ENDM
  3672.         endm
  3673.        
  3674.        IRL_PUSH
  3675.         int 3
  3676.                 COPMO:
  3677.         COPDT:
  3678.         UDEFI: ;; undef opcode abnormal
  3679.          int 3
  3680.          
  3681.       ;; Thumb Instruction Entry -----------------------------------------------------------------------------------  
  3682.       ALUOP:
  3683.         SRC_cx equ ecx
  3684.         DST_i equ edx
  3685.         DST equ ZRS (DST_i)
  3686.         TMPR equ eax
  3687.         TMPR8 equ al
  3688.         ;; ALU Unwind ------------------------
  3689.         GetRFI_T SC_INVOL, 0, DST_i  ;;Rd's Index .
  3690.         GetRFIV_T SC_INVOL, 3, SRC_cx  ;;Rs/Rm/Rn
  3691.         mov TMPR, SC_INVOL
  3692.         shr TMPR, 6
  3693.         and TMPR, 15
  3694.         jmp taTAB[TMPR*4]
  3695.       taAND:
  3696.         OUTd "AND R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3697.         and DST, SRC_cx
  3698.         SetNZ_A
  3699.         tb_ExitAddPC 1
  3700.       taEOR:
  3701.         OUTd "EOR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3702.         xor DST, SRC_cx
  3703.         SetNZ_A
  3704.         tb_ExitAddPC 1    
  3705.       taORR:
  3706.         OUTd "ORR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3707.         or DST, SRC_cx
  3708.         SetNZ_A
  3709.         tb_ExitAddPC 1    
  3710.       taADC:
  3711.         OUTd "ADC R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3712.         bt SC_CPSR, FLAG_CHECK_C_X86_BT
  3713.         adc DST, SRC_cx
  3714.         SetNZCV_A 0
  3715.         tb_ExitAddPC 1
  3716.       taSBC:
  3717.         OUTd "SBC R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3718.         xor SC_CPSR, FLAG_C
  3719.         bt SC_CPSR, FLAG_CHECK_C_X86_BT
  3720.         sbb DST, SRC_cx
  3721.         SetNZCV_A 1
  3722.         tb_ExitAddPC 1
  3723.       taCMP:
  3724.         OUTd "CMP R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3725.         cmp DST, SRC_cx
  3726.         SetNZCV_A 1
  3727.         tb_ExitAddPC 1  
  3728.       taCMN:
  3729.         OUTd "CMN R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3730.         add SRC_cx, DST
  3731.         SetNZCV_A 0
  3732.         tb_ExitAddPC 1
  3733.       taTST:
  3734.         OUTd "TST R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3735.         test DST, SRC_cx
  3736.         SetNZ_A
  3737.         tb_ExitAddPC 1
  3738.       taNEG:
  3739.         mov DST, 0
  3740.         sub DST, SRC_cx
  3741.         SetNZCV_A 1
  3742.         tb_ExitAddPC 1  
  3743.       taBIC:
  3744.         OUTd "BIC R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3745.         not SRC_cx
  3746.         and DST, SRC_cx
  3747.         SetNZ_A
  3748.         tb_ExitAddPC 1      
  3749.       taMVN:
  3750.         OUTd "MVN R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3751.         xor SRC_cx, -1
  3752.         mov DST, SRC_cx
  3753.         SetNZ_A  
  3754.         tb_ExitAddPC 1              
  3755.       taMUL:
  3756.         OUTd "MUL R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3757.         movd xmm0, SRC_cx
  3758.         movd xmm1, DST
  3759.         pmuludq xmm0, xmm1
  3760.         movd TMPR, xmm0
  3761.         mov DST, TMPR
  3762.         or TMPR, TMPR
  3763.         SetNZ_A
  3764.         mulClks SRC_cx, DST_i, TMPR ;; @FIXME
  3765.         lea SC_INVOL, [TMPR+1]
  3766.         GamePAK_Prefetch TMPR
  3767.         tb_ExitAddPC SC_INVOL
  3768.       taLSL:
  3769.         OUTd "LSL R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3770.         and SRC_cx, 255
  3771.         jne @F
  3772.         ;; ZERO.
  3773.         mov TMPR, DST
  3774.         or TMPR, TMPR
  3775.         SetNZ_A
  3776.         GamePAK_Prefetch 1
  3777.         tb_ExitAddPC 2
  3778.       @@:
  3779.         xor TMPR, TMPR
  3780.         cmp SRC_cx, 32
  3781.         jb @F
  3782.         ;; >= 32      
  3783.         mov SRC_cx, DST
  3784.         mov DST, TMPR ;; Rd:= 0
  3785.         sete TMPR8 ;; 32 1
  3786.         and SC_CPSR, not (FLAG_C or FLAG_N)
  3787.         and SRC_cx, 1
  3788.         and SRC_cx, TMPR ;; and it.  
  3789.         shl SRC_cx, FLAG_CHECK_C_X86_BT
  3790.         or SC_CPSR, SRC_cx
  3791.         or SC_CPSR, FLAG_Z
  3792.         GamePAK_Prefetch 1
  3793.         tb_ExitAddPC 2
  3794.       @@:
  3795.         shl DST, cl
  3796.         SetNZC_A
  3797.         GamePAK_Prefetch 1
  3798.         tb_ExitAddPC 2
  3799.       taLSR:
  3800.         OUTd "LSR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3801.         and SRC_cx, 255
  3802.         jne @F
  3803.         ;; ZERO.
  3804.         mov TMPR, DST
  3805.         or TMPR, TMPR
  3806.         SetNZ_A
  3807.         GamePAK_Prefetch 1
  3808.         tb_ExitAddPC 2
  3809.       @@:
  3810.         xor TMPR, TMPR
  3811.         cmp SRC_cx, 32
  3812.         jb @F
  3813.         ;; >= 32      
  3814.         mov SRC_cx, DST
  3815.         mov DST, TMPR ;; Rd:= 0
  3816.         sete TMPR8 ;; 32 1
  3817.         and SC_CPSR, not (FLAG_C or FLAG_N)
  3818.         shr SRC_cx, 31
  3819.         and SRC_cx, TMPR ;; and it.  
  3820.         shl SRC_cx, FLAG_CHECK_C_X86_BT
  3821.         or SC_CPSR, SRC_cx
  3822.         or SC_CPSR, FLAG_Z
  3823.         GamePAK_Prefetch 1
  3824.         tb_ExitAddPC 2
  3825.       @@:
  3826.         shr DST, cl
  3827.         SetNZC_A
  3828.         GamePAK_Prefetch 1
  3829.         tb_ExitAddPC 2      
  3830.       taASR:
  3831.         OUTd "ASR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3832.         and SRC_cx, 255
  3833.         jne @F
  3834.         ;; ZERO.
  3835.         mov TMPR, DST
  3836.         or TMPR, TMPR
  3837.         SetNZ_A
  3838.         GamePAK_Prefetch 1
  3839.         tb_ExitAddPC 2
  3840.       @@:
  3841.         cmp SRC_cx, 32
  3842.         jb @F
  3843.         bt DST, 31
  3844.         sbb SRC_cx, SRC_cx  
  3845.         mov DST, SRC_cx
  3846.         SetNZC_A
  3847.         GamePAK_Prefetch 1
  3848.         tb_ExitAddPC 2
  3849.       @@:
  3850.         sar DST, cl
  3851.         SetNZC_A
  3852.         GamePAK_Prefetch 1
  3853.         tb_ExitAddPC 2
  3854.       taROR:
  3855.         OUTd "ROR R%d, R%d", "SC_INVOL & 7", "SC_INVOL } 3 & 7"
  3856.         and SRC_cx, 255
  3857.         jne @F
  3858.         ;; ZERO.
  3859.         mov TMPR, DST
  3860.         or TMPR, TMPR
  3861.         SetNZ_A
  3862.         GamePAK_Prefetch 1
  3863.         tb_ExitAddPC 2
  3864.       @@:
  3865.         test SRC_cx, 31
  3866.         jne @F
  3867.         mov SC_INVOL, DST
  3868.         or SC_INVOL, SC_INVOL
  3869.         rol SC_INVOL, 1
  3870.         SetNZC_A
  3871.         GamePAK_Prefetch 1
  3872.         tb_ExitAddPC 2
  3873.       @@:
  3874.         and SRC_cx, 31
  3875.         ror DST, cl
  3876.         SetC_A
  3877.         mov eax, DST
  3878.         or eax, eax
  3879.         SetNZ_A
  3880.         GamePAK_Prefetch 1
  3881.         tb_ExitAddPC 2
  3882.        
  3883.       INLSL:
  3884.         OUTd "LSL R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 31"
  3885.         mov ecx, SC_INVOL
  3886.         GetRFIV_T SC_INVOL, 3, edx  ;;Rm.
  3887.         GetRFI_T SC_INVOL, 0,  eax  ;;Rd's Index .
  3888.         shr ecx, 6
  3889.         and ecx, 31  
  3890.         jne @F
  3891.         or edx, edx
  3892.         mov ZRS (eax), edx
  3893.         SetNZ_A
  3894.         tb_ExitAddPC 1
  3895.       @@:
  3896.         shl edx, cl
  3897.         mov ZRS (eax), edx            
  3898.         SetNZC_A  
  3899.         tb_ExitAddPC 1      
  3900.       INLSR:
  3901.         OUTd "LSR R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 31"
  3902.         mov ecx, SC_INVOL
  3903.         GetRFIV_T SC_INVOL, 3, edx  ;;Rm.
  3904.         GetRFI_T SC_INVOL, 0,  eax  ;;Rd's Index .
  3905.         shr ecx, 6
  3906.         and ecx, 31  
  3907.         jne @F
  3908.         and SC_CPSR, not (FLAG_Z or FLAG_N or FLAG_C)
  3909.         or SC_CPSR, FLAG_Z
  3910.         shl edx, 1
  3911.         mov ZRS (eax), 0
  3912.         SetC_A
  3913.         tb_ExitAddPC 1
  3914.       @@:
  3915.         shr edx, cl
  3916.         mov ZRS (eax), edx            
  3917.         SetNZC_A  
  3918.         tb_ExitAddPC 1    
  3919.       INASR:
  3920.         OUTd "ASR R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 31"
  3921.         mov ecx, SC_INVOL
  3922.         GetRFIV_T SC_INVOL, 3, edx  ;;Rm.
  3923.         GetRFI_T SC_INVOL, 0,  eax  ;;Rd's Index .
  3924.         shr ecx, 6
  3925.         and ecx, 31  
  3926.         jne @F
  3927.         shl edx, 1
  3928.         sbb ecx, ecx  ;; 0 or -1
  3929.         mov ZRS (eax), ecx          
  3930.         SetNZC_A
  3931.         tb_ExitAddPC 1
  3932.       @@:
  3933.         sar edx, cl
  3934.         mov ZRS (eax), edx            
  3935.         SetNZC_A  
  3936.         tb_ExitAddPC 1
  3937.       ADDI3:
  3938.         OUTd "ADD R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
  3939.         GetRFIV_T SC_INVOL, 3, edx  ;;Rn.
  3940.         GetRFI_T SC_INVOL, 0, eax  ;;Rd's Index .  
  3941.         GetRFI_T SC_INVOL, 6, ecx  ;;Imm3
  3942.         add edx, ecx  
  3943.         mov ZRS (eax), edx
  3944.         SetNZCV_A 0
  3945.         tb_ExitAddPC 1
  3946.       SUBI3:
  3947.         OUTd "SUB R%d, R%d, #%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
  3948.         GetRFIV_T SC_INVOL, 3, edx  ;;Rn.
  3949.         GetRFI_T SC_INVOL, 0, eax  ;;Rd's Index .  
  3950.         GetRFI_T SC_INVOL, 6, ecx  ;;Imm3
  3951.         sub edx, ecx  
  3952.         mov ZRS (eax), edx
  3953.         SetNZCV_A 1
  3954.         tb_ExitAddPC 1    
  3955.       ADDRT:
  3956.         OUTd "ADD R%d, R%d, R%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
  3957.         GetRFIV_T SC_INVOL, 3, edx  ;;Rn.
  3958.         GetRFI_T SC_INVOL, 0, eax  ;;Rd's Index .  
  3959.         GetRFIV_T SC_INVOL, 6, ecx  ;;Rm
  3960.         add edx, ecx  
  3961.         mov ZRS (eax), edx
  3962.         SetNZCV_A 0
  3963.         tb_ExitAddPC 1
  3964.       SUBRT:
  3965.         OUTd "SUB R%d, R%d, R%d", "SC_INVOL & 7", "SC_INVOL }3 & 7", "SC_INVOL } 6 & 7"
  3966.         GetRFIV_T SC_INVOL, 3, edx  ;;Rn.
  3967.         GetRFI_T SC_INVOL, 0, eax  ;;Rd's Index .  
  3968.         GetRFIV_T SC_INVOL, 6, ecx  ;;Rm
  3969.         sub edx, ecx  
  3970.         mov ZRS (eax), edx
  3971.         SetNZCV_A 1
  3972.         tb_ExitAddPC 1    
  3973.       MOVI8:
  3974.         OUTd "MOV R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
  3975.         GetRFI_T SC_INVOL, 8, ecx  ;;Rd's Index .  
  3976.         and SC_INVOL, 255
  3977.         mov ZRS (ecx), SC_INVOL
  3978.         SetNZ_A
  3979.         tb_ExitAddPC 1    
  3980.       CMPI8:
  3981.         OUTd "CMP R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
  3982.         GetRFIV_T SC_INVOL, 8, ecx  ;;Rn's Value .  
  3983.         and SC_INVOL, 255
  3984.         cmp ecx, SC_INVOL
  3985.         SetNZCV_A 1
  3986.         tb_ExitAddPC 1
  3987.       ADDI8:
  3988.         OUTd "ADD R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
  3989.         GetRFI_T SC_INVOL, 8, ecx  ;;Rd's Index .  
  3990.         and SC_INVOL, 255
  3991.         add ZRS (ecx), SC_INVOL
  3992.         SetNZCV_A 0
  3993.         tb_ExitAddPC 1      
  3994.       SUBI8:
  3995.         OUTd "SUB R%d, #%d", "SC_INVOL }8 & 7", "SC_INVOL & 255"
  3996.         GetRFI_T SC_INVOL, 8, ecx  ;;Rd's Index .  
  3997.         and SC_INVOL, 255
  3998.         sub ZRS (ecx), SC_INVOL
  3999.         SetNZCV_A 1
  4000.         tb_ExitAddPC 1
  4001.        
  4002.       ih1h2Get macro Post, RdRev, RmRev
  4003.         mov RmRev, Post
  4004.         bt Post, 7
  4005.         sbb RdRev, RdRev
  4006.         and RdRev, 8
  4007.         and RmRev, 7
  4008.         or RdRev, RmRev
  4009.         mov RmRev, Post
  4010.         and RmRev, 078h
  4011.         shr RmRev, 3  ;; TODO: Check LO-LO Trans UB.
  4012.       endm
  4013.      
  4014.       ADD16:
  4015.         ih1h2Get SC_INVOL, ecx, edx
  4016.         OUTd "ADD R%d, R%d", "ecx", "edx"
  4017.         mov edx, ZRS (edx)
  4018.         add ZRS (ecx), edx        
  4019.         cmp ecx, 15
  4020.         jne @F
  4021.         and ZRS (ecx), -2
  4022.         tb_FlushPipeline 3
  4023.       @@:        
  4024.         tb_ExitAddPC 1
  4025.       MOV16:
  4026.         ih1h2Get SC_INVOL, ecx, edx
  4027.         OUTd "MOV R%d, R%d", "ecx", "edx"
  4028.         mov edx, ZRS (edx)
  4029.         mov ZRS (ecx), edx  
  4030.         cmp ecx, 15
  4031.         jne @F
  4032.         and ZRS (ecx), -2
  4033.         tb_FlushPipeline 3
  4034.       @@:        
  4035.         tb_ExitAddPC 1
  4036.       CMP16:
  4037.         ih1h2Get SC_INVOL, ecx, edx
  4038.         OUTd "CMP R%d, R%d", "ecx", "edx"
  4039.         mov edx, ZRS (edx)
  4040.         cmp ZRS (ecx), edx      
  4041.         SetNZCV_A 1        
  4042.         tb_ExitAddPC 1
  4043.  
  4044.       SIM08 macro lSym, SZ_BODY
  4045.        lSym:
  4046.         mov eax, SC_INVOL
  4047.         mov ecx, SC_INVOL
  4048.         mov edx, ZRS (SZ_BODY) ;; edx:PC or SP
  4049.         and eax, 255 ;; Imm8
  4050.         shr ecx, 8
  4051.         and ecx, 7 ;; ecx: RdI
  4052.         shl eax, 2 ;; eax: address temp  
  4053.         IF SZ_BODY eq SZ_STACK
  4054.           OUTd "ADD R%d, SP, %d-%03X", "ecx", "eax", "eax"
  4055.         ELSEIF SZ_BODY eq SZ_PC
  4056.           OUTd "ADD R%d, PC, %d-%03X", "ecx", "eax", "eax"
  4057.         ELSE
  4058.           ERRORS_ASSERT
  4059.         ENDIF
  4060.       endm
  4061.      
  4062.       SIM08 PCI08, SZ_PC
  4063.         and edx, -4
  4064.         add edx, eax
  4065.         mov ZRS (ecx), edx
  4066.         tb_ExitAddPC 1
  4067.       SIM08 SPI08, SZ_STACK
  4068.         add edx, eax
  4069.         mov ZRS (ecx), edx
  4070.         tb_ExitAddPC 1    
  4071.       STKS7:
  4072.         test SC_INVOL, 080h
  4073.         je @F
  4074.         and SC_INVOL, 07Fh
  4075.         shl SC_INVOL, 2
  4076.         OUTd "SUB SP, #%d", "SC_INVOL"
  4077.         sub ZRS (SZ_STACK), SC_INVOL    
  4078.         tb_ExitAddPC 1
  4079.       @@:
  4080.         and SC_INVOL, 07Fh
  4081.         shl SC_INVOL, 2
  4082.         OUTd "ADD SP, #%d", "SC_INVOL"
  4083.         add ZRS (SZ_STACK), SC_INVOL
  4084.         tb_ExitAddPC 1
  4085.        
  4086.       SWI08: ;; Thumb Software Interrupt
  4087.         OUTd "SWI-THUMB FUNC:%02X R0 %08X R1 %08X R2 %08X\n", "SC_INVOL & 255", "Z0", "Z1", "Z2"
  4088.         mov eax, ZRS (SZ_PC)
  4089.         mov ecx, SC_CPSR
  4090.         and ecx, ARM7_MODE_CLR_MASK
  4091.         or ecx, ARM7_MODE_MGR_MASK  ;; Set SVC mode.
  4092.         and ecx, not FLAG_THUMB ;; Clear Thumb exec flag
  4093.         or ecx, IRQ_INHIBI_MASK ;; Set IRQ inhibit mask
  4094.         ;; PC to SVC's LR, LR:= Current Instruction next ins
  4095.         lea edx, [eax-2]
  4096.         mov [SC_ARM7].R1314_T[R1314b_MGR+4], edx
  4097.         ;; Adjust PC Pointer to IRQ Interrupt vector address
  4098.         mov ZRS (SZ_PC), ARM7_VECTOR_SOFTWARE
  4099.         mov SC_INVOL, SC_CPSR
  4100.         and SC_INVOL, ARM7_MODE_GET_MASK
  4101.         cmp SC_INVOL, ARM7_MODE_MGR_MASK
  4102.         je @NestSwi_thumb
  4103.         ;; switch Mode
  4104.         SwitchMode ecx, 0
  4105.         ;; Prefetch Opcode pipeline
  4106.         arm7_FlushPipeline 3
  4107.     @NestSwi_thumb:
  4108.         mov ZRS (SZ_LRLINK), edx
  4109.         mov [SC_ARM7].SPSR_T[SPSRb_MGR], SC_CPSR
  4110.         mov eax, ZRS (SZ_STACK)
  4111.         mov [SC_ARM7].R1314_T[R1314b_MGR], eax
  4112.         mov eax, ZRS (SZ_LRLINK)
  4113.         mov [SC_ARM7].R1314_T[R1314b_MGR+4], eax
  4114.         mov SC_CPSR, ecx
  4115.         ;; Prefetch Opcode pipeline
  4116.         arm7_FlushPipeline 3
  4117.        
  4118.     PUSHR: ;; PUSH is DB stack opreate type, if R spec, Push LRLINK to stack.
  4119.         OUTd "PUSH R:%d R7-R4:%01X R3-R0:%01X", "SC_INVOL } 8 & 1", "SC_INVOL } 4 & 15", "SC_INVOL & 15"  
  4120.         sub esp, LDM_STACK_REQUIRE
  4121.         mov STA (RnFirst), 0
  4122.         sub ZRS (SZ_STACK), 4
  4123.         mov STA (RnCount), 8
  4124.         shl SC_INVOL, 23
  4125.       @@:
  4126.         shl SC_INVOL, 1
  4127.         jnc PUSHR_c
  4128.         add SC_WAIT, 1
  4129.         mov eax, STA (RnCount)
  4130.         bt eax, 3  ;; Check R Spec
  4131.         sbb ecx, ecx
  4132.         and ecx, SZ_LRLINK
  4133.         or eax, ecx ;; XXX: LRLINK must be 14  
  4134.         push STACK_PUSH_STATUS_PUSH
  4135.         push eax      
  4136.         push ZRS (eax)
  4137.         push ZRS (SZ_STACK)
  4138.         sub ZRS (SZ_STACK), 4
  4139.         cmp STA (RnFirst+16), 0
  4140.         mov STA (RnFirst+16), 1
  4141.         je PUSHR_first
  4142.         CallMemOrIOAddWaitState StackWriteSeq
  4143.         jmp PUSHR_c
  4144.       PUSHR_first:
  4145.         CallMemOrIOAddWaitState StackWriteNoSeq
  4146.       PUSHR_c:
  4147.         sub STA (RnCount), 1
  4148.         jge @B
  4149.         add ZRS (SZ_STACK), 4
  4150.         add esp, LDM_STACK_REQUIRE
  4151.         mov [SC_ARM7].nextNoSeqFetch, 1
  4152.         tb_ExitAddPC 1
  4153.        
  4154.     POPRP:  ;; POP is IA stack opreate type, if R spec, Pop PC from stack.
  4155.         OUTd "POP R:%d R7-R4:%01X R3-R0:%01X", "SC_INVOL } 8 & 1", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
  4156.         GamePAK_Prefetch 1
  4157.         xor eax, eax
  4158.         sub esp, LDM_STACK_REQUIRE
  4159.         mov STA (RnFirst), eax
  4160.         mov STA (RnCount), eax
  4161.       @@:
  4162.         shr SC_INVOL, 1
  4163.         jnc POPRP_c  
  4164.         inc SC_WAIT
  4165.         push ZRS (SZ_STACK)
  4166.         cmp STA (RnFirst+4), 0
  4167.         mov STA (RnFirst+4), 1
  4168.         je POPRP_first
  4169.         CallMemOrIOAddWaitState StackReadSeq
  4170.         jmp POPRP_continue
  4171.       POPRP_first:
  4172.         CallMemOrIOAddWaitState StackReadNoSeq
  4173.       POPRP_continue:        
  4174.         mov edx, STA (RnCount)
  4175.         bt edx, 3 ;; Check R Spec
  4176.         sbb ecx, ecx
  4177.         and ecx, SZ_PC
  4178.         or edx, ecx ;; XXX: PC must be 15  
  4179.         mov ZRS (edx), eax    
  4180.         add ZRS (SZ_STACK), 4
  4181.         cmp edx, SZ_PC ;; PC Flush? Flush Pipeline : nodone.
  4182.         je @F
  4183.       POPRP_c:
  4184.         add STA (RnCount), 1
  4185.         cmp STA (RnCount), 9
  4186.         jne @B
  4187.         add esp, LDM_STACK_REQUIRE
  4188.         tb_ExitAddPC 2
  4189.       @@:
  4190.         add esp, LDM_STACK_REQUIRE  
  4191.         tb_FlushPipeline 4
  4192.        
  4193.       TB_LDR equ 0
  4194.       TB_LDRH equ 1
  4195.       TB_LDRSH equ 2
  4196.       TB_RESET equ 7
  4197.  
  4198.       STRsc macro Routine
  4199.         mov eax, SC_INVOL
  4200.         mov ecx, SC_INVOL
  4201.         mov edx, SC_INVOL
  4202.         and eax, 7
  4203.         shr ecx, 3
  4204.         and ecx, 7
  4205.         shr edx, 6
  4206.         and edx, 7
  4207.         OUTd "R%d, [R%d, R%d]", "eax", "ecx", "edx"
  4208.         mov ecx, ZRS (ecx)
  4209.         mov eax, ZRS (eax)      
  4210.         add ecx, ZRS (edx)  
  4211.         push eax
  4212.         push ecx
  4213.         CallMemOrIOAddWaitState Routine
  4214.         mov [SC_ARM7].nextNoSeqFetch, 1 ;; STR always NoSeq fetch in next fetch.
  4215.         tb_ExitAddPC 2
  4216.       endm
  4217.       LDRsc macro MemAccessType, Routine, MovSt, rhs, alignBlk
  4218.         mov eax, SC_INVOL
  4219.         mov ecx, SC_INVOL
  4220.         mov edx, SC_INVOL
  4221.         and eax, 7
  4222.         shr ecx, 3
  4223.         and ecx, 7
  4224.         shr edx, 6
  4225.         and edx, 7
  4226.         OUTd "R%d, [R%d, R%d]", "eax", "ecx", "edx"
  4227.         mov ecx, ZRS (ecx)
  4228.         mov SC_INVOL, eax    
  4229.         add ecx, ZRS (edx)  
  4230.         mov [SC_ARM7].calc, ecx
  4231.         ;; and ecx, alignBlk    
  4232.         push ecx  
  4233.         CallMemOrIOAddWaitState Routine
  4234.         mov ecx, [SC_ARM7].calc
  4235.        
  4236.         IF MemAccessType eq TB_RESET
  4237.           MovSt eax, rhs
  4238.         ELSEIF MemAccessType eq TB_LDR
  4239.           and ecx, 3
  4240.           shl ecx, 3
  4241.           ror eax, cl
  4242.         ELSEIF MemAccessType eq TB_LDRH  
  4243.           and eax, 0FFFFh
  4244.           and ecx, 1
  4245.           shl ecx, 3
  4246.           ror eax, cl
  4247.         ELSEIF MemAccessType eq TB_LDRSH
  4248.           mov edx, eax
  4249.           movsx eax, ax
  4250.           and ecx, 1
  4251.           je @F
  4252.           movsx eax, dh
  4253.         @@:
  4254.         ELSE
  4255.           ERRORS_ASSERT
  4256.         ENDIF
  4257.         mov ZRS (SC_INVOL), eax
  4258.         GamePAK_Prefetch 1
  4259.         tb_ExitAddPC 3
  4260.       endm
  4261.      
  4262.       STRWD:  
  4263.         OUTd "STR "
  4264.         STRsc MmuWriteWordNoSeq
  4265.       STRHW:
  4266.         OUTd "STRH "
  4267.         STRsc MmuWriteHalfWordNoSeq  
  4268.       STRUB:
  4269.         OUTd "STRB "
  4270.         STRsc MmuWriteByteNoSeq
  4271.       LDRWD:
  4272.         OUTd "LDR "
  4273.         LDRsc TB_LDR, MmuReadWordNoSeq, mov, eax, 0FFFFFFFCh
  4274.       LDHW2:
  4275.         OUTd "LDRH "
  4276.         LDRsc TB_LDRH, MmuReadHalfWordNoSeq, movzx, ax, 0FFFFFFFEh
  4277.       LDRSW:
  4278.         OUTd "LDRSH "
  4279.         LDRsc TB_LDRSH, MmuReadHalfWordNoSeq, movsx, ax, 0FFFFFFFEh
  4280.       LDRUB:
  4281.         OUTd "LDRB "
  4282.         LDRsc TB_RESET, MmuReadByteNoSeq, movzx, al, 0FFFFFFFFh
  4283.       LDRSB:
  4284.         OUTd "LDRSB "
  4285.         LDRsc TB_RESET, MmuReadByteNoSeq, movsx, al, 0FFFFFFFFh
  4286.        
  4287.       ;; encode: d0-d2 rd, d3-d5 rn, r6-r10 imm5*sizeof(bitdepth/8)      
  4288.       ADR5 macro SftBit ;; eax:rdi, edx:address
  4289.         mov eax, SC_INVOL
  4290.         mov ecx, SC_INVOL
  4291.         mov edx, SC_INVOL
  4292.         and eax, 7 ;; Rd
  4293.         shr ecx, 3
  4294.         and ecx, 7 ;; Rn
  4295.         shr edx, 6
  4296.         and edx, 31 ;; Imm5  
  4297.         shl edx, SftBit    
  4298.         OUTd "R%d, [R%d, %d]", "eax", "ecx", "edx"
  4299.         add edx, ZRS (ecx)    
  4300.         mov [SC_ARM7].calc, edx
  4301.       endm
  4302.       STR5 macro SftBit, CallRoutine
  4303.         ADR5 SftBit
  4304.         push ZRS (eax)
  4305.         push edx
  4306.         CallMemOrIOAddWaitState CallRoutine
  4307.         mov [SC_ARM7].nextNoSeqFetch, 1
  4308.         tb_ExitAddPC 2
  4309.       endm
  4310.       LDR5 macro MemAccessType, SftBit, BitLimit, CallRoutine
  4311.         ADR5 SftBit
  4312.         mov SC_INVOL, eax
  4313.         push edx
  4314.         CallMemOrIOAddWaitState CallRoutine
  4315.         mov ecx, [SC_ARM7].calc
  4316.         IF MemAccessType eq TB_LDR
  4317.           and ecx, 3
  4318.           shl ecx, 3
  4319.           ror eax, cl
  4320.         ELSEIF MemAccessType eq TB_LDRH
  4321.           and eax, 0FFFFh
  4322.           and ecx, 1
  4323.           shl ecx, 3
  4324.           ror eax, cl
  4325.         ELSEIF MemAccessType eq TB_RESET
  4326.           movzx eax, al        
  4327.         ENDIF
  4328.         mov ZRS (SC_INVOL), eax
  4329.         GamePAK_Prefetch 1
  4330.         tb_ExitAddPC 3
  4331.       endm
  4332.  
  4333.       LDSTR1315 macro lSym
  4334.        lSym:
  4335.         mov eax, SC_INVOL
  4336.         mov ecx, SC_INVOL
  4337.         mov edx, SC_INVOL
  4338.         and eax, 255 ;; Imm8
  4339.         shr ecx, 8
  4340.         and ecx, 7 ;; Rd
  4341.         shl eax, 2 ;;;;4 address temp
  4342.       endm
  4343.      
  4344.       STRW5:
  4345.         OUTd "STR "
  4346.         STR5 2, MmuWriteWordNoSeq
  4347.       STRH5:
  4348.         OUTd "STRH "
  4349.         STR5 1, MmuWriteHalfWordNoSeq
  4350.       STRB5:
  4351.         OUTd "STRB "
  4352.         STR5 0, MmuWriteByteNoSeq
  4353.       LDRW5: ;;=======================DEBUG
  4354.         OUTd "LDR "
  4355.         LDR5 TB_LDR, 2, 0FFFFFFFFh, MmuReadWordNoSeq
  4356.       LDRH5:
  4357.         OUTd "LDRH "
  4358.         LDR5 TB_LDRH, 1, 0FFFFh, MmuReadHalfWordNoSeq
  4359.       LDRB5:
  4360.         OUTd "LDRB "
  4361.         LDR5 TB_RESET, 0, 0FFh, MmuReadByteNoSeq
  4362.        
  4363.       LDSTR1315 LDRPC
  4364.         OUTd "LDR R%d, [PC, #%d-%03X]", "ecx", "eax", "eax"    
  4365.         mov edx, ZRS (SZ_PC)
  4366.         and edx, -4
  4367.         add eax, edx
  4368.         mov SC_INVOL, ecx
  4369.         push eax
  4370.         mov [SC_ARM7].calc, eax
  4371.         CallMemOrIOAddWaitState MmuReadWordNoSeq
  4372.         mov ecx, [SC_ARM7].calc
  4373.         and ecx, 3
  4374.         shl ecx, 3
  4375.         ror eax, cl
  4376.         mov ZRS (SC_INVOL), eax
  4377.         GamePAK_Prefetch 1
  4378.         tb_ExitAddPC 3
  4379.       LDSTR1315 LDRSP
  4380.         OUTd "LDR R%d, [SP, #%d-%03X]", "ecx", "eax", "eax"
  4381.         add eax, ZRS (SZ_STACK)
  4382.         mov SC_INVOL, ecx  
  4383.         push eax
  4384.         mov [SC_ARM7].calc, eax
  4385.         CallMemOrIOAddWaitState MmuReadWordNoSeq
  4386.         mov ecx, [SC_ARM7].calc
  4387.         and ecx, 3
  4388.         shl ecx, 3
  4389.         ror eax, cl
  4390.         mov ZRS (SC_INVOL), eax
  4391.         GamePAK_Prefetch 1
  4392.         tb_ExitAddPC 3          
  4393.       LDSTR1315 STRSP
  4394.         OUTd "STR R%d, [SP, #%d-%03X]", "ecx", "eax", "eax"
  4395.         add eax, ZRS (SZ_STACK)  
  4396.         push ZRS (ecx)
  4397.         push eax
  4398.         CallMemOrIOAddWaitState MmuWriteWordNoSeq
  4399.         mov [SC_ARM7].nextNoSeqFetch, 1
  4400.         tb_ExitAddPC 2
  4401.        
  4402.     ;; A7.1.57 - STMIA (INC, AFTER)
  4403.     ;;
  4404.     ;; Codec: 15 14 13 12 11    10 9 8      7 6 5 4 3 2 1 0
  4405.     ;;         1  1  1  0  0      Rn           Reglist.
  4406.     ;;
  4407.    
  4408.     STMIA:
  4409.         OUTd "T-STMIA [R%d]!, R7-R4:%01X R3-R0:%01X ", "SC_INVOL } 8 & 7", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
  4410.         sub esp, LDM_STACK_REQUIRE
  4411.         mov eax, SC_INVOL
  4412.         mov ecx, SC_INVOL
  4413.         and eax, 255
  4414.         shr ecx, 8
  4415.         and ecx, 7
  4416.         ;; Get Rn's index and Rn's init value.
  4417.         mov edx, ZRS (ecx)
  4418.         mov STA (RnTempi), ecx
  4419.         mov STA (RnTemp), edx
  4420.         mov STA (RnFirst), 0
  4421.         mov STA (RnCount), 0
  4422.         ;; Check Reglist is empty ?
  4423.         ;; ================================= NO$GBA doc =================================
  4424.         ;; Strange Effects on Invalid Rlist's
  4425.         ;; Empty Rlist: R15 loaded/stored (ARMv4 only), and Rb=Rb+40h (ARMv4-v5).
  4426.         ;; Writeback with Rb included in Rlist: Store OLD base if Rb is FIRST entry in
  4427.         ;; Rlist, otherwise store NEW base (STM/ARMv4), always store OLD base (STM/ARMv5),
  4428.         ;; no writeback (LDM/ARMv4/ARMv5; at this point, THUMB opcodes work different than ARM opcodes).
  4429.         test eax, eax
  4430.         jne @F
  4431.         push STACK_PUSH_STATUS_PUSH
  4432.         push SZ_PC    
  4433.         mov eax, ZRS (SZ_PC)
  4434.         add eax, 2
  4435.         push eax
  4436.         push edx
  4437.         add ZRS (ecx), 64
  4438.         and ZRS (ecx), -4
  4439.         CallMemOrIOAddWaitState StackWriteNoSeq
  4440.         add esp, LDM_STACK_REQUIRE
  4441.         mov [SC_ARM7].nextNoSeqFetch, 1
  4442.         tb_ExitAddPC 2
  4443.         ;; Check Rn with Reglist ?
  4444.       @@:
  4445.         bt eax, ecx
  4446.         jnc @F  
  4447.         DEBUG_BREAK
  4448.         OUTd "R%d in reglist! FIRST-V:", "ecx"
  4449.         xor edx, edx  
  4450.         not edx
  4451.         ;; Check First Vailed bit
  4452.         ;; IF Done, write inital value to stack
  4453.         ;; ELSE. write final Rn's value to stack (this is UB. but i test on AXD Debugger 1.2 is final Rn)
  4454.         ;; See ARM Developer Suite Assembler Guide:: Thumb Instruction Reference::5.1.5 LDMIA and STMIA
  4455.         ;;
  4456.         shl edx, cl
  4457.         not edx
  4458.         test edx, eax
  4459.         je STMIA_k
  4460.         OUTd "NO"
  4461.         ;; Calc write back's Rn in end.
  4462.       IF  1
  4463.         mov ecx, 8
  4464.         xor edx, edx
  4465.       STMIA0:
  4466.         shr eax, 1
  4467.         adc edx, 0
  4468.         dec ecx
  4469.         jne STMIA0
  4470.       ELSE
  4471.         and eax, 255
  4472.         popcnt edx, eax
  4473.       ENDIF
  4474.         ;; Write back Rn.
  4475.         lea edx, [edx*4]
  4476.         mov ecx, SC_INVOL
  4477.         shr ecx, 8
  4478.         and ecx, 7
  4479.         add ZRS (ecx), edx  
  4480.         and ZRS (ecx), -4
  4481.       STMIA_k:
  4482.         OUTd "YES"
  4483.       @@:
  4484.         shr SC_INVOL, 1
  4485.         jnc STMIA_c  
  4486.         inc SC_WAIT        
  4487.         mov eax, STA (RnCount)
  4488.         push STACK_PUSH_STATUS_PUSH
  4489.         push eax    
  4490.         push ZRS (eax)
  4491.         mov eax, STA (RnTemp+12)
  4492.         add STA (RnTemp+12), 4
  4493.         ;; and eax, -4
  4494.         push eax
  4495.         cmp STA (RnFirst+16), 0
  4496.         mov STA (RnFirst+16), 1
  4497.         je STMIA_first
  4498.         CallMemOrIOAddWaitState StackWriteSeq
  4499.         jmp STMIA_c
  4500.       STMIA_first:
  4501.         CallMemOrIOAddWaitState StackWriteNoSeq
  4502.       STMIA_c:
  4503.         add STA (RnCount), 1
  4504.         cmp STA (RnCount), 8
  4505.         jne @B
  4506.         cmp STA (RnFirst), 0
  4507.         jne @F
  4508.       @@:
  4509.         mov ecx, STA (RnTemp)
  4510.         mov eax, STA (RnTempi)
  4511.         mov ZRS (eax), ecx
  4512.         and ZRS (eax), -4
  4513.         add esp, LDM_STACK_REQUIRE
  4514.         mov [SC_ARM7].nextNoSeqFetch, 1
  4515.         tb_ExitAddPC 1    
  4516.    
  4517.     ;; A7.1.27 LDMIA  
  4518.     ;;
  4519.     ;; Codec: 15 14 13 12 11    10 9 8      7 6 5 4 3 2 1 0
  4520.     ;;         1  1  1  0  1      Rn           Reglist.
  4521.     ;;    
  4522.    
  4523.     LDMIA:
  4524.         GamePAK_Prefetch 1
  4525.         OUTd "T-LDMIA [R%d]!, R7-R4:%01X R3-R0:%01X ", "SC_INVOL } 8 & 7", "SC_INVOL } 4 & 15", "SC_INVOL & 15"
  4526.         sub esp, LDM_STACK_REQUIRE
  4527.         mov eax, SC_INVOL
  4528.         mov ecx, SC_INVOL
  4529.         and eax, 255
  4530.         shr ecx, 8
  4531.         and ecx, 7
  4532.         ;; Get Rn's index and Rn's init value.
  4533.         mov edx, ZRS (ecx)
  4534.         mov STA (RnTempi), ecx
  4535.         mov STA (RnTemp), edx
  4536.         mov STA (RnFirst), 0
  4537.         mov STA (RnCount), 0
  4538.         mov STA (RnAdjust), 1  
  4539.         ;; Check empty reglist
  4540.         test eax, eax
  4541.         jne @F
  4542.         push edx
  4543.         add ZRS (ecx), 64
  4544.         and ZRS (ecx), -4
  4545.         CallMemOrIOAddWaitState StackReadNoSeq
  4546.         mov ZRS (SZ_PC), eax
  4547.         add esp, LDM_STACK_REQUIRE
  4548.         tb_FlushPipeline 3  
  4549.       @@:
  4550.         bt eax, ecx
  4551.         jnc @F  
  4552.         ;; Rn with Reglist
  4553.         ;; Rn WriteBack will miss in thumb-LDMIA.
  4554.         ;; DEBUG_BREAK
  4555.         OUTd "R%d in reglist!"
  4556.         mov STA (RnAdjust), 0
  4557.       @@:
  4558.         shr SC_INVOL, 1
  4559.         jnc LDMIA_c  
  4560.         inc SC_WAIT        
  4561.         mov eax, STA (RnTemp)
  4562.         add STA (RnTemp), 4
  4563.         ;; and eax, -4
  4564.         push eax
  4565.         cmp STA (RnFirst+4), 0
  4566.         mov STA (RnFirst+4), 1
  4567.         je LDMIA_first
  4568.         CallMemOrIOAddWaitState StackReadSeq
  4569.         jmp LDMIA_a
  4570.       LDMIA_first:
  4571.         CallMemOrIOAddWaitState StackReadNoSeq
  4572.       LDMIA_a:
  4573.         mov ecx, STA (RnCount)
  4574.         mov ZRS (ecx), eax        
  4575.       LDMIA_c:
  4576.         add STA (RnCount), 1
  4577.         cmp STA (RnCount), 8
  4578.         jne @B
  4579.         cmp STA (RnFirst), 0
  4580.         jne @F
  4581.         ;; FIXME: No Reglist mask exist stuff..
  4582.         DEBUG_BREAK
  4583.       @@:
  4584.         cmp STA (RnAdjust), 0
  4585.         je @F
  4586.         mov ecx, STA (RnTemp)
  4587.         mov eax, STA (RnTempi)
  4588.         mov ZRS (eax), ecx
  4589.         and ZRS (eax), -4
  4590.       @@:
  4591.         add esp, LDM_STACK_REQUIRE
  4592.         tb_ExitAddPC 2
  4593.        
  4594.       ;; JMP Sign Offset 11bit. @!SMARK.
  4595.       JMP11:
  4596.         and SC_INVOL, 07FFh
  4597.         bt SC_INVOL, 10
  4598.         sbb eax, eax
  4599.         shl eax, 10
  4600.         or SC_INVOL, eax
  4601.         shl SC_INVOL, 1
  4602.         OUTd ":JMP 11 Offset %d-%08X ", "SC_INVOL", "SC_INVOL"
  4603.         add ZRS (SZ_PC), SC_INVOL
  4604.         OUTd ":CurrentPC %d-%08X", "ZF", "ZF"
  4605.         tb_FlushPipeline 2
  4606. IF 0
  4607.       ;; BL Ext
  4608.       BLEXT:
  4609.         ;; Fetch Ext High  
  4610.         ;; int 3
  4611.         and SC_INVOL, 07FFh
  4612.         bt SC_INVOL, 10
  4613.         sbb eax, eax
  4614.         shl eax, 10
  4615.         or SC_INVOL, eax
  4616.         shl SC_INVOL, 12
  4617.         add SC_INVOL, ZRS(SZ_PC)
  4618.         mov ZRS (SZ_LRLINK), SC_INVOL
  4619.         ;; Fetch Next Opcode Must be BLSTD (TODO: Opcode Check)
  4620.         mov eax, [SC_ARM7].Opcode[0]
  4621.         and eax, 07FFh
  4622.         shl eax, 1
  4623.         add eax, ZRS (SZ_LRLINK)
  4624.         OUTd ":BL Offset %d-%08X ", "ZE", "ZE"
  4625.         mov ecx, ZRS (SZ_PC)
  4626.         mov ZRS (SZ_PC), eax
  4627.         OUTd ":CurrentPC %d-%08X ", "ZF", "ZF"
  4628.         sub ecx, 0 ;; backup to next instruction base current instruction
  4629.         or ecx, 1 ;; With Thumb flags, for BX
  4630.         OUTd ":LINK %d-%08X ", "ecx", "ecx"
  4631.         mov ZRS (SZ_LRLINK) ,ecx
  4632.         ;; prefetch opcode .
  4633.         tb_FlushPipeline 3
  4634.       BLSTD: ;;(in fact, with BLEXT).
  4635. ELSE
  4636.       ;; BL Ext
  4637.       BLEXT:
  4638.         ;; Fetch Ext High  
  4639.         ;; int 3
  4640.         and SC_INVOL, 07FFh
  4641.         bt SC_INVOL, 10
  4642.         sbb eax, eax
  4643.         shl eax, 10
  4644.         or SC_INVOL, eax
  4645.         shl SC_INVOL, 12
  4646.         add SC_INVOL, ZRS(SZ_PC)
  4647.         mov ZRS (SZ_LRLINK), SC_INVOL
  4648.         tb_ExitAddPC 1
  4649.       BLSTD: ;;(in fact, with BLEXT).
  4650.         mov eax, SC_INVOL
  4651.         and eax, 07FFh
  4652.         shl eax, 1
  4653.         add eax, ZRS (SZ_LRLINK)
  4654.         OUTd ":BL Offset %d-%08X ", "ZE", "ZE"
  4655.         mov ecx, ZRS (SZ_PC)
  4656.         mov ZRS (SZ_PC), eax
  4657.         OUTd ":CurrentPC %d-%08X ", "ZF", "ZF"
  4658.         sub ecx, 2 ;; backup to next instruction base current instruction
  4659.         or ecx, 1 ;; With Thumb flags, for BX
  4660.         OUTd ":LINK %d-%08X ", "ecx", "ecx"
  4661.         mov ZRS (SZ_LRLINK) ,ecx
  4662.         ;; prefetch opcode .
  4663.         tb_FlushPipeline 3
  4664. ENDIF
  4665.    
  4666.      
  4667.      
  4668.      
  4669.       UNDEF:
  4670.         int 3
  4671.       BX_TB:
  4672.         mov eax, SC_INVOL
  4673.         and eax, 078h
  4674.         shr eax, 3
  4675.         OUTd "BX R%d", "eax"
  4676.         mov ecx, ZRS (eax)
  4677.         test ecx, 1
  4678.         je @F
  4679.         or SC_CPSR, FLAG_THUMB
  4680.         and ecx, -2
  4681.         mov ZRS (SZ_PC), ecx
  4682.         tb_FlushPipeline 3
  4683.       @@:
  4684.         and SC_CPSR, not FLAG_THUMB
  4685.         and ecx, -4
  4686.         mov ZRS (SZ_PC), ecx
  4687.         arm7_FlushPipeline 3
  4688.        
  4689.       ;; Thumb JCC -----------------------------------------------------------------
  4690.       JCCEQ:
  4691.         OUTd "JCC:EQ "
  4692.         test SC_CPSR, FLAG_Z
  4693.         jne JCCAL
  4694.       JCCNV:
  4695.         OUTd  ":Skip "
  4696.         tb_ExitAddPC 1
  4697.       JCCNE:  
  4698.         OUTd "JCC:NE "
  4699.         test SC_CPSR, FLAG_Z
  4700.         je JCCAL
  4701.         tb_ExitAddPC 1    
  4702.       JCCCS:
  4703.         OUTd "JCC:CS "
  4704.         test SC_CPSR, FLAG_C
  4705.         jne JCCAL
  4706.         jmp JCCNV
  4707.       JCCCC:
  4708.         OUTd "JCC:CC "
  4709.         test SC_CPSR, FLAG_C
  4710.         je JCCAL
  4711.         jmp JCCNV
  4712.       JCCMI:      
  4713.         OUTd "JCC:MI "
  4714.         test SC_CPSR, FLAG_N
  4715.         jne JCCAL  
  4716.         jmp JCCNV      
  4717.       JCCPL:
  4718.         OUTd "JCC:PL "
  4719.         test SC_CPSR, FLAG_N
  4720.         je JCCAL
  4721.         jmp JCCNV
  4722.       JCCVS:
  4723.         OUTd "JCC:VS "
  4724.         test SC_CPSR, FLAG_V
  4725.         jne JCCAL
  4726.         jmp JCCNV
  4727.       JCCVC:
  4728.         OUTd "JCC:VC "
  4729.         test SC_CPSR, FLAG_V
  4730.         je JCCAL
  4731.         jmp JCCNV
  4732.       JCCHI: ;; C = 1 && Z = 0
  4733.         OUTd "JCC:HI "
  4734.         mov ecx, SC_CPSR
  4735.         and ecx, FLAG_CZ
  4736.         cmp ecx, FLAG_C
  4737.         je JCCAL
  4738.         jmp JCCNV
  4739.       JCCLS: ;; C = 0 || Z = 1
  4740.         OUTd "JCC:LS "
  4741.         mov ecx, SC_CPSR
  4742.         and ecx, FLAG_CZ
  4743.         ;; C0Z1 ^ C1Z0 -> C1Z1
  4744.         ;; C1Z1 ^ C1Z0 -> C0Z1
  4745.         ;; C0Z0 ^ C1Z0 -> C1Z0
  4746.         ;; C1Z0 ^ C1Z0 -> ZERO.
  4747.         xor ecx, FLAG_C
  4748.         jne JCCAL
  4749.         jmp JCCNV
  4750.        
  4751.       JCCGE: ;; N = V
  4752.         OUTd "JCC:GE "
  4753.         mov eax, SC_CPSR
  4754.         mov ecx, SC_CPSR
  4755.         shr eax, FLAG_V_TOLSB_BIT
  4756.         shr ecx, FLAG_N_TOLSB_BIT  
  4757.         and eax, 1
  4758.         and ecx, 1
  4759.         xor eax, ecx
  4760.         je JCCAL
  4761.         jmp JCCNV
  4762.       JCCLT:  ;; N != V
  4763.         OUTd "JCC:LT "
  4764.         mov eax, SC_CPSR
  4765.         mov ecx, SC_CPSR
  4766.         shr eax, FLAG_V_TOLSB_BIT
  4767.         shr ecx, FLAG_N_TOLSB_BIT  
  4768.         and eax, 1
  4769.         and ecx, 1
  4770.         xor eax, ecx
  4771.         jne JCCAL
  4772.         jmp JCCNV  
  4773.       JCCGT: ;;    N = V  && Z= 0
  4774.         OUTd "JCC:GT "
  4775.         mov eax, SC_CPSR
  4776.         mov ecx, SC_CPSR
  4777.         shr eax, FLAG_V_TOLSB_BIT
  4778.         shr ecx, FLAG_N_TOLSB_BIT  
  4779.         and eax, 1
  4780.         and ecx, 1
  4781.         xor eax, ecx
  4782.         mov ecx, SC_CPSR
  4783.         shr ecx, FLAG_Z_TOLSB_BIT
  4784.         and ecx, 1
  4785.         or eax, ecx
  4786.         je JCCAL
  4787.         jmp JCCNV
  4788.       JCCLE: ;;  Z = 1 || N!=V
  4789.         OUTd "JCC:LE "
  4790.         mov eax, SC_CPSR
  4791.         mov ecx, SC_CPSR
  4792.         shr eax, FLAG_V_TOLSB_BIT
  4793.         shr ecx, FLAG_N_TOLSB_BIT  
  4794.         and eax, 1
  4795.         and ecx, 1
  4796.         xor eax, ecx
  4797.         mov ecx, SC_CPSR
  4798.         shr ecx, FLAG_Z_TOLSB_BIT
  4799.         and ecx, 1
  4800.         or eax, ecx
  4801.         je JCCNV
  4802.       JCCAL: ;; 1110
  4803.         OUTd "Exec It.:"
  4804.         mov eax, SC_INVOL
  4805.         and eax, 255
  4806.         mov [esp-8], eax
  4807.         movsx eax, byte ptr [esp-8]
  4808.         OUTd ":Offset %d-%08X ", "eax", "eax"
  4809.         shl eax, 1
  4810.         add ZRS (SZ_PC), eax
  4811.         OUTd ":CurrentPC %d-%08X", "ZF", "ZF"
  4812.         tb_FlushPipeline 2    
  4813.        
  4814.       ; Instruction Hash Entry -----------------------------------------------------------------------------------
  4815. .data
  4816.         i8r4TAB dd i8r4AND, i8r4ANDS, i8r4EOR, i8r4EORS
  4817.                   dd i8r4SUB, i8r4SUBS, i8r4RSB, i8r4RSBS
  4818.                   dd i8r4ADD, i8r4ADDS, i8r4ADC, i8r4ADCS
  4819.                   dd i8r4SBC, i8r4SBCS, i8r4RSC, i8r4RSCS
  4820.                   dd i8r4UB, i8r4TST, i8r4ToCPSR, i8r4TEQ
  4821.                   dd i8r4UB, i8r4CMP, i8r4ToSPSR, i8r4CMN  
  4822.                   dd i8r4ORR, i8r4ORRS, i8r4MOV, i8r4MOVS
  4823.                   dd i8r4BIC, i8r4BICS, i8r4MVN, i8r4MVNS
  4824.         si5TAB dd si5AND, si5ANDS, si5EOR, si5EORS
  4825.                   dd si5SUB, si5SUBS, si5RSB, si5RSBS
  4826.                   dd si5ADD, si5ADDS, si5ADC, si5ADCS
  4827.                   dd si5SBC, si5SBCS, si5RSC, si5RSCS
  4828.                   dd si5PSR1, si5TST, si5ToCPSR, si5TEQ
  4829.                   dd si5PSR3, si5CMP, si5PSR4, si5CMN  
  4830.                   dd si5ORR, si5ORRS, si5MOV, si5MOVS
  4831.                   dd si5BIC, si5BICS, si5MVN, si5MVNS
  4832.         rsTAB dd rsAND, rsANDS, rsEOR, rsEORS ;; 0  0  0  0  0
  4833.                   dd rsSUB, rsSUBS, rsRSB, rsRSBS ;; 0  0  1  0  0
  4834.                   dd rsADD, rsADDS, rsADC, rsADCS ;; 0  1  0  0  0
  4835.                   dd rsSBC, rsSBCS, rsRSC, rsRSCS ;; 0  1  1  0  0
  4836.                   dd rsUB, rsTST, rsBX, rsTEQ   ;; 1  0  0  0  0
  4837.                   dd rsUB, rsCMP, rsUB, rsCMN ;; 1  0  1  0  0
  4838.                   dd rsORR, rsORRS, rsMOV, rsMOVS ;; 1  1  0  0  0
  4839.                   dd rsBIC, rsBICS, rsMVN, rsMVNS ;; 1  1  1  0  0    
  4840.                   ;; LDR/STR Word/Byte Imm12
  4841.                                  ;; P  U  B  W  L            
  4842.         nTAB    dd n0, n1, n2, n3 ;; 0  0  0  0  0
  4843.                   dd n4, n5, n6, n7 ;; 0  0  1  0  0
  4844.                   dd n8, n9, n10, n11 ;; 0  1  0  0  0
  4845.                   dd n12, n13, n14, n15 ;; 0  1  1  0  0
  4846.                   dd n16, n17, n18, n19 ;; 1  0  0  0  0
  4847.                   dd n20, n21, n22, n23 ;; 1  0  1  0  0
  4848.                   dd n24, n25, n26, n27 ;; 1  1  0  0  0
  4849.                   dd n28, n29, n30, n31 ;; 1  1  1  0  0    
  4850.                 ;; LDR/STR Word/Byte Scaled                  
  4851.                                  ;; P  U  B  W  L            
  4852.         eTAB    dd e0, e1, e2, e3 ;; 0  0  0  0  0
  4853.                   dd e4, e5, e6, e7 ;; 0  0  1  0  0
  4854.                   dd e8, e9, e10, e11 ;; 0  1  0  0  0
  4855.                   dd e12, e13, e14, e15 ;; 0  1  1  0  0
  4856.                   dd e16, e17, e18, e19 ;; 1  0  0  0  0
  4857.                   dd e20, e21, e22, e23 ;; 1  0  1  0  0
  4858.                   dd e24, e25, e26, e27 ;; 1  1  0  0  0
  4859.                   dd e28, e29, e30, e31 ;; 1  1  1  0  0  
  4860.                  
  4861.                   ;; LDR/STR HalfWord/SByte Imm8 Hash
  4862.                               ;; P  U  X1 W X2      
  4863.         cTAB    dd c0, c1, c2, c3 ;; 0  0  0  0  0
  4864.                   dd c4, c5, c6, c7 ;; 0  0  1  0  0
  4865.                   dd c8, c9, c10, c11 ;; 0  1  0  0  0
  4866.                   dd c12, c13, c14, c15 ;; 0  1  1  0  0
  4867.                   dd c16, c17, c18, c19 ;; 1  0  0  0  0
  4868.                   dd c20, c21, c22, c23 ;; 1  0  1  0  0
  4869.                   dd c24, c25, c26, c27 ;; 1  1  0  0  0
  4870.                   dd c28, c29, c30, c31 ;; 1  1  1  0  0
  4871.                     ;; LDR/STR HalfWord/SByte  Rm, Rn Hash
  4872.                                                    ;; P  U  X1 W X2            
  4873.         pTAB    dd p0, p1, p2, p3 ;; 0  0  0  0  0
  4874.                   dd p4, p5, p6, p7 ;; 0  0  1  0  0
  4875.                   dd p8, p9, p10, p11 ;; 0  1  0  0  0
  4876.                   dd p12, p13, p14, p15 ;; 0  1  1  0  0
  4877.                   dd p16, p17, p18, p19 ;; 1  0  0  0  0
  4878.                   dd p20, p21, p22, p23 ;; 1  0  1  0  0
  4879.                   dd p24, p25, p26, p27 ;; 1  1  0  0  0
  4880.                   dd p28, p29, p30, p31 ;; 1  1  1  0  0
  4881.                                                   ;; P  U  X1 W X2  
  4882.                                                    ;; X1 X2     3:= LDRSH (7)
  4883.                                                    ;;        2:= STRHW (1)  
  4884.                                                    ;;        1:= LDRSB (6)
  4885.                                                    ;;        0:= LDRUH (5)  
  4886.                                  ;; LDM/STM Hash
  4887.                                  ;; P  U  S  W  L            
  4888.         zTAB    dd z0, z1, z2, z3 ;; 0  0  0  0  0
  4889.                   dd z4, z5, z6, z7 ;; 0  0  1  0  0
  4890.                   dd z8, z9, z10, z11 ;; 0  1  0  0  0
  4891.                   dd z12, z13, z14, z15 ;; 0  1  1  0  0
  4892.                   dd z16, z17, z18, z19 ;; 1  0  0  0  0
  4893.                   dd z20, z21, z22, z23 ;; 1  0  1  0  0
  4894.                   dd z24, z25, z26, z27 ;; 1  1  0  0  0
  4895.                   dd z28, z29, z30, z31 ;; 1  1  1  0  0
  4896.           fTAB dd fEQ, fNE, fCS, fCC
  4897.                    dd fMI, fPL, fVS, fVC
  4898.                   dd fHI, fLS, fGE, fLT
  4899.                   dd fGT, fLE, fAL, fNV
  4900.  
  4901.         pcMTAB dd 000h, 100b ;; 0 0 0
  4902.                    dd 000b, 000b ;; 0 1 0
  4903.                     dd 000b, 000b ;; 0 0 0
  4904.                    dd 0001b, 0101b ;; 0 1 0  
  4905.                    
  4906.         ARM7_MUL_TAB dd mMUL, mMULS, mMLA, mMLAS
  4907.                      dd mUB, mUB, mUB, mUB
  4908.                      dd mUMUL64, mUMUL64S, mUMLA64, mUMLA64S
  4909.                      dd mSMUL64, mSMUL64S, mSMLA64, mSMLA64S
  4910.                      ;; thumb alu
  4911.          taTAB dd taAND, taEOR, taLSL, taLSR
  4912.               dd taASR, taADC, taSBC, taROR
  4913.               dd taTST, taNEG, taCMP, taCMN
  4914.               dd taORR, taMUL, taBIC, taMVN
  4915.              
  4916.       ;; ALU Shift Imm5 / Shift Rs / MUL / MISC                  |                           |
  4917. 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
  4918.       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
  4919.       ;; ALU Imm8 Bitmap + 4bit Even Shift
  4920.       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
  4921.       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  
  4922.       ;; LDR/ STR Imm
  4923.       dd  LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12 ;;post index
  4924.       dd  LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12, LDI12 ;;preindex or std index
  4925.       ;; LDR/ STR Shift Rm
  4926.       dd  LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI
  4927.       dd  LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI, LDIRS, UDEFI
  4928.      
  4929.       ;; Negtive --------------------|---------------------------|---------------------------|---------------------------------------------------
  4930.      
  4931.       ;; Load/Stroe Multi
  4932.       dd  RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET
  4933.       dd  RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET, RGSET
  4934.       ;; Branch Sign Imm24 Without LRLINK
  4935.       dd  JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24, JMP24
  4936.       ;; Branch Sign Imm24 With LRLINK
  4937.       dd  JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR, JMPLR
  4938.       ;; FPU, GBA doesn't have to deal with these things, For Simple, Link it to int 3
  4939.       dd  COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT
  4940.       dd  COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT, COPDT
  4941.       dd  COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO, COPMO
  4942.       ;; GBA Bios Software Interrupt.
  4943.       dd  SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT, SWINT
  4944.  
  4945. sTAB dd  INLSL, INLSL, INLSL, INLSL, INLSL, INLSL, INLSL, INLSL, INLSR, INLSR, INLSR, INLSR, INLSR, INLSR, INLSR, INLSR
  4946.       dd  INASR, INASR, INASR, INASR, INASR, INASR, INASR, INASR, ADDRT, ADDRT, SUBRT, SUBRT, ADDI3, ADDI3, SUBI3, SUBI3
  4947.       dd  MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, MOVI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8, CMPI8  
  4948.       dd  ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, ADDI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8, SUBI8    
  4949.       dd  ALUOP, ALUOP, ALUOP, ALUOP, ADD16, CMP16, MOV16, BX_TB, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC, LDRPC
  4950.       dd  STRWD, STRWD, STRHW, STRHW, STRUB, STRUB, LDRSB, LDRSB, LDRWD, LDRWD, LDHW2, LDHW2, LDRUB, LDRUB, LDRSW, LDRSW
  4951.       dd  STRW5, STRW5, STRW5, STRW5, STRW5, STRW5, STRW5, STRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5, LDRW5
  4952.       dd  STRB5, STRB5, STRB5, STRB5, STRB5, STRB5, STRB5, STRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5, LDRB5
  4953.      
  4954.       ;; Negtive --------------------------------------------------------------------------------------------------------------------------------
  4955.       dd  STRH5, STRH5, STRH5, STRH5, STRH5, STRH5, STRH5, STRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5, LDRH5  
  4956.       dd  STRSP, STRSP, STRSP, STRSP, STRSP, STRSP, STRSP, STRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP, LDRSP
  4957.       dd  PCI08, PCI08, PCI08, PCI08, PCI08, PCI08, PCI08, PCI08, SPI08, SPI08, SPI08, SPI08, SPI08, SPI08, SPI08, SPI08
  4958.       dd  STKS7, UNDEF, UNDEF, UNDEF, PUSHR, PUSHR, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, POPRP, POPRP, UNDEF, UNDEF      
  4959.       dd  STMIA, STMIA, STMIA, STMIA, STMIA, STMIA, STMIA, STMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA, LDMIA
  4960.       dd  JCCEQ, JCCNE, JCCCS, JCCCC, JCCMI, JCCPL, JCCVS, JCCVC, JCCHI, JCCLS, JCCGE, JCCLT, JCCGT, JCCLE, JCCAL, SWI08  
  4961.       dd  JMP11, JMP11, JMP11, JMP11, JMP11, JMP11, JMP11, JMP11, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF
  4962.       dd  BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLEXT, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD, BLSTD
  4963.      
  4964.       .code
  4965.        
  4966. arm7tdmi_ticks endp
  4967.    
  4968.                  
  4969. end
  4970.  
  4971.  
  4972. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement