mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 01:14:21 +00:00
1051 lines
23 KiB
Plaintext
1051 lines
23 KiB
Plaintext
;*****************************************************
|
||
;*
|
||
;* Submit CCP/M-86
|
||
;*
|
||
;*****************************************************
|
||
|
||
;Revisions:
|
||
; 30 Mar 83 dh - attach after commands except chain
|
||
; 21 Mar 83 whf - cli on 'mov ss'; fix readchar eof
|
||
; 18 Feb 83 whf - $global/$local cmds
|
||
; 15 Feb 83 dh - closing windows
|
||
|
||
cseg
|
||
|
||
jmps submit
|
||
|
||
db 'SUBMIT 1.3 '
|
||
db 'COPYRIGHT (C) 1983,'
|
||
db ' DIGITAL RESEARCH '
|
||
db '3/21/83'
|
||
db 13,10,0,'$'
|
||
|
||
|
||
|
||
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_closefile equ 16
|
||
mpm_readfile equ 20
|
||
mpm_getdefdisk equ 25
|
||
mpm_setdma equ 26
|
||
mpm_usercode equ 32
|
||
mpm_chain equ 47
|
||
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
|
||
modesys equ 10 ; SYS attribute byte
|
||
ftype equ 9 ; file type
|
||
|
||
sysdrive equ byte ptr .4bh ;system disk in SYSDAT
|
||
|
||
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_illdisk equ 23 ; illegal disk #
|
||
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
|
||
e_ill_lst equ 37 ; illegal list device
|
||
e_ill_passwd equ 38 ; illegal password
|
||
e_abort equ 40 ; aborted in CLI
|
||
|
||
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
|
||
p_drv equ byte ptr 012H
|
||
p_user equ byte ptr 013H
|
||
p_list equ byte ptr 024H
|
||
|
||
pf_keep equ 02H ;keep flag
|
||
pf_childabort equ 800H ;child aborted abnormally
|
||
pf_ctlc equ 080H ;control c occured
|
||
|
||
;*****************************************************
|
||
;*
|
||
;* Submit Code
|
||
;*
|
||
;*****************************************************
|
||
|
||
;======
|
||
submit: ; PROGRAM MAIN - INITIALIZATION
|
||
;======
|
||
mov ax,ds
|
||
pushf ! pop bx ! cli ;disable interrupts for stack switch
|
||
mov ss,ax
|
||
mov sp,offset stacktop
|
||
push bx ! popf ;restore interrupts
|
||
|
||
mov cl,mpm_version
|
||
call mpm
|
||
and bh,not 2 ;strip network bit
|
||
cmp bh,11H ! jz okvers ;check MP/M-86 or
|
||
cmp bh,14H ! jz okvers ;check Concurrent CP/M-86
|
||
mov dx,offset wrongvers
|
||
call print_string
|
||
jmp terminate
|
||
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
|
||
mov parent_offset,bx ;save parent's PD addr
|
||
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
|
||
|
||
call getuser
|
||
mov command_user,al
|
||
mov defuser,al
|
||
|
||
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'
|
||
or byte ptr mode2[si],80h ;open in R/O mode
|
||
mov dx,si
|
||
call openfile
|
||
cmp al,0ffh
|
||
jne exists
|
||
|
||
mov dl,0 ;try user 0
|
||
mov command_user,dl
|
||
call setuser
|
||
mov es,sysdatseg ;on system drive
|
||
mov al,es:sysdrive
|
||
inc al
|
||
mov fcb,al
|
||
mov dx,offset fcb
|
||
call openfile
|
||
cmp al,0ffh
|
||
je openfail
|
||
mov si,offset fcb
|
||
test byte ptr modesys[si],080H ;does it have SYS attribute?
|
||
jnz exists
|
||
openfail:
|
||
mov dx,offset sopen_err
|
||
call print_string
|
||
jmp submitabort
|
||
|
||
exists:
|
||
mov dx,offset fcb
|
||
call closefile
|
||
mov al,fcb ;save disk number where command file is
|
||
cmp al,0 ;default disk ?
|
||
jnz save_disk_no
|
||
call getdisk
|
||
inc al
|
||
save_disk_no:
|
||
mov command_disk,al
|
||
|
||
call getconsole ;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
|
||
|
||
mov cmdbuf,maxcmdlen ;get first command
|
||
mov dx,offset cmdbuf
|
||
call readbuffer
|
||
cmp bx,0
|
||
jne submitexit ;EOF on first command
|
||
|
||
mov lcmdbuf,maxcmdlen ;try next command
|
||
mov dx,offset lcmdbuf
|
||
call readbuffer
|
||
mov no_more_cmds,bl ;true if EOF
|
||
jmps topofcmdloop ;and look ahead to see
|
||
;if there are more commands
|
||
|
||
;==========
|
||
submitexit:
|
||
;==========
|
||
|
||
mov cl,0 ! mov dx,0
|
||
;jmp mpm
|
||
|
||
;===
|
||
mpm: ; INTERFACE ROUTINE FOR SYSTEM ENTRY POINTS
|
||
;===
|
||
|
||
int mpmint ! ret
|
||
|
||
;===========
|
||
topofcmdloop: ; LOOP FOREVER
|
||
;===========
|
||
|
||
;
|
||
; 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
|
||
|
||
|
||
call getdisk
|
||
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
|
||
|
||
call getuser
|
||
mov defuser,al
|
||
|
||
;create user part of prompt string
|
||
|
||
mov promptutens,13
|
||
mov promptuones,13
|
||
test al,al ;don't print user 0
|
||
jz prprompt
|
||
mov promptuones,'0'
|
||
cmp al,10 ! jb ones
|
||
mov promptutens,'1'
|
||
sub al,10
|
||
ones: add promptuones,al
|
||
prprompt:
|
||
; 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:
|
||
call print_ds_string
|
||
|
||
;
|
||
; 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
|
||
jcxz nextchar
|
||
jmps echo_cmd ;can't expand any more params,
|
||
;buffer is full
|
||
argmaybe:
|
||
cmp byte ptr [si],'$' ;look for two '$' in a row
|
||
jne numeric
|
||
inc si ;skip 2nd $ sign
|
||
jmps noarg ;copy one $ sign to command buffer
|
||
numeric:
|
||
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
|
||
|
||
|
||
copyit:
|
||
;copy character in AL to location BP + DI, increment DI.
|
||
;if AL = 0, or command buffer is full then return CX = 0ffffH
|
||
;else return CX = 0H
|
||
|
||
mov [bp + di],al ;mov to cli command buffer
|
||
inc di
|
||
xor cx,cx
|
||
cmp di,maxcmdlen ;cli buffer size
|
||
jae donecopy
|
||
testend:
|
||
cmp al,0
|
||
jz donecopy
|
||
ret
|
||
donecopy:
|
||
mov clicmdlen, di
|
||
dec cx
|
||
ret
|
||
|
||
echo_cmd:
|
||
mov si, offset clicmd ;print command line after
|
||
mov cx, clicmdlen ;parameter substitution
|
||
call printcmdline
|
||
|
||
;
|
||
; echo newline
|
||
;
|
||
|
||
call crlf
|
||
|
||
;
|
||
; make sure not a null command
|
||
;
|
||
|
||
lea bx,cmd
|
||
cmp blen,0 ! je gonextcmd
|
||
dblank:
|
||
cmp byte ptr [bx],' ' ! je zapblank
|
||
cmp byte ptr [bx],9 ! jne noblanks ;no tabs
|
||
zapblank:
|
||
inc bx ! dec blen ! jmps dblank
|
||
noblanks:
|
||
lea ax,cmd ! cmp ax,bx ! je chksemi
|
||
; remove leading blanks
|
||
push ds ! pop es ! xor ch,ch ! mov cl,blen
|
||
mov di,ax ! mov si,bx ! cld ! rep movsb
|
||
mov bx,ax
|
||
chksemi: ; see if line starts with semicolon
|
||
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:
|
||
mov dx,offset errstr ! call print_string
|
||
mov dx,offset drverr ! call print_string !call crlf
|
||
jmp submitabort
|
||
okdrive:
|
||
push dx ! call setdisk ! pop dx ; select default disk
|
||
cmp fix_parent,false
|
||
jz gonextcmd ;don't change parent's drive
|
||
mov bx,parent_offset ! test bx,bx
|
||
jz gonextcmd ;parent doesn't exist
|
||
mov es,sysdatseg
|
||
mov es:p_drv[bx],dl
|
||
|
||
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 ! push dx
|
||
call setuser ! pop dx
|
||
mov defuser,dl
|
||
cmp fix_parent,false
|
||
jz pruser ;don't fix parent
|
||
mov bx,parent_offset ! test bx,bx
|
||
jz pruser ;parent doesn't exist
|
||
mov es,sysdatseg
|
||
mov es:p_user[bx],dl
|
||
jmps pruser
|
||
usererr: mov dx,offset usererrmsg
|
||
call print_string
|
||
jmp submitabort ;any error fatal
|
||
pruser: mov dx,offset usermsg
|
||
call print_string
|
||
call getuser
|
||
mov dl,bl ! call prnum
|
||
call crlf ! 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 ! push dx
|
||
call setlist ! pop dx
|
||
jcxz setparent ;CX=0 if ok list #
|
||
printererr: mov dx,offset printererrmsg
|
||
call print_string ! jmp submitabort ;any err fatal
|
||
setparent:
|
||
cmp fix_parent,false
|
||
jz prprinter ;don't fix parent
|
||
mov bx,parent_offset ! test bx,bx
|
||
jz prprinter ;check for parent
|
||
mov es,sysdat_seg
|
||
mov es:p_list[bx],dl ;0 relative
|
||
;in CCP/M
|
||
prprinter:
|
||
mov dx,offset printermsg
|
||
call print_string
|
||
call getlist
|
||
mov dl,bl ! call prnum
|
||
call crlf ! 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 print_string
|
||
|
||
jmps clicall ; send submit command
|
||
|
||
includerr: mov dx,offset includerrmsg
|
||
call print_string
|
||
jmp submitabort
|
||
notinclude:
|
||
; check for '$global' option
|
||
|
||
mov si,offset parseresult ! inc si
|
||
mov di,offset globalcmd
|
||
push ds ! pop es
|
||
mov cx,4 ! repz cmpsw
|
||
jnz notglobcmd
|
||
|
||
mov fix_parent,true ;for d:, USER & PRINTER cmds
|
||
mov dx,offset globalmsg
|
||
call print_string
|
||
jmp getnxtcmd
|
||
notglobcmd:
|
||
; check for '$local' option
|
||
|
||
mov si,offset parseresult ! inc si
|
||
mov di,offset localcmd
|
||
push ds ! pop es
|
||
mov cx,4 ! repz cmpsw
|
||
jnz notlocal
|
||
|
||
mov fix_parent,false ;for d:, USER & PRINTER cmds
|
||
mov dx,offset localmsg
|
||
call print_string
|
||
jmp getnxtcmd
|
||
notlocal:
|
||
|
||
notbuiltin:
|
||
|
||
;=======
|
||
cli_call: ; SEND CLI COMMAND
|
||
;=======
|
||
|
||
; initialize Cli Control Block
|
||
|
||
mov clicb_net,0
|
||
; make cli call
|
||
|
||
mov cmdsent,true
|
||
cmp no_more_cmds,true
|
||
jne gocli
|
||
mov dx,offset clicmd ;this is the last command
|
||
mov cl,mpm_setdma
|
||
call mpm
|
||
mov cl,mpm_chain
|
||
call mpm
|
||
;returned from chain
|
||
;*********
|
||
; mov cx,e_bad_open no longer with us
|
||
nop ! nop ! nop ;so same as patch
|
||
;*********
|
||
jmp clierror
|
||
gocli:
|
||
lea dx,clicb ! mov cl,mpm_clicmd
|
||
call mpm
|
||
cmp bx,0 ! jne clierror
|
||
;jmps get_nxtcmd
|
||
|
||
getnxtcmd:
|
||
cmp no_more_cmds,true
|
||
jne getnxt2
|
||
jmp submitexit ;terminate if no more commands
|
||
getnxt2:
|
||
call attach ;get the console back
|
||
;before the TMP does
|
||
|
||
mov si,offset lcmdbuf ;copy look ahead command
|
||
mov di,offset cmdbuf ;buffer to cmdbuf
|
||
mov cx,maxcmdlen+3 ;cmd buffer length
|
||
mov ax,ds
|
||
mov es,ax
|
||
cld
|
||
rep movsb
|
||
|
||
mov dx,offset lcmdbuf ;get look ahead command
|
||
call readbuffer
|
||
mov no_more_cmds,bl ;true if EOF
|
||
jmp topofcmdloop ;and look ahead to see
|
||
;if there are more commands
|
||
|
||
;========
|
||
clierror:
|
||
;========
|
||
; Cli call unsuccesful, analyze and display err msg
|
||
; input: CX = ERROR CODE
|
||
|
||
mov si,(offset clierrtab)-4
|
||
push ds ! push cs ! pop ds
|
||
nexterr:
|
||
add si,4
|
||
cmp cs:word ptr [si],0ffffh ! je unknownerr
|
||
cmp cx,cs:[si] ! jne nexterr
|
||
unknownerr:
|
||
mov dx,cs:2[si]
|
||
pop ds
|
||
; jmps showerr
|
||
|
||
|
||
showerr: ; Print Error String
|
||
;------- ; input: DX = string in CSEG
|
||
|
||
perr: push dx ! call crlf
|
||
mov dx, offset errstr ! call print_string
|
||
pop dx ! call print_string ! call crlf
|
||
mov dx, offset cmdstr ! call print_string
|
||
mov si, offset clicmd
|
||
mov cx, clicmdlen
|
||
call printcmdline ! call crlf
|
||
;jmp submitabort ;any error at this level is fatal
|
||
|
||
;===========
|
||
submitabort:
|
||
;===========
|
||
; Tell user we are aborting
|
||
mov dx,offset abortstr ! call print_string
|
||
jmp submitexit
|
||
|
||
;==========
|
||
readbuffer:
|
||
;==========
|
||
; Simulate Read Console buffer from a disk file.
|
||
; input: DX = buffer address
|
||
; output: BX = 0ffffh 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 ;ready for error
|
||
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 = 0ffffh if error or EOF
|
||
;
|
||
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 number of command file
|
||
call setuser
|
||
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 dx,offset fcb
|
||
call closefile
|
||
mov bx,0
|
||
pop si
|
||
no_read:
|
||
mov al,dma[bx]
|
||
cmp al,1ah ;check for EOF
|
||
jz ret_eof
|
||
mov [si],al
|
||
inc bl
|
||
mov buf_ptr,bl ;point to next char in disk buffer
|
||
xor bx,bx
|
||
jmps read_ret
|
||
|
||
readerr:
|
||
pop si
|
||
ret_eof:
|
||
mov bx,0ffffh ;error or eof
|
||
;jmps read_ret
|
||
|
||
read_ret:
|
||
push bx ! mov dl,defuser ! call setuser ! pop bx
|
||
ret
|
||
|
||
;*****************************************************
|
||
;*
|
||
;* SUBROUTINES
|
||
;*
|
||
;*****************************************************
|
||
|
||
printcmdline: ;SI = string to print, CX = length
|
||
test cx,cx ;print byte by byte
|
||
jz blank ;to include $ signs
|
||
moreecho:
|
||
lodsb
|
||
mov dl,al
|
||
push cx ! push si
|
||
call prchar
|
||
pop si ! pop cx
|
||
loop moreecho
|
||
blank:
|
||
ret
|
||
|
||
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
|
||
|
||
terminate: xor dx,dx ! mov cx,dx ! jmps mpm1
|
||
charin: mov cl,mpm_conin ! jmps mpm1
|
||
prchar: mov cl,mpm_conout ! jmps mpm1
|
||
getuser: mov dl,0ffh
|
||
setuser: mov cl,mpm_usercode ! jmps mpm1
|
||
crlf: mov dx,offset crlfstr
|
||
;jmp printstring
|
||
print_string: push ds ! mov ax,cs ! mov ds,ax
|
||
call print_ds_string ! pop ds ! ret
|
||
print_ds_string:
|
||
push es ! push ds ! pop es
|
||
mov si,dx
|
||
mov di,dx
|
||
mov cx,0FFFFH
|
||
mask:
|
||
lodsb
|
||
and al,07FH ;mask parity
|
||
stosb
|
||
cmp al, '$' ! je print_it
|
||
loop mask
|
||
print_it:
|
||
pop es
|
||
mov cl,mpm_conwrite ! jmps mpm1
|
||
getconsole: mov cl,mpm_getdefcon ! jmps mpm1
|
||
setconsole: mov cl,mpm_setdefcon ! jmps mpm1
|
||
setdisk: mov cl,mpm_diskselect ! jmps mpm1
|
||
getdisk: mov cl,mpm_getdefdisk ! jmps mpm1
|
||
setlist: mov cl,mpm_setdeflst ! jmps mpm1
|
||
getlist: mov cl,mpm_getdeflst ! jmps mpm1
|
||
attach: mov cl,mpm_conattach ! jmps mpm1
|
||
detach: mov cl,mpm_condetach ! jmps mpm1
|
||
conread: mov cl,mpm_conread ! jmps mpm1
|
||
openfile: mov cl,mpm_openfile ! jmps mpm1
|
||
closefile: mov cl,mpm_closefile ! jmps mpm1
|
||
readfile: mov cl,mpm_readfile ;!; jmps mpm1
|
||
mpm1:
|
||
jmp mpm
|
||
|
||
|
||
;*****************************************************
|
||
;*
|
||
;* CODE DATA AREA - can be shared
|
||
;*
|
||
;*****************************************************
|
||
|
||
clierrtab dw e_nullcmd, 0 ;null command
|
||
dw e_no_memory, memerr ;No memory
|
||
dw e_no_pd, pderr ;No unused PD
|
||
dw e_badfname, fnameerr;Ill. command
|
||
dw e_illdisk, fnameerr;Ill. disk
|
||
dw e_ill_passwd, fnameerr;Ill. password
|
||
dw e_badftype, fnameerr;Ill. type
|
||
dw e_bad_load, loaderr ;
|
||
dw e_bad_read, loaderr ;
|
||
dw e_bad_open, openerr ;
|
||
dw e_q_full, qfullerr;
|
||
dw e_abort, aborterr;
|
||
|
||
; a few extra entries for future errors
|
||
|
||
dw 0ffffh, catcherr;
|
||
dw 0ffffh, catcherr;
|
||
dw 0ffffh, catcherr;
|
||
dw 0ffffh, catcherr;
|
||
|
||
; MESSAGES
|
||
|
||
wrongvers db 'Requires CCP/M-86 or MP/M-86'
|
||
crlfstr db 10,13,'$'
|
||
|
||
usererrmsg db 13,10,'Invalid User Number',13,10,'$'
|
||
usermsg db 'User Number = $'
|
||
printererrmsg db 13,10,'Invalid Printer Number',13,10,'$'
|
||
printermsg db 'Printer Number = $'
|
||
includerrmsg db 13,10,'Include Error$'
|
||
includemsg db '(submit)',10,13,'$'
|
||
globalmsg db 'Global mode ON',13,10,10,'$'
|
||
localmsg db 'Global mode OFF',13,10,10,'$'
|
||
abortstr db 'SUBMIT can not continue',13,10,'$'
|
||
|
||
errstr db 'CP/M Error: $'
|
||
memerr db 'Not Enough Memory$'
|
||
pderr db 'PD Table Full$'
|
||
fnameerr db 'Bad File Spec$'
|
||
catcherr db 'Unknown CLI Error$' ;we should never print
|
||
;this error, it means
|
||
;we have added CLI
|
||
;error returns and
|
||
;have not updated SUBMIT
|
||
loaderr db 'Load Error$'
|
||
openerr db 'Can''t Find Command$'
|
||
qfullerr db 'RSP Command Que Full$'
|
||
aborterr db 'CLI Abort$'
|
||
drverr db 'Invalid Drive$'
|
||
cmdstr db 'Command = $'
|
||
|
||
sopen_err db 'No ''SUB'' File Present',10,13, '$'
|
||
|
||
|
||
;*****************************************************
|
||
;*
|
||
;* Data Area - separate per invokation of SUBMIT
|
||
;*
|
||
;*****************************************************
|
||
|
||
dseg
|
||
org 05cH
|
||
|
||
fcb rb 32
|
||
cr db 0 ;current record
|
||
r0 rw 0
|
||
r2 rb 0
|
||
|
||
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
|
||
|
||
no_more_cmds db false ;set to true when EOF is
|
||
;found
|
||
lcmdbuf rb 1
|
||
lblen rb 1 ;read from disk to here,
|
||
lcmd rb maxcmdlen + 1 ;copy this to CMD
|
||
|
||
cmdbuf rb 1 ;current cmd goes here
|
||
blen rb 1
|
||
cmd rb maxcmdlen + 1 ;copy w/ expanded args to CLICMD
|
||
|
||
clicb rb 0 ;cmd w/ expanded args goes here
|
||
clicb_net db 0
|
||
clicmd rb maxcmdlen+1
|
||
clicmdlen dw 0
|
||
|
||
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
|
||
parent_offset rw 1 ;parents pd address
|
||
fix_parent db false ;local/global mode
|
||
|
||
usercmd db 'USER '
|
||
printercmd db 'PRINTER '
|
||
includecmd db '$INCLUDE'
|
||
globalcmd db '$GLOBAL '
|
||
localcmd db '$LOCAL '
|
||
|
||
end
|
||
|