It still crashes. Was I supposed to put it at the end of the main code?
Code;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; –C‘äƒNƒŠƒ{ƒ“
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Uses first extra bit: YES
; bit2 - ŒŠ‚É—Ž‚¿‚»‚¤‚É‚È‚Á‚Ä‚àŒü‚«‚ð•Ï‚¦‚È‚¢
; bit3 - ŒŠ‚É—Ž‚¿‚»‚¤‚É‚È‚Á‚½‚çŒü‚«‚ð•Ï‚¦‚é
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXTRA_BITS = $7FAB10
GET_DRAW_INFO = $1D8438
;SUB_OFF_SCREEN = $1D843C
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
X_SPEED dcb $08,$F8 ;‰E‘¬“x/¶‘¬“x
TILEMAP dcb $80,$A8,$80,$AA
Y_OFFSET dcb $F3,$00
SMOKE_X_OFFSET dcb $0C,$F4
SOUND_TO_GEN = $09 ;”ŽË‰¹
GEN_TIMER = $60 ;”ŽËƒ^ƒCƒ}[
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "INIT"
JSR SUB_HORZ_POS
TYA
STA $157C,x
LDA #GEN_TIMER
STA $1558,x
STZ $1594,x
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "MAIN"
PHB
PHK
PLB
JSR START_HB_CODE
PLB
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START_HB_CODE JSR SUB_GFX
LDA $9D
BNE RETURN
LDA $14C8,x
CMP #$03
BEQ HURT
CMP #$08
BNE RETURN
LDA $14
STA $1504,x
JSR SUB_OFF_SCREEN_X3 ; only process sprite while on screen
LDA $1558,x
BNE NOT_GEN
LDA $15A0,x
BNE NOT_GEN
LDA #SOUND_TO_GEN
STA $1DFC
LDA #GEN_TIMER
STA $1558,x
JSR SUB_SMOKE
JSR GEN_BULLET
LDA $157C,x
STA $00C2,y
NOT_GEN LDA $1588,x
AND #$04
BEQ TURN2
LDA #$10
STA $AA,x
LDA $1588,x
AND #$03
BNE TURN
BRA MOVE
TURN2 LDA EXTRA_BITS,x
AND #$04
BEQ MOVE
LDA $1594,x
BEQ MOVE
TURN LDA $157C,x
EOR #$01
STA $157C,x
MOVE LDY $157C,x
LDA X_SPEED,y
STA $B6,x
JSL $01802A
JSL $018032
JSL $01A7DC
LDA #$01
STA $1594,x
RETURN RTS
HURT STZ $14C8,x
JSR SUB_SMOKE
JSR GEN_NORMAL
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; generate sprite
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GEN_BULLET JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN67 ; / after: Y has index of sprite being generated
LDA #$08 ; \ set sprite status for new sprite
STA $14C8,y ; /ƒXƒvƒ‰ƒCƒg¶¬Žž‚Ìó‘Ô‚ðÝ’è
LDA #$1C ;‚±‚±‚ɶ¬‚µ‚½‚¢ƒXƒvƒ‰ƒCƒg”Ô†‚ð“ü‚ê‚é
STA $009E,y
LDA $E4,x ;\ set x position for new sprite
STA $00E4,y ; |ƒXƒvƒ‰ƒCƒg¶¬Žž‚ÌxÀ•W‚ð“ü—Í
LDA $14E0,x ; |‚±‚Ì—á‚Ìê‡AeƒXƒvƒ‰ƒCƒg‚Æ“¯‚¶ˆÊ’u‚ɶ¬‚µ‚Ä‚¢‚é
STA $14E0,y ; /
LDA $D8,x ;\ set y position for new sprite
SEC
SBC #$0C
STA $00D8,y ; |ƒXƒvƒ‰ƒCƒg¶¬Žž‚ÌyÀ•W‚ð“ü—Í
LDA $14D4,x ; |‚±‚Ì—á‚Ìê‡AeƒXƒvƒ‰ƒCƒg‚Æ“¯‚¶ˆÊ’u‚ɶ¬‚µ‚Ä‚¢‚é
SBC #$00
STA $14D4,y ; /
PHX
TYX
JSL $07F7D2 ;
PLX
RTS ; return
RETURN67 RTS
GEN_NORMAL JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN67 ; / after: Y has index of sprite being generated
LDA #$08 ; \ set sprite status for new sprite
STA $14C8,y ; /ƒXƒvƒ‰ƒCƒg¶¬Žž‚Ìó‘Ô‚ðÝ’è
LDA #$0F ;‚±‚±‚ɶ¬‚µ‚½‚¢ƒXƒvƒ‰ƒCƒg”Ô†‚ð“ü‚ê‚é
STA $009E,y
LDA $E4,x ;\ set x position for new sprite
STA $00E4,y ; |ƒXƒvƒ‰ƒCƒg¶¬Žž‚ÌxÀ•W‚ð“ü—Í
LDA $14E0,x ; |‚±‚Ì—á‚Ìê‡AeƒXƒvƒ‰ƒCƒg‚Æ“¯‚¶ˆÊ’u‚ɶ¬‚µ‚Ä‚¢‚é
STA $14E0,y ; /
LDA $D8,x ;\ set y position for new sprite
STA $00D8,y ; |ƒXƒvƒ‰ƒCƒg¶¬Žž‚ÌyÀ•W‚ð“ü—Í
LDA $14D4,x ; |‚±‚Ì—á‚Ìê‡AeƒXƒvƒ‰ƒCƒg‚Æ“¯‚¶ˆÊ’u‚ɶ¬‚µ‚Ä‚¢‚é
STA $14D4,y ; /
LDA $157C,x ; |Œü‚«‚àeƒXƒvƒ‰ƒCƒg‚Æ“¯‚¶Œü‚«‚É
STA $157C,y ; /
PHX
TYX
JSL $07F7D2 ;
PLX
RTS ; return
SUB_SMOKE LDY #$03
FINDFREE LDA $17C0,y
BEQ FOUNDONE
DEY
BPL FINDFREE
RTS
FOUNDONE LDA #$01 ;ƒXƒvƒ‰ƒCƒg‚ÌŽí—Þ
STA $17C0,y
LDA #$1B
STA $17CC,y ;ƒ^ƒCƒ}[
LDA $D8,x ;y˥W
CLC
ADC #$F3
STA $17C4,y
LDA $14C8,x
BNE NOT_DEATH_SMOKE
LDA $E4,x ;x˥W
STA $17C8,y
RTS
NOT_DEATH_SMOKE PHX
LDA $E4,x
PHA
LDA $157C,x
PHA
LDX #$00
PLA
BEQ NO_INX2
INX
NO_INX2 PLA
CLC
ADC SMOKE_X_OFFSET,x
STA $17C8,y
PLX
GFX_RETURN RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SUB_GFX JSL GET_DRAW_INFO ; YƒŒƒWƒXƒ^ = OAM offset
LDA $157C,x ; \ ƒXƒvƒ‰ƒCƒg‚ÌŒü‚«‚ð$02‚É‘ã“ü
STA $02 ; /
LDA $1504,x
LSR A ; | (1/2)
LSR A ; | (1/4)
LSR A ; | Œv1/8”{
AND #$01 ; | ‚±‚ê‚Å $00 ¨ $01 ¨ $00 ¨ $01 ‚Æ‚È‚éƒJƒEƒ“ƒ^‚É‚È‚é
ASL A ; | 2”{‚·‚é‚Æ $00 ¨ $02 ¨ $00 ¨ $02 ‚Æ‚È‚éƒJƒEƒ“ƒ^‚É‚È‚é
STA $03 ; / ‚±‚ê‚ð$03‚É‘ã“ü
PHX ; ƒ‹[ƒv‚ÉXƒŒƒWƒXƒ^‚ðŽg—p‚·‚é‚Ì‚ÅA•ÛŒì‚·‚é
LDX #$01 ; ƒ‹[ƒv‰ñ” = ƒ^ƒCƒ‹”(2) - 1 = 1
LOOP_START
LDA $00 ; \ XÀ•W‚Í‚±‚ê‚Ü‚Å’Ê‚è
STA $0300,y ; /
LDA Y_OFFSET,x ; \
CLC ; | ƒ^ƒCƒ‹ˆÊ’u(Šî€=00)‚ÉF0‚Æ00‚ð‘«‚·‚Æ
ADC $01 ; | ƒ^ƒCƒ‹ˆÊ’u‚ÍF0‚Æ00‚É‚È‚è‚Ü‚·‚Ë
STA $0301,y ; /
PHX
TXA ; X ¨ A(‚‚܂èƒCƒ“ƒfƒNƒX”Ô†‚ðA‚ÉŽ‚Á‚Ä‚‚é)
CLC ; \ A‚ɃJƒEƒ“ƒ^‚Ì•ª‚ð‘«‚µ‚Ä‚ ‚°‚Ü‚·
ADC $03 ; /
TAX ; A ¨ X(‘«‚µ‚½’l‚ð–ß‚·)
LDA TILEMAP,x ; \ ƒ^ƒCƒ‹ƒ}ƒbƒv‚ð‘ã“ü
STA $0302,y ; /
PLX
STX $05
PHX
LDX $15E9 ; ƒXƒvƒ‰ƒCƒg‚̃Cƒ“ƒfƒNƒX”Ô†‚ÉŠÖ‚·‚éRAM ‚±‚ꂪ‚È‚¢‚ƃpƒŒƒbƒg‚È‚Ç‚ª‚¨‚©‚µ‚‚È‚è‚Ü‚·
LDA $15F6,x ; ƒpƒŒƒbƒg
LDX $05
BNE NO_RED
LDA #$08
BRA NO_FLIP
NO_RED LDX $02 ; \ ‚±‚̃Xƒvƒ‰ƒCƒg‚ÌŒü‚«‚ðŒÄ‚Ño‚µ‚Ü‚·
BNE NO_FLIP ; | = 0(‰EŒü‚«)‚Å‚È‚¢‚È‚ç[NO_FLIP]‚Ɉړ®‚³‚¹‚Ü‚·
ORA #$40 ; | ¶Œü‚«‚Ìê‡Aƒ^ƒCƒ‹‚ð¶‰E”½“]‚³‚¹‚Ü‚·
NO_FLIP ORA $64 ; | ‰EŒü‚«‚Ȃ綉E”½“]‚ð‚¹‚¸‚É‚»‚Ì‚Ü‚Ü$0303,y‚É‘ã“ü‚µ‚Ü‚·
STA $0303,y ; / ƒ^ƒCƒ‹‘®«‚ð‘ã“ü
PLX
INY ; \
INY ; | ƒ‹[ƒv–ˆ‚Ƀ^ƒCƒ‹‚ÌRAM‚̃AƒhƒŒƒX‚ð‘‚â‚·
INY ; |
INY ; /
DEX ; \ ƒ‹[ƒv‚̈—‚Å‚±‚Ì‹Lq‚Í•K{‚Å‚·‚æ‚Ë
BPL LOOP_START ; /
PLX ; ƒ‹[ƒv‚ªI—¹‚µ‚½‚̂ŃCƒ“ƒfƒNƒX”Ô†‚ð–ß‚µ‚Ä‚ ‚°‚é
LDY #$02 ; ƒ^ƒCƒ‹ƒTƒCƒY‚ð16x16‚Å“ˆê
LDA #$01 ; ƒ^ƒCƒ‹”(2) - 1 = 1
JSL $01B7B3 ; ‰æ–ÊŠO‚Å•`ŽÊ‚µ‚È‚¢
RTS ; I—¹
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_HORZ_POS
; This routine determines which side of the sprite Mario is on. It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $03B817
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SUB_HORZ_POS LDY #$00 ;A:25D0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1020 VC:097 00 FL:31642
LDA $94 ;A:25D0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZCHC:1036 VC:097 00 FL:31642
SEC ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1060 VC:097 00 FL:31642
SBC $E4,x ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1074 VC:097 00 FL:31642
STA $0F ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1104 VC:097 00 FL:31642
LDA $95 ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1128 VC:097 00 FL:31642
SBC $14E0,x ;A:2500 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZcHC:1152 VC:097 00 FL:31642
BPL SPR_L16 ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1184 VC:097 00 FL:31642
INY ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1200 VC:097 00 FL:31642
SPR_L16 RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; off screen processing code - shared
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B83B
TABLE3 dcb $40,$B0
TABLE6 dcb $01,$FF
TABLE4 dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0
TABLE5 dcb $01,$FF,$01,$FF,$01,$00,$01,$FF
SUB_OFF_SCREEN_X0 LDA #$06 ; \ entry point of routine determines value of $03
BRA STORE_03 ; |
SUB_OFF_SCREEN_X1 LDA #$04 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X2 LDA #$02 ; |
STORE_03 STA $03 ; |
BRA START_SUB ; |
SUB_OFF_SCREEN_X3 STZ $03 ; /
START_SUB JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return
BEQ RETURN_2 ; /
LDA $5B ; \ goto VERTICAL_LEVEL if vertical level
AND #$01 ; |
BNE VERTICAL_LEVEL ; /
LDA $D8,x ; \
CLC ; |
ADC #$50 ; | if the sprite has gone off the bottom of the level...
LDA $14D4,x ; | (if adding 0x50 to the sprite y position would make the high byte >= 2)
ADC #$00 ; |
CMP #$02 ; |
BPL ERASE_SPRITE ; / ...erase the sprite
LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_2 ; /
LDA $13 ; \
AND #$01 ; |
ORA $03 ; |
STA $01 ; |
TAY ; /
LDA $1A
CLC
ADC TABLE4,y
ROL $00
CMP $E4,x
PHP
LDA $1B
LSR $00
ADC TABLE5,y
PLP
SBC $14E0,x
STA $00
LSR $01
BCC LABEL20
EOR #$80
STA $00
LABEL20 LDA $00
BPL RETURN_2
ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite
CMP #$08 ; |
BCC KILL_SPRITE ; /
LDY $161A,x
CPY #$FF
BEQ KILL_SPRITE
LDA #$00
STA $1938,y
KILL_SPRITE STZ $14C8,x ; erase sprite
RETURN_2 RTS ; return
VERTICAL_LEVEL LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_2 ; /
LDA $13 ; \ only handle every other frame??
LSR A ; |
BCS RETURN_2 ; /
AND #$01
STA $01
TAY
LDA $1C
CLC
ADC TABLE3,y
ROL $00
CMP $D8,x
PHP
LDA.W $001D
LSR $00
ADC TABLE6,y
PLP
SBC $14D4,x
STA $00
LDY $01
BEQ LABEL22
EOR #$80
STA $00
LABEL22 LDA $00
BPL RETURN_2
BMI ERASE_SPRITE
SUB_IS_OFF_SCREEN LDA $15A0,x ; \ if sprite is on screen, accumulator = 0
ORA $186C,x ; |
RTS ; / return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GET_DRAW_INFO
; This is a helper for the graphics routine. It sets off screen flags, and sets up
; variables. It will return with the following:
;
; Y = index to sprite OAM ($300)
; $00 = sprite x position relative to screen boarder
; $01 = sprite y position relative to screen boarder
; It is adapted from the subroutine at $03B760
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SPR_T1 dcb $0C,$1C
SPR_T2 dcb $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 ;
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 ; /
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 PLA ; \ return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
PLA
RTS ; /
Your layout has been removed.