diff --git a/src/fds.c b/src/fds.c index 2dc76a6..f7358ab 100644 --- a/src/fds.c +++ b/src/fds.c @@ -82,6 +82,30 @@ static int32 DiskPtr; static int32 DiskSeekIRQ; 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; #define DC_INC 1 @@ -148,6 +172,16 @@ static void FDSInit(void) { FDSSoundReset(); InDisk = 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) { @@ -216,6 +250,7 @@ static DECLFR(FDSRead4030) { return ret; } +#ifndef USE_DINK static DECLFR(FDSRead4031) { static uint8 z = 0; if (InDisk != 255) { @@ -232,6 +267,51 @@ static DECLFR(FDSRead4031) { } 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) { uint8 ret; @@ -530,6 +610,7 @@ static DECLFW(FDSWrite) { X6502_IRQEnd(FCEU_IQEXT2); } case 0x4024: +#ifndef USE_DINK if ((InDisk != 255) && !(FDSRegs[5] & 0x4) && (FDSRegs[3] & 0x1)) { if (DiskPtr >= 0 && DiskPtr < 65500) { 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; case 0x4025: +#ifndef USE_DINK X6502_IRQEnd(FCEU_IQEXT2); if (InDisk != 255) { if (!(V & 0x40)) { @@ -559,6 +675,55 @@ static DECLFW(FDSWrite) { if (V & 0x40) DiskSeekIRQ = 200; } 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: /* */ + 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; } FDSRegs[A & 7] = V; @@ -903,15 +1068,24 @@ int FDSLoad(const char *name, FCEUFILE *fp) { AddExState(&FDSRegs[3], 1, 0, "REG4"); AddExState(&FDSRegs[4], 1, 0, "REG5"); AddExState(&FDSRegs[5], 1, 0, "REG6"); - AddExState(&IRQCount, 4, 1, "IRQC"); - AddExState(&IRQLatch, 4, 1, "IQL1"); + AddExState(&IRQCount, 4 | FCEUSTATE_RLSB, 1, "IRQC"); + AddExState(&IRQLatch, 4 | FCEUSTATE_RLSB, 1, "IQL1"); AddExState(&IRQa, 1, 0, "IRQA"); AddExState(&writeskip, 1, 0, "WSKI"); - AddExState(&DiskPtr, 4, 1, "DPTR"); - AddExState(&DiskSeekIRQ, 4, 1, "DSIR"); + AddExState(&DiskPtr, 4 | FCEUSTATE_RLSB, 1, "DPTR"); + AddExState(&DiskSeekIRQ, 4 | FCEUSTATE_RLSB, 1, "DSIR"); AddExState(&SelectDisk, 1, 0, "SELD"); AddExState(&InDisk, 1, 0, "INDI"); 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; CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);