fixed C89 remaining incompatibilities + various code cleanup

This commit is contained in:
ekeeke31 2012-01-15 19:59:13 +00:00
parent 238382d8a8
commit 09c02fd693
35 changed files with 780 additions and 762 deletions

View File

@ -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<size; i+=0x1000)
{
fread(action_replay.rom+i,0x1000,1,f);
i += 0x1000;
fread(action_replay.rom + i, 0x1000, 1, f);
}
#ifdef LSB_FIRST
/* Byteswap ROM */
uint8 temp;
for(i = 0; i < size; i += 2)
for (i= 0; i<size; i+=2)
{
temp = action_replay.rom[i];
/* Byteswap ROM */
uint8 temp = action_replay.rom[i];
action_replay.rom[i] = action_replay.rom[i+1];
action_replay.rom[i+1] = temp;
}
#endif
}
/* Close ROM file */
fclose(f);
}

View File

@ -45,7 +45,7 @@ typedef enum
WAIT_START,
GET_OPCODE,
WRITE_WORD,
READ_WORD,
READ_WORD
} T_STATE;

View File

@ -59,45 +59,40 @@ static void ggenie_write_regs(unsigned int offset, unsigned int data);
void ggenie_init(void)
{
int i;
FILE *f;
memset(&ggenie,0,sizeof(ggenie));
/* Open Game Genie ROM file */
FILE *f = fopen(GG_ROM,"rb");
if (!f) return;
/* Store Game Genie ROM above cartridge ROM + SRAM */
if (cart.romsize > 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;

View File

@ -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)
{

View File

@ -48,7 +48,7 @@ typedef enum
GET_WORD_ADR_HIGH,
GET_WORD_ADR_LOW,
WRITE_DATA,
READ_DATA,
READ_DATA
} T_EEPROM_STATE;

View File

@ -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

View File

@ -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;

View File

@ -13,7 +13,6 @@
#include "shared.h"
svp_t *svp = NULL;
int16 SVP_cycles = 800;
void svp_init(void)
{

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -42,7 +42,6 @@
#define _FILEIO_H_
/* Function prototypes */
void get_zipfilename(char *filename);
int load_archive(char *filename);
#endif /* _FILEIO_H_ */

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -114,7 +114,7 @@ typedef enum
#endif
/* Convenience registers */
M68K_REG_IR, /* Instruction register */
M68K_REG_IR /* Instruction register */
} m68k_register_t;

View File

@ -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) */

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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 )

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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 <stdio.h>
#include <string.h>
#include <math.h>
#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);
}

View File

@ -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__ */

View File

@ -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);
}
blip_read_samples(blip, buffer, length);
}

View File

@ -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 */

View File

@ -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++ )
{

View File

@ -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

View File

@ -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
}
/*--------------------------------------------------------------------------*/

View File

@ -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);

View File

@ -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)