;*****************************************************************************
;*
;*		WindowArranger.asm (assembler version)		29.2.88
;*						by Heiko Rath
;*
;* This little goodie is able to send a window to front or back. I wrote it
;* for a friend (<CB>) who wanted to bring his AmiCron window to front if  
;* something of interest happened in this window.
;*
;* A short description:
;* The program first trys to open the 'dos.library', if it had success to do
;* so it trys to parse your input string. If it can't understand what you want
;* it gives you help how to use it. If it is able to parse your input it trys
;* to open 'intuition.library' and to find a window with a matching name. If
;* there is one it rearranges it to front or to back. After this it closes
;* the 'intuition.library' & the 'dos.library'.
;*
;* This program was compiled using Asm68K.
;*
;* Thanx to Larry Phillips, (CIS -76703,4322) & C.Heath.
;*****************************************************************************
;*
;*		!!!!!!!!COPY ME FAST, I WANT TO TRAVEL!!!!!!!!
;*
;* This program is public domain. Feel free to copy and modify it. If you
;* like it you can do one of the following things:
;*
;* 1.	absolutly nothing
;* 2.	send me something I deserve:
;*				money, yachts, beer, Marabou chocolate
;* 3.	contact us
;*
;*				Heiko Rath
;*				Raiffeisenstr.10a
;*				D-6108 Weiterstadt
;*				WEST GERMANY
;*				Tel.06150-2658
;*
;*                                     or
;*                          
;*______  /          
;*______\O                    - The Software Brewery - 
;*      \\              		    
;*       o            Sparkling, fresh software from W.-Germany
;*                 
;*     @@@@@	      Straight from the bar to your system
;*     |~~~|\        
;*     | | |/        
;*     |___|        With our regards to the Software Distillery
;*
;*Members are (listed alphabetically):
;*Christian Balzer alias <CB>, Lattice C, user interfaces, beer addict. 
;*Christof Bonnkirch, Aztec C, telecommunications, beer adict.
;*Heiko Rath alias <HR>, Assembler, ROM-Kernal stuff, Marabou addict. 
;*Peter Stark alias PS, Lattice C, IO & utilities, WordStar addict.
;*Ralf Woitinas alias RAF, Assembler, anything, Ray-Tracing addict.
;*Torsten Wronski alias MM, Assembler, anything, girls addict.
;*
;*Beverages: Altenmuenster Brauer Bier, Urfraenkisches Landbier, Grohe Bock.
;*
;*Send exotic drinks, beautyfull girls, $$$$, comments, critizism, flames to:
;*
;*The Software Brewery
;*Christian Balzer
;*Im Wingertsberg 45
;*D-6108 Weiterstadt
;*West-Germany
;*
;*Our BBS "AmigaNode" isn't online yet. As soon as it becomes available, 
;*you'll be the first to know :-).
;*
;*

ExecBase	Equ	4

;*** Exec Offsets:
FindTask	Equ	-294	;(name)(a1)
WaitPort	Equ	-384	;(port)(a0)
GetMsg		Equ	-372	;(port)(a0)
ReplyMsg	Equ	-378	;(message)(a1)
Forbid		Equ	-132	;()()
OpenLibrary	Equ	-552	;(libName,version)(a1,d0)
CloseLibrary	Equ	-414	;(library)(a1)
OldOpenLibrary	Equ	-408
CLOSEWINDOW	Equ	$200	;IDCMP-Flag CloseWindow
WD_USERPORT	Equ	86	;WD_UserPort
IM_CLASS	Equ	20	;Even Class

;*** DOS Offsets:

Input		Equ	-54	;()
OutPut		Equ	-60	;()
Write		Equ	-48	;(file, buffer, length)(d1,d2,d3)

;*** Intuition Offsets:

OpenWindow	Equ	-204	;(OWArgs)(a0)
CloseWindow	Equ	-72	;(Window)(a0)
LockIBase	Equ	-414	;(dontknow)(d0)
UnlockIBase	Equ	-420	;(IBlock)(a0)
WindowToFront	Equ	-312	;(Window)(a0)
WindowToBack	Equ	-306	;(Window)(a0)
AutoRequest	Equ	-348	;(Window,body,PText,NText,PFlags,NFlags,W,H)
				;(a0,a1,a2,a3,d0,d1,d2)

timer		Equ	0
GfxBase		Equ	2
fac		Equ	6
PR_CLI		Equ	172
PR_MsgPort	Equ	92

;*** Macro Definitions:
push.w	MACRO
	move.w	\1,-(sp)	;push a word onto stack
	ENDM

push.l	MACRO
	move.l	\1,-(sp)	;push a longword onto stack
	ENDM

