SFC Development Wiki
🌝
Browse Tags
New Document
Editing 65c816 Code Snippets
Title
Slug
Original Slug (Reference Only)
Redirects
Image
Excerpt
65c816 Code Snippets - Hopefully useful code snippets for the 65c816.
Content
Write
[toc] Hopefully useful code snippets for the 65c816. ## Math ### Unsigned 16bit * 8bit Operation / 符号無し16bit*8bit演算 ```armasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 符号無し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演算 ```armasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 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演算 ```armasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 符号無し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 / 原点から目標点への角度を求める ```armasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 原点から目標点への角度を求める ; 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) / 原点から目標点への角度を求める(高精度版) ```armasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 原点から目標点への角度を求める(高精度版 ; 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 / ファイアボールとスプライトの当たり判定を取得 ```armasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ファイアボールと自スプライトの当たり判定を取得 ; 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 ```
Preview
Tags
Delete
Drop files here or click to upload.