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