Merge git://github.com/ekeeke/Genesis-Plus-GX

Conflicts:
	source/system.c
This commit is contained in:
Twinaphex 2012-07-26 13:12:06 +02:00
commit d28fe8ee29
28 changed files with 686 additions and 503 deletions

@ -6,124 +6,142 @@
#
# Defines :
# -DLSB_FIRST : for little endian systems.
# -DBUILD_TABLES: do not use const tables for 68k instructions (obsolete)
# -DLOGERROR : enable message logging
# -DLOGVDP : enable VDP debug messages
# -DLOG_SCD : enable SCD debug messages
# -DLOG_CDD : enable CDD debug messages
# -DLOG_CDC : enable CDC debug messages
# -DLOG_PCM : enable PCM debug messages
# -DLOGSOUND : enable AUDIO debug messages
# -D8BPP_RENDERING - configure for 8-bit pixels (RGB332)
# -D15BPP_RENDERING - configure for 15-bit pixels (RGB555)
# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565)
# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888)
# -D8BPP_RENDERING - configure for 8-bit pixels (RGB332)
# -D15BPP_RENDERING - configure for 15-bit pixels (RGB555)
# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565)
# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888)
NAME = gen_sdl.exe
CC = gcc
CFLAGS = `sdl-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing
CFLAGS = `sdl-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing -ansi -std=c89 -pedantic-errors
#-ansi -pedantic-errors
#-g -ggdb -pg
#-fomit-frame-pointer
#LDFLAGS = -pg
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING
INCLUDES = -Isource -Isource/z80 -Isource/m68k -Isource/sound -Isource/input_hw -Isource/cart_hw -Isource/cart_hw/svp -Isource/ntsc -Isource/win
LDFLAGS =
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING -DLOGERROR -DLOG_CDC -DLOG_CDD -DLOG_SCD -DLOGVDP -DLOG_PCM
INCLUDES = -I. -I.. -I../z80 -I../m68k -I../sound -I../input_hw -I../cart_hw -I../cd_hw -I../cart_hw/svp -I../ntsc
LIBS = `sdl-config --libs` -lz -lm
OBJDIR = ./build_sdl
OBJECTS = obj/z80.o
OBJECTS = $(OBJDIR)/z80.o
OBJECTS += obj/m68kcpu.o \
obj/s68kcpu.o \
OBJECTS += $(OBJDIR)/m68kcpu.o
OBJECTS += obj/genesis.o \
obj/vdp_ctrl.o \
obj/vdp_render.o \
obj/system.o \
obj/io_ctrl.o \
obj/mem68k.o \
obj/memz80.o \
obj/membnk.o \
obj/state.o
OBJECTS += $(OBJDIR)/genesis.o \
$(OBJDIR)/vdp_ctrl.o \
$(OBJDIR)/vdp_render.o \
$(OBJDIR)/system.o \
$(OBJDIR)/io_ctrl.o \
$(OBJDIR)/mem68k.o \
$(OBJDIR)/memz80.o \
$(OBJDIR)/membnk.o \
$(OBJDIR)/state.o \
$(OBJDIR)/loadrom.o
OBJECTS += obj/input.o \
obj/gamepad.o \
obj/lightgun.o \
obj/mouse.o \
obj/activator.o \
obj/xe_a1p.o \
obj/teamplayer.o \
obj/paddle.o \
obj/sportspad.o \
obj/terebi_oekaki.o
OBJECTS += $(OBJDIR)/input.o \
$(OBJDIR)/gamepad.o \
$(OBJDIR)/lightgun.o \
$(OBJDIR)/mouse.o \
$(OBJDIR)/activator.o \
$(OBJDIR)/xe_a1p.o \
$(OBJDIR)/teamplayer.o \
$(OBJDIR)/paddle.o \
$(OBJDIR)/sportspad.o \
$(OBJDIR)/terebi_oekaki.o
OBJECTS += $(OBJDIR)/sound.o \
$(OBJDIR)/sn76489.o \
$(OBJDIR)/ym2413.o \
$(OBJDIR)/ym2612.o
OBJECTS += obj/sound.o \
obj/sn76489.o \
obj/ym2413.o \
obj/ym2612.o
OBJECTS += $(OBJDIR)/Fir_Resampler.o
OBJECTS += $(OBJDIR)/blip.o
OBJECTS += $(OBJDIR)/eq.o
OBJECTS += obj/Fir_Resampler.o
OBJECTS += obj/blip.o
OBJECTS += $(OBJDIR)/sram.o \
$(OBJDIR)/svp.o \
$(OBJDIR)/ssp16.o \
$(OBJDIR)/ggenie.o \
$(OBJDIR)/areplay.o \
$(OBJDIR)/gg_eeprom.o \
$(OBJDIR)/md_eeprom.o \
$(OBJDIR)/md_cart.o \
$(OBJDIR)/sms_cart.o
OBJECTS += obj/eq.o \
OBJECTS += $(OBJDIR)/sms_ntsc.o \
$(OBJDIR)/md_ntsc.o
OBJECTS += obj/sram.o \
obj/svp.o \
obj/ssp16.o \
obj/ggenie.o \
obj/areplay.o \
obj/gg_eeprom.o \
obj/md_eeprom.o \
obj/md_cart.o \
obj/sms_cart.o
OBJECTS += $(OBJDIR)/main.o \
$(OBJDIR)/config.o \
$(OBJDIR)/error.o \
$(OBJDIR)/unzip.o \
$(OBJDIR)/fileio.o
OBJECTS += obj/scd.o \
obj/cdd.o \
obj/cdc.o \
obj/gfx.o \
obj/pcm.o \
obj/cd_cart.o
OBJECTS += $(OBJDIR)/icon.o
OBJECTS += obj/main.o \
obj/config.o \
obj/error.o \
obj/unzip.o \
obj/fileio.o \
obj/loadrom.o
OBJECTS += obj/sms_ntsc.o \
obj/md_ntsc.o
OBJECTS += obj/icon.o
all: $(NAME)
$(NAME): $(OBJDIR) $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
$(NAME): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ -Wl,-Map,genplus.map
$(OBJDIR) :
@[ -d $@ ] || mkdir -p $@
$(OBJDIR)/%.o : source/%.c source/%.h
obj/%.o : ../%.c ../%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/sound/%.c source/sound/%.h
obj/%.o : ../asm/%.s
$(AS) $< -o $@
obj/%.o : ../sound/%.c ../sound/%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
obj/%.o : ../sound/%.c
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/input_hw/%.c source/input_hw/%.h
obj/%.o : ../input_hw/%.c ../input_hw/%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/cart_hw/%.c source/cart_hw/%.h
obj/%.o : ../cart_hw/%.c ../cart_hw/%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/cart_hw/svp/%.c
obj/%.o : ../cart_hw/svp/%.c
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
obj/%.o : ../cart_hw/svp/%.c ../cart_hw/svp/%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/cart_hw/svp/%.c source/cart_hw/svp/%.h
obj/%.o : ../cd_hw/%.c
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/z80/%.c source/z80/%.h
obj/%.o : ../z80/%.c ../z80/%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/m68k/%.c source/m68k/%.h
obj/%.o : ../m68k/%.c
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/ntsc/%.c source/ntsc/%.h
obj/%.o : ./%.c ./%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/%.o : source/win/%.c source/win/%.h
obj/%.o : ../ntsc/%.c ../ntsc/%.h
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
$(OBJDIR)/icon.o :
windres source/win/icon.rc $@
obj/icon.o :
windres icon.rc $@
pack :
strip $(NAME)

@ -249,10 +249,10 @@ void cd_cart_init(void)
m68k.memory_map[i].base = scd.cartridge.area + ((i & 0x3f) << 16);
m68k.memory_map[i].read8 = NULL;
m68k.memory_map[i].read16 = NULL;
m68k.memory_map[i].write8 = NULL;
m68k.memory_map[i].write16 = NULL;
m68k.memory_map[i].write8 = m68k_unused_8_w;
m68k.memory_map[i].write16 = m68k_unused_16_w;
zbank_memory_map[i].read = NULL;
zbank_memory_map[i].write = NULL;
zbank_memory_map[i].write = zbank_unused_w;
}
}
}

