Menu Toolbox III

by Jeff Jones (jeff@loadstar.com)
Copyright 1996: J and F Publishing

Introduction

This toolbox has the most versatile menu commands I've ever coded, and will make your BASIC and ML programs scream with speedy scrolling menus and file selectors with multi- item selectability. That's right. I said scrolling! Because of its size, there are only two versions of MENU TOOLBOX III:

Filename        SYS Location   Notes 
MENUTOOLS 1000     4096       (Reference: code, SubRef: menucode1)
MENUTOOLS 8000    32768       (Reference: code, SubRef: menucode2)

These are the optimal locations for BASIC. It's 8K (33 blocks) in length, but your programs will be much smaller, and have access to RAM under ROM for array, screen and menu storage. You won't suffer for memory.

There are four types of menus:

You usually can't use SYS 32768,1,2,3,4,5 from ML or compiled programs so you'll have to POKE the parameters into a location and then tell the toolbox where to get the parameters. You tell MENU TOOLBOX II where to find the parameters by loading the .X and .Y registers with the low and high bytes of the location and then SYSing. From BASIC, the .X register is location 781 and the .Y register is 782. Here I'll use $033C (+828) as an example. The high/low bytes for location 828 are 3 high and 60 low. The following BASIC example of the lattice command works equally well as BASIC or compiled.

   poke828,x1
   poke829,x2
   poke830,y1
   poke831,y2
   poke832,t1
   poke833,t2
   poke834,c1
   poke835,c2
   poke781,60
   poke782,3
   sys32768+102

This may look slow, but in compiled programs, POKE commands are executed at near ML speeds. If there is a chance that you're going to compile your program, you may want to use the ML/compiler protocols from the start. It's heck converting a program. I know (Directomeister).

ML programmers can embed parameters within their programs. It's actually easier from ML than compiled:

   background ldx <b'lattice
              ldy >b'lattice
              jsr 32768+102
              rts
   b'lattice .byt 0,39,0,24,9,10,15,12

Instant Pages:
SYS 32768+198,PAGENAME$, items,list$..., hotkeys$

Since it's by far the easiest to use, we'll discuss instant pages first. A page is a computer screen with a user interface setup. Instant page allows you to create with one SYS a screen with a tiled background, a title bar, and a centered working menu complete with hotkeys. Consider the following code:

   10 T$="M  Y   D A T A B A S E"
   20 A$(1)="OPEN DATABASE       (O)"
   30 A$(2)="DEFINE FIELDS       (D)"
   40 A$(3)="ADD RECORD          (A)"
   50 A$(4)="SEARCH RECORDS      (S)
   60 A$(5)="PRINT RECORDS       (P)"
   70 A$(6)="RETURN TO LOADSTAR  (Q)"
   80 A$(7)="odaspq"
   90 sys32768+198,T$,6,A$(1),A$(2),A$(3),A$(4),A$(5),A$(6),a$(7)
   100 onf%gosub200,300,400,500,600,700	  
   110 goto 10

Make sure the number of items in your list$ matches the number declared with ITEMS. If you RUN this program, a typical LOADSTAR type program will pop up on the screen:

   M Y   D A T A B A S E 
   OPEN DATABASE       (O)
   DEFINE FIELDS       (D)
   ADD RECORD          (A)
   SEARCH RECORDS      (S)
   PRINT RECORDS       (P)
   RETURN TO LOADSTAR  (Q)

CRSR/RETURN TO SELECT

You'll have a CRSR/RETURN menu with hotkeys for each menu item, and more hotkeys if you simply include them. The menu is automatically centered left to right and top to bottom. CRSRing to ADD RECORD or pressing [A] will exit the menu and the variable, F%, will be 3. This is how you know which item or hotkey was selected by the user. There can be up to 40 hotkeys defined so that your page goes beyond the items presented on the menu. If hotkey #20 is pressed, the menu is exited, and F%'s value is 20. It's not mandatory for your menu to have alternative hotkeys, but if you do, list the menu's hotkeys first, and in the same order that they appear in the menu so that F% is always the same as the menu choices and the hotkeys.

