From 974fdb5bfda8ed006661031e22c920828ddb60dc Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 12 Sep 2009 21:54:46 +0000 Subject: [PATCH] 32x: packed pixel mode (works over 68k) git-svn-id: file:///home/notaz/opt/svn/PicoDrive@773 be3aeb3a-fb24-0410-a615-afba39da0efa --- pico/32x/32x.c | 62 +++++++++++++++--- pico/32x/draw.c | 58 +++++++++++++++++ pico/32x/memory.c | 140 ++++++++++++++++++++++++++++++---------- pico/draw.c | 41 ++++++------ pico/memory.c | 2 - pico/pico.c | 9 +++ pico/pico.h | 3 + pico/pico_cmn.c | 5 +- pico/pico_int.h | 33 +++++++++- platform/common/emu.c | 52 ++++++++++----- platform/common/menu.c | 2 +- platform/common/plat.h | 2 +- platform/gp2x/Makefile | 2 + platform/gp2x/emu.c | 8 ++- platform/linux/Makefile | 2 +- 15 files changed, 330 insertions(+), 91 deletions(-) create mode 100644 pico/32x/draw.c diff --git a/pico/32x/32x.c b/pico/32x/32x.c index dc881a9..7a122cb 100644 --- a/pico/32x/32x.c +++ b/pico/32x/32x.c @@ -1,4 +1,5 @@ #include "../pico_int.h" +#include "../sound/ym2612.h" struct Pico32x Pico32x; @@ -9,23 +10,68 @@ void Pico32xStartup(void) PicoAHW |= PAHW_32X; PicoMemSetup32x(); - // probably should only done on power -// memset(&Pico32x, 0, sizeof(Pico32x)); - if (!Pico.m.pal) - Pico32x.vdp_regs[0] |= 0x8000; + Pico32x.vdp_regs[0] |= P32XV_nPAL; - // prefill checksum - Pico32x.regs[0x28/2] = *(unsigned short *)(Pico.rom + 0x18e); + emu_32x_startup(); } void Pico32xInit(void) { - // XXX: mv - Pico32x.regs[0] = 0x0082; +} + +void PicoPower32x(void) +{ + memset(&Pico32x, 0, sizeof(Pico32x)); + Pico32x.regs[0] = 0x0082; // SH2 reset? + Pico32x.vdp_regs[0x0a/2] = P32XV_VBLK|P32XV_HBLK|P32XV_PEN; } void PicoReset32x(void) { } +static void p32x_start_blank(void) +{ + // enter vblank + Pico32x.vdp_regs[0x0a/2] |= P32XV_VBLK|P32XV_PEN; + + // swap waits until vblank + if ((Pico32x.vdp_regs[0x0a/2] ^ Pico32x.pending_fb) & P32XV_FS) { + Pico32x.vdp_regs[0x0a/2] &= ~P32XV_FS; + Pico32x.vdp_regs[0x0a/2] |= Pico32x.pending_fb; + Pico32xSwapDRAM(Pico32x.pending_fb ^ 1); + } +} + +// FIXME.. +static __inline void SekRunM68k(int cyc) +{ + int cyc_do; + SekCycleAim+=cyc; + if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return; +#if defined(EMU_CORE_DEBUG) + // this means we do run-compare + SekCycleCnt+=CM_compareRun(cyc_do, 0); +#elif defined(EMU_C68K) + PicoCpuCM68k.cycles=cyc_do; + CycloneRun(&PicoCpuCM68k); + SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles; +#elif defined(EMU_M68K) + SekCycleCnt+=m68k_execute(cyc_do); +#elif defined(EMU_F68K) + SekCycleCnt+=fm68k_emulate(cyc_do+1, 0, 0); +#endif +} + +#define PICO_32X +#include "../pico_cmn.c" + +void PicoFrame32x(void) +{ + if ((Pico32x.vdp_regs[0] & 3 ) != 0) // no forced blanking + Pico32x.vdp_regs[0x0a/2] &= ~(P32XV_VBLK|P32XV_PEN); // get out of vblank + + PicoFrameStart(); + PicoFrameHints(); +} diff --git a/pico/32x/draw.c b/pico/32x/draw.c new file mode 100644 index 0000000..794e2d4 --- /dev/null +++ b/pico/32x/draw.c @@ -0,0 +1,58 @@ +#include "../pico_int.h" + +static void convert_pal555(void) +{ + unsigned int *ps = (void *)Pico32xMem->pal; + unsigned int *pd = (void *)Pico32xMem->pal_native; + unsigned int m1 = 0x001f001f; + unsigned int m2 = 0x03e003e0; + unsigned int m3 = 0xfc00fc00; + int i; + + // place prio to LS green bit + for (i = 0x100/2; i > 0; i--, ps++, pd++) { + unsigned int t = *ps; + *pd = ((t & m1) << 11) | ((t & m2) << 1) | ((t & m3) >> 10); + } + + Pico32x.dirty_pal = 0; +} + +void FinalizeLine32xRGB555(int sh, int line) +{ + unsigned short *pd = DrawLineDest; + unsigned short *pal = Pico32xMem->pal_native; + unsigned char *pb = HighCol + 8; + unsigned short cram0; + + // this is a bit hackish: + // we swap cram color 0 with color that is used for background, + // as bg is forced to 0 when we do 32X + cram0 = Pico.cram[0]; + Pico.cram[0] = Pico.cram[Pico.video.reg[7] & 0x3f]; + + FinalizeLineRGB555(sh, line); + Pico.cram[0] = cram0; + + if ((Pico32x.vdp_regs[0] & 3) == 0) + return; // blanking + + if (Pico32x.dirty_pal) + convert_pal555(); + + if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 1) { + unsigned short *dram = (void *)Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS]; + unsigned short *ps = dram + dram[line]; + unsigned short t; + int i; + for (i = 320/2; i > 0; i--, ps++, pd += 2, pb += 2) { + t = pal[*ps >> 8]; + if (pb[0] == 0 || (t & 0x20)) + pd[0] = t; + t = pal[*ps & 0xff]; + if (pb[1] == 0 || (t & 0x20)) + pd[1] = t; + } + } +} + diff --git a/pico/32x/memory.c b/pico/32x/memory.c index 324c789..f1a109e 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -3,18 +3,33 @@ static const char str_mars[] = "MARS"; -struct Pico32xMem { - u8 sdram[0x40000]; - u8 dram[0x40000]; // AKA fb - u8 m68k_rom[M68K_BANK_SIZE]; // 0x100 +struct Pico32xMem *Pico32xMem; + +// SH2 faking +static const u16 comm_fakevals[] = { + 0x4d5f, 0x4f4b, // M_OK + 0x535f, 0x4f4b, // S_OK + 0x0002, // Mortal Kombat + 0, // pad }; -static struct Pico32xMem *Pico32xMem; - static u32 p32x_reg_read16(u32 a) { a &= 0x3e; + // SH2 faker + if ((a & 0x30) == 0x20) + { + static int f = 0, csum_faked = 0; + if (a == 0x28 && !csum_faked) { + csum_faked = 1; + return *(unsigned short *)(Pico.rom + 0x18e); + } + if (f >= sizeof(comm_fakevals) / sizeof(comm_fakevals[0])) + f = 0; + return comm_fakevals[f++]; + } + return Pico32x.regs[a / 2]; } @@ -48,36 +63,39 @@ static u32 p32x_vdp_read16(u32 a) 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) { + u16 *r = Pico32x.vdp_regs; a &= 0x0f; + // TODO: verify what's writeable switch (a) { + case 0x01: + if (((r[0] & 3) == 0) != ((d & 3) == 0)) { // forced blanking changed + if (Pico.video.status & 8) + r[0x0a/2] |= P32XV_VBLK; + else + r[0x0a/2] &= ~P32XV_VBLK; + } + r[0] = (r[0] & P32XV_nPAL) | (d & 0xff); + break; 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; + d &= 1; + Pico32x.pending_fb = d; + // if we are blanking and FS bit is changing + if ((r[0x0a/2] & P32XV_VBLK) && ((r[0x0a/2] ^ d) & P32XV_FS)) { + r[0x0a/2] ^= 1; + Pico32xSwapDRAM(d ^ 1); } break; } } +static void p32x_vdp_write16(u32 a, u32 d) +{ + p32x_vdp_write8(a | 1, d); +} + // default 32x handlers u32 PicoRead8_32x(u32 a) { @@ -87,11 +105,20 @@ u32 PicoRead8_32x(u32 a) goto out_16to8; } - if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { + if (!(Pico32x.regs[0] & 1)) + goto no_vdp; + + if ((a & 0xfff0) == 0x5180) { // a15180 d = p32x_vdp_read16(a); goto out_16to8; } + if ((a & 0xfe00) == 0x5200) { // a15200 + d = Pico32xMem->pal[(a & 0x1ff) / 2]; + goto out_16to8; + } + +no_vdp: if ((a & 0xfffc) == 0x30ec) { // a130ec d = str_mars[a & 3]; goto out; @@ -119,11 +146,20 @@ u32 PicoRead16_32x(u32 a) goto out; } - if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180 + if (!(Pico32x.regs[0] & 1)) + goto no_vdp; + + if ((a & 0xfff0) == 0x5180) { // a15180 d = p32x_vdp_read16(a); goto out; } + if ((a & 0xfe00) == 0x5200) { // a15200 + d = Pico32xMem->pal[(a & 0x1ff) / 2]; + goto out; + } + +no_vdp: if ((a & 0xfffc) == 0x30ec) { // a130ec d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S'; goto out; @@ -147,11 +183,23 @@ void PicoWrite8_32x(u32 a, u32 d) return; } - if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180 + if (!(Pico32x.regs[0] & 1)) + goto no_vdp; + + if ((a & 0xfff0) == 0x5180) { // a15180 p32x_vdp_write8(a, d); return; } + // TODO: verify + if ((a & 0xfe00) == 0x5200) { // a15200 + elprintf(EL_32X|EL_ANOMALY, "m68k 32x PAL w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); + ((u8 *)Pico32xMem->pal)[(a & 0x1ff) ^ 1] = d; + Pico32x.dirty_pal = 1; + return; + } + +no_vdp: elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); } @@ -165,11 +213,21 @@ void PicoWrite16_32x(u32 a, u32 d) return; } - if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180 + if (!(Pico32x.regs[0] & 1)) + goto no_vdp; + + if ((a & 0xfff0) == 0x5180) { // a15180 p32x_vdp_write16(a, d); return; } + if ((a & 0xfe00) == 0x5200) { // a15200 + Pico32xMem->pal[(a & 0x1ff) / 2] = d; + Pico32x.dirty_pal = 1; + return; + } + +no_vdp: elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); } @@ -194,6 +252,14 @@ static void PicoWrite16_hint(u32 a, u32 d) elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); } +void Pico32xSwapDRAM(int b) +{ + cpu68k_map_set(m68k_read8_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0); + cpu68k_map_set(m68k_read16_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0); + cpu68k_map_set(m68k_write8_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0); + cpu68k_map_set(m68k_write16_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0); +} + #define HWSWAP(x) (((x) << 16) | ((x) >> 16)) void PicoMemSetup32x(void) { @@ -212,7 +278,7 @@ void PicoMemSetup32x(void) 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); + pl[i] = HWSWAP(0x880200 + (i - 1) * 6); // fill with nops for (i = 0xc0/2; i < 0x100/2; i++) @@ -223,7 +289,7 @@ void PicoMemSetup32x(void) ps[0xfe/2] = 0x60fe; // jump to self // fill remaining mem with ROM - memcpy(Pico32xMem->m68k_rom + 0x100, Pico.rom + 0x100, M68K_BANK_SIZE - 0x100); + memcpy(Pico32xMem->m68k_rom + 0x100, Pico.rom + 0x100, sizeof(Pico32xMem->m68k_rom) - 0x100); // cartridge area becomes unmapped // XXX: we take the easy way and don't unmap ROM, @@ -231,10 +297,14 @@ void PicoMemSetup32x(void) // 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); + rs = sizeof(Pico32xMem->m68k_rom); + cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico32xMem->m68k_rom, 0); + cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico32xMem->m68k_rom, 0); + cpu68k_map_set(m68k_write8_map, 0x000000, rs - 1, PicoWrite8_hint, 1); // TODO verify + cpu68k_map_set(m68k_write16_map, 0x000000, rs - 1, PicoWrite16_hint, 1); + + // DRAM area + Pico32xSwapDRAM(1); // 32X ROM (unbanked, XXX: consider mirroring?) rs1 = rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK; diff --git a/pico/draw.c b/pico/draw.c index 8647a36..180045d 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -78,7 +78,7 @@ void DrawAllSprites(unsigned char *sprited, int prio, int sh); void DrawTilesFromCache(int *hc, int sh, int rlim); void DrawSpritesSHi(unsigned char *sprited); void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells); -void FinalizeLineBGR444(int sh); +void FinalizeLineBGR444(int sh, int line); void *blockcpy(void *dst, const void *src, size_t n); void blockcpy_or(void *dst, void *src, size_t n, int pat); #else @@ -1192,7 +1192,7 @@ void PicoDoHighPal555(int sh) } } -static void FinalizeLineBGR444(int sh) +static void FinalizeLineBGR444(int sh, int line) { unsigned short *pd=DrawLineDest; unsigned char *ps=HighCol+8; @@ -1230,7 +1230,7 @@ static void FinalizeLineBGR444(int sh) } -void FinalizeLineRGB555(int sh) +void FinalizeLineRGB555(int sh, int line) { unsigned short *pd=DrawLineDest; unsigned char *ps=HighCol+8; @@ -1266,7 +1266,7 @@ void FinalizeLineRGB555(int sh) } #endif -static void FinalizeLine8bit(int sh) +static void FinalizeLine8bit(int sh, int line) { unsigned char *pd = DrawLineDest; int len, rs = rendstatus; @@ -1306,7 +1306,7 @@ static void FinalizeLine8bit(int sh) } } -static void (*FinalizeLine)(int sh); +static void (*FinalizeLine)(int sh, int line); // -------------------------------------------- @@ -1429,43 +1429,38 @@ PICO_INTERNAL void PicoFrameStart(void) PrepareSprites(1); } -static void DrawBlankedLine(int line, int offs) +static void DrawBlankedLine(int line, int offs, int sh, int bgc) { - int sh = (Pico.video.reg[0xC]&8)>>3; // shadow/hilight? - if (PicoScanBegin != NULL) PicoScanBegin(line + offs); - BackFill(Pico.video.reg[7], sh); + BackFill(bgc, sh); if (FinalizeLine != NULL) - FinalizeLine(sh); + FinalizeLine(sh, line); if (PicoScanEnd != NULL) PicoScanEnd(line + offs); } -static void PicoLine(int line, int offs) +static void PicoLine(int line, int offs, int sh, int bgc) { - int sh; if (skip_next_line > 0) { skip_next_line--; return; } - sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight? - DrawScanline = line; if (PicoScanBegin != NULL) skip_next_line = PicoScanBegin(line + offs); // Draw screen: - BackFill(Pico.video.reg[7], sh); + BackFill(bgc, sh); if (Pico.video.reg[1]&0x40) DrawDisplay(sh); if (FinalizeLine != NULL) - FinalizeLine(sh); + FinalizeLine(sh, line); if (PicoScanEnd != NULL) skip_next_line = PicoScanEnd(line + offs); @@ -1474,16 +1469,22 @@ static void PicoLine(int line, int offs) void PicoDrawSync(int to, int blank_last_line) { int line, offs = 0; + int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight? + int bgc = Pico.video.reg[7]; if (!(rendstatus & PDRAW_240LINES)) offs = 8; + // need to know which pixels are bg for 32x + if (PicoAHW & PAHW_32X) + bgc = 0; + for (line = DrawScanline; line < to; line++) { #if !CAN_HANDLE_240_LINES if (line >= 224) break; #endif - PicoLine(line, offs); + PicoLine(line, offs, sh, bgc); } #if !CAN_HANDLE_240_LINES @@ -1497,8 +1498,8 @@ void PicoDrawSync(int to, int blank_last_line) if (line <= to) { if (blank_last_line) - DrawBlankedLine(line, offs); - else PicoLine(line, offs); + DrawBlankedLine(line, offs, sh, bgc); + else PicoLine(line, offs, sh, bgc); line++; } DrawScanline = line; @@ -1509,7 +1510,7 @@ void PicoDrawSetColorFormat(int which) switch (which) { case 2: FinalizeLine = FinalizeLine8bit; break; - case 1: FinalizeLine = FinalizeLineRGB555; break; + case 1: FinalizeLine = (PicoAHW & PAHW_32X) ? FinalizeLine32xRGB555 : FinalizeLineRGB555; break; case 0: FinalizeLine = FinalizeLineBGR444; break; default:FinalizeLine = NULL; break; } diff --git a/pico/memory.c b/pico/memory.c index d2dced3..5160df1 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -1082,7 +1082,6 @@ static unsigned char MEMH_FUNC z80_md_vdp_read(unsigned short a) static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a) { - extern unsigned int PicoReadM68k8(unsigned int a); unsigned int addr68k; unsigned char ret; @@ -1124,7 +1123,6 @@ static void MEMH_FUNC z80_md_vdp_br_write(unsigned int a, unsigned char data) static void MEMH_FUNC z80_md_bank_write(unsigned int a, unsigned char data) { - extern void PicoWriteM68k8(unsigned int a, unsigned char d); unsigned int addr68k; addr68k = Pico.m.z80_bank68k << 15; diff --git a/pico/pico.c b/pico/pico.c index aa2be38..302cc69 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -76,6 +76,9 @@ void PicoPower(void) if (PicoAHW & PAHW_MCD) PicoPowerMCD(); + if (!(PicoOpt & POPT_DIS_32X)) + PicoPower32x(); + PicoReset(); } @@ -302,11 +305,17 @@ void PicoFrame(void) return; } + // TODO: MCD+32X if (PicoAHW & PAHW_MCD) { PicoFrameMCD(); return; } + if (PicoAHW & PAHW_32X) { + PicoFrame32x(); + return; + } + //if(Pico.video.reg[12]&0x2) Pico.video.status ^= 0x10; // change odd bit in interlace mode PicoFrameStart(); diff --git a/pico/pico.h b/pico/pico.h index 8b7d032..e20820c 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -34,6 +34,9 @@ extern void cache_flush_d_inval_i(const void *start_addr, const void *end_addr); // this one should handle display mode changes extern void emu_video_mode_change(int start_line, int line_count, int is_32cols); +// this must switch to 32bpp mode +extern void emu_32x_startup(void); + // Pico.c #define POPT_EN_FM (1<< 0) // 00 000x #define POPT_EN_PSG (1<< 1) diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 368b4c8..407309a 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -31,7 +31,6 @@ } #endif -// Accurate but slower frame which does hints static int PicoFrameHints(void) { struct PicoVideo *pv=&Pico.video; @@ -176,6 +175,10 @@ static int PicoFrameHints(void) pv->status|=0x08; // go into vblank pv->pending_ints|=0x20; +#ifdef PICO_32X + p32x_start_blank(); +#endif + // the following SekRun is there for several reasons: // there must be a delay after vblank bit is set and irq is asserted (Mazin Saga) // also delay between F bit (bit 7) is set in SR and IRQ happens (Ex-Mutants) diff --git a/pico/pico_int.h b/pico/pico_int.h index 85f2506..431c9a6 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -389,12 +389,32 @@ typedef struct #define Pico_mcd ((mcd_state *)Pico.rom) // 32X +#define P32XV_nPAL (1<<15) +#define P32XV_PRI (1<< 7) +#define P32XV_Mx (3<< 0) + +#define P32XV_VBLK (1<<15) +#define P32XV_HBLK (1<<14) +#define P32XV_PEN (1<<13) +#define P32XV_nFEN (1<< 1) +#define P32XV_FS (1<< 0) + struct Pico32x { unsigned short regs[0x20]; unsigned short vdp_regs[0x10]; unsigned char pending_fb; - unsigned char pad[3]; + unsigned char dirty_pal; + unsigned char pad[2]; +}; + +struct Pico32xMem +{ + unsigned char sdram[0x40000]; + unsigned short dram[2][0x20000/2]; // AKA fb + unsigned char m68k_rom[0x10000]; // 0x100; using M68K_BANK_SIZE + unsigned short pal[0x100]; + unsigned short pal_native[0x100]; // converted to native (for renderer) }; // area.c @@ -436,7 +456,7 @@ int CM_compareRun(int cyc, int is_sub); PICO_INTERNAL void PicoFrameStart(void); void PicoDrawSync(int to, int blank_last_line); void BackFill(int reg7, int sh); -void FinalizeLineRGB555(int sh); +void FinalizeLineRGB555(int sh, int line); extern int DrawScanline; #define MAX_LINE_SPRITES 29 extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; @@ -588,15 +608,22 @@ void PicoFrameDrawOnlyMS(void); // 32x/32x.c extern struct Pico32x Pico32x; void Pico32xInit(void); -void Pico32xStartup(void); +void PicoPower32x(void); void PicoReset32x(void); +void Pico32xStartup(void); +void PicoFrame32x(void); // 32x/memory.c +struct Pico32xMem *Pico32xMem; 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); +void Pico32xSwapDRAM(int b); + +// 32x/draw.c +void FinalizeLine32xRGB555(int sh, int line); /* avoid dependency on newer glibc */ static __inline int isspace_(int c) diff --git a/platform/common/emu.c b/platform/common/emu.c index 6fc25b4..627c3be 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -409,6 +409,32 @@ static void shutdown_MCD(void) PicoAHW &= ~PAHW_MCD; } +static void system_announce(void) +{ + const char *sys_name, *tv_standard; + int fps; + + if (PicoAHW & PAHW_SMS) { + sys_name = "Master System"; + } else if (PicoAHW & PAHW_PICO) { + sys_name = "Pico"; + } else if (PicoAHW & PAHW_MCD) { + sys_name = "Mega CD"; + if ((Pico.m.hardware & 0xc0) == 0x80) + sys_name = "Sega CD"; + } else if (PicoAHW & PAHW_32X) { + sys_name = "32X"; + } else { + sys_name = "MegaDrive"; + if ((Pico.m.hardware & 0xc0) == 0x80) + sys_name = "Genesis"; + } + tv_standard = Pico.m.pal ? "PAL" : "NTSC"; + fps = Pico.m.pal ? 50 : 60; + + emu_status_msg("%s %s / %dFPS", tv_standard, sys_name, fps); +} + // note: this function might mangle rom_fname // XXX: portions of this code should move to pico/ int emu_reload_rom(char *rom_fname) @@ -612,21 +638,7 @@ int emu_reload_rom(char *rom_fname) } else { - const char *sys_name, *tv_standard; - int fps; - - if (PicoAHW & PAHW_SMS) { - sys_name = "Master System"; - } else { - sys_name = "MegaDrive"; - if ((Pico.m.hardware&0xc0) == 0x80) - sys_name = "Genesis"; - } - tv_standard = Pico.m.pal ? "PAL" : "NTSC"; - fps = Pico.m.pal ? 50 : 60; - - emu_status_msg("%s %s / %dFPS", tv_standard, sys_name, fps); - + system_announce(); PicoOpt &= ~POPT_DIS_VDP_FIFO; } @@ -1073,6 +1085,12 @@ static void emu_tray_close(void) emu_status_msg("CD tray closed."); } +void emu_32x_startup(void) +{ + plat_video_toggle_renderer(0, 1, 0); + system_announce(); +} + void emu_reset_game(void) { PicoReset(); @@ -1200,9 +1218,9 @@ static void run_events_ui(unsigned int which) PicoStateProgressCB = NULL; } } - if (which & PEV_SWITCH_RND) + if ((which & PEV_SWITCH_RND) && !(PicoAHW & PAHW_32X)) { - plat_video_toggle_renderer(1, 0); + plat_video_toggle_renderer(1, 0, 0); } if (which & (PEV_SSLOT_PREV|PEV_SSLOT_NEXT)) { diff --git a/platform/common/menu.c b/platform/common/menu.c index e651694..adfacef 100644 --- a/platform/common/menu.c +++ b/platform/common/menu.c @@ -1452,7 +1452,7 @@ static int menu_loop_adv_options(menu_id id, int keys) static int mh_opt_render(menu_id id, int keys) { - plat_video_toggle_renderer((keys & PBTN_RIGHT) ? 1 : 0, 1); + plat_video_toggle_renderer((keys & PBTN_RIGHT) ? 1 : 0, 0, 1); return 0; } diff --git a/platform/common/plat.h b/platform/common/plat.h index ca847c6..e1fc29b 100644 --- a/platform/common/plat.h +++ b/platform/common/plat.h @@ -36,7 +36,7 @@ void plat_video_menu_begin(void); void plat_video_menu_end(void); void plat_video_wait_vsync(void); -void plat_video_toggle_renderer(int is_next, int is_menu); +void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu); void plat_validate_config(void); void plat_update_volume(int has_changed, int is_up); diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 817237a..8ccea30 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -72,6 +72,8 @@ 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 endif +# Pico - 32X +OBJS += pico/32x/32x.o pico/32x/memory.o pico/32x/draw.o # Pico - Pico OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o # Pico - carthw diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 97b28b6..757bea6 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -498,10 +498,14 @@ static void vidResetMode(void) make_local_pal = (PicoAHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md; } -void plat_video_toggle_renderer(int is_next, int is_menu) +void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu) { + if (force_16bpp) { + PicoOpt &= ~POPT_ALT_RENDERER; + currentConfig.EmuOpt |= EOPT_16BPP; + } /* alt, 16bpp, 8bpp */ - if (PicoOpt & POPT_ALT_RENDERER) { + else if (PicoOpt & POPT_ALT_RENDERER) { PicoOpt &= ~POPT_ALT_RENDERER; if (is_next) currentConfig.EmuOpt |= EOPT_16BPP; diff --git a/platform/linux/Makefile b/platform/linux/Makefile index e6a94a2..32fa3c5 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -40,7 +40,7 @@ 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 +OBJS += pico/32x/32x.o pico/32x/memory.o pico/32x/draw.o # Pico - Pico OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o # Pico - sound -- 2.39.2