rotozoom: null set working

This commit is contained in:
Vince Weaver 2021-01-06 14:00:59 -05:00
parent f05c1744c4
commit 424af605e1
18 changed files with 1470 additions and 135 deletions

View File

@ -4,21 +4,27 @@ DOS33 = ../../../utils/dos33fs-utils/dos33
TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft
LINKERSCRIPTS = ../../../linker_scripts
all: gr.dsk
all: roto.dsk
gr.dsk: SNOW
cp empty.dsk gr.dsk
$(DOS33) -y gr.dsk BSAVE -a 0x0300 SNOW
roto.dsk: HELLO ROTO
cp empty.dsk roto.dsk
$(DOS33) -y roto.dsk SAVE A HELLO
$(DOS33) -y roto.dsk BSAVE -a 0x1000 ROTO
###
SNOW: snow.o
ld65 -o SNOW snow.o -C $(LINKERSCRIPTS)/apple2_300.inc
HELLO: hello.bas
$(TOKENIZE) < hello.bas > HELLO
snow.o: snow.s
ca65 -o snow.o snow.s -l snow.lst
###
ROTO: roto.o
ld65 -o ROTO roto.o -C $(LINKERSCRIPTS)/apple2_1000.inc
roto.o: roto.s rotozoom.s gr_plot.s gr_scrn.s
ca65 -o roto.o roto.s -l roto.lst
###
clean:
rm -f *~ *.o *.lst SNOW
rm -f *~ *.o *.lst ROTO

View File

@ -1,2 +1,6 @@
place to test out lo-res programs
testing out rotozoom
doing more complicated one where centered in screen

View File

