FFIII init code [TNROM]?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
FARID
Posts: 499
Joined: Wed Apr 07, 2010 1:14 am
Location: Iran
Contact:

FFIII init code [TNROM]?

Post by FARID »

This is the init code of Final Fantasy III (J) [!].nes

Code: Select all

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: Select all

@ $FFB3 :
00 02 04 05 06 07
I tried to comment some of them :

Code: Select all

  .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.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: FFIII init code [TNROM]?

Post by Bregalad »

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).
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: FFIII init code [TNROM]?

Post by AWJ »

FARID wrote:

Code: Select all

	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)

Code: Select all

	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.

Code: Select all

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: Select all

[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.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: FFIII init code [TNROM]?

Post by Dwedit »

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!
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: FFIII init code [TNROM]?

Post by tepples »

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.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: FFIII init code [TNROM]?

Post by Bregalad »

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.
Post Reply