asm code updated, Bass Masters fix
[picodrive.git] / Pico / cd / Memory.s
index ecfc7ec..1b9fe96 100644 (file)
@@ -1,12 +1,12 @@
 @ 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
 
 
 
 .equiv PCM_STEP_SHIFT, 11
+.equiv POLL_LIMIT, 16
 
 @ jump tables
 .data
     .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
@@ -62,7 +65,7 @@
 .endm
 
 
-@ the jumptables themselves
+@ the jumptables themselves.
 m_m68k_read8_table:   mk_m68k_jump_table read 8
 m_m68k_read16_table:  mk_m68k_jump_table read 16
 m_m68k_read32_table:  mk_m68k_jump_table read 32
@@ -77,6 +80,26 @@ m_s68k_write8_table:  mk_s68k_jump_table write 8
 m_s68k_write16_table: mk_s68k_jump_table write 16
 m_s68k_write32_table: mk_s68k_jump_table write 32
 
+m_s68k_decode_write_table:
+    .long m_s68k_write8_2M_decode_b0_m0
+    .long m_s68k_write16_2M_decode_b0_m0
+    .long m_s68k_write32_2M_decode_b0_m0
+    .long m_s68k_write8_2M_decode_b0_m1
+    .long m_s68k_write16_2M_decode_b0_m1
+    .long m_s68k_write32_2M_decode_b0_m1
+    .long m_s68k_write8_2M_decode_b0_m2
+    .long m_s68k_write16_2M_decode_b0_m2
+    .long m_s68k_write32_2M_decode_b0_m2
+    .long m_s68k_write8_2M_decode_b1_m0
+    .long m_s68k_write16_2M_decode_b1_m0
+    .long m_s68k_write32_2M_decode_b1_m0
+    .long m_s68k_write8_2M_decode_b1_m1
+    .long m_s68k_write16_2M_decode_b1_m1
+    .long m_s68k_write32_2M_decode_b1_m1
+    .long m_s68k_write8_2M_decode_b1_m2
+    .long m_s68k_write16_2M_decode_b1_m2
+    .long m_s68k_write32_2M_decode_b1_m2
+
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
@@ -84,6 +107,7 @@ m_s68k_write32_table: mk_s68k_jump_table write 32
 .align 4
 
 .global PicoMemResetCD
+.global PicoMemResetCDdecode
 .global PicoReadM68k8
 .global PicoReadM68k16
 .global PicoReadM68k32
@@ -104,13 +128,18 @@ m_s68k_write32_table: mk_s68k_jump_table write 32
 .extern PicoVideoRead
 .extern Read_CDC_Host
 .extern m68k_reg_write8
-.extern OtherWrite8
 .extern OtherWrite16
 .extern gfx_cd_read
 .extern s68k_reg_read16
 .extern SRam
 .extern gfx_cd_write16
 .extern s68k_reg_write8
+.extern s68k_poll_adclk
+.extern PicoCpuMS68k
+.extern s68k_poll_detect
+.extern SN76496Write
+.extern m_m68k_read8_misc
+.extern m_m68k_write8_misc
 
 
 @ r0=reg3, r1-r3=temp
