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