@* @* Memory I/O handlers for Sega/Mega CD emulation @* (C) notaz, 2007-2009 @* @* This work is licensed under the terms of MAME license. @* See COPYING file in the top-level directory. @* #include "../pico_int_o32.h" .equiv PCM_STEP_SHIFT, 11 .text .align 2 .global PicoRead8_mcd_io .global PicoRead16_mcd_io .global PicoWrite8_mcd_io .global PicoWrite16_mcd_io .global PicoReadS68k8_pr .global PicoReadS68k16_pr .global PicoWriteS68k8_pr .global PicoWriteS68k16_pr .global PicoReadM68k8_cell0 .global PicoReadM68k8_cell1 .global PicoReadM68k16_cell0 .global PicoReadM68k16_cell1 .global PicoWriteM68k8_cell0 .global PicoWriteM68k8_cell1 .global PicoWriteM68k16_cell0 .global PicoWriteM68k16_cell1 .global PicoReadS68k8_dec0 .global PicoReadS68k8_dec1 .global PicoReadS68k16_dec0 .global PicoReadS68k16_dec1 .global PicoWriteS68k8_dec_m0b0 .global PicoWriteS68k8_dec_m1b0 .global PicoWriteS68k8_dec_m2b0 .global PicoWriteS68k8_dec_m0b1 .global PicoWriteS68k8_dec_m1b1 .global PicoWriteS68k8_dec_m2b1 .global PicoWriteS68k16_dec_m0b0 .global PicoWriteS68k16_dec_m1b0 .global PicoWriteS68k16_dec_m2b0 .global PicoWriteS68k16_dec_m0b1 .global PicoWriteS68k16_dec_m1b1 .global PicoWriteS68k16_dec_m2b1 @ externs, just for reference .extern Pico .extern cdc_host_r .extern m68k_reg_write8 .extern s68k_reg_read16 .extern s68k_reg_write8 .extern s68k_reg_write16 .extern s68k_poll_detect .extern pcd_pcm_write .extern pcd_pcm_read .extern PicoRead8_io .extern PicoRead16_io .extern PicoWrite8_io .extern PicoWrite16_io .extern m68k_comm_check @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ utilities @ r0=addr[in,out], r1,r2=tmp .macro cell_map ands r1, r0, #0x01c000 ldrne pc, [pc, r1, lsr #12] beq 0f @ most common? .long 0f .long 0f .long 0f .long 0f .long 1f .long 1f .long 2f .long 3f 1: @ x16 cells and r1, r0, #0x7e00 @ col and r2, r0, #0x01fc @ row orr r2, r2, #0x0400 orr r1, r2, r1, ror #13 b 9f 2: @ x8 cells and r1, r0, #0x3f00 @ col and r2, r0, #0x00fc @ row orr r2, r2, #0x0600 orr r1, r2, r1, ror #12 b 9f 3: @ x4 cells and r1, r0, #0x1f80 @ col and r2, r0, #0x007c @ row orr r1, r2, r1, ror #11 and r2, r0,#0x1e000 orr r1, r1, r2, lsr #6 b 9f 0: @ x32 cells and r1, r0, #0xfc00 @ col and r2, r0, #0x03fc @ row orr r1, r2, r1, ror #14 9: and r0, r0, #3 orr r0, r0, r1, ror #26 @ rol 4+2 .endm @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_read_null: mov r0, #0 bx lr PicoReadM68k8_cell0: @ 0x220000 - 0x23ffff, cell arranged mov r3, #0x0c0000 b 0f PicoReadM68k8_cell1: @ 0x220000 - 0x23ffff, cell arranged mov r3, #0x0e0000 0: cell_map ldr r1, =Pico add r0, r0, r3 ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd (used everywhere) eor r0, r0, #1 ldrb r0, [r1, r0] bx lr PicoRead8_mcd_io: and r1, r0, #0xff00 cmp r1, #0x2000 @ a120xx? bne PicoRead8_io ldr r1, =Pico and r0, r0, #0x3f ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd cmp r0, #0x0e ldrlt pc, [pc, r0, lsl #2] b m_m68k_read8_hi .long m_m68k_read8_r00 .long m_m68k_read8_r01 .long m_m68k_read8_r02 .long m_m68k_read8_r03 .long m_m68k_read8_r04 .long m_read_null @ unused bits .long m_m68k_read8_r06 .long m_m68k_read8_r07 .long m_m68k_read8_r08 .long m_m68k_read8_r09 .long m_read_null @ reserved .long m_read_null .long m_m68k_read8_r0c .long m_m68k_read8_r0d m_m68k_read8_r00: add r1, r1, #0x110000 ldr r0, [r1, #0x30] and r0, r0, #0x04000000 @ we need irq2 mask state mov r0, r0, lsr #19 bx lr m_m68k_read8_r01: add r1, r1, #0x110000 add r1, r1, #0x002200 ldrb r0, [r1, #2] @ Pico_mcd->m.busreq bx lr m_m68k_read8_r02: add r1, r1, #0x110000 ldrb r0, [r1, #2] bx lr m_m68k_read8_r03: add r1, r1, #0x110000 push {r1, lr} bl m68k_comm_check pop {r1, lr} ldrb r0, [r1, #3] and r0, r0, #0xc7 bx lr m_m68k_read8_r04: add r1, r1, #0x110000 ldrb r0, [r1, #4] bx lr m_m68k_read8_r06: ldrb r0, [r1, #0x73] @ IRQ vector bx lr m_m68k_read8_r07: ldrb r0, [r1, #0x72] bx lr m_m68k_read8_r08: mov r0, #0 bl cdc_host_r mov r0, r0, lsr #8 bx lr m_m68k_read8_r09: mov r0, #0 b cdc_host_r m_m68k_read8_r0c: add r1, r1, #0x110000 add r1, r1, #0x002200 ldr r0, [r1, #0x14] @ Pico_mcd->m.timer_stopwatch mov r0, r0, lsr #24 bx lr m_m68k_read8_r0d: add r1, r1, #0x110000 add r1, r1, #0x002200 ldr r0, [r1, #0x14] mov r0, r0, lsr #16 bx lr m_m68k_read8_hi: cmp r0, #0x30 add r1, r1, #0x110000 movge r0, #0 bxge lr add r1, r0 push {r1, lr} bl m68k_comm_check pop {r1, lr} ldrb r0, [r1] bx lr @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PicoReadM68k16_cell0: @ 0x220000 - 0x23ffff, cell arranged mov r3, #0x0c0000 b 0f PicoReadM68k16_cell1: @ 0x220000 - 0x23ffff, cell arranged mov r3, #0x0e0000 0: cell_map ldr r1, =Pico add r0, r0, r3 ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd bic r0, r0, #1 ldrh r0, [r1, r0] bx lr PicoRead16_mcd_io: and r1, r0, #0xff00 cmp r1, #0x2000 @ a120xx bne PicoRead16_io m_m68k_read16_m68k_regs: ldr r1, =Pico and r0, r0, #0x3e ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd cmp r0, #0x0e ldrlt pc, [pc, r0, lsl #1] b m_m68k_read16_hi .long m_m68k_read16_r00 .long m_m68k_read16_r02 .long m_m68k_read16_r04 .long m_m68k_read16_r06 .long m_m68k_read16_r08 .long m_read_null @ reserved .long m_m68k_read16_r0c m_m68k_read16_r00: add r1, r1, #0x110000 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 orr r0, r1, r0, lsr #11 bx lr m_m68k_read16_r02: add r1, r1, #0x110000 push {r1, lr} bl m68k_comm_check pop {r1, lr} ldrb r2, [r1, #3] ldrb r0, [r1, #2] and r2, r2, #0xc7 orr r0, r2, r0, lsl #8 bx lr m_m68k_read16_r04: add r1, r1, #0x110000 ldrb r0, [r1, #4] mov r0, r0, lsl #8 bx lr m_m68k_read16_r06: ldrh r0, [r1, #0x72] @ IRQ vector bx lr m_m68k_read16_r08: mov r0, #0 b cdc_host_r m_m68k_read16_r0c: add r1, r1, #0x110000 add r1, r1, #0x002200 ldr r0, [r1, #0x14] mov r0, r0, lsr #16 bx lr m_m68k_read16_hi: cmp r0, #0x30 add r1, r1, #0x110000 movge r0, #0 bxge lr add r1, r0, r1 push {r1, lr} bl m68k_comm_check pop {r0, lr} ldrh r0, [r0] mov r1, r0, lsr #8 and r0, r0, #0xff orr r0, r1, r0, lsl #8 bx lr @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PicoWriteM68k8_cell0: @ 0x220000 - 0x23ffff, cell arranged mov r12,#0x0c0000 b 0f PicoWriteM68k8_cell1: @ 0x220000 - 0x23ffff, cell arranged mov r12,#0x0e0000 0: mov r3, r1 cell_map ldr r2, =Pico add r0, r0, r12 ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd ldr r2, [r2] eor r0, r0, #1 strb r3, [r2, r0] bx lr PicoWrite8_mcd_io: and r2, r0, #0xff00 cmp r2, #0x2000 @ a120xx? beq m68k_reg_write8 b PicoWrite8_io @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PicoWriteM68k16_cell0: @ 0x220000 - 0x23ffff, cell arranged mov r12, #0x0c0000 b 0f PicoWriteM68k16_cell1: @ 0x220000 - 0x23ffff, cell arranged mov r12, #0x0e0000 0: mov r3, r1 cell_map ldr r1, =Pico add r0, r0, r12 ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd bic r0, r0, #1 strh r3, [r1, r0] bx lr PicoWrite16_mcd_io: and r2, r0, #0xff00 cmp r2, #0x2000 @ a120xx? bne PicoWrite16_io 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} mov r1, r1, lsr #8 bl m68k_reg_write8 ldmfd sp!,{r0,r1,lr} b m68k_reg_write8 m_m68k_write16_regs_spec: @ special case mov r1, r1, lsr #8 b m68k_reg_write8 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Sub 68k @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PicoReadS68k8_dec0: @ 0x080000 - 0x0bffff mov r3, #0x080000 @ + ^ / 2 b 0f PicoReadS68k8_dec1: mov r3, #0x0a0000 @ + ^ / 2 0: ldr r2, =Pico eor r0, r0, #2 ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd movs r0, r0, lsr #1 @ +4-6 <<16 add r2, r2, r3 @ map to our address ldrb r0, [r2, r0] movcc r0, r0, lsr #4 andcs r0, r0, #0xf bx lr PicoReadS68k8_pr: and r2, r0, #0xfe00 cmp r2, #0x8000 bne m_s68k_read8_pcm m_s68k_read8_regs: bic r0, r0, #0xff0000 bic r0, r0, #0x008000 sub r2, r0, #0x0e cmp r2, #(0x30-0x0e) blo m_s68k_read8_comm stmfd sp!,{r0,lr} bic r0, r0, #1 bl s68k_reg_read16 ldmfd sp!,{r1,lr} tst r1, #1 moveq r0, r0, lsr #8 and r0, r0, #0xff bx lr m_s68k_read8_comm: ldr r1, =Pico ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd add r1, r1, #0x110000 ldrb r1, [r1, r0] bic r0, r0, #1 b s68k_poll_detect m_s68k_read8_pcm: tst r0, #0x8000 bne m_read_null @ must not trash r3 and r12 ldr r1, =Pico bic r0, r0, #0xff0000 ldr r1, [r1, #OFS_Pico_rom] @ Pico.mcd mov r2, #0x110000 orr r2, r2, #0x002200 cmp r0, #0x2000 bge m_s68k_read8_pcm_ram cmp r0, #0x20 movge r0, r0, lsr #1 bge pcd_pcm_read mov r0, #0 bx lr m_s68k_read8_pcm_ram: orr r2, r2, #0x40 ldr r2, [r1, r2] add r1, r1, #0x100000 @ pcm_ram and r2, r2, #0x0f000000 @ bank add r1, r1, r2, lsr #12 bic r0, r0, #0x00e000 mov r0, r0, lsr #1 ldrb r0, [r1, r0] bx lr @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PicoReadS68k16_dec0: @ 0x080000 - 0x0bffff mov r3, #0x080000 @ + ^ / 2 b 0f PicoReadS68k16_dec1: mov r3, #0x0a0000 @ + ^ / 2 0: ldr r2, =Pico eor r0, r0, #2 ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd mov r0, r0, lsr #1 @ +4-6 <<16 add r2, r2, r3 @ map to our address ldrb r0, [r2, r0] orr r0, r0, r0, lsl #4 bic r0, r0, #0xf0 bx lr PicoReadS68k16_pr: and r2, r0, #0xfe00 cmp r2, #0x8000 @ pcm is on 8-bit bus, would this be same as byte access? bne m_s68k_read8_pcm m_s68k_read16_regs: bic r0, r0, #0xff0000 bic r0, r0, #0x008000 bic r0, r0, #0x000001 cmp r0, #8 bne s68k_reg_read16 mov r0, #1 b cdc_host_r @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .macro m_s68k_write8_2M_decode ldr r2, =Pico eor r0, r0, #2 ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd movs r0, r0, lsr #1 @ +4-6 <<16 add r2, r2, r3 @ map to our address .endm PicoWriteS68k8_dec_m2b0: @ overwrite ands r1, r1, #0x0f bxeq lr PicoWriteS68k8_dec_m0b0: mov r3, #0x080000 b 0f PicoWriteS68k8_dec_m2b1: @ overwrite ands r1, r1, #0x0f bxeq lr PicoWriteS68k8_dec_m0b1: mov r3, #0x0a0000 0: m_s68k_write8_2M_decode 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 strneb r3, [r2] bx lr PicoWriteS68k8_dec_m1b0: @ underwrite mov r3, #0x080000 b 0f PicoWriteS68k8_dec_m1b1: mov r3, #0x0a0000 0: ands r1, r1, #0x0f bxeq lr m_s68k_write8_2M_decode ldrb r0, [r2, r0]! movcc r1, r1, lsl #4 andcc r3, r0, #0x0f andcs r3, r0, #0xf0 teq r3, r0 bxne lr orr r3, r3, r1 strneb r3, [r2] bx lr PicoWriteS68k8_pr: and r2, r0, #0xfe00 cmp r2, #0x8000 bne m_s68k_write8_pcm m_s68k_write8_regs: bic r0, r0, #0xff0000 bic r0, r0, #0x008000 tst r0, #0x7e00 movne r0, #0 bxne lr sub r2, r0, #0x59 cmp r2, #0x0f bhs s68k_reg_write8 bic r0, r0, #1 orr r1, r1, r1, lsl #8 b s68k_reg_write16 m_s68k_write8_pcm: tst r0, #0x8000 bxne lr bic r0, r0, #0xff0000 cmp r0, #0x12 movlt r0, r0, lsr #1 blt pcd_pcm_write cmp r0, #0x2000 bxlt lr m_s68k_write8_pcm_ram: ldr r3, =Pico bic r0, r0, #0x00e000 ldr r3, [r3, #OFS_Pico_rom] @ Pico.mcd mov r0, r0, lsr #1 add r2, r3, #0x110000 add r2, r2, #0x002200 add r2, r2, #0x000040 ldr r2, [r2] add r3, r3, #0x100000 @ pcm_ram and r2, r2, #0x0f000000 @ bank add r3, r3, r2, lsr #12 strb r1, [r3, r0] bx lr @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .macro m_s68k_write16_2M_decode ldr r2, =Pico eor r0, r0, #2 ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd mov r0, r0, lsr #1 @ +4-6 <<16 add r2, r2, r3 @ map to our address .endm PicoWriteS68k16_dec_m0b0: mov r3, #0x080000 b 0f PicoWriteS68k16_dec_m0b1: mov r3, #0x0a0000 0: m_s68k_write16_2M_decode bic r1, r1, #0xf0 orr r1, r1, r1, lsr #4 strb r1, [r2, r0] bx lr PicoWriteS68k16_dec_m1b0: @ underwrite mov r3, #0x080000 b 0f PicoWriteS68k16_dec_m1b1: mov r3, #0x0a0000 0: bics r1, r1, #0xf000 bicnes r1, r1, #0x00f0 bxeq lr orr r1, r1, r1, lsr #4 m_s68k_write16_2M_decode 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 PicoWriteS68k16_dec_m2b0: @ overwrite mov r3, #0x080000 b 0f PicoWriteS68k16_dec_m2b1: mov r3, #0x0a0000 0: bics r1, r1, #0xf000 bicnes r1, r1, #0x00f0 bxeq lr orr r1, r1, r1, lsr #4 m_s68k_write16_2M_decode 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 PicoWriteS68k16_pr: and r2, r0, #0xfe00 cmp r2, #0x8000 bne m_s68k_write8_pcm m_s68k_write16_regs: bic r0, r0, #0xff0000 bic r0, r0, #0x008000 bic r0, r0, #1 tst r0, #0x7e00 movne r0, #0 bxne lr cmp r0, #0x0e bne s68k_reg_write16 m_s68k_write16_regs_spec: @ special case ldr r2, =Pico mov r0, #0x110000 ldr r2, [r2, #OFS_Pico_rom] @ Pico.mcd add r0, r0, #0x00000f strb r1, [r2, r0] @ if (a == 0xe) s68k_regs[0xf] = d; bx lr .pool @ vim:filetype=armasm