From 219e45df562cc4681844aca3bc32a4adf4bb057a Mon Sep 17 00:00:00 2001 From: infvaL <38145742+infval@users.noreply.github.com> Date: Wed, 3 Jul 2019 05:34:12 +0300 Subject: [PATCH] Update core 1.0.4 --- Makefile.psp | 2 +- common/gpu.c | 29 ++++----- common/m6502/m6502.c | 145 ++++++++++++++++++++++++++----------------- common/memorymap.c | 131 ++++++++++++++++++++------------------ common/sound.c | 18 +++++- common/supervision.h | 2 +- common/watara.c | 2 + 7 files changed, 194 insertions(+), 135 deletions(-) diff --git a/Makefile.psp b/Makefile.psp index 5e1e014..c98eded 100644 --- a/Makefile.psp +++ b/Makefile.psp @@ -7,7 +7,7 @@ PSP_FW_VERSION=200 export PSP_FW_VERSION PSP_APP_NAME=Potator PSP -PSP_APP_VER=1.0.4 +PSP_APP_VER=1.0.5 TARGET=potator EXTRA_TARGETS=EBOOT.PBP diff --git a/common/gpu.c b/common/gpu.c index 02a2338..6866923 100644 --- a/common/gpu.c +++ b/common/gpu.c @@ -15,7 +15,7 @@ static uint16 rgb555(uint8 r, uint8 g, uint8 b) static SV_MapRGBFunc mapRGB = rgb555; -const static uint8 palettes[SV_COLOR_SCHEME_COUNT][12] = { +static const uint8 palettes[SV_COLOR_SCHEME_COUNT][12] = { { 252, 252, 252, 168, 168, 168, @@ -162,6 +162,9 @@ void gpu_set_ghosting(int frameCount) if (screenBuffers[0] == NULL) { for (i = 0; i < SB_MAX; i++) { screenBuffers[i] = malloc(SV_H * SV_W / 4); + if (screenBuffers[i] == NULL) { + return; + } } } for (i = 0; i < SB_MAX; i++) { @@ -191,30 +194,28 @@ static void add_ghosting(uint32 scanline, uint16 *backbuffer, uint8 innerx, uint uint8 innerInd = (j & 3) * 2; uint8 c = (b >> innerInd) & 3; int pixInd = (x + lineCount * SV_W) / 4; - if (c == 0) { + if (c != 3) { for (i = 0; i < ghostCount; i++) { uint8 sbInd = (curSB + (SB_MAX - 1) - i) % SB_MAX; - innerInd = ((screenBufferInnerX[sbInd] + x) & 3) * 2; - c = (screenBuffers[sbInd][pixInd] >> innerInd) & 3; - if (c != 0) { + uint8 innerInd_ = ((screenBufferInnerX[sbInd] + x) & 3) * 2; + uint8 c_ = (screenBuffers[sbInd][pixInd] >> innerInd_) & 3; + if (c_ > c) { #if 0 backbuffer[x] = palette[3 - 3 * i / ghostCount]; #else - uint8 r = palettes[paletteIndex][c * 3 + 0]; - uint8 g = palettes[paletteIndex][c * 3 + 1]; - uint8 b = palettes[paletteIndex][c * 3 + 2]; - r = r + (palettes[paletteIndex][0] - r) * i / ghostCount; - g = g + (palettes[paletteIndex][1] - g) * i / ghostCount; - b = b + (palettes[paletteIndex][2] - b) * i / ghostCount; + uint8 r = palettes[paletteIndex][c_ * 3 + 0]; + uint8 g = palettes[paletteIndex][c_ * 3 + 1]; + uint8 b = palettes[paletteIndex][c_ * 3 + 2]; + r = r + (palettes[paletteIndex][c * 3 + 0] - r) * i / ghostCount; + g = g + (palettes[paletteIndex][c * 3 + 1] - g) * i / ghostCount; + b = b + (palettes[paletteIndex][c * 3 + 2] - b) * i / ghostCount; backbuffer[x] = mapRGB(r, g, b); #endif break; } } } - else { - screenBuffers[curSB][pixInd] |= c << innerInd; - } + screenBuffers[curSB][pixInd] |= c << innerInd; } if (lineCount == SV_H - 1) { diff --git a/common/m6502/m6502.c b/common/m6502/m6502.c index f2377b3..933c4a7 100644 --- a/common/m6502/m6502.c +++ b/common/m6502/m6502.c @@ -11,6 +11,7 @@ /** Alex Krasivsky 1996 **/ /** Steve Nickolas 2002 **/ /** Portions by Holger Picker 2002 **/ +/** ADC and SBC instructions provided by Scott Hemphill **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ @@ -115,64 +116,43 @@ #define M_TRB(Data) R->P = (R->P & ~Z_FLAG) | ((Data & R->A) == 0 ? Z_FLAG : 0); \ Data &= ~R->A; -#ifdef NO_DECIMAL - -#define M_ADC(Rg) \ - K.W=R->A+Rg+(R->P&C_FLAG); \ - R->P&=~(N_FLAG|V_FLAG|Z_FLAG|C_FLAG); \ - R->P|=(~(R->A^Rg)&(R->A^K.B.l)&0x80? V_FLAG:0)| \ - (K.B.h? C_FLAG:0)|ZNTable[K.B.l]; \ - R->A=K.B.l - -/* Warning! C_FLAG is inverted before SBC and after it */ -#define M_SBC(Rg) \ - K.W=R->A-Rg-(~R->P&C_FLAG); \ - R->P&=~(N_FLAG|V_FLAG|Z_FLAG|C_FLAG); \ - R->P|=((R->A^Rg)&(R->A^K.B.l)&0x80? V_FLAG:0)| \ - (K.B.h? 0:C_FLAG)|ZNTable[K.B.l]; \ - R->A=K.B.l - -#else /* NO_DECIMAL */ - -#define M_ADC(Rg) \ - if(R->P&D_FLAG) \ - { \ - K.B.l=(R->A&0x0F)+(Rg&0x0F)+(R->P&C_FLAG); \ - if(K.B.l>9) K.B.l+=6; \ - K.B.h=(R->A>>4)+(Rg>>4)+(K.B.l>15? 1:0); \ - R->A=(K.B.l&0x0F)|(K.B.h<<4); \ - R->P=(R->P&~C_FLAG)|(K.B.h>15? C_FLAG:0); \ - } \ - else \ - { \ - K.W=R->A+Rg+(R->P&C_FLAG); \ - R->P&=~(N_FLAG|V_FLAG|Z_FLAG|C_FLAG); \ - R->P|=(~(R->A^Rg)&(R->A^K.B.l)&0x80? V_FLAG:0)| \ - (K.B.h? C_FLAG:0)|ZNTable[K.B.l]; \ - R->A=K.B.l; \ - } - -/* Warning! C_FLAG is inverted before SBC and after it */ -#define M_SBC(Rg) \ - if(R->P&D_FLAG) \ - { \ - K.B.l=(R->A&0x0F)-(Rg&0x0F)-(~R->P&C_FLAG); \ - if(K.B.l&0x10) K.B.l-=6; \ - K.B.h=(R->A>>4)-(Rg>>4)-((K.B.l&0x10)>>4); \ - if(K.B.h&0x10) K.B.h-=6; \ - R->A=(K.B.l&0x0F)|(K.B.h<<4); \ - R->P=(R->P&~C_FLAG)|(K.B.h>15? 0:C_FLAG); \ - } \ - else \ - { \ - K.W=R->A-Rg-(~R->P&C_FLAG); \ - R->P&=~(N_FLAG|V_FLAG|Z_FLAG|C_FLAG); \ - R->P|=((R->A^Rg)&(R->A^K.B.l)&0x80? V_FLAG:0)| \ - (K.B.h? 0:C_FLAG)|ZNTable[K.B.l]; \ - R->A=K.B.l; \ - } - -#endif /* NO_DECIMAL */ + +/* The following code was provided by Mr. Scott Hemphill. Thanks a lot! */ +#define M_ADC(Rg) \ + { \ + register unsigned int w; \ + if ((R->A ^ Rg) & 0x80) { \ + R->P &= ~V_FLAG; } \ + else { \ + R->P |= V_FLAG; } \ + if (R->P&D_FLAG) { \ + w = (R->A & 0xf) + (Rg & 0xf) + (R->P & C_FLAG); \ + if (w >= 10) w = 0x10 | ((w+6)&0xf); \ + w += (R->A & 0xf0) + (Rg & 0xf0); \ + if (w >= 160) { \ + R->P |= C_FLAG; \ + if ((R->P&V_FLAG) && w >= 0x180) R->P &= ~ V_FLAG; \ + w += 0x60; \ + } else { \ + R->P &= ~C_FLAG; \ + if ((R->P&V_FLAG) && w < 0x80) R->P &= ~V_FLAG; \ + } \ + } else { \ + w = R->A + Rg + (R->P&C_FLAG); \ + if (w >= 0x100) { \ + R->P |= C_FLAG; \ + if ((R->P & V_FLAG) && w >= 0x180) R->P &= ~V_FLAG; \ + } else { \ + R->P &= ~C_FLAG; \ + if ((R->P&V_FLAG) && w < 0x80) R->P &= ~V_FLAG; \ + } \ + } \ + R->A = (unsigned char)w; \ + R->P = (R->P & ~(Z_FLAG | N_FLAG)) | (R->A >= 0x80 ? N_FLAG : 0) | (R->A == 0 ? Z_FLAG : 0); \ + } + + +#define M_SBC(Rg) SBCInstruction(R, Rg) #define M_CMP(Rg1,Rg2) \ @@ -198,6 +178,55 @@ R->P&=~C_FLAG;R->P|=Rg&C_FLAG;Rg=K.B.l; \ M_FL(Rg) +/* The following code was provided by Mr. Scott Hemphill. Thanks a lot again! */ +static void SBCInstruction(M6502 *R, register unsigned char val) { + register unsigned int w; + register unsigned int temp; + + if ((R->A ^ val) & 0x80) { + R->P |= V_FLAG; + } + else { + R->P &= ~V_FLAG; + } + + if (R->P&D_FLAG) { /* decimal subtraction */ + temp = 0xf + (R->A & 0xf) - (val & 0xf) + (R->P & C_FLAG); + if (temp < 0x10) { + w = 0; + temp -= 6; + } + else { + w = 0x10; + temp -= 0x10; + } + w += 0xf0 + (R->A & 0xf0) - (val & 0xf0); + if (w < 0x100) { + R->P &= ~C_FLAG; + if ((R->P&V_FLAG) && w < 0x80) R->P &= ~V_FLAG; + w -= 0x60; + } + else { + R->P |= C_FLAG; + if ((R->P&V_FLAG) && w >= 0x180) R->P &= ~V_FLAG; + } + w += temp; + } + else { /* standard binary subtraction */ + w = 0xff + R->A - val + (R->P&C_FLAG); + if (w < 0x100) { + R->P &= ~C_FLAG; + if ((R->P & V_FLAG) && w < 0x80) R->P &= ~V_FLAG; + } + else { + R->P |= C_FLAG; + if ((R->P&V_FLAG) && w >= 0x180) R->P &= ~V_FLAG; + } + } + R->A = (unsigned char)w; + R->P = (R->P & ~(Z_FLAG | N_FLAG)) | (R->A >= 0x80 ? N_FLAG : 0) | (R->A == 0 ? Z_FLAG : 0); +} /* SBCinstruction */ + /** Reset6502() **********************************************/ /** This function can be used to reset the registers before **/ /** starting execution with Run6502(). It sets registers to **/ diff --git a/common/memorymap.c b/common/memorymap.c index b15feb4..75d3d25 100644 --- a/common/memorymap.c +++ b/common/memorymap.c @@ -19,6 +19,7 @@ static uint32 programRomSize; static BOOL dma_finished = FALSE; static BOOL timer_shot = FALSE; +static BOOL isMAGNUM = FALSE; static void check_irq(void) { @@ -60,7 +61,7 @@ void memorymap_reset(void) // 96KB -> 80KB // 112KB -> 96KB // 128KB -> 112KB (max in theory) - // 512KB -- 'Journey to the West' isn't supported + // 512KB -- 'Journey to the West' is supported! (MAGNUM cartridge) upperRomBank = programRom + (programRomSize - 0x4000); memset(lowerRam, 0x00, 0x2000); @@ -110,73 +111,82 @@ uint8 memorymap_registers_read(uint32 Addr) return data; } -// General Purpose DMA +// General Purpose DMA (for 'Journey to the West') // Pass only the first test (WaTest.bin from Wataroo) -//typedef struct { -// uint16 caddr; -// uint16 vaddr; -// BOOL cpu2vram; -// uint16 length; -//} GENERIC_DMA; -//static GENERIC_DMA dma; -// -//static void dma_write(uint32 Addr, uint8 Value) -//{ -// switch (Addr & 0x1fff) { -// case 0x08: -// dma.caddr = Value; -// printf("CBUS LO (%x)\n", Value); -// break; -// case 0x09: -// dma.caddr |= (Value << 8); -// printf("CBUS HI %x (%x)\n", dma.caddr, Value); -// break; -// case 0x0a: -// dma.vaddr = Value; -// printf("VBUS LO (%x)\n", Value); -// break; -// case 0x0b: -// dma.vaddr |= (Value << 8); -// dma.vaddr &= 0x1fff; -// dma.cpu2vram = ((Value >> 6) & 1) == 1; -// printf("VBUS HI %x %x (%x)\n", dma.vaddr, dma.cpu2vram, Value); -// break; -// case 0x0c: -// dma.length = Value ? Value * 16 : 4096; -// printf("LEN %x\n", dma.length); -// break; -// case 0x0d: -// printf("Request %x\n", Value); -// if (Value & 0x80) { -// int i; -// printf("Transfer\n"); -// for (i = 0; i < dma.length; i++) { -// if (dma.cpu2vram) { -// upperRam[dma.vaddr + i] = Rd6502(dma.caddr + i); -// } -// else { -// Wr6502(dma.caddr + i, upperRam[dma.vaddr + i]); -// } -// } -// } -// else if ((Value & 0x80) == 0) { -// -// } -// break; -// } -//} +typedef struct { + uint16 caddr; + uint16 vaddr; + BOOL cpu2vram; + uint16 length; +} GENERIC_DMA; +static GENERIC_DMA dma; + +static void dma_write(uint32 Addr, uint8 Value) +{ + switch (Addr & 0x1fff) { + case 0x08: // CBUS LO + dma.caddr = Value; + break; + case 0x09: // CBUS HI + dma.caddr |= (Value << 8); + break; + case 0x0a: // VBUS LO + dma.vaddr = Value; + break; + case 0x0b: // VBUS HI + dma.vaddr |= (Value << 8); + dma.vaddr &= 0x1fff; + dma.cpu2vram = ((Value >> 6) & 1) == 1; + break; + case 0x0c: // LEN + dma.length = Value ? Value * 16 : 4096; + break; + case 0x0d: // Request + if (Value & 0x80) { + int i; + for (i = 0; i < dma.length; i++) { + if (dma.cpu2vram) { + upperRam[dma.vaddr + i] = Rd6502(dma.caddr + i); + } + else { + Wr6502(dma.caddr + i, upperRam[dma.vaddr + i]); + } + } + } + break; + } +} + +static void update_lowerRomBank(void) +{ + uint32 bankOffset = 0; + if (isMAGNUM) { + bankOffset = (((regs[BANK] & 0x20) << 9) | ((regs[0x21] & 0xf) << 15)); + } + else { + bankOffset = ((regs[BANK] & 0xe0) << 9); + } + lowerRomBank = programRom + bankOffset % programRomSize; +} void memorymap_registers_write(uint32 Addr, uint8 Value) { regs[Addr & 0x1fff] = Value; switch (Addr & 0x1fff) { + case 0x21: + // MAGNUM cartridge && Output (Link Port Data Direction) + if (isMAGNUM && regs[0x22] == 0) { + update_lowerRomBank(); + check_irq(); + } + break; case 0x23: timer_write(Value); break; case 0x26: - lowerRomBank = programRom + ((Value & 0xe0) << 9) % programRomSize; + update_lowerRomBank(); check_irq(); - return; + break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: sound_wave_write(((Addr & 0x4) >> 2), Addr & 3, Value); @@ -193,9 +203,9 @@ void memorymap_registers_write(uint32 Addr, uint8 Value) case 0x2a: sound_noise_write(Addr & 0x07, Value); break; - //case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: - // dma_write(Addr, Value); - // break; + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: + dma_write(Addr, Value); + break; } } @@ -255,6 +265,7 @@ BOOL memorymap_load(const uint8 *rom, uint32 size) } programRomSize = size; programRom = rom; + isMAGNUM = size > 131072; return TRUE; } diff --git a/common/sound.c b/common/sound.c index a26d0d9..509f01b 100644 --- a/common/sound.c +++ b/common/sound.c @@ -109,7 +109,7 @@ void sound_stream_update(uint8 *stream, uint32 len) if (m_noise.right) *right += s; m_noise.pos += m_noise.step; - if (m_noise.pos >= 1.0) { + while (m_noise.pos >= 1.0) { // if/while difference - Pacific Battle // LFSR: x^2 + x + 1 uint16 feedback; m_noise.value = m_noise.state & 1; @@ -169,6 +169,16 @@ void sound_wave_write(int which, int offset, uint8 data) // if size == 0 then channel->size == 0 channel->size = (uint16)((real)SV_SAMPLE_RATE * ((size + 1) << 5) / UNSCALED_CLOCK); channel->pos = 0; +#ifndef SV_DISABLE_SUPER_DUPER_WAVE + // Popo Team + if (channel->count != 0 || ch[which].size == 0 || channel->size == 0) { + ch[which].size = channel->size; + if (channel->count == 0) + ch[which].pos = 0; + } +#else + memcpy(&ch[which], channel, sizeof(ch[which])); +#endif } break; case 2: @@ -177,7 +187,10 @@ void sound_wave_write(int which, int offset, uint8 data) channel->volume = data & 0x0f; #ifndef SV_DISABLE_SUPER_DUPER_WAVE if (!channel->on || ch[which].size == 0 || channel->size == 0) { + uint16 pos = ch[which].pos; memcpy(&ch[which], channel, sizeof(ch[which])); + if (channel->count != 0) // Journey to the West + ch[which].pos = pos; } #else memcpy(&ch[which], channel, sizeof(ch[which])); @@ -185,6 +198,9 @@ void sound_wave_write(int which, int offset, uint8 data) break; case 3: channel->count = data + 1; +#ifndef SV_DISABLE_SUPER_DUPER_WAVE + ch[which].size = channel->size; // Sonny Xpress! +#endif break; } } diff --git a/common/supervision.h b/common/supervision.h index 1103939..9055c9c 100644 --- a/common/supervision.h +++ b/common/supervision.h @@ -11,7 +11,7 @@ extern "C" { #endif -#define SV_CORE_VERSION 0x01000003U +#define SV_CORE_VERSION 0x01000004U #define SV_CORE_VERSION_MAJOR ((SV_CORE_VERSION >> 24) & 0xFF) #define SV_CORE_VERSION_MINOR ((SV_CORE_VERSION >> 12) & 0xFFF) #define SV_CORE_VERSION_PATCH ((SV_CORE_VERSION >> 0) & 0xFFF) diff --git a/common/watara.c b/common/watara.c index dfa9a96..f5c8d71 100644 --- a/common/watara.c +++ b/common/watara.c @@ -91,6 +91,8 @@ void supervision_exec_ex(uint16 *backbuffer, int16 backbufferWidth) scan = regs[XPOS] / 4 + regs[YPOS] * 0x30; innerx = regs[XPOS] & 3; size = regs[XSIZE]; // regs[XSIZE] <= SV_W + if (size > SV_W) + size = SV_W; // 192: Chimera, Matta Blatta, Tennis Pro '92 for (i = 0; i < SV_H; i++) { if (scan >= 0x1fe0)