!pr2
Fast Text Windows for Applesoft..................Michael Ching
                          2118 Kula Street, Honolulu, HI 96817

The program WINDER by Mike Seeds in the January 1985 NIBBLE was found to be very interesting.  This was especially so because we, coincidentally, had been working on a similar routine for use in an upcoming strategy sports game.

The main difference between our programs was that the routines used in WINDER are written completely in Applesoft, and thus suffer from the relatively slow speed of the Applesoft interpreter.  This is especially evident in the opening of the windows.  Our routine, on the other hand, is written in assembly language and executes more quickly.

There are a couple of other major differences.  Seeds' routine saves the text, to be overwritten by the window, in a string array WS$.  Our routine saves the text in the secondary text page (memory locations $800 through $BFF).  One advantage of doing this is that more than one window can be opened at the same time, (although the windows may not overlap).  A disadvantage is that the secondary text page occupies the same space that an Applesoft program normally would start at.  This makes it necessary to relocate the Applesoft program above the secondary text page.

Another difference is that WINDER specifies the window dimensions with the width and height of the window, along with the top and left coordinates.  We chose to specify directly the top, bottom, left, and right boundaries.

The assembly language routine is called by the familiar & followed by the appropriate parameters.  The format is & WT,WB,WL,WR,TP where WT is the top coordinate of the window, WB is the bottom coordinate, WL is the left coordinate, WR is the right coordinate, and TP is the text page number.  If TP is set to 1, the text to be replaced by the window is saved to the secondary text page and the window is formed.  If TP is set to 2, the text is restored to the primary text page from the secondary text page.  At present, there is no error checking of the parameter values, and care must be taken to ensure that WB is set greater than WT, and WR greater than WL.

The program is assembled to load into the tail end of the input buffer and the free space in page 3 ($2F5-3C9).  The portion inside page 2 is only used to set up the ampersand hook, so it is not a problem if this code gets wiped out by long input lines after loading.  This setup is done in lines 1250-1290.

Lines 1320-1470 perform the task of getting the parameter values from Applesoft and placing them into temporary storage.  The routines GETBYT and COMBYTE are used, and will evaluate expressions used in the calling Applesoft program.  The width of the window is also calculated here.  The text page value is decremented by one for ease of future manipulation.  Line 1340 initializes the beginning of a loop which will copy the characters in the designated text page to the opposite text page.

Lines 1500-1510 call the monitor routine BASCALC.  BASCALC calculates the starting (leftmost) memory address of the screenline, and stores it in the pointers BASL and BASH.

Lines 1520-1640 set up two pointers, one in the real screen and one in the alternate screen area.  The pointers point to the beginning of the current line starting at the left edge of the caller's window.  A1 points at the source, and A2 at the destination, for a move loop which will copy the characters within the window on the current line.

The destination address is the source address offset by $400 (up or down depending on the source text page).  The calculation is done by exclusive ORing the source address with #$0C (or 00001100 in binary).  For example, if BASH was $07, exclusive ORing will yield $0B.  If it was $0B, exclusive ORing will yield $07.

Lines 1660-1700 comprise the move loop.

Lines 1720-1850 check to see if the frame of the window needs to be drawn.  If the text page is being restored (window being closed), then the frame routine is skipped.  If the window is being cleared, the frame is drawn.

First I store an inverse blank at each end of the line, which is sufficient for all except the top and bottom lines.  Then I check:  if it is the top or bottom line, I fill in the rest of the line with inverse blanks.

Lines 1870-1900 check whether the entire window has been processed.  If not, the program loops back to process the next line.

Lines 1920-2050 check to see whether the window boundaries need to be set.  If the window is being opened (TPAGE = 0), then they are set, and HOME clears out the window.  Note that the window parameters are set so that the frame is outside it.





<<<assembly listing here.....
!np
The next listing shows the revised WINDER routine using the assembly language routines.  Line 40 checks to see if the program has been relocated above the secondary text page.  If not, the start of program pointers are changed and the program is re-RUN.  This causes DOS to position the program above the secondary text page.  Line 50 BRUNS the assembly language routine.

The program is really quite different from that of Mike Seeds, as you can see if you compare them.  Clearing and restoring windows is now very efficient, due to the &-routine.  I moved the delay and closing logic into a common subroutine.  I also added a randomly sized and positioned window in lines 400-410.





<<<<Applesoft listing>>>>
