#endif\r
\r
\r
-#ifdef _ASM_DRAW_C_MIPS\r
+#ifdef _ASM_DRAW_C_AMIPS\r
int TileNorm(int sx,int addr,int pal);\r
int TileFlip(int sx,int addr,int pal);\r
#else\r
#ifndef _ASM_DRAW_C\r
static void BackFill(int reg7, int sh)\r
{\r
- unsigned int back=0;\r
- unsigned int *pd=NULL,*end=NULL;\r
+ unsigned int back;\r
\r
// Start with a blank scanline (background colour):\r
back=reg7&0x3f;\r
back|=back<<8;\r
back|=back<<16;\r
\r
- pd= (unsigned int *)(HighCol+8);\r
- end=(unsigned int *)(HighCol+8+320);\r
-\r
- do { pd[0]=pd[1]=pd[2]=pd[3]=back; pd+=4; } while (pd<end);\r
+ memset32((int *)(HighCol+8), back, 320/4);\r
}\r
#endif\r
\r
#ifndef _ASM_DRAW_C\r
static void BackFillFull(int reg7)\r
{\r
- unsigned int back, i;\r
- unsigned int *p=(unsigned int *)PicoDraw2FB;\r
+ unsigned int back;\r
\r
// Start with a background color:\r
// back=PicoCramHigh[reg7&0x3f];\r
back|=back<<8;\r
back|=back<<16;\r
\r
- for(i = LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/16; i; i--) {\r
- *p++ = back; // do 16 pixels per iteration\r
- *p++ = back;\r
- *p++ = back;\r
- *p++ = back;\r
- }\r
+ memset32((int *)PicoDraw2FB, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);\r
}\r
#endif\r
\r
log_io(a, 8, 0);\r
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
\r
- d=OtherRead16(a&~1, 8); if ((a&1)==0) d>>=8;\r
+ if ((a&0xe700e0)==0xc00000) // VDP\r
+ d=PicoVideoRead(a);\r
+ else d=OtherRead16(a&~1, 8);\r
+ if ((a&1)==0) d>>=8;\r
+\r
\r
-end:\r
#ifdef __debug_io\r
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
#endif\r
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom\r
log_io(a, 16, 0);\r
\r
- d = OtherRead16(a, 16);\r
+ if ((a&0xe700e0)==0xc00000)\r
+ d = PicoVideoRead(a);\r
+ else d = OtherRead16(a, 16);\r
\r
end:\r
#ifdef __debug_io\r
if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom\r
log_io(a, 32, 0);\r
\r
- d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
+ if ((a&0xe700e0)==0xc00000)\r
+ d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);\r
+ else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
\r
end:\r
#ifdef __debug_io\r
log_io(a, 16, 1);\r
\r
a&=0xfffffe;\r
+ if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP\r
OtherWrite16(a,d);\r
}\r
\r
log_io(a, 32, 1);\r
\r
a&=0xfffffe;\r
+ if ((a&0xe700e0)==0xc00000)\r
+ {\r
+ // VDP:\r
+ PicoVideoWrite(a, (u16)(d>>16));\r
+ PicoVideoWrite(a+2,(u16)d);\r
+ return;\r
+ }\r
+\r
OtherWrite16(a, (u16)(d>>16));\r
OtherWrite16(a+2,(u16)d);\r
}\r
{\r
u8 ret = 0;\r
\r
-#ifndef _USE_DRZ80\r
- if (a<0x4000) return Pico.zram[a&0x1fff];\r
-#endif\r
-\r
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)\r
{\r
if (PicoOpt&1) ret = (u8) YM2612Read();\r
return ret;\r
}\r
\r
-#ifdef _USE_DRZ80\r
- // should not be needed || dprintf("z80_read RAM");\r
+ // should not be needed, cores should be able to access RAM themselves\r
if (a<0x4000) return Pico.zram[a&0x1fff];\r
-#endif\r
\r
elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);\r
return ret;\r
PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)\r
#endif\r
{\r
-#ifndef _USE_DRZ80\r
- if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }\r
-#endif\r
-\r
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)\r
{\r
if(PicoOpt&1) emustatus|=YM2612Write(a, data) & 1;\r
return;\r
}\r
\r
-#ifdef _USE_DRZ80\r
- // should not be needed, drZ80 knows how to access RAM itself || dprintf("z80_write RAM @ %08x", lr);\r
+ // should not be needed\r
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }\r
-#endif\r
\r
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);\r
}\r
cmp r2, #0x4000\r
mvnne r0, #0\r
bxne lr @ invalid\r
-.if EXTERNAL_YM2612\r
ldr r1, =PicoOpt\r
ldr r1, [r1]\r
tst r1, #1\r
- beq m_read8_fake_ym2612\r
- tst r1, #0x200\r
- beq YM2612Read_\r
- b YM2612Read_940\r
-.else\r
- b YM2612Read_\r
-.endif\r
+\r
+ ldrne r1, =ym2612_st\r
+ ldrne r1, [r1]\r
+ ldrneb r0, [r1, #0x11] @ ym2612_st->status\r
+ bxne lr\r
\r
m_read8_fake_ym2612:\r
ldr r3, =(Pico+0x22200)\r
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;
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 {
goto end;
}
-#ifndef _ASM_MEMORY_C
- if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }
-#endif
-
d = OtherRead16End(a, realsize);
end:
#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
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
*dest++ = (src_[0] << 8) | src_[1];\r
}\r
\r
-\r
+#ifndef _ASM_MISC_C_AMIPS\r
PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)\r
{\r
intblock *bd = (intblock *) dest, *bs = (intblock *) src;\r
while (count--)\r
*dest++ = c;\r
}\r
+void memset32_uncached(int *dest, int c, int count) { memset32(dest, c, count); }\r
+#endif\r
#endif\r
\r
--- /dev/null
+# 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
+
if ((line == 224 || line == line_sample) && PsndOut) getSamples(line);\r
if (line == 32 && PsndOut) emustatus &= ~1;\r
if (line >= line_from_r && line < line_to_r)\r
- z80_run(228);\r
+ z80_run_nr(228);\r
}\r
} else if (line_to_r-line_from_r > 0) {\r
- z80_run(228*(line_to_r-line_from_r));\r
+ z80_run_nr(228*(line_to_r-line_from_r));\r
// samples will be taken by caller\r
}\r
}\r
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }\r
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }\r
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))\r
+\r
+#define SekInterrupt(i) PicoCpuCM68k.irq=i\r
+\r
#ifdef EMU_M68K\r
#define EMU_CORE_DEBUG\r
#endif\r
\r
#ifdef EMU_F68K\r
#include "../cpu/fame/fame.h"\r
-M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;\r
+extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;\r
#define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter\r
#define SekCyclesLeft \\r
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)\r
if (x) { PicoCpuFS68k.execinfo |= FM68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \\r
}\r
#define SekShouldInterrupt fm68k_would_interrupt()\r
+\r
+#define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq\r
+\r
#ifdef EMU_M68K\r
#define EMU_CORE_DEBUG\r
#endif\r
else PicoCpuMS68k.stopped=0; \\r
}\r
#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)\r
+\r
+#define SekInterrupt(irq) {\r
+ void *oldcontext = m68ki_cpu_p; \\r
+ m68k_set_context(&PicoCpuMM68k); \\r
+ m68k_set_irq(irq); \\r
+ m68k_set_context(oldcontext); \\r
+}\r
+\r
#endif\r
#endif\r
\r
#define SekEndRun(c)\r
#endif\r
\r
+// ----------------------- Z80 CPU -----------------------\r
+\r
+#if defined(_USE_MZ80)\r
+#include "../../cpu/mz80/mz80.h"\r
+\r
+#define z80_run(cycles) mz80_run(cycles)\r
+#define z80_run_nr(cycles) mz80_run(cycles)\r
+#define z80_int() mz80int(0)\r
+#define z80_resetCycles() mz80GetElapsedTicks(1)\r
+\r
+#elif defined(_USE_DRZ80)\r
+#include "../../cpu/DrZ80/drz80.h"\r
+\r
+extern struct DrZ80 drZ80;\r
+\r
+#define z80_run(cycles) ((cycles) - DrZ80Run(&drZ80, cycles))\r
+#define z80_run_nr(cycles) DrZ80Run(&drZ80, cycles)\r
+#define z80_int() { \\r
+ drZ80.z80irqvector = 0xFF; /* default IRQ vector RST opcode */ \\r
+ drZ80.Z80_IRQ = 1; \\r
+}\r
+#define z80_resetCycles()\r
+\r
+#elif defined(_USE_CZ80)\r
+#include "../../cpu/cz80/cz80.h"\r
+\r
+#define z80_run(cycles) Cz80_Exec(&CZ80, cycles)\r
+#define z80_run_nr(cycles) Cz80_Exec(&CZ80, cycles)\r
+#define z80_int() Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE)\r
+#define z80_resetCycles()\r
+\r
+#else\r
+\r
+#define z80_run(cycles) (cycles)\r
+#define z80_run_nr(cycles)\r
+#define z80_int()\r
+#define z80_resetCycles()\r
+\r
+#endif\r
+\r
// ---------------------------------------------------------\r
\r
extern int PicoMCD;\r
// Sek.c\r
PICO_INTERNAL int SekInit(void);\r
PICO_INTERNAL int SekReset(void);\r
-PICO_INTERNAL int SekInterrupt(int irq);\r
PICO_INTERNAL void SekState(int *data);\r
PICO_INTERNAL void SekSetRealTAS(int use_real);\r
\r
PICO_INTERNAL void PsndClear(void);\r
// z80 functionality wrappers\r
PICO_INTERNAL void z80_init(void);\r
-PICO_INTERNAL void z80_resetCycles(void);\r
-PICO_INTERNAL void z80_int(void);\r
-PICO_INTERNAL int z80_run(int cycles);\r
PICO_INTERNAL void z80_pack(unsigned char *data);\r
PICO_INTERNAL void z80_unpack(unsigned char *data);\r
PICO_INTERNAL void z80_reset(void);\r
}\r
\r
\r
-PICO_INTERNAL int SekInterrupt(int irq)\r
-{\r
-#ifdef EMU_CORE_DEBUG\r
- {\r
- extern int dbg_irq_level;\r
- dbg_irq_level=irq;\r
- return 0;\r
- }\r
-#endif\r
-#ifdef EMU_C68K\r
- PicoCpuCM68k.irq=irq;\r
-#endif\r
-#ifdef EMU_M68K\r
- {\r
- void *oldcontext = m68ki_cpu_p;\r
- m68k_set_context(&PicoCpuMM68k);\r
- m68k_set_irq(irq); // raise irq (gets lowered after taken or must be done in ack)\r
- m68k_set_context(oldcontext);\r
- }\r
-#endif\r
-#ifdef EMU_F68K\r
- PicoCpuFM68k.interrupts[0]=irq;\r
-#endif\r
-\r
- return 0;\r
-}\r
-\r
// data must be word aligned\r
PICO_INTERNAL void SekState(int *data)\r
{\r
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);
{\r
u32 d=0;\r
\r
- if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram\r
-\r
a&=0xffffff;\r
\r
- if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios\r
+ switch (a >> 17)\r
+ {\r
+ case 0x00>>1: // BIOS: 000000 - 020000\r
+ d = *(u8 *)(Pico_mcd->bios+(a^1));\r
+ break;\r
+ case 0x02>>1: // prg RAM\r
+ if ((Pico_mcd->m.busreq&3)!=1) {\r
+ u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+ d = *(prg_bank+((a^1)&0x1ffff));\r
+ }\r
+ break;\r
+ case 0x20>>1: // word RAM: 200000 - 220000\r
+ wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
+ a &= 0x1ffff;\r
+ if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
+ d = Pico_mcd->word_ram1M[bank][a^1];\r
+ } else {\r
+ // allow access in any mode, like Gens does\r
+ d = Pico_mcd->word_ram2M[a^1];\r
+ }\r
+ wrdprintf("ret = %02x", (u8)d);\r
+ break;\r
+ case 0x22>>1: // word RAM: 220000 - 240000\r
+ wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
+ if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
+ a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
+ d = Pico_mcd->word_ram1M[bank][a^1];\r
+ } else {\r
+ // allow access in any mode, like Gens does\r
+ d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
+ }\r
+ wrdprintf("ret = %02x", (u8)d);\r
+ break;\r
+ case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
+ case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
+ case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
+ case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
+ // VDP\r
+ if ((a&0xe700e0)==0xc00000) {\r
+ d=PicoVideoRead(a);\r
+ if ((a&1)==0) d>>=8;\r
+ }\r
+ break;\r
+ case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
+ case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
+ case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
+ case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:\r
+ // RAM:\r
+ d = *(u8 *)(Pico.ram+((a^1)&0xffff));\r
+ break;\r
+ default:\r
+ if ((a&0xff4000)==0xa00000) { d=z80Read8(a); break; } // Z80 Ram\r
+ if ((a&0xffffc0)==0xa12000)\r
+ rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
\r
- // prg RAM\r
- if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
- u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
- d = *(prg_bank+((a^1)&0x1ffff));\r
- goto end;\r
- }\r
+ d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
\r
- // word RAM\r
- if ((a&0xfc0000)==0x200000) {\r
- wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
- if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
- int bank = Pico_mcd->s68k_regs[3]&1;\r
- if (a >= 0x220000)\r
- a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
- else a &= 0x1ffff;\r
- d = Pico_mcd->word_ram1M[bank][a^1];\r
- } else {\r
- // allow access in any mode, like Gens does\r
- d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
- }\r
- wrdprintf("ret = %02x", (u8)d);\r
- goto end;\r
+ if ((a&0xffffc0)==0xa12000)\r
+ rdprintf("ret = %02x", (u8)d);\r
+ break;\r
}\r
\r
- if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
-\r
- if ((a&0xffffc0)==0xa12000)\r
- rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
- d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
-\r
- if ((a&0xffffc0)==0xa12000)\r
- rdprintf("ret = %02x", (u8)d);\r
-\r
- end:\r
\r
#ifdef __debug_io\r
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
{\r
u32 d=0;\r
\r
- if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram\r
-\r
a&=0xfffffe;\r
\r
- if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios\r
+ switch (a >> 17)\r
+ {\r
+ case 0x00>>1: // BIOS: 000000 - 020000\r
+ d = *(u16 *)(Pico_mcd->bios+a);\r
+ break;\r
+ case 0x02>>1: // prg RAM\r
+ if ((Pico_mcd->m.busreq&3)!=1) {\r
+ u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+ wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
+ d = *(u16 *)(prg_bank+(a&0x1fffe));\r
+ wrdprintf("ret = %04x", d);\r
+ }\r
+ break;\r
+ case 0x20>>1: // word RAM: 200000 - 220000\r
+ wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
+ a &= 0x1fffe;\r
+ if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
+ d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
+ } else {\r
+ // allow access in any mode, like Gens does\r
+ d = *(u16 *)(Pico_mcd->word_ram2M+a);\r
+ }\r
+ wrdprintf("ret = %04x", d);\r
+ break;\r
+ case 0x22>>1: // word RAM: 220000 - 240000\r
+ wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
+ if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
+ a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
+ d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
+ } else {\r
+ // allow access in any mode, like Gens does\r
+ d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
+ }\r
+ wrdprintf("ret = %04x", d);\r
+ break;\r
+ case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
+ case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
+ case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
+ case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
+ // VDP\r
+ if ((a&0xe700e0)==0xc00000)\r
+ d=PicoVideoRead(a);\r
+ break;\r
+ case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
+ case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
+ case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
+ case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:\r
+ // RAM:\r
+ d=*(u16 *)(Pico.ram+(a&0xfffe));\r
+ break;\r
+ default:\r
+ if ((a&0xffffc0)==0xa12000)\r
+ rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
\r
- // prg RAM\r
- if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
- u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
- wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
- d = *(u16 *)(prg_bank+(a&0x1fffe));\r
- wrdprintf("ret = %04x", d);\r
- goto end;\r
- }\r
+ d = OtherRead16(a, 16);\r
\r
- // word RAM\r
- if ((a&0xfc0000)==0x200000) {\r
- wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
- if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
- int bank = Pico_mcd->s68k_regs[3]&1;\r
- if (a >= 0x220000)\r
- a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
- else a &= 0x1fffe;\r
- d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
- } else {\r
- // allow access in any mode, like Gens does\r
- d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
- }\r
- wrdprintf("ret = %04x", d);\r
- goto end;\r
+ if ((a&0xffffc0)==0xa12000)\r
+ rdprintf("ret = %04x", d);\r
+ break;\r
}\r
\r
- if ((a&0xffffc0)==0xa12000)\r
- rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
- d = OtherRead16(a, 16);\r
-\r
- if ((a&0xffffc0)==0xa12000)\r
- rdprintf("ret = %04x", d);\r
-\r
- end:\r
\r
#ifdef __debug_io\r
dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
{\r
u32 d=0;\r
\r
- if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram\r
-\r
a&=0xfffffe;\r
\r
- if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios\r
-\r
- // prg RAM\r
- if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
- u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
- u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
- d = (pm[0]<<16)|pm[1];\r
- goto end;\r
- }\r
-\r
- // word RAM\r
- if ((a&0xfc0000)==0x200000) {\r
- wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
- if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
- int bank = Pico_mcd->s68k_regs[3]&1;\r
- if (a >= 0x220000) { // cell arranged\r
+ switch (a >> 17)\r
+ {\r
+ case 0x00>>1: { // BIOS: 000000 - 020000\r
+ u16 *pm=(u16 *)(Pico_mcd->bios+a);\r
+ d = (pm[0]<<16)|pm[1];\r
+ break;\r
+ }\r
+ case 0x02>>1: // prg RAM\r
+ if ((Pico_mcd->m.busreq&3)!=1) {\r
+ u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+ u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
+ d = (pm[0]<<16)|pm[1];\r
+ }\r
+ break;\r
+ case 0x20>>1: // word RAM: 200000 - 220000\r
+ wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
+ a&=0x1fffe;\r
+ if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
+ u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
+ d = (pm[0]<<16)|pm[1];\r
+ } else {\r
+ // allow access in any mode, like Gens does\r
+ u16 *pm=(u16 *)(Pico_mcd->word_ram2M+a);\r
+ d = (pm[0]<<16)|pm[1];\r
+ }\r
+ wrdprintf("ret = %08x", d);\r
+ break;\r
+ case 0x22>>1: // word RAM: 220000 - 240000\r
+ wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
+ if (Pico_mcd->s68k_regs[3]&4) { // 1M mode, cell arranged?\r
u32 a1, a2;\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
a1 = (a&2) | (cell_map(a >> 2) << 2);\r
if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
else a2 = a1 + 2;\r
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;\r
d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);\r
} else {\r
- u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
+ // allow access in any mode, like Gens does\r
+ u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
+ d = (pm[0]<<16)|pm[1];\r
}\r
- } else {\r
- // allow access in any mode, like Gens does\r
- u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
+ wrdprintf("ret = %08x", d);\r
+ break;\r
+ case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
+ case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
+ case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
+ case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
+ // VDP\r
+ d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);\r
+ break;\r
+ case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
+ case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
+ case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
+ case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: {\r
+ // RAM:\r
+ u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
+ d = (pm[0]<<16)|pm[1];\r
+ break;\r
}\r
- wrdprintf("ret = %08x", d);\r
- goto end;\r
- }\r
+ default:\r
+ if ((a&0xffffc0)==0xa12000)\r
+ rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
\r
- if ((a&0xffffc0)==0xa12000)\r
- rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
+ d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
\r
- d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
+ if ((a&0xffffc0)==0xa12000)\r
+ rdprintf("ret = %08x", d);\r
+ break;\r
+ }\r
\r
- if ((a&0xffffc0)==0xa12000)\r
- rdprintf("ret = %08x", d);\r
\r
- end:\r
#ifdef __debug_io\r
dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
#endif\r
return;\r
}\r
\r
- a&=0xffffff;\r
-\r
// prg RAM\r
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
return;\r
}\r
\r
+ a&=0xffffff;\r
+\r
// word RAM\r
if ((a&0xfc0000)==0x200000) {\r
wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
return;\r
}\r
\r
- a&=0xfffffe;\r
-\r
// prg RAM\r
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
return;\r
}\r
\r
+ a&=0xfffffe;\r
+\r
// word RAM\r
if ((a&0xfc0000)==0x200000) {\r
wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
return;\r
}\r
\r
+ // VDP\r
+ if ((a&0xe700e0)==0xc00000) {\r
+ PicoVideoWrite(a,(u16)d);\r
+ return;\r
+ }\r
+\r
OtherWrite16(a,d);\r
}\r
#endif\r
return;\r
}\r
\r
- a&=0xfffffe;\r
-\r
// prg RAM\r
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
return;\r
}\r
\r
+ a&=0xfffffe;\r
+\r
// word RAM\r
if ((a&0xfc0000)==0x200000) {\r
if (d != 0) // don't log clears\r
if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);\r
}\r
\r
+ // VDP\r
+ if ((a&0xe700e0)==0xc00000)\r
+ {\r
+ PicoVideoWrite(a, (u16)(d>>16));\r
+ PicoVideoWrite(a+2,(u16)d);\r
+ return;\r
+ }\r
+\r
OtherWrite16(a, (u16)(d>>16));\r
OtherWrite16(a+2,(u16)d);\r
}\r
SRam.data = NULL;
if (PicoOpt&0x8000)
SRam.data = calloc(1, 0x12000);
+ SRam.start = SRam.end = 0; // unused
return 0;
}
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);
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
{
{
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
{
// This is part of Pico Library\r
\r
// (c) Copyright 2004 Dave, All rights reserved.\r
-// (c) Copyright 2006 notaz, All rights reserved.\r
+// (c) Copyright 2006,2007 notaz, All rights reserved.\r
// Free for non-commercial use.\r
\r
// For commercial use, separate licencing terms must be obtained.\r
#include "ym2612.h"\r
#include "sn76496.h"\r
\r
-#if defined(_USE_MZ80)\r
-#include "../../cpu/mz80/mz80.h"\r
-#elif defined(_USE_DRZ80)\r
-#include "../../cpu/DrZ80/drz80.h"\r
-#elif defined(_USE_CZ80)\r
-#include "../../cpu/cz80/cz80.h"\r
-#endif\r
-\r
#include "../PicoInt.h"\r
#include "../cd/pcm.h"\r
#include "mix.h"\r
int PsndLen_exc_cnt=0;\r
short *PsndOut=NULL; // PCM data buffer\r
\r
-// from ym2612.c\r
-extern int *ym2612_dacen;\r
-extern INT32 *ym2612_dacout;\r
-void YM2612TimerHandler(int c,int cnt);\r
-\r
// sn76496\r
extern int *sn76496_regs;\r
\r
{(UINT16) -1,(UINT16) -1,NULL}\r
};\r
\r
+int mz80_run(int cycles)\r
+{\r
+ int ticks_pre = mz80GetElapsedTicks(0);\r
+ mz80exec(cycles);\r
+ return mz80GetElapsedTicks(0) - ticks_pre;\r
+}\r
+\r
#elif defined(_USE_DRZ80)\r
\r
-static struct DrZ80 drZ80;\r
+struct DrZ80 drZ80;\r
\r
static unsigned int DrZ80_rebasePC(unsigned short a)\r
{\r
Cz80_Init(&CZ80);\r
Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM\r
Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram - 0x2000); // mirror\r
- Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read);\r
+ Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read); // unused (hacked in)\r
Cz80_Set_WriteB(&CZ80, z80_write);\r
Cz80_Set_INPort(&CZ80, z80_in);\r
Cz80_Set_OUTPort(&CZ80, z80_out);\r
Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled\r
}\r
\r
-PICO_INTERNAL void z80_resetCycles(void)\r
-{\r
-#if defined(_USE_MZ80)\r
- mz80GetElapsedTicks(1);\r
-#endif\r
-}\r
-\r
-PICO_INTERNAL void z80_int(void)\r
-{\r
-#if defined(_USE_MZ80)\r
- mz80int(0);\r
-#elif defined(_USE_DRZ80)\r
- drZ80.z80irqvector = 0xFF; // default IRQ vector RST opcode\r
- drZ80.Z80_IRQ = 1;\r
-#elif defined(_USE_CZ80)\r
- Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE);\r
-#endif\r
-}\r
-\r
-// returns number of cycles actually executed\r
-PICO_INTERNAL int z80_run(int cycles)\r
-{\r
-#if defined(_USE_MZ80)\r
- int ticks_pre = mz80GetElapsedTicks(0);\r
- mz80exec(cycles);\r
- return mz80GetElapsedTicks(0) - ticks_pre;\r
-#elif defined(_USE_DRZ80)\r
- return cycles - DrZ80Run(&drZ80, cycles);\r
-#elif defined(_USE_CZ80)\r
- return Cz80_Exec(&CZ80, cycles);\r
-#else\r
- return cycles;\r
-#endif\r
-}\r
\r
PICO_INTERNAL void z80_pack(unsigned char *data)\r
{\r
}\r
\r
\r
-INLINE void FM_KEYON(FM_CH *CH , int s )\r
+INLINE void FM_KEYON(int c , int s )\r
{\r
- FM_SLOT *SLOT = &CH->SLOT[s];\r
+ FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];\r
if( !SLOT->key )\r
{\r
SLOT->key = 1;\r
SLOT->phase = 0; /* restart Phase Generator */\r
SLOT->state = EG_ATT; /* phase -> Attack */\r
+ ym2612.slot_mask |= (1<<s) << (c*4);\r
}\r
}\r
\r
-INLINE void FM_KEYOFF(FM_CH *CH , int s )\r
+INLINE void FM_KEYOFF(int c , int s )\r
{\r
- FM_SLOT *SLOT = &CH->SLOT[s];\r
+ FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];\r
if( SLOT->key )\r
{\r
SLOT->key = 0;\r
UINT32 pack; // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16]\r
UINT32 algo; /* 50: algo[3], was_update */\r
INT32 op1_out;\r
+#ifdef _MIPS_ARCH_ALLEGREX\r
+ UINT32 pad1[3+8];\r
+#endif\r
} chan_rend_context;\r
\r
\r
\r
switch( ct->CH->ALGO )\r
{\r
-#if 0\r
- case 0: smp = upd_algo0(ct); break;\r
- case 1: smp = upd_algo1(ct); break;\r
- case 2: smp = upd_algo2(ct); break;\r
- case 3: smp = upd_algo3(ct); break;\r
- case 4: smp = upd_algo4(ct); break;\r
- case 5: smp = upd_algo5(ct); break;\r
- case 6: smp = upd_algo6(ct); break;\r
- case 7: smp = upd_algo7(ct); break;\r
-#else\r
case 0:\r
{\r
/* M1---C1---MEM---M2---C2---OUT */\r
}\r
break;\r
}\r
-#endif\r
}\r
/* done calculating channel sample */\r
\r
void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);\r
#endif\r
\r
+static chan_rend_context __attribute__((aligned(64))) crct;\r
\r
-static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
+static int chan_render(int *buffer, int length, int c, UINT32 flags) // flags: stereo, ?, disabled, ?, pan_r, pan_l\r
{\r
- chan_rend_context ct;\r
-\r
- ct.CH = CH;\r
- ct.mem = CH->mem_value; /* one sample delay memory */\r
- ct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
- ct.lfo_inc = ym2612.OPN.lfo_inc;\r
+ crct.CH = &ym2612.CH[c];\r
+ crct.mem = crct.CH->mem_value; /* one sample delay memory */\r
+ crct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
+ crct.lfo_inc = ym2612.OPN.lfo_inc;\r
\r
- flags &= 0x37;\r
+ flags &= 0x35;\r
\r
- if (ct.lfo_inc) {\r
+ if (crct.lfo_inc) {\r
flags |= 8;\r
flags |= g_lfo_ampm << 16;\r
- flags |= CH->AMmasks << 8;\r
- if (CH->ams == 8) // no ams\r
- flags &= ~0xf00;\r
- else flags |= (CH->ams&3)<<6;\r
+ flags |= crct.CH->AMmasks << 8;\r
+ if (crct.CH->ams == 8) // no ams\r
+ flags &= ~0xf00;\r
+ else flags |= (crct.CH->ams&3)<<6;\r
}\r
- flags |= (CH->FB&0xf)<<12; /* feedback shift */\r
- ct.pack = flags;\r
+ flags |= (crct.CH->FB&0xf)<<12; /* feedback shift */\r
+ crct.pack = flags;\r
\r
- ct.eg_cnt = ym2612.OPN.eg_cnt; /* envelope generator counter */\r
- ct.eg_timer = ym2612.OPN.eg_timer;\r
- ct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
+ crct.eg_cnt = ym2612.OPN.eg_cnt; /* envelope generator counter */\r
+ crct.eg_timer = ym2612.OPN.eg_timer;\r
+ crct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
\r
/* precalculate phase modulation incr */\r
- ct.phase1 = CH->SLOT[SLOT1].phase;\r
- ct.phase2 = CH->SLOT[SLOT2].phase;\r
- ct.phase3 = CH->SLOT[SLOT3].phase;\r
- ct.phase4 = CH->SLOT[SLOT4].phase;\r
+ crct.phase1 = crct.CH->SLOT[SLOT1].phase;\r
+ crct.phase2 = crct.CH->SLOT[SLOT2].phase;\r
+ crct.phase3 = crct.CH->SLOT[SLOT3].phase;\r
+ crct.phase4 = crct.CH->SLOT[SLOT4].phase;\r
\r
/* current output from EG circuit (without AM from LFO) */\r
- ct.vol_out1 = CH->SLOT[SLOT1].tl + ((UINT32)CH->SLOT[SLOT1].volume);\r
- ct.vol_out2 = CH->SLOT[SLOT2].tl + ((UINT32)CH->SLOT[SLOT2].volume);\r
- ct.vol_out3 = CH->SLOT[SLOT3].tl + ((UINT32)CH->SLOT[SLOT3].volume);\r
- ct.vol_out4 = CH->SLOT[SLOT4].tl + ((UINT32)CH->SLOT[SLOT4].volume);\r
+ crct.vol_out1 = crct.CH->SLOT[SLOT1].tl + ((UINT32)crct.CH->SLOT[SLOT1].volume);\r
+ crct.vol_out2 = crct.CH->SLOT[SLOT2].tl + ((UINT32)crct.CH->SLOT[SLOT2].volume);\r
+ crct.vol_out3 = crct.CH->SLOT[SLOT3].tl + ((UINT32)crct.CH->SLOT[SLOT3].volume);\r
+ crct.vol_out4 = crct.CH->SLOT[SLOT4].tl + ((UINT32)crct.CH->SLOT[SLOT4].volume);\r
\r
- ct.op1_out = CH->op1_out;\r
- ct.algo = CH->ALGO & 7;\r
+ crct.op1_out = crct.CH->op1_out;\r
+ crct.algo = crct.CH->ALGO & 7;\r
\r
- if(CH->pms)\r
+ if(crct.CH->pms)\r
{\r
/* add support for 3 slot mode */\r
- UINT32 block_fnum = CH->block_fnum;\r
+ UINT32 block_fnum = crct.CH->block_fnum;\r
\r
UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;\r
- INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + ((ct.pack>>16)&0xff) ];\r
+ INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + crct.CH->pms + ((crct.pack>>16)&0xff) ];\r
\r
if (lfo_fn_table_index_offset) /* LFO phase modulation active */\r
{\r
/* phase increment counter */\r
fc = fn_table[fn]>>(7-blk);\r
\r
- ct.incr1 = ((fc+CH->SLOT[SLOT1].DT[kc])*CH->SLOT[SLOT1].mul) >> 1;\r
- ct.incr2 = ((fc+CH->SLOT[SLOT2].DT[kc])*CH->SLOT[SLOT2].mul) >> 1;\r
- ct.incr3 = ((fc+CH->SLOT[SLOT3].DT[kc])*CH->SLOT[SLOT3].mul) >> 1;\r
- ct.incr4 = ((fc+CH->SLOT[SLOT4].DT[kc])*CH->SLOT[SLOT4].mul) >> 1;\r
+ crct.incr1 = ((fc+crct.CH->SLOT[SLOT1].DT[kc])*crct.CH->SLOT[SLOT1].mul) >> 1;\r
+ crct.incr2 = ((fc+crct.CH->SLOT[SLOT2].DT[kc])*crct.CH->SLOT[SLOT2].mul) >> 1;\r
+ crct.incr3 = ((fc+crct.CH->SLOT[SLOT3].DT[kc])*crct.CH->SLOT[SLOT3].mul) >> 1;\r
+ crct.incr4 = ((fc+crct.CH->SLOT[SLOT4].DT[kc])*crct.CH->SLOT[SLOT4].mul) >> 1;\r
}\r
else /* LFO phase modulation = zero */\r
{\r
- ct.incr1 = CH->SLOT[SLOT1].Incr;\r
- ct.incr2 = CH->SLOT[SLOT2].Incr;\r
- ct.incr3 = CH->SLOT[SLOT3].Incr;\r
- ct.incr4 = CH->SLOT[SLOT4].Incr;\r
+ crct.incr1 = crct.CH->SLOT[SLOT1].Incr;\r
+ crct.incr2 = crct.CH->SLOT[SLOT2].Incr;\r
+ crct.incr3 = crct.CH->SLOT[SLOT3].Incr;\r
+ crct.incr4 = crct.CH->SLOT[SLOT4].Incr;\r
}\r
}\r
else /* no LFO phase modulation */\r
{\r
- ct.incr1 = CH->SLOT[SLOT1].Incr;\r
- ct.incr2 = CH->SLOT[SLOT2].Incr;\r
- ct.incr3 = CH->SLOT[SLOT3].Incr;\r
- ct.incr4 = CH->SLOT[SLOT4].Incr;\r
+ crct.incr1 = crct.CH->SLOT[SLOT1].Incr;\r
+ crct.incr2 = crct.CH->SLOT[SLOT2].Incr;\r
+ crct.incr3 = crct.CH->SLOT[SLOT3].Incr;\r
+ crct.incr4 = crct.CH->SLOT[SLOT4].Incr;\r
}\r
\r
- chan_render_loop(&ct, buffer, length);\r
+ chan_render_loop(&crct, buffer, length);\r
\r
- // write back persistent stuff:\r
- if (flags & 2) { /* last channel */\r
- ym2612.OPN.eg_cnt = ct.eg_cnt;\r
- ym2612.OPN.eg_timer = ct.eg_timer;\r
- g_lfo_ampm = ct.pack >> 16;\r
- ym2612.OPN.lfo_cnt = ct.lfo_cnt;\r
+ crct.CH->op1_out = crct.op1_out;\r
+ crct.CH->mem_value = crct.mem;\r
+ if (crct.CH->SLOT[SLOT1].state | crct.CH->SLOT[SLOT2].state | crct.CH->SLOT[SLOT3].state | crct.CH->SLOT[SLOT4].state)\r
+ {\r
+ crct.CH->SLOT[SLOT1].phase = crct.phase1;\r
+ crct.CH->SLOT[SLOT2].phase = crct.phase2;\r
+ crct.CH->SLOT[SLOT3].phase = crct.phase3;\r
+ crct.CH->SLOT[SLOT4].phase = crct.phase4;\r
}\r
+ else\r
+ ym2612.slot_mask &= ~(0xf << (c*4));\r
\r
- CH->op1_out = ct.op1_out;\r
- CH->SLOT[SLOT1].phase = ct.phase1;\r
- CH->SLOT[SLOT2].phase = ct.phase2;\r
- CH->SLOT[SLOT3].phase = ct.phase3;\r
- CH->SLOT[SLOT4].phase = ct.phase4;\r
- CH->mem_value = ct.mem;\r
+ // if this the last call, write back persistent stuff:\r
+ if ((ym2612.slot_mask >> ((c+1)*4)) == 0)\r
+ {\r
+ ym2612.OPN.eg_cnt = crct.eg_cnt;\r
+ ym2612.OPN.eg_timer = crct.eg_timer;\r
+ g_lfo_ampm = crct.pack >> 16;\r
+ ym2612.OPN.lfo_cnt = crct.lfo_cnt;\r
+ }\r
\r
- return (ct.algo & 8) >> 3; // had output\r
+ return (crct.algo & 8) >> 3; // had output\r
}\r
\r
/* update phase increment and envelope generator */\r
}\r
\r
\r
-static void reset_channels(FM_CH *CH, int num)\r
+static void reset_channels(FM_CH *CH)\r
{\r
int c,s;\r
\r
ym2612.OPN.ST.TB = 0;\r
ym2612.OPN.ST.TBC = 0;\r
\r
- for( c = 0 ; c < num ; c++ )\r
+ for( c = 0 ; c < 6 ; c++ )\r
{\r
CH[c].fc = 0;\r
for(s = 0 ; s < 4 ; s++ )\r
CH[c].SLOT[s].volume = MAX_ATT_INDEX;\r
}\r
}\r
+ ym2612.slot_mask = 0;\r
}\r
\r
/* initialize generic tables */\r
\r
\r
/* CSM Key Controll */\r
+#if 0\r
INLINE void CSMKeyControll(FM_CH *CH)\r
{\r
/* this is wrong, atm */\r
FM_KEYON(CH,SLOT3);\r
FM_KEYON(CH,SLOT4);\r
}\r
+#endif\r
\r
\r
/* prescaler set (and make time tables) */\r
\r
int *ym2612_dacen;\r
INT32 *ym2612_dacout;\r
+FM_ST *ym2612_st;\r
\r
\r
/* Generate samples for YM2612 */\r
// if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash\r
if (is_buf_empty) memset32(buffer, 0, length<<stereo);\r
\r
+/*\r
+ {\r
+ int c, s;\r
+ ppp();\r
+ for (c = 0; c < 6; c++) {\r
+ int slr = 0, slm;\r
+ printf("%i: ", c);\r
+ for (s = 0; s < 4; s++) {\r
+ if (ym2612.CH[c].SLOT[s].state != EG_OFF) slr = 1;\r
+ printf(" %i", ym2612.CH[c].SLOT[s].state != EG_OFF);\r
+ }\r
+ slm = (ym2612.slot_mask&(0xf<<(c*4))) ? 1 : 0;\r
+ printf(" | %i", slm);\r
+ printf(" | %i\n", ym2612.CH[c].SLOT[SLOT1].Incr==-1);\r
+ if (slr != slm) exit(1);\r
+ }\r
+ }\r
+*/\r
/* refresh PG and EG */\r
refresh_fc_eg_chan( &ym2612.CH[0] );\r
refresh_fc_eg_chan( &ym2612.CH[1] );\r
if (stereo) stereo = 1;\r
\r
/* mix to 32bit dest */\r
- // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
- active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0;\r
- active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1;\r
- active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )) << 2;\r
- active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3;\r
- active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4;\r
- active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5;\r
+ // flags: stereo, ?, disabled, ?, pan_r, pan_l\r
+ if (ym2612.slot_mask & 0x00000f) active_chs |= chan_render(buffer, length, 0, stereo|((pan&0x003)<<4)) << 0;\r
+ if (ym2612.slot_mask & 0x0000f0) active_chs |= chan_render(buffer, length, 1, stereo|((pan&0x00c)<<2)) << 1;\r
+ if (ym2612.slot_mask & 0x000f00) active_chs |= chan_render(buffer, length, 2, stereo|((pan&0x030) )) << 2;\r
+ if (ym2612.slot_mask & 0x00f000) active_chs |= chan_render(buffer, length, 3, stereo|((pan&0x0c0)>>2)) << 3;\r
+ if (ym2612.slot_mask & 0x0f0000) active_chs |= chan_render(buffer, length, 4, stereo|((pan&0x300)>>4)) << 4;\r
+ if (ym2612.slot_mask & 0xf00000) active_chs |= chan_render(buffer, length, 5, stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)) << 5;\r
\r
return active_chs; // 1 if buffer updated\r
}\r
// notaz\r
ym2612_dacen = &ym2612.dacen;\r
ym2612_dacout = &ym2612.dacout;\r
+ ym2612_st = &ym2612.OPN.ST;\r
\r
memset(&ym2612, 0, sizeof(ym2612));\r
init_tables();\r
ym2612.OPN.eg_cnt = 0;\r
ym2612.OPN.ST.status = 0;\r
\r
- reset_channels( &ym2612.CH[0] , 6 );\r
+ reset_channels( &ym2612.CH[0] );\r
for(i = 0xb6 ; i >= 0xb4 ; i-- )\r
{\r
OPNWriteReg(i ,0xc0);\r
case 0x28: /* key on / off */\r
{\r
UINT8 c;\r
- FM_CH *CH;\r
\r
c = v & 0x03;\r
if( c == 3 ) { ret=0; break; }\r
if( v&0x04 ) c+=3;\r
- CH = &ym2612.CH[c];\r
- if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);\r
- if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);\r
- if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);\r
- if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);\r
+ if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);\r
+ if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);\r
+ if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);\r
+ if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4);\r
break;\r
}\r
case 0x2a: /* DAC data (YM2612) */\r
return ret;\r
}\r
\r
+#if 0\r
UINT8 YM2612Read_(void)\r
{\r
return ym2612.OPN.ST.status;\r
}\r
\r
-\r
int YM2612PicoTick_(int n)\r
{\r
int ret = 0;\r
\r
return ret;\r
}\r
-\r
+#endif\r
\r
void YM2612PicoStateLoad_(void)\r
{\r
#ifndef EXTERNAL_YM2612\r
int i, real_A1 = ym2612.addr_A1;\r
\r
- reset_channels( &ym2612.CH[0], 6 );\r
+ reset_channels( &ym2612.CH[0] );\r
\r
// feed all the registers and update internal state\r
for(i = 0; i < 0x100; i++) {\r
\r
ym2612.addr_A1 = real_A1;\r
#else\r
- reset_channels( &ym2612.CH[0], 6 );\r
+ reset_channels( &ym2612.CH[0] );\r
#endif\r
}\r
\r
-\r
#ifndef EXTERNAL_YM2612\r
void *YM2612GetRegs(void)\r
{\r
{\r
int clock; /* master clock (Hz) */\r
int rate; /* sampling rate (Hz) */\r
- double freqbase; /* frequency base */\r
- UINT8 address; /* address register */\r
- UINT8 status; /* status flag */\r
+ double freqbase; /* 08 frequency base */\r
+ UINT8 address; /* 10 address register */\r
+ UINT8 status; /* 11 status flag */\r
UINT8 mode; /* mode CSM / 3SLOT */\r
UINT8 fn_h; /* freq latch */\r
int TA; /* timer a */\r
int TAC; /* timer a maxval */\r
int TAT; /* timer a ticker */\r
UINT8 TB; /* timer b */\r
+ UINT8 pad[3];\r
int TBC; /* timer b maxval */\r
int TBT; /* timer b ticker */\r
/* local time tables */\r
INT32 dacout;\r
\r
FM_OPN OPN; /* OPN state */\r
+\r
+ UINT32 slot_mask; /* active slot mask (performance hack) */\r
} YM2612;\r
#endif\r
\r
+extern int *ym2612_dacen;\r
+extern INT32 *ym2612_dacout;\r
+extern FM_ST *ym2612_st;\r
+\r
+\r
+#define YM2612Read() ym2612_st->status\r
+\r
+#define YM2612PicoTick(n) \\r
+{ \\r
+ /* timer A */ \\r
+ if(ym2612_st->mode & 0x01 && (ym2612_st->TAT+=64*n) >= ym2612_st->TAC) { \\r
+ ym2612_st->TAT -= ym2612_st->TAC; \\r
+ if(ym2612_st->mode & 0x04) ym2612_st->status |= 1; \\r
+ } \\r
+ \\r
+ /* timer B */ \\r
+ if(ym2612_st->mode & 0x02 && (ym2612_st->TBT+=64*n) >= ym2612_st->TBC) { \\r
+ ym2612_st->TBT -= ym2612_st->TBC; \\r
+ if(ym2612_st->mode & 0x08) ym2612_st->status |= 2; \\r
+ } \\r
+}\r
\r
\r
void YM2612Init_(int baseclock, int rate);\r
#define YM2612ResetChip YM2612ResetChip_\r
#define YM2612UpdateOne YM2612UpdateOne_\r
#define YM2612Write YM2612Write_\r
-#define YM2612Read YM2612Read_\r
-#define YM2612PicoTick YM2612PicoTick_\r
#define YM2612PicoStateLoad YM2612PicoStateLoad_\r
#else\r
/* GP2X specific */\r
YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);\r
#define YM2612Write(a,v) \\r
(PicoOpt&0x200) ? YM2612Write_940(a, v) : YM2612Write_(a, v)\r
-#define YM2612Read() \\r
- (PicoOpt&0x200) ? YM2612Read_940() : YM2612Read_()\r
-#define YM2612PicoTick(n) \\r
- (PicoOpt&0x200) ? YM2612PicoTick_940(n) : YM2612PicoTick_(n)\r
#define YM2612PicoStateLoad() { \\r
if (PicoOpt&0x200) YM2612PicoStateLoad_940(); \\r
else YM2612PicoStateLoad_(); \\r
.endif\r
\r
.if DRZ80_FOR_PICODRIVE\r
-.include "port_config.s"\r
- .extern YM2612Read_\r
-.if EXTERNAL_YM2612\r
- .extern YM2612Read_940\r
-.endif\r
.extern PicoRead8\r
.extern Pico\r
.extern z80_write\r
+ .extern ym2612_st\r
.endif\r
\r
DrZ80Ver: .long 0x0001\r
.if DRZ80_FOR_PICODRIVE\r
\r
.macro YM2612Read_and_ret8\r
- stmfd sp!,{r3,r12,lr}\r
-.if EXTERNAL_YM2612\r
- ldr r1,=PicoOpt\r
- ldr r1,[r1]\r
- tst r1,#0x200\r
- ldrne r2, =YM2612Read_940\r
- ldreq r2, =YM2612Read_\r
- mov lr,pc\r
- bx r2\r
-.else\r
- bl YM2612Read_\r
-.endif\r
- ldmfd sp!,{r3,r12,pc}\r
+ ldr r0, =ym2612_st\r
+ ldr r0, [r0]\r
+ ldrb r0, [r0, #0x11] ;@ ym2612_st->status\r
+ bx lr\r
.endm\r
\r
.macro YM2612Read_and_ret16\r
- stmfd sp!,{r3,r12,lr}\r
-.if EXTERNAL_YM2612\r
- ldr r0,=PicoOpt\r
- ldr r0,[r0]\r
- tst r0,#0x200\r
- ldrne r2, =YM2612Read_940\r
- ldreq r2, =YM2612Read_\r
- mov lr,pc\r
- bx r2\r
+ ldr r0, =ym2612_st\r
+ ldr r0, [r0]\r
+ ldrb r0, [r0, #0x11] ;@ ym2612_st->status\r
orr r0,r0,r0,lsl #8\r
-.else\r
- bl YM2612Read_\r
- orr r0,r0,r0,lsl #8\r
-.endif\r
- ldmfd sp!,{r3,r12,pc}\r
+ bx lr\r
.endm\r
\r
pico_z80_read8: @ addr\r
add r0,r4,#1\r
bl PicoRead8\r
orr r0,r5,r0,lsl #8\r
- ldmfd sp!,{r3-r5,r12,pc}\r
+ ldmfd sp!,{r3-r5,r12,pc}\r
1:\r
mov r1,r0,lsr #13\r
cmp r1,#2 @ YM2612 (0x4000-0x5fff)\r
bne 0f\r
and r0,r0,#3\r
- YM2612Read_and_ret16\r
+ YM2612Read_and_ret16\r
0:\r
cmp r0,#0x4000\r
movge r0,#0xff\r
#include <string.h>\r
#include "cz80.h"\r
\r
+#if PICODRIVE_HACKS\r
+#include <Pico/PicoInt.h>\r
+#endif\r
+\r
#ifndef ALIGN_DATA\r
#define ALIGN_DATA __attribute__((aligned(4)))\r
#endif\r
Cz80_Set_Reg(CPU, CZ80_PC, 0);\r
}\r
\r
+/* */\r
+#if PICODRIVE_HACKS\r
+static inline unsigned char picodrive_read(unsigned short a)\r
+{\r
+ return (a < 0x4000) ? Pico.zram[a&0x1fff] : z80_read(a);\r
+}\r
+#endif\r
\r
/*--------------------------------------------------------\r
CPU\8eÀ\8ds\r
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)\r
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)\r
\r
+#define PICODRIVE_HACKS 1\r
#define CZ80_LITTLE_ENDIAN 1\r
#define CZ80_USE_JUMPTABLE 1\r
#define CZ80_BIG_FLAGS_ARRAY 1\r
//#ifndef BUILD_CPS1PSP\r
//#define READ_MEM8(A) memory_region_cpu2[(A)]\r
//#else\r
+#if PICODRIVE_HACKS\r
+#define READ_MEM8(A) picodrive_read(A)\r
+#else\r
#define READ_MEM8(A) CPU->Read_Byte(A)\r
+#endif\r
//#endif\r
#if CZ80_LITTLE_ENDIAN\r
#define READ_MEM16(A) (READ_MEM8(A) | (READ_MEM8((A) + 1) << 8))\r
#define READ_MEM16(A) ((READ_MEM8(A) << 8) | READ_MEM8((A) + 1))\r
#endif\r
\r
+#if PICODRIVE_HACKS\r
+#define WRITE_MEM8(A, D) { \\r
+ unsigned short a = A; \\r
+ unsigned char d = D; \\r
+ if (a < 0x4000) Pico.zram[a&0x1fff] = d; \\r
+ else z80_write(a, d); \\r
+}\r
+#else\r
#define WRITE_MEM8(A, D) CPU->Write_Byte(A, D);\r
+#endif\r
#if CZ80_LITTLE_ENDIAN\r
#define WRITE_MEM16(A, D) { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }\r
#else\r
\r
// Options //\r
#define FAMEC_ROLL_INLINE\r
-#define FAMEC_EMULATE_TRACE\r
-#define FAMEC_CHECK_BRANCHES\r
+//#define FAMEC_EMULATE_TRACE\r
+//#define FAMEC_CHECK_BRANCHES\r
#define FAMEC_EXTRA_INLINE\r
// #define FAMEC_DEBUG\r
//#define FAMEC_NO_GOTOS\r
((u32)PC - BasePC)\r
\r
\r
+#ifdef FAMEC_CHECK_BRANCHES\r
+#define FORCE_ALIGNMENT(pc)\r
+#else\r
+#define FORCE_ALIGNMENT(pc) pc&=~1;\r
+#endif\r
+\r
#ifndef FAMEC_32BIT_PC\r
\r
#define SET_PC(A) \\r
{ \\r
u32 pc = A; \\r
+ FORCE_ALIGNMENT(pc); \\r
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \\r
PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \\r
}\r
#define SET_PC(A) \\r
{ \\r
u32 pc = A; \\r
+ FORCE_ALIGNMENT(pc); \\r
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \\r
BasePC -= pc & 0xFF000000; \\r
PC = (u16*)(pc + BasePC); \\r
#ifndef FAMEC_32BIT_PC\r
newPC&=M68K_ADR_MASK\r
#endif\r
+#ifdef FAMEC_CHECK_BRANCHES\r
newPC&=~1; // don't crash on games with bad vector tables\r
+#endif\r
\r
// SET_PC(newPC)\r
\r
#ifdef PICODRIVE_HACK\r
dualcore_mode:\r
\r
+ while (1)\r
{\r
extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k;\r
#define PS_STEP_M68K ((488<<16)/20) // ~24\r
}\r
cycles = m68kcontext.io_cycle_counter = 0;\r
}\r
- goto dualcore_mode;\r
}\r
#endif\r
\r
}\r
\r
/* these will be managed locally on our side */\r
-extern int *ym2612_dacen;\r
-extern INT32 *ym2612_dacout;\r
static UINT8 *REGS = 0; /* we will also keep local copy of regs for savestates and such */\r
static INT32 *addr_A1; /* address line A1 */\r
\r
static int dacen;\r
static INT32 dacout;\r
static UINT8 ST_address; /* address register */\r
-static UINT8 ST_status; /* status flag */\r
-static UINT8 ST_mode; /* mode CSM / 3SLOT */\r
-static int ST_TA; /* timer a */\r
-static int ST_TAC; /* timer a maxval */\r
-static int ST_TAT; /* timer a ticker */\r
-static UINT8 ST_TB; /* timer b */\r
-static int ST_TBC; /* timer b maxval */\r
-static int ST_TBT; /* timer b ticker */\r
\r
static int writebuff_ptr = 0;\r
\r
/* b2 = timer enable a */\r
/* b1 = load b */\r
/* b0 = load a */\r
- change = (ST_mode ^ v) & 0xc0;\r
- ST_mode = v;\r
+ change = (ym2612_st->mode ^ v) & 0xc0;\r
+ ym2612_st->mode = v;\r
\r
/* reset Timer b flag */\r
if( v & 0x20 )\r
- ST_status &= ~2;\r
+ ym2612_st->status &= ~2;\r
\r
/* reset Timer a flag */\r
if( v & 0x10 )\r
- ST_status &= ~1;\r
+ ym2612_st->status &= ~1;\r
\r
return change;\r
}\r
switch( addr )\r
{\r
case 0x24: { // timer A High 8\r
- int TAnew = (ST_TA & 0x03)|(((int)v)<<2);\r
- if(ST_TA != TAnew) {\r
+ int TAnew = (ym2612_st->TA & 0x03)|(((int)v)<<2);\r
+ if (ym2612_st->TA != TAnew) {\r
// we should reset ticker only if new value is written. Outrun requires this.\r
- ST_TA = TAnew;\r
- ST_TAC = (1024-TAnew)*18;\r
- ST_TAT = 0;\r
+ ym2612_st->TA = TAnew;\r
+ ym2612_st->TAC = (1024-TAnew)*18;\r
+ ym2612_st->TAT = 0;\r
}\r
return 0;\r
}\r
case 0x25: { // timer A Low 2\r
- int TAnew = (ST_TA & 0x3fc)|(v&3);\r
- if(ST_TA != TAnew) {\r
- ST_TA = TAnew;\r
- ST_TAC = (1024-TAnew)*18;\r
- ST_TAT = 0;\r
+ int TAnew = (ym2612_st->TA & 0x3fc)|(v&3);\r
+ if (ym2612_st->TA != TAnew) {\r
+ ym2612_st->TA = TAnew;\r
+ ym2612_st->TAC = (1024-TAnew)*18;\r
+ ym2612_st->TAT = 0;\r
}\r
return 0;\r
}\r
case 0x26: // timer B\r
- if(ST_TB != v) {\r
- ST_TB = v;\r
- ST_TBC = (256-v)<<4;\r
- ST_TBC *= 18;\r
- ST_TBT = 0;\r
+ if (ym2612_st->TB != v) {\r
+ ym2612_st->TB = v;\r
+ ym2612_st->TBC = (256-v)<<4;\r
+ ym2612_st->TBC *= 18;\r
+ ym2612_st->TBT = 0;\r
}\r
return 0;\r
case 0x27: /* mode, timer control */\r
return 0; // cause the engine to do updates once per frame only\r
}\r
\r
-UINT8 YM2612Read_940(void)\r
-{\r
- return ST_status;\r
-}\r
-\r
-\r
-int YM2612PicoTick_940(int n)\r
-{\r
- //int ret = 0;\r
-\r
- // timer A\r
- if(ST_mode & 0x01 && (ST_TAT+=64*n) >= ST_TAC) {\r
- ST_TAT -= ST_TAC;\r
- if(ST_mode & 0x04) ST_status |= 1;\r
- // CSM mode total level latch and auto key on\r
-/* FIXME\r
- if(ST_mode & 0x80) {\r
- CSMKeyControll( &(ym2612_940->CH[2]) ); // Vectorman2, etc.\r
- ret = 1;\r
- }\r
-*/\r
- }\r
-\r
- // timer B\r
- if(ST_mode & 0x02 && (ST_TBT+=64*n) >= ST_TBC) {\r
- ST_TBT -= ST_TBC;\r
- if(ST_mode & 0x08) ST_status |= 2;\r
- }\r
-\r
- return 0;\r
-}\r
-\r
\r
#define CHECK_BUSY(job) \\r
(gp2x_memregs[0x3b46>>1] & (1<<(job-1)))\r
static void internal_reset(void)\r
{\r
writebuff_ptr = 0;\r
- ST_mode = 0;\r
- ST_status = 0; /* normal mode */\r
- ST_TA = 0;\r
- ST_TAC = 0;\r
- ST_TB = 0;\r
- ST_TBC = 0;\r
+ ym2612_st->mode = 0;\r
+ ym2612_st->status = 0; /* normal mode */\r
+ ym2612_st->TA = 0;\r
+ ym2612_st->TAC = 0;\r
+ ym2612_st->TAT = 0;\r
+ ym2612_st->TB = 0;\r
+ ym2612_st->TBC = 0;\r
+ ym2612_st->TBT = 0;\r
dacen = 0;\r
dacout = 0;\r
ST_address= 0;\r
all: PicoDrive.gpe\r
\r
PicoDrive.gpe : $(OBJS) ../common/helix/helix_mp3.a\r
- @echo $@\r
- @$(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map\r
+ @echo ">>>" $@\r
+ $(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map\r
ifeq ($(DEBUG),)\r
- @$(STRIP) $@\r
-endif\r
-# @$(GCC) $(COPT) $(OBJS) -lm -o PicoDrive_.gpe\r
-# @gpecomp PicoDrive_.gpe $@\r
-ifeq "$(up)" "1"\r
- @cmd //C copy $@ \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
+ $(STRIP) $@\r
endif\r
\r
up: PicoDrive.gpe\r
# @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
\r
\r
-testrefr.gpe : test.o gp2x.o\r
- @echo $@\r
- @$(GCC) $(COPT) $^ -o $@\r
- @$(STRIP) $@\r
-\r
.c.o:\r
- @echo $<\r
- @$(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
+ @echo ">>>" $<\r
+ $(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
.s.o:\r
- @echo $<\r
- @$(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
+ @echo ">>>" $<\r
+ $(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
\r
../../Pico/draw_asm.o : ../../Pico/Draw.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/draw2_asm.o : ../../Pico/Draw2.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/memory_asm.o : ../../Pico/Memory.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/sound/ym2612_asm.o : ../../Pico/sound/ym2612.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/sound/mix_asm.o : ../../Pico/sound/mix.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/misc_asm.o : ../../Pico/Misc.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/cd/memory_asm.o : ../../Pico/cd/Memory.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
../../Pico/cd/misc_asm.o : ../../Pico/cd/Misc.s\r
- @echo $<\r
- @$(AS) $(ASOPT) $< -o $@\r
+ @echo ">>>" $<\r
+ $(AS) $(ASOPT) $< -o $@\r
\r
# build Cyclone\r
../../cpu/Cyclone/proj/Cyclone.s :\r
-#define VERSION "1.34"\r
+#define VERSION "1.35"\r
\r
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)
{
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)
#use_musashi = 1\r
#use_mz80 = 1\r
amalgamate = 0\r
-#profile = 1\r
-#up = 1\r
\r
\r
CFLAGS += -I../.. -I. -DNO_SYNC -DLPRINTF_STDIO\r
CFLAGS += -Wall -Winline -G0\r
+CFLAGS += -DLPRINTF_STDIO\r
+#CFLAGS += -fprofile-generate\r
+#CFLAGS += -fprofile-use\r
+#CFLAGS += -pg\r
ifeq ($(DEBUG),)\r
CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math\r
else\r
CFLAGS += -ggdb\r
endif\r
-ifeq "$(profile)" "1"\r
-CFLAGS += -fprofile-generate\r
-endif\r
-ifeq "$(profile)" "2"\r
-CFLAGS += -fprofile-use\r
-endif\r
\r
\r
# frontend\r
else\r
OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.o \\r
../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o \\r
- ../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o\r
+ ../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o ../../Pico/Misc_amips.o\r
# Pico - CD\r
OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pico/cd/LC89510.o \\r
../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/gfx_cd.o \\r
\r
\r
LIBS += -lpng -lm -lpspgu -lpsppower -lpspaudio -lpsprtc -lpspaudiocodec\r
+#LIBS += -lpspprof\r
LDFLAGS += -Wl,-Map=PicoDrive.map\r
\r
+\r
# target\r
TARGET = PicoDrive\r
EXTRA_TARGETS = EBOOT.PBP\r
\r
../../Pico/Draw.o : ../../Pico/Draw.c\r
@echo ">>>" $<\r
- $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_DRAW_C_MIPS\r
+ $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_DRAW_C_AMIPS\r
+\r
+../../Pico/Misc.o : ../../Pico/Misc.c\r
+ @echo ">>>" $<\r
+ $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_MISC_C_AMIPS\r
\r
readme.txt: ../../tools/textfilter ../base_readme.txt\r
../../tools/textfilter ../base_readme.txt $@ PSP\r
\r
# ?\r
rel: EBOOT.PBP readme.txt\r
- zip -9 -j ../../PicoDrive_$(VER).zip $^\r
-# zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt\r
+ zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt\r
\r
#include "psp.h"
#include "menu.h"
#include "emu.h"
+#include "mp3.h"
#include "../common/emu.h"
#include "../common/lprintf.h"
#include "../../Pico/PicoInt.h"
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);
{
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
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;
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 {
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
/*
*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;
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)
if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
}
- dbg_text();
+ //dbg_text();
if ((emu_opt & 0x400) && (PicoMCD & 1))
cd_leds();
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);
}
}
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;
}
// 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);
}
void emu_msg_cb(const char *msg);
+// actually comes from Pico/Misc_amips.s
+void memset32_uncached(int *dest, int c, int count);
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);
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 ------------
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);
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
}
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();
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) {
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) {
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;
}
/* 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;
}
--- /dev/null
+
+// additional stuff for PSP mp3 decoder implementation
+extern int mp3_last_error;
+
+int mp3_init(void);
+void mp3_deinit(void);
+
+
#include <pspgu.h>
#include "psp.h"
+#include "emu.h"
#include "../common/lprintf.h"
PSP_MODULE_INFO("PicoDrive", 0, 1, 34);
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)
{
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
+ cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
+ scePowerRegisterCallback(0, cbid);
sceKernelSleepThreadCB();
-#define VERSION "1.34"\r
+#define VERSION "1.35"\r
\r
--- /dev/null
+#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;
+}
+