;==========================================================================================
;
;   UNOFFICIAL SNES POWERPAK FIRMWARE V2.02 (CODENAME: "SIMBA")
;   (c) 2012/2013 by ManuLöwe (http://www.manuloewe.de/)
;
;	*** CF MODULE: SI (INTRO SCREEN) ***
;	Code in this file based on v1.0X code written by:
;	- bunnyboy (SNES PowerPak creator), (c) 2009
;
;==========================================================================================



; ****************************** Includes ******************************

; More includes at end of file!

	.INCLUDE "module_rommakeup.inc"		; MemoryMap, VectorTable, HeaderInfo

	.INCLUDE "global_variables.asm"		; Global Variables



; ******************************** Main ********************************

Main:
	sep #A_8BIT				; 8 bit Accumulator, 16 bit X/Y
	rep #XY_8BIT

	jsr VersionCheck			; check for bootloader ROM version, back here means we're up to date

	lda #$FF				; hide cursor (necessary when returning here from another module)
	sta cursorX
	lda #$F0
	sta cursorY

	ClearLine 10

	SetCursorPos 10, 7
	PrintString " CF modules v2.02 \"SIMBA\""

	jsr UserLogo				; check for user logo setting

	lda #$00
	sta CONFIGWRITEDSP			; turn off DSP chip

	stz Joy1Press
	stz Joy1Press+1				; reset input buttons
	stz Joy1New
	stz Joy1New+1



; *************************** Configure FPGA ***************************

	lda CONFIGREADSTATUS			; open bus = $20

;	sta errorCode
;	SetCursorPos 14, 1
;	PrintString "FPGA status="
;	PrintHexNum errorCode
;
;	jump jForever

	and #$F0
	cmp #$A0
	bne ConfigureFPGA

;	SetCursorPos 15, 1
;	PrintString "FPGA was configured"

	lda CONFIGREADSTATUS			; battery used = D1
	and #$02
	bne BatteryUsed

;	SetCursorPos 16, 1
;	PrintString "battery not used"

	jmp FPGAConfigured



BatteryUsed:
;	SetCursorPos 16, 1
;	PrintString "battery used"

	FindFile "SQ.MAP"

	jmp NextModule



ConfigureFPGA:
;	lda #$FF
;	sta $420d				; turn on FastROM

	lda #$01
	sta FPGAPROGRAMWRITE			; SEND PROGRAM SIGNAL TO FPGA
	lda #$00
	sta FPGAPROGRAMWRITE			; SEND PROGRAM SIGNAL TO FPGA
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	lda #$01
	sta FPGAPROGRAMWRITE			; SEND PROGRAM SIGNAL TO FPGA

	FindFile "TOPLEVEL.BIT"

	jump jCardLoadFPGA

;	ClearLine 18
;	SetCursorPos 18, 1
;	PrintString "FPGA just configured\n"

	wai
	lda #%00000001
	sta CONFIGWRITESTATUS			; unlock SDRAM

;	PrintString "unlocked sdram"

	SetCursorPos 24, 0

	jsr FPGACheck
	jsr DSPCheck
	jsr SDRAMCheck



FPGAConfigured:
	rep #A_8BIT				; A = 16 bit

	ldy #$0000				; clear out game name, save name, and clusters
	lda #'  '

-	sta gameName.gName, y
	sta saveName.sName, y
	iny
	iny
	cpy #$007C
	bne -

	stz gameName.gCluster
	stz gameName.gCluster+2

	stz saveName.sCluster
	stz saveName.sCluster+2

	sep #A_8BIT				; A = 8 bit

	jump jGameGenieClearAll			; clear out Game Genie codes

	jsr ShowHelp				; show button assignment hints

.IFDEF SHOWDEBUGMSGS

	SetCursorPos 2, 22

	rep #A_8BIT

	tsc					; print stack pointer (initial value: $1FFF)

	sep #A_8BIT

	xba
	sta temp
	PrintHexNum temp

	xba
	sta temp
	PrintHexNum temp

.ENDIF



; ***************************** Intro Loop *****************************

IntroLoop:
	wai

;	ClearLine 27
;	SetCursorPos 27, 1
;	PrintString "FPGA STATUS = "
;	lda CONFIGREADSTATUS
;	sta errorCode
;	PrintHexNum errorCode

SelectCheck:
	lda Joy1New+1				; check for Select button
	and #%00100000
	beq __SelectCheckDone

	jsr ShowChipsetDMA			; Select pressed, show console chipset revision, and more
	jsr ShowLogoNo
	jsr FPGACheck
	jsr DSPCheck
	jsr SDRAMCheck

	ClearLine 21				; hide help lines
	ClearLine 22

	jump jMemCheck				; do a profound SDRAM check

	jsr ShowHelp				; restore help ...

	ClearLine 12				; ... and hide system info lines again
	ClearLine 13
	ClearLine 14
	ClearLine 15

	bra IntroLoop

__SelectCheckDone:



StartCheck:
	lda Joy1New+1				; check for Start button
	and #%00010000
	beq __StartCheckDone

	jsr ShowLoadingMsg

	jsr LoadLastGame			; load last game info

	FindFile "SO.MAP"			; go to options module

	jmp NextModule

__StartCheckDone:



LRCheck:
	lda Joy1Press				; check for L and R button
	and #%00110000
	cmp #%00110000
	beq +

	jmp __LRCheckDone

+	jsr ShowLoadingMsg

	wai					; ensure "Loading" appears on the screen

	jump jLoadDevMusic			; load music first

	FindFile "SD.MAP"			; load Developer's Note module

	jmp NextModule

__LRCheckDone:



ACheck:
	lda Joy1New+0				; check for A button
	and #%10000000
	beq __ACheckDone

	jsr ShowLoadingMsg

	FindFile "SN.MAP"			; go to ROM browser

	jmp NextModule

__ACheckDone:



XCheck:
	lda Joy1New				; check for X button
	and #%01000000
	beq __XCheckDone

	FindFile "SC.MAP"			; go to customization

	jmp NextModule

__XCheckDone:



.IFDEF ALLOWMANUALUPDATE

BUpCheck:
	lda Joy1Press+1				; check for B+Up button
	and #%10001000
	cmp #%10001000
	bne __BUpCheckDone

	jmp __LaunchUpdater

__BUpCheckDone:

.ENDIF

	jmp IntroLoop



; ******************************* Checks *******************************

FPGACheck:
	lda #$00
	sta CONFIGWRITEDSP			; turn off DSP chip
	lda CONFIGREADSTATUS			; open bus = $20
	sta errorCode
	and #$F0
	cmp #$A0
	beq FPGACheckPass

FPGACheckFail:
	PrintString "\n    FPGA error "
	PrintHexNum errorCode

	jump jForever

FPGACheckPass:

rts



SDRAMCheck:
	lda $F00000
	sta errorCode

	lda #$55
	sta $F00000
	lda $F00000
	sta errorCode+1

	lda errorCode
	sta $F00000

	lda errorCode+1
	cmp #$55

	lda #$AA
	sta $F00000
	lda $F00000
	cmp #$AA

	bne SDRAMError
	bra SDRAMPass1

SDRAMError:
	PrintString "\n         SDRAM error "
	lda $F00000
	sta errorCode
	PrintHexNum errorCode

	jump jForever

SDRAMPass1:

rts



DSPCheck:
	SetCursorPos 13, 1

	lda #$04
	sta CONFIGWRITEDSP			; turn on HiROM chip
	lda.l $007000				; HiROM $00:6000 = DR, $00:7000 = SR
	sta errorCode
	and #%10000000
	beq __NoDSP

	PrintString "DSP1: installed"
	bra __DSPCheckDone

__NoDSP:
	PrintString "DSP1: not installed"

__DSPCheckDone:

rts



ShowChipsetDMA:
	lda $4210				; CPU version
	and #$0F
	sta temp

	lda $213E				; PPU1 version
	and #$0F
	sta temp+1

	lda $213F				; PPU2 version
	and #$0F
	sta temp+2

	SetCursorPos 12, 23
	PrintString "CPU: "
	PrintHexNum temp

	SetCursorPos 13, 22
	PrintString " PPU1: "
	PrintHexNum temp+1

	SetCursorPos 14, 22
	PrintString " PPU2: "
	PrintHexNum temp+2

	SetCursorPos 15, 22
	PrintString "Video: "			; completed in the following subroutine

	jsr CheckFrameLength

	SetCursorPos 12, 1
	PrintString "DMA: "

	lda dontUseDMA
	bne __DMAOff

	PrintString "on "
	bra __ShowChipsetDMADone

__DMAOff:
	PrintString "off"

__ShowChipsetDMADone:

rts



ShowLogoNo:
	SetCursorPos 14, 1
	PrintString "Logo: "

	lda configLogo
	cmp #$02				; $02 = Simba
	bne +
	PrintString "2 (Simba)"
	bra __ShowLogoNoDone
+
	cmp #$03				; $03 = SFC dots
	bne +
	PrintString "3 (SFC dots)"
	bra __ShowLogoNoDone
+
	PrintString "1 (Power)"			; else it must be the standard PowerPak logo

__ShowLogoNoDone:

rts



; ********************** Check user logo setting ***********************

UserLogo:
	lda configLogo

	cmp #$02				; if LOGO=2, change logo to Simba
	bne +
	lda #$7C				; logo tile diff. ($7C = Simba)
	sta temp
	lda #$02				; logo palette diff. ($02 = Simba)
	sta temp+1
	lda #$20				; tile num for "paw" cursor, next is palette
	sta temp+2
	lda #$02				; vhoopppc Vert Horiz priOrity Palette Charmsb
	sta temp+3
	bra __LogoConfigDone

+	cmp #$03				; if LOGO=3, change logo to SFC "four dots"
	bne +
	lda #$84				; logo tile diff. ($84 = SFC dots)
	sta temp
	lda #$04				; logo palette diff. ($04 = SFC dots)
	sta temp+1
	lda #$22				; tile num for "red dot" cursor, next is palette
	sta temp+2
	lda #$04				; vhoopppc Vert Horiz priOrity Palette Charmsb
	sta temp+3
	bra __LogoConfigDone

+	stz temp				; in any other case, logo tile & palette diff. = $00 = PowerPak (standard)
	stz temp+1
	stz temp+2
	lda #$06				; standard PowerPak cursor palette
	sta temp+3

__LogoConfigDone:

	jump jLoadLogo				; load logo
rts



; ************************* Frame length check *************************

; This code snippet is roughly based on a Super GameBoy (rev 1.0) dis-
; assembly, which to my knowledge is the only commercial ROM to perform
; a fail-safe check like this.
;
; I don't fully understand why the Y counter value differs depending
; on the video refresh rate (50 or 60 Hz). In any case, the actual set-
; ting is correctly returned even on hardware that tries to "cheat" by
; overriding bit 4 of register $213F (e.g. ARP, Ultra16).

CheckFrameLength:
	sei					; disable NMI & IRQ so it won't interfere with timing
	stz REG_NMI_TIMEN

	phy
	ldy #$0000

-	bit HVBJOY				; wait for Vblank
	bpl -

	lda $4210				; RDNMI (bit 7 = Vblank NMI flag)

-	iny
	lda $4210
	bpl -

	lda $4210

	lda #$00				; dunno what this is for, possibly timing-related?

	cpy #$137F				; rough average between 50 and 60 Hz values (see debug section below)
	bcc __60hz
	PrintString "50Hz"
	bra +

__60hz:
	PrintString "60Hz"

+

.IFDEF SHOWDEBUGMSGS

; Print current counter value. The number varies depending both on the context of this subroutine and on
; what happens during Vblank, so it's necessary to re-measure after changing anything. Also, the currently
; selected HDMA design has a slight influence (hence the XX). Some measured values:
; @50Hz: $15XX (U16, PAL/1Chip, PAL/2PPUs)
; @60Hz: $11XX (U16, PAL/1Chip, US/GPM-01, PAL/2PPUs, 1/1/1 chipset SFC)

	SetCursorPos 2, 22

	rep #A_8BIT

	tya

	sep #A_8BIT

	xba
	sta temp
	PrintHexNum temp

	xba
	sta temp
	PrintHexNum temp

.ENDIF

	ply

	lda #$81				; re-enable Vblank NMI + automatic joypad reading
	sta REG_NMI_TIMEN
	cli
rts



; **************************** Button hints ****************************

ShowHelp:
	SetCursorPos 21, 6
	PrintString "A: browse card  -  X: customize"

	SetCursorPos 22, 3
	PrintString "Start: last game - Sel: info - L+R: credits"
rts



; ************************ Show loading message ************************

ShowLoadingMsg:
	lda #$FF				; hide logo
	sta SpriteBuf1+17
	sta SpriteBuf1+21
	sta SpriteBuf1+25
	sta SpriteBuf1+29
	sta SpriteBuf2+1			; 32x32 sprites

	stz scrollY				; make sure previous scrolling won't affect string position
	stz scrollYCounter
	stz scrollYUp
	stz scrollYDown
	stz speedCounter
	stz speedScroll

	jump jPrintClearScreen

	SetCursorPos 11, 11
	PrintString "Loading ..."
rts



; *************************** Version check ****************************

; This checks the boot ROM version and launches the flash updater if a
; previous version is detected.

VersionCheck:
	lda $00814C				; check for "SIMBA" (= v2.0X final)
	cmp #'S'
	bne __BlackScreen			; go to trap loop if no SIMBA firmware installed
	lda $00814D
	cmp #'I'
	bne __BlackScreen
	lda $00814E
	cmp #'M'
	bne __BlackScreen
	lda $00814F
	cmp #'B'
	bne __BlackScreen
	lda $008150
	cmp #'A'
	bne __BlackScreen

	lda $008149				; last digit of on-screen ROM version string
	cmp #'2'				; current version or not?
	bcc __LaunchUpdater
rts

__BlackScreen:
	lda #$80				; turn screen off
	sta $2100
-	wai
	bra -

__LaunchUpdater:
	FindFile "SU.MAP"



NextModule:
	jump jCardLoadModule



; ****************************** Includes ******************************

	.INCLUDE "global_func_lastload.inc.asm"	; Module-specific functions