@ -0,0 +1,370 @@
; note -- modified by Vince Weaver to assemble with ca65
; in this case, A = page to decompress to
; getsrc_smc+1, getsrc_smc+2 is src location
; -----------------------------------------------------------------------------
; Decompress raw LZSA2 block.
; Create one with lzsa -r -f2 <original_file> <compressed_file>
;
; in:
; * LZSA_SRC_LO and LZSA_SRC_HI contain the compressed raw block address
; * LZSA_DST_LO and LZSA_DST_HI contain the destination buffer address
;
; out:
; * LZSA_DST_LO and LZSA_DST_HI contain the last decompressed byte address, +1
;
; -----------------------------------------------------------------------------
; Backward decompression is also supported, use lzsa -r -b -f2 <original_file> <compressed_file>
; To use it, also define BACKWARD_DECOMPRESS=1 before including this code!
;
; in:
; * LZSA_SRC_LO/LZSA_SRC_HI must contain the address of the last byte of compressed data
; * LZSA_DST_LO/LZSA_DST_HI must contain the address of the last byte of the destination buffer
;
; out:
; * LZSA_DST_LO/LZSA_DST_HI contain the last decompressed byte address, -1
;
; -----------------------------------------------------------------------------
;
; Copyright (C) 2019 Emmanuel Marty, Peter Ferrie
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Permission is granted to anyone to use this software for any purpose,
; including commercial applications, and to alter it and redistribute it
; freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you must not
; claim that you wrote the original software. If you use this software
; in a product, an acknowledgment in the product documentation would be
; appreciated but is not required.
; 2. Altered source versions must be plainly marked as such, and must not be
; misrepresented as being the original software.
; 3. This notice may not be removed or altered from any source distribution.
; -----------------------------------------------------------------------------
;NIBCOUNT = $FC ; zero-page location for temp offset
decompress_lzsa2_fast:
sta LZSA_DST_HI
ldy #$00
sty LZSA_DST_LO
sty NIBCOUNT
decode_token:
jsr getsrc ; read token byte: XYZ|LL|MMM
pha ; preserve token on stack
and #$18 ; isolate literals count (LL)
beq no_literals ; skip if no literals to copy
cmp #$18 ; LITERALS_RUN_LEN_V2?
bcc prepare_copy_literals ; if less, count is directly embedded in token
jsr getnibble ; get extra literals length nibble
; add nibble to len from token
adc #$02 ; (LITERALS_RUN_LEN_V2) minus carry
cmp #$12 ; LITERALS_RUN_LEN_V2 + 15 ?
bcc prepare_copy_literals_direct ; if less, literals count is complete
jsr getsrc ; get extra byte of variable literals count
; the carry is always set by the CMP above
; GETSRC doesn't change it
sbc #$EE ; overflow?
jmp prepare_copy_literals_direct
prepare_copy_literals_large:
; handle 16 bits literals count
; literals count = directly these 16 bits
jsr getlargesrc ; grab low 8 bits in X, high 8 bits in A
tay ; put high 8 bits in Y
bcs prepare_copy_literals_high ; (*same as JMP PREPARE_COPY_LITERALS_HIGH but shorter)
prepare_copy_literals:
lsr ; shift literals count into place
lsr
lsr
prepare_copy_literals_direct:
tax
bcs prepare_copy_literals_large ; if so, literals count is large
prepare_copy_literals_high:
txa
beq copy_literals
iny
copy_literals:
jsr getput ; copy one byte of literals
dex
bne copy_literals
dey
bne copy_literals
no_literals:
pla ; retrieve token from stack
pha ; preserve token again
asl
bcs repmatch_or_large_offset ; 1YZ: rep-match or 13/16 bit offset
asl ; 0YZ: 5 or 9 bit offset
bcs offset_9_bit
; 00Z: 5 bit offset
ldx #$FF ; set offset bits 15-8 to 1
jsr getcombinedbits ; rotate Z bit into bit 0, read nibble for bits 4-1
ora #$E0 ; set bits 7-5 to 1
bne got_offset_lo ; go store low byte of match offset and prepare match
offset_9_bit: ; 01Z: 9 bit offset
;;asl ; shift Z (offset bit 8) in place
rol
rol
and #$01
eor #$FF ; set offset bits 15-9 to 1
bne got_offset_hi ; go store high byte, read low byte of match offset and prepare match
; (*same as JMP GOT_OFFSET_HI but shorter)
repmatch_or_large_offset:
asl ; 13 bit offset?
bcs repmatch_or_16bit ; handle rep-match or 16-bit offset if not
; 10Z: 13 bit offset
jsr getcombinedbits ; rotate Z bit into bit 8, read nibble for bits 12-9
adc #$DE ; set bits 15-13 to 1 and substract 2 (to substract 512)
bne got_offset_hi ; go store high byte, read low byte of match offset and prepare match
; (*same as JMP GOT_OFFSET_HI but shorter)
repmatch_or_16bit: ; rep-match or 16 bit offset
;;ASL ; XYZ=111?
bmi rep_match ; reuse previous offset if so (rep-match)
; 110: handle 16 bit offset
jsr getsrc ; grab high 8 bits
got_offset_hi:
tax
jsr getsrc ; grab low 8 bits
got_offset_lo:
sta OFFSLO ; store low byte of match offset
stx OFFSHI ; store high byte of match offset
rep_match:
.ifdef BACKWARD_DECOMPRESS
; Backward decompression - substract match offset
sec ; add dest + match offset
lda putdst+1 ; low 8 bits
OFFSLO = *+1
sbc #$AA
sta copy_match_loop+1 ; store back reference address
lda putdst+2
OFFSHI = *+1
sbc #$AA ; high 8 bits
sta copy_match_loop+2 ; store high 8 bits of address
sec
.else
; Forward decompression - add match offset
clc ; add dest + match offset
lda putdst+1 ; low 8 bits
OFFSLO = *+1
adc #$AA
sta copy_match_loop+1 ; store back reference address
OFFSHI = *+1
lda #$AA ; high 8 bits
adc putdst+2
sta copy_match_loop+2 ; store high 8 bits of address
.endif
pla ; retrieve token from stack again
and #$07 ; isolate match len (MMM)
adc #$01 ; add MIN_MATCH_SIZE_V2 and carry
cmp #$09 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2?
bcc prepare_copy_match ; if less, length is directly embedded in token
jsr getnibble ; get extra match length nibble
; add nibble to len from token
adc #$08 ; (MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2) minus carry
cmp #$18 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15?
bcc prepare_copy_match ; if less, match length is complete
jsr getsrc ; get extra byte of variable match length
; the carry is always set by the CMP above
; GETSRC doesn't change it
sbc #$E8 ; overflow?
prepare_copy_match:
tax
bcc prepare_copy_match_y ; if not, the match length is complete
beq decompression_done ; if EOD code, bail
; Handle 16 bits match length
jsr getlargesrc ; grab low 8 bits in X, high 8 bits in A
tay ; put high 8 bits in Y
prepare_copy_match_y:
txa
beq copy_match_loop
iny
copy_match_loop:
lda $AAAA ; get one byte of backreference
jsr putdst ; copy to destination
.ifdef BACKWARD_DECOMPRESS
; Backward decompression -- put backreference bytes backward
lda copy_match_loop+1
beq getmatch_adj_hi
getmatch_done:
dec copy_match_loop+1
.else
; Forward decompression -- put backreference bytes forward
inc copy_match_loop+1
beq getmatch_adj_hi
getmatch_done:
.endif
dex
bne copy_match_loop
dey
bne copy_match_loop
jmp decode_token
.ifdef BACKWARD_DECOMPRESS
getmatch_adj_hi:
dec copy_match_loop+2
jmp getmatch_done
.else
getmatch_adj_hi:
inc copy_match_loop+2
jmp getmatch_done
.endif
getcombinedbits:
eor #$80
asl
php
jsr getnibble ; get nibble into bits 0-3 (for offset bits 1-4)
plp ; merge Z bit as the carry bit (for offset bit 0)
combinedbitz:
rol ; nibble -> bits 1-4; carry(!Z bit) -> bit 0 ; carry cleared
decompression_done:
rts
getnibble:
NIBBLES = *+1
lda #$AA
lsr NIBCOUNT
bcc need_nibbles
and #$0F ; isolate low 4 bits of nibble
rts
need_nibbles:
inc NIBCOUNT
jsr getsrc ; get 2 nibbles
sta NIBBLES
lsr
lsr
lsr
lsr
sec
rts
.ifdef BACKWARD_DECOMPRESS
; Backward decompression -- get and put bytes backward
getput:
jsr getsrc
putdst:
LZSA_DST_LO = *+1
LZSA_DST_HI = *+2
sta $AAAA
lda putdst+1
beq putdst_adj_hi
dec putdst+1
rts
putdst_adj_hi:
dec putdst+2
dec putdst+1
rts
getlargesrc:
jsr getsrc ; grab low 8 bits
tax ; move to X
; fall through grab high 8 bits
getsrc:
LZSA_SRC_LO = *+1
LZSA_SRC_HI = *+2
lda $AAAA
pha
lda getsrc+1
beq getsrc_adj_hi
dec getsrc+1
pla
rts
getsrc_adj_hi:
dec getsrc+2
dec getsrc+1
pla
rts
.else
; Forward decompression -- get and put bytes forward
getput:
jsr getsrc
putdst:
LZSA_DST_LO = *+1
LZSA_DST_HI = *+2
sta $AAAA
inc putdst+1
beq putdst_adj_hi
rts
putdst_adj_hi:
inc putdst+2
rts
getlargesrc:
jsr getsrc ; grab low 8 bits
tax ; move to X
; fall through grab high 8 bits
getsrc:
getsrc_smc:
LZSA_SRC_LO = *+1
LZSA_SRC_HI = *+2
lda $AAAA
inc getsrc+1
beq getsrc_adj_hi
rts
getsrc_adj_hi:
inc getsrc+2
rts
.endif

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,207 @@
clear_screens:
;===================================
; Clear top/bottom of page 0
;===================================
lda DRAW_PAGE
pha
lda #$0
sta DRAW_PAGE
jsr clear_top
jsr clear_bottom
;===================================
; Clear top/bottom of page 1
;===================================
lda #$4
sta DRAW_PAGE
jsr clear_top
jsr clear_bottom
pla
sta DRAW_PAGE
rts
;=========================================================
; clear_top
;=========================================================
; clear DRAW_PAGE
; original = 14,558 cycles(?) 15ms, 70Hz
; OPTIMIZED MAX (page0,48rows): 45*120+4+6 = 5410 = 5.4ms 185Hz
; (pageX,40rows): 50*120+4+6 = 6010 = 6.0ms 166Hz
; 50*120+4+6+37 = 6055 = 6.0ms 166Hz
clear_top:
lda #0 ; 2
clear_top_a:
sta COLOR ; 3
clc ; 2
lda DRAW_PAGE ; 3
adc #4 ; 2
sta __ctf+2 ; 3
sta __ctf+5 ; 3
adc #1 ; 2
sta __ctf+8 ; 3
sta __ctf+11 ; 3
adc #1 ; 2
sta __ctf2+2 ; 3
sta __ctf2+5 ; 3
adc #1 ; 2
sta __ctf2+8 ; 3
sta __ctf2+11 ; 3
ldy #120 ; 2
lda COLOR ; 3
clear_top_fast_loop:
__ctf:
sta $400,Y ; 5
sta $480,Y ; 5
sta $500,Y ; 5
sta $580,Y ; 5
cpy #80 ; 2
bpl no_draw_bottom ; 2nt/3
__ctf2:
sta $600,Y ; 5
sta $680,Y ; 5
sta $700,Y ; 5
sta $780,Y ; 5
no_draw_bottom:
dey ; 2
bpl clear_top_fast_loop ; 2nt/3
rts ; 6
;=========================================================
; clear_bottom
;=========================================================
; clear bottom of draw page
clear_bottom:
clc ; 2
lda DRAW_PAGE ; 3
adc #6 ; 2
sta __cbf2+2 ; 3
sta __cbf2+5 ; 3
adc #1 ; 2
sta __cbf2+8 ; 3
sta __cbf2+11 ; 3
ldy #120 ; 2
lda #$a0 ; Normal Space ; 2
clear_bottom_fast_loop:
__cbf2:
sta $600,Y ; 5
sta $680,Y ; 5
sta $700,Y ; 5
sta $780,Y ; 5
dey ; 2
cpy #80 ; 2
bpl clear_bottom_fast_loop ; 2nt/3
rts ; 6
;clear_screens_notext:
;===================================
; Clear top/bottom of page 0
;===================================
; lda #$0
; sta DRAW_PAGE
; jsr clear_all
;===================================
; Clear top/bottom of page 1
;===================================
; lda #$4
; sta DRAW_PAGE
; jsr clear_all
; rts
clear_bottoms:
lda DRAW_PAGE
pha
;===================================
; Clear bottom of page 0
;===================================
lda #$0
sta DRAW_PAGE
jsr clear_bottom
;===================================
; Clear bottom of page 1
;===================================
lda #$4
sta DRAW_PAGE
jsr clear_bottom
pla
sta DRAW_PAGE
rts
;=========================================================
; clear_all
;=========================================================
; clear 48 rows
clear_all:
clc ; 2
lda DRAW_PAGE ; 3
adc #4 ; 2
sta __caf+2 ; 3
sta __caf+5 ; 3
adc #1 ; 2
sta __caf+8 ; 3
sta __caf+11 ; 3
adc #1 ; 2
sta __caf2+2 ; 3
sta __caf2+5 ; 3
adc #1 ; 2
sta __caf2+8 ; 3
sta __caf2+11 ; 3
ldy #120 ; 2
clear_all_color:
lda #' '|$80 ; 2
clear_all_fast_loop:
__caf:
sta $400,Y ; 5
sta $480,Y ; 5
sta $500,Y ; 5
sta $580,Y ; 5
__caf2:
sta $600,Y ; 5
sta $680,Y ; 5
sta $700,Y ; 5
sta $780,Y ; 5
dey ; 2
bpl clear_all_fast_loop ; 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

