vs: some work on vertical scrolling

This commit is contained in:
Vince Weaver 2020-02-17 13:41:01 -05:00
parent 744f3f9a64
commit b7e70b388c
10 changed files with 841 additions and 0 deletions

43
vertical_scroll/Makefile Normal file
View File

@ -0,0 +1,43 @@
include ../Makefile.inc
DOS33 = ../dos33fs-utils/dos33
PNG_TO_40x96 = ../gr-utils/png_to_40x96
PNG_TO_40x48D = ../gr-utils/png_to_40x48d
PNG2RLE = ../gr-utils/png2rle
all: scroller.dsk
scroller.dsk: HELLO SCROLLER
cp empty.dsk scroller.dsk
$(DOS33) -y scroller.dsk SAVE A HELLO
$(DOS33) -y scroller.dsk BSAVE -a 0x1000 SCROLLER
###
HELLO: hello.bas
../asoft_basic-utils/tokenize_asoft < hello.bas > HELLO
####
SCROLLER: scroller.o
ld65 -o SCROLLER scroller.o -C ../linker_scripts/apple2_1000.inc
scroller.o: scroller.s gr_copy.s gr_unrle.s gr_unrle_large.s \
gr_copy_large.s \
zp.inc hardware.inc desire.inc spaceman.inc
ca65 -o scroller.o scroller.s -l scroller.lst
####
desire.inc: desire.png desire2.png
$(PNG2RLE) asm desire.png desire_rle > desire.inc
$(PNG2RLE) asm desire2.png desire2_rle >> desire.inc
spaceman.inc: spaceman_big.png
$(PNG2RLE) asm spaceman_big.png spaceman_rle > spaceman.inc
####
clean:
rm -f *~ *.o *.lst SCROLLER

161
vertical_scroll/gr_copy.s Normal file
View File

@ -0,0 +1,161 @@
;=========================================================
; gr_copy_to_current, 40x48 version
;=========================================================
; copy 0xc00 to DRAW_PAGE
;
; 45 + 2 + 120*(8*9 + 5) -1 + 6 = 9292
;.align $100
gr_copy_to_current:
lda DRAW_PAGE ; 3
clc ; 2
adc #$4 ; 2
sta gr_copy_line+5 ; 4
sta gr_copy_line+11 ; 4
adc #$1 ; 2
sta gr_copy_line+17 ; 4
sta gr_copy_line+23 ; 4
adc #$1 ; 2
sta gr_copy_line+29 ; 4
sta gr_copy_line+35 ; 4
adc #$1 ; 2
sta gr_copy_line+41 ; 4
sta gr_copy_line+47 ; 4
;===========
; 45
ldy #119 ; for early ones, copy 120 bytes ; 2
gr_copy_line:
lda $C00,Y ; load a byte (self modified) ; 4
sta $400,Y ; store a byte (self modified) ; 5
lda $C80,Y ; load a byte (self modified) ; 4
sta $480,Y ; store a byte (self modified) ; 5
lda $D00,Y ; load a byte (self modified) ; 4
sta $500,Y ; store a byte (self modified) ; 5
lda $D80,Y ; load a byte (self modified) ; 4
sta $580,Y ; store a byte (self modified) ; 5
lda $E00,Y ; load a byte (self modified) ; 4
sta $600,Y ; store a byte (self modified) ; 5
lda $E80,Y ; load a byte (self modified) ; 4
sta $680,Y ; store a byte (self modified) ; 5
lda $F00,Y ; load a byte (self modified) ; 4
sta $700,Y ; store a byte (self modified) ; 5
lda $F80,Y ; load a byte (self modified) ; 4
sta $780,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line ; ; 2nt/3
rts ; 6
;=========================================================
; gr_copy_to_current, 40x48 version
;=========================================================
; copy 0x1000 to DRAW_PAGE
gr_copy_to_current_1000:
lda DRAW_PAGE ; 3
clc ; 2
adc #$4 ; 2
sta gr_copy_line_40+5 ; 4
sta gr_copy_line_40+11 ; 4
adc #$1 ; 2
sta gr_copy_line_40+17 ; 4
sta gr_copy_line_40+23 ; 4
adc #$1 ; 2
sta gr_copy_line_40+29 ; 4
sta gr_copy_line_40+35 ; 4
adc #$1 ; 2
sta gr_copy_line_40+41 ; 4
sta gr_copy_line_40+47 ; 4
;===========
; 45
ldy #119 ; for early ones, copy 120 bytes ; 2
gr_copy_line_40:
lda $1000,Y ; load a byte (self modified) ; 4
sta $400,Y ; store a byte (self modified) ; 5
lda $1080,Y ; load a byte (self modified) ; 4
sta $480,Y ; store a byte (self modified) ; 5
lda $1100,Y ; load a byte (self modified) ; 4
sta $500,Y ; store a byte (self modified) ; 5
lda $1180,Y ; load a byte (self modified) ; 4
sta $580,Y ; store a byte (self modified) ; 5
lda $1200,Y ; load a byte (self modified) ; 4
sta $600,Y ; store a byte (self modified) ; 5
lda $1280,Y ; load a byte (self modified) ; 4
sta $680,Y ; store a byte (self modified) ; 5
lda $1300,Y ; load a byte (self modified) ; 4
sta $700,Y ; store a byte (self modified) ; 5
lda $1380,Y ; load a byte (self modified) ; 4
sta $780,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line_40 ; ; 2nt/3
rts ; 6
;=========================================================
; gr_copy_to_current_40x40
;=========================================================
; Take image in 0xc00
; Copy to DRAW_PAGE
; Actually copy lines 0..39
; Don't over-write bottom 4 lines of text
gr_copy_to_current_40x40:
ldx #0
gc_40x40_loop:
lda gr_offsets,x
sta OUTL
sta INL
lda gr_offsets+1,x
clc
adc DRAW_PAGE
sta OUTH
lda gr_offsets+1,x
clc
adc #$8
sta INH
ldy #39
gc_40x40_inner:
lda (INL),Y
sta (OUTL),Y
dey
bpl gc_40x40_inner
inx
inx
cpx #40
bne gc_40x40_loop
rts ; 6