Lines 10-80 set up the data for the menu into variables since you can see that there's no way all this text could fit on one line. Just imagine it with 20 hotkeys.

Line 90 calls the routine. Program flow is transferred to MENU TOOLBOX II until a menu item or hotkey is pressed.

Line 100 is one way of dispatching flow of the program based on the user input.

Ironically, this feature will only work from BASIC. I wrote the INSTANT PAGE feature as a simple driver to test MENU TOOLBOX II's ability to take commands from ML. I liked the routine I ended up with and decided it should be added to the package. Adding links for ML for this routine could be done -- but since I wrote the routine with many parameters intending for it to be called from BASIC, it becomes more difficult, even convoluted, to write ML links for a program which is essentially a series of ML links. Plus there's no time left this month.

Instant Page Setup:
SYS 32768+201, tilea, tileb, colora, colorb, title color, highlight color, menu color, message color, frame color, frame on, background, border

You can use my bland default colors or you can use your own. This command simply changes the presets.

Your background is made up of a mesh of two characters, A & B, in two colors. TILE A is one of the characters in the tiled background (0-255) TILE B is the other tile in the background

COLOR A is the color of TILE A, 0-15 where COLOR A has the following effect:

   COLOR A VALUE  COLOR

       0          BLACK
       1          WHITE
       2          RED
       3          CYAN
       4          PURPLE
       5          GREEN
       6          BLUE
       7          YELLOW
       8          ORANGE
       9          BROWN
      10          LIGHT RED
      11          DARK GRAY
      12          MED GRAY
      13          LIGHT GREEN
      14          LIGHT BLUE
      15          LIGHT GRAY   

This chart applies to all subsequent color values mentioned in the documentation.

COLOR B is the color of TILE B

TITLE COLOR is the color of the title of the page.

HIGHLIGHT COLOR is the color of the highlight bar of the menu

MENU COLOR is the color of the menu

MESSAGE COLOR is the color of the message at the bottom of the screen, "CRSR/RETURN To Select."

FRAME COLOR is the color of the frames surrounding the title and menu.

FRAME ON turns the frame around the menu on with a nonzero value. You might need to turn off the frame to squeeze in extra menu items. Maybe you don't like frames, either.

BACKGROUND is the background color

BORDER is the border color

Change Message:
SYS 32768+204,New Message$

In case your page needs a custom message at the bottom of the screen, change it here. Keep it less than 38 characters.

Screen To Menu:
SYS 32768+63,y,x1,x2,n,t,h,"keys"

Screen To Menu is an easy way to create a CRSR/RETURN menu from a vertical list of options that you've previously printed on the screen. So any list on your screen can be made to "spring to life" as a CRSR/RETURN menu. There may be up to 24 items, as wide as the entire screen. It's up to you to write the subroutines that correspond to each menu item.

After an item is selected, the variable, F%, tells you which item was selected. It will hold a value between 1 and the number of items in the menu. Here it is in use:

   150 sysaddr,y,x1,x2,n,t,h,"hotkeys"
   160 on f% goto200,300,400,500,600...

"f%" is the nth item selected.

Y is the starting row on the screen.

X1 is the left extreme of the highlight bar.

X2 is the right extreme of the highlight bar.

N is the number of items in the menu.

T is the text color of the unhighlighted items in the menu.

H is the highlight bar color.

NOTE: If you don't want the highlight bar to reverse items, add 128 to the color codes (0-15) of parameters T and H.

The MENU command has been extended per imperial order of Maurice Jones. Maurice likes to press one key instead of using CRSR/RETURN menus, which force you to press more than one key. The new "keys" field allows you to define hotkeys for each menu item, and also for flow control beyond the CRSR/RETURN menu.

For instance, you have five items on your menu, but "keys" is defined as "12345qlprt". 1-5 happen to be hotkeys for the menu in this example. You can use mnemonic keys if you like. If the user CRSRs to item 4 and presses RETURN, F% will become 4. If they press 4, f% becomes 4. But as a bonus, if the user presses "l", which is seventh in the KEYS string, F% becomes 7. If they press "r", F% becomes 9, and so on. MENU now has the power of BRANCHER. You can have up to 40 hotkeys in the string.