pop.w	MACRO
	move.w	(sp)+,\1	;pop a word from stack
	ENDM

pop.l	MACRO
	move.l	(sp)+,\1	;pop a longword from stack
	ENDM

pushm	MACRO
	movem.l	\1,-(sp)	;push several register on stack
	ENDM

popm	MACRO
	movem.l	(sp)+,\1	;pop several register from stack
	ENDM


Amiga_Init:
	move.l	sp,d6			;save stack pointer

	move.l	a0,a2			;register a2 is cmdline henceforth
	clr.b	0(a2,d0.w)		;make sure that cmdline is null terminated
	push.w	d0			;save cmdlength

	move.l	ExecBase,a6		;get ExecBaseaddress to a6
	suba.l	a1,a1			;clear a1
	jsr	FindTask(a6)		;get pointer

	move.l	d0,a4			;get process-pointer to a4
	tst.l	PR_CLI(a4)		;pr_CLI: CLI or WB?
	bne	main			;if <> 0 then CLI

fromWB:
	lea	PR_MsgPort(a4),a0	;pr_MsgPort: messageportaddress to a0
	jsr	WaitPort(a6)		;wait until message arrives
	lea.l	PR_MsgPort(a4),a0	;
	jsr	GetMsg(a6)		;get message
	move.l	d0,a5			;save return message in a5
	moveq.l	#0,d0			;any version
	lea.l	INTName,a1		;get address of libraryname to a1
	jsr	OpenLibrary(a6)		;try to open Intuition
	tst.l	d0			;see if d0 = 0
	beq	ErrorExit		;ohh shit, failed to open Intuition
	move.l	d0,a6			;get Baseaddress of Intuition to a6
	moveq.l	#0,d0			;PFlag = 0
	moveq.l	#0,d1			;NFlag = 0
	move.l	#320,d2			;width 320
	move.l	#68,d3			;height 68
	suba.l	a0,a0			;clear a0
	lea.l	ITextId,a1		;get address of ITextId to a1
	suba.l	a2,a2			;PosText = 0
	lea.l	ITextOk,a3		;get address of NegText to a3
	jsr	AutoRequest(a6)		;display Autorequest
	move.l	a6,a1			;get INTBase to a1
	move.l	ExecBase,a6		;get ExecBase to a6
	jsr	CloseLibrary(a6)	;close Intuition

	jsr	Forbid(a6)		;we have to do this, so that WB can't
					; unload us to far
	move.l	a5,a1			;get address of ReturnMessage to a1
	jsr	ReplyMsg(a6)		;reply the message
	pop.w	d0
ErrorExit:
	rts

main:
	move.l	ExecBase,a6		;ExecBase to a6
	lea	DOSName(pc),a1		;Address of string 'dos.library',0
	jsr	OldOpenLibrary(a6)	;open library
	move.l	d0,DOSBase		;save DOSBaseaddress
	beq	Exit			;if d0=0 then Exit (System is realy sick!)
	move.l	D0,A6			;move DOSBasepointer to a6
	jsr	OutPut(A6)		;identify the initial output handle
	move.l	D0,stdout		;save stdout

	pop.w	d0			;get cmdlength
SkipSP:	
	move.b	(a2)+,d1		;skip spaces
	beq.b	ShowHow			;if NULL-String then /* help */
	cmp.b	#' ',d1			;is it a Space ?
	beq.b	SkipSP			;yes -> SkipSP

	sub.l	#1,a2
	move.l	a2,StringAddress	;store windownamestart
	add.l	#1,a2

	cmp.b	#$0a,d1			;is it #$0a ?
	beq.b	ShowHow			;yes -> ShowHow /* help */

	cmp.b	#'?',d1			;is it '?' ?
	beq.b	ShowHow			;yes -> ShowHow /* help required */

	cmp.b	#'"',d1			;is it '"' ?
	beq.b	DoQuotes		;yes -> DoQuotes

DoTheMainParsing:
	cmp.b	#'-',d1			;is it '-' ?
	beq.b	Parser			;yes -> Parser /* see if -f or -b */
	move.b	(a2)+,d1		;get the next byte
	bne.b	DoTheMainParsing	;-> DoTheMainParsing

ShowHow:
	lea	HelpString(pc),a0	;give the user help
	move.l	a0,d2			;copy address of string to d2
	bsr	TextOutPut		;output text via Amiga-Dog
	bra	DosClose		;close DOS

DoQuotes:
	move.l	a2,StringAddress	;store address of string
QuotesLoop:
	move.b	(a2)+,d1		;get the next character
	beq.b	ShowHow			;if we have reached the end -> ShowHow
	cmp.b	#'"',d1			;is it '"' ?
	bne.b	QuotesLoop		;no ->QuotesLoop
	move.b	#0,-(a2)		;clear the last '"'
	addq.l	#1,a2
	bra.b	DoTheMainParsing	;-> DoTheMainParsing