View File

@ -0,0 +1,136 @@
;=========================================================
; gr_copy_to_current, large, 40x48 version
;=========================================================
; copy A000 to DRAW_PAGE
;
gr_copy_to_current_large:
lda DRAW_PAGE ; 3
clc ; 2
adc #$4 ; 2
sta gr_copy_line_large+5 ; 4
sta gr_copy_line_large+11 ; 4
sta gr_copy_line_large2+5 ; 4
sta gr_copy_line_large2+11 ; 4
sta gr_copy_line_large3+5 ; 4
sta gr_copy_line_large3+11 ; 4
adc #$1 ; 2
sta gr_copy_line_large+17 ; 4
sta gr_copy_line_large+23 ; 4
sta gr_copy_line_large2+17 ; 4
sta gr_copy_line_large2+23 ; 4
sta gr_copy_line_large3+17 ; 4
sta gr_copy_line_large3+23 ; 4
adc #$1 ; 2
sta gr_copy_line_large+29 ; 4
sta gr_copy_line_large+35 ; 4
sta gr_copy_line_large2+29 ; 4
sta gr_copy_line_large2+35 ; 4
sta gr_copy_line_large3+29 ; 4
sta gr_copy_line_large3+35 ; 4
adc #$1 ; 2
sta gr_copy_line_large+41 ; 4
sta gr_copy_line_large+47 ; 4
sta gr_copy_line_large2+41 ; 4
sta gr_copy_line_large2+47 ; 4
sta gr_copy_line_large3+41 ; 4
sta gr_copy_line_large3+47 ; 4
;===========
; 45
ldy #39 ; for early ones, copy 120 bytes ; 2
gr_copy_line_large:
lda $A000,Y ; load a byte (self modified) ; 4
sta $400,Y ; store a byte (self modified) ; 5
lda $A028,Y ; load a byte (self modified) ; 4
sta $480,Y ; store a byte (self modified) ; 5
lda $A050,Y ; load a byte (self modified) ; 4
sta $500,Y ; store a byte (self modified) ; 5
lda $A078,Y ; load a byte (self modified) ; 4
sta $580,Y ; store a byte (self modified) ; 5
lda $A0A0,Y ; load a byte (self modified) ; 4
sta $600,Y ; store a byte (self modified) ; 5
lda $A0C8,Y ; load a byte (self modified) ; 4
sta $680,Y ; store a byte (self modified) ; 5
lda $A0F0,Y ; load a byte (self modified) ; 4
sta $700,Y ; store a byte (self modified) ; 5
lda $A118,Y ; load a byte (self modified) ; 4
sta $780,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line_large ; ; 2nt/3
ldy #39 ; for early ones, copy 120 bytes ; 2
gr_copy_line_large2:
lda $A140,Y ; load a byte (self modified) ; 4
sta $428,Y ; store a byte (self modified) ; 5
lda $A168,Y ; load a byte (self modified) ; 4
sta $4A8,Y ; store a byte (self modified) ; 5
lda $A190,Y ; load a byte (self modified) ; 4
sta $528,Y ; store a byte (self modified) ; 5
lda $A1B8,Y ; load a byte (self modified) ; 4
sta $5A8,Y ; store a byte (self modified) ; 5
lda $A1E0,Y ; load a byte (self modified) ; 4
sta $628,Y ; store a byte (self modified) ; 5
lda $A208,Y ; load a byte (self modified) ; 4
sta $6A8,Y ; store a byte (self modified) ; 5
lda $A230,Y ; load a byte (self modified) ; 4
sta $728,Y ; store a byte (self modified) ; 5
lda $A258,Y ; load a byte (self modified) ; 4
sta $7A8,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line_large2 ; ; 2nt/3
ldy #39 ; for early ones, copy 120 bytes ; 2
gr_copy_line_large3:
lda $A280,Y ; load a byte (self modified) ; 4
sta $450,Y ; store a byte (self modified) ; 5
lda $A2A8,Y ; load a byte (self modified) ; 4
sta $4D0,Y ; store a byte (self modified) ; 5
lda $A2D0,Y ; load a byte (self modified) ; 4
sta $550,Y ; store a byte (self modified) ; 5
lda $A2F8,Y ; load a byte (self modified) ; 4
sta $5D0,Y ; store a byte (self modified) ; 5
lda $A320,Y ; load a byte (self modified) ; 4
sta $650,Y ; store a byte (self modified) ; 5
lda $A348,Y ; load a byte (self modified) ; 4
sta $6D0,Y ; store a byte (self modified) ; 5
lda $A370,Y ; load a byte (self modified) ; 4
sta $750,Y ; store a byte (self modified) ; 5
lda $A398,Y ; load a byte (self modified) ; 4
sta $7D0,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line_large3 ; ; 2nt/3
rts ; 6