What would you use these hotkeys for? Well you might have a CRSR/RETURN menu, but also "q" to quit and SPACE to go to another menu. The only new requirement is that you now have to define hotkeys for each of your menus. It's a good idea to let your users know about the hotkeys.

To use screen menus from ML:

   ldx <parameters
   ldy >parameters
   jsr 32768+162

User input is returned in 253

Parameters is a stream of legal parameter bytes followed by the length of the hotkey string, followed by the hotkey string.

Introduction to Scrolling Menus

These menus are more involved to implement, but well worth the setup time. The multi-file selector in DISKMEISTER is an example of a quirky BASIC/ML slow POKE (pardon the pun). You need self-contained ML to handle your menus, especially scrolling ones. MENU TOOLBOX will create its own pointers for the menu items you define. Normally these pointers will be right at the end of the ML. Each item in your menu will take up 4 bytes. The pointers can extend under ROM and IO with no problem. If you don't want the pointers to be at their default location, you can change the array location with the following SYS.

Change Location:
SYS 32768+27,location

From ML

   ldx <location
   ldy >location
   jsr 32768+126

Since the default pointers will begin around $a000, you will want to change the location if you have data such as a screen stored there. Typically you'll want the pointers somewhere where they won't cost you anything, which is usually under some ROM.

You'll also want to use this command if you want to switch between pointers for different menus.

Declaring Menu Items

Before MENU TOOLBOX can create a menu for you, you must either BLOAD a directory, an EDSTAR PRG text file with a list of menu items in it, or declare items from DATA statements. I've included tools to make this process easy. Since directories are so structured, they don't need pointers so all you have to do is tell MENU TOOLBOX where to BLOAD the directory:

Bload Directory:
SYS 32768+39,"$:*",device,location

Before you can show a file requestor, you must first have a directory in memory. You can BLOAD a directory anywhere in RAM, even under IO at $D000-$DFFF. There is NO NEED to use the CHANGE LOCATION command after BLOADing a directory. F% holds the number of files, but keep in mind that counting starts from 0, not 1.

From ML:

   ldx <filename
   ldy >filename
   lda namelength
   jsr 32768+138

the directory filename, usually "$:*" must be followed immediately in memory by the device number byte and then the low/high bytes of the load address.

File Requestor:
SYS 32768+45,x,y1,y2,r,c,h,s,m

This command will pop up a scrolling (if necessary) menu on your screen. Your users will be able to CRSR up and down or page with the + and - keys. You should print this somewhere on the screen so that your users will know. Lotta parameters? Here's what they mean:

X is the upper left hand corner of the requestor box. Since directories are always going to be about 32 columns across, you would never have a number more than 6 here.

Y1 is the top row of the menu, 0- 20.

Y2 is the bottom row in the menu. Y2 determines how much of your screen will be taken up by the file requestor.

R stands for REVERSE mode. If you want all the items in the menu to be printed in reverse, put a 1 here. Highlighted items will appear unreversed.

C is the color of the menu and all unhighlighted menu items.

H is the color of the highlighted (current) item.