Parser:
	move.b	#0,-(a2)

	add.l	#1,a2
	move.b	(a2),d1
	and.b	#%11011111,d1		;convert lowercase to uppercase
	cmp.b	#'F',d1
	beq.b	Front
	cmp.b	#'B',d1
	beq.b	Back
	bra.b	ShowHow

Front:	push.w	#'FR'			;this is only to remember that the user
					; wanted '-f'
	bra.b	Intuitionopen

Back:	push.w	#'BA'

Intuitionopen:				;try to open Intuition
	move.l	ExecBase,a6
	lea	INTName,a1
	jsr	OldOpenLibrary(a6)
	move.l	d0,IntuitionBase	;save IntuitionBase
	beq	DosClose		;if d0=0 then DosClose (Unable to open Intuition)
	move.l	d0,a6			;copy IntuitionBase to a6
	moveq	#0,d0			;clear d0
	jsr	LockIBase(a6)		;lock Intuition
	move.l	d0,MyLock		;store lock

	move.l	60(a6),d0		;get address of first screen
	beq	NoScreen		;if d0=0 then /* there is no
					; Screen !? */
	move.l	d0,ScreenPointer	;store address of screen
	move.l	d0,a0
GetFirst:
	move.l	4(a0),d0		;get address of 1. Window
	move.l	d0,a2
	tst.l	d0			;is d0=0?
	beq	NextScreen		;if a2=0 then /* there is no
					; window in this screen */
****						 ****
* Compare the name of the windowtitle with a string *
* if equal then rearrange window		    *
*****						 ****
DoCompare:
	move.l	StringAddress,a1	;get address of String to a1
	move.l	32(a2),a0		;get address of windowtitle to a0
001$:
	move.b	(a0)+,d0		;copy one byte to d0
	move.b	(a1)+,d1		;copy one byte to d1
	and.b	#%11011111,d0		;convert lowercase to uppercase
	and.b	#%11011111,d1		;convert lowercase to uppercase
	cmp.b	d0,d1			;see if equal
	bne.b	NotTheSame		;if no then -> NotTheSame	
	tst.b	d0			;see if NULL
	beq.b	Same			;if yes then -> Same
	bra.b	001$			;-> 001$

NotTheSame:
	move.l	(a2),d0			;get address of next window
	move.l	d0,a2			;copy address to a2
	tst.l	d0			;is d0=0?
	bne.b	DoCompare		;look at the next windowtitle
					;if a2=0 then/* this was the last window */
NextScreen:
	move.l	ScreenPointer,a0
	move.l	(a0),a0			;get address of next screen
	move.l	a0,d0
	tst.l	d0			;is a0=0?
	beq	NotFound		;if a0=0 then /* no more screens */
	bra.b	GetFirst		;get first windowaddress

NotFound:
	pop.w	d0
	lea	HelpString(pc),a0	;get address of Helpstring to a0
	move.l	a0,d2			;copy address to d2
	bsr	TextOutPut		;output text
	lea	NotFoundString(pc),a0	;get address of NotFoundString to a0
	move.l	a0,d2			;copy address to d2
	bsr	TextOutPut		;output text
	bra.b	NoScreen		;-> NoScreen

Same:
	move.l	a2,a0			;copy windowaddress to a0
	pop.w	d0
	cmp.w	#'BA',d0
	beq.b	MoveToBack 
	jsr	WindowToFront(a6)	;window to front
	bra.b	NoScreen

MoveToBack:
	jsr	WindowToBack(a6)	;window to back

NoScreen:
	move.l	MyLock,a0		;get lockvalue
	jsr	UnlockIBase(a6)		;unlock Intuition

Intuitionclose:				;close Intuition
	move.l	ExecBase,a6
	move.l	IntuitionBase,a1
	jsr	CloseLibrary(a6)

DosClose:				;close Amiga-DOG
	move.l	ExecBase,a6
	move.l	DOSBase,a1
	jsr	CloseLibrary(a6)
Exit:
	move.l	#0,d0			;no return-error
	rts

