HERE'S THE CODE:
Code: Select all
NMI:
INC scroll
; add one to our scroll variable each frame
NTSwapCheck:
LDA scroll ; check if the scroll just wrapped from 255 to 0
BNE NTSwapCheckP2
NTSwap:
LDA nametable ; load current nametable number (0 or 1)
EOR #$01 ; exclusive OR of bit 0 will flip that bit
STA nametable ; so if nametable was 0, now 1
; if nametable was 1, now 0
NTSwapCheckP2:
NTSwapCheckP2:
LDA scrolly ; check if the scroll just wrapped from 255 to 0
BNE NTSwapCheckP3
NTSwap2:
LDA nametabley ; load current nametable number (0 or 1)
EOR #$01 ; exclusive OR of bit 0 will flip that bit
STA nametabley ; so if nametable was 0, now 1
NTSwapCheckP3:
NewAttribCheck:
LDA scroll
AND #%00011111 ; check for multiple of 32
BNE NewAttribCheckDone ; if low 5 bits = 0, time to write new attribute bytes
jsr DrawNewAttributes
NewAttribCheckDone:
NewColumnCheck:
LDA scroll
AND #%00000111 ; throw away higher bits to check for multiple of 8
BNE NewColumnCheckDone ; done if lower bits != 0
JSR DrawNewColumn ; if lower bits = 0, time for new column
lda columnNumber
CMP #$FE
BCC DT9
LDA #$00
STA scroll+2
DT9:
lda columnNumber
clc
adc #$01 ; go to next column
and #%11111111 ; only 256 columns of data, throw away top bit to wrap
sta columnNumber
lda scroll+2
clc
adc #$01
STA scroll+2
JSR Scrollcheck
NewColumnCheckDone:
LDA #$00
STA $2003
LDA #$02
STA $4014 ; sprite DMA from $0200
JSR LoadPalettes2
LDA #$00
STA $2006 ; clean up PPU address registers
STA $2006
LDA scroll
STA $2005 ; write the horizontal scroll count register
LDA scrolly ; no vertical scrolling
STA $2005
;;This is the PPU clean up section, so rendering the next frame starts properly.
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
ORA nametable ; select correct nametable for bit 0
STA $2000
LDA #%00011110 ; enable sprites, enable background, no clipping on left side
STA $2001
JSR Updating
JSR Gravity
JSR ReadController1
LDA #$00
STA T
LDA #$00
STA D
LDA #$00
STA D+1
LDA buttons
AND #%10000000 ; only look at bit 0
BEQ ReadADone ; branch to ReadADone if button is NOT pressed (0)
LDA JumpState
CMP #$01
BCS ReadADone
LDA #$01
STA JumpState
; save sprite X position
ReadADone:
LDA buttons
AND #%00000001 ; only look at bit 0
BEQ ReadRightDone ; branch to ReadADone if button is NOT pressed (0)
LDA #$01
STA D
LDA player
CLC
ADC #$01
STA player
LDA #$00
STA pdirection
LDA #$01
STA T
; save sprite X position
ReadRightDone:
LDA buttons
AND #%00000010 ; only look at bit 0
BEQ ReadLeftDone ; branch to ReadADone if button is NOT pressed (0)
LDA player
SEC
SBC #$01
STA player
LDA #$01
STA pdirection
LDA #$01
STA T
; save sprite X position
ReadLeftDone:
LDA buttons
AND #%00100000 ; only look at bit 0
BEQ ReadUpDone
LDA buttons
AND #%00010000
LDA gamestate
CLC
ADC #$01
STA gamestate
ReadUpDone:
; run normal game engine code here
; reading from controllers, etc
RTI ; return from interrupt
DrawNewColumn:
LDA scroll ; calculate new column address using scroll register
LSR A
LSR A
LSR A ; shift right 3 times = divide by 8
STA columnLow ; $00 to $1F, screen is 32 tiles wide
LDA nametable ; calculate new column address using current nametable
EOR #$01 ; invert low bit, A = $00 or $01
ASL A ; shift up, A = $00 or $02
ASL A ; $00 or $04
CLC
ADC #$20 ; add high byte of nametable base address ($2000) can change to lower name table $2000 = ADC #$20 $2800 = ADC #$28
STA columnHigh ; now address = $20 or $24 for nametable 0 or 1
LDA columnNumber ; column number * 32 = column data offset
ASL A
ASL A
ASL A
ASL A
ASL A
STA sourceLow
LDA columnNumber
LSR A
LSR A
LSR A
STA sourceHigh
JSR levelselect
DrawColumn:
LDA #%00000100 ; set to increment +32 mode
STA $2000
LDA $2002 ; read PPU status to reset the high/low latch
LDA columnHigh
STA $2006 ; write the high byte of column address
LDA columnLow
STA $2006 ; write the low byte of column address
LDX #$1E ; copy 30 bytes
LDY #$1E
DrawColumnLoop:
LDA [sourceLow], y
STA $2007
INY
DEX
BNE DrawColumnLoop
DrawNewColumn2:
LDA scroll ; calculate new column address using scroll register
LSR A
LSR A
LSR A ; shift right 3 times = divide by 8
STA columnLow2 ; $00 to $1F, screen is 32 tiles wide
LDA nametable ; calculate new column address using current nametable
EOR #$01 ; invert low bit, A = $00 or $01
ASL A ; shift up, A = $00 or $02
ASL A ; $00 or $04
CLC
ADC #$28 ; add high byte of nametable base address ($2000) can change to lower name table $2000 = ADC #$20 $2800 = ADC #$28 changes what loads the name table in the bottem name table in
STA columnHigh ; now address = $20 or $24 for nametable 0 or 1
LDA columnNumber2 ; column number * 32 = column data offset
ASL A
ASL A
ASL A
ASL A
ASL A
STA sourceLow2
LDA columnNumber
LSR A
LSR A
LSR A
STA sourceHigh2
LDA sourceLow ; column data start + offset = address to load column data from
CLC
ADC #$04
STA sourceLow2
LDA sourceHigh
ADC #$04
STA sourceHigh2
DrawColumn2:
LDA #%00000100 ; set to increment +32 mode
STA $2000
LDA $2002 ; read PPU status to reset the high/low latch
LDA columnHigh
STA $2006 ; write the high byte of column address
LDA columnLow
STA $2006 ; write the low byte of column address
LDX #$1E ; copy 30 bytes
LDY #$1E
DrawColumnLoop2:
LDA [sourceLow2], y
STA $2007
INY
DEX
BNE DrawColumnLoop2
RTS
DrawNewAttributes:
LDA nametable
EOR #$01 ; invert low bit, A = $00 or $01
ASL A ; shift up, A = $00 or $02
ASL A ; $00 or $04
CLC
ADC #$23 ; add high byte of attribute base address ($23C0)
STA columnHigh ; now address = $23 or $27 for nametable 0 or 1
LDA scroll
LSR A
LSR A
LSR A
LSR A
LSR A
CLC
ADC #$C0
STA columnLow ; attribute base + scroll / 32
LDA columnNumber ; (column number / 4) * 8 = column data offset
AND #%11111100
ASL A
STA sourceLow
LDA columnNumber
LSR A
LSR A
LSR A
LSR A
LSR A
LSR A
LSR A
STA sourceHigh
LDA sourceLow ; column data start + offset = address to load column data from
CLC
ADC #LOW(attribData)
STA sourceLow
LDA sourceHigh
ADC #HIGH(attribData)
STA sourceHigh
LDY #$00
LDA $2002 ; read PPU status to reset the high/low latch
DrawNewAttributesLoop
LDA columnHigh
STA $2006 ; write the high byte of column address
LDA columnLow
STA $2006 ; write the low byte of column address
LDA [sourceLow], y ; copy new attribute byte
STA $2007
INY
CPY #$08 ; copy 8 attribute bytes
BEQ DrawNewAttributesLoopDone
LDA columnLow ; next attribute byte is at address + 8
CLC
ADC #$08
STA columnLow
JMP DrawNewAttributesLoop
DrawNewAttributesLoopDone:
RTS
DrawNewAttributes2:
LDA nametable
EOR #$01 ; invert low bit, A = $00 or $01
ASL A ; shift up, A = $00 or $02
ASL A ; $00 or $04
CLC
ADC #$23 ; add high byte of attribute base address ($23C0)
STA columnHigh ; now address = $23 or $27 for nametable 0 or 1
LDA scroll
LSR A
LSR A
LSR A
LSR A
LSR A
CLC
ADC #$C0
STA columnLow ; attribute base + scroll / 32
LDA columnNumber ; (column number / 4) * 8 = column data offset
AND #%11111100
ASL A
STA sourceLow
LDA columnNumber
LSR A
LSR A
LSR A
LSR A
LSR A
LSR A
LSR A
STA sourceHigh
LDA sourceLow ; column data start + offset = address to load column data from
CLC
ADC #$04
STA sourceLow2
LDA sourceHigh
ADC #$04
STA sourceHigh2
LDY #$00
LDA $2002 ; read PPU status to reset the high/low latch
DrawNewAttributesLoop2
LDA columnHigh2
STA $2006 ; write the high byte of column address
LDA columnLow
STA $2006 ; write the low byte of column address
LDA [sourceLow2], y ; copy new attribute byte
STA $2007
INY
CPY #$08 ; copy 8 attribute bytes
BEQ DrawNewAttributesLoopDone2
LDA columnLow2 ; next attribute byte is at address + 8
CLC
ADC #$08
STA columnLow2
JMP DrawNewAttributesLoop2
DrawNewAttributesLoopDone2:
rts
; skip the update function
LoadPalettes2:
LDA #$00
STA Timer1+5
LDA #$00
STA Timer1+6
LDX #$00
LP2:
LDA #$3F
STA $2006
LDA Timer1+6
STA $2006
LDA paletteswap , x
STA $2007
INX
INC Timer1+5
INC Timer1+6
LDA Timer1+5
CMP #$20
BEQ Fin
JMP LP2
Fin:
RTS
https://wiki.nesdev.com/w/index.php/The_frame_and_NMIs
And I don't Understand what he mean to do for lda needppureg
Please first explain what the problem is before showing the code.
Thanks.