View File

@ -0,0 +1,48 @@
;================================
; plot routine
;================================
; Xcoord in XPOS
; Ycoord in YPOS
; color in COLOR
plot:
lda YPOS ; 2
lsr ; shift bottom bit into carry ; 2
bcc plot_even ; 2nt/3
plot_odd:
ldx #$f0 ; 2
bcs plot_c_done ; 2nt/3
plot_even:
ldx #$0f ; 2
plot_c_done:
stx MASK ; 3
asl ; shift back (now even) ; 2
tay
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc XPOS ; 3
sta GBASL ; 3
iny ; 2
lda gr_offsets,Y ; 4
adc DRAW_PAGE ; add in draw page offset ; 3
sta GBASH ; 3
ldy #0 ; 2
plot_write:
lda MASK ; 3
eor #$ff ; 2
and (GBASL),Y ; 5
sta COLOR_MASK ; 3
lda COLOR ; 3
and MASK ; 3
ora COLOR_MASK ; 3
sta (GBASL),Y ; 5
rts ; 6

View File

@ -0,0 +1,59 @@
;================================
; scrn routine
;================================
; Xcoord in XPOS
; Ycoord in YPOS
; color returned in A
; assume reading from $c00
scrn:
lda YPOS ; 2
; lsr ; shift bottom bit into carry ; 2
; bcc scrn_even ; 2nt/3
;scrn_odd:
; ldx #$f0 ; 2
; bcs scrn_c_done ; 2nt/3
;scrn_even:
; ldx #$0f ; 2
;scrn_c_done:
; stx MASK ; 3
; asl ; shift back (now even) ; 2
and #$fe ; make even
tay
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc XPOS ; 3
sta GBASL ; 3
lda gr_offsets+1,Y ; 4
adc #$8 ; assume reading from $c0 ; 3
sta GBASH ; 3
ldy #0
lda YPOS
lsr
bcs scrn_adjust_even
scrn_adjust_odd:
lda (GBASL),Y ; top/bottom color
jmp scrn_done
scrn_adjust_even:
lda (GBASL),Y ; top/bottom color
lsr
lsr
lsr
lsr
scrn_done:
and #$f
rts

View File

@ -0,0 +1,99 @@
;; 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
TBCOLOR = $C022 ; IIgs text foreground / background colors
NEWVIDEO = $C029 ; IIgs graphics modes
SPEAKER = $C030
CLOCKCTL = $C034 ; bits 0-3 are IIgs border color
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
PADDLE_BUTTON1 = $C062
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
ROM_TEXT2COPY = $F962 ;; iigs
TEXT = $FB36
TABV = $FB5B ;; VTAB to A
ROM_MACHINEID = $FBB3 ;; iigs
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

View File

@ -0,0 +1,2 @@
5 HOME
10 PRINT CHR$(4);"CATALOG"

102
graphics/gr/rotozoom/roto.s Normal file
View File

@ -0,0 +1,102 @@
; do a (hopefully fast) roto-zoom
.include "zp.inc"
.include "hardware.inc"
;================================
; Clear screen and setup graphics
;================================
jsr HOME
bit PAGE0 ; set page 0
bit LORES ; Lo-res graphics
bit TEXTGR ; mixed gr/text mode
bit SET_GR ; set graphics
lda #0
sta DISP_PAGE
lda #4
sta DRAW_PAGE
;===================================
; Clear top/bottom of page 0 and 1
;===================================
jsr clear_screens
;======================
; show the title screen
;======================
; Title Screen
title_screen:
;===========================
; Clear both bottoms
jsr clear_bottoms
;=============================
; Load title
lda #<(title_lzsa)
sta getsrc_smc+1
lda #>(title_lzsa)
sta getsrc_smc+2
lda #$0c
jsr decompress_lzsa2_fast
;=================================
; copy to both pages
jsr gr_copy_to_current
jsr page_flip
jsr gr_copy_to_current
;=================================
; main loop
lda #0
sta ANGLE
main_loop:
jsr rotozoom
jsr page_flip
wait_for_keypress:
lda KEYPRESS
bpl wait_for_keypress
bit KEYRESET
inc ANGLE
jmp main_loop
;===============================================
; External modules
;===============================================
.include "rotozoom.s"
.include "gr_pageflip.s"
.include "gr_fast_clear.s"
.include "gr_copy.s"
.include "decompress_fast_v2.s"
.include "gr_offsets.s"
.include "gr_plot.s"
.include "gr_scrn.s"
;===============================================
; Data
;===============================================
.include "tfv_title.inc"

