;;;;SM = mapper game loading
;=== Include MemoryMap, VectorTable, HeaderInfo ===
.INCLUDE "mapper.inc"

;=== Global Variables ===
.INCLUDE "variables.asm"


Main:
  SEP #$20     ; 8 bit Accumulator, 16 bit X/Y
  REP #$10

  lda #$FF
  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 gameCluster
  sta sourceCluster
  lda gameCluster+1
  sta sourceCluster+1
  lda gameCluster+2
  sta sourceCluster+2
  lda gameCluster+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:

CopyGame:
  PrintString "\nCopying Game..."
  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, dont check again
  
  lda gameSize
  beq CopyGameDone
  PrintString "\nBad header or file size"
  PrintString "\nCopying again..."
  lda #$00
  sta DMAWRITELO
  sta DMAWRITEHI
  sta DMAWRITEBANK   ;;read file so dma wraps, erasing header   REMOVED with CardReadGameFill
 
  lda #$FF
  sta headerType  ;;force it to skip headers, even when not detected  ADDED with CardReadGameFill
  
  wai
  jsr CardReadGameFill  ;;copy again, forcing header skip


CopyGameDone:
  wai
  PrintString "\nGame Copied  "
  PrintHexNum gameSize+1
  PrintHexNum gameSize  
  PrintString "sectors "
  lda gameSize+1
  sta gameROMMbits
  PrintNum gameROMMbits
  PrintString "Mbit"
  
FixMbits:
  lda gameROMMbits
  cmp #10
  bne FixMbitsDone
Fix10Mbits:         ;;rom size fix, change 10Mbits to 12Mbits
  lda #12
  sta gameROMMbits
  jmp FixMbitsDone


FixMbitsDone:



LoadSave:
	PrintString "\nChecking BRAM..."
  lda saveCluster
  bne LoadSaveStart
  lda saveCluster+1
  bne LoadSaveStart
  lda saveCluster+2
  bne LoadSaveStart
  lda saveCluster+3
  bne LoadSaveStart
	PrintString "\nNo Save File"
  jmp LoadSaveDone
LoadSaveStart:
  lda saveCluster
  sta sourceCluster
  lda saveCluster+1
  sta sourceCluster+1
  lda saveCluster+2
  sta sourceCluster+2
  lda saveCluster+3
  sta sourceCluster+3

	PrintString "\nCopying BRAM..."
  lda #$F8
  sta DMAWRITEBANK
  lda #$00
  sta DMAWRITELO
  sta DMAWRITEHI
    
  stz sectorCounter
  stz bankCounter
  lda #kDestSDRAM
  sta destType
  jump jCardReadFile
  PrintString "\nBRAM Copied  "
  PrintHexNum gameSize+1
  PrintHexNum gameSize
  PrintString "sectors "
  lda gameSize
  lsr a
  sta gameSize
  PrintNum gameSize
  PrintString "KB"
  
LoadSaveDone:




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
  jmp 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   ;;dont 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
  jmp 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   ;;dont 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
  jmp 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

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

InternalHeaderIs96:
  PrintString "\n96Mbit ROM"
  jmp InternalHeaderDone

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

InternalHeaderIsLo:
  PrintString "\nHeader at $7FC0"
  jmp InternalHeaderDone
  
InternalHeaderIsHi:
  PrintString "\nHeader at $FFC0"
  jmp InternalHeaderDone


InternalHeaderDone:  
 
  

ROMBattCheck:
  lda gameROMType
  cmp #$02
  beq ROMHasBatt
  cmp #$05
  beq ROMHasBatt
  jmp 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 Forever
 
PrintSRAMSizePrint:
  lda SRAMSizes, y
;  sta temp
  ldy #sourceLo
  PrintString "\n%sKB SRAM Added "
;  PrintHexNum temp
PrintSRAMSizeDone:





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
  jmp 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 Forever


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
  jmp ExLoROMBankingLoop
ExLoROMBankingNot64Mbit:


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

ExLoROMTryHeaderFix:
  jump jPrintClearScreen
  SetCursorPos 0, 0
  PrintString "\nExLoROM "
  PrintNum gameROMMbits
  PrintString "Mbit unsupported"
  PrintString "\nTrying again 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  
  jmp 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
  jmp ExHiROMSRAM
