/****************************************************************************************
*****************************************************************************************
Technická univerzita v Kosiciach
Fakulta elektrotechniky a informatiky
Katedra elektroniky a multimedialnych telekomunikacii

Tema diplomovej prace:    Implementacia zakladnych algoritmov cislicoveho spracovania
                          signalov pomocou procesorov Analog Devices ADSP218x a ADSP219x

Veduci diplomovej prace:  doc. Ing. Milos Drutarovsky, CSc.

*****************************************************************************************
Nazov suboru:             iir_EZ_KIT_interrupt.asm

Datum modifikacie:        29-04-2002

Autor:                    Peter Popadic

Verzia:                   1.00 pre ADSP2191, VisualDSP++ verzie 3


Opis:
Subor obsahuje obsluhu prerusenia od serioveho portu. V obsluhe sa prijmu vstupne data
a ulozia sa do buffra Left_Channel a Right_Channel. Nasleduje kontrola volnych buffrov
a hodnoty z Left_Channel sa zapisujy do volneho buffra. Ak sa naplni volny buffer, prepne
sa na druhy buffer a zmeni sa hodnota 'rx'.
Nasleduje zapisanie vyfiltrovanych vzoriek do Left_Channel, Right_Channel zostava nezmeneni.
Nasledne sa obe kanaly vyslu
****************************************************************************************/

#include <def2191.h>
#include "..\..\include\2191_EZ_KIT_constant.h"
#include "iir_EZ_KIT_constant.h"

.GLOBAL Process_AD1885_Audio_Samples;
.EXTERN _tx_buf;
.EXTERN _rx_buf;
.extern _input_buf;
.extern _output_buf;
.extern Left_Channel;
.extern Right_Channel;
.extern _Coef;
.extern _Delay_Line;
.extern _rx;
.extern _RBuf;
.extern _TBuf;

.section/pm program;
Process_AD1885_Audio_Samples:
    ax0 = 0x8000;                            // vycistenie vystupneho ramca a nastavenie
    dm(_tx_buf + TAG_PHASE) = ax0;           // bitu 'Valid Frame' v Tag phase SLOT '0'
    ax0 = 0;
    dm(_tx_buf + COMMAND_ADDRESS_SLOT) = ax0;
    dm(_tx_buf + COMMAND_DATA_SLOT) = ax0;
    dm(_tx_buf + LEFT) = ax0;
    dm(_tx_buf + RIGHT) = ax0;

Check_ADCs_For_Valid_Data:
    ax0 = dm(_rx_buf + TAG_PHASE);           // zistovanie platnych bitov z Tag phase
    ax1 = 0x1800;                            // maskovanie ostatnych bitov
    ar = ax0 and ax1;

Set_TX_Slot_Valid_Bits:
    ay1 = dm(_tx_buf + TAG_PHASE);
    ar = ar or ay1;                         // nastavenie platnych bitov pre TX
    dm(_tx_buf + TAG_PHASE) = ar;

Check_AD1885_ADC_Left:
    AR = TSTBIT M_Left_ADC of ax0;          // zachytenie platneho bitu pre lavy kanal
    IF EQ JUMP Check_AD1885_ADC_Right;
    ax1 = dm(_rx_buf + LEFT);                // ulozenie vzorky
    dm(Left_Channel) = ax1;

Check_AD1885_ADC_Right:
    AR = TSTBIT M_Right_ADC of ax0;         // zachytenie platneho bitu pre pravy kanal
    IF EQ JUMP Valid_Frame;
    ax1 = dm(_rx_buf + RIGHT);
    dm(Right_Channel) = ax1;                // ulozenie vzorky

user_dsp_applic:
    ena SD;                                 // povolenie sekundarnych DAG registrov

    ax0=Dlzka_Bloku;
    ay0=M1;
    ar=ax0-ay0;
    if ne jump set_ok;                      // kontrola ci uz mame naplneny cely blok
       M1=0;                                // ak ano zmenime buffre
       AX0=1;
       DM(_rx)=AX0;

       AX0=_input_buf;       // do AX0 vlozime adresu na vstupny buffer input_buf
       AY0=DM(_RBuf);        // do AY0 vlozime adresu na prave pouzivany vstupny buffer
       AR=AX0-AY0;                     // zistovanie toho ktory buffer sa prave pouziva
       if eq jump skok;
       AX0=_input_buf;
       DM(_RBuf)=AX0;                  // nastavenie smernika na aktualny buffer
       AX0=_output_buf;
       DM(_TBuf)=AX0;                  // nastavenie smernika na novy vystupny buffer
       jump set_ok;                    // ukoncenie obsluhy prerusenia
    skok: AX0=_input_buf + Dlzka_Bloku;
       DM(_RBuf)=AX0;                  // zmena smernika na vstupny buffer
       AX0=_output_buf + Dlzka_Bloku;
       DM(_TBuf)=AX0;                  // nastavenie smernika na novy vystupny buffer
    set_ok:

    ax0=dm(Left_Channel);
    dm(I2,1)=ax0;

    ax0=dm(I3,1);
    dm(Left_Channel)=ax0;

    ar=M1;
    ar=ar+1;
    M1=ar;

    dis SD;                                 // zakazanie sekundarnych DAG registrov

Playback_Audio_Data:
    ar = dm(Left_Channel);
    dm(_tx_buf + LEFT) = ar;                 // zapis filtrovanej vzorky do Slotu 3
    ar = dm(Right_Channel);
    dm(_tx_buf + RIGHT) = ar;                // zapis nezmenenej vzorky do Slotu 4

Valid_Frame:
    ar=3;                                   // vicistenie preruseni
    io(SP0DR_IRQ)=ar;
    IOPG = ay1;
    DIS SR;                                 // zakazanie sekundarnych registrov
    RTI;