
%if 0

lDOS DOSENTRY handling
 by C. Masloch, 2018

Usage of the works is permitted provided that this
instrument is retained with the works, so that any entity
that uses the works is notified of this instrument.

DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

%endif

%if 0

The DOSENTRY section is always located at segment 70h. It includes some data
structures found in MS-DOS (most notably the Int19 interrupt restoration table
at 70h:100h), the device headers for all default devices (except NUL) and all
code entries into the DOS code. If the DOS code is not relocateable, DOSENTRY
and DOSCODE are merged into one section.

Relocated entries which are in DOSENTRY for relocation:
Interrupt 00h		Division error exception
Interrupt 06h		Invalid opcode exception
Interrupt 13h		BIOS disk services
Interrupt 19h		Reboot
Interrupt 1Bh		Ctrl-Break notification
Interrupt 20h		Terminate program
Interrupt 21h		DOS services
Interrupt 25h		Absolute disk read
Interrupt 26h		Absolute disk write
Interrupt 27h		Terminate and stay resident
Interrupt 28h		Idle
Interrupt 29h		Display character
Interrupt 2Fh		Multiplex, DOS services
CALL 5			CP/M compatibility services (subset of interrupt 21h)
Device strategy		All device functions
Case map function	Maps language-specific characters >=80h to uppercase
Redirector mapper	Maps unhandled redirector calls to MS-DOS interface

If DOSCODE is not the same section as DOSENTRY (if DOSCODE is relocateable),
each of the relocated entries calls relocatedentry with a parameter behind the
near call opcode. The near call opcode and the word sized parameter for each
entry need 5 byte. relocatedentry insures that DOSCODE is available (switches
the A20 line on if DOSCODE is in the HMA) and jumps to the far address
DOSCODE:parameter. relocatedentry detects whether the parameter equals the
device strategy code address and will read two more parameters used by that
code from the entry. (Which are the pointer to the device's function table in
DOSCODE and an optional device unit number.)

Entries which are in DOSENTRY but don't execute code in DOSCODE:
Interrupt 23h		Always terminates application
Interrupt 24h		Always fails call
Interrupt 2Eh		Always reports error
Device interrupt	MS-DOS device compatibility (does nothing)
Dummy file sharer	Always returns error 0001h (Invalid function)
Dummy redirector	Always returns error 0001h (Invalid function)
Other hooked interrupts	Do nothing

%endif

%include "RXDMACRO.NEW"


%assign _RELOCATEDOSCODE	1
%assign _FATFS			0
%assign _MAPPER			0
%assign _INT28			1
%assign _CALL5			1
%assign DEVStrategy		0

%if _RELOCATEDOSCODE
i00:	call relocatedentry, relocatedi00
i06:	call relocatedentry, relocatedi06
; i13:	call relocatedentry, relocatedi13
; i19:	call relocatedentry, relocatedi19
i19:	jmp Interrupt_19
; i1B:	call relocatedentry, relocatedi1B
i20:	xor ax, ax
i21:	call relocatedentry, relocatedi21
i25:	call relocatedentry, relocatedi25
i26:	call relocatedentry, relocatedi26
i27:	call relocatedentry, relocatedi27
 %if _INT28
i28:	call relocatedentry, relocatedi28
 %endif
; i29:	call relocatedentry, relocatedi29
i29:	jmp Interrupt_29
i2F:	call relocatedentry, relocatedi2F
 %if _CALL5
call5:	call relocatedentry, relocatedcall5
 %endif
; casemap:call relocatedentry, relocatedcasemap
 %if _FATFS
fatfs:	jmp short .jump
.next:	jmp FIXDOSENTRY:mapper
.jump:	call relocatedentry, relocatedfatfs
fatfs2:	jmp short .jump
.next:	jmp FIXDOSENTRY:NotHooked
.jump:	call relocatedentry, relocatedfatfs2
 %endif
 %if _MAPPER
mapper:	call relocatedentry, relocatedmapper
 %endif
%endif

i23:
	stc
	retf

i24:
	mov al, 03h
entry_iret:
	iret


	%imacro irtentry 1.nolist
db %1
dd 0
	%endmacro


%assign num 256-($-$$)
%warning num bytes in front of IRT

	_fill 256, 0, dosentry_start
InterruptRestorationTable:
	irtentry 10h
	irtentry 13h
	irtentry 15h
	irtentry 19h
	irtentry 1Bh
		; Above interrupts are in the order MS-DOS 6.x saves them
		;  (FDEMM386?/Jemm expects Int19 within the first five entries)

	irtentry 00h
	irtentry 01h
	irtentry 03h
	irtentry 04h
	irtentry 06h
	irtentry 08h
	irtentry 16h
	irtentry 1Ch
	irtentry 1Eh
	irtentry 21h
	irtentry 23h
	irtentry 24h
	irtentry 29h
	irtentry 2Fh
	irtentry 33h
	db -1


%if _RELOCATEDOSCODE
		; INP:	cs:ip-> relocated entry address (word),
		;		optional pointer to device function table (word),
		;		optional device unit (word)
		; OUT:	Returns to DOSCODE:(relocated entry address)
		;	If the relocated entry address is DEVStrategy,
		;	 ss:sp-> device unit or garbage (word),
		;		 pointer to device function table (word)
		; CHG:	- (not even flags!)
		; STT:	-
		; STK:	12 word or 9 word + XMS driver
relocatedentry:						; _devicefunctiontable, 1
	push cs						; _deviceunit, 2
	jmp 70h:.fixsegment				; insure cs = 70h
.fixsegment:
	push ax						; ax restored from this word (_executecode+_segment)
	push ax						; _executecode
	pushf						; _extern, 5 argument words (%2 of _specialentry)
	push ds
	push si
	push bp						; 3 more words (%1 of _specialentry)
	setDS cs
	cld

	mov bp, sp

	_specialentry 3,5,0
	darg parameterpointer
	rarg devicefunctiontable, _parameterpointer + 2	; re-used
	rarg deviceunit, _parameterpointer + 0		; re-used
	darg executecode
	arg extern
	mov ds, word [ bp + _parameterpointer + 0 ]	; can't use lds si, offset and segment swapped
	mov si, word [ bp + _parameterpointer + 2 ]	; ds:si-> parameters (behind near call opcode)
	lodsw
	mov word [ bp + _executecode +_pointer ], ax	; store relocated entry address in DOSCODE
	cmp ax, DEVStrategy				; is it a device entry ?
	lodsw
	mov word [ bp + _devicefunctiontable ], ax	; store device function table if true
	lodsw
	mov word [ bp + _deviceunit ], ax		; store device unit if true
	mov ax, word [ cs:doscode_segment ]
	xchg ax, word [ bp + _executecode +_segment ]	; store DOSCODE and restore ax
	pop bp
	pop si
	pop ds
	jne .nodeviceentry				; no, remove device parameters from stack -->
							; (Flags must not have changed since the cmp instruction!)
	popf
	retf
		; Relocated DEVStrategy entry: Called with device function table and device
		; unit parameters on stack. Any register and flags left unchanged.

.nodeviceentry:
	popf
	retf 2*2
		; Any other relocated entry: Stack, any register and flags left unchanged.
%endif


%include "RxBIO.ASM"

