	title	 'MP/M II V2.0 Extended Disk Operating System'
	name	'xdos'
	dseg
@@xdos:
	public	@@xdos
	cseg
;xdos:
@xdos:
	public	@xdos
;do;

;/*
;  Copyright (C) 1979,1980,1981
;  Digital Research
;  P.O. Box 579
;  Pacific Grove, CA 93950
;
;  Revised:
;    14 Sept 81 by Thomas Rolander
;*/

;$include (common.lit)
;$nolist
;$include (queue.lit)
;$nolist
;$include (proces.lit)
;$nolist
;$include (memmgr.lit)
;$nolist
;$include (datapg.ext)
;$nolist
;$include (proces.ext)
;$nolist
;$include (queue.ext)
;$nolist
;$include (flag.ext)
;$nolist
;$include (memmgr.ext)
;$nolist
;$include (th.ext)
;$nolist
;  flshbf:
	extrn	flshbf
;    procedure;
;    end flshbf;

;  parse$filename:
	extrn	parsefilename
;    procedure (pcb$address) address external;
;      declare pcb$address address;
;    end parse$filename;

;  exitr:
	extrn	exitr
;    procedure external;
;    end exitr;

;  flgwt:
	extrn	flgwt
;    procedure (flgnmb) byte external;
;      declare flgnmb byte;
;    end flgwt;

;  flgset:
	extrn	flgset
;    procedure (flgnmb) byte external;
;      declare flgnmb byte;
;    end flgset;

;  absrq:
	extrn	absrq
;    procedure (mdadr) byte external;
;      declare mdadr address;
;    end absrq;

;  relrq:
	extrn	relrq
;    procedure (mdadr) byte external;
;      declare mdadr address;
;    end relrq;

;  memfr:
	extrn	memfr
;    procedure (mdadr) byte external;
;      declare mdadr address;
;    end memfr;

;  dispat:
	extrn	dispat
;    procedure external;
;    end dispat;

;  makeq:
	extrn	makeq
;    procedure (qcbadr) byte external;
;      declare qcbadr address;
;    end makeq;

;  openq:
	extrn	openq
;    procedure (uqcbadr) byte external;
;      declare uqcbadr address;
;    end openq;

;  deletq:
	extrn	deletq
;    procedure (uqcbadr) byte external;
;      declare uqcbadr address;
;    end deletq;

;  readq:
	extrn	readq
;    procedure (uqcbadr) byte external;
;      declare uqcbadr address;
;    end readq;

;  creadq:
	extrn	creadq
;    procedure (uqcbadr) byte external;
;      declare uqcbadr address;
;    end creadq;

;  writeq:
	extrn	writeq
;    procedure (uqcbadr) byte external;
;      declare uqcbadr address;
;    end writeq;

;  cwriteq:
	extrn	cwriteq
;    procedure (uqcbadr) byte external;
;      declare uqcbadr address;
;    end cwriteq;

;  assign:
	extrn	assign
;    procedure (pname) byte external;
;      declare pname address;
;    end assign;

;  declare dparam address external;
	extrn	dparam

;  declare rlr address external;
	extrn	rlr

;  declare drl address external;
	extrn	drl

;  declare dlr address external;
	extrn	dlr

;  declare plr address external;
	extrn	plr

;  declare slr address external;
	extrn	slr

;  declare qlr address external;
	extrn	qlr

;  declare thrdrt address external
	extrn	thrdrt

;  declare nmbcns literally '16';
nmbcns	equ	16

;  declare cnsatt (1) address external;
	extrn	cnsatt

;  declare lstatt (1) address external;
	extrn	lstatt

;  declare mpmver address external;
	extrn	mpmver

;  declare cnsque (1) address external;
	extrn	cnsque

;  declare tod structure (
	extrn	tod
;    day address,
;    hr byte,
;    min byte,
;    sec byte ) external;

;  declare nmbflags byte external;
	extrn	nmbflags

;  declare sysfla (1) address external;
	extrn	sysfla

