From: notaz Date: Fri, 11 Sep 2009 11:29:19 +0000 (+0000) Subject: 32x: initial code (security code passes) X-Git-Tag: v1.85~278 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=picodrive.git;a=commitdiff_plain;h=be2c420828ab3c36ef652584fbdef0e0597c7028 32x: initial code (security code passes) git-svn-id: file:///home/notaz/opt/svn/PicoDrive@772 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/pico/32x/32x.c b/pico/32x/32x.c new file mode 100644 index 0000000..dc881a9 --- /dev/null +++ b/pico/32x/32x.c @@ -0,0 +1,31 @@ +#include "../pico_int.h" + +struct Pico32x Pico32x; + +void Pico32xStartup(void) +{ + elprintf(EL_STATUS|EL_32X, "32X startup"); + + PicoAHW |= PAHW_32X; + PicoMemSetup32x(); + + // probably should only done on power +// memset(&Pico32x, 0, sizeof(Pico32x)); + + if (!Pico.m.pal) + Pico32x.vdp_regs[0] |= 0x8000; + + // prefill checksum + Pico32x.regs[0x28/2] = *(unsigned short *)(Pico.rom + 0x18e); +} + +void Pico32xInit(void) +{ + // XXX: mv + Pico32x.regs[0] = 0x0082; +} + +void PicoReset32x(void) +{ +} + diff --git a/pico/32x/memory.c b/pico/32x/memory.c new file mode 100644 index 0000000..324c789 --- /dev/null +++ b/pico/32x/memory.c @@ -0,0 +1,252 @@ +#include "../pico_int.h" +#include "../memory.h" + +static const char str_mars[] = "MARS"; + +struct Pico32xMem { + u8 sdram[0x40000]; + u8 dram[0x40000]; // AKA fb + u8 m68k_rom[M68K_BANK_SIZE]; // 0x100 +}; + +static struct Pico32xMem *Pico32xMem; + +static u32 p32x_reg_read16(u32 a) +{ + a &= 0x3e; + + return Pico32x.regs[a / 2]; +} + +static void p32x_reg_write16(u32 a, u32 d) +{ + a &= 0x3e; + + if (a == 0 && !(Pico32x.regs[0] & 1)) { + Pico32x.regs[0] |= 1; + Pico32xStartup(); + return; + } +} + +static void p32x_reg_write8(u32 a, u32 d) +{ + a &= 0x3f; + + if (a == 1 && !(Pico32x.regs[0] & 1)) { + Pico32x.regs[0] |= 1; + Pico32xStartup(); + return; + } +} + +// VDP regs +static u32 p32x_vdp_read16(u32 a) +{ + a &= 0x0e; + + return Pico32x.vdp_regs[a / 2]; +} + +static void p32x_vdp_write16(u32 a, u32 d) +{ + a &= 0x0e; + + switch (a) { + case 0x0a: + Pico32x.pending_fb = d & 1; + if (Pico.video.status & 8) { + Pico32x.vdp_regs[0x0a/2] &= ~1; + Pico32x.vdp_regs[0x0a/2] |= d & 1; + } + break; + } +} + +static void p32x_vdp_write8(u32 a, u32 d) +{ + a &= 0x0f; + + switch (a) { + case 0x0b: + Pico32x.pending_fb = d & 1; + if (Pico.video.status & 8) { + Pico32x.vdp_regs[0x0a/2] &= ~1; + Pico32x.vdp_regs[0x0a/2] |= d & 1; + } + break; + } +} + +// default 32x handlers +u32 PicoRead8_32x(u32 a) +{ + u32 d = 0; + if ((a & 0xffc0) == 0x5100) { // a15100 + d = p32x_reg_read16(a); + goto out_16to8; + } + + if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { + d = p32x_vdp_read16(a); + goto out_16to8; + } + + if ((a & 0xfffc) == 0x30ec) { // a130ec + d = str_mars[a & 3]; + goto out; + } + + elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); + return d; + +out_16to8: + if (a & 1) + d &= 0xff; + else + d >>= 8; + +out: + elprintf(EL_32X, "m68k 32x r8 [%06x] %02x @%06x", a, d, SekPc); + return d; +} + +u32 PicoRead16_32x(u32 a) +{ + u32 d = 0; + if ((a & 0xffc0) == 0x5100) { // a15100 + d = p32x_reg_read16(a); + goto out; + } + + if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180 + d = p32x_vdp_read16(a); + goto out; + } + + if ((a & 0xfffc) == 0x30ec) { // a130ec + d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S'; + goto out; + } + + elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc); + return d; + +out: + elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc); + return d; +} + +void PicoWrite8_32x(u32 a, u32 d) +{ + if ((a & 0xfc00) == 0x5000) + elprintf(EL_32X, "m68k 32x w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); + + if ((a & 0xffc0) == 0x5100) { // a15100 + p32x_reg_write8(a, d); + return; + } + + if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180 + p32x_vdp_write8(a, d); + return; + } + + elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); +} + +void PicoWrite16_32x(u32 a, u32 d) +{ + if ((a & 0xfc00) == 0x5000) + elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); + + if ((a & 0xffc0) == 0x5100) { // a15100 + p32x_reg_write16(a, d); + return; + } + + if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180 + p32x_vdp_write16(a, d); + return; + } + + elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); +} + +// hint vector is writeable +static void PicoWrite8_hint(u32 a, u32 d) +{ + if ((a & 0xfffc) == 0x0070) { + Pico32xMem->m68k_rom[a ^ 1] = d; + return; + } + + elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); +} + +static void PicoWrite16_hint(u32 a, u32 d) +{ + if ((a & 0xfffc) == 0x0070) { + ((u16 *)Pico32xMem->m68k_rom)[a/2] = d; + return; + } + + elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); +} + +#define HWSWAP(x) (((x) << 16) | ((x) >> 16)) +void PicoMemSetup32x(void) +{ + unsigned short *ps; + unsigned int *pl; + unsigned int rs, rs1; + int i; + + Pico32xMem = calloc(1, sizeof(*Pico32xMem)); + if (Pico32xMem == NULL) { + elprintf(EL_STATUS, "OOM"); + return; + } + + // generate 68k ROM + ps = (unsigned short *)Pico32xMem->m68k_rom; + pl = (unsigned int *)Pico32xMem->m68k_rom; + for (i = 1; i < 0xc0/4; i++) + pl[i] = HWSWAP(0x880200 + i * 6); + + // fill with nops + for (i = 0xc0/2; i < 0x100/2; i++) + ps[i] = 0x4e71; + + ps[0xc0/2] = 0x46fc; + ps[0xc2/2] = 0x2700; // move #0x2700,sr + ps[0xfe/2] = 0x60fe; // jump to self + + // fill remaining mem with ROM + memcpy(Pico32xMem->m68k_rom + 0x100, Pico.rom + 0x100, M68K_BANK_SIZE - 0x100); + + // cartridge area becomes unmapped + // XXX: we take the easy way and don't unmap ROM, + // so that we can avoid handling the RV bit. + // m68k_map_unmap(0x000000, 0x3fffff); + + // MD ROM area + cpu68k_map_set(m68k_read8_map, 0x000000, M68K_BANK_SIZE - 1, Pico32xMem->m68k_rom, 0); + cpu68k_map_set(m68k_read16_map, 0x000000, M68K_BANK_SIZE - 1, Pico32xMem->m68k_rom, 0); + cpu68k_map_set(m68k_write8_map, 0x000000, M68K_BANK_SIZE - 1, PicoWrite8_hint, 1); // TODO verify + cpu68k_map_set(m68k_write16_map, 0x000000, M68K_BANK_SIZE - 1, PicoWrite16_hint, 1); + + // 32X ROM (unbanked, XXX: consider mirroring?) + rs1 = rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK; + if (rs1 > 0x80000) + rs1 = 0x80000; + cpu68k_map_set(m68k_read8_map, 0x880000, 0x880000 + rs1 - 1, Pico.rom, 0); + cpu68k_map_set(m68k_read16_map, 0x880000, 0x880000 + rs1 - 1, Pico.rom, 0); + + // 32X ROM (banked) + if (rs > 0x100000) + rs = 0x100000; + cpu68k_map_set(m68k_read8_map, 0x900000, 0x900000 + rs - 1, Pico.rom, 0); + cpu68k_map_set(m68k_read16_map, 0x900000, 0x900000 + rs - 1, Pico.rom, 0); +} + diff --git a/pico/memory.c b/pico/memory.c index da73961..d2dced3 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -501,6 +501,11 @@ u32 PicoRead8_io(u32 a) goto end; } + if (!(PicoOpt & POPT_DIS_32X)) { + d = PicoRead8_32x(a); + goto end; + } + d = m68k_unmapped_read8(a); end: return d; @@ -529,6 +534,11 @@ u32 PicoRead16_io(u32 a) goto end; } + if (!(PicoOpt & POPT_DIS_32X)) { + d = PicoRead16_32x(a); + goto end; + } + d = m68k_unmapped_read16(a); end: return d; @@ -554,6 +564,11 @@ void PicoWrite8_io(u32 a, u32 d) Pico.m.sram_reg |= (u8)(d & 3); return; } + if (!(PicoOpt & POPT_DIS_32X)) { + PicoWrite8_32x(a, d); + return; + } + m68k_unmapped_write8(a, d); } @@ -577,6 +592,10 @@ void PicoWrite16_io(u32 a, u32 d) Pico.m.sram_reg |= (u8)(d & 3); return; } + if (!(PicoOpt & POPT_DIS_32X)) { + PicoWrite16_32x(a, d); + return; + } m68k_unmapped_write16(a, d); } diff --git a/pico/pico.c b/pico/pico.c index f2da10b..aa2be38 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -40,6 +40,7 @@ void PicoInit(void) PicoInitMCD(); PicoSVPInit(); + Pico32xInit(); } // to be called once on emu exit @@ -187,6 +188,11 @@ int PicoReset(void) if (!(PicoOpt & POPT_DIS_IDLE_DET)) SekInitIdleDet(); + if (!(PicoOpt & POPT_DIS_32X)) { + PicoReset32x(); + return 0; + } + // reset sram state; enable sram access by default if it doesn't overlap with ROM Pico.m.sram_reg = 0; if ((SRam.flags & SRF_EEPROM) || Pico.romsize <= SRam.start) diff --git a/pico/pico.h b/pico/pico.h index 45e948f..8b7d032 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -55,7 +55,9 @@ extern void emu_video_mode_change(int start_line, int line_count, int is_32cols) #define POPT_EN_SVP_DRC (1<<17) #define POPT_DIS_SPRITE_LIM (1<<18) #define POPT_DIS_IDLE_DET (1<<19) +#define POPT_DIS_32X (1<<20) extern int PicoOpt; // bitfield + #define PAHW_MCD (1<<0) #define PAHW_32X (1<<1) #define PAHW_SVP (1<<2) diff --git a/pico/pico_int.h b/pico/pico_int.h index cb12bc1..85f2506 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -257,15 +257,15 @@ struct PicoMisc unsigned char pal; // 08 1=PAL 0=NTSC unsigned char sram_reg; // 09 SRAM reg. See SRR_* below unsigned short z80_bank68k; // 0a - unsigned short z80_lastaddr; // this is for Z80 faking - unsigned char pad0; + unsigned short pad0; + unsigned char pad1; unsigned char z80_reset; // z80 reset held unsigned char padDelay[2]; // 10 gamepad phase time outs, so we count a delay unsigned short eeprom_addr; // EEPROM address register unsigned char eeprom_cycle; // EEPROM cycle number unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs unsigned char eeprom_status; - unsigned char pad1; + unsigned char pad2; unsigned short dma_xfers; // 18 unsigned char eeprom_wb[2]; // EEPROM latch/write buffer unsigned int frame_count; // 1c for movies and idle det @@ -385,8 +385,17 @@ typedef struct Rot_Comp rot_comp; } mcd_state; +// XXX: this will need to be reworked for cart+cd support. #define Pico_mcd ((mcd_state *)Pico.rom) +// 32X +struct Pico32x +{ + unsigned short regs[0x20]; + unsigned short vdp_regs[0x10]; + unsigned char pending_fb; + unsigned char pad[3]; +}; // area.c PICO_INTERNAL void PicoAreaPackCpu(unsigned char *cpu, int is_sub); @@ -576,6 +585,19 @@ void PicoMemSetupMS(void); void PicoFrameMS(void); void PicoFrameDrawOnlyMS(void); +// 32x/32x.c +extern struct Pico32x Pico32x; +void Pico32xInit(void); +void Pico32xStartup(void); +void PicoReset32x(void); + +// 32x/memory.c +unsigned int PicoRead8_32x(unsigned int a); +unsigned int PicoRead16_32x(unsigned int a); +void PicoWrite8_32x(unsigned int a, unsigned int d); +void PicoWrite16_32x(unsigned int a, unsigned int d); +void PicoMemSetup32x(void); + /* avoid dependency on newer glibc */ static __inline int isspace_(int c) { @@ -606,6 +628,7 @@ static __inline int isspace_(int c) #define EL_IDLE 0x00010000 /* idle loop det. */ #define EL_CDREGS 0x00020000 /* MCD: register access */ #define EL_CDREG3 0x00040000 /* MCD: register 3 only */ +#define EL_32X 0x00080000 #define EL_STATUS 0x40000000 /* status messages */ #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */ diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 3ec56b9..e6a94a2 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -39,6 +39,8 @@ OBJS += pico/area.o pico/cart.o pico/memory.o pico/pico.o pico/sek.o \ OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \ pico/cd/area.o pico/cd/misc.o pico/cd/pcm.o pico/cd/buffering.o +# Pico - 32X +OBJS += pico/32x/32x.o pico/32x/memory.o # Pico - Pico OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o # Pico - sound @@ -81,7 +83,7 @@ CFLAGS += $(addprefix -D,$(DEFINES)) vpath %.c = ../.. DIRS = platform platform/gp2x platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \ - zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80 + pico/32x zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80 all: mkdirs PicoDrive clean: tidy diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index fc2e118..152d1a8 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -26,7 +26,7 @@ #define SIMPLE_WRITE_SOUND 0 #define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo -#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) +#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE|EL_32X)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) // EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK) //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)