;=================================================================
; [INITSYS.INC] -- Probably nice if you'd like to use the SNES..
;
; Note: Do not call `SNES_INITIALIZE0' directly!
;       Just run the `INIT_SNES'-macro!  This macro
;       doesn't return which means that `SNES_INITIALIZE0'
;       will be executed *after* `INIT_SNES'.
;=================================================================


.MACRO INIT_SNES
    sei                         ; disable interrupts
    clc                         ; switch to native mode
    xce
    rep   #$38                  ; A/mem=X/Y=16bits, decimal mode = off
    ldx   #$1FFF
    txs
    jsl   $008000
    sep   #$20                  ; A/mem=8bits
.ENDM


;=================================================================


.BANK 0 SLOT 0
.ORG HEADER_OFF
.SECTION "snesinit0c" FORCE

SNES_INITIALIZE0:
    phk                         ; Data bank = program bank
    plb

    sep #$20                    ; We'll start off with cleaning stuff
    lda #$80                    ; so that this game gets a chance to
    sta $2100                   ; actually really run on the real snes :)
    stz $2101
    stz $2102
    stz $2103
    stz $2104
    stz $2105
    stz $2106
    stz $2107
    stz $2108
    stz $2109
    stz $210a
    stz $210b
    stz $210c
    stz $210d
    stz $210d
    stz $210e
    stz $210e
    stz $210f
    stz $210f
    stz $2110
    stz $2110
    stz $2111
    stz $2111
    stz $2112
    stz $2112
    stz $2113
    stz $2113
    stz $2114
    stz $2114
    lda #$80
    sta $2115
    stz $2116
    stz $2117
    stz $211a
    stz $211b
    lda #$01
    sta $211b
    stz $211c
    stz $211c
    stz $211d
    stz $211d
    stz $211e
    lda #$01
    sta $211e
    stz $211f
    stz $211f
    stz $2120
    stz $2120
    stz $2121
    stz $2123
    stz $2124
    stz $2125
    stz $2126
    stz $2127
    stz $2128
    stz $2129
    stz $212a
    stz $212b
    stz $212c
    stz $212d
    stz $212e
    stz $212f
    stz $4200
    lda #$ff
    sta $4201
    stz $4202
    stz $4203
    stz $4204
    stz $4205
    stz $4206
    stz $4207
    stz $4208
    stz $4209
    stz $420a
    stz $420b
    stz $420c
    stz $420d

    ;=============================================
    ;=============================================
    ;=============================================

    lda   #$0000
    tcd
    ldx   $1FFD                 ; We'll clear all mem at a certain point ..
    stx   $4372                 ; ..so save the return address in a place
                                ; that won't get overwritten!
    ldx   $1FFF
    stx   $4374
    sep   #$20                  ; A/mem=8bits
    lda   #$8F
    sta   $2100                 ; Disable screen, full brightness
    ldx   #$2101
_INISN_00:                      ; ($2101-$210C) spr/chr etc.
    stz   $00, X
    inx
    cpx   #$210D
    bne   _INISN_00
_INISN_01:                      ; ($210D-$2114) BG scroll values
    stz   $00, X
    stz   $00, X
    inx
    cpx   #$2115
    bne   _INISN_01
    lda   #$80
    sta   $2115                 ; VRAM transfer mode = word, inc by one
    stz   $2116
    stz   $2117                 ; Clear VRAM settings
    stz   $211A                 ; Clear mode#7 setting
    ldx   #$211B
_INISN_02:                      ; ($211B-$2120) mode#7 matrix values
    stz   $00, X
    stz   $00, X
    inx
    cpx   #$2121
    bne   _INISN_02
    ldx   #$2123
_INISN_03:                      ; ($2123-$2133)
    stz   $00, X
    inx
    cpx   #$2134
    bne   _INISN_03
    
    ;;; BG#2 translucency ;;;
    ;lda   #$01
    ;sta   $212D                ; Set BG#1 as subscreen
    ;lda   #$02                 ; Turn on always color-addition/subtraction
    ;sta   $2130                ; for subscreen
    ;lda   #$52                 ; Color addition, 1/2 average mode and
    ;sta   $2131                ; enable addition to main BG#2 and BG#5
    ;;;;

    stz   $213E                 ; PPU master/slave mode
    stz   $4200                 ; Disable timers, NMI and auto-joyread
    lda   #$FF
    sta   $4201                 ; Programmable I/O write port..
                                ; ..Allow reading at in-port
    stz   $420B                 ; Disable all general DMA channels
    stz   $420C                 ; Disable all HMA channels
    stz   $420D                 ; ROM access time to slow (2.68 MHz)
    lda   $4210                 ; NMI status, reading resets

    ; Reset VRAM
    pha
    phx
    php
    rep   #$30                  ; A/mem=8bits, X/Y=16bits
    sep   #$20
    lda   #$80
    sta   $2115                 ; Set VRAM port to word access
    ldx   #$1809
    stx   $4300                 ; DMA mode=fixed source, $2118 & $2119=word
    ldx   #$0000
    stx   $2116                 ; VRAM port address = $0000
    stx   $0000                 ; $00:0000 to $0000 (assumes scratchpad ram)
    stx   $4302                 ; Set source address to $xx:0000
    lda   #$00
    sta   $4304                 ; Source bank = $00
    ldx   #$FFFF
    stx   $4305                 ; Set transfer size to $FFFF (65535)
    lda   #$01
    sta   $420B                 ; Initiate transfer
    stz   $2119                 ; Clear last byte of VRAM (#65536)
    plp
    plx
    pla

    ; Clear palette
    phx
    php
    rep   #$30                  ; A/mem=8bits, X/Y=16bits
    sep   #$20
    stz   $2121
    ldx   #$0100
_INISN_04:
    stz   $2122
    dex
    bne   _INISN_04
    plp
    plx

    ; Clear sprite tables
    stz   $2102
    stz   $2103
    ldx   #$0080                ; 128 tiles
    lda   #$F0
_INISN_05:
    sta   $2104                 ; X = 240
    sta   $2104                 ; Y = 240
    stz   $2104                 ; CHR = $00
    stz   $2104                 ; No priority and no flips
    dex
    bne   _INISN_05
    ldx   #$0020
_INISN_06:
    stz   $2104                 ; Size bit=0, x MSB=0
    dex
    bne   _INISN_06

    ; Clear WRAM
    stz   $2181                 ; Set WRAM address to $000000
    stz   $2182
    stz   $2183
    ldx   #$8008
    stx   $4300                 ; DMA mode=fixed source, $2180=byte
    ldx   #$00
    stx   $4302                 ; Set source offset
    lda   #$00
    sta   $4304                 ; Set source bank
    ldx   #$0000
    stx   $4305                 ; Transfer size = 64k
    lda   #$01
    sta   $420B                 ; Initiate transfer
    lda   #$01                  ; Set the next 64k
    sta   $420B                 ; Initiate transfer
    phk
    plb                         ; Assure that data bank = program bank
    cli                         ; Enable interrupts
    ldx   $4372                 ; Retrieve our return address
    stx   $1FFD
    lda   $4374
    sta   $1FFF
    rtl

.ENDS
