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