Useful Code Snippets: Difference between revisions
Vitor Vilela (talk | contribs) (Add branching and carry-flag macros.) |
mNo edit summary |
||
(4 intermediate revisions by 4 users not shown) | |||
Line 17: | Line 17: | ||
==== Inverse the accumulator (8-bit) ==== | ==== Inverse the accumulator (8-bit) ==== | ||
By [[User:Nambona890|Nambona890]] | |||
Works with SA-1. | |||
<pre> | <pre> | ||
Line 24: | Line 27: | ||
==== Inverse the accumulator (16-bit) ==== | ==== Inverse the accumulator (16-bit) ==== | ||
By [[User:Nambona890|Nambona890]] | |||
Works with SA-1. | |||
<pre> | <pre> | ||
Line 31: | Line 37: | ||
==== Toggle Carry Flag Macro ==== | ==== Toggle Carry Flag Macro ==== | ||
Works with SA-1. | |||
<pre> | <pre> | ||
Line 40: | Line 47: | ||
?done: | ?done: | ||
endmacro | 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> | </pre> | ||
==== Long Branch Macros ==== | ==== Long Branch Macros ==== | ||
Useful if | Useful if you want to branch more than 0x80 bytes forward/backwards. | ||
Works with SA-1. | |||
<pre> | <pre> | ||
macro JEQ(branch) | macro JEQ(branch) | ||
BNE branch | BNE ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JNE(branch) | macro JNE(branch) | ||
BEQ branch | BEQ ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JCC(branch) | macro JCC(branch) | ||
BCS branch | BCS ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JCS(branch) | macro JCS(branch) | ||
BCC branch | BCC ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JPL(branch) | macro JPL(branch) | ||
BMI branch | BMI ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JMI(branch) | macro JMI(branch) | ||
BPL branch | BPL ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JVC(branch) | macro JVC(branch) | ||
BVS branch | BVS ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | endmacro | ||
macro JVS(branch) | macro JVS(branch) | ||
BVC branch | BVC ?branch | ||
JMP <branch> | JMP <branch> | ||
branch: | ?branch: | ||
endmacro | 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> | </pre> | ||
Line 98: | Line 185: | ||
==== Custom block template ==== | ==== Custom block template ==== | ||
By [[User:Alcaro|Alcaro]] | |||
Works with SA-1. | Works with SA-1. | ||
Line 128: | Line 216: | ||
==== Decompress GFX File ==== | ==== Decompress GFX File ==== | ||
By [[User:Vitor Vilela|Vitor Vilela]] | |||
Works with SA-1. | Works with SA-1. | ||
Line 145: | Line 234: | ||
==== Get acts like from map16 number ==== | ==== Get acts like from map16 number ==== | ||
By [[User:Vitor Vilela|Vitor Vilela]] | |||
Works with SA-1. | Works with SA-1. | ||
Line 170: | Line 260: | ||
==== Find free OAM slot ==== | ==== Find free OAM slot ==== | ||
By [[User:Vitor Vilela|Vitor Vilela]] | |||
SA-1 hybrid. | SA-1 hybrid. | ||
Line 193: | Line 284: | ||
==== Erase current save file ==== | ==== Erase current save file ==== | ||
By [[User:Sixtare|Sixtare]] | |||
<pre> | <pre> | ||
Line 222: | Line 313: | ||
SEP #$10 | SEP #$10 | ||
RTS | 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> | ||
Line 230: | Line 349: | ||
==== Unsigned 16 bit x 16 bit = 32 bit multiplication ==== | ==== Unsigned 16 bit x 16 bit = 32 bit multiplication ==== | ||
By [[User:Akaginite|Akaginite]] | |||
<pre> | <pre> |
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