Talk:Family Computer Disk System

From NESdev Wiki
Jump to navigationJump to search


I think there was a mistake in the document, it said that GetDiskInfo was at E23A, and that makes no sense since it overlaps with another function. Another document said it was E32A (not E23A), so I changed it. --Dwedit 21:37, 11 October 2010 (UTC)

Yes, it was a typo. Thank you for correcting it Bregalad 11:14, 12 October 2010 (UTC)


Given a few minutes of analysis, the routine at $eb13 appears to read the Family basic keyboard state into $00-$08. --Quietust 13:31, 13 October 2010 (UTC)

Great finding Q ! What about completing the article about it ? Now only $e8b3 and $e94f are still somewhat obscure. Bregalad 21:03, 13 October 2010 (UTC)

VRAM Buffer

I'm trying to learn how the FDS works (hence my efforts to tidy up descriptions and such), and I'm a little confused. There's a buffer at $3xx which is what the various PrepareVRAMString routines and such copy to/from, but it doesn't support fills and doesn't support 32-byte increment? WriteVRAMBuffer is what you use to actually copy the $3xx buffer into VRAM, correct?

That seems a little less useful than just simply using VRAMStructWrite, pointing to $0302, and gaining access to the extra features like fill and 32-byte increment. --Drag 17:27, 26 February 2012 (PST)

You are correct. The missing future are fill, 32-byte increment, but also sub-structures. The advantage, however, is that the second routine (WriteVRAMBuffer) is way faster than the first (VRAMStructWrite), as it doesn't have to check for those flags (which aren't available any longer), and uses direct addressing $302,X instead of indirect addressing to access the buffer. So the second routine is more suited to do VRAM updates during VBlank, while the first routine is more suited to do bulk updates during forced blanking, although technically both can do both. BTW thanks for fixing/correcting my work.Bregalad 12:33, 27 February 2012 (PST)

VRAM updates during VBlank like writing a column of a horizontally scrolling background? --Tepples 12:38, 27 February 2012 (PST)

Well....... Then you either upload it a tile at a time or call the slow routine (both will be slow) or write your own (fast).Bregalad 13:18, 27 February 2012 (PST)

Thanks! I wanted to see if it would be better to use the one in the BIOS first, before I went straight to just using my own. Thank you for clearing that up for me. :D --Drag 18:01, 27 February 2012 (PST)


Do you have information of Famicom Disk System pinout? --Zzo38 11:43, 28 September 2012 (MDT)

QDI format

