Merge pull request #316 from negativeExponent/update_fds_disk_handling
(fds.c) backport new fds disk handling
This commit is contained in:
182
src/fds.c
182
src/fds.c
@@ -82,6 +82,30 @@ static int32 DiskPtr;
|
|||||||
static int32 DiskSeekIRQ;
|
static int32 DiskSeekIRQ;
|
||||||
static uint8 SelectDisk, InDisk;
|
static uint8 SelectDisk, InDisk;
|
||||||
|
|
||||||
|
/* dec-12-19 */
|
||||||
|
/* 4024(w), 4025(w), 4031(r) by dink(fbneo) */
|
||||||
|
/* remove this and old code after testing phase */
|
||||||
|
#define USE_DINK
|
||||||
|
|
||||||
|
enum FDS_DiskBlockIDs {
|
||||||
|
DSK_INIT = 0,
|
||||||
|
DSK_VOLUME,
|
||||||
|
DSK_FILECNT,
|
||||||
|
DSK_FILEHDR,
|
||||||
|
DSK_FILEDATA
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8 mapperFDS_control; /* 4025(w) control register */
|
||||||
|
static uint16 mapperFDS_filesize; /* size of file being read/written */
|
||||||
|
static uint8 mapperFDS_block; /* block-id of current block */
|
||||||
|
static uint16 mapperFDS_blockstart; /* start-address of current block */
|
||||||
|
static uint16 mapperFDS_blocklen; /* length of current block */
|
||||||
|
static uint16 mapperFDS_diskaddr; /* current address relative to blockstart */
|
||||||
|
static uint8 mapperFDS_diskaccess; /* disk needs to be accessed at least once before writing */
|
||||||
|
|
||||||
|
#define GET_FDS_DISK() (diskdata[InDisk][mapperFDS_blockstart + mapperFDS_diskaddr])
|
||||||
|
#define FDS_DISK_INSERTED (InDisk != 255)
|
||||||
|
|
||||||
uint32 lastDiskPtrRead, lastDiskPtrWrite;
|
uint32 lastDiskPtrRead, lastDiskPtrWrite;
|
||||||
|
|
||||||
#define DC_INC 1
|
#define DC_INC 1
|
||||||
@@ -148,6 +172,16 @@ static void FDSInit(void) {
|
|||||||
FDSSoundReset();
|
FDSSoundReset();
|
||||||
InDisk = 0;
|
InDisk = 0;
|
||||||
SelectDisk = 0;
|
SelectDisk = 0;
|
||||||
|
|
||||||
|
#ifdef USE_DINK
|
||||||
|
mapperFDS_control = 0;
|
||||||
|
mapperFDS_filesize = 0;
|
||||||
|
mapperFDS_block = 0;
|
||||||
|
mapperFDS_blockstart = 0;
|
||||||
|
mapperFDS_blocklen = 0;
|
||||||
|
mapperFDS_diskaddr = 0;
|
||||||
|
mapperFDS_diskaccess = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_FDSInsert(int oride) {
|
void FCEU_FDSInsert(int oride) {
|
||||||
@@ -216,6 +250,7 @@ static DECLFR(FDSRead4030) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_DINK
|
||||||
static DECLFR(FDSRead4031) {
|
static DECLFR(FDSRead4031) {
|
||||||
static uint8 z = 0;
|
static uint8 z = 0;
|
||||||
if (InDisk != 255) {
|
if (InDisk != 255) {
|
||||||
@@ -232,6 +267,51 @@ static DECLFR(FDSRead4031) {
|
|||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* USE_DISK */
|
||||||
|
|
||||||
|
static DECLFR(FDSRead4031) {
|
||||||
|
uint8 ret = 0xff;
|
||||||
|
|
||||||
|
if (FDS_DISK_INSERTED && mapperFDS_control & 0x04) {
|
||||||
|
mapperFDS_diskaccess = 1;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
switch (mapperFDS_block) {
|
||||||
|
case DSK_FILEHDR:
|
||||||
|
if (mapperFDS_diskaddr < mapperFDS_blocklen) {
|
||||||
|
ret = GET_FDS_DISK();
|
||||||
|
switch (mapperFDS_diskaddr) {
|
||||||
|
case 13:
|
||||||
|
mapperFDS_filesize = ret;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
mapperFDS_filesize |= ret << 8;
|
||||||
|
/* char fdsfile[10]; */
|
||||||
|
/* strncpy(fdsfile, (char*)&diskdata[InDisk][mapperFDS_blockstart + 3], 8); */
|
||||||
|
/* printf("Read file: %s (size: %d)\n"), fdsfile, mapperFDS_filesize); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mapperFDS_diskaddr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mapperFDS_diskaddr < mapperFDS_blocklen) {
|
||||||
|
ret = GET_FDS_DISK();
|
||||||
|
mapperFDS_diskaddr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiskSeekIRQ = 150;
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_DINK */
|
||||||
|
|
||||||
static DECLFR(FDSRead4032) {
|
static DECLFR(FDSRead4032) {
|
||||||
uint8 ret;
|
uint8 ret;
|
||||||
|
|
||||||
@@ -530,6 +610,7 @@ static DECLFW(FDSWrite) {
|
|||||||
X6502_IRQEnd(FCEU_IQEXT2);
|
X6502_IRQEnd(FCEU_IQEXT2);
|
||||||
}
|
}
|
||||||
case 0x4024:
|
case 0x4024:
|
||||||
|
#ifndef USE_DINK
|
||||||
if ((InDisk != 255) && !(FDSRegs[5] & 0x4) && (FDSRegs[3] & 0x1)) {
|
if ((InDisk != 255) && !(FDSRegs[5] & 0x4) && (FDSRegs[3] & 0x1)) {
|
||||||
if (DiskPtr >= 0 && DiskPtr < 65500) {
|
if (DiskPtr >= 0 && DiskPtr < 65500) {
|
||||||
if (writeskip)
|
if (writeskip)
|
||||||
@@ -541,8 +622,43 @@ static DECLFW(FDSWrite) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else /* USE_DINK */
|
||||||
|
if (FDS_DISK_INSERTED && ~mapperFDS_control & 0x04) {
|
||||||
|
|
||||||
|
if (mapperFDS_diskaccess == 0) {
|
||||||
|
mapperFDS_diskaccess = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mapperFDS_block) {
|
||||||
|
case DSK_FILEHDR:
|
||||||
|
if (mapperFDS_diskaddr < mapperFDS_blocklen) {
|
||||||
|
GET_FDS_DISK() = V;
|
||||||
|
switch (mapperFDS_diskaddr) {
|
||||||
|
case 13: mapperFDS_filesize = V; break;
|
||||||
|
case 14:
|
||||||
|
mapperFDS_filesize |= V << 8;
|
||||||
|
/* char fdsfile[10]; */
|
||||||
|
/* strncpy(fdsfile, (char*)&diskdata[InDisk][mapperFDS_blockstart + 3], 8); */
|
||||||
|
/* printf("Write file: %s (size: %d)\n"), fdsfile, mapperFDS_filesize); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mapperFDS_diskaddr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mapperFDS_diskaddr < mapperFDS_blocklen) {
|
||||||
|
GET_FDS_DISK() = V;
|
||||||
|
mapperFDS_diskaddr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* USE_DINK */
|
||||||
break;
|
break;
|
||||||
case 0x4025:
|
case 0x4025:
|
||||||
|
#ifndef USE_DINK
|
||||||
X6502_IRQEnd(FCEU_IQEXT2);
|
X6502_IRQEnd(FCEU_IQEXT2);
|
||||||
if (InDisk != 255) {
|
if (InDisk != 255) {
|
||||||
if (!(V & 0x40)) {
|
if (!(V & 0x40)) {
|
||||||
@@ -559,6 +675,55 @@ static DECLFW(FDSWrite) {
|
|||||||
if (V & 0x40) DiskSeekIRQ = 200;
|
if (V & 0x40) DiskSeekIRQ = 200;
|
||||||
}
|
}
|
||||||
setmirror(((V >> 3) & 1) ^ 1);
|
setmirror(((V >> 3) & 1) ^ 1);
|
||||||
|
#else /* USE_DINK */
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT2);
|
||||||
|
if (FDS_DISK_INSERTED) {
|
||||||
|
if (V & 0x40 && ~mapperFDS_control & 0x40) {
|
||||||
|
mapperFDS_diskaccess = 0;
|
||||||
|
|
||||||
|
DiskSeekIRQ = 150;
|
||||||
|
|
||||||
|
/* blockstart - address of block on disk
|
||||||
|
* diskaddr - address relative to blockstart
|
||||||
|
* _block -> _blockID ?
|
||||||
|
*/
|
||||||
|
mapperFDS_blockstart += mapperFDS_diskaddr;
|
||||||
|
mapperFDS_diskaddr = 0;
|
||||||
|
|
||||||
|
mapperFDS_block++;
|
||||||
|
if (mapperFDS_block > DSK_FILEDATA)
|
||||||
|
mapperFDS_block = DSK_FILEHDR;
|
||||||
|
|
||||||
|
switch (mapperFDS_block) {
|
||||||
|
case DSK_VOLUME:
|
||||||
|
mapperFDS_blocklen = 0x38;
|
||||||
|
break;
|
||||||
|
case DSK_FILECNT:
|
||||||
|
mapperFDS_blocklen = 0x02;
|
||||||
|
break;
|
||||||
|
case DSK_FILEHDR:
|
||||||
|
mapperFDS_blocklen = 0x10;
|
||||||
|
break;
|
||||||
|
case DSK_FILEDATA: /* <blockid><filedata> */
|
||||||
|
mapperFDS_blocklen = 0x01 + mapperFDS_filesize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (V & 0x02) { /* transfer reset */
|
||||||
|
mapperFDS_block = DSK_INIT;
|
||||||
|
mapperFDS_blockstart = 0;
|
||||||
|
mapperFDS_blocklen = 0;
|
||||||
|
mapperFDS_diskaddr = 0;
|
||||||
|
DiskSeekIRQ = 150;
|
||||||
|
}
|
||||||
|
if (V & 0x40) { /* turn on motor */
|
||||||
|
DiskSeekIRQ = 150;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mapperFDS_control = V;
|
||||||
|
setmirror(((V >> 3) & 1) ^ 1);
|
||||||
|
#endif /* USE_DINK */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
FDSRegs[A & 7] = V;
|
FDSRegs[A & 7] = V;
|
||||||
@@ -903,15 +1068,24 @@ int FDSLoad(const char *name, FCEUFILE *fp) {
|
|||||||
AddExState(&FDSRegs[3], 1, 0, "REG4");
|
AddExState(&FDSRegs[3], 1, 0, "REG4");
|
||||||
AddExState(&FDSRegs[4], 1, 0, "REG5");
|
AddExState(&FDSRegs[4], 1, 0, "REG5");
|
||||||
AddExState(&FDSRegs[5], 1, 0, "REG6");
|
AddExState(&FDSRegs[5], 1, 0, "REG6");
|
||||||
AddExState(&IRQCount, 4, 1, "IRQC");
|
AddExState(&IRQCount, 4 | FCEUSTATE_RLSB, 1, "IRQC");
|
||||||
AddExState(&IRQLatch, 4, 1, "IQL1");
|
AddExState(&IRQLatch, 4 | FCEUSTATE_RLSB, 1, "IQL1");
|
||||||
AddExState(&IRQa, 1, 0, "IRQA");
|
AddExState(&IRQa, 1, 0, "IRQA");
|
||||||
AddExState(&writeskip, 1, 0, "WSKI");
|
AddExState(&writeskip, 1, 0, "WSKI");
|
||||||
AddExState(&DiskPtr, 4, 1, "DPTR");
|
AddExState(&DiskPtr, 4 | FCEUSTATE_RLSB, 1, "DPTR");
|
||||||
AddExState(&DiskSeekIRQ, 4, 1, "DSIR");
|
AddExState(&DiskSeekIRQ, 4 | FCEUSTATE_RLSB, 1, "DSIR");
|
||||||
AddExState(&SelectDisk, 1, 0, "SELD");
|
AddExState(&SelectDisk, 1, 0, "SELD");
|
||||||
AddExState(&InDisk, 1, 0, "INDI");
|
AddExState(&InDisk, 1, 0, "INDI");
|
||||||
AddExState(&DiskWritten, 1, 0, "DSKW");
|
AddExState(&DiskWritten, 1, 0, "DSKW");
|
||||||
|
#ifdef USE_DINK
|
||||||
|
AddExState(&mapperFDS_control, 1, 0, "CTRG");
|
||||||
|
AddExState(&mapperFDS_filesize, 2 | FCEUSTATE_RLSB, 1, "FLSZ");
|
||||||
|
AddExState(&mapperFDS_block, 1, 0, "BLCK");
|
||||||
|
AddExState(&mapperFDS_blockstart, 2 | FCEUSTATE_RLSB, 1, "BLKS");
|
||||||
|
AddExState(&mapperFDS_blocklen, 2 | FCEUSTATE_RLSB, 1, "BLKL");
|
||||||
|
AddExState(&mapperFDS_diskaddr, 2 | FCEUSTATE_RLSB, 1, "DADR");
|
||||||
|
AddExState(&mapperFDS_diskaccess, 1, 0, "DACC");
|
||||||
|
#endif
|
||||||
|
|
||||||
CHRRAMSize = 8192;
|
CHRRAMSize = 8192;
|
||||||
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
|
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user