@ -471,9 +471,6 @@ void cdc_reg_w(unsigned char data)
unsigned char cdc_reg_r(void)
{
#ifdef LOG_CDC
error("CDC register %X read (%X) ", scd.regs[0x04>>1].byte.l & 0x0F, s68k.pc);
#endif
switch (scd.regs[0x04>>1].byte.l & 0x0F)
{
case 0x01: /* IFSTAT */

@ -74,6 +74,15 @@ static const uint16 lut_BCD_16[100] =
0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, 0x0909,
};
static const uint16 toc_snatcher[21] =
{
56164, 495, 10120, 20555, 1580, 5417, 12502, 16090, 6553, 9681,
8148, 20228, 8622, 6142, 5858, 1287, 7424, 3535, 31697, 2485,
31380
};
void cdd_init(void)
{
}
@ -126,33 +135,65 @@ void cdd_load(char *filename, int type_bin)
fseek(cdd.toc.tracks[0].fd, 0, SEEK_SET);
/* initialize TOC */
/* TODO: add 2 seconds pause after data track ? */
cdd.toc.end = cdd.toc.tracks[0].end;
cdd.toc.last = 1;
/* TODO: add audio track support from BIN/CUE, ISO/WAV, MP3, OGG ? */
/* Fake audio tracks if none found */
/* Simulated audio tracks if none found */
if (cdd.toc.last == 1)
{
/* default track duration (fix Snatcher intro) */
int length = 4 * 60 * 75;
/* A-Rank Thunder Tanjouen requires shorter track duration to pass intro */
if (strstr(rominfo.product,"T-49064") != NULL)
/* Some games require specific TOC infos */
if (strstr(rominfo.product,"T-95035") != NULL)
{
length = 2 * 75;
/* Snatcher */
cdd.toc.last = cdd.toc.end = 0;
do
{
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_snatcher[cdd.toc.last];
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
cdd.toc.last++;
}
while (cdd.toc.last < 21);
}
/* max length = 60:02:00 */
do
else if (strstr(rominfo.product,"T-45074") != NULL)
{
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.end + length;
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
cdd.toc.last++;
/* Lunar - Eternal Blue (J) */
cdd.toc.tracks[1].start = cdd.toc.end + 2*75;
cdd.toc.tracks[1].end = cdd.toc.tracks[1].start + 21654;
cdd.toc.end = cdd.toc.tracks[1].end;
cdd.toc.tracks[2].start = cdd.toc.end + 2*75;
cdd.toc.tracks[2].end = cdd.toc.tracks[2].start + 5004;
cdd.toc.end = cdd.toc.tracks[2].end;
cdd.toc.tracks[3].start = cdd.toc.end + 2*75;
cdd.toc.tracks[3].end = cdd.toc.tracks[3].start + 684;
cdd.toc.end = cdd.toc.tracks[3].end;
cdd.toc.last = 4;
}
else if (strstr(rominfo.product,"T-127045") != NULL)
{
/* Lunar - Eternal Blue (U) */
cdd.toc.tracks[1].start = cdd.toc.end + 2*75;
cdd.toc.tracks[1].end = cdd.toc.tracks[1].start + 21735;
cdd.toc.end = cdd.toc.tracks[1].end;
cdd.toc.tracks[2].start = cdd.toc.end + 2*75;
cdd.toc.tracks[2].end = cdd.toc.tracks[2].start + 27131;
cdd.toc.end = cdd.toc.tracks[2].end;
cdd.toc.last = 3;
}
else
{
/* default TOC (99 x 2s) */
do
{
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + 2*75;
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + 2*75;
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
cdd.toc.last++;
}
while ((cdd.toc.last < 99) && (cdd.toc.end < 56*60*75));
}
while (cdd.toc.last <= 54);
}
/* CD loaded */
@ -175,15 +216,15 @@ void cdd_unload(void)
}
}
/* reset TOC */
memset(&cdd.toc, 0x00, sizeof(cdd.toc));
/* CD unloaded */
cdd.loaded = 0;
/* unknown CD image file format */
cdd.sectorSize = 0;
}
/* reset TOC */
memset(&cdd.toc, 0x00, sizeof(cdd.toc));
/* unknown CD image file format */
cdd.sectorSize = 0;
}
void cdd_read(uint8 *dst)
@ -219,19 +260,22 @@ void cdd_update(void)
}
/* track type */
if (cdd.index)
if (cdd.index > 0)
{
/* audio track sector is sent to CD Fader/DAC but also CDD */
cdc_decoder_update(0);
/* next audio track sector is automatically read */
cdd.lba++;
/* check end of current track */
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
if (cdd.index < cdd.toc.last)
{
/* next track */
cdd.index++;
/* audio track sector sent to CD Fader/DAC should also be sent to CDD */
cdc_decoder_update(0);
/* next sector is automatically read */
cdd.lba++;
/* check end of current track */
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
{
/* next track */
cdd.index++;
}
}
}
else
@ -249,7 +293,36 @@ void cdd_update(void)
}
}
/* TODO: handle FAST_FW & FAST_RW commands */
/* fast scanning disc */
else if (cdd.status == CD_SCAN)
{
/* skip track */
cdd.lba += cdd.scanOffset;
/* check current track limits */
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
{
/* next track */
cdd.index++;
}
else if (cdd.lba < cdd.toc.tracks[cdd.index].start)
{
/* previous track */
cdd.index--;
}
/* check disc limits */
if (cdd.index < 0)
{
cdd.index = 0;
cdd.lba = 0;
}
else if (cdd.index >= cdd.toc.last)
{
cdd.index = cdd.toc.last;
cdd.lba = cdd.toc.end;
}
}
}
void cdd_process(void)
@ -303,7 +376,7 @@ void cdd_process(void)
case 0x02: /* Current track */
{
scd.regs[0x38>>1].w = (cdd.status << 8) | 0x02;
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index + 1];
scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A;
scd.regs[0x3c>>1].w = 0x0000;
scd.regs[0x3e>>1].w = 0x0000;
scd.regs[0x40>>1].byte.h = 0x00;
@ -383,7 +456,7 @@ void cdd_process(void)
cdd.lba = lba;
/* update current track index */
while (cdd.toc.tracks[index].end <= lba) index++;
while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++;
cdd.index = index;
/* track type */
@ -405,7 +478,7 @@ void cdd_process(void)
/* update status */
cdd.status = CD_PLAY;
scd.regs[0x38>>1].w = (CD_PLAY << 8) | 0x02;
scd.regs[0x3a>>1].w = lut_BCD_16[index + 1];
scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[index + 1] : 0x0A0A;
scd.regs[0x3c>>1].w = 0x0000;
scd.regs[0x3e>>1].w = 0x0000;
scd.regs[0x40>>1].byte.h = 0x00;
@ -426,7 +499,7 @@ void cdd_process(void)
cdd.lba = lba;
/* update current track index */
while (cdd.toc.tracks[index].end <= lba) index++;
while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++;
cdd.index = index;
/* DATA track */
@ -482,7 +555,7 @@ void cdd_process(void)
/* update status */
cdd.status = CD_PLAY;
scd.regs[0x38>>1].w = (CD_PLAY << 8) | 0x02;
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A;
scd.regs[0x3c>>1].w = 0x0000;
scd.regs[0x3e>>1].w = 0x0000;
scd.regs[0x40>>1].byte.h = 0x00;
@ -491,6 +564,7 @@ void cdd_process(void)
case 0x08: /* Forward Scan */
{
cdd.scanOffset = 10;
cdd.status = CD_SCAN;
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
@ -502,6 +576,7 @@ void cdd_process(void)
case 0x09: /* Rewind Scan */
{
cdd.scanOffset = -10;
cdd.status = CD_SCAN;
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];

@ -67,6 +67,7 @@ typedef struct
int loaded;
int index;
int lba;
int scanOffset;
uint8 status;
uint16 sectorSize;
toc_t toc;

@ -93,38 +93,41 @@ void pcm_update(short *buffer, int length)
/* run eight PCM channels */
for (j=0; j<8; j++)
{
/* check if channel is enabled (bit cleared) */
if (!(pcm.status & (1 << j)))
/* check if channel is enabled */
if (pcm.status & (1 << j))
{
/* read current WAVE RAM address */
/* read from current WAVE RAM address */
short data = pcm.ram[(pcm.chan[j].addr >> 11) & 0xffff];
/* STOP data ? */
/* loop data ? */
if (data == 0xff)
{
/* reset WAVE RAM address with loop address */
/* reset WAVE RAM address */
pcm.chan[j].addr = pcm.chan[j].ls.w << 11;
/* read WAVE RAM address again */
/* read again from WAVE RAM address */
data = pcm.ram[pcm.chan[j].ls.w];
/* no output on infinite loop */
if (data == 0xff) break;
}
/* output L & R subchannels */
if (data & 0x80)
else
{
/* PCM data is negative */
data = -(data & 0x7f);
/* increment WAVE RAM address */
pcm.chan[j].addr += pcm.chan[j].fd.w;
}
/* multiply PCM data with ENV & stereo PAN data then add to outputs (13.6 fixed point) */
l += ((data * pcm.chan[j].env * (pcm.chan[j].pan & 0x0F)) >> 6);
r += ((data * pcm.chan[j].env * (pcm.chan[j].pan >> 4)) >> 6);
/* infinite loop should not output any data */
if (data != 0xff)
{
/* output L & R subchannels */
if (data & 0x80)
{
/* PCM data is negative */
data = -(data & 0x7f);
}
/* increment WAVE RAM address */
pcm.chan[j].addr += pcm.chan[j].fd.w;
/* multiply PCM data with ENV & stereo PAN data then add to outputs (13.6 fixed point) */
l += ((data * pcm.chan[j].env * (pcm.chan[j].pan & 0x0F)) >> 6);
r += ((data * pcm.chan[j].env * (pcm.chan[j].pan >> 4)) >> 6);
}
}
}
@ -175,6 +178,10 @@ void pcm_update(short *buffer, int length)
void pcm_write(unsigned int address, unsigned char data)
{
#ifdef LOG_PCM
error("[%d][%d]PCM %x write -> 0x%02x (%X)\n", v_counter, s68k.cycles, address, data, s68k.pc);
#endif
/* external RAM is mapped to $1000-$1FFF */
if (address >= 0x1000)
{
@ -232,6 +239,12 @@ void pcm_write(unsigned int address, unsigned char data)
{
/* update channel WAVE RAM start address (16.11 fixed point) */
pcm.chan[pcm.index].st = data << (8 + 11);
/* reload WAVE RAM address if channel is OFF */
if (!(pcm.status & (1 << pcm.index)))
{
pcm.chan[pcm.index].addr = pcm.chan[pcm.index].st;
}
return;
}
@ -255,18 +268,18 @@ void pcm_write(unsigned int address, unsigned char data)
case 0x08: /* ON/OFF register */
{
/* reload WAVE RAM address pointers when channels are switched ON (bit cleared) */
if ((pcm.status & 0x01) && !(data & 0x01)) pcm.chan[0].addr = pcm.chan[0].st;
if ((pcm.status & 0x02) && !(data & 0x02)) pcm.chan[1].addr = pcm.chan[1].st;
if ((pcm.status & 0x04) && !(data & 0x04)) pcm.chan[2].addr = pcm.chan[2].st;
if ((pcm.status & 0x08) && !(data & 0x08)) pcm.chan[3].addr = pcm.chan[3].st;
if ((pcm.status & 0x10) && !(data & 0x10)) pcm.chan[4].addr = pcm.chan[4].st;
if ((pcm.status & 0x20) && !(data & 0x20)) pcm.chan[5].addr = pcm.chan[5].st;
if ((pcm.status & 0x40) && !(data & 0x40)) pcm.chan[6].addr = pcm.chan[6].st;
if ((pcm.status & 0x80) && !(data & 0x80)) pcm.chan[7].addr = pcm.chan[7].st;
/* update PCM channels status */
pcm.status = data;
pcm.status = ~data;
/* reload WAVE RAM address pointers when channels are OFF */
if (data & 0x01) pcm.chan[0].addr = pcm.chan[0].st;
if (data & 0x02) pcm.chan[1].addr = pcm.chan[1].st;
if (data & 0x04) pcm.chan[2].addr = pcm.chan[2].st;
if (data & 0x08) pcm.chan[3].addr = pcm.chan[3].st;
if (data & 0x10) pcm.chan[4].addr = pcm.chan[4].st;
if (data & 0x20) pcm.chan[5].addr = pcm.chan[5].st;
if (data & 0x40) pcm.chan[6].addr = pcm.chan[6].st;
if (data & 0x80) pcm.chan[7].addr = pcm.chan[7].st;
return;
}
@ -280,6 +293,10 @@ void pcm_write(unsigned int address, unsigned char data)
unsigned char pcm_read(unsigned int address)
{
#ifdef LOG_PCM
error("[%d][%d]PCM %x read (%X)\n", v_counter, s68k.cycles, address, s68k.pc);
#endif
/* external RAM (TODO: verify if possible to read, some docs claim it's not !) */
if (address >= 0x1000)
{
@ -294,7 +311,7 @@ unsigned char pcm_read(unsigned int address)
if (address & 1)
{
return pcm.chan[index].addr >> (11 + 8);
return (pcm.chan[index].addr >> (11 + 8)) & 0xff;
}
else
{

@ -190,6 +190,9 @@ INLINE void s68k_poll_detect(reg)
if (s68k.pc == s68k.poll.pc)
{
/* stop SUB-CPU until register is modified by MAIN-CPU */
#ifdef LOG_SCD
error("s68k stopped from %d cycles\n", s68k.cycles);
#endif
s68k.cycles = s68k.cycle_end;
s68k.stopped = 1 << reg;
}
@ -226,6 +229,9 @@ INLINE void s68k_poll_sync(reg)
/* restart MAIN-CPU */
m68k.stopped = 0;
#ifdef LOG_SCD
error("m68k started from %d cycles\n", cycles);
#endif
}
/* clear CPU register(s) access flags */
@ -269,6 +275,9 @@ static unsigned int scd_read_byte(unsigned int address)
if (address == 0xff8007)
{
unsigned int data = cdc_reg_r();
#ifdef LOG_CDC
error("CDC register %X read 0x%02X (%X) ", scd.regs[0x04>>1].byte.l & 0x0F, data, s68k.pc);
#endif
return data;
}
@ -412,6 +421,7 @@ INLINE void word_ram_switch(uint8 mode)
if (mode & 0x04)
{
/* 2M -> 1M mode */
for (i=0; i<0x10000; i++)
{
*ptr2++=*ptr1++;
@ -420,11 +430,43 @@ INLINE void word_ram_switch(uint8 mode)
}
else
{
/* 1M -> 2M mode */
for (i=0; i<0x10000; i++)
{
*ptr1++=*ptr2++;
*ptr1++=*ptr3++;
}
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
{
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
m68k.memory_map[i].read8 = NULL;
m68k.memory_map[i].read16 = NULL;
m68k.memory_map[i].write8 = NULL;
m68k.memory_map[i].write16 = NULL;
zbank_memory_map[i].read = NULL;
zbank_memory_map[i].write = NULL;
}
for (i=0x08; i<0x0c; i++)
{
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
s68k.memory_map[i].read8 = NULL;
s68k.memory_map[i].read16 = NULL;
s68k.memory_map[i].write8 = NULL;
s68k.memory_map[i].write16 = NULL;
}
for (i=0x0c; i<0x0e; i++)
{
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
s68k.memory_map[i].read8 = s68k_read_bus_8;
s68k.memory_map[i].read16 = s68k_read_bus_16;
s68k.memory_map[i].write8 = s68k_unused_8_w;
s68k.memory_map[i].write16 = s68k_unused_16_w;
}
}
}
@ -471,12 +513,12 @@ static void scd_write_byte(unsigned int address, unsigned int data)
case 0x03: /* Memory Mode */
{
s68k_poll_sync(0x02);
/* detect MODE & RET bits modifications */
if ((data ^ scd.regs[0x03 >> 1].byte.l) & 0x05)
{
int i;
s68k_poll_sync(0x02);
/* MODE bit */
if (data & 0x04)
@ -485,7 +527,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
if (!(scd.regs[0x03 >> 1].byte.l & 0x04))
{
/* re-arrange Word-RAM banks */
word_ram_switch(data);
word_ram_switch(0x04);
}
/* RET bit in 1M Mode */
@ -501,7 +543,6 @@ static void scd_write_byte(unsigned int address, unsigned int data)
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
{
/* VRAM cell image mapped at $220000-$23FFFF */
m68k.memory_map[i].base = NULL;
m68k.memory_map[i].read8 = cell_ram_1_read8;
m68k.memory_map[i].read16 = cell_ram_1_read16;
m68k.memory_map[i].write8 = cell_ram_1_write8;
@ -545,7 +586,6 @@ static void scd_write_byte(unsigned int address, unsigned int data)
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
{
/* VRAM cell image mapped at $220000-$23FFFF */
m68k.memory_map[i].base = NULL;
m68k.memory_map[i].read8 = cell_ram_0_read8;
m68k.memory_map[i].read16 = cell_ram_0_read16;
m68k.memory_map[i].write8 = cell_ram_0_write8;
@ -585,38 +625,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
if (scd.regs[0x02 >> 1].byte.l & 0x04)
{
/* re-arrange Word-RAM banks */
word_ram_switch(data);
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
{
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
m68k.memory_map[i].read8 = NULL;
m68k.memory_map[i].read16 = NULL;
m68k.memory_map[i].write8 = NULL;
m68k.memory_map[i].write16 = NULL;
zbank_memory_map[i].read = NULL;
zbank_memory_map[i].write = NULL;
}
for (i=0x08; i<0x0c; i++)
{
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
s68k.memory_map[i].read8 = NULL;
s68k.memory_map[i].read16 = NULL;
s68k.memory_map[i].write8 = NULL;
s68k.memory_map[i].write16 = NULL;
}
for (i=0x0c; i<0x0e; i++)
{
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
s68k.memory_map[i].read8 = s68k_read_bus_8;
s68k.memory_map[i].read16 = s68k_read_bus_16;
s68k.memory_map[i].write8 = s68k_unused_8_w;
s68k.memory_map[i].write16 = s68k_unused_16_w;
}
word_ram_switch(0x00);
/* RET bit set during 1M mode ? */
data |= ~scd.dmna & 0x01;
@ -777,12 +786,12 @@ static void scd_write_word(unsigned int address, unsigned int data)
case 0x02: /* Memory Mode */
{
s68k_poll_sync(0x02);
/* detect MODE & RET bits modifications */
if ((data ^ scd.regs[0x03>>1].byte.l) & 0x05)
{
int i;
s68k_poll_sync(0x02);
/* MODE bit */
if (data & 0x04)
@ -791,7 +800,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
if (!(scd.regs[0x03 >> 1].byte.l & 0x04))
{
/* re-arrange Word-RAM banks */
word_ram_switch(data);
word_ram_switch(0x04);
}
/* RET bit in 1M Mode */
@ -807,7 +816,6 @@ static void scd_write_word(unsigned int address, unsigned int data)
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
{
/* VRAM cell image mapped at $220000-$23FFFF */
m68k.memory_map[i].base = NULL;
m68k.memory_map[i].read8 = cell_ram_1_read8;
m68k.memory_map[i].read16 = cell_ram_1_read16;
m68k.memory_map[i].write8 = cell_ram_1_write8;
@ -851,7 +859,6 @@ static void scd_write_word(unsigned int address, unsigned int data)
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
{
/* VRAM cell image mapped at $220000-$23FFFF */
m68k.memory_map[i].base = NULL;
m68k.memory_map[i].read8 = cell_ram_0_read8;
m68k.memory_map[i].read16 = cell_ram_0_read16;
m68k.memory_map[i].write8 = cell_ram_0_write8;
@ -891,38 +898,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
if (scd.regs[0x03>>1].byte.l & 0x04)
{
/* re-arrange Word-RAM banks */
word_ram_switch(data);
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
{
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
m68k.memory_map[i].read8 = NULL;
m68k.memory_map[i].read16 = NULL;
m68k.memory_map[i].write8 = NULL;
m68k.memory_map[i].write16 = NULL;
zbank_memory_map[i].read = NULL;
zbank_memory_map[i].write = NULL;
}
for (i=0x08; i<0x0c; i++)
{
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
s68k.memory_map[i].read8 = NULL;
s68k.memory_map[i].read16 = NULL;
s68k.memory_map[i].write8 = NULL;
s68k.memory_map[i].write16 = NULL;
}
for (i=0x0c; i<0x0e; i++)
{
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
s68k.memory_map[i].read8 = s68k_read_bus_8;
s68k.memory_map[i].read16 = s68k_read_bus_16;
s68k.memory_map[i].write8 = s68k_unused_8_w;
s68k.memory_map[i].write16 = s68k_unused_16_w;
}
word_ram_switch(0x00);
/* RET bit set during 1M mode ? */
data |= ~scd.dmna & 0x01;
@ -1104,7 +1080,7 @@ void scd_init(void)
/* $240000-$3FFFFF (resp. $400000-$7FFFFF): unused area (Word-RAM mirrored ?) */
for (i=base+0x24; i<base+0x40; i++)
{
m68k.memory_map[i].base = NULL;
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 3) << 16);
m68k.memory_map[i].read8 = m68k_read_bus_8;
m68k.memory_map[i].read16 = m68k_read_bus_16;
m68k.memory_map[i].write8 = m68k_unused_8_w;
@ -1143,10 +1119,10 @@ void scd_init(void)
s68k.memory_map[i].write16 = NULL;
}
/* $0C0000-$FD0000: Unused area */
/* $0C0000-$FD0000: Unused area (Word-RAM mirrored ?) */
for (i=0x0c; i<0xfd; i++)
{
s68k.memory_map[i].base = NULL;
s68k.memory_map[i].base = scd.word_ram_2M + ((i & 3) << 16);
s68k.memory_map[i].read8 = s68k_read_bus_8;
s68k.memory_map[i].read16 = s68k_read_bus_16;
s68k.memory_map[i].write8 = s68k_unused_8_w;
@ -1205,6 +1181,9 @@ void scd_reset(int hard)
/* Power ON initial values (MAIN-CPU side) */
scd.regs[0x00>>1].w = 0x0002;
scd.regs[0x02>>1].w = 0x0001;
/* 2M mode */
word_ram_switch(0);
}
else
{
@ -1697,9 +1676,6 @@ int scd_context_load(uint8 *state)
load_param(&tmp32, 4); s68k_set_reg(M68K_REG_USP,tmp32);
load_param(&tmp32, 4); s68k_set_reg(M68K_REG_ISP,tmp32);
/* update IRQ level */
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
return bufferptr;
}

@ -258,8 +258,21 @@ void gen_reset(int hard_reset)
/* 8-bit / 16-bit modes */
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
/* reset cartridge hardware & mapping */
md_cart_reset(hard_reset);
if (system_hw == SYSTEM_MCD)
{
/* reset CD hardware */
scd_reset(1);
/* reset & halt SUB-CPU */
s68k.cycles = 0;
s68k_pulse_reset();
s68k_pulse_halt();
}
else
{
/* reset MD cartridge hardware */
md_cart_reset(hard_reset);
}
/* Z80 bus is released & Z80 is reseted */
m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
@ -301,17 +314,6 @@ void gen_reset(int hard_reset)
}
}
if (system_hw == SYSTEM_MCD)
{
/* reset CD hardware */
scd_reset(1);
/* reset & halt SUB-CPU */
s68k.cycles = 0;
s68k_pulse_reset();
s68k_pulse_halt();
}
/* reset MAIN-CPU */
m68k_pulse_reset();
}
@ -348,7 +350,7 @@ void gen_tmss_w(unsigned int offset, unsigned int data)
WRITE_WORD(tmss, offset, data);
/* VDP requires "SEGA" value to be written in TMSS register */
if (strncmp((char *)tmss, "SEGA", 4) == 0)
if (memcmp((char *)tmss, "SEGA", 4) == 0)
{
for (i=0xc0; i<0xe0; i+=8)
{
@ -376,21 +378,29 @@ void gen_tmss_w(unsigned int offset, unsigned int data)
void gen_bankswitch_w(unsigned int data)
{
if (data & 1)
if (system_hw == SYSTEM_MD)
{
/* enable cartridge ROM */
m68k.memory_map[0].base = cart.base;
}
else
{
/* enable internal BOOT ROM */
m68k.memory_map[0].base = boot_rom;
if (data & 1)
{
/* enable cartridge ROM */
m68k.memory_map[0].base = cart.base;
}
else
{
/* enable internal BOOT ROM */
m68k.memory_map[0].base = boot_rom;
}
}
}
unsigned int gen_bankswitch_r(void)
{
return (m68k.memory_map[0].base == cart.base);
if (system_hw == SYSTEM_MD)
{
return (m68k.memory_map[0].base == cart.base);
}
return 0xff;
}

@ -61,7 +61,7 @@ static int config_load(void)
char version[16];
fseek(fp, 0, SEEK_SET);
fread(version, 16, 1, fp);
if (strncmp(version,CONFIG_VERSION,16))
if (memcmp(version,CONFIG_VERSION,16))
{
fclose(fp);
return 0;

@ -108,12 +108,17 @@ void slot_autoload(int slot, int device)
/* update CRC */
brm_crc[0] = crc32(0, scd.bram, 0x2000);
}
else
{
/* force internal backup RAM format (does not use previous region backup RAM) */
scd.bram[0x1fff] = 0;
}
/* check if internal backup RAM is correctly formatted */
if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20))
{
/* clear internal backup RAM */
memset(scd.bram, 0x00, 0x200);
memset(scd.bram, 0x00, 0x2000 - 0x40);
/* internal Backup RAM size fields */
brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00;
@ -121,6 +126,9 @@ void slot_autoload(int slot, int device)
/* format internal backup RAM */
memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40);
/* clear CRC to force file saving (in case previous region backup RAM was also formatted) */
brm_crc[0] = 0;
}
/* automatically load cartridge backup RAM (if enabled) */
@ -129,7 +137,24 @@ void slot_autoload(int slot, int device)
fp = fopen(CART_BRAM, "rb");
if (fp != NULL)
{
fread(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp);
int filesize = scd.cartridge.mask + 1;
int done = 0;
/* Read into buffer (2k blocks) */
while (filesize > CHUNKSIZE)
{
fread(scd.cartridge.area + done, CHUNKSIZE, 1, fp);
done += CHUNKSIZE;
filesize -= CHUNKSIZE;
}
/* Read remaining bytes */
if (filesize)
{
fread(scd.cartridge.area + done, filesize, 1, fp);
}
/* close file */
fclose(fp);
/* update CRC */
@ -194,7 +219,24 @@ void slot_autosave(int slot, int device)
FILE *fp = fopen(CART_BRAM, "wb");
if (fp != NULL)
{
fwrite(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp);
int filesize = scd.cartridge.mask + 1;
int done = 0;
/* Write to file (2k blocks) */
while (filesize > CHUNKSIZE)
{
fwrite(scd.cartridge.area + done, CHUNKSIZE, 1, fp);
done += CHUNKSIZE;
filesize -= CHUNKSIZE;
}
/* Write remaining bytes */
if (filesize)
{
fwrite(scd.cartridge.area + done, filesize, 1, fp);
}
/* Close file */
fclose(fp);
/* update CRC */
@ -622,6 +664,9 @@ int slot_save(int slot, int device)
fclose(fp);
free(buffer);
/* Close message box */
GUI_MsgBoxClose();
/* Save state screenshot */
if (slot > 0)
{
@ -768,8 +813,10 @@ int slot_save(int slot, int device)
CARD_Unmount(device);
free(out);
free(buffer);
}
GUI_MsgBoxClose();
/* Close message box */
GUI_MsgBoxClose();
}
return 1;
}

@ -83,37 +83,7 @@ static inline u16 FLIP16 (u16 b)
return c;
}
void get_zipfilename(char *filename)
{
char in[CHUNKSIZE];
/* Open file */
FILE *fd = fopen(filename, "rb");
if (!fd) return;
/* Read first 2 bytes */
fread(in, 2, 1, fd);
/* Detect Zip file */
if (memcmp(in, "PK", 2) == 0)
{
/* Read remaining header data */
fread(in + 2, sizeof(PKZIPHEADER) - 2, 1, fd);
/* Zip header pointer */
PKZIPHEADER *pkzip = (PKZIPHEADER *) in;
/* Return compressed file name */
int len = FLIP16(pkzip->filenameLength);
if (len >= MAXPATHLEN) len = MAXPATHLEN - 1;
fread(filename, len, 1, fd);
filename[len] = 0;
}
fclose(fd);
}
int load_archive(char *filename, unsigned char *buffer, int maxsize)
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
{
int size = 0;
char in[CHUNKSIZE];
@ -132,7 +102,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
/* Mega CD BIOS are required files */
if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP))
{
sprintf(msg,"Unable to open CD BIOS");
sprintf(msg,"Unable to open %s", filename + 14);
}
if (!fd)
@ -187,19 +157,23 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
return 0;
}
/* Compressed filename offset */
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength);
if (extension)
{
memcpy(extension, &in[offset - 3], 3);
extension[3] = 0;
}
/* Initial Zip buffer offset */
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength) + FLIP16(pkzip->extraDataLength);
offset += FLIP16(pkzip->extraDataLength);
zs.next_in = (Bytef *)&in[offset];
/* Initial Zip remaining chunk size */
zs.avail_in = CHUNKSIZE - offset;
/* Overwrite input filename with compressed filename */
offset = FLIP16(pkzip->filenameLength);
if (offset >= MAXPATHLEN) offset = MAXPATHLEN - 1;
strncpy(filename, &in[sizeof(PKZIPHEADER)], offset);
filename[offset] = 0;
/* Start unzipping file */
do
{
@ -255,6 +229,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
sprintf((char *)msg,"Loading %d bytes ...", size);
GUI_MsgBoxOpen("Information", (char *)msg, 1);
/* filename extension */
if (extension)
{
memcpy(extension, &filename[strlen(filename) - 3], 3);
extension[3] = 0;
}
/* Read into buffer */
int left = size;
while (left > CHUNKSIZE)

@ -42,6 +42,6 @@
#define _FILEIO_H_
/* Function prototypes */
int load_archive(char *filename, unsigned char *buffer, int maxsize);
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
#endif /* _FILEIO_H_ */

@ -52,8 +52,8 @@
extern const u8 Key_Minus_wii_png[];
extern const u8 Key_Plus_wii_png[];
#else
extern const u8 Key_L_gcn_png[];
extern const u8 Key_R_gcn_png[];
extern const u8 Key_L_gcn_png[];
#endif
extern const u8 Key_DPAD_png[];
@ -784,19 +784,19 @@ static void cheatmenu_cb(void)
gui_image key_enable;
gui_image key_delete;
#ifdef HW_RVL
key_delete.texture = gxTextureOpenPNG(Key_Minus_wii_png,0);
key_enable.texture = gxTextureOpenPNG(Key_Plus_wii_png,0);
gxDrawTexture(key_delete.texture,152,424,24,24,255);
gxDrawTexture(key_enable.texture,372,424,24,24,255);
FONT_write("Delete\nCheat",16,184,436,640,(GXColor)WHITE);
FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,404,436,640,(GXColor)WHITE);
key_delete.texture = gxTextureOpenPNG(Key_Minus_wii_png,0);
gxDrawTexture(key_enable.texture,152,424,24,24,255);
gxDrawTexture(key_delete.texture,372,424,24,24,255);
FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,184,436,640,(GXColor)WHITE);
FONT_write("Delete\nCheat",16,404,436,640,(GXColor)WHITE);
#else
key_delete.texture = gxTextureOpenPNG(Key_L_gcn_png,0);
key_enable.texture = gxTextureOpenPNG(Key_R_gcn_png,0);
gxDrawTexture(key_delete.texture,136,426,44,20,255);
gxDrawTexture(key_enable.texture,368,426,44,20,255);
FONT_write("Delete\nCheat",16,188,436,640,(GXColor)WHITE);
FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,420,436,640,(GXColor)WHITE);
key_enable.texture = gxTextureOpenPNG(Key_L_gcn_png,0);
key_delete.texture = gxTextureOpenPNG(Key_R_gcn_png,0);
gxDrawTexture(key_enable.texture,136,426,44,20,255);
gxDrawTexture(key_delete.texture,368,426,44,20,255);
FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,188,436,640,(GXColor)WHITE);
FONT_write("Delete\nCheat",16,420,436,640,(GXColor)WHITE);
#endif
gxTextureClose(&key_enable.texture);
gxTextureClose(&key_delete.texture);
@ -1191,7 +1191,7 @@ void CheatMenu(void)
if ((offset + selection) < maxcheats)
{
/* Special inputs */
if (m_input.keys & PAD_TRIGGER_L)
if (m_input.keys & PAD_TRIGGER_R)
{
/* sort cheat list */
for (i = offset + selection + 1; i < maxcheats; i++)
@ -1223,7 +1223,7 @@ void CheatMenu(void)
/* reset scrolling */
string_offset = 0;
}
else if (m_input.keys & PAD_TRIGGER_R)
else if (m_input.keys & PAD_TRIGGER_L)
{
/* cheat ON/OFF */
cheatlist[offset + selection].enable ^= 1;

@ -1145,7 +1145,7 @@ static void systemmenu ()
else
sprintf (items[7].text, "Lock-On: OFF");
sprintf (items[8].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF");
if (svp)
{
@ -1233,6 +1233,9 @@ static void systemmenu ()
}
}
/* reinitialize audio streams */
audio_init(snd.sample_rate, snd.frame_rate);
/* force hard reset */
system_init();
system_reset();
@ -1389,7 +1392,7 @@ static void systemmenu ()
case 8: /*** Cartridge Hot Swap ***/
{
config.hot_swap ^= 1;
sprintf (items[8].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF");
break;
}
@ -1421,6 +1424,12 @@ static void systemmenu ()
{
system_init();
system_reset();
/* restore SRAM */
if (config.s_auto & 1)
{
slot_autoload(0,config.s_device);
}
}
else
{

@ -182,6 +182,7 @@ void gx_audio_Start(void)
ASND_End();
AUDIO_StopDMA();
AUDIO_RegisterDMACallback(NULL);
DSP_Halt();
/* when VSYNC is forced OFF or AUTO with TV mode not matching emulated video mode, emulation is synchronized with Audio Hardware */
if (!config.vsync || (config.tv_mode == !vdp_pal))
@ -206,6 +207,7 @@ void gx_audio_Start(void)
void gx_audio_Stop(void)
{
/* restart menu audio processing */
DSP_Unhalt();
ASND_Init();
ASND_Pause(0);

@ -1218,8 +1218,8 @@ void gx_input_SetDefault(void)
{
/* Wiimote */
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONA] = WPAD_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONB] = WPAD_BUTTON_2;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONC] = WPAD_BUTTON_1;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONB] = WPAD_BUTTON_1;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONC] = WPAD_BUTTON_2;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_START] = WPAD_BUTTON_PLUS;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONX] = 0;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONY] = 0;
@ -1228,8 +1228,8 @@ void gx_input_SetDefault(void)
/* Wiimote + Nunchuk */
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONB] = WPAD_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONC] = WPAD_BUTTON_B;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONB] = WPAD_BUTTON_B;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONC] = WPAD_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_START] = WPAD_BUTTON_PLUS;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONY] = WPAD_BUTTON_1;
@ -1242,8 +1242,8 @@ void gx_input_SetDefault(void)
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_X;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_ZR;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_X;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_MODE] = WPAD_CLASSIC_BUTTON_MINUS;
}
#endif

