	opt l-,c+,a+,p+    ;Executable,case-sensitive,auto PC,position independent
    
;{ ---------- Program name:- Window_Sizer ---------------------------------------------------------------------------- }

;{ ---------- Program Version 1.00 ----------------------------------------------------------------------------------- }
 
;{ ---------- Where to find include files ---------------------------------------------------------------------------- }

	incdir	"dh0:Hi-Soft/Include/"

;{ ---------- Include files required --------------------------------------------------------------------------------- }

	include	exec/exec_lib.i
	include	intuition/intuition_lib.i
	include	intuition/intuitionbase.i
	include	intuition/intuition.i
	include	libraries/dos_lib.i
	include	libraries/dos.i

;{----------- Macro CALLSYS ------------------------------------------------------------------------------------------ }

CALLSYS MACRO
			JSR	_LVO\1(A6)
			ENDM

;{----------- Defintions used in the program ------------------------------------------------------------------------- }

IntB			EQU		-4				;Reserved for intuition base address (long)
DosB			EQU		-8				;Reserved for dos base address (long)
WdAdd			EQU		-12				;Reserved for window base address (long)

TopOfWindow		EQU		-14				;
LeftEdge		EQU		-16				;Reserved for new window parameters
Width			EQU		-18				;(word)
Height			EQU		-20				;

Mul			EQU		-22				;Multiplication factor (m.f.)

;{----------- Open required libraries -------------------------------------------------------------------------------- }
 
Start			link		a5,#-22				;Reserve user stack space
			movem.l		d0/a0,-(sp)			;Save parameter data on system stack

OpenLibraries		moveq.l		#33,d0				;
			lea		IntName,a1			;Open intuition library version 1.2 or greater
			CALLEXEC	OpenLibrary			;
			move.l		d0,IntB(a5)			;
			beq		Error_No_Int			;

			moveq.l		#33,d0				;
			lea		DosName,a1			;Open dos library version 1.2 or greater
			CALLSYS		OpenLibrary			;
			move.l		d0,DosB(a5)			;
			beq		Error_No_Dos			;

;{----------- Routines ---------------------------------------------------------------------------------------------- }

;{----------- Get window base address ------------------------------------------------------------------------------- }

			move.l		IntB(a5),a0			;
			move.l		ib_ActiveWindow(a0),d0		;Get the address for the active window
			beq		Error_No_Window			;
			move.l		d0,WdAdd(a5)			;Save the base address
			movem.l		(sp)+,d0/a0			;Get parameter address back from stack				

;{----------- Get Parameters ---------------------------------------------------------------------------------------- }

			cmp.b		#1,d0				;See if any parameters passed
			beq.s		No_Parameters			;Go set default values
			adda.l		d0,a0				;
			subq		#1,a0				;
Return			cmp.b		#"?",-1(a0)			;
			beq		Help				;Display help screen
			cmp.b		#"s",-1(a0)			;
			beq.s		Small				;
			clr.l		d6				;
			bsr.s		Get				;
			move.w		d7,Height(a5)			;Calculate and store parameters for
			cmp.w		#256,d7				;
			bhi.s		JumpEm				;
			bsr.s		Get				;window positioning
			move.w		d7,Width(a5)			;
			cmp.w		#640,d7				;
			bhi.s		JumpEm				;
			bsr.s		Get				;
			move.w		d7,TopOfWindow(a5)		;
			cmp.w		Height(a5),d7			;
			bcc.s		JumpEm				;
			move.l		#1,d6				;
			bsr.s		Get				;
			move.w		d7,LeftEdge(a5)			;
			cmp.w		Width(a5),d7			;
			bcc.s		JumpEm				;

Cont			bra		Main				;

JumpEm			bra		ErrorMess			;Branch to error message routine

;{----------- Present Screen Sizes --------------------------------------------------------------------------------- }

No_Parameters		move.w		#0,TopOfWindow(a5)		;
			move.w		#0,LeftEdge(a5)			;Values for maximum window
			bra.s		BottomCorner			;

Small			move.w		#255,TopOfWindow(a5)		;
			move.w		#639,LeftEdge(a5)		;Values for minimum window
BottomCorner		move.w		#640,Width(a5)			;
			move.w		#256,Height(a5)			;
			bra.s		Cont

;{----------- Check Current Parameter ------------------------------------------------------------------------------ }

Get			clr.l		d1				;Setup variables required for routine
			clr.l		d7				;
			move.w		#1,Mul(a5)			;Set m.f. to 1
Search			subi		#1,d0				;
			cmp.b		#$20,-(a0)			;Skip spaces in parameter line
			bne.s		Again				;
			cmp		#0,d0				;
			bne.s		Search				;
Again			bsr.s		Test				;
			cmp.b		#0,d2				;See if present digit is valid
			beq.s		Skip				;Branch if o.k.
			cmp.b		#1,d2				;
			beq.s		End				;
			cmp.b		#1,d6				;
			bne.s		ErrorMess				;Check error not caused by end of
			cmp.b		#0,d0				;parameter list
			beq.s		End				;
			bra.s		ErrorMess			;
Skip			muls		Mul(a5),d1			;Multiply digit by multiplication factor
			add.w		d1,d7				;Add to running total
			move.w		Mul(a5),d3			;
			muls		#10,d3				;Make m.f.:=m.f. * 10
			move.w		d3,Mul(a5)			;
			cmp.w		#1000,d3			;See if all three digits have been processed
			bne.s		Again				;No
