The keyH:keyL pair are used to increment oscH:oscL per channel, for efficiency Marcel coded this using a 15bit value in keyH:keyL that spans bits 7:0 in keyH and bits 6:0 in keyL; this means that bit 7 in keyL should be 0, (i.e. the top most bit of keyL=0). To answer your above question, keyL should not exceed 127.denjhang wrote: ↑19 Mar 2022, 07:59 I want to make a vibrato-like effect, which requires the gigatron to emit audio frequencies that don't exist in the ROM's note table. These frequency values may lie between two adjacent pitches in the note table. So I made some small changes to store relative pitch changes in my note array. The increased and decreased pitch values are then written to keyH and keyL, but I find that my pitch adjustment algorithm seems to be somewhat imprecise. I'm not sure if keyL will exceed 100.
In practice if you want to convert a 15bit linear value to a 15bit Gigatron internal frequency you do the following:
1) Start off with a 16bit unsigned value and mask off the top 15 bits.
2) Right shift the low byte by 1 bit.
3) Set the high bit of the low byte to zero if your right shift did not do it.
Or use a look up table, you only need a 256 byte look up table for the low byte; (technically you could get away with 128 bytes spanned in an interlace fashion across a 256byte page, which would leave 128 single interlaced bytes free for something else).
See this for a more comprehensive explanation and additional notes about wavX and wavA.
https://github.com/kervinck/gigatron-ro ... /Audio.txt
Here is the actual native code that updates each individual sound channel:
Code: Select all
ld(0x7f) #6 Update sound channel anda([Y,oscL]) #7 adda([Y,keyL]) #8 st([Y,oscL]) #9 anda(0x80,X) #10 ld([X]) #11 adda([Y,oscH]) #12 adda([Y,keyH]) #13 st([Y,oscH]) #14 anda(0xfc) #15 xora([Y,wavX]) #16 ld(AC,X) #17 ld([Y,wavA]) #18 ld(soundTable>>8,Y) #19 adda([Y,X]) #20 bmi(pc()+3) #21 bra(pc()+3) #22 anda(63) #23 ld(63) #23(!) adda([sample]) #24 st([sample]) #25