S is the color of selected files (if the menu is in multi-file select mode.

M is for MULTI MODE. It allows the user to select more than one file. Make this a 0 for a normal single file and 1 for multi-file selection ability. Files are selected with SPACE or RETURN. To exit the requestor you must press F1. Your program should inform the user of this if they are in the multi file mode.

When in single mode the file name is returned in W$, the position in the directory is in I% and the block size of the selected file is in B%.

From ML:

   ldx <location
   ldy >location
   jsr 32768+144

Have parameters as a stream of bytes in the order and extremes presented above. When in single mode, .X and .Y point to the filename and .A holds the file length. Compiler users, .A is location 780, .X is 781 and .Y is 782.

You can find F% at 253, I% at $14 and b% at $22

Index Items:
SYS32768+33,item

This command works best with bloaded directories, but can be used on normal scrolling menu data. It returns the filename or menu item string of ITEM into w$. When f% <> 0, it means the item or file has been selected. So when you have a multi file menu, do a loop to check each file. If f% <> 0, act on that file.

[Big note:] if you're hurting for string array space or suffering from garbage collection blues, why not store/load lists into menu item slots in high memory? You can use INDEX to check your hidden pseudo arrays, and DEFINE MENU ITEM (below) to store/flag items. Such arrays won't be dynamic, but they can come in handy.

From ML:

   ldx <item
   ldy >item
   jsr 32768+132

.X and .Y point to the returned string and .A holds the string length. F% is in locations 253 and 254 always.

Menus from BASIC Strings

Menu items can also exist in BASIC, but preferably in DATA lines and not in dynamic strings since some dynamic strings can change location after a garbage collection.

MENU TOOLBOX has to know a few things about your menu items before it can make a menu out of them. It has to know each item's place in the menu. Is it item number one or three hundred? If you have many items, you can tell MENU TOOLBOX all about your menu in a FOR loop with the following command. This isn't difficult to do. All you have to do is:

Define Menu Item:
SYS32768+30,item$,index,selected

Here you're telling the system the place of a certain string in your menu. If you're doing this from an array, you can use a FOR loop.

ITEM$ will always be a string variable, probably from an array or from DATA read into a string. If your menu items are in DATA statements, you don't need to DIMension an array to hold the strings. You can READ the data into a throwaway variable like a$ and then

   sys32768+42,a$,index,selected 

in a FOR loop. If you will want to print the menu item somewhere outside of the menu, you will probably want and need an array. In any case, string DATA in arrays doesn't take up any memory except for pointers.

INDEX is just the item's place in the menu.

SELECTED is whether or not the item should be considered selected when the menu pops up. You can use this even when not in multi-select mode to show that some items are not available or to highlight items to show that some pending action is needed.

From ML:

   ldx <parameters
   ldy >parameters
   lda string'length
   jsr 32768+129
   parameters .asc "item name"
   .word index
   .byt selected

Menu Command:
SYSaddr+42,x1,x2,y1,y2,r,c,h,s,o,l,m

This command will pop up a scrolling (if necessary) menu on your screen. Your users will be able to CRSR up and down or page with the + and - keys. You should print this somewhere on the screen so that your users will know. Here's what the parameters mean:

X1 is the upper left hand corner of the requestor box.

X2 is the right extreme of the menu. Any menu item that exceeds the width defined by X1 and X2 will be truncated.

Y1 is the top row of the menu, 0- 20.

Y2 is the bottom row in the menu. Y2 determines how much of your screen will be taken up by the menu.

R stands for REVERSE mode. If you want all the items in the menu to be printed in reverse, put a 1 here. Highlighted items will appear unreversed.

C is the color of the menu and all unhighlighted menu items.

H is the color of the highlighted (current) item.

S is the color of selected menu items.

O is the offset, in case you've sectioned off your menu items, generally zero. If you want to pop into the menu at a particular point (say at the last item selected which you've preserved), use offset to do so. The rest of the menu is still accessible.

L is the limit or the highest menu item allowed. Note that this will usually be one less than f% when you use the Rack Em Up command.

M is for MULTI MODE, which allows the user to be able to select more than one item. Outside of a file requestor, there are few uses for this. Make this a 0 for a normal single item and 1 for multi-item selection ability. Items are selected with RETURN or SPACE. To exit a multi-select menu you must press F1. Your program should inform the user of this if they are in the multi item mode.

When RETURN is pressed in single mode, the item number is returned in F%.

From ML:

           ldx <parameters
           ldy >parameters
           jsr 32768+141
parameters .byt x1,x2,y1,y2,,r,c,h,s
           .word o,l
           .byt m

Set Mode:
SYS32768+48,n

Sometimes you may have a regular menu and a directory set up in memory. You may want to set the proper mode for FIND AND CLEAR with this command before using it. N is 0 for normal retrieval and 1 for file requestor retrieval.

BLOADT Text File:
SYS32768+15,file$,device,location

This command will BLOAD a standard EDSTAR text file into memory and place a zero at the end of the file to mark the end. It can also be used as a regular BLOAD.

FILE$ is the filename of the file you want to BLOAD.

DEVICE is any legal device number.

LOCATION is anywhere in RAM except the IO area $D000-$DFFF. Again, you really should take advantage of areas outside of BASIC and beneath ROM.

