We've just updated MediaWiki and its underlying software. If anything doesn't look or work quite right, please mention it to us. --RanAS

Useful Code Snippets

From SnesLab
Jump to: navigation, search

Useful code snippets for the 65c816 ASM and general SNES hardware.

65c816 S-CPU

General

Wait for H-Blank

-
BIT $4212
BVS -
-
BIT $4212
BVC -

Inverse the accumulator (8-bit)

By Nambona890

Works with SA-1.

EOR #$FF
INC

Inverse the accumulator (16-bit)

By Nambona890

Works with SA-1.

EOR #$FFFF
INC

Toggle Carry Flag Macro

Works with SA-1.

macro XOC()
	BCC ?set
	CLC
	BRA ?done
?set:	SEC
?done:
endmacro

Toggle Carry Flag Alternative (8-bit)

Works with SA-1.

ROL
EOR #$01
ROR

Toggle Carry Flag Alternative (16-bit)

Works with SA-1.

ROL
EOR #$0001
ROR

Long Branch Macros

Useful if you want to branch more than 0x80 bytes forward/backwards.

Works with SA-1.

macro JEQ(branch)
	BNE ?branch
	JMP <branch>
?branch:
endmacro

macro JNE(branch)
	BEQ ?branch
	JMP <branch>
?branch:
endmacro

macro JCC(branch)
	BCS ?branch
	JMP <branch>
?branch:
endmacro

macro JCS(branch)
	BCC ?branch
	JMP <branch>
?branch:
endmacro

macro JPL(branch)
	BMI ?branch
	JMP <branch>
?branch:
endmacro

macro JMI(branch)
	BPL ?branch
	JMP <branch>
?branch:
endmacro

macro JVC(branch)
	BVS ?branch
	JMP <branch>
?branch:
endmacro

macro JVS(branch)
	BVC ?branch
	JMP <branch>
?branch:
endmacro

Jump Tables (word pointers)

By lion

Useful for creating complex bits of code with multiple states.
IF USED ON SMW: You will need to reload the Sprite Index ($15E9) to X in each label due to it using the X Register, else it'll crash. SMW however has its own premade Jump Table routine.

	LDA ?pointer	; A simple RAM address that changes value depending on state will suffice.
	ASL		; Multiply the value by 2, as labels are words (16-bit 2 bytes).
	TAX
	JSR.w (Pointers,x)
	RTL/RTS

pointers:
	dw Label00
	dw Label01
	dw Label02

Label00:
	RTS
Label01:
	RTS
Label02:
	RTS

Jump Tables (longword pointers)

By lion

Same as above but for longwords instead of words, such as when needing to access different banks.
You can also alter it to use words if you cannot use the X Register for whatever reason.

	LDA ?pointer	; A simple RAM address that changes value depending on state will suffice.
	STA <scratch>	; Scratch RAM, like $00 in SMW will suffice.
	ASL		; \
	CLC		; | Multiply the value by 3, as labels are longwords (24-bits, 3 bytes).
	ADC <scratch>	; /
	TAX
	LDA Pointers,x
	STA <scratch>
	LDA Pointers+1,x
	STA <scratch>+1
	LDA Pointers+2,x
	STA <scratch>+2
	JML [<scratch>]

pointers:
	dl Label00
	dl Label01
	dl Label02

Label00:
	RTS/RTL
Label01:
	RTS/RTL
Label02:
	RTS/RTL

SMW Hacking

Custom block template

By Alcaro

Works with SA-1.

db $42 ; or db $37
JMP MarioBelow : JMP MarioAbove : JMP MarioSide
JMP SpriteV : JMP SpriteH : JMP MarioCape : JMP MarioFireball
JMP TopCorner : JMP BodyInside : JMP HeadInside
; JMP WallFeet : JMP WallBody ; if using db $37

MarioBelow:
MarioAbove:
MarioSide:

TopCorner:
BodyInside:
HeadInside:

WallFeet:
WallBody:

SpriteV:
SpriteH:

MarioCape:
MarioFireball:
RTL

Decompress GFX File

By Vitor Vilela

Works with SA-1.

; Decompress input GFX file
; Must be called from SNES CPU.
; SA-1 is automatically invoked on SA-1 Pack ROMs.

STZ $00
REP #$20
LDA #$7EAD	; destination buffer = $7EAD00
STA $01
LDA #$0080	; deoompress ExGFX80.bin ..
JSL $0FF900

Get acts like from map16 number

By Vitor Vilela

Works with SA-1.

; $00 = map16 tile
get_act_like:
	LDA $06F624
	STA $02
	LDA $06F625
	STA $03
	LDA $06F626
	STA $04
	
	REP #$30
	LDA $00
	AND #$3FFF
	ASL
	TAY
	LDA [$02],y
	STA $00
	SEP #$30
	RTS

Find free OAM slot

By Vitor Vilela

SA-1 hybrid.

; Routine for finding a free OAM slot
; NMSTL compatible. Tested against Level ASM, Overworld ASM.

find_oam:
	LDY #$FC
-	LDA $02FD|!addr,y
	CMP #$F0
	BNE +
	CPY #$3C
	BEQ +
	DEY
	DEY
	DEY
	DEY
	BRA -
+	RTS

Erase current save file

By Sixtare

Erase:
REP #$10
	LDA $010A
	CMP #$01
	BEQ .01
	BCS .02
.00
LDX #$008F
JMP .delete

.01
LDX #$011E
JMP .delete

.02
LDX #$01AD
	.delete
	LDY #$008F
	LDA #$00
-	STA $700000,x
	STA $7001AD,x
	DEX
	DEY
	BPL -
	SEP #$10
RTS

Jump Tables (Using ExecutePtr)

By lion

The above Jump Table codes can also be used in SMW, however there is also a routine included in the original code.
However this does have the inconvenience of the table being right next to the JSL and is also much slower.

	LDA ?pointer	; A simple RAM address that changes value depending on state will suffice.
	JSL $0086DF	; The word (2 bytes) equivalent.

pointers:
	dw Label00

Label00:
	RTS/RTL
	LDA ?pointer	; A simple RAM address that changes value depending on state will suffice.
	JSL $0086FA	; The longword (3 bytes) equivalent.

pointers:
	dl Label00

Label00:
	RTS/RTL

65c816 SA-1 CPU

Some snippets present on S-CPU section works with SA-1 CPU as well.

General

Unsigned 16 bit x 16 bit = 32 bit multiplication

By Akaginite

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 16bit * 16bit Multiplication SA-1 version
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Parameters
; $00-$01 : Multiplicand
; $02-$03 : Multiplier
; Return values
; $04-$07 : Product
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MathMul16_16:	STZ $2250
		REP #$20
		LDA $00
		STA $2251
		ASL A
		LDA $02
		STA $2253
		BCS +
		LDA.w #$0000
+		BIT $02
		BPL +
		CLC
		ADC $00
+		CLC
		ADC $2308
		STA $06
		LDA $2306
		STA $04
		SEP #$20
		RTS