Originally posted by: siudym
Hi,
I have a problem with background animation. Mapper is UNROM, so the animation is changing the tiles in VRAM (NameTable)
Unfortunately, the method is poor and takes a lot of NMI time. How do you animate background elements (change BGR tiles numbers in VRAM) to minimize the VBLANK time (NMI)?
The code that is used for the animation:
[code]
;------------------------------------
BGR_Anim: ;in the NMI loop
INC Anim_Timer ;timer
INC Anim_Timer
INC Anim_Timer
INC Anim_Timer
LDA Anim_Timer
CMP #$00
BCC skip1
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE1_AddrLO
STA $2006
lda #$10 ;pattern table bgr tile1 nr.
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE2_AddrLO
STA $2006
lda #$11 ;pattern table bgr tile2 nr.
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE3_AddrLO
STA $2006
lda #$20 ;pattern table bgr tile3 nr.
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE4_AddrLO
STA $2006
lda #$21 ;pattern table bgr tile4 nr.
sta $2007
LDA #$00 ;reset screen
STA $2006
LDA #$00
STA $2006
skip1:
LDA Anim_Timer
CMP #$40
BCC skip2
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE1_AddrLO
STA $2006
lda #$12
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE2_AddrLO
STA $2006
lda #$13
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE3_AddrLO
STA $2006
lda #$22
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE4_AddrLO
STA $2006
lda #$23
sta $2007
LDA #$00
STA $2006
LDA #$00
STA $2006
skip2:
LDA Anim_Timer
CMP #$80
BCC skip3
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE1_AddrLO
STA $2006
lda #$14
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE2_AddrLO
STA $2006
lda #$15
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE3_AddrLO
STA $2006
lda #$24
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE4_AddrLO
STA $2006
lda #$25
sta $2007
LDA #$00
STA $2006
LDA #$00
STA $2006
skip3:
LDA Anim_Timer
CMP #$C0
BCC skip4
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE1_AddrLO
STA $2006
lda #$12
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE2_AddrLO
STA $2006
lda #$13
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE3_AddrLO
STA $2006
lda #$22
sta $2007
LDA BGR_NT_TILE1_AddrHI
STA $2006
LDA BGR_NT_TILE4_AddrLO
STA $2006
lda #$23
sta $2007
LDA #$00
STA $2006
LDA #$00
STA $2006
skip4:
RTS
[/code]
after branching on Anim_Timer, and executing the corresponding code, you don't skip the rest of the code.
You should do something like this :
lda Anim_Timer
; cmp#$00 ; not needed
beq anim1
cmp #$40
beq anim2
cmp #$80
beq anim3
cmp #$C0
beq anim4
jmp skipAnimation
anim1:
; anim 1 code here
jmp skipAnimation
anim2:
; anim 2 code here
jmp skipAnimation
anim3:
; anim 3 code here
jmp skipAnimation
anim4:
; anim 4 code here
skipAnimation:
Note that I'm using BEQ and not BCC to check Anim_Timer state and update only once the NT.
Also you can replace this :
LDA #$00
STA $2006
LDA #$00
STA $2006
by this :
LDA #$00
STA $2006
STA $2006
and this :
INC Anim_Timer ;timer
INC Anim_Timer
INC Anim_Timer
INC Anim_Timer
by this :
lda Anim_Timer
clc
adc #$04
sta Anim_Timer
to gain cycles and ROM bytes.
Hope it helps !