It is currently Thu Oct 19, 2017 6:05 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: FFIII init code [TNROM]?
PostPosted: Thu Mar 02, 2017 11:45 am 
Offline
User avatar

Joined: Wed Apr 07, 2010 1:14 am
Posts: 484
Location: Iran
This is the init code of Final Fantasy III (J) [!].nes

Code:
1F:FF48:78        SEI
1F:FF49:D8        CLD
1F:FF4A:A9 00     LDA #$00
1F:FF4C:8D 00 20  STA $2000 = #$00
1F:FF4F:8D 01 20  STA $2001 = #$00
1F:FF52:8D 10 40  STA $4010 = #$FF
1F:FF55:A2 02     LDX #$02
1F:FF57:2C 02 20  BIT $2002 = #$00
1F:FF5A:10 FB     BPL $FF57
1F:FF5C:CA        DEX
1F:FF5D:D0 F8     BNE $FF57
1F:FF5F:A2 FF     LDX #$FF
1F:FF61:9A        TXS
1F:FF62:A9 40     LDA #$40
1F:FF64:8D 00 01  STA $0100 = #$4C
1F:FF67:8D 03 01  STA $0103 = #$40
1F:FF6A:8D 17 40  STA $4017 = #$FF
1F:FF6D:A9 00     LDA #$00
1F:FF6F:8D 00 A0  STA $A000 = #$02
1F:FF72:A9 80     LDA #$80
1F:FF74:8D 01 A0  STA $A001 = #$FF
1F:FF77:8D 00 80  STA $8000 = #$01
1F:FF7A:A9 00     LDA #$00
1F:FF7C:8D 01 80  STA $8001 = #$69
1F:FF7F:8D 00 E0  STA $E000 = #$A9
1F:FF82:AD 02 20  LDA $2002 = #$00
1F:FF85:A9 10     LDA #$10
1F:FF87:AA        TAX
1F:FF88:8D 06 20  STA $2006 = #$00
1F:FF8B:8D 06 20  STA $2006 = #$00
1F:FF8E:49 10     EOR #$10
1F:FF90:CA        DEX
1F:FF91:D0 F5     BNE $FF88
1F:FF93:8D 00 E0  STA $E000 = #$A9
1F:FF96:A2 00     LDX #$00
1F:FF98:8E 00 80  STX $8000 = #$01
1F:FF9B:BD B3 FF  LDA $FFB3,X @ $FFB3 = #$00
1F:FF9E:8D 01 80  STA $8001 = #$69
1F:FFA1:E8        INX
1F:FFA2:E0 06     CPX #$06
1F:FFA4:90 F2     BCC $FF98
1F:FFA6:A9 40     LDA #$40
1F:FFA8:8D 00 A0  STA $A000 = #$02
1F:FFAB:A9 80     LDA #$80
1F:FFAD:8D 01 A0  STA $A001 = #$FF
1F:FFB0:4C 00 C0  JMP $C000


Code:
@ $FFB3 :
00 02 04 05 06 07


I tried to comment some of them :

Code:
  .org $C000

   .db $00, $02, $04, $05, $06, $07
 
RESET:
   SEI         ; ignore IRQs
   CLD         ; disable decimal mode   
   LDA #$00
   STA $2000   ; disable NMI
   STA $2001   ; disable rendering
   STA $4010   ; disable DMC IRQs
   
   LDX #$02      ;
loop1:         ;
   BIT $2002   ; PPU warm up
   BPL loop1   ;
   DEX         ;
   BNE loop1   ;
   
   LDX #$FF
   TXS         ; Set up stack
   
   LDA #$40
   STA $0100   ; maybe for future use?
   STA $0103   ; maybe for future use?
   STA $4017   ; disable APU frame IRQ
   
   LDA #$00
   STA $A000   ; MMC3 Mirroring reg
   
   LDA #$80
   STA $A001   ; MMC3 wram reg
   
   STA $8000   ; MMC3 bank select reg
   LDA #$00
   STA $8001   ; MMC3 bank number reg
   
   STA $E000   ; MMC3 IRQ disable reg
   
   LDA $2002   ;
   LDA #$10      ;
   TAX         ;
