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