-- WaferProberImpl.mesa -- Access to Wafer Prober DIRECTORY Inline USING [LowHalf], IODefs: FROM "IODefs" USING [ WriteChar, ReadChar, CR, LF, ControlE, ControlS, ControlQ, ControlR, ControlT, ControlU, WriteString, WriteDecimal], PupStream: FROM "PupStream" USING [ GetPupAddress, PupAddress, PupPackageDestroy, PupPackageMake, SecondsToTocks, PupByteStreamCreate], Storage USING [Words, FreeWords, String], Stream: FROM "Stream" USING [ Handle, Delete, SetInputOptions, SendNow, Block, GetBlock, PutBlock, InputOptions, CompletionCode, GetChar, PutChar, TimeOut], String USING [ AppendChar, AppendSubString, AppendString, DeleteSubString, SubString, EqualSubString, SubStringDescriptor, EquivalentString, WordsForString], WaferProber; WaferProberImpl: PROGRAM IMPORTS Inline, IODefs, PupStream, Storage, Stream, String EXPORTS WaferProber = BEGIN OPEN IODefs, PupStream, Stream, String; WaferProberObject: PUBLIC TYPE = RECORD[streamHandle: Stream.Handle, pupAddress: PupAddress, inBlock, outBlock: Block, buffer: STRING ← NIL]; Handle: TYPE = LONG POINTER TO WaferProberObject; MyOptions: InputOptions = [terminateOnEndPhysicalRecord: TRUE, signalLongBlock: FALSE, signalShortBlock: TRUE, signalSSTChange: FALSE, signalEndOfStream: FALSE]; -- -- Open: PUBLIC PROCEDURE [name: STRING] RETURNS [h: Handle ← NIL] = BEGIN h ← Storage.Words[SIZE[WaferProberObject]]; h.buffer ← Storage.Words[WordsForString[256]]; h.buffer↑ ← [length: 0, maxlength: 256, text:]; h.inBlock.blockPointer ← @h.buffer.text; h.inBlock.startIndex ← 0; h.inBlock.stopIndexPlusOne ← h.buffer.maxlength; h.outBlock.startIndex ← 0; PupPackageMake; GetPupAddress[Inline.LowHalf[@h.pupAddress], name]; h.streamHandle ← PupByteStreamCreate[h.pupAddress, SecondsToTocks[60]]; SetInputOptions[h.streamHandle, MyOptions]; RETURN[h] END; -- Open Close: PUBLIC PROCEDURE [ph: LONG POINTER TO Handle] = BEGIN h: Handle = ph↑; Stream.Delete[h.streamHandle]; PupPackageDestroy; ph↑ ← NIL; Storage.FreeWords[h.buffer]; Storage.FreeWords[Inline.LowHalf[h]]; END; -- Close Align: PUBLIC PROCEDURE [h: Handle] = BEGIN [] ← TalkToWaferProber[h, "AL*"]; END; -- Align GetDeviceCoordinate: PUBLIC PROCEDURE [h: Handle] RETURNS [x, y: STRING ← NIL] = BEGIN response: STRING = TalkToWaferProber[h, "?DC*", FALSE]; ssd: SubStringDescriptor; ss: SubString = @ssd; IF response[0] = 'D AND response[1] = 'C THEN { indexSep: CARDINAL ← 0; indexLast: CARDINAL ← 0; FOR i: CARDINAL IN [0..response.length) DO IF response[i] = '- THEN indexSep ← i; IF response[i] = '* THEN indexLast ← i; ENDLOOP; x ← Storage.String[indexSep-2]; ssd ← [base: response, offset: 2, length: x.maxlength]; AppendSubString[x, ss]; y ← Storage.String[indexLast-(indexSep+1)]; ssd ← [base: response, offset: (indexSep+1), length: y.maxlength]; AppendSubString[y, ss]; } ELSE {ERROR}; RETURN[x, y] END; -- GetDeviceCoordinate GoHide: PUBLIC PROCEDURE [h: Handle] = BEGIN [] ← TalkToWaferProber[h, "HI*"]; END; -- GoHide GoHome: PUBLIC PROCEDURE [h: Handle] = BEGIN [] ← TalkToWaferProber[h, "HO*"]; END; -- GoHome InitializeZ: PUBLIC PROCEDURE [h: Handle] = BEGIN [] ← TalkToWaferProber[h, "ZI*"]; END; -- InitializeZ Load: PUBLIC PROCEDURE [h: Handle] = BEGIN [] ← TalkToWaferProber[h, "LD*"]; END; -- Load SetDieSize: PUBLIC PROCEDURE [h: Handle, x, y: STRING] = BEGIN command: STRING = [128]; command.length ← 0; AppendString[command, "DS"L]; AppendString[command, x]; AppendString[command, "-"L]; AppendString[command, y]; AppendString[command, "*"L]; [] ← TalkToWaferProber[h, command]; END; -- SetDieSize Seek: PUBLIC PROCEDURE [h: Handle, x, y: STRING] = BEGIN command: STRING = [128]; command.length ← 0; AppendString[command, "SK"L]; AppendString[command, x]; AppendString[command, "-"L]; AppendString[command, y]; AppendString[command, "*"L]; [] ← TalkToWaferProber[h, command]; END; -- Seek SetDeviceCoordinate: PUBLIC PROCEDURE [h: Handle, x, y: STRING] = BEGIN command: STRING = [128]; command.length ← 0; AppendString[command, "DC"L]; AppendString[command, x]; AppendString[command, "-"L]; AppendString[command, y]; AppendString[command, "*"L]; [] ← TalkToWaferProber[h, command]; END; -- SetDeviceCoordinate ToggleZ: PUBLIC PROCEDURE [h: Handle] = BEGIN [] ← TalkToWaferProber[h, "ZM*"]; END; -- ToggleZ -- -- -- TalkToWaferProber: PROCEDURE [h: Handle, DummyPointer: STRING, actionCompleteExpected: BOOLEAN ← TRUE] RETURNS [NewPointer: STRING] = BEGIN Why: CompletionCode; h.outBlock.blockPointer ← @DummyPointer.text; h.outBlock.stopIndexPlusOne ← DummyPointer.length; PutBlock[h.streamHandle, h.outBlock, FALSE]; SendNow[h.streamHandle]; [h.buffer.length, Why] ← GetBlock[h.streamHandle, h.inBlock! TimeOut => BEGIN WriteChar[CR]; WriteString["No response from LoGlas, it may be busy"]; WriteChar[CR]; WriteString["Try Again,Debugger,Quit?"]; SELECT ReadChar[] FROM 'T, 't => RETRY; 'C, 'c => CONTINUE; 'D, 'd => ERROR TimeOut[nextIndex]; 'Q, 'q => BEGIN WriteString["Will now close data base"]; WriteChar[CR]; --NoMoreWafers ← TRUE; GOTO End; END; ENDCASE => ERROR; END; ]; SELECT Why FROM = normal => NULL;--WriteString["CompletionCode is Normal "]; = endRecord => NULL;--WriteString["CompletionCode is endRecord "]; = sstChange => WriteString["CompletionCode is sstChange "]; = endOfStream => WriteString["CompletionCode is endOfStream "]; ENDCASE => WriteString["CompletionCode Error "]; --WriteChar[CR]; SELECT h.buffer[h.buffer.length - 2] FROM = ControlS => NULL; = ControlQ => BEGIN WriteString["On-Line mode Selected---"]; WriteString["Strike a key to continue"]; [] ← ReadChar[]; END; = ControlR => BEGIN WriteString["Off-Line mode Selected---"]; WriteString["Strike a key to continue"]; [] ← ReadChar[]; END; = ControlT => BEGIN WriteString["Repeat Transmission---"]; WriteString["Strike a key to continue"]; [] ← ReadChar[]; END; = ControlU => BEGIN WriteString["Data Not Acknowledged---"]; WriteString["Strike a key to continue"]; [] ← ReadChar[]; END; ENDCASE; -- => WriteString["You must not have found the correct character"]; -- WriteChar[CR]; -- WriteString["Prober responds with "]; -- WriteString[h.buffer]; -- WriteChar[CR]; NewPointer ← h.buffer; EXITS End => NULL; END; -- TalkToWaferProber CutOffRecord: SubStringDescriptor; CutOff: SubString = @CutOffRecord; PromptString: STRING = "COMMAND:"; PromptRecord: SubStringDescriptor ← [PromptString, 0, 8]; Prompt: SubString = @PromptRecord; BREAKString: STRING = "*BREAK"; BREAKRecord: SubStringDescriptor ← [BREAKString, 0, 6]; BREAK: SubString = @BREAKRecord; LineRecord: SubStringDescriptor; LinePointer: SubString = @LineRecord; CRLF: STRING ← [2]; ContE: STRING ← [1]; -- Mainline Statements Follow, Initialization only AppendChar[CRLF, CR]; AppendChar[CRLF, LF]; AppendChar[ContE, ControlE]; END.-- WaferProberImpl