home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
a
/
mszrmx.a86
< prev
next >
Wrap
Text File
|
2020-01-01
|
67KB
|
2,102 lines
NAME MSZRMX
true equ 1
escbslh equ 5c1bh ; ESC \
escbrac equ 5d1bh ; ESC ]
$INCLUDE(mssdef.h86)
%*DEFINE(pushv(v))(%IF(%OS EQ 286)THEN(push %v)ELSE(mov ax,%v
push ax)FI)
datas segment
public citok, cotok, mbox, tmbox, sigpair, sematok, bufill, ciptr
public cifill, cibuf1, cibuf2, combx, cimbx, termatt, oneport
public subpksz, trok, source, trmstr, temp, machnam
extrn sintok:word, srcptr:word, takadr:word, taklev:byte, comand:byte
extrn portval:word, savsi:word, xofsnt:byte, portatt:word
extrn costrt:word, coptr:word, flags:byte, pack:byte, dtrtime:word
extrn bdtab:byte, bddat:word
env db 0,0 ; "environment" must be on PARA boundary
machnam db 21 dup(' ')
trmstr db 6,':TERM:'
lp db 4,':LP:'
bb db 4,':BB:'
work db 6,':WORK:'
dolsgn db 1,'$'
rqglob db 8,'RQGLOBAL'
dotini db 'MSKERMIT.INI',0
kermtmp db '$kermit$.tmp ',0 ; Kermit's DOS name for scratch file
sigpair dw 0
db 3 ; control C
kilpair dw 0
db 0
setosc db ESCAPE,']C:T=1,E=1,R=1,O=1,C=2;T:R=1',ESCAPE,'\'
flush db ESCAPE,']C:T=3',ESCAPE,'\'
escapec db ESCAPE,'c'
printer db 'PRN',0
typecmd db 'type '
delcmd db 'del '
chkdsk db 'chkdsk.com'
dirfree db 'dir $ free',cr
delrmx db 'delete ' ; keep these 2 lines together
deltail db 73 dup(?)
wccmd db 0,'WC ' ; keep these 2 lines together
wcpath db 80 dup(?)
pushmsg db cr,lf,'PUSH not implemented, use RUN whatever$'
syserr db cr,lf,'Your version of MSKERMIT used an unsupported DOS '
db 'function call'
crlf db cr,lf,'$'
cfgerr db cr,lf,'Configuration error',cr,lf,'$'
killmsg db cr,lf,'Only 1st KILL accepted',cr,lf,'$'
mbmsg db cr,lf,'MAX-BAUD error',cr,lf,'$'
oscmsg db cr,lf,'OSC error',cr,lf,'$'
prmsg db cr,lf,'Priority error',cr,lf,'$'
nmsg db cr,lf,'Number > 0ffh',cr,lf,'$'
dnmsg db cr,lf,'Must be decimal number',cr,lf,'$'
nxtflg db 1
oneport db 0
codone db ?
esc_c db 0
trok db 0
$SAVE NOGEN
comtab db 13
%mkeyw (%('bufill'),fillbuf)
%mkeyw (%('cifill'),fillci)
%mkeyw (%('co-delay'),codel)
%mkeyw (%('dtr-time'),dtr)
%mkeyw (%('echo'),takset)
%mkeyw (%('escc'),esccset)
%mkeyw (%('kill'),kill)
%mkeyw (%('max-baud'),maxbd)
%mkeyw (%('no-modem'),nomdm)
%mkeyw (%('osc'),osc)
%mkeyw (%('priority'),prior)
%mkeyw (%('sub-pack'),subpack)
%mkeyw (%('translate'),trnslt)
$RESTORE
even
citok dw ? ; DON'T reorder citok, cotok, lptok lines
cotok dw 3 dup (?)
lptok dw ?
sematok dw ?
initok dw 0
globtok dw ?
doltok dw ?
scfitok dw ?
rcmdtok dw ?
mbox dw ?
tmbox dw ?
cimbx dw ?
combx dw ?
kbuf dw ?
cmdtok dw ?
xitcode dw 40ffh
savebx dw ?
status dw ?
ccstat dw ?
siostat dw ?
priorty dw 254
bufill dw 0ffffh
cifill dw 8080h
subpksz dw 60
codelay dw 6
ciptr dw offset cibuf1
cistrt dw ?
inisize dw ?
savspec dw 12,12,12 dup (0)
termatt dw 2,2,2 dup (?) ; terminal port attributes for special
ignore dw ?
xcepinf dw 3 dup (0)
temp dw 110 dup(?)
org offset temp
db 'Copyright 1988, John Bryans.'
db 'Permission is granted to copy and give away,'
db 'but not to sell for profit any form of this program.'
db 'No Warranties Whatsoever'
org offset temp+size temp
cibuf1 db cibufl dup (?)
cibuf2 db cibufl dup (?)
cobuf1 db cobufl dup (?)
cobuf2 db cobufl dup (?)
source db bufsiz dup(0) ; serial input buffer
PURGE conin,conout,lstout,dconio,coninq,prstr,seldsk,gcurdsk,setdma,gettim
PURGE dosver,gswitch,chdir,creat2,open2,close2,readf2,write2,del2,lseek,gcd
PURGE alloc,setblk,exec,first2,next2
dosf dw notimp ; DOS function call jump table
dw conin
dw conout
dw 2 dup(notimp)
dw lstout
dw dconio
dw coninq
dw rkbd
dw prstr
dw 4 dup(notimp)
dw seldsk
dw 10 dup(notimp)
dw gcurdsk
dw setdma
dw 10 dup(notimp)
dw setintv
dw 6 dup(notimp)
dw gettim
dw 3 dup(notimp)
dw dosver
dw 4 dup(notimp)
dw getintv
dw notimp
dw gswitch
dw 3 dup(notimp)
dw chdir
dw creat2
dw open2
dw close2
dw readf2
dw write2
dw del2
dw lseek
dw 4 dup(notimp)
dw gcd
dw alloc
dw notimp
dw setblk
dw exec
dw exit
dw notimp
dw first2
dw next2
dosfl equ ($-dosf-2)/2
datas ends
%IF (%OS EQ 86) THEN (
stack segment stack 'stack'
dw 750 dup(?)
stack ends
) ELSE (
stack stackseg 1500
)FI
code segment
public dosint, crfile, opfile, special, writer, delcon, prstr, dconio
public aopen, aclose, awrite, aspcl, waitio, sendms, rcvmsg, delseg
public gfilsta, flushci
extrn start:near, outchr:near, takrd:near, prompt:near, comnd:near
extrn takset:near, atoi:near, katoi:near
extrn dqdecodetime:near, dqgetsystemid:near
extrn rqcgetchar:near, rqcgetcommandname:near
extrn rqccreatecommandconnection:near, rqcsendcommand:near
extrn rqsopen:near, rqsdeleteconnection:near, rqsattachfile:near
extrn rqsreadmove:near, rqsseek:near, rqsgetconnectionstatus:near
extrn rqscreatefile:near, rqswritemove:near, rqsspecial:near
extrn rqsgetfilestatus:near, rqsdeletefile:near, rqsclose:near
extrn rqstruncatefile:near, rqexitiojob:near
extrn rqaopen:near, rqaclose:near, rqaread:near, rqawrite:near
extrn rqwaitio:near, rqaspecial:near, rqsetdefaultprefix:near
extrn rqsetexceptionhandler:near, rqsetpriority:near
extrn rqcreatesemaphore:near, rqreceiveunits:near, rqcreatetask:near
extrn rqcreatemailbox:near, rqreceivemessage:near, rqsendmessage:near
extrn rqcreatesegment:near, rqdeletesegment:near, rqlookupobject:near
%IF (%OS EQ 286) THEN (
extrn rqegetaddress:near, rqecreatedescriptor:near
extrn rqedeletedescriptor:near
)FI
psp: jmp stop ; "program segment prefix"
db 10h ; combined w/previous byte makes size>65K
db 0
db 9ah,0f0h,0ffh,0dh,0f0h ; beats the hell out of me
dd quitint ; termination address
dd cctask ; control-break address
dd quitint ; critical error address
db (psp+2ch)-$ dup(?)
dw seg env ; segment address of environment
db (psp+50h)-$ dup(?)
fake proc far
jmp dosint ; DOS function dispatcher entry
fake endp
db (psp+80h)-$ dup(?)
cline db 82 dup(0)
begin proc far
call setexcp
%IF (%OS EQ 286) THEN (
push cs
push offset psp
push ds
push offset status
call rqegetaddress
push dx
push ax
push offset begin
push ds
push offset status
call rqecreatedescriptor
)ELSE(
mov ax,cs
)FI
mov es,ax
mov di,offset cline ; move command line to cline
sub al,al
L1: inc byte ptr es:cline
stosb ; clears count 1st time thru
push es ; save es & di
push di
push ds ; al=call rqcgetchar(@status)
%pushv(offset status)
call rqcgetchar
pop di ; restore es & di
pop es
test al,al ; end of string?
jnz L1 ; no
mov byte ptr es:[di],cr ; stuff cr
%IF (%OS EQ 286) THEN (
push es ; let's not leave this descriptor laying around
push ds
push offset status
call rqedeletedescriptor)FI
call crmbx ; mbox=rqcreatemailbox(0,@status)
mov mbox,ax
call crmbx ; tmbox=rqcreatemailbox(0,@status)
mov tmbox,ax
call crmbx ; combx=rqcreatemailbox(0,@status)
mov combx,ax
call crmbx ; cimbx=rqcreatemailbox(0,@status)
mov cimbx,ax
mov di,offset work ; scfitok=rqscreatefile(@(6,':WORK:'),@status)
call crfile ; scratch file is for wild card implementation
mov scfitok,ax ; (FIRST2 & NEXT2), and :CO: redirection (EXEC)
mov bx,3 ; call rqsopen(scfitok,3,2,@status)
mov cx,2
call opfile
mov di,offset trmstr
call crfile
mov citok,ax ; citok=rqscreatefile(@(4,':TERM:'),@status)
mov bx,3 ; call rqaopen(citok,3,3,0,@status)
call aopen
mov di,offset trmstr
call crfile
mov cotok,ax ; cotok=rqscreatefile(@(4,':TERM:'),@status)
mov cotok+2,ax
mov cotok+4,ax
mov bx,3 ; call rqsopen(cotok,3,3,@status)
mov cx,bx
call opfile
mov ax,cotok ; call rqsspecial(cotok,4,@savspec,0,@status)
mov bx,offset savspec
mov cx,4
call special
test savspec+18,8000h
js L2
mov word ptr savspec+2,7
L2: mov ax,citok ; set OSCs for :CI:
mov bx,offset setosc
mov cx,size setosc
sub dx,dx
call awrite
mov ax,cotok ; set OSCs for :CO:
mov bx,offset setosc
mov cx,size setosc
call writer
mov ax,citok ; rumor has it write before read
mov bx,offset crlf ; is s'posed to convince Terminal Support Code
mov cx,2 ; we're serious about wanting transparent input
mov dx,tmbox
call awrite
push ds ; get pathname that called us
%pushv(offset cobuf1) ; stash @cobuf1
%pushv(size cobuf1) ; call rqgetcommandname
push ds ; (@cobuf1,size cobuf1,@status)
%pushv(offset status)
call rqcgetcommandname
mov ax,citok ; wait for TSC to settle down
mov bx,tmbox ; necessary for 386's & lickety-split 286's
call waitio
mov ax,ds ; back scan to last path separator
mov es,ax
mov bl,cobuf1
sub bh,bh
lea si,cobuf1[bx]
call bakscan ; si=file name ptr, bx=its length, al=separator
; The full string @cobuf1 is used to look for .cfg & .ini in the dir from which
; Kermit was loaded. The mid-string, @si-1, is used to look in :$:.
mov [bx+si],'c.' ; catenate '.cfg'
mov [bx+si+2],'gf'
dec si ; byte before file name for string count
mov word ptr cobuf2,si ; save ptr
add cobuf1,4 ; bump length of full string for .cfg
add bl,4 ; bump length of mid-string
mov [si],bl ; RMX string for lookup in :$:
mov ah,bl ; ah=current byte @si, al=old char @si
cmp si,offset cobuf1 ; if no path, use bl for old char
jne L3
mov al,bl ; instead of the one from bakscan
L3: mov word ptr cobuf2+2,ax ; save them
call cfgini ; look for .cfg, open, size to dx:si
jcxz L4 ; OK?
jmp short L7 ; no, do .ini
L4: inc taklev
add takadr,size takinfo
mov di,takadr
mov [di].takhnd,ax ; token
mov [di].taktyp,0feh ; mark as take
mov [di].takcnt,si ; low size
mov [di].takcnt+2,dx ; high size
call takrd
L5: mov ax,ds
mov es,ax
mov dx,offset dolsgn ; ptr for prompt
call prompt
cmp taklev,0 ; done?
je L7 ; eq = yes
mov dx,offset comtab ; command table ptr
mov bx,offset dolsgn ; help ptr
mov comand.cmcr,1
mov ah,cmkey
call comnd
jmp short L6 ; error exit
nop
call bx ; call cfg s/r
jmp L5 ; loop
L6: mov dx,offset cfgerr ; output error msg & loop
call prstr
jmp L5
L7: mov si,word ptr cobuf2 ; point to mid-string
mov ax,word ptr cobuf2+2 ; ah=mid-string count, al=path separator
mov [si],ah
mov bl,ah
sub bh,bh
mov byte ptr[bx+si],'i' ; replace 'cfg' w/'ini'
dec bx
dec bx
mov [bx+si],'ni'
call cfgini ; look for .ini, open, size to dx:si
jcxz L8 ; found
jmp short L9 ; not found
CFGINI proc
mov di,si
mov temp,si ; save string pointer
call atfile ; attach from :$:
jcxz CGIN1 ; z=found
mov si,word ptr cobuf2 ; point to mid-string
mov ax,word ptr cobuf2+2 ; al=path separator
mov [si],al ; put it back
mov di,offset cobuf1 ; point to full path
mov temp,di ; save string pointer
call atfile ; attach from full path
jcxz CGIN1
ret
CGIN1: mov temp+100,ax ; save token
mov bx,1
mov cx,bx
call opfile ; open for reading
jcxz CGIN2
ret
CGIN2: mov di,temp ; string pointer
call gfilsta ; get file status to find size
mov si,ax ; low order file size
mov ax,temp+100 ; token
ret
CFGINI endp
L8: mov inisize,si ; size of .ini
mov initok,ax ; close KERMIT.INI,
call clfile ; but leave attached for open2
L9: mov ax,cotok ; save configured attributes
mov bx,offset termatt ; for ping-ponging
mov cx,4
call special
call crsema ; sematok=rqcreatesemaphore(0,1,0,@statu
mov sematok,ax
mov sigpair,ax ; for ^C trapping
mov ax,citok ; establish ^C & sematok as signal pair
mov cx,6
mov bx,offset sigpair
call aspcl
mov bx,offset cctask ; call rqcreatetask
call crtsk ; (0,@cctask,datas,0,300,0,@status)
mov bx,offset siotsk ; call rqcreatetask
call crtsk ; (0,@siotsk,datas,0,300,0,@status)
mov bx,offset citsk ; call rqcreatetask
call crtsk ; (0,@citsk,datas,0,300,0,@status)
mov bx,offset cotsk ; call rqcreatetask
call crtsk ; (0,@cotsk,datas,0,300,0,@status)
mov di,offset lp ; lptok=rqscreatefile(@(4,':LP:'),@status)
call crfile
jcxz L10 ; jump if OK
mov di,offset bb ; otherwise use :BB:
call crfile
L10: mov lptok,ax
mov bx,2 ; call rqsopen(lptok,2,2,@status)
mov cx,bx
call opfile
mov ax,citok ; cmdtok = rqccreatecommandconnection(citok,
mov bx,cotok ; cotok,0,@status)
sub cx,cx
call crcmdco
mov cmdtok,ax
mov ax,lptok ; rcmdtok = rqccreatecommandconnection(lptok,
mov bx,scfitok ; scfitok,1,@status)
mov cx,1 ; lptok forces error if ":CI:" gets read,
call crcmdco ; scfitok is ":CO:" redirected to scratch file
mov rcmdtok,ax
push ds ; call dqgetsystemid(@temp,@status)
%pushv(offset temp)
push ds
%pushv(offset status)
call dqgetsystemid
mov ax,ds ; use system id for machine name
mov es,ax
mov si,offset temp+1
mov di,offset machnam
mov cl,byte ptr temp
sub ch,ch
rep movsb
mov al,'$' ; it's a $ terminated string
stosb
mov ax,cx
mov bx,offset rqglob
call lookup ; globtok=rqlookupobject(0,@rqglob,0,@status)
mov globtok,ax
mov bx,offset dolsgn
call lookup ; doltok=rqlookupobject(globtok,@dolsgn,0,@statu
mov doltok,ax
push cx ; call rqsetpriority(0,priorty,@status)
push priorty
push ds
%pushv(offset status)
call rqsetpriority
mov ax,cs
mov ds,ax ; point ds & es to psp
mov es,ax
jmp start ; go to Kermit
begin endp
; cfg subroutines.
; Number conversion routines getn & getdn return to caller's caller on error
fillbuf proc
call getn ; convert backslash number
mov bufill,ax ; set serial input background fill
ret
fillbuf endp
fillci proc
call getn ; convert backslash number
mov cifill,ax ; set terminal input background fill
ret
fillci endp
codel proc
call getdn ; convert decimal number
mov codelay,ax ; set connect mode terminal output buffer time
ret
codel endp
dtr proc
call getdn ; convert decimal number
mov dtrtime,ax ; set time to hold DTR down
ret
dtr endp
esccset proc
mov esc_c,true ; enable sending ESC c (VT100 reset) on exit
ret
esccset endp
kill proc
call getn ; convert backslash number
cmp kilpair,0 ; has task already been created?
jne K1 ; ne = yes
mov byte ptr kilpair+2,al ; set control char to trap
call crsema ; kilpair=rqcreatesemaphore(0,1,0,@status)
mov kilpair,ax
mov bx,offset kiltsk
call crtsk ; create kill task
mov ax,citok
mov cx,6
mov bx,offset kilpair
call aspcl ; establish trap char & kiltsk as signal pair
ret
K1: mov dx,offset killmsg ; don't let 'em do it twice
call prstr
ret
kill endp
maxbd proc
mov dx,offset bdtab ; parse for baud rate
sub bx,bx
mov ah,cmkey
call comnd
jmp short MB1 ; NG, bitch
nop
mov temp,bx ; save baud ix
mov ah,cmcfm ; proper parsing ettiqutte
call comnd
jmp short MB1 ; NG, bitch
nop
mov bx,temp ; baud ix
inc bx ; next higher
mov cx,baudsiz ; baudsiz - (1+baud ix) is # wds to clear
sub cx,bx ; x2 is word ix
shl bx,1
mov ax,ds
mov es,ax
sub ax,ax
mov di,offset bddat ; point to 1st word to clear
add di,bx
cld
rep stosw ; wipe 'em out
ret
MB1: mov dx,offset mbmsg
call prstr
ret
maxbd endp
nomdm proc
and portatt+6,0fff7h ; turn off modem control bit
ret
nomdm endp
osc proc
mov ah,cmtxt ; parse text upto cr to temp+2
mov bx,offset temp+2
mov dx,offset dolsgn
call comnd
jmp short OSCERR ; NG
nop
mov cl,ah
sub ch,ch ; cx = # bytes
mov di,offset temp+2 ; point to start
mov ax,ds
mov es,ax
mov al,' '
cld
repe scasb ; discard leading blanks
je OSCERR ; empty, show indignation
xchg bx,di ; bx = 1st non-blank char ptr
dec di ; di = last char ptr
std
repe scasb ; discard trailing blanks
cld
add cl,6 ; cx = total length of OSC
inc di
inc di ; point to plant trailer
sub bx,3 ; point to plant lead-in
mov [bx],escbrac ; insert lead-in
mov [di],escbslh ; insert trailer
mov ax,cotok
push bx ; save ptr for ci
push cx ; save count for ci
call writer ; write OSC to cotok
pop cx
pop bx
mov ax,citok ; write OSC to citok
sub dx,dx
call awrite
ret
OSCERR: mov dx,offset oscmsg
call prstr
ret
osc endp
prior proc
call getn ; convert backslash number
je PRERR ; getn compared to 255, reject if =
mov byte ptr priorty,al ; set priority
ret
PRERR: mov dx,offset prmsg
call prstr
ret
prior endp
subpack proc
call getdn ; convert decimal number
mov subpksz,ax ; set sub-packet size (tuning param for sending)
ret
subpack endp
trnslt proc
mov trok,true ; enable translation during connect
ret
trnslt endp
getn proc ; bags backslash #, converts it, ensures<256, returns in ah & al
mov ah,cmfile ; parse upto whitespace into temp
mov bx,offset dolsgn
mov dx,offset temp
mov byte ptr temp,0
call comnd
jmp short NERR ; NG return
nop
mov si,offset temp ; point to it
call katoi ; convert it
jc NERR ; carry set = NG
cmp ax,0ffh ; we want 255 max
ja NERR
mov ah,al ; both bytes the same for word filling
ret
NERR: mov dx,offset nmsg
call prstr
pop ax
ret
getn endp
getdn proc ; bags decimal number, converts it, returns it in ax
mov ah,cmtxt ; parse upto cr into temp
mov bx,offset temp
mov dx,offset dolsgn
mov byte ptr[bx],0
call comnd
jmp short DNERR ; NG return
nop
mov si,offset temp ; point to it
call atoi ; convert it
jmp short DNERR ; NG return
nop
ret ; got it, it's in ax
DNERR: mov dx,offset dnmsg
call prstr
pop ax
ret
getdn endp
dosint proc ; DOS function call table look up
push ds
push bx
mov bx,datas
mov ds,bx
pop savebx
cmp ah,dosfl
ja notimp
sub bh,bh
mov bl,ah
rol bx,1
call dosf[bx]
mov bx,savebx
pop ds
ret
dosint endp
notimp: ; not implemented DOS function error routine
mov dx,offset syserr
call prstr
quitint proc far
stop: mov ax,datas
mov ds,ax
mov dx,offset crlf
call prstr
cmp esc_c,true ; is ESC c cfg'd?
jne ST1 ; ne = no
mov ax,cotok ; give Terminal Support Code an ESC c
mov bx,offset escapec ; to restore terminal to initial state
mov cx,size escapec
call writer
ST1: mov ax,cotok ; close to wait for output completion
call clfile
mov ax,citok ; restore terminal attributes
mov bx,offset savspec
mov cx,5
call aspcl
mov cx,globtok ; restore $ directory
mov ax,doltok ; call rqsetdefaultprefix(globtok,doltok,@status
call sdefpfx
mov cx,kilpair ; was a kill kermit ctrl char established
jcxz ST2 ; z = no
mov ax,citok ; yes, disestablish
mov bx,offset kilpair
mov word ptr[bx],0
mov cx,6
call aspcl
ST2: mov ax,citok ; wait for completion before exit
mov cx,tmbox
call aclose
mov ax,tmbox
mov bx,0ffffh
call rcvmsg
push xitcode ; call rqexitiojob(xitcode,@0,@status)
sub ax,ax
push ax
push ax
push ds
%pushv(offset status)
call rqexitiojob
quitint endp
kiltsk proc ; kill task
mov ax,kilpair ; wait for kill char to be typed
call rcvun
jmp STOP ; then quit
kiltsk endp
cctask proc far ; ^C task
CCT: mov ax,sematok ; wait for ^C to be typed
call rcvun
mov flags.cxzflg,'C' ; slightly adapted (mostly stolen) from
mov pack.state,'A' ; MSSKER's intbrk
jmp CCT
cctask endp
siotsk proc far ; serial input task
call setexcp ; never call exception handler
SIO1: mov bx,0ffffh ; wait forever @ mbox for something to do
SIO2: mov ax,mbox
call rcvmsg
cmp ax,mbox ; if it's the token for mbox,
je SIO6 ; it's SERINI asking us to crank up input
dec cx ; otherwise it's E$TIME or an IORS
jz SIO3 ; it's E$TIME
call delseg ; it's an IORS, so delete it
SIO3: cmp sintok,0 ; if the port has been reset,
je SIO1 ; let the interrupts expire unanswered
cmp xofsnt,true
jne SIO4
mov bx,50
jmp SIO2
SIO4: call sread ; start aread & fill following buffer quadrant
mov ax,srcptr
sub ax,savsi ; if there's at least 2 quadrants between next
jns SIO5 ; quadrant & current pointer,
add ax,bufsiz
SIO5: cmp ax,bufsiz/2
jle SIO1 ; we don't need to XOF, so wait for interrupt
mov bx,portval
cmp [bx].floflg,0 ; is flow control enabled?
je SIO1 ; no
mov ax,[bx].flowc ; ouput whatever we're using for XOF
mov ah,al
call outchr
nop
nop
nop
mov xofsnt,true
jmp SIO1
SIO6: mov ax,sintok ; for aspecial to set it
mov bx,offset portatt
or word ptr[bx+4],3 ; change to flushing mode
mov cx,5 ; while we're at it
call aspcl
SIO7: mov ax,sintok
mov bx,offset source ; initialize
mov savsi,bx ; current byte ptr
mov srcptr,bx ; & next quadrant ptr
mov cx,bufsiz ; in case the ports on a buffered board
mov dx,mbox ; flush it's buffer
call aread
mov ax,sintok
mov bx,mbox
call waitio
cmp ax,bufsiz
je SIO7 ; no matter how big the damn thing is
mov ax,sintok
mov bx,offset portatt
and word ptr[bx+4],0fffdh ; change back to transparent mode
mov cx,5
call aspcl
mov ax,ds ; fill 1st quadrant
mov es,ax
mov ax,bufill
mov cx,bufsiz/8
mov di,offset source
cld
rep stosw
call sread ; start 1st read & fill 2nd quadrant
jmp SIO4 ; go do 2nd read
sread proc
mov ax,sintok
mov bx,srcptr ; next quadrant ptr
mov cx,bufsiz/4
mov dx,mbox
call aread ; read current quadrant
mov ax,ds
mov es,ax
mov ax,bufill
mov cx,bufsiz/4
mov di,srcptr
add di,cx
cmp di,bufsiz+offset source ; was it last quadrant
jl SRD1 ; no
mov di,offset source ; yes, point to 1st
SRD1: mov srcptr,di ; set next quadrant ptr
shr cx,1
cld
rep stosw ; fill quadrant
ret
sread endp
siotsk endp
citsk proc far ; read terminal task
call setexcp
CIT1: mov bx,offset cibuf1
CIT2: mov cistrt,bx ; set buffer ptr
mov ax,ds ; fill it w/cifill
mov es,ax
mov di,bx
mov cx,(size cibuf1)/2
mov ax,cifill
cld
rep stosw
mov ax,citok ; call rqaread
mov cx,size cibuf1 ; (citok,@buffer,size(buffer),cimbx,@statu
mov dx,cimbx
call aread
CIT3: mov ax,cimbx ; wait for completion or task restart
mov bx,0ffffh
call rcvmsg
cmp ax,cimbx ; if it's the mail box token, it's task restart
jne CIT4 ; if, not it's an IORS
mov bx,offset cibuf1
mov ciptr,bx ; initialize buffer & char pointers
jmp CIT2 ; & start over
CIT4: mov es,ax ; check IORS for "flushing" status
cmp es:word ptr 0,2ch
pushf
call delseg ; delete IORS
popf ; "flushing" means suspend task,
je CIT3 ; go wait for restart
mov bx,offset cibuf2
cmp bx,cistrt ; exchange buffers
je CIT1
jmp CIT2
citsk endp
cotsk proc far ; write terminal task -- active in connect mode
call setexcp
COT1: mov ax,combx ; wait for task start or IORS
mov bx,0ffffh
call rcvmsg
cmp ax,combx ; if it's the mail box token, it's task start
je COT2
call delseg ; otherwise it's an expiring IORS, delete it
jmp COT1 ; & wait for task start
COT2: mov ax,cotok ; task start. close EIOS & re-open BIOS
call clfile
mov ax,cotok
mov bx,2
mov codone,bl ; mark write complete
call aopen
COT3: mov ax,offset cobuf1
COT4: mov coptr,ax ; byte ptr
mov costrt,ax ; buffer ptr
COT5: mov ax,combx ; wait for timer, IORS, or suspend task request
mov bx,codelay ; default = 60 milliseconds
call rcvmsg
jcxz COT6 ; 0 = IORS or suspend task
cmp codone,0 ; timeout. Is write complete?
jne COT7 ; ne = yes
jmp COT5 ; no, wait for it
COT6: cmp ax,combx ; if mail box token
je COT9 ; it's suspend task request
mov codone,true ; it's IORS, mark write complete
call delseg ; delete IORS
COT7: mov bx,costrt ; buffer ptr
mov cx,coptr ; byte prt
sub cx,bx ; # bytes to write
jcxz COT8 ; don't write 0
mov ax,cotok ; call rqawrite
mov dx,combx ; (cotok,@buffer,nbytes,combx,@status)
call awrite
mov codone,0 ; mark write not finished
COT8: mov ax,offset cobuf2
cmp ax,costrt ; exchange buffers
je COT3
jmp COT4
COT9: mov ax,cotok ; suspend task. Close BIOS, wait for task start
call aclose
jmp COT1
cotsk endp
conin proc
call rkbd ; read 1 from :CI: to al
push dx
mov dl,al ; conout writes out dl
call conout ; echo it to :CO:
pop dx
ret
conin endp
conout proc
call save
mov ax,cotok ; write dl to :CO:
CO1: mov cx,1
mov temp,dx
mov bx,offset temp
call writer
call rstr
ret
conout endp
lstout proc
call save
mov ax,lptok ; write dl to :LP:
jmp CO1
lstout endp
dconio proc
cmp dl,0ffh ; if dl ain't ff,
jne conout ; it's same as conout
push si
push cx
call rdci ; read 1 from :CI: to temp, on return
test cx,cx ; cx=1 if read, 0 if not, set zero flag if not
pop cx
pop si
ret
dconio endp
coninq proc
push cx
DC1: call rdci ; read 1 from :CI: to temp
jcxz DC1 ; 'til we get 1
pop cx
ret
coninq endp
rkbd proc
RKBD1: call pollci ; read 1 from :CI: to al
je RKBD1 ; 'til we get 1
ret
rkbd endp
rdci proc
sub cx,cx
cmp flags.cxzflg,'C' ; reads 1 from :CI: to temp, doesn't
jne RDC1 ; wait, doesn't check ^C
mov flags.cxzflg,ch ; returns cx=1 if read, 0 if not
mov al,3
jmp short RDC2
RDC1: call pollci
je RDC3
RDC2: inc cx
RDC3: ret
rdci endp
pollci proc
push si
cmp sintok,0 ; if serial port's active
je PCI1
cmp oneport,true ; & oneport
je PCI3 ; return no character
PCI1: mov si,ciptr ; next byte ptr
lodsb
cmp al,byte ptr cifill
je PCI3 ; eq = no byte
cmp si,offset cibuf2 + size cibuf2
jne PCI2
mov si,offset cibuf1
test si,si ; clear equal
PCI2: mov ciptr,si ; set ptr for next byte
PCI3: pop si
ret
pollci endp
prstr proc
call save ; call rqswritemove(cotok,ds:dx,#char,@status)
mov ax,ds
mov es,ax
mov di,dx
mov cx,0ffffh
mov al,'$'
repne scasb
neg cx
add cx,0fffeh ; cx=#characters
jcxz PRSTR1 ; why bother
mov ax,cotok
mov bx,dx
call writer
PRSTR1: call rstr
ret
prstr endp
seldsk proc
mov al,1 ; what the hell, say there's 1
ret
seldsk endp
gcurdsk proc
sub al,al ; always A: -- meaningless anyway
ret
gcurdsk endp
setdma proc
mov kbuf,dx ; save disk transfer address, DTA
ret
setdma endp
setintv proc
ret ; if KERMIT ever does more than
setintv endp ; setup int 23h, we're in trouble
gettim proc
call save
sub ax,ax ; let dword @temp be system time
mov temp,ax ; set to 0, so decodetime returns current time
mov temp+2,ax
push ds ; call dqdecodetime(@temp,@status)
%pushv(offset temp)
push ds
%pushv(offset status)
call dqdecodetime
call rstr
push ax
mov dx,temp+12
call asc2bin
mov ch,dl ; ch=hours
mov dx,temp+15
call asc2bin
mov cl,dl ; cl=minutes
mov dx,temp+18
call asc2bin
mov dh,dl ; dh=seconds
sub dl,dl ; dl=0 hundredths
pop ax
ret
asc2bin proc
sub dx,'00'
shl dl,1
mov al,dl
shl dl,1
shl dl,1
add dl,al
add dl,dh
ret
asc2bin endp
gettim endp
dosver proc
mov al,2 ; we're simulating DOS 2.x
ret
dosver endp
gswitch proc
mov dl,'/' ; undocumented DOS get switch character
ret
gswitch endp
getintv proc
ret ; if KERMIT ever does more than
getintv endp ; setup int 23h, we're in trouble
chdir proc
call save
mov ax,ds
mov es,ax
mov si,offset temp+1
call z2rmx ; copy ASCIIZ string @ds:dx to temp+1
mov byte ptr temp,al
mov di,offset temp ; length to temp makes it RMX string
call atfile ; attach file
jcxz CHD2 ; jump if OK
CHD1: call rstr
mov ax,3 ; return error code w/carry set
stc
ret
CHD2: mov cx,globtok ; call rqsetdefaultprefix(globtok,ax,@status)
push ax
call sdefpfx
pop ax
jcxz CHD3
jmp CHD1
CHD3: call sdefpfx ; call rqsetdefaultprefix(0,ax,@status)
call rstr
clc
ret
chdir endp
creat2 proc
call save
mov ax,ds
mov es,ax
mov si,offset printer ; is it PRN ?
mov di,dx
mov cx,size printer
repe cmpsb
jne CRF1 ; ne=no
call rstr
mov ax,lptok ; yes, use :LP:
clc
ret
CRF1: call cropsr
jnc CRF2
call exfisr
jmp short OP5
CRF2: call crfile ; create file
mov bx,3 ; mode for OPEN & error return code
mov temp+2,bx ; error return code
jmp short OP4
cropsr proc
mov si,dx
mov di,offset kermtmp ; is it "$kermit$.tmp"?
mov cx,size kermtmp
repe cmpsb
jne CROP1
mov bx,scfitok ; yes, use token for scratch file
mov temp,bx ; save it
stc
ret
CROP1: mov si,offset temp+3
call z2rmx ; ASCIIZ string to temp+3
mov di,offset temp+2 ; setup di
mov [di],al ; length makes it RMX string at temp+2
clc
ret
cropsr endp
creat2 endp
open2 proc
call save
sub ah,ah ; convert DOS mode to RMX
inc ax
mov temp,ax ; save mode
mov ax,ds
mov es,ax
mov si,dx
mov di,offset dotini ; is it MSKERMIT.INI?
mov cx,size dotini
repe cmpsb
jne OP1 ; no
mov ax,initok ; yes, initok's already attached
jmp short OP3
OP1: call cropsr
jnc OP2
call rewind
jmp short OP5
OP2: call atfile
OP3: mov temp+2,2 ; error return code
mov bx,temp ; get mode
OP4: mov temp,ax ; save token
mov cx,2 ; call rqsopen(token,mode,2,@status)
call opfile
OP5: call rstr
mov ax,temp ; return token to caller in ax
mov bx,temp+2 ; get error return code
jmp short CRYFLG
open2 endp
close2 proc
mov bx,savebx ; savebx has file token
cmp bx,scfitok ; if it's the scratch file,
je CL1 ; don't you dare!
cmp bx,lptok ; :LP:, neither
je CL1
call save
mov bx,savebx
call delcon ; delete connection
call rstr
mov bx,6 ; error flag, if necessary
jmp short CRYFLG
CL1: ret
close2 endp
readf2 proc
call save
mov ax,savebx ; savebx has file token
mov bx,dx ; nbyt=rqsreadmove(token,@buf,cnt,@status)
call reader
RF1: mov temp,ax ; save # bytes read
call rstr
mov ax,temp ; return to caller in ax
mov bx,6 ; error flag, if necessary
jmp short CRYFLG
readf2 endp
write2 proc
call save
mov bx,savebx ; savebx has file token
test bx,bx ; is it magic token 0 (CI)?
jz WRT1 ; yes, let fail gracefully
cmp bx,4 ; other magic tokens?
ja WRT1 ; no
shl bx,1 ; yes, lookup real token
mov bx,citok[bx]
WRT1: mov ax,bx
mov bx,dx ; nbyt=rqswritemove(token,@buf,cnt,@status)
call writer
jmp RF1
write2 endp
del2 proc
call save
mov ax,ds
mov es,ax
mov si,offset temp+1 ; ASCIIZ string @ds:dx to temp+1
call z2rmx
mov bx,offset temp
mov byte ptr[bx],al ; length makes it RMX string at temp
push ds ; call rqsdeletefile(@temp,@status)
push bx
push ds
%pushv(offset status)
call rqsdeletefile
call rstr
mov bx,2 ; error return code
CRYFLG: clc
cmp status,0 ; OK?
je CFLG1 ; yes
stc
mov ax,bx ; & return error code
CFLG1: ret
del2 endp
lseek proc
call save
mov bx,savebx ; savebx has file token
push bx ; save for get con. status
add al,2 ; convert DOS mode to RMX
cbw
call seek
pop bx
call gconsta ; getconnectionstatus puts file ptr
call rstr ; in temp+4 & 6
mov ax,temp+4 ; dx:ax are file pointer
mov dx,temp+6
mov bx,6 ; error flag, if necessary
jmp CRYFLG
lseek endp
alloc proc
call save
mov ax,savebx ; savebx has # paragraphs
cmp ax,1000h ; is it 65K?
jl AL2 ; <65K, it's OK
jne AL1 ; >65K, too much
sub ax,ax ; =65K, use 0 for full segment
jmp short AL2
AL1: mov status,ax ; force error
jmp short AL3
AL2: mov cl,4 ; convert paragraphs to bytes
shl ax,cl
push ax ; seg_base=rqcreatesegment(#bytes,@status)
push ds
%pushv(offset status)
call rqcreatesegment
mov temp,ax ; save
AL3: call rstr
mov ax,temp ; restore seg_base return param
mov bx,8 ; error return code
jmp CRYFLG
alloc endp
gcd proc
mov byte ptr[si],0 ; return null string @ds:si
clc
ret
gcd endp
setblk proc
ret
setblk endp
PUSHCMD: ; actually, part of exec
mov dx,offset pushmsg ; for now, say "no pushing"
call prstr ; but here's the spot to implement later
call rstr
mov ax,11
stc
ret
exec proc
call save
mov bx,savebx ; saved bx
mov di,es:[bx+2] ; command tail pointer to es:di
mov es,es:[bx+4]
sub cx,cx
mov cl,es:[di] ; if command tail length is 0, it's PUSH
jcxz PUSHCMD
inc di
mov al,' '
repne scasb ; scan past DOSisms
repe scasb
dec di ; 1st non-blank char of command
mov bx,di
mov dx,cx ; bx is ptr, dx is count
mov al,'>' ; if '>' appears, Kermit's asking for
repne scasb ; redirected output
mov ax,cmdtok ; if not, use ordinary cmd token
jne EX1 ; ne = no redirection
sub dx,cx ; reduce count by chars from '>' to end
dec dx
push bx
push dx
push es
call exfisr ; rewind & truncate scratch file
pop es
pop dx
pop bx
mov ax,rcmdtok ; use redirected cmd token
EX1: mov temp+100,ax ; save cmd token
mov si,offset typecmd ; is it 'TYPE'?
mov di,bx
mov cx,size typecmd
repe cmpsb
jne EX2 ; ne = no
mov [bx],'oc' ; replace w/'COPY'
mov [bx+2],'yp'
jmp short EX4
EX2: mov si,offset delcmd ; is it 'DEL'?
mov di,bx
mov cl,size delcmd
repe cmpsb
jne EX3 ; ne = no
sub dx,size delcmd ; construct RMX DELETE command @delrmx
mov cx,dx
mov al,' '
repe scasb
dec di
inc cx
mov dx,cx
add dx,size delrmx
push ds
push es
pop ds
pop es
mov si,di
mov di,offset deltail
rep movsb
mov si,offset delrmx
jmp short EX5
EX3: mov si,offset chkdsk
mov di,bx
mov cl,size chkdsk
repe cmpsb
jne EX4
mov bx,offset dirfree ; yes, use 'dir $ free' as command
mov dx,size dirfree
mov cx,ds
mov es,cx
EX4: push ds ; swap ds & es
push es
pop ds
pop es
mov si,bx
EX5: mov di,offset temp ; move command to temp
mov ax,dx
stosb
mov cx,dx
rep movsb
push es ; restore ds
pop ds
mov ax,temp+100 ; command token
cmp ax,rcmdtok ; if output's going to scratch file
je EX6 ; bypass fussing w/:TERM:
mov ax,citok ; shut down citsk
call aclose
mov ax,citok ; reopen
mov bx,3
call aopen
call flushci ; wait for output to :TERM: to finish
mov bx,offset savspec ; ping back to user's connection &
push word ptr[bx+2] ; terminal attributes
mov word ptr[bx+2],2
mov ax,cotok
mov cx,5
call special
mov ax,citok
mov bx,offset savspec
mov cx,5
call aspcl
pop savspec+2
EX6: mov ax,temp+100 ; command token
push ax ; save it
mov bx,offset temp ; call rqcsendcommand
mov cx,offset temp+100 ; (token,@temp,@temp+100,@status)
call sendcmd
pop ax ; command token
cmp ax,rcmdtok ; if it went to scratch file,
je EX7 ; don't mess w/:TERM:
push cx ; save status
call flushci ; wait for completion of cmd's output
mov ax,cotok ; pong attr's back to Kermit's
mov bx,offset termatt
mov cx,5
call special
mov ax,citok
mov bx,offset termatt
mov cx,5
call aspcl
mov ax,cimbx ; restart citsk
mov bx,ax
call sendms
pop cx ; restore status
EX7: cmp cx,83h ; is it E$CONTINUED
je EX8 ; yes, return w/carry clear
or cx,temp+100 ; sendcmd status OR status from command
jcxz EX8 ; jump if OK
call rstr
mov ax,2 ; return error code w/carry set
stc
ret
EX8: call rstr
clc
ret
exfisr proc ; rewind & truncate scratch file
mov bx,scfitok
push bx ; save for truncate
call rewind ; rewind scratch file
push ds ; call rqstruncatefile(scfitok,@status)
%pushv(offset status)
call rqstruncatefile
ret
exfisr endp
flushci proc
mov ax,citok ; this is necessary to wait for completion
mov bx,offset flush ; of output to :TERM: for fast systems
mov cx,size flush
sub dx,dx
call awrite
mov ax,citok
mov bx,offset cobuf1
mov cx,cobufl
mov dx,tmbox
call aread
mov ax,citok
mov bx,tmbox
call waitio
ret
flushci endp
exec endp
exit proc
sub ah,ah ; convert DOS exit code to RMX
test ax,ax
jz X1
mov ah,40h ; put in user range, if non-0
X1: mov xitcode,ax
jmp stop
exit endp
first2 proc
call save
mov si,dx ; ds:dx points to ASCIIZ file name
mov ax,ds
mov es,ax
mov di,offset kermtmp ; is it "$kermit$.tmp"?
mov temp+100,di
mov cx,size kermtmp
mov temp+102,cx
repe cmpsb
jne FST2
mov bx,scfitok ; yes, fill in DTA. For scratch file,
call gconsta ; getconnectionstatus to temp
mov ax,temp+4 ; bx:ax are file pointer,
mov bx,temp+6 ; which is length of scratch file
FST1: mov di,kbuf
mov [di+1ah],ax ; lo file size to DTA
mov [di+1ch],bx ; hi file size to DTA
mov byte ptr [di+15h],0 ; clear DTA's attribute field
add di,1eh ; point to DTA's file name field
mov si,temp+100
mov cx,temp+102
rep movsb
call rstr
mov bx,2
jmp CRYFLG
FST2: mov si,dx
mov di,offset dotini ; is it MSKERMIT.INI?
mov temp+100,di
mov cx,size dotini
mov temp+102,cx
sub bx,bx
repe cmpsb
mov ax,inisize
je FST1 ; yes, initok's already attached
mov temp+100,2
mov si,dx
cmp word ptr[si],002ch ; is it ',',0?
je NXT1 ; eq = yes, treat as next
push es
push dx
call exfisr ; rewind & truncate scratch file
pop dx
pop es
mov si,offset wcpath ; move file-spec to wcpath, length to ax
call z2rmx
mov bx,ax
add al,3
mov wccmd,al ; + 3 for 'wc ' makes RMX string
mov si,dx ; point to file-spec
mov cx,bx ; length
FST3: lodsb ; scan for wc chars, if any goto FST4
cmp al,'*'
je FST4
cmp al,'?'
je FST4
cmp al,','
je FST4
loop FST3
mov si,dx ; no need for wc, next can handle it
mov di,offset wcpath+1 ; if we move it over 1 byte
mov cx,bx
rep movsb
jmp short NXT3
FST4: mov si,dx
add si,bx ; point to end
dec si ; backup over zero byte
call bakscan ; find rightmost path separater
cmp al,'\' ; is it \?
jne FST5
call rstr ; yes, force error
mov ax,2 ; it's a DOSism we can do without
stc
ret
FST5: mov ax,rcmdtok ; call rqcsendcommand
mov bx,offset wccmd ; (rcmdtok,@wccmd,@temp,@status)
mov cx,offset temp
call sendcmd
mov bx,scfitok ; rewind scratch file
call rewind
mov nxtflg,0
jmp short NXT1 ; let next finish up
first2 endp
next2 proc
call save
mov temp+100,18 ; error return code
cmp nxtflg,0 ; was next called before 1st,
jne NXT4 ; or after no more? ne = yes
NXT1: mov bx,offset wcpath ; place to stash file name string
mov byte ptr[bx],0 ; empty
NXT2: inc bx ; bump count
push bx
mov ax,scfitok ; read 1 from scratch
mov cx,1
call reader
test ax,ax
pop bx
jz NXT4 ; 0 = EOF
cmp byte ptr[bx],lf
jne NXT2 ; loop 'til EOL
sub bx,offset wcpath+2 ; bx = length file name
NXT3: mov di,offset wcpath
mov [di],bl ; RMX string @di
call gfilsta ; does it exist?
jcxz NXT5 ; 0 = yes
NXT4: mov nxtflg,1 ; mark no more next w/o 1st 1st
call rstr
mov ax,temp+100 ; return error code
stc
ret
NXT5: mov di,kbuf
mov [di+15h],bl ; directory attribute to DTA
mov [di+1ah],ax ; low file size
mov [di+1ch],dx ; high file size
mov bl,byte ptr wcpath
sub bh,bh ; bx = length file name stirng
lea si,wcpath[bx] ; point to end
call bakscan ; separate path/file name
mov cx,bx ; cx = file name length
add di,1eh ; DTA file name field ptr
mov ax,ds ; si points to file name, move it
mov es,ax
rep movsb
mov [di],cl ; make ASCIIZ
call rstr
clc
ret
next2 endp
save proc ; save regs
pop bx
push es
push si
push di
push dx
push cx
push ax
jmp bx
save endp
rstr proc ; restore regs
pop bx
pop ax
pop cx
pop dx
pop di
pop si
pop es
jmp bx
rstr endp
setexcp proc
push ds ; call rqsetexceptionhandler(@xcepinf,@status)
%pushv(offset xcepinf)
push ds
%pushv(offset status)
call rqsetexceptionhandler
ret
setexcp endp
crtsk proc ; ax=rqcreatetask(0,cs:bx,ds,0:0,300h,0,@status)
sub cx,cx ; bx is start address
push cx
push cs
push bx
push ds
push cx
push cx
%pushv(300h)
push cx
push ds
%pushv(offset status)
call rqcreatetask
ret
crtsk endp
crmbx proc ; ax=rqcreatemailbox(0,@status)
%pushv(0)
push ds
%pushv(offset status)
call rqcreatemailbox
ret
crmbx endp
crsema proc
sub ax,ax ; ax=rqcreatesemaphore(0,1,0,@status)
push ax
inc ax
push ax
dec ax
push ax
push ds
%pushv(offset status)
call rqcreatesemaphore
ret
crsema endp
atfile proc ; ax=rqsattachfile(ds:di,@status)
push ds ; ds:di is path ptr
push di
push ds
%pushv(offset status)
call rqsattachfile
ret
atfile endp
crfile proc ; ax=rqscreatefile(ds:di,@status)
push di ; ds:di is path ptr. save di
push ds
push di
push ds
%pushv(offset status)
call rqscreatefile
pop di ; restore di
ret
crfile endp
opfile proc ; call rqsopen(ax,bx,cx,@status)
push ax ; token
push bx ; mode
push cx ; number of buffers
push ds
%pushv(offset status)
call rqsopen
ret
opfile endp
clfile proc ; call rqsclose(ax,@siostat)
push ax ; token
push ds
%pushv(offset siostat)
call rqsclose
ret
clfile endp
delcon proc ; call rqsdeleteconnection(bx,@status)
push bx ; token
push ds
%pushv(offset status)
call rqsdeleteconnection
ret
delcon endp
special proc ; call rqsspecial(ax,cx,ds:bx,0,@status)
push ax ; token
push cx ; function
push ds
push bx ; data ptr
sub ax,ax
push ax
push ax
push ds
%pushv(offset status)
call rqsspecial
ret
special endp
reader proc ; ax=rqsreadmove(ax,ds:bx,cx,@status)
push ax ; token
push ds
push bx ; buffer ptr
push cx ; number of bytes
push ds
%pushv(offset status)
call rqsreadmove
ret
reader endp
writer proc ; ax=rqswritemove(ax,ds:bx,cx,@status)
push ax ; token
push ds
push bx ; buffer ptr
push cx ; number of bytes
push ds
%pushv(offset status)
call rqswritemove
ret
writer endp
rewind proc
mov ax,2 ; setup so seek positions to BOF
sub cx,cx
mov dx,cx
seek proc
push bx ; call rqsseek(token,mode,count,@status)
push ax
push cx
push dx
push ds
%pushv(offset status)
call rqsseek
ret
seek endp
rewind endp
lookup proc ; ax=rqlookupobject(ax,ds:bx,0,@status)
push ax ; job token
push ds ; @name
push bx
push cx ; time limit
push ds
%pushv(offset status)
call rqlookupobject
ret
lookup endp
sdefpfx proc ; call rqsetdefaultprefix(cx,ax,@status)
push cx ; job token
push ax ; prefix token
push ds
%pushv(offset status)
call rqsetdefaultprefix
ret
sdefpfx endp
crcmdco proc ; ax=rqccreatecommandconnection(ax,bx,cx,@status)
push ax ; input token
push bx ; output token
push cx ; flag
push ds
%pushv(offset status)
call rqccreatecommandconnection ; can you believe this shit?
ret
crcmdco endp
sendcmd proc ; call rqcsendcommand(ax,ds:bx,ds:cx,@status)
push ax ; command connection token
push ds
push bx ; pointer to command
push ds
push cx ; pointer to command exception
push ds
%pushv(offset status)
call rqcsendcommand
push cx ; save status
mov ax,citok
mov bx,offset sigpair
mov cx,6
call aspcl ; restore ^C trap
pop cx ; restore status
ret
sendcmd endp
z2rmx proc ; copies ASCIIZ @ds:dx to si, returns count in ax
mov di,dx
mov cx,0ffffh
sub ax,ax
repne scasb
neg cx
add cx,0fffeh
mov ax,cx ; ax=cx= # of bytes
mov di,si
mov si,dx
rep movsb
ret
z2rmx endp
bakscan proc ; finds path part & file name part
std ; bx=string size, si points to EOstring
mov cx,bx
BSC1: lodsb
cmp al,':'
je BSC2
cmp al,'/'
je BSC2
cmp al,'^'
je BSC2
loop BSC1
dec si
BSC2: inc si
inc si ; si point to file name
cld
sub bx,cx ; bx=size file name, cx=size path
ret ; al=separator
bakscan endp
aopen proc ; call rqaopen(ax,bx,3,0,@status)
push ax ; token
push bx ; mode
%pushv(3)
%pushv(0)
push ds
%pushv(offset status)
call rqaopen
ret
aopen endp
aclose proc
push ax ; call rqaclose(ax,cx,@siostat)
push cx
push ds
%pushv(offset siostat)
call rqaclose
ret
aclose endp
aread proc ; call rqaread(ax,ds:bx,cx,dx,@siostat)
push ax
push ds
push bx ; buffer ptr
push cx ; count
push dx ; response mailbox
push ds
%pushv(offset siostat)
call rqaread
ret
aread endp
awrite proc ; call rqawrite(ax,ds:bx,cx,dx,@siostat)
push ax
push ds
push bx ; buffer ptr
push cx ; count
push dx ; response mailbox
push ds
%pushv(offset siostat)
call rqawrite
ret
awrite endp
aspcl proc ; call rqaspecial(ax,cx,ds:bx,tmbox,@siostat)
push ax ; token
push cx ; function
push ds
push bx ; ioparm ptr
push tmbox
push ds
%pushv(offset siostat)
call rqaspecial
mov ax,tmbox
mov bx,0ffffh
call rcvmsg ; ax=rqreceivemessage(tmbox,0ffffh,@ignore,@siostat)
call delseg
ret
aspcl endp
waitio proc ; ax=rqwaitio(ax,bx,0ffffh,@status)
push ax ; token
push bx ; response mailbox
%pushv(0ffffh)
push ds
%pushv(offset status)
call rqwaitio
ret
waitio endp
sendms proc ; call rqsendmessage(ax,bx,0,@status)
push ax ; mailbox token
push bx ; object to send
%pushv(0)
push ds
%pushv(offset status)
call rqsendmessage
cld
ret
sendms endp
rcvmsg proc
pop bp ; ax=rqreceivemessage(tmbox,0ffffh,@ignore,@siostat)
push ax ; mail box token
push bx ; time limit
push ds
%pushv(offset ignore)
push ds
%pushv(offset siostat)
call rqreceivemessage
jmp bp
rcvmsg endp
rcvun proc ; call rqreceiveunits(ax,1,0ffffh,@ccstat)
pop bp
push ax ; semaphore token
%pushv(1) ; units
%pushv(0ffffh) ; time limit
push ds
%pushv(offset ccstat)
call rqreceiveunits
jmp bp
rcvun endp
delseg proc ; call rqdeletesegment(ax,@status)
push ax
push ds
%pushv(offset siostat)
call rqdeletesegment
ret
delseg endp
gconsta proc
push bx ; call rqsgetconnectionstatus(token,@temp,@status)
push ds
%pushv(offset temp)
push ds
%pushv(offset status)
call rqsgetconnectionstatus
ret
gconsta endp
gfilsta proc
push ds ; call rqsgetfilestatus(ds:di,@temp,@status)
push di ; path ptr
push ds
%pushv(offset temp)
push ds
%pushv(offset status)
call rqsgetfilestatus
jcxz GFIL1
ret
GFIL1: mov bx,cx
cmp byte ptr temp+9,0ffh ; is it a named file?
je GFIL2
mov ax,cx ; no, setup for zero length
mov dx,cx
ret
GFIL2: cmp byte ptr temp+38,8 ; is it a directory?
je GFIL3 ; eq = no
mov bl,10h ; yes, get DOS directory attribute
GFIL3: mov ax,temp+54 ; low file size
mov dx,temp+56 ; high file size
ret
gfilsta endp
code ends
end begin, ds:datas, ss:stack