;  declare nmblst byte external;
	extrn	nmblst

;  declare lstque (1) address external;
	extrn	lstque

;  declare sysdat address external;
	extrn	sysdat

;  declare cli$lqcb address external;
	extrn	clilqcb

	dseg
;  declare cli$uqcb userqcbhead
;    initial (.cli$lqcb,0);
;cliuqcb:    /* This data structure has been moved to the stack */
;	dw	clilqcb	; pointer
;	dw	$-$	; msgadr

;  declare rsp$adr address;
rspadr:	ds	2

;  declare rsp$uqcb userqcb
;    initial (0,.rsp$adr,'$$$$$$$$');
rspuqcb:
	dw	$-$	; pointer
	dw	rspadr	; msgadr
	db	'$$$$$$$$'	; name

;  declare cpb$adr address;
cpbadr:	ds	2
;  declare cpb based cpb$adr structure (
;    rsp$name$adr address,
;    rsp$param address);

;  declare flag$wait$function literally '4';
;  declare flag$set$function literally '5';

;  declare (svstk,old$drl,old$thread$root) address;
svstk:	ds	2
olddrl:	ds	2
oldthreadroot:
	ds	2
	cseg

;  xdos:
xdos:
	public	xdos
;    procedure (function,parameter) address reentrant public;
;      declare function byte;
;      declare parameter address;
;      declare ret address;
;      declare pd based parameter process$descriptor;

;      ret = 0000H;
	MOV	A,C
;      function = function - 128;
	SUI	80H
;      if function > max$xdos$function then
	CPI	maxfunc
	LXI	H,0FFFFH
	RNC
;      do;
;        ret = 0FFFFH;
;      end;
;      else
;      do case function;
	CPI	4H
	JZ	@1	; SETUP RETURN TO DISPATCH
	CPI	5H	;  FOR ALL BUT FLAG OP'S
	JZ	@1
	LXI	H,DISPAT
	PUSH	H
@1:
	LXI	H,EXDOS
	PUSH	H
	MOV	B,D
	MOV	C,E
	MOV	E,A
	MVI	D,0
	LXI	H,@37
	DAD	D
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	LHLD	RLR
	INX	H
	INX	H	; HL = .RLR.STATUS
	XCHG
	PCHL

;        /* function = 128, Absolute Memory Request */
;        ret = abs$rq (parameter);
;	CALL	ABSRQ

;        /* function = 129, Relocatable Memory Request */
;        ret = rel$rq (parameter);
;	CALL	RELRQ

;        /* function = 130, Memory Free */
;        call mem$fr (parameter);
;	CALL	MEMFR

;        /* function = 131, Poll Device */
;        do;
@7:
;          enter$region;
	DI
;          dsptch$param = parameter;
	MOV	L,C
	MOV	H,B
	SHLD	DPARAM
;          rlrpd.status = poll$status;
	XCHG
	MVI	M,3H
;        end;
	RET

;        /* function = 132, Flag Wait */
;        ret = flag$wait (parameter);
;	CALL	FLGWT

;        /* function = 133, Flag Set */
;        ret = flag$set (parameter);
;	CALL	FLGSET

;        /* function = 134, Make Queue */
;        ret = makeq (parameter);
;	CALL	MAKEQ

;        /* function = 135, Open Queue */
;        ret = openq (parameter);
;	CALL	OPENQ

;        /* function = 136, Delete Queue */
;        ret = deletq (parameter);
;	CALL	DELETQ

;        /* function = 137, Read Queue */
;        ret = readq (parameter);
;	CALL	READQ

;        /* function = 138, Conditional Read Queue */
;        ret = creadq (parameter);
;	CALL	CREADQ

;        /* function = 139, Write Queue */
;        ret = writeq (parameter);
;	CALL	WRITEQ

;        /* function = 140, Conditional Write Queue */
;        ret = cwriteq (parameter);
;	CALL	CWRITEQ

;        /* function = 141, Delay */
;        do;
@17:
;          enter$region;
	DI
;          dsptch$param = parameter;
	MOV	L,C
	MOV	H,B
	SHLD	DPARAM
;          rlrpd.status = delay$status;
	XCHG
	MVI	M,5H
;        end;
	RET

;        /* function = 142, Dispatch */
;        do;
@18:
;          enter$region;
	DI
;          rlrpd.status = dispatch$status;
	XCHG
	MVI	M,9H
;        end;
	RET

;        /* function = 143, Terminate */
;        do;
@19:
;          call flush$buffers;
	push	b
	push	d
	call	flshbf
	pop	d
	pop	b
;          enter$region;
	DI
;          dsptch$param = parameter;
	MOV	L,C
	MOV	H,B
	SHLD	DPARAM
;          rlrpd.status = terminate$status;
	XCHG
	MVI	M,7H
;        end;
	RET

;        /* function = 144, Create */
;        do;
@20:
;          enter$region;
	DI
;          old$drl = drl;
	LHLD	DRL
	SHLD	OLDDRL
;          old$thread$root = thread$root;
	LHLD	THRDRT
	SHLD	OLDTHREADROOT
;          drl,
;          thread$root = parameter;
	MOV	L,C
	MOV	H,B
	SHLD	DRL
	SHLD	THRDRT
;          do while pd.pl <> 0;
@38:
	MOV	E,M
	INX	H
	MOV	D,M
	MOV	A,E
	ORA	D
	JZ	@39
;            pd.thread = pd.pl;
	LXI	H,12H
	DAD	B
	MOV	M,E
	INX	H
	MOV	M,D
	CALL @39A
;            parameter = pd.pl;
	MOV	B,D
	MOV	C,E
	XCHG
;          end;
	JMP	@38
@39:
;          pd.pl = old$drl;
	XCHG
	LHLD	OLDDRL
	XCHG
	MOV	M,D
	DCX	H
	MOV	M,E
;          pd.thread = old$thread$root;
	LHLD	OLDTHREADROOT
	XCHG
	LXI	H,12H
	DAD	B
	MOV	M,E
	INX	H
	MOV	M,D
@39A:
;            pd.drvacc = 0;
	lxi	h,1ch
	dad	b
	xra	a
	mov	m,a
	inx	h
	mov	m,a
;            pd.multcnt = 1;
	lxi	h,32h
	dad	b
	mvi	m,1
;            pd.pdcnt = 0;
	inx	h
	mov	m,a
;        end;
	RET

;        /* function = 145, Set Priority */
;        do;
@21:
;          enter$region;
	DI
;          dsptch$param = parameter;
	MOV	L,C
	MOV	H,B
	SHLD	DPARAM
;          rlrpd.status = set$prior$status;
	XCHG
	MVI	M,8H
;        end;
	RET

;        /* function = 146, Attach */
;        do;
@22:
;          enter$region;
	DI
;          rlrpd.status = attach$status;
	XCHG
	MVI	M,0AH
;        end;
	RET

;        /* function = 147, Detach */
;        do;
@23:
;          enter$region;
	DI
;          rlrpd.status = detach$status;
	XCHG
	MVI	M,0BH
;        end;
	RET

;        /* function = 148, Set Console */
;        do;
@24:
;          rlrpd.console = parameter;
	lxi	h,0eh-02h
	dad	d	;HL = .rlrpd.console
	mov	a,m
	ani	0f0h
	ora	c
	mov	m,a
	pop	h	;discard EXDOS return
;        end;
	RET

;        /* function = 149, Assign Console */
;        ret = assign (parameter);
;	CALL	ASSIGN

;        /* function = 150, Send CLI Command */
;        do;
@26:
;			+------+
;			|msgadr|
;			+------+
;	Stk Ptr	------->| qptr |
;			+------+

;          cli$uqcb.msgadr = parameter;
	push	b
;          cli$uqcb.pointer = .cli$lqcb;
	lxi	h,clilqcb
	push	h
;          ret = writeq (.cli$uqcb);
	lxi	h,0
	dad	sp
	mov	b,h
	mov	c,l
	call	WRITEQ
	pop	h
	pop	h
	ret
;        end;

;        /* function = 151, Call Resident System Process */
;        do;
@27:
	POP	H	; DISCARD EXDOS RETURN

	mov	h,b
	mov	l,c		;HL = .cpb
;            cpb$adr = parameter;
	mov	c,m
	inx	h
	mov	b,m		;BC = cpb.name
	inx	h
	mov	e,m
	inx	h
	mov	d,m		;DE = cpb.param
	lxi	h,-14
	dad	sp
	sphl			;make room for uqcb+2 on stk
	push	d
;
;	Stack Structure:
;
;	+-----------------------+
;	|   Return Address      |
;	+-----------------------+
;	|                       |
;	  uqcb.name(0) - name(7)
;	|                       |
;	+-----------------------+
;	|   uqcb.msgadr         | ---+
;	+-----------------------+    |
;	|   uqcb.pointer        |    |
;	+-----------------------+    |
;	|  (space for .proc)    | <--+
;	+-----------------------+
;  S--->|   .cpb.param          |
;	+-----------------------+
;
	mov	d,h
	mov	e,l
	inx	h
	inx	h
	inx	h
	inx	h
	mov	m,e
	inx	h
	mov	m,d		;uqcb.msgadr <-
	inx	h
;            call move (8,cpb.rsp$name$adr,.rsp$uqcb.name);
	mvi	e,8
clresploop:
	ldax	b
	mov	m,a
	inx	b
	inx	h
	dcr	e
	jnz	clresploop
;            /* open queue having passed procedure name */
;            if openq(.rsp$uqcb) <> 0ffh then
	lxi	b,-12
	dad	b		;HL = .uqcb
	mov	b,h
	mov	c,l
	call	openq
	inr	a
;            else
;            do;
;              /* procedure not resident */
;              ret = 1;
;            end;
	lxi	h,0001h
	pop	d		;DE = cpb.param
	jz	clrespdone	;queue not found
;            do;
;              /* read queue to get procedure entry point address */
;              call readq (.rsp$uqcb);
	lxi	h,2
	dad	sp
	mov	b,h
	mov	c,l
	push	d
	call	readq		;read proc adr from queue
;              /* execute the procedure (function) */
;              ret = xfunc (cpb.rsp$param,rsp$adr);

	pop	b		;BC = cpb.param
	pop	h		;HL = procadr
	push	h
	lxi	d,clresprtn
	push	d		;setup return addr
	pchl			;call proc (param)
clresprtn:			;return here from proc call
	push	h		;save returned result
;              /* write queue to put message back on queue, this
;                 mechanism makes the procedure a serially
;                 resuseable resource                            */
;              call writeq (.rsp$uqcb);
;            end;
	lxi	h,4
	dad	sp
	mov	b,h
	mov	c,l		;BC = .uqcb
	call	writeq		;write proc adr to queue
	pop	h		;DE = result returned from proc
clrespdone:
	xchg
	lxi	h,14
	dad	sp
	sphl			;discard uqcb on stack
	xchg
;        end;
	ret			;return with HL = proc()

;        /* function = 152, Parse Filename */
;        ret = parse$filename (parameter);
@31:
	POP	H	; DISCARD EXDOS RETURN
	JMP	PARSEFILENAME

;        /* function = 153, Get Console Number */
;        ret = rlrpd.console;
@32:
	LXI	B,0CH
	XCHG
	DAD	B
	MOV	A,M
	ani	0fh
	RET

;        /* function = 154, System Data Address */
;        ret = sysdat;
@33:
	POP	H	; DISCARD EXDOS RETURN
	LHLD	SYSDAT
	RET

;        /* function = 155, Get Time & Date */
;        do;
@34:
;          call move (5,.tod,parameter);
	LXI	D,TOD
	MVI	L,5H
	LDAX	D
	STAX	B
	INX	B
	INX	D
	DCR	L
	JNZ	$-5H