@@ -141,10 +170,12 @@ m_s68k_write32_table: mk_s68k_jump_table write 32
     ldr     r3, =m_m68k_&\on&\sz&_wordram1_1M_b0
     str     r2, [r1, #16*4]
     str     r3, [r1, #17*4]
-    ldr     r2, =m_s68k_&\on&\sz&_wordram_2M_decode_b1
     ldr     r3, =m_s68k_&\on&\sz&_wordram_1M_b1
+.ifeqs "\on", "read"
+    ldr     r2, =m_s68k_&\on&\sz&_wordram_2M_decode_b1
     str     r2, [r12,#4*4]
     str     r2, [r12,#5*4]
+.endif
     str     r3, [r12,#6*4]
     b       9f @ pmr_8_done
 
@@ -153,10 +184,12 @@ m_s68k_write32_table: mk_s68k_jump_table write 32
     ldr     r3, =m_m68k_&\on&\sz&_wordram1_1M_b1
     str     r2, [r1, #16*4]
     str     r3, [r1, #17*4]
-    ldr     r2, =m_s68k_&\on&\sz&_wordram_2M_decode_b0
     ldr     r3, =m_s68k_&\on&\sz&_wordram_1M_b0
+.ifeqs "\on", "read"
+    ldr     r2, =m_s68k_&\on&\sz&_wordram_2M_decode_b0
     str     r2, [r12,#4*4]
     str     r2, [r12,#5*4]
+.endif
     str     r3, [r12,#6*4]
 
 9: @ pmr_8_done:
@@ -173,6 +206,29 @@ PicoMemResetCD: @ r3
     bx      lr
 
 
+PicoMemResetCDdecode: @reg3
+    tst     r0, #4
+    bxeq    lr                 @ we should not be called in 2M mode
+    ldr     r1, =m_s68k_write8_table
+    ldr     r3, =m_s68k_decode_write_table
+    and     r2, r0, #0x18
+    mov     r2, r2, lsr #3
+    cmp     r2, #3
+    moveq   r2, #2             @ mode3 is same as mode2?
+    tst     r0, #1
+    addeq   r2, r2, #3         @ bank1 (r2=0..5)
+    add     r2, r2, r2, lsl #1 @ *= 3
+    add     r2, r3, r2, lsl #2
+    ldmia   r2, {r0,r3,r12}
+    str     r0, [r1, #4*4]
+    str     r0, [r1, #5*4]
+    str     r3, [r1, #4*4+8*4]
+    str     r3, [r1, #5*4+8*4]
+    str     r12,[r1, #4*4+8*4*2]
+    str     r12,[r1, #5*4+8*4*2]
+    bx      lr
+
+
 .pool
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -290,7 +346,7 @@ PicoWriteS68k32: @ u32 a, u32 d
 .endm
 
 
-@ r0=prt1, r1=ptr2
+@ r0=prt1, r1=ptr2; unaligned ptr MUST be r0
 .macro m_read32_gen
     tst     r0, #2
     ldrneh  r0, [r1, r0]!
@@ -301,7 +357,7 @@ PicoWriteS68k32: @ u32 a, u32 d
 .endm
 
 
-@ r0=prt1, r1=data, r2=ptr2
+@ r0=prt1, r1=data, r2=ptr2; unaligned ptr MUST be r0
 .macro m_write32_gen
     tst     r0, #2
     mov     r1, r1, ror #16
@@ -311,6 +367,25 @@ PicoWriteS68k32: @ u32 a, u32 d
     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]      @ Pico_mcd->m.bcram_reg
+.else
+    strb    r1, [r2, #0x18]
+.endif
+    bx      lr
+.endm
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
@@ -337,7 +412,8 @@ m_m68k_read8_prgbank:
     orr     r3, r2, #0x002200
     ldr     r3, [r1, r3]
     ldr     r2, [r1, r2]
-    tst     r3, #0x00020000             @ have bus?
+    and     r3, r3, #0x00030000
+    cmp     r3,     #0x00010000         @ have bus or in reset state?
     moveq   r0, #0
     bxeq    lr
     and     r2, r2, #0xc0000000                @ r3 & 0xC0
@@ -394,11 +470,40 @@ m_m68k_read8_wordram1_1M_b1:            @ 0x220000 - 0x23ffff, cell arranged
     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
@@ -422,7 +527,7 @@ m_m68k_read8_system_io:
     .long   m_m68k_read8_r0d
 m_m68k_read8_r00:
     add     r1, r1, #0x110000
-    ldr     r0, [r1, #30]
+    ldr     r0, [r1, #0x30]
     and     r0, r0, #0x04000000       @ we need irq2 mask state
     mov     r0, r0, lsr #19
     bx      lr
@@ -438,7 +543,13 @@ m_m68k_read8_r02:
 m_m68k_read8_r03:
     add     r1, r1, #0x110000
     ldrb    r0, [r1, #3]
+    add     r1, r1, #0x002200
+    ldr     r1, [r1, #4]
     and     r0, r0, #0xc7
+    tst     r1, #2                    @ DMNA pending?
+    bxeq    lr
+    bic     r0, r0, #1
+    orr     r0, r0, #2
     bx      lr
 m_m68k_read8_r04:
     add     r1, r1, #0x110000
@@ -478,7 +589,7 @@ m_m68k_read8_hi:
     ldrb    r0, [r1, r0]
     bx      lr
 
-
+/*
 m_m68k_read8_misc:
     bic     r2, r0, #0x00ff
     bic     r2, r2, #0xbf00
@@ -494,7 +605,7 @@ m_m68k_read8_misc:
     tst     r1, #1
     moveq   r0, r0, lsr #8
     bx      lr
-
+*/
 
 m_m68k_read8_vdp:
     tst     r0, #0x70000
@@ -537,7 +648,8 @@ m_m68k_read16_prgbank:
     orr     r3, r2, #0x002200
     ldr     r3, [r1, r3]
     ldr     r2, [r1, r2]
-    tst     r3, #0x00020000             @ have bus?
+    and     r3, r3, #0x00030000
+    cmp     r3,     #0x00010000         @ have bus or in reset state?
     moveq   r0, #0
     bxeq    lr
     and     r2, r2, #0xc0000000                @ r3 & 0xC0
@@ -595,6 +707,25 @@ m_m68k_read16_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
     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
@@ -617,7 +748,7 @@ m_m68k_read16_m68k_regs:
     .long   m_m68k_read16_r0c
 m_m68k_read16_r00:
     add     r1, r1, #0x110000
-    ldr     r0, [r1, #30]
+    ldr     r0, [r1, #0x30]
     add     r1, r1, #0x002200
     ldrb    r1, [r1, #2]              @ Pico_mcd->m.busreq
     and     r0, r0, #0x04000000       @ we need irq2 mask state
@@ -626,9 +757,15 @@ m_m68k_read16_r00:
 m_m68k_read16_r02:
     add     r1, r1, #0x110000
     ldrb    r0, [r1, #2]
-    ldrb    r1, [r1, #3]
-    and     r1, r1, #0xc7
-    orr     r0, r1, r0, lsl #8
+    ldrb    r2, [r1, #3]
+    add     r1, r1, #0x002200
+    ldr     r1, [r1, #4]
+    and     r2, r2, #0xc7
+    orr     r0, r2, r0, lsl #8
+    tst     r1, #2                    @ DMNA pending?
+    bxeq    lr
+    bic     r0, r0, #1
+    orr     r0, r0, #2
     bx      lr
 m_m68k_read16_r04:
     add     r1, r1, #0x110000
@@ -701,7 +838,8 @@ m_m68k_read32_prgbank:
     orr     r3, r2, #0x002200
     ldr     r3, [r1, r3]
     ldr     r2, [r1, r2]
-    tst     r3, #0x00020000             @ have bus?
+    and     r3, r3, #0x00030000
+    cmp     r3,     #0x00010000         @ have bus or in reset state?
     moveq   r0, #0
     bxeq    lr
     and     r2, r2, #0xc0000000                @ r3 & 0xC0
@@ -783,6 +921,33 @@ m_m68k_read32_wordram1_1M_b1_unal:
     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
@@ -796,11 +961,12 @@ m_m68k_read32_system_io:
     movge   r0, #0
     bxge    lr
     @ I have seen the range 0x0e-0x2f accessed quite frequently with long i/o, so here is some code for that
-    ldr     r0, =(Pico+0x22200)
+    mov     r0, r1
+    ldr     r1, =(Pico+0x22200)
     mov     r2, #0xff
-    ldr     r0, [r0]
+    ldr     r1, [r1]
     orr     r2, r2, r2, lsl #16
-    add     r0, r0, #0x110000
+    add     r1, r1, #0x110000
     m_read32_gen
     and     r1, r2, r0                @ data is big-endian read as little, have to byteswap
     and     r0, r2, r0, lsr #8
@@ -847,6 +1013,7 @@ m_m68k_read32_ram:
 
 m_write_null:
 m_m68k_write8_bios:
+m_m68k_write8_bcram_size:               @ 0x400000
     bx      lr
 
 
@@ -858,7 +1025,8 @@ m_m68k_write8_prgbank:
     orr     r3, r12, #0x002200
     ldr     r3, [r2, r3]
     ldr     r12,[r2, r12]
-    tst     r3, #0x00020000             @ have bus?
+    and     r3, r3, #0x00030000
+    cmp     r3,     #0x00010000         @ have bus or in reset state?
     bxeq    lr
     and     r12,r12,#0xc0000000                @ r3 & 0xC0
     add     r2, r2, r12, lsr #12
@@ -916,19 +1084,51 @@ m_m68k_write8_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
     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:
     tst     r0, #0x70000
     tsteq   r0, #0x000e0
     bxne    lr                          @ invalid
+    and     r2, r0, #0x19
+    cmp     r2, #0x11
+    andeq   r0, r1, #0xff
+    beq     SN76496Write
     and     r1, r1, #0xff
     orr     r1, r1, r1, lsl #8          @ byte access gets mirrored
     b       PicoVideoWrite
@@ -946,6 +1146,7 @@ m_m68k_write8_ram:
 
 
 m_m68k_write16_bios:
+m_m68k_write16_bcram_size:              @ 0x400000
     bx      lr
 
 
@@ -957,7 +1158,8 @@ m_m68k_write16_prgbank:
     orr     r3, r12, #0x002200
     ldr     r3, [r2, r3]
     ldr     r12,[r2, r12]
-    tst     r3, #0x00020000             @ have bus?
+    and     r3, r3, #0x00030000
+    cmp     r3,     #0x00010000         @ have bus or in reset state?
     bxeq    lr
     and     r12,r12,#0xc0000000                @ r3 & 0xC0
     add     r2, r2, r12, lsr #12
@@ -1016,6 +1218,14 @@ m_m68k_write16_wordram1_1M_b1:           @ 0x220000 - 0x23ffff, cell arranged
     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
@@ -1023,7 +1233,10 @@ m_m68k_write16_system_io:
     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     r3, r1, #0xff
     add     r2, r0, #1
     stmfd   sp!,{r2,r3,lr}
@@ -1032,13 +1245,35 @@ m_m68k_write16_m68k_regs:
     ldmfd   sp!,{r0,r1,lr}
     b       m68k_reg_write8
 
+m_m68k_write16_regs_spec:               @ special case
+    ldr     r2, =(Pico+0x22200)
+    ldr     r3, =s68k_poll_adclk
+    mov     r0, #0x110000
+    ldr     r2, [r2]
+    add     r0, r0, #0x00000e
+    mov     r1, r1, lsr #8
+    strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0x0e] = d >> 8;
+    ldr     r2, [r3]
+    mov     r1, #0
+    and     r2, r2, #0xfe
+    cmp     r2, #0x0e
+    bxne    lr
+    ldr     r0, =PicoCpuCS68k
+    str     r1, [r0, #0x58]             @ push s68k out of stopped state
+    str     r1, [r3]
+    bx      lr
+
 
 m_m68k_write16_vdp:
     tst     r0, #0x70000
     tsteq   r0, #0x000e0
     bxne    lr              @ invalid
     bic     r0, r0, #1
-    b       PicoVideoWrite
+    and     r2, r0, #0x18
+    cmp     r2, #0x10
+    bne     PicoVideoWrite
+    and     r0, r1, #0xff
+    b       SN76496Write    @ lsb goes to 0x11
 
 
 m_m68k_write16_ram:
@@ -1053,6 +1288,7 @@ m_m68k_write16_ram:
 
 
 m_m68k_write32_bios:
+m_m68k_write32_bcram_size:              @ 0x400000
     bx      lr
 
 
@@ -1064,7 +1300,8 @@ m_m68k_write32_prgbank:
     orr     r3, r12, #0x002200
     ldr     r3, [r2, r3]
     ldr     r12,[r2, r12]
-    tst     r3, #0x00020000             @ have bus?
+    and     r3, r3, #0x00030000
+    cmp     r3,     #0x00010000         @ have bus or in reset state?
     bxeq    lr
     and     r12,r12,#0xc0000000                @ r3 & 0xC0
     add     r2, r2, r12, lsr #12
@@ -1147,6 +1384,22 @@ m_m68k_write32_wordram1_1M_b1_unal:
     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
@@ -1154,26 +1407,13 @@ m_m68k_write32_system_io:
     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
@@ -1192,6 +1432,29 @@ m_m68k_write32_regs:
     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}
@@ -1201,11 +1464,24 @@ m_m68k_write32_misc:
     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
     tsteq   r0, #0x000e0
     bxne    lr              @ invalid
+    and     r2, r0, #0x18
+    cmp     r2, #0x10
+    moveq   r0, r1, lsr #16
+    beq     SN76496Write    @ which game is crazy enough to do that?
     stmfd   sp!,{r0,r1,lr}
     mov     r1, r1, lsr #16
     bl      PicoVideoWrite
@@ -1325,6 +1601,9 @@ m_s68k_read8_regs:
     tst     r0, #0x7e00
     movne   r0, #0
     bxne    lr
+    sub     r2, r0, #0x0e
+    cmp     r2, #(0x30-0x0e)
+    blo     m_s68k_read8_comm
     sub     r2, r0, #0x58
     cmp     r2, #0x10
     ldrlo   r2, =gfx_cd_read
@@ -1339,6 +1618,13 @@ m_s68k_read8_regs:
     and     r0, r0, #0xff
     bx      lr
 
+m_s68k_read8_comm:
+    ldr     r1, =(Pico+0x22200)
+    ldr     r1, [r1]
+    add     r1, r1, #0x110000
+    ldrb    r1, [r1, r0]
+    b       s68k_poll_detect
+
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
@@ -1405,7 +1691,10 @@ m_s68k_read16_regs:
     sub     r2, r0, #0x58
     cmp     r2, #0x10
     blo     gfx_cd_read
-    b       s68k_reg_read16
+    cmp     r0, #8
+    bne     s68k_reg_read16
+    mov     r0, #1
+    b       Read_CDC_Host
 
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1529,16 +1818,86 @@ m_s68k_read32_regs_gfx:
     bx      lr
 .endm
 
+.macro m_s68k_write8_2M_decode map_addr
+    ldr     r2, =(Pico+0x22200)
+    eor     r0, r0, #2
+    ldr     r2, [r2]
+    movs    r0, r0, lsr #1              @ +4-6 <<16
+    add     r2, r2, #\map_addr          @ map to our address
+.endm
+
+.macro m_s68k_write8_2M_decode_m0 map_addr @ mode off
+    m_s68k_write8_2M_decode \map_addr
+    ldrb    r0, [r2, r0]!
+    and     r1, r1, #0x0f
+    movcc   r1, r1, lsl #4
+    andcc   r3, r0, #0x0f
+    andcs   r3, r0, #0xf0
+    orr     r3, r3, r1
+    cmp     r0, r3                      @ avoid writing if result is same
+    strneb  r3, [r2]
+    bx      lr
+.endm
+
+.macro m_s68k_write8_2M_decode_m1 map_addr @ mode underwrite
+    ands    r1, r1, #0x0f
+    bxeq    lr
+    m_s68k_write8_2M_decode \map_addr
+    ldrb    r0, [r2, r0]!
+    movcc   r1, r1, lsl #4
+    andcc   r3, r0, #0x0f
+    andcs   r3, r0, #0xf0
+    tst     r3, r3
+    bxeq    lr
+    orr     r3, r3, r1
+    cmp     r0, r3
+    strneb  r3, [r2]
+    bx      lr
+.endm
+
+.macro m_s68k_write8_2M_decode_m2 map_addr @ mode overwrite
+    ands    r1, r1, #0x0f
+    bxeq    lr
+    m_s68k_write8_2M_decode_m0 \map_addr   @ same as in off mode
+.endm
+
+
 
 m_s68k_write8_prg:                      @ 0x000000 - 0x07ffff
+    ldr     r2, =(Pico+0x22200)
+    eor     r0, r0, #1
+    ldr     r2, [r2]
+    add     r3, r0, #0x020000           @ map to our address
+    add     r12,r2, #0x110000
+    ldr     r12,[r12]
+    and     r12,r12,#0x00ff0000         @ wp
+    cmp     r0, r12, lsr #8
+    strgeb  r1, [r2, r3]
+    bx      lr
+
+
 m_s68k_write8_wordram_2M:               @ 0x080000 - 0x0bffff
 m_s68k_write8_wordram_1M_b1:            @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
     m_s68k_write8_ram 0x020000
 
 
-m_s68k_write8_wordram_2M_decode_b0:     @ 0x080000 - 0x0bffff
-m_s68k_write8_wordram_2M_decode_b1:     @ 0x080000 - 0x0bffff
-    bx      lr @ TODO
+m_s68k_write8_2M_decode_b0_m0:          @ 0x080000 - 0x0bffff
+    m_s68k_write8_2M_decode_m0 0x080000
+
+m_s68k_write8_2M_decode_b0_m1:
+    m_s68k_write8_2M_decode_m1 0x080000
+
+m_s68k_write8_2M_decode_b0_m2:
+    m_s68k_write8_2M_decode_m2 0x080000
+
+m_s68k_write8_2M_decode_b1_m0:
+    m_s68k_write8_2M_decode_m0 0x0a0000
+
+m_s68k_write8_2M_decode_b1_m1:
+    m_s68k_write8_2M_decode_m1 0x0a0000
+
+m_s68k_write8_2M_decode_b1_m2:
+    m_s68k_write8_2M_decode_m2 0x0a0000
 
 
 m_s68k_write8_wordram_1M_b0:            @ 0x0c0000 - 0x0dffff (same as our offset :)
@@ -1557,7 +1916,7 @@ m_s68k_write8_backup:                   @ 0xfe0000 - 0xfe3fff (repeated?)
     strb    r1, [r2, r0]
     ldr     r1, =SRam
     mov     r0, #1
-    str     r0, [r1, #0x0e]             @ SRam.changed = 1
+    strb    r0, [r1, #0x0e]             @ SRam.changed = 1
     bx      lr
 
 
@@ -1614,16 +1973,93 @@ m_s68k_write8_regs:
     bx      lr
 .endm
 
+.macro m_s68k_write16_2M_decode map_addr
+    ldr     r2, =(Pico+0x22200)
+    eor     r0, r0, #2
+    ldr     r2, [r2]
+    mov     r0, r0, lsr #1              @ +4-6 <<16
+    add     r2, r2, #\map_addr          @ map to our address
+.endm
+
+.macro m_s68k_write16_2M_decode_m0 map_addr @ mode off
+    m_s68k_write16_2M_decode \map_addr
+    bic     r1, r1, #0xf0
+    orr     r1, r1, r1, lsr #4
+    strb    r1, [r2, r0]
+    bx      lr
+.endm
+
+.macro m_s68k_write16_2M_decode_m1 map_addr @ mode underwrite
+    bics    r1, r1, #0xf000
+    bicnes  r1, r1, #0x00f0
+    bxeq    lr
+    orr     r1, r1, r1, lsr #4
+    m_s68k_write16_2M_decode \map_addr
+    ldrb    r0, [r2, r0]!
+    and     r3, r1, #0x0f
+    and     r1, r1, #0xf0
+    tst     r0, #0x0f
+    orreq   r0, r0, r3
+    tst     r0, #0xf0
+    orreq   r0, r0, r1
+    strb    r0, [r2]
+    bx      lr
+.endm
+
+.macro m_s68k_write16_2M_decode_m2 map_addr @ mode overwrite
+    bics    r1, r1, #0xf000
+    bicnes  r1, r1, #0x00f0
+    bxeq    lr
+    orr     r1, r1, r1, lsr #4
+    m_s68k_write16_2M_decode \map_addr
+    ldrb    r0, [r2, r0]!
+    ands    r3, r1, #0x0f
+    andne   r0, r0, #0xf0
+    orrne   r0, r0, r3
+    ands    r1, r1, #0xf0
+    andne   r0, r0, #0x0f
+    orrne   r0, r0, r1
+    strb    r0, [r2]
+    bx      lr
+.endm
+
+
 
 m_s68k_write16_prg:                     @ 0x000000 - 0x07ffff
+    ldr     r2, =(Pico+0x22200)
+    bic     r0, r0, #1
+    ldr     r2, [r2]
+    add     r3, r0, #0x020000           @ map to our address
+    add     r12,r2, #0x110000
+    ldr     r12,[r12]
+    and     r12,r12,#0x00ff0000         @ wp
+    cmp     r0, r12, lsr #8
+    strgeh  r1, [r2, r3]
+    bx      lr
+
+
 m_s68k_write16_wordram_2M:              @ 0x080000 - 0x0bffff
 m_s68k_write16_wordram_1M_b1:           @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
     m_s68k_write16_ram 0x020000
 
 
-m_s68k_write16_wordram_2M_decode_b0:    @ 0x080000 - 0x0bffff
-m_s68k_write16_wordram_2M_decode_b1:    @ 0x080000 - 0x0bffff
-    bx      lr @ TODO
+m_s68k_write16_2M_decode_b0_m0:         @ 0x080000 - 0x0bffff
+    m_s68k_write16_2M_decode_m0 0x080000
+
+m_s68k_write16_2M_decode_b0_m1:
+    m_s68k_write16_2M_decode_m1 0x080000
+
+m_s68k_write16_2M_decode_b0_m2:
+    m_s68k_write16_2M_decode_m2 0x080000
+
+m_s68k_write16_2M_decode_b1_m0:
+    m_s68k_write16_2M_decode_m0 0x0a0000
+
+m_s68k_write16_2M_decode_b1_m1:
+    m_s68k_write16_2M_decode_m1 0x0a0000
+
+m_s68k_write16_2M_decode_b1_m2:
+    m_s68k_write16_2M_decode_m2 0x0a0000
 
 
 m_s68k_write16_wordram_1M_b0:           @ 0x0c0000 - 0x0dffff (same as our offset :)
@@ -1664,7 +2100,7 @@ m_s68k_write16_regs_spec:               @ special case
     ldr     r2, [r2]
     add     r0, r0, #0x00000f
     strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0xf] = d;
-    bxeq    lr
+    bx      lr
 
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1681,16 +2117,137 @@ m_s68k_write16_regs_spec:               @ special case
     bx      lr
 .endm
 
+.macro m_s68k_write32_2M_decode map_addr
+    ldr     r2, =(Pico+0x22200)
+    eor     r0, r0, #2
+    ldr     r2, [r2]
+    mov     r0, r0, lsr #1              @ +4-6 <<16
+    add     r2, r2, #\map_addr          @ map to our address
+.endm
+
+.macro m_s68k_write32_2M_decode_m0 map_addr @ mode off
+    m_s68k_write32_2M_decode \map_addr
+    bic     r1, r1, #0x000000f0
+    bic     r1, r1, #0x00f00000
+    orr     r1, r1, r1, lsr #4
+    mov     r3, r1, lsr #16
+    strb    r3, [r2, r0]!
+    tst     r0, #1
+    strneb  r1, [r2, #-1]
+    streqb  r1, [r2, #3]
+    bx      lr
+.endm
+
+.macro m_s68k_write32_2M_decode_m1 map_addr @ mode underwrite
+    bics    r1, r1, #0x000000f0
+    bicnes  r1, r1, #0x0000f000
+    bicnes  r1, r1, #0x00f00000
+    bicnes  r1, r1, #0xf0000000
+    bxeq    lr
+    orr     r1, r1, r1, lsr #4
+    m_s68k_write32_2M_decode \map_addr
+    ldrb    r3, [r2, r0]!
+    tst     r0, #1
+    ldrneb  r0, [r2, #-1]
+    ldreqb  r0, [r2, #3]
+    and     r12,r1, #0x0000000f
+    orr     r0, r0, r3, lsl #16
+    orrne   r0, r0, #0x80000000          @ remember addr lsb bit
+    tst     r0,     #0x0000000f
+    orreq   r0, r0, r12
+    tst     r0,     #0x000000f0
+    andeq   r12,r1, #0x000000f0
+    orreq   r0, r0, r12
+    tst     r0,     #0x000f0000
+    andeq   r12,r1, #0x000f0000
+    orreq   r0, r0, r12
+    tst     r0,     #0x00f00000
+    andeq   r12,r1, #0x00f00000
+    orreq   r0, r0, r12
+    tst     r0, #0x80000000
+    strneb  r0, [r2, #-1]
+    streqb  r0, [r2, #3]
+    mov     r0, r0, lsr #16
+    strb    r0, [r2]
+    bx      lr
+.endm
+
+.macro m_s68k_write32_2M_decode_m2 map_addr @ mode overwrite
+    bics    r1, r1, #0x000000f0
+    bicnes  r1, r1, #0x0000f000
+    bicnes  r1, r1, #0x00f00000
+    bicnes  r1, r1, #0xf0000000
+    bxeq    lr
+    orr     r1, r1, r1, lsr #4
+    m_s68k_write32_2M_decode \map_addr
+    ldrb    r3, [r2, r0]!
+    tst     r0, #1
+    ldrneb  r0, [r2, #-1]
+    ldreqb  r0, [r2, #3]
+    orrne   r1, r1, #0x80000000          @ remember addr lsb bit
+    orr     r0, r0, r3, lsl #16
+    tst     r1,     #0x0000000f
+    andeq   r12,r0, #0x0000000f
+    orreq   r1, r1, r12
+    tst     r1,     #0x000000f0
+    andeq   r12,r0, #0x000000f0
+    orreq   r1, r1, r12
+    tst     r1,     #0x000f0000
+    andeq   r12,r0, #0x000f0000
+    orreq   r1, r1, r12
+    tst     r1,     #0x00f00000
+    andeq   r12,r0, #0x00f00000
+    orreq   r1, r1, r12
+    cmp     r0, r1
+    bxeq    lr
+    tst     r1, #0x80000000
+    strneb  r1, [r2, #-1]
+    streqb  r1, [r2, #3]
+    mov     r1, r1, lsr #16
+    strb    r1, [r2]
+    bx      lr
+.endm
+
+
 
 m_s68k_write32_prg:                     @ 0x000000 - 0x07ffff
+    ldr     r2, =(Pico+0x22200)
+    bic     r0, r0, #1
+    ldr     r2, [r2]
+    add     r3, r0, #0x020000           @ map to our address
+    add     r12,r2, #0x110000
+    ldr     r12,[r12]
+    and     r12,r12,#0x00ff0000         @ wp
+    cmp     r0, r12, lsr #8
+    bxlt    lr
+    mov     r0, r1, lsr #16
+    strh    r0, [r2, r3]!
+    strh    r1, [r2, #2]
+    bx      lr
+
+
 m_s68k_write32_wordram_2M:              @ 0x080000 - 0x0bffff
 m_s68k_write32_wordram_1M_b1:           @ 0x0c0000 - 0x0dffff, maps to 0x0e0000
     m_s68k_write32_ram 0x020000
 
 
-m_s68k_write32_wordram_2M_decode_b0:    @ 0x080000 - 0x0bffff
-m_s68k_write32_wordram_2M_decode_b1:    @ 0x080000 - 0x0bffff
-    bx      lr @ TODO
+m_s68k_write32_2M_decode_b0_m0:  @ 0x080000 - 0x0bffff
+    m_s68k_write32_2M_decode_m0 0x080000
+
+m_s68k_write32_2M_decode_b0_m1:
+    m_s68k_write32_2M_decode_m1 0x080000
+
+m_s68k_write32_2M_decode_b0_m2:
+    m_s68k_write32_2M_decode_m2 0x080000
+
+m_s68k_write32_2M_decode_b1_m0:
+    m_s68k_write32_2M_decode_m0 0x0a0000
+
+m_s68k_write32_2M_decode_b1_m1:
+    m_s68k_write32_2M_decode_m1 0x0a0000
+
+m_s68k_write32_2M_decode_b1_m2:
+    m_s68k_write32_2M_decode_m2 0x0a0000
 
 
 m_s68k_write32_wordram_1M_b0:           @ 0x0c0000 - 0x0dffff (same as our offset :)
@@ -1737,12 +2294,11 @@ m_s68k_write32_pcm_ram:
 
 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
 
 
@@ -1751,11 +2307,16 @@ m_s68k_write32_regs:
     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
@@ -1775,11 +2336,34 @@ m_s68k_write32_regs:
     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
+
+