@ vim:filetype=armasm
-@ Memory i/o handlers for Sega/Mega CD emulation
+@ Memory I/O handlers for Sega/Mega CD emulation
@ (c) Copyright 2007, Grazvydas "notaz" Ignotas
-@ All Rights Reserved
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x280000 - 0x2fffff
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x300000
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x3fffff
- .long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x400000
+ .long m_m68k_&\on&\sz&_bcram_size @ 0x400000
+ .long m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x420000
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x4fffff
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x500000
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x5fffff
- .long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x600000
+ .long m_m68k_&\on&\sz&_bcram @ 0x600000
+ .long m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x620000
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x6fffff
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x700000
- .long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x7fffff
+ .long m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x7dffff
+ .long m_m68k_&\on&\sz&_bcram_reg @ 0x7e0000
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x800000
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ - 0x8fffff
.long m_&\on&_null, m_&\on&_null, m_&\on&_null, m_&\on&_null @ 0x900000
.extern gfx_cd_write16
.extern s68k_reg_write8
.extern s68k_poll_adclk
-.extern PicoCpuS68k
+.extern PicoCpuMS68k
.extern s68k_poll_detect
.extern SN76496Write
+.extern m_m68k_read8_misc
+.extern m_m68k_write8_misc
@ r0=reg3, r1-r3=temp
streq r1, [r2, r0]
.endm
+@
+.macro bcram_reg_rw is_read addr_check
+ rsb r0, r0, #0x800000
+ ldr r2, =(Pico+0x22200)
+ cmp r0, #(0x800000-\addr_check)
+ ldreq r2, [r2]
+.if \is_read
+ movne r0, #0
+.endif
+ bxne lr
+ add r2, r2, #0x110000
+ add r2, r2, #0x002200
+.if \is_read
+ ldrb r0, [r2, #0x18]
+.else
+ strb r1, [r2, #0x18]
+.endif
+ bx lr
+.endm
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bx lr
+m_m68k_read8_bcram_size: @ 0x400000
+ sub r0, r0, #1
+ cmp r0, #0x400000
+ ldreq r1, =SRam
+ mov r0, #0
+ ldreq r1, [r1]
+ bxne lr
+ tst r1, r1
+ movne r0, #3 @ pretend to be a 64k cart (8<<3)
+ bx lr
+
+
+m_m68k_read8_bcram: @ 0x600000 - 0x61ffff
+ ldr r1, =SRam
+ bic r0, r0, #0xfe0000
+ ldr r1, [r1]
+ mov r0, r0, lsr #1
+ tst r1, r1
+ moveq r0, #0
+ bxeq lr
+ add r1, r1, #0x2000
+ ldrb r0, [r1, r0]
+ bx lr
+
+
+m_m68k_read8_bcram_reg: @ 0x7fffff
+ bcram_reg_rw 1, 0x7fffff
+
+
m_m68k_read8_system_io:
bic r2, r0, #0xfe0000
bic r2, r2, #0x3f
cmp r2, #0x012000
- bne m_m68k_read8_misc
+ bne m_m68k_read8_misc @ now from Pico/Memory.s
ldr r1, =(Pico+0x22200)
and r0, r0, #0x3f
ldrb r0, [r1, r0]
bx lr
-
+/*
m_m68k_read8_misc:
bic r2, r0, #0x00ff
bic r2, r2, #0xbf00
tst r1, #1
moveq r0, r0, lsr #8
bx lr
-
+*/
m_m68k_read8_vdp:
tst r0, #0x70000
bx lr
+m_m68k_read16_bcram_size: @ 0x400000
+ cmp r0, #0x400000
+ ldreq r1, =SRam
+ mov r0, #0
+ ldreq r1, [r1]
+ bxne lr
+ tst r1, r1
+ movne r0, #3 @ pretend to be a 64k cart
+ bx lr
+
+
+@ m_m68k_read16_bcram: @ 0x600000 - 0x61ffff
+.equiv m_m68k_read16_bcram, m_m68k_read8_bcram
+
+
+m_m68k_read16_bcram_reg: @ 0x7fffff
+ bcram_reg_rw 1, 0x7ffffe
+
+
m_m68k_read16_system_io:
bic r1, r0, #0xfe0000
bic r1, r1, #0x3f
bx r12
+m_m68k_read32_bcram_size: @ 0x400000
+ cmp r0, #0x400000
+ ldreq r1, =SRam
+ mov r0, #0
+ ldreq r1, [r1]
+ bxne lr
+ tst r1, r1
+ movne r0, #0x30000 @ pretend to be a 64k cart
+ bx lr
+
+
+m_m68k_read32_bcram: @ 0x600000 - 0x61ffff, not likely to be called
+ mov r12,lr
+ add r3, r0, #2
+ bl m_m68k_read8_bcram
+ mov r1, r0
+ mov r0, r3
+ mov r3, r1
+ bl m_m68k_read8_bcram
+ orr r0, r0, r3, lsl #16
+ bx r12
+
+
+m_m68k_read32_bcram_reg: @ 0x7fffff
+ bcram_reg_rw 1, 0x7ffffc
+
+
@ it is not very practical to use long access on hw registers, so I assume it is not used too much.
m_m68k_read32_system_io:
bic r1, r0, #0xfe0000
m_write_null:
m_m68k_write8_bios:
+m_m68k_write8_bcram_size: @ 0x400000
bx lr
bx lr
+m_m68k_write8_bcram: @ 0x600000 - 0x61ffff
+ @ can't use r3 or r12, because of write32
+ ldr r2, =SRam
+ bic r0, r0, #0xfe0000
+ ldr r2, [r2]
+ tst r2, r2
+ bxeq lr
+ add r0, r2, r0, lsr #1
+ ldr r2, =(Pico+0x22200)
+ ldr r2, [r2]
+ add r0, r0, #0x2000
+ add r2, r2, #0x110000
+ add r2, r2, #0x002200
+ ldr r2, [r2, #0x18]
+ tst r2, #1 @ check bcram reg
+ bxeq lr
+ strb r1, [r0]
+ ldr r2, =SRam
+ mov r0, #1
+ strb r0, [r2, #0x0e] @ SRam.changed = 1
+ bx lr
+
+
+m_m68k_write8_bcram_reg: @ 0x7fffff
+ bcram_reg_rw 0, 0x7fffff
+
+
m_m68k_write8_system_io:
bic r2, r0, #0xfe0000
bic r2, r2, #0x3f
cmp r2, #0x012000
beq m68k_reg_write8
mov r2, #8
- b OtherWrite8
+@ b OtherWrite8
+ b m_m68k_write8_misc
m_m68k_write8_vdp:
m_m68k_write16_bios:
+m_m68k_write16_bcram_size: @ 0x400000
bx lr
bx lr
+@ m_m68k_write16_bcram: @ 0x600000 - 0x61ffff
+.equiv m_m68k_write16_bcram, m_m68k_write8_bcram
+
+
+m_m68k_write16_bcram_reg: @ 0x7fffff
+ bcram_reg_rw 0, 0x7ffffe
+
+
m_m68k_write16_system_io:
bic r0, r0, #1
bic r2, r0, #0xfe0000
cmp r2, #0x012000
bne OtherWrite16
-m_m68k_write16_m68k_regs:
+m_m68k_write16_regs:
and r0, r0, #0x3e
cmp r0, #0x0e
beq m_m68k_write16_regs_spec
and r2, r2, #0xfe
cmp r2, #0x0e
bxne lr
- ldr r0, =PicoCpuS68k
+ ldr r0, =PicoCpuCS68k
str r1, [r0, #0x58] @ push s68k out of stopped state
str r1, [r3]
bx lr
m_m68k_write32_bios:
+m_m68k_write32_bcram_size: @ 0x400000
bx lr
b m_m68k_write16_wordram1_1M_b1
+m_m68k_write32_bcram: @ 0x600000 - 0x61ffff, not likely to be called
+ mov r12,lr
+ add r3, r0, #2
+ mov r1, r1, ror #16
+ bl m_m68k_write8_bcram
+ mov r0, r3
+ mov r1, r1, ror #16
+ bl m_m68k_write8_bcram
+ bx r12
+
+
+m_m68k_write32_bcram_reg: @ 0x7fffff
+ bcram_reg_rw 0, 0x7ffffc
+
+
+
@ it is not very practical to use long access on hw registers, so I assume it is not used too much.
m_m68k_write32_system_io:
bic r2, r0, #0xfe0000
cmp r2, #0x012000
bne m_m68k_write32_misc
and r2, r0, #0x3e
- cmp r2, #0x10
- blt m_m68k_write32_regs
cmp r2, #0x20
bxge lr
- @ Handle the 0x10-0x1f range
- ldr r0, =(Pico+0x22200)
- mov r3, #0xff
- ldr r0, [r0]
- orr r3, r3, r3, lsl #16
- add r0, r0, #0x110000
- and r12,r3, r1, ror #16 @ data is big-endian to be written as little, have to byteswap
- and r1, r3, r1, ror #24
- orr r1, r1, r12,lsl #8 @ end of byteswap
- strh r1, [r2, r0]!
- cmp r2, #0x1e
- movne r1, r1, lsr #16
- strneh r1, [r2, #2]
- bx lr
+ cmp r2, #0x10
+ bge m_m68k_write32_regs_comm
+ cmp r2, #0x0c
+ bge m_m68k_write32_regs_spec @ hits the nasty comm reg qiurk
-m_m68k_write32_regs:
bic r0, r0, #1
stmfd sp!,{r0,r1,lr}
mov r1, r1, lsr #24
add r0, r0, #3
b m68k_reg_write8
+m_m68k_write32_regs_comm: @ Handle the 0x10-0x1f range
+ ldr r0, =(Pico+0x22200)
+ mov r3, #0xff
+ ldr r0, [r0]
+ orr r3, r3, r3, lsl #16
+ add r0, r0, #0x110000
+ and r12,r3, r1, ror #16 @ data is big-endian to be written as little, have to byteswap
+ and r1, r3, r1, ror #24
+ orr r1, r1, r12,lsl #8 @ end of byteswap
+ cmp r2, #0x1e
+ strh r1, [r2, r0]!
+ ldr r3, =s68k_poll_adclk
+ ldr r0, [r3]
+ movne r1, r1, lsr #16
+ strneh r1, [r2, #2]
+ cmp r0, #0x10
+ bxlt lr
+ ldr r0, =PicoCpuCS68k @ remove poll detected state for s68k
+ mov r1, #0
+ str r1, [r0, #0x58]
+ str r1, [r3]
+ bx lr
+
m_m68k_write32_misc:
bic r0, r0, #1
stmfd sp!,{r0,r1,lr}
add r0, r0, #2
b OtherWrite16
+m_m68k_write32_regs_spec:
+ bic r0, r0, #1
+ stmfd sp!,{r0,r1,lr}
+ mov r1, r1, lsr #16
+ bl m_m68k_write16_regs
+ ldmfd sp!,{r0,r1,lr}
+ add r0, r0, #2
+ b m_m68k_write16_regs
+
m_m68k_write32_vdp:
tst r0, #0x70000
m_s68k_write32_pcm_reg:
mov r0, r0, lsr #1
- add r2, r0, #1
- mov r3, r1
- stmfd sp!,{r2,r3,lr}
+ stmfd sp!,{r0,r1,lr}
mov r1, r1, lsr #16
bl pcm_write
ldmfd sp!,{r0,r1,lr}
+ add r0, r0, #1
b pcm_write
bic r0, r0, #0x008000
bic r0, r0, #1
tst r0, #0x7e00
- movne r0, #0
bxne lr
sub r2, r0, #0x58
cmp r2, #0x10
blo m_s68k_write32_regs_gfx
+ and r2, r0, #0x1fc
+ cmp r2, #0x0c
+ beq m_s68k_write32_regs_spec @ hits 0x0f
+ and r2, r0, #0x1f0
+ cmp r2, #0x20
+ beq m_s68k_write32_regs_comm
stmfd sp!,{r0,r1,lr}
mov r1, r1, lsr #24
b s68k_reg_write8
m_s68k_write32_regs_gfx:
- mov r3, r1
- add r2, r0, #2
- stmfd sp!,{r2,r3,lr}
+ stmfd sp!,{r0,r1,lr}
mov r1, r1, lsr #16
bl gfx_cd_write16
ldmfd sp!,{r0,r1,lr}
+ add r0, r0, #2
b gfx_cd_write16
+m_s68k_write32_regs_comm: @ Handle the 0x20-0x2f range
+ ldr r2, =(Pico+0x22200)
+ mov r3, #0xff
+ ldr r2, [r2]
+ orr r3, r3, r3, lsl #16
+ add r2, r2, #0x110000
+ and r12,r3, r1, ror #16 @ data is big-endian to be written as little, have to byteswap
+ and r1, r3, r1, ror #24
+ orr r1, r1, r12,lsl #8 @ end of byteswap
+ cmp r0, #0x2e
+ strh r1, [r0, r2]!
+ movne r1, r1, lsr #16
+ strneh r1, [r0, #2]
+ bx lr
+
+m_s68k_write32_regs_spec:
+ stmfd sp!,{r0,r1,lr}
+ mov r1, r1, lsr #16
+ bl m_s68k_write16_regs
+ ldmfd sp!,{r0,r1,lr}
+ add r0, r0, #2
+ b m_s68k_write16_regs
+
+