asm code updated, Bass Masters fix
[picodrive.git] / Pico / Memory_amips.s
1 # vim:filetype=mips
2
3 # memory handlers with banking support for SSF II - The New Challengers
4 # mostly based on Gens code
5
6 # (c) Copyright 2007, Grazvydas "notaz" Ignotas
7 # All Rights Reserved
8
9
10 .set noreorder
11 .set noat
12
13 .text
14 .align 4
15
16 # default jump tables
17
18 m_read8_def_table:
19     .long   m_read8_rom0    # 0x000000 - 0x07FFFF
20     .long   m_read8_rom1    # 0x080000 - 0x0FFFFF
21     .long   m_read8_rom2    # 0x100000 - 0x17FFFF
22     .long   m_read8_rom3    # 0x180000 - 0x1FFFFF
23     .long   m_read8_rom4    # 0x200000 - 0x27FFFF
24     .long   m_read8_rom5    # 0x280000 - 0x2FFFFF
25     .long   m_read8_rom6    # 0x300000 - 0x37FFFF
26     .long   m_read8_rom7    # 0x380000 - 0x3FFFFF
27     .long   m_read8_rom8    # 0x400000 - 0x47FFFF - for all those large ROM hacks
28     .long   m_read8_rom9    # 0x480000 - 0x4FFFFF
29     .long   m_read8_romA    # 0x500000 - 0x57FFFF
30     .long   m_read8_romB    # 0x580000 - 0x5FFFFF
31     .long   m_read8_romC    # 0x600000 - 0x67FFFF
32     .long   m_read8_romD    # 0x680000 - 0x6FFFFF
33     .long   m_read8_romE    # 0x700000 - 0x77FFFF
34     .long   m_read8_romF    # 0x780000 - 0x7FFFFF
35     .long   m_read8_rom10   # 0x800000 - 0x87FFFF
36     .long   m_read8_rom11   # 0x880000 - 0x8FFFFF
37     .long   m_read8_rom12   # 0x900000 - 0x97FFFF
38     .long   m_read8_rom13   # 0x980000 - 0x9FFFFF
39     .long   m_read8_misc    # 0xA00000 - 0xA7FFFF
40     .long   m_read_null     # 0xA80000 - 0xAFFFFF
41     .long   m_read_null     # 0xB00000 - 0xB7FFFF
42     .long   m_read_null     # 0xB80000 - 0xBFFFFF
43     .long   m_read8_vdp     # 0xC00000 - 0xC7FFFF
44     .long   m_read8_vdp     # 0xC80000 - 0xCFFFFF
45     .long   m_read8_vdp     # 0xD00000 - 0xD7FFFF
46     .long   m_read8_vdp     # 0xD80000 - 0xDFFFFF
47     .long   m_read8_ram     # 0xE00000 - 0xE7FFFF
48     .long   m_read8_ram     # 0xE80000 - 0xEFFFFF
49     .long   m_read8_ram     # 0xF00000 - 0xF7FFFF
50     .long   m_read8_ram     # 0xF80000 - 0xFFFFFF
51
52 m_read16_def_table:
53     .long   m_read16_rom0    # 0x000000 - 0x07FFFF
54     .long   m_read16_rom1    # 0x080000 - 0x0FFFFF
55     .long   m_read16_rom2    # 0x100000 - 0x17FFFF
56     .long   m_read16_rom3    # 0x180000 - 0x1FFFFF
57     .long   m_read16_rom4    # 0x200000 - 0x27FFFF
58     .long   m_read16_rom5    # 0x280000 - 0x2FFFFF
59     .long   m_read16_rom6    # 0x300000 - 0x37FFFF
60     .long   m_read16_rom7    # 0x380000 - 0x3FFFFF
61     .long   m_read16_rom8    # 0x400000 - 0x47FFFF
62     .long   m_read16_rom9    # 0x480000 - 0x4FFFFF
63     .long   m_read16_romA    # 0x500000 - 0x57FFFF
64     .long   m_read16_romB    # 0x580000 - 0x5FFFFF
65     .long   m_read16_romC    # 0x600000 - 0x67FFFF
66     .long   m_read16_romD    # 0x680000 - 0x6FFFFF
67     .long   m_read16_romE    # 0x700000 - 0x77FFFF
68     .long   m_read16_romF    # 0x780000 - 0x7FFFFF
69     .long   m_read16_rom10   # 0x800000 - 0x87FFFF
70     .long   m_read16_rom11   # 0x880000 - 0x8FFFFF
71     .long   m_read16_rom12   # 0x900000 - 0x97FFFF
72     .long   m_read16_rom13   # 0x980000 - 0x9FFFFF
73     .long   m_read16_misc    # 0xA00000 - 0xA7FFFF
74     .long   m_read_null      # 0xA80000 - 0xAFFFFF
75     .long   m_read_null      # 0xB00000 - 0xB7FFFF
76     .long   m_read_null      # 0xB80000 - 0xBFFFFF
77     .long   m_read16_vdp     # 0xC00000 - 0xC7FFFF
78     .long   m_read16_vdp     # 0xC80000 - 0xCFFFFF
79     .long   m_read16_vdp     # 0xD00000 - 0xD7FFFF
80     .long   m_read16_vdp     # 0xD80000 - 0xDFFFFF
81     .long   m_read16_ram     # 0xE00000 - 0xE7FFFF
82     .long   m_read16_ram     # 0xE80000 - 0xEFFFFF
83     .long   m_read16_ram     # 0xF00000 - 0xF7FFFF
84     .long   m_read16_ram     # 0xF80000 - 0xFFFFFF
85
86 m_read32_def_table:
87     .long   m_read32_rom0    # 0x000000 - 0x07FFFF
88     .long   m_read32_rom1    # 0x080000 - 0x0FFFFF
89     .long   m_read32_rom2    # 0x100000 - 0x17FFFF
90     .long   m_read32_rom3    # 0x180000 - 0x1FFFFF
91     .long   m_read32_rom4    # 0x200000 - 0x27FFFF
92     .long   m_read32_rom5    # 0x280000 - 0x2FFFFF
93     .long   m_read32_rom6    # 0x300000 - 0x37FFFF
94     .long   m_read32_rom7    # 0x380000 - 0x3FFFFF
95     .long   m_read32_rom8    # 0x400000 - 0x47FFFF
96     .long   m_read32_rom9    # 0x480000 - 0x4FFFFF
97     .long   m_read32_romA    # 0x500000 - 0x57FFFF
98     .long   m_read32_romB    # 0x580000 - 0x5FFFFF
99     .long   m_read32_romC    # 0x600000 - 0x67FFFF
100     .long   m_read32_romD    # 0x680000 - 0x6FFFFF
101     .long   m_read32_romE    # 0x700000 - 0x77FFFF
102     .long   m_read32_romF    # 0x780000 - 0x7FFFFF
103     .long   m_read32_rom10   # 0x800000 - 0x87FFFF
104     .long   m_read32_rom11   # 0x880000 - 0x8FFFFF
105     .long   m_read32_rom12   # 0x900000 - 0x97FFFF
106     .long   m_read32_rom13   # 0x980000 - 0x9FFFFF
107     .long   m_read32_misc    # 0xA00000 - 0xA7FFFF
108     .long   m_read_null      # 0xA80000 - 0xAFFFFF
109     .long   m_read_null      # 0xB00000 - 0xB7FFFF
110     .long   m_read_null      # 0xB80000 - 0xBFFFFF
111     .long   m_read32_vdp     # 0xC00000 - 0xC7FFFF
112     .long   m_read32_vdp     # 0xC80000 - 0xCFFFFF
113     .long   m_read32_vdp     # 0xD00000 - 0xD7FFFF
114     .long   m_read32_vdp     # 0xD80000 - 0xDFFFFF
115     .long   m_read32_ram     # 0xE00000 - 0xE7FFFF
116     .long   m_read32_ram     # 0xE80000 - 0xEFFFFF
117     .long   m_read32_ram     # 0xF00000 - 0xF7FFFF
118     .long   m_read32_ram     # 0xF80000 - 0xFFFFFF
119
120
121 # #############################################################################
122
123 .bss
124 .align 4
125
126 # used tables
127 m_read8_table:
128     .skip 32*4
129
130 m_read16_table:
131     .skip 32*4
132
133 m_read32_table:
134     .skip 32*4
135
136
137 # #############################################################################
138
139 .text
140 .align 4
141
142 .global PicoMemReset
143 .global PicoRead8
144 .global PicoRead16
145 .global PicoRead32
146 .global PicoWriteRomHW_SSF2
147
148 .global m_read8_def_table
149 .global m_read8_table
150
151 .macro PicoMemResetCopyDef dst_table src_table
152     lui     $t0, %hi(\dst_table)
153     addiu   $t0, %lo(\dst_table)
154     lui     $t1, %hi(\src_table)
155     addiu   $t1, %lo(\src_table)
156     li      $t2, 32
157 1:
158     lw      $t3, 0($t1)
159     sw      $t3, 0($t0)
160     addiu   $t2, -1
161     addiu   $t1, 4
162     bnez    $t2, 1b
163     addiu   $t0, 4
164 .endm
165
166 # $t4 = 4
167 .macro PicoMemResetRomArea dst_table ar_label
168     lui     $t0, %hi(\dst_table)
169     addiu   $t0, %lo(\dst_table)
170     lui     $t1, %hi(\ar_label)
171     addiu   $t1, %lo(\ar_label)
172     li      $t2, 20
173 1:
174     beq     $t2, $v1, 2f
175     addiu   $t2, -1
176     sll     $t3, $t2, 2
177     beq     $t2, $t4, 1b           # do not touch the SRAM area
178     addu    $t3, $t0
179     j       1b
180     sw      $t1, 0($t3)
181 2:
182 .endm
183
184
185 PicoMemReset:
186     lui     $v1, %hi(Pico+0x22204)
187     lw      $v1, %lo(Pico+0x22204)($v1)  # romsize
188     lui     $t0, 8
189     addu    $v1, $t0
190     addiu   $v1, -1
191     srl     $v1, 19
192
193     PicoMemResetCopyDef m_read8_table  m_read8_def_table
194     PicoMemResetCopyDef m_read16_table m_read16_def_table
195     PicoMemResetCopyDef m_read32_table m_read32_def_table
196
197     # update memhandlers according to ROM size
198     li      $t4, 4
199     PicoMemResetRomArea m_read8_table  m_read8_above_rom
200     PicoMemResetRomArea m_read16_table m_read16_above_rom
201     PicoMemResetRomArea m_read32_table m_read32_above_rom
202
203     jr      $ra
204     nop
205
206 # #############################################################################
207
208 .macro PicoReadJump table
209     lui     $t0, %hi(\table)
210     srl     $t1, $a0, 19
211     ins     $t0, $t1, 2, 5
212     lw      $t0, %lo(\table)($t0)
213     ins     $a0, $0,  24, 8
214     jr      $t0
215     nop
216 .endm
217
218 PicoRead8: # u32 a
219     PicoReadJump m_read8_table
220
221 PicoRead16: # u32 a
222     PicoReadJump m_read16_table
223
224 PicoRead32: # u32 a
225     PicoReadJump m_read32_table
226
227 # #############################################################################
228
229 m_read_null:
230     jr      $ra
231     li      $v0, 0
232
233 m_read_neg1:
234     jr      $ra
235     addiu   $v0, $0, 0xffff
236
237 # loads &Pico.rom to $t3
238 .macro m_read_rom_try_sram is200000 size
239     lui     $t2, %hi(SRam)
240     addiu   $t2, %lo(SRam)
241     lui     $t3, %hi(Pico+0x22200)
242     lw      $t1, 8($t2)     # SRam.end
243 .if \is200000
244     ins     $a0, $0,  19, 13
245     lui     $t4, 0x20
246     or      $a0, $t4
247 .endif
248     subu    $t4, $a0, $t1
249     bgtz    $t4, 1f
250     addiu   $t3, %lo(Pico+0x22200)
251     lw      $t1, 4($t2)     # SRam.start
252     subu    $t4, $t1, $a0
253     bgtz    $t4, 1f
254     nop
255     lb      $t1, 0x11($t3)  # Pico.m.sram_reg
256     andi    $t4, $t1, 5
257     beqz    $t4, 1f
258     nop
259 .if \size == 8
260     j       SRAMRead
261     nop
262 .elseif \size == 16
263     sw      $ra, -4($sp)
264     jal     SRAMRead16
265     addiu   $sp, -4
266     lw      $ra, 0($sp)
267     jr      $ra
268     addiu   $sp, 4
269 .else
270     addiu   $sp, -8
271     sw      $ra, 0($sp)
272     sw      $a0, 4($sp)
273     jal     SRAMRead16
274     nop
275     lw      $a0, 4($sp)
276     sw      $v0, 4($sp)
277     jal     SRAMRead16
278     addiu   $a0, 2
279     lw      $v1, 4($sp)
280     lw      $ra, 0($sp)
281     addiu   $sp, 8
282     jr      $ra
283     ins     $v0, $v1, 16, 16
284 .endif
285 # m_read_nosram:
286 1:
287 .endm
288
289 .macro m_read8_rom sect
290     lui     $t0, %hi(Pico+0x22200)
291     lw      $t0, %lo(Pico+0x22200)($t0)  # rom
292     xori    $a0, 1
293     ins     $a0, $0,  19, 13
294 .if \sect
295     lui     $t1, 8*\sect
296     addu    $a0, $t1
297 .endif
298     addu    $t0, $a0
299     jr      $ra
300     lb      $v0, 0($t0)
301 .endm
302
303
304 m_read8_rom0: # 0x000000 - 0x07ffff
305     m_read8_rom 0
306
307 m_read8_rom1: # 0x080000 - 0x0fffff
308     m_read8_rom 1
309
310 m_read8_rom2: # 0x100000 - 0x17ffff
311     m_read8_rom 2
312
313 m_read8_rom3: # 0x180000 - 0x1fffff
314     m_read8_rom 3
315
316 m_read8_rom4: # 0x200000 - 0x27ffff, SRAM area
317     m_read_rom_try_sram 1 8
318     lw      $t1, 4($t3)     # romsize
319     subu    $t4, $t1, $a0
320     blez    $t4, m_read_null
321     lw      $t1, 0($t3)     # rom
322     xori    $a0, 1
323     addu    $t1, $a0
324     jr      $ra
325     lb      $v0, 0($t1)
326
327 m_read8_rom5: # 0x280000 - 0x2fffff
328     m_read8_rom 5
329
330 m_read8_rom6: # 0x300000 - 0x37ffff
331     m_read8_rom 6
332
333 m_read8_rom7: # 0x380000 - 0x3fffff
334     m_read8_rom 7
335
336 m_read8_rom8: # 0x400000 - 0x47ffff
337     m_read8_rom 8
338
339 m_read8_rom9: # 0x480000 - 0x4fffff
340     m_read8_rom 9
341
342 m_read8_romA: # 0x500000 - 0x57ffff
343     m_read8_rom 0xA
344
345 m_read8_romB: # 0x580000 - 0x5fffff
346     m_read8_rom 0xB
347
348 m_read8_romC: # 0x600000 - 0x67ffff
349     m_read8_rom 0xC
350
351 m_read8_romD: # 0x680000 - 0x6fffff
352     m_read8_rom 0xD
353
354 m_read8_romE: # 0x700000 - 0x77ffff
355     m_read8_rom 0xE
356
357 m_read8_romF: # 0x780000 - 0x7fffff
358     m_read8_rom 0xF
359
360 m_read8_rom10: # 0x800000 - 0x87ffff
361     m_read8_rom 0x10
362
363 m_read8_rom11: # 0x880000 - 0x8fffff
364     m_read8_rom 0x11
365
366 m_read8_rom12: # 0x900000 - 0x97ffff
367     m_read8_rom 0x12
368
369 m_read8_rom13: # 0x980000 - 0x9fffff
370     m_read8_rom 0x13
371
372
373 m_read8_misc:
374     srl     $t0, $a0, 5
375     sll     $t0, $t0, 5
376     lui     $t1, 0xa1
377     bne     $t0, $t1, m_read8_misc2
378     andi    $t0, $a0, 0x1e
379 m_read8_misc_io:
380     beqz    $t0, m_read8_misc_hwreg
381     sub     $t1, $t0, 4
382     bgtz    $t1, m_read8_misc_ioports
383     nop
384     slti    $a0, $t0, 4
385     xori    $a0, 1
386     j       PadRead
387     nop
388
389 m_read8_misc_hwreg:
390     lui     $v0, %hi(Pico+0x2220f)
391     jr      $ra
392     lb      $v0, %lo(Pico+0x2220f)($v0)
393
394 m_read8_misc_ioports:
395     lui     $v0, %hi(Pico+0x22000)
396     ins     $v0, $t0, 0, 5
397     jr      $ra
398     lb      $v0, %lo(Pico+0x22000)($v0)
399
400 m_read8_misc2:
401     lui     $t0, 0xa1
402     ori     $t0, 0x1100
403     bne     $a0, $t0, m_read8_misc3
404     srl     $t0, $a0, 16
405     j       z80ReadBusReq
406
407 m_read8_misc3:
408     addiu   $t0, 0xff60       # expecting 0xa0 to get 0
409     bnez    $t0, m_read8_misc4
410
411     # z80 area
412     andi    $t0, $a0, 0x4000
413     bnez    $t0, m_read8_z80_misc
414     andi    $t0, $a0, 0x6000
415     j       z80Read8          # z80 RAM
416
417 m_read8_z80_misc:
418     addiu   $t0, 0xc000       # expecting 0x4000 to get 0
419     bnez    $t0, m_read_neg1  # invalid
420
421     lui     $t0, %hi(PicoOpt)
422     lw      $t0, %lo(PicoOpt)($t0)
423     andi    $t0, 1
424     beqz    $t0, m_read8_fake_ym2612
425     lui     $t0, %hi(Pico+0x22208)
426     lui     $t0, %hi(ym2612_st)
427     lw      $t0, %lo(ym2612_st)($t0)
428     jr      $ra
429     lb      $v0, 0x11($t0)
430
431 m_read8_fake_ym2612:
432     lb      $v0, %lo(Pico+0x22208)($t0) # Pico.m.rotate
433     addiu   $t1, $v0, 1
434     jr      $ra
435     sb      $t1, %lo(Pico+0x22208)($t0)
436
437 # delay slot friendly
438 .macro m_read8_call16 funcname is_func_ptr=0
439 .if \is_func_ptr
440     lui     $t1, %hi(\funcname)
441     lw      $t1, %lo(\funcname)($t1)
442 .endif
443     andi    $t0, $a0, 1
444     beqz    $t0, 1f
445     li      $a1, 8      # not always needed, but shouln't cause problems
446 .if \is_func_ptr
447     jr      $t1
448 .else
449     j       \funcname   # odd address
450 .endif
451     nop
452 1:
453     addiu   $sp, -4
454     sw      $ra, 0($sp)
455 .if \is_func_ptr
456     jalr    $t1
457 .else
458     jal     \funcname
459 .endif
460     xori    $a0, 1
461     lw      $ra, 0($sp)
462     addiu   $sp, 4
463     jr      $ra
464     srl     $v0, 8
465 .endm
466
467 m_read8_misc4:
468     # if everything else fails, use generic handler
469     m_read8_call16 OtherRead16
470
471 m_read8_vdp:
472     ext     $t0, $a0, 16, 3
473     andi    $t1, $a0, 0xe0
474     or      $t0, $t1
475     bnez    $t0, m_read_null # invalid address
476     m_read8_call16 PicoVideoRead
477
478 m_read8_ram:
479     lui     $t0, %hi(Pico)
480     ins     $t0, $a0, 0, 16
481     xori    $t0, 1
482     jr      $ra
483     lb      $v0, %lo(Pico)($t0)
484
485 m_read8_above_rom:
486     # might still be SRam (Micro Machines, HardBall '95)
487     m_read_rom_try_sram 0 8
488     m_read8_call16 PicoRead16Hook 1
489
490 # #############################################################################
491
492 .macro m_read16_rom sect
493     lui     $t0, %hi(Pico+0x22200)
494     lw      $t0, %lo(Pico+0x22200)($t0)  # rom
495     ins     $a0, $0,   0,  1
496     ins     $a0, $0,  19, 13
497 .if \sect
498     lui     $t1, 8*\sect
499     addu    $a0, $t1
500 .endif
501     addu    $t0, $a0
502     jr      $ra
503     lh      $v0, 0($t0)
504 .endm
505
506
507 m_read16_rom0: # 0x000000 - 0x07ffff
508     m_read16_rom 0
509
510 m_read16_rom1: # 0x080000 - 0x0fffff
511     m_read16_rom 1
512
513 m_read16_rom2: # 0x100000 - 0x17ffff
514     m_read16_rom 2
515
516 m_read16_rom3: # 0x180000 - 0x1fffff
517     m_read16_rom 3
518
519 m_read16_rom4: # 0x200000 - 0x27ffff, SRAM area
520     m_read_rom_try_sram 1 16
521     lw      $t1, 4($t3)     # romsize
522     subu    $t4, $t1, $a0
523     blez    $t4, m_read_null
524     lw      $t1, 0($t3)     # rom
525     ins     $a0, $0, 0, 1
526     addu    $t1, $a0
527     jr      $ra
528     lh      $v0, 0($t1)
529
530 m_read16_rom5: # 0x280000 - 0x2fffff
531     m_read16_rom 5
532
533 m_read16_rom6: # 0x300000 - 0x37ffff
534     m_read16_rom 6
535
536 m_read16_rom7: # 0x380000 - 0x3fffff
537     m_read16_rom 7
538
539 m_read16_rom8: # 0x400000 - 0x47ffff
540     m_read16_rom 8
541
542 m_read16_rom9: # 0x480000 - 0x4fffff
543     m_read16_rom 9
544
545 m_read16_romA: # 0x500000 - 0x57ffff
546     m_read16_rom 0xA
547
548 m_read16_romB: # 0x580000 - 0x5fffff
549     m_read16_rom 0xB
550
551 m_read16_romC: # 0x600000 - 0x67ffff
552     m_read16_rom 0xC
553
554 m_read16_romD: # 0x680000 - 0x6fffff
555     m_read16_rom 0xD
556
557 m_read16_romE: # 0x700000 - 0x77ffff
558     m_read16_rom 0xE
559
560 m_read16_romF: # 0x780000 - 0x7fffff
561     m_read16_rom 0xF
562
563 m_read16_rom10: # 0x800000 - 0x87ffff
564     m_read16_rom 0x10
565
566 m_read16_rom11: # 0x880000 - 0x8fffff
567     m_read16_rom 0x11
568
569 m_read16_rom12: # 0x900000 - 0x97ffff
570     m_read16_rom 0x12
571
572 m_read16_rom13: # 0x980000 - 0x9fffff
573     m_read16_rom 0x13
574
575 m_read16_misc:
576     ins     $a0, $0, 0, 1
577     j       OtherRead16
578     li      $a1, 16
579
580 m_read16_vdp:
581     ext     $t0, $a0, 16, 3
582     andi    $t1, $a0, 0xe0
583     or      $t0, $t1
584     bnez    $t0, m_read_null # invalid address
585     ins     $a0, $0, 0, 1
586     j       PicoVideoRead
587     nop
588
589 m_read16_ram:
590     lui     $t0, %hi(Pico)
591     ins     $a0, $0, 0, 1
592     ins     $t0, $a0, 0, 16
593     jr      $ra
594     lh      $v0, %lo(Pico)($t0)
595
596 m_read16_above_rom:
597     # might still be SRam
598     m_read_rom_try_sram 0 16
599     lui     $t1, %hi(PicoRead16Hook)
600     lw      $t1, %lo(PicoRead16Hook)($t1)
601     jr      $t1
602     ins     $a0, $0, 0, 1
603
604 # #############################################################################
605
606 .macro m_read32_rom sect
607     lui     $t0, %hi(Pico+0x22200)
608     lw      $t0, %lo(Pico+0x22200)($t0)  # rom
609     ins     $a0, $0,   0,  1
610     ins     $a0, $0,  19, 13
611 .if \sect
612     lui     $t1, 8*\sect
613     addu    $a0, $t1
614 .endif
615     addu    $t0, $a0
616     lh      $v1, 0($t0)
617     lh      $v0, 2($t0)
618     jr      $ra
619     ins     $v0, $v1, 16, 16
620 .endm
621
622
623 m_read32_rom0: # 0x000000 - 0x07ffff
624     m_read32_rom 0
625
626 m_read32_rom1: # 0x080000 - 0x0fffff
627     m_read32_rom 1
628
629 m_read32_rom2: # 0x100000 - 0x17ffff
630     m_read32_rom 2
631
632 m_read32_rom3: # 0x180000 - 0x1fffff
633     m_read32_rom 3
634
635 m_read32_rom4: # 0x200000 - 0x27ffff, SRAM area
636     m_read_rom_try_sram 1 32
637     lw      $t1, 4($t3)     # romsize
638     subu    $t4, $t1, $a0
639     blez    $t4, m_read_null
640     lw      $t1, 0($t3)     # rom
641     ins     $a0, $0, 0, 1
642     addu    $t1, $a0
643     lh      $v1, 0($t1)
644     lh      $v0, 2($t1)
645     jr      $ra
646     ins     $v0, $v1, 16, 16
647
648 m_read32_rom5: # 0x280000 - 0x2fffff
649     m_read32_rom 5
650
651 m_read32_rom6: # 0x300000 - 0x37ffff
652     m_read32_rom 6
653
654 m_read32_rom7: # 0x380000 - 0x3fffff
655     m_read32_rom 7
656
657 m_read32_rom8: # 0x400000 - 0x47ffff
658     m_read32_rom 8
659
660 m_read32_rom9: # 0x480000 - 0x4fffff
661     m_read32_rom 9
662
663 m_read32_romA: # 0x500000 - 0x57ffff
664     m_read32_rom 0xA
665
666 m_read32_romB: # 0x580000 - 0x5fffff
667     m_read32_rom 0xB
668
669 m_read32_romC: # 0x600000 - 0x67ffff
670     m_read32_rom 0xC
671
672 m_read32_romD: # 0x680000 - 0x6fffff
673     m_read32_rom 0xD
674
675 m_read32_romE: # 0x700000 - 0x77ffff
676     m_read32_rom 0xE
677
678 m_read32_romF: # 0x780000 - 0x7fffff
679     m_read32_rom 0xF
680
681 m_read32_rom10: # 0x800000 - 0x87ffff
682     m_read32_rom 0x10
683
684 m_read32_rom11: # 0x880000 - 0x8fffff
685     m_read32_rom 0x11
686
687 m_read32_rom12: # 0x900000 - 0x97ffff
688     m_read32_rom 0x12
689
690 m_read32_rom13: # 0x980000 - 0x9fffff
691     m_read32_rom 0x13
692
693 .macro m_read32_call16 func need_a1=0
694     addiu   $sp, -8
695     sw      $ra, 0($sp)
696     sw      $s0, 4($sp)
697 .if \need_a1
698     li      $a1, 16
699 .endif
700     jal     \func
701     move    $s0, $a0
702
703     addu    $a0, $s0, 2
704 .if \need_a1
705     li      $a1, 16
706 .endif
707     jal     \func
708     move    $s0, $v0
709
710     ins     $v0, $s0, 16, 16
711     lw      $ra, 0($sp)
712     lw      $s0, 4($sp)
713     jr      $ra
714     addiu   $sp, 8
715 .endm
716
717 m_read32_misc:
718     ins     $a0, $0, 0, 1
719     m_read32_call16 OtherRead16, 1
720
721 m_read32_vdp:
722     ext     $t0, $a0, 16, 3
723     andi    $t1, $a0, 0xe0
724     or      $t0, $t1
725     bnez    $t0, m_read_null # invalid address
726     ins     $a0, $0, 0, 1
727     m_read32_call16 PicoVideoRead
728
729 m_read32_ram:
730     lui     $t0, %hi(Pico)
731     ins     $a0, $0, 0, 1
732     ins     $t0, $a0, 0, 16
733     lh      $v1, %lo(Pico)($t0)
734     lh      $v0, %lo(Pico+2)($t0)
735     jr      $ra
736     ins     $v0, $v1, 16, 16
737
738 m_read32_above_rom:
739     # might still be SRam
740     m_read_rom_try_sram 0 32
741     ins     $a0, $0, 0, 1
742     lui     $t1, %hi(PicoRead16Hook)
743     lw      $t1, %lo(PicoRead16Hook)($t1)
744     addiu   $sp, -4*3
745     sw      $ra, 0($sp)
746     sw      $s0, 4($sp)
747     sw      $t1, 8($sp)
748     jalr    $t1
749     move    $s0, $a0
750
751     lw      $t1, 8($sp)
752     addu    $a0, $s0, 2
753     jalr    $t1
754     move    $s0, $v0
755
756     ins     $v0, $s0, 16, 16
757     lw      $ra, 0($sp)
758     lw      $s0, 4($sp)
759     jr      $ra
760     addiu   $sp, 4*3
761
762 # #############################################################################
763
764 .macro PicoWriteRomHW_SSF2_ls def_table table
765     lui     $t3, %hi(\def_table)
766     ins     $t3, $a1, 2, 5
767     lw      $t0, %lo(\def_table)($t3)
768     lui     $t2, %hi(\table)
769     ins     $t2, $a0, 2, 3
770     sw      $t0, %lo(\table)($t2)
771 .endm
772
773 PicoWriteRomHW_SSF2: # u32 a, u32 d
774     ext     $a0, $a0, 1, 3
775     bnez    $a0, pwr_banking
776
777     # sram register
778     lui     $t0, %hi(Pico+0x22211)
779     lb      $t1, %lo(Pico+0x22211)($t0) # Pico.m.sram_reg
780     ins     $t1, $a1, 0, 2
781     jr      $ra
782     sb      $t1, %lo(Pico+0x22211)($t0)
783
784 pwr_banking:
785     andi    $a1, 0x1f
786
787     PicoWriteRomHW_SSF2_ls m_read8_def_table  m_read8_table
788     PicoWriteRomHW_SSF2_ls m_read16_def_table m_read16_table
789     PicoWriteRomHW_SSF2_ls m_read32_def_table m_read32_table
790  
791     jr      $ra
792     nop
793