loop2:         ;
   STA $2006   ; ?
   STA $2006   ;
   EOR #$10      ;
   DEX         ;
   BNE loop2   ;
   
   STA $E000   ; MMC3 IRQ disable reg (isn't it disabled already?)
   
   LDX #$00      ;
loop3:         ;
   STX $8000   ;
   LDA $C000,X   ; ?
   STA $8001   ;
   INX         ;
   CPX #$06      ;
   BCC loop3   ;
   
   LDA #$40
   STA $A000   ; MMC3 Mirroring reg (isn't 6th bit unused?)
   
   LDA #$80
   STA $A001   ; MMC3 wram reg (isn't it enabled already?)


Can anyone please explain the unknown parts?


Last edited by FARID on Thu Mar 02, 2017 12:03 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Thu Mar 02, 2017 12:00 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7230
Location: Chexbres, VD, Switzerland
The first unknown part seems to manually clock the IRQ counter 10 times. The second unknown part swaps character RAM banks in order, so that banks #0 and #2 are swapped in the left pattern table and #4, #5, #6 and #7 swapped in the right pattern table. (i.e. this is contigious 8kb CHR-RAM as if it was unbanked).


Top
 Profile  
 
PostPosted: Thu Mar 02, 2017 12:21 pm 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 429
FARID wrote:
Code:
   LDA #$40
   STA $0100   ; maybe for future use?
   STA $0103   ; maybe for future use?


In Final Fantasy 3 (and many games by Square, on both the NES and SNES) the IRQ and NMI vectors point into RAM rather than ROM. By writing a JMP instruction at the vector location, different sections of the game can use different, optimized interrupt handlers. At startup, and when they want to change the address the trampoline points to, they write a RTI instruction ($40) to ensure that the game doesn't jump to invalid code (think of what would happen if the interrupt fired in the middle of updating the vector, when the low byte is the new vector but the high byte is still the old vector)

Quote:
Code:
   LDA $2002   ;
   LDA #$10   ;
   TAX         ;
loop2:         ;
   STA $2006   ; ?
   STA $2006   ;
   EOR #$10   ;
   DEX         ;
   BNE loop2   ;


This code is toggling bit $1000 of the PPU address bus in a loop. I think it must have something to do with MMC3 scanline interrupts, but I'm not sure whether it's really needed. Someone with more experience with MMC3 can probably answer.

Quote:
Code:
loop3:         ;
   STX $8000   ;
   LDA $C000,X   ; ?
   STA $8001   ;
   INX         ;
   CPX #$06   ;
   BCC loop3   ;


This part is setting up the CHR banks. TNROM boards have CHR RAM rather than CHR ROM, but the CHR RAM is still bankswitched through the mapper.

Code:
[quote]   LDA #$40
   STA $A000   ; MMC3 Mirroring reg (6th bit isn't unused?)
   
   LDA #$80
   STA $A001   ; MMC3 wram reg (isn't it enabled already?)
[/quote]

Not sure about $A000... maybe development/prototype hardware has a meaningful register bit there?

The second write to $A001 is indeed redundant. They may have copy-pasted part of the initialization from another game or from Nintendo sample code, and didn't notice that they ended up initializing the same register twice.


Top
 Profile  
 
PostPosted: Thu Mar 02, 2017 4:22 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
The nice thing about code that only runs once is that it doesn't matter at all how optimized it is.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Thu Mar 02, 2017 5:23 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19100
Location: NE Indiana, USA (NTSC)
Dwedit wrote:
The nice thing about code that only runs once is that it doesn't matter at all how optimized it is.

Very little code "only runs once". More commonly, code runs every time you start the program. Something that takes ten seconds every time you start the program will be noticed. That's why the copy protection in Spyro: Year of the Dragon wasn't more thorough: it needed exclusive use of the optical drive for several seconds. But I see your point: in practice, it's fine to burn a couple hundred thousand 6502 cycles at every reset.

In addition, code that only runs once per power-on still takes space, and that can add up in a crowded fixed bank.


Top
 Profile  
 
PostPosted: Fri Mar 03, 2017 1:06 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7230
Location: Chexbres, VD, Switzerland
Dwedit wrote:
The nice thing about code that only runs once is that it doesn't matter at all how optimized it is.

Not for speed, but for ROM usage, yes, and FF3 definitely was getting very tight on ROM, there's few if any unused bytes in the ROM.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 9 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