__LFN__		EQU 	1	; use long file names
__MOUSE__ 	EQU 	1	; use mouse

include	inc/macro.inc
include	inc/dir.inc
include	inc/dos.inc
include	inc/stdio.inc
include	inc/doszip.inc

MAXENTRYNAME	= 512

ENOENT		= 2

ER_EXEC		= 2
ER_ZIP		= 2
ER_BADERR	= 3
ER_MEM		= 4
ER_CRCERR	= 5
ER_NOZIP	= 9
ER_FIND		= 11
ER_OPEN		= 12
ER_DISK		= 50
ER_USERABORT	= 66
ER_READARCH	= -2
ER_DISK_FULL	= 112
ER_NEGATIVE_SEEK = 131

; DLL functions

dll_read	PROTO PASCAL, wsub:dword
dll_copy	PROTO PASCAL wsub:dword, fblk:dword, outp:dword
dll_add		PROTO PASCAL wsub:dword, wsub:dword, fblk:dword
dll_move	PROTO PASCAL wsub:dword, fblk:dword, wsub:dword
dll_mkdir	PROTO PASCAL wsub:dword, directory:dword
dll_delete	PROTO PASCAL wsub:dword, fblk:dword
dll_rename	PROTO PASCAL wsub:dword, fblk:dword
dll_edit	PROTO PASCAL wsub:dword, fblk:dword
dll_view	PROTO PASCAL wsub:dword, fblk:dword
dll_property	PROTO PASCAL wsub:dword, fblk:dword
dll_enter	PROTO PASCAL wsub:dword, fblk:dword

DLL_Header	MACRO ?PROC, ?FLAG, DLLVERS
	db	'DZ'		; signature
	dw	VERSION		; doszip version
	dw	DLLVERS		; plugin version
$FLAG	dw	?PROC		; functions supported
	dw	?FLAG		; functions that need $PROG
$SIG0	dw	?		; magic signature of archive
$SIG2	dw	?		; set by dll_init(console, stack, magic)
$STACK	dw	?		; stack offset
__mouse	db	1		; installed
__mbool	db	1		; visible
__mflag	db	0		; mouse state
_scrseg	dw	0B800h		; screen segment
_scrcol	db	80		; screen size
_scrrow	db	25
	ENDM

DLL_Startup	MACRO ?PROC, ?FLAG
	org	100h
start:	push	bp		; clear carry flag - assuming success
	mov	bp,sp
	and	byte ptr [bp+6],not 1
	pop	bp
	or	ah,ah
	jnz	DLL_01
    DLL_00:		; 00 dll_init(console, stack, magic)
	mov	cs:__mouse,dh	; console values from dzmain.exe
	mov	cs:__mbool,al
	mov	cs:__mflag,dl
	mov	cs:_scrseg,cx
	mov	cs:_scrcol,bl
	mov	cs:_scrrow,bh
	mov	cs:$SIG0,di	; signature for this archive
	mov	cs:$SIG2,si
	mov	cs:$STACK,es	; stack top -- size(SP-$STACK)
  ifdef DEBUG
	mov	cs:reg_st,es	; ST: <value>
  endif
	jmp	dll_init	; Direct jump to install proc
    DLL_01:		; 01 dll_read(wsub:dword)
	dec	ah
	jnz	DLL_02
	invoke	dll_read, ss::bx
	iret
   DLL_02:		; 02 dll_copy(wsub:dword, fblk:dword, outpath:dword)
	dec	ah
	jnz	DLL_03
  if (?PROC and __DLL_02)	; only implement functions defined
   if (?FLAG and __DLL_02)	; include test if function need $PROG
	test	cs:$FLAG,__DLL_02
	jz	DLL_NOTSUP
   endif
	invoke	dll_copy, ss::bx, es::cx, ss::dx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_03:		; 03 dll_add(wsub:dword, wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_04
  if (?PROC and __DLL_03)
   if (?FLAG and __DLL_03)
	test	cs:$FLAG,__DLL_03
	jz	DLL_NOTSUP
   endif
	invoke	dll_add, ss::bx, ss::dx, es::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_04:		; 04 dll_move(wsub:dword, fblk:dword, wsub:dword)
	dec	ah
	jnz	DLL_05
  if (?PROC and __DLL_04)
   if (?FLAG and __DLL_04)
	test	cs:$FLAG,__DLL_04
	jz	DLL_NOTSUP
   endif
	invoke	dll_move, ss::bx, ss::dx, es::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_05:		; 05 dll_mkdir(wsub:dword)
	dec	ah
	jnz	DLL_06
  if (?PROC and __DLL_05)
   if (?FLAG and __DLL_05)
	test	cs:$FLAG,__DLL_05
	jz	DLL_NOTSUP
   endif
	invoke	dll_mkdir, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_06:		; 06 dll_delete(wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_07
  if (?PROC and __DLL_06)
   if (?FLAG and __DLL_06)
	test	cs:$FLAG,__DLL_06
	jz	DLL_NOTSUP
   endif
	invoke	dll_delete, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_07:		; 07 dll_rename(wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_08
  if (?PROC and __DLL_07)
   if (?FLAG and __DLL_07)
	test	cs:$FLAG,__DLL_07
	jz	DLL_NOTSUP
   endif
	invoke	dll_rename, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_08:		; 08 dll_edit(wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_09
  if (?PROC and __DLL_08)
   if (?FLAG and __DLL_08)
	test	cs:$FLAG,__DLL_08
	jz	DLL_NOTSUP
   endif
	invoke	dll_edit, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_09:		; 09 dll_view(wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_0A
  if (?PROC and __DLL_09)
   if (?FLAG and __DLL_09)
	test	cs:$FLAG,__DLL_09
	jz	DLL_NOTSUP
   endif
	invoke	dll_view, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_0A:		; 0A dll_property(wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_0B
  if (?PROC and __DLL_0A)
   if (?FLAG and __DLL_0A)
	test	cs:$FLAG,__DLL_0A
	jz	DLL_NOTSUP
   endif
	invoke	dll_property, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_0B:		; 0B dll_enter(wsub:dword, fblk:dword)
	dec	ah
	jnz	DLL_0C
  if (?PROC and __DLL_0B)
   if (?FLAG and __DLL_0B)
	test	cs:$FLAG,__DLL_0B
	jz	DLL_NOTSUP
   endif
	invoke	dll_enter, ss::bx, dx::cx
	iret
  else
	jmp	DLL_NOTSUP
  endif
   DLL_0C:
	dec	ah
   DLL_0D:
	dec	ah
   DLL_0E:
	dec	ah
   DLL_0F:
	dec	ah
   DLL_10:
	dec	ah
   DLL_11:
	dec	ah
	jnz	DLL_NOTSUP
	jmp	dll_exit		; direct jump to exit proc
DLL_NOTSUP:
	mov	ah,0
	push	si
	mov	si,sp
	or	byte ptr [si+6],1	; set carry flag
	pop	si
	iret
	ENDM

