nesdev.com
http://forums.nesdev.com/

FFIII init code [TNROM]?
http://forums.nesdev.com/viewtopic.php?f=2&t=15603
Page 1 of 1

Author:  FARID [ Thu Mar 02, 2017 11:45 am ]
Post subject:  FFIII init code [TNROM]?

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?

Author:  Bregalad [ Thu Mar 02, 2017 12:00 pm ]
Post subject:  Re: FFIII init code [TNROM]?

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).

Author:  AWJ [ Thu Mar 02, 2017 12:21 pm ]
Post subject:  Re: FFIII init code [TNROM]?

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.

Author:  Dwedit [ Thu Mar 02, 2017 4:22 pm ]
Post subject:  Re: FFIII init code [TNROM]?

The nice thing about code that only runs once is that it doesn't matter at all how optimized it is.

Author:  tepples [ Thu Mar 02, 2017 5:23 pm ]
Post subject:  Re: FFIII init code [TNROM]?

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.

Author:  Bregalad [ Fri Mar 03, 2017 1:06 am ]
Post subject:  Re: FFIII init code [TNROM]?

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.

Page 1 of 1 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/