View File

@ -0,0 +1,5 @@
gr_offsets:
.word $400,$480,$500,$580,$600,$680,$700,$780
.word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8
.word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0

View File

@ -0,0 +1,24 @@
;==========
; page_flip
;==========
page_flip:
lda DISP_PAGE ; 3
beq page_flip_show_1 ; 2nt/3
page_flip_show_0:
bit PAGE0 ; 4
lda #4 ; 2
sta DRAW_PAGE ; DRAW_PAGE=1 ; 3
lda #0 ; 2
sta DISP_PAGE ; DISP_PAGE=0 ; 3
rts ; 6
page_flip_show_1:
bit PAGE1 ; 4
sta DRAW_PAGE ; DRAW_PAGE=0 ; 3
lda #1 ; 2
sta DISP_PAGE ; DISP_PAGE=1 ; 3
rts ; 6
;====================
; DISP_PAGE=0 26
; DISP_PAGE=1 24

112
vertical_scroll/gr_unrle.s Normal file
View File

@ -0,0 +1,112 @@
;=================
; load RLE image
;=================
; Output is A:00 (assume page aligned)
; Input is in GBASH/GBASL
; format: first byte=xsize
; A0,X,Y means run of X bytes of Y color
; A1 means end of file
; A2-AF,X means run of low nibble, X color
; if high nibble not A: just display color
; CV = current Y
; CH = max xsize (usually 40)
; TEMP = page
; TEMPY= current X
load_rle_gr:
sec
sbc #4 ; adjust page to write to
; to match gr_offsets
sta TEMP
ldy #$0 ; init Y to 0
sty CV
jsr load_and_increment ; load xsize
sta CH
jsr unrle_new_y
rle_loop:
jsr load_and_increment
tax
cmp #$A1 ; if 0xa1
beq rle_done ; we are done
and #$f0 ; mask
cmp #$a0 ; see if special AX
beq decompress_special
; not special, just color
txa ; put color back in A
ldx #$1 ; only want to print 1
bne decompress_run
decompress_special:
txa ; put read value back in A
and #$0f ; check if was A0
bne decompress_color ; if A0 need to read run, color
decompress_large:
jsr load_and_increment ; run length now in A
decompress_color:
tax ; put runlen into X
jsr load_and_increment ; get color into A
decompress_run:
rle_run_loop:
sta (BASL),y ; write out the value
inc BASL
dec TEMPY
bne rle_not_eol ; if less then keep going
; if here, we are > max_X
inc CV
inc CV
pha
jsr unrle_new_y
pla
rle_not_eol:
dex
bne rle_run_loop ; if not zero, keep looping
beq rle_loop ; and branch always
rle_done:
lda #$15 ; move the cursor somewhere sane
sta CV
rts
load_and_increment:
lda (GBASL),Y
inc GBASL
bne lai_no_oflo
inc GBASH
lai_no_oflo:
rts
unrle_new_y:
ldy CV
lda gr_offsets,Y
sta BASL
lda gr_offsets+1,Y
clc
adc TEMP ; adjust for page
sta BASH
lda CH
sta TEMPY
ldy #0
rts

