Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

View File

@@ -0,0 +1,429 @@
;*************************************************************
;*
;* Terminate and Abort Specify Process Entry Points
;*
;* (D.H - July 1981)
;*
;*************************************************************
;============== ==============
sysreset_entry: ; System Reset
;============== ==============
sub dx,dx
; jmp terminate_entry
;=============== ===============================
terminate_entry: ; Terminate - DX=terminate code
;=============== ===============================
; This entry point is used for a process to terminate itself. The
; code from the label 'TERMINATE:' on, is also used by a process to be
; terminated when it comes back into context, as set up by
; abort specified process.
mov bx,rlr
call abt_chk
cmp cx,0 ! jle term_err
terminate: pushf ! cli
mov bx,(offset thrdrt)-p_thread
mov ax,rlr
nchld: mov bx,p_thread[bx]
cmp bx,0 ! je nochld
cmp p_parent[bx],ax ! jne nchld
mov p_parent[bx],0 ! jmps nchld
nochld: mov bx,ax
test p_flag[bx],pf_ctlc ! jz term_r1
and p_flag[bx],not pf_ctlc
mov bx,p_parent[bx]
cmp bx,0 ! je term_r1
or p_flag[bx],pf_childabort
term_r1: popf
mov si,rlr ! call rlsmx
mov u_error_mode,0feh
mov cx,f_bdosterm ! call mpmif
mov dx,offset mxmemqpb ! mov cx,f_qread
call mpmif
mov bx,rlr
mov mxmemowner,bx
mov mxmemcount,1
mov p_stat[bx],ps_term
jmp dsptch
term_err:
jcxz term_err1
sub bx,bx ! mov cx,bx ! ret
term_err1:
mov cx,e_pd_noterm
mov bx,0ffffh ! ret
; end of terminate entry point
;================
abort_spec_entry: ;Abort the specified process
;================
; Set up the specified PD for termination when it is next in context.
; If the running PD is the same as the PD to abort, we can just use
; the terminate entry point. Otherwise we use the Abort Parameter Block
; to find it. If it cannot be found, name and console must both match,
; return failure. If the keep flag is on, return failure.
; If the conditional terminate byte is not 0FFH
; (low byte of passed parameter) - meaning conditional
; termination - and the system flag is on in the PD to be aborted, then fail.
; The PD is taken off the list it is attached to via its link field.
; Its u_dparam is set to the termination code, its priority is made the
; best possible and the address of abort_code: is pushed on its UDA stack.
; Abort_code: is shared by the terminate entry point.
;
; Input: DX = address of APB in the caller's u_wrkseg
; Output: BX = 0 if success, 0FFFFH if failure
; CX = 0 " " , err code if failure
push ds ! mov ds,u_wrkseg
mov si,dx ! mov bx,apb_pd[si] ; get PD adr to abort
mov cx,apb_term[si] ; get termination/memfree code
mov ah,apb_cns[si] ; console from APB
pop ds
push cx ; save termination code
test bx,bx ! jz abt_findit ; got a PD ID, but not verified
call find_pdthrd ; find it on thread
jcxz abt_err
jmps abt_foundpd
abt_findit:
add dx,offset apb_pdname ; get adr of named PD
mov bx,offset thrdrt - p_thread ; find it on thread
call findpdnc ; look for PD name and console match
jcxz abt_err
abt_foundpd:
cmp bx,rlr ; BX has verified PD address to abort
jnz abt_notus
pop dx ; put term code in dx
jmp terminate_entry ; we are the PD to abort
abt_notus:
call abt_chk ; ok to abort this PD ?
pop dx ; if error - balance stack
cmp cx,0 ! jle term_err ; in terminate entry point
push dx
mov dl,p_stat[bx] ; call abort function based on status
mov dh,0 ! mov di,dx
pop dx ! push dx
add di,di
pushf ! cli
call cs:abort_tab[di] ; find via p_link and take PD of its list
popf ; allow interrupts
jcxz abt_err ; couldn't find PD, if several processes
; are attempting an abort of the same
; process, only one of the abort calls
; will find it
; PD is only on thread list - can't come back into context
; until put on drl. It is safe to fiddle with its priority
; and stack
pop dx ; recall termination code
mov p_prior[bx],abt_prior
and p_flag[bx],not pf_ctlc
push es ; set to low priority
mov es,p_uda[bx] ; uda of PD being aborted
mov si,(ulen-2)
mov u_sp,si
mov u_ss,es
mov u_inint,false
mov es:[si],offset terminate ; terminate code
mov u_dparam,dx ; put in terminate code
pop es ; restore calling PD's UDA
call abt_putdrl ; PD will now terminate itself when next
; in context
xor cx,cx ; indicate sucess
mov bx,cx
jmp pdisp ; force abort to happen before we return
; Error exits for abort routines
abt_tab_err: ; if we can't find PD a status function,
pop dx ! popf ; throw out return adr, restore flags.
abt_err: ; if error from above
pop dx ; throw out termination code
mov cx,e_no_pdname ; one kind of error returned
mov bx,0ffffh
ret
; The folowing are the abort handlers for a specific PD status.
; These labels are entered in the abort_tab(le) in the RTM data area.
; Interrupts assumed off.
; For all of the following:
; input: BX = PD addr to be aborted
; AH = cons
; output: return if success
; else a jump abort_tab_err:
;
; abort_specified process jump table
;
; Status
abort_tab dw abtrun ; 0 = ready list root
dw abtpol ; 1 = poll
dw abtdly ; 2 = delay
dw abtswp ; 3 = swap
dw abtrun ; 4 = term
dw abtrun ; 5 = sleep
dw abtdq ; 6 = dq
dw abtnq ; 7 = nq
dw abtflg ; 8 = flagwait
dw abtcns ; 9 = ciowait
abt_tablen equ offset $ - offset abort_tab
abtrun:
;-------
; On ready list root or dispatcher ready list
mov di,(offset rlr) - p_link
call find_pd
jcxz abtr_drl
jmps snip_it
abtr_drl: ; wasn't on rlr, try drl
mov di,(offset drl) - plink
jmps abt_common
abtdq:
;------
; On a dq list
xor al,al ; arg to find_pdq: to look on DQ lists
jmps abtq_common
abtnq:
;-------
; On an nq list
mov al,0ffh ; to look on NQ lists
abtq_common:
call find_pdq
jcxz abt_tab_err
jmps snip_it ; BX,SI = PD;DI = last link
; BP = adr of nq or dq root
abtpol:
;------
mov di,offset plr - p_link
jmps abt_common
abtflg:
;-------
call fflgpd ; Find flag we are waiting on
jcxz abt_tab_err
inc flg_ignore[di]
mov flg_pd[di],flag_off
ret
abtdly:
;------
mov di,offset dlr - p_link
call find_pd
jcxz abt_tab_err
mov si,p_link[si] ; Fix wait field in next PD on dlr
test si,si
jz ad_nofix ; Are there more PDs after the one
mov dx,p_wait[si] ; being aborted on the DLR ?
add dx,p_wait[bx] ; Add wait of aborting PD
mov p_wait[si],dx ; New value in next PD on dlr
ad_nofix:
jmps snip_it
abtswp:
;----
mov di,offset slr - p_link
jmps abt_common
abtcns:
;------
mov al,p_cns[bx] ; Assume legal cns #
call gccba
lea di,(c_queue-p_link)[si] ; offset of root - p_link
call findpd ! jcxz abtlst
jmps snipit
abtlst: mov al,p_lst[bx]
call gccba
lea di,(c_queue-p_link)[si]
jmps abt_common
gccba: ; get ccb address - AL=cio index
xor ah,ah ! mov cx,ccblen
mul cx ; figure offset for this console
mov si,ax
add si,ccb ; add base of ccb table
ret
abtdrl:
;------
mov di,(offset drl) - p_link
;jmps abt_common
abt_common:
;----------
call find_pd ! jcxz aterr1
jmps snip_it
aterr1: jmp abt_tab_err
snip_it:
;-------
; Take PD out of linked list of PDs
; input: BX = PD being sniped out
; DI = offset of previous PD or offset of root - p_link.
mov dx,p_link[bx] ; DX = next link
mov p_link[di],dx
ret
;
; End of abort_tab(le) functions
;
abt_putdrl:
;-------
; Puts PD on DRL
; Input: BX = PD to insert
pushf ! cli
mov dx,drl
mov p_link[bx],dx
mov drl,bx
popf ! ret
; Utility routines for abort entry point
findpdnc:
;--------
; Find PD by name and console, via thread list.
; input: BX = offset of thread list root - p_thread
; DX = adr of name in u_wrkseg
; AH = console number
; output: BX = PD
; CX = 0 failure
pushf ! cli ! xor cx,cx
nxt_pdname:
push ax ! call findpdname_entry ! pop ax
jcxz fnc_found_one ; CX = 0 is success from findpdname
xor cx,cx ! popf
ret ; CX = 0 is failure from this routine
fnc_found_one: ; found PD w/ same name
cmp p_cns[bx],ah ; chk for same console #
jnz nxt_pdname
inc cx ! popf ! ret ; success
findpdq:
;-------
; find the queue list a PD is on
; input: BX = PD address
; AL = ff if looking on NQ, 0 if on DQ lists
; output: DI = previous link,p_link[DI] = BX
; SI = BX = PD address
; CX = 0 if failure
xor cx,cx
mov di,(offset qlr) - q_link
push di
fpdq_nxtq: ; DI is QD currently scanning
pop di ; Recall QD adr
mov di,q_link[di] ; Next QD adr
test di,di ; End of queues ?
jz fpdq_no_pd
test al,al ; DQ or NQ ?
jz fpdq_dq_lst
lea di,(q_nq-p_link)[di]
jmps fpdq_nxt_pd
fpdq_dq_lst:
lea di,(q_dq-p_link)[di] ; root address of list to search
fpdq_nxt_pd:
push di ; Save QD adr
call find_pd
jcxz fpdq_nxt_q ; PD not in this QD, try next QD
pop dx ; Clean stack
fpdq_no_pd: ; find_pd returns non-zero CX if found
ret
find_pdthrd:
; Find PD on thread list
; input: BX = PD address we want
; output: CX = 0 if not found
pushf ! cli
xor cx,cx
mov di,offset thrdrt - p_thread
fp_next:
mov di,p_thread[di]
test di,di
jz fp_err
cmp bx,di
jne fp_next
inc cx
fp_err:
popf ! ret
find_pd:
; Find PD on linked list of PDs. Interrupts are assumed off
; input: BX = PD address
; DI = offset of list root - p_link
; output: BX = SI = PD address
; DI = Previous PD
; CX = 0 if failure
mov si,p_link[di]
xor cx,cx
fpd_nxt_pd:
test si,si ; SI could be zero to start
jz fpd_not_found
cmp si,bx ; Are addresses the same ?
jz fpd_found
fpd_nxt_lnk:
mov di,si ; Save previous link
mov si,p_link[si]
jmps fpd_nxt_pd
fpd_found:
inc cx
fpd_not_found:
ret
fflgpd:
;-----
; Find offset into flag table of flag waiting PD
; input: BX = PD
; output: DI = offset in RTM data of flag
; CX = 0 if failure
mov cl,nflags
xor ch,ch
mov di,flags
ffp_nxt_flg:
cmp bx,flg_pd[di] ; assume legal flag
jz ffp_pdfound
add di,flglen
loop ffp_nxt_flg
ffp_pdfound:
ret ; CX is 0 at end of loop instr
; CX <> 0 if found
; end of abort specified process code
abt_chk:
;-------
; Check flags and termination code for abort,termination
; Input: BX = PD to possibly abort
; DX = termination code
; Output: CX = 00000H if NOT ok to abort
; 00001H IF OK TO ABORT
; 0FFFFH IF tempkeep
sub cx,cx ! mov ax,p_flag[bx]
test ax,pf_keep ! jnz ac_n ;KEEP=ctlc off,no abort
test ax,pf_tempkeep ! jnz ac_tk ;TEMPKEEP=ctlc on,no abort
test ax,pf_sys ! jz ac_y ;not SYS=abort
cmp dl,0ffh ! jne ac_n ;SYS and FF=abort,else no abort
ac_y: inc cx ! ret
ac_tk: or p_flag[bx],pf_ctlc ! dec cx ! ret
ac_n: and p_flag[bx],not pf_ctlc ! ret


