1.30 release
[picodrive.git] / Pico / cd / Memory.s
1 @ vim:filetype=armasm
2
3 @ Memory i/o handlers for Sega/Mega CD emulation
4 @ (c) Copyright 2007, Grazvydas "notaz" Ignotas
5 @ All Rights Reserved
6
7
8
9 .equiv PCM_STEP_SHIFT, 11
10 .equiv POLL_LIMIT, 16
11
12 @ jump tables
13 .data
14 .align 4
15
16 .altmacro
17 .macro mk_m68k_jump_table on sz @ operation name, size
18     .long   m_m68k_&\on&\sz&_bios           @ 0x000000 - 0x01ffff
19     .long   m_m68k_&\on&\sz&_prgbank        @ 0x020000 - 0x03ffff
20     .long   m_&\on&_null, m_&\on&_null      @ 0x040000 - 0x07ffff
21     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x080000 - 0x0fffff
22     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x100000 - 0x17ffff
23     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x180000 - 0x1fffff
24     .long   m_m68k_&\on&\sz&_wordram0_2M    @ 0x200000 - 0x21ffff
25     .long   m_m68k_&\on&\sz&_wordram1_2M    @ 0x220000 - 0x23ffff
26     .long   m_&\on&_null, m_&\on&_null      @ 0x240000 - 0x27ffff
27     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x280000 - 0x2fffff
28     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x300000
29     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x3fffff
30     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x400000
31     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x4fffff
32     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x500000
33     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x5fffff
34     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x600000
35     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x6fffff
36     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x700000
37     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x7fffff
38     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x800000
39     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x8fffff
40     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x900000
41     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0x9fffff
42     .long   m_m68k_&\on&\sz&_system_io      @ 0xa00000 - 0xa1ffff
43     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null               @ 0xa20000 - 0xa7ffff
44     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0xa80000 - 0xafffff
45     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0xb00000
46     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0xbfffff
47     .long   m_m68k_&\on&\sz&_vdp, m_m68k_&\on&\sz&_vdp, m_m68k_&\on&\sz&_vdp, m_m68k_&\on&\sz&_vdp @ 0xc00000
48     .long   m_m68k_&\on&\sz&_vdp, m_m68k_&\on&\sz&_vdp, m_m68k_&\on&\sz&_vdp, m_m68k_&\on&\sz&_vdp @          - 0xcfffff
49     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0xd00000
50     .long   m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @          - 0xdfffff
51     .long   m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram @ 0xe00000
52     .long   m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram @          - 0xefffff
53     .long   m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram @ 0xf00000
54     .long   m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram, m_m68k_&\on&\sz&_ram @          - 0xffffff
55 .endm
56
57 .macro mk_s68k_jump_table on sz @ operation name, size
58     .long   m_s68k_&\on&\sz&_prg, m_s68k_&\on&\sz&_prg, m_s68k_&\on&\sz&_prg, m_s68k_&\on&\sz&_prg            @ 0x000000 - 0x07ffff
59     .long   m_s68k_&\on&\sz&_wordram_2M     @ 0x080000 - 0x09ffff
60     .long   m_s68k_&\on&\sz&_wordram_2M     @ 0x0a0000 - 0x0bffff
61     .long   m_&\on&_null                    @ 0x0c0000 - 0x0dffff, 1M area
62     .long   m_&\on&_null                    @ 0x0e0000 - 0x0fffff
63 .endm
64
65
66 @ the jumptables themselves.
67 m_m68k_read8_table:   mk_m68k_jump_table read 8
68 m_m68k_read16_table:  mk_m68k_jump_table read 16
69 m_m68k_read32_table:  mk_m68k_jump_table read 32
70 m_m68k_write8_table:  mk_m68k_jump_table write 8
71 m_m68k_write16_table: mk_m68k_jump_table write 16
72 m_m68k_write32_table: mk_m68k_jump_table write 32
73
74 m_s68k_read8_table:   mk_s68k_jump_table read 8
75 m_s68k_read16_table:  mk_s68k_jump_table read 16
76 m_s68k_read32_table:  mk_s68k_jump_table read 32
77 m_s68k_write8_table:  mk_s68k_jump_table write 8
78 m_s68k_write16_table: mk_s68k_jump_table write 16
79 m_s68k_write32_table: mk_s68k_jump_table write 32
80
81 m_s68k_decode_write_table:
82     .long m_s68k_write8_2M_decode_b0_m0
83     .long m_s68k_write16_2M_decode_b0_m0
84     .long m_s68k_write32_2M_decode_b0_m0
85     .long m_s68k_write8_2M_decode_b0_m1
86     .long m_s68k_write16_2M_decode_b0_m1
87     .long m_s68k_write32_2M_decode_b0_m1
88     .long m_s68k_write8_2M_decode_b0_m2
89     .long m_s68k_write16_2M_decode_b0_m2
90     .long m_s68k_write32_2M_decode_b0_m2
91     .long m_s68k_write8_2M_decode_b1_m0
92     .long m_s68k_write16_2M_decode_b1_m0
93     .long m_s68k_write32_2M_decode_b1_m0
94     .long m_s68k_write8_2M_decode_b1_m1
95     .long m_s68k_write16_2M_decode_b1_m1
96     .long m_s68k_write32_2M_decode_b1_m1
97     .long m_s68k_write8_2M_decode_b1_m2
98     .long m_s68k_write16_2M_decode_b1_m2
99     .long m_s68k_write32_2M_decode_b1_m2
100
101
102 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
103
104 .text
105 .align 4
106
107 .global PicoMemResetCD
108 .global PicoMemResetCDdecode
109 .global PicoReadM68k8
110 .global PicoReadM68k16
111 .global PicoReadM68k32
112 .global PicoWriteM68k8
113 .global PicoWriteM68k16
114 .global PicoWriteM68k32
115 .global PicoReadS68k8
116 .global PicoReadS68k16
117 .global PicoReadS68k32
118 .global PicoWriteS68k8
119 .global PicoWriteS68k16
120 .global PicoWriteS68k32
121
122 @ externs, just for reference
123 .extern Pico
124 .extern z80Read8
125 .extern OtherRead16
126 .extern PicoVideoRead
127 .extern Read_CDC_Host
128 .extern m68k_reg_write8
129 .extern OtherWrite8
130 .extern OtherWrite16
131 .extern gfx_cd_read
132 .extern s68k_reg_read16
133 .extern SRam
134 .extern gfx_cd_write16
135 .extern s68k_reg_write8
136 .extern s68k_poll_adclk
137 .extern PicoCpuS68k
138
139
140 @ r0=reg3, r1-r3=temp
141 .macro mk_update_table on sz @ operation name, size
142     @ we only set word-ram handlers
143     ldr     r1, =m_m68k_&\on&\sz&_table
144     ldr     r12,=m_s68k_&\on&\sz&_table
145     tst     r0, #4
146     bne     0f @ pmr_8_1M
147
148 @ pmr_8_2M:
149     ldr     r2, =m_m68k_&\on&\sz&_wordram0_2M
150     ldr     r3, =m_s68k_&\on&\sz&_wordram_2M
151     str     r2, [r1, #16*4]
152     str     r2, [r1, #17*4]
153     ldr     r2, =m_&\on&_null
154     str     r3, [r12,#4*4]
155     str     r3, [r12,#5*4]
156     str     r2, [r12,#6*4]
157     b       9f @ pmr_8_done
158
159 0: @ pmr_8_1M:
160     tst     r0, #1
161     bne     1f @ pmr_8_1M1
162
163 @ pmr_8_1M0:
164     ldr     r2, =m_m68k_&\on&\sz&_wordram0_1M_b0
165     ldr     r3, =m_m68k_&\on&\sz&_wordram1_1M_b0
166     str     r2, [r1, #16*4]
167     str     r3, [r1, #17*4]
168     ldr     r3, =m_s68k_&\on&\sz&_wordram_1M_b1
169 .ifeqs "\on", "read"
170     ldr     r2, =m_s68k_&\on&\sz&_wordram_2M_decode_b1
171     str     r2, [r12,#4*4]
172     str     r2, [r12,#5*4]
173 .endif
174     str     r3, [r12,#6*4]
175     b       9f @ pmr_8_done
176
177 1: @ pmr_8_1M1:
178     ldr     r2, =m_m68k_&\on&\sz&_wordram0_1M_b1
179     ldr     r3, =m_m68k_&\on&\sz&_wordram1_1M_b1
180     str     r2, [r1, #16*4]
181     str     r3, [r1, #17*4]
182     ldr     r3, =m_s68k_&\on&\sz&_wordram_1M_b0
183 .ifeqs "\on", "read"
184     ldr     r2, =m_s68k_&\on&\sz&_wordram_2M_decode_b0
185     str     r2, [r12,#4*4]
186     str     r2, [r12,#5*4]
187 .endif
188     str     r3, [r12,#6*4]
189
190 9: @ pmr_8_done:
191 .endm
192
193
194 PicoMemResetCD: @ r3
195     mk_update_table read 8
196     mk_update_table read 16
197     mk_update_table read 32
198     mk_update_table write 8
199     mk_update_table write 16
200     mk_update_table write 32
201     bx      lr
202
203
204 PicoMemResetCDdecode: @reg3
205     tst     r0, #4
206     bxeq    lr                 @ we should not be called in 2M mode
207     ldr     r1, =m_s68k_write8_table
208     ldr     r3, =m_s68k_decode_write_table
209     and     r2, r0, #0x18
210     mov     r2, r2, lsr #3
211     cmp     r2, #3
212     moveq   r2, #2             @ mode3 is same as mode2?
213     tst     r0, #1
214     addeq   r2, r2, #3         @ bank1 (r2=0..5)
215     add     r2, r2, r2, lsl #1 @ *= 3
216     add     r2, r3, r2, lsl #2
217     ldmia   r2, {r0,r3,r12}
218     str     r0, [r1, #4*4]
219     str     r0, [r1, #5*4]
220     str     r3, [r1, #4*4+8*4]
221     str     r3, [r1, #5*4+8*4]
222     str     r12,[r1, #4*4+8*4*2]
223     str     r12,[r1, #5*4+8*4*2]
224     bx      lr
225
226
227 .pool
228
229 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
230
231 .macro mk_entry_m68k table
232     ldr     r2, =\table
233     bic     r0, r0, #0xff000000
234     and     r3, r0, #0x00fe0000
235     ldr     pc, [r2, r3, lsr #15]
236 .endm
237
238 PicoReadM68k8: @ u32 a
239     mk_entry_m68k m_m68k_read8_table
240
241 PicoReadM68k16: @ u32 a
242     mk_entry_m68k m_m68k_read16_table
243
244 PicoReadM68k32: @ u32 a
245     mk_entry_m68k m_m68k_read32_table
246
247 PicoWriteM68k8: @ u32 a, u8 d
248     mk_entry_m68k m_m68k_write8_table
249
250 PicoWriteM68k16: @ u32 a, u16 d
251     mk_entry_m68k m_m68k_write16_table
252
253 PicoWriteM68k32: @ u32 a, u32 d
254     mk_entry_m68k m_m68k_write32_table
255
256
257 .macro mk_entry_s68k on sz
258     bic     r0, r0, #0xff000000
259     cmp     r0, #0x00080000
260     blt     m_s68k_&\on&\sz&_prg
261     cmp     r0, #0x000e0000
262     ldrlt   r2, =m_s68k_&\on&\sz&_table
263     andlt   r3, r0, #0x000e0000
264     ldrlt   pc, [r2, r3, lsr #15]
265     mov     r3,     #0x00ff0000
266     orr     r3, r3, #0x00008000
267     cmp     r0, r3
268     bge     m_s68k_&\on&\sz&_regs
269     cmp     r0, #0x00ff0000
270     bge     m_s68k_&\on&\sz&_pcm
271     cmp     r0, #0x00fe0000
272     bge     m_s68k_&\on&\sz&_backup
273     mov     r0, #0
274     bx      lr
275 .endm
276
277 PicoReadS68k8: @ u32 a
278     mk_entry_s68k read 8
279
280 PicoReadS68k16: @ u32 a
281     mk_entry_s68k read 16
282
283 PicoReadS68k32: @ u32 a
284     mk_entry_s68k read 32
285
286 PicoWriteS68k8: @ u32 a, u8 d
287     mk_entry_s68k write 8
288
289 PicoWriteS68k16: @ u32 a, u16 d
290     mk_entry_s68k write 16
291
292 PicoWriteS68k32: @ u32 a, u32 d
293     mk_entry_s68k write 32
294
295
296 .pool
297
298 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
299
300 @ utilities
301
302 @ r0=addr[in,out], r1,r2=tmp
303 .macro cell_map
304     ands    r1, r0, #0x01c000
305     ldrne   pc, [pc, r1, lsr #12]
306     beq     0f                          @ most common?
307     .long   0f
308     .long   0f
309     .long   0f
310     .long   0f
311     .long   1f
312     .long   1f
313     .long   2f
314     .long   3f
315 1: @ x16 cells
316     and     r1, r0, #0x7e00             @ col
317     and     r2, r0, #0x01fc             @ row
318     orr     r2, r2, #0x0400
319     orr     r1, r2, r1, ror #13
320     b       9f
321 2: @ x8 cells
322     and     r1, r0, #0x3f00             @ col
323     and     r2, r0, #0x00fc             @ row
324     orr     r2, r2, #0x0600
325     orr     r1, r2, r1, ror #12
326     b       9f
327 3: @ x4 cells
328     and     r1, r0, #0x1f80             @ col
329     and     r2, r0, #0x007c             @ row
330     orr     r1, r2, r1, ror #11
331     and     r2, r0,#0x1e000
332     orr     r1, r1, r2, lsr #6
333     b       9f
334 0: @ x32 cells
335     and     r1, r0, #0xfc00             @ col
336     and     r2, r0, #0x03fc             @ row
337     orr     r1, r2, r1, ror #14
338 9:
339     and     r0, r0, #3
340     orr     r0, r0, r1, ror #26         @ rol 4+2
341 .endm
342
343
344 @ r0=prt1, r1=ptr2; unaligned ptr MUST be r0
345 .macro m_read32_gen
346     tst     r0, #2
347     ldrneh  r0, [r1, r0]!
348     ldrneh  r1, [r1, #2]
349     ldreq   r0, [r1, r0]
350     moveq   r0, r0, ror #16
351     orrne   r0, r1, r0, lsl #16
352 .endm
353
354
355 @ r0=prt1, r1=data, r2=ptr2; unaligned ptr MUST be r0
356 .macro m_write32_gen
357     tst     r0, #2
358     mov     r1, r1, ror #16
359     strneh  r1, [r2, r0]!
360     movne   r1, r1, lsr #16
361     strneh  r1, [r2, #2]
362     streq   r1, [r2, r0]
363 .endm
364
365
366 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
367
368
369 m_read_null:
370     mov     r0, #0
371     bx      lr
372
373
374 m_m68k_read8_bios:
375     ldr     r1, =(Pico+0x22200)
376     bic     r0, r0, #0xfe0000
377     ldr     r1, [r1]
378     eor     r0, r0, #1
379     ldrb    r0, [r1, r0]
380     bx      lr
381
382
383 m_m68k_read8_prgbank:
384     ldr     r1, =(Pico+0x22200)
385     eor     r0, r0, #1
386     ldr     r1, [r1]
387     mov     r2, #0x110000
388     orr     r3, r2, #0x002200
389     ldr     r3, [r1, r3]
390     ldr     r2, [r1, r2]
391     tst     r3, #0x00020000             @ have bus?
392     moveq   r0, #0
393     bxeq    lr
394     and     r2, r2, #0xc0000000         @ r3 & 0xC0
395     add     r1, r1, r2, lsr #12
396     ldrb    r0, [r1, r0]
397     bx      lr
398
399
400 m_m68k_read8_wordram0_2M:               @ 0x200000 - 0x21ffff
401 m_m68k_read8_wordram1_2M:               @ 0x220000 - 0x23ffff
402     ldr     r1, =(Pico+0x22200)
403     sub     r0, r0, #0x160000           @ map to our offset, which is 0x0a0000
404     ldr     r1, [r1]
405     eor     r0, r0, #1
406     ldrb    r0, [r1, r0]
407     bx      lr
408
409
410 m_m68k_read8_wordram0_1M_b0:            @ 0x200000 - 0x21ffff
411     ldr     r1, =(Pico+0x22200)
412     sub     r0, r0, #0x140000           @ map to our offset, which is 0x0c0000
413     ldr     r1, [r1]
414     eor     r0, r0, #1
415     ldrb    r0, [r1, r0]
416     bx      lr
417
418
419 m_m68k_read8_wordram0_1M_b1:            @ 0x200000 - 0x21ffff
420     ldr     r1, =(Pico+0x22200)
421     sub     r0, r0, #0x120000           @ map to our offset, which is 0x0e0000
422     ldr     r1, [r1]
423     eor     r0, r0, #1
424     ldrb    r0, [r1, r0]
425     bx      lr
426
427
428 m_m68k_read8_wordram1_1M_b0:            @ 0x220000 - 0x23ffff, cell arranged
429     cell_map
430     ldr     r1, =(Pico+0x22200)
431     add     r0, r0, #0x0c0000
432     ldr     r1, [r1]
433     eor     r0, r0, #1
434     ldrb    r0, [r1, r0]
435     bx      lr
436
437
438 m_m68k_read8_wordram1_1M_b1:            @ 0x220000 - 0x23ffff, cell arranged
439     cell_map
440     ldr     r1, =(Pico+0x22200)
441     add     r0, r0, #0x0e0000
442     ldr     r1, [r1]
443     eor     r0, r0, #1
444     ldrb    r0, [r1, r0]
445     bx      lr
446
447
448 m_m68k_read8_system_io:
449     bic     r2, r0, #0xfe0000
450     bic     r2, r2, #0x3f
451     cmp     r2, #0x012000
452     bne     m_m68k_read8_misc
453
454     ldr     r1, =(Pico+0x22200)
455     and     r0, r0, #0x3f
456     ldr     r1, [r1]                  @ Pico.mcd (used everywhere)
457     cmp     r0, #0x0e
458     ldrlt   pc, [pc, r0, lsl #2]
459     b       m_m68k_read8_hi
460     .long   m_m68k_read8_r00
461     .long   m_m68k_read8_r01
462     .long   m_m68k_read8_r02
463     .long   m_m68k_read8_r03
464     .long   m_m68k_read8_r04
465     .long   m_read_null               @ unused bits
466     .long   m_m68k_read8_r06
467     .long   m_m68k_read8_r07
468     .long   m_m68k_read8_r08
469     .long   m_m68k_read8_r09
470     .long   m_read_null               @ reserved
471     .long   m_read_null
472     .long   m_m68k_read8_r0c
473     .long   m_m68k_read8_r0d
474 m_m68k_read8_r00:
475     add     r1, r1, #0x110000
476     ldr     r0, [r1, #0x30]
477     and     r0, r0, #0x04000000       @ we need irq2 mask state
478     mov     r0, r0, lsr #19
479     bx      lr
480 m_m68k_read8_r01:
481     add     r1, r1, #0x110000
482     add     r1, r1, #0x002200
483     ldrb    r0, [r1, #2]              @ Pico_mcd->m.busreq
484     bx      lr
485 m_m68k_read8_r02:
486     add     r1, r1, #0x110000
487     ldrb    r0, [r1, #2]
488     bx      lr
489 m_m68k_read8_r03:
490     add     r1, r1, #0x110000
491     ldrb    r0, [r1, #3]
492     and     r0, r0, #0xc7
493     bx      lr
494 m_m68k_read8_r04:
495     add     r1, r1, #0x110000
496     ldrb    r0, [r1, #4]
497     bx      lr
498 m_m68k_read8_r06:
499     ldrb    r0, [r1, #0x73]           @ IRQ vector
500     bx      lr
501 m_m68k_read8_r07:
502     ldrb    r0, [r1, #0x72]
503     bx      lr
504 m_m68k_read8_r08:
505     mov     r0, #0
506     bl      Read_CDC_Host             @ TODO: make it local
507     mov     r0, r0, lsr #8
508     bx      lr
509 m_m68k_read8_r09:
510     mov     r0, #0
511     b       Read_CDC_Host
512 m_m68k_read8_r0c:
513     add     r1, r1, #0x110000
514     add     r1, r1, #0x002200
515     ldr     r0, [r1, #0x14]           @ Pico_mcd->m.timer_stopwatch
516     mov     r0, r0, lsr #24
517     bx      lr
518 m_m68k_read8_r0d:
519     add     r1, r1, #0x110000
520     add     r1, r1, #0x002200
521     ldr     r0, [r1, #0x14]
522     mov     r0, r0, lsr #16
523     bx      lr
524 m_m68k_read8_hi:
525     cmp     r0, #0x30
526     movge   r0, #0
527     bxeq    lr
528     add     r1, r1, #0x110000
529     ldrb    r0, [r1, r0]
530     bx      lr
531
532
533 m_m68k_read8_misc:
534     bic     r2, r0, #0x00ff
535     bic     r2, r2, #0xbf00
536     cmp     r2, #0xa00000  @ Z80 RAM?
537     beq     z80Read8
538 @    ldreq   r2, =z80Read8
539 @    bxeq    r2
540     stmfd   sp!,{r0,lr}
541     bic     r0, r0, #1
542     mov     r1, #8
543     bl      OtherRead16                 @ non-MCD version should be ok too
544     ldmfd   sp!,{r1,lr}
545     tst     r1, #1
546     moveq   r0, r0, lsr #8
547     bx      lr
548
549
550 m_m68k_read8_vdp:
551     tst     r0, #0x70000
552     tsteq   r0, #0x000e0
553     bxne    lr              @ invalid read
554     stmfd   sp!,{r0,lr}
555     bic     r0, r0, #1
556     bl      PicoVideoRead               @ TODO: implement it in asm
557     ldmfd   sp!,{r1,lr}
558     tst     r1, #1
559     moveq   r0, r0, lsr #8
560     bx      lr
561
562
563 m_m68k_read8_ram:
564     ldr     r1, =Pico
565     bic     r0, r0, #0xff0000
566     eor     r0, r0, #1
567     ldrb    r0, [r1, r0]
568     bx      lr
569
570
571 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
572
573
574 m_m68k_read16_bios:
575     ldr     r1, =(Pico+0x22200)
576     bic     r0, r0, #0xfe0000
577     ldr     r1, [r1]
578     bic     r0, r0, #1
579     ldrh    r0, [r1, r0]
580     bx      lr
581
582
583 m_m68k_read16_prgbank:
584     ldr     r1, =(Pico+0x22200)
585     bic     r0, r0, #1
586     ldr     r1, [r1]
587     mov     r2, #0x110000
588     orr     r3, r2, #0x002200
589     ldr     r3, [r1, r3]
590     ldr     r2, [r1, r2]
591     tst     r3, #0x00020000             @ have bus?
592     moveq   r0, #0
593     bxeq    lr
594     and     r2, r2, #0xc0000000         @ r3 & 0xC0
595     add     r1, r1, r2, lsr #12
596     ldrh    r0, [r1, r0]
597     bx      lr
598
599
600 m_m68k_read16_wordram0_2M:              @ 0x200000 - 0x21ffff
601 m_m68k_read16_wordram1_2M:              @ 0x220000 - 0x23ffff
602     ldr     r1, =(Pico+0x22200)
603     sub     r0, r0, #0x160000           @ map to our offset, which is 0x0a0000
604     ldr     r1, [r1]
605     bic     r0, r0, #1
606     ldrh    r0, [r1, r0]
607     bx      lr
608
609
610 m_m68k_read16_wordram0_1M_b0:           @ 0x200000 - 0x21ffff
611     ldr     r1, =(Pico+0x22200)
612     sub     r0, r0, #0x140000           @ map to our offset, which is 0x0c0000
613     ldr     r1, [r1]
614     bic     r0, r0, #1
615     ldrh    r0, [r1, r0]
616     bx      lr
617
618
619 m_m68k_read16_wordram0_1M_b1:           @ 0x200000 - 0x21ffff
620     ldr     r1, =(Pico+0x22200)
621     sub     r0, r0, #0x120000           @ map to our offset, which is 0x0e0000
622     ldr     r1, [r1]
623     bic     r0, r0, #1
624     ldrh    r0, [r1, r0]
625     bx      lr
626
627
628 m_m68k_read16_wordram1_1M_b0:           @ 0x220000 - 0x23ffff, cell arranged
629     @ Warning: read32 relies on NOT using r3 and r12 here
630     cell_map
631     ldr     r1, =(Pico+0x22200)
632     add     r0, r0, #0x0c0000
633     ldr     r1, [r1]
634     bic     r0, r0, #1
635     ldrh    r0, [r1, r0]
636     bx      lr
637
638
639 m_m68k_read16_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
640     cell_map
641     ldr     r1, =(Pico+0x22200)
642     add     r0, r0, #0x0e0000
643     ldr     r1, [r1]
644     bic     r0, r0, #1
645     ldrh    r0, [r1, r0]
646     bx      lr
647
648
649 m_m68k_read16_system_io:
650     bic     r1, r0, #0xfe0000
651     bic     r1, r1, #0x3f
652     cmp     r1, #0x012000
653     bne     m_m68k_read16_misc
654
655 m_m68k_read16_m68k_regs:
656     ldr     r1, =(Pico+0x22200)
657     and     r0, r0, #0x3e
658     ldr     r1, [r1]                  @ Pico.mcd (used everywhere)
659     cmp     r0, #0x0e
660     ldrlt   pc, [pc, r0, lsl #1]
661     b       m_m68k_read16_hi
662     .long   m_m68k_read16_r00
663     .long   m_m68k_read16_r02
664     .long   m_m68k_read16_r04
665     .long   m_m68k_read16_r06
666     .long   m_m68k_read16_r08
667     .long   m_read_null               @ reserved
668     .long   m_m68k_read16_r0c
669 m_m68k_read16_r00:
670     add     r1, r1, #0x110000
671     ldr     r0, [r1, #0x30]
672     add     r1, r1, #0x002200
673     ldrb    r1, [r1, #2]              @ Pico_mcd->m.busreq
674     and     r0, r0, #0x04000000       @ we need irq2 mask state
675     orr     r0, r1, r0, lsr #11
676     bx      lr
677 m_m68k_read16_r02:
678     add     r1, r1, #0x110000
679     ldrb    r0, [r1, #2]
680     ldrb    r1, [r1, #3]
681     and     r1, r1, #0xc7
682     orr     r0, r1, r0, lsl #8
683     bx      lr
684 m_m68k_read16_r04:
685     add     r1, r1, #0x110000
686     ldrb    r0, [r1, #4]
687     mov     r0, r0, lsl #8
688     bx      lr
689 m_m68k_read16_r06:
690     ldrh    r0, [r1, #0x72]           @ IRQ vector
691     bx      lr
692 m_m68k_read16_r08:
693     mov     r0, #0
694     b       Read_CDC_Host
695 m_m68k_read16_r0c:
696     add     r1, r1, #0x110000
697     add     r1, r1, #0x002200
698     ldr     r0, [r1, #0x14]
699     mov     r0, r0, lsr #16
700     bx      lr
701 m_m68k_read16_hi:
702     cmp     r0, #0x30
703     addlt   r1, r1, #0x110000
704     ldrlth  r1, [r1, r0]
705     movge   r0, #0
706     bxge    lr
707     mov     r0, r1, lsr #8
708     and     r1, r1, #0xff
709     orr     r0, r0, r1, lsl #8
710     bx      lr
711
712
713 m_m68k_read16_misc:
714     bic     r0, r0, #1
715     mov     r1, #16
716     b       OtherRead16
717
718
719 m_m68k_read16_vdp:
720     tst     r0, #0x70000
721     tsteq   r0, #0x000e0
722     bxne    lr              @ invalid read
723     bic     r0, r0, #1
724     b       PicoVideoRead
725
726
727 m_m68k_read16_ram:
728     ldr     r1, =Pico
729     bic     r0, r0, #0xff0000
730     bic     r0, r0, #1
731     ldrh    r0, [r1, r0]
732     bx      lr
733
734
735 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
736
737
738 m_m68k_read32_bios:
739     ldr     r1, =(Pico+0x22200)
740     bic     r0, r0, #0xfe0000
741     ldr     r1, [r1]
742     bic     r0, r0, #1
743     m_read32_gen
744     bx      lr
745
746
747 m_m68k_read32_prgbank:
748     ldr     r1, =(Pico+0x22200)
749     bic     r0, r0, #1
750     ldr     r1, [r1]
751     mov     r2, #0x110000
752     orr     r3, r2, #0x002200
753     ldr     r3, [r1, r3]
754     ldr     r2, [r1, r2]
755     tst     r3, #0x00020000             @ have bus?
756     moveq   r0, #0
757     bxeq    lr
758     and     r2, r2, #0xc0000000         @ r3 & 0xC0
759     add     r1, r1, r2, lsr #12
760     m_read32_gen
761     bx      lr
762
763
764 m_m68k_read32_wordram0_2M:              @ 0x200000 - 0x21ffff
765 m_m68k_read32_wordram1_2M:              @ 0x220000 - 0x23ffff
766     ldr     r1, =(Pico+0x22200)
767     sub     r0, r0, #0x160000           @ map to our offset, which is 0x0a0000
768     ldr     r1, [r1]
769     bic     r0, r0, #1
770     m_read32_gen
771     bx      lr
772
773
774 m_m68k_read32_wordram0_1M_b0:           @ 0x200000 - 0x21ffff
775     ldr     r1, =(Pico+0x22200)
776     sub     r0, r0, #0x140000           @ map to our offset, which is 0x0c0000
777     ldr     r1, [r1]
778     bic     r0, r0, #1
779     m_read32_gen
780     bx      lr
781
782
783 m_m68k_read32_wordram0_1M_b1:           @ 0x200000 - 0x21ffff
784     ldr     r1, =(Pico+0x22200)
785     sub     r0, r0, #0x120000           @ map to our offset, which is 0x0e0000
786     ldr     r1, [r1]
787     bic     r0, r0, #1
788     m_read32_gen
789     bx      lr
790
791
792 m_m68k_read32_wordram1_1M_b0:           @ 0x220000 - 0x23ffff, cell arranged
793     tst     r0, #2
794     bne     m_m68k_read32_wordram1_1M_b0_unal
795     cell_map
796     ldr     r1, =(Pico+0x22200)
797     add     r0, r0, #0x0c0000
798     ldr     r1, [r1]
799     bic     r0, r0, #1
800     m_read32_gen
801     bx      lr
802 m_m68k_read32_wordram1_1M_b0_unal:
803     @ hopefully this doesn't happen too often
804     mov     r12,lr
805     mov     r3, r0
806     bl      m_m68k_read16_wordram1_1M_b0 @ must not trash r12 and r3
807     add     r1, r3, #2
808     mov     r3, r0
809     mov     r0, r1
810     bl      m_m68k_read16_wordram1_1M_b0
811     orr     r0, r0, r3, lsl #16
812     bx      r12
813
814
815 m_m68k_read32_wordram1_1M_b1:            @ 0x220000 - 0x23ffff, cell arranged
816     tst     r0, #2
817     bne     m_m68k_read32_wordram1_1M_b1_unal
818     cell_map
819     ldr     r1, =(Pico+0x22200)
820     add     r0, r0, #0x0e0000
821     ldr     r1, [r1]
822     bic     r0, r0, #1
823     m_read32_gen
824     bx      lr
825 m_m68k_read32_wordram1_1M_b1_unal:
826     mov     r12,lr
827     mov     r3, r0
828     bl      m_m68k_read16_wordram1_1M_b1 @ must not trash r12 and r3
829     add     r1, r3, #2
830     mov     r3, r0
831     mov     r0, r1
832     bl      m_m68k_read16_wordram1_1M_b1
833     orr     r0, r0, r3, lsl #16
834     bx      r12
835
836
837 @ it is not very practical to use long access on hw registers, so I assume it is not used too much.
838 m_m68k_read32_system_io:
839     bic     r1, r0, #0xfe0000
840     bic     r1, r1, #0x3f
841     cmp     r1, #0x012000
842     bne     m_m68k_read32_misc
843     and     r1, r0, #0x3e
844     cmp     r1, #0x0e
845     blt     m_m68k_read32_misc
846     cmp     r1, #0x30
847     movge   r0, #0
848     bxge    lr
849     @ I have seen the range 0x0e-0x2f accessed quite frequently with long i/o, so here is some code for that
850     mov     r0, r1
851     ldr     r1, =(Pico+0x22200)
852     mov     r2, #0xff
853     ldr     r1, [r1]
854     orr     r2, r2, r2, lsl #16
855     add     r1, r1, #0x110000
856     m_read32_gen
857     and     r1, r2, r0                @ data is big-endian read as little, have to byteswap
858     and     r0, r2, r0, lsr #8
859     orr     r0, r0, r1, lsl #8
860     bx      lr
861
862 m_m68k_read32_misc:
863     add     r1, r0, #2
864     stmfd   sp!,{r1,lr}
865     bl      m_m68k_read16_system_io
866     swp     r0, r0, [sp]
867     bl      m_m68k_read16_system_io
868     ldmfd   sp!,{r1,lr}
869     orr     r0, r0, r1, lsl #16
870     bx      lr
871
872
873 m_m68k_read32_vdp:
874     tst     r0, #0x70000
875     tsteq   r0, #0x000e0
876     bxne    lr              @ invalid read
877     bic     r0, r0, #1
878     add     r1, r0, #2
879     stmfd   sp!,{r1,lr}
880     bl      PicoVideoRead
881     swp     r0, r0, [sp]
882     bl      PicoVideoRead
883     ldmfd   sp!,{r1,lr}
884     orr     r0, r0, r1, lsl #16
885     bx      lr
886
887
888 m_m68k_read32_ram:
889     ldr     r1, =Pico
890     bic     r0, r0, #0xff0000
891     bic     r0, r0, #1
892     m_read32_gen
893     bx      lr
894
895 .pool
896
897 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
898
899
900 m_write_null:
901 m_m68k_write8_bios:
902     bx      lr
903
904
905 m_m68k_write8_prgbank:
906     ldr     r2, =(Pico+0x22200)
907     eor     r0, r0, #1
908     ldr     r2, [r2]
909     mov     r12,#0x110000
910     orr     r3, r12, #0x002200
911     ldr     r3, [r2, r3]
912     ldr     r12,[r2, r12]
913     tst     r3, #0x00020000             @ have bus?
914     bxeq    lr
915     and     r12,r12,#0xc0000000         @ r3 & 0xC0
916     add     r2, r2, r12, lsr #12
917     strb    r1, [r2, r0]
918     bx      lr
919
920
921 m_m68k_write8_wordram0_2M:              @ 0x200000 - 0x21ffff
922 m_m68k_write8_wordram1_2M:              @ 0x220000 - 0x23ffff
923     ldr     r2, =(Pico+0x22200)
924     sub     r0, r0, #0x160000           @ map to our offset, which is 0x0a0000
925     ldr     r2, [r2]
926     eor     r0, r0, #1
927     strb    r1, [r2, r0]
928     bx      lr
929
930
931 m_m68k_write8_wordram0_1M_b0:           @ 0x200000 - 0x21ffff
932     ldr     r2, =(Pico+0x22200)
933     sub     r0, r0, #0x140000           @ map to our offset, which is 0x0c0000
934     ldr     r2, [r2]
935     eor     r0, r0, #1
936     strb    r1, [r2, r0]
937     bx      lr
938
939
940 m_m68k_write8_wordram0_1M_b1:           @ 0x200000 - 0x21ffff
941     ldr     r2, =(Pico+0x22200)
942     sub     r0, r0, #0x120000           @ map to our offset, which is 0x0e0000
943     ldr     r2, [r2]
944     eor     r0, r0, #1
945     strb    r1, [r2, r0]
946     bx      lr
947
948
949 m_m68k_write8_wordram1_1M_b0:           @ 0x220000 - 0x23ffff, cell arranged
950     mov     r3, r1
951     cell_map
952     ldr     r2, =(Pico+0x22200)
953     add     r0, r0, #0x0c0000
954     ldr     r2, [r2]
955     eor     r0, r0, #1
956     strb    r3, [r2, r0]
957     bx      lr
958
959
960 m_m68k_write8_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
961     mov     r3, r1
962     cell_map
963     ldr     r2, =(Pico+0x22200)
964     add     r0, r0, #0x0e0000
965     ldr     r2, [r2]
966     eor     r0, r0, #1
967     strb    r3, [r2, r0]
968     bx      lr
969
970
971 m_m68k_write8_system_io:
972     bic     r2, r0, #0xfe0000
973     bic     r2, r2, #0x3f
974     cmp     r2, #0x012000
975     beq     m68k_reg_write8
976     mov     r2, #8
977     b       OtherWrite8
978
979
980 m_m68k_write8_vdp:
981     tst     r0, #0x70000
982     tsteq   r0, #0x000e0
983     bxne    lr                          @ invalid
984     and     r1, r1, #0xff
985     orr     r1, r1, r1, lsl #8          @ byte access gets mirrored
986     b       PicoVideoWrite
987
988
989 m_m68k_write8_ram:
990     ldr     r2, =Pico
991     bic     r0, r0, #0xff0000
992     eor     r0, r0, #1
993     strb    r1, [r2, r0]
994     bx      lr
995
996
997 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
998
999
1000 m_m68k_write16_bios:
1001     bx      lr
1002
1003
1004 m_m68k_write16_prgbank:
1005     ldr     r2, =(Pico+0x22200)
1006     bic     r0, r0, #1
1007     ldr     r2, [r2]
1008     mov     r12,#0x110000
1009     orr     r3, r12, #0x002200
1010     ldr     r3, [r2, r3]
1011     ldr     r12,[r2, r12]
1012     tst     r3, #0x00020000             @ have bus?
1013     bxeq    lr
1014     and     r12,r12,#0xc0000000         @ r3 & 0xC0
1015     add     r2, r2, r12, lsr #12
1016     strh    r1, [r2, r0]
1017     bx      lr
1018
1019
1020 m_m68k_write16_wordram0_2M:             @ 0x200000 - 0x21ffff
1021 m_m68k_write16_wordram1_2M:             @ 0x220000 - 0x23ffff
1022     ldr     r2, =(Pico+0x22200)
1023     sub     r0, r0, #0x160000           @ map to our offset, which is 0x0a0000
1024     ldr     r2, [r2]
1025     bic     r0, r0, #1
1026     strh    r1, [r2, r0]
1027     bx      lr
1028
1029
1030 m_m68k_write16_wordram0_1M_b0:          @ 0x200000 - 0x21ffff
1031     ldr     r2, =(Pico+0x22200)
1032     sub     r0, r0, #0x140000           @ map to our offset, which is 0x0c0000
1033     ldr     r2, [r2]
1034     bic     r0, r0, #1
1035     strh    r1, [r2, r0]
1036     bx      lr
1037
1038
1039 m_m68k_write16_wordram0_1M_b1:          @ 0x200000 - 0x21ffff
1040     ldr     r2, =(Pico+0x22200)
1041     sub     r0, r0, #0x120000           @ map to our offset, which is 0x0e0000
1042     ldr     r2, [r2]
1043     bic     r0, r0, #1
1044     strh    r1, [r2, r0]
1045     bx      lr
1046
1047
1048 m_m68k_write16_wordram1_1M_b0:           @ 0x220000 - 0x23ffff, cell arranged
1049     @ Warning: write32 relies on NOT using r12 and and keeping data in r3
1050     mov     r3, r1
1051     cell_map
1052     ldr     r1, =(Pico+0x22200)
1053     add     r0, r0, #0x0c0000
1054     ldr     r1, [r1]
1055     bic     r0, r0, #1
1056     strh    r3, [r1, r0]
1057     bx      lr
1058
1059
1060 m_m68k_write16_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
1061     mov     r3, r1
1062     cell_map
1063     ldr     r1, =(Pico+0x22200)
1064     add     r0, r0, #0x0e0000
1065     ldr     r1, [r1]
1066     bic     r0, r0, #1
1067     strh    r3, [r1, r0]
1068     bx      lr
1069
1070
1071 m_m68k_write16_system_io:
1072     bic     r0, r0, #1
1073     bic     r2, r0, #0xfe0000
1074     bic     r2, r2, #0x3f
1075     cmp     r2, #0x012000
1076     bne     OtherWrite16
1077
1078 m_m68k_write16_m68k_regs:
1079     and     r0, r0, #0x3e
1080     cmp     r0, #0x0e
1081     beq     m_m68k_write16_regs_spec
1082     and     r3, r1, #0xff
1083     add     r2, r0, #1
1084     stmfd   sp!,{r2,r3,lr}
1085     mov     r1, r1, lsr #8
1086     bl      m68k_reg_write8
1087     ldmfd   sp!,{r0,r1,lr}
1088     b       m68k_reg_write8
1089
1090 m_m68k_write16_regs_spec:               @ special case
1091     ldr     r2, =(Pico+0x22200)
1092     ldr     r3, =s68k_poll_adclk
1093     mov     r0, #0x110000
1094     ldr     r2, [r2]
1095     add     r0, r0, #0x00000e
1096     mov     r1, r1, lsr #8
1097     strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0x0e] = d >> 8;
1098     ldr     r2, [r3]
1099     mov     r1, #0
1100     and     r2, r2, #0xfe
1101     cmp     r2, #0x0e
1102     bxne    lr
1103     ldr     r0, =PicoCpuS68k
1104     str     r1, [r0, #0x58]             @ push s68k out of stopped state
1105     str     r1, [r3]
1106     bx      lr
1107
1108
1109 m_m68k_write16_vdp:
1110     tst     r0, #0x70000
1111     tsteq   r0, #0x000e0
1112     bxne    lr              @ invalid
1113     bic     r0, r0, #1
1114     b       PicoVideoWrite
1115
1116
1117 m_m68k_write16_ram:
1118     ldr     r2, =Pico
1119     bic     r0, r0, #0xff0000
1120     bic     r0, r0, #1
1121     strh    r1, [r2, r0]
1122     bx      lr
1123
1124
1125 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1126
1127
1128 m_m68k_write32_bios:
1129     bx      lr
1130
1131
1132 m_m68k_write32_prgbank:
1133     ldr     r2, =(Pico+0x22200)
1134     bic     r0, r0, #1
1135     ldr     r2, [r2]
1136     mov     r12,#0x110000
1137     orr     r3, r12, #0x002200
1138     ldr     r3, [r2, r3]
1139     ldr     r12,[r2, r12]
1140     tst     r3, #0x00020000             @ have bus?
1141     bxeq    lr
1142     and     r12,r12,#0xc0000000         @ r3 & 0xC0
1143     add     r2, r2, r12, lsr #12
1144     m_write32_gen
1145     bx      lr
1146
1147
1148 m_m68k_write32_wordram0_2M:             @ 0x200000 - 0x21ffff
1149 m_m68k_write32_wordram1_2M:             @ 0x220000 - 0x23ffff
1150     ldr     r2, =(Pico+0x22200)
1151     sub     r0, r0, #0x160000           @ map to our offset, which is 0x0a0000
1152     ldr     r2, [r2]
1153     bic     r0, r0, #1
1154     m_write32_gen
1155     bx      lr
1156
1157
1158 m_m68k_write32_wordram0_1M_b0:           @ 0x200000 - 0x21ffff
1159     ldr     r2, =(Pico+0x22200)
1160     sub     r0, r0, #0x140000           @ map to our offset, which is 0x0c0000
1161     ldr     r2, [r2]
1162     bic     r0, r0, #1
1163     m_write32_gen
1164     bx      lr
1165
1166
1167 m_m68k_write32_wordram0_1M_b1:           @ 0x200000 - 0x21ffff
1168     ldr     r2, =(Pico+0x22200)
1169     sub     r0, r0, #0x120000           @ map to our offset, which is 0x0e0000
1170     ldr     r2, [r2]
1171     bic     r0, r0, #1
1172     m_write32_gen
1173     bx      lr
1174
1175
1176 m_m68k_write32_wordram1_1M_b0:           @ 0x220000 - 0x23ffff, cell arranged
1177     tst     r0, #2
1178     bne     m_m68k_write32_wordram1_1M_b0_unal
1179     mov     r3, r1
1180     cell_map
1181     ldr     r2, =(Pico+0x22200)
1182     add     r0, r0, #0x0c0000
1183     ldr     r2, [r2]
1184     bic     r0, r0, #1
1185     mov     r1, r3
1186     m_write32_gen
1187     bx      lr
1188 m_m68k_write32_wordram1_1M_b0_unal:
1189     @ hopefully this doesn't happen too often
1190     add     r12,r0, #2
1191     mov     r1, r1, ror #16
1192     stmfd   sp!,{lr}
1193     bl      m_m68k_write16_wordram1_1M_b0 @ must not trash r12 and keep data in r3
1194     ldmfd   sp!,{lr}
1195     mov     r0, r12
1196     mov     r1, r3, lsr #16
1197     b       m_m68k_write16_wordram1_1M_b0
1198
1199
1200 m_m68k_write32_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
1201     tst     r0, #2
1202     bne     m_m68k_write32_wordram1_1M_b1_unal
1203     mov     r3, r1
1204     cell_map
1205     ldr     r2, =(Pico+0x22200)
1206     add     r0, r0, #0x0e0000
1207     ldr     r2, [r2]
1208     bic     r0, r0, #1
1209     mov     r1, r3
1210     m_write32_gen
1211     bx      lr
1212 m_m68k_write32_wordram1_1M_b1_unal:
1213     add     r12,r0, #2
1214     mov     r1, r1, ror #16
1215     stmfd   sp!,{lr}
1216     bl      m_m68k_write16_wordram1_1M_b1 @ same as above
1217     ldmfd   sp!,{lr}
1218     mov     r0, r12
1219     mov     r1, r3, lsr #16
1220     b       m_m68k_write16_wordram1_1M_b1
1221
1222
1223 @ it is not very practical to use long access on hw registers, so I assume it is not used too much.
1224 m_m68k_write32_system_io:
1225     bic     r2, r0, #0xfe0000
1226     bic     r2, r2, #0x3f
1227     cmp     r2, #0x012000
1228     bne     m_m68k_write32_misc
1229     and     r2, r0, #0x3e
1230     cmp     r2, #0x10
1231     blt     m_m68k_write32_regs
1232     cmp     r2, #0x20
1233     bxge    lr
1234     @ Handle the 0x10-0x1f range
1235     ldr     r0, =(Pico+0x22200)
1236     mov     r3, #0xff
1237     ldr     r0, [r0]
1238     orr     r3, r3, r3, lsl #16
1239     add     r0, r0, #0x110000
1240     and     r12,r3, r1, ror #16       @ data is big-endian to be written as little, have to byteswap
1241     and     r1, r3, r1, ror #24
1242     orr     r1, r1, r12,lsl #8        @ end of byteswap
1243     strh    r1, [r2, r0]!
1244     cmp     r2, #0x1e
1245     movne   r1, r1, lsr #16
1246     strneh  r1, [r2, #2]
1247     bx      lr
1248
1249 m_m68k_write32_regs:
1250     bic     r0, r0, #1
1251     stmfd   sp!,{r0,r1,lr}
1252     mov     r1, r1, lsr #24
1253     bl      m68k_reg_write8
1254     ldr     r0, [sp]
1255     ldr     r1, [sp, #4]
1256     add     r0, r0, #1
1257     mov     r1, r1, lsr #16
1258     bl      m68k_reg_write8
1259     ldr     r0, [sp]
1260     ldr     r1, [sp, #4]
1261     add     r0, r0, #2
1262     mov     r1, r1, lsr #8
1263     bl      m68k_reg_write8
1264     ldmfd   sp!,{r0,r1,lr}
1265     add     r0, r0, #3
1266     b       m68k_reg_write8
1267
1268 m_m68k_write32_misc:
1269     bic     r0, r0, #1
1270     stmfd   sp!,{r0,r1,lr}
1271     mov     r1, r1, lsr #16
1272     bl      OtherWrite16
1273     ldmfd   sp!,{r0,r1,lr}
1274     add     r0, r0, #2
1275     b       OtherWrite16
1276
1277
1278 m_m68k_write32_vdp:
1279     tst     r0, #0x70000
1280     tsteq   r0, #0x000e0
1281     bxne    lr              @ invalid
1282     stmfd   sp!,{r0,r1,lr}
1283     mov     r1, r1, lsr #16
1284     bl      PicoVideoWrite
1285     ldmfd   sp!,{r0,r1,lr}
1286     add     r0, r0, #2
1287     b       PicoVideoWrite
1288
1289
1290 m_m68k_write32_ram:
1291     ldr     r2, =Pico
1292     bic     r0, r0, #0xff0000
1293     bic     r0, r0, #1
1294     m_write32_gen
1295     bx      lr
1296
1297 .pool
1298
1299
1300 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1301
1302 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1303
1304
1305 .macro m_s68k_read8_ram map_addr
1306     ldr     r1, =(Pico+0x22200)
1307     eor     r0, r0, #1
1308     ldr     r1, [r1]
1309 .if \map_addr
1310     add     r0, r0, #\map_addr          @ map to our address
1311 .endif
1312     ldrb    r0, [r1, r0]
1313     bx      lr
1314 .endm
1315
1316 .macro m_s68k_read8_wordram_2M_decode map_addr
1317     ldr     r2, =(Pico+0x22200)
1318     eor     r0, r0, #2
1319     ldr     r2, [r2]
1320     movs    r0, r0, lsr #1              @ +4-6 <<16
1321     add     r2, r2, #\map_addr          @ map to our address
1322     ldrb    r0, [r2, r0]
1323     movcc   r0, r0, lsr #4
1324     andcs   r0, r0, #0xf
1325     bx      lr
1326 .endm
1327
1328
1329 m_s68k_read8_prg:                       @ 0x000000 - 0x07ffff
1330 m_s68k_read8_wordram_2M:                @ 0x080000 - 0x0bffff
1331 m_s68k_read8_wordram_1M_b1:             @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
1332     m_s68k_read8_ram 0x020000
1333
1334
1335 m_s68k_read8_wordram_2M_decode_b0:      @ 0x080000 - 0x0bffff
1336     m_s68k_read8_wordram_2M_decode 0x080000 @ + ^ / 2
1337
1338
1339 m_s68k_read8_wordram_2M_decode_b1:      @ 0x080000 - 0x0bffff
1340     m_s68k_read8_wordram_2M_decode 0x0a0000 @ + ^ / 2
1341
1342
1343 m_s68k_read8_wordram_1M_b0:             @ 0x0c0000 - 0x0dffff (same as our offset :)
1344     m_s68k_read8_ram 0
1345
1346
1347 m_s68k_read8_backup:                    @ 0xfe0000 - 0xfe3fff (repeated?)
1348     @ must not trash r3 and r12
1349     ldr     r1, =(Pico+0x22200)
1350     mov     r0, r0, lsr #1
1351     ldr     r1, [r1]
1352     bic     r0, r0, #0xff0000
1353     bic     r0, r0, #0x00e000
1354     add     r1, r1, #0x110000
1355     add     r1, r1, #0x000200
1356     ldrb    r0, [r1, r0]
1357     bx      lr
1358
1359
1360 m_s68k_read8_pcm:
1361     @ must not trash r3 and r12
1362     ldr     r1, =(Pico+0x22200)
1363     bic     r0, r0, #0xff0000
1364 @    bic     r0, r0, #0x008000
1365     ldr     r1, [r1]
1366     mov     r2, #0x110000
1367     orr     r2, r2, #0x002200
1368     cmp     r0, #0x2000
1369     bge     m_s68k_read8_pcm_ram
1370     cmp     r0, #0x20
1371     movlt   r0, #0
1372     bxlt    lr
1373     orr     r2, r2, #(0x48+8)           @ pcm.ch + addr_offset
1374     add     r1, r1, r2
1375     and     r2, r0, #0x1c
1376     ldr     r1, [r1, r2, lsl #2]
1377     tst     r0, #2
1378     moveq   r0, r1, lsr #PCM_STEP_SHIFT
1379     movne   r0, r1, lsr #(PCM_STEP_SHIFT+8)
1380     and     r0, r0, #0xff
1381     bx      lr
1382
1383 m_s68k_read8_pcm_ram:
1384     orr     r2, r2, #0x40
1385     ldr     r2, [r1, r2]
1386     add     r1, r1, #0x100000           @ pcm_ram
1387     and     r2, r2, #0x0f000000         @ bank
1388     add     r1, r1, r2, lsr #12
1389     bic     r0, r0, #0x00e000
1390     mov     r0, r0, lsr #1
1391     ldrb    r0, [r1, r0]
1392     bx      lr
1393
1394
1395 m_s68k_read8_regs:
1396     bic     r0, r0, #0xff0000
1397     bic     r0, r0, #0x008000
1398     tst     r0, #0x7e00
1399     movne   r0, #0
1400     bxne    lr
1401     sub     r2, r0, #0x58
1402     cmp     r2, #0x10
1403     ldrlo   r2, =gfx_cd_read
1404     ldrhs   r2, =s68k_reg_read16
1405     stmfd   sp!,{r0,lr}
1406     bic     r0, r0, #1
1407     mov     lr, pc
1408     bx      r2
1409     ldmfd   sp!,{r1,lr}
1410     tst     r1, #1
1411     moveq   r0, r0, lsr #8
1412     and     r0, r0, #0xff
1413     bx      lr
1414
1415
1416 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1417
1418
1419 .macro m_s68k_read16_ram map_addr
1420     ldr     r1, =(Pico+0x22200)
1421     bic     r0, r0, #1
1422     ldr     r1, [r1]
1423 .if \map_addr
1424     add     r0, r0, #\map_addr          @ map to our address
1425 .endif
1426     ldrh    r0, [r1, r0]
1427     bx      lr
1428 .endm
1429
1430 .macro m_s68k_read16_wordram_2M_decode map_addr
1431     ldr     r2, =(Pico+0x22200)
1432     eor     r0, r0, #2
1433     ldr     r2, [r2]
1434     mov     r0, r0, lsr #1              @ +4-6 <<16
1435     add     r2, r2, #\map_addr          @ map to our address
1436     ldrb    r0, [r2, r0]
1437     orr     r0, r0, r0, lsl #4
1438     bic     r0, r0, #0xf0
1439     bx      lr
1440 .endm
1441
1442
1443 m_s68k_read16_prg:                      @ 0x000000 - 0x07ffff
1444 m_s68k_read16_wordram_2M:               @ 0x080000 - 0x0bffff
1445 m_s68k_read16_wordram_1M_b1:            @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
1446     m_s68k_read16_ram 0x020000
1447
1448
1449 m_s68k_read16_wordram_2M_decode_b0:     @ 0x080000 - 0x0bffff
1450     m_s68k_read16_wordram_2M_decode 0x080000
1451
1452
1453 m_s68k_read16_wordram_2M_decode_b1:     @ 0x080000 - 0x0bffff
1454     m_s68k_read16_wordram_2M_decode 0x0a0000
1455
1456
1457 m_s68k_read16_wordram_1M_b0:            @ 0x0c0000 - 0x0dffff (same as our offset :)
1458     m_s68k_read16_ram 0
1459
1460
1461 @ m_s68k_read16_backup:                 @ 0xfe0000 - 0xfe3fff (repeated?)
1462 @ bram is not meant to be accessed by words, does any game do this?
1463 .equiv m_s68k_read16_backup, m_s68k_read8_backup
1464
1465
1466 @ m_s68k_read16_pcm:
1467 @ pcm is on 8-bit bus, would this be same as byte access?
1468 .equiv m_s68k_read16_pcm, m_s68k_read8_pcm
1469
1470
1471 m_s68k_read16_regs:
1472     bic     r0, r0, #0xff0000
1473     bic     r0, r0, #0x008000
1474     bic     r0, r0, #0x000001
1475     tst     r0, #0x7e00
1476     movne   r0, #0
1477     bxne    lr
1478     sub     r2, r0, #0x58
1479     cmp     r2, #0x10
1480     blo     gfx_cd_read
1481     cmp     r0, #8
1482     bne     s68k_reg_read16
1483     mov     r0, #1
1484     b       Read_CDC_Host
1485
1486
1487 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1488
1489
1490 .macro m_s68k_read32_ram map_addr
1491     ldr     r1, =(Pico+0x22200)
1492     bic     r0, r0, #1
1493     ldr     r1, [r1]
1494 .if \map_addr
1495     add     r0, r0, #\map_addr          @ map to our address
1496 .endif
1497     m_read32_gen
1498     bx      lr
1499 .endm
1500
1501 .macro m_s68k_read32_wordram_2M_decode map_addr
1502     ldr     r2, =(Pico+0x22200)
1503     eor     r0, r0, #2
1504     ldr     r2, [r2]
1505     mov     r0, r0, lsr #1              @ +4-6 <<16
1506     add     r2, r2, #\map_addr          @ map to our address
1507     ldrb    r1, [r2, r0]!
1508     tst     r0, #1
1509     ldrneb  r0, [r2, #-1]
1510     ldreqb  r0, [r2, #2]
1511     orr     r1, r1, r1, lsl #4
1512     bic     r1, r1, #0xf0
1513     orr     r0, r0, r0, lsl #4
1514     bic     r0, r0, #0xf0
1515     orr     r0, r0, r1, lsl #16
1516     bx      lr
1517 .endm
1518
1519
1520 m_s68k_read32_prg:                      @ 0x000000 - 0x07ffff
1521 m_s68k_read32_wordram_2M:               @ 0x080000 - 0x0bffff
1522 m_s68k_read32_wordram_1M_b1:            @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
1523     m_s68k_read32_ram 0x020000
1524
1525
1526 m_s68k_read32_wordram_2M_decode_b0:     @ 0x080000 - 0x0bffff
1527     m_s68k_read32_wordram_2M_decode 0x080000
1528
1529
1530 m_s68k_read32_wordram_2M_decode_b1:     @ 0x080000 - 0x0bffff
1531     m_s68k_read32_wordram_2M_decode 0x0a0000
1532
1533
1534 m_s68k_read32_wordram_1M_b0:            @ 0x0c0000 - 0x0dffff (same as our offset :)
1535     m_s68k_read32_ram 0
1536
1537
1538 m_s68k_read32_backup:                   @ 0xfe0000 - 0xfe3fff (repeated?)
1539     @ bram is not meant to be accessed by words, does any game do this?
1540     mov     r12,lr
1541     mov     r3, r0
1542     bl      m_s68k_read8_backup         @ must preserve r3 and r12
1543     mov     r1, r0
1544     add     r0, r3, #2
1545     mov     r3, r1
1546     bl      m_s68k_read8_backup
1547     orr     r0, r0, r3, lsl #16
1548     bx      r12
1549
1550
1551 m_s68k_read32_pcm:
1552     mov     r12,lr
1553     mov     r3, r0
1554     bl      m_s68k_read8_pcm            @ must preserve r3 and r12
1555     mov     r1, r0
1556     add     r0, r3, #2
1557     mov     r3, r1
1558     bl      m_s68k_read8_pcm
1559     orr     r0, r0, r3, lsl #16
1560     bx      r12
1561
1562
1563 m_s68k_read32_regs:
1564     bic     r0, r0, #0xff0000
1565     bic     r0, r0, #0x008000
1566     bic     r0, r0, #0x000001
1567     tst     r0, #0x7e00
1568     movne   r0, #0
1569     bxne    lr
1570     sub     r2, r0, #0x58
1571     cmp     r2, #0x10
1572     add     r1, r0, #2
1573     blo     m_s68k_read32_regs_gfx
1574     stmfd   sp!,{r1,lr}
1575     bl      s68k_reg_read16
1576     swp     r0, r0, [sp]
1577     bl      s68k_reg_read16
1578     ldmfd   sp!,{r1,lr}
1579     orr     r0, r0, r1, lsl #16
1580     bx      lr
1581
1582
1583 m_s68k_read32_regs_gfx:
1584     stmfd   sp!,{r1,lr}
1585     bl      gfx_cd_read
1586     swp     r0, r0, [sp]
1587     bl      gfx_cd_read
1588     ldmfd   sp!,{r1,lr}
1589     orr     r0, r0, r1, lsl #16
1590     bx      lr
1591
1592 .pool
1593
1594 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1595
1596
1597 .macro m_s68k_write8_ram map_addr
1598     ldr     r2, =(Pico+0x22200)
1599     eor     r0, r0, #1
1600     ldr     r2, [r2]
1601 .if \map_addr
1602     add     r0, r0, #\map_addr          @ map to our address
1603 .endif
1604     strb    r1, [r2, r0]
1605     bx      lr
1606 .endm
1607
1608 .macro m_s68k_write8_2M_decode map_addr
1609     ldr     r2, =(Pico+0x22200)
1610     eor     r0, r0, #2
1611     ldr     r2, [r2]
1612     movs    r0, r0, lsr #1              @ +4-6 <<16
1613     add     r2, r2, #\map_addr          @ map to our address
1614 .endm
1615
1616 .macro m_s68k_write8_2M_decode_m0 map_addr @ mode off
1617     m_s68k_write8_2M_decode \map_addr
1618     ldrb    r0, [r2, r0]!
1619     and     r1, r1, #0x0f
1620     movcc   r1, r1, lsl #4
1621     andcc   r3, r0, #0x0f
1622     andcs   r3, r0, #0xf0
1623     orr     r3, r3, r1
1624     cmp     r0, r3                      @ avoid writing if result is same
1625     strneb  r3, [r2]
1626     bx      lr
1627 .endm
1628
1629 .macro m_s68k_write8_2M_decode_m1 map_addr @ mode underwrite
1630     ands    r1, r1, #0x0f
1631     bxeq    lr
1632     m_s68k_write8_2M_decode \map_addr
1633     ldrb    r0, [r2, r0]!
1634     movcc   r1, r1, lsl #4
1635     andcc   r3, r0, #0x0f
1636     andcs   r3, r0, #0xf0
1637     tst     r3, r3
1638     bxeq    lr
1639     orr     r3, r3, r1
1640     cmp     r0, r3
1641     strneb  r3, [r2]
1642     bx      lr
1643 .endm
1644
1645 .macro m_s68k_write8_2M_decode_m2 map_addr @ mode overwrite
1646     ands    r1, r1, #0x0f
1647     bxeq    lr
1648     m_s68k_write8_2M_decode_m0 \map_addr   @ same as in off mode
1649 .endm
1650
1651
1652
1653 m_s68k_write8_prg:                      @ 0x000000 - 0x07ffff
1654 m_s68k_write8_wordram_2M:               @ 0x080000 - 0x0bffff
1655 m_s68k_write8_wordram_1M_b1:            @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
1656     m_s68k_write8_ram 0x020000
1657
1658
1659 m_s68k_write8_2M_decode_b0_m0:          @ 0x080000 - 0x0bffff
1660     m_s68k_write8_2M_decode_m0 0x080000
1661
1662 m_s68k_write8_2M_decode_b0_m1:
1663     m_s68k_write8_2M_decode_m1 0x080000
1664
1665 m_s68k_write8_2M_decode_b0_m2:
1666     m_s68k_write8_2M_decode_m2 0x080000
1667
1668 m_s68k_write8_2M_decode_b1_m0:
1669     m_s68k_write8_2M_decode_m0 0x0a0000
1670
1671 m_s68k_write8_2M_decode_b1_m1:
1672     m_s68k_write8_2M_decode_m1 0x0a0000
1673
1674 m_s68k_write8_2M_decode_b1_m2:
1675     m_s68k_write8_2M_decode_m2 0x0a0000
1676
1677
1678 m_s68k_write8_wordram_1M_b0:            @ 0x0c0000 - 0x0dffff (same as our offset :)
1679     m_s68k_write8_ram 0
1680
1681
1682 m_s68k_write8_backup:                   @ 0xfe0000 - 0xfe3fff (repeated?)
1683     @ must not trash r3 and r12
1684     ldr     r2, =(Pico+0x22200)
1685     mov     r0, r0, lsr #1
1686     ldr     r2, [r2]
1687     bic     r0, r0, #0xff0000
1688     bic     r0, r0, #0x00e000
1689     add     r2, r2, #0x110000
1690     add     r2, r2, #0x000200
1691     strb    r1, [r2, r0]
1692     ldr     r1, =SRam
1693     mov     r0, #1
1694     strb    r0, [r1, #0x0e]             @ SRam.changed = 1
1695     bx      lr
1696
1697
1698 m_s68k_write8_pcm:
1699     bic     r0, r0, #0xff0000
1700     cmp     r0, #0x12
1701     movlt   r0, r0, lsr #1
1702     blt     pcm_write
1703
1704     cmp     r0, #0x2000
1705     bxlt    lr
1706
1707 m_s68k_write8_pcm_ram:
1708     ldr     r3, =(Pico+0x22200)
1709     bic     r0, r0, #0x00e000
1710     ldr     r3, [r3]
1711     mov     r0, r0, lsr #1
1712     add     r2, r3, #0x110000
1713     add     r2, r2, #0x002200
1714     add     r2, r2, #0x000040
1715     ldr     r2, [r2]
1716     add     r3, r3, #0x100000           @ pcm_ram
1717     and     r2, r2, #0x0f000000         @ bank
1718     add     r3, r3, r2, lsr #12
1719     strb    r1, [r3, r0]
1720     bx      lr
1721
1722
1723 m_s68k_write8_regs:
1724     bic     r0, r0, #0xff0000
1725     bic     r0, r0, #0x008000
1726     tst     r0, #0x7e00
1727     movne   r0, #0
1728     bxne    lr
1729     sub     r2, r0, #0x58
1730     cmp     r2, #0x10
1731     bhs     s68k_reg_write8
1732     bic     r0, r0, #1
1733     orr     r1, r1, r1, lsl #8
1734     b       gfx_cd_write16
1735
1736
1737 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1738
1739
1740 .macro m_s68k_write16_ram map_addr
1741     ldr     r2, =(Pico+0x22200)
1742     bic     r0, r0, #1
1743     ldr     r2, [r2]
1744 .if \map_addr
1745     add     r0, r0, #\map_addr          @ map to our address
1746 .endif
1747     strh    r1, [r2, r0]
1748     bx      lr
1749 .endm
1750
1751 .macro m_s68k_write16_2M_decode map_addr
1752     ldr     r2, =(Pico+0x22200)
1753     eor     r0, r0, #2
1754     ldr     r2, [r2]
1755     mov     r0, r0, lsr #1              @ +4-6 <<16
1756     add     r2, r2, #\map_addr          @ map to our address
1757 .endm
1758
1759 .macro m_s68k_write16_2M_decode_m0 map_addr @ mode off
1760     m_s68k_write16_2M_decode \map_addr
1761     bic     r1, r1, #0xf0
1762     orr     r1, r1, r1, lsr #4
1763     strb    r1, [r2, r0]
1764     bx      lr
1765 .endm
1766
1767 .macro m_s68k_write16_2M_decode_m1 map_addr @ mode underwrite
1768     bics    r1, r1, #0xf000
1769     bicnes  r1, r1, #0x00f0
1770     bxeq    lr
1771     orr     r1, r1, r1, lsr #4
1772     m_s68k_write16_2M_decode \map_addr
1773     ldrb    r0, [r2, r0]!
1774     and     r3, r1, #0x0f
1775     and     r1, r1, #0xf0
1776     tst     r0, #0x0f
1777     orreq   r0, r0, r3
1778     tst     r0, #0xf0
1779     orreq   r0, r0, r1
1780     strb    r0, [r2]
1781     bx      lr
1782 .endm
1783
1784 .macro m_s68k_write16_2M_decode_m2 map_addr @ mode overwrite
1785     bics    r1, r1, #0xf000
1786     bicnes  r1, r1, #0x00f0
1787     bxeq    lr
1788     orr     r1, r1, r1, lsr #4
1789     m_s68k_write16_2M_decode \map_addr
1790     ldrb    r0, [r2, r0]!
1791     ands    r3, r1, #0x0f
1792     andne   r0, r0, #0xf0
1793     orrne   r0, r0, r3
1794     ands    r1, r1, #0xf0
1795     andne   r0, r0, #0x0f
1796     orrne   r0, r0, r1
1797     strb    r0, [r2]
1798     bx      lr
1799 .endm
1800
1801
1802
1803 m_s68k_write16_prg:                     @ 0x000000 - 0x07ffff
1804 m_s68k_write16_wordram_2M:              @ 0x080000 - 0x0bffff
1805 m_s68k_write16_wordram_1M_b1:           @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
1806     m_s68k_write16_ram 0x020000
1807
1808
1809 m_s68k_write16_2M_decode_b0_m0:         @ 0x080000 - 0x0bffff
1810     m_s68k_write16_2M_decode_m0 0x080000
1811
1812 m_s68k_write16_2M_decode_b0_m1:
1813     m_s68k_write16_2M_decode_m1 0x080000
1814
1815 m_s68k_write16_2M_decode_b0_m2:
1816     m_s68k_write16_2M_decode_m2 0x080000
1817
1818 m_s68k_write16_2M_decode_b1_m0:
1819     m_s68k_write16_2M_decode_m0 0x0a0000
1820
1821 m_s68k_write16_2M_decode_b1_m1:
1822     m_s68k_write16_2M_decode_m1 0x0a0000
1823
1824 m_s68k_write16_2M_decode_b1_m2:
1825     m_s68k_write16_2M_decode_m2 0x0a0000
1826
1827
1828 m_s68k_write16_wordram_1M_b0:           @ 0x0c0000 - 0x0dffff (same as our offset :)
1829     m_s68k_write16_ram 0
1830
1831
1832 @ m_s68k_write16_backup:
1833 .equiv m_s68k_write16_backup, m_s68k_write8_backup
1834
1835
1836 @ m_s68k_write16_pcm:
1837 .equiv m_s68k_write16_pcm, m_s68k_write8_pcm
1838
1839
1840 m_s68k_write16_regs:
1841     bic     r0, r0, #0xff0000
1842     bic     r0, r0, #0x008000
1843     bic     r0, r0, #1
1844     tst     r0, #0x7e00
1845     movne   r0, #0
1846     bxne    lr
1847     cmp     r0, #0x0e
1848     beq     m_s68k_write16_regs_spec
1849     sub     r2, r0, #0x58
1850     cmp     r2, #0x10
1851     blo     gfx_cd_write16
1852     and     r3, r1, #0xff
1853     add     r2, r0, #1
1854     stmfd   sp!,{r2,r3,lr}
1855     mov     r1, r1, lsr #8
1856     bl      s68k_reg_write8
1857     ldmfd   sp!,{r0,r1,lr}
1858     b       s68k_reg_write8
1859
1860 m_s68k_write16_regs_spec:               @ special case
1861     ldr     r2, =(Pico+0x22200)
1862     mov     r0, #0x110000
1863     ldr     r2, [r2]
1864     add     r0, r0, #0x00000f
1865     strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0xf] = d;
1866     bx      lr
1867
1868
1869 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1870
1871
1872 .macro m_s68k_write32_ram map_addr
1873     ldr     r2, =(Pico+0x22200)
1874     bic     r0, r0, #1
1875     ldr     r2, [r2]
1876 .if \map_addr
1877     add     r0, r0, #\map_addr          @ map to our address
1878 .endif
1879     m_write32_gen
1880     bx      lr
1881 .endm
1882
1883 .macro m_s68k_write32_2M_decode map_addr
1884     ldr     r2, =(Pico+0x22200)
1885     eor     r0, r0, #2
1886     ldr     r2, [r2]
1887     mov     r0, r0, lsr #1              @ +4-6 <<16
1888     add     r2, r2, #\map_addr          @ map to our address
1889 .endm
1890
1891 .macro m_s68k_write32_2M_decode_m0 map_addr @ mode off
1892     m_s68k_write32_2M_decode \map_addr
1893     bic     r1, r1, #0x000000f0
1894     bic     r1, r1, #0x00f00000
1895     orr     r1, r1, r1, lsr #4
1896     mov     r3, r1, lsr #16
1897     strb    r3, [r2, r0]!
1898     tst     r0, #1
1899     strneb  r1, [r2, #-1]
1900     streqb  r1, [r2, #3]
1901     bx      lr
1902 .endm
1903
1904 .macro m_s68k_write32_2M_decode_m1 map_addr @ mode underwrite
1905     bics    r1, r1, #0x000000f0
1906     bicnes  r1, r1, #0x0000f000
1907     bicnes  r1, r1, #0x00f00000
1908     bicnes  r1, r1, #0xf0000000
1909     bxeq    lr
1910     orr     r1, r1, r1, lsr #4
1911     m_s68k_write32_2M_decode \map_addr
1912     ldrb    r3, [r2, r0]!
1913     tst     r0, #1
1914     ldrneb  r0, [r2, #-1]
1915     ldreqb  r0, [r2, #3]
1916     and     r12,r1, #0x0000000f
1917     orr     r0, r0, r3, lsl #16
1918     orrne   r0, r0, #0x80000000          @ remember addr lsb bit
1919     tst     r0,     #0x0000000f
1920     orreq   r0, r0, r12
1921     tst     r0,     #0x000000f0
1922     andeq   r12,r1, #0x000000f0
1923     orreq   r0, r0, r12
1924     tst     r0,     #0x000f0000
1925     andeq   r12,r1, #0x000f0000
1926     orreq   r0, r0, r12
1927     tst     r0,     #0x00f00000
1928     andeq   r12,r1, #0x00f00000
1929     orreq   r0, r0, r12
1930     tst     r0, #0x80000000
1931     strneb  r0, [r2, #-1]
1932     streqb  r0, [r2, #3]
1933     mov     r0, r0, lsr #16
1934     strb    r0, [r2]
1935     bx      lr
1936 .endm
1937
1938 .macro m_s68k_write32_2M_decode_m2 map_addr @ mode overwrite
1939     bics    r1, r1, #0x000000f0
1940     bicnes  r1, r1, #0x0000f000
1941     bicnes  r1, r1, #0x00f00000
1942     bicnes  r1, r1, #0xf0000000
1943     bxeq    lr
1944     orr     r1, r1, r1, lsr #4
1945     m_s68k_write32_2M_decode \map_addr
1946     ldrb    r3, [r2, r0]!
1947     tst     r0, #1
1948     ldrneb  r0, [r2, #-1]
1949     ldreqb  r0, [r2, #3]
1950     orrne   r1, r1, #0x80000000          @ remember addr lsb bit
1951     orr     r0, r0, r3, lsl #16
1952     tst     r1,     #0x0000000f
1953     andeq   r12,r0, #0x0000000f
1954     orreq   r1, r1, r12
1955     tst     r1,     #0x000000f0
1956     andeq   r12,r0, #0x000000f0
1957     orreq   r1, r1, r12
1958     tst     r1,     #0x000f0000
1959     andeq   r12,r0, #0x000f0000
1960     orreq   r1, r1, r12
1961     tst     r1,     #0x00f00000
1962     andeq   r12,r0, #0x00f00000
1963     orreq   r1, r1, r12
1964     cmp     r0, r1
1965     bxeq    lr
1966     tst     r1, #0x80000000
1967     strneb  r1, [r2, #-1]
1968     streqb  r1, [r2, #3]
1969     mov     r1, r1, lsr #16
1970     strb    r1, [r2]
1971     bx      lr
1972 .endm
1973
1974
1975
1976 m_s68k_write32_prg:                     @ 0x000000 - 0x07ffff
1977 m_s68k_write32_wordram_2M:              @ 0x080000 - 0x0bffff
1978 m_s68k_write32_wordram_1M_b1:           @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
1979     m_s68k_write32_ram 0x020000
1980
1981
1982 m_s68k_write32_2M_decode_b0_m0:  @ 0x080000 - 0x0bffff
1983     m_s68k_write32_2M_decode_m0 0x080000
1984
1985 m_s68k_write32_2M_decode_b0_m1:
1986     m_s68k_write32_2M_decode_m1 0x080000
1987
1988 m_s68k_write32_2M_decode_b0_m2:
1989     m_s68k_write32_2M_decode_m2 0x080000
1990
1991 m_s68k_write32_2M_decode_b1_m0:
1992     m_s68k_write32_2M_decode_m0 0x0a0000
1993
1994 m_s68k_write32_2M_decode_b1_m1:
1995     m_s68k_write32_2M_decode_m1 0x0a0000
1996
1997 m_s68k_write32_2M_decode_b1_m2:
1998     m_s68k_write32_2M_decode_m2 0x0a0000
1999
2000
2001 m_s68k_write32_wordram_1M_b0:           @ 0x0c0000 - 0x0dffff (same as our offset :)
2002     m_s68k_write32_ram 0
2003
2004
2005 m_s68k_write32_backup:
2006     add     r12,r0, #2
2007     mov     r3, r1
2008     mov     r1, r1, lsr #16
2009     stmfd   sp!,{lr}
2010     bl      m_s68k_write8_backup        @ must preserve r3 and r12
2011     ldmfd   sp!,{lr}
2012     mov     r0, r12
2013     mov     r1, r3
2014     b       m_s68k_write8_backup
2015
2016
2017 m_s68k_write32_pcm:
2018     bic     r0, r0, #0xff0000
2019     cmp     r0, #0x12
2020     blt     m_s68k_write32_pcm_reg
2021
2022     cmp     r0, #0x2000
2023     bxlt    lr
2024
2025 m_s68k_write32_pcm_ram:
2026     ldr     r3, =(Pico+0x22200)
2027     bic     r0, r0, #0x00e000
2028     ldr     r3, [r3]
2029     mov     r0, r0, lsr #1
2030     add     r2, r3, #0x110000
2031     add     r2, r2, #0x002200
2032     add     r2, r2, #0x000040
2033     ldr     r2, [r2]
2034     add     r3, r3, #0x100000           @ pcm_ram
2035     and     r2, r2, #0x0f000000         @ bank
2036     add     r3, r3, r2, lsr #12
2037     mov     r1, r1, ror #16
2038     strb    r1, [r3, r0]!
2039     mov     r1, r1, ror #16
2040     strb    r1, [r3]
2041     bx      lr
2042
2043 m_s68k_write32_pcm_reg:
2044     mov     r0, r0, lsr #1
2045     add     r2, r0, #1
2046     mov     r3, r1
2047     stmfd   sp!,{r2,r3,lr}
2048     mov     r1, r1, lsr #16
2049     bl      pcm_write
2050     ldmfd   sp!,{r0,r1,lr}
2051     b       pcm_write
2052
2053
2054 m_s68k_write32_regs:
2055     bic     r0, r0, #0xff0000
2056     bic     r0, r0, #0x008000
2057     bic     r0, r0, #1
2058     tst     r0, #0x7e00
2059     movne   r0, #0
2060     bxne    lr
2061     sub     r2, r0, #0x58
2062     cmp     r2, #0x10
2063     blo     m_s68k_write32_regs_gfx
2064
2065     stmfd   sp!,{r0,r1,lr}
2066     mov     r1, r1, lsr #24
2067     bl      s68k_reg_write8
2068     ldr     r0, [sp]
2069     ldr     r1, [sp, #4]
2070     add     r0, r0, #1
2071     mov     r1, r1, lsr #16
2072     bl      s68k_reg_write8
2073     ldr     r0, [sp]
2074     ldr     r1, [sp, #4]
2075     add     r0, r0, #2
2076     mov     r1, r1, lsr #8
2077     bl      s68k_reg_write8
2078     ldmfd   sp!,{r0,r1,lr}
2079     add     r0, r0, #3
2080     b       s68k_reg_write8
2081
2082 m_s68k_write32_regs_gfx:
2083     mov     r3, r1
2084     add     r2, r0, #2
2085     stmfd   sp!,{r2,r3,lr}
2086     mov     r1, r1, lsr #16
2087     bl      gfx_cd_write16
2088     ldmfd   sp!,{r0,r1,lr}
2089     b       gfx_cd_write16
2090