Edit: BTW there is a way to trick the BIOS to skip the Kyodaku screen so you can boot faster, but I haven't tried it and I didn't want to do it in a basic example template.

Once you have a working program and want to try it, make a new [CODE] file on the disk that gets loaded last upon bootup, whose load address is $2000. It should be about 256 bytes long, and have these 8 bytes repeating:

$90 00 00 00 00 00 00 00

The FDS BIOS/Copyright screen will be skipped.

I've been trying to implement this, but I haven't been able to get it to work. I built some tests on top of an example FDS project I made recently:

This adds the extra file, but removes the KYODAKU license file. Now the game fails to boot with a disk error 20, like usual with a disk missing its license screen.

The results are the same in emulators as they are with my FDS + loopy's FDSStick.

Has anyone else implemented this correctly? What am I missing? (What does this hack do, anyway? Is it trying to "hide" the screen by blanking $2001 during the test, or bypass the test entirely?)

Edit: I discovered hawken's pirate pops disk successfully suppresses the screen, and does not appear to have the KYODAKU license file. Its "HIJACK" file contains the repeating string [ $80 $80 $80 $80 $80 $80 $00 $00 ] instead... but after trying that in my own disk it doesn't seem to help, though.

Last edited by rainwarrior on Tue May 09, 2017 12:40 am, edited 2 times in total.

1. The last boot file should write one byte [ $90 ] to the CPU location $2000, and increase the disk's file count by one (without adding another file).

Normally NMI is disabled during disk access because it relies on an IRQ from the disk drive, but since this enables NMI by writing to $2000, eventually it will get interrupted by that. This will result in the NMI jumping to the NMI #3 vector ($DFFA). So, $DFFA is now the entry point into your program, i.e. it is really your RESET vector, and not your NMI #3 vector as the FDS normally expects.

The too-high file count will cause the boot loader to continue scanning to the end of the disk, giving the NMI ample time to fire before the end of boot is reached where the license text would be checked. (This was suggested by Loopy below.)

An alternative technique exists, instead creating a 256-byte file of [ $90, $00, $00, $00, $00, $00, $00, $00 ] repeating (mirrored writes to the PPU registers) without doing anything special to the file count. This works on some systems, but notably may fail on the PowerPak, which has a modified BIOS that may read through such a file too fast for an NMI to trigger.

2. Place your RESET vector at $DFFA, instead of the usual "NMI #3". After entry here, you should either write your real NMI routine vector to $DFFA, or write to $100 to make it use one of the other two NMI vectors instead.

The KYODAKU file is not needed, as the test is not executed. The "false reset" has taken control of the system before the test would happen (after the last boot file was finished loading).

3. To make sure resets go to your game, rather than reboot the BIOS write two bytes at $102/103:

$102 = #$35

$103 = #$AC

This will tell the BIOS' reset routine to jump to your RESET vector ($DFFC), rather than trying to reboot the BIOS and starting from scratch.

4. JMP ($FFFC). This will execute the BIOS' reset stub, which should put everything back to a "safe" starting state before jumping to your ($DFFC) reset vector. This does:

For a slightly faster startup you might just do these things manually rather than using the BIOS' reset. In particular you should write to $4025 to stop the disk motor, and $4023 to re-initialize. The rest you can probably skip?

After your program begins you should make sure that either $100 is set to use one of the other NMI vectors, or make sure NMI 3 at $DFFA has been rewritten with a valid NMI handler. See: Wiki: FDS Pseudo-registers

I've tested this with FDS + FDSStick, Everdrive, PowerPak, and various emulators, all of which appear to support this technique. (See note about PowerPak above in step 1.)

Edited to incorporate further information provided by Loopy below.

Last edited by rainwarrior on Mon May 08, 2017 11:45 pm, edited 5 times in total.

Oh, I see. You were suggesting a size optimization. Yeah, I suppose that makes sense. The FDS will keep reading the entire disk side anyway, right?

Do you know whether this has any potential to produce extra IRQs? Is the FDS in a fully "safe to use" state right away or do I need to wait for the disk to finish before I could enable IRQs in my program?

Oh, I see. You were suggesting a size optimization. Yeah, I suppose that makes sense. The FDS will keep reading the entire disk side anyway, right?

To be clear - by "increase the file count" I mean the value in the File Amount Block, don't actually add another file. That gives the BIOS something to do (seek the next file) instead of end its disk load routine. It just spins until your NMI hits. You don't need to do anything else, the drive will spin to the end of the disk on its own.

rainwarrior wrote:

Do you know whether this has any potential to produce extra IRQs? Is the FDS in a fully "safe to use" state right away or do I need to wait for the disk to finish before I could enable IRQs in my program?

I don't think you need to wait for the disk to finish. FYI - in the fdsstick boot loader, I couldn't use timer IRQs until I wrote $03 to $4023. Without it I would get spurious disk IRQs even after the drive stopped.

That's kinda curious about $4023. The BIOS doesn't seem to write to it except in its reset routine... though it does jump to the reset routine again at the end before it begins your game. In that case it writes $00 then $83 to $4023. Perhaps instead of just I/O enable it also has some sort of reset/acknowledge function?

On another note, after testing on Everdrive and PowerPak as well, both methods worked on Everdrive, but I couldn't get the "256 byte file" method to work on PowerPak. Loopy's "extra non-existent file" method works there, though.

I'm not sure of the cause, but I'd guess that the PowerPak's modified FDS BIOS or implementation is reading through the 256 bytes too fast for an NMI to trigger? (Error 20 is given.)

Both methods work on emulators I've tried, the FDSStick + FDS Ram adapter, and Everdrive, and Loopy's method works on PowerPak. I don't have a working FDS disk drive to test with, but I imagine it should work with both as well.

I didn't know I had to be a programmer to do this. I'm not trying to make my own games, just edit existing games. I have edited text and palletes via hex. I'm trying to do this for use on the NES Classic. I want to have games appear as though they are NES cartridges, rather than Famicom Disks. Can't someone just post a before and after example? Obviously not the whole rom, but the relevant sections.

I think the NES classic uses a different "QD" format but it's mostly similar? I do not have documenation to provide for it though.

Anyway, you'd need to write an alternative bootloader file that responds to entry via NMI #3, and then replaces itself and restores what the original FDS disk would have loaded there during boot. Other than this addition, everything should be more or less like described above.

I think someone could theoretically write an automated tool to do this, but it is not quite trivial work.

On another note, after testing on Everdrive and PowerPak as well, both methods worked on Everdrive, but I couldn't get the "256 byte file" method to work on PowerPak. Loopy's "extra non-existent file" method works there, though.

I'm not sure of the cause, but I'd guess that the PowerPak's modified FDS BIOS or implementation is reading through the 256 bytes too fast for an NMI to trigger? (Error 20 is given.)

Both methods work on emulators I've tried, the FDSStick + FDS Ram adapter, and Everdrive, and Loopy's method works on PowerPak. I don't have a working FDS disk drive to test with, but I imagine it should work with both as well.

I took a look at the PowerPak's modified FDS bios diffed against the original, and it NOPs out a bunch of delay timers in the loading code. I think the intent was to have things load faster than they would have from disk. Anyhow, that explains why the "256 byte" method didn't seem to work for me. Interestingly, hawken's pirate pops appears to do that but it works on PowerPak, but I think it might just be luck about where its timing slice appears to fall.

Anyway, Loopy's suggestion to just use a too-big file count seems to work well everywhere I've tried it. Have amended my post to list it as the "primary" method.

Who is online

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum