From 76397192423f46a83d5c045ffbabc81efb26c6ae Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 25 Jan 2022 16:42:56 -0500 Subject: [PATCH] thick_cos: update optimization --- graphics/hgr/sine/Makefile | 26 ++++++- graphics/hgr/sine/oops2_cos.s | 132 ++++++++++++++++++++++++++++++++++ graphics/hgr/sine/oops_cos.s | 125 ++++++++++++++++++++++++++++++++ graphics/hgr/sine/rom_sine.s | 4 ++ graphics/hgr/sine/thick_cos.s | 108 ++++++++++++++-------------- 5 files changed, 341 insertions(+), 54 deletions(-) create mode 100644 graphics/hgr/sine/oops2_cos.s create mode 100644 graphics/hgr/sine/oops_cos.s diff --git a/graphics/hgr/sine/Makefile b/graphics/hgr/sine/Makefile index 5b5e2e5c..944fdde8 100644 --- a/graphics/hgr/sine/Makefile +++ b/graphics/hgr/sine/Makefile @@ -7,7 +7,8 @@ EMPTYDISK = ../../../empty_disk/empty.dsk all: plasma_hgr.dsk -plasma_hgr.dsk: HELLO APPROX_SINE THICK_SINE THICK_COS TABLE_SINE ROM_SINE +plasma_hgr.dsk: HELLO APPROX_SINE THICK_SINE THICK_COS TABLE_SINE ROM_SINE \ + OOPS_COS OOPS2_COS cp $(EMPTYDISK) plasma_hgr.dsk $(DOS33) -y plasma_hgr.dsk SAVE A HELLO $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 APPROX_SINE @@ -15,6 +16,8 @@ plasma_hgr.dsk: HELLO APPROX_SINE THICK_SINE THICK_COS TABLE_SINE ROM_SINE $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 ROM_SINE $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 THICK_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 ### @@ -47,6 +50,25 @@ thick_cos.o: thick_cos.s ca65 -o thick_cos.o thick_cos.s -l thick_cos.lst +### + +OOPS_COS: oops_cos.o + ld65 -o OOPS_COS oops_cos.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +oops_cos.o: oops_cos.s + ca65 -o oops_cos.o oops_cos.s -l oops_cos.lst + +### + +OOPS2_COS: oops2_cos.o + ld65 -o OOPS2_COS oops2_cos.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +oops2_cos.o: oops2_cos.s + ca65 -o oops2_cos.o oops2_cos.s -l oops2_cos.lst + + + + ### TABLE_SINE: table_sine.o @@ -67,5 +89,5 @@ rom_sine.o: rom_sine.s clean: rm -f *~ *.o *.lst THICK_SINE THICK_COS \ - TABLE_SINE ROM_SINE APPROX_SINE + TABLE_SINE ROM_SINE APPROX_SINE OOPS_COS OOPS2_COS diff --git a/graphics/hgr/sine/oops2_cos.s b/graphics/hgr/sine/oops2_cos.s new file mode 100644 index 00000000..c5d51a50 --- /dev/null +++ b/graphics/hgr/sine/oops2_cos.s @@ -0,0 +1,132 @@ +; 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 + +; zero page +sinetable=$70 +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + +SAVEX = $FE +SAVEY = $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 + ;============================ + +; dex + stx HGR_COLOR ; required + ; though in emulator it defaults to $FF + +draw_circle: + + ldy #0 + sty SAVEY + +blah_smc: + ldx #0 + stx SAVEX + +circle_loop: + lda SAVEX + and #$3f + tax + lda sinetable,X + +; clc + asl + + ; $60 is midscreen + adc #$60 + ldx SAVEY + ldy #0 + jsr HPLOT0 ; plot at (Y,X), (A) + + inc SAVEX + + inc SAVEY + bne circle_loop + +done: + inc blah_smc+1 + + ; 14 bytes to flip color + +; lda SAVEX +; and #$3f +; cmp #$3f +; bne blah + + bit SAVEX + bvc blah + + lda #$FF +blah: + eor #$FF + sta HGR_COLOR + +; lda HGR_COLOR ; flip draw color $ff/$00/$ff +; eor #$ff +; sta HGR_COLOR +;blah: + + jmp draw_circle diff --git a/graphics/hgr/sine/oops_cos.s b/graphics/hgr/sine/oops_cos.s new file mode 100644 index 00000000..523db987 --- /dev/null +++ b/graphics/hgr/sine/oops_cos.s @@ -0,0 +1,125 @@ +; 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 + +; zero page +sinetable=$70 +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + +SAVEX = $FE +SAVEY = $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 + ;============================ + +; dex + stx HGR_COLOR ; required + ; though in emulator it defaults to $FF + +draw_circle: + + ldy #0 + sty SAVEY + +blah_smc: + ldx #0 + stx SAVEX + +circle_loop: + lda SAVEX + and #$3f + tax + lda sinetable,X + +; clc + asl + + ; $60 is midscreen + adc #$60 + ldx SAVEY + ldy #0 + jsr HPLOT0 ; plot at (Y,X), (A) + + inc SAVEX + + inc SAVEY + bne circle_loop + +done: + inc blah_smc+1 + +; lda SAVEX +; and #$3f +; cmp #$3f +; bne blah + + bit SAVEX + bvc blah + + lda HGR_COLOR ; flip draw color $ff/$00/$ff + eor #$ff + sta HGR_COLOR +blah: + + jmp draw_circle diff --git a/graphics/hgr/sine/rom_sine.s b/graphics/hgr/sine/rom_sine.s index 16ddab0f..8ff37c21 100644 --- a/graphics/hgr/sine/rom_sine.s +++ b/graphics/hgr/sine/rom_sine.s @@ -21,6 +21,10 @@ force_zero: sta sinetable+$10,X sta sinetable+$00,Y eor #$FF + + sec ; these aren't strictly necessary + adc #$0 ; depending how accurate you want it + sta sinetable+$30,X sta sinetable+$20,Y diff --git a/graphics/hgr/sine/thick_cos.s b/graphics/hgr/sine/thick_cos.s index 36c33b93..7db8dbe5 100644 --- a/graphics/hgr/sine/thick_cos.s +++ b/graphics/hgr/sine/thick_cos.s @@ -3,6 +3,12 @@ ; 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 ; zero page sinetable=$70 @@ -12,8 +18,8 @@ HGR_Y = $E2 HGR_COLOR = $E4 HGR_PAGE = $E6 -SAVEX = $FE -SAVEY = $FF + +FRAME = $FF ; ROM routines @@ -37,87 +43,85 @@ rom_sine: ;========================================== ; create sinetable using ROM cosine table - ldx #0 - ldy #$f +; ldy #0 + ldx #$f sinetable_loop: - lda costable_base+1,X + lda costable_base+1,Y force_zero: lsr ; rom value is *256 lsr ; we want *32 lsr - sta sinetable+$10,X - sta sinetable+$00,Y + sta sinetable+$10,Y + sta sinetable+$00,X eor #$FF - sta sinetable+$30,X - sta sinetable+$20,Y + sec + adc #$0 + sta sinetable+$30,Y + sta sinetable+$20,X - lda #0 + lda #0 ; hack, ROM cosine table doesn't + ; have a good zero for some reason - inx - dey + iny + dex beq force_zero bpl sinetable_loop - ; y is FF at this point + ; x is FF at this point ;============================ ; main loop ;============================ -; dey - sty HGR_COLOR ; required - ; though in emulator it defaults to $FF + inx +draw_sine: + ; X is 0 here, either from above, or from end of loop -draw_circle: +; ldx #0 ; HGR_X - ldy #0 - sty SAVEY + ; 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 -blah_smc: - ldx #0 - stx SAVEX circle_loop: - lda SAVEX - and #$3f - tax - lda sinetable,X -; clc + ; 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 - - ; $60 is midscreen adc #$60 - ldx SAVEY - ldy #0 +; ldx HGR_X ; saved in HGR_X + ldy #0 ; saved in HGR_XH jsr HPLOT0 ; plot at (Y,X), (A) - inc SAVEX + inc FRAME + + ldx HGR_X + inx ; HGR_X - inc SAVEY bne circle_loop -done: - inc blah_smc+1 - - lda SAVEX - and #$3f - cmp #$3f - bne blah - lda HGR_COLOR - eor #$ff - sta HGR_COLOR -blah: - - jmp draw_circle - - - - - - + beq draw_sine