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