.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 8 Send \015 ; 1 Pass \011 9 Send CTL chars ; 2 Enable lower case 10 Raise DTR ; 3 Pass \012 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 ; /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 ; /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 ; /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 ; /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 ; /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 ; /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 ; 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 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 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 ; 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 ; 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 ; 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 ; /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 decout r1 message 100$: unsave ; /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 .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 ; /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 ; /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