mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
optimizations, fixes, hacks, psp, ...
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@295 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
8022f53da6
commit
b542be4686
37 changed files with 928 additions and 548 deletions
10
Pico/Draw.c
10
Pico/Draw.c
|
@ -66,7 +66,7 @@ void blockcpy_or(void *dst, void *src, size_t n, int pat)
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef _ASM_DRAW_C_MIPS
|
||||
#ifdef _ASM_DRAW_C_AMIPS
|
||||
int TileNorm(int sx,int addr,int pal);
|
||||
int TileFlip(int sx,int addr,int pal);
|
||||
#else
|
||||
|
@ -1127,8 +1127,7 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh)
|
|||
#ifndef _ASM_DRAW_C
|
||||
static void BackFill(int reg7, int sh)
|
||||
{
|
||||
unsigned int back=0;
|
||||
unsigned int *pd=NULL,*end=NULL;
|
||||
unsigned int back;
|
||||
|
||||
// Start with a blank scanline (background colour):
|
||||
back=reg7&0x3f;
|
||||
|
@ -1136,10 +1135,7 @@ static void BackFill(int reg7, int sh)
|
|||
back|=back<<8;
|
||||
back|=back<<16;
|
||||
|
||||
pd= (unsigned int *)(HighCol+8);
|
||||
end=(unsigned int *)(HighCol+8+320);
|
||||
|
||||
do { pd[0]=pd[1]=pd[2]=pd[3]=back; pd+=4; } while (pd<end);
|
||||
memset32((int *)(HighCol+8), back, 320/4);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
10
Pico/Draw2.c
10
Pico/Draw2.c
|
@ -485,8 +485,7 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
|
|||
#ifndef _ASM_DRAW_C
|
||||
static void BackFillFull(int reg7)
|
||||
{
|
||||
unsigned int back, i;
|
||||
unsigned int *p=(unsigned int *)PicoDraw2FB;
|
||||
unsigned int back;
|
||||
|
||||
// Start with a background color:
|
||||
// back=PicoCramHigh[reg7&0x3f];
|
||||
|
@ -494,12 +493,7 @@ static void BackFillFull(int reg7)
|
|||
back|=back<<8;
|
||||
back|=back<<16;
|
||||
|
||||
for(i = LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/16; i; i--) {
|
||||
*p++ = back; // do 16 pixels per iteration
|
||||
*p++ = back;
|
||||
*p++ = back;
|
||||
*p++ = back;
|
||||
}
|
||||
memset32((int *)PicoDraw2FB, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -334,9 +334,12 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
|
|||
log_io(a, 8, 0);
|
||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
|
||||
|
||||
d=OtherRead16(a&~1, 8); if ((a&1)==0) d>>=8;
|
||||
if ((a&0xe700e0)==0xc00000) // VDP
|
||||
d=PicoVideoRead(a);
|
||||
else d=OtherRead16(a&~1, 8);
|
||||
if ((a&1)==0) d>>=8;
|
||||
|
||||
|
||||
end:
|
||||
#ifdef __debug_io
|
||||
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
|
||||
#endif
|
||||
|
@ -370,7 +373,9 @@ PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
|
|||
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
|
||||
log_io(a, 16, 0);
|
||||
|
||||
d = OtherRead16(a, 16);
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
d = PicoVideoRead(a);
|
||||
else d = OtherRead16(a, 16);
|
||||
|
||||
end:
|
||||
#ifdef __debug_io
|
||||
|
@ -404,7 +409,9 @@ PICO_INTERNAL_ASM u32 PicoRead32(u32 a)
|
|||
if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
|
||||
log_io(a, 32, 0);
|
||||
|
||||
d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
|
||||
else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
|
||||
|
||||
end:
|
||||
#ifdef __debug_io
|
||||
|
@ -454,6 +461,7 @@ void PicoWrite16(u32 a,u16 d)
|
|||
log_io(a, 16, 1);
|
||||
|
||||
a&=0xfffffe;
|
||||
if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
|
||||
OtherWrite16(a,d);
|
||||
}
|
||||
|
||||
|
@ -476,6 +484,14 @@ static void PicoWrite32(u32 a,u32 d)
|
|||
log_io(a, 32, 1);
|
||||
|
||||
a&=0xfffffe;
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
{
|
||||
// VDP:
|
||||
PicoVideoWrite(a, (u16)(d>>16));
|
||||
PicoVideoWrite(a+2,(u16)d);
|
||||
return;
|
||||
}
|
||||
|
||||
OtherWrite16(a, (u16)(d>>16));
|
||||
OtherWrite16(a+2,(u16)d);
|
||||
}
|
||||
|
@ -660,10 +676,6 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
|
|||
{
|
||||
u8 ret = 0;
|
||||
|
||||
#ifndef _USE_DRZ80
|
||||
if (a<0x4000) return Pico.zram[a&0x1fff];
|
||||
#endif
|
||||
|
||||
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
|
||||
{
|
||||
if (PicoOpt&1) ret = (u8) YM2612Read();
|
||||
|
@ -681,10 +693,8 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef _USE_DRZ80
|
||||
// should not be needed || dprintf("z80_read RAM");
|
||||
// should not be needed, cores should be able to access RAM themselves
|
||||
if (a<0x4000) return Pico.zram[a&0x1fff];
|
||||
#endif
|
||||
|
||||
elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);
|
||||
return ret;
|
||||
|
@ -696,10 +706,6 @@ PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a)
|
|||
PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
|
||||
#endif
|
||||
{
|
||||
#ifndef _USE_DRZ80
|
||||
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
|
||||
#endif
|
||||
|
||||
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
|
||||
{
|
||||
if(PicoOpt&1) emustatus|=YM2612Write(a, data) & 1;
|
||||
|
@ -730,10 +736,8 @@ PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef _USE_DRZ80
|
||||
// should not be needed, drZ80 knows how to access RAM itself || dprintf("z80_write RAM @ %08x", lr);
|
||||
// should not be needed
|
||||
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
|
||||
#endif
|
||||
|
||||
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
|
||||
}
|
||||
|
|
|
@ -386,17 +386,14 @@ m_read8_misc2:
|
|||
cmp r2, #0x4000
|
||||
mvnne r0, #0
|
||||
bxne lr @ invalid
|
||||
.if EXTERNAL_YM2612
|
||||
ldr r1, =PicoOpt
|
||||
ldr r1, [r1]
|
||||
tst r1, #1
|
||||
beq m_read8_fake_ym2612
|
||||
tst r1, #0x200
|
||||
beq YM2612Read_
|
||||
b YM2612Read_940
|
||||
.else
|
||||
b YM2612Read_
|
||||
.endif
|
||||
|
||||
ldrne r1, =ym2612_st
|
||||
ldrne r1, [r1]
|
||||
ldrneb r0, [r1, #0x11] @ ym2612_st->status
|
||||
bxne lr
|
||||
|
||||
m_read8_fake_ym2612:
|
||||
ldr r3, =(Pico+0x22200)
|
||||
|
|
|
@ -72,9 +72,9 @@ static
|
|||
void z80WriteBusReq(u32 d)
|
||||
{
|
||||
d&=1; d^=1;
|
||||
//if (Pico.m.scanline != -1)
|
||||
{
|
||||
if(!d) {
|
||||
if (!d)
|
||||
{
|
||||
// this is for a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)
|
||||
if (Pico.m.z80Run) {
|
||||
int lineCycles;
|
||||
|
@ -85,7 +85,7 @@ void z80WriteBusReq(u32 d)
|
|||
if (lineCycles > 0) { // && lineCycles <= 488) {
|
||||
//dprintf("zrun: %i/%i cycles", lineCycles, (lineCycles>>1)-(lineCycles>>5));
|
||||
lineCycles=(lineCycles>>1)-(lineCycles>>5);
|
||||
z80_run(lineCycles);
|
||||
z80_run_nr(lineCycles);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -136,10 +136,6 @@ u32 OtherRead16(u32 a, int realsize)
|
|||
goto end;
|
||||
}
|
||||
|
||||
#ifndef _ASM_MEMORY_C
|
||||
if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }
|
||||
#endif
|
||||
|
||||
d = OtherRead16End(a, realsize);
|
||||
|
||||
end:
|
||||
|
@ -204,7 +200,6 @@ static
|
|||
#endif
|
||||
void OtherWrite16(u32 a,u32 d)
|
||||
{
|
||||
if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }
|
||||
if (a==0xa11100) { z80WriteBusReq(d>>8); return; }
|
||||
if (a==0xa11200) { dprintf("write z80reset: %04x", d); if(!(d&0x100)) z80_reset(); return; }
|
||||
if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports
|
||||
|
|
|
@ -425,8 +425,10 @@ m_read8_z80_misc:
|
|||
andi $t0, 1
|
||||
beqz $t0, m_read8_fake_ym2612
|
||||
lui $t0, %hi(Pico+0x22208)
|
||||
j YM2612Read_
|
||||
nop
|
||||
lui $t0, %hi(ym2612_st)
|
||||
lw $t0, %lo(ym2612_st)($t0)
|
||||
jr $ra
|
||||
lb $v0, 0x11($t0)
|
||||
|
||||
m_read8_fake_ym2612:
|
||||
lb $v0, %lo(Pico+0x22208)($t0) # Pico.m.rotate
|
||||
|
|
|
@ -353,7 +353,7 @@ PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count)
|
|||
*dest++ = (src_[0] << 8) | src_[1];
|
||||
}
|
||||
|
||||
|
||||
#ifndef _ASM_MISC_C_AMIPS
|
||||
PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)
|
||||
{
|
||||
intblock *bd = (intblock *) dest, *bs = (intblock *) src;
|
||||
|
@ -376,5 +376,7 @@ PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)
|
|||
while (count--)
|
||||
*dest++ = c;
|
||||
}
|
||||
void memset32_uncached(int *dest, int c, int count) { memset32(dest, c, count); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
171
Pico/Misc_amips.s
Normal file
171
Pico/Misc_amips.s
Normal file
|
@ -0,0 +1,171 @@
|
|||
# vim:filetype=mips
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl memset32 # int *dest, int c, int count
|
||||
|
||||
memset32:
|
||||
ms32_aloop:
|
||||
andi $t0, $a0, 0x3f
|
||||
beqz $t0, ms32_bloop_prep
|
||||
nop
|
||||
sw $a1, 0($a0)
|
||||
addiu $a2, -1
|
||||
beqz $a2, ms32_return
|
||||
addiu $a0, 4
|
||||
j ms32_aloop
|
||||
nop
|
||||
|
||||
ms32_bloop_prep:
|
||||
srl $t0, $a2, 4 # we will do 64 bytes per iteration (cache line)
|
||||
beqz $t0, ms32_bloop_end
|
||||
|
||||
ms32_bloop:
|
||||
addiu $t0, -1
|
||||
cache 0x18, ($a0) # create dirty exclusive
|
||||
sw $a1, 0x00($a0)
|
||||
sw $a1, 0x04($a0)
|
||||
sw $a1, 0x08($a0)
|
||||
sw $a1, 0x0c($a0)
|
||||
sw $a1, 0x10($a0)
|
||||
sw $a1, 0x14($a0)
|
||||
sw $a1, 0x18($a0)
|
||||
sw $a1, 0x1c($a0)
|
||||
sw $a1, 0x20($a0)
|
||||
sw $a1, 0x24($a0)
|
||||
sw $a1, 0x28($a0)
|
||||
sw $a1, 0x2c($a0)
|
||||
sw $a1, 0x30($a0)
|
||||
sw $a1, 0x34($a0)
|
||||
sw $a1, 0x38($a0)
|
||||
sw $a1, 0x3c($a0)
|
||||
bnez $t0, ms32_bloop
|
||||
addiu $a0, 0x40
|
||||
|
||||
ms32_bloop_end:
|
||||
andi $a2, $a2, 0x0f
|
||||
beqz $a2, ms32_return
|
||||
|
||||
ms32_cloop:
|
||||
addiu $a2, -1
|
||||
sw $a1, 0($a0)
|
||||
bnez $a2, ms32_cloop
|
||||
addiu $a0, 4
|
||||
|
||||
ms32_return:
|
||||
jr $ra
|
||||
nop
|
||||
|
||||
|
||||
.globl memset32_uncached # int *dest, int c, int count
|
||||
|
||||
memset32_uncached:
|
||||
srl $t0, $a2, 3 # we will do 32 bytes per iteration
|
||||
beqz $t0, ms32u_bloop_end
|
||||
|
||||
ms32u_bloop:
|
||||
addiu $t0, -1
|
||||
sw $a1, 0x00($a0)
|
||||
sw $a1, 0x04($a0)
|
||||
sw $a1, 0x08($a0)
|
||||
sw $a1, 0x0c($a0)
|
||||
sw $a1, 0x10($a0)
|
||||
sw $a1, 0x14($a0)
|
||||
sw $a1, 0x18($a0)
|
||||
sw $a1, 0x1c($a0)
|
||||
bnez $t0, ms32u_bloop
|
||||
addiu $a0, 0x20
|
||||
|
||||
ms32u_bloop_end:
|
||||
andi $a2, $a2, 0x0f
|
||||
beqz $a2, ms32u_return
|
||||
|
||||
ms32u_cloop:
|
||||
addiu $a2, -1
|
||||
sw $a1, 0($a0)
|
||||
bnez $a2, ms32u_cloop
|
||||
addiu $a0, 4
|
||||
|
||||
ms32u_return:
|
||||
jr $ra
|
||||
nop
|
||||
|
||||
|
||||
.globl memcpy32 # int *dest, int *src, int count
|
||||
|
||||
memcpy32:
|
||||
mc32_aloop:
|
||||
andi $t0, $a0, 0x3f
|
||||
beqz $t0, mc32_bloop_prep
|
||||
nop
|
||||
lw $t1, 0($a1)
|
||||
addiu $a2, -1
|
||||
sw $t1, 0($a0)
|
||||
beqz $a2, mc32_return
|
||||
addiu $a0, 4
|
||||
j mc32_aloop
|
||||
addiu $a1, 4
|
||||
|
||||
mc32_bloop_prep:
|
||||
srl $t0, $a2, 4 # we will do 64 bytes per iteration (cache line)
|
||||
beqz $t0, mc32_bloop_end
|
||||
|
||||
mc32_bloop:
|
||||
addiu $t0, -1
|
||||
cache 0x18, ($a0) # create dirty exclusive
|
||||
lw $t2, 0x00($a1)
|
||||
lw $t3, 0x04($a1)
|
||||
lw $t4, 0x08($a1)
|
||||
lw $t5, 0x0c($a1)
|
||||
lw $t6, 0x10($a1)
|
||||
lw $t7, 0x14($a1)
|
||||
lw $t8, 0x18($a1)
|
||||
lw $t9, 0x1c($a1)
|
||||
sw $t2, 0x00($a0)
|
||||
sw $t3, 0x04($a0)
|
||||
sw $t4, 0x08($a0)
|
||||
sw $t5, 0x0c($a0)
|
||||
sw $t6, 0x10($a0)
|
||||
sw $t7, 0x14($a0)
|
||||
sw $t8, 0x18($a0)
|
||||
sw $t9, 0x1c($a0)
|
||||
lw $t2, 0x20($a1)
|
||||
lw $t3, 0x24($a1)
|
||||
lw $t4, 0x28($a1)
|
||||
lw $t5, 0x2c($a1)
|
||||
lw $t6, 0x30($a1)
|
||||
lw $t7, 0x34($a1)
|
||||
lw $t8, 0x38($a1)
|
||||
lw $t9, 0x3c($a1)
|
||||
sw $t2, 0x20($a0)
|
||||
sw $t3, 0x24($a0)
|
||||
sw $t4, 0x28($a0)
|
||||
sw $t5, 0x2c($a0)
|
||||
sw $t6, 0x30($a0)
|
||||
sw $t7, 0x34($a0)
|
||||
sw $t8, 0x38($a0)
|
||||
sw $t9, 0x3c($a0)
|
||||
addiu $a0, 0x40
|
||||
bnez $t0, mc32_bloop
|
||||
addiu $a1, 0x40
|
||||
|
||||
mc32_bloop_end:
|
||||
andi $a2, $a2, 0x0f
|
||||
beqz $a2, mc32_return
|
||||
|
||||
mc32_cloop:
|
||||
lw $t1, 0($a1)
|
||||
addiu $a2, -1
|
||||
addiu $a1, 4
|
||||
sw $t1, 0($a0)
|
||||
bnez $a2, mc32_cloop
|
||||
addiu $a0, 4
|
||||
|
||||
mc32_return:
|
||||
jr $ra
|
||||
nop
|
||||
|
|
@ -297,10 +297,10 @@ static void PicoRunZ80Simple(int line_from, int line_to)
|
|||
if ((line == 224 || line == line_sample) && PsndOut) getSamples(line);
|
||||
if (line == 32 && PsndOut) emustatus &= ~1;
|
||||
if (line >= line_from_r && line < line_to_r)
|
||||
z80_run(228);
|
||||
z80_run_nr(228);
|
||||
}
|
||||
} else if (line_to_r-line_from_r > 0) {
|
||||
z80_run(228*(line_to_r-line_from_r));
|
||||
z80_run_nr(228*(line_to_r-line_from_r));
|
||||
// samples will be taken by caller
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,9 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
|
|||
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }
|
||||
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
|
||||
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))
|
||||
|
||||
#define SekInterrupt(i) PicoCpuCM68k.irq=i
|
||||
|
||||
#ifdef EMU_M68K
|
||||
#define EMU_CORE_DEBUG
|
||||
#endif
|
||||
|
@ -56,7 +59,7 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
|
|||
|
||||
#ifdef EMU_F68K
|
||||
#include "../cpu/fame/fame.h"
|
||||
M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
||||
extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
||||
#define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter
|
||||
#define SekCyclesLeft \
|
||||
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
||||
|
@ -77,6 +80,9 @@ M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
|||
if (x) { PicoCpuFS68k.execinfo |= FM68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \
|
||||
}
|
||||
#define SekShouldInterrupt fm68k_would_interrupt()
|
||||
|
||||
#define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq
|
||||
|
||||
#ifdef EMU_M68K
|
||||
#define EMU_CORE_DEBUG
|
||||
#endif
|
||||
|
@ -106,6 +112,14 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
|
|||
else PicoCpuMS68k.stopped=0; \
|
||||
}
|
||||
#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)
|
||||
|
||||
#define SekInterrupt(irq) {
|
||||
void *oldcontext = m68ki_cpu_p; \
|
||||
m68k_set_context(&PicoCpuMM68k); \
|
||||
m68k_set_irq(irq); \
|
||||
m68k_set_context(oldcontext); \
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -148,6 +162,46 @@ extern int SekCycleAimS68k;
|
|||
#define SekEndRun(c)
|
||||
#endif
|
||||
|
||||
// ----------------------- Z80 CPU -----------------------
|
||||
|
||||
#if defined(_USE_MZ80)
|
||||
#include "../../cpu/mz80/mz80.h"
|
||||
|
||||
#define z80_run(cycles) mz80_run(cycles)
|
||||
#define z80_run_nr(cycles) mz80_run(cycles)
|
||||
#define z80_int() mz80int(0)
|
||||
#define z80_resetCycles() mz80GetElapsedTicks(1)
|
||||
|
||||
#elif defined(_USE_DRZ80)
|
||||
#include "../../cpu/DrZ80/drz80.h"
|
||||
|
||||
extern struct DrZ80 drZ80;
|
||||
|
||||
#define z80_run(cycles) ((cycles) - DrZ80Run(&drZ80, cycles))
|
||||
#define z80_run_nr(cycles) DrZ80Run(&drZ80, cycles)
|
||||
#define z80_int() { \
|
||||
drZ80.z80irqvector = 0xFF; /* default IRQ vector RST opcode */ \
|
||||
drZ80.Z80_IRQ = 1; \
|
||||
}
|
||||
#define z80_resetCycles()
|
||||
|
||||
#elif defined(_USE_CZ80)
|
||||
#include "../../cpu/cz80/cz80.h"
|
||||
|
||||
#define z80_run(cycles) Cz80_Exec(&CZ80, cycles)
|
||||
#define z80_run_nr(cycles) Cz80_Exec(&CZ80, cycles)
|
||||
#define z80_int() Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE)
|
||||
#define z80_resetCycles()
|
||||
|
||||
#else
|
||||
|
||||
#define z80_run(cycles) (cycles)
|
||||
#define z80_run_nr(cycles)
|
||||
#define z80_int()
|
||||
#define z80_resetCycles()
|
||||
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
extern int PicoMCD;
|
||||
|
@ -358,7 +412,6 @@ PICO_INTERNAL int PicoFrameMCD(void);
|
|||
// Sek.c
|
||||
PICO_INTERNAL int SekInit(void);
|
||||
PICO_INTERNAL int SekReset(void);
|
||||
PICO_INTERNAL int SekInterrupt(int irq);
|
||||
PICO_INTERNAL void SekState(int *data);
|
||||
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
||||
|
||||
|
@ -398,9 +451,6 @@ PICO_INTERNAL int PsndRender(int offset, int length);
|
|||
PICO_INTERNAL void PsndClear(void);
|
||||
// z80 functionality wrappers
|
||||
PICO_INTERNAL void z80_init(void);
|
||||
PICO_INTERNAL void z80_resetCycles(void);
|
||||
PICO_INTERNAL void z80_int(void);
|
||||
PICO_INTERNAL int z80_run(int cycles);
|
||||
PICO_INTERNAL void z80_pack(unsigned char *data);
|
||||
PICO_INTERNAL void z80_unpack(unsigned char *data);
|
||||
PICO_INTERNAL void z80_reset(void);
|
||||
|
|
27
Pico/Sek.c
27
Pico/Sek.c
|
@ -165,33 +165,6 @@ PICO_INTERNAL int SekReset()
|
|||
}
|
||||
|
||||
|
||||
PICO_INTERNAL int SekInterrupt(int irq)
|
||||
{
|
||||
#ifdef EMU_CORE_DEBUG
|
||||
{
|
||||
extern int dbg_irq_level;
|
||||
dbg_irq_level=irq;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef EMU_C68K
|
||||
PicoCpuCM68k.irq=irq;
|
||||
#endif
|
||||
#ifdef EMU_M68K
|
||||
{
|
||||
void *oldcontext = m68ki_cpu_p;
|
||||
m68k_set_context(&PicoCpuMM68k);
|
||||
m68k_set_irq(irq); // raise irq (gets lowered after taken or must be done in ack)
|
||||
m68k_set_context(oldcontext);
|
||||
}
|
||||
#endif
|
||||
#ifdef EMU_F68K
|
||||
PicoCpuFM68k.interrupts[0]=irq;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// data must be word aligned
|
||||
PICO_INTERNAL void SekState(int *data)
|
||||
{
|
||||
|
|
|
@ -164,8 +164,12 @@ static int g_read_offs = 0;
|
|||
g_read_offs += len;
|
||||
|
||||
#define CHECKED_READ2(len2,data) \
|
||||
if (len2 != len) R_ERROR_RETURN("unexpected len, wanted " #len2); \
|
||||
CHECKED_READ(len2, data)
|
||||
if (len2 != len) { \
|
||||
printf("unexpected len %i, wanted %i (%s)", len, len2, #len2); \
|
||||
if (len > len2) R_ERROR_RETURN("failed."); \
|
||||
/* else read anyway and hope for the best.. */ \
|
||||
} \
|
||||
CHECKED_READ(len, data)
|
||||
|
||||
#define CHECKED_READ_BUFF(buff) CHECKED_READ2(sizeof(buff), &buff);
|
||||
|
||||
|
|
206
Pico/cd/Memory.c
206
Pico/cd/Memory.c
|
@ -454,38 +454,62 @@ static u32 PicoReadM68k8(u32 a)
|
|||
{
|
||||
u32 d=0;
|
||||
|
||||
if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram
|
||||
|
||||
a&=0xffffff;
|
||||
|
||||
if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios
|
||||
|
||||
// prg RAM
|
||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||
switch (a >> 17)
|
||||
{
|
||||
case 0x00>>1: // BIOS: 000000 - 020000
|
||||
d = *(u8 *)(Pico_mcd->bios+(a^1));
|
||||
break;
|
||||
case 0x02>>1: // prg RAM
|
||||
if ((Pico_mcd->m.busreq&3)!=1) {
|
||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
||||
d = *(prg_bank+((a^1)&0x1ffff));
|
||||
goto end;
|
||||
}
|
||||
|
||||
// word RAM
|
||||
if ((a&0xfc0000)==0x200000) {
|
||||
break;
|
||||
case 0x20>>1: // word RAM: 200000 - 220000
|
||||
wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);
|
||||
a &= 0x1ffff;
|
||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?
|
||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||
d = Pico_mcd->word_ram1M[bank][a^1];
|
||||
} else {
|
||||
// allow access in any mode, like Gens does
|
||||
d = Pico_mcd->word_ram2M[a^1];
|
||||
}
|
||||
wrdprintf("ret = %02x", (u8)d);
|
||||
break;
|
||||
case 0x22>>1: // word RAM: 220000 - 240000
|
||||
wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);
|
||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?
|
||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||
if (a >= 0x220000)
|
||||
a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged
|
||||
else a &= 0x1ffff;
|
||||
d = Pico_mcd->word_ram1M[bank][a^1];
|
||||
} else {
|
||||
// allow access in any mode, like Gens does
|
||||
d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];
|
||||
}
|
||||
wrdprintf("ret = %02x", (u8)d);
|
||||
goto end;
|
||||
break;
|
||||
case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:
|
||||
case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:
|
||||
case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:
|
||||
case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:
|
||||
// VDP
|
||||
if ((a&0xe700e0)==0xc00000) {
|
||||
d=PicoVideoRead(a);
|
||||
if ((a&1)==0) d>>=8;
|
||||
}
|
||||
|
||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
|
||||
|
||||
break;
|
||||
case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:
|
||||
case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:
|
||||
case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:
|
||||
case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:
|
||||
// RAM:
|
||||
d = *(u8 *)(Pico.ram+((a^1)&0xffff));
|
||||
break;
|
||||
default:
|
||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); break; } // Z80 Ram
|
||||
if ((a&0xffffc0)==0xa12000)
|
||||
rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);
|
||||
|
||||
|
@ -493,8 +517,9 @@ static u32 PicoReadM68k8(u32 a)
|
|||
|
||||
if ((a&0xffffc0)==0xa12000)
|
||||
rdprintf("ret = %02x", (u8)d);
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
#ifdef __debug_io
|
||||
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
|
||||
|
@ -517,38 +542,61 @@ static u32 PicoReadM68k16(u32 a)
|
|||
{
|
||||
u32 d=0;
|
||||
|
||||
if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios
|
||||
|
||||
// prg RAM
|
||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||
switch (a >> 17)
|
||||
{
|
||||
case 0x00>>1: // BIOS: 000000 - 020000
|
||||
d = *(u16 *)(Pico_mcd->bios+a);
|
||||
break;
|
||||
case 0x02>>1: // prg RAM
|
||||
if ((Pico_mcd->m.busreq&3)!=1) {
|
||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
||||
wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);
|
||||
d = *(u16 *)(prg_bank+(a&0x1fffe));
|
||||
wrdprintf("ret = %04x", d);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// word RAM
|
||||
if ((a&0xfc0000)==0x200000) {
|
||||
break;
|
||||
case 0x20>>1: // word RAM: 200000 - 220000
|
||||
wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);
|
||||
a &= 0x1fffe;
|
||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?
|
||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);
|
||||
} else {
|
||||
// allow access in any mode, like Gens does
|
||||
d = *(u16 *)(Pico_mcd->word_ram2M+a);
|
||||
}
|
||||
wrdprintf("ret = %04x", d);
|
||||
break;
|
||||
case 0x22>>1: // word RAM: 220000 - 240000
|
||||
wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);
|
||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?
|
||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||
if (a >= 0x220000)
|
||||
a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged
|
||||
else a &= 0x1fffe;
|
||||
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);
|
||||
} else {
|
||||
// allow access in any mode, like Gens does
|
||||
d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));
|
||||
}
|
||||
wrdprintf("ret = %04x", d);
|
||||
goto end;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:
|
||||
case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:
|
||||
case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:
|
||||
case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:
|
||||
// VDP
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
d=PicoVideoRead(a);
|
||||
break;
|
||||
case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:
|
||||
case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:
|
||||
case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:
|
||||
case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:
|
||||
// RAM:
|
||||
d=*(u16 *)(Pico.ram+(a&0xfffe));
|
||||
break;
|
||||
default:
|
||||
if ((a&0xffffc0)==0xa12000)
|
||||
rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);
|
||||
|
||||
|
@ -556,8 +604,9 @@ static u32 PicoReadM68k16(u32 a)
|
|||
|
||||
if ((a&0xffffc0)==0xa12000)
|
||||
rdprintf("ret = %04x", d);
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
#ifdef __debug_io
|
||||
dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
|
||||
|
@ -580,43 +629,70 @@ static u32 PicoReadM68k32(u32 a)
|
|||
{
|
||||
u32 d=0;
|
||||
|
||||
if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios
|
||||
|
||||
// prg RAM
|
||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||
switch (a >> 17)
|
||||
{
|
||||
case 0x00>>1: { // BIOS: 000000 - 020000
|
||||
u16 *pm=(u16 *)(Pico_mcd->bios+a);
|
||||
d = (pm[0]<<16)|pm[1];
|
||||
break;
|
||||
}
|
||||
case 0x02>>1: // prg RAM
|
||||
if ((Pico_mcd->m.busreq&3)!=1) {
|
||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
||||
u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));
|
||||
d = (pm[0]<<16)|pm[1];
|
||||
goto end;
|
||||
}
|
||||
|
||||
// word RAM
|
||||
if ((a&0xfc0000)==0x200000) {
|
||||
break;
|
||||
case 0x20>>1: // word RAM: 200000 - 220000
|
||||
wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);
|
||||
a&=0x1fffe;
|
||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?
|
||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||
if (a >= 0x220000) { // cell arranged
|
||||
u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+a);
|
||||
d = (pm[0]<<16)|pm[1];
|
||||
} else {
|
||||
// allow access in any mode, like Gens does
|
||||
u16 *pm=(u16 *)(Pico_mcd->word_ram2M+a);
|
||||
d = (pm[0]<<16)|pm[1];
|
||||
}
|
||||
wrdprintf("ret = %08x", d);
|
||||
break;
|
||||
case 0x22>>1: // word RAM: 220000 - 240000
|
||||
wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);
|
||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode, cell arranged?
|
||||
u32 a1, a2;
|
||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||
a1 = (a&2) | (cell_map(a >> 2) << 2);
|
||||
if (a&2) a2 = cell_map((a+2) >> 2) << 2;
|
||||
else a2 = a1 + 2;
|
||||
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;
|
||||
d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);
|
||||
} else {
|
||||
u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];
|
||||
}
|
||||
} else {
|
||||
// allow access in any mode, like Gens does
|
||||
u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];
|
||||
u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));
|
||||
d = (pm[0]<<16)|pm[1];
|
||||
}
|
||||
wrdprintf("ret = %08x", d);
|
||||
goto end;
|
||||
break;
|
||||
case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:
|
||||
case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:
|
||||
case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:
|
||||
case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:
|
||||
// VDP
|
||||
d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
|
||||
break;
|
||||
case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:
|
||||
case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:
|
||||
case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:
|
||||
case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: {
|
||||
// RAM:
|
||||
u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));
|
||||
d = (pm[0]<<16)|pm[1];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if ((a&0xffffc0)==0xa12000)
|
||||
rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);
|
||||
|
||||
|
@ -624,8 +700,10 @@ static u32 PicoReadM68k32(u32 a)
|
|||
|
||||
if ((a&0xffffc0)==0xa12000)
|
||||
rdprintf("ret = %08x", d);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
end:
|
||||
#ifdef __debug_io
|
||||
dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
|
||||
#endif
|
||||
|
@ -659,8 +737,6 @@ static void PicoWriteM68k8(u32 a,u8 d)
|
|||
return;
|
||||
}
|
||||
|
||||
a&=0xffffff;
|
||||
|
||||
// prg RAM
|
||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
||||
|
@ -668,6 +744,8 @@ static void PicoWriteM68k8(u32 a,u8 d)
|
|||
return;
|
||||
}
|
||||
|
||||
a&=0xffffff;
|
||||
|
||||
// word RAM
|
||||
if ((a&0xfc0000)==0x200000) {
|
||||
wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);
|
||||
|
@ -712,8 +790,6 @@ static void PicoWriteM68k16(u32 a,u16 d)
|
|||
return;
|
||||
}
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
// prg RAM
|
||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
||||
|
@ -722,6 +798,8 @@ static void PicoWriteM68k16(u32 a,u16 d)
|
|||
return;
|
||||
}
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
// word RAM
|
||||
if ((a&0xfc0000)==0x200000) {
|
||||
wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);
|
||||
|
@ -756,6 +834,12 @@ static void PicoWriteM68k16(u32 a,u16 d)
|
|||
return;
|
||||
}
|
||||
|
||||
// VDP
|
||||
if ((a&0xe700e0)==0xc00000) {
|
||||
PicoVideoWrite(a,(u16)d);
|
||||
return;
|
||||
}
|
||||
|
||||
OtherWrite16(a,d);
|
||||
}
|
||||
#endif
|
||||
|
@ -781,8 +865,6 @@ static void PicoWriteM68k32(u32 a,u32 d)
|
|||
return;
|
||||
}
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
// prg RAM
|
||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
||||
|
@ -791,6 +873,8 @@ static void PicoWriteM68k32(u32 a,u32 d)
|
|||
return;
|
||||
}
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
// word RAM
|
||||
if ((a&0xfc0000)==0x200000) {
|
||||
if (d != 0) // don't log clears
|
||||
|
@ -821,6 +905,14 @@ static void PicoWriteM68k32(u32 a,u32 d)
|
|||
if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);
|
||||
}
|
||||
|
||||
// VDP
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
{
|
||||
PicoVideoWrite(a, (u16)(d>>16));
|
||||
PicoVideoWrite(a+2,(u16)d);
|
||||
return;
|
||||
}
|
||||
|
||||
OtherWrite16(a, (u16)(d>>16));
|
||||
OtherWrite16(a+2,(u16)d);
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ PICO_INTERNAL int PicoResetMCD(int hard)
|
|||
SRam.data = NULL;
|
||||
if (PicoOpt&0x8000)
|
||||
SRam.data = calloc(1, 0x12000);
|
||||
SRam.start = SRam.end = 0; // unused
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
|
|||
dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
|
||||
pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
|
||||
}
|
||||
else if (prev_lba == 0x80000000) printf("wtf?\n");
|
||||
|
||||
dprintf("CD buffer miss %i -> %i\n", prev_lba, lba);
|
||||
|
||||
|
@ -89,6 +90,7 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
|
|||
dprintf("CD buffer move=%i, read_len=%i", PicoCDBuffers - read_len, read_len);
|
||||
memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048);
|
||||
moved = 1;
|
||||
if (prev_lba == 0x80000000) printf("wtf?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -104,17 +106,20 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
|
|||
{
|
||||
int i = 0;
|
||||
#if REDUCE_IO_CALLS
|
||||
int bufs = (read_len*2048+304) / (2048+304);
|
||||
int bufs = (read_len*2048) / (2048+304);
|
||||
pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F);
|
||||
for (i = 1; i < bufs; i++)
|
||||
// should really use memmove here, but my memcpy32 implementation is also suitable here
|
||||
memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4);
|
||||
#endif
|
||||
for (; i < read_len; i++)
|
||||
for (; i < read_len - 1; i++)
|
||||
{
|
||||
pm_read(cd_buffer + i*2048, 2048 + 304, Pico_mcd->TOC.Tracks[0].F);
|
||||
// pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); // seeking is slower, in PSP case even more
|
||||
}
|
||||
// further data might be moved, do not overwrite
|
||||
pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F);
|
||||
pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// This is part of Pico Library
|
||||
|
||||
// (c) Copyright 2004 Dave, All rights reserved.
|
||||
// (c) Copyright 2006 notaz, All rights reserved.
|
||||
// (c) Copyright 2006,2007 notaz, All rights reserved.
|
||||
// Free for non-commercial use.
|
||||
|
||||
// For commercial use, separate licencing terms must be obtained.
|
||||
|
@ -11,14 +11,6 @@
|
|||
#include "ym2612.h"
|
||||
#include "sn76496.h"
|
||||
|
||||
#if defined(_USE_MZ80)
|
||||
#include "../../cpu/mz80/mz80.h"
|
||||
#elif defined(_USE_DRZ80)
|
||||
#include "../../cpu/DrZ80/drz80.h"
|
||||
#elif defined(_USE_CZ80)
|
||||
#include "../../cpu/cz80/cz80.h"
|
||||
#endif
|
||||
|
||||
#include "../PicoInt.h"
|
||||
#include "../cd/pcm.h"
|
||||
#include "mix.h"
|
||||
|
@ -36,11 +28,6 @@ int PsndLen_exc_add=0; // this is for non-integer sample counts per line, eg. 22
|
|||
int PsndLen_exc_cnt=0;
|
||||
short *PsndOut=NULL; // PCM data buffer
|
||||
|
||||
// from ym2612.c
|
||||
extern int *ym2612_dacen;
|
||||
extern INT32 *ym2612_dacout;
|
||||
void YM2612TimerHandler(int c,int cnt);
|
||||
|
||||
// sn76496
|
||||
extern int *sn76496_regs;
|
||||
|
||||
|
@ -306,9 +293,16 @@ static struct z80PortWrite mz80_io_write[]={
|
|||
{(UINT16) -1,(UINT16) -1,NULL}
|
||||
};
|
||||
|
||||
int mz80_run(int cycles)
|
||||
{
|
||||
int ticks_pre = mz80GetElapsedTicks(0);
|
||||
mz80exec(cycles);
|
||||
return mz80GetElapsedTicks(0) - ticks_pre;
|
||||
}
|
||||
|
||||
#elif defined(_USE_DRZ80)
|
||||
|
||||
static struct DrZ80 drZ80;
|
||||
struct DrZ80 drZ80;
|
||||
|
||||
static unsigned int DrZ80_rebasePC(unsigned short a)
|
||||
{
|
||||
|
@ -379,7 +373,7 @@ PICO_INTERNAL void z80_init(void)
|
|||
Cz80_Init(&CZ80);
|
||||
Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM
|
||||
Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram - 0x2000); // mirror
|
||||
Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read);
|
||||
Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read); // unused (hacked in)
|
||||
Cz80_Set_WriteB(&CZ80, z80_write);
|
||||
Cz80_Set_INPort(&CZ80, z80_in);
|
||||
Cz80_Set_OUTPort(&CZ80, z80_out);
|
||||
|
@ -405,40 +399,6 @@ PICO_INTERNAL void z80_reset(void)
|
|||
Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled
|
||||
}
|
||||
|
||||
PICO_INTERNAL void z80_resetCycles(void)
|
||||
{
|
||||
#if defined(_USE_MZ80)
|
||||
mz80GetElapsedTicks(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
PICO_INTERNAL void z80_int(void)
|
||||
{
|
||||
#if defined(_USE_MZ80)
|
||||
mz80int(0);
|
||||
#elif defined(_USE_DRZ80)
|
||||
drZ80.z80irqvector = 0xFF; // default IRQ vector RST opcode
|
||||
drZ80.Z80_IRQ = 1;
|
||||
#elif defined(_USE_CZ80)
|
||||
Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns number of cycles actually executed
|
||||
PICO_INTERNAL int z80_run(int cycles)
|
||||
{
|
||||
#if defined(_USE_MZ80)
|
||||
int ticks_pre = mz80GetElapsedTicks(0);
|
||||
mz80exec(cycles);
|
||||
return mz80GetElapsedTicks(0) - ticks_pre;
|
||||
#elif defined(_USE_DRZ80)
|
||||
return cycles - DrZ80Run(&drZ80, cycles);
|
||||
#elif defined(_USE_CZ80)
|
||||
return Cz80_Exec(&CZ80, cycles);
|
||||
#else
|
||||
return cycles;
|
||||
#endif
|
||||
}
|
||||
|
||||
PICO_INTERNAL void z80_pack(unsigned char *data)
|
||||
{
|
||||
|
|
|
@ -553,20 +553,21 @@ INLINE void set_timers( int v )
|
|||
}
|
||||
|
||||
|
||||
INLINE void FM_KEYON(FM_CH *CH , int s )
|
||||
INLINE void FM_KEYON(int c , int s )
|
||||
{
|
||||
FM_SLOT *SLOT = &CH->SLOT[s];
|
||||
FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];
|
||||
if( !SLOT->key )
|
||||
{
|
||||
SLOT->key = 1;
|
||||
SLOT->phase = 0; /* restart Phase Generator */
|
||||
SLOT->state = EG_ATT; /* phase -> Attack */
|
||||
ym2612.slot_mask |= (1<<s) << (c*4);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void FM_KEYOFF(FM_CH *CH , int s )
|
||||
INLINE void FM_KEYOFF(int c , int s )
|
||||
{
|
||||
FM_SLOT *SLOT = &CH->SLOT[s];
|
||||
FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];
|
||||
if( SLOT->key )
|
||||
{
|
||||
SLOT->key = 0;
|
||||
|
@ -844,6 +845,9 @@ typedef struct
|
|||
UINT32 pack; // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16]
|
||||
UINT32 algo; /* 50: algo[3], was_update */
|
||||
INT32 op1_out;
|
||||
#ifdef _MIPS_ARCH_ALLEGREX
|
||||
UINT32 pad1[3+8];
|
||||
#endif
|
||||
} chan_rend_context;
|
||||
|
||||
|
||||
|
@ -905,16 +909,6 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
|||
|
||||
switch( ct->CH->ALGO )
|
||||
{
|
||||
#if 0
|
||||
case 0: smp = upd_algo0(ct); break;
|
||||
case 1: smp = upd_algo1(ct); break;
|
||||
case 2: smp = upd_algo2(ct); break;
|
||||
case 3: smp = upd_algo3(ct); break;
|
||||
case 4: smp = upd_algo4(ct); break;
|
||||
case 5: smp = upd_algo5(ct); break;
|
||||
case 6: smp = upd_algo6(ct); break;
|
||||
case 7: smp = upd_algo7(ct); break;
|
||||
#else
|
||||
case 0:
|
||||
{
|
||||
/* M1---C1---MEM---M2---C2---OUT */
|
||||
|
@ -1064,7 +1058,6 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* done calculating channel sample */
|
||||
|
||||
|
@ -1092,55 +1085,54 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
|||
void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);
|
||||
#endif
|
||||
|
||||
static chan_rend_context __attribute__((aligned(64))) crct;
|
||||
|
||||
static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l
|
||||
static int chan_render(int *buffer, int length, int c, UINT32 flags) // flags: stereo, ?, disabled, ?, pan_r, pan_l
|
||||
{
|
||||
chan_rend_context ct;
|
||||
crct.CH = &ym2612.CH[c];
|
||||
crct.mem = crct.CH->mem_value; /* one sample delay memory */
|
||||
crct.lfo_cnt = ym2612.OPN.lfo_cnt;
|
||||
crct.lfo_inc = ym2612.OPN.lfo_inc;
|
||||
|
||||
ct.CH = CH;
|
||||
ct.mem = CH->mem_value; /* one sample delay memory */
|
||||
ct.lfo_cnt = ym2612.OPN.lfo_cnt;
|
||||
ct.lfo_inc = ym2612.OPN.lfo_inc;
|
||||
flags &= 0x35;
|
||||
|
||||
flags &= 0x37;
|
||||
|
||||
if (ct.lfo_inc) {
|
||||
if (crct.lfo_inc) {
|
||||
flags |= 8;
|
||||
flags |= g_lfo_ampm << 16;
|
||||
flags |= CH->AMmasks << 8;
|
||||
if (CH->ams == 8) // no ams
|
||||
flags |= crct.CH->AMmasks << 8;
|
||||
if (crct.CH->ams == 8) // no ams
|
||||
flags &= ~0xf00;
|
||||
else flags |= (CH->ams&3)<<6;
|
||||
else flags |= (crct.CH->ams&3)<<6;
|
||||
}
|
||||
flags |= (CH->FB&0xf)<<12; /* feedback shift */
|
||||
ct.pack = flags;
|
||||
flags |= (crct.CH->FB&0xf)<<12; /* feedback shift */
|
||||
crct.pack = flags;
|
||||
|
||||
ct.eg_cnt = ym2612.OPN.eg_cnt; /* envelope generator counter */
|
||||
ct.eg_timer = ym2612.OPN.eg_timer;
|
||||
ct.eg_timer_add = ym2612.OPN.eg_timer_add;
|
||||
crct.eg_cnt = ym2612.OPN.eg_cnt; /* envelope generator counter */
|
||||
crct.eg_timer = ym2612.OPN.eg_timer;
|
||||
crct.eg_timer_add = ym2612.OPN.eg_timer_add;
|
||||
|
||||
/* precalculate phase modulation incr */
|
||||
ct.phase1 = CH->SLOT[SLOT1].phase;
|
||||
ct.phase2 = CH->SLOT[SLOT2].phase;
|
||||
ct.phase3 = CH->SLOT[SLOT3].phase;
|
||||
ct.phase4 = CH->SLOT[SLOT4].phase;
|
||||
crct.phase1 = crct.CH->SLOT[SLOT1].phase;
|
||||
crct.phase2 = crct.CH->SLOT[SLOT2].phase;
|
||||
crct.phase3 = crct.CH->SLOT[SLOT3].phase;
|
||||
crct.phase4 = crct.CH->SLOT[SLOT4].phase;
|
||||
|
||||
/* current output from EG circuit (without AM from LFO) */
|
||||
ct.vol_out1 = CH->SLOT[SLOT1].tl + ((UINT32)CH->SLOT[SLOT1].volume);
|
||||
ct.vol_out2 = CH->SLOT[SLOT2].tl + ((UINT32)CH->SLOT[SLOT2].volume);
|
||||
ct.vol_out3 = CH->SLOT[SLOT3].tl + ((UINT32)CH->SLOT[SLOT3].volume);
|
||||
ct.vol_out4 = CH->SLOT[SLOT4].tl + ((UINT32)CH->SLOT[SLOT4].volume);
|
||||
crct.vol_out1 = crct.CH->SLOT[SLOT1].tl + ((UINT32)crct.CH->SLOT[SLOT1].volume);
|
||||
crct.vol_out2 = crct.CH->SLOT[SLOT2].tl + ((UINT32)crct.CH->SLOT[SLOT2].volume);
|
||||
crct.vol_out3 = crct.CH->SLOT[SLOT3].tl + ((UINT32)crct.CH->SLOT[SLOT3].volume);
|
||||
crct.vol_out4 = crct.CH->SLOT[SLOT4].tl + ((UINT32)crct.CH->SLOT[SLOT4].volume);
|
||||
|
||||
ct.op1_out = CH->op1_out;
|
||||
ct.algo = CH->ALGO & 7;
|
||||
crct.op1_out = crct.CH->op1_out;
|
||||
crct.algo = crct.CH->ALGO & 7;
|
||||
|
||||
if(CH->pms)
|
||||
if(crct.CH->pms)
|
||||
{
|
||||
/* add support for 3 slot mode */
|
||||
UINT32 block_fnum = CH->block_fnum;
|
||||
UINT32 block_fnum = crct.CH->block_fnum;
|
||||
|
||||
UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
|
||||
INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + ((ct.pack>>16)&0xff) ];
|
||||
INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + crct.CH->pms + ((crct.pack>>16)&0xff) ];
|
||||
|
||||
if (lfo_fn_table_index_offset) /* LFO phase modulation active */
|
||||
{
|
||||
|
@ -1158,45 +1150,51 @@ static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flag
|
|||
/* phase increment counter */
|
||||
fc = fn_table[fn]>>(7-blk);
|
||||
|
||||
ct.incr1 = ((fc+CH->SLOT[SLOT1].DT[kc])*CH->SLOT[SLOT1].mul) >> 1;
|
||||
ct.incr2 = ((fc+CH->SLOT[SLOT2].DT[kc])*CH->SLOT[SLOT2].mul) >> 1;
|
||||
ct.incr3 = ((fc+CH->SLOT[SLOT3].DT[kc])*CH->SLOT[SLOT3].mul) >> 1;
|
||||
ct.incr4 = ((fc+CH->SLOT[SLOT4].DT[kc])*CH->SLOT[SLOT4].mul) >> 1;
|
||||
crct.incr1 = ((fc+crct.CH->SLOT[SLOT1].DT[kc])*crct.CH->SLOT[SLOT1].mul) >> 1;
|
||||
crct.incr2 = ((fc+crct.CH->SLOT[SLOT2].DT[kc])*crct.CH->SLOT[SLOT2].mul) >> 1;
|
||||
crct.incr3 = ((fc+crct.CH->SLOT[SLOT3].DT[kc])*crct.CH->SLOT[SLOT3].mul) >> 1;
|
||||
crct.incr4 = ((fc+crct.CH->SLOT[SLOT4].DT[kc])*crct.CH->SLOT[SLOT4].mul) >> 1;
|
||||
}
|
||||
else /* LFO phase modulation = zero */
|
||||
{
|
||||
ct.incr1 = CH->SLOT[SLOT1].Incr;
|
||||
ct.incr2 = CH->SLOT[SLOT2].Incr;
|
||||
ct.incr3 = CH->SLOT[SLOT3].Incr;
|
||||
ct.incr4 = CH->SLOT[SLOT4].Incr;
|
||||
crct.incr1 = crct.CH->SLOT[SLOT1].Incr;
|
||||
crct.incr2 = crct.CH->SLOT[SLOT2].Incr;
|
||||
crct.incr3 = crct.CH->SLOT[SLOT3].Incr;
|
||||
crct.incr4 = crct.CH->SLOT[SLOT4].Incr;
|
||||
}
|
||||
}
|
||||
else /* no LFO phase modulation */
|
||||
{
|
||||
ct.incr1 = CH->SLOT[SLOT1].Incr;
|
||||
ct.incr2 = CH->SLOT[SLOT2].Incr;
|
||||
ct.incr3 = CH->SLOT[SLOT3].Incr;
|
||||
ct.incr4 = CH->SLOT[SLOT4].Incr;
|
||||
crct.incr1 = crct.CH->SLOT[SLOT1].Incr;
|
||||
crct.incr2 = crct.CH->SLOT[SLOT2].Incr;
|
||||
crct.incr3 = crct.CH->SLOT[SLOT3].Incr;
|
||||
crct.incr4 = crct.CH->SLOT[SLOT4].Incr;
|
||||
}
|
||||
|
||||
chan_render_loop(&ct, buffer, length);
|
||||
chan_render_loop(&crct, buffer, length);
|
||||
|
||||
// write back persistent stuff:
|
||||
if (flags & 2) { /* last channel */
|
||||
ym2612.OPN.eg_cnt = ct.eg_cnt;
|
||||
ym2612.OPN.eg_timer = ct.eg_timer;
|
||||
g_lfo_ampm = ct.pack >> 16;
|
||||
ym2612.OPN.lfo_cnt = ct.lfo_cnt;
|
||||
crct.CH->op1_out = crct.op1_out;
|
||||
crct.CH->mem_value = crct.mem;
|
||||
if (crct.CH->SLOT[SLOT1].state | crct.CH->SLOT[SLOT2].state | crct.CH->SLOT[SLOT3].state | crct.CH->SLOT[SLOT4].state)
|
||||
{
|
||||
crct.CH->SLOT[SLOT1].phase = crct.phase1;
|
||||
crct.CH->SLOT[SLOT2].phase = crct.phase2;
|
||||
crct.CH->SLOT[SLOT3].phase = crct.phase3;
|
||||
crct.CH->SLOT[SLOT4].phase = crct.phase4;
|
||||
}
|
||||
else
|
||||
ym2612.slot_mask &= ~(0xf << (c*4));
|
||||
|
||||
// if this the last call, write back persistent stuff:
|
||||
if ((ym2612.slot_mask >> ((c+1)*4)) == 0)
|
||||
{
|
||||
ym2612.OPN.eg_cnt = crct.eg_cnt;
|
||||
ym2612.OPN.eg_timer = crct.eg_timer;
|
||||
g_lfo_ampm = crct.pack >> 16;
|
||||
ym2612.OPN.lfo_cnt = crct.lfo_cnt;
|
||||
}
|
||||
|
||||
CH->op1_out = ct.op1_out;
|
||||
CH->SLOT[SLOT1].phase = ct.phase1;
|
||||
CH->SLOT[SLOT2].phase = ct.phase2;
|
||||
CH->SLOT[SLOT3].phase = ct.phase3;
|
||||
CH->SLOT[SLOT4].phase = ct.phase4;
|
||||
CH->mem_value = ct.mem;
|
||||
|
||||
return (ct.algo & 8) >> 3; // had output
|
||||
return (crct.algo & 8) >> 3; // had output
|
||||
}
|
||||
|
||||
/* update phase increment and envelope generator */
|
||||
|
@ -1274,7 +1272,7 @@ static void init_timetables(const UINT8 *dttable)
|
|||
}
|
||||
|
||||
|
||||
static void reset_channels(FM_CH *CH, int num)
|
||||
static void reset_channels(FM_CH *CH)
|
||||
{
|
||||
int c,s;
|
||||
|
||||
|
@ -1284,7 +1282,7 @@ static void reset_channels(FM_CH *CH, int num)
|
|||
ym2612.OPN.ST.TB = 0;
|
||||
ym2612.OPN.ST.TBC = 0;
|
||||
|
||||
for( c = 0 ; c < num ; c++ )
|
||||
for( c = 0 ; c < 6 ; c++ )
|
||||
{
|
||||
CH[c].fc = 0;
|
||||
for(s = 0 ; s < 4 ; s++ )
|
||||
|
@ -1293,6 +1291,7 @@ static void reset_channels(FM_CH *CH, int num)
|
|||
CH[c].SLOT[s].volume = MAX_ATT_INDEX;
|
||||
}
|
||||
}
|
||||
ym2612.slot_mask = 0;
|
||||
}
|
||||
|
||||
/* initialize generic tables */
|
||||
|
@ -1401,6 +1400,7 @@ static void init_tables(void)
|
|||
|
||||
|
||||
/* CSM Key Controll */
|
||||
#if 0
|
||||
INLINE void CSMKeyControll(FM_CH *CH)
|
||||
{
|
||||
/* this is wrong, atm */
|
||||
|
@ -1411,6 +1411,7 @@ INLINE void CSMKeyControll(FM_CH *CH)
|
|||
FM_KEYON(CH,SLOT3);
|
||||
FM_KEYON(CH,SLOT4);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* prescaler set (and make time tables) */
|
||||
|
@ -1585,6 +1586,7 @@ static int OPNWriteReg(int r, int v)
|
|||
|
||||
int *ym2612_dacen;
|
||||
INT32 *ym2612_dacout;
|
||||
FM_ST *ym2612_st;
|
||||
|
||||
|
||||
/* Generate samples for YM2612 */
|
||||
|
@ -1596,6 +1598,24 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
|
|||
// if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash
|
||||
if (is_buf_empty) memset32(buffer, 0, length<<stereo);
|
||||
|
||||
/*
|
||||
{
|
||||
int c, s;
|
||||
ppp();
|
||||
for (c = 0; c < 6; c++) {
|
||||
int slr = 0, slm;
|
||||
printf("%i: ", c);
|
||||
for (s = 0; s < 4; s++) {
|
||||
if (ym2612.CH[c].SLOT[s].state != EG_OFF) slr = 1;
|
||||
printf(" %i", ym2612.CH[c].SLOT[s].state != EG_OFF);
|
||||
}
|
||||
slm = (ym2612.slot_mask&(0xf<<(c*4))) ? 1 : 0;
|
||||
printf(" | %i", slm);
|
||||
printf(" | %i\n", ym2612.CH[c].SLOT[SLOT1].Incr==-1);
|
||||
if (slr != slm) exit(1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* refresh PG and EG */
|
||||
refresh_fc_eg_chan( &ym2612.CH[0] );
|
||||
refresh_fc_eg_chan( &ym2612.CH[1] );
|
||||
|
@ -1618,13 +1638,13 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
|
|||
if (stereo) stereo = 1;
|
||||
|
||||
/* mix to 32bit dest */
|
||||
// flags: stereo, lastchan, disabled, ?, pan_r, pan_l
|
||||
active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0;
|
||||
active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1;
|
||||
active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )) << 2;
|
||||
active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3;
|
||||
active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4;
|
||||
active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5;
|
||||
// flags: stereo, ?, disabled, ?, pan_r, pan_l
|
||||
if (ym2612.slot_mask & 0x00000f) active_chs |= chan_render(buffer, length, 0, stereo|((pan&0x003)<<4)) << 0;
|
||||
if (ym2612.slot_mask & 0x0000f0) active_chs |= chan_render(buffer, length, 1, stereo|((pan&0x00c)<<2)) << 1;
|
||||
if (ym2612.slot_mask & 0x000f00) active_chs |= chan_render(buffer, length, 2, stereo|((pan&0x030) )) << 2;
|
||||
if (ym2612.slot_mask & 0x00f000) active_chs |= chan_render(buffer, length, 3, stereo|((pan&0x0c0)>>2)) << 3;
|
||||
if (ym2612.slot_mask & 0x0f0000) active_chs |= chan_render(buffer, length, 4, stereo|((pan&0x300)>>4)) << 4;
|
||||
if (ym2612.slot_mask & 0xf00000) active_chs |= chan_render(buffer, length, 5, stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)) << 5;
|
||||
|
||||
return active_chs; // 1 if buffer updated
|
||||
}
|
||||
|
@ -1636,6 +1656,7 @@ void YM2612Init_(int clock, int rate)
|
|||
// notaz
|
||||
ym2612_dacen = &ym2612.dacen;
|
||||
ym2612_dacout = &ym2612.dacout;
|
||||
ym2612_st = &ym2612.OPN.ST;
|
||||
|
||||
memset(&ym2612, 0, sizeof(ym2612));
|
||||
init_tables();
|
||||
|
@ -1663,7 +1684,7 @@ void YM2612ResetChip_(void)
|
|||
ym2612.OPN.eg_cnt = 0;
|
||||
ym2612.OPN.ST.status = 0;
|
||||
|
||||
reset_channels( &ym2612.CH[0] , 6 );
|
||||
reset_channels( &ym2612.CH[0] );
|
||||
for(i = 0xb6 ; i >= 0xb4 ; i-- )
|
||||
{
|
||||
OPNWriteReg(i ,0xc0);
|
||||
|
@ -1763,16 +1784,14 @@ int YM2612Write_(unsigned int a, unsigned int v)
|
|||
case 0x28: /* key on / off */
|
||||
{
|
||||
UINT8 c;
|
||||
FM_CH *CH;
|
||||
|
||||
c = v & 0x03;
|
||||
if( c == 3 ) { ret=0; break; }
|
||||
if( v&0x04 ) c+=3;
|
||||
CH = &ym2612.CH[c];
|
||||
if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
|
||||
if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
|
||||
if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
|
||||
if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
|
||||
if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);
|
||||
if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);
|
||||
if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);
|
||||
if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4);
|
||||
break;
|
||||
}
|
||||
case 0x2a: /* DAC data (YM2612) */
|
||||
|
@ -1823,12 +1842,12 @@ int YM2612Write_(unsigned int a, unsigned int v)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
UINT8 YM2612Read_(void)
|
||||
{
|
||||
return ym2612.OPN.ST.status;
|
||||
}
|
||||
|
||||
|
||||
int YM2612PicoTick_(int n)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -1852,14 +1871,14 @@ int YM2612PicoTick_(int n)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void YM2612PicoStateLoad_(void)
|
||||
{
|
||||
#ifndef EXTERNAL_YM2612
|
||||
int i, real_A1 = ym2612.addr_A1;
|
||||
|
||||
reset_channels( &ym2612.CH[0], 6 );
|
||||
reset_channels( &ym2612.CH[0] );
|
||||
|
||||
// feed all the registers and update internal state
|
||||
for(i = 0; i < 0x100; i++) {
|
||||
|
@ -1874,11 +1893,10 @@ void YM2612PicoStateLoad_(void)
|
|||
|
||||
ym2612.addr_A1 = real_A1;
|
||||
#else
|
||||
reset_channels( &ym2612.CH[0], 6 );
|
||||
reset_channels( &ym2612.CH[0] );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef EXTERNAL_YM2612
|
||||
void *YM2612GetRegs(void)
|
||||
{
|
||||
|
|
|
@ -76,15 +76,16 @@ typedef struct
|
|||
{
|
||||
int clock; /* master clock (Hz) */
|
||||
int rate; /* sampling rate (Hz) */
|
||||
double freqbase; /* frequency base */
|
||||
UINT8 address; /* address register */
|
||||
UINT8 status; /* status flag */
|
||||
double freqbase; /* 08 frequency base */
|
||||
UINT8 address; /* 10 address register */
|
||||
UINT8 status; /* 11 status flag */
|
||||
UINT8 mode; /* mode CSM / 3SLOT */
|
||||
UINT8 fn_h; /* freq latch */
|
||||
int TA; /* timer a */
|
||||
int TAC; /* timer a maxval */
|
||||
int TAT; /* timer a ticker */
|
||||
UINT8 TB; /* timer b */
|
||||
UINT8 pad[3];
|
||||
int TBC; /* timer b maxval */
|
||||
int TBT; /* timer b ticker */
|
||||
/* local time tables */
|
||||
|
@ -135,9 +136,32 @@ typedef struct
|
|||
INT32 dacout;
|
||||
|
||||
FM_OPN OPN; /* OPN state */
|
||||
|
||||
UINT32 slot_mask; /* active slot mask (performance hack) */
|
||||
} YM2612;
|
||||
#endif
|
||||
|
||||
extern int *ym2612_dacen;
|
||||
extern INT32 *ym2612_dacout;
|
||||
extern FM_ST *ym2612_st;
|
||||
|
||||
|
||||
#define YM2612Read() ym2612_st->status
|
||||
|
||||
#define YM2612PicoTick(n) \
|
||||
{ \
|
||||
/* timer A */ \
|
||||
if(ym2612_st->mode & 0x01 && (ym2612_st->TAT+=64*n) >= ym2612_st->TAC) { \
|
||||
ym2612_st->TAT -= ym2612_st->TAC; \
|
||||
if(ym2612_st->mode & 0x04) ym2612_st->status |= 1; \
|
||||
} \
|
||||
\
|
||||
/* timer B */ \
|
||||
if(ym2612_st->mode & 0x02 && (ym2612_st->TBT+=64*n) >= ym2612_st->TBC) { \
|
||||
ym2612_st->TBT -= ym2612_st->TBC; \
|
||||
if(ym2612_st->mode & 0x08) ym2612_st->status |= 2; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
void YM2612Init_(int baseclock, int rate);
|
||||
|
@ -157,8 +181,6 @@ void *YM2612GetRegs(void);
|
|||
#define YM2612ResetChip YM2612ResetChip_
|
||||
#define YM2612UpdateOne YM2612UpdateOne_
|
||||
#define YM2612Write YM2612Write_
|
||||
#define YM2612Read YM2612Read_
|
||||
#define YM2612PicoTick YM2612PicoTick_
|
||||
#define YM2612PicoStateLoad YM2612PicoStateLoad_
|
||||
#else
|
||||
/* GP2X specific */
|
||||
|
@ -177,10 +199,6 @@ extern int PicoOpt;
|
|||
YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
|
||||
#define YM2612Write(a,v) \
|
||||
(PicoOpt&0x200) ? YM2612Write_940(a, v) : YM2612Write_(a, v)
|
||||
#define YM2612Read() \
|
||||
(PicoOpt&0x200) ? YM2612Read_940() : YM2612Read_()
|
||||
#define YM2612PicoTick(n) \
|
||||
(PicoOpt&0x200) ? YM2612PicoTick_940(n) : YM2612PicoTick_(n)
|
||||
#define YM2612PicoStateLoad() { \
|
||||
if (PicoOpt&0x200) YM2612PicoStateLoad_940(); \
|
||||
else YM2612PicoStateLoad_(); \
|
||||
|
|
|
@ -21,14 +21,10 @@
|
|||
.endif
|
||||
|
||||
.if DRZ80_FOR_PICODRIVE
|
||||
.include "port_config.s"
|
||||
.extern YM2612Read_
|
||||
.if EXTERNAL_YM2612
|
||||
.extern YM2612Read_940
|
||||
.endif
|
||||
.extern PicoRead8
|
||||
.extern Pico
|
||||
.extern z80_write
|
||||
.extern ym2612_st
|
||||
.endif
|
||||
|
||||
DrZ80Ver: .long 0x0001
|
||||
|
@ -111,37 +107,18 @@ DrZ80Ver: .long 0x0001
|
|||
.if DRZ80_FOR_PICODRIVE
|
||||
|
||||
.macro YM2612Read_and_ret8
|
||||
stmfd sp!,{r3,r12,lr}
|
||||
.if EXTERNAL_YM2612
|
||||
ldr r1,=PicoOpt
|
||||
ldr r1,[r1]
|
||||
tst r1,#0x200
|
||||
ldrne r2, =YM2612Read_940
|
||||
ldreq r2, =YM2612Read_
|
||||
mov lr,pc
|
||||
bx r2
|
||||
.else
|
||||
bl YM2612Read_
|
||||
.endif
|
||||
ldmfd sp!,{r3,r12,pc}
|
||||
ldr r0, =ym2612_st
|
||||
ldr r0, [r0]
|
||||
ldrb r0, [r0, #0x11] ;@ ym2612_st->status
|
||||
bx lr
|
||||
.endm
|
||||
|
||||
.macro YM2612Read_and_ret16
|
||||
stmfd sp!,{r3,r12,lr}
|
||||
.if EXTERNAL_YM2612
|
||||
ldr r0,=PicoOpt
|
||||
ldr r0, =ym2612_st
|
||||
ldr r0, [r0]
|
||||
tst r0,#0x200
|
||||
ldrne r2, =YM2612Read_940
|
||||
ldreq r2, =YM2612Read_
|
||||
mov lr,pc
|
||||
bx r2
|
||||
ldrb r0, [r0, #0x11] ;@ ym2612_st->status
|
||||
orr r0,r0,r0,lsl #8
|
||||
.else
|
||||
bl YM2612Read_
|
||||
orr r0,r0,r0,lsl #8
|
||||
.endif
|
||||
ldmfd sp!,{r3,r12,pc}
|
||||
bx lr
|
||||
.endm
|
||||
|
||||
pico_z80_read8: @ addr
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include <string.h>
|
||||
#include "cz80.h"
|
||||
|
||||
#if PICODRIVE_HACKS
|
||||
#include <Pico/PicoInt.h>
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_DATA
|
||||
#define ALIGN_DATA __attribute__((aligned(4)))
|
||||
#endif
|
||||
|
@ -203,6 +207,13 @@ void Cz80_Reset(cz80_struc *CPU)
|
|||
Cz80_Set_Reg(CPU, CZ80_PC, 0);
|
||||
}
|
||||
|
||||
/* */
|
||||
#if PICODRIVE_HACKS
|
||||
static inline unsigned char picodrive_read(unsigned short a)
|
||||
{
|
||||
return (a < 0x4000) ? Pico.zram[a&0x1fff] : z80_read(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------
|
||||
CPUŽÀ<EFBFBD>s
|
||||
|
|
|
@ -52,6 +52,7 @@ extern "C" {
|
|||
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)
|
||||
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)
|
||||
|
||||
#define PICODRIVE_HACKS 1
|
||||
#define CZ80_LITTLE_ENDIAN 1
|
||||
#define CZ80_USE_JUMPTABLE 1
|
||||
#define CZ80_BIG_FLAGS_ARRAY 1
|
||||
|
|
|
@ -57,7 +57,11 @@
|
|||
//#ifndef BUILD_CPS1PSP
|
||||
//#define READ_MEM8(A) memory_region_cpu2[(A)]
|
||||
//#else
|
||||
#if PICODRIVE_HACKS
|
||||
#define READ_MEM8(A) picodrive_read(A)
|
||||
#else
|
||||
#define READ_MEM8(A) CPU->Read_Byte(A)
|
||||
#endif
|
||||
//#endif
|
||||
#if CZ80_LITTLE_ENDIAN
|
||||
#define READ_MEM16(A) (READ_MEM8(A) | (READ_MEM8((A) + 1) << 8))
|
||||
|
@ -65,7 +69,16 @@
|
|||
#define READ_MEM16(A) ((READ_MEM8(A) << 8) | READ_MEM8((A) + 1))
|
||||
#endif
|
||||
|
||||
#if PICODRIVE_HACKS
|
||||
#define WRITE_MEM8(A, D) { \
|
||||
unsigned short a = A; \
|
||||
unsigned char d = D; \
|
||||
if (a < 0x4000) Pico.zram[a&0x1fff] = d; \
|
||||
else z80_write(a, d); \
|
||||
}
|
||||
#else
|
||||
#define WRITE_MEM8(A, D) CPU->Write_Byte(A, D);
|
||||
#endif
|
||||
#if CZ80_LITTLE_ENDIAN
|
||||
#define WRITE_MEM16(A, D) { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }
|
||||
#else
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
// Options //
|
||||
#define FAMEC_ROLL_INLINE
|
||||
#define FAMEC_EMULATE_TRACE
|
||||
#define FAMEC_CHECK_BRANCHES
|
||||
//#define FAMEC_EMULATE_TRACE
|
||||
//#define FAMEC_CHECK_BRANCHES
|
||||
#define FAMEC_EXTRA_INLINE
|
||||
// #define FAMEC_DEBUG
|
||||
//#define FAMEC_NO_GOTOS
|
||||
|
@ -280,11 +280,18 @@ typedef signed int s32;
|
|||
((u32)PC - BasePC)
|
||||
|
||||
|
||||
#ifdef FAMEC_CHECK_BRANCHES
|
||||
#define FORCE_ALIGNMENT(pc)
|
||||
#else
|
||||
#define FORCE_ALIGNMENT(pc) pc&=~1;
|
||||
#endif
|
||||
|
||||
#ifndef FAMEC_32BIT_PC
|
||||
|
||||
#define SET_PC(A) \
|
||||
{ \
|
||||
u32 pc = A; \
|
||||
FORCE_ALIGNMENT(pc); \
|
||||
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
|
||||
PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \
|
||||
}
|
||||
|
@ -294,6 +301,7 @@ typedef signed int s32;
|
|||
#define SET_PC(A) \
|
||||
{ \
|
||||
u32 pc = A; \
|
||||
FORCE_ALIGNMENT(pc); \
|
||||
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
|
||||
BasePC -= pc & 0xFF000000; \
|
||||
PC = (u16*)(pc + BasePC); \
|
||||
|
@ -734,7 +742,9 @@ static FAMEC_EXTRA_INLINE u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR)
|
|||
#ifndef FAMEC_32BIT_PC
|
||||
newPC&=M68K_ADR_MASK
|
||||
#endif
|
||||
#ifdef FAMEC_CHECK_BRANCHES
|
||||
newPC&=~1; // don't crash on games with bad vector tables
|
||||
#endif
|
||||
|
||||
// SET_PC(newPC)
|
||||
|
||||
|
@ -948,6 +958,7 @@ famec_End:
|
|||
#ifdef PICODRIVE_HACK
|
||||
dualcore_mode:
|
||||
|
||||
while (1)
|
||||
{
|
||||
extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k;
|
||||
#define PS_STEP_M68K ((488<<16)/20) // ~24
|
||||
|
@ -989,7 +1000,6 @@ dualcore_mode:
|
|||
}
|
||||
cycles = m68kcontext.io_cycle_counter = 0;
|
||||
}
|
||||
goto dualcore_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -51,22 +51,12 @@ static FILE *loaded_mp3 = 0;
|
|||
}
|
||||
|
||||
/* these will be managed locally on our side */
|
||||
extern int *ym2612_dacen;
|
||||
extern INT32 *ym2612_dacout;
|
||||
static UINT8 *REGS = 0; /* we will also keep local copy of regs for savestates and such */
|
||||
static INT32 *addr_A1; /* address line A1 */
|
||||
|
||||
static int dacen;
|
||||
static INT32 dacout;
|
||||
static UINT8 ST_address; /* address register */
|
||||
static UINT8 ST_status; /* status flag */
|
||||
static UINT8 ST_mode; /* mode CSM / 3SLOT */
|
||||
static int ST_TA; /* timer a */
|
||||
static int ST_TAC; /* timer a maxval */
|
||||
static int ST_TAT; /* timer a ticker */
|
||||
static UINT8 ST_TB; /* timer b */
|
||||
static int ST_TBC; /* timer b maxval */
|
||||
static int ST_TBT; /* timer b ticker */
|
||||
|
||||
static int writebuff_ptr = 0;
|
||||
|
||||
|
@ -84,16 +74,16 @@ static int set_timers( int v )
|
|||
/* b2 = timer enable a */
|
||||
/* b1 = load b */
|
||||
/* b0 = load a */
|
||||
change = (ST_mode ^ v) & 0xc0;
|
||||
ST_mode = v;
|
||||
change = (ym2612_st->mode ^ v) & 0xc0;
|
||||
ym2612_st->mode = v;
|
||||
|
||||
/* reset Timer b flag */
|
||||
if( v & 0x20 )
|
||||
ST_status &= ~2;
|
||||
ym2612_st->status &= ~2;
|
||||
|
||||
/* reset Timer a flag */
|
||||
if( v & 0x10 )
|
||||
ST_status &= ~1;
|
||||
ym2612_st->status &= ~1;
|
||||
|
||||
return change;
|
||||
}
|
||||
|
@ -139,30 +129,30 @@ int YM2612Write_940(unsigned int a, unsigned int v)
|
|||
switch( addr )
|
||||
{
|
||||
case 0x24: { // timer A High 8
|
||||
int TAnew = (ST_TA & 0x03)|(((int)v)<<2);
|
||||
if(ST_TA != TAnew) {
|
||||
int TAnew = (ym2612_st->TA & 0x03)|(((int)v)<<2);
|
||||
if (ym2612_st->TA != TAnew) {
|
||||
// we should reset ticker only if new value is written. Outrun requires this.
|
||||
ST_TA = TAnew;
|
||||
ST_TAC = (1024-TAnew)*18;
|
||||
ST_TAT = 0;
|
||||
ym2612_st->TA = TAnew;
|
||||
ym2612_st->TAC = (1024-TAnew)*18;
|
||||
ym2612_st->TAT = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case 0x25: { // timer A Low 2
|
||||
int TAnew = (ST_TA & 0x3fc)|(v&3);
|
||||
if(ST_TA != TAnew) {
|
||||
ST_TA = TAnew;
|
||||
ST_TAC = (1024-TAnew)*18;
|
||||
ST_TAT = 0;
|
||||
int TAnew = (ym2612_st->TA & 0x3fc)|(v&3);
|
||||
if (ym2612_st->TA != TAnew) {
|
||||
ym2612_st->TA = TAnew;
|
||||
ym2612_st->TAC = (1024-TAnew)*18;
|
||||
ym2612_st->TAT = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case 0x26: // timer B
|
||||
if(ST_TB != v) {
|
||||
ST_TB = v;
|
||||
ST_TBC = (256-v)<<4;
|
||||
ST_TBC *= 18;
|
||||
ST_TBT = 0;
|
||||
if (ym2612_st->TB != v) {
|
||||
ym2612_st->TB = v;
|
||||
ym2612_st->TBC = (256-v)<<4;
|
||||
ym2612_st->TBC *= 18;
|
||||
ym2612_st->TBT = 0;
|
||||
}
|
||||
return 0;
|
||||
case 0x27: /* mode, timer control */
|
||||
|
@ -229,38 +219,6 @@ int YM2612Write_940(unsigned int a, unsigned int v)
|
|||
return 0; // cause the engine to do updates once per frame only
|
||||
}
|
||||
|
||||
UINT8 YM2612Read_940(void)
|
||||
{
|
||||
return ST_status;
|
||||
}
|
||||
|
||||
|
||||
int YM2612PicoTick_940(int n)
|
||||
{
|
||||
//int ret = 0;
|
||||
|
||||
// timer A
|
||||
if(ST_mode & 0x01 && (ST_TAT+=64*n) >= ST_TAC) {
|
||||
ST_TAT -= ST_TAC;
|
||||
if(ST_mode & 0x04) ST_status |= 1;
|
||||
// CSM mode total level latch and auto key on
|
||||
/* FIXME
|
||||
if(ST_mode & 0x80) {
|
||||
CSMKeyControll( &(ym2612_940->CH[2]) ); // Vectorman2, etc.
|
||||
ret = 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// timer B
|
||||
if(ST_mode & 0x02 && (ST_TBT+=64*n) >= ST_TBC) {
|
||||
ST_TBT -= ST_TBC;
|
||||
if(ST_mode & 0x08) ST_status |= 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define CHECK_BUSY(job) \
|
||||
(gp2x_memregs[0x3b46>>1] & (1<<(job-1)))
|
||||
|
@ -339,12 +297,14 @@ void YM2612PicoStateLoad_940(void)
|
|||
static void internal_reset(void)
|
||||
{
|
||||
writebuff_ptr = 0;
|
||||
ST_mode = 0;
|
||||
ST_status = 0; /* normal mode */
|
||||
ST_TA = 0;
|
||||
ST_TAC = 0;
|
||||
ST_TB = 0;
|
||||
ST_TBC = 0;
|
||||
ym2612_st->mode = 0;
|
||||
ym2612_st->status = 0; /* normal mode */
|
||||
ym2612_st->TA = 0;
|
||||
ym2612_st->TAC = 0;
|
||||
ym2612_st->TAT = 0;
|
||||
ym2612_st->TB = 0;
|
||||
ym2612_st->TBC = 0;
|
||||
ym2612_st->TBT = 0;
|
||||
dacen = 0;
|
||||
dacout = 0;
|
||||
ST_address= 0;
|
||||
|
|
|
@ -138,15 +138,10 @@ endif
|
|||
all: PicoDrive.gpe
|
||||
|
||||
PicoDrive.gpe : $(OBJS) ../common/helix/helix_mp3.a
|
||||
@echo $@
|
||||
@$(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map
|
||||
@echo ">>>" $@
|
||||
$(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map
|
||||
ifeq ($(DEBUG),)
|
||||
@$(STRIP) $@
|
||||
endif
|
||||
# @$(GCC) $(COPT) $(OBJS) -lm -o PicoDrive_.gpe
|
||||
# @gpecomp PicoDrive_.gpe $@
|
||||
ifeq "$(up)" "1"
|
||||
@cmd //C copy $@ \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\
|
||||
$(STRIP) $@
|
||||
endif
|
||||
|
||||
up: PicoDrive.gpe
|
||||
|
@ -155,45 +150,40 @@ up: PicoDrive.gpe
|
|||
# @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\
|
||||
|
||||
|
||||
testrefr.gpe : test.o gp2x.o
|
||||
@echo $@
|
||||
@$(GCC) $(COPT) $^ -o $@
|
||||
@$(STRIP) $@
|
||||
|
||||
.c.o:
|
||||
@echo $<
|
||||
@$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||
.s.o:
|
||||
@echo $<
|
||||
@$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||
|
||||
../../Pico/draw_asm.o : ../../Pico/Draw.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/draw2_asm.o : ../../Pico/Draw2.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/memory_asm.o : ../../Pico/Memory.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/sound/ym2612_asm.o : ../../Pico/sound/ym2612.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/sound/mix_asm.o : ../../Pico/sound/mix.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/misc_asm.o : ../../Pico/Misc.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/cd/memory_asm.o : ../../Pico/cd/Memory.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
../../Pico/cd/misc_asm.o : ../../Pico/cd/Misc.s
|
||||
@echo $<
|
||||
@$(AS) $(ASOPT) $< -o $@
|
||||
@echo ">>>" $<
|
||||
$(AS) $(ASOPT) $< -o $@
|
||||
|
||||
# build Cyclone
|
||||
../../cpu/Cyclone/proj/Cyclone.s :
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#define VERSION "1.34"
|
||||
#define VERSION "1.35"
|
||||
|
||||
|
|
|
@ -40,19 +40,6 @@ int YM2612Write_940(unsigned int a, unsigned int v)
|
|||
return 0; // cause the engine to do updates once per frame only
|
||||
}
|
||||
|
||||
UINT8 YM2612Read_940(void)
|
||||
{
|
||||
return YM2612Read_();
|
||||
}
|
||||
|
||||
|
||||
int YM2612PicoTick_940(int n)
|
||||
{
|
||||
YM2612PicoTick_(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void YM2612PicoStateLoad_940(void)
|
||||
{
|
||||
|
|
|
@ -13,8 +13,8 @@ STRIP = strip
|
|||
AS = gcc
|
||||
|
||||
ifeq "$(profile)" "1"
|
||||
COPT_COMMON = -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -fprofile-generate # -static
|
||||
COPT = $(COPT_COMMON) # -mtune=arm920t
|
||||
COPT_COMMON = -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -fprofile-generate
|
||||
COPT = $(COPT_COMMON)
|
||||
else
|
||||
COPT = -ggdb -Wall -fno-strict-aliasing # -pg -O3 -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -ffast-math
|
||||
COPT_COMMON = $(COPT)
|
||||
|
|
|
@ -6,23 +6,19 @@ PSPSDK = $(shell psp-config --pspsdk-path)
|
|||
#use_musashi = 1
|
||||
#use_mz80 = 1
|
||||
amalgamate = 0
|
||||
#profile = 1
|
||||
#up = 1
|
||||
|
||||
|
||||
CFLAGS += -I../.. -I. -DNO_SYNC -DLPRINTF_STDIO
|
||||
CFLAGS += -Wall -Winline -G0
|
||||
CFLAGS += -DLPRINTF_STDIO
|
||||
#CFLAGS += -fprofile-generate
|
||||
#CFLAGS += -fprofile-use
|
||||
#CFLAGS += -pg
|
||||
ifeq ($(DEBUG),)
|
||||
CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math
|
||||
else
|
||||
CFLAGS += -ggdb
|
||||
endif
|
||||
ifeq "$(profile)" "1"
|
||||
CFLAGS += -fprofile-generate
|
||||
endif
|
||||
ifeq "$(profile)" "2"
|
||||
CFLAGS += -fprofile-use
|
||||
endif
|
||||
|
||||
|
||||
# frontend
|
||||
|
@ -37,7 +33,7 @@ OBJS += ../../PicoAll.o
|
|||
else
|
||||
OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.o \
|
||||
../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o \
|
||||
../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o
|
||||
../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o ../../Pico/Misc_amips.o
|
||||
# Pico - CD
|
||||
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/gfx_cd.o \
|
||||
|
@ -77,8 +73,10 @@ OBJS += data/bg32.o data/bg40.o
|
|||
|
||||
|
||||
LIBS += -lpng -lm -lpspgu -lpsppower -lpspaudio -lpsprtc -lpspaudiocodec
|
||||
#LIBS += -lpspprof
|
||||
LDFLAGS += -Wl,-Map=PicoDrive.map
|
||||
|
||||
|
||||
# target
|
||||
TARGET = PicoDrive
|
||||
EXTRA_TARGETS = EBOOT.PBP
|
||||
|
@ -114,7 +112,11 @@ AS := psp-as
|
|||
|
||||
../../Pico/Draw.o : ../../Pico/Draw.c
|
||||
@echo ">>>" $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@ -D_ASM_DRAW_C_MIPS
|
||||
$(CC) $(CFLAGS) -c $< -o $@ -D_ASM_DRAW_C_AMIPS
|
||||
|
||||
../../Pico/Misc.o : ../../Pico/Misc.c
|
||||
@echo ">>>" $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@ -D_ASM_MISC_C_AMIPS
|
||||
|
||||
readme.txt: ../../tools/textfilter ../base_readme.txt
|
||||
../../tools/textfilter ../base_readme.txt $@ PSP
|
||||
|
@ -152,6 +154,5 @@ endif
|
|||
|
||||
# ?
|
||||
rel: EBOOT.PBP readme.txt
|
||||
zip -9 -j ../../PicoDrive_$(VER).zip $^
|
||||
# zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt
|
||||
zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "psp.h"
|
||||
#include "menu.h"
|
||||
#include "emu.h"
|
||||
#include "mp3.h"
|
||||
#include "../common/emu.h"
|
||||
#include "../common/lprintf.h"
|
||||
#include "../../Pico/PicoInt.h"
|
||||
|
@ -57,7 +58,7 @@ static void osd_text(int x, const char *text, int is_active, int clear_all)
|
|||
for (h = 0; h < 8; h++) {
|
||||
p = (int *) (screen+x+512*(264+h));
|
||||
p = (int *) ((int)p & ~3); // align
|
||||
memset32(p, 0, len);
|
||||
memset32_uncached(p, 0, len);
|
||||
}
|
||||
if (is_active) { tmp = psp_screen; psp_screen = screen; } // nasty pointer tricks
|
||||
emu_textOut16(x, 264, text);
|
||||
|
@ -126,8 +127,8 @@ void emu_setDefaultConfig(void)
|
|||
{
|
||||
memset(¤tConfig, 0, sizeof(currentConfig));
|
||||
currentConfig.lastRomFile[0] = 0;
|
||||
currentConfig.EmuOpt = 0x1f | 0x680; // | confirm_save, cd_leds, 16bit rend
|
||||
currentConfig.PicoOpt = 0x0f | 0xc00; // | cd_pcm, cd_cdda
|
||||
currentConfig.EmuOpt = 0x1d | 0x680; // | confirm_save, cd_leds, acc rend
|
||||
currentConfig.PicoOpt = 0x0f | 0x1c00; // | gfx_cd, cd_pcm, cd_cdda
|
||||
currentConfig.PsndRate = 22050;
|
||||
currentConfig.PicoRegion = 0; // auto
|
||||
currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP
|
||||
|
@ -172,7 +173,7 @@ static int fbimg_offs = 0;
|
|||
|
||||
static void set_scaling_params(void)
|
||||
{
|
||||
int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs;
|
||||
int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs, border_hack = 0;
|
||||
g_vertices[0].x = g_vertices[0].y =
|
||||
g_vertices[0].z = g_vertices[1].z = 0;
|
||||
|
||||
|
@ -185,9 +186,13 @@ static void set_scaling_params(void)
|
|||
src_width = 256;
|
||||
}
|
||||
|
||||
if (fbimg_width & 1) fbimg_width++; // make even
|
||||
if (fbimg_height & 1) fbimg_height++;
|
||||
|
||||
if (fbimg_width >= 480) {
|
||||
g_vertices[0].u = (fbimg_width-480)/2;
|
||||
g_vertices[1].u = src_width - (fbimg_width-480)/2;
|
||||
g_vertices[1].u = src_width - (fbimg_width-480)/2 - 1;
|
||||
if (fbimg_width == 480) border_hack = 1;
|
||||
fbimg_width = 480;
|
||||
fbimg_xoffs = 0;
|
||||
} else {
|
||||
|
@ -211,6 +216,12 @@ static void set_scaling_params(void)
|
|||
g_vertices[1].y = fbimg_height;
|
||||
if (fbimg_xoffs < 0) fbimg_xoffs = 0;
|
||||
if (fbimg_yoffs < 0) fbimg_yoffs = 0;
|
||||
if (border_hack) {
|
||||
g_vertices[0].u++;
|
||||
g_vertices[0].x++;
|
||||
g_vertices[1].u--;
|
||||
g_vertices[1].x--;
|
||||
}
|
||||
fbimg_offs = (fbimg_yoffs*512 + fbimg_xoffs) * 2; // dst is always 16bit
|
||||
|
||||
/*
|
||||
|
@ -371,7 +382,7 @@ static void cd_leds(void)
|
|||
*p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void dbg_text(void)
|
||||
{
|
||||
int *p, h, len;
|
||||
|
@ -382,11 +393,11 @@ static void dbg_text(void)
|
|||
for (h = 0; h < 8; h++) {
|
||||
p = (int *) ((unsigned short *) psp_screen+2+512*(256+h));
|
||||
p = (int *) ((int)p & ~3); // align
|
||||
memset32(p, 0, len);
|
||||
memset32_uncached(p, 0, len);
|
||||
}
|
||||
emu_textOut16(2, 256, text);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* called after rendering is done, but frame emulation is not finished */
|
||||
void blit1(void)
|
||||
|
@ -415,7 +426,7 @@ static void blit2(const char *fps, const char *notice, int lagging_behind)
|
|||
if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
|
||||
}
|
||||
|
||||
dbg_text();
|
||||
//dbg_text();
|
||||
|
||||
if ((emu_opt & 0x400) && (PicoMCD & 1))
|
||||
cd_leds();
|
||||
|
@ -431,15 +442,15 @@ static void blit2(const char *fps, const char *notice, int lagging_behind)
|
|||
static void clearArea(int full)
|
||||
{
|
||||
if (full) {
|
||||
memset32(psp_screen, 0, 512*272*2/4);
|
||||
memset32_uncached(psp_screen, 0, 512*272*2/4);
|
||||
psp_video_flip(0);
|
||||
memset32(psp_screen, 0, 512*272*2/4);
|
||||
memset32_uncached(psp_screen, 0, 512*272*2/4);
|
||||
memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*240/4);
|
||||
memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4);
|
||||
} else {
|
||||
void *fb = psp_video_get_active_fb();
|
||||
memset32((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
|
||||
memset32((int *)((char *)fb + 512*264*2), 0, 512*8*2/4);
|
||||
memset32_uncached((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
|
||||
memset32_uncached((int *)((char *)fb + 512*264*2), 0, 512*8*2/4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,7 +670,7 @@ void emu_forcedFrame(void)
|
|||
vidResetMode();
|
||||
memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
|
||||
memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
|
||||
memset32((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
|
||||
memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
|
||||
|
||||
PicoDrawSetColorFormat(-1);
|
||||
PicoScan = EmuScanSlow;
|
||||
|
@ -1036,7 +1047,7 @@ void emu_Loop(void)
|
|||
}
|
||||
|
||||
// clear fps counters and stuff
|
||||
memset32((int *)psp_video_get_active_fb() + 512*264*2/4, 0, 512*8*2/4);
|
||||
memset32_uncached((int *)psp_video_get_active_fb() + 512*264*2/4, 0, 512*8*2/4);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,4 +28,6 @@ void emu_forcedFrame(void);
|
|||
|
||||
void emu_msg_cb(const char *msg);
|
||||
|
||||
// actually comes from Pico/Misc_amips.s
|
||||
void memset32_uncached(int *dest, int c, int count);
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ void menu_romload_prepare(const char *rom_name)
|
|||
|
||||
psp_video_switch_to_single();
|
||||
if (rom_data) menu_draw_begin();
|
||||
else memset32(psp_screen, 0, 512*272*2/4);
|
||||
else memset32_uncached(psp_screen, 0, 512*272*2/4);
|
||||
|
||||
smalltext_out16(1, 1, "Loading", 0xffff);
|
||||
smalltext_out16_lim(1, 10, p, 0xffff, 80);
|
||||
|
@ -453,8 +453,10 @@ static void draw_debug(void)
|
|||
|
||||
static void debug_menu_loop(void)
|
||||
{
|
||||
int ret = 0;
|
||||
draw_debug();
|
||||
wait_for_input(BTN_X|BTN_CIRCLE, 0);
|
||||
while (!(ret & (BTN_X|BTN_CIRCLE)))
|
||||
ret = wait_for_input(BTN_X|BTN_CIRCLE, 0);
|
||||
}
|
||||
|
||||
// ------------ patch/gg menu ------------
|
||||
|
@ -1059,7 +1061,7 @@ static void menu_opt3_preview(int is_32col)
|
|||
lprintf("uncompress returned %i\n", ret);
|
||||
}
|
||||
|
||||
memset32(psp_screen, 0, 512*272*2/4);
|
||||
memset32_uncached(psp_screen, 0, 512*272*2/4);
|
||||
emu_forcedFrame();
|
||||
menu_prepare_bg(1, 0);
|
||||
|
||||
|
@ -1119,6 +1121,7 @@ static void dispmenu_loop_options(void)
|
|||
if (setting != NULL) {
|
||||
while ((inp = psp_pad_read(0)) & (BTN_LEFT|BTN_RIGHT)) {
|
||||
*setting += (inp & BTN_LEFT) ? -0.01 : 0.01;
|
||||
if (*setting <= 0) *setting = 0.01;
|
||||
menu_opt3_preview(is_32col);
|
||||
draw_dispmenu_options(menu_sel); // will wait vsync
|
||||
}
|
||||
|
@ -1735,12 +1738,12 @@ static void menu_prepare_bg(int use_game_bg, int use_fg)
|
|||
int i;
|
||||
for (i = 272; i > 0; i--, dst += 480, src += 512)
|
||||
menu_darken_bg(dst, src, 480, 1);
|
||||
//memset32((int *)(bg_buffer + 480*264), 0, 480*8*2/4);
|
||||
//memset32_uncached((int *)(bg_buffer + 480*264), 0, 480*8*2/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// should really only happen once, on startup..
|
||||
memset32((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4);
|
||||
memset32_uncached((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4);
|
||||
readpng(bg_buffer, "skin/background.png", READPNG_BG);
|
||||
}
|
||||
sceKernelDcacheWritebackAll();
|
||||
|
@ -1814,7 +1817,7 @@ int menu_loop_tray(void)
|
|||
for (;;)
|
||||
{
|
||||
draw_menu_tray(menu_sel);
|
||||
inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_X, 0);
|
||||
inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_CIRCLE, 0);
|
||||
if(inp & BTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
|
||||
if(inp & BTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
|
||||
if(inp & BTN_CIRCLE) {
|
||||
|
|
|
@ -181,8 +181,6 @@ int mp3_init(void)
|
|||
goto fail2;
|
||||
}
|
||||
|
||||
lprintf("thread_busy_sem: %08x, thread_job_sem: %08x\n", thread_busy_sem, thread_job_sem);
|
||||
|
||||
thread_exit = 0;
|
||||
thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, 0); /* use slightly higher prio then main */
|
||||
if (thid < 0) {
|
||||
|
@ -273,7 +271,7 @@ static int decode_thread(SceSize args, void *argp)
|
|||
|
||||
int mp3_get_bitrate(FILE *f, int size)
|
||||
{
|
||||
int ret = -1, sample_rate, bitrate;
|
||||
int ret, retval = -1, sample_rate, bitrate;
|
||||
// filenames are stored instead handles in PSP, due to stupid max open file limit
|
||||
char *fname = (char *)f;
|
||||
|
||||
|
@ -307,14 +305,14 @@ int mp3_get_bitrate(FILE *f, int size)
|
|||
}
|
||||
|
||||
/* looking good.. */
|
||||
ret = bitrate;
|
||||
retval = bitrate;
|
||||
end:
|
||||
if (mp3_handle >= 0) sceIoClose(mp3_handle);
|
||||
mp3_handle = -1;
|
||||
mp3_fname = NULL;
|
||||
psp_sem_unlock(thread_busy_sem);
|
||||
if (ret < 0) mp3_last_error = -1; // remember we had a problem..
|
||||
return ret;
|
||||
if (retval < 0) mp3_last_error = -1; // remember we had a problem..
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
|
8
platform/psp/mp3.h
Normal file
8
platform/psp/mp3.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
// additional stuff for PSP mp3 decoder implementation
|
||||
extern int mp3_last_error;
|
||||
|
||||
int mp3_init(void);
|
||||
void mp3_deinit(void);
|
||||
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
#include <pspgu.h>
|
||||
|
||||
#include "psp.h"
|
||||
#include "emu.h"
|
||||
#include "../common/lprintf.h"
|
||||
|
||||
PSP_MODULE_INFO("PicoDrive", 0, 1, 34);
|
||||
|
@ -28,6 +29,19 @@ static int exit_callback(int arg1, int arg2, void *common)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Power Callback */
|
||||
static int power_callback(int unknown, int pwrflags, void *common)
|
||||
{
|
||||
/* check for power switch and suspending as one is manual and the other automatic */
|
||||
if (pwrflags & PSP_POWER_CB_POWER_SWITCH || pwrflags & PSP_POWER_CB_SUSPENDING)
|
||||
{
|
||||
lprintf("power_callback: flags: 0x%08X: suspending\n", pwrflags);
|
||||
engineState = PGS_Menu;
|
||||
}
|
||||
sceDisplayWaitVblankStart();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Callback thread */
|
||||
static int callback_thread(SceSize args, void *argp)
|
||||
{
|
||||
|
@ -38,6 +52,8 @@ static int callback_thread(SceSize args, void *argp)
|
|||
|
||||
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
|
||||
sceKernelRegisterExitCallback(cbid);
|
||||
cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
|
||||
scePowerRegisterCallback(0, cbid);
|
||||
|
||||
sceKernelSleepThreadCB();
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#define VERSION "1.34"
|
||||
#define VERSION "1.35"
|
||||
|
||||
|
|
110
tools/gcda.c
Normal file
110
tools/gcda.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static int search_gcda(const char *str, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len - 6; i++)
|
||||
if (str[i] == '.' && str[i+1] == 'g' && str[i+2] == 'c' &&
|
||||
str[i+3] == 'd' && str[i+4] == 'a' && str[i+5] == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int is_good_char(char c)
|
||||
{
|
||||
return c >= ' ' && c < 0x7f;
|
||||
}
|
||||
|
||||
static int is_good_path(char *path)
|
||||
{
|
||||
int len = strlen(path);
|
||||
|
||||
path[len-2] = 'n';
|
||||
path[len-1] = 'o';
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
|
||||
path[len-2] = 'd';
|
||||
path[len-1] = 'a';
|
||||
|
||||
if (f) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char buff[1024], *p;
|
||||
char cwd[4096];
|
||||
FILE *f;
|
||||
int l, pos, pos1, old_len, cwd_len;
|
||||
|
||||
if (argc != 2) return 1;
|
||||
|
||||
getcwd(cwd, sizeof(cwd));
|
||||
cwd_len = strlen(cwd);
|
||||
if (cwd[cwd_len-1] != '/') {
|
||||
cwd[cwd_len++] = '/';
|
||||
cwd[cwd_len] = 0;
|
||||
}
|
||||
|
||||
f = fopen(argv[1], "rb+");
|
||||
if (f == NULL) return 2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
readnext:
|
||||
l = fread(buff, 1, sizeof(buff), f);
|
||||
if (l <= 16) break;
|
||||
|
||||
pos = 0;
|
||||
while (pos < l)
|
||||
{
|
||||
pos1 = search_gcda(buff + pos, l - pos);
|
||||
if (pos1 < 0) {
|
||||
fseek(f, -5, SEEK_CUR);
|
||||
goto readnext;
|
||||
}
|
||||
pos += pos1;
|
||||
|
||||
while (pos > 0 && is_good_char(buff[pos-1])) pos--;
|
||||
|
||||
if (pos == 0) {
|
||||
fseek(f, -16, SEEK_CUR);
|
||||
goto readnext;
|
||||
}
|
||||
|
||||
// paths must start with /
|
||||
while (pos < l && buff[pos] != '/') pos++;
|
||||
p = buff + pos;
|
||||
old_len = strlen(p);
|
||||
|
||||
if (!is_good_path(p)) {
|
||||
pos += old_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(p, cwd, cwd_len) != 0) {
|
||||
printf("can't handle: %s\n", p);
|
||||
pos += old_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
memmove(p, p + cwd_len, old_len - cwd_len + 1);
|
||||
fseek(f, -(sizeof(buff) - pos), SEEK_CUR);
|
||||
fwrite(p, 1, old_len, f);
|
||||
goto readnext;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue