/* asmsup.c
**
** This is the assembler support code used by PP. It contains code for
** patching the DOS library. Context sensitivity has been added since
** v1.1 - these routines now act differently when running under DOS2.0
**
** Freeware 1991, Copyright (C) 1991 by Michael Berg
*/

#asm
DOSLibPatch	MACRO
		public	_Real\1
		public	_New\1
		public	_Make\1
		public	_Rest\1
		public	_LVO\1
		public	\2

_Make\1		movem.l	a6/d0-d2,-(sp)		;save registers
		move.l	\2,a6			;store DOSBase in a6
		movem.w	_LVO\1(a6),d0-d2	;get the 3-word original seq.
		movem.w	d0-d2,Orig\1		;save these words
		cmp.w	#$4ef9,d0		;determine state of DOS vect.
		bne.s	1$			;original 1.2/1.3 DOS code

		lea	_Real\1,a0		;takes care of 2.0/already
		move.l	_LVO\1+2(a6),d0		;patched code. Get the JMP
		move.l	d0,4(a0)		;target and create our own
		move.w	#$4e71,(a0)		;little code stub. 4e71='NOP'
		lea	_New\1,a0		;(we will not be needing the
		move.l	a0,d0			;moveq)
		move.l	d0,_LVO\1+2(a6)
		bra.s	2$

1$		lea	_LVO\1(a6),a6
		moveq	#0,d0
		lea	_Real\1,a0
		move.w	(a6),(a0)	;fetch the 'moveq #?,d0' opcode
		move.w	4(a6),d0	;fetch the 'bra' offset
		add.l	a6,d0		;add to find branch target
		addq.l	#4,d0		;pc relative offset compensation
		move.l	d0,4(a0)	;we need this so we can jump directly
		move.w	#$4ef9,(a6)	;initiate new sequence: jmp $abs_addrs
		move.l	#_New\1,2(a6)	;jump to our new function, of corz!
2$		movem.l	(sp)+,a6/d0-d2	;restore regs
		rts

_Real\1		moveq	#0,d0		;moveq value will be ajusted
		jmp	$fffffe		;the JMP address will be fixed

		dseg
Orig\1		dc.w	0,0,0
		cseg

_Rest\1		move.w	d2,-(sp)
		move.l	\2,a0
		movem.w	Orig\1,d0-d2
		movem.w	d0-d2,_LVO\1(a0)
		move.w	(sp)+,d2
		rts
		ENDM

;DOSLibPatch is a macro which defines three functions. For Open(), they are:
;
;MakeOpen	- Patch the DOS library Open() vector
;RestOpen	- Restore the DOS library to it's original state
;RealOpen	- This calls the original DOS function
;
;Furthermore, you yourself have to create a function called (in this case)
;NewOpen, with a parameter specification like Open(). Future calls to Open
;will be redirected to NewOpen. NewOpen has access to the original DOS code
;through the function RealOpen. RealOpen should also be defined like Open.
;More details follow. For now, you need to know that DOSLibPatch works only
;with the DOS library, which differes in format from other libraries. Also
;note that these functions are sensitive to their environment. Versions 1.2
;and 1.3 of the OS has this weird looking DOS library, where 2.0 has had its
;DOS library normalized to conform to the appearance of the other libraries.
;The global variable 'os20' controls the flow of these functions. If running
;under 2.0, this variable MUST be set to a non-zero value.

		XREF	_os20

		DOSLibPatch Open,_DOSBase
		DOSLibPatch Close,_DOSBase
		DOSLibPatch Examine,_DOSBase
		DOSLibPatch Write,_DOSBase
#endasm
