// ChatAudioInit.bcpl
// Copyright Xerox Corporation 1979, 1980

//	Last modified March 19, 1980  4:38 PM by Taft

get "ChatAudio.d"
get "AltoDefs.d"

external
[
// outgoing procedures
InitAudio

// incoming procedures
SwatContextProc; AudioFinish; EnqueueAudioOut
Allocate; FindInterruptMask; IntervalTimerInterrupt; Noop

// incoming statics
audioSavedSCP; audioSavedUFP
@acb; interruptsActive; lvSwatContextProc; lvUserFinishProc
AltoVersion
]


// ---------------------------------------------------------------------------
let InitAudio(zone, nItems) be
// ---------------------------------------------------------------------------
[
// If this is not really an Alto, or is an Alto-II with microcode version 2
// (which has bugs in the interval timer code), disable the audio.
AltoVersion = (table [ #61014; #1401 ])()
if AltoVersion<<VERS.eng gr 3 %
 AltoVersion<<VERS.eng gr 1 & AltoVersion<<VERS.microcode ls 3 then
   [ EnqueueAudioOut = Noop; return ]

let buf = Allocate(zone, 2*nItems)
acb>>ACB.base = buf
acb>>ACB.read = buf
acb>>ACB.write = buf
acb>>ACB.end = buf + 2*nItems
acb>>ACB.duration = 0
acb>>ACB.data = 0
// timer interval is positioned differently on Alto-I and Alto-II
acb>>ACB.sitShiftCount = AltoVersion<<VERS.eng gr 1? 2, 6
acb>>ACB.timeMask = #1777 lshift acb>>ACB.sitShiftCount

let mask = FindInterruptMask(1)
let tMask = mask
let pIntVec = interruptVector
while (tMask&1) eq 0 do [ pIntVec = pIntVec+1; tMask = tMask rshift 1 ]
@pIntVec = IntervalTimerInterrupt
@activeInterrupts = @activeInterrupts % mask
@itInterruptMask = mask
// make interrupt package turn off this channel when we finish
interruptsActive = interruptsActive % mask

@itTime = 0
audioSavedSCP = @lvSwatContextProc
@lvSwatContextProc = SwatContextProc
audioSavedUFP = @lvUserFinishProc
@lvUserFinishProc = AudioFinish
]