Initial import.

This commit is contained in:
Colin McMillen 2015-05-22 12:49:40 -04:00
parent 32de60678c
commit 424ddce8fb
3 changed files with 537 additions and 0 deletions

260
InitSNES.asm Normal file
View File

@ -0,0 +1,260 @@
;------------------------------------------------------------------------
;- Standard SNES initialization routine, by Neviksti
;------------------------------------------------------------------------
;----------------------------------------------------------------------------
; InitSNES -- my "standard" initialization of SNES memory and registers
;----------------------------------------------------------------------------
.MACRO InitSNES
sei ;disable interrupts
clc ;switch to native mode
xce
REP #$38 ; mem/A = 16 bit, X/Y = 16 bit
;decimal mode off
LDX #$1FFF ;Setup the stack
TXS ;Transfer Index X to Stack Pointer Register
;do the rest of the initialization in a routine
JSL $008000
SEP #$20 ; mem/A = 8 bit
.ENDM
;----------------------------------------------------------------------------
.BANK 0 SLOT 0
.ORG 0
.SECTION "InitializeSNESCode" FORCE
InitializeSNES:
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 #$20 ; mem/A = 8 bit
REP #$10
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
STA $2115 ; Initialize VRAM transfer mode to word-access, increment by 1
STZ $2116 ;regs $2117-$2117
STZ $2117 ;VRAM address = $0000
;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 initilaizing
;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 necesary, 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-MA 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
JSR ClearVRAM ;Reset VRAM
JSR ClearPalette ;Reset colors
;**** clear Sprite tables ********
STZ $2102 ;sprites initialized to be off the screen, palette 0, character 0
STZ $2103
LDX #$0080
LDA #$F0
_Loop08:
STA $2104 ;set X = 240
STA $2104 ;set Y = 240
STZ $2104 ;set character = $00
STZ $2104 ;set priority=0, no flips
DEX
BNE _Loop08
LDX #$0020
_Loop09:
STZ $2104 ;set size bit=0, x MSB = 0
DEX
BNE _Loop09
;**** clear WRAM ********
STZ $2181 ;set WRAM address to $000000
STZ $2182
STZ $2183
LDX #$8008
STX $4300 ;Set DMA mode to fixed source, BYTE to $2180
LDX #wram_fill_byte
STX $4302 ;Set source offset
LDA #:wram_fill_byte
STA $4304 ;Set source bank
LDX #$0000
STX $4305 ;Set transfer size to 64k bytes
LDA #$01
STA $420B ;Initiate transfer
LDA #$01 ;now set the next 64k bytes
STA $420B ;Initiate transfer
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
wram_fill_byte:
.db $00
;----------------------------------------------------------------------------
; ClearVRAM -- Sets every byte of VRAM to zero
; In: None
; Out: None
; Modifies: flags
;----------------------------------------------------------------------------
ClearVRAM:
pha
phx
php
REP #$30 ; mem/A = 8 bit, X/Y = 16 bit
SEP #$20
LDA #$80
STA $2115 ;Set VRAM port to word access
LDX #$1809
STX $4300 ;Set DMA mode to fixed source, WORD to $2118/9
LDX #$0000
STX $2116 ;Set VRAM port address to $0000
STX $0000 ;Set $00:0000 to $0000 (assumes scratchpad ram)
STX $4302 ;Set source address to $xx:0000
LDA #$00
STA $4304 ;Set source bank to $00
LDX #$FFFF
STX $4305 ;Set transfer size to 64k-1 bytes
LDA #$01
STA $420B ;Initiate transfer
STZ $2119 ;clear the last byte of the VRAM
plp
plx
pla
RTS
;----------------------------------------------------------------------------
; ClearPalette -- Reset all palette colors to zero
; In: None
; Out: None
; Modifies: flags
;----------------------------------------------------------------------------
ClearPalette:
PHX
PHP
REP #$30 ; mem/A = 8 bit, X/Y = 16 bit
SEP #$20
STZ $2121
LDX #$0100
ClearPaletteLoop:
STZ $2122
STZ $2122
DEX
BNE ClearPaletteLoop
PLP
PLX
RTS
.ENDS

61
header.inc Normal file
View File

@ -0,0 +1,61 @@
;------------------------------ Header File ---------------------------------
; This is basically a combo of MarctheMER's and Neviksti's header files
; Perhaps reading their's will also help your understanding of the header,
; but I believe this will be the simplest method of defining your header,
; as Marc's doesn't provide a full explanation, and Neviksti's can be
; a bit more difficult for beginners (using the WLA directives is easier).
;----------------------------------------------------------------------------
;==LoRom== ; We'll get to HiRom some other time.
.MEMORYMAP ; Begin describing the system architecture.
SLOTSIZE $8000 ; The slot is $8000 bytes in size. More details on slots later.
DEFAULTSLOT 0 ; There's only 1 slot in SNES, there are more in other consoles.
SLOT 0 $8000 ; Define's Slot 0's starting address.
.ENDME ; End MemoryMap definition
.ROMBANKSIZE $8000 ; Every ROM bank is 32 KBytes in size
.ROMBANKS 8 ; 2 Mbits - Tell WLA we want to use 8 ROM Banks
.SNESHEADER
ID "SNES" ; 1-4 letter string, just leave it as "SNES"
NAME "PEW PEW " ; Program Title - can't be over 21 bytes,
; "123456789012345678901" ; use spaces for unused bytes of the name.
SLOWROM
LOROM
CARTRIDGETYPE $00 ; $00 = ROM only, see WLA documentation for others
ROMSIZE $08 ; $08 = 2 Mbits, see WLA doc for more..
SRAMSIZE $00 ; No SRAM see WLA doc for more..
COUNTRY $01 ; $01 = U.S. $00 = Japan, that's all I know
LICENSEECODE $00 ; Just use $00
VERSION $00 ; $00 = 1.00, $01 = 1.01, etc.
.ENDSNES
.SNESNATIVEVECTOR ; Define Native Mode interrupt vector table
COP EmptyHandler
BRK EmptyHandler
ABORT EmptyHandler
NMI VBlankHandler
IRQ EmptyHandler
.ENDNATIVEVECTOR
.SNESEMUVECTOR ; Define Emulation Mode interrupt vector table
COP EmptyHandler
ABORT EmptyHandler
NMI EmptyHandler
RESET Start
IRQBRK EmptyHandler
.ENDEMUVECTOR
.BANK 0 SLOT 0 ; Defines the ROM bank and the slot it is inserted in memory.
.ORG 0 ; .ORG 0 is really $8000, because the slot starts at $8000
.SECTION "EmptyVectors" SEMIFREE
EmptyHandler:
rti
.ENDS
.EMPTYFILL $00

