mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-05-02 04:01:13 +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 :
|
# Defines :
|
||||||
# -DLSB_FIRST : for little endian systems.
|
# -DLSB_FIRST : for little endian systems.
|
||||||
|
# -DBUILD_TABLES: do not use const tables for 68k instructions (obsolete)
|
||||||
# -DLOGERROR : enable message logging
|
# -DLOGERROR : enable message logging
|
||||||
# -DLOGVDP : enable VDP debug messages
|
# -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
|
# -DLOGSOUND : enable AUDIO debug messages
|
||||||
# -D8BPP_RENDERING - configure for 8-bit pixels (RGB332)
|
# -D8BPP_RENDERING - configure for 8-bit pixels (RGB332)
|
||||||
# -D15BPP_RENDERING - configure for 15-bit pixels (RGB555)
|
# -D15BPP_RENDERING - configure for 15-bit pixels (RGB555)
|
||||||
# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565)
|
# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565)
|
||||||
# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888)
|
# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888)
|
||||||
|
|
||||||
NAME = gen_sdl.exe
|
NAME = gen_sdl.exe
|
||||||
|
|
||||||
CC = gcc
|
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
|
#-g -ggdb -pg
|
||||||
#-fomit-frame-pointer
|
#-fomit-frame-pointer
|
||||||
#LDFLAGS = -pg
|
LDFLAGS =
|
||||||
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING
|
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING -DLOGERROR -DLOG_CDC -DLOG_CDD -DLOG_SCD -DLOGVDP -DLOG_PCM
|
||||||
|
|
||||||
INCLUDES = -Isource -Isource/z80 -Isource/m68k -Isource/sound -Isource/input_hw -Isource/cart_hw -Isource/cart_hw/svp -Isource/ntsc -Isource/win
|
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
|
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 \
|
OBJECTS += obj/input.o \
|
||||||
$(OBJDIR)/vdp_ctrl.o \
|
obj/gamepad.o \
|
||||||
$(OBJDIR)/vdp_render.o \
|
obj/lightgun.o \
|
||||||
$(OBJDIR)/system.o \
|
obj/mouse.o \
|
||||||
$(OBJDIR)/io_ctrl.o \
|
obj/activator.o \
|
||||||
$(OBJDIR)/mem68k.o \
|
obj/xe_a1p.o \
|
||||||
$(OBJDIR)/memz80.o \
|
obj/teamplayer.o \
|
||||||
$(OBJDIR)/membnk.o \
|
obj/paddle.o \
|
||||||
$(OBJDIR)/state.o \
|
obj/sportspad.o \
|
||||||
$(OBJDIR)/loadrom.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 \
|
OBJECTS += obj/sound.o \
|
||||||
$(OBJDIR)/sn76489.o \
|
obj/sn76489.o \
|
||||||
$(OBJDIR)/ym2413.o \
|
obj/ym2413.o \
|
||||||
$(OBJDIR)/ym2612.o
|
obj/ym2612.o
|
||||||
|
|
||||||
OBJECTS += $(OBJDIR)/Fir_Resampler.o
|
OBJECTS += obj/Fir_Resampler.o
|
||||||
OBJECTS += $(OBJDIR)/blip.o
|
OBJECTS += obj/blip.o
|
||||||
OBJECTS += $(OBJDIR)/eq.o
|
|
||||||
|
|
||||||
OBJECTS += $(OBJDIR)/sram.o \
|
OBJECTS += obj/eq.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 += $(OBJDIR)/sms_ntsc.o \
|
OBJECTS += obj/sram.o \
|
||||||
$(OBJDIR)/md_ntsc.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 \
|
OBJECTS += obj/scd.o \
|
||||||
$(OBJDIR)/config.o \
|
obj/cdd.o \
|
||||||
$(OBJDIR)/error.o \
|
obj/cdc.o \
|
||||||
$(OBJDIR)/unzip.o \
|
obj/gfx.o \
|
||||||
$(OBJDIR)/fileio.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)
|
all: $(NAME)
|
||||||
|
|
||||||
$(NAME): $(OBJDIR) $(OBJECTS)
|
$(NAME): $(OBJECTS)
|
||||||
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
|
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ -Wl,-Map,genplus.map
|
||||||
|
|
||||||
$(OBJDIR) :
|
obj/%.o : ../%.c ../%.h
|
||||||
@[ -d $@ ] || mkdir -p $@
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o : source/%.c source/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
$(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 $@
|
$(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 $@
|
$(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 $@
|
$(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 $@
|
$(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 $@
|
$(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 $@
|
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||||
|
|
||||||
$(OBJDIR)/%.o : source/m68k/%.c source/m68k/%.h
|
obj/%.o : ../m68k/%.c
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||||
|
|
||||||
$(OBJDIR)/%.o : source/ntsc/%.c source/ntsc/%.h
|
obj/%.o : ./%.c ./%.h
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
$(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 $@
|
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||||
|
|
||||||
$(OBJDIR)/icon.o :
|
obj/icon.o :
|
||||||
windres source/win/icon.rc $@
|
windres icon.rc $@
|
||||||
|
|
||||||
pack :
|
pack :
|
||||||
strip $(NAME)
|
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].base = scd.cartridge.area + ((i & 0x3f) << 16);
|
||||||
m68k.memory_map[i].read8 = NULL;
|
m68k.memory_map[i].read8 = NULL;
|
||||||
m68k.memory_map[i].read16 = NULL;
|
m68k.memory_map[i].read16 = NULL;
|
||||||
m68k.memory_map[i].write8 = NULL;
|
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||||
m68k.memory_map[i].write16 = NULL;
|
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||||
zbank_memory_map[i].read = NULL;
|
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)
|
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)
|
switch (scd.regs[0x04>>1].byte.l & 0x0F)
|
||||||
{
|
{
|
||||||
case 0x01: /* IFSTAT */
|
case 0x01: /* IFSTAT */
|
||||||
|
@ -74,6 +74,15 @@ static const uint16 lut_BCD_16[100] =
|
|||||||
0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, 0x0909,
|
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)
|
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);
|
fseek(cdd.toc.tracks[0].fd, 0, SEEK_SET);
|
||||||
|
|
||||||
/* initialize TOC */
|
/* initialize TOC */
|
||||||
/* TODO: add 2 seconds pause after data track ? */
|
|
||||||
cdd.toc.end = cdd.toc.tracks[0].end;
|
cdd.toc.end = cdd.toc.tracks[0].end;
|
||||||
cdd.toc.last = 1;
|
cdd.toc.last = 1;
|
||||||
|
|
||||||
/* TODO: add audio track support from BIN/CUE, ISO/WAV, MP3, OGG ? */
|
/* 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)
|
if (cdd.toc.last == 1)
|
||||||
{
|
{
|
||||||
/* default track duration (fix Snatcher intro) */
|
/* Some games require specific TOC infos */
|
||||||
int length = 4 * 60 * 75;
|
if (strstr(rominfo.product,"T-95035") != NULL)
|
||||||
|
|
||||||
/* A-Rank Thunder Tanjouen requires shorter track duration to pass intro */
|
|
||||||
if (strstr(rominfo.product,"T-49064") != 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);
|
||||||
}
|
}
|
||||||
|
else if (strstr(rominfo.product,"T-45074") != NULL)
|
||||||
/* max length = 60:02:00 */
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
/* Lunar - Eternal Blue (J) */
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.end + length;
|
cdd.toc.tracks[1].start = cdd.toc.end + 2*75;
|
||||||
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
|
cdd.toc.tracks[1].end = cdd.toc.tracks[1].start + 21654;
|
||||||
cdd.toc.last++;
|
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 */
|
/* CD loaded */
|
||||||
@ -175,15 +216,15 @@ void cdd_unload(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset TOC */
|
|
||||||
memset(&cdd.toc, 0x00, sizeof(cdd.toc));
|
|
||||||
|
|
||||||
/* CD unloaded */
|
/* CD unloaded */
|
||||||
cdd.loaded = 0;
|
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)
|
void cdd_read(uint8 *dst)
|
||||||
@ -219,19 +260,22 @@ void cdd_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* track type */
|
/* track type */
|
||||||
if (cdd.index)
|
if (cdd.index > 0)
|
||||||
{
|
{
|
||||||
/* audio track sector is sent to CD Fader/DAC but also CDD */
|
if (cdd.index < cdd.toc.last)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
/* next track */
|
/* audio track sector sent to CD Fader/DAC should also be sent to CDD */
|
||||||
cdd.index++;
|
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
|
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)
|
void cdd_process(void)
|
||||||
@ -303,7 +376,7 @@ void cdd_process(void)
|
|||||||
case 0x02: /* Current track */
|
case 0x02: /* Current track */
|
||||||
{
|
{
|
||||||
scd.regs[0x38>>1].w = (cdd.status << 8) | 0x02;
|
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[0x3c>>1].w = 0x0000;
|
||||||
scd.regs[0x3e>>1].w = 0x0000;
|
scd.regs[0x3e>>1].w = 0x0000;
|
||||||
scd.regs[0x40>>1].byte.h = 0x00;
|
scd.regs[0x40>>1].byte.h = 0x00;
|
||||||
@ -383,7 +456,7 @@ void cdd_process(void)
|
|||||||
cdd.lba = lba;
|
cdd.lba = lba;
|
||||||
|
|
||||||
/* update current track index */
|
/* 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;
|
cdd.index = index;
|
||||||
|
|
||||||
/* track type */
|
/* track type */
|
||||||
@ -405,7 +478,7 @@ void cdd_process(void)
|
|||||||
/* update status */
|
/* update status */
|
||||||
cdd.status = CD_PLAY;
|
cdd.status = CD_PLAY;
|
||||||
scd.regs[0x38>>1].w = (CD_PLAY << 8) | 0x02;
|
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[0x3c>>1].w = 0x0000;
|
||||||
scd.regs[0x3e>>1].w = 0x0000;
|
scd.regs[0x3e>>1].w = 0x0000;
|
||||||
scd.regs[0x40>>1].byte.h = 0x00;
|
scd.regs[0x40>>1].byte.h = 0x00;
|
||||||
@ -426,7 +499,7 @@ void cdd_process(void)
|
|||||||
cdd.lba = lba;
|
cdd.lba = lba;
|
||||||
|
|
||||||
/* update current track index */
|
/* 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;
|
cdd.index = index;
|
||||||
|
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
@ -482,7 +555,7 @@ void cdd_process(void)
|
|||||||
/* update status */
|
/* update status */
|
||||||
cdd.status = CD_PLAY;
|
cdd.status = CD_PLAY;
|
||||||
scd.regs[0x38>>1].w = (CD_PLAY << 8) | 0x02;
|
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[0x3c>>1].w = 0x0000;
|
||||||
scd.regs[0x3e>>1].w = 0x0000;
|
scd.regs[0x3e>>1].w = 0x0000;
|
||||||
scd.regs[0x40>>1].byte.h = 0x00;
|
scd.regs[0x40>>1].byte.h = 0x00;
|
||||||
@ -491,6 +564,7 @@ void cdd_process(void)
|
|||||||
|
|
||||||
case 0x08: /* Forward Scan */
|
case 0x08: /* Forward Scan */
|
||||||
{
|
{
|
||||||
|
cdd.scanOffset = 10;
|
||||||
cdd.status = CD_SCAN;
|
cdd.status = CD_SCAN;
|
||||||
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
||||||
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
|
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
|
||||||
@ -502,6 +576,7 @@ void cdd_process(void)
|
|||||||
|
|
||||||
case 0x09: /* Rewind Scan */
|
case 0x09: /* Rewind Scan */
|
||||||
{
|
{
|
||||||
|
cdd.scanOffset = -10;
|
||||||
cdd.status = CD_SCAN;
|
cdd.status = CD_SCAN;
|
||||||
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
||||||
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
|
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
|
||||||
|
@ -67,6 +67,7 @@ typedef struct
|
|||||||
int loaded;
|
int loaded;
|
||||||
int index;
|
int index;
|
||||||
int lba;
|
int lba;
|
||||||
|
int scanOffset;
|
||||||
uint8 status;
|
uint8 status;
|
||||||
uint16 sectorSize;
|
uint16 sectorSize;
|
||||||
toc_t toc;
|
toc_t toc;
|
||||||
|
@ -93,38 +93,41 @@ void pcm_update(short *buffer, int length)
|
|||||||
/* run eight PCM channels */
|
/* run eight PCM channels */
|
||||||
for (j=0; j<8; j++)
|
for (j=0; j<8; j++)
|
||||||
{
|
{
|
||||||
/* check if channel is enabled (bit cleared) */
|
/* check if channel is enabled */
|
||||||
if (!(pcm.status & (1 << j)))
|
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];
|
short data = pcm.ram[(pcm.chan[j].addr >> 11) & 0xffff];
|
||||||
|
|
||||||
/* STOP data ? */
|
/* loop data ? */
|
||||||
if (data == 0xff)
|
if (data == 0xff)
|
||||||
{
|
{
|
||||||
/* reset WAVE RAM address with loop address */
|
/* reset WAVE RAM address */
|
||||||
pcm.chan[j].addr = pcm.chan[j].ls.w << 11;
|
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];
|
data = pcm.ram[pcm.chan[j].ls.w];
|
||||||
|
|
||||||
/* no output on infinite loop */
|
|
||||||
if (data == 0xff) break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* output L & R subchannels */
|
|
||||||
if (data & 0x80)
|
|
||||||
{
|
{
|
||||||
/* PCM data is negative */
|
/* increment WAVE RAM address */
|
||||||
data = -(data & 0x7f);
|
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) */
|
/* infinite loop should not output any data */
|
||||||
l += ((data * pcm.chan[j].env * (pcm.chan[j].pan & 0x0F)) >> 6);
|
if (data != 0xff)
|
||||||
r += ((data * pcm.chan[j].env * (pcm.chan[j].pan >> 4)) >> 6);
|
{
|
||||||
|
/* output L & R subchannels */
|
||||||
|
if (data & 0x80)
|
||||||
|
{
|
||||||
|
/* PCM data is negative */
|
||||||
|
data = -(data & 0x7f);
|
||||||
|
}
|
||||||
|
|
||||||
/* increment WAVE RAM address */
|
/* multiply PCM data with ENV & stereo PAN data then add to outputs (13.6 fixed point) */
|
||||||
pcm.chan[j].addr += pcm.chan[j].fd.w;
|
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)
|
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 */
|
/* external RAM is mapped to $1000-$1FFF */
|
||||||
if (address >= 0x1000)
|
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) */
|
/* update channel WAVE RAM start address (16.11 fixed point) */
|
||||||
pcm.chan[pcm.index].st = data << (8 + 11);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,18 +268,18 @@ void pcm_write(unsigned int address, unsigned char data)
|
|||||||
|
|
||||||
case 0x08: /* ON/OFF register */
|
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 */
|
/* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,6 +293,10 @@ void pcm_write(unsigned int address, unsigned char data)
|
|||||||
|
|
||||||
unsigned char pcm_read(unsigned int address)
|
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 !) */
|
/* external RAM (TODO: verify if possible to read, some docs claim it's not !) */
|
||||||
if (address >= 0x1000)
|
if (address >= 0x1000)
|
||||||
{
|
{
|
||||||
@ -294,7 +311,7 @@ unsigned char pcm_read(unsigned int address)
|
|||||||
|
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
{
|
{
|
||||||
return pcm.chan[index].addr >> (11 + 8);
|
return (pcm.chan[index].addr >> (11 + 8)) & 0xff;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -190,6 +190,9 @@ INLINE void s68k_poll_detect(reg)
|
|||||||
if (s68k.pc == s68k.poll.pc)
|
if (s68k.pc == s68k.poll.pc)
|
||||||
{
|
{
|
||||||
/* stop SUB-CPU until register is modified by MAIN-CPU */
|
/* 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.cycles = s68k.cycle_end;
|
||||||
s68k.stopped = 1 << reg;
|
s68k.stopped = 1 << reg;
|
||||||
}
|
}
|
||||||
@ -226,6 +229,9 @@ INLINE void s68k_poll_sync(reg)
|
|||||||
|
|
||||||
/* restart MAIN-CPU */
|
/* restart MAIN-CPU */
|
||||||
m68k.stopped = 0;
|
m68k.stopped = 0;
|
||||||
|
#ifdef LOG_SCD
|
||||||
|
error("m68k started from %d cycles\n", cycles);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear CPU register(s) access flags */
|
/* clear CPU register(s) access flags */
|
||||||
@ -269,6 +275,9 @@ static unsigned int scd_read_byte(unsigned int address)
|
|||||||
if (address == 0xff8007)
|
if (address == 0xff8007)
|
||||||
{
|
{
|
||||||
unsigned int data = cdc_reg_r();
|
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;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,6 +421,7 @@ INLINE void word_ram_switch(uint8 mode)
|
|||||||
|
|
||||||
if (mode & 0x04)
|
if (mode & 0x04)
|
||||||
{
|
{
|
||||||
|
/* 2M -> 1M mode */
|
||||||
for (i=0; i<0x10000; i++)
|
for (i=0; i<0x10000; i++)
|
||||||
{
|
{
|
||||||
*ptr2++=*ptr1++;
|
*ptr2++=*ptr1++;
|
||||||
@ -420,11 +430,43 @@ INLINE void word_ram_switch(uint8 mode)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* 1M -> 2M mode */
|
||||||
for (i=0; i<0x10000; i++)
|
for (i=0; i<0x10000; i++)
|
||||||
{
|
{
|
||||||
*ptr1++=*ptr2++;
|
*ptr1++=*ptr2++;
|
||||||
*ptr1++=*ptr3++;
|
*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 */
|
case 0x03: /* Memory Mode */
|
||||||
{
|
{
|
||||||
|
s68k_poll_sync(0x02);
|
||||||
|
|
||||||
/* detect MODE & RET bits modifications */
|
/* detect MODE & RET bits modifications */
|
||||||
if ((data ^ scd.regs[0x03 >> 1].byte.l) & 0x05)
|
if ((data ^ scd.regs[0x03 >> 1].byte.l) & 0x05)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s68k_poll_sync(0x02);
|
|
||||||
|
|
||||||
/* MODE bit */
|
/* MODE bit */
|
||||||
if (data & 0x04)
|
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))
|
if (!(scd.regs[0x03 >> 1].byte.l & 0x04))
|
||||||
{
|
{
|
||||||
/* re-arrange Word-RAM banks */
|
/* re-arrange Word-RAM banks */
|
||||||
word_ram_switch(data);
|
word_ram_switch(0x04);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RET bit in 1M Mode */
|
/* 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++)
|
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||||
{
|
{
|
||||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
/* 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].read8 = cell_ram_1_read8;
|
||||||
m68k.memory_map[i].read16 = cell_ram_1_read16;
|
m68k.memory_map[i].read16 = cell_ram_1_read16;
|
||||||
m68k.memory_map[i].write8 = cell_ram_1_write8;
|
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++)
|
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||||
{
|
{
|
||||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
/* 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].read8 = cell_ram_0_read8;
|
||||||
m68k.memory_map[i].read16 = cell_ram_0_read16;
|
m68k.memory_map[i].read16 = cell_ram_0_read16;
|
||||||
m68k.memory_map[i].write8 = cell_ram_0_write8;
|
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)
|
if (scd.regs[0x02 >> 1].byte.l & 0x04)
|
||||||
{
|
{
|
||||||
/* re-arrange Word-RAM banks */
|
/* re-arrange Word-RAM banks */
|
||||||
word_ram_switch(data);
|
word_ram_switch(0x00);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RET bit set during 1M mode ? */
|
/* RET bit set during 1M mode ? */
|
||||||
data |= ~scd.dmna & 0x01;
|
data |= ~scd.dmna & 0x01;
|
||||||
@ -777,12 +786,12 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
|||||||
|
|
||||||
case 0x02: /* Memory Mode */
|
case 0x02: /* Memory Mode */
|
||||||
{
|
{
|
||||||
|
s68k_poll_sync(0x02);
|
||||||
|
|
||||||
/* detect MODE & RET bits modifications */
|
/* detect MODE & RET bits modifications */
|
||||||
if ((data ^ scd.regs[0x03>>1].byte.l) & 0x05)
|
if ((data ^ scd.regs[0x03>>1].byte.l) & 0x05)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s68k_poll_sync(0x02);
|
|
||||||
|
|
||||||
/* MODE bit */
|
/* MODE bit */
|
||||||
if (data & 0x04)
|
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))
|
if (!(scd.regs[0x03 >> 1].byte.l & 0x04))
|
||||||
{
|
{
|
||||||
/* re-arrange Word-RAM banks */
|
/* re-arrange Word-RAM banks */
|
||||||
word_ram_switch(data);
|
word_ram_switch(0x04);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RET bit in 1M Mode */
|
/* 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++)
|
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||||
{
|
{
|
||||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
/* 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].read8 = cell_ram_1_read8;
|
||||||
m68k.memory_map[i].read16 = cell_ram_1_read16;
|
m68k.memory_map[i].read16 = cell_ram_1_read16;
|
||||||
m68k.memory_map[i].write8 = cell_ram_1_write8;
|
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++)
|
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||||
{
|
{
|
||||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
/* 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].read8 = cell_ram_0_read8;
|
||||||
m68k.memory_map[i].read16 = cell_ram_0_read16;
|
m68k.memory_map[i].read16 = cell_ram_0_read16;
|
||||||
m68k.memory_map[i].write8 = cell_ram_0_write8;
|
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)
|
if (scd.regs[0x03>>1].byte.l & 0x04)
|
||||||
{
|
{
|
||||||
/* re-arrange Word-RAM banks */
|
/* re-arrange Word-RAM banks */
|
||||||
word_ram_switch(data);
|
word_ram_switch(0x00);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RET bit set during 1M mode ? */
|
/* RET bit set during 1M mode ? */
|
||||||
data |= ~scd.dmna & 0x01;
|
data |= ~scd.dmna & 0x01;
|
||||||
@ -1104,7 +1080,7 @@ void scd_init(void)
|
|||||||
/* $240000-$3FFFFF (resp. $400000-$7FFFFF): unused area (Word-RAM mirrored ?) */
|
/* $240000-$3FFFFF (resp. $400000-$7FFFFF): unused area (Word-RAM mirrored ?) */
|
||||||
for (i=base+0x24; i<base+0x40; i++)
|
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].read8 = m68k_read_bus_8;
|
||||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||||
@ -1143,10 +1119,10 @@ void scd_init(void)
|
|||||||
s68k.memory_map[i].write16 = NULL;
|
s68k.memory_map[i].write16 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $0C0000-$FD0000: Unused area */
|
/* $0C0000-$FD0000: Unused area (Word-RAM mirrored ?) */
|
||||||
for (i=0x0c; i<0xfd; i++)
|
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].read8 = s68k_read_bus_8;
|
||||||
s68k.memory_map[i].read16 = s68k_read_bus_16;
|
s68k.memory_map[i].read16 = s68k_read_bus_16;
|
||||||
s68k.memory_map[i].write8 = s68k_unused_8_w;
|
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) */
|
/* Power ON initial values (MAIN-CPU side) */
|
||||||
scd.regs[0x00>>1].w = 0x0002;
|
scd.regs[0x00>>1].w = 0x0002;
|
||||||
scd.regs[0x02>>1].w = 0x0001;
|
scd.regs[0x02>>1].w = 0x0001;
|
||||||
|
|
||||||
|
/* 2M mode */
|
||||||
|
word_ram_switch(0);
|
||||||
}
|
}
|
||||||
else
|
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_USP,tmp32);
|
||||||
load_param(&tmp32, 4); s68k_set_reg(M68K_REG_ISP,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;
|
return bufferptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +258,21 @@ void gen_reset(int hard_reset)
|
|||||||
/* 8-bit / 16-bit modes */
|
/* 8-bit / 16-bit modes */
|
||||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||||
{
|
{
|
||||||
/* reset cartridge hardware & mapping */
|
if (system_hw == SYSTEM_MCD)
|
||||||
md_cart_reset(hard_reset);
|
{
|
||||||
|
/* 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 */
|
/* Z80 bus is released & Z80 is reseted */
|
||||||
m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
|
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 */
|
/* reset MAIN-CPU */
|
||||||
m68k_pulse_reset();
|
m68k_pulse_reset();
|
||||||
}
|
}
|
||||||
@ -348,7 +350,7 @@ void gen_tmss_w(unsigned int offset, unsigned int data)
|
|||||||
WRITE_WORD(tmss, offset, data);
|
WRITE_WORD(tmss, offset, data);
|
||||||
|
|
||||||
/* VDP requires "SEGA" value to be written in TMSS register */
|
/* 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)
|
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)
|
void gen_bankswitch_w(unsigned int data)
|
||||||
{
|
{
|
||||||
if (data & 1)
|
if (system_hw == SYSTEM_MD)
|
||||||
{
|
{
|
||||||
/* enable cartridge ROM */
|
if (data & 1)
|
||||||
m68k.memory_map[0].base = cart.base;
|
{
|
||||||
}
|
/* enable cartridge ROM */
|
||||||
else
|
m68k.memory_map[0].base = cart.base;
|
||||||
{
|
}
|
||||||
/* enable internal BOOT ROM */
|
else
|
||||||
m68k.memory_map[0].base = boot_rom;
|
{
|
||||||
|
/* enable internal BOOT ROM */
|
||||||
|
m68k.memory_map[0].base = boot_rom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int gen_bankswitch_r(void)
|
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];
|
char version[16];
|
||||||
fseek(fp, 0, SEEK_SET);
|
fseek(fp, 0, SEEK_SET);
|
||||||
fread(version, 16, 1, fp);
|
fread(version, 16, 1, fp);
|
||||||
if (strncmp(version,CONFIG_VERSION,16))
|
if (memcmp(version,CONFIG_VERSION,16))
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -108,12 +108,17 @@ void slot_autoload(int slot, int device)
|
|||||||
/* update CRC */
|
/* update CRC */
|
||||||
brm_crc[0] = crc32(0, scd.bram, 0x2000);
|
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 */
|
/* check if internal backup RAM is correctly formatted */
|
||||||
if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20))
|
if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20))
|
||||||
{
|
{
|
||||||
/* clear internal backup RAM */
|
/* clear internal backup RAM */
|
||||||
memset(scd.bram, 0x00, 0x200);
|
memset(scd.bram, 0x00, 0x2000 - 0x40);
|
||||||
|
|
||||||
/* internal Backup RAM size fields */
|
/* internal Backup RAM size fields */
|
||||||
brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00;
|
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 */
|
/* format internal backup RAM */
|
||||||
memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40);
|
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) */
|
/* automatically load cartridge backup RAM (if enabled) */
|
||||||
@ -129,7 +137,24 @@ void slot_autoload(int slot, int device)
|
|||||||
fp = fopen(CART_BRAM, "rb");
|
fp = fopen(CART_BRAM, "rb");
|
||||||
if (fp != NULL)
|
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);
|
fclose(fp);
|
||||||
|
|
||||||
/* update CRC */
|
/* update CRC */
|
||||||
@ -194,7 +219,24 @@ void slot_autosave(int slot, int device)
|
|||||||
FILE *fp = fopen(CART_BRAM, "wb");
|
FILE *fp = fopen(CART_BRAM, "wb");
|
||||||
if (fp != NULL)
|
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);
|
fclose(fp);
|
||||||
|
|
||||||
/* update CRC */
|
/* update CRC */
|
||||||
@ -622,6 +664,9 @@ int slot_save(int slot, int device)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
|
/* Close message box */
|
||||||
|
GUI_MsgBoxClose();
|
||||||
|
|
||||||
/* Save state screenshot */
|
/* Save state screenshot */
|
||||||
if (slot > 0)
|
if (slot > 0)
|
||||||
{
|
{
|
||||||
@ -768,8 +813,10 @@ int slot_save(int slot, int device)
|
|||||||
CARD_Unmount(device);
|
CARD_Unmount(device);
|
||||||
free(out);
|
free(out);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
|
||||||
|
|
||||||
GUI_MsgBoxClose();
|
/* Close message box */
|
||||||
|
GUI_MsgBoxClose();
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -83,37 +83,7 @@ static inline u16 FLIP16 (u16 b)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_zipfilename(char *filename)
|
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
|
||||||
{
|
|
||||||
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 size = 0;
|
int size = 0;
|
||||||
char in[CHUNKSIZE];
|
char in[CHUNKSIZE];
|
||||||
@ -132,7 +102,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
|||||||
/* Mega CD BIOS are required files */
|
/* Mega CD BIOS are required files */
|
||||||
if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP))
|
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)
|
if (!fd)
|
||||||
@ -187,19 +157,23 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
|||||||
return 0;
|
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 */
|
/* Initial Zip buffer offset */
|
||||||
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength) + FLIP16(pkzip->extraDataLength);
|
offset += FLIP16(pkzip->extraDataLength);
|
||||||
zs.next_in = (Bytef *)&in[offset];
|
zs.next_in = (Bytef *)&in[offset];
|
||||||
|
|
||||||
/* Initial Zip remaining chunk size */
|
/* Initial Zip remaining chunk size */
|
||||||
zs.avail_in = CHUNKSIZE - offset;
|
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 */
|
/* Start unzipping file */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -255,6 +229,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
|||||||
sprintf((char *)msg,"Loading %d bytes ...", size);
|
sprintf((char *)msg,"Loading %d bytes ...", size);
|
||||||
GUI_MsgBoxOpen("Information", (char *)msg, 1);
|
GUI_MsgBoxOpen("Information", (char *)msg, 1);
|
||||||
|
|
||||||
|
/* filename extension */
|
||||||
|
if (extension)
|
||||||
|
{
|
||||||
|
memcpy(extension, &filename[strlen(filename) - 3], 3);
|
||||||
|
extension[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read into buffer */
|
/* Read into buffer */
|
||||||
int left = size;
|
int left = size;
|
||||||
while (left > CHUNKSIZE)
|
while (left > CHUNKSIZE)
|
||||||
|
@ -42,6 +42,6 @@
|
|||||||
#define _FILEIO_H_
|
#define _FILEIO_H_
|
||||||
|
|
||||||
/* Function prototypes */
|
/* 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_ */
|
#endif /* _FILEIO_H_ */
|
||||||
|
@ -52,8 +52,8 @@
|
|||||||
extern const u8 Key_Minus_wii_png[];
|
extern const u8 Key_Minus_wii_png[];
|
||||||
extern const u8 Key_Plus_wii_png[];
|
extern const u8 Key_Plus_wii_png[];
|
||||||
#else
|
#else
|
||||||
extern const u8 Key_L_gcn_png[];
|
|
||||||
extern const u8 Key_R_gcn_png[];
|
extern const u8 Key_R_gcn_png[];
|
||||||
|
extern const u8 Key_L_gcn_png[];
|
||||||
#endif
|
#endif
|
||||||
extern const u8 Key_DPAD_png[];
|
extern const u8 Key_DPAD_png[];
|
||||||
|
|
||||||
@ -784,19 +784,19 @@ static void cheatmenu_cb(void)
|
|||||||
gui_image key_enable;
|
gui_image key_enable;
|
||||||
gui_image key_delete;
|
gui_image key_delete;
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
key_delete.texture = gxTextureOpenPNG(Key_Minus_wii_png,0);
|
|
||||||
key_enable.texture = gxTextureOpenPNG(Key_Plus_wii_png,0);
|
key_enable.texture = gxTextureOpenPNG(Key_Plus_wii_png,0);
|
||||||
gxDrawTexture(key_delete.texture,152,424,24,24,255);
|
key_delete.texture = gxTextureOpenPNG(Key_Minus_wii_png,0);
|
||||||
gxDrawTexture(key_enable.texture,372,424,24,24,255);
|
gxDrawTexture(key_enable.texture,152,424,24,24,255);
|
||||||
FONT_write("Delete\nCheat",16,184,436,640,(GXColor)WHITE);
|
gxDrawTexture(key_delete.texture,372,424,24,24,255);
|
||||||
FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,404,436,640,(GXColor)WHITE);
|
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
|
#else
|
||||||
key_delete.texture = gxTextureOpenPNG(Key_L_gcn_png,0);
|
key_enable.texture = gxTextureOpenPNG(Key_L_gcn_png,0);
|
||||||
key_enable.texture = gxTextureOpenPNG(Key_R_gcn_png,0);
|
key_delete.texture = gxTextureOpenPNG(Key_R_gcn_png,0);
|
||||||
gxDrawTexture(key_delete.texture,136,426,44,20,255);
|
gxDrawTexture(key_enable.texture,136,426,44,20,255);
|
||||||
gxDrawTexture(key_enable.texture,368,426,44,20,255);
|
gxDrawTexture(key_delete.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,188,436,640,(GXColor)WHITE);
|
||||||
FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,420,436,640,(GXColor)WHITE);
|
FONT_write("Delete\nCheat",16,420,436,640,(GXColor)WHITE);
|
||||||
#endif
|
#endif
|
||||||
gxTextureClose(&key_enable.texture);
|
gxTextureClose(&key_enable.texture);
|
||||||
gxTextureClose(&key_delete.texture);
|
gxTextureClose(&key_delete.texture);
|
||||||
@ -1191,7 +1191,7 @@ void CheatMenu(void)
|
|||||||
if ((offset + selection) < maxcheats)
|
if ((offset + selection) < maxcheats)
|
||||||
{
|
{
|
||||||
/* Special inputs */
|
/* Special inputs */
|
||||||
if (m_input.keys & PAD_TRIGGER_L)
|
if (m_input.keys & PAD_TRIGGER_R)
|
||||||
{
|
{
|
||||||
/* sort cheat list */
|
/* sort cheat list */
|
||||||
for (i = offset + selection + 1; i < maxcheats; i++)
|
for (i = offset + selection + 1; i < maxcheats; i++)
|
||||||
@ -1223,7 +1223,7 @@ void CheatMenu(void)
|
|||||||
/* reset scrolling */
|
/* reset scrolling */
|
||||||
string_offset = 0;
|
string_offset = 0;
|
||||||
}
|
}
|
||||||
else if (m_input.keys & PAD_TRIGGER_R)
|
else if (m_input.keys & PAD_TRIGGER_L)
|
||||||
{
|
{
|
||||||
/* cheat ON/OFF */
|
/* cheat ON/OFF */
|
||||||
cheatlist[offset + selection].enable ^= 1;
|
cheatlist[offset + selection].enable ^= 1;
|
||||||
|
@ -1145,7 +1145,7 @@ static void systemmenu ()
|
|||||||
else
|
else
|
||||||
sprintf (items[7].text, "Lock-On: OFF");
|
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)
|
if (svp)
|
||||||
{
|
{
|
||||||
@ -1233,6 +1233,9 @@ static void systemmenu ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reinitialize audio streams */
|
||||||
|
audio_init(snd.sample_rate, snd.frame_rate);
|
||||||
|
|
||||||
/* force hard reset */
|
/* force hard reset */
|
||||||
system_init();
|
system_init();
|
||||||
system_reset();
|
system_reset();
|
||||||
@ -1389,7 +1392,7 @@ static void systemmenu ()
|
|||||||
case 8: /*** Cartridge Hot Swap ***/
|
case 8: /*** Cartridge Hot Swap ***/
|
||||||
{
|
{
|
||||||
config.hot_swap ^= 1;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1421,6 +1424,12 @@ static void systemmenu ()
|
|||||||
{
|
{
|
||||||
system_init();
|
system_init();
|
||||||
system_reset();
|
system_reset();
|
||||||
|
|
||||||
|
/* restore SRAM */
|
||||||
|
if (config.s_auto & 1)
|
||||||
|
{
|
||||||
|
slot_autoload(0,config.s_device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -182,6 +182,7 @@ void gx_audio_Start(void)
|
|||||||
ASND_End();
|
ASND_End();
|
||||||
AUDIO_StopDMA();
|
AUDIO_StopDMA();
|
||||||
AUDIO_RegisterDMACallback(NULL);
|
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 */
|
/* 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))
|
if (!config.vsync || (config.tv_mode == !vdp_pal))
|
||||||
@ -206,6 +207,7 @@ void gx_audio_Start(void)
|
|||||||
void gx_audio_Stop(void)
|
void gx_audio_Stop(void)
|
||||||
{
|
{
|
||||||
/* restart menu audio processing */
|
/* restart menu audio processing */
|
||||||
|
DSP_Unhalt();
|
||||||
ASND_Init();
|
ASND_Init();
|
||||||
ASND_Pause(0);
|
ASND_Pause(0);
|
||||||
|
|
||||||
|
@ -1218,8 +1218,8 @@ void gx_input_SetDefault(void)
|
|||||||
{
|
{
|
||||||
/* Wiimote */
|
/* Wiimote */
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONA] = WPAD_BUTTON_A;
|
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_BUTTONB] = WPAD_BUTTON_1;
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONC] = 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_START] = WPAD_BUTTON_PLUS;
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONX] = 0;
|
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONX] = 0;
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONY] = 0;
|
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONY] = 0;
|
||||||
@ -1228,8 +1228,8 @@ void gx_input_SetDefault(void)
|
|||||||
|
|
||||||
/* Wiimote + Nunchuk */
|
/* 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_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_BUTTONB] = WPAD_BUTTON_B;
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONC] = 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_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_BUTTONX] = WPAD_NUNCHUK_BUTTON_C;
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONY] = WPAD_BUTTON_1;
|
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_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_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_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_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR;
|
||||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONZ] = 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;
|
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_MODE] = WPAD_CLASSIC_BUTTON_MINUS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -118,7 +118,7 @@ static void init_machine(void)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* check BOOT ROM */
|
/* 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 */
|
/* mark Genesis BIOS as loaded */
|
||||||
system_bios = SYSTEM_MD;
|
system_bios = SYSTEM_MD;
|
||||||
|
@ -54,6 +54,8 @@
|
|||||||
#define CD_BRAM_JP "/genplus/saves/cd/scd_J.brm"
|
#define CD_BRAM_JP "/genplus/saves/cd/scd_J.brm"
|
||||||
#define CART_BRAM "/genplus/saves/cd/cart.brm"
|
#define CART_BRAM "/genplus/saves/cd/cart.brm"
|
||||||
|
|
||||||
|
#define ALIGN_SND 0xfffffff8 /* 32 bytes aligned sound buffers (8 samples alignment) */
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
|
@ -403,13 +403,13 @@ int load_bios(void)
|
|||||||
switch (region_code)
|
switch (region_code)
|
||||||
{
|
{
|
||||||
case REGION_USA:
|
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;
|
break;
|
||||||
case REGION_EUROPE:
|
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;
|
break;
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,12 +431,6 @@ int load_bios(void)
|
|||||||
|
|
||||||
/* loaded BIOS region */
|
/* loaded BIOS region */
|
||||||
system_bios = (system_bios & 0xf0) | (region_code >> 4);
|
system_bios = (system_bios & 0xf0) | (region_code >> 4);
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* CD BOOT ROM disabled (SYSTEM ERROR) */
|
|
||||||
memset(scd.bootrom, 0xff, sizeof(scd.bootrom));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -458,7 +452,7 @@ int load_bios(void)
|
|||||||
if (cart.romsize <= 0x400000)
|
if (cart.romsize <= 0x400000)
|
||||||
{
|
{
|
||||||
/* load Game Gear "BIOS" file */
|
/* 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)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
@ -489,13 +483,13 @@ int load_bios(void)
|
|||||||
switch (region_code)
|
switch (region_code)
|
||||||
{
|
{
|
||||||
case REGION_USA:
|
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;
|
break;
|
||||||
case REGION_EUROPE:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000);
|
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,14 +537,19 @@ int load_rom(char *filename)
|
|||||||
ggenie_shutdown();
|
ggenie_shutdown();
|
||||||
areplay_shutdown();
|
areplay_shutdown();
|
||||||
|
|
||||||
/* unload any existing disc */
|
|
||||||
if (romtype == SYSTEM_MCD)
|
if (romtype == SYSTEM_MCD)
|
||||||
{
|
{
|
||||||
|
/* unload CD image */
|
||||||
cdd_unload();
|
cdd_unload();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no CD image loaded */
|
||||||
|
cdd.loaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* .cue file support */
|
/* .cue file support */
|
||||||
if (!strncmp(".cue", &filename[strlen(filename) - 4], 4))
|
if (!memcmp(".cue", &filename[strlen(filename) - 4], 4))
|
||||||
{
|
{
|
||||||
/* open associated .bin file */
|
/* open associated .bin file */
|
||||||
strncpy(&filename[strlen(filename) - 4], ".bin", 4);
|
strncpy(&filename[strlen(filename) - 4], ".bin", 4);
|
||||||
@ -565,7 +564,7 @@ int load_rom(char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* auto-detect CD image file */
|
/* auto-detect CD image file */
|
||||||
if (!strncmp("SEGADISCSYSTEM", buf + 0x10, 14))
|
if (!memcmp("SEGADISCSYSTEM", buf + 0x10, 14))
|
||||||
{
|
{
|
||||||
/* file header pointer (BIN format) */
|
/* file header pointer (BIN format) */
|
||||||
header = buf + 0x10;
|
header = buf + 0x10;
|
||||||
@ -573,7 +572,7 @@ int load_rom(char *filename)
|
|||||||
/* enable CD hardware */
|
/* enable CD hardware */
|
||||||
system_hw = SYSTEM_MCD;
|
system_hw = SYSTEM_MCD;
|
||||||
}
|
}
|
||||||
else if (!strncmp("SEGADISCSYSTEM", buf, 14))
|
else if (!memcmp("SEGADISCSYSTEM", buf, 14))
|
||||||
{
|
{
|
||||||
/* file header pointer (ISO format) */
|
/* file header pointer (ISO format) */
|
||||||
header = buf;
|
header = buf;
|
||||||
@ -583,25 +582,30 @@ int load_rom(char *filename)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* load file into ROM buffer (input filename is overwritten by uncompressed filename) */
|
/* load file into ROM buffer */
|
||||||
int size = load_archive(filename, cart.rom, sizeof(cart.rom));
|
char extension[4];
|
||||||
if (!size) return(0);
|
int size = load_archive(filename, cart.rom, sizeof(cart.rom), extension);
|
||||||
|
|
||||||
/* mark CD BIOS as unloaded */
|
/* mark CD BIOS as unloaded */
|
||||||
system_bios &= ~0x10;
|
system_bios &= ~0x10;
|
||||||
|
|
||||||
|
if (!size) return(0);
|
||||||
|
|
||||||
|
/* convert lower case to upper case */
|
||||||
|
*(uint32 *)(extension) &= 0xdfdfdfdf;
|
||||||
|
|
||||||
/* Auto-detect system hardware from ROM file extension */
|
/* 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 */
|
/* Master System II hardware */
|
||||||
system_hw = SYSTEM_SMS2;
|
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) */
|
/* Game Gear hardware (GG mode) */
|
||||||
system_hw = SYSTEM_GG;
|
system_hw = SYSTEM_GG;
|
||||||
}
|
}
|
||||||
else if (!strncmp(".sg", &filename[strlen(filename) - 3], 3))
|
else if (!memcmp("SG", &extension[1], 2))
|
||||||
{
|
{
|
||||||
/* SG-1000 hardware */
|
/* SG-1000 hardware */
|
||||||
system_hw = SYSTEM_SG;
|
system_hw = SYSTEM_SG;
|
||||||
@ -612,7 +616,7 @@ int load_rom(char *filename)
|
|||||||
system_hw = SYSTEM_MD;
|
system_hw = SYSTEM_MD;
|
||||||
|
|
||||||
/* Decode .MDX format */
|
/* Decode .MDX format */
|
||||||
if (!strncmp(".mdx", &filename[strlen(filename) - 4], 4))
|
if (!memcmp("MDX", &extension[0], 3))
|
||||||
{
|
{
|
||||||
for (i = 4; i < size - 1; i++)
|
for (i = 4; i < size - 1; i++)
|
||||||
{
|
{
|
||||||
@ -623,7 +627,7 @@ int load_rom(char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* auto-detect 512 byte extra header */
|
/* 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 */
|
/* remove header */
|
||||||
size -= 512;
|
size -= 512;
|
||||||
@ -713,8 +717,11 @@ int load_rom(char *filename)
|
|||||||
/* boot from CD */
|
/* boot from CD */
|
||||||
scd.cartridge.boot = 0x00;
|
scd.cartridge.boot = 0x00;
|
||||||
|
|
||||||
/* CD unloaded */
|
/* no CD image loaded */
|
||||||
cdd.loaded = 0;
|
cdd.loaded = 0;
|
||||||
|
|
||||||
|
/* clear CD TOC */
|
||||||
|
cdd_unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* special ROM cartridges that use CD hardware */
|
/* special ROM cartridges that use CD hardware */
|
||||||
@ -729,9 +736,12 @@ int load_rom(char *filename)
|
|||||||
/* load CD BOOT ROM */
|
/* load CD BOOT ROM */
|
||||||
if (load_bios())
|
if (load_bios())
|
||||||
{
|
{
|
||||||
/* CD unloaded */
|
/* no CD image loaded */
|
||||||
cdd.loaded = 0;
|
cdd.loaded = 0;
|
||||||
|
|
||||||
|
/* clear CD TOC */
|
||||||
|
cdd_unload();
|
||||||
|
|
||||||
/* boot from cartridge */
|
/* boot from cartridge */
|
||||||
scd.cartridge.boot = 0x40;
|
scd.cartridge.boot = 0x40;
|
||||||
}
|
}
|
||||||
@ -739,6 +749,9 @@ int load_rom(char *filename)
|
|||||||
{
|
{
|
||||||
/* assume Mega Drive hardware */
|
/* assume Mega Drive hardware */
|
||||||
system_hw = SYSTEM_MD;
|
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;
|
int country = 0;
|
||||||
|
|
||||||
/* from Gens */
|
/* from Gens */
|
||||||
if (!strncmp(rominfo.country, "eur", 3)) country |= 8;
|
if (!memcmp(rominfo.country, "eur", 3)) country |= 8;
|
||||||
else if (!strncmp(rominfo.country, "EUR", 3)) country |= 8;
|
else if (!memcmp(rominfo.country, "EUR", 3)) country |= 8;
|
||||||
else if (!strncmp(rominfo.country, "jap", 3)) country |= 1;
|
else if (!memcmp(rominfo.country, "jap", 3)) country |= 1;
|
||||||
else if (!strncmp(rominfo.country, "JAP", 3)) country |= 1;
|
else if (!memcmp(rominfo.country, "JAP", 3)) country |= 1;
|
||||||
else if (!strncmp(rominfo.country, "usa", 3)) country |= 4;
|
else if (!memcmp(rominfo.country, "usa", 3)) country |= 4;
|
||||||
else if (!strncmp(rominfo.country, "USA", 3)) country |= 4;
|
else if (!memcmp(rominfo.country, "USA", 3)) country |= 4;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -273,7 +273,11 @@ void m68k_run(unsigned int cycles)
|
|||||||
|
|
||||||
/* Save end cycles count for when CPU is stopped */
|
/* Save end cycles count for when CPU is stopped */
|
||||||
m68k.cycle_end = cycles;
|
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)
|
while (m68k.cycles < cycles)
|
||||||
{
|
{
|
||||||
/* Set tracing accodring to T1. */
|
/* Set tracing accodring to T1. */
|
||||||
|
@ -211,13 +211,13 @@ void s68k_update_irq(unsigned int mask)
|
|||||||
|
|
||||||
/* Set IRQ level */
|
/* Set IRQ level */
|
||||||
CPU_INT_LEVEL = mask << 8;
|
CPU_INT_LEVEL = mask << 8;
|
||||||
|
|
||||||
/* Check interrupt mask to process IRQ */
|
|
||||||
m68ki_check_interrupts();
|
|
||||||
|
|
||||||
#ifdef LOG_SCD
|
#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);
|
error("[%d][%d] IRQ Level = %d(0x%02x) (%x)\n", v_counter, s68k.cycles, CPU_INT_LEVEL>>8,FLAG_INT_MASK,s68k.pc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Check interrupt mask to process IRQ */
|
||||||
|
m68ki_check_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void s68k_run(unsigned int cycles)
|
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 */
|
/* Save end cycles count for when CPU is stopped */
|
||||||
s68k.cycle_end = cycles;
|
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)
|
while (s68k.cycles < cycles)
|
||||||
{
|
{
|
||||||
/* Set tracing accodring to T1. */
|
/* Set tracing accodring to T1. */
|
||||||
|
@ -233,6 +233,9 @@ INLINE void m68k_poll_detect(reg)
|
|||||||
if (m68k.pc == m68k.poll.pc)
|
if (m68k.pc == m68k.poll.pc)
|
||||||
{
|
{
|
||||||
/* stop MAIN-CPU until register is modified by SUB-CPU */
|
/* 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.cycles = m68k.cycle_end;
|
||||||
m68k.stopped = 1 << reg;
|
m68k.stopped = 1 << reg;
|
||||||
}
|
}
|
||||||
@ -269,6 +272,9 @@ INLINE void m68k_poll_sync(reg)
|
|||||||
|
|
||||||
/* restart SUB-CPU */
|
/* restart SUB-CPU */
|
||||||
s68k.stopped = 0;
|
s68k.stopped = 0;
|
||||||
|
#ifdef LOG_SCD
|
||||||
|
error("s68k started from %d cycles\n", cycles);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear CPU register(s) access flags */
|
/* clear CPU register(s) access flags */
|
||||||
|
@ -46,7 +46,7 @@ int state_load(unsigned char *state)
|
|||||||
char version[17];
|
char version[17];
|
||||||
load_param(version,16);
|
load_param(version,16);
|
||||||
version[16] = 0;
|
version[16] = 0;
|
||||||
if (strncmp(version,STATE_VERSION,11))
|
if (memcmp(version,STATE_VERSION,11))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -178,9 +178,9 @@ int audio_update(int16 *buffer)
|
|||||||
/* get number of available samples */
|
/* get number of available samples */
|
||||||
int size = sound_update(mcycles_vdp);
|
int size = sound_update(mcycles_vdp);
|
||||||
|
|
||||||
#ifndef __LIBRETRO__
|
#ifdef ALIGN_SND
|
||||||
/* return an aligned number of samples */
|
/* return an aligned number of samples if necessary*/
|
||||||
size &= ~7;
|
size &= ALIGN_SND;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (config.hq_fm)
|
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_68k_data_r)(void);
|
||||||
unsigned int (*vdp_z80_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 */
|
/* Tables that define the playfield layout */
|
||||||
static const uint8 hscroll_mask_table[] = { 0x00, 0x07, 0xF8, 0xFF };
|
static const uint8 hscroll_mask_table[] = { 0x00, 0x07, 0xF8, 0xFF };
|
||||||
static const uint8 shift_table[] = { 6, 7, 0, 8 };
|
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)(unsigned int level);
|
||||||
static void (*set_irq_line_delay)(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) */
|
/* Vertical counter overflow values (see hvc.h) */
|
||||||
static const uint16 vc_table[4][2] =
|
static const uint16 vc_table[4][2] =
|
||||||
{
|
{
|
||||||
@ -139,27 +152,30 @@ static const uint16 vc_table[4][2] =
|
|||||||
{0x106, 0x10A} /* Mode 5 (240 lines) */
|
{0x106, 0x10A} /* Mode 5 (240 lines) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/* DMA Timings (number of access slots per line) */
|
||||||
/* Function prototypes */
|
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 */
|
/* Init, reset, context functions */
|
||||||
@ -608,30 +624,8 @@ void vdp_dma_update(unsigned int cycles)
|
|||||||
/* Update DMA length */
|
/* Update DMA length */
|
||||||
dma_length -= dma_bytes;
|
dma_length -= dma_bytes;
|
||||||
|
|
||||||
/* Select DMA operation */
|
/* Process DMA operation */
|
||||||
switch (dma_type)
|
dma_func[reg[23] >> 4](dma_bytes);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if DMA is finished */
|
/* Check if DMA is finished */
|
||||||
if (!dma_length)
|
if (!dma_length)
|
||||||
@ -2868,78 +2862,112 @@ static void vdp_z80_data_w_sg(unsigned int data)
|
|||||||
/* DMA operations */
|
/* DMA operations */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* 68K bus to VRAM, VSRAM or CRAM */
|
/* DMA from 68K bus: $000000-$7FFFFF (external area) */
|
||||||
static void vdp_dma_vbus(unsigned int length)
|
static void vdp_dma_68k_ext(unsigned int length)
|
||||||
{
|
{
|
||||||
uint16 data;
|
uint16 data;
|
||||||
|
|
||||||
/* 68k bus source address */
|
/* 68k bus source address */
|
||||||
uint32 source = (reg[23] << 17) | (dma_src << 1);
|
uint32 source = (reg[23] << 17) | (dma_src << 1);
|
||||||
|
|
||||||
/* Z80 & I/O area ($A00000-$A1FFFF) specific */
|
do
|
||||||
if (reg[23] == 0x50)
|
|
||||||
{
|
{
|
||||||
do
|
/* Read data word from 68k bus */
|
||||||
|
if (m68k.memory_map[source>>16].read16)
|
||||||
{
|
{
|
||||||
/* Z80 area */
|
data = m68k.memory_map[source>>16].read16(source);
|
||||||
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);
|
else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
/* Read data word from 68k bus */
|
data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF));
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment source address */
|
/* Increment source address */
|
||||||
source += 2;
|
source += 2;
|
||||||
|
|
||||||
/* 128k DMA window */
|
/* 128k DMA window */
|
||||||
source = (reg[23] << 17) | (source & 0x1FFFF);
|
source = (reg[23] << 17) | (source & 0x1FFFF);
|
||||||
|
|
||||||
/* Write data word to VRAM, CRAM or VSRAM */
|
/* Write data word to VRAM, CRAM or VSRAM */
|
||||||
vdp_bus_w(data);
|
vdp_bus_w(data);
|
||||||
}
|
|
||||||
while (--length);
|
|
||||||
}
|
}
|
||||||
|
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 */
|
/* Update DMA source address */
|
||||||
dma_src = (source >> 1) & 0xffff;
|
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) */
|
/* 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) */
|
/* VRAM write operation only (Williams Greatest Hits after soft reset) */
|
||||||
if ((code & 0x1F) == 0x01)
|
if ((code & 0x1F) == 0x01)
|
||||||
{
|
{
|
||||||
int name;
|
int name;
|
||||||
|
uint8 data = dmafill;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Intercept writes to Sprite Attribute Table */
|
/* Intercept writes to Sprite Attribute Table */
|
||||||
|
@ -45,9 +45,8 @@
|
|||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
static int check_zip(char *filename);
|
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;
|
int size = 0;
|
||||||
|
|
||||||
@ -55,6 +54,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
|||||||
{
|
{
|
||||||
unz_file_info info;
|
unz_file_info info;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
char fname[256];
|
||||||
|
|
||||||
/* Attempt to open the archive */
|
/* Attempt to open the archive */
|
||||||
unzFile *fd = unzOpen(filename);
|
unzFile *fd = unzOpen(filename);
|
||||||
@ -69,13 +69,20 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get file informations and update filename */
|
/* 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)
|
if(ret != UNZ_OK)
|
||||||
{
|
{
|
||||||
unzClose(fd);
|
unzClose(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compressed filename extension */
|
||||||
|
if (extension)
|
||||||
|
{
|
||||||
|
strncpy(extension, &fname[strlen(fname) - 3], 3);
|
||||||
|
extension[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the file for reading */
|
/* Open the file for reading */
|
||||||
ret = unzOpenCurrentFile(fd);
|
ret = unzOpenCurrentFile(fd);
|
||||||
if(ret != UNZ_OK)
|
if(ret != UNZ_OK)
|
||||||
@ -121,6 +128,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
|||||||
/* Read file data */
|
/* Read file data */
|
||||||
size = gzread(gd, buffer, maxsize);
|
size = gzread(gd, buffer, maxsize);
|
||||||
|
|
||||||
|
/* filename extension */
|
||||||
|
if (extension)
|
||||||
|
{
|
||||||
|
strncpy(extension, &filename[strlen(filename) - 3], 3);
|
||||||
|
extension[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Close file */
|
/* Close file */
|
||||||
gzclose(gd);
|
gzclose(gd);
|
||||||
}
|
}
|
||||||
@ -143,25 +157,3 @@ static int check_zip(char *filename)
|
|||||||
if(memcmp(buf, "PK", 2) == 0) return (1);
|
if(memcmp(buf, "PK", 2) == 0) return (1);
|
||||||
return (0);
|
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_
|
#define _FILEIO_H_
|
||||||
|
|
||||||
/* Function prototypes */
|
/* 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_ */
|
#endif /* _FILEIO_H_ */
|
||||||
|
@ -701,7 +701,7 @@ int main (int argc, char **argv)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* check BOOT ROM */
|
/* 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 */
|
/* mark Genesis BIOS as loaded */
|
||||||
system_bios = SYSTEM_MD;
|
system_bios = SYSTEM_MD;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user