|
|
| version 1.5, 2003/11/07 18:31:24 | version 1.21, 2005/04/05 20:37:07 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "strres.h" | |
| #include "dosio.h" | #include "dosio.h" |
| #include "sysmng.h" | #include "sysmng.h" |
| #include "i286.h" | #include "cpucore.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | |
| #include "sxsi.h" | #include "sxsi.h" |
| #if defined(SUPPORT_IDEIO) | |
| #include "ideio.h" | |
| #endif | |
| _SXSIDEV sxsi_dev[SASIHDD_MAX + SCSIHDD_MAX]; | |
| typedef struct { | |
| char vhd[3]; | |
| char ver[4]; | |
| char delimita; | |
| char comment[128]; | |
| BYTE padding[4]; | |
| BYTE mbsize[2]; | |
| BYTE sectorsize[2]; | |
| BYTE sectors; | |
| BYTE surfaces; | |
| BYTE tracks[2]; | |
| BYTE totals[4]; | |
| } V98SCSIHDR; | |
| typedef struct { | |
| BYTE tracks[2]; | |
| } THDHDR; | |
| typedef struct { | |
| BYTE dummy[8]; | |
| BYTE headersize[4]; | |
| BYTE filesize[4]; | |
| BYTE sectorsize[4]; | |
| BYTE sectors[4]; | |
| BYTE surfaces[4]; | |
| BYTE tracks[4]; | |
| } HDIHDR; | |
| static const _SXSIHDD defsasi = {615*33*8, 615, 256, 33, 8, | |
| HDDTYPE_SASI, 256, 0, {0x00}}; | |
| static const _SXSIHDD defscsi = {40*16*32*8, 40*16, 256, 32, 8, | |
| HDDTYPE_SCSI, 220, 0, {0x00}}; | |
| // ---- | |
| static BRESULT nc_reopen(SXSIDEV sxsi) { | |
| (void)sxsi; | |
| return(FAILURE); | |
| } | |
| static REG8 nc_read(SXSIDEV sxsi, long pos, UINT8 *buf, UINT size) { | |
| (void)sxsi; | |
| (void)pos; | |
| (void)buf; | |
| (void)size; | |
| return(0x60); | |
| } | |
| _SXSIHDD sxsi_hd[4]; | static REG8 nc_write(SXSIDEV sxsi, long pos, const UINT8 *buf, UINT size) { |
| (void)sxsi; | |
| (void)pos; | |
| (void)buf; | |
| (void)size; | |
| return(0x60); | |
| } | |
| static REG8 nc_format(SXSIDEV sxsi, long pos) { | |
| (void)sxsi; | |
| (void)pos; | |
| return(0x60); | |
| } | |
| static void nc_close(SXSIDEV sxsi) { | |
| (void)sxsi; | |
| } | |
| static void nc_destroy(SXSIDEV sxsi) { | |
| (void)sxsi; | |
| } | |
| static void sxsi_disconnect(SXSIDEV sxsi) { | |
| if (sxsi) { | |
| if (sxsi->flag & SXSIFLAG_FILEOPENED) { | |
| #if defined(SUPPORT_IDEIO) | |
| ideio_notify(sxsi->drv, 0); | |
| #endif | |
| (*sxsi->close)(sxsi); | |
| } | |
| if (sxsi->flag & SXSIFLAG_READY) { | |
| (*sxsi->destroy)(sxsi); | |
| } | |
| sxsi->flag = 0; | |
| sxsi->reopen = nc_reopen; | |
| sxsi->read = nc_read; | |
| sxsi->write = nc_write; | |
| sxsi->format = nc_format; | |
| sxsi->close = nc_close; | |
| sxsi->destroy = nc_destroy; | |
| } | |
| } | |
| // ---- | // ---- |
| Line 49 void sxsi_initialize(void) { | Line 86 void sxsi_initialize(void) { |
| UINT i; | UINT i; |
| ZeroMemory(sxsi_hd, sizeof(sxsi_hd)); | ZeroMemory(sxsi_dev, sizeof(sxsi_dev)); |
| for (i=0; i<(sizeof(sxsi_hd)/sizeof(_SXSIHDD)); i++) { | for (i=0; i<SASIHDD_MAX; i++) { |
| sxsi_hd[i].fh = (long)FILEH_INVALID; | sxsi_dev[i].drv = (UINT8)(SXSIDRV_SASI + i); |
| } | |
| #if defined(SUPPORT_SCSI) | |
| for (i=0; i<SCSIHDD_MAX; i++) { | |
| sxsi_dev[SASIHDD_MAX + i].drv = (UINT8)(SXSIDRV_SCSI + i); | |
| } | |
| #endif | |
| for (i=0; i<NELEMENTS(sxsi_dev); i++) { | |
| sxsi_disconnect(sxsi_dev + i); | |
| } | } |
| } | } |
| SXSIHDD sxsi_getptr(BYTE drv) { | void sxsi_allflash(void) { |
| SXSIDEV sxsi; | |
| SXSIDEV sxsiterm; | |
| sxsi = sxsi_dev; | |
| sxsiterm = sxsi + NELEMENTS(sxsi_dev); | |
| while(sxsi < sxsiterm) { | |
| if (sxsi->flag & SXSIFLAG_FILEOPENED) { | |
| sxsi->flag &= ~SXSIFLAG_FILEOPENED; | |
| (*sxsi->close)(sxsi); | |
| } | |
| sxsi++; | |
| } | |
| } | |
| void sxsi_alltrash(void) { | |
| SXSIDEV sxsi; | |
| SXSIDEV sxsiterm; | |
| sxsi = sxsi_dev; | |
| sxsiterm = sxsi + NELEMENTS(sxsi_dev); | |
| while(sxsi < sxsiterm) { | |
| sxsi_disconnect(sxsi); | |
| sxsi++; | |
| } | |
| } | |
| BOOL sxsi_isconnect(SXSIDEV sxsi) { | |
| if (sxsi) { | |
| switch(sxsi->devtype) { | |
| case SXSIDEV_HDD: | |
| if (sxsi->flag & SXSIFLAG_READY) { | |
| return(TRUE); | |
| } | |
| break; | |
| case SXSIDEV_CDROM: | |
| return(TRUE); | |
| } | |
| } | |
| return(FALSE); | |
| } | |
| BRESULT sxsi_prepare(SXSIDEV sxsi) { | |
| if ((sxsi == NULL) || (!(sxsi->flag & SXSIFLAG_READY))) { | |
| return(FAILURE); | |
| } | |
| if (!(sxsi->flag & SXSIFLAG_FILEOPENED)) { | |
| if ((*sxsi->reopen)(sxsi) == SUCCESS) { | |
| sxsi->flag |= SXSIFLAG_FILEOPENED; | |
| } | |
| else { | |
| return(FAILURE); | |
| } | |
| } | |
| sysmng_hddaccess(sxsi->drv); | |
| return(SUCCESS); | |
| } | |
| // ---- | |
| SXSIDEV sxsi_getptr(REG8 drv) { | |
| UINT num; | UINT num; |
| num = drv & 0x0f; | num = drv & 0x0f; |
| if (num >= 2) { | if (!(drv & 0x20)) { // SASI or IDE |
| return(NULL); | if (num < SASIHDD_MAX) { |
| return(sxsi_dev + num); | |
| } | |
| } | } |
| num += (drv & 0x20) >> 4; | #if defined(SUPPORT_SCSI) |
| return(sxsi_hd + num); | else { |
| if (num < SCSIHDD_MAX) { // SCSI | |
| return(sxsi_dev + SASIHDD_MAX + num); | |
| } | |
| } | |
| #endif | |
| return(NULL); | |
| } | } |
| const char *sxsi_getname(BYTE drv) { | OEMCHAR *sxsi_getfilename(REG8 drv) { |
| SXSIHDD sxsi; | SXSIDEV sxsi; |
| sxsi = sxsi_getptr(drv); | sxsi = sxsi_getptr(drv); |
| if (sxsi) { | if ((sxsi) && (sxsi->flag & SXSIFLAG_READY)) { |
| return(sxsi->fname); | return(sxsi->fname); |
| } | } |
| return(NULL); | return(NULL); |
| } | } |
| BOOL sxsi_hddopen(BYTE drv, const char *file) { | BRESULT sxsi_setdevtype(REG8 drv, UINT8 dev) { |
| SXSIDEV sxsi; | |
| sxsi = sxsi_getptr(drv); | |
| if (sxsi) { | |
| if (sxsi->devtype != dev) { | |
| sxsi_disconnect(sxsi); | |
| sxsi->devtype = dev; | |
| } | |
| return(SUCCESS); | |
| } | |
| else { | |
| return(FAILURE); | |
| } | |
| } | |
| UINT8 sxsi_getdevtype(REG8 drv) { | |
| SXSIDEV sxsi; | |
| sxsi = sxsi_getptr(drv); | |
| if (sxsi) { | |
| return(sxsi->devtype); | |
| } | |
| else { | |
| return(SXSIDEV_NC); | |
| } | |
| } | |
| BRESULT sxsi_devopen(REG8 drv, const OEMCHAR *fname) { | |
| SXSIHDD sxsi; | SXSIDEV sxsi; |
| const char *ext; | BRESULT r; |
| FILEH fh; | |
| THDHDR thd; | |
| HDIHDR hdi; | |
| V98SCSIHDR v98; | |
| if ((file == NULL) || (file[0] == '\0')) { | if ((fname == NULL) || (fname[0] == '\0')) { |
| goto sxsiope_err; | goto sxsiope_err; |
| } | } |
| sxsi = sxsi_getptr(drv); | sxsi = sxsi_getptr(drv); |
| if (sxsi == NULL) { | if (sxsi == NULL) { |
| goto sxsiope_err; | goto sxsiope_err; |
| } | } |
| ext = file_getext((char *)file); | switch(sxsi->devtype) { |
| if ((!file_cmpname(ext, "thd")) && (!(drv & 0x20))) { | case SXSIDEV_HDD: |
| fh = file_open(file); // T98 HDD (SASI) | r = sxsihdd_open(sxsi, fname); |
| if (fh == FILEH_INVALID) { | break; |
| goto sxsiope_err; | |
| } | case SXSIDEV_CDROM: |
| if (file_read(fh, &thd, sizeof(thd)) == sizeof(thd)) { | r = sxsicd_open(sxsi, fname); |
| *sxsi = defsasi; | break; |
| sxsi->tracks = LOADINTELWORD(thd.tracks); | |
| sxsi->totals = sxsi->tracks * sxsi->sectors * sxsi->surfaces; | default: |
| file_cpyname(sxsi->fname, file, sizeof(sxsi->fname)); | r = FAILURE; |
| sxsi->fh = (long)fh; | break; |
| return(SUCCESS); | } |
| } | if (r != SUCCESS) { |
| file_close(fh); | goto sxsiope_err; |
| } | |
| else if ((!file_cmpname(ext, "hdi")) && (!(drv & 0x20))) { | |
| fh = file_open(file); // ANEX86 HDD (SASI) thanx Mamiya | |
| if (fh == FILEH_INVALID) { | |
| goto sxsiope_err; | |
| } | |
| if (file_read(fh, &hdi, sizeof(hdi)) == sizeof(hdi)) { | |
| *sxsi = defsasi; | |
| sxsi->size = LOADINTELWORD(hdi.sectorsize); | |
| sxsi->headersize = LOADINTELDWORD(hdi.headersize); | |
| sxsi->tracks = LOADINTELWORD(hdi.tracks); | |
| sxsi->surfaces = hdi.surfaces[0]; | |
| sxsi->sectors = hdi.sectors[0]; | |
| sxsi->totals = sxsi->tracks * sxsi->sectors * sxsi->surfaces; | |
| file_cpyname(sxsi->fname, file, sizeof(sxsi->fname)); | |
| sxsi->fh = (long)fh; | |
| return(SUCCESS); | |
| } | |
| file_close(fh); | |
| } | |
| else if ((!file_cmpname(ext, "hdd")) && (drv & 0x20)) { | |
| fh = file_open(file); // Virtual98 HDD (SCSI) | |
| if (fh == FILEH_INVALID) { | |
| goto sxsiope_err; | |
| } | |
| if ((file_read(fh, &v98, sizeof(v98)) == sizeof(v98)) && | |
| (!memcmp(v98.vhd, "VHD", 3))) { | |
| sxsi = &sxsi_hd[drv+2]; | |
| *sxsi = defscsi; | |
| sxsi->totals = (SINT32)LOADINTELDWORD(v98.totals); | |
| sxsi->tracks = LOADINTELWORD(v98.tracks); | |
| sxsi->size = LOADINTELWORD(v98.sectorsize); | |
| sxsi->sectors = v98.sectors; | |
| sxsi->surfaces = v98.surfaces; | |
| file_cpyname(sxsi->fname, file, sizeof(sxsi->fname)); | |
| sxsi->fh = (long)fh; | |
| return(SUCCESS); | |
| } | |
| file_close(fh); | |
| } | } |
| file_cpyname(sxsi->fname, fname, NELEMENTS(sxsi->fname)); | |
| sxsi->flag = SXSIFLAG_READY | SXSIFLAG_FILEOPENED; | |
| #if defined(SUPPORT_IDEIO) | |
| ideio_notify(sxsi->drv, 1); | |
| #endif | |
| return(SUCCESS); | |
| sxsiope_err: | sxsiope_err: |
| return(FAILURE); | return(FAILURE); |
| } | } |
| void sxsi_open(void) { | void sxsi_devclose(REG8 drv) { |
| int i; | SXSIDEV sxsi; |
| BYTE sasi; | |
| sxsi_trash(); | sxsi = sxsi_getptr(drv); |
| sasi = 0; | sxsi_disconnect(sxsi); |
| for (i=0; i<2; i++) { | |
| if (sxsi_hddopen(sasi, np2cfg.hddfile[i]) == SUCCESS) { | |
| sasi++; | |
| } | |
| } | |
| } | } |
| void sxsi_flash(void) { | BOOL sxsi_issasi(void) { |
| SXSIHDD sxsi; | |
| SXSIHDD sxsiterm; | |
| sxsi = sxsi_hd; | REG8 drv; |
| sxsiterm = sxsi + (sizeof(sxsi_hd)/sizeof(_SXSIHDD)); | SXSIDEV sxsi; |
| while(sxsi < sxsiterm) { | BOOL ret; |
| if ((FILEH)sxsi->fh != FILEH_INVALID) { | |
| file_close((FILEH)sxsi->fh); | ret = FALSE; |
| sxsi->fh = (long)FILEH_INVALID; | for (drv=0x00; drv<0x04; drv++) { |
| sxsi = sxsi_getptr(drv); | |
| if (sxsi) { | |
| if ((drv < 0x02) && (sxsi->devtype == SXSIDEV_HDD)) { | |
| if (sxsi->flag & SXSIFLAG_READY) { | |
| if (sxsi->mediatype & SXSIMEDIA_INVSASI) { | |
| return(FALSE); | |
| } | |
| ret = TRUE; | |
| } | |
| } | |
| else { | |
| return(FALSE); | |
| } | |
| } | } |
| sxsi++; | |
| } | } |
| return(ret); | |
| } | } |
| void sxsi_trash(void) { | BOOL sxsi_isscsi(void) { |
| SXSIHDD sxsi; | REG8 drv; |
| SXSIHDD sxsiterm; | SXSIDEV sxsi; |
| sxsi = sxsi_hd; | for (drv=0x20; drv<0x28; drv++) { |
| sxsiterm = sxsi + (sizeof(sxsi_hd)/sizeof(_SXSIHDD)); | sxsi = sxsi_getptr(drv); |
| while(sxsi < sxsiterm) { | if (sxsi_isconnect(sxsi)) { |
| if ((FILEH)sxsi->fh != FILEH_INVALID) { | return(TRUE); |
| file_close((FILEH)sxsi->fh); | |
| sxsi->fh = (long)FILEH_INVALID; | |
| } | } |
| sxsi->fname[0] = '\0'; | |
| sxsi++; | |
| } | } |
| return(FALSE); | |
| } | } |
| static SXSIHDD getdrive(BYTE drv) { | BOOL sxsi_iside(void) { |
| UINT num; | REG8 drv; |
| SXSIHDD ret; | SXSIDEV sxsi; |
| num = drv & 0x0f; | for (drv=0x00; drv<0x04; drv++) { |
| if (num >= 2) { | sxsi = sxsi_getptr(drv); |
| return(NULL); | if (sxsi_isconnect(sxsi)) { |
| } | return(TRUE); |
| num += (drv & 0x20) >> 4; | |
| ret = sxsi_hd + num; | |
| if (ret->fname[0] == '\0') { | |
| return(NULL); | |
| } | |
| if ((FILEH)ret->fh == FILEH_INVALID) { | |
| ret->fh = (long)file_open(ret->fname); | |
| if ((FILEH)ret->fh == FILEH_INVALID) { | |
| ret->fname[0] = '\0'; | |
| return(NULL); | |
| } | } |
| } | } |
| sysmng_hddaccess(drv); | return(FALSE); |
| return(ret); | |
| } | } |
| BYTE sxsi_read(BYTE drv, long pos, BYTE *buf, UINT16 size) { | |
| const _SXSIHDD *sxsi; | |
| long r; | |
| UINT16 rsize; | |
| sxsi = getdrive(drv); | REG8 sxsi_read(REG8 drv, long pos, UINT8 *buf, UINT size) { |
| if (sxsi == NULL) { | |
| return(0x60); | SXSIDEV sxsi; |
| } | |
| pos = pos * sxsi->size + sxsi->headersize; | sxsi = sxsi_getptr(drv); |
| r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET); | if (sxsi != NULL) { |
| if (r == -1) { | return(sxsi->read(sxsi, pos, buf, size)); |
| return(0x40); | |
| } | |
| if (pos != r) { | |
| return(0xd0); | |
| } | } |
| while(size) { | else { |
| rsize = min(size, sxsi->size); | return(0x60); |
| I286_REMCLOCK -= rsize; | |
| if (file_read((FILEH)sxsi->fh, buf, rsize) != rsize) { | |
| return(0xd0); | |
| } | |
| buf += rsize; | |
| size -= rsize; | |
| } | } |
| return(0x00); | |
| } | } |
| BYTE sxsi_write(BYTE drv, long pos, const BYTE *buf, UINT16 size) { | REG8 sxsi_write(REG8 drv, long pos, const UINT8 *buf, UINT size) { |
| const _SXSIHDD *sxsi; | SXSIDEV sxsi; |
| long r; | |
| UINT16 wsize; | |
| sxsi = getdrive(drv); | sxsi = sxsi_getptr(drv); |
| if (sxsi == NULL) { | if (sxsi != NULL) { |
| return(0x60); | return(sxsi->write(sxsi, pos, buf, size)); |
| } | |
| pos = pos * sxsi->size + sxsi->headersize; | |
| r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET); | |
| if (r == -1) { | |
| return(0x40); | |
| } | |
| if (pos != r) { | |
| return(0xd0); | |
| } | } |
| while(size) { | else { |
| wsize = min(size, sxsi->size); | return(0x60); |
| I286_REMCLOCK -= wsize; | |
| if (file_write((FILEH)sxsi->fh, buf, wsize) != wsize) { | |
| return(0x70); | |
| } | |
| buf += wsize; | |
| size -= wsize; | |
| } | } |
| return(0x00); | |
| } | } |
| BYTE sxsi_format(BYTE drv, long pos) { | REG8 sxsi_format(REG8 drv, long pos) { |
| const _SXSIHDD *sxsi; | SXSIDEV sxsi; |
| long r; | |
| UINT16 i; | |
| BYTE work[256]; | |
| UINT size; | |
| UINT wsize; | |
| sxsi = getdrive(drv); | sxsi = sxsi_getptr(drv); |
| if (sxsi == NULL) { | if (sxsi != NULL) { |
| return(0x60); | return(sxsi->format(sxsi, pos)); |
| } | } |
| pos = pos * sxsi->size + sxsi->headersize; | else { |
| r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET); | return(0x60); |
| if (r == -1) { | |
| return(0x40); | |
| } | |
| if (pos != r) { | |
| return(0xd0); | |
| } | |
| FillMemory(work, sizeof(work), 0xe5); | |
| for (i=0; i<sxsi->sectors; i++) { | |
| size = sxsi->size; | |
| while(size) { | |
| wsize = min(size, sizeof(work)); | |
| size -= wsize; | |
| I286_REMCLOCK -= wsize; | |
| if (file_write((FILEH)sxsi->fh, work, wsize) != wsize) { | |
| return(0x70); | |
| } | |
| } | |
| } | } |
| return(0x00); | |
| } | } |