You can indeed use packed text if you BLOAD it with DTEXT, published on LOADSTAR #122 and the COMPLEAT PROGRAMMER.

From ML:

              ldx <parameters
              ldy >parameters
              lda filename'length
              jsr 32768+114
   parameters .asc "filename"
              .byt device
              .word location

Rack 'em Up
SYS32768+36,location

This command simply itemizes every line in a text file that you've BLOADed so that it can be used as a menu. Pointers for each line in the text file will be located starting from the end of the file. So don't BLOAD a file that ends too close to $FFFF or the beginning of important data.

F% tells you the number of lines it has itemized. Save this into another variable because you will need the value to set a limit (bottom) to any menu made with the BLOADed data.

The longest length of a line is stored in $14 (decimal 20). If you want your resulting menu properly centered, check out this location immediately after the call as this location is heavily trafficked by Menu Toolbox and BASIC.

From ML:

   ldx <location
   ldy >location
   jsr 32768+135

Text File Reader

You would simply BLOAD a text file using the aformentioned command, and then RACK IT UP. Next just define a regular menu wide enough to accommodate the text anywhere on the screen. Don't forget to prompt your users to press RETURN to exit the reader (which is really a big menu).

Report Location:
SYS32768+54

If you don't want to rack up a text file again, you can find out and store exactly where the menu pointers begin with this command. The location will be reported in F%. Remember that F% is an integer variable, and has a max of 32767. So if F% is negative, subtract it from 32768:

   SYSAD+69:ad=f%:if f% < 0 then ad = 32768 - f%

From ML:

   jsr 32768+153 

Location returned in .X and .Y

Get Word:
SYS32768+51,color,cursor,limit,text$

Your program will probably need input from the user. Here you have the best input routine I've ever done. It allows you to cursor through already-typed text, and it allows you to predefine the text from a variable or static string, allowing the user to just hit RETURN if they don't want to change the text as it appears at the blinking cursor. The results of editing (or non-editing) is returned in W$.

COLOR is the color of text that is typed by the user.

CURSOR is the color of the flashing cursor.

LIMIT is the maximum length of the input.

TEXT$ will usually be null. If not, the contents of the variable will be printed at the current location of the cursor, respecting the COLOR parameter. The length of TEXT$ overrides LIMIT only if it's longer than LIMIT.

From ML:

              ldx <parameters
              ldy >parameters
              jsr 32768+150
              rts
   parameters .byt color,cursor,limit
              .byt length of default string
              .asc "default string"

Returns location of edited string in .X and .Y. .A holds the length of the string.

Start Memory Print:
SYS32768+60,location,string$

Continue Memory Print:
SYS32768+63,string$

Use START MEMORY print to start a list of text in memory. This command allows you to print to memory in case you want to build a menu from software instead of a table or file. You can print a list in memory, RACK it up, and make a scrolling menu out of it. Works beneath ROMs, too. A carriage return is appended to the string in memory.

Once you've started memory printing, just keep sending strings with continue memory print. The updated address of the end of your menu is kept in locations 251 and 252. USE NO OTHER COMMANDS while building your list with memory print! You might corrupt 251 and 252.

The final item in your menu should end with a character string 0 so that RACK IT UP knows where the end of your list is.

   sys32768+63,final$+chr$(0)

START From ML:

   lda <string'loc
   sta $22
   lda >string'loc
   sta $23
   lda string'length
   ldx <start
   ldy >start
   jsr 32768+156

CONTINUE From ML:

   lda <string'loc
   sta $22
   lda >string'loc
   sta $23
   lda string'length
   jsr 32768+159

Scroll Up:
SYS32768+18,x1,x2,y1,y1

This scrolls a section of the screen defined by the extremes above. Scroll need not be used with menus. That's done automatically, but since the code exists for the MENU command, I thought I'd give you direct access to it if you want. The cursor is placed right where new screen text would appear according to the parameters of the scroll.

From ML:

              ldx <parameters
              ldy >parameters
              jsr 32768+117
              rts
   parameters .byt x1,x2,y1,y2

