;*****************************************************************************
;*
;*      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.s   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(pc),a1      ;get address of libraryname to a1
   jsr   OpenLibrary(a6)      ;try to open Intuition
   tst.l   d0         ;see if d0 = 0
   beq.s   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(pc),a1      ;get address of ITextId to a1
   suba.l   a2,a2         ;PosText = 0
   lea.l   ITextOk(pc),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(pc),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.s   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.s   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(pc),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(pc),a0
   move.l   (a0),a0         ;get address of next screen
   move.l   a0,d0
   tst.l   d0         ;is a0=0?
   beq.s   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.s   TextOutPut      ;output text
   lea   NotFoundString(pc),a0   ;get address of NotFoundString to a0
   move.l   a0,d2         ;copy address to d2
   bsr.s   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(pc),a0      ;get lockvalue
   jsr   UnlockIBase(a6)      ;unlock Intuition

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

DosClose:            ;close Amiga-DOG
   move.l   ExecBase,a6
   move.l   DOSBase(pc),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(pc),d1      ;get stdout to d1
   move.l   DOSBase(pc),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
      end
