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