memhandlers slightly improved
[picodrive.git] / Pico / cd / Memory.s
index d10f1a5..7b19e61 100644 (file)
@@ -1,8 +1,7 @@
 @ 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
@@ -135,6 +137,10 @@ m_s68k_decode_write_table:
 .extern s68k_reg_write8
 .extern s68k_poll_adclk
 .extern PicoCpuS68k
+.extern s68k_poll_detect
+.extern SN76496Write
+.extern m_m68k_read8_misc
+.extern m_m68k_write8_misc
 
 
 @ r0=reg3, r1-r3=temp
@@ -362,6 +368,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]
+.else
+    strb    r1, [r2, #0x18]
+.endif
+    bx      lr
+.endm
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
@@ -388,7 +413,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
@@ -445,11 +471,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
@@ -535,7 +590,7 @@ m_m68k_read8_hi:
     ldrb    r0, [r1, r0]
     bx      lr
 
-
+/*
 m_m68k_read8_misc:
     bic     r2, r0, #0x00ff
     bic     r2, r2, #0xbf00
@@ -551,7 +606,7 @@ m_m68k_read8_misc:
     tst     r1, #1
     moveq   r0, r0, lsr #8
     bx      lr
-
+*/
 
 m_m68k_read8_vdp:
     tst     r0, #0x70000
@@ -594,7 +649,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
@@ -652,6 +708,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
@@ -764,7 +839,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
@@ -846,6 +922,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
@@ -911,6 +1014,7 @@ m_m68k_read32_ram:
 
 m_write_null:
 m_m68k_write8_bios:
+m_m68k_write8_bcram_size:               @ 0x400000
     bx      lr
 
 
@@ -922,7 +1026,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
@@ -980,19 +1085,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
@@ -1010,6 +1147,7 @@ m_m68k_write8_ram:
 
 
 m_m68k_write16_bios:
+m_m68k_write16_bcram_size:              @ 0x400000
     bx      lr
 
 
@@ -1021,7 +1159,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
@@ -1080,6 +1219,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
@@ -1087,7 +1234,7 @@ 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
@@ -1123,7 +1270,11 @@ m_m68k_write16_vdp:
     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:
@@ -1138,6 +1289,7 @@ m_m68k_write16_ram:
 
 
 m_m68k_write32_bios:
+m_m68k_write32_bcram_size:              @ 0x400000
     bx      lr
 
 
@@ -1149,7 +1301,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
@@ -1232,6 +1385,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
@@ -1239,26 +1408,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
@@ -1277,6 +1433,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, =PicoCpuS68k          @ 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}
@@ -1286,11 +1465,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
@@ -1410,6 +1602,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
@@ -1424,6 +1619,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
+
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
@@ -1663,6 +1865,18 @@ m_s68k_read32_regs_gfx:
 
 
 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
@@ -1813,6 +2027,18 @@ m_s68k_write8_regs:
 
 
 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
@@ -1986,6 +2212,21 @@ m_s68k_write16_regs_spec:               @ special case
 
 
 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
@@ -2054,12 +2295,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
 
 
@@ -2068,11 +2308,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
@@ -2092,11 +2337,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
+
+