;==========================================================================================
;
;   UNOFFICIAL SNES POWERPAK FIRMWARE V2.01 (CODENAME: "SIMBA")
;   (c) 2012/2013 by ManuLöwe (http://www.manuloewe.de/)
;
;	*** SNES INITIALIZATION ***
;	Code in this file based on v1.0X code written by:
;	- Neviksti, (c) 2002
;
;==========================================================================================



InitSNES:					; A and X/Y are 16 bit!
	PHK					; set Data Bank = Program Bank
	PLB

	LDA #$0000				; set Direct Page = $0000
	TCD					; transfer Accumulator to Direct Register

	LDX $1FFD				; we clear all the mem at one point ...
	STX $4372				; so save the return address in a place that won't get overwritten
	LDX $1FFF
	STX $4374

	SEP #A_8BIT				; mem/A = 8 bit

	LDA #$8F
	STA $2100				; turn screen off for now, set brightness to normal

	LDX #$2101

_Loop00:					; regs $2101-$210C
	STZ $00,X				; set sprite, character, tile sizes to lowest, and set addresses to $0000
	INX
	CPX #$210D
	BNE _Loop00

_Loop01:					; regs $210D-$2114
	STZ $00,X				; set all BG scroll values to $0000
	STZ $00,X
	INX
	CPX #$2115
	BNE _Loop01

;	LDA #$80				; reg $2115 - VRAM transfer mode, is initialized later
;	STA $2115

;	STZ $2116				; regs $2117-$2117 - VRAM address, is initialized later
;	STZ $2117

			;reg $2118-$2119
			;VRAM write register... don't need to initialize

	STZ $211A				; clear Mode7 setting

	LDX #$211B

_Loop02:					; regs $211B-$2120
	STZ $00,X				; clear out the Mode7 matrix values
	STZ $00,X
	INX
	CPX #$2121
	BNE _Loop02

			;reg $2121 - Color address, doesn't need initializing
			;reg $2122 - Color data, is initialized later

	LDX #$2123

_Loop03:					; regs $2123-$2133
	STZ $00,X				; turn off windows, main screens, sub screens, color addition,
	INX					; fixed color = $00, no super-impose (external synchronization),
	CPX #$2134				; no interlaced mode, normal resolution
	BNE _Loop03

			;regs $2134-$2136 - multiplication result, no initialization needed
			;reg $2137 - software H/V latch, no initialization needed
			;reg $2138 - Sprite data read, no initialization needed
			;regs $2139-$213A - VRAM data read, no initialization needed
			;reg $213B - Color RAM data read, no initialization needed
			;regs $213C-$213D - H/V latched data read, no initialization needed

	STZ $213E				; reg $213E - might not be necessary, but selects PPU master/slave mode

			;reg $213F - PPU status flag, no initialization needed

			;reg $2140-$2143 - APU communication regs, no initialization required

			;reg $2180 - read/write WRAM register, no initialization required
			;reg $2181-$2183 - WRAM address, no initialization required

			;reg $4016-$4017 - serial JoyPad read registers, no need to initialize


	STZ $4200				; reg $4200 - disable timers, NMI, and auto-joyread

	LDA #$FF
	STA $4201				; reg $4201 - programmable I/O write port, initalize to allow reading at in-port

			;regs $4202-$4203  - multiplication registers, no initialization required
			;regs $4204-$4206  - division registers, no initialization required

			;regs $4207-$4208  - Horizontal-IRQ timer setting, since we disabled this, it is OK to not init
			;regs $4209-$420A  - Vertical-IRQ timer setting, since we disabled this, it is OK to not init

	STZ $420B				; reg $420B - turn off all general DMA channels
	STZ $420C				; reg $420C - turn off all H-DMA channels

	STZ $420D				; reg $420D - ROM access time to slow (2.68Mhz)

	LDA $4210				; reg $4210 - NMI status, reading resets

			;reg $4211 - IRQ status, no need to initialize
			;reg $4212 - H/V blank and JoyRead status, no need to initialize
			;reg $4213 - programmable I/O inport, no need to initialize

			;reg $4214-$4215 - divide results, no need to initialize
			;reg $4216-$4217 - multiplication or remainder results, no need to initialize

			;regs $4218-$421f - JoyPad read registers, no need to initialize

			;regs $4300-$437F
			;no need to intialize because DMA was disabled above
			;also, we're not sure what all of the registers do, so it is better to leave them at
			;their reset state value

; ******** clear VRAM ********

	lda #$80				; VRAM address increment mode: increment address by one word
	sta $2115				; after accessing the high byte ($2119)

	ldx #$0000				; reset VRAM address
	stx $2116

	DMA_CH0 $09, :Zeroes, Zeroes, $18, $0000	; $0000 = 65536 bytes

; ******** clear CGRAM *******

	stz $2121				; reset CGRAM address

	DMA_CH0 $08, :Zeroes, Zeroes, $22, $0200	; 512 bytes

; ******** clear OAM *********

	ldx #$0000				; reset OAM address
	stx $2102

	DMA_CH0 $08, :Zeroes, Zeroes, $04, $0220	; 512+32 bytes (low/high OAM table)

; ******** clear WRAM ********

	stz $2181				; reset WRAM address
	stz $2182
	stz $2183

	DMA_CH0 $08, :Zeroes, Zeroes, $80, $0000	; 65536 bytes (lower 64K of WRAM)

	lda #$01

	pha					; /!\ Let's play around with the stack a bit before the next DMA,
	pha					; /!\ this might help suppress horizontal flickering on startup/reset
	pla					; /!\ (or not at all), but at least it's required for version string
	pla					; /!\ offset consistency, so don't remove! :p

	sta $420B				; re-initiate DMA transfer for the upper 64K of WRAM

	PHK					; make sure Data Bank = Program Bank
	PLB

	CLI					; enable interrupts again

	LDX $4372				; get our return address...
	STX $1FFD
	LDA $4374
	STA $1FFF
RTL



Zeroes:
	.dw $0000
