mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 03:31:49 +01:00
fixed C89 remaining incompatibilities + various code cleanup
This commit is contained in:
parent
238382d8a8
commit
09c02fd693
@ -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);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ typedef enum
|
||||
WAIT_START,
|
||||
GET_OPCODE,
|
||||
WRITE_WORD,
|
||||
READ_WORD,
|
||||
READ_WORD
|
||||
|
||||
} T_STATE;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ typedef enum
|
||||
GET_WORD_ADR_HIGH,
|
||||
GET_WORD_ADR_LOW,
|
||||
WRITE_DATA,
|
||||
READ_DATA,
|
||||
READ_DATA
|
||||
|
||||
} T_EEPROM_STATE;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "shared.h"
|
||||
|
||||
svp_t *svp = NULL;
|
||||
int16 SVP_cycles = 800;
|
||||
|
||||
void svp_init(void)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -42,7 +42,6 @@
|
||||
#define _FILEIO_H_
|
||||
|
||||
/* Function prototypes */
|
||||
void get_zipfilename(char *filename);
|
||||
int load_archive(char *filename);
|
||||
|
||||
#endif /* _FILEIO_H_ */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -114,7 +114,7 @@ typedef enum
|
||||
#endif
|
||||
|
||||
/* Convenience registers */
|
||||
M68K_REG_IR, /* Instruction register */
|
||||
M68K_REG_IR /* Instruction register */
|
||||
} m68k_register_t;
|
||||
|
||||
|
||||
|
@ -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) */
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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++ )
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user