View File

@ -0,0 +1,213 @@
; ANGLE in our case it's 0..15?
CAL = $B0
CAH = $B1
SAL = $B2
SAH = $B3
YPL = $B4
YPH = $B5
XPL = $B6
XPH = $B7
;YY
;XX
CCAL = $B8
CCAH = $B9
CSAL = $BA
CSAH = $BB
YCAL = $BC
YCAH = $BD
YSAL = $BE
YSAH = $BF
rotozoom:
; ca = cos(theta)*scale;
; ca=fixed_sin[(theta+4)&0xf]
lda ANGLE ; 3
clc ; 2
adc #4 ; 2
and #$f ; 2
asl ; 2
tay ; 2
lda fixed_sin,Y ; load integer half ; 4
sta CAH ; 3
lda fixed_sin+1,Y ; load integer half ; 4
sta CAL ; 3
; sa = sin(theta)*scale;
lda ANGLE ; 3
asl ; 2
tay ; 2
lda fixed_sin,Y ; load integer half ; 4
sta SAH ; 3
lda fixed_sin+1,Y ; load integer half ; 4
sta SAL ; 3
; cca = -20*ca;
; csa = -20*sa;
; yca=cca+ycenter;
lda CCAL
sta YCAL
clc
lda CCAH
adc #20
sta YCAH
; ysa=csa+xcenter;
lda CSAL
sta YSAL
clc
lda CSAH
adc #20
sta YSAH
; for(yy=0;yy<40;yy++) {
lda #0
sta YY
rotozoom_yloop:
; xp=cca+ysa;
clc
lda YSAL
adc CCAL
sta XPL
lda YSAH
adc CCAH
sta XPH
; yp=yca-csa;
sec
lda YCAL
sbc CSAL
sta YPL
lda YCAH
sbc CSAH
sta YPH
; for(xx=0;xx<40;xx++) {
lda #0
sta XX
rotozoom_xloop:
; if ((xp<0) || (xp>39)) color=0;
; else if ((yp<0) || (yp>39)) color=0;
; else color=scrn_page(xp,yp,PAGE2);
; lda #0
; ldx XPH
; bmi rotozoom_set_color
; cpx #40
; bcs rotozoom_set_color
; ldx YPH
; bmi rotozoom_set_color
; cpx #40
; bcs rotozoom_set_color
; scrn()
lda XX
sta XPOS
lda YY
sta YPOS
jsr scrn
rotozoom_set_color:
; color_equals(color);
jsr SETCOL
; plot(xx,yy);
lda XX
sta XPOS
lda YY
sta YPOS
jsr plot
; xp=xp+ca;
clc
lda CAL
adc XPL
sta XPL
lda CAH
adc XPH
sta XPH
; yp=yp-sa;
sec
lda YPL
sbc SAL
sta YPL
lda YPH
sbc SAH
sta YPH
rotozoom_end_xloop:
inc XX
lda XX
cmp #40
bne rotozoom_xloop
; yca+=ca;
clc
lda YCAL
adc CAL
sta YCAL
lda YCAH
adc CAH
sta YCAH
; ysa+=sa;
clc
lda YSAL
adc SAL
sta YSAL
lda YSAH
adc SAH
sta YSAH
rotozoom_end_yloop:
inc YY
lda YY
cmp #40
beq done_rotozoom
jmp rotozoom_yloop ; too far
done_rotozoom:
rts
fixed_sin:
.byte $00,$00 ; 0.000000=00.00
.byte $00,$61 ; 0.382683=00.61
.byte $00,$b5 ; 0.707107=00.b5
.byte $00,$ec ; 0.923880=00.ec
.byte $01,$00 ; 1.000000=01.00
.byte $00,$ec ; 0.923880=00.ec
.byte $00,$b5 ; 0.707107=00.b5
.byte $00,$61 ; 0.382683=00.61
.byte $00,$00 ; 0.000000=00.00
.byte $ff,$9f ; -0.382683=ff.9f
.byte $ff,$4b ; -0.707107=ff.4b
.byte $ff,$14 ; -0.923880=ff.14
.byte $ff,$00 ; -1.000000=ff.00
.byte $ff,$14 ; -0.923880=ff.14
.byte $ff,$4b ; -0.707107=ff.4b
.byte $ff,$9f ; -0.382683=ff.9f

View File

@ -1,120 +0,0 @@
GBASL = $26
GBASH = $27
HGRPAGE = $E6
PAGE0 = $C054
PAGE1 = $C055
HGR = $F3E2
HGR2 = $F3D8
HCLR = $F3F2
HPOSN = $F411
WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us
snow:
jsr HGR
jsr HGR2
lda #0
sta ybase
lda #$20
sta HGRPAGE
move_snow:
lda HGRPAGE
cmp #$20
beq show_page1
show_page2:
bit PAGE1
lsr HGRPAGE
bne doit
show_page1:
bit PAGE0
asl HGRPAGE
doit:
jsr HCLR
lda #<flake
sta ll_smc+1
lda #$18
sta c_smc
lda #$69
sta dir_smc
lda #23
sta line
inc ybase
lda ybase
sta ylo
cmp #160
bne snow_loop
lda #0
sta ybase
snow_loop:
ldy xhi
ldx xlo
lda ylo
jsr HPOSN
ldx #0
line_loop:
ll_smc:
lda flake,X
sta (GBASL),Y
inx
iny
cpx #6
bne line_loop
lda ll_smc+1
c_smc:
clc
dir_smc:
adc #6
sta ll_smc+1
inc ylo
dec line
beq forever
lda line
cmp #12
bne snow_loop
lda #$E9 ; sbc imm
sta dir_smc
lda #$38 ; sec
sta c_smc
jmp snow_loop
forever:
jmp move_snow
xhi: .byte $00
xlo: .byte 77
ybase: .byte 100
ylo: .byte 100
line: .byte 23
flake:
.byte $00,$00,$40,$01,$00,$00
.byte $00,$00,$0C,$18,$00,$00
.byte $00,$00,$70,$07,$00,$00
.byte $00,$00,$43,$61,$00,$00
.byte $00,$00,$4C,$19,$00,$00
.byte $33,$00,$70,$07,$00,$66
.byte $30,$06,$40,$01,$30,$06
.byte $3f,$06,$40,$01,$30,$7e
.byte $40,$07,$30,$06,$70,$01
.byte $7c,$07,$30,$06,$70,$1f
.byte $00,$18,$0F,$78,$0C,$00
.byte $00,$60,$40,$01,$03,$00

View File

@ -0,0 +1 @@
title_lzsa: .incbin "title.lzsa"

Binary file not shown.

154
graphics/gr/rotozoom/zp.inc Normal file
View File

@ -0,0 +1,154 @@
;; Zero page monitor routines addresses
;; LZSA addresses
NIBCOUNT = $00
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 = $30
INVFLG = $32
; More zero-page addresses
; we try not to conflict with anything DOS, MONITOR or BASIC related
;; Flying Routine Only
TURNING = $60
;SCREEN_X = $61 ; not used?
SCREEN_Y = $62
ANGLE = $63
HORIZ_SCALE_I = $64
HORIZ_SCALE_F = $65
FACTOR_I = $66
FACTOR_F = $67
DX_I = $68
DX_F = $69
SPACEX_I = $6A
SPACEX_F = $6B
CX_I = $6C
CX_F = $6D
DY_I = $6E
DY_F = $6F
SPACEY_I = $70
SPACEY_F = $71
CY_I = $72
CY_F = $73
TEMP_I = $74
TEMP_F = $75
DISTANCE_I = $76
DISTANCE_F = $77
SPACEZ_I = $78
SPACEZ_F = $79
DRAW_SPLASH = $7A
SPEED = $7B
SPLASH_COUNT = $7C
OVER_LAND = $7D
NUM1L = $7E
NUM1H = $7F
NUM2L = $80
NUM2H = $81
RESULT = $82 ; 83,84,85
NEGATE = $86 ; UNUSED?
LAST_SPACEX_I = $87
LAST_SPACEY_I = $88
LAST_MAP_COLOR = $89
COLOR_MASK = $8A
;; World Map Only
ODD = $7B
DIRECTION = $7C
REFRESH = $7D
ON_BIRD = $7E
MOVED = $7F
STEPS = $80
TFV_X = $81
TFV_Y = $82
NEWX = $83
NEWY = $84
MAP_X = $85
GROUND_COLOR = $86
LEVEL_OVER = $A0
JOYSTICK_ENABLED= $A1
FRAMEL = $A2
FRAMEH = $A3
WHICH_LOAD = $A4
MENU_RESULT = $A5
SOUND_STATUS = $A6
SOUND_DISABLED = $80
SOUND_IN_LC = $01 ; $01 sound effects in language card
SOUND_MOCKINGBOARD = $02 ; mockingboard detected
JS_BUTTON_STATE = $A7
COLOR1 = $E0
COLOR2 = $E1
MATCH = $E2
XX = $E3
YY = $E4
SHIPY = $E4
YADD = $E5
LOOP = $E6
;MEMPTRL = $E7
;MEMPTRH = $E8
NAMEL = $E9
NAMEH = $EA
NAMEX = $EB
CHAR = $EC
DISP_PAGE = $ED
DRAW_PAGE = $EE
FIRST = $F0
LASTKEY = $F1
PADDLE_STATUS = $F2
XPOS = $F3
YPOS = $F4
TEMP = $FA
RUN = $FA
TEMP2 = $FB
TEMPY = $FB
INL = $FC
INH = $FD
OUTL = $FE
OUTH = $FF
; read any file slot 6 version
; based on FASTLD6 and RTS copyright (c) Peter Ferrie 2011-2013,2018
; modified to assemble with ca65 -- vmw
; added code to patch it to run from current disk slot -- vmw
adrlo = $26 ; constant from boot prom
adrhi = $27 ; constant from boot prom
tmpsec = $3c ; constant from boot prom
reqsec = $3d ; constant from boot prom
sizelo = $44
sizehi = $45
secsize = $46
ldsizel = $70
ldsizeh = $71
namlo = $7b
namhi = $7c
step = $7d ; state for stepper motor
tmptrk = $7e ; temporary copy of current track
phase = $7f ; current phase for /seek

View File

@ -71,12 +71,12 @@ blah:
yca=cca+ycenter;
ysa=csa+xcenter;
for(yy=-20;yy<20;yy++) {
for(yy=0;yy<40;yy++) {
xp=cca+ysa;
yp=yca-csa;
for(xx=-20;xx<20;xx++) {
for(xx=0;xx<40;xx++) {
if ((xp<0) || (xp>39)) color=0;
else if ((yp<0) || (yp>39)) color=0;
@ -85,15 +85,15 @@ blah:
}
if (
((xx==-20) && (yy==-20)) ||
((xx==0) && (yy==0)) ||
((xx==19) && (yy==19))
((xx==20) && (yy==20)) ||
((xx==39) && (yy==39))
) {
printf("%d,%d -> %0.2lf,%0.2lf\n",xx,yy,xp,yp);
}
color_equals(color);
plot(xx+20,yy+20);
plot(xx,yy);
xp=xp+ca;
yp=yp-sa;
}