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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _ASM_DRAW_C_MIPS
|
#ifdef _ASM_DRAW_C_AMIPS
|
||||||
int TileNorm(int sx,int addr,int pal);
|
int TileNorm(int sx,int addr,int pal);
|
||||||
int TileFlip(int sx,int addr,int pal);
|
int TileFlip(int sx,int addr,int pal);
|
||||||
#else
|
#else
|
||||||
|
@ -1127,8 +1127,7 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh)
|
||||||
#ifndef _ASM_DRAW_C
|
#ifndef _ASM_DRAW_C
|
||||||
static void BackFill(int reg7, int sh)
|
static void BackFill(int reg7, int sh)
|
||||||
{
|
{
|
||||||
unsigned int back=0;
|
unsigned int back;
|
||||||
unsigned int *pd=NULL,*end=NULL;
|
|
||||||
|
|
||||||
// Start with a blank scanline (background colour):
|
// Start with a blank scanline (background colour):
|
||||||
back=reg7&0x3f;
|
back=reg7&0x3f;
|
||||||
|
@ -1136,10 +1135,7 @@ static void BackFill(int reg7, int sh)
|
||||||
back|=back<<8;
|
back|=back<<8;
|
||||||
back|=back<<16;
|
back|=back<<16;
|
||||||
|
|
||||||
pd= (unsigned int *)(HighCol+8);
|
memset32((int *)(HighCol+8), back, 320/4);
|
||||||
end=(unsigned int *)(HighCol+8+320);
|
|
||||||
|
|
||||||
do { pd[0]=pd[1]=pd[2]=pd[3]=back; pd+=4; } while (pd<end);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
10
Pico/Draw2.c
10
Pico/Draw2.c
|
@ -485,8 +485,7 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
|
||||||
#ifndef _ASM_DRAW_C
|
#ifndef _ASM_DRAW_C
|
||||||
static void BackFillFull(int reg7)
|
static void BackFillFull(int reg7)
|
||||||
{
|
{
|
||||||
unsigned int back, i;
|
unsigned int back;
|
||||||
unsigned int *p=(unsigned int *)PicoDraw2FB;
|
|
||||||
|
|
||||||
// Start with a background color:
|
// Start with a background color:
|
||||||
// back=PicoCramHigh[reg7&0x3f];
|
// back=PicoCramHigh[reg7&0x3f];
|
||||||
|
@ -494,12 +493,7 @@ static void BackFillFull(int reg7)
|
||||||
back|=back<<8;
|
back|=back<<8;
|
||||||
back|=back<<16;
|
back|=back<<16;
|
||||||
|
|
||||||
for(i = LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/16; i; i--) {
|
memset32((int *)PicoDraw2FB, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);
|
||||||
*p++ = back; // do 16 pixels per iteration
|
|
||||||
*p++ = back;
|
|
||||||
*p++ = back;
|
|
||||||
*p++ = back;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -334,9 +334,12 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
|
||||||
log_io(a, 8, 0);
|
log_io(a, 8, 0);
|
||||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
|
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
|
#ifdef __debug_io
|
||||||
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
|
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
|
||||||
#endif
|
#endif
|
||||||
|
@ -370,7 +373,9 @@ PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
|
||||||
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
|
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
|
||||||
log_io(a, 16, 0);
|
log_io(a, 16, 0);
|
||||||
|
|
||||||
d = OtherRead16(a, 16);
|
if ((a&0xe700e0)==0xc00000)
|
||||||
|
d = PicoVideoRead(a);
|
||||||
|
else d = OtherRead16(a, 16);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
#ifdef __debug_io
|
#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
|
if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
|
||||||
log_io(a, 32, 0);
|
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:
|
end:
|
||||||
#ifdef __debug_io
|
#ifdef __debug_io
|
||||||
|
@ -454,6 +461,7 @@ void PicoWrite16(u32 a,u16 d)
|
||||||
log_io(a, 16, 1);
|
log_io(a, 16, 1);
|
||||||
|
|
||||||
a&=0xfffffe;
|
a&=0xfffffe;
|
||||||
|
if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
|
||||||
OtherWrite16(a,d);
|
OtherWrite16(a,d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +484,14 @@ static void PicoWrite32(u32 a,u32 d)
|
||||||
log_io(a, 32, 1);
|
log_io(a, 32, 1);
|
||||||
|
|
||||||
a&=0xfffffe;
|
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, (u16)(d>>16));
|
||||||
OtherWrite16(a+2,(u16)d);
|
OtherWrite16(a+2,(u16)d);
|
||||||
}
|
}
|
||||||
|
@ -660,10 +676,6 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
|
||||||
{
|
{
|
||||||
u8 ret = 0;
|
u8 ret = 0;
|
||||||
|
|
||||||
#ifndef _USE_DRZ80
|
|
||||||
if (a<0x4000) return Pico.zram[a&0x1fff];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
|
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
|
||||||
{
|
{
|
||||||
if (PicoOpt&1) ret = (u8) YM2612Read();
|
if (PicoOpt&1) ret = (u8) YM2612Read();
|
||||||
|
@ -681,10 +693,8 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _USE_DRZ80
|
// should not be needed, cores should be able to access RAM themselves
|
||||||
// should not be needed || dprintf("z80_read RAM");
|
|
||||||
if (a<0x4000) return Pico.zram[a&0x1fff];
|
if (a<0x4000) return Pico.zram[a&0x1fff];
|
||||||
#endif
|
|
||||||
|
|
||||||
elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);
|
elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);
|
||||||
return 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)
|
PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef _USE_DRZ80
|
|
||||||
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
|
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
|
||||||
{
|
{
|
||||||
if(PicoOpt&1) emustatus|=YM2612Write(a, data) & 1;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _USE_DRZ80
|
// should not be needed
|
||||||
// should not be needed, drZ80 knows how to access RAM itself || dprintf("z80_write RAM @ %08x", lr);
|
|
||||||
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
|
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
|
||||||
#endif
|
|
||||||
|
|
||||||
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
|
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,17 +386,14 @@ m_read8_misc2:
|
||||||
cmp r2, #0x4000
|
cmp r2, #0x4000
|
||||||
mvnne r0, #0
|
mvnne r0, #0
|
||||||
bxne lr @ invalid
|
bxne lr @ invalid
|
||||||
.if EXTERNAL_YM2612
|
|
||||||
ldr r1, =PicoOpt
|
ldr r1, =PicoOpt
|
||||||
ldr r1, [r1]
|
ldr r1, [r1]
|
||||||
tst r1, #1
|
tst r1, #1
|
||||||
beq m_read8_fake_ym2612
|
|
||||||
tst r1, #0x200
|
ldrne r1, =ym2612_st
|
||||||
beq YM2612Read_
|
ldrne r1, [r1]
|
||||||
b YM2612Read_940
|
ldrneb r0, [r1, #0x11] @ ym2612_st->status
|
||||||
.else
|
bxne lr
|
||||||
b YM2612Read_
|
|
||||||
.endif
|
|
||||||
|
|
||||||
m_read8_fake_ym2612:
|
m_read8_fake_ym2612:
|
||||||
ldr r3, =(Pico+0x22200)
|
ldr r3, =(Pico+0x22200)
|
||||||
|
|
|
@ -72,9 +72,9 @@ static
|
||||||
void z80WriteBusReq(u32 d)
|
void z80WriteBusReq(u32 d)
|
||||||
{
|
{
|
||||||
d&=1; d^=1;
|
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)
|
// this is for a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)
|
||||||
if (Pico.m.z80Run) {
|
if (Pico.m.z80Run) {
|
||||||
int lineCycles;
|
int lineCycles;
|
||||||
|
@ -85,7 +85,7 @@ void z80WriteBusReq(u32 d)
|
||||||
if (lineCycles > 0) { // && lineCycles <= 488) {
|
if (lineCycles > 0) { // && lineCycles <= 488) {
|
||||||
//dprintf("zrun: %i/%i cycles", lineCycles, (lineCycles>>1)-(lineCycles>>5));
|
//dprintf("zrun: %i/%i cycles", lineCycles, (lineCycles>>1)-(lineCycles>>5));
|
||||||
lineCycles=(lineCycles>>1)-(lineCycles>>5);
|
lineCycles=(lineCycles>>1)-(lineCycles>>5);
|
||||||
z80_run(lineCycles);
|
z80_run_nr(lineCycles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -136,10 +136,6 @@ u32 OtherRead16(u32 a, int realsize)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _ASM_MEMORY_C
|
|
||||||
if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
d = OtherRead16End(a, realsize);
|
d = OtherRead16End(a, realsize);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -204,7 +200,6 @@ static
|
||||||
#endif
|
#endif
|
||||||
void OtherWrite16(u32 a,u32 d)
|
void OtherWrite16(u32 a,u32 d)
|
||||||
{
|
{
|
||||||
if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }
|
|
||||||
if (a==0xa11100) { z80WriteBusReq(d>>8); return; }
|
if (a==0xa11100) { z80WriteBusReq(d>>8); return; }
|
||||||
if (a==0xa11200) { dprintf("write z80reset: %04x", d); if(!(d&0x100)) z80_reset(); 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
|
if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports
|
||||||
|
|
|
@ -425,8 +425,10 @@ m_read8_z80_misc:
|
||||||
andi $t0, 1
|
andi $t0, 1
|
||||||
beqz $t0, m_read8_fake_ym2612
|
beqz $t0, m_read8_fake_ym2612
|
||||||
lui $t0, %hi(Pico+0x22208)
|
lui $t0, %hi(Pico+0x22208)
|
||||||
j YM2612Read_
|
lui $t0, %hi(ym2612_st)
|
||||||
nop
|
lw $t0, %lo(ym2612_st)($t0)
|
||||||
|
jr $ra
|
||||||
|
lb $v0, 0x11($t0)
|
||||||
|
|
||||||
m_read8_fake_ym2612:
|
m_read8_fake_ym2612:
|
||||||
lb $v0, %lo(Pico+0x22208)($t0) # Pico.m.rotate
|
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];
|
*dest++ = (src_[0] << 8) | src_[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _ASM_MISC_C_AMIPS
|
||||||
PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)
|
PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)
|
||||||
{
|
{
|
||||||
intblock *bd = (intblock *) dest, *bs = (intblock *) src;
|
intblock *bd = (intblock *) dest, *bs = (intblock *) src;
|
||||||
|
@ -376,5 +376,7 @@ PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)
|
||||||
while (count--)
|
while (count--)
|
||||||
*dest++ = c;
|
*dest++ = c;
|
||||||
}
|
}
|
||||||
|
void memset32_uncached(int *dest, int c, int count) { memset32(dest, c, count); }
|
||||||
|
#endif
|
||||||
#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 == 224 || line == line_sample) && PsndOut) getSamples(line);
|
||||||
if (line == 32 && PsndOut) emustatus &= ~1;
|
if (line == 32 && PsndOut) emustatus &= ~1;
|
||||||
if (line >= line_from_r && line < line_to_r)
|
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) {
|
} 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
|
// 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 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 SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
|
||||||
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))
|
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))
|
||||||
|
|
||||||
|
#define SekInterrupt(i) PicoCpuCM68k.irq=i
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
#define EMU_CORE_DEBUG
|
#define EMU_CORE_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,7 +59,7 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
|
||||||
|
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
#include "../cpu/fame/fame.h"
|
#include "../cpu/fame/fame.h"
|
||||||
M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
||||||
#define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter
|
#define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter
|
||||||
#define SekCyclesLeft \
|
#define SekCyclesLeft \
|
||||||
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
(((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; } \
|
if (x) { PicoCpuFS68k.execinfo |= FM68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \
|
||||||
}
|
}
|
||||||
#define SekShouldInterrupt fm68k_would_interrupt()
|
#define SekShouldInterrupt fm68k_would_interrupt()
|
||||||
|
|
||||||
|
#define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
#define EMU_CORE_DEBUG
|
#define EMU_CORE_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,6 +112,14 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
|
||||||
else PicoCpuMS68k.stopped=0; \
|
else PicoCpuMS68k.stopped=0; \
|
||||||
}
|
}
|
||||||
#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -148,6 +162,46 @@ extern int SekCycleAimS68k;
|
||||||
#define SekEndRun(c)
|
#define SekEndRun(c)
|
||||||
#endif
|
#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;
|
extern int PicoMCD;
|
||||||
|
@ -358,7 +412,6 @@ PICO_INTERNAL int PicoFrameMCD(void);
|
||||||
// Sek.c
|
// Sek.c
|
||||||
PICO_INTERNAL int SekInit(void);
|
PICO_INTERNAL int SekInit(void);
|
||||||
PICO_INTERNAL int SekReset(void);
|
PICO_INTERNAL int SekReset(void);
|
||||||
PICO_INTERNAL int SekInterrupt(int irq);
|
|
||||||
PICO_INTERNAL void SekState(int *data);
|
PICO_INTERNAL void SekState(int *data);
|
||||||
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
||||||
|
|
||||||
|
@ -398,9 +451,6 @@ PICO_INTERNAL int PsndRender(int offset, int length);
|
||||||
PICO_INTERNAL void PsndClear(void);
|
PICO_INTERNAL void PsndClear(void);
|
||||||
// z80 functionality wrappers
|
// z80 functionality wrappers
|
||||||
PICO_INTERNAL void z80_init(void);
|
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_pack(unsigned char *data);
|
||||||
PICO_INTERNAL void z80_unpack(unsigned char *data);
|
PICO_INTERNAL void z80_unpack(unsigned char *data);
|
||||||
PICO_INTERNAL void z80_reset(void);
|
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
|
// data must be word aligned
|
||||||
PICO_INTERNAL void SekState(int *data)
|
PICO_INTERNAL void SekState(int *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -164,8 +164,12 @@ static int g_read_offs = 0;
|
||||||
g_read_offs += len;
|
g_read_offs += len;
|
||||||
|
|
||||||
#define CHECKED_READ2(len2,data) \
|
#define CHECKED_READ2(len2,data) \
|
||||||
if (len2 != len) R_ERROR_RETURN("unexpected len, wanted " #len2); \
|
if (len2 != len) { \
|
||||||
CHECKED_READ(len2, data)
|
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);
|
#define CHECKED_READ_BUFF(buff) CHECKED_READ2(sizeof(buff), &buff);
|
||||||
|
|
||||||
|
|
312
Pico/cd/Memory.c
312
Pico/cd/Memory.c
|
@ -454,47 +454,72 @@ static u32 PicoReadM68k8(u32 a)
|
||||||
{
|
{
|
||||||
u32 d=0;
|
u32 d=0;
|
||||||
|
|
||||||
if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram
|
|
||||||
|
|
||||||
a&=0xffffff;
|
a&=0xffffff;
|
||||||
|
|
||||||
if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios
|
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));
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
// prg RAM
|
d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;
|
||||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
|
||||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
if ((a&0xffffc0)==0xa12000)
|
||||||
d = *(prg_bank+((a^1)&0x1ffff));
|
rdprintf("ret = %02x", (u8)d);
|
||||||
goto end;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// word RAM
|
|
||||||
if ((a&0xfc0000)==0x200000) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
|
|
||||||
|
|
||||||
if ((a&0xffffc0)==0xa12000)
|
|
||||||
rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);
|
|
||||||
|
|
||||||
d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;
|
|
||||||
|
|
||||||
if ((a&0xffffc0)==0xa12000)
|
|
||||||
rdprintf("ret = %02x", (u8)d);
|
|
||||||
|
|
||||||
end:
|
|
||||||
|
|
||||||
#ifdef __debug_io
|
#ifdef __debug_io
|
||||||
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
|
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
|
||||||
|
@ -517,47 +542,71 @@ static u32 PicoReadM68k16(u32 a)
|
||||||
{
|
{
|
||||||
u32 d=0;
|
u32 d=0;
|
||||||
|
|
||||||
if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram
|
|
||||||
|
|
||||||
a&=0xfffffe;
|
a&=0xfffffe;
|
||||||
|
|
||||||
if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios
|
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);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
// prg RAM
|
d = OtherRead16(a, 16);
|
||||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
|
||||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
if ((a&0xffffc0)==0xa12000)
|
||||||
wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);
|
rdprintf("ret = %04x", d);
|
||||||
d = *(u16 *)(prg_bank+(a&0x1fffe));
|
break;
|
||||||
wrdprintf("ret = %04x", d);
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// word RAM
|
|
||||||
if ((a&0xfc0000)==0x200000) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((a&0xffffc0)==0xa12000)
|
|
||||||
rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);
|
|
||||||
|
|
||||||
d = OtherRead16(a, 16);
|
|
||||||
|
|
||||||
if ((a&0xffffc0)==0xa12000)
|
|
||||||
rdprintf("ret = %04x", d);
|
|
||||||
|
|
||||||
end:
|
|
||||||
|
|
||||||
#ifdef __debug_io
|
#ifdef __debug_io
|
||||||
dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
|
dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
|
||||||
|
@ -580,52 +629,81 @@ static u32 PicoReadM68k32(u32 a)
|
||||||
{
|
{
|
||||||
u32 d=0;
|
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;
|
a&=0xfffffe;
|
||||||
|
|
||||||
if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios
|
switch (a >> 17)
|
||||||
|
{
|
||||||
// prg RAM
|
case 0x00>>1: { // BIOS: 000000 - 020000
|
||||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
u16 *pm=(u16 *)(Pico_mcd->bios+a);
|
||||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
d = (pm[0]<<16)|pm[1];
|
||||||
u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));
|
break;
|
||||||
d = (pm[0]<<16)|pm[1];
|
}
|
||||||
goto end;
|
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];
|
||||||
// word RAM
|
u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));
|
||||||
if ((a&0xfc0000)==0x200000) {
|
d = (pm[0]<<16)|pm[1];
|
||||||
wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);
|
}
|
||||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?
|
break;
|
||||||
int bank = Pico_mcd->s68k_regs[3]&1;
|
case 0x20>>1: // word RAM: 200000 - 220000
|
||||||
if (a >= 0x220000) { // cell arranged
|
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;
|
||||||
|
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;
|
u32 a1, a2;
|
||||||
|
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||||
a1 = (a&2) | (cell_map(a >> 2) << 2);
|
a1 = (a&2) | (cell_map(a >> 2) << 2);
|
||||||
if (a&2) a2 = cell_map((a+2) >> 2) << 2;
|
if (a&2) a2 = cell_map((a+2) >> 2) << 2;
|
||||||
else a2 = a1 + 2;
|
else a2 = a1 + 2;
|
||||||
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;
|
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;
|
||||||
d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);
|
d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);
|
||||||
} else {
|
} else {
|
||||||
u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];
|
// allow access in any mode, like Gens does
|
||||||
|
u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));
|
||||||
|
d = (pm[0]<<16)|pm[1];
|
||||||
}
|
}
|
||||||
} else {
|
wrdprintf("ret = %08x", d);
|
||||||
// allow access in any mode, like Gens does
|
break;
|
||||||
u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];
|
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;
|
||||||
}
|
}
|
||||||
wrdprintf("ret = %08x", d);
|
default:
|
||||||
goto end;
|
if ((a&0xffffc0)==0xa12000)
|
||||||
|
rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);
|
||||||
|
|
||||||
|
d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
|
||||||
|
|
||||||
|
if ((a&0xffffc0)==0xa12000)
|
||||||
|
rdprintf("ret = %08x", d);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((a&0xffffc0)==0xa12000)
|
|
||||||
rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);
|
|
||||||
|
|
||||||
d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
|
|
||||||
|
|
||||||
if ((a&0xffffc0)==0xa12000)
|
|
||||||
rdprintf("ret = %08x", d);
|
|
||||||
|
|
||||||
end:
|
|
||||||
#ifdef __debug_io
|
#ifdef __debug_io
|
||||||
dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
|
dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
|
||||||
#endif
|
#endif
|
||||||
|
@ -659,8 +737,6 @@ static void PicoWriteM68k8(u32 a,u8 d)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
a&=0xffffff;
|
|
||||||
|
|
||||||
// prg RAM
|
// prg RAM
|
||||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a&=0xffffff;
|
||||||
|
|
||||||
// word RAM
|
// word RAM
|
||||||
if ((a&0xfc0000)==0x200000) {
|
if ((a&0xfc0000)==0x200000) {
|
||||||
wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);
|
wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);
|
||||||
|
@ -712,8 +790,6 @@ static void PicoWriteM68k16(u32 a,u16 d)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
a&=0xfffffe;
|
|
||||||
|
|
||||||
// prg RAM
|
// prg RAM
|
||||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a&=0xfffffe;
|
||||||
|
|
||||||
// word RAM
|
// word RAM
|
||||||
if ((a&0xfc0000)==0x200000) {
|
if ((a&0xfc0000)==0x200000) {
|
||||||
wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);
|
wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);
|
||||||
|
@ -756,6 +834,12 @@ static void PicoWriteM68k16(u32 a,u16 d)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VDP
|
||||||
|
if ((a&0xe700e0)==0xc00000) {
|
||||||
|
PicoVideoWrite(a,(u16)d);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OtherWrite16(a,d);
|
OtherWrite16(a,d);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -781,8 +865,6 @@ static void PicoWriteM68k32(u32 a,u32 d)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
a&=0xfffffe;
|
|
||||||
|
|
||||||
// prg RAM
|
// prg RAM
|
||||||
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {
|
||||||
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a&=0xfffffe;
|
||||||
|
|
||||||
// word RAM
|
// word RAM
|
||||||
if ((a&0xfc0000)==0x200000) {
|
if ((a&0xfc0000)==0x200000) {
|
||||||
if (d != 0) // don't log clears
|
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);
|
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, (u16)(d>>16));
|
||||||
OtherWrite16(a+2,(u16)d);
|
OtherWrite16(a+2,(u16)d);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,7 @@ PICO_INTERNAL int PicoResetMCD(int hard)
|
||||||
SRam.data = NULL;
|
SRam.data = NULL;
|
||||||
if (PicoOpt&0x8000)
|
if (PicoOpt&0x8000)
|
||||||
SRam.data = calloc(1, 0x12000);
|
SRam.data = calloc(1, 0x12000);
|
||||||
|
SRam.start = SRam.end = 0; // unused
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
|
||||||
dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
|
dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
|
||||||
pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
|
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);
|
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);
|
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);
|
memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048);
|
||||||
moved = 1;
|
moved = 1;
|
||||||
|
if (prev_lba == 0x80000000) printf("wtf?\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -104,17 +106,20 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
#if REDUCE_IO_CALLS
|
#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);
|
pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F);
|
||||||
for (i = 1; i < bufs; i++)
|
for (i = 1; i < bufs; i++)
|
||||||
// should really use memmove here, but my memcpy32 implementation is also suitable here
|
// 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);
|
memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4);
|
||||||
#endif
|
#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_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
|
// 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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// This is part of Pico Library
|
// This is part of Pico Library
|
||||||
|
|
||||||
// (c) Copyright 2004 Dave, All rights reserved.
|
// (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.
|
// Free for non-commercial use.
|
||||||
|
|
||||||
// For commercial use, separate licencing terms must be obtained.
|
// For commercial use, separate licencing terms must be obtained.
|
||||||
|
@ -11,14 +11,6 @@
|
||||||
#include "ym2612.h"
|
#include "ym2612.h"
|
||||||
#include "sn76496.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 "../PicoInt.h"
|
||||||
#include "../cd/pcm.h"
|
#include "../cd/pcm.h"
|
||||||
#include "mix.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;
|
int PsndLen_exc_cnt=0;
|
||||||
short *PsndOut=NULL; // PCM data buffer
|
short *PsndOut=NULL; // PCM data buffer
|
||||||
|
|
||||||
// from ym2612.c
|
|
||||||
extern int *ym2612_dacen;
|
|
||||||
extern INT32 *ym2612_dacout;
|
|
||||||
void YM2612TimerHandler(int c,int cnt);
|
|
||||||
|
|
||||||
// sn76496
|
// sn76496
|
||||||
extern int *sn76496_regs;
|
extern int *sn76496_regs;
|
||||||
|
|
||||||
|
@ -306,9 +293,16 @@ static struct z80PortWrite mz80_io_write[]={
|
||||||
{(UINT16) -1,(UINT16) -1,NULL}
|
{(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)
|
#elif defined(_USE_DRZ80)
|
||||||
|
|
||||||
static struct DrZ80 drZ80;
|
struct DrZ80 drZ80;
|
||||||
|
|
||||||
static unsigned int DrZ80_rebasePC(unsigned short a)
|
static unsigned int DrZ80_rebasePC(unsigned short a)
|
||||||
{
|
{
|
||||||
|
@ -379,7 +373,7 @@ PICO_INTERNAL void z80_init(void)
|
||||||
Cz80_Init(&CZ80);
|
Cz80_Init(&CZ80);
|
||||||
Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM
|
Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM
|
||||||
Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram - 0x2000); // mirror
|
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_WriteB(&CZ80, z80_write);
|
||||||
Cz80_Set_INPort(&CZ80, z80_in);
|
Cz80_Set_INPort(&CZ80, z80_in);
|
||||||
Cz80_Set_OUTPort(&CZ80, z80_out);
|
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.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)
|
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 )
|
if( !SLOT->key )
|
||||||
{
|
{
|
||||||
SLOT->key = 1;
|
SLOT->key = 1;
|
||||||
SLOT->phase = 0; /* restart Phase Generator */
|
SLOT->phase = 0; /* restart Phase Generator */
|
||||||
SLOT->state = EG_ATT; /* phase -> Attack */
|
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 )
|
if( SLOT->key )
|
||||||
{
|
{
|
||||||
SLOT->key = 0;
|
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 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 */
|
UINT32 algo; /* 50: algo[3], was_update */
|
||||||
INT32 op1_out;
|
INT32 op1_out;
|
||||||
|
#ifdef _MIPS_ARCH_ALLEGREX
|
||||||
|
UINT32 pad1[3+8];
|
||||||
|
#endif
|
||||||
} chan_rend_context;
|
} chan_rend_context;
|
||||||
|
|
||||||
|
|
||||||
|
@ -905,16 +909,6 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
||||||
|
|
||||||
switch( ct->CH->ALGO )
|
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:
|
case 0:
|
||||||
{
|
{
|
||||||
/* M1---C1---MEM---M2---C2---OUT */
|
/* M1---C1---MEM---M2---C2---OUT */
|
||||||
|
@ -1064,7 +1058,6 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* done calculating channel sample */
|
/* 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);
|
void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);
|
||||||
#endif
|
#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;
|
flags &= 0x35;
|
||||||
ct.mem = CH->mem_value; /* one sample delay memory */
|
|
||||||
ct.lfo_cnt = ym2612.OPN.lfo_cnt;
|
|
||||||
ct.lfo_inc = ym2612.OPN.lfo_inc;
|
|
||||||
|
|
||||||
flags &= 0x37;
|
if (crct.lfo_inc) {
|
||||||
|
|
||||||
if (ct.lfo_inc) {
|
|
||||||
flags |= 8;
|
flags |= 8;
|
||||||
flags |= g_lfo_ampm << 16;
|
flags |= g_lfo_ampm << 16;
|
||||||
flags |= CH->AMmasks << 8;
|
flags |= crct.CH->AMmasks << 8;
|
||||||
if (CH->ams == 8) // no ams
|
if (crct.CH->ams == 8) // no ams
|
||||||
flags &= ~0xf00;
|
flags &= ~0xf00;
|
||||||
else flags |= (CH->ams&3)<<6;
|
else flags |= (crct.CH->ams&3)<<6;
|
||||||
}
|
}
|
||||||
flags |= (CH->FB&0xf)<<12; /* feedback shift */
|
flags |= (crct.CH->FB&0xf)<<12; /* feedback shift */
|
||||||
ct.pack = flags;
|
crct.pack = flags;
|
||||||
|
|
||||||
ct.eg_cnt = ym2612.OPN.eg_cnt; /* envelope generator counter */
|
crct.eg_cnt = ym2612.OPN.eg_cnt; /* envelope generator counter */
|
||||||
ct.eg_timer = ym2612.OPN.eg_timer;
|
crct.eg_timer = ym2612.OPN.eg_timer;
|
||||||
ct.eg_timer_add = ym2612.OPN.eg_timer_add;
|
crct.eg_timer_add = ym2612.OPN.eg_timer_add;
|
||||||
|
|
||||||
/* precalculate phase modulation incr */
|
/* precalculate phase modulation incr */
|
||||||
ct.phase1 = CH->SLOT[SLOT1].phase;
|
crct.phase1 = crct.CH->SLOT[SLOT1].phase;
|
||||||
ct.phase2 = CH->SLOT[SLOT2].phase;
|
crct.phase2 = crct.CH->SLOT[SLOT2].phase;
|
||||||
ct.phase3 = CH->SLOT[SLOT3].phase;
|
crct.phase3 = crct.CH->SLOT[SLOT3].phase;
|
||||||
ct.phase4 = CH->SLOT[SLOT4].phase;
|
crct.phase4 = crct.CH->SLOT[SLOT4].phase;
|
||||||
|
|
||||||
/* current output from EG circuit (without AM from LFO) */
|
/* current output from EG circuit (without AM from LFO) */
|
||||||
ct.vol_out1 = CH->SLOT[SLOT1].tl + ((UINT32)CH->SLOT[SLOT1].volume);
|
crct.vol_out1 = crct.CH->SLOT[SLOT1].tl + ((UINT32)crct.CH->SLOT[SLOT1].volume);
|
||||||
ct.vol_out2 = CH->SLOT[SLOT2].tl + ((UINT32)CH->SLOT[SLOT2].volume);
|
crct.vol_out2 = crct.CH->SLOT[SLOT2].tl + ((UINT32)crct.CH->SLOT[SLOT2].volume);
|
||||||
ct.vol_out3 = CH->SLOT[SLOT3].tl + ((UINT32)CH->SLOT[SLOT3].volume);
|
crct.vol_out3 = crct.CH->SLOT[SLOT3].tl + ((UINT32)crct.CH->SLOT[SLOT3].volume);
|
||||||
ct.vol_out4 = CH->SLOT[SLOT4].tl + ((UINT32)CH->SLOT[SLOT4].volume);
|
crct.vol_out4 = crct.CH->SLOT[SLOT4].tl + ((UINT32)crct.CH->SLOT[SLOT4].volume);
|
||||||
|
|
||||||
ct.op1_out = CH->op1_out;
|
crct.op1_out = crct.CH->op1_out;
|
||||||
ct.algo = CH->ALGO & 7;
|
crct.algo = crct.CH->ALGO & 7;
|
||||||
|
|
||||||
if(CH->pms)
|
if(crct.CH->pms)
|
||||||
{
|
{
|
||||||
/* add support for 3 slot mode */
|
/* 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;
|
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 */
|
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 */
|
/* phase increment counter */
|
||||||
fc = fn_table[fn]>>(7-blk);
|
fc = fn_table[fn]>>(7-blk);
|
||||||
|
|
||||||
ct.incr1 = ((fc+CH->SLOT[SLOT1].DT[kc])*CH->SLOT[SLOT1].mul) >> 1;
|
crct.incr1 = ((fc+crct.CH->SLOT[SLOT1].DT[kc])*crct.CH->SLOT[SLOT1].mul) >> 1;
|
||||||
ct.incr2 = ((fc+CH->SLOT[SLOT2].DT[kc])*CH->SLOT[SLOT2].mul) >> 1;
|
crct.incr2 = ((fc+crct.CH->SLOT[SLOT2].DT[kc])*crct.CH->SLOT[SLOT2].mul) >> 1;
|
||||||
ct.incr3 = ((fc+CH->SLOT[SLOT3].DT[kc])*CH->SLOT[SLOT3].mul) >> 1;
|
crct.incr3 = ((fc+crct.CH->SLOT[SLOT3].DT[kc])*crct.CH->SLOT[SLOT3].mul) >> 1;
|
||||||
ct.incr4 = ((fc+CH->SLOT[SLOT4].DT[kc])*CH->SLOT[SLOT4].mul) >> 1;
|
crct.incr4 = ((fc+crct.CH->SLOT[SLOT4].DT[kc])*crct.CH->SLOT[SLOT4].mul) >> 1;
|
||||||
}
|
}
|
||||||
else /* LFO phase modulation = zero */
|
else /* LFO phase modulation = zero */
|
||||||
{
|
{
|
||||||
ct.incr1 = CH->SLOT[SLOT1].Incr;
|
crct.incr1 = crct.CH->SLOT[SLOT1].Incr;
|
||||||
ct.incr2 = CH->SLOT[SLOT2].Incr;
|
crct.incr2 = crct.CH->SLOT[SLOT2].Incr;
|
||||||
ct.incr3 = CH->SLOT[SLOT3].Incr;
|
crct.incr3 = crct.CH->SLOT[SLOT3].Incr;
|
||||||
ct.incr4 = CH->SLOT[SLOT4].Incr;
|
crct.incr4 = crct.CH->SLOT[SLOT4].Incr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* no LFO phase modulation */
|
else /* no LFO phase modulation */
|
||||||
{
|
{
|
||||||
ct.incr1 = CH->SLOT[SLOT1].Incr;
|
crct.incr1 = crct.CH->SLOT[SLOT1].Incr;
|
||||||
ct.incr2 = CH->SLOT[SLOT2].Incr;
|
crct.incr2 = crct.CH->SLOT[SLOT2].Incr;
|
||||||
ct.incr3 = CH->SLOT[SLOT3].Incr;
|
crct.incr3 = crct.CH->SLOT[SLOT3].Incr;
|
||||||
ct.incr4 = CH->SLOT[SLOT4].Incr;
|
crct.incr4 = crct.CH->SLOT[SLOT4].Incr;
|
||||||
}
|
}
|
||||||
|
|
||||||
chan_render_loop(&ct, buffer, length);
|
chan_render_loop(&crct, buffer, length);
|
||||||
|
|
||||||
// write back persistent stuff:
|
crct.CH->op1_out = crct.op1_out;
|
||||||
if (flags & 2) { /* last channel */
|
crct.CH->mem_value = crct.mem;
|
||||||
ym2612.OPN.eg_cnt = ct.eg_cnt;
|
if (crct.CH->SLOT[SLOT1].state | crct.CH->SLOT[SLOT2].state | crct.CH->SLOT[SLOT3].state | crct.CH->SLOT[SLOT4].state)
|
||||||
ym2612.OPN.eg_timer = ct.eg_timer;
|
{
|
||||||
g_lfo_ampm = ct.pack >> 16;
|
crct.CH->SLOT[SLOT1].phase = crct.phase1;
|
||||||
ym2612.OPN.lfo_cnt = ct.lfo_cnt;
|
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;
|
return (crct.algo & 8) >> 3; // had output
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update phase increment and envelope generator */
|
/* 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;
|
int c,s;
|
||||||
|
|
||||||
|
@ -1284,7 +1282,7 @@ static void reset_channels(FM_CH *CH, int num)
|
||||||
ym2612.OPN.ST.TB = 0;
|
ym2612.OPN.ST.TB = 0;
|
||||||
ym2612.OPN.ST.TBC = 0;
|
ym2612.OPN.ST.TBC = 0;
|
||||||
|
|
||||||
for( c = 0 ; c < num ; c++ )
|
for( c = 0 ; c < 6 ; c++ )
|
||||||
{
|
{
|
||||||
CH[c].fc = 0;
|
CH[c].fc = 0;
|
||||||
for(s = 0 ; s < 4 ; s++ )
|
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;
|
CH[c].SLOT[s].volume = MAX_ATT_INDEX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ym2612.slot_mask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize generic tables */
|
/* initialize generic tables */
|
||||||
|
@ -1401,6 +1400,7 @@ static void init_tables(void)
|
||||||
|
|
||||||
|
|
||||||
/* CSM Key Controll */
|
/* CSM Key Controll */
|
||||||
|
#if 0
|
||||||
INLINE void CSMKeyControll(FM_CH *CH)
|
INLINE void CSMKeyControll(FM_CH *CH)
|
||||||
{
|
{
|
||||||
/* this is wrong, atm */
|
/* this is wrong, atm */
|
||||||
|
@ -1411,6 +1411,7 @@ INLINE void CSMKeyControll(FM_CH *CH)
|
||||||
FM_KEYON(CH,SLOT3);
|
FM_KEYON(CH,SLOT3);
|
||||||
FM_KEYON(CH,SLOT4);
|
FM_KEYON(CH,SLOT4);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* prescaler set (and make time tables) */
|
/* prescaler set (and make time tables) */
|
||||||
|
@ -1585,6 +1586,7 @@ static int OPNWriteReg(int r, int v)
|
||||||
|
|
||||||
int *ym2612_dacen;
|
int *ym2612_dacen;
|
||||||
INT32 *ym2612_dacout;
|
INT32 *ym2612_dacout;
|
||||||
|
FM_ST *ym2612_st;
|
||||||
|
|
||||||
|
|
||||||
/* Generate samples for YM2612 */
|
/* 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, it means it has valid samples to mix with, else it may contain trash
|
||||||
if (is_buf_empty) memset32(buffer, 0, length<<stereo);
|
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 PG and EG */
|
||||||
refresh_fc_eg_chan( &ym2612.CH[0] );
|
refresh_fc_eg_chan( &ym2612.CH[0] );
|
||||||
refresh_fc_eg_chan( &ym2612.CH[1] );
|
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;
|
if (stereo) stereo = 1;
|
||||||
|
|
||||||
/* mix to 32bit dest */
|
/* mix to 32bit dest */
|
||||||
// flags: stereo, lastchan, disabled, ?, pan_r, pan_l
|
// flags: stereo, ?, disabled, ?, pan_r, pan_l
|
||||||
active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0;
|
if (ym2612.slot_mask & 0x00000f) active_chs |= chan_render(buffer, length, 0, stereo|((pan&0x003)<<4)) << 0;
|
||||||
active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1;
|
if (ym2612.slot_mask & 0x0000f0) active_chs |= chan_render(buffer, length, 1, stereo|((pan&0x00c)<<2)) << 1;
|
||||||
active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )) << 2;
|
if (ym2612.slot_mask & 0x000f00) active_chs |= chan_render(buffer, length, 2, stereo|((pan&0x030) )) << 2;
|
||||||
active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3;
|
if (ym2612.slot_mask & 0x00f000) active_chs |= chan_render(buffer, length, 3, stereo|((pan&0x0c0)>>2)) << 3;
|
||||||
active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4;
|
if (ym2612.slot_mask & 0x0f0000) active_chs |= chan_render(buffer, length, 4, stereo|((pan&0x300)>>4)) << 4;
|
||||||
active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5;
|
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
|
return active_chs; // 1 if buffer updated
|
||||||
}
|
}
|
||||||
|
@ -1636,6 +1656,7 @@ void YM2612Init_(int clock, int rate)
|
||||||
// notaz
|
// notaz
|
||||||
ym2612_dacen = &ym2612.dacen;
|
ym2612_dacen = &ym2612.dacen;
|
||||||
ym2612_dacout = &ym2612.dacout;
|
ym2612_dacout = &ym2612.dacout;
|
||||||
|
ym2612_st = &ym2612.OPN.ST;
|
||||||
|
|
||||||
memset(&ym2612, 0, sizeof(ym2612));
|
memset(&ym2612, 0, sizeof(ym2612));
|
||||||
init_tables();
|
init_tables();
|
||||||
|
@ -1663,7 +1684,7 @@ void YM2612ResetChip_(void)
|
||||||
ym2612.OPN.eg_cnt = 0;
|
ym2612.OPN.eg_cnt = 0;
|
||||||
ym2612.OPN.ST.status = 0;
|
ym2612.OPN.ST.status = 0;
|
||||||
|
|
||||||
reset_channels( &ym2612.CH[0] , 6 );
|
reset_channels( &ym2612.CH[0] );
|
||||||
for(i = 0xb6 ; i >= 0xb4 ; i-- )
|
for(i = 0xb6 ; i >= 0xb4 ; i-- )
|
||||||
{
|
{
|
||||||
OPNWriteReg(i ,0xc0);
|
OPNWriteReg(i ,0xc0);
|
||||||
|
@ -1763,16 +1784,14 @@ int YM2612Write_(unsigned int a, unsigned int v)
|
||||||
case 0x28: /* key on / off */
|
case 0x28: /* key on / off */
|
||||||
{
|
{
|
||||||
UINT8 c;
|
UINT8 c;
|
||||||
FM_CH *CH;
|
|
||||||
|
|
||||||
c = v & 0x03;
|
c = v & 0x03;
|
||||||
if( c == 3 ) { ret=0; break; }
|
if( c == 3 ) { ret=0; break; }
|
||||||
if( v&0x04 ) c+=3;
|
if( v&0x04 ) c+=3;
|
||||||
CH = &ym2612.CH[c];
|
if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);
|
||||||
if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
|
if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);
|
||||||
if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
|
if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);
|
||||||
if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
|
if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4);
|
||||||
if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x2a: /* DAC data (YM2612) */
|
case 0x2a: /* DAC data (YM2612) */
|
||||||
|
@ -1823,12 +1842,12 @@ int YM2612Write_(unsigned int a, unsigned int v)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
UINT8 YM2612Read_(void)
|
UINT8 YM2612Read_(void)
|
||||||
{
|
{
|
||||||
return ym2612.OPN.ST.status;
|
return ym2612.OPN.ST.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int YM2612PicoTick_(int n)
|
int YM2612PicoTick_(int n)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -1852,14 +1871,14 @@ int YM2612PicoTick_(int n)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void YM2612PicoStateLoad_(void)
|
void YM2612PicoStateLoad_(void)
|
||||||
{
|
{
|
||||||
#ifndef EXTERNAL_YM2612
|
#ifndef EXTERNAL_YM2612
|
||||||
int i, real_A1 = ym2612.addr_A1;
|
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
|
// feed all the registers and update internal state
|
||||||
for(i = 0; i < 0x100; i++) {
|
for(i = 0; i < 0x100; i++) {
|
||||||
|
@ -1874,11 +1893,10 @@ void YM2612PicoStateLoad_(void)
|
||||||
|
|
||||||
ym2612.addr_A1 = real_A1;
|
ym2612.addr_A1 = real_A1;
|
||||||
#else
|
#else
|
||||||
reset_channels( &ym2612.CH[0], 6 );
|
reset_channels( &ym2612.CH[0] );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef EXTERNAL_YM2612
|
#ifndef EXTERNAL_YM2612
|
||||||
void *YM2612GetRegs(void)
|
void *YM2612GetRegs(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,15 +76,16 @@ typedef struct
|
||||||
{
|
{
|
||||||
int clock; /* master clock (Hz) */
|
int clock; /* master clock (Hz) */
|
||||||
int rate; /* sampling rate (Hz) */
|
int rate; /* sampling rate (Hz) */
|
||||||
double freqbase; /* frequency base */
|
double freqbase; /* 08 frequency base */
|
||||||
UINT8 address; /* address register */
|
UINT8 address; /* 10 address register */
|
||||||
UINT8 status; /* status flag */
|
UINT8 status; /* 11 status flag */
|
||||||
UINT8 mode; /* mode CSM / 3SLOT */
|
UINT8 mode; /* mode CSM / 3SLOT */
|
||||||
UINT8 fn_h; /* freq latch */
|
UINT8 fn_h; /* freq latch */
|
||||||
int TA; /* timer a */
|
int TA; /* timer a */
|
||||||
int TAC; /* timer a maxval */
|
int TAC; /* timer a maxval */
|
||||||
int TAT; /* timer a ticker */
|
int TAT; /* timer a ticker */
|
||||||
UINT8 TB; /* timer b */
|
UINT8 TB; /* timer b */
|
||||||
|
UINT8 pad[3];
|
||||||
int TBC; /* timer b maxval */
|
int TBC; /* timer b maxval */
|
||||||
int TBT; /* timer b ticker */
|
int TBT; /* timer b ticker */
|
||||||
/* local time tables */
|
/* local time tables */
|
||||||
|
@ -135,9 +136,32 @@ typedef struct
|
||||||
INT32 dacout;
|
INT32 dacout;
|
||||||
|
|
||||||
FM_OPN OPN; /* OPN state */
|
FM_OPN OPN; /* OPN state */
|
||||||
|
|
||||||
|
UINT32 slot_mask; /* active slot mask (performance hack) */
|
||||||
} YM2612;
|
} YM2612;
|
||||||
#endif
|
#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);
|
void YM2612Init_(int baseclock, int rate);
|
||||||
|
@ -157,8 +181,6 @@ void *YM2612GetRegs(void);
|
||||||
#define YM2612ResetChip YM2612ResetChip_
|
#define YM2612ResetChip YM2612ResetChip_
|
||||||
#define YM2612UpdateOne YM2612UpdateOne_
|
#define YM2612UpdateOne YM2612UpdateOne_
|
||||||
#define YM2612Write YM2612Write_
|
#define YM2612Write YM2612Write_
|
||||||
#define YM2612Read YM2612Read_
|
|
||||||
#define YM2612PicoTick YM2612PicoTick_
|
|
||||||
#define YM2612PicoStateLoad YM2612PicoStateLoad_
|
#define YM2612PicoStateLoad YM2612PicoStateLoad_
|
||||||
#else
|
#else
|
||||||
/* GP2X specific */
|
/* GP2X specific */
|
||||||
|
@ -177,10 +199,6 @@ extern int PicoOpt;
|
||||||
YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
|
YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
|
||||||
#define YM2612Write(a,v) \
|
#define YM2612Write(a,v) \
|
||||||
(PicoOpt&0x200) ? YM2612Write_940(a, v) : 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() { \
|
#define YM2612PicoStateLoad() { \
|
||||||
if (PicoOpt&0x200) YM2612PicoStateLoad_940(); \
|
if (PicoOpt&0x200) YM2612PicoStateLoad_940(); \
|
||||||
else YM2612PicoStateLoad_(); \
|
else YM2612PicoStateLoad_(); \
|
||||||
|
|
|
@ -21,14 +21,10 @@
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if DRZ80_FOR_PICODRIVE
|
.if DRZ80_FOR_PICODRIVE
|
||||||
.include "port_config.s"
|
|
||||||
.extern YM2612Read_
|
|
||||||
.if EXTERNAL_YM2612
|
|
||||||
.extern YM2612Read_940
|
|
||||||
.endif
|
|
||||||
.extern PicoRead8
|
.extern PicoRead8
|
||||||
.extern Pico
|
.extern Pico
|
||||||
.extern z80_write
|
.extern z80_write
|
||||||
|
.extern ym2612_st
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
DrZ80Ver: .long 0x0001
|
DrZ80Ver: .long 0x0001
|
||||||
|
@ -111,37 +107,18 @@ DrZ80Ver: .long 0x0001
|
||||||
.if DRZ80_FOR_PICODRIVE
|
.if DRZ80_FOR_PICODRIVE
|
||||||
|
|
||||||
.macro YM2612Read_and_ret8
|
.macro YM2612Read_and_ret8
|
||||||
stmfd sp!,{r3,r12,lr}
|
ldr r0, =ym2612_st
|
||||||
.if EXTERNAL_YM2612
|
ldr r0, [r0]
|
||||||
ldr r1,=PicoOpt
|
ldrb r0, [r0, #0x11] ;@ ym2612_st->status
|
||||||
ldr r1,[r1]
|
bx lr
|
||||||
tst r1,#0x200
|
|
||||||
ldrne r2, =YM2612Read_940
|
|
||||||
ldreq r2, =YM2612Read_
|
|
||||||
mov lr,pc
|
|
||||||
bx r2
|
|
||||||
.else
|
|
||||||
bl YM2612Read_
|
|
||||||
.endif
|
|
||||||
ldmfd sp!,{r3,r12,pc}
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro YM2612Read_and_ret16
|
.macro YM2612Read_and_ret16
|
||||||
stmfd sp!,{r3,r12,lr}
|
ldr r0, =ym2612_st
|
||||||
.if EXTERNAL_YM2612
|
ldr r0, [r0]
|
||||||
ldr r0,=PicoOpt
|
ldrb r0, [r0, #0x11] ;@ ym2612_st->status
|
||||||
ldr r0,[r0]
|
|
||||||
tst r0,#0x200
|
|
||||||
ldrne r2, =YM2612Read_940
|
|
||||||
ldreq r2, =YM2612Read_
|
|
||||||
mov lr,pc
|
|
||||||
bx r2
|
|
||||||
orr r0,r0,r0,lsl #8
|
orr r0,r0,r0,lsl #8
|
||||||
.else
|
bx lr
|
||||||
bl YM2612Read_
|
|
||||||
orr r0,r0,r0,lsl #8
|
|
||||||
.endif
|
|
||||||
ldmfd sp!,{r3,r12,pc}
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
pico_z80_read8: @ addr
|
pico_z80_read8: @ addr
|
||||||
|
@ -214,13 +191,13 @@ pico_z80_read16: @ addr
|
||||||
add r0,r4,#1
|
add r0,r4,#1
|
||||||
bl PicoRead8
|
bl PicoRead8
|
||||||
orr r0,r5,r0,lsl #8
|
orr r0,r5,r0,lsl #8
|
||||||
ldmfd sp!,{r3-r5,r12,pc}
|
ldmfd sp!,{r3-r5,r12,pc}
|
||||||
1:
|
1:
|
||||||
mov r1,r0,lsr #13
|
mov r1,r0,lsr #13
|
||||||
cmp r1,#2 @ YM2612 (0x4000-0x5fff)
|
cmp r1,#2 @ YM2612 (0x4000-0x5fff)
|
||||||
bne 0f
|
bne 0f
|
||||||
and r0,r0,#3
|
and r0,r0,#3
|
||||||
YM2612Read_and_ret16
|
YM2612Read_and_ret16
|
||||||
0:
|
0:
|
||||||
cmp r0,#0x4000
|
cmp r0,#0x4000
|
||||||
movge r0,#0xff
|
movge r0,#0xff
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "cz80.h"
|
#include "cz80.h"
|
||||||
|
|
||||||
|
#if PICODRIVE_HACKS
|
||||||
|
#include <Pico/PicoInt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ALIGN_DATA
|
#ifndef ALIGN_DATA
|
||||||
#define ALIGN_DATA __attribute__((aligned(4)))
|
#define ALIGN_DATA __attribute__((aligned(4)))
|
||||||
#endif
|
#endif
|
||||||
|
@ -203,6 +207,13 @@ void Cz80_Reset(cz80_struc *CPU)
|
||||||
Cz80_Set_Reg(CPU, CZ80_PC, 0);
|
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
|
CPUŽÀ<EFBFBD>s
|
||||||
|
|
|
@ -52,6 +52,7 @@ extern "C" {
|
||||||
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)
|
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)
|
||||||
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)
|
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)
|
||||||
|
|
||||||
|
#define PICODRIVE_HACKS 1
|
||||||
#define CZ80_LITTLE_ENDIAN 1
|
#define CZ80_LITTLE_ENDIAN 1
|
||||||
#define CZ80_USE_JUMPTABLE 1
|
#define CZ80_USE_JUMPTABLE 1
|
||||||
#define CZ80_BIG_FLAGS_ARRAY 1
|
#define CZ80_BIG_FLAGS_ARRAY 1
|
||||||
|
|
|
@ -57,7 +57,11 @@
|
||||||
//#ifndef BUILD_CPS1PSP
|
//#ifndef BUILD_CPS1PSP
|
||||||
//#define READ_MEM8(A) memory_region_cpu2[(A)]
|
//#define READ_MEM8(A) memory_region_cpu2[(A)]
|
||||||
//#else
|
//#else
|
||||||
|
#if PICODRIVE_HACKS
|
||||||
|
#define READ_MEM8(A) picodrive_read(A)
|
||||||
|
#else
|
||||||
#define READ_MEM8(A) CPU->Read_Byte(A)
|
#define READ_MEM8(A) CPU->Read_Byte(A)
|
||||||
|
#endif
|
||||||
//#endif
|
//#endif
|
||||||
#if CZ80_LITTLE_ENDIAN
|
#if CZ80_LITTLE_ENDIAN
|
||||||
#define READ_MEM16(A) (READ_MEM8(A) | (READ_MEM8((A) + 1) << 8))
|
#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))
|
#define READ_MEM16(A) ((READ_MEM8(A) << 8) | READ_MEM8((A) + 1))
|
||||||
#endif
|
#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);
|
#define WRITE_MEM8(A, D) CPU->Write_Byte(A, D);
|
||||||
|
#endif
|
||||||
#if CZ80_LITTLE_ENDIAN
|
#if CZ80_LITTLE_ENDIAN
|
||||||
#define WRITE_MEM16(A, D) { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }
|
#define WRITE_MEM16(A, D) { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
// Options //
|
// Options //
|
||||||
#define FAMEC_ROLL_INLINE
|
#define FAMEC_ROLL_INLINE
|
||||||
#define FAMEC_EMULATE_TRACE
|
//#define FAMEC_EMULATE_TRACE
|
||||||
#define FAMEC_CHECK_BRANCHES
|
//#define FAMEC_CHECK_BRANCHES
|
||||||
#define FAMEC_EXTRA_INLINE
|
#define FAMEC_EXTRA_INLINE
|
||||||
// #define FAMEC_DEBUG
|
// #define FAMEC_DEBUG
|
||||||
//#define FAMEC_NO_GOTOS
|
//#define FAMEC_NO_GOTOS
|
||||||
|
@ -280,11 +280,18 @@ typedef signed int s32;
|
||||||
((u32)PC - BasePC)
|
((u32)PC - BasePC)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FAMEC_CHECK_BRANCHES
|
||||||
|
#define FORCE_ALIGNMENT(pc)
|
||||||
|
#else
|
||||||
|
#define FORCE_ALIGNMENT(pc) pc&=~1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FAMEC_32BIT_PC
|
#ifndef FAMEC_32BIT_PC
|
||||||
|
|
||||||
#define SET_PC(A) \
|
#define SET_PC(A) \
|
||||||
{ \
|
{ \
|
||||||
u32 pc = A; \
|
u32 pc = A; \
|
||||||
|
FORCE_ALIGNMENT(pc); \
|
||||||
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
|
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
|
||||||
PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \
|
PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \
|
||||||
}
|
}
|
||||||
|
@ -294,6 +301,7 @@ typedef signed int s32;
|
||||||
#define SET_PC(A) \
|
#define SET_PC(A) \
|
||||||
{ \
|
{ \
|
||||||
u32 pc = A; \
|
u32 pc = A; \
|
||||||
|
FORCE_ALIGNMENT(pc); \
|
||||||
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
|
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
|
||||||
BasePC -= pc & 0xFF000000; \
|
BasePC -= pc & 0xFF000000; \
|
||||||
PC = (u16*)(pc + BasePC); \
|
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
|
#ifndef FAMEC_32BIT_PC
|
||||||
newPC&=M68K_ADR_MASK
|
newPC&=M68K_ADR_MASK
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FAMEC_CHECK_BRANCHES
|
||||||
newPC&=~1; // don't crash on games with bad vector tables
|
newPC&=~1; // don't crash on games with bad vector tables
|
||||||
|
#endif
|
||||||
|
|
||||||
// SET_PC(newPC)
|
// SET_PC(newPC)
|
||||||
|
|
||||||
|
@ -948,6 +958,7 @@ famec_End:
|
||||||
#ifdef PICODRIVE_HACK
|
#ifdef PICODRIVE_HACK
|
||||||
dualcore_mode:
|
dualcore_mode:
|
||||||
|
|
||||||
|
while (1)
|
||||||
{
|
{
|
||||||
extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k;
|
extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k;
|
||||||
#define PS_STEP_M68K ((488<<16)/20) // ~24
|
#define PS_STEP_M68K ((488<<16)/20) // ~24
|
||||||
|
@ -989,7 +1000,6 @@ dualcore_mode:
|
||||||
}
|
}
|
||||||
cycles = m68kcontext.io_cycle_counter = 0;
|
cycles = m68kcontext.io_cycle_counter = 0;
|
||||||
}
|
}
|
||||||
goto dualcore_mode;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -51,22 +51,12 @@ static FILE *loaded_mp3 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* these will be managed locally on our side */
|
/* 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 UINT8 *REGS = 0; /* we will also keep local copy of regs for savestates and such */
|
||||||
static INT32 *addr_A1; /* address line A1 */
|
static INT32 *addr_A1; /* address line A1 */
|
||||||
|
|
||||||
static int dacen;
|
static int dacen;
|
||||||
static INT32 dacout;
|
static INT32 dacout;
|
||||||
static UINT8 ST_address; /* address register */
|
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;
|
static int writebuff_ptr = 0;
|
||||||
|
|
||||||
|
@ -84,16 +74,16 @@ static int set_timers( int v )
|
||||||
/* b2 = timer enable a */
|
/* b2 = timer enable a */
|
||||||
/* b1 = load b */
|
/* b1 = load b */
|
||||||
/* b0 = load a */
|
/* b0 = load a */
|
||||||
change = (ST_mode ^ v) & 0xc0;
|
change = (ym2612_st->mode ^ v) & 0xc0;
|
||||||
ST_mode = v;
|
ym2612_st->mode = v;
|
||||||
|
|
||||||
/* reset Timer b flag */
|
/* reset Timer b flag */
|
||||||
if( v & 0x20 )
|
if( v & 0x20 )
|
||||||
ST_status &= ~2;
|
ym2612_st->status &= ~2;
|
||||||
|
|
||||||
/* reset Timer a flag */
|
/* reset Timer a flag */
|
||||||
if( v & 0x10 )
|
if( v & 0x10 )
|
||||||
ST_status &= ~1;
|
ym2612_st->status &= ~1;
|
||||||
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
@ -139,30 +129,30 @@ int YM2612Write_940(unsigned int a, unsigned int v)
|
||||||
switch( addr )
|
switch( addr )
|
||||||
{
|
{
|
||||||
case 0x24: { // timer A High 8
|
case 0x24: { // timer A High 8
|
||||||
int TAnew = (ST_TA & 0x03)|(((int)v)<<2);
|
int TAnew = (ym2612_st->TA & 0x03)|(((int)v)<<2);
|
||||||
if(ST_TA != TAnew) {
|
if (ym2612_st->TA != TAnew) {
|
||||||
// we should reset ticker only if new value is written. Outrun requires this.
|
// we should reset ticker only if new value is written. Outrun requires this.
|
||||||
ST_TA = TAnew;
|
ym2612_st->TA = TAnew;
|
||||||
ST_TAC = (1024-TAnew)*18;
|
ym2612_st->TAC = (1024-TAnew)*18;
|
||||||
ST_TAT = 0;
|
ym2612_st->TAT = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case 0x25: { // timer A Low 2
|
case 0x25: { // timer A Low 2
|
||||||
int TAnew = (ST_TA & 0x3fc)|(v&3);
|
int TAnew = (ym2612_st->TA & 0x3fc)|(v&3);
|
||||||
if(ST_TA != TAnew) {
|
if (ym2612_st->TA != TAnew) {
|
||||||
ST_TA = TAnew;
|
ym2612_st->TA = TAnew;
|
||||||
ST_TAC = (1024-TAnew)*18;
|
ym2612_st->TAC = (1024-TAnew)*18;
|
||||||
ST_TAT = 0;
|
ym2612_st->TAT = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case 0x26: // timer B
|
case 0x26: // timer B
|
||||||
if(ST_TB != v) {
|
if (ym2612_st->TB != v) {
|
||||||
ST_TB = v;
|
ym2612_st->TB = v;
|
||||||
ST_TBC = (256-v)<<4;
|
ym2612_st->TBC = (256-v)<<4;
|
||||||
ST_TBC *= 18;
|
ym2612_st->TBC *= 18;
|
||||||
ST_TBT = 0;
|
ym2612_st->TBT = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case 0x27: /* mode, timer control */
|
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
|
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) \
|
#define CHECK_BUSY(job) \
|
||||||
(gp2x_memregs[0x3b46>>1] & (1<<(job-1)))
|
(gp2x_memregs[0x3b46>>1] & (1<<(job-1)))
|
||||||
|
@ -339,12 +297,14 @@ void YM2612PicoStateLoad_940(void)
|
||||||
static void internal_reset(void)
|
static void internal_reset(void)
|
||||||
{
|
{
|
||||||
writebuff_ptr = 0;
|
writebuff_ptr = 0;
|
||||||
ST_mode = 0;
|
ym2612_st->mode = 0;
|
||||||
ST_status = 0; /* normal mode */
|
ym2612_st->status = 0; /* normal mode */
|
||||||
ST_TA = 0;
|
ym2612_st->TA = 0;
|
||||||
ST_TAC = 0;
|
ym2612_st->TAC = 0;
|
||||||
ST_TB = 0;
|
ym2612_st->TAT = 0;
|
||||||
ST_TBC = 0;
|
ym2612_st->TB = 0;
|
||||||
|
ym2612_st->TBC = 0;
|
||||||
|
ym2612_st->TBT = 0;
|
||||||
dacen = 0;
|
dacen = 0;
|
||||||
dacout = 0;
|
dacout = 0;
|
||||||
ST_address= 0;
|
ST_address= 0;
|
||||||
|
|
|
@ -138,15 +138,10 @@ endif
|
||||||
all: PicoDrive.gpe
|
all: PicoDrive.gpe
|
||||||
|
|
||||||
PicoDrive.gpe : $(OBJS) ../common/helix/helix_mp3.a
|
PicoDrive.gpe : $(OBJS) ../common/helix/helix_mp3.a
|
||||||
@echo $@
|
@echo ">>>" $@
|
||||||
@$(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map
|
$(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map
|
||||||
ifeq ($(DEBUG),)
|
ifeq ($(DEBUG),)
|
||||||
@$(STRIP) $@
|
$(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\\
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
up: PicoDrive.gpe
|
up: PicoDrive.gpe
|
||||||
|
@ -155,45 +150,40 @@ up: PicoDrive.gpe
|
||||||
# @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\
|
# @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:
|
.c.o:
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||||
.s.o:
|
.s.o:
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
$(GCC) $(COPT) $(DEFINC) -c $< -o $@
|
||||||
|
|
||||||
../../Pico/draw_asm.o : ../../Pico/Draw.s
|
../../Pico/draw_asm.o : ../../Pico/Draw.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/draw2_asm.o : ../../Pico/Draw2.s
|
../../Pico/draw2_asm.o : ../../Pico/Draw2.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/memory_asm.o : ../../Pico/Memory.s
|
../../Pico/memory_asm.o : ../../Pico/Memory.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/sound/ym2612_asm.o : ../../Pico/sound/ym2612.s
|
../../Pico/sound/ym2612_asm.o : ../../Pico/sound/ym2612.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/sound/mix_asm.o : ../../Pico/sound/mix.s
|
../../Pico/sound/mix_asm.o : ../../Pico/sound/mix.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/misc_asm.o : ../../Pico/Misc.s
|
../../Pico/misc_asm.o : ../../Pico/Misc.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s
|
../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/cd/memory_asm.o : ../../Pico/cd/Memory.s
|
../../Pico/cd/memory_asm.o : ../../Pico/cd/Memory.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
../../Pico/cd/misc_asm.o : ../../Pico/cd/Misc.s
|
../../Pico/cd/misc_asm.o : ../../Pico/cd/Misc.s
|
||||||
@echo $<
|
@echo ">>>" $<
|
||||||
@$(AS) $(ASOPT) $< -o $@
|
$(AS) $(ASOPT) $< -o $@
|
||||||
|
|
||||||
# build Cyclone
|
# build Cyclone
|
||||||
../../cpu/Cyclone/proj/Cyclone.s :
|
../../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
|
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)
|
void YM2612PicoStateLoad_940(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,8 +13,8 @@ STRIP = strip
|
||||||
AS = gcc
|
AS = gcc
|
||||||
|
|
||||||
ifeq "$(profile)" "1"
|
ifeq "$(profile)" "1"
|
||||||
COPT_COMMON = -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -fprofile-generate # -static
|
COPT_COMMON = -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -fprofile-generate
|
||||||
COPT = $(COPT_COMMON) # -mtune=arm920t
|
COPT = $(COPT_COMMON)
|
||||||
else
|
else
|
||||||
COPT = -ggdb -Wall -fno-strict-aliasing # -pg -O3 -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -ffast-math
|
COPT = -ggdb -Wall -fno-strict-aliasing # -pg -O3 -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -ffast-math
|
||||||
COPT_COMMON = $(COPT)
|
COPT_COMMON = $(COPT)
|
||||||
|
|
|
@ -6,23 +6,19 @@ PSPSDK = $(shell psp-config --pspsdk-path)
|
||||||
#use_musashi = 1
|
#use_musashi = 1
|
||||||
#use_mz80 = 1
|
#use_mz80 = 1
|
||||||
amalgamate = 0
|
amalgamate = 0
|
||||||
#profile = 1
|
|
||||||
#up = 1
|
|
||||||
|
|
||||||
|
|
||||||
CFLAGS += -I../.. -I. -DNO_SYNC -DLPRINTF_STDIO
|
CFLAGS += -I../.. -I. -DNO_SYNC -DLPRINTF_STDIO
|
||||||
CFLAGS += -Wall -Winline -G0
|
CFLAGS += -Wall -Winline -G0
|
||||||
|
CFLAGS += -DLPRINTF_STDIO
|
||||||
|
#CFLAGS += -fprofile-generate
|
||||||
|
#CFLAGS += -fprofile-use
|
||||||
|
#CFLAGS += -pg
|
||||||
ifeq ($(DEBUG),)
|
ifeq ($(DEBUG),)
|
||||||
CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math
|
CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math
|
||||||
else
|
else
|
||||||
CFLAGS += -ggdb
|
CFLAGS += -ggdb
|
||||||
endif
|
endif
|
||||||
ifeq "$(profile)" "1"
|
|
||||||
CFLAGS += -fprofile-generate
|
|
||||||
endif
|
|
||||||
ifeq "$(profile)" "2"
|
|
||||||
CFLAGS += -fprofile-use
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# frontend
|
# frontend
|
||||||
|
@ -37,7 +33,7 @@ OBJS += ../../PicoAll.o
|
||||||
else
|
else
|
||||||
OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.o \
|
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/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
|
# Pico - CD
|
||||||
OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pico/cd/LC89510.o \
|
OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pico/cd/LC89510.o \
|
||||||
../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/gfx_cd.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 += -lpng -lm -lpspgu -lpsppower -lpspaudio -lpsprtc -lpspaudiocodec
|
||||||
|
#LIBS += -lpspprof
|
||||||
LDFLAGS += -Wl,-Map=PicoDrive.map
|
LDFLAGS += -Wl,-Map=PicoDrive.map
|
||||||
|
|
||||||
|
|
||||||
# target
|
# target
|
||||||
TARGET = PicoDrive
|
TARGET = PicoDrive
|
||||||
EXTRA_TARGETS = EBOOT.PBP
|
EXTRA_TARGETS = EBOOT.PBP
|
||||||
|
@ -114,7 +112,11 @@ AS := psp-as
|
||||||
|
|
||||||
../../Pico/Draw.o : ../../Pico/Draw.c
|
../../Pico/Draw.o : ../../Pico/Draw.c
|
||||||
@echo ">>>" $<
|
@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
|
readme.txt: ../../tools/textfilter ../base_readme.txt
|
||||||
../../tools/textfilter ../base_readme.txt $@ PSP
|
../../tools/textfilter ../base_readme.txt $@ PSP
|
||||||
|
@ -152,6 +154,5 @@ endif
|
||||||
|
|
||||||
# ?
|
# ?
|
||||||
rel: EBOOT.PBP readme.txt
|
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 "psp.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
#include "mp3.h"
|
||||||
#include "../common/emu.h"
|
#include "../common/emu.h"
|
||||||
#include "../common/lprintf.h"
|
#include "../common/lprintf.h"
|
||||||
#include "../../Pico/PicoInt.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++) {
|
for (h = 0; h < 8; h++) {
|
||||||
p = (int *) (screen+x+512*(264+h));
|
p = (int *) (screen+x+512*(264+h));
|
||||||
p = (int *) ((int)p & ~3); // align
|
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
|
if (is_active) { tmp = psp_screen; psp_screen = screen; } // nasty pointer tricks
|
||||||
emu_textOut16(x, 264, text);
|
emu_textOut16(x, 264, text);
|
||||||
|
@ -126,8 +127,8 @@ void emu_setDefaultConfig(void)
|
||||||
{
|
{
|
||||||
memset(¤tConfig, 0, sizeof(currentConfig));
|
memset(¤tConfig, 0, sizeof(currentConfig));
|
||||||
currentConfig.lastRomFile[0] = 0;
|
currentConfig.lastRomFile[0] = 0;
|
||||||
currentConfig.EmuOpt = 0x1f | 0x680; // | confirm_save, cd_leds, 16bit rend
|
currentConfig.EmuOpt = 0x1d | 0x680; // | confirm_save, cd_leds, acc rend
|
||||||
currentConfig.PicoOpt = 0x0f | 0xc00; // | cd_pcm, cd_cdda
|
currentConfig.PicoOpt = 0x0f | 0x1c00; // | gfx_cd, cd_pcm, cd_cdda
|
||||||
currentConfig.PsndRate = 22050;
|
currentConfig.PsndRate = 22050;
|
||||||
currentConfig.PicoRegion = 0; // auto
|
currentConfig.PicoRegion = 0; // auto
|
||||||
currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP
|
currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP
|
||||||
|
@ -172,7 +173,7 @@ static int fbimg_offs = 0;
|
||||||
|
|
||||||
static void set_scaling_params(void)
|
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].x = g_vertices[0].y =
|
||||||
g_vertices[0].z = g_vertices[1].z = 0;
|
g_vertices[0].z = g_vertices[1].z = 0;
|
||||||
|
|
||||||
|
@ -185,9 +186,13 @@ static void set_scaling_params(void)
|
||||||
src_width = 256;
|
src_width = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fbimg_width & 1) fbimg_width++; // make even
|
||||||
|
if (fbimg_height & 1) fbimg_height++;
|
||||||
|
|
||||||
if (fbimg_width >= 480) {
|
if (fbimg_width >= 480) {
|
||||||
g_vertices[0].u = (fbimg_width-480)/2;
|
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_width = 480;
|
||||||
fbimg_xoffs = 0;
|
fbimg_xoffs = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -211,6 +216,12 @@ static void set_scaling_params(void)
|
||||||
g_vertices[1].y = fbimg_height;
|
g_vertices[1].y = fbimg_height;
|
||||||
if (fbimg_xoffs < 0) fbimg_xoffs = 0;
|
if (fbimg_xoffs < 0) fbimg_xoffs = 0;
|
||||||
if (fbimg_yoffs < 0) fbimg_yoffs = 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
|
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;
|
*p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void dbg_text(void)
|
static void dbg_text(void)
|
||||||
{
|
{
|
||||||
int *p, h, len;
|
int *p, h, len;
|
||||||
|
@ -382,11 +393,11 @@ static void dbg_text(void)
|
||||||
for (h = 0; h < 8; h++) {
|
for (h = 0; h < 8; h++) {
|
||||||
p = (int *) ((unsigned short *) psp_screen+2+512*(256+h));
|
p = (int *) ((unsigned short *) psp_screen+2+512*(256+h));
|
||||||
p = (int *) ((int)p & ~3); // align
|
p = (int *) ((int)p & ~3); // align
|
||||||
memset32(p, 0, len);
|
memset32_uncached(p, 0, len);
|
||||||
}
|
}
|
||||||
emu_textOut16(2, 256, text);
|
emu_textOut16(2, 256, text);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* called after rendering is done, but frame emulation is not finished */
|
/* called after rendering is done, but frame emulation is not finished */
|
||||||
void blit1(void)
|
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);
|
if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_text();
|
//dbg_text();
|
||||||
|
|
||||||
if ((emu_opt & 0x400) && (PicoMCD & 1))
|
if ((emu_opt & 0x400) && (PicoMCD & 1))
|
||||||
cd_leds();
|
cd_leds();
|
||||||
|
@ -431,15 +442,15 @@ static void blit2(const char *fps, const char *notice, int lagging_behind)
|
||||||
static void clearArea(int full)
|
static void clearArea(int full)
|
||||||
{
|
{
|
||||||
if (full) {
|
if (full) {
|
||||||
memset32(psp_screen, 0, 512*272*2/4);
|
memset32_uncached(psp_screen, 0, 512*272*2/4);
|
||||||
psp_video_flip(0);
|
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(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*240/4);
|
||||||
memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4);
|
memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4);
|
||||||
} else {
|
} else {
|
||||||
void *fb = psp_video_get_active_fb();
|
void *fb = psp_video_get_active_fb();
|
||||||
memset32((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
|
memset32_uncached((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 *)fb + 512*264*2), 0, 512*8*2/4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +670,7 @@ void emu_forcedFrame(void)
|
||||||
vidResetMode();
|
vidResetMode();
|
||||||
memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
|
memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
|
||||||
memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
|
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);
|
PicoDrawSetColorFormat(-1);
|
||||||
PicoScan = EmuScanSlow;
|
PicoScan = EmuScanSlow;
|
||||||
|
@ -1036,7 +1047,7 @@ void emu_Loop(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear fps counters and stuff
|
// 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);
|
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();
|
psp_video_switch_to_single();
|
||||||
if (rom_data) menu_draw_begin();
|
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(1, 1, "Loading", 0xffff);
|
||||||
smalltext_out16_lim(1, 10, p, 0xffff, 80);
|
smalltext_out16_lim(1, 10, p, 0xffff, 80);
|
||||||
|
@ -453,8 +453,10 @@ static void draw_debug(void)
|
||||||
|
|
||||||
static void debug_menu_loop(void)
|
static void debug_menu_loop(void)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
draw_debug();
|
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 ------------
|
// ------------ patch/gg menu ------------
|
||||||
|
@ -1059,7 +1061,7 @@ static void menu_opt3_preview(int is_32col)
|
||||||
lprintf("uncompress returned %i\n", ret);
|
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();
|
emu_forcedFrame();
|
||||||
menu_prepare_bg(1, 0);
|
menu_prepare_bg(1, 0);
|
||||||
|
|
||||||
|
@ -1119,6 +1121,7 @@ static void dispmenu_loop_options(void)
|
||||||
if (setting != NULL) {
|
if (setting != NULL) {
|
||||||
while ((inp = psp_pad_read(0)) & (BTN_LEFT|BTN_RIGHT)) {
|
while ((inp = psp_pad_read(0)) & (BTN_LEFT|BTN_RIGHT)) {
|
||||||
*setting += (inp & BTN_LEFT) ? -0.01 : 0.01;
|
*setting += (inp & BTN_LEFT) ? -0.01 : 0.01;
|
||||||
|
if (*setting <= 0) *setting = 0.01;
|
||||||
menu_opt3_preview(is_32col);
|
menu_opt3_preview(is_32col);
|
||||||
draw_dispmenu_options(menu_sel); // will wait vsync
|
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;
|
int i;
|
||||||
for (i = 272; i > 0; i--, dst += 480, src += 512)
|
for (i = 272; i > 0; i--, dst += 480, src += 512)
|
||||||
menu_darken_bg(dst, src, 480, 1);
|
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
|
else
|
||||||
{
|
{
|
||||||
// should really only happen once, on startup..
|
// 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);
|
readpng(bg_buffer, "skin/background.png", READPNG_BG);
|
||||||
}
|
}
|
||||||
sceKernelDcacheWritebackAll();
|
sceKernelDcacheWritebackAll();
|
||||||
|
@ -1814,7 +1817,7 @@ int menu_loop_tray(void)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
draw_menu_tray(menu_sel);
|
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_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_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
|
||||||
if(inp & BTN_CIRCLE) {
|
if(inp & BTN_CIRCLE) {
|
||||||
|
|
|
@ -181,8 +181,6 @@ int mp3_init(void)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
lprintf("thread_busy_sem: %08x, thread_job_sem: %08x\n", thread_busy_sem, thread_job_sem);
|
|
||||||
|
|
||||||
thread_exit = 0;
|
thread_exit = 0;
|
||||||
thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, 0); /* use slightly higher prio then main */
|
thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, 0); /* use slightly higher prio then main */
|
||||||
if (thid < 0) {
|
if (thid < 0) {
|
||||||
|
@ -273,7 +271,7 @@ static int decode_thread(SceSize args, void *argp)
|
||||||
|
|
||||||
int mp3_get_bitrate(FILE *f, int size)
|
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
|
// filenames are stored instead handles in PSP, due to stupid max open file limit
|
||||||
char *fname = (char *)f;
|
char *fname = (char *)f;
|
||||||
|
|
||||||
|
@ -307,14 +305,14 @@ int mp3_get_bitrate(FILE *f, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* looking good.. */
|
/* looking good.. */
|
||||||
ret = bitrate;
|
retval = bitrate;
|
||||||
end:
|
end:
|
||||||
if (mp3_handle >= 0) sceIoClose(mp3_handle);
|
if (mp3_handle >= 0) sceIoClose(mp3_handle);
|
||||||
mp3_handle = -1;
|
mp3_handle = -1;
|
||||||
mp3_fname = NULL;
|
mp3_fname = NULL;
|
||||||
psp_sem_unlock(thread_busy_sem);
|
psp_sem_unlock(thread_busy_sem);
|
||||||
if (ret < 0) mp3_last_error = -1; // remember we had a problem..
|
if (retval < 0) mp3_last_error = -1; // remember we had a problem..
|
||||||
return ret;
|
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 <pspgu.h>
|
||||||
|
|
||||||
#include "psp.h"
|
#include "psp.h"
|
||||||
|
#include "emu.h"
|
||||||
#include "../common/lprintf.h"
|
#include "../common/lprintf.h"
|
||||||
|
|
||||||
PSP_MODULE_INFO("PicoDrive", 0, 1, 34);
|
PSP_MODULE_INFO("PicoDrive", 0, 1, 34);
|
||||||
|
@ -28,6 +29,19 @@ static int exit_callback(int arg1, int arg2, void *common)
|
||||||
return 0;
|
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 */
|
/* Callback thread */
|
||||||
static int callback_thread(SceSize args, void *argp)
|
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);
|
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
|
||||||
sceKernelRegisterExitCallback(cbid);
|
sceKernelRegisterExitCallback(cbid);
|
||||||
|
cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
|
||||||
|
scePowerRegisterCallback(0, cbid);
|
||||||
|
|
||||||
sceKernelSleepThreadCB();
|
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