Skip to content

Instantly share code, notes, and snippets.

@Themaister
Created March 25, 2011 20:30
Show Gist options
  • Save Themaister/887580 to your computer and use it in GitHub Desktop.
Save Themaister/887580 to your computer and use it in GitHub Desktop.
.include "header.inc"
.include "initsnes.asm"
.equ BGColorL $0000
.equ BGColorH $0001
; Some handy HW addresses we're using.
.equ JoypadState $4212
.equ JoypadStatus $4218
.equ JoypadEnable $4016
.equ NMIReg $4210
.equ ScreenBright $2100
.equ NMIEnable $4200
.equ BGIndex $2121
.equ BGColorDW $2122
;----------------------------------------------
; Subroutines:
; Return values in A register. Will be set 8-bit or 16-bit depending on return size.
; All registers are considered non-volatile except for P, unless it returns a value, (A is then also volatile).
;
; Arguments pushed on stack in reverse order of arguments. Caller cleans up.
;
; Handy offsets when doing argument handling and return.
.equ ARG1_OFF $00
.equ ARG2_OFF $01
.equ ARG3_OFF $02
.equ ARG4_OFF $03
.equ ARG5_OFF $04
.equ ARG6_OFF $05
.equ LOCAL_OFF 3
.equ NONLOCAL_OFF 4
.equ PUSHED_0 0
.equ PUSHED_1 1
.equ PUSHED_2 2
.equ PUSHED_3 3
;-----------------------------------------
; The actual code :D
.bank 0 slot 0
.org 0
.section "MainCode"
; Entry point
Start:
InitSNES ; Some fancy macro to init our SNES to a known, default state.
sep #$20 ; Set A/mem - 8-bit
rep #$10 ; Set X/Y - 16-bit
stz BGIndex ; Edit color 0
lda #%00011111 ; binary LSB
sta BGColorDW ; Store low-byte
sta BGColorL ; Save our color for later.
sta BGColorH ; Save our color for later.
asl ; Shift left twice to get B channel.
asl
sta BGColorDW ; Store hi-byte
lda #$0F
sta ScreenBright ; Turn on screen, full brightness
stz JoypadEnable ; Enable player 1 joypad?
lda #%10000001 ; enable NMI and Joypad
sta NMIEnable ; enable NMI (VBlank IRQ)
forever:
wai ; Wait for interupt to occur ...
jmp forever ; We let all action happen during VBlank, since we're cool. :D
VBlank:
pha ; Save A on stack
jsr WaitJoypadState ; Wait till joypad is up
jsr GetJoypadStatus ; Gets status from joypad
and #$80 ; Gets status about A button
cmp #$80 ; Check it ...
bne VBlankEnd ; If we have nothing to do, just quit it.
lda BGColorL
inc A ; Increment accumulator.
and #%00011111 ; Make sure we're still only using red color.
sta BGColorL ; Store our increment
pha
; Push 1 byte to stack. Our argument.
; Memory layout:
;
; | A
; Stack -> |
;
lda BGColorH
inc A
and #%00011111
sta BGColorH ; Store our increment
asl
asl ; Shift left to get actual blue value
pha
; Push 1 byte to stack. Our argument.
; Memory layout:
;
; | Low-color
; | Hi-color
; Stack -> |
;
jsr SetBackground ; Push return address to stack.
; This is 2 bytes long since we're calling a local procedure (same bank).
; The pushing sequence seems to save data to stack pointer, then decrement it.
; This is opposite with how x86 typically works where it decrements, then adds data.
; Memory layout:
; | Low-color
; | Hi-color
; | Hi-return
; | Lo-return
; Stack -> |
pla ; Popping must mean this increment stack pointer and move data there whereever.
pla ; Pop the two arguments we gave SetBackground
; Our stack is back to normal, yay :)
VBlankEnd:
lda NMIReg ; No idea why we're reading this, but hey :)
pla ; Pop back A
rti ; Return from IRQ.
;------------------------------------
; Takes color as argument on stack.
;------------------------------------
; void SetBackground(byte hi-byte, byte lo-byte);
;------------------------------------
SetBackground:
pha ; Push a on stack
; Memory layout
; 2. arg | Low-color
; 1. arg | Hi-color
; | Hi-return
; | Lo-return
; | A
; Stack -> |
stz BGIndex ; Set color
lda ARG2_OFF + LOCAL_OFF + PUSHED_1, s ; Pull 2nd argument, 5 bytes away.
; 2 bytes for JSR, 1 byte we just pushed and one dummy byte that is not written to yet.
; A = S[4] essentially since we're using indexed mode.
sta BGColorDW ; Store low-byte
lda ARG1_OFF + LOCAL_OFF + PUSHED_1, s ; Pull 1st argument, 4 bytes away.
sta BGColorDW ; Store hi-byte
pla ; Pull a, increment stack.
rts ; Return, increment stack twice.
;------------------------------------------
; Returns when joypad is ready to be read.
;------------------------------------------
; void WaitJoypadState(void)
;------------------------------------------
WaitJoypadState:
pha
sep #$20 ; Force A to 8-bit
lda JoypadState
and #$01
cmp #$00 ; Is Joypad not ready to be read?
beq WaitJoypadState ; If so, busywait till we do.
pla
rts
;-----------------------------
; Return joypad status.
;-----------------------------
; byte GetJoypadStatus(void);
;-----------------------------
GetJoypadStatus:
sep #$20
lda JoypadStatus ; Read status and return with result in A :)
rts
.ends
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment