From 2795f3e49168e2829a5ba9b3059535c5038d4c10 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 25 Jan 2022 17:03:41 -0500 Subject: [PATCH] thick_cos: optimizations --- graphics/hgr/sine/Makefile | 20 +++++- graphics/hgr/sine/oops3_cos.s | 129 ++++++++++++++++++++++++++++++++++ graphics/hgr/sine/oops4_cos.s | 128 +++++++++++++++++++++++++++++++++ graphics/hgr/sine/thick_cos.s | 18 ++--- 4 files changed, 285 insertions(+), 10 deletions(-) create mode 100644 graphics/hgr/sine/oops3_cos.s create mode 100644 graphics/hgr/sine/oops4_cos.s diff --git a/graphics/hgr/sine/Makefile b/graphics/hgr/sine/Makefile index 944fdde8..bcf5e1ee 100644 --- a/graphics/hgr/sine/Makefile +++ b/graphics/hgr/sine/Makefile @@ -8,7 +8,7 @@ EMPTYDISK = ../../../empty_disk/empty.dsk all: plasma_hgr.dsk plasma_hgr.dsk: HELLO APPROX_SINE THICK_SINE THICK_COS TABLE_SINE ROM_SINE \ - OOPS_COS OOPS2_COS + OOPS_COS OOPS2_COS OOPS3_COS OOPS4_COS cp $(EMPTYDISK) plasma_hgr.dsk $(DOS33) -y plasma_hgr.dsk SAVE A HELLO $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 APPROX_SINE @@ -18,6 +18,8 @@ plasma_hgr.dsk: HELLO APPROX_SINE THICK_SINE THICK_COS TABLE_SINE ROM_SINE \ $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 THICK_COS $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 OOPS_COS $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 OOPS2_COS + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 OOPS3_COS + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 OOPS4_COS ### @@ -66,8 +68,21 @@ OOPS2_COS: oops2_cos.o oops2_cos.o: oops2_cos.s ca65 -o oops2_cos.o oops2_cos.s -l oops2_cos.lst +### +OOPS3_COS: oops3_cos.o + ld65 -o OOPS3_COS oops3_cos.o -C $(LINKERSCRIPTS)/apple2_c00.inc +oops3_cos.o: oops3_cos.s + ca65 -o oops3_cos.o oops3_cos.s -l oops3_cos.lst + +### + +OOPS4_COS: oops4_cos.o + ld65 -o OOPS4_COS oops4_cos.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +oops4_cos.o: oops4_cos.s + ca65 -o oops4_cos.o oops4_cos.s -l oops4_cos.lst ### @@ -89,5 +104,6 @@ rom_sine.o: rom_sine.s clean: rm -f *~ *.o *.lst THICK_SINE THICK_COS \ - TABLE_SINE ROM_SINE APPROX_SINE OOPS_COS OOPS2_COS + TABLE_SINE ROM_SINE APPROX_SINE \ + OOPS_COS OOPS2_COS OOPS3_COS OOPS4_COS diff --git a/graphics/hgr/sine/oops3_cos.s b/graphics/hgr/sine/oops3_cos.s new file mode 100644 index 00000000..ac1894c6 --- /dev/null +++ b/graphics/hgr/sine/oops3_cos.s @@ -0,0 +1,129 @@ +; thick sine + +; 105 bytes -- original with table sine +; 89 bytes -- use ROM cosine table to generate sine table +; 86 bytes -- put sine table in zero page +; 89 bytes -- adjust to add #1 to avoid thick line at middle +; 87 bytes -- Y is 0 after HGR2 +; 83 bytes -- optimize color flip +; 79 bytes -- use X +; 74 bytes -- optimize frame +; 72 bytes -- depend on X being 0 at end of loop +; 71 bytes -- rerrange so can beq rather than jmp + +; zero page +sinetable=$70 +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + + +FRAME = $FF + +; ROM routines + +HGR2 = $F3D8 +HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) +HPLOT0 = $F457 ; plot at (Y,X), (A) +costable_base = $F5BA + + ;================================ + ; Clear screen and setup graphics + ;================================ +thick_sine: + + jsr HGR2 ; set hi-res 140x192, page2, fullscreen + ; A and Y both 0 at end + +; try to get sine table from ROM + +rom_sine: + + ;========================================== + ; create sinetable using ROM cosine table + +; ldy #0 + ldx #$f +sinetable_loop: + + lda costable_base+1,Y +force_zero: + lsr ; rom value is *256 + lsr ; we want *32 +; lsr + adc #$60 + + sta sinetable+$10,Y + sta sinetable+$00,X + eor #$FF + sec + adc #$0 + sta sinetable+$30,Y + sta sinetable+$20,X + + lda #0 ; hack, ROM cosine table doesn't + ; have a good zero for some reason + + iny + dex + + beq force_zero + bpl sinetable_loop + + ; x is FF at this point + + + ;============================ + ; main loop + ;============================ + + inx +draw_sine: + ; X is 0 here, either from above, or from end of loop + +; ldx #0 ; HGR_X + + ; offset next time through + + inc FRAME + + ; X is zero here + + ; 10 bytes to flip color (was 14) + + txa +; lda #$FF + bit FRAME + bvs color_white + eor #$FF +color_white: + sta HGR_COLOR + + +circle_loop: + + ; get sine value + + lda FRAME + and #$3f ; wrap value to 0..63 + tay + lda sinetable,Y + + ; multiply by 2 and center on screen $60 is midscreen +; asl +; adc #$60 + +; ldx HGR_X ; saved in HGR_X + ldy #0 ; saved in HGR_XH + jsr HPLOT0 ; plot at (Y,X), (A) + + inc FRAME + + ldx HGR_X + inx ; HGR_X + + bne circle_loop + + beq draw_sine ; bra diff --git a/graphics/hgr/sine/oops4_cos.s b/graphics/hgr/sine/oops4_cos.s new file mode 100644 index 00000000..f7ea8d76 --- /dev/null +++ b/graphics/hgr/sine/oops4_cos.s @@ -0,0 +1,128 @@ +; thick sine + +; 105 bytes -- original with table sine +; 89 bytes -- use ROM cosine table to generate sine table +; 86 bytes -- put sine table in zero page +; 89 bytes -- adjust to add #1 to avoid thick line at middle +; 87 bytes -- Y is 0 after HGR2 +; 83 bytes -- optimize color flip +; 79 bytes -- use X +; 74 bytes -- optimize frame +; 72 bytes -- depend on X being 0 at end of loop +; 71 bytes -- rerrange so can beq rather than jmp + +; zero page +sinetable=$70 +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + + +FRAME = $FF + +; ROM routines + +HGR2 = $F3D8 +HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) +HPLOT0 = $F457 ; plot at (Y,X), (A) +costable_base = $F5BA + + ;================================ + ; Clear screen and setup graphics + ;================================ +thick_sine: + + jsr HGR2 ; set hi-res 140x192, page2, fullscreen + ; A and Y both 0 at end + +; try to get sine table from ROM + +rom_sine: + + ;========================================== + ; create sinetable using ROM cosine table + +; ldy #0 + ldx #$f +sinetable_loop: + + lda costable_base+1,Y +force_zero: + lsr ; rom value is *256 + lsr ; we want *32 +; lsr + + sta sinetable+$10,Y + sta sinetable+$00,X + eor #$FF + sec + adc #$0 + sta sinetable+$30,Y + sta sinetable+$20,X + + lda #0 ; hack, ROM cosine table doesn't + ; have a good zero for some reason + + iny + dex + + beq force_zero + bpl sinetable_loop + + ; x is FF at this point + + + ;============================ + ; main loop + ;============================ + + inx +draw_sine: + ; X is 0 here, either from above, or from end of loop + +; ldx #0 ; HGR_X + + ; offset next time through + + inc FRAME + + ; X is zero here + + ; 10 bytes to flip color (was 14) + + txa +; lda #$FF + bit FRAME + bvs color_white + eor #$FF +color_white: + sta HGR_COLOR + + +circle_loop: + + ; get sine value + + lda FRAME + and #$3f ; wrap value to 0..63 + tay + lda sinetable,Y + + ; multiply by 2 and center on screen $60 is midscreen +; asl + adc #$60 + +; ldx HGR_X ; saved in HGR_X + ldy #0 ; saved in HGR_XH + jsr HPLOT0 ; plot at (Y,X), (A) + + inc FRAME + + ldx HGR_X + inx ; HGR_X + + bne circle_loop + + beq draw_sine ; bra diff --git a/graphics/hgr/sine/thick_cos.s b/graphics/hgr/sine/thick_cos.s index 7db8dbe5..1ba9fd9e 100644 --- a/graphics/hgr/sine/thick_cos.s +++ b/graphics/hgr/sine/thick_cos.s @@ -9,6 +9,8 @@ ; 79 bytes -- use X ; 74 bytes -- optimize frame ; 72 bytes -- depend on X being 0 at end of loop +; 71 bytes -- rerrange so can beq rather than jmp +; 70 bytes -- update the sine table division ; zero page sinetable=$70 @@ -43,7 +45,7 @@ rom_sine: ;========================================== ; create sinetable using ROM cosine table -; ldy #0 +; ldy #0 ; from HGR2 ldx #$f sinetable_loop: @@ -51,7 +53,7 @@ sinetable_loop: force_zero: lsr ; rom value is *256 lsr ; we want *32 - lsr +; lsr sta sinetable+$10,Y sta sinetable+$00,X @@ -89,17 +91,16 @@ draw_sine: ; X is zero here - ; 10 bytes to flip color (was 14) + ; 9 bytes to flip color (was 14) txa ; lda #$FF bit FRAME - bvs color_white + bvs color_black eor #$FF -color_white: +color_black: sta HGR_COLOR - circle_loop: ; get sine value @@ -110,7 +111,8 @@ circle_loop: lda sinetable,Y ; multiply by 2 and center on screen $60 is midscreen - asl +; asl + clc adc #$60 ; ldx HGR_X ; saved in HGR_X @@ -124,4 +126,4 @@ circle_loop: bne circle_loop - beq draw_sine + beq draw_sine ; bra