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