--- np2/fdd/sxsicd.c 2005/03/05 06:02:29 1.1 +++ np2/fdd/sxsicd.c 2005/04/05 13:48:09 1.5 @@ -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,18 @@ static const UINT8 cd001[7] = {0x01,'C','D','0','0','1',0x01}; +typedef struct { + UINT type; + UINT32 pos; +} CDTRK; + +typedef struct { + FILEH fh; + UINT type; + CDTRK trk[99]; + OEMCHAR path[MAX_PATH]; +} _CDINFO, *CDINFO; -// ---- 後でまとめる。 // ---- セクタ2048 @@ -47,6 +58,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 +68,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 +120,7 @@ sec2352_err: static REG8 sec2352_read(SXSIDEV sxsi, long pos, UINT8 *buf, UINT size) { + FILEH fh; long fpos; UINT rsize; @@ -116,14 +130,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 +151,256 @@ 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)); + mediatype = 0; + for (i=0; itrk, trk, trks * sizeof(CDTRK)); + } + else { + cdinfo->trk[0].type = 0x14; +// cdinfo->trk[0].pos = 0; + mediatype = SXSIMEDIA_DATA; + } + 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 BRESULT getpos(const OEMCHAR *str, UINT32 *pos) { + + 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(FAILURE); + } + if (pos) { + *pos = (((m * 60) + s) * 75) + f; + } + return(SUCCESS); +} + +static BRESULT opencue(SXSIDEV sxsi, const OEMCHAR *fname) { + + CDTRK trk[99]; + OEMCHAR path[MAX_PATH]; + UINT curtrk; + TEXTFILEH tfh; + OEMCHAR buf[512]; + OEMCHAR *argv[8]; + int argc; + UINT type; + + ZeroMemory(trk, sizeof(trk)); + path[0] = '\0'; + curtrk = -1; + 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 = milstr_solveINT(argv[1]) - 1; + type = 0; + if (!milstr_cmp(argv[2], str_mode1)) { + type = 0x14; + } + else if (!milstr_cmp(argv[2], str_audio)) { + type = 0x10; + } + if ((curtrk < NELEMENTS(trk)) && (type != 0)) { + trk[curtrk].type = type; + } + } + else if ((argc >= 3) && (!milstr_cmp(argv[0], str_index))) { + if (curtrk < NELEMENTS(trk)) { + getpos(argv[2], &trk[curtrk].pos); + } + } + } + textfile_close(tfh); + return(openimg(sxsi, path, trk, NELEMENTS(trk))); +} + +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)); +} + +static void storepos(UINT8 *ptr, UINT32 pos) { + + UINT f; + UINT m; + + pos += 150; + f = pos % 75; + pos = pos / 75; + m = pos % 60; + pos = pos / 60; + ptr[0] = 0; + ptr[1] = (UINT8)pos; + ptr[2] = (UINT8)m; + ptr[3] = (UINT8)f; +} + +UINT sxsicd_gettocinfo(SXSIDEV sxsi, UINT8 *buf) { + + CDINFO cdinfo; + UINT8 *ptr; + UINT trks; + UINT i; + UINT type; + + cdinfo = (CDINFO)sxsi->hdl; + ptr = buf + 2; + trks = 0; + for (i=0; itrk); i++) { + type = cdinfo->trk[i].type; + if (type) { + ptr[0] = (UINT8)(type >> 8); + ptr[1] = (UINT8)(type >> 0); + ptr[2] = (UINT8)(i + 1); + ptr[3] = 0; + storepos(ptr + 4, cdinfo->trk[i].pos); + ptr += 8; + trks++; + } + } + buf[0] = 1; + buf[1] = (UINT8)trks; + ptr[0] = 0x00; + ptr[1] = 0x10; + ptr[2] = 0xaa; + ptr[3] = 0; + storepos(ptr + 4, sxsi->totals); + return(trks * 8 + 10); +} +