TITLE TABCDP - Routines to drive the TAB Products Cardpunch Terminal SUBTTL Joe Smith, CSM, 29-Jun-83 SEARCH MACTEN,UUOSYM SALL ENTRY TABINI ;Initialize punch ENTRY TABBYT ;Put a 12-bit byte into buffer ENTRY TABPUN ;Punch the card ENTRY TABFIN ;Finish up routine EXTERN TTYIN,TIWAIT,TRMERR ;Input routines in SPROUT ;AC Definitions ;*; TF=0 ;TRUE/FALSE S1=1 ;Temp S2=2 ;(not preserved) T1=3 ;Less temp T2=4 ; T3=5 ; T4=6 ; ;*; J=14 ;Base reg ;*; C=15 ;I/O character P=17 ;Stack Pointer ; Table of Contents for TAB Products Card Puncher ; ; ; Section Page ; ; 1. Interface to SPROUT - TABINI, TABBYT, TABPUN . . . . . 2 ; 2. Definitions for Punch Terminal . . . . . . . . . . . . 2 ; 3. SNDPUN - Send buffer to punch . . . . . . . . . . . . 4 ; 4. TTYINI - Initialize terminal . . . . . . . . . . . . . 5 ; 5. Data area . . . . . . . . . . . . . . . . . . . . . . 6 SUBTTL Interface to SPROUT - TABINI, TABBYT, TABPUN ;Routine to initialize the terminal. ;S1 zero to print as well as punch, RH of S2 has TTY UDX. TABINI::MOVEM S1,NOPRIN ;Nonzero to not print HRRZM S2,TTYUDX ;Save terminal number PUSHJ P,TTYINI ;Set terminal characteristics PJRST TABCLR ;Clear the bed and return ;Routine to put 12-bit byte into the buffer ;Byte in S1, uses S2 TABBYT::ANDI S1,7777 ;Clear junk IDIVI S1,100 ;Split 12-bit byte in half TRO S1,100 ;Make into printing ASCII char IDPB S1,PUNPNT ;Put in buffer TRO S2,100 ;Make into ASCII IDPB S2,PUNPNT ;Put in buffer POPJ P, ;Return ;Routine to output the buffer ;Uses S1-S2, T1-T4 TABPUN::MOVEI S1,CR ;CR forces punch IDPB S1,PUNPNT ;Put in buffer MOVEI S1,0 ;Terminate with IDPB S1,PUNPNT ; ASCIZ MOVE S1,[POINT 7,FEEDCR] ;Code to feed a card PUSHJ P,SNDPUN ;Feed blank card into punching station MOVE S1,[POINT 7,PUNBUF] ;Point to data PUSHJ P,SNDPUN ;Send it MOVE S1,PNTINI ;Reset pointer MOVEM S1,PUNPNT ; to data area POPJ P, ;Routine to finish up TABFIN::PJRST TABCLR ;Clear out any cards SUBTTL Definitions for Punch Terminal ;Codes to activate the TAB-Products Card Reader/Punch NUL== 0 ;Select NO-REMOTE mode SOH== 1 ;Select PUNCH and PRINT same mode STX== 2 ;Select PUNCH and PRINT different mode (nonbinary) ENQ== 5 ;Select PUNCH ONLY mode ACK== 6 ;Positive ACK char from terminal BEL== 7 ;Format code for ASCII transmission (only 7 rows) BS== 10 ;Select READ mode, format code for EBCDIC transmission TAB==11 ;Select READ/PUNCH mode, format code for BINARY data LF== 12 ;Select KEY ENTRY mode, and sent before each CR FF== 14 ;Command to PICK a card from main hopper CR== 15 ;End of command, to/from terminal SO== 16 ;Command to disable automatic feed SI== 17 ;Command to enable automatic card feed DLE==20 ;Command to CLEAR bed DC1==21 ;Command to pick card from AUX hopper DC2==22 ;Command for STATUS request ;Command to select program: 0=DC3,1=DC4,2=FS,3=SYN,4=ETB,5=CAN,6=EM,7=SUB,8=ESC NAK==25 ;Negative ACK, parity error ;NOTE: Because NUL is a command to load binary program data, the Monitor ; must NOT send any extra NULs to the terminal, nor ^Q(DC1) or ^S(DC3). FCLOAD==NUL ;Format code for loading programs FCCOMM==ENQ ;Format code for control commands FCSTAT==STX ;Format code for returned status FCHOLL==LF ;FC to convert record from ASCII to HOLLERITH (12 rows) FCASCI==BEL ;FC to process ASCII data with no conversion (7 rows) FCEBCD==BS ;FC to process EBCDIC data with no conversion (8 rows) FCBINA==TAB ;FC to process BINARY data, 2 bytes per column (12 rows) ;Data to the card punch always starts with a FORMAT CODE and ends with a CR. ;Data read from cards is sent alway received as 80 ASCII bytes, plus LF and CR. ;A binary data record to the terminal consists of 162 bytes. It starts with a ;TAB (FCBINA), has 80 pairs of (+100,+100), ends with a CR. CDPCHR==1+^D<80*2>+1+1 ;Number of chars (including null at end) ;Because the terminal is not INITed in Packed Image Mode, the Monitor will ;append an LF to each CR received from the terminal. A positive response is ;, a negative response is , and a response to ;REQUEST-STATUS (ENQ,DC2,CR) when in PUNCH ONLY mode is . CLRPUN: BYTE (7) FCCOMM,DLE,CR,0 ;Clear Bed FEEDCR: BYTE (7) FCCOMM,FF,CR,0 ;Feed Card SELPM: BYTE (7) FCCOMM,ENQ,CR,0 ;Select Punch Mode (without printing) SELPRT: BYTE (7) FCCOMM,SOH,CR,0 ;Select Punch and Print mode SUBTTL SNDPUN - Send buffer to punch ;Routine to send an ASCIZ string to the card punch terminal and ; wait for an ACK, re-transmitting if necessary. S1 has pointer to ASCIZ SNDPUN: MOVE T4,S1 ;Copy pointer in case of NAK SNDAGN: MOVE S1,T4 ;Point to string PUSHJ P,OUTTTY ;Output string to TTY CAIN S1,ACK ;Did the terminal get it OK? POPJ P, ;Yes PUSHJ P,TTYIN## ;Clear input buffer JUMPN S1,.-1 ;Loop until no more input MOVE S1,[POINT 7,SELPRT] ;Code to select PUNCH & PRINT mode SKIPE NOPRIN ;If not NORMAL forms, MOVE S1,[POINT 7,SELPM] ; punch without printing PUSHJ P,OUTTTY ;In case terminal lost power JRST SNDAGN ;Try again ;Routine to send string pointed to by S1. ;On return, S1 has ACK, NAK, or zero if timed out OUTTTY: MOVX T1,.TOOUS ;OUTSTR function MOVE T2,TTYUDX ;TRMNO. HRRZ T3,S1 ;Addr of data MOVE S1,[3,,T1] ;Point to args TRMOP. S1, ;Send the string PUSHJ P,TRMERR## ;Should never happen ;This response time assumes 120 characters per second (1200 baud) RESPTM==^D<<*1000>/120> ;4 char response MOVX S1,HB.RTL+RESPTM ;Delay before calling TIWAIT HIBER S1, JFCL GETACK: PUSHJ P,TIWAIT## ;Get a byte from the TTY JUMPE S1,CPOPJ ;Return if no response CAIE S1,ACK ;Positive ACK? CAIN S1,NAK ;Negative ACK? SKIPA ;OK JRST GETACK ;Not one of those two PUSH P,S1 ;Save response character PUSHJ P,TTYIN## ;Get the LF from terminal PUSHJ P,TTYIN## ;Get the CR from terminal PUSHJ P,TTYIN## ;Get the LF from monitor POP P,S1 ;Restore response char CPOPJ: POPJ P, SUBTTL TTYINI - Initialize terminal ;Data for TRMOP.s ;*HACK* All this will not be needed when PIM works properly (no extra nulls) TRMTAB: .TOLCT,,0 ;SET TTY LC .TOSND,,0 ;SET TTY GAG .TOBLK,,0 ;SET TTY BLANKS .TOWID,,CDPCHR+8 ;SET TTY WIDTH 171 (include HT char) .TOFRM,,1 ;SET TTY FORM .TONFC,,1 ;SET TTY NO CRLF .TOFLC,,0 ;SET TTY FILL 0 .TOSLV,,1 ;SET TTY SLAVE .TOLCP,,1 ;SET TTY NO ECHO TRMSIZ==.-TRMTAB ;Set TTY characteristics, set to PUNCH or PUNCH+PRINT mode TTYINI: MOVSI S2,-TRMSIZ ;Get number of functions MOVE T2,TTYUDX ;Get terminal number TTYIN1: MOVE S1,[3,,T1] ;Point to args HLRZ T1,TRMTAB(S2) ;Get function code ADDI T1,.TOSET ;Convert to set function HRRZ T3,TRMTAB(S2) ;Get data TRMOP. S1, ;Set the function PUSHJ P,TRMERR## AOBJN S2,TTYIN1 ;Loop for all TTYIN2: MOVX T1,.TOCIB ;Clear input buffer MOVE S1,[2,,T1] ;Point to args TRMOP. S1, ;Do it PUSHJ P,TRMERR## MOVE S1,[POINT 7,SELPRT] ;Code to select PUNCH & PRINT mode SKIPE NOPRIN ;If not NORMAL forms, MOVE S1,[POINT 7,SELPM] ; punch without printing PJRST SNDPUN ;Tell the terminal and return ;Routine to clear all partially processed cards TABCLR: MOVE S1,[POINT 7,CLRPUN] ;Code to clear the punch PUSHJ P,SNDPUN ;Clear all cards out MOVE S1,[POINT 7,PUNBUF] ;Point to the punch buffer MOVEI S2,FCBINA ;Code for binary punching IDPB S2,S1 ;Put code in buffer MOVEM S1,PNTINI ;Save initial pointer MOVEM S1,PUNPNT ;Save data pointer POPJ P, SUBTTL Data area CDPSIZ==/5 ;Number of words DS: PUNBUF: BLOCK CDPSIZ ;Buffer PUNPNT: BLOCK 1 ;Byte pointer to buffer PNTINI: BLOCK 1 ;Initial value of PUNPNT TTYUDX: BLOCK 1 ;UDX of terminal NOPRIN: BLOCK 1 ;Nonzero unless /FORMS:NORMAL DE: TABC..==:J$$END##+ LITS: END