View File

@@ -0,0 +1,52 @@
;
; GENERATE SUP.MPM
;
a86 sup
gencmd sup
era sup.mpm
ren sup.mpm=sup.cmd
vax sup.lst $$atn
xref86 sup
vax sup.xrf $$atn
;
; GENERATE RTM.MPM
;
a86 rtm
gencmd rtm
era rtm.mpm
ren rtm.mpm=rtm.cmd
vax rtm.lst $$atn
xref86 rtm
vax rtm.xrf $$atn
;
; GENERATE MEM.MPM
;
a86 mem
gencmd mem
era mem.mpm
ren mem.mpm=mem.cmd
vax mem.lst $$atn
xref86 mem
vax mem.xrf $$atn
;
; GENERATE CIO.MPM
;
a86 cio
gencmd cio
era cio.mpm
ren cio.mpm=cio.cmd
vax cio.lst $$atn
xref86 cio
vax cio.xrf $$atn
;
; GENERATE SYSDAT.MPM
;
a86 sysdat
gencmd sysdat
era sysdat.mpm
ren sysdat.mpm=sysdat.cmd
vax sysdat.lst $$atn
xref86 sysdat
vax sysdat.xrf $$atn
;


View File

@@ -0,0 +1,15 @@
abt_prior equ 32
;*************************************************************
;*
;* Abort Parameter Block
;*
;*************************************************************
apb_pd equ word ptr 0
apb_term equ word ptr apb_pd + word
apb_cns equ byte ptr apb_term + word
apb_net equ byte ptr apb_cns + byte
apb_pdname equ byte ptr apb_net + byte
apb_len equ apb_pdname + pnamsiz


Binary file not shown.

View File

@@ -0,0 +1,178 @@
title 'Clock process'
;*****************************************************
;*
;* CLOCK RSP
;*
;* The clock process will update the MP/M-86 Time of
;* Day structure each time it returns from waiting for
;* the 'Second' System Flag (Flag 2). When the minute
;* is updated, the 'minute' flag is set (Flag 3).
;*
;*****************************************************
; MPM functions
mpmint equ 224 ; mpm entry interrupt
mpm_flagw equ 132 ; flagwait
mpm_flags equ 133 ; flagset
mpm_tod equ 155 ; get tod address
tod_offset equ 07Eh
sec_flag equ 2
min_flag equ 3
; TOD format
tod_day equ word ptr 0
tod_hour equ byte ptr 2
tod_min equ byte ptr 3
tod_sec equ byte ptr 4
; PD fields
pdlen equ 48 ; length of process descriptor
ps_run equ 0 ; PD run status
pf_keep equ 2 ; PD nokill flag
; RSP format
rsp_top equ 0 ; rsp offset
rsp_pd equ 010h ; PD offset
rsp_uda equ 040h ; UDA offset
rsp_bottom equ 140h ; end rsp header
;*****************************************************
;*
;* CLOCK CODE SEGMENT
;*
;*****************************************************
cseg
org 0
mpm: int mpmint ! ret
clock: ; Clock process starts here
mov ds,sysdat
mov bx,tod_offset
; Loop forever
clockloop:
; BX -> TOD structure in SYSDAT
; Wait for Seconds Flag
mov cx,mpm_flagw ! mov dx,sec_flag
push bx ! call mpm ! pop bx
; increment seconds
clc
mov al,tod_sec[bx]
inc al ! daa ! mov tod_sec[bx],al
; check for minute mark
cmp al,60h ! jae update_min
jmp clock_loop
update_min:
; set minute flag
mov tod_sec[bx],0
mov cx,mpm_flags ! mov dx,min_flag
push bx ! call mpm ! pop bx
; increment minute field of TOD
clc ! mov al,tod_min[bx]
inc al ! daa ! mov tod_min[bx],al
; check if hour
cmp al,60h ! jae update_hour
jmp clock_loop
update_hour:
;update hour field
mov tod_min[bx],0
clc ! mov al,tod_hour[bx]
inc al ! daa ! mov tod_hour[bx],al
; check for day
cmp al,24h ! jae update_day
jmp clock_loop
update_day:
; update Day field
mov tod_hour[bx],0
inc tod_day[bx]
jmp clock_loop ; loop forever
;*****************************************************
;*
;* Data Segment
;*
;*****************************************************
dseg
org 0
sysdat dw 0,0,0
dw 0,0,0
dw 0,0
org rsp_pd
dw 0,0 ; link,thread
db ps_run ; status
db 190 ; priority
dw pf_keep ; flags
db 'CLOCK ' ; name
dw offset uda/10h ; uda seg
db 0,0,0,0 ; dsk,usr,ldsk,luser
dw 0 ; mem partitions
dw 0,0 ; dvract,wait
db 0,0 ; org,net
dw 0 ; parent
db 0,0,0,0 ; cns,abort,cin,cout
db 0,0,0,0 ; lst,sf3,sf4,sf5
dw 0,0,0,0 ; reserved,pret,scratch
org rsp_uda
uda dw 0,offset dma,0,0 ;0
dw 0,0,0,0
dw 0,0,0,0 ;10
dw 0,0,0,0
dw 0,0,0,0 ;20
dw 0,0,0,0
dw 0,0,offset stack_tos,0 ;30
dw 0,0,0,0
dw 0,0,0,0 ;40
dw 0,0,0,0
dw 0,0,0,0 ;50
dw 0,0,0,0
dw 0,0,0,0 ;60
dw 0,0,0,0
org rsp_bottom
dma rb 128
stack dw 0CCCCH,0CCCCH,0CCCCH
dw 0CCCCH,0CCCCH,0CCCCH
dw 0CCCCH,0CCCCH,0CCCCH
dw 0CCCCH,0CCCCH,0CCCCH
dw 0CCCCH,0CCCCH,0CCCCH
stack_tos dw offset clock ; offset
dw 0 ; segment
dw 0 ; flags
dw 0 ; END OF DATA
;
end

View File