;        end;
	RET

;        /* function = 156, Return Process Descriptor Address */
;	 do;
rtnpdadr:
;          return rlr;
	pop	h	; discard EXDOS return
	lhld	rlr
;        end;
	ret

;        /* function = 157, Abort Specified Process */
;        do;
abort:
;
; BC -> Abort$parameter$control$block
; declare apcb structure (
;   pdadr address,
;   param address,
;   pname (8) byte );
	ldax	b
	inx	b
	mov	e,a
	ldax	b
	inx	b
	mov	d,a
	ora	e	;test for PD address present
	ldax	b
	inx	b
	mov	l,a
	ldax	b
	inx	b
	mov	h,a	;DE = apcb.pdadr, HL = apcb.param
	di
	shld	dparam
	shld	tparam
	jnz	@15	;jump if already have pdadr
;      pdadr = thread$root;
	LHLD	THRDRT
	XCHG
;      do while pdadr <> 0;
@9:
;        i = 1;
	PUSH	B
	LXI	H,6
	DAD	D
	PUSH	H
	MVI	L,8	;** this no longer includes the pd.console byte !
;        do while (i <> 9) and (pd.name(i-1) = pname(i));
@11:
	XTHL
	LDAX	B
	sub	M
	INX	B
	INX	H
	JZ	@11A
	ani	7fh
	jz	@11a	;also don't care on high order bit
	POP	H
	POP	B
	JMP	@6
@11A:
	XTHL
	DCR	L
	JNZ	@11
	xthl		;now test console byte
	ldax	b
	mov	b,a
	mov	a,m
	ani	0fh
	cmp	b
;          i = i + 1;
;        end;
	pop	h
	pop	b
	jz	@15
@6:
;        pdadr = pd.thread;
	LXI	H,12H
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	MOV	A,D
	ORA	E
	JNZ	@9
;      end;
exitabort:
;      return 0FFFFH;
	ei
	mvi	a,0ffh
	RET
@15:
	lxi	h,13
	dad	d
	mov	a,m
	ani	80h
	jnz	@15b	;jump if no abort flag bit set
	push	h
	lxi	h,7
	dad	d
	mov	a,m
	ani	80h
	pop	h
	jz	@15a	;jump if in bdos flag bit not set
	dcx	h
	ora	m
	mov	m,a
	dcx	h
	dcx	h
	dcx	h
	dcx	h
	mov	a,m
	ori	80h
	mov	m,a	;set no sys stk swp flag bit
	dcx	h
	dcx	h
	dcx	h
	dcx	h
	dcx	h
	xra	a
	mov	m,a	;set priority to zero
	ei
	ret
@15b:
	dcx	h
	ora	m
	mov	m,a		;set process abort flag
	jmp	exitabort	;cannot abort
@15a:
	lhld	rlr
	mov	a,e
	cmp	l
	jnz	@16
	mov	a,d
	cmp	h
	jnz	@16
;
; aborting the running process
	inx	h
	inx	h
	mvi	m,7	;set pd.status to terminate
	ret
@16:
	lxi	b,setupabort
	push	b		;setup return address
	lxi	h,2
	dad	d
	mov	c,m
	mvi	b,0
	lxi	h,abtbl
	dad	b
	dad	b
	mov	a,m
	inx	h
	mov	h,m
	mov	l,a
	pchl

abtbl:
	dw	abtrun	; 0 = Ready to run
	dw	abtque	; 1 = DQ
	dw	abtque	; 2 = NQ
	dw	abtpol	; 3 = Poll
	dw	abtflg	; 4 = Flag Wait
	dw	abtdly	; 5 = Delay
	dw	abtswp	; 6 = Swap
	dw	abtrun	; 7 = Terminate
	dw	abtrun	; 8 = Set Priority
	dw	abtrun	; 9 = Dispatch
	dw	abtcns	;10 = Attach
	dw	abtrun	;11 = Detach
	dw	abtcns	;12 = Set Console
	dw	abtlst	;13 = Attach List
	dw	abtrun	;14 = Detach List

