Published using Google Docs
( SIDcog.fth )
Updated automatically every 5 minutes

TACHYON [~

DECIMAL

IFNDEF SIDEMU

                         ." SIDEMU and CombinedWaveForms binary must be loaded first !!! "

}

FORGET SIDcog.fth

pub SIDcog.fth                ." 140107-2230 Tachyon Forth adaption by PBJ of SID/MOS8580 emulator v1.3 (C) 2012 Johannes Ahlebrand" ;

{

The SIDcog interface has been restructured so that it is easier to interact with the SID.

Sounds can be produced and changed just from the serial console.

i.e.

0 CHAN 8 3 4 2 ADSR ON HP ON BP OFF LP ON SAWTOOTH #1000 NOTE

or

: DEMO        0 CHAN 8 3 4 2 ADSR ON HP ON BP OFF LP ON SAWTOOTH #1000 NOTE ;

then type DEMO to play that effect

NOTE: this code is incomplete and quite possible ridden with typos etc - will test this out soon

TO DO: Generate table for PASM section (WIP - extracting code bytes from BST listing)

}

( The original 6581 SID chip block diagram )

( SID CHANNEL REGISTERS )

\ Create a long aligned byte array table for all the SID variables which are read by the SID cog

32 BYTES sidtbl

  0 ORG                \ compile as channel offsets (computed as offsets in sidtbl)

  2 DS freq

  2 DS pulseWidth          

  1 DS control

  1 DS ad        

  1 DS sr  

\ next 2 channels

  7 DS+                \ channel 2

  7 DS+                \ channel 3

( SID FILTERS )

  sidtbl 21 + ORG          \ compile these as absolute addresses

  1 DS filterLo         \ lowpass cutoff        

  1 DS filterHi                \ highpass cutoff

  1 DS filterRes               \ filter enables + resonance

  1 DS volume                \ filter selects + volume

  1 DS oldVolume

LONG SIDSample,cog

\ function to convert 2 nibbles into a byte

pri NIB>BYTE ( highnib lownib -- byte )

        $0F AND SWAP $0F AND 4 SHL OR                \ (release&$F) | ((sustain&$F)<<4)

          ;

\ Set or reset the mask at addr depending upon state (true=set)

pri BIT ( state mask addr -- )        

         ROT BIT!

        ;

WORD sidadr                        \ holds the base address of the current channel

pub CHAN ( channel -- )

         7 * sidtbl + sidadr W!                \ Set base address

         ;

pub @SID ( offset -- addr )        sidadr W@ + ;

( setADSR )

pub ADSR ( attack, decay, sustain, release -- )

{   Sets the envelope values of a SID channel                

  attack - The attack value. (0 - 15)                              

  decay - The decay value. (0 - 15)                                

  sustain - The sustain value. (0 - 15)                                    

  release - The release value. (0 - 15)                            

}

         NIB>BYTE sr @SID C!

         NIB>BYTE ad @SID C!

         ;

( setPulseWidth )

pub PULSE ( pulseWidth -- )

{   Sets the pulse width of the preselected SID channel                  

 pulseWidth - The 12 bit pulse width value to use. (0 - 4095)

 - The pulse width value affects square waves ONLY.    

   PWout = (pulseWidth/40.95)%          

}  

         pulseWidth @SID W!

         ;

( setFreq )

pub FREQ ( freq  -- )

{   Sets the frequency of the preselected SID channel                  

  freq - The 16 bit frequency value. (0 - 65535)                  

  (The SID can output tone frequencies from 0 - 3.9 kHz)          

}

         freq @SID W!

        ;

( updateRegisters )

pub UPDATE ( source -- )

{   Update all 25 SID registers                      

    source - A pointer to an array containing 25 bytes to update

    the 25 SID registers with.                              

}

        sidtbl 25 CMOVE

;

( resetRegisters )

pub !SID

{   Reset all 25 SID registers  }

         sidtbl 25 ERASE

         ;

pub VOLUME ( volume -- )

{   Sets the main volume                          

  value - A value betwen 0 and 15.                                

}

         $0F AND volume C@ $0F ANDN OR volume C!

         ;

( FILTER REGISTERS )

( setResonance )

pub RESONANCE ( resonanceValue -- )

{   Sets the resonance value of the filter                

  resonanceValue - The resonance value to use. (0 - 15)            

}

         4 SHL filterRes C@ $0F AND OR filterRes C!

;

 

pub CUTLOW ( lowcutoff -- )

         7 AND filterLo C!

         ;

( setCutoff )

pub CUTOFF ( cutoffValue -- )

{   Sets the cutoff frequency of the 12-bit filter }

         DUP CUTLOW 3 SHR

pub CUTHIGH ( hicutoff -- )

         filterHi C!

         ;

( setFilterMask )

pub FILTERMASK ( mask --- )

{   Enable/Disable filtering on channels }

         filterRes C@ $0F ANDN OR filterRes C!

         ;

( setFilterType )

pub FILTERS ( mask -- ) ( b0=lp b1 =bp b2=hp b3=3off )

{   Enable/Disable filter types using additive bit-field masks }

         4 SHL volume C@ $0F AND OR volume C!

        ;

pub HP ( on/off -- )        \ Turn high-pass filter on or off

         $40 volume BIT

         ;

pub BP ( on/off -- )

         $20 volume BIT

         ;

pub LP ( on/off -- )

         $10 volume BIT

         ;

( CONTROL REGISTERS - each channel )

\ control register bit field masks - Multiple waveforms are ANDed, not added

$80        == &NOISE

$40        == &SQUARE                \ Select SQUARE wave

$20        == &SAW

$10        == &TRIANGLE

4        == &RING

2        == &SYNCH                \ Sync with OSC3

1        == &GATE                \ ADSR is triggered, or release

pub NOISE ( on/off -- )

         &NOISE

pri CTL! ( on/off mask -- )        \ set or reset control bit

         control @SID BIT

         ;

pub SQUARE ( on/off -- )

         &SQUARE CTL!

         ;

pub SAWTOOTH ( on/off -- )        \ Turn on or off SAWTOOTH for the preselected channel

         &SAW CTL!

         ;

pub TRIANGLE ( on/off -- )

         &TRIANGLE CTL!

         ;

pub RINGMOD ( on/off -- )

         &RING CTL!

         ;

pub SYNCH ( on/off -- )

         &SYNC CTL!

         ;

pub GATE ( on/off -- )

         &GATE CTL!

         ;

( setWaveform )

pub WAVE ( waveform -- )

{   Sets the waveform of the preselected SID channel                  

  waveform - The waveform combination to use.                      

  e.g. sid.setWaveform(x, sid#SQUARE | sid#SAW)                    

}

        control @SID C@ $0F AND OR control @SID C!

        ;

        

( enableRingmod )

pub RINGMODS ( chmask -- )

{   Enable/Disable ring modulation on channels

 - Channel 3 modulates channel 1                                  

 - Channel 1 modulates channel 2                                            

 - Channel 2 modulates channel 3                                    

}

         &RING

pri CONTROLS ( chmask regmask -- )

        3 0 DO OVER I MASK AND OVER control sidtbl + I 7 * + BIT LOOP

        2DROP

        ;

( enableSynchronization )

pub SYNCHS ( chmask -- )

{   Enable/Disable oscillator synchronization on channels        

 - Channel 3 synchronizes channel 1                                

 - Channel 1 synchronizes channel 2                                        

 - Channel 2 synchronizes channel 3                                  

}

         &SYNCH CONTROLS

;

        

pub PLAY ( waveform, freq, attack, decay, sustain, release -- )

{   Plays a tone in a SID channel.                    

  ( The channel is selected beforehand using CHAN )

                                                                   

  freq - The 16 bit frequency value use. (0 - 65535)              

  (The SID can output tone frequencies from 0 - 3.9 kHz)          

                                                                   

  waveform - The waveform combination to use.                      

  e.g. sid.play(x, x, sid#SQUARE | sid#SAW, x, x, x, x)            

         

  attack - The attack value. (0 - 15)                              

  decay - The decay value. (0 - 15)                                

  sustain - The sustain value. (0 - 15)                            

  release - The release value. (0 - 15)                            

  When calling this method, the envelope generator enters the

  "attack - decay - sustain" phase. Don't forget to call          

  "noteOff" before using it so the envelope is in release phase

}

        ADSR FREQ

         WAVE                                \ activate last to play sound

        ;

pub NOTE ( freq -- )

{   Plays a tone in a SID channel                    

 freq - The 16 bit frequency value use. (0 - 65535)  

*NB - a freq of 0 will mute the channel (OFF NOTE)

 (The SID can output tone frequencies from 0 - 3.9 kHz)          

 - Don't forget to set the envelope values for the channel    

 before using this method.                                        

                                                                 

 - Make sure you have set the waveform for the channel before

 using this method.                                              

                                                                   

 - When calling this method, the envelope generator enters the

 "attack - decay - sustain" phase. Don't forget to call          

 "noteOff" before calling this method to set the envelope to  

 release phase.                                                  

}

         DUP FREQ

         &GATE CTL!

;

 

\ startSID

pub RUNSID ( right, left -- )

{   Starts SIDcog in a single cog                      

  Returns a pointer to the first SID register in hub memory    

  on success; otherwise returns 0.                                

  right - The pin to output the right channel to. 0 = Not used        

  left - The pin to output the left channel to. 0 = Not used  

}

        DUP $18000000 OR arg1 !

         OVER $18000000 OR arg2 !

         MASK SWAP MASK OR r1 !

          CLKFREQ C64_CLOCK_FREQ 5 SHL / sampleRate !

         combinedWaveFortms combTableAddr !

        SIDEMU sidtbl COGNEW ( code pars -- ret )

         1+ ?DUP IF freq W@ ELSE 0 THEN  

         ;

{           PASM object loader - reads code bytes from BST listing  

\ redefine | temporarily so that it compiles 4 bytes into the table

pri |

         DEPTH 4 =>

         IF

           >L ROT | SWAP | | L> |                \ compile 4 bytes into current location (table)

         THEN

         [COMPILE] \                                \ ignore rest of line - we just want the 4 bytes

         ;

IMMEDIATE

' NOOP unum W!                 \ nullify number exception processing - TO DO: needs to be able to recognize numbers that begin with A-F

!SP                                \ clean up stack so we can detect depth

TABLE SIDEMU                \ create a table to hold the assembled PASM image

\ -------> CODE BYTES  <------ this is all we are interested in extracting

0018(0000) 93 ED BF A0 | SIDEMU            mov          dira, r1

001C(0001) 91 F1 BF A0 |                   mov          ctra, arg1

0020(0002) 92 F3 BF A0 |                   mov          ctrb, arg2

0024(0003) F1 93 BF A0 |                   mov          waitCounter, cnt

0028(0004) 8F 93 BF 80 |                   add          waitCounter, sampleRate

002C(0005) F0 95 BF A0 | getRegisters  mov           tempValue, par                         ' Read in first long ( 16bit frequency / 16bit pulse-width )

0030(0006) CA 45 BF 08 |                   rdlong        frequency1, tempValue

0034(0007) A2 51 BF A0 |                   mov           pulseWidth1, frequency1

0038(0008) 04 50 FF 2C |                   shl           pulseWidth1, #4                        ' Shift in "12 bit" pulse width value( make it 32 bits )

003C(0009) 82 51 BF 64 |                   andn          pulseWidth1, mask20bit

0040(000A) 83 45 BF 60 |                   and           frequency1, mask16bit                  ' Mask out 16 bit frequency value

0044(000B) 0D 44 FF 2C |                   shl           frequency1, #13

0048(000C) 04 94 FF 80 |                   add           tempValue, #4                          ' Read in next long ( Control register / ADSR )

004C(000D) CA 57 BF 08 |                   rdlong        selectedWaveform1, tempValue

0050(000E) AB 3F BF A0 |                   mov           controlRegister1, selectedWaveform1

0054(000F) AB 23 BF A0 |                   mov           arg1, selectedWaveform1                '|

0058(0010) 08 22 FF 28 |                   shr           arg1, #8                               '|

005C(0011) 60 CB FE 5C |                   call          #getADSR                               '|

0060(0012) 93 69 BF A0 |                   mov           decay1, r1                             '|

0064(0013) 60 CB FE 5C |                   call          #getADSR                               '|

0068(0014) 93 63 BF A0 |                   mov           attack1, r1                            '|  Convert 4bit ADSR "presets" to their corresponding

006C(0015) 60 CB FE 5C |                   call          #getADSR                               '|  32bit values using attack/decay tables.

0070(0016) 93 75 BF A0 |                   mov           release1, r1                           '|

0074(0017) 91 6F BF A0 |                   mov           sustain1, arg1                         '|

0078(0018) 04 6E FF 20 |                   ror           sustain1, #4                           '|

007C(0019) 91 6F BF 68 |                   or            sustain1, arg1                         '|

0080(001A) 04 6E FF 20 |                   ror           sustain1, #4                           '|

0084(001B) 04 56 FF 28 |                   shr           selectedWaveform1, #4                  '   Mask out waveform selection

0088(001C) 0F 56 FF 60 |                   and           selectedWaveform1, #15

008C(001D) 01 3E 7F 61 |                   test          controlRegister1, #1                wc

0090(001E) 02 5C 7F 86 |                   cmp           envelopeState1, #2                  wz

0094(001F) 00 5C E3 A0 |  if_z_and_c   mov           envelopeState1, #0

0098(0020) 02 5C C7 A0 |  if_nz_and_nc mov           envelopeState1, #2

009C(0021) 04 94 FF 80 |                   add           tempValue, #4                          ' Read in first long ( 16bit frequency / 16bit pulse-width )

00A0(0022) CA 47 BF 08 |                   rdlong        frequency2, tempValue

00A4(0023) A3 53 BF A0 |                   mov           pulseWidth2, frequency2

00A8(0024) 04 52 FF 2C |                   shl           pulseWidth2, #4                        ' Shift in "12 bit" pulse width value( make it 32 bits )

00AC(0025) 82 53 BF 64 |                   andn          pulseWidth2, mask20bit

00B0(0026) 83 47 BF 60 |                   and           frequency2, mask16bit                  ' Mask out 16 bit frequency value

00B4(0027) 0D 46 FF 2C |                   shl           frequency2, #13

00B8(0028) 04 94 FF 80 |                   add           tempValue, #4                          ' Read in next long ( Control register / ADSR )

00BC(0029) CA 59 BF 08 |                   rdlong        selectedWaveform2, tempValue

00C0(002A) AC 41 BF A0 |                   mov           controlRegister2,  selectedWaveform2

00C4(002B) AC 23 BF A0 |                   mov           arg1, selectedWaveform2                '|

00C8(002C) 08 22 FF 28 |                   shr           arg1, #8                               '|

00CC(002D) 60 CB FE 5C |                   call          #getADSR                               '|

00D0(002E) 93 6B BF A0 |                   mov           decay2, r1                             '|

00D4(002F) 60 CB FE 5C |                   call          #getADSR                               '|

00D8(0030) 93 65 BF A0 |                   mov           attack2, r1                            '|  Convert 4bit ADSR "presets" to their corresponding

00DC(0031) 60 CB FE 5C |                   call          #getADSR                               '|  32bit values using attack/decay tables.

00E0(0032) 93 77 BF A0 |                   mov           release2, r1                           '|

00E4(0033) 91 71 BF A0 |                   mov           sustain2, arg1                         '|

00E8(0034) 04 70 FF 20 |                   ror           sustain2, #4                           '|

00EC(0035) 91 71 BF 68 |                   or            sustain2, arg1                         '|

00F0(0036) 04 70 FF 20 |                   ror           sustain2, #4                           '|

00F4(0037) 04 58 FF 28 |                   shr           selectedWaveform2, #4                  '   Mask out waveform selection

00F8(0038) 0F 58 FF 60 |                   and           selectedWaveform2, #15

00FC(0039) 01 40 7F 61 |                   test          controlRegister2, #1                wc

0100(003A) 02 5E 7F 86 |                   cmp           envelopeState2, #2                  wz

0104(003B) 00 5E E3 A0 |  if_z_and_c   mov           envelopeState2, #0

0108(003C) 02 5E C7 A0 |  if_nz_and_nc mov           envelopeState2, #2

010C(003D) 04 94 FF 80 |                   add           tempValue, #4                          ' Read in first long ( 16bit frequency / 16bit pulse-width )

0110(003E) CA 49 BF 08 |                   rdlong        frequency3, tempValue                  '

0114(003F) A4 55 BF A0 |                   mov           pulseWidth3, frequency3

0118(0040) 04 54 FF 2C |                   shl           pulseWidth3, #4                        ' Shift in "12 bit" pulse width value( make it 32 bits )

011C(0041) 82 55 BF 64 |                   andn          pulseWidth3, mask20bit

0120(0042) 83 49 BF 60 |                   and           frequency3, mask16bit                  ' Mask out 16 bit frequency value

0124(0043) 0D 48 FF 2C |                   shl           frequency3, #13

0128(0044) 04 94 FF 80 |                   add           tempValue, #4                          ' Read in next long ( Control register / ADSR )

012C(0045) CA 5B BF 08 |                   rdlong        selectedWaveform3, tempValue

0130(0046) AD 43 BF A0 |                   mov           controlRegister3,  selectedWaveform3

0134(0047) AD 23 BF A0 |                   mov           arg1, selectedWaveform3                '|

0138(0048) 08 22 FF 28 |                   shr           arg1, #8                               '|

013C(0049) 60 CB FE 5C |                   call          #getADSR                               '|

0140(004A) 93 6D BF A0 |                   mov           decay3, r1                             '|

0144(004B) 60 CB FE 5C |                   call          #getADSR                               '|

0148(004C) 93 67 BF A0 |                   mov           attack3, r1                            '|  Convert 4bit ADSR "presets" to their corresponding

014C(004D) 60 CB FE 5C |                   call          #getADSR                               '|  32bit values using attack/decay tables.

0150(004E) 93 79 BF A0 |                   mov           release3, r1                           '|

0154(004F) 91 73 BF A0 |                   mov           sustain3, arg1                         '|

0158(0050) 04 72 FF 20 |                   ror           sustain3, #4                           '|

015C(0051) 91 73 BF 68 |                   or            sustain3, arg1                         '|

0160(0052) 04 72 FF 20 |                   ror           sustain3, #4                           '|

0164(0053) 04 5A FF 28 |                   shr           selectedWaveform3, #4                  ' Mask out waveform selection

0168(0054) 0F 5A FF 60 |                   and           selectedWaveform3, #15

016C(0055) 01 42 7F 61 |                   test          controlRegister3, #1                wc

0170(0056) 02 60 7F 86 |                   cmp           envelopeState3, #2                  wz

0174(0057) 00 60 E3 A0 |  if_z_and_c   mov           envelopeState3, #0

0178(0058) 02 60 C7 A0 |  if_nz_and_nc mov           envelopeState3, #2

017C(0059) 04 94 FF 80 |                   add           tempValue, #4                          '|

0180(005A) CA 8D BF 08 |                   rdlong        filterControl, tempValue               '|

0184(005B) C6 83 BF A0 |                   mov           filterCutoff, filterControl            '|

0188(005C) 10 8C FF 28 |                   shr           filterControl, #16                     '|  Filter control

018C(005D) 05 82 FF 28 |                   shr           filterCutoff, #5                       '|

0190(005E) 07 82 FF 64 |                   andn          filterCutoff, #7                       '|

0194(005F) C6 95 BF A0 |                   mov           tempValue, filterControl               '|

0198(0060) 07 94 FF 60 |                   and           tempValue, #7                          '|  Filter cutoff frequency

019C(0061) CA 83 BF 68 |                   or            filterCutoff, tempValue                '|

01A0(0062) 84 83 BF 60 |                   and           filterCutoff, mask11bit                '|

01A4(0063) 8C 83 BF 80 |                   add           filterCutoff, filterOffset             '|

01A8(0064) C6 8B BF A0 |                   mov           filterMode_Volume, filterControl   '|  Main volume and filter mode

01AC(0065) 08 8A FF 28 |                   shr           filterMode_Volume, #8                  '|

01B0(0066) C6 81 BF A0 |                   mov           filterResonance,filterControl          '|

01B4(0067) F0 80 FF 60 |                   and           filterResonance,#$F0                   '|  Filter Resonance level

01B8(0068) 04 80 FF 28 |                   shr           filterResonance,#4                     '|

01BC(0069) A2 4B BF 81 | SID               add          phaseAccumulator1, frequency1        wc ' Add frequency value to phase accumulator 1

01C0(006A) 02 40 CF 64 |   if_nc           andn         controlRegister2, #2

01C4(006B) 0A 40 7F 62 |                   test         controlRegister2, #10                wz ' Sync oscilator 2 to oscillator 1 if sync = on

01C8(006C) 00 4C D7 A0 |   if_nz           mov          phaseAccumulator2, #0                   ' Or reset counter 2 when bit 4 of control register is 1

01CC(006D) A3 4D BF 81 |                   add          phaseAccumulator2, frequency2        wc

01D0(006E) 02 42 CF 64 |   if_nc           andn         controlRegister3, #2

01D4(006F) 0A 42 7F 62 |                   test         controlRegister3, #10                wz ' Sync oscilator 3 to oscillator 2 if sync = on

01D8(0070) 00 4E D7 A0 |   if_nz           mov          phaseAccumulator3, #0                   ' Or reset oscilator 3 when bit 4 of control register is 1

01DC(0071) A4 4F BF 81 |                   add          phaseAccumulator3, frequency3        wc

01E0(0072) 02 3E CF 64 |   if_nc           andn         controlRegister1, #2

01E4(0073) 0A 3E 7F 62 |                   test         controlRegister1, #10                wz ' Sync oscilator 1 to oscillator 3 if sync = on

01E8(0074) 00 4A D7 A0 |   if_nz           mov          phaseAccumulator1, #0                   ' Or reset oscilator 1 when bit 4 of control register is 1

01EC(0075) 02 56 7F 86 | Saw1              cmp          selectedWaveform1, #2                wz

01F0(0076) A5 23 BF A0 |                   mov          arg1, phaseAccumulator1

01F4(0077) 99 00 68 5C |   if_z            jmp          #Envelope1

01F8(0078) 01 56 7F 87 | Triangle1         cmp          selectedWaveform1, #1                wz, wc

01FC(0079) 80 00 54 5C |   if_nz           jmp          #Square1

0200(007A) 01 22 FF 2D |                   shl          arg1, #1                             wc

0204(007B) 7E 23 B3 6C |   if_c            xor          arg1, mask32bit

0208(007C) 04 3E 7F 62 |                   test         controlRegister1, #4                 wz '|

020C(007D) 85 4F 17 62 |   if_nz           test         phaseAccumulator3, val31bit          wz '| These 3 lines handles ring modulation

0210(007E) 7E 23 97 6C |   if_nz           xor          arg1, mask32bit                         '|

0214(007F) 99 00 7C 5C |                   jmp          #Envelope1

0218(0080) 04 56 7F 86 | Square1           cmp          selectedWaveform1, #4                wz

021C(0081) A5 51 AB 85 |   if_z            sub          pulseWidth1, phaseAccumulator1   wc ' C holds the pulse width modulated square wave

0220(0082) 7E 23 AB 70 |   if_z            muxc         arg1, mask32bit

0224(0083) 99 00 68 5C |   if_z            jmp          #Envelope1

0228(0084) 08 56 7F 86 | Noise1            cmp          selectedWaveform1, #8                wz

022C(0085) 8E 00 54 5C |   if_nz           jmp          #Combined1

0230(0086) 80 23 BF 60 |                   and          arg1, mask28bit

0234(0087) A2 23 BF 85 |                   sub          arg1, frequency1                     wc

0238(0088) 96 23 BF 58 |                   movi         arg1, noiseValue1

023C(0089) 94 23 BF 80 |                   add          arg1, noiseAddValue

0240(008A) 99 00 4C 5C |   if_nc           jmp          #Envelope1

0244(008B) 95 2D 3F 61 |                   test         noiseValue1, noiseTap                wc

0248(008C) 01 2C FF 30 |                   rcr          noiseValue1, #1

024C(008D) 99 00 7C 5C |                   jmp          #Envelope1

0250(008E) 08 56 7F 62 | Combined1         test         selectedWaveform1, #8                wz

0254(008F) 04 56 FF 84 |                   sub          selectedWaveform1, #4

0258(0090) 00 56 FF 40 |                   mins         selectedWaveform1, #0

025C(0091) 08 56 FF 2C |                   shl          selectedWaveform1, #8

0260(0092) A5 95 BF A0 |                   mov          tempValue, phaseAccumulator1

0264(0093) 18 94 FF 28 |                   shr          tempValue, #24

0268(0094) CA 57 BF 80 |                   add          selectedWaveform1, tempValue

026C(0095) 90 57 BF 80 |                   add          selectedWaveform1, combTableAddr

0270(0096) AB 23 8B 00 |   if_nc_and_z rdbyte   arg1, selectedWaveform1

0274(0097) 18 22 CB 2C |   if_nc_and_z shl          arg1, #24

0278(0098) 85 23 B7 A0 |   if_c_or_nz  mov          arg1, val31bit

027C(0099) 8D 95 BF A0 | Envelope1         mov          tempValue, decayDivideRef

0280(009A) 99 95 BF 28 |                   shr          tempValue, decayDivide1

0284(009B) CA 39 3F 85 |                   cmp          envelopeLevel1, tempValue            wc

0288(009C) A2 5C 7F E8 |                   tjnz         envelopeState1, #Env_Dec1            nr

028C(009D) 01 32 CF E0 | Env_At1 if_nc cmpsub   decayDivide1, #1

0290(009E) B1 39 BF 81 |                   add          envelopeLevel1, attack1              wc

0294(009F) 7E 39 B3 A0 |   if_c            mov          envelopeLevel1, mask32bit

0298(00A0) 01 5C F3 A0 |   if_c            mov          envelopeState1, #1

029C(00A1) AC 00 7C 5C |                   jmp          #Amplitude1

02A0(00A2) 01 32 F3 80 | Env_Dec1 if_c add          decayDivide1, #1

02A4(00A3) 9C F9 3E 85 |                   cmp          startLogLevel, envelopeLevel1        wc

02A8(00A4) 01 5C 7F 86 |                   cmp          envelopeState1, #1                   wz

02AC(00A5) AA 00 54 5C |   if_nz           jmp          #Rel1

02B0(00A6) 99 69 8F 28 |   if_nc           shr          decay1, decayDivide1

02B4(00A7) B4 39 BF 84 |                   sub          envelopeLevel1, decay1

02B8(00A8) B7 39 BF 49 |                   min          envelopeLevel1, sustain1             wc

02BC(00A9) AC 00 7C 5C |                   jmp          #Amplitude1

02C0(00AA) 99 75 8F 28 | Rel1 if_nc        shr          release1, decayDivide1

02C4(00AB) BA 39 BF E0 |                   cmpsub   envelopeLevel1, release1

02C8(00AC) 0E 22 FF 28 | Amplitude1        shr          arg1, #14

02CC(00AD) 88 23 BF 84 |                   sub          arg1, val17bit

02D0(00AE) 9C 25 BF A0 |                   mov          arg2, envelopeLevel1

02D4(00AF) 18 24 FF 28 |                   shr          arg2, #24

02D8(00B0) 66 D7 FE 5C |                   call         #multiply

02DC(00B1) 93 7B BF A0 |                   mov          out1, r1

02E0(00B2) 02 58 7F 86 | Saw2              cmp          selectedWaveform2, #2                wz

02E4(00B3) A6 23 BF A0 |                   mov          arg1, phaseAccumulator2

02E8(00B4) D6 00 68 5C |   if_z            jmp          #Envelope2

02EC(00B5) 01 58 7F 87 | Triangle2         cmp          selectedWaveform2, #1                wz, wc

02F0(00B6) BD 00 54 5C |   if_nz           jmp          #Square2

02F4(00B7) 01 22 FF 2D |                   shl          arg1, #1                             wc

02F8(00B8) 7E 23 B3 6C |   if_c            xor          arg1, mask32bit

02FC(00B9) 04 40 7F 62 |                   test         controlRegister2, #4                 wz '|

0300(00BA) 85 4B 17 62 |   if_nz           test         phaseAccumulator1, val31bit          wz '| These 3 lines handles ring modulation

0304(00BB) 7E 23 97 6C |   if_nz           xor          arg1, mask32bit                         '|

0308(00BC) D6 00 7C 5C |                   jmp          #Envelope2

030C(00BD) 04 58 7F 86 | Square2           cmp          selectedWaveform2, #4                wz

0310(00BE) A6 53 AB 85 |   if_z            sub          pulseWidth2, phaseAccumulator2   wc ' C holds the pulse width modulated square wave

0314(00BF) 7E 23 AB 70 |   if_z            muxc         arg1, mask32bit

0318(00C0) D6 00 68 5C |   if_z            jmp          #Envelope2

031C(00C1) 08 58 7F 86 | Noise2            cmp          selectedWaveform2, #8                wz

0320(00C2) CB 00 54 5C |   if_nz           jmp          #Combined2

0324(00C3) 80 23 BF 60 |                   and          arg1, mask28bit

0328(00C4) A3 23 BF 85 |                   sub          arg1, frequency2                     wc

032C(00C5) 97 23 BF 58 |                   movi         arg1, noiseValue2

0330(00C6) 94 23 BF 80 |                   add          arg1, noiseAddValue

0334(00C7) D6 00 4C 5C |   if_nc           jmp          #Envelope2

0338(00C8) 95 2F 3F 61 |                   test         noiseValue2, noiseTap                wc

033C(00C9) 01 2E FF 30 |                   rcr          noiseValue2, #1

0340(00CA) D6 00 7C 5C |                   jmp          #Envelope2

0344(00CB) 08 58 7F 62 | Combined2         test         selectedWaveform2, #8                wz

0348(00CC) 04 58 FF 84 |                   sub          selectedWaveform2, #4

034C(00CD) 00 58 FF 40 |                   mins         selectedWaveform2, #0

0350(00CE) 08 58 FF 2C |                   shl          selectedWaveform2, #8

0354(00CF) A6 95 BF A0 |                   mov          tempValue, phaseAccumulator2

0358(00D0) 18 94 FF 28 |                   shr          tempValue, #24

035C(00D1) CA 59 BF 80 |                   add          selectedWaveform2, tempValue

0360(00D2) 90 59 BF 80 |                   add          selectedWaveform2, combTableAddr

0364(00D3) AC 23 8B 00 |   if_nc_and_z rdbyte   arg1, selectedWaveform2

0368(00D4) 18 22 CB 2C |   if_nc_and_z shl          arg1, #24

036C(00D5) 85 23 B7 A0 |   if_c_or_nz  mov          arg1, val31bit

0370(00D6) 8D 95 BF A0 | Envelope2         mov          tempValue, decayDivideRef

0374(00D7) 9A 95 BF 28 |                   shr          tempValue, decayDivide2

0378(00D8) CA 3B 3F 85 |                   cmp          envelopeLevel2, tempValue            wc

037C(00D9) DF 5E 7F E8 |                   tjnz         envelopeState2, #Env_Dec2            nr

0380(00DA) 01 34 CF E0 | Env_At2 if_nc cmpsub   decayDivide2, #1

0384(00DB) B2 3B BF 81 |                   add          envelopeLevel2, attack2              wc

0388(00DC) 7E 3B B3 A0 |   if_c            mov          envelopeLevel2, mask32bit

038C(00DD) 01 5E F3 A0 |   if_c            mov          envelopeState2, #1

0390(00DE) E9 00 7C 5C |                   jmp          #Amplitude2

0394(00DF) 01 34 F3 80 | Env_Dec2 if_c add          decayDivide2, #1

0398(00E0) 9D F9 3E 85 |                   cmp          startLogLevel,envelopeLevel2         wc

039C(00E1) 01 5E 7F 86 |                   cmp          envelopeState2, #1                   wz

03A0(00E2) E7 00 54 5C |   if_nz           jmp          #Rel2

03A4(00E3) 9A 6B 8F 28 |   if_nc           shr          decay2, decayDivide2

03A8(00E4) B5 3B BF 84 |                   sub          envelopeLevel2, decay2

03AC(00E5) B8 3B BF 49 |                   min          envelopeLevel2, sustain2             wc

03B0(00E6) E9 00 7C 5C |                   jmp          #Amplitude2

03B4(00E7) 9A 77 8F 28 | Rel2 if_nc        shr          release2, decayDivide2

03B8(00E8) BB 3B BF E0 |                   cmpsub   envelopeLevel2, release2

03BC(00E9) 0E 22 FF 28 | Amplitude2        shr          arg1, #14

03C0(00EA) 88 23 BF 84 |                   sub          arg1, val17bit

03C4(00EB) 9D 25 BF A0 |                   mov          arg2, envelopeLevel2

03C8(00EC) 18 24 FF 28 |                   shr          arg2, #24

03CC(00ED) 66 D7 FE 5C |                   call         #multiply

03D0(00EE) 93 7D BF A0 |                   mov          out2, r1

03D4(00EF) 02 5A 7F 86 | Saw3              cmp          selectedWaveform3, #2                wz

03D8(00F0) A7 23 BF A0 |                   mov          arg1, phaseAccumulator3

03DC(00F1) 13 01 68 5C |   if_z            jmp          #Envelope3

03E0(00F2) 01 5A 7F 87 | Triangle3         cmp          selectedWaveform3, #1                wz, wc

03E4(00F3) FA 00 54 5C |   if_nz           jmp          #Square3

03E8(00F4) 01 22 FF 2D |                   shl          arg1, #1                             wc

03EC(00F5) 7E 23 B3 6C |   if_c            xor          arg1, mask32bit

03F0(00F6) 04 42 7F 62 |                   test         controlRegister3, #4                 wz '|

03F4(00F7) 85 4D 17 62 |   if_nz           test         phaseAccumulator2, val31bit          wz '| These 3 lines handles ring modulation

03F8(00F8) 7E 23 97 6C |   if_nz           xor          arg1, mask32bit                         '|

03FC(00F9) 13 01 7C 5C |                   jmp          #Envelope3

0400(00FA) 04 5A 7F 86 | Square3           cmp          selectedWaveform3, #4                wz

0404(00FB) A7 55 AB 85 |   if_z            sub          pulseWidth3, phaseAccumulator3   wc ' C holds the pulse width modulated square wave

0408(00FC) 7E 23 AB 70 |   if_z            muxc         arg1, mask32bit

040C(00FD) 13 01 68 5C |   if_z            jmp          #Envelope3

0410(00FE) 08 5A 7F 86 | Noise3            cmp          selectedWaveform3, #8                wz

0414(00FF) 08 01 54 5C |   if_nz           jmp          #Combined3

0418(0100) 80 23 BF 60 |                   and          arg1, mask28bit

041C(0101) A4 23 BF 85 |                   sub          arg1, frequency3                     wc

0420(0102) 98 23 BF 58 |                   movi         arg1, noiseValue3

0424(0103) 94 23 BF 80 |                   add          arg1, noiseAddValue

0428(0104) 13 01 4C 5C |   if_nc           jmp          #Envelope3

042C(0105) 95 31 3F 61 |                   test         noiseValue3, noiseTap                wc

0430(0106) 01 30 FF 30 |                   rcr          noiseValue3, #1

0434(0107) 13 01 7C 5C |                   jmp          #Envelope3

0438(0108) 08 5A 7F 62 | Combined3         test         selectedWaveform3, #8                wz

043C(0109) 04 5A FF 84 |                   sub          selectedWaveform3, #4

0440(010A) 00 5A FF 40 |                   mins         selectedWaveform3, #0

0444(010B) 08 5A FF 2C |                   shl          selectedWaveform3, #8

0448(010C) A7 95 BF A0 |                   mov          tempValue, phaseAccumulator3

044C(010D) 18 94 FF 28 |                   shr          tempValue, #24

0450(010E) CA 5B BF 80 |                   add          selectedWaveform3, tempValue

0454(010F) 90 5B BF 80 |                   add          selectedWaveform3, combTableAddr

0458(0110) AD 23 8B 00 |   if_nc_and_z rdbyte   arg1, selectedWaveform3

045C(0111) 18 22 CB 2C |   if_nc_and_z shl          arg1, #24

0460(0112) 85 23 B7 A0 |   if_c_or_nz  mov          arg1, val31bit

0464(0113) 8D 95 BF A0 | Envelope3         mov          tempValue, decayDivideRef

0468(0114) 9B 95 BF 28 |                   shr          tempValue, decayDivide3

046C(0115) CA 3D 3F 85 |                   cmp          envelopeLevel3, tempValue            wc

0470(0116) 1C 61 7F E8 |                   tjnz         envelopeState3, #Env_Dec3            nr

0474(0117) 01 36 CF E0 | Env_At3 if_nc cmpsub   decayDivide3, #1

0478(0118) B3 3D BF 81 |                   add          envelopeLevel3, attack3              wc

047C(0119) 7E 3D B3 A0 |   if_c            mov          envelopeLevel3, mask32bit

0480(011A) 01 60 F3 A0 |   if_c            mov          envelopeState3, #1

0484(011B) 26 01 7C 5C |                   jmp          #Amplitude3

0488(011C) 01 36 F3 80 | Env_Dec3 if_c add          decayDivide3, #1

048C(011D) 9E F9 3E 85 |                   cmp          startLogLevel, envelopeLevel3        wc

0490(011E) 01 60 7F 86 |                   cmp          envelopeState3, #1                   wz

0494(011F) 24 01 54 5C |   if_nz           jmp          #Rel3

0498(0120) 9B 6D 8F 28 |   if_nc           shr          decay3, decayDivide3

049C(0121) B6 3D BF 84 |                   sub          envelopeLevel3, decay3

04A0(0122) B9 3D BF 49 |                   min          envelopeLevel3, sustain3             wc

04A4(0123) 26 01 7C 5C |                   jmp          #Amplitude3

04A8(0124) 9B 79 8F 28 | Rel3 if_nc        shr          release3, decayDivide3

04AC(0125) BC 3D BF E0 |                   cmpsub   envelopeLevel3, release3

04B0(0126) 0E 22 FF 28 | Amplitude3        shr          arg1, #14

04B4(0127) 88 23 BF 84 |                   sub          arg1, val17bit

04B8(0128) 9E 25 BF A0 |                   mov          arg2, envelopeLevel3

04BC(0129) 18 24 FF 28 |                   shr          arg2, #24

04C0(012A) 66 D7 FE 5C |                   call         #multiply

04C4(012B) 93 7F BF A0 |                   mov          out3, r1

04C8(012C) 00 90 FF A0 | filter            mov          ordinaryOutput, #0                      '|

04CC(012D) 00 84 FF A0 |                   mov          highPassFilter, #0                      '|

04D0(012E) 01 8C 7F 61 |                   test         filterControl, #1                    wc '|

04D4(012F) BD 85 B3 80 |   if_c            add          highPassFilter, out1                    '|

04D8(0130) BD 91 8F 80 |   if_nc           add          ordinaryOutput, out1                    '|

04DC(0131) 02 8C 7F 61 |                   test         filterControl, #2                    wc '| Route channels trough the filter

04E0(0132) BE 85 B3 80 |   if_c            add          highPassFilter, out2                    '| or bypass them

04E4(0133) BE 91 8F 80 |   if_nc           add          ordinaryOutput, out2                    '|

04E8(0134) 04 8C 7F 61 |                   test         filterControl, #4                    wc '|

04EC(0135) BF 85 B3 80 |   if_c            add          highPassFilter, out3                    '|

04F0(0136) BF 91 8F 80 |   if_nc           add          ordinaryOutput, out3                    '|

04F4(0137) C0 25 BF A0 |                   mov          arg2, filterResonance                   '|

04F8(0138) 06 24 FF 80 |                   add          arg2, #RESONANCE_OFFSET                 '|

04FC(0139) C3 23 BF A0 |                   mov          arg1, bandPassFilter                    '|

0500(013A) 05 22 FF 38 |                   sar          arg1, #RESONANCE_FACTOR                 '|

0504(013B) 66 D7 FE 5C |                   call         #multiply                               '| High pass filter

0508(013C) C3 85 BF 84 |                   sub          highPassFilter, bandPassFilter          '|

050C(013D) 93 85 BF 80 |                   add          highPassFilter, r1                      '|

0510(013E) C4 85 BF 84 |                   sub          highPassFilter, lowPassFilter           '|

0514(013F) C2 23 BF A0 |                   mov          arg1, highPassFilter                    '|

0518(0140) 0A 22 FF 38 |                   sar          arg1, #BP_MAX_CUTOFF                    '|

051C(0141) C1 25 BF A0 |                   mov          arg2, filterCutoff                      '| Band pass filter

0520(0142) 8E 25 BF 4C |                   max          arg2, maxCutoff                         '|

0524(0143) 66 D7 FE 5C |                   call         #multiply                               '|

0528(0144) 93 87 BF 80 |                   add          bandPassFilter, r1                      '|

052C(0145) C3 23 BF A0 |                   mov          arg1, bandPassFilter                    '|

0530(0146) 0B 22 FF 38 |                   sar          arg1, #LP_MAX_CUTOFF                    '|

0534(0147) C1 25 BF A0 |                   mov          arg2, filterCutoff                      '| Low pass filter

0538(0148) 66 D7 FE 5C |                   call         #multiply                               '|

053C(0149) 93 89 BF 80 |                   add          lowPassFilter, r1                       '|

0540(014A) 00 8E FF A0 |                   mov          filterOutput, #0                        '|

0544(014B) 10 8A 7F 61 |                   test         filterMode_Volume, #16               wc '|

0548(014C) C4 8F B3 80 |   if_c            add          filterOutput, lowPassFilter             '|

054C(014D) 20 8A 7F 61 |                   test         filterMode_Volume, #32               wc '| Enable/Disable

0550(014E) C3 8F B3 80 |   if_c            add          filterOutput, bandPassFilter            '| Low/Band/High pass filtering

0554(014F) 40 8A 7F 61 |                   test         filterMode_Volume, #64               wc '|

0558(0150) C2 8F B3 80 |   if_c            add          filterOutput, highPassFilter            '|

055C(0151) C7 23 BF A0 | mixer             mov          arg1, filterOutput

0560(0152) C8 23 BF 80 |                   add          arg1, ordinaryOutput

0564(0153) 8A 23 BF 44 |                   maxs         arg1, clipLevelHigh                     '|

0568(0154) 8B 23 BF 40 |                   mins         arg1, clipLevelLow                      '|

056C(0155) C5 25 BF A0 |                   mov          arg2, filterMode_Volume                 '| Main volume adjustment

0570(0156) 0F 24 FF 60 |                   and          arg2, #15                               '|

0574(0157) 66 D7 FE 5C |                   call         #multiply                               '|

0578(0158) 85 27 BF 80 |                   add          r1, val31bit                            '  DC offset

057C(0159) 8F 93 BF F8 |                   waitcnt  waitCounter, sampleRate                 '  Wait until the right time to update

0580(015A) 93 F5 BF A0 |                   mov          FRQA, r1                                '| Update PWM values in FRQA/FRQB

0584(015B) 93 F7 BF A0 |                   mov          FRQB, r1                                '|

0588(015C) F0 95 BF A0 |                   mov          tempValue, par

058C(015D) 1C 94 FF 80 |                   add          tempValue, #28

0590(015E) CA 27 3F 08 |                   wrlong   r1, tempValue                           '| Write the sample to hub ram

0594(015F) 05 00 7C 5C |                   jmp          #getRegisters

0598(0160) 91 C9 BE 50 | getADSR           movs          :indexed1, arg1

059C(0161) F0 C9 FE 64 |                   andn          :indexed1, #$1F0

05A0(0162) 6C C9 FE 80 |                   add           :indexed1, #ADSRTable

05A4(0163) 04 22 FF 28 |                   shr           arg1, #4

05A8(0164) 00 26 BF A0 | :indexed1         mov           r1, 0

05AC(0165) 00 00 7C 5C | getADSR_ret   ret

05B0(0166) 00 26 FF A0 | multiply          mov           r1,   #0                'Clear 32-bit product

05B4(0167) 01 24 FF 2B | :multiLoop        shr           arg2, #1   wc, wz   'Half multiplyer and get LSB of it

05B8(0168) 91 27 B3 80 |   if_c            add           r1,   arg1              'Add multiplicand to product on C

05BC(0169) 01 22 FF 2C |                   shl           arg1, #1                'Double multiplicand

05C0(016A) 67 01 54 5C |   if_nz           jmp           #:multiLoop             'Check nonzero multiplier to continue multiplication

05C4(016B) 00 00 7C 5C | multiply_ret  ret

05C8(016C) 38 07 9C 03 | ADSRTable               long trunc(ENV_CAL_FACTOR * (1.0 / 9.0        )) '2   ms

05CC(016D) 08 E2 03 01 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 32.0   )) '8   ms

05D0(016E) 09 01 84 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 63.0   )) '16  ms

05D4(016F) 1E 8A 57 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 95.0   )) '24  ms

05D8(0170) 54 D0 37 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 149.0  )) '38  ms

05DC(0171) 18 CD 25 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 220.0  )) '56  ms

05E0(0172) A3 25 1F 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 267.0  )) '68  ms

05E4(0173) CA 91 1A 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 313.0  )) '80  ms

05E8(0174) 05 37 15 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 392.0  )) '100 ms

05EC(0175) 14 83 08 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 977.0  )) '250 ms

05F0(0176) 8A 41 04 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 1954.0 )) '500 ms

05F4(0177) 0C A9 02 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 3126.0 )) '800 ms

05F8(0178) E8 20 02 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 3907.0 )) '1   s

05FC(0179) A6 B5 00 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 11720.0)) '3   s

0600(017A) FF 6C 00 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 19532.0)) '5   s

0604(017B) 1F 44 00 00 |                         long trunc(ENV_CAL_FACTOR * (1.0 / 31251.0)) '8   s

0608(017C) 5D 5D 5D 5D | startLogLevel           long START_LOG_LEVEL

060C(017D) 00 00 00 0F | sustainAdd              long $0f000000

0610(017E) FF FF FF FF | mask32bit               long $ffffffff

0614(017F) FF FF FF 7F | mask31bit               long $7fffffff

0618(0180) FF FF FF 0F | mask28bit               long $fffffff

061C(0181) FF FF FF 00 | mask24bit               long $ffffff

0620(0182) FF FF 0F 00 | mask20bit               long $fffff

0624(0183) FF FF 00 00 | mask16bit               long $ffff

0628(0184) FF 07 00 00 | mask11bit               long $7ff

062C(0185) 00 00 00 80 | val31bit                long $80000000

0630(0186) 00 00 00 10 | val28bit                long $10000000

0634(0187) 00 00 00 08 | val27bit                long $8000000

0638(0188) 00 00 02 00 | val17bit                long $20000

063C(0189) 00 00 01 00 | val16bit                long $10000

0640(018A) 00 00 00 08 | clipLevelHigh           long $8000000

0644(018B) 00 00 00 F8 | clipLevelLow            long-$8000000

0648(018C) 0C 00 00 00 | filterOffset            long FILTER_OFFSET

064C(018D) 6C 6C 6C 6C | decayDivideRef          long DECAY_DIVIDE_REF

0650(018E) 4C 04 00 00 | maxCutoff               long CUTOFF_LIMIT

0654(018F) 00 00 00 00 | sampleRate              long 0                     'clocks between samples ( ~31.250 khz )

0658(0190) 00 00 00 00 | combTableAddr           long 0

065C(0191) 01 00 00 00 | arg1                    long 1

0660(0192) 01 00 00 00 | arg2                    long 1

0664(0193) 01 00 00 00 | r1                      long 1

0668(0194) 00 00 80 AA | noiseAddValue           long NOISE_ADD

066C(0195) 00 21 00 00 | noiseTap                long NOISE_TAP

0670(0196) FF FF FF 00 | noiseValue1             long $ffffff

0674(0197) FF FF FF 00 | noiseValue2             long $ffffff

0678(0198) FF FF FF 00 | noiseValue3             long $ffffff

067C(0199) 00 00 00 00 | decayDivide1            long 0

0680(019A) 00 00 00 00 | decayDivide2            long 0

0684(019B) 00 00 00 00 | decayDivide3            long 0

{

0688(019C)                 | envelopeLevel1          res  1

0688(019D)                 | envelopeLevel2          res  1

0688(019E)                 | envelopeLevel3          res  1

0688(019F)                 | controlRegister1        res  1

0688(01A0)                 | controlRegister2        res  1

0688(01A1)                 | controlRegister3        res  1

0688(01A2)                 | frequency1              res  1

0688(01A3)                 | frequency2              res  1

0688(01A4)                 | frequency3              res  1

0688(01A5)                 | phaseAccumulator1   res  1

0688(01A6)                 | phaseAccumulator2   res  1

0688(01A7)                 | phaseAccumulator3   res  1

0688(01A8)                 | pulseWidth1             res  1

0688(01A9)                 | pulseWidth2             res  1

0688(01AA)                 | pulseWidth3             res  1

0688(01AB)                 | selectedWaveform1   res  1

0688(01AC)                 | selectedWaveform2   res  1

0688(01AD)                 | selectedWaveform3   res  1

0688(01AE)                 | envelopeState1          res  1

0688(01AF)                 | envelopeState2          res  1

0688(01B0)                 | envelopeState3          res  1

0688(01B1)                 | attack1                 res  1

0688(01B2)                 | attack2                 res  1

0688(01B3)                 | attack3                 res  1

0688(01B4)                 | decay1                  res  1

0688(01B5)                 | decay2                  res  1

0688(01B6)                 | decay3                  res  1

0688(01B7)                 | sustain1                res  1

0688(01B8)                 | sustain2                res  1

0688(01B9)                 | sustain3                res  1

0688(01BA)                 | release1                res  1

0688(01BB)                 | release2                res  1

0688(01BC)                 | release3                res  1

0688(01BD)                 | out1                    res  1

0688(01BE)                 | out2                    res  1

0688(01BF)                 | out3                    res  1

0688(01C0)                 | filterResonance         res  1

0688(01C1)                 | filterCutoff            res  1

0688(01C2)                 | highPassFilter          res  1

0688(01C3)                 | bandPassFilter          res  1

0688(01C4)                 | lowPassFilter           res  1

0688(01C5)                 | filterMode_Volume   res  1

0688(01C6)                 | filterControl           res  1

0688(01C7)                 | filterOutput            res  1

0688(01C8)                 | ordinaryOutput          res  1

0688(01C9)                 | waitCounter             res  1

0688(01CA)                 | tempValue               res  1

}

unum ~                \ restore number exception processing        

}

]~

END