I think its glitching after seven cycles, I think this is due to the fact that the character redefine is a lot faster than the scroll , addnext mountain and copy buffer to screen routines.
Interestingly,, if I add a delay in each cycle it actually looks smoother.
I'm playing around with a few things to see if I can make it better without breaking it
As you probably know that is harder than it sounds.
I've pasted the full asm code below which includes an experimental 1 pixel row coloring routine and also a currently unused player character keyboard and plotting rouitine.
Code: Select all
#define CHAR_BUF $B018
#define BUFFER_ADRESS ($afc8+40+26*40+38) ;last char pos of buffer
#define DISPLAY_ADRESS $BB80 ; start address of text screen
#define TERRAIN_CHARS $B400+97*8-1 ; memory location of 1st char to redefine
#define SRC_ADD $AFC8 ;first mem loc of buffer screen area
#define DEST_ADD ($Bb80+40) ;destination address to copy buffer to
#define SRC_ADD2 $AFC9 ; mem location of 2nd column of buffer to scroll into first
#define DEST_ADD2 $afc8 ;mem location of 1st column of buffer - gets 2nd column copied into here to achieve scroll
#define COL1_START $afc8 ; mem location of first column of buffer to set paper attributes
#define COL2_START $afc9 ; mem location of 2nd column of buffer to set ink attributes
#define CURRENT_TERRAIN $09 ; zero page to track current definition of terrain
#define CUR_X $08
#define CUR_Y $07
#define blankchar #32 ;ASCII code of characters to use.
#define charblankb4up #97 ; first non-blank char , used with TERRAIN_CHARS to set what characters to redefine
#define charup #98
#define charsolid #99
#define charb4down #100
#define chardown #101
#define spcafter #32
#define hirescol1 $a000 ;mem location of 1st column of hires screen area - experimental coloring
.text
mainprog
.(
jsr clrscreen
;lda #<CHAR_BUF
;sta putscrn+1
;lda #>CHAR_BUF
;sta putscrn+2
;ldx #84
;stx $04
;jsr add
;lda #02
;sta $02
;lda #04
;sta $03
lda #01
sta $024e
lda #01
sta $024f
lda #10
sta $26a
starter
ldx #00
stx $01
;lda #$58
;sta $05
lda #00
sta CURRENT_TERRAIN
jsr defchars
bigloop
lda CURRENT_TERRAIN
cmp #00
bne sc3 ; if current terrain is not 0 then dont scroll just redefine characters
jsr _scroll ; scroll buffer
jsr _buff2scrn ; copy buffer to screen
jsr defchars ; redefine characters
jsr _nextmount ; add next moutain column to buffer
jmp endscroll
sc3
jsr defchars ; redefine characters
endscroll
;jsr chkkey ;future keyboard and player movement controls
inc CURRENT_TERRAIN
cmp #07
bne noreset
lda #00 ;reset terrain flag if 7
sta CURRENT_TERRAIN
noreset
inc $01
ldx $01
cpx #255
bne bigloop
jmp starter
rts
chkkey
lda $2df
beq nokey
lda #00
sta $2df
lda $208
and #$7f
cmp #56
beq nokey
cmp #03
beq left
cmp #46
beq up
cmp #15
beq right
cmp #42
beq down
rts
nokey
rts
left
ldy $02
cpy #02
beq nokey
lda #32
sta $05
jsr display
dec $02
ldx #01
stx $04
jsr sub
lda #$58
sta $05
jsr display
rts
right
ldy $02
cpy #39
beq nokey
lda #32
sta $05
jsr display
inc $02
ldx #01
stx $04
jsr add
lda #$58
sta $05
jsr display
rts
up
ldx $03
cpx #02
beq nokey
lda #32
sta $05
jsr display
dec $03
ldx #40
stx $04
jsr sub
lda #$58
sta $05
jsr display
rts
down
ldx $03
cpx #27
beq nokey
lda #32
sta $05
jsr display
inc $03
ldx #40
stx $04
jsr add
lda #$58
sta $05
jsr display
rts
display
lda #04
jsr putscrn
ldx #01
stx $04
jsr add
lda $05
jsr putscrn
jsr add
ldx $03
lda inks,x
jsr putscrn
ldx #03
stx $04
jsr sub
rts
putscrn
sta $0123
rts
add
clc
lda putscrn+1
adc $04
sta putscrn+1
lda putscrn+2
adc #00
sta putscrn+2
rts
sub
sec
lda putscrn+1
sbc $04
sta putscrn+1
lda putscrn+2
sbc #00
sta putscrn+2
rts
.)
_nextmount
.(
lda #<BUFFER_ADRESS ; End column to add mountain to
sta write+1
lda #>BUFFER_ADRESS
sta write+2
ldy #26 ;load y with number of rows to loop
loop
addblock ;calc inverts the height so can use logical numbers in heights table
sty CUR_Y ;current height to check
ldx CUR_X ;current heights table position
clc
lda heights,x
eor #255
sec
adc #26
cmp CUR_Y
beq testnext
bcs lookforup ; y is less than height look if next block is an up
bcc lookfordown ; y is greater than height ie plot something
lookforup
ldx CUR_X
inx
clc
lda heights,x
eor #255
sec
adc #26
cmp CUR_Y
beq b4up
jmp noc
lookfordown
ldx CUR_X
inx
clc
lda heights,x
eor #255
sec
adc #26
cmp CUR_Y
beq sb4d
jmp sol
smallloop
jmp loop
testprev
ldx CUR_X
dex
clc
lda heights,x
eor #255
sec
adc #26
cmp CUR_Y
bcs sb4d
jmp noc
testnext
ldx CUR_X
inx
clc
lda heights,x
eor #255
sec
adc #26
cmp CUR_Y
beq sol
bcs dnc
bcc upc
jmp write
b4up
lda charblankb4up
jmp write
sol
lda charsolid
jmp write
sb4d
lda charb4down
jmp write
upc
lda charup
jmp write
dnc
lda chardown
jmp write
noc
lda blankchar
jmp write
write
sta $0123
decrem
sec ; Calc new buffer adress
lda write+1
sbc #40
sta write+1
lda write+2
sbc #0
sta write+2
dey
bne smallloop
inc CUR_X
lda CUR_X
cmp #62
bne skip2
ldx #00
stx CUR_X
skip2
rts
.)
_buff2scrn ;routine to copy buffer to screen
.(
lda #<SRC_ADD ;set our source memory address to copy from
sta $FB
lda #>SRC_ADD
sta $FC
lda #<DEST_ADD ;set our destination memory to copy to
sta $FD
lda #>DEST_ADD
sta $FE
ldy #$00 ;reset x and y for our loop
ldx #$05
Loop
lda ($FB),Y ;indirect index source memory address, starting at $00
sta ($FD),Y ;indirect index dest memory address, starting at $00
iny
bne Loop ;loop until our dest goes over 255
inc $FC ;increment high order source memory address, starting at $80
inc $FE ;increment high order dest memory address, starting at $60
dex
bne Loop ;
rts
.)
_copyback ;routine to copy screen to buffer after a clearscreen
.(
lda #<DEST_ADD ;set our source memory address to copy from, bb80
sta $FB
lda #>DEST_ADD
sta $FC
lda #<SRC_ADD;set our destination memory to copy to, $00, WRAM afc8
sta $FD
lda #>SRC_ADD
sta $FE
ldy #$00 ;reset x and y for our loop
ldx #$04
Loop
lda ($FB),Y
sta ($FD),Y
iny
bne Loop ;loop until our dest goes over 255
inc $FC
inc $FE
dex
bne Loop
rts
.)
_scroll ; scroll routine, copies all rows starting at column 2 left by 1 char position
.(
lda #<SRC_ADD2
sta $FB
lda #>SRC_ADD2
sta $FC
lda #<DEST_ADD2
sta $FD
lda #>DEST_ADD2
sta $FE
ldy #$00 ;reset x and y for our loop
ldx #$05
Loop:
lda ($FB),Y
sta ($FD),Y
iny
bne Loop ;loop until our dest goes over 255
inc $FC
inc $FE
dex
bne Loop ;
jsr _resetatt ;reset paper attributes after scroll
jsr _resetatt2 ;reset ink attributes after scroll
;jsr _resetatt3 ;experimental hires ink colourings, comment out above line and uncomment this to use
rts
.)
_resetatt ; put paper attribute based on papers table into 1st column of buffer after a scroll
.(
lda #<COL1_START
sta paperadd+1
lda #>COL1_START
sta paperadd+2
ldy #27 ;load y with number of rows to loop
loop
lda papers,y
paperadd
sta $0123
increm
clc ; Calc new buffer adress
lda paperadd+1
adc #40
sta paperadd+1
lda paperadd+2
adc #0
sta paperadd+2
dey
bne loop
rts
.)
_resetatt2 ; put ink attribute based on inks table into 2nd column of buffer after a scroll
.(
lda #<COL2_START
sta inkadd+1
lda #>COL2_START
sta inkadd+2
ldy #27 ;load y with number of rows to loop
loop
lda inks,y
inkadd
sta $0123
increm
clc ; Calc new buffer adress
lda inkadd+1
adc #40
sta inkadd+1
lda inkadd+2
adc #0
sta inkadd+2
dey
bne loop
rts
.)
_resetatt3 ;experimental mixing of text and hires attributes for single pixel row coloring
.(
lda #<COL2_START
sta inkadd2+1
lda #>COL2_START
sta inkadd2+2
lda #<hirescol1+1 ;3rd column of hires memory area
sta inkadd3+1
lda #>hirescol1+1
sta inkadd3+2
ldy #27 ;load y with number of rows to loop
loop
lda #30 ;hires attribute in 2nd column (paper attribute in 1st column)
jsr inkadd2
clc ; Calc new buffer adress
lda inkadd2+1
adc #40
sta inkadd2+1
lda inkadd2+2
adc #0
sta inkadd2+2
dey
bne loop
ldy #0
loop2
clc ; Calc new buffer adress
lda inkadd3+1
adc #01
sta inkadd3+1
lda inkadd3+2
adc #0
sta inkadd3+2
lda inks2,y
jsr inkadd3 ;put attribute in current row
clc ; add 1 to column to set back to text
lda inkadd3+1
adc #01
sta inkadd3+1
lda inkadd3+2
adc #0
sta inkadd3+2
lda #26 ;text mode attribute
jsr inkadd3
clc
lda inkadd3+1 ;add 38 to goto next row
adc #38
sta inkadd3+1
lda inkadd3+2
adc #0
sta inkadd3+2
iny
cpy #175
bne loop2
rts
inkadd2
sta $0123
rts
inkadd3
sta $0234
rts
.)
defchars
.(
ldy #40
lda CURRENT_TERRAIN
cmp #00 ; check current terain flag and jump to relevant redefine routine
beq tloop1
cmp #01
beq tloop2
cmp #02
beq tloop3
cmp #03
beq tloop4
cmp #04
beq tloop5
cmp #05
beq tloop6
cmp #06
beq tloop7
rts
tloop1
lda terraindata1,Y
sta TERRAIN_CHARS,Y
dey
tya
beq enddef
jmp tloop1
tloop2
lda terraindata2,Y
sta TERRAIN_CHARS,Y
dey
tya
beq enddef
jmp tloop2
tloop3
lda terraindata3,Y
sta TERRAIN_CHARS,Y
dey
tya
beq enddef
jmp tloop3
tloop4
lda terraindata4,Y
sta TERRAIN_CHARS,Y
dey
tya
beq enddef
jmp tloop4
tloop5
lda terraindata5,Y
sta TERRAIN_CHARS,Y
dey
tya
beq enddef
jmp tloop5
tloop6
lda terraindata6,Y
sta TERRAIN_CHARS,Y
dey
tya
beq enddef
jmp tloop6
tloop7
lda terraindata7,Y
sta TERRAIN_CHARS,Y
dey
tya
bne tloop7
enddef
rts
.)
clrscreen ; clears text screen
.(
lda #<DISPLAY_ADRESS
sta write2+1
lda #>DISPLAY_ADRESS
sta write2+2
ldy #26 ;row to loop
clearloop2
ldx #38 ;cols to loop
clearloop1
lda #32 ;ASCII of char to write to screen
jsr write2
clc
lda write2+1
adc #1
sta write2+1
lda write2+2
adc #0
sta write2+2
dex
bne clearloop1
clc
lda write2+1
adc #2
sta write2+1
lda write2+2
adc #0
sta write2+2
dey
bne clearloop2
jsr _copyback
rts
write2
sta $0123
rts
.)
; various tables for mountain heights, paper colors, ink colors, and terrain character definitions
heights
.byt 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,7,8,9,10,11,12,13,12,11,10,9,8,7,8,9,10,11,11,12,13,14,13,12,11,10,9,8,7,6,5,6,5
papers
.byt 0,0,0,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22 ;first entry is bottom row
inks
.byt 0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7
; below is a table for the experimental hires row coloring
inks2
.byt 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,4,5,6,7,7,6,5,6,7,5,4,3,2,3,4,6,2,4,5,5,5,6,7,5,3,2,4,5,7
terraindata1
.byt 0,0,0,0,0,0,0,0,0 ;33
.byt 1,3,7,15,31,31,63,63 ;34
.byt 63,63,63,63,63,63,63,63 ;35
.byt 63,63,63,63,63,63,63,63 ;36
.byt 32,48,56,60,62,62,63,63 ;37
terraindata2
.byt 0,0,0,0,0,0,0,1,1
.byt 3,7,15,31,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 0,32,48,56,60,60,62,62
terraindata3
.byt 0,0,0,0,0,1,1,3,3
.byt 7,15,31,63,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 62,63,63,63,63,63,63,63
.byt 0,0,32,48,56,56,60,60
terraindata4
.byt 0,0,0,0,1,3,3,7,7
.byt 15,31,63,63,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 60,62,63,63,63,63,63,63
.byt 0,0,0,32,48,48,56,56
terraindata5
.byt 0,0,0,1,3,7,7,15,15
.byt 31,63,63,63,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 56,60,62,63,63,63,63,63
.byt 0,0,0,0,32,32,48,48
terraindata6
.byt 0,0,1,3,7,15,15,31,31
.byt 63,63,63,63,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 48,56,60,62,63,63,63,63
.byt 0,0,0,0,0,0,32,32
terraindata7
.byt 0,1,3,7,15,31,31,63,63
.byt 63,63,63,63,63,63,63,63
.byt 63,63,63,63,63,63,63,63
.byt 32,48,56,60,62,62,63,63
.byt 0,0,0,0,0,0,0,0