;==========================================================================================
;
;   UNOFFICIAL SNES POWERPAK FIRMWARE V2.01 (CODENAME: "SIMBA")
;   (c) 2012/2013 by ManuLöwe (http://www.manuloewe.de/)
;
;	*** CF MODULE: SM (GAME MAPPING) ***
;	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

	lda #$FF				; hide cursor
	sta cursorX
	lda #$F0
	sta cursorY

	jump jPrintClearScreen

 	SetCursorPos 0, 0

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

	ldx #$0000
	lda #$00

ClearBanks:
	sta gameBanks, x
	inx
	cpx #$20
	bne ClearBanks

	lda #$00
	sta headerType
	sta fixheader

	lda gameName.gCluster
	sta sourceCluster
	lda gameName.gCluster+1
	sta sourceCluster+1
	lda gameName.gCluster+2
	sta sourceCluster+2
	lda gameName.gCluster+3
	sta sourceCluster+3

	lda #<sectorBuffer1
	sta destLo
	lda #>sectorBuffer1
	sta destHi				; put into sector RAM
	stz destBank

	stz sectorCounter
	stz bankCounter

	jump jClusterToLBA			; sourceCluster -> first sourceSector

	lda #kDestWRAM
	sta destType

	jump jCardReadSector			; sector -> WRAM     lda gameCluster

;  lda #$00
;  sta DMAWRITELO
;  lda #$FE
;  sta DMAWRITEHI
;  lda #$FF
;  sta DMAWRITEBANK   ;;read file so dma wraps, erasing header   REMOVED with CardReadFileFill

	jump jSWCHeaderCheck
	jump jGD3HeaderCheck

;  lda headerType
;  bne FileHeaderDone   REMOVED with CardReadFileFill

	lda #$00
	sta DMAWRITELO
	sta DMAWRITEHI
	sta DMAWRITEBANK			; read file to beginning

FileHeaderDone:



; **************************** ROM Loading *****************************

CopyGame:
	PrintString "\nLoading ROM ..."

	wai

;lda gameCluster
;sta sourceCluster
;lda gameCluster+1
;sta sourceCluster+1
;lda gameCluster+2
;sta sourceCluster+2  ; REMOVED with CardReadGameFill
;lda gameCluster+3
;sta sourceCluster+3
;stz sectorCounter
;stz bankCounter

	jsr CardReadGameFill

;  wai
;  PrintString "\nGame Copied  "
;  PrintHexNum gameSize+1
;  PrintHexNum gameSize
;  PrintString "sectors "
;  lda gameSize+1
;  sta gameROMMbits
;  PrintNum gameROMMbits
;  PrintString "Mbit"

	lda headerType
	cmp #$00
	bne CopyGameDone			; if already found header, don't check again

	lda gameSize
	beq CopyGameDone

	PrintString "\nIrregular header or file size, retrying ..."

	lda #$00
	sta DMAWRITELO
	sta DMAWRITEHI
	sta DMAWRITEBANK			; read file so dma wraps, erasing header

	lda #$FF				; force it to skip headers, even when not detected
	sta headerType				; (ADDED with CardReadGameFill)

	wai

	jsr CardReadGameFill			; copy again, forcing header skip

CopyGameDone:
	wai
	PrintString "\nLoaded "
	PrintHexNum gameSize+1
	PrintHexNum gameSize
	PrintString " sectors ="
	lda gameSize+1
	sta gameROMMbits
	PrintNum gameROMMbits
	PrintString " Mbit"

FixMbits:
	lda gameROMMbits
	cmp #9
	beq Fix9or10Mbits
	cmp #10
	beq Fix9or10Mbits
	bra FixMbitsDone

Fix9or10Mbits:					; ROM size fix, change 9 or 10 Mbits to 12 Mbits
	lda #12
	sta gameROMMbits

;  jmp FixMbitsDone

FixMbitsDone:



; **************************** SRAM Loading ****************************

LoadSave:
	PrintString "\nChecking SRAM ..."

	lda saveName.sCluster
	bne LoadSaveStart
	lda saveName.sCluster+1
	bne LoadSaveStart
	lda saveName.sCluster+2
	bne LoadSaveStart
	lda saveName.sCluster+3
	bne LoadSaveStart

	PrintString "\nNo save file."

	jmp LoadSaveDone

LoadSaveStart:
	lda saveName.sCluster
	sta sourceCluster
	lda saveName.sCluster+1
	sta sourceCluster+1
	lda saveName.sCluster+2
	sta sourceCluster+2
	lda saveName.sCluster+3
	sta sourceCluster+3

	PrintString "\nLoading SRAM ..."

	lda #$F8
	sta DMAWRITEBANK
	lda #$00
	sta DMAWRITELO
	sta DMAWRITEHI

	stz sectorCounter
	stz bankCounter
	lda #kDestSDRAM
	sta destType

	jump jCardReadFile

	PrintString "\nSRAM loaded "
	PrintHexNum gameSize+1
	PrintHexNum gameSize
	PrintString " sectors ="
	lda gameSize
	lsr a
	sta gameSize
	PrintNum gameSize
	PrintString " KB"

LoadSaveDone:



; *************************** ROM ID checks ****************************

CheckInternalHeaderExHi:
	lda #$D5
	sta DMAWRITELO
	lda #$FF
	sta DMAWRITEHI
	lda #$40
	sta DMAWRITEBANK			; check for internal header  40FFC0

	jump jCopyROMInfo

;PrintString "/nmapper="
;PrintHexNum gameROMMapper

	lda gameROMMapper

; cmp #$35
; beq CheckInternalHeaderExHiType

	cmp #$25
	beq CheckInternalHeaderExHiType
	bra NotInternalHeaderExHi

CheckInternalHeaderExHiType:

; PrintString "/nMAP good "

	lda gameROMType
	cmp #$06				; ROM type must be <= 5
	bcs NotInternalHeaderExHi

;PrintString "/nROM good "

	lda #$60
	cmp gameROMMbits			; ROM size <= 96Mbits
	bcc NotInternalHeaderExHi

;PrintString "SIZE good "

	lda #$08
	cmp saveSize				; SRAM size <= 8d
	bcc NotInternalHeaderExHi

;PrintString "RAM good "

	lda gameResetVector+1
	cmp #$80				; reset vector goes to >= 8000
	bcc NotInternalHeaderExHi

;PrintString "RESET good "

	jmp InternalHeaderIsExHi

NotInternalHeaderExHi:
	PrintString "\nNo $40FFC0 header"



CheckInternalHeaderHi:
	lda #$D5
	sta DMAWRITELO
	lda #$FF
	sta DMAWRITEHI
	lda #$00
	sta DMAWRITEBANK			; check for internal header $FFC0

	jump jCopyROMInfo

	lda fixheader
	beq CheckInternalHeaderHiMapper		; don't fix the header
	lda #$21
	sta gameROMMapper			; assume HiROM

CheckInternalHeaderHiMapper:
	lda gameROMMapper

;cmp #$20
;beq CheckInternalHeaderHiType

	cmp #$21
	beq CheckInternalHeaderHiType

;cmp #$22
;beq CheckInternalHeaderHiType

	cmp #$25
	beq CheckInternalHeaderHiType
	bra NotInternalHeaderHi

CheckInternalHeaderHiType:
	lda gameROMType
	cmp #$06				; ROM type must be <= 5
	bcs NotInternalHeaderHi

	lda #$40
	cmp gameROMMbits			; ROM size <= 64Mbits
	bcc NotInternalHeaderHi

	lda #$08
	cmp saveSize				; SRAM size <= 8d
	bcc NotInternalHeaderHi

	lda gameResetVector+1
	cmp #$80				; reset vector goes to >= 8000
	bcc NotInternalHeaderHi

	jmp InternalHeaderIsHi

NotInternalHeaderHi:
	PrintString "\nNo $FFC0 header"



CheckInternalHeaderLo:
	lda #$D5
	sta DMAWRITELO
	lda #$7F
	sta DMAWRITEHI
	lda #$00
	sta DMAWRITEBANK			; check for internal header $7FC0

	jump jCopyROMInfo

	lda fixheader
	beq CheckInternalHeaderLoMapper		; don't fix the header
	lda #$20
	sta gameROMMapper			; assume LoROM

CheckInternalHeaderLoMapper:
	lda gameROMMbits
	cmp #$60
	beq InternalHeaderIs96

	lda gameROMMapper
	cmp #$20
	beq CheckInternalHeaderLoType

;cmp #$21
;beq CheckInternalHeaderLoType

	cmp #$22
	beq CheckInternalHeaderLoType

;cmp #$25
;beq CheckInternalHeaderLoType

	bra NotInternalHeaderLo

CheckInternalHeaderLoType:
	lda gameROMType
	cmp #$06				; ROM type must be <= 5
	bcs NotInternalHeaderLo

	lda #$20
	cmp gameROMMbits			; ROM size <= 32Mbits
	bcc NotInternalHeaderLo

	lda #$08
	cmp saveSize				; SRAM size <= 8d
	bcc NotInternalHeaderLo

	lda gameResetVector+1
	cmp #$80				; reset vector goes to >= 8000
	bcc NotInternalHeaderLo

	bra InternalHeaderIsLo

NotInternalHeaderLo:
	PrintString "\nNo $7FC0 header"
	jmp NoInternalHeader

InternalHeaderIs96:
	PrintString "\n96Mbit ROM"
	bra InternalHeaderDone

InternalHeaderIsExHi:
	PrintString "\nHeader at $40FFC0"
	bra InternalHeaderDone

InternalHeaderIsLo:
	PrintString "\nHeader at $7FC0"
	bra InternalHeaderDone

InternalHeaderIsHi:
	PrintString "\nHeader at $FFC0"
;	bra InternalHeaderDone

InternalHeaderDone:



ROMBattCheck:
	lda gameROMType
	cmp #$02
	beq ROMHasBatt
	cmp #$05
	beq ROMHasBatt
	bra ROMBattCheckDone

ROMHasBatt:
	lda #$01
	sta useBattery

	PrintString "\nBattery added"

	lda saveSize
	bne ROMBattCheckDone

	PrintString "\nNo SRAM, no battery"

	lda #$00
	sta useBattery

ROMBattCheckDone:

SetSRAMSize:
	lda saveSize
	sta destLo
	lda #$00
	sta destHi
	ldy destLo

	lda SRAMSizes, y
	sta sramSizeByte
	sta CONFIGWRITESRAMSIZE

	lda saveSize
	bne SetSRAMSizeDone
	lda #$00
	sta useBattery				; no battery when no SRAM

SetSRAMSizeDone:

PrintSRAMSize:

;  lda saveSize
;  cmp #$07
;  bcs PrintSRAMSizeBad

	lda saveSize
	sta destLo
	lda #$00
	sta destHi
	ldy destLo
	lda SRAMTextLo, y
	sta sourceLo
	lda SRAMTextHi, y
	sta sourceHi

;  jmp PrintSRAMSizePrint
;PrintSRAMSizeBad:
;  PrintString "\nUnknown SRAM size"
;  jmp FatalError

PrintSRAMSizePrint:
	lda SRAMSizes, y

;  sta temp

	ldy #sourceLo

;  PrintString "\n%s KB SRAM added"		; FIXME2.0 if possible (broken, shows wrong numbers)
;  PrintHexNum temp

PrintSRAMSizeDone:



; **************************** ROM Banking *****************************

SetROMBanking:
	lda #$00
	sta bankOffset
	sta bankOffset+1



Check96Banking:
	lda gameROMMbits
	cmp #$60
	bne Check96BankingDone
	jmp ExHiROMBanking

Check96BankingDone:



CheckLoROMBanking:
	lda gameROMMapper
	cmp #$20
	bne CheckLoROMBankingDone
	bra LoROMBanking

CheckLoROMBankingDone:



CheckHiROMBanking:
	lda gameROMMapper
	cmp #$21
	bne CheckHiROMBankingDone
	jmp HiROMBanking

CheckHiROMBankingDone:



CheckExLoROMBanking:
	lda gameROMMapper
	cmp #$22
	bne CheckExLoROMBankingDone
	jmp ExLoROMBanking

CheckExLoROMBankingDone:



CheckExHiROMBanking:
	lda gameROMMapper
	cmp #$25
	bne CheckExHiROMBankingDone
	jmp ExHiROMBanking

CheckExHiROMBankingDone:

;  PrintString "\nMapper "
;  PrintHexNum gameROMMapper
;  PrintString " unsupported"
;  jmp FatalError



LoROMBanking:
	PrintString "\nLoROM "
	PrintNum gameROMMbits
	PrintString " Mbit"
	lda gameROMMbits
	lsr a
	lsr a
	sta bankCounter
	dec bankCounter
                     ;        76543210
                     ;  76543 210
	lda bankCounter				; multiply by 32 for bytes in map
	asl a
	asl a
	asl a
	asl a
	asl a
	sta sourceLo
	lda bankCounter
	lsr a
	lsr a
	lsr a
	sta sourceHi

	lda #<LoRom4Mbit
	clc
	adc sourceLo
	sta destLo
	lda #>LoRom4Mbit
	adc sourceHi
	sta destHi

	jump jCopyBanks



LoROMSRAM:
	lda saveSize
	beq LoROMBankingDone
	PrintString "\nSRAM in 7x/Fx"
	lda #$7F
	sta CONFIGWRITEBANK+$0E0		; 70l // add sram into banks
	sta gameBanks+$0E
	sta CONFIGWRITEBANK+$1E0		; F0l
	sta gameBanks+$1E

LoROMBankingDone:



	lda #$00
	sta CONFIGWRITESRAMLO			; no SRAM in $6000-$7fff
	sta CONFIGWRITESRAMHI
	jmp SetROMBankingDone



ExLoROMBanking:
	PrintString "\nExLoROM "
	lda gameROMMbits

ExLoROMBanking48Mbit:
	cmp #$30
	bne ExLoROMBankingNot48Mbit
	PrintString "48Mbit"
	lda #<ExLoRom48Mbit
	sta destLo
	lda #>ExLoRom48Mbit
	sta destHi
	jmp ExLoROMBankingLoop

ExLoROMBankingNot48Mbit:



ExLoROMBanking64Mbit:
	cmp #$40
	bne ExLoROMBankingNot64Mbit
	PrintString "64Mbit"
	lda #<ExLoRom64Mbit
	sta destLo
	lda #>ExLoRom64Mbit
	sta destHi
	bra ExLoROMBankingLoop

ExLoROMBankingNot64Mbit:



	lda fixheader				; ExLoROM of wrong size found
	cmp #$01
	bne ExLoROMTryHeaderFix			; header fix already attempted

	jmp FatalError



ExLoROMTryHeaderFix:
	jump jPrintClearScreen
	SetCursorPos 0, 0

;  PrintString "\nExLoROM "
;  PrintNum gameROMMbits
;  PrintString " Mbit unsupported"
;  PrintString "\nRetrying with fixed header ..."

	PrintString "\nUnsupported ExLoROM size, retrying with fixed header ..."

	lda #$01
	sta fixheader
	lda #$FF
	sta headerType
	jmp CheckInternalHeaderHi



ExLoROMBankingLoop:
	jump jCopyBanks

	jmp LoROMSRAM



HiROMBanking:
	PrintString "\nHiROM "
	PrintNum gameROMMbits
	PrintString " Mbit"
	lda gameROMMbits
	lsr a
	lsr a
	sta bankCounter
	dec bankCounter
                     ;        76543210
                     ;  76543 210
	lda bankCounter				; multiply by 32 for bytes in map
	asl a
	asl a
	asl a
	asl a
	asl a
	sta sourceLo
	lda bankCounter
	lsr a
	lsr a
	lsr a
	sta sourceHi

	lda #<HiRom4Mbit
	clc
	adc sourceLo
	sta destLo
	lda #>HiRom4Mbit
	adc sourceHi
	sta destHi

	jump jCopyBanks

	lda saveSize
	beq HiROMNoSRAM
	PrintString "\nSRAM in 20-3F/A0-BF:$6000-7FFF"
	lda #$0C
	sta CONFIGWRITESRAMLO			; SRAM in $6000-$7fff = 0C 0C
	sta CONFIGWRITESRAMHI

;;;;;;FIXME lda something here?

	cmp #$30
	bne HiROMBankingDone



HiROM48SRAM:
	PrintString "\nSRAM in $80-BF:$6000-7FFF"
	lda #$00
	sta CONFIGWRITESRAMLO			; SRAM in $6000-$7fff = 00 0F
	lda #$0F
	sta CONFIGWRITESRAMHI
	bra HiROMBankingDone



HiROMNoSRAM:
	PrintString "\nNo HiROM SRAM"
	lda #$00
	sta CONFIGWRITESRAMLO			; no SRAM
	sta CONFIGWRITESRAMHI



HiROMBankingDone:
	jmp SetROMBankingDone



ExHiROMBanking:
	PrintString "\nExHiROM "
	lda #$00
	sta CONFIGWRITESRAMLO			; no SRAM
	sta CONFIGWRITESRAMHI

	lda gameROMMbits



ExHiROMBanking48Mbit:
	cmp #$30
	bne ExHiROMBankingNot48Mbit
	PrintString "48Mbit"
	lda #<ExHiRom48Mbit
	sta destLo
	lda #>ExHiRom48Mbit
	sta destHi

;PrintString "\nSRAM in $80-BF:$6000-7FFF"
;lda #$00
 ; sta CONFIGWRITESRAMLO           ;;sram in 6000-7fff = 00 0F
;lda #$0F
;sta CONFIGWRITESRAMHI

	PrintString "\nSRAM in 20-3F/A0-BF:$6000-7FFF"
	lda #$0C
	sta CONFIGWRITESRAMLO			; SRAM in $6000-$7fff = 0C 0C
	sta CONFIGWRITESRAMHI

	jmp ExHiROMBankingLoop

ExHiROMBankingNot48Mbit:



ExHiROMBanking64Mbit:
	cmp #$40
	bne ExHiROMBankingNot64Mbit
	PrintString "64Mbit"
	lda #<ExHiRom64Mbit
	sta destLo
	lda #>ExHiRom64Mbit
	sta destHi
	bra ExHiROMSRAM

ExHiROMBankingNot64Mbit:



ExHiROMBanking96Mbit:
	cmp #$60
	bne ExHiROMBankingNot96Mbit
	PrintString "96Mbit"
	lda #<ExHiRom96Mbit
	sta destLo
	lda #>ExHiRom96Mbit
	sta destHi
	bra ExHiROMSRAM

ExHiROMBankingNot96Mbit:

	PrintNum gameROMMbits
	PrintString "Mbit unsupported"



ExHiROMSRAM:
	lda saveSize
	beq ExHiROMBankingLoop
	PrintString "\nSRAM in 20-3F/A0-BF:$6000-7FFF"
	lda #$0C
	sta CONFIGWRITESRAMLO			; SRAM in $6000-$7fff = 0C 0C
	sta CONFIGWRITESRAMHI

ExHiROMBankingLoop:
	jump jCopyBanks

ExHiROMBankingDone:
;	bra SetROMBankingDone

SetROMBankingDone:



ROMDSPCheck:
	lda gameROMType
	cmp #$03
	beq ROMHasDSP
	cmp #$04
	beq ROMHasDSP
	cmp #$05
	beq ROMHasDSP
	jmp ROMDSPCheckDone

ROMHasDSP:



DSPCheck:
	lda #$04				; turn on HiROM chip
	sta CONFIGWRITEDSP			; HiROM $00:6000 = DR, $00:7000 = SR
	lda $007000
	and #%10000000
	bne DSPGood



DSPBad:
	lda #$00
	sta CONFIGWRITEDSP			; turn off DSP

	PrintString "\n\nDSP1 chip required"

	jmp FatalError



DSPGood:
	lda #$00
	sta CONFIGWRITEDSP			; turn off DSP
	lda gameROMMapper
	cmp #$21
	beq HiROMDSP				; HiROM

	lda gameROMMbits			; LoROM 16MB
	cmp #$09
	bcs LoROM16DSP

	bra LoROM8DSP



HiROMDSP:
	PrintString "\nHiROM DSP1"		; $00-1f:6000-7fff
	lda #$04
	sta CONFIGWRITEDSP
	bra ROMDSPCheckDone



LoROM8DSP:
	PrintString "\nLoROM DSP1 4-8Mb"	; $20-3f:8000-ffff
	lda #$01
	sta CONFIGWRITEDSP
	lda #$00
	sta CONFIGWRITEBANK+$050		; 20
	sta gameBanks+$05
	sta CONFIGWRITEBANK+$150		; A0
	sta gameBanks+$15
	sta CONFIGWRITEBANK+$070		; 30
	sta gameBanks+$07
	sta CONFIGWRITEBANK+$170		; B0
	sta gameBanks+$17
	bra ROMDSPCheckDone



LoROM16DSP:
	PrintString "\nLoROM DSP1 16Mb"		; $60-6f:0000-7fff
	lda #$02
	sta CONFIGWRITEDSP
	lda #$00
	sta CONFIGWRITEBANK+$0C0		; 60
	sta gameBanks+$0C
	sta CONFIGWRITEBANK+$1C0		; E0
	sta gameBanks+$1C
;	bra ROMDSPCheckDone



ROMDSPCheckDone:

	jump jPrintBanks			; skip to avoid user confusion due to possible screen overflow



; ************************** GameGenie codes ***************************

LoadGameGenie:

;lda #$60
;sta CONFIGWRITEBANK+$3F0
;lda #$60
;sta CONFIGWRITEBANK+$3E0
;lda $F08000
;sta errorCode
;PrintHexNum errorCode
;lda #$55
;sta $F08000
;lda $F08000
;sta errorCode
;PrintHexNum errorCode

	PrintString "\n"
	ldy #$0000
	jump jGameGenieWriteCode
	PrintString "\n"
	ldy #$0008
	jump jGameGenieWriteCode
	PrintString "\n"
	ldy #$0010
	jump jGameGenieWriteCode
	PrintString "\n"
	ldy #$0018
	jump jGameGenieWriteCode
	PrintString "\n"
	ldy #$0020
	jump jGameGenieWriteCode



; ***************************** Reset SNES *****************************

ResetSystem:
	lda #$00
	sta Joy1New
	sta Joy1New+1

	lda Joy1Press+1
	and #%00100000				; if user holds Select, log screen and wait
	beq ResetSystemNow

	jsr LogScreenMessage



ResetSystemWait:

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

	wai
	lda Joy1New+1
	and #%00010000				; once Start is pressed, reset SNES to start game
	beq ResetSystemWait



ResetSystemNow:
	jsr SaveLastGame

	PrintString "\nResetting ..."

;lda #$00
;sta $4200    ;;turn off nmi
;sta $420B    ;;turn off dma

	lda #$80
	sta $2100				; turn off the screen, might help suppress annoying effects

	lda #$00
	sta $420d				; turn off FastROM

	lda useBattery
	asl a
	and #%00000010
	ora #%10000000
	sta CONFIGWRITESTATUS			; reset PowerPak, start game



; *********************** Screen logging message ***********************

LogScreenMessage:
	jump jLogScreen

	PrintString "\nScreen saved to POWERPAK/LOG.TXT"
rts



; *************************** Error handling ***************************

FatalError:
	jsr LogScreenMessage

	PrintString "\n\nPress Start to return to the titlescreen"

-	wai
	lda Joy1New+1
	and #%00010000				; wait for Start button ...
	beq -

	FindFile "SI.MAP"			; Start pressed, return to intro

	jump jPrintClearScreen

	jump jLoadRomVersion

	jump jCardLoadModule			; return to titlescreen

;	lda #%10000001				; alternatively:
;	sta CONFIGWRITESTATUS			; Start pressed, reset PowerPak, stay in boot mode



NoInternalHeader:
	lda fixheader
	cmp #$01
	beq NoInteralHeaderFixed		; header fix already attempted

	jump jPrintClearScreen

	SetCursorPos 0, 0

	PrintString "\nNo internal header found, retrying with fixed header ..."

	lda #$01
	sta fixheader

	jmp CheckInternalHeaderHi



NoInteralHeaderFixed:
	PrintString "\nROM loading failed, please check the compatibility list!"

	jmp FatalError



; ************************** Banking Database **************************

;	     00   10   20   30   40   50   60   70   80   90   A0   B0   C0   D0   E0   F0
LoRom4Mbit:
	.db $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20
	.db $00, $00, $00, $00, $20, $20, $20, $20, $00, $00, $00, $00, $20, $20, $20, $20

LoRom8Mbit:
	.db $20, $21, $20, $21, $20, $21, $20, $21, $20, $21, $20, $21, $20, $21, $20, $21
	.db $00, $00, $00, $00, $20, $21, $20, $21, $00, $00, $00, $00, $20, $21, $20, $21

LoRom12Mbit:					; UNTESTED
	.db $20, $21, $22, $23, $20, $21, $22, $23, $20, $21, $22, $23, $20, $21, $22, $23
	.db $00, $00, $00, $00, $20, $21, $22, $23, $00, $00, $00, $00, $20, $21, $22, $23

LoRom16Mbit:
	.db $20, $21, $22, $23, $20, $21, $22, $23, $20, $21, $22, $23, $20, $21, $22, $23
	.db $00, $00, $00, $00, $20, $21, $22, $23, $00, $00, $00, $00, $20, $21, $22, $23

LoRom20Mbit:					; UNTESTED
	.db $20, $21, $22, $23, $24, $25, $26, $27, $20, $21, $22, $23, $24, $25, $26, $27
	.db $00, $00, $00, $00, $24, $25, $26, $27, $00, $00, $00, $00, $24, $25, $26, $27

LoRom24Mbit:					; UNTESTED
	.db $20, $21, $22, $23, $24, $25, $26, $27, $20, $21, $22, $23, $24, $25, $26, $27
	.db $00, $00, $00, $00, $24, $25, $26, $27, $00, $00, $00, $00, $24, $25, $26, $27

LoRom28Mbit:					; UNTESTED
	.db $20, $21, $22, $23, $24, $25, $26, $27, $20, $21, $22, $23, $24, $25, $26, $27
	.db $00, $00, $00, $00, $24, $25, $26, $27, $00, $00, $00, $00, $24, $25, $26, $27

LoRom32Mbit:
	.db $20, $21, $22, $23, $24, $25, $26, $27, $20, $21, $22, $23, $24, $25, $26, $27
	.db $00, $00, $00, $00, $24, $25, $26, $27, $00, $00, $00, $00, $24, $25, $26, $27

ExLoRom48Mbit:					; UNTESTED
	.db $28, $29, $2A, $2B, $20, $21, $22, $23, $28, $29, $2A, $2B, $24, $25, $26, $27
	.db $00, $00, $00, $00, $20, $21, $22, $23, $00, $00, $00, $00, $24, $25, $26, $27

ExLoRom64Mbit:					; UNTESTED
	.db $28, $29, $2A, $2B, $20, $21, $22, $23, $2C, $2D, $2E, $2F, $24, $25, $26, $27
	.db $00, $00, $00, $00, $20, $21, $22, $23, $00, $00, $00, $00, $24, $25, $26, $27



;	     00   10   20   30   40   50   60   70   80   90   A0   B0   C0   D0   E0   F0
HiRom4Mbit:
	.db $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1
	.db $00, $00, $00, $00, $A0, $A0, $A0, $A0, $00, $00, $00, $00, $A0, $A0, $A0, $A0

HiRom8Mbit:
	.db $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1, $A1
	.db $00, $00, $00, $00, $A0, $A0, $A0, $A0, $00, $00, $00, $00, $A0, $A0, $A0, $A0

HiRom12Mbit:					; UNTESTED
	.db $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3
	.db $00, $00, $00, $00, $A0, $A2, $A0, $A2, $00, $00, $00, $00, $A0, $A2, $A0, $A2

HiRom16Mbit:
	.db $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3, $A1, $A3
	.db $00, $00, $00, $00, $A0, $A2, $A0, $A2, $00, $00, $00, $00, $A0, $A2, $A0, $A2

HiRom20Mbit:					; UNTESTED
	.db $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A0, $A2, $A4, $A6, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom24Mbit:					; UNTESTED
	.db $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A0, $A2, $A4, $A6, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom28Mbit:					; UNTESTED
	.db $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A0, $A2, $A4, $A6, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom32Mbit:
	.db $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A0, $A2, $A4, $A6, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom36Mbit:					; UNTESTED
	.db $A1, $A3, $A5, $A7, $A9, $AB, $A9, $AB, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A8, $AA, $A8, $AA, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom40Mbit:					; UNTESTED
	.db $A1, $A3, $A5, $A7, $A9, $AB, $A9, $AB, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A8, $AA, $A8, $AA, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom44Mbit:					; UNTESTED
	.db $A1, $A3, $A5, $A7, $A9, $AB, $A9, $AB, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A8, $AA, $A8, $AA, $00, $00, $00, $00, $A0, $A2, $A4, $A6

HiRom48Mbit:
	.db $A1, $A3, $A5, $A7, $A9, $AB, $A9, $AB, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A8, $AA, $A8, $AA, $00, $00, $00, $00, $A0, $A2, $A4, $A6

ExHiRom48Mbit:
	.db $A9, $AB, $A9, $AB, $A9, $AB, $A9, $AB, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A8, $AA, $A8, $AA, $00, $00, $00, $00, $A0, $A2, $A4, $A6

ExHiRom64Mbit:
	.db $A9, $AB, $AD, $AF, $A9, $AB, $AD, $AF, $A1, $A3, $A5, $A7, $A1, $A3, $A5, $A7
	.db $00, $00, $00, $00, $A8, $AA, $AC, $AE, $00, $00, $00, $00, $A0, $A2, $A4, $A6

ExHiRom96Mbit:
	.db $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $2A, $2B, $2C, $2D, $2E, $2F
	.db $00, $00, $00, $00, $30, $31, $32, $33, $00, $00, $00, $00, $34, $35, $36, $37



SRAMSizes:
	.db %11111111, %11111111, %11111110, %11111100, %11111000, %11110000, %11100000, %11000000, %10000000, %00000000
;	       0          2          4          8        16          32           64       128        256         512



SRAMTextLo:
	.db <SRAM0Kb, <SRAM16Kb, <SRAM32Kb, <SRAM64Kb, <SRAM128Kb, <SRAM256Kb, <SRAM512Kb, <SRAM1024Kb

SRAMTextHi:
	.db >SRAM0Kb, >SRAM16Kb, >SRAM32Kb, >SRAM64Kb, >SRAM128Kb, >SRAM256Kb, >SRAM512Kb, >SRAM1024Kb

SRAM0Kb:
	.db "0", 0

SRAM16Kb:
	.db "2", 0

SRAM32Kb:
	.db "4", 0

SRAM64Kb:
	.db "8", 0

SRAM128Kb:
	.db "16", 0

SRAM256Kb:
	.db "32", 0

SRAM512Kb:
	.db "64", 0

SRAM1024Kb:
	.db "128", 0



; ************************** CardReadGameFill **************************

CardReadGameFill:

CardReadFile:					; sourceCluster already set
	stz gameSize
	stz gameSize+1
	stz headerCounter
	stz headerCounter+1

	lda gameName.gCluster
	sta sourceCluster
	lda gameName.gCluster+1
	sta sourceCluster+1
	lda gameName.gCluster+2
	sta sourceCluster+2
	lda gameName.gCluster+3
	sta sourceCluster+3

	stz sectorCounter
	stz bankCounter

	jump jClusterToLBA			; sourceCluster -> first sourceSector

CardReadFileLoop:

;  PrintHexNum sourceSector+3
;  PrintHexNum sourceSector+2
;  PrintHexNum sourceSector+1
;  PrintHexNum sourceSector+0
;  PrintString "."

	lda headerCounter
	bne CardReadFileSector
	lda headerCounter+1
	bne CardReadFileSector			; if header counter != 0, load sector
	lda headerType
	beq CardReadFileSector			; if no header, load sector

	bra CardReadFileSectorDone		; if sector=0 and header, skip copying that sector

CardReadFileSector:
	lda #kDestSDRAM
	sta destType
	jump jCardReadSector

	clc
	lda gameSize
	adc #$01
	sta gameSize
	lda gameSize+1
	adc #$00
	sta gameSize+1				; keep track of game size, skipping header sectors

CardReadFileSectorDone:

	clc
	lda headerCounter
	adc #$01
	sta headerCounter
	lda headerCounter+1
	adc #$00
	sta headerCounter+1			; keep track of sector count for header skipping

	lda destHi
	pha
	lda destLo
	pha
	jump jLoadNextSectorNum
	pla
	sta destLo
	pla
	sta destHi

CardReadFileLastSectorCheck:
	lda #$0F
	sta temp
	lda #$FF
	sta temp+1				; FAT32 last cluster = 0x0FFFFFFF
	sta temp+2
	sta temp+3

	lda fat32Enabled
	cmp #$01
	beq CardReadFileLastSectorCheck2	; if FAT32, last cluster mask done

	lda #$00
	sta temp
	sta temp+1				; FAT16 last cluster = 0x0000FFFF

CardReadFileLastSectorCheck2:			; if cluster = last cluster, jmp to last entry found
	lda temp
	cmp sourceCluster+3
	bne CardReadFileNextSector
	lda temp+1
	cmp sourceCluster+2
	bne CardReadFileNextSector
	lda temp+2
	cmp sourceCluster+1
	bne CardReadFileNextSector
	lda temp+3
	cmp sourceCluster+0
	bne CardReadFileNextSector
	bra CardReadFileDone

CardReadFileNextSector:
	inc destHi
	inc destHi
	inc bankCounter
	lda bankCounter

;  cmp #$00                 ;;only load 256x512=128KB for modules
;  beq CardReadFileDone

	jmp CardReadFileLoop

CardReadFileDone:

	lda gameSize+1
	cmp #$04
	bcs CardReadFileExit			; if A >= mem, carry set     $400 sectors = 512KB

CardReadFileAgain:
	stz headerCounter
	stz headerCounter+1			; reset the header checking

	lda gameName.gCluster
	sta sourceCluster
	lda gameName.gCluster+1
	sta sourceCluster+1
	lda gameName.gCluster+2
	sta sourceCluster+2
	lda gameName.gCluster+3
	sta sourceCluster+3

	stz sectorCounter
	stz bankCounter

	jump jClusterToLBA			; sourceCluster -> first sourceSector

	jmp CardReadFileLoop			; continue looping, copying file from beginning again

CardReadFileExit:

rts



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

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