Trailing-Edge
-
PDP-10 Archives
-
tops10_tools_bb-fp64b-sb
-
10,7/amis/ttyio.mac
There are no other files named ttyio.mac in the archive.
TITLE TTYIO - Low level terminal routines and PSI control for AMIS.
SUBTTL Macros, definments and such things.
SEARCH UUOSYM,MACTEN ;Needed external symbols
SALL ;Listing control
TWOSEG 600000 ;Make this a two segment program
IFNDEF F$DBUG,<F$DBUG==0> ;Assume not debugging
IFNDEF F$KSYS,<F$KSYS==-1> ;Default for KSYS warnings
IFNDEF F$OPAR,<F$OPAR==-1> ;Default for output parity
IFNDEF F$META,<F$META==-1> ;Default for TERMINAL META TRMOP.
IFNDEF F$SUBT,<F$SUBT==-1> ;Default for TERMINAL SUBTYPE TRMOP.
IFNDEF BUFSIZ,<BUFSIZ==20> ;Default buffer size is 20 words
IFNDEF CCMAX,<CCMAX==3> ;Default is 3 ^C to break
IFNDEF MBFTIM,<MBFTIM==500> ;Default wakeup time (milliseconds)
IFNDEF PDLLEN,<PDLLEN==150> ;Default length of interrupt stack
IFNDEF TAHSIZ,<TAHSIZ==200> ;Default type ahead size (chars)
IFNDEF .TOMET,<.TOMET==1770> ;Local TRMOP., for TERMINAL [NO] META.
IFNDEF .TOSUB,<.TOSUB==1767> ;Local TRMOP., for TERMINAL SUBTYPE xxx.
IFNDEF .TOFLO,<.TOFLO==1764> ;Local TRMOP., for TERMINAL [NO] FLOWCONTROL.
METACH==200 ;The meta bit in a character
OPDEF CALL[ PUSHJ P,]
TTY==1 ;Channel to open TTY: on.
PTY==3 ;Channel to push to exec on.
STRSIZE==^D40 ;Length of strings.
T0==0
T1==1
T2==2
T3==3
T4==4
T5==5
T6==6
T7==7
P==17
SUBTTL BUG - Print bug message and exit to monitor
BUG:: SETZM RUNFIL## ;Really don't run anything after this...
PUSH P,T2 ;Save argument
MOVEI T2,[BYTE(7) "?",.CHCRT,.CHLFD,"?",.CHNUL]
CALL OUTSTR ;Print start of bug message
POP P,T7 ;Restore argument into T7
HRLI T7,(POINT 7) ;Make T7 a byte pointer to the string
MOVEI T3,STRSIZE ;Get length of string
BUG1: ILDB T2,T7 ;Get a character
JUMPE T2,BUG.2 ;If it's a <NUL>, break,
CALL TTYWRITE ; else print it
SOJG T3,BUG1 ; and loop back if more
BUG.2: CALL MONITOR ;Kick him out
MOVEI T2,[ASCIZ "Use the monitor command 'REENTER' to restart."]
CALL OUTSTR ;Print string
JRST BUG.2 ; and loop back to monitor
SUBTTL DAYTIME - Give back a string containing date and time
DAYTIM::CALL BLANKS ;Clear string
HRLI T2,(POINT 7) ;Make T2 a byte pointer to string
MOVE T0,[%CNYER]
GETTAB T0, ;Get current year
SETZ T0,
IDIVI T0,^D100 ;Divide into first and last digit pairs
PUSH P,T0+1 ;Save last two digits
CALL TWODIG ;Put first two in string
POP P,T0 ;Get last two digits again
CALL TWODIG ;Deposit them too
MOVEI T0,"-" ;Get a hyphen
IDPB T0,T2 ;Deposit it
MOVE T0,[%CNMON]
GETTAB T0, ;Get current month
SETZ T0,
CALL TWODIG ;Deposit them
MOVEI T0,"-" ;Get a hyphen
IDPB T0,T2 ;Deposit it
MOVE T0,[%CNDAY]
GETTAB T0, ;Get current day
SETZ T0,
CALL TWODIG ;Deposit day
MOVEI T0," " ;Get a space
IDPB T0,T2 ;Put it in string
MOVE T0,[%CNHOR]
GETTAB T0, ;Get current hour
SETZ T0,
CALL TWODIG ;Put hour in string
MOVEI T0,":" ;Get a colon
IDPB T0,T2 ;Put it into string
MOVE T0,[%CNMIN]
GETTAB T0, ;Get current minute
SETZ T0,
CALL TWODIG ;Put minutes into string
MOVEI T0,":" ;Get a colon again
IDPB T0,T2 ;Put it into string
MOVE T0,[%CNSEC]
GETTAB T0, ;Get current seconds
SETZ T0,
TWODIG: IDIVI T0,^D10 ;Divide argument into first and second
ADDI T0,"0" ; digits, then make them ascii chars.
ADDI T0+1,"0"
IDPB T0,T2 ;Deposit first...
IDPB T0+1,T2 ; then second digit into goal string
POPJ P,
SUBTTL GetVersion -- Get current version number, encode in string arg.
GETVER::PUSHJ P,BLANKS ;Blank out string.
HRLI T2,(POINT 7) ;Make a byte pointer.
SKIPA T3,[
POINT 7,[ ;1234567890123456789012345678901234567890
ASCIZ "Tops-10 AMIS, Version 1C, edit # "]]
GVER.2: IDPB T0,T2 ;Store in string.
ILDB T0,T3 ;Load next byte.
JUMPN T0,GVER.2 ;Loop until null.
HRRZ T3,.JBVER ;Get edit number.
IDIVI T3,^O100 ;Divide away first digit of three.
IDIVI T4,^O10 ;Split second and third digit.
MOVEI T3,"0"(T3) ;Make a digit.
IDPB T3,T2 ;Store it.
MOVEI T3,"0"(T4) ;Make a digit.
IDPB T3,T2 ;Store it.
MOVEI T3,"0"(T5) ;Make a digit.
IDPB T3,T2 ;Store it.
POPJ P, ;All done!
SUBTTL DETACH - Leave AMIS and visit your local Chinese restaurant
DETACH::CALL TTYCLOSE ;Reset terminal parameters
MOVEI T2,[ASCIZ "From job "]
CALL OUTSTR
PJOB T2,
MOVEI T3,^D10
CALL OUTNUM
MOVEI T2,[ASCIZ "
."]
CALL OUTSTR
CALL TTYWRITE ; write it out,
CALL TTYFORCE ; and force the buffer!
MOVSI T1,-1
ATTACH T1, ;Detach
JFCL ; Well...
POPJ P,
SUBTTL MONITOR - Return to operating system
MONITO::CALL TTYCLOSE ;Reset terminal parameters
MOVE T1,[
PS.FRC+[.PCDAT
XWD VECDAT-VECTOR,0
EXP 0]]
PISYS. T1, ;Remove attach/detach trap
JFCL ;Ignore error here
SKIPN RUNFIL## ;Shall we do /RUN?
JRST MONI.2 ; No, handle normally.
MOVEI T1,RUNBLK## ;Load address of run block.
RUN T1, ;Start the program.
HALT ;This shall not return.
MONI.2: MONRT. ;Go to operating system
MOVE T1,[
PS.FAC+[.PCDAT
XWD VECDAT-VECTOR,0
EXP 0]]
PISYS. T1, ;Restore attach/detach trap
JFCL ;Ignore error here
CALL TTYFLUSH ;Clear internal buffer
SETZM CCCNT ;Reset ^C counter
CALL TTYOPEN ;Set terminal parameters again
MOVE T2,TTFLOW ;Set pref. XonXoff state.
CALL XONXOFF
MOVE T2,ACTSTR ;Get address of activation string
JRST OUTLST ;Print it
SUBTTL NOINT & OKINT - disable/enable interrupts.
NOINT:: AOS INHIBIT
POPJ P,
OKINT:: SOS INHIBIT
SKIPE CCDONE ;Any deferred interrupt?
CALL MONITOR ;Yes, exit now.
SETZM CCDONE ;Wipe flag
POPJ P,
SUBTTL PPUSH - Push to exec routine
PPUSH:: MOVEM T2,BRKCHR ;Save break character
MOVEI T1,PTY ;Get PTY channel #
GETCHR T1, ;Get device characteristics
JUMPN T1,PPUSH1 ;If not zero, we already got PTY open
OPEN PTY,[
EXP UU.FSP!.IOASC
SIXBIT /PTY/
XWD PTOBUF,PTIBUF]
JRST RFALSE ;Can't push.
MOVE T1,[ ;Set up PTY buffer headers
XWD 400K,PIBUF1+1]
MOVEM T1,PTIBUF+.BFADR
HRRI T1,POBUF1+1
MOVEM T1,PTOBUF+.BFADR
MOVE T1,[
POINT ^D7,0,35]
MOVEM T1,PTIBUF+.BFPTR
MOVEM T1,PTOBUF+.BFPTR
SETZM PTIBUF+.BFCTR
SETZM PTOBUF+.BFCTR
HRLI T1,BUFSIZ+1 ;Get buffer size, plus one
HRRI T1,PIBUF2+.BFHDR ;Set up PTY buffers
MOVEM T1,PIBUF1+.BFHDR
HRRI T1,PIBUF1+.BFHDR
MOVEM T1,PIBUF2+.BFHDR
HRRI T1,POBUF2+.BFHDR
MOVEM T1,POBUF1+.BFHDR
HRRI T1,POBUF1+.BFHDR
MOVEM T1,POBUF2+.BFHDR
SETZM VECPID+.PSVFL
MOVE T1,[
PS.FAC+[EXP PTY
XWD VECPID-VECTOR,PS.RID
EXP 0]]
PISYS. T1, ;Add input done interrupts on PTY
JRST RFALSE ; Can't add? No push then
; Here to give commands to the PTY to set up terminal type.
MOVEI T2,"." ;Get a dot
CALL TTYWRITE ;Play monitor for a while...
MOVEI T1,[ASCIZ "TERMINAL TYPE "]
CALL PTY7ST ;Give string to PTY
move t1,tttype
CALL PTY6WD ;Give sixbit word to PTY
define $tell(flag,command),<
movei t1,[asciz " NO"]
skipn flag
call pty7st
movei t1,[asciz " 'command'"]
call pty7st
>;$tell macro
$tell(ttpage,PAGE)
$tell(tttab,TAB)
$tell(ttform,FORM)
$tell(ttdefr,DEFER)
movei t1,[byte (7).CHCRT,.CHNUL]
pushj p,pty7st ;Terminate command.
jrst ppush2 ;No need to add interrups again.
PPUSH1: SETZM VECPID+.PSVFL
MOVE T1,[
PS.FAC+[EXP PTY
XWD VECPID-VECTOR,PS.RID
EXP 0]]
PISYS. T1, ;Add input done interrupts on PTY
JRST RFALSE ; Can't add? No push then
MOVEI T1,PTY ;Get subjob channel
JOBSTS T1, ;Get subjob info
JRST PPUSH2 ; Hmmmmm... Lose some.
ANDI T1,JB.UJN ;Extract job #
HRLS T1 ;Job # to left half...
HRRI T1,'WAK' ;Function code == wake it up
PIJBI. T1, ;Rrrrrrriiiiiinnnnngggg!
JFCL ; Nobody home, I presume.
PPUSH2: MOVE T2,DEASTR ;Get pointer to deactivation string
CALL OUTLST ;Deactivate terminal
SKIPN CHRCNT ;Type ahead buffer empty?
JRST PPUSH4 ; Yes, go start looping
PPUSH3: CALL TTYREAD ;Read the char from type ahead
SOSGE PTOBUF+.BFCTR ;Room in output buffer?
OUTPUT PTY, ; No, make some
IDPB T1,PTOBUF+.BFPTR ;Deposit character
SKIPE CHRCNT ;Type ahead buffer empty now?
JRST PPUSH3 ; No, get next byte
OUTPUT PTY, ;Yes, force out PTY output buffer
PPUSH4: SETOM PUSHED ;We are pushed now...
PPUSH5: PUSHJ P,PTYSHF ;Shuffle eventual data from PTY.
MOVEI T1,^D60*^D1000 ;Get sleep time
HIBER T1,
JFCL
SKIPE PUSHED ;Break loop if we are not pushed.
JRST PPUSH5
MOVE T1,[
PS.FRC+[EXP PTY
XWD VECPID-VECTOR,PS.RID
EXP 0]]
PISYS. T1,
JFCL
MOVE T2,ACTSTR ;Get pointer to activation string
CALL OUTLST ;Activate terminal
CALL TTYFORCE
MOVEI T1,PTY ;Get PTY channel number
JOBSTS T1, ;Get Status for subjob
setz t1,
TLNN T1,(JB.ULI) ;Job logged in on PTY?
RELEAS PTY, ; No, don't hold up the PTY
rtrue: MOVEI T1,1 ;Return true
MOVEM T1,1(P)
POPJ P,
rfalse: SETZM 1(P) ;Return false
POPJ P,
SUBTTL RUNCOM - Start compil with runoffset 1
RUNCOM::CALL TTYCLOSE ;Reset line parameters
MOVSI T1,1 ;Runoffset
HRRI T1,RUNCMP ;Address of run block
RUN T1,UU.PHY ;Run the program, from physical SYS:
HALT .
RUNCMP: SIXBIT /SYS/ ;Device
SIXBIT /COMPIL/ ;Program
Z ;Unused
Z ;Unused
Z ;Unused
Z ;Unused
SUBTTL TTYACTIVATION - Get addresses of (de)activation strings.
TTYACT::MOVEM T2,ACTSTR ;Save pointer to activation
MOVEM T3,DEASTR ; and deactivation string
JRST OUTLST ;Go give activation string to TTY
SUBTTL TTYCHECK - Look if terminal input buffer is empty
TTYCHE::SETZM 1(P) ;Assume we return FALSE
SKIPE CHRCNT ;Is type ahead buffer empty?
JRST TTYCH2 ; No, go return TRUE
JUMPE T2,TTYCH3 ;We go sync output buffer?
IMULI T2,^D1000 ;Convert seconds to milliseconds
HRRZ T2,T2 ;Clear flag bits in ac
HIBER T2, ;Take a nap
JFCL ;Just ignore error on this one
TTYCH1: SKIPE CHRCNT ;Wake up, look again
TTYCH2: AOS 1(P) ; Make result TRUE
POPJ P, ;Go back
TTYCH3: CALL TTYFORCE ;Force output buffer
SETZM 1(P) ;Reset top of stack
JRST TTYCH1 ;Go look again
SUBTTL TTYFLUSH - Flush terminal input buffer
TTYFLU::MOVE T1,TAHPTR
MOVEM T1,TAHGET
MOVEM T1,TAHPUT
SETZM CHRCNT
MOVEI T1,TAHSIZ
MOVEM T1,CHRGET
MOVEM T1,CHRPUT
MOVEM T1,CHREMP
POPJ P,
SUBTTL TTYFORCE - Force output buffer
TTYFOR::SKIPE DTACHD ;Are we detached?
POPJ P, ; Yep, keep quiet
MOVSI T1,770000
TDNN T1,TTOBUF+.BFPTR ;Anything in buffer?
POPJ P, ; No, nothing to do.
OUT TTY, ;Try force out the buffer
JRST TTYFO2 ;All OK? go syncronize with monitor
MOVEI T1,^D300
HIBER T1, ;Else wait a while...
JFCL
JRST TTYFOR
TTYFO2: MOVE T1,[
XWD 2,[
.TOTOC
-1]]
TRMOP. T1, ;Read # of chars in monitor buffer
POPJ P, ;If we can't read, just return
IMUL T1,FUDGEF ;Estimate I/O time
SUBI T1,MBFTIM ; and wake a moment earlier...
JUMPLE T1,TTYFO3 ;Shall we go to bed, madam?
HIBER T1,
JFCL
TTYFO3: POPJ P,
SUBTTL TTYHACKER - Set/reset hackmatic terminal flag
TTYHAC::MOVEM T2,HACKER ;Save new hackmatic terminal flag
IFN F$META,<
MOVEI T0,.TOMET+.TOSET ;Load function code.
SETO T1, ;Argument = my terminal.
MOVX T3,<3,,T0> ;Arg for TRMOP.
TRMOP. T3, ;Tell monitor too.
JFCL ; Ignore error, possibly not implemented here.
>;End of IFN F$META
POPJ P,
;*
;* Here to read the initial setting of .TOMET from monitor. Called directly
;* by MAIN.PAS, as a temporary kludge.
;*
IFN F$META,<
TTYMET::MOVE T1,[ ;Load up the arguments.
XWD 2,[
EXP .TOMET
EXP -1]]
TRMOP. T1, ;Ask monitor.
SETZ T1, ; Default not meta key on terminal.
MOVEM T1,1(P) ;Tell MAIN.PAS.
MOVEM T1,HACKER ;Also remember for TTYREAD.
POPJ P, ;Return cheerfully.
>;End of IFN F$META
; TTYPROTOCOL - decide if to use ^S/^Q as commands or flow control.
TTYPRO::move t1,[xwd 2,[exp .toflo,-1]]
trmop. t1,
movei t1,0 ; Default is NO FLOWCONTROL.
jumpe t1,rfalse ;Zero means use as commands.
jrst rtrue ;Non-zero means flow control.
SUBTTL TTYINIT - Init terminal handler
TTYINI::MOVEI T2,TTY ;Try to prevent ?Address check...
RESDV. T2, ;Release channel if it is there,
JFCL ; ignore errors.
MOVE T2,[XWD 2,[EXP .TODEM,-1]]
TRMOP. T2, ;Read TERMINAL DEFER setting.
SETZ T2, ; If error, assume NO DEFER.
movem t2,ttdefr ;Save flag for later use.
JUMPE T2,FRITZ ;Terminal is NO DEFER, skip kludge.
MOVE T1,[XWD 3,[EXP .TODEM+.TOSET,-1,0]]
TRMOP. T1, ;Set NO DEFER
JRST FROTZ ; Well, skip this then.
FRITZ: OPEN TTY,[ ;Open then terminal in NOECHO mode,
EXP IO.SUP ; to bypass bug in TOPS-10.
SIXBIT /TTY/
EXP 0]
JFCL ; Don't care if this fails.
SETZ T1, ;Clear T1.
SLEEP T1, ;Take a short nap.
JUMPE T2,FROTZ ;Don't set DEFER if it was off initially.
MOVE T1,[XWD 3,[EXP .TODEM+.TOSET,-1,1]]
TRMOP. T1, ;Set DEFER back on.
JFCL ; Ignore error.
FROTZ: OPEN TTY,[ ;Continue and assume SCNSER is in phase now.
EXP UU.AIO!.IOPIM!UU.PHS
SIXBIT /TTY/
XWD TTOBUF,TTIBUF]
HALT . ; Too bad...
MOVEI T1,TTY
IONDX. T1, ;Get UDX for TTY:
SETO T1, ; Can't happen, but...
MOVEM T1,TTUDX ;Save UDX
define $read(func,save,default<0>),<
movei t1,func
pushj p,dtrmop
movx t1,<default>
movem t1,save
>;$read macro
$read(.totrm,tttype,<sixbit'TTY '>)
$read(.topag,ttpage,1)
$read(.totab,tttab)
$read(.tofrm,ttform)
movei t1,.topbs+.toset;Set an empty PIM mode break set.
movei t3,0
pushj p,dtrmop
jfcl ;Ignore error.
; Set up buffer pointers
MOVE T1,[XWD 400K,TIBUF1+1]
MOVEM T1,TTIBUF+.BFADR
HRRI T1,TOBUF1+1
MOVEM T1,TTOBUF+.BFADR
MOVE T1,[POINT ^D8,0,35]
MOVEM T1,TTIBUF+.BFPTR
MOVEM T1,TTOBUF+.BFPTR
SETZM TTIBUF+.BFCTR
SETZM TTOBUF+.BFCTR
HRLI T1,BUFSIZ+1
HRRI T1,TIBUF2+.BFHDR ;Set up TTY buffers
MOVEM T1,TIBUF1+.BFHDR
HRRI T1,TIBUF1+.BFHDR
MOVEM T1,TIBUF2+.BFHDR
HRRI T1,TOBUF2+.BFHDR
MOVEM T1,TOBUF1+.BFHDR
HRRI T1,TOBUF1+.BFHDR
MOVEM T1,TOBUF2+.BFHDR
CALL TTYFLUSH ;Get a clean taye ahead buffer
; TTYINIT - Set up PSI system for us
MOVEI T1,VECTOR
PIINI. T1,
JRST PISYSE
setzm vectim+.psvfl
move t1,[
ps.fac+[.pctmr
xwd vectim-vector,0
exp 0]]
pisys. t1,
jfcl ;Oh my.
SETZM VECDAT+.PSVFL
MOVE T1,[
PS.FAC+[.PCDAT
XWD VECDAT-VECTOR,0
EXP 0]]
PISYS. T1,
jfcl ;Funny to have, but...
SETZM VECJBI+.PSVFL
MOVE T1,[
PS.FAC+[.PCJBI
XWD VECJBI-VECTOR,0
EXP 0]]
PISYS. T1,
jfcl ;Funny to have, but...
SETZM VECRID+.PSVFL
MOVE T1,[
PS.FAC+[EXP TTY
XWD VECRID-VECTOR,PS.RID
EXP 0]]
PISYS. T1,
JRST PISYSE
SETZM VECTLE+.PSVFL
MOVE T1,[
PS.FAC+[.PCTLE
XWD VECTLE-VECTOR,0
EXP 0]]
PISYS. T1,
JRST PISYSE
IFN F$KSYS,<
MOVE T1,[
PS.FAC+[.PCKSY
XWD VECKSY-VECTOR,0
EXP 0]]
PISYS. T1,
jfcl ;Funny to have, but...
>;End of IFN F$KSYS
MOVSI T1,(PS.FON)
PISYS. T1,
JRST PISYSE
setom timflg ;Fudge up a timer interrupt.
SETZM CCCNT ;We have not seen any ^C yet
SETZM DTACHD ; and we are not detached
SETZM INHIBIT ;Interrupts are allowed right now
SETZM CCDONE ;But none pending.
setzm savttp ;For terminal type listings.
CALL TTYOPEN ;Set up the rest of the terminal junk
JRST INDONE ;Simulate input done, pick up typeahead
;Routine to do a TRMOP. for our terminal.
dtrmop: move t2,ttudx ;Load UDX.
move t4,[3,,t1]
trmop. t4, ;Perform the function
popj p, ; Non-skip return on failure.
move t1,t4 ;Return value in T1.
aos (p) ;Do skip return.
popj p,
SUBTTL TTYREAD - Read one character.
TTYREA::SKIPG CHRCNT ;Anything to read?
CALL WAITER ; No, go wait for some
ILDB T1,TAHGET ;Yes, get it
SKIPN HACKER ;Using hackmatic terminal?
ANDI T1,177 ;No, get rid of parity bit
TRNE T1,200 ;Meta bit?
TRC T1,200+400 ; Yes, shift it one step left.
MOVEM T1,1(P) ;Give it to pascal
SOS CHRCNT
AOS CHREMP ;Fix up buffer pointers
SOSLE CHRGET ;Need to wrap get pointer yet?
POPJ P, ; No, return
MOVE T1,TAHPTR ;Yes, do the wrap
MOVEM T1,TAHGET
MOVEI T1,TAHSIZ
MOVEM T1,CHRGET
POPJ P,
WAITER: PUSHJ P,TTYFORCE ;Force output buffer meanwhile
wait.2: movx t2,<sleep t2,> ;Load instruction
movem t2,hibloc ;Set up for sleeping.
skipe chrcnt ;Still empty?
popj p, ; Nope, done waiting
IFN F$KSYS,<
SKIPE KSYMSG ;Any KSYS message to print?
PUSHJ P,KSYOUT ; Yes, go do it.
>;End of IFN F$KSYS
skipe timflg ;Timer interrupt?
pushj p,clkupd ; Yes, update clock.
movei t2,^D60 ;Load time to sleep.
xct hibloc ;Sleep or JFCL.
jrst wait.2 ;Loop back and try again.
clkupd: setzm timflg ;Clear flag until next time.
mstime t2, ;Get time of day.
idivi t2,^D60000 ;Compute milliseconds until next interrupt.
movei t2,^D60000
subi t2,(t3)
tlo t2,(1B0)
pitmr. t2, ;Request interrupt.
jfcl ; Oh my...
push p,0 ;Push a dummy word (stack frame)
pushj p,TimeStamp## ;Call mode line clock update routine
pop p,(p) ;Trim off stack (standard method)
jrst ttyforce ;Return after a good work (and force buffer)
;*
;* PROCEDURE GetClock(VAR Hour, Minute: integer);
;* This routine are used to get values for mode line clock.
;*
getclo::mstime t4, ;Get time of day, in milliseconds.
idivi t4,^D1000*^D60 ;Get time of day, in minutes.
idivi t4,^D60 ;Split into hours and minutes.
movem t4,(t2) ;Return hours.
movem t5,(t3) ;Return minutes.
popj p, ;Return to caller
SUBTTL TTYSPEED - Read terminal speed from monitor
TTYSPE::MOVEI T1,.TOTSP
pushj p,dtrmop
SETZ T1, ;If error, assume 0
MOVE T1,SPDTAB(T1) ;Map speed code to baude rate
MOVEM T1,1(P) ;Give back
POPJ P,
SPDTAB: EXP ^D0 ;Code 0 ...
EXP ^D50
EXP ^D75
EXP ^D110
EXP ^D134
EXP ^D150
EXP ^D200
EXP ^D300
EXP ^D600
EXP ^D1200
EXP ^D1800
EXP ^D2400
EXP ^D4800
EXP ^D9600
EXP ^D19200
EXP ^D0 ; ... 17 ( Octal )
SUBTTL TTYTYPE - Give terminal type in special code
TTYTYP::MOVE T6,T2 ;Save pointer to TERM string
SETZM 0(T2) ;Clear first word in string
SETZM 1(T2) ;Clear second word in string
MOVE T3,[ ;Read TMPcore file, arg block in T4-T5
XWD .TCRRF,T4]
DMOVE T4,[
XWD 'TRM',0 ;File name is TMP:TRM,
IOWD 2,10] ; read two words into AC 10 and 11
TMPCOR T3,
JRST TTYTY3 ;TMP:TRM not found, use TRMOP.(.TOTRM)
JUMPE T3,TTYTY3 ;Use TRMOP. if file is empty, too
MOVE T4,[ ;Get a byte pointer to file
POINT 7,10]
MOVE T5,[ ;Get a byte pointer to SIXBIT word
POINT 6,T1]
SETZ T1,
MOVEI T7,6 ;Max. # of characters in a SIXBIT word
TTYTY1: ILDB T3,T4 ;Get a character
CAIL T3,"a" ;Lower case alphabetic?
CAILE T3,"z"
SKIPA
SUBI T3,"a"-"A" ;Yes, make it upper case
CAIL T3,"0" ;Look if character is digit or letter
CAILE T3,"9"
SKIPA ;Not digit, look if letter
JRST TTYTY2
CAIL T3,"A"
CAILE T3,"Z"
JRST TTYTY4 ;Not letter either, break loop
TTYTY2: SUBI T3,"A"-'A' ;Convert character from ASCII to SIXBIT
IDPB T3,T5 ;Put character in SIXBIT word
SOJG T7,TTYTY1 ;Loop back if we got more room
;Now we got sixbit word in T1, go look
JRST TTYTY4 ; it up in the terminal type table.
TTYTY3:
IFN F$SUBTYP,<
MOVE T1,[XWD 2,[EXP .TOSUB,-1]]
TRMOP. T1, ;Get SUBTYPE, if we have it.
MOVEI T1,0 ; Error -- say nothing.
TLNN T1,-1 ;Left half zero?
>;End IFN F$SUBTYP
MOVE T1,tttype
ttyty4: MOVEI T7,6 ;Transfer 6 characters
HRLI T6,(POINT 7) ;Build byte pointer to TERM string
MOVE T5,[ ;Build byte pointer to SIXBIT name
POINT 6,T1]
TTYTY5: ILDB T0,T5 ;Get a byte
ADDI T0,"A"-'A' ;Make it ASCII
IDPB T0,T6 ;Give it to TERM
SOJG T7,TTYTY5 ;Loop back if more
MOVEM T1,TTNAME ;Remember the terminal name for later.
CAME T1,['VT100 '] ;Is this a VT100?
TDZA T1,T1 ; Nope, return zero.
MOVEI T1,1 ; Yes, the only one from now on...
MOVEM T1,1(P) ;Give back 0 or 3.
POPJ P,
SUBTTL BADTTY - tell user his terminal type is not supported.
BADTTY::SETZM ACTSTR ;Clear activation string pointer
SETZM DEASTR ;Clear deactivation string pointer
MOVEI T2,[
ASCIZ "
The terminal type "]
CALL OUTSTR ;Print first half of short message.
MOVE T2,TTNAME ;Get terminal name.
SETZ T3, ;Clear junk.
CALL OUTSIX ;Print terminal name.
MOVEI T2,[
ASCIZ " is not supported by AMIS.
Type 'CONTINUE' for further information.
"]
CALL OUTSTR ;Print second half of short message.
BADT.2: CALL MONITOR ;Exit to operating system.
SKIPN SAVTTP
JRST[ MOVEI T2,NTTMSG
CALL OUTSTR
JRST BADT.2]
MOVEI T2,[ASCIZ "
The following terminals are supported:
"]
CALL OUTSTR
movei t1,0
jsp t7,stor.c
MOVEI T2,SAVTTL
CALL OUTSTR
MOVEI T2,[ASCIZ "
Use the monitor command 'TERMINAL TYPE <name>' to set
the terminal type.
"]
CALL OUTSTR
JRST BADT.2
nttmsg: asciz "
There are no terminals defined. Contact your friendly systems programmer.
"
SaveTerminalName::
MOVE T4,[point 7,t2]
MOVEI t5,6
SKIPE SAVTTP ;Set up yet?
JRST ss4711 ; Yes, skip this.
setzm savnum
MOVE T1,[POINT 7,SAVTTL]
MOVEM T1,SAVTTP
MOVEI T1,<<5*SAVLEN>-1>
MOVEM T1,SAVCNT
ss4711: ildb t1,t4 ;get byte...
jsp t7,stor.c
sojg t5,ss4711 ;Maybe loop.
movei t1," "
jsp t7,stor.c
jsp t7,stor.c
aos t1,savnum
caige t1,8
popj p,
movei t1,15
jsp t7,stor.c
movei t1,12
jsp t7,stor.c
setzm savnum
popj p,
stor.c: sosle savcnt ;room?
idpb t1,savttp ; room. store.
jrst (t7) ;return.
SUBTTL TTYWIDTH - Read terminal width from monitor
TTYWID::MOVEI t1,.TOWID
pushj p,dtrmop
MOVEI T1,^D80 ;If error, assume page width is 80
MOVEM T1,1(P) ;Store the result
POPJ P,
; TTYPRINTABLE - Return set of printable chars.
TTYPRI::movei 1,<000000,,000017>
movem 1,0(2)
setom 1(2)
setom 2(2)
movx 1,<777777,,400000>
movem 1,3(2)
popj p,
SUBTTL TTYLENGTH - override default terminal length, if possible.
ttylen::push p,t2 ;Save argument.
movei t1,.tolnb
pushj p,dtrmop ;Read terminal length.
setz t1, ; Default length.
pop p,t2 ;Restore argument pointer.
jumple t1,.popj ;Don't overwrite default with junk.
movem t1,(t2) ;Store new value.
popj p, ;Return.
SUBTTL TTYWRITE - write one character.
TTYWRI::SKIPE DTACHD ;Are we detached?
POPJ P, ; Yep, keep quiet
IFN F$OPAR,<
MOVEI T1,(T2) ;Copy char
LSH T1,-4 ;Shift...
XORI T1,(T2) ;Get together...
TRCE T1,14
TRNN T1,14
TRC T2,200
TRCE T1,3
TRNN T1,3
TRC T2,200
>;End of IFN F$OPAR
SOSGE TTOBUF+.BFCTR ;Room in buffer?
JRST TTYWR2 ; No, go force out
IDPB T2,TTOBUF+.BFPTR ;Deposit
POPJ P, ;Done!
TTYWR2: OUT TTY, ;Out with the buffer
JRST TTYWRITE ; OK, but we may have been detached.
MOVEI T1,^D300 ;Time to sleep
HIBER T1, ;Take a nap
JFCL ; Ignore error return,
JRST TTYWRITE ; and hope for better luck
SUBTTL USRNAME - Put user name in argument string
USRNAM::CALL BLANKS ;Put blanks in all of string T2 points to
HRLI T2,(POINT 7) ;Make argument a byte pointer
HRROI T3,.GTNM1 ;Set up to get first
HRROI T4,.GTNM2 ; and second half of user name
GETTAB T3,
SKIPA
GETTAB T4,
SETZB T3,T4 ; In case of errors, clear both words.
USRNM1: LDB T1,[ ;Get first sixbit char
POINT ^D6,T3,^D5]
ADDI T1,"A"-'A' ;Make it ascii
IDPB T1,T2
LSHC T3,6 ;Shift both T6 and T7
JUMPN T3,USRNM1 ;Loop back if any of them
JUMPN T4,USRNM1 ; is non-zero
POPJ P,
;I/O routines for PTY
; Interrupt routine to flag data ready.
PTYDON: SETOM PTYFLG ;Remember to try to read sometime.
DEBRK. ;Dismiss interrupt.
JFCL ; Can't happen.
POPJ P, ;Can happen.
; Actual reader, called by background loop.
PTYSHF: SKIPN PTYFLG ;Any data to shuffle from PTY?
POPJ P, ; No, return now.
SETZM PTYFLG ;Yes, but clear flag.
SHFLUP: INPUT PTY, ;Get info from PTY
SKIPG PTIBUF+.BFCTR ;Did we get anything?
JRST TTYFORCE ; No more data, force terminal buffers.
SHFL.2: SOSGE PTIBUF+.BFCTR ;Decrement buffer counter
JRST SHFLUP ; No more, try for another buffer.
ILDB T2,PTIBUF+.BFPTR ;Get a byte
CALL TTYWRITE ;Write it on terminal
JRST SHFL.2 ; and loop back for more
;; Routine to give an ASCIZ string to the PTY.
PTY7ST: HRLI T1,(POINT ^D7) ;Get a byte pointer to the string
PTY7S1: ILDB T2,T1 ;Get a byte from the string
JUMPE T2,PTY7S2 ;Break on null
SOSGE PTOBUF+.BFCTR ;Look if more foom in PTY output buffer
OUTPUT PTY, ; Make more room then!
IDPB T2,PTOBUF+.BFPTR ;Deposit byte in buffer
JRST PTY7S1 ;Loop back and look if more
PTY7S2: OUTPUT PTY, ;Finally, force out the buffer
POPJ P, ; and return to caller
;; Routine to give SIXBIT word in T1 to the PTY.
PTY6WD: LDB T2,[ ;Get first character
POINT ^D6,T1,^D5]
ADDI T2,"A"-'A' ;Convert SIXBIT to ASCII
SOSGE PTOBUF+.BFCTR ;Room in buffer?
OUTPUT PTY, ; No, make some
IDPB T2,PTOBUF+.BFPTR ; then deposit character
LSH T1,6 ;Shift out one character
JUMPN T1,PTY6WD ;Loop back if more in word
OUTPUT PTY, ;No more, force out buffer
POPJ P, ; and return to caller
SUBTTL Routine to set up terminal parameters
TTYOPE: movei t1,.tocom
pushj p,dtrmop
setz t1,
jumpe t1,TTYOP1 ;Look if we are in monitor mode
movei t1,.todsp
movei t3,msgnmm
pushj p,dtrmop
jfcl
MONRT. ;Exit to monitor
JRST TTYOPEN ;Try again
TTYOP1: SETSTS TTY,.IOPIM ;Reset PIM mode on TTY
MOVEI T5,TTY ;Get TTY channel #
IONDX. T5, ;Get UDX for channel
SETO T5, ; Can't happen, but...
MOVEM T5,TTUDX ;Save UDX
CALL TTYSPEED ;Compute fudge factor
SKIPG T1,2(P)
MOVEI T1,^D9600
MOVEI T2,^D10K
IDIV T2,T1
MOVEM T2,FUDGEF ;Save new fudge factor
POPJ P,
SUBTTL Routine to reset terminal parameters
TTYCLO: MOVE T2,DEASTR ;Get address of deactivation string
CALL OUTLST ;Print string
CALL TTYFORCE ;Force out buffers
SKIPA T2,TTPAGE ;Get previous page mode setting.
;* Skip into XonXoff handler.
XONXOF::MOVEM T2,TTFLOW ;Save pref. xonxoff state.
MOVEI T0,.TOPAG+.TOSET;Function code.
MOVE T1,TTUDX ;Device index.
MOVX T3,<3,,T0> ;Argument pointer.
TRMOP. T3, ;Set new value.
JFCL ; Ignore error.
JUMPN T2,.POPJ ;If setting XonXoff mode, done.
MOVEI T0,.TOSTP+.TOSET
MOVX T3,<3,,T0> ;Else we have to make sure the terminal don't
TRMOP. T3, ; get stuck in XOFF state...
JFCL
POPJ P, ;Return.
SUBTTL Some junk...
BLANKS: MOVE T3,[ ;Blank string
BYTE(7) " "," "," "," "," "]
MOVEM T3,(T2) ;Put blanks in first word
HRL T3,T2 ;Source in left halfword
HRRI T3,1(T2) ;Dest in right
BLT T3,<STRSIZ/5>-1(T2) ;Blank rest of string
POPJ P,
OUTLST: JUMPE T2,.POPJ ;Any pointer there?
SKIPG T3,(T2) ;Anything to type out?
POPJ P,
HRRI T7,1(T2)
HRLI T7,(POINT 7)
OUTLS1: ILDB T2,T7
CALL TTYWRITE
SOJG T3,OUTLS1
.POPJ: POPJ P,
OUTSTR: MOVE T7,T2
HRLI T7,(POINT 7)
OUTST1: ILDB T2,T7
JUMPE T2,.POPJ
CALL TTYWRITE
JRST OUTST1
SUBTTL Input done interrupt routine
INDONE: MOVEM T1,INSAVE ;Save AC 1
INDON1: SOSGE TTIBUF+.BFCTR ;More chars in buffer?
JRST GETBUF ; No, go get a buffer
ILDB T1,TTIBUF+.BFPTR ;Get a char from buffer
SKIPE PUSHED ;Look if we are pushed
JRST PTYPUT ; We are, give char to PTY
INDON2: CAIE T1,.CHCNC ;Is char C-C
CAIN T1,.CHCNC+METACH ; or C-M-C?
JRST INDON4 ; Yep, go look if we had enough
SETZM CCCNT ;No, clear counter
INDON3: SOSGE CHREMP ;Is there space to put this char in?
JRST INDON5 ; Nope, go beep the user
IDPB T1,TAHPUT ;Yes, put it there
AOS CHRCNT ;Increment # of chars in buffer
SOSLE CHRPUT ;Decrement wrap pointer
JRST INDON1 ; We need not wrap yet, loop back
MOVE T1,TAHPTR
MOVEM T1,TAHPUT ;Do the wrap
MOVEI T1,TAHSIZ
MOVEM T1,CHRPUT
JRST INDON1 ;Loop back
IFN F$DBUG,< ;If debugging, pretend we have
INDON4: MOVEI T1,$0BPT##+1 ; a breakpoint at the interrupted
EXCH T1,VECRID+.PSVOP; instruction.
MOVEM T1,$0BPT##
MOVE T1,INSAVE ;Restore T1 for us
OUTSTR[ ASCIZ /
****************************************************
******** DDT (Type <ESC>P to continue) ********
****************************************************
/]
JRST INTEND ;DEBRK. rigth into DDT!
>;End IFN F$DBUG
IFE F$DBUG,<
INDON4: AOS T1,CCCNT ;Increment ^C count, put result in T1
CAIGE T1,CCMAX ;Greater than max # allowed?
JRST INDON6 ; No, go return this char
SKIPLE INHIBIT ;Are we allowed to break here?
AOSA CCDONE ; No, set flag to break as soon as possible
SKIPA
JRST INDON6 ; and forget this
MOVEM T0,SAVEB2 ;Save AC 0
MOVE T0,[ ;Set up a BLT pointer
XWD T1,SAVEB2+1]
BLT T0,SAVEB2+17 ;Save all the other AC's
MOVE T0,[
XWD PDLP2,15]
BLT T0,17 ;Move in a new stack
CALL MONITOR ;Go to operating system
MOVE T0,[ ;Get a BLT pointer
XWD SAVEB2+1,T1]
BLT T0,17 ;Restore all AC's
MOVE T0,SAVEB2 ;Restore AC 0 too
SETZM CCCNT ;Zero ^C counter
JRST INDON1 ;Loop back
>;End IFE F$DBUG
SUBTTL Continuing input done routines.
INDON5: AOS CHREMP
OUTCHR[ EXP .CHBEL]
JRST INDON1
INDON6: LDB T1,TTIBUF+.BFPTR ;Get ^C type character again
JRST INDON3 ;Go back, process as normal char
GETBUF: IN TTY,
JRST INDON1
movx t1,<jfcl>
movem t1,hibloc
MOVE T1,INSAVE
DEBRK.
jfcl ;Can't happen.
POPJ P,
OUTPUT PTY,
PTYPUT: SKIPN HACKER ;Eight bit terminal?
ANDI T1,177 ; No, mung parity bit
CAMN T1,BRKCHR ;Is this the break character?
JRST PTYPU2 ; Yep, pop it up a little
SOSGE PTOBUF+.BFCTR
JRST PTYPUT-1 ;*** Kludgy ***
IDPB T1,PTOBUF+.BFPTR
OUTPUT PTY,
JRST INDON1
PTYPU2: SETZM PUSHED
JRST INDON1
SUBTTL PSI handling -- KSYS warnings
;*
;* KSYS interrupts go here.
;*
IFN F$KSYS,<
KSYS: DMOVEM T1,KSYSAV ;Save a couple.
MOVEM T3,KSYSAV+2 ;... and another...
SKIPG T1,VECKSY+.PSVIS;Get time left until KSYS
AOJN T1,KSYS.2 ; Ignore zero, change -1 to 0.
MOVSI T2,-KSYLEN ;Load length of KSYS checkpoint table
KSYS.1: MOVS T3,KSYTAB(T2) ;Get table entry. (swapped)
CAIN T1,(T3) ;Is this the it?
HLRZM T3,KSYMSG ; Yes, remember pointer to message.
AOBJN T2,KSYS.1 ;Loop if more table
KSYS.2: MOVE T3,KSYSAV+2 ;Restore T3.
DMOVE T1,KSYSAV ;Restore T1 & T2.
JRST INTEND ;Dismiss the interrupt.
;*
;* When the time left until KSYS is equal to one of the entries in KSYTAB,
;* we issue a warning on the users terminal.
;*
KSYTAB: XWD ^D0,[ASCIZ "is over!!!"]
XWD ^D1,[ASCIZ "ends in one minute"]
XWD ^D2,[ASCIZ "ends in two minutes"]
XWD ^D5,[ASCIZ "ends in five minutes"]
XWD ^D15,[ASCIZ "ends in fifteen minutes"]
KSYLEN==.-KSYTAB
;*
;* This is the routine that gets called when KSYMSG gets non-zero.
;*
KSYOUT: MOVEI T2,[ ;Load start of KSYS message.
BYTE(7) .CHBEL, .CHCRT, .CHLFD, "*", "*"
ASCIZ "*** Timesharing "]
PUSHJ P,OUTSTR ;Print string on terminal
MOVE T2,KSYMSG ;Get main message.
PUSHJ P,OUTSTR ;Print it.
MOVEI T2,[
ASCIZ " *****"]
PUSHJ P,OUTSTR ;Print final part.
PUSHJ P,TTYFORCE ;Force out TTY buffers
SETZM KSYMSG ;We did it now, don't do it again.
POPJ P, ;Return to caller.
>;End IFN F$KSYS
SUBTTL Attach/detach trap
ATTDET: SKIPGE VECDAT+.PSVIS ;Look if it was a detach
JRST ATTDE2 ; It was
MOVEM 17,SAVEB2+17 ;Save AC 17
MOVEI 17,SAVEB2
BLT 17,SAVEB2+16 ;Save the rest
MOVE 15,PDLP2 ;Get new AC 15
DMOVE 16,PDLP2+1 ;Get new AC 16 & 17
movei t1,.todsp
movei t3,msgatt
pushj p,dtrmop
jfcl
CALL MONITOR ;Go to operating system
SETZM DTACHD
SKIPE PUSHED ;Are we pushed?
JRST ATTDE1 ; Yep, don't refresh screen.
PUSH P,1(P) ;ADJSP P,1
CALL WINREFRESH## ;Restore jumbled screen
CALL WINUPDATE## ;Allow updating...
POP P,(P) ;ADJSP P,-1
ATTDE1: HRLZI 17,SAVEB2
BLT 17,17
JRST INTEND
ATTDE2: SETOM DTACHD ;We are detached now
CLRBFO ;Clear output buffer
JRST INTEND ;Dismiss!
SUBTTL Internal error messages.
MSGATT: BYTE(7) .CHCRT,"Y","o","u"," "
ASCIZ "have attached a job running AMIS.
Type 'CONTINUE' to resume editing."
MSGNMM: BYTE(7) .CHCRT,"S","o","r","r"
ASCIZ "y, I can't work in monitor mode"
SUBTTL Other interrupt routines
timint: setom timflg ;Just flag timer interrupt.
tlx: jrst intend ;Ignore time limit exceeded
CROSS: movem t1,savcrs ;Save T1.
HRRZ T1,VECJBI+.PSVIS
CAIE T1,'POP'
jrst crosse
MOVEI T1,PTY ;Get PTY channel
JOBSTS T1, ;Get job status for subjob
JRST CROSSE ; Error, ignore pop request
HRL T1,T1 ;Move job # to left half word
HRRI T1,'POP' ;Get function code
CAMN T1,VECJBI+.PSVIS ;Interrupted by our own subjob?
SETZM PUSHED ; Yes, not pushed any more
CROSSE: move t1,savcrs ;Restore T1
INTEND: movem t1,hibloc ;Save t1.
movx t1,<jfcl> ;Load instruction.
exch t1,hibloc ;Restore t1, set up hiber location.
debrk.
jfcl
PISYSE: MOVEI T2,[ASCIZ "TTYIO: Some PISYS function failed."]
JRST BUG
SUBTTL Some internal I/O routines
OUTNUM: MOVE T7,T2 ;Move number to T7
OUTNU2: IDIV T7,T3 ;The standard recursive
PUSH P,T7+1 ; number printing routine.
SKIPE T7
CALL OUTNU2
POP P,T2
ADDI T2,"0"
JRST TTYWRITE
OUTSIX: DMOVE T6,T2 ;Get words into T6 & T7
OUTSI1: LDB T2,[ ;Get first sixbit char
POINT ^D6,T6,^D5]
ADDI T2,"A"-'A' ;Make it ascii
CALL TTYWRITE
LSHC T6,6 ;Shift both T6 and T7
JUMPN T6,OUTSI1 ;Loop back if any of them
JUMPN T7,OUTSI1 ; is non-zero
POPJ P,
SUBTTL Low segment data areas
XLIST
LIT
LIST
RELOC 0 ;Put data in low segment
VECTOR: ;Start of PSI vector here
VECTIM: EXP TIMINT ;Slot for timer interrupts.
BLOCK 3
VECDAT: EXP ATTDET ;Slot for attach/detach
BLOCK 3
VECJBI: EXP CROSS ;Slot for cross job interrupts
BLOCK 3
VECRID: EXP INDONE ;Slot for input done
BLOCK 3
VECPID: EXP PTYDON ;Slot for PTY input done
BLOCK 3
VECTLE: EXP TLX ;Slot for time limit exceeded
BLOCK 3
IFN F$KSYS,<
VECKSY: EXP KSYS ;Slot for KSYS warnings.
BLOCK 3
>;End IFN F$KSYS
VECEND: ;End of PSI vector here
ACTSTR: BLOCK 1 ;Pointer to activation string
BRKCHR: BLOCK 1 ;Break char, when pushing
CCCNT: BLOCK 1 ;^C counter
CCDONE: BLOCK 1 ;Non-zero means inhibited ^C trap
; should be served
DEASTR: BLOCK 1 ;Pointer to deactivation string
DTACHD: BLOCK 1 ;Detach flag (set if job is detached)
FUDGEF: BLOCK 1 ;Fudge factor
HACKER: BLOCK 1 ;Flag for hackmatic terminal
HIBLOC: SLEEP T2, ;Instruction to execute for sleeping.
INHIBIT:BLOCK 1 ;Non-zero means inhibit ^C exits from
; interrupt level
INSAVE: BLOCK 1 ;Save T1 here when input done interrupt
IFN F$KSYS,<
KSYMSG: BLOCK 1 ;Pointer to KSYS message to print sometime.
KSYSAV: BLOCK 3 ;Place to save T1-T3 when checking KSYS.
>;End of IFN F$KSYS
PUSHED: BLOCK 1 ;If we are pushed or not
PTYFLG: BLOCK 1 ;PTY has data ready.
TIMFLG: BLOCK 1 ;Timer interrupt flag.
;Various terminal parameters, set up mainly by TTYINIT.
ttname: block 1 ;Holds terminal name, in sixbit.
tttype: block 1 ;Holds terminal type. (.TOTRM)
ttdefr: block 1 ;Holds terminal defer flag. (.TODEM)
tttab: block 1 ;Holds terminal tabs flag. (.TOTAB)
ttform: block 1 ;Holds terminal form flag. (.TOFRM)
ttudx: block 1 ;Holds UDX for TTY:
ttflow: block 1 ;Pref. xonxoff state inside editor.
ttpage: block 1 ;Pref. xonxoff state outside editor.
TTOBUF: BLOCK 3 ;Terminal output buffer header
TOBUF1: BLOCK 3+BUFSIZ
TOBUF2: BLOCK 3+BUFSIZ
TTIBUF: BLOCK 3 ;Terminal input buffer header
TIBUF1: BLOCK 3+BUFSIZ
TIBUF2: BLOCK 3+BUFSIZ
PTOBUF: BLOCK 3 ;PTY output buffer header
POBUF1: BLOCK 3+BUFSIZ
POBUF2: BLOCK 3+BUFSIZ
PTIBUF: BLOCK 3 ;PTY input buffer header
PIBUF1: BLOCK 3+BUFSIZ
PIBUF2: BLOCK 3+BUFSIZ
CHRCNT: BLOCK 1 ;# of internally bufferd characters
CHREMP: BLOCK 1 ;# of empty positions in tah buffer
CHRGET: BLOCK 1 ;Wrap counter for get pointer
CHRPUT: BLOCK 1 ;Wrap counter for put pointer
TAHGET: BLOCK 1 ;Current get pointer
TAHPUT: BLOCK 1 ;Current put pointer
TAHPTR: POINT ^D8,TAHBUF ;Pure pointer to type ahead buffer
TAHBUF: BLOCK <TAHSIZ+^D3>/^D4 ;Internal type ahead buffer
savttp: block 1
savcnt: block 1
savnum: block 1
savttl: block <savlen==100>
SAVEB2: BLOCK 20
savcrs: block 1 ;Save T1 here on cross job interrupt.
PDLP2: EXP PDL2+PDLLEN-10
XWD PDL2,PDL2
XWD 400K,PDL2+1
PDL2: BLOCK PDLLEN
END