-- D0CatTest.mesa
-- D0 printer port CAT test
-- Last Modified LStewart January 29, 1981 12:00 PM
DIRECTORY
ImageDefs USING [BcdTime],
Inline USING [COPY],
IODefs USING [ReadChar, ReadID, Rubout],
MiscDefs USING [Zero],
Mopcodes USING [zJRAM, zLIW],
ProcessDefs USING [Yield],
StringDefs USING [InvalidNumber, LowerCase, StringToNumber],
SystemDefs USING [AllocateResidentSegment, FreeSegment, Quad],
TimeDefs USING [PackedTime],
WF USING [WF0, WF1, WFCR];
D0CatTest: PROGRAM
IMPORTS ImageDefs, Inline, IODefs, MiscDefs, ProcessDefs, StringDefs, SystemDefs, WF =
BEGIN
-- Data buffer
BufSize: CARDINAL = 16384; -- for each input and output (samples)
BufWords: CARDINAL = BufSize/2;
Buffer: TYPE = RECORD[
outputStartOffset: CARDINAL,
outputEndOffset: CARDINAL,
outputCurrentOffset: CARDINAL,
inputDisplacement: CARDINAL,
buffers: ARRAY [0..0) OF UNSPECIFIED
];
buffer: POINTER TO Buffer;
lbuffer: LONG POINTER TO Buffer;
audioOn, echoOn, quitFlag: BOOLEAN ← FALSE;
memory: POINTER;
request: CARDINAL;
echoer: PROCESS;
Main: PROCEDURE = {
c: CHARACTER;
bcdTime: TimeDefs.PackedTime ← ImageDefs.BcdTime[];
WF.WF1["Dolphin Printer Port Audio Terminal Test of %lt*n", @bcdTime];
DO ENABLE {
StringDefs.InvalidNumber, IODefs.Rubout => LOOP;
};
WF.WF0["%% "];
c ← StringDefs.LowerCase[IODefs.ReadChar[]];
SELECT c FROM
’a => {
arg: LONG UNSPECIFIED;
WF.WF0["Audio is now "];
audioOn ← NOT audioOn;
arg ← IF audioOn THEN lbuffer ELSE 1;
AudioControl[arg];
WF.WF0[IF audioOn THEN "ON*n" ELSE "OFF*n"];
};
’b => {
s: STRING ← [40];
arg: CARDINAL;
WF.WF1["Buffer length (max %u words): ", BufWords];
IODefs.ReadID[s];
arg ← StringDefs.StringToNumber[s, 10];
arg ← MAX[BufWords, arg];
buffer.outputEndOffset ← arg-1;
WF.WF1[" [used %u]*n",arg];
};
’e => {
WF.WF0["Echo is now "];
echoOn ← NOT echoOn;
WF.WF0[IF echoOn THEN "ON*n" ELSE "OFF*n"];
};
’o => {
s: STRING ← [40];
arg: CARDINAL;
WF.WF1["Offset of input buffer (max %u): ", BufWords];
IODefs.ReadID[s];
arg ← StringDefs.StringToNumber[s, 10];
arg ← MAX[BufWords, arg];
buffer.inputDisplacement ← arg;
WF.WF1[" [used %u]*n",arg];
};
’q => { WF.WF0["Quit!*n"]; EXIT; };
’z => {
WF.WF0["Zero output buffer*n"];
MiscDefs.Zero[@buffer.buffers[0], BufWords];
};
’? => {
WF.WF0["Audio on/off, "];
WF.WF0["Buffer length, "];
WF.WF0["Echo on/off, "];
WF.WF0["Offset (to input buffer), "];
WF.WF0["Quit, "];
WF.WF0["Zero output buffer, "];
WF.WF0["???, "];
WF.WFCR[];
};
ENDCASE => WF.WF0["???*n"];
ENDLOOP;
WF.WF0["Bye*n"];
};
EchoProcess: PROCEDURE = {
wLoc, rLoc, diff: CARDINAL ← 0;
DO
IF quitFlag THEN EXIT;
ProcessDefs.Yield[];
IF NOT echoOn THEN {rLoc ← buffer.outputCurrentOffset; LOOP; };
wLoc ← buffer.outputCurrentOffset;
diff ← wLoc-rLoc;
IF (BufWords+diff) MOD BufWords > 256 THEN {
IF buffer.outputCurrentOffset>rLoc THEN {
-- no wraparound
Inline.COPY[from: @buffer.buffers[rLoc+buffer.inputDisplacement], nwords: diff, to: @buffer.buffers[rLoc]];
rLoc ← wLoc;
}
ELSE { --wraparound
Inline.COPY[from: @buffer.buffers[rLoc+buffer.inputDisplacement], nwords: BufWords-rLoc, to: @buffer.buffers[rLoc]];
rLoc ← 0;
Inline.COPY[from: @buffer.buffers[buffer.inputDisplacement], nwords: wLoc, to: @buffer.buffers[0]];
rLoc ← wLoc;
};
};
ENDLOOP;
};
-- Calling AudioControl with a LONG POINTER to the (quad-aligned) Buffer will turn on the audio microcode. Calling AudioCOntrol with an odd value will turn it off again.
AudioGo: CARDINAL = 166600B;
oAudioControl: PROCEDURE [bp: LONG UNSPECIFIED] =
MACHINE CODE BEGIN
Mopcodes.zLIW, AudioGo/256, AudioGo MOD 256;
Mopcodes.zJRAM;
END;
AudioControl: PROCEDURE [bp: LONG UNSPECIFIED, xxx: CARDINAL ← AudioGo] =
MACHINE CODE BEGIN
Mopcodes.zJRAM;
END;
-- Mainline code
request ← SIZE[Buffer]+(BufWords*2)+4;
memory ← SystemDefs.AllocateResidentSegment[request];
buffer ← LOOPHOLE[SystemDefs.Quad[memory], POINTER];
lbuffer ← buffer;
buffer.outputStartOffset ← 4;
buffer.outputEndOffset ← 4+BufWords-1;
buffer.outputCurrentOffset ← 0;
buffer.inputDisplacement ← BufWords;
echoer ← FORK EchoProcess[];
Main[];
echoOn ← FALSE;
quitFlag ← TRUE;
JOIN echoer;
AudioControl[1]; -- Definitely turn off the audio stuff.
SystemDefs.FreeSegment[memory];
END.