--- np2/fdd/sxsicd.c 2005/03/05 06:02:29 1.1 +++ np2/fdd/sxsicd.c 2011/01/15 18:04:43 1.8 @@ -1,5 +1,6 @@ #include "compiler.h" #include "strres.h" +#include "textfile.h" #include "dosio.h" #include "sysmng.h" #include "cpucore.h" @@ -9,8 +10,14 @@ static const UINT8 cd001[7] = {0x01,'C','D','0','0','1',0x01}; +typedef struct { + FILEH fh; + UINT type; + UINT trks; + _CDTRK trk[100]; + OEMCHAR path[MAX_PATH]; +} _CDINFO, *CDINFO; -// ---- 後でまとめる。 // ---- セクタ2048 @@ -47,6 +54,7 @@ sec2048_err: static REG8 sec2048_read(SXSIDEV sxsi, long pos, UINT8 *buf, UINT size) { + FILEH fh; UINT rsize; if (sxsi_prepare(sxsi) != SUCCESS) { @@ -56,13 +64,14 @@ static REG8 sec2048_read(SXSIDEV sxsi, l return(0x40); } pos = pos * 2048; - if (file_seek((FILEH)sxsi->fh, pos, FSEEK_SET) != pos) { + fh = ((CDINFO)sxsi->hdl)->fh; + if (file_seek(fh, pos, FSEEK_SET) != pos) { return(0xd0); } while(size) { rsize = min(size, 2048); CPU_REMCLOCK -= rsize; - if (file_read((FILEH)sxsi->fh, buf, rsize) != rsize) { + if (file_read(fh, buf, rsize) != rsize) { return(0xd0); } buf += rsize; @@ -107,6 +116,7 @@ sec2352_err: static REG8 sec2352_read(SXSIDEV sxsi, long pos, UINT8 *buf, UINT size) { + FILEH fh; long fpos; UINT rsize; @@ -116,14 +126,15 @@ static REG8 sec2352_read(SXSIDEV sxsi, l if ((pos < 0) || (pos >= sxsi->totals)) { return(0x40); } + fh = ((CDINFO)sxsi->hdl)->fh; while(size) { fpos = (pos * 2352) + 16; - if (file_seek((FILEH)sxsi->fh, fpos, FSEEK_SET) != fpos) { + if (file_seek(fh, fpos, FSEEK_SET) != fpos) { return(0xd0); } rsize = min(size, 2048); CPU_REMCLOCK -= rsize; - if (file_read((FILEH)sxsi->fh, buf, rsize) != rsize) { + if (file_read(fh, buf, rsize) != rsize) { return(0xd0); } buf += rsize; @@ -136,62 +147,247 @@ static REG8 sec2352_read(SXSIDEV sxsi, l // ---- -static REG8 cd_write(SXSIDEV sxsi, long pos, const UINT8 *buf, UINT size) { +static BRESULT cd_reopen(SXSIDEV sxsi) { - return(0x60); + CDINFO cdinfo; + FILEH fh; + + cdinfo = (CDINFO)sxsi->hdl; + fh = file_open_rb(cdinfo->path); + if (fh != FILEH_INVALID) { + cdinfo->fh = fh; + return(SUCCESS); + } + else { + return(FAILURE); + } } -static REG8 cd_format(SXSIDEV sxsi, long pos) { +static void cd_close(SXSIDEV sxsi) { - return(0x60); + CDINFO cdinfo; + + cdinfo = (CDINFO)sxsi->hdl; + file_close(cdinfo->fh); } +static void cd_destroy(SXSIDEV sxsi) { -// ---- + _MFREE((CDINFO)sxsi->hdl); +} -BRESULT sxsicd_open(SXSIDEV sxsi, const OEMCHAR *file) { - FILEH fh; - long totals; +// ---- + +static const OEMCHAR str_cue[] = OEMTEXT("cue"); +static const OEMCHAR str_file[] = OEMTEXT("FILE"); +static const OEMCHAR str_track[] = OEMTEXT("TRACK"); +static const OEMCHAR str_mode1[] = OEMTEXT("MODE1/2352"); +static const OEMCHAR str_index[] = OEMTEXT("INDEX"); +static const OEMCHAR str_audio[] = OEMTEXT("AUDIO"); + + +static BRESULT openimg(SXSIDEV sxsi, const OEMCHAR *path, + const _CDTRK *trk, UINT trks) { + + FILEH fh; + UINT type; + long totals; + CDINFO cdinfo; + UINT mediatype; + UINT i; - fh = file_open(file); + fh = file_open_rb(path); if (fh == FILEH_INVALID) { goto sxsiope_err1; } + type = 2048; totals = issec2048(fh); - if (totals >= 0) { - sxsi->fh = (INTPTR)fh; - sxsi->read = sec2048_read; - sxsi->write = cd_write; - sxsi->format = cd_format; + if (totals < 0) { + type = 2352; + totals = issec2352(fh); + } + if (totals < 0) { + goto sxsiope_err2; + } + cdinfo = (CDINFO)_MALLOC(sizeof(_CDINFO), path); + if (cdinfo == NULL) { + goto sxsiope_err2; + } + ZeroMemory(cdinfo, sizeof(_CDINFO)); + cdinfo->fh = fh; + cdinfo->type = type; + if ((trk != NULL) && (trks != 0)) { + trks = min(trks, NELEMENTS(cdinfo->trk) - 1); + CopyMemory(cdinfo->trk, trk, trks * sizeof(_CDTRK)); + } + else { + cdinfo->trk[0].type = 0x14; + cdinfo->trk[0].track = 1; +// cdinfo->trk[0].pos = 0; + trks = 1; + } + mediatype = 0; + for (i=0; itrk[i].type == 0x14) { + mediatype |= SXSIMEDIA_DATA; + } + else if (cdinfo->trk[i].type == 0x10) { + mediatype |= SXSIMEDIA_AUDIO; + } + } + cdinfo->trk[trks].type = 0x10; + cdinfo->trk[trks].track = 0xaa; + cdinfo->trk[trks].pos = totals; + cdinfo->trks = trks; + file_cpyname(cdinfo->path, path, NELEMENTS(cdinfo->path)); - sxsi->totals = totals; - sxsi->cylinders = 0; - sxsi->size = 2048; - sxsi->sectors = 1; - sxsi->surfaces = 1; - sxsi->headersize = 0; - sxsi->mediatype = 0; - } - totals = issec2352(fh); - if (totals >= 0) { - sxsi->fh = (INTPTR)fh; + sxsi->reopen = cd_reopen; + if (type == 2048) { + sxsi->read = sec2048_read; + } + else { sxsi->read = sec2352_read; - sxsi->write = cd_write; - sxsi->format = cd_format; - - sxsi->totals = totals; - sxsi->cylinders = 0; - sxsi->size = 2048; - sxsi->sectors = 1; - sxsi->surfaces = 1; - sxsi->headersize = 0; - sxsi->mediatype = 0; - return(SUCCESS); } + sxsi->close = cd_close; + sxsi->destroy = cd_destroy; + sxsi->hdl = (INTPTR)cdinfo; + sxsi->totals = totals; + sxsi->cylinders = 0; + sxsi->size = 2048; + sxsi->sectors = 1; + sxsi->surfaces = 1; + sxsi->headersize = 0; + sxsi->mediatype = mediatype; + return(SUCCESS); + +sxsiope_err2: file_close(fh); sxsiope_err1: return(FAILURE); } +static BRESULT getint2(const OEMCHAR *str, UINT *val) { + + if ((str[0] < '0') || (str[0] > '9') || + (str[1] < '0') || (str[1] > '9')) { + return(FAILURE); + } + if (val) { + *val = ((str[0] - '0') * 10) + (str[1] - '0'); + } + return(SUCCESS); +} + +static UINT32 getpos(const OEMCHAR *str) { + + UINT m; + UINT s; + UINT f; + + if ((getint2(str + 0, &m) != SUCCESS) || (str[2] != ':') || + (getint2(str + 3, &s) != SUCCESS) || (str[5] != ':') || + (getint2(str + 6, &f) != SUCCESS)) { + return(0); + } + return((((m * 60) + s) * 75) + f); +} + +static BRESULT opencue(SXSIDEV sxsi, const OEMCHAR *fname) { + + _CDTRK trk[99]; + OEMCHAR path[MAX_PATH]; + UINT idx; + UINT8 curtrk; + UINT curtype; + TEXTFILEH tfh; + OEMCHAR buf[512]; + OEMCHAR *argv[8]; + int argc; + + ZeroMemory(trk, sizeof(trk)); + path[0] = '\0'; + idx = 0; + curtrk = 1; + curtype = 0x14; + tfh = textfile_open(fname, 0x800); + if (tfh == NULL) { + return(FAILURE); + } + while(textfile_read(tfh, buf, NELEMENTS(buf)) == SUCCESS) { + argc = milstr_getarg(buf, argv, NELEMENTS(argv)); + if ((argc >= 3) && (!milstr_cmp(argv[0], str_file))) { + file_cpyname(path, fname, NELEMENTS(path)); + file_cutname(path); + file_catname(path, argv[1], NELEMENTS(path)); + } + else if ((argc >= 3) && (!milstr_cmp(argv[0], str_track))) { + curtrk = (UINT8)milstr_solveINT(argv[1]); + if (!milstr_cmp(argv[2], str_mode1)) { + curtype = 0x14; + } + else if (!milstr_cmp(argv[2], str_audio)) { + curtype = 0x10; + } + } + else if ((argc >= 3) && (!milstr_cmp(argv[0], str_index))) { + if (idx < NELEMENTS(trk)) { + trk[idx].type = curtype; + trk[idx].track = curtrk; + trk[idx].pos = getpos(argv[2]); + idx++; + } + } + } + textfile_close(tfh); + return(openimg(sxsi, path, trk, idx)); +} + +BRESULT sxsicd_open(SXSIDEV sxsi, const OEMCHAR *fname) { + +const OEMCHAR *ext; + + ext = file_getext(fname); + if (!file_cmpname(ext, str_cue)) { + return(opencue(sxsi, fname)); + } + return(openimg(sxsi, fname, NULL, 0)); +} + +CDTRK sxsicd_gettrk(SXSIDEV sxsi, UINT *tracks) { + + CDINFO cdinfo; + + cdinfo = (CDINFO)sxsi->hdl; + if (tracks) { + *tracks = cdinfo->trks; + } + return(cdinfo->trk); +} + +BRESULT sxsicd_readraw(SXSIDEV sxsi, long pos, void *buf) { + + CDINFO cdinfo; + FILEH fh; + long fpos; + + cdinfo = (CDINFO)sxsi->hdl; + if (cdinfo->type != 2352) { + return(FAILURE); + } + if (sxsi_prepare(sxsi) != SUCCESS) { + return(FAILURE); + } + if ((pos < 0) || (pos >= sxsi->totals)) { + return(FAILURE); + } + fh = ((CDINFO)sxsi->hdl)->fh; + fpos = pos * 2352; + if ((file_seek(fh, fpos, FSEEK_SET) != fpos) || + (file_read(fh, buf, 2352) != 2352)) { + return(FAILURE); + } + return(SUCCESS); +} +