From 09c02fd693216ee6a4aabd4fe2f019396b0730ec Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Sun, 15 Jan 2012 19:59:13 +0000 Subject: [PATCH] fixed C89 remaining incompatibilities + various code cleanup --- source/cart_hw/areplay.c | 34 +-- source/cart_hw/gg_eeprom.h | 2 +- source/cart_hw/ggenie.c | 35 ++- source/cart_hw/md_eeprom.c | 4 +- source/cart_hw/md_eeprom.h | 2 +- source/cart_hw/svp/ssp16.c | 465 +++++++++++++++++------------------ source/cart_hw/svp/ssp16.h | 38 ++- source/cart_hw/svp/svp.c | 1 - source/cart_hw/svp/svp.h | 3 +- source/genesis.c | 2 +- source/genesis.h | 2 +- source/gx/fileio/fileio.h | 1 - source/input_hw/activator.c | 11 +- source/input_hw/gamepad.c | 4 +- source/input_hw/lightgun.c | 2 +- source/input_hw/paddle.c | 4 +- source/input_hw/sportspad.c | 4 +- source/input_hw/teamplayer.c | 4 +- source/input_hw/xe_a1p.c | 8 +- source/m68k/m68k.h | 2 +- source/mem68k.c | 26 +- source/membnk.c | 2 +- source/memz80.c | 22 +- source/sound/Fir_Resampler.c | 27 +- source/sound/blip.c | 36 +-- source/sound/blip.h | 6 +- source/sound/eq.c | 61 ++--- source/sound/eq.h | 42 ++-- source/sound/sn76489.c | 18 +- source/sound/ym2413.c | 67 +++-- source/sound/ym2612.c | 40 +-- source/types.h | 8 + source/vdp_ctrl.c | 270 +++++++++++--------- source/vdp_ctrl.h | 3 +- source/vdp_render.c | 286 +++++++++++---------- 35 files changed, 780 insertions(+), 762 deletions(-) diff --git a/source/cart_hw/areplay.c b/source/cart_hw/areplay.c index 1b3e8b1..c39ab4b 100644 --- a/source/cart_hw/areplay.c +++ b/source/cart_hw/areplay.c @@ -59,20 +59,23 @@ static void ar_write_ram_8(uint32 address, uint32 data); void areplay_init(void) { + int size; + FILE *f; + memset(&action_replay,0,sizeof(action_replay)); - if (cart.romsize > 0x800000) return; + + /* store Action replay ROM (max. 128k) & RAM (64k) above cartridge ROM + SRAM area */ + if (cart.romsize > 0x600000) return; + action_replay.rom = cart.rom + 0x600000; + action_replay.ram = cart.rom + 0x620000; /* Open Action Replay ROM */ - FILE *f = fopen(AR_ROM,"rb"); - if (!f) return; - - /* store Action replay ROM + RAM above cartridge ROM + SRAM */ - action_replay.rom = cart.rom + 0x800000; - action_replay.ram = cart.rom + 0x810000; + f = fopen(AR_ROM,"rb"); + if (f == NULL) return; /* ROM size */ fseek(f, 0, SEEK_END); - int size = ftell(f); + size = ftell(f); fseek(f, 0, SEEK_SET); /* detect Action Replay board type */ @@ -85,7 +88,6 @@ void areplay_init(void) /* internal registers mapped at $010000-$01ffff */ m68k_memory_map[0x01].write16 = ar_write_regs; - break; } @@ -124,7 +126,6 @@ void areplay_init(void) m68k_memory_map[sp[1]].write8 = ar_write_ram_8; m68k_memory_map[sp[1]].write16 = NULL; } - break; } @@ -138,24 +139,23 @@ void areplay_init(void) { /* Load ROM */ int i = 0; - while (i < size) + for (i=0; i 0x600000) - { - fclose(f); - return; - } - + /* Store Game Genie ROM (32k) above cartridge ROM + SRAM area */ + if (cart.romsize > 0x600000) return; ggenie.rom = cart.rom + 0x600000; + /* Open Game Genie ROM file */ + f = fopen(GG_ROM,"rb"); + if (f == NULL) return; + /* Load ROM */ - int i = 0; - while (i < 0x8000) + for (i=0; i<0x8000; i+=0x1000) { - fread(ggenie.rom+i,0x1000,1,f); - i += 0x1000; + fread(ggenie.rom + i, 0x1000, 1, f); } /* Close ROM file */ fclose(f); #ifdef LSB_FIRST - /* Byteswap ROM */ - uint8 temp; - for(i = 0; i < 0x8000; i += 2) + for (i=0; i<0x8000; i+=2) { - temp = ggenie.rom[i]; + /* Byteswap ROM */ + uint8 temp = ggenie.rom[i]; ggenie.rom[i] = ggenie.rom[i+1]; ggenie.rom[i+1] = temp; } #endif /* $0000-$7fff mirrored into $8000-$ffff */ - memcpy(ggenie.rom+0x8000,ggenie.rom,0x8000); + memcpy(ggenie.rom + 0x8000, ggenie.rom, 0x8000); /* set flag */ ggenie.enabled = 1; diff --git a/source/cart_hw/md_eeprom.c b/source/cart_hw/md_eeprom.c index d799dfc..33099a1 100644 --- a/source/cart_hw/md_eeprom.c +++ b/source/cart_hw/md_eeprom.c @@ -230,7 +230,7 @@ void md_eeprom_write_word(unsigned int address, unsigned int data) } -static inline void Detect_START() +static __inline__ void Detect_START() { if (md_eeprom.old_scl && md_eeprom.scl) { @@ -248,7 +248,7 @@ static inline void Detect_START() } } -static inline void Detect_STOP() +static __inline__ void Detect_STOP() { if (md_eeprom.old_scl && md_eeprom.scl) { diff --git a/source/cart_hw/md_eeprom.h b/source/cart_hw/md_eeprom.h index e1c489e..a0cd997 100644 --- a/source/cart_hw/md_eeprom.h +++ b/source/cart_hw/md_eeprom.h @@ -48,7 +48,7 @@ typedef enum GET_WORD_ADR_HIGH, GET_WORD_ADR_LOW, WRITE_DATA, - READ_DATA, + READ_DATA } T_EEPROM_STATE; diff --git a/source/cart_hw/svp/ssp16.c b/source/cart_hw/svp/ssp16.c index 6ab1d37..f2f648c 100644 --- a/source/cart_hw/svp/ssp16.c +++ b/source/cart_hw/svp/ssp16.c @@ -194,27 +194,27 @@ #define u32 unsigned int -//#define USE_DEBUGGER +/*#define USE_DEBUGGER*/ -// 0 -#define rX ssp->gr[SSP_X].h -#define rY ssp->gr[SSP_Y].h -#define rA ssp->gr[SSP_A].h -#define rST ssp->gr[SSP_ST].h // 4 -#define rSTACK ssp->gr[SSP_STACK].h -#define rPC ssp->gr[SSP_PC].h +/* 0 */ +#define rX ssp->gr[SSP_X].byte.h +#define rY ssp->gr[SSP_Y].byte.h +#define rA ssp->gr[SSP_A].byte.h +#define rST ssp->gr[SSP_ST].byte.h /* 4 */ +#define rSTACK ssp->gr[SSP_STACK].byte.h +#define rPC ssp->gr[SSP_PC].byte.h #define rP ssp->gr[SSP_P] -#define rPM0 ssp->gr[SSP_PM0].h // 8 -#define rPM1 ssp->gr[SSP_PM1].h -#define rPM2 ssp->gr[SSP_PM2].h -#define rXST ssp->gr[SSP_XST].h -#define rPM4 ssp->gr[SSP_PM4].h // 12 -// 13 -#define rPMC ssp->gr[SSP_PMC] // will keep addr in .h, mode in .l -#define rAL ssp->gr[SSP_A].l +#define rPM0 ssp->gr[SSP_PM0].byte.h /* 8 */ +#define rPM1 ssp->gr[SSP_PM1].byte.h +#define rPM2 ssp->gr[SSP_PM2].byte.h +#define rXST ssp->gr[SSP_XST].byte.h +#define rPM4 ssp->gr[SSP_PM4].byte.h /* 12 */ +/* 13 */ +#define rPMC ssp->gr[SSP_PMC] /* will keep addr in .h, mode in .l */ +#define rAL ssp->gr[SSP_A].byte.l #define rA32 ssp->gr[SSP_A].v -#define rIJ ssp->r +#define rIJ ssp->ptr.r #define IJind (((op>>6)&4)|(op&3)) @@ -222,45 +222,45 @@ #define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2) #define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d -#define REG_READ(r) (((r) <= 4) ? ssp->gr[r].h : read_handlers[r]()) +#define REG_READ(r) (((r) <= 4) ? ssp->gr[r].byte.h : read_handlers[r]()) #define REG_WRITE(r,d) { \ int r1 = r; \ if (r1 >= 4) write_handlers[r1](d); \ - else if (r1 > 0) ssp->gr[r1].h = d; \ + else if (r1 > 0) ssp->gr[r1].byte.h = d; \ } -// flags +/* flags */ #define SSP_FLAG_L (1<<0xc) #define SSP_FLAG_Z (1<<0xd) #define SSP_FLAG_V (1<<0xe) #define SSP_FLAG_N (1<<0xf) -// update ZN according to 32bit ACC. +/* update ZN according to 32bit ACC. */ #define UPD_ACC_ZN \ rST &= ~(SSP_FLAG_Z|SSP_FLAG_N); \ if (!rA32) rST |= SSP_FLAG_Z; \ else rST |= (rA32>>16)&SSP_FLAG_N; -// it seems SVP code never checks for L and OV, so we leave them out. -// rST |= (t>>4)&SSP_FLAG_L; +/* it seems SVP code never checks for L and OV, so we leave them out. */ +/* rST |= (t>>4)&SSP_FLAG_L; */ #define UPD_LZVN \ rST &= ~(SSP_FLAG_L|SSP_FLAG_Z|SSP_FLAG_V|SSP_FLAG_N); \ if (!rA32) rST |= SSP_FLAG_Z; \ else rST |= (rA32>>16)&SSP_FLAG_N; -// standard cond processing. -// again, only Z and N is checked, as SVP doesn't seem to use any other conds. +/* standard cond processing. */ +/* again, only Z and N is checked, as SVP doesn't seem to use any other conds. */ #define COND_CHECK \ switch (op&0xf0) { \ case 0x00: cond = 1; break; /* always true */ \ case 0x50: cond = !((rST ^ (op<<5)) & SSP_FLAG_Z); break; /* Z matches f(?) bit */ \ case 0x70: cond = !((rST ^ (op<<7)) & SSP_FLAG_N); break; /* N matches f(?) bit */ \ - default:elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unimplemented cond @ %04x", GET_PPC_OFFS()); break; \ + default: break; \ } -// ops with accumulator. -// how is low word really affected by these? -// nearly sure 'ld A' doesn't affect flags +/* ops with accumulator. */ +/* how is low word really affected by these? */ +/* nearly sure 'ld A' doesn't affect flags */ #define OP_LDA(x) \ rA = x @@ -348,10 +348,10 @@ static int running = 0; static int last_iram = 0; #endif -// ----------------------------------------------------- -// register i/o handlers +/* ----------------------------------------------------- */ +/* register i/o handlers */ -// 0-4, 13 +/* 0-4, 13 */ static u32 read_unknown(void) { #ifdef LOG_SVP @@ -367,17 +367,17 @@ static void write_unknown(u32 d) #endif } -// 4 +/* 4 */ static void write_ST(u32 d) { - //if ((rST ^ d) & 0x0007) elprintf(EL_SVP, "ssp RPL %i -> %i @ %04x", rST&7, d&7, GET_PPC_OFFS()); + /* if ((rST ^ d) & 0x0007) elprintf(EL_SVP, "ssp RPL %i -> %i @ %04x", rST&7, d&7, GET_PPC_OFFS()); */ #ifdef LOG_SVP if ((rST ^ d) & 0x0f98) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME ST %04x -> %04x @ %04x", rST, d, GET_PPC_OFFS()); #endif rST = d; } -// 5 +/* 5 */ static u32 read_STACK(void) { --rSTACK; @@ -401,10 +401,10 @@ static void write_STACK(u32 d) ssp->stack[rSTACK++] = d; } -// 6 +/* 6 */ static u32 read_PC(void) { - //g_cycles--; + /* g_cycles--; */ return GET_PC(); } @@ -414,25 +414,25 @@ static void write_PC(u32 d) g_cycles--; } -// 7 +/* 7 */ static u32 read_P(void) { int m1 = (signed short)rX; int m2 = (signed short)rY; rP.v = (m1 * m2 * 2); - return rP.h; + return rP.byte.h; } -// ----------------------------------------------------- +/* ----------------------------------------------------- */ static int get_inc(int mode) { int inc = (mode >> 11) & 7; if (inc != 0) { if (inc != 7) inc--; - //inc = (1<<16) << inc; // 0 1 2 4 8 16 32 128 - inc = 1 << inc; // 0 1 2 4 8 16 32 128 - if (mode & 0x8000) inc = -inc; // decrement mode + /* inc = (1<<16) << inc; */ + inc = 1 << inc; /* 0 1 2 4 8 16 32 128 */ + if (mode & 0x8000) inc = -inc; /* decrement mode */ } return inc; } @@ -449,7 +449,7 @@ static u32 pm_io(int reg, int write, u32 d) { if (ssp->emu_status & SSP_PMC_SET) { - // this MUST be blind r or w + /* this MUST be blind r or w */ if ((*(PC-1) & 0xff0f) && (*(PC-1) & 0xfff0)) { #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: tried to set PM%i (%c) with non-blind i/o %08x @ %04x", @@ -461,22 +461,20 @@ static u32 pm_io(int reg, int write, u32 d) #ifdef LOG_SVP elprintf(EL_SVP, "PM%i (%c) set to %08x @ %04x", reg, write ? 'w' : 'r', rPMC.v, GET_PPC_OFFS()); #endif - - unsigned int *pmac = &ssp->pmac_read[reg]; - pmac[6*write] = rPMC.v; + ssp->pmac[write][reg] = rPMC.v; ssp->emu_status &= ~SSP_PMC_SET; #ifdef LOG_SVP if ((rPMC.v & 0x7f) == 0x1c && (rPMC.v & 0x7fff0000) == 0) { - elprintf(EL_SVP, "ssp IRAM copy from %06x", (ssp->RAM1[0]-1)<<1); + elprintf(EL_SVP, "ssp IRAM copy from %06x", (ssp->mem.bank.RAM1[0]-1)<<1); #ifdef USE_DEBUGGER - last_iram = (ssp->RAM1[0]-1)<<1; + last_iram = (ssp->mem.bank.RAM1[0]-1)<<1; #endif } #endif return 0; } - // just in case + /* just in case */ if (ssp->emu_status & SSP_PMC_HAVE_ADDR) { #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: PM%i (%c) with only addr set @ %04x", @@ -495,13 +493,13 @@ static u32 pm_io(int reg, int write, u32 d) { /*int mode = ssp->pmac_write[reg]&0xffff; int addr = ssp->pmac_write[reg]>>16;*/ - int addr = ssp->pmac_write[reg]&0xffff; - int mode = ssp->pmac_write[reg]>>16; + int addr = ssp->pmac[1][reg]&0xffff; + int mode = ssp->pmac[1][reg]>>16; #ifdef LOG_SVP if ((mode & 0xb800) == 0xb800) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: mode %04x", mode); #endif - if ((mode & 0x43ff) == 0x0018) // DRAM + if ((mode & 0x43ff) == 0x0018) /* DRAM */ { int inc = get_inc(mode); #ifdef LOG_SVP @@ -511,9 +509,9 @@ static u32 pm_io(int reg, int write, u32 d) if (mode & 0x0400) { overwite_write(dram[addr], d); } else dram[addr] = d; - ssp->pmac_write[reg] += inc; + ssp->pmac[1][reg] += inc; } - else if ((mode & 0xfbff) == 0x4018) // DRAM, cell inc + else if ((mode & 0xfbff) == 0x4018) /* DRAM, cell inc */ { #ifdef LOG_SVP elprintf(EL_SVP, "ssp PM%i DRAM w [%06x] %04x (cell inc, ovrw %i) @ %04x", @@ -522,10 +520,10 @@ static u32 pm_io(int reg, int write, u32 d) if (mode & 0x0400) { overwite_write(dram[addr], d); } else dram[addr] = d; - //ssp->pmac_write[reg] += (addr&1) ? (31<<16) : (1<<16); - ssp->pmac_write[reg] += (addr&1) ? 31 : 1; + /* ssp->pmac_write[reg] += (addr&1) ? (31<<16) : (1<<16); */ + ssp->pmac[1][reg] += (addr&1) ? 31 : 1; } - else if ((mode & 0x47ff) == 0x001c) // IRAM + else if ((mode & 0x47ff) == 0x001c) /* IRAM */ { int inc = get_inc(mode); #ifdef LOG_SVP @@ -534,7 +532,7 @@ static u32 pm_io(int reg, int write, u32 d) elprintf(EL_SVP, "ssp IRAM w [%06x] %04x (inc %i)", (addr<<1)&0x7ff, d, inc >> 16); #endif ((unsigned short *)svp->iram_rom)[addr&0x3ff] = d; - ssp->pmac_write[reg] += inc; + ssp->pmac[1][reg] += inc; } #ifdef LOG_SVP else @@ -548,10 +546,10 @@ static u32 pm_io(int reg, int write, u32 d) { /*int mode = ssp->pmac_read[reg]&0xffff; int addr = ssp->pmac_read[reg]>>16;*/ - int addr = ssp->pmac_read[reg]&0xffff; - int mode = ssp->pmac_read[reg]>>16; + int addr = ssp->pmac[0][reg]&0xffff; + int mode = ssp->pmac[0][reg]>>16; - if ((mode & 0xfff0) == 0x0800) // ROM, inc 1, verified to be correct + if ((mode & 0xfff0) == 0x0800) /* ROM, inc 1, verified to be correct */ { #ifdef LOG_SVP elprintf(EL_SVP, "ssp ROM r [%06x] %04x", CADDR, @@ -559,19 +557,19 @@ static u32 pm_io(int reg, int write, u32 d) #endif /*if ((signed int)ssp->pmac_read[reg] >> 16 == -1) ssp->pmac_read[reg]++; ssp->pmac_read[reg] += 1<<16;*/ - if ((signed int)(ssp->pmac_read[reg] & 0xffff) == -1) ssp->pmac_read[reg] += 1<<16; - ssp->pmac_read[reg] ++; + if ((signed int)(ssp->pmac[0][reg] & 0xffff) == -1) ssp->pmac[0][reg] += 1<<16; + ssp->pmac[0][reg] ++; d = ((unsigned short *)cart.rom)[addr|((mode&0xf)<<16)]; } - else if ((mode & 0x47ff) == 0x0018) // DRAM + else if ((mode & 0x47ff) == 0x0018) /* DRAM */ { int inc = get_inc(mode); #ifdef LOG_SVP elprintf(EL_SVP, "ssp PM%i DRAM r [%06x] %04x (inc %i)", reg, CADDR, dram[addr], inc >> 16); #endif d = dram[addr]; - ssp->pmac_read[reg] += inc; + ssp->pmac[0][reg] += inc; } else { @@ -583,9 +581,8 @@ static u32 pm_io(int reg, int write, u32 d) } } - // PMC value corresponds to last PMR accessed (not sure). - unsigned int *pmac = &ssp->pmac_read[reg]; - rPMC.v = pmac[6*write]; + /* PMC value corresponds to last PMR accessed (not sure). */ + rPMC.v = ssp->pmac[write][reg]; return d; } @@ -593,7 +590,7 @@ static u32 pm_io(int reg, int write, u32 d) return (u32)-1; } -// 8 +/* 8 */ static u32 read_PM0(void) { u32 d = pm_io(0, 0, 0); @@ -608,7 +605,7 @@ static u32 read_PM0(void) elprintf(EL_SVP, "det TIGHT loop: PM0"); #endif } - rPM0 &= ~2; // ? + rPM0 &= ~2; /* ? */ return d; } @@ -622,12 +619,12 @@ static void write_PM0(u32 d) rPM0 = d; } -// 9 +/* 9 */ static u32 read_PM1(void) { u32 d = pm_io(1, 0, 0); if (d != (u32)-1) return d; - // can be removed? + /* can be removed? */ #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "PM1 raw r %04x @ %04x", rPM1, GET_PPC_OFFS()); #endif @@ -638,19 +635,19 @@ static void write_PM1(u32 d) { u32 r = pm_io(1, 1, d); if (r != (u32)-1) return; - // can be removed? + /* can be removed? */ #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "PM1 raw w %04x @ %04x", d, GET_PPC_OFFS()); #endif rPM1 = d; } -// 10 +/* 10 */ static u32 read_PM2(void) { u32 d = pm_io(2, 0, 0); if (d != (u32)-1) return d; - // can be removed? + /* can be removed? */ #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "PM2 raw r %04x @ %04x", rPM2, GET_PPC_OFFS()); #endif @@ -661,17 +658,17 @@ static void write_PM2(u32 d) { u32 r = pm_io(2, 1, d); if (r != (u32)-1) return; - // can be removed? + /* can be removed? */ #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "PM2 raw w %04x @ %04x", d, GET_PPC_OFFS()); #endif rPM2 = d; } -// 11 +/* 11 */ static u32 read_XST(void) { - // can be removed? + /* can be removed? */ u32 d = pm_io(3, 0, 0); if (d != (u32)-1) return d; #ifdef LOG_SVP @@ -682,7 +679,7 @@ static u32 read_XST(void) static void write_XST(u32 d) { - // can be removed? + /* can be removed? */ u32 r = pm_io(3, 1, d); if (r != (u32)-1) return; #ifdef LOG_SVP @@ -692,7 +689,7 @@ static void write_XST(u32 d) rXST = d; } -// 12 +/* 12 */ static u32 read_PM4(void) { u32 d = pm_io(4, 0, 0); @@ -713,7 +710,7 @@ static u32 read_PM4(void) } } if (d != (u32)-1) return d; - // can be removed? + /* can be removed? */ #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); #endif @@ -724,64 +721,64 @@ static void write_PM4(u32 d) { u32 r = pm_io(4, 1, d); if (r != (u32)-1) return; - // can be removed? + /* can be removed? */ #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "PM4 raw w %04x @ %04x", d, GET_PPC_OFFS()); #endif rPM4 = d; } -// 14 +/* 14 */ static u32 read_PMC(void) { #ifdef LOG_SVP - elprintf(EL_SVP, "PMC r a %04x (st %c) @ %04x", rPMC.h, + elprintf(EL_SVP, "PMC r a %04x (st %c) @ %04x", rPMC.byte.h, (ssp->emu_status & SSP_PMC_HAVE_ADDR) ? 'm' : 'a', GET_PPC_OFFS()); #endif if (ssp->emu_status & SSP_PMC_HAVE_ADDR) { - //if (ssp->emu_status & SSP_PMC_SET) - // elprintf(EL_ANOMALY|EL_SVP, "prev PMC not used @ %04x", GET_PPC_OFFS()); + /* if (ssp->emu_status & SSP_PMC_SET) */ + /* elprintf(EL_ANOMALY|EL_SVP, "prev PMC not used @ %04x", GET_PPC_OFFS()); */ ssp->emu_status |= SSP_PMC_SET; ssp->emu_status &= ~SSP_PMC_HAVE_ADDR; - //return ((rPMC.h << 4) & 0xfff0) | ((rPMC.h >> 4) & 0xf); - return ((rPMC.l << 4) & 0xfff0) | ((rPMC.l >> 4) & 0xf); + /* return ((rPMC.h << 4) & 0xfff0) | ((rPMC.h >> 4) & 0xf); */ + return ((rPMC.byte.l << 4) & 0xfff0) | ((rPMC.byte.l >> 4) & 0xf); } else { ssp->emu_status |= SSP_PMC_HAVE_ADDR; - //return rPMC.h; - return rPMC.l; + /* return rPMC.h; */ + return rPMC.byte.l; } } static void write_PMC(u32 d) { if (ssp->emu_status & SSP_PMC_HAVE_ADDR) { - //if (ssp->emu_status & SSP_PMC_SET) - // elprintf(EL_ANOMALY|EL_SVP, "prev PMC not used @ %04x", GET_PPC_OFFS()); + /* if (ssp->emu_status & SSP_PMC_SET) */ + /* elprintf(EL_ANOMALY|EL_SVP, "prev PMC not used @ %04x", GET_PPC_OFFS()); */ ssp->emu_status |= SSP_PMC_SET; ssp->emu_status &= ~SSP_PMC_HAVE_ADDR; - //rPMC.l = d; - rPMC.h = d; + /* rPMC.l = d; */ + rPMC.byte.h = d; #ifdef LOG_SVP - elprintf(EL_SVP, "PMC w m %04x @ %04x", rPMC.l, GET_PPC_OFFS()); + elprintf(EL_SVP, "PMC w m %04x @ %04x", rPMC.byte.l, GET_PPC_OFFS()); #endif } else { ssp->emu_status |= SSP_PMC_HAVE_ADDR; - //rPMC.h = d; - rPMC.l = d; + /* rPMC.h = d; */ + rPMC.byte.l = d; #ifdef LOG_SVP - elprintf(EL_SVP, "PMC w a %04x @ %04x", rPMC.h, GET_PPC_OFFS()); + elprintf(EL_SVP, "PMC w a %04x @ %04x", rPMC.byte.h, GET_PPC_OFFS()); #endif } } -// 15 +/* 15 */ static u32 read_AL(void) { if (*(PC-1) == 0x000f) { #ifdef LOG_SVP elprintf(EL_SVP, "ssp dummy PM assign %08x @ %04x", rPMC.v, GET_PPC_OFFS()); #endif - ssp->emu_status &= ~(SSP_PMC_SET|SSP_PMC_HAVE_ADDR); // ? + ssp->emu_status &= ~(SSP_PMC_SET|SSP_PMC_HAVE_ADDR); /* ? */ } return rAL; } @@ -797,96 +794,95 @@ typedef void (*write_func_t)(u32 d); static read_func_t read_handlers[16] = { - read_unknown, read_unknown, read_unknown, read_unknown, // -, X, Y, A - read_unknown, // 4 ST + read_unknown, read_unknown, read_unknown, read_unknown, /* -, X, Y, A */ + read_unknown, /* 4 ST */ read_STACK, read_PC, read_P, - read_PM0, // 8 + read_PM0, /* 8 */ read_PM1, read_PM2, read_XST, - read_PM4, // 12 - read_unknown, // 13 gr13 + read_PM4, /* 12 */ + read_unknown, /* 13 gr13 */ read_PMC, read_AL }; static write_func_t write_handlers[16] = { - write_unknown, write_unknown, write_unknown, write_unknown, // -, X, Y, A -// write_unknown, // 4 ST - write_ST, // 4 ST (debug hook) + write_unknown, write_unknown, write_unknown, write_unknown, /* -, X, Y, A */ +/* write_unknown, */ /* 4 ST */ + write_ST, /* 4 ST (debug hook) */ write_STACK, write_PC, - write_unknown, // 7 P - write_PM0, // 8 + write_unknown, /* 7 P */ + write_PM0, /* 8 */ write_PM1, write_PM2, write_XST, - write_PM4, // 12 - write_unknown, // 13 gr13 + write_PM4, /* 12 */ + write_unknown, /* 13 gr13 */ write_PMC, write_AL }; -// ----------------------------------------------------- -// pointer register handlers +/* ----------------------------------------------------- */ +/* pointer register handlers */ -// #define ptr1_read(op) ptr1_read_(op&3,(op>>6)&4,(op<<1)&0x18) static u32 ptr1_read_(int ri, int isj2, int modi3) { - //int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); + /* int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); */ u32 mask, add = 0, t = ri | isj2 | modi3; unsigned char *rp = NULL; switch (t) { - // mod=0 (00) + /* mod=0 (00) */ case 0x00: case 0x01: - case 0x02: return ssp->RAM0[ssp->r0[t&3]]; - case 0x03: return ssp->RAM0[0]; + case 0x02: return ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]]; + case 0x03: return ssp->mem.bank.RAM0[0]; case 0x04: case 0x05: - case 0x06: return ssp->RAM1[ssp->r1[t&3]]; - case 0x07: return ssp->RAM1[0]; - // mod=1 (01), "+!" + case 0x06: return ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]]; + case 0x07: return ssp->mem.bank.RAM1[0]; + /* mod=1 (01), "+!" */ case 0x08: case 0x09: - case 0x0a: return ssp->RAM0[ssp->r0[t&3]++]; - case 0x0b: return ssp->RAM0[1]; + case 0x0a: return ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]++]; + case 0x0b: return ssp->mem.bank.RAM0[1]; case 0x0c: case 0x0d: - case 0x0e: return ssp->RAM1[ssp->r1[t&3]++]; - case 0x0f: return ssp->RAM1[1]; - // mod=2 (10), "-" + case 0x0e: return ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]++]; + case 0x0f: return ssp->mem.bank.RAM1[1]; + /* mod=2 (10), "-" */ case 0x10: case 0x11: - case 0x12: rp = &ssp->r0[t&3]; t = ssp->RAM0[*rp]; + case 0x12: rp = &ssp->ptr.bank.r0[t&3]; t = ssp->mem.bank.RAM0[*rp]; if (!(rST&7)) { (*rp)--; return t; } add = -1; goto modulo; - case 0x13: return ssp->RAM0[2]; + case 0x13: return ssp->mem.bank.RAM0[2]; case 0x14: case 0x15: - case 0x16: rp = &ssp->r1[t&3]; t = ssp->RAM1[*rp]; + case 0x16: rp = &ssp->ptr.bank.r1[t&3]; t = ssp->mem.bank.RAM1[*rp]; if (!(rST&7)) { (*rp)--; return t; } add = -1; goto modulo; - case 0x17: return ssp->RAM1[2]; - // mod=3 (11), "+" + case 0x17: return ssp->mem.bank.RAM1[2]; + /* mod=3 (11), "+" */ case 0x18: case 0x19: - case 0x1a: rp = &ssp->r0[t&3]; t = ssp->RAM0[*rp]; + case 0x1a: rp = &ssp->ptr.bank.r0[t&3]; t = ssp->mem.bank.RAM0[*rp]; if (!(rST&7)) { (*rp)++; return t; } add = 1; goto modulo; - case 0x1b: return ssp->RAM0[3]; + case 0x1b: return ssp->mem.bank.RAM0[3]; case 0x1c: case 0x1d: - case 0x1e: rp = &ssp->r1[t&3]; t = ssp->RAM1[*rp]; + case 0x1e: rp = &ssp->ptr.bank.r1[t&3]; t = ssp->mem.bank.RAM1[*rp]; if (!(rST&7)) { (*rp)++; return t; } add = 1; goto modulo; - case 0x1f: return ssp->RAM1[3]; + case 0x1f: return ssp->mem.bank.RAM1[3]; } return 0; @@ -902,43 +898,43 @@ static void ptr1_write(int op, u32 d) int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); switch (t) { - // mod=0 (00) + /* mod=0 (00) */ case 0x00: case 0x01: - case 0x02: ssp->RAM0[ssp->r0[t&3]] = d; return; - case 0x03: ssp->RAM0[0] = d; return; + case 0x02: ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]] = d; return; + case 0x03: ssp->mem.bank.RAM0[0] = d; return; case 0x04: case 0x05: - case 0x06: ssp->RAM1[ssp->r1[t&3]] = d; return; - case 0x07: ssp->RAM1[0] = d; return; - // mod=1 (01), "+!" - // mod=3, "+" + case 0x06: ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]] = d; return; + case 0x07: ssp->mem.bank.RAM1[0] = d; return; + /* mod=1 (01), "+!" */ + /* mod=3, "+" */ case 0x08: case 0x18: case 0x09: case 0x19: case 0x0a: - case 0x1a: ssp->RAM0[ssp->r0[t&3]++] = d; return; - case 0x0b: ssp->RAM0[1] = d; return; + case 0x1a: ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]++] = d; return; + case 0x0b: ssp->mem.bank.RAM0[1] = d; return; case 0x0c: case 0x1c: case 0x0d: case 0x1d: case 0x0e: - case 0x1e: ssp->RAM1[ssp->r1[t&3]++] = d; return; - case 0x0f: ssp->RAM1[1] = d; return; - // mod=2 (10), "-" + case 0x1e: ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]++] = d; return; + case 0x0f: ssp->mem.bank.RAM1[1] = d; return; + /* mod=2 (10), "-" */ case 0x10: case 0x11: - case 0x12: ssp->RAM0[ssp->r0[t&3]--] = d; return; - case 0x13: ssp->RAM0[2] = d; return; + case 0x12: ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]--] = d; return; + case 0x13: ssp->mem.bank.RAM0[2] = d; return; case 0x14: case 0x15: - case 0x16: ssp->RAM1[ssp->r1[t&3]--] = d; return; - case 0x17: ssp->RAM1[2] = d; return; - // mod=3 (11) - case 0x1b: ssp->RAM0[3] = d; return; - case 0x1f: ssp->RAM1[3] = d; return; + case 0x16: ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]--] = d; return; + case 0x17: ssp->mem.bank.RAM1[2] = d; return; + /* mod=3 (11) */ + case 0x1b: ssp->mem.bank.RAM0[3] = d; return; + case 0x1f: ssp->mem.bank.RAM1[3] = d; return; } } @@ -947,33 +943,36 @@ static u32 ptr2_read(int op) int mv = 0, t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); switch (t) { - // mod=0 (00) + /* mod=0 (00) */ case 0x00: case 0x01: - case 0x02: mv = ssp->RAM0[ssp->r0[t&3]]++; break; - case 0x03: mv = ssp->RAM0[0]++; break; + case 0x02: mv = ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]]++; break; + case 0x03: mv = ssp->mem.bank.RAM0[0]++; break; case 0x04: case 0x05: - case 0x06: mv = ssp->RAM1[ssp->r1[t&3]]++; break; - case 0x07: mv = ssp->RAM1[0]++; break; - // mod=1 (01) - case 0x0b: mv = ssp->RAM0[1]++; break; - case 0x0f: mv = ssp->RAM1[1]++; break; - // mod=2 (10) - case 0x13: mv = ssp->RAM0[2]++; break; - case 0x17: mv = ssp->RAM1[2]++; break; - // mod=3 (11) - case 0x1b: mv = ssp->RAM0[3]++; break; - case 0x1f: mv = ssp->RAM1[3]++; break; - default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: invalid mod in ((rX))? @ %04x", GET_PPC_OFFS()); - return 0; + case 0x06: mv = ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]]++; break; + case 0x07: mv = ssp->mem.bank.RAM1[0]++; break; + /* mod=1 (01) */ + case 0x0b: mv = ssp->mem.bank.RAM0[1]++; break; + case 0x0f: mv = ssp->mem.bank.RAM1[1]++; break; + /* mod=2 (10) */ + case 0x13: mv = ssp->mem.bank.RAM0[2]++; break; + case 0x17: mv = ssp->mem.bank.RAM1[2]++; break; + /* mod=3 (11) */ + case 0x1b: mv = ssp->mem.bank.RAM0[3]++; break; + case 0x1f: mv = ssp->mem.bank.RAM1[3]++; break; + default: +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: invalid mod in ((rX))? @ %04x", GET_PPC_OFFS()); +#endif + return 0; } return ((unsigned short *)svp->iram_rom)[mv]; } -// ----------------------------------------------------- +/* ----------------------------------------------------- */ void ssp1601_reset(ssp1601_t *l_ssp) { @@ -981,7 +980,7 @@ void ssp1601_reset(ssp1601_t *l_ssp) ssp->emu_status = 0; ssp->gr[SSP_GR0].v = 0xffff0000; rPC = 0x400; - rSTACK = 0; // ? using ascending stack + rSTACK = 0; /* ? using ascending stack */ rST = 0; } @@ -989,7 +988,7 @@ void ssp1601_reset(ssp1601_t *l_ssp) #ifdef USE_DEBUGGER static void debug_dump(void) { - printf("GR0: %04x X: %04x Y: %04x A: %08x\n", ssp->gr[SSP_GR0].h, rX, rY, ssp->gr[SSP_A].v); + printf("GR0: %04x X: %04x Y: %04x A: %08x\n", ssp->gr[SSP_GR0].byte.h, rX, rY, ssp->gr[SSP_A].v); printf("PC: %04x (%04x) P: %08x\n", GET_PC(), GET_PC() << 1, ssp->gr[SSP_P].v); printf("PM0: %04x PM1: %04x PM2: %04x\n", rPM0, rPM1, rPM2); printf("XST: %04x PM4: %04x PMC: %08x\n", rXST, rPM4, ssp->gr[SSP_PMC].v); @@ -1010,7 +1009,7 @@ static void debug_dump_mem(void) if (h == 16) printf("RAM1\n"); printf("%03x:", h*16); for (i = 0; i < 16; i++) - printf(" %04x", ssp->RAM[h*16+i]); + printf(" %04x", ssp->mem.RAM[h*16+i]); printf("\n"); } } @@ -1084,7 +1083,7 @@ static void debug(unsigned int pc, unsigned int op) } } } -#endif // USE_DEBUGGER +#endif /* USE_DEBUGGER */ void ssp1601_run(int cycles) @@ -1103,12 +1102,12 @@ void ssp1601_run(int cycles) #endif switch (op >> 9) { - // ld d, s + /* ld d, s */ case 0x00: - if (op == 0) break; // nop - if (op == ((SSP_A<<4)|SSP_P)) { // A <- P - // not sure. MAME claims that only hi word is transfered. - read_P(); // update P + if (op == 0) break; /* nop */ + if (op == ((SSP_A<<4)|SSP_P)) { /* A <- P */ + /* not sure. MAME claims that only hi word is transfered. */ + read_P(); /* update P */ rA32 = rP.v; } else @@ -1118,37 +1117,37 @@ void ssp1601_run(int cycles) } break; - // ld d, (ri) + /* ld d, (ri) */ case 0x01: tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break; - // ld (ri), s + /* ld (ri), s */ case 0x02: tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv); break; - // ldi d, imm + /* ldi d, imm */ case 0x04: tmpv = *PC++; REG_WRITE((op & 0xf0) >> 4, tmpv); break; - // ld d, ((ri)) + /* ld d, ((ri)) */ case 0x05: tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break; - // ldi (ri), imm + /* ldi (ri), imm */ case 0x06: tmpv = *PC++; ptr1_write(op, tmpv); break; - // ld adr, a - case 0x07: ssp->RAM[op & 0x1ff] = rA; break; + /* ld adr, a */ + case 0x07: ssp->mem.RAM[op & 0x1ff] = rA; break; - // ld d, ri + /* ld d, ri */ case 0x09: tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv); break; - // ld ri, s + /* ld ri, s */ case 0x0a: rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4); break; - // ldi ri, simm + /* ldi ri, simm */ case 0x0c: case 0x0d: case 0x0e: case 0x0f: rIJ[(op>>8)&7] = op; break; - // call cond, addr + /* call cond, addr */ case 0x24: { int cond = 0; COND_CHECK @@ -1157,10 +1156,10 @@ void ssp1601_run(int cycles) break; } - // ld d, (a) + /* ld d, (a) */ case 0x25: tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv); break; - // bra cond, addr + /* bra cond, addr */ case 0x26: { int cond = 0; COND_CHECK @@ -1169,16 +1168,16 @@ void ssp1601_run(int cycles) break; } - // mod cond, op + /* mod cond, op */ case 0x48: { int cond = 0; COND_CHECK if (cond) { switch (op & 7) { - case 2: rA32 = (signed int)rA32 >> 1; break; // shr (arithmetic) - case 3: rA32 <<= 1; break; // shl - case 6: rA32 = -(signed int)rA32; break; // neg - case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; // abs + case 2: rA32 = (signed int)rA32 >> 1; break; /* shr (arithmetic) */ + case 3: rA32 <<= 1; break; /* shl */ + case 6: rA32 = -(signed int)rA32; break; /* neg */ + case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; /* abs */ default: #ifdef LOG_SVP elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x", @@ -1186,47 +1185,47 @@ void ssp1601_run(int cycles) #endif break; } - UPD_ACC_ZN // ? + UPD_ACC_ZN /* ? */ } break; } - // mpys? + /* mpys? */ case 0x1b: #ifdef LOG_SVP if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); #endif - read_P(); // update P - rA32 -= rP.v; // maybe only upper word? - UPD_ACC_ZN // there checking flags after this - rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) - rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj + read_P(); /* update P */ + rA32 -= rP.v; /* maybe only upper word? */ + UPD_ACC_ZN /* there checking flags after this */ + rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */ + rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */ break; - // mpya (rj), (ri), b + /* mpya (rj), (ri), b */ case 0x4b: #ifdef LOG_SVP if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); #endif - read_P(); // update P - rA32 += rP.v; // confirmed to be 32bit - UPD_ACC_ZN // ? - rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) - rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj + read_P(); /* update P */ + rA32 += rP.v; /* confirmed to be 32bit */ + UPD_ACC_ZN /* ? */ + rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */ + rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */ break; - // mld (rj), (ri), b + /* mld (rj), (ri), b */ case 0x5b: #ifdef LOG_SVP if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); #endif rA32 = 0; - rST &= 0x0fff; // ? - rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) - rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj + rST &= 0x0fff; /* ? */ + rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */ + rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */ break; - // OP a, s + /* OP a, s */ case 0x10: OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv); break; case 0x30: OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv); break; case 0x40: OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv); break; @@ -1234,7 +1233,7 @@ void ssp1601_run(int cycles) case 0x60: OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv); break; case 0x70: OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv); break; - // OP a, (ri) + /* OP a, (ri) */ case 0x11: tmpv = ptr1_read(op); OP_SUBA(tmpv); break; case 0x31: tmpv = ptr1_read(op); OP_CMPA(tmpv); break; case 0x41: tmpv = ptr1_read(op); OP_ADDA(tmpv); break; @@ -1242,16 +1241,16 @@ void ssp1601_run(int cycles) case 0x61: tmpv = ptr1_read(op); OP_ORA (tmpv); break; case 0x71: tmpv = ptr1_read(op); OP_EORA(tmpv); break; - // OP a, adr - case 0x03: tmpv = ssp->RAM[op & 0x1ff]; OP_LDA (tmpv); break; - case 0x13: tmpv = ssp->RAM[op & 0x1ff]; OP_SUBA(tmpv); break; - case 0x33: tmpv = ssp->RAM[op & 0x1ff]; OP_CMPA(tmpv); break; - case 0x43: tmpv = ssp->RAM[op & 0x1ff]; OP_ADDA(tmpv); break; - case 0x53: tmpv = ssp->RAM[op & 0x1ff]; OP_ANDA(tmpv); break; - case 0x63: tmpv = ssp->RAM[op & 0x1ff]; OP_ORA (tmpv); break; - case 0x73: tmpv = ssp->RAM[op & 0x1ff]; OP_EORA(tmpv); break; + /* OP a, adr */ + case 0x03: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_LDA (tmpv); break; + case 0x13: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_SUBA(tmpv); break; + case 0x33: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_CMPA(tmpv); break; + case 0x43: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ADDA(tmpv); break; + case 0x53: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ANDA(tmpv); break; + case 0x63: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ORA (tmpv); break; + case 0x73: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_EORA(tmpv); break; - // OP a, imm + /* OP a, imm */ case 0x14: tmpv = *PC++; OP_SUBA(tmpv); break; case 0x34: tmpv = *PC++; OP_CMPA(tmpv); break; case 0x44: tmpv = *PC++; OP_ADDA(tmpv); break; @@ -1259,7 +1258,7 @@ void ssp1601_run(int cycles) case 0x64: tmpv = *PC++; OP_ORA (tmpv); break; case 0x74: tmpv = *PC++; OP_EORA(tmpv); break; - // OP a, ((ri)) + /* OP a, ((ri)) */ case 0x15: tmpv = ptr2_read(op); OP_SUBA(tmpv); break; case 0x35: tmpv = ptr2_read(op); OP_CMPA(tmpv); break; case 0x45: tmpv = ptr2_read(op); OP_ADDA(tmpv); break; @@ -1267,7 +1266,7 @@ void ssp1601_run(int cycles) case 0x65: tmpv = ptr2_read(op); OP_ORA (tmpv); break; case 0x75: tmpv = ptr2_read(op); OP_EORA(tmpv); break; - // OP a, ri + /* OP a, ri */ case 0x19: tmpv = rIJ[IJind]; OP_SUBA(tmpv); break; case 0x39: tmpv = rIJ[IJind]; OP_CMPA(tmpv); break; case 0x49: tmpv = rIJ[IJind]; OP_ADDA(tmpv); break; @@ -1275,7 +1274,7 @@ void ssp1601_run(int cycles) case 0x69: tmpv = rIJ[IJind]; OP_ORA (tmpv); break; case 0x79: tmpv = rIJ[IJind]; OP_EORA(tmpv); break; - // OP simm + /* OP simm */ case 0x1c: OP_SUBA(op & 0xff); #ifdef LOG_SVP @@ -1294,7 +1293,7 @@ void ssp1601_run(int cycles) if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); #endif break; - // MAME code only does LSB of top word, but this looks wrong to me. + /* MAME code only does LSB of top word, but this looks wrong to me. */ case 0x5c: OP_ANDA(op & 0xff); #ifdef LOG_SVP @@ -1323,7 +1322,7 @@ void ssp1601_run(int cycles) } while (--g_cycles > 0 && !(ssp->emu_status & SSP_WAIT_MASK)); - read_P(); // update P + read_P(); /* update P */ rPC = GET_PC(); #ifdef LOG_SVP diff --git a/source/cart_hw/svp/ssp16.h b/source/cart_hw/svp/ssp16.h index 4dbc73e..1717489 100644 --- a/source/cart_hw/svp/ssp16.h +++ b/source/cart_hw/svp/ssp16.h @@ -14,12 +14,10 @@ #define _SSP16_H_ /* emulation event logging (from Picodrive) */ +#ifdef LOG_SVP #define EL_SVP 0x00004000 /* SVP stuff */ #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */ -#ifdef LOG_SVP #define elprintf(w,f,...) error("%d(%d): " f "\n",frame_count,v_counter,##__VA_ARGS__); -#else -#define elprintf(w,f,...) #endif /* register names */ @@ -41,37 +39,35 @@ typedef union unsigned short h; unsigned short l; #endif - }; + } byte; } ssp_reg_t; typedef struct { union { - unsigned short RAM[256*2]; // 2 internal RAM banks + unsigned short RAM[256*2]; /* 2 internal RAM banks */ struct { unsigned short RAM0[256]; unsigned short RAM1[256]; - }; - }; - ssp_reg_t gr[16]; // general registers + } bank; + } mem; + ssp_reg_t gr[16]; /* general registers */ union { - unsigned char r[8]; // BANK pointers + unsigned char r[8]; /* BANK pointers */ struct { unsigned char r0[4]; unsigned char r1[4]; - }; - }; + } bank; + } ptr; unsigned short stack[6]; - unsigned int pmac_read[6]; // read modes/addrs for PM0-PM5 - unsigned int pmac_write[6]; // write ... - - #define SSP_PMC_HAVE_ADDR 0x0001 // address written to PMAC, waiting for mode - #define SSP_PMC_SET 0x0002 // PMAC is set - #define SSP_HANG 0x1000 // 68000 hangs SVP - #define SSP_WAIT_PM0 0x2000 // bit1 in PM0 - #define SSP_WAIT_30FE06 0x4000 // ssp tight loops on 30FE08 to become non-zero - #define SSP_WAIT_30FE08 0x8000 // same for 30FE06 - #define SSP_WAIT_MASK 0xf000 + unsigned int pmac[2][6]; /* read/write modes/addrs for PM0-PM5 */ + #define SSP_PMC_HAVE_ADDR 0x0001 /* address written to PMAC, waiting for mode */ + #define SSP_PMC_SET 0x0002 /* PMAC is set */ + #define SSP_HANG 0x1000 /* 68000 hangs SVP */ + #define SSP_WAIT_PM0 0x2000 /* bit1 in PM0 */ + #define SSP_WAIT_30FE06 0x4000 /* ssp tight loops on 30FE08 to become non-zero */ + #define SSP_WAIT_30FE08 0x8000 /* same for 30FE06 */ + #define SSP_WAIT_MASK 0xf000 unsigned int emu_status; unsigned int pad[30]; } ssp1601_t; diff --git a/source/cart_hw/svp/svp.c b/source/cart_hw/svp/svp.c index 5d9557c..9176319 100644 --- a/source/cart_hw/svp/svp.c +++ b/source/cart_hw/svp/svp.c @@ -13,7 +13,6 @@ #include "shared.h" svp_t *svp = NULL; -int16 SVP_cycles = 800; void svp_init(void) { diff --git a/source/cart_hw/svp/svp.h b/source/cart_hw/svp/svp.h index 1109a8a..e052053 100644 --- a/source/cart_hw/svp/svp.h +++ b/source/cart_hw/svp/svp.h @@ -17,13 +17,12 @@ #include "ssp16.h" typedef struct { - unsigned char iram_rom[0x20000]; // IRAM (0-0x7ff) and program ROM (0x800-0x1ffff) + unsigned char iram_rom[0x20000]; /* IRAM (0-0x7ff) and program ROM (0x800-0x1ffff) */ unsigned char dram[0x20000]; ssp1601_t ssp1601; } svp_t; extern svp_t *svp; -extern int16 SVP_cycles; extern void svp_init(void); extern void svp_reset(void); diff --git a/source/genesis.c b/source/genesis.c index 001dd79..536a9ab 100644 --- a/source/genesis.c +++ b/source/genesis.c @@ -47,7 +47,7 @@ uint8 zram[0x2000]; /* Z80 RAM */ uint32 zbank; /* Z80 bank window address */ uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */ uint8 pico_current; /* PICO current page */ -uint8 pico_page[7]; /* PICO page registers */ +uint8 pico_regs[7]; /* PICO page registers */ static uint8 tmss[4]; /* TMSS security register */ diff --git a/source/genesis.h b/source/genesis.h index d5afa4c..acb357d 100644 --- a/source/genesis.h +++ b/source/genesis.h @@ -49,7 +49,7 @@ extern uint8 zram[0x2000]; extern uint32 zbank; extern uint8 zstate; extern uint8 pico_current; -extern uint8 pico_page[7]; +extern uint8 pico_regs[7]; /* Function prototypes */ extern void gen_init(void); diff --git a/source/gx/fileio/fileio.h b/source/gx/fileio/fileio.h index b5568f8..1759c51 100644 --- a/source/gx/fileio/fileio.h +++ b/source/gx/fileio/fileio.h @@ -42,7 +42,6 @@ #define _FILEIO_H_ /* Function prototypes */ -void get_zipfilename(char *filename); int load_archive(char *filename); #endif /* _FILEIO_H_ */ diff --git a/source/input_hw/activator.c b/source/input_hw/activator.c index e741215..984dd21 100644 --- a/source/input_hw/activator.c +++ b/source/input_hw/activator.c @@ -51,13 +51,10 @@ void activator_reset(int index) activator[index].Counter = 0; } -static inline unsigned char activator_read(int port) +static __inline__ unsigned char activator_read(int port) { /* IR sensors 1-16 data (active low) */ - uint16 data = ~input.pad[port]; - - /* Device index */ - port = port >> 2; + uint16 data = ~input.pad[port << 2]; /* D1 = D0 (data is ready) */ uint8 temp = (activator[port].State & 0x01) << 1; @@ -88,7 +85,7 @@ static inline unsigned char activator_read(int port) return temp; } -static inline void activator_write(int index, unsigned char data, unsigned char mask) +static __inline__ void activator_write(int index, unsigned char data, unsigned char mask) { /* update bits set as output only */ data = (activator[index].State & ~mask) | (data & mask); @@ -123,7 +120,7 @@ unsigned char activator_1_read(void) unsigned char activator_2_read(void) { - return activator_read(4); + return activator_read(1); } void activator_1_write(unsigned char data, unsigned char mask) diff --git a/source/input_hw/gamepad.c b/source/input_hw/gamepad.c index 20eae8a..9ef5f8b 100644 --- a/source/input_hw/gamepad.c +++ b/source/input_hw/gamepad.c @@ -71,7 +71,7 @@ void gamepad_refresh(int port) } } -static inline unsigned char gamepad_read(int port) +static __inline__ unsigned char gamepad_read(int port) { /* bit 7 is latched, returns current TH state */ unsigned int data = (gamepad[port].State & 0x40) | 0x3F; @@ -142,7 +142,7 @@ static inline unsigned char gamepad_read(int port) return data; } -static inline void gamepad_write(int port, unsigned char data, unsigned char mask) +static __inline__ void gamepad_write(int port, unsigned char data, unsigned char mask) { /* update bits set as output only */ data = (gamepad[port].State & ~mask) | (data & mask); diff --git a/source/input_hw/lightgun.c b/source/input_hw/lightgun.c index 22414ad..7133b31 100644 --- a/source/input_hw/lightgun.c +++ b/source/input_hw/lightgun.c @@ -140,7 +140,7 @@ void lightgun_refresh(int port) /* Sega Phaser */ /*--------------------------------------------------------------------------*/ -static inline unsigned char phaser_read(int port) +static __inline__ unsigned char phaser_read(int port) { /* TL returns TRIGGER (INPUT_A) button status (active low) */ unsigned char temp = ~((input.pad[port] >> 2) & 0x10); diff --git a/source/input_hw/paddle.c b/source/input_hw/paddle.c index f8b681c..f32b6f9 100644 --- a/source/input_hw/paddle.c +++ b/source/input_hw/paddle.c @@ -49,7 +49,7 @@ void paddle_reset(int index) paddle[index].State = 0x40; } -static inline unsigned char paddle_read(int port) +static __inline__ unsigned char paddle_read(int port) { /* FIRE button status (active low) */ unsigned char temp = ~(input.pad[port] & 0x10); @@ -83,7 +83,7 @@ static inline unsigned char paddle_read(int port) return temp; } -static inline void paddle_write(int index, unsigned char data, unsigned char mask) +static __inline__ void paddle_write(int index, unsigned char data, unsigned char mask) { /* update bits set as output only */ paddle[index].State = (paddle[index].State & ~mask) | (data & mask); diff --git a/source/input_hw/sportspad.c b/source/input_hw/sportspad.c index 6c85554..df2f77a 100644 --- a/source/input_hw/sportspad.c +++ b/source/input_hw/sportspad.c @@ -52,7 +52,7 @@ void sportspad_reset(int index) sportspad[index].Counter = 0; } -static inline unsigned char sportspad_read(int port) +static __inline__ unsigned char sportspad_read(int port) { /* Buttons 1(B) & 2(C) status (active low) */ unsigned char temp = ~(input.pad[port] & 0x30); @@ -98,7 +98,7 @@ static inline unsigned char sportspad_read(int port) return temp; } -static inline void sportspad_write(int index, unsigned char data, unsigned char mask) +static __inline__ void sportspad_write(int index, unsigned char data, unsigned char mask) { /* update bits set as output only */ data = (sportspad[index].State & ~mask) | (data & mask); diff --git a/source/input_hw/teamplayer.c b/source/input_hw/teamplayer.c index 85c9a33..9523a53 100644 --- a/source/input_hw/teamplayer.c +++ b/source/input_hw/teamplayer.c @@ -80,7 +80,7 @@ void teamplayer_reset(int port) teamplayer[port].Counter = 0; } -static inline unsigned int teamplayer_read(int port) +static __inline__ unsigned int teamplayer_read(int port) { unsigned int counter = teamplayer[port].Counter; @@ -131,7 +131,7 @@ static inline unsigned int teamplayer_read(int port) } } -static inline void teamplayer_write(int port, unsigned char data, unsigned char mask) +static __inline__ void teamplayer_write(int port, unsigned char data, unsigned char mask) { /* update bits set as output only */ unsigned int state = (teamplayer[port].State & ~mask) | (data & mask); diff --git a/source/input_hw/xe_a1p.c b/source/input_hw/xe_a1p.c index 859904b..0cb702f 100644 --- a/source/input_hw/xe_a1p.c +++ b/source/input_hw/xe_a1p.c @@ -68,7 +68,10 @@ unsigned char xe_a1p_read() /* Buttons status (active low) */ uint16 pad = ~input.pad[0]; - + + /* Current internal cycle (0-7) */ + unsigned int cycle = xe_a1p.Counter & 7; + /* Current 4-bit data cycle */ /* There are eight internal data cycle for each 5 acquisition sequence */ /* First 4 return the same 4-bit data, next 4 return next 4-bit data */ @@ -104,9 +107,6 @@ unsigned char xe_a1p_read() break; } - /* Get current internal cycle (0-7) */ - unsigned int cycle = xe_a1p.Counter & 7; - /* TL indicates which part of data is returned (0=1st part, 1=2nd part) */ temp |= ((cycle & 4) << 2); diff --git a/source/m68k/m68k.h b/source/m68k/m68k.h index 295d377..fb2b111 100644 --- a/source/m68k/m68k.h +++ b/source/m68k/m68k.h @@ -114,7 +114,7 @@ typedef enum #endif /* Convenience registers */ - M68K_REG_IR, /* Instruction register */ + M68K_REG_IR /* Instruction register */ } m68k_register_t; diff --git a/source/mem68k.c b/source/mem68k.c index b65b52a..ef43c1e 100644 --- a/source/mem68k.c +++ b/source/mem68k.c @@ -255,9 +255,9 @@ unsigned int ctrl_io_read_byte(unsigned int address) return m68k_read_bus_8(address); } - case 0x41: /* OS ROM */ + case 0x41: /* BOOT ROM */ { - if (address & 1) + if ((config.bios & 1) && (address & 1)) { unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xFE; return (gen_bankswitch_r() | data); @@ -320,13 +320,13 @@ unsigned int ctrl_io_read_word(unsigned int address) { if ((address & 0xFD) == 0) { - return svp->ssp1601.gr[SSP_XST].h; + return svp->ssp1601.gr[SSP_XST].byte.h; } if ((address & 0xFF) == 4) { - unsigned int data = svp->ssp1601.gr[SSP_PM0].h; - svp->ssp1601.gr[SSP_PM0].h &= ~1; + unsigned int data = svp->ssp1601.gr[SSP_PM0].byte.h; + svp->ssp1601.gr[SSP_PM0].byte.h &= ~1; return data; } @@ -337,7 +337,7 @@ unsigned int ctrl_io_read_word(unsigned int address) case 0x12: /* RESET */ case 0x20: /* MEGA-CD */ case 0x40: /* TMSS */ - case 0x41: /* OS ROM */ + case 0x41: /* BOOT ROM */ case 0x44: /* RADICA */ { return m68k_read_bus_16(address); @@ -394,9 +394,9 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data) return; } - case 0x41: /* OS ROM */ + case 0x41: /* BOOT ROM */ { - if (address & 1) + if ((config.bios & 1) && (address & 1)) { gen_bankswitch_w(data & 1); return; @@ -458,7 +458,7 @@ void ctrl_io_write_word(unsigned int address, unsigned int data) case 0x40: /* TMSS */ { - if (config.tmss & 1) + if (config.bios & 1) { gen_tmss_w(address & 3, data); return; @@ -471,8 +471,8 @@ void ctrl_io_write_word(unsigned int address, unsigned int data) { if (!(address & 0xFD)) { - svp->ssp1601.gr[SSP_XST].h = data; - svp->ssp1601.gr[SSP_PM0].h |= 2; + svp->ssp1601.gr[SSP_XST].byte.h = data; + svp->ssp1601.gr[SSP_PM0].byte.h |= 2; svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; return; } @@ -482,7 +482,7 @@ void ctrl_io_write_word(unsigned int address, unsigned int data) case 0x10: /* MEMORY MODE */ case 0x20: /* MEGA-CD */ - case 0x41: /* OS ROM */ + case 0x41: /* BOOT ROM */ case 0x44: /* RADICA */ { m68k_unused_16_w (address, data); @@ -727,7 +727,7 @@ unsigned int pico_read_byte(unsigned int address) case 0x0D: /* PAGE register (TODO) */ { - return pico_page[pico_current]; + return pico_regs[pico_current]; } case 0x10: /* PCM registers (TODO) */ diff --git a/source/membnk.c b/source/membnk.c index 2521601..e96e3cb 100644 --- a/source/membnk.c +++ b/source/membnk.c @@ -55,7 +55,7 @@ unsigned int zbank_unused_r(unsigned int address) void zbank_unused_w(unsigned int address, unsigned int data) { #ifdef LOGERROR - error("Z80 bank unused write %06X = %02X\n", address, data); + error("Z80 bank unused write %06X = %02X (%x)\n", address, data, Z80.pc.d); #endif } diff --git a/source/memz80.c b/source/memz80.c index cfca9f0..376c9fa 100644 --- a/source/memz80.c +++ b/source/memz80.c @@ -47,14 +47,14 @@ /* machine lock up. */ /*--------------------------------------------------------------------------*/ -static inline void z80_unused_w(unsigned int address, unsigned char data) +static __inline__ void z80_unused_w(unsigned int address, unsigned char data) { #ifdef LOGERROR error("Z80 unused write %04X = %02X (%x)\n", address, data, Z80.pc.w.l); #endif } -static inline unsigned char z80_unused_r(unsigned int address) +static __inline__ unsigned char z80_unused_r(unsigned int address) { #ifdef LOGERROR error("Z80 unused read %04X (%x)\n", address, Z80.pc.w.l); @@ -62,7 +62,7 @@ static inline unsigned char z80_unused_r(unsigned int address) return 0xFF; } -static inline void z80_lockup_w(unsigned int address, unsigned char data) +static __inline__ void z80_lockup_w(unsigned int address, unsigned char data) { #ifdef LOGERROR error("Z80 lockup write %04X = %02X (%x)\n", address, data, Z80.pc.w.l); @@ -74,7 +74,7 @@ static inline void z80_lockup_w(unsigned int address, unsigned char data) } } -static inline unsigned char z80_lockup_r(unsigned int address) +static __inline__ unsigned char z80_lockup_r(unsigned int address) { #ifdef LOGERROR error("Z80 lockup read %04X (%x)\n", address, Z80.pc.w.l); @@ -119,12 +119,11 @@ unsigned char z80_memory_r(unsigned int address) default: /* $8000-$FFFF: 68k bank (32K) */ { address = zbank | (address & 0x7FFF); - unsigned int slot = address >> 16; - if (zbank_memory_map[slot].read) + if (zbank_memory_map[address >> 16].read) { - return (*zbank_memory_map[slot].read)(address); + return (*zbank_memory_map[address >> 16].read)(address); } - return READ_BYTE(m68k_memory_map[slot].base, address & 0xFFFF); + return READ_BYTE(m68k_memory_map[address >> 16].base, address & 0xFFFF); } } } @@ -174,13 +173,12 @@ void z80_memory_w(unsigned int address, unsigned char data) default: /* $8000-$FFFF: 68k bank (32K) */ { address = zbank | (address & 0x7FFF); - unsigned int slot = address >> 16; - if (zbank_memory_map[slot].write) + if (zbank_memory_map[address >> 16].write) { - (*zbank_memory_map[slot].write)(address, data); + (*zbank_memory_map[address >> 16].write)(address, data); return; } - WRITE_BYTE(m68k_memory_map[slot].base, address & 0xFFFF, data); + WRITE_BYTE(m68k_memory_map[address >> 16].base, address & 0xFFFF, data); return; } } diff --git a/source/sound/Fir_Resampler.c b/source/sound/Fir_Resampler.c index e11cfb9..231eafe 100644 --- a/source/sound/Fir_Resampler.c +++ b/source/sound/Fir_Resampler.c @@ -43,9 +43,8 @@ static void gen_sinc(double rolloff, int width, double offset, double spacing, d double const fstep = M_PI / maxh * spacing; double const to_w = maxh * 2 / width; double const pow_a_n = pow( rolloff, maxh ); - scale /= maxh * 2; - double angle = (count / 2 - 1 + offset) * -fstep; + scale /= maxh * 2; do { @@ -154,10 +153,8 @@ void Fir_Resampler_clear() double Fir_Resampler_time_ratio( double new_factor, double rolloff ) { - ratio = new_factor; - int i, r; - double nearest, error; + double nearest, error, filter; double fstep = 0.0; double least_error = 2; double pos = 0.0; @@ -165,7 +162,7 @@ double Fir_Resampler_time_ratio( double new_factor, double rolloff ) for ( r = 1; r <= MAX_RES; r++ ) { - pos += ratio; + pos += new_factor; nearest = floor( pos + 0.5 ); error = fabs( pos - nearest ); if ( error < least_error ) @@ -183,7 +180,7 @@ double Fir_Resampler_time_ratio( double new_factor, double rolloff ) ratio = fstep; fstep = fmod( fstep, 1.0 ); - double filter = (ratio < 1.0) ? 1.0 : 1.0 / ratio; + filter = (ratio < 1.0) ? 1.0 : 1.0 / ratio; pos = 0.0; input_per_cycle = 0; @@ -310,9 +307,9 @@ int Fir_Resampler_read( sample_t* out, long count ) imp_phase = res - remain; - int left = write_pos - in; - write_pos = &buffer [left]; - memmove( buffer, in, left * sizeof *in ); + n = write_pos - in; + write_pos = &buffer [n]; + memmove( buffer, in, n * sizeof *in ); return out - out_; } @@ -321,9 +318,9 @@ int Fir_Resampler_read( sample_t* out, long count ) int Fir_Resampler_input_needed( long output_count ) { long input_count = 0; - unsigned long skip = skip_bits >> imp_phase; int remain = res - imp_phase; + while ( (output_count) > 0 ) { input_count += step + (skip & 1) * STEREO; @@ -336,10 +333,10 @@ int Fir_Resampler_input_needed( long output_count ) output_count --; } - long input_extra = input_count - (write_pos - &buffer [WRITE_OFFSET]); - if ( input_extra < 0 ) - input_extra = 0; - return (input_extra >> 1); + input_count -= (write_pos - &buffer [WRITE_OFFSET]); + if ( input_count < 0 ) + input_count = 0; + return (input_count >> 1); } int Fir_Resampler_skip_input( long count ) diff --git a/source/sound/blip.c b/source/sound/blip.c index 38fea15..cf1c3da 100644 --- a/source/sound/blip.c +++ b/source/sound/blip.c @@ -105,33 +105,19 @@ int blip_samples_avail( const blip_buffer_t* s ) return s->offset >> time_bits; } -/* Removes n samples from buffer */ -static void remove_samples( blip_buffer_t* s, int n ) -{ - int remain = blip_samples_avail( s ) + buf_extra - n; - - s->offset -= n * time_unit; - - /* Copy remaining samples to beginning of buffer and clear the rest */ - memmove( s->buf, &s->buf [n], remain * sizeof (buf_t) ); - memset( &s->buf [remain], 0, n * sizeof (buf_t) ); -} - -int blip_read_samples( blip_buffer_t* s, short out [], int count, int stereo ) +void blip_read_samples( blip_buffer_t* s, short out[], int count) { /* can't read more than available */ - int avail = blip_samples_avail( s ); + int avail = s->offset >> time_bits; if ( count > avail ) count = avail; if ( count ) { /* Sum deltas and write out */ - int i; + int i, sample; for ( i = 0; i < count; ++i ) - { - int sample; - + { /* Apply slight high-pass filter */ s->amp -= s->amp >> 9; @@ -145,11 +131,15 @@ int blip_read_samples( blip_buffer_t* s, short out [], int count, int stereo ) if ( sample < -32768 ) sample = -32768; if ( sample > +32767 ) sample = +32767; - out [i << stereo] = sample; + out [i] = sample; } - - remove_samples( s, count ); - } - return count; + /* Copy remaining samples to beginning of buffer and clear the rest */ + i = (s->offset >> time_bits) + buf_extra - count; + memmove( s->buf, &s->buf [count], i * sizeof (buf_t) ); + memset( &s->buf [i], 0, count * sizeof (buf_t) ); + + /* Remove samples */ + s->offset -= count * time_unit; + } } diff --git a/source/sound/blip.h b/source/sound/blip.h index 98daa55..b535a4c 100644 --- a/source/sound/blip.h +++ b/source/sound/blip.h @@ -39,10 +39,8 @@ void blip_end_frame( blip_buffer_t*, int duration ); int blip_samples_avail( const blip_buffer_t* ); /* Reads at most n samples out of buffer into out, removing them from from -the buffer. Returns number of samples actually read and removed. If stereo is -true, increments 'out' one extra time after writing each sample, to allow -easy interleving of two channels into a stereo output buffer. */ -int blip_read_samples( blip_buffer_t*, short out [], int n, int stereo ); +the buffer. */ +void blip_read_samples( blip_buffer_t*, short out [], int n); #ifdef __cplusplus } diff --git a/source/sound/eq.c b/source/sound/eq.c index 327cb63..2ad5041 100644 --- a/source/sound/eq.c +++ b/source/sound/eq.c @@ -1,4 +1,4 @@ -//---------------------------------------------------------------------------- +/*---------------------------------------------------------------------------- // // 3 Band EQ :) // @@ -14,9 +14,9 @@ // The author assumes NO RESPONSIBILITY for any problems caused by the use of // this software. // -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------*/ -// NOTES : +/* NOTES : // // - Original filter code by Paul Kellet (musicdsp.pdf) // @@ -25,71 +25,72 @@ // - Now with P4 Denormal fix :) -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------*/ -// ---------- +/* ---------- //| Includes | -// ---------- +// ----------*/ #include #include #include #include "eq.h" +#include "types.h" -// ----------- +/* ----------- //| Constants | -// ----------- +// -----------*/ -static double vsa = (1.0 / 4294967295.0); // Very small amount (Denormal Fix) +static double vsa = (1.0 / 4294967295.0); /* Very small amount (Denormal Fix) */ -// --------------- +/* --------------- //| Initialise EQ | -// --------------- +// ---------------*/ -// Recommended frequencies are ... +/* Recommended frequencies are ... // // lowfreq = 880 Hz // highfreq = 5000 Hz // -// Set mixfreq to whatever rate your system is using (eg 48Khz) +// Set mixfreq to whatever rate your system is using (eg 48Khz)*/ void init_3band_state(EQSTATE * es, int lowfreq, int highfreq, int mixfreq) { - // Clear state + /* Clear state */ memset(es, 0, sizeof(EQSTATE)); - // Set Low/Mid/High gains to unity + /* Set Low/Mid/High gains to unity */ es->lg = 1.0; es->mg = 1.0; es->hg = 1.0; - // Calculate filter cutoff frequencies + /* Calculate filter cutoff frequencies */ es->lf = 2 * sin(M_PI * ((double) lowfreq / (double) mixfreq)); es->hf = 2 * sin(M_PI * ((double) highfreq / (double) mixfreq)); } -// --------------- +/* --------------- //| EQ one sample | -// --------------- +// ---------------*/ -// - sample can be any range you like :) +/* - sample can be any range you like :) // // Note that the output will depend on the gain settings for each band // (especially the bass) so may require clipping before output, but you -// knew that anyway :) +// knew that anyway :)*/ double do_3band(EQSTATE * es, int sample) { - // Locals + /* Locals */ - double l, m, h; // Low / Mid / High - Sample Values + double l, m, h; /* Low / Mid / High - Sample Values */ - // Filter #1 (lowpass) + /* Filter #1 (lowpass) */ es->f1p0 += (es->lf * ((double) sample - es->f1p0)) + vsa; es->f1p1 += (es->lf * (es->f1p0 - es->f1p1)); @@ -98,7 +99,7 @@ double do_3band(EQSTATE * es, int sample) l = es->f1p3; - // Filter #2 (highpass) + /* Filter #2 (highpass) */ es->f2p0 += (es->hf * ((double) sample - es->f2p0)) + vsa; es->f2p1 += (es->hf * (es->f2p0 - es->f2p1)); @@ -107,25 +108,25 @@ double do_3band(EQSTATE * es, int sample) h = es->sdm3 - es->f2p3; - // Calculate midrange (signal - (low + high)) + /* Calculate midrange (signal - (low + high)) */ - //m = es->sdm3 - (h + l); - // fix from http://www.musicdsp.org/showArchiveComment.php?ArchiveID=236 ? + /* m = es->sdm3 - (h + l); */ + /* fix from http://www.musicdsp.org/showArchiveComment.php?ArchiveID=236 ? */ m = sample - (h + l); - // Scale, Combine and store + /* Scale, Combine and store */ l *= es->lg; m *= es->mg; h *= es->hg; - // Shuffle history buffer + /* Shuffle history buffer */ es->sdm3 = es->sdm2; es->sdm2 = es->sdm1; es->sdm1 = sample; - // Return result + /* Return result */ return (int) (l + m + h); } diff --git a/source/sound/eq.h b/source/sound/eq.h index 4eaef4d..d1f37dc 100644 --- a/source/sound/eq.h +++ b/source/sound/eq.h @@ -1,4 +1,4 @@ -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- // // 3 Band EQ :) // @@ -14,54 +14,54 @@ // The author assumes NO RESPONSIBILITY for any problems caused by the use of // this software. // -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------*/ #ifndef __EQ3BAND__ #define __EQ3BAND__ -// ------------ +/* ------------ //| Structures | -// ------------ +// ------------*/ typedef struct { - // Filter #1 (Low band) + /* Filter #1 (Low band) */ - double lf; // Frequency - double f1p0; // Poles ... + double lf; /* Frequency */ + double f1p0; /* Poles ... */ double f1p1; double f1p2; double f1p3; - // Filter #2 (High band) + /* Filter #2 (High band) */ - double hf; // Frequency - double f2p0; // Poles ... + double hf; /* Frequency */ + double f2p0; /* Poles ... */ double f2p1; double f2p2; double f2p3; - // Sample history buffer + /* Sample history buffer */ - double sdm1; // Sample data minus 1 - double sdm2; // 2 - double sdm3; // 3 + double sdm1; /* Sample data minus 1 */ + double sdm2; /* 2 */ + double sdm3; /* 3 */ - // Gain Controls + /* Gain Controls */ - double lg; // low gain - double mg; // mid gain - double hg; // high gain + double lg; /* low gain */ + double mg; /* mid gain */ + double hg; /* high gain */ } EQSTATE; -// --------- +/* --------- //| Exports | -// --------- +// ---------*/ extern void init_3band_state(EQSTATE * es, int lowfreq, int highfreq, int mixfreq); extern double do_3band(EQSTATE * es, int sample); -#endif // #ifndef __EQ3BAND__ +#endif /* #ifndef __EQ3BAND__ */ diff --git a/source/sound/sn76489.c b/source/sound/sn76489.c index f5158ef..fb523ab 100644 --- a/source/sound/sn76489.c +++ b/source/sound/sn76489.c @@ -165,9 +165,7 @@ void SN76489_Write(int data) SN76489.LatchedRegister = (data >> 4) & 0x07; } - int LatchedRegister = SN76489.LatchedRegister; - - switch (LatchedRegister) + switch (SN76489.LatchedRegister) { case 0: case 2: @@ -175,22 +173,22 @@ void SN76489_Write(int data) if (data & 0x80) { /* Data byte %1 cc t dddd */ - SN76489.Registers[LatchedRegister] = (SN76489.Registers[LatchedRegister] & 0x3f0) | (data & 0xf); + SN76489.Registers[SN76489.LatchedRegister] = (SN76489.Registers[SN76489.LatchedRegister] & 0x3f0) | (data & 0xf); } else { /* Data byte %0 - dddddd */ - SN76489.Registers[LatchedRegister] = (SN76489.Registers[LatchedRegister] & 0x00f) | ((data & 0x3f) << 4); + SN76489.Registers[SN76489.LatchedRegister] = (SN76489.Registers[SN76489.LatchedRegister] & 0x00f) | ((data & 0x3f) << 4); } /* Zero frequency changed to 1 to avoid div/0 */ - if (SN76489.Registers[LatchedRegister] == 0) SN76489.Registers[LatchedRegister] = 1; + if (SN76489.Registers[SN76489.LatchedRegister] == 0) SN76489.Registers[SN76489.LatchedRegister] = 1; break; case 1: case 3: case 5: /* Channel attenuation */ - SN76489.Registers[LatchedRegister] = data & 0x0f; - SN76489.Channels[LatchedRegister>>1] = PSGVolumeValues[data&0x0f]; + SN76489.Registers[SN76489.LatchedRegister] = data & 0x0f; + SN76489.Channels[SN76489.LatchedRegister>>1] = PSGVolumeValues[data&0x0f]; break; case 6: /* Noise control */ @@ -327,5 +325,5 @@ void SN76489_Update(INT16 *buffer, int length) /* Read samples into output buffer */ blip_end_frame(blip, clock_length); - blip_read_samples(blip, buffer, length, 0); -} \ No newline at end of file + blip_read_samples(blip, buffer, length); +} diff --git a/source/sound/ym2413.c b/source/sound/ym2413.c index 7331040..0facea1 100644 --- a/source/sound/ym2413.c +++ b/source/sound/ym2413.c @@ -464,34 +464,34 @@ static const INT8 lfo_pm_table[8*8] = { static unsigned char table[19][8] = { /* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */ /* 0 1 2 3 4 5 6 7 */ - {0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, //0 + {0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, /* 0 */ - {0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17 }, //1 - {0x13, 0x41, 0x1e, 0x0d, 0xd7, 0xf7, 0x13, 0x13 }, //2 - {0x13, 0x01, 0x99, 0x04, 0xf2, 0xf4, 0x11, 0x23 }, //3 - {0x21, 0x61, 0x1b, 0x07, 0xaf, 0x64, 0x40, 0x27 }, //4 + {0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17 }, /* 1 */ + {0x13, 0x41, 0x1e, 0x0d, 0xd7, 0xf7, 0x13, 0x13 }, /* 2 */ + {0x13, 0x01, 0x99, 0x04, 0xf2, 0xf4, 0x11, 0x23 }, /* 3 */ + {0x21, 0x61, 0x1b, 0x07, 0xaf, 0x64, 0x40, 0x27 }, /* 4 */ -//{0x22, 0x21, 0x1e, 0x09, 0xf0, 0x76, 0x08, 0x28 }, //5 - {0x22, 0x21, 0x1e, 0x06, 0xf0, 0x75, 0x08, 0x18 }, //5 +/*{0x22, 0x21, 0x1e, 0x09, 0xf0, 0x76, 0x08, 0x28 }, */ /* 5 */ + {0x22, 0x21, 0x1e, 0x06, 0xf0, 0x75, 0x08, 0x18 }, /* 5 */ -//{0x31, 0x22, 0x16, 0x09, 0x90, 0x7f, 0x00, 0x08 }, //6 - {0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x13 }, //6 +/*{0x31, 0x22, 0x16, 0x09, 0x90, 0x7f, 0x00, 0x08 }, */ /* 6 */ + {0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x13 }, /* 6 */ - {0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x10, 0x17 }, //7 - {0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07 }, //8 - {0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17 }, //9 + {0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x10, 0x17 }, /* 7 */ + {0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07 }, /* 8 */ + {0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17 }, /* 9 */ -//{0x61, 0x61, 0x0c, 0x08, 0x85, 0xa0, 0x79, 0x07 }, //A - {0x61, 0x61, 0x0c, 0x18, 0x85, 0xf0, 0x70, 0x07 }, //A +/* {0x61, 0x61, 0x0c, 0x08, 0x85, 0xa0, 0x79, 0x07 }, */ /* A */ + {0x61, 0x61, 0x0c, 0x18, 0x85, 0xf0, 0x70, 0x07 }, /* A */ - {0x23, 0x01, 0x07, 0x11, 0xf0, 0xa4, 0x00, 0x22 }, //B - {0x97, 0xc1, 0x24, 0x07, 0xff, 0xf8, 0x22, 0x12 }, //C + {0x23, 0x01, 0x07, 0x11, 0xf0, 0xa4, 0x00, 0x22 }, /* B */ + {0x97, 0xc1, 0x24, 0x07, 0xff, 0xf8, 0x22, 0x12 }, /* C */ -//{0x61, 0x10, 0x0c, 0x08, 0xf2, 0xc4, 0x40, 0xc8 }, //D - {0x61, 0x10, 0x0c, 0x05, 0xf2, 0xf4, 0x40, 0x44 }, //D +/* {0x61, 0x10, 0x0c, 0x08, 0xf2, 0xc4, 0x40, 0xc8 }, */ /* D */ + {0x61, 0x10, 0x0c, 0x05, 0xf2, 0xf4, 0x40, 0x44 }, /* D */ - {0x01, 0x01, 0x55, 0x03, 0xf3, 0x92, 0xf3, 0xf3 }, //E - {0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13 }, //F + {0x01, 0x01, 0x55, 0x03, 0xf3, 0x92, 0xf3, 0xf3 }, /* E */ + {0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13 }, /* F */ /* drum instruments definitions */ /* MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR */ @@ -886,16 +886,16 @@ INLINE void rhythm_calc( YM2413_OPLL_CH *CH, unsigned int noise ) /* Phase generation is based on: */ - // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) - // SD (16) channel 7->slot 1 - // TOM (14) channel 8->slot 1 - // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) + /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */ + /* SD (16) channel 7->slot 1 */ + /* TOM (14) channel 8->slot 1 */ + /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */ /* Envelope generation based on: */ - // HH channel 7->slot1 - // SD channel 7->slot2 - // TOM channel 8->slot1 - // TOP channel 8->slot2 + /* HH channel 7->slot1 */ + /* SD channel 7->slot2 */ + /* TOM channel 8->slot1 */ + /* TOP channel 8->slot2 */ /* The following formulas can be well optimized. @@ -1219,12 +1219,10 @@ INLINE void set_ksl_wave_fb(int chan,int v) /*carrier*/ SLOT = &CH->SLOT[SLOT2]; - int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ - - SLOT->ksl = ksl ? 3-ksl : 31; - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - SLOT->wavetable = ((v&0x10)>>4)*SIN_LEN; + v >>= 6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ + SLOT->ksl = v ? 3-v : 31; + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); } /* set attack rate & decay rate */ @@ -1533,6 +1531,7 @@ static void OPLLWriteReg(int r, int v) /* update */ if(CH->block_fnum != block_fnum) { + UINT8 block; CH->block_fnum = block_fnum; /* BLK 2,1,0 bits -> bits 3,2,1 of kcode, FNUM MSB -> kcode LSB */ @@ -1541,7 +1540,7 @@ static void OPLLWriteReg(int r, int v) CH->ksl_base = ksl_tab[block_fnum>>5]; block_fnum = block_fnum * 2; - UINT8 block = (block_fnum&0x1c00) >> 10; + block = (block_fnum&0x1c00) >> 10; CH->fc = ym2413.fn_tab[block_fnum&0x03ff] >> (7-block); /* refresh Total Level in both SLOTs of this channel */ diff --git a/source/sound/ym2612.c b/source/sound/ym2612.c index f6fd5e9..cf0d44f 100644 --- a/source/sound/ym2612.c +++ b/source/sound/ym2612.c @@ -244,7 +244,7 @@ O( 0),O( 1),O( 2),O( 3), O( 0),O( 1),O( 2),O( 3), */ O(18),O(18),O( 0),O( 0), -O( 0),O( 0),O( 2),O( 2), // Nemesis's tests +O( 0),O( 0),O( 2),O( 2), /* Nemesis's tests */ O( 0),O( 1),O( 2),O( 3), O( 0),O( 1),O( 2),O( 3), @@ -986,9 +986,9 @@ INLINE void set_ar_ksr(FM_CH *CH,FM_SLOT *SLOT,int v) } /* Even if it seems unnecessary to do it here, it could happen that KSR and KC */ - /* but the resulted SLOT->ksr value (kc >> SLOT->KSR) remains unchanged. */ + /* are modified but the resulted SLOT->ksr value (kc >> SLOT->KSR) remains unchanged. */ /* In such case, Attack Rate would not be recalculated by "refresh_fc_eg_slot". */ - /* This fixes the intro of "The Adventures of Batman & Robin" (Eke-Eke) */ + /* This actually fixes the intro of "The Adventures of Batman & Robin" (Eke-Eke) */ if ((SLOT->ar + SLOT->ksr) < (32+62)) { SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; @@ -1287,16 +1287,18 @@ INLINE void update_phase_lfo_slot(FM_SLOT *SLOT , INT32 pms, UINT32 block_fnum) if (lfo_fn_table_index_offset) /* LFO phase modulation active */ { - block_fnum = block_fnum*2 + lfo_fn_table_index_offset; + UINT8 blk; + int kc, fc; - UINT8 blk = (block_fnum&0x7000) >> 12; + block_fnum = block_fnum*2 + lfo_fn_table_index_offset; + blk = (block_fnum&0x7000) >> 12; block_fnum = block_fnum & 0xfff; /* keyscale code */ - int kc = (blk<<2) | opn_fktable[block_fnum >> 8]; + kc = (blk<<2) | opn_fktable[block_fnum >> 8]; /* (frequency) phase increment counter */ - int fc = (ym2612.OPN.fn_table[block_fnum]>>(7-blk)) + SLOT->DT[kc]; + fc = (ym2612.OPN.fn_table[block_fnum]>>(7-blk)) + SLOT->DT[kc]; /* (frequency) phase overflow (credits to Nemesis) */ if (fc < 0) fc += ym2612.OPN.fn_max; @@ -1318,19 +1320,21 @@ INLINE void update_phase_lfo_channel(FM_CH *CH) if (lfo_fn_table_index_offset) /* LFO phase modulation active */ { + UINT8 blk; + int kc, fc, finc; + block_fnum = block_fnum*2 + lfo_fn_table_index_offset; - - UINT8 blk = (block_fnum&0x7000) >> 12; + blk = (block_fnum&0x7000) >> 12; block_fnum = block_fnum & 0xfff; /* keyscale code */ - int kc = (blk<<2) | opn_fktable[block_fnum >> 8]; + kc = (blk<<2) | opn_fktable[block_fnum >> 8]; /* (frequency) phase increment counter */ - int fc = (ym2612.OPN.fn_table[block_fnum]>>(7-blk)); + fc = (ym2612.OPN.fn_table[block_fnum]>>(7-blk)); /* (frequency) phase overflow (credits to Nemesis) */ - int finc = fc + CH->SLOT[SLOT1].DT[kc]; + finc = fc + CH->SLOT[SLOT1].DT[kc]; if (finc < 0) finc += ym2612.OPN.fn_max; CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1; @@ -1435,12 +1439,11 @@ INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm) INLINE void chan_calc(FM_CH *CH) { UINT32 AM = ym2612.OPN.LFO_AM >> CH->ams; + unsigned int eg_out = volume_calc(&CH->SLOT[SLOT1]); m2 = c1 = c2 = mem = 0; *CH->mem_connect = CH->mem_value; /* restore delayed sample (MEM) value to m2 or c2 */ - - unsigned int eg_out = volume_calc(&CH->SLOT[SLOT1]); { INT32 out = CH->op1_out[0] + CH->op1_out[1]; CH->op1_out[0] = CH->op1_out[1]; @@ -1720,7 +1723,7 @@ INLINE void OPNWriteReg(int r, int v) ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7]; /* phase increment counter */ ym2612.OPN.SL3.fc[c] = ym2612.OPN.fn_table[fn*2]>>(7-blk); - ym2612.OPN.SL3.block_fnum[c] = (blk<<11) | fn; //fn; + ym2612.OPN.SL3.block_fnum[c] = (blk<<11) | fn; ym2612.CH[2].SLOT[SLOT1].Incr=-1; } break; @@ -2136,7 +2139,7 @@ void YM2612Update(int *buffer, int length) if (out_fm[5] > 8192) out_fm[5] = 8192; else if (out_fm[5] < -8192) out_fm[5] = -8192; - /* 6-channels mixing */ + /* 6-channels stereo mixing */ lt = ((out_fm[0]) & ym2612.OPN.pan[0]); rt = ((out_fm[0]) & ym2612.OPN.pan[1]); lt += ((out_fm[1]) & ym2612.OPN.pan[2]); @@ -2215,14 +2218,13 @@ void YM2612Restore(unsigned char *buffer) int YM2612LoadContext(unsigned char *state) { + int c,s; + uint8 index; int bufferptr = sizeof(YM2612); /* restore YM2612 context */ YM2612Restore(state); - int c,s; - uint8 index; - /* restore DT table address pointer for each channel slots */ for( c = 0 ; c < 6 ; c++ ) { diff --git a/source/types.h b/source/types.h index ae0d511..1d7c464 100644 --- a/source/types.h +++ b/source/types.h @@ -1,6 +1,9 @@ #undef uint8 #undef uint16 #undef uint32 +#undef int8 +#undef int16 +#undef int32 #define uint8 unsigned char #define uint16 unsigned short @@ -8,3 +11,8 @@ #define int8 signed char #define int16 signed short #define int32 signed int + +/* C89 compatibility */ +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327 +#endif diff --git a/source/vdp_ctrl.c b/source/vdp_ctrl.c index 38baeae..cfea3f1 100644 --- a/source/vdp_ctrl.c +++ b/source/vdp_ctrl.c @@ -42,7 +42,7 @@ #include "shared.h" #include "hvc.h" -/* Mark a pattern as dirty */ +/* Mark a pattern as modified */ #define MARK_BG_DIRTY(addr) \ { \ name = (addr >> 5) & 0x7FF; \ @@ -73,7 +73,6 @@ uint16 hscb; /* Horizontal scroll table base address */ uint8 bg_name_dirty[0x800]; /* 1= This pattern is dirty */ uint16 bg_name_list[0x800]; /* List of modified pattern indices */ uint16 bg_list_index; /* # of modified patterns in list */ -uint8 bg_pattern_cache[0x80000]; /* Cached and flipped patterns */ uint8 hscroll_mask; /* Horizontal Scrolling line mask */ uint8 playfield_shift; /* Width of planes A, B (in bits) */ uint8 playfield_col_mask; /* Playfield column mask */ @@ -139,7 +138,6 @@ static const uint16 vc_table[4][2] = {0x106, 0x10A} /* Mode 5 (240 lines) */ }; - /*--------------------------------------------------------------------------*/ /* Function prototypes */ /*--------------------------------------------------------------------------*/ @@ -162,7 +160,6 @@ static void vdp_dma_copy(int length); static void vdp_dma_vbus(int length); static void vdp_dma_fill(unsigned int data, int length); - /*--------------------------------------------------------------------------*/ /* Init, reset, context functions */ /*--------------------------------------------------------------------------*/ @@ -196,6 +193,8 @@ void vdp_init(void) void vdp_reset(void) { + int i; + memset ((char *) sat, 0, sizeof (sat)); memset ((char *) vram, 0, sizeof (vram)); memset ((char *) cram, 0, sizeof (cram)); @@ -235,11 +234,10 @@ void vdp_reset(void) sat_base_mask = 0xFE00; sat_addr_mask = 0x01FF; - /* clear pattern cache */ + /* reset pattern cache changes */ bg_list_index = 0; memset ((char *) bg_name_dirty, 0, sizeof (bg_name_dirty)); memset ((char *) bg_name_list, 0, sizeof (bg_name_list)); - memset ((char *) bg_pattern_cache, 0, sizeof (bg_pattern_cache)); /* default HVC */ hvc_latch = 0x10000; @@ -284,7 +282,7 @@ void vdp_reset(void) /* default rendering mode */ update_bg_pattern_cache = update_bg_pattern_cache_m4; - if (system_hw < SYSTEM_SMS) + if (system_hw < SYSTEM_MD) { /* Mode 0 */ render_bg = render_bg_m0; @@ -299,11 +297,11 @@ void vdp_reset(void) parse_satb = parse_satb_m4; } - /* default 68k bus access mode (Mode 4) */ + /* 68k bus access mode (Mode 4 by default) */ vdp_68k_data_w = vdp_68k_data_w_m4; vdp_68k_data_r = vdp_68k_data_r_m4; - /* default Z80 bus access mode */ + /* Z80 bus access mode */ switch (system_hw) { case SYSTEM_SG: @@ -344,12 +342,12 @@ void vdp_reset(void) if (system_hw == SYSTEM_SG) { - /* disable H-INT */ + /* no H-INT on TMS9918 */ vdp_reg_w(10, 0xFF, 0); } - else if ((system_hw > SYSTEM_MARKIII) && (system_hw < SYSTEM_MD)) + else if ((system_hw & SYSTEM_SMS) && ((config.bios & (SYSTEM_SMS | 0x01)) != (SYSTEM_SMS | 0x01))) { - /* initialize registers normally set by Master System BIOS */ + /* force registers initialization (if not done by Master System BIOS) */ vdp_reg_w(0 , 0x36, 0); vdp_reg_w(1 , 0x80, 0); vdp_reg_w(2 , 0xFF, 0); @@ -358,10 +356,15 @@ void vdp_reset(void) vdp_reg_w(5 , 0xFF, 0); vdp_reg_w(6 , 0xFF, 0); vdp_reg_w(10, 0xFF, 0); + + /* Mode 4 */ + render_bg = render_bg_m4; + render_obj = render_obj_m4; + parse_satb = parse_satb_m4; } - else if ((system_hw != SYSTEM_PBC) && (config.tmss == 1)) + else if ((system_hw == SYSTEM_MD) && ((config.bios & (SYSTEM_MD | 0x01)) == 0x01)) { - /* initialize registers if BIOS is simulated */ + /* force registers initialization on TMSS model (if not done by BOOT ROM) */ vdp_reg_w(0 , 0x04, 0); vdp_reg_w(1 , 0x04, 0); vdp_reg_w(10, 0xFF, 0); @@ -370,7 +373,6 @@ void vdp_reset(void) } /* reset color palette */ - int i; for(i = 0; i < 0x20; i ++) { color_update_m4(i, 0x00); @@ -401,7 +403,7 @@ int vdp_context_save(uint8 *state) return bufferptr; } -int vdp_context_load(uint8 *state, char *version) +int vdp_context_load(uint8 *state) { int i, bufferptr = 0; uint8 temp_reg[0x20]; @@ -419,11 +421,6 @@ int vdp_context_load(uint8 *state, char *version) load_param(&dmafill, sizeof(dmafill)); load_param(&hint_pending, sizeof(hint_pending)); load_param(&vint_pending, sizeof(vint_pending)); - if ((version[11] <= 0x31) && (version[13] <= 0x35)) - { - uint8 dummy; - load_param(&dummy, sizeof(dummy)); - } load_param(&dma_length, sizeof(dma_length)); load_param(&dma_type, sizeof(dma_type)); load_param(&cached_write, sizeof(cached_write)); @@ -522,7 +519,7 @@ int vdp_context_load(uint8 *state, char *version) void vdp_dma_update(unsigned int cycles) { - int dma_cycles; + int dma_cycles, dma_bytes; /* DMA transfer rate (bytes per line) @@ -570,7 +567,7 @@ void vdp_dma_update(unsigned int cycles) } /* Remaining DMA bytes for that line */ - int dma_bytes = (dma_cycles * rate) / MCYCLES_PER_LINE; + dma_bytes = (dma_cycles * rate) / MCYCLES_PER_LINE; #ifdef LOGVDP error("[%d(%d)][%d(%d)] DMA type %d (%d access/line)(%d cycles left)-> %d access (%d remaining) (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE,dma_type/4, rate, dma_cycles, dma_bytes, dma_length, m68k_get_reg(M68K_REG_PC)); @@ -856,7 +853,7 @@ void vdp_z80_ctrl_w(unsigned int data) { case 2: { - /* VRAM write operation only (Williams Greatest Hits after soft reset) */ + /* VRAM write operation only */ if ((code & 0x0F) == 1) { /* VRAM fill will be triggered by next write to DATA port */ @@ -933,17 +930,14 @@ void vdp_sms_ctrl_w(unsigned int data) if (code == 2) { - /* VDP register index (0-15) */ - data &= 0x0F; - /* Save current VDP mode */ - int prev = (reg[0] & 0x06) | (reg[1] & 0x18); + int mode, prev = (reg[0] & 0x06) | (reg[1] & 0x18); - /* Write VDP register */ - vdp_reg_w(data, addr_latch, mcycles_z80); + /* Write VDP register 0-15 */ + vdp_reg_w(data & 0x0F, addr_latch, mcycles_z80); /* Check VDP mode changes */ - int mode = (reg[0] & 0x06) | (reg[1] & 0x18); + mode = (reg[0] & 0x06) | (reg[1] & 0x18); prev ^= mode; if (prev) @@ -1072,6 +1066,8 @@ void vdp_sms_ctrl_w(unsigned int data) /* Mode switching */ if (prev & 0x04) { + int i; + if (mode & 0x04) { /* Mode 4 sprites */ @@ -1092,7 +1088,6 @@ void vdp_sms_ctrl_w(unsigned int data) } /* reinitialize palette */ - int i; for(i = 0; i < 0x20; i ++) { color_update_m4(i, *(uint16 *)&cram[i << 1]); @@ -1221,6 +1216,7 @@ void vdp_tms_ctrl_w(unsigned int data) */ unsigned int vdp_68k_ctrl_r(unsigned int cycles) { + unsigned int temp; /* Update FIFO flags */ vdp_fifo_update(cycles); @@ -1232,7 +1228,7 @@ unsigned int vdp_68k_ctrl_r(unsigned int cycles) } /* Return VDP status */ - unsigned int temp = status; + temp = status; /* Clear pending flag */ pending = 0; @@ -1261,15 +1257,17 @@ unsigned int vdp_68k_ctrl_r(unsigned int cycles) unsigned int vdp_z80_ctrl_r(unsigned int cycles) { + unsigned int temp; + + /* Cycle-accurate SOVR & VINT flags */ + int line = (lines_per_frame + (cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; + /* Update DMA Busy flag (Mega Drive VDP specific) */ if ((system_hw & SYSTEM_MD) && (status & 2) && !dma_length && (cycles >= dma_endCycles)) { status &= 0xFD; } - /* Cycle-accurate SOVR & VINT flags */ - int line = (lines_per_frame + (mcycles_z80 / MCYCLES_PER_LINE) - 1) % lines_per_frame; - /* Check if we are already on next line */ if (line > v_counter) { @@ -1287,7 +1285,7 @@ unsigned int vdp_z80_ctrl_r(unsigned int cycles) } /* Return VDP status */ - unsigned int temp = status; + temp = status; /* Clear pending flag */ pending = 0; @@ -1358,16 +1356,42 @@ unsigned int vdp_z80_ctrl_r(unsigned int cycles) unsigned int vdp_hvc_r(unsigned int cycles) { - /* VCounter */ - int vc = (cycles / MCYCLES_PER_LINE) - 1; + int vc; + unsigned int temp = hvc_latch; - /* Check counter overflow */ + /* Check if HVC is frozen */ + if (!temp) + { + /* Cycle-accurate HCounter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */ + temp = hctab[cycles % MCYCLES_PER_LINE]; + } + else + { + if (reg[1] & 4) + { + /* Mode 5: both counters are frozen (Lightgun games, Sunset Riders) */ +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, hvc_latch & 0xffff, m68k_get_reg(M68K_REG_PC)); +#endif + return (temp & 0xffff); + } + else + { + /* Mode 4: VCounter runs normally, HCounter is frozen */ + temp &= 0xff; + } + } + + /* Cycle-accurate VCounter (cycle counter starts from line -1) */ + vc = (cycles / MCYCLES_PER_LINE) - 1; + + /* VCounter overflow */ if (vc > vc_max) { vc -= lines_per_frame; } - /* Check interlaced modes */ + /* Interlaced modes */ if (interlaced) { /* Interlace mode 2 (Sonic the Hedgehog 2, Combat Cars) */ @@ -1377,29 +1401,8 @@ unsigned int vdp_hvc_r(unsigned int cycles) vc = (vc & ~1) | ((vc >> 8) & 1); } - /* Returned value */ - unsigned int temp = (vc & 0xff) << 8; - - /* Check if HVC is frozen */ - if (!hvc_latch) - { - /* Cycle-accurate HCounter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */ - temp |= hctab[cycles % MCYCLES_PER_LINE]; - } - else - { - if (reg[1] & 4) - { - /* Mode 5: both counters are frozen (Lightgun games, Sunset Riders) */ - temp = hvc_latch & 0xffff; - } - else - { - /* Mode 4: VCounter runs normally, HCounter is frozen */ - temp |= (hvc_latch & 0xff); - } - } - + temp |= ((vc & 0xff) << 8); + #ifdef LOGVDP error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, temp, m68k_get_reg(M68K_REG_PC)); #endif @@ -1881,6 +1884,8 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles) case 8: /* Horizontal Scroll (Mode 4 only) */ { + int line; + /* Hscroll is latched at HCount 0xF3, HCount 0xF6 on MD */ /* Line starts at HCount 0xF4, HCount 0xF6 on MD */ if (system_hw < SYSTEM_MD) @@ -1889,7 +1894,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles) } /* Make sure Hscroll has not already been latched */ - int line = (lines_per_frame + (cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; + line = (lines_per_frame + (cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; if ((line > v_counter) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) { v_counter = line; @@ -2092,21 +2097,18 @@ static void vdp_bus_w(unsigned int data) { case 0x01: /* VRAM */ { -#ifdef LOGVDP - error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); -#endif - /* Byte-swap data if A0 is set */ - if (addr & 1) - { - data = ((data >> 8) | (data << 8)) & 0xFFFF; - } - /* VRAM address */ int index = addr & 0xFFFE; /* Pointer to VRAM */ uint16 *p = (uint16 *)&vram[index]; + /* Byte-swap data if A0 is set */ + if (addr & 1) + { + data = ((data >> 8) | (data << 8)) & 0xFFFF; + } + /* Intercept writes to Sprite Attribute Table */ if ((index & sat_base_mask) == satb) { @@ -2117,21 +2119,23 @@ static void vdp_bus_w(unsigned int data) /* Only write unique data to VRAM */ if (data != *p) { + int name; + /* Write data to VRAM */ *p = data; /* Update pattern cache */ - int name; MARK_BG_DIRTY (index); } + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif break; } case 0x03: /* CRAM */ { -#ifdef LOGVDP - error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); -#endif /* Pointer to CRAM 9-bit word */ uint16 *p = (uint16 *)&cram[addr & 0x7E]; @@ -2141,12 +2145,12 @@ static void vdp_bus_w(unsigned int data) /* Check if CRAM data is being modified */ if (data != *p) { - /* Write CRAM data */ - *p = data; - /* CRAM index (64 words) */ int index = (addr >> 1) & 0x3F; + /* Write CRAM data */ + *p = data; + /* Color entry 0 of each palette is never displayed (transparent pixel) */ if (index & 0x0F) { @@ -2167,14 +2171,14 @@ static void vdp_bus_w(unsigned int data) remap_line(v_counter); } } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif break; } case 0x05: /* VSRAM */ { -#ifdef LOGVDP - error("[%d(%d)][%d(%d)] VSRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); -#endif *(uint16 *)&vsram[addr & 0x7E] = data; /* 2-cell Vscroll mode */ @@ -2187,16 +2191,19 @@ static void vdp_bus_w(unsigned int data) render_line(v_counter); } } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VSRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif break; } -#ifdef LOGERROR default: { +#ifdef LOGERROR error("[%d(%d)][%d(%d)] Unknown (%d) 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE-1, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif break; } -#endif } /* Increment address register (TODO: see how address is incremented in Mode 4) */ @@ -2269,26 +2276,27 @@ static void vdp_68k_data_w_m4(unsigned int data) } else { - /* Byte-swap data if A0 is set */ - if (addr & 1) - { - data = ((data >> 8) | (data << 8)) & 0xFFFF; - } - /* VRAM address (interleaved format) */ int index = ((addr << 1) & 0x3FC) | ((addr & 0x200) >> 8) | (addr & 0x3C00); /* Pointer to VRAM */ uint16 *p = (uint16 *)&vram[index]; + /* Byte-swap data if A0 is set */ + if (addr & 1) + { + data = ((data >> 8) | (data << 8)) & 0xFFFF; + } + /* Only write unique data to VRAM */ if (data != *p) { + int name; + /* Write data to VRAM */ *p = data; /* Update the pattern cache */ - int name; MARK_BG_DIRTY (index); } } @@ -2354,12 +2362,12 @@ static void vdp_68k_data_w_m5(unsigned int data) static unsigned int vdp_68k_data_r_m4(void) { - /* Clear pending flag */ - pending = 0; - /* VRAM address (interleaved format) */ int index = ((addr << 1) & 0x3FC) | ((addr & 0x200) >> 8) | (addr & 0x3C00); + /* Clear pending flag */ + pending = 0; + /* Increment address register */ addr += (reg[15] + 1); @@ -2472,11 +2480,12 @@ static void vdp_z80_data_w_m4(unsigned int data) /* Only write unique data to VRAM */ if (data != vram[index]) { + int name; + /* Write data */ vram[index] = data; /* Update pattern cache */ - int name; MARK_BG_DIRTY(index); } } @@ -2508,11 +2517,12 @@ static void vdp_z80_data_w_m5(unsigned int data) /* Only write unique data to VRAM */ if (data != READ_BYTE(vram, index)) { + int name; + /* Write data */ WRITE_BYTE(vram, index, data); /* Update pattern cache */ - int name; MARK_BG_DIRTY (index); } break; @@ -2538,12 +2548,12 @@ static void vdp_z80_data_w_m5(unsigned int data) /* Check if CRAM data is being modified */ if (data != *p) { - /* Write CRAM data */ - *p = data; - /* CRAM index (64 words) */ int index = (addr >> 1) & 0x3F; + /* Write CRAM data */ + *p = data; + /* Color entry 0 of each palette is never displayed (transparent pixel) */ if (index & 0x0F) { @@ -2594,12 +2604,12 @@ static void vdp_z80_data_w_m5(unsigned int data) static unsigned int vdp_z80_data_r_m4(void) { - /* Clear pending flag */ - pending = 0; - /* Read buffer */ unsigned int data = fifo[0]; + /* Clear pending flag */ + pending = 0; + /* Process next read */ fifo[0] = vram[addr & 0x3FFF]; @@ -2671,6 +2681,8 @@ static void vdp_z80_data_w_ms(unsigned int data) if (code < 3) { + int index; + /* check if we are already on next line */ int line = (lines_per_frame + (mcycles_z80 / MCYCLES_PER_LINE) - 1) % lines_per_frame; if ((line > v_counter) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) @@ -2680,25 +2692,26 @@ static void vdp_z80_data_w_ms(unsigned int data) } /* VRAM address */ - int index = addr & 0x3FFF; + index = addr & 0x3FFF; #ifdef LOGVDP error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); #endif /* VRAM write */ - if(data != vram[index]) + if (data != vram[index]) { int name; vram[index] = data; MARK_BG_DIRTY(index); } + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); +#endif } else { -#ifdef LOGVDP - error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l); -#endif /* CRAM address */ int index = addr & 0x1F; @@ -2720,6 +2733,9 @@ static void vdp_z80_data_w_ms(unsigned int data) color_update_m4(0x40, data); } } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l); +#endif } /* Update read buffer */ @@ -2736,6 +2752,8 @@ static void vdp_z80_data_w_gg(unsigned int data) if (code < 3) { + int index; + /* check if we are already on next line*/ int line = (lines_per_frame + (mcycles_z80 / MCYCLES_PER_LINE) - 1) % lines_per_frame; if ((line > v_counter) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) @@ -2745,38 +2763,41 @@ static void vdp_z80_data_w_gg(unsigned int data) } /* VRAM address */ - int index = addr & 0x3FFF; + index = addr & 0x3FFF; #ifdef LOGVDP error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); #endif /* VRAM write */ - if(data != vram[index]) + if (data != vram[index]) { int name; vram[index] = data; MARK_BG_DIRTY(index); } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); +#endif } else { - if(addr & 1) + if (addr & 1) { - /* 12-bit data word */ - data = (data << 8) | cached_write; - /* Pointer to CRAM word */ uint16 *p = (uint16 *)&cram[addr & 0x3E]; + /* 12-bit data word */ + data = (data << 8) | cached_write; + /* Check if CRAM data is being modified */ if (data != *p) { - /* Write CRAM data */ - *p = data; - /* Color index (0-31) */ int index = (addr >> 1) & 0x1F; + + /* Write CRAM data */ + *p = data; /* Update color palette */ color_update_m4(index, data); @@ -2793,6 +2814,9 @@ static void vdp_z80_data_w_gg(unsigned int data) /* Latch LSB */ cached_write = data; } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l); +#endif } /* Update read buffer */ @@ -2804,12 +2828,12 @@ static void vdp_z80_data_w_gg(unsigned int data) static void vdp_z80_data_w_sg(unsigned int data) { - /* Clear pending flag */ - pending = 0; - /* VRAM address */ int index = addr & 0x3FFF; + /* Clear pending flag */ + pending = 0; + /* 4K address decoding (cf. tms9918a.txt) */ if (!(reg[1] & 0x80)) { @@ -2821,6 +2845,10 @@ static void vdp_z80_data_w_sg(unsigned int data) /* Update address register */ addr++; + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_z80/MCYCLES_PER_LINE-1, mcycles_z80, mcycles_z80%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); +#endif } /*--------------------------------------------------------------------------*/ diff --git a/source/vdp_ctrl.h b/source/vdp_ctrl.h index dbc1bf9..4422830 100644 --- a/source/vdp_ctrl.h +++ b/source/vdp_ctrl.h @@ -62,7 +62,6 @@ extern uint16 hscb; extern uint8 bg_name_dirty[0x800]; extern uint16 bg_name_list[0x800]; extern uint16 bg_list_index; -extern uint8 bg_pattern_cache[0x80000]; extern uint8 hscroll_mask; extern uint8 playfield_shift; extern uint8 playfield_col_mask; @@ -90,7 +89,7 @@ extern unsigned int (*vdp_z80_data_r)(void); extern void vdp_init(void); extern void vdp_reset(void); extern int vdp_context_save(uint8 *state); -extern int vdp_context_load(uint8 *state, char *version); +extern int vdp_context_load(uint8 *state); extern void vdp_dma_update(unsigned int cycles); extern void vdp_68k_ctrl_w(unsigned int data); extern void vdp_z80_ctrl_w(unsigned int data); diff --git a/source/vdp_render.c b/source/vdp_render.c index acacfaf..d6dfa0d 100644 --- a/source/vdp_render.c +++ b/source/vdp_render.c @@ -539,6 +539,9 @@ static const uint32 tms_palette[16] = }; #endif +/* Cached and flipped patterns */ +static uint8 bg_pattern_cache[0x80000]; + /* Sprite pattern name offset look-up table (Mode 5) */ static uint8 name_lut[0x400]; @@ -738,13 +741,15 @@ static uint32 make_lut_bg_ste(uint32 bx, uint32 ax) /* Output: d5-d0=color, d6=priority, d7=sprite pixel marker */ static uint32 make_lut_obj(uint32 bx, uint32 sx) { + int c; + int bf = (bx & 0x7F); int bs = (bx & 0x80); int sf = (sx & 0x7F); if((sx & 0x0F) == 0) return bx; - int c = (bs ? bf : sf); + c = (bs ? bf : sf); /* Strip palette bits from transparent pixels */ if((c & 0x0F) == 0x00) c &= 0xC0; @@ -758,6 +763,8 @@ static uint32 make_lut_obj(uint32 bx, uint32 sx) /* Output: d5-d0=color, d6=zero/priority, d7=opaque sprite pixel marker */ static uint32 make_lut_bgobj(uint32 bx, uint32 sx) { + int c; + int bf = (bx & 0x3F); int bs = (bx & 0x80); int bp = (bx & 0x40); @@ -772,7 +779,7 @@ static uint32 make_lut_bgobj(uint32 bx, uint32 sx) /* Previous sprite has higher priority */ if(bs) return bx; - int c = (sp ? sf : (bp ? (b ? bf : sf) : sf)); + c = (sp ? sf : (bp ? (b ? bf : sf) : sf)); /* Strip palette & priority bits from transparent pixels */ if((c & 0x0F) == 0x00) c &= 0x80; @@ -914,6 +921,8 @@ static uint32 make_lut_bgobj_ste(uint32 bx, uint32 sx) /* Output: d3-d0=color, d4=palette, d5=zero/priority, d6=zero, d7=sprite pixel marker */ static uint32 make_lut_bgobj_m4(uint32 bx, uint32 sx) { + int c; + int bf = (bx & 0x3F); int bs = (bx & 0x80); int bp = (bx & 0x20); @@ -929,7 +938,7 @@ static uint32 make_lut_bgobj_m4(uint32 bx, uint32 sx) if(bs) return bx; /* note: priority bit is always 0 for Modes 0,1,2,3 */ - int c = (bp ? (b ? bf : sf) : sf); + c = (bp ? (b ? bf : sf) : sf); return (c | 0x80); } @@ -939,7 +948,7 @@ static uint32 make_lut_bgobj_m4(uint32 bx, uint32 sx) /* Pixel layer merging function */ /*--------------------------------------------------------------------------*/ -static inline void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width) +static __inline__ void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width) { do { @@ -1207,8 +1216,13 @@ void render_bg_m1(int line, int width) void render_bg_m1x(int line, int width) { uint8 pattern; + uint8 *pg; + uint8 color = reg[7]; + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line >> 3) * 40)]; + uint16 pg_mask = ~0x3800 ^ (reg[4] << 11); /* Unused bits used as a mask on TMS9918 & 315-5124 VDP only */ @@ -1217,9 +1231,7 @@ void render_bg_m1x(int line, int width) pg_mask |= 0x1800; } - uint8 *lb = &linebuf[0][0x20]; - uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line >> 3) * 40)]; - uint8 *pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + (line & 7)]; + pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + (line & 7)]; /* Left border (8 pixels) */ memset (lb, 0x40, 8); @@ -1250,6 +1262,10 @@ void render_bg_m2(int line, int width) { uint8 color, pattern; uint16 name; + uint8 *ct, *pg; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; uint16 ct_mask = ~0x3FC0 ^ (reg[3] << 6); uint16 pg_mask = ~0x3800 ^ (reg[4] << 11); @@ -1261,10 +1277,8 @@ void render_bg_m2(int line, int width) pg_mask |= 0x1800; } - uint8 *lb = &linebuf[0][0x20]; - uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; - uint8 *ct = &vram[((0x2000 + ((line & 0xC0) << 5)) & ct_mask) + (line & 7)]; - uint8 *pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + (line & 7)]; + ct = &vram[((0x2000 + ((line & 0xC0) << 5)) & ct_mask) + (line & 7)]; + pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + (line & 7)]; /* 32 x 8 pixels */ width = 32; @@ -1322,6 +1336,10 @@ void render_bg_m3x(int line, int width) { uint8 color; uint16 name; + uint8 *pg; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; uint16 pg_mask = ~0x3800 ^ (reg[4] << 11); @@ -1331,9 +1349,7 @@ void render_bg_m3x(int line, int width) pg_mask |= 0x1800; } - uint8 *lb = &linebuf[0][0x20]; - uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; - uint8 *pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + ((line >> 2) & 7)]; + pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + ((line >> 2) & 7)]; /* 32 x 8 pixels */ width = 32; @@ -1398,6 +1414,9 @@ void render_bg_m4(int line, int width) /* Background line buffer */ uint32 *dst = (uint32 *)&linebuf[0][0x20 + shift]; + /* Vertical scrolling */ + int v_line = line + vscroll; + /* Pattern name table mask */ uint16 nt_mask = ~0x3C00 ^ (reg[2] << 10); @@ -1407,9 +1426,6 @@ void render_bg_m4(int line, int width) nt_mask |= 0x400; } - /* Vertical scrolling */ - int v_line = line + vscroll; - /* Test for extended modes (Master System II & Game gear VDP only) */ if (bitmap.viewport.h > 192) { @@ -1499,6 +1515,13 @@ void render_bg_m5(int line, int width) /* Common data */ uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; uint32 yscroll = *(uint32 *)&vsram[0]; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; /* Plane B width */ int start = 0; @@ -1507,16 +1530,16 @@ void render_bg_m5(int line, int width) /* Plane B scroll */ #ifdef LSB_FIRST uint32 shift = (xscroll >> 16) & 0x0F; - uint32 index = playfield_col_mask + 1 - ((xscroll >> 20) & playfield_col_mask); - uint32 v_line = (line + ((yscroll >> 16) & 0x3FF)) & playfield_row_mask; + uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); + uint32 v_line = (line + ((yscroll >> 16) & 0x3FF)) & pf_row_mask; #else uint32 shift = (xscroll & 0x0F); - uint32 index = playfield_col_mask + 1 - ((xscroll >> 4) & playfield_col_mask); - uint32 v_line = (line + (yscroll & 0x3FF)) & playfield_row_mask; + uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); + uint32 v_line = (line + (yscroll & 0x3FF)) & pf_row_mask; #endif /* Plane B name table */ - uint32 *nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << playfield_shift) & 0x1FC0)]; + uint32 *nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; /* Pattern row index */ v_line = (v_line & 7) << 3; @@ -1526,7 +1549,7 @@ void render_bg_m5(int line, int width) /* Plane B line buffer */ dst = (uint32 *)&linebuf[0][0x10 + shift]; - atbuf = nt[(index - 1) & playfield_col_mask]; + atbuf = nt[(index - 1) & pf_col_mask]; DRAW_COLUMN(atbuf, v_line) } else @@ -1537,14 +1560,10 @@ void render_bg_m5(int line, int width) for(column = 0; column < end; column++, index++) { - atbuf = nt[index & playfield_col_mask]; + atbuf = nt[index & pf_col_mask]; DRAW_COLUMN(atbuf, v_line) } - /* Window & Plane A */ - int a = (reg[18] & 0x1F) << 3; - int w = (reg[18] >> 7) & 1; - if (w == (line >= a)) { /* Window takes up entire line */ @@ -1568,16 +1587,16 @@ void render_bg_m5(int line, int width) /* Plane A scroll */ #ifdef LSB_FIRST shift = (xscroll & 0x0F); - index = playfield_col_mask + start + 1 - ((xscroll >> 4) & playfield_col_mask); - v_line = (line + (yscroll & 0x3FF)) & playfield_row_mask; + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + (yscroll & 0x3FF)) & pf_row_mask; #else shift = (xscroll >> 16) & 0x0F; - index = playfield_col_mask + start + 1 - ((xscroll >> 20) & playfield_col_mask); - v_line = (line + ((yscroll >> 16) & 0x3FF)) & playfield_row_mask; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + ((yscroll >> 16) & 0x3FF)) & pf_row_mask; #endif /* Plane A name table */ - nt = (uint32 *)&vram[ntab + (((v_line >> 3) << playfield_shift) & 0x1FC0)]; + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; /* Pattern row index */ v_line = (v_line & 7) << 3; @@ -1590,11 +1609,11 @@ void render_bg_m5(int line, int width) /* Window bug */ if (start) { - atbuf = nt[index & playfield_col_mask]; + atbuf = nt[index & pf_col_mask]; } else { - atbuf = nt[(index - 1) & playfield_col_mask]; + atbuf = nt[(index - 1) & pf_col_mask]; } DRAW_COLUMN(atbuf, v_line) @@ -1607,7 +1626,7 @@ void render_bg_m5(int line, int width) for(column = start; column < end; column++, index++) { - atbuf = nt[index & playfield_col_mask]; + atbuf = nt[index & pf_col_mask]; DRAW_COLUMN(atbuf, v_line) } @@ -1650,6 +1669,10 @@ void render_bg_m5_vs(int line, int width) uint32 pf_shift = playfield_shift; uint32 *vs = (uint32 *)&vsram[0]; + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; + /* Plane B width */ int start = 0; int end = width >> 4; @@ -1663,9 +1686,10 @@ void render_bg_m5_vs(int line, int width) uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); #endif - /* Left-most column vertical scrolling when partially shown horizontally */ - /* Same value for both planes, only in 40-cell mode, verified on PAL MD2 */ - /* See Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge */ + /* Left-most column vertical scrolling when partially shown horizontally (verified on PAL MD2) */ + /* TODO: check on Genesis 3 models since it apparently behaves differently */ + /* In H32 mode, vertical scrolling is disabled, in H40 mode, same value is used for both planes */ + /* See Formula One / Kawasaki Superbike Challenge (H32) & Gynoug / Cutie Suzuki no Ringside Angel (H40) */ if (reg[12] & 1) { yscroll = vs[19] & (vs[19] >> 16); @@ -1714,10 +1738,6 @@ void render_bg_m5_vs(int line, int width) DRAW_COLUMN(atbuf, v_line) } - /* Window & Plane A */ - int a = (reg[18] & 0x1F) << 3; - int w = (reg[18] >> 7) & 1; - if (w == (line >= a)) { /* Window takes up entire line */ @@ -1829,13 +1849,16 @@ void render_bg_m5_im2(int line, int width) uint32 atex, atbuf, *src, *dst; /* Common data */ + int odd = odd_frame; uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; uint32 yscroll = *(uint32 *)&vsram[0]; uint32 pf_col_mask = playfield_col_mask; uint32 pf_row_mask = playfield_row_mask; uint32 pf_shift = playfield_shift; - int odd = odd_frame; + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; /* Plane B width */ int start = 0; @@ -1878,10 +1901,6 @@ void render_bg_m5_im2(int line, int width) DRAW_COLUMN_IM2(atbuf, v_line) } - /* Window & Plane A */ - int a = (reg[18] & 0x1F) << 3; - int w = (reg[18] >> 7) & 1; - if (w == (line >= a)) { /* Window takes up entire line */ @@ -1980,6 +1999,7 @@ void render_bg_m5_im2_vs(int line, int width) uint32 v_line, *nt; /* Common data */ + int odd = odd_frame; uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; uint32 yscroll = 0; uint32 pf_col_mask = playfield_col_mask; @@ -1987,7 +2007,9 @@ void render_bg_m5_im2_vs(int line, int width) uint32 pf_shift = playfield_shift; uint32 *vs = (uint32 *)&vsram[0]; - int odd = odd_frame; + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; /* Plane B width */ int start = 0; @@ -2002,12 +2024,12 @@ void render_bg_m5_im2_vs(int line, int width) uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); #endif - /* Left-most column vertical scrolling when partially shown horizontally */ - /* Same value for both planes, only in 40-cell mode, verified on PAL MD2 */ - /* See Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge */ + /* Left-most column vertical scrolling when partially shown horizontally (verified on PAL MD2) */ + /* TODO: check on Genesis 3 models since it apparently behaves differently */ + /* In H32 mode, vertical scrolling is disabled, in H40 mode, same value is used for both planes */ + /* See Formula One / Kawasaki Superbike Challenge (H32) & Gynoug / Cutie Suzuki no Ringside Angel (H40) */ if (reg[12] & 1) { - /* only in 40-cell mode, verified on MD2 */ yscroll = (vs[19] >> 1) & (vs[19] >> 17); yscroll &= 0x3FF; } @@ -2054,10 +2076,6 @@ void render_bg_m5_im2_vs(int line, int width) DRAW_COLUMN_IM2(atbuf, v_line) } - /* Window & Plane A */ - int a = (reg[18] & 0x1F) << 3; - int w = (reg[18] >> 7) & 1; - if (w == (line >= a)) { /* Window takes up entire line */ @@ -3007,6 +3025,9 @@ void render_obj_m4(int max_width) /* Default sprite width */ int width = 8; + + /* Sprite Generator address mask (LSB is masked for 8x16 sprites) */ + uint16 sg_mask = (~0x1C0 ^ (reg[6] << 6)) & (~((reg[1] & 0x02) >> 1)); /* Zoomed sprites (not working on Genesis VDP) */ if (system_hw < SYSTEM_MD) @@ -3014,9 +3035,6 @@ void render_obj_m4(int max_width) width <<= (reg[1] & 0x01); } - /* Sprite Generator address mask (LSB is masked for 8x16 sprites) */ - uint16 sg_mask = (~0x1C0 ^ (reg[6] << 6)) & (~((reg[1] & 0x02) >> 1)); - /* Unused bits used as a mask on 315-5124 VDP only */ if (system_hw > SYSTEM_SMS) { @@ -3555,82 +3573,79 @@ void render_obj_m5_im2_ste(int max_width) void parse_satb_tms(int line) { - if (reg[1] & 0x10) - { - /* no sprites in Text modes */ - object_count = 0; - return; - } - int i = 0; - /* Pointer to sprite attribute table */ - uint8 *st = &vram[(reg[5] << 7) & 0x3F80]; - /* Sprite counter (4 max. per line) */ int count = 0; - /* Y position */ - int ypos; - - /* Sprite height (8 pixels by default) */ - int height = 8; - - /* Adjust height for 16x16 sprites */ - height <<= ((reg[1] & 0x02) >> 1); - - /* Adjust height for zoomed sprites */ - height <<= (reg[1] & 0x01); - - /* Parse Sprite Table (32 entries) */ - do + /* no sprites in Text modes */ + if (!(reg[1] & 0x10)) { - /* Sprite Y position */ - ypos = st[i << 2]; + /* Pointer to sprite attribute table */ + uint8 *st = &vram[(reg[5] << 7) & 0x3F80]; - /* Check end of sprite list marker */ - if (ypos == 0xD0) + /* Y position */ + int ypos; + + /* Sprite height (8 pixels by default) */ + int height = 8; + + /* Adjust height for 16x16 sprites */ + height <<= ((reg[1] & 0x02) >> 1); + + /* Adjust height for zoomed sprites */ + height <<= (reg[1] & 0x01); + + /* Parse Sprite Table (32 entries) */ + do { - break; - } + /* Sprite Y position */ + ypos = st[i << 2]; - /* Wrap Y coordinate for sprites > 256-32 */ - if (ypos >= 224) - { - ypos -= 256; - } - - /* Y range */ - ypos = line - ypos; - - /* Sprite is visble on this line ? */ - if ((ypos >= 0) && (ypos < height)) - { - /* Sprite overflow */ - if (count == 4) + /* Check end of sprite list marker */ + if (ypos == 0xD0) { - /* Flag is set only during active area */ - if (line < bitmap.viewport.h) - { - spr_ovr = 0x40; - } break; } - /* Adjust Y range back for zoomed sprites */ - ypos >>= (reg[1] & 0x01); + /* Wrap Y coordinate for sprites > 256-32 */ + if (ypos >= 224) + { + ypos -= 256; + } - /* Store sprite attributes for later processing */ - object_info[count].ypos = ypos; - object_info[count].xpos = st[(i << 2) + 1]; - object_info[count].attr = st[(i << 2) + 2]; - object_info[count].size = st[(i << 2) + 3]; + /* Y range */ + ypos = line - ypos; - /* Increment Sprite count */ - ++count; + /* Sprite is visble on this line ? */ + if ((ypos >= 0) && (ypos < height)) + { + /* Sprite overflow */ + if (count == 4) + { + /* Flag is set only during active area */ + if (line < bitmap.viewport.h) + { + spr_ovr = 0x40; + } + break; + } + + /* Adjust Y range back for zoomed sprites */ + ypos >>= (reg[1] & 0x01); + + /* Store sprite attributes for later processing */ + object_info[count].ypos = ypos; + object_info[count].xpos = st[(i << 2) + 1]; + object_info[count].attr = st[(i << 2) + 2]; + object_info[count].size = st[(i << 2) + 3]; + + /* Increment Sprite count */ + ++count; + } } + while (++i < 32); } - while (++i < 32); /* Update sprite count for next line */ object_count = count; @@ -3642,6 +3657,7 @@ void parse_satb_tms(int line) void parse_satb_m4(int line) { int i = 0; + uint8 *st; /* Sprite counter (8 max. per line) */ int count = 0; @@ -3649,11 +3665,8 @@ void parse_satb_m4(int line) /* Y position */ int ypos; - /* Sprite height (8x8 by default) */ - int height = 8; - - /* Adjust height for 8x16 sprites */ - height <<= ((reg[1] & 0x02) >> 1); + /* Sprite height (8x8 or 8x16) */ + int height = 8 + ((reg[1] & 0x02) << 2); /* Sprite attribute table address mask */ uint16 st_mask = ~0x3F80 ^ (reg[5] << 7); @@ -3665,7 +3678,7 @@ void parse_satb_m4(int line) } /* Pointer to sprite attribute table */ - uint8 *st = &vram[st_mask & 0x3F00]; + st = &vram[st_mask & 0x3F00]; /* Parse Sprite Table (64 entries) */ do @@ -3674,7 +3687,7 @@ void parse_satb_m4(int line) ypos = st[i]; /* Check end of sprite list marker */ - if(ypos == (bitmap.viewport.h + 16)) + if (ypos == (bitmap.viewport.h + 16)) { break; } @@ -3927,15 +3940,15 @@ void window_clip(unsigned int data, unsigned int sw) int hp = (data & 0x1f); int hf = (data >> 7) & 1; - /* Display width (16 or 20 columns) */ - sw = 16 + (sw << 2); - /* Perform horizontal clipping; the results are applied in reverse if the horizontal inversion flag is set */ int a = hf; int w = hf ^ 1; + /* Display width (16 or 20 columns) */ + sw = 16 + (sw << 2); + if(hp) { if(hp > sw) @@ -4012,6 +4025,9 @@ void render_reset(void) /* Clear color palettes */ memset(pixel, 0, sizeof(pixel)); + /* Clear pattern cache */ + memset ((char *) bg_pattern_cache, 0, sizeof (bg_pattern_cache)); + /* Reset Sprite infos */ spr_ovr = spr_col = object_count = 0; } @@ -4024,6 +4040,7 @@ void render_reset(void) void render_line(int line) { int width = bitmap.viewport.w; + int x_offset; /* Check display status */ if (reg[1] & 0x40) @@ -4074,7 +4091,7 @@ void render_line(int line) } /* Horizontal borders */ - int x_offset = bitmap.viewport.x; + x_offset = bitmap.viewport.x; if (x_offset > 0) { memset(&linebuf[0][0x20 - x_offset], 0x40, x_offset); @@ -4094,8 +4111,10 @@ void blank_line(int line, int offset, int width) void remap_line(int line) { /* Line width */ - int x_offset = bitmap.viewport.x; - int width = bitmap.viewport.w + (x_offset * 2); + int width = bitmap.viewport.w + (bitmap.viewport.x * 2); + + /* Pixel line buffer */ + uint8 *src = &linebuf[0][0x20 - bitmap.viewport.x]; /* Adjust line offset in framebuffer */ line = (line + bitmap.viewport.y) % lines_per_frame; @@ -4109,9 +4128,6 @@ void remap_line(int line) line = (line * 2) + odd_frame; } - /* Pixel line buffer */ - uint8 *src = &linebuf[0][0x20 - x_offset]; - /* NTSC Filter (only supported for 16-bit pixels rendering) */ #ifdef USE_16BPP_RENDERING if (config.ntsc)