Grow Window in Asm
Volume Number: | | 1
|
Issue Number: | | 11
|
Column Tag: | | Assembly Language Lab
|
Grow Window in MacAsm
By Jan Eugenides, Software Engineer, Assembly Corner, Pembroke Pines, FL
There are several stages a programmer goes through when learning to program the Macintosh. The first is to learn about the tools available to you, how they work and what they can do. The second is to unlearn everything you know about interacting with the person using the program. This in itself is quite an undertaking. Then and only then can you begin putting the tools together into a complete program that works like a Macintosh program should work. This article, and the program which accompanies it, is designed to help you with the first stage - learning to use the Macintosh Tool Kit.
This article deals with assembly language programming, to fill the need for technical information directly related to Macintosh programming. Apple Computer, Inc. is not overly supportive of assembly language programming, and most of Inside Macintosh deals with Pascal examples and procedures. I'm not knocking Apple, they had to choose some language to use in the examples and I suppose Pascal was a logical choice. They did include some very helpful information for assembly language programmers at the end of each chapter. However, the assembly language programmer is still faced with translating the Pascal procedures and definitions into the necessary stack setups and such. Not an easy task, especially if you are not familiar with Pascal's inner workings.
What it Does
This month's program is a complete, double-clickable application, designed to demonstrate some very useful programming techniques. You can use it as a "shell" for writing your own applications. Everything is in place and working, all you have to do is insert your own code in the appropriate places.
The program, called "Show Windows," displays three common types of windows, and shows how to handle each one properly from assembly language. It also shows how to set up and display the menu bar, how to get events from the Mac operating system (in this case mouse events), and shows how to create resource files such as icons and dialog boxes for use by the application. Desk accessories are fully supported, and the application can be run by double-clicking its icon.
Running the Program
Before you run the application you must assemble and compile it (see the "Typing in the Program" section of this article for more details about assembling and compiling). When you double-click the icon, you'll see the familiar zoom boxes, the menu bar will be redrawn, and a window with the title "Window 1" will appear. You can drag and re-size the window with the mouse as usual. Clicking in the goaway box will close the window, and a new one will appear. Three types of windows can be seen in this fashion.
When the program first runs, you'll notice the disk whirrs when you close a window, before the next one is drawn. It also whirrs the first time you open the dialog box. This is the resources being fetched from the disk. After this, they will be in memory and everything will run much faster the next time you display the windows or dialog box. They will stay in memory until another application or accessory needs the space and then they'll be purged. When you need them again after that, they'll have to be re-loaded from the disk.
Open a desk accessory or two, and experiment with clicking on the various windows, moving them about. As you can see, everything runs concurrently with no problems.
Typing in the Program
This application was written using the Mainstay MasASM assembler. The MacASM assembler is a very fast 68000 assembler. It does not use the Mac interface much, but is more like running an assembler on a conventional computer. In fact, it is very similar to the S-C Macro Assembler for the Apple II. I admit I would like to see it use the mouse for editing, but otherwise it's great, and it is FAST.
MacASM comes with several examples on the disk, written by Yves Lempereur. They certainly helped me get this application working, thanks, Yves!
MacASM also comes with an automatic resource compiler that will translate resource definitions into actual resource files. This makes life easy for the programmer. Ordinarily, I just use "filler" resources, standard templates which are assembled with the program. Then, I use ResEdit to change them into the actual resources I need. That's generally a faster and easier method. But for the sake of demonstration, I have spelled out all the resources as they should be in this example.
After you have typed in the source code and assembled it, all you need to do is double-click the assembled program's icon, and the compiler will automatically run and compile the assembled binary file into a Macintosh application file with a data and resource fork. The application is then ready to run.
Blow by Blow Description
From here on out I'll be dealing with the technical description of the program. I'm assuming you are already familiar with 68000 assembly language, and with the information in "Inside Macintosh."
Line 250 starts off the program with an .INCLUDE "Library.Asm" directive, which causes the file "Library.Asm" to be included in the assembly. This is a file which is included on the MacASM disk, and contains all the trap words for the various Mac ROM calls, as well as some simple macro definitions, such as DEFV which simulates the "define variable" directive, and GLOBAL which handles allocation of global variable space. TBX is the macro for trap calls. [ MDS users can use similar library files for the trap maco names. -Ed]
Lines 270-420 are setting up storage for the variables used in the program, and by the system. Line 460 sets the target file to SW.BIN [this is specific to MacAsm. -Ed.], and line 480 sets the resource file to Show Window 1.0 -- 05/05/85.
The Resources
Next come the resource definitions. Resources are data which the program can call from disk or memory for its use, and are separate from the actual code. That makes it easy to change them later, without reassembling or recompiling the program.
Lines 500-520 are the "owner" resource, an application-defined file. Lines 540-700 are the application's icon, [See last month's article by Steve Rabalais on creating an icon for MacAsm with his version of the Icon Converter. -Ed.] and lines 720-870 are the icon mask, which will affect how the icon looks when highlighted, and when it's moved onto the desktop. Next, in lines 900-1060 are standard File reference and Bundle resources.
Lines 1080-1200 are the Menu 1 resource. This data will be added to the first menu (the Apple menu) by the program when it runs. Lines 1220-1320 are the Menu 2 resource, and will comprise the second menu when the program runs.
Lines 1340-1420 contain a dialog box definition, with the size, location, type, and other parameters. Following that in lines 1440-1640 are the items which will go in the dialog box, including an "OK" button and some text.
Lines 1660-1910 contain the window templates for the three windows the program can display. These are standard type 0, type 4, and type 16 windows, as described in Inside Macintosh.
And that concludes the resource definitions. At assembly time, they are assembled as hex data, and after assembly, the compiler converts the whole shebang into a complete application with a data and resource fork. The process is quite easy and fast.
The Code
Lines 1930-3960 comprise the actual application code. All the various trap calls are commented, so I won't go into them here, but you should notice the way the stack is set up prior to each call. All the ROM calls expect the stack to be set up like it would be set up by Pascal. When programming in assembly, it's up to you to properly initialize the stack before each call, and then to remove any data which is returned there. It takes a little getting used to, but once you know the setups for the various calls, it's not too bad. [Note: back issues of MacTutor have covered events and windows in some detail, so you may wish to refer to these for more specific information on how windows are constructed and how the event manager works. See especially numbers 3 and 4 -Ed.]
Lines 1940-2260 handle the initialization of the various necessary routines, inserting the applications menu items and redrawing the menu bar, and drawing the first window.
Event Driven
The application is entirely event driven, which means that it simply loops until an event is detected by the system and passed on to the application. Events are such things as clicking the mouse button, pressing a key on the keyboard, inserting a disk, etc. The application can either respond to the event, or ignore it. This application ignores all events except Mousedown, Update, and Activate events. (Mousedown is clicking, Update means a window must be redrawn, and Activate means a window is becomming active.)
Line 2280 begins the loop with a call to SystemTask, which allows the system to do whatever it wants while the application is idling. This is necessary to allow desk accessories to operate. Then the next event is fetched, and depending on what it is, the program jumps to the proper subroutine. If an event is to be ignored, the program just returns to the loop.
Lines 2520-2570 take care of an Activate event. When a new window is activated, all that's necessary in this application is to test to see if it is window #1. If it is, a grow box is drawn. The other windows do not have grow boxes.
Lines 2580-2720 handle an Update event. The grafport is set to the current port, the background is replaced, and again the grow box is drawn if necessary.
Lines 2760-3960 handle the various types of Mousedown events. First, lines 2760-2900 figure out where the mouse button was pressed. It can be in the menu, on the desktop, in the content portion of a window, in the drag bar of a window, in the grow box, or in the go away box.
Lines 2910-3360 handle menu selections. Lines 2910-3020 determine which menu and highlight it, then determine which item of the menu and branch accordingly.
Lines 3040-3160 handle the items in Menu 1. If it's the first item, it's our "About Show Windows..." selection, and a branch is made to lines 3180-3310 which display the dialog box. If it is not the first item, the parms are passed to OpenDeskAcc which opens the proper desk accessory.
Lines 3180-3310 open our dialog box, make it modal so it can't be dismissed, and wait for the OK button to be pressed. Then, the dialog box is closed and the loop continues.
Lines 3330-3360 handles Menu 2 selections. If item 1 is selected, the program ends with an ExitToShell.
Lines 3370-3400 handle a mousedown on the desktop with a call to SystemClick, which would allow any accessories to handle the event as they chose. With the Mac, you must be polite because you don't know who you might be working with. [Note that desk accessories that support TextEdit are not operable since they require an Edit menu, which we have not added. Hence if you try to type into the note pad, the program will crash. As an exercise, try to add support for typing into the note pad. If you get stuck, see MacTutor number 4 for a complete support of the note pad in MDS assembly.-Ed.]
Lines 3410-3480 take care of clicking in the content portion of a window. If it's our window, a call to SelectWindow will activate it.
Lines 3490-3520 handle dragging the windows around the desktop.
Lines 3540-3690 change the size of the window, first drawing the grey outline with a call to GrowWindow, and then resizing the window with a call to SizeWindow. Then the grafport is reset, and the window manager is notified that the window has changed. This will result in the proper update and activate events being generated.
Lines 3700-3960 handle closing windows. After a window is closed, the next type of window is drawn, over and over, so that closing one window automatically creates another of the next type.
Finally some boundaries for the drag are defined, and the necessary segment zero definition ends the program.
Possible Uses
The source code for this program is purposefully written in such a way that you can easily modify it for your own uses. The jump tables are all complete, containing all the various events even though they are not all used in this program. All you need to do is insert your own code in the right places to produce a working application of your own.
00010 *SAVE S.SHOW.WINDOW
00020 *--------------------------------
00030 ; This is a simple stand alone
00040 ; double-clickable application.
00050 ; It has its own icon and other
00060 ; resources. It is intended as an
00070 ; example of how to create an
00080 ; application from assembly language.
00090 ; All it does is create three common
00100 ; types of windows. Closing one window
00110 ; causes the next type to appear.
00120 *--------------------------------
00130 ; by Jan Eugenides
00140 ; for MacTutor, Oct. 1985
00150 ; 11601 N.W 18th St.
00160 ; Pembroke Pines, FL 33026
00170 ;
00180 ; Many thanks to Yves Lempeurer for
00190 ; his examples and help.
00200 ;
00210 ; MacASM assembler
00220 *--------------------------------
00230 list off
00240 *--------------------------------
00250 INCLUDE "Library.Asm"
00260 *--------------------------------
00270 GLOBAL 52,$200
00280 ;
00290 DEFV W,ITMHIT
00300 DEFV L,WINDOW1
00310 DEFV L,WINDOW2
00320 DEFV L,WINDOW
00330 DEFV W,MENU
00340 DEFV W,MENUITM
00350 DEFV 16,DSKNAM
00360 DEFV 0,EVENTRECORD
00370 DEFV W,WHAT
00380 DEFV L,MESSAGE
00390 DEFV L,WHEN
00400 DEFV L,WHERE
00410 DEFV W,MODIFY
00420 DEFV W,CURWINDOW
00430 ;
00440 ENDG
00450 *--------------------------------
00460 TFILE "SW.Bin"
00470 *--------------------------------
00480 RFILE "Show Windows", APPL,JWIN,$2000
00490 *--------------------------------
00500 RSRC JWIN,0
00510 STR "Show Window 1.0 -- 05/05/85"
00520 ENDR
00530 *--------------------------------
00540 RSRC ICN#,128
00550 HEX 00000100FFFFFFFF Icon
00560 HEX 8000000180000001
00570 HEX FFFFFFFF82000061
00580 HEX C2000051C200006D
00590 HEX E2000075B2000055
00600 HEX 9E00007F8600002F
00610 HEX 82000027BA000027
00620 HEX C60000278C000021
00630 HEX 88000029AFFFFFF9
00640 HEX B601001983FFFFE9
00650 HEX 8A01002FE601004F
00660 HEX EC01004DEC01004F
00670 HEX B4010045AC010065
00680 HEX 96010031CA010011
00690 HEX E601001986010009
00700 HEX 8C01000DDFFFFFFF
00710 *
00720 HEX FFFFFFFFFFFFFFFF mask
00730 HEX FFFFFFFFFFFFFFFF
00740 HEX FFFFFFFFFFFFFFFF
00750 HEX FFFFFFFFFFFFFFFF
00760 HEX FFFFFFFFFFFFFFFF
00770 HEX FFFFFFFFFFFFFFFF
00780 HEX FFFFFFFFFFFFFFFF
00790 HEX FFFFFFFFFFFFFFFF
00800 HEX FFFFFFFFFFFFFFFF
00810 HEX FFFFFFFFFFFFFFFF
00820 HEX F801807FFE01803F
00830 HEX FC01803FFC01807F
00840 HEX FC01807FFC01803F
00850 HEX FC01803FFC01801F
00860 HEX FC01800FFC01800F
00870 HEX FFFFFFFFFFFFFFFF
00880 ENDR
00890 *--------------------------------
00900 RSRC FREF,128 File ref
00910 ASC "APPL"
00920 DATA /0
00930 STR ""
00940 ENDR
00950 *--------------------------------
00960 RSRC BNDL,128 Bundle
00970 ASC "JWIN"
00980 DATA /0
00990 DATA /2-1
01000 ASC "ICN#"
01010 DATA /1-1
01020 DATA /0,/128
01030 ASC "FREF"
01040 DATA /1-1
01050 DATA /0,/128
01060 ENDR
01070 *--------------------------------
01080 RSRC MENU,1 Menu 1
01090 DATA /1 ID
01100 DATA /0,/0
01110 DATA /0
01120 DATA /0
01130 DATA $FFFFFFFB enable bits
01140 HEX 0114 Title
01150 STR "About Show Windows..."
01160 DATA #0,#0,#0,#0 style...
01170 STR "-"
01180 DATA #0,#0,#0,#0
01190 STR ""
01200 ENDR
01210 *--------------------------------
01220 RSRC MENU,2 Menu 2
01230 DATA /2
01240 DATA /0,/0
01250 DATA /0
01260 DATA /0
01270 DATA $FFFFFFFF
01280 STR "File"
01290 STR "Exit"
01300 DATA #0,#'E,#0,#0
01310 STR ""
01320 ENDR
01330 *--------------------------------
01340 RSRC DLOG,1 dialog res
01350 DATA /50,/60,/180,/320 Bounds
01360 DATA /1 Wind ID
01370 DATA #1,#0 Visible
01380 DATA #0,#0 NoGoAway
01390 DATA 0 refCon
01400 DATA /1 Item ID
01410 STR "" Title
01420 ENDR
01430 *--------------------------------
01440 RSRC DITL,1
01450 DATA /2-1 Number of Items
01460 DATA 0
01470 DATA /90,/220,/120,/250 Coords
01480 DATA #4 Item type length
01490 STR "OK" Content
01500 DATA 0
01510 DATA /2,/2,/118,/240
01520 HEX 0892 static text 144 Bytes
01530 ASC " Jan Eugenides"
01540 HEX 0D
01550 ASC " Assembly Corner"
01560 HEX 0D
01570 ASC " 11601 N.W. 18th Street"
01580 HEX 0D
01590 ASC " Pembroke Pines, FL 33026"
01600 HEX 0D0D
01610 ASC "A simple application example"
01620 HEX 0D
01630 ASC "from assembly language. "
01640 ENDR
01650 *--------------------------------
01660 RSRC WIND,128,32 Window
01670 DATA /50,/150,/300,/380 Coord
01680 DATA /0 Type 0
01690 DATA #1,#0 visible
01700 DATA #1,#0 GoAway
01710 DATA 0 refCon
01720 STR "Window 1" title
01730 ENDR
01740 *--------------------------------
01750 RSRC WIND,129,32
01760 DATA /50,/150,/300,/380
01770 DATA /4 Type 4
01780 DATA #1,#0
01790 DATA #1,#0
01800 DATA 0
01810 STR "Window 2"
01820 ENDR
01830 *--------------------------------
01840 RSRC WIND,130,32
01850 DATA /50,/150,/300,/380
01860 DATA /16 Type 16
01870 DATA #1,#0
01880 DATA #1,#0
01890 DATA 0
01900 STR "Window 3"
01910 ENDR
01920 *--------------------------------
01930 SEG 1,52 segment 1
01940 START PEA -4(A5)
01950 TBX InitGraf init QD
01960 TBX InitFonts font mgr
01970 TBX InitWindows window mgr
01980 TBX InitMenus menu mgr
01990 CLR.L -(SP)
02000 TBX InitDialogs dialog mgr
02010 CLR.L -(SP) menu handle
02020 MOVE.W #1,-(SP) meni id 1
02030 TBX GetRMenu get menu
02040 MOVE.L (SP),-(SP) push again
02050 CLR.W -(SP) append...
02060 TBX InsertMenu add menu item
02070 MOVE.L #$44525652,-(SP) 'DRVR'
02080 TBX AddResMenu Add desk Acc
02090 CLR.L -(SP) menu handle
02100 MOVE.W #2,-(SP) file menu
02110 TBX GetRMenu get menu
02120 CLR.W -(SP)append...
02130 TBX InsertMenu insert menu
02140 TBX DrawMenuBar menu bar
02150 MOVE.W #128,CURWINDOW(A5) rscs id
02160 CLR.L -(SP)window ptr. return
02170 MOVE.W CURWINDOW(A5),-(SP) id
02180 CLR.L -(SP) heap window
02190 MOVE.L #-1,-(SP) front window
02200 TBX GetNewWindow make window
02210 MOVE.L (SP)+,WINDOW1(A5) save ptr
02220 MOVE.L WINDOW1(A5),-(SP) push ptr
02230 TBX DrawGrowIcon add grow icon
02240 MOVE.L #$0000FFFF,D0 all events
02250 OST FlushEvents clear all
02260 TBX InitCursor show cursor
02270 *--------------------------------
02280 LOOP TBX SystemTask check DA
02290 CLR.W -(SP) returned event
02300 MOVE.W #-1,-(SP)mask all events
02310 PEA EVENTRECORD(A5)
02320 TBX GetNextEvent Get an event
02330 MOVE.B (SP)+,D0 result ret.
02340 BEQ.S LOOP nothing...
02350 MOVE.W WHAT(A5),D0 got one
02360 ADD.W D0,D0 table two bytes
02370 MOVE.W ETABLE(PC,D0.W),D0
02380 JMP ETABLE(PC,D0.W) go do it
02390 ETABLE DATA /LOOP-ETABLE
02400 DATA /MOUSEDWN-ETABLE
02410 DATA /MOUSEUP-ETABLE
02420 DATA /KEYDWN-ETABLE
02430 DATA /LOOP-ETABLE key up
02440 DATA /AUTOKEY-ETABLE
02450 DATA /UPDATE-ETABLE
02460 DATA /DISKINS-ETABLE
02470 DATA /ACTIVATE-ETABLE
02480 DATA /LOOP-ETABLE networking
02490 DATA /LOOP-ETABLE device driver
02500 DATA /LOOP-ETABLE app
02510 MOUSEUP BRA LOOP Mouse up, just loop
02520 ACTIVATE MOVE.W CURWINDOW(A5),D0
02530 CMP.W #128,D0 is it window 1?
02540 BNE.S .1 nope
02550 MOVE.L WINDOW1(A5),-(SP) yes
02560 TBX DrawGrowIcon
02570 .1 BRA LOOP and return to loop
02580 UPDATE MOVE.L MESSAGE(A5),-(SP)
02590 TBX BeginUpDate
02600 MOVE.L MESSAGE(A5),-(SP)
02610 TBX SetPort set graphport
02620 MOVE.L MESSAGE(A5),A0
02630 PEA 16(A0) rect in window rec
02640 TBX EraseRect wipe out
02650 MOVE.W CURWINDOW(A5),D0
02660 CMP.W #128,D0 is it window 1?
02670 BNE.S .1 no
02680 MOVE.L MESSAGE(A5),-(SP)
02690 TBX DrawGrowIcon yes
02700 .1 MOVE.L MESSAGE(A5),-(SP)
02710 TBX EndUpDate
02720 BRA LOOP return to loop
02730 AUTOKEY BRA LOOP
02740 KEYDWN BRA LOOP
02750 DISKINS BRA LOOP
02760 MOUSEDWN CLR.W -(SP) ret result
02770 MOVE.L WHERE(A5),-(SP) where?
02780 PEA WINDOW(A5) window ptr addr
02790 TBX FindWindow
02800 MOVE.W (SP)+,D0 get resykt
02810 ADD.W D0,D0 time 2...
02820 MOVE.W WTABLE(PC,D0.W),D0
02830 JMP WTABLE(PC,D0.W) do it
02840 WTABLE DATA /LOOP-WTABLE in desk...
02850 DATA /INMENU-WTABLE menu bar...
02860 DATA /SYSEVNT-WTABLE system...
02870 DATA /CONTENT-WTABLE content...
02880 DATA /DRAG-WTABLE drag area...
02890 DATA /GROW-WTABLE grow area...
02900 DATA /GOAWAY-WTABLE goaway...
02910 INMENU CLR.L -(SP) ret menu choice
02920 MOVE.L WHERE(A5),-(SP)
02930 TBX MenuSelect which menu?
02940 MOVE.L (SP)+,D7 menu id & item
02950 FUNCTION MOVE.L D7,MENU(A5) save menu
02960 CLR.W -(SP) select all menus
02970 TBX HiliteMenu unhilite all
02980 MOVE.W MENU(A5),D0 get menu id
02990 CMP.W #1,D0
03000 BEQ.S INMENU1 its menu 1
03010 CMP.W #2,D0
03020 BEQ.S INMENU2 its menu 2
03030 BRA LOOP no one else
03040 INMENU1 MOVE.W MENUITM(A5),D0 apple menu
03050 CMP.W #1,D0 menu item 1?
03060 BEQ.S LOGO about item...
03070 CLR.L -(SP)no, must be DA...
03080 MOVE.W #1,-(SP)
03090 TBX GetRMenu not item 1
03100 MOVE.W MENUITM(A5),-(SP)
03110 PEA DSKNAM(A5) holder for DA
03120 TBX GetItem find DA name
03130 CLR.W -(SP) ret result
03140 PEA DSKNAM(A5)
03150 TBX OpenDeskAcc do DA...
03160 MOVE.W (SP)+,D0 ret result...
03170 BRA LOOP and loop
03180 LOGO CLR.L -(SP) dialog wnd ptr
03190 MOVE.W #1,-(SP) dialog box id
03200 CLR.L -(SP) store on heap
03210 MOVE.L #-1,-(SP) in front...
03220 TBX GetNewDialog get the box
03230 MOVE.L (SP)+,D7 save result
03240 .0 CLR.L -(SP) no filter proc
03250 PEA ITMHIT(A5) VAR hit item
03260 TBX ModalDialog it's modal
03270 MOVE.W ITMHIT(A5),D0 what happen
03280 CMP.W #1,D0 time to exit?
03290 BNE.S .0 no, wait for press
03300 MOVE.L D7,-(SP) get wind. ptr
03310 TBX CloseDialog and close
03320 BRA LOOP return
03330 INMENU2 MOVE.W MENUITM(A5),D0 file menu
03340 CMP.W #1,D0 item 1?
03350 BNE LOOP no, loop
03360 TBX ExitToShell yes, exit
03370 SYSEVNT PEA EVENTRECORD(A5)
03380 MOVE.L WINDOW(A5),-(SP)
03390 TBX SystemClick handle it
03400 BRA LOOP and loop
03410 CONTENT MOVE.L WINDOW(A5),A0
03420 CMP.L WINDOW1(A5),A0 our window?
03430 BEQ.S .0 yes...
03440 CMP.L WINDOW2(A5),A0 window2?
03450 BNE LOOP no, loop again
03460 .0 MOVE.L A0,-(SP)
03470 TBX SelectWindow Select it
03480 BRA LOOP and loop
03490 DRAG MOVE.L WINDOW(A5),-(SP) window ptr
03500 MOVE.L WHERE(A5),-(SP) where
03510 PEA BOUNDS(PC) drag boundary
03520 TBX DragWindow and drag it
03530 BRA LOOP
03540 GROW CLR.L -(SP) grow box event
03550 MOVE.L WINDOW(A5),-(SP) window ptr
03560 MOVE.L WHERE(A5),-(SP) where?
03570 PEA SIZE(PC)
03580 TBX GrowWindow draw grow area
03590 MOVE.L (SP)+,D7
03600 MOVE.L WINDOW(A5),-(SP)
03610 MOVE.L D7,-(SP)
03620 MOVE.B #1,-(SP)
03630 TBX SizeWindow resize window
03640 MOVE.L WINDOW(A5),-(SP)
03650 TBX SetPort set graphport
03660 MOVE.L WINDOW(A5),A0
03670 PEA 16(A0) rect of graphport
03680 TBX InvalRect force update evt
03690 BRA LOOP and loop
03700 GOAWAY CLR.W -(SP)
03710 MOVE.L WINDOW(A5),-(SP)
03720 MOVE.L WHERE(A5),-(SP)
03730 TBX TrackGoAway
03740 BEQ LOOP goaway canceled
03750 ;
03760 MOVE.L WINDOW(A5),-(SP)
03770 TBX DisposWindow close window
03780 ADDQ #1,CURWINDOW(A5)
03790 MOVE.W CURWINDOW(A5),D0
03800 CMP.W #131,D0 all three yet?
03810 BEQ.S .1 yes, start over
03820 BSR DRAW.NEW.WINDOW no
03830 BRA LOOP and loop
03840 .1 MOVE #128,CURWINDOW(A5) reset
03850 BSR DRAW.NEW.WINDOW draw it
03860 MOVE.L WINDOW1(A5),-(SP)
03870 TBX DrawGrowIcon
03880 BRA LOOP and return to loop
03890 DRAW.NEW.WINDOW
03900 CLR.L -(SP)
03910 MOVE.W CURWINDOW(A5),-(SP)
03920 CLR.L -(SP)
03930 MOVE.L #-1,-(SP)
03940 TBX GetNewWindow new window
03950 MOVE.L (SP)+,WINDOW1(A5)
03960 RTS and return
03970 *--------------------------------
03980 BOUNDS DATA /24,/4,/338,/508
03990 SIZE DATA /32,/64,/290,/470
04000 ENDR
04010 *--------------------------------
04020 SEG 0,32,VAR.LEN,$20
04030 SEG0
04040 SEG_1 JP START,1
04050 END_1
04060 END0
04070 ENDR
04080 *--------------------------------
04090 END