memory refactoring (mostly for cd) + ARM mem asm update
[picodrive.git] / pico / cd / memory_arm.s
1 @ vim:filetype=armasm
2
3 @ Memory I/O handlers for Sega/Mega CD emulation
4 @ (c) Copyright 2007-2009, Grazvydas "notaz" Ignotas
5
6
7 .equiv PCM_STEP_SHIFT, 11
8
9 .text
10 .align 2
11
12 .global PicoReadM68k8_io
13 .global PicoReadM68k16_io
14 .global PicoWriteM68k8_io
15 .global PicoWriteM68k16_io
16
17 .global PicoReadS68k8_pr
18 .global PicoReadS68k16_pr
19 .global PicoWriteS68k8_pr
20 .global PicoWriteS68k16_pr
21
22 .global PicoReadM68k8_cell0
23 .global PicoReadM68k8_cell1
24 .global PicoReadM68k16_cell0
25 .global PicoReadM68k16_cell1
26 .global PicoWriteM68k8_cell0
27 .global PicoWriteM68k8_cell1
28 .global PicoWriteM68k16_cell0
29 .global PicoWriteM68k16_cell1
30
31 .global PicoReadS68k8_dec0
32 .global PicoReadS68k8_dec1
33 .global PicoReadS68k16_dec0
34 .global PicoReadS68k16_dec1
35 .global PicoWriteS68k8_dec_m0b0
36 .global PicoWriteS68k8_dec_m1b0
37 .global PicoWriteS68k8_dec_m2b0
38 .global PicoWriteS68k8_dec_m0b1
39 .global PicoWriteS68k8_dec_m1b1
40 .global PicoWriteS68k8_dec_m2b1
41 .global PicoWriteS68k16_dec_m0b0
42 .global PicoWriteS68k16_dec_m1b0
43 .global PicoWriteS68k16_dec_m2b0
44 .global PicoWriteS68k16_dec_m0b1
45 .global PicoWriteS68k16_dec_m1b1
46 .global PicoWriteS68k16_dec_m2b1
47
48 @ externs, just for reference
49 .extern Pico
50 .extern Read_CDC_Host
51 .extern m68k_reg_write8
52 .extern s68k_reg_read16
53 .extern s68k_reg_write8
54 .extern s68k_poll_adclk
55 .extern s68k_poll_detect
56 .extern gfx_cd_read
57 .extern gfx_cd_write16
58 .extern PicoCpuCS68k
59 .extern PicoRead8_io
60 .extern PicoRead16_io
61 .extern PicoWrite8_io
62 .extern PicoWrite16_io
63
64
65 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
66
67 @ utilities
68
69 @ r0=addr[in,out], r1,r2=tmp
70 .macro cell_map
71     ands    r1, r0, #0x01c000
72     ldrne   pc, [pc, r1, lsr #12]
73     beq     0f                          @ most common?
74     .long   0f
75     .long   0f
76     .long   0f
77     .long   0f
78     .long   1f
79     .long   1f
80     .long   2f
81     .long   3f
82 1: @ x16 cells
83     and     r1, r0, #0x7e00             @ col
84     and     r2, r0, #0x01fc             @ row
85     orr     r2, r2, #0x0400
86     orr     r1, r2, r1, ror #13
87     b       9f
88 2: @ x8 cells
89     and     r1, r0, #0x3f00             @ col
90     and     r2, r0, #0x00fc             @ row
91     orr     r2, r2, #0x0600
92     orr     r1, r2, r1, ror #12
93     b       9f
94 3: @ x4 cells
95     and     r1, r0, #0x1f80             @ col
96     and     r2, r0, #0x007c             @ row
97     orr     r1, r2, r1, ror #11
98     and     r2, r0,#0x1e000
99     orr     r1, r1, r2, lsr #6
100     b       9f
101 0: @ x32 cells
102     and     r1, r0, #0xfc00             @ col
103     and     r2, r0, #0x03fc             @ row
104     orr     r1, r2, r1, ror #14
105 9:
106     and     r0, r0, #3
107     orr     r0, r0, r1, ror #26         @ rol 4+2
108 .endm
109
110
111 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
112
113
114 m_read_null:
115     mov     r0, #0
116     bx      lr
117
118
119 PicoReadM68k8_cell0:                    @ 0x220000 - 0x23ffff, cell arranged
120     mov     r3, #0x0c0000
121     b       0f
122
123 PicoReadM68k8_cell1:                    @ 0x220000 - 0x23ffff, cell arranged
124     mov     r3, #0x0e0000
125 0:
126     cell_map
127     ldr     r1, =(Pico+0x22200)
128     add     r0, r0, r3
129     ldr     r1, [r1]
130     eor     r0, r0, #1
131     ldrb    r0, [r1, r0]
132     bx      lr
133
134
135 PicoReadM68k8_io:
136     and     r1, r0, #0xff00
137     cmp     r1, #0x2000               @ a120xx?
138     bne     PicoRead8_io
139
140     ldr     r1, =(Pico+0x22200)
141     and     r0, r0, #0x3f
142     ldr     r1, [r1]                  @ Pico.mcd (used everywhere)
143     cmp     r0, #0x0e
144     ldrlt   pc, [pc, r0, lsl #2]
145     b       m_m68k_read8_hi
146     .long   m_m68k_read8_r00
147     .long   m_m68k_read8_r01
148     .long   m_m68k_read8_r02
149     .long   m_m68k_read8_r03
150     .long   m_m68k_read8_r04
151     .long   m_read_null               @ unused bits
152     .long   m_m68k_read8_r06
153     .long   m_m68k_read8_r07
154     .long   m_m68k_read8_r08
155     .long   m_m68k_read8_r09
156     .long   m_read_null               @ reserved
157     .long   m_read_null
158     .long   m_m68k_read8_r0c
159     .long   m_m68k_read8_r0d
160 m_m68k_read8_r00:
161     add     r1, r1, #0x110000
162     ldr     r0, [r1, #0x30]
163     and     r0, r0, #0x04000000       @ we need irq2 mask state
164     mov     r0, r0, lsr #19
165     bx      lr
166 m_m68k_read8_r01:
167     add     r1, r1, #0x110000
168     add     r1, r1, #0x002200
169     ldrb    r0, [r1, #2]              @ Pico_mcd->m.busreq
170     bx      lr
171 m_m68k_read8_r02:
172     add     r1, r1, #0x110000
173     ldrb    r0, [r1, #2]
174     bx      lr
175 m_m68k_read8_r03:
176     add     r1, r1, #0x110000
177     ldrb    r0, [r1, #3]
178     add     r1, r1, #0x002200
179     ldr     r1, [r1, #4]
180     and     r0, r0, #0xc7
181     tst     r1, #2                    @ DMNA pending?
182     bxeq    lr
183     bic     r0, r0, #1
184     orr     r0, r0, #2
185     bx      lr
186 m_m68k_read8_r04:
187     add     r1, r1, #0x110000
188     ldrb    r0, [r1, #4]
189     bx      lr
190 m_m68k_read8_r06:
191     ldrb    r0, [r1, #0x73]           @ IRQ vector
192     bx      lr
193 m_m68k_read8_r07:
194     ldrb    r0, [r1, #0x72]
195     bx      lr
196 m_m68k_read8_r08:
197     mov     r0, #0
198     bl      Read_CDC_Host             @ TODO: make it local
199     mov     r0, r0, lsr #8
200     bx      lr
201 m_m68k_read8_r09:
202     mov     r0, #0
203     b       Read_CDC_Host
204 m_m68k_read8_r0c:
205     add     r1, r1, #0x110000
206     add     r1, r1, #0x002200
207     ldr     r0, [r1, #0x14]           @ Pico_mcd->m.timer_stopwatch
208     mov     r0, r0, lsr #24
209     bx      lr
210 m_m68k_read8_r0d:
211     add     r1, r1, #0x110000
212     add     r1, r1, #0x002200
213     ldr     r0, [r1, #0x14]
214     mov     r0, r0, lsr #16
215     bx      lr
216 m_m68k_read8_hi:
217     cmp     r0, #0x30
218     movge   r0, #0
219     bxeq    lr
220     add     r1, r1, #0x110000
221     ldrb    r0, [r1, r0]
222     bx      lr
223
224
225 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
226
227
228 PicoReadM68k16_cell0:                   @ 0x220000 - 0x23ffff, cell arranged
229     mov     r3, #0x0c0000
230     b       0f
231
232 PicoReadM68k16_cell1:                   @ 0x220000 - 0x23ffff, cell arranged
233     mov     r3, #0x0e0000
234 0:
235     cell_map
236     ldr     r1, =(Pico+0x22200)
237     add     r0, r0, r3
238     ldr     r1, [r1]
239     bic     r0, r0, #1
240     ldrh    r0, [r1, r0]
241     bx      lr
242
243
244 PicoReadM68k16_io:
245     and     r1, r0, #0xff00
246     cmp     r1, #0x2000               @ a120xx
247     bne     PicoRead16_io
248
249 m_m68k_read16_m68k_regs:
250     ldr     r1, =(Pico+0x22200)
251     and     r0, r0, #0x3e
252     ldr     r1, [r1]                  @ Pico.mcd (used everywhere)
253     cmp     r0, #0x0e
254     ldrlt   pc, [pc, r0, lsl #1]
255     b       m_m68k_read16_hi
256     .long   m_m68k_read16_r00
257     .long   m_m68k_read16_r02
258     .long   m_m68k_read16_r04
259     .long   m_m68k_read16_r06
260     .long   m_m68k_read16_r08
261     .long   m_read_null               @ reserved
262     .long   m_m68k_read16_r0c
263 m_m68k_read16_r00:
264     add     r1, r1, #0x110000
265     ldr     r0, [r1, #0x30]
266     add     r1, r1, #0x002200
267     ldrb    r1, [r1, #2]              @ Pico_mcd->m.busreq
268     and     r0, r0, #0x04000000       @ we need irq2 mask state
269     orr     r0, r1, r0, lsr #11
270     bx      lr
271 m_m68k_read16_r02:
272     add     r1, r1, #0x110000
273     ldrb    r0, [r1, #2]
274     ldrb    r2, [r1, #3]
275     add     r1, r1, #0x002200
276     ldr     r1, [r1, #4]
277     and     r2, r2, #0xc7
278     orr     r0, r2, r0, lsl #8
279     tst     r1, #2                    @ DMNA pending?
280     bxeq    lr
281     bic     r0, r0, #1
282     orr     r0, r0, #2
283     bx      lr
284 m_m68k_read16_r04:
285     add     r1, r1, #0x110000
286     ldrb    r0, [r1, #4]
287     mov     r0, r0, lsl #8
288     bx      lr
289 m_m68k_read16_r06:
290     ldrh    r0, [r1, #0x72]           @ IRQ vector
291     bx      lr
292 m_m68k_read16_r08:
293     mov     r0, #0
294     b       Read_CDC_Host
295 m_m68k_read16_r0c:
296     add     r1, r1, #0x110000
297     add     r1, r1, #0x002200
298     ldr     r0, [r1, #0x14]
299     mov     r0, r0, lsr #16
300     bx      lr
301 m_m68k_read16_hi:
302     cmp     r0, #0x30
303     addlt   r1, r1, #0x110000
304     ldrlth  r1, [r1, r0]
305     movge   r0, #0
306     bxge    lr
307     mov     r0, r1, lsr #8
308     and     r1, r1, #0xff
309     orr     r0, r0, r1, lsl #8
310     bx      lr
311
312
313 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
314
315
316 PicoWriteM68k8_cell0:                   @ 0x220000 - 0x23ffff, cell arranged
317     mov     r12,#0x0c0000
318     b       0f
319
320 PicoWriteM68k8_cell1:                   @ 0x220000 - 0x23ffff, cell arranged
321     mov     r12,#0x0e0000
322 0:
323     mov     r3, r1
324     cell_map
325     ldr     r2, =(Pico+0x22200)
326     add     r0, r0, r12
327     ldr     r2, [r2]
328     eor     r0, r0, #1
329     strb    r3, [r2, r0]
330     bx      lr
331
332
333 PicoWriteM68k8_io:
334     and     r2, r0, #0xff00
335     cmp     r2, #0x2000                 @ a120xx?
336     beq     m68k_reg_write8
337     b       PicoWrite8_io
338
339
340 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
341
342
343 PicoWriteM68k16_cell0:                   @ 0x220000 - 0x23ffff, cell arranged
344     mov     r12, #0x0c0000
345     b       0f
346
347 PicoWriteM68k16_cell1:                   @ 0x220000 - 0x23ffff, cell arranged
348     mov     r12, #0x0e0000
349 0:
350     mov     r3, r1
351     cell_map
352     ldr     r1, =(Pico+0x22200)
353     add     r0, r0, r12
354     ldr     r1, [r1]
355     bic     r0, r0, #1
356     strh    r3, [r1, r0]
357     bx      lr
358
359
360 PicoWriteM68k16_io:
361     and     r2, r0, #0xff00
362     cmp     r2, #0x2000                 @ a120xx?
363     bne     PicoWrite16_io
364
365 m_m68k_write16_regs:
366     and     r0, r0, #0x3e
367     cmp     r0, #0x0e
368     beq     m_m68k_write16_regs_spec
369     and     r3, r1, #0xff
370     add     r2, r0, #1
371     stmfd   sp!,{r2,r3,lr}
372     mov     r1, r1, lsr #8
373     bl      m68k_reg_write8
374     ldmfd   sp!,{r0,r1,lr}
375     b       m68k_reg_write8
376
377 m_m68k_write16_regs_spec:               @ special case
378     ldr     r2, =(Pico+0x22200)
379     ldr     r3, =s68k_poll_adclk
380     mov     r0, #0x110000
381     ldr     r2, [r2]
382     add     r0, r0, #0x00000e
383     mov     r1, r1, lsr #8
384     strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0x0e] = d >> 8;
385     ldr     r2, [r3]
386     mov     r1, #0
387     and     r2, r2, #0xfe
388     cmp     r2, #0x0e
389     bxne    lr
390     ldr     r0, =PicoCpuCS68k
391     str     r1, [r0, #0x58]             @ push s68k out of stopped state
392     str     r1, [r3]
393     bx      lr
394
395
396 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
397 @                                   Sub 68k
398 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
399
400
401 PicoReadS68k8_dec0:                     @ 0x080000 - 0x0bffff
402     mov     r3, #0x080000               @ + ^ / 2
403     b       0f
404
405 PicoReadS68k8_dec1:
406     mov     r3, #0x0a0000               @ + ^ / 2
407 0:
408     ldr     r2, =(Pico+0x22200)
409     eor     r0, r0, #2
410     ldr     r2, [r2]
411     movs    r0, r0, lsr #1              @ +4-6 <<16
412     add     r2, r2, r3                  @ map to our address
413     ldrb    r0, [r2, r0]
414     movcc   r0, r0, lsr #4
415     andcs   r0, r0, #0xf
416     bx      lr
417
418
419 PicoReadS68k8_pr:
420     and     r2, r0, #0xfe00
421     cmp     r2, #0x8000
422     bne     m_s68k_read8_pcm
423
424 m_s68k_read8_regs:
425     bic     r0, r0, #0xff0000
426     bic     r0, r0, #0x008000
427     sub     r2, r0, #0x0e
428     cmp     r2, #(0x30-0x0e)
429     blo     m_s68k_read8_comm
430     sub     r2, r0, #0x58
431     cmp     r2, #0x10
432     ldrlo   r2, =gfx_cd_read
433     ldrhs   r2, =s68k_reg_read16
434     stmfd   sp!,{r0,lr}
435     bic     r0, r0, #1
436     mov     lr, pc
437     bx      r2
438     ldmfd   sp!,{r1,lr}
439     tst     r1, #1
440     moveq   r0, r0, lsr #8
441     and     r0, r0, #0xff
442     bx      lr
443
444 m_s68k_read8_comm:
445     ldr     r1, =(Pico+0x22200)
446     ldr     r1, [r1]
447     add     r1, r1, #0x110000
448     ldrb    r1, [r1, r0]
449     b       s68k_poll_detect
450
451
452 m_s68k_read8_pcm:
453     tst     r0, #0x8000
454     bne     m_read_null
455
456     @ must not trash r3 and r12
457     ldr     r1, =(Pico+0x22200)
458     bic     r0, r0, #0xff0000
459 @    bic     r0, r0, #0x008000
460     ldr     r1, [r1]
461     mov     r2, #0x110000
462     orr     r2, r2, #0x002200
463     cmp     r0, #0x2000
464     bge     m_s68k_read8_pcm_ram
465     cmp     r0, #0x20
466     movlt   r0, #0
467     bxlt    lr
468     orr     r2, r2, #(0x48+8)           @ pcm.ch + addr_offset
469     add     r1, r1, r2
470     and     r2, r0, #0x1c
471     ldr     r1, [r1, r2, lsl #2]
472     tst     r0, #2
473     moveq   r0, r1, lsr #PCM_STEP_SHIFT
474     movne   r0, r1, lsr #(PCM_STEP_SHIFT+8)
475     and     r0, r0, #0xff
476     bx      lr
477
478 m_s68k_read8_pcm_ram:
479     orr     r2, r2, #0x40
480     ldr     r2, [r1, r2]
481     add     r1, r1, #0x100000           @ pcm_ram
482     and     r2, r2, #0x0f000000         @ bank
483     add     r1, r1, r2, lsr #12
484     bic     r0, r0, #0x00e000
485     mov     r0, r0, lsr #1
486     ldrb    r0, [r1, r0]
487     bx      lr
488
489
490 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
491
492
493 PicoReadS68k16_dec0:                    @ 0x080000 - 0x0bffff
494     mov     r3, #0x080000               @ + ^ / 2
495     b       0f
496
497 PicoReadS68k16_dec1:
498     mov     r3, #0x0a0000               @ + ^ / 2
499 0:
500     ldr     r2, =(Pico+0x22200)
501     eor     r0, r0, #2
502     ldr     r2, [r2]
503     mov     r0, r0, lsr #1              @ +4-6 <<16
504     add     r2, r2, r3                  @ map to our address
505     ldrb    r0, [r2, r0]
506     orr     r0, r0, r0, lsl #4
507     bic     r0, r0, #0xf0
508     bx      lr
509
510
511 PicoReadS68k16_pr:
512     and     r2, r0, #0xfe00
513     cmp     r2, #0x8000
514     @ pcm is on 8-bit bus, would this be same as byte access?
515     bne     m_s68k_read8_pcm
516
517 m_s68k_read16_regs:
518     bic     r0, r0, #0xff0000
519     bic     r0, r0, #0x008000
520     bic     r0, r0, #0x000001
521     sub     r2, r0, #0x58
522     cmp     r2, #0x10
523     blo     gfx_cd_read
524     cmp     r0, #8
525     bne     s68k_reg_read16
526     mov     r0, #1
527     b       Read_CDC_Host
528
529
530 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
531
532
533 .macro m_s68k_write8_2M_decode
534     ldr     r2, =(Pico+0x22200)
535     eor     r0, r0, #2
536     ldr     r2, [r2]                    @ Pico.rom
537     movs    r0, r0, lsr #1              @ +4-6 <<16
538     add     r2, r2, r3                  @ map to our address
539 .endm
540
541 PicoWriteS68k8_dec_m2b0:                @ overwrite
542     ands    r1, r1, #0x0f
543     bxeq    lr
544
545 PicoWriteS68k8_dec_m0b0:
546     mov     r3, #0x080000
547     b       0f
548
549 PicoWriteS68k8_dec_m2b1:                @ overwrite
550     ands    r1, r1, #0x0f
551     bxeq    lr
552
553 PicoWriteS68k8_dec_m0b1:
554     mov     r3, #0x0a0000
555 0:
556     m_s68k_write8_2M_decode
557     ldrb    r0, [r2, r0]!
558     and     r1, r1, #0x0f
559     movcc   r1, r1, lsl #4
560     andcc   r3, r0, #0x0f
561     andcs   r3, r0, #0xf0
562     orr     r3, r3, r1
563     strneb  r3, [r2]
564     bx      lr
565
566 PicoWriteS68k8_dec_m1b0:                @ underwrite
567     mov     r3, #0x080000
568     b       0f
569
570 PicoWriteS68k8_dec_m1b1:
571     mov     r3, #0x0a0000
572 0:
573     ands    r1, r1, #0x0f
574     bxeq    lr
575     m_s68k_write8_2M_decode
576     ldrb    r0, [r2, r0]!
577     movcc   r1, r1, lsl #4
578     andcc   r3, r0, #0x0f
579     andcs   r3, r0, #0xf0
580     teq     r3, r0
581     bxne    lr
582     orr     r3, r3, r1
583     strneb  r3, [r2]
584     bx      lr
585
586
587 PicoWriteS68k8_pr:
588     and     r2, r0, #0xfe00
589     cmp     r2, #0x8000
590     bne     m_s68k_write8_pcm
591
592 m_s68k_write8_regs:
593     bic     r0, r0, #0xff0000
594     bic     r0, r0, #0x008000
595     tst     r0, #0x7e00
596     movne   r0, #0
597     bxne    lr
598     sub     r2, r0, #0x58
599     cmp     r2, #0x10
600     bhs     s68k_reg_write8
601     bic     r0, r0, #1
602     orr     r1, r1, r1, lsl #8
603     b       gfx_cd_write16
604
605
606 m_s68k_write8_pcm:
607     tst     r0, #0x8000
608     bxne    lr
609     bic     r0, r0, #0xff0000
610     cmp     r0, #0x12
611     movlt   r0, r0, lsr #1
612     blt     pcm_write
613
614     cmp     r0, #0x2000
615     bxlt    lr
616
617 m_s68k_write8_pcm_ram:
618     ldr     r3, =(Pico+0x22200)
619     bic     r0, r0, #0x00e000
620     ldr     r3, [r3]
621     mov     r0, r0, lsr #1
622     add     r2, r3, #0x110000
623     add     r2, r2, #0x002200
624     add     r2, r2, #0x000040
625     ldr     r2, [r2]
626     add     r3, r3, #0x100000           @ pcm_ram
627     and     r2, r2, #0x0f000000         @ bank
628     add     r3, r3, r2, lsr #12
629     strb    r1, [r3, r0]
630     bx      lr
631
632
633 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
634
635
636 .macro m_s68k_write16_2M_decode
637     ldr     r2, =(Pico+0x22200)
638     eor     r0, r0, #2
639     ldr     r2, [r2]
640     mov     r0, r0, lsr #1              @ +4-6 <<16
641     add     r2, r2, r3                  @ map to our address
642 .endm
643
644 PicoWriteS68k16_dec_m0b0:
645     mov     r3, #0x080000
646     b       0f
647
648 PicoWriteS68k16_dec_m0b1:
649     mov     r3, #0x0a0000
650 0:
651     m_s68k_write16_2M_decode
652     bic     r1, r1, #0xf0
653     orr     r1, r1, r1, lsr #4
654     strb    r1, [r2, r0]
655     bx      lr
656
657 PicoWriteS68k16_dec_m1b0:               @ underwrite
658     mov     r3, #0x080000
659     b       0f
660
661 PicoWriteS68k16_dec_m1b1:
662     mov     r3, #0x0a0000
663 0:
664     bics    r1, r1, #0xf000
665     bicnes  r1, r1, #0x00f0
666     bxeq    lr
667     orr     r1, r1, r1, lsr #4
668     m_s68k_write16_2M_decode
669     ldrb    r0, [r2, r0]!
670     and     r3, r1, #0x0f
671     and     r1, r1, #0xf0
672     tst     r0, #0x0f
673     orreq   r0, r0, r3
674     tst     r0, #0xf0
675     orreq   r0, r0, r1
676     strb    r0, [r2]
677     bx      lr
678
679 PicoWriteS68k16_dec_m2b0:               @ overwrite
680     mov     r3, #0x080000
681     b       0f
682
683 PicoWriteS68k16_dec_m2b1:
684     mov     r3, #0x0a0000
685 0:
686     bics    r1, r1, #0xf000
687     bicnes  r1, r1, #0x00f0
688     bxeq    lr
689     orr     r1, r1, r1, lsr #4
690     m_s68k_write16_2M_decode
691     ldrb    r0, [r2, r0]!
692     ands    r3, r1, #0x0f
693     andne   r0, r0, #0xf0
694     orrne   r0, r0, r3
695     ands    r1, r1, #0xf0
696     andne   r0, r0, #0x0f
697     orrne   r0, r0, r1
698     strb    r0, [r2]
699     bx      lr
700
701
702 PicoWriteS68k16_pr:
703     and     r2, r0, #0xfe00
704     cmp     r2, #0x8000
705     bne     m_s68k_write8_pcm
706
707 m_s68k_write16_regs:
708     bic     r0, r0, #0xff0000
709     bic     r0, r0, #0x008000
710     bic     r0, r0, #1
711     tst     r0, #0x7e00
712     movne   r0, #0
713     bxne    lr
714     cmp     r0, #0x0e
715     beq     m_s68k_write16_regs_spec
716     sub     r2, r0, #0x58
717     cmp     r2, #0x10
718     blo     gfx_cd_write16
719     and     r3, r1, #0xff
720     add     r2, r0, #1
721     stmfd   sp!,{r2,r3,lr}
722     mov     r1, r1, lsr #8
723     bl      s68k_reg_write8
724     ldmfd   sp!,{r0,r1,lr}
725     b       s68k_reg_write8
726
727 m_s68k_write16_regs_spec:               @ special case
728     ldr     r2, =(Pico+0x22200)
729     mov     r0, #0x110000
730     ldr     r2, [r2]
731     add     r0, r0, #0x00000f
732     strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0xf] = d;
733     bx      lr
734
735 .pool
736