View File

@ -0,0 +1,90 @@
;======================
; load large RLE image
;======================
; Output is A:00 (assume page aligned)
; Input is in GBASH/GBASL
; format: first byte=xsize
; A0,X,Y means run of X bytes of Y color
; A1 means end of file
; A2-AF,X means run of low nibble, X color
; if high nibble not A: just display color
; CV = current Y
; CH = max X xsize (usually 40)
; TEMP = page
; TEMPY= current X
load_rle_large:
sta OUTH
ldy #0
sty OUTL
sty CV ; init Y to 0
jsr load_and_increment ; load xsize, increment
sta CH
rle_large_loop:
jsr load_and_increment ; load next value from
tax
cmp #$A1 ; if 0xa1
beq rle_large_done ; we are done
and #$f0 ; mask
cmp #$a0 ; see if special AX
beq rle_large_decompress_special
; not special, just color
txa ; put color back in A
ldx #$1 ; only want to print 1
bne rle_large_decompress_run
rle_large_decompress_special:
txa ; put read value back in A
and #$0f ; check if was A0
bne rle_large_decompress_color ; if A0 need to read run, color
rle_large_decompress_large:
jsr load_and_increment ; run length now in A
rle_large_decompress_color:
tax ; put runlen into X
jsr load_and_increment ; get color into A
rle_large_decompress_run:
rle_large_run_loop:
sta (OUTL),y ; write out the value
inc OUTL
bne rle_large_inc_done
inc OUTH ; handle 16-bit
rle_large_inc_done:
dec TEMPY
bne rle_large_not_eol ; if less then keep going
rle_large_not_eol:
dex
bne rle_large_run_loop ; if not zero, keep looping
beq rle_large_loop ; and branch always
rle_large_done:
lda #$15 ; move the cursor somewhere sane
sta CV
rts
;load_and_increment:
; lda (GBASL),Y
; inc GBASL
; bne lai_no_oflo
; inc GBASH
;lai_no_oflo:
; rts

View File

@ -0,0 +1,86 @@
;; HARDWARE LOCATIONS
KEYPRESS = $C000
KEYRESET = $C010
;; SOFT SWITCHES
CLR80COL = $C000 ; PAGE0/PAGE1 normal
SET80COL = $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead
EIGHTYCOLOFF = $C00C
EIGHTYCOLON = $C00D
SPEAKER = $C030
SET_GR = $C050
SET_TEXT = $C051
FULLGR = $C052
TEXTGR = $C053
PAGE0 = $C054
PAGE1 = $C055
LORES = $C056 ; Enable LORES graphics
HIRES = $C057 ; Enable HIRES graphics
AN3 = $C05E ; Annunciator 3
PADDLE_BUTTON0 = $C061
PADDL0 = $C064
PTRIG = $C070
;; BASIC ROUTINES
NORMAL = $F273
;; MONITOR ROUTINES
HLINE = $F819 ;; HLINE Y,$2C at A
VLINE = $F828 ;; VLINE A,$2D at Y
CLRSCR = $F832 ;; Clear low-res screen
CLRTOP = $F836 ;; clear only top of low-res screen
SETCOL = $F864 ;; COLOR=A
TEXT = $FB36
TABV = $FB5B ;; VTAB to A
BELL = $FBDD ;; ring the bell
BASCALC = $FBC1 ;;
VTAB = $FC22 ;; VTAB to CV
HOME = $FC58 ;; Clear the text screen
WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us
CROUT1 = $FD8B
SETINV = $FE80 ;; INVERSE
SETNORM = $FE84 ;; NORMAL
COUT = $FDED ;; output A to screen
COUT1 = $FDF0 ;; output A to screen
COLOR_BLACK = 0
COLOR_RED = 1
COLOR_DARKBLUE = 2
COLOR_PURPLE = 3
COLOR_DARKGREEN = 4
COLOR_GREY = 5
COLOR_MEDIUMBLUE = 6
COLOR_LIGHTBLUE = 7
COLOR_BROWN = 8
COLOR_ORANGE = 9
COLOR_GREY2 = 10
COLOR_PINK = 11
COLOR_LIGHTGREEN = 12
COLOR_YELLOW = 13
COLOR_AQUA = 14
COLOR_WHITE = 15
COLOR_BOTH_BLACK = $00
COLOR_BOTH_RED = $11
COLOR_BOTH_DARKBLUE = $22
COLOR_BOTH_DARKGREEN = $44
COLOR_BOTH_GREY = $55
COLOR_BOTH_MEDIUMBLUE = $66
COLOR_BOTH_LIGHTBLUE = $77
COLOR_BOTH_BROWN = $88
COLOR_BOTH_ORANGE = $99
COLOR_BOTH_PINK = $BB
COLOR_BOTH_LIGHTGREEN = $CC
COLOR_BOTH_YELLOW = $DD
COLOR_BOTH_AQUA = $EE
COLOR_BOTH_WHITE = $FF

