mirror of
				https://github.com/RaySollium99/picodrive.git
				synced 2025-10-27 00:29:39 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			627 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			627 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| @*
 | |
| @* Compiler helper functions and some SVP HLE code
 | |
| @* (C) notaz, 2008,2009
 | |
| @*
 | |
| @* This work is licensed under the terms of MAME license.
 | |
| @* See COPYING file in the top-level directory.
 | |
| @*
 | |
| 
 | |
| #include "../../arm_features.h"
 | |
| 
 | |
| .syntax unified
 | |
| .text
 | |
| .align 2
 | |
| 
 | |
| @       SSP_GR0, SSP_X,     SSP_Y,   SSP_A,
 | |
| @       SSP_ST,  SSP_STACK, SSP_PC,  SSP_P,
 | |
| @       SSP_PM0, SSP_PM1,   SSP_PM2, SSP_XST,
 | |
| @       SSP_PM4, SSP_gr13,  SSP_PMC, SSP_AL
 | |
| 
 | |
| @ register map:
 | |
| @ r4:  XXYY
 | |
| @ r5:  A
 | |
| @ r6:  STACK and emu flags: sss0 * .uu. .lll NZCV (NZCV is PSR bits from ARM)
 | |
| @ r7:  SSP context
 | |
| @ r8:  r0-r2 (.210)
 | |
| @ r9:  r4-r6 (.654)
 | |
| @ r10: P
 | |
| @ r11: cycles
 | |
| @ r12: tmp
 | |
| 
 | |
| 
 | |
| #define SSP_OFFS_GR         0x400
 | |
| #define SSP_PC                  6
 | |
| #define SSP_P                   7
 | |
| #define SSP_PM0                 8
 | |
| #define SSP_PMC                14
 | |
| #define SSP_OFFS_PM_WRITE   0x46c // pmac_write[]
 | |
| #define SSP_OFFS_EMUSTAT    0x484 // emu_status
 | |
| #define SSP_OFFS_IRAM_ROM   0x48c // ptr_iram_rom
 | |
| #define SSP_OFFS_DRAM       0x490 // ptr_dram
 | |
| #define SSP_OFFS_IRAM_DIRTY 0x494
 | |
| #define SSP_OFFS_IRAM_CTX   0x498 // iram_context
 | |
| #define SSP_OFFS_BLTAB      0x49c // block_table
 | |
| #define SSP_OFFS_BLTAB_IRAM 0x4a0
 | |
| #define SSP_OFFS_TMP0       0x4a4 // for entry PC
 | |
| #define SSP_OFFS_TMP1       0x4a8
 | |
| #define SSP_OFFS_TMP2       0x4ac
 | |
| #define SSP_WAIT_PM0       0x2000
 | |
| 
 | |
| 
 | |
| .macro ssp_drc_do_next patch_jump=0
 | |
| .if \patch_jump
 | |