;
; 0 Ready to run
; 7 Terminate
; 8 Set Priority
; 9 Dispatch
;11 Detach
;
abtrun:
	pop	h	;discard return addr
	jmp	procrdy	;no action simply setup abort

;
; 1 DQ
; 2 NQ
;
abtque:
	;find queue link & remove
	lxi	b,qlr
abtq0:
	ldax	b
	mov	l,a
	inx	b
	ldax	b
	mov	h,a
	ora	l
	rz		;not DQing or NQing ?
	push	h
	lxi	b,14
	dad	b
	mov	b,h
	mov	c,l
	push	b
	call	delpr
	pop	b
	pop	h
	rc		;return if DQing & removed
	push	h
	inx	b
	inx	b
	call	delpr
	pop	b
	rc		;return if NQing & removed
	jmp	abtq0

;
; 3 Poll
;
abtpol:
	;remove PD from poll list
	lxi	b,plr
	jmp	delpr
	;ret

;
; 4 Flag Wait
;
abtflg:
	;remove PD from flag
	lda	nmbflags
	mov	c,a
	inr	c
	lxi	h,sysfla-1
abtfl0:
	inx	h
	dcr	c
	rz		;not waiting for a flag ?!
	mov	a,e
	cmp	m
	inx	h
	jnz	abtfl0
	mov	a,d
	cmp	m
	jnz	abtfl0
	mvi	m,0ffh
	dcx	h
	mvi	m,0ffh
	ret

;
; 5 Delay
;
abtdly:
	;remove PD from delay list
	lxi	b,dlr
	jmp	delpr
	;ret

;
; 6 Swap
;
abtswp:
	;remove PD from swap list
	lxi	b,slr
	jmp	delpr
	;ret

;
;10 Attach
;12 Set Console
;
abtcns:
	;remove PD from console queue
	mvi	l,nmbcns
	inr	l
	lxi	b,cnsque
abct0:
	dcr	l
	rz		;not queued for any console ?
	push	b
	push	h
	call	delpr
	pop	h
	pop	b
	inx	b
	inx	b
	jnc	abct0
	ret

;
;13 Attach List
;
abtlst:
	;remove PD from list queue
	mvi	l,nmbcns
	inr	l
	lxi	b,lstque
ablt0:
	dcr	l
	rz		;not queued for any list ?
	push	b
	push	h
	call	delpr
	pop	h
	pop	b
	inx	b
	inx	b
	jnc	ablt0
	ret

setupabort:
	;put PD on dispatcher ready list
	lhld	drl
	xchg
	mov	m,e
	inx	h
	mov	m,d
	dcx	h
	shld	drl
	xchg
procrdy:
	;compute process return address location in stack
	;and fill in with address of abort code.
	xchg
	inx	h
	inx	h
	inx	h
	mvi	m,0	;pd.priority = 0
	inx	h	;HL = .pd.stkptr
	mov	e,m
	inx	h
	mov	d,m	;DE = pd.stkptr
	dcx	d
	dcx	d	;DE = pd.stkptr-2 (PUSHed)
	mov	m,d
	dcx	h
	mov	m,e
	inx	h
	inx	h
	inx	h
	inx	h
	mov	a,m
	ori	80h
	mov	m,a
	lhld	tparam
	xchg
	lxi	b,abortcode
	mov	m,c
	inx	h
	mov	m,b
	inx	h
	mov	m,e
	inx	h
	mov	m,d
	ei
	xra	a
	ret

abortcode:
	di
	mvi	c,143
	pop	d
	jmp	xdos

	dseg
tparam:	ds	2
	cseg

;        end;


;        /* function = 158, Attach List */
;        do;
@40:
;          enter$region;
	DI
;          rlrpd.status = attach$list$status;
	XCHG
	MVI	M,0DH
;        end;
	RET

;        /* function = 159, Detach List */
;        do;
@41:
;          enter$region;
	DI