ExHiROMBankingNot64Mbit:

ExHiROMBanking96Mbit:
  cmp #$60
  bne ExHiROMBankingNot96Mbit
  PrintString "96Mbit"
  lda #<ExHiRom96Mbit
  sta destLo
  lda #>ExHiRom96Mbit
  sta destHi
  jmp 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:
  jmp SetROMBankingDone

SetROMBankingDone:




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

DSPCheck:
  lda #$04
  sta CONFIGWRITEDSP  ;;turn on hirom chip     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 Forever
DSPGood:
  lda #$00
  sta CONFIGWRITEDSP  ;;turn off dsp
  lda gameROMMapper
  cmp #$21
  beq HiROMDSP   ;;HIROM 

  lda gameROMMbits  ;;LOROM 16MB
  cmp #$09
  bcs LoROM16DSP
  
  jmp LoROM8DSP
  
HiROMDSP:
  PrintString "\nHiROM DSP1"  ;$00-1f:6000-7fff
  lda #$04
  sta CONFIGWRITEDSP
  jmp 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
  jmp 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
  jmp ROMDSPCheckDone
  
ROMDSPCheckDone:

  jump jPrintBanks

  
  
  
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

  ldy #$0000
  jsr GameGenieWriteCode
  PrintString "\n"
  ldy #$0008
  jsr GameGenieWriteCode
  PrintString "\n"
  ldy #$0010
  jsr GameGenieWriteCode
  PrintString "\n"
  ldy #$0018
  jsr GameGenieWriteCode
  PrintString "\n"
  ldy #$0020
  jsr GameGenieWriteCode
  
  
  

  
  
  
ResetSystem:
  lda #$00
  sta Joy1New
  sta Joy1New+1
  
  lda Joy1Press+1
  and #%00100000
  beq ResetSystemNow
  
  jump jLogScreen
  PrintString "\nScreen Saved to POWERPAK/LOG.TXT"
  
ResetSystemWait:
;	SetCursorPos 27, 1
;	PrintString "FPGA STATUS = "
;  lda CONFIGREADSTATUS
;  sta errorCode
;  PrintHexNum errorCode
  
  wai
  lda Joy1New+1
  and #%00100000
  beq ResetSystemWait

      
ResetSystemNow:
  jsr SaveLast  

  PrintString "\nResetting Now..."
  

  ;lda #$00
  ;sta $4200    ;;turn off nmi
  ;sta $420B    ;;turn off dma 
  ;lda #$80
  ;sta $2100    ;;turn screen off
  
  lda #$00
  sta $420d  ;;turn OFF FASTROM

  
  lda useBattery
  asl a
  and #%00000010
  ora #%10000000
  sta CONFIGWRITESTATUS   ;;WRITE RESET HERE


Forever:
  jump jLogScreen
  PrintString "\nScreen Saved to POWERPAK/LOG.TXT"
ForeverLoop:
  lda Joy1New+1
  and #%00010000
  beq ForeverLoop
  

LoadSIModule:
  jump jClearFindEntry
  lda #'S'
  sta findEntry
  lda #'I'
  sta findEntry+1    
  jump jCardLoadModule      ;load intro module


NoInternalHeader:
  
  lda fixheader
  cmp #$01
  beq NoInteralHeaderFixed  ;;header fix already attempted
  
  jump jPrintClearScreen
  SetCursorPos 0, 0
  PrintString "\nNo Internal Header Found"
  PrintString "\nTrying again with fixed header"
  lda #$01
  sta fixheader
  jmp CheckInternalHeaderHi
  
NoInteralHeaderFixed:
  PrintString "\nNo Internal Header Found"
  PrintString "\nCheck the compatibility list"
  jmp Forever








