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