Scroll Down:
SYS32768+21,x1,x2,y1,y1

This scrolls a section of the screen defined by the extremes above.

From ML:

           ldx <parameters
           ldy >parameters
           jsr 32768+120
           rts
parameters .byt x1,x2,y1,y2

Clear Row:
SYS32768+24,code,color

In case you have to blank a duplicated line in the scroll area, this command will do it using the screen code and color you specify. Cursor position isn't changed.

From ML:

   ldx code
   ldy color
   jsr 32768+123  

Titles

In order to make use of the internal tiles, you MUST use a custom font in your program. The use of fonts in programs is beyond the scope of this article. FOr information on fonts, please see LOADSTAR's Compleat Programmer or Font Finale on LOADSTAR #92.

Here is the command structure of the tile functions. Since I made three versions of the program, I'll refer to only the $C000 version. Replace 32768 with the other addresses if you will be using other versions.

Lattice:
SYS 32768,x1,x2,y1,y2,t1,t2,c1,c2

This command will create a colorful pattern on the screen. If T1 and T2 were 1 and 2, the grid would consist of As and Bs in the following fashion:

   abababababababa
   bababababababab
   ababababbababab

These lattices can be any dimension, as thin as a column or row and as large as the entire screen. They can be very colorful and eye-catching as you will see in DIRECTOMEISTER on our pass-around issue, available from our http://www.loadstar.com/

X1 is the leftmost column of the lattice, 0-39.

X2 is the rightmost column of the screen, 0-39 > X1.

Y1 is the top row of the lattice, 0-24.

Y2 is the bottom of the lattice, 0-24 > Y1. Note that if Y2 is greater than 24, the lattice can overwrite your BASIC program at $0801 (+2049).

T1 is the screen code of the tile in your lattice, 0-255. You can find the screen code of any character by printing it at HOME and then issuing the command:

   print peek(1024)

T2 is the screen code of the other tile in your lattice. It can be the same as T1 if you like. You can still get a lattice effect by using the same tile with a lattice of color only.

C1 is the color of T1, 0-15.

C2 is the color value of T2 in your lattice. As with tile selection, C1 and C2 can have identical values with T1 and T2 having different values, creating a lattice of tiles and not color. If T1, T2, C1 and C2 are all the same, then what you have is a block. There's a simpler way to get a block.

From ML:

          ldx <params
          ldy >params
          jsr 32768+102
          rts
   params .byt x1,x2,y1,y1,t1,t2,c1,c2

Block:
SYS 32768+3,x1,x2,y1,y2,code,color

This routine will draw a block of characters on the screen. It will also paint an area of the screen without changing the characters if you use a CODE of 255. It can erase portions of the screen if you use spaces, and it can draw single lines or rows of characters if you like. It is a mainstay of my programming. Can't do without it.

X1 is the leftmost column of the block, 0-39.

X2 is the rightmost column of the screen, 0-39 > X1.

Y1 is the top row of the block, 0-24.

Y2 is the bottom of the block, 0-24 > Y1. Note that if Y2 is greater than 24, the block can overwrite your BASIC program at $0801 (+2049).

CODE is the screen code of the tile in your block, 0-254. You can find the screen code of any character by printing it at HOME and then issuing the command:

   print peek(1024)

When a CODE of 255 is issued, the BLOCK program will not alter the screen at all, only the color. This allows you to change (PAINT) colors of portions of the screen without having to re-print them. If you must use character #255 on the screen, use LATTICE with both screen codes set to 255. With both codes and both colors set the same, LATTICE becomes BLOCK.

COLOR is the color of CODE, 0-15.

From ML:

   ldx <params
   ldy >params
   jsr 32768+105
   rts
   params .byt x1,x2,y1,y2,code,color

Outline Box:
SYS 32768+6,x1,x2,y1,y2,color

This routine will pop up a box on the screen using the CMDR-A,S,Z,X, SHIFT-ASTERISK and SHIFT-MINUS characters. The area inside the box will not be affected.

X1 is the leftmost column of the box, 0-39. X2 is the rightmost column of the screen, 0-39 > X1.

Y1 is the top row of the box, 0-24.