;          rlrpd.status = detach$list$status;
	XCHG
	MVI	M,0EH
;        end;
	RET

;        /* function = 160, Set List */
;        do;
@42:
;          rlrpd.console = parameter;
	mov	a,c
	ral
	ral
	ral
	ral
	mov	c,a
	lxi	h,0eh-02h
	dad	d	;HL = .rlrpd.console
	mov	a,m
	ani	0fh
	ora	c
	mov	m,a
	pop	h	;discard EXDOS return
;        end;
	RET

;        /* function = 161, Conditional Attach List */
;        do;
@43:
;          enter$region;
	DI
	lhld	rlr
	xchg		;DE = Ready List Root
	lxi	h,0eh	;rlrpd.console offset
	dad	d
	mov	a,m
	ani	0f0h
	rrc
	rrc
	rrc
	rrc
	lxi	h,lstatt
	jmp	attcmn
;        end;
	RET

;        /* function = 162, Conditional Attach Console */
;        do;
@44:
;          enter$region;
	DI
	lhld	rlr
	xchg		;DE = Ready List Root
	lxi	h,0eh	;rlrpd.console offset
	dad	d
	mov	a,m
	ani	0fh
	lxi	h,cnsatt
attcmn:
	add	a
	mov	c,a
	mvi	b,0
	dad	b
	mov	a,m
	cmp	e
	inx	h
	jnz	@44a
	mov	a,m
	cmp	d
	jz	@44b
@44a:
	mov	a,m
	dcx	h
	ora	m	;testing for non-attached
	jnz	@44b
	mov	m,e
	inx	h
	mov	m,d
	xra	a
@44b:
	mvi	a,0
	rz
	dcr	a
;        end;
	RET

;        /* function = 163, Return MP/M Version Number */
;        do;
@45:
	pop	h	;discard EXDOS return
	lhld	mpmver
;        end;
	RET

;        /* function = 164, Get List Number */
;        ret = rlrpd.console$list;
@46:
	LXI	B,0CH
	XCHG
	DAD	B
	MOV	A,M
	rlc
	rlc
	rlc
	rlc
	ani	0fh
	RET

;      end; /* case */
@37:
	DW	ABSRQ
	DW	RELRQ
	DW	MEMFR
	DW      @7
	DW	FLGWT
	DW	FLGSET
	DW	MAKEQ
	DW	OPENQ
	DW	DELETQ
	DW	READQ
	DW	CREADQ
	DW	WRITEQ
	DW	CWRITEQ
	DW      @17
	DW      @18
	DW      @19
	DW      @20
	DW      @21
	DW      @22
	DW      @23
	DW      @24
	DW	ASSIGN
	DW      @26
	DW      @27
	DW	@31
	DW      @32
	DW      @33
	DW      @34
	dw	rtnpdadr
	dw	abort
	dw	@40
	dw	@41
	dw	@42
	dw	@43
	dw	@44
	dw	@45
	dw	@46
maxfunc	equ	($-@37)/2

;      if function <> flag$set$function then
;      do;
;        if function <> flag$wait$function then
;        do;
;          call dispatch;
;        end;
;      end;
;      return ret;
EXDOS:
	MVI	H,0
	MOV	L,A
	RET
;    end xdos;

delpr0:
	mov	b,h
	mov	c,l
;  delete$process:
;    procedure (nxtpdladr,pdadr) public;
delpr:
	public	delpr
;      declare (nxtpdladr,pdadr) address;
;      declare pdladr based nxtpdladr address;
	ldax	b
	mov	l,a
	inx	b
	ldax	b
	dcx	b
	mov	h,a
	ora	l
	rz		;end of list with no match
	mov	a,l
	cmp	e
	jnz	delpr0
	mov	a,h
	cmp	d
	jnz	delpr0
	mov	a,m	;found match, update pointers
	stax	b
	inx	h
	inx	b
	mov	a,m
	stax	b
	stc		;indicate success
	ret
;end xdos;
	END
