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