@@ -0,0 +1,599 @@
;*****************************************************
;*
;* Command Line Interpreter, Program Chain
;*
;*****************************************************
;===========
chain_entry:
;===========
sub dx,dx
;============
clicmd_entry:
;============
; Create a process based on an Ascii Command Line.
; The command Line is first parsed and an FCB is
; initialized as a result.
; An attempt is made to open a queue with the filename
; of the FCB. If this succeeds, The default console
; is assigned to a process by the same name.
; The commandtail is then written to the queue and
; the we exit (even if assign fails).
; If there is a failure, We make the type name in the
; FCB to be 'CMD' and open the file. If this fails,
; so do we.
; We then obtain a Process Descriptor from the
; PD table. Again we fail if it does.
; On a successful open, we call the BDOS load function.
; If the load fails, so do we. The PD is
; initialized, the default console is assigned to the
; PD and a create process call is made.
;
; input: DX -> command buffer in u_wrkseg
; It is assumed that the calling process
; is attached to its default console
; and is willing to lose it since it
; will be handed to the newly created
; process.
; if DX = 0, assume chain w/command in DMA
;
; output: BX = 0 if successful
; = 0ffffh if failure has occured
; CX = error code
push dx ! call mxread ! pop dx
mov bx,rlr ! mov ax,p_flag[bx]
mov cli_pflag,ax
and ax,not pf_keep ! or ax,pf_tempkeep
mov p_flag[bx],ax
; we have MXcli queue.
; Check for Chain
mov cli_chain,false
cmp dx,0 ! jne cli_cli
mov cli_chain,true
mov cli_term,false
cli_cli:
; initialize defaults from parent PD
mov cli_dfil,false
cmp dayfile,0ffh ! jne nodf
push dx ! mov cx,f_cconattch
call mpmif ! pop dx
cmp cx,0 ! jne nodf
mov cli_dfil,true
push dx
call prtime
pop dx
nodf: mov bx,rlr
mov cli_ppd,bx
mov cl,p_dsk[bx]
mov cli_dsk,cl
mov cl,p_user[bx]
mov cli_user,cl
mov cl,p_cns[bx]
mov cli_cns,cl
mov cl,u_error_mode
mov cli_err_mode,cl
mov cx,u_dma_ofst
mov cli_dma_ofst,cx
mov cx,u_dma_seg
mov cli_dma_seg,cx
mov clierr,0
; copy command into local area
cmp cli_chain,true ! jne cli_copy
push es ! push ds
mov es,sysdat
mov si,cli_dma_ofst
mov di,offset cli_cmdtail
mov ds,cli_dma_seg
mov cx,040H
rep movsw
pop ds ! pop es
jmp cli_parse
cli_copy:
push es ! push ds
mov ds,u_wrkseg ! pop es
; DS=Wrkseg, ES=Sysdat, SP->UDA
; copy clicb_net
mov si,dx ! mov di,offset cli_net
movsb
; copy command
mov si,dx ! add si,clicb_cmd
mov di,offset cli_cmdtail
mov cx,clicblen-clicb_cmd
rep movsb
push es ! pop ds ! pop es
;parse the command
cli_parse:
call pfn ! jcxz cli_goodparse
mov clierr,cx
jmp cli_exit
cli_goodparse:
call shifttail
;fcb has parsed filename
;if not explicit disk then
; if not RSP try CMD
;else try CMD
cmp cli_fcb,0 ! jne cli_ffload
mov bx,(offset cli_fcb)
cmp fcb_plen[bx],0 ! jne cli_ffload
call cli_checkque ! jnz cli_ffload
;successful RSP access
cli_qful:
cmp cli_chain,true ! jne cli_exit2
mov cli_term,true
cli_exit2: jmp cli_exit
cli_ffload:
cmp cx,e_q_full ! jne cli_fload
mov clierr,cx ! jmps cli_qful
cli_checkque:
;------------
; output: z flag on if successful
;copy fcb.name to qpb.name
mov si,(offset cli_fcb)+fcb_name
mov di,(offset cli_cuspqpb)+qpb_name
mov cx,qnamsiz/2 ! push es ! push ds ! pop es
push si ! rep movsw
;copy fcb.name to acb.name
pop si ! mov cx,qnamsiz/2
mov di,(offset cli_acb)+acb_name
rep movsw ! pop es
;open queue
mov cx,f_qopen ! mov dx,(offset cli_cuspqpb)
call mpmif ! jcxz cli_goodq
retcli1: cmp cx,0 ! ret
;we successfully opened the queue
;check for process by assign console
cli_goodq:
mov bx,offset cli_cuspqpb
mov bx,qpb_qaddr[bx]
test q_flags[bx],qf_rsp ! jnz cli_gq
mov cx,e_no_queue ! jmps retcli1
;write command tail to queue
cli_gq: mov cx,f_cqwrite ! mov dx,offset cli_cuspqpb
call mpmif ! jcxz cli_qw
mov cx,e_q_full ! jmps retcli1
;successful queue write, assign console
cli_qw: cmp cli_dfil,true ! jne noqm
call prcusp
noqm: mov bx,offset cli_acb
mov al,cli_cns ! mov acb_cns[bx],al
mov acb_match[bx],false
mov acb_pd[bx],0
call conasn ! sub cx,cx ! ret
cli_fload:
;---------
; Try to Load a file for execution
; The Command Line Parsed correctly and we have an FCB
; set up. We already know there isn't a queue and a
; process by the same name as the command.
; Obtain a Process Descriptor
pushf ! cli ! mov bx,pul
cmp bx,0 ! jne cli_gpd
popf ! mov clierr,e_no_pd
jmp cli_exit
cli_gpd:
mov si,p_link[bx] ! mov pul,si
popf ! mov cli_pd,bx
; zero PD
push es ! push ds ! pop es
mov di,bx ! mov cx,pdlen/2
sub ax,ax ! rep stosw
pop es
; Initialize the PD for Load
mov al,cli_fcb
mov cli_lddsk,al
mov bx,cli_pd
mov p_flag[bx],pf_table
mov di,bx ! add di,p_name
mov si,offset cli_fcb ! add si,fcb_name
push es ! mov ax,ds ! mov es,ax
mov cx,pnamsiz/2 ! rep movsw
pop es
mov si,rlr
mov al,cli_dsk ! mov p_dsk[bx],al
mov al,cli_user ! mov p_user[bx],al
mov al,cli_cns ! mov p_cns[bx],al
mov al,p_lst[si] ! sub al,ncondev
mov p_lst[bx],al
; 3. Open the file
mov si,(offset cli_fcb)+fcb_dskmap
mov di,offset cli_dma
push es ! mov es,sysdat
mov cx,4 ! rep movsw
pop es
mov u_dma_ofst,offset cli_dma
mov u_dma_seg,ds
mov si,offset cli_fcb
mov byte ptr fcb_type[si],'C'
mov byte ptr fcb_type+1[si],'M'
mov byte ptr fcb_type+2[si],'D'
; Open the CMD file
mov u_error_mode,0feh
call fileopen
cmp bl,0ffh ! jne cli_gopen
; on failure,
; if default is not system disk
; and not an explicit disk then
; try CMD file on System disk
cmp bh,0 ! jne cli_bopen ;extended error
mov cl,srchdisk
cmp cl,cli_dsk ! je cli_bopen
cmp cli_fcb,0 ! jne cli_bopen
; try system disk
mov bx,rlr
mov p_dsk[bx],cl
call fileopen
cmp bl,0ffh ! je cli_bopen
;make sure SYS attribute is on...
mov bx,offset cli_fcb
test byte ptr fcb_type+1[bx],080h ! jnz cli_gopen
;We opened a NON-SYS file. Do explicit open
;on user zero if not already
call fileclose
mov bx,rlr
cmp p_user[bx],0 ! je cli_bopene
mov p_user[bx],0
call fileopen
cmp bl,0ffh ! je cli_bopen
mov bx,offset cli_fcb
test byte ptr fcb_type+1[bx],080h
jnz cli_gopen
call fileclose
jmps cli_bopene
;could not find CMD file
cli_bopen: cmp bh,0 ! jne cli_rmpd2
cli_bopene: mov clierr,e_bad_open
cli_rmpd2: jmp cli_rmpd
cli_gopen:
; 8. Call the load function
mov bx,rlr
test p_flag[bx],pf_ctlc ! jz cli_ld1
mov bx,0ffffh ! mov cx,e_abort
jmp cli_cl
cli_ld1:
cmp cli_chain,true ! jne cli_kuda
mov bx,cli_pd
mov p_uda[bx],es
mov ax,offset inituda
mov cl,4 ! shr ax,cl
add ax,sysdat
mov bx,es ! mov es,ax ! mov di,0
mov ds,bx ! mov si,di
mov cx,ulen/2
rep movsw
pushf ! cli ! pop dx
mov ax,es
mov ds,sysdat
mov ss,ax
mov bx,rlr
mov p_uda[bx],ax
push dx ! popf
cli_kuda:
cmp cli_dfil,true ! jne noprfil
call prfilnam
noprfil:mov bx,cli_pd
mov dx,offset cli_fcb
mov cx,f_load
cmp cli_chain,true ! jne cli_ld
mov cli_term,true
mov cx,f_cload
cli_ld: call mpmif
cli_cl: push bx ! push cx
mov u_error_mode,0
call fileclose
pop cx ! pop bx
jcxz cli_gload
cmp cx,e_abort ! jne cli_lnab
jmp cli_rmpd
cli_lnab: mov clierr,cx
jmp cli_rmpd
cli_gload:
mov cli_bpage,bx
; 9a. Parse Command Tail
; copy cmdtail to user DMA buffer
push es ! mov es,cli_bpage
mov di,offset bpg_dma+1
mov si,offset cli_cmdtail
mov cx,127
rep movsb ! pop es
; count cmd length and convert
; to upper case
push ds ! mov ds,cli_bpage
mov cl,0 ! mov di,offset bpg_dma+1
ncmdchar:
cmp byte ptr [di],0 ! je endtail
cmp byte ptr [di],'a' ! jb nlow
cmp byte ptr [di],'z' ! ja nlow
and byte ptr [di],05fh
nlow: inc di ! inc cl ! jmps ncmdchar
endtail:
mov bpg_dma,cl ! pop ds
; init default fcb
push es ! mov es,cli_bpage
mov al,cli_lddsk
mov es:bpg_lddsk,al
mov di,offset bpg_fcb0
sub ax,ax ! stosb ;default disk
mov al,' '
mov cx,11 ! rep stosb ;name,type
sub ax,ax
mov cx,2 ! rep stosw ;other
push ds ! push es ! pop ds
mov si,offset bpg_fcb0
mov cx,8 ! rep movsw
pop ds ! pop es
; init load disk
; if cmdtail, parse
cmp cli_cmdtail,0 ! je cmdtaildone
call pfn
cmp bx,0ffffh ! je cmdtaildone
; copy fcb to user fcb front
push es ! mov es,cli_bpage
mov di,offset bpg_fcb0
mov si,offset cli_fcb
mov ax,fcb_pptr[si]
mov es:bpg_pw1ptr,ax
mov al,fcb_plen[si]
mov es:bpg_pw1len,al
mov cx,8 ! rep movsw ! pop es
; if more cmdtail, parse
cmp bx,0 ! je cmdtaildone
push cli_pcb ! inc bx
mov cli_pcb,bx
call pfn
pop cli_pcb
cmp bx,0ffffh ! je cmdtaildone
; copy 2nd fcb front
push es ! mov es,cli_bpage
mov di,offset bpg_fcb1
mov si,offset cli_fcb
mov ax,fcb_pptr[si]
mov es:bpg_pw2ptr,ax
mov al,fcb_plen[si]
mov es:bpg_pw2len,al
mov cx,8
rep movsw
pop es
cmdtaildone:
; 10. Create the process
cmp cli_chain,true ! jne noprior
mov cx,f_setprior
mov dx,1 ! call mpmif
noprior:
mov dx,cli_pd ! mov cx,f_createproc
call mpmif
; 11. Assign Console to new process
cmp cli_dfil,true ! jne nocrlf
call crlf
nocrlf: mov bx,offset cli_acb
mov al,cli_cns ! mov acb_cns[bx],al
mov ax,cli_pd ! mov acb_pd[bx],ax
mov acb_match[bx],true
call conasn
mov clierr,cx ! jmps cli_exit
; 12. All Done
cli_rmpd: ; release PD
pushf ! cli
mov bx,pul ! mov si,cli_pd
mov p_link[si],bx ! mov pul,si
popf
; Normal EXIT
cli_exit: ; close file and release MXCli queue
mov bx,rlr
mov cl,cli_dsk ! mov p_dsk[bx],cl
mov cl,cli_user ! mov p_user[bx],cl
mov cl,cli_err_mode ! mov u_error_mode,cl
mov cx,cli_dma_ofst ! mov u_dma_ofst,cx
mov cx,cli_dma_seg ! mov u_dma_seg,cx
cmp cli_chain,true ! jne clirls
cmp cli_term,true ! jne clirls
mov bx,rlr
and p_flag[bx],not (pf_keep+pf_sys+pf_tempkeep+pf_ctlc)
mov cx,f_terminate
jmp mpmif
clirls:
push cli_pflag
call mxwrite
pop ax ! and ax,pf_tempkeep+pf_keep
mov bx,rlr ! mov cx,p_flag[bx]
and cx,not pf_tempkeep+pf_keep
or cx,ax ! mov p_flag[bx],cx
test p_flag[bx],pf_ctlc ! jz cli_nctl
mov cx,f_terminate ! sub dx,dx
call mpmif
mov cli_err,e_abort
; setup error return if needed
cli_nctl:
mov cx,clierr ! sub bx,bx
jcxz cli_gexit
mov bx,0ffffh
cli_gexit:
ret
shifttail:
;---------
; setup command tail to be parsed
; input: AX = output of previous parsefilename
cmp ax,0 ! je cli_notail
;shift command tail to beginning
;of command buffer
push ax ! sub ax,offset cli_cmdtail
mov cx,128 ! sub cx,ax ! shr cx,1
pop si ! mov di,offset cli_cmdtail
push es ! push ds ! pop es
rep movsw ! pop es
ret
cli_notail:
mov cli_cmdtail,0
ret
crlf: mov dl,13 ! call prchar
mov dl,10
;jmps prchar
prchar: mov cx,f_conout ! jmp mpmif
prtime: mov dl,tod_hr ! call prnum
mov dl,':' ! call prchar
mov dl,tod_min ! call prnum
mov dl,':' ! call prchar
mov dl,tod_sec ! call prnum
mov dl,' ' ! jmps prchar
prnum: push dx ! mov cl,4
shr dl,cl ! add dl,'0'
call prchar
pop dx ! and dl,0fh
add dl,'0' ! jmps prchar
prfilnam:
call prdisk
mov dx,(offset cli_fcb)+fcb_name
call prnam
mov dl,'.' ! call prchar
mov dx,(offset cli_fcb) + fcb_type
call prtyp
mov dl,' ' ! call prchar
mov bx,offset cli_fcb
test byte ptr fcb_name+7[bx],080h ! jnz pruser
cmp cli_user,0 ! je pret
mov bx,rlr
cmp p_user[bx],0 ! je pruser
pret: ret
pruser: mov dx,offset userstr
jmps prcsm
prdisk: mov dl,cli_fcb
cmp dl,0 ! je prpddsk
dec dl ! jmps prdsk1
prpddsk:
mov bx,rlr
mov dl,p_dsk[bx]
prdsk1: add dl,'A' ! call prchar
mov dl,':' ! jmp prchar
prcusp: mov dx,(offset cli_cuspqpb) + qpb_name
call prnam ! mov dx,offset questr
call prcsm ! jmp crlf
prcsm: sub bx,bx ! push ds
mov ax,cs ! mov ds,ax
call cprnt ! pop ds ! ret
prtyp: mov bh,3 ! jmps prn1
prnam: mov bh,8
prn1: mov bl,' '
cprnt: mov cx,f_conprint ! jmps jmpm
fileclose:
mov cx,f_fclose ! mov dx,offset cli_fcb
jmps fo1
fileopen:
mov cx,f_fopen
mov si,offset cli_fcb
or byte ptr fcb_name+5[si],080h ;f6`=open read-only
mov dx,si
fo1: push es ! call mpmif ! pop es ! ret
mxwrite:mov cx,f_qwrite
jmps mxw1
mxread: mov cx,f_qread
mxw1: mov dx,offset mxcliqpb
jmpm: jmp mpmif
pfn: mov dx,offset cli_pcb ! mov cx,f_parsefilename
jmps jmpm
conasn: mov cx,f_conassign ! mov dx,offset cli_acb
jmps jmpm
questr db ' Msg Qued',0
userstr db '(User 0)',0
;=========
user_retf:
;=========
; If a user does a RETF expecting to go to CCP,
; The process ends here
mov bx,rlr
and p_flag[bx],not pf_keep+pf_tempkeep+pf_ctlc+pf_sys
mov cx,f_terminate ! sub dx,dx ! int mpmint


View File

@@ -0,0 +1,176 @@
;*****************************************************
;*
;* MEM Entry Points
;*
;*****************************************************
; Format of Memory Control Block used
; in CP/M-86 Memory Calls (53 - 58)
;
; +-----------+-----------+-----+
; MCB | Base | Length | ext |
; +-----------+-----------+-----+
;
mcb_base equ word ptr 0
mcb_length equ word ptr mcb_base + word
mcb_ext equ byte ptr mcb_length + word
mcblen equ mcb_ext + byte
;============ =====================
maxmem_entry: ; 53 - Get Max Memory
;============ =====================
; input: DX = address of MCB in u_wrkseg
; output: BX = 0ffffh if failure
; 0h if success
; CX = Error Code
; mcb_ext = 0 if no additional mem
; 1 if more available
mov si,dx
push ds ! mov ds,u_wrkseg
mov dx,mcb_length[si] ! pop ds
sub ax,ax ! mov bx,ax
call getmemory ! jcxz mm_gm
mov bx,0ffffh ! ret
mm_gm: push ds ! mov ds,u_wrkseg
mov mcb_length[si],dx
mov mcb_base[si],ax
mov mcb_ext[si],1
pop ds ! sub bx,bx ! ret
;============
absmax_entry: ; 54 - Get Abs Max Mem
;============
; Allocate the largest absolute memory region which
; is less than or equal mcb_length
; input: DX = address of MCB in u_wrkseg
; output: BX = 0ffffh if failure
; 0h if success
; CX = Error Code
mov si,dx
push ds ! mov ds,u_wrkseg
mov ax,mcb_base[si]
mov dx,mcb_length[si] ! pop ds
sub bx,bx
call getmemory ! jcxz am_gm
mov bx,0ffffh ! ret
am_gm: push ds ! mov ds,u_wrkseg
mov mcb_length[si],dx
mov mcb_base[si],ax
pop ds ! sub bx,bx ! ret
;==============
cpmalloc_entry: ; 55 - Alloc Mem
;==============
; Allocate a memory region which is equal to mcb_length
;
; input: DX = address of MCB in u_wrkseg
; output: BX = 0ffffh if failure
; 0h if success
; CX = Error Code
mov si,dx
push ds ! mov ds,u_wrkseg
sub ax,ax ! mov bx,mcb_length[si]
mov dx,bx ! pop ds
call getmemory ! jcxz ca_gm
mov bx,0ffffh ! ret
ca_gm: push ds ! mov ds,u_wrkseg
mov mcb_length[si],dx
mov mcb_base[si],ax
pop ds ! sub bx,bx ! ret
;=============
cpmabsa_entry: ; 56 - Alloc Abs Mem
;=============
; Allocate an absolut memory region which is
; equal to mcb_length
;
; input: DX = address of MCB in u_wrkseg
; output: BX = 0ffffh if failure
; 0h if success
; CX = Error Code
mov si,dx
push ds ! mov ds,u_wrkseg
mov ax,mcb_base[si]
mov bx,mcb_length[si]
mov dx,bx ! pop ds
call getmemory ! jcxz caa_gm
mov bx,0ffffh ! ret
caa_gm: push ds ! mov ds,u_wrkseg
mov mcb_length[si],dx
mov mcb_base[si],ax
pop ds ! sub bx,bx ! ret
getmemory:
;---------
; input: AX = start
; BX = min
; DX = max
; output: AX = start
; DX = length
; CX = error code
; preserve SI
push si
sub cx,cx ! push cx ! push cx ! push dx ! push bx
push ax ! mov dx,sp
push ds ! mov cx,ss ! mov ds,cx
mov cx,f_malloc ! call mpmif
pop ds ! pop ax ! pop dx ! pop bx ! pop bx ! pop bx
pop si ! ret
;=============
cpmfree_entry: ; 57 - Free Mem
;=============
; Free memory as specified in MCB
; input: DX = offset of MCB in u_wrkseg
; mcb_ext = 0ffh = free all but load mem
; else as specified by mcb_base.
; mcb_base = seg addr of memory segment
; to free. IF in middle of
; existing segment then just free
; the end of the segment.
push ds ! mov ds,u_wrkseg
mov si,dx
mov al,mcb_ext[si]
mov dx,mcb_base[si] ! pop ds
cmp al,0ffh ! jne free_memory
cpmf_root: mov bx,rlr
add bx,p_mem-ms_link
cpmf_next: mov si,ms_link[bx]
cmp si,0 ! jne try_seg
sub bx,bx ! mov cx,bx ! ret
try_seg: and ms_flags[si],mf_load ! jz free_seg
mov bx,si ! jmps cpmf_next
free_seg: mov dx,ms_start[si]
push si ! call free_memory ! pop si
jcxz cpmf_root
jmps cpmf_next
free_memory:
;-----------
; input: DX = start
; output: BX = 0,0ffffh (success,fail)
; CX = Error Code
push ds ! push ss ! pop ds
sub cx,cx ! push cx ! push dx
mov dx,sp
mov cx,f_memfree ! call mpmif
pop dx ! pop dx ! pop ds
ret
;=============
freeall_entry: ; 58 - Free All Mem
;=============
mov cx,f_terminate ! sub dx,dx
jmp mpmif


View File

@@ -0,0 +1,192 @@
;
; ECHO - Resident System Process
; Print Command tail to console
;
;
; DEFININTIONS
;
mpmint equ 224 ;mpm entry interrupt
mpm_conwrite equ 9 ;print string
mpm_qmake equ 134 ;create queue
mpm_qopen equ 135 ;open queue
mpm_qread equ 137 ;read queue
mpm_qwrite equ 139 ;write queue
mpm_setprior equ 145 ;set priority
mpm_condetach equ 147 ;detach console
mpm_setdefcon equ 148 ;set default console
pdlen equ 48 ;length of Process
; Descriptor
p_cns equ byte ptr 020h ;default cns
p_disk equ byte ptr 012h ;default disk
p_user equ byte ptr 013h ;default user
p_list equ byte ptr 024h ;default list
ps_run equ 0 ;PD run status
pf_keep equ 2 ;PD nokill flag
rsp_top equ 0 ;rsp offset
rsp_pd equ 010h ;PD offset
rsp_uda equ 040h ;UDA offset
rsp_bottom equ 140h ;end rsp header
qf_rsp equ 08h ;queue RSP flag
;
; CODE SEGMENT
;
CSEG
org 0
mpm: int mpmint
ret
main: ;create ECHO queue
mov cl,mpm_qmake ! mov dx,offset qd
call mpm
;open ECHO queue
mov cl,mpm_qopen ! mov dx,offset qpb
call mpm
;set priority to normal
mov cl,mpm_setprior ! mov dx,200
call mpm
;ES points to SYSDAT
mov es,sdatseg
loop: ;forever
;read cmdtail from queue
mov cl,mpm_qread ! mov dx,offset qpb
call mpm
;set default values from PD
mov bx,pdadr
; mov dl,es:p_disk[bx] ;p_disk=0-15
; inc dl ! mov disk,dl ;make disk=1-16
; mov dl,es:p_user[bx]
; mov user,dl
; mov dl,es:p_list[bx]
; mov list,dl
mov dl,es:p_cns[bx]
mov console,dl
;set default console
; mov dl,console
mov cl,mpm_setdefcon ! call mpm
;scan cmdtail and look for '$' or 0.
;when found, replace w/ cr,lf,'$'
lea bx,cmdtail ! mov al,'$' ! mov ah,0
mov dx,bx ! add dx,131
nextchar:
cmp bx,dx ! ja endcmd
cmp [bx],al ! je endcmd
cmp [bx],ah ! je endcmd
inc bx ! jmps nextchar
endcmd:
mov byte ptr [bx],13
mov byte ptr 1[bx],10
mov byte ptr 2[bx],'$'
;write command tail
lea dx,cmdtail ! mov cl,mpm_conwrite
call mpm
;detach console
mov dl,console
mov cl,mpm_condetach ! call mpm
;done, get next command
jmps loop
;
; DATA SEGMENT
;
DSEG
org rsp_top
sdatseg dw 0,0,0
dw 0,0,0
dw 0,0
org rsp_pd
pd dw 0,0 ; link,thread
db ps_run ; status
db 190 ; priority
dw pf_keep ; flags
db 'ECHO ' ; name
dw offset uda/10h ; uda seg
db 0,0 ; disk,user
db 0,0 ; load dsk,usr
dw 0 ; mem
dw 0,0 ; dvract,wait
db 0,0
dw 0
db 0 ; console
db 0,0,0
db 0 ; list
db 0,0,0
dw 0,0,0,0
org rsp_uda
uda dw 0,offset dma,0,0 ;0
dw 0,0,0,0
dw 0,0,0,0 ;10h
dw 0,0,0,0
dw 0,0,0,0 ;20h
dw 0,0,0,0
dw 0,0,offset stack_tos,0 ;30h
dw 0,0,0,0
dw 0,0,0,0 ;40h
dw 0,0,0,0
dw 0,0,0,0 ;50h
dw 0,0,0,0
dw 0,0,0,0 ;60h
org rsp_bottom
qbuf rb 131 ;Queue buffer
qd dw 0 ;link
db 0,0 ;net,org
dw qf_rsp ;flags
db 'ECHO ' ;name
dw 131 ;msglen
dw 1 ;nmsgs
dw 0,0 ;dq,nq
dw 0,0 ;msgcnt,msgout
dw offset qbuf ;buffer addr.
dma rb 128
stack dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
stack_tos dw offset main ; start offset
dw 0 ; start seg
dw 0 ; init flags
pdadr rw 1 ; QPB Buffer
cmdtail rb 129 ; starts here
db 13,10,'$'
qpb db 0,0 ;must be zero
dw 0 ;queue ID
dw 1 ;nmsgs
dw offset pdadr ;buffer addr.
db 'ECHO ' ;name to open
console db 0
;disk db 0
;user db 0
;list db 0
end


View File

@@ -0,0 +1,38 @@
;*****************************************************
;*
;* Find Process Descriptor
;*
;*****************************************************
;================ =================================
findpdname_entry: ; Find Process Descriptor by Name
;================ =================================
; find process by name in thread list
; input: DX->name in u_wrkseg
; BX->thread list root - p_thread
; output: BX=pd if found
; =0ffffh if not found
; CX=0 if found
; =e_no_pdname if not found
pushf ! cli
push es ! mov es,u_wrkseg
fpn_cmpname:
mov si,dx
mov bx,p_thread[bx]
cmp bx,0 ! je fpn_nomatch
mov cl,0
lea di,p_name[bx]
fpn_cmplet:
cmp cl,8 ! je fpn_found
mov al,es:[si] ! sub al,[di]
shl al,1 ! jnz fpn_cmpname
inc cl ! inc si ! inc di
jmps fpn_cmplet
fpn_found: mov cx,0 ! jmps fpn_exit
fpn_nomatch:
mov cx,e_no_pdname ! mov bx,0ffffh
fpn_exit:
pop es ! popf ! ret


View File

@@ -0,0 +1,116 @@
;*****************************************************
;*
;* MP/M-86 Supervisor Initialization
;*
;*****************************************************
cseg
org 0
jmp init ;system initialization
jmp entry ;intermodule entry pt.
sysdat dw 0 ;sysdat segment
supervisor dw entry ;Supervisor entry point
dw 0 ; (segment address)
db 'COPYRIGHT (C) 1981,'
db ' DIGITAL RESEARCH '
serial db '654321'
ver db 13,10,10
db 'MP/M-86 2.0 '
db '[5 Oct 81]'
db 13,10
db 'Copyright (C) 1981, Digital Research'
db 13,10,10,'$'
;====
init:
;====
; system initialization
; assume DS = Sysdat Segment
;
; set up stack,remember DSEG
mov ax,ds
mov ss,ax ! mov sp,offset (init_tos)
mov sysdat,ax
; set up supervisor entry point
mov bx,(offset supmod)+2 ! mov ax,[bx]
mov si,offset supervisor
mov cs:2[si],ax
mov version,offset ver
mov tick_tos,offset notick
mov idle_tos,offset idle
; set up mpm entry point
mov ax,ds ! sub bx,bx ! mov ds,bx
mov i_mpm_ip,offset user_entry
mov i_mpm_cs,cs
mov ds,ax
;initialize init uda
mov bx,offset initpd
mov ax,offset inituda
mov cl,4 ! shr ax,cl
add ax,sysdat ! mov p_uda[bx],ax
mov es,ax
mov u_wrkseg,ds
;initialize modules
mov bx,mod_init
push bx ! callf dword ptr rtmmod[bx] ! pop bx ; init RTM
push bx ! callf dword ptr memmod[bx] ! pop bx ; init MEM
test module_map,bdosmod_bit ! jz nbdom
push bx ! callf dword ptr bdosmod[bx] ! pop bx ; init BDOS
nbdom: test module_map,ciomod_bit ! jz nciom
push bx ! callf dword ptr ciomod[bx] ! pop bx ; init CIO
nciom: test module_map,xiosmod_bit ! jz nxiom
push ds ! push es
callf dword ptr xiosmod[bx] ! pop es ! pop ds ; init XIOS
nxiom:
;if intflag is non-zero, interrupts
;are explicitly turned on at the RTM
;entry point.
mov intflag,0ffh
; reset interrupt vectors
mov ax,ds ! sub bx,bx ! mov ds,bx
mov i_mpm_ip,offset user_entry
mov i_mpm_cs,cs
mov ds,ax
; get Character Dev Info from XIOS
mov ax,io_maxconsole ! call xiosif
mov ncondev,bl ! mov nciodev,bl
mov ax,io_maxlist ! call xiosif
mov nlstdev,bl ! add nciodev,bl
; Start RSPs
nrsp: ;loop til done
mov ds,sysdat ;reset DS
mov cx,rspseg ! jcxz rsp_out ;?all done?
mov es,cx ;ES->RSP
mov ax,es:.rsp_link ;save next RSP
mov rspseg,ax
mov es:.rsp_link,ds ;give Sysdat to RSP
mov si,rsp_pd ;get PD
mov ds,cx ;DS = RSP Data Seg
mov cl,f_createproc ;Create RSP Process(s)
mov dx,si ! int mpmint
jmps nrsp ;Do another...
rsp_out:
; terminate init process
mov cl,f_terminate
mov dl,0ffh ! int mpmint


Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,238 @@
;*****************************************************
;*
;* Queue Routines
;*
;*****************************************************
;=========== =======================
makeq_entry: ; Create a System Queue
;=========== =======================
; input : DX = address of QD in u_wrkseg
; u_wrkseg = segment of QD
; output: BX = 0 if okay , 0ffffh if error
; CX = Error Code
call getqdaddr ! mov di,dx ;DI->QD addr
cmp cx,0 ! je qm_chk
mov bx,0ffffh ! ret
;Make sure this queue doesn't already exist
qm_chk: pushf ! cli
push es ! mov es,sysdat
mov si,(offset qlr)-q_link
qm_nxt: mov si,q_link[si]
cmp si,0 ! je qm_go
push di ! push si ! mov cx,qnamsiz/2
add di,q_name ! add si,q_name
repe cmpsw
pop si ! pop di ! jne qm_nxt
;Names match
mov bx,0ffffh ! mov cx,e_q_inuse
pop es ! popf ! ret
qm_go: pop es
;We have a QD initialize it
mov dx,0 ! mov q_dq[di],dx
mov q_nq[di],dx ! mov q_msgcnt[di],dx
mov q_msgout[di],dx
;put it on QLR
mov ax,qlr ! mov q_link[di],ax
mov qlr,di ! sub bx,bx
mov cx,bx ! popf ! ret
;=========== ======================
openq_entry: ; Find an active Queue
;=========== ======================
; input: DX = address of QPB
; segment is u_wrkseg
; output: Fills QPB with appropriate info
; BX = 0 if okay, 0ffffh if not
; CX = Error Code
pushf ! cli
push es ! mov es,u_wrkseg
mov si,(offset qlr)-q_link ! mov di,dx
qo_nqd: mov si,q_link[si]
cmp si,0 ! je qo_noq
push di ! push si ! mov cx,qnamsiz/2
add si,q_name ! add di,qpb_name
repe cmpsw
pop si ! pop di ! jne qo_nqd
;Names match
mov es:qpb_qaddr[di],si
sub bx,bx ! mov cx,bx
pop es ! popf ! ret
qo_noq: ;No name matches
mov cx,e_no_queue ! mov bx,0ffffh
pop es ! popf ! ret
;============= =======================
deleteq_entry: ; Delete a System Queue
;============= =======================
; Takes a qd off the qlr and places it in the qul.
; input: DX = offset of QPB
; in u_wrkseg
; output: BX = 0 if ok, 0ffffh if bad
; CX = Error Code
pushf ! cli
push es ! mov es,u_wrkseg
mov di,dx ! add di,qpb_qaddr
mov di,es:[di]
mov ax,q_dq[di] ! mov dx,q_nq[di]
add dx,ax ! jnz qd_use
mov bx,(offset qlr)-q_link
qd_nqd: mov si,q_link[bx]
cmp si,0 ! jz qd_noq
cmp si,di ! jne qd_neq
mov ax,q_link[si]!mov q_link[bx],ax
call remqd
mov bx,0 ! mov cx,bx
pop es ! jmps qd_e
qd_neq: mov bx,si ! jmps qd_nqd
qd_noq: mov cx,e_q_notactive ! jmps qd_be
qd_use: pop ax ! mov cx,e_q_inuse
qd_be: mov bx,0ffffh
qd_e: popf ! ret
;=========== ============
readq_entry: ; Read Queue
;=========== ============
mov ax,0 ! jmps readq
;============
creadq_entry: ; Conditional Read Queue
;============
mov ax,0ffffh
; jmps readq
readq: ; Read message from queue
;----- -------------------------
; If no buffer is available, the process is placed into the DQ list
; of the queue and waits until another process writes into the queue.
; input: DX = address of qpb in u_wrkseg
; AX = 0ffffh if conditional
; 0 if not
; output: BX = 0 if okay
; 0ffffh if error
; CX = Error Code
push ax ! call queverify ! pop ax
cmp cx,0 ! je qr_ver
mov bx,0ffffh ! ret
qr_ver: push es ! mov es,u_wrkseg
mov si,dx ;es:[si]->QPB
mov bx,es:qpb_qaddr[si] ;bx->QD
mov di,es:qpb_buffptr[si] ;es:[di]->buff
pushf ! cli
mov cx,q_msgcnt[bx]
cmp cx,0 ! jne qr_gmsg
inc ax ! jnz qr_wait
mov bx,0ffffh ! mov cx,e_q_empty
popf ! pop es ! jmps qr_exit
qr_wait: lea dx,q_dq[bx] ;DX=addr of DQ List
mov bx,rlr ! mov p_stat[bx],ps_dq ;status=DQ
popf ! pop es ! push si
mov cx,f_sleep ! call mpmif ;Sleep on DQ List
pop dx ! jmps qr_ver
qr_gmsg:mov cx,q_msglen[bx]
cmp cx,0 ! jne qr_lmsg
mov cx,q_flags[bx] ; msglen=0
and cx,qf_mx ! jz qr_finish
mov ax,rlr ;Its a MX queue
mov q_buf[bx],ax ;BUF = PD addr (owner)
jmps qr_finish
qr_lmsg: ; msglen > 0
mov ax,q_msgout[bx] ! push ax
mul cx ! add ax,q_buf[bx]
mov si,ax ! rep movsb
pop ax ! inc ax
cmp ax,q_nmsgs[bx] ! jne qr_nend
mov ax,0
qr_nend:mov q_msgout[bx],ax
qr_finish:
dec q_msgcnt[bx] ! popf
mov si,bx ! pop es
lea dx,q_nq[si] ;DX = NQ List
mov cx,f_wakeup ;Wakeup a process
call mpmif ; waiting to write
mov cx,0 ! mov bx,cx
qr_exit:ret
;============ =============
writeq_entry: ; Write Queue
;============ =============
mov ax,0 ! jmps writeq
;============= =========================
cwriteq_entry: ; conditional Write Queue
;============= =========================
mov ax,0ffffh
;jmps writeq
writeq: ; Write message into queue
;------ --------------------------
; If no buffer is available, the process is placed into the NQ list
; of the queue and waits until another process reads from the queue.
; input: DX = address of qpb in u_wrkseg
; BX = pd address
; AX = 0ffffh if conditional
; 0 if not
; output: BX = 0 if okay
; 0ffffh if error
; CX = Error Code
push ax ! call queverify ! pop ax
cmp cx,0 ! je qw_ver
mov bx,0ffffh ! ret
qw_ver: push es ! mov es,u_wrkseg
mov di,dx ; es:[di]->QPB
mov bx,es:qpb_qaddr[di] ; bx -> QD
mov si,es:qpb_buffptr[di] ; es:[si]->QPB.buff
pushf ! cli
mov cx,q_msgcnt[bx]
cmp cx,q_nmsgs[bx] ! jne qw_gbuf
inc ax ! jnz qw_wait
popf ! pop es ! mov bx,0ffffh
mov cx,e_q_full ! jmps qw_exit
qw_wait: lea dx,q_nq[bx] ;DX = NQ List
mov bx,rlr ! mov p_stat[bx],ps_nq ;status=NQ
popf ! pop es ! push si
mov cx,f_sleep ! call mpmif ;Sleep on NQ List
pop dx ! jmps qw_ver ;try again
qw_gbuf:mov cx,q_msglen[bx] ;there is a buffer
cmp cx,0 ! je qw_fin
mov ax,q_msgout[bx] ! add ax,q_msgcnt[bx]
cmp ax,q_nmsgs[bx] ! jb qw_move
sub ax,q_nmsgs[bx]
qw_move: mul cx ! add ax,q_buf[bx]
mov di,ax ;DI=start of new msg
push ds ! push es ! pop ds ! pop es
rep movsb ; copy message
push ds ! push es ! pop ds ! pop es
qw_fin: inc q_msgcnt[bx]
mov cx,q_flags[bx] ! and cx,qf_mx
jz qw_nomx
mov q_buf[bx],0 ;an MX queue,no owner
qw_nomx:mov si,bx ! popf ! pop es
lea dx,q_dq[si] ;DX = DQ List
mov cx,f_wakeup ;Wakeup a process trying
call mpmif ; to read a message
sub bx,bx ! mov cx,bx
qw_exit:ret
queverify: ; check QLR for existence of QD address
;--------- ---------------------------------------
; input: DX = offset of QPB
; output: CX = error code
push ds ! mov ds,u_wrkseg
mov bx,dx ! mov si,qpb_qaddr[bx] ! pop ds
mov bx,offset qlr
qv_nxt: mov bx,q_link[bx]
cmp bx,0 ! jne qv_chk
mov cx,e_no_queue ! ret
qv_chk: cmp bx,si ! je qv_fnd
jmps qv_nxt
qv_fnd: mov cx,0 ! ret


View File

@@ -0,0 +1,334 @@
;
;****************************************************
;* *
;* Sample Random Access Program for MP/M-86 *
;* *
;****************************************************
;
; BDOS Functions
;
coninp equ 1 ;console input function
conout equ 2 ;console output function
pstring equ 9 ;print string until '$'
rstring equ 10 ;read console buffer
version equ 12 ;return version number
openf equ 15 ;file open function
closef equ 16 ;close function
makef equ 22 ;make file function
readr equ 33 ;read random
writer equ 34 ;write random
writerz equ 40 ;write random zero fill
;
; Equates for non graphic characters
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
;
;
; load SP, ready file for random access
;
cseg
pushf ;push flags in CCP stack
pop ax ;save flags in AX
cli ;disable interrupts
mov bx,ds ;set SS register to base of DATA group
mov ss,bx ;set SS, SP with interrupts disabled
mov sp,offset stack ; for 80888
push ax ;restore the flags
popf
;
; CP/M-86 initial release returns the file
; system version number of 2.2: check is
; shown below for illustration purposes.
;
mov cl,version
call bdos
cmp al,20h ;version 2.0 or later?
jnb versok
; bad version, message and go back
mov dx,offset badver
call print
jmp abort
;
versok:
; correct version for random access
mov cl,openf ;open default fct
mov dx,offset fcb
call bdos
inc al ;err 255 becomes zero
jnz ready
;
; cannot open file, so create it
mov cl,makef
mov dx,offset fcb
call bdos
inc al ;err 255 becomes zero
jnz ready
;
; cannot create file, directory full
mov dx,offset nospace
call print
jmp abort ;back to ccp
;
; loop back to "ready" after each command
;
ready:
; file is ready for processing
;
call readcom ;read next command
mov ranrec,dx ;store input record#
mov ranovf,ch ;set high byte
cmp al,'Q' ;quit?
jnz notq
;
; quit processing, close file
mov cl,closef
mov dx,offset fcb
call bdos
inc al ;err 255 becomes 0
jnz $+5
jmp error ;error message, retry
jmp abort ;back to ccp
;
;
; end of quit command, process write
;
;
notq:
; not the quit command, random write?
cmp al,'W'
jnz notw
;
; this is a random write, fill buffer until cr
mov dx,offset datmsg
call print ;data prompt
mov cx,127 ;up to 127 characters
mov bx,offset buff ;destination
rloop: ;read next character to buff
push cx ;save loop conntrol
push bx ;next destination
call getchr ;character to AL
pop bx ;restore destination
pop cx ;restore counter
cmp al,cr ;end of line?
jz erloop
; not end, store character
mov byte ptr [bx],al
inc bx ;next to fill
loop rloop ;decrement cx ..loop if not 0
erloop:
; end of read loop, store 00
mov byte ptr [bx],0h
;
; write the record to selected record number
mov cl,writer
mov dx,offset fcb
call bdos
or al,al ;error code zero?
jz ready ;for another record
jmps error ;message if not
;
;
;
; end of write random command, process write random zero fill
;
;
notw:
; not the quit command, random write?
cmp al,'Z'
jnz notz
;
; this is a random write, fill buffer until cr
mov dx,offset datmsg
call print ;data prompt
mov cx,127 ;up to 127 characters
mov bx,offset buff ;destination
rzloop: ;read next character to buff
push cx ;save loop conntrol
push bx ;next destination
call getchr ;character to AL
pop bx ;restore destination
pop cx ;restore counter
cmp al,cr ;end of line?
jz erzloop
; not end, store character
mov byte ptr [bx],al
inc bx ;next to fill
loop rzloop ;decrement cx ..loop if not 0
erzloop:
; end of read loop, store 00
mov byte ptr [bx],0h
;
; write the record to selected record number
mov cl,writerz
mov dx,offset fcb
call bdos
or al,al ;error code zero?
jnz $+5
jmp ready ;for another record
jmps error ;message if not
;
;
;
; end of write random zero fill command, process read
;
;
notz:
; not a write command, read record?
cmp al,'R'
jz ranread
jmps error ;skip if not
;
; read random record
ranread:
mov cl,readr
mov dx,offset fcb
call bdos
or al,al ;return code 00?
jz readok
jmps error
;
; read was successful, write to console
readok:
call crlf ;new line
mov cx,128 ;max 128 characters
mov si,offset buff ;next to get
wloop:
lods al ;next character
and al,07fh ;mask parity
jnz wloop1
jmp ready ;for another command if 00
wloop1:
push cx ;save counter
push si ;save next to get
cmp al,' ' ;graphic?
jb skipw ;skip output if not graphic
call putchr ;output character
skipw:
pop si
pop cx
loop wloop ;decrement CX and check for 00
jmp ready
;
;
; end of read command, all errors end-up here
;
;
error:
mov dx,offset errmsg
call print
jmp ready
;
; BDOS entry subroutine
bdos:
int 224 ;entry to BDOS if by INT 224
ret
;
abort: ;return to CCP
mov cl,0
call bdos ;use function 0 to end execution
;
; utility subroutines for console i/o
;
getchr:
;read next console character to a
mov cl,coninp
call bdos
ret
;
putchr:
;write character from a to console
mov cl,conout
mov dl,al ;character to send
call bdos ;send character
ret
;
crlf:
;send carriage return line feed
mov al,cr ;carriage return
call putchr
mov al,lf ;line feed
call putchr
ret
;
print:
;print the buffer addressed by dx until $
push dx
call crlf
pop dx ;new line
mov cl,pstring
call bdos ;print the string
ret
;
readcom:
;read the next command line to the conbuf
mov dx,offset prompt
call print ;command?
mov cl,rstring
mov dx,offset conbuf
call bdos ;read command line
; command line is present, scan it
mov ax,0 ;start with 0000
mov bx,offset conlin
mov ch,0 ;zero high byte of 3 byte result
readc: mov dl,[bx] ;next command character
inc bx ;to next command position
mov dh,0 ;zero high byte for add
or dl,dl ;check for end of command
jnz getnum
ret
; not zero, numeric?
getnum:
sub dl,'0'
cmp dl,10 ;carry if numeric
jnb endrd
cmp ch,0
jnz error ;error - number too large
push dx ;multiply by 10
mov cx,10
mul cx
mov ch,dl
pop dx
add ax,dx ;+digit
adc ch,0
jmps readc ;for another char
endrd:
; end of read, restore value in a and return value in bx
mov dx,ax ;return value in DX
mov al,-1[bx]
cmp al,'a' ;check for lower case
jnb transl
ret
transl: and al,5fH ;translate to upper case
ret
;
;
; Template for Page 0 of Data Group
; Contains default FCB and DMA buffer
;
dseg
org 05ch
fcb rb 33 ;default file control block
ranrec rw 1 ;random record position
ranovf rb 1 ;high order (overflow) byte
buff rb 128 ;default DMA buffer
;
; string data area for console messages
badver db 'sorry, you need cp/m version 2$'
nospace db 'no directory space$'
datmsg db 'type data: $'
errmsg db 'error, try again.$'
prompt db 'next command? $'
;
;
; fixed and variable data area
;
conbuf db conlen ;length of console buffer
consiz rs 1 ;resulting size after read
conlin rs 32 ;length 32 buffer
conlen equ offset $ - offset consiz
;
rs 31 ;16 level stack
stack rb 1
db 0 ;end byte for GENCMD
end


Binary file not shown.

View File

@@ -0,0 +1,884 @@
;*****************************************************
;*
;* 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


View File

@@ -0,0 +1,44 @@
include cpyright.def
;*****************************************************
;*
;* MP/M-86 Supervisor Module
;*
;*****************************************************
eject ! include system.def
eject ! include modfunc.def
eject ! include modtab.def
eject ! include xioscb.def
eject ! include pd.def
eject ! include err.def
eject ! include qd.def
eject ! include fcb.def
eject ! include acb.def
eject ! include enttab.def
eject ! include mem.def
eject ! include mpb.def
eject ! include clicb.def
eject ! include rsp.def
eject ! include pcb.def
eject ! include cmdh.def
eject ! include ldtab.def
eject ! include char.def
eject ! include init.sup
eject ! include idle.sup
eject ! include tick.sup
eject ! include supif.sup
eject ! include sysfunc.sup
eject ! include command.sup
eject ! include load.sup
eject ! include parse.sup
eject ! include rpl.sup
eject ! include patch.cod
eject ! include basep.fmt
eject ! include lstk.fmt
eject ! include vec.fmt
eject ! include uda.fmt
eject ! include sysdat.fmt
eject ! end


Binary file not shown.

View File

@@ -0,0 +1,18 @@
eject ! include cpyright.def
;*****************************************************
;*
;* System Data Area - Initialized Data
;*
;*****************************************************
eject ! include system.def
eject ! include pd.def
eject ! include qd.def
eject ! include modfunc.def
eject ! include system.dat
eject
cpm equ false
mpm equ true
include data.bdo
eject ! end


View File

@@ -0,0 +1,509 @@
;*****************************************************
;*
;* Terminal Message Processor
;*
;* The TMP determines the user interface to MPM.
;* Much of the interface is available though
;* system calls. This TMP takes advantage of
;* as much as possible for simplicity. The TMP
;* could, for instance, be easily modified to
;* force logins and have non-standard defaults.
;*
;* With a little more work, The TMP could do all
;* command parsing and File Loading instead of
;* using the CLI COMMAND FUNCTION. This is also
;* the place to AUTOLOAD programs for specific
;* users. Suggestions are given in the MP/M-86
;* SYSTEM'S GUIDE.
;*
;*****************************************************
true equ 0ffh
false equ 0
unknown equ 0
mpmint equ 224 ; int vec for mpm
cr equ 13
lf equ 10
mpm_conout equ 2
mpm_conwrite equ 9
mpm_conread equ 10
mpm_diskselect equ 14
mpm_getdefdisk equ 25
mpm_usercode equ 32
mpm_freedrive equ 39
mpm_conattach equ 146
mpm_condetach equ 147
mpm_setdefcon equ 148
mpm_clicmd equ 150
mpm_parse equ 152
mpm_setdeflst equ 160
mpm_getdeflst equ 164
ps_run equ 00 ; on ready list root
pf_sys equ 001h ; system process
pf_keep equ 002h ; do not terminate
s_mpmseg equ word ptr 40H ;begin MPM segment
s_sysdisk equ byte ptr 04bh ;system disk
s_ncns equ byte ptr 47H ;sys. consoles
s_version equ word ptr 78h ;ofst ver. str in SUP
rsp_top equ 0
rsp_md equ 008h
rsp_pd equ 010h
rsp_uda equ 040h
rsp_bottom equ 140h
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
;*****************************************************
;*
;* TMP Shared Code and Constant Area
;*
;*****************************************************
cseg
org 0
;===
mpm: ; INTERFACE ROUTINE FOR SYSTEM ENTRY POINTS
;===
int mpmint ! ret
;===
tmp: ; PROGRAM MAIN - INITIALIZATION
;===
; set default console # = TMP#
mov dl,defconsole ! call setconsole
; set default disk = drive A
push ds ! mov ds,sysdatseg
mov dl,.s_sysdisk ! pop ds
call setdisk
; set default user # = console
mov dl,defconsole ! call setuser
; print version
call attach
push ds ! mov ds,sysdatseg
mov dx,.s_version
mov ds,.s_mpmseg
call print_ds_string ! pop ds
call detach
; THIS IS WHERE A LOGIN ROUTINE MIGHT
; BE IMPLEMENTED. THE DATA FILE THAT
; CONTAINS THE USER NAME AND PASSWORD
; MIGHT ALSO CONTAIN AN INITIAL DEFAULT
; DISK AND USER NUMBER FOR THAT USER.
;===========
nextcommand: ; LOOP FOREVER
;===========
; free drive
mov dx,0ffffh ! call freedrive
; attach console
call attach
; print CR,LF if we just sent command
cmp cmdsent,false ! je noclearline
mov cmdsent,false
call crlf
noclearline:
; set up and print user prompt
; get current default user # and disk
; this call should be made on every
; loop in case the last command
; has changed the default.
mov dl,cr ! call prchar
call getuser
mov dl,bl ! call prnum
call getdisk
mov dl,'A' ! add dl,bl
call prchar
mov dx,offset prompt
call print_string
; Read Command from Console
mov dx,offset read_buf ! call conread
; echo newline
mov dl,lf ! call prchar
; make sure not a null command
lea bx,clicb_cmd
cmp read_blen,0 ! je gonextcmd
cmp byte ptr [bx],';' ! je gonextcmd
; see if disk change
; if 'X:' change def disk to X
cmp read_blen,2 ! jne clicall
cmp byte ptr 1[bx],':'
jne clicall
; change default disk
mov dl,[bx] ;get disk name
and dl,5fh ;Upper Case
sub dl,'A' ;disk number
; check bounds
cmp dl,0 ! jb gonextcmd
cmp dl,15 ! ja gonextcmd
; select default disk
call setdisk
gonextcmd: jmp nextcommand
;=======
clicall: ; SEND CLI COMMAND
;=======
; put null at end of input
mov bx,offset clicb_cmd
mov al,read_blen ! mov ah,0
add bx,ax ! mov byte ptr [bx],0
; copy command string for err
; reporting later and to check
; for built in commands...
mov cx,64
mov si,offset clicb_cmd
mov di,offset savebuf
push ds ! pop es
rep movsw
; parse front to see if
; built in command
mov si,offset fcb
mov di,offset savebuf
call parsefilename
jcxz goodparse
sub bx,bx ! mov bl,read_blen
add bx,offset savebuf
mov byte ptr [bx],'$'
jmp clierror
goodparse: mov parseret,bx
cmp bx,0 ! jne haveatail
mov bl,read_blen
add bx,offset savebuf
haveatail: mov byte ptr [bx],'$' ! inc bx
cmp fcb,0 ! je try_builtin
jmp not_builtin
; is it USER command?
try_builtin: mov si,offset fcb ! inc si
mov di,offset usercmd
push cs ! pop es
mov cx,4 ! repz cmpsw
jnz notuser
mov si,offset fcb
mov di,parseret
cmp di,0 ! je pruser
inc di
call parsefilename
cmp cx,0 ! jne pruser
mov si,offset fcb
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 printstring
pruser: mov dx,offset usermsg
call printstring
call getuser
mov dl,bl ! call prnum
call crlf
jmp nextcommand
notuser:
mov si,offset fcb ! inc si
mov di,offset printercmd
push cs ! pop es
mov cx,4 ! repz cmpsw
jnz notprinter
mov si,offset fcb
mov di,parseret
cmp di,0 ! je prprinter
inc di
call parsefilename
cmp cx,0 ! jne prprinter
mov si,offset fcb
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 printemsg
call printstring
prprinter: mov dx,offset printermsg
call printstring
call getlist
mov dl,bl ! call prnum
call crlf
jmp nextcommand
notprinter:
not_builtin:
; 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
jmp nextcommand
;========
clierror:
;========
; Cli call unsuccesful, analyze and display err msg
; input: CX = ERROR CODE
;null command?
cmp cx,e_nullcmd ! jne not_nullcmd
mov cmdsent,false
jmp nextcommand
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:
;bad file spec?
cmp cx,e_badfname ! je fname_bad
cmp cx,e_illdisk ! je fname_bad
cmp cx,e_ill_passwd ! 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 in CSEG
push dx
mov dx,offset savebuf ! call print_ds_string
mov dl,':' ! call prchar
mov dl,' ' ! call prchar
pop dx
call printstring ! call crlf
jmp nextcommand
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
prchar: mov cl,mpm_conout ! jmp mpm1
getuser: mov dl,0ffh
setuser: mov cl,mpm_usercode ! jmp mpm1
crlf: mov dx,offset crlfstr
;jmp printstring
printstring: push ds ! mov ax,cs ! mov ds,ax
call print_ds_string ! pop ds ! ret
print_ds_string:mov cl,mpm_conwrite ! 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
freedrive: mov cl,mpm_freedrive ! jmps mpm1
mpm1: jmp mpm
;*****************************************************
;*
;* CONSTANTS (IN SHARED CODE SEGMENT)
;*
;*****************************************************
prompt db '>$'
crlfstr db 13,10,'$'
memerr db '?Not Enough Memory$'
pderr db '?PD Table Full$'
fnameerr db '?Bad File Spec$'
loaderr db '?Load Error$'
openerr db '?Can''t Find Command$'
catcherr db '?$'
qfullerr db '?RSP Command Que Full$'
usererrmsg db 13,10,'Invalid User Number,'
db ' IGNORED',13,10,'$'
usermsg db 13,10,'User Number = $'
printemsg db 13,10,'Invalid Printer Number,'
db ' IGNORED',13,10,'$'
printermsg db 13,10,'Printer Number = $'
usercmd db 'USER '
printercmd db 'PRINTER '
;*****************************************************
;*
;* TMP Data Area - this area is copied once for
;* each system console. The 'defconsole'
;* field is unique for each copy
;* - Each Data Area is run by a common
;* shared code segment.
;*
;*****************************************************
DSEG
org rsp_top
sysdatseg dw 0
sdatvar dw s_ncns
defconsole db 0,0
dw 0,0,0,0,0
org rsp_pd
pd dw 0,0 ; link fields
db ps_run ; status
db 198 ; priority
dw pf_sys+pf_keep ; flags
db 'Tmp ' ; Name
dw offset uda/10h ; uda seg
db 0,0 ; disk,user
db 0,0 ; ldisk,luser
dw 0ffffh ; mem
dw 0,0 ; dvract,wait
db 0,0 ; org,net
dw 0 ; parent
db 0,0 ; cns,abort
db 0,0 ; cin,cout
db 0,0 ; lst,sf3
db 0,0 ; sf4,sf5
dw 0,0 ; reserved
dw 0,0 ; pret,scratch
org rsp_uda
uda dw 0,offset dma,0,0 ;0-7
dw 0,0,0,0 ;8-fh
dw 0,0,0,0 ;10-17
dw 0,0,0,0 ;18-1f
dw 0,0,0,0 ;20-27
dw 0,0,0,0 ;28-2f
dw 0,0,offset stack_top,0 ;30-37
dw 0,0,0,0 ;38-3f
dw 0,0,0,0 ;40-47
dw 0,0,0,0 ;48-4f
dw 0,0,0,0 ;50-57
dw 0,0,0,0 ;58-5f
dw 0,0,0,0 ;60-67
org rsp_bottom
dma rb 128
stack dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
dw 0cccch,0cccch,0cccch
stack_top dw offset tmp ; code offset
dw unknown ; code seg
dw unknown ; init. flags
maxcmdlen equ 128
; the Read Console Buffer and the
; Cli Control Block share the same memory
read_buf rb 0
read_maxcmd db 128
clicb rb 0
clicb_net rb 0
read_blen rb 1
clicb_cmd rb maxcmdlen + 1
cmdsent db false
parseret dw 0
pcb dw offset savebuf
dw offset fcb
fcb rb 32
savebuf rb 128
;make sure hex is formed
db 0
end


Binary file not shown.

View File

@@ -0,0 +1,66 @@
vax sup.a86 $$atn
vax cpmmem.mem $$atn
vax que1.rtm $$atn
vax abort.rtm $$atn
vax command.sup $$atn
vax all.sub $$atn
vax sysdat.a86 $$atn
vax init.sup $$atn
vax apb.def $$atn
vax findpd.rtm $$atn
vax system.dat $$atn
vax rtm.a86 $$atn
vax xioscb.def $$atn
vax cmdh.def $$atn
vax fcb.def $$atn
vax basep.fmt $$atn
vax load.sup $$atn
vax ldtab.def $$atn
vax lstk.fmt $$atn
vax supif.sup $$atn
vax mem.a86 $$atn
vax modtab.def $$atn
vax cio.a86 $$atn
vax modfunc.def $$atn
vax share.def $$atn
vax char.def $$atn
vax mpb.def $$atn
vax cpyright.def $$atn
vax sysent.rtm $$atn
vax flag.rtm $$atn
vax sysfunc.sup $$atn
vax parse.sup $$atn
vax memory.mem $$atn
vax mau.mem $$atn
vax pd.def $$atn
vax qd.def $$atn
vax system.def $$atn
vax loadms.def $$atn
vax dsptch.rtm $$atn
vax rpl.sup $$atn
vax que2.rtm $$atn
vax uda.fmt $$atn
vax ml.mem $$atn
vax acb.def $$atn
vax proc.rtm $$atn
vax mem.def $$atn
vax util.mem $$atn
vax clicb.def $$atn
vax ccb.def $$atn
vax rtmif.rtm $$atn
vax memif.mem $$atn
vax cioif.cio $$atn
vax sysdat.fmt $$atn
vax err.def $$atn
vax tick.sup $$atn
vax pcb.def $$atn
vax idle.sup $$atn
vax flg.def $$atn
vax chario.cio $$atn
vax data.bdo $$atn
vax vec.fmt $$atn
vax rsp.def $$atn
vax enttab.def $$atn
vax patch.cod $$atn
vax console.cio $$atn