@ -118,7 +118,7 @@ static void init_machine(void)
fclose(fp);
/* check BOOT ROM */
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
{
/* mark Genesis BIOS as loaded */
system_bios = SYSTEM_MD;

@ -54,6 +54,8 @@
#define CD_BRAM_JP "/genplus/saves/cd/scd_J.brm"
#define CART_BRAM "/genplus/saves/cd/cart.brm"
#define ALIGN_SND 0xfffffff8 /* 32 bytes aligned sound buffers (8 samples alignment) */
/*************************************************/
#ifdef HW_RVL

@ -403,13 +403,13 @@ int load_bios(void)
switch (region_code)
{
case REGION_USA:
size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom));
size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom), 0);
break;
case REGION_EUROPE:
size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom));
size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom), 0);
break;
default:
size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom));
size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom), 0);
break;
}
@ -431,12 +431,6 @@ int load_bios(void)
/* loaded BIOS region */
system_bios = (system_bios & 0xf0) | (region_code >> 4);
}
else
{
/* CD BOOT ROM disabled (SYSTEM ERROR) */
memset(scd.bootrom, 0xff, sizeof(scd.bootrom));
}
return size;
@ -458,7 +452,7 @@ int load_bios(void)
if (cart.romsize <= 0x400000)
{
/* load Game Gear "BIOS" file */
size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000);
size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000, 0);
if (size > 0)
{
@ -489,13 +483,13 @@ int load_bios(void)
switch (region_code)
{
case REGION_USA:
size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x100000);
size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x100000, 0);
break;
case REGION_EUROPE:
size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x100000);
size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x100000, 0);
break;
default:
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000);
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000, 0);
break;
}
@ -543,14 +537,19 @@ int load_rom(char *filename)
ggenie_shutdown();
areplay_shutdown();
/* unload any existing disc */
if (romtype == SYSTEM_MCD)
{
/* unload CD image */
cdd_unload();
}
else
{
/* no CD image loaded */
cdd.loaded = 0;
}
/* .cue file support */
if (!strncmp(".cue", &filename[strlen(filename) - 4], 4))
if (!memcmp(".cue", &filename[strlen(filename) - 4], 4))
{
/* open associated .bin file */
strncpy(&filename[strlen(filename) - 4], ".bin", 4);
@ -565,7 +564,7 @@ int load_rom(char *filename)
}
/* auto-detect CD image file */
if (!strncmp("SEGADISCSYSTEM", buf + 0x10, 14))
if (!memcmp("SEGADISCSYSTEM", buf + 0x10, 14))
{
/* file header pointer (BIN format) */
header = buf + 0x10;
@ -573,7 +572,7 @@ int load_rom(char *filename)
/* enable CD hardware */
system_hw = SYSTEM_MCD;
}
else if (!strncmp("SEGADISCSYSTEM", buf, 14))
else if (!memcmp("SEGADISCSYSTEM", buf, 14))
{
/* file header pointer (ISO format) */
header = buf;
@ -583,25 +582,30 @@ int load_rom(char *filename)
}
else
{
/* load file into ROM buffer (input filename is overwritten by uncompressed filename) */
int size = load_archive(filename, cart.rom, sizeof(cart.rom));
if (!size) return(0);
/* load file into ROM buffer */
char extension[4];
int size = load_archive(filename, cart.rom, sizeof(cart.rom), extension);
/* mark CD BIOS as unloaded */
system_bios &= ~0x10;
if (!size) return(0);
/* convert lower case to upper case */
*(uint32 *)(extension) &= 0xdfdfdfdf;
/* Auto-detect system hardware from ROM file extension */
if (!strncmp(".sms", &filename[strlen(filename) - 4], 4))
if (!memcmp("SMS", &extension[0], 3))
{
/* Master System II hardware */
system_hw = SYSTEM_SMS2;
}
else if (!strncmp(".gg", &filename[strlen(filename) - 3], 3))
else if (!memcmp("GG", &extension[1], 2))
{
/* Game Gear hardware (GG mode) */
system_hw = SYSTEM_GG;
}
else if (!strncmp(".sg", &filename[strlen(filename) - 3], 3))
else if (!memcmp("SG", &extension[1], 2))
{
/* SG-1000 hardware */
system_hw = SYSTEM_SG;
@ -612,7 +616,7 @@ int load_rom(char *filename)
system_hw = SYSTEM_MD;
/* Decode .MDX format */
if (!strncmp(".mdx", &filename[strlen(filename) - 4], 4))
if (!memcmp("MDX", &extension[0], 3))
{
for (i = 4; i < size - 1; i++)
{
@ -623,7 +627,7 @@ int load_rom(char *filename)
}
/* auto-detect 512 byte extra header */
if (strncmp((char *)(cart.rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
if (memcmp((char *)(cart.rom + 0x100), "SEGA", 4) && ((size / 512) & 1))
{
/* remove header */
size -= 512;
@ -713,8 +717,11 @@ int load_rom(char *filename)
/* boot from CD */
scd.cartridge.boot = 0x00;
/* CD unloaded */
/* no CD image loaded */
cdd.loaded = 0;
/* clear CD TOC */
cdd_unload();
}
/* special ROM cartridges that use CD hardware */
@ -729,9 +736,12 @@ int load_rom(char *filename)
/* load CD BOOT ROM */
if (load_bios())
{
/* CD unloaded */
/* no CD image loaded */
cdd.loaded = 0;
/* clear CD TOC */
cdd_unload();
/* boot from cartridge */
scd.cartridge.boot = 0x40;
}
@ -739,6 +749,9 @@ int load_rom(char *filename)
{
/* assume Mega Drive hardware */
system_hw = SYSTEM_MD;
/* copy back to cartridge ROM area */
memcpy(cart.rom, scd.cartridge.area, sizeof(scd.cartridge.area));
}
}
@ -817,12 +830,12 @@ void get_region(char *romheader)
int country = 0;
/* from Gens */
if (!strncmp(rominfo.country, "eur", 3)) country |= 8;
else if (!strncmp(rominfo.country, "EUR", 3)) country |= 8;
else if (!strncmp(rominfo.country, "jap", 3)) country |= 1;
else if (!strncmp(rominfo.country, "JAP", 3)) country |= 1;
else if (!strncmp(rominfo.country, "usa", 3)) country |= 4;
else if (!strncmp(rominfo.country, "USA", 3)) country |= 4;
if (!memcmp(rominfo.country, "eur", 3)) country |= 8;
else if (!memcmp(rominfo.country, "EUR", 3)) country |= 8;
else if (!memcmp(rominfo.country, "jap", 3)) country |= 1;
else if (!memcmp(rominfo.country, "JAP", 3)) country |= 1;
else if (!memcmp(rominfo.country, "usa", 3)) country |= 4;
else if (!memcmp(rominfo.country, "USA", 3)) country |= 4;
else
{
int i;

@ -273,7 +273,11 @@ void m68k_run(unsigned int cycles)
/* Save end cycles count for when CPU is stopped */
m68k.cycle_end = cycles;
#ifdef LOGVDP
error("[%d][%d] m68k run to %d cycles (%x)\n", v_counter, m68k.cycles, cycles, m68k.pc);
#endif
while (m68k.cycles < cycles)
{
/* Set tracing accodring to T1. */

@ -211,13 +211,13 @@ void s68k_update_irq(unsigned int mask)
/* Set IRQ level */
CPU_INT_LEVEL = mask << 8;
/* Check interrupt mask to process IRQ */
m68ki_check_interrupts();
#ifdef LOG_SCD
error("[%d][%d] IRQ Level = %d(0x%02x) (%x)\n", v_counter, s68k.cycles, CPU_INT_LEVEL>>8,FLAG_INT_MASK,s68k.pc);
#endif
/* Check interrupt mask to process IRQ */
m68ki_check_interrupts();
}
void s68k_run(unsigned int cycles)
@ -234,7 +234,10 @@ void s68k_run(unsigned int cycles)
/* Save end cycles count for when CPU is stopped */
s68k.cycle_end = cycles;
#ifdef LOG_SCD
error("[%d][%d] s68k run to %d cycles (%x), irq mask = %x (%x)\n", v_counter, s68k.cycles, cycles, s68k.pc,FLAG_INT_MASK, CPU_INT_LEVEL);
#endif
while (s68k.cycles < cycles)
{
/* Set tracing accodring to T1. */

@ -233,6 +233,9 @@ INLINE void m68k_poll_detect(reg)
if (m68k.pc == m68k.poll.pc)
{
/* stop MAIN-CPU until register is modified by SUB-CPU */
#ifdef LOG_SCD
error("m68k stopped from %d cycles\n", m68k.cycles);
#endif
m68k.cycles = m68k.cycle_end;
m68k.stopped = 1 << reg;
}
@ -269,6 +272,9 @@ INLINE void m68k_poll_sync(reg)
/* restart SUB-CPU */
s68k.stopped = 0;
#ifdef LOG_SCD
error("s68k started from %d cycles\n", cycles);
#endif
}
/* clear CPU register(s) access flags */

@ -46,7 +46,7 @@ int state_load(unsigned char *state)
char version[17];
load_param(version,16);
version[16] = 0;
if (strncmp(version,STATE_VERSION,11))
if (memcmp(version,STATE_VERSION,11))
{
return -1;
}

@ -178,9 +178,9 @@ int audio_update(int16 *buffer)
/* get number of available samples */
int size = sound_update(mcycles_vdp);
#ifndef __LIBRETRO__
/* return an aligned number of samples */
size &= ~7;
#ifdef ALIGN_SND
/* return an aligned number of samples if necessary*/
size &= ALIGN_SND;
#endif
if (config.hq_fm)

@ -96,6 +96,27 @@ void (*vdp_z80_data_w)(unsigned int data);
unsigned int (*vdp_68k_data_r)(void);
unsigned int (*vdp_z80_data_r)(void);
/* Function prototypes */
static void vdp_68k_data_w_m4(unsigned int data);
static void vdp_68k_data_w_m5(unsigned int data);
static unsigned int vdp_68k_data_r_m4(void);
static unsigned int vdp_68k_data_r_m5(void);
static void vdp_z80_data_w_m4(unsigned int data);
static void vdp_z80_data_w_m5(unsigned int data);
static unsigned int vdp_z80_data_r_m4(void);
static unsigned int vdp_z80_data_r_m5(void);
static void vdp_z80_data_w_ms(unsigned int data);
static void vdp_z80_data_w_gg(unsigned int data);
static void vdp_z80_data_w_sg(unsigned int data);
static void vdp_bus_w(unsigned int data);
static void vdp_fifo_update(unsigned int cycles);
static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles);
static void vdp_dma_68k_ext(unsigned int length);
static void vdp_dma_68k_ram(unsigned int length);
static void vdp_dma_68k_io(unsigned int length);
static void vdp_dma_copy(unsigned int length);
static void vdp_dma_fill(unsigned int length);
/* Tables that define the playfield layout */
static const uint8 hscroll_mask_table[] = { 0x00, 0x07, 0xF8, 0xFF };
static const uint8 shift_table[] = { 6, 7, 0, 8 };
@ -121,14 +142,6 @@ static uint16 fifo[4]; /* FIFO buffer */
static void (*set_irq_line)(unsigned int level);
static void (*set_irq_line_delay)(unsigned int level);
/* DMA Timings */
static const uint8 dma_timing[2][2] =
{
/* H32, H40 */
{16 , 18}, /* active display */
{167, 205} /* blank display */
};
/* Vertical counter overflow values (see hvc.h) */
static const uint16 vc_table[4][2] =
{
@ -139,27 +152,30 @@ static const uint16 vc_table[4][2] =
{0x106, 0x10A} /* Mode 5 (240 lines) */
};
/*--------------------------------------------------------------------------*/
/* Function prototypes */
/*--------------------------------------------------------------------------*/
/* DMA Timings (number of access slots per line) */
static const uint8 dma_timing[2][2] =
{
/* H32, H40 */
{16 , 18}, /* active display */
{167, 205} /* blank display */
};
/* DMA processing functions (set by VDP register 23 high nibble) */
static void (*const dma_func[16])(unsigned int length) =
{
/* 0x0-0x3 : DMA from 68k bus $000000-$7FFFFF (external area) */
vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,
/* 0x4-0x7 : DMA from 68k bus $800000-$FFFFFF (internal RAM & I/O) */
vdp_dma_68k_ram, vdp_dma_68k_io,vdp_dma_68k_ram,vdp_dma_68k_ram,
/* 0x8-0xB : DMA Fill */
vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,
/* 0xC-0xF : DMA Copy */
vdp_dma_copy,vdp_dma_copy,vdp_dma_copy,vdp_dma_copy
};
static void vdp_68k_data_w_m4(unsigned int data);
static void vdp_68k_data_w_m5(unsigned int data);
static unsigned int vdp_68k_data_r_m4(void);
static unsigned int vdp_68k_data_r_m5(void);
static void vdp_z80_data_w_m4(unsigned int data);
static void vdp_z80_data_w_m5(unsigned int data);
static unsigned int vdp_z80_data_r_m4(void);
static unsigned int vdp_z80_data_r_m5(void);
static void vdp_z80_data_w_ms(unsigned int data);
static void vdp_z80_data_w_gg(unsigned int data);
static void vdp_z80_data_w_sg(unsigned int data);
static void vdp_bus_w(unsigned int data);
static void vdp_fifo_update(unsigned int cycles);
static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles);
static void vdp_dma_copy(unsigned int length);
static void vdp_dma_vbus(unsigned int length);
static void vdp_dma_fill(unsigned char data, unsigned int length);
/*--------------------------------------------------------------------------*/
/* Init, reset, context functions */
@ -608,30 +624,8 @@ void vdp_dma_update(unsigned int cycles)
/* Update DMA length */
dma_length -= dma_bytes;
/* Select DMA operation */
switch (dma_type)
{
case 2:
{
/* VRAM Fill */
vdp_dma_fill(dmafill, dma_bytes);
break;
}
case 3:
{
/* VRAM Copy */
vdp_dma_copy(dma_bytes);
break;
}
default:
{
/* 68K bus to VRAM, CRAM or VSRAM */
vdp_dma_vbus(dma_bytes);
break;
}
}
/* Process DMA operation */
dma_func[reg[23] >> 4](dma_bytes);
/* Check if DMA is finished */
if (!dma_length)
@ -2868,78 +2862,112 @@ static void vdp_z80_data_w_sg(unsigned int data)
/* DMA operations */
/*--------------------------------------------------------------------------*/
/* 68K bus to VRAM, VSRAM or CRAM */
static void vdp_dma_vbus(unsigned int length)
/* DMA from 68K bus: $000000-$7FFFFF (external area) */
static void vdp_dma_68k_ext(unsigned int length)
{
uint16 data;
/* 68k bus source address */
uint32 source = (reg[23] << 17) | (dma_src << 1);
/* Z80 & I/O area ($A00000-$A1FFFF) specific */
if (reg[23] == 0x50)
do
{
do
/* Read data word from 68k bus */
if (m68k.memory_map[source>>16].read16)
{
/* Z80 area */
if (source <= 0xA0FFFF)
{
/* Return $FFFF only when the Z80 isn't hogging the Z-bus.
(e.g. Z80 isn't reset and 68000 has the bus) */
data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF);
}
/* The I/O chip and work RAM try to drive the data bus which results
in both values being combined in random ways when read.
We return the I/O chip values which seem to have precedence, */
else if (source <= 0xA1001F)
{
data = io_68k_read((source >> 1) & 0x0F);
data = (data << 8 | data);
}
/* All remaining locations access work RAM */
else
{
data = *(uint16 *)(work_ram + (source & 0xFFFF));
}
/* Increment source address */
source += 2;
/* 128k DMA window */
source = (reg[23] << 17) | (source & 0x1FFFF);
/* Write data to VRAM, CRAM or VSRAM */
vdp_bus_w(data);
data = m68k.memory_map[source>>16].read16(source);
}
while (--length);
}
else
{
do
else
{
/* Read data word from 68k bus */
if (m68k.memory_map[source>>16].base)
{
data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF));
}
else
{
data = m68k.memory_map[source>>16].read16(source);
}
data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF));
}
/* Increment source address */
source += 2;
/* Increment source address */
source += 2;
/* 128k DMA window */
source = (reg[23] << 17) | (source & 0x1FFFF);
/* 128k DMA window */
source = (reg[23] << 17) | (source & 0x1FFFF);
/* Write data word to VRAM, CRAM or VSRAM */
vdp_bus_w(data);
}
while (--length);
/* Write data word to VRAM, CRAM or VSRAM */
vdp_bus_w(data);
}
while (--length);
/* Update DMA source address */
dma_src = (source >> 1) & 0xffff;
}
/* DMA from 68K bus: $800000-$FFFFFF (internal area) except I/O area */
static void vdp_dma_68k_ram(unsigned int length)
{
uint16 data;
/* 68k bus source address */
uint32 source = (reg[23] << 17) | (dma_src << 1);
do
{
/* access Work-RAM by default */
data = *(uint16 *)(work_ram + (source & 0xFFFF));
/* Increment source address */
source += 2;
/* 128k DMA window */
source = (reg[23] << 17) | (source & 0x1FFFF);
/* Write data word to VRAM, CRAM or VSRAM */
vdp_bus_w(data);
}
while (--length);
/* Update DMA source address */
dma_src = (source >> 1) & 0xffff;
}
/* DMA from 68K bus: $A00000-$A1FFFF (I/O area) specific */
static void vdp_dma_68k_io(unsigned int length)
{
uint16 data;
/* 68k bus source address */
uint32 source = (reg[23] << 17) | (dma_src << 1);
do
{
/* Z80 area */
if (source <= 0xA0FFFF)
{
/* Return $FFFF only when the Z80 isn't hogging the Z-bus.
(e.g. Z80 isn't reset and 68000 has the bus) */
data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF);
}
/* The I/O chip and work RAM try to drive the data bus which results
in both values being combined in random ways when read.
We return the I/O chip values which seem to have precedence, */
else if (source <= 0xA1001F)
{
data = io_68k_read((source >> 1) & 0x0F);
data = (data << 8 | data);
}
/* All remaining locations access work RAM */
else
{
data = *(uint16 *)(work_ram + (source & 0xFFFF));
}
/* Increment source address */
source += 2;
/* 128k DMA window */
source = (reg[23] << 17) | (source & 0x1FFFF);
/* Write data to VRAM, CRAM or VSRAM */
vdp_bus_w(data);
}
while (--length);
/* Update DMA source address */
dma_src = (source >> 1) & 0xffff;
@ -2989,12 +3017,14 @@ static void vdp_dma_copy(unsigned int length)
}
/* VRAM Fill (TODO: check if CRAM or VSRAM fill is possible) */
static void vdp_dma_fill(unsigned char data, unsigned int length)
static void vdp_dma_fill(unsigned int length)
{
/* VRAM write operation only (Williams Greatest Hits after soft reset) */
if ((code & 0x1F) == 0x01)
{
int name;
uint8 data = dmafill;
do
{
/* Intercept writes to Sprite Attribute Table */

@ -45,9 +45,8 @@
#include <zlib.h>
static int check_zip(char *filename);
static int gzsize(gzFile *gd);
int load_archive(char *filename, unsigned char *buffer, int maxsize)
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
{
int size = 0;
@ -55,6 +54,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
{
unz_file_info info;
int ret = 0;
char fname[256];
/* Attempt to open the archive */
unzFile *fd = unzOpen(filename);
@ -69,13 +69,20 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
}
/* Get file informations and update filename */
ret = unzGetCurrentFileInfo(fd, &info, filename, 128, NULL, 0, NULL, 0);
ret = unzGetCurrentFileInfo(fd, &info, fname, 256, NULL, 0, NULL, 0);
if(ret != UNZ_OK)
{
unzClose(fd);
return 0;
}
/* Compressed filename extension */
if (extension)
{
strncpy(extension, &fname[strlen(fname) - 3], 3);
extension[3] = 0;
}
/* Open the file for reading */
ret = unzOpenCurrentFile(fd);
if(ret != UNZ_OK)
@ -121,6 +128,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
/* Read file data */
size = gzread(gd, buffer, maxsize);
/* filename extension */
if (extension)
{
strncpy(extension, &filename[strlen(filename) - 3], 3);
extension[3] = 0;
}
/* Close file */
gzclose(gd);
}
@ -143,25 +157,3 @@ static int check_zip(char *filename)
if(memcmp(buf, "PK", 2) == 0) return (1);
return (0);
}
/*
Returns the size of a GZ compressed file.
*/
static int gzsize(gzFile *gd)
{
#define CHUNKSIZE (0x10000)
int size = 0, length = 0;
unsigned char buffer[CHUNKSIZE];
gzrewind(gd);
do
{
size = gzread(gd, buffer, CHUNKSIZE);
if(size <= 0) break;
length += size;
}
while (!gzeof(gd));
gzrewind(gd);
return (length);
#undef CHUNKSIZE
}

@ -43,6 +43,6 @@
#define _FILEIO_H_
/* Function prototypes */
extern int load_archive(char *filename, unsigned char *buffer, int maxsize);
extern int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
#endif /* _FILEIO_H_ */

@ -701,7 +701,7 @@ int main (int argc, char **argv)
fclose(fp);
/* check BOOT ROM */
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
{
/* mark Genesis BIOS as loaded */
system_bios = SYSTEM_MD;