lorom header !Location = $1D8000 ;(PC:E8200) !MAIN_CODE_SIZE = END_OF_FILE-CodeStart ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ;便利なJSLを一括してぶちこむものです。 ; ;!Location の所にコードが設置されます。 ; ;以下のアドレスを指定することで ;それぞれのJSLが呼び出せます。 ; ; ;@サインJSL !Location + $08 ;AコサインJSL !Location + $0C ;B任意タイル設置 !Location + $10 ;C↑のレイヤー2フラグ !Location + $14 ;DGET DRAW INFO !Location + $18 ;ESUB OFF SCREEN !Location + $1C ;FインスタントNMI !Location + $20 ;G√JSL !Location + $24 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org !Location db "STAR" ;RATSタグ生成 dw !MAIN_CODE_SIZE-$01 dw !MAIN_CODE_SIZE-$01^$FFFF CodeStart: JML SIN JML COS JML SUBL_SET_MAP16 JML SUBL_SET_LAYER2 JML GET_DRAW_INFO JML START_SUB JML INSTANT_NMI JML ROOT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;@A三角関数JSL ; ; ;$00 に半径R、 ;$01 $02 に角θ(000〜01FF)を代入して ; ;サインJSL を呼び出すと ;$03 $04 に Rsinθ、 ; ;コサインJSL を呼び出すと、 ;$05 $06 に Rcosθ が計算されて返ってきます。 ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;サインJSL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SIN: PHP PHX REP #$30 ;16bitモード LDA $01 AND #$00FF ASL A TAX LDA $07F7DB,x STA $03 SEP #$30 ;8bitモード LDA $02 ;$02を保存 PHA LDA $03 ;|sin|を STA $4202 ;「かけられる数」とする。 LDA $00 ;半径を呼ぶ LDX $04 ;|sin| = 1.00 だったら計算不要(Rsin = 半径) BNE IF1_SIN STA $4203 ;半径を「かける数」とする。 ASL $4216 ;出た答えの小数点以下を四捨五入 LDA $4217 ADC #$00 IF1_SIN: LSR $02 ;絶対値を外す BCC IF_SIN_PLUS EOR #$FF INC A STA $03 BEQ IF0_SIN LDA #$FF STA $04 BRA END_SIN IF_SIN_PLUS: STA $03 IF0_SIN: STZ $04 END_SIN: PLA STA $02 ;$02を復元 PLX PLP RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;コサインJSL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; COS: PHP PHX REP #$30 ;16bitモード LDA $01 ;$01 = θ CLC ADC #$0080 AND #$01FF STA $07 ;$07 = θ + 90° LDA $07 AND #$00FF ASL A TAX LDA $07F7DB,x STA $05 SEP #$30 LDA $05 ;|cos|を STA $4202 ;「かけられる数」とする。 LDA $00 ;半径を呼ぶ LDX $06 ;|cos| = 1.00 だったら計算不要(Rsin = 半径) BNE IF1_COS STA $4203 ;半径を「かける数」とする。 ASL $4216 ;出た答えの小数点以下を四捨五入 LDA $4217 ADC #$00 IF1_COS: LSR $08 ;絶対値を外す BCC IF_COS_PLUS EOR #$FF INC A STA $05 BEQ IF0_COS LDA #$FF STA $06 BRA END_COS IF_COS_PLUS: STA $05 IF0_COS: STZ $06 END_COS: PLX PLP RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;BC任意のタイルを設置 ; ;Carol氏の講座のものです。 ; ;$9A $9B にY座標、 ;$98 $99 にX座標を入力し、 ; ; ; REP #$30 ; LDA.W #$???? ;生成するタイルの16x番号 ; JSL B ; SEP #$30 ; ;でタイルを設置できます。 ; ; ;レイヤー2なら ; ; JSL C ; REP #$30 ; LDA.W #$???? ;生成するタイルの16x番号 ; JSL B ; SEP #$30 ; ;でタイルを設置できます。 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SUBL_SET_MAP16: PHX TAX JSR SUB_8034 PLX RTL RETURN_MAP16_18: PLX PLB RTS SUB_8034: SEP #$20 PHB LDA #$00 PHA PLB REP #$30 PHX LDA $9A STA $0C LDA $98 STA $0E LDA.w #$0000 SEP #$20 LDA $5B STA $09 LDA $1933 BEQ NO_SHIFT_MAP16 LSR $09 NO_SHIFT_MAP16: LDY $0E LDA $09 AND #$01 BEQ HORIZ_MAP16 LDA $9B STA $00 LDA $99 STA $9B LDA $00 STA $99 LDY $0C HORIZ_MAP16: CPY.w #$0200 BCS RETURN_MAP16_18 LDA $1933 ASL A TAX LDA $BEA8,x STA $65 LDA $BEA9,x STA $66 STZ $67 LDA $1925 ASL A TAY LDA ($65),y STA $04 INY LDA ($65),y STA $05 STZ $06 LDA $9B STA $07 ASL A CLC ADC $07 TAY LDA ($04),y STA $6B STA $6E INY LDA ($04),y STA $6C STA $6F LDA #$7E STA $6D INC A STA $70 LDA $09 AND #$01 BEQ NO_AND LDA $99 LSR A LDA $9B AND #$01 BRA LABEL52 NO_AND: LDA $9B LSR A LDA $99 LABEL52: ROL A ASL A ASL A ORA #$20 STA $04 CPX.w #$0000 BEQ NO_ADD CLC ADC #$10 STA $04 NO_ADD: LDA $98 AND #$F0 CLC ASL A ROL A STA $05 ROL A AND #$03 ORA $04 STA $06 LDA $9A AND #$F0 LSR A LSR A LSR A STA $04 LDA $05 AND #$C0 ORA $04 STA $07 REP #$20 LDA $09 AND.w #$0001 BNE LABEL51 LDA $1A SEC SBC.w #$0080 TAX LDY $1C LDA $1933 BEQ LABEL50 LDX $1E LDA $20 SEC SBC.w #$0080 TAY BRA LABEL50 LABEL51: LDX $1A LDA $1C SEC SBC.w #$0080 TAY LDA $1933 BEQ LABEL50 LDA $1E SEC SBC.w #$0080 TAX LDY $20 LABEL50: STX $08 STY $0A LDA $98 AND.w #$01F0 STA $04 LDA $9A LSR A LSR A LSR A LSR A AND.w #$000F ORA $04 TAY PLA SEP #$20 STA [$6B],y XBA STA [$6E],y XBA REP #$20 ASL A TAY PHK PER $0006 PEA $804C JML $00C0FB MAP16_RETURN: PLB RTS SUBL_SET_LAYER2: LDA #$01 ;レイヤー2フラグ STA $1933 REP #$20 ;レイヤー1とレイヤー2の座標のズレを考慮した位置修正 LDA $9A SEC SBC $1462 CLC ADC $1466 STA $9A LDA $98 SEC SBC $1464 CLC ADC $1468 STA $98 SEP #$20 RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;Sprite toolでの基本JSL ; ;いちいち各スプライトに入れているのも ;効率的でない気がします。 ; ;GET DRAW INFO はいつも通り。 ;SUB_OFF_SCREEN_X4以降のあるASMにはこのJSL.asm内にあるSTART_SUBを使わないでください。 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SPR_T1: db $0C,$1C SPR_T2: db $01,$02 GET_DRAW_INFO: STZ $186C,x ; reset sprite offscreen flag, vertical STZ $15A0,x ; reset sprite offscreen flag, horizontal LDA $E4,x ; \ CMP $1A ; | set horizontal offscreen if necessary LDA $14E0,x ; | SBC $1B ; | BEQ ON_SCREEN_X ; | INC $15A0,x ; / ON_SCREEN_X: LDA $14E0,x ; \ XBA ; | LDA $E4,x ; | REP #$20 ; | SEC ; | SBC $1A ; | mark sprite invalid if far enough off screen CLC ; | ADC.w #$0040 ; | CMP.w #$0180 ; | SEP #$20 ; | ROL A ; | AND #$01 ; | STA $15C4,x ; / BNE INVALID ; PHB PHK PLB LDY #$00 ; \ set up loop: LDA $1662,x ; | AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice BEQ ON_SCREEN_LOOP ; | else, go through loop once INY ; / ON_SCREEN_LOOP: LDA $D8,x ; \ CLC ; | set vertical offscreen if necessary ADC SPR_T1,y ; | PHP ; | CMP $1C ; | (vert screen boundry) ROL $00 ; | PLP ; | LDA $14D4,x ; | ADC #$00 ; | LSR $00 ; | SBC $1D ; | BEQ ON_SCREEN_Y ; | LDA $186C,x ; | (vert offscreen) ORA SPR_T2,y ; | STA $186C,x ; | ON_SCREEN_Y: DEY ; | BPL ON_SCREEN_LOOP ; / PLB LDY $15EA,x ; get offset to sprite OAM LDA $E4,x ; \ SEC ; | SBC $1A ; | $00 = sprite x position relative to screen boarder STA $00 ; / LDA $D8,x ; \ SEC ; | SBC $1C ; | $01 = sprite y position relative to screen boarder STA $01 ; / RTL ; return INVALID: REP #$20 PLA ; \ return from *main gfx routine* subroutine... PLY PLA ; | ...(not just this subroutine) PHY PHA SEP #$20 RTL ; / START_SUB: PHB LDA #$83 PHA PLB PEA $839D ;PEA $B75B-1 JML $03B859 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;インスタントNMI ; ;7EC10E…認証用 ;7EC10F…OFFSET ;7EC110…8バイト単位のテーブル ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INSTANT_NMI: STA $00 STX $01 PLA STA $02 PLA STA $03 PLA STA $04 REP #$30 ;AXY INC $02 INC $02 SEP #$20 ;aXY LDA $7EC10F CMP #$7E BCC STORE_NMI REP #$30 ;まずありえないが、NMI処理が限界(7E個のJSL)に達した時は回さない INC $02 INC $02 RETURN_NMI: SEP #$30 LDA $04 PHA LDA $03 PHA LDA $02 PHA LDA $00 LDX $01 RTL STORE_NMI: REP #$30 ;AXY LDA $7EC10F ; AND #$00FF ASL ASL ASL TAX ;X = OFFSET x 8 SEP #$20 ;aXY LDA #$A9 STA $7EC110,x LDA $00 STA $7EC111,x LDA #$A2 STA $7EC112,x LDA $01 STA $7EC113,x LDA #$22 STA $7EC114,x LDA [$02] STA $7EC115,x REP #$20 INC $02 SEP #$20 LDA [$02] STA $7EC116,x REP #$20 INC $02 SEP #$20 LDA [$02] STA $7EC117,x LDA #$6B STA $7EC118,x INC $7EC10F LDA $7EC10F EOR #$FF STA $7EC10E BRA RETURN_NMI ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;√ ; ;$00$01に16bitの数値を入れてこのサブルーチンを呼び出すと ; ;$02にその平方根を返します。 ;$03を途中計算で潰します。 ; ;ちなみに計算方法はニュートン法2発です。 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ROOT: SEP #$30 PHX LDA $01 BNE ROOT_NOTS LDX $00 LDA ROOT_DATA,x STA $02 PLX RTL ROOT_NOTS: LDA $01 STA $4205 LDA $00 STA $4204 ;被除数セット LDX $01 LDA ROOT_DATA,x ASL ASL ASL ASL ORA #$07 STA $4206 ;除数セット。この後16サイクル待つ REP #$20 ;3サイクル消費 AND #$00FF ;2サイクル消費 CLC ;2サイクル消費 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ;念のため10サイクル消費 ADC $4214 LSR STA $02 SEP #$30 STA $4206 ;除数セット。 LDA $03 ;3サイクル消費 BEQ SKIP_FF ;2サイクル消費 LDA #$FF STA $02 PLX RTL SKIP_FF: REP #$30 ;3サイクル消費 LDA $02 ;3サイクル消費 CLC ;2サイクル消費 NOP NOP NOP NOP ;念のため4サイクル消費 ADC $4214 LSR STA $02 SEP #$30 PLX RTL ROOT_DATA: db $00 db $01,$01,$01 db $02,$02,$02,$02,$02 db $03,$03,$03,$03,$03,$03,$03 db $04,$04,$04,$04,$04,$04,$04,$04,$04 db $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05 db $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06 db $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07 db $08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08 db $09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09 db $0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A db $0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B db $0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C db $0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D db $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F END_OF_FILE: