procedure DDSmono;
begin
  asm;
   ; DDS, aus Zeitgründen etwas geschachtelt
    LDI  _ACCBHI, SinusGen.SinusWaveHi SHRB 8  ; oberes Byte Adresse High-Tabelle
    LDI  _ACCBLO, SinusGen.SinusWaveLow SHRB 8 ; oberes Byte Adresse Low-Tabelle
    ldi  _ACCA, $00
    mov  _ACCCLO, _ACCA ;Z-Pointer nullen
    mov  _ACCEHI, _ACCA ;Phasen-Akkumulator und Pointer 1. Kanal
    mov  _ACCELO, _ACCA ;Phasen-Akkumulator
    mov  _ACCFHI, _ACCA ;Phasen-Akkumulator und Pointer 2. Kanal
    mov  _ACCFLO, _ACCA ;Phasen-Akkumulator
    mov  _ACCDHI, _ACCA ; 1. Datenbyte
    mov  _ACCDLO, _ACCA ; 1. Datenbyte

    ldi  _ACCA, 01000010b;  // CTC, Toggle OC1 on Timer1
    out  TCCR0A, _ACCA;     // CTC, Toggle OC1 on Timer1
  DDSinitLoopMono:
    sbis TIFR0,1
    rjmp  DDSinitLoopMono ; auf Timer OCF0A warten
    sbi TIFR0,1           ; ... Timer OCF0A Flag löschen

  SinusGen.DDSmonoLoop1:
    sbis TIFR0,1
    rjmp  SinusGen.DDSmonoLoop1 ; auf Timer OCF0A warten
    sbi TIFR0,1          ; ... Timer OCF0A Flag löschen

    sbi PortB,5          ; I2S-Vorimpuls an
    ldi _ACCA, 01010000b ; SPI Einschaltwert laden
    cbi PortB,5          ; I2S-Vorimpuls aus
    out SPCR, _ACCA      ; SPI einschalten

    out SPDR, _ACCDHI    ; vorbereitetes MSB ausgeben
    ; nächstes MSB berechnen
    add  _ACCELO, SinusGen.DDSL2 ; add value to DDS1 accumulator
    adc  _ACCEHI, SinusGen.DDSH2 ; variable Werte vom linken Kanal
    cpi  _ACCEHI, 192            ; Überlauf nach 192 Stützwerten
    brlo DDSmonoNoSub
    subi  _ACCEHI, 192
  DDSmonoNoSub:
    LDI  _ACCCHI, SinusGen.SinusWaveHi SHRB 8  ; oberes Byte Z-Register auf High-Tabelle
    mov  _ACCCLO,_ACCEHI  ; Z=Index für Sinus-Tabelle
    LPM  _ACCDHI, Z       ; ... LSB in Data-Reg LO
  SPIwait1:
    in _ACCA, SPSR
    sbrs _ACCA,7 ; SPIF?
    rjmp SPIwait1;
    nop                   ; wg. Clock-Versatz ein NOP einfügen
    out SPDR, _ACCDLO
    ; nächstes LSB berechnen
    LDI  _ACCCHI, SinusGen.SinusWaveLow SHRB 8  ; oberes Byte Z-Register auf Low-Tabelle
    mov  _ACCCLO,_ACCEHI  ; Z=Index für Sinus-Tabelle
    LPM  _ACCDLO, Z       ; ... LSB in Data-Reg LO
  SPIwait2:
    in _ACCA, SPSR
    sbrs _ACCA,7 ; SPIF?
    rjmp SPIwait2;

    ldi _ACCA, 0
    out SPCR, _ACCA ; SPI ausschalten
  ; 2. Kanal: letzte Werte einfach nochmal ausgeben
  SinusGen.DDSmonoLoop2:
    sbis TIFR0,1
    rjmp  SinusGen.DDSmonoLoop2 ; auf Timer OCF0A warten
    sbi TIFR0,1          ; ... Timer OCF0A Flag löschen

    sbi PortB,5          ; I2S-Vorimpuls an
    ldi _ACCA, 01010000b ; SPI Einschaltwert laden
    cbi PortB,5          ; I2S-Vorimpuls aus
    out SPCR, _ACCA      ; SPI einschalten

    out SPDR, _ACCDHI    ; altes MSB ausgeben
    ; nächstes MSB berechnen
  SPImonoWait1:
    in _ACCA, SPSR
    sbrs _ACCA,7 ; SPIF?
    rjmp SPImonoWait1;
    nop                  ; wg.  Clock-Versatz ein NOP einfügen
    out SPDR, _ACCDLO
  SPImonoWait2:
    in _ACCA, SPSR       ; altes LSB ausgeben
    sbrs _ACCA,7 ; SPIF?
    rjmp SPImonoWait2;

    ldi _ACCA, 0
    out SPCR, _ACCA ; SPI ausschalten

    LDS _ACCA, UCSRA
    sbrs _ACCA,7
    rjmp  SinusGen.DDSmonoLoop1; auf Receive warten
  endasm;
end;