|     str     lr, [r7, #SSP_OFFS_TMP2]		@ jump instr. (actually call) address + 4
 | |
| .endif
 | |
|     mov     r0, r0, lsl #16
 | |
|     mov     r0, r0, lsr #16
 | |
|     str     r0, [r7, #SSP_OFFS_TMP0]
 | |
|     cmp     r0, #0x400
 | |
|     blt     0f @ ssp_de_iram
 | |
| 
 | |
|     ldr     r2, [r7, #SSP_OFFS_BLTAB]
 | |
|     ldr     r2, [r2, r0, lsl #2]
 | |
|     tst     r2, r2
 | |
| .if \patch_jump
 | |
|     bne     ssp_drc_do_patch
 | |
| .else
 | |
|     bxne    r2
 | |
| .endif
 | |
|     bl      ssp_translate_block
 | |
|     mov     r2, r0
 | |
|     ldr     r0, [r7, #SSP_OFFS_TMP0]		@ entry PC
 | |
|     ldr     r1, [r7, #SSP_OFFS_BLTAB]
 | |
|     str     r2, [r1, r0, lsl #2]
 | |
| .if \patch_jump
 | |
|     b       ssp_drc_do_patch
 | |
| .else
 | |
|     bx      r2
 | |
| .endif
 | |
| 
 | |
| 0: @ ssp_de_iram:
 | |
|     ldr     r1, [r7, #SSP_OFFS_IRAM_DIRTY]
 | |
|     tst     r1, r1
 | |
|     ldreq   r1, [r7, #SSP_OFFS_IRAM_CTX]
 | |
|     beq     1f @ ssp_de_iram_ctx
 | |
| 
 | |
|     bl      ssp_get_iram_context
 | |
|     mov     r1, #0
 | |
|     str     r1, [r7, #SSP_OFFS_IRAM_DIRTY]
 | |
|     mov     r1, r0
 | |
|     str     r1, [r7, #SSP_OFFS_IRAM_CTX]
 | |
|     ldr     r0, [r7, #SSP_OFFS_TMP0]		@ entry PC
 | |
|     
 | |
| 1: @ ssp_de_iram_ctx:
 | |
|     ldr     r2, [r7, #SSP_OFFS_BLTAB_IRAM]
 | |
|     add     r2, r2, r1, lsl #12			@ block_tab_iram + iram_context * 0x800/2*4
 | |
|     add     r1, r2, r0, lsl #2
 | |
|     ldr     r2, [r1]
 | |
|     tst     r2, r2
 | |
| .if \patch_jump
 | |
|     bne     ssp_drc_do_patch
 | |
| .else
 | |
|     bxne    r2
 | |
| .endif
 | |
|     str     r1, [r7, #SSP_OFFS_TMP1]
 | |
|     bl      ssp_translate_block
 | |
|     mov     r2, r0
 | |
|     ldr     r0, [r7, #SSP_OFFS_TMP0]		@ entry PC
 | |
|     ldr     r1, [r7, #SSP_OFFS_TMP1]		@ &block_table_iram[iram_context][rPC]
 | |
|     str     r2, [r1]
 | |
| .if \patch_jump
 | |
|     b       ssp_drc_do_patch
 | |
| .else
 | |
|     bx      r2
 | |
| .endif
 | |
| .endm @ ssp_drc_do_next
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_drc_entry):
 | |
|     stmfd   sp!, {r4-r11, lr}
 | |
|     mov     r7, r0                      @ ssp
 | |
|     mov     r11, r1
 | |
| ssp_regfile_load:
 | |
|     add     r2, r7, #0x400
 | |
|     add     r2, r2, #4
 | |
|     ldmia   r2, {r3,r4,r5,r6,r8}
 | |
|     mov     r3, r3, lsr #16
 | |
|     mov     r3, r3, lsl #16
 | |
|     orr     r4, r3, r4, lsr #16         @ XXYY
 | |
| 
 | |
|     and     r8, r8, #0x0f0000
 | |
|     mov     r8, r8, lsl #13             @ sss0 *
 | |
|     and     r9, r6, #0x670000
 | |
|     tst     r6,     #0x80000000
 | |
|     orrne   r8, r8, #0x8
 | |
|     tst     r6,     #0x20000000
 | |
|     orrne   r8, r8, #0x4                @ sss0 *           NZ..
 | |
|     orr     r6, r8, r9, lsr #12         @ sss0 * .uu. .lll NZ..
 | |
| 
 | |
|     ldr     r8, [r7, #0x440]            @ r0-r2
 | |
|     ldr     r9, [r7, #0x444]            @ r4-r6
 | |
|     ldr     r10,[r7, #(0x400+SSP_P*4)]  @ P
 | |
| 
 | |
|     ldr     r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)]
 | |
|     mov     r0, r0, lsr #16
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_drc_next):
 | |
|     ssp_drc_do_next 0
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_drc_next_patch):
 | |
|     ssp_drc_do_next 1
 | |
| 
 | |
| ssp_drc_do_patch:
 | |
|     ldr     r1, [r7, #SSP_OFFS_TMP2]	@ jump instr. (actually call) address + 4
 | |
|     subs    r12,r2, r1
 | |
|     moveq   r3,     #0xe1000000
 | |
|     orreq   r3, r3, #0x00a00000		@ nop
 | |
|     streq   r3, [r1, #-4]
 | |
|     beq     ssp_drc_dp_end
 | |
| 
 | |
|     cmp     r12,#4
 | |
|     ldreq   r3, [r1]
 | |
|     addeq   r3, r3, #1
 | |
|     streq   r3, [r1, #-4]               @ move the other cond up
 | |
|     moveq   r3,     #0xe1000000
 | |
|     orreq   r3, r3, #0x00a00000
 | |
|     streq   r3, [r1]                    @ fill it's place with nop
 | |
|     beq     ssp_drc_dp_end
 | |
| 
 | |
|     ldr     r3, [r1, #-4]
 | |
|     sub     r12,r12,#4
 | |
|     mov     r3, r3, lsr #24
 | |
|     bic     r3, r3, #1			@ L bit
 | |
|     orr     r3, r3, r12,lsl #6
 | |
|     mov     r3, r3, ror #8              @ patched branch instruction
 | |
|     str     r3, [r1, #-4]               @ patch the bl/b to jump directly to another handler
 | |
| 
 | |
| ssp_drc_dp_end:
 | |
|     str     r2, [r7, #SSP_OFFS_TMP1]
 | |
|     sub     r0, r1, #4
 | |
|     add     r1, r1, #4
 | |
|     bl      cache_flush_d_inval_i
 | |
|     ldr     r2, [r7, #SSP_OFFS_TMP1]
 | |
|     ldr     r0, [r7, #SSP_OFFS_TMP0]
 | |
|     bx      r2
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_drc_end):
 | |
|     mov     r0, r0, lsl #16
 | |
|     str     r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)]
 | |
| 
 | |
| ssp_regfile_store:
 | |
|     str     r10,[r7, #(0x400+SSP_P*4)]  @ P
 | |
|     str     r8, [r7, #0x440]            @ r0-r2
 | |
|     str     r9, [r7, #0x444]            @ r4-r6
 | |
| 
 | |
|     mov     r9, r6, lsr #13
 | |
|     and     r9, r9, #(7<<16)            @ STACK
 | |
|     mov     r3, r6, lsl #28
 | |
|     msr     cpsr_f, r3                  @ to to ARM PSR
 | |
|     and     r6, r6, #0x670
 | |
|     mov     r6, r6, lsl #12
 | |
|     orrmi   r6, r6, #0x80000000         @ N
 | |
|     orreq   r6, r6, #0x20000000         @ Z
 | |
| 
 | |
|     mov     r3, r4, lsl #16             @ Y
 | |
|     mov     r2, r4, lsr #16
 | |
|     mov     r2, r2, lsl #16             @ X
 | |
|     add     r8, r7, #0x400
 | |
|     add     r8, r8, #4
 | |
|     stmia   r8, {r2,r3,r5,r6,r9}
 | |
| 
 | |
|     mov     r0, r11
 | |
|     ldmfd   sp!, {r4-r11, lr}
 | |
|     bx      lr
 | |
| 
 | |
| 
 | |
| 
 | |
| @ ld      A, PM0
 | |
| @ andi    2
 | |
| @ bra     z=1, gloc_0800
 | |
| FUNCTION(ssp_hle_800):
 | |
|     ldr     r0, [r7, #(SSP_OFFS_GR+SSP_PM0*4)]
 | |
|     ldr     r1, [r7, #SSP_OFFS_EMUSTAT]
 | |
|     tst     r0, #0x20000
 | |
|     orreq   r1, r1,  #SSP_WAIT_PM0
 | |
|     subeq   r11,r11, #1024
 | |
|     streq   r1, [r7, #SSP_OFFS_EMUSTAT]
 | |
|     mov     r0,     #0x400
 | |
|     beq     ssp_drc_end
 | |
|     orrne   r0, r0, #0x004
 | |
|     b       ssp_drc_next
 | |
| 
 | |
| 
 | |
| .macro hle_flushflags
 | |
|     bic     r6, r6, #0xf
 | |
|     mrs     r1, cpsr
 | |
|     orr     r6, r6, r1, lsr #28 
 | |
| .endm
 | |
| 
 | |
| .macro hle_popstack
 | |
|     sub     r6, r6, #0x20000000
 | |
|     add     r1, r7, #0x400
 | |
|     add     r1, r1, #0x048			@ stack
 | |
|     add     r1, r1, r6, lsr #28
 | |
|     ldrh    r0, [r1]
 | |
| .endm
 | |
| 
 | |
| FUNCTION(ssp_hle_902):
 | |
|     cmp     r11, #0
 | |
|     ble     ssp_drc_end
 | |
| 
 | |
|     add     r1, r7, #0x200
 | |
|     ldrh    r0, [r1]
 | |
|     ldr     r3, [r7, #SSP_OFFS_IRAM_ROM]
 | |
|     add     r2, r3, r0, lsl #1			@ (r7|00)
 | |
|     ldrh    r0, [r2], #2
 | |
|     mov     r5, r5, lsl #16
 | |
|     mov     r5, r5, lsr #16
 | |
|     bic     r0, r0, #0xfc00
 | |
|     add     r3, r3, r0, lsl #1 			@ IRAM dest
 | |
|     ldrh    r12,[r2], #2			@ length
 | |
|     bic     r3, r3, #3				@ always seen aligned
 | |
| @    orr     r5, r5, #0x08000000
 | |
| @    orr     r5, r5, #0x00880000
 | |
| @    sub     r5, r5, r12, lsl #16
 | |
|     bic     r6, r6, #0xf
 | |
|     add     r12,r12,#1
 | |
|     mov     r0, #1
 | |
|     str     r0, [r7, #SSP_OFFS_IRAM_DIRTY]
 | |
|     sub     r11,r11,r12,lsl #1
 | |
|     sub     r11,r11,r12				@ -= length*3
 | |
| 
 | |
| ssp_hle_902_loop:
 | |
|     ldrh    r0, [r2], #2
 | |
|     ldrh    r1, [r2], #2
 | |
|     subs    r12,r12,#2
 | |
|     orr     r0, r0, r1, lsl #16
 | |
|     str     r0, [r3], #4
 | |
|     bgt     ssp_hle_902_loop
 | |
| 
 | |
|     tst     r12, #1
 | |
|     ldrhne  r0, [r2], #2
 | |
|     strhne  r0, [r3], #2
 | |
| 
 | |
|     ldr     r0, [r7, #SSP_OFFS_IRAM_ROM]
 | |
|     add     r1, r7, #0x200
 | |
|     sub     r2, r2, r0
 | |
|     mov     r2, r2, lsr #1
 | |
|     strh    r2, [r1]				@ (r7|00)
 | |
| 
 | |
|     sub     r0, r3, r0
 | |
|     mov     r0, r0, lsr #1
 | |
|     orr     r0, r0, #0x08000000
 | |
|     orr     r0, r0, #0x001c8000
 | |
|     str     r0, [r7, #(SSP_OFFS_GR+SSP_PMC*4)]
 | |
|     str     r0, [r7, #(SSP_OFFS_PM_WRITE+4*4)]
 | |
| 
 | |
|     hle_popstack
 | |
|     subs    r11,r11,#16				@ timeslice is likely to end
 | |
|     ble     ssp_drc_end
 | |
|     b       ssp_drc_next
 | |
| 
 | |
| 
 | |
| @ this one is car rendering related
 | |
| .macro hle_11_12c_mla offs_in
 | |
|     ldrsh   r5, [r7, #(\offs_in+0)]
 | |
|     ldrsh   r0, [r7, #(\offs_in+2)]
 | |
|     ldrsh   r1, [r7, #(\offs_in+4)]
 | |
|     mul     r5, r2, r5
 | |
|     ldrsh   r12,[r7, #(\offs_in+6)]
 | |
|     mla     r5, r3, r0, r5
 | |
|     mla     r5, r4, r1, r5
 | |
|     add     r5, r5, r12,lsl #11
 | |
| 
 | |
|     movs    r5, r5, lsr #13
 | |
|     add     r1, r7, r8, lsr #23
 | |
|     strh    r5, [r1]
 | |
|     add     r8, r8, #(1<<24)
 | |
| .endm
 | |
| 
 | |
| FUNCTION(ssp_hle_11_12c):
 | |
|     cmp     r11, #0
 | |
|     ble     ssp_drc_end
 | |
| 
 | |
|     mov     r0, #0
 | |
|     bl      ssp_pm_read
 | |
|     mov     r4, r0
 | |
| 
 | |
|     mov     r0, #0
 | |
|     bl      ssp_pm_read
 | |
|     mov     r5, r0
 | |
| 
 | |
|     mov     r0, #0
 | |
|     bl      ssp_pm_read
 | |
| 
 | |
|     mov     r2, r4, lsl #16
 | |
|     mov     r2, r2, asr #15			@ (r7|00) << 1
 | |
|     mov     r3, r5, lsl #16
 | |
|     mov     r3, r3, asr #15			@ (r7|01) << 1
 | |
|     mov     r4, r0, lsl #16
 | |
|     mov     r4, r4, asr #15			@ (r7|10) << 1
 | |
| 
 | |
|     bic     r8, r8, #0xff
 | |
|     mov     r8, r8, ror #16
 | |
| 
 | |
|     hle_11_12c_mla 0x20
 | |
|     hle_11_12c_mla 0x28
 | |
|     hle_11_12c_mla 0x30
 | |
| 
 | |
|     mov     r8, r8, ror #16
 | |
|     orr     r8, r8, #0x1c
 | |
| @    hle_flushflags
 | |
|     hle_popstack
 | |
|     sub     r11,r11,#33
 | |
|     b       ssp_drc_next
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_hle_11_384):
 | |
|     mov     r3, #2
 | |
|     b       ssp_hle_11_38x
 | |
| 
 | |
| FUNCTION(ssp_hle_11_38a):
 | |
|     mov     r3, #3		@ r5
 | |
| 
 | |
| ssp_hle_11_38x:
 | |
|     cmp     r11, #0
 | |
|     ble     ssp_drc_end
 | |
| 
 | |
|     mov     r2, #0		@ EFh, EEh
 | |
|     mov     r1, #1		@ r4
 | |
|     add     r0, r7, #0x1c0	@ r0 (based)
 | |
| 
 | |
| ssp_hle_11_38x_loop:
 | |
|     ldrh    r5, [r0], #2
 | |
|     ldr     r12,[r7, #0x224]
 | |
|     mov     r5, r5, lsl #16
 | |
|     eor     r5, r5, r5, asr #31
 | |
|     add     r5, r5, r5, lsr #31	@ abs(r5)
 | |
|     cmp     r5, r12,lsl #16
 | |
|     orrpl   r2, r2, r1,lsl #16	@ EFh |= r4
 | |
| 
 | |
|     ldrh    r5, [r0, #2]!
 | |
|     ldr     r12,[r7, #0x220]
 | |
|     cmp     r5, r12,lsr #16
 | |
|     orrpl   r2, r2, r1,lsl #16	@ EFh |= r4
 | |
| 
 | |
|     ldr     r12,[r7, #0x1e8]
 | |
|     add     r0, r0, #2
 | |
|     mov     r12,r12,lsl #16
 | |
|     cmp     r5, r12,lsr #16
 | |
|     orrmi   r2, r2, r1
 | |
| 
 | |
|     mov     r1, r1, lsl #1
 | |
|     subs    r3, r3, #1
 | |
|     bpl     ssp_hle_11_38x_loop
 | |
| 
 | |
|     str     r2, [r7, #0x1dc]
 | |
|     sub     r0, r0, r7
 | |
|     bic     r8, r8, #0xff
 | |
|     orr     r8, r8, r0, lsr #1
 | |
|     bic     r9, r9, #0xff
 | |
|     orr     r9, r9, r1
 | |
| 
 | |
| @    hle_flushflags
 | |
|     hle_popstack
 | |
|     sub     r11,r11,#(9+30*4)
 | |
|     b       ssp_drc_next
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_hle_07_6d6):
 | |
|     cmp     r11, #0
 | |
|     ble     ssp_drc_end
 | |
| 
 | |
|     ldr     r1, [r7, #0x20c]
 | |
|     and     r0, r8, #0xff	@ assuming alignment
 | |
|     add     r0, r7, r0, lsl #1
 | |
|     mov     r2, r1, lsr #16
 | |
|     mov     r1, r1, lsl #16	@ 106h << 16
 | |
|     mov     r2, r2, lsl #16	@ 107h << 16
 | |
| 
 | |
| ssp_hle_07_6d6_loop:
 | |
|     ldr     r5, [r0], #4
 | |
|     tst     r5, r5
 | |
|     bmi     ssp_hle_07_6d6_end
 | |
|     mov     r5, r5, lsl #16
 | |
|     cmp     r5, r1
 | |
|     movmi   r1, r5
 | |
|     cmp     r5, r2
 | |
|     sub     r11,r11,#16
 | |
|     bmi     ssp_hle_07_6d6_loop
 | |
|     mov     r2, r5
 | |
|     b       ssp_hle_07_6d6_loop
 | |
| 
 | |
| ssp_hle_07_6d6_end:
 | |
|     sub     r0, r0, r7
 | |
|     mov     r0, r0, lsr #1
 | |
|     bic     r8, r8, #0xff
 | |
|     orr     r8, r8, r0
 | |
|     orr     r1, r2, r1, lsr #16
 | |
|     str     r1, [r7, #0x20c]
 | |
|     hle_popstack
 | |
|     sub     r11,r11,#6
 | |
|     b       ssp_drc_next
 | |
| 
 | |
| 
 | |
| FUNCTION(ssp_hle_07_030):
 | |
|     ldrh    r0, [r7]
 | |
|     mov     r0, r0, lsl #4
 | |
|     orr     r0, r0, r0, lsr #16
 | |
|     strh    r0, [r7]
 | |
|     sub     r11,r11,#3
 | |
| 
 | |
| FUNCTION(ssp_hle_07_036):
 | |
|     ldr     r1, [r7, #0x1e0]	@ F1h F0h
 | |
|     rsb     r5, r1, r1, lsr #16
 | |
|     mov     r5, r5, lsl #16	@ AL not needed
 | |
|     cmp     r5, #(4<<16)
 | |
|     sub     r11,r11,#5
 | |
|     bmi     hle_07_036_ending2
 | |
|     ldr     r1, [r7, #0x1dc]	@ EEh
 | |
|     cmp     r5, r1, lsl #16
 | |
|     sub     r11,r11,#5
 | |
|     bpl     hle_07_036_ret
 | |
| 
 | |
|     mov     r0, r5, lsr #16
 | |
|     add     r1, r7, #0x100
 | |
|     strh    r0, [r1, #0xea]	@ F5h
 | |
|     ldr     r0, [r7, #0x1e0]	@ F0h
 | |
|     and     r0, r0, #3
 | |
|     strh    r0, [r1, #0xf0]	@ F8h
 | |
|     add     r2, r0, #0xc0	@ r2
 | |
|     add     r2, r7, r2, lsl #1
 | |
|     ldrh    r2, [r2]
 | |
|     ldr     r0, [r7]
 | |
|     mov     r1, #4
 | |
|     and     r0, r0, r2
 | |
|     bl      ssp_pm_write
 | |
|     @ will handle PMC later
 | |
|     ldr     r0, [r7, #0x1e8]	@ F5h << 16
 | |
|     ldr     r1, [r7, #0x1f0]	@ F8h
 | |
|     ldr     r2, [r7, #0x1d4]	@ EAh
 | |
|     sub     r0, r0, #(3<<16)
 | |
|     add     r0, r0, r1, lsl #16
 | |
|     sub     r0, r2, r0, asr #18
 | |
|     and     r0, r0, #0x7f
 | |
|     rsbs    r0, r0, #0x78	@ length
 | |
|     ble     hle_07_036_ending1
 | |
| 
 | |
|     sub     r11,r11,r0
 | |
| 
 | |
|     @ copy part
 | |
|     ldr     r1, [r7, #(SSP_OFFS_GR+SSP_PMC*4)]
 | |
|     ldr     r2, [r7, #SSP_OFFS_DRAM]
 | |
|     mov     r1, r1, lsl #16
 | |
|     add     r1, r2, r1, lsr #15	@ addr (based)
 | |
|     ldrh    r2, [r7, #0]	@ pattern
 | |
|     ldrh    r3, [r7, #6]	@ mode
 | |
| 
 | |
|     mov     r12,    #0x4000
 | |
|     orr     r12,r12,#0x0018
 | |
|     subs    r12,r3, r12
 | |
|     subsne  r12,r12,#0x0400
 | |
|     blne    tr_unhandled
 | |
| 
 | |
|     orr     r2, r2, r2, lsl #16
 | |
|     tst     r3, #0x400
 | |
|     bne     hle_07_036_ovrwr
 | |
| 
 | |
| hle_07_036_no_ovrwr:
 | |
|     tst     r1, #2
 | |
|     strhne  r2, [r1], #0x3e	@ align
 | |
|     subne   r0, r0, #1
 | |
|     subs    r0, r0, #4
 | |
|     blt     hle_07_036_l2
 | |
| 
 | |
| hle_07_036_l1:
 | |
|     subs    r0, r0, #4
 | |
|     str     r2, [r1], #0x40
 | |
|     str     r2, [r1], #0x40
 | |
|     bge     hle_07_036_l1
 | |
| 
 | |
| hle_07_036_l2:
 | |
|     tst     r0, #2
 | |
|     strne   r2, [r1], #0x40
 | |
|     tst     r0, #1
 | |
|     strhne  r2, [r1], #2
 | |
|     b       hle_07_036_end_copy
 | |
| 
 | |
| hle_07_036_ovrwr:
 | |
|     tst     r2,     #0x000f
 | |
|     orreq   r12,r12,#0x000f
 | |
|     tst     r2,     #0x00f0
 | |
|     orreq   r12,r12,#0x00f0
 | |
|     tst     r2,     #0x0f00
 | |
|     orreq   r12,r12,#0x0f00
 | |
|     tst     r2,     #0xf000
 | |
|     orreq   r12,r12,#0xf000
 | |
|     orrs    r12,r12,r12,lsl #16
 | |
|     beq     hle_07_036_no_ovrwr
 | |
| 
 | |
|     tst     r1, #2
 | |
|     beq     hle_07_036_ol0
 | |
|     ldrh    r3, [r1]
 | |
|     and     r3, r3, r12
 | |
|     orr     r3, r3, r2
 | |
|     strh    r3, [r1], #0x3e	@ align
 | |
|     sub     r0, r0, #1
 | |
| 
 | |
| hle_07_036_ol0:
 | |
|     subs    r0, r0, #2
 | |
|     blt     hle_07_036_ol2
 | |
| 
 | |
| hle_07_036_ol1:
 | |
|     subs    r0, r0, #2
 | |
|     ldr     r3, [r1]
 | |
|     and     r3, r3, r12
 | |
|     orr     r3, r3, r2
 | |
|     str     r3, [r1], #0x40
 | |
|     bge     hle_07_036_ol1
 | |
| 
 | |
| hle_07_036_ol2:
 | |
|     tst     r0, #1
 | |
|     ldrhne  r3, [r1]
 | |
|     andne   r3, r3, r12
 | |
|     orrne   r3, r3, r2
 | |
|     strhne  r3, [r1], #2
 | |
| 
 | |
| hle_07_036_end_copy:
 | |
|     ldr     r2, [r7, #SSP_OFFS_DRAM]
 | |
|     add     r3, r7, #0x400
 | |
|     sub     r0, r1, r2          @ new addr
 | |
|     mov     r0, r0, lsr #1
 | |
|     strh    r0, [r3, #(0x6c+4*4)] @ SSP_OFFS_PM_WRITE+4*4 (low)
 | |
| 
 | |
| hle_07_036_ending1:
 | |
|     ldr     r0, [r7, #0x1e0]	@ F1h << 16
 | |
|     add     r0, r0, #(1<<16)
 | |
|     and     r0, r0, #(3<<16)
 | |
|     add     r0, r0, #(0xc4<<16)
 | |
|     bic     r8, r8, #0xff0000
 | |
|     orr     r8, r8, r0		@ r2
 | |
|     add     r0, r7, r0, lsr #15
 | |
|     ldrh    r0, [r0]
 | |
|     ldr     r2, [r7]
 | |
|     and     r0, r0, r2
 | |
|     movs    r5, r0, lsl #16
 | |
| 
 | |
|     ldr     r1, [r7, #4]	@ new mode
 | |
|     add     r2, r7, #0x400
 | |
|     strh    r1, [r2, #(0x6c+4*4+2)] @ SSP_OFFS_PM_WRITE+4*4 (high)
 | |
|     mov     r1, #4
 | |
|     bl      ssp_pm_write
 | |
|     sub     r11,r11,#35
 | |
| 
 | |
| hle_07_036_ret:
 | |
|     hle_popstack
 | |
|     b       ssp_drc_next
 | |
| 
 | |
| hle_07_036_ending2:
 | |
|     sub     r11,r11,#3
 | |
|     movs    r5, r5, lsl #1
 | |
|     bmi     hle_07_036_ret
 | |
|     mov     r0, #0x87
 | |
|     b       ssp_drc_next	@ let the dispatcher finish this
 | |
| 
 | |
| 
 | |
| @ ios stuff - preserving r9 on external calls
 | |
| #ifdef __MACH__
 | |
| 
 | |
| #define APPLE_WRAP(f) \
 | |
|   f:; \
 | |
|   push {r9,lr}; \
 | |
|   bl _##f; \
 | |
|   pop {r9,pc}
 | |
| 
 | |
| APPLE_WRAP(cache_flush_d_inval_i)
 | |
| APPLE_WRAP(ssp_get_iram_context)
 | |
| APPLE_WRAP(ssp_pm_read)
 | |
| APPLE_WRAP(ssp_pm_write)
 | |
| APPLE_WRAP(ssp_translate_block)
 | |
| APPLE_WRAP(tr_unhandled)
 | |
| 
 | |
| #endif
 | |
| 
 | |
| @ vim:filetype=armasm
 | 
