Skip to main content

816 Vol 1 No 06 AUG 1990

  • Publication8/16 Central
  • Date1990-08-01
  • Pages44
  • Source816-Vol_1_No_06-AUG_1990.pdf
← Magazines 816 Vol 1 No 06 AUG 1990
/ 44
Source: Brutal Deluxe Software — Apple II/Mac user group newsletter, via applearchives.com.
Page 1
Loading…
Text content (OCR)
August, 1990 Volume 1, No. 6 The Journal of Apple II Programming $3.50 Toto, I don't think we're in Kansas anymore. (— = p In this issue: Computer Title Author Page both The Publisher's Pen Ross Lambert 3 re: the Publishing Time Warp, the Subscriber Survey, Our Directions lIgs Multi-Bank James Hodge 5 re: A Ilgs monitor utility 8 bit Checking out the Locals Ross Lambert 9 re: Ross delivers FN Local and FN SetEOF both Getting Over Extended Doni Grande 18 re: the good Dr. Grande prescribes accessing extended keyboards 8 bit Generic StartUp8 Jerry Kindall 26 re: a standard startup routine for 8 bit assembly both Vaporware Murphy Sewall 30 re: the industry-wide ruminations of Murph the Magnificent llgs Get Control of Yourself Jay Jennings o2 re: getting control over ~NewControl2 New kit restores your Apple Ilas Nite Owl's If you purchased an Apple IIGS computer before August 1989 (512K model), a Lithium battery was soldered onto the computer board at the factory and the internal clock started ticking. It is just a matter of time until the battery runs out of juice and your computer forgets what day it is and any special settings you have selected in the Control Panel. If the software you are running uses the date and time to keep track of records you could be in for real trouble when the clock runs out. The IIGS is also known to lose disk drives along with numerous other side effects caused by a dead battery. Before the introduction of Nite Owl's Slide-On battery, the normal method for replacing the IIGS battery was to pack your computer up and take it to your local Apple dealer. That was very inconvenient, time consuming, and expensive for the typical computer owner. “Slide-On Brand Battery ent Kit Apple fies Computer * Fantastic Savings * Easy Installation * No Solder Required « Complete instructions * 10 Year Shelf Life * Top Quality Lithium Slide-On battery replacement is not much more difficult than changing a light bulb. Using wire cutters, scissors, or nail clippers, the old battery is removed leaving the original wires still soldered to the mother board. The new Slide-On battery has special terminals which have been designed to fit onto the old battery wires. It usually takes only a couple of minutes. Complete, easy-to-follow instructions are included with every kit Typically, our customers have reported that the original equipment batteries have an average life expectancy of 2 to 3 years. This is about half as long as they were supposed to last. Slide-On replacement kits include Heavy Duty batteries which should provide for a longer battery service life We highly recommend that every IIGS owner keep a spare battery on hand ready for when the inevitable battery failure occurs. These Lithium batteries have a shelf life of over 10 years, and come with a full 90 day satisfaction guarantee Font Collection - The A2-Central staff has spent years searching out and compiling hundreds of IGS fonts. These fonts are packed onto eight 3.5 inch disks. They work with HGS paint, draw, and word processing programs. Includes a program to unpack them and an Appleworks data file. $39 WRAITH Adventure Game ARATTH fy bias Cnr Special J hool P ase Orders are Welco Introductory ]p Play Mo Map Ship to: B . * H - Help x . * Price $9.95 Coo ymit 16 ee Cash, Check, Money Order, This graphic adventure game comes complete on a single 3.5 inch disk with on-screen instructions, a | — map, demo play option, and dungeons which were too vast and expansive to fit on 5.25" disks The object is to search out and destroy the evil WRAITH to save the mythical island of Arathia. | —~~~—— — ane = Purchase To succeed at this quest the adventurer must fend Telephone #: Order off many monsters, learn magic spells, and buy SR weapons and armor to defeat the evil WRAITH. Works on ANY Apple ][ with a 3.5" drive. It will have a retail price of $14.95. One of the best Begentats] VISA Master Card Credit Card or PO# Expiration Date Price Amount ware values ever! * mcexpires 12 software values ever Offer expires 12/31/90 Slide-On Battery Kits | $ 14.95 us acall today at: (913) 362-9898 WRAITH Adventure $ 9.95 FAX: (913) 362-5798 = " a. po-oooc tcc -——4 Font Collection $ 39.00 | Nite Owl Productions | [Signature Tor Credit Card Orders ie ae | 1 5734Lamar Avenue A | __ Shipping & | Mission, KS 66202 | | Please include $2 shipping and Handling | USA , handling / $5 for overseas orders TOTAL Lo _| LKansas residents add 6% sales tax. i (Cut & Paste Address Label) Prices may Change without notice. 8/16 August, 1990 Page 8 "a 8/16 Copyright (C) 1990, Ariel Publishing, All Rights Reserved Publisher & Editor-in-Chief Ross W. Lambert Classic Apple Editor Jerry Kindall Apple ligs Editor Eric Mueller Contributing Editors Walter Torres-Hurt Mike Westerfield Steve Stephenson Jay Jennings Tamara Lambert Becky Milton Subscription Services Introductory subscription prices in US dollars: * magazine 1 year $29.95 2 years $56 + disk 1 year $69.95 6 mo $39.95 3 mo. $21 Canada and Mexico add $5 per year per product ordered. Non-North American orders add $15 per year per product ordered. WARRANTY and LIMITATION of LIABILITY Ariel Publishing, Inc. warrants that the information in 8/16 is correct and useful to somebody somewhere. Any subscriber may ask for a full refund of their last subscription payment at any time. Ariel Publishing's LIABILITY FOR ERRORS AND OMISSIONS IS LIMITED TO THIS PUBLICATION’S PUR- CHASE PRICE. In no case shall Ariel Publishing, Inc., Ross W. Lambert, the editorial staff, or article authors be liable for any incidental or consequential damages, nor for ANY dam- ages in excess of the fees paid by a subscriber. Subscribers are free to use program source code printed herein in their own compiled, stand-alone applications with no licensing application or fees required. Ariel Publishing prohib- its the distribution of source code printed in our pages without our prior permission. Direct all correspondence to: Ariel Publishing, Inc., P.O. Box 398, Pateros, WA 98846 (509) 923-2249 (voice), (509) 689- 3136 (fax) Apple, Apple Il, Apple Ile, Apple ligs, Apple lic, Apple Ilc+, Ap- pleTalk, Apple Programmers Workshop, and Macintosh are all registered trademarks of Apple Computers, Inc. AppleWorks is a registered trademark of Claris, Corp. ZBasic is a registered trademark of Zedcor, Inc. Micol Advanced Basic is a registered trademark of Micol Sytems, Canada We here at Ariel Publishing freely admit our shortcomings, but nevertheless strive to bring glory to the Lord Jesus Christ. > JD NS The Publisher's Pen by Ross W. Lambert Ihave finally entered the publisher's time warp. Iam writing for a post- A2 Central Summer Conference audience even though the event has not happened yet. For that reason we'll be covering the happenings in more detail next month. About all I can tell you now is that by the time you read this Apple will have unveiled (but not officially released) some remark- able achievements in Apple II software engineering. Probably the most remarkable is HyperCard GS. If the rumors are correct, this critter can run stacks written on the Macintosh. I bet somebody suffered to make that happen. According to the conference schedule, we'll also get a look at an animation toolkit for the GS and a few other goodies. I may not be able to discuss every- thing in great detail because many of the Apple, Inc. seminars require non-disclosure agreements. Still, we'll bring you all the news that fits in print, or whatever. So hang on until next month. I bet we scoop inCider/ At. Half a birthday to you, half a birthday to you... 8/16 is one half of one year old with this issue. I'd like to use this occassion to humbly request your analysis of our publication. We have included a subscriber survey form toward the back of this issue which is designed to be cut out. There is no “content” on the back side of it or anything. There are lots of questions on the form, some of which are about you. Our intent with this survey is not to be nosey, but rather to A) massage our content to meet your desires, and B) get a demographic profile of our subscribers. Let's be frank: advertisers like that sort of thing. Even so, feel free to skip any part of the form that you don’t want to fill out. 8/16 August, 1990 Page 4 This magazine is not nearly as dependent on adver- tising as most publications, but we'd be fools not to encourage folks to travel that avenue. WARNING: Let me strongly encourage you to fill out the survey. These types of things tend to attract a disproportionate number of the “least satisfied”. If you are pretty much happy with the magazine it is important that you say so in order to help prevent us from having a skewed view of the results. Ariel Publishing, Inc. is most definitely a customer-driven. sort of operation, so if folks seem to be saying “Jump!”, our response will be “How high?” The View From Pateros At the risk of sounding arrogant, nearly 100% of the mail we've gotten has suggested that 8/ 16is the best thing since frozen yogurt. I am proud of our work to date, yes, but I know it is far from perfect. And a few folks have shared their concerns with me already. Here’s where I plan to put our emphasis in the future: Q More graphical presentation of concepts (a pic- ture is worth a thousand words, so to speak). This is harder than it sounds. Q More and lengthier explanations. Some of our authors (including me) have made some pretty hefty conceptual leaps at times. Q More code in higher level languages (C, Pascal, Micol Advanced Basic). Q Earlier distribution. We're moving back produc- tion for the October issue by one full week. This should get it to most of you by the first day or two of the month. Q Faster, more consistent service. We've hired two part time people to help fill your orders and manage our data entry. Such expansion is a fairly bold move in the face of the current Apple II market. We are not a mail-order software house, however. I do not plan to aim for the 24-48 hour turnaround of the mail houses. I do plan to get orders filled in approximately five working days or better. Those are my priorities for our second six months of life. Now it is your turn to tell me yours. == Ross == —_ eetateehegetie Bn ATTRA: Ponte ne SOO rere nc me tr, ene ee Ne a AMER the single most important business-oriented product for the Apple Il since AppleWorks.” APPLE Il BY CHARLES H. GAJEWAY «Masterful database. Are you { ready for a sweeping statement? Here goes: I think that DB Master Profes- sional (Stone Edge Technologies: $295) is the single most important business- oriented product for the Apple II since the introduction of AppleWorks. As the only true relational database program for the Apple Ile, Ic, and IIGS, DBMP can give a 128K Apple Il the kind of data-handling power and flexibility nor- mally associated with MS-DOS and Macintosh systems running expensive and hard-to-leam software. (A relational database can link, or relate, information DB Master Professional from several data files.) Tjumped right into the program with my standard test data—a pair of files that tracks a record collection, with in- formation on album titles, artists, mu- sic category, song lengths, and com- posers. This test is complex, and many well-regarded programs—including AppleWorks—have failed miserably at it. Even with very little experience, I was able to get the system up and run- ning with DBMP ina surprisingly short time. Report generation is extremely pow- erful, making iteasy to design anything from a mailing label, to a point-of-sale invoice (that automatically updates in- ventory records, of course), to custom- ized form letters. Whereas most data- base programs must be combined with a word processor to do complex reports or mail merge, DBMP does it all. The manuals are complete, well il- lustrated, and generally clear, although they are sometimes overly technical and fragmented. You will need to keep both books handy at all times, especially as you try out some of the more sophisti- cated features. And while the program is operated with a simple menu system, DBMP takes a fair amount of time to Jeam because of its array of features and options. DBMP gives you all the power you need and can even import your current files from AppleWorks (except version 3.0) and other programs. I Reprinted with permission from Home Office Computing. Stone Edge Technologies, Inc. P.O. Box 3200 * Maple Glen, PA 19002 » (215) 641-1825 August, 1990 Page 5 IIgs Programming Multi-Bank: A IIgs Monitor Utility by James Hodge Editor: We here at 8/16 are quite pleased to have James write for us. As a long time CALL A.P.P.L.E. author he has already wowed us with neat stuff on many occassions. Welcome! Modern computers are really something! Long gone are the days when a 48K Apple was considered a big machine. Now you need 768K to 1280K to run many common games and applications. To be fair, a lot of the software available today is pretty impressive, despite the hardware requirements. Monster machines place an added burden on pro- grammers. It would have been nice if Apple had endowed some of the IIgs monitor commands with the ability to work across bank boundaries, but they didn’t. As a result, trying to clear out 10 or 12 banks of memory, or find a byte pattern “needle” in the memory “haystack” can be a tedious task. The “Multi-Bank” monitor utility presented here can ease some of the tedium by forcing the Apple to do more of the work. The Multi-Bank routine takes advantage of what is probably the least used feature of the Apple monitor, the ability to repeat some, or all, of the command line. This is documented in the old _Apple ][ Refer- ence Manual_on page 56 and in the new _Apple IIGS Firmware Reference_ on page 46. As explained in the Firmware Reference, the repeat- ing command trick alters the index that the monitor uses as it scans the keyboard input buffer at $00/ 0200. When the monitor locates and executes a command it saves the value of the index at $00/0034 (also called YSAV) and then reloads the index regis- ter and resumes scanning the command line when it has finished. By changing the value at $34, you tell the monitor to continue parsing the input at some other point in the keyboard buffer. To see what happens to location $34 when the monitor parses the command line, try the following example (tilde characters (~) are used to indicate spaces): an~~34~~34~~34~~34:0~<ret> The result will look like this: 00/0034:06-. 00/0034:0A-. 00/0034:0E-. This will repeat until you press Control-Reset or shut the machine off. To make use of this trick there are a couple of rules that must be observed. You need to start the repeat- ing portion of the command line with a letter com- mand (N, the monitor “normal video” command, is suggested) and end the command line with “34:x “, where x is a hex value specifying the position of the start of the loop. To start the loop at the beginning of the command line, x would equal 0. The line MUST end with a space. The manuals state that the only way to end the loop is by pressing Control-Reset. "The Multi-Bank routine takes advantage of what is probably the least used feature of the Apple monitor, the ability to repeat some, or all, of the command line.” With a little extra machine language, the “repeat” command becomes quite a time saver. Multi-Bank, 8/16 August, 1990 Page © a routine that runs at $300, allows monitor com- mands to work throughout the memory of a Ilgs, rather than being limited to a single bank at a time. The upper limit of memory you wish to operate on is hard-coded in the program, and when that limit is reached Multi-Bank will terminate cleanly. Multi- Bank was designed to work in conjunction with the pattern search (P) and fill memory (Z) monitor com- mands, but it will also work with the move (M) and verify (V) commands. It’s also possible to arrange a command line to make Multi-Bank work with the memory change and examine commands. About Multi-Bank On the first pass through Multi-Bank, an indirect address pointer to the input buffer is set up at locations $8 and $9 and a flag is set to indicate that initialization has been performed. Multi-Bank then searches for, and expects to find, the “<“ character within the first $40 bytes of the input buffer. Ifthe “<“ symbol isn’t found in the first $40 bytes of the input buffer, the command sequence will terminate. As- suming that it is found, Multi-Bank leaves the pointer aimed at the two digit bank specification that follows it. The initialization step will not be used again. At this point Multi-Bank increments the bank number and checks to see that it is within the limit set by “max_bank”. If it is, control returns to the monitor and the rest of the command line will be scanned and executed. If the bank number equals max_bank, Multi-Bank will re-zero the “frstpass” flag and place a Return character in the command line to end the loop. Multi-Bank expects to be called with the registers set to their 8 bit width. Adding the command “SEP $30” at the beginning of the routine would ensure the condition was met, but right now it is the user’s responsibility. Multi-Bank will only work on the bank number following the first “<“ symbol in the command line. The routine is machine-specific since the value for max_bank is hard-coded. The value for max_bank should equal the highest bank number plus 1. Different users will have to determine the upper limit that suits their needs. Generally, you won't want search (P) or zap (Z) commands operating on the so called ROM disks provided by battery backed up memory (e.g., the Applied Engineering Ramkeeper) or in memory allocated to RAM disks. As with any monitor command that specifies a range of memory to work with, you MUST be careful not to reference the areas of memory containing the softswitches (unless you like to turn on disk drives and change the screen mode from text to trash). Using Multi-Bank Installing Multi-Bank might take a little forethought. Ifyou are running ProDOS 8 or DOS3.3 then youcan. BLOAD MULTI.BANK. If, while in a GS/OS applica- tion, you expect to get into the “Visit Monitor” desk accessory and use Multi-Bank you'll want to put the program on a RAM or ROM disk, or store it ina (hopefully) unused area in memory, and then use the memory move (M) command. There are times during program development that I need to know what areas of memory are being used. Since I have an AE RamKeeper installed in my system, it causes “clutter” to accumulate (old, junk values in memory) that won’t go away by simply switching off the machine. Acommand to set most of the memory in a IIgs to zeroes would look like this (again, tilde characters (~) are used to indicate spaces): *n~~0<02/0. ff£ffz~~n~~0/300g~~n~~34:0~<ret> This example would first set bank 2 memory to zeroes and then it would call the Multi-Bank routine with the command “0/300g”. Multi-Bank would do its work and return control to the monitor. The rest of the line would be parsed and executed and, since $34 had been set to 0, the command line would execute again, but with a bank value of 03. This process would repeat until Multi-Bank reaches its limit, at which point it would replace the next command in the line with a Return character to force the loop to terminate. The example starts at bank 2 so it will avoid the $CO00.COFF softswitch areas in banks 0 and 1. (Warning: This command string can destroy the operating system in RAM memory. GS/ OS system 5.0 loads into RAM so that switching between Applesoft and P8 applications and GS/OS applications goes quickly. If you launched BASIC under GS/OS, you may need to switch your GS off and on again to reboot your system.) 8/16 August, 1990 Page 7 Using Multi-Bank with a pattern search (P) com- mand requires extra care in the way the command line is formed. When the monitor processes a search request it places a length byte at $200 followed by the pattern to search for. That de- stroys the first part of the command in the input buffer. The workaround for this problem is to start the command line with blanks or “N"s (Normal video commands). There should be enough of a buffer to allow for the search pattern and its length byte. The value to store at $34 should point to a letter command at the end of the pattern buffer area. I usually leave an area slightly larger than I need, rather than trying to figure out the smallest space needed. Multi-Bank pattern searches look like this: A ennn enn n~~\6b 08 €2\<02/ 0. £££fp~~n~~0/300g~~n~~34:b~<ret> *nnnnnnnnnnnn~~\"hi world”\<00/ 0.bfffp~~n~~0/300g~~n~~34:b~<ret> Rig minireni n~~\”Apple”\<02/0.££f££p~~n~~0/ ~34:6~<ret> The first two examples show command lines with buffer spaces larger than needed. The first searches for a three byte pattern, and the second example searches for the text “hi world”. (Note: The high bit in the bytes of the text pattern will depend on the system mask (F). Using the monitor command “FF=F" before entering text into the monitor will set the high bit, while the command “7F=F" will clear it.) The third example does a pattern search and calls Multi-Bank, but before it repeats it dumps mem- ory in the range 0/212.215. This allows you to see the bank values change, but it also clutters up the display and makes it harder to see the output from the search command. It's possible to enhance the memory change command to work across bank boundaries using Multi-Bank with a creative command line. The following example shows how to place a particular byte sequence into multiple memory banks: *34:1a~~n~~<01/1000:1~2~3~~n~~0/ 300g~~n~~0/20a:a0~~n~~34:7~<ret> The command “34:1a” causes the monitor to skip the “n <01/1000:1 2 3” and go to the second “n” in the command line (at $00/02 1a). In this case the index at $34 is adjusted to point farther into the input buffer, rather than towards the buffer start. When Multi-Bank is called it sets up a pointer to the bank specifier following the “<“ character and then increments the bank number. The next significant command, “O/ 20a:a0”, changes the “<“ character to a blank. The “<“ character is needed only so Multi-Bank can find the bank number. Control then loops back to repeat the command line, starting at the normal video command “n” at $00/0207. When the monitor executes this line the second time the command “<01/1000:1 2 3” has been changed to “ 02/1000:1 2 3”, so the values 1, 2, and 3 are placed into memory starting at $02/1000. Multi-Bank increments the bank number again and the process repeats until the max_bank value is reached. Because this sequence of commands incre- ments the bank number first, you need to start with a bank value of one less than the first bank you want to affect. To summarize the rules for using Multi-Bank: v 1. It must be located at $0/300, unless it is “ORGed” and assembled to execute at a different address. v 2. The value of max_bank should be set to either the highest bank number + 1 of the machine, or to the value of the highest bank + 1 that you wish to operate on, as appropriate. v¥ 3. Max_bank is encoded as a pair of ASCII digits with their high bits set. Valid values range from “O" through “9” ($BO to $B9) and “A” through “F” ($C1 to $C6). v 4. There must be at least one blank following the command to set $00/0034. v 5. The firstpass flag should be zero. If a previous command terminated prematurely, either by hitting reset or by failing to include a space after the command “34:x", you will have to zero the flag or reload a fresh copy of Multi-Bank. v 6. The registers should be set to 8 bit width. The value of the m and x flags should be 1. v 7. Multi-Bank expects to find the “<“ character in the first $40 bytes of the input buffer, followed by a 2 byte 8/16 August, 1990 Page bank specification. While Multi-Bank may not revolutionize your devel- opment work, it should prove itself useful if you need its ability. Program Listing: Copyright a es tr org ida bne inc ida sta stz findbank inc ida cmp beq ida cmp bne inc do_it ldy lda inc cmp bee bne lda bra nextchar cmp bec lda inc sta lida Monitor Command Multi-Bank Looper by James A. Hodge - 9/19/89 Assembler: Merlin 8/16 1990 Ariel Publishing and James Hodge - some rights reserved adr $300 frstpass ;first pass flag do_it 7do fndbnk 1st #pass only frstpass ;set flag #2 $9 $8 ;point 8.9 at kbd buff $8 ;increment pointer $8 ;check it #540 so_long;quit after X bytes ($8) ;locate 2 byt sbank# that #0< gafter “<“ symbol findbank ;if not *<™* ;continue $8 ;leave this -> to bank# #1 ($8) ,y ;inc low byte of bank# #”9"+1 ;valid values = 70-9, A-F ok ;if val = 0 to 9 nextchar Pra pA =O" 41 o_k HOR TH ok sif val =AtoF ($8) 7else ; inc high byte ($8) #70" set lo byte to “0” ok sta ($8),y ;now bank#’s inc'd emp max_bank+1;chk lo byt ;of max_bank bee go_on lida ($8) check hi byte cmp max_bank ;if bank# >= then quit bes so_long go_on rts so_long stz frstpass ;0 flag for reuse ldy $34 7get cmnd line index lda #$8D ;carriage return char sta $201,y ;terminate cmd line rts max_bank asc “18” frstpass hex 00 MicroDot | t$,22.95 {freeing up some RAM her BS = The Logical 9 os Replacement a: for Var BASIC.SYSTEM Just 2.5K in size, but more powerful than BASIC.SYSTEM. Imagine doing BASIC overlays simply by specifying the file name and the line number where you want to overlay. How about loading an array of directory names at machine lan- guage speed. You get this and total control over ProDOS that is impossible with BASIC.SYSTEM. Works with Pro- gram Writer ($42.45. Both for $59.95 + S&H). Love it or get your money back! Inexpensive publishers’ licenses. Free Catalog and Details Dealer Inquiries Invited Kitchen Sink Software, Inc 903 Knebworth Ct. Dept. 8 Westerville, OH 43081 (614) 891-2111 August, 1990 by Ross W. Lambert You Z-fans out there got a little bit short-changed last month; I had to cut an article due to lack of space. I ended up axing my own contribution. I thought I'd counter that this month by providing you with an extra dose of Z-Power. We're going to cover two separate topics; hang on to your hats. Those of you who are not really into ZBasic may want to read along anyway because | dip into compiler construc- tionjust a tad. You might (shudder) learn something. Part I: FN Local and FN Global Those of you who read these articles closely probably noticed that I promised local variables for ZBasic in a “teaser” at the end of my June column. From the sounds of things, nobody really believed me. O ye of little faith. The ZBasic Zealot is long gone, ofcourse (i.e. switched out), but youcan still get at the system monitor in the highest reaches of ROM. Inside the monitor ROMS there lives a little memory move routine. It hides discreetly at location $FE2C. The only caveats for using this bugger are that it will not copy data between banks (main and aux) and your source block cannot overlap to the right (i.e. to the high memory side) of the destination block (see Figure 2). Neither caveat is an issue for our current purposes. We only intend to move memory in main memory, and our source variable data and the data buffer are in sepa- No, I didn’t rewrite the language or even patch it. Rather, I created a little function that takes ad- vantage of the way ZBasic "You can access the Apple monitor from within a running ZBasic program.” rate, discrete blocks of memory. Speaking of blocks: that brings us to the costs of FN Local. organizes data in mem- ory. Ina nutshell, I stash the variables you want “localized” into a buffer. When you want their values restored, I move them from the buffer back into the correct spots in mem- ory. Easy stuff. And it was made even easier by a fact that may surprise a few of you; you can access the Apple II monitor from a running ZBasic program. Applesoft There ain’t no free lunch Here’s a mini-lesson on compilers... in other times and places (and CPUs) compilers create what is called a “stack frame” whenever they encounter a function, subprogram, etc. A stack frame is simply a little section of memory on the stack (c.f. my June 8/16 August, 1990 Page 10 90 column) that belongs to the function being called. The first thing a compiler usually does when creating function code is to save the current address of the stack pointer. The function is then allowed to keep its variables on the stack, and then when the func- tion is all done it just resets the stack pointer to its old value. The function’s old local variables just float away. When I first attacked the question of local variables, I'm sure that I had to grapple with the same issues the ZBasic authors did. On most microcomputers, and especially eight bit Apple IIs, stack space is at a premium. We've only got 256 bytes, and most of that will already be spoken for by the time one of our functions steps up to bat. Some compilers have opted to create what is often called a “pseudo-stack”. This section of memory behaves like the normal system stack, but the CPU itself does not manage it or have instructions to access it directly. A pseudo-stack is merely a Last In First Out data structure managed by the language, not the CPU. They are just like the LIFO structures I mentioned in my June ’90 column. One problem with pseudo-stacks is that they tend to be slow. Another problem is that they take up memory, and usually a lot of it. ZBasic does indeed have a pseudo-stack for its various internal operations, but it is relatively small because it doesn’t mess with local variables. This is all a long winded excuse for not creating a FN Local that pushes your local variables on the stack. Chances are you'd get a ?9STACK OVERFLOW error or trash the system so often it'd be more trouble than it is worth. The simplest way to provide some of the functionality of local variables without hardly any hassles at all is to ask you to plan ahead. Thus FN Local comes at two main costs, organization and memory. The organization cost involved stems from the fact that the range of variables you'd like localized must be contiguous in memory. In order to make them contiguous, you have to dimension them in order. For example, DIM IntOne, IntTwo, DIM 100 MyString$, ArrayOne (999), IntFour IntThree ..creates a block of memory 2108 bytes long. Each integer variable is two bytes long (for a total of eight bytes), the string is defined to be 100 bytes, and a 1000 element integer array at 2 bytes per element is 2000 more bytes. If I added correctly, we get 2108. You could, using FN Local, save this entire block of memory, pollute each and every one of the variables, and then restore them all in one fell swoop with FN Global. Neat, huh? Well, yes, except that there is one more cost: RAM. Since I have elected not to push the variables to be localized onto the stack, you must provide some RAM for temporary storage. Since every program (and indeed, every programmer) is different, I de- cided not to mandate a buffer size or location. That is up to you. Fortunately, there are several potential locations that may be useful depending on the type of program you are writing: Q One obvious option is to create your buffer in the standard ZBasic data space (in main mem). This is what I chose to do in the demo code, DIMensioning a LocalBuffer(10) array. This storage option works best when you don't have tons of variables to localize or you have lots of data storage space available. O Another option is to use the high resolution graph- ics page. This whopping 8K block ($2000-$3999) is unused by text based ZBasic programs. Q There is also the page three free space (200 bytes starting at 768). Q Finally, you could find the start of your block with VARPTR, save it to a temporary file on a disk or RAMdisk with the BSAVE function (on the ZBasic distribution disk), and then restore the entire thing with FN BLOAD. This would, in fact, create some- thing a little bit akin to virtual memory. It’s really a neat trick for super memory intensive applications. Back to the BASICs When a new variable is DIMensioned or defined in ZBasic, the variable storage pointer is moved lower in memory by the appropriate amount (c.f. Figure 1). 8/16 August, 1990 Page 12 Figure 1: ZBasic Variable Memory Use top of variable bytes 0-1 DIM IntOne space ($A7CO in the 128K bytes 2-3 DIM IntTwo, DO: i Fepesseoe) DIM ArrayOne (999) bytes 4-2003 bytes 2004-2005 DIM IntThree variable space bytes 2006-2105 DIM 100 MyString$ pointer — XS bytes 2106-2107 remaing RAM variable spaci DIM IntFour y, This means that if the first four variables you define are integers, you can find the beginning of the 8 byte block they occupy by getting the VARPTRof the last variable defined. Like so: DIM One, Two, BlockStart = Three, Four VARPTR (Four) The same principle applies to all data types; inte- gers are just easier for demonstration purposes. Consult your ZBasic manual for the lengths of other data types (and don't forget to consult your configuration screen for how many digits of preci- sion you've set for floating point vars). Don't let arrays throw you off either. Although they store their data internally lowest to highest in memory (i.e. element one starts lower in memory than element two), the start of the entire array is lower than the variable declared or DIMmed imme- diately before it. How to get it to do what it does As I mentioned earlier, you two main concerns when localizing variables are “what” (what variable block to localize) and “where” (where to put it). Assum- ing you can answer both of those questions, the syntax to the function looks like this: REM saves bytes starting at Source FN Local (Source, Bytes) REM restore bytes that live at Source+ FN Global (Source, Bytes) As you might guess, one important use of these functions is inside other functions. For example, LONG FN MyFN FN Local (Source, Bytes) . pollute all the variables living at Source to Source+Bytes FN Global (Source, Bytes) END FN This means that you can really make your functions independent of one another and increase the liklihood that you can use them in another program without variable trashing. 8/16 August, 1990 Page 12 Another approach, and the one I used in the demo, is to call FN Local before calling a function and FN Global after calling a function, thereby restoring any variables that may have been trashed during the passing of parameters. Like so: FN Local (Source, Bytes) X = MyFN (Whatever) FN Global (Source, Bytes) Digging into the Demo You'll notice that the functions assume that the start of the variable buffer can be found at LocalBuffer. You assembly hacks will also note that I set the Y register of the CPU to zero before the jump to $FE2C. This is necessary because Y is used as an offset for the indexed indirect addressing loop that lives in the monitor memory mover. And I “bounced off” the RTS in ROM, saving a byte (I’m cheap), hence the JMP instruction in the MACHLG statements and not a JSR. The LONG FN MoveMem does most of the work; FN Local and FN Global switch the parameters around for you so that it is all a little less taxing on the ol noggin. Improvements Now that I've pretty much finished the code and run up against our publication deadline (earlier this month than normal due to KCFest), I've thought of some really wonderful additions... As the functions stand right now, they don’t manage the buffer memory for you at all. They always stash the data to be saved at the begnning of the buffer, memory location LocalBuffer. A better solution would allow you to stash as many sets of data as would fit into the buffer. This would involve keeping track of what was where, but that could be easily handled with a BuffPtr(x) array. For the block of data you number as X, look up its position in the buffer by reading BuffPtr(X). Another approach would be to treat the data buffer as a pseudo stack. Each time you “push” a group of values onto the stack, you increment the “stack pointer” by the size of the block. To get the values back, just “pull” the values off the stack and down into the right location in memory. Hopefully this code will inspire you to do something truly outstanding, or at least make your life a little easier. Listing 1: FN Local and FN Global REM REM FN Local and FN Global REM REM by Ross W. Lambert REM Copyright (C) 1990 REM Ariel Publishing, Inc. REM Most Rights Reserved REM REM I assume that the default REM var type is integer REM DIM Xtop, Ytop,Xbot, Ybot : REM demo data DIM LocalBuffer(10): REM temp buffer ML = 768 LocalBuffer = VARPTR(LocalBuffer (0) ) LONG FN MoveMem (Source,Dest, Amount) Z1 = PEEK WORD (60) : REM save zpg Z2 = PEEK WORD (62) Z3 = PEEK WORD (66) POKE WORD 60,Source : REM poke addrs POKE WORD 62,Source+Amount POKE WORD 66,Dest REM This ML routine could be REM deposited at startup and REM then just CALLed as long as REM it was not overwritten by REM anything else. REM ldy #0 POKE ML, 160:POKE ML+1,0 REM jmp $FE2C POKE ML+2,76:POKE ML+3, 44 POKE ML+4,254 August, 1990 Page 18 CALL ML POKE WORD 60,Z1 : POKE WORD 62,22 POKE WORD 66,23 REM restore zero pg END FN DEF FN Local (Source,Bytes) = FN MoveMem (Source, LocalBuf fer, Bytes) DEF FN Global (Source,Bytes) = FN MoveMem (LocalBuf fer, Source, Bytes) REM ---39----=----- REM Main REM ~~~-----------~ Xtop = 10 : Ytop = 20 Xbot = 30 : Ybot = 40 MODE 7 : REM double high res graphics CLS PRINT Xtop, Ytop, Xbot, Ybot:REM before... FN Local (VARPTR(Ybot),8):REM save data Xtop = 50 : Ytop = 100 : REM pollute it Xbot = 90 : Ybot = 170 BOX Xtop,Ytop TO Xbot, Ybot FN Global (VARPTR(Ybot),8):REM restore it PRINT Xtop, Ytop, Xbot, Ybot :REM after... INPUT R$ MODE 2 END Part II: Playing with ProDOS The remainder of this article was inspired by long time, loyal subscriber Jim Shug of Midwest Agri- Business Services. Ol’ Jim called me when he noticed that even though he had deleted several large chunks out of a text file one of his programs was maintaining, the actual file size reported in the directory was not getting any smaller. This occurs because ProDOS cannot really make any assumptions when you don’t write up to or past the end of the file. Unlike MS-DOS, ProDOS does not have an end of file “character”. Instead, it maintains the file length as part of the information that travels with the file. There is therefore no writing an EOF character to the middle of the file and getting ProDOS to adjust automatically. That is one of the very few advantages to MS-DOS, I can tell you. And even that advantage is occassion- ally troublesome. If an EOF gets written mid-file by accident (perhaps an embedded control-character in a file or something) all of the data past the character boils off into the vacuum of space. There are two solutions to the EOF problem for ProDOS 8. The first is to avoid the situation altogether ala’ AppleWorks™. AppleWorks creates a temporary copy of the file to be saved and then goes back and deletes the original. After that it renames the tempo- rary with the same name as the original. The problem with this solution is that your users will run out of disk space long before their disks are actually full. If you're working with floppies, as soon as the original AND the temporary file exceed the disk size, you have a problem. AppleWorks 3.0+ solved this by asking users if it could delete the original to get more space. Although the technique works, deleting the original tends to scare the heck out of the non-hacker crowd. Another solution is the one we'll take here: explicitly set the file length yourself by doing a call to the ProDOS Machine Language Interface. As you'll see, it doesn’t really require any knowledge of machine language. And in the process we'll discover a fun little tidbit about mixing Z and MLI calls. The Tidbit (or TidByte) Whenever you open a file under ProDOS 8, the DOS assigns a reference number to the open file. This way it can refer to open files by number and not have to dink around with pathnames all the time. This is true whether you open the file with ZBasic’s OPEN or do it via assembly language. To muddy the waters some, the file number that we assign to an open file in ZBasic is most definitely not the same as the ProDOS reference number. The ZBasic file number is really for our bookkeeping purposes. ProDOS returns a reference number to ZBasic, but ZBasic does not pass it on to us. At least 8/16 Awgust, 1990 Page 14 Va . o Figure 1 : Resetting the End of File Pointer to Reflect Deleted Data Myfile: 10 items at 10 bytes each. EOF = 100 bytes EOF still = 100 byte 0 byte 0 Item 1 Now delete Item 2 item number 5, Item 3 pulling up all Item 4 the others that Item 5 follow. Item 6 Item 7 —__» Item 8 Item 9 Item 10 byte 99 byte 99 Unless you reset the EOF pointer yourself in this instance, ProDOS has no way of knowing where you really want the end of the file to be. Hence you'll end up with two Item 10's (the rewritten one and the old one) byte 0 Item 1 By resetting the EOF with FN Item 2 SetEOF, you can rewrite an Item 3 existing file and really make it Item 4 shorter. Item 6 Item 7 Item 8 : Item9 FN SetEOF(MyFile,90) Item 10 byte 89 X of not directly. Imust confess that, up until now, whenever I wanted to get the P8 file reference number, I did what everybody else did and wrote a special call to the MLI to OPEN the file and grab the refnum. Alas, how could I have been so blind? An OPEN call is an OPEN call is an OPEN call. When ZBasic opens a file, it is doing the exact same things we are when we code it ourselves. And since the ProDOS ZBasic author, Greg Branche, was so generous with infor- mation, we know exactly where ZBasic’s own MLI parameter table lives ($1F00). All we must do is a simple PEEK to the proper spot in the parameter table immediately following the standard ZBasic OPEN statement. Voile’ (say wa-lah’). We have arefnum. A function to do this doesn’t even require the LONG variety: REM REM REM This function only works if called immediately following a ZBasic OPEN command. DEF FN GetRef = PEEK (&1F05) 8/16 Angust, 1990 Page 15 The next step involved in messing with the EOF marker is to find out its current status. As I've discussed before, there are two approaches, one is all-ZBasic and one is more fun. The all-ZBasic method is to open the file with a record length of 1 byte and then ask how many records there are with an LOF(#) command. It would look like this: OPEN “O”, #1,File$,1: Len! = LOF(1) The only trick here is to remember that ProDOS supports file sizes larger than can represented in an integer variable. Amore entertaining approach is to go straight to the MLI. FN GetEOF in the demo below does just that. The only reason it is more entertaining is another little tidbyte: most folks don’t know it, but you can save a little time and a little variable space by putting the expression that creates your function's return value right in the END FN = statement. END FN will figure it all out jes’ fine, thank you. The real meat of the demo (if there is any) is to be found in FN SetEOF. This function takes the file ref num as a parameter, as well as the new desired length of the file. Caveat Emptor here, boys and girls (that’s Latin for “Hold on to your wallet.”) Like the potential boo-boos under MS-DOS, if you set the file length shorter than you mean to, your data will hiss away into the electronic nothingness. FN SetEOF divides NewLen! by 16%3 (4096) because ProDOS file sizes must be represented by three bytes. The highest-order byte is the number of groups 4096's (like the number of 10's in 100 or something). That’s why I indicated this with 1643 and not 4096. That makes a little sense, doesn't it? You divide by either representation of the number. It’s not a time critical operation. There is one last point of interest in the demo. The main program writes 100 four byte strings to disk (*0123"). I couldn't figure out for the life of me why the file length kept showing up as 500 bytes! The answer is that the PRINT# statement sends output to disk exactly like PRINT does to the screen. In short, there is a carriage return delimeter after each and every string. This fills out each group to five REM record length of 1 byte : REM how many records we got? bytes, and makes the entire file 500 bytes long. Hope this fills your needs Jim, and I hope the rest of you get some use out of it, too. Listing 2: FN SetEOF and brethren FN SetEOF, FN GetEOF, by Ross W. Lambert Copyright (Cc) 1990 Ariel Publishing, Inc. Most Rights Reserved I assume that the default var type is integer REM = 65 Path$:REM DIM max len plus len byte REM Ref is reference number of open file REM REM REM This function only works if called immediately following a ZBasic OPEN command DEF FN GetRef = PEEK(&1F05) LONG FN GetEOF! (Ref) POKE &1F00,2 : REM two parms POKE &1F01,Ref: REM ProDOS ref number REM do GET_EOF call MACHLG &A9, &D1, &20, &0865 REM put expression in END statement END FN=PEEK WORD (&1F02) +PEEK (&1F04) * 16.0*3 LONG FN SetEOF (Ref, NewLen!) POKE &1F00,2 : REM two parms POKE &1F01,Ref: REM ProDOS ref number Temp = NewLen!/(16*3) POKE &1F04,Temp:REM poke into parm tbl REM subtract to get remainder Temp = NewLen!-Temp REM poke word length remainder POKE WORD &1F02, Temp REM do SET_EOF call MACHLG &A9, &DO, &20, &0865 END FN = ERROR REM Create a dummy file at the current prefix KILL “DUMMY” IF ERROR <> 0 THEN ERROR = 0 OPEN ‘O”,1,”DUMMY” IF ERROR <> 0 THEN STOP Ref = FN GetRef : REM internal reference # get ProDos FOR X = 0 TO 99 PRINT #1,”0123" : REM implicit car- riage return here! NEXT PRINT “The current file length is: ‘“;FN GetEOF! (Ref);” bytes” CLOSE REM Go write some bytes in the middle OPEN “O”,1,”DUMMY”,1 : REM record len=1 IF ERROR <> 0 THEN STOP Ref = FN GetRef RECORD#1,20:REM PRINT#1, ”56789" FN SetEOF (Ref,25) :REM write bytes 20-24 set new length PRINT “The new length is: “;FN GetEOF! (Ref) CLOSE END Palette to 3 > ie EEE in| Applesoft" Never Looked So Good! The Call Box TPS™ (Toolbox Programming System) gives you the tools to look and sound your best. Make your own Applesoft BASIC desktop applications which look and sound like professional programs. Over 1000 toolbox calls have been added to Applesoft BASIC which gives you, the BASIC programmer instant access to the Apple IIgs toolbox in a simple and flexible way. You can use the Memory Manager, Miscellaneous Tools, Tool Locator, Quickdraw II, Desk Manager, Event Manager, Scheduler, Sound Manager, Desktop Bus, Text Tools, Window Manager, Menu Manager, Control Manager, Quickdraw II (aux.), Line Edit, Dialog Manager, Scrap Manager, Note Synthesizer, Note Sequencer, A.C.E., Standard File and much more. In addition to all the tool calls you have access to ProDOS 16 and GS/OS commands at the same time that you have access to ProDOS 8 commands. You can even load and run relocatable shell applications from within the Call Box BASIC environment. The Call Box TPS includes the BASIC interface, WYSIWYG Window, Dialog, Menu and Image editors, Disk and system utilities plus demos and tutorials. The Call Box TPS comes on 3 - 3.5"disks with a 140+ page hard cover ring binder manual. Requires 1 megabyte min. and GS/OS V5.0.2 min. Call Box is supported by a programmers association which provides its members with disks and documentation designed to educate as well as illuminate. The Call Box TPS ........ssssevesveees $99.00 (714) 964-4298 VISA/Mastercard accepted LRO Computer Sales 665 West Jackson Street, Woodstock, (800) 869-9152 Mon-Fri, 9-6 CST Memory GS-4 Memory Board 0k $49 1 Meg $99 2Meg $166 4 Meg $289 Chinook RAM 4000 0k $75 1 Meg $139 2Meg $199 4 Meg $319 GS-Sauce SIMM Board 0k $89 1 Meg $161 2 Meg $230 4 Meg $369 GS Ram + 1 Meg $212 2 Meg $279 3. Meg $344 4 Meg $411 5 Meg $475 6 Meg $535 Checkmate MemorySaver $119 All memory is new and has a 5 year warranty. Apple 1 Meg 80ns exp. set $67 SIMM expansion set $69 Apple 256k 120ns exp. set $18 Apple 256k X 4 exp. set $19 Accesories for GS Transwarp GS 7 Mhz $279 Sonic Blaster $96 VisionaryGS Digitizer $279 RamFast 256k DMA SCSI $197 Sound System II speakers $99 System Saver GS $69 Conserver GS $89 A+ Optical Mouse ADB $87 Cordless Mouse ADB $109 GS Hardware * Apple IIGS ROM 01 CPU $649 Apple IIGS 1 Meg CPU, keyboard and mouse $819 Apple Color RGB Monitor $447 Apple IW II w/32k buffer $449 Magnavox RGB Monitor $319 Fortris ImageWriter compatible printer $229 HP DeskjJet+ 300 DPI!$599 3.5" Drive upgradable from 800k tol.44Meg $219 AMR 3.5" Drive $183 AMR 5.25" Drive $149 Software Utilities Copy Il Plus v. 9.0 $25 Print Shop GS $27 ProSel 8/16 $66 Programmers's Online Companion $37.50 (815) 338-8685 Vitesse Salvation Series: Guardian— HD Backup $29 Renaissance— Optimizer $29 Exorciser— Virus Detector $26 Graphic Disk Labeler v.2.0 Print Color Disk Labels on IW II in 320 and 640 modes! $24.50 Business AppleWorks GS $212 Manzanita Businessworks $294 Education Designasaurus GS $33 Geometry GS $56 Talking Once Upon a Time $34 StudyMate- Grade Booster $33 GS Numerics A complete math program for high school, college students and professionals $104 Zip GS 8 Mhz $269 Entertainment FutureShock v.2.0 $54 Heatwave Offshore Racing$37 Test Drive II: The Duel $34 Grand Prix Circuit $36 Blue Angels Flight Sim. $37 Third Courier $37 Jam Session $32.25 Task Force $29 California Games $14.50 Qix $25 Rastan $25 Arkanoid I or II $25 Chessmaster 2100 $37 Tunnels of Armageddon $32 IL 60098 Sat 12-5 CST GS Starter System ® Apple IIGS 1 Meg CPU, keyboard and mouse e Magnavox RGB Monitor ¢ Fortris ImageWriter compatible printer AMR 3.5" Drive Mouse pad ¢ Box of 10 Maxell 3.5" Disks $1599 GS Power System Apple IIgs 1 Meg CPU, keyboard and mouse ¢ Apple Color RGB Monitor Apple ImageWriter II with 32k buffer Apple High Speed DMA SCSI AMR 40 Meg GS Partener HD Chinook RAM 4000 w/ 2 Meg AMR 3.5" Drive Mouse pad Box of 10 Maxell 3.5" Disks $2959 Modems USR 14.4 kbs Courier HST $589 Cardinal 2400 baud $109 Supra 2400 baud $109 Prometheus Promodem internal 2400G $144 Hard Drives Chinook CT100 16k cache $780 UniStore 80 Meg HS HD $529 UniStore 60 Meg HS HD $474 AMR GS Partner (0 Footprint) 40 Meg $420 60 Meg $640 80 Meg $700 100 Meg $876 AMR 45 Removable HD $769 CMS 60 Meg HD $539 Apple DMA SCSI w/ purchase of HD: $96 Without: $101 All HDs come formatted w/ GSOS or Mac system software, and 5-10 megs of PD, Share/Freeware.NDAs, CDAs, and INITs. InnerExpress $85 Prices subject to change without notice. Returns within 15 days with no restocking fee. IL residents add 65%. FAX orders and receive 2nd day air upgrade! (815) 338-8597 8/16 August, 1990 Page (= © Programming the Extended Keyboard Getting Over Extended By Dr. Doni G. Grande Many of us lead a dark, dual existence. By day, we are tied to some three-letter computer at work, slaving away at a keyboard with multiple function keys, and by night we are released and able to soar with our fantastic IIgs’s, with their less-endowed keyboards. But the curse of this lifestyle is that we are forever having to relearn the keyboard layout when we switch between machines. This is where an extended keyboard comes to the rescue. The key layout on the Apple extended key- board is very similar to the “enhanced keyboard” many of us use on those other computers. There are fifteen function keys (called F-keys and labeled F1- F15) across the top of the keyboard. The cursor movement keys (in an inverted-T configuration) and an editing keypad (with keys labeled help, home, page up, delete, end, and page down) are located between the main alphanumeric keys and the numeric keypad. There are even three lights (num lock, caps lock, and scroll lock) located above the keypad. Where'd it go, George, where did it go? How do you know when those extra keys are pressed? Well, the extra keys act like they are ona big extended keypad. Table 1 lists the key equivalents for these keys. In case you are wondering where the “keypad bit” is located, its kept in the key modifier register located at $£0/C025 (or PEEK(49189) from Applesoft) as shown in Table 2. Listing 1 is a short Applesoft program that GETs a keyboard character and the key modifier register and prints which keys were hit. The key modifier register (read into KEYMOD) is parsed by checking for the higher bits first. If set, the appropriate modi- fier is added to the description string and the bit is subtracted from KEYMOD. This is continued until no bits are left set in KEYMOD, and then the string is printed out. Note that control characters are printed with a caret preceding the letter; thus, control-E prints as “E. It is interesting to notice that some keys return control characters (RETURN, ESC, TAB, and the arrow keys) without setting the CTRL bit since control is not actually held down to gener- ate these characters (but the keyboard WILL cor- rectly report CTRL 4M if you hold down CONTROL and hit RETURN, as well as KP 4M if you press ENTER on the keypad!). Unfortunately, most Apple IIgs programs don’t check for the keypad bit, so they just appear to return the characters in Table 1 (F1 gives you a “z”, F2 an “x”, etc.). This isn’t very useful. Perhaps as more people get the extended keyboard, more pro- grams will be adapted to them. ",..a Permanent Initialization File (PIF) can be written that will be installed when the Igs boots and will set the keyboard lights when any desired modifier keys are down.” UltraExtended Some programs can be made to recognize the func- tion keys, however. For example, Beagle Bros’ Time- Out UltraMacros 3.0 will accept extended keyboard keys to trigger macros, so you can setup the function 8/16 August, 1990 Page 19 keys in AppleWorks. The only problem with this approach is that each key is mapped into its equiva- lent solid-Apple (SA) key sequence, and most of the predefined UltraMacros already use the Fkey equivalents. For example, HOME maps into SA-s, which is already used for the “Save File and Remove” macro. After discussing this on the Beagle Bros Support BBS, Mark Munz sent me a patch that would let the F-keys map into the Both-Apple (BA) macros, which are much less used. This patch and the standard set of macros I use are in listing 2. (Editor: Please note that our beta tester had trouble with the UltraMacros part of this presentation. I elected to print them anyway due to the very broad interest in the subject. Caveat Emptor.) Turnin' on the lights Finally, there’s the three lights on the keyboard: NUMLOCK, CAPS LOCK, and SCROLL LOCK? It seems that Apple thought about how to handle them, albeit in hindsight. The ROM 3 machines will follow the status of the CAPS LOCK key with the CAPS LOCK light, but the earlier ROM O and ROM 1 machines don't. Let’s remedy that! Figuring out exactly what to do takes a little bit of digging. The Apple IIGS Toolbox Reference Volume One documents the Apple Desktop Bus toolset. There is a SendInfo routine documented to send data to ADB devices, on pages 3-19 through 3-22. How- ever, how this relates to the extended keyboard is not documented. By disassembling a program by Tracy Valleau that set the CAPS LOCK light and a little playing around with some values, the following parameter list was discovered: ADB Sendinfo parameters to set keyboard lights: 2 byte count for ADB call 4 byte pointer to ADB data 2 byte $00A2 - send two bytes to ADB device 2, register 1 The ADB data should be of the form (in binary): 1111 1xyz 1111 1111 where x = 1 for numlock off,0 for on y = 1 for capslock off,0 for on z = 1 for scroll lock off,0 for on Knowing this, a Permanent Initialization File (PIF) can be written that will be installed when the IIgs boots and will set the keyboard lights when any desired modifier keys are down. The PIF source is shown in listing 3, with the “make” file in listing 4. Table 1 Extended Keyboard Function Key Equivalents All values are returned with the keypad bit set. FI[F2|F3|F4]| FS] FO|F7 | F8[F9 FIO] FIl] FI2]) Fis} Fl4 Z| x |ctlyv albjdje m g to) i kK q 8/16 Amgust, 1990 Page 20 Table 2 Modifier Key Register at $E0C025 bit number 7/6/5/4/3);2]11)0 shift key control key caps lock key repeat function S keypad key updated modifier key latch option key (solid apple) open apple key This PIF is the one originally written by Tracy Valleau Listing 1 modified to allow any of the keyboard lights to follow Applesoft Modifier Key Register Display any of the modifier keys. As the code now stands, it merely follows the status of the CAPS LOCK key with 5 REM Program to show use of Modifier the CAPS LOCK light. To change which modifierkeys Key register ($C025) control which lights, change the constants at the end 10 GET A$:A = ASC (AS): IF A < 32 THEN of the program to reflect your desires. Forexample, ag = “*” + CHRS (A + 64): REM Convert changing the constants to: control chars 20 KEYMOD = PEEK (49189): REM = $C025 numlight dc i2’appletoption’ 30 KM$ = “”: IF KEYMOD > 127 THEN KEYMOD caplight dc i2’capslock’ = KEYMOD - 128:KM$ = “OA “ scrlight dc i2’ctrldwnt+keypad’ 40 IF KEYMOD 63 THEN KEYMOD = KEYMOD > allmods dec il’appletoptiontcapslock+ - 64:KM$ = KM$ + “CA “ ctrldwnt+keypad' 50 IF KEYMOD > 31 THEN KEYMOD = KEYMOD - 32:KM$ = KM$ + “KEYMOD * ...would make the NUM LOCK light follow the status 60 IF KEYMOD > 15 THEN KEYMOD = KEYMOD of either Apple key, the CAPS LOCK light follow the - 16:KM$ = KMS + “KP » CAPS LOCK key, and the SCROLL LOCK light follow 70 %XIF KEYMOD > 7 THEN KEYMOD = KEYMOD - the CONTROL and KEYPAD keys. The allmodscon- 8:KM$ = KMS + “RPT * stant must contain all the modifiers you are inter- 80 IF KEYMOD > 3 THEN KEYMOD = KEYMOD - ested in; it makes the code quicker in deciding if 4:xms = KMS + “CAPSLOCK * anything needs to be done when a modifier key is 90 IF KEYMOD > 1 THEN KEYMOD = KEYMOD - down. (A desktop program that allows you tocustom- 2:KM$ = KM$ + “CTRL ~ ize the PIF is available on the 8/ 16 monthly disk. -ed) 100 IF KEYMOD > 0 THEN KMS = KMS + 8/16 Amgust, 1990 Page 2il “SHIFT “ 110 PRINT “Key hit: “;KM$;AS$ 120 GoTo 10 Listing 2 Ultramacros Macro to Enable Extended Keyboard Fkeys (A reminder: some folks have no problem with these, others find that it locks up their computer or crashes it. This may be due to inteference with other INITs or the effects of cosmic rays. - editor) Here is a fix for the extended keyboard. All the function keys are turned into ba- macros instead of sa- macros. Thanks to Mark Munz for these! Note: these patches use memory from $30E-318. Anything that writes over this area will crash Apple- Works! The STARTUP macro appears to trash this memory, so you can’t have this patch automatically installed when AppleWorks boots. <ba-ctrl-e>:<all:A=782:poke A+0,32 atl,3 : poke a+2,181 : poke at3,208 poke a+4,3 : poke at5,76 : poke at6,13 : poke a+7,182 : poke at+8,76 : poke at9,20 : poke a+10,182 : pokeword 4503,$30E: msg ‘BA extended keys’>! poke <ba-ctrl-n>:<all:pokeword 4503,$B60D: msg ‘SA extended keys’>! <ba-S>:<awp:oa-,>! ginning of line. <ba-w>:<awp:oa-.>! Home key goes to be- End goes to the end of line. <ba-t>:<awp:oa-up>! Page up goes up one page <ba-y>:<awp:oa-down>! Page down goes down one page <ba-r>:<all:oa-?>! Help shows help screen <ba-u>:<all:oa-del>! Deletes character under the cursor <ba-z>:<all:sa-u>! Fl - UNDO - Undo last delete - paste from clipboard <ba-x>:<all: oa-m>T! F2 - CUT - Move data to clipboard <ba-c>:<all: oa-c>T! F3 - COPY - Copy data to clipboard <ba-v>:<all: sa-u>! from clipboard F4 - PASTE - copy Listing 3 LIGHTS PIF to Enable Extended Keyboard Lights LIGHTS V1.0 - 26 Jun 1990 By Doni G. Grande ; A PIF that enables the lights on an + extended keyboard. One or more of the ; modifier keys may be linked to any of the three lights (numlock, capslock, or scroll 7 lock). Use the CONFIG.LIGHTS program to ; configure which keys control the lights. ; Based on the MYLIGHTS program by Tracy ; Valleau. This driver was created from 7 a disassembly of MYLIGHTS (made with 7ORCA/Disassembler) which was modified to ; add support for lights and keys other 7 than capslock. 1990 Ariel Publishing and Some rights reserved. + Copyright (c) ; Doni G. Grande. 7 Get our macros mcopy lights.mac ; Predefined labels: OS_KIND gequ $E100BC PRODOS8 gequ $BF00 PREFLAG gequ $BF9A INCBUSYFLG gequ $E10064 DECBUSYFLG gequ $E10068 KEYMODREG gequ $C025 MTSptr gequ $00 Define bits for modifier key register 8/16 August, 1990 Page 22 shiftdwn gequ $01 Shift key down ctrldwn gequ $02 Control key down capslock gequ $04 Caps Lock key down anydown gequ $08 Some key is down keypad gequ $10 Keypad key down option gequ $40 Option key down apple gequ $80 Apple key down lights start Start w/some housekeeping Get direct page and start some tools 7; we need phk plb rep #930 longa on longi on _TLStartUp pha _MMStartUp _MTStartUp Start Tool locator Start memory manager Start misc toolset We need a ptr in zero page, the original contents. so preserve lda MTSptr+2 save zero page pha locations lda MTSptr pha Have to patch the Misc Toolset’s reset rtn to reinstall our heartbeat task. pea $0000 Reserve space pea $0000 for result pea $0000 Get system tool pea $0003 Want Misc Toolset _GetTSPtr Get ptr pla Move pointer to sta MTSptr zero page pla sta MTSptr+2 ;The reset routine is number $0014. Load ;the original value and place in our code 780 we can call when needed. Then patch ithe Misc Toolset reset routine to point 7to our routine. ldy #90014 loword of addr-1 lda [MTSptr],y of Misc Tool Reset. inc a Point to addr of MTS sta oMTSrst MTS reset routine lda #ResetFix dec a sta (MTSptr],y idy #$0016 sep #820 longa off lda (MTSptr],y sta oMTSrsthi lida #°ResetFix sta (MTSptr],y Get hibyte addr-1 of MTS reset routine Restore zero page to way we found it. rep #$20 longa on pla Restore zero page sta MTSptr location pla sta $02 7 Install our heartbeat routine jsl >Inst HB ; Shutdown the tools we started _MTShutDown _MMShutDown _TLShutDown rtl ; This is reset routine patch. The first ; instruction will be patched to point to 7; original Misc Toolset reset rtn. After 7; executing the original routine, kybd ; light heartbeat task is re-installed. ResetFix dc ne22* JSL opcode oMTSrst dc h’0000' Orig Misc Toolset oMTSrsthi de n’oo' Reset address InstHB pea pea HBtskptr _SetHeartBeat HBtskptr|-$10 Install our heartbeat task 8/16 August, 1990 Page 28 pea $0002 Enable VBL ints _IntSource (vblEnable) rtl ; This is actual heartbeat task routine. HBtskptr dc h’ 00000000" Heartbeat task header HBCount dc i2'SOOO0A’ Six inter- rupts/sec HBSig de h’ SAAS" Heartbeat signature php rep #$30 Switch to native mode longa on longi on phk plb ; Check to see if the current operating 7; system is busy. If so, shorten the wait ; time to five ticks & return; otherwise #7 go check the keyboard modifiers. lida >SE100FF and #S00FF bne WaitFive lida >OS_KIND indicates current and #$00FF running 0/S bne doit lida >PRODOS8 and #SO00FF cmp #$004C bne WaitTen lida >PREFLAG prefix flag bmi WaitFive doit jsl >INCBUSYFLG inc busy flag jsx ChkCAPS jsl >DECBUSYFLG dec busy flag WaitTen lda #$000A bra SetHBC WaitFive lda #$0005 SetHBC sta HBCount pip rtl ; This rtn does all the work of checking ; the kbd modifiers & setting the lights. ChkCAPS sep #$30 longa off longi off lda >KEYMODREG Get key mod reg and allmods Strip bits we want sta CAPstatus Save current rep #$30 status longa on longi on lda CAPstatus Compare caps now eor PrevCAPS with previous. bne NotEqual Go if changed rts Otherwise return NotEqual anop Update the lights stz ADBdata Zero ADB data byte lda CAPstatus Get light status sta PrevCAPS Save 4 next pass pha and numlight Check numlight on beq nonum Go if not sec Roll bit into the rol ADBdata ADB data byte nonum pla Get light status pha cle and caplight Check capslock on beq nocap Go if not sec Roll bit into the nocap rol ADBdata ADB data byte pla cle and scrlight Check scroll lock beq noscrl Go if off sec Roll bit into the noscrl rol ADBdata ADB data byte lda ADBdata #SPEFF Get ADB data val eor Invert all bits 7Here is the rtn that does all the work. It uses SendInfo ADB Toolset call to set ;the lights. This is documented in the ;Toolbox Reference Vol 1, but the parm used here is not mentioned.From what jwe've been able to figure out, the ;parameters are: ; 2 byte count for ADB call F 4 byte pointer to ADB data i 2 byte $00A2 - send two bytes to ADB i device 2 register 1 8/16 August, 1990 Page 24 7; The ADB data should be of the form ;Marker for data area. This is used by ; (in binary): ;configure program (on 8/16 monthly disk) ? ;to find the data area in the disk file. ? EDEL. eye TELL 1111 7 : where x = 1 for numlock off, 0 for on de ce’ data’ ; y = 1 for capslock off, 0 for on 7 ; z = 1 for scroll lock off, 0 for on ; The following determines which lights ; ; correspond to which keys. SendData anop Send data to kbd xba Swap hi/lo bytes numlight dc i2'$0000' sta ADBdata Save in buffer |caplight dc i2'’capslock’ pea $0002 Send ADB two bytes scrlight de i2'soooo' lda ADBdataptr+2 Ptr to data allmods dc il’ capslock' buffer 7; All mod keys we pha ; are interested in lda ADBdataptr end pha pea $00A2 Send to register at SendInfo rts Listing 4 Makefile for LIGHTS PIF ADBdata dc i2'$0000' Data for ADB kbd ADBdataptr dc a4’ADBdata’ Ptr to above |asml lights.asm keep=lights PrevCAPS dc i2'$0000'Previous CAPS stat |erase lights. root CAPstatus de i2'$0000' Present CAPS stat |filetype lights str o you've written a great piece of Apple II” software, but you're not sure how to turn all that tecsa cea ol hard work:into cash. You’re wary of shareware jhe ee nae and have been snubbed by other publishers. thot wil put « gleam in ‘our eyes (ond money in etus take a fook at your work! We are-the publisher i ec ee L of Softdisk"and Softdisk G-5,"a pair of monthly co : softwate collections sold by subscription, on 4318) 291-5194 newsstands and in-booksteres everywhere. We are looking for top-notch Apple software. We respond promptly, pay APPLICATIONS «well, aid are actually fun to work with! UTILITIES EDUCATION hat-have you got to lose? Nothing! You could see ENTERTAINMENT your software published and-earn cold, hard cash. GRAPHICS” Send your best software to: FONTS Jay Wilbur _ DESK ACCESSORIES, c/o, Softdisk Publishing, Inc. INITS, CDEVS, ETC. 606 Common St. Dept. ES, Shreveport, LA 71101 . GEnie: JJJ / America Online: Cycles — Ca BA ce e= -— J (=) p= _ = = Ell = New Concepts Software DREAM *, ~ GRAPRLX ree FT a DreamGraphix: A full feature paint program and more! *® 16, 256, and 3200 color and palette control with ability to copy, spread, and swap colors and palettes *® Draw filled or outlined circles, ovals, squares, rectangles, polygons, arcs, lines, and any other shapes © Mask color, spray paint, fill region (solid, pattern, and brush), freehand, zoom (with and without grid) e@ Use anything as a brush with ability to stretch, halve, double, rotate, flip, bend, shear and mirror Smear, shade, blend, and smooth commands ©¢ Use all available fonts ®Hard drive instalable Load and save pictures on all available and custom 3200 formats on the GS © Load and save palettes User expandable through extended commands eoe InnerExpress: Speeds up Falcons, Inner and OverDrives 200%—300% InnerDrive without InnerExpress InnerDrive with InnerExpress ID with InnerExpress and TWGS Interleave: 10:1 Interleave: 61 Interleave: 51 Block access/second: 81 Block access/second: 225 Block access/second: 284 FutureShock V 2.0: Entertainment system with FuturePad controller FutureShock is a revolutionary game with its own interface controller- FuturePad. To manipulate the objects in the game, you move your hand over the pad! These games (DeathSquash, Zertotron Racer, and Metal Heads) can kin or the game! $42 Inner Express $95 FutureShock $59 p by Is “i Limited Time Offers Through September 15th: Free 2nd day shipping with any order! Dealer Inquires Welcomed New Concepts Software: 1-800-487-8684 'DreamGraphix August, 1990 Generic StartUp 8 Carl Hilton asked me on GEnie why the Sourceror'’s Apprentice had once run a generic GS/OS startup and shutdown routine, but never an 8-bit version of the same song and dance. It sounded like a good idea tome. It’s not exactly crystal clear what one must do at the beginning of a ProDOS 8 SYS application. I took the front end I'd written for MicroDot and extended it to make it as generic as possible. The result was Listing 1. I designed the program so that it can be included easily in your assembly by using the Merlin PUT directive. Here’s how a SYS application might start: 1 * The world’s greatest program 2 * by Ima Bozo 3 4 erg $2000 ;SYS files ORG @ $2000 5 typ $FF ;SYS files type $FF 6 dsk GREATPROG gassemble to disk 7 8 put generic ;include generic startup rtn 9 1 0 * Program begins here... I tried to minimize the impact the Generic Startup Routine would have on your program's own labels. Many internal labels are local labels, rather than global labels. The only global labels in the routine (besides the equates, some of which you may find useful anyway) are: strtpath: the startup path passed to this application by the launcher the starting address of the generic startup routine progpath: the program’s complete pathname, or null if indeterminable main: the starting address of the program code you write start: I won't go into great detail describing the program’s inner workings. It’s well commented, and besides, by Jerry Kindall writing the program was mainly a matter of looking through various manuals and figuring out what most SYS programs need to do, then writing the code. I've pointed out (in the comments) places where the routine can be modified to better suit your needs. The routine isn’t particularly tricky, but I sure am glad I'll never have to worry about it again. I hope it saves you a headache or two, as well. Be on the lookout for a generic shutdown routine next month! Listing 1: The Generic 8-bit Startup Routine al 2 * Generic 8-bit Startup Routine 3 * by Jerry Kindall - 8/16 4 5 lst off 6 7 csw $36 joutput hook 8 ksw = $38 ;input hook 9 resvec = $3F2 jreset vector 10 settxt = SFB39 pset text 11 home = SFC58 ;elear screen 12 setnorm = $FE84 ;select norm vid 13 setkbd = SFE89 ;select IN#0 14 setvid = SFE93 ;select PR#0 15 coldst $E000 ;coldstart BASIC 16 17. fretop = $6F ;beginning of strs 18 memsiz = $73 yend of strings 19 20 GETINFO = $C4 ;ProDOS MLI codes 21 ONLINE $c 22 SETPFX $C6 23. GETPFX = $C7 24 CLOSE = $cc 25 26 0 mli SBFOO ;ProDOS entry pt 27 devnum = $BF30;last disk accessd 28 bitmap = $BF58;memory protection 29 level = $BF94 ;file access level 30 machid = SBF98 ;machine id byte 8/16 Amgust, 1990 Page 27 31 pfxflag= SBF9A;prefx active flag 82 32 83 :inittxt jsr setkbd INO 33 * Hardware & Firmware: 84 jsr setvid ;PR#O 34 85 jsr setnorm ;normal video 35 kbd = $c000 ;read keypress 86 jsx settxt ;text mode 36 strobe = $010 ;clear keypress 87 bit pagel ;display page 1 37 pagel $c054 ;select page 1 88 jsr home ;elear screen 38 ent80 $C300;80column entry pt 89 39 90 * Get BASIC going If you will not be using 40 fn 7 $280 ;filename 1 91 * Applesoft BASIC routines, such as FP math, 41 fn2 7 $2C0 ;filename 2 92 * you may leave out this section 42 93 43 jmp start; jmp over startup buffer | 94 lda #:reentry ;this is our 44 return ticket 45 * Startup buffer 95 sta ksw 46 * This code can be omitted if you 96 lda #/:reentry 47 * don't want the ability to pass a 97 sta kswtl 48 * string to your program. Otherwise 98 lda #:nullout ;eat all output 49 * it’s kind of nifty to have. chars 50 hex EEEE41 ;startup buffer ID 99 sta csw bytes 100 lda #/:nullout 51 101 sta cswt1 52 strtpath str ‘STARTUP’ ;omit this line |102 jmp coldst ;coldstart Applesoft for null 103 53 ; startup path 104 :reentry lda #$BF;protect ProDOS global pg 54 105 sta memsizt+l ;from BASIC strings 55 ds 65-*+strtpath ;filler 106 sta fretop+1 56 107 lda #0 57 * Close all open files and init stack 108 sta memsiz pointer 109 sta fretop 58 110 59 start lda #0 ;level set to 0 for all |111 * Set memory protection files 112 * Clears out ProDOS bitmap & reserves pages 60 sta level 113 * 0,1,4-7, $BF. Add other protection here if 61 jsx mii 114 * necessary. 62 dfb CLOSE 115 63 dw :pelose 116 lda #0 64 ldx #$FF ;stack pointer should | 117 ldx #$17 be set to 118 :memloop sta bitmap,x ;all mem accessible 65 txs ; top of stack page 119 dex 66 120 bne — :memloop 67*Check for and deactivate 80-columns 121 1da #%11001111 ;except 0,1, 4-7 68*I£ you want instead to activate 80columns if | 122 sta bitmap 69*available, use lda #$19 instead of lda #$15. | 123 lda #800000001 ;$BF 70*You could require 80 columns by branching to | 124 sta bitmapt$17 7Jl*error handling routine instead of :inittxt. |125 712 126 * Avoid null prefix 713 lda machid ;get machine id 127 * If null prefix found, set prefix to name of 74 and #802 ;eheck bit 1 128 * volume last accessed. 75 beq sinittxt gno 80-col card 129 installed 130 :prefix lda pfxflag 76 lida #$15 ;turn it off 131 bne :getpath j;not null 11 jsr ent80 7$C300 entry 132 lda devnum ;get current disk 18 133 sta :ponline+1 79*Set up display 134 jsx mili 80*This is executed on re-entry from Applesoft | 135 dfb ONLINE 81* (when Applesoft calls RDKEY to get keypress) | 136 dw :ponline 8/16 August, 1990 Page 28 137 lda fnl+1 138 and #$0F ;if length zero 139 tax 140 lda#'/" ;put beg slash 141 sta fnl+1 142 inx 143 stx fn ysave new length 144 jsx mili jand set prefix 145 dfb SETPFX 146 dw :psetpf£x 147 148*Get application pathname 149*I£ you do not need to know the name of your 150*app, or the directory it’s in (possibly 151*different from launch prefix), skip this. 152*When this routine has completed, the memory 153*area “progpath” will contain full pathname 154*of application program. If the information 155*was unavailable (or pathname was too long) 156*the str will be null. You may wish to strip 157*the last name in path in order to get the 158*application directory, then set prefix to 159*that directory. This allows your program 160*to find its files even if the prefix wasn’t 161*set to application’s directory. It also 162*assumes that the launching program followed 163*ProDOS convention of placing application 164*pathname at $280. 165 166 :getpath ldy #0 167 ldx #0 168 lida fnl+1l;check slash at strt 169 cmp #°/" 170 beq :fulpath ;full path speci- fied by launcher 171 jsx oo mli 172 dfb GETPFX 173 dw ipgetpf£x 174 ldx progpath 175 :fulpath lda fnl+l,y 176 sta progpatht1,x 177 iny 178 inx 179 cpx #64 ;pathname overflow? 180 beq :chkpath tyes 181 cepy nl ;no, done copying path? 182 bne :fulpath no, do more 183 184 :chkpath stx progpath 185 jsr mli ;get info on pathname 186 dfb GETINFO 187 dw rpgetinf 188 bee :reset 7no errors 189 ida #0;otherwise we've an error 190 sta progpath ; make null 191 192 * Set up reset vector 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 bb i 214 215 216 217 218 219 220 gel. 222 223 224 225 226 227 228 229 230 231 232. 233 224 235 236 237 238 239 240 241 242 243 244 * This code makes program restart if Reset * is pressed. Probably you need to change * where program goes when Reset is pressed. rreset lda #main sta resvec lda = #/main sta resvectl eor #$A5 ;set funny complement to sta resvect2;avoid rebooting on reset * Clear keyboard buffer * Clears all buffered keystrokes on IIgs relrkey bit kbd bit strobe bmi :clrkey * Begin program execution jmp = main * Fake RTS to eat output during BASIC startup rullout rts * MLI parmlists and data areas ipgetinf dfb $0A ;GET_INFO pathname dw progpath ;pathname ds 15 ;we don’t care about rest :pgetpfx dfb $01 ;GET_PREFIX pathname dw progpath j pathname :psetpfx dfb $01 ;SET_PREFIX pathname dw £n2 ;pathname :ponline dfb $02 ONLINE parmlist dfb $00 junit number dw fn2+1 ;data buffer :pclose dfb $01 ;CLOSE parmlist dfb $00 pref num (all files) progpath ds 65 japplication pathname ynull if unknown junneeded if you omit the code ; which initializes it main yyer program goes here lst off CENESVS Now available and shipping! Genesys™...the premier resource creation, editing, and source code generation tool for the Apple II GS. Genesys is the first Apple IGS CASE tool of its kind with an open- ended architecture, allowing for support of new resource types as Apple Computer releases them by simply copying additional Genesys Editors to a folder. Experienced programmers will appreciate the ability to create their own style of Genesys Editors, useful for private resource creation and maintenance. And Genesys generates fully commented source code for ANY language supporting System 5.0. Using the Genesys Source Code Generation Langugage (SCGL), the Genesys user can tailor the source code generated to their individual tastes, and also have the ability to generate source code for new languages, existing or not. Genesys allows creation and editing of resources using a WYSIWYG environment. Easily create and edit windows, dialogs, menu bars, menus menu items, strings of all types, all the new system 5.0 controls, icons, cursors, alerts, and much more without typing, compiling, or linking one single line of code. The items created with Genesys can be saved as aresource fork or turned into source code for just about any language. Genesys even allows you to edit an existing program that makes use of resources. Genesys is guaranteed to cut weeks, even months, off program develop- ment and maintenance. Since the interface is attached to the program, additions and modifications take an instant effect. Budding programmers will appreciate the ability to generate source code in a variety of different languages, gaining an insight into resources and programming in general. Non-programmers can use Genesys to tailor programs that make use of resources. Renaming menus and menu items, adding keyboard equivalents to menus and controls, changing the shape and color of windows and controls, and more. The possibilities are almost limitless! Genesys is an indispensable tool for the programmer and non- programmer alike! Retail Price: $150.00 SUCMIN SSSiis pleased to announce that we will be carrying the GS Sauce memory card by Harris Laboratories. This card offers several unique features to Apple //gs owners: Made in USA Limited Lifetime Warranty 100% DMA compatable 100% GS/OS 5.0 and ProDOS 8 & 16 compatable Installs in less than 15 seconds! Low-power CMOS chips Uses “snap-in” SIMMs modules - the same ones used on the Macintosh Recycle your Macintosh SIMMs modules with GS Sauce. Expandable from 256K to 4 Meg of extra DRAM This card is 100% compatable with all GS software and GS operating systems. It is 100% tested before shipping and has a lifetime warranty. The CMOS technol- ogy means that it consumes less power and produces less heat thus making it easier on your //gs power supply. There are no jumpers, just simple to use switches to set the memory configuration. One step installation takes less than 15 seconds. Sc Memory configurations: Apple //gs model add these: total GS RAM 256K (ROM 1) (1) 256K SIMM 512K (2) 256K SIMMs 768K (4) 256K SIMMs 1.25 Meg (1) 1 Meg SIMM 1.25 Meg (2)1MegSIMMs 2.25 Meg. (4)1MegSIMMs 4.25 Meg 1 Meg (ROM 3) (1) 256K SIMM 1.25 Meg (2) 256K SIMMs 1.50 Meg (4) 256K SIMMs 1.78 Meg (1) 1 Meg SIMM. 2.0 Meg (2)1MegSIMMs —-3.0 Meg (4)1MegSIMMs 5.0 Meg Please note that you can not mix 256K and 1 Meg SIMMs packages on the same GS Sauce card, and thatexpansion mustbe performed in (1), (2) or (4) SIMMs modules. a 7 i ERC, Pricing: We are offering a limited time “get acquainted” offer to our customers. The GS Sauce card is available from SSSi as: OK $89.95 - use your own 256K or 1 Meg SIMMs modules 1Meg $179.95 2Meg $269.85 4Meg $449.75 "F We are making a special offer to our Genesys users: Buy Genesys and and get a coupon to purchase GS Sauce for: 0K $79.95 - use your own 256K or 1 Meg SIMMs modules 1Meg $159.90 2Meg $239.85 4Meg $399.75 We hope you will see what an excellant value the GS Sauce card is: low power consumption, SIMMs technology, inexpensive, made in USA and lifetime war- ranty! Call or write for seperate 256K and 1 Meg SIMMs modules to upgrade your GS Order by phone or by mail. Check, money order, MasterCard, Visa and American Express accepted. Please add $5.00 for SIH Simple Software Systems International, Inc. 4612 North Landing Dr. (404) 928-4388 Marietta, GA 30066 Fi 8/16 Amgust, 1990 Page 80 VaporWare by Murphy Sewall Reprinted from the APPLE PULP (E. Hartford, CT) Laser, Scanner, FAX, Modem. National Semiconductor has introduced the NS32GX320 Imaging/Signal processor which can allow a single peripheral to print, scan, send and receive FAXes and function as a modem. Printer-FAX-copiers that include the new chip are expected as early as next fall’s Comdex. Ed Pullen, an analyst at San Jose market research firm InfoCorp, predicts an 8 page per minute unit will cost about $2,400. - PC Week 28 May “What If?” Graphics. Bell Atlantic plans an August release of a Windows 3.0 program called Thinx which allows users to draw or import images, attach numeric values or other attributes to them, and then do “what if” analysis by manipulating the images. Bell Atlantic product manager, Jack Coppley, says Thinx blends drawing tools with database and spread- sheet capabilities. The proposed retail price is $495. - PC Week 11 June Macintosh llgs? Maybe John Sculley’s reference to a Macintosh llgs, at AppleVision ’90 back in April, wasn’t a “Freudian slip.” Word from Germany is that Apple dealers are telling their salesmen not to turn away customers asking about the Apple Il. Instead the salesman are told to promote the Mac II line which “can be upgraded to the Macintosh ligs early next year!” - found in my electronic mailbox Low End Macs. John Sculley is quoted as telling a developers conference recently “We clearly underestimated the market impor- tance for new low-end and laptop Macs. We will catch up by offering both low-end and laptop Macs over the next 12 to 15 months.” The long awaited, modular color K-12 Macintosh may be offered as early as October, but the “no compromises” (does that really mean IIgs?) Apple Il emulation card may not be ready until next spring (sources say it has existed in one form or another for more than two years, but production cost remains a problem). - InfoWorld 4 June, A2-Central June, and my electronic mailbox Color PostScript. Seiko plans to ship a PostScript compatible color thermal printer in August for $7,000. The printer will work on a network and will offer Centronics, RS-232, and Appletalk ports. - InfoWorld 28 May Apple Demos System 7. Apple engineer Chris Espinosa demonstrated the alpha version of System 7 for the Macintosh at MacAdemia in Rochester, New York at the end of May. The new operating system will, without question require 2 Mbytes of RAM and a hard disk for every machine running it. Apple engineers emphatically deny any plans to make a “cut-down” version for smaller machine (Does that say something about the memory of the K-12 Mac?). Espinosa was quite clear, it will run the Finder and at least one application on a Mac with only 2 Mbytes of RAM. He also is anticipating that Apple may bundle SIMMS with “a good price” (but for less than already is available by mail order). Apple will 8/16 August, 1990 Page 81 make System 7 the operating system bundled with every machine and will run on every machine within a year or so after introduction. - found in my electronic mailbox Micro Channel Extensions. Sixty-four bit and even 128 bit extensions of IBM's Micro Channel Architecture are under development. When these buses become available, desktop systems will approach the I/O channel capacity of mainframes. - InfoWorld 11 June PM Lite Lives. Cyco International and GeoWorks continue to work toward Presentation Manager interfaces for DOS even though IBM abandoned the idea last fall. Cyco will begin shipping Autobase, a graphical database system that includes a PM interface in August. GeoDOS from GeoWorks, a multitasking graphic environment that runs in as little as 512K, is scheduled for this Fall (yes, that is the same company that offered a graphic user interface for the Commodore 64 back in antediluvian times - nearly five years ago). - PC Week 11 June PM Programming Difficulties. Programming in the Presentation Manager environment is said to be so difficult that IBM is hastily porting Motif to OS/2 to keep the Defense Department happy. Motif will permit X Window applications to run under OS/2. - PC Week 11 June Laptop Printer. Computer Product Plus has a 3.6 pound (including the batteries), 11.5 by 6.75 by 1.125 inch 24 pin thermal printer which prints full width (8.5 inch) paper. The WSP-200 printer is scheduled to ship in August for $349.95. Output quality is said to be comparable with many 24-pin impact printers. Future plans call for the addition of FAX and scanning capabilities. - InfoWorld 21 May Flash (continued). There’s some dispute about how many Macintosh programmers remain working at Beagle Brothers (see last month’s column). The original author of Flash has departed, but someone fixed a few bugs and made enough improvements to create version 1.1 (a free upgrade to registered Flash owners). Does building HyperCard stacks count as Mac programming, or must one Think C (4.0)? We'll find out if a substantially enhanced version 2.0 makes it to market “later this year,” and if Flash continues to be a “quick, easy, fun, and inexpensive” utility even after System 7.0 is released. - found in my electronic mailbox Automatic, Continuous Backup Golden Triangle will offer an accelerated SCSI card and Macintosh software that simultaneously writes files to two hard drives as early as this month. The product named DiskTwin is expected to have a “street price” on the order of $500. Robert R. Tillman, a consultant to Golden Triangle, points out that, due to the falling price of hard drives, a user may be able to acquire Disk Twin and two 100 Mbyte drives for about $2,000. - InfoWorld 4 June Another Bert Sighting Bert Kersey was recently spotted filling up his Porsche at a Speedway station in Detroit not too long ago. Rumor has it that he’s taken flight due to the large amount of public attention focused on him recently. He can be reached only by cellular phone, and only when he’s in his phone’s limited calling area, so he’s out of touch with civilization most of the time. - found in Ross's electronic mailbox 8/16 August, 1990 Page 32 The Return of PunkWare Get Control of Yourself, Young Man! By Jay Jennings I have some good news and I have some bad news. The good news is that System Disk 5.0 brought with it some fantastic capabilities, including a tool call that installs lots of hip controls in a window with just one line of code! The bad news is that you have to be a contortionist to get the information from those controls during your program. Way back when I was boy... In the good old days, if you used a LineEdit control in a dialog box, your program could return the text input by using two toolcalls. Ifyou used a check box, you could get or set the value with only one toolcall. Well, who ever said programming was supposed to be easy all the time? Yeah, we've had it easy up until now, but if you want to use the capabilities of ~NewControl2, get used to the fact that it’s a chore to get and set control info now. It’s not an impossible task, but it’s a pain in the gluteus maximus to try and figure out...which is why I'm writing this: so that your derriere doesn’t have to go through the same things that mine did. This article will introduce the concepts of using the new controls and I'll even include a few subroutines to get you started on the road to Control Mastery. The source code included in this article is based on some that was written a while back with the help of Eric Mueller, the IIgs editor of 8/16. Eric flew to Kansas City just to help me figure out the difference between a LineEdit Control Record and a LineEdit Edit Record. (Well, that wasn’t the only reason, but this code was one of the many things that came out of our marathon hacking sessions.) Just as a way of introduction, look at listing one. It shows how easy it is to create a bunch of controls using the ~NewControl2 call. You basically pass it the address ofa table that is composed of the address of your control templates. It’s no big deal. In fact, it makes creating controls a breeze. Power Programming for Punks Take a look at listing two for the macros that we'll use for the following routines. I like to put macros like these together as it gives me a sense of working ina high level language, and makes the source code more readable. Notice that the macros I'm using here just parse the parameters and call different subroutines...that way, we can have fairly generic subroutines in our code, yet pull several of them together with a macro for one specific task. If there’s one thing I've learned in the past few months, it’s to make your code as generic as possible. There are those people who will tell you that by making code generic it won't run as fast. They're right. But most of the programs I write aren’t so speed sensitive that a couple milliseconds are going to make any discernible difference. If you're writing an arcade game, hardcode some stuff. However, if you're writing “normal” applications, you'll find that by making generic routines your coding output will increase in the future. Cut and paste programming willmake you a master programmer. And that’s what these routines represent: the Lazy Man's Way to Pro- gramming. The first thing we'll tackle was the most complicated for Eric and I to figure out: getting text from an edit line that was created with ~NewControl2. In the following examples, I'm assuming you used ~New- Control2 to create several controls. You can use it to 8/16 August, 1990 Page 88 create just one control at a time, but since most windows have multiple controls, that’s what my rou- tines were written for. If you are just creating one control, you'll already have the handle to that ex- tended control record since ~NewControl2 will pass it back to you. When creating more than one control at a time, however, ~NewControl2 doesn’t pass back anything useful. The code in listing two is the subroutine that collects the text from a specified LineEdit control. All the needed parameters are passed via the stack. We need to know three things in order to get the informa- tion from the LineEdit control: first, the pointer tothe window that the control lives in. (If you want to use the frontmost window, stick a zero in that slot.) Next, we need to know the ID number of the control. Finally, we need the address of a buffer we can stick the text from the control inyo. Make sure you've reserved enough space so that a long piece of text doesn’t overwrite whatever happens to fall after the buffer in your source code. A Closer Look Okay, let’s take a detailed look at what’s happening in the GetELine subroutine. The first thing we do is to pull the parameters off the stack and store them in some temporary locations. Note that you must pull the return address off the stack first and then return it else bad things will happen. (Just use the X register to hold the return address temporarily.) Next we use ~GetCtlHandleFromID to get the handle to the extended control record. This record was created for the control when the ~NewControl2 tool call was used. You can get the extended control record layouts and descriptions from the Apple IIgs Toolbox Reference, Volume 3, starting on page 28-87. You're allowed to read these records to get informa- tion, but setting the values directly is a no-no. Once we have the handle to the extended control record, we stick it in a direct page location in preparation for dereferencing. After that I-can-now- do-it-with-my-eyes-closed procedure (editor: speak for yoursefl, man), we have a pointer to the LineEdit extended control record. Offset $1C into the ex- tended control record gives us the handle to the LineEdit edit record, and that’s what we're looking for. We don’t have to dereference that because eve- tything else we need to do can be done with the handle. We're getting warmer... The handle we have points to a record that looks quite a lot like that pictured on page 10-5 ofthe Apple IIgs Toolbox Reference, Volume 1. Ah! We're getting closer to actually finding out what text was entered into the LineEdit control. We can now use our old friends ~LEGetTextLen to get the length of the entered text, and ~LEGetTextHand to get a handle to the text that was entered. Notice that after we get the length of the entered text, we store it in the first word of the buffer space that we've allocated for the LineEdit text. This is so that when all is said and done, we have a pascal string waiting for us to use. Then we add 1 to the address of the text buffer so that we don't overwrite our length byte with the text from the control. Finally, once we have the handle to the text, we can use ~HandToPtr to move the text from the LineEdit control to our storage buffer. Ta-da! Several contor- tions, but once you have a generic routine, you can forget all about how hard it was the first time. Doing a one eighty The routine SetELine in listing four allows you to place text into a LineEdit control. It’s very similar to the previous routine. It needs one more parameter passed on the stack, and after we get the handle to the LineEdit edit record, we only need to do one call, ~LESetText, to complete the routine. Listing five shows two routines that can be used to activate or deactivate extended controls in a window. They're fairly simple and only require the window number and the control ID to use. The ~GetCtIHan- dleFromID call is used as before to get a handle to the specified control. Then ~HiliteControl is used to turn the control on or off. You could combine the two routines into one by pushing one more parameter onto the stack: a zero to activate the control, or 255 to deactivate it. This value would then be used as a parameter for the ~HiliteControl call. For subrou- tines as small as these, I tend to go with simplifica- tion rather than saving a few bytes of code. On larger 8/16 August, 1990 Page 84 projects, you might need the extra room, however. Listing six contains two routines that you can use to check and uncheck check boxes (say that three times fast!). The routine GetCBValue returns a boolean value on the stack. You could also just load the accumulator with the value and return. At the front of the routine, right before we shove the return address back on the stack, we push a space word. Now look at the end of the routine. We place the boolean value we're returning in that space that’s right above the return address. A bonus from Uncle Jay And finally, just to sweeten the pot, there are a couple routines in listing seven that come in handy when you're using GS/OS and Pascal strings in the same program. They’re well commented and quite simple, so I won’t go into them in detail. Bugsville There’s a documented bug in ~NewControl2 that you should be aware of (documented in Apple IIgs Tech Note #82). When you use that call, the GrafPort is supposed to be set to the current window but doesn’t do that as of System Disk 5.0.2. The way around this is to do a ~SetPort call to the correct window before calling ~NewControl2. That should make everything okey-dokey. This should be enough information to get you started on the road to control mastery. If this is all the information you've read about extended controls, however, you're doomed to a life of mediocrity. To become a true Apple IIgs programmer requires hard work, self denial, and the purchase of the Apple IIgs Toolbox Reference, Volume Three. Listing One : NewControl2 Call ~NewWindow #WindowTemplate PullLong WindowPtr ~FrontWindow ;see what window is in front _SetPort gand set the GrafPort to it ~NewControl2 WindowPtr; #3; #ClientCList pla pla ;just junk the return value ClientCList adrl ButtonTemplate adrl CheckBoxTemplate adrl LineEditTemplate adrl 0 Listing Two: Get Edit Line Text Subroutine GetEditLineText mac PushLong ]1 PushLong ]2 PushLong ]3 jsr GetELine eom ;window pointer 7control ID ;buffer address SetEditLineText mac PushLong ]1 PushLong ]2 PushLong ]3 ;which window to use yedit line control ID jaddress of text to set lda 14 length of text to set and #S00FF pha jsx SetELine eom GetText mac ;window ptr, control ID, & storage buffer GetEditLine 11712733 PascalToGS 13 CopyGSString #GSString;]3;GSString eom PascalToGS mac PushLong ]1 ;address of the Pascal string jsr Pascal2GS eom GSToPascal mac PushLong ]1 jaddress of the GS/OS string jsr GS2Pascal eom CopyGSString mac PushLong ]1 PushLong ]2 jaddress of the source jaddress of the destination pea 0 ;zero high word for # of bytes to move lda 13 ;number of bytes to move ine inc ;add two so we move the length word, too 8/16 August, 1990 Page 85 pha _BlockMove eom GetCheckBoxValue mac PushLong ]1 ;window ptr (or zero) PushLong ]2 ;eontrol ID number| jsr GetCBValue eom SetCheckBoxValue mac PushLong ]1 ;window ptr (or zero) PushLong ]2 ;control ID number| PushWord ]3 ;l=turn on, O=turn off jsr SetCBValue eom Listing Three : Get Edit Line Text Subroutine * * GetELine ent * * this plucks a piece of text from a specified edit line and stores * it as a Pascal string in a specified location * * enter: x || | * |= WindowPtr -| ptr to wind 0=top window | | * | ——---------—] a | | * |- IDNumber -| ID number of control = | i * |———_--------- —| | i] * |- textAddr -| buff addr for editin txt ia | | Bo nee eee. * <- stack pointer * plx igrab & save the return addr PullLong :TextAddr ;ptr to text buffer PullLong :IDNumber ;econtrol ID number PullLong :Window;window we're working with phx ;replace the return addr ~GetCtlHandleFromID :Window; :IDNumber PullLong dpTemp ;store in direct pg space Deref dpTemp;dpTemp2;get ptr from the hndl ldy #$1c;get handle to LE: pg28-100 in TRE lda [dpTemp2],y sta :Handle iny iny lda [dpTemp2],y sta :Handle+2 ~LEGetTextLen :Handle get length of text mov_l :TextAddr;dpTemp ;move text buff addr ldy #0 pla ynow grab length from last toolcall sta [dpTemp],y ;store length in text buffer sta :TextLength j;and save for use in a sec add4 :TextAddr;#1;:TextAddr;pt past len byte ~LEGetTextHand :Handle PullLong :Handle ;grab the text handle ~HandToPtr :Handle;:TextAddr; :TextLength zcopy info to text buffer rts :TextLength ds 4 plength of the text :TextAddr ds 4 saddress of the text :Handle ds 4 ;handle to LineEdit Record :Window ds 4 ;window we're working with : IDNumber ds 4 ;eontrol ID number Listing Four: Set Edit Line Text Subroutine * * SetELine ent * * this places a specified piece of text ina specified edit line * enter: im | i * |= WindowPtr -| ptr to wnd 0=top window * | I i a | * i] | * |- IDNumber -| ID number of control * || | * i * | * -| addr of text for edit line * I * I * | length of text to set * <- stack pointer 8/16 Amgust, 1990 Pag

Showing the first 100000 of 121075 characters.

mp.ls