
_TEXT		SEGMENT  DWORD PUBLIC 'CODE'
_TEXT		ENDS
_DATA		SEGMENT  WORD PUBLIC 'DATA'
_DATA		ENDS
CONST		SEGMENT  WORD PUBLIC 'CONST'
CONST		ENDS
_BSS		SEGMENT  WORD PUBLIC 'BSS'
_BSS		ENDS
_INST		SEGMENT  WORD PUBLIC 'INST'
_INST		ENDS
DGROUP		GROUP	_TEXT,	CONST,	_BSS,	_DATA,	_INST

dev_hed		struc
dev_next	dd	0
dev_sts		dw	0
str_ent		dw	0
int_ent		dw	0
res		db	8 dup (0)
dev_hed		ends

DEV_HED_SIZ	equ	size dev_hed

MAX_DEV		equ	16

extrn		_dmy_dev:near
extrn		_req_ptr:near
extrn		_Device_entry:near
extrn		_setup:near
extrn		_tmp:dword
extrn		_SecLen:word
extrn		_psp_seg:word

_TEXT		SEGMENT
		ASSUME  CS: DGROUP, DS: DGROUP, SS: DGROUP

		org	02ch
EnvSeg		label	word

		org	080h
CmdsLine	label	byte

		org	100h
		public	entry
entry:		jmp	main

bak_ds_seg	dw	?
bak_es_seg	dw	?
dev_tbl		dev_hed	16 dup (<>)

ax_reg		dw	?
bx_reg		dw	?
cx_reg		dw	?
dx_reg		dw	?
si_reg		dw	?
di_reg		dw	?
bp_reg		dw	?
ds_reg		dw	?
es_reg		dw	?

DMY_STR		macro	n
_str_ent&n&	proc	far
		push	ds
		mov	ds,cs:bak_ds_seg
		mov	word ptr [_req_ptr+n*4],bx
		mov	word ptr [_req_ptr+n*4+2],es
		pop	ds
		ret
_str_ent&n&	endp
		endm

DMY_ENT		macro	n
_int_ent&n&	proc	far
		pushf
		mov	cs:ax_reg,ax
		mov	ax,n
		jmp	_int_ent_all
_int_ent&n&	endp
		endm

DMY_SET		macro	n
		mov	cs:[bx].str_ent,offset DGROUP:_str_ent&n&
		mov	cs:[bx].int_ent,offset DGROUP:_int_ent&n&
		add	bx,DEV_HED_SIZ
		endm

_DevNum		=	0
	rept	MAX_DEV
		DMY_STR	%_DevNum
		DMY_ENT	%_DevNum
_DevNum		=	_DevNum + 1
	endm

_int_ent_all	proc	near
		mov	cs:bx_reg,bx
		mov	cs:cx_reg,cx
		mov	cs:dx_reg,dx
		mov	cs:si_reg,si
		mov	cs:di_reg,di
		mov	cs:bp_reg,bp
		mov	cs:ds_reg,ds
		mov	cs:es_reg,es

		cld
		mov	ds,cs:bak_ds_seg
		mov	es,cs:bak_es_seg
		push	ax
		call	_Device_entry
		pop	ax

		mov	es,cs:es_reg
		mov	ds,cs:ds_reg
		mov	bp,cs:bp_reg
		mov	di,cs:di_reg
		mov	si,cs:si_reg
		mov	dx,cs:dx_reg
		mov	cx,cs:cx_reg
		mov	bx,cs:bx_reg
		mov	ax,cs:ax_reg
		popf
		retf			; far return !!
_int_ent_all	endp

		public	_init_dmy_dev
_init_dmy_dev	proc	near
		push	bx
		mov	cs:bak_ds_seg,ds
		mov	cs:bak_es_seg,es

		mov	bx,offset DGROUP:dev_tbl

_DevNum		=	0
	rept	MAX_DEV
		DMY_SET	%_DevNum
_DevNum		=	_DevNum + 1
	endm

		mov	ax,offset DGROUP:dev_tbl
		mov	dx,cs

		pop	bx
		ret
_init_dmy_dev	endp

		public	_Dev_str_call
_Dev_str_call	proc	near
		push	bp
		mov	bp,sp
		push	bx
		push	es
		les	bx,[bp+4+4]
		call	dword ptr ss:[bp+4]
		pop	es
		pop	bx
		pop	bp
		ret
_Dev_str_call	endp

		public	_Dev_int_call
