diff --git a/graphics/gr/rotozoom/Makefile b/graphics/gr/rotozoom/Makefile index 7b75feb3..97bf9189 100644 --- a/graphics/gr/rotozoom/Makefile +++ b/graphics/gr/rotozoom/Makefile @@ -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 diff --git a/graphics/gr/rotozoom/README b/graphics/gr/rotozoom/README index 3939bb69..145ba978 100644 --- a/graphics/gr/rotozoom/README +++ b/graphics/gr/rotozoom/README @@ -1,2 +1,6 @@ -place to test out lo-res programs +testing out rotozoom + +doing more complicated one where centered in screen + + diff --git a/graphics/gr/rotozoom/decompress_fast_v2.s b/graphics/gr/rotozoom/decompress_fast_v2.s new file mode 100644 index 00000000..fb2f24ad --- /dev/null +++ b/graphics/gr/rotozoom/decompress_fast_v2.s @@ -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 +; +; 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 +; 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 + diff --git a/graphics/gr/rotozoom/gr_copy.s b/graphics/gr/rotozoom/gr_copy.s new file mode 100644 index 00000000..a657400b --- /dev/null +++ b/graphics/gr/rotozoom/gr_copy.s @@ -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 + + + + diff --git a/graphics/gr/rotozoom/gr_fast_clear.s b/graphics/gr/rotozoom/gr_fast_clear.s new file mode 100644 index 00000000..a86eb105 --- /dev/null +++ b/graphics/gr/rotozoom/gr_fast_clear.s @@ -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 diff --git a/graphics/gr/rotozoom/gr_offsets.s b/graphics/gr/rotozoom/gr_offsets.s new file mode 100644 index 00000000..d3af91f7 --- /dev/null +++ b/graphics/gr/rotozoom/gr_offsets.s @@ -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 + diff --git a/graphics/gr/rotozoom/gr_pageflip.s b/graphics/gr/rotozoom/gr_pageflip.s new file mode 100644 index 00000000..f199f5be --- /dev/null +++ b/graphics/gr/rotozoom/gr_pageflip.s @@ -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 + diff --git a/graphics/gr/rotozoom/gr_plot.s b/graphics/gr/rotozoom/gr_plot.s new file mode 100644 index 00000000..1ad15895 --- /dev/null +++ b/graphics/gr/rotozoom/gr_plot.s @@ -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 diff --git a/graphics/gr/rotozoom/gr_scrn.s b/graphics/gr/rotozoom/gr_scrn.s new file mode 100644 index 00000000..c28f7fce --- /dev/null +++ b/graphics/gr/rotozoom/gr_scrn.s @@ -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 diff --git a/graphics/gr/rotozoom/hardware.inc b/graphics/gr/rotozoom/hardware.inc new file mode 100644 index 00000000..1a03bcf1 --- /dev/null +++ b/graphics/gr/rotozoom/hardware.inc @@ -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 + diff --git a/graphics/gr/rotozoom/hello.bas b/graphics/gr/rotozoom/hello.bas new file mode 100644 index 00000000..133a44bb --- /dev/null +++ b/graphics/gr/rotozoom/hello.bas @@ -0,0 +1,2 @@ +5 HOME +10 PRINT CHR$(4);"CATALOG" diff --git a/graphics/gr/rotozoom/roto.s b/graphics/gr/rotozoom/roto.s new file mode 100644 index 00000000..4f7eec4a --- /dev/null +++ b/graphics/gr/rotozoom/roto.s @@ -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" diff --git a/graphics/gr/rotozoom/rotozoom.s b/graphics/gr/rotozoom/rotozoom.s new file mode 100644 index 00000000..abd0fd8c --- /dev/null +++ b/graphics/gr/rotozoom/rotozoom.s @@ -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 + diff --git a/graphics/gr/rotozoom/snow.s b/graphics/gr/rotozoom/snow.s deleted file mode 100644 index 54fe49ef..00000000 --- a/graphics/gr/rotozoom/snow.s +++ /dev/null @@ -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 #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; }