;
; Audio.a
;
; Scritto da Antonello Biancalana, ProMIND per Amiga Magazine
;

        include "exec/memory.i"
        include "hardware/custom.i"
        include "hardware/adkbits.i"
        include "hardware/cia.i"
        include "hardware/dmabits.i"
        include "hardware/intbits.i"

WFLEN   equ     256                     ; lunghezza della forma d'onda
WFWRD   equ     WFLEN/2                 ; Lunghezza onda in word

; indirizzo di CIA A e dei processori

        XREF    _ciaa
        XREF    _custom

; funzioni exec.library

        XREF    _AbsExecBase
        XREF    _LVOAllocMem
        XREF    _LVOFreeMem

        section code

        move.l  _AbsExecBase,a6         ; base di exec.library

        move.l  #WFLEN,d0               ; lunghezza forma d'onda
        move.l  #MEMF_CHIP,d1           ; CHIP MEMORY !!
        jsr     _LVOAllocMem(a6)        ; Richiesta di allocazione

        tst.l   d0                      ; Memoria disponibile ?
        beq     ExNoMem                 ; no, uscita programma

        move.l  d0,d6                   ; Salvataggio indirizzo memoria

;
; Generazione di una semplice onda quadra
;

        move.l  d6,a0                   ; Indirizzo memoria
        move.l  #127,d0                 ; contatore

FstCyc:
        move.b  #127,(a0)+              ; Generazione primo ciclo
        dbra    d0,FstCyc               ; Generazione di 128 campioni

        move.l  #127,d0                 ; contatore
SecCyc:
        move.b  #-127,(a0)+             ; Generazione secondo ciclo
        dbra    d0,SecCyc               ; Generazione di 128 campioni

; Riproduzione dell'onda mediante il canale zero

        lea     _custom,a0              ; indirizzo di custom

        move.l  d6,AUD0LC(a0)           ; Indirizzo della forma d'onda
        move.w  #WFWRD,AUD0LEN(a0)      ; Lunghezza (Numero di word)
        move.w  #150,AUD0PER(a0)        ; Periodo di riproduzione
        move.w  #64,AUD0VOL(a0)         ; Volume di riproduzione

; Abilitazione DMA per il canale zero
; Silenzio, SI SUONA !

        move.w  #(DMAF_SETCLR!DMAF_AUD0!DMAF_MASTER),DMACON(a0)

        move.l  #200,d0                 ; Numero di ripetizione onda

WaitCyc:
        andi.w  #INTF_AUD0,INTREQR(a0)  ; forma d'onda conclusa ?
        beq     WaitCyc                 ; No, controlla di nuovo

; A questo punto abbiamo rilevato la condizione di interrupt
; dovremo quindi cancellare la richiesta e fermare la riproduzione

        move.w  #INTF_AUD0,INTREQ(a0)   ; Cancellazione richiesta interrupt

        dbra    d0,WaitCyc              ; ripeti per 200 volte

        move.w  #DMAF_AUD0,DMACON(a0)   ; Termine riproduzione
        
exit:
        move.l  d6,a1               ; Indirizzo forma d'onda
        move.l  #WFLEN,d0               ; lunghezza
        jsr     _LVOFreeMem(a6)         ; Deallocazione memoria

ExNoMem:
        rts                             ; Uscita

        end
