It is currently Mon Dec 11, 2017 10:15 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue May 02, 2017 12:21 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
Edit: Problem has been solved, full solution below.


In this post ccovell described a way of bypassing the FDS license screen, and I'm having trouble getting it to work.

ccovell wrote:
Pokun wrote:
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:

Attachment:
File comment: modified example with KYODAKU license
fds_example3b.fds [63.98 KiB]
Downloaded 35 times

This simply adds one more booting file like described. I see no change; the game still boots but the license screen appears too.

Attachment:
File comment: modified example with no KYODAKU license
fds_example3a.fds [63.98 KiB]
Downloaded 40 times

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.

Top
 Profile  
 
PostPosted: Tue May 02, 2017 2:11 am 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3487
Location: Indianapolis
Maybe you could also look at the games by Super Pig, they bypass the license screen also.


Top
 Profile  
 
PostPosted: Tue May 02, 2017 2:30 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
I've got it now. ccovell's description was incomplete. Here's the full solution:


Example ca65 project: thread post


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:
  • $2001 = #$10 ; disable NMI
  • Wait 2 frames (PPU warmup)
  • $4022 = #$00 ; disable IRQ timer
  • $4023 = #$00 ; disable disk and audio I/O?
  • $4023 = #$83 ; enable disk and audio I/O? (Might also "reset" it? See Loopy's post below.)
  • $FB-FD = #$00 ; initializes some ZP variables
  • $4016 = #$00 ; gamepad read strobe off
  • $4025 = #$2E ; stop disk drive motor, select horizontal mirroring (also written to $FA for BIOS readback)
  • $4026 = #$FF ; expansion connector? (also written to $F9)
  • $4010 = #$00 ; disable DPCM
  • $4017 = #$C0 ; disable APU frame IRQ
  • $4015 = #$0F ; enable APU sound
  • $4080 = #$80 ; reset FDS audio volume envelope
  • $408A = #$E8 ; initialize FDS audio envelope speed to specific valus
  • S = #$FF ; set up stack
  • $100 = #$C0 ; Select "NMI #3" (overwrite this if you haven't replaced $DFFA)
  • $101 = #$80 ; Selects IRQ routine (routine for $80 is $4030 read with delay)

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.

Top
 Profile  
 
PostPosted: Tue May 02, 2017 8:28 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:52 pm
Posts: 361
Location: UT
rainwarrior wrote:
1. The last boot file should write 32 copies of [ $90, $00, $00, $00, $00, $00, $00, $00 ] repeating, loaded at $2000. (256 bytes.)

Write just the one byte ($90) and increase the file count. NMI kicks in while BIOS is busy looking for the next file.


Top
 Profile  
 
PostPosted: Tue May 02, 2017 10:11 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
loopy wrote:
rainwarrior wrote:
1. The last boot file should write 32 copies of [ $90, $00, $00, $00, $00, $00, $00, $00 ] repeating, loaded at $2000. (256 bytes.)

Write just the one byte ($90) and increase the file count. NMI kicks in while BIOS is busy looking for the next file.

I had tried a longer file, actually, but it's not the problem (256 bytes is plenty long enough). See my second post in this thread, above.

The problem was that you need to use NMI 3 like a "reset" vector. A regular NMI routine will finish and go back to the loading.


Last edited by rainwarrior on Tue May 02, 2017 10:15 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue May 02, 2017 10:15 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:52 pm
Posts: 361
Location: UT
Yes of course, you still need to replace the NMI vector. I'm just saying the 256-byte fill is unnecessary.


Top
 Profile  
 
PostPosted: Tue May 02, 2017 10:18 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
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?


Top
 Profile  
 
PostPosted: Tue May 02, 2017 10:56 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:52 pm
Posts: 361
Location: UT
rainwarrior wrote:
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.

FDSStick reset code
Code:
reset
        lda #%00010000          ;NMI off
        sta $2000
        lda #%00100110          ;stop drive, select v-mirror
        sta $4025
        lda #$03                ;stop disk irq?  Need this to use timer irq, disk irq seems to stay active...
        sta $4023
        lda #$80                ;select $DFF8 nmi vector
        sta $100


Top
 Profile  
 
PostPosted: Tue May 02, 2017 11:20 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
Thanks for that information!

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?


Top
 Profile  
 
PostPosted: Tue May 02, 2017 2:14 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
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.


Top
 Profile  
 
PostPosted: Mon May 08, 2017 7:52 am 
Offline

Joined: Mon May 08, 2017 7:44 am
Posts: 2
Can someone explain this for dummies? So, do I just add $90 (3 characters?) before the header?

What is a reset vector?

Where do I change the number of sides?

Explain it to me like I'm five. I sorta know how to use a hex editor. That's about all.


Top
 Profile  
 
PostPosted: Mon May 08, 2017 10:33 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
marioxb wrote:
Can someone explain this for dummies? So, do I just add $90 (3 characters?) before the header?

What is a reset vector?

Where do I change the number of sides?

Explain it to me like I'm five. I sorta know how to use a hex editor. That's about all.

Your questions indicate that you will need to learn a lot of things before you will be able to accomplish this.

I made an example FDS project here but it's intended as an example for people who understand NES development but don't know the FDS yet.

For you, though, I'd suggest finding an NES development tutorial (e.g. Nerdy Nights is the most popular), and come back to thinking about the FDS later once you're comfortable with the basics.

Alternatively you could explain the specific thing that you hope to do? Why are you asking about skipping the license screen on the FDS specifically?


Top
 Profile  
 
PostPosted: Mon May 08, 2017 10:58 am 
Offline

Joined: Mon May 08, 2017 7:44 am
Posts: 2
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.


Top
 Profile  
 
PostPosted: Mon May 08, 2017 11:09 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
If you want to patch existing FDS files there's a bit more work involved. My example was for making a homebrew from scratch.

The FDS file format is outlined here: http://wiki.nesdev.com/w/index.php/Family_Computer_Disk_System

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.


Top
 Profile  
 
PostPosted: Mon May 08, 2017 11:40 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
rainwarrior wrote:
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Nioreh and 4 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group