;;     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
  
  
SaveLast:
  ;;load LAST.TXT file
  lda #'T'
  sta exMatch1
  sta exMatch1+1
  sta exMatch1+2
  sta exMatch1+3
  lda #'X'
  sta exMatch2
  sta exMatch2+1
  sta exMatch2+2
  sta exMatch2+3
  lda #'T'
  sta exMatch3
  sta exMatch3+1
  sta exMatch3+2
  sta exMatch3+3

  lda baseDirCluster   ;;powerpak dir start
  sta sourceCluster
  lda baseDirCluster+1
  sta sourceCluster+1
  lda baseDirCluster+2
  sta sourceCluster+2
  lda baseDirCluster+3
  sta sourceCluster+3


  jump jClearFindEntry   ;;save info to LASTSNES.TXT
  lda #'L'
  sta findEntry
  lda #'A'
  sta findEntry+1
  lda #'S'
  sta findEntry+2
  lda #'T'
  sta findEntry+3
  lda #'S'
  sta findEntry+4
  lda #'N'
  sta findEntry+5
  lda #'E'
  sta findEntry+6
  lda #'S'
  sta findEntry+7

  jump jCardLoadDir    ; powerpak dir
  
  jump jDirFindEntry        ;;get first cluster
  lda tempEntry+$1C
  sta sourceCluster
  lda tempEntry+$1D
  sta sourceCluster+1
  lda tempEntry+$1E
  sta sourceCluster+2
  lda tempEntry+$1F
  sta sourceCluster+3

  ldx #$0000
  ldy #$0000
SaveLastGameLoop:         ;;game name and cluster
  lda gameName, x
  sta sectorBuffer1, y
  iny
  inx
  cpx #34
  bne SaveLastGameLoop
  
  ldx #$0000
SaveLastSaveLoop:         ;;save name and cluster
  lda saveName, x
  sta sectorBuffer1, y
  iny
  inx
  cpx #34
  bne SaveLastSaveLoop
  
  ldx #$0000
SaveLastGameGenieLoop:    ;;game genie chars 5x8
  lda gameGenie, x
  sta sectorBuffer1, y
  iny
  inx
  cpx #40
  bne SaveLastGameGenieLoop
  
  lda #<sectorBuffer1
  sta sourceLo
  lda #>sectorBuffer1
  sta sourceHi
  
  lda #kSourceWRAM
  sta sourceType

  jump jCardWriteFile
  rts
  
  
  
  
  
  
  
  
  
  
  
  
CardReadGameFill:
CardReadFile:                 ;;sourceCluster already set  
  stz gameSize
  stz gameSize+1
  stz headerCounter
  stz headerCounter+1


  lda gameCluster
  sta sourceCluster
  lda gameCluster+1
  sta sourceCluster+1
  lda gameCluster+2
  sta sourceCluster+2
  lda gameCluster+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
  
  jmp 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:
  ;check if cluster = last cluster
  ; if match, 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
  jmp 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 gameCluster
  sta sourceCluster
  lda gameCluster+1
  sta sourceCluster+1
  lda gameCluster+2
  sta sourceCluster+2
  lda gameCluster+3
  sta sourceCluster+3
  stz sectorCounter
  stz bankCounter
  jump jClusterToLBA            ;sourceCluster -> first sourceSector
  jmp CardReadFileLoop          ;;continue looping, copying file from beginning again

CardReadFileExit:
  rts



GameGenieWriteCode:
  PrintString "GG-> "
  jump jGameGenieDecode
 ; PrintString "\n"
  
  lda gameGenie, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+1, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+2, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+3, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+4, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+5, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+6, y
  cmp #16
  beq GameGenieWriteCodeSkip
  lda gameGenie+7, y
  cmp #16
  beq GameGenieWriteCodeSkip
  jmp GameGenieWriteCodeGood

GameGenieWriteCodeSkip:
  PrintString " code unused"
  jmp GameGenieWriteCodeDone
GameGenieWriteCodeGood:

  lda gameGenieDecode, y    ;;data
  sta ggcode
  lda gameGenieDecode+1, y   ;bank
  sta ggcode+1
  lda gameGenieDecode+2, y   ;;high
  sta ggcode+2
  lda gameGenieDecode+3, y   ;;low
  sta ggcode+3

  lda #$00
  sta CONFIGWRITESRAMSIZE

  ;PrintString "$F0"
  ;lda ggcode+2
  ;sta errorCode
