;(overscan_lib.asm)

;    overscan
;   ----------

;   By Ari Freund - 20/11/87

; Patches up the Intuition library so that sizable windows with MaxHeight = 200
; (or 400 in lace), and screens with Height = 200 (or 400 in lace) will take
; advantage of the PAL overscan capability of Intuition V1.2.

; To install the patch type: overscan
; To remove it type:         overscan delete

; Compile and assemble using Aztec C V3.40a:cc overscan.c +C +D
;                                           as overscan_lib.asm
; Create a library file using the librarian:lb overscan.lib overscan_lib.o
; Link using Aztec C V3.40a:                ln +S overscan.o overscan.lib c.lib

; You may also execute the overscan.make file.

; This part contains the patch itself and should be linked to 'overscan.o'
; which installes and deletes it.

; See overscan.doc for more information.
;-------------------------------------------------------------------------------

		far	code
		far	data

		nolist
		include	"intuition/intuition.i"
		list

ib_Preferences	equ	868		;pointer to Preferences in Intuition.lib

addq.l_1	equ	$52b9		;opcode for: "addq.l   #1,in_use"
subq.l_1	equ	$53b9		;opcode for: "subq.l   #1,in_use"

INC_IN_USE	macro			;  addq.l   #1,in_use
		dc.w	addq.l_1	;Flag patch as in use.
		dc.l	in_use
		endm

DEC_IN_USE	macro			;  subq.l   #1,in_use
		dc.w	subq.l_1	;Flag patch as not in use.
		dc.l	in_use
		endm

; Data items are placed in the code segment in order for the entire patch
; to be contained within a single segment.

		cseg

; ATTENTION!!
; The following data items MUST appear in the following precise order!

; The following chunk of variables is identified by the external symbol
; '_data' so C programs can refer to them as members in the 'data' struct.

_data:

;Initialize the Node substructure in the message port.
port		ds.l	2		; ln_Succ and ln_Pred
		dc.b	NT_MSGPORT	; ln_Type
		dc.b	0		; ln_Pri
		dc.l	_myname		; ln_Name
;Allocate the rest of the port.
		ds.b	MP_SIZE-LN_SIZE
		cnop	0,2
myseg		ds.l	1		;pointer to this segment
oldscreen_adr	ds.l	1		;pointer to Intuition's OpenScreen()
oldwindow_adr	ds.l	1		;pointer to Intuition's OpenWindow()
in_use		dc.l	0		;flag indicating patch is/isn't in use
_IntuitionBase	ds.l	1		;pointer to Intuition
_myname		dc.b	"Ari's: overscan message port",0

		public	_data,_IntuitionBase,_myname
		public	in_use

; O.K., here come the routines themselves.

;   This routine is called from Intuition's (patched) vector table
;   each time somebody calls OpenScreen().

;     if
;        not a custom bitmap
;        and height is the maximum for the American standard (lace/no lace)
;     then set height to the maximum for this Amiga.

	cnop	0,2				;allign to word boundry

	public	_screenpatch
_screenpatch:

	INC_IN_USE

	move.w	ns_Height(a0),-(sp)		;Save height.
	move.l	a0,-(sp)			;Save pointer to NewScreen.

	move.w	ns_Type(a0),d0			;Is it a custombitmap screen?
	andi.w	#CUSTOMBITMAP,d0	
	bne	openscreen			;Yes - open it with no change.

	move.w	#200,d0 			;Maxheight is 200.
	move.w	ns_ViewModes(a0),d1		;If in lace double it to 400.
	andi.w	#V_LACE,d1
	beq	dotest
	asl.w	#1,d0
dotest:
	cmp.w	ns_Height(a0),d0		;Does Height=maxheight?
	bne	openscreen			;No - open screen with no change
	move.w	#STDSCREENHEIGHT,ns_Height(a0)	;Set to maxheight for this Amiga

openscreen:
	move.l	oldscreen_adr,a1		;Call Intuition to open screen.
	jsr	(a1)

	move.l	(sp)+,a0			;Restore height.
	move.w	(sp)+,ns_Height(a0)

	DEC_IN_USE

	rts


;   This routine is called from Intuition's (patched) vector table
;   each time somebody calls OpenWindow().

;     if
;        not a super bitmap
;        and windowsizing gadget is attached
;        and
;            either
;                   screen is a custom screen
;                   and screen is big enough
;                   and max height for the window is the American standard max
;             or
;                   screen is wb
;                   and max height for the window is the American standard max
;     then set max height to the maximum for this Amiga.

	public	_windowpatch
_windowpatch:

	INC_IN_USE

	move.w	nw_MaxHeight(a0),-(sp)		;Save max height.
	move.l	a0,-(sp)			;Save pointer to NewWindow.

	move.l	nw_Flags(a0),d0			;Is it a super bitmap window?
	andi.l	#SUPER_BITMAP,d0
	bne	openwindow			;Yes - open it with no change.

	move.l	nw_Flags(a0),d0			;Is a sizing gadget attached?
	andi.l	#WINDOWSIZING,d0
	beq	openwindow			;No - open window with no change

	move.w	#200,d0				;Maxheight is 200.
	cmpi.w	#CUSTOMSCREEN,nw_Type(a0)	;Is it in a custom screen?
	bne	checkwb				;No - go check for WB screen.

	move.l	nw_Screen(a0),a1
	cmpi.w	#256,sc_Height(a1)		;Is screen big enough?
	bne	openwindow			;No - open window with no change

	move.w	sc_ViewPort+vp_Modes(a1),d1	;If in lace...
	andi.w	#V_LACE,d1			;...double maxheight to 400.
	beq	dotest1
	asl.w	#1,d0
dotest1:
	cmp.w	nw_MaxHeight(a0),d0		;Does MaxHeight=maxheight?
	bne	openwindow			;No - open window with no change

	move.w	#STDSCREENHEIGHT,nw_MaxHeight(a0)

openwindow:
	move.l	oldwindow_adr,a1		;Call Intuition to open window.
	jsr	(a1)

	move.l	(sp)+,a0			;Restore MaxHeight.
	move.w	(sp)+,nw_MaxHeight(a0)

	DEC_IN_USE

	rts

checkwb:
	cmpi.w	#WBENCHSCREEN,nw_Type(a0)	;Is it the wb screen?
	bne	openwindow			;Unknown type - don't change.

	move.l	_IntuitionBase,a1
	move.l	ib_Preferences(a1),a1
	cmpi.b	#LACEWB,pf_LaceWB(a1)		;If in lace double max height...
	bne	dotest1				;...to 400.
	asl.w	#1,d0
	bra	dotest1				;Go do the change if needed.

	end
