	NAME pcgen
	include	pmacros.h

dseg
pubvar	mtasker,<db ?>
dsegend

if TURBO
else
; setvect - set interrupt vector
; called from C as follows
; setvect(vec,vecval)
; char vec;		/* Interrupt number */
; void (*vecval)();	/* offset (and segment in large code model) */

	procdef	setvect,<<vec,byte>,<ipval,fptr>>
	mov	ah,25h
	mov	al,vec
	push	ds		; save
ifdef	LARGECODE
	lds	dx,ipval
else
	mov	dx,ipval
	push	cs
	pop	ds
endif
	int	21h
	pop	ds		; restore
	pret
	pend	setvect

; getvect - return current interrupt vector
; called from C as
; long		/* Returns CS in high word, IP in low word */
; getvect(vecnum)
; char vecnum;	/* Interrupt number */

	procdef	getvect,<<vecnum,byte>>
	mov	ah,35h
	mov	al,vecnum
	push	es	; save, since DOS uses it for a return value
	int	21h
	mov	dx,es	; CS value into DX (C high word)
	mov	ax,bx	; IP value into AX (C low word)
	pop	es	; restore es
	pret
	pend	getvect
endif

; kbraw - raw, nonblocking read from console
; If character is ready, return it; if not, return -1

	procdef kbraw
	mov	ah,06h	; Direct Console I/O
	mov	dl,0ffh ; Read from keyboard
	int	21h	; Call DOS
	jz	nochar	; zero flag set -> no character ready
	mov	ah,0	; valid char is 0-255
	pret
nochar:
	mov	ax,-1	; no char, return -1
	pret
	pend	kbraw

; disable - disable interrupts and return previous state: 0 = disabled,
;           1 = enabled

 if	TURBO
	procdef	Disable
 else
	procdef	disable
 endif
	pushf			; save state on stack
	cli			; interrupts off
	pop	ax		; original flags -> ax
	and	ax,200h		; 1<<9 is IF bit
	jnz	ion		; nonzero -> interrupts were on
	pret
ion:	mov	ax,1
	pret
 if	TURBO
	pend	Disable
 else
	pend	disable
 endif

; restore - restore interrupt state: 0 = off, nonzero = on

	procdef	restore,<<istate,byte>>
	test	istate,0ffh
	jz	ioff
	sti
ioff:	pret
	pend	restore

; Halt until an interrupt occurs, then return
	procdef eihalt
	sti	; make sure interrupts are enabled
	hlt
	pret
	pend	eihalt

; multitasker types
NONE		equ	0
DOUBLEDOS	equ	1
DESQVIEW	equ	2

; Relinquish processor so other task can run
	procdef	giveup
	cmp	mtasker@,DOUBLEDOS
	jnz	givedesqview
	mov	al,2		; 110 ms
	mov	ah,0eeh
	int	21h

givedesqview:
	cmp	mtasker@,DESQVIEW
	jnz	notask
	mov	ax,1000h
	int	15h
notask:
	pret
	pend	giveup

; check for a multitasker running
	procdef chktasker
	mov	mtasker@,NONE
	; do the doubledos test
	mov	ah,0e4h
	int	21h
	cmp	al,1
	jz	isdos
	cmp	al,2
	jnz	test_desq
isdos:	mov	mtasker@,DOUBLEDOS
	pret

	; test for desqview
test_desq:
	mov	ax,2b01h
	mov	cx,4445h
	mov	dx,5351h
	int	21h
	cmp	al,0ffh
	jnz	isdesq
	pret
isdesq:	mov	mtasker@,DESQVIEW
	pret
	pend	chktasker

; getds - Read DS for debugging purposes
	procdef	getds
	getds
	pret
	pend	getds
;
; dos service routine used by JK1NNT installed by N3EUA
;

	procdef	jkintdos,<<reg_a,word>,<reg_b,word>,<reg_d,word>>
	mov	ax,reg_a
	mov	bx,reg_b
	mov	dx,reg_d
	int	21h
	pret
	pend	jkintdos
;
; NEC PC-9801 speed setting routine by JK1NNT installed by N3EUA
;
	procdef	set_speed,<<s_code,word>>
	push	ds
	mov	ax,40h
	mov	ds,ax
	mov	dx,s_code
	mov	ds:[269h],dl
	mov	dh,4ch
	mov	ds:[268h],dh
	pop	ds
	mov	cl,0ah
	int	0dch
	pret
	pend	set_speed

;
; This routine is a generic int 21h handler, is used only by disk free
; routine.  Added by K3MC  3 Dec 87
;
;
; General-purpose int 21h caller, currently used only to return AX, BX, CX, DX
; for computing amount of free disk space, and amount of total disk space.
;
; declared as: void isfree();
;
; Called from C as:
;
; isfree(&ax,&bx,&cx,&dx)
; unsigned short ax,bx,cx,dx;
;
	procdef	isfree,<<c_ax,ptr>,<c_bx,ptr>,<c_cx,ptr>,<c_dx,ptr>>
	push	ax
	push	bx
	push	cx
	push	dx
	push	bp
	push	si
	push	di
	pushds
	ldptr	di,c_ax,ds
	mov	ax,[di]
	ldptr	di,c_bx,ds
	mov	bx,[di]
	ldptr	di,c_cx,ds
	mov	cx,[di]
	ldptr	di,c_dx,ds
	mov	dx,[di]
	int 	21h
	ldptr	di,c_ax,ds
	mov	[di],ax
	ldptr	di,c_bx,ds
	mov	[di],bx
	ldptr	di,c_cx,ds
	mov	[di],cx
	ldptr	di,c_dx,ds
	mov	[di],dx
	popds
	pop	di
	pop	si
	pop	bp
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	pret
	pend	isfree

; Return 03 in AL to fail a critical error

	pubproc	crit_hdl
	mov	al,3
	iret
	pend	crit_hdl

	end
