From 05275139053ab57f6903d0771aa033adef72dc61 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 25 Oct 2021 16:58:31 -0400 Subject: [PATCH] hgr: oval: pageflipping --- graphics/hgr/plasma/Makefile | 43 +++++++- graphics/hgr/plasma/jaws.s | 180 ++++++++++++++++++++++++++++++ graphics/hgr/plasma/oval.s | 55 +++------- graphics/hgr/plasma/oval_bot.s | 193 +++++++++++++++++++++++++++++++++ graphics/hgr/plasma/zebra.s | 179 ++++++++++++++++++++++++++++++ linker_scripts/apple2_378.inc | 12 ++ 6 files changed, 620 insertions(+), 42 deletions(-) create mode 100644 graphics/hgr/plasma/jaws.s create mode 100644 graphics/hgr/plasma/oval_bot.s create mode 100644 graphics/hgr/plasma/zebra.s create mode 100644 linker_scripts/apple2_378.inc diff --git a/graphics/hgr/plasma/Makefile b/graphics/hgr/plasma/Makefile index 435de688..67365b56 100644 --- a/graphics/hgr/plasma/Makefile +++ b/graphics/hgr/plasma/Makefile @@ -7,11 +7,15 @@ EMPTYDISK = ../../../empty_disk/empty.dsk all: plasma_hgr.dsk -plasma_hgr.dsk: HELLO OVAL PURPLE_WAVES +plasma_hgr.dsk: HELLO OVAL PURPLE_WAVES ZEBRA JAWS TWIST OVAL_BOT cp $(EMPTYDISK) plasma_hgr.dsk $(DOS33) -y plasma_hgr.dsk SAVE A HELLO $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 OVAL $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 PURPLE_WAVES + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 ZEBRA + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 JAWS + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 TWIST + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0x378 OVAL_BOT ### @@ -28,6 +32,41 @@ oval.o: oval.s ### +OVAL_BOT: oval_bot.o + ld65 -o OVAL_BOT oval_bot.o -C $(LINKERSCRIPTS)/apple2_378.inc + +oval_bot.o: oval_bot.s + ca65 -o oval_bot.o oval_bot.s -l oval_bot.lst + + +### + +JAWS: jaws.o + ld65 -o JAWS jaws.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +jaws.o: jaws.s + ca65 -o jaws.o jaws.s -l jaws.lst + + +### + +TWIST: twist.o + ld65 -o TWIST twist.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +twist.o: twist.s + ca65 -o twist.o twist.s -l twist.lst + + +### + +ZEBRA: zebra.o + ld65 -o ZEBRA zebra.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +zebra.o: zebra.s + ca65 -o zebra.o zebra.s -l zebra.lst + +### + PURPLE_WAVES: purple_waves.o ld65 -o PURPLE_WAVES purple_waves.o -C $(LINKERSCRIPTS)/apple2_c00.inc @@ -37,5 +76,5 @@ purple_waves.o: purple_waves.s ### clean: - rm -f *~ *.o *.lst OVAL PURPLE_WAVES + rm -f *~ *.o *.lst OVAL PURPLE_WAVES ZEBRA JAWS TWIST OVAL_BOT diff --git a/graphics/hgr/plasma/jaws.s b/graphics/hgr/plasma/jaws.s new file mode 100644 index 00000000..9438828a --- /dev/null +++ b/graphics/hgr/plasma/jaws.s @@ -0,0 +1,180 @@ + +; Jaws -- can remove the sine table to make smaller + + +; inner loop after lots of ops = 49 cycles (376320) = 2.6fps +; optimized to 38 (256-entry sine table) = (291840) = 3.4fps +; optimized to 37 (row_sum smc) = (284160) = 3.5fps + +; zero page +GBASL = $26 +GBASH = $27 +YY = $69 +ROW_SUM = $70 + +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + +FRAME = $FC +SUM = $FD +SAVEX = $FE +SAVEY = $FF + +; soft-switches +FULLGR = $C052 +PAGE1 = $C054 + +; ROM routines + +HGR2 = $F3D8 +HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ;================================ + ; Clear screen and setup graphics + ;================================ +oval: + + jsr HGR2 ; set hi-res 140x192, page2, fullscreen + + ;==================== + ; create sinetable + + ldy #0 +sinetable_loop: + tya ; 2 + and #$3f ; wrap sine at 63 entries ; 2 + + cmp #$20 + php ; save pos/negative for later + + and #$1f + + cmp #$10 + bcc sin_left + +sin_right: + ; sec carry should be set? + eor #$FF + adc #$20 ; 32-X +sin_left: + tax + lda sinetable_base,X ; 4+ + lsr + lsr + + plp + bcc sin_done + +sin_negate: + ; carry set here + eor #$ff + adc #0 + +sin_done: + sta sinetable,Y + + iny + bne sinetable_loop + + ; NOTE: making gbash/gbasl table wasn't worth it + + ;============================ + ; main loop + ;============================ + +draw_oval: + inc FRAME + + ldx #191 ; YY + stx HGR_Y + +create_yloop: + lda HGR_Y +; ldx #39 ; X is don't care? + ldy #0 + + jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ; restore values + + ldy #39 ; XX + + lda HGR_Y ; YY + +calcsine_div2: + lsr ; 2 + tax + clc + lda sinetable,X + adc FRAME + sta row_sum_smc+1 + + ldx HGR_Y ; YY + + +create_xloop: + + ;===================== + ; critical inner loop + ; every cycle here is 40x192 cycles + ;===================== + + lda sinetable,Y ; 4+ + clc ; 2 +row_sum_smc: + adc #$dd ; row base value ; 2 + + lsr ; double colors ; 2 + ; also puts bit in carry + ; which helps make blue + and #$7 ; mask ; 2 + tax ; 2 + lda colorlookup,X ; lookup in table ; 5 + +ror_nop_smc: + ror ; $6A/$EA ; 2 +; and #$7f ; make all purple + sta (GBASL),Y ; 6 + + lda ror_nop_smc ; toggle ror/nop ; 4 + eor #$80 ; 2 + sta ror_nop_smc ; 4 + + dey ; 2 + bpl create_xloop ; 2/3 + + dec HGR_Y + bne create_yloop + + ; we skip drawing line 0 as it makes it easier + + beq draw_oval + + +colorlookup: +.byte $11,$55,$5d,$7f,$5d,$55,$11 ; use 00 from sinetable +;.byte $00 + +sinetable_base = $F5BA + +;sinetable_base: +; this is actually (32*sin(x)) + +.byte $00,$03,$06,$09,$0C,$0F,$11,$14 +.byte $16,$18,$1A,$1C,$1D,$1E,$1F,$1F +.byte $20 +;,$1F,$1F,$1E,$1D,$1C,$1A,$18 +;.byte $16,$14,$11,$0F,$0C,$09,$06,$03 + + + ; for bot + + jmp oval + +sinetable=$6000 +gbasl = $6100 +gbash = $6200 + diff --git a/graphics/hgr/plasma/oval.s b/graphics/hgr/plasma/oval.s index a3766c0b..c9be9d57 100644 --- a/graphics/hgr/plasma/oval.s +++ b/graphics/hgr/plasma/oval.s @@ -41,51 +41,24 @@ oval: ;==================== ; create sinetable -.if 0 - ldy #0 -sinetable_loop: - tya ; 2 - and #$3f ; wrap sine at 63 entries ; 2 - - tax ; 2 - cmp #$20 ; see if negative ; 2 - bcc sin_pos ; 2/3 - -sin_neg: - lda #0 ; 2 - sbc sinetable_base-32,X ; 4+ - jmp sin_done ; 3 - -sin_pos: - ; carry already clear - lda sinetable_base,X ; 4+ - -sin_done: - sta sinetable,Y - iny - bne sinetable_loop -.endif - - - ldy #0 sinetable_loop: tya ; 2 and #$3f ; wrap sine at 63 entries ; 2 cmp #$20 - php + php ; save pos/negative for later and #$1f cmp #$10 - bcc sin_blah + bcc sin_left sin_right: - sec + ; sec carry should be set? eor #$FF adc #$20 ; 32-X -sin_blah: +sin_left: tax lda sinetable_base,X ; 4+ @@ -93,16 +66,17 @@ sin_blah: bcc sin_done sin_negate: - clc + ; carry set here eor #$ff - adc #1 + adc #0 sin_done: sta sinetable,Y + iny bne sinetable_loop - + ; NOTE: making gbash/gbasl table wasn't worth it ;============================ ; main loop @@ -116,7 +90,7 @@ draw_oval: create_yloop: lda HGR_Y - ldx #39 +; ldx #39 ; X is don't care? ldy #0 jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) @@ -151,6 +125,8 @@ row_sum_smc: adc #$dd ; row base value ; 2 lsr ; double colors ; 2 + ; also puts bit in carry + ; which helps make blue and #$7 ; mask ; 2 tax ; 2 lda colorlookup,X ; lookup in table ; 5 @@ -176,13 +152,12 @@ ror_nop_smc: colorlookup: - .byte $11,$55,$5d,$7f,$5d,$55,$11 ; use 00 from sinetable ;.byte $00 + sinetable_base: ; this is actually (32*sin(x)) - .byte $00,$03,$06,$09,$0C,$0F,$11,$14 .byte $16,$18,$1A,$1C,$1D,$1E,$1F,$1F .byte $20 @@ -190,8 +165,8 @@ sinetable_base: ;.byte $16,$14,$11,$0F,$0C,$09,$06,$03 - ; for bot - - jmp oval sinetable=$6000 +gbasl = $6100 +gbash = $6200 + diff --git a/graphics/hgr/plasma/oval_bot.s b/graphics/hgr/plasma/oval_bot.s new file mode 100644 index 00000000..950620f2 --- /dev/null +++ b/graphics/hgr/plasma/oval_bot.s @@ -0,0 +1,193 @@ +; Ovals + + +; inner loop after lots of ops = 49 cycles (376320) = 2.6fps +; optimized to 38 (256-entry sine table) = (291840) = 3.4fps +; optimized to 37 (row_sum smc) = (284160) = 3.5fps + +; zero page +GBASL = $26 +GBASH = $27 +YY = $69 +ROW_SUM = $70 + +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + +FRAME = $FC +SUM = $FD +SAVEX = $FE +SAVEY = $FF + +; soft-switches +FULLGR = $C052 +PAGE1 = $C054 + +; ROM routines + +HGR2 = $F3D8 +HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ;================================ + ; Clear screen and setup graphics + ;================================ +oval: + + jsr HGR2 ; set hi-res 140x192, page2, fullscreen + + ;==================== + ; create sinetable + + ldy #0 +sinetable_loop: + tya ; 2 + and #$3f ; wrap sine at 63 entries ; 2 + + cmp #$20 + php ; save pos/negative for later + + and #$1f + + cmp #$10 + bcc sin_left + +sin_right: + ; sec carry should be set? + eor #$FF + adc #$20 ; 32-X +sin_left: + tax + lda sinetable_base,X ; 4+ + + plp + bcc sin_done + +sin_negate: + ; carry set here + eor #$ff + adc #0 + +sin_done: + sta sinetable,Y + + iny + bne sinetable_loop + + ; NOTE: making gbash/gbasl table wasn't worth it + + ;============================ + ; main loop + ;============================ + +draw_oval: + inc FRAME + + lda #191 ; YY +; sta HGR_Y + +create_yloop: +; dec HGR_Y + +; lda HGR_Y +; ldx #39 ; X is don't care? + ldy #0 + + jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ; restore values + + ldy #39 ; XX + + lda HGR_Y ; YY + +calcsine_div2: + lsr ; 2 + tax + clc + lda sinetable,X + adc FRAME + sta row_sum_smc+1 + + ldx HGR_Y ; YY + + +create_xloop: + + ;===================== + ; critical inner loop + ; every cycle here is 40x192 cycles + ;===================== + + lda sinetable,Y ; 4+ + clc ; 2 +row_sum_smc: + adc #$dd ; row base value ; 2 + + lsr ; double colors ; 2 + ; also puts bit in carry + ; which helps make blue + and #$7 ; mask ; 2 + tax ; 2 + lda colorlookup,X ; lookup in table ; 5 + +ror_nop_smc: + ror ; $6A/$EA ; 2 +; and #$7f ; make all purple + sta (GBASL),Y ; 6 + + lda ror_nop_smc ; toggle ror/nop ; 4 + eor #$80 ; 2 + sta ror_nop_smc ; 4 + + dey ; 2 + bpl create_xloop ; 2/3 + + dec HGR_Y + lda HGR_Y + bne create_yloop + + ; we skip drawing line 0 as it makes it easier + +flip_pages: + + ; Y should be $FF here + + iny + lda HGR_PAGE + cmp #$20 + beq done_page + iny +done_page: + ldx PAGE1,Y ; set display page to PAGE1 or PAGE2 + + eor #$60 ; flip draw page between $400/$800 + sta HGR_PAGE + + bne draw_oval ; bra + + +colorlookup: +.byte $11,$55,$5d,$7f,$5d,$55,$11 ; use 00 from sinetable +;.byte $00 + + +sinetable_base: +; this is actually (32*sin(x)) +.byte $00,$03,$06,$09,$0C,$0F,$11,$14 +.byte $16,$18,$1A,$1C,$1D,$1E,$1F,$1F +.byte $20 +;,$1F,$1F,$1E,$1D,$1C,$1A,$18 +;.byte $16,$14,$11,$0F,$0C,$09,$06,$03 + + + ; for bot + ; 3F5 - 7d = 378 + jmp oval + +sinetable=$6000 +gbasl = $6100 +gbash = $6200 + diff --git a/graphics/hgr/plasma/zebra.s b/graphics/hgr/plasma/zebra.s new file mode 100644 index 00000000..39751e63 --- /dev/null +++ b/graphics/hgr/plasma/zebra.s @@ -0,0 +1,179 @@ +; Ovals + + +; inner loop after lots of ops = 49 cycles (376320) = 2.6fps +; optimized to 38 (256-entry sine table) = (291840) = 3.4fps +; optimized to 37 (row_sum smc) = (284160) = 3.5fps + +; zero page +GBASL = $26 +GBASH = $27 +YY = $69 +ROW_SUM = $70 + +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + +FRAME = $FC +SUM = $FD +SAVEX = $FE +SAVEY = $FF + +; soft-switches +FULLGR = $C052 +PAGE1 = $C054 + +; ROM routines + +HGR2 = $F3D8 +HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ;================================ + ; Clear screen and setup graphics + ;================================ +oval: + + jsr HGR2 ; set hi-res 140x192, page2, fullscreen + + ;==================== + ; create sinetable + + ldy #0 +sinetable_loop: + tya ; 2 + and #$3f ; wrap sine at 63 entries ; 2 + + cmp #$20 + php ; save pos/negative for later + + and #$1f + + cmp #$10 + bcc sin_left + +sin_right: + ; sec carry should be set? + eor #$FF + adc #$20 ; 32-X +sin_left: + tax + lda sinetable_base,X ; 4+ + + plp + bcc sin_done + +sin_negate: + ; carry set here + eor #$ff + adc #0 + +sin_done: + sta sinetable,Y + + iny + bne sinetable_loop + + ; NOTE: making gbash/gbasl table wasn't worth it + + ;============================ + ; main loop + ;============================ + +draw_oval: + inc FRAME + + ldx #191 ; YY + stx HGR_Y + +create_yloop: + lda HGR_Y + ldx #39 + ldy #0 + + jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ; restore values + + ldy #39 ; XX + + lda HGR_Y ; YY + +calcsine_div2: + lsr ; 2 + tax + clc + lda sinetable,X + adc FRAME + sta row_sum_smc+1 + + ldx HGR_Y ; YY + + +create_xloop: + + ;===================== + ; critical inner loop + ; every cycle here is 40x192 cycles + ;===================== + + lda sinetable,Y ; 4+ + clc ; 2 +row_sum_smc: + adc #$dd ; row base value ; 2 + +; lsr ; double colors ; 2 + and #$fe ; mask ; 2 + tax ; 2 + lda colorlookup,X ; lookup in table ; 5 + +ror_nop_smc: + ror ; $6A/$EA ; 2 +; and #$7f ; make all purple + sta (GBASL),Y ; 6 + + lda ror_nop_smc ; toggle ror/nop ; 4 + eor #$80 ; 2 + sta ror_nop_smc ; 4 + + dey ; 2 + bpl create_xloop ; 2/3 + + dec HGR_Y + bne create_yloop + + ; we skip drawing line 0 as it makes it easier + + beq draw_oval + + +colorlookup: + +.byte $11,$11,$55,$55,$5d,$5d +.byte $7f,$7f,$5d,$5d,$55,$55 +.byte $11,$11,$00 ; use 00 from sinetable +;.byte $00 + +;.byte $11,$55,$5d,$7f,$5d,$55,$11 ; use 00 from sinetable +;.byte $00 + +sinetable_base: +; this is actually (32*sin(x)) + +.byte $00,$03,$06,$09,$0C,$0F,$11,$14 +.byte $16,$18,$1A,$1C,$1D,$1E,$1F,$1F +.byte $20 +;,$1F,$1F,$1E,$1D,$1C,$1A,$18 +;.byte $16,$14,$11,$0F,$0C,$09,$06,$03 + + + ; for bot + + jmp oval + +sinetable=$6000 +gbasl = $6100 +gbash = $6200 + diff --git a/linker_scripts/apple2_378.inc b/linker_scripts/apple2_378.inc new file mode 100644 index 00000000..8e1015fb --- /dev/null +++ b/linker_scripts/apple2_378.inc @@ -0,0 +1,12 @@ +MEMORY { + ZP: start = $00, size = $1A, type = rw; + RAM: start = $378, size = $8E00, file = %O; +} + +SEGMENTS { +CODE: load = RAM, type = ro; +RODATA: load = RAM, type = ro; +DATA: load = RAM, type = rw; +BSS: load = RAM, type = bss, define = yes; +ZEROPAGE: load = ZP, type = zp; +}