.title KRTDSP I/O dispatch and support .ident "V03.62" ; /62/ 27-Jul-93 Billy Youdelman ; ; leave comm handler chans open after assigning it as the link device ; add version testing to support RT-11 V4 ; /BBS/ 1-Dec-91 Billy Youdelman V03.61 ; ; this module has been extensively modified ; ; moved kbread here, one copy is sufficient, cleaned up also ; streamlined jsw/nowait/single_char modes/setting/resetting/etc ; added writ1char routine - writes a single character to TT ; add entry for inqdtr, only works with CL handler ; assdev patched for new mapxl in krtxl ; made packet buffer length = $ALLSIZ to match checkpacket buffer ; ttyrst - resume TSX window processing, as after packets, connect ; added cl.dump to clean up CL stuff when exiting/modifying the line ; inqbuf patched to use MAXLNG for TSX+, MAXPAK for RT-11 ; added inqcd ; ; moved binread here so CONNECT can share it and XL can be left ; open under TSX and RT-11SJ where there is no hope of closing it ; ; I/O is now dispatched this way: ; 1) if via the controlling terminal line, use routines in KRTERM ; regardless of operating system. that is, the t.tty... calls ; 2) if via a handler, use routines in KRTXL. that is, the ; x.tty... calls for CL XC or XL ; 3) RT-11 multi-terminal I/O has been pulled ; ; moved set$line here, patched to reset modem to idle state and release ; a TSX CL line after SET LINE TT if same was acquired within Kermit ; ; set$line won't write bad device to ttname ; SET LINE TT now reverts to remote mode ; 08-Nov-84 16:16:40 Brian Nelson ; ; Collect K11PRT and K11TSX into separate overlays in ; the same region (either disk or virtual). Dispatch to the ; correct one based on how the link device is SET. While the ; cost in address space to create overlay table entries for ; all of the ept's in each module is about 300 words doing so ; saves me the need to create multiple save images every time ; I change Kermit-11. Additionally, one save image for all ; systems sounds like a nice idea to me. ; ; 12-Sep-86 11:20:20 BDN Changed around to separate I/D space .include "IN:KRTMAC.MAC" .iif ndf KRTINC .error <; .include for IN:KRTMAC.MAC failed> ; /62/ .ABTIO,.POKE bypassed for V4, also expanded to allow assy under same .mcall .CLOSE ,.GVAL ,.RCTRLO,.RSUM .mcall .SPFUN ,.TTINR ,.TTYIN ,.TTYOU ,.TWAIT .macro entry ep ; dispatch to TT or handler as needed .list me .enabl lsb ep:: mov #200$ ,r0 jmp dispat .save .psect $pdata 200$: .word x.'ep,t.'ep ; dropped multi-term stuff .restore .dsabl lsb .nlist me .endm entry .sbttl Global and local data CLHOSE = 265 ; reset for TSX V6.0 and up CL handler DTRDRV = 206 ; RT-11 V5.2 and up, set/clear DTR OFFDRV = 205 ; disable interrupts at program exit $tcfig = 424 ; ADDR of SET TERM options status word .psect xcdata ,rw,d,gbl,rel,con attcl:: .byte 0 ,155 ; attach a CL unit to a TSX line cl.unit::.word 0 ; integer copy of CL unit number cl.line::.word 0 ; connect CL unit to this TSX line # cl$line::.word 0 ; perm copy, follows valid assign d.allo::.byte 0 ,156 ; (de)allocate a device emt args .word cl.r50 ; device to (de)allo.. cl.r50::.word 0 ,0 ,0 ,0 ; ..which lives here km.lock::.word 0 ; /62/ if <> it's KM running r50dev::.word 0 ,0 ,0 ,0 ; current link dev name, if handler suspnd::.word 0 ; suspend count for CONNECT tasks xcdone::.word 0 ; moved here, read is complete xk.con::.word 0 ; if <>, reads to terminal emulator xkrd1: .word 0 ,0 ,0 ,0 ,0 ,0 ; work area for handler reads xksize == 100 ; size in bytes for handler reads xkbuff::.blkb xksize+2 ; read buffer for handler xkpoint::.word xkbuff ; pointer to current position in buff xkspeed::.word 0 ; moved here to live in root xl.lock::.word 0 ; if <> XL can't do .close z.atch::.word 0 ; if <> TSX line was gotten here .psect $pdata tsxwai: .word 0 ,1 ; ticks between reads from keyboard w$resume:.byte 4 ,161 ; resume TSX window processing .psect packet ,rw,d,lcl,rel,con packet::.blkb $allsiz ; the packet buffer .psect $code ; /62/ missed this in the last edit.. .sbttl SET LINE ; /BBS/ moved this here set$li::tst xl.lock ; can current device go away? beq 1$ ; no problem mov #er$150 ,r0 ; big problem br 45$ ; go handle it 1$: upcase argbuf ; ensure case is correct.. strlen argbuf ; get length of device name add argbuf ,r0 ; then point to end of it cmpb -(r0) ,#': ; is last byte a colon? beq 43$ ; ya tstb (r0)+ ; no, bump to where colon goes movb #': ,(r0)+ ; insert same after device name clrb @r0 ; and re-terminate 43$: calls assdev , ; try to get the exec to allocate it tst r0 ; did the allocation work? beq 60$ ; ya.. 45$: direrr r0 ; no, print out the directive error call incsts ; /62/ flag there was an error clr r0 ; error just handled sec ; so CONNECT can detect error br 80$ ; done 60$: tst tt$io ; /62/ talking to TT? beq 70$ ; no clrb ttname ; ya, clear the name clr cl$line ; not using a TSX port any more mov sp ,remote ; we are now the remote system br 77$ 70$: strcpy #ttname ,argbuf ; /62/ moved this here.. mov cl.line ,cl$line ; save perm copy of TSX port # clr remote ; no longer are we remote 77$: tst infomsg ; SET TT QUIET? beq 79$ ; ya call sho$line ; no, display the new line 79$: clr r0 ; error handled above 80$: return .sbttl Assign the link device assdev::mov @r5 ,r0 ; get the first character of the name cmpb #'T&137 ,(r0)+ ; a "T" ? bne 3$ ; nope.. cmpb #'T&137 ,(r0)+ ; a second "T" ? bne 3$ ; nope.. tstb @r0 ; "TT" beq 11$ ; is okie.. cmpb #': ,(r0)+ ; so iz "TT:" bne 3$ ; this ain't it tstb @r0 ; must be null beq 11$ ; ok 3$: tst r50dev ; is something already in use? beq 4$ ; no mov #er$140 ,r0 ; ya, got to drop it first br 5$ 4$: call x.assdev ; try to talk to it 5$: return 11$: mov mready ,-(sp) ; save modem status call c$idle ; reset modem, if need be.. tst (sp)+ ; was there a modem? beq 111$ ; nope calls suspend ,<#0,settle> ; ya, let it settle 111$: call xl.dump ; drop handler interrupts tst tsxcl ; was prior line a CL unit? beq 12$ ; nope call cl.dump ; dump possible CL cross-connect 12$: clr r50dev ; not a handler now.. clr xkspeed ; kludge, can't get from handler clr b4speed ; hose any fallback reset speed clr tsxcl ; can't be this now mov sp ,tt$io ; /62/ flag to do I/O via TT tst tsxsav ; real TSX+ ? bne 100$ ; /62/ ya, that's it.. tst parity ; /BBS/ parity already set up? bne 20$ ; /39/ yes mov #par$space,parity ; /39/ need 8-bit quoting also 20$: mov #60. ,senlen ; /62/ console port won't XOFF fast movb #60. ,senpar+p.spsiz ; /62/ enough, do receive size too clr dolong ; need this too.. clr reclng ; and this just to be safe 100$: clr r0 return .sbttl Drop the comm handler xl.dump::tst r50dev ; /BBS/ newer better way to bomb it beq 999$ ; no device to hose .spfun #rtwork,#xc.control,#dtrdrv,#0,#0,#1 ; /62/ drop DTR and RTS calls suspend ,<#0,settle> ; let any external hardware settle.. mov #offdrv ,r1 ; preset for RT-11 tst tsxcl ; TSX and CL? beq 993$ ; no cmp tsxver ,#600. ; ya, but is it V6.00 or above? blo 993$ ; no mov #clhose ,r1 ; ya 993$: .spfun #rtwork,#xc.control,r1,#0,#0,#1 ; /62/ disable interrupts tst xl.lock ; /62/ can monitor .close the handler? bne 995$ ; /62/ no cmp rt11ver ,#5 ; /62/ is this RT-11 V5 or above? blt 995$ ; /62/ no, V4 can't abort I/O.. ; /62/ .abtio #lun.xk ; /62/ ya, dump any lingering data MOV #lun.xk+<11.*^o400>,R0 ; /62/ expanded for assy under V4 EMT ^o374 ; /62/ even though V4 can't run it .close #lun.xk ; /62/ close its chan ; /62/ .abtio #xc.control ; /62/ hose control chan MOV #xc.control+<11.*^o400>,R0 ; /62/ expanded for assy under V4 EMT ^o374 ; /62/ even though V4 can't run it .close #xc.control ; /62/ close it clr xcdone ; /62/ handler read no longer pending 995$: tst tsxsav ; running under TSX? beq 999$ ; no mov r50dev ,cl.r50 ; ya, copy name to call deallo ; deallocate the device 999$: return .sbttl Drop a CL unit cl.dump::save ; /BBS/ added this.. mov r50dev ,cl.r50 ; copy for emt mov r50dev ,r0 ; copy to extract CL unit number sub #^rCL ,r0 ; got it beq 777$ ; using "space' for "0" in unit number sub #36 ,r0 ; using existing unit number 777$: mov r0 ,cl.unit ; save it clr cl.line ; SET CLn LIN=0 tst z.atch ; did this pgm attach this line? beq 7771$ ; no mov #attcl ,r0 ; try to emt 375 ; deattach it clr z.atch ; nothing is now attached.. 7771$: call deallo ; DEALLOCATE even if not ALLOC'd by us unsave ; restore caller's error return .sbttl Deallocate the TSX+ comm handler deallo: movb #1 ,d.allo ; set to drop it mov #d.allo ,r0 ; try to emt 375 ; deallocate the device return .sbttl Init the link device ttyini::mov #L999$ ,r0 ; load possible choices call dispat ; dispatch as appropriate tst r0 ; did it work? beq 100$ ; ya direrr r0 ; no, handle error here, right away.. call incsts ; /62/ flag there was an error 100$: return .save .psect $pdata L999$: .word x.ttyini,t.ttyini .restore .sbttl Reset terminal after using it for file transfer or CONNECT ttyrst::mov ttparm ,@#jsw ; restore jsw .rctrlo ; force read of new jsw tst tsxsave ; running under TSX? bne 5$ ; ya, skip to TSX reset .gval #rtwork,#$tcfig ; restore terminal configuration cmp rt11ver ,#5 ; /62/ is this RT-11 V5 or above? bge 135$ ; /62/ ya, .poke will work tst montyp ; /62/ if XM and V4.. bgt 137$ ; /62/ ..tough luck mov ttpar2 ,(r0) ; /62/ otherwise, this is it br 137$ 135$: mov r0 ,r1 ; copy as poke eats r0 ; /62/ .poke #rtwork,r1,ttpar2 ; stuff back into memory MOV #rtwork ,R0 ; /62/ expanded to assemble under V4 MOV #28.*^o400+3,@R0 ; /62/ even though V4 can't run it MOV r1 ,2.(R0) ; /62/ MOV ttpar2 ,4.(R0) ; /62/ EMT ^o375 ; /62/ 137$: .rctrlo ; force update of $tcfig br 70$ ; skip TSX stuff 5$: save mov #1 ,r1 ; offset to second byte mov #11. ,r2 ; 11 of 'em to do 6$: movb #'P ,limits(r1) ; load deactivation prefix add #3 ,r1 ; bump to next string sob r2 ,6$ ; next one wrtall #limits ; reset TSX activation chars tstb vl$chr ; if 0 windowing was left on beq 7$ ; so no need to resume it here mov #w$resume,r0 ; resume TSX emt 375 ; window processing 7$: unsave 70$: clr r0 ; success return .sbttl SET MODEM_TYPE ; /BBS/ almost 100% new.. .enabl lsb ; /62/ moved here to shrink KRTDIA set$mo::strcpy #spare1 ,#modem ; save copy of what's there now mov modtype ,r4 ; address of its structure mov mready ,r3 ; and its status upcase argbuf ; upper case the argument copyz argbuf ,#modem ,#40 ; copy new modem name over call findmodem ; and look for it in the list tst r0 ; did it work? bne 10$ ; ya strcpy #modem ,#spare1 ; no, restore the old modem type mov r3 ,mready ; its status mov r4 ,modtype ; and its structure's address call incsts ; flag error, so r0 can be cleared clr r0 ; strcpy, just above, trashes this reg return ; error already handled by findmodem 10$: clr blind ; reset this ; clr pulse ; commented out, phone line is same.. mov dial.time(r0),diatmo ; /62/ start with default time_out mov time.set(r0) ,settle ; /62/ and settle_time mov #xresult ,r1 ; /62/ where to put new extended mode mov x.result(r0) ,r0 ; /62/ default supplied? bmi 101$ ; /62/ no, let null say it's nothing.. call L10012 ; /62/ ya, write it as ascii number(s) 101$: clrb (r1) ; /62/ null terminate the string clr r0 ; preset to no error tstb ttname ; is line to modem set yet? beq 11$ ; no call ttyhang ; ya, assert DTR on PRO, reset modem tst r0 ; did it work? bne 11$ ; no, ttyini handles its own error mov settle ,r0 ; /62/ double the wait here because asl r0 ; /62/ some modems are just too slow! calls suspend ,<#0,r0> ; /62/ let modem recover from DTR drop call set.mo ; shared code 11$: tst r0 ; did all this work? bne 999$ ; no, goto error handler return .sbttl SET DTR and HANGUP ; /62/ moved here to shrink KRTDIA set$dt::call set.dtr ; toggle DTR tst r0 ; did it work? bne 999$ ; no .newline return c$hang::call set.dtr ; toggle DTR tst r0 ; did it work? bne 999$ ; no message wrtall #ttname ; include the device name message < disconnected>,cr return 999$: direrr r0 ; dump error message call incsts ; flag error, so r0 can be cleared clr r0 ; only do error message once return .dsabl lsb .sbttl I/O dispatch ENTRY BINREAD ; binary read, send XON if no char ENTRY BINWRITE ; binary write ENTRY CANTYP ; (try to) cancel type_ahead ENTRY HOSE ; 100% hose the link device ENTRY DCDTST ; /62/ check DCD during transfers ENTRY INQCD ; is DCD there? ENTRY INQDTR ; is DTR there? (CL/KM handlers only) ENTRY SETSPD ; set speed ENTRY TTSPEED ; get speed (CL/KM handlers only) ENTRY TTXON ; clear local XOFF, send a ^Q ENTRY TTYFIN ; finished with the link device ENTRY TTYHAN ; hang up ENTRY XBINREAD ; no_XON_if_no_char binary read dispatch:tst tt$io ; /62/ talking to TT? bne tt.io ; ya.. jmp @(r0) ; /62/ no, it's a handler tt.io: tst (r0)+ ; bump to TT I/O address jmp @(r0) ; /62/ and call it .sbttl Shared read for XL .close problem SRDDRV = 203 ; special read, wc is max # of bytes ; to read, always returns at least one ; byte, up to max if data are there STATE = 2 ; <> flags scheduler to run the task readxk::tst xcdone ; is there a read already queued? bne 1$ ; /62/ ya, can't queue more than one mov sp ,xcdone ; /62/ no, but there is now.. mov #xkbuff ,xkpoint ; reset buffer pointer now clrb xkbuff ; and init it .spfun #xkrd1,#lun.xk,#srddrv,#xkbuff,#xksize,#1,#200$ ; read in data 1$: return 200$: clr xcdone ; /62/ flag a read completion tst xk.con ; here from CONNECT? beq 100$ ; no mov r0 ,-(sp) ; ya, get things going when we exit mov #xkhead ,r0 ; top of xkproc's entry in data table mov sp ,state(r0) ; flag to run, data are waiting for it mov (sp)+ ,r0 tst suspnd ; need to resume? beq 100$ ; no dec suspnd ; ya, make sure no one else does this .rsum ; resume mainline so xkproc can run 100$: return .sbttl Get input from a printing terminal kbread::save ; /BBS/ rewritten a bit.. bic #10000!100,@#jsw ; ditch single char input and nowait .rctrlo ; force read of new jsw tst tsxsav ; running under TSX? beq 1$ ; nope.. wrtall #m.tsxr ; if TSX, ensure LF echo is on 1$: mov @r5 ,r1 ; a buffer to put the chars clrb @r1 ; init buffer mov #ln$max ,r2 ; size of the buffer here ; /BBS/ NOTE: under TSX what actually happens here is the line is stored in ; an internal to TSX buffer until an "activation" character is received, ; in this case the return at the end of the line, then the whole thing ; is dumped into the program via .ttyin in one fell swoop.. this limits ; what might be done in advance of the return being typed, such as not ; echoing chars destined to be truncated - however on the whole it is ; all handled reasonably well by TSX as regards rubouts, retype, etc.. 10$: .ttyin ; read a character please cmpb r0 ,#'Z&37 ; ^Z ? bne 11$ ; no mov #cmd$ex ,r0 ; ya, distinguish it from ^C .. br 100$ ; bail out 11$: cmpb r0 ,#'C&37 ; ^C ? bne 13$ ; no mov #cmd$ab ,r0 ; ya, say it's an abort br 100$ ; bail out 13$: cmpb r0 ,#cr ; carriage return? beq 40$ ; ya, done tst r2 ; any room left in buffer? ble 10$ ; nope, truncate the rest movb r0 ,(r1)+ ; return what we just got dec r2 ; decrement what's left counter br 10$ ; and back for more 40$: emt 340 ; .ttinr to eat the LF after CR clrb @r1 ; null terminate the buffer sub @r5 ,r1 ; the length clr r0 ; no error.. 100$: unsave bis #10000!100,@#jsw ; restore single char & nowait input save ; /62/ save error code .rctrlo ; force read of new jsw unsave ; /62/ restore error code tst tsxsav ; running under TSX? beq 101$ ; no wrtall #m.tsxs ; if TSX, kill LF echo 101$: return .sbttl Get one char from TT read1c::.ttinr ; try to get a char bcc 90$ ; got one .twait #rtwork,#tsxwai ; nothing there, wait one tick br read1c ; and try again 90$: return .sbttl TT output in various ways ; /BBS/ heavily hacked .enabl lsb writ1ch::save .ttyou ; dump char mov xprint ,r1 ; send to LP? beq 99$ ; no save call putcr0 ; channel is passed in r1 unsave ; ignore any error.. 99$: unsave return wrtall::save mov 10(sp) ,r2 ; get string address loop: tstb (r2) ; done? beq 199$ ; yes, exit clr r0 ; init reg to avoid sign extension bisb (r2)+ ,r0 ; the character to write out .ttyou ; no, dump a byte mov xprint ,r1 ; dump to LP? beq loop ; no, continue call putcr0 ; channel is passed in r1 br loop ; continue 199$: unsave mov (sp)+ ,(sp) ; move return address up return l$nolf::save tst vttype ; unless it's a hard copy term beq 299$ ; it is .ttyou #cr ; it isn't, just a CR, no line feed.. br 300$ l$pcrlf::save 299$: .ttyou #cr .ttyou #lf 300$: mov xprint ,r1 ; dump to LP? beq 399$ ; no mov #cr ,r0 ; ya, add in a return call putcr0 mov #lf ,r0 ; and a line feed call putcr0 399$: unsave return .dsabl lsb .sbttl Clear the console, hose all pending terminal input clrcns::call chkabo ; try to get a byte of input tst r0 ; get it? bne clrcns ; ya, loop until nothing is left return .sbttl Check for abort, see if anything typed at the terminal chkabo::.ttinr ; nowait TT input bcc 11$ ; got something clr r0 ; got nothing 11$: return .end