_Dev_int_call	proc	near
		push	bp
		mov	bp,sp
		call	dword ptr ss:[bp+4]
		pop	bp
		ret
_Dev_int_call	endp

		public	_farmemcpy
_farmemcpy	proc	near
		push	bp
		mov	bp,sp
		push	si
		push	di
		push	ds
		push	es

		les	di,[bp+4]
		lds	si,[bp+8]

		mov	cx,[bp+12]
		shr	cx,1
		jnc	_farmem2
		movsb

_farmem2:	jcxz	_farmem3
		rep movsw

_farmem3:	pop	es
		pop	ds
		pop	di
		pop	si
		pop	bp
		ret
_farmemcpy	endp


extrn		_SecLen:word

		public	_sum_calc
_sum_calc	proc	near
		push	bp
		mov	bp,sp
		push	si
		push	ds

		mov	cx,[bp+8]
		cmp	cx,_SecLen
		jb	_sum_c2
		mov	cx,_SecLen

_sum_c2:	lds	si,[bp+4]
		xor	ah,ah

_sum_loop:	lodsb
		add	ah,al
		loop	_sum_loop

		xor	al,al
		xchg	ah,al

		pop	ds
		pop	si
		pop	bp
		ret
_sum_calc	endp

		public	_get_DPB
_get_DPB	proc	near
		push	bp
		mov	bp,sp
		push	bx
		push	ds

		mov	ah,32h
		mov	dl,[bp+4]
		inc	dl
		int	21h
		jnc	_get_DPB2

		mov	ax,0FFFFh
		mov	dx,ax
		jmp	_get_DPB3

_get_DPB2:	mov	ax,bx
		mov	dx,ds

_get_DPB3:	pop	ds
		pop	bx
		pop	bp
		ret
_get_DPB	endp

		public	_link_DPB
_link_DPB	proc	near
		push	bp
		mov	bp,sp
		push	bx
		push	es

		mov	ah,52h
		int	21h
		mov	ax,es:[bx]
		mov	dx,es:[bx+2]

		pop	es
		pop	bx
		pop	bp
		ret
_link_DPB	endp

		public	_msg_disp
_msg_disp	proc	near
		push	bp
		mov	bp,sp

		mov	dx,[bp+4]
		mov	ah,9
		int	21h

		pop	bp
		ret
_msg_disp	endp

_TEXT		ENDS

_INST		segment
		ASSUME CS: DGROUP, DS: DGROUP, SS: DGROUP

Start_init	label	word

main		proc	near
		mov	ax,cs
		mov	ds,ax
		mov	es,ax
		mov	[_psp_seg],ax
		cld

		mov	sp,offset DGROUP:Local_Stack
		mov	bx,sp
		add	bx,15
		mov	cl,4
		shr	bx,cl
		mov	ah,4Ah
		int	21h

		mov	ax,offset DGROUP:CmdsLine
		push	ax
		call	_setup
		add	sp,2
		cmp	ax,0
		je	tsr_go

		mov	ax,4C00h		; End of
		int	21h

tsr_go:		mov	es,[EnvSeg]
		mov	word ptr [EnvSeg],0
		mov	ah,49h			; Free ENV Seg
		int	21h

		mov	dx,offset DGROUP:Start_init
		add	dx,15
		mov	cl,4
		shr	dx,cl

		mov	ax,cs
		add	ax,dx
		mov	word ptr [_tmp+2],ax
		mov	word ptr [_tmp],0

		mov	ax,[_SecLen]
		add	ax,15
		mov	cl,4
		shr	ax,cl
		add	dx,ax

		mov	ax,3100h		; TSR End of
		int	21h

main		endp

		public	_DOS_allocmem
_DOS_allocmem	proc	near
		push	bp
		mov	bp,sp
		push	bx

		mov	ah,48h
		mov	bx,[bp+4]
		int	21h
		jc	_D_alcerr

		mov	bx,[bp+6]
		mov	[bx],ax
		xor	ax,ax
		jmp	_D_alcend

_D_alcerr:	mov	ax,-1
_D_alcend:	pop	bx
		pop	bp
		ret
_DOS_allocmem	endp

		public	_DOS_memfree
_DOS_memfree	proc	near
		push	bp
		mov	bp,sp
		push	es

		mov	ax,[bp+4]
		mov	es,ax
		mov	ah,49h
		int	21h

		pop	es
		pop	bp
		ret
_DOS_memfree	endp

		db	1024 dup (?)
Local_Stack	label	word

_INST		ends
		END	entry
