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