base:triangle_waveform
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:triangle_waveform [2015-04-17 04:34] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Examination of SID triangle waveform ====== | ||
+ | |||
+ | ===== Data recorded on the triangle waveform ($10) ===== | ||
+ | |||
+ | The data are recorded using a REU. The recording is done like this: | ||
+ | < | ||
+ | ;* Program 1 * | ||
+ | |||
+ | ;Turn off screen and sprites | ||
+ | |||
+ | ... | ||
+ | |||
+ | ;Set frequency of voice 3 | ||
+ | |||
+ | LDA #<freq | ||
+ | LDX #>freq | ||
+ | STA $D40E | ||
+ | STX $D40F | ||
+ | |||
+ | ;Reset waveform | ||
+ | |||
+ | LDA #$08 ;Set test bit | ||
+ | STA $D412 | ||
+ | |||
+ | ;Setup REU to sample register $D41B for $10000 cycles | ||
+ | |||
+ | ... | ||
+ | |||
+ | ;Start recording | ||
+ | |||
+ | LDA # | ||
+ | LDX # | ||
+ | STA $D412 ; | ||
+ | STX $DF01 ; | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | Furthermore, | ||
+ | < | ||
+ | ;* Program 2 * | ||
+ | |||
+ | ... | ||
+ | |||
+ | LDA #$10 | ||
+ | STA $D412 ; | ||
+ | LDA $D41B ; | ||
+ | STA Haps ;Save value | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | The table below summarizes the recordings (all values in hex): | ||
+ | < | ||
+ | Frequency | ||
+ | |||
+ | 8000 | ||
+ | 4000 | ||
+ | 2000 | ||
+ | 1000 | ||
+ | FFFF | ||
+ | DEAD | ||
+ | 28 29 2B 2D 2E 30 32 34 35 37 39 3B 3C 3E 40 42 43 45 | ||
+ | 47 49 4A 4C 4E 50 51 53 55 56 58 5A 5C 5D 5F 61 63 64 | ||
+ | </ | ||
+ | Legend: | ||
+ | * Frequency is the value stored to $D40E and $D40F. | ||
+ | * Haps is the value of the Haps variable from program 2. | ||
+ | * REU is the data collected with the REU after running program 1. | ||
+ | |||
+ | Conclusion: The triangle waveform starts with value $00 and goes to $ff linearly. Then it goes from $ff to $00 linearly. | ||
+ | |||
+ | |||
+ | (As a sidenote, I'll mention that the data for the sawtooth waveform at frequency $8000 is Haps= 02, REU= 02 03 03 04 04 ... FE FE FF FF 00 00 01 01 ...) | ||
+ | |||
+ | The Haps variable is the value of the waveform on one cycle earlier than the REU starts recording. | ||
+ | |||
+ | Further data used to investigate the frequency/ | ||
+ | < | ||
+ | Frequency | ||
+ | Haps+REU, Number of this*value | ||
+ | |||
+ | 0001 7FFC*00 8000*01 8000*02 ... | ||
+ | 0002 3FFC*00 4000*01 4000*02 ... | ||
+ | 0003 2AA7*00 2AAB*01 2AAA*02 2AAB*03 | ||
+ | 0004 1FFC*00 2000*01 2000*02 ... | ||
+ | 0005 1996*00 199A*01 1999*02 199A*03 1999*04 | ||
+ | 0006 1552*00 1555*01 1555*02 1556*03 1555*04 1555*05 1556*06 | ||
+ | 0007 1245*00 1249*01 1249*02 1249*03 1249*04 1249*05 1249*06 124A*07 | ||
+ | 1249*08 | ||
+ | 0008 0FFC*00 1000*01 1000*02 ... | ||
+ | 0009 0E35*00 0E39*01 0E39*02 | ||
+ | 000A 0CC9*00 0CCD*01 | ||
+ | 000B 0B9F*00 | ||
+ | </ | ||
+ | Legend: | ||
+ | * Frequency is the value stored to $D40E and $D40F. | ||
+ | * Haps+REU is the contents of the Haps variable from program 2 and the contents of the REU after running program 1. | ||
+ | * The format is number of times of repeation * value. (i.e. 7FFC*00 means that the value " | ||
+ | |||
+ | Conclusion: We know that with the STA $D412; LDA $D41B construct, A contains the value of the waveform after 4 cycles. This is consistence with the observation that the number of times the value $00 appears generally is 4 lower than the number of times the other values appear. | ||
+ | |||
+ | The overall behaviour can thus be simulated with this C-program: | ||
+ | < | ||
+ | void Triangle(long Frequency) { | ||
+ | long Cycle; /* Count of Phi2 cycles */ | ||
+ | |||
+ | long Delay= 0x8000; | ||
+ | long Counter= 0; /* Initial value is 0 */ | ||
+ | |||
+ | for (Cycle=0; ;Cycle= Cycle+1) { | ||
+ | |||
+ | /* Build waveform: Triangle */ | ||
+ | if (Counter | ||
+ | Waveform[cycle]= Counter; | ||
+ | else | ||
+ | Waveform[cycle]= 511- Counter; | ||
+ | |||
+ | /* | ||
+ | For the sawtooth waveform, use: | ||
+ | |||
+ | Waveform[Cycle]= Counter / 2; | ||
+ | */ | ||
+ | |||
+ | /* Handle frequency-function */ | ||
+ | Delay = Delay- Frequency; | ||
+ | |||
+ | /* Frequency overflow? */ | ||
+ | while (Delay =0 ) do { | ||
+ | /* For frequencies above $8000, this will be executed twice */ | ||
+ | |||
+ | Delay = Delay + 0x8000; | ||
+ | |||
+ | /* Calculate new value for waveform */ | ||
+ | Counter= (Counter+1) % 512; /* Keep in range 0..511 */ | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | The above program (when checked) is only capable of reproducing the output of register $1B. We can't be sure that the true output of pin 27 of the SID is the same. In this respect, there are two issues: | ||
+ | |||
+ | * Is the output digital and 8 bit? | ||
+ | * Is the output aligned to the ø2 clock? | ||
+ | |||
+ | ===== Is the output digital and 8 bit? ===== | ||
+ | |||
+ | People have used oscilloscopes and concluded that this is the output is digital and probably 8 bit. This can also be checked with this program, if you have decent audio-equipment: | ||
+ | < | ||
+ | jsr $e544 ; | ||
+ | |||
+ | ldx #0 | ||
+ | stx $d021 ; | ||
+ | stx $d020 ; | ||
+ | ;(The black color reduces noise with my equipment) | ||
+ | |||
+ | lda #11 ;As of request from Andreas with kernal R2 :-) | ||
+ | col sta $d800, | ||
+ | inx | ||
+ | bne col | ||
+ | |||
+ | lda #$01 ;Frequency 1 | ||
+ | sta $d40e | ||
+ | lda #$00 | ||
+ | sta $d40f | ||
+ | |||
+ | lda # | ||
+ | sta $d412 | ||
+ | lda #$f0 | ||
+ | sta $d413 | ||
+ | |||
+ | lda # | ||
+ | ;Change for other waveforms | ||
+ | sta $d412 | ||
+ | |||
+ | lda #$0f ;Max volume: $f | ||
+ | sta $d418 | ||
+ | |||
+ | ldx $d41b | ||
+ | loop1 stx temp | ||
+ | |||
+ | loop2 ldx $d41b | ||
+ | cpx temp | ||
+ | bne loop2 | ||
+ | |||
+ | lda $0400, | ||
+ | eor #$80 | ||
+ | sta $0400,x | ||
+ | jmp loop1 | ||
+ | |||
+ | temp .byte $00 | ||
+ | </ | ||
+ | |||
+ | Turn up the volume of the TV-set and you can hear the " | ||
+ | |||
+ | You can also try other waveforms (substitute the lda #$81 with lda #$11 for triangle or lda #$21 for sawtooth. Pulse ($41) requires definition of the pulse width in $d410 and $d411), but these are all much faster and/or the changes in the waveform are small, so it is not as easy to hear the distinct ticks. | ||
+ | |||
+ | ===== Is the output aligned to the ø2 clock? ===== | ||
+ | |||
+ | This is an open question as of now (23 Mar 1995 :-)). My feeling is that the output is aligned, but this is only a feeling based on the fact that, all, the SID has available to synchronize with, is the ø2 feed. | ||
+ | |||
+ | I believe examination of this requires an oscilloscope, | ||
+ | What should be done is to display the ø2 clock along with the pin 27 output with a triangle waveform at frequency $ffff (Just modify the above program to use frequency $ffff and triangle waveform). If the waveform change only once every ø2 cycle, the output is ø2 aligned and thus " | ||
+ | |||
+ | Observation: | ||
+ | < | ||
+ | ... | ||
+ | |||
+ | lda #$08 ;Reset waveform: Test bit is 1. | ||
+ | sta $d412 | ||
+ | |||
+ | lda # | ||
+ | sta $d40e | ||
+ | lda #$80 | ||
+ | sta $d40f | ||
+ | |||
+ | ... | ||
+ | |||
+ | ldy #$00 ;Clear test bit | ||
+ | lda # | ||
+ | ldx #$90 ;REU command | ||
+ | sty $d412 ;The difference! | ||
+ | sta $d412 | ||
+ | stx $df01 | ||
+ | </ | ||
+ | the recorded data are all 4 cycles behind! I.e. the first value in the REU data is not $05, but $09. The similar thing happens if you use the capture in program 2: Instead of getting $04, you get $08. The 4 cycle delay is the time, the sta $d412 takes. | ||
+ | |||
+ | If you change the ldy #$00 (test bit=0) to ldy #$08 (test bit=1), the effect disappears, so the conclusion is: | ||
+ | * The triangle counter counts all the time, whether or not the waveform is activated. The counter is held reset to 0 when the test bit is 1 (supposedly), | ||
+ | Another explanation, | ||
+ | |||
+ | I have not examined whether this is the case for the sawtooth and the pulse waveforms, but my bet is, this is the case. | ||
base/triangle_waveform.txt · Last modified: 2015-04-17 04:34 by 127.0.0.1