I want to mention this here in case someone finds it useful. A .QDI file is a raw disk image for a single side of a single disk (including gaps, checksums, full size, etc). In order for an emulator to support it, I recommend the following:

  • If loading a .NES ROM image with mapper 20, it should treat it as a BIOS ROM and start the FDS with no disk inserted. If a hard or soft reset is requested, and any .QDI is inserted, it should boot that disk side; if none is inserted, it should boot from no disk.
  • If loading a .FDS disk image, it should enable the "insert disk 1 side A" and so on, and treat it as it already does. (Some emulators may make a private copy in the user's home directory for saving (maybe even converting to .QDI upon first loading!); others may overwrite the existing .FDS instead.)
  • If loading a .QDI disk image, it should boot from that one, and have a "insert .QDI" option.
  • If possible, the emulator should use the underlying filesystem's read-only flag (or otherwise determine if it is read-only) to determine how to set the write-protect flag in the FDS registers.

--Zzo38 (talk) 10:31, 4 November 2013 (MST)

Disk Status Register ($4030) behavior

I have built my new dumper. So I'm reverse-engineering FDS now. My dumper can read and write FDS cards already. But I noticed some inconsistencies with this page. In particular, I found out something about the $4030 (Disk Status) register. Bits 2 and 5 are set after any write to $4025 (FDS Control) register. Bit 2 is cleared when disk becomes ready ($4032.1 cleared) or after any transfer ($4024 or $4031 is serviced). Bit 2 is cleared only after any transfer ($4024 or $4031 is serviced). Also bit 7 is set every time $4031 is ready to be read or $4024 is ready to be written, e.g. it's messed up with bit 1 on this page. There is full trace of my work with FDS:

 PRG(FDS_IRQ_CONTROL) = 0x00; // disable timer IRQ
 PRG(FDS_MASTER_IO) = 0x01; // enable disk registers
 // FDS_DISK_STATUS == 0x00 (0b00000000) here
 PRG(FDS_CONTROL) = 0b00001110; // reset
 // FDS_DISK_STATUS == 0x24 (0b00100100) here
 PRG(FDS_CONTROL) = 0b00001101; // monor on, unreset
 // FDS_DISK_STATUS == 0x24 (0b00100100) here
 // waiting until drive is rewinded
 } while (PRG(FDS_DRIVE_STATUS) & 2);
 // FDS_DISK_STATUS == 0x20 (0b00100000) here, bit 2 is cleared!
 PRG(FDS_CONTROL) = 0b00001101; // monor on without transfer
 // FDS_DISK_STATUS == 0x24 (0b00100100) here, bit 2 is set again!
 delay_clock(500000); // delay ~500000 clock cycles before first block
 // FDS_DISK_STATUS == 0x24 (0b00100100) here
 PRG(FDS_CONTROL) = 0b11001101; // enable transfer and interrupt
 // FDS_DISK_STATUS == 0x24 (0b00100100) here
 // waiting for IRQ
 // IRQ fired, first byte of data arrived
 // FDS_DISK_STATUS == 0xA4 (0b10100100) here, bit 7 is set when IRQ fired
 output = PRG(FDS_DATA_READ); // reading $4031, IRQ acknowledge
 // FDS_DISK_STATUS == 0x00 (0b00000000) here, everything is cleared when IRQ was acknowledged
 // waiting for IRQ
 // IRQ fired, second byte of data arrived
 // FDS_DISK_STATUS == 0x80 (0b10000000) here, bit 7 is set when IRQ fired
 output = PRG(FDS_DATA_READ); // reading $4031, IRQ acknowledge
 // FDS_DISK_STATUS == 0x00 (0b00000000) here, bit 7 is cleared
 ...and so on

Waiting for IRQ can be replaced with waiting for bit 7 in FDS_DISK_STATUS. Anyway, seems like there are no games that test these bits. FDS BIOS using interrupts. Cluster (talk) 04:39, 2 December 2020 (MST)

Battery bit in register $4033

Battery bit in register $4033 is messed up too. Actually 1 = good, 0 = voltage is low. fceux source code as proof:

   static DECLFR(FDSRead4033) {
       return 0x80; // battery

Cluster (talk) 05:22, 2 December 2020 (MST)

FDS Control ($4025) register

Actually bit 1 controls motor, not bit 0. Bit 1: 1 = stop motor (and reset?), 0 = start motor. Seems like it messed up because FDS BIOS always sets bit 0 after bit 1 clear. I'm not sure what actually bit 0 does: disk reading works fine when bit 0 is not set. Disk writing works only with small blocks otherwise motor actually stops during writing and data is corrupted. Also if set bit 1 (turn off motor) while bit 0 is also set, motor will be stopped after ~1 second, not instantly. So bit 0 should always be set when bit 1 is cleared and cleared when bit 1 is set. Further investigation required. Bit 5 is always set by FDS BIOS but seems like it doesn't do anything. Both reading and writing works fine when it's not set. Cluster (talk) 09:18, 2 December 2020 (MST) It looks like interrupts are not working correctly when bit 5 is not set. Cluster (talk) 04:20, 6 December 2020 (MST)

FDS cycle time

>>A complete cycle through the entire disc takes about 7 seconds

After some tests with the original licensed disk, I found that 7600 milliseconds is the fastest possible speed to read the disk correctly and 8700 milliseconds is the slowest possible speed. So seems like the optimal value is (7600 + 8700) / 2 ~= 8150 milliseconds. But I'm not sure about it. Cluster (talk) 15:59, 22 April 2021 (MDT)