Hopefully useful code snippets for the 65c816.
Math
Unsigned 16bit * 8bit Operation / 符号無し16bit*8bit演算
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 符号無し16bit*8bit演算
; Unsigned 16 bits * 8 bit operation
; $00,$01に被乗数、$02に乗数をセットして呼び出すと
; When you call by setting the multiplicand to $00, $01 and the multiplier to $02
; $00~$02に結果が返ってきます
; The result will be returned from $00 to $02
; A,Yレジスタを使用
; Uses A, Y registers
; 42 Bytes,96 Cycles
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDY $02
LDA $00
JSR Multi_8
STY $02
PHA
LDY $01
JSR Multi_8_0
STA $00
TYA
CLC
ADC $02
STA $01
PLA
ADC #$00
STA $02
RTS
Multi_8: STA $4202
Multi_8_0: STY $4203
;NOP
;NOP
;NOP
;NOP
LDA $4216
LDY $4217
RTS
Unsigned 16bit * 16bit Operation / 符号無し16bit*16bit演算
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 16bit * 16bit演算
; 16 bit * 16 bit operation
; $00,$01に被乗数、$02,$03に乗数をセットして呼び出すと
; When you call $00, $01 by setting the multiplicand, $02, $03 a multiplier
; $00~$03に結果が返ってきます
; The result will be returned from $00 to $03
; A,Yレジスタを使用
; Uses A, Y registers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Multi16_16: LDA $03
LDY $01
JSR Multi_0
PHA
PHY
LDA $03
LDY $00
JSR Multi_0
STA $03
PHY
LDA $02
LDY $01
JSR Multi_0
STA $01
LDA $02
STY $02
LDY $00
JSR Multi_0
STA $00
TYA
CLC
ADC $01
STA $01
PLA
ADC $02
PLY
BCC Multi_1
INY
Multi_1: STA $02
LDA $01
CLC
ADC $03
STA $01
PLA
ADC $02
BCC Multi_2
INY
Multi_2: STA $02
STY $03
RTS
Multi_0: STA $4202
Multi_3: STY $4203
;NOP
;NOP
;NOP
;NOP
LDA $4216
LDY $4217
RTS
Unsigned 16bit / 16bit Operation / 符号無し16bit/16bit演算
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 符号無し16bit/16bit演算
; Unsigned 16 bit / 16 bit operation
; $00~$01に被除数,$02~$03に除数をセットして呼び出すと
; When you call dividend from $00 to $01 by setting dividend and $02 to $03 divisor
; $06~$07に結果,$00~$01に余りが返ってきます
; From $06 to $07, the remainder will be returned from $00 to $01
; ゼロ除算が発生した場合$06~$07,$00~$01の値は$FFFFになります
; When division by zero occurred $06 to $07, $00 to $01 is $FFFF
; A,Yレジスタを使用
; Uses A, Y registers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MathDiv: REP #$20
LDA $00 ; 被除数
ASL A
STA $06 ; 結果
LDY #$0F
TDC
.Loop ROL A
CMP $02
BCC .Skip
SBC $02
.Skip ROL $06
DEY
BPL .Loop
STA $00
SEP #$20
RTS
Super Mario World Specific
Find the angle from the origin to the target point / 原点から目標点への角度を求める
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 原点から目標点への角度を求める
; Find the angle from the origin to the target point
; $00,$01に原点のX,$02,$03に原点のY
; $00, $01 the origin X, $02, $03 Y of origin
; $04,$05に目標点X,$06,$07に目標点Yをセットして呼び出すと
; If you set target point Y at $04, $05 at target points X, $06, $07 and call it
; $00,$01に角度θ($0000~$01FF)が返ってきます
; Angle θ ($0000 - $01FF) will be returned to $00, $01
; 対応している差の範囲はX,Y共に-$01FE~$01FEです
; The corresponding difference range is - $01FE to $01FE for both X and Y
; アークタンジェントのテーブルが256Bytesあるので
; Because there are 256 bytes of arctangent table
; JSLルーチン化推奨
; Recommended for JSL routines
; A,Yレジスタを使用
; Uses A, Y registers
; 一時変数 $00~$07を使用
; Uses temporary variable $00 ~ $07
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetAngle: REP #$20
LDY #$00
LDA $02
SEC
SBC $06
BPL If_Plus20
INY
EOR.w #$FFFF
INC A
If_Plus20: STA $02
LDA $00
SEC
SBC $04
BPL If_Plus21
INY
INY
EOR.w #$FFFF
INC A
If_Plus21: STA $00
STY $04
BEQ X_Zero
CMP.w #$0100
XBA
ROR A
XBA
TAY
LDA $02
BEQ Y_Zero
CMP.w #$0100
XBA
ROR A
AND.w #$FF80
STA $4204
STY $4206
LDA $4214
LSR A
LSR A
LSR A
LSR A
CMP.w #$0100
SEP #$20
BCC NoOverFlow
LDA #$FF
NoOverFlow: TAY
LDA AtanTable,y
LSR $04
BCS If_Plus30
EOR #$FF ;\
INC A ; | θ:360°-θ
BEQ If_Plus30 ; |
INC $01 ;/
If_Plus30: LSR $04
BCS If_Plus31
EOR #$FF ;\
INC A ; | θ:180°-θ
BNE If_Plus31 ; |
INC $01 ;/
If_Plus31: STA $00
LDA #$FE
TRB $01
RTS
X_Zero: SEP #$20
LDY #$00
LSR $04
BCS If_Plus32
INY
If_Plus32: STY $01
LDA #$80
STA $00
LDY #$FF
RTS
Y_Zero: SEP #$20
STZ $00
LDY #$00
LDA $04
AND #$02
BNE If_Plus33
INY
If_Plus33: STY $01
LDY #$00
RTS
AtanTable:
db $00,$05,$0A,$0F,$13,$18,$1D,$21,$25,$29,$2D,$31,$34,$37,$3A,$3D
db $40,$42,$44,$46,$49,$4A,$4C,$4E,$50,$51,$53,$54,$55,$56,$58,$59
db $5A,$5B,$5C,$5D,$5D,$5E,$5F,$60,$60,$61,$62,$62,$63,$64,$64,$65
db $65,$66,$66,$67,$67,$68,$68,$68,$69,$69,$6A,$6A,$6A,$6B,$6B,$6B
db $6C,$6C,$6C,$6C,$6D,$6D,$6D,$6D,$6E,$6E,$6E,$6E,$6F,$6F,$6F,$6F
db $6F,$70,$70,$70,$70,$70,$71,$71,$71,$71,$71,$71,$71,$72,$72,$72
db $72,$72,$72,$72,$73,$73,$73,$73,$73,$73,$73,$73,$74,$74,$74,$74
db $74,$74,$74,$74,$74,$74,$75,$75,$75,$75,$75,$75,$75,$75,$75,$75
db $75,$75,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76
db $76,$77,$77,$77,$77,$77,$77,$77,$77,$77,$77,$77,$77,$77,$77,$77
db $77,$77,$77,$78,$78,$78,$78,$78,$78,$78,$78,$78,$78,$78,$78,$78
db $78,$78,$78,$78,$78,$78,$78,$78,$78,$78,$79,$79,$79,$79,$79,$79
db $79,$79,$79,$79,$79,$79,$79,$79,$79,$79,$79,$79,$79,$79,$79,$79
db $79,$79,$79,$79,$79,$79,$79,$79,$79,$7A,$7A,$7A,$7A,$7A,$7A,$7A
db $7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A
db $7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$7A,$80
Find the angle from the origin to the target point (high precision version) / 原点から目標点への角度を求める(高精度版)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 原点から目標点への角度を求める(高精度版
; Find the angle from the origin to the target point (high accuracy version)
; 使用する一時変数はほぼ同じです
; The temporary variables used are almost the same
; このコードは精度が高い代わりに処理が重いです
; This code is more accurate but heavier processing
; こっちもJSLルーチン化推奨
; JSL routine recommendation
; A,Yレジスタを使用
; Uses A, Y registers
; 一時変数 $00~$07を使用
; Uses temporary variable $00 ~ $07
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetAngle: PHX
REP #$20
LDA $02
SEC
SBC $06
PHP
BPL IfPlus1
EOR.w #$FFFF
INC A
IfPlus1: STA $02
LDA $00
SEC
SBC $04
PHP
BPL IfPlus0
EOR.w #$FFFF
INC A
IfPlus0: STA $00
BEQ X_Zero
LSR A
TAY
LDA $02
BEQ Y_Zero
CMP.w #$0100
XBA
ROR A
AND.w #$FF80
STA $4204
STY $4206
STZ $00
LDA.w #$0040
STA $02
LDA $4214
STA $06
Loop00: LDA $00
INY
ORA $02
ASL A
TAX
LDA $06
CMP.l GetTan,x
BCC Label00
LDA $02
TSB $00
Label00: LSR $02
BCC Loop00
SEP #$20
PLA
;EOR $01,s
db $43,$01
BPL Label02
LDA $00
EOR #$FF
INC A
STA $00
BNE Label02
INC $01
Label02: PLP
BMI Label03
INC $01
Label03: PLX
RTS
X_Zero: LDA.w #$0080
STA $00
PLP
PLP
BMI IfPlus4
INC $01
IfPlus4: PLX
RTS
Y_Zero: STZ $00
PLP
BMI IfPlus5
INC $01
IfPlus5: PLP
PLX
RTS
GetTan:
dw $0000,$0003,$0006,$0009,$000C,$000F,$0012,$0016
dw $0019,$001C,$001F,$0022,$0025,$0029,$002C,$002F
dw $0032,$0036,$0039,$003C,$0040,$0043,$0046,$004A
dw $004D,$0051,$0054,$0058,$005B,$005F,$0062,$0066
dw $006A,$006D,$0071,$0075,$0079,$007C,$0080,$0084
dw $0088,$008C,$0091,$0095,$0099,$009D,$00A2,$00A6
dw $00AB,$00AF,$00B4,$00B9,$00BD,$00C2,$00C7,$00CC
dw $00D2,$00D7,$00DC,$00E2,$00E8,$00ED,$00F3,$00F9
dw $0100,$0106,$010C,$0113,$011A,$0121,$0128,$0130
dw $0137,$013F,$0148,$0150,$0159,$0162,$016B,$0175
dw $017F,$0189,$0194,$019F,$01AB,$01B7,$01C3,$01D1
dw $01DE,$01ED,$01FC,$020C,$021D,$022E,$0241,$0255
dw $026A,$0280,$0297,$02B0,$02CB,$02E8,$0306,$0328
dw $034B,$0372,$039D,$03CB,$03FE,$0435,$0474,$04B9
dw $0506,$055E,$05C3,$0637,$06BD,$075C,$081B,$0904
dw $0A27,$0B9C,$0D8E,$1046,$145A,$1B26,$28BC,$517B
Acquisition judgment of fireball and sprite / ファイアボールとスプライトの当たり判定を取得
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ファイアボールと自スプライトの当たり判定を取得
; Acquire hit judgment between fire ball and self sprite
; キャリーフラグに結果が返ってきます(C=1:触れている)
; The result will be returned in carry flag (C = 1: touched)
; A,X,Yレジスタを使用
; Uses A, X, Y registers
; 一時変数 $00~$0C,$0Fを使用
; Uses temporary variables $00 to $0C, $0F
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FireContact LDY #$01
ExtLoop LDA $1713,y
CMP #$05
BEQ CheckContact
NextExtSpr DEY
BPL ExtLoop
RTS
CheckContact LDA $154C,x
ORA $1781,y
BNE NextExtSpr
JSR GetExtSprA
JSL $03B6E5
JSL $03B72B
BCC NextExtSpr
LDA #$01 ;\
STA $1713,y ; | ファイアを消滅させない場合
LDA #$10 ; | コメント化する必要あり
STA $1777,y ;/
RTS
GetExtSprA PHX
LDX $1713,y
LDA $1727,y
CLC
ADC $02A4E7,x
STA $04
LDA $173B,y
ADC #$00
STA $0A
LDA $02A4FF,x
STA $06
LDA $171D,y
CLC
ADC $02A4F3,x
STA $05
LDA $1731,y
ADC #$00
STA $0B
LDA $02A50B,x
STA $07
PLX
RTS