DIRECTORY Ascii, Basics, GPIB, Process, RefText, Rope, XBus; GPIBImpl: CEDAR MONITOR IMPORTS Basics, Process, RefText, Rope, XBus EXPORTS GPIB = BEGIN OPEN Basics, Rope; controller: GPIB.DeviceAddr _ 0; statusWord: WORD _ 0000H; BusEND: WORD = LOOPHOLE[BITSHIFT[1, 13]]; SRQI: WORD = LOOPHOLE[BITSHIFT[1, 12]]; GPIBBaseAddr: LONG POINTER = LOOPHOLE[LONG[8000H]]; -- current setting for Multibus monitorStatusWord: BOOL _ TRUE; --for debugging swRegister: WORD _ statusWord; --for debugging maxBytes: CARDINAL = LAST[CARDINAL]/4; smallBuf: NAT = 16; bigBuf: NAT = GPIB.maxReadBuffer; InitializeController: PUBLIC PROC RETURNS [open: BOOL] = { [] _ Init[]; open _ TRUE; }; FinalizeController: PUBLIC PROC = { SetIdle[] }; SRQAsserted: PUBLIC PROC RETURNS [asserted: BOOL] = { asserted _ FALSE; IF swRegister # 0 THEN { swRegister _ 0H; asserted _ TRUE; }; }; Command: PUBLIC PROC [sendMsg: Rope.ROPE] = { sendBuffer: REF TEXT _ RefText.ObtainScratch[bigBuf]; sendBuffer _ RefText.AppendRope[sendBuffer, sendMsg]; [] _ Cmd[sendBuffer]; RefText.ReleaseScratch[sendBuffer]; }; DevicesClear: PUBLIC PROC = { [] _ LCmd[LIST[GPIB.devicesClear, GPIB.UnListen]]}; GoToLocal: PUBLIC PROC = { [] _ LCmd[LIST[GPIB.goToLocal, GPIB.UnListen]]}; GroupExecuteTrigger: PUBLIC PROC = { [] _ LCmd[LIST[GPIB.groupExecuteTrigger, GPIB.UnListen]]}; InterfaceClear: PUBLIC PROC = {[] _ Clear[]}; LocalLockout: PUBLIC PROC = { [] _ LCmd[LIST[GPIB.localLockout, GPIB.UnListen]]}; RemoteEnable: PUBLIC PROC = {[] _ SetRemote[TRUE]}; SelectedDeviceClear: PUBLIC PROC [device: GPIB.DeviceAddr]= { [] _ LCmd[LIST[GPIB.UnListen, GetLAD[device], GPIB.selectedDeviceClear, GPIB.UnListen]]}; SelectedGoToLocal: PUBLIC PROC [device: GPIB.DeviceAddr] = { [] _ LCmd[LIST[GPIB.UnListen, GetLAD[device], GPIB.goToLocal, GPIB.UnListen]]}; SelectedExecuteTrigger: PUBLIC PROC [device: GPIB.DeviceAddr] = { [] _ LCmd[LIST[GPIB.UnListen, GetLAD[device],GPIB.groupExecuteTrigger,GPIB.UnListen]]}; SelectedGroupEnableTrigger: PUBLIC PROC [device: GPIB.DeviceAddr] = {ERROR}; SelectedRemoteEnable: PUBLIC PROC [device: GPIB.DeviceAddr] = { [] _ SetRemote[TRUE]; [] _ LCmd[LIST[GPIB.UnListen, GetLAD[device], GetTAD[device], GPIB.UnListen]]; }; ParallelPollConfigure: PUBLIC PROC [device: GPIB.DeviceAddr] = { [] _ LCmd[LIST[GPIB.UnListen, GPIB.parallelPollConfigure, GPIB.parallelPollEnable, GPIB.UnListen]]; }; ParallelPollUnconfigure: PUBLIC PROC = { [] _ LCmd[LIST[GPIB.UnListen, GPIB.parallelPollConfigure, GPIB.parallelPollDisable, GPIB.UnListen]]; }; SelectedParallelPollConfigure: PUBLIC PROC [device: GPIB.DeviceAddr] = { [] _ LCmd[LIST[GPIB.UnListen, GetLAD[device], GPIB.parallelPollConfigure, GPIB.parallelPollEnable, GPIB.UnListen]]; }; SelectedParallelPollUnconfigure: PUBLIC PROC [device: GPIB.DeviceAddr] = { [] _ LCmd[LIST[GPIB.UnListen, GetLAD[device], GPIB.parallelPollConfigure, GPIB.parallelPollDisable, GPIB.UnListen]]; }; PollDevice: PUBLIC PROC [device: GPIB.DeviceAddr, labels: GPIB.SRQLabels] = {ERROR}; SelectedReadSerialPoll: PUBLIC PROC [device: GPIB.DeviceAddr] RETURNS [statusByte: CHAR] = { [] _ LCmd[LIST[GPIB.UnListen, GPIB.serialPollEnable, GetTAD[device], GetLAD[controller]]]; [statusByte, ] _ DataByteRead[]; [] _ LCmd[LIST[GPIB.serialPollDisable, GPIB.UnTalk]]; }; ReadStatusByte: PUBLIC PROC [device: GPIB.DeviceAddr] RETURNS [char: CHAR] = { [] _ LCmd[LIST[GPIB.UnListen, GetTAD[device], GetLAD[controller]]]; [char, ] _ DataByteRead[! ABORTED => CONTINUE]; [] _ LCmd[LIST[GPIB.UnTalk]]; }; ReadDevice: PUBLIC PROC [device: GPIB.DeviceAddr, terminator: GPIB.Terminator _ EOI] RETURNS [recvMsg: Rope.ROPE, end: BOOL] = { sendBuffer: REF TEXT _ RefText.ObtainScratch[smallBuf]; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnListen]; sendBuffer _ RefText.AppendChar[sendBuffer, GetTAD[device]]; sendBuffer _ RefText.AppendChar[sendBuffer, GetLAD[controller]]; [] _ Cmd[sendBuffer]; [recvMsg, , end] _ DataRead[terminator ! ABORTED => CONTINUE]; sendBuffer.length _ 0; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnTalk]; [] _ Cmd[sendBuffer]; RefText.ReleaseScratch[sendBuffer]; }; ReadOnInterrupt: PUBLIC PROC [device: GPIB.DeviceAddr, recvMsg: Rope.ROPE, labels: GPIB.SRQLabels] = {ERROR}; WriteDevice: PUBLIC PROC [device: GPIB.DeviceAddr, sendMsg: Rope.ROPE] = { sendBuffer: REF TEXT _ RefText.ObtainScratch[smallBuf]; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnListen]; sendBuffer _ RefText.AppendChar[sendBuffer, GetLAD[device]]; sendBuffer _ RefText.AppendChar[sendBuffer, GetTAD[controller]]; [] _ Cmd[sendBuffer]; [] _ DataWrite[sendMsg ! ABORTED => CONTINUE]; sendBuffer.length _ 0; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnListen]; [] _ Cmd[sendBuffer]; RefText.ReleaseScratch[sendBuffer]; }; dev: GPIB.DeviceAddr; buffer: Rope.ROPE _ NIL; bufferEmptyCV, bufferFullCV: CONDITION; bufferEmpty: BOOL _ TRUE; WriteDeviceBuffered: PUBLIC ENTRY PROC [device: GPIB.DeviceAddr, sendMsg: Rope.ROPE, hold: BOOL] = { ENABLE UNWIND => NULL; UNTIL bufferEmpty DO WAIT bufferEmptyCV; ENDLOOP; dev _ device; buffer _ sendMsg; bufferEmpty _ FALSE; BROADCAST bufferFullCV; IF hold THEN UNTIL bufferEmpty DO WAIT bufferEmptyCV; ENDLOOP; }; BufferToDevice: ENTRY PROC = { ENABLE UNWIND => NULL; open: REF TEXT _ NEW[TEXT[smallBuf]]; close: REF TEXT _ NEW[TEXT[smallBuf]]; close _ RefText.AppendChar[close, GPIB.UnListen]; DO WHILE bufferEmpty DO WAIT bufferFullCV; ENDLOOP; open.length _ 0; open _ RefText.AppendChar[open, GPIB.UnListen]; open _ RefText.AppendChar[open, GetLAD[dev]]; open _ RefText.AppendChar[open, GetTAD[controller]]; [] _ Cmd[open]; [] _ DataWrite[buffer ! ABORTED => CONTINUE]; [] _ Cmd[close]; bufferEmpty _ TRUE; BROADCAST bufferEmptyCV; ENDLOOP; }; WriteDeviceInitial: PUBLIC ENTRY PROC [device: GPIB.DeviceAddr, sendMsg: Rope.ROPE] = BEGIN ENABLE UNWIND => NULL; sendBuffer: REF TEXT _ RefText.ObtainScratch[bigBuf]; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnListen]; sendBuffer _ RefText.AppendChar[sendBuffer, GetLAD[device]]; sendBuffer _ RefText.AppendChar[sendBuffer, GetTAD[controller]]; [] _ Cmd[sendBuffer]; sendBuffer.length _ 0; [] _ DataWrite[sendMsg, TRUE, FALSE ! ABORTED => CONTINUE]; RefText.ReleaseScratch[sendBuffer]; END; WriteDeviceContinued: PUBLIC ENTRY PROC [device: GPIB.DeviceAddr, sendMsg: Rope.ROPE, last: BOOL] = BEGIN ENABLE UNWIND => NULL; sendBuffer: REF TEXT _ RefText.ObtainScratch[bigBuf]; [] _ DataWrite[sendMsg, FALSE, last ! ABORTED => CONTINUE]; RefText.ReleaseScratch[sendBuffer]; END; WriteDeviceBlock: PUBLIC ENTRY UNSAFE PROC [device: GPIB.DeviceAddr, lp: LONG POINTER, quadWordCnt: CARDINAL, last: BOOL] = TRUSTED BEGIN OPEN Basics; ENABLE UNWIND => NULL; dataWord: MACHINE DEPENDENT RECORD [a,b: CHAR] _ LOOPHOLE [lp^]; IF quadWordCnt < 1 THEN quadWordCnt _ 1; FOR i: CARDINAL IN [0 .. quadWordCnt-1) DO XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; ENDLOOP; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; lp _ lp + 1; dataWord _ LOOPHOLE [lp^]; XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.a, CARDINAL]]; IF last THEN WriteReg[auxmr, sendEOI]; -- EOI with last byte XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[dataWord.b, CARDINAL]]; END; WriteDMABlock: PUBLIC UNSAFE PROC [device: GPIB.DeviceAddr, multiBusAddress: LONG POINTER TO WORD, -- For Lupine -- byteCnt: CARDINAL, last: BOOL] = TRUSTED BEGIN i: INTEGER; bp: Basics.BytePair; md: MACHINE DEPENDENT RECORD [b1, b0, b3, b2: BYTE]; i _ 0 - LOOPHOLE[byteCnt, INTEGER]; byteCnt _ LOOPHOLE[i, CARDINAL]; bp _ LOOPHOLE[byteCnt]; WriteReg[bcr0, LOOPHOLE[bp.low]]; WriteReg[bcr1, LOOPHOLE[bp.high]]; md _ LOOPHOLE[multiBusAddress]; WriteReg[acr0, LOOPHOLE[md.b0]]; WriteReg[acr1, LOOPHOLE[md.b1]]; WriteReg[acr2, LOOPHOLE[md.b2]]; IF last THEN WriteReg[ccfr, sendEOI]; WriteReg[imr1, LOOPHOLE[0]]; WriteReg[cr1, LOOPHOLE[0Bh]]; -- ~MIE, *Burst, ~CBRE, SC, 22.4 to 25.6 timeout WriteReg[imr2, LOOPHOLE[20H]]; -- DMAO WriteReg[cr0, LOOPHOLE[(IF last THEN 052H ELSE 012H)]]; WriteReg[cr0, LOOPHOLE[(IF last THEN 053H ELSE 013H)]]; END; ReadDeviceInitial: PUBLIC ENTRY PROC [ device: GPIB.DeviceAddr] = BEGIN sendBuffer: REF TEXT _ RefText.ObtainScratch[smallBuf]; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnListen]; sendBuffer _ RefText.AppendChar[sendBuffer, GetTAD[device]]; sendBuffer _ RefText.AppendChar[sendBuffer, GetLAD[controller]]; [] _ Cmd[sendBuffer]; RefText.ReleaseScratch[sendBuffer]; WriteReg[auxmr, goToStandby]; -- if controller active state, go to standby [] _ ReadRegL[sr]; END; ReadDMABlock: PUBLIC UNSAFE PROC [device: GPIB.DeviceAddr, multiBusAddress: LONG POINTER TO WORD, -- For Lupine -- byteCnt: CARDINAL, last: BOOL _ FALSE] = TRUSTED BEGIN i: INTEGER; bp: Basics.BytePair; md: MACHINE DEPENDENT RECORD [b1, b0, b3, b2: BYTE]; i _ 0 - LOOPHOLE[byteCnt, INTEGER]; byteCnt _ LOOPHOLE[i, CARDINAL]; bp _ LOOPHOLE[byteCnt]; WriteReg[bcr0, LOOPHOLE[bp.low]]; WriteReg[bcr1, LOOPHOLE[bp.high]]; md _ LOOPHOLE[multiBusAddress]; WriteReg[acr0, LOOPHOLE[md.b0]]; WriteReg[acr1, LOOPHOLE[md.b1]]; WriteReg[acr2, LOOPHOLE[md.b2]]; IF last THEN WriteReg[ccfr, sendEOI]; WriteReg[imr1, LOOPHOLE[10H]]; -- Setup as listener WriteReg[cr1, LOOPHOLE[4Bh]]; -- ~MIE, Burst, ~CBRE, SC, 22.4 to 25.6 timeout WriteReg[imr2, LOOPHOLE[10H]]; -- DMAI WriteReg[cr0, LOOPHOLE[02H]]; -- DMA en WriteReg[cr0, LOOPHOLE[03H]]; -- GO END; ReadDMADone: PUBLIC PROC [device: GPIB.DeviceAddr] = BEGIN sendBuffer: REF TEXT _ RefText.ObtainScratch[smallBuf]; sendBuffer _ RefText.AppendChar[sendBuffer, GPIB.UnListen]; [] _ Cmd[sendBuffer]; RefText.ReleaseScratch[sendBuffer]; END; CheckDMADone: PUBLIC PROC RETURNS [BOOL] = BEGIN foo: CARDINAL _ ReadRegL[sr]; foo _ Basics.BITAND[foo, 80h]; Process.CheckForAbort[]; RETURN [foo # 0]; END; GetLAD: PRIVATE PROC [device: GPIB.DeviceAddr] RETURNS [CHAR] = { IF device > 30 THEN ERROR; RETURN [LOOPHOLE[device+32]]; -- ASCII Listen adr }; GetTAD: PRIVATE PROC [device: GPIB.DeviceAddr] RETURNS [CHAR] = { IF device > 30 THEN ERROR; RETURN [LOOPHOLE[device+64]]; -- ASCII Talk adr }; BufferSW: PRIVATE PROC = { IF statusWord # 0 THEN swRegister _ statusWord; }; powerOn: CHAR = 000C; -- AUX-PON chipReset: CHAR = 002C; -- AUXCR sendEOI: CHAR = 006C; -- AUXSEOI takeAsynchControl: CHAR = 021C; -- AUXTCA goToStandby: CHAR = 020C; -- AUXGTS executeParaPoll: CHAR = 035C; -- AUX-EPP setIFC: CHAR = 036C; -- AUXSIFC clearIFC: CHAR = 026C; -- AUXCIFC setREN: CHAR = 037C; -- AUX-SREN clearREN: CHAR = 027C; -- AUXCREN ICR: CARDINAL = 000040B; -- Internal Counter Register PPR: CARDINAL = 000140B; -- Parallel Poll Register AUXRA: CARDINAL = 000200B; -- Aux Register A AUXRB: CARDINAL = 000240B; -- Aux Register B AUXRE: CARDINAL = 000300B; -- Aux Register E WRegister: TYPE = { -- WriteOnly cdro, -- cdor imr1, -- imr1 imr2, -- imr2 spmr, -- spmr admr, -- admr auxmr, -- auxmr adr, -- adr eosr, -- eosr bcr0, -- bcr 0 bcr1, -- bcr hi cr0, -- cr0 ccfr, -- ccfr acr0, -- acr0 acr1, -- acr1 acr2, -- acr2 cr1 -- cr1 }; RRegister: TYPE = { -- ReadOnly dir, -- dir isr1, -- isr1 isr2, -- isr2 spsr, -- spsr adsr, -- adsr cptr, -- cptr adr0, -- adr0 adr1, -- adr1 bcr0, -- bcr lo bcr1, -- bcr hi sr, -- SR ccfr -- ccfr }; mask: RECORD [ DI: CARDINAL _ BITSHIFT[1, 0], -- Data In D0: CARDINAL _ BITSHIFT[1, 1], -- Data Out BusEND: CARDINAL _ BITSHIFT[1, 4], -- End CO: CARDINAL _ BITSHIFT[1, 3], -- Command Output SRQI: CARDINAL _ BITSHIFT[1, 6], -- Service Request Input DMAI: CARDINAL _ BITSHIFT[1, 4], -- DMA Input Enable DMAO: CARDINAL _ BITSHIFT[1, 5], -- DMA Output Enable ADMO: CARDINAL _ BITSHIFT[1, 0], -- Addr Mode bit 0 TRMO: CARDINAL _ BITSHIFT[1, 4], -- Transmit/Receive Mode bit 0 TRMI: CARDINAL _ BITSHIFT[1, 5], -- Transmit/Receive Mode bit 1 DL: CARDINAL _ BITSHIFT[1, 5], -- Disable Listener DT: CARDINAL _ BITSHIFT[1, 6], -- Disable Talker ARS: CARDINAL _ BITSHIFT[1, 7], -- Addr Reg Select PPU: CARDINAL _ BITSHIFT[1, 4] -- Para Poll Unconfigure ]; Init: PROC [] RETURNS [WORD] = { WriteReg[auxmr, chipReset]; -- NEC 7210 [] _ ReadReg[cptr]; -- clear registers by reading & trashing result [] _ ReadReg[isr1]; [] _ ReadReg[isr2]; WriteReg[imr1, 0C]; -- disable all interrupts WriteReg[imr2, 0C]; WriteReg[spmr, 0C]; WriteReg[adr, 0C]; -- set 796P TAD = 100B+100B (controller) WriteRegL[adr, BITOR[mask.ARS, BITOR[mask.DT, mask.DL]]]; WriteRegL[admr, BITOR[mask.TRMI, BITOR[mask.TRMO, mask.ADMO]]]; WriteReg[eosr, 0C]; WriteReg[auxmr, clearIFC]; -- and by default enable system controller WriteRegL[auxmr, BITOR[ICR, 5]]; -- set internal counter register N = 5 WriteRegL[auxmr, BITOR[PPR, mask.PPU]]; -- parallel poll unconfigure WriteRegL[auxmr, BITOR[AUXRA, 0]]; WriteRegL[auxmr, BITOR[AUXRB, 0]]; WriteRegL[auxmr, BITOR[AUXRE, 0]]; WriteReg[auxmr, powerOn]; -- put chip online IF monitorStatusWord THEN { statusWord _ IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0; BufferSW[]; }; RETURN[statusWord]; }; ResetDMA: PROC = BEGIN WriteReg[cr0, LOOPHOLE[0]]; END; SetIdle: PROC = { WriteReg[auxmr, chipReset]; [] _ ReadReg[cptr]; -- clear registers by reading & trashing result [] _ ReadReg[isr1]; [] _ ReadReg[isr2]; WriteReg[imr1, 0C]; -- disable all interrupts WriteReg[imr2, 0C]; WriteReg[spmr, 0C]; WriteReg[adr, 0C]; -- set 796P TAD = 100B+100B (controller) WriteRegL[adr, BITOR[mask.ARS, BITOR[mask.DT, mask.DL]]]; WriteRegL[admr, BITOR[mask.TRMI, BITOR[mask.TRMO, mask.ADMO]]]; WriteReg[eosr, 0C]; WriteReg[auxmr, clearIFC]; -- and by default enable system controller WriteRegL[auxmr, BITOR[ICR, 5]]; -- set internal counter register N = 5 WriteRegL[auxmr, BITOR[PPR, mask.PPU]]; -- parallel poll unconfigure WriteRegL[auxmr, BITOR[AUXRA, 0]]; WriteRegL[auxmr, BITOR[AUXRB, 0]]; WriteRegL[auxmr, BITOR[AUXRE, 0]]; }; LCmd: PROC [chars: LIST OF CHAR] RETURNS [w: WORD] = { sendBuffer: REF TEXT _ RefText.ObtainScratch[smallBuf]; FOR l: LIST OF CHAR _ chars, l.rest WHILE l#NIL DO sendBuffer _ RefText.AppendChar[sendBuffer, l.first]; ENDLOOP; w _ Cmd[sendBuffer]; RefText.ReleaseScratch[sendBuffer]; }; Cmd: PROC [sendBuffer: REF TEXT] RETURNS [WORD] = { s: CARDINAL _ 0; WriteReg[auxmr, takeAsynchControl]; -- if on standby, go to controller active state FOR i: NAT IN [0..sendBuffer.length) DO s _ BITAND[s, BITNOT[mask.CO]]; -- clear saved copy of Command Output WriteReg[cdro, sendBuffer.text[i]]; -- output command WHILE BITAND[(s _ BITOR[s, ReadRegL[isr2]]), mask.CO] = 0 DO Process.CheckForAbort[]; -- escape route ENDLOOP; ENDLOOP; IF monitorStatusWord THEN { statusWord _ IF BITAND[s, mask.SRQI] # 0 THEN SRQI ELSE 0; BufferSW[]; }; RETURN[statusWord]; }; DataRead: PROC [terminateOn: GPIB.Terminator] RETURNS [ROPE, WORD, BOOL] = { recBuffer: REF TEXT _ RefText.ObtainScratch[bigBuf]; s: CARDINAL _ 0; rope: Rope.ROPE _ NIL; end: BOOL _ FALSE; byteCount: CARDINAL _ 0; [] _ ReadReg[dir]; -- krock to clear dir reg WriteReg[auxmr, goToStandby]; -- if controller active state, go to standby DO -- read unspecified number of bytes Process.CheckForAbort[]; WHILE BITAND[(s _ ReadRegL[isr1]), mask.DI] = 0 DO Process.CheckForAbort[]; ENDLOOP; recBuffer _ RefText.AppendChar[recBuffer, ReadReg[dir]]; -- store byte SELECT terminateOn FROM CR => IF recBuffer[recBuffer.length-1] = '\n THEN {end _ TRUE; EXIT}; LF => IF recBuffer[recBuffer.length-1] = '\l THEN {end _ TRUE; EXIT}; -- IEEE 728 string terminator ENDCASE => IF BITAND[s, mask.BusEND] # 0 THEN {end _ TRUE; EXIT}; -- EOI IF byteCount > maxBytes THEN {end _ FALSE; EXIT}; IF recBuffer.length = recBuffer.maxLength THEN { rope _ Rope.Concat[rope, Rope.FromRefText[recBuffer]]; recBuffer.length _ 0; }; byteCount _ byteCount+1; ENDLOOP; rope _ Rope.Concat[rope, Rope.FromRefText[recBuffer]]; RefText.ReleaseScratch[recBuffer]; IF monitorStatusWord THEN { statusWord _ IF BITAND[s, mask.BusEND] # 0 THEN BusEND ELSE 0; statusWord _ BITOR[statusWord, IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0]; BufferSW[]; }; RETURN[rope, statusWord, end]; }; DataByteRead: PROC [] RETURNS [c: CHAR, w: WORD] = { s: CARDINAL _ 0; [] _ ReadReg[dir]; -- krock to clear dir reg WriteReg[auxmr, goToStandby]; -- if controller active state, go to standby Process.CheckForAbort[]; WHILE BITAND[(s _ ReadRegL[isr1]), mask.DI] = 0 DO Process.CheckForAbort[]; ENDLOOP; c _ ReadReg[dir]; -- store byte IF monitorStatusWord THEN { statusWord _ IF BITAND[s, mask.BusEND] # 0 THEN BusEND ELSE 0; statusWord _ BITOR[statusWord, IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0]; BufferSW[]; }; RETURN[c, statusWord]; }; mBusCtl: POINTER = LOOPHOLE[2]; lBusOutData: POINTER = LOOPHOLE[2]; lBusInData: POINTER = LOOPHOLE[2]; mBusAddr: POINTER = LOOPHOLE[3]; lBusAddr: POINTER = LOOPHOLE[3]; DataWrite: PROC [buffer: ROPE, init, last: BOOL _ TRUE] RETURNS [WORD] = { IF init THEN WriteReg[auxmr, goToStandby]; -- if controller active state, go to standby (data mode) buffer _ Rope.InlineFlatten[buffer]; FOR i: INT IN [0..Length[buffer]) DO XBus.IOWrite[GPIBBaseAddr, LOOPHOLE[Rope.InlineFetch[buffer, i]]]; DO mumble: WORD _ XBus.IORead[GPIBBaseAddr + 1]; IF BITAND[mumble, mask.D0] # 0 THEN EXIT; ENDLOOP; ENDLOOP; IF last THEN WriteReg[auxmr, sendEOI]; -- EOI with last byte IF monitorStatusWord THEN { statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0); BufferSW[]; }; RETURN[statusWord]; }; Clear: PROC [] RETURNS [WORD] = { WriteReg[auxmr, setIFC]; Process.Pause[ticks: 10]; -- 40 ticks = 1mS WriteReg[auxmr, clearIFC]; IF monitorStatusWord THEN { statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0); BufferSW[]; }; RETURN[statusWord]; }; SetRemote: PROC [set: BOOL] RETURNS [WORD] = { WriteReg[auxmr, (IF set THEN setREN ELSE clearREN)]; IF monitorStatusWord THEN { statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0); BufferSW[]; }; RETURN[statusWord]; }; SetStandby: PROC [] RETURNS [WORD] = { WriteReg[auxmr, goToStandby]; IF monitorStatusWord THEN { statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0); BufferSW[]; }; RETURN[statusWord]; }; SetCACS: PROC [] RETURNS [WORD] = { WriteReg[auxmr, takeAsynchControl]; IF monitorStatusWord THEN { statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0); BufferSW[]; }; RETURN[statusWord]; }; Wait: PROC [for: WORD] = { WHILE (BITAND[GetStatus[], for] = 0) DO IF for = 0 THEN EXIT; Process.CheckForAbort[]; ENDLOOP; }; GetStatus: PROC RETURNS [WORD] = { RETURN[statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI]#0 THEN SRQI ELSE 0)]; }; GetParaPoll: PROC [] RETURNS [ROPE, WORD] = { c: CHAR; WriteReg[auxmr, takeAsynchControl]; -- if standby, go to controller active state WriteReg[auxmr, executeParaPoll]; c _ ReadReg[cptr]; -- store the response byte IF monitorStatusWord THEN { statusWord _ (IF BITAND[ReadRegL[isr2], mask.SRQI] # 0 THEN SRQI ELSE 0); BufferSW[]; }; RETURN[Rope.FromChar[c], statusWord]; }; ReadReg: PRIVATE PROC [register: RRegister] RETURNS [char: CHAR] = INLINE { addr: NAT _ SELECT register FROM dir => 0, isr1 => 1, isr2 => 2, spsr => 3, adsr => 4, cptr => 5, adr0 => 6, adr1 => 7, bcr0 => 8, bcr1 => 9, sr => 0Ah, ccfr => 0Bh, ENDCASE => ERROR; word: WORD _ XBus.IORead[LOOPHOLE[GPIBBaseAddr+addr]]; char _ LOOPHOLE[LowByte[word]]; }; ReadRegL: PRIVATE PROC [register: RRegister] RETURNS [word: CARDINAL] = INLINE { addr: NAT _ SELECT register FROM dir => 0, isr1 => 1, isr2 => 2, spsr => 3, adsr => 4, cptr => 5, adr0 => 6, adr1 => 7, bcr0 => 8, bcr1 => 9, sr => 0Ah, ccfr => 0Bh, ENDCASE => ERROR; word _ XBus.IORead[LOOPHOLE[GPIBBaseAddr+addr]]; }; WriteReg: PRIVATE PROC [register: WRegister, dataByte: CHAR ] = INLINE { addr: NAT _ SELECT register FROM cdro => 0, imr1 => 1, imr2 => 2, spmr => 3, admr => 4, auxmr => 5, adr => 6, eosr => 7, bcr0 => 8, bcr1 => 9, cr0 => 0Ah, ccfr => 0Bh, acr0 => 0Ch, acr1 => 0Dh, acr2 => 0Eh, cr1 => 0Fh, ENDCASE => ERROR; XBus.IOWrite[LOOPHOLE[GPIBBaseAddr+addr], LOOPHOLE[dataByte]]; }; WriteRegL: PRIVATE PROC [register: WRegister, dataWord: CARDINAL ] = INLINE { addr: NAT _ SELECT register FROM cdro => 0, imr1 => 1, imr2 => 2, spmr => 3, admr => 4, auxmr => 5, adr => 6, eosr => 7, bcr0 => 8, bcr1 => 9, cr0 => 0Ah, ccfr => 0Bh, acr0 => 0Ch, acr1 => 0Dh, acr2 => 0Eh, cr1 => 0Fh, ENDCASE => ERROR; XBus.IOWrite[LOOPHOLE[GPIBBaseAddr+addr], dataWord]; }; TRUSTED {Process.Detach[FORK BufferToDevice[]]}; END... of GPIBImpl.mesa âGPIBImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Last edited by Neil Gunther, November 5, 1985 4:55:51 pm PST Last Edited by: Gasbarro April 24, 1986 11:37:59 am PST Tim Diebert: September 11, 1986 12:18:30 pm PDT Globals for Level 1 Globals for Level 2 (GPIB-796P interface) *** Level 1: Implementation of GPIB.mesa *** Universal commands (all devices whether adred or not) Selected Device Commands (only those devices adred) Explicit Polling Routines Read Specific Devices for efficiency, don't do any allocates here... for efficiency, don't do do any allocates here... Printer Functions (see Tim Diebert) Private Procedures *** Level 2: Board-specific Procedures *** NEC 7210 M a s k s a n d R e g i s t e r s Auxiliary Controller Commands Nat. Instr. mnemonic Control Masks for Hidden Registers Nat. Instr. mnemonic Controller Register Definitions Nat. Instr. mnemonic G P I B - 7 9 6 P F u n c t i o n s disable secondary adring return controller to idle state or somesuch. disable secondary adring ships the global "sendBuffer" wait for Command Output flag BITOR-ed to preserve SRQI Read unspecified number of bytes of data from the GPIB-796P interface into buffer. In addition to I/O complete, the read operation terminates on detection of EOI. Prior to beginning the read the interface is placed in the controller standby state. No handshake holdoffs are used so care must be exercised when taking control (i.e., asserting ATN) following DataRead. Prior to calling DataRead, the intended devices as well as the interface board itself must be adred by calling Cmd. wait for Data In flag Read one byte of data from the GPIB-796P interface into buffer. In addition to I/O complete, the read operation terminates on detection of EOI. Prior to beginning the read the interface is placed in the controller standby state. No handshake holdoffs are used so care must be exercised when taking control (i.e., asserting ATN) following DataRead. Prior to calling DataRead, the intended devices as well as the interface board itself must be adred by calling Cmd. wait for Data In flag Write data bytes from buffer to the GPIB-796P. The write operation terminates only on I/O complete. By default, EOI is always sent along with the last byte. Prior to beginning the write the interface is placed in the controller standby state. Prior to calling DataWrite, the intended devices, as well as the interface board itself, must be adred by calling Cmd. Send IFC for at least 100 microseconds(4 ticks). Clear must be called prior to the first call to Cmd in order to initialize the bus and enable the interface to leave the controller idle state. Go to the controller standby state (Data mode) from the controller active state, i.e., deassert ATN. Return to the controller active state (Command mode) from the controller standby state, i.e., assert ATN. Note that in order to enter the controller active state from the controller idle state, Clear must be called. Check or wait for a GPIB event to occur. The mask argument is a bit vector corresponding to the status bit vector. It has a bit set for each condition which can terminate the wait. If the mask is 0 then no condition is waited on and the current status is simply returned. Note that since the hardware SRQI bit is volatile it will only be reported once for each occurrence of SRQ. If another function has returned the SRQI status bit, then a call to Wait with a mask containing SRQI will never return. Update GPIB status information. Conduct a parallel poll and return the byte in buf. Prior to conducting the poll the interface is placed in the controller active state. P r i v a t e R e g i s t e r O p e r a t i o n s Initialization Ê!®˜codešœ ™ Kšœ Ïmœ7™BKšœ<™Kšœ˜Kšœ,žœ ˜9Kšœ˜Kšœ#˜#K˜K˜—Kš£œžœžœ žœžœ žœžœ˜mK˜š £ œžœžœ žœžœ˜JKšœ1™1Kšœ žœžœ#˜7Kšœ,žœ ˜;Kšœ<˜Kšžœžœžœ¡˜6Kšžœžœžœ¡˜:Kšžœžœžœ¡˜4Kšžœžœžœ¡˜AKšžœžœžœ¡!˜DKšžœžœžœ¡˜4Kšžœžœžœ¡˜2Kšžœžœžœ¡˜3Kšžœžœžœ¡˜:—Kšœ˜K˜Kš¦'™'K˜š£œžœžœžœ˜ Kšœ"¡ ˜.Kšœ¡0˜MKšœ˜Kšœ˜Kšœ¡˜9Kšœ˜Kšœ˜Kšœ¡)˜DKšœ™Kš œžœžœžœžœžœ˜;Kš œžœžœžœžœžœ˜?Kšœ˜Kšœ$¡+˜OKšœžœžœ¡'˜TKšœžœžœžœ¡˜HKšœžœžœ˜"Kšœžœžœ˜"Kšœžœžœ˜"Kšœ¡˜0šžœžœ˜Kš œ žœžœžœžœžœžœ˜GKšœ ˜ K˜—Kšžœ ˜K˜—K˜š£œžœž˜Kšœžœ˜Kšžœ˜K˜—š£œžœ˜Kšœ,™,Kšœ#˜#Kšœ¡0˜MKšœ˜Kšœ˜Kšœ¡˜9Kšœ˜Kšœ˜Kšœ¡)˜DKšœ™Kš œžœžœžœžœžœ˜;Kš œžœžœžœžœžœ˜?Kšœ˜Kšœ$¡+˜OKšœžœžœ¡'˜TKšœžœžœžœ¡˜HKšœžœžœ˜"Kšœžœžœ˜"Kšœžœžœ˜"K˜—K˜š£œžœ žœžœžœžœžœ˜6Kšœ žœžœ#˜7š žœžœžœžœžœžœž˜2Kšœ5˜5Kšž˜—K˜Kšœ#˜#K˜—K˜š £œžœžœžœžœžœ˜3K™Kšœžœ˜Kšœ'¡0˜Wšžœžœžœž˜'Kšœžœžœžœ ¡&˜OKšœ$¡˜5š žœžœžœžœžœ˜=Kšœ¡œ™6Kšœ¡§ ¡˜+Kšžœ˜ —Kšžœ˜—šžœžœ˜Kš œ žœžœ žœžœžœžœ˜:Kšœ ˜ Kšœ˜—Kšžœ ˜K˜—K˜Kš£œžœžœ žœžœžœžœ˜Lšœ¡ œ¡ œžœžœ(žœžœ:žœ·žœŒ™éKšœ žœžœ!˜4Kšœžœ˜Kšœ žœžœ˜Kšœžœžœ˜Kšœ žœ˜Kšœ¡˜-Kšœ!¡-˜Nšžœ¡#˜'Kšœ˜šžœžœžœž˜2Kšœ™Kšœ˜Kšžœ˜—Kšœ=¡˜Kšžœ žœ˜Kš žœžœ%žœžœžœ˜FKš žœžœ%žœžœžœ¡˜cKšžœžœžœžœžœžœ¡§˜I—Kšžœžœžœžœ˜1šžœ(žœ˜0Kšœ6˜6Kšœ˜K˜—Kšœ˜Kšžœ˜—Kšœ6˜6Kšœ"˜"šžœžœ˜ Kš œ žœžœžœžœ ˜EKšœ žœ žœžœžœžœžœžœ˜ZKšœ ˜ K˜—Kšžœ˜K˜K˜—Kš £ œžœžœžœžœ˜4šœ œžœžœ(žœžœ:žœ·žœŒ™ÖKšœžœ˜Kšœ¡˜-Kšœ!¡-˜NKšœ˜šžœžœžœž˜2Kšœ™Kšœ˜Kšžœ˜—Kšœ¡˜%šžœžœ˜ Kš œ žœžœžœžœ ˜EKšœ žœ žœžœžœžœžœžœ˜ZKšœ ˜ K˜—Kšžœ˜K˜K˜—Kšœ žœžœ˜Kšœ žœžœ˜#Kšœ žœžœ˜"Kšœ žœžœ˜ Kšœ žœžœ˜ K˜Kš£ œžœ žœžœžœžœžœ˜Jš œ$žœžœ*žœžœžœû™ðKšžœžœ"¡8˜fKšœ$˜$šžœžœžœž˜$Kšœžœ˜Bšž˜Kšœžœ!˜-Kšžœžœžœžœ˜)Kšžœ˜—Kšžœ˜ —Kšžœžœ¡§¡˜?šžœžœ˜Kš œžœžœžœžœžœžœ˜IKšœ ˜ K˜—Kšžœ ˜K˜—K˜Kš£œžœžœžœ˜!šœžœ»™ÃKšœ ˜ Kšœ¡˜.Kšœ˜šžœžœ˜Kš œžœžœžœžœžœžœ˜IKšœ ˜ K˜—Kšžœ ˜K˜—K˜š £ œžœžœžœžœ˜.Kšœžœžœžœ ˜6šžœžœ ˜#Kš œžœžœžœžœžœžœ˜IKšœ ˜ K˜—Kšžœ ˜K˜—K˜Kš£ œžœžœžœ˜&šœ`žœ™dKšœ˜šžœžœ˜Kš œžœžœžœžœžœžœ˜IKšœ ˜ K˜—Kšžœ ˜K˜—K˜Kš£œžœžœžœ˜#šœežœp™ØKšœ#˜#šžœžœ˜Kš œžœžœžœžœžœžœ˜IKšœ ˜ K˜—Kšžœ ˜K˜—K˜Kš£œžœžœ˜š œžœžœGžœ)žœ8žœ™ÿšžœžœžœ˜(Kšœžœ žœžœ˜Kšœ˜Kšžœ˜—K˜K˜—š£ œžœžœžœ˜"Kšœžœ™Kšžœžœžœžœžœžœžœ˜OK˜K˜—Kš £ œžœžœžœžœ˜.™ŽKšœžœ˜Kšœ'¡-˜TKšœ%˜%Kšœ¡˜2šžœžœ˜Kš œžœžœžœžœžœžœ˜IKšœ ˜ K˜—Kšžœ˜%K˜—K˜KšÐnzÑbnz¨©¨©™;K˜š £œžœžœžœžœžœ˜Kšœžœžœ ž˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšžœžœ˜—Kšœžœžœ˜6Kšœžœ˜K˜—K˜š £œžœžœžœžœžœ˜Pšœžœžœ ž˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšžœžœ˜—Kšœžœ˜0K˜—K˜š £œžœžœ"žœžœ˜Kšœžœžœ ž˜ K˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—Kšœ žœžœ ˜>K˜—K˜š £ œžœžœ"žœžœ˜Pšœžœžœ ž˜ K˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—Kšœ žœ˜4K˜—K˜—Kš©™™Kšžœžœ˜0—˜KšžœÏi˜——…—U^…î