Source: Brutal Deluxe Software
— Apple II/Mac user group newsletter, via applearchives.com.
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.