216
pewpew.asm Normal file
View File

@ -0,0 +1,216 @@
.INCLUDE "header.inc"
.INCLUDE "InitSNES.asm"
; Memory layout:
; 00-0F: scratch space for functions.
; 10-13: controller state.
; 14-17: 32-bit counter of vblanks.
; 20-22: [rgb] color values to use for background color.
;========================
; Start
;========================
.BANK 0 SLOT 0
.ORG 0
.SECTION "MainCode"
Start:
InitSNES ; Initialize SNES.
; Set the background color.
; $2121 is the color palette selection register [CGADD].
; Storing 0 because that's the SNES background color.
stz $2121
; Turn on the screen.
; $2100: Screen display register [INIDISP]
;
; Format: x000bbbb
; x: 0 = screen on, 1 = screen off, bbbb: Brightness ($0-$F)
lda #%00001111
sta $2100
; Enable NMI interrupt & joypad.
; Register $4200: Counter enable [NMITIMEN]
; n-vh---j n: NMI interrupt enable v: vertical counter enable
; h: horizontal counter enable j: joypad enable
lda #$81
sta $4200
; Store zeroes to the controller status registers.
; TODO(mcmillen): is this needed?
stz $4218
stz $4219
; Write something recognizable into our scratch space.
jsr FillScratch
Loop:
wai
jmp Loop
VBlankHandler:
jsr VBlankCounter ; DEBUG
jsr JoypadHandler
jsr SetBackgroundColor
; jsr FillScratch ; DEBUG
rti
VBlankCounter:
; Keeps a counter of how many VBlanks we've done.
inc $14
lda $14
cmp #$00
bne VBlankCounterDone
inc $15
lda $15
cmp #$00
bne VBlankCounterDone
inc $16
lda $16
cmp #$00
bne VBlankCounterDone
inc $17
VBlankCounterDone:
rts
JoypadHandler:
; $4218: Joypad #1 status [JOY1L]
; Format: AXLR0000
; $4219: Joypad #1 status [JOY1H]
; Format: BYsSudlr (s=select, S=start, udlr = joypad)
; Joypad #2 status is $421A [JOY2L] and $421B [JOY2H].
jsr JoypadDebug ; DEBUG
; TODO(mcmillen): read joypad from local memory instead of registers?
JoypadUp:
lda $4219
and #$08 ; Up
cmp #$08
bne JoypadDown ; Button not pressed.
lda $20
cmp #31
beq JoypadDown ; Value saturated.
inc $20
JoypadDown:
lda $4219
and #$04 ; Down
cmp #$04
bne JoypadLeft ; Button not pressed.
lda $20
cmp #0
beq JoypadLeft ; Value saturated.
dec $20
JoypadLeft:
lda $4219
and #$02 ; Left
cmp #$02
bne JoypadRight ; Button not pressed.
lda $22
cmp #0
beq JoypadRight ; Value saturated.
dec $22
JoypadRight:
lda $4219
and #$01
cmp #$01 ; Right
bne JoypadB ; Button not pressed.
lda $22
cmp #31
beq JoypadB ; Value saturated.
inc $22
JoypadB:
lda $4219
and #$80 ; B
cmp #$80
bne JoypadY ; Button not pressed.
lda $21
cmp #31
beq JoypadY ; Value saturated.
inc $21
JoypadY:
lda $4219
and #$40 ; Y
cmp #$40
bne JoypadDone ; Button not pressed.
lda $21
cmp #0
beq JoypadDone
dec $21
JoypadDone:
rts
JoypadDebug:
; Load joypad registers into RAM for easier inspection.
lda $4218
sta $10
lda $4219
sta $11
lda $421A
sta $12
lda $421B
sta $13
rts
SetBackgroundColor:
; $20 $21 $22 are R, G, B, as appropriate.
; The color format is 15-bit: [0bbbbbgg][gggrrrrr]
; We store the low-order byte first.
lda $20 ; RED
sta $00
lda $22 ; BLUE
asl
asl
sta $01
lda $21 ; GREEN.
; First store the high-order bits of green into $01.
lsr
lsr
lsr
ora $01
pha ; push 1
; Now store the low-order bits into $00.
lda $21
and #%00000111
asl
asl
asl
asl
asl
ora $00
pha ; push 2
; Now store the two values from the stack into the palette.
pla ; pull 2
sta $2122
pla ; pull 1
sta $2122
rts
FillScratch:
lda #$42 ; B
ldx #0
FillScratchLoop:
sta $00,X
inx
cpx #$10
bne FillScratchLoop
rts
.ENDS