106
vertical_scroll/scroller.s Normal file
View File

@ -0,0 +1,106 @@
; Vertical scroll lo-res
; by deater (Vince Weaver) <vince@deater.net>
; Zero Page
.include "zp.inc"
.include "hardware.inc"
;===================
; init screen
jsr TEXT
jsr HOME
bit KEYRESET
; GR part
bit PAGE1
bit LORES ; 4
bit SET_GR ; 4
bit FULLGR ; 4
;===================
; init vars
lda #0
sta DRAW_PAGE
lda #4
sta DISP_PAGE
;=============================
; Load desire 1st
lda #<desire_rle
sta GBASL
lda #>desire_rle
sta GBASH
lda #$c
jsr load_rle_gr
jsr gr_copy_to_current ; copy to page1
jsr page_flip
jsr wait_until_keypress
;=============================
; Load desire 2nd
lda #<desire2_rle
sta GBASL
lda #>desire2_rle
sta GBASH
lda #$c
jsr load_rle_gr
jsr gr_copy_to_current ; copy to page1
jsr page_flip
jsr wait_until_keypress
;=============================
; Load spaceman
lda #<spaceman_rle
sta GBASL
lda #>spaceman_rle
sta GBASH
lda #$a0
jsr load_rle_large
jsr gr_copy_to_current_large ; copy to page1
jsr page_flip
jsr wait_until_keypress
forever:
jmp forever
wait_until_keypress:
lda KEYPRESS
bpl wait_until_keypress
bit KEYRESET
rts
.include "gr_unrle.s"
.include "gr_unrle_large.s"
.include "gr_offsets.s"
.include "gr_copy.s"
.include "gr_copy_large.s"
.include "gr_pageflip.s"
.include "desire.inc"
.include "spaceman.inc"

78
vertical_scroll/zp.inc Normal file
View File

@ -0,0 +1,78 @@
;; Zero Page
;; LZ4 addresses
LZ4_SRC = $00
LZ4_DST = $02
LZ4_END = $04
WHICH_LOAD = $05
COUNT = $06
MENU_BASE = $06
MENU_HIGHLIGHT = $07
DELTA = $08
;; Zero page monitor routines addresses
WNDLFT = $20
WNDWDTH = $21
WNDTOP = $22
WNDBTM = $23
CH = $24
CV = $25
GBASL = $26
GBASH = $27
BASL = $28
BASH = $29
H2 = $2C
V2 = $2D
MASK = $2E
COLOR_MASK = $2F
COLOR = $30
SEEDL = $4e
SEEDH = $4f
AY_REGISTERS = $70
A_FINE_TONE = $70
A_COARSE_TONE = $71
B_FINE_TONE = $72
B_COARSE_TONE = $73
C_FINE_TONE = $74
C_COARSE_TONE = $75
NOISE = $76
ENABLE = $77
PT3_MIXER_VAL = $77
A_VOLUME = $78
B_VOLUME = $79
C_VOLUME = $7A
ENVELOPE_FINE = $7B
ENVELOPE_COARSE = $7C
ENVELOPE_SHAPE = $7D
PATTERN_L = $7E
PATTERN_H = $7F
ORNAMENT_L = $80
ORNAMENT_H = $81
SAMPLE_L = $82
SAMPLE_H = $83
LOOP = $84
MB_VALUE = $85
MB_ADDR_L = $86
MB_ADDR_H = $87
DONE_PLAYING = $88
DONE_SONG = $89
PT3_TEMP = $8A
DISP_PAGE = $ED ; ALL
DRAW_PAGE = $EE ; ALL
TEMP = $FA
TEMPY = $FB
INL = $FC
INH = $FD
OUTL = $FE
OUTH = $FF