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