home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / mszrmx.a86 < prev    next >
Text File  |  2020-01-01  |  67KB  |  2,102 lines

  1.         NAME    MSZRMX
  2. true    equ     1
  3. escbslh equ     5c1bh           ; ESC \
  4. escbrac equ     5d1bh           ; ESC ]
  5. $INCLUDE(mssdef.h86)
  6.  
  7. %*DEFINE(pushv(v))(%IF(%OS EQ 286)THEN(push     %v)ELSE(mov     ax,%v
  8.         push    ax)FI)
  9.  
  10. datas   segment
  11.  
  12.         public  citok, cotok, mbox, tmbox, sigpair, sematok, bufill, ciptr
  13.         public  cifill, cibuf1, cibuf2, combx, cimbx, termatt, oneport
  14.         public  subpksz, trok, source, trmstr, temp, machnam
  15.  
  16.         extrn   sintok:word, srcptr:word, takadr:word, taklev:byte, comand:byte
  17.         extrn   portval:word, savsi:word, xofsnt:byte, portatt:word
  18.         extrn   costrt:word, coptr:word, flags:byte, pack:byte, dtrtime:word
  19.         extrn   bdtab:byte, bddat:word
  20.  
  21. env     db      0,0             ; "environment" must be on PARA boundary
  22. machnam db      21 dup(' ')
  23. trmstr  db      6,':TERM:'
  24. lp      db      4,':LP:'
  25. bb      db      4,':BB:'
  26. work    db      6,':WORK:'
  27. dolsgn  db      1,'$'
  28. rqglob  db      8,'RQGLOBAL'
  29. dotini  db      'MSKERMIT.INI',0
  30. kermtmp db      '$kermit$.tmp ',0       ; Kermit's DOS name for scratch file
  31.  
  32. sigpair dw      0
  33.         db      3                       ; control C
  34.  
  35. kilpair dw      0
  36.         db      0
  37.  
  38. setosc  db      ESCAPE,']C:T=1,E=1,R=1,O=1,C=2;T:R=1',ESCAPE,'\'
  39. flush   db      ESCAPE,']C:T=3',ESCAPE,'\'
  40. escapec db      ESCAPE,'c'
  41. printer db      'PRN',0
  42. typecmd db      'type '
  43. delcmd  db      'del '
  44. chkdsk  db      'chkdsk.com'
  45. dirfree db      'dir $ free',cr
  46.  
  47. delrmx  db      'delete '               ; keep these 2 lines together
  48. deltail db      73 dup(?)
  49.  
  50. wccmd   db      0,'WC '                 ; keep these 2 lines together
  51. wcpath  db      80 dup(?)
  52.  
  53. pushmsg db      cr,lf,'PUSH not implemented, use RUN whatever$'
  54. syserr  db      cr,lf,'Your version of MSKERMIT used an unsupported DOS '
  55.         db      'function call'
  56. crlf    db      cr,lf,'$'
  57. cfgerr  db      cr,lf,'Configuration error',cr,lf,'$'
  58. killmsg db      cr,lf,'Only 1st KILL accepted',cr,lf,'$'
  59. mbmsg   db      cr,lf,'MAX-BAUD error',cr,lf,'$'
  60. oscmsg  db      cr,lf,'OSC error',cr,lf,'$'
  61. prmsg   db      cr,lf,'Priority error',cr,lf,'$'
  62. nmsg    db      cr,lf,'Number > 0ffh',cr,lf,'$'
  63. dnmsg   db      cr,lf,'Must be decimal number',cr,lf,'$'
  64. nxtflg  db      1
  65. oneport db      0
  66. codone  db      ?
  67. esc_c   db      0
  68. trok    db      0
  69.  
  70. $SAVE NOGEN
  71. comtab  db      13
  72.         %mkeyw  (%('bufill'),fillbuf)
  73.         %mkeyw  (%('cifill'),fillci)
  74.         %mkeyw  (%('co-delay'),codel)
  75.         %mkeyw  (%('dtr-time'),dtr)
  76.         %mkeyw  (%('echo'),takset)
  77.         %mkeyw  (%('escc'),esccset)
  78.         %mkeyw  (%('kill'),kill)
  79.         %mkeyw  (%('max-baud'),maxbd)
  80.         %mkeyw  (%('no-modem'),nomdm)
  81.         %mkeyw  (%('osc'),osc)
  82.         %mkeyw  (%('priority'),prior)
  83.         %mkeyw  (%('sub-pack'),subpack)
  84.         %mkeyw  (%('translate'),trnslt)
  85. $RESTORE
  86.  
  87.         even
  88. citok   dw      ?               ; DON'T reorder citok, cotok, lptok lines
  89. cotok   dw      3 dup (?)
  90. lptok   dw      ?
  91.  
  92.  
  93. sematok dw      ?
  94. initok  dw      0
  95. globtok dw      ?
  96. doltok  dw      ?
  97. scfitok dw      ?
  98. rcmdtok dw      ?
  99. mbox    dw      ?
  100. tmbox   dw      ?
  101. cimbx   dw      ?
  102. combx   dw      ?
  103. kbuf    dw      ?
  104. cmdtok  dw      ?
  105. xitcode dw      40ffh
  106. savebx  dw      ?
  107. status  dw      ?
  108. ccstat  dw      ?
  109. siostat dw      ?
  110. priorty dw      254
  111. bufill  dw      0ffffh
  112. cifill  dw      8080h
  113. subpksz dw      60
  114. codelay dw      6
  115. ciptr   dw      offset cibuf1
  116. cistrt  dw      ?
  117. inisize dw      ?
  118. savspec dw      12,12,12 dup (0)
  119. termatt dw      2,2,2 dup (?)   ; terminal port attributes for special
  120. ignore  dw      ?
  121. xcepinf dw      3 dup (0)
  122.  
  123. temp    dw      110 dup(?)
  124.         org     offset temp
  125.         db      'Copyright 1988, John Bryans.'
  126.         db      'Permission is granted to copy and give away,'
  127.         db      'but not to sell for profit any form of this program.'
  128.         db      'No Warranties Whatsoever'
  129.         org     offset temp+size temp
  130.  
  131. cibuf1  db      cibufl dup (?)
  132. cibuf2  db      cibufl dup (?)
  133. cobuf1  db      cobufl dup (?)
  134. cobuf2  db      cobufl dup (?)
  135.  
  136. source  db      bufsiz dup(0)                   ; serial input buffer
  137.  
  138. PURGE   conin,conout,lstout,dconio,coninq,prstr,seldsk,gcurdsk,setdma,gettim
  139. PURGE   dosver,gswitch,chdir,creat2,open2,close2,readf2,write2,del2,lseek,gcd
  140. PURGE   alloc,setblk,exec,first2,next2
  141.  
  142. dosf    dw      notimp          ; DOS function call jump table
  143.         dw      conin
  144.         dw      conout
  145.         dw      2 dup(notimp)
  146.         dw      lstout
  147.         dw      dconio
  148.         dw      coninq
  149.         dw      rkbd
  150.         dw      prstr
  151.         dw      4 dup(notimp)
  152.         dw      seldsk
  153.         dw      10 dup(notimp)
  154.         dw      gcurdsk
  155.         dw      setdma
  156.         dw      10 dup(notimp)
  157.         dw      setintv
  158.         dw      6 dup(notimp)
  159.         dw      gettim
  160.         dw      3 dup(notimp)
  161.         dw      dosver
  162.         dw      4 dup(notimp)
  163.         dw      getintv
  164.         dw      notimp
  165.         dw      gswitch
  166.         dw      3 dup(notimp)
  167.         dw      chdir
  168.         dw      creat2
  169.         dw      open2
  170.         dw      close2
  171.         dw      readf2
  172.         dw      write2
  173.         dw      del2
  174.         dw      lseek
  175.         dw      4 dup(notimp)
  176.         dw      gcd
  177.         dw      alloc
  178.         dw      notimp
  179.         dw      setblk
  180.         dw      exec
  181.         dw      exit
  182.         dw      notimp
  183.         dw      first2
  184.         dw      next2
  185. dosfl   equ     ($-dosf-2)/2
  186.  
  187. datas   ends
  188. %IF (%OS EQ 86) THEN (
  189. stack   segment stack 'stack'
  190.         dw      750 dup(?)
  191. stack   ends
  192. ) ELSE (
  193. stack   stackseg 1500
  194. )FI
  195. code    segment
  196.         public  dosint, crfile, opfile, special, writer, delcon, prstr, dconio
  197.         public  aopen, aclose, awrite, aspcl, waitio, sendms, rcvmsg, delseg
  198.         public  gfilsta, flushci
  199.  
  200.         extrn   start:near, outchr:near, takrd:near, prompt:near, comnd:near
  201.         extrn   takset:near, atoi:near, katoi:near
  202.  
  203.         extrn   dqdecodetime:near, dqgetsystemid:near
  204.  
  205.         extrn   rqcgetchar:near, rqcgetcommandname:near
  206.         extrn   rqccreatecommandconnection:near, rqcsendcommand:near
  207.  
  208.         extrn   rqsopen:near, rqsdeleteconnection:near, rqsattachfile:near
  209.         extrn   rqsreadmove:near, rqsseek:near, rqsgetconnectionstatus:near
  210.         extrn   rqscreatefile:near, rqswritemove:near, rqsspecial:near
  211.         extrn   rqsgetfilestatus:near, rqsdeletefile:near, rqsclose:near
  212.         extrn   rqstruncatefile:near, rqexitiojob:near
  213.  
  214.         extrn   rqaopen:near, rqaclose:near, rqaread:near, rqawrite:near
  215.         extrn   rqwaitio:near, rqaspecial:near, rqsetdefaultprefix:near
  216.  
  217.         extrn   rqsetexceptionhandler:near, rqsetpriority:near
  218.         extrn   rqcreatesemaphore:near, rqreceiveunits:near, rqcreatetask:near
  219.         extrn   rqcreatemailbox:near, rqreceivemessage:near, rqsendmessage:near
  220.         extrn   rqcreatesegment:near, rqdeletesegment:near, rqlookupobject:near
  221. %IF (%OS EQ 286) THEN (
  222.         extrn   rqegetaddress:near, rqecreatedescriptor:near
  223.         extrn   rqedeletedescriptor:near
  224. )FI
  225. psp:    jmp     stop            ; "program segment prefix"
  226.         db      10h             ; combined w/previous byte makes size>65K
  227.         db      0
  228.         db      9ah,0f0h,0ffh,0dh,0f0h  ; beats the hell out of me
  229.         dd      quitint         ; termination address
  230.         dd      cctask          ; control-break address
  231.         dd      quitint         ; critical error address
  232.         db      (psp+2ch)-$ dup(?)
  233.         dw      seg env         ; segment address of environment
  234.         db      (psp+50h)-$ dup(?)
  235. fake    proc    far
  236.         jmp     dosint          ; DOS function dispatcher entry
  237. fake    endp
  238.         db      (psp+80h)-$ dup(?)
  239. cline   db      82 dup(0)
  240.  
  241. begin   proc    far
  242.         call    setexcp
  243. %IF (%OS EQ 286) THEN (
  244.         push    cs
  245.         push    offset psp
  246.         push    ds
  247.         push    offset status
  248.         call    rqegetaddress
  249.         push    dx
  250.         push    ax
  251.         push    offset begin
  252.         push    ds
  253.         push    offset status
  254.         call    rqecreatedescriptor
  255. )ELSE(
  256.         mov     ax,cs
  257. )FI
  258.         mov     es,ax
  259.         mov     di,offset cline ; move command line to cline
  260.         sub     al,al
  261. L1:     inc     byte ptr es:cline
  262.         stosb                   ; clears count 1st time thru
  263.         push    es              ; save es & di
  264.         push    di
  265.         push    ds              ; al=call rqcgetchar(@status)
  266.         %pushv(offset status)
  267.         call    rqcgetchar
  268.         pop     di              ; restore es & di
  269.         pop     es
  270.         test    al,al           ; end of string?
  271.         jnz     L1              ; no
  272.         mov     byte ptr es:[di],cr     ; stuff cr
  273. %IF (%OS EQ 286) THEN (
  274.         push    es              ; let's not leave this descriptor laying around
  275.         push    ds
  276.         push    offset status
  277.         call    rqedeletedescriptor)FI
  278.  
  279.         call    crmbx           ; mbox=rqcreatemailbox(0,@status)
  280.         mov     mbox,ax
  281.         call    crmbx           ; tmbox=rqcreatemailbox(0,@status)
  282.         mov     tmbox,ax
  283.         call    crmbx           ; combx=rqcreatemailbox(0,@status)
  284.         mov     combx,ax
  285.         call    crmbx           ; cimbx=rqcreatemailbox(0,@status)
  286.         mov     cimbx,ax
  287.  
  288.         mov     di,offset work  ; scfitok=rqscreatefile(@(6,':WORK:'),@status)
  289.         call    crfile          ; scratch file is for wild card implementation
  290.         mov     scfitok,ax      ; (FIRST2 & NEXT2), and :CO: redirection (EXEC)
  291.  
  292.         mov     bx,3            ; call rqsopen(scfitok,3,2,@status)
  293.         mov     cx,2
  294.         call    opfile
  295.  
  296.         mov     di,offset trmstr
  297.         call    crfile
  298.         mov     citok,ax        ; citok=rqscreatefile(@(4,':TERM:'),@status)
  299.  
  300.         mov     bx,3            ; call rqaopen(citok,3,3,0,@status)
  301.         call    aopen
  302.  
  303.         mov     di,offset trmstr
  304.         call    crfile
  305.         mov     cotok,ax        ; cotok=rqscreatefile(@(4,':TERM:'),@status)
  306.         mov     cotok+2,ax
  307.         mov     cotok+4,ax
  308.  
  309.         mov     bx,3            ; call rqsopen(cotok,3,3,@status)
  310.         mov     cx,bx
  311.         call    opfile
  312.  
  313.         mov     ax,cotok        ; call rqsspecial(cotok,4,@savspec,0,@status)
  314.         mov     bx,offset savspec
  315.         mov     cx,4
  316.         call    special
  317.         test    savspec+18,8000h
  318.         js      L2
  319.         mov     word ptr savspec+2,7
  320.  
  321. L2:     mov     ax,citok        ; set OSCs for :CI:
  322.         mov     bx,offset setosc
  323.         mov     cx,size setosc
  324.         sub     dx,dx
  325.         call    awrite
  326.  
  327.         mov     ax,cotok        ; set OSCs for :CO:
  328.         mov     bx,offset setosc
  329.         mov     cx,size setosc
  330.         call    writer
  331.  
  332.         mov     ax,citok        ; rumor has it write before read
  333.         mov     bx,offset crlf  ; is s'posed to convince Terminal Support Code
  334.         mov     cx,2            ; we're serious about wanting transparent input
  335.         mov     dx,tmbox
  336.         call    awrite
  337.  
  338.         push    ds              ; get pathname that called us
  339.         %pushv(offset cobuf1)   ; stash @cobuf1
  340.         %pushv(size cobuf1)     ; call rqgetcommandname
  341.         push    ds              ;       (@cobuf1,size cobuf1,@status)
  342.         %pushv(offset status)
  343.         call    rqcgetcommandname
  344.  
  345.         mov     ax,citok        ; wait for TSC to settle down
  346.         mov     bx,tmbox        ; necessary for 386's & lickety-split 286's
  347.         call    waitio
  348.  
  349.         mov     ax,ds           ; back scan to last path separator
  350.         mov     es,ax
  351.         mov     bl,cobuf1
  352.         sub     bh,bh
  353.         lea     si,cobuf1[bx]
  354.         call    bakscan         ; si=file name ptr, bx=its length, al=separator
  355.  
  356. ; The full string @cobuf1 is used to look for .cfg & .ini in the dir from which
  357. ; Kermit was loaded.  The mid-string, @si-1, is used to look in :$:.
  358.  
  359.         mov     [bx+si],'c.'            ; catenate '.cfg'
  360.         mov     [bx+si+2],'gf'
  361.         dec     si                      ; byte before file name for string count
  362.         mov     word ptr cobuf2,si      ; save ptr
  363.         add     cobuf1,4                ; bump length of full string for .cfg
  364.         add     bl,4                    ; bump length of mid-string
  365.         mov     [si],bl                 ; RMX string for lookup in :$:
  366.         mov     ah,bl                   ; ah=current byte @si, al=old char @si
  367.         cmp     si,offset cobuf1        ; if no path, use bl for old char
  368.         jne     L3
  369.         mov     al,bl                   ; instead of the one from bakscan
  370. L3:     mov     word ptr cobuf2+2,ax    ; save them
  371.  
  372.         call    cfgini                  ; look for .cfg, open, size to dx:si
  373.         jcxz    L4                      ; OK?
  374.         jmp     short L7                ; no, do .ini
  375. L4:     inc     taklev
  376.         add     takadr,size takinfo
  377.         mov     di,takadr
  378.         mov     [di].takhnd,ax          ; token
  379.         mov     [di].taktyp,0feh        ; mark as take
  380.         mov     [di].takcnt,si          ; low size
  381.         mov     [di].takcnt+2,dx        ; high size
  382.         call    takrd
  383.  
  384. L5:     mov     ax,ds
  385.         mov     es,ax
  386.         mov     dx,offset dolsgn        ; ptr for prompt
  387.         call    prompt
  388.         cmp     taklev,0                ; done?
  389.         je      L7                      ; eq = yes
  390.         mov     dx,offset comtab        ; command table ptr
  391.         mov     bx,offset dolsgn        ; help ptr
  392.         mov     comand.cmcr,1
  393.         mov     ah,cmkey
  394.         call    comnd
  395.          jmp    short L6                ; error exit
  396.          nop
  397.         call    bx                      ; call cfg s/r
  398.         jmp     L5                      ; loop
  399.  
  400. L6:     mov     dx,offset cfgerr        ; output error msg & loop
  401.         call    prstr
  402.         jmp     L5
  403.  
  404. L7:     mov     si,word ptr cobuf2      ; point to mid-string
  405.         mov     ax,word ptr cobuf2+2    ; ah=mid-string count, al=path separator
  406.         mov     [si],ah
  407.         mov     bl,ah
  408.         sub     bh,bh
  409.         mov     byte ptr[bx+si],'i'     ; replace 'cfg' w/'ini'
  410.         dec     bx
  411.         dec     bx
  412.         mov     [bx+si],'ni'
  413.         call    cfgini                  ; look for .ini, open, size to dx:si
  414.         jcxz    L8                      ; found
  415.         jmp     short L9                ; not found
  416.  
  417. CFGINI  proc
  418.         mov     di,si
  419.         mov     temp,si                 ; save string pointer
  420.         call    atfile                  ; attach from :$:
  421.         jcxz    CGIN1                   ; z=found
  422.         mov     si,word ptr cobuf2      ; point to mid-string
  423.         mov     ax,word ptr cobuf2+2    ; al=path separator
  424.         mov     [si],al                 ; put it back
  425.         mov     di,offset cobuf1        ; point to full path
  426.         mov     temp,di                 ; save string pointer
  427.         call    atfile                  ; attach from full path
  428.         jcxz    CGIN1
  429.         ret
  430. CGIN1:  mov     temp+100,ax             ; save token
  431.         mov     bx,1
  432.         mov     cx,bx
  433.         call    opfile                  ; open for reading
  434.         jcxz    CGIN2
  435.         ret
  436. CGIN2:  mov     di,temp                 ; string pointer
  437.         call    gfilsta                 ; get file status to find size
  438.         mov     si,ax                   ; low order file size
  439.         mov     ax,temp+100             ; token
  440.         ret
  441. CFGINI  endp
  442.  
  443. L8:     mov     inisize,si              ; size of .ini
  444.         mov     initok,ax               ; close KERMIT.INI,
  445.         call    clfile                  ; but leave attached for open2
  446.  
  447. L9:     mov     ax,cotok                ; save configured attributes
  448.         mov     bx,offset termatt       ; for ping-ponging
  449.         mov     cx,4
  450.         call    special
  451.  
  452.         call    crsema                  ; sematok=rqcreatesemaphore(0,1,0,@statu
  453.         mov     sematok,ax
  454.         mov     sigpair,ax              ; for ^C trapping
  455.  
  456.         mov     ax,citok                ; establish ^C & sematok as signal pair
  457.         mov     cx,6
  458.         mov     bx,offset sigpair
  459.         call    aspcl
  460.  
  461.         mov     bx,offset cctask        ; call rqcreatetask
  462.         call    crtsk                   ;    (0,@cctask,datas,0,300,0,@status)
  463.  
  464.         mov     bx,offset siotsk        ; call rqcreatetask
  465.         call    crtsk                   ;    (0,@siotsk,datas,0,300,0,@status)
  466.  
  467.         mov     bx,offset citsk         ; call rqcreatetask
  468.         call    crtsk                   ;    (0,@citsk,datas,0,300,0,@status)
  469.  
  470.         mov     bx,offset cotsk         ; call rqcreatetask
  471.         call    crtsk                   ;    (0,@cotsk,datas,0,300,0,@status)
  472.  
  473.         mov     di,offset lp    ; lptok=rqscreatefile(@(4,':LP:'),@status)
  474.         call    crfile
  475.         jcxz    L10             ; jump if OK
  476.         mov     di,offset bb    ; otherwise use :BB:
  477.         call    crfile
  478. L10:    mov     lptok,ax
  479.  
  480.         mov     bx,2            ; call rqsopen(lptok,2,2,@status)
  481.         mov     cx,bx
  482.         call    opfile
  483.  
  484.         mov     ax,citok        ; cmdtok = rqccreatecommandconnection(citok,
  485.         mov     bx,cotok        ;                       cotok,0,@status)
  486.         sub     cx,cx
  487.         call    crcmdco
  488.         mov     cmdtok,ax
  489.  
  490.         mov     ax,lptok        ; rcmdtok = rqccreatecommandconnection(lptok,
  491.         mov     bx,scfitok      ;                       scfitok,1,@status)
  492.         mov     cx,1            ; lptok forces error if ":CI:" gets read,
  493.         call    crcmdco         ; scfitok is ":CO:" redirected to scratch file
  494.         mov     rcmdtok,ax
  495.  
  496.         push    ds              ; call dqgetsystemid(@temp,@status)
  497.         %pushv(offset temp)
  498.         push    ds
  499.         %pushv(offset status)
  500.         call    dqgetsystemid
  501.         mov     ax,ds           ; use system id for machine name
  502.         mov     es,ax
  503.         mov     si,offset temp+1
  504.         mov     di,offset machnam
  505.         mov     cl,byte ptr temp
  506.         sub     ch,ch
  507.         rep movsb
  508.         mov     al,'$'          ; it's a $ terminated string
  509.         stosb
  510.  
  511.         mov     ax,cx
  512.         mov     bx,offset rqglob
  513.         call    lookup          ; globtok=rqlookupobject(0,@rqglob,0,@status)
  514.         mov     globtok,ax
  515.  
  516.         mov     bx,offset dolsgn
  517.         call    lookup          ; doltok=rqlookupobject(globtok,@dolsgn,0,@statu
  518.         mov     doltok,ax
  519.  
  520.         push    cx              ; call rqsetpriority(0,priorty,@status)
  521.         push    priorty
  522.         push    ds
  523.         %pushv(offset status)
  524.         call    rqsetpriority
  525.  
  526.         mov     ax,cs
  527.         mov     ds,ax           ; point ds & es to psp
  528.         mov     es,ax
  529.  
  530.         jmp     start           ; go to Kermit
  531.  
  532. begin   endp
  533.  
  534. ; cfg subroutines.
  535. ; Number conversion routines getn & getdn return to caller's caller on error
  536.  
  537. fillbuf proc
  538.         call    getn            ; convert backslash number
  539.         mov     bufill,ax       ; set serial input background fill
  540.         ret
  541. fillbuf endp
  542.  
  543. fillci  proc
  544.         call    getn            ; convert backslash number
  545.         mov     cifill,ax       ; set terminal input background fill
  546.         ret
  547. fillci  endp
  548.  
  549. codel   proc
  550.         call    getdn           ; convert decimal number
  551.         mov     codelay,ax      ; set connect mode terminal output buffer time
  552.         ret
  553. codel   endp
  554.  
  555. dtr     proc
  556.         call    getdn           ; convert decimal number
  557.         mov     dtrtime,ax      ; set time to hold DTR down
  558.         ret
  559. dtr     endp
  560.  
  561. esccset proc
  562.         mov     esc_c,true      ; enable sending ESC c (VT100 reset) on exit
  563.         ret
  564. esccset endp
  565.  
  566. kill    proc
  567.         call    getn            ; convert backslash number
  568.         cmp     kilpair,0       ; has task already been created?
  569.         jne     K1              ; ne = yes
  570.         mov     byte ptr kilpair+2,al   ; set control char to trap
  571.         call    crsema          ; kilpair=rqcreatesemaphore(0,1,0,@status)
  572.         mov     kilpair,ax
  573.         mov     bx,offset kiltsk
  574.         call    crtsk           ; create kill task
  575.         mov     ax,citok
  576.         mov     cx,6
  577.         mov     bx,offset kilpair
  578.         call    aspcl           ; establish trap char & kiltsk as signal pair
  579.         ret
  580. K1:     mov     dx,offset killmsg       ; don't let 'em do it twice
  581.         call    prstr
  582.         ret
  583. kill    endp
  584.  
  585. maxbd   proc
  586.         mov     dx,offset bdtab ; parse for baud rate
  587.         sub     bx,bx
  588.         mov     ah,cmkey
  589.         call    comnd
  590.          jmp    short MB1       ; NG, bitch
  591.          nop
  592.         mov     temp,bx         ; save baud ix
  593.         mov     ah,cmcfm        ; proper parsing ettiqutte
  594.         call    comnd
  595.          jmp    short MB1       ; NG, bitch
  596.          nop
  597.         mov     bx,temp         ; baud ix
  598.         inc     bx              ; next higher
  599.         mov     cx,baudsiz      ; baudsiz - (1+baud ix) is # wds to clear
  600.         sub     cx,bx           ; x2 is word ix
  601.         shl     bx,1
  602.         mov     ax,ds
  603.         mov     es,ax
  604.         sub     ax,ax
  605.         mov     di,offset bddat ; point to 1st word to clear
  606.         add     di,bx
  607.         cld
  608.         rep stosw               ; wipe 'em out
  609.         ret
  610. MB1:    mov     dx,offset mbmsg
  611.         call    prstr
  612.         ret
  613. maxbd   endp
  614.  
  615. nomdm   proc
  616.         and     portatt+6,0fff7h        ; turn off modem control bit
  617.         ret
  618. nomdm   endp
  619.  
  620. osc     proc
  621.         mov     ah,cmtxt        ; parse text upto cr to temp+2
  622.         mov     bx,offset temp+2
  623.         mov     dx,offset dolsgn
  624.         call    comnd
  625.          jmp    short OSCERR    ; NG
  626.          nop
  627.         mov     cl,ah
  628.         sub     ch,ch           ; cx = # bytes
  629.         mov     di,offset temp+2        ; point to start
  630.         mov     ax,ds
  631.         mov     es,ax
  632.         mov     al,' '
  633.         cld
  634.         repe scasb              ; discard leading blanks
  635.         je      OSCERR          ; empty, show indignation
  636.         xchg    bx,di           ; bx = 1st non-blank char ptr
  637.         dec     di              ; di = last char ptr
  638.         std
  639.         repe scasb              ; discard trailing blanks
  640.         cld
  641.         add     cl,6            ; cx = total length of OSC
  642.         inc     di
  643.         inc     di              ; point to plant trailer
  644.         sub     bx,3            ; point to plant lead-in
  645.         mov     [bx],escbrac    ; insert lead-in
  646.         mov     [di],escbslh    ; insert trailer
  647.         mov     ax,cotok
  648.         push    bx              ; save ptr for ci
  649.         push    cx              ; save count for ci
  650.         call    writer          ; write OSC to cotok
  651.         pop     cx
  652.         pop     bx
  653.         mov     ax,citok        ; write OSC to citok
  654.         sub     dx,dx
  655.         call    awrite
  656.         ret
  657. OSCERR: mov     dx,offset oscmsg
  658.         call    prstr
  659.         ret
  660. osc     endp
  661.  
  662. prior   proc
  663.         call    getn            ; convert backslash number
  664.         je      PRERR           ; getn compared to 255, reject if =
  665.         mov     byte ptr priorty,al     ; set priority
  666.         ret
  667. PRERR:  mov     dx,offset prmsg
  668.         call    prstr
  669.         ret
  670. prior   endp
  671.  
  672. subpack proc
  673.         call    getdn           ; convert decimal number
  674.         mov     subpksz,ax      ; set sub-packet size (tuning param for sending)
  675.         ret
  676. subpack endp
  677.  
  678. trnslt  proc
  679.         mov     trok,true       ; enable translation during connect
  680.         ret
  681. trnslt  endp
  682.  
  683. getn    proc    ; bags backslash #, converts it, ensures<256, returns in ah & al
  684.         mov     ah,cmfile       ; parse upto whitespace into temp
  685.         mov     bx,offset dolsgn
  686.         mov     dx,offset temp
  687.         mov     byte ptr temp,0
  688.         call    comnd
  689.          jmp    short NERR      ; NG return
  690.          nop
  691.         mov     si,offset temp  ; point to it
  692.         call    katoi           ; convert it
  693.         jc      NERR            ; carry set = NG
  694.         cmp     ax,0ffh         ; we want 255 max
  695.         ja      NERR
  696.         mov     ah,al           ; both bytes the same for word filling
  697.         ret
  698. NERR:   mov     dx,offset nmsg
  699.         call    prstr
  700.         pop     ax
  701.         ret
  702. getn    endp
  703.  
  704. getdn   proc    ; bags decimal number, converts it, returns it in ax
  705.         mov     ah,cmtxt        ; parse upto cr into temp
  706.         mov     bx,offset temp
  707.         mov     dx,offset dolsgn
  708.         mov     byte ptr[bx],0
  709.         call    comnd
  710.          jmp    short DNERR     ; NG return
  711.          nop
  712.         mov     si,offset temp  ; point to it
  713.         call    atoi            ; convert it
  714.          jmp    short DNERR     ; NG return
  715.          nop
  716.         ret                     ; got it, it's in ax
  717. DNERR:  mov     dx,offset dnmsg
  718.         call    prstr
  719.         pop     ax
  720.         ret
  721. getdn   endp
  722.  
  723. dosint  proc                    ; DOS function call table look up
  724.         push    ds
  725.         push    bx
  726.         mov     bx,datas
  727.         mov     ds,bx
  728.         pop     savebx
  729.         cmp     ah,dosfl
  730.         ja      notimp
  731.         sub     bh,bh
  732.         mov     bl,ah
  733.         rol     bx,1
  734.         call    dosf[bx]
  735.         mov     bx,savebx
  736.         pop     ds
  737.         ret
  738. dosint  endp
  739.  
  740. notimp:                         ; not implemented DOS function error routine
  741.         mov     dx,offset syserr
  742.         call    prstr
  743.  
  744. quitint proc    far
  745. stop:   mov     ax,datas
  746.         mov     ds,ax
  747.         mov     dx,offset crlf
  748.         call    prstr
  749.  
  750.         cmp     esc_c,true      ; is ESC c cfg'd?
  751.         jne     ST1             ; ne = no
  752.         mov     ax,cotok        ; give Terminal Support Code an ESC c
  753.         mov     bx,offset escapec       ; to restore terminal to initial state
  754.         mov     cx,size escapec
  755.         call    writer
  756.  
  757. ST1:    mov     ax,cotok        ; close to wait for output completion
  758.         call    clfile
  759.         mov     ax,citok        ; restore terminal attributes
  760.         mov     bx,offset savspec
  761.         mov     cx,5
  762.         call    aspcl
  763.  
  764.         mov     cx,globtok      ; restore $ directory
  765.         mov     ax,doltok       ; call rqsetdefaultprefix(globtok,doltok,@status
  766.         call    sdefpfx
  767.  
  768.         mov     cx,kilpair      ; was a kill kermit ctrl char established
  769.         jcxz    ST2             ; z = no
  770.         mov     ax,citok        ; yes, disestablish
  771.         mov     bx,offset kilpair
  772.         mov     word ptr[bx],0
  773.         mov     cx,6
  774.         call    aspcl
  775.  
  776. ST2:    mov     ax,citok        ; wait for completion before exit
  777.         mov     cx,tmbox
  778.         call    aclose
  779.         mov     ax,tmbox
  780.         mov     bx,0ffffh
  781.         call    rcvmsg
  782.  
  783.         push    xitcode         ; call rqexitiojob(xitcode,@0,@status)
  784.         sub     ax,ax
  785.         push    ax
  786.         push    ax
  787.         push    ds
  788.         %pushv(offset status)
  789.         call    rqexitiojob
  790. quitint endp
  791.  
  792. kiltsk  proc                    ; kill task
  793.         mov     ax,kilpair      ; wait for kill char to be typed
  794.         call    rcvun
  795.         jmp     STOP            ; then quit
  796. kiltsk  endp
  797.  
  798. cctask  proc    far             ; ^C task
  799. CCT:    mov     ax,sematok      ; wait for ^C to be typed
  800.         call    rcvun
  801.         mov     flags.cxzflg,'C'        ; slightly adapted (mostly stolen) from
  802.         mov     pack.state,'A'  ; MSSKER's intbrk
  803.         jmp     CCT
  804. cctask  endp
  805.  
  806. siotsk  proc    far             ; serial input task
  807.         call    setexcp         ; never call exception handler
  808. SIO1:   mov     bx,0ffffh       ; wait forever @ mbox for something to do
  809. SIO2:   mov     ax,mbox
  810.         call    rcvmsg
  811.         cmp     ax,mbox         ; if it's the token for mbox,
  812.         je      SIO6            ; it's SERINI asking us to crank up input
  813.         dec     cx              ; otherwise it's E$TIME or an IORS
  814.         jz      SIO3            ; it's E$TIME
  815.         call    delseg          ; it's an IORS, so delete it
  816. SIO3:   cmp     sintok,0        ; if the port has been reset,
  817.         je      SIO1            ; let the interrupts expire unanswered
  818.         cmp     xofsnt,true
  819.         jne     SIO4
  820.         mov     bx,50
  821.         jmp     SIO2
  822. SIO4:   call    sread           ; start aread & fill following buffer quadrant
  823.         mov     ax,srcptr
  824.         sub     ax,savsi        ; if there's at least 2 quadrants between next
  825.         jns     SIO5            ; quadrant & current pointer,
  826.         add     ax,bufsiz
  827. SIO5:   cmp     ax,bufsiz/2
  828.         jle     SIO1            ; we don't need to XOF, so wait for interrupt
  829.         mov     bx,portval
  830.         cmp     [bx].floflg,0   ; is flow control enabled?
  831.         je      SIO1            ; no
  832.         mov     ax,[bx].flowc   ; ouput whatever we're using for XOF
  833.         mov     ah,al
  834.         call    outchr
  835.          nop
  836.          nop
  837.          nop
  838.         mov     xofsnt,true
  839.         jmp     SIO1
  840. SIO6:   mov     ax,sintok               ; for aspecial to set it
  841.         mov     bx,offset portatt
  842.         or      word ptr[bx+4],3        ; change to flushing mode
  843.         mov     cx,5                    ; while we're at it
  844.         call    aspcl
  845. SIO7:   mov     ax,sintok
  846.         mov     bx,offset source        ; initialize
  847.         mov     savsi,bx                ; current byte ptr
  848.         mov     srcptr,bx               ; & next quadrant ptr
  849.         mov     cx,bufsiz               ; in case the ports on a buffered board
  850.         mov     dx,mbox                 ; flush it's buffer
  851.         call    aread
  852.         mov     ax,sintok
  853.         mov     bx,mbox
  854.         call    waitio
  855.         cmp     ax,bufsiz
  856.         je      SIO7                    ; no matter how big the damn thing is
  857.         mov     ax,sintok
  858.         mov     bx,offset portatt
  859.         and     word ptr[bx+4],0fffdh   ; change back to transparent mode
  860.         mov     cx,5
  861.         call    aspcl
  862.         mov     ax,ds                   ; fill 1st quadrant
  863.         mov     es,ax
  864.         mov     ax,bufill
  865.         mov     cx,bufsiz/8
  866.         mov     di,offset source
  867.         cld
  868.         rep stosw
  869.         call    sread                   ; start 1st read & fill 2nd quadrant
  870.         jmp     SIO4                    ; go do 2nd read
  871.  
  872. sread   proc
  873.         mov     ax,sintok
  874.         mov     bx,srcptr               ; next quadrant ptr
  875.         mov     cx,bufsiz/4
  876.         mov     dx,mbox
  877.         call    aread                   ; read current quadrant
  878.         mov     ax,ds
  879.         mov     es,ax
  880.         mov     ax,bufill
  881.         mov     cx,bufsiz/4
  882.         mov     di,srcptr
  883.         add     di,cx
  884.         cmp     di,bufsiz+offset source ; was it last quadrant
  885.         jl      SRD1                    ; no
  886.         mov     di,offset source        ; yes, point to 1st
  887. SRD1:   mov     srcptr,di               ; set next quadrant ptr
  888.         shr     cx,1
  889.         cld
  890.         rep stosw                       ; fill quadrant
  891.         ret
  892. sread   endp
  893. siotsk  endp
  894.  
  895. citsk   proc    far             ; read terminal task
  896.         call    setexcp
  897. CIT1:   mov     bx,offset cibuf1
  898. CIT2:   mov     cistrt,bx       ; set buffer ptr
  899.  
  900.         mov     ax,ds           ; fill it w/cifill
  901.         mov     es,ax
  902.         mov     di,bx
  903.         mov     cx,(size cibuf1)/2
  904.         mov     ax,cifill
  905.         cld
  906.         rep stosw
  907.  
  908.         mov     ax,citok        ; call rqaread
  909.         mov     cx,size cibuf1  ;       (citok,@buffer,size(buffer),cimbx,@statu
  910.         mov     dx,cimbx
  911.         call    aread
  912.  
  913. CIT3:   mov     ax,cimbx        ; wait for completion or task restart
  914.         mov     bx,0ffffh
  915.         call    rcvmsg
  916.  
  917.         cmp     ax,cimbx        ; if it's the mail box token, it's task restart
  918.         jne     CIT4            ; if, not it's an IORS
  919.         mov     bx,offset cibuf1
  920.         mov     ciptr,bx        ; initialize buffer & char pointers
  921.         jmp     CIT2            ; & start over
  922.  
  923. CIT4:   mov     es,ax           ; check IORS for "flushing" status
  924.         cmp     es:word ptr 0,2ch
  925.         pushf
  926.         call    delseg          ; delete IORS
  927.         popf                    ; "flushing" means suspend task,
  928.         je      CIT3            ; go wait for restart
  929.  
  930.         mov     bx,offset cibuf2
  931.         cmp     bx,cistrt       ; exchange buffers
  932.         je      CIT1
  933.         jmp     CIT2
  934. citsk   endp
  935.  
  936. cotsk   proc    far             ; write terminal task -- active in connect mode
  937.         call    setexcp
  938. COT1:   mov     ax,combx        ; wait for task start or IORS
  939.         mov     bx,0ffffh
  940.         call    rcvmsg
  941.  
  942.         cmp     ax,combx        ; if it's the mail box token, it's task start
  943.         je      COT2
  944.         call    delseg          ; otherwise it's an expiring IORS, delete it
  945.         jmp     COT1            ; & wait for task start
  946.  
  947. COT2:   mov     ax,cotok        ; task start.  close EIOS & re-open BIOS
  948.         call    clfile
  949.         mov     ax,cotok
  950.         mov     bx,2
  951.         mov     codone,bl       ; mark write complete
  952.         call    aopen
  953.  
  954. COT3:   mov     ax,offset cobuf1
  955. COT4:   mov     coptr,ax        ; byte ptr
  956.         mov     costrt,ax       ; buffer ptr
  957.  
  958. COT5:   mov     ax,combx        ; wait for timer, IORS, or suspend task request
  959.         mov     bx,codelay      ; default = 60 milliseconds
  960.         call    rcvmsg
  961.         jcxz    COT6            ; 0 = IORS or suspend task
  962.         cmp     codone,0        ; timeout.  Is write complete?
  963.         jne     COT7            ; ne = yes
  964.         jmp     COT5            ; no, wait for it
  965.  
  966. COT6:   cmp     ax,combx        ; if mail box token
  967.         je      COT9            ; it's suspend task request
  968.         mov     codone,true     ; it's IORS, mark write complete
  969.         call    delseg          ; delete IORS
  970.  
  971. COT7:   mov     bx,costrt       ; buffer ptr
  972.         mov     cx,coptr        ; byte prt
  973.         sub     cx,bx           ; # bytes to write
  974.         jcxz    COT8            ; don't write 0
  975.         mov     ax,cotok        ; call rqawrite
  976.         mov     dx,combx        ;       (cotok,@buffer,nbytes,combx,@status)
  977.         call    awrite
  978.         mov     codone,0        ; mark write not finished
  979.  
  980. COT8:   mov     ax,offset cobuf2
  981.         cmp     ax,costrt       ; exchange buffers
  982.         je      COT3
  983.         jmp     COT4
  984.  
  985. COT9:   mov     ax,cotok        ; suspend task.  Close BIOS, wait for task start
  986.         call    aclose
  987.         jmp     COT1
  988. cotsk   endp
  989.  
  990. conin   proc
  991.         call    rkbd            ; read 1 from :CI: to al
  992.         push    dx
  993.         mov     dl,al           ; conout writes out dl
  994.         call    conout          ; echo it to :CO:
  995.         pop     dx
  996.         ret
  997. conin   endp
  998.  
  999. conout  proc
  1000.         call    save
  1001.         mov     ax,cotok        ; write dl to :CO:
  1002. CO1:    mov     cx,1
  1003.         mov     temp,dx
  1004.         mov     bx,offset temp
  1005.         call    writer
  1006.         call    rstr
  1007.         ret
  1008. conout  endp
  1009.  
  1010. lstout  proc
  1011.         call    save
  1012.         mov     ax,lptok        ; write dl to :LP:
  1013.         jmp     CO1
  1014. lstout  endp
  1015.  
  1016. dconio  proc
  1017.         cmp     dl,0ffh         ; if dl ain't ff,
  1018.         jne     conout          ; it's same as conout
  1019.         push    si
  1020.         push    cx
  1021.         call    rdci            ; read 1 from :CI: to temp, on return
  1022.         test    cx,cx           ; cx=1 if read, 0 if not, set zero flag if not
  1023.         pop     cx
  1024.         pop     si
  1025.         ret
  1026. dconio  endp
  1027.  
  1028. coninq  proc
  1029.         push    cx
  1030. DC1:    call    rdci            ; read 1 from :CI: to temp
  1031.         jcxz    DC1             ; 'til we get 1
  1032.         pop     cx
  1033.         ret
  1034. coninq  endp
  1035.  
  1036. rkbd    proc
  1037. RKBD1:  call    pollci          ; read 1 from :CI: to al
  1038.         je      RKBD1           ; 'til we get 1
  1039.         ret
  1040. rkbd    endp
  1041.  
  1042. rdci    proc
  1043.         sub     cx,cx
  1044.         cmp     flags.cxzflg,'C'        ; reads 1 from :CI: to temp, doesn't
  1045.         jne     RDC1                    ; wait, doesn't check ^C
  1046.         mov     flags.cxzflg,ch         ; returns cx=1 if read, 0 if not
  1047.         mov     al,3
  1048.         jmp     short RDC2
  1049. RDC1:   call    pollci
  1050.         je      RDC3
  1051. RDC2:   inc     cx
  1052. RDC3:   ret
  1053. rdci    endp
  1054.  
  1055. pollci  proc
  1056.         push    si
  1057.         cmp     sintok,0        ; if serial port's active
  1058.         je      PCI1
  1059.         cmp     oneport,true    ; & oneport
  1060.         je      PCI3            ; return no character
  1061.  
  1062. PCI1:   mov     si,ciptr        ; next byte ptr
  1063.         lodsb
  1064.         cmp     al,byte ptr cifill
  1065.         je      PCI3            ; eq = no byte
  1066.         cmp     si,offset cibuf2 + size cibuf2
  1067.         jne     PCI2
  1068.         mov     si,offset cibuf1
  1069.         test    si,si           ; clear equal
  1070. PCI2:   mov     ciptr,si        ; set ptr for next byte
  1071. PCI3:   pop     si
  1072.         ret
  1073. pollci  endp
  1074.  
  1075. prstr   proc
  1076.         call    save    ; call rqswritemove(cotok,ds:dx,#char,@status)
  1077.         mov     ax,ds
  1078.         mov     es,ax
  1079.         mov     di,dx
  1080.         mov     cx,0ffffh
  1081.         mov     al,'$'
  1082.         repne scasb
  1083.         neg     cx
  1084.         add     cx,0fffeh       ; cx=#characters
  1085.         jcxz    PRSTR1          ; why bother
  1086.         mov     ax,cotok
  1087.         mov     bx,dx
  1088.         call    writer
  1089. PRSTR1: call    rstr
  1090.         ret
  1091. prstr   endp
  1092.  
  1093. seldsk  proc
  1094.         mov     al,1            ; what the hell, say there's 1
  1095.         ret
  1096. seldsk  endp
  1097.  
  1098. gcurdsk proc
  1099.         sub     al,al           ; always A: -- meaningless anyway
  1100.         ret
  1101. gcurdsk endp
  1102.  
  1103. setdma  proc
  1104.         mov     kbuf,dx         ; save disk transfer address, DTA
  1105.         ret
  1106. setdma  endp
  1107.  
  1108. setintv proc
  1109.         ret                     ; if KERMIT ever does more than
  1110. setintv endp                    ; setup int 23h, we're in trouble
  1111.  
  1112. gettim  proc
  1113.         call    save
  1114.         sub     ax,ax           ; let dword @temp be system time
  1115.         mov     temp,ax         ; set to 0, so decodetime returns current time
  1116.         mov     temp+2,ax
  1117.         push    ds              ; call dqdecodetime(@temp,@status)
  1118.         %pushv(offset temp)
  1119.         push    ds
  1120.         %pushv(offset status)
  1121.         call    dqdecodetime
  1122.         call    rstr
  1123.         push    ax
  1124.         mov     dx,temp+12
  1125.         call    asc2bin
  1126.         mov     ch,dl           ; ch=hours
  1127.         mov     dx,temp+15
  1128.         call    asc2bin
  1129.         mov     cl,dl           ; cl=minutes
  1130.         mov     dx,temp+18
  1131.         call    asc2bin
  1132.         mov     dh,dl           ; dh=seconds
  1133.         sub     dl,dl           ; dl=0 hundredths
  1134.         pop     ax
  1135.         ret
  1136. asc2bin proc
  1137.         sub     dx,'00'
  1138.         shl     dl,1
  1139.         mov     al,dl
  1140.         shl     dl,1
  1141.         shl     dl,1
  1142.         add     dl,al
  1143.         add     dl,dh
  1144.         ret
  1145. asc2bin endp
  1146. gettim  endp
  1147.  
  1148. dosver  proc
  1149.         mov     al,2            ; we're simulating DOS 2.x
  1150.         ret
  1151. dosver  endp
  1152.  
  1153. gswitch proc
  1154.         mov     dl,'/'          ; undocumented DOS get switch character
  1155.         ret
  1156. gswitch endp
  1157.  
  1158. getintv proc
  1159.         ret                     ; if KERMIT ever does more than
  1160. getintv endp                    ; setup int 23h, we're in trouble
  1161.  
  1162. chdir   proc
  1163.         call    save
  1164.         mov     ax,ds
  1165.         mov     es,ax
  1166.         mov     si,offset temp+1
  1167.         call    z2rmx           ; copy ASCIIZ string @ds:dx to temp+1
  1168.         mov     byte ptr temp,al
  1169.         mov     di,offset temp  ; length to temp makes it RMX string
  1170.         call    atfile          ; attach file
  1171.         jcxz    CHD2            ; jump if OK
  1172. CHD1:   call    rstr
  1173.         mov     ax,3            ; return error code w/carry set
  1174.         stc
  1175.         ret
  1176. CHD2:   mov     cx,globtok      ; call rqsetdefaultprefix(globtok,ax,@status)
  1177.         push    ax
  1178.         call    sdefpfx
  1179.         pop     ax
  1180.         jcxz    CHD3
  1181.         jmp     CHD1
  1182. CHD3:   call    sdefpfx         ; call rqsetdefaultprefix(0,ax,@status)
  1183.         call    rstr
  1184.         clc
  1185.         ret
  1186. chdir   endp
  1187.  
  1188. creat2  proc
  1189.         call    save
  1190.         mov     ax,ds
  1191.         mov     es,ax
  1192.         mov     si,offset printer       ; is it PRN ?
  1193.         mov     di,dx
  1194.         mov     cx,size printer
  1195.         repe cmpsb
  1196.         jne     CRF1                    ; ne=no
  1197.         call    rstr
  1198.         mov     ax,lptok                ; yes, use :LP:
  1199.         clc
  1200.         ret
  1201. CRF1:   call    cropsr
  1202.         jnc     CRF2
  1203.         call    exfisr
  1204.         jmp     short OP5
  1205. CRF2:   call    crfile                  ; create file
  1206.         mov     bx,3                    ; mode for OPEN & error return code
  1207.         mov     temp+2,bx               ; error return code
  1208.         jmp     short OP4
  1209.  
  1210. cropsr  proc
  1211.         mov     si,dx
  1212.         mov     di,offset kermtmp       ; is it "$kermit$.tmp"?
  1213.         mov     cx,size kermtmp
  1214.         repe cmpsb
  1215.         jne     CROP1
  1216.         mov     bx,scfitok              ; yes, use token for scratch file
  1217.         mov     temp,bx                 ; save it
  1218.         stc
  1219.         ret
  1220. CROP1:  mov     si,offset temp+3
  1221.         call    z2rmx                   ; ASCIIZ string to temp+3
  1222.         mov     di,offset temp+2        ; setup di
  1223.         mov     [di],al                 ; length makes it RMX string at temp+2
  1224.         clc
  1225.         ret
  1226. cropsr  endp
  1227.  
  1228. creat2  endp
  1229.  
  1230. open2   proc
  1231.         call    save
  1232.         sub     ah,ah                   ; convert DOS mode to RMX
  1233.         inc     ax
  1234.         mov     temp,ax                 ; save mode
  1235.         mov     ax,ds
  1236.         mov     es,ax
  1237.         mov     si,dx
  1238.         mov     di,offset dotini        ; is it MSKERMIT.INI?
  1239.         mov     cx,size dotini
  1240.         repe cmpsb
  1241.         jne     OP1                     ; no
  1242.         mov     ax,initok               ; yes, initok's already attached
  1243.         jmp     short OP3
  1244. OP1:    call    cropsr
  1245.         jnc     OP2
  1246.         call    rewind
  1247.         jmp     short OP5
  1248. OP2:    call    atfile
  1249. OP3:    mov     temp+2,2                ; error return code
  1250.         mov     bx,temp                 ; get mode
  1251. OP4:    mov     temp,ax                 ; save token
  1252.         mov     cx,2                    ; call rqsopen(token,mode,2,@status)
  1253.         call    opfile
  1254. OP5:    call    rstr
  1255.         mov     ax,temp                 ; return token to caller in ax
  1256.         mov     bx,temp+2               ; get error return code
  1257.         jmp     short CRYFLG
  1258. open2   endp
  1259.  
  1260. close2  proc
  1261.         mov     bx,savebx               ; savebx has file token
  1262.         cmp     bx,scfitok              ; if it's the scratch file,
  1263.         je      CL1                     ; don't you dare!
  1264.         cmp     bx,lptok                ; :LP:, neither
  1265.         je      CL1
  1266.         call    save
  1267.         mov     bx,savebx
  1268.         call    delcon                  ; delete connection
  1269.         call    rstr
  1270.         mov     bx,6                    ; error flag, if necessary
  1271.         jmp     short CRYFLG
  1272. CL1:    ret
  1273. close2  endp
  1274.  
  1275. readf2  proc
  1276.         call    save
  1277.         mov     ax,savebx               ; savebx has file token
  1278.         mov     bx,dx           ; nbyt=rqsreadmove(token,@buf,cnt,@status)
  1279.         call    reader
  1280. RF1:    mov     temp,ax                 ; save # bytes read
  1281.         call    rstr
  1282.         mov     ax,temp                 ; return to caller in ax
  1283.         mov     bx,6                    ; error flag, if necessary
  1284.         jmp     short CRYFLG
  1285. readf2  endp
  1286.  
  1287. write2  proc
  1288.         call    save
  1289.         mov     bx,savebx               ; savebx has file token
  1290.         test    bx,bx                   ; is it magic token 0 (CI)?
  1291.         jz      WRT1                    ; yes, let fail gracefully
  1292.         cmp     bx,4                    ; other magic tokens?
  1293.         ja      WRT1                    ; no
  1294.         shl     bx,1                    ; yes, lookup real token
  1295.         mov     bx,citok[bx]
  1296. WRT1:   mov     ax,bx
  1297.         mov     bx,dx           ; nbyt=rqswritemove(token,@buf,cnt,@status)
  1298.         call    writer
  1299.         jmp     RF1
  1300. write2  endp
  1301.  
  1302. del2    proc
  1303.         call    save
  1304.         mov     ax,ds
  1305.         mov     es,ax
  1306.         mov     si,offset temp+1        ; ASCIIZ string @ds:dx to temp+1
  1307.         call    z2rmx
  1308.         mov     bx,offset temp
  1309.         mov     byte ptr[bx],al         ; length makes it RMX string at temp
  1310.         push    ds                      ; call rqsdeletefile(@temp,@status)
  1311.         push    bx
  1312.         push    ds
  1313.         %pushv(offset status)
  1314.         call    rqsdeletefile
  1315.         call    rstr
  1316.         mov     bx,2                    ; error return code
  1317. CRYFLG: clc
  1318.         cmp     status,0                ; OK?
  1319.         je      CFLG1                   ; yes
  1320.         stc
  1321.         mov     ax,bx                   ; & return error code
  1322. CFLG1:  ret
  1323. del2    endp
  1324.  
  1325. lseek   proc
  1326.         call    save
  1327.         mov     bx,savebx       ; savebx has file token
  1328.         push    bx              ; save for get con. status
  1329.         add     al,2            ; convert DOS mode to RMX
  1330.         cbw
  1331.         call    seek
  1332.         pop     bx
  1333.         call    gconsta         ; getconnectionstatus puts file ptr
  1334.         call    rstr            ; in temp+4 & 6
  1335.         mov     ax,temp+4       ; dx:ax are file pointer
  1336.         mov     dx,temp+6
  1337.         mov     bx,6            ; error flag, if necessary
  1338.         jmp     CRYFLG
  1339. lseek   endp
  1340.  
  1341. alloc   proc
  1342.         call    save
  1343.         mov     ax,savebx       ; savebx has # paragraphs
  1344.         cmp     ax,1000h        ; is it 65K?
  1345.         jl      AL2             ; <65K, it's OK
  1346.         jne     AL1             ; >65K, too much
  1347.         sub     ax,ax           ; =65K, use 0 for full segment
  1348.         jmp     short AL2
  1349. AL1:    mov     status,ax       ; force error
  1350.         jmp     short AL3
  1351. AL2:    mov     cl,4            ; convert paragraphs to bytes
  1352.         shl     ax,cl
  1353.         push    ax              ; seg_base=rqcreatesegment(#bytes,@status)
  1354.         push    ds
  1355.         %pushv(offset status)
  1356.         call    rqcreatesegment
  1357.         mov     temp,ax         ; save
  1358. AL3:    call    rstr
  1359.         mov     ax,temp         ; restore seg_base return param
  1360.         mov     bx,8            ; error return code
  1361.         jmp     CRYFLG
  1362. alloc   endp
  1363.  
  1364. gcd     proc
  1365.         mov     byte ptr[si],0  ; return null string @ds:si
  1366.         clc
  1367.         ret
  1368. gcd     endp
  1369.  
  1370. setblk  proc
  1371.         ret
  1372. setblk  endp
  1373.  
  1374. PUSHCMD:                                ; actually, part of exec
  1375.         mov     dx,offset pushmsg       ; for now, say "no pushing"
  1376.         call    prstr                   ; but here's the spot to implement later
  1377.         call    rstr
  1378.         mov     ax,11
  1379.         stc
  1380.         ret
  1381.  
  1382. exec    proc
  1383.         call    save
  1384.         mov     bx,savebx               ; saved bx
  1385.         mov     di,es:[bx+2]            ; command tail pointer to es:di
  1386.         mov     es,es:[bx+4]
  1387.         sub     cx,cx
  1388.         mov     cl,es:[di]              ; if command tail length is 0, it's PUSH
  1389.         jcxz    PUSHCMD
  1390.         inc     di
  1391.         mov     al,' '
  1392.         repne scasb                     ; scan past DOSisms
  1393.         repe scasb
  1394.         dec     di                      ; 1st non-blank char of command
  1395.         mov     bx,di
  1396.         mov     dx,cx                   ; bx is ptr, dx is count
  1397.         mov     al,'>'                  ; if '>' appears, Kermit's asking for
  1398.         repne scasb                     ; redirected output
  1399.         mov     ax,cmdtok               ; if not, use ordinary cmd token
  1400.         jne     EX1                     ; ne = no redirection
  1401.         sub     dx,cx                   ; reduce count by chars from '>' to end
  1402.         dec     dx
  1403.         push    bx
  1404.         push    dx
  1405.         push    es
  1406.         call    exfisr                  ; rewind & truncate scratch file
  1407.         pop     es
  1408.         pop     dx
  1409.         pop     bx
  1410.         mov     ax,rcmdtok              ; use redirected cmd token
  1411.  
  1412. EX1:    mov     temp+100,ax             ; save cmd token
  1413.         mov     si,offset typecmd       ; is it 'TYPE'?
  1414.         mov     di,bx
  1415.         mov     cx,size typecmd
  1416.         repe cmpsb
  1417.         jne     EX2                     ; ne = no
  1418.         mov     [bx],'oc'               ; replace w/'COPY'
  1419.         mov     [bx+2],'yp'
  1420.         jmp     short EX4
  1421.  
  1422. EX2:    mov     si,offset delcmd        ; is it 'DEL'?
  1423.         mov     di,bx
  1424.         mov     cl,size delcmd
  1425.         repe cmpsb
  1426.         jne     EX3                     ; ne = no
  1427.         sub     dx,size delcmd          ; construct RMX DELETE command @delrmx
  1428.         mov     cx,dx
  1429.         mov     al,' '
  1430.         repe scasb
  1431.         dec     di
  1432.         inc     cx
  1433.         mov     dx,cx
  1434.         add     dx,size delrmx
  1435.         push    ds
  1436.         push    es
  1437.         pop     ds
  1438.         pop     es
  1439.         mov     si,di
  1440.         mov     di,offset deltail
  1441.         rep movsb
  1442.         mov     si,offset delrmx
  1443.         jmp     short EX5
  1444.  
  1445. EX3:    mov     si,offset chkdsk
  1446.         mov     di,bx
  1447.         mov     cl,size chkdsk
  1448.         repe cmpsb
  1449.         jne     EX4
  1450.         mov     bx,offset dirfree       ; yes, use 'dir $ free' as command
  1451.         mov     dx,size dirfree
  1452.         mov     cx,ds
  1453.         mov     es,cx
  1454.  
  1455. EX4:    push    ds                      ; swap ds & es
  1456.         push    es
  1457.         pop     ds
  1458.         pop     es
  1459.         mov     si,bx
  1460. EX5:    mov     di,offset temp          ; move command to temp
  1461.         mov     ax,dx
  1462.         stosb
  1463.         mov     cx,dx
  1464.         rep movsb
  1465.         push    es                      ; restore ds
  1466.         pop     ds
  1467.         mov     ax,temp+100             ; command token
  1468.         cmp     ax,rcmdtok              ; if output's going to scratch file
  1469.         je      EX6                     ; bypass fussing w/:TERM:
  1470.  
  1471.         mov     ax,citok                ; shut down citsk
  1472.         call    aclose
  1473.         mov     ax,citok                ; reopen
  1474.         mov     bx,3
  1475.         call    aopen
  1476.  
  1477.         call    flushci                 ; wait for output to :TERM: to finish
  1478.         mov     bx,offset savspec       ; ping back to user's connection &
  1479.         push    word ptr[bx+2]          ; terminal attributes
  1480.         mov     word ptr[bx+2],2
  1481.         mov     ax,cotok
  1482.         mov     cx,5
  1483.         call    special
  1484.         mov     ax,citok
  1485.         mov     bx,offset savspec
  1486.         mov     cx,5
  1487.         call    aspcl
  1488.         pop     savspec+2
  1489.  
  1490. EX6:    mov     ax,temp+100             ; command token
  1491.         push    ax                      ; save it
  1492.         mov     bx,offset temp          ; call rqcsendcommand
  1493.         mov     cx,offset temp+100      ;       (token,@temp,@temp+100,@status)
  1494.         call    sendcmd
  1495.         pop     ax                      ; command token
  1496.         cmp     ax,rcmdtok              ; if it went to scratch file,
  1497.         je      EX7                     ; don't mess w/:TERM:
  1498.  
  1499.         push    cx                      ; save status
  1500.         call    flushci                 ; wait for completion of cmd's output
  1501.         mov     ax,cotok                ; pong attr's back to Kermit's
  1502.         mov     bx,offset termatt
  1503.         mov     cx,5
  1504.         call    special
  1505.         mov     ax,citok
  1506.         mov     bx,offset termatt
  1507.         mov     cx,5
  1508.         call    aspcl
  1509.  
  1510.         mov     ax,cimbx                ; restart citsk
  1511.         mov     bx,ax
  1512.         call    sendms
  1513.         pop     cx                      ; restore status
  1514.  
  1515. EX7:    cmp     cx,83h                  ; is it E$CONTINUED
  1516.         je      EX8                     ; yes, return w/carry clear
  1517.         or      cx,temp+100             ; sendcmd status OR status from command
  1518.         jcxz    EX8                     ; jump if OK
  1519.         call    rstr
  1520.         mov     ax,2                    ; return error code w/carry set
  1521.         stc
  1522.         ret
  1523. EX8:    call    rstr
  1524.         clc
  1525.         ret
  1526.  
  1527. exfisr  proc                    ; rewind & truncate scratch file
  1528.         mov     bx,scfitok
  1529.         push    bx              ; save for truncate
  1530.         call    rewind          ; rewind scratch file
  1531.         push    ds              ; call rqstruncatefile(scfitok,@status)
  1532.         %pushv(offset status)
  1533.         call    rqstruncatefile
  1534.         ret
  1535. exfisr  endp
  1536.  
  1537. flushci proc
  1538.         mov     ax,citok        ; this is necessary to wait for completion
  1539.         mov     bx,offset flush ; of output to :TERM: for fast systems
  1540.         mov     cx,size flush
  1541.         sub     dx,dx
  1542.         call    awrite
  1543.         mov     ax,citok
  1544.         mov     bx,offset cobuf1
  1545.         mov     cx,cobufl
  1546.         mov     dx,tmbox
  1547.         call    aread
  1548.         mov     ax,citok
  1549.         mov     bx,tmbox
  1550.         call    waitio
  1551.         ret
  1552. flushci endp
  1553. exec    endp
  1554.  
  1555. exit    proc
  1556.         sub     ah,ah           ; convert DOS exit code to RMX
  1557.         test    ax,ax
  1558.         jz      X1
  1559.         mov     ah,40h          ; put in user range, if non-0
  1560. X1:     mov     xitcode,ax
  1561.         jmp     stop
  1562. exit    endp
  1563.  
  1564. first2  proc
  1565.         call    save
  1566.         mov     si,dx                   ; ds:dx points to ASCIIZ file name
  1567.         mov     ax,ds
  1568.         mov     es,ax
  1569.         mov     di,offset kermtmp       ; is it "$kermit$.tmp"?
  1570.         mov     temp+100,di
  1571.         mov     cx,size kermtmp
  1572.         mov     temp+102,cx
  1573.         repe cmpsb
  1574.         jne     FST2
  1575.         mov     bx,scfitok              ; yes, fill in DTA.  For scratch file,
  1576.         call    gconsta                 ; getconnectionstatus to temp
  1577.         mov     ax,temp+4               ; bx:ax are file pointer,
  1578.         mov     bx,temp+6               ; which is length of scratch file
  1579. FST1:   mov     di,kbuf
  1580.         mov     [di+1ah],ax             ; lo file size to DTA
  1581.         mov     [di+1ch],bx             ; hi file size to DTA
  1582.         mov     byte ptr [di+15h],0     ; clear DTA's attribute field
  1583.         add     di,1eh                  ; point to DTA's file name field
  1584.         mov     si,temp+100
  1585.         mov     cx,temp+102
  1586.         rep movsb
  1587.         call    rstr
  1588.         mov     bx,2
  1589.         jmp     CRYFLG
  1590.  
  1591. FST2:   mov     si,dx
  1592.         mov     di,offset dotini        ; is it MSKERMIT.INI?
  1593.         mov     temp+100,di
  1594.         mov     cx,size dotini
  1595.         mov     temp+102,cx
  1596.         sub     bx,bx
  1597.         repe cmpsb
  1598.         mov     ax,inisize
  1599.         je      FST1                    ; yes, initok's already attached
  1600.  
  1601.         mov     temp+100,2
  1602.         mov     si,dx
  1603.         cmp     word ptr[si],002ch      ; is it ',',0?
  1604.         je      NXT1                    ; eq = yes, treat as next
  1605.  
  1606.         push    es
  1607.         push    dx
  1608.         call    exfisr                  ; rewind & truncate scratch file
  1609.         pop     dx
  1610.         pop     es
  1611.  
  1612.         mov     si,offset wcpath        ; move file-spec to wcpath, length to ax
  1613.         call    z2rmx
  1614.         mov     bx,ax
  1615.         add     al,3
  1616.         mov     wccmd,al                ; + 3 for 'wc ' makes RMX string
  1617.         mov     si,dx                   ; point to file-spec
  1618.         mov     cx,bx                   ; length
  1619.  
  1620. FST3:   lodsb                           ; scan for wc chars, if any goto FST4
  1621.         cmp     al,'*'
  1622.         je      FST4
  1623.         cmp     al,'?'
  1624.         je      FST4
  1625.         cmp     al,','
  1626.         je      FST4
  1627.         loop    FST3
  1628.  
  1629.         mov     si,dx                   ; no need for wc, next can handle it
  1630.         mov     di,offset wcpath+1      ; if we move it over 1 byte
  1631.         mov     cx,bx
  1632.         rep movsb
  1633.         jmp     short NXT3
  1634.  
  1635. FST4:   mov     si,dx
  1636.         add     si,bx                   ; point to end
  1637.         dec     si                      ; backup over zero byte
  1638.         call    bakscan                 ; find rightmost path separater
  1639.         cmp     al,'\'                  ; is it \?
  1640.         jne     FST5
  1641.         call    rstr                    ; yes, force error
  1642.         mov     ax,2                    ; it's a DOSism we can do without
  1643.         stc
  1644.         ret
  1645.  
  1646. FST5:   mov     ax,rcmdtok              ; call rqcsendcommand
  1647.         mov     bx,offset wccmd         ;       (rcmdtok,@wccmd,@temp,@status)
  1648.         mov     cx,offset temp
  1649.         call    sendcmd
  1650.  
  1651.         mov     bx,scfitok              ; rewind scratch file
  1652.         call    rewind
  1653.         mov     nxtflg,0
  1654.         jmp     short NXT1              ; let next finish up
  1655. first2  endp
  1656.  
  1657. next2   proc
  1658.         call    save
  1659.         mov     temp+100,18             ; error return code
  1660.         cmp     nxtflg,0                ; was next called before 1st,
  1661.         jne     NXT4                    ; or after no more?  ne = yes
  1662.  
  1663. NXT1:   mov     bx,offset wcpath        ; place to stash file name string
  1664.         mov     byte ptr[bx],0          ; empty
  1665. NXT2:   inc     bx                      ; bump count
  1666.         push    bx
  1667.         mov     ax,scfitok              ; read 1 from scratch
  1668.         mov     cx,1
  1669.         call    reader
  1670.         test    ax,ax
  1671.         pop     bx
  1672.         jz      NXT4                    ; 0 = EOF
  1673.         cmp     byte ptr[bx],lf
  1674.         jne     NXT2                    ; loop 'til EOL
  1675.  
  1676.         sub     bx,offset wcpath+2      ; bx = length file name
  1677. NXT3:   mov     di,offset wcpath
  1678.         mov     [di],bl                 ; RMX string @di
  1679.         call    gfilsta                 ; does it exist?
  1680.         jcxz    NXT5                    ; 0 = yes
  1681. NXT4:   mov     nxtflg,1                ; mark no more next w/o 1st 1st
  1682.         call    rstr
  1683.         mov     ax,temp+100             ; return error code
  1684.         stc
  1685.         ret
  1686.  
  1687. NXT5:   mov     di,kbuf
  1688.         mov     [di+15h],bl             ; directory attribute to DTA
  1689.         mov     [di+1ah],ax             ; low file size
  1690.         mov     [di+1ch],dx             ; high file size
  1691.         mov     bl,byte ptr wcpath
  1692.         sub     bh,bh                   ; bx = length file name stirng
  1693.         lea     si,wcpath[bx]           ; point to end
  1694.         call    bakscan                 ; separate path/file name
  1695.         mov     cx,bx                   ; cx = file name length
  1696.         add     di,1eh                  ; DTA file name field ptr
  1697.         mov     ax,ds                   ; si points to file name, move it
  1698.         mov     es,ax
  1699.         rep movsb
  1700.         mov     [di],cl                 ; make ASCIIZ
  1701.         call    rstr
  1702.         clc
  1703.         ret
  1704. next2   endp
  1705.  
  1706. save    proc            ; save regs
  1707.         pop     bx
  1708.         push    es
  1709.         push    si
  1710.         push    di
  1711.         push    dx
  1712.         push    cx
  1713.         push    ax
  1714.         jmp     bx
  1715. save    endp
  1716.  
  1717. rstr    proc            ; restore regs
  1718.         pop     bx
  1719.         pop     ax
  1720.         pop     cx
  1721.         pop     dx
  1722.         pop     di
  1723.         pop     si
  1724.         pop     es
  1725.         jmp     bx
  1726. rstr    endp
  1727.  
  1728. setexcp proc
  1729.         push    ds      ; call rqsetexceptionhandler(@xcepinf,@status)
  1730.         %pushv(offset xcepinf)
  1731.         push    ds
  1732.         %pushv(offset status)
  1733.         call    rqsetexceptionhandler
  1734.         ret
  1735. setexcp endp
  1736.  
  1737. crtsk   proc            ; ax=rqcreatetask(0,cs:bx,ds,0:0,300h,0,@status)
  1738.         sub     cx,cx   ; bx is start address
  1739.         push    cx
  1740.         push    cs
  1741.         push    bx
  1742.         push    ds
  1743.         push    cx
  1744.         push    cx
  1745.         %pushv(300h)
  1746.         push    cx
  1747.         push    ds
  1748.         %pushv(offset status)
  1749.         call    rqcreatetask
  1750.         ret
  1751. crtsk   endp
  1752.  
  1753. crmbx   proc            ; ax=rqcreatemailbox(0,@status)
  1754.         %pushv(0)
  1755.         push    ds
  1756.         %pushv(offset status)
  1757.         call    rqcreatemailbox
  1758.         ret
  1759. crmbx   endp
  1760.  
  1761. crsema  proc
  1762.         sub     ax,ax   ; ax=rqcreatesemaphore(0,1,0,@status)
  1763.         push    ax
  1764.         inc     ax
  1765.         push    ax
  1766.         dec     ax
  1767.         push    ax
  1768.         push    ds
  1769.         %pushv(offset status)
  1770.         call    rqcreatesemaphore
  1771.         ret
  1772. crsema  endp
  1773.  
  1774. atfile  proc            ; ax=rqsattachfile(ds:di,@status)
  1775.         push    ds      ; ds:di is path ptr
  1776.         push    di
  1777.         push    ds
  1778.         %pushv(offset status)
  1779.         call    rqsattachfile
  1780.         ret
  1781. atfile  endp
  1782.  
  1783. crfile  proc            ; ax=rqscreatefile(ds:di,@status)
  1784.         push    di      ; ds:di is path ptr.  save di
  1785.         push    ds
  1786.         push    di
  1787.         push    ds
  1788.         %pushv(offset status)
  1789.         call    rqscreatefile
  1790.         pop     di      ; restore di
  1791.         ret
  1792. crfile  endp
  1793.  
  1794. opfile  proc            ; call rqsopen(ax,bx,cx,@status)
  1795.         push    ax      ; token
  1796.         push    bx      ; mode
  1797.         push    cx      ; number of buffers
  1798.         push    ds
  1799.         %pushv(offset status)
  1800.         call    rqsopen
  1801.         ret
  1802. opfile  endp
  1803.  
  1804. clfile  proc            ; call rqsclose(ax,@siostat)
  1805.         push    ax      ; token
  1806.         push    ds
  1807.         %pushv(offset siostat)
  1808.         call    rqsclose
  1809.         ret
  1810. clfile  endp
  1811.  
  1812. delcon  proc            ; call rqsdeleteconnection(bx,@status)
  1813.         push    bx      ; token
  1814.         push    ds
  1815.         %pushv(offset status)
  1816.         call    rqsdeleteconnection
  1817.         ret
  1818. delcon  endp
  1819.  
  1820. special proc            ; call rqsspecial(ax,cx,ds:bx,0,@status)
  1821.         push    ax      ; token
  1822.         push    cx      ; function
  1823.         push    ds
  1824.         push    bx      ; data ptr
  1825.         sub     ax,ax
  1826.         push    ax
  1827.         push    ax
  1828.         push    ds
  1829.         %pushv(offset status)
  1830.         call    rqsspecial
  1831.         ret
  1832. special endp
  1833.  
  1834. reader  proc            ; ax=rqsreadmove(ax,ds:bx,cx,@status)
  1835.         push    ax      ; token
  1836.         push    ds
  1837.         push    bx      ; buffer ptr
  1838.         push    cx      ; number of bytes
  1839.         push    ds
  1840.         %pushv(offset status)
  1841.         call    rqsreadmove
  1842.         ret
  1843. reader  endp
  1844.  
  1845. writer  proc            ; ax=rqswritemove(ax,ds:bx,cx,@status)
  1846.         push    ax      ; token
  1847.         push    ds
  1848.         push    bx      ; buffer ptr
  1849.         push    cx      ; number of bytes
  1850.         push    ds
  1851.         %pushv(offset status)
  1852.         call    rqswritemove
  1853.         ret
  1854. writer  endp
  1855.  
  1856. rewind  proc
  1857.         mov     ax,2    ; setup so seek positions to BOF
  1858.         sub     cx,cx
  1859.         mov     dx,cx
  1860.  
  1861. seek    proc
  1862.         push    bx      ; call rqsseek(token,mode,count,@status)
  1863.         push    ax
  1864.         push    cx
  1865.         push    dx
  1866.         push    ds
  1867.         %pushv(offset status)
  1868.         call    rqsseek
  1869.         ret
  1870. seek    endp
  1871. rewind  endp
  1872.  
  1873. lookup  proc            ; ax=rqlookupobject(ax,ds:bx,0,@status)
  1874.         push    ax      ; job token
  1875.         push    ds      ; @name
  1876.         push    bx
  1877.         push    cx      ; time limit
  1878.         push    ds
  1879.         %pushv(offset status)
  1880.         call    rqlookupobject
  1881.         ret
  1882. lookup  endp
  1883.  
  1884. sdefpfx proc            ; call rqsetdefaultprefix(cx,ax,@status)
  1885.         push    cx      ; job token
  1886.         push    ax      ; prefix token
  1887.         push    ds
  1888.         %pushv(offset status)
  1889.         call    rqsetdefaultprefix
  1890.         ret
  1891. sdefpfx endp
  1892.  
  1893. crcmdco proc            ; ax=rqccreatecommandconnection(ax,bx,cx,@status)
  1894.         push    ax      ; input token
  1895.         push    bx      ; output token
  1896.         push    cx      ; flag
  1897.         push    ds
  1898.         %pushv(offset status)
  1899.         call    rqccreatecommandconnection      ; can you believe this shit?
  1900.         ret
  1901. crcmdco endp
  1902.  
  1903. sendcmd proc            ; call rqcsendcommand(ax,ds:bx,ds:cx,@status)
  1904.         push    ax      ; command connection token
  1905.         push    ds
  1906.         push    bx      ; pointer to command
  1907.         push    ds
  1908.         push    cx      ; pointer to command exception
  1909.         push    ds
  1910.         %pushv(offset status)
  1911.         call    rqcsendcommand
  1912.         push    cx      ; save status
  1913.         mov     ax,citok
  1914.         mov     bx,offset sigpair
  1915.         mov     cx,6
  1916.         call    aspcl   ; restore ^C trap
  1917.         pop     cx      ; restore status
  1918.         ret
  1919. sendcmd endp
  1920.  
  1921. z2rmx   proc            ; copies ASCIIZ @ds:dx to si, returns count in ax
  1922.         mov     di,dx
  1923.         mov     cx,0ffffh
  1924.         sub     ax,ax
  1925.         repne scasb
  1926.         neg     cx
  1927.         add     cx,0fffeh
  1928.         mov     ax,cx   ; ax=cx= # of bytes
  1929.         mov     di,si
  1930.         mov     si,dx
  1931.         rep movsb
  1932.         ret
  1933. z2rmx   endp
  1934.  
  1935. bakscan proc            ; finds path part & file name part
  1936.         std             ; bx=string size, si points to EOstring
  1937.         mov     cx,bx
  1938. BSC1:   lodsb
  1939.         cmp     al,':'
  1940.         je      BSC2
  1941.         cmp     al,'/'
  1942.         je      BSC2
  1943.         cmp     al,'^'
  1944.         je      BSC2
  1945.         loop    BSC1
  1946.         dec     si
  1947. BSC2:   inc     si
  1948.         inc     si      ; si point to file name
  1949.         cld
  1950.         sub     bx,cx   ; bx=size file name, cx=size path
  1951.         ret             ; al=separator
  1952. bakscan endp
  1953.  
  1954. aopen   proc            ; call rqaopen(ax,bx,3,0,@status)
  1955.         push    ax      ; token
  1956.         push    bx      ; mode
  1957.         %pushv(3)
  1958.         %pushv(0)
  1959.         push    ds
  1960.         %pushv(offset status)
  1961.         call    rqaopen
  1962.         ret
  1963. aopen endp
  1964.  
  1965. aclose  proc
  1966.         push    ax      ; call rqaclose(ax,cx,@siostat)
  1967.         push    cx
  1968.         push    ds
  1969.         %pushv(offset siostat)
  1970.         call    rqaclose
  1971.         ret
  1972. aclose  endp
  1973.  
  1974. aread   proc            ; call rqaread(ax,ds:bx,cx,dx,@siostat)
  1975.         push    ax
  1976.         push    ds
  1977.         push    bx      ; buffer ptr
  1978.         push    cx      ; count
  1979.         push    dx      ; response mailbox
  1980.         push    ds
  1981.         %pushv(offset siostat)
  1982.         call    rqaread
  1983.         ret
  1984. aread   endp
  1985.  
  1986. awrite  proc            ; call rqawrite(ax,ds:bx,cx,dx,@siostat)
  1987.         push    ax
  1988.         push    ds
  1989.         push    bx      ; buffer ptr
  1990.         push    cx      ; count
  1991.         push    dx      ; response mailbox
  1992.         push    ds
  1993.         %pushv(offset siostat)
  1994.         call    rqawrite
  1995.         ret
  1996. awrite  endp
  1997.  
  1998. aspcl   proc            ; call rqaspecial(ax,cx,ds:bx,tmbox,@siostat)
  1999.         push    ax      ; token
  2000.         push    cx      ; function
  2001.         push    ds
  2002.         push    bx      ; ioparm ptr
  2003.         push    tmbox
  2004.         push    ds
  2005.         %pushv(offset siostat)
  2006.         call    rqaspecial
  2007.         mov     ax,tmbox
  2008.         mov     bx,0ffffh
  2009.         call    rcvmsg  ; ax=rqreceivemessage(tmbox,0ffffh,@ignore,@siostat)
  2010.         call    delseg
  2011.         ret
  2012. aspcl   endp
  2013.  
  2014. waitio  proc            ; ax=rqwaitio(ax,bx,0ffffh,@status)
  2015.         push    ax      ; token
  2016.         push    bx      ; response mailbox
  2017.         %pushv(0ffffh)
  2018.         push    ds
  2019.         %pushv(offset status)
  2020.         call    rqwaitio
  2021.         ret
  2022. waitio  endp
  2023.  
  2024. sendms  proc            ; call rqsendmessage(ax,bx,0,@status)
  2025.         push    ax      ; mailbox token
  2026.         push    bx      ; object to send
  2027.         %pushv(0)
  2028.         push    ds
  2029.         %pushv(offset status)
  2030.         call    rqsendmessage
  2031.         cld
  2032.         ret
  2033. sendms  endp
  2034.  
  2035. rcvmsg  proc
  2036.         pop     bp      ; ax=rqreceivemessage(tmbox,0ffffh,@ignore,@siostat)
  2037.         push    ax      ; mail box token
  2038.         push    bx      ; time limit
  2039.         push    ds
  2040.         %pushv(offset ignore)
  2041.         push    ds
  2042.         %pushv(offset siostat)
  2043.         call    rqreceivemessage
  2044.         jmp     bp
  2045. rcvmsg  endp
  2046.  
  2047. rcvun   proc            ; call rqreceiveunits(ax,1,0ffffh,@ccstat)
  2048.         pop     bp
  2049.         push    ax      ; semaphore token
  2050.         %pushv(1)       ; units
  2051.         %pushv(0ffffh)  ; time limit
  2052.         push    ds
  2053.         %pushv(offset ccstat)
  2054.         call    rqreceiveunits
  2055.         jmp     bp
  2056. rcvun   endp
  2057.  
  2058. delseg  proc            ; call rqdeletesegment(ax,@status)
  2059.         push    ax
  2060.         push    ds
  2061.         %pushv(offset siostat)
  2062.         call    rqdeletesegment
  2063.         ret
  2064. delseg  endp
  2065.  
  2066. gconsta proc
  2067.         push    bx      ; call rqsgetconnectionstatus(token,@temp,@status)
  2068.         push    ds
  2069.         %pushv(offset temp)
  2070.         push    ds
  2071.         %pushv(offset status)
  2072.         call    rqsgetconnectionstatus
  2073.         ret
  2074. gconsta endp
  2075.  
  2076. gfilsta proc
  2077.         push    ds      ; call rqsgetfilestatus(ds:di,@temp,@status)
  2078.         push    di      ; path ptr
  2079.         push    ds
  2080.         %pushv(offset temp)
  2081.         push    ds
  2082.         %pushv(offset status)
  2083.         call    rqsgetfilestatus
  2084.         jcxz    GFIL1
  2085.         ret
  2086. GFIL1:  mov     bx,cx
  2087.         cmp     byte ptr temp+9,0ffh    ; is it a named file?
  2088.         je      GFIL2
  2089.         mov     ax,cx                   ; no, setup for zero length
  2090.         mov     dx,cx
  2091.         ret
  2092. GFIL2:  cmp     byte ptr temp+38,8      ; is it a directory?
  2093.         je      GFIL3                   ; eq = no
  2094.         mov     bl,10h                  ; yes, get DOS directory attribute
  2095. GFIL3:  mov     ax,temp+54              ; low file size
  2096.         mov     dx,temp+56              ; high file size
  2097.         ret
  2098. gfilsta endp
  2099.  
  2100. code    ends
  2101.         end     begin, ds:datas, ss:stack
  2102.