From 265ca7b7ec7c99be10d4557dc50249801dd9e72d Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 25 Jan 2022 14:16:08 -0500 Subject: [PATCH] sine: work on small sines --- graphics/hgr/sine/Makefile | 51 ++++++++++++++++++++ graphics/hgr/sine/approx_sine.s | 60 +++++++++++++++++++++++ graphics/hgr/sine/hello.bas | 2 + graphics/hgr/sine/rom_sine.s | 85 +++++++++++++++++++++++++++++++++ graphics/hgr/sine/thick_sine.s | 75 +++++++++++++++++++++++++++++ 5 files changed, 273 insertions(+) create mode 100644 graphics/hgr/sine/Makefile create mode 100644 graphics/hgr/sine/approx_sine.s create mode 100644 graphics/hgr/sine/hello.bas create mode 100644 graphics/hgr/sine/rom_sine.s create mode 100644 graphics/hgr/sine/thick_sine.s diff --git a/graphics/hgr/sine/Makefile b/graphics/hgr/sine/Makefile new file mode 100644 index 00000000..6ffc900f --- /dev/null +++ b/graphics/hgr/sine/Makefile @@ -0,0 +1,51 @@ +include ../../../Makefile.inc + +DOS33 = ../../../utils/dos33fs-utils/dos33 +TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft +LINKERSCRIPTS = ../../../linker_scripts +EMPTYDISK = ../../../empty_disk/empty.dsk + +all: plasma_hgr.dsk + +plasma_hgr.dsk: HELLO APPROX_SINE THICK_SINE ROM_SINE + cp $(EMPTYDISK) plasma_hgr.dsk + $(DOS33) -y plasma_hgr.dsk SAVE A HELLO + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 APPROX_SINE + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 THICK_SINE + $(DOS33) -y plasma_hgr.dsk BSAVE -a 0xc00 ROM_SINE + + +### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +### + +APPROX_SINE: approx_sine.o + ld65 -o APPROX_SINE approx_sine.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +approx_sine.o: approx_sine.s + ca65 -o approx_sine.o approx_sine.s -l approx_sine.lst + +### + +THICK_SINE: thick_sine.o + ld65 -o THICK_SINE thick_sine.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +thick_sine.o: thick_sine.s + ca65 -o thick_sine.o thick_sine.s -l thick_sine.lst + +### + +ROM_SINE: rom_sine.o + ld65 -o ROM_SINE rom_sine.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +rom_sine.o: rom_sine.s + ca65 -o rom_sine.o rom_sine.s -l rom_sine.lst + +### + +clean: + rm -f *~ *.o *.lst THICK_SINE ROM_SINE APPROX_SINE + diff --git a/graphics/hgr/sine/approx_sine.s b/graphics/hgr/sine/approx_sine.s new file mode 100644 index 00000000..36805ff8 --- /dev/null +++ b/graphics/hgr/sine/approx_sine.s @@ -0,0 +1,60 @@ +; approx sine + +; uses two parabolas to approximate sine +; see https://codebase64.org/doku.php?id=base:generating_approximate_sines_in_assembly + +VALUE_L = $F0 +VALUE_H = $F1 +DELTA_L = $F2 +DELTA_H = $F3 + + + +approx_sine: + + +initSineTable: + + ldy #$3f + ldx #$00 + stx VALUE_L + stx VALUE_H + stx DELTA_L + stx DELTA_H + + + ; Accumulate the delta (normal 16-bit addition) + +outer_loop: + lda VALUE_L + clc + adc DELTA_L + sta VALUE_L + lda VALUE_H + adc DELTA_H + sta VALUE_H + + ; Reflect the value around for a sine wave + + sta sinetable+$c0,X + sta sinetable+$80,Y + eor #$ff + sta sinetable+$40,X + sta sinetable+$00,Y + + ; Increase the delta, which creates the "acceleration" for a parabola + lda DELTA_L + adc #$10 ; this value adds up to the proper amplitude + sta DELTA_L + bcc skip_oflo + inc DELTA_H +skip_oflo: + ; Loop + inx + dey + bpl outer_loop + +end: + jmp end + +sinetable=$6000 diff --git a/graphics/hgr/sine/hello.bas b/graphics/hgr/sine/hello.bas new file mode 100644 index 00000000..133a44bb --- /dev/null +++ b/graphics/hgr/sine/hello.bas @@ -0,0 +1,2 @@ +5 HOME +10 PRINT CHR$(4);"CATALOG" diff --git a/graphics/hgr/sine/rom_sine.s b/graphics/hgr/sine/rom_sine.s new file mode 100644 index 00000000..64be94cf --- /dev/null +++ b/graphics/hgr/sine/rom_sine.s @@ -0,0 +1,85 @@ +; try to get sine table from ROM + +; 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 + + ;================================ + ; Clear screen and setup graphics + ;================================ +rom_sine: + + ;========================================== + ; create sinetable using ROM cosine table + + ldy #0 +sinetable_loop: + tya ; 2 + and #$3f ; wrap sine at 63 entries ; 2 + + cmp #$20 + php ; save pos/negative for later + + and #$1f + + beq sin_noadjust + + cmp #$10 + bcc sin_left ; blt + bne sin_right + + lda #$20 ; force sin(16) to $20 instead of $1F + bne sin_noadjust + +sin_right: + ; sec carry should be set here + sbc #$10 ; X-16 (x=16..31) + bne sin_both ; bra +sin_left: + ; clc ; carry should be clear + eor #$FF ; 16-X (but plus one twos complement) + adc #$11 +sin_both: + tax + lda sinetable_base,X ; 4+ + + lsr ; rom value is *256 + lsr ; we want *32 + lsr +sin_noadjust: + + plp + bcc sin_done + +sin_negate: + ; carry set here + eor #$ff +; adc #0 ; off by one, does it matter? + +sin_done: + sta sinetable,Y + + iny + bne sinetable_loop + +end: + jmp end + +sinetable_base = $F5BA + +sinetable=$6000 + + diff --git a/graphics/hgr/sine/thick_sine.s b/graphics/hgr/sine/thick_sine.s new file mode 100644 index 00000000..152f058a --- /dev/null +++ b/graphics/hgr/sine/thick_sine.s @@ -0,0 +1,75 @@ +; thick sine + +; 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 + + +thick_sine: + + ;================== + ; create sinetable + + ldy #0 ; Y is 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 ; blt + +sin_right: + ; sec carry should be set here + 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 ; FIXME: this makes things off by 1 + +sin_done: + sta sinetable,Y + + iny + bne sinetable_loop + + ; Y is 0 at this point? + +done: + jmp done + + +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 + + +sinetable=$6000 +