`L i=L\Ʃx ? N'i  ͭЅ?0ȱ Ѕ?iȱi lԠԠ͠ԠϠŠͮŠ SYSTEM.APPLE   L$JO^lb ATTACHUD.CODEZlDOC.TEXT>ZvI488.CODEI488.CODEIEEEE1 & I488.TEXT>Zl&D I488A.TEXTZlDP I488B.TEXTZlP\ GPIB.TEXT>Zv\c GPIB.CODE>Zvcq IGPIB.TEXTZvq| IGPIB.CODEZv|ATTACH.DRIVERSl SYSTEM.ATTACHZ&꽌ɪɖ'*&%&,E'зЮ꽌ɪФ`+*xH&x'8*7Ixix&&  ') + &п x) ++`FG8`0($ p,&") (jJJ>L+ "?I>  N `  ` x V Nx .x- z `V0^*^*>` aI꽌ɪVɭ&Y&&Y& 꽌ɪ\8`&0.TITLE " APPLE II IEEE-488 Pascal/FORTRAN Driver"  ;--------------------------------------------------------------- ; ; IEEE-488 Pascal/FORTRAN Driver for Apple II ; (C) Apple Computer 1981 ; DEV+3 ;Auxiliary command BUSST .EQU DEV+3 ;Bus status reg  ADRMD .EQU DEV+4 ;Address mode reg CPTRG .EQU DEV+6 ;CMD pass through DIN .EQU DEV+7 ;Daerrupt status 0 INT1 .EQU DEV+1 ;Interrupt status 1 INTM0 .EQU DEV+0 ;INT mask 0 INTM1 .EQU DEV+1 ;INT mask 1 ADRST .EQU DEV+2 ;Address status AUXCMD .EQU DEV .EQU 0BFF1 ;Register addr base is C0NX H; where N = slot # + 80 H;C0NX = BFF1 + X + SLOT H;SLOT = slot # + 8F H;Page BF is used to avoid false read H; on page C0 - 6502 quirk INT0 .EQU DEV+0 ;Inte 0.ENDC ;Otherwise, drop through $010 .ENDM  ;----------------------------------------------- (  0.PROC I488 ; ; GPIB Card Hardware I/O addresses ; n switch index 0.ENDC 0ASL A 0TAY 0LDA %3+1,Y ;Get switch address from table 0PHA ; and push onto stack 0LDA %3,Y 0PHA 0.IF "%4" <> "*" ;If PARM4 is omitted, 0RTS ; Exit to cod.MACRO SWITCH 0.IF "%1" <> "" ;If PARM1 is present, 0LDA %1 ; Load A with switch index 0.ENDC 0.IF "%2" <> "" ;If PARM2 is present, 0CMP #%2+1 ; Perform bounds checking 0BCS $010 ; o ; it; execution will continue following the macro. The  ; program may then load registers or set the status before  ; exiting to the switch address.  ;  ;----------------------------------------------- ; 0first entry corresponds to index zero.  ;  ; * If an asterisk is supplied as the fourth parameter, the  ; macro will push the switch address but will not exit to nd execution  ; will continue following the macro. If bounds is omitted,  ; no bounds checking will be performed.  ;  ; adrs_table This is a table of addresses (low byte first) used by the  ; switch. The ble that is to be used as the switch index.  ; If omitted, the value in the accumulator is used.  ;  ; bounds This is the maximum allowable value for index. If index  ; exceeds this value, the carry bit will be set a ; as an option. The macro uses the A and Y registers and alters the C,  ; Z, and N flags of the status register, but the X register is unchanged.  ;  ; SWITCH [index], [bounds], adrs_table, [*]  ;  ; index This is the varia ;-----------------------------------------------  ;  ; The macro SWITCH performs an N way branch based on a switch index. The  ; maximum value of the switch index is 127 with bounds checking provided PLA (STA %1+1 (.ENDM  ;  ; MACRO PUT 16 BIT ARGUMENT ONTO STACK  ; (.MACRO PUSH (LDA %1+1 (PHA (LDA %1 (PHA (.ENDM ;  ; INCREMENT WORD MACRO  ; (.MACRO INW (INC %1 (BNE $210 (INC %1+1  $210 .ENDM Jim Trezzo 12/22/81 ; ;--------------------------------------------------------------- 0.NOMACROLIST   ;-----------------------------------------------  ;  ; MACRO POPS 16 BIT ARGUMENT FROM STACK  ; (.MACRO POP (PLA (STA %1 (ta in DOUT .EQU DEV+7 ;Data out ; ; Auxiliary Command Equates ; RST .EQU 80 ;Chip reset RSTCLR .EQU 00 ;Clear chip reset  DACR .EQU 01 ;Release DAC holdoff VSADR .EQU 81 ;Valid secondary addr RHDF .EQU 02 ;Release RFD holdoff HDFA .EQU 83 ;Holdoff on all data HDACLR ;Error - driver not yet initilized  BADCNT .EQU 131. ;Count is out of range  US125 .EQU 19 ;Delay count  ;----------------------------------------------------------------------   ENTRYPOINT 1A BLKNUM .EQU 1C  ; ; Miscellaneous Equates ; BADCMD .EQU 128. ;Command error - invalid request  BADLST .EQU 129. ;Invalid address list for function  NOTINIT .EQU 130.  ; ; Zero Page Storage ; LSTFLG .EQU 08  LENGTH .EQU 09  RETURN .EQU 10 TEMP1 .EQU 12 CNTRLWD .EQU 14 UNITNUM .EQU 16 BUFADR .EQU 18 BYTECNT .EQU PAR POLL UNCONFIG SDC .EQU 04 ;SELECTED DEV CLR SPD .EQU 19 ;SERIAL POLL DISABLE SPE .EQU 18 ;SERIAL POLL ENABLE TCT .EQU 09 ;TAKE CONTROL 0 .EQU 11 ;LOCAL LOCKOUT PPC .EQU 05 ;PAR POLL CONFIG. PPD .EQU 70 ;PAR POLL DISABLE PPE .EQU 60 ;PAR POLL ENABLE PPU .EQU 15 ; ;UNIVERSAL UNLSTN UNT .EQU 5F ;UNIVERSAL UNTALK DCL .EQU 14 ;DEVICE CLEAR GET .EQU 08 ;GROUP EXQ TRIGGER GTL .EQU 01 ;GO TO LOCAL LLO BSRQM .EQU 04 ;Bus Status SRQ mask  ; ; GPIB Command Equates ;  MLA .EQU 20 ;MY LISTEN ADDR MTA .EQU 40 ;MY TALK ADDR UNL .EQU 3F Register Mask Equates ; BOM .EQU 10 ;Byte out mask BIM .EQU 20 ;Byte in mask EOIM .EQU 08 ;EOI mask SRQM .EQU 02 ;SRQ mask ;Release control DAI .EQU 93 ;Disable all interrupts DAICLR .EQU 13 ;Clear DAI SHDW .EQU 96 ;Shadow handshake SHDCLR .EQU 16 ;Clear SHDW  ; ; SICCLR .EQU 0F ;Clear IFC SRE .EQU 90 ;Send remote enable SRECLR .EQU 10 ;Clear REN RQC .EQU 11 ;Request control RLC .EQU 12 TCS .EQU 0D ;Take control synchronously  RPP .EQU 8E ;Request parallel poll RPPCLR .EQU 0E ;Clear parallel poll SIC .EQU 8F ;Send interface clear ;Talk only TONCLR .EQU 0A ;Clear talk only GTS .EQU 0B ;Go to standby TCA .EQU 0C ;Take control asynchronously .EQU 06 ;Force Group Execute Trigger FEOI .EQU 08 ;Force EOI on next byte LON .EQU 89 ;Listen only LONCLR .EQU 09 ;Clear listen only TON .EQU 8A .EQU 03 ;Stop holdoff on all data HDFE .EQU 84 ;Holdoff on EOI HDECLR .EQU 04 ;Stop holdoff on EOI  NBAF .EQU 05 ;New byte not available FGET STA TEMP1 ;Save A and Y reg's 0STY TEMP1+1 0POP RETURN ;Save return addr 0TXA ;Use the X reg to determine H; type of call 0SWITCH ,4,IDXTAB 0 BADREQ .EQU * ;Put error code in X reg 0LDX #BADCMD ;Command error - invalid command 0JMP RET1 IDXTAB .EQU * 0.WORD PMS-1 ;0 - read 0.WORD PMS-1 ;1 - write 0.WORD INIT-1 0 0LDA #80 ;Set check for second terminator 0STA TRM2CK 0 $020 INC BYTECNT ;Increment count 0BNE $025 ;Is count zero? 0INC BYTECNT+1 0BEQ $040 ;If bytecount is zero, exit RM2CK 0BEQ $020 ;Always taken 0 $015 CMP EOS+1 ;Is this the first terminator ? 0BNE $020 ;No, continue 0 0BIT EOS ;Check for two terminator mode 0BVC $040 ;No, exit0BIT TRM2CK ;Checking for second terminator ? 0BPL $015 ;No, continue 0 0CMP EOS+2 ;Is this the second terminator ? 0BEQ $040 ;Yes, exit 0 0LDA #0 ;No, clear check 0STA T #EOIM 0BNE $030 ;If EOI, get last byte 0 0LDA DIN,X ;Get data byte 0STA (BUFADR),Y ;Store in buffer 0BIT EOS ;Looking for message terminators ? 0BPL $020 ;No, continue 0 ;Listen only mode 0STA AUXCMD,X 0LDA #GTS ;Go to standby 0STA AUXCMD,X ; ATN goes false 0 $010 LDA INT0,X ;Wait for byte in 0AND #EOIM|BIM ;Test for EOI or byte in 0BEQ $010 0AND ment count 0BNE $05 ;Is count zero? 0INC BYTECNT+1 0BNE $05 0JMP RET ;If bytecount is zero, exit 0 $05 LDA #HDFA ;Enable holdoff on all data 0STA AUXCMD,X 0LDA #LON 0STY RETCNT+1 0STY TRM2CK ;Clear check for second terminator 0LDA #0FF ;One's complement count 0EOR BYTECNT 0STA BYTECNT 0LDA #0FF 0EOR BYTECNT+1 0STA BYTECNT+1 0 0INC BYTECNT ;Incre 0TXA 0BEQ READ 0JMP WRITE  READ LDX SLOT ;Set up slot offset 0BNE $01 0LDX #NOTINIT ;Error if slot is zero 0JMP RET1 0 $01 LDY #0 0STY RETCNT ;Zero count DEX 0BNE $010 0 0TAX ;Restore X 0LDA #SICCLR ;Clear IFC 0STA AUXCMD,X 0RTS 0  PMS POP BLKNUM ;Get the parameters 0POP BYTECNT 0POP BUFADR 0POP UNITNUM 0POP CNTRLWDterface clear (IFC) 0STA AUXCMD,X ; and take control 0TXA ;Save X 0 0LDX #4 ;5130 usec delay (GPIB req >100usec) 0LDY #0 $010 DEY ;5 usec inner loop 0BNE $010 0;----------------------------------------------------------------------  ;  INIT LDA #0 ;Initilization routine 0STA SLOT ;Clear slot offset 0JMP RET 0 0  SNDIFC LDA #SIC ;Send in for H; second terminator  RETCNT .WORD 0 ;Number of bytes received on last read  DEVADR .BYTE 0 ;Device address ('OR' with MTA and MLA)  ;If bit 7 of EOS=1, terminator enabled H; =0, disabled H;If bit 6 of EOS=1, two terminators H;EOS+1 contains message terminator 1 H;EOS+2 contains message terminator 2  TRM2CK .BYTE 0 ;If bit 7 is set, checking ;2 - init 0.WORD BADREQ-1 0.WORD STATUS-1 ;4 - status ; ; LOCAL VARIABLES ; SLOT .BYTE 0 ;SLOT = slot # of IEEE card + 8F H;Slot # ranges from 10 to 70  EOS .BLOCK 3 0 $025 LDA #RHDF 0STA AUXCMD,X ;Release holdoff 0INW BUFADR 0INW RETCNT 0JMP $010 ;Loop 0 $030 LDA DIN,X ;Get last data byte 0STA (BUFADR),Y ;Store in buffer  $040 INW RETCNT 0LDA #TCS 0STA AUXCMD,X ;Take control synchronously 0JSR WAIT 0LDA #RHDF 0STA AUXCMD,X ;Release holdoff 0LDA #TON 0STA AUXCMD,X ;Set talk only mode 0LDA #HDACLR O^l #TCA ;Take control - ATN true 0STA AUXCMD,X 0JSR WAIT 0JSR GPIBCLR ;Clear holdoffs and shadow $050 JMP RET 0 0.INCLUDE I488A.TEXT 0.INCLUDE I488B.TEXT   nator JMP $020 0 $018 LDA (BUFADR),Y ;Get last byte   $020 PHA 0LDA #FEOI ;Force EOI on last byte 0STA AUXCMD,X 0PLA 0STA DOUT,X ;Send to bus 0JSR WAIT 0LDA 0BVS $016 0LDA EOS+1 ;Get first terminator 0JMP $020 0  $016 LDA EOS+1 ;If here, two terminators 0STA DOUT,X ;Send first terminator 0JSR WAIT 0LDA EOS+2 ;Get second termi BIT EOS ;Test for message terminator 0BPL $018 ;No terminator, continue 0 0LDA (BUFADR),Y 0STA DOUT,X ;Send next byte 0JSR WAIT 0 0BIT EOS ;Check for two terminators ;Waits until the byte out flag is set 0AND #BOM 0BEQ $012 ;NOTE - Code could be added here H; to time out after some number of H; seconds if desired. 0JMP $010 ;Loop   $014 JSR WAIT $015 Output to bus 0INW BUFADR ;Point to next byte 0INC BYTECNT ;Increment count 0BNE $012 ;Is count zero? 0INC BYTECNT+1 0BEQ $014 ;Yes, go send last byte  $012 LDA INT0,X 0INC BYTECNT ;Increment count 0BNE $010 ;Is count zero? 0INC BYTECNT+1 0BEQ $015 ;Yes, go send last byte  $010 LDA (BUFADR),Y ;Get next byte  STA DOUT,X ; LDA #SHDW ;Shadow handshake 0STA AUXCMD,X 0LDA #HDFE ;Holdoff on EOI 0STA AUXCMD,X 0LDA #GTS ;Go to standby 0STA AUXCMD,X ; ATN goes false 0LDY #0 lement count 0EOR BYTECNT 0STA BYTECNT 0LDA #0FF 0EOR BYTECNT+1 0STA BYTECNT+1 0 0INC BYTECNT ;Increment count 0BNE $05 ;Is count zero? 0INC BYTECNT+1 0BEQ $050 ;Yes, exit 0 $05 0STA AUXCMD,X ;Clear holdoff mode 0JMP RET 0  WRITE LDX SLOT ;Set up slot offset 0BNE $01 0LDX #NOTINIT ;Error if slot is zero 0JMP RET1 0 $01 LDA #0FF ;One's comp ;--------------------------------------------------------------- ;  ; I488A.TEXT - Continuation of I488.TEXT ; (C) Apple Computer 1981 ; Jim Trezzo 12/22/81 ; ;-------------------------------ETCNT+1 0STA (BUFADR),Y ;Pass hi byte 0JMP RET CONTROL .EQU * ;Control request routine 0LDY #0 0LDA (BUFADR),Y ;Get request code 0CMP #17. ;If CTL17, don't set up slot 0BEQ $05  (BUFADR),Y ;Zero HI byte 0LDA #RPPCLR 0STA AUXCMD,X ;Clear parallel poll command 0JMP RET 0 STAT3 LDY #1 ;Bytes Received 0LDA RETCNT 0STA (BUFADR),Y ;Pass low byte 0INY 0LDA R0STA AUXCMD,X ;Send parallel poll command 0LDY #US125 ;125 usec delay $010 DEY 0BNE $010 0 0LDA CPTRG,X ;Get parallel poll byte 0INY 0STA (BUFADR),Y ;Move to buffer 0INY 0LDA #0 0STA ;Return "0" if SRQ false 0LDY #1 ; "1" if SRQ true 0STA (BUFADR),Y 0INY 0LDA #0 0STA (BUFADR),Y ;Zero HI byte 0JMP RET 0  STAT2 LDA #RPP ;Parallel Poll MD,X ;Clear holdoff mode 0LDA #SPD 0STA DOUT,X ;Send serial poll disable 0JSR WAIT 0JMP RET 0  STAT1 LDA BUSST,X ;Service Requested 0AND #BSRQM ;Check SRQ bit 0LSR A 0LSR A ;Zero HI byte 0LDA #TCS 0STA AUXCMD,X ;Take control synchronously 0JSR WAIT 0LDA #RHDF 0STA AUXCMD,X ;Release holdoff 0LDA #TON 0STA AUXCMD,X ;Set talk only mode 0LDA #HDACLR 0STA AUXC$015 LDA INT0,X ;Wait for byte in 0AND #BIM ;Test for byte in 0BEQ $015 0 0LDA DIN,X ;Get data byte 0LDY #1 0STA (BUFADR),Y ;Store in buffer 0INY 0LDA #0 0STA (BUFADR),Y WAIT 0LDA #HDFA ;Enable holdoff on all data 0STA AUXCMD,X 0LDA #LON ;Listen only mode 0STA AUXCMD,X 0LDA #GTS ;Go to standby 0STA AUXCMD,X ; ATN goes false 0 erial poll 0JSR WAIT 0LDY #3 ;Y points to length byte 0JSR LISTOUT ;Send talk address 0LDA #UNL 0STA DOUT,X 0JSR WAIT 0LDA #MLA 0ORA DEVADR 0STA DOUT,X ;Send my listen address 0JSRSTCK ;Validate address list 0LDA #40 0CMP LSTFLG 0BEQ $010 ;TAD only - list good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDA #SPE 0STA DOUT,X ;Enable s0.WORD STAT0-1 ;0 - Serial Poll 0.WORD STAT1-1 ;1 - Service Requested 0.WORD STAT2-1 ;2 - Parallel Poll 0.WORD STAT3-1 ;3 - Bytes Received Count 0 STAT0 LDY #3 ;Serial Poll 0JSR L ;Get request code 0 0SWITCH ,3,STATTAB   BADSTAT .EQU * ;Put error code in X reg 0LDX #BADCMD ;Command error - invalid command 0JMP RET1 0  STATTAB .EQU * ;Control request 0 $010 LDY #0 ;Status request routine 0LDX SLOT ;Set up slot offset 0BNE $015 0LDX #NOTINIT ;Error if slot is zero 0JMP RET1 0 $015 LDA (BUFADR),Y -------------------------------- 0 STATUS POP BUFADR ;Address of status record 0POP CNTRLWD 0 0LDA #02 0BIT CNTRLWD ;Check if control or status req 0BEQ $010 ;Status request 0JMP CONTROL 0 0LDX SLOT ;Set up slot offset 0BNE $05 0LDX #NOTINIT ;Error if slot is zero 0JMP RET1 0 $05 SWITCH ,17.,CTLTAB 0  BADCTL .EQU * ;Put error code in X reg 0LDX #BADCMD ;Command error - invalid command 0JMP RET1 0  CTLTAB .EQU * 0.WORD CTL0-1 ;0 - Transfer Data 0.WORD CTL1-1 ;1 - Group Execute Trigger 0.WORD CTL2-1 ;2 - Device Clear 0.WORD erflows 0DEC LENGTH 0BNE $010 ;Loop if not done 0 0LDA #7F ;Clear error bit 0AND LSTFLG 0STA LSTFLG 0BPL $050 ;Always taken  $045 LDA #80 ;Set error bit 0ORA ;Secondary addr 60 - 7E hex 0BCC $045 0CMP #7F 0BCS $045 ;Not secondary, invalid 0LDA #7F 0AND LSTFLG ;Clear primary bit 0STA LSTFLG 0  $025 INY 0BEQ $045 ;Terminate if Y ov0ORA LSTFLG ;Set TAD bit and primary bit 0STA LSTFLG 0BNE $025 ;Always taken 0 $020 BIT LSTFLG ;Was previous addr a primary one? 0BPL $045 ;No - invalid list 0CMP #60 Always taken 0 $015 CMP #40 ;Primary talker 40 - 5E hex 0BCC $045 0CMP #5F 0BCS $020 ;Not TAD, continue 0BIT LSTFLG 0BVS $045 ;More than one TAD - invalid 0LDA #0C0 0CMP #3F 0BCS $015 ;Not LAD, continue 0LDA LSTFLG ;Set bit 1 if more than one LAD 0ASL A 0AND #02 0ORA #81 0ORA LSTFLG ;Set LAD bit and primary bit 0STA LSTFLG 0BNE $025 ; ; (A-reg contains length) 0BEQ $050 ;Length is zero, return 0STA LENGTH ;Load length 0INY  $010 LDA (BUFADR),Y ;Get next byte 0CMP #20 ;Primary listener 20 - 3E hex 0BCC $045 0STA LSTFLG ;Clear list flag bits 0 ; bit 7 - Error/Primary addr bit H; bit 6 - TAD bit H; bit 1 - more than one LAD H; bit 0 - LAD bit 0LDA (BUFADR),Y ;Y points to length byte in list 0CMP #0 ta 0.BYTE 0 ;15 - Set Message Terminator 0.BYTE 0 ;16 - Set Controller Device Number 0.BYTE 0 ;17 - Initilize Driver and card 0  LSTCK LDA #0 ;Address list validation ;9 - Remote Enable 0.BYTE 0 ;10 - Local 0.BYTE LLO ;11 - Local Lock Out 0.BYTE 0 ;12 - Abort Interface Clear 0.BYTE 0 ;13 - Send Data 0.BYTE 0 ;14 - Receive Daear 0.BYTE 0 ;4 - Parallel Poll Enable 0.BYTE 0 ;5 - Parallel Poll Disable 0.BYTE PPU ;6 - Parallel Poll Unconfigure 0.BYTE UNT ;7 - Untalk 0.BYTE UNL ;8 - Unlisten 0.BYTE 0  CMDTAB .EQU * ;GPIB Command Table 0 0.BYTE 0 ;0 - Transfer Data 0.BYTE 0 ;1 - Group Execute Trigger 0.BYTE DCL ;2 - Device Clear 0.BYTE 0 ;3 - Selected Device Cl.WORD CTL14-1 ;14 - Receive Data 0.WORD CTL15-1 ;15 - Set Message Terminator 0.WORD CTL16-1 ;16 - Set Controller Device Number 0.WORD CTL17-1 ;17 - Initilize Driver and card 0 L2-1 ;8 - Unlisten 0.WORD CTL9-1 ;9 - Remote Enable 0.WORD CTL10-1 ;10 - Local 0.WORD CTL2-1 ;11 - Local Lock Out 0.WORD CTL12-1 ;12 - Abort Interface Clear 0.WORD CTL13-1 ;13 - Send Data 0 CTL3-1 ;3 - Selected Device Clear 0.WORD CTL4-1 ;4 - Parallel Poll Enable 0.WORD CTL5-1 ;5 - Parallel Poll Disable 0.WORD CTL2-1 ;6 - Parallel Poll Unconfigure 0.WORD CTL2-1 ;7 - Untalk 0.WORD CT LSTFLG 0STA LSTFLG  $050 RTS  LISTOUT .EQU * ;Put list on bus 0LDA (BUFADR),Y ;Y points to length byte in list 0CMP #0 ; (A-reg contains length) 0BEQ $050 ;Length is zero, return 0STA LENGTH ;Load length 0INY 0LDA #01 ;Check for LAD 0BIT LSTFLG 0BEQ $010 ;No LAD 0LDA #UNL 0STA DOUT,X ;Send Unlisten 0JSR WAI ;Send Parallel Poll Configure 0JSR WAIT 0LDY #1 0LDA (BUFADR),Y ;Get SPPP (sense and line addr) 0AND #0F 0ORA #PPE 0STA DOUT,X ;Send Parallel Poll Enable 0JSR WAIT 0JMP RET  CTL5 LDY LG 0BEQ $010 ;List good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDY #2 ;Y points to length byte 0JSR LISTOUT ;Address list 0LDA #PPC 0STA DOUT,X 0STA DOUT,X ;Send Selected Device Clear 0JSR WAIT 0JMP RET  CTL4 LDY #2 ;Parallel Poll Enable 0JSR LSTCK ;Validate address list 0LDA #01 ;Should be one LAD 0CMP LSTFt - list good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDY #1 ;Y points to length byte 0JSR LISTOUT ;Address list 0LDA #SDC mmand on bus 0JSR WAIT 0JMP RET 0  CTL3 LDY #1 ;Selected Device Clear 0JSR LSTCK ;Validate address list 0BIT LSTFLG 0BMI $05 ;Invalid list 0BVC $010 ;No TAD presen DOUT,X ;Send Group Execute Trigger 0JSR WAIT 0JMP RET  CTL2 LDY #0 ;Single command requests 0LDA (BUFADR),Y 0TAY 0LDA CMDTAB,Y ;Index into command table 0STA DOUT,X ;Put co0BVC $010 ;No TAD present - list good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDY #1 ;Y points to length byte 0JSR LISTOUT ;Address list 0LDA #GET 0STA t talk only 0STA AUXCMD,X 0JMP RET  CTL1 LDY #1 ;Group Execute Trigger 0JSR LSTCK ;Validate address list 0BIT LSTFLG 0BMI $05 ;Invalid list EOI 0AND #EOIM 0BEQ $015 ;Loop until EOI 0 0LDA #TCS ;Take control synchronously 0STA AUXCMD,X ; ATN true 0JSR WAIT 0JSR GPIBCLR ;Clear holdoffs and shadow 0LDA #TON ;SeDA #LON ;Listen only mode 0STA AUXCMD,X 0LDA #SHDW ;Shadow handshake 0STA AUXCMD,X 0LDA #GTS ;Go to standby 0STA AUXCMD,X ; ATN goes false $015 LDA INT0,X ;Wait for$05 LDX #BADLST ;Invalid list - TAD required 0JMP RET1 0 $010 LDY #1 ;Y points to length byte 0JSR LISTOUT ;Address list 0LDA #HDFE ;Holdoff on EOI 0STA AUXCMD,X 0L   CTL0 LDY #1 ;Transfer Data 0JSR LSTCK ;Validate address list 0BIT LSTFLG 0BMI $05 ;Invalid list 0BVS $010 ;TAD present - list good 0 RTS  GPIBCLR LDA #RHDF ;Clear holdoffs and shadow 0STA AUXCMD,X ;Release holdoff 0LDA #HDECLR 0STA AUXCMD,X ;Clear holdoff on EOI 0LDA #SHDCLR 0STA AUXCMD,X ;Clear shadow handshake 0RTST  $010 LDA (BUFADR),Y ;Get next byte 0STA DOUT,X ;Put on data bus 0JSR WAIT 0INY 0BEQ $050 ;Terminate if Y overflows 0DEC LENGTH 0BNE $010 ;Loop if not done  $050 #1 ;Parallel Poll Disable 0JSR LSTCK ;Validate address list 0LDA #01 ;Should be one LAD 0CMP LSTFLG 0BEQ $010 ;List good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDY #1 ;Y points to length byte 0JSR LISTOUT ;Address list 0LDA #PPC 0STA DOUT,X ;Send Parallel Poll Configure 0JSR WAIT 0LDA #PPD 0STA DOUT,X ;Send ;Validate address list 0BIT LSTFLG 0BMI $05 ;Invalid list 0BVC $010 ;No TAD present - list good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDA #MTA -------------------------------------------- 0 CTL12 JSR SNDIFC ;Interface Clear 0LDA #TON 0STA AUXCMD,X ;Restore talk only mode 0JMP RET 0  CTL13 LDY #1 ;Send Data 0JSR LSTCK  ;--------------------------------------------------------------- ;  ; I488B.TEXT - Continuation of I488.TEXT, I488A.TEXT ; (C) Apple Computer 1981 ; Jim Trezzo 12/22/81 ; ;-------------------O^l RET  ;Y points to length byte 0JSR LISTOUT ;Address list  LDA #GTL 0STA DOUT,X ;Send Go To Local 0JSR WAIT 0JMP RET 0  $015 LDA #SRECLR ;Clear REN 0STA AUXCMD,X 0JMP 0BVS $05 ;TAD present - invalid 0BNE $010 ;LAD present, send list 0BEQ $015 ;No LAD, clear REN 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDY #1 gth byte 0JSR LISTOUT ;Address list 0JMP RET   CTL10 LDY #1 ;Local 0JSR LSTCK ;Validate address list 0LDA #1 0BIT LSTFLG 0BMI $05 ;Invalid list - list good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 $010 LDA #SRE 0STA AUXCMD,X ;Set Remote Enable 0LDA #0 0STA LSTFLG ;Prevent UNL 0LDY #1 ;Y points to lenParallel Poll Disable 0JSR WAIT 0JMP RET  CTL9 LDY #1 ;Remote Enable 0JSR LSTCK ;Validate address list 0BIT LSTFLG 0BMI $05 ;Invalid list 0BVC $010 ;No TAD present ;Send Data 0ORA DEVADR 0STA DOUT,X ;Send My Talk Address 0JSR WAIT 0LDY #1 ;Y points to length byte 0JSR LISTOUT ;Address list 0JMP RET 0 CTL14 LDY #1 ;Receive Data 0JSR LSTCK ;Validate address list 0LDA #40 0CMP LSTFLG 0BEQ $010 ;TAD only - list good 0 $05 LDX #BADLST ;Invalid list 0JMP RET1 0 INT0,X ;Waits until the byte out flag is set 0AND #BOM 0BEQ WAIT ;NOTE - Code could be added here H; to time out after some number of H; seconds if desired. 0RTS  0.END   RET LDX #0 ;Success - error code = 0  RET1 PUSH RETURN 0LDA TEMP1 ;Restore A and Y reg's 0LDY TEMP1+1 0RTS ;Completion code should be in X reg 0  WAIT LDA AUXCMD,X 0JSR WAIT ;Wait for byte out (BO) 0LDA #RQC ;Go to controller active state 0STA AUXCMD,X 0LDA #SHDCLR ;Clear shadow handshake 0STA AUXCMD,X 0JMP RET  ;Disable all interrupts 0STA AUXCMD,X 0LDA #0 0STA INTM0,X ;Set interrupt mask regesters 0STA INTM1,X 0LDA #RSTCLR ;Clear software reset 0STA AUXCMD,X 0LDA #TON ;Set talk only mode 0STA ;Set up slot offset 0LDA #0 0STA EOS ;Clear message terminator mode 0STA EOS+1 0STA EOS+2 0STA DEVADR ;Set device addr to zero 0LDA #RST ;Reset 9914 0STA AUXCMD,X 0LDA #DAI $010 CMP #8 ;Valid slots are 1 to 7 0BCS $05 0ASL A 0ASL A 0ASL A 0ASL A ;Slot # ranges from 10 to 70 0CLC 0ADC #8F ;SLOT = slot # + 8F 0STA SLOT 0TAX ;Initilize driver and IEEE card 0LDA (BUFADR),Y ;Get slot number 0BNE $010 ;Validate slot number $05 LDX #BADCNT ;Count error - invalid slot number 0JMP RET1 0 ice number 0AND #1F 0CMP #1F 0BEQ $010 ;Dev number 31 not allowed 0STA DEVADR ;Save new device address 0JMP RET $010 LDX #BADCNT ;Count error 0JMP RET1  CTL17 LDY #2 LDX #BADCNT ;Count error 0JMP RET1 0 $015 STA EOS ;Clear message terminator bit 0JMP RET 0  CTL16 LDY #2 ;Set Controller Device Number 0LDA (BUFADR),Y ;Get dev0STA EOS 0BNE $06 ;Always taken 0 $05 LDA #80 ;Set message terminator bit 0STA EOS $06 LDY #2 0LDA (BUFADR),Y 0STA EOS+1 ;Store terminator 1 0JMP RET $010 tors 0BCS $010 ;If length > 2, error 0BNE $05 ;Always taken, load one terminator 0 $04 LDY #3 0LDA (BUFADR),Y 0STA EOS+2 ;Store terminator 2 0LDA #0C0 ;Set bits 7 and 6 ddress 0JSR WAIT 0JMP RET 0  CTL15 LDY #1 ;Set Message Terminator 0LDA (BUFADR),Y 0BEQ $015 ;If length = 0, clear terminator 0CMP #2 0BEQ $04 ;If length = 2, load two termina $010 LDY #1 ;Y points to length byte 0JSR LISTOUT ;Address listener 0LDA #UNL 0STA DOUT,X ;Send Unlisten 0JSR WAIT 0LDA #MLA 0ORA DEVADR 0STA DOUT,X ;Send My Listen AO^kvUNCTION RCV; $BEGIN &IF DATALEN=0 THEN ERR:=BADCNT 3ELSE CONTROL(14, ADDRLST); &IF ERR=0 THEN DATAIN(DATABUF, DATALEN); &IF ERR=0 THEN STATUS(3, RCVCNT, INUL); &RCV:=ERR $END; $ "FUNCTION XFER; $BEGIN &CONTROL(0, ADDRLST); &XFER:=ERR $END; $ HEN BEGIN 6TMPSTR:=' '; 6TMPSTR[1]:=CHR(SLOT); 6CONTROL(17, TMPSTR) 4END; &IBINIT:=ERR $END; $ "FUNCTION SEND; $BEGIN &IF DATALEN=0 THEN ERR:=BADCNT 3ELSE CONTROL(13, ADDRLST); &IF ERR=0 THEN DATAOUT(DATABUF, DATALEN); &SEND:=ERR $END; $ "F&ERR:=IORESULT $END; "PROCEDURE DATAIN(VAR DATABUF:BUSBUF; DATALEN:INTEGER); " $BEGIN &UNITREAD(I488,DATABUF,DATALEN); &ERR:=IORESULT $END; "FUNCTION IBINIT; $VAR TMPSTR : STRING[1]; $ $BEGIN $ UNITCLEAR(I488); &ERR:=IORESULT; &IF ERR=0 TODE); &MOVELEFT(ADDRLST, BUF[3], LENGTH(ADDRLST)+1); &UNITSTATUS(I488,BUF,STAT); &ERR:=IORESULT; &MOVELEFT(BUF[1], STATRES, 2) $END;  "PROCEDURE DATAOUT(VAR DATABUF:BUSBUF; DATALEN:INTEGER); " $BEGIN &UNITWRITE(I488,DATABUF,DATALEN,,12); " $BEGIN &BUF[0]:=CHR(CODE); &MOVELEFT(ADDRLST, BUF[1], LENGTH(ADDRLST)+1); &UNITSTATUS(I488,BUF,CTL); &ERR:=IORESULT $END;  "PROCEDURE STATUS(CODE:INTEGER;VAR STATRES:INTEGER; VAR ADDRLST:STRING); " VAR BUF : PA258; " $BEGIN &BUF[0]:=CHR(C= 2; $STAT = 0; $MAXDEV = 30; $BADCNT = 131; { Error code for count error } "TYPE $PA258 = PACKED ARRAY [0..258] OF CHAR;  VAR $ERR, CODE : INTEGER; $INUL : STRING[1];  "PROCEDURE CONTROL(CODE:INTEGER; VAR ADDRLST:STRING); " VAR BUF : PA258;"FUNCTION SPL(VAR ADDRLST:STRING; VAR RESULT:INTEGER): INTEGER; "FUNCTION SRQ(VAR RESULT:INTEGER): INTEGER; "FUNCTION PPL(VAR RESULT:INTEGER): INTEGER;  IMPLEMENTATION "CONST $I488 = 128; { Pascal unit number of the attached IEEE-488 driver } $CTL NG): INTEGER; "FUNCTION LCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION LLO: INTEGER; "FUNCTION IFC: INTEGER; "FUNCTION EOS(VAR ADDRLST:STRING): INTEGER; "FUNCTION DEV(DEVICE:INTEGER): INTEGER; :STRING): INTEGER; "FUNCTION DCL: INTEGER; "FUNCTION PPE(VAR ADDRLST:STRING; ENABLE:INTEGER): INTEGER; "FUNCTION PPD(VAR ADDRLST:STRING): INTEGER; "FUNCTION PPU: INTEGER; "FUNCTION UNT: INTEGER; "FUNCTION UNL: INTEGER; "FUNCTION REN(VAR ADDRLST:STRIUF; 0DATALEN:INTEGER): INTEGER; "FUNCTION RCV(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; DATALEN:INTEGER; /VAR RCVCNT:INTEGER): INTEGER; "FUNCTION SDCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION XFER(VAR ADDRLST:STRING): INTEGER; "FUNCTION GETR(VAR ADDRLST{$SETC APPLE := 2} { Allows compilation on an Apple /// for an Apple II } {$S+}  {$V-}  UNIT GPIB;  INTERFACE "TYPE $BUSBUF=PACKED ARRAY [0..0] OF CHAR; " "FUNCTION IBINIT(SLOT:INTEGER): INTEGER; "FUNCTION SEND(VAR ADDRLST:STRING; VAR DATABUF:BUSB"FUNCTION GETR; $BEGIN &CONTROL(1, ADDRLST); &GETR:=ERR $END; $ "FUNCTION DCL; $BEGIN &CONTROL(2, INUL); &DCL:=ERR $END; $ "FUNCTION SDCL; $BEGIN &CONTROL(3, ADDRLST); &SDCL:=ERR $END; $ "FUNCTION PPE; " VAR BUF : PA258; $ $BEGIN &BUF[0]:=CHR(4); &BUF[1]:=CHR(ENABLE); &MOVELEFT(ADDRLST, BUF[2], LENGTH(ADDRLST)+1); &UNITSTATUS(I488,BUF,CTL); &PPE:=IORESULT $END; $ "FUNCTION PPD; $BEGIN &CONTROL(5, ADDRLST); &PPD:=ERR $END; $ "FUNCTION PPU; $BEGIN &CONTROL(6, INUL); "FUNCTION SPL(VAR ADDRLST:STRING; VAR RESULT:INTEGER): INTEGER; "FUNCTION SRQ(VAR RESULT:INTEGER): INTEGER; "FUNCTION PPL(VAR RESULT:INTEGER): INTEGER;  IMPLEMENTATION E T:STRING): INTEGER; "FUNCTION LLO: INTEGER; "FUNCTION IFC: INTEGER; "FUNCTION EOS(VAR ADDRLST:STRING): INTEGER; "FUNCTION DEV(DEVICE:INTEGER): INTEGER; :--)PBBINTEGER xON PPD(VAR ADDRLST:STRING): INTEGER; "FUNCTION PPU: INTEGER; "FUNCTION UNT: INTEGER; "FUNCTION UNL: INTEGER; "FUNCTION REN(VAR ADDRLST:STRING): INTEGER; "FUNCTION LCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION LLO: INTEGER; "FUNCTION IFC: INTEGER; "FUVCNT:INTEGER): INTEGER; "FUNCTION SDCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION XFER(VAR ADDRLST:STRING): INTEGER; "FUNCTION GETR(VAR ADDRLST:STRING): INTEGER; "FUNCTION DCL: INTEGER; "FUNCTION PPE(VAR ADDRLST:STRING; ENABLE:INTEGER): INTEGER; "FUNCTI "TYPE $BUSBUF=PACKED ARRAY [0..0] OF CHAR; " "FUNCTION IBINIT(SLOT:INTEGER): INTEGER; "FUNCTION SEND(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; 0DATALEN:INTEGER): INTEGER; "FUNCTION RCV(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; DATALEN:INTEGER; /VAR RCBBBBBBBBBBBBBBBBr GPIB "FUNCTION SRQ; $BEGIN &STATUS(1, RESULT, INUL); &SRQ:=ERR $END; $ "FUNCTION PPL; $BEGIN &STATUS(2, RESULT, INUL); &PPL:=ERR $END; $ "BEGIN ${ INITILIZATION CODE } " INUL:='' "END.  PSTR : STRING[1]; $ $BEGIN &IF DEVICE > MAXDEV THEN ERR:=BADCNT 4ELSE BEGIN 6TMPSTR:=' '; 6TMPSTR[1]:=CHR(DEVICE); 6CONTROL(16, TMPSTR) 4END; &DEV:=ERR $END; $ "FUNCTION SPL; $BEGIN &STATUS(0, RESULT, ADDRLST); &SPL:=ERR $END; $ ADDRLST); &LCL:=ERR $END; $ "FUNCTION LLO; $BEGIN &CONTROL(11, INUL); &LLO:=ERR $END; $ "FUNCTION IFC; $BEGIN &CONTROL(12, INUL); &IFC:=ERR $END; $ "FUNCTION EOS; $BEGIN &CONTROL(15, ADDRLST); &EOS:=ERR $END; $ "FUNCTION DEV; $VAR TM&PPU:=ERR $END; $ "FUNCTION UNT; $BEGIN &CONTROL(7, INUL); &UNT:=ERR $END; $ "FUNCTION UNL; $BEGIN &CONTROL(8, INUL); &UNL:=ERR $END; $ "FUNCTION REN; $BEGIN &CONTROL(9, ADDRLST); &REN:=ERR $END; $ "FUNCTION LCL; $BEGIN &CONTROL(10, NCTION EOS(VAR ADDRLST:STRING): INTEGER; "FUNCTION DEV(DEVICE:INTEGER): INTEGER; :--)PBBINTEGER xٿǀ "2ڿǀ ">ǀ "ǀ"ǀ&"á ڿ.áǃ á$WRITELN(' UNT UNL REN LCL LLO IFC INI'); " WRITELN(' ENTER "X" TO EXIT'); "END;   PROCEDURE ISND; "BEGIN $GTADR; $GTDATA; $ERR:= SEND(ADDRBUF, DATA.IBUF, DATALEN); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR SEND') "END;   PROCEDUR[1], DATA.BUF, DATALEN) %{$R+} #END; *  PROCEDURE HELP; "BEGIN " WRITELN('AVAILABLE FUNCTIONS:'); $WRITELN(' SND RCV XFR GET DCL SDC EOS'); $WRITELN(' SPL SRQ PPL PPE PPD PPU DEV'); (BUF:PA255); 'END; " PROCEDURE GTADR; # #BEGIN %WRITE('ENTER LIST OF ADDRESSES: '); %READLN(ADDRBUF) #END; * PROCEDURE GTDATA; # #BEGIN %WRITE('ENTER LIST OF DATA: '); %READLN(INSTRING); %DATALEN:=LENGTH(INSTRING); %{$R-} %MOVELEFT(INSTRING"PA255= PACKED ARRAY [0..255] OF CHAR;  VAR "ENABLE,DEVICE,SLOT,ERR,DATALEN,COMNUM,I:INTEGER; "INSTRING,SDATA,SOUT:STRING[255]; "COMMANDS:ARRAY [0..LASTCOM] OF STRING[3]; "ADDRBUF:STRING; "DATA:RECORD CASE BOOLEAN OF (FALSE: (IBUF:BUSBUF); (TRUE:{$SETC APPLE := 2} { Allows compilation on an Apple /// for an Apple II }  {$S+}  PROGRAM IGPIB;  { INTERACTIVE GPIB CARD EXERCISER }  {$USING GPIB.CODE}  USES GPIB;   CONST "LASTCOM = 23; { 1 MORE THAN # OF VALID COMMANDS } TYPE O^ǡvڥת8Rj0Jd|\4ڿǀ ":  ERR  ']"-;Qg1G]uINUL  6z,p) Pšǃ ڿ*ڥڥת8Rj0Jd|\4ڿǀ ":         šǃ ڿ*ڥ *áǃááڥ 8ڿǀ ":  E IRCV; "BEGIN $GTADR; $DATALEN:=255; $ERR:= RCV(ADDRBUF, DATA.IBUF, DATALEN, I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR RCV'); $DATALEN:=I MOD 256; ${$R-} SOUT[0]:=CHR(DATALEN); $MOVELEFT(DATA.BUF, SOUT[1], DATALEN); {$R+} $WRITELN(I,' DATA BYTES RECEIVED'); $WRITELN(SOUT) "END;   PROCEDURE IXFR; "BEGIN $GTADR; $ERR:= XFER(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR XFR') "END;   PROCEDURE IGET; "BEGIN $GTADR; $ERR:= GETR(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = '"FOR COMNUM:=0 TO LASTCOM DO COMMANDS[COMNUM]:=COPY(SDATA,COMNUM*3+1,3); "SLTINIT; "REPEAT $WRITELN; $WRITE('ENTER DESIRED FUNCTION (? - HELP): '); $READLN(INSTRING); $FOR I:= LENGTH(INSTRING)+1 TO 3 DO INSTRING:=CONCAT(INSTRING,' '); $COMMANDS[LAS-} $SLOT:=ORD(INSTRING[1])-ORD('0'); ${$R+} $ERR:= IBINIT(SLOT); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR IBINIT') "END;   BEGIN "SDATA:= '? SNDXFRGETDCLSDCSPLSRQPPLPPERCVPPDPPUUNTUNLRENLCLLLOIFCEOSDEVINIX '; EVICE:=ORD(INSTRING[1])-ORD('0'); $IF DEVICE<>-1 THEN ERR:= DEV(DEVICE); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR DEV') "END;  PROCEDURE SLTINIT; "BEGIN $WRITELN('ENTER SLOT NUMBER OF IEEE-488 CARD'); $WRITE('(1-7) :'); $READLN(INSTRING); ${$R  PROCEDURE IDEV; "BEGIN $DEVICE:=-1; $ERR:=0; $WRITE('ENTER CONTROLLER DEVICE NUMBER: (0-30)'); $READLN(INSTRING); $IF LENGTH(INSTRING)=2 (THEN DEVICE:=(ORD(INSTRING[1])-ORD('0'))*10 + ORD(INSTRING[2])-ORD('0') (ELSE IF LENGTH(INSTRING)=1 THEN D(ELSE IF INSTRING[1]='2' THEN BEGIN DADDRBUF:=' '; DADDRBUF[1]:=CHR(13); DADDRBUF[2]:=CHR(10) BEND (ELSE INSTRING[1]:='X'; &IF INSTRING[1]<>'X' THEN BEGIN >ERR:= EOS(ADDRBUF); >IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR EOS') , 2 FOR :'); $READLN(INSTRING); $IF LENGTH(INSTRING)=1 THEN &BEGIN &IF INSTRING[1]='0' THEN ADDRBUF:='' (ELSE IF INSTRING[1]='1' THEN BEGIN C ADDRBUF:=' '; DADDRBUF[1]:=CHR(13) BEND ;   PROCEDURE ILLO; "BEGIN $ERR:= LLO; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR LLO') "END;   PROCEDURE IIFC; "BEGIN $ERR:= IFC; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR IFC') "END;   PROCEDURE IEOS; "BEGIN WRITE('ENTER; 0 FOR RR,' FOR UNL') "END;   PROCEDURE IREN; "BEGIN $GTADR; $ERR:= REN(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR REN') "END;   PROCEDURE ILCL; "BEGIN $GTADR; $ERR:= LCL(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR LCL') "END"BEGIN $ERR:= PPU; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPU') "END;   PROCEDURE IUNT; "BEGIN $ERR:= UNT; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR UNT') "END;   PROCEDURE IUNL; "BEGIN $ERR:= UNL; $IF ERR<>0 THEN WRITELN('ERR = ',E; $IF ENABLE<>-1 THEN ERR:= PPE(ADDRBUF, ENABLE); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPE') "END;   PROCEDURE IPPD; "BEGIN $GTADR; $ERR:= PPD(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPD') "END;   PROCEDURE IPPU; R; $ENABLE:=-1; $ERR:=0; $WRITE('ENTER ENABLE BYTE VALUE: (0-15)'); $READLN(INSTRING); $IF LENGTH(INSTRING)=2 (THEN ENABLE:=(ORD(INSTRING[1])-ORD('0'))*10 + ORD(INSTRING[2])-ORD('0') (ELSE IF LENGTH(INSTRING)=1 THEN ENABLE:=ORD(INSTRING[1])-ORD('0')SRQ'); $WRITELN('SERVICE REQUESTED RESULT (decimal) = ',I) "END;   PROCEDURE IPPL; "BEGIN $ERR:= PPL(I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPL'); $WRITELN('PARALLEL POLL RESULT (decimal) = ',I) "END;   PROCEDURE IPPE; "BEGIN $GTAD PROCEDURE ISPL; "BEGIN $GTADR; $ERR:= SPL(ADDRBUF, I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR SPL'); $WRITELN('SERIAL POLL RESULT (decimal) = ',I) "END;   PROCEDURE ISRQ; "BEGIN $ERR:= SRQ(I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR ,ERR,' FOR GET') "END;   PROCEDURE IDCL; "BEGIN $ERR:= DCL; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR DCL') "END;   PROCEDURE ISDC; "BEGIN $GTADR; $ERR:= SDCL(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR SDC') "END;  TCOM]:=COPY(INSTRING,1,3); $COMNUM:=0; $WHILE COMMANDS[COMNUM]<>COPY(INSTRING,1,3) &DO COMNUM:=COMNUM+1; $CASE COMNUM OF &0,LASTCOM:HELP; &1:ISND; 10:IRCV; &2:IXFR; 11:IPPD; &3:IGET; 12:IPPU; &4:IDCL; 13:IUNT; &5:ISDC; 14:IUNL; &6:ISPL; 15:IREN; &7:ISRQ; 16:ILCL; &8:IPPL; 17:ILLO; &9:IPPE; 18:IIFC; &19:IEOS; 20:IDEV; &21:SLTINIT $END "UNTIL COMNUM=LASTCOM-1  END.  á 0 0  á 0 ˡ  ˡ8צERR =  צ FOR PPE ˡ8צERR =  צ FOR PPDR ˡ8Eimal) =   ˡ8ERR =   FOR PPL!PARALLEL POLL RESULT (decimal) =    צENTER ENABLE BYTE VALUE: (0-15) R ˡ8צERR =  צ FOR SPLצSERIAL POLL RESULT (decimal) =   ˡ8ERR =   FOR SRQ%SERVICE REQUESTED RESULT (decRˡ8צERR =  צ FOR GETRˡ8ERR =   FOR DCLL ˡ8צERR =  צ FOR SDCˡ8ERR =   FOR RCV 쿥   DATA BYTES RECEIVED ˡ8צERR =  צ FOR XFR SPL SRQ PPL PPE PPD PPU DEV# UNT UNL REN LCL LLO IFC INIצ ENTER "X" TO EXITˡ9צERR =  צ FOR SENDXENTER LIST OF ADDRESSES: PBENTER LIST OF DATA:    PAVAILABLE FUNCTIONS:# SND RCV XFR GET DCL SDC EOSצ# ڥת8Rj0Jd|\4ڿǀ ":         šǃ ڿ*ڥ *áǃááڥ 8ڿǀ ":  ٿǀ "2ڿǀ ">ǀ "ǀ"ǀ&"䩂á ڿ.áǃ áBB rIGPIB GPIB RR =   FOR PPUL ˡ8ERR =   FOR UNTL ˡ8ERR =   FOR UNLLˡ8צERR =  צ FOR RENRˡ8צERR =  צ FOR LCLRˡ8ERR =   FOR LLOLˡ8ERR =  s L L $0PL s L L s ) ` L L s p L $0PL sL $0pL s LL 9L $0PL@_?U ȱ F?  ) &@1_ $p)$`% м%` ȩ$?   `` $0pL s )  L $0PL  @L  s?  0  ) ȩ  L)JJȩLȑȩL.ȭ/L )L HH`L =k    ;q./ L)LEEz   )L` ,*" ,*p+L+ ,LHh   Lhhhh$L)L HH`Lvhh HH`LOO0)L`hhhhhhhhhhL))L./-EEL )()H,* ,- ,9-+ ,*P(-./LGZI488 c ccX{ws ok gc _[ WS OKGC?;70_]WQKE?93-ke_YSMGA;975.á u!nplFr  ` b ~ 2SDEVINIX c멂cȡ$ddצ#ENTER DESIRED FUNCTION (? - HELP):   cꩂcȡ, dd dצ d cc ccX{ws ok gc _[ WS OKGC?;70_]WQKE?93-ke_YSMGA;975.á u!npPPERCVPPDPPUUNTUNLRENLCLLLOIFCEOSDEVINIX c멂cȡ$ddצ#ENTER DESIRED FUNCTION (? - HELP):   cꩂcȡ, dd dצ d cDEV"ENTER SLOT NUMBER OF IEEE-488 CARD(1-7) :  0ˡ;צERR =  צ FOR IBINITצH? SNDXFRGETDCLSDCSPLSRQPPLERR =   FOR EOSצ&ENTER CONTROLLER DEVICE NUMBER: (0-30)  á 0 0 á 0ˡˡ8צERR =  צ FOR  FOR IFCL8ENTER; 0 FOR NO TERMINATOR, 1 FOR , 2 FOR :  á 0á צPD 1á P + 2á תP   X XˡGˡ8 0  sL @L s?  0 L*,**+LL*L)0LLL i)*+,0 LHH`)`tTQNIFC>*'& {xsjhccccc`WQNHEA*$ }|ypmga`]THGD5GU /@8Y[<>PJLFHJL579;=?ACEGIKMOQSةY  Y eٓYyؤ ١-(A needed driver is not in ATTACH.DRIVERS ȡإYˡצreading driver,!6 d <ȡةYعQ+~ ( .v4nB  00EE BB00E2 B!00EA Gצ00E8 /0 Y ˡY ˡ  4 Yš.,A  IN HEX CHAR--..rZ ڨ铡 VS!4 ٪P,,T تP,,T بġ!4 6SS012345678 9 A B C DEF<Jۨڨš+áġR٪P-././ġh-,,.,04,~TTACH.DATAȡ Y ATTACH.DATA"ˡ(צ#ATTACH.DATA needed by SYSTEM.ATTACHATTACH.DRIVERS"ˡ+&ATTACH.DRIVERS needed by SYSTEM.ATTACHYˡ1צ,Reading segment dictionary of ATTACH.DRIVERتPצERROR =>RETURN to exit SYSTEM.ATTACH:R`Y Yآ آ V6000תSצ6000Nآ V4000תSצ6000+V2000תآ Sצ4000 S6000תצNo records in APRINTU PSUBDR =RREAD RINIT REMIU RELOCATE REMOU RWRITE RSTAT 4SYSTU UD128U  UD129U UD130U UD131U UD132U UD133U Ɓ\ƂƁ\ 6U UD137U UD138U UD139U UD140U UD141U UD142U UD143U UDJVM1 /UDRWI :UNDEFU WRITEBIO  PSTAT .G$PASCALSYSYSATCH I488 I488  2,+%$ |qR м%` ȩ$?   `` $0pL s )  L $0PL Yrc |צ00EE B00EA Gצ00E8 /07L^ȡ  ɡ؞&s&&4Y  Yf8hhhhhhhhhhHH`8hhhhhhh h hhȱLC8 ȥ  e ȱ e 8iiHHHH`Jt,40<v^b(-(A needed driver is not in ATTACH.DRIVERSצdevice driver?,0 /0 .00,&Unit number (RETURN to abort program):***z---{- q-@g-ǀ[-ǀO-C- the .PROC name in it's assemblyצ source (RETURN to exit program):š Name of driver too long0 +/+/ȡ0++++'Which unit numbers should refer to this 256 byte PAGE boundry.**šP'Enter boundry (RETURN to exit program):*0 * 0 {  &What is the name of this driver? This'must be%The boundry can be between 0 and 256.צ( 0=>Driver can start anywhere.(default)צ% 8=>Driver starts on 8 byte boundry.% N=>Driver starts on N byte boundry.צ,256=>Driver starts on& Do you want this unit to beצinitialized at boot time?00- %Do you want this driver to start on aצcertain byte boundry?צ%You can't attach a character unit and#a block unit to the same driver. Iצ'will remove the last unit# you entered.00-Type RETURN to continue:attachud [1.1]צEnter name of attach data file:0"ˡlצERROR opening attach data fileצHit RETURN to exit program00צprompt for that page.%Will you ever use the (2000.3FFF hex)צ hires page? /%Will you ever use the (4000.5FFF hex)צ hires page? .Apple pascal P&These next questions will determine if(attached drivers can reside in the hires'pages. It will be assumed they can forצ(page in question if you answer no to theצY/N:RšצNumber too largeބݛޓWe want a positive numberޡބ<  ݛ7ńۦ תP ݛ0ޡPá&٪Pצ ERROR => צ#Try again (RETURN to exit program):Rx P@@NPá P@@B ATTACHUD Yrc |צ00EE B00EA Gצ00E8 /07L^ȡ  ɡ؞&s&&4Y  Yj8>x8^< |7-+- yskc[QG=3)*ǀǏ*- -@------- -@-w-g-W-G-7-' {m_QC5?ERROR => Illegal unit number-00-  (Do you want another unit number to referfunctions provided by the attached device driver. Low level functions such as UNITCLEAR, UNITREAD, UNITWRITE and UNITSTATUS are provided by the driver. All communication with the IEEE-488 card will be through the driver. GER; The second part of the software takes the form of an attached driver to the Pascal BIOS. This driver (I488) is written in TLA assembler code. The Pascal unit GPIB, which supports the higher level functions, relies on low level TION PPD(VAR ADDRLST:STRING): INTEGER; FUNCTION PPU: INTEGER; FUNCTION UNT: INTEGER; FUNCTION UNL: INTEGER; FUNCTION REN(VAR ADDRLST:STRING): INTEGER; FUNCTION LCL(VAR ADDRLST:STRING): INTEGER; FUNCTION LLO: INTEGER; FUNCTION IFC: INTEAR ADDRLST:STRING): INTEGER; FUNCTION SPL(VAR ADDRLST:STRING; VAR RESULT:INTEGER): INTEGER; FUNCTION SRQ(VAR RESULT:INTEGER): INTEGER; FUNCTION PPL(VAR RESULT:INTEGER): INTEGER; FUNCTION PPE(VAR ADDRLST:STRING; ENABLE:INTEGER): INTEGER; FUNC FUNCTION RCV(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; DATALEN:INTEGER; VAR RCVCNT:INTEGER): INTEGER; FUNCTION XFER(VAR ADDRLST:STRING): INTEGER; FUNCTION GETR(VAR ADDRLST:STRING): INTEGER; FUNCTION DCL: INTEGER; FUNCTION SDCL(VER): INTEGER; FUNCTION EOS(VAR ADDRLST:STRING): INTEGER; FUNCTION DEV(DEVICE:INTEGER): INTEGER; FUNCTION SEND(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; DATALEN:INTEGER): INTEGER; ritten in Pascal as a Pascal unit. This unit (GPIB.CODE) contains the following higher level functions available to the Pascal or FORTRAN application program: INTERFACE TYPE BUSBUF=PACKED ARRAY [0..0] OF CHAR; FUNCTION IBINIT(SLOT:INTEG INTRODUCTION The software to support the IEEE-488 card from Pascal and FORTRAN takes the form of an application note; source listings, informal documentation (no manual) and a diskette. The software consists of two separate parts. One part is w IEEE-488 SOFTWARE DRIVER ROUTINES FOR APPLE II PASCAL/FORTRAN By Jim Trezzo 6/23/82 O^lvto this device driver?:, 0  ^ץ0\ --C%Do you want to attach another driver?-00Xp&L|  B  w- Page 1 GENERAL NOTES ON THE USE OF THE GPIB FUNCTIONS All of the high level functions provided by the unit GPIB are implemented as Pascal functions. These functions all return an integer value, ERR, which is a completion code. The code values corespond to the values returned by the Pascal IORESULT function, with the addition of several GPIB specific codes. 0 No error; normal I/O completion 2 Bad unit number 3 Ilof bytes to by sent out on the bus, or the maximum number of bytes which can be received. In no case should DATALEN be greater than the the number of bytes which the buffer DATABUF can hold. The driver assumes DATALEN is correct and will read or writebyte "n". However when a GPIB function is called, the name "DATA.IBUF" is used for the parameter "DATABUF". The parameter "DATALEN" is an integer whose value represents either the number LEAN OF FALSE: (IBUF:BUSBUF); TRUE: (BUF:PA500); END; The data type BUSBUF is defined in the unit GPIB. To refer to elements of the five hundred byte data buffer, the variable "DATA.BUF[n]" is used for lication program flexibility in allocating the size of the data buffer area. The following example shows how this technique is used: TYPE PA500= PACKED ARRAY [0..499] OF CHAR; VAR DATA:RECORD CASE BOOcharacters. In FORTRAN it is an array of integers, where each element of the array contains two characters (low-byte/high-byte order). Because of the strong type checking of the Pascal language, a special technique is required to allow the Pascal apparameter "DATABUF" is used by both the Send Data and Receive Data functions. DATABUF is the address of the area of memory where data is read from or written to by the driver. In Pascal this buffer is a packed array of := ''; ADDRLST := CONCAT(ADDRLST, CHR(TLKOFF+1), CHR(LSNOFF+11)); where TLKOFF = 64 and LSNOFF = 32 the offset for a secondary address is 96 Page 2 The pt follow a valid Primary address) A Pascal example of an address list containing talker address one and listener address eleven: ADDRLST := 'A+'; or ADDRLST @ to ^ ASCII Character Secondary Address 96 to 126 decimal ` to ~ ASCII Character (All secondary addresses musas follows: Listener Address 32 to 62 decimal SPACE to > ASCII Character Talker Address 64 to 94 decimal Pascal string type. The first character of the string is contained in the high-order byte of the first element. The remaining characters follow in low-byte/high-byte order for the rest of the array. The valid ranges for the instrument addresses are r "ADDRLST". ADDRLST must be a Pascal string data type. Since FORTRAN does not have this data type, an integer array must be used. The first byte of this array (low-order byte of the first element) contains the string length, in order to look like a 131 Count error; invalid numeric value In general, if ERR is not zero, the function was not performed. The functions require anywhere from none to four parameters. The listener and talker addresses are determined by the parametelegal operation 128 Command error; invalid command 129 Invalid address list; listener/talker list is not valid for the command being used 130 Driver not initialized to the buffer based on the size given by DATALEN. In the descriptions which follow, some of the bus input/output sequences are shown. The DIO mnemonics for messages as defined by the IEEE-488 standard will be used. Additionally a bar above the sequence will indicate that the ATN message is being sent. When brackets enclose a sequence, this indicates the sequence may or may not occur, depending on the function's parameter values. Page 3 ____________________ ____ MTA [UNL LAD1..LADn] DAB1..DABn [EOS]+EOI idle EOS represents any message termination string. Receive Data: ERR = RCV (ADDRLST, DATABUF, DATALEN, RCVCNT) The Recei are addressed. If the listener list is empty, the data will be sent to currently addressed listeners. ERR will be set to 129 (invalid address list) if talkers or invalid addresses are in ADDRLST. Bus input/output sequence: nator characters). In either mode, when the last character is sent, the End-Or-Identify (EOI) signal will occur. If ADDRLST contains one or more listen addresses, the bus will be cleared of all current listeners (by an unlisten) before the new ones, or ERR will be set to 131 (count error) and the function will not be performed. If message terminator mode is enabled, the termination string will be appended to the data stream (total bytes sent equals the value of DATALEN plus the number of termiThis function will send data from the Apple to one or more listening devices on the bus. The data will be read from the array DATABUF by the driver. DATALEN specifies the number of data bytes to be read from DATABUF. DATALEN must be greater than zero Page 4 of range, ERR will be set to 131 (count error). TALKER/LISTENER FUNCTIONS Send Data: ERR = SEND (ADDRLST, DATABUF, DATALEN) e device number will be set to zero by the IBINIT function. The device number is used when my talk address (MTA) or my listen address (MLA) is being sent on the bus. The valid range for DEVICE is from zero to thirty decimal. If DEVICE is out ng during the receive data function will signal the end of the data stream. Set Controller Device Number: ERR = DEV (DEVICE) The DEV function will set the device number of the Apple controller. The normal or default device number is zero. ThWhen message termination mode is enabled, a send data function will automatically append the termination string (one or two characters) onto the end of the data stream, with the EOI message sent on the last character. Detection of the termination striis greater than two, ERR will be set to 131 (count error) and the function will not be performed. If ADDRLST is length zero, the mode will be disabled. When the device driver is initialized, message terminator mode is disabled. ssage terminator mode will be set. The first character of the string will be the first terminating character. If the string contains a second character, it will be the second terminating character. Any character is valid. IF the length of ADDRLST if SLOT is out of range. After initialization, the ATN message will be sent. Set Message Terminator: ERR = EOS (ADDRLST) The EOS function can be used to enable message terminator mode. When ADDRLST contains a one or two character string, meII IEEE-488 Interface Card must be initialized by this routine. SLOT, an integer, must be the correct slot number which the interface card is installed in. The valid range of values for SLOT is one to seven. ERR will have the value 131 (count error) GPIB FUNCTION DESCRIPTIONS DRIVER COMMAND FUNCTIONS Initialize: ERR = IBINIT (SLOT) Before any of the GPIB functions can be used, the device driver and the Apple ve Data function loads the incoming data stream from a talker into the array DATABUF. ADDRLST must contain one valid talker address. If it does not, ERR will be set to 129 (invalid address list) and the function will not be performed. DATALEN, which specifies the capacity of the buffer DATABUF, must be greater than zero. ERR will be set to 131 (count error) if it is not. The integer parameter RCVCNT will be equal to the number of bytes received. The function will terminate when one of the folloinformation bits. The low-order byte of RESULT will contain the byte received from the serial poll. Bit 7 of this byte (corresponds to 64 decimal if set) will be set if the instrument is issuing a service request. Bit 8 and bits 1-6 may contain devic an instrument to obtain its Status Byte. Upon successful completion, the integer parameter RESULT will contain both an indication whether the device is requesting service and some device specific (invalid address list) if talkers or invalid addresses are in ADDRLST. Bus input/output sequence: _________________________ [UNL LAD1..LADn] SDC idle Serial Poll: ERR = SPL (ADDRLST, RESULT) Used to perform a Serial Poll of one or more listen addresses, the bus will be cleared of all current listeners (by an unlisten) before the new ones are addressed. If the listener list is empty, the SDC message will be sent to currently addressed listeners. ERR will be set to 129 operation manual. Bus input/output sequence: ________ DCL idle Selected Device Clear: ERR = SDCL (ADDRLST) Similar to Device Clear except that only the instruments which are listeners will be cleared. If ADDRLST contains idle Page 6 Device Clear: ERR = DCL All instruments on the bus will be cleared by this function. Each instrument will go to a predefined state which should be described in the instruments he GET message will be sent to currently addressed listeners. ERR will be set to 129 (invalid address list) if talkers or invalid addresses are in ADDRLST. Bus input/output sequence: _________________________ [UNL LAD1..LADn] GETific ( not all instruments can respond to group execute trigger). If ADDRLST contains one or more listen addresses, the bus will be cleared of all current listeners (by an unlisten) before the new ones are addressed. If the listener list is empty, t [UNL] TAD [LAD1..LADn] DAB1..DABn+EOI idle CONTROLLER FUNCTIONS Group Execute Trigger: ERR = GETR (ADDRLST) This function simultaneously triggers the functions of all instruments addressed as listeners. The response is instrument specst, the data will be transfered to currently addressed listeners. ERR will be set to 129 (invalid address list) if no talker or invalid addresses are in ADDRLST. Bus input/output sequence: ______________________ ____ OI. The address list ADDRLST must contain one talker address. If ADDRLST contains one or more listen addresses, the bus will be cleared of all current listeners (by an unlisten) before the new ones are addressed. If their are no listeners in the li move data from a talker to one or more listeners, where the bus controller (Apple) does not participate in the data transfer. The function will only terminate when the EOI signal is sent by the talker. XFER cannot be used if the talker doesn't send E The number of bytes received equals DATALEN. Bus input/output sequence: ___________ ____ TAD UNL MLA DAB1..DABn [EOS]+EOI idle Transfer Data: ERR = XFER (ADDRLST) The Transfer function is used towing conditions occur: The EOI signal from the talker. A termination string is received (only if message termination Page 5 mode is enabled). e specific information. ADDRLST must contain the talk address of the instrument being polled. ERR will be set to 129 (invalid address list) if listeners or invalid addresses are in ADDRLST. Bus input/output sequence: _______________ ________ SPE TAD UNL MLA status byte SPD idle Page 7 Service Requested: ERR = SRQ (RESULT) This function is used to determine if any device on the GPIB is requesting service. Onspecified. Devices will not go into remote mode until they are addressed to listen, either now or by a subsequent command. The Remote Enable line will remain true. ADDRLST may contain one or more listener addresses or may be empty. ERR will be set Page 9 SYSTEM CONTROLLER FUNCTIONS Remote Enable: ERR = REN (ADDRLST) This function asserts the Remote Enable line. A list of addresses may be . Bus input/output sequence: ________ UNT idle Unlisten: ERR = UNL All current listeners on the bus will be unaddressed (deactivated). Bus input/output sequence: ________ UNL idle ERR = PPU This function causes all instruments to be unconfigured for parallel poll response. Bus input/output sequence: ________ PPU idle Untalk: ERR = UNT The current talker on the bus is unaddressed (deactivated)ADDRLST must contain the listener address of the instrument which will be disabled or ERR will be set to 129 (invalid address list). Bus input/output sequence: _____________________ UNL LADn PPC PPD idle Parallel Poll Unconfigure:PC PPE|sppp idle Parallel Poll Disable: ERR = PPD (ADDRLST) This function selectively disables one instrument, specified in ADDRLST, from responding to a parallel poll. ee parallel poll) is assigned to this instrument. Bits 8 through 5 and the high-order byte are ignored. Page 8 Bus input/output sequence: __________________________ UNL LADn Pllows: x x x x S P3 P2 P1 Bit 4, "S", assigns the sense of the listener's poll bit (whether the instrument will signal a request for service with a 1 or a 0. Bits 3 through 1, "P3", "P2" and "P1", determine which bit of the status byte (sThe integer parameter ENABLE contains four bits (the four least significant bits of the low-order byte) which are used to determine the bit number and bit sense assigned to the instrument for use during a parallel poll. The low-order byte is used as fofunction assigns a bit number and a bit sense to each remote device to be enabled. ADDRLST must contain the listener address of the one instrument which will be configured for a parallel poll or ERR will be set to 129 (invalid address list). order byte of RESULT will contain the byte received from the parallel poll. Parallel Poll Enable: ERR = PPE (ADDRLST, ENABLE) For instruments which are able to respond to a parallel poll and can be configured with a Parallel Poll Enable, this t is either set or clear to indicate a single piece of information about an instrument's status. Each of the eight bits may be assigned to a device using the Parallel Poll Enable function for some devices, or by a DIP switch on other devices. The low-The integer parameter RESULT will have the value one if SRQ is true, and zero if SRQ is false. Parallel Poll: ERR = PPL (RESULT) A parallel poll is conducted on the bus and an eight bit status byte is returned by this function. Each status bie or more instruments may assert the service request signal (SRQ) simultaneously. A serial poll would normally be performed after a service request has been detected by this function. to 129 (invalid address list) if talkers or invalid addresses are in ADDRLST. The unlisten (UNL) message will not be sent by this function. Bus input/output sequence: ____________________________ [LAD1..LADn] idle Local: ERR = LCL (ADDRLST) If listener addresses are specified with this function, the Go to Local command will be sent. All addressed instruments will now accept front panel (local) commands. If listener addresses are not specified, the Remote byte 0 control code 2 Selected Device Clear - Used by SDCL. The format of "data" is as follows: byte 0 control code 3 byte 1 length of address list PagGETR. The format of "data" is as follows: byte 0 control code 1 byte 1 length of address list byte 2 - n address list Device Clear - Used by DCL. The format of "data" is as follows: trol functions: Transfer Data - Used by XFER. The format of "data" is as follows: byte 0 control code 0 byte 1 length of address list byte 2 - n address list Group Execute Trigger - Used by is a variable reference. The variable is an array of bytes, with the first byte containing a control or status code which determines the function. The meaning of the remaining bytes is function dependent. The following functions are in I488: ConUNITSTATUS(unitnum, data, option): This procedure provides a set of control and status functions. If the parameter "option" has the value two, a control function will be called. The value zero will specify a status function. The parameter "data" complete a single function. UNITCLEAR(unitnum): This procedure is only used by the function IBINIT. The parameter "unitnum" must be 128, as in all of the procedures which follow. This procedure only clears the slot number variable in I488. 488 functions, the files I488.TEXT, I488A.TEXT and I488B.TEXT should be listed and studied. Access to I488 is provided by the UNITCLEAR, UNITSTATUS, UNITREAD and UNITWRITE Pascal procedures. Each GPIB function may call one or more I488 procedure to the I488 functions, it is not necessary to deal with I488 directly. You only need to read the descriptions which follow if you intend to modify GPIB or I488. A listing of GPIB.TEXT will show how the I488 functions are used. To fully understand the IThe IFC message will be sent for about 5 msec (standard requires > 100 usec). Page 11 I488 FUNCTION DESCRIPTIONS Since the GPIB functions callf the instrument interfaces to the BUS into a known state. All talker, listener and controller functions go to an idle state. Use this function only under unusual circumstances such as a system hang up or a control conflict. l lockout state is left when the Remote Enable line goes false. Page 10 Bus input/output sequence: ________ LLO idle Abort/Interface Clear: ERR = IFC This function places all o or _______________________ UNL LAD1..LADn GTL idle Local Lockout: ERR = LLO Issuing this function will put all remoted instruments into a state whereby they will not respond to their Local/Reset button. This locaall current listeners (by an unlisten) before the new ones are addressed. ERR will be set to 129 (invalid address list) if talkers or invalid addresses are in ADDRLST. Bus input/output sequence: ________________ idle Enable control line will become false. This will set all devices on the bus to local operating mode. If ADDRLST contains one or more listen addresses, the bus will be cleared of e 12 byte 2 - n address list Parallel Poll Enable - Used by PPE. The format of "data" is as follows: byte 0 control code 4 byte 1 enable byte (sppp) byte 2 length of address list byte 3 - n address list Parallel Poll Disable - Used by PPD. The format of "data" is as follows: byte 0 control code 5 byte 1 length of address list byte 2 - n address Page 14 This procedure is used by RCV (receive data), after UNITSTATUS (control code 14) has been called. The variable reference "data" refers to an array where data bytes will be read into. The value of theVCNT). The format of "data" is as follows: byte 0 status code 3 byte 1-2 returns number of bytes received (low byte/high byte) UNITREAD(unitnum, data, datalen): ws: byte 0 status code 2 byte 1-2 poll result returned (low byte/high byte) Bytes Received - Used by RCV. This function is used after a UNITREAD, to determine how many bytes were read into the data buffer (RCt Service Reqested - Used by SRQ. The format of "data" is as follows: byte 0 status code 1 byte 1-2 result returned (low byte/high byte) Parallel Poll - Used by PPL. The format of "data" is as folloSerial Poll - Used by SPL. The format of "data" is as follows: byte 0 status code 0 byte 1-2 poll result returned (low byte/high byte) byte 3 length of address list byte 4 - n address lis of "data" is as follows: byte 0 control code 17 byte 1 length of slot number list (must be 1) byte 2 slot number Status functions: mber - Used by DEV. The format of "data" is as follows: byte 0 control code 16 byte 1 length of device number list (must be 1) byte 2 device number Initialize - Used by IBINIT. The format Set Message Terminator - Used by EOS. The format of "data" is as follows: byte 0 control code 15 byte 1 length of terminator list (0 to 2) byte 2 - n terminator list Set Controller Device NuReceive Data - Used by RCV. The format of "data" is as follows: Page 13 byte 0 control code 14 byte 1 length of address list byte 2 - n address list Send Data - Used by SEND. The format of "data" is as follows: byte 0 control code 13 byte 1 length of address list byte 2 - n address list Local Lockout - Used by LLO. The format of "data" is as follows: byte 0 control code 11 Abort/Interface Clear - Used by IFC. The format of "data" is as follows: byte 0 control code 12 ength of address list byte 2 - n address list Local - Used by LCL. The format of "data" is as follows: byte 0 control code 10 byte 1 length of address list byte 2 - n address list Unlisten - Used by UNL. The format of "data" is as follows: byte 0 control code 8 Remote Enable - Used by REN. The format of "data" is as follows: byte 0 control code 9 byte 1 l list Parallel Poll Unconfigure - Used by PPU. The format of "data" is as follows: byte 0 control code 6 Untalk - Used by UNT. The format of "data" is as follows: byte 0 control code 7 parameter "datalen" specifies the maximum number of bytes "data" can hold. UNITWRITE(unitnum, data, datalen,,12): This procedure is used by SEND (send data), after UNITSTATUS (control code 13) has been called. The variable reference "data" refers to an array where data bytes will be read from. The value of the parameter "datalen" specifies the number of bytes to be transfered out of "data". Page 15 IERR=SEND(ADRLST, DATABF, DATALN) C RECEIVE DATA IERR=RCV(TLKLST, DATABF, DATALN, RCVCNT) WRITE(*,1100)RCVCNT DO 20 I=1,(RCVCNT+1)/2 I1=I*2-1 C SEND DEVICE CLEAR IERR=DCL() C SEND REMOTE ENABLE IERR=REN(ADRLST) C SEND DATA 10 DATABF(I)=ICHAR(D(I1))+ICHAR(D(I2))*256 WRITE(*,1000) C INITILIZE GPIB DRIVER IERR=IBINIT(ISLOT) C SEND INTERFACE CLEAR IERR=IFC() C FORM ADDRESS LIST ADRLST(1)=ALSTLN+ICHAR(A(1))*256 ADRLST(2)=ICHAR(A(2)) C FORM DATA BUFFER DO 10 I=1,(DATALN+1)/2 I1=I*2-1 I2=I*2 DATA A/'!','"'/ DATA D/'1','2','3','4','5','6','7','8','9','0'/ ALSTLN=2 DATALN=10 ISLOT=1 C TAD1 TLKLST=1+ICHAR('A')*256 C FORTRAN PROGRAM TO CALL PASCAL GPIB ROUTINE INTEGER DATALN, ADRLST(128), DATABF(500), TLKLST, RCVCNT CHARACTER A(2), D(10) C LAD1 AND LAD2 E, and can be executed as is. Page 17 A FORTRAN EXAMPLE $USES GPIB IN GPIB.CODE PROGRAM FGPIB hich calls the GPIB.CODE functions. It is a good idea to list this program and study how GPIB.CODE is used. IGPIB is also handy for experimenting with instruments before any program has been written. IGPIB.CODE has already been linked with GPIB.COD Page 16 INTERACTIVE GPIB EXERCISER Included on the diskette is a program called IGPIB. This is a simple GPIB excerciser written in Pascal and is useful as an example Pascal program w I488 Unit number: 128 Initialized at boot time: No Another unit number: No Start on a byte boundary: No Attach another driver: No DOC.TEXT - This document When ATTACHUD.CODE is run, give the following answers to the questions: Name of data file: ATTACH.DATA Questions on hires page: No Name of driver:CODE) Transfer to boot disk SYSTEM.ATTACH - Transfer to boot disk ATTACHUD.CODE - Run this program to create ATTACH.DATA and transfer ATTACH.DATA to boot disk GPIB.TEXT - Pascal unit source and code files GPIB.CODE IGPIB.TEXT - Interactive GPIB exerciser IGPIB.CODE source file and linked code file ATTACH.DRIVERS - Contains the driver code file (I488. NOTES ON INSTALLING THE APPLE II IEEE-488 DRIVER The supplied diskette contains the following files: I488.TEXT - I488 driver source code I488A.TEXT I488B.TEXT I2=I*2 D(I1)=CHAR(MOD(DATABF(I),256)) 20 D(I2)=CHAR(DATABF(I)/256) WRITE(*,1200) (D(I), I=1,RCVCNT) Page 18 1000 FORMAT('BEGIN FORTRAN TEST PROGRAM') 1100 FORMAT(I6,' BYTES RECEIVED') 1200 FORMAT(10A) END Page 19 DADDRBUF[1]:=CHR(13); DADDRBUF[2]:=CHR(10) BEND (ELSE INPUT[1]:='X'; &IF INPUT[1]<>'X' THEN BEGIN >ERR:= EOS(ADDRBUF); >IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR EOS') , 2 FOR :'); $READLN(INPUT); $IF LENGTH(INPUT)=1 THEN &BEGIN &IF INPUT[1]='0' THEN ADDRBUF:='' (ELSE IF INPUT[1]='1' THEN BEGIN C ADDRBUF:=' '; DADDRBUF[1]:=CHR(13) BEND (ELSE IF INPUT[1]='2' THEN BEGIN DADDRBUF:=' '; ; "BEGIN $ERR:= LLO; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR LLO') "END;   PROCEDURE IIFC; "BEGIN $ERR:= IFC; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR IFC') "END;   PROCEDURE IEOS; "BEGIN WRITE('ENTER; 0 FOR NO TERMINATOR, 1 FOR   PROCEDURE IREN; "BEGIN $GTADR; $ERR:= REN(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR REN') "END;   PROCEDURE ILCL; "BEGIN $GTADR; $ERR:= LCL(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR LCL') "END;   PROCEDURE ILLO$IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPU') "END;   PROCEDURE IUNT; "BEGIN $ERR:= UNT; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR UNT') "END;   PROCEDURE IUNL; "BEGIN $ERR:= UNL; $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR UNL') "END;F ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPE') "END;   PROCEDURE IPPD; "BEGIN $GTADR; $ERR:= PPD(ADDRBUF); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPD') "END;   PROCEDURE IPPU; "BEGIN $ERR:= PPU; ENTER ENABLE BYTE VALUE: (0-15)'); $READLN(INPUT); $IF LENGTH(INPUT)=2 (THEN ENABLE:=(ORD(INPUT[1])-ORD('0'))*10 + ORD(INPUT[2])-ORD('0') (ELSE IF LENGTH(INPUT)=1 THEN ENABLE:=ORD(INPUT[1])-ORD('0'); $IF ENABLE<>-1 THEN ERR:= PPE(ADDRBUF, ENABLE); $IRESULT (decimal) = ',I) "END;   PROCEDURE IPPL; "BEGIN $ERR:= PPL(I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR PPL'); $WRITELN('PARALLEL POLL RESULT (decimal) = ',I) "END;   PROCEDURE IPPE; "BEGIN $GTADR; $ENABLE:=-1; $ERR:=0; $WRITE('$ERR:= SPL(ADDRBUF, I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR SPL'); $WRITELN('SERIAL POLL RESULT (decimal) = ',I) "END;   PROCEDURE ISRQ; "BEGIN $ERR:= SRQ(I); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR SRQ'); $WRITELN('SERVICE REQUESTED nual, Sept. 1979 Page 20 Apple II Apple FORTRAN Language Reference Manual, 1980 ATTACH-BIOS document for Apple II Pascal 1.1, Jan 12, 1981 IEEE Standard 488-1978, "Digital Interface for Programmable Instrumentation" Texas Instruments TMS 9914 GPIB Adapter Preliminary Data Ma REFERENCES Apple II IEEE-488 Interface User's Guide, 1981 Apple II Apple Pascal Language Reference Manual, 1980 Apple II Apple Pascal Operating System Reference Manual, 1980 'ENTER CONTROLLER DEVICE NUMBER: (0-30)'); $READLN(INPUT); $IF LENGTH(INPUT)=2 (THEN DEVICE:=(ORD(INPUT[1])-ORD('0'))*10 + ORD(INPUT[2])-ORD('0') (ELSE IF LENGTH(INPUT)=1 THEN DEVICE:=ORD(INPUT[1])-ORD('0'); $IF DEVICE<>-1 THEN ERR:= DEV(DEVICE); $IF ERR<>0 THEN WRITELN('ERR = ',ERR,' FOR DEV') "END;  PROCEDURE SLTINIT; "BEGIN $WRITELN('ENTER SLOT NUMBER OF IEEE-488 CARD'); $WRITE('(1-7) :'); $READLN(INPUT); ${$R-} $SLOT:=ORD(INPUT[1])-ORD('0'); ${$R+} $ERR:= IBINIT(SLOT); $IF ERR<>0 THEN á 0 0  á 0 ˡ  ˡ8צERR =  צ FOR PPE ˡ8צERR =  צ FOR PPDR ˡ8Eimal) =   ˡ8ERR =   FOR PPL!PARALLEL POLL RESULT (decimal) =    צENTER ENABLE BYTE VALUE: (0-15) R ˡ8צERR =  צ FOR SPLצSERIAL POLL RESULT (decimal) =   ˡ8ERR =   FOR SRQ%SERVICE REQUESTED RESULT (decRˡ8צERR =  צ FOR GETRˡ8ERR =   FOR DCLL ˡ8צERR =  צ FOR SDCˡ8ERR =   FOR RCV 쿥   DATA BYTES RECEIVED ˡ8צERR =  צ FOR XFR SPL SRQ PPL PPE PPD PPU DEV# UNT UNL REN LCL LLO IFC INIצ ENTER "X" TO EXITˡ9צERR =  צ FOR SENDXENTER LIST OF ADDRESSES: PBENTER LIST OF DATA:    PAVAILABLE FUNCTIONS:# SND RCV XFR GET DCL SDC EOSצ# BBBBBBBBBBBBBBBB IGPIB GPIB 19:IEOS; 20:IDEV; *21:SLTINIT (END &END $UNTIL COMNUM=LASTCOM-1  END. F *0,LASTCOM:HELP; *1:ISND; 10:IRCV; *2:IXFR; 11:IPPD; *3:IGET; 12:IPPU; *4:IDCL; 13:IUNT; *5:ISDC; 14:IUNL; *6:ISPL; 15:IREN; *7:ISRQ; 16:ILCL; *8:IPPL; 17:ILLO; *9:IPPE; 18:IIFC; *&WRITE('ENTER DESIRED FUNCTION (? - HELP): '); &READLN(INPUT); &FOR I:= LENGTH(INPUT)+1 TO 3 DO INPUT:=CONCAT(INPUT,' '); &COMMANDS[LASTCOM]:=COPY(INPUT,1,3); &COMNUM:=0; &WHILE COMMANDS[COMNUM]<>COPY(INPUT,1,3) (DO COMNUM:=COMNUM+1; *CASE COMNUM O WRITELN('ERR = ',ERR,' FOR IBINIT') "END;   BEGIN "SDATA:= '? SNDXFRGETDCLSDCSPLSRQPPLPPERCVPPDPPUUNTUNLRENLCLLLOIFCEOSDEVINIX '; "FOR COMNUM:=0 TO LASTCOM DO COMMANDS[COMNUM]:=COPY(SDATA,COMNUM*3+1,3); "SLTINIT; "REPEAT $BEGIN &WRITELN; RR =   FOR PPUL ˡ8ERR =   FOR UNTL ˡ8ERR =   FOR UNLLˡ8צERR =  צ FOR RENRˡ8צERR =  צ FOR LCLRˡ8ERR =   FOR LLOLˡ8ERR =  N PPD(VAR ADDRLST:STRING): INTEGER; "FUNCTION PPU: INTEGER; "FUNCTION UNT: INTEGER; "FUNCTION UNL: INTEGER; "FUNCTION REN(VAR ADDRLST:STRING): INTEGER; "FUNCTION LCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION LLO: INTEGER; "FUNCTION IFC: INTEGER; "FUNVCNT:INTEGER): INTEGER; "FUNCTION SDCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION XFER(VAR ADDRLST:STRING): INTEGER; "FUNCTION GET(VAR ADDRLST:STRING): INTEGER; "FUNCTION DCL: INTEGER; "FUNCTION PPE(VAR ADDRLST:STRING; ENABLE:INTEGER): INTEGER; "FUNCTIO "TYPE $BUSBUF=PACKED ARRAY [0..0] OF CHAR; " "FUNCTION IBINIT(SLOT:INTEGER): INTEGER; "FUNCTION SEND(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; 0DATALEN:INTEGER): INTEGER; "FUNCTION RCV(VAR ADDRLST:STRING; VAR DATABUF:BUSBUF; DATALEN:INTEGER; /VAR RCBBBBBBBBBBBBBBBB GPIB c ccX{ws ok gc _[ WS OKGC?;70_]WQKE?93-ke_YSMGA;975.á u!npADDRBUF DATALEN COMNUM COMMANDSDATA ENABLE  DEVICE ERR I LASTCOM INPUT  SDATA SLOT SOUT  EE cc ccX{ws ok gc _[ WS OKGC?;70_]WQKE?93-ke_YSMGA;975.á u!nplFr  ` b ~ 2SDEVINIX c멂cȡ$ddצ#ENTER DESIRED FUNCTION (? - HELP):   cꩂcȡ, dd dצ d cc ccX{ws ok gc _[ WS OKGC?;70_]WQKE?93-ke_YSMGA;975.á u!npPPERCVPPDPPUUNTUNLRENLCLLLOIFCEOSDEVINIX c멂cȡ$ddצ#ENTER DESIRED FUNCTION (? - HELP):   cꩂcȡ, dd dצ d cDEV"ENTER SLOT NUMBER OF IEEE-488 CARD(1-7) :  0ˡ;צERR =  צ FOR IBINITצH? SNDXFRGETDCLSDCSPLSRQPPLERR =   FOR EOSצ&ENTER CONTROLLER DEVICE NUMBER: (0-30)  á 0 0 á 0ˡˡ8צERR =  צ FOR  FOR IFCL8ENTER; 0 FOR NO TERMINATOR, 1 FOR , 2 FOR :  á 0á צPD 1á P + 2á תP   X XˡGˡ8CTION EOS(VAR ADDRLST:STRING): INTEGER; "FUNCTION DEV(DEVICE:INTEGER): INTEGER; "FUNCTION SPL(VAR ADDRLST:STRING; VAR RESULT:INTEGER): INTEGER; :--)PBBINT"FUNCTION SRQ(VAR RESULT:INTEGER): INTEGER; "FUNCTION PPL(VAR RESULT:INTEGER): INTEGER;  IMPLEMENTATION E TION REN(VAR ADDRLST:STRING): INTEGER; "FUNCTION LCL(VAR ADDRLST:STRING): INTEGER; "FUNCTION LLO: INTEGER; "FUNCTION IFC: INTEGER; "FUN @L  o?  0  ) ȩ  L)JJȩLȑȩL.ȭ/L )L HH`L9g 7m./ L)LEEv  L` ,*" ,*p+L+ ,LHh   Lhhhh$L)L HH`Lrhh HH`LOO0)L`hhhhhhhhhhL))L./-EEL )()H,* ,- ,9-+ ,*P(-./LGXI488 h^|LEN IRTMPSTR )NTb EE4ڥڥתP >\>^|2PBUF  ";N\iv#CODE ,8HZd<?X[vy &)\_z}ERR  +e%CN]mEc/IgINUL  ) šǃ Pڿ4ڥڥתP >\>^|2Pp6Vt 4ǀ "F         šǃ Pڿ4ڥڥתP >\>^|2Pڿǀ "F         áǃá 0áǃáá ڥ Dٿǀ "6ڿǀ "٥Pǀ"ǀ"ǀ&"á Pڿ8CTION EOS(VAR ADDRLST:STRING): INTEGER; "FUNCTION DEV(DEVICE:INTEGER): INTEGER; "FUNCTION SPL(VAR ADDRLST:STRING; VAR RESULT:INTEGER): INTEGER; :--)PBBINT_?U ȱ F?  ) &@1_ $p)$`% м%` ȩ$?   `` $0pL o )  L $0PL o L L $0PL o L L o ) ` L L o p L $0PL oL $0pL o LL 9L $0PL@ 0pPMJEB?:&#"}zuljeeeeebYSPJGC,& ~{roicb_VJIF74  oL @L o?  0 L*,**+LL*L)0LLL i)*+,0 LHH`)` L L $0PL o L L o ) ` L L o p L $0PL oL $0pL o LL 9L $0PL@ 0_?U ȱ F?  ) &@1_ $p)$`% м%` ȩ$?   `` $0pL o )  L $0PL o @L  o?  0  ) ȩ  L)JJȩLȑȩL.ȭ/L )L HH`L9g 7m./ L)LEEv  L` ,*" ,*p+L+ ,LHh   Lhhhh$L)L HH`Lrhh HH`LOO0)L`hhhhhhhhhhL))L./-EEL )()H,* ,- ,9-+ ,*P(-./LGA3/1.0DDX I488 I488 I488  .-'&    ~sP м%` ȩ$?   `` $0pL o )  L $0PL opPMJEB?:&#"}zuljeeeeebYSPJGC,& ~{roicb_VJIF74  oL @L o?  0 L*,**+LL*L)0LLL i)*+,0 LHH`)`.-'&    ~sP м%` ȩ$?   `` $0pL o )  L $0PL oI488 I488  R ˡ8צERR =  צ FOR PPDR ˡ8ERR =   FOR PPUL ˡ8ERR =   FOR UNT) =   ˡ8ERR =   FOR PPL!PARALLEL POLL RESULT (decimal) =    ˡ8צERR =  צ FOR PPEˡ8צERR =  צ FOR SPLצSERIAL POLL RESULT (decimal) =   ˡ8ERR =   FOR SRQ%SERVICE REQUESTED RESULT (decimalRˡ8צERR =  צ FOR GETRˡ8ERR =   FOR DCLL ˡ8צERR =  צ FOR SDCR ˡ8ERR =   FOR RCV 쿥   DATA BYTES RECEIVED ˡ8צERR =  צ FOR XFR SPL SRQ PPL PPE PPD PPU DEV UNT UNL REN LCL LLO IFC ENTER "X" TO EXITˡ9צERR =  צ FOR SENDXENTER LIST OF ADDRESSES: PBENTER LIST OF DATA:    PAVAILABLE FUNCTIONS:# SND RCV XFR GET DCL SDC EOSצ# š Pڿ㩂㥃2㩂㩂ڥ㩂ڥתP (z>^|0Nn&Dd4 㩂 㩂㥂 㩂㥂 㩂㥂  㩂 㩂 㩂㥂 㩂㥂㩂áá .áá㩂á ڥ B㩂㩂㩂㥂㩂㩂 ٿ̀ʀǀ "2ڿ̀ʀǀ "Lǀ"ǀ"ǀ&"䩂á Pڿ㩂㥃8 BB IGPIB GPIB L ˡ8ERR =   FOR UNLLˡ8צERR =  צ FOR RENRˡ8צERR =  צ FOR LCLRˡ8ERR =   FOR LLOLˡ8ERR =   FOR IFCL8ENTER; 0 FOR NO TERMINATOR, 1 FOR , 2 FOR : R ˡ8צERR =  צ FOR PPDR ˡ8ERR =   FOR PPUL ˡ8ERR =   FOR UNTimal) =   ˡ8ERR =   FOR PPL!PARALLEL POLL RESULT (decimal) =    ˡ8צERR =  צ FOR PPER ˡ8צERR =  צ FOR SPLצSERIAL POLL RESULT (decimal) =   ˡ8ERR =   FOR SRQ%SERVICE REQUESTED RESULT (decRˡ8צERR =  צ FOR GETRˡ8ERR =   FOR DCLL ˡ8צERR =  צ FOR SDCˡ8ERR =   FOR RCV 쿥   DATA BYTES RECEIVED ˡ8צERR =  צ FOR XFR SPL SRQ PPL PPE PPD PPU DEV# UNT UNL REN LCL LLO IFC INIצ ENTER "X" TO EXITˡ9צERR =  צ FOR SENDXENTER LIST OF ADDRESSES: PBENTER LIST OF DATA:    PAVAILABLE FUNCTIONS:# SND RCV XFR GET DCL SDC EOSצ# BB IGPIB GPIB 70_]WQKE?93-ke_YSMGA;975.á w!hnplX 0 P 2SDEVINIX b멂bȡ$ccצ#ENTER DESIRED FUNCTION (? - HELP):   bꩂbȡ, cc cצ c bb bbX{ws ok gc _[ WS OKGC?;ˡ;צERR =  צ FOR IBINITצH? SNDXFRGETDCLSDCSPLSRQPPLPPERCVPPDPPUUNTUNLRENLCLLLOIFCEOSDEVINIX b멂bȡ$ccצ#ENTER DESIRED FUNCTIO á 0 0 á 0ˡˡ8צERR =  צ FOR DEV"ENTER SLOT NUMBER OF IEEE-488 CARD(1-7) :  0 á 0á צPD 1á P + 2á תP   X XˡGˡ8ERR =   FOR EOSצ&ENTER CONTROLLER DEVICE NUMBER: (0-30) L ˡ8ERR =   FOR UNLLˡ8צERR =  צ FOR RENRˡ8צERR =  צ FOR LCLRˡ8ERR =   FOR LLOLˡ8ERR =   FOR IFCL8ENTER; 0 FOR NO TERMINATOR, 1 FOR , 2 FOR : ;70_]WQKE?93-ke_YSMGA;975.á u!nplX 0 T 2SDEVINIX b멂bȡ$ccצ#ENTER DESIRED FUNADDRBUF DATALEN COMNUM COMMANDSDATA DEVICE ERR I LASTCOM INPUT  SDATA SLOT SOUT  o [ WS OKGC?;70_]WQKE?93-ke_YSMGA;975.á u!nplX 0 T 2SDEVINIX b멂bȡ$ccצ#ENTER DESIRED FUNCTION (? - HELP):   bꩂbȡ, cc cצ c bb bbX{ws ok gc _[ WS OKGC?0ˡ;צERR =  צ FOR IBINITצH? SNDXFRGETDCLSDCSPLSRQPPLPPERCVPPDPPUUNTUNLRENLCLLLOIFCEOSDEVINIX b멂bȡ$ccצ#ENTER DESIRED FUN  á 0 0 á 0ˡˡ8צERR =  צ FOR DEV"ENTER SLOT NUMBER OF IEEE-488 CARD(1-7) :   á 0á צPD 1á P + 2á תP   X XˡGˡ8ERR =   FOR EOSצ&ENTER CONTROLLER DEVICE NUMBER: (0-30)