home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
archives
/
kermit11.zip
/
k11prt.mac
< prev
next >
Wrap
Text File
|
1989-06-13
|
27KB
|
951 lines
.title k11prt pro/rt XC/XL interface
.ident /1.0.01/
; 13-Oct-84 11:02:39 Brian Nelson
;
; 6-May-85 Basically had to add in checks for xl and tsx
; and then roll in some of the code from k11tsx
; in order to properly use the cl lines under
; TSX. (Ned W. Rhodes)
;
; 04-Nov-85 13:59:39 Mods suggested by Chuck Sandoian for TSX (BDN)
; All such edits marked by /37/
;
; 31-Dec-85 04:25:02 Added DTR control for RT11 5.2 and XC/XL
; 02-Sep-86 09:31:48 Fix SET SPEED for TSX+, edit /54/
;
; Copyright (C) 1984 1985 Change Software, Inc.
; NOTICE: !!!!!!
;
; To operate properly with Kermits at high speed and with Kermits
; not supporting xon/xoff flow control, the PRO/RT11 device handler
; for XC: MUST be modified to increase the internal buffer size and
; to repress XON/XOFF transmission within a packet. This is very
; easy to do. In the file XL.MAC from your PRO/RT kit, change the
; line
; from: BUFSIZ = 64.
; to: BUFSIZ = 220.
;
; and the line
; from: STPSIZ = BUFSIZ/4
; to: STPSIZ = BUFSIZ/2
;
; To recreate XCX.SYS, first copy XC.MAC, XM.MAC, XL.MAC, XM.ANS
; and SYSGEN.COM to DK: and then type IND SYSGEN. Tell it to use
; the saved answer file XM.ANS. When SYSGEN exits, it will have
; created, among other files, a file called XM.CND which is needed
; for the driver assembly.
;
; Then:
;
; assign dk: src:
; copy xcx.sys xcx.old
; ren/nopro xcx.sys xcx.sys
; unlo xc:
; rem xc:
; macro/obj:xcx (xm,xm.cnd,xc)
; link/exe:xcx.sys xcx
; ins xc:
.if ndf, K11INC
.ift
.include /IN:K11MAC.MAC/
.endc
.psect
.mcall .ABTIO ,.READW ,.WRITW ,.SPFUN ,.TTINR ,.TTYIN ,.TTYOU
.mcall .MRKT ,.CMKT ,.TWAIT ,.WRITC
.mcall .LOOKUP ,.DSTAT ,.FETCH ,.CLOSE
.mcall .PRINT ,.GVAL ,.HRESET,.RELEAS
.enabl gbl
.psect XCRW ,rw,d,lcl,rel,con
xcwork: .blkw 12 ; for asynch calls to the XC driver
xcsts: .word 0,0 ; /51/ Saved from STSDRV
second: .word 0,60. ; wait a full second
third: .word 0,20.
tenth: .word 0,6 ; wait 1/10 second
break: .word 0,17. ; for sending breaks, .283 seconds
wait: .word 0,1 ; wait one tick (1/60 second)
dtrlow: .word 0,60.*1 ; /41/ 2 second DTR drop
nobinar:.word 1 ; /37/ assume XL/XC (no binary I/O)
r50dev::.word 0,0,0,0 ; /37/ save name in rad50
devnam: .word 0,0,0,0,0,0,0,0,0,0,0,0 ; save the device name
ttctlc: .blkw 1 ; for control C things in connect mode
xoffed: .word 0 ; flag that we xoffed the other kermit
xcpoint:.word xcrdbf ; current pointer into XCRDBF
xcsize: .word 0 ; size of last XC read (not used)
xcdone: .word 0 ; read is complete
xcwdon: .word 0 ; writc is complete
timwrk: .blkw 4
.even
xcrdbf: .blkb 102 ; for a local read buffer, always asciz
xcrdsi = 100 ; size of XCRDBF
m.tsxs: .byte 35,'S ; Single Character
.BYTE 35,'W ; Tape mode on
.BYTE 35,'U ; No wait
.BYTE 35,'Y ; High efficiency
.BYTE 35,'R
.BYTE 0
.even
m.tsxr: .byte 35,'T ; Single character off
.byte 35,'X ; Tape mode off
.byte 35,'Z ; Line feed echo
.byte 0
.even
hieff: .byte 0,120 ; Turn hi eff off
; Edit 37 04-Nov-85 13:45:32 Brian Nelson
;
; /37/ Conversations with Chuck Sandoian, (Compuserve 76703,414) have
; determined that (1) the CL handler can run in 8bit mode (NULLS
; will, of course, not be passed). This is enabled by setting bit
; 11 in the .SPFUN code 250. Also, the CL driver DROPS DTR if the
; driver is passed an .SPFUN OFFDRV (code 205). Ned Rhodes had
; the code for 250 set to 1427. With the release of v5 and v6, we
; caln now use 8bit mode and control DTR, so now it's 7427. The
; meaning of the bits follow:
;
; 0 Pass \014 <FF> 8 Send \015 <CR>
; 1 Pass \011 <HT> 9 Send CTL chars
; 2 Enable lower case 10 Raise DTR
; 3 Pass \012 <LF> 11 Enable 8bit mode
; 4 Accept \012 12 unknown
; 5 N/A 13 ...ditto
; 6 Binary output 14 ......and so on
; 7 Binary input 15 .........
xlset: .word 7427 ; /37/ Options to set (was 1427)
xlset2: .word 40!10 ; /44/ NOLFOUT and NOFORM0
xlset3: .word 10 ; /45/ Put LFOUT back in
; The following tables are used for:
;
; (1) On TSX+, map decimal speeds into .SPFUN speeds for setting
; speed on DH/DHV/DHU and DZ/DZV interfaces.
; (2) At some future time when either TSX+ or RT supports it get
; the interface speed from the exec and insert a .TWAIT in
; front of the .SPFUN read call to reduce cpu usage at lower
; line speeds. For now, default to one tick unless a SET SPE
; command was given on TSX+.
.word 0
splst: .word 75. ,110. ,134. ,150. ,300. ,600. ; /44/
.word 1200. ,1800. ,2000. ,2400. ,3600. ,4800. ; /44/
.word 7200. ,9600. ,19200. ,0 ; /44/
spmap: .word 1 ,2 ,3 ,4 ,5 ,6 ; /44/
.word 7 ,10 ,11 ,12 ,13 ,14 ; /44/
.word 15 ,16 ,17 ; /44/
;
waitti: .byte 1 ; /52/
.byte 6 ,6 ,6 ,6 ,6 ,4 ; /52/
.byte 3 ,2 ,2 ,2 ,2 ,1 ; /52/
.byte 1 ,1 ,0 ,0 ,0 ,0 ; /52/
.even ; /52/
waitarg:.word 0,0 ; /52/
xkspeed:.word 0 ; /52/
.psect $CODE
ERRBYT = 52
JSW = 44
; .SPFUN codes for the XC/XL driver
CLRDRV == 201 ; undo xon, reset the driver
BRKDRV == 202 ; wc=0, end break else break
SRDDRV == 203 ; special read, wc is max # of bytes
; to read, always returns at least one
; byte, up to max if data is there.
STSDRV == 204 ; driver status, high byte is driver
; version, low byte is:
; bit 0 = 1 if sent xoff to host
; bit 1 = 1 if rec xoff from host
; bit 2 = 1 if CTS is ok
OFFDRV = 205 ; disable interupts at program exit
DTRDRV = 206 ; rt 5.2, set/clear DTR. If WC <> 0
; then turn it on else turn it off.
CLSET = 250 ; Set cl options for TSX-Plus
CLRSET = 251 ; Reset cl option for TSX-Plus
CLSPEED = 256 ; /44/ Speed control
CLCLR = 257 ; /37/ Reset w/o dropping DTR
XC.CONTROL == 14 ; channel for controlling the driver
XC.AUX = 15 ; /41/ Ditto
.iif ndf, XON , XON = 'Q&37
.iif ndf, XOFF , XOFF= 'S&37
.sbttl assign and init the XC/XL port
.enabl lsb
.mcall .SERR ,.HERR ; /51/
x.ttysav::
x.ttyrst::
x.deadev::
mov r1 ,-(sp) ; /45/
br 10$ ; /45/
x.assdev::
mov r1 ,-(sp) ; /44/ Save a register please
mov @r5 ,r1 ; /44/ Address of the devname
call mapxl ; /44/ Do we know about this dev?
bcs 110$ ; /44/ No, return error in R0
10$: .SERR ; /51/
tst tsxcl ; Under tsx and using cl line?
beq 100$ ; Nope
mov #hieff,r0 ; Get emt parameter block
emt 375 ; Turn off hi efficiency
.PRINT #m.tsxr ; Reset some terminal parameters
100$: .HERR ; /51/
clr r0 ; Success
110$: mov (sp)+ ,r1 ; /44/ Restore
return ; not needed for PRO/RT
.dsabl lsb
; T T Y I N I
;
; input: @r5 device name
; 2(r5) LUN
; 4(r5) modifiers
;
; output: r0 error code
x.TTYINi::
save <r1,r2,r3,r4> ; /37/ always save temps please
mov @r5 ,r1 ; get the device name address
mov 2(r5) ,r0 ; copy the device name please
asl r0 ; lun times two please
movb (r1) ,devnam(r0) ; save it please
movb 1(r1) ,devnam+1(r0) ; both ascii characters please
clr r0 ; assume success
tstb @r1 ; perhaps the console ?
beq 100$ ; yes, don't do anything
cmpb @r1 ,#'T&137 ; TT: ?
beq 100$ ; do nothing then
1$: clr xoffed ; reset 'sent an XOFF' flag
mov #xcrdbf ,xcpoint ; a pointer into the XC: buffer
mov #xcrdbf ,r2 ; xc device, zero the buffer
mov #xcrdsi+2,r0 ; the size of the buffer
5$: clrb (r2)+ ; clear it out
sob r0 ,5$ ; next please
call mapxl ; /44/ See if XL/XC or CLn passed
bcs 95$ ; /44/ No, exit with ER$UKN
mov r0 ,r2 ; /44/ Point to RAD50 device name
10$: calls fetch ,<@r2> ; get the device loaded ?
tst r0 ; did it work ?
bne 95$ ; no
20$: clr xcdone ; nothing pending to read from XC:
mov r2 ,r3 ; /37/ get pointer to rad50 of dev
mov #r50dev ,r4 ; /37/ where to save r50 of name
mov (r3)+ ,(r4)+ ; /37/ copy rad50 of device name
mov (r3)+ ,(r4)+ ; /37/ copy rad50 of device name
mov (r3)+ ,(r4)+ ; /37/ copy rad50 of device name
mov (r3)+ ,(r4)+ ; /37/ copy rad50 of device name
.LOOKUP #rtwork,2(r5),r2 ; try to open the port up please
bcs 60$ ; oops
.LOOKUP #rtwork,#XC.CONTROL,r2 ; also open a control channel
bcs 60$ ; should never happen, of course
call 200$ ; /51/ Extra for driver version
call tsxopt ; /37/ set CLn: if it's TSX+
tst nobinary ; can we do binary i/o to XC: ?
beq 30$ ; yes
cmpb parity ,#par$no ; currently PARITY NONE ?
bne 30$ ; no
movb #par$sp ,parity ; set space parity to fake it
30$: clr r0 ; all is well today
br 100$ ; exit with sucess
60$: mov #xcierr ,r0 ; open error on X?0: device
br 90$ ; map it to a global error
70$: mov #xcspfun,r0 ; .SPFUN error for X?0:
br 90$ ; map it to a global error
90$: clr r1 ; now map to the global error code
movb @#ERRBYT,r1 ; get RT11's error code
asl r1 ; times 2 for word indexing
add r0 ,r1 ; point to the global error code
mov @r1 ,r0 ; and get it
95$: mov 2(r5) ,r1 ; clear the saved device name
asl r1 ; times two please
clr devnam(r1) ; simple
100$: unsave <r4,r3,r2,r1> ; /37/ pop scratch registers and exit
return ; bye
200$: .SPFUN #rtwork,#XC.CONTROL,#STSDRV,#xcsts,#0,#1
.SPFUN #rtwork,#XC.CONTROL,#CLRDRV,#0,#0,#1
bit #1 ,xcsts ; Did we ever xoff the host?
beq 210$ ; No
.WRITC #rtwork,2(r5),#$xon,#1,#290$,#1
210$: return
290$: return ; .WRTIC completion
.save
.psect $pdata ,ro,d,lcl,rel,con
.even
$xon: .byte 'Q&37,0
.even
.restore
.sbttl TSX+ things
tsxopt: tst tsxcl ; /37/ TSX+ and CL:
beq 100$ ; /37/ No
cmp nobinary,#1 ; /37/ currently set to default?
bne 10$ ; /37/ no, don't change it
clr nobinary ; /37/ Yes, we can do 8BIT I/O on CL
10$: .GVAL #rtwork,#-4 ; get tsx leadin
movb r0,m.tsxr ; set in place
movb r0,m.tsxr+2 ; set in place
movb r0,m.tsxr+4 ; set in place
movb r0,m.tsxs ; set in place
movb r0,m.tsxs+2 ; set in place
movb r0,m.tsxs+4 ; set in place
movb r0,m.tsxs+6 ; set in place
movb r0,m.tsxs+8. ; set in place
.PRINT #m.tsxs ; set the options
.SPFUN #rtwork,#xc.control,#clset,#xlset,#1,#0
; set some cl options
.SPFUN #rtwork,#xc.control,#clrset,#xlset2,#1,#0
; reset some cl options
bis #40000!10000!100,@#JSW ; lower case, no wait, and special
100$: return ; back to caller
mapxl: save <r1,r2,r3> ; /44/ Save these please
clr r3 ; /44/ Current index
sub #50 ,sp ; /44/ Allocate a buffer for new name
mov sp ,r2 ; /44/ And also a pointer to it
5$: cmpb (r1) ,#': ; /44/ While ( *devnam != ':' )
beq 6$ ; /44/ {
movb (r1) ,(r2)+ ; /44 *newnam++ = *devnam
beq 6$ ; /44/ if ( *devnam == NULL) break
inc r1 ; /44/ devnam++
br 5$ ; /44/ } ;
6$: clrb (r2) ; /44/ *newnam = NULL
mov sp ,r2 ; /44/ newnam = newnam_base_address
10$: tst 200$(r3) ; /44/ End of the list yet ?
beq 90$ ; /44/ Yes, exit with ER$UKN
strcmp r2 ,200$(r3) ; /44/ Find a device name match?
tst r0 ; /44/ Well ?
beq 20$ ; /44/ Yes
tst (r3)+ ; /44/ No, try the next entry
br 10$ ; /44/ ....
20$: mov #310$ ,r0 ; /44/ Success, copy r50 devicename
mov 300$(r3),@r0 ; /44/ Just copy over first word
add #50 ,sp ; /44/ Pop local buffer....
clc ; /44/ No errors
br 100$ ; /44/ Exit
90$: mov #ER$UKN ,r0 ; /44/ Return error and exit
add #50 ,sp ; /44/ Pop local buffer....
sec ; /44/ Flag error
100$: unsave <r3,r2,r1> ; /44/ Exit
return
200$: .word 201$,202$,203$,204$
.word 210$,211$,212$,213$,214$,215$,216$,217$
.word 220$,221$
.word 0
201$: .asciz /XC/
202$: .asciz /XL/
203$: .asciz /XC0/
204$: .asciz /XL0/
210$: .asciz /CL0/
211$: .asciz /CL1/
212$: .asciz /CL2/
213$: .asciz /CL3/
214$: .asciz /CL4/
215$: .asciz /CL5/
216$: .asciz /CL6/
217$: .asciz /CL7/
220$: .asciz /KL/
221$: .asciz /KL0/
.even
300$: .rad50 /XC /
.rad50 /XL /
.rad50 /XC /
.rad50 /XL /
.rad50 /CL0/
.rad50 /CL1/
.rad50 /CL2/
.rad50 /CL3/
.rad50 /CL4/
.rad50 /CL5/
.rad50 /CL6/
.rad50 /CL7/
.rad50 /KL /
.rad50 /KL0/
310$: .rad50 / /
.rad50 / /
.rad50 / /
.rad50 / /
.sbttl close the line up
.enabl lsb
x.ttyfin::
save <r1,r2> ; /37/ save temps please
.TWAIT #rtwork,#third ; /37/ insure ack for B packet done
tst tsxcl ; /45/ Tsx+ and CLn?
beq 1$ ; /45/ No
.SPFUN #rtwork,#xc.control,#clset,#xlset3,#1,#0 ; /45/ Yes, SET LFOUT
1$: clr wasxc ; was not xc/xl and pure RT
mov 2(r5) ,r1 ; get the internal lun
asl r1 ; map it
cmpb devname(r1),#'C&137 ; /44/ CLn: and TSX+ ?
beq 2$ ; /44/ Yes, let it through
cmpb devname(r1),#'X&137 ; see if the device was X?:
bne 10$ ; no, then do nothing
2$: call clrxc ; reset the driver
mov #CLCLR ,r2 ; /37/ assume TSX CL function 257
tst tsxcl ; tsx and cl?
bne 5$ ; yes
mov sp ,wasxc ; flag for .exit that this was XC/XL
mov #OFFDRV ,r2 ; /37/ No, was real RT11 today
5$: .SPFUN #rtwork,#XC.CONTROL,r2,#0,#0,#1 ;disable interupts at exit
.ABTIO 2(r5) ; try to stop all i/o please
.ABTIO #XC.CONTROL ; /51/
.CLOSE 2(r5) ; yes, was XC/XL, thus close it
.CLOSE #XC.CONTROL ; and close the controller port
clr xcwdone ; nothing as far as writes either
clr xcdone ; nothing pending to read from XC:
mov #xcrdbf ,xcpoint ; reset the pointer to the buffer
clrb @xcpoint ; stuff a null in please
10$: clr devnam(r1) ; no device active now
clr r0 ; no error are possible
unsave <r2,r1> ; /37/ pop temp and exit
return ; bye
.dsabl lsb
x.finrt:: ; /37/ clear the line for good
tst r50dev ; /37/ anything ever opened up ?
beq 10$ ; /37/ no
.LOOKUP #rtwork,#XC.CONTROL,#r50dev ; /37/ yes, open it
.SPFUN #rtwork,#XC.CONTROL,#OFFDRV,#0,#0,#1 ; /37/ and kill it
10$: tst wasxc ; /37/ need a .HRESET ?
beq 20$ ; /37/ no
.ABTIO #XC.CONTROL ; /51/
.CLOSE #XC.CONTROL ; /51/
.HRESET ; /51/
br 100$ ; /51/ And exit
;
20$: .CLOSE #XC.CONTROL ; /37/
100$: clr r0 ; /37/ bye
return
.save
.psect XCDATA ,rw,d,lcl,rel,con
XCNAME: .rad50 /XC /
.rad50 / /
.rad50 / /
.rad50 / /
XLNAME: .rad50 /XL /
.rad50 / /
.rad50 / /
.rad50 / /
.restore
.sbttl binrea read binary
; B I N R E A
;
; input: @r5 LUN
; 2(r5) timeout
; output: r0 error code
; r1 character just read
;
; To avoid rewriting the terminal emulation code, the case
; where we get passed a timeout of -1 is used to do a qio
; to the XC port and then subsequent calls simply check to
; see if it completed. If so, get whats in the buffer. If
; it's not done, exit and check next time. This is only
; done from the connect code, so perhaps later I will get
; around to rewriting it.
;
; For the normal Kermit timed packet read, we post the qio
; and loop waiting for it to complete. If it does not com-
; plete within the specified time, we cancel the i/o and
; reset the driver.
; For proper operation, the XC driver must be modified as
; described at the beginning of the file.
rdmode: .word 0
x.xbin::mov sp ,rdmode
br rdcom
x.binr::clr rdmode
rdcom: save <r2,r3,r4> ; we may want to use these here
mov @r5 ,r2 ; get the lun to use
asl r2 ; if TT: then do it different
cmpb devnam(r2),#'C&137 ; /44/ CLn: and TSX+ ?
beq 10$ ; /44/ Yes, let it through
cmpb devnam(r2),#'X&137 ; XC: ?
beq 10$ ; yes (or at least assume so)
call ttread ; yes, get from the console tt
br 100$ ; bye
10$: cmp xcpoint ,#xcrdbf+xcrdsi ; insure no buffer overflows
bhis 20$ ; gone too far, XC driver is %$#@!
tstb @xcpoint ; anything left in the readbuffer?
bne 30$ ; no
20$: mov #xcrdbf ,xcpoint ; reset the pointer to the buffer
clrb @xcpoint ; stuff a null in please
call xxread ; load the buffer with as much as can
tst r0 ; did this read succeed ?
bne 100$ ; no
30$: clr r1 ; avoid sxt even if the fubar XC
bisb @xcpoint,r1 ; driver always drops bit 7 (future?)
inc xcpoint ; point to the next one in the buffer
clr r0 ; insure success and exit
100$: unsave <r4,r3,r2>
return
xxread: mov 2(r5) ,r3 ; timeout in seconds here
bne 10$ ;
inc r3 ; convert nothing to one second
10$: cmp r3 ,#-1 ; no wait ?
beq 15$ ; yes
mul #60. ,r3 ; no, convert time to ticks then
br 20$ ; and check on the i/o status
15$: mov #1 ,r3 ; no wait (really, one tick)
20$: tst xcdone ; no timout, last read ever finish?
bmi 30$ ; no, keep waiting then
mov #-1 ,xcdone ; read without waiting for it
mov xkspeed ,r1 ; /52/ Get current line speed
movb waitti(r1),waitarg+2 ; /52/ Insert the desired delay now
.TWAIT #rtwork,#waitarg ; /52/ Now delay processing a moment
.SPFUN #xcwork,@r5,#SRDDRV,#xcrdbf,#xcrdsi,#1,#200$
30$: tst xcdone ; return that fast (?)
bgt 40$ ; yes
tst clkflg ; /37/ system have a clock?
bne 34$ ; /37/ yes
cpuwait #1 ; /37/ no, loop to wait
br 35$ ; /37/ next please
34$: .TWAIT #rtwork,#wait ; no, sleep for 1/60 second
35$: sob r3 ,30$ ; and see if we should keep waiting
tst xcdone ; got it from the XC buffer now?
bmi 50$ ; no, return no data and exit
40$: clr r1 ; all done, get character and exit
bisb xcrdbf ,r1 ; and set the error code to zero
clr xcdone ; que a new read next time called
clr r0 ; in r0
br 100$ ; bye
50$: cmp 2(r5) ,#-1 ; no xon's if we are looping no tmo
beq 60$ ;
tst rdmode ; /45/ From CONNECT or DIAL ?
bne 60$ ; /45/ Yes, please drop XON's then
call clrxc ; insure interupts are ok, also XON
60$: mov #ER$NIN ,r0 ; no data has come it yet
br 100$ ; exit
100$: return
200$: mov #1 ,xcdone ; flag a read completion and exit
return ; so we will break the .TWAIT loop
.sbttl raw i/o from the console TT
ttread: bis #40000!10000!100,@#JSW ; lower case, no wait
cmp 2(r5) ,#-1 ; read without any wait ?
bne 10$ ; no
.TTINR ; one char from the console tt:
bcs 80$ ; it worked
mov r0 ,r1 ; and exit with success
clr r0 ; bye
br 100$ ; exit at last
10$: mov 2(r5) ,r1 ; get the timeout in seconds
mul #60. ,r1 ; into ticks now
20$: .TTINR ; try a character from TT:
bcc 30$ ; it worked, get the ch into r1
dec r1 ; been here too long ?
beq 80$ ; yes, exit with error
.TWAIT #rtwork,#wait ; sleep a moment please
br 20$ ; and try again please
30$: clr r1 ; it worked, get the character and exit
bisb r0 ,r1 ; simple
clr r0 ; success
br 100$ ; and exit
80$: mov #ER$NIN ,r0 ; no data today
clr r1 ; same here, return a null
100$:
tst tsxcl ; tsx and cl
bne 101$ ; yes
bic #40000!10000!100,@#JSW ; reset some tt options
101$: return
.sbttl binary write
; B I N W R I
;
; binwri( %loc buffer, %val buffer_size, %val lun )
;
; output: r0 error code
$XLV51 = 16.
$XLV52 = 17.
x.binwri::
save <r1,r2,r3,r4>
clr r0 ; presume no errors
tst 2(r5) ; any i/o to do at all?
beq 100$ ; no
mov 4(r5) ,r4 ; check for TT: please
asl r4 ; by indexing to DEVNAM:
cmpb devnam(r4),#'T&137 ; TT: ?
bne 20$ ; no
mov @r5 ,r4 ; simple
mov 2(r5) ,r2 ; number of characters to write
15$: .TTYOUT (r4)+ ; dump via .TTYOU to avoid .PRINT's
sob r2 ,15$ ; problems with 8bit characters please
clr r0 ; and exit
br 100$ ; bye
20$: mov #-1 ,xcwdone ; Done yet?
mov (r5) ,r3 ; Copy the data to a local buffer
mov xklgbuf ,r2 ; Pick up pointer to a buffer
mov 2(r5) ,r4 ; The byte count for the write
mov r4 ,r1 ; Set byte count for the copy.
25$: movb (r3)+ ,(r2)+ ; for (i=bytecount;i>0;i--)
sob r4 ,25$ ; *buffer++ = *source++
mov r1 ,r4 ; restore the byte count
dec r4 ; if bytecount <> 1
beq 40$ ; then
cmpb -(r3) ,#CR ; if lastcharacter == CR
bne 30$ ; then
movb #LF ,(r2)+ ; *bufffer++ = NULL
inc r1 ; bytecount++
30$: clr xoffed ; xoffed = false ;
;- tst rtflow ; if (needflowcontrol)
;- beq 35$ ; then
;- movb #XOFF ,(r2)+ ; *buffer++ = XOFF
;- inc r1 ; bytecount++
;- mov sp ,xoffed ; xoffed = true
35$:
40$: clrb (r2)+ ; *buffer++ = NULL ;
inc r1 ; bytecount++
asr r1 ; bytecount = bytecount/2
.WRITC #xcwork,4(r5),xklgbuf,r1,#200$,#1
mov #10.*60.,r3 ; wait at most 10 seconds (?)
50$: tst xcwdone ; ast completion as of yet ?
bne 60$ ; yes
tst clkflg ; A clock?
bne 55$ ; Yes
CPUWAIT #1 ; No, loop and fall thru, twait is NOP
55$: .TWAIT #rtwork,#wait ; still not complete, wait a tick
sob r3 ,50$ ; and check again
call clrxc ; clear the driver out, send XON
clr r0
br 100$ ; exit
60$: tst r4 ; was that a single character i/o?
beq 70$ ; yes
tst xoffed ; in case a virgin xcdriver, wait.
beq 70$ ; no, skip the wait and xon then.
.TWAIT #rtwork,#tenth ; no, sleep for a moment please
.TWAIT #rtwork,#tenth ; at 9600, we need this one also
call 300$ ; xon the other side please
70$: clr r0 ; success
clr xcwdone ; reset the i/o in progress flag
100$: unsave <r4,r3,r2,r1> ; pop registers and exit
return ; bye
200$: mov #1 ,xcwdone ; flag ast level completion
return ; and exit
300$: tst xoffed ; did we xoff the other side?
beq 310$ ; no
.WRITC #xcwork,4(r5),#320$,#1,#0,#1 ; synch i/o this time please
310$: clr xoffed ; say no xoff's anymore please
return
320$: .byte XON,0
clrxc: .SPFUN #rtwork,#XC.CONTROL,#CLRDRV,#0,#0,#1 ; clear the driver
return
.sbttl cantyp try to dump all typeahead
x.cantyp::
save <r1,r2> ; save temps
mov #200 ,r2 ; loop for no more than 128 characters
mov #xcrdbf ,xcpoint ; reset the pointer to the buffer
clrb @xcpoint ; stuff a null in please
10$: calls binrea ,<2(r5),#-1> ; try to get something
tst r0 ; did it work ?
bne 20$ ; no, exit
sob r2 ,10$ ; yes, eat somemore characters
20$: .ABTIO 2(r5) ; try to reinit the driver and exit
call clrxc ; this also please
100$: unsave <r2,r1> ; pop temp and exit
clr r0
return ; bye
x.ttxon::
call clrxc ; get the driver to clear xoff status
return
x.senbrk::
.SPFUN #rtwork,#XC.CONTROL,#BRKDRV,#0,#1,#1
tst brklen ; /43/ User set a BREAK length?
beq 10$ ; /43/ No
mov brklen ,break+2 ; /43/ Yes, use it
10$: .MRKT #timwrk,#break,#20$,#20
clr r0
return
20$: .SPFUN #rtwork,#XC.CONTROL,#BRKDRV,#0,#0,#1
clr r0
return
; Drop dtr for a moment, For RT11 5.2 only
; Added 31-Dec-85 03:46:44 Edit 2.41
.enabl lsb
x.ttyhan::
x.ttydtr::
save <r1> ; /41/ Save a register
mov (r5) ,r1 ; /44/ Get device name address in R1
call mapxl ; /44/ See if device names maps
bcs 100$ ; /44/ No, so exit
mov r0 ,r1 ; /44/ Point to it
10$: calls fetch ,<@r1> ; /41/ Insure handler is loaded
.LOOKUP #rtwork,#XC.AUX,r1 ; /41/ Now open it up
bcs 90$ ; /41/ Oops, should not happen
.SPFUN #rtwork,#XC.AUX,#DTRDRV,#0,#0,#1 ;/41/ Now DROP DTR
.TWAIT #rtwork,#dtrlow ;/41/ And let it stay low for
.TWAIT #rtwork,#dtrlow ;/41/ And let it stay low for
.TWAIT #rtwork,#dtrlow ;/41/ And let it stay low for
.SPFUN #rtwork,#XC.AUX,#DTRDRV,#0,#1,#1 ;/41/ while, then bring it up
.CLOSE #XC.AUX ; /41/ Close controlling channel
br 100$
90$: movb @#52 ,r1
message <Error from .lookup >
decout r1
message
100$: unsave <r1> ; /41/ Pop saved register
clr r0 ; /41/ Assume that it worked
return ; /41/ And exit
.dsabl lsb
.sbttl parse terminal unit
; T T P A R S
;
; input: @r5 address of RT11 Multiple terminal service unit string
; output: r0 unit in binary
x.ttpars::
clr r0 ; always unit zero for PRO/RT
return
.sbttl GTTNAM get MT unit of current console (set tt:consol=nn)
; G T T N A M
;
; input: @r5 address of console name to be written
; output: @r5 current console name
; consave same thing
x.gttnam::
mov @r5 ,r0 ; for PRO/RT, always return TT:
movb #'T&137 ,@r0
movb (r0)+ ,consave
movb #'T&137 ,@r0
movb (r0)+ ,consave+1
movb #': ,@r0
movb (r0)+ ,consave+2
clrb @r0
clrb consave+3
clr r0
return
global <consave>
.sbttl terminal i/o things we don't need, can't do or haven't done yet
; Edit: /54/ Remove ASL R3 to get correct speed indexing
x.setspd::
clr xkspeed ; /52/ No saved speed now
tst tsxcl ; /44/ TSX+ and CL ?
beq 110$ ; /44/ No can do if not
save <r1,r2,r3> ; /44/ Save a register or three
clr r3 ; /44/ Match passed speed in table
10$: tst splst(r3) ; /44/ End of the speed table ?
beq 90$ ; /44/ Yes, exit please
cmp splst(r3),2(r5) ; /44/ Speeds match up ?
beq 20$ ; /44/ Yes, exit loop
tst (r3)+ ; /44/ No, try next entry then
br 10$ ; /44/ Next please
20$: mov (r5) ,r1 ; /44/ Get device name address in R1
call mapxl ; /44/ See if device names maps
bcs 100$ ; /44/ No, so exit
mov r0 ,r1 ; /44/ Point to it
calls fetch ,<@r1> ; /44/ Insure handler is loaded
.LOOKUP #rtwork,#XC.AUX,r1 ; /44/ Now open it up
bcs 100$ ; /44/ Oops, should not happen
add #spmap ,r3 ; /45/ for the speed
.SPFUN #rtwork,#XC.AUX,#CLSPEED,r3,#1,#0 ; /45/ Address NOT value
bcs 40$ ; /52/ Oops
mov (r3) ,xkspeed ; /52/ Save it please
40$: .CLOSE #XC.AUX ; /44/ Close controlling channel
br 100$ ; /44/ Exit
90$: mov #ER$SPE ,r0 ; /44/ Return UNKNOWN speed
100$: unsave <r3,r2,r1> ; /44/ Pop saved registers
clr r0 ; /44/ Assume that it worked
return ; /44/ And exit
110$: mov #377 ,r0
return
x.ttsp::clr r0 ; /54/ Presume failure
tst tsxcl ; /54/ CL and TSX+
beq 100$ ; /54/ No
mov xkspeed ,r0 ; /54/ Get from last SET SPEED
asl r0 ; /54/ Word indexing
mov splst-2(r0),r0 ; /54/ Copy and exit
100$: return ; /54/ Bye
x.ttset::
x.ttrfin::
x.ttrini::
clr r0
return
.mcall .TTYIN
jsw = 44
x.kbread::
mov r2 ,-(sp)
mov r3 ,-(sp)
bis #40000 ,@#jsw ; enable lower case tt: input
tst tsxcl ; tsx and cl?
beq 5$ ; nope
bic #10000!100,@#jsw ; ditch single ch input and wait
br 7$ ; jump ahead
5$: bic #10000 ,@#jsw ; ditch single ch input please
7$: mov @r5 ,r1 ; a buffer to put the chars
mov #80. ,r3 ; size of the buffer here
;10$: .SCCA #area ,#kmonbf ; so we can catch control Z
10$: .TTYIN ; read a character please
tstb r0
beq 15$ ; a null
cmpb r0 ,#'Z&37 ; control Z ?
beq 20$ ; yes
cmpb r0 ,#'C&37 ; control C ?
beq 20$ ; yep
cmpb r0 ,#15 ; carriage return ?
beq 30$ ; yep
movb r0 ,(r1)+ ; return what we just got
cmpb r0 ,#14 ; form feed ?
beq 40$ ; yep
15$: sob r3 ,10$ ; next please
20$: mov #ER$EOF ,r0 ; say read error and exit
br 100$ ; bye
30$: movb #cr ,(r1)+ ; return all terminators please
movb #lf ,(r1)+ ; simple
.TTYIN ; eat the line feed now
40$: clrb @r1
sub @r5 ,r1 ; the length
clr r0
100$: mov (sp)+ ,r3
mov (sp)+ ,r2
return
.end