mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-04-27 15:51:25 +02:00
Merge git://github.com/ekeeke/Genesis-Plus-GX
Conflicts: source/system.c
This commit is contained in:
commit
d28fe8ee29
168
Makefile.win32
168
Makefile.win32
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user