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: Difference between revisions

From SnesLab
Jump to: navigation, search
mNo edit summary
 
(14 intermediate revisions by 5 users not shown)
Line 3: Line 3:
== 65c816 S-CPU ==
== 65c816 S-CPU ==


=== Wait for H-Blank ===
=== General ===
 
==== Wait for H-Blank ====


<pre>
<pre>
Line 12: Line 14:
BIT $4212
BIT $4212
BVC -
BVC -
</pre>
==== Inverse the accumulator (8-bit) ====
By [[User:Nambona890|Nambona890]]
Works with SA-1.
<pre>
EOR #$FF
INC
</pre>
==== Inverse the accumulator (16-bit) ====
By [[User:Nambona890|Nambona890]]
Works with SA-1.
<pre>
EOR #$FFFF
INC
</pre>
==== Toggle Carry Flag Macro ====
Works with SA-1.
<pre>
macro XOC()
BCC ?set
CLC
BRA ?done
?set: SEC
?done:
endmacro
</pre>
==== Toggle Carry Flag Alternative (8-bit) ====
Works with SA-1.
<pre>
ROL
EOR #$01
ROR
</pre>
==== Toggle Carry Flag Alternative (16-bit) ====
Works with SA-1.
<pre>
ROL
EOR #$0001
ROR
</pre>
==== Long Branch Macros ====
Useful if you want to branch more than 0x80 bytes forward/backwards.
Works with SA-1.
<pre>
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
</pre>
==== Jump Tables (word pointers) ====
By [[User:KobaBeach|lion]]
Useful for creating complex bits of code with multiple states. <br>
'''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.
<pre>
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
</pre>
==== Jump Tables (longword pointers) ====
By [[User:KobaBeach|lion]]
Same as above but for longwords instead of words, such as when needing to access different banks. <br>
You can also alter it to use words if you cannot use the X Register for whatever reason.
<pre>
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
</pre>
=== SMW Hacking ===
==== Custom block template ====
By [[User:Alcaro|Alcaro]]
Works with SA-1.
<pre>
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
</pre>
==== Decompress GFX File ====
By [[User:Vitor Vilela|Vitor Vilela]]
Works with SA-1.
<pre>
; 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
</pre>
==== Get acts like from map16 number ====
By [[User:Vitor Vilela|Vitor Vilela]]
Works with SA-1.
<pre>
; $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
</pre>
==== Find free OAM slot ====
By [[User:Vitor Vilela|Vitor Vilela]]
SA-1 hybrid.
<pre>
; 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
</pre>
==== Erase current save file ====
By [[User:Sixtare|Sixtare]]
<pre>
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
</pre>
==== Jump Tables (Using ExecutePtr) ====
By [[User:KobaBeach|lion]]
The above Jump Table codes can also be used in SMW, however there is also a routine included in the original code. <br>
However this does have the inconvenience of the table being right next to the JSL and is also much slower.
<pre>
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
</pre>
<pre>
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
</pre>
</pre>


== 65c816 SA-1 CPU ==
== 65c816 SA-1 CPU ==
Some snippets present on [[#65c816_S-CPU|S-CPU]] section works with SA-1 CPU as well.
=== General ===


=== Unsigned 16 bit x 16 bit = 32 bit multiplication ===
==== Unsigned 16 bit x 16 bit = 32 bit multiplication ====
by [[User:Akaginite|Akaginite]]
By [[User:Akaginite|Akaginite]]


<pre>
<pre>
Line 23: Line 355:
; 16bit * 16bit Multiplication SA-1 version
; 16bit * 16bit Multiplication SA-1 version
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Argusment
; Parameters
; $00-$01 : Multiplicand
; $00-$01 : Multiplicand
; $02-$03 : Multiplier
; $02-$03 : Multiplier

Latest revision as of 22:19, 9 September 2019

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