End			rts						;

;{----------- Test Present Digit ------------------------------------------------------------------------------------ }

Test			cmp.b		#$20,(a0)			;Check of current number has finished
			beq.s		Fin				;
			cmp.b		#"0",(a0)			;
			blt.s		Error				;See if digit is in allowed range
			cmp.b		#"9",(a0)			;
			bhi.s		Error				;
			move.b		(a0),d1				;Convert digit from ASCII to absolute
			subi		#48,d1				;
			subi		#1,d0				;
			suba		#1,a0				;
			clr.b		d2				;
			rts						;

Error			move.b		#2,d2				;Invalid parameter error
			rts						;

Fin			move.b		#1,d2				;End of current number
			rts						;

;{----------- Error Message Display --------------------------------------------------------------------------------- }

ErrorMess		lea		Error_Mess,a2			;Get details on error message and display
			move.l		a2,d2				;it on active window. (Keep position indi)
			move.l		#Error_Mess_Len,d3		;
			bra.s		Display				;

;{----------- Help display ------------------------------------------------------------------------------------------ }

Help			lea		Help_Text,a2			;Get details on help text and display it on
			move.l		a2,d2				;the active window
			move.l		#Help_Text_Len,d3		;(Keep position indipendent)
			
;{----------- Display requested text ------------------------------------------------------------------------------- }

Display						
			move.l		DosB(a5),a6			;Get output window address through DOS
			CALLSYS		Output				;
			move.l		d0,d1				;
			CALLSYS		Write				;Display Message

;{----------- Close open libraries ---------------------------------------------------------------------------------- }

CloseLibraries

Error_No_Window		move.l		DosB(a5),a1			;Close dos library
			CALLEXEC	CloseLibrary			;
Error_No_Dos		move.l		IntB(a5),a1			;Close graphics library
			CALLSYS		CloseLibrary			;

Error_No_Int		unlk		a5				;Destroy user stack
			rts						;Go home

;{----------- Zero window ------------------------------------------------------------------------------------------- }

Zero_Window		move.l		WdAdd(a5),a0			;Restore active window base address
			clr.l		d0				;
			sub.w		wd_LeftEdge(a0),d0		;Calculate offset to move window to 0,0
			clr.l		d1				;
			sub.w		wd_TopEdge(a0),d1		;
			bra.s		Test_Window			;

;{----------- Move the window --------------------------------------------------------------------------------------- }

Move_Window		move.l		WdAdd(a5),a0			;Restore active window base address
			clr.l		d0				;Clear the two data registers
			clr.l		d1				;
			move.w		LeftEdge(a5),d0			;
			sub.w		wd_LeftEdge(a0),d0		;Calculate the offset to move the window
			move.w		TopOfWindow(a5),d1		;
			sub.w		wd_TopEdge(a0),d1		;
Test_Window		tst.w		d0				;
			bne.s		Move_It				;Only move window if required
			tst.w		d1				;
			beq.s		Return1				;

Move_It			move.l		IntB(a5),a6			;Call move window routine
			CALLSYS		MoveWindow			;
Return1			bra.s		Wait				;

;{----------- Size the window --------------------------------------------------------------------------------------- }

Size_Window		move.l		WdAdd(a5),a0			;Restore active window base address
			clr.l		d0				;Clear two data registers
			clr.l		d1				;
			move.w		Width(a5),d0			;
			sub.w		wd_Width(a0),d0			;Calculate offset for sizing window
			sub.w		LeftEdge(a5),d0			;
			move.w		Height(a5),d1			;
			sub.w		wd_Height(a0),d1		;
			sub.w		TopOfWindow(a5),d1		;
			tst.w		d0				;
			bne.s		Size_It				;Only size window if required
			tst.w		d1				;
			beq.s		Wait				;

Size_It			move.l		IntB(a5),a6			;
			CALLSYS		SizeWindow			;Call size window routine


;{----------- Delay ------------------------------------------------------------------------------------------------- }

Wait			move.l		DosB(a5),a6			;
			move.l		#$05,d1				;Give small delay between moving and sizing
			CALLSYS		Delay				;the window
			rts						;

;{----------- Main -------------------------------------------------------------------------------------------------- }

Main			
			bsr.s		Zero_Window			;Move window to 0,0
			bsr.s		Size_Window			;Make window required size
			bsr.s		Move_Window			;Move window to required position
			bra 		CloseLibraries			;Close the libraries openned

;{----------- Error Message ----------------------------------------------------------------------------------------- }

Error_Mess		dc.b	$a,'Bad Args.',$a,$a
			
Error_Mess_Len		equ	*-Error_Mess

;{----------- Help text --------------------------------------------------------------------------------------------- }

Help_Text		dc.b	$a,'Written By Steve White. January 1990.',$a,$a
			dc.b	'Usage:- Size [s] [LeftEdge TopEdge RightEdge BottomEdge]',$a,$a
			dc.b	'Enjoy!!',$a,$a
Help_Text_Len		equ	*-Help_Text

;{----------- Library names from include files ---------------------------------------------------------------------- }

IntName			INTNAME

DosName			DOSNAME