Y2 is the bottom of the box, 0-24 > Y1. Note that if Y2 is greater than 24, the box can overwrite your BASIC program at $0801 (+2049).

COLOR is the color of the box, 0-15.

From ML:

          ldx <params
          ldy >params
          jsr 32768+108
          rts
   params .byt x1,x2,y1,y2,color

Copy Tile:
SYS32768+9,FONT LOCATION,TILE,CHAR

This is a magic command. Within the ML are 60 tiles, lifted from TILE STYLIST. This command will copy any of those tiles to any character in your font. All you have to do is tell the command where your font is.

FONT LOCATION is the location of your font in memory.

TILE is the built in tile 0-9, that you want to have copied into your font.

CHAR is the screen code of the character you want replaced with the tile.

From ML:

         ldx <parms
         ldy >parms
         jsr 32768+111
         rts
   parms .word font'location
         .byt tile,char

More Than Sixty Tiles?:
SYS32768+12

If you use this command, you must be a tile fanatic. You can use values greater than 99 for TILE if you BLOAD a tile font into the proper location. This will only work with the $9000 and $0800 versions of TILE TOOLBOX. It can work with the $C000 version, but under normal circumstances, you can't BLOAD to the $D000 area, which is where the VIC chip and I/O are.

To get the proper BLOAD location, SYS32768+12. The address will be returned in the .X and .Y registers. For BASIC users, the address will be returned in locations 781 and 782.

ML users would simply insert the JSR before a LOAD:

   jsr 32768+12
   jsr LOAD

BASIC users would BLOAD their font into place this way:

   20 sys57812"tiles",8,0:poke780,0: sys32768+12:sys65493

This would give you a total of 266 tiles in memory if your tile font is 9 blocks long, but you will only be able to access the first 256, including the ten already in the ML.

Animation

You can use the COPY TILE command for animation by copying a series of tiles into the same CHAR. This will be much faster than drawing new characters or re-drawing an entire lattice or block. Of course if you're changing just one character, you can poke one byte on the screen, but the advantage of copying is that you have information [outside] of your font so your font isn't crowded and barely usable for text.

Shade:
SYS 32768+96,x1,x2,y1,y2

SHADE paints with intelligence. I have always used BLOCK to shade an area with a uniform color just beneath and to the left of a box I'm about to draw. This gives a nice 3-D effect. SHADE does one better. If there are multiple colors in the area, each color is assigned a darker shade. So your overlapping windows will have a consistent shading effect.

SHADE can have a flash-type cycling effect when used repeatedly on the same section of a screen. Eventually it will only cycle between blacks and all the shades of white.

From ML:

         ldx <parms
         ldy >parms
         jsr 32768+192
         rts
   parms .byt x1,x2,y1,y2

Screen Stash:
SYS 32768+66,page

Screen Restore:
SYS 32768+69,page

Screen Merge:
SYS 32768+87,page

Without screen swapping, pop-up help screens and menus would be cumbersome. These two routines will store a screen at any page (256 byte section) in memory. To store the current screen at $d000 (53248), you would:

   SYS 32768+66,53248/256 

To get the screen back:

   SYS 32768+99,53248/256

$D000 is at page 208. Note that each screen takes up 8 pages, and should be kept 8 pages apart.

Note that screen stash stores the current border and background colors, as well as cursor position per imperial order of Maurice Jones. Screen restore will bring back the border and background colors of the stored screen.

SCREEN MERGE will restore a screen "under" an existing screen, meaning that every place where there's a SPACE can be written to by the screen being merged. Background and border colors aren't changed by MERGE.

In case you're confused about what screen merge does, MERGE would be a simple screen restore on a blank screen. On a screen with something, anything that's not a SPACE or SHIFT SPACE, MERGE allows restored screen to bleed through without wiping out the current screen.

You can use MERGE in games like Concentration, where you only want to reveal part of the screen at a time.

STASH From ML:

   lda page
   jsr32768+165  

RESTORE From ML:

   lda page
   jsr32768+168 

MERGE From ML:

   lda page
   jsr32768+183

Link:
SYS 32768+72

Though all TOOLBOX routines that affect the screen use LINX and keep line links clear, you can call LINX directly with a SYS 32768+72. Same from ML.