;*****************************************************************************
;*
;*	TextOutPut
;*			by	Heiko Rath
;*				Raiffeisenstr.10a
;*				D-6108 Weiterstadt
;*				West Germany
;*				Tel.06150-2658
;*                          
;*______  /          
;*______\O                    - The Software Brewery - 
;*      \\              		    
;*       o            Sparkling, fresh software from W.-Germany
;*                 
;*     @@@@@	      Straight from the bar to your system
;*     |~~~|\        
;*     | | |/        
;*     |___|        With our regards to the Software Distillery
;*
;*Members are (listed alphabetically):
;*Christian Balzer alias <CB>, Lattice C, user interfaces, beer addict. 
;*Christof Bonnkirch, Aztec C, telecommunications, beer adict.
;*Heiko Rath alias <HR>, Assembler, ROM-Kernal stuff, Marabou addict. 
;*Peter Stark alias PS, Lattice C, IO & utilities, WordStar addict.
;*Ralf Woitinas alias RAF, Assembler, anything, Ray-Tracing addict.
;*Torsten Wronski alias MM, Assembler, anything, girls addict.
;*
;*Beverages: Altenmuenster Brauer Bier, Urfraenkisches Landbier, Grohe Bock.
;*
;*
;* PURPOSE: 		output a NULL-terminated string via stdout
;*
;* ROUTINE TYPE: 	subroutine
;*
;* SYNTAX:		bsr	TextOutPut	(stringaddress)(d2)
;*
;* ENTRY CONDITIONS:	needs DOSlibrary opened and stdout defined
;*			also needs DOS-'Write' offset -48 defined.
;*
;* RETURNS:		Text via DOS-stdout
;*
;* NOTE:		its better if the string is really NULL-terminated
;*
;* CHANGED:		nothing
;*
;* USAGE:		move.l	#Textaddress,d2
;*			bsr	TextOutPut
;*
;*****************************************************************************



TextOutPut:		;TextOutPut (Textaddress)(d2)
			;prints a NULL-terminated string via stdout
			;changed: nothing
	movem.l	d0-d7/a0-a6,-(sp)	;save registers
	move.l	d2,a0			;address to a0
	clr.l	d3			;count = 0
CountLoop:
	tst.b	(a0)+			;is it NULL ?
	beq.b	PMsg			;yes: -=> determine length
	addq.l	#1,d3			;count = count+1
	bra.b	CountLoop		;test next byte
PMsg:
	move.l	stdout,d1		;get stdout to d1
	move.l	DOSBase,a6		;move DOSBase to a6
	jsr	Write(a6)		;write the Text
	movem.l	(sp)+,a0-a6/d0-d7	;reserve registers
	rts

;*** variables:

DOSBase		dc.l	0			;pointer to the DOSBaseaddress
stdout		dc.l	0			;pointer to standard output
IntuitionBase:					;address of Intuitionbase
		dc.l	0
UserPort:
		dc.l	0
MyLock		dc.l	0
ScreenPointer	dc.l	0
StringAddress	dc.l	0

		cnop	0,2
;*** constants:
DOSName		dc.b	'dos.library',0		;name of the DOS-library
INTName		dc.b	'intuition.library',0	;name of the Intuition-library

		cnop	0,2

HelpString:	dc.b	$9b,'0;33;40m','WindowArranger',$9b,'0;31;40m'
		dc.b	' by ',$9b,'0;32;40m','Heiko Rath ',$9b,'0;31;40m'
		dc.b	$9b,'4;31;40m',169,' by '
		dc.b	$9b,'1;31;40m','The Software Brewery',$9b,'0;31;40m',10
		dc.b	'To arrange a window use ',$9b,'0;33;40m'
		dc.b	'WindowArranger name -f',$9b,'0;31;40m',' or '
		dc.b	$9b,'0;33;40m','-b',$9b,'0;31;40m',10
		dc.b	$9b,'1;31;40m','f',$9b,'0;31;40m'
		dc.b	'= window to front & '
		dc.b	$9b,'1;31;40m','b',$9b,'0;31;40m'
		dc.b	'= window to back',10
		dc.b	0
		cnop	0,2
NotFoundString:
		dc.b	$9b,'0;32;40m','Please give me a babel fish'
		dc.b	' or a new windowname!!',$9b,'0;31;40m',10,0

		cnop	0,2
******************************************************************************
*
*	This is the IntuitionTextStructure of the AutoRequester
*
******************************************************************************
ITextId:	dc.b	0,1,1,0	     ;pens, drawmode and filler
		dc.w	17,6	     ;XY
		dc.l	0	     ;NULL for default font
		dc.l	S1 	     ;pointer to text
		dc.l	ITextId2     ;next IntuitText structure
ITextId2	dc.b	0,1,1,0
		dc.w	17,18
		dc.l	0
		dc.l	S2
		dc.l	0
ITextOk:	dc.b	0,1,1,0
		dc.w	6,3
		dc.l	0
		dc.l	SOk
		dc.l	0
		cnop	0,2
S1		dc.b	'WindowArranger must be',0
		cnop	0,2
S2		dc.b	'started from the CLI.',0
		cnop	0,2
SOk		dc.b	'Ok',0
		cnop	0,2
