(c) and stuff
[picodrive.git] / Pico / carthw / svp / stub_arm.S
1 @ vim:filetype=armasm
2
3 @ Compiler helper functions and some SVP HLE code
4
5 @ (c) Copyright 2008, Grazvydas "notaz" Ignotas
6 @ Free for non-commercial use.
7
8 .if 0
9 #include "compiler.h"
10 .endif
11
12 .global tcache
13 .global ssp_block_table
14 .global ssp_block_table_iram
15
16 .global flush_inval_caches
17 .global ssp_drc_entry
18 .global ssp_drc_next
19 .global ssp_drc_next_patch
20 .global ssp_drc_end
21 .global ssp_hle_800
22 .global ssp_hle_902
23 .global ssp_hle_07_030
24 .global ssp_hle_07_036
25 .global ssp_hle_07_6d6
26 .global ssp_hle_11_12c
27 .global ssp_hle_11_384
28 .global ssp_hle_11_38a
29
30 @ translation cache buffer + pointer table
31 .text
32 .align 12 @ 4096
33 .size tcache, SSP_TCACHE_SIZE
34 .size ssp_block_table, SSP_BLOCKTAB_SIZE
35 .size ssp_block_table_iram, SSP_BLOCKTAB_IRAM_SIZE
36 tcache:
37  .space SSP_TCACHE_SIZE
38 ssp_block_table:
39  .space SSP_BLOCKTAB_SIZE
40 ssp_block_table_iram:
41  .space SSP_BLOCKTAB_IRAM_SIZE
42  .space SSP_BLOCKTAB_ALIGN_SIZE
43
44
45 .text
46 .align 2
47
48
49 flush_inval_caches:
50     mov     r2, #0x0  @ must be 0
51     swi     0x9f0002
52     bx      lr
53
54
55 @       SSP_GR0, SSP_X,     SSP_Y,   SSP_A,
56 @       SSP_ST,  SSP_STACK, SSP_PC,  SSP_P,
57 @       SSP_PM0, SSP_PM1,   SSP_PM2, SSP_XST,
58 @       SSP_PM4, SSP_gr13,  SSP_PMC, SSP_AL
59
60 @ register map:
61 @ r4:  XXYY
62 @ r5:  A
63 @ r6:  STACK and emu flags: sss0 * .uu. .lll NZCV (NZCV is PSR bits from ARM)
64 @ r7:  SSP context
65 @ r8:  r0-r2 (.210)
66 @ r9:  r4-r6 (.654)
67 @ r10: P
68 @ r11: cycles
69
70
71 #define SSP_OFFS_GR         0x400
72 #define SSP_PC                  6
73 #define SSP_P                   7
74 #define SSP_PM0                 8
75 #define SSP_PMC                14
76 #define SSP_OFFS_PM_WRITE   0x46c // pmac_write[]
77 #define SSP_OFFS_EMUSTAT    0x484 // emu_status
78 #define SSP_OFFS_IRAM_ROM   0x48c // ptr_iram_rom
79 #define SSP_OFFS_DRAM       0x490 // ptr_dram
80 #define SSP_OFFS_IRAM_DIRTY 0x494
81 #define SSP_OFFS_IRAM_CTX   0x498 // iram_context
82 #define SSP_OFFS_BLTAB      0x49c // block_table
83 #define SSP_OFFS_BLTAB_IRAM 0x4a0
84 #define SSP_OFFS_TMP0       0x4a4 // for entry PC
85 #define SSP_OFFS_TMP1       0x4a8
86 #define SSP_OFFS_TMP2       0x4ac
87 #define SSP_WAIT_PM0       0x2000
88
89
90 .macro ssp_drc_do_next patch_jump=0
91 .if \patch_jump
92     str     lr, [r7, #SSP_OFFS_TMP2]            @ jump instr. (actually call) address + 4
93 .endif
94     mov     r0, r0, lsl #16
95     mov     r0, r0, lsr #16
96     str     r0, [r7, #SSP_OFFS_TMP0]
97     cmp     r0, #0x400
98     blt     0f @ ssp_de_iram
99
100     ldr     r2, [r7, #SSP_OFFS_BLTAB]
101     ldr     r2, [r2, r0, lsl #2]
102     tst     r2, r2
103 .if \patch_jump
104     bne     ssp_drc_do_patch
105 .else
106     bxne    r2
107 .endif
108     bl      ssp_translate_block
109     mov     r2, r0
110     ldr     r0, [r7, #SSP_OFFS_TMP0]            @ entry PC
111     ldr     r1, [r7, #SSP_OFFS_BLTAB]
112     str     r2, [r1, r0, lsl #2]
113 .if \patch_jump
114     b       ssp_drc_do_patch
115 .else
116     bx      r2
117 .endif
118
119 0: @ ssp_de_iram:
120     ldr     r1, [r7, #SSP_OFFS_IRAM_DIRTY]
121     tst     r1, r1
122     ldreq   r1, [r7, #SSP_OFFS_IRAM_CTX]
123     beq     1f @ ssp_de_iram_ctx
124
125     bl      ssp_get_iram_context
126     mov     r1, #0
127     str     r1, [r7, #SSP_OFFS_IRAM_DIRTY]
128     mov     r1, r0
129     str     r1, [r7, #SSP_OFFS_IRAM_CTX]
130     ldr     r0, [r7, #SSP_OFFS_TMP0]            @ entry PC
131     
132 1: @ ssp_de_iram_ctx:
133     ldr     r2, [r7, #SSP_OFFS_BLTAB_IRAM]
134     add     r2, r2, r1, lsl #12                 @ block_tab_iram + iram_context * 0x800/2*4
135     add     r1, r2, r0, lsl #2
136     ldr     r2, [r1]
137     tst     r2, r2
138 .if \patch_jump
139     bne     ssp_drc_do_patch
140 .else
141     bxne    r2
142 .endif
143     str     r1, [r7, #SSP_OFFS_TMP1]
144     bl      ssp_translate_block
145     mov     r2, r0
146     ldr     r0, [r7, #SSP_OFFS_TMP0]            @ entry PC
147     ldr     r1, [r7, #SSP_OFFS_TMP1]            @ &block_table_iram[iram_context][rPC]
148     str     r2, [r1]
149 .if \patch_jump
150     b       ssp_drc_do_patch
151 .else
152     bx      r2
153 .endif
154 .endm @ ssp_drc_do_next
155
156
157 ssp_drc_entry:
158     stmfd   sp!, {r4-r11, lr}
159     mov     r11, r0
160 ssp_regfile_load:
161     ldr     r7, =ssp
162     ldr     r7, [r7]
163     add     r2, r7, #0x400
164     add     r2, r2, #4
165     ldmia   r2, {r3,r4,r5,r6,r8}
166     mov     r3, r3, lsr #16
167     mov     r3, r3, lsl #16
168     orr     r4, r3, r4, lsr #16         @ XXYY
169
170     and     r8, r8, #0x0f0000
171     mov     r8, r8, lsl #13             @ sss0 *
172     and     r9, r6, #0x670000
173     tst     r6,     #0x80000000
174     orrne   r8, r8, #0x8
175     tst     r6,     #0x20000000
176     orrne   r8, r8, #0x4                @ sss0 *           NZ..
177     orr     r6, r8, r9, lsr #12         @ sss0 * .uu. .lll NZ..
178
179     ldr     r8, [r7, #0x440]            @ r0-r2
180     ldr     r9, [r7, #0x444]            @ r4-r6
181     ldr     r10,[r7, #(0x400+SSP_P*4)]  @ P
182
183     ldr     r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)]
184     mov     r0, r0, lsr #16
185
186
187 ssp_drc_next:
188     ssp_drc_do_next 0
189
190
191 ssp_drc_next_patch:
192     ssp_drc_do_next 1
193
194 ssp_drc_do_patch:
195     ldr     r1, [r7, #SSP_OFFS_TMP2]    @ jump instr. (actually call) address + 4
196     subs    r12,r2, r1
197     moveq   r3,     #0xe1000000
198     orreq   r3, r3, #0x00a00000         @ nop
199     streq   r3, [r1, #-4]
200     beq     ssp_drc_dp_end
201
202     cmp     r12,#4
203     ldreq   r3, [r1]
204     addeq   r3, r3, #1
205     streq   r3, [r1, #-4]               @ move the other cond up
206     moveq   r3,     #0xe1000000
207     orreq   r3, r3, #0x00a00000
208     streq   r3, [r1]                    @ fill it's place with nop
209     beq     ssp_drc_dp_end
210
211     ldr     r3, [r1, #-4]
212     sub     r12,r12,#4
213     mov     r3, r3, lsr #24
214     bic     r3, r3, #1                  @ L bit
215     orr     r3, r3, r12,lsl #6
216     mov     r3, r3, ror #8              @ patched branch instruction
217     str     r3, [r1, #-4]
218
219 ssp_drc_dp_end:
220     str     r2, [r7, #SSP_OFFS_TMP1]
221     sub     r0, r1, #4
222     add     r1, r1, #4
223     bl      flush_inval_caches
224     ldr     r2, [r7, #SSP_OFFS_TMP1]
225     ldr     r0, [r7, #SSP_OFFS_TMP0]
226     bx      r2
227
228
229 ssp_drc_end:
230     mov     r0, r0, lsl #16
231     str     r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)]
232
233 ssp_regfile_store:
234     str     r10,[r7, #(0x400+SSP_P*4)]  @ P
235     str     r8, [r7, #0x440]            @ r0-r2
236     str     r9, [r7, #0x444]            @ r4-r6
237
238     mov     r9, r6, lsr #13
239     and     r9, r9, #(7<<16)            @ STACK
240     mov     r3, r6, lsl #28
241     msr     cpsr_flg, r3                @ to to ARM PSR
242     and     r6, r6, #0x670
243     mov     r6, r6, lsl #12
244     orrmi   r6, r6, #0x80000000         @ N
245     orreq   r6, r6, #0x20000000         @ Z
246
247     mov     r3, r4, lsl #16             @ Y
248     mov     r2, r4, lsr #16
249     mov     r2, r2, lsl #16             @ X
250     add     r8, r7, #0x400
251     add     r8, r8, #4
252     stmia   r8, {r2,r3,r5,r6,r9}
253
254     mov     r0, r11
255     ldmfd   sp!, {r4-r11, lr}
256     bx      lr
257
258
259
260 @ ld      A, PM0
261 @ andi    2
262 @ bra     z=1, gloc_0800
263 ssp_hle_800:
264     ldr     r0, [r7, #(SSP_OFFS_GR+SSP_PM0*4)]
265     ldr     r1, [r7, #SSP_OFFS_EMUSTAT]
266     tst     r0, #0x20000
267     orreq   r1, r1,  #SSP_WAIT_PM0
268     subeq   r11,r11, #1024
269     streq   r1, [r7, #SSP_OFFS_EMUSTAT]
270     mov     r0,     #0x400
271     beq     ssp_drc_end
272     orrne   r0, r0, #0x004
273     b       ssp_drc_next
274
275
276 .macro hle_flushflags
277     bic     r6, r6, #0xf
278     mrs     r1, cpsr
279     orr     r6, r6, r1, lsr #28 
280 .endm
281
282 .macro hle_popstack
283     sub     r6, r6, #0x20000000
284     add     r1, r7, #0x400
285     add     r1, r1, #0x048                      @ stack
286     add     r1, r1, r6, lsr #28
287     ldrh    r0, [r1]
288 .endm
289
290 ssp_hle_902:
291     cmp     r11, #0
292     ble     ssp_drc_end
293
294     add     r1, r7, #0x200
295     ldrh    r0, [r1]
296     ldr     r3, [r7, #SSP_OFFS_IRAM_ROM]
297     add     r2, r3, r0, lsl #1                  @ (r7|00)
298     ldrh    r0, [r2], #2
299     mov     r5, r5, lsl #16
300     mov     r5, r5, lsr #16
301     bic     r0, r0, #0xfc00
302     add     r3, r3, r0, lsl #1                  @ IRAM dest
303     ldrh    r12,[r2], #2                        @ length
304     bic     r3, r3, #3                          @ always seen aligned
305 @    orr     r5, r5, #0x08000000
306 @    orr     r5, r5, #0x00880000
307 @    sub     r5, r5, r12, lsl #16
308     bic     r6, r6, #0xf
309     add     r12,r12,#1
310     mov     r0, #1
311     str     r0, [r7, #SSP_OFFS_IRAM_DIRTY]
312     sub     r11,r11,r12,lsl #1
313     sub     r11,r11,r12                         @ -= length*3
314
315 ssp_hle_902_loop:
316     ldrh    r0, [r2], #2
317     ldrh    r1, [r2], #2
318     subs    r12,r12,#2
319     orr     r0, r0, r1, lsl #16
320     str     r0, [r3], #4
321     bgt     ssp_hle_902_loop
322
323     tst     r12, #1
324     ldrneh  r0, [r2], #2
325     strneh  r0, [r3], #2
326
327     ldr     r0, [r7, #SSP_OFFS_IRAM_ROM]
328     add     r1, r7, #0x200
329     sub     r2, r2, r0
330     mov     r2, r2, lsr #1
331     strh    r2, [r1]                            @ (r7|00)
332
333     sub     r0, r3, r0
334     mov     r0, r0, lsr #1
335     orr     r0, r0, #0x08000000
336     orr     r0, r0, #0x001c8000
337     str     r0, [r7, #(SSP_OFFS_GR+SSP_PMC*4)]
338     str     r0, [r7, #(SSP_OFFS_PM_WRITE+4*4)]
339
340     hle_popstack
341     subs    r11,r11,#16                         @ timeslice is likely to end
342     ble     ssp_drc_end
343     b       ssp_drc_next
344
345
346 @ this one is car rendering related
347 .macro hle_11_12c_mla offs_in
348     ldrsh   r5, [r7, #(\offs_in+0)]
349     ldrsh   r0, [r7, #(\offs_in+2)]
350     ldrsh   r1, [r7, #(\offs_in+4)]
351     mul     r5, r2, r5
352     ldrsh   r12,[r7, #(\offs_in+6)]
353     mla     r5, r3, r0, r5
354     mla     r5, r4, r1, r5
355     add     r5, r5, r12,lsl #11
356
357     movs    r5, r5, lsr #13
358     add     r1, r7, r8, lsr #23
359     strh    r5, [r1]
360     add     r8, r8, #(1<<24)
361 .endm
362
363 ssp_hle_11_12c:
364     cmp     r11, #0
365     ble     ssp_drc_end
366
367     mov     r0, #0
368     bl      ssp_pm_read
369     mov     r4, r0
370
371     mov     r0, #0
372     bl      ssp_pm_read
373     mov     r5, r0
374
375     mov     r0, #0
376     bl      ssp_pm_read
377
378     mov     r2, r4, lsl #16
379     mov     r2, r2, asr #15                     @ (r7|00) << 1
380     mov     r3, r5, lsl #16
381     mov     r3, r3, asr #15                     @ (r7|01) << 1
382     mov     r4, r0, lsl #16
383     mov     r4, r4, asr #15                     @ (r7|10) << 1
384
385     bic     r8, r8, #0xff
386     mov     r8, r8, ror #16
387
388     hle_11_12c_mla 0x20
389     hle_11_12c_mla 0x28
390     hle_11_12c_mla 0x30
391
392     mov     r8, r8, ror #16
393     orr     r8, r8, #0x1c
394 @    hle_flushflags
395     hle_popstack
396     sub     r11,r11,#33
397     b       ssp_drc_next
398
399
400 ssp_hle_11_384:
401     mov     r3, #2
402     b       ssp_hle_11_38x
403
404 ssp_hle_11_38a:
405     mov     r3, #3              @ r5
406
407 ssp_hle_11_38x:
408     cmp     r11, #0
409     ble     ssp_drc_end
410
411     mov     r2, #0              @ EFh, EEh
412     mov     r1, #1              @ r4
413     add     r0, r7, #0x1c0      @ r0 (based)
414
415 ssp_hle_11_38x_loop:
416     ldrh    r5, [r0], #2
417     ldr     r12,[r7, #0x224]
418     mov     r5, r5, lsl #16
419     eor     r5, r5, r5, asr #31
420     add     r5, r5, r5, lsr #31 @ abs(r5)
421     cmp     r5, r12,lsl #16
422     orrpl   r2, r2, r1,lsl #16  @ EFh |= r4
423
424     ldrh    r5, [r0, #2]!
425     ldr     r12,[r7, #0x220]
426     cmp     r5, r12,lsr #16
427     orrpl   r2, r2, r1,lsl #16  @ EFh |= r4
428
429     ldr     r12,[r7, #0x1e8]
430     add     r0, r0, #2
431     mov     r12,r12,lsl #16
432     cmp     r5, r12,lsr #16
433     orrmi   r2, r2, r1
434
435     mov     r1, r1, lsl #1
436     subs    r3, r3, #1
437     bpl     ssp_hle_11_38x_loop
438
439     str     r2, [r7, #0x1dc]
440     sub     r0, r0, r7
441     bic     r8, r8, #0xff
442     orr     r8, r8, r0, lsr #1
443     bic     r9, r9, #0xff
444     orr     r9, r9, r1
445
446 @    hle_flushflags
447     hle_popstack
448     sub     r11,r11,#(9+30*4)
449     b       ssp_drc_next
450
451
452 ssp_hle_07_6d6:
453     cmp     r11, #0
454     ble     ssp_drc_end
455
456     ldr     r1, [r7, #0x20c]
457     and     r0, r8, #0xff       @ assuming alignment
458     add     r0, r7, r0, lsl #1
459     mov     r2, r1, lsr #16
460     mov     r1, r1, lsl #16     @ 106h << 16
461     mov     r2, r2, lsl #16     @ 107h << 16
462
463 ssp_hle_07_6d6_loop:
464     ldr     r5, [r0], #4
465     tst     r5, r5
466     bmi     ssp_hle_07_6d6_end
467     mov     r5, r5, lsl #16
468     cmp     r5, r1
469     movmi   r1, r5
470     cmp     r5, r2
471     sub     r11,r11,#16
472     bmi     ssp_hle_07_6d6_loop
473     mov     r2, r5
474     b       ssp_hle_07_6d6_loop
475
476 ssp_hle_07_6d6_end:
477     sub     r0, r0, r7
478     mov     r0, r0, lsr #1
479     bic     r8, r8, #0xff
480     orr     r8, r8, r0
481     orr     r1, r2, r1, lsr #16
482     str     r1, [r7, #0x20c]
483     hle_popstack
484     sub     r11,r11,#6
485     b       ssp_drc_next
486
487
488 ssp_hle_07_030:
489     ldrh    r0, [r7]
490     mov     r0, r0, lsl #4
491     orr     r0, r0, r0, lsr #16
492     strh    r0, [r7]
493     sub     r11,r11,#3
494
495 ssp_hle_07_036:
496     ldr     r1, [r7, #0x1e0]    @ F1h F0h
497     rsb     r5, r1, r1, lsr #16
498     mov     r5, r5, lsl #16     @ AL not needed
499     cmp     r5, #(4<<16)
500     sub     r11,r11,#5
501     bmi     hle_07_036_ending2
502     ldr     r1, [r7, #0x1dc]    @ EEh
503     cmp     r5, r1, lsl #16
504     sub     r11,r11,#5
505     bpl     hle_07_036_ret
506
507     mov     r0, r5, lsr #16
508     add     r1, r7, #0x100
509     strh    r0, [r1, #0xea]     @ F5h
510     ldr     r0, [r7, #0x1e0]    @ F0h
511     and     r0, r0, #3
512     strh    r0, [r1, #0xf0]     @ F8h
513     add     r2, r0, #0xc0       @ r2
514     add     r2, r7, r2, lsl #1
515     ldrh    r2, [r2]
516     ldr     r0, [r7]
517     mov     r1, #4
518     and     r0, r0, r2
519     bl      ssp_pm_write
520     @ will handle PMC later
521     ldr     r0, [r7, #0x1e8]    @ F5h << 16
522     ldr     r1, [r7, #0x1f0]    @ F8h
523     ldr     r2, [r7, #0x1d4]    @ EAh
524     sub     r0, r0, #(3<<16)
525     add     r0, r0, r1, lsl #16
526     sub     r0, r2, r0, asr #18
527     and     r0, r0, #0x7f
528     rsbs    r0, r0, #0x78       @ length
529     ble     hle_07_036_ending1
530
531     sub     r11,r11,r0
532
533     @ copy part
534     ldr     r1, [r7, #(SSP_OFFS_GR+SSP_PMC*4)]
535     ldr     r2, [r7, #SSP_OFFS_DRAM]
536     mov     r1, r1, lsl #16
537     add     r1, r2, r1, lsr #15 @ addr (based)
538     ldrh    r2, [r7, #0]        @ pattern
539     ldrh    r3, [r7, #6]        @ mode
540
541     mov     r12,    #0x4000
542     orr     r12,r12,#0x0018
543     subs    r12,r3, r12
544     subnes  r12,r12,#0x0400
545     blne    tr_unhandled
546
547     orr     r2, r2, r2, lsl #16
548     tst     r3, #0x400
549     bne     hle_07_036_ovrwr
550
551 hle_07_036_no_ovrwr:
552     tst     r1, #2
553     strneh  r2, [r1], #0x3e     @ align
554     subne   r0, r0, #1
555     subs    r0, r0, #4
556     blt     hle_07_036_l2
557
558 hle_07_036_l1:
559     subs    r0, r0, #4
560     str     r2, [r1], #0x40
561     str     r2, [r1], #0x40
562     bge     hle_07_036_l1
563
564 hle_07_036_l2:
565     tst     r0, #2
566     strne   r2, [r1], #0x40
567     tst     r0, #1
568     strneh  r2, [r1], #2
569     b       hle_07_036_end_copy
570
571 hle_07_036_ovrwr:
572     tst     r2,     #0x000f
573     orreq   r12,r12,#0x000f
574     tst     r2,     #0x00f0
575     orreq   r12,r12,#0x00f0
576     tst     r2,     #0x0f00
577     orreq   r12,r12,#0x0f00
578     tst     r2,     #0xf000
579     orreq   r12,r12,#0xf000
580     orrs    r12,r12,r12,lsl #16
581     beq     hle_07_036_no_ovrwr
582
583     tst     r1, #2
584     beq     hle_07_036_ol0
585     ldrh    r3, [r1]
586     and     r3, r3, r12
587     orr     r3, r3, r2
588     strh    r3, [r1], #0x3e     @ align
589     sub     r0, r0, #1
590
591 hle_07_036_ol0:
592     subs    r0, r0, #2
593     blt     hle_07_036_ol2
594
595 hle_07_036_ol1:
596     subs    r0, r0, #2
597     ldr     r3, [r1]
598     and     r3, r3, r12
599     orr     r3, r3, r2
600     str     r3, [r1], #0x40
601     bge     hle_07_036_ol1
602
603 hle_07_036_ol2:
604     tst     r0, #1
605     ldrneh  r3, [r1]
606     andne   r3, r3, r12
607     orrne   r3, r3, r2
608     strneh  r3, [r1], #2
609
610 hle_07_036_end_copy:
611     ldr     r2, [r7, #SSP_OFFS_DRAM]
612     add     r3, r7, #0x400
613     sub     r0, r1, r2          @ new addr
614     mov     r0, r0, lsr #1
615     strh    r0, [r3, #(0x6c+4*4)] @ SSP_OFFS_PM_WRITE+4*4 (low)
616
617 hle_07_036_ending1:
618     ldr     r0, [r7, #0x1e0]    @ F1h << 16
619     add     r0, r0, #(1<<16)
620     and     r0, r0, #(3<<16)
621     add     r0, r0, #(0xc4<<16)
622     bic     r8, r8, #0xff0000
623     orr     r8, r8, r0          @ r2
624     add     r0, r7, r0, lsr #15
625     ldrh    r0, [r0]
626     ldr     r2, [r7]
627     and     r0, r0, r2
628     movs    r5, r0, lsl #16
629
630     ldr     r1, [r7, #4]        @ new mode
631     add     r2, r7, #0x400
632     strh    r1, [r2, #(0x6c+4*4+2)] @ SSP_OFFS_PM_WRITE+4*4 (high)
633     mov     r1, #4
634     bl      ssp_pm_write
635     sub     r11,r11,#35
636
637 hle_07_036_ret:
638     hle_popstack
639     b       ssp_drc_next
640
641 hle_07_036_ending2:
642     sub     r11,r11,#3
643     movs    r5, r5, lsl #1
644     bmi     hle_07_036_ret
645     mov     r0, #0x87
646     b       ssp_drc_next        @ let the dispatcher finish this
647