Print At:
SYS32768+75,x,y,string$

This will print text anywhere on the screen. X and Y are your screen parameters. STRING can be a literal or a string variable.

From ML:

   lda <string'loc
   sta $22
   lda >string'loc
   sta $23
   ldx row
   ldy column
   jsr 32768+171

From ML the string must terminate in a zero.

Center:
SYS 32768+78,row,string$

Centers a string (fewer than 41 bytes) on a specified line.

From ML:

   lda <string'loc
   sta $22
   lda >string'loc
   sta $23
   ldx row
   jsr 32768+174

String must terminate in zero.

UPcase:
SYS 32768+81,variable$

Converts all characters in a string to upper case. "We, The People" becomes "WE, THE PEOPLE"

Note UPCASE will not print the string for you.

From ML:

   lda <string'loc
   sta $22
   lda >string'loc
   sta $23
   jsr 32768+177

String must terminate in zero.

LCase:
SYS 32768+84,variable$

Converts all characters in a string to lowercase. "We, The People" becomes "we, the people". Great for use before a test of input like Y and y or N and n to consistently lowercase input.

From ML:

   lda <string'loc
   sta $22
   lda >string'loc
   sta $23
   jsr 32768+180

String must terminate in zero.

CHARACTER SWAP:
SYS32768+90,a,b,c

CHAR SWAP will search the screen for parameter A and change it to parameter B with the color, C. Here A and B are screen codes as revealed in LOADSTAR LETTER #34 or page 376 of your Programmer's Reference Guide. But the quickest way to find out a screen code is to print the character in the HOME position and then:

   print peek(1024) 

or if your screen is moved:

   print peek(peek(648)*256)

In a flash, you can change every instance of a character to another character, or you can leave the character the same and just change its color. This is good for font animation where absolute speed isn't a factor.

Note: if you want to change characters, but not their colors, send a color code of 128.

From ML:

         ldx <parms
         ldy >parms
         jsr 32768+186
   parms .byt a,b,c

COLOR SWAP:
SYS32768+93,c1,c2

This changes every instance of a target color on the screen to another color.

From ML:

         ldx <parms
         ldy >parms
         jsr 32768+189
   parms .byt a,b,c

BRANCHER:
SYS32768+99,"string"

BRANCHER adds very quick flow control to BASIC programs. Send this routine a string and it will wait until a key, included in that string, is pressed. The string can be up to 207 bytes long. Imagine the BASIC code necessary to check 207 hot keys! This call will handle it in one command -- and much, MUCH faster.

When a valid key is pressed, BRANCHER will inform you which key was pressed by passing its instring position to the F% variable

   1000 SYS 32768+99,"mdvc":on f% goto100,200,300,400 

Here's the BASIC equivalent:

   1000 geta$:if a$<>"m"anda$<>"d" anda$<>"v"anda$<>"c"then1000
   1010 if a$="m" then 100
   1020 if a$="d" then 200
   1030 if a$="v" then 300
   1040 if a$="c" then 400

Not only is this code more bulky, but imagine how clunky it would be if you had 25 active keys.

From ML:

   ldx <string'loc
   ldy >string'loc
   stx $22
   sty $23
   jsr 32768+195

String must terminate in a zero.

License Agreement

As with all LOADSTAR tools, we encourage you to use them in your programming endeavors. You can do so without a licensing fee as long as you mention somewhere briefly in the docs that you got the routines from LOADSTAR. If you'd prefer not to mention us, write for permission. LOADSTAR's tools may be used in commercial products, and programs published in other magazines under the same provisions.

C= Hacking Home | Issue 14 Contents


Copyright © 1992 - 1997 Commodore Hacking

Commodore, CBM, its respective computer system names, and the CBM logo are either registered trademarks or trademarks of ESCOM GmbH or VISCorp in the United States and/or other countries. Neither ESCOM nor VISCorp endorse or are affiliated with Commodore Hacking.

Commodore Hacking is published by:

Brain Innovations, Inc.
10710 Bruhn Avenue
Bennington, NE 68007

Last Updated: 1997-03-31 by Jim Brain