mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-30 21:21:49 +01:00
commit
5ea9a525e1
@ -43,6 +43,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
|||||||
---------------
|
---------------
|
||||||
* added support for some new unlicensed games with copy protection (Thunderbolt II, Tom Clown, Chaoji Puke / Super Poker)
|
* added support for some new unlicensed games with copy protection (Thunderbolt II, Tom Clown, Chaoji Puke / Super Poker)
|
||||||
* added support for Everdrive extended SSF mapper
|
* added support for Everdrive extended SSF mapper
|
||||||
|
* added (very basic) emulation of Flashkit MD hardware
|
||||||
* improved console region auto-detection for a few PAL-only games (The Smurfs Travel the World & Williams Arcade's Greatest Hits)
|
* improved console region auto-detection for a few PAL-only games (The Smurfs Travel the World & Williams Arcade's Greatest Hits)
|
||||||
* improved I2C EEPROM boards emulation accuracy
|
* improved I2C EEPROM boards emulation accuracy
|
||||||
* improved SVP memory handlers accuracy (fixes Virtua Racing debug mode)
|
* improved SVP memory handlers accuracy (fixes Virtua Racing debug mode)
|
||||||
@ -105,6 +106,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
|||||||
* improved FIFO timings accuracy (fixes "Overdrive" Demo)
|
* improved FIFO timings accuracy (fixes "Overdrive" Demo)
|
||||||
* improved H-Counter accuracy in H32 mode
|
* improved H-Counter accuracy in H32 mode
|
||||||
* improved VDP status timing accuracy
|
* improved VDP status timing accuracy
|
||||||
|
* improved DMA timing accuracy during blanking (verified on real hardware by Mask of Destiny)
|
||||||
* improved accuracy of Master System color palette brightness range (verified against real hardware)
|
* improved accuracy of Master System color palette brightness range (verified against real hardware)
|
||||||
* fixed misaligned buffer writes in Mode 4 when -DALIGN_LONG option is used
|
* fixed misaligned buffer writes in Mode 4 when -DALIGN_LONG option is used
|
||||||
* fixed alpha channel for 15-bit (RGB555) and 32-bit (RGB888) color support
|
* fixed alpha channel for 15-bit (RGB555) and 32-bit (RGB888) color support
|
||||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
Binary file not shown.
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* Mega Drive cartridge hardware support
|
* Mega Drive cartridge hardware support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Many cartridge protections were initially documented by Haze
|
* Many cartridge protections were initially documented by Haze
|
||||||
* (http://haze.mameworld.info/)
|
* (http://haze.mameworld.info/)
|
||||||
@ -65,6 +65,8 @@ static void mapper_sf004_w(uint32 address, uint32 data);
|
|||||||
static uint32 mapper_sf004_r(uint32 address);
|
static uint32 mapper_sf004_r(uint32 address);
|
||||||
static void mapper_t5740_w(uint32 address, uint32 data);
|
static void mapper_t5740_w(uint32 address, uint32 data);
|
||||||
static uint32 mapper_t5740_r(uint32 address);
|
static uint32 mapper_t5740_r(uint32 address);
|
||||||
|
static void mapper_flashkit_w(uint32 address, uint32 data);
|
||||||
|
static uint32 mapper_flashkit_r(uint32 address);
|
||||||
static uint32 mapper_smw_64_r(uint32 address);
|
static uint32 mapper_smw_64_r(uint32 address);
|
||||||
static void mapper_smw_64_w(uint32 address, uint32 data);
|
static void mapper_smw_64_w(uint32 address, uint32 data);
|
||||||
static void mapper_realtec_w(uint32 address, uint32 data);
|
static void mapper_realtec_w(uint32 address, uint32 data);
|
||||||
@ -628,6 +630,13 @@ void md_cart_init(void)
|
|||||||
zbank_memory_map[i].write = zbank_unused_w;
|
zbank_memory_map[i].write = zbank_unused_w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strstr(rominfo.ROMType,"GM") && strstr(rominfo.product,"00000000-42"))
|
||||||
|
{
|
||||||
|
/* Flashkit MD mapper */
|
||||||
|
m68k.memory_map[0x00].write8 = mapper_flashkit_w;
|
||||||
|
m68k.memory_map[0x00].write16 = mapper_flashkit_w;
|
||||||
|
zbank_memory_map[0x00].write = mapper_flashkit_w;
|
||||||
|
}
|
||||||
else if ((*(uint16 *)(cart.rom + 0x08) == 0x6000) && (*(uint16 *)(cart.rom + 0x0a) == 0x01f6) && (rominfo.realchecksum == 0xf894))
|
else if ((*(uint16 *)(cart.rom + 0x08) == 0x6000) && (*(uint16 *)(cart.rom + 0x0a) == 0x01f6) && (rominfo.realchecksum == 0xf894))
|
||||||
{
|
{
|
||||||
/* Super Mario World 64 (unlicensed) mapper */
|
/* Super Mario World 64 (unlicensed) mapper */
|
||||||
@ -1267,6 +1276,44 @@ static uint32 mapper_t5740_r(uint32 address)
|
|||||||
return READ_BYTE(cart.rom, address);
|
return READ_BYTE(cart.rom, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
FlashKit MD mapper (very limited M29W320xx Flash memory support -- enough for unlicensed games using device signature as protection)
|
||||||
|
*/
|
||||||
|
static void mapper_flashkit_w(uint32 address, uint32 data)
|
||||||
|
{
|
||||||
|
/* Increment Bus Write counter */
|
||||||
|
cart.hw.regs[0]++;
|
||||||
|
|
||||||
|
/* Wait for 3 consecutive bus writes */
|
||||||
|
if (cart.hw.regs[0] == 3)
|
||||||
|
{
|
||||||
|
/* assume 'Auto Select' command */
|
||||||
|
m68k.memory_map[0x0].read16 = mapper_flashkit_r;
|
||||||
|
}
|
||||||
|
else if (cart.hw.regs[0] == 4)
|
||||||
|
{
|
||||||
|
/* assume 'Read/Reset' command */
|
||||||
|
m68k.memory_map[0x0].read16 = NULL;
|
||||||
|
|
||||||
|
/* reset Bus Write counter */
|
||||||
|
cart.hw.regs[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 mapper_flashkit_r(uint32 address)
|
||||||
|
{
|
||||||
|
/* hard-coded device signature */
|
||||||
|
switch (address & 0x06)
|
||||||
|
{
|
||||||
|
case 0x00: /* Manufacturer Code (STMicroelectronics) */
|
||||||
|
return 0x0020;
|
||||||
|
case 0x02: /* Device Code (M29W320EB) */
|
||||||
|
return 0x2257;
|
||||||
|
default: /* not supported */
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Super Mario World 64 (unlicensed) mapper
|
Super Mario World 64 (unlicensed) mapper
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* Mega Drive cartridge hardware support
|
* Mega Drive cartridge hardware support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Most cartridge protections were initially documented by Haze
|
* Most cartridge protections were initially documented by Haze
|
||||||
* (http://haze.mameworld.info/)
|
* (http://haze.mameworld.info/)
|
||||||
|
176
core/cd_hw/cdd.c
176
core/cd_hw/cdd.c
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* CD drive processor & CD-DA fader
|
* CD drive processor & CD-DA fader
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2012-2017 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -183,6 +183,19 @@ static const char extensions[SUPPORTED_EXT][16] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
|
|
||||||
|
static int seek64_wrap(void *f,ogg_int64_t off,int whence){
|
||||||
|
return cdStreamSeek(f,off,whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ov_callbacks cb =
|
||||||
|
{
|
||||||
|
(size_t (*)(void *, size_t, size_t, void *)) cdStreamRead,
|
||||||
|
(int (*)(void *, ogg_int64_t, int)) seek64_wrap,
|
||||||
|
(int (*)(void *)) cdStreamClose,
|
||||||
|
(long (*)(void *)) cdStreamTell
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef DISABLE_MANY_OGG_OPEN_FILES
|
#ifdef DISABLE_MANY_OGG_OPEN_FILES
|
||||||
static void ogg_free(int i)
|
static void ogg_free(int i)
|
||||||
{
|
{
|
||||||
@ -196,9 +209,10 @@ static void ogg_free(int i)
|
|||||||
cdd.toc.tracks[i].vf.seekable = 1;
|
cdd.toc.tracks[i].vf.seekable = 1;
|
||||||
|
|
||||||
/* reset file reading position */
|
/* reset file reading position */
|
||||||
filestream_seek(cdd.toc.tracks[i].fd, 0, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[i].fd, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void cdd_init(int samplerate)
|
void cdd_init(int samplerate)
|
||||||
@ -281,21 +295,21 @@ int cdd_context_load(uint8 *state)
|
|||||||
if (cdd.toc.sub)
|
if (cdd.toc.sub)
|
||||||
{
|
{
|
||||||
/* 96 bytes per sector */
|
/* 96 bytes per sector */
|
||||||
filestream_seek(cdd.toc.sub, lba * 96, SEEK_SET);
|
cdStreamSeek(cdd.toc.sub, lba * 96, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current track position */
|
/* seek to current track position */
|
||||||
if (cdd.toc.tracks[cdd.index].type)
|
if (cdd.toc.tracks[cdd.index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
filestream_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||||
}
|
}
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
else if (cdd.toc.tracks[cdd.index].vf.seekable)
|
else if (cdd.toc.tracks[cdd.index].vf.seekable)
|
||||||
{
|
{
|
||||||
#ifdef DISABLE_MANY_OGG_OPEN_FILES
|
#ifdef DISABLE_MANY_OGG_OPEN_FILES
|
||||||
/* VORBIS file need to be opened first */
|
/* VORBIS file need to be opened first */
|
||||||
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,fs_ov_callbacks);
|
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,cb);
|
||||||
#endif
|
#endif
|
||||||
/* VORBIS AUDIO track */
|
/* VORBIS AUDIO track */
|
||||||
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba * 588) - cdd.toc.tracks[cdd.index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba * 588) - cdd.toc.tracks[cdd.index].offset);
|
||||||
@ -304,7 +318,7 @@ int cdd_context_load(uint8 *state)
|
|||||||
else if (cdd.toc.tracks[cdd.index].fd)
|
else if (cdd.toc.tracks[cdd.index].fd)
|
||||||
{
|
{
|
||||||
/* PCM AUDIO track */
|
/* PCM AUDIO track */
|
||||||
filestream_seek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bufferptr;
|
return bufferptr;
|
||||||
@ -315,7 +329,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
char fname[256+10];
|
char fname[256+10];
|
||||||
char line[128];
|
char line[128];
|
||||||
char *ptr, *lptr;
|
char *ptr, *lptr;
|
||||||
FILE *fd;
|
cdStream *fd;
|
||||||
|
|
||||||
/* assume CD image file by default */
|
/* assume CD image file by default */
|
||||||
int isCDfile = 1;
|
int isCDfile = 1;
|
||||||
@ -324,7 +338,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd_unload();
|
cdd_unload();
|
||||||
|
|
||||||
/* open file */
|
/* open file */
|
||||||
fd = filestream_open(filename, RFILE_MODE_READ, -1);
|
fd = cdStreamOpen(filename);
|
||||||
if (!fd) return (-1);
|
if (!fd) return (-1);
|
||||||
|
|
||||||
/* save a copy of base filename */
|
/* save a copy of base filename */
|
||||||
@ -336,7 +350,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* read first 16 bytes */
|
/* read first 16 bytes */
|
||||||
filestream_read(fd, header, 0x10);
|
cdStreamRead(header, 0x10, 1, fd);
|
||||||
|
|
||||||
/* look for valid CD image identifier */
|
/* look for valid CD image identifier */
|
||||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||||
@ -347,7 +361,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* read next 16 bytes */
|
/* read next 16 bytes */
|
||||||
filestream_read(fd, header, 0x10);
|
cdStreamRead(header, 0x10, 1, fd);
|
||||||
|
|
||||||
/* look for valid CD image identifier */
|
/* look for valid CD image identifier */
|
||||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||||
@ -361,7 +375,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
if (cdd.sectorSize)
|
if (cdd.sectorSize)
|
||||||
{
|
{
|
||||||
/* read CD image header + security code */
|
/* read CD image header + security code */
|
||||||
filestream_read(fd, header + 0x10, 0x200);
|
cdStreamRead(header + 0x10, 0x200, 1, fd);
|
||||||
|
|
||||||
/* initialize first track file descriptor */
|
/* initialize first track file descriptor */
|
||||||
cdd.toc.tracks[0].fd = fd;
|
cdd.toc.tracks[0].fd = fd;
|
||||||
@ -370,8 +384,8 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.toc.tracks[0].type = TYPE_CDROM;
|
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||||
|
|
||||||
/* DATA track end LBA (based on DATA file length) */
|
/* DATA track end LBA (based on DATA file length) */
|
||||||
filestream_seek(fd, 0, SEEK_END);
|
cdStreamSeek(fd, 0, SEEK_END);
|
||||||
cdd.toc.tracks[0].end = filestream_tell(fd) / cdd.sectorSize;
|
cdd.toc.tracks[0].end = cdStreamTell(fd) / cdd.sectorSize;
|
||||||
|
|
||||||
/* DATA track length should be at least 2s (BIOS requirement) */
|
/* DATA track length should be at least 2s (BIOS requirement) */
|
||||||
if (cdd.toc.tracks[0].end < 150)
|
if (cdd.toc.tracks[0].end < 150)
|
||||||
@ -380,7 +394,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* DATA track start LBA (logical block 0) */
|
/* DATA track start LBA (logical block 0) */
|
||||||
filestream_seek(fd, 0, SEEK_SET);
|
cdStreamSeek(fd, 0, SEEK_SET);
|
||||||
cdd.toc.tracks[0].start = 0;
|
cdd.toc.tracks[0].start = 0;
|
||||||
|
|
||||||
/* initialize TOC */
|
/* initialize TOC */
|
||||||
@ -393,14 +407,14 @@ int cdd_load(char *filename, char *header)
|
|||||||
isCDfile = 0;
|
isCDfile = 0;
|
||||||
|
|
||||||
/* close file */
|
/* close file */
|
||||||
filestream_close(fd);
|
cdStreamClose(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* automatically try to mount CD associated CUE file */
|
/* automatically try to mount CD associated CUE file */
|
||||||
len = strlen(fname);
|
len = strlen(fname);
|
||||||
while ((len && (fname[len] != '.')) || (len > 251)) len--;
|
while ((len && (fname[len] != '.')) || (len > 251)) len--;
|
||||||
strcpy(&fname[len], ".cue");
|
strcpy(&fname[len], ".cue");
|
||||||
fd = filestream_open(fname, RFILE_MODE_READ, -1);
|
fd = cdStreamOpen(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse CUE file */
|
/* parse CUE file */
|
||||||
@ -412,7 +426,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
if (cdd.toc.last)
|
if (cdd.toc.last)
|
||||||
{
|
{
|
||||||
/* skip first track */
|
/* skip first track */
|
||||||
while (filestream_gets(fd, line, 128))
|
while (cdStreamGets(line, 128, fd))
|
||||||
{
|
{
|
||||||
if (strstr(line, "INDEX 01") && !strstr(line, "INDEX 1"))
|
if (strstr(line, "INDEX 01") && !strstr(line, "INDEX 1"))
|
||||||
break;
|
break;
|
||||||
@ -420,7 +434,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read lines until end of file */
|
/* read lines until end of file */
|
||||||
while (filestream_gets(fd, line, 128))
|
while (cdStreamGets(line, 128, fd))
|
||||||
{
|
{
|
||||||
/* skip any SPACE characters */
|
/* skip any SPACE characters */
|
||||||
lptr = line;
|
lptr = line;
|
||||||
@ -457,7 +471,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
|
|
||||||
/* open current track file descriptor */
|
/* open current track file descriptor */
|
||||||
cdd.toc.tracks[cdd.toc.last].fd = filestream_open(fname, RFILE_MODE_READ, -1);
|
cdd.toc.tracks[cdd.toc.last].fd = cdStreamOpen(fname);
|
||||||
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
{
|
{
|
||||||
/* error opening file */
|
/* error opening file */
|
||||||
@ -475,32 +489,32 @@ int cdd_load(char *filename, char *header)
|
|||||||
{
|
{
|
||||||
/* read file header */
|
/* read file header */
|
||||||
unsigned char head[28];
|
unsigned char head[28];
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, 8, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 8, SEEK_SET);
|
||||||
filestream_read(cdd.toc.tracks[cdd.toc.last].fd, head, 28);
|
cdStreamRead(head, 28, 1, cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||||
|
|
||||||
/* autodetect WAVE file header (44.1KHz 16-bit stereo format only) */
|
/* autodetect WAVE file header (44.1KHz 16-bit stereo format only) */
|
||||||
if (!memcmp(head, waveHeader, 28))
|
if (!memcmp(head, waveHeader, 28))
|
||||||
{
|
{
|
||||||
/* look for 'data' chunk id */
|
/* look for 'data' chunk id */
|
||||||
int dataOffset = 0;
|
int dataOffset = 0;
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, 36, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 36, SEEK_SET);
|
||||||
while (filestream_read(cdd.toc.tracks[cdd.toc.last].fd, head, 4))
|
while (cdStreamRead(head, 4, 1, cdd.toc.tracks[cdd.toc.last].fd))
|
||||||
{
|
{
|
||||||
if (!memcmp(head, "data", 4))
|
if (!memcmp(head, "data", 4))
|
||||||
{
|
{
|
||||||
dataOffset = filestream_tell(cdd.toc.tracks[cdd.toc.last].fd) + 4;
|
dataOffset = cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) + 4;
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, -2, SEEK_CUR);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, -2, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if 'data' chunk has not been found */
|
/* check if 'data' chunk has not been found */
|
||||||
if (!dataOffset)
|
if (!dataOffset)
|
||||||
{
|
{
|
||||||
/* invalid WAVE file */
|
/* invalid WAVE file */
|
||||||
filestream_close(cdd.toc.tracks[cdd.toc.last].fd);
|
cdStreamClose(cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -509,7 +523,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.toc.tracks[cdd.toc.last].offset -= dataOffset;
|
cdd.toc.tracks[cdd.toc.last].offset -= dataOffset;
|
||||||
}
|
}
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
else if (!ov_open_callbacks(cdd.toc.tracks[cdd.toc.last].fd,&cdd.toc.tracks[cdd.toc.last].vf,0,0,fs_ov_callbacks))
|
else if (!ov_open_callbacks(cdd.toc.tracks[cdd.toc.last].fd,&cdd.toc.tracks[cdd.toc.last].vf,0,0,cb))
|
||||||
{
|
{
|
||||||
/* retrieve stream infos */
|
/* retrieve stream infos */
|
||||||
vorbis_info *info = ov_info(&cdd.toc.tracks[cdd.toc.last].vf,-1);
|
vorbis_info *info = ov_info(&cdd.toc.tracks[cdd.toc.last].vf,-1);
|
||||||
@ -525,7 +539,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* unsupported audio file */
|
/* unsupported audio file */
|
||||||
filestream_close(cdd.toc.tracks[cdd.toc.last].fd);
|
cdStreamClose(cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -541,7 +555,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
/* close any opened file */
|
/* close any opened file */
|
||||||
if (cdd.toc.tracks[cdd.toc.last].fd)
|
if (cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
{
|
{
|
||||||
filestream_close(cdd.toc.tracks[cdd.toc.last].fd);
|
cdStreamClose(cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
cdd.toc.tracks[cdd.toc.last].fd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,7 +578,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.sectorSize = 2352;
|
cdd.sectorSize = 2352;
|
||||||
|
|
||||||
/* skip 16-byte header */
|
/* skip 16-byte header */
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdd.sectorSize)
|
if (cdd.sectorSize)
|
||||||
@ -573,8 +587,8 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.toc.tracks[0].type = TYPE_CDROM;
|
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||||
|
|
||||||
/* read CD image header + security code */
|
/* read CD image header + security code */
|
||||||
filestream_read(cdd.toc.tracks[0].fd, header, 0x210);
|
cdStreamRead(header, 0x210, 1, cdd.toc.tracks[0].fd);
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, 0, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -664,18 +678,18 @@ int cdd_load(char *filename, char *header)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* current track end time */
|
/* current track end time */
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_END);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_END);
|
||||||
if (cdd.toc.tracks[cdd.toc.last].type)
|
if (cdd.toc.tracks[cdd.toc.last].type)
|
||||||
{
|
{
|
||||||
/* DATA track length */
|
/* DATA track length */
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((filestream_tell(cdd.toc.tracks[cdd.toc.last].fd) + cdd.sectorSize - 1) / cdd.sectorSize);
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) + cdd.sectorSize - 1) / cdd.sectorSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* AUDIO track length */
|
/* AUDIO track length */
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((filestream_tell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352);
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352);
|
||||||
}
|
}
|
||||||
filestream_seek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust track start time (based on current file start time + index absolute time) */
|
/* adjust track start time (based on current file start time + index absolute time) */
|
||||||
@ -713,11 +727,11 @@ int cdd_load(char *filename, char *header)
|
|||||||
#endif
|
#endif
|
||||||
if (cdd.toc.tracks[cdd.toc.last].fd)
|
if (cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
{
|
{
|
||||||
filestream_close(cdd.toc.tracks[cdd.toc.last].fd);
|
cdStreamClose(cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close CUE file */
|
/* close CUE file */
|
||||||
filestream_close(fd);
|
cdStreamClose(fd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -731,7 +745,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
{
|
{
|
||||||
/* auto-detect wrong initial track index */
|
/* auto-detect wrong initial track index */
|
||||||
sprintf(ptr, extensions[i], cdd.toc.last);
|
sprintf(ptr, extensions[i], cdd.toc.last);
|
||||||
fd = filestream_open(fname, RFILE_MODE_READ, -1);
|
fd = cdStreamOpen(fname);
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -739,7 +753,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(ptr, extensions[i], cdd.toc.last + 1);
|
sprintf(ptr, extensions[i], cdd.toc.last + 1);
|
||||||
fd = filestream_open(fname, RFILE_MODE_READ, -1);
|
fd = cdStreamOpen(fname);
|
||||||
if (fd) break;
|
if (fd) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,31 +762,31 @@ int cdd_load(char *filename, char *header)
|
|||||||
{
|
{
|
||||||
/* read file HEADER */
|
/* read file HEADER */
|
||||||
unsigned char head[28];
|
unsigned char head[28];
|
||||||
filestream_seek(fd, 8, SEEK_SET);
|
cdStreamSeek(fd, 8, SEEK_SET);
|
||||||
filestream_read(fd, head, 28);
|
cdStreamRead(head, 28, 1, fd);
|
||||||
filestream_seek(fd, 0, SEEK_SET);
|
cdStreamSeek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
/* check if this is a valid WAVE file (44.1KHz 16-bit stereo format only) */
|
/* check if this is a valid WAVE file (44.1KHz 16-bit stereo format only) */
|
||||||
if (!memcmp(head, waveHeader, 28))
|
if (!memcmp(head, waveHeader, 28))
|
||||||
{
|
{
|
||||||
/* look for 'data' chunk id */
|
/* look for 'data' chunk id */
|
||||||
int dataOffset = 0;
|
int dataOffset = 0;
|
||||||
filestream_seek(fd, 36, SEEK_SET);
|
cdStreamSeek(fd, 36, SEEK_SET);
|
||||||
while (filestream_read(fd, head, 4))
|
while (cdStreamRead(head, 4, 1, fd))
|
||||||
{
|
{
|
||||||
if (!memcmp(head, "data", 4))
|
if (!memcmp(head, "data", 4))
|
||||||
{
|
{
|
||||||
dataOffset = filestream_tell(fd) + 4;
|
dataOffset = cdStreamTell(fd) + 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
filestream_seek(fd, -2, SEEK_CUR);
|
cdStreamSeek(fd, -2, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if 'data' chunk has not been found */
|
/* check if 'data' chunk has not been found */
|
||||||
if (!dataOffset)
|
if (!dataOffset)
|
||||||
{
|
{
|
||||||
/* invalid WAVE file */
|
/* invalid WAVE file */
|
||||||
filestream_close(fd);
|
cdStreamClose(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,16 +800,16 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.toc.tracks[cdd.toc.last].start += 150;
|
cdd.toc.tracks[cdd.toc.last].start += 150;
|
||||||
|
|
||||||
/* current track end time */
|
/* current track end time */
|
||||||
filestream_seek(fd, 0, SEEK_END);
|
cdStreamSeek(fd, 0, SEEK_END);
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((filestream_tell(fd) - dataOffset + 2351) / 2352);
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((cdStreamTell(fd) - dataOffset + 2351) / 2352);
|
||||||
|
|
||||||
/* initialize file read offset for current track */
|
/* initialize file read offset for current track */
|
||||||
cdd.toc.tracks[cdd.toc.last].offset = cdd.toc.tracks[cdd.toc.last].start * 2352;
|
cdd.toc.tracks[cdd.toc.last].offset = cdd.toc.tracks[cdd.toc.last].start * 2352;
|
||||||
|
|
||||||
/* auto-detect PAUSE within audio files */
|
/* auto-detect PAUSE within audio files */
|
||||||
filestream_seek(fd, 100 * 2352, SEEK_SET);
|
cdStreamSeek(fd, 100 * 2352, SEEK_SET);
|
||||||
filestream_read(fd, head, 4);
|
cdStreamRead(head, 4, 1, fd);
|
||||||
filestream_seek(fd, 0, SEEK_SET);
|
cdStreamSeek(fd, 0, SEEK_SET);
|
||||||
if (*(int32 *)head == 0)
|
if (*(int32 *)head == 0)
|
||||||
{
|
{
|
||||||
/* assume 2s PAUSE is included at the beginning of the file */
|
/* assume 2s PAUSE is included at the beginning of the file */
|
||||||
@ -813,7 +827,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.toc.last++;
|
cdd.toc.last++;
|
||||||
}
|
}
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
else if (!ov_open_callbacks(fd,&cdd.toc.tracks[cdd.toc.last].vf,0,0,fs_ov_callbacks))
|
else if (!ov_open_callbacks(fd,&cdd.toc.tracks[cdd.toc.last].vf,0,0,cb))
|
||||||
{
|
{
|
||||||
/* retrieve stream infos */
|
/* retrieve stream infos */
|
||||||
vorbis_info *info = ov_info(&cdd.toc.tracks[cdd.toc.last].vf,-1);
|
vorbis_info *info = ov_info(&cdd.toc.tracks[cdd.toc.last].vf,-1);
|
||||||
@ -878,7 +892,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* unsupported audio file format */
|
/* unsupported audio file format */
|
||||||
filestream_close(fd);
|
cdStreamClose(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -887,7 +901,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
|
|
||||||
/* try to open next audio track file */
|
/* try to open next audio track file */
|
||||||
sprintf(ptr, extensions[i], cdd.toc.last + offset);
|
sprintf(ptr, extensions[i], cdd.toc.last + offset);
|
||||||
fd = filestream_open(fname, RFILE_MODE_READ, -1);
|
fd = cdStreamOpen(fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1002,7 +1016,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
|
|
||||||
/* Automatically try to open associated subcode data file */
|
/* Automatically try to open associated subcode data file */
|
||||||
strncpy(&fname[strlen(fname) - 4], ".sub", 4);
|
strncpy(&fname[strlen(fname) - 4], ".sub", 4);
|
||||||
cdd.toc.sub = filestream_open(fname, RFILE_MODE_READ, -1);
|
cdd.toc.sub = cdStreamOpen(fname);
|
||||||
|
|
||||||
/* return 1 if loaded file is CD image file */
|
/* return 1 if loaded file is CD image file */
|
||||||
return (isCDfile);
|
return (isCDfile);
|
||||||
@ -1040,13 +1054,13 @@ void cdd_unload(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* close file */
|
/* close file */
|
||||||
filestream_close(cdd.toc.tracks[i].fd);
|
cdStreamClose(cdd.toc.tracks[i].fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close any opened subcode file */
|
/* close any opened subcode file */
|
||||||
if (cdd.toc.sub) filestream_close(cdd.toc.sub);
|
if (cdd.toc.sub) cdStreamClose(cdd.toc.sub);
|
||||||
|
|
||||||
/* CD unloaded */
|
/* CD unloaded */
|
||||||
cdd.loaded = 0;
|
cdd.loaded = 0;
|
||||||
@ -1068,16 +1082,16 @@ void cdd_read_data(uint8 *dst)
|
|||||||
if (cdd.sectorSize == 2048)
|
if (cdd.sectorSize == 2048)
|
||||||
{
|
{
|
||||||
/* Mode 1 COOKED data (ISO) */
|
/* Mode 1 COOKED data (ISO) */
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, cdd.lba * 2048, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2048, SEEK_SET);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Mode 1 RAW data (skip 16-byte header) */
|
/* Mode 1 RAW data (skip 16-byte header) */
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read sector data (Mode 1 = 2048 bytes) */
|
/* read sector data (Mode 1 = 2048 bytes) */
|
||||||
filestream_read(cdd.toc.tracks[0].fd, dst, 2048);
|
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,7 +1179,7 @@ void cdd_read_audio(unsigned int samples)
|
|||||||
#else
|
#else
|
||||||
uint8 *ptr = cdc.ram;
|
uint8 *ptr = cdc.ram;
|
||||||
#endif
|
#endif
|
||||||
filestream_read(cdd.toc.tracks[cdd.index].fd, cdc.ram, samples * 4);
|
cdStreamRead(cdc.ram, 1, samples * 4, cdd.toc.tracks[cdd.index].fd);
|
||||||
|
|
||||||
/* process 16-bit (little-endian) stereo samples */
|
/* process 16-bit (little-endian) stereo samples */
|
||||||
for (i=0; i<samples; i++)
|
for (i=0; i<samples; i++)
|
||||||
@ -1243,7 +1257,7 @@ static void cdd_read_subcode(void)
|
|||||||
index = (scd.regs[0x68>>1].byte.l + 0x100) >> 1;
|
index = (scd.regs[0x68>>1].byte.l + 0x100) >> 1;
|
||||||
|
|
||||||
/* read interleaved subcode data from .sub file (12 x 8-bit of P subchannel first, then Q subchannel, etc) */
|
/* read interleaved subcode data from .sub file (12 x 8-bit of P subchannel first, then Q subchannel, etc) */
|
||||||
filestream_read(cdd.toc.sub, subc, 96);
|
cdStreamRead(subc, 1, 96, cdd.toc.sub);
|
||||||
|
|
||||||
/* convert back to raw subcode format (96 bytes with 8 x P-W subchannel bits per byte) */
|
/* convert back to raw subcode format (96 bytes with 8 x P-W subchannel bits per byte) */
|
||||||
for (i=0; i<96; i+=2)
|
for (i=0; i<96; i+=2)
|
||||||
@ -1277,7 +1291,7 @@ static void cdd_read_subcode(void)
|
|||||||
void cdd_update(void)
|
void cdd_update(void)
|
||||||
{
|
{
|
||||||
#ifdef LOG_CDD
|
#ifdef LOG_CDD
|
||||||
error("LBA = %d (track n°%d)(latency=%d)\n", cdd.lba, cdd.index, cdd.latency);
|
error("LBA = %d (track n°%d)(latency=%d)\n", cdd.lba, cdd.index, cdd.latency);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* seeking disc */
|
/* seeking disc */
|
||||||
@ -1371,7 +1385,7 @@ void cdd_update(void)
|
|||||||
{
|
{
|
||||||
#ifdef DISABLE_MANY_OGG_OPEN_FILES
|
#ifdef DISABLE_MANY_OGG_OPEN_FILES
|
||||||
/* VORBIS file need to be opened first */
|
/* VORBIS file need to be opened first */
|
||||||
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,fs_ov_callbacks);
|
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,cb);
|
||||||
#endif
|
#endif
|
||||||
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.toc.tracks[cdd.index].start * 588) - cdd.toc.tracks[cdd.index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.toc.tracks[cdd.index].start * 588) - cdd.toc.tracks[cdd.index].offset);
|
||||||
}
|
}
|
||||||
@ -1379,7 +1393,7 @@ void cdd_update(void)
|
|||||||
#endif
|
#endif
|
||||||
if (cdd.toc.tracks[cdd.index].fd)
|
if (cdd.toc.tracks[cdd.index].fd)
|
||||||
{
|
{
|
||||||
filestream_seek(cdd.toc.tracks[cdd.index].fd, (cdd.toc.tracks[cdd.index].start * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, (cdd.toc.tracks[cdd.index].start * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1457,14 +1471,14 @@ void cdd_update(void)
|
|||||||
/* seek to current subcode position */
|
/* seek to current subcode position */
|
||||||
if (cdd.toc.sub)
|
if (cdd.toc.sub)
|
||||||
{
|
{
|
||||||
filestream_seek(cdd.toc.sub, cdd.lba * 96, SEEK_SET);
|
cdStreamSeek(cdd.toc.sub, cdd.lba * 96, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current track position */
|
/* seek to current track position */
|
||||||
if (cdd.toc.tracks[cdd.index].type)
|
if (cdd.toc.tracks[cdd.index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, cdd.lba * cdd.sectorSize, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * cdd.sectorSize, SEEK_SET);
|
||||||
}
|
}
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
else if (cdd.toc.tracks[cdd.index].vf.seekable)
|
else if (cdd.toc.tracks[cdd.index].vf.seekable)
|
||||||
@ -1474,7 +1488,7 @@ void cdd_update(void)
|
|||||||
if (!cdd.toc.tracks[cdd.index].vf.datasource)
|
if (!cdd.toc.tracks[cdd.index].vf.datasource)
|
||||||
{
|
{
|
||||||
/* VORBIS file need to be opened first */
|
/* VORBIS file need to be opened first */
|
||||||
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,fs_ov_callbacks);
|
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,cb);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* VORBIS AUDIO track */
|
/* VORBIS AUDIO track */
|
||||||
@ -1484,7 +1498,7 @@ void cdd_update(void)
|
|||||||
else if (cdd.toc.tracks[cdd.index].fd)
|
else if (cdd.toc.tracks[cdd.index].fd)
|
||||||
{
|
{
|
||||||
/* PCM AUDIO track */
|
/* PCM AUDIO track */
|
||||||
filestream_seek(cdd.toc.tracks[cdd.index].fd, (cdd.lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, (cdd.lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1667,7 +1681,7 @@ void cdd_process(void)
|
|||||||
/* open current track VORBIS file */
|
/* open current track VORBIS file */
|
||||||
if (cdd.toc.tracks[index].vf.seekable)
|
if (cdd.toc.tracks[index].vf.seekable)
|
||||||
{
|
{
|
||||||
ov_open_callbacks(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0,fs_ov_callbacks);
|
ov_open_callbacks(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0,cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1685,14 +1699,14 @@ void cdd_process(void)
|
|||||||
/* seek to current subcode position */
|
/* seek to current subcode position */
|
||||||
if (cdd.toc.sub)
|
if (cdd.toc.sub)
|
||||||
{
|
{
|
||||||
filestream_seek(cdd.toc.sub, lba * 96, SEEK_SET);
|
cdStreamSeek(cdd.toc.sub, lba * 96, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current track position */
|
/* seek to current track position */
|
||||||
if (cdd.toc.tracks[index].type)
|
if (cdd.toc.tracks[index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||||
}
|
}
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
else if (cdd.toc.tracks[index].vf.seekable)
|
else if (cdd.toc.tracks[index].vf.seekable)
|
||||||
@ -1704,7 +1718,7 @@ void cdd_process(void)
|
|||||||
else if (cdd.toc.tracks[index].fd)
|
else if (cdd.toc.tracks[index].fd)
|
||||||
{
|
{
|
||||||
/* PCM AUDIO track */
|
/* PCM AUDIO track */
|
||||||
filestream_seek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no audio track playing (yet) */
|
/* no audio track playing (yet) */
|
||||||
@ -1765,7 +1779,7 @@ void cdd_process(void)
|
|||||||
/* open current track VORBIS file */
|
/* open current track VORBIS file */
|
||||||
if (cdd.toc.tracks[index].vf.seekable)
|
if (cdd.toc.tracks[index].vf.seekable)
|
||||||
{
|
{
|
||||||
ov_open_callbacks(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0,fs_ov_callbacks);
|
ov_open_callbacks(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0,cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1784,7 +1798,7 @@ void cdd_process(void)
|
|||||||
if (cdd.toc.tracks[index].type)
|
if (cdd.toc.tracks[index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
filestream_seek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||||
}
|
}
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
else if (cdd.toc.tracks[index].vf.seekable)
|
else if (cdd.toc.tracks[index].vf.seekable)
|
||||||
@ -1796,13 +1810,13 @@ void cdd_process(void)
|
|||||||
else if (cdd.toc.tracks[index].fd)
|
else if (cdd.toc.tracks[index].fd)
|
||||||
{
|
{
|
||||||
/* PCM AUDIO track */
|
/* PCM AUDIO track */
|
||||||
filestream_seek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
|
cdStreamSeek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current subcode position */
|
/* seek to current subcode position */
|
||||||
if (cdd.toc.sub)
|
if (cdd.toc.sub)
|
||||||
{
|
{
|
||||||
filestream_seek(cdd.toc.sub, lba * 96, SEEK_SET);
|
cdStreamSeek(cdd.toc.sub, lba * 96, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no audio track playing */
|
/* no audio track playing */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* CD drive processor & CD-DA fader
|
* CD drive processor & CD-DA fader
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2012-2017 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -66,7 +66,7 @@ typedef struct RFILE RFILE;
|
|||||||
/* CD track */
|
/* CD track */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
RFILE *fd;
|
cdStream *fd;
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
#endif
|
#endif
|
||||||
@ -82,7 +82,7 @@ typedef struct
|
|||||||
int end;
|
int end;
|
||||||
int last;
|
int last;
|
||||||
track_t tracks[CD_MAX_TRACKS];
|
track_t tracks[CD_MAX_TRACKS];
|
||||||
RFILE *sub;
|
cdStream *sub;
|
||||||
} toc_t;
|
} toc_t;
|
||||||
|
|
||||||
/* CDD hardware */
|
/* CDD hardware */
|
||||||
|
@ -529,16 +529,6 @@
|
|||||||
#define m68k_read_pcrelative_16(address) m68k_read_immediate_16(address)
|
#define m68k_read_pcrelative_16(address) m68k_read_immediate_16(address)
|
||||||
#define m68k_read_pcrelative_32(address) m68k_read_immediate_32(address)
|
#define m68k_read_pcrelative_32(address) m68k_read_immediate_32(address)
|
||||||
|
|
||||||
/* Read from the current address space */
|
|
||||||
#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space())
|
|
||||||
#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space())
|
|
||||||
#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space())
|
|
||||||
|
|
||||||
/* Write to the current data space */
|
|
||||||
#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
|
|
||||||
#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
|
|
||||||
#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
|
|
||||||
|
|
||||||
/* map read immediate 8 to read immediate 16 */
|
/* map read immediate 8 to read immediate 16 */
|
||||||
#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16())
|
#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16())
|
||||||
|
|
||||||
@ -547,17 +537,6 @@
|
|||||||
#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A)
|
#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A)
|
||||||
#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A)
|
#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A)
|
||||||
|
|
||||||
/* Read from the program space */
|
|
||||||
#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
|
|
||||||
#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
|
|
||||||
#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
|
|
||||||
|
|
||||||
/* Read from the data space */
|
|
||||||
#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
|
|
||||||
#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
|
|
||||||
#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
/* =============================== PROTOTYPES ============================= */
|
/* =============================== PROTOTYPES ============================= */
|
||||||
@ -684,15 +663,15 @@ static const uint16 m68ki_exception_cycle_table[256] =
|
|||||||
INLINE uint32_t m68ki_read_imm_16(void);
|
INLINE uint32_t m68ki_read_imm_16(void);
|
||||||
INLINE uint32_t m68ki_read_imm_32(void);
|
INLINE uint32_t m68ki_read_imm_32(void);
|
||||||
|
|
||||||
/* Read data with specific function code */
|
/* Read from the current address space */
|
||||||
INLINE uint32_t m68ki_read_8_fc (uint32_t address, uint32_t fc);
|
INLINE uint m68ki_read_8(uint address);
|
||||||
INLINE uint32_t m68ki_read_16_fc (uint32_t address, uint32_t fc);
|
INLINE uint m68ki_read_16(uint address);
|
||||||
INLINE uint32_t m68ki_read_32_fc (uint32_t address, uint32_t fc);
|
INLINE uint m68ki_read_32(uint address);
|
||||||
|
|
||||||
/* Write data with specific function code */
|
/* Write to the current data space */
|
||||||
INLINE void m68ki_write_8_fc (uint32_t address, uint32_t fc, uint32_t value);
|
INLINE void m68ki_write_8(uint address, uint value);
|
||||||
INLINE void m68ki_write_16_fc(uint32_t address, uint32_t fc, uint32_t value);
|
INLINE void m68ki_write_16(uint address, uint value);
|
||||||
INLINE void m68ki_write_32_fc(uint32_t address, uint32_t fc, uint32_t value);
|
INLINE void m68ki_write_32(uint address, uint value);
|
||||||
|
|
||||||
/* Indexed and PC-relative ea fetching */
|
/* Indexed and PC-relative ea fetching */
|
||||||
INLINE uint32_t m68ki_get_ea_pcdi(void);
|
INLINE uint32_t m68ki_get_ea_pcdi(void);
|
||||||
@ -864,69 +843,69 @@ INLINE uint32_t m68ki_read_imm_32(void)
|
|||||||
* These functions will also check for address error and set the function
|
* These functions will also check for address error and set the function
|
||||||
* code if they are enabled in m68kconf.h.
|
* code if they are enabled in m68kconf.h.
|
||||||
*/
|
*/
|
||||||
INLINE uint32_t m68ki_read_8_fc(uint32_t address, uint32_t fc)
|
INLINE uint m68ki_read_8(uint address)
|
||||||
{
|
{
|
||||||
cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];;
|
cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];;
|
||||||
|
|
||||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
|
if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
|
||||||
else return READ_BYTE(temp->base, (address) & 0xffff);
|
else return READ_BYTE(temp->base, (address) & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE uint32_t m68ki_read_16_fc(uint32_t address, uint32_t fc)
|
INLINE uint m68ki_read_16(uint address)
|
||||||
{
|
{
|
||||||
cpu_memory_map *temp;
|
cpu_memory_map *temp;
|
||||||
|
|
||||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */
|
||||||
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error(address, MODE_READ, FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
||||||
if (temp->read16) return (*temp->read16)(ADDRESS_68K(address));
|
if (temp->read16) return (*temp->read16)(ADDRESS_68K(address));
|
||||||
else return *(uint16 *)(temp->base + ((address) & 0xffff));
|
else return *(uint16 *)(temp->base + ((address) & 0xffff));
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE uint32_t m68ki_read_32_fc(uint32_t address, uint32_t fc)
|
INLINE uint m68ki_read_32(uint address)
|
||||||
{
|
{
|
||||||
cpu_memory_map *temp;
|
cpu_memory_map *temp;
|
||||||
|
|
||||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */
|
||||||
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error(address, MODE_READ, FLAG_S | m68ki_get_address_space()) /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
||||||
if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));
|
if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));
|
||||||
else return m68k_read_immediate_32(address);
|
else return m68k_read_immediate_32(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void m68ki_write_8_fc(uint32_t address, uint32_t fc, uint32_t value)
|
INLINE void m68ki_write_8(uint address, uint value)
|
||||||
{
|
{
|
||||||
cpu_memory_map *temp;
|
cpu_memory_map *temp;
|
||||||
|
|
||||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_DATA) /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
||||||
if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value);
|
if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value);
|
||||||
else WRITE_BYTE(temp->base, (address) & 0xffff, value);
|
else WRITE_BYTE(temp->base, (address) & 0xffff, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void m68ki_write_16_fc(uint32_t address, uint32_t fc, uint32_t value)
|
INLINE void m68ki_write_16(uint address, uint value)
|
||||||
{
|
{
|
||||||
cpu_memory_map *temp;
|
cpu_memory_map *temp;
|
||||||
|
|
||||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_DATA) /* auto-disable (see m68kcpu.h) */
|
||||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error(address, MODE_WRITE, FLAG_S | FUNCTION_CODE_USER_DATA); /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
||||||
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value);
|
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value);
|
||||||
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
|
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void m68ki_write_32_fc(uint32_t address, uint32_t fc, uint32_t value)
|
INLINE void m68ki_write_32(uint address, uint value)
|
||||||
{
|
{
|
||||||
cpu_memory_map *temp;
|
cpu_memory_map *temp;
|
||||||
|
|
||||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_DATA) /* auto-disable (see m68kcpu.h) */
|
||||||
m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */
|
m68ki_check_address_error(address, MODE_WRITE, FLAG_S | FUNCTION_CODE_USER_DATA) /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
|
||||||
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16);
|
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16);
|
||||||
@ -1070,36 +1049,30 @@ INLINE uint32_t OPER_PCIX_32(void) {uint32_t ea = EA_PCIX_32(); return m68ki_r
|
|||||||
/* ---------------------------- Stack Functions --------------------------- */
|
/* ---------------------------- Stack Functions --------------------------- */
|
||||||
|
|
||||||
/* Push/pull data from the stack */
|
/* Push/pull data from the stack */
|
||||||
/* Optimized access assuming stack is always located in ROM/RAM [EkeEke] */
|
INLINE void m68ki_push_16(uint value)
|
||||||
INLINE void m68ki_push_16(uint32_t value)
|
|
||||||
{
|
{
|
||||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
|
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
|
||||||
/*m68ki_write_16(REG_SP, value);*/
|
m68ki_write_16(REG_SP, value);
|
||||||
*(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void m68ki_push_32(uint32_t value)
|
INLINE void m68ki_push_32(uint32_t value)
|
||||||
{
|
{
|
||||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
|
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
|
||||||
/*m68ki_write_32(REG_SP, value);*/
|
m68ki_write_32(REG_SP, value);
|
||||||
*(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value >> 16;
|
|
||||||
*(uint16 *)(m68ki_cpu.memory_map[((REG_SP + 2)>>16)&0xff].base + ((REG_SP + 2) & 0xffff)) = value & 0xffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE uint32_t m68ki_pull_16(void)
|
INLINE uint32_t m68ki_pull_16(void)
|
||||||
{
|
{
|
||||||
uint32_t sp = REG_SP;
|
uint32_t sp = REG_SP;
|
||||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
|
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
|
||||||
return m68k_read_immediate_16(sp);
|
return m68ki_read_16(sp);
|
||||||
/*return m68ki_read_16(sp);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE uint32_t m68ki_pull_32(void)
|
INLINE uint32_t m68ki_pull_32(void)
|
||||||
{
|
{
|
||||||
uint32_t sp = REG_SP;
|
uint32_t sp = REG_SP;
|
||||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
|
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
|
||||||
return m68k_read_immediate_32(sp);
|
return m68ki_read_32(sp);
|
||||||
/*return m68ki_read_32(sp);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1117,7 +1090,8 @@ INLINE void m68ki_jump(uint32_t new_pc)
|
|||||||
|
|
||||||
INLINE void m68ki_jump_vector(uint32_t vector)
|
INLINE void m68ki_jump_vector(uint32_t vector)
|
||||||
{
|
{
|
||||||
REG_PC = m68ki_read_data_32(vector<<2);
|
m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */
|
||||||
|
REG_PC = m68ki_read_32(vector<<2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1385,11 +1359,12 @@ INLINE void m68ki_exception_interrupt(uint32_t int_level)
|
|||||||
m68ki_int_ack(int_level);
|
m68ki_int_ack(int_level);
|
||||||
|
|
||||||
/* Get the new PC */
|
/* Get the new PC */
|
||||||
new_pc = m68ki_read_data_32(vector<<2);
|
m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */
|
||||||
|
new_pc = m68ki_read_32(vector<<2);
|
||||||
|
|
||||||
/* If vector is uninitialized, call the uninitialized interrupt vector */
|
/* If vector is uninitialized, call the uninitialized interrupt vector */
|
||||||
if(new_pc == 0)
|
if(new_pc == 0)
|
||||||
new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2));
|
new_pc = m68ki_read_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2));
|
||||||
|
|
||||||
/* Generate a stack frame */
|
/* Generate a stack frame */
|
||||||
m68ki_stack_frame_3word(REG_PC, sr);
|
m68ki_stack_frame_3word(REG_PC, sr);
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
/* Set to your compiler's static inline keyword to enable it, or
|
/* Set to your compiler's static inline keyword to enable it, or
|
||||||
* set it to blank to disable it.
|
* set it to blank to disable it.
|
||||||
* If you define INLINE in the makefile, it will override this value.
|
* If you define INLINE in makefile or osd.h, it will override this value.
|
||||||
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||||
*/
|
*/
|
||||||
#ifndef INLINE
|
#ifndef INLINE
|
||||||
@ -53,4 +53,18 @@
|
|||||||
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Default CD image file access (read-only) functions */
|
||||||
|
/* If you need to override default stdio.h functions with custom filesystem API,
|
||||||
|
redefine following macros in platform specific include file (osd.h) or Makefile
|
||||||
|
*/
|
||||||
|
#ifndef cdStream
|
||||||
|
#define cdStream FILE
|
||||||
|
#define cdStreamOpen(fname) fopen(fname, "rb")
|
||||||
|
#define cdStreamClose fclose
|
||||||
|
#define cdStreamRead fread
|
||||||
|
#define cdStreamSeek fseek
|
||||||
|
#define cdStreamTell ftell
|
||||||
|
#define cdStreamGets fgets
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _MACROS_H_ */
|
#endif /* _MACROS_H_ */
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "macros.h"
|
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
|
#include "macros.h"
|
||||||
#include "loadrom.h"
|
#include "loadrom.h"
|
||||||
#include "m68k.h"
|
#include "m68k.h"
|
||||||
#include "z80.h"
|
#include "z80.h"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
|
* Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -161,7 +161,7 @@ static const uint8 dma_timing[2][2] =
|
|||||||
{
|
{
|
||||||
/* H32, H40 */
|
/* H32, H40 */
|
||||||
{16 , 18}, /* active display */
|
{16 , 18}, /* active display */
|
||||||
{167, 205} /* blank display */
|
{166, 204} /* blank display */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DMA processing functions (set by VDP register 23 high nibble) */
|
/* DMA processing functions (set by VDP register 23 high nibble) */
|
||||||
@ -560,19 +560,16 @@ void vdp_dma_update(unsigned int cycles)
|
|||||||
|
|
||||||
/* DMA transfer rate (bytes per line)
|
/* DMA transfer rate (bytes per line)
|
||||||
|
|
||||||
According to the manual, here's a table that describes the transfer
|
|
||||||
rates of each of the three DMA types:
|
|
||||||
|
|
||||||
DMA Mode Width Display Transfer Count
|
DMA Mode Width Display Transfer Count
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
68K > VDP 32-cell Active 16
|
68K > VDP 32-cell Active 16
|
||||||
Blanking 167
|
|
||||||
40-cell Active 18
|
|
||||||
Blanking 205
|
|
||||||
VRAM Fill 32-cell Active 15
|
|
||||||
Blanking 166
|
Blanking 166
|
||||||
40-cell Active 17
|
40-cell Active 18
|
||||||
Blanking 204
|
Blanking 204
|
||||||
|
VRAM Fill 32-cell Active 15
|
||||||
|
Blanking 165
|
||||||
|
40-cell Active 17
|
||||||
|
Blanking 203
|
||||||
VRAM Copy 32-cell Active 8
|
VRAM Copy 32-cell Active 8
|
||||||
Blanking 83
|
Blanking 83
|
||||||
40-cell Active 9
|
40-cell Active 9
|
||||||
@ -897,7 +894,10 @@ void vdp_z80_ctrl_w(unsigned int data)
|
|||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
/* DMA Fill will be triggered by next write to DATA port */
|
/* DMA Fill */
|
||||||
|
dma_type = 2;
|
||||||
|
|
||||||
|
/* DMA is pending until next DATA port write */
|
||||||
dmafill = 1;
|
dmafill = 1;
|
||||||
|
|
||||||
/* Set DMA Busy flag */
|
/* Set DMA Busy flag */
|
||||||
@ -2039,7 +2039,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
|
|||||||
|
|
||||||
static void vdp_fifo_update(unsigned int cycles)
|
static void vdp_fifo_update(unsigned int cycles)
|
||||||
{
|
{
|
||||||
int slots, count = 0;
|
int num, slots, count = 0;
|
||||||
|
|
||||||
const int *fifo_timing;
|
const int *fifo_timing;
|
||||||
|
|
||||||
@ -2075,13 +2075,13 @@ static void vdp_fifo_update(unsigned int cycles)
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* number of processed FIFO entries since last access */
|
/* number of processed FIFO entries since last access (byte access needs two slots to process one FIFO word) */
|
||||||
slots = (slots + count - fifo_slots) >> fifo_byte_access;
|
num = (slots + count - fifo_slots) >> fifo_byte_access;
|
||||||
|
|
||||||
if (slots > 0)
|
if (num > 0)
|
||||||
{
|
{
|
||||||
/* process FIFO entries */
|
/* process FIFO entries */
|
||||||
fifo_write_cnt -= slots;
|
fifo_write_cnt -= num;
|
||||||
|
|
||||||
/* Clear FIFO full flag */
|
/* Clear FIFO full flag */
|
||||||
status &= 0xFEFF;
|
status &= 0xFEFF;
|
||||||
@ -2093,14 +2093,19 @@ static void vdp_fifo_update(unsigned int cycles)
|
|||||||
|
|
||||||
/* Set FIFO empty flag */
|
/* Set FIFO empty flag */
|
||||||
status |= 0x200;
|
status |= 0x200;
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Reinitialize FIFO access slot counter */
|
||||||
|
fifo_slots = slots + count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Update FIFO access slot counter */
|
/* Update FIFO access slot counter */
|
||||||
fifo_slots += (slots << fifo_byte_access);
|
fifo_slots += (num << fifo_byte_access);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next FIFO update cycle */
|
/* next FIFO update cycle */
|
||||||
fifo_cycles = mcycles_vdp + fifo_timing[count | fifo_byte_access];
|
fifo_cycles = mcycles_vdp + fifo_timing[fifo_slots - slots + fifo_byte_access];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
|
* Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
|
Loading…
Reference in New Issue
Block a user