mirror of
https://github.com/FunKey-Project/picodrive-irixxxx.git
synced 2026-04-04 00:52:49 +02:00
sms, fix pad TH, some BIOS init, korean 32k mapper
sms, fix some minor vdp bugs z80, fix for cz80 handling of A register libretro, enable drc usage on WiiU
This commit is contained in:
@@ -281,12 +281,9 @@ else ifeq ($(platform), wiiu)
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
|
||||
CFLAGS += -DGEKKO -DWIIU -DHW_RVL -mwup -mcpu=750 -meabi -mhard-float -D__ppc__ -DMSB_FIRST
|
||||
CFLAGS += -DGEKKO -DWIIU -DHW_RVL -DHW_WUP -mwup -mcpu=750 -meabi -mhard-float -D__ppc__ -DMSB_FIRST
|
||||
STATIC_LINKING = 1
|
||||
NO_MMAP = 1
|
||||
# Wii U has memory mapped in a way not suitable for DRC
|
||||
use_sh2drc = 0
|
||||
use_svpdrc = 0
|
||||
|
||||
# Nintendo Switch (libtransistor)
|
||||
else ifeq ($(platform), switch)
|
||||
|
||||
@@ -196,7 +196,7 @@ void Cz80_Init(cz80_struc *CPU)
|
||||
CPU->pzR16[0] = pzBC;
|
||||
CPU->pzR16[1] = pzDE;
|
||||
CPU->pzR16[2] = pzHL;
|
||||
CPU->pzR16[3] = pzAF;
|
||||
CPU->pzR16[3] = pzFA;
|
||||
|
||||
zIX = zIY = 0xffff;
|
||||
|
||||
@@ -339,13 +339,13 @@ UINT32 Cz80_Get_Reg(cz80_struc *CPU, INT32 regnum)
|
||||
{
|
||||
case CZ80_PC: return (CPU->PC - CPU->BasePC);
|
||||
case CZ80_SP: return zSP;
|
||||
case CZ80_AF: return zAF;
|
||||
case CZ80_FA: return zFA;
|
||||
case CZ80_BC: return zBC;
|
||||
case CZ80_DE: return zDE;
|
||||
case CZ80_HL: return zHL;
|
||||
case CZ80_IX: return zIX;
|
||||
case CZ80_IY: return zIY;
|
||||
case CZ80_AF2: return zAF2;
|
||||
case CZ80_FA2: return zFA2;
|
||||
case CZ80_BC2: return zBC2;
|
||||
case CZ80_DE2: return zDE2;
|
||||
case CZ80_HL2: return zHL2;
|
||||
@@ -378,13 +378,13 @@ void Cz80_Set_Reg(cz80_struc *CPU, INT32 regnum, UINT32 val)
|
||||
break;
|
||||
|
||||
case CZ80_SP: zSP = val; break;
|
||||
case CZ80_AF: zAF = val; break;
|
||||
case CZ80_FA: zFA = val; break;
|
||||
case CZ80_BC: zBC = val; break;
|
||||
case CZ80_DE: zDE = val; break;
|
||||
case CZ80_HL: zHL = val; break;
|
||||
case CZ80_IX: zIX = val; break;
|
||||
case CZ80_IY: zIY = val; break;
|
||||
case CZ80_AF2: zAF2 = val; break;
|
||||
case CZ80_FA2: zFA2 = val; break;
|
||||
case CZ80_BC2: zBC2 = val; break;
|
||||
case CZ80_DE2: zDE2 = val; break;
|
||||
case CZ80_HL2: zHL2 = val; break;
|
||||
|
||||
@@ -79,12 +79,12 @@ extern "C" {
|
||||
#define zR8(A) (*CPU->pzR8[A])
|
||||
#define zR16(A) (CPU->pzR16[A]->W)
|
||||
|
||||
#define pzAF &(CPU->AF)
|
||||
#define zAF CPU->AF.W
|
||||
#define zlAF CPU->AF.B.L
|
||||
#define zhAF CPU->AF.B.H
|
||||
#define zA zhAF
|
||||
#define zF zlAF
|
||||
#define pzFA &(CPU->FA)
|
||||
#define zFA CPU->FA.W
|
||||
#define zlFA CPU->FA.B.L
|
||||
#define zhFA CPU->FA.B.H
|
||||
#define zA zlFA
|
||||
#define zF zhFA
|
||||
|
||||
#define pzBC &(CPU->BC)
|
||||
#define zBC CPU->BC.W
|
||||
@@ -107,11 +107,11 @@ extern "C" {
|
||||
#define zH zhHL
|
||||
#define zL zlHL
|
||||
|
||||
#define zAF2 CPU->AF2.W
|
||||
#define zlAF2 CPU->AF2.B.L
|
||||
#define zhAF2 CPU->AF2.B.H
|
||||
#define zA2 zhAF2
|
||||
#define zF2 zlAF2
|
||||
#define zFA2 CPU->FA2.W
|
||||
#define zlFA2 CPU->FA2.B.L
|
||||
#define zhFA2 CPU->FA2.B.H
|
||||
#define zA2 zhFA2
|
||||
#define zF2 zlFA2
|
||||
|
||||
#define zBC2 CPU->BC2.W
|
||||
#define zDE2 CPU->DE2.W
|
||||
@@ -187,13 +187,13 @@ enum
|
||||
{
|
||||
CZ80_PC = 1,
|
||||
CZ80_SP,
|
||||
CZ80_AF,
|
||||
CZ80_FA,
|
||||
CZ80_BC,
|
||||
CZ80_DE,
|
||||
CZ80_HL,
|
||||
CZ80_IX,
|
||||
CZ80_IY,
|
||||
CZ80_AF2,
|
||||
CZ80_FA2,
|
||||
CZ80_BC2,
|
||||
CZ80_DE2,
|
||||
CZ80_HL2,
|
||||
@@ -232,7 +232,7 @@ typedef struct cz80_t
|
||||
union16 BC;
|
||||
union16 DE;
|
||||
union16 HL;
|
||||
union16 AF;
|
||||
union16 FA;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -244,7 +244,7 @@ typedef struct cz80_t
|
||||
union16 BC2;
|
||||
union16 DE2;
|
||||
union16 HL2;
|
||||
union16 AF2;
|
||||
union16 FA2;
|
||||
|
||||
union16 R;
|
||||
union16 IFF;
|
||||
|
||||
@@ -200,9 +200,15 @@ OP_LD_mNN_xx:
|
||||
POP
|
||||
-----------------------------------------*/
|
||||
|
||||
OP(0xf1): // POP AF
|
||||
OP_POP_AF:
|
||||
POP_16(res)
|
||||
zA = res >> 8;
|
||||
zF = res & 0xFF;
|
||||
RET(10)
|
||||
|
||||
OP(0xc1): // POP BC
|
||||
OP(0xd1): // POP DE
|
||||
OP(0xf1): // POP AF
|
||||
OP_POP_RR:
|
||||
data = CPU->pzR16[(Opcode >> 4) & 3];
|
||||
|
||||
@@ -215,9 +221,14 @@ OP_POP:
|
||||
PUSH
|
||||
-----------------------------------------*/
|
||||
|
||||
OP(0xf5): // PUSH AF
|
||||
OP_PUSH_AF:
|
||||
PUSH_16((zA << 8) | zF);
|
||||
RET(11)
|
||||
|
||||
|
||||
OP(0xc5): // PUSH BC
|
||||
OP(0xd5): // PUSH DE
|
||||
OP(0xf5): // PUSH AF
|
||||
OP_PUSH_RR:
|
||||
data = CPU->pzR16[(Opcode >> 4) & 3];
|
||||
|
||||
@@ -232,9 +243,9 @@ OP_PUSH:
|
||||
|
||||
OP(0x08): // EX AF,AF'
|
||||
OP_EX_AF_AF2:
|
||||
res = zAF;
|
||||
zAF = zAF2;
|
||||
zAF2 = res;
|
||||
res = zFA;
|
||||
zFA = zFA2;
|
||||
zFA2 = res;
|
||||
RET(4)
|
||||
|
||||
OP(0xeb): // EX DE,HL
|
||||
|
||||
@@ -194,8 +194,9 @@ switch (Opcode)
|
||||
|
||||
OPXY(0xc1): // POP BC
|
||||
OPXY(0xd1): // POP DE
|
||||
OPXY(0xf1): // POP AF
|
||||
goto OP_POP_RR;
|
||||
OPXY(0xf1): // POP AF
|
||||
goto OP_POP_AF;
|
||||
|
||||
OPXY(0xe1): // POP IX
|
||||
goto OP_POP;
|
||||
@@ -206,8 +207,9 @@ switch (Opcode)
|
||||
|
||||
OPXY(0xc5): // PUSH BC
|
||||
OPXY(0xd5): // PUSH DE
|
||||
OPXY(0xf5): // PUSH AF
|
||||
goto OP_PUSH_RR;
|
||||
OPXY(0xf5): // PUSH AF
|
||||
goto OP_PUSH_AF;
|
||||
|
||||
OPXY(0xe5): // PUSH IX
|
||||
goto OP_PUSH;
|
||||
|
||||
30
pico/mode4.c
30
pico/mode4.c
@@ -428,17 +428,18 @@ static void DrawSpritesTMS(int scanline)
|
||||
if (sat[MEM_LE2(i+3)] & 0x80)
|
||||
x -= 32;
|
||||
c = sat[MEM_LE2(i+3)] & 0x0f;
|
||||
// c may be 0 (transparent): sprite invisible
|
||||
if (x > 0) {
|
||||
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s])];
|
||||
if (zoomed) TileDoubleSprTMS(x, pack, c);
|
||||
else TileNormSprTMS(x, pack, c);
|
||||
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
||||
if (zoomed && c) TileDoubleSprTMS(x, pack, c);
|
||||
else if (c) TileNormSprTMS(x, pack, c);
|
||||
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
||||
}
|
||||
if((pv->reg[1] & 0x2) && (x+=w) > 0) {
|
||||
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s]+0x10)];
|
||||
if (zoomed) TileDoubleSprTMS(x, pack, c);
|
||||
else TileNormSprTMS(x, pack, c);
|
||||
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
||||
if (zoomed && c) TileDoubleSprTMS(x, pack, c);
|
||||
else if (c) TileNormSprTMS(x, pack, c);
|
||||
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
||||
}
|
||||
}
|
||||
if (m)
|
||||
@@ -615,6 +616,7 @@ void PicoFrameStartSMS(void)
|
||||
void PicoLineSMS(int line)
|
||||
{
|
||||
int skip = skip_next_line;
|
||||
unsigned bgcolor;
|
||||
|
||||
// GG LCD, render only visible part of screen
|
||||
if ((Pico.m.hardware & 0x3) == 0x3 && (line < 24 || line >= 24+144))
|
||||
@@ -629,7 +631,8 @@ void PicoLineSMS(int line)
|
||||
}
|
||||
|
||||
// Draw screen:
|
||||
BackFill(Pico.video.reg[7] & 0x0f, 0, &Pico.est);
|
||||
bgcolor = (Pico.video.reg[7] & 0x0f) | ((Pico.video.reg[0] & 0x04) << 2);
|
||||
BackFill(bgcolor, 0, &Pico.est); // bgcolor is from 2nd palette in mode 4
|
||||
if (Pico.video.reg[1] & 0x40) {
|
||||
if (Pico.video.reg[0] & 0x04) DrawDisplayM4(line);
|
||||
else if (Pico.video.reg[0] & 0x02) DrawDisplayM2(line);
|
||||
@@ -649,8 +652,13 @@ norender:
|
||||
|
||||
/* Fixed palette for TMS9918 modes */
|
||||
static u16 tmspal[32] = {
|
||||
#if 1 // SMS palette
|
||||
0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0,
|
||||
0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff,
|
||||
#else // TMS palette
|
||||
0x0000, 0x0000, 0x04c2, 0x07d5, 0x0e55, 0x0f77, 0x045d, 0x0fe4,
|
||||
0x055f, 0x077f, 0x05cd, 0x08ce, 0x03b2, 0x0b5c, 0x0ccc, 0x0fff,
|
||||
#endif
|
||||
};
|
||||
|
||||
void PicoDoHighPal555SMS(void)
|
||||
@@ -668,15 +676,11 @@ void PicoDoHighPal555SMS(void)
|
||||
if (FinalizeLineSMS == FinalizeLineRGB555SMS)
|
||||
spal = (void *)PicoMem.cram;
|
||||
|
||||
// fixed palette in TMS modes
|
||||
if (!(Pico.video.reg[0] & 0x4)) {
|
||||
spal = (u32 *)tmspal;
|
||||
cnt = 1;
|
||||
}
|
||||
|
||||
/* SMS 6 bit cram data was already converted to MD/GG format by vdp write,
|
||||
* hence GG/SMS/TMS can all be handled the same here */
|
||||
for (j = cnt; j > 0; j--) {
|
||||
if (!(Pico.video.reg[0] & 0x4))
|
||||
spal = (u32 *)tmspal; // fixed palette in TMS modes
|
||||
for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
||||
t = *spal;
|
||||
#if defined(USE_BGR555)
|
||||
|
||||
56
pico/sms.c
56
pico/sms.c
@@ -10,7 +10,6 @@
|
||||
* TODO:
|
||||
* - start in a state as if BIOS ran
|
||||
* - region support
|
||||
* - H counter
|
||||
*/
|
||||
#include "pico_int.h"
|
||||
#include "memory.h"
|
||||
@@ -164,7 +163,7 @@ static unsigned char z80_sms_in(unsigned short a)
|
||||
break;
|
||||
|
||||
case 0x41: /* H counter */
|
||||
d = Pico.ms.vdp_hlatch;
|
||||
d = Pico.ms.vdp_hlatch;
|
||||
elprintf(EL_HVCNT, "H counter read: %02x", d);
|
||||
break;
|
||||
|
||||
@@ -178,15 +177,13 @@ static unsigned char z80_sms_in(unsigned short a)
|
||||
|
||||
case 0xc0: /* I/O port A and B */
|
||||
d = ~((PicoIn.pad[0] & 0x3f) | (PicoIn.pad[1] << 6));
|
||||
if (Pico.ms.io_ctl & 0x01) d &= ~0x20;
|
||||
break;
|
||||
|
||||
case 0xc1: /* I/O port B and miscellaneous */
|
||||
d = (Pico.ms.io_ctl & 0x80) | ((Pico.ms.io_ctl << 1) & 0x40) | 0x30;
|
||||
d |= ~(PicoIn.pad[1] >> 2) & 0x0f;
|
||||
if (Pico.ms.io_ctl & 0x08) d &= ~0x80;
|
||||
if (Pico.ms.io_ctl & 0x04) d &= ~0x08;
|
||||
if (Pico.ms.io_ctl & 0x02) d &= ~0x40;
|
||||
if (Pico.ms.io_ctl & 0x08) d |= 0x80; // TH as input is unconnected
|
||||
if (Pico.ms.io_ctl & 0x02) d |= 0x40;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -244,7 +241,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
|
||||
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
PsndDoPSG(Pico.m.scanline*228 + 228-z80_cyclesLeft);
|
||||
PsndDoPSG(z80_cyclesDone());
|
||||
SN76496Write(d);
|
||||
break;
|
||||
|
||||
@@ -276,7 +273,7 @@ static void write_sram(unsigned short a, unsigned char d)
|
||||
// 16KB bank mapping for Sega mapper
|
||||
static void write_bank_sega(unsigned short a, unsigned char d)
|
||||
{
|
||||
if (Pico.ms.mapper != 1 && d == 0) return;
|
||||
if (Pico.ms.mapper != 1 && (Pico.ms.mapper || d == 0)) return;
|
||||
elprintf(EL_Z80BNK, "bank 16k %04x %02x @ %04x", a, d, z80_pc());
|
||||
Pico.ms.mapper = 1;
|
||||
Pico.ms.carthw[a & 0x0f] = d;
|
||||
@@ -313,7 +310,7 @@ static void write_bank_sega(unsigned short a, unsigned char d)
|
||||
// 8KB ROM mapping for MSX mapper
|
||||
static void write_bank_msx(unsigned short a, unsigned char d)
|
||||
{
|
||||
if (Pico.ms.mapper != 2 && (a|d) == 0) return;
|
||||
if (Pico.ms.mapper != 2 && (Pico.ms.mapper || (a|d) == 0)) return;
|
||||
elprintf(EL_Z80BNK, "bank 8k %04x %02x @ %04x", a, d, z80_pc());
|
||||
Pico.ms.mapper = 2; // TODO define (more) mapper types
|
||||
Pico.ms.carthw[a] = d;
|
||||
@@ -323,6 +320,17 @@ static void write_bank_msx(unsigned short a, unsigned char d)
|
||||
z80_map_set(z80_read_map, a, a+0x1fff, Pico.rom + (d << 13), 0);
|
||||
}
|
||||
|
||||
static void write_bank_32k(unsigned short a, unsigned char d)
|
||||
{
|
||||
if (Pico.ms.mapper != 3 && (Pico.ms.mapper || z80_pc() < 0xc000)) return;
|
||||
elprintf(EL_Z80BNK, "bank 32k %04x %02x @ %04x", a, d, z80_pc());
|
||||
Pico.ms.mapper = 3; // TODO define (more) mapper types
|
||||
Pico.ms.carthw[0xf] = d;
|
||||
|
||||
d &= bank_mask >> 1;
|
||||
z80_map_set(z80_read_map, 0, 0x7fff, Pico.rom + (d << 15), 0);
|
||||
}
|
||||
|
||||
// TODO mapping is currently auto-selecting, but that's not very reliable.
|
||||
static void xwrite(unsigned int a, unsigned char d)
|
||||
{
|
||||
@@ -330,21 +338,25 @@ static void xwrite(unsigned int a, unsigned char d)
|
||||
if (a >= 0xc000)
|
||||
PicoMem.zram[a & 0x1fff] = d;
|
||||
|
||||
// korean 32k. 1 selectable 32KB bank at the bottom
|
||||
if (a == 0xffff)
|
||||
write_bank_32k(a, d);
|
||||
// Sega. Maps 4 bank 16KB each
|
||||
if (a >= 0xfff8 && Pico.ms.mapper != 2)
|
||||
if (a >= 0xfff8)
|
||||
write_bank_sega(a, d);
|
||||
// Codemasters. Similar to Sega, but different addresses
|
||||
// if (a == 0x0000 && Pico.ms.mapper != 2)
|
||||
// NB mapping on 0x0000 collides with MSX mapper, but AFAICT CM isn't using it
|
||||
// if (a == 0x0000)
|
||||
// write_bank_sega(0xfffd, d);
|
||||
if (a == 0x4000 && Pico.ms.mapper != 2)
|
||||
if (a == 0x4000)
|
||||
write_bank_sega(0xfffe, d);
|
||||
if (a == 0x8000 && Pico.ms.mapper != 2)
|
||||
if (a == 0x8000)
|
||||
write_bank_sega(0xffff, d);
|
||||
// Korean. 1 selectable 16KB bank at the top
|
||||
if (a == 0xa000 && Pico.ms.mapper != 2)
|
||||
if (a == 0xa000)
|
||||
write_bank_sega(0xffff, d);
|
||||
// MSX. 4 selectable 8KB banks at the top
|
||||
if (a <= 0x0003 && Pico.ms.mapper != 1)
|
||||
if (a <= 0x0003)
|
||||
write_bank_msx(a, d);
|
||||
}
|
||||
|
||||
@@ -376,7 +388,7 @@ void PicoResetMS(void)
|
||||
// reset memory mapping
|
||||
PicoMemSetupMS();
|
||||
|
||||
// BIOS values for VDP initialisation
|
||||
// BIOS, VDP intialisation
|
||||
Pico.video.reg[0] = 0x36;
|
||||
Pico.video.reg[1] = 0xa0;
|
||||
Pico.video.reg[2] = 0xff;
|
||||
@@ -388,6 +400,9 @@ void PicoResetMS(void)
|
||||
Pico.video.reg[8] = 0x00;
|
||||
Pico.video.reg[9] = 0x00;
|
||||
Pico.video.reg[10] = 0xff;
|
||||
|
||||
// BIOS, clean zram
|
||||
memset(PicoMem.zram, 0, sizeof(PicoMem.zram));
|
||||
}
|
||||
|
||||
void PicoPowerMS(void)
|
||||
@@ -399,9 +414,6 @@ void PicoPowerMS(void)
|
||||
memset(&Pico.m,0,sizeof(Pico.m));
|
||||
Pico.m.pal = 0;
|
||||
|
||||
for (s = 0; s < sizeof(PicoMem.zram); s++)
|
||||
PicoMem.zram[s] = rand();
|
||||
|
||||
// calculate a mask for bank writes.
|
||||
// ROM loader has aligned the size for us, so this is safe.
|
||||
s = 0; tmp = Pico.romsize;
|
||||
@@ -442,6 +454,8 @@ void PicoMemSetupMS(void)
|
||||
xwrite(0x0001, 0);
|
||||
xwrite(0x0002, 0);
|
||||
xwrite(0x0003, 0);
|
||||
} else if (Pico.ms.mapper == 3) {
|
||||
xwrite(0xffff, 0);
|
||||
} else {
|
||||
xwrite(0xfffc, 0);
|
||||
xwrite(0xfffd, 0);
|
||||
@@ -459,6 +473,8 @@ void PicoStateLoadedMS(void)
|
||||
xwrite(0x0001, Pico.ms.carthw[1]);
|
||||
xwrite(0x0002, Pico.ms.carthw[2]);
|
||||
xwrite(0x0003, Pico.ms.carthw[3]);
|
||||
} else if (Pico.ms.mapper == 3) {
|
||||
xwrite(0xffff, Pico.ms.carthw[0x0f]);
|
||||
} else {
|
||||
xwrite(0xfffc, Pico.ms.carthw[0x0c]);
|
||||
xwrite(0xfffd, Pico.ms.carthw[0x0d]);
|
||||
@@ -515,7 +531,7 @@ void PicoFrameMS(void)
|
||||
if ((pv->reg[0] & 0x10) && (pv->pending_ints & 2)) {
|
||||
elprintf(EL_INTS, "hint");
|
||||
z80_int_assert(1);
|
||||
}
|
||||
}
|
||||
pv->pending_ints &= ~2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,8 +572,12 @@ void plat_munmap(void *ptr, size_t size)
|
||||
void *plat_mem_get_for_drc(size_t size)
|
||||
{
|
||||
void *mem = NULL;
|
||||
#ifdef VITA
|
||||
#if defined VITA
|
||||
sceKernelGetMemBlockBase(sceBlock, &mem);
|
||||
#elif defined HW_WUP
|
||||
// For WiiU, a slice of RWX memory left from the exploit is used, see:
|
||||
// https://github.com/embercold/pcsx_rearmed/commit/af0453223
|
||||
mem = (void *)(0x01000000 - size);
|
||||
#endif
|
||||
return mem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user