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