Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/05/SUBMIT.A86
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

884 lines
18 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************
;*
;* Submit MP/M-86
;*
;*****************************************************
true equ 0ffh
false equ 0
unknown equ 0
mpmint equ 224 ; int vec for mpm ent.
mpm_conin equ 1
mpm_conout equ 2
mpm_conwrite equ 9
mpm_conread equ 10
mpm_constat equ 11
mpm_version equ 12
mpm_diskselect equ 14
mpm_openfile equ 15
mpm_readfile equ 20
mpm_getdefdisk equ 25
mpm_setdma equ 26
mpm_usercode equ 32
mpm_terminate equ 143
mpm_setprior equ 145
mpm_conattach equ 146
mpm_condetach equ 147
mpm_setdefcon equ 148
mpm_clicmd equ 150
mpm_parse equ 152
mpm_getdefcon equ 153
mpm_getpdadr equ 156
mpm_setdeflst equ 160
mpm_getdeflst equ 164
; fcb offsets
mode2 equ 6 ; 2nd open mode byte
ftype equ 9 ; file type
cr equ 32 ; offset of current record
e_no_memory equ 3 ; cant find memory
e_no_pd equ 12 ; no free pd's
e_q_full equ 15 ; full queue
e_badfname equ 24 ; illegal filename
e_badftype equ 25 ; illegal filetype
e_bad_load equ 28 ; bad ret. from BDOS load
e_bad_read equ 29 ; bad ret. from BDOS read
e_bad_open equ 30 ; bad ret. from BDOS open
e_nullcmd equ 31 ; null command sent
p_prior equ 05H ;process descriptor priority
p_flag equ word ptr 06H ;flags
p_name equ 08H ;name of process
p_parent equ 1EH ;PD's parent
pf_keep equ 02H ;keep flag
pf_childabort equ 800H ;child aborted abnormally
pf_ctlc equ 080H ;control c occured
;*****************************************************
;*
;* Submit Code
;*
;*****************************************************
cseg
org 0
jmps submit
db 'COPYRIGHT (C) 1981,'
db ' DIGITAL RESEARCH '
db '5 Oct 1981'
db 13,10,0,'$'
;======
submit: ; PROGRAM MAIN - INITIALIZATION
;======
mov ax,ds
pushf ! pop bx
mov ss,ax
mov sp,offset stacktop
push bx ! popf
mov cl,mpm_version
call mpm
cmp bh,11H
jz okvers
mov dx,offset wrongvers
mov cl, mpm_conwrite ! call mpm
mov cl,0 ! call mpm
okvers:
;
;set priority better than parent
;
mov cl,mpm_getpdadr
call mpm ;get our PD address
mov pdadr,bx ;save PD address
mov sysdatseg,es ;and the system data area segment
mov bx,es:p_parent[bx] ;get our parent's PD address
cmp bx,0 ! jne psetpar ;see if parent exists
mov dx,197 ! jmps setp ; oops, set to better than TMP
psetpar:mov dx,es:p_prior[bx] ;our parent's priority
dec dx ;we run at one better,
cmp dx,64 ! jae setp
mov dx,64 ;don't compete w/system
setp: mov cl,mpm_setprior
call mpm ;set our priority
mov cl,mpm_setdma ;using default buffer at 80H for
mov dx,offset dma ;command tail and argument expansion
call mpm
mov si,offset fcb
mov byte ptr ftype[si],'S' ;look for file with type = SUB
mov byte ptr ftype+1[si],'U'
mov byte ptr ftype+2[si],'B'
mov byte ptr cr[si],0 ;zero current record
or byte ptr mode2[si],80h ;open in R/O mode
mov dx,si
call openfile
cmp al,0ffh
jnz exists
mov dx,offset sopen_err
call con_write
jmp submitexit
exists:
mov al,fcb ;save disk number where command file is
cmp al,0 ;default disk ?
jnz save_disk_no
mov cl,mpm_getdefdisk
call mpm
inc al
save_disk_no:
mov command_disk,al
mov cl,mpm_usercode ;save user number of
mov dl,0ffh
call mpm ;command file
mov command_user,al
mov cx,mpm_getdefcon
call mpm ;save console number this
mov command_con,al ;program was run from
;
;deblank command tail
;
mov si,offset cmdtail + 1
mov di,offset deblankbuf
firstwhites:
cmp byte ptr [si],' '
jnz tab
jmps morewhites
tab:
cmp byte ptr [si],9
jnz deblank
morewhites:
inc si
jmps firstwhites
deblank:
mov al,byte ptr [si]
inc si
cmp al,' '
jz skipwhite
cmp al,9 ;tab
jz skipwhite
jmps copychar
copychar:
cmp al,0 ;end of of command tail ?
jz putlastblank
mov [di],al
inc di
jmps deblank
putlastblank:
mov byte ptr [di],' '
inc di
mov [di],al ;ends with space and zero
jmps dedone
skipmore:
inc si
skipwhite: ;input = si points at tab or blank
mov al,[si]
cmp al,' '
jz skipmore
cmp al,9 ;tab
jz skipmore
mov byte ptr [di],' '
inc di
jmps deblank ;si points to non white char
;di is next char to copy
dedone:
;
;fill argument tail
;
mov bp,offset deblankbuf
mov bx,offset argtable
xor si,si ;pointer into deblankbuf
mov di,si ;index into argtable
nxtfill:
mov al,byte ptr [bp + si] ;0th argument is '<filename>.sub'
cmp al,0
jz filldone
mov [bx + di],si
inc di
call skiparg ;skip over argument and blank
jmps nxtfill
skiparg:
inc si
cmp byte ptr [bp + si],' '
jnz skiparg
inc si ;char after blank
ret
filldone:
mov numargs,di
call crlf
;get first command from SUB file
mov cmdbuf,maxcmdlen ! mov dx,offset cmdbuf
call readbuffer ;read from file to next crlf
cmp bx,0 ! je topofcmdloop ;assume EOF if BX <> 0
;jmp submitexit
;==========
submitexit:
;==========
mov cl,0 ! mov dx,0
;jmp mpm
;===
mpm: ; INTERFACE ROUTINE FOR SYSTEM ENTRY POINTS
;===
int mpmint ! ret
;===========
topofcmdloop: ; LOOP FOREVER
;===========
;
; check to see if control c was typed during last command
;
mov bx,pdadr
mov es,sysdatseg
test es:p_flag[bx],pf_childabort
jz gonext
and es:p_flag[bx],not pf_childabort ;turn off child abort flg
mov cl,11 ! mov si,offset fcb + 1
mov di, offset subfilename
push ds ! pop es
rep movs al,al
mov dx,offset askabortmsg
call con_write
call charin
and al,5fh ;make upper case
cmp al,'Y'
jnz gonext
;stop this submit and turn on
;pf_ctlc flag
mov bx,pdadr ! mov es,sysdatseg
or es:p_flag[bx],pf_ctlc
submitexit1: jmp submitexit
gonext:
;
; print CR,LF if we just sent a command
;
cmp cmdsent,false ! je noclearline
mov cmdsent,false
call crlf
noclearline:
;
; set up and print user prompt
;
; get current default disk
mov cl,mpm_getdefdisk ! call mpm
mov defdisk,al
; get current default user #
; this call should be made on every
; loop in case the 'USER' program
; has changed the default user number
mov cl,mpm_usercode ! mov dl,0ffh
call mpm
mov defuser,al
;create user part of prompt string
mov promptutens,13
mov promptuones,'0'
cmp al,10 ! jb ones
mov promptutens,'1'
sub al,10
ones: add promptuones,al
; create disk part of prompt string
mov al,'A' ! add al,defdisk
mov promptdisk,al
; write user prompt
mov dx,offset prompt
cmp promptutens,13 ! jne writeprompt
mov dx,offset promptutens
writeprompt:
mov cl,mpm_conwrite ! call mpm
;
; copy command to cli buffer, make upper case and
; expand command arguments
;
mov si,offset cmd ;where command is
mov bp,offset clicmd ;copy w/ expanded args here
xor di,di ;index into cli command
nextchar:
mov al,[si] ;char from command
inc si
cmp al,'$' ;argument ?
jz argmaybe
noarg:
call copyit
jmps nextchar
argmaybe:
cmp byte ptr [si],'0' ;is next char after '$' a digit ?
jb noarg
cmp byte ptr [si],'9'
ja noarg
realarg:
xor ax,ax ;copy argument throw out - '$' in al
mov al,[si]
sub al,'0' ;1st digit
inc si
cmp byte ptr [si],'0' ;is there a second digit ?
jb onedigit
cmp byte ptr [si],'9'
ja onedigit
mov dl,10 ;1st digit is tens in column
mul dl
mov dl,[si] ;2nd argument is ones column
inc si
sub dl,'0'
add al,dl
onedigit:
mov bx,ax
copyarg:
cmp bx,numargs ;
jb oknum ;numargs in range 1 to n
jmps nextchar ;no such argument
oknum:
mov bl,argtable[bx] ;argument address rel to deblankbuf
copymore:
mov al,deblankbuf[bx]
cmp al,' '
jz nextchar ;end of argument
call copyit
inc bx
jmps copymore
;utility subroutine
copyit:
mov [bp + di],al ;mov to cli command buffer
inc di
cmp di,maxcmdlen ;cli buffer size
jae donecopy
testend:
cmp al,0
jz donecopy
ret
donecopy:
mov byte ptr [bp + di], '$'
pop ax ;return is garbage
;jmps echocommand ;fall through to echocommand
echocommand:
;print command after argument
mov dx,offset clicmd ;substitution
mov bx,dx ! cmp byte ptr [bx], '$'
jnz writecommand
inc dx ;skip '$' if line begins with '$'
writecommand:
call con_write
;
; echo newline
;
call crlf
;
; make sure not a null command
;
lea bx,cmd
cmp blen,0 ! je gonextcmd
cmp byte ptr [bx],';' ! je gonextcmd
;
; see if disk change - if 'X:' change def disk to X
;
cmp blen,2 ! jne notdrive
cmp byte ptr 1[bx],':' ! jne try_builtin
; change default disk
mov dl,[bx] ;get disk name
and dl,5fh ;make Upper Case
sub dl,'A' ;make disk number
; check bounds
cmp dl,0 ! jb subex
cmp dl,15 ! jbe okdrive
subex:
jmp submitexit
okdrive:
; select default disk
mov cl,mpm_diskselect
call mpm
gonextcmd: jmp getnxtcmd
notdrive: mov di,offset clicmd
mov si, offset parseresult
call parsefilename
jcxz goodparse
mov cl,126
mov di,offset clicmd
mov al, ' '
push cs ! pop es
repne scasb
mov byte ptr[di], '$'
jmp clierror
goodparse: mov parseret,bx
cmp parseresult,0 ! jz try_builtin
jmp not_builtin
try_builtin:
mov di,offset usercmd
mov si,offset parseresult ! inc si
push ds ! pop es
mov cx,4 ! repz cmpsw
jnz notuser
mov si,offset parseresult
mov di,parseret ! cmp di,0
je pruser
call parsefilename ; CX = 0 if ok
cmp cx,0 ! jne pruser
mov si,offset parseresult ! inc si
mov dx,[si]
call a_to_b
cmp bl,15 ! ja usererr
mov dl,bl ! call setuser
jmp pruser
usererr: mov dx,offset usererrmsg
call con_write
pruser: mov dx,offset usermsg
call con_write
call getuser
mov dl,bl ! call prnum
call crlf
jmp getnxtcmd
notuser:
mov si,offset parseresult ! inc si
mov di,offset printercmd
push ds ! pop es
mov cx,4 ! repz cmpsw
jnz notprinter
mov si,offset parseresult
mov di,parseret ! test di,di
jz prprinter
call parsefilename ; CX = 0 if ok
cmp cx,0 ! jne prprinter; no tail
mov si,offset parseresult ! inc si
mov dx,[si]
call a_to_b
cmp bl,0ffh ! je printererr
mov dl,bl ! call setlist
jcxz prprinter
printererr: mov dx,offset printererrmsg
call con_write
prprinter: mov dx,offset printermsg
call con_write
call getlist
mov dl,bl ! call prnum
call crlf
jmp getnxtcmd
notprinter:
; check for '$include' option
mov si,offset parseresult ! inc si
mov di,offset includecmd
push ds ! pop es
mov cx,4 ! repz cmpsw
jnz notinclude
mov si,offset parseresult
mov di,parseret ! test di,di
jz notinclude
call parsefilename ; CX = 0 if ok
cmp cx,0 ! jne includerr; no tail
mov si,pdadr
add si,p_name
mov di,offset clicmd
mov cl,4
push ds ! pop es
push ds ! mov ds,sysdatseg
; overwrite $include with
rep movsw ; name of this program
; for recursive submits
pop ds
mov dx,offset includemsg
call con_write
jmps clicall ; send submit command
includerr: mov dx,offset includerrmsg
call con_write
jmp submitexit
notinclude:
notbuiltin:
;=======
clicall: ; SEND CLI COMMAND
;=======
; initialize Cli Control Block
mov clicb_net,0
; make cli call
mov cmdsent,true
lea dx,clicb ! mov cl,mpm_clicmd
call mpm
cmp bx,0 ! jne clierror
;
; more commands in sub file to process ?
;
getnxtcmd:
mov cmdbuf,maxcmdlen ! mov dx,offset cmdbuf
call readbuffer ;read from file to next crlf
cmp bx,0 ! je moretodo ;assume EOF if BX <> 0
jmp submitexit
moretodo:
mov cl,mpm_conattach ! call mpm
jmp topofcmdloop
;========
clierror:
;========
; Cli call unsuccesful, analyze and display error message
; input: CX = ERROR CODE
;null command?
cmp cx,e_nullcmd ! jne not_nullcmd
mov cmdsent,false
jmp getnxtcmd
not_nullcmd:
;no memory?
cmp cx,e_no_memory ! jne memory_ok
mov dx,offset memerr ! jmp showerr
memory_ok:
;no pd in table?
cmp cx,e_no_pd ! jne pd_ok
mov dx,offset pderr ! jmp showerr
pd_ok:
;illegal command name?
cmp cx,e_badfname ! je fname_bad
cmp cx,e_badftype ! jne fname_ok
fname_bad: mov dx,offset fnameerr ! jmp showerr
fname_ok:
;bad load?
cmp cx,e_bad_load ! je load_bad
cmp cx,e_bad_read ! jne load_ok
load_bad: mov dx,offset loaderr ! jmp showerr
load_ok:
;bad open?
cmp cx,e_bad_open ! jne open_ok
mov dx,offset openerr ! jmp showerr
open_ok:
;RSP que full?
cmp cx,e_q_full ! jne que_ok
mov dx,offset qfullerr ! jmp showerr
que_ok:
;some other error...
mov dx,offset catcherr
;jmp showerr
;=======
showerr:
;=======
; Print Error String
; input: DX = address of Error String
call conwrite
jmp submitexit
;==========
readbuffer:
;==========
; Simulate Read Console buffer from a disk file.
; input: DX = buffer address
; output: BX <> 0 if EOF
mov di,dx
xor al,al
mov 1[di],al ;no chars read
cmp 0[di],al ;zero length buffer
jnz buf_ok ;return no error - nop
mov bx,0ffffh
ret
buf_ok:
mov si,di ! inc si ! inc si
;si is next char
read_another:
mov al,1[di]
cmp al,[di]
jae done_ok ;full buffer
push di
call readchar ;fills [si]
pop di
cmp bx,0 ;non-zero or eof error
jz not_error
ret
not_error:
cmp byte ptr [si],0ah ! jne not_lf
jmps done_ok
not_lf: cmp byte ptr [si],0dh ! je done_ok
inc byte ptr 1[di] ;not cr, inc buffer count
inc si ;inc char position
jmp read_another
done_ok:
cmp byte ptr 1[di],0 ;no characters read in buffer
jz read_another ;skip leading cr's and lf's
mov byte ptr [si],0
mov bx,0 ! ret
;========
readchar:
;========
; Read a character from file.
; input = si is address of where to put character
; output = bx <> 0 if error
;
xor bh,bh
mov bl,buf_ptr ;char ptr in dma buffer
cmp bl,128
jb no_read
push si
mov dl,command_user ;user of command file
mov cl,mpm_usercode
call mpm
mov bx,offset fcb
mov al,command_disk ;disk drive number of command file
mov [bx],al ;re-open each time to allow deletion
or byte ptr mode2[bx],80h ;of command file, open in R/O mode
mov dx,bx
call openfile
cmp al,0ffh
jz readerr
mov dx,offset fcb
call readfile ;read sequential
cmp al,0
jnz readerr
mov cl,mpm_usercode ;set user back to what the command
mov dl,defuser ;file has set it to
call mpm
mov bx,0
pop si
no_read:
mov al,dma[bx]
cmp al,1ah ;check for EOF
jz eof
mov [si],al
inc bl
mov buf_ptr,bl ;point to next char in disk buffer
xor bx,bx
ret
readerr:
pop si
eof:
mov bx,0ffffh ;error or eof
ret
;*****************************************************
;*
;* SUBROUTINES
;*
;*****************************************************
parsefilename: ;SI = fcb DI = string
mov cx,mpm_parse
mov bx,offset pcb
mov [bx],di ! mov 2[bx],si
mov dx,bx ! jmp mpm
a_to_b: ;dl = 1st char, dh = 2nd char
cmp dh,' ' ! jne atob2char
mov dh,dl ! mov dl,'0'
atob2char: cmp dh,'0' ! jb atoberr
cmp dh,'9' ! ja atoberr
cmp dl,'0' ! jb atoberr
cmp dl,'9' ! ja atoberr
sub dh,'0' ! sub dl,'0'
mov ax,0 ! mov al,dl
push dx ! mov cl,10 ! mul cl ! pop dx
mov dl,dh ! mov dh,0 ! add ax,dx
mov bx,ax ! ret
atoberr: mov bl,0ffh ! ret
prnum: ; dl = num (0-15)
cmp dl,10 ! jb prnum_one
push dx
mov dl,'1' ! call prchar
pop dx ! sub dl,10
prnum_one: add dl,'0'
jmp prchar
charin: mov cl,mpm_conin ! jmp mpm
prchar: mov cl,mpm_conout ! jmp mpm
getuser: mov dl,0ffh
setuser: mov cl,mpm_usercode ! jmp mpm
setconsole: mov cl,mpm_setdefcon ! jmp mpm
setdisk: mov cl,mpm_diskselect ! jmp mpm
getdisk: mov cl,mpm_getdefdisk ! jmp mpm
setlist: mov cl,mpm_setdeflst ! jmp mpm
getlist: mov cl,mpm_getdeflst ! jmp mpm
attach: mov cl,mpm_conattach ! jmp mpm
detach: mov cl,mpm_condetach ! jmp mpm
conread: mov cl,mpm_conread ! jmp mpm
crlf:
mov dx,offset newline
;jmp con_write
con_write:
mov cl,mpm_conwrite
jmp mpm
openfile:
mov cl,mpm_openfile
jmp mpm
readfile:
mov cl,mpm_readfile
jmp mpm
;*****************************************************
;*
;* Data Area
;*
;*****************************************************
dseg
org 05cH
fcb rb 024H
org 080h
cmdtail rb 128
stack dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
stacktop rw 0
maxcmdlen equ 128
; the Read Console Buffer and the
; Cli Control Block share the same memory
dma rb 128
numargs rw 1
argtable rb 64 ;address of arguments in cmdtail
deblankbuf rb maxcmdlen + 1
cmdbuf rb 1 ;single command gets put here
blen rb 1
cmd rb maxcmdlen + 1
clicb rb 0 ;command w/ expanded args goes here
clicb_net db 0
clicmd rb maxcmdlen+1
command_user rb 1
command_disk rb 1
command_con rb 1
defdisk rb 1
defuser rb 1
buf_ptr db 128 ;force initial read
;in readchar routine
prompt db 13
promptutens db '0'
promptuones db '0'
promptdisk db 'A'
promptend db '>$'
pcb dw offset clicmd
dw offset parseresult
parseret dw 0
parseresult rb 36
cmdsent db false
pdadr rw 1 ;our pd address
sysdatseg rw 1 ;the system data area's segment
;*****************************************************
;*
;* CONSTANTS
;*
;*****************************************************
wrongvers db 'Requires MP/M-86'
newline db 10,13,'$'
askabortmsg db 13,10,10,'Terminate '
subfilename rb 11
db ' (Y/N) ? $'
usercmd db 'USER '
printercmd db 'PRINTER '
includecmd db '$INCLUDE'
usererrmsg db 13,10,'Invalid User Number, IGNORED',13,10,'$'
usermsg db 13,10,'User Number = $'
printererrmsg db 13,10,'Invalid Printer Number, IGNORED',13,10,'$'
printermsg db 13,10,'Printer Number = $'
includerrmsg db 13,10,'Include Error$'
includemsg db '(submit)',10,13,'$'
memerr db '?Not Enough Memory$'
pderr db '?PD Table Full$'
fnameerr db '?Illegal Command$'
loaderr db '?Load Error$'
openerr db '?Can''t Find Command$'
catcherr db '?$'
qfullerr db '?RSP Command Que Full$'
;SUBMIT error messages
sopenerr db 'No ''SUB'' File Present$'
argerr db 'Illegal Argument$'
end