Colin McMillen
9 years ago
3 changed files with 537 additions and 0 deletions
-
260InitSNES.asm
-
61header.inc
-
216pewpew.asm
@ -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 |
@ -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 |
@ -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 |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue