Trailing-Edge
-
PDP-10 Archives
-
BB-D351C-SM_3-16-83
-
sources/xl3780.p11
There are 16 other files named xl3780.p11 in the archive. Click here to see a list.
.SBTTL XL3780 - translate task for 2780/3780 lines
; this section contains the translate task
; and the tables used by the translate (xlate) task
; to convert between ascii and ebcdic, and to simulate
; a printer carriage control tape.
.REPT 0
COPYRIGHT (c) 1982,1981,1980, 1979
DIGITAL EQUIPMENT CORPORATION, maynard, mass.
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.
DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
.ENDR
;REVISION HISTORY
; 3(001) BS PAD CARDS TO 80. CHARACTERS WHEN IRS RECEIVED IN 3780 MODE
;
; 3(002) BS REMOVE EBCDIC TO ASCII TRANSLATION TABLES FOR USE WITH TRNTAB
;
; 3(003) BS RESET CDR TCHPS TO 0 FOR 2780/3780 SUPPORT AFTER 80 CHARACTERS
;
; 3(004) BS ALLOW TASK TO PROCESS ONLY ONE MESSAGE AT A TIME
;
; 3(005) BS SIGNAL INPUT EOF ONLY AFTER LAST MESSAGE SENT TO PDP-10
;
; 3(006) RLS NEW STORAGE MGT CHANGES
;
; 3(007) RLS SET DEVICE ACTIVE BIT WHEN TCIEC SET SINCE ACTION BY TEN
; REQUIRED TO CLEAR IT.
;
; 3(010) RLS ADD HSPIGO PARAMETER USE IN XLEBAS TO CONTROL REPETITIVE
; TRANSLATION OF INPUT BLOCKS WITHOUT SLEEPING.
; 3(011) RLS REDUCE WAIT AFTER PERMISSION GRANT IN XLWAIT.DON'T CLEAR TCIRN
; UNTIL TCIEC CLEARED IN XLEBAS.
;
; 3(012) RLS REMOVE HSPIGO. ADD MORE GLOBAL FLOW CONTROL.
; 3(013) RLS 6-Mar-81
; Create common end of message fucntion XLSNDE to be used
; by XLSNDM and XLEOFO.
; Makes XLEOFO increment LB.MSC when queuing EOF msg also.
; 3(014) RLS 9-MAR-81
; Make XLOABT and XLIABT check for LS.ENB clear so they won't
; wait in vain for the 10 to clear abort complete bits
; 3(015) RLS 07-APR-81
; Changes to reflect use of message header to store data.
; 3(016) RLS 17-APR-81
; Transform static flow control to static/line control
; 4(017) RLS 17-MAR-82 GCO 4.2.1270
; Check for input request before output requests at XLATE.
; 4(020) RLS 14-APR-82 GCO 4.2.1316
; if TCOPR set, check for TCOPG already set in bsc...race.
; 4(021) RLS 19-APR-82 GCO 4.2.1326
; Fix obscure race condtions in XLIABT,XLOABT,XLODMP.
; 4(022) RLS 18-JUN-82 GCO 4.2.1392
; do input abort processing similar to input eof.
; 4(023) RLS 25-JUN-82 GCO 4.2.1402
; check for signed on emulation node before granting input permission
; 4(024) RLS 28-JUN-82 GCO 4.2.1405
; check for error returns might happen from GETSTG if aborting
; 4(025) RLS 28-JUN-82 GCO 4.2.1407
; check for active io on device before waiting for ack of abort
; 4(026) RLS 01-JUL-82 GCO 4.2.1415
; in XLESEB set LF.SON after eof completes so input can be accepted
; 4(027) RLS 07-JUL-82 GCO 4.2.1425
; in XLEBAS restore R1 after call to SACTI to prevent crash when
; line is disabled.
; 4(030) RLS 09-AUG-82 GCO 4.2.1489
; in XLIABT, fix initial not running test to save ps before going
; to label that restores it(15$)
; 4(031) RLS 16-AUG-82 GCO 4.2.1491
; in XLOABT, account for reserved chunks when discarding ascii chunks
; 4(032) RLS 23-AUG-82 GCO 4.2.1500
; in XLOCNK, ignore null ascii characters
V3780=032
VEDIT=VEDIT+V3780
; specify translate options available
; bit 0 = ibm 3780/2780
; bit 1 = hasp multileaving
; bit 2 = ibm 3270
; bits 3-15 = reserved
XLOPTN=XLOPTN!B0 ;2780/3780 translation available
.SBTTL XLATE - 2780/3780 translate task
; this task translates data from ascii to ebcdic and from
; ebcdic to ascii.
XLATE: CALL XLWAIT ;check for input
BIT #TCOPR,TCFG2(R5) ;no - output permission requested?
BNE 11$ ;yes, start output.
BIT #TCOAB,TCFG2(R5) ;was abort flag set?
BEQ 10$ ;no.
CALL XLOABT ;yes, clear it (no output running)
10$: DSCHED #EBINTR!EBQCHK!EBQMSG,#JIFSEC/4
BR XLATE ; and try again.
; here if the pdp-10 program is requesting output permission.
11$: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.TC1(R4),R0 ;point to bsc task
BIT #TCOPG,TCFG2(R0) ;do we already have output permission?
BNE 13$ ;yes - no waiting
BIS #TCOPR,TCFG2(R0) ;ask for a bid for the line
MOV #20.*JIFSEC,R0 ;wait this long for response
12$: DSCHED #EBINTR,R0
MOV LB.TC1(R4),R0 ;point to bsc task
BIT #TCOPG,TCFG2(R0) ;do we have output permission?
BNE 13$ ;yes - proceed
BIT #TCOPR,TCFG2(R0) ;no - still bidding for the line?
BEQ 15$ ;no - bid failed
MOV TCTIM(R5),R0 ;yes, did time expire?
BNE 12$ ;no, keep waiting.
BIC #TCOPR,TCFG2(R0) ;yes, cease bidding
15$: BIC #TCOPR,TCFG2(R5) ;kill output request
BR XLATE ;the bid was a failure.
; here when bidding is complete.
13$: BIS #TCOPG,TCFG2(R5) ;yes, tell the pdp-10 we have permission
BIC #TCOPR,TCFG2(R5) ;no longer requesting permission
CALL SACTO ;set the output device active
CLR LB.MSC(R4) ;initialize count of msgs to transmit
MOV TCBFP(R5),R0 ;initialize r0 and r2 for
CLR R2 ; line buffer
CLR TCHPS(R5) ;assume we start at left margin
CLR TCVPS(R5) ; and at the top of a page
BIT #TCPRO,TCFG1(R5) ;carriage control on output?
BEQ 14$ ;no.
MOV #EBCESC,R1 ;yes, put an escape at the front
CALL XLAPBF ; of the line buffer
MOVB ASCEBC+'M,R1 ;and an 'M' in the second place
CALL XLAPBF ; to mean "no spacing".
14$: ; fall into XLASEB
.SBTTL XLASEB - 2780/3780 output processing
; here to translate chunks from ASCII to EBCDIC.
XLASEB:
11$: MOV R0,-(SP) ;save r0 (line buffer pointer)
MOV R2,-(SP) ; and r2 (line buffer counter)
12$: BIT #TCOAB,TCFG2(R5) ;is the stream aborted?
BEQ 29$
JMP 22$ ;yes, empty the queues
29$: CALL DEQCHK ;no, get a chunk
BCC 16$ ;got one.
BIT #TCOEF,TCFG2(R5) ;none, end of file?
BNE 17$ ;yes, send etx.
BIT #TCDMP,TCFG1(R5) ;no, has pdp-10 requested a dump?
BEQ 13$ ;no.
MOV (SP)+,R2 ;yes, restore r2
MOV (SP)+,R0 ; and r0
CALL XLODMP ;empty our buffers
BCS 23$ ;stream aborted
BR 11$ ;recirculate
13$: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.TC1(R4),R0 ;point to bsc task
BIT #TCORN,TCFG2(R0) ;is output running?
BEQ 15$ ;no.
BIS #TCORN,TCFG2(R5) ;yes, set our flag for pdp-10
BIC #TCOPG,TCFG2(R5) ; and clear permission flag
15$: DSCHED #EBINTR!EBQCHK
BR 12$ ; and test again.
; here when there is a chunk available
16$: MOV R0,R3 ;point r3 to new chunk
MOV (SP)+,R2 ;restore r2
MOV (SP)+,R0 ;restore r0
CALL XLOCNK ;translate a chunk from ascii to ebcdic
MOV TCLCB(R5),R4 ;get the lcb
SUB #TXLN,LB.RES(R4) ;unreserve translation chunks
BR 11$ ;try to translate another chunk
; here on end of file.
17$: MOV (SP)+,R2 ;restore r2
MOV (SP)+,R0 ;restore r0
18$: CALL XLEOFO ;signal end of file to the printer
19$: DSCHED #EBINTR,#JIFSEC/2
MOV TCLCB(R5),R4 ;point to lcb
MOV LB.TC1(R4),R1 ;point to bsc task
BIT #TCOAB,TCFG2(R1) ;stream aborted?
BNE 23$ ;yes.
BIT #TCOAB,TCFG2(R5) ;stream aborted?
BNE 23$ ;yes.
BIT #TCOEC,TCFG2(R1) ;no, completed eof processing?
BEQ 19$ ;no, wait for it.
BIS #LF.SON,LB.FGS(R4) ;set signon so input can be accepted
BIC #TCOEF!TCOEC,TCFG2(R1) ;yes, its all done.
BIS #TCOEC,TCFG2(R5) ;signal eof complete.
BIC #TCORN!TCOPG,TCFG2(R5) ;clear permission and running flags
20$: BIT #TCOAB,TCFG2(R5) ;has the stream aborted?
BNE 23$ ;yes, (may be too late, but try.)
BIT #LS.ENB,(R4) ;has the line been blown away?
BEQ 23$ ;yes - can't expect eof to be cleared by the 10
BIT #TCOEC,TCFG2(R5) ;output eof acknowledged?
BEQ 21$ ;yes, all done.
DSCHED #EBINTR,#JIFSEC/2
BR 20$ ;see if acknowldeged yet
21$:
CALL CACTO ;clear the output device active
JMP XLATE ;when all is done, recirculate
; here when the message stream is aborted.
22$: MOV (SP)+,R2 ;discard line counter
MOV (SP)+,R0 ; and line pointer
23$: CALL XLOABT ;do the abort processing
JMP XLATE ; and recirculate
.SBTTL XLOCNK - 2780/3780 translate an ASCII chunk to EBCDIC
; subroutine to translate a chunk from ASCII to EBCDIC
; R0 = pointer into line buffer
; R2 = count of chars in line buffer
; R3 = pointer to chunk to translate
; on return:
; R0 = updated pointer into line buffer
; R2 = updated count of chars in line buffer
XLOCNK:
11$: CLR -(SP) ;count of chars processed so far
MOV R3,R4 ;build pointer to data space
ADD #CHDAT,R4
12$: CMP CHLEN(R3),(SP) ;have we processed all chars?
BEQ 18$ ;yes, done with the chunk.
INC (SP) ;no, increment chars processed
MOVB (R4)+,R1 ;get next char
BEQ 12$ ;flush nulls
TRACE TRCXLD,R1 ;trace xlate char processing
MOV R3,-(SP) ;save chunk pointer
MOV R4,-(SP) ;save data pointer
13$: BIT #TCPRO,TCFG1(R5) ;printer-style output?
BNE 14$ ;yes.
CALL XLASCD ;no, card style output
BR 16$
14$: CALL XLASPR ;send character to printer
; here if we successfully sent the character
16$: MOV (SP)+,R4 ;restore r4
MOV (SP)+,R3 ;restore r3
BR 12$ ;go get next character
; here when an abort is detected while waiting for message
; space to free up.
17$: MOV (SP)+,R4 ;restore r4
MOV (SP)+,R3 ;restore r3
; here when the chunk is depleted or the stream aborted.
18$: MOV R0,(SP) ;save buffer pointer (done with count)
MOV R3,R0 ;put chunk pointer in r0
CALL FRECHK ;flush the garbage
MOV (SP)+,R0 ;restore r0
;set or clear the device active bit
XLCSAB: SAVE <R0,R1,R2>
MOV TCLCB(R5),R2 ;point to lcb
22$: MOV LB.TCD(R2),R0 ;point to xlate task
TST TCCHKQ(R0) ;any messages queued to this task ?
BEQ 23$ ;no, set device active bit
25$: CALL CACTO ;yes, clear device active bit, buffers full
BR 24$ ;continue
23$: CALL SACTO ;no, buffers empty, set device active bit
24$: RESTOR <R2,R1,R0>
RETURN
.SBTTL XLOABT - output abort processing
; subroutine called when the message stream is aborted. wait for
; all the data we have sent to the bsc task to
; be processed and then indicate that the message termination
; is complete.
XLOABT: MOV TCMSG(R5),R0 ;are we building a message?
BEQ 12$ ;no.
CALL FREMSG ;flush the garbage
CLR TCMSG(R5) ;we no longer have a message
BR 12$ ;no need to sleep immediately
11$: DSCHED #EBINTR!EBQCHK,#JIFSEC/4
12$: CALL DEQCHK ;is there a chunk?
BCS 13$ ;no.
CALL FRECHK ;yes, free it
MOV TCLCB(R5),R4
SUB #TXLN,LB.RES(R4) ;unreserve resources
BGE 12$
CLR LB.RES(R4)
BR 12$ ; and get the rest.
13$: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.TC1(R4),R1 ;point to bsc driver tcb
BIT #TCOAC,TCFG2(R1) ;has it completed the abort?
BNE 14$ ;yes - proceed
BIS #TCOAB,TCFG2(R1) ;be sure it's aborted [1(715]
SIGNAL R1,EBINTR ;wake the bsc task
BR 11$
14$: TST TCMSG1(R1) ;maybe, has it more messages?
BNE 11$ ;yes, wait until it flushes those
;aborts all done - have only to wait for 10
MOV TCLCB(R5),R4 ;yes, point to lcb
BIS #TCOAC,TCFG2(R5) ;we have completed the abort
BIT #TCOPR!TCOPG!TCORN!TCOEF!TCOEC,TCFG2(R5) ;check if running
BEQ 20$
16$: BIT #LS.ENB,(R4) ;line disabled ?
BEQ 20$ ; yes - can't wait for 10 to come by
PIOFF
BIT #TCOAC,TCFG2(R5) ;abort acknowledged?
BEQ 19$ ;yes - clean up
;not yet. (ack is from the pdp-10)
CALL SACTO ;keep the active bit on
PION
DSCHED #EBINTR,#JIFSEC/4
BR 16$
19$: PION
20$: MOV LB.TC1(R4),R1 ;point to bsc driver tcb
BIC #TCOAB!TCOAC,TCFG2(R1) ;acknowledge abort
;clear abort and running bits
BIC #TCOAB!TCOAC!TCOPR!TCOPG!TCORN!TCOEF!TCOEC,TCFG2(R5)
SIGNAL R1,EBINTR ;wake the bsc task
CALL CACTO ;device no longer active
RETURN
.SBTTL XLWAIT - check for input to do
; subroutine to wait for a message from the line driver, a
; chunk from the dl10 driver, or just for some time to pass.
; called from output routine when there is no output going.
XLWAIT: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.TC1(R4),R0 ;point to bsc task
PIOFF
BIT #TCIPR!TCIRN,TCFG2(R0) ;input permission requested or still running?
BEQ 14$ ;no - go away
;yes - try to synchronize 10 and remote
BIT #LF.SIM,LB.FGS(R4) ;check for emulation
BEQ 10$ ;no - grant permission
BIT #LF.SON,LB.FGS(R4) ;yes - check if signed on already
BEQ 14$ ;no - don't grant permission
10$: BIS #TCIPG,TCFG2(R0) ;pass grant to bsc task
BIS #TCIRN,TCFG2(R5) ;we are now running
BIC #TCIPG!TCIPR!TCIWR,TCFG2(R5) ;clear grant flag
SIGNAL R0,EBINTR ;wake the bsc task
PION
BR XLEBAS ;translate ebcdic to ascii
; here if input permission has not been requested.
14$: PION
BIT #TCIAB!TCIAC,TCFG2(R0) ;check for bsc task abort
BNE XLEBAS ;yes - go do the abort processing
BIT #TCIAB,TCFG2(R5) ;xlate abort while idle?
BNE XLEBAS ;yes, process the abort.
15$: RETURN
.SBTTL XLEBAS - translate chunk from EBCDIC to ASCII
; here when we have the bsc task running, at end-of-file
; or aborted. set up for input data processing.
XLEBAS: CLR TCHPS(R5) ;clear hpos
CLR TCVPS(R5) ; and vpos
BIC #TCESC!TCIGS,TCST2(R5) ;not in escape or igs sequence
MOVB ASCEBC+'/,TCCCI(R5) ;initial spacing is single
11$:
19$: CALL DEQMSG ;get a message
BCS 12$ ;none
MOV R0,R1
CALL CNTMSG ;count the chunks
SAVE R0 ;save it til later
MOV R1,R0
CALL XLIMSG ;got one, process it.
MOV TCLCB(R5),R4
SUB (SP)+,LB.RES(R4) ;unreserve xlate chunks
BGE 19$
CLR LB.RES(R4)
BR 19$ ;try again
20$: DSCHED #EBQMSG!EBINTR
BR 11$ ; and do the rest.
; here if no message to process.
12$: MOV TCLCB(R5),R4 ;get lcb
MOV LB.TC1(R4),R1 ;get bsc task
BIT #TCIAB!TCIAC,TCFG2(R1) ;is the bsc task input aborted?
BNE 10$ ;yes - check for cleaup
BIT #TCIAB,TCFG2(R5) ;has stream been aborted?
BEQ 13$ ;no.
10$: BIS #TCIAB,TCFG2(R1) ;make sure bsc is input aborted
BIT #TCIAC,TCFG2(R1) ;check if bsc input abort complete
BEQ 20$ ;continue processing input til it is
CALL XLIABT ;yes, do abort processing
RETURN
13$: BIT #LS.ENB,(R4) ;has the line been blown away?
BEQ 10$ ;yes - can't expect eof to be cleared by the 10
BIT #TCIEC,TCFG2(R1) ;have we reached eof?
BEQ 20$ ;no - nap awhile
;EOF
14$: BIS #TCIEC,TCFG2(R5) ;flag end of file
15$: CALL SACTI ;set device active bit since ten must clear tciec
MOV LB.TC1(R4),R1 ;restore pointer to bsc task
BIT #LS.ENB,(R4) ;has the line been blown away?
BEQ 10$ ;yes - can't expect eof to be cleared by the 10
DSCHED #EBQMSG!EBINTR
BIT #TCIEC,TCFG2(R5) ;eof acknowledged yet?
BNE 15$ ;no, keep waiting
BIC #TCIRN,TCFG2(R5) ; 3(011) rls flag no longer running
BIC #TCIEC,TCFG2(R1) ;clear its eof complete bit
BIT #TCIRN,TCFG2(R5) ;check if input still running(blocked messages)
BEQ 25$
JMP XLWAIT ;yes - another message is already here
25$: CALL CACTI ;device no longer active
; here to return to check for output
16$: RETURN
.SBTTL XLIABT - process input abort
; subroutine to process an input abort.
XLIABT: ;come here only when bsc input abort complete
12$: MOV TCLCB(R5),R4 ;point to lcb
13$: BIS #TCIAC,TCFG2(R5) ;indicate abort complete
BIT #TCIRN!TCIPG!TCIEF!TCIEC,TCFG2(R5) ;check if running
BEQ 16$
14$: PIOFF
BIT #LS.ENB,(R4) ;line disabled?
BEQ 15$ ;yes - can't wait for 10 to acknowledge
BIT #TCIAC,TCFG2(R5) ;is it acknowledged?
BEQ 15$ ;yes - clean up
CALL SACTI ;keep the active bit on
PION
DSCHED #EBINTR,#JIFSEC/4
BR 14$
16$: PIOFF ;accomodate main loop
15$: ;clear abort and running bits
BIC #TCIAB!TCIAC!TCIPR!TCIWR!TCIPG!TCIRN!TCIEF!TCIEC,TCFG2(R5)
MOV LB.TC1(R4),R1 ;point to bsc task
BIC #TCIAB!TCIAC,TCFG2(R1) ;clear abort bits
PION
SIGNAL R1,EBINTR ;wake the BSC task
CALL CACTI ;device no longer active
RETURN
.SBTTL XLAPBF - stash EBCDIC character in line buffer
; subroutine to accept a character from the 10 and put it in
; the line buffer. the character is already in ebcdic.
; R0 points to the current position in the line buffer
; R1 contains the character to be stored
; R2 contains the number of characters stored already
; on return:
;
; R0 and R2 are updated
XLAPBF: CMP R2,TCBFC(R5) ;buffer full?
BEQ 11$ ;yes, dont store.
MOVB R1,(R0)+ ;no, store char
INC R2 ;increment character count
11$: RETURN
.SBTTL XLASPR - translate printer character from ASCII to EBCDIC
; subroutine to translate a character from ascii to
; line printer ebcdic.
; handles format effectors and compression.
; R0 = pointer to the current position in the line buffer
; R1 = the character to be translated
; R2 = the number of characters already stored in the line buffer
; TCHPS(R5) = the current horizontal line position.
; (left margin = 0)
; TCVPS(R5) = the current vertical page position.
; (top of page = 0)
; on return:
; TCHPS(R5) and TCVPS(R5) are updated.
; c is set if we ran out of chunks, clear if not.
XLASPR: CMPB R1,#' ;compare char with blank
BGE 12$ ;graphic, space or del.
MOVB ASCSPC(R1),R3 ;control--get its code
JMP @11$(R3) ;dispatch on the code
; dispatch table for ascii control character types
11$: .WORD 26$ ;invalid -- ignore
.WORD 25$ ;ht
.WORD 26$ ;esc (invalid) -- ignore
.WORD 24$ ;cr
.WORD 17$ ;ff
.WORD 19$ ;other vertical control (lf, vt)
; here on space, graphic or del.
12$: CMPB #177,R1 ;is this a del?
BEQ 26$ ;yes, dont send to printer.
BIT #TCLBK,TCST2(R5) ;no, is previous line broken?
BNE 16$ ;yes, graphic or space after line break
CMP TCHPS(R5),#132. ;no, beyond end of line?
BLT 13$ ;no.
MOV R1,-(SP) ;yes, save character
MOV #12,R1 ;give free lf (= crlf)
CALL XLASPR ;this will break the line
MOV (SP)+,R1 ;restore character
BR 16$ ;send the line
; here if the line has not overflowed.
13$: MOVB ASCEBC(R1),R1 ;translate to ebcdic
CMPB #EBCBLK,R1 ;blank?
BNE 14$ ;no.
CALL XLASSP ;yes, try to compress it.
BCC 15$ ;nothing to store, just inc hpos
14$: CALL XLAPBF ;store character in buffer
15$: INC TCHPS(R5) ;increment horizontal position
BR 26$ ; and give successful return.
; here if the previous line had ended. since this character
; is a graphic or space, send the previous line.
16$: CALL XLSNDL ;send line
BR 12$ ;append to buffer
; here on a form feed or a vertical motion character which
; has no stops below the current vertical position.
; go to the top of the next page.
17$: CALL XLASTF ;top of form
CLR TCVPS(R5) ;clear vertical position
BR 24$ ;clear hpos and give ok return.
; here on other vertical motion character -- lf, vt, dc...
19$: MOV TCVPS(R5),R3 ;current vertical position
INC R3 ;look at next position
TSTB XLVFU(R3) ;at bottom of page?
BPL 21$ ;no.
BR 17$ ;yes, skip to top of next form.
20$: CALL XLASSF ;single space the printer
INC TCVPS(R5) ;down one vertical space
BR 24$ ;clear hpos and give ok return.
; here if we are not at the bottom of the vfu.
21$: BITB XLLPCH-12(R1),XLVFU(R3) ;should this char stop here?
BNE 20$ ;yes, single space and quit
; see if there is a stop for this character before the end of
; form. if so, space down to it. if not, just skip to
; the top of the next page.
22$: INC R3 ;look at next position
TSTB XLVFU(R3) ;bottom of form?
BLT 17$ ;yes, treat as form feed.
; here if we are not yet at bottom of form. see if the
; vfu says we should stop here.
23$: BITB XLLPCH-12(R1),XLVFU(R3) ;this channel punched here?
BEQ 22$ ;no, look at next position
CALL XLASSF ;yes, give single space
CLR TCHPS(R5) ;move to left margin
INC TCVPS(R5) ;down one vertical space
BR 19$ ;do it again until we get there.
; here on carriage return and after vertical motion.
; set "tclbk", which
; will cause the next graphic to output the current line buffer.
24$: CLR TCHPS(R5) ;horiz. pos. to left margin
BIS #TCLBK,TCST2(R5) ;set "tclbk"
BR 26$ ;give ok return.
; here on horizontal tab. output spaces until the horizontal
; position is a multiple of 8. always output at least one
; space.
25$: MOV #' ,R1 ;space
CALL XLASPR ;output it
BIT #7,TCHPS(R5) ;is horizontal position mod 8 = 0?
BNE 25$ ;no, output another space
; here to give ok return.
26$: CLC ;signal success
27$: RETURN
.SBTTL XLASTF - skip printer to top of page
; subroutine to skip the printer to the top of the next page.
; note: caller sets tclbk on return to force the buffer out
; on the next character. we could call xlsndl from here but
; for end-of-file processing, which would cause an extra line
; in that case.
; on return:
; c is set if the function could not be performed due
; to lack of chunks, clear otherwise.
XLASTF: MOV TCBFP(R5),R3 ;point to line buffer
CMPB ASCEBC+'M,1(R3) ;carriage control = no spacing?
BEQ 11$ ;yes, change to top of form.
CALL XLSNDL ;no, finish off that line
; here after making sure the current line specifies no spacing.
; change to "top of form".
11$: MOV TCBFP(R5),R3 ;point to line buffer
MOVB ASCEBC+'A,1(R3) ;make carriage control = top of form
BIT #TCPCE,TCFG1(R5) ;is page counter enabled?
BEQ 12$ ;no.
DEC TCPGC(R5) ;yes, decrement page counter
BNE 12$ ;it has not overflowed
BIS #TCPCO,TCFG1(R5) ;it has overflowed, "interrupt"
12$: CLC ;indicate no error
13$: RETURN
.SBTTL XLASSF - vertical space printer
; subroutine to space the printer vertically by one.
; escalate carriage control from no spacing through
; 1, 2 and 3 spaces if possible before releasing the line.
; note: caller takes responsibility for setting tclbk on return.
XLASSF: MOV TCBFP(R5),R3 ;point to line buffer
INC R3 ;point to carriage control
CMPB ASCEBC+'M,(R3) ;no spacing?
BEQ 11$ ;yes, make single space
CMPB ASCEBC+'/,(R3) ;no, single space?
BEQ 12$ ;yes, make double space
CMPB ASCEBC+'S,(R3) ;no, double space?
BEQ 13$ ;yes, make triple space
CALL XLSNDL ;no, send the line
BR XLASSF ;change no spacing to single
; here on no spacing to change to single
11$: MOVB ASCEBC+'/,(R3) ;make single spacing
BR 14$
; here on single spacing to change to double
12$: MOVB ASCEBC+'S,(R3) ;make double spacing
BR 14$
; here on double spacing to change to triple
13$: MOVB ASCEBC+'T,(R3) ;make triple spacing
14$: CLC ;signal ok
15$: RETURN
.SBTTL XLASCD - translate card reader character from ASCII to EBDCIC
; subroutine to translate a character from ascii to card punch
; or card reader ebcdic.
; r1 = character to be translated
; tchps(r5) = current horizontal position
; on return:
; tchps(r5) is updated
; c is set if we are out of chunks. the character
; should be re-sent.
XLASCD: CMPB R1,#' ;space?
BEQ 15$ ;yes.
BGT 11$ ;no, graphic or del
TST R1 ;null?
BEQ 13$ ;yes, just ignore it.
CMPB #12,R1 ;no, is it line feed?
BEQ 16$ ;yes, end of card.
CMPB #11,R1 ;no, horizontal tab?
BEQ 20$ ;yes, simulate with spaces.
CMPB #15,R1 ;carriage return?
BEQ 13$ ;yes, ignore.
; here on graphic, del or miscellaneous control characters.
11$: CMP TCHPS(R5),#80. ;is line full?
BEQ 13$ ;yes, ignore character.
MOVB ASCEBC(R1),R1 ;no, translate to ebcdic
BEQ 13$ ;ignore untranslatable chars
BIT #300,R1 ;control character?
BNE 12$ ;no, it is ok to send.
TSTB EBCSPC(R1) ;yes, data link ctl or irs?
BNE 15$ ;yes, convert to space
; here on graphic, del, miscellaneous control characters
; which are not data link control characters or irs
; and if the space subroutine wants to store a character.
; the character is in r1 and is in ebcdic.
12$: INC TCHPS(R5) ;increment hpos
CALL XLAPBF ;store in line buffer
13$: CLC ;indicate success
14$: RETURN
; here on space or improper control character, treated as space.
15$: CMP TCHPS(R5),#80. ;is line already full?
BGE 13$ ;yes, ignore character
CALL XLASSP ;no, worry about space compression
BCS 12$ ;store something
INC TCHPS(R5) ;nothing to store, increment hpos
BR 13$ ;and give success return.
; here on line feed. this marks the end of the card.
16$: BIT #TCOBS,TCFG1(R5) ;old bsc protocol
BEQ 19$ ;no, no need for padding.
17$: CMP TCHPS(R5),#80. ;yes, have we finished padding?
BEQ 19$ ;yes.
CALL XLASSP ;no, append a space
BCC 18$ ;nothing to store
CALL XLAPBF ;append character to buffer
18$: INC TCHPS(R5) ;we have padded by one character
BR 17$ ;see if we need more.
; here when the card has been padded to 80 characters if necessary
19$: CALL XLSNDL ;send the card, blocking with
; previous if possible
CLR TCHPS(R5) ;now back to col. zero
BR 13$ ;give success return.
; here on horizontal tab. convert to the proper number of
; spaces.
20$: MOV #' ,R1 ;space
CALL XLASCD ;output it
BIT #7,TCHPS(R5) ;are we at a mult. of 8 ?
BEQ 13$ ;yes, give success return.
CMP TCHPS(R5),#80. ;no, at end of card?
BEQ 13$ ;yes, we are all done.
BR 20$ ;no, give another space.
; subroutine to store a blank into the line buffer, compressing
; if indicated.
; on return:
; c clear - do nothing.
; c set - put r1 in the line buffer.
XLASSP: BIT #TCCPS,TCFG1(R5) ;compression active?
BEQ 12$ ;no, treat as graphic
TST TCHPS(R5) ;any chars on line?
BEQ 12$ ;no, first space is graphic
CMPB #EBCBLK,-1(R0) ;yes, prev. char a blank?
BEQ 11$ ;yes, make 2 comp. blanks
CMP TCHPS(R5),#1 ;no, at least 2 chars already?
BLE 12$ ;no, cant be in a compression.
CMPB #EBCIGS,-2(R0) ;yes, already in a compression?
BNE 12$ ;no, first blank just stored
CMPB #EBCBLK+63.,-1(R0) ;yes, already full?
BEQ 12$ ;yes, just store blank
INCB -1(R0) ;no, increment blank count
CLC ;indicate dont store anything
RETURN
; here on the second blank in a row
11$: MOVB #EBCIGS,-1(R0) ;turn blank into "igs"
MOV #EBCBLK+2,R1 ;store char indicating...
SEC ; two blanks.
RETURN ;put into line buffer
; here to return indicating that the blank character in r1
; should be stored in the line buffer.
12$: MOV #EBCBLK,R1 ;put ebcdic blank in r1
SEC ;flag to store r1
RETURN
.SBTTL XLSNDL - 2780/3780 send line buffer to BSC task
; subroutine to send the line buffer to the bsc task. build
; it into a message.
; r0 points to the last used position of the buffer.
; on return:
; c is set if out of chunks. otherwise, c is clear and:
; the line buffer (and r0 and r2, which refer to it)
; contains "esc" "m" if we are doing printer output,
; otherwise (card output) the line buffer is empty.
; tclbk is clear.
XLSNDL: MOV R1,-(SP) ;save current character
MOV R0,-(SP) ;save pointer to end of buffer
11$: MOV TCBFP(R5),R3 ;point r3 to start of buffer
BIT #TCOBS,TCFG1(R5) ;old bsc mode?
BEQ 12$ ;no.
BIT #TCPRO,TCFG1(R5) ;yes, printer output?
BEQ 12$ ;no.
CMPB ASCEBC+'M,1(R3) ;yes, overprint request?
BNE 12$ ;no.
MOV (SP)+,R2 ;yes, discard pointer to end of buffer
BR 20$ ;we can't overprint, so ignore line.
; here when the line does spacing or we have new bsc protocol,
; which permits overprinting.
12$: MOV TCMSG(R5),R0 ;point to partial message
BNE 14$ ;there is one.
13$: CALL MSGSUP ;none, set up a message
MOV R0,TCMSG(R5) ;we now have a message
BR 17$ ;put this line in it
; here when there is already a partially filled message
14$: MOV TCBFP(R5),R3 ;point to start of buffer
SUB (SP),R3 ;compute length of buffer
ADD R3,MSGSNL(R0) ;deplete sync count by length
NEG R3 ;true count
CALL XLSNDM ;send message if record too big
MOV TCMSG(R5),R0 ;do we still have a message?
BEQ 13$ ;no, build another.
; here if there is enough room for this record in the message.
; first end the previous record.
BIT #TCOBS,TCFG1(R5) ;old bsc protocol?
BNE 15$ ;yes, use ius with bcc.
MOV #EBCIRS,R1 ;no, end record with irs
KGACUM R1 ;accumulate in bcc
CALL MSGAPC ;append to message
BR 16$ ;rejoin common path.
15$: CALL XLIBCC ;store intermediate bcc
16$: TST MSGSNL(R0) ;will we need a sync?
BGT 17$ ;no, wait for next record
MOV #EBCSYN,R1 ;yes, append a sync
CALL MSGAPC ; to the message
MOV #SYNLEN,MSGSNL(R0) ;come back later
; here to store the line buffer in the message.
17$: MOV TCBFP(R5),R3 ;point to line buffer
MOV (SP)+,R2 ;point to end of line buffer
; fall into copy loop
; this is the loop which copies characters from the line buffer
; into the transmission message.
18$: CMP R2,R3 ;all done?
BEQ 19$ ;yes.
MOVB (R3)+,R1 ;no, get next character
KGACUM R1 ;accumulate bcc
CALL MSGAPC ;append to message
BR 18$ ;process all the characters
; here when all done.
19$: INC MSGNLR(R0) ;count logical records in message
; processing of the line buffer is now complete.
20$: BIC #TCLBK,TCST2(R5) ;line is no longer broken
MOV TCBFP(R5),R0 ;point r0 to line buffer
CLR R2 ;clear line buffer counter
BIT #TCPRO,TCFG1(R5) ;are we doing carriage control?
BEQ 21$ ;no.
MOV #EBCESC,R1 ;yes, put escape at start of buffer
CALL XLAPBF
MOVB ASCEBC+'M,R1 ;second char is "m"
CALL XLAPBF
21$: MOV (SP)+,R1 ;restore current character
CLC ;signal all ok
RETURN
.SBTTL XLIBCC - insert IUS and BCC in message
; subroutine to insert ius, bcc in a message.
; this is used only in "old bsc" mode, since hasp does not
; support ius from ibm 3780's.
XLIBCC: MOV #EBCIUS,R1 ;start with ius
KGACUM R1 ;include the ius in the bcc
CALL MSGAPC ;put in the block
JMP STOBCC ;put bcc after the ius
.SBTTL XLSNDM - send the message if current record won't fit
; subroutine to determine if there is enough room in
; the current message for the next record, and if not
; end the message. worries about logical record limit.
; R0 and TCMSG(R5) point to the current message
; R3 contains the length of the next record
; on return:
;
; TCMSG(R5) is zero if we had to finish off the current message
; either because we had reached our record limit or because
; the next record is so long that it would have caused the message
; to exceed the length limit.
.ENABL LSB
XLSNDM: MOV TCLCB(R5),R1 ;point to lcb
CMP MSGNLR(R0),LB.MLR(R1) ;have we reached record limit?
BEQ 11$ ;yes, end message now.
ADD MSGLEN(R0),R3 ;no, compute new length
ADD #7,R3 ;add overhead
CMP R3,LB.MBL(R1) ;would result be too big?
BLT 13$ ;no, append it.
11$: BIT #TCOBS,TCFG1(R5) ;old bsc protocol?
BNE 12$ ;yes, etb implies irs
MOV #EBCIRS,R1 ;no, include an explicit irs
KGACUM R1 ;include in bcc
CALL MSGAPC ;append to message
12$: MOV #EBCETB,R1 ;"etb"
XLSNDE: ; wind up a message
; r0/msg ptr
; r1/end character
KGACUM R1 ;accumulate bcc
CALL MSGAPC ;append to message
CALL STOBCC ;append bcc
CALL XLPADS ;append pads to message
CALL MSGAPE ;return unused chunks
MOV TCLCB(R5),R4 ;point to lcb
MOV LB.TC1(R4),R1 ;point to bsc driver
CALL QUEMSG ;send it the message
CLR TCMSG(R5) ;we no longer have a message
INC LB.MSC(R4) ;one more message for bsc task to transmit
13$: RETURN
.DSABL LSB
.SBTTL XLODMP - 2780/3780 dump output buffers
; subroutine to dump output, as requested by the pdp-10.
; all local buffers are cleared.
; on return, c set if stream aborted, c clear if all messages
; are dumped.
XLODMP: CALL XLSNDL ;empty the line buffer
MOV R0,-(SP) ;save line buffer position
MOV R2,-(SP) ; and count
MOV TCMSG(R5),R0 ;is there a message waiting?
BEQ 13$ ;no.
MOV TCLCB(R5),R1 ;point to lcb
MOV LB.MLR(R1),MSGNLR(R0) ;yes, pretend it is full...
CALL XLSNDM ; and send it.
11$: DSCHED #EBINTR,#JIFSEC/4
13$: BIT #TCOAB,TCFG2(R5) ;is stream aborted?
BNE 12$ ;yes, return immediately.
MOV TCLCB(R5),R4 ;no, point to lcb
TST LB.MSC(R4) ;are all messages sent?
BNE 11$ ;no, wait for them all.
BIC #TCDMP,TCFG1(R5) ;yes, clear "dumping" flag
MOV (SP)+,R2 ;restore line buffer count
MOV (SP)+,R0 ; and position
CLC ;indicate not abort
RETURN
; here if the stream is aborted.
12$: MOV (SP)+,R2 ;restore line buffer count
MOV (SP)+,R0 ; and position
SEC ;flag stream aborted
RETURN
.SBTTL MSGSUP - 2780/3780 message setup
; subroutine to set up a message. all the leading bsc stuff
; is placed in the data portion.
; on return, c is set if we are out of chunks.
; otherwise, r0 points to the first chunk of the message.
; note: msgsup will not fail for translate tasks - only for tentsk and
; bsc tasks.
.ENABL LSB
MSGSUP: CALL CREATM ;get a message header
BCS 17$ ;out of chunks.
MOV #EBCLPD,R1 ;get leading pad character (alt bits)
CALL MSGAPC ;store in message
BCS 16$
MOV #5,R2 ;count of leading syncs
11$: MOV #EBCSYN,R1 ;"synchronous idle"
CALL MSGAPN ;put character in string
BCS 16$
MOV TCLCB(R5),R4 ;point to lcb
.IF NE,FT.HSP
CMP #TTHASP,LB.DVT(R4) ;hasp mode?
BNE 21$ ;no, send stx for 2780/3780
BIT #LF.TSP,LB.FGS(R4) ;transparent mode?
BNE 22$ ;yes, use dle-stx
MOV #EBCSOH,R1 ;no, use soh-stx for non-trans
BR 23$ ;put in message
22$: MOV #EBCDLE,R1 ;use dle for transparent
23$: CALL MSGAPC ;append to message
BCS 16$
.ENDC ;.IF NE,FT.HSP
21$: MOV #EBCSTX,R1 ;"start of text"
CALL MSGAPC ;append to string
BCS 16$
CALL XLPREL ;preallocate chunks
BCS 16$
KGLOAD #0 ;initialize the kg11-a
MOV #SYNLEN,MSGSNL(R0) ;initialize intermediate
; synch counter.
CLC ;suc
RETURN
; now pre-allocate enough room for a max-size message so
; we won't have to worry about running out of chunks while
; building it.
XLPREL: ; common to hasp msg allocator
MOV R0,-(SP) ;save pointer to message
20$: MOV TCLCB(R5),R1 ;point to lcb
MOV LB.MBL(R1),R0 ;get max transmission block size
ASL R0 ;compute max length of message
ASL R0 ; as 125 percent of
ADD LB.MBL(R1),R0 ; the max block length
ASR R0
ASR R0
19$: MOV R0,-(SP) ;max message length
12$: CALL GETSTG ;get a hunk
BCS 15$ ;out of chunks
MOV 2(SP),R1 ;point r1 at message
13$: TST (R1) ;is this the last chunk?
BEQ 14$ ;yes, append new chunk here
MOV (R1),R1 ;no, go on to next chunk
BR 13$
; here when we have found the last chunk. append the new
; chunk here.
14$: MOV R0,(R1) ;append new chunk
SUB #CHDATL,(SP) ;we have room for that many more chars
BGT 12$ ;need more room
MOV (SP)+,R0 ;discard depleted count
MOV (SP)+,R0 ;restore pointer to message
CLC ;signal ok
RETURN
; here if we run out of chunks while doing pre-allocation.
15$: MOV (SP)+,R0 ;discard depleted count
MOV (SP)+,R0 ;restore pointer to message
; here if we run out of chunks or short of chunks
; while building the message.
16$: CALL FREMSG ;flush the garbage
SEC ;signal error
17$: RETURN
.DSABL LSB
.SBTTL XLEOFO - 2780/3780 output end of file processing
; subroutine to send an end-of-file indication to the output.
XLEOFO: BIT #TCPRO,TCFG1(R5) ;printer-style output?
BEQ 11$ ;no, lose any unterminated line
CALL XLSNDL ;finish off the current line
11$: MOV TCMSG(R5),R0 ;point to current message
BNE 12$ ;there is one.
CALL MSGSUP ;none, build one.
MOV R0,TCMSG(R5) ;we now have a message
12$: BIT #TCOBS,TCFG1(R5) ;old bsc protocol?
BNE 13$ ;yes, etx implies irs
MOV #EBCIRS,R1 ;no, provide an explicit irs
KGACUM R1 ;include in bcc
CALL MSGAPC ;append to message
13$: MOV #EBCETX,R1 ;end of text
CALL XLSNDE ; wind up the message
BIS #TCOEF,TCFG2(R1) ;indicate last message
CLC ;signal success
RETURN
; subroutine to append some pads to the end of a message.
; only one of these pads is actually transmitted; the
; others are lost in the dq11 transmit buffer.
XLPADS: SAVE R2
MOV TCLCB(R5),R2 ;get line block ptr
MOV LB.TRL(R2),R2 ;count of pads
MOV #EBCPAD,R1 ;pad character
CALL MSGAPN ;append a pad character
RESTOR R2
RETURN
.SBTTL XLIMSG - 2780/3780 translate message from EBCDIC to ASCII
; subroutine to translate an input message. the ascii is sent
; to the dl10 task for the user's buffer.
XLIMSG: MOV R0,-(SP) ;save pointer to message
TST MSGLEN(R0) ;check for null messages
BNE XLIMSR ;[1006]there is a first chunk
JMP XLIIGN ;[1006]there is none, ignore message.
XLIMSR: CALL CREATM ;get a message header even if have to wait all day
BCC 11$
JMP XLIIGN ;things are truly desperate
; we have the header chunk for the ascii message
11$: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.LNU(R4),MSGID(R0) ;store message id (line no.)
MOV (SP),R2 ;point to ebcdic message
MOV TCCCI(R5),-(SP) ;save current carriage control char
MOV TCVPS(R5),-(SP) ; and current vertical position
MOV TCHPS(R5),-(SP) ; and current horizontal position
MOV TCST2(R5),-(SP) ;and two status bits in case we
; run out of chunks and have to restart
BIT #MSGTSP,MSGFGS(R2) ;transparent?
BEQ 12$ ;no.
CALL XLITSP ;yes, special translation
10$: JMP XLIMSE ;successful translation
; here if the message is not transparent.
12$: MOV CHLEN(R2),R3 ;get count in header block
MOV (R2),-(SP) ;save ptr to next chunk
MOV MSGPTR(R2),R2 ;get initial ptr
BIC #TCPRI,TCFG1(R5) ; set punch flag
BR 14$
13$: MOV (R2)+,-(SP) ;save pointer to next chunk
MOV (R2)+,R3 ;get count of bytes in this chunk
14$: TST R3 ;any bytes left?
BEQ 22$ ;no, done with this chunk
DEC R3 ;yes, count down counter
MOVB (R2)+,R1 ;get ebcdic character
BIT #<TCIGS!TCESC>,TCST2(R5) ;last character igs or esc?
BNE 19$ ;yes, treat this character specially
BIT #300,R1 ;no, is this a special character?
BNE 21$ ;no, translate and send to -10
CMPB #EBCESC,R1 ; is this an escape ?
BEQ 24$ ; yes, flag it
; we have a control character
CMPB #EBCIGS,R1 ;is it igs?
BNE 15$ ;no.
BIS #TCIGS,TCST2(R5) ;yes, remember that
BR 14$ ;process next character in special way
; the character is not an igs
15$: BIT #TCPRI,TCFG1(R5) ;are we in "printer" mode?
BEQ 18$ ;no.
; we are in printer mode -- check for esc, irs and ht
CMPB #EBCESC,R1 ;is this an escape?
BNE 16$ ;no.
BIS #TCESC,TCST2(R5) ;yes, remember that
BR 14$ ;process next character in special way
; not an escape
16$: CMPB #EBCIRS,R1 ;is it an irs?
BNE 17$ ;no.
CALL XLIPRS ;yes, process an irs
BR 14$ ;process next character
; not an irs
17$: CMPB #EBCHT,R1 ;horizontal tab?
BNE 21$ ;no, try to treat as ordinary char
CALL XLIPHT ;yes, process horizontal tab
BR 14$ ;process next character
; card mode -- check for irs
18$: CMPB #EBCIRS,R1 ;have we an irs?
BNE 21$ ;no, try to treat as ordinary char
;pad to 80. characters when irs is encountered if less than 80.
31$: CMP TCHPS(R5),#80. ;do we have 80. characters ?
BGE 32$ ;yes, the line is finished
SAVE R2
MOV #' ,R1 ;no, get a blank
MOV #80.,R2 ;calc number to pad
SUB TCHPS(R5),R2
CALL MSGAPN ;append the block
RESTOR R2
32$: CLR TCHPS(R5) ;start the next card at the beginning
MOV #15,R1 ;yes, put crlf in ascii message
CALL MSGAPC
MOV #12,R1
CALL MSGAPC
INC TCVPS(R5) ;we have done a line
BR 14$ ;try for another character.
; here if previous character was igs or esc
19$: BIT #TCIGS,TCST2(R5) ;was last char an igs?
BEQ 20$ ;no, must have been esc
CALL XLIPGS ;yes, process the igs
BR 14$ ;process next character
; here if last character wasn't an igs. it must have been
; an esc and we must be in printer mode.
20$: MOVB R1,TCCCI(R5) ;store character after the esc
; for use by irs
BIC #TCESC,TCST2(R5) ;last char no longer an esc
; esc-4 says this is a punch
CMPB #364,R1 ; ebcdic 4 ?
BEQ 23$ ; yes, continue as punch
BIS #TCPRI,TCFG1(R5) ; no, flag as printer
23$: ;
CMPB #EBCHT,R1 ;have we an "esc ht" sequence?
BNE 14$ ;no. get next character.
CALL XLISHT ;yes, set horiz. tabs.
BR 14$ ;get next character. (probably an escape)
24$: BIS #TCESC,TCST2(R5) ; flag last character was escape
BR 14$ ; continue
; here on normal character in card and printer modes.
21$: MOVB EBCASC(R1),R1 ;translate to ascii
BEQ 14$ ;ignore nulls and untranslatables
INC TCHPS(R5) ;increment horizontal position
CALL MSGAPC ;store ascii character in message
BR 14$ ;go process another character
; here when we run out of bytes in the chunk.
; go on to the next, if there is one.
22$: MOV (SP)+,R2 ;get next chunk pointer
BNE 13$ ;there is one, process it.
BR XLIMSE ;none, end of processing
.SBTTL XLIMSE - end of input message processing
; here when processing is complete. send the ascii message
; to the tentsk task and the ebcdic message to be freed.
XLIMSE: ;r0/ptr to completed ascii message
MOV TCDLDR,R1 ;point to tentsk
CALL QUEMSG ;send it the ascii msg
;discard old tcst2
;discard old tchps
;discard old tcvps
;discard old tccci
ADD #4*2,SP
CALL SACTI ;set device active bit
XLIIGN: ;[1006]here is message has no chunks.
MOV (SP)+,R0 ;get back ebcdic message
CALL FREMSG ;flush the garbage
CLC ;signal all ok
RETURN
.SBTTL XLITSP - translate transparent input messages
; subroutine to translate transparent messages. a crlf is
; inserted every 80 characters and at the end of the record
; if any text is left unterminated. (this is to accomodate
; future extension to support of the ibm 3770's 51-column
; card feature.)
;
; r0 = empty ascii message
; r2 = ebcdic message
XLITSP: MOV CHLEN(R2),R3 ;get count in header block
MOV (R2),-(SP) ;save ptr to next chunk
MOV MSGPTR(R2),R2 ;get initial ptr
CLR TCHPS(R5) ;we are at front of line
BR 12$
11$: MOV (R2)+,-(SP) ;save pointer to next chunk
MOV (R2)+,R3 ;get count of bytes in this chunk [2(772)]
12$: TST R3 ;any more chars in this chunk?
BEQ 14$ ;no, all done.
DEC R3 ;yes, now one fewer char
MOVB (R2)+,R1 ;get char from chunk
MOVB EBCASC(R1),R1 ;translate to ascii
BEQ 13$ ;dont store untranslatables
CALL MSGAPC ;put character in ascii msg
13$: INC TCHPS(R5) ;we have processed a character
BIT #TCPRI,TCFG1(R5) ; lpt mode or card ??
BEQ 9$ ; the venerable card
CMP TCHPS(R5),#132. ; lpt - wider by far
BR 10$
9$: CMP TCHPS(R5),#80. ;reached end of card?
10$: BLT 12$ ;no, process next character
MOV #15,R1 ;yes, send crlf to ascii file
CALL MSGAPC
MOV #12,R1
CALL MSGAPC
CLR TCHPS(R5) ;now back to left margin
BR 12$ ;process next character
; here at end of chunk. get next chunk and process it, if any.
14$: MOV (SP)+,R2 ;point to next chunk
BNE 11$ ;process it, if any.
; here when the message is complete. give an extra crlf
; if necessary.
TST TCHPS(R5) ;odd length line?
BEQ 15$ ;no.
MOV #15,R1 ;yes, give extra crlf
CALL MSGAPC
MOV #12,R1
CALL MSGAPC
15$: CLC ;give ok return
RETURN
.SBTTL XLIPRS - translate printer character from ASCII to EBCDIC
; subroutine to process an irs character in printer mode.
; do the indicated carriage control.
XLIPRS: MOVB TCCCI(R5),R1 ;get char after escape ("/" if none)
MOVB ASCEBC+'/,TCCCI(R5) ;return to single space
CMPB ASCEBC+'M,R1 ;overprint request?
BEQ 14$ ;yes.
CMPB ASCEBC+'A,R1 ;no, skip to top of form?
BEQ 15$ ;yes.
CMPB ASCEBC+'/,R1 ;no, single space?
BEQ 13$ ;yes.
CMPB ASCEBC+'S,R1 ;no, double space?
BEQ 12$ ;yes.
CMPB ASCEBC+'T,R1 ;no, triple space?
BEQ 11$ ;yes.
; if unrecognized carriage control, treat as single space.
BR 13$ ;single space by default
; here on triple space
11$: CALL XLIPSP ;space once
; here on double space
12$: CALL XLIPSP ;space once
; here on single space
13$: CALL XLIPSP ;space once
BR 16$ ;process next character
; here on overprint request
14$: CALL XLIPCR ;just send carriage return
BR 16$ ;process next character
; here on top of form
15$: CALL XLIPTF ;go to top of next page
; here to give successful return. worry about eating all of cpu.
16$: CLC ;indicate no error
17$: RETURN
; subroutine to clear hpos and output a carriage return
; if necessary.
XLIPCR: TST TCHPS(R5) ;already at left margin?
BEQ 11$ ;yes, don't need carriage return.
MOV #15,R1 ;no, send carriage return
CALL MSGAPC ;put in user's buffer
CLR TCHPS(R5) ;horizontal position now = 0
11$: RETURN
; subroutine to space the printer once, returning
; the carriage if necessary and counting vpos.
XLIPSP: CALL XLIPCR ;set hpos = 0
CMP TCVPS(R5),#59. ;getting into perforations?
BLT 11$ ;no.
MOV #23,R1 ;yes, use special spacing command
BR 12$
; here if still in body of page. use normal line feed.
11$: MOV #12,R1 ;line feed
12$: CALL MSGAPC ;put char in user's buffer
INC TCVPS(R5) ;increment vpos
CMP TCVPS(R5),#66. ;reached top of next page?
BNE 13$ ;no.
CLR TCVPS(R5) ;yes, we are now at top of next page
13$: CLC ;no errors
14$: RETURN
; subroutine to go to top of form.
XLIPTF: CALL XLIPCR ;set hpos = 0
MOV #14,R1 ;form feed
CALL MSGAPC ;put in user's buffer
CLR TCVPS(R5) ;set vpos = 0
RETURN
.SBTTL XLIPGS - generate the count of blanks after IGS
; subroutine to process the character following an "igs".
; r1 = the character following the "igs". this is interpreted
; as a count of blanks plus the code for an ebcdic blank.
XLIPGS: BIC #TCIGS,TCST2(R5) ;we are no longer right after an igs.
SUB #EBCBLK,R1 ;convert to blank count
BEQ 12$ ;count is zero
SAVE R2
MOV R1,R2
ADD R2,TCHPS(R5)
MOV #' ,R1 ;get a blank
CALL MSGAPN ;append to output message
RESTOR R2
12$: CLC ;indicate success
RETURN
.SBTTL XLISHT - set horizontal tab stops from input message
; subroutine to set horizontal tab stops. the tab stops are set
; based on an ebcdic message consisiting of "esc ht" followed
; by a series of blanks and "ht"'s, ended by an nl.
; a tab stop is placed for each ht and cleared for each blank.
XLISHT: MOV R0,-(SP) ;save r0
MOV R5,R0 ;build pointer to tchfu
ADD #TCHFU,R0
MOV #<160./16.>,R1 ;length of tab buffer
11$: CLR (R0)+ ;clear out tabs buffer
SOB R1,11$ ; ... all of it.
CLR TCHPS(R5) ;start at left margin
12$: TST R3 ;any characters left in this chunk?
BNE 13$ ;yes, get the next character.
MOV 4(SP),R2 ;no, get next chunk
BEQ 20$ ;end of message, this is not allowed.
MOV (R2)+,4(SP) ;store pointer to next chunk
MOV (R2)+,R3 ;put count in r3
BR 12$ ;get first char in this chunk
13$: DEC R3 ;decrement count of chars in this chunk
MOVB (R2)+,R1 ;get next char from this chunk
MOV #EBCNL,R0 ;get ending character
BIT #TCOBS,TCFG1(R5) ;old bsc protocol?
BEQ 14$ ;no, nl is right.
MOV #EBCIRS,R0 ;yes, check for the irs substituted by
; the bsc task for the ius
; that ended the record.
14$: CMPB R0,R1 ;have we the end character?
BEQ 19$ ;yes, all done.
CMPB #EBCHT,R1 ;no, "ht" character?
BEQ 15$ ;yes, set tab stop
CMPB #EBCBLK,R1 ;no, a blank?
BEQ 18$ ;yes, tab stop is clear.
STOPCD HTS ;error in setting horiz. tabs.
; here to set a horizontal tab stop.
15$: MOV TCHPS(R5),R1 ;get current horiz. position
BIC #177760,R1 ;leave only low-order 4 bits
MOV #1,R0 ;build mask in r0
16$: TST R1 ;mask need any more rotation?
; (note this clears c for the rol)
BEQ 17$ ;no, done.
ROL R0 ;yes, rotate left one.
DEC R1 ;decrement count of rotations
BR 16$ ;do the rest of the rotations
17$: MOV TCHPS(R5),R1 ;get hpos again
ASR R1 ; hpos/2
ASR R1 ; hpos/4
ASR R1 ; hpos/8
BIC #1,R1 ; hpos/16 * 2 for word addressing
ADD R5,R1 ;build pointer to tchfu
BIS R0,TCHFU(R1) ;set tab stop bit
; here on space and from above on ht.
18$: INC TCHPS(R5) ;next horizontal position
CMP TCHPS(R5),#160. ;too many?
BLE 12$ ;no, get next character
STOPCD HTS ;yes, error in horiz. tab setting
; here on nl from an ibm 3780 or end of record from an ibm 2780.
; this is the end of the tab setting message.
19$: CLR TCHPS(R5) ;back to left margin
MOV (SP)+,R0 ;restore r0
RETURN
; here if the message ends before the nl or irs. this is not allowed.
20$: STOPCD HTS ;end of message before nl or irs
.SBTTL XLIPHT - process input horizontal tab
; subroutine to process a horizontal tab found in the
; data stream.
XLIPHT: MOV #' ,R1 ;send a blank to the '10
CALL MSGAPC
INC TCHPS(R5) ;increment horizontal position
MOV R0,-(SP) ;save r0
MOV TCHPS(R5),R1 ;get current horiz. position
CMP R1,#160. ;reached end of line?
BGE 13$ ;yes, return.
MOV #1,R0 ;build mask for tab bit
BIC #177760,R1 ;no, mask out all but bit index
BEQ 12$ ;yes.
11$: CLC
ROL R0 ;rotate left one
SOB R1,11$
12$: MOV TCHPS(R5),R1 ;get horiz. position again
ASR R1 ; hpos/2
ASR R1 ; hpos/4
ASR R1 ; hpos/8
BIC #1,R1 ; hpos/16 * 2 for word addressing
ADD R5,R1 ;build pointer to tchfu
BIT R0,TCHFU(R1) ;is there a tab stop here?
BNE 13$ ;yes, stop.
MOV (SP)+,R0 ;no, restore r0
BR XLIPHT ; and give another space.
; here when we have reached a tab stop or end of line.
13$: MOV (SP)+,R0 ;restore r0
CLC ;indicate success
14$: RETURN
.SBTTL ASCSPC - ASCII special control character table
; ascii special character table for control characters
; 0 1 2 3 4 5 6 7
ASCSPC: .BYTE 000,000,000,000,000,000,000,000 ;000-007
.BYTE 000,002,012,012,010,006,000,000 ;010-017
.BYTE 012,012,012,012,012,000,000,000 ;020-027
.BYTE 000,000,000,000,000,000,000,000 ;030-037
; 0 1 2 3 4 5 6 7
;
; special code assignments used in table ascspc
;
; 000 = invalid character -- ignore
; 002 = horizontal tab character
; 004 = escape character (not currently used)
; 006 = carriage return character
; 010 = form feed character
; 012 = other vertical carriage control character
;
.SBTTL EBCSPC - EBCDIC special control character table
; ebcdic special character table
;
; 0 1 2 3 4 5 6 7
; 8 9 a b c d e f
EBCSPC: .BYTE 000,000,000,006,000,000,000,000 ;00-07
.BYTE 000,000,000,000,000,000,000,000 ;08-0f
.BYTE 016,000,000,000,000,000,000,000 ;10-17
.BYTE 000,000,000,000,000,000,012,010 ;18-1f
.BYTE 000,000,000,000,000,000,004,000 ;20-27
.BYTE 000,000,000,000,000,014,000,000 ;28-2f
.BYTE 000,000,002,000,000,000,000,000 ;30-37
.BYTE 000,000,000,000,000,000,000,000 ;38-3f
; 0 1 2 3 4 5 6 7
; 8 9 a b c d e f
;
; special code assignments used in table ebcspc
;
; 000 = miscellaneous (none of those below)
; 002 = syn
; 004 = etb
; 006 = etx
; 010 = ius
; 012 = irs
; 014 = enq
; 016 = dle
;
.SBTTL XLVFU - carriage control tape
; carriage control tape, for simulating an lp10
XLVFU: .BYTE 000 ; not used
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 055 ; 3-5-6-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 057 ; 3-5-6-7-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 175 ; 2-3-4-5-6-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 057 ; 3-5-6-7-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 055 ; 3-5-6-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE -1 ;flag end of tape
; translate table to convert a vertical motion character into
; a channel number for indexing into the vfu table.
XLLPCH: .BYTE 001 ;lf = channel 8
.BYTE 002 ;vt = channel 7
.BYTE 0,0,0,0 ;not vertical motion chars (14-17)
.BYTE 100 ;dle = channel 2
.BYTE 040 ;dc1 = channel 3
.BYTE 020 ;dc2 = channel 4
.BYTE 010 ;dc3 = channel 5
.BYTE 004 ;dc4 = channel 6
.EVEN ;be sure next section starts
; on a word boundry