From: notaz Date: Sat, 31 Mar 2007 13:57:45 +0000 (+0000) Subject: bugfixes, new scaling, double ym upd at 940 X-Git-Tag: v1.85~728 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2433f409129279095926eb00cf8ab429738f80dd;p=picodrive.git bugfixes, new scaling, double ym upd at 940 git-svn-id: file:///home/notaz/opt/svn/PicoDrive@83 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/Pico/Cart.c b/Pico/Cart.c index 3954670..07ced8c 100644 --- a/Pico/Cart.c +++ b/Pico/Cart.c @@ -79,10 +79,8 @@ zip_failed: f = fopen(path, "rb"); if (f == NULL) return NULL; -#ifndef NO_IONBF /* we use our own buffering */ setvbuf(f, NULL, _IONBF, 0); -#endif file = malloc(sizeof(*file)); if (file == NULL) { diff --git a/Pico/Pico.c b/Pico/Pico.c index 4847f55..d0845e1 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -72,7 +72,7 @@ int PicoReset(int hard) PicoMemReset(); SekReset(); // s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games). - CycloneSetRealTAS(PicoMCD & 1); + SekSetRealTAS(PicoMCD & 1); SekCycleCntT=0; z80_reset(); @@ -486,7 +486,13 @@ static int PicoFrameSimple(void) int y=0,line=0,lines=0,lines_step=0,sects; int cycles_68k_vblock,cycles_68k_block; - if(Pico.m.pal) { + // we don't emulate DMA timing in this mode + if (Pico.m.dma_bytes) { + Pico.m.dma_bytes=0; + Pico.video.status&=~2; + } + + if (Pico.m.pal) { // M68k cycles/frame: 152009.78 if(pv->reg[1]&8) { // 240 lines cycles_68k_block = (int) ((double) OSC_PAL / 7 / 50 / 312 * 15 + 0.4); // 16 sects, 16*15=240, 7308 diff --git a/Pico/Pico.h b/Pico/Pico.h index 597f021..a8b276d 100644 --- a/Pico/Pico.h +++ b/Pico/Pico.h @@ -31,7 +31,7 @@ void mp3_update(int *buffer, int length, int stereo); // enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound, // alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites, // draw_no_32col_border, external_ym2612, enable_pcm, enable cdda -// enable_cdgfx, cd_perfect_sync +// enable_cdgfx, cd_perfect_sync, soft_32col_scaling extern int PicoOpt; extern int PicoVer; extern int PicoSkipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index 5c71f8a..e11f58b 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -311,6 +311,7 @@ int SekInit(void); int SekReset(void); int SekInterrupt(int irq); void SekState(unsigned char *data); +void SekSetRealTAS(int use_real); // cd/Sek.c int SekInitS68k(void); diff --git a/Pico/Sek.c b/Pico/Sek.c index 0ca575f..e05f6f4 100644 --- a/Pico/Sek.c +++ b/Pico/Sek.c @@ -186,3 +186,11 @@ void SekState(unsigned char *data) memcpy(data+0x40,&PicoM68kCPU.pc, 0x04); #endif } + +void SekSetRealTAS(int use_real) +{ +#ifdef EMU_C68K + CycloneSetRealTAS(use_real); +#endif +} + diff --git a/Pico/cd/Memory.c b/Pico/cd/Memory.c index 08a4486..fc6e4de 100644 --- a/Pico/cd/Memory.c +++ b/Pico/cd/Memory.c @@ -30,10 +30,13 @@ typedef unsigned int u32; #define rdprintf(...) //#define wrdprintf dprintf #define wrdprintf(...) +//#define plprintf dprintf +#define plprintf(...) // ----------------------------------------------------------------- // poller detection +//#undef USE_POLL_DETECT #define POLL_LIMIT 16 #define POLL_CYCLES 124 // int m68k_poll_addr, m68k_poll_cnt; @@ -143,7 +146,7 @@ void m68k_reg_write8(u32 a, u32 d) #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -163,7 +166,7 @@ void m68k_reg_write8(u32 a, u32 d) #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -174,7 +177,7 @@ void m68k_reg_write8(u32 a, u32 d) #ifdef USE_POLL_DETECT if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -183,6 +186,31 @@ void m68k_reg_write8(u32 a, u32 d) dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d); } +#ifndef _ASM_CD_MEMORY_C +static +#endif +u32 s68k_poll_detect(u32 a, u32 d) +{ +#ifdef USE_POLL_DETECT + // polling detection + if (a == (s68k_poll_adclk&0xff)) { + unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8); + if (clkdiff <= POLL_CYCLES) { + s68k_poll_cnt++; + //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt); + if (s68k_poll_cnt > POLL_LIMIT) { + SekSetStopS68k(1); + plprintf("s68k poll detected @ %06x, a=%02x\n", SekPcS68k, a); + } + s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; + return d; + } + } + s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; + s68k_poll_cnt = 0; +#endif + return d; +} #define READ_FONT_DATA(basemask) \ { \ @@ -208,9 +236,9 @@ u32 s68k_reg_read16(u32 a) case 0: return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state case 2: - d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f); + d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f); //printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k); - goto poll_detect; + return s68k_poll_detect(a, d); case 6: return CDC_Read_Reg(); case 8: @@ -240,30 +268,9 @@ u32 s68k_reg_read16(u32 a) d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1]; - if (a >= 0x0e && a < 0x30) goto poll_detect; - - return d; - -poll_detect: -#ifdef USE_POLL_DETECT - // polling detection - if (a == (s68k_poll_adclk&0xfe)) { - unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8); - if (clkdiff <= POLL_CYCLES) { - s68k_poll_cnt++; - //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt); - if (s68k_poll_cnt > POLL_LIMIT) { - SekSetStopS68k(1); - //printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, SekPcS68k, a); - } - s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; - return d; - } - } - s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; - s68k_poll_cnt = 0; + if (a >= 0x0e && a < 0x30) + return s68k_poll_detect(a, d); -#endif return d; } @@ -407,6 +414,7 @@ static void OtherWrite8End(u32 a, u32 d, int realsize) #include "cell_map.c" #endif // !def _ASM_CD_MEMORY_C + // ----------------------------------------------------------------- // Read Rom and read Ram @@ -631,8 +639,11 @@ static void PicoWriteM68k8(u32 a,u8 d) return; } - if ((a&0xffffc0)==0xa12000) + if ((a&0xffffc0)==0xa12000) { rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc); + m68k_reg_write8(a, d); + return; + } OtherWrite8(a,d,8); } @@ -688,7 +699,7 @@ static void PicoWriteM68k16(u32 a,u16 d) #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = -1; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -755,8 +766,10 @@ static void PicoWriteM68k32(u32 a,u32 d) return; } - if ((a&0xffffc0)==0xa12000) + if ((a&0xffffc0)==0xa12000) { rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc); + if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f); + } OtherWrite16(a, (u16)(d>>16)); OtherWrite16(a+2,(u16)d); @@ -785,7 +798,13 @@ static u8 PicoReadS68k8(u32 a) if ((a&0xfffe00) == 0xff8000) { a &= 0x1ff; rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k); - if (a >= 0x58 && a < 0x68) + if (a >= 0x0e && a < 0x30) { + d = Pico_mcd->s68k_regs[a]; + s68k_poll_detect(a, d); + rdprintf("ret = %02x", (u8)d); + goto end; + } + else if (a >= 0x58 && a < 0x68) d = gfx_cd_read(a&~1); else d = s68k_reg_read16(a&~1); if ((a&1)==0) d>>=8; @@ -1008,7 +1027,7 @@ static u32 PicoReadS68k32(u32 a) // PCM if ((a&0xff8000)==0xff0000) { - dprintf("FIXME: s68k_pcm r32: [%06x] @%06x", a, SekPcS68k); + dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k); a &= 0x7fff; if (a >= 0x2000) { a >>= 1; @@ -1293,6 +1312,7 @@ static void PicoWriteS68k32(u32 a,u32 d) gfx_cd_write16(a, d>>16); gfx_cd_write16(a+2, d&0xffff); } else { + if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f); s68k_reg_write8(a, d>>24); s68k_reg_write8(a+1,(d>>16)&0xff); s68k_reg_write8(a+2,(d>>8) &0xff); diff --git a/Pico/cd/Memory.s b/Pico/cd/Memory.s index d10f1a5..3328667 100644 --- a/Pico/cd/Memory.s +++ b/Pico/cd/Memory.s @@ -135,6 +135,8 @@ m_s68k_decode_write_table: .extern s68k_reg_write8 .extern s68k_poll_adclk .extern PicoCpuS68k +.extern s68k_poll_detect +.extern SN76496Write @ r0=reg3, r1-r3=temp @@ -993,6 +995,10 @@ m_m68k_write8_vdp: tst r0, #0x70000 tsteq r0, #0x000e0 bxne lr @ invalid + and r2, r0, #0x19 + cmp r2, #0x11 + andeq r0, r1, #0xff + beq SN76496Write and r1, r1, #0xff orr r1, r1, r1, lsl #8 @ byte access gets mirrored b PicoVideoWrite @@ -1123,7 +1129,11 @@ m_m68k_write16_vdp: tsteq r0, #0x000e0 bxne lr @ invalid bic r0, r0, #1 - b PicoVideoWrite + and r2, r0, #0x18 + cmp r2, #0x10 + bne PicoVideoWrite + and r0, r1, #0xff + b SN76496Write @ lsb goes to 0x11 m_m68k_write16_ram: @@ -1291,6 +1301,10 @@ m_m68k_write32_vdp: tst r0, #0x70000 tsteq r0, #0x000e0 bxne lr @ invalid + and r2, r0, #0x18 + cmp r2, #0x10 + moveq r0, r1, lsr #16 + beq SN76496Write @ which game is crazy enough to do that? stmfd sp!,{r0,r1,lr} mov r1, r1, lsr #16 bl PicoVideoWrite @@ -1410,6 +1424,9 @@ m_s68k_read8_regs: tst r0, #0x7e00 movne r0, #0 bxne lr + sub r2, r0, #0x0e + cmp r2, #(0x30-0x0e) + blo m_s68k_read8_comm sub r2, r0, #0x58 cmp r2, #0x10 ldrlo r2, =gfx_cd_read @@ -1424,6 +1441,13 @@ m_s68k_read8_regs: and r0, r0, #0xff bx lr +m_s68k_read8_comm: + ldr r1, =(Pico+0x22200) + ldr r1, [r1] + add r1, r1, #0x110000 + ldrb r1, [r1, r0] + b s68k_poll_detect + @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/Pico/sound/ym2612.c b/Pico/sound/ym2612.c index 3c3b17e..754f496 100644 --- a/Pico/sound/ym2612.c +++ b/Pico/sound/ym2612.c @@ -1702,7 +1702,9 @@ int YM2612Write_(unsigned int a, unsigned int v) } addr = ym2612.OPN.ST.address; +#ifndef EXTERNAL_YM2612 ym2612.REGS[addr] = v; +#endif switch( addr & 0xf0 ) { @@ -1800,7 +1802,9 @@ int YM2612Write_(unsigned int a, unsigned int v) } addr = ym2612.OPN.ST.address | 0x100; +#ifndef EXTERNAL_YM2612 ym2612.REGS[addr] = v; +#endif ret = OPNWriteReg(addr, v); break; @@ -1869,7 +1873,10 @@ void YM2612PicoStateLoad_(void) } +#ifndef EXTERNAL_YM2612 void *YM2612GetRegs(void) { return ym2612.REGS; } +#endif + diff --git a/platform/gp2x/940ctl.c b/platform/gp2x/940ctl.c index bcbb09b..f2e98a9 100644 --- a/platform/gp2x/940ctl.c +++ b/platform/gp2x/940ctl.c @@ -66,8 +66,10 @@ static int writebuff_ptr = 0; /* OPN Mode Register Write */ -static void set_timers( int v ) +static int set_timers( int v ) { + int change; + /* b7 = CSM MODE */ /* b6 = 3 slot mode */ /* b5 = reset b */ @@ -76,6 +78,7 @@ static void set_timers( int v ) /* b2 = timer enable a */ /* b1 = load b */ /* b0 = load a */ + change = (ST_mode ^ v) & 0xc0; ST_mode = v; /* reset Timer b flag */ @@ -85,6 +88,8 @@ static void set_timers( int v ) /* reset Timer a flag */ if( v & 0x10 ) ST_status &= ~1; + + return change; } /* YM2612 write */ @@ -93,11 +98,14 @@ static void set_timers( int v ) /* returns 1 if sample affecting state changed */ int YM2612Write_940(unsigned int a, unsigned int v) { - int addr; //, ret=1; + int addr; + int upd = 1; /* the write affects sample generation */ v &= 0xff; /* adjust to 8 bit bus */ a &= 3; + //printf("%05i:%03i: ym w ([%i] %02x)\n", Pico.m.frame_count, Pico.m.scanline, a, v); + switch( a ) { case 0: /* address port 0 */ if (!addr_A1 && ST_address == v) @@ -108,7 +116,7 @@ int YM2612Write_940(unsigned int a, unsigned int v) (v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a)) return 0; addr_A1 = 0; - //ret=0; + upd = 0; break; case 1: /* data port 0 */ @@ -152,14 +160,16 @@ int YM2612Write_940(unsigned int a, unsigned int v) } return 0; case 0x27: /* mode, timer control */ - set_timers( v ); - break; // other side needs ST.mode for 3slot mode + if (set_timers( v )) + break; // other side needs ST.mode for 3slot mode + return 0; case 0x2a: /* DAC data (YM2612) */ dacout = ((int)v - 0x80) << 6; /* level unknown (notaz: 8 seems to be too much) */ return 0; case 0x2b: /* DAC Sel (YM2612) */ /* b7 = dac enable */ dacen = v & 0x80; + upd = 0; break; // other side has to know this default: break; @@ -173,7 +183,7 @@ int YM2612Write_940(unsigned int a, unsigned int v) return 0; ST_address = v; addr_A1 = 1; - //ret=0; + upd = 0; break; case 3: /* data port 1 */ @@ -186,14 +196,25 @@ int YM2612Write_940(unsigned int a, unsigned int v) break; } + //printf("ym pass\n"); + if(currentConfig.EmuOpt & 4) { - /* queue this write for 940 */ - if (writebuff_ptr < 2047) { - if (shared_ctl->writebuffsel == 1) { - shared_ctl->writebuff0[writebuff_ptr++] = (a<<8)|v; - } else { - shared_ctl->writebuff1[writebuff_ptr++] = (a<<8)|v; + UINT16 *writebuff = shared_ctl->writebuffsel ? shared_ctl->writebuff0 : shared_ctl->writebuff1; + + /* detect rapid ym updates */ + if (upd && !(writebuff_ptr & 0x80000000) && Pico.m.scanline < 224) { + int mid = Pico.m.pal ? 68 : 93; + if (Pico.m.scanline > mid) { + //printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, Pico.m.scanline); + writebuff[writebuff_ptr++ & 0xffff] = 0xfffe; + writebuff_ptr |= 0x80000000; + //printf("%05i:%03i: ym w ([%02x] %02x, upd=%i)\n", Pico.m.frame_count, Pico.m.scanline, addr, v, upd); } + } + + /* queue this write for 940 */ + if ((writebuff_ptr&0xffff) < 2047) { + writebuff[writebuff_ptr++ & 0xffff] = (a<<8)|v; } else { printf("warning: writebuff_ptr > 2047 ([%i] %02x)\n", a, v); } @@ -301,7 +322,7 @@ void YM2612PicoStateLoad_940(void) addr_A1 = old_A1; - add_job_940(JOB940_PICOSTATELOAD); +// add_job_940(JOB940_PICOSTATELOAD); } @@ -465,9 +486,9 @@ int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty) else memset32(buffer, 0, length<writebuffsel == 1) { - shared_ctl->writebuff0[writebuff_ptr] = 0xffff; + shared_ctl->writebuff0[writebuff_ptr & 0xffff] = 0xffff; } else { - shared_ctl->writebuff1[writebuff_ptr] = 0xffff; + shared_ctl->writebuff1[writebuff_ptr & 0xffff] = 0xffff; } writebuff_ptr = 0; diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index b045c2d..07f9992 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -84,7 +84,8 @@ OBJS += mp3.o # CPU cores ifeq "$(use_musashi)" "1" DEFINC += -DEMU_M68K -OBJS += _build\m68kcpu.o _build\m68kopac.o _build\m68kopdm.o _build\m68kopnz.o _build\m68kops.o +OBJS += ../../cpu/musashi/m68kcpu.o ../../cpu/musashi/m68kopac.o ../../cpu/musashi/m68kopdm.o +OBJS += ../../cpu/musashi/m68kopnz.o ../../cpu/musashi/m68kops.o else DEFINC += -DEMU_C68K OBJS += ../../cpu/Cyclone/proj/Cyclone.o diff --git a/platform/gp2x/code940/940.c b/platform/gp2x/code940/940.c index c37c80e..4a1e718 100644 --- a/platform/gp2x/code940/940.c +++ b/platform/gp2x/code940/940.c @@ -55,6 +55,56 @@ static void mp3_decode(void) set_if_not_changed(&shared_ctl->mp3_offs, mp3_offs, readPtr - mp3_data); } +static void ym_update(int *ym_buffer) +{ + int i, dw; + int two_upds = 0; + UINT16 *wbuff; + + if (shared_ctl->writebuffsel == 1) { + wbuff = shared_ctl->writebuff1; + } else { + wbuff = shared_ctl->writebuff0; + } + + /* playback all writes */ + for (i = 2048/2; i > 0; i--) { + UINT16 d; + dw = *(int *)wbuff; + d = dw; + wbuff++; + if (d == 0xffff) break; + if (d == 0xfffe) { two_upds=1; break; } + YM2612Write_(d >> 8, d); + d = (dw>>16); + wbuff++; + if (d == 0xffff) break; + if (d == 0xfffe) { two_upds=1; break; } + YM2612Write_(d >> 8, d); + } + + if (two_upds) { + int len1 = shared_ctl->length / 2; + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1); + + for (i *= 2; i > 0; i--) { + UINT16 d = *wbuff++; + if (d == 0xffff) break; + YM2612Write_(d >> 8, d); + } + + ym_buffer += shared_ctl->stereo ? len1*2 : len1; + len1 = shared_ctl->length - len1; + + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1); + } else { + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1); + } +} + void Main940(void) { @@ -92,30 +142,9 @@ void Main940(void) YM2612PicoStateLoad_(); break; - case JOB940_YM2612UPDATEONE: { - int i, dw, *wbuff; - if (shared_ctl->writebuffsel == 1) { - wbuff = (int *) shared_ctl->writebuff1; - } else { - wbuff = (int *) shared_ctl->writebuff0; - } - - /* playback all writes */ - for (i = 2048/2; i > 0; i--) { - UINT16 d; - dw = *wbuff++; - d = dw; - if (d == 0xffff) break; - YM2612Write_(d >> 8, d); - d = (dw>>16); - if (d == 0xffff) break; - YM2612Write_(d >> 8, d); - } - - shared_ctl->ym_active_chs = - YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1); + case JOB940_YM2612UPDATEONE: + ym_update(ym_buffer); break; - } case JOB940_MP3DECODE: mp3_decode(); diff --git a/platform/gp2x/code940/Makefile b/platform/gp2x/code940/Makefile index 5858381..0af15b9 100644 --- a/platform/gp2x/code940/Makefile +++ b/platform/gp2x/code940/Makefile @@ -32,7 +32,7 @@ all: code940.bin # stuff for 940 core # init, emu_control, emu -OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o mix.o +OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o mix.o misc.o # the asm code seems to be faster when run on 920, but not on 940 for some reason # OBJS940 += ../../Pico/sound/ym2612_asm.o @@ -56,6 +56,9 @@ code940.gpe : $(OBJS940) ../helix/helix_mp3.a mix.o : ../../../Pico/sound/mix.s @echo $@ @$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@ +misc.o : ../../../Pico/misc.s + @echo $@ + @$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@ ../helix/helix_mp3.a: @make -C ../helix/ diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index f43f9b7..99357b2 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -63,21 +63,7 @@ unsigned char *framebuff = 0; // temporary buffer for alt renderer int state_slot = 0; int reset_timing = 0; -/* -// tmp -static FILE *logf = NULL; -void pprintf(char *texto, ...) -{ - va_list args; - - va_start(args,texto); - vfprintf(logf,texto,args); - va_end(args); - fflush(logf); - sync(); -} -*/ // utilities static void strlwr(char* string) { @@ -467,6 +453,18 @@ static void find_combos(void) } +void scaling_update(void) +{ + PicoOpt &= ~0x4100; + switch (currentConfig.scaling) { + default: break; // off + case 1: // hw hor + case 2: PicoOpt |= 0x0100; break; // hw hor+vert + case 3: PicoOpt |= 0x4000; break; // sw hor + } +} + + int emu_ReadConfig(int game) { FILE *f; @@ -501,6 +499,7 @@ int emu_ReadConfig(int game) currentConfig.KeyBinds[22] = 1<<30; // vol down currentConfig.gamma = 100; currentConfig.PicoCDBuffers = 64; + currentConfig.scaling = 0; strncpy(cfg, PicoConfigFile, 511); cfg[511] = 0; } else { @@ -516,7 +515,7 @@ int emu_ReadConfig(int game) bread = fread(¤tConfig, 1, sizeof(currentConfig), f); fclose(f); } - printf((bread == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n"); + printf(bread > 0 ? "(ok)\n" : "(failed)\n"); PicoOpt = currentConfig.PicoOpt; PsndRate = currentConfig.PsndRate; @@ -527,6 +526,7 @@ int emu_ReadConfig(int game) actionNames[ 8] = "Z"; actionNames[ 9] = "Y"; actionNames[10] = "X"; actionNames[11] = "MODE"; } + scaling_update(); // some sanity checks if (currentConfig.CPUclock < 1 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200; if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100; @@ -536,7 +536,7 @@ int emu_ReadConfig(int game) currentConfig.KeyBinds[22] = 1<<30; // vol down } - return (bread == sizeof(currentConfig)); + return (bread > 0); // == sizeof(currentConfig)); } @@ -565,7 +565,9 @@ int emu_WriteConfig(int game) bwrite = fwrite(¤tConfig, 1, sizeof(currentConfig), f); fflush(f); fclose(f); +#ifndef NO_SYNC sync(); +#endif } printf((bwrite == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n"); @@ -581,8 +583,23 @@ void emu_Deinit(void) SRam.changed = 0; } - if (!(currentConfig.EmuOpt & 0x20)) - emu_WriteConfig(0); + if (!(currentConfig.EmuOpt & 0x20)) { + FILE *f = fopen(PicoConfigFile, "r+b"); + if (!f) emu_WriteConfig(0); + else { + // if we already have config, reload it, except last ROM + fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET); + fread(¤tConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f); + fseek(f, 0, SEEK_SET); + fwrite(¤tConfig, 1, sizeof(currentConfig), f); + fflush(f); + fclose(f); +#ifndef NO_SYNC + sync(); +#endif + } + } + free(framebuff); PicoExit(); @@ -706,9 +723,13 @@ static void blit(const char *fps, const char *notice) } } - if (notice) osd_text(4, 232, notice); - if (emu_opt & 2) - osd_text(osd_fps_x, 232, fps); + if (notice || (emu_opt & 2)) { + int h = 232; + if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8)) h -= 8; + if (notice) osd_text(4, h, notice); + if (emu_opt & 2) + osd_text(osd_fps_x, h, fps); + } if ((emu_opt & 0x400) && (PicoMCD & 1)) cd_leds(); @@ -771,7 +792,9 @@ static void vidResetMode(void) } Pico.m.dirtyPal = 1; // reset scaling - gp2x_video_RGB_setscaling((PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240); + if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8)) + gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224); + else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240); } @@ -1133,7 +1156,9 @@ void emu_Loop(void) vidCpyM2 = vidCpyM2_32col; } } - gp2x_video_RGB_setscaling(scalex, 240); + if (currentConfig.scaling == 2 && !(modes&8)) // want vertical scaling and game is not in 240 line mode + gp2x_video_RGB_setscaling(8, scalex, 224); + else gp2x_video_RGB_setscaling(0, scalex, 240); oldmodes = modes; clearArea(1); } @@ -1171,7 +1196,7 @@ void emu_Loop(void) if (frames_shown > frames_done) frames_shown = frames_done; } } -#if 0 +#if 1 sprintf(fpsbuff, "%05i", Pico.m.frame_count); #endif lim_time = (frames_done+1) * target_frametime; @@ -1446,7 +1471,9 @@ int emu_SaveLoadGame(int load, int sram) ret = fwrite(sram_data, 1, sram_size, sramFile); ret = (ret != sram_size) ? -1 : 0; fclose(sramFile); +#ifndef NO_SYNC sync(); +#endif } } return ret; @@ -1470,8 +1497,10 @@ int emu_SaveLoadGame(int load, int sram) ret = PmovState(load ? 6 : 5, PmovFile); areaClose(PmovFile); PmovFile = 0; - if (!load) sync(); - else Pico.m.dirtyPal=1; + if (load) Pico.m.dirtyPal=1; +#ifndef NO_SYNC + else sync(); +#endif } else ret = -1; if (!ret) diff --git a/platform/gp2x/emu.h b/platform/gp2x/emu.h index f5dcee3..b487c51 100644 --- a/platform/gp2x/emu.h +++ b/platform/gp2x/emu.h @@ -18,7 +18,7 @@ enum TPicoGameState { typedef struct { char lastRomFile[512]; int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves, - // squidgehack, save_cfg_on_exit, , 16_bit_mode + // squidgehack, no_save_cfg_on_exit, , 16_bit_mode // craigix_ram, confirm_save, show_cd_leds // int PicoOpt; // used for config saving only, see Pico.h @@ -32,6 +32,7 @@ typedef struct { int JoyBinds[4][32]; int PicoAutoRgnOrder; int PicoCDBuffers; + int scaling; // 0=center, 1=hscale, 2=hvscale, 3=hsoftscale } currentConfig_t; extern char romFileName[]; @@ -52,4 +53,5 @@ int emu_check_save_file(int slot); void emu_set_save_cbs(int gz); void emu_forced_frame(void); int find_bios(int region, char **bios_file); +void scaling_update(void); diff --git a/platform/gp2x/gp2x.c b/platform/gp2x/gp2x.c index 28c0a93..f138be6 100644 --- a/platform/gp2x/gp2x.c +++ b/platform/gp2x/gp2x.c @@ -52,19 +52,21 @@ void *gp2x_screen; #define FRAMEBUFF_ADDR2 (FRAMEBUFF_ADDR1+0x30000) #define FRAMEBUFF_ADDR3 (FRAMEBUFF_ADDR2+0x30000) -static const int gp2x_screenaddrs[] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 }; +static const int gp2x_screenaddrs[4] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 }; +static int gp2x_screenaddrs_use[4]; static unsigned short gp2x_screenaddr_old[4]; /* video stuff */ void gp2x_video_flip(void) { - unsigned short msw = (unsigned short)(gp2x_screenaddrs[screensel&3] >> 16); + unsigned short lsw = (unsigned short) gp2x_screenaddrs_use[screensel&3]; + unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&3] >> 16); gp2x_memregs[0x2910>>1] = msw; gp2x_memregs[0x2914>>1] = msw; - gp2x_memregs[0x290E>>1] = 0; - gp2x_memregs[0x2912>>1] = 0; + gp2x_memregs[0x290E>>1] = lsw; + gp2x_memregs[0x2912>>1] = lsw; // jump to other buffer: gp2x_screen = gp2x_screens[++screensel&3]; @@ -73,7 +75,7 @@ void gp2x_video_flip(void) /* doulblebuffered flip */ void gp2x_video_flip2(void) { - unsigned short msw = (unsigned short)(gp2x_screenaddrs[screensel&1] >> 16); + unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&1] >> 16); gp2x_memregs[0x2910>>1] = msw; gp2x_memregs[0x2914>>1] = msw; @@ -113,10 +115,17 @@ void gp2x_video_setpalette(int *pal, int len) // TV Compatible function // -void gp2x_video_RGB_setscaling(int W, int H) +void gp2x_video_RGB_setscaling(int ln_offs, int W, int H) { float escalaw, escalah; int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3; + unsigned short scalw; + + // set offset + gp2x_screenaddrs_use[0] = gp2x_screenaddrs[0] + ln_offs * 320 * bpp; + gp2x_screenaddrs_use[1] = gp2x_screenaddrs[1] + ln_offs * 320 * bpp; + gp2x_screenaddrs_use[2] = gp2x_screenaddrs[2] + ln_offs * 320 * bpp; + gp2x_screenaddrs_use[3] = gp2x_screenaddrs[3] + ln_offs * 320 * bpp; escalaw = 1024.0; // RGB Horiz LCD escalah = 320.0; // RGB Vert LCD @@ -131,7 +140,10 @@ void gp2x_video_RGB_setscaling(int W, int H) } // scale horizontal - gp2x_memregs[0x2906>>1]=(unsigned short)((float)escalaw *(W/320.0)); + scalw = (unsigned short)((float)escalaw *(W/320.0)); + /* if there is no horizontal scaling, vertical doesn't work. Here is a nasty wrokaround... */ + if (H != 240 && W == 320) scalw--; + gp2x_memregs[0x2906>>1]=scalw; // scale vertical gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0)); } @@ -304,6 +316,7 @@ void gp2x_init(void) gp2x_screenaddr_old[2] = gp2x_memregs[0x2912>>1]; gp2x_screenaddr_old[3] = gp2x_memregs[0x2914>>1]; + memcpy(gp2x_screenaddrs_use, gp2x_screenaddrs, sizeof(gp2x_screenaddrs)); gp2x_memset_all_buffers(0, 0, 320*240*2); // snd diff --git a/platform/gp2x/gp2x.h b/platform/gp2x/gp2x.h index 9883b22..349b898 100644 --- a/platform/gp2x/gp2x.h +++ b/platform/gp2x/gp2x.h @@ -12,7 +12,7 @@ void gp2x_video_flip2(void); void gp2x_video_changemode(int bpp); void gp2x_video_changemode2(int bpp); void gp2x_video_setpalette(int *pal, int len); -void gp2x_video_RGB_setscaling(int W, int H); +void gp2x_video_RGB_setscaling(int ln_offs, int W, int H); void gp2x_video_wait_vsync(void); void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len); void gp2x_memcpy_all_buffers(void *data, int offset, int len); diff --git a/platform/gp2x/menu.c b/platform/gp2x/menu.c index d29d6d0..f9c8065 100644 --- a/platform/gp2x/menu.c +++ b/platform/gp2x/menu.c @@ -286,7 +286,10 @@ static int scandir_cmp(const void *p1, const void *p2) return alphasort(d1, d2); } -static char *filter_exts[] = { ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html", ".jpg", ".gpe" }; +static char *filter_exts[] = { + ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html", + ".jpg", ".gpe", ".cue" +}; static int scandir_filter(const struct dirent *ent) { @@ -864,16 +867,15 @@ static void draw_amenu_options(int menu_sel) //memset(gp2x_screen, 0, 320*240); gp2x_pd_clone_buffer2(); - gp2x_text_out8(tl_x, y, "Scale 32 column mode %s", (currentConfig.PicoOpt&0x100)?"ON":"OFF"); // 0 - gp2x_text_out8(tl_x, (y+=10), "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 1 - gp2x_text_out8(tl_x, (y+=10), "Emulate Z80 %s", (currentConfig.PicoOpt&0x004)?"ON":"OFF"); // 2 - gp2x_text_out8(tl_x, (y+=10), "Emulate YM2612 (FM) %s", (currentConfig.PicoOpt&0x001)?"ON":"OFF"); // 3 - gp2x_text_out8(tl_x, (y+=10), "Emulate SN76496 (PSG) %s", (currentConfig.PicoOpt&0x002)?"ON":"OFF"); // 4 - gp2x_text_out8(tl_x, (y+=10), "gzip savestates %s", (currentConfig.EmuOpt &0x008)?"ON":"OFF"); // 5 - gp2x_text_out8(tl_x, (y+=10), "Don't save config on exit %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 6 + gp2x_text_out8(tl_x, y, "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 0 + gp2x_text_out8(tl_x, (y+=10), "Emulate Z80 %s", (currentConfig.PicoOpt&0x004)?"ON":"OFF"); // 1 + gp2x_text_out8(tl_x, (y+=10), "Emulate YM2612 (FM) %s", (currentConfig.PicoOpt&0x001)?"ON":"OFF"); // 2 + gp2x_text_out8(tl_x, (y+=10), "Emulate SN76496 (PSG) %s", (currentConfig.PicoOpt&0x002)?"ON":"OFF"); // 3 + gp2x_text_out8(tl_x, (y+=10), "gzip savestates %s", (currentConfig.EmuOpt &0x008)?"ON":"OFF"); // 4 + gp2x_text_out8(tl_x, (y+=10), "Don't save config on exit %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 5 gp2x_text_out8(tl_x, (y+=10), "needs restart:"); - gp2x_text_out8(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 8 - gp2x_text_out8(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 9 + gp2x_text_out8(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 7 + gp2x_text_out8(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 8 gp2x_text_out8(tl_x, (y+=10), "Done"); // draw cursor @@ -884,7 +886,7 @@ static void draw_amenu_options(int menu_sel) static void amenu_loop_options(void) { - int menu_sel = 0, menu_sel_max = 10; + int menu_sel = 0, menu_sel_max = 9; unsigned long inp = 0; for(;;) @@ -895,21 +897,20 @@ static void amenu_loop_options(void) if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; } if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options switch (menu_sel) { - case 0: currentConfig.PicoOpt^=0x100; break; - case 2: currentConfig.PicoOpt^=0x004; break; - case 3: currentConfig.PicoOpt^=0x001; break; - case 4: currentConfig.PicoOpt^=0x002; break; - case 5: currentConfig.EmuOpt ^=0x008; break; - case 6: currentConfig.EmuOpt ^=0x020; break; - case 8: currentConfig.EmuOpt ^=0x100; break; - case 9: currentConfig.EmuOpt ^=0x010; break; - case 10: return; + case 1: currentConfig.PicoOpt^=0x004; break; + case 2: currentConfig.PicoOpt^=0x001; break; + case 3: currentConfig.PicoOpt^=0x002; break; + case 4: currentConfig.EmuOpt ^=0x008; break; + case 5: currentConfig.EmuOpt ^=0x020; break; + case 7: currentConfig.EmuOpt ^=0x100; break; + case 8: currentConfig.EmuOpt ^=0x010; break; + case 9: return; } } if(inp & (GP2X_X|GP2X_A)) return; if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise switch (menu_sel) { - case 1: + case 0: while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) { currentConfig.gamma += (inp & GP2X_LEFT) ? -1 : 1; if (currentConfig.gamma < 1) currentConfig.gamma = 1; @@ -949,8 +950,8 @@ static const char *region_name(unsigned int code) static void draw_menu_options(int menu_sel) { - int tl_x = 25, tl_y = 40, y; - char monostereo[8], strframeskip[8], *strrend; + int tl_x = 25, tl_y = 32, y; + char monostereo[8], strframeskip[8], *strrend, *strscaling; strcpy(monostereo, (currentConfig.PicoOpt&0x08)?"stereo":"mono"); if (currentConfig.Frameskip < 0) @@ -963,27 +964,34 @@ static void draw_menu_options(int menu_sel) } else { strrend = " 8bit accurate"; } + switch (currentConfig.scaling) { + default: strscaling = " OFF"; break; + case 1: strscaling = "hw horizontal"; break; + case 2: strscaling = "hw horiz. + vert."; break; + case 3: strscaling = "sw horizontal"; break; + } y = tl_y; //memset(gp2x_screen, 0, 320*240); gp2x_pd_clone_buffer2(); gp2x_text_out8(tl_x, y, "Renderer: %s", strrend); // 0 - gp2x_text_out8(tl_x, (y+=10), "Accurate timing (slower) %s", (currentConfig.PicoOpt&0x040)?"ON":"OFF"); // 1 - gp2x_text_out8(tl_x, (y+=10), "Accurate sprites (slower) %s", (currentConfig.PicoOpt&0x080)?"ON":"OFF"); // 2 - gp2x_text_out8(tl_x, (y+=10), "Show FPS %s", (currentConfig.EmuOpt &0x002)?"ON":"OFF"); // 3 + gp2x_text_out8(tl_x, (y+=10), "Scaling: %s", strscaling); // 1 + gp2x_text_out8(tl_x, (y+=10), "Accurate timing (slower) %s", (currentConfig.PicoOpt&0x040)?"ON":"OFF"); // 2 + gp2x_text_out8(tl_x, (y+=10), "Accurate sprites (slower) %s", (currentConfig.PicoOpt&0x080)?"ON":"OFF"); // 3 + gp2x_text_out8(tl_x, (y+=10), "Show FPS %s", (currentConfig.EmuOpt &0x002)?"ON":"OFF"); // 4 gp2x_text_out8(tl_x, (y+=10), "Frameskip %s", strframeskip); - gp2x_text_out8(tl_x, (y+=10), "Enable sound %s", (currentConfig.EmuOpt &0x004)?"ON":"OFF"); // 5 + gp2x_text_out8(tl_x, (y+=10), "Enable sound %s", (currentConfig.EmuOpt &0x004)?"ON":"OFF"); // 6 gp2x_text_out8(tl_x, (y+=10), "Sound Quality: %5iHz %s", currentConfig.PsndRate, monostereo); - gp2x_text_out8(tl_x, (y+=10), "Use ARM940 core for sound %s", (currentConfig.PicoOpt&0x200)?"ON":"OFF"); // 7 - gp2x_text_out8(tl_x, (y+=10), "6 button pad %s", (currentConfig.PicoOpt&0x020)?"ON":"OFF"); // 8 + gp2x_text_out8(tl_x, (y+=10), "Use ARM940 core for sound %s", (currentConfig.PicoOpt&0x200)?"ON":"OFF"); // 8 + gp2x_text_out8(tl_x, (y+=10), "6 button pad %s", (currentConfig.PicoOpt&0x020)?"ON":"OFF"); // 9 gp2x_text_out8(tl_x, (y+=10), "Genesis Region: %s", region_name(currentConfig.PicoRegion)); - gp2x_text_out8(tl_x, (y+=10), "Use SRAM/BRAM savestates %s", (currentConfig.EmuOpt &0x001)?"ON":"OFF"); // 10 - gp2x_text_out8(tl_x, (y+=10), "Confirm save overwrites %s", (currentConfig.EmuOpt &0x200)?"ON":"OFF"); // 11 - gp2x_text_out8(tl_x, (y+=10), "Save slot %i", state_slot); // 12 + gp2x_text_out8(tl_x, (y+=10), "Use SRAM/BRAM savestates %s", (currentConfig.EmuOpt &0x001)?"ON":"OFF"); // 11 + gp2x_text_out8(tl_x, (y+=10), "Confirm save overwrites %s", (currentConfig.EmuOpt &0x200)?"ON":"OFF"); // 12 + gp2x_text_out8(tl_x, (y+=10), "Save slot %i", state_slot); // 13 gp2x_text_out8(tl_x, (y+=10), "GP2X CPU clocks %iMhz", currentConfig.CPUclock); gp2x_text_out8(tl_x, (y+=10), "[Sega/Mega CD options]"); - gp2x_text_out8(tl_x, (y+=10), "[advanced options]"); // 15 + gp2x_text_out8(tl_x, (y+=10), "[advanced options]"); // 16 gp2x_text_out8(tl_x, (y+=10), "Save cfg as default"); if (rom_data) gp2x_text_out8(tl_x, (y+=10), "Save cfg for current game only"); @@ -1042,11 +1050,12 @@ static void menu_options_save(void) } else { actionNames[8] = actionNames[9] = actionNames[10] = actionNames[11] = 0; } + scaling_update(); } static int menu_loop_options(void) { - int menu_sel = 0, menu_sel_max = 16; + int menu_sel = 0, menu_sel_max = 17; unsigned long inp = 0; if (rom_data) menu_sel_max++; @@ -1062,25 +1071,25 @@ static int menu_loop_options(void) if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; } if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options switch (menu_sel) { - case 1: currentConfig.PicoOpt^=0x040; break; - case 2: currentConfig.PicoOpt^=0x080; break; - case 3: currentConfig.EmuOpt ^=0x002; break; - case 5: currentConfig.EmuOpt ^=0x004; break; - case 7: currentConfig.PicoOpt^=0x200; break; - case 8: currentConfig.PicoOpt^=0x020; break; - case 10: currentConfig.EmuOpt ^=0x001; break; - case 11: currentConfig.EmuOpt ^=0x200; break; - case 14: cd_menu_loop_options(); + case 2: currentConfig.PicoOpt^=0x040; break; + case 3: currentConfig.PicoOpt^=0x080; break; + case 4: currentConfig.EmuOpt ^=0x002; break; + case 6: currentConfig.EmuOpt ^=0x004; break; + case 8: currentConfig.PicoOpt^=0x200; break; + case 9: currentConfig.PicoOpt^=0x020; break; + case 11: currentConfig.EmuOpt ^=0x001; break; + case 12: currentConfig.EmuOpt ^=0x200; break; + case 15: cd_menu_loop_options(); if (engineState == PGS_ReloadRom) return 0; // test BIOS break; - case 15: amenu_loop_options(); break; - case 16: // done (update and write) + case 16: amenu_loop_options(); break; + case 17: // done (update and write) menu_options_save(); if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved"); else strcpy(menuErrorMsg, "failed to write config"); return 1; - case 17: // done (update and write for current game) + case 18: // done (update and write for current game) menu_options_save(); if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved"); else strcpy(menuErrorMsg, "failed to write config"); @@ -1104,28 +1113,33 @@ static int menu_loop_options(void) else if ( currentConfig.EmuOpt &0x80) currentConfig.EmuOpt &= ~0x80; } break; - case 4: + case 1: + currentConfig.scaling += (inp & GP2X_LEFT) ? -1 : 1; + if (currentConfig.scaling < 0) currentConfig.scaling = 0; + if (currentConfig.scaling > 3) currentConfig.scaling = 3; + break; + case 5: currentConfig.Frameskip += (inp & GP2X_LEFT) ? -1 : 1; if (currentConfig.Frameskip < 0) currentConfig.Frameskip = -1; if (currentConfig.Frameskip > 32) currentConfig.Frameskip = 32; break; - case 6: + case 7: if ((inp & GP2X_RIGHT) && currentConfig.PsndRate == 44100 && !(currentConfig.PicoOpt&0x08)) { currentConfig.PsndRate = 8000; currentConfig.PicoOpt|= 0x08; } else if ((inp & GP2X_LEFT) && currentConfig.PsndRate == 8000 && (currentConfig.PicoOpt&0x08)) { currentConfig.PsndRate = 44100; currentConfig.PicoOpt&=~0x08; } else currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & GP2X_RIGHT); break; - case 9: + case 10: region_prevnext(inp & GP2X_RIGHT); break; - case 12: + case 13: if (inp & GP2X_RIGHT) { state_slot++; if (state_slot > 9) state_slot = 0; } else {state_slot--; if (state_slot < 0) state_slot = 9; } break; - case 13: + case 14: while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) { currentConfig.CPUclock += (inp & GP2X_LEFT) ? -1 : 1; if (currentConfig.CPUclock < 1) currentConfig.CPUclock = 1; @@ -1222,7 +1236,11 @@ static void menu_loop_root(void) if (rom_data) menu_sel = menu_sel_min = 0; if (PicoPatches) menu_sel_max = 9; - for(;;) + /* make sure action buttons are not pressed on entering menu */ + draw_menu_root(menu_sel); + while (gp2x_joystick_read(1) & (GP2X_B|GP2X_X|GP2X_SELECT)) usleep(50*1000); + + for (;;) { draw_menu_root(menu_sel); inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X|GP2X_SELECT); @@ -1324,7 +1342,7 @@ static void menu_gfx_prepare(void) // switch to 8bpp gp2x_video_changemode2(8); - gp2x_video_RGB_setscaling(320, 240); + gp2x_video_RGB_setscaling(0, 320, 240); gp2x_video_flip2(); } diff --git a/platform/gp2x/version.h b/platform/gp2x/version.h index 1725e8d..cc93f89 100644 --- a/platform/gp2x/version.h +++ b/platform/gp2x/version.h @@ -1,2 +1,2 @@ -#define VERSION "1.31" +#define VERSION "1.32" diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 9a8f3df..a01a529 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -90,7 +90,7 @@ PicoDrive : $(OBJS) ../gp2x/helix/helix_mp3_x86.a ../../Pico/sound/ym2612.o : ../../Pico/sound/ym2612.c @echo $@ - @$(GCC) $(COPT_COMMON) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@ # -mtune=arm940t + @$(GCC) $(COPT_COMMON) $(DEFINC) -c $< -o $@ # -mtune=arm940t -DEXTERNAL_YM2612 # faked asm ../../Pico/Draw.o : ../../Pico/Draw.c diff --git a/platform/linux/gp2x.c b/platform/linux/gp2x.c index cc4db98..40cd7bc9 100644 --- a/platform/linux/gp2x.c +++ b/platform/linux/gp2x.c @@ -257,7 +257,7 @@ void gp2x_video_setpalette(int *pal, int len) memcpy(current_pal, pal, len*4); } -void gp2x_video_RGB_setscaling(int W, int H) +void gp2x_video_RGB_setscaling(int v_offs, int W, int H) { } diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index 42be264..765c0cd 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -4,7 +4,7 @@ #define PORT_CONFIG_H #define CPU_CALL -#define NO_IONBF +#define NO_SYNC // draw2.c #define START_ROW 0 // which row of tiles to start rendering at? diff --git a/platform/readme.txt b/platform/readme.txt index c658bdd..9436491 100644 --- a/platform/readme.txt +++ b/platform/readme.txt @@ -214,6 +214,15 @@ Symbian: Changelog --------- +1.32 + + Added some new scaling options. + * Fixed DMA timing emulation (caused lock-ups for some genesis games). + * Idle loop detection was picking up wrong code and causing glitches, fixed. + * The ym2612 code on 940 now can handle multiple updates per frame + (fixes Thunger Force III "seiren" level drums for example). + * Memory handlers were ignoring some writes to PSG chip, fixed (missing sounds in + Popful Mail, Silpheed). + 1.31 * Changed the way memory mode register is read (fixes Lunar 2, broken in 1.30). * Fixed TAS opcode on sub-68k side (fixes Batman games).