Parallel out sine wave from custom sine table
Okay, so I've been trying to output a discrete signal to a resistor dac on pins p0-p8 for three days to no avail. I'm hoping someone can tell me my fatal mistakes, I'm desperate. Thanks.
con
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
obj
var
long cog1
pub main
cog1:=cognew(@sinwave, 0) +1
dat
org
sinwave
mov DIRA, #$FF
mov t1, #0
mov sin, #0
mov acc, #0
mov ptr, #sintab
:loop add ptr, #128
movs :set, ptr
:set mov outa, 0-0
testn acc,#255 wz
if_z mov acc,#0
if_z mov ptr, #sintab
if_nz add acc, #1
if_nz add ptr, #1
jmp #:loop
sin long 0
t1 long 0
acc long 0
ptr long 0
sintab long 128, 132, 135, 138, 141, 144, 147, 150, 153, 157, 160, 163, 166, 169, 172, 175, 177, 180, 183, 186
long 189, 192, 194, 197, 200, 202, 205, 207, 210, 212, 214, 217, 219, 221, 223, 225, 227, 229, 231, 233
long 235, 237, 238, 240, 241, 243, 244, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 255, 255, 256
long 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 254, 253, 253, 252, 251, 250, 249, 248
long 247, 246, 244, 243, 241, 240, 238, 237, 235, 233, 231, 229, 227, 225, 223, 221, 219, 217, 214, 212
long 210, 207, 205, 202, 200, 197, 194, 192, 189, 186, 183, 180, 177, 175, 172, 169, 166, 163, 160, 157
long 153, 150, 147, 144, 141, 138, 135, 132, 129, 125, 122, 119, 116, 113, 110, 107, 104, 100, 97, 94
long 91, 88, 85, 82, 80, 77, 74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40
long 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7
long 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2
long 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 28
long 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77
long 80, 82, 85, 88, 91, 94, 97, 100, 104, 107, 110, 113, 116, 119, 122, 125

Comments
Also, the table only has 236 entries. As for testn, this will do a binary AND of !255 == $FFFFFF00 against acc. As acc is 0 it will always result in the Z flag being set which keeps acc at 0. Maybe you meant to use cmp & Co (or do the reset for if_nz)?
As for checking, add labels at the appropriate locations, press F9 and place the cursor on the label you're interested in. The status line will give you info as to object location and cog offset.
con _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 obj var long cog1 pub main cog1:=cognew(@sinwave, 0) +1 dat org sinwave mov DIRA, #$FF mov t1, #0 mov acc, #0 mov ptr, #sintab add ptr, #1 :loop movs :set, ptr :set mov outa, 0-0 testn acc,top wz if_z jmp #:accum :reset mov acc,#0 mov ptr, #sintab jmp #:loop :accum add acc, #1 add ptr, #1 jmp #:loop t1 long 0 acc long 0 ptr long 0 top long 255 sintab long 128, 132, 135, 138, 141, 144, 147, 150, 153, 157, 160, 163, 166, 169, 172, 175, 177, 180, 183, 186 long 189, 192, 194, 197, 200, 202, 205, 207, 210, 212, 214, 217, 219, 221, 223, 225, 227, 229, 231, 233 long 235, 237, 238, 240, 241, 243, 244, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 255, 255, 256 long 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 254, 253, 253, 252, 251, 250, 249, 248 long 247, 246, 244, 243, 241, 240, 238, 237, 235, 233, 231, 229, 227, 225, 223, 221, 219, 217, 214, 212 long 210, 207, 205, 202, 200, 197, 194, 192, 189, 186, 183, 180, 177, 175, 172, 169, 166, 163, 160, 157 long 153, 150, 147, 144, 141, 138, 135, 132, 129, 125, 122, 119, 116, 113, 110, 107, 104, 100, 97, 94 long 91, 88, 85, 82, 80, 77, 74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40 long 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7 long 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2 long 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 28 long 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77 long 80, 82, 85, 88, 91, 94, 97, 100, 104, 107, 110, 113, 116, 119, 122, 125,128I tried to use the nop between the two instructions, and it seemed to just slow down the frequency. It didn't have any effect on the break to zero.CON _clkmode = XTAL1 + PLL16X _xinfreq = 5_000_000 PUB main cognew(@sinwave, 0) DAT org 0 sinwave mov dira, #$FF :reset mov ptr, #sintab :loop movs :set, ptr add ptr, #1 :set mov outa, 0-0 cmp ptr, #sintab_end wz if_e jmp #:reset ' reached end of table jmp #:loop ptr long 0 sintab long 128, 132, 135, 138, 141, 144, 147, 150, 153, 157, 160, 163, 166, 169, 172, 175, 177, 180, 183, 186 long 189, 192, 194, 197, 200, 202, 205, 207, 210, 212, 214, 217, 219, 221, 223, 225, 227, 229, 231, 233 long 235, 237, 238, 240, 241, 243, 244, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 255, 255, 256 long 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 254, 253, 253, 252, 251, 250, 249, 248 long 247, 246, 244, 243, 241, 240, 238, 237, 235, 233, 231, 229, 227, 225, 223, 221, 219, 217, 214, 212 long 210, 207, 205, 202, 200, 197, 194, 192, 189, 186, 183, 180, 177, 175, 172, 169, 166, 163, 160, 157 long 153, 150, 147, 144, 141, 138, 135, 132, 129, 125, 122, 119, 116, 113, 110, 107, 104, 100, 97, 94 long 91, 88, 85, 82, 80, 77, 74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40 long 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7 long 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2 long 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 28 long 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77 long 80, 82, 85, 88, 91, 94, 97, 100, 104, 107, 110, 113, 116, 119, 122, 125 sintab_end DATEdit: @kuroneko
You have beaten me by a few seconds
Your algorithms are too complicated, what's with all this checking for sin_tab_end?
Why not use the simple Direct Digital Synthesis (DDS) technique?
1) Have sine table of 256 longs.
2) Have 32 bit counter, call it "phase" that maintains he current position in the wave.
3) Use only the top 8 bits of phase to index the sin table for the current sample value.
4) Add a small amount "delta" to the phase value on every iteration.
5) Changing the value of delta changes your frequency with a very high resolution.
With this there is no need to check for end of table, the 8 bits of phase used to index the table will just wrap around to the table as required.
If you arrange for the table to start at location zero in your code you save a few instructions as you don't need to add any base offset address of the table when you access it.
A guy called Jesper did this in 6 lines of AVR code in his miniDDS project: www.myplace.nu/avr/minidds/index.htm
I know you are not normally happy with just "it works"