.title k11rtt mt terminal service for Kermit-11/RT .ident /1.0.01/ ; 28-May-84 09:06:31 Brian Nelson ; ; Copyright (C) 1984 Change Software, Inc. .include /IN:K11MAC.MAC/ .psect .sbttl definitions for multiple terminal support .mcall .mtstat ,.mtatch,.mtdtch,.mtget ,.mtin .mcall .mtout ,.mtprnt,.mtrcto,.mtset .mcall .mrkt ,.cmkt ,.twait .enabl gbl m.tsts = 0 ; terminal status word m.tst2 = 2 ; terminal status word number 2 m.tfil = 4 ; character requiring fill m.fcnt = 5 ; number of fillers m.twid = 6 ; width m.tstw = 7 ; terminal status byte m.nlun = 4 ; number of terminals for .mtstat .macro $mterr ; map multiple terminal service movb @#errbyt,r0 ; into a global error code asl r0 ; simple to do mov mterr(r0),r0 ; thats all there is to it .endm $mterr .save .psect mtmap ,rw,d,lcl,rel,con lunmap: .blkw 12 ; map LUNS to RT units mtsts: .blkw 10 ; from the .mtstat call ttsts: .blkw 10 ; for ttyini tmowrk: .blkw 10 ; for mark time while reading ttsave: .blkw 4 ttctlc: .blkw 1 ; for control C things in connect mode ttime: .word 0,1 ; a tick sleep for .twait .restore .sbttl assign the terminal unit assdev::save ; we may want to use these .mtstat #rtwork ,#mtsts ; get terminal driver status bcs 90$ ; oops tst mtsts+m.nlun ; any multi tty support in exec? beq 80$ ; no, thats fatal call ttpars ; parse the device unit number bcs 70$ ; bad device name mov r0 ,r1 ; save the unit number now .mtatch #rtwork,#kbiost,r1 ; try to attach the terminal now bcs 90$ ; fatal error, exit clr r0 ; ok, exit with success br 100$ ; bye 70$: mov #er$dev ,r0 ; return bad device name error br 100$ ; bye 80$: mov #er$sup ,r0 ; return missing support error br 100$ ; bye 90$: $mterr ; map local error into global error 100$: unsave ; pop local registers and exit return deadev: save ; save this one, folks call ttpars ; parse the device name bcs 70$ ; oops mov r0 ,r1 ; save the unit number now .mtdtch #rtwork,r1 ; do it clr r0 ; success br 100$ ; bye 70$: mov #er$dev ,r0 ; bad device name error br 100$ ; bye 100$: unsave ; exit return ; dh .sbttl initialize the terminal ; T T Y I N I ; ; input: @r5 device name ; 2(r5) LUN ; 4(r5) modifiers ; ; output: r0 error code ttmode = 100 ! 10000 ! 40000 ttyini::save ; we will need this one call ttpars ; get the unit number bcs 70$ ; oops, return ER$DEV error mov 2(r5) ,r1 ; get the internal LUN to use asl r1 ; into a word offset mov r0 ,lunmap(r1) ; so we can map lun into a unit movb #377 ,lunmap+1(r1) ; say we have done this already mov r0 ,r1 ; save the unit number please .mtatch #rtwork,#kbiost,r1 ; ensure it's attached mov #ttsts ,r2 ; point to the status area .mtget #rtwork,r2,r1 ; get the current terminal setting bcs 90$ ; oops bic #2 ,m.tsts(r2) ; no automatic cr/lf's please bis #ttmode ,m.tsts(r2) ; no lower case convert, no echo bis #200!100000,m.tst2(r2) ; read and write pass all please .mtset #rtwork,r2,r1 ; set these please bcs 90$ ; oops mov #1000 ,r2 10$: calls binrea ,<2(r5),#-1> ; eat anything that's pending please dec r2 ; don't loop forever please beq 20$ ; exit the loop tst r0 ; did we get anything at all ? beq 10$ ; yes, eat some more input 20$: clr r0 ; all done br 100$ ; bye 70$: mov #er$dev ,r0 ; device name parse failed br 100$ ; bye 90$: $mterr ; map local error into a global one 100$: unsave ; pop and exit return .mcall .scca contrp::.scca #rtwork ,#ttctlc return conrst::.scca #rtwork ,#0 return .sbttl save/restore terminal settings ttysav::save ; we will use this one call ttpars ; parse the unit number please bcs 80$ ; oops mov r0 ,r1 ; copy the parsed unit number .mtget #rtwork,#ttparm,r1 ; get the current settings bcs 90$ ; error clr r0 ; success br 100$ ; bye 80$: mov #er$dev ,r0 ; bad device name br 100$ ; bye 90$: $mterr ; error, map into global and exit 100$: unsave ; pop this and exit return ttyrst::save ; we will use this one clr r2 ; was already attached call ttpars ; parse the unit number please bcs 80$ ; oops mov r0 ,r1 ; copy the parsed unit number .mtset #rtwork,#ttparm,r1 ; get the current settings bcc 20$ ; it worked cmpb @#errbyt,#1 ; not attached? bne 90$ ; no .mtatch #rtwork,#0,r1 ; yes, attach it bcs 90$ ; oops mov sp ,r2 ; flag we just attached it .mtset #rtwork,#ttparm,r1 ; get the current settings bcs 90$ ; error 20$: clr r0 ; success br 100$ ; bye 80$: mov #er$dev ,r0 ; bad device name br 100$ ; bye 90$: $mterr ; error, map into global and exit 100$: tst r2 ; need to detach it again beq 110$ ; no .mtdtch #rtwork,r1 ; yes, do it please 110$: unsave ; pop this and exit return .sbttl binrea read binary ; B I N R E A ; ; input: @r5 LUN ; 2(r5) timeout ; output: r0 error code ; r1 character just read xbinre:: binrea::save ; we may want to use these here clr -(sp) ; allocate a single character buffer mov sp ,r4 ; and a pointer to it also clr -(sp) ; allocate a mark time tim buffer clr -(sp) ; simple mov sp ,r2 ; and point to it mov @r5 ,r3 ; get the LUN asl r3 ; and map it into the unit number movb lunmap(r3),r3 ; simple ;- .mtget #rtwork,#ttsts,r3 ; get current terminal setting ;- bcs 90$ ; oops ;- bis #ttmode ,ttsts+m.tsts ; set so we don't wait for anything ;- .mtset #rtwork,#ttsts,r3 ; set this please ;- bcs 90$ ; can't set it for some reason cmp 2(r5) ,#-1 ; read without any wait ? bne 40$ ; no .mtin #rtwork,r4,r3,#1 ; read a single character now bcs 80$ ; it worked clr r1 ; get the character into r1 now bisb @r4 ,r1 ; and exit with success clr r0 ; bye br 100$ ; exit at last 40$: mov 2(r5) ,r1 ; get the timeout in seconds mul #60. ,r1 ; into ticks now 50$: .mtin #rtwork,r4,r3,#1 ; do it please bcc 60$ ; it worked, get the ch into r1 dec r1 ; been here too long ? beq 80$ ; yes, exit with error .twait #rtwork,#ttime ; sleep a moment please br 50$ ; and try again please 60$: clr r1 ; it worked, get the character and exit bisb @r4 ,r1 ; simple clr r0 ; success br 100$ 80$: mov #er$nin ,r0 ; no data today br 100$ ; bye 90$: $mterr ; map the error code into a global one 100$: add #6 ,sp ; pop local buffers unsave ; pop registers and exit return 200$: mov #1 ,r1 ; flag a timeout return .sbttl binary write ; B I N W R I ; ; binwri( %loc buffer, %val buffer_size, %val lun ) ; ; output: r0 error code ; ; Assumption: TTYINI has been called to map the Kermit LUN ; into the RT11 unit number for the terminal. binwri::save ; save registers we may need sub #20 ,sp ; a save area for tt settings clr r0 ; preset no errors as of yet mov @r5 ,r1 ; get the string address mov 2(r5) ,r2 ; get the string length beq 100$ ; nothing to do mov #ttsts ,r3 ; for getting tt settings mov 4(r5) ,r4 ; the internal LUN bne 10$ ; map LUN 0 to console print r1,r2 ; simple clr r0 ; no errors br 100$ ; exit 10$: mov sp ,r5 ; point to the stack work area asl r4 ; times two tstb lunmap+1(r4) ; have we mapped the lun into unit? beq 80$ ; no, fatal error movb lunmap(r4),r4 ; map into the rt11 unit number .mtget #rtwork,r3,r4 ; get current settings, set to wait bcs 90$ ; oops, exit with the error code in r0 mov (r3)+ ,(r5)+ ; copy the four words now mov (r3)+ ,(r5)+ ; copy the four words now mov (r3)+ ,(r5)+ ; copy the four words now mov (r3)+ ,(r5)+ ; copy the four words now bit #100 ,ttsts+m.tsts ; is the wait bit set already ? beq 20$ ; no, don't bother to clear it bic #100 ,ttsts+m.tsts ; set so we will wait for buffer space .mtset #rtwork,#ttsts,r4 ; simple to set 20$: .mtout #rtwork,r1,r4,r2 ; do the output now bcs 90$ ; oops, it failed for whatever reason mov -(r5) ,-(r3) ; restore the terminal settings mov -(r5) ,-(r3) ; restore the terminal settings mov -(r5) ,-(r3) ; restore the terminal settings mov -(r5) ,-(r3) ; restore the terminal settings .mtset #rtwork,r3,r4 ; simple clr r0 ; say it worked and exit br 100$ ; bye 80$: mov #er$map ,r0 ; rt11 unit not mapped to internal LUN br 100$ ; bye 90$: $mterr ; map mt error into global error code 100$: add #20 ,sp ; pop local work buffer unsave ; pop the saved registers return ; and exit .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 ttpars::mov r1 ,-(sp) ; save scratch register please mov @r5 ,r0 ; get the address of the string call 200$ ; check for legit character bcs 110$ ; oops movb (r0)+ ,r1 ; get the first byte please sub #'0 ,r1 ; convert to binary call 200$ ; check for legit character bcs 110$ ; oops movb @r0 ,r0 ; get the next digit beq 100$ ; nothing there then we are done mul #12 ,r1 ; something there, shift over by 10 sub #'0 ,r0 ; and convert low digit to binary add r0 ,r1 ; add into the accumulator 100$: mov r1 ,r0 ; and return the result clc ; return success 110$: mov (sp)+ ,r1 return 200$: tstb @r0 ; null ? beq 210$ ; yes, it's ok cmpb @r0 ,#'0 ; must only be digits today blo 220$ ; oops cmpb @r0 ,#'9 ; 0..9 bhi 220$ ; bad device name 210$: clc ; device name ok so far return ; bye 220$: sec ; bad, set and exit return ; G T T N A M ; ; input: @r5 address of console name to be written ; output: @r5 console name, always .asciz /0/ gttnam::mov @r5 ,r0 ; get the address of where to put it movb #'0 ,(r0)+ ; tt0: is always mt unit 0 clrb @r0 ; insure .asciz and exit clr r0 ; return success return ; bye ttyfin::call ttpars ; finish up mt service mov r0 ,r1 ; parse the device name .mtdtch #rtwork,r1 ; and detach the device now clr r0 ; return 'success' return ; and exit .sbttl speed read and change setspd::save ; save temps that we will use clr r0 ; find the speed map now 10$: tst spdlst(r0) ; reach the end of the table? beq 80$ ; yes, return unknown speed cmp 2(r5) ,spdlst(r0) ; table entry match the passed speed beq 20$ ; yes add #2 ,r0 ; no, try the next one please br 10$ ; next please 20$: mov spdmap(r0),r3 ; and get the speed setting bits call ttpars ; parse the mt unit number bcs 70$ ; oops mov r0 ,r1 ; save the unit number .mtatch #rtwork,#kbiost,r1 ; insure unit is attached mov #ttsts ,r2 ; point to the status area .mtget #rtwork,r2,r1 ; get the current terminal setting bcs 90$ ; oops bic #7400 ,m.tsts(r2) ; clear out old speed bits bis r3 ,m.tsts(r2) ; stuff the dz11 speed bits in .mtset #rtwork,r2,r1 ; set these please bcs 90$ ; oops clr r0 ; all done br 100$ ; bye 70$: mov #er$dev ,r0 ; device name parse failed br 100$ ; bye 80$: mov #er$spe ,r0 ; unknown speed ? br 100$ 90$: $mterr ; map local error into a global one 100$: unsave ; pop and exit return ttspee::save ; save these please call ttpars ; parse the mt unit number bcs 70$ ; oops mov r0 ,r1 ; save the unit number .mtatch #rtwork,#kbiost,r1 ; insure unit is attached mov #ttsts ,r2 ; point to the status area .mtget #rtwork,r2,r1 ; get the current terminal setting bcs 90$ ; oops mov m.tsts(r2),r3 ; get the speed mask out now bic #^C7400 ,r3 ; drop all bits but the speed clr r0 ; now look for the correct speed map 10$: tst spdmap(r0) ; reach the end of the list ? bmi 80$ ; yes, return a speed of zero cmp r3 ,spdmap(r0) ; setting match up now ? beq 20$ ; yes add #2 ,r0 ; no, try again please br 10$ ; next 20$: mov spdlst(r0),r0 ; a match, return the speed setting br 100$ ; bye 70$: mov #er$dev ,r0 ; device name parse failed br 100$ ; bye 80$: clr r0 ; failure br 100$ ; return a speed of zero then 90$: $mterr ; map local error into a global one 100$: unsave ; pop and exit return .save .psect $pdata spdlst::.word 50. ,75. ,110. ,134. ,150. ,300. ,600. .word 1200. ,1800. ,2000. ,2400. ,3600. ,4800. ,7200. .word 9600. ,0 ,0 spdmap::.word 0 ,400 ,1000 ,1400 ,2000 ,2400 ,3000 .word 3400 ,4000 ,4400 ,5000 ,5400 ,6000 ,6400 .word 7000 ,7400 ,-1 .restore .sbttl terminal i/o things we don't need, can't do or haven't done yet ttxon:: cantyp:: ttyset:: ttydtr:: ttrfin:: ttrini::clr r0 return ttyhan::mov #er$iop ,r0 return .mcall .ttyin jsw = 44 kbread::mov r2 ,-(sp) mov r3 ,-(sp) bis #40000 ,@#jsw ; enable lower case tt: input bic #10000 ,@#jsw ; ditch single ch input please 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