;  PrintHexNum ggcode+1
;  PrintHexNum ggcode+2
;  PrintHexNum ggcode+3
  ;lda ggcode+3
  ;sta errorCode
  ;PrintHexNum errorCode


  ;PrintString "<=$"
  ;lda ggcode
  ;sta errorCode
  ;PrintHexNum errorCode
  
 ; jsr Delay5Sec

  lda ggcode+1  ;;GG addr = bbhhll
  and #$F0
  lsr a
  lsr a                  ;;bank index = bb >> 3  Fx->1F
  lsr a
  sta sourceLo  
  PrintString " b="
  PrintHexNum sourceLo
  lda #$00
  sta sourceHi
  ldx sourceLo
  lda gameBanks, x
  sta errorCode
  inx                  ;;;THIS IS WRONG?  SHOULD BE +$10?
  
  lda gameBanks, x
  sta errorCode+1
    
;  jsr Delay5Sec
  
  lda errorCode

 ; and #$20
 ; asl a
 ; ora errorCode
;  ora #$40       ;;make writeable
;  sta errorCode
  sta CONFIGWRITEBANK+$1E0  ;;put indexed bank into F0low reg
  PrintString "blo="
  PrintHexNum errorCode
  
;  jsr Delay5Sec
  
  lda errorCode+1
;  and #$20
;  asl a
;  ora errorCode+1
;  sta errorCode+1
  sta CONFIGWRITEBANK+$1F0  ;;put indexed bank into F0hi reg
  
  PrintString "bhi="
  PrintHexNum errorCode+1
;  jsr Delay5Sec

  lda ggcode+3
  sta destLo
  lda ggcode+2
  sta destHi
  lda ggcode+1
  and #$0F
  sta errorCode
  PrintHexNum  errorCode
  PrintHexNum  destHi
  PrintHexNum  destLo
  ldx destLo
  lda errorCode
  cmp #$00
  beq GGF0
  cmp #$01
  beq GGF1
  cmp #$02
  beq GGF2
  cmp #$03
  beq GGF3
  cmp #$04
  beq GGF4
  cmp #$05
  beq GGF5
  cmp #$06
  beq GGF6
  cmp #$07
  beq GGF7
  jmp GGFjump


GGF0:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F00000, x
  jmp GGCheck
GGF1:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F10000, x
  jmp GGCheck
GGF2:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F20000, x
  jmp GGCheck
GGF3:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F30000, x
  jmp GGCheck
GGF4:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F40000, x
  jmp GGCheck
GGF5:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F50000, x
  jmp GGCheck
GGF6:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F60000, x
  jmp GGCheck
GGF7:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F70000, x
  jmp GGCheck
GGFjump
  cmp #$08
  beq GGF8
  cmp #$09
  beq GGF9
  cmp #$0A
  beq GGFA
  cmp #$0B
  beq GGFB
  cmp #$0C
  beq GGFC
  cmp #$0D
  beq GGFD
  cmp #$0E
  beq GGFE
  cmp #$0F
  beq GGFF
GGF8:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F80000, x
  jmp GGCheck
GGF9:  
  lda ggcode             ;;write GG data to F0hhll
  sta $F90000, x
  jmp GGCheck
GGFA:  
  lda ggcode             ;;write GG data to F0hhll
  sta $FA0000, x
  jmp GGCheck
GGFB:  
  lda ggcode             ;;write GG data to F0hhll
  sta $FB0000, x
  jmp GGCheck
GGFC:  
  lda ggcode             ;;write GG data to F0hhll
  sta $FC0000, x
  jmp GGCheck
GGFD:  
  lda ggcode             ;;write GG data to F0hhll
  sta $FD0000, x
  jmp GGCheck
GGFE:  
  lda ggcode             ;;write GG data to F0hhll
  sta $FE0000, x
  jmp GGCheck
GGFF:  
  lda ggcode             ;;write GG data to F0hhll
  sta $FF0000, x
  jmp GGCheck

  
GGCheck:
  lda $F00000, x
  sta errorCode
  stx sourceLo
;  PrintString "c="
;  PrintHexNum errorCode
  
;  PrintString " a="
;  PrintHexNum sourceLo+1
;  PrintHexNum sourceLo
  
;  jsr Delay5Sec
;  jsr Delay5Sec

  lda sramSizeByte
  sta CONFIGWRITESRAMSIZE
  lda gameBanks+$1E
  sta CONFIGWRITEBANK+$1E0  ;;put bank back
  lda gameBanks+$1F
  sta CONFIGWRITEBANK+$1F0  ;;put bank back
   
GameGenieWriteCodeDone:
  rts
