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



; *************************** Hardware info ****************************

;00 - boot rom
;20 -
;40 - fpga program
;60 - fpga cs
;80 - card write
;A0 - card read
;C0 -
;E0 -



; BOARD REV C
;  $00-$1F boot rom in 8000-FFFF  LOROM 1MB
;  $20-$3F config regs in 8000-FFFF   20=configs/status  30=DMA regs
;  $40-$5F FPGA /program in 8000-FFFF
;  $60-$7F FPGA /cs in 8000-FFFF
;  $80-$9F CF write in 0000-FFFF
;  $A0-$BF CF READ in 0000-FFFF
;  $C0-$DF
;  $E0-$FF



; KNOWN BOARD REVISIONS:
; revC ??????? (source: original PowerPak creator's comment just above)
; revD 8/ 9/09 (source: ManuLöwe's PowerPak :p)
; revE 2/23/10 (source: http://forums.nesdev.com/viewtopic.php?p=97596#p97596)
; revH 8/14/11 (source: http://forums.nesdev.com/viewtopic.php?p=106411#p106411)



;********************;   pdf p113
; CF                  A10  A3  A2  A1  A0  /REG
; SNES                gnd  A3  A2  A1  A0  vcc
;
; data read                0   0   0   0       xxx0
; error                    0   0   0   1       xxx1
; status                   0   1   1   1       xxx7
;
; data write               0   0   0   0       xxx0
; feature write            0   0   0   1       xxx1
; sector count             0   0   1   0       xxx2
; lba 0                    0   0   1   1       xxx3
; lba 1                    0   1   0   0       xxx4
; lba 2                    0   1   0   1       xxx5
; lba 3                    0   1   1   0       xxx6
; command                  0   1   1   1       xxx7
; device                   1   1   1   0       xxxE
;
;*********************;



; ********************** Global compiler settings **********************

;.DEFINE ALLOWMANUALUPDATE			; uncomment to enable manual launching of the flash updater (press B+Up on the intro)

;.DEFINE SHOWDEBUGMSGS				; uncomment to print stack pointer, selectedEntry, frame length counter etc.

;.DEFINE DEBUG					; whatever you do, don't uncomment this one (effects untested!)



; *************************** SNES registers ***************************

; status bits

	.DEFINE XY_8BIT			$10
	.DEFINE A_8BIT			$20
	.DEFINE AXY_8BIT		$30

; some general registers

	.DEFINE REG_SLHV		$2137
	.DEFINE REG_OPVCT		$213D
	.DEFINE REG_NMI_TIMEN		$4200

; joypad ports

	.DEFINE HVBJOY			$4212
	.DEFINE JOY0			$4218
	.DEFINE JOY1			$421A
	.DEFINE JOY2			$421C
	.DEFINE JOY3			$421E
	.DEFINE JOYSER0			$4016
	.DEFINE JOYSER1			$4017
	.DEFINE WRIO			$4201

; SPC700 I/O ports

	.DEFINE APUIO0			$2140
	.DEFINE APUIO1			$2141
	.DEFINE APUIO2			$2142
	.DEFINE APUIO3			$2143



; ************************* PowerPak registers *************************

; CF CARD READ REGISTERS

	.DEFINE CARDDATAREAD		$A08000
	.DEFINE CARDDATAREADbank	$A0
	.DEFINE CARDDATAREADhigh	$80
	.DEFINE CARDDATAREADlow		$00
	.DEFINE CARDSTATUS		$A0800E	; 7   ;0111
	.DEFINE CARDALTSTATUS		$A08007	; E   ;1110
	.DEFINE CARDDRIVEADDRESS	$A0800F	; F   ;1111
	.DEFINE CARDERROR		$A08008	; 1   ;0001
	.DEFINE CARDSECTORCOUNTREAD	$A08004	; 2   ;0010
	.DEFINE CARDLBA0READ		$A0800C	; 3   ;0011
	.DEFINE CARDLBA1READ		$A08002	; 4   ;0100
	.DEFINE CARDLBA2READ		$A0800A	; 5   ;0101
	.DEFINE CARDLBA3READ		$A08006	; 6   ;0110

; CF CARD WRITE REGISTERS

	.DEFINE CARDDATAWRITE		$808000	; 0  ;0000
	.DEFINE CARDSECTORCOUNT		$808004	; 2  ;0010
	.DEFINE CARDLBA0		$80800C	; 3  ;0011
	.DEFINE CARDLBA1		$808002	; 4  ;0100
	.DEFINE CARDLBA2		$80800A	; 5  ;0101
	.DEFINE CARDLBA3		$808006	; 6  ;0110
	.DEFINE CARDCOMMAND		$80800E	; 7  ;0111
	.DEFINE CARDDEVICE		$808007	; E  ;1110


; FPGA CONFIG WRITE REGISTERS

	.DEFINE FPGADATAWRITE		$608000
	.DEFINE FPGAPROGRAMWRITE	$408000



; ************************* Config. registers **************************

; MEM MAPPER CONFIG REGS

	.DEFINE CONFIGWRITEBANK		$208000

;00h 10h 20h 30h 40h 50h 60h 70h  80h 90h A0h B0h C0h D0h E0h F0h   bit5=rom bit6=sram
;010 030 050 070 090 0B0 0D0 0F0  110 130 150 170 190 1B0 1D0 1F0    xSRxxxxx
;                                                 390 3B0 3D0 3F0   ;;F0 active during boot

;                40l 50l 60l 70l                  C0l D0l E0l F0l
;                080 0A0 0C0 0E0                  180 1A0 1C0 1E0
;                                                 380 3A0 3C0 3E0   ;;F0 active during boot

	.DEFINE CONFIGWRITESRAMLO	$208001
	.DEFINE CONFIGWRITESRAMHI	$208002
	.DEFINE CONFIGWRITESRAMSIZE	$208003	; 0 = use bit, 1 = dont use bit
	.DEFINE CONFIGWRITESTATUS	$208004
	.DEFINE CONFIGREADSTATUS	$208005
	.DEFINE CONFIGWRITEDSP		$208005	; 0=none, 1=8MbLoROM, 2=16MbLoROM, 4=HIROM

;  7     6      5      4      3       2       1       0
; programmed signature A   clklock sdramidle batt
; rst                      rstclk  rstsdram  batt

	.DEFINE DMAWRITELO		$308000
	.DEFINE DMAWRITEHI		$308001
	.DEFINE DMAWRITEBANK		$308002
	.DEFINE DMAREADDATA		$21FF



; **************************** Jump table ******************************

.ENUM $00
	jCardReadSector			dw
	jCardWriteSector		dw
	jForever			dw
	jCardReset			dw
	jCardWaitNotBusy		dw
	jCardWaitReady			dw
	jCardWaitDataReq		dw
	jCardCheckError			dw
	jCardLoadLBA			dw
	jCardReadBytesNoDMA		dw
	jCardReadBytesToWRAM		dw
	jCardReadBytesToFPGA		dw
	jCardReadBytesToSDRAM		dw
	jCardReadBytesToSDRAMNoDMA	dw
	jCardReadFile			dw
	jCardWriteFile			dw
	jCardWriteBytesFromWRAM		dw
	jCardWriteBytesFromSDRAM	dw
	jCardLoadModule			dw
	jCardLoadDirClearEntryName	dw
	jCardLoadDir			dw
	jClusterToLBA			dw
	jNextCluster			dw
	jDirPrintDir			dw
	jDirPrintEntry			dw
	jDirGetEntry			dw
	jDirFindEntry			dw
	jNextDir			dw
	jPrintF				dw
	jPrintInt8_noload		dw
	jPrintHex8_noload		dw
	jPrintClearLine			dw
	jPrintClearScreen		dw
	jDoScrolling			dw
	jScrollUp			dw
	jScrollDown			dw
	jLoadNextSectorNum		dw
	jCardLoadFPGA			dw
	jClearFindEntry			dw
	jGameGeniePrint			dw
	jGameGenieClearCode		dw
	jGameGenieDecode		dw
	jGameGenieNextChar		dw
	jGameGeniePrevChar		dw
	jGameGenieClearAll		dw
	jGameGenieWriteCode		dw
	jLoadDevMusic			dw
	jLoadLogo			dw
	jLoadRomVersion			dw
	jMemCheck			dw
	jCopyROMInfo			dw
	jCopyBanks			dw
	jPrintBanks			dw
	jLogScreen			dw
	jSWCHeaderCheck			dw
	jGD3HeaderCheck			dw
	jWaitHblank			dw
	jspcPlay			dw
	jspcStop			dw
	jspcProcess			dw
	jspcSetModuleVolume		dw	; 61 functions, max. = 64
.ENDE



; ************************** Misc. constants ***************************

; Constants (hardcoded up to v2.00-beta1) used by directory printing
; and scrolling routines. Caveat: Changing these values won't be enough,
; HDMA windowing will need to be adjusted accordingly to suppress scrol-
; ling "artifact" lines in the filebrowser caused by the Y indentions.

	.DEFINE maxFiles		$18	; max. number of files to show in the filebrowser (currently 24),
						; used by scrolling and directory printing/navigation routines

	.DEFINE minPrintX		$02	; number of tiles by which to indent horizontally from the left,
						; used by scrolling and print handler routines, macro "SetCursorPos"

	.DEFINE minPrintY		$02	; number of lines by which to indent vertically from the top,
						; also used by macros "ClearLine", "SetCursorPos"

	.DEFINE cursorYmin		$18	; equal to #minPrintY * $08 + $08 because for the cursor sprite,
						; $08 = line 0, $10 = line 1, $18 = line 2, etc.

	.DEFINE cursorYmax		$D0	; scanline 208, equal to #(maxFiles + minPrintY) * $08

	.DEFINE insertStandardTop	$01	; has to be #minPrintY - 1, or $1F if #minPrintY = 0
						; since screen/tilemap size = 32 = $20

	.DEFINE insertStandardBottom	$1A	; entry point for more stuff, probably equal to #maxFiles + minPrintY



.ENUM $00
	kDestNoDMA			db
	kDestWRAM			db
	kDestFPGA			db
	kDestSDRAM			db
	kDestSDRAMNoDMA			db
.ENDE



.ENUM $00
	kSourceNoDMA			db
	kSourceWRAM			db
	kSourceFPGA			db
	kSourceSDRAM			db
	kSourceSDRAMNoDMA		db
.ENDE



; ******************************* Macros *******************************

.MACRO jump
	phx
	ldx #\1
	jsr (jumpTable, x)
	plx
.ENDM



; SetCursorPos  y, x

.MACRO SetCursorPos
	ldx #32*\1+32*minPrintY + \2+minPrintX	; add values of indention constants
	stx Cursor
	stz BGPrintMon				; reset BG monitor value to zero (start on BG2)
.ENDM



.MACRO ClearLine
	clc
	lda.b #\1
	adc.b #minPrintY			; add Y indention

	jump jPrintClearLine
.ENDM



.MACRO PrintString
	ldx #STRlabel\@
	stx strPtr2

	jump jPrintF

	bra END_STRlabel\@

STRlabel\@:
	.DB \1, 0

END_STRlabel\@:

.ENDM



;here's a macro for printing a number (a byte)
;
; ex:  PrintNum $2103 	;print value of reg $2103
;      PrintNum #9	;print 9

.MACRO PrintNum
	lda \1

	jump jPrintInt8_noload
.ENDM



.MACRO PrintHexNum
	lda \1

	jump jPrintHex8_noload
.ENDM



; DMA macro by ManuLöwe (added for v2.01)
;
; Usage: DMA_CH0 mode[8bit], A_bus_bank[8bit], A_bus_src[16bit], B_bus_register[8bit], length[16bit]
; Effect: Transfers data via DMA channel 0.
;
; Expects: A 8 bit, X/Y 16 bit

.MACRO DMA_CH0
	lda #\1					; DMA mode (8 bit)
 	sta $4300
	lda #\4					; B bus register (8 bit)
	sta $4301
	ldx #\3					; data offset (16 bit)
	stx $4302
	lda #\2					; data bank (8 bit)
	sta $4304
	ldx #\5					; data length (16 bit)
	stx $4305

	lda #$01				; initiate DMA transfer
	sta $420B
.ENDM



; DMA (with wait-for-Hblank) macro by ManuLöwe (added for v2.01)
;
; Usage: DMA_WaitHblank mode[8bit], A_bus_bank[8bit], A_bus_src_hi[8bit], A_bus_src_lo[8bit], B_bus_register[8bit], length[16bit variable]
; Effect: Waits for Hblank before transferring data via DMA channel 0.
;
; Expects: A 8 bit, X/Y 16 bit

.MACRO DMA_WaitHblank
	lda #\1					; DMA mode (8 bit)
 	sta $4300
	lda #\5					; B bus register (8 bit)
	sta $4301
	lda #\4					; data offset, low byte (8 bit)
	sta $4302
	lda #\3					; data offset, high byte (8 bit)
	sta $4303
	lda #\2					; data bank (8 bit)
	sta $4304
	ldx \6					; data length (must be a variable)
	stx $4305

	jump jWaitHblank			; wait for Hblank to avoid DMA/HDMA crashes on CPU rev1 consoles

	lda #$01				; initiate DMA transfer
	sta $420B
.ENDM



; Macro FindFile by ManuLöwe (added for v2.00)
;
; Usage (files): FindFile "FILE.EXT"
; Usage (dirs) : FindFile "DIRNAME.   "
; Effect: Puts first cluster of file/directory into sourceCluster.
;
; Restrictions:
; - can only find a single file at a time
; - only searches the POWERPAK directory (for CF modules and other firmware-related files)
; - the filename has to be in strict 8.3 format

.MACRO FindFile
	jump jClearFindEntry

	ldx #$0001				; number of file types to look for (1)
	stx extNum

	ldx #$0000

__LoadFileNameLoop\@:
	lda.w FileName\@, x			; load filename and store it in findEntry
	cmp #'.'
	beq __FileNameComplete\@
	sta findEntry, x
	inx
	cpx #$0008
	bne __LoadFileNameLoop\@

__FileNameComplete\@:
	inx					; skip '.'
	lda.w FileName\@, x			; load extension and store it in extMatchX
	sta extMatch1

	inx
	lda.w FileName\@, x
	sta extMatch2

	inx
	lda.w FileName\@, x
	sta extMatch3

	rep #A_8BIT				; A = 16 bit

	lda baseDirCluster			; "POWERPAK" dir start
	sta sourceCluster

	lda baseDirCluster+2
	sta sourceCluster+2

	sep #A_8BIT				; A = 8 bit

	jump jCardLoadDir			; "POWERPAK" dir

	jump jDirFindEntry			; get first cluster of file to look for

	rep #A_8BIT

	lda tempEntry.tempCluster
	sta sourceCluster

	lda tempEntry.tempCluster+2
	sta sourceCluster+2

	sep #A_8BIT

	bra END_FindFile\@

FileName\@:
	.DB \1

END_FindFile\@:

.ENDM



; Macro InitFileBrowser by ManuLöwe (added for v2.01)
;
; Usage: InitFileBrowser
; Effect: Loads root directory into SDRAM buffer, and prints it to the screen.

.MACRO InitFileBrowser
	rep #A_8BIT				; A = 16 bit

	lda rootDirCluster
	sta sourceCluster

	lda rootDirCluster+2
	sta sourceCluster+2

	sep #A_8BIT				; A = 8 bit

	lda #'S'				; use SDRAM buffer
	sta bufferType

	jump jCardLoadDir			; reminder: bufferType is reset upon rts

	lda filesInDir+1			; check if root dir contains files beside the "POWERPAK" folder
	bne __RootDirNotEmpty\@

	lda filesInDir
	bne __RootDirNotEmpty\@

	SetCursorPos 11, 7
	PrintString "Root directory is empty."

	SetCursorPos 12, 4
	PrintString " Please copy games to your CF card!"

	jump jForever

__RootDirNotEmpty\@:

	jump jDirPrintDir			; this includes a PrintClearScreen / SetCursorPos 0, 0

.ENDM



; Macro IncrementSectorNum by ManuLöwe (added for v2.02)
;
; Usage: IncrementSectorNum
; Effect: Increments source sector. Used by 4 routines (3 in main code, 1 in SM module).

.MACRO IncrementSectorNum

.ACCU 8
.INDEX 16

	pei (destLo)				; push destLo/destHi onto stack

	jump jLoadNextSectorNum

	rep #A_8BIT				; A = 16 bit

	pla					; pull destLo/destHi from stack
	sta destLo

; check for last sector
; FAT32 last cluster = 0x0FFFFFFF
; FAT16 last cluster = 0x0000FFFF

	lda fat32Enabled			; check for FAT32
	and #$0001
	bne __LastClusterMaskFAT32\@

	stz temp+2				; if FAT16, high word = $0000
	bra __LastClusterMaskDone\@

__LastClusterMaskFAT32\@:
	lda #$0FFF				; if FAT32, high word = $0FFF
	sta temp+2

__LastClusterMaskDone\@:			; if cluster = last cluster, jump to last entry found
	lda sourceCluster
	cmp #$FFFF				; low word = $FFFF (FAT16/32)
	bne __NextSector\@

	lda sourceCluster+2
	cmp temp+2
	bne __NextSector\@

	sep #A_8BIT				; A = 8 bit

	bra _f					; last cluster (intentional forward jump, "beyond" of the macro)

__NextSector\@:
	sep #A_8BIT				; A = 8 bit

.ENDM



; Macro DpadUpHold2Scroll by ManuLöwe (added for v2.02)
;
; Usage: DpadUpHold2Scroll
; Effect: Checks if d-pad is held up, and scrolls up after a short delay (used in the filebrowser only)

.MACRO DpadUpHold2Scroll

.ACCU 8
.INDEX 16

	lda Joy1Press+1
	and #%00001000
	beq __UpCheckDone\@

__UpPressed\@:
	lda cursorYCounter
	bne __UpCheckDone\@
	lda scrollYCounter
	bne __UpCheckDone\@

	lda #$08
	sta speedScroll
	lda #$01
	sta speedCounter

	jump jScrollUp

	lda Joy1Old+1
	and #%00001000
	bne __UpHeld\@

	ldx #$000E				; 14 frames

__UpLongDelay\@:
	wai
	lda Joy1+1
	and #%00001000
	beq __UpCheckDone\@
	dex
	bne __UpLongDelay\@

	bra __UpPressed\@

__UpHeld\@:
	ldx #$0002				; 2 frames

__UpShortDelay\@:
	wai
	lda Joy1+1
	and #%00001000
	beq __UpCheckDone\@
	dex
	bne __UpShortDelay\@

	bra __UpPressed\@

__UpCheckDone\@:

.ENDM



; Macro DpadDownHold2Scroll by ManuLöwe (added for v2.02)
;
; Usage: DpadDownHold2Scroll
; Effect: Checks if d-pad is held down, and scrolls down after a short delay (used in the filebrowser only)

.MACRO DpadDownHold2Scroll

.ACCU 8
.INDEX 16

	lda Joy1Press+1
	and #%00000100
	beq __DownCheckDone\@

__DownPressed\@:
	lda cursorYCounter
	bne __DownCheckDone\@
	lda scrollYCounter
	bne __DownCheckDone\@

	lda #$08
	sta speedScroll
	lda #$01
	sta speedCounter

	jump jScrollDown

	lda Joy1Old+1
	and #%00000100
	bne __DownHeld\@

	ldx #$000E				; 14 frames

__DownLongDelay\@:
	wai
	lda Joy1+1
	and #%00000100
	beq __DownCheckDone\@
	dex
	bne __DownLongDelay\@

	bra __DownPressed\@

__DownHeld\@:
	ldx #$0002				; 2 frames

__DownShortDelay\@:
	wai
	lda Joy1+1
	and #%00000100
	beq __DownCheckDone\@
	dex
	bne __DownShortDelay\@

	bra __DownPressed\@

__DownCheckDone\@:

.ENDM



; Macro DpadLeftScrollUp by ManuLöwe (added for v2.02)
;
; Usage: DpadLeftScrollUp
; Effect: Checks if d-pad is pressed left, and scrolls up very fast (used in the filebrowser only)

.MACRO DpadLeftScrollUp

.ACCU 8
.INDEX 16

	lda Joy1Press+1
	and #%00000010
	beq __LeftCheckDone\@

	lda cursorYCounter
	bne __LeftCheckDone\@
	lda scrollYCounter
	bne __LeftCheckDone\@

	lda #$08
;	lda #$04
	sta speedScroll

	lda #$01
;	lda #$02
	sta speedCounter

	jump jScrollUp

__LeftCheckDone\@:

.ENDM



; Macro DpadRightScrollDown by ManuLöwe (added for v2.02)
;
; Usage: DpadRightScrollDown
; Effect: Checks if d-pad is pressed right, and scrolls down very fast (used in the filebrowser only)

.MACRO DpadRightScrollDown

.ACCU 8
.INDEX 16

	lda Joy1Press+1
	and #%00000001
	beq __RightCheckDone\@

	lda cursorYCounter
	bne __RightCheckDone\@
	lda scrollYCounter
	bne __RightCheckDone\@

	lda #$08
;	lda #$04
	sta speedScroll

	lda #$01
;	lda #$02
	sta speedCounter

	jump jScrollDown

__RightCheckDone\@:

.ENDM



; SNESMod macro: increment memory pointer by 2

.MACRO incptr
	iny
	iny
	bmi __no_overflow\@

	inc spc_ptr+2
	ldy #$8000

__no_overflow\@:

.ENDM



; SNESMod macro: SPC700 sync (port 0)

.MACRO WaitForAPUIO0

__waitForAPUIO0\@:
	cmp APUIO0
	bne __waitForAPUIO0\@

.ENDM



; SNESMod macro: SPC700 sync (port 1)

.MACRO WaitForAPUIO1

__waitForAPUIO1\@:
	cmp APUIO1
	bne __waitForAPUIO1\@

.ENDM



; ****************************** .STRUCTs ******************************

; These are for stuff that used to be hardcoded in v1.0X.

.STRUCT temp_entry
	tempName		dsb 123
	tempFlags		db		; '$7B' / rrrrrryx [r = Reserved, y = Hidden, x = Directory]
	tempCluster		dsb 4		; '$7C'-'$7F'
.ENDST



.STRUCT game_name
	gName			dsb 124
	gCluster		dsb 4		; '$7C'-'$7F'
.ENDST



.STRUCT save_name
	sName			dsb 124
	sCluster		dsb 4		; '$7C'-'$7F'
.ENDST



.STRUCT game_genie
	CharOffset		dw		; GG char offset, used when printing codes
	Codes			dsb 40		; five GameGenie codes, each 8 bytes long
	RealHex			dsb 8		; real hex equivalent of GG hex characters
	Decoded			dsb 40		; GG decoding scratchpad & decoded codes
	Scratchpad		dsb 30		; more GG scratchpad space
.ENDST



; *********************** Direct page variables ************************

.ENUM $00
	strPtr			dw
	strPtr2			dw
	loaderState		db
	errorCode		dw
	fat32Enabled		db

	sourceBytes		db
	source256		db
	sourceBytes16		dw

	sourceLo		db
	sourceHi		db
	sourceBank		db
	sourceType		db
						; 16 bytes and counting
	sourceEntryLo		db
	sourceEntryHi		db
	sourceEntryBank		db

	destEntryLo		db
	destEntryHi		db
	destEntryBank		db

	destLo			db
	destHi			db
	destBank		db
	destType		db

	filesInDir		dw
	temp			dsb 8
	selectedEntry		dw
	lfnFound		db
						; 39 bytes and counting
	sourceSector		dsb 4
	sourceCluster		dsb 4
	partitionLBABegin	dsb 4
	clusterBeginLBA    	dsb 4
	sectorsPerCluster	db
	reservedSectors		dw
	sectorsPerFat		dsb 4
	fatBeginLBA		dsb 4
	fat16RootSectors	db
	rootDirCluster		dsb 4
	baseDirCluster		dsb 4		; "baseDir" = "POWERPAK" directory
	sectorCounter		db
	Reserved01		db		; sectorCounter used to be a word (can be re-used / don't remove!)
						; 77 bytes and counting
	Cursor			dw

	Reserved02		dsb 2		; used to be the frame counter (can be re-used / don't remove!)

	Joy1			dw		; Current button state of joypad1, bit0=0 if it is a valid joypad
	Joy2			dw		; same thing for all pads...

	Joy1Press		dw		; Holds joypad1 keys that are pressed and have been
						; pressed since clearing this mem location
	Joy2Press		dw		; same thing for all pads...
						; X Y TL  TR . . . .
						; A B sel st U D L R
	Joy1New			dw
	Joy2New			dw

	Joy1Old			dw
	Joy2Old			dw
						; 97 bytes and counting
	findEntry		dsb 10

	extMatch1		dsb 11		; number of bytes = number of file types to search for at once
	extMatch2		dsb 11
	extMatch3		dsb 11
						; 140 bytes and counting
	scrollY			db
	scrollYCounter		db
	scrollYUp		db
	scrollYDown		db

	cursorX			db
	cursorY			db
	cursorYCounter		db
	cursorYUp		db
	cursorYDown		db

	speedCounter		db
	speedScroll		db

	insertTop		db
	insertBottom		db
						; 153 bytes and counting
	saveSize		db
	useBattery		db

	gameSize		dw
	gameResetVector		dw
	gameROMMapper		db
	gameROMType		db
	gameROMSize		db
	gameBanks		dsb 32
	gameROMMbits		db
	sramSizeByte		db
						; 196 bytes and counting
	ggcode			dsb 4

	nextModule		db		; holds S?.MAP value (where ? = module), or $00 (don't leave current module),
						; or #'S' = don't skip hidden files (this is checked in CardLoadDir)

	bankCounter		db

	dontUseDMA		db

	bankOffset		dw

	headerType		db		; holds ROM header type ($01 = SWC, $02 = GD3, $FF = unknown)
	partitionIndex		dw
						; 208 bytes and counting
; added for v1.04
	fixheader		db
	tempheader		db
	audioPC			dsb 2		; all audioXXX variables re-used for blargg's SPC player
	audioA			db
	audioX			db
	audioY			db
	audioPSW		db
	audioSP			db
	spcTimer		dsb 4

	lastCluster		dsb 4

; added for CardReadGameFill (v1.05?)
	headerCounter		dsb 2

; added for v2.00
	configDMA		db		; user config variables
	configLogo		db
	configBGdesign		db

	BGPrintMon		db		; keep track of BG we're printing on: $00 = BG2 (start), $01 = BG1
	extNum			dw		; number of file extensions to look for (16 bit for X/Y register use)
	disableHDMA		db		; "emergency" HDMA off, $00 = false (checked during Vblank)

; added for v2.01
	bufferType		db		; holds buffer destination: #$00 = WRAM ("reset"), #'S' = SDRAM ("set")
						; Buffer selection is implemented as follows:
						; Variable is reset on start-up, checked & reset in CardLoadDir,
						; set & reset in DirPrintEntry, checked (not modified) in DirGetEntry,
						; set in InitFileBrowser macro. (Note that supporting both buffers is
						; mandatory because FPGA programming -- and thus, SDRAM unlocking --
						; does NOT occur until SI.MAP is loaded.)

; added for v2.02
	spc_ptr			dsb 3		; SNESMod variables (up to, and including, "digi_src2")
	spc_v			db
	spc_bank		db

	spc1			dsb 2
	spc2			dsb 2

	spc_fread		db
	spc_fwrite		db

	spc_pr			dsb 4		; port record [for interruption]

	SoundTable		dsb 3
.ENDE						; 253 of 256 bytes used



.ENUM $1C					; "temp" variable, reused for loading music
	digi_src		dsb 3
	digi_src2		dsb 3
.ENDE



; *********** $0100-$01FF: Reserved for another direct page ************



; ******************* Variables in lower 8K of WRAM ********************

.ENUM $0200
	codeBuffer	dsb 5120		; 5KB code for modules
	sectorBuffer1	dsb 512
	tempEntry	INSTANCEOF temp_entry	; 128 bytes
	gameName	INSTANCEOF game_name	; ditto
	saveName	INSTANCEOF save_name	; ditto
	SpriteBuf1	dsb 512
	SpriteBuf2	dsb 32
	GameGenie	INSTANCEOF game_genie	; 120 bytes
	jumpTable	dsb 128

						; more SNESMod variables (added for v2.02)
	spc_fifo	dsb 256			; 128-byte command fifo
	spc_sfx_next	db
	spc_q		db

	digi_init	db
	digi_pitch	db
	digi_vp		db
	digi_remain	dsb 2
	digi_active	db
	digi_copyrate	db
.ENDE						; $1BA1 (7073) bytes + $200 = $1DA1 (7585) bytes used
						; reminder: stack resides at $1FFF



; ********************** Variables in upper WRAM ***********************

.ENUM $7E8000					; used by the SPC RAM buffer
	spcRAM1stBytes	dsb 2
	spcFLGReg	db
	spcKONReg	db
	spcDSPRegAddr	db
	spcCONTROLReg	db
	spcIOPorts	dsb 4
	spcIPLBuffer	dsb 238
	spcRegBuffer	dsb 128
	spcF8Buffer	dsb 264
.ENDE



.ENUM $7EEFFF
	LogBuffer	dsb 2048		; needed for writing error messages to LOG.TXT
	TxtBuf2bpp	dsb 1024		; moved here from the .ENUM $0200 section
	TxtBuf4bpp	dsb 1024		; added for v2.00 (hi-res text rendering)
.ENDE



.ENUM $7F0000
	dirBuffer	dsb 65536		; 64KB (512 * 128 bytes) for directory buffering
.ENDE

; **********************************************************************
