Not for resale
The Hitchhiker's
Guide to GEOS
A Potpourri of Technical Programming Notes
(provided "as is" without support)
April 1988
Copyright ©1988,. 1989 Berkeley Softworks.
This is a copyrighted work and is not in the public domain. However, you may use, copy, and
distribute this document without fee, provided you do the following:
• You display this page prominently in all copies of this work.
• You provide copies of this work free of charges or charge only a distribution fee for the
physical act of transferring a copy.
Please distribute copies of this work as widely as possible.
Note: Berkeley Softworks makes no representations about the suitability of this work for any
purpose. It is provided "as is" without warranty or support of any kind.
BERKELEY SOFTWORKS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
WORK, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL BERKELEY SOFTWORKS BE LIABLE FOR ANY
SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT. NEGLIGENCE, OR OTHER TORTIOUS ACTIONS, ARISING
OUT OF OR IN CONNECnOr^ WITH THE USE OF THIS WORK.
Introduction (second edit / MGL)
1/13/88 12:22 PM
Introduction
In 1986, Berkeley Softworks pioneerecj GEOS — the Graphic Environment Operating System —
for the Commodore .64. GEOS bffered the power of an icon/windowing operating system, once
thought possible'.on the likes of Apple's Macintosh, to one of the world's lowest priced
microcomputers. The computing community quickly recognized this innovation as significant: the
Software Publisher's Association (SPA) gave GEOS a Technical Achievement Award and
Commodore Business Machines endorsed it as the official operating system for the Commodore
64. Some industry critics even said it brought the Commodore 64 out of obsolescence. Since that
time, GEOS has been ported to the Commodore 128 and, most recently, to the Apple 11 family of
computers. Boasting an installed base approaching one-million units, GEOS not only promises to
be around for some time, but to grow into^the operating system for low-end computers
Why Develop GEOS Applications
GEOS provides an environment for programmers and software companies to quickly and
efficiently develop sophisticated applications. GEOS insulates the programmer from the frustrating
details and dirty work usually associated with application development. By using the GEOS
facilities for disk file handling, screen graphics, menus, icons, dialog boxes, printer and input
device support, the application can concentrate on doing what it does best, applying itself to the
task at hand, using the GEOS system resources, routines, and user-interface facilities to both speed
program development and build better programs.
Consistent User-interface
A very large portion of GEOS is devoted to supporting the user-interface. THe GEOS interface has
proven popular with thousands of users, and an application that takes advantage of this will likely
be well received because the users will already be familiar with the basic program operation. Once
a user has learned to operate geoWrite, for example, it is a smooth transition to another application
such as geoCalc.
Large Installed Base and Portability
GEOS is currently available for three machines: the Commodore 64, the Commodore 128, and the
Apple 11. There are hundreds of thousands of owners who use GEOS on these machines and there
is a correspondingly large demand for follow-on products. With careful programming, an
application can be developed to run under all available system configurations with only minor
changes. Berkeley Softworks plans to port GEOS to other 6502-based microconiputers, thereby
further increasing the user base. As the popularity of GEOS grows, so does the market for your
product.
Application Integration
GEOS offers a flexible cut and paste facility for text and graphic images. These photo scraps and
text scraps allow applications to share data: a word processor can use graphics from a paint
program and a graph and charting application can use data from a spreadsheet. The scrap format is
standard and allows applications from different manufacturers to exchange data, Berkeley
Softworks is currently developing a second-generation scrap facility for object-oriented graphics
such as those used in desktop publishing and CAD programs.
1
Introduction (second edit / MGL)
1/13/88
12:22 PM
Input and Output Technology
GEOS supports the concept of a device driver. A device driver is a small program which co-resides
with the GEOS Kemal and communicates with I/O devices. Device drivers translates data and
parameters from a generalized format. that GEOS understands into a format relevant to the specific
device. GEOS has input drivers for mice, joysticks, light pens, and other input devices, printer
drivers for text and graphic output devices (including laser printers), and disk drivers for storage
devices such as floppy disk drives, hard disks, and RAM expansion units (RAMdisks). As new
devices become available, it is merely necessary to write a driver to support it.
What Exactly is GEOS?
First and foremost, GEOS is an operating system: a unified means for an application to interact
with peripherals and system resources. GEOS is also an environment — specifically, a graphics-
based user-interface environment offering a standard library of routines and visual-based controls,
such as menus and icons. And finally, GEOS is a programmer's toolbox, providing routines for
double-precision integer math, random-number generation, and memory manipulation..
NOTE: GEOS as a general term can represent full range of concepts — an operating system, a
user environment, the deskTop, a group of integrated applications — but in this book it
usually refers specifically to the GEOS KernaU the resident portion of the operating
system with which the application deals with.
GEOS As an Operating System
College textbook writers are forever coming up with splendid new metaphors to describe operating
systems. But as the coach of a baseball team or the governor of California, an operating system has
the same basic function: it is the manager of a computer, providing facilities for controlling the
• system while isolating the application from the underlying hardware. An operating system allows
the application to function in higher-level abstract terms such as "load a file into memory" rather
than "let a bit rotate into the serial I/O shift register and send an acknowledge signal." The
operating system will handle the laborious tasks of reading disk files, moving the mouse pointer,
and printing to the printer,
GEOS provides the following basic operating system functions:
♦ Complete management of system initialization, multiple RAM banks, interrupt
processing, keyboard/joystick/mouse input, as well as an application environment that
supports dynamic overlays for programs larger than available memory, desk
accessories, and the ability to launch other applications.
• A sophisticated disk file system that supports multiple drives, fast disk I/O, and RAM
disks.
• Time-based processes, allowing a limited form of multitasking within an application.
♦ Printer output support, offering a unified way to deal with a wide variety of printers.
2
Introduction (second edit / MGL)
1/13/88 12:22 PM
GEOS As a Graphic and User-Interface Environment
Interactive graphic interfaces have become the norm for niodem day productivity. GEOS provides
a services for placing lines, rectangles, and images on the screen, as well as handling menus,
icons, and dialog boxes. Using the GEOS graphic elements make applications look better and
easier to use.
GEOS provides the following graphic and user-interface functions:
• Multi-level dynamic menus which can be placed anywhere on the screen. GEOS
automatically handles the user's interaction with the menus without permanently
disrupting the display.
• Icons — graphic pictures the user can click on to perform some function.
• Complete dialog box library offering a standard set of dialog boxes (such as the file-
selector) ready for use. The application may also define its own custom dialog boxes.
• A library of graphic primitives for drawing points, lines, patterned rectangles, and
pasting photo scraps from programs like geoPaint.
• Sprite support. (Sprites are small graphic images which overlay the display screen and
can be moved easily. The mouse pointer, for example, is a sprite.)
• A secondary screen buffer for undo operations.
GEOS As a Programmer's Toolbox
« GEOS also contains a large library of general support routines for math operations, string
manipulations, and other functions. This relieves the application programmer of the task of writing
and debugging common routines ("re-inventing the wheel" as it were).
GEOS provides the following support routines:
• Double-precision (two-byte) math: shifting, signed and unsigned multiplication and
division, random number generation, etc.
• Copy and compare string operations.
• Memory functions for initializing, filling, clearing, and moving.
• Miscellaneous routines for performing cyclic redundancy checks (CRC), initialization,
error handling, and machine-specific functions.
Development System Recommendations
There are many ways to develop GEOS applications. Berkeley Softworks, for example, uses a
UNIX™ based 6502 cross assembler and proprietary in-circuit emulators to design, test, and
debug GEOS applications. Most developer's, however, will find this method too costiy or
impractical and will opt to develop directly on the target machines. Anticipating this, Berkeley
3
Introduction (second edit / MGL)
1/13/88 12:22 PM
Softworks has developed geoProgrammer, an assembler, linker, debugger package designed
specifically for building GEOS applications.
geoProgrammer
geoProgrammer is a sophisticated set of assembly language development tools designed
specifically for building GEOS applications. geoProgrammer is a scaled-down version of the
UNIX™ based development environment Berkeley Softworks actually uses to develop GEOS
programs. In fact, nearly all the functionality of our microPORT™ system has been preserved in
the conversion to the GEOS environment. All sample source code, equates, and examples in this
book are designed for uses with geoProgrammer.
The geoProgrammer development system consists of three major components:
geoAssembler, the workhorse of the system, takes 6502 assembly language source code and
creates linkable object files.
• Reads source text from geoWrite documents; automatically converts graphic and icon
images into binary data.
• Recognizes standard MOS Technology 6502 assembly language mnemonics and
addressing modes.
• Allows over 1,000 symbol, label, and equate definitions, each up to 20 characters long.
• Full 16-bit expression evaluator allows any combination of arithmetic and logical
operations.
• Supports local labels;, as targets for branch instructions.
• Extensive macro facility with nested invocation and multiple arguments.
• Conditional assembly, memory segmentation, and space allocation directives.
• Generates relocatable object files with external definitions, encouraging modular
programming.
geoLinker takes object files created with geoAssembler and links them together, resolving all
cross-references and generating a runable GEOS application file.
• Accepts a link command file created with geoWrite.
• Creates all GEOS applications types (sequential, desk accessory, and VLIR), allowing a
customized header block and file icon. geoLinker will also create standard Commodore
applications which do not require GEOS to run.
• Resolves external definitions and cross-references; supports complex expression
evaluation at link-time.
• Allows over 1,700 unique, extemally referenced symbols.
• Supports VLIR overlay modules.
4
Introduction (second edit / MGL)
1/13/88 12:22 PM
geoDebugger allows you to interactively track-down and eliminate bugs and errors in your GEOS
applications.
• Resides with your application and maintains two independent displays: a graphics screen
for your application and a text screen for debugging.
• Automatically takes advantage of a RAM-expansion unit, allowing you to debug
applications which use all of available program space.
• Complete set of memory examination and modification commands, including memory
dump, fill, move, compare, and find.
• Symbolic assembly and disassembly.
• Supports up to eight conditional breakpoints.
• Single-step, subroutine step, loop, next, and execute commands.
• RESTORE key stops program execution and enters the debugger at any time.
• Contains a full-featured macro programming language to automate multiple keystrokes
and customize the debugger command set.
Commodore 64
GEOS was first implemented on the Commodore 64, and currentiy there are more GEOS
applications for this system than the Apple II or the Commodore 128. The following is
recommended for developing under this environment:
• Commodore 64 or 64c computer.
• Commodore 1351 mouse.
• At least one 1541 or 1571 disk drive.
• Commodore 1764 or 1751 RAM-expansion unit.
• GEOS supported printer.
• The basic GEOS operating system (GEOS 64), version 1.3 or later which includes
geoWrite and geoPaint.
• geoProgrammer for the Conimodore 64.
Commodore 128
The Commodore 128 may be the ideal environment for prototyping and developing GEOS
applications because it can be used to create programs which run under GEOS 64 (in 64 emulation
mode) and GEOS 128. The 128 sports a larger memory capacity, and geoProgrammer takes
advantage of this extra space for symbol and macro tables. The following is recommended for
developing under this environment:
5
Introduction (second edit / MGL) 1/13/88 12:22 PM
• Commodore 128 computer,
• Commodore 1351 mouse.
• At least one 1541 or 1571 disk drive.
• Commodore 1764 or 1751 RAM-expansion unit.
• GEOS supported printer.
• The basic GEOS operating system (GEOS 64), version 1.3 or later which includes
geoWrite and geoPaint.
• The basic GEOS 128 operating system, version 1.3 or later which includes geoWrite
128 and geoPaint 128.
• geoProgrammer for the Commodore 128.
Apple II
The Apple II is the latest addition to the GEOS family. The following is recommended for
developing in this environment:
• Apple He, lie, or Ilgs computer.
• Apple Mouse card.
• At least one floppy disk drive.
• RAM card or hard disk.
• GEOS supported printer.
• The basic GEOS operating system (Apple GEOS), which includes geoWrite and
geoPaint.
• geoProgrammer for the Apple 11.
Other Useful GEOS Applications
In addition to those applications listed above, you may find the following useful:
• GEOS Icon Editor for customizing you icons.
• Photo Manager and Text Manager for cutting and pasting text and graphics to and from
your geoProgrammer source code modules.
• Text Grabber for converting any 6502 source code you may have already written to
geoWrite.
6
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Graphic Routines
As the name GEOS (Graphics Environment Operating System) implies, screen graphics are central
to both the operating system and its applications. GEOS provides a number of graphic primitives
("primitive" because they are the basis of more complex objects) for drawing points, lines,
rectangles, and other objects, as well as displaying bitmap images such as those cut from geoPaint.
GEOS also provides graphic support routines for undoing regions, inverting areas, scrolling,.and
direcdy accessing the screen memory.
Drawing with the built-in GEOS routines increases program portability by making much of the
internal, machine-dependent screen architecture transparent to the application. When you draw a
line, for example, you merely supply the two endpoints. GEOS takes care of calculating the proper
pixel locations and modifying the screen memory. This allows an application to use the same code
to draw lines on machines with very different graphics hardware and spares the programmer from
dealing direcdy with screen memory.
Introduction to GEOS Graphics
If you look closely at a monitor or television screen, you will notice that the image is made up of
many small dots. These small dots, called pixels, can be either on or off and are represented in
memory by I's and 0*s, respectively. A pixel with a value of one is considered set and a pixel of
value zero is considered clear. This binary, or bitwise, representation of images is refered to as
bitmapped graphics, and a bitmap is a picture or image created in this way.
0000000000
0000000000
0000000000
0000000000
1
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Color
Although some hardware configurations support color graphics, GEOS assumes that the screen is
a monochromatic device; that is, GEOS only deals with one drawing color and one background
color. Typically, the drawing color is black, like ink and the background color is white, like a piece
of paper. Depending on the monitor being used and the Preference Manager settings, the actual
displayed colors may be different. We will refer to the color displayed by a zero-pixel as the
background color and the color displayed with a one-pixel as the drawing color. Applications that
support multiple drawing colors, such as the Commodore 64 version of geoPaint, must do so on
their own, bypassing GEOS (at the expense of portability) to provide multiple colors on the screen.
The GEOS Virtual Screen
The GEOS screen is often referred to as virtual screen^ one whose layout and internal storage
characteristics exist independent of any underlying graphics hardware. For this reason, the GEOS
screen is fundamentally identical under all versions of the operating system.
The GEOS screen is a rectangular array of pixels arranged like a sheet of graph paper. Each pixel
on the screen has a corresponding (x,y) coordinate. The x-axis begins with zero and runs
horizontally (left to right) across the screen, and the y-axis begins with zero and runs vertically (top
to bottom) down the screen. The maximum x- and y-positions, because they differ from machine
to machine, are calculated by subtracting one from the GEOS constants SC FIX WIDTH and
SC FIX HEIGHT.
(0. 0)
^ (SC FIX WIDTH-1.0
X increasing
-<
5*
o
3
GEOS
0)
22.
SCREEN COORDINATES
3*
(Q
(0. SC_PIX_HEIGHT-1 ) (SC_PIX_WIDTH-1 , SC_PIX_HEIGHT-1 )
Important: GEOS does no clipping or range-checking on coordinates passed to it. If you pass
it invalid data or coordinates, Ae results are unpredictable and will often crash the
application.
2
Graphics Routines (fourth edit / MGL) 4/24/8 8 8:13 PM
GEOS 128 40/80-Column Support
Because applications that run under GEOS 128 may want to take advantage of both the 40- and 80-
column screen modes, the following conventions have been adopted for the screen width and
height constants:
• The following constants can be used to access the dimensions of the 40- or 80-column
screen specifically:
SC 40 WIDTH
Pixel width of 40-column screen.
SC 40 HEIGHT
Pixel height of 40-column screen.
SC 80 WIDTH
Pixel width of 80-column screen.
SC 80 HEIGHT
Pixel height of 80-column screen.
• If the application is designed to run under GEOS 128 only and not run under GEOS 64
(the C64 constant is set to $00 and the CI 28 constant is set to $01 ), then the standard
SC^PIXJWIDTH and SCJPIXJHEIGHT constants take on the following values:
SC FIX WIDTH
Pixel width of 80-column screen.
iiC'HX'HElOHT
Pixel height of 80-column screen.
• If the application is designed to run under GEOS 64 and GEOS 128 (both the C64
constant and the C128 constant set to $01), then the standard SC_PIX_WIDTH and
SC_PIX_HEIGHT constants take on the following values:
WiDtH
Pixel width of 40-column screen.
SC FIX HElGHt
Pixel height of 40-column screen.
This is because the application (typically) will be written with the 40'Column screen in
mind. At runtime, the application can check to see which version of GEOS it is running
under and add doubling bits to the appropriate coordinate values so that the 40'Column
coordinates will be normalized automatically when GEOS 128 is in 80'Column mode.
An application can use the following subroutine to determine whether it is running under GEOS
128 or GEOS 64:
.if (0)
Checkl28:
Check for GEOS 128.
Pass :
nothing
Returns :
St minus flag set if running under GEOS 128,
Example usage:
/ignore if under GEOS 64
;else, patch x-coordinates with doubling bits
'3
jsr Checkl28
bpl 10$
jsr DoDoubling
10$:
3
Graphics Routines (fourth edit / MGL)
4/24/88
8:13 PM
.endif
Checkl28:
Ida
cmp
bpl
10$:
Ida
rts
#$12
version
10$
cl28Flag
cl28Flag not guaranteed to be valid in version 1.2 and lower
first see if version <= 1.2
if so; branch and say C64 . Note this is a signed comparison,
(it WILL NOT work if GEOS goes beyond version $7f !)
else set minus based on high bit cl28Flag
When running under GEOS 128, the graphMode variable may be checked to determine whether
GEOS is in 40- or 80-column mode:
bit graphMode / check 40/80 mode bits
bpl C64Mode ; branch if in 4 0-column mode
; else, handle as 80-column...
For more information, refer to "GEOS 128 X-poisition and Bitmap Doubling" in this chapter. Also
see NormalizeX in the Routine Reference Section.
Inclusive Dimensions
All dimensions and GEOS coordinates are inclusive: a line contains the endpoints which define it,
and a rectangle includes the lines that make up its sides. For example, a rectangle defined by an
upper-left comer of (10,10) and a lower-right comer of (20,20) would include the lines around its
perimeter defined by the points (10,10), (10,20), (20,10), and (20,20).
Linear Bitmap
For the purpose of bitmap compaction and patterns, the GEOS screen is treated as a linear bitmap,
a contiguous block of bytes with each bit controlling an individual pixel. The bytes are lined up
end-to-end for each screen line! The high-order bit (bit 7) of each byte controls the leftmost pixel
and the low-order bit (bit 0) controls the rightmost pixel.
X-axis
1 1 1 J 1 1 1 1 1 1 ij 1 1 1 r
1
X
(5*
byte byte 1
GEOS Virtual Screen
Keep in mind that this is a conceptual organization of the screen; the actual in-memory storage of
the screen and bitmap data may be very different
Dividing the Screen Into Cards
Many GEOS routines subdivide the GEOS virtual screen into 8x8-pixel blocks called cards. A card
is a two-dimensional unit of measurement eight pixels on each side. The first card begins in the
4
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
upper-left comer of the screen (0, 0) and extends to (7, 7). The next card is just to the right of the
first and extends from (8, 0) to (15, 7).
Cards are always aligned to eight pixel boundaries called card boundaries (pixel positions 0, 8, 16,
24, etc.). Aligning an object to a card boundary is called card alignment^ and tiie position of an
object expressed in cards is called its card position. Pixel position (32, 72), for example, would
correspond to card position (4, 9) because 32/8 =.4 and 72/8 = 9). The card width of an object is
its width in cards, and the card height is its height in cards. An entire row of cards is called a
cardrow.
The card is a convenient unit of measurement because its dimensions, 8x8, which is a power of 2,
lend themselves to simple binary arithmetic. For example, converting a pixel position to a card
position is merely a matter shifting right three times.
Example:
MseToCardPos :
converts current mouse positions to card position
Pass :
Uses :
Returns :
Destroys :
nothing
MouseXPos, MouseYPos
rOL mouse card x-position (byte)
rOH mouse card y-position (byte)
a,x,y
(mgl)
llr It 1^ ************************** *
MseToCardPos:
php
• save current interrupt disable status
sei
• disable interrupts so mouseXPos doesn't change
MoveW
MouseXPos, rO
' copy mouse x-position to zp work reg (ro)
pip
• reset interrupt status asap.
Idx
#rO
• divide x-position (rO) by 8
Idy
#3
• (shift right 3 times)
jsr
DShiftRight
• this gives us the card x-position in rOL
Ida
MouseYPos ,
• get mouse y-position
Isr
a t
' and shift right 3 times
Isr
a <
• which is a divide by 8
Isr
a t
• and gives us the card y-position in a
sta
rOH
• set down card y-position
rts
• exit
Cards are also convenient because they map directly to the internal storage format of the
Commodore 40-column graphics screen. (Converting to other formats, such as the Commodore
128 80-column screen or the Apple n double hi-res screen, requires additional translation. This
translation is handled automaticdly by the GEOS graphics routines.)
Display Buffering
Normally the application has control of the screen. But when an item such as a dialog box or a
menu is displayed, GEOS overwrites the screen. When the dialog box is removed or the menu is
retracted, GEOS needs to restore the portion of the screen it destroyed. For this purpose, GEOS
5
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
maintains a background screen buffer. Most of the time, the background buffer contains an exact
copy of the foreground screen (rfie screen that is displayed) because GEOS normally sends
graphics data to both screen buffers. When a temporary object is displayed, however, it is only
drawn to the foreground screen. Removing the object, or recovering the original area of the screen,
is then simply a matter of copying pixels from the background buffer to the foreground screen. The
GEOS dialog box and menu routines- handle this sort of recovery automatically.
dispBufferOn
Usually the application will want to draw to both buffers so that GEOS can properly recover the
foreground screen after menus and dialog boxes. If graphics are only drawn to one buffer and a
menu is brought down or a dialog box is displayed, the subsequent recover may restore the wrong
data.
However, sometimes an application may want to limit drawing to only the foreground or
background screen buffer. GEOS graphics and text routines use the global variable
dispBufTerOn to determine whether to draw to the foreground screen, the background buffer, or
both simultaneously. Bits 6 and 7 of dispBufferOn determine the writing and reading mode:
bit 7:
i
1 — use foreground screen.
— do not use foreground screen.
bit 6:
1 — use background buffer.
— do not use background buffer.
bits 5-0:
reserved for future use — should always be 0.
There are some constants which allow you to gain access to these bits:
ST^WR^FORE use foreground.
ST_WR_B ACK use background.
and they can be used in following manner:
;Use both foreground screen and background buffer (normal) .
LoadB dispBufferOn, # (ST__WR_FORE I ST_WR_BACK)
;Use foreground screen only.
LoadB dispBufferOn, #ST__WR_FORE
;Use background buffer only.
LoadB dispBufferOn, #ST_WR_BACK
Note: If bits 6 and 7 of dispBufferOn are both zero, GEOS considers this an undefined
state and will not produce useful results. In most cases, the internal address calculations
will force your graphic objects to appear in the center of the drawing area where they
can do little harm. If the center line on the screen becomes garbled, dispBufferOn
probably contains a bad value.
Using dispBufferOn
Typically applications leave dispBufferOn set to draw to both screens, whereas most desk
accessories will only draw to the foreground screen. In some situations, an application may want
to limit drawing to the foreground screen so that it may recover from the background buffer at a
later time. Internally this is what GEOS does when it opens a menu or dialog box: the object is
6
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
only drawn to the foreground screen, and when it needs to be erased, the original data is recovered
from the background buffer. dispBufTerOn can also be used to pre-draw complex objects in the
background buffer (ST_WR_BACK) and make them instantly appear on the foreground screen
by doing a recover. "
An application must take special precautions.when using dispBufferOn to draw selectively to
one buffer or the other. For example, when GEOS automatically recovers from a menu or a dialog
box, it recovers the data from the background buffer. If the background buffer has not been
updated (the application has been drawing with the ST_WR_BACK bit cleared, for example),
then the menu or dialog may recover the wrong data.
Since dialog boxes are only displayed when the the application calls DoDlgBox and menus are
only opened while GEOS is in MainLoop, the application has some control over GEOS's
automatic recovering. The application can postpone displaying dialog boxes and returning to
MainLoop until the foreground screen and background buffer contain the same data. If an
application must return to MainLoop while the buffers contain different data (to let processes run,
for example), it can always disable menus by clearing the.MENUON_BIT bit of mouseOn. The
menus may be reenabled again by restoring the MENUON_BIT bit of mouseON:
Example:
StopMenus :
MoveB
rmbf
rts
mouseOn, oldMouseOn
MENUON BIT,mouseOn
save current enable status for later
disable menus temporarily
exit.
RestartMenus :
Ida
and
ora
sta
rts
OldMouseOn :
OldMouseOn
#(%1 «MENUON_BIT)
mouseOn
mouseOn
.byte $00
get old menu enable status
ignore all but menu bit
restore old menu bit
in current mouseOn byte
exit
temp save area for mouseOn variable
Using the Background Buffer as Extra Memory
Some applications are so starved for memory that they opt to use the background buffer for
program code or data. To do this, they must always keep the ST_WR BACK bit of
dispBufferOn clear so that the background buffer is not corrupted with graphic 3ata.
If you disable the background buffer, GEOS cannot automatically recover after menus and dialog
boxes. The application must provide its own routine for restoring the foreground screen. There is a
GEOS vector called RecoverVector, which normally points to the RecoverRectangle
routine. Whenever GEOS needs to recover from a menu, dialog box, or desk accessory, it sets up
parameters as if it were going to call RecoverRectangle and jsr's indirectly through the address
in RecoverVector. If the application is using the background buffer, it must place the address of
its own screen recover routine in RecoverVector. When GEOS needs to recover a portion of the
screen, it will jsr to the application's recover routine with the following register values describing
the rectangular area to recover:
r3 XI — x-coordinate of upper-left (word).
r2L Yl — y-coordinate of upper-left (byte).
r4 X2 — x-coordinate of lower-right (word).
r2H Y2 — y-coordinate of lower-right (byte).
7
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
where (X1,Y1) is the upper-left comer and (X2,Y2) is the lower-right comer of the rectangular
area to recover. The rectangle's coordinates are inclusive. The application must then use these
values to restore the portion of the screen that lies within the rectangle's boundaries and retum with
an rts. This recovery can be as simple as filling with a halftoned pattern or as involved as
redrawing graphic and text objects that fall within the rectangular recover area.
Most of the larger Berkeley Softworks GEOS applications use a technique called
saveFG/recoverFG (short for "save foreground" and "recover background") to save and recover
the foreground screen when displaying menus and dialog boxes. Basically, saveFG will save a
rectangular subregion of the foreground screen to a special buffer just before GEOS displays a
menu or a dialog box. When GEOS tries to recover from the background buffer, recoverFG
restores the data from the special buffer. Although the size of the buffer varies from application to
application, it will seldom be larger than 5.5K (just large enough to hold the largest standard
dialog box).
Transferring data to and from the buffer is fairly straightforward. With the Commdore 40-column
screen, it is mostly a matter of calculating the proper address offsets and copying bytes. With the
GEOS 128 80-column screen, the process is compUcated a bit because the bytes must be read from
the VDC chip's RAM. With Apple GEOS, the process is simplicity itself because there are two
routines for saving and restoring automatically: saveFG and recoverFG.
The real trick is knowing how to intercept the normal GEOS menu and dialog box drawing and
recovering mechanisms. Dialog boxes are the easiest because they are always called by the
application. The program only needs to save the foreground screen area prior to calling
DoDIgBox. The size of the dialog box can be caculated from its table (be sure to account for any
shadow) and the foreground data can be copied into the saveFG buffer. When the dialog box is
finished, GEOS will jsr through RecoverVector. The application installs its own recoverFG
routine into RecoverVector and restores the foreground area from the saveFG buffer. The
GEOS dialog box recovery does have one quirk that concerns shadowed dialog boxes. GEOS
shadowed dialog boxes consists of two overlapping rectangular areas: the actual diaJog box and the
slightly offset shadow rectangle. GEOS first calls through RecoverVector once for the region
bounded by the shadow box, then again for the region bounded by the dialog box. When saving
the foreground area, the entire dialog box region (the area bounded by the union of all eight comer
points) should be saved and a special flag should be set so that the area is only recovered once.
Under Apple GEOS, the recovery of dialog box shadows can be suppressed by setting
recoverOnce to a non-zero value. When recoverOnce is non-zero, GEOS only vectors through
RecoverVector once with the bounding rectangle of the dialog box. The application's recover
routine will need to compensate for the shadow box. For more information on dialog boxes, refer
to Chapter @DLG@ .
Saving the foreground area before a menu is displayed is a bit tougher because GEOS displays
menus at MainLoop, the application has little notice that a submenu is opening up. Fortunately,
there is a workaround: GEOS supports a special type of sub-menu called a dynamic sub-menu.
Just before a dynamic sub-menu opens, GEOS calls a subroutine whose address is stored in the
menu data structure. This opporunity can be used to save the foreground screen area before GEOS
draws the menu by calculating the bounding rectangle from the menu structure. When GEOS
recovers a menu, it calls through RecoverVector as it does with dialog boxes. With multiple
sub-menus, the menus are always recovered in the reverse order they were drawn. For more
information on menus, refer to Chapter @ICNMENU@
8
Graphics Routines tfourth edit / MGL)
4/24/88 8:13 PM
Manual Imprinting and Recovering
Within an application, data can be moved between the foreground screen and background buffer
with GEOS routines that copy data to and from the two areas. Copying data from the foreground
screen to the background buffer is called imprinting, and copying data from the background buffer
to the foreground screen is called recovering. There are GEOS routines for imprinting and
recovering points, lines, and rectangular regions.
Some Possible dispBufferOn Complications
When drawing with both buffers enabled (with both foreground and background bits set in
dispBufferOn), GEOS requires that the foreground screen and the background buffer contain
exacdy the same data. If they are different, the resuhs of graphic operations may be unpredictable.
If you need to draw to the foreground screen and the background buffer when they contain
different data, you must perform the graphic operation once by writing only to the foreground
screen, and then a second time, writing only to the background buffer — you cannot write to both
of screen areas simultaneously if they contain different data.
Machine Dependencies
The GEOS graphics routines hide much of the underlying hardware from the application. This
allows the same code to run under a variety of different environments with very few changes.
However, it is sometimes necessary to optimize graphic routines for a specific machine. This can
be as simple as taking advantage of color display capabilities or as complex as direct screen
memory manipulation. Either way, an application should only resort to such tactics when the
desired effect cannot be achieved through the standard graphics routines. Be aware that
circumventing the GEOS Kemal will very likely increase your development time and that there is
no guarantee that the techniques will be compatible with future versions of GEOS.
Commodore 64
The Commore 64 version of GEOS uses the standard high-resolution bitmap mode (not multi-color
bitmap mode), which is 320 pixels wide by 200 pixels high. Memory is mapped to the screen in
eight-byte stacks called cards: byte controls pixels (0,0) through (7,0), with bit 7 on the left and
bit on the right, and byte 1 controls the same pixels on the Une below, which is pixels (0,1)
through (7,1). This stacking continues through byte 7, which controls pixels (0,7) through (7,7)
and completes the 8x8-pixel card. Byte 8 begins the next card, controlling pixels (8,0) through
(15,0). The screen memory begins at SCREEN BASE and occupies 8,000 bytes, extending to
SCREEN_BASE+7999. The background buf^r begijis at BACK SCR BASE and extends
to BACK^SCR_BASE+7999.
GEOS does not directly support the foreground and background color options of the standard
high-resolution bitmap mode. The color matrix, located from COLOR_MATRIX to
COLOR MATRIX+999, is set to a constant foreground and background color as determined
by the Preference Manager. If an application wants to support color Gike geoPaint), it must manage
the color matrix itself. Each byte in the color matrix sets the foreground and background colors of a
card (8x8 pixel block): color byte sets the colors for card (bitmap bytes 0-7) and color byte 1
sets the colors for card 1 (bitmap bytes 8-15). Before the application exits, it must restore the
original color matrix. This best done by sa;ving the first byte and then filling the color matrix before
calling EnterDeskTop, as the following code fragments illustrate:
Example:
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
;0n entry, save off the first byte of the color matrix
MoveB COLOR_MATRIX, saveColor
;0n exit, fill the color matrix with the saved value
LoadW rO,#1000 /color matrix is 1000 bytes
LoadW r 1 , #COLOR_MATRIX
MoveB saveColor, r2L ;fill with original color
jsr FillRam
Commodore 128
In 40-column mode, GEOS 128 screen memory is identical to the Commodore 64. In 80-column
mode, GEOS 128 uses the high-resolution 640x200 mode supported by the 8563 VDC (Video
Display Controller) chip.. The foreground screen memory is not stored in the normal Commodore
memory but on the VDC chip instead. The VDC RAM is accessed indirecdy through the VDC
control registers. The screen occupies 16,000 bytes, and each byte is accessed one at time by its
address within the VDC display RAM(the first screen byte is at 0, the last at 15999). Bits are
mapped sequentially from memory to the screen pixels: bits 7 through of byte (in that order)
control the first seven pixels, (0,0) through (7,0). The following byte controls the next seven
pixels, (8,0) through (15,0). And so on for the remainder of the screen. The following two
subroutines will access bytes in the VDC screen RAM when GEOS 128 is in 80-column mode:
Example:
*********************************** **«***«***«****«4r**********«**«***-****««^
StaSOFore
LdaSOFore
Pass :
r5
A
— stores byte to 128 80-column foreground screen
— loads byte from 128 80-column foreground screen
= address in foreground memory
= data value (for StaSOFore)
Returns:
A
Destroyed:
x
» data value (for Lda80Fore)
Note: Call TempHideMouse to disable software sprites before accessing
foreground screen directly.
(mgl)
Constants for VDC internal registers
VDC_HI_UPDATE
VDC_LO_UPDATE
VDC DATA
18
19
31
/update hi-byte of VDC pointer
/update lo-byte of VDC pointer
;data byte at current VDC pointer
StaSOFore:
; Send data byte to the VDC chip
jsr NewVDCAddress
Idx #VDC_DATA
stx VDC
30$: bit VDC
bpl 30$
sta VDC+1
rts
Update VDC address with fg screen pointer (r5)
request VDC data register
test VDC status
loop till VDC ready for data byte
store data byte
exit
10
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
LdaSOFore:
; Get data byte from the VDC chip
jsr NewVDCAddress ; Update VDC address with fg screen pointer (r5)
Idx #VDC__DATA ; request VDC data register
stx VDC
30$: bit VDC ; t^st VDC status
bpl 30$ ; loop till data byte ready
Ida VDC+1 ; get data byte
rts / exit
NewVDCAddress :
; Transfer value in r5 to VDC internal hi/lo address register.
; Destroys:
X
Idx
#VDC_HI__UPDATE
ask VDC for high byte
stx
VDC
10$:
bit
VDC
• check VDC status
bpl
10$
• and loop till VDC ready
Idx
r5H
• store hi-byte of address
stx
VDC+1
• to VDC chip
Idx
#VDC_LO_UPDATE
• ask VDC for low-byte
stx
VDC
20$:
bit
VDC
• check VDC status
bpl
20$
• and loop till VDC ready
Idx
r5L
• store lo-byte of address
stx
VDC+1
• to VDC chip
rts
• exit
For more information on controlling the 8563 VDC chip, refer to the Commodore 128
Programmer's Reference Guide.
Before writing directly to the 80-column foreground screen, be sure to call TempHideMouse to
temporarily disable the virtual sprites (for more information, refer to TempHideMouse in
Chapter XX).
c
Because the 80-column screen requires a 16,000-byte background buffer, GEOS 128 (when in 80-
column mode) uses the 8,000-byte 40-column screen foreground buffer (SCREEN BASE to
SCREEN_BASE+7999) for store the first 100 scanlines of background buffer data and the
8,000-byte foreground screen buffer (BACK_^SCR_BASE to BACK_SCR_BASE+7999)
to store the last 100 scanlines of background^buffeF data. Because these data areas are not
contiguous, an application that directly accesses the background screen must compensate for this
break.
Apple II
Apple GEOS uses the double hi-res screen, which is 560 pixels wide by 192 pixels high. The
seven lower bits (0-6) of each graphic byte are displayed in bit to bit 6 order on the screen, and
bit 7 is ignored (not displayed). That is. Pixel (0,0) is controlled by bit of byte 0, pixel (1,0) is
controlled by bit 1 of byte 0, and pixel (7,0) is controlled by bit of byte 1. The graphic screen is
located in memory at SCREEN^BASE ($2000) to SCREEN_BASE+$lfff ($3fff) in both the
main and auxiliary memory banks? The bytes in main memory are mapped to odd byte positions on
the screen (bytes 1,3,5...), and the bytes in auxiliary memory are mapped to even byte positions
on the screen (byte 0,2,4...). This means that adjacent bytes on the screen are in separate banks of
memory. For example, byte is located at $2000 in the auxiliary bank and byte 1 is located at
$20(X) in the main memory bank. (For more information on accessing the Apple foreground screen
across memory banks, refer to GetScanLine in the Routine Reference Section.)
11
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Apple GEOS uses over 7K of tables to efficiently map pixel positions to screen memory bytes,
thereby avoiding time-consuming shift and convert algorithms. If an application writes directly to
screen memory, keep in mind that it will need to handle this pixel conversion manually. Also,
before writing directly to the Apple screen, be sure to call TempHideMouse to temporarily
disable the virtual sprites (for more information, refer to TempHideMouse in Routine Reference
Section).
Porting Considerations and Techniques
Outside of the normal considerations for porting a GEOS application from one machine to another,
there are a few additional elements which pertain specifically to graphics.
Apple GEOS and GEOS 128 Virtual Sprites
Apple GEOS and GEOS 128 (in 80-column mode) render sprites entirely in software by modifying
the actual bitmap screen. (GEOS 64 and GEOS 128 in 40-column mode, use the hardware sprite
capabilities of the VIC chip.) In order to properly treat these virtual sprites as if they were apart
from the bitmap screen, they must be erased before any graphic operation, whether drawing,
testing, imprinting, or recovering, is done. To do this, Apple GEOS and GEOS 128 provide the
TempHideMouse routine to temporarily remove all sprites. The sprites are not redrawn until the
application returns to MainLoop. Normal GEOS graphics and text routines will automatically call
TempHideMouse; only applications that are directly accessing the foreground screen area need
call TempHideMouse. For more information, refer to TempHideMouse in the Routine
Reference Section "Software Sprites" in Chapter @ SPRITE®.
GEOS 128 X-position and Bitmap Doubling
Because the GEOS 128 80-column bitmap screen has a horizontal resolution exacdy twice that of
GEOS 64 (640 vs. 320), GEOS 128 supports the ability to automatically double the x-
coordinate(s) of graphic and text objects, and the width of bitmap objects, by setting spetial bits in
the x-position and width calling parameter(s). This allows the visual elements of a GEOS 64
application to run in 80-column mode under GEOS 128 with a minimum of effort. The special bits
can also be added at run-time to dynamically configure a program to run correctly under both
GEOS 64 and GEOS 128. X-position and bitmap doubling is supported by nearly every GEOS
128 routine that writes to the screen (including text, dialog lx)x, and icon routines).
The following constants may be bitwise or*ed into GEOS 128 x-coordinates and bitmap widths to
take advantage of the automatic 80-column doubling features:
12
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
DOUBLE^W
For doubling word-length values. Normal x-
coordinates, such as those passed to Rectangle and
DrawPoint.
DOUBLETS
For doubling byte-length values. A byte-lei||Mt value is
either a card x-position or a card width, botn of which
apply almost exclusively to bitmap routines, such as
R iftTiJi nT In nnH Ritmanr^lin
u 11 Jii<i p u p diivi JLyiiiiiapv^ii |j.
ADDl^W
Used in conjunction with DOUBLE_W; adds one to
a doubled word-length value. This allows addressing
odd-coordinates, as when drawing a one-pixel frame
around a filled rectangle.
Used in conjunctioij-with DPUBLEJB; ad^s-one u>a
^oublpd:Dyte lengtn valupr^ /
These doubling bits have no effect when GEOS 128 is in 40-column mode but come to life when
GEOS 128 is in 80-column mode. For example, the following code fragment will frame a filled V^>5i^>^,
rectangle. It will appear similarly in both 40- and 80-column modes.
Example:
XI
= 35
;left
edge
X2
« 301
/ right
edge
Yl
= 40
/top edge
Y2
= 100
/bottom edge
; Draw
a filled
rectangle using the
current
pattern
jsr
i_Rectangle.
/inline call
.byte
Yl . .
;yi
.byte
Y2
;y2
.word
(X1|D0UBLE_W|ADD1_W)
/xl with doubled
width
.word
(X2|D0UBLE__W)
/x2 with doubled
width
jsr
i^FrameRect angle
/inline call
.byte
Yl
;yi
.byte
Y2
;y2
.word
(X1|D0UBLE__W)
/xl with doubled
width
.word
(X2I DOUBLE WIADDl W)
/x2 with doubled
width
.byte
$ff
/solid line pattern
rts
/ exit
+ space on left for frame
+ offset for frame
NOTE: GEOS 128 filters all word-length x-coordinates (but not widths or byte-length x-
coordinates) through the routine NormalizeX to process the doubling. For more
detailed information on how this routine works, refer to its documentation in this
chapter. NormalizeX will also double signed x-coordinates. If the x-coordinate is a
signed number (like you might pass to SmallPutChar), then the double bits must be
exclusive-or'ed into the x-coordinate parameters rather than simply ofed.
The graphic elements of existing GEOS 64 applications can be ported to run under GEOS 128 with
a minimum of effort by taking advantage of the GEOS 128 doubling bits. However, once the
doubling bits have been installed, the application will' no longer run under GEOS 64. The simplest
approach to this problem is to have two entirely different applications. One designed to run under
GEOS 64 and the other designed to run under GEOS 128. The doubling bits may be controlled at
assembly-time with conditional assembly, as the following example illustrates.
Example:
13
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
DblDemol :
;Will assemble differently depending on the status of the C64 and C128 assembly
/constants. If assembling for GEOS 64, doubling constants will be set to zero so
;that they will not affect the x-poisitions. If assembling for GEOS 64, doubling
/constants will be set according to geosConstants file so that graphic operations
;will double automatically in 128 mode.
.if (C128 C64)
.if !C128
DOUBLE_B
ADDl e
DOUBLE__W
ADDl W
;C64/C128 flags must be mutually exclusive!
;if not assembling for GEOS 128, force doubling
/constants to harmless values so GEOS 64 graphics
/routines don't get confused.
= $00
-= $0000
= $0000
.endif
BM__XPOS
BM YPOS
= (32/8)
« 20
/byte x-position of bitmap (40-col)
/y-position of bitmap
Bitmap:
BM_WIDTH
BM HEGHT
PicW
PicH
/byte bitmap width (40-col)
/bitmap height
FPATTERN
DoBmap:
%11111111 /pattern for surrounding frame
/Place the bitmap on the screen, loading the registers with
/inline
data
(note double-width settings) .
jsr
i__BitmapUp
/inline call
.word
Bitmap
/bitmap address
.byte
(BM_XPOS|DOUBLE_B)
/xpos
.byte
BM^YPOS
/ypos
.byte
(BM_WIDTH 1 DOUBLETS)
/width
.byte
BM_HEIGHT
/ height
90$:
rts
/exit
• else
/ (both
C128 & C64 constants were both true or both false)
.echo
"DblDemo routin^'^Ursigned to assemble for both GEOS
.endif
r\
Designing an application so that it runs well under both GEOS 64 and GEOS 128 is a more
difficult task. It usually involves using self-modifying code: part of the initialization code for each
module can check the version of GEOS it is running under (use the Checkl28 subroutine
illustrated in "GEOS 128 40/80-Column Support" in this chapter) and add the proper doubling-bits
to all relevant x-coordinates.
14
Graphics Routines (fourth edit / MGL)
4/24/88. 8:13 PM
Apple Bitmap Doubling and Aux-memory Bitmaps
Apple GEOS supports the ability to automatically double the width of bitmap objects by setting
special bits in the x-width calling parameter(s). TTiis allows GEOS 64 bitmaps to be converted to
Apple GEOS with a minimum of effort. By doubling the width, a similar appearance can be
maintained. Apple GEOS bitmap routines can also specify whether the bitmap data is in main
memory or auxiliary memory by setting special bits in the x-position parameters. Bitmap doubling
and aux-memory specification applies to the following routines and any other higher-level routines
which depend on these for placing bitmaps on screen (such as Dolcons):
• BitmapUp
• NewBitUp
• BitmapCIip
•NewBitCIip
• BitOhterClip
• NewBitOtherClip
Because Apple GEOS allows widths specified by byte values (as in BitmapUp) and widths
specified by word values (as in NewBitUp), there are different bits and constants to use for
doubling the width, depending on the number of bytes (one or two) in the parameter. To double
the widdi of a bitmap, bitwise-or one of the following constants into the width parameter:
d6uble w
For doubling word-length values.
DOUBLE b
For doubling byte-length values.
\
To force Apple GEOS to grab the bitmap data from auxiliary memory, bitwise-or the bitmap x-
position with one of the following values, depending on whether the x-position is a byte-length or
word-length parameter:
INAUX B
for byte-length x-position parameters.
iNai)X"'w
for word-length x-position parameters.
For more information on the bits to set for bitmap doubling and auxiliary memory specificatiion,
refer to the documentation of the specific routines in Routine Reference Section.
Example:
;Put a bitmap up, using an address in auxiliary memory and doubling its width
LoadW r , tMyAuxBitmap
LoadW r3, # (MY^XPOS I INAUX__W)
LoadB rlH,#MY_YPOS
LoadB r2,#(MY_CWIDTH*8) I DOUBLE I W
LoadB rlL, #MY__HEIGHT
jsr NewBitUp
;aux address of bitmap
; x-position + in-aux flag
;y-coordinate
/width = card width * 8 + doubling bit
/height
;put bitmap on screen
15
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Points and Lines
Points
The simplest graphic operation involves setting, clearing, or testing the state of an individual pixel,
or point, on the screen. GEOS provides two routines for working with points:
• DrawPoint
Set or clear a single point.
• TestPoint
Test a single point: is it set or clear?
Horizontal and Vertical Lines
Due to the rectangular nature of bitmapped graphics, horizontal and vertical lines are inherently fast
and easy to create and manipulate. GEOS provides five routines for working with horizontal and
vertical lines:
• HorizontalLine
Draw a horizontal line with a repeating bit pattern.
• VerticalLine
Draw a vertical line with a repeating bit pattern.
• InvertLine
Invert the pixels in a horizontal line.
♦ ImprintLine
Imprint a horizontal line to the background buffer.
• RecoverLine
Recover a horizontal line from the background buffer.
Line Patterns.
Both HorizontalLine and VerticalLine use a byte-sized bit pattern when creating the line. Each
bit in the pattem byte represents a pixel in the line: wherever a one appears in the pattern byte, the
corresponding pixel will be set, and wherever a zero appears , the corresponding pixel will be
cleared. This allows lines which vary from solid (all Ts) to dashed (a mixture of Ts and O's) to
clear (all O's). Note: this concept of a line-pattem is different from die 8x8 GEOS fill patterns used
for rectangles.
Bits in the pattem byte are used left-to-right for horizontal lines and top-to-bottom in vertical lines,
where bit 7 is at the left and the top, respectively. A bit pattem of %1111(X)(X) would create a
horizontal line like:
mmKErnjmmMjjn
and a vertical line like:
16
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
I
I
The pattern byte is always drawn as if aligned to an eight-pixel boundary. If the endpoints of a line
do not coincide with eight-pixel boundaries, then bits are masked off the appropriate ends. The
effect of this is that a pattern is always aligned to specific pixels, regardless of the endpoints and
that adjacent lines drawn in the same pattern will line up. That is, positions 0, 8, 16, 24, etc. will
always depend on pattern bit 7, and positions 1,9, 17, 25, etc. will always depend on pattern bit 6.
NOTE: Because of the internal memory layout of screen memory, horizontal lines will often
draw up to eight times faster than vertical lines.
Diagonal Lines
For the same reason that bitmap displays are well-suited for displaying horizontal and vertical
lines, they are ill-suited for displaying diagonal Hnes. A smooth, even-density line cannot be drawn
diagonally between two points (except at 45-degree angles) — the points on the line must be
approximated in a stairstep fashion:
GEOS provides one routine for drawing and recovering a line between two arbitrary points:
pT)rawLine Draw or recover a line between any two points.
DrawLine does not utilize a pattern byte; it will either set or clear all pixels between the two
endpoints.
NOTE: DrawLine is the most general-purpose drawing routine. It can be used to draw single
points (both endpoints the same), horizontal and vertical lines, or lines at arbitrary
angles. However, it is burdened by this flexibility^ making it appreciably slower than
the other plotting routines.
Patterns and Rectangles
17
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
GEOS uses two types of patterns: line patterns and fill patterns. A line pattern is a one-byte
repeating pixel pattern used by routines lUce HorizontalLine and VerticalLine, and a fill pattern
is an 8x8 pixel block represented by eight bytes in memory and used by routines like Rectangle.
Line patterns are discussed in "Points and Lines" earlier in this chapter. Fill patterns are discussed
here.
A 50% fill pattern might be defined by the following:
.byte %10101010
.byte %01010101
.byte %10101010
.byte %01010101
.byte %10101010
.byte %01010101
.byte %10101010
.byte %01010101
The pattern has alternating set and clear pixels. Drawing a filled rectangle in this pattern would
produce a medium-dark block.
All versions of the GEOS Kemal contains the following predefined patterns:
18
Graphics Routines (fourth edit / MGL)
4/24/88
8:13 PM
Apple GEOS contains an additional, user-defined pattern which is left for the application to
modify.
Fills occur in the current pattern. The current pattern can be changed with the following routine:
hSetPattern Set the current pattern.
To use one of the system patterns, the application would first call SetPattern with the appropriate
pattern number. SetPattern calculates tihe proper pattern address, the adckess of the eight-byte
19
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
block, and places it in the GEOS variable curPattern (formeriy currentPattern). Any
subsequent call to a routine which uses a system pattern will index off of the address in
curPattern to access the 8x8 block. Some applications, finding the need to define their own
patterns, modify either the address in curPattern to point to their own eight-byte pattern or use
the address in curPattern (after a valid call to SetPattern) to modify the GEOS system patterns
directly. This technique will work on both GEOS 64 and GEOS 128, but will not on Apple GEOS
because the patterns are stored in a fairly inaccessible portion of memory. Apple GEOS provides
two routines for accessing and redefing patterns:
• GetPattern
Download a GEOS pattern to an eight-byte buffer.
• SetUserPattern
Upload an eight-byte buffer to a GEOS pattern.
NOTE: GEOS does not restore the system patterns when an application exits. If an application
modifies the patterns, it should restore them when it exits unless it is desirable for the
next application to inherit the redefined patterns (as with the GEOS Pattern Editor).
Rectangles
Rectangles in GEOS are defined by their upper-left and lower-right comers. The upper-left is
usually referred to as (X1,Y1) and the lower-right as (X2,Y2), where XI, X2, Yl, and Y2 are
valid X and y screen positions. From these two coordinates, the rectangle routines can determine
the coordinates of the other two comers:
(XI, YD
{X2,Y1)
(XI, Y2)
(X2,Y2)
GEOS provides five routines for dealing with rectangular regions:
• Rectangle
Draw a solid rectangle using the current fill pattern.
♦ FrameRectangle
Draw an unfilled rectangle (bounding frame).
• InvertRectangle
Invert the pixels in a rectangular area.
• ImprintRectangle
Imprint a rectangular area to the background buffer.
• RecoverRectangle
Recover a rectangular area from the background buffer.
Bit-mapped Images
All graphic picture objects, such as icons and Photo Scrap images cut from geoPaint, are stored
internally in GEOS Compacted Bitmap Format to save space. When you paste an image or icon
into a geoProgrammer source file, it is in compacted bitmap format, and when you read a geoPaint
image, it too is in compacted bitmap format If a compacted image were to be copied direcdy to the
screen, it would very likely be unrecognizable. GEOS bitmap routines first decompact the image
and then transfer it to the screen area.
20
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Standard Bitmap Routines
All versions of GEOS support the following bitmap routines:
• BitmapUp
Place a full compacted bitmap on the screen.
• BitmapClip
Place a rectangular subset of a compacted bitmap on the screen.
• BitOtlierCIip
Special version of BitMapClip which uses an application-
defined routine to collect the compacted bitmap data a byte at a
time, allowing the image to come from disk or other I/O device.
GEOS bitmaps are compacted from the GEOS virtual screen format rather than the internal machine
format. Because the standard bitmap routines deal with byte-sized chunks (eight-pixels at a time),
the following apply:
♦ Horizontally, the bitmap occupies pixels up to the nearest eight-pixel (byte) boundary.
That is: a bitmap of five pixels is extended to eight and a bitmap of 30 pixels is extended to
32 pixels. Bitmaps which are not evenly divisable by eight (in the horizontal direction) are
usually padded with zero bits.
• Bitmaps can only be placed at eight-pixel intervals on the x-axis (0, 8, 16...). This
limitation does not apply to the y-axis.
Apple GEOS, however, provides two extended bitmap routines for overcoming these limitations.
These routines might eventually be incorporated into GEOS 64 and GEOS 128.
Apple GEOS Extended Bitmap Routines
The Apple GEOS extended bitmap routines allow bitmaps of any pixel width and do not force the
bitmap to be drawn on eight-pixel x-axis boundaries. These bitmaps are still compacted in byte-
sized chunks, but by specifying a pixel width, any extra bits at the end of the last byte are ignored
(masked out) when the bitmap is displayed. Apple GEOS offers three new bitmap routines:
• NewBitUp
Pixel width and positioning version of BitmapUp.
• NewBitCIip
Pixel width and positioning version of BitmapClip.
• NewBitOtherClip
Pixel width and positioning version of BitOtherClip.
GEOS Compacted Bitmap Format
The GEOS compacted bitmap format relies on the observation that pixel patterns in bitmap images
are frequently repetitive. If you were to examine a rectangular area of the screen (in GEOS linear
bitmap format) it would often be the case that adjacent bytes would be identical. The compacted
bitmap format encodes this redundancy into groups of bytes called packets. Each packet can
decompress to a large number of bytes in the actual bitmap.
21
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Packet Format
Each packet in a GEOS compacted bitmap follows a specific foraiat. The first byte of each packet
is called the count byte and is part of the packet header. Depending on its value, it has the
following significance:
COUNT
(HEX)
SIGNIFICANCE
($00)
reserved for future use.
1-127
($00-$7f)
repeat: repeat the following byte count times. The total length of
this packet is two bytes and decompresses to count bytes in the
actual bitmap.
128
($80)
reserved for future use.
129-219
($81-$db)
unique: use the next count-128 bytes literally. The total length
of this packet is (count-128)+l or count-127 bytes and
decompresses to count-128 bytes.
220
($dc)
reserved for future use.
221-255
($dd-$ff)
bigcount: the next byte is a bigcount value in the range 2
through 255. The following count-220 bytes comprise data in
repeat and unique format that should be repeated bigcount
times. The total length of this packet depends on the decompacted
size of tht.repeat and unique packets. A bigcount cannot
containt another bigcount.
Decompaction Walkthrough
Given the following compacted data:
.byte 25, 0, 133, 240, 220, 10, 0, 7, 224, 4, 3, 10, 5, 3
The decompaction routine would interpret it like this:
repeat: the decompaction routine encounters the count value 25. Since it is in the range
1-127, the following byte (0), is repeated 25 times:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133, 240, 220, 10, 0, 7"!
unique: the next packet begins with a count of 133,which is in the range 129-219, The
next 133-128 = 4 bytes are used once each:
240, 220, 10, 0, 7
1224, 4, 3, 10, 5, 3 |
bigcount: the final packet begins with a count of 24 which is in the range 221-255.
This signals a two byte header and the following byte, the bigcount, is 4. These two
bytes are interpreted to mean repeat the next 224-220 = 4 bytes four times. The next four
bytes, however, are expected to be in the unique and repeat compacted formats. In this
case, its 3,10 (repeat: 10 three times) and 5,3 (repeat: 3 five times), which in turn are
repeated four times:
22
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
10, 10, 10 ,3, 3, 3, 3, 3, 10, 10, 10 ,3, 3, 3, 3, 3, 10, 10, 10 ,3, 3, 3, 3, 3, 10,
10, 10 ,3, 3, 3, 3, 3
Compacting Strategy
The easiest way to compact a bitmap image is to let geoPaint do it for you by cutting the image out
as a photo scrap and pasting it directly into your geoProgrammer source code. Sometimes this
method is impractical and you will want to compress images directly from within an application.
The following subroutine can be used to compact bitmap data:
.if (0)
*»««**«***★**«**««********★***★***«★********«**«***«*
BitCompact
«*««*■««*★*★★*«****»*********«★★*★**★«*★***★★★*****
DESCRIPTION:
Converts linear bitmap data into compacted bitmap format, suitable
for passing to routines such as BitmapDp.
When compacting bitmaps directly from screen memory, the data must
must first be converted from the internal screen format to linear
bitmap format. The left edge of the source bitmap must start on a
card boundary and the right edge must extend to the end of another,....-^ . ^
card boundary. (Under Apple GEOS, strictly speaking, the wrg^^t "Cdge^ need
not fully extend to a card boundary because the new bitmap routines
(NewBitUp, NewBitClip, etc.) can mask bits at the right edge.)
This bitmap data must then be converted to a linear format, where
the first byte represents the first eight pixels of the upper-left
corner of the bitmap, the next byte represents the next eight pixels
and so on to the right edge of the bitmap. The byte following the
last byte in a single line of a bitmap is the first byte of the next
line. (The actual dimensions of the bitmap will be reconstructed from
the WIDTH and HEIGHT parameters passed to the bitmap display routine.
To convert from internal screen format to linear bitmap format:
C64: Set dispBufferOn appropriately (to reflect which
screen buffer to grap data from) and...
(
7
Cnvrt40:
Idx
yPos
; get y coord of top of bitmap
jsr
GetScanLine
; use it to calc screen ptrs
Ida
xPos
; get x pixel coord (lo byte)
and
#%11111000
; strip off 3 bits for card x-position
clc
; Add card offset to
adc
r5L
; base pointer (lo byte first)
sta
r5L
Ida
xPos+1
; (hi byte also)
adc
r5H
sta
r5H
;At
this point, (r5)
points to the first byte in
;the
bitmap (upper-left corner) .
Now step through each byte in this scanline by adding
8 to the pointer in r5 (compensating for the card architecture)
to get to the next byte, and repeat this process for each line
in the bitmap (incrementing yPos appropriately for each scanline) ,
C128: (40-column, same as C64; 80-column, read on...)
Conveniently, the 80-column data is already in linear bitmap
23
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
format. The data, will probably be coming from the
background buffer because the foreground screen is
entirely contained on the VDC chip's internal RAM and
is difficult to access...
CnvrtSO:
bit graphicsMode
bpl Cnvrt4
PushB dispBufferOn
LoadB dispBufferOn, #ST_WR
Idx yPos
jsr GetScanLine
Movew xPos,rO
Idx #rO
Idy #3
jsr DShiftRight
AddW r0,r6
;At this point (r6) points
/bitmap.
; make sure in 80-col mode
; handle 40 like C64
; save current dispBuffer
BACK /force use of back buffer
get y coordinate
use it to calc screen ptrs
copy x-position to zp work reg
divide rO by 8
(shift right 3 times)
this gives us the card offset
add card (byte) offset to scanline addr
to the first byte of the
Now step each byte in this scanline by adding
1 to the pointer in r6 to get to the next byte,
and repeat this process for each line in the
bitmap (incrementing yPos appropriately) .
Apple: Use the Apple GEOS Kernal routines ReadScanLine
and ReadBackLine to convert the internal Apple
screen format into linear bitmap format. Nice and simple.
CALLED BY:
PASSED:
rO Pointer to destination buffer to store compacted data
(this buffer must be at least 1 and 1/64 of size of the
uncompacted data because it is possible, but unlikely, that
the compacted data will actually be larger than the ucompacted
data) .
rl Pointer to linear bitmap data to compact.
r2 # of bytes to compact.
RETURNS :
rO Points to byte following last byte in compacted data.
DESTROYED:
a, X, y, rl-r6
PSEUDO CODE / STRATEGY:
Starts with the first source byte and counts the number of identical bytes
following it to determine whether to generate a UNIQUE or REPEAT packet. If
there are three or less identical bytes in a row, a UNIQUE packet is generated,
four or more generates a REPEAT packet. The packet is placed in the destination
buffer and this process is then repeated until all bytes in the source buffer
have been compressed.
KNOWN BUGS / SIDE EFFECTS / IDEAS:
Only uses the UNIQUE and REPEAT compaction types. The BIGCOUNT compaction type is
such that it is difficult to determine the compaction payoff point. BIGCOUNT could
be used to compress adjacent scanlines that are identical because this type of check
would be trivial. The basic scanline could be compressed with UNIQUE and REPEAT, then
duplicated by placing it inside a BIGCOUNT.
This routine is not limited to compressing bitmap data. In fact, it works quite
24
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
well on any data where strings of identical bytes are common (e.g., fonts). It does
not, for example, compress text very efficiently. A Huffman-based algorithm yields
better results.
ir*********
t * * * 'k te ic * * it -i
(mgl)
.endif
MAX__R£?£AT
MAXJJNIQUE
UNIQ THRESH
127
91
3
maximum repeat COUNT value
maximum unique COUNT value
byte count threshold, beyond which a REPEAT type
should be used instead of UNIQUE.
BitCompact :
10$:
jsr
cmp
ble
sta
Idy
sta
Ida
iny
sta
AddVW
bra
20$:
jsr
Idy
ora
sta
Ida
iny
sta
cpy
bne
inc
AddBW
dec
30$:
100$:
AddBW
SubBW
Ida
ora
bne
rts
CountRepeat
#UNIQ_THRESH
20$
r5L
#0
(rO) .
(rl) ,
(rO),y
#2,r0
100$
GetUnique
#0
#$80
(rO) ,y
(rl) ,y
(rO),y
r5L
30$
r5L
r5L, rO
rSL
r5L,rl
r5L,r2
r2L
r2H
10$
rl = current addr in source buffer
rO = current addr in destination buffer
r2 = # bytes left in source
count the # of identical bytes here
Enough repeats to justify REPEAT type?
No, go use UNIQUE
yes, use REPEAT (A = # to repeat)
store repeat # for later
init. index into buffers
store repeat # to destination
get repeat value
point to next byte in dest buffer
store to destination buffer
move up dest . pointer
exit.
use UNIQUE
Calc # of unique bytes to use
(A = number of unique)
init. index into buffers.
convert unique count to packet count value
store to dest. buffer
get first unique value
increment pointer pointer
store to destination buffer
done yet? (r5L « repeat #)
loop till done copying
convert to # to add to dest pointer
move up destination pointer
correct bac)c to # done
fall through to -exit
move up source pointer
subtract off # left in source buffer
check for zero bytes left
more to do?
if so, loop
else, exit.
CountRepeat :
Idy
Idx
#0
#0
rl « current pointer into source buffer
rO = current pointer into destination buffer
r2 « number of bytes left in source
initialize relative buffer index
initalize current repeat count
25
Graphics Routines (fourtli edit / MGL)
4/24/88 8:13 PM
Ida
(rl),y
get first byte
sta
r6L
keep in r6L. This is the byte we're trying
to match.
10$:
Ida
r2H
more than 255 bytes left in source?
bne
20$
if so, ignore # check
cpx
r2L
else, are we at the last byte?
beq
90$
if so, exit
20$:
cpx
#MAX__REPEAT
check repeat count with max # of repeats
beq
90$
if at maximum, branch to exit.
Ida
(rl),y
does it actually match?
cmp
r6L
check against 1st byte
bne
90$
if no match, exit.
inx
else, we found a match, increment repeat count
iny
move to next byte in source
;NOTE
— following branch changed to
save a byte, y is never incremented to $00.
bra
10$
and loop to check it
bne
10$ ,
branch always... iny above will always clear z
90$:
txa
return repeat count in A
rts
exit
GetUnique:
PushW
rl
Save orig pointer
LoadB
r5L,#0
start none unique
10$:
inc
r5L
• do one more unique
Idx
r5L
• get # unique so far
Ida
r2H
• lots left?
bne
20$
• if so, skip end check
cpx
r2L
• all of them?
beq
90$
• if yes, then that many
20$:
cpx
#MAX_UNIQUE
? max # unique
beq
90$
? if full, do them
AddVW
#l,rl
; move up a byte
jsr
CountRepeat
; how many of the following bytes are repeats?
cmp
#UNIQ THRESH
? Enough to warrant a REPEAT packet?
ble
10$
; No, go stuff them in this UNIQUE packet
; Yes, close this UNIQUE packet.
90$:
PopW
rl
; retrieve start pointer
Ida
r5L
; get # to do unique
rts
Direct Screen Access and Block Copying
Direct Screen Access
One purpose of an operating system such as GEOS is to insulate the application from the
peculiarities of the machine it is running on, allowing the programmer to worry more abot how the
application will function than how it will interact with the hardware. However, because of the
complexity of GEOS graphics routines, it is sometimes necessary, for performance reasons, to
bypass the operating system and manipulate the screen memory directly. Although this practice is
not recommended — it increases portability problems, defeating much of the purpose of a GEOS
26
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
— it is a reality. And with that in mind, Berkeley Softworks built routines into GEOS to facilitate
direct screen access. The following routine exists in all versions of the Kemal:
I • GetScanLine Calculate the address of the first byte of a particular screen line.
And these two additional routines exist in Apple GEOS:
• GetScreenLine
Copy a horizontal line (in internal format) from the screen to an
application's buffer.
• PutScreenLine
Copy a horizontal line (in internal format) from an application's
buffer to the screen.
GetScreenLine and PutScreenLine are intended to let the application directly access the Apple
double hi-res screen without worrying about bank switching on alternate bytes. The screen is
treated as a contiguous block, as if the alternating bytes in the two memory banks were actually
adjacent in memory. These routines are not well-suited for scrolling large regions (they are too
slow), but are sufficient for drawing with small brushes. For scrolling, use the block copy
routines.
Linear Bitmap Conversion (Apple GEOS)
Because the Apple's pixel memory mapping scheme is so convoluted, Apple GEOS provides
routines to convert a line of data (in Apple's internal format) to linear bitmap data, where pixels
occupy contiguous bits in contiguous bytes:
• ReadScanline
Translates a screen line from the foregorund screen from Apple
internal format to linear bitmap format.
• ReacBackLine
Translates a screen line from the background buffer from Apple
internal format to linear bitmap format.
Although it would seem that routines which translate in the other direction — from linear bitmap
format to Apple format — are necessary, BitmapUp can be used for this purpose. Merely
prepend a 70 to the front of the linear bitmap and call BitmapUp as if the line were a bitmap 70
bytes wide and one pixel high.
Block Copy and Scrolling (Apple GEOS)
Apple GEOS also extends the direct screen access facilities by offering three block copy routines
which are useful for scrolling and moving rectangular areas of the screen:
• CopyLine Copies a horizontal line from one area of the foreground screen to
another.
"^opyScreenBlock Copies a rectangular area from one part of the screen to another.
♦ CopyFuIIScreen Copies a rectangle of the full width of the screen (but of variable
height) to another position vertically.
Although these routines deal directly with the screen, the screen architecture is actually transparent
to the application. Therefore, future versions of GEOS may implement these functions.
27
Graphics Routines (fourth edit / MGL)
4/24/88 8:13 PM
Special Graphics Related Routines
GEOS provides a few graphics-related routines which don't fit nicely into any other category:
• GraphicsString
Execute a string of graphics commands.
• DivideBySeven
Quickly divide a screen coordinate by seven for direct screen
access (Apple GEOS only).
• NormalizeX
Adjust an x-coordinate (under GEOS 128 only) to compensate for
the higher-resolution 80-column mode.
• SetNewMode
Change GEOS 128 graphics mode (40/80-column).
28
Icons, Menus, and Other Mouse Presses
Icons, Menus, and Other Mouse Presses
When the user clicks the mouse button, GEOS determines whether the mouse pointer was
positioned over an icon, a menu item, or some other region of the screen. GEOS has a unique
method of handling a mouse press for each of these cases. If the user pressed on an icon, GEOS
calls the appropriate icon event routine. If the user pressed on a menu, GEOS opens up a sub-
menu or calls the appropriate menu event routine, whichever is applicable. And if the user pressed
somewhere else, GEOS calls through otherPressVector, letting the application handle (or
ignore) these "other" mouse presses.
Icons
When you open a disk by clicking on its picture, delete a file by dragging it to the trash can, or
click on the CANCEL button in a dialog box, you are dealing with iconSy small pictorial
representations of program functions. A GEOS icon is a bitmapped image, whether the picture of a
disk or a button-shaped rectangle, that allows the user to interact with the application. When the
application enables icons, GEOS draws them to the screen and then keeps track of their positions.
When the user clicks on an icon, an icon event is generated, and the application is given control
with information concerning which icon was selected
Icon Table Structure
The information for all active screen icons is stored in a data structure called the icon table. GEOS
only deals with one icon table at a time. The icon table consists of an icon table header and a
number of icon entries. The whole table is stored sequentially in memory with the header first,
followed by the individual icon entries.
Icon Table Header
The icon table header is a four byte structure which tells GEOS how many icons to expect in the
structure and where to position the mouse when the icons are enabled. It is in the following format:
Icon Table Header:
Index
Constant
Size
Descriptibn
+0
OFF_LNUM
byte
Total number of icons in this table.
+1
OFFJ.MX
wad
Initial mouse x-posidon. If $0000, mouse positiion will not
be altered
+3
OFF_I_MY
byte
Initial mouse y-position.
This first byte reflects the number of icon entries in the icon table (and, hence, the number of icons
that can be displayed). The table can specify up to MAX_ICONS icons.
The next word (bytes 1 and 2) is an absolute screen x-coordinate and the following byte (byte 3) is
an absolute screen y-coordinate. The mouse will be positioned to this coordinate when the icons
are first displayed. If you do not want the mouse positioned, set the x-coordinate word to $0000,
which will signal Dolcons to leave the mouse positions alone.
1
IconSp Menus, and Other Mouse Presses
Icon Entries
Following the icon table header are the icon entries, one for each specified in the OFF_I_NUM
byte in the icon table header. Each icon entry is a seven-byte structure in the following format:
Icon Entries:
Index
Constant
Size
Description
+0
OFFJ.PIC
wod
Pointer to compacted bitmap picture data for this icon. If set
to $0000, icon is disabled.
+2
OFF I X
byte
Card x-position for icon bitmap.
+3
OFF I Y
byte
Y-position of icon bitmap.
+4
OFF I WIDTH
byte
Card width of icon bitmap.
+5
OFF I HEIGHT
byte
Pixel height of icon biunap.
+6
OFFJ EVENT
wad
Pointer to icon event routine to call if this icon is selected.
The first word (OFF I PIC) is a pointer to the compacted bitmap data for the icon. The icon can
be of any size (up tolhe full size of the screen). If this word is set to NULL ($0(X)0), the icon is
disabled.
The third byte (OFF I X) is the x byte-position of the icon. The x byte-position is the x-position
in bytes — icons are"pTaced on the screen by BitmapUp and so must appear on an eight-pixel
boundary. The byte-position can be calculated by dividing the pixel-position by eight
(x_byte_position = x.pixeLposition/8).
The fourth byte (OFF_I Y) is the pixel position of the top of the icon. The icon will be placed at
(x_byte_position*8 , y_pixeLposition).
The next two bytes (OFF J^WIDTH and OFF J_.HEIGHT) are the width in bytes and height
in pixels, respectively. These values correspond to the geoProgrammer internal variables PicW
and PicH when they are assigned immediately after a pasted icon image.
The final word (OFF_I_EVENT) is the address of the icon event handler associated with this
icon.
Sample Icon Table
The following data block defines three icons which are placed near the middle of the screen. The
mouse is positioned over the first icon:
/SAMPLE ICON TABLE
**********************************************
;Icon positions and bitmap data
I__SPACE - 1 /space between our icons (in cards)
Paint Icon:
PAINTW - PicW
Icons, Menus, and Other Mouse Presses
PAINTH » PicH
PAINTX = 16/8
PAINTY « 80
Writelcon :
WRITEW = PicW
WRITER = PicH
WRITEX " PAINTX + PAINTW + I_SPACE
WRITEY = PAINTY
Publishlcon :
PUBLISHW
PUBLISHH
PUBLISHX
PUBLISHY
PicW
PicH
WRITEX + WRITEW + I__SPACE
WRITEY
;The actual icon data structure to pass to Dolcons follows
IconTable:
I_header :
.byte
.word
.byte
NUMOFICONS
(PAINTX*8) + (PAINTW*8/2)
PAINTY + PAINTH/2
number of icon entries
position mouse over paint icon
I_entries:
PaintlStruct :
.word Paintlcon
.byte
.byte
.word
PAINTX, PAINTY
PAINTW, PAINTH
PaintEvent
; pointer to bitmap
;icon position
;icon width, height
/event handler
WritelStruct :
.word Writelcon
.byte
.byte
WRITEX, WRITEY
WRITEW, WRITER
.word WriteEvent
/pointer to bitmap
/icon position
/icon width, height
/event handler
PublishlStruct :
.word Publishlcon
.byte PUBLISHX, PUBLISHY
.byte PUBLISHW, PUBLISHH
.word PublishEvent
NUMOFICONS
(*-I_entries) /lESIZE
/pointer to bitmap
/icon position
/icon width, height
/event handler
/number of icons in table
/Dummy icon event routines which do nothing but return
V PaintEvent:
^'"^ WriteEvent :
3
Icons, Menus, and Other Mouse Presses
PublishEvent :
rts
Installing Icons
When an application is first loaded, GEOS will not have an active icon structure. GEOS must be
given the address of tiie applications icon table before MainLoop can display and track the user's
interaction with them. GEOS provides one routine for installing icons
I • Dolcons Display and activate an icon table. |
Dolcons draws the enabled icons and instructs MainLoop to begin watching for a single- or
double-click on one. The icon table stays activated and enabled until the ICONS_ON_BIT of
mouseOn is cleared or another icon table is installed by calling Dolcons with the address of a
different icon structure. In either case, the old icons are not erased from the screen by GEOS.
Dolcons will draw to the foreground screen and background buffer depending on the value of
dispBufferOn. Icons are usually permanent structures in a display and so often warrant being
drawn to both screens. If icons are only drawn to the foreground screen, they will not be recovered
after a menu or dialog box.
Example:
; IconsUp Draw and intialize our icons
•*★**★★**★****★★***★*******★**★*★*****★★**★*★***★★★*★*★*★*★*★
IconsUp:
LoadB dispBufferOn, #(ST_WR_FORE I ST_WR_BACK) ;draw to both buffei;s
LoadW rO, #IconTable ;point to icon table
jsr Dolcons /install icons
rts ;exit
Important: Due to a limitation in the icon-scanning code, the application must always install an
icon table with at least one icon. If the application is not using icons, create a
dummy icon table with one icon (see below).
Nolcons Install a dummy icon table. For use in applications that
aren't using icons. Call early in the initialization of the
application, before returning to MainLoop.
Nolcons:
LoadW rO,#DummyIconTable /point to dummy icon table
jmp Dolcons /install. Let Dolcons rts
DummylconTabie :
.byte 1 ;one icon
.word $0000 /dummy mouse x (don't reposition)
•byte $00 /dummy mouse y
.word $0000 /bitmap pointer to $0000 (disabled)
.byte $00 /dummy x-pos
4
Icons, Menus, and Other Mouse Presses
.byte $00 /dummy y-pos
.byte 1,1 /dummy width and height
.word $0000 /dummy event handler
MainLoop and Icon Event Handlers
When the user clicks the mouse button on an active icon, GEOS MainLoop will recognize this as
an icon event and call the icon event handler associated with the particular icon. The icon event
handler is given control with the number of the icon in rOL (the icon number is based on the
icon^s position in the table: the first icon is icon 0). Before the event handler is called, though,
MainLoop might flash or invert the icon depending on which of the following values is in
iconSelFlag:
Constants for iconSelFlag:
ST NOTHING
The icon event handler is immediately called; the icon image is untouched.
ST.FLASH
The icon ijs inverted for selectionFlash vblanks and then reverted to its
nonnal state before the event handler is called.
ST_INVERT
The icon is inverted (foreground screen image only) before the event handler is
called. The event handler will usually want to revert the image before returning
to MainLoop by calculating the bounding rectangle of the icon, loading
dispBufferOn with ST^WILJFORE, and calling InvertRectangle.
Detecting Single- and Double-clicks on Icons
When the user first clicks on an icon, GEOS loads the global variable dblCIickCount with the
GEOS constant CLICK^GOUNT, GEOS then calls the icon event handler with rOH set to
FALSE, indicating a single-click. dblClickCount is decremented at interrupt level every vblank.
If the icon event handler returns to MainLoop and the the user again clicks on the icon before
dblClickCount reaches zero, GEOS calls the icon event handler a second time with rOH set to
TRUE to indicate a double-click.
Checking for a double-click or a single-click (but not both) on a particular icon is trivial: merely
check rOH. If rOH is TRUE when you're looking for a single-click or its FALSE when you're
looking for a double-click, then return to MainLoop immediately. Otherwise, process the click
appropriately. This way, tS the user single-clicks on an icon which requires double-clicking or
double-clicks on an icon which requires single-clicking, the event will be ignored
However, checking for both a double- or a single-click on the same icon (and performing different
actions) is a bit more complicated because of the way double-clicks are processed: during the brief
interval between the first and second clicks of a double-click, the icon event handler will be called
with rOH set to FALSE, which will appear as a single-click; when the second press happens
before dblClickCount hits zero, the icon event handler is called a second time with rOH set to
TRUE, which will appear as a double-click. There is no simple way (using the GEOS double-
click facility) to distinguish a single-click which is part of a double-click from a single-click which
stands alone
There are two reliable ways to handle single- and double-click actions on icons: the additive
function method and the polled mouse method. The additive function method relies on a simple
single-click event which toggles some state in the application and a double-click event (usually
more complicated) which happens in addition to the single-click event. The GEOS dcskTop uses
tiie additive function method for selecting (inverting) file icons on a single-click and selecting and
opening them on a double-click. The icon event handler first checks the state of rOH. If it is
5
Icons, Menus, and Other Mouse Presses
FALSE (single-click) then the icon (and an associated selection flag) is inverted. If it is TRUE
(double-click) then the file is opened. If the user single-clicks, the icon is merely inverted. If the
user double-clicks, the icon is inverted (on the first click) and then processed as opened (on the
second click).
Example:
Icon double-click handler
additive function method
**«★*★********★******★*★★**★★★★*★**★*★*«★***★**★★*★★*
IconEventl:
Ida rOH ; check double-click flag
bne 10$ /branch if second click of a double-click
;else, this is a single-click or the
; first: push of a double-click,
; ;so just invert the selection
;and exit.
10$:
90$:
jsr Invertlcon
bra 90$
jsr Open Icon
rts
/double-click detected, go process it
;fall through to exit
/return to MainLoop
The polled-mouse method can be used when the single-click and double-click functions are
mutually exclusive. When a single-click is detected the icon event handler, rather than returning to
MainLoop and letting GEOS manage the double-click, handles it manually by loading
dblCIickCount with a delay and watching mouseData for a release followed by a second click.
Example: *
*********************************************** ****:«r«««**************
Icon double-click handler .
polled mouse method
** it** *ic ********** it It-it itir* it *it*it*****ik*irit***icitii*ic*
IconEvent2 :
;User pressed mouse once, start double-click counter going
LoadB dblClickCount,#CLICK_COUNT /start delay
/Loop until double-click counter times-out or button is released
10$:
Ida dblClickCount /check double-click timer
beq 30$ /If timed-out, no double-click
Ida mouseData /Else, check for release
bpl 10$ /loop until released
/mouse was released, loop until double-click counter times-out or
/button is pressed a second time.
20$:
Ida dblClickCount /check double-click timer
beq 30$ /If timed-out, no double-click
Ida mouseData ./Else, check for second press
bmi 20$ /loop iinril pressed
/.Double-click detected (no single-click)
.'30$i- jsr DoDoubleClick /do double-click stuff
• bra 90$ /exit
/Single-click detected (no double-click)
Icons, Menus, and Other Mouse Presses
jsr DoSingleClick ;do single-click stuff
;and fall through to exit
/Exit
90$: rts /return to MainLoop -
Note: These techniques for handling single- and double-clicks are described here as they
pertain to icons; they are not directly applicable to applications that detect mouse clicks
through otherPressVector. When control vectors through otherPressVector, the
value in rOH is meaningless. For more information on otherPressVector, refer to
"Other Mouse Presses" in this chapter.
Other Things to Know About Icons
Icon Releases and otherPressVector
When the user clicks on an active icon, MainLoop will call the proper icon event routine rather
than vectoring through otherPressVector. However, the routine pointed to by
OtherPressVector will get called when the mouse is released. Applications that aren*t using
OtherPressVector can disable this vectoring by storing a. $0000 into otherPressVector
($0000 is actually its default value). Applications that depend on otherPressVector, however,
can check mouseData and ignore all releases.
Example:
/OtherPressVector routine that ignores releases (high bit of mouseData is set on releases)
MyOtherPress: /control comes here from otherPressVector
Ida mouseData /check state of the mouse button
bmi 90$ /ignore it if it's a release
jsr PressDown /otherwise process the press'
90$:
rts /return to MainLoop
For more information on otherPressVector, refer to "Other Mouse Presses" in this chapter.
Icon Precedence
GEOS draws icons sequentially. Therefore, if icons overlap, the ones which are drawn later will
be drawn on top. When the user clicks somewhere on the screen, GEOS scans the icon table in this
same order, looking for an icon whose rectangular boundaries enclose the coordinates of the
mouse pointer. If more than one icon occupies the coordinate position, the icon that is defined first
in the icon table (and therefore drawn on bottom) will be given the icon event. If an active menu
and an icon overlap, the menu will always be given precedence.
Disabling Icons
An application can disable an icon in the current icon structure by clearing the OFF_PIC ICON
word of tiie icon (setting it to $(X)00). If an icon is disabled prior to a call to Dolcons, the icon
will not be drawn. If an icon is disabled after the call to Dolcons, the icon will remain on die
screen but will be ignored during the icon scan. The application can reenable the icon by restoring
the OFF_PIC^ICON word to its original value. (Actually, any non-zero value will do because
reenabling an Icon does not redraw it, it only restores the coordinates to MainLoop's active
search list.)
7
Icons, Menus, and Other Mouse Presses
GEOS 128 Icon Doubling
as with bitmaps, special flags in the icon data structure can be set to automatically double the x-
position and/or icon width when GEOS 128 is running in 80-column mode. To have an an icon's
x-position automatically doubled in 80-column mode, bitwise-or the OFF_I X parameter with
DOUBLE^B. To double an icon*s width in 80-colunin mode, bitwise-or the^OFFJ^WIDTH
parameter with DOUBLE_B. These bits will be ignormed when GEOS 128 is running in 40-
column mode. Do not, however, use these doubling bits when running under GEOS 64. GEOS 64
will try to treat the doubling bit as part of the coordinate or width value rather than a special-case
flag. For more information, refer to "GEOS 128 X-position and Bitmap Doubling" in Chapter
@GR@.
Example:
/SAMPLE GEOS 128 ICON TABLE THAT USES AUTOMATIC DOUBLING FEATURE
.if !C128
.echo Error: cannot assemble GEOS 128 specific code without C128 flag set
.else
Paintlcon:
PAINTW = PicW
PAINTH •= PicH
PAINTX » 16/8
PAINTY « 80
;The actual icon data structure to pass to Dolcons follows
IconTable:
I_header :
.byte NUMOFICONS
.word ((PAINTX*8) + (PAINTW*8/2) ) I DOUBLE^W)
.byte PAINTY + PAINTH/2
number of icon entries
position mouse over paint icon
I__entries:
PaintlStruct :
.word Paintlcon
.byte (PAINTX I DOUBLE_B)
.byte PAINTY
.byte (PAINTW | DOUBLE_B)
.byte PAINTH
.word PaintEvent
/pointer to bitmap
;x card position (dbl in 80-column mode)
;y-position
;icon width (dbl in 80-column mode)
;icon height
/event handler
NUMOFICONS
(*-I_entries)/IESIZE
/number of icons in table
/Dummy icon event routines which do nothing but return
PaintEvent:
rts
.endif
8
Icons, Menus, and Other Mouse Presses
Apple GEOS Double-width and Aux-memory Icons
As with Apple GEOS bitmaps, special flags can be set in the icon data structure to double an icon's
width and/or lcx)k for the icon image data in auxiliary memory. To double an icon's width, bitwise-
or the OFF_I_^WIDTH parameter with DOUBLE B. To mark the OFF I PIC word as an
address in auxiliary memory, bitwise-or the OFF_r_X parameter with INaTIX_B. For more
information, refer to "Apple Bitmap Doubling and Aux^emory Bitmaps" in Chapter @GR@.
Menus
Menus, one of the most common and powerful user-interface facilities provided by GEOS, allow
the application to offer lists of items and options to the user. The familiar menus of the GEOS
deskTop, for example, provide options for selecting desk accessories, manipulating files, copying
disks, and opening applications. Virtually every GEOS-based program will take advantage of these
capabilities, providing a consistent interface across applications.
GEOS menus come in two flavors: horizontal and vertical. The main menu, the menu which is
always displayed, is usually of the horizontal type and is typically placed at the top of the screen.
Each selection in the main menu usually has a corresponding vertical sub-menu that opens up when
an item in the main menu is chosen. These sub-menus can contain items that trigger the application
to perform some action. They can also lead to further levels of sub-menus. For example, a
horizontal main menu item can open up to a vertical menu, which can have items which then open
up other horizontal sub-menus, which can then lead to other vertical menus, and so on.
Division of Labor with Menus
GEOS divides the labor of handling menus between itself and the application. The GEOS Kemal
handles all of the user's interaction with the menus. This includes drawing the menu items,
opening up necessary sub-menus, and restoring the Screen area from the background buffer when
the menus are retracted. MainLoop manages the menus, keeping track of which items the user
selects. If the user moves off of the menu area without making a selection, GEOS automatically
retracts the menus without alerting the application.
If the user selects a menu item which generates a menu event, the application's menu event handler
is called with the menus left open. Leaving the menus open allows the application to choose when
and how to retract them: all the way back to the main menu, up one or more levels (for multiple
sub-menus), or up no levels (keeping the current menu open). This lets the application choose the
menu level which is given control upon return, thereby allowing multiple selections from a sub-
menu without forcing the user to repeatedly traverse the full menu tree for each option.
Menu Data Structure
The main menu, all its sub-menus, their individual selectable items, and various attributes
associated with each menu and each item are all stored in a hierarchical data structure called the
menu tree. Conceptually, a menu tree with multiple sub-menus might have the following layout:
9
icons, Menus, and Other Mouse Presses
sub-menu
Level
gill Level 1
Level 2
Level 3
Sample Menu Tree
The main menu (or level 0) is the first element in the tree; it is the menu that is always displayed
while menus are enabled. Each item in a main menu will usually point to a secondary menu or
submenu. Items in these submenus can point to events (alerts to Ae application that an item was
selected) or they can point to additional submenus. Menus are linked together by address pointers.
Sub-menus are sometimes referred to as child menus, and the menu which spawned the sub-menu
as its parent. Sub-menus can be nested to a depth determined by the GEOS constant
MAX_M NESTEVG, which reflects the internal variable space allocated to menus. The depth or
level of tEe current menu can be determined by the GEOS variable menuNumber, which can
range from to (MAX^M^NESTING- 1).
In memory, all menus, whether the main menu or its children, are stored in the same basic menu
structure format Each menu is comprised of a single menu header block followed by a number of
menu item blocks (one for each selectable item in the menu):
10
Icons, Menus, and Other Mouse Presses
menu
Menu/Sub-menu structure
Menu/Sub-menu Header
The menu header is a seven-byte structure that specifies the size and location of the menu (How big
is the rectangle that suirounds the menu and where should the menu be drawn?), any attributes that
affect the entire menu (Is it a vertical or horizontal menu?), and the number of selectable items in
the menu. The header is in the following format:
Menu/Sub-menu Table Header:
Index
Constant
Size
Description
+0
OFF M Y TOP
byte
Top edge of menu rectangle (yl pixel position).
+1
OFF M Y BOT
byte
Bottom edge of menu rectangle (yl pixel position).
+2
OFF M X LEFT
wad
Left edge of menu rectangle (xl pixel position).
+4
OFF_M_X_RIGHT
wcxd
Right edge of menu rectangle (x2 pixel position).
+6
OFF^NUM^M.ITEMS
byte
Menu type bitwise-or*ed with number of items in this
menu/sub-menu.
The first six bytes specify the screen location and size of the menu with the positions of the
bounding rectangle in pixel positions. The x-positions are word (two-byte) vdues and the y-
positions are byte values These values are absolute screen pixel positions. The size of die bounding
rectangle depends on the number of menu items and the size of text strings within the toenu. The
height of the rectangle can be calculated with the constant M^HEIGHT: a horizontal menu is
always a height of M HEIGHT, and a vertical menu is a height of the number of menu items
multiplied by M HEIGHT. For example, the height of a vertical menu with seven items would
be 7*M_HEIGITT. The width of a menu is more difficult to calculate because it depends on the
1 1
Icons, Menus, and Other Mouse Presses
length of the individual text strings. It is best to use a large number for this dimension and adjust it
to a smaller size if necessary.
Important: GEOS 64 and GEOS 128 before version 2.0 do not correctly handle menus that
extend beyond an x-position of 255. This problem does not exist in Apple GEOS.
All menus and sub-menus are positioned independently. This means that the main menu need not
be at the top of the screen (it can be inside a window, for example), and sub-menus need not be
adjacent to their parent menus (although that is where you will usually want them). You can
experiment with the flexibility of menu positioning to customize your applications.
The seventh byte is the attribute byte. It is the number of selectable items in the menu bitwise-or'ed
with any menu type flags. A menu can have as many as MAX_M_ITEMS selectable menu
items.
Menu/Sub-menu Types (use in attribute byte):
Constant
Description
HORIZONTAL
Arrange menu items in this menu/sub-menu horizontally.
VERTICAL
Arrange menu items in this menu/sub-menu vertically.
CONSTRAINED
Constrain the mouse to the menu/sub-menu. If the menu is a sub-menu, the
mouse can still be moved off to the parent menu (off the top of a vertical sub-
menu or off the left of a horizontal menu).
UN.CONSTRAINED
Do not constrain the mouse to the menu/sub-menu. If the user moves off of
the menu, GEOS will retract it
Bitwise Breakdown of the Attribute Byte:
7 6 5 4
3 2 1
b7 b6 1
b5-bO 1
b7 orientation: 1= vertical; = horizontal,
b6 constrained: 1 = yes; = no.
b5-bO number of items in menu/sub-menu (up to MAX_M_ITEMS).
Some of the menu types are obviously mutually exclusive: you can't, for example, make a menu
both vertical and horizontal, nor simultaneously constrained and unconstrained.
A vertical, unconstrained menu with seven selectable items would have an attribute byte of:
.byte (7 | VERTICAL | UN_CONSTRAINED)
A horizontal, constrained menu with 1 1 selectable items would have an attribute byte of:
.byte (11 I HORIZONTAL I CONSTRAINED)
Most sub-menus are unconstrained: if the user moves the pointer off the sub-menu, all opened
menus are retracted as if GotoFirstMenu had been called. A constrained menu, on the other
hand, restricts the pointer from moving off the menu area from aU but one side. A constrained
menu will only allow the pointer to move off the side leading back to where it expects the parent
menu to be: off the top for a vertical sub-menu and off the left for a horizontal sub-menu. If the
12
Icons, Menus, and Other Mouse Presses
user moves off of a constrained menu (in the only available direction), the current sub-menu is
retracted and the parent menu becomes active as if DoPreviousMenu had been called.
NOTE: The constrain option is only applicable to sub-menus — if the CONSTRAINED flag
is set in the main menu (level 0), the option will have no effect.
Menu Item Structure
For each selectable item in a menu (the number items is specified in the header) there is a five-byte
item structure. These item structures follow the menu header in memory. The first item represents
the first menu selection (top- or leftmost), the second, the second, and so on. Each item structure
specifies the text that will appear in the menu, what happens when the item is selected (Will it
generate an event or a sub-menu?), and the appropriate event routine or sub-menu. Each menu item
is in the following format:
Menu Item:
Index
Constant
Size
Description
+0
OFF_TEXTJTEM
Pointer to null-terminated text string for this menu
item.
+2
OFF TYPE ITEM
byte
Selection type (sub-menu, event, dynamic sub-menu).
+3
OFF_POINTERJTEM
woid
Pointer to sub-menu data structure, event routine, or
dynamic sub-menu routine, depending on selection type.
The first word of the item is a pointer to the text that will be placed in the menu. The text is
expected to be null-terminated (the last byte should be $00 or NULL). If the menu rectangle
specified in the header is not wide enough to contain the entire text string, the text will be clipped at
the right edge when the menu is drawn.
The byte following the text pointer (die third byte) is an item type indicator. Each selectable item
can either be an an action, a sub-menu, or a dynamic sub-menu selection. An action "type item
generates a menu event from MainLoop. A sub-menu type item automatically opens up a sub-
menu structure. And a dynamic sub-menu type selection opens up a sub-menu, but before it does,
it calls an application's routine. Dynamic sub-menus are useful for modifying a menu structure on
the fly. For example, a point size sub-menu, such as those used in geoWritc, can be changed
dynamically when a new font is selected. When the user chooses the font item, the dynamic sub-
menu routine checks the list of available point sizes and builds out the point size sub-menu based
on its findings. The following table summarizes the three menu item types:
Types of Menu Items (for use in item type byte):
Constant Description
SUB.MENU
This menu item leads to a sub-menu. The OFF_POINTER_ITEM is a
pointer to the sub-menu data structure (points thelfirst byte of a menu/sub-
menu header).
DYN.SUB.MENU
This menu item is a dynamic sub-menu. The OFF_POINTER_ITEM is a
pointer to a dynamic sub-menu routine that is called before the menu is
actually drawn. The dynamic sub-menu routine can do any necessary pre-
processing and return with rO containing a pointer to a sub-menu data
structure or $0000 to ignore the selection.
MENU.ACnON
This menu item generates an event. The OFF^POINTERJTEM is a
pointer to the event routine that will to call.
1 3
icons, Menus, and Other Mouse Presses
Bitwise Bre^ mn of the Item Type Byte:
7 6 4 3 2 1
I b7 I b6 I d: I b4-b0 1
b7 sub-menu flag.
b6 dynamic sub-menu flag.
b4-b0 reserved for future use.
Example Menu
The following code fragment defines an unconstrained horizontal menu of three items, suitable for
use as the main menu. Each item in the menu points to a sub-menu that is not shown
(GeosMenu, FileMenu, and EditMenu).
Example:
/SAMPLE MENU TABLE
MENU CONSTANTS ***
/bounding rectangle
MAINXl = /left
MAINYl = /top edge
MAINX2 = 72 /right
MAINY2 = MAINYl + M HEIGHT /bottom edge
/••
/*** MENU DEFINITION ***
• ************************
HEADER
MainMenu :
.byte MAINYl
.byte MAINY2
.word MAINXl
.word MAINX2
/top
/bottom
/ left
/right
.byte ( HORIZONTAL I UN_CONSTRAINED I M_ITEMS)
/*** ITEMS
Mainltems:
/Geos
.word
.byte
.word
GeosText
SUB_MENU
GeosMenu
/pointer to null-terminated text
/generates sub-menu
/pointer to sub-menu structure
/File
.word
.byte
.word
FileText
SUB_MENU
FileMenu
/pointer to null-terminated text
/generates sub-menu
/pointer to sub-menu structure
/Edit
• word
.byte
.word
EditText
SDB_MENU
EditMenu
/pointer to null-terminated text
/generates sub-menu
/pointer to sub-menu structure
M ITEMS
(* - Mainltems) /MISI2E /number of items in the menu
/text string for Geos selection
14
Icons, Menus, and Other Mouse Presses
GeosText :
.byte
Geos t
NULL
;text string
for File
selection
FileText :
• byte
"File",
NULL
;text string
for Edit
selection
Edit Text :
.byte
"Edit",
NULL
; null-terminated item string
; null-terminated item string
/null-terminated item string
Installing Menus
When an application is first loaded, GEOS will not have an active menu structure. GEOS must be
given the address of the application's menu structure before MainLoop can display and track the
user's interaction with it GEOS provides one routine for installing menus:
!• DoMenu
Display and activate a menu structure.
]
DoMenu draws the main menu on the foreground screen and instructs MainLoop to begin taking
care of all menu processing. The menu stays activated and enabled until the MENU_ON_BIT or
the MOUSE_ON BIT of mouseOn is cleared or another menu is installed by calling iJbMenu
with the address o7a different menu structure. In either case, the old menu is not erased from the
foreground screen by GEOS. The application must recover the area from the background buffer
itself.
MainLoop and Menu Events
When the user clicks the mouse button on a menu item, GEOS MainLoop will invert the selection
and examine' the item data block, processing the selection according to its type.
SUB^MENU
If the menu item is of the SUB^MENU type, then menuNumber is incremented, the
appropriate sub-menu is drawn, anS MainLoop begins tracking the user's interaction with the
sub-menu, making it the current menu. If the user moves off of a sub-menu back onto its parent
menu, MainLoop will retract the sub-menu, decrement menuNumber, and make the parent
menu the current menu. If the user moves off of the menus entirely (assuming this is possible —
the menu might be constrained), then MainLoop retracts all sub-menus back up to the the main
menu and sets menuNumber to zero.
DYNAMIC SUB MENU
If the menu item is of the DYNAMIC_SUB^MENU type, MainLoop calls the routine whose
address is in tiie item structure. This routine Ts called before the sub-menu is drawn and before
menuNumber is incremented. The accumulator will contain the item number selected (item
numbers start with zero). When the routine returns with the address of the appropriate sub-menu in
rO, MainLoop continues processing as if it was handling a SUB_MENU type menu. If the
dynamic sub-menu routine returns $0000 in rO, then the sub-menu i^not opened and the current
menu remains active.
15
Icons, Menus, and Other Mouse Presses
MENU^CTION
If the menu item is of the MENU ACTION type, GEOS flashes the menu inverted for
selectionFIash vblanks. selectionPlash is a GEOS variable which is initialized with the
constant SELECTION_DELAY, but may be adjusted by the application. MainLoop will then
call the menu event routine whose address is in the item structure, passing the number of the
selected item in the accumulator (item numbers start with zero). One of the first things a menu
event routine must do, among its own duties, is specify which menu level MainLoop should
return to when it gets control. This is done by calling one of the GEOS routines designed for this
purpose:
• ReDoMenu
Reactivate the menu at the current level.
• DoPreviousMenu
Retract the current sub-menu and reactivate the menu at the
previous level.
• GotoFirstMenu
Retract all sub-menus and reactivate the menu at the main menu
level.
These routines retract menus as necessary (recovering from the background buffer) and sets special
flags which tell MainLoop what has happened; MainLoop is not given control at this time —
that is the job of the menu event handler's rts. If an application's menu event handler does not call
one of these routines before it returns to MainLoop, the menu will remain open but inactive.
NOTE: A menu remains on the foreground screen until DoPreviousMenu or
GotoFirstMenu is called to retract it. If graphics need to be drawn in the area
obscured by a menu, but menus cannot be retracted, then limit drawing to th;
background buffer by setting the proper bits in dispBufferOn. j
Specialized Menu Recover Routines
•
GEOS provides two very low-level menu routines which recover areas obscured by menus from
the background buffer. Usually these routines are only called internally by the higher-level menu
routines such as DoPreviousMenu. They are of little use in most applications and are included in
the jump table mainly for historical reasons. There are two routines:
• RecoverMenu Recovers the current menu from the background buffer toThe
foreground screen.
• RecoverAllMenus Recovers all extant menus and sub-menus from the background
buffer to the foreground screen.
Advanced Menu Ideas
Menu routines can be as clever as desired One common technique involves dynamically modifying
the text strings associated with menu items. This can be used, for example, to add asterisks next to
currendy active options as they are selected
16
Icons, Menus, and Other Mouse Presses
Menus and Mouse-Fault Interaction
How GEOS uses Mouse Faults
In general, the following is true:
• When a menu is down, the system interrupt-level mouse-processing routine is checking
for two types of mouse faults: the mouse moving outside of the rectangle defined by
mouseTop, mouseBottom, mouseLeft, and mouseRight and the mouse moving off
of the menu. It sets bits in mouseFauIt accordingly.
• If the menu is unconstrained, mouseTop, mouseBottom, mouseLeft, and
mouseRight are set to full-screen dimensions, thereby ruling out this type of mouse fault,
• If the menu is constrained, mouseTop, mouseBottom, mouseLeft, and
mouseRight are set to the dimensions of the current menu's rectangle. This will keep the
mouse from moving off of the menu area (and will also generate a mouse fault when an
edge is encountered).
• The system mouse fault routine (called through mouseFauItVec) checks the
mouseFauIt variable. If the mouse faulted by moving off of the menu (only possible if
the menu is unconstrained), DoPreviousMenu is called. If the user moved off of the
sub-menu without moving onto another menu, mouse menu faults will continue to retract
menus until only the main menu is displayed. If the mouse faulted by attempting to move
beyond the mouseTop on a vertical sub-menu or mouseLeft on a horizontal sub-menu
(only possible on a constrained menu) then DoPreviousMenu is called.
Application's Use of Mouse Faults
When the user is interacting with menus, the system uses the mouse fault variables (mouseTop,
mouseBottom, mouseLeft, and mouseRight) and expects its own fault service routine to be
called through mouseFauItVec. If an application needs use mouse faults for its own purposes,
should first disable menus by clearing the MENUON^BIT of mouseOn Before reenabling
menus, it should set the fault variables to the full screen dimensions and call StartMouseMode to
restore the system's fault service routine:
* ************ ***i«r********#****************4r************
; Routine to restore the mouse service routines to an
; operational state after an application's use of
/mouse faults through mouseFauItVec. Should be called
/before menus are reenabled.
Re set Mouse:
Following lines changed to save bytes
LoadW mouseLeft, #0
LoadB mouseTop, #0
Ida #0
St a mouseLeft
sta mouseLeft+1
sta mouseTop
.if (C128)
LoadW rO,# (SC_40_WIDTH-1
Idx #rO
jsr NormalizeX
MoveW rO, mouseRight
• else ; (APPLE I I C64)
reset mouse left to left screen edge
and mouse top to top screen fedge
I DOUBLE__W I ADD1_W) /put in zp reg to normalize
/point to register
/double if in 80-column
/mouse right to right screen edge
1 7
Icons, Menus, and Other Mouse Presses
LoadW mouseRight, #SC_PIX_WIDTH-1
/mouse right to right screen edge
.endif
LoadB mouseBottom, #SC__PIX_HEIGHT-1
clc
jsr StartMouseMode
rts
mouse bottom to bottom screen edge
don't reposition mouse...
exit
Sample Menu
Other Mouse Presses
When the user clicks the mouse somewhere on the screen where there is no active menu or icon,
GEOS consideres this an "other" press and checks otherPressVector for an application-
provided subroutine. If otherPressVector is $0000, then the press is ignored, if
OtherPressVector contains anything but $0000, GEOS treats the value as an absolute address
and simulates an indirect jsr to that address. otherPressVector defaults to $0000 at application
startup.
OtherPressVector gets called on all presses that are not on an active icon or menu and on all
releases, whether on a menu, icon, or anywhere else. In most cases, the application will want to
ignore the releases. This is done simply by checking mouseData for the current state of the
mouse button, as in:-
Because otherPressVector gets called on each press (and release), any double-click detection
must be performed manually by the other-press routine. Handling double-clicks through
Ida
bpl
rts
mouseData
10$
; check state of the mouse button
/branch to handle presses
;but return immediately to ignore releases
10$:
1 8
Icons, Menus, and Other Mouse Presses
otherPress Vector is similar to the polled mouse method used with icons, the major difference
being a check for releases on entry.
Example:
/Ignore releases on entry
Ida mouseData /check state of the mouse button
bpl 5$ /branch to handle presses
rts /but return immediately to ignore releases
5$:
/User pressed mouse once, start double-click counter going
LoadB dblClickCount, #CLICK__COUNT /start delay
/Loop until double-click counter times-out or button is released
10$:
Ida dblClickCount /check double-click timer
beq 30$ /If timed-out, no double-click
Ida mouseData /Else, check for release
bpl 10$ /loop until released
/mouse was released, loop until double-click counter times-out or
/button is pressed a second time.
20$:
Ida dblClickCount /check double-click timer
beq 30$ /If timed-out, no double-click
Ida mouseData /Else, check for second press
bmi 20$ /loop until pressed
^•.Double-click detected (no single-click)
-J0.$: jsr DoDoubleClick /do double-click stuff
^' bra 90$ /exit
' /Single-click detected (no double-click)
— -r- jsr DoSingleClick /do single-click stuff
• / and ^f all through to exit
/Exit
90$: rts /return to MainLoop
1 9
Process Library
Process Library
A process is a is an event that is triggered on a regular basis by a timer. This allows GEOS to
generate an event at specific time intervals, such as 20 times per second, once every minute, or five
times each hour. Processes allow a limited form of multitasking, where many short routines can
appear to run concurrently with MainLoop. Thus an application could update an alarm clock and
scroll the work area while calculating a cell in a spreadsheet. Applications can also use processes to
monitor the mouse. geoPaint, for example, uses a process to monitor the mouse's position when
using the line tool; when the mouse moves, the process prints the new line length in the status
window. geoPublish operates in a similar manner, using a process to update the values in the
coordinate boxes as the user moves the across the preview page.
Note: Processes do not provide true multitasking. There is no interrupt-driven context
switching, nor any concurrence (where two routines run simultaneously). Processes
are best thought of as events triggered off of MainLoop just like any other event.
When one process is running, the next process in line won't get executed until the first
finishes and returns to MainLoop.
Process Nomenclature
There are a number of terms associated with processes. Each process has a countdown timer.
When the countdown timer reaches zero or times-out, the process becomes runable. If a process is
frozen, its timer is not being decremented. The timer will continue when the process is unfrozen. If
a process is blocked, a process event will not be generated until the process becomes unblocked.
Process Data Structure
The application must initialize the GEOS process handler with a process data structure. Thfe
process data structure contains the necessary information for all the desired processes. The table
can specify up to MAX^PROCESSES (formeriy MAXIMUM_PROCESSES) processes.
Each process in the table is in the following format:
Index Constant Size Description
+0
OEF.PJVENT
word
Pointer to event routine that is called when this
process times-out.
+2
OFF^P.TIMER
word
Timer initialization value: number of vblanks to
wait between one event trigger and the next.
The first word is the address of the process event handler. The process event handler is much like
any other event handler: it is called by MainLoop when process becomes runable (as opposed to,
say, when the user clicks on an icon or selects a menu item) and is expected to return with an rts.
The second word is the number of vblanks to wait between one event trigger and the next. If the
the OFF_P_TIMER word of a process is set to 20, for example^ then the process event handler
will be called every 20 vblanks (about 3 times per second on NTSC machines and 2.5 times per
second on PAL machines).
1
Process Library
c
Sample Process Table
The following data block defines three processes, each with a different process event handler. The
first process will execute once every 10 vblanks, the second will execute once every second, and
the third will execute once every five minutes. Notice the use of the FRAME_RATE constant to
calculate the correct vblank delay for PAL and NTSC machines and the automatic assignment of
process constants with (* - PrTabIe)/PSIZE.
Sample process data structure
oc
PrTable:
A* MOUSE CHECK PROCESS***
Check mouse position and change pointer form as
necessary.
MOUSECHECK « (*-P^Table) /PSIZE /process number
.word CheckMouse /process event routine
.word 10 ; check every 10 vblanks
;*** REAL-TIME CLOCK PROCESS ***
; Increment a r^^l-time clock counter every second
RTCLOCK = (*-P5,Table) /PSIZE /process number
.word Tick /process event routine
.word FRAME_RATE /one second worth of vblanks
*** SCREEN-SAVER PROCESS ***
Save the screen by turning off colors after five
minutes.
SCRNSAVER = (*-Pr^able) /PSIZE /process number
.word ScreenSave /process event routine
.word 5*60*FRAME_RATE /frames in 5 minutes
/delay « 5 min* 60 sec/min * frames/sec)
NUM_PROC = (*-ProcTable) /PSIZB*4r /number of processes in this table A/0 T tj
/for passing to InitProcesses
.if (NUM__PROC > MAX_PROCESSES) /check for too many processes
echo Warning: too many processes
.endif
Process Management
Installing Processes
The application must install its processes by telling GEOS the location of the process data structure
and the number of processes in the structure. GEOS provides one routine for installing processes:
pTnitProcesses Initialize and install processes.
InitProcesses copies the process data structure into an internal area of meir; - v, hidden from the
application. GEOS maintains the processes within this internal area, keepi: rack of the event
routine addresses, the timer initialization values (used to reload the timers afie: : time-out), the
current value of the timer, and the state of each process (i.e., frozen, blocke d, runable). The
application's copy of the process data structure is no longer needed because GEOS remembers this
information until a subsequent call to InitProcesses.
2
Process Library
Example:
Initialize process table ***
LoadW rO,#ProcTable /point at process data structure
Ida #NUM_PROC /pass actual number of processes
jsr InitProcesses /call GEOS to install processes
/processes in table are now blocked and frozen
Starting and Restarting Processes
When a process table is installed, the processes do not begin executing immediately because all
processes are initialized as frozen. GEOS provides a routine to simultaneously unblock and
unfreeze a single process while reinitializing its countdown timer:
plRestartProcess Initialize a process's timer value then unblock and unfreeze it. |
RestartProcess should always be used to start a process for the first time, otherwise the timer
will begin in an unknown state.
Example:
start all processes ***
Idx #NUM_PR0C-1 /process numbers range from to NUM_PR0C-1
10$:
jsr RestartProcess /reset timer, unblock, and unfreeze process
dex /next process
bpl 10$ /loop until done
RestartProcess can also be used rewind a process to the beginning of its cycle. One application
for this is a screen-saver utility which blanks the screen after, say, five minutes of inactivity to
prevent phosphor bum-in. A five-minute process is established which, when it triggers an event,
blanks the screen. Any routine which detects activity from the user (a mouse movement, button
press, keypress, etc.) before the screen is blanked can call RestartProcess to reset the screen-
saver countdown timer to its initial five minute value.
Freezing and Blocking Processes
When a process is frozen, its timer is no longer decremented every vblank. It will therefore never
time-out and generate a process event When a process is unfrozen, its timer again begins counting
from the point where it was frozen. GEOS provides the following routines for freezing and
unfreezing a process's timer:
• FreezeProcess
Freeze a process's countdown timer at its current value.
• UnfreezeProcess
Resume (unfreeze) a process's countdown timer.
Example:
Freeze all processes ***
php
sei
Idx #NUM_PR0C-1
10$:
jsr FreezeProcess
dex
bpl 10$
pip
disable interrupts to synchronize freezing
process numbers range from to NUM_PR0C-1
/freeze process
/next process
•loop until done
/restore interrupt status
3
Process Library
A process may also be blocked. Blocking a process temporarily prevents the event service routine
from being executed. It does not stop the timer from decrementing, but when the timer reaches zero
and the process bcomes runable, the event is not generated. When a process is subsequently
unblocked, its events will again be generated. GEOS provides the following routines for blocking
and unblocking processes:
• BlockProcess Block a process's events.
• UnblockProcess Allow a process's events to go through.
Example:
Block mouse-checking process ***
Idx #MOUSECHECK /process number of mouse check
jsr BlockProcess ;block it
Unblock Real-time clock process ***
Idx #RTCLOCK ; process number of real-time clock
jsr UnblockProcess /unblock it
When a timer reaches zer (times-out), its process becomes runable. An internal GEOS flag (called
the runable flag) is set, indicating to MainLoop that an event is pending. The timer is then
restarted with its initialize "'on value. MainLoop will ignore the runable flag as long as the process
is blocked. When the prox iss is later unblocked, MainLoop will see the runable flag, recognize it
as a pending event, and ca:l the appropriate service routine. However, multiple pending events are
ignored: if a blocked processes timer reaches zero more than once, only one event will be generated
when it is unblocked.
Freezing vs. Blocking
The differences between freezing and blocking are in many cases unimportant to the application.
However, a good understanding of their subtleties will prevent problems that may arise if the
wrong method is used.
Normally, a process's timer is decremented every vblank. If a process is frozen, however, the
GEOS vblank interrupt routine will ignore the associated timer. The timer value will not change
and, hence, will never reach zero. The process will never become runable. If you think of a
process as a wind-up alarm clock, freezing is equivalent to disconnecting the drive spring — even
the second hand stops moving.
Freezing a process only guarantees that the process will not subsequently become runable. The
process may in fact already be marked as runable and GEOS is only awaiting the next pass through
MainLoop to generate an event. (A process that is marked as runable but not yet run is said to be
apending event.)
If a process is blocked (but not also frozen), GEOS Interrupt Level will continue to decrement the
associated timer. If the timer reaches zero, GEOS will reset the timer and make the process
runable. But MainLoop will ignore the process and not generate an event because the process is
blocked. If the process is later unblocked, the event will be generated during the next pass through
MainLoop. Using the alarm clock analogy, freezing is equivalent to disconnecting the alarm bell
— the clock continues to run but the alarm does not sound unless the bell is reconnected.
The only way to absolutely disable a process — both stopping its clock and preventing any
pending events to get through — is to freeze and block it.
Example:
4
Process Library
****************************************************************************************
StopProcess — freeze a process timer and block any pending events
UnstopProcess — unfreeze and unblock the process
Pass: X = process number
Returns: x unchanged
Destroys: a
StopProcess:
jsr FreezeProcess ;not that it really matters, but we'll freeze first
jmp BlockProcess ;then block (let BlockProcess rts)
UnstopProcess :
jsr UnblockProcess ;unblock first
jmp UnfreezeProcess ;then unfreeze (let Unf reezeProcess rts)
Forcing a Process Event
Sometimes it is desirable to force a process to run on the next pass through MainLoop,
independent of its timer value. GEOS provides one routine for this:
plEnableProcess Makes a process runable immediately. H
EnableProcess merely sets the runable flag in the hidden process table. When MainLoop
encounters a process with this flag set, it will attempt to generate an event, just as if the timer had
decremented to zero. This means that EnableProcess has no priveleged status and cannot
override a blocked state. However, because it doesn't depend on (or affect) the current timer value,
the process can become runable even with a frozen timer.
The Nitty-gritty of Processes
Processes involve a complex (but hopefully transparent to the application) interaction between
multiple levels of GEOS. In advanced uses, it may be necessary to understand this interaction. The
following discussing clarifies some of the fine points of processes.
Interrupt Level and MainLoop Level
Processes involve two distinct levels of GEOS: interrupt level and MainLoop level. Every vblank
an IRQ (Interrupt ReQuest) signal is generated by the computer hardware. Part of the GEOS
interrupt service routine manages process timers: if a process exists and it is not frozen, its timer is
decremented. When the timer reaches zero, the interrupt level routine sets the associated runable
flag and restarts the timer with its initialization value. The process event routine is not called at this
time.
If for some reason interrupts are disabled (usually by setting the interrupt disable flag with an sei
instruction) and a vblank occurs, the interrupt will be ignored and the process timers, therefore,
will not be decremented during that vblank. This is usually not a problem because interrupts are
normally enabled. However, be aware that some operating system functions (such as disk I/O)
disable interrupts.
5
Process Library
During a normal pass through MainLoop, GEOS will examine the active processes. If a
process's runable flag is set and it is not blocked, MainLoop clears the runable flag and and calls
the process. If a process is blocked, MainLoop ignores it.
Because of the way MainLoop and the interrupt level interact, there is a certain level of
imprecision with processes:
1: If a process has a very low timer initialization value (e.g., less than five) such that it is
possible it will time-out more than once during the time it takes for a single pass through
MainLoop, MainLoop may miss some of these time-outs.Each time the timer reaches
zero it sets the runable flag, but since there is only one runable flag per process,
MainLoop has no way of knowing if it should generate more than one event.
2: It is impossible to guarantee any precise relationship (e.g., a timer difference less than
five) between two or more timers. Although all processes that time-out during the same
interrupt will become runable at that time, the interrupt may occur while MainLoop is
the midst of handling processes: processes that have already been passed-by may bee
runable but not get executed until the next time through MainLoop, which could
fraction of a second later.
For more Information refer to Chapter @ML&INTS@.
Process Synchronization
It is sometimes desirable to maintain a synchronized relationship between the timer values of two
or more processes. This is nontrivial because even if the calls to restart, freeze, or unfreeze these
timers are done immediately after each other, there is always a slight chance that the vblank
C interrupt will occur after the status of some of the timers has changed but before all have been
changed. For example: if an application is trying to freeze three timers simultaneously and the
interrupt happens after the first timer has been frozen but before the other two, the remaining two
timers will still be decremented. To circumvent this problem, bracket the calls by disabling
interrupts before freezing, blocking, or restarting, and reenabling afterward. This is best done as in
the following example:
RESTART CLOCK PRCXTESSES AT THE SAME TIME ***
f
RstartP:
php ;save interrupt disable flag
sei /disable interrupts (stopping timers)
Idx tRTCLOCK /restart clock
jsr RestartProcess
Idx #SCRNSAVER /restart screen-saver
jsr RestartProcess
pip /restore interrupt disable status
Disabling Processes While Menus Are Down
Because MainLoop is still running when menus are down, process events continue to occur. It is
often desirable to disable a process while the user has a sub-menu opened. The easiest way to
handle this situation is to check menuNumber at the beginning of the process event routine. If
menuNumber is non-zero, then a menu is down and the event routine can exit early:
PrEventRoutine :
Ida menuNumber /check menu level
bne 90$ ;and exit immediately if a menu is down
jsr DoPrEvent . /else, process the event normally
90$:
rts /return to MainLoop
6
Process Library
Sleeping
Sleeping is a method of stopping execution of a routine for a specified amount of time. That is: a
routine can stop itself and "go to sleep," requesting MainLoop to wake it up at a later time. GEOS
provides one routine for sleeping:
Sleep does not actually suspend execution of the processor. When the application does a jsr
Sleep, GEOS sets up a hidden timer, much like a process timer, that is decremented during the
vblank interrupt. It removes the return address from the stack (which corresponds to the jsr
Sleep) and saves it for later use, then perfoms an rts. Since the return address on the stack no
longer corresponds to the jsr Sleep, control is returned to a jsr one level lower. In many cases,
this will return control directly to MainLoop.
When the timer decrements to zero, a wake-up flag is set, and, on the next pass through
MainLoop, the sleeping routine will be called with a jsr to the instruction that immediately
follows the jsr sleep. When the routine finishes with an rts (or another jsr Sleep), MainLoop
will resume processing.
Important: Any temporary values pushed onto the stack must be pulled off prior to calling
Sleep. Also, when a routine is awoken, the values in the processor registers and
the GEOS pseudoregisters will most certainly contain different values from when it
went to sleep. This is because MainLoop has been running full-speed, calling
events and doing its own internal processing, thereby changing these values. If a
routine needs to pass data from before it sleeps to after it awakes, it must do so in
its own variable space.
Sleep can be used to set up temporary, run-once. processes by placing calls to Sleep inside
subroutines. For example, an educational program may want to flash items on the screen and make
a noise when the student selects a correct answer. The routines that handle these "bells and
whistles" can be established using Sleep without needlessly complicating the function that deals
with correct answers. The following code fragment illustrates this idea:
1^ Sleep
Pause execution for a given time interval.
*1^«****«*4r*********************************** ******************
Routine to handle a correct answer. Does some graphics, makes
some noise, and adjusts the student's score.
***************************************************************
BELL^DELAY
FLASH DELAY
60
23
; length of bell
; delay between flashes
Correct :
IncW
jsr
jsr
rts
Bell
Flash
score
/score +« 1
/start the bell going
/start the answer flashing
7
Process Library
Subroutine:
If sound is enabled (user-determined), start the
bell sound and then go to sleep; Sleep
returns control to the routine that called us
When we wake
to MainLoop
up, we stop the be'll sound and return
Bell:
90$:
If sound is disabled, then the rts returns
directly to the routine that called us.
Ida
soundFlag
/check sound flag
beq
90$
;exit if user turned sound off
jsr
BellOn
;else, turn the bell on
LoadW
rO,BELL_DELAY
;and delay before turning off
jsr
Sleep
;by going to sleep (think rts)
jsr
BellOff
;turn bell off when we awake
rts
;exit
Subroutine: Invert the answer. Go to sleep.
answer when we wake up.
Re-invert the
Flash:
jsr
LoadW
jsr
jsr
rts
InvAnswer
rO,FLASH_DELAY
Sleep
InvAnswer
; Graphically invert the answer
;and delay before reverting
/by going to sleep (think rts)
/when we awake, revert the image
/ exit
8
Math Routines
Math Routines
One of the major limitations of eight-bit microprocessors such as the 6502 is their math capabilites:
they can only operate directly on eight-bit quantites (0-255), and multiplication and division require
extensive computational energy. For the sake of the application programmer, GEOS has some of
the more popular arithmetic routines built into the Kemal. These include double-precison (two-
byte) shifting, as well as multiplication and divison.
Parameter Passing to Math Routines
The math routines use a flexible parameter passing convention: rather than putting values into
specific GEOS pseudoregisters, the application can place the values in any zero-page location
(almost) and then tell GEOS where to find die values by passing the address of the of the
parameter. Because the parameters are located on zero-page, their addresses are one-byte quantites
that can be passed in the x and y index registers. For example, a GEOS math routine might require
two word values. The application could place these values in pseudoregisters aO and al, then call
a GEOS math routine, like Ddiv (double-precision divide) with the address of aO and al in the x
and y registers.
Example:
Idx #aO ;load up address of first parameter
Idy #al ;and address of other parameter
jsr Ddiv /divide the word in aO by the word in al
Important: It is easy to get confused and leave off the immediate-mode sign (#) when trying to
load the address of a zero-page variable, thereby loading the value contained in the
variable instead.
Double-precision Shifting
The 6502 provides instructions for shifting eight-bit quantites left and right but no instructions for
directing these operations on 16-bit (double-precision) numbers. GEOS provides two routines for
double-precision shifting:
• DShiftLeft
Arithmetically left-shifts a 16-bit word value.
• Di^hiftRight
Arithmetically right-shifts a 16-bit word value.
Double-Precision Arithmetic
Many of the possible double-precision arithmetic operations (such as word+word addition) are
provided with GEOS macros. The standard set of GEOS macros, which include the likes of
AddW and SubW, are listed in Appendix XX. Many double-precision operations, however, such
as multiplication and division, are complicated enough to warrant an actual subroutine. GEOS
provides many of these routines, some of which have signed and unsigned incarnations.
Math Routines
Signed vs. Unsigned Arithmetic
6502 arithmetic operations rely on the two's complement numbering system — an artifact of binary
math — to provide both signed and unsigned operations with the same instructions (ado and sbc).
For example, an ado #$6c can be seen as either adding 188 to the accumulator (unsigned math: all
eight bits represent the positive number, any carry out of bit 7 indicates an overflow) or as adding a
-68 to the accumulator (signed math: the high-bit, bit 7, holds the sign and any carry out of bit 6
indicates an overflow). The 6502 has' little trouble adding and subtracting these two*s-complement
signed numbers. Operations such as multiplication and division, however, need to special-case the
sign of the numbers.
Incrementing and Decrementing
GEOS has only one routine in the category of incrementing and decrementing:
I • Ddec Decrements a word, setting a flag if the value reaches zero. |
However, because incrementing and decrementing words are such common operations, Berkeley
Softworks has created a set of macros specifically designed for incrementing and decrementing
word values:
IncW
Increment Word — IncW addr
Args: addr — address of word to increment
Action: IncW increments a word. If the result is zero,
then the zero flag in the status register is set.
• macro IncW addr
inc addr /increment low-byte
,bne done /branch if no carry into hi-byte
inc addr+1 /propagate carry into hi-byte
done: /z-flag is set if both hi & low were $00
• endm
*★*★★**★★***★***★*★*★★*****★***★*****★*****★★*★**★******★*★*★**★★
DecW
Decrement Word — DecW zpaddr
Args: zpaddr — zero-page address of word to decrement
Action: DecW Decrements a word. If the result is zero,
then the zero flag in the status register is set.
a and x registers are destroyed.
*****************************************************************
•macro DecW zpaddr
Idx #zpaddr /load x with address of word for call
jsr Ddec /call GEOS routine
/z-flag is set if both hi & low were $00
• endm
k******************* ************* ************************ ********
Decrement Word #2 — DecW2 addr
(fast version)
Args: addr — address of word to decrement
2
Math Routines
Action: DecW2 decrements a word with inline code. No
flags are set on reaching $0000. Destroys a.
.macro DecW2 addr
Ida addr
bne noOvrflw
dec addr+1
noOvrflw:
dec addr
.endm
;get low byte
;if low_byte != $00, then skip high byte dec
/decrement hi-byte
/decrement low-byte
Most applications will use IncW and DecW to take advantage of the flags which are set when the
values reach zero. However, DecW2 can be useful when a word needs to be decremented quickly
and the zero flag is not needed.
Unsigned Arithmetic
GEOS provides the following routines for arithmetic with unsigned numbers:
• BBMult
Byte-by-byte multiply: multiplies two unsigned byte operands to
produce an unsigned word result.
• BMult
Word-by-byte multiply: multiplies an unsigned word and an
unsigned byte to produce an unsigned word result.
• DMuIt
Word-by- word (double-precision) multiply: multiplies two
unsigned words to produce an unsigned word result.
•Ddiv
Word-by-word (double-precision) division: divides one unsigned
word by another to produce an unsigned word result.
Example:
ConvToUnits
This routine converts a pixel measurement to inches or, optionally,
centimeters, at the rate of 80 pixels per inch or 31.5 pixels per
centimeter .
pass :
rO - number to convert (in pixels)
return :
rO - inches / centimeters
rlL - tenths of an inch / millimeters
affects:
nothing
destroys :
a, X, y, rO-rl, r8-r9
if AMERICAN
. INCHES « TRUE
.else ; ! AMERICAN
INCHES = FALSE
.endif
; decide whether inches or centimeters is
; appropriate
ConvUnits :
Math Routines
.if
INCHES
; First, convert rO to length in 1/20 of
/standard units
*** START INCHES SPECIFIC CODE ***
For ENGLISH, need to multiply by
20 1
Idx #rO
Idy #2
jsr DShiftRight
.else /CENTIMETERS
80 dots/inch 4
which amounts to a divide by four
( /4 = two right shifts)
rO = r0»2 (rO « rO/4)
;*** START OF CENTIMETER SPECIFIC CODE ***
For centimeters, need to do multiply by
20 40
31.5 dots/cm
Following lines changed to save bytes
63
LoadW
Idx
Idy
jsr
LoadB
Idx
Idy
jsr
LoadW
Idx
Idy
jsr
.endif
rl,#40
#rO
#rl
DMult
rl,#40
#rO
#rl
BMult
rl,#63
#rO
#rl
Ddiv
First multiply by 40
(word value)
(byte value)
rO « rO*40 (byte by word multiply)
then divide by 63
rO = rO/63
START OF COMMON CODE
IncW
LoadW
Idx
idy
jsr
MoveB
Isr
rts
rO
rl,#20
#rO
#rl
Ddiv
r8L,rlL
rlL
rO » result in l/20ths
add in one more l/20th, for rounding
now divide by 20 (to move decimal over one)
dividend
divisor
rO = rO/20 (rO = result in proper unit)
rlL « l/20ths
and convert to 1/lOths (rounded)
exit
Signed Arithmetic
GEOS provides the following routines for arithmetic with signed numbers:
• Dabs
Computes the absolute value of a two's-complement signed word.
• Dnegate
Negates a signed word by doing a two's complement sign-switch.
• bSdiv
Signed word-by-word (double-precision) division: divides one
two*s complement word by another to produce an signed word
result.
There is no signed double-precision multiply routine in the GEOS Kemal. The following
subroutine can be used to multiply two signed words together.
4
Math Routines
DSir.ult double-precision signed multiply.
pass: X - zpage address of multiplicand
y - zpage address of multiplier
returns: signed result in address pointed to by x
word pointed to by y is absolute-value of the
multiplier passed-
X, y unchanged
/Strategy:
Establish the sign of the result: if the signs of the
; multiplicand and the multiplier are different, then the result
; is negative; otherwise, the result is positive. Make both the
; multiplicand and the multiplier positive, do unsigned
/ multiplication on those, then adjust the sign of the result
; to reflect the signs of the original numbers.
/destroys: a, r6 - r8 (mgl)
DSmult:
Ida
zpage+l, X
;get sign of multiplicand (hi-byte)
eor
zpage+l,y
;and compare with sign of multiplier
php
;save the result for when we come back
jsr
Dabs
/multiplicand = abs (multiplicand)
stx
r6L
;save multiplicand index
tya
;put multiplier index into x
tax
;for call to Dabs
jsr
Dabs
/multiplier = abs (multiplier)
Idx
r6L
/restore multiplier index
jsr
Dmult
/do multiplication as if unsigned
pip
/get back sign of result
bpl
90$
/ignore sign-change if result positive
jsr
Dnegate
/otherwise, make the result negative
rts
«
Dividing by Zero
Division by zero is an undefined mathematical operation. The two GEOS division routines (Ddiv
and DSdiv) do not check for a zero divisor and will end up returning incorrect results. It is easy to
divide-by-zero error checking to these two routines:
Example:
/NewDdiv — Ddiv with divide-by- zero error checking
/NewDSdiv — DSdiv with divide-by-zero error checking
Pass :
X
zp address of dividend
y
zp address of divisor
Returns
x,y
unchanged
2p,x
result
r8
remainder
a
$00 — no error
%ff — divide by zero error
st
set to reflect error code in accumulator
Destroys
r9
Math Routines
DIVIDE BY ZERO = $ff
t***************** f - ^ *************************************
NewDdiv :
Ida
ora
bne
Ida
rts
10$:
Ida
rts
zpage,y
2page,y
10$
#DIVIDE BY ZERO
Ddiv
#$00
;get low byte of divisor
;and high byte of divisor
;.if either is non-zero, go divide
/return error
; exit
!
/divide
;and return no error
NewDSdiv:
Ida
ora
bne
Ida
rts
10$:
zpage,y
zpage,y
10$
#DIVIDE BY ZERO
Apple
stx
.if
.endif
jsr DSdiv
.if Apple
Idx
.endif
Ida #$00
rts
Xsave
Xsave
get low byte of divisor
and high byte of divisor
if either is non-zero, go divide
return error
exit
save x-register because Apple destroys
divide
restore x-register because that ageos destroyed
and return no error
.if Apple
•ramsect
Xsave .block 1
.psect
.endif
temp x register save variable for ageos
6
r/^/ " Fonts, and Keyboard Input
Text, Fonts, and Keyboard Input
At one point or another, almost every application will need to place text directly on the screen or get
keyboard input from the user.
GEOS text output facilities support disk-loaded fonts, multiple point sizes, and additive style
attributes. The application can use GEOS text routines to print individual characters, one at a time,
or entire strings, including strings with embedded style changes and special cursor positioning
codes. GEOS will automatically restrict character printing to margins allowing text to be confined
within screen or window edges. GEOS even contains a routine for formatting and printing decimal
integers.
GEOS keyboard input facilities the translation of keyboard input to text output by mapping most
keypress so that they correspond to the printable characters within the GEOS ASCII character set.
GEOS will buffer keypresses and use them to trigger MainLoop events, giving the application
full control of keypresses as they arrive. And if desired, GEOS can also automate the process of
character input, prompting the user for a complete line of text.
Text Basics
Fonts and Point Sizes
Fonts come in various shapes and sizes and usually bear monikers like BSW 9, Hwnbolt 12, and
Boalt 10. A font is a complete set of characters of a particular size and typeface. In typesetting, the
height of a character is measured in points (approximately 1/72 inch), so Humbolt 12 would be a
12 point (1/6 inch) Humbolt font. A text point in GEOS is similar to a typesetter's point: when
printed to the screen, each GEOS point corresponds to one screen pixel. GEOS printer drivers map
screen pixels to 1/80 inch dots on the paper to work best with 80 dot-per-inch printers.A GEOS
1/80 inch point is, therefore, very close to a typsetter's 1/72 inch point.
GEOS has one resident font, BSW 9 (Berkeley Softworks 9 point). The application can load as
many additional fonts as memory will allow. Fonts require approximately one to three kilobytes of
memory.
Proportional Fonts
Computer text fonts are typically monospaced fonts. The characters of a monospaced font are all
the same width, compromising the appearance of the thinnest and widest characters. GEOS fonts
arc proportional fonts, fonts whose characters are of variable widths. Proportional fonts tend to
look better than monospaced fonts because thinner characters occupy less space than wider
characters; a lower-case "i," for example, is often less than l/5th the width of an upper-case "W."
Character Width and Height
Although some characters are taller than others, all characters in a given font are treated as if they
are the same height. This height is the font's point size. A 10 point font has a height of ten pixels.
If a character's image is smaller than 10 pbcels, it is because its definition includes white pixels at
the top or bottom. The height of the current font is stored in the GEOS variable curHeight.
Although fonts taller than 28 points are rare (some megafonts are as tall as 48 points), a font could
tiieoretically be as tall as 255 points.
1
Text, Fonts, and Keyboard Input
Because GEOS uses proportional fonts, the width of each character is determined by its pixel
definition — the tiiinner characters occupy fewer pixels horizontally than the wider characters.
Most character definitions include a few columns of white pixels on the right side so that the next
character will print an appropriate distance to the right If this space didn't exist, adjacent characters
would appear crowded. The width of any single character cannot exceed 57 pixels after adding any
style attributes, which means that the plaintext version of the character can be no wider than 54
pixels.
The Baseline
Each font has a baseline, an imaginary line that intersects the bottom half of its character images.
The baseline is used to align the characters vertically and can be thought of as the line upon which
characters rest. The baseline is specified by a relative pixel offset from the top of the characters (the
baseline offset). Any portion of a character that falls below the baseline is called a descender. For
example, an 18 point font might have a baseline offset of 15, which means that the 15th pixel row
of the character would rest on the baseline. Any pixels in the 16th, 17th, or 18th row of the
character's definition form part of a descender. The baseline offset for the current font is stored in
the GEOS variable baselineOffset. The application may increment or decrement the value in this
variable to print subscript or superscript characters
The following diagram illustrates the relationship between the baseline and the font height:
The y-position passed to GEOS printing routines usually refers to the position of the baseline, not
the top of the character. Most of the character will appear above that position, with any descender
appearing below. If it is necessary to print text relative to the top of the characters, a simple
transformation can be used:
charYPos = graphics YPos + baselineOffset
Where graphicsYFos is the true pixel position of the top of the characters, charYPos is the
transformed position to pass to text routines, and baselineOffset is the value in the global
variable of that name.
Styles
The basic character style of a font is called plaintext. Applying additional 5fy/e attributes to the
plaintext modifies the appearance of the characters. There are five available style attirbutes: reverse,
italic, bold, outline, and underline. These styles may be mixed and matched in any combination,
resulting in hybrids such as bold italic underline . The current style attributes are stored in the
variable currentMode. Whenever GEOS outputs a character, it first alters the image (in an
internal buffer) based on the flags in this variable:
2
Math Routines
Action :
DecW2 decrements a word with inline code. No
flags are set on reaching $0000. Destroys a.
.macro DecW2 addr
Ida addr
bne noOvrflw
dec addr+1
noOvrflw:
dec addr
.endm
;get low byte
;if low^byte != $00, then skip high byte dec
/decrement hi-byte
/decrement low-byte
Most applications will use IncW and DecW to take advantage of the flags which are set when the
values reach zero. However, Dec\V2 can be useful when a word needs to be decremented quickly
and the zero flag is not needed.
Unsigned Arithmetic
GEOS provides the following routines for arithmetic with unsigned numbers:
• BBMult
Byte-by-byte multiply: multiplies two unsigned byte operands to
produce an unsigned word result.
• BMult
Word-by- byte multiply: multiplies an unsigned word and an
unsigned byte to produce an unsigned word result.
• DMuIt
Word-by-word (double-precision) multiply: multiplies two
unsigned words to produce an unsigned word result.
•Ddiv
Word-by-word (double-precision) division: divides one unsigned
word by another to produce an unsigned word result.
Example:
ConvToUnits
This routine converts a pixel measurement to inches or, optionally,
centimeters, at the rate of 80 pixels per inch or 31.5 pixels per
centimeter .
pass :
rO - number to convert (in pixels)
return :
rO - inches / centimeters
rlL - tenths of an inch / millimeters
affects :
nothing
destroys :
a, X, y, rO-rl, r8-r9
*********************************************************
if AMERICAN
; decide whether inches or centimeters is
; appropriate
. INCHES = TRUE
.else ; ! AMERICAN
INCHES = FALSE
.endif
ConvUnits:
Math Routines
.if
INCHES
; First, convert rO to length in 1/20 of
/standard units
*** START INCHES SPECIFIC CODE ***
For ENGLISH, need to multiply by
20 1
Idx #rO
Idy #2
jsr DShiftRight
.else /CENTIMETERS
80 dots/inch 4
which amounts to a divide by four
( /4 = two right shifts)
rO = r0»2 (rO = rO/4)
;*** START OF CENTIMETER SPECIFIC CODE ***
For centimeters, need to do multiply by
20 40
31.5 dots/cm
Following lines changed to save bytes
63
LoadW
Idx
Idy
jsr
LoadB
Idx
Idy
jsr
LoadW
Idx
Idy
jsr
rl,#40
#r0
#rl
DMult
rl,#40
#r0
#rl
BMult
rl,#63
#r0
#rl
Ddiv
.endif
IncW
LoadW
Idx
idy
jsr
MoveB
Isr
rts
rO
rl,#20
#r0
#rl
Ddiv
r8L,rlL
rlL
First multiply by 40
(word value)
(byte value)
rO = rO*40 (byte by word multiply)
then divide by 63
rO = rO/63
;*** START OF COMMON CODE ***
rO = result in l/20ths
add in one more l/20th, for rounding
now divide by 20 (to move decimal over one)
dividend
divisor
rO = rO/20 (rO = result in proper unit)
rlL - l/20ths
and convert to 1/lOths (rounded)
exit
Signed Arithmetic
GEOS provides the following routines for arithmetic with signed numbers:
• Dabs
Computes the absolute value of a two's-complement signed word.
• Dnegate
Negates a signed word by doing a two's complement sign-switch.
• DSdiv
Signed word-by-word (double-precision) division: divides one
two*s complement word by another to produce an signed word
result.
There is no signed double-precision multiply routine in the GEOS Kemal. The following
subroutine can be used to multiply two signed words together.
4
Math Routines
DSmult double-precision signed multiply.
pass: X - zpage address of multiplicand
y - zpage address of multiplier
returns: signed result in address pointed to by x
word pointed to by y is absolute-value of the
multiplier passed-
X, y unchanged
/Strategy:
Establish the sign of the result: if the signs of the
multiplicand and the multiplier are different, then the result
; is negative; otherwise, the result is positive. Make both the
; multiplicand and the multiplier positive, do unsigned
/ multiplication on those, then adjust the sign of the result
/ to reflect the signs of the original numbers.
/destroys: a, r6 - r8 (mgl)
DSmult:
Ida
2page+l, X
;get sign of multiplicand (hi-byte)
eor
zpage+1, y
;and compare with sign of multiplier
php
;save the result for when we come back
jsr
Dabs
/multiplicand = abs (multiplicand)
stx
r6L
;save multiplicand index
tya
/put multiplier index into x
tax
/for call to Dabs
jsr
Dabs
/multiplier = abs (multiplier)
Idx
r6L
/restore multiplier index
jsr
Dmult
/do multiplication as if unsigned
pip
/get back sign of result
bpl
90$
/ignore sign-change if result positive
jsr
Dnegate
/otherwise, make the result negative
rts
4
Dividing by Zero
Division by zero is an undefined mathematical operation. The two GEOS division routines (Ddiv
and DSdiv) do not check for a zero divisor and will end up returning incorrect results. It is easy to
divide-by-zero error checking to these two routines:
Example:
-k ic * ie * it * -k -k it it it it it it it it it ic it It it It it it it -k it 1i it it* It icic -kit it -kit it it it It it it it it it it it*
NewDdiv — Ddiv with divide-by-zero error checking
— DSdiv with divide-by-zero error checking
NewDSdiv
Pass :
Returns
Destroys
X zp address of dividend
y zp address of divisor
x,y unchanged
zp,x result
r8 remainder
a $00 — no error
%ff — divide by zero error
St set to reflect error code in accumulator
r9
Math Routines
DIVIDE BY ZERO = $ff
NewDdiv :
10$:
Ida
ora
bne
Ida
rts
jsr
Ida
rts
2page,y
2page,y
10$
#DIVIDE BY ZERO
Ddiv
#$00
/get low byte of divisor
;and high byte of divisor
;.if either is non-zero, go divide
/return error
; exit
/
/divide
/and return no error
NewDSdiv:
Ida
ora
bne
Ida
rts
10$:
zpage,y
zpage, y
10$
#DIVIDE BY ZERO
Apple
stx
.if
.endif
jsr DSdiv
.if Apple
Idx
.endif
Ida #$00
rts
Xsave
Xsave
get low byte of divisor
and high byte of divisor
if either is non-zero, go divide
return error
exit
save x-register because Apple destroys
divide
restore x-register because that ageos destroyed
and return no error
•if Apple
.ramsect
Xsave .block 1
.psect
.endif
temp x register save variable for ageos
6
rf/"^ Fonts, and Keyboard Input
Text, Fonts, and Keyboard Input
At one point or another, almost every application will need to place text directly on the screen or get
keyboard input from the user.
GEOS text output facilities support disk-loaded fonts, multiple point sizes, and additive style
attributes. The application can use GEOS text routines to print individual characters, one at a time,
or entire strings, including strings with embedded style changes and special cursor positioning
codes. GEOS will automatically restrict character printing to margins allowing text to be confined
within screen or window edges. GEOS even contains a routine for formatting and printing decimal
integers.
GEOS keyboard input facilities the translation of keyboard input to text output by mapping most
keypress so that they correspond to the printable characters within the GEOS ASCII character set.
GEOS will buffer keypresses and use them to trigger MainLoop events, giving the application
full control of keypresses as they arrive. And if desired, GEOS can also automate the process of
character input, prompting the user for a complete line of text.
Text Basics
Fonts and Point Sizes
Fonts come in various shapes and sizes and usually bear monikers like BSW 9, Humbolt 12^ and
Boalt 10. A font is a complete set of characters of a particular size and typeface. In typesetting, the
height of a character is measured in points (approximately 1/72 inch), so Humbolt 12 would be a
12 point (1/6 inch) Humbolt font. A text point in GEOS is similar to a typesetter's point: when
printed to die screen, each GEOS point corresponds to one screen pixel. GEOS printer drivers map
screen pixels to 1/80 inch dots on the paper to work best with 80 dot-per-inch printers.A GEOS
1/80 inch point is, therefore, very close to a typsetter's 1/72 inch point.
GEOS has one resident font, BSW 9 (Berkeley Softworks 9 point). The application can load as
many additional fonts as memory will allow. Fonts require approximately one to three kilobytes of
memory.
Proportional Fonts
Computer text fonts are typically monospaced fonts. The characters of a monospaced font are all
the same width, compromising the appearance of the thinnest and widest characters. GEOS fonts
are proportional fonts, fonts whose characters are of variable widths. Proportional fonts tend to
look better than monospaced fonts because thinner characters occupy less space than wider
characters; a lower-case "i," for example, is often less than l/5th the width of an upper-case "W."
Character Width and Height
Although some characters are taller than others, all characters in a given font are treated as if they
are the same height. This height is the font's point size. A 10 point font has a height of ten pixels.
If a character's image is smaller than 10 pbcels, it is because its definition includes white pixels at
the top or bottom. The height of the current font is stored in the GEOS variable curHeight.
Although fonts taller than 28 points are rare (some megafonts are as tall as 48 points), a font could
theoretically be as tall as 255 points.
1
Text, Fonts, and Keyboard Input
Because GEOS uses proportional fonts, the width of each character is determined by its pixel
definition — the thinner characters occupy fewer pixels horizontally than the wider characters.
Most character definitions include a few columns of white pixels on the right side so that the next
character will print an appropriate distance to the right If this space didn*t exist, adjacent characters
would appear crowded. The width of any single character cannot exceed 57 pixels after adding any
style attributes, which means that the plaintext version of the character can be no wider than 54
pixels.
The Baseline
Each font has a baseline, an imaginary line that intersects the bottom half of its character images.
The baseline is used to align the characters vertically and can be thought of as the line upon which
characters rest. The baseline is specified by a relative pixel offset from the top of the characters (the
baseline offset). Any portion of a character that falls below the baseline is called a descender. For
example, an 18 point font might have a baseline offset of 15, which means that the 15th pixel row
of the character would rest on the baseline. Any pixels in the 16th, 17th, or 18th row of the
character's definition form part of a descender. The baseline offset for the current font is stored in
the GEOS variable baseh'neOffset. The application may increment or decrement the value in this
variable to print subscript or superscript characters
The following diagram illustrates the relationship between the baseline and the font height:
The y-position passed to GEOS printing routines usually refers to the position of the baseline, not
the top of the character. Most of the character will appear above that position, with any descender
appearing below. If it is necessary to print text relative to the top of the characters, a simple
transformation can be used:
charYPos = graphicsYPos + baselineOffset
Where graphicsYPos is the true pixel position of the top of the characters, charYPos is the
transformed position to pass to text routines, and baselineOffset is the value in die global
variable of that name.
Styles
The basic character style of a font is called plaintext. Applying additional 5fy/e attributes to the
plaintext modifies the appearance of the characters. There are five available style attirbutes: reverse,
italic, bold, outline, and underline. These styles may be mixed and matched in any combination,
resulting in hybrids such as bold italic underline . The current style attributes are stored in the
variable currentMode. Whenever GEOS outputs a character, it first alters the image (in an
internal buffer) based on the flags in this variable:
2
7 6 5 4 3 2 1
I b7 I b6 I b5 I b4 I b3 I b2 I bl
Fonts, and Keyboard Input
b7
underline: 1 = on; = off.
b6
boldface: 1 = on; = off.
b5
reverse: 1 = on; = off.
b4
italic: 1 = on; = off.
b3
outline: 1 = on; = Off.
b2t
superscript: 1 = on; = off.
bit
subscript: 1 = on; = off.
bO
unused.
tSuperscript and subscript characters are not supported by the standard text routines. However, geoWrite
uses these bits in its ruler escapes. An application can print superscript and subscript by characters by
changing the value in baselineOffset before printing: subtracting a constant will superscript the
following characters and adding a constant will subscript the following characters. Additionally, some Apple
GEOS printer drivers support these two bits when SetMode is used to format ASCII output.
Normally it is not necessary to modify the bits of currentMode directly. Special style codes can
be embedded directly in text strings.
Style attributes temporarily modify the plaintext definition of the character and, in some cases,
change the size and ultimate shape of the character:
Underline
Inverts the pixels of the line beloy^ the baseline. The size of the character
does not change.
Boldface
The character image is shifted onto itself by one pixel. The width of the
character increases by one.
Outline
Transforms the character into an oudine style. This transformation occurs
after boldfacing and underUning. //e^^/^A 4 \h^c>4^ ^^u^e^^
Italic
Pairs of lines above the baseline are shifted right and pairs of lines below
the baseline are shifted left. Thus the baseline is not changed, the two
lines above it are shifted to the right one pixel, the next two are shifted
four pixels from their original position, and so forth. The effect of this is
to take the character rectangle and lean it into a parallelogranL The width is
not actually changed. The same number of italicized characters will fit on a
line as non-italicized characters, and because the shifting is consistent
from character to character, adjacent italic characters will appear next to
each other correctly. However, if a non-italic character immediately
follows an italic character, the non-italic character will overwrite right side
of the shifted italic character. This can be avoided by inserting an italicized
space character.
Reverse
Reverses the pixel image of the character. This is the last transformation to
take place. Thz Sx2f J}o6^ /v^^ OVW/vtc.
Note: Although, at this time, style attributes affect the printed size of a character in a
predictable fashion, the application should not perform these calculations itself but use
the GEOS GetRealSize routine to ensure compatibility with future versions of the
operating system. For more information, refer to "Calculating Character WidthCin diis
chapter. \^
r
lo
3
Text, Fonts, and Keyboard Input
How GEOS Prints Characters
When a character is printed, a rectangular area the width of the character and the height of the
current font is stamped onto the background, leaving cleared pixels surrounding the character.
When writing to a clear background, tihe cleared pixels around the character will mesh with the
cleared background, leaving no trace. But when writing to a patterned background, the background
will be overwritten:
Is stampea^\
background. J
There is no simple way to print to a non-cleared background without getting clear pixels
surrounding the characters. Solutions usually involve accessing screen memory direcdy.
Text and dispBufferOn
Like graphics routines, most text routines use the special bits in dispBufferOn to direct printing
to the foreground screen or the background buffer as necessary. For more information on using
dispBufferOn, refer to "Display Buffering" in Chapter @GR@.
GEOS 128 Character X-position Doubling
GEOS 128 text routines pass character x-coordinates through NormalizeX, allowing automatic
x-position doubling. (The character width is never doubled, only the x-position). Character x-
position doubling is very much like graphic x-positions doubling and is explained in "GEOS 128
X-position and Bitmap Doubling" in Chapter @GR@. There is one notable difference: because
smallPutChar will accept negative x-positions (allowing characters to be clipped at the left screen
screen edge), die DOUBLE_W and ADD1_W constants should be bitwise exclusive-or'ed into
the x-positions as opposed to merely bitwise"br*ed This will maintain the correct sign information
with negative numbers.
Character Codes
Each character in GEOS is referenced by a single-byte code called a character code. GEOS
character codes are based upon the ASCII character set, offering 128 possible characters
(numbered 0-127). GEOS reserves the first 32 codes (0-31) as escape codes. Escape codes are
non-printing characters that provide special functions, such as boldface enabling and text-cursor
positioning. Character codes 32 through 126 represent the 95 basic ASCII characters, consisting of
upper- and lower-case letters, numbers, and punctuation symbols. The 127th character is a special
deletion character, a blank space as wide as the widest character, used internally for deleting and
backspacing.
Most GEOS fonts do not offer characters for codes above 127 except in one special instance: the
standard system character set (BSW 9) includes a 128th character that is a visual representation of
the shortcut key (a Commodore symbol on Commodore computers and a filled Apple logo on
4
Fonts, and Keyboard Input
Apple computers). There is no inherent limitation in the text routines that would prevent an
application from printing characters corresponding to codes 129 through 159, assuming the current
font has image definitions for these character codes. The printing routines cannot handle character
codes beyond 159, however. The text routines do no range-checking on character codes; do not try
to print a character that does not exist in the current font.
A complete list of GEOS character codes appears in Appendix @TBL@,
Printing Single Characters
GEOS will print text at the string level or at the character level. The high-level string routines,
where many characters are printed at once, will often provide all the text facilities an application
evers need outside the environment of a dialog box. However, in return for generality, string-level
routines sacrifice some of the flexibility offered by character level routines.Character level routines,
where text is printed a character at a time, require the application to do some of the work: deciding
which character to print next and where to place it. Because of this overhead, t is tempting to
dispense with text at the character level, relying entirely on the string level routines instead. But the
character level routines are the basic text output building blocks and the string level routines depend
upon them gready. For this reason, it helps to understand character output even when dealing
entirely with string-level output
GEOS provides two character-level routines that are available in all configurations of GEOS:
• PutChar Process a single character code. Processes escape codes and only
prints the character if it lies entirely within the left and right
margins (leftMargin, rightMargin). ^
• SmallPutChar Draw a single character. Does not check margins for proper
placement. Does not handle escape codes. Prints partial characters,
clipping at margin edges.
And one routine that only exists in Apple GEOS:
• EraseCharacter Erase a character from the screen, accounting for the current font
and style attributes.
PutChar is the basic character handling routine. It will attempt to print any character within the
range 32 through 256 ($20 through $ff) as well as process any escape codes (character codes less
than 32), such as style escapes. It will also check to miake sure that the character image will fit
entirely within the left and right margins. SmallPutChar, on the other hand, carries none of the
overhead necessary for processing escape codes and checking margins; it is smaller (hence, the
name) and faster but requires that Ae application send it appropriate data. Do not send escape codes
to SmallPutChar.
Typically an application will call PutChar in a loop, using SmallPutChar to print a portion of a
character that crosses a marpn boundary. SmallPutChar can also be used by an appUcation that
does its own range-checking, thereby avoiding any redundancy. Be sure to only send
SmallPutChar character codes for printable characters.
PutChar and Margin Faults
Ptior to printing a character, PutChar checks two system variables, leftMargin and
rightMargin. When an application is first run, these two margin variables default to the screen
5
Text, Fonts, and Keyboard Input
edges (0 and SC_PIX_WIDTH-1, respectively). If any part of the current character will fall
outside one of these two margins, the character is not printed. Instead, GEOS jsr's through
stringFaultVec with the following parameters:
rll Character x-position. If the character exceeded the right margin, then this is the
position GECSs tried to place the offending character. If the character fell outside of
the left margin, then' the width of the offending character was added to the x-
position, making this the position for the next character.
r 1 H Character y-position.
Note: When Apple GEOS vectors through StringFaultVec, the current values of rll and
rlH are stored on the alternate zero-page. Do a sta ALTZP_ON before accessing
them and a sta ALTZP_OFF after accessing them. When the string fault routine
returns, PutChar will automatically copy these working registers over to the main
zero-page.
StringFaultVec defaults to $0000. Because GEOS uses the conditional jsr mechanism,
CallRoutine, a $0000 will cause character faults to be ignored.
There are many ways to handle a margin faults (including ignoring them entirely), . Faults on the
left margin are usually ignored or not even bothered with because printing will usually begin
predictably at the left margin, thereby precluding that type of fault. But faults on the right margin,
(which are less predictable) will often get special handling, such as using SmallPutChar to
output the fractional portion of the character that lies to the left of rightMargin.
There is one unfortunate problem with faults through PutChar: the fault routine has no direct way
of knowing which character should be printed and so will lose some of its generality by needing
access to chta that should be local to the routine that calls PutChar. One simple way around this
problem is to use a global variable — call it something like lastChar — to hold the character code
of the character being printed, or perhaps, make it a pointer into memory (PutString does just that
with rO). This way the fault routine will faiow which character caused the fault.
Example:
/macro: PutChar char (char « character code)
; Macro to replace jsr PutChar in your code so that lastChar
; holds the value of the last character printed
.*****************************************************************
.macro PutChar character
sta lastChar ; character is already in A-reg
jsr PutChar
.endm
Calculating the Size of a Character
Text foraiatting techniques such as right justification require the application to know the size of a
character before it is printed. GEOS offers two routines for calculating the size of a character:
6
Fonts, and Keyboard Input
• GetCharWidth
Calculates the pixel width of a character as it exists in the font (in
its plaintext form). Ignores any current style attributes.
• GetRealSize
Calculates the pixel height, width, and baseline offset for a
character, accounting for any style attributes.
These routines can be used in succession to calculate the printed size of any character combination,
whether groups of random characters, individual words, or complete sentences.
Partial Character Clipping
Confining text output to a window on the. screen is called clipping. Characters that will appear
outside the window*s margins are not printed; they are "clipped," so to speak. Sometimes,
however, it is desirable to print the portion of the offending character that lies within the margin
and only clip the portion that lies outside the window area. This sort of clipping is called partial
character clipping.
Top and Bottom Character Clipping
Both PutChar and SmallPutChar handle top and bottom partial character clipping. Any portion
of a character that lies outside of the vertical range specified by windowTop and
windowBottom will not be printed. windowTop and windowBottom default to the full
screen dimensions (0 and SC_PIX_HEIGHT-1, respectively). They may be changed by the
application before printing text" "
Left and Right Character Clipping with SmallPutChar
Whenever a character crosses the left or right margin boundary, PutChar vectors through
StringFaultVec without printing the character. SmallPutChar, unlike PutChar, will not
generate string faults. If a character crosses a margin boundary, SmallPutChar will print the
portidn of the character that lies within the margin.
SmallPutChar will also accept small negative values as the character x-position, allowing
characters to be clipped at the left screen edge by placing leftMargin at 0.
Note: Clipping at the left margin, including negative x-position clipping, is not supported by
early versions of GEOS 64 (earlier than version 1.4) — the entire character is clipped
instead. Left margin clipping is supported on all other version of GEOS: GEOS 64
vl.4 and above, GEOS 128 (in botii 64 and 128 mode), and Apple GEOS. Early
versios of Apple GEOS (versions earlier than 2.0.3) did not properly clip at the left-
margin.
Manual Character Clipping
Once of the criticisms of GEOS is the iconsistent and sometimes capricious character clipping
capabilities — not all versions of GEOS fully support partial character clipping and the versions
that do have inherent ideosyncracies. A carefully desilwd program can usually work around these
limitations. Some applications, however, will need a reliable method to perform partial character
clipping. The following ClipChar subroutine will properly clip and print a character Aat partially
exceeds one of the left or right margins. Be aware that ClipChar does quite a bit of caculation and
should only be used in special cases where controlled character clipping is needed.
Example:
7
Text, Fonts, and Keyboard Input
.if (0)
ClipChar — print a character, clipping to window margins.
Description:
Draw a character, clipping it EXACTLY to leftMargin, rightMargin,
windowTop and windowBottom
Operates by temporarily modifying the font definition (making the
character thinner, so as to fit in the margin) .
Pass :
a - character to print
rll - X position
rlH - y position
Return :
rll - X position for next char
rlH - y position for next char
Destroyed:
a, X, y, r2-rlOL
.endif
ClipChar:
sta
\e It tt It ic -k * * * it -k H
tit*it*1t'kittt1tiftftt'ttitit1tiHt
Idx
jsr
dey
tya
add
sta
Ida
adc
sta
rlL
currentMode
GetRealSize
rllL
r2L
#0
rllH
r2H
store character
get width of character
use width - 1 to calc last position
r2 = last pixel that char covers
3$:
5$:
10$:
CmpW
r2, leftMargin ,
•cfteck for char entirely off window
bit
3$
•if so then exit
CmpW
rightMargin, rll ,
bge
5$
AddWVW
r2,l,rll ;rll « one pixel beyond where char would
rts
; exit
Ida
rlL
•push old width table values
sub
#32
?get card #
sta
r3L
asl
a
tay
Idx
#0
Ida
(curlndexTable) , y
•store this char's index values
sta
savedWidths,x <
iny
inx
cpx
#4
bne
10$
'loop to copy values
CmpW
leftMargin, rll ,
bit
30$
Ida
r3L
asl
a 1
tay
Ida
leftMargin ,
check for clipping on left
8
Fonts, and Keyboard Input
30$:
50$:
60$:
sub
rllL
clc
adc
(curlndexTable) , y
sta
(curlndexTable) , y
inv
Ida
#0
adc
(curlndexTable) ,y
sta
(curlndexTable) ,y
MoveW
leftMargin, rll
CmpW
r2, rightMargin
bit
50$
Ida
r2L
sub
rightMargin
sta
r3H
Ida
r3L
asl
a
tav
iny
iny
Ida
(curlndexTable) , y
sub
r3H
sta
(curlndexTable) ,y .
iny
Ida
(curlndexTable) ,y
sbc
#0
sta
(curlndexTable) , y
Ida
rlL
pha
jsr
SmallPutChar
pla
sub
#32
asl
a
tay
Idx
#0
Ida
savedWidths, X
sta
(curlndexTable) ,y
iny
inx
cpx
#4
bne
60$
rts
check for clipping on right
save amount to subtract
draw the character ! !
save it for later
recover old widths
, ramsect
savedWidths :
.block 4
•psect
/values from index tabel stored here
Printing Decimal Integers (PutDecimal)
One of the unfortunate side-effects of binary math is the conversion necessary to print numbers in
decimal. Fortunately, GEOS offers a routine to remove this drudgery from the application:
rnputPecimal Format and print a 1 6-bit, positive integer H
PutDecimal is like a combination of character and string level routines. The application passes it
a single 16-bit, positive integer, some formatting codes (e.g., right justify, left justify, suppress
9
Text, Fonts, and Keyboard Input
leading zeros), and a printing position. PutDecimal converts the binary number into a series of
one to five numeric characters and calls PutChar to output each one.
String Level Routines
Many applications will never need complex text output and can rely on GEOS's string-level
routines for simple text output and input. GEOS provides two string-level text routines, one for
printing strings to the screen and one for getting strings through the keyboard
• PutString
Print a string to the screen.
• GetString
Get a string from the keyboard using a cursor prompt and echoing
characters to the screen as they are typed.
GEOS Strings
A GEOS string is a null-terminated group of character codes. (Null-terminated means the end of
the string is marked by a NULL character ($00).) These strings can contain alphanumeric
characters as well as special escape codes for changing the style attributes or changing the printing
position.
There is no basic limit to the possible length of a string; GEOS processes the string one character at
a time until it encounters the NULL, which it interprets as the end of the string. If the string is not
terminated, GEOS will have way of knowing where the end of the string is and will continue
printing until it encounters a $00 in memory.
A simple string of ASCII characters might look like this:
Stringl :
.byte "This is a simple string NULL
The above string, including the NULL, is 25 characters long (and therefore 25 bytes long also).
Escape codes may be emb^ded within the string to effect changes while printing. An individual
word, for example, may be underlined by embedding an ULINEON escape code before the word
and an ULINEOFF after it as in:
String2 :
.byte "This word is "
.byte OLINEON, "underlined", ULINEOFF,".", NULL
The embedded escape codes change the style attribute bits in currentMode mid-string, resulting
in something like:
This word is underlined .
PutString
PutString offers a simple way to handle text output. It is really does nothing more than call
PutChar in a loop, so issues that apply to PutChar, such as top and bottom character clipping,
also apply to PutString. PutString directly supports a feature that PutChar doesn't, though:
muWbyte escape codes, such as GOTOXY,which require rO to contain a pointer to the auxUiary
1
Fonts, and Keyboard Input
bytes in a multibyte sequence (PutString maintains rO automatically, allowing the extra
parameters to be embedded directly in the string). Printing a string to the screen with PutString
involves specifying a position to begin printing and passing a pointer to a null-tenninated string:
Example:
Example use of PutString. Places a test string onto the
screen. Assumes that leftMargin, rightMargin, windowTop and
windowBottom contain their default, startup values (full
screen dimensions) .
Print :
String:
STR_X
= 40
;x-position of first character
STR_Y
= 100
;y-position of character baseline
LoadB
dispBuffOn,#(ST_WR_
JORE 1 ST_WR_BACK) ;both buffers
LoadW
rll,#STR__X
/string x-postion
LoadB
rlH,#STR__Y
/string y-position
LoadW
rO,#String
/address of text string
jsr
PutString
/print the string
rts
/exit
.byte
"This is a test.",
NULL /null-terminated string
String Faults (Left or Right Margin Exceeded)
Because PutString calls PutChar, if any part of the current character will fall outside of
leftMargin or rightMargin, the character is not printed. Instead, GEOS jsr's through
stringFaultVec with the following parameters:
rll Character x-position. If the character exceeded the right margin, then this is the
position GEOS tried to place the offending character. If the character fell outside of
the left margin, then the width of the offending character was added to the x-
position, making this the position for the next character.
r 1 H Character y-position.
rO Pointer to the offending character in the string. Only valid with PutString, unused
by Putchar.
Note: When Apple GEOS vectors through StringFaultVec, the current values of rll, and
rlH, and rO are stored on the alternate zero-page. Do a sta ALTZP_ON before
accessing them and a sta ALTZP^OFF after accessing them. When the string fault
routine returns, PutString will automatically copy these working registers over to the
main zero-page>
GEOS 64 and GEOS 128 do nothing special to handle these string faults. If the application has not
installed its own string fault routine, stringFaultVec it should contain a default value of $0000,
which will cause the string fault to be ignored. If this is the case, the following will happen:
• If part of the character was outside of the left margin, the width of the offending
character was added to the x-position in rll before the fault. PutString moves on to
the next character in the string and attempts to print it at this new position.
1 1
Text, Fonts, and Keyboard input
• If part of the character was inside the left margin but outside the right margin,
PutString leaves the x-position unchanged and moves on to the next character in the
string.
The strategy behind this system is to only print the portion of the string that lies entirely within the
left and right margins. Unfortunately, this strategy is flawed. Whenever the right margin is
encountered, PutString should stop completely. But it doesn't. It continues searching through
the string, looking for a character that will fit. This can be a problem when a thin character follows
a wide character. For example, trying to print the word "working" with only a few pixels of space
before the right margin, PrintString would try to print the "w," but since it doesn't fit, would
move on and try its luck with the following "o." But the "o" won't fit either, so it moves on until it
encounters the "i," which just happens to fit in the available space. PutString proudly prints the
"i," thinking it has done a good thing, entirely unaware that the proper sequence of characters has
been lost.
The Apple GEOS version of PutString offers a partial solution to this problem. If
stringFaultVec contains $0000, it installs a temporary string fault routine (PutStringFault).
PutStringFault immediately terminates string printing on any fault (left or right margin) by
moving rO forward to point to the null. To disable the Apple PutStringFault so that Apple
GEOS PutString is identical to GEOS 64 and GEOS 128 PutString, point StringFaultVec to
an rts prior to calling PutString. PutStringFault can be implemented on GEOS 64 and GEOS
128 by placing the following routine into StringFaultVec prior to calling PutString:
PutStrFault (for GEOS 64/128 only)
String fault routine for duplicating the Apple GEOS PutString
fault handling on GEOS 64 and GEOS 128. Immediately terminates
string printing when any fault (left or right margin) is
generated by setting rO to point at the end of the string.
******************* €
PutStrFault :
;Go through the string looking for the null
Idy #1 ;load index to look at next character
bne ^'-^"'0$ 4 M' ; always branch — don't inc on 1st pass
20$:
IncW rO /check next character
10$: Ida (rO),y ;get character
bne 20$ ;loop until we find null
/Return to PutString pointing at a null
rts
The above technique, however, has two flaws: if a character lies outside the left margin, printing is
aborted, and, with either type of fault, the application has no way of knowing wjiich character in
the string caused the fault. The following routine, SmartPutString, will solve both these
problems. If a character lies outside the left margin, it is skipped, and if it lies outside the right
margin, SmartPutString returns with rO pointing to the character in the string that caused it to
terminate. If rO points to a NULL, then SmartPutString was able to print the whole string and
terminated noraially.
.if
. ****** ************* ************* *********************** **********
; SmartPutString
1 2
Fonts, and Keyboard Input
New front-end to PutString that handles right-edge string
; faults by exiting immediately rather than moving through
/ the string until it finds a character that fits. It operates
by replacing the current string fault service routine with
its own routine that tricks PutString into thinking it
; encountered a null on a right -margin fault.
/ Pass: same as PutString. The string must not be located
in zero-page ($00-$f f) .
; Returns: same as PutString, except that if the string
; faulted, then rl5 points to the offending character
rather than the null at the end of the string. If
rl5 = $0000, then the string printed without a fault
; Destroys: same as PutString.
; Note: No inline support.
.endif
SmartPutString :
/Insert our own string fault routine into stringFaultVec,
; saving the old one so that we can restore it when we leave.
PushW StringFaultVec ;save old
LoadW StringFaultVec, #FaultFix ; install new
; Clear the flag that alerts us to a right-edge fault. If the high
;byte of rl5 is zero then PutString returns immediately because
;our string never encountered the right edge.
LoadW rl5,#0 ; clear rl5 to $0000
;Call PutString with our string fault routine in place
jsr PutString
90$:
; Restore the old string fault routine
PopW StringFaultVec
; Return
rts
;FaultFix
;Our own string fault routine that sets up the string 'pointer
;so that PutString is tricked into thinking it encountered a
;NULL when the right margin is exceeded.
FaultFix:
; Check to see if we exceeded the right margin or if we just
; haven't reached the left margin yet. If the right margin was
;not exceeded, return early — the text routine handles this,
•case appropriately. If the first character in the string will not
;fit within either margin, we treat it as if the right margin was
; exceeded. Don't need to normalize the coordinates under GEOS 128
/because the character output routine has already taken care of
;this for us.
.if (APPLE) /Apple GEOS hides registers
13
Text, Fonts, and Keyboard Input
sta ALTZP_ON ;on aux. zpage.
.endif
CmpW rightMargin, rll /check x with right edge
ble 90$ ;exit if right not exceeded;
;the character was outside the
/left edge.
/Save the pointer to the offending character in rl5 (which is left
/untouched by the normal PutString)
Ida rOL
Idx rOH
.if (APPLE) /need to change rl5 on main zp if apple
sta ALTZP__OFF
.endif
stx rl5H
sta rl5L
.if (APPLE) /return Apple to
sta ALTZP__ON /aux. zpage.
.endif
/Change the string pointer so that PutString thinks the next
/character is a null.
LoadW rO, # (FakeNull-1) /one less to compensate for
/increment that PutString will
/do before it checks.
90$:
/Return to let PutString do its stuff
.if (APPLE)
sta ALTZP__OFF
.endif
rts /return to to StringFault caller
FakeNull: .byte NULL /null for FaultFix
. Embedding Style Changes Within a String
A string may contain embedded escape codes for changing the style attributes mid-string. For
example, if while printing a string GEOS encounters a BOLDON (24) escape code, then
PutString will temporarily escape from normal processing to set the boldface bit in
currentMode. Any characters thereafter will be printed in boldface.
Style changes are typically cumulative. If a OUTLINEON code is sent, for example, then the
outline style attribute will be added to current set of attirbutes. If boldface was already set, then
subsequent characters will be both outiined and boldfaced. The PLAINTEXT escape code
returns text to its normal, unaltered state.
When PutString is first called, it begins printing in the styles specified by the value in
currentMode and when it returns, currentMode retains the most recent value, reflecting any
style-change escapes. The next call to PutString (or any other GEOS printing routine) will
continue printing in that style. To guarantee printing in a particular style without inheriting any
style attributes from previous strings, the first character in the string should be a PLAINTEXT
escape code. Any specific style escape codes can then follow.
Position Escapes (Moving the Printing Position Mid-string)
GEOS provides escape codes for changing the current printing position. Like other escape codes,
tiiese can be embedded within the string. Some of them are simple, such as LF and UPLINE,
which move the current printing position down one line or up one line, respectively, based on the
14
Fonts, and Keyboard Input
height of the current font. Others, such as GOTOX, GOTOY, and GOTOXY, require byte or
woni pixel coordinates to be embedded within the string immediately after the escape code.
Example:
string:
.byte HOME ; start in the upper-left corner
.byte LF /move down one line. so we have room
.byte "This ",LF,"is LF, "stepping ",LF-
. byte "Down" , LF"ward" , CR
.byte LF, "HELLO"
.byte GOTOXY
.word 4 ;x-position
.byte 15 ;y-position of baseline
.byte "Look! I moved."
.byte NULL
Escaping to a Graphics String
GEOS provides a special escape code (ESC_GRAPHICS) that takes the remainder of a string
and treats it as input to the GraphicsString routine. This allows graphics command to be
embedded within a text string, which is useful for creating complex displays, especially those that
require graphics to be drawn over text. The current pen positions for the graphics arc unitialized so
the first graphics string command should be a MOVEPENTO.
Example:
TextGraphics :
.byte GOTOXY
.word 20
.byte 20
.byte "BOX:
.byte ESC__GRAPHICS
.byte MOVEPENTO
.word 10
.byte 10
.byte RECTANGLETO
.word 50
.byte 30
.byte NULL
Note: When GraphicsString encounters the NULL marking the end of a string, control is
returned to the application as if PutString had terminated normally. The NULL does
not resume PutString processing.
If it is necessary to print additional text after graphics, the ESC^PUTSTRING
command may be used to escape from GraphicsString. A subsequent NULL will
still mark the end of the string. Be aware that each context-switch between these two
routines allocates additional 6502 stack space that is not released until the NULL
terminator is encountered
GetString
; string with both text and graphics
GetString provides a convenient way for an application to get text input from the user without
using a dialog box. GetString takes care of intercepting keypresses and echoing the characters to
the screen. The beauty of GetString is that it builds the string concurrently with the rest of
Text, Fonts, and Keyboard Input
Unfortunately, there is no direct way to terminate GetString before the user presses [Return].
The trick of choice in this situation is to simulate a press of the return key by loading keyData
with a CR and vectoring through key Vector as in:
; simulate a CR to end GetString
LoadB keyData, #CR ;load up a CR (Return) key
Ida keyVector .;and vector through keyVector
Idx keyVector+1 ;so SystemStringService will
jsr CallRoutine ;think it was pressed now
This same technique can be used to terminate a DB GETSTRING when an icon is pressed to
leave a dialog box.
Note: The Apple GEOS version of GetString always keeps the partial string null-terminated
while it is building it in the buffer. An application can peek at the status of the string by
looking in this buffer. GEOS 64 and GEOS 128 (through vl.3) do not null-terminate
the string until [Return] is pressed (or simulated).
Fonts
In GEOS a font is a complete set of characters of a particular size and typeface. On disk, fonts are
organized by style, where a single font file holds all the available point sizes for a given style. Each
point size occupies its own VLIR record in the font file. The record number corresponds to the
point size. For example, a font file called MyFont might use three VLIR records, one for each
available font size: the MyFont 10 would occupy record 10, MyFont 12 would occupy record 12,
and MyFont 24 would occupy record 24.
It is the job of the application to decide which fonts to keep in memory at any one time, reading in
the appropriate records from the VLIR font file. Once a font is in memory (usually as the result of a
call to ReadRecord), the application must inform GEOS to begin using the new font with the
following routine:
• LoadCharSet Instruct GEOS to begin using a new font. (Font is already ir
memory.)
Because Apple GEOS allows font data to be stored in auxiliary memory, an additional routine is
provided for doing the equivalent of LoadCharSet when the font is in auxiliary memory
(LoadCharSet is still used when the font is in main memory):
• LoadAuxCharSet Instruct GEOS to begin using a new font. (Font is already in
auxiliary memory.)
Although the word "Load" in LoadCharSet and LoadAuxCharSet is misleading in that it
implies they automatically load the character set from disk into memory, the application must read
the font data into memory prior to calling these routines. LoadCharSet and LoadAuxCharSet
expect an address pointer to the beginning of the font in memory. It will then build out a variable
table for the text routines, providing information such as the baseline offset and font point height.
The application may keep as many fonts resident as free memory will allow, switching tiiem at will
with calls to LoadCharSet and LoadAuxCharSet . Some sophisticated GEOS applications use
a font-cacheing system where fonts are kept in memory based on their frequency of use.
GEOS provides an additional routine for returning to the always-resident BSW 9 system font:
1 8
Fonts, and Keyboard Input
I • UseSystemFont Instruct GEOS to begin using the default BSW 9 font.
UseSystemFont passes the address of the the system BSW 9 font to LoadCharSet.
The Structure of a Font File
Fonts are stored in VLIR files of GEOS type FONT, A single font file contains all the available
point sizes for a particular style (up to a maximum of 16). Each point size occupies one complete
VLIR record. The record number corresponds to the point size (i.e., record 9 would contain the
data for the nine point character set). If a VLIR record in a font file is empty, then the
corresponding point size is not available (the record will exist, but will marked as empty in the
index table). The data in each of these records is what GEOS considers a character set, and its
structure is described later in "Character Set Data Structure." Unless the application is creating or
modifying fonts, this data structure is unimportant,^
The font files on a given disk can be (ound^sing the FindFTypes routine. Once the font files
are known, the application can us^ G5fflBfInft>>^o access the header block for each font file. The
font file header block contains infotingtiojii^itineht to the particular font file, such as the font style
ID, the available point sizes, and the amount of memory required for each point size. These values
can be accessed in the header block by using the following offsets:
Offset
Field size Description
O GHFONTID
1 word
Font style ID.
O^GHPTSIZES
16 words
Character set ID's for those available in this
file. Arranged from smallest to largest point
size. Table is padded with zeros.
16 words
Size (in bytes) of each character set from
smallest to largest point size. (These numbers
have a one-to-one coorespondence with the
O^GHPTSIZES table. Table is padded with
zeros.
Every font style has a unique 10-bit ID number. This number is stored in the word-length field
O^GHFONTID. The next field, O^GHPTSIZES, has room for 16 character set ID numbers.A
character set ID number is a 16-bit combination of the style ID and a point size identifier. The style
ID is stored in the upper 10 bits and the point size is stored in the lower 6 bits:
Character Set ID Wordt
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
I 10-bit Style ID (b6-bl5) I point size (bO-b5)
b6-bl5 Style ID.
bO-b5 Point Size.
This combination of style ID number and point size gives each character set (font) a unique word-
length identifier. This allows any style/point-size combination to be referenced with a two-byte
number. For example, the Durrant style has a style ID of 15, so the Durrant 10 font would have a
character ID of
(15 « 6) I 10 or $03ca
1 9
Text, Fonts, and Keyboard Input
Berkeley Softworks' applications use the NEWCARDSET escape followed by the character set
ID word to flag font changes within a text document
Note: A complete list of font ID's for registered fonts appears in Chapter XX. Developers
wishing to register their own fonts should contact Berkeley Softworks in writing for
available ID numbers:
Berkeley Softworks
Attn: Font Registration
2150 Shattuck Avenue
Berkeley, CA 94704
Each request must include a disk with the font files along with the desired registration
names.
Character Set Data Structure
A character set is stored — both in memory and in its VLIR record — as a contiguous data
structure consisting of an eight-byte header, followed by an index table and the actu^ character
image data. The image data for the characters are stored in a bitstream format, pixel row by pixel
row. Imagine laying every printable character side by side, in character code order, starting with
character number 32 (the space character). If the top row of pixels from every character were then
stored together as a contiguous stream of bits, this would be the proper bitstream format. In
GEOS, for every pixel of height in a character set, there is a corresponding bitstream row. Starting
with the top row, each bitstream row is padded with zeros to make it end on a byte boundary. The
next row (if there is one) is appended at the next byte. The number of bytes in each bitstream row
is called the set width.J^
Because each character in a GEOS font can be of a different pixel width, GEOS needs some way
of induing into the bitstream data to find the beginning of each character. For each character there
is gjS»&Pindex werfTfliat indicates where the character begins in the bitstream. For example, if the
first pixel for the "A" character begins at pixel 148 in the bitstream, then the index value for
character code 65 (uppercase "A") would be 148.
20
Fonts, and Keyboard Input
Character Set Data Structure
Offset Field size Description IN
uyic
OaoCilllC UiioCl |(/lACio irUili LUp UL dlaiadCly.
+1
word
Bytes in one bitstream row (set width).
+3
byte
Font height, ("/vc^/^ 66/1. o/^ rizr%rneAm fio^%)
+4
word
Pointer to beginning of index table (relative to beginning of
data structure). Usually $0008 because the index table
follows immediately after theiieader. ^^Ah WQrt/O .
+6
1 word
Pointer to beginning of character bitstream data (relative to
beginning of data structure). Bitstream data typically follows
the index table.
^ •
; woras
inciex taoie. one wora entry lor eacn prmtaoie cnaracter (tne
first word corresponds to character code 32). Each index
word is pixel position of the character in each bitstream row.
Total number of words = number of printable characters in
the set.
+?
? bytes
Bitstream rows: one row of bitstream data for each pixel of
height in the character set. Each bitstream row ij padded
with ztxoi^'^x to the next byte. Total bytes?^ number of
printable characters in the set times the set width.
Saving and Restoring the Font Variables
In both GEOS 64 and GEOS 128/^1 the information GEOS needs for using a font is stored in the
variable table beginning at fontTable and stretching for FONTLEN bytes. Whenever GEOS
needs to switch fonts internally (while drawing the BSW 9 text fii^crtnenus, for example), these
bytes are saved off to saveFontTab, which is also FONTLEN bytes long. If a Commodore
GEOS application needs to temporarily change fonts, it can simply duplicate tins technique, saving
and restoring between fontTable and saveFontTab as needed.
Under Apple GEOS, however, not all the font information is accessible to applications. Apple
GEOS, therefore, includes two routines for saving and restoring all the necessary font table
information between its own variables and saveFontTab:
♦ SaveFontData
Save internal font data to saveFontTab.
• RestoreFontData
Restore internal font data from saveFontTab.
An application should never return to MainLoop with valid data in the saveFontTab
area^ecause MainLoop may use the saveFontTab area for its own purposes, thereby
destroying any font information that may be saved there. Of course, the information in
saveFontTab can always be copied to another buffer before giving MainLoop control.
When GEOS runs a desk accessory, it saves off all the current font variables to a special area of
memory. However, the temporal saveFontTab area is no(j;aved. If a desk accessory uses
menus, the menu routines will use the area at saveFontTab, thereby overwriting any saved data.
Since the saveFontTab area is not saved in die context switch between the application and the
desk accessory, it will come back with incorrect data. It is, therefore, the desk accessory's job to
save and restore the data at saveFontTab if necessary.
21
Text, Fonts, and Keyboard Input
Keyboard Input
Many keyboard input needs can be accomodated through normal processing with GetString and
through dialog boxes with DBGETSTRING, but many specialized functions require servicing
keypresses directly. The application might want to implement shortcut keys — special key
combinations that allow quick access t& menu items or other functions — or an application, such as
a word processor, might need to do dynamic text formatting as characters are typed.
Key-scan Conversion
The internal code that the computer hardware returns for each keypress usually reflects the position
of the key on the keyboard, not the actual character on the keycap. GEOS pre-processes all
keypresses, ignoring some and translating others. For most keys, the keyp ress is translated into
the GEOS ASCII character code equivalent: [a] translates to 97, [SHIFT] + [a] translates to 65,
and [RETURN] translates to CR. These keys can go directly to GEOS text routines wihtout any
further work. However, there are some key combinations that get translated outside of the printable
character range (codes between and 32), and the application will need to filter these out.
Note: Apple GEOS input drivers and aux-drivers both have the opportunity to preprocess or
translate keypresses before they undergo the standard GEOS translation. For more
information, refer to KeyFilter and AuxDKeyFilter in the Routine Reference
Section.
If the shortcut key (designated by the Commodore logo on CBM computers and the filled Apple
logo on Apple computers) is pressed in combination with another key, the high-bit (bit 7) of the
keypress byte will be set. This means, for example, that [SHORTCUT] + [a] is equivalent to
.byte (SHORTCUT I 'aM
How GEOS Handles Keypresses
At interrupt level, GEOS scans the keyboard looking for a key presses and releases. If a new key
has been pressed or an old key has been held down long enough to begin auto-repeating, GEOS
places the corresponding character code for the key at the end of the keyboard queue. The
keyboard queue is a circular FIFO (first-in, first-out) buffer that holds keypresses. A queue is used
because many typists can, at times, type keys faster than the application can process them. If there
was no key buffer, keypresses would be lost. As long as there are characters in in the keyboard
queue, the KEYPRESS^BIT of pressFlag is set.
On each pass through MainLoop, GEOS checks the KEYPRESS^BIT of pressFIag. If the
bit is set, GEOS removes the oldest keypress from the queue, places it in the global variable
keyData, and attempts to vector through keyVector. keyVector usually contains a $0000,
which causes GEOS to ignore the vector and, hence, ignore the keypress. As long as keyVector
is $0000, keypresses will continue to accumulate in die queue at interrupt level and be ignored, one
at a time, at MainLoop level.
By placing the address of a key-handling routine in keyVector^ the application can be called off
of MainLoop to process keypresses as they become available. When the application's key handler
gets called, it merely picks up the key code from keyData, does any necessary processing, and
returns to MainLoop with an rts when done.
22
Fonts, and Keyboard Input
With this technique, though, the application can only process one keypress on each pass through
MainLoop, even though the keyboard queue may have more than one character in it. This is
typically not a problem because the overhead most applications need to handle a character is
minimal. But take geoWrite, for example. If only one character could be processed at a time, it
might need to print, word- wrap, and scroll for each character. Even a medium speed typist could
get far ahead of the screen updating. If there was a way to get at all the keypresses in the queue at
once, then all the calculating and screen manipulations could be done for more than one character
on each pass through MainLoop. GEOS offers a routine to do just this:
I • GetNextChar Retrieve the next character from the keyboard queue!*
J
GetNextChar gets the keycode of the next available character from the keyboard queue and
returns it in the accumulator. If there are no more characters available, GetNextChar returns a
NULL. To retrieve all the queued keypresses, an application can call GetNextChar in a loop,
transferring all queued characters to its own buffer. This buffer must be at least KEY_QUEUE
bytes long so that it won't be overflowed.
Example:
KeyHandler
Sample key handler. Stuff address of this routine into
keyVector. Unloads the keyboard queue into an internal
buffer but does nothing with the characters.
KeyHandler :
Idx
Ida
sta
#0
keyData
newKeys, X
10$:
php
sei
inx
jsr
sta
cmp
bne
pip
GetNextChar
newKeys, X
#NULL
10$
; start at beginning of internal buffer
;get first keypress
; store it in my buffer
;lock out interrupts for a moement
;so we don't get any new keypresses
/point to next position in buffer
;get another character
;put it in our buffer
;was that the last
;loop back to get more
; restore interrupt disable status
/All new keys are now in our buffer. Our buffer is conveniently
/null-terminated because the last character we set down was a
/NULL. Neat, huh?
jsr DoNewKeys /go process the keys we picked up
99$:
rts
.ramsect
newKeys: .block KEY_QUEUE+1
.psect
/return to MainLoop
?max queue size + NULL
DoNewKeys
A do-nothing routine that just pretends to empty our own
23
Text, Fonts, and Keyboard Input
; keyboard buffer.
DoNewKeys :
Idx #$00 ; start at beginning of buffer
10$:
Ida newKeys,x ;get a key
beq 20$ -/exit loop if it's the null
nop ;do nothing with this keypress
inx /point to next position
bne 10$ /always branch (X should never go to 0)
20$:
•We've encountered the NULL and therefore gone through the entire
/string. Clear the buffer by storing the null in the first
/position of the string,
sta newKeys+0
99$:
rts /exit
Ignoring Keys While Menus are Down
Becuase MainLoop is still running full-speed when menus are down, keyVector will still ber
vectored through on a regular basis. The application may want to postpone any text output or
keypress interpretation when menus are down. Checking for this case is simple:
Ida menuNumber [ /check current menu level
bne 99$ I- ^ /leave if any menus are down
Implementing Shortcuts
Shortcut keys are a common user-interface facility found in GEOS applications. Briefly, a shortcut
key is a key combination that allows the quick selection of a menu item or function in the
application. Typically shortcuts are distinguished from other keypresses by pressing the shortcut
key (the Commodore logo or the filled Apple logo) while typing another key. Key combinations
that include the shortcut key will have the high-bit set, which maJkes them easy to recognize. Even
if an application is not using shortcuts, it will most likely want to at least filter out all shortcut keys.
To process shortcut keys, the normal key handler (the one the application installs into keyVector)
should first check the high-bit of the keypress and branch to the shortcut key handler if the bit is
set:
KeyHandle:
Ida
menuNumber
/check current menu level
bne
99$
^ . /ignore keys while menus
Ida
keyData
rrTget the keypress
bmi
10$
/was it a shortcut?
jsr
NormalKey
/no, process normally
bra
99$
/exit
10$:
jsr
ShortKey
/yes, process as a shortcut
99$:
rts
/exit
The shortcut key handler will need to decide what to do based on the key that was pressed Usually
the shortcut bit (bit 7) will be removed, the character will then be converted to uppercase, and the
resulting character code will be used to search through a table of valid shortcut keys. If the
particular shortcut key is not supported, the handler just returns, ignoring the keypress. If the key
is implemented, the handler needs to call an appropriate subroutine to process the shortcut key:
24
Fonts, and Keyboard Input
/Shortcut key handler. Call with keycode in A-register
ShortKey :
;Do some minor conversion on the keycode
and #-SHORTCUT
cmp # • a '
bit 10$
cmp #'z'+l
bge 10$
sec
she #('a'-»A')
/lop off shortcut bit
/check if lowercase
/branch if less than "a"
/or greater than "2" — ^
/it's lowercase: convert to upper
/by subtracting the ASCII difference—^
/between a lowercase 'a' and an
/uppercase 'A'
10$:
/Now that we have a shortcut key, we go searching through
/a table of valid shortcut keys, looking for a match. Use Y-reg
/to index so we can use X-reg later for CallRoutine.
20$:
Idy
cmp
beq
dey
bpl
bmi
#NUM__SHORTCUTS
shortcuts, y
30$
20$
99$
/start at top of table
/check for a keycode match
/branch if found
/else, try next
/loop until done. NOTE: must
/not have more than 127 shortcuts
/or this branch will fail!
/no match, ignore this key
30$:
/We've found a match. Get the corresponding routine address from
/the Jump table and call the routine
Idx h__shortCutTbl, y /get high address of routine
Ida l__shortCutTbl, y /and low address
jsr CallRoutine /call the routine
99$:
rts
/ exit
/Table of shortcut keys and their corresponding routines
/Valid shortcut keys
shortcuts:
.byte
•0'
/I
undo
.byte
1 fj* t
/2
text
.byte
.p.
/3
print
.byte
«Q«
/4
quit
.byte
ijjt
;5
new document
.byte
•G'
/6
goto page
.byte
•B*
/7
boldface toggle
.byte
•0'
/8
outline toggle
.byte
'I'
/9
italic toggle
.byte
•U'
/lO
underline toggle
.byte
•D'
/II
delete
.byte
•c
/12
copy
.byte
•S'
/13
scroll
.byte
/14
load document
NUM_SHORTCUTS
ss= { -k _
shortcuts
- 1) /numbe
.if (NUM__SHORTCUTS
> 127)
.echo
WARNING:
too many
shortcuts
.endif
25
Text, Fonts, and Keyboard Input
; Table of low bytes of shortcut routine
1 shortCutTbl:
.byte
[DoUndo ,
' 1
. byte
[DoText ,
' 2
. byte
luorrmt ,
• 3
• byte
lUOUUxt ,
A
H
. byte
(DoNew ,
' 5
• byte
lL/0(jOt , 1
» c
o
.byte
[DoBoldface ,
7
.byte
[DoOutline ,
8
.byte
[Doltalic
9
.byte
(DoUnderline ,
•10
.byte
IDoDelete ,
•11
.byte
(DoCopy ,
•12
.byte
[DoScroll t
•13
.byte
[DoLoad t
•14
; Table of high bytes of shortcut routine
h ShortCutTbl:
.byte
] DoUndo
;1
.byte
] DoText
;2
.byte
IDoPrint
;3
.byte
IDoQuit
;4
.byte
] DoNew
;5
.byte
]DoGoto
;6
.byte
3 DoBoldface
;7
.byte
] DoOutline.
;8
.byte
] Doltalic
;9
.byte
] DoUnderline
;io
.byte
] DoDelete
;11
.byte
] DoCopy
;12
.byte
] DoScroll
;13
.byte
] DoLoad
;14
The Text Entry Prompt
Whenever an application will be accepting text input, it is a good idea to offer a prompt, or cursor,
to mark the point at which text will appear. GEOS offers three routines for automatically
configuring sprite #1 to act as a text entry prompt:
• InitTextPrompt
Initialize sprite #1 for use as a text prompt.
• PromptOn
Turn on the prompt (show the text cursor on the screen).
• PromptOff
Turn off the prompt (remove the text cursor from the screen).
The prompt automatically flashes on the screen without disrupting the display and can be resized
to reflect die point size of a particular font
26
Fonts, and Keyboard Input
Important: Interrupts should always be disabled and alphaFlag should be cleared when
PromptOff is called. The following subroutine illustrates the proper use of
PromptOff:
KillPrompt :
php /save i status
sei > /disable interrupts
jsr PromptOff /prompt « off
LoadB alphaFlag, #0 — ^lear alpha flag ^
pip /restore i status
rts /exit
Sample Keyboard Entry Routine
As an example, we will use some of the concepts covered in this chapter in real-world code. The
following routine will patch into key Vector and output text as keys are pressed:
/*** CONSTANTS ***
TXT_LEFT ==10
TXT_RIGHT == (SC_PIX_WIDTH - TXT_LEFT)
TXT_TOP ==20
TXT__BOT == (SC PIX HEIGHT - TXT TOP)
/text (x,y) starting position
TXT_X ==20
TXT_Y ==50
/size of the text buffer
TXTBUFSIZE == $200
/text left margin
/text right margin
/text top margin
/text bottom margin
/1/2K is far more than enough for ^
/now. To accept multiple lines,
/the buffer will need to grow
/Characters to accept before buffer overflow fault
MAX CHARS 30
if
Start Text :
Initializes the text input process by loading the proper
vectors, setting flags, etc. Wedges Keyin into keyVector to
intercept keypresses and output them to a single line.
Pass: nothing
Returns: text input routine in keyVector
Destroys: ?
endif
StartText:
/Send our text output to both screens
LoadB textDispBufOn,#(ST_WR_FORE | ST WR BACK)
27
Text, Fonts, and Keyboard Input
/Install our character handler
LoadW keyVector, #KeyIn /keypresses vector thru here
LoadW stringFaultVec,#TextFault /and string faults here
/Install the system font and clear all text attributes
jsr UseSystemFont-
Ida #PLAINTEXT
jsr PutChar
/Set the left and right margins
LoadW leftMargin, #TXT_LEFT
LoadW rightMargin,#TXT_RIGHT
/Set the top and bottom margins
LoadW windowTop, #TXT_TOP
LoadW windowBottom,TXT_BOT
/Set the text starting position
LoadW stringX, #TXT_X
LoadB stringy, #TXT__Y
/Initialize the prompt
Ida currentHeight
jsr InitTextPrompt
jsr PromptOn
/Point at the start of the line buffer
LoadW txtBuf ,#bigTextBuffer /where to start
LoadB txtBuf Index, #0 /index from start
/Max number of characters to accept
LoadB txtlnMax, #MAX_CHARS
/And where control goes if we go over...
LoadW bufFaultVec,#Buf Overflow
/Turn text on •
LoadB textOn, #TRUE
/Exit
rts
.ramsect
/Buffer that will hold all the text we enter. We let the key input
/routine build it up a line at a time by passing
bigTextBuf fer: .block TXTBDFSIZE
textDispBufOn: .block 1 /holds dispBufferOn value for text
txtlnMax: .block 1 /number of characters that will
/generate buffer overflow fault
textOn: .block 1 /text is ON flag. (TRUE « ON)
.if ((* & $ff) $ff) /if indirect jump vector straddles a page
.block 1 /boundary, fix it to compensate for a bug
.endif /in the 6502 architecture ^
bufFaultVec .block 2
.psect
★★***************************************************************
KeyIn:
When a key is pressed, control comes here off of MainLoop
28
Fonts, and Keyboard Input
Keyin:
10$:
99$:
Ida menuNuiTiber
bne 99$
Ida keyData
brr.i 10$
jsr Norrr.alKey
bra 99$
jsr ShortKey
rts
; check current menu level
/ignore keys while menus down
;get the keypress
;w'as it a shortcut?
/no, process normally
/exit
/yes, process as a shortcut
/exit
/ShortKey:
/Control comes here when shortcut keys are pressed
ShortKey:
rts
/no shortcut key handler now. just ignore keypress.
.**★*★«********«*★****«★**«♦«**** *«*******************************
/NormalKey :
/Control comes here when non-shortcut keys are pressed
SPACE
32
/first printable character code
NormalKey:
/Return immediately if text is off
Ida textOn
bne
rts
5$
/branch if text on
5$:
jsr
KillPrompt
/turn the prompt off
/Save the current value of dispBufferOn and load up the correct
/value for text output.
PushB dispBufferOn
MoveB textDispBuf On, dispBufferOn
/Load the current cursor position into the PutChar position
/registers, just in case we need to use them later.
MoveW stringX,rll
Ida stringY
clc
adc baselineOf f set
sta rlH
/X printing position
/convert y cursor position to
/baseline position
/y printing position
/Process the character
Ida keyData
cmp #SPACE
bge 4 0$
/get the keypress again
/cmp with first printable char
/branch if printable
/Check the control character against a table of special action
/keys. Use Y-reg to index so we can use X-reg later for
29
Text, Fonts, and Keyboard Input
;CallRoutine .
Idy
20$:
cmp
beq
dey •
bpl
bmi
#NUM_CTRL ; start at top of table
i
ctrlKeys,y /check for a keycode match
30$ ;branch if key matches table entry
;else, try next '
20$ ;loop until done. NOTE: must not
./have more than 127 special keys
/or this branch will fail!
88$ /no match was found, ignore this key
30$:
/We've found a match on a
/routine address from the
Idx . h__CtrlTbl,y
Ida l_CtrlTbl,y
jsr CallRoutine
bra 88$
4 0$:
/It's a normal alphanumeric
/screen and save it in the t
pha
control character. Get the corresponding
jump table and call the routine
/get high address of routine
/and low address
/call the routine
/go clean up and exit
Idy
sta
iny
Ida
sta
sty
pla
Dsr
MoveW
Ida
cmp
bit
Ida
Idx
jsr
88$:
/Clean up
Ida
beq
jsr
txtBuf Index
(txtBuf ) ,y
#NULL
(txtBuf) ,y
txtBuf Index
99$:
PopB
rts
PutChar
rll, stringX
txtBuf Index
txtlnMax
88$
bufFaultVec
bufFaultVec+1
CallRoutine
textOn
99$
Prompt On
dispBuf ferOn
character. Output it to the
ext buffer
save the character code
pointer into current text buffer
place the character into the buffer
point to next position in buffer
and null-terminate the string
set down the new index value
get the character code back. (Note:
we could have pulled it off of
keyData, but future versions may
pre-process or translate the char
code in the A-reg before passing)
print it on the screen
update the prompt X-position
was that the last character we
can accept?
OK if under max.
otherwise, call buffer overflow
routine
/only re-enable the prompt if text
/is still on (might have changed!)
/turn the prompt back on
/restore dispBufferOn
/ Exit
Table of control keys and their corresponding routines
/Valid control keys
ctrlKeys :
.byte CR
.byte BACKSPACE
.byte KEY_DELETE
.-byte KEY INSERT
1 Carriage return
2 backspace
3 ditto
4 ditto
30
Fonts, and Keyboard Input
.byte KEY__RIGKT ;5 ditto
NUM_CTRL == (* - ctrlKeys - 1) ; number of control keys
.if (NUM__CTRL > 127)
.echo WARNING: too many control keys
.encif
; Table of low bytes of control key routine addresses
l_CtrlTbl:
.byte [DoReturn ;1
.byte ' ' (DoBackSpace ;2
.byte [DoBackSpace ;3
.byte (DoBackSpace ;4
.byte [DoBackSpace ;5
; Table of high bytes of control key routine addresses
h__CtrlTbl:
.byte ] DoReturn
.byte ] DoBackSpace
.byte ] DoBackSpace
.byte ) DoBackSpace
.byte ) DoBackSpace
; Exit
rts
. ramsect
tempDisp: .block 1
sysKeySave: .block 2
.psect
.**«««**«★***★***★★★★★*★**★★★★★★******★★****«*********************
;KillPrompt:
/Proper way to use PromptOff. Disable interrupts and
/clears alphaFlag. •
t
KillPrompt :
php /save i status
sei /disable interrupts
jsr PromptOff /prompt « off
LoadB alphaFlag, #0 /clear alpha flag
pip /restore i status
rts /exit
/DoReturn:
/Process a carriage return
J
.★***«*****★★****★★★*★**★*★*********★*★*****★*******★***★★
DoReturn :
/No real carriage return handler, yet. Just shut text off
LoadB textOn, #FALSE /
rts / . . .
.*******★*********★*★★★****★*****«*******★***********★*★*★★***
/DoBackSpace:
»
/Process a- backspace
/temporary hold for dispBufferOn
/holds address of system key routine
31
Text, Fonts, and Keyboard input
DoDoBackspace:
Idy
txtBuf Index
;get ptr into current text buffer
beq
99$
;if no characters in buffer, exit
dey
/back up a character
sty
txtBuf Index
7 and make the new index permanent
Ida
(txtBuf ) ,y
;get the character we want to delete
jsr
EraseCharacter
/and remove it from the screen
Idy
txtBuf Index
/get the index to the character we
Ida
#NULL
/we just deleted and make it the
sta
(txtBuf ),y
/ null-terminator
MoveW
rll, stringX
/update the cursor's x-position
rts
/exit
'k**'kit*ie**'k-kitit'k1r-teicie-te1e*ieieif*ie1eieieie*ic1iitirieielrieicie***
EraseCharacter:
Physically remove a character from
.if (C64 II C128) /This routine
EraseCharacter :
10$:
.endif
MoveW
rll,r4
Idx
currentMode
jsr
GetRealSize
sta
r3L
Ida
rlH
sec
sbc
r3L
sta
r2L
txa
clc
adc
r2L
sta
r2H
sty
r3L
sec
sbc
rllL
sta
r3L
Idy
rllH
bcs
10$
dey
sty
r3H
jsr
Rectangle
rts
the screen
is in the Apple GEOS jump table
/current X is rectangle's right edge
/get the mode we're in
/go calc the size of the character
/set down baseline offset
/calc top of character by subtracting
/baseline offset from y-position
/and making top edge of rectangle
/add char height to top edge
/to calc bottom edge
/and make bottom of rectangle
/set down width so we can subtract it
/from the current x-position to
/find the character's starting
/position
/subtract one from hi if borrow
/make left edge of rectangle
/erase in current pattern
/exit
Buf Over flow:
What to do if the buffer hits its maximum.
BufOverflow:
/No real overflow handler, yet. Just shut text off
LoadB textOn,#FALSE /
rts
/Text Fault:
32
Fonts, and Keyboard Input
; string faults come here.
**************************************************
TextFault :
/No real text fault handler, yet. Just shut text off
LoadB textOn, #FALSE
rts ;
33
MainLoop and Interrupt Level: a Technical Breakdown
MainLoop and Interrupt Level: a
Technical Breakdown
The GEOS Kemal operates on two distinct levels: MainLoop Level and Interrupt Level. MainLoop
Level is characterized by the GEOS MainLoop — a never-ending loop at the heart of GEOS that
routes events to the application. Whenever the application does not have control, MainLoop
usually does.
But there is also Interrupt Level. Periodically (usually every l/60th of a second) the computer
hardware temporarily interrupts the microprocessor. The processor may be in the middle of
MainLoop, deep within a GEOS routine, or somewhere in the applcation. Either way, the 6502
immediately suspends whatever it is doing and passes control to the GEOS Interrupt Level.
Interrupt Level scans the keyboard circuitry, moves the mouse pointer, flashes the text prompt,
decrements timers, and performs other low-level tasks. Interrupt Level operates independently of
MainLoop and ensures that certain things get done on a regular basis. When the Interrupt Level
processing is complete, control returns to the point where the original interrupt occurred.
Whatever GEOS does at Interrupt Level is mostly transparent to the application. Only when an
application strays from the beaten path will it need to worry about the specifics of Interrupt Level
processing.
This is a technical discussion of MainLoop and Interrupt Level. For a more general
discussion, refer to Chapter @GEOSAPPS@.
MainLoop Level
When GEOS starts an application, it first initializes the operating system and then jsr's to the
application's start address. The application is expected to perform its basic startup procedures,
such as initializing its menus, icons, and processes, and the return immediately with an rts. This
rts will place GEOS at the beginning of MainLoop. MainLoop is primarily a small, endless
loop of function calls:
MainLoop Service Routines
MainLoop itself is rather short. The meat of its function is hidden in the various service routines
that it calls. Because these service routines interact direcdy with the application, it is useful to
understand the specific conditions that affect their operation. The pseudo-code diagrams at the end
of this chapter illustrate the operation of the more important service routines.
Patching Into MainLoop
Although most applications can function entirely off of events, some may find the need to install
their own service routine direcdy off of MainLoop. GEOS has a single vector for tiiis purpose:
appIicationMain, which usually contains $0000 and is therefore unused. By placing a routine
address into this vector, GEOS will call through tiiis vector every pass through MainLoop. To
remove tills call, tfie application can again store $0000 into the vector.
1
MainLoop and Interrupt Level: a Technical Breakdown
The Basics of Interrupt Level
Interrupt Level is primarily responsible for maintaining the interactive and time-based apsects of
GEOS. Interrupt Level updates the mouse state and the mouse cursor position, watches for double-
clicks, decrements process and sleep timers, gets keyboard input, flashes the prompt, and
generates a new random number every vblank, among other (more obscure) tasks.
The Vertical Blank Interrupt
The Interrupt Level interrupt is tied directly to the video circuitry. In order to keep the screen
phosphors glowing, the image must be redrawn, or refreshed, many times per second. Each
complete coverage of the picture tube is called 2i frame, and the rate at which frames are drawn is
cailtdthtframe rate or refresh rate.
At the end of each frame, the electron beam is switched off and returned to the upper left comer of
the picture tube to begin drawing again. This period when the beam is off is called the vertical
blank, or vblank. Every vblank, the IRQ (Interrupt ReQuest) line on the 6502 is pulled low. If the
interrupt disable bit in the status register is clear (asit usually should be), an interrupt is generated.
This interrupt is often called the vblank interrupt. ^EOS uses the vblank interrupt as the basis for
its Interrupt Level processing.
The vblank interrupt, along with the scanning of the video frame, occurs in a precisely timed
sequence: 60 times per second on NTSC monitors (the United States standard) and 50 times per
second on PAL monitors (the European standard).The GEOS FRAME^RATE constant reflects
the number of frames per second (either 50 or 60) depending on the state of the PAL and NTSC
constants.
How to Disable Interrupts
Because the vblank interupt is an IRQ (Interrupt ReQuest), the 6502 has the option of ingoring the
request. To disable IRQ interrupts, an application need only set the interrupt disable bit in the
6502*s status register using the sei (SEt Interrupt disable bit) instruction. Because GEOS depends
on Interrupt Level executing on a timely basis, an application should disable interrupts only when
absolutely needs to and then only for short periods of time. If an interupt occurs while the
interrupt-disable bit is set, the interrupt will not be serviced. If too many interrupts are missed,
much of the real-time features of GEdS — the mouse pointer, processes, double click detection,
etc. — will become sluggish.
In conventional 6502 programming, it is standard practice to surround blocks of interupt-sensitive
code with an sei-cli sequence: an initial sei to disable interrupts and an ending cli to reenable
interrupts. This, however, is not a totally safe practice because the cli always reenables interrupts
regardless of their original state. If interrupts were originally disabled, the cli may inadvertently
reenable them. As applications get large, it becomes easier to embed these interrupt disable/enable
sequences deep within subroutines. If one subroutine disables interrupts then calls another
subroutine that then performs a cli (returning with interrupts enabled when they shouldn't be), the
results may be a disasterous bug.
It is good to practice a littie defensive coding and get into the habit of saving the interupt status
when disabling them around blocks of code. The following sequence works well:
php ;save current interrupt disable status
sei /disable interupts
; (interrupt-sensitive code goes here)
2
MainLoop and Interrupt Level: a Technical Breakdown
pip
/restore old interrupt status
This php-sei-pip method will save, set, and then restore the interrupt disable bit. This way
interrupts won't be inadvertently reenabled when they're expected to be disabled.
Apple GEOS Interrupts
Unlike the Commodore computers, the Apple He does not generate its own vblank IRQ interrupts.
This function is usually provided by external hardware plugged into slot 7: the Apple mouse card
or the Berkeley Softworks IRQ Management Card. If neither of these devices is present and there
is no other interrupt source, Apple GEOS will generate software interrupts.
Apple Software Interrupts
GEOS may occasionally be run on systems with no interrupt source. This is an unfortunate
situation because GEOS depends heavily on interrupt processing. GEOS will recognize this
configuration and generate software interrupts during MainLoop by calling IrqMiddle. With
applications that don't have time-consuming event routines hanging off of MainLoop, Interrupt
L^vel processing will occur often enough to make the system usable. If system degradation is too
great, an application can simulate its own software interrupts as necessary. For more information,
refer to IrqMiddle in the Routine Reference Section.
Example:
DoSoftlnts
Description: Simulate vblank interrupts under Apple GEOS when no interrupt source is
present.
Pass: nothing
Destroys: a,x,y
DoSoftlnts:
bit
bne
php
sei
Jsr
pip
10$:
intSource
10$
IrqMiddle
; check interrupt source
;exit if hardware interrupt source
;else, generate soft interrupt
/disable interrupts (just in case)
/software interrupt now!
/restore old interrupt status
The Apple GEOS Interrupt Management Card
The Berkeley Softworks JRQfManagement card requires reenabling after every interrupt in order to
generate next interrupt. Part of the Apple Interrupt Level processing reenables the IRQ G enei aio i^
card to interrupt on the next vblank. Normally this will keep interrupts triggering on a regular
basis.
^miSrd^r
However, if the«Q44anagemem^ard generates an interupt while the 6502 interrupt disable bit is
set, the interrupt service routine will not run, and the IRQ Management card will never be
reenabled for the next interrupt
Co,
ho
MainLoop and Interrupt Level: a Technical Breakdown
Apple GEOS attempts to keep interrupts running by reenabling the IRQ Management card during
MainLoop and whenever a call through the jump table switches banks. Normally applications
will do this often enough in their normal operation to reenable the IRQ Management card ron a
regular basis. It is conceivable, however, that in some very odd cases neither of these
circumstances will occur often enough (very odd cases, indeed — if an application is both disabling
interrupts and not going back to MainLoop, there is probably something fundamentally wrong
with the structure of the program). An application can reenable the IRQ Management cardwhen
necessary with the following sequence:
bit intSource
bvc 5$
St a IRQ__GEN
5$:
; check the interrupt source
/ignore if not BSW card IRQ Manager
/otherwise, trigger IRQ Manager
J
Important Things to Know About Interrupt Level
The vblank interrupt service routine is one of the most complex aspects of GEOS. Fortunately,
most applications will need to know little more about the Interupt Level process than its basic
functionioning. However, there are some unavoidable conflicts between Interupt Level and
normal, mainstream processing, and these are important to know.
Two-byte Variables
During non-interrupt level processing, it is important to disable interrupts before referencing a
word value that might get changed at Interrupt Level or changing a word value that might get
referenced at Interupt Level. A two-byte quantity requires two memory accesses, and there is a
small chance that an interrupt may occur after the first byte has been accessed but before the second
byte has been accessed. This can result in a situation where a word value has the high-byte of one
number and the low- byte of another. Take for example the variable mouseXPos, which is
modified at Interrupt Level. The seemingly innocent code fragment below illustrates the problem:
MoveW mouseXPos, oldX /update our old mouse x-position with current mouse x
Which exands to the following at assembly time:
Ida mouseXPos /update our old mouse x-position with current mouse
sta oldX
Ida mouseXPos+1
sta oldX+1
If an interrupt occurs between the Ida mouseXPos and the subsequent Ida mouseXPos+1,
the result word result stored in oldX may be entirely wrong. The solution is to temporarily disable
interrupts around the access:
php ; disable interrupts around access
sei ;
MoveW mouseXPos, oldX /update our old mouse x-position with current mouse x
pip ; restore old interrupt status
Be aware, though, that the php-sei-pip sequence has its own set of ideosyncracies: the pip
restores the entire status register, not just the interrupt disable bit, thereby overwriting any new
condition codes. Therefore, disabling as in
php ; disable interrupts around compare
sei ;
4
MainLoop and Interrupt Level: a Technical Breakdown
CmpW mouseXPos, oldX /compare current X with Old X
pip '/restore interrupts
would defeat the whole purpose of the CmpW. In such cases, the condition codes can, of course,
be tested before the pip. A better solution, however, would disable interrupts, shadow the word
value to a temporary variable, restore the interrupt disable status, then do all checking against this
temporary value, which won't get changed by Interrupt Level.
Example:
/Check if mouse is within the left and right text margin
IsMselnMargins:
10$:
20$:
99$:
php
sei
MoveW mouseXPos,rO
pip
CmpW
bge
Ida
beq
CmpW
ble
Ida
beq
Ida
rts
rO, leftMargin
10$
#FALSE
99$
rO, rightMargin
20$:
#FALSE
99$
#TRUE
disable interrupts around mouseXPos access
and copy current pos to a working location
restore interrupts
/check left margin
/branch if inside left
/else, flag fault
/branch always to exit
/check right margin
/branch if inside right
/else, flag fault
/branch always to exit
/no fault (inside text margins)
/exit
Word variables to be careful with include mouseXPos, mouseLeft, mouseRight,
intTop Vector, and intBot Vector, all of which are either read or written to by Interrupt level.
The Decimal Mode Flag
GEOS adopts the convention that the normal operating state of the computer has decimal mode
disabled. Any routine that enables decimal mode must also disable it Versions of GEOS 64 prior
to V 1.2 do not disable decimal mode during interrupt level processing. If operating under one of
these versions, it is necessary to disable intemipts prior to using the decimal mode flag.
Patching Into Interrupt Level
Very few applications will need access to the system at Interrupt Level. Most tasks that would
traditionally require the use of a time-based interrupt can be handled deftly enough with GEOS
processes. If an application can drive itself entirely off of MainLoop events, it should. The world
of Interrupt Level is a delicate one; it is very easy to disrupt the entire system by doing the wrong
thing during Interrupt Level. With that said, though, GEOS provides two vectors that allow an
application that knows what it's doing to tap directly into Interrupt Level: intTopVector and
intBotVector.
As illustrated in the Interrupt Level pseudo-code at the end of this chapter, control passes through
these two vectors at different points in the intermipt process. intTopVector allows the
application to patch in before most of the Interrupt Level processing has occurred and
intBotVector allows the application to patch in after most of the Interrupt Level processing has
occurred.
5
MainLoop and Interrupt Level: a Technical Breakdown
Important: The application should always disable interrupts before loading a new address into
either intTopVector or intBot Vector. The program will very likely crash if this
precaution is not taken.
(
System Use of intTopVector and intBotVector
GEOS 64 and GEOS 128 use intTopVector to point to InterruptMain, a vital function of the
Commodore GEOS Interrupt Level, whereas Apple GEOS does not use either of these vectors.
The application can use either intTopVector or intBotVector under Apple GEOS without any
worry. However, under Commodore GEOS, an application that uses intTopVector should call
the address that was originally in intTopVector when it is done.This will ensure that the
Commodore GEOS InterruptMain will be executed properly.
Example:
; Install our interrupt routine into intTopVector
Installint :
php /disable interrupts
sei
MoveW intTopVector, oldTopVector ;save address of current routine
LoadW intTopVector, #MyIntRout /install our interrupt routine
pip /restore interrupts
rts
/Remove our interrupt routine from intTopVector, replacing it with old.
Removeint
php /disable interrupts
sei
MoveW oldTopVect or, intTopVector /restore old routine
pip /restore interrupts
rts
/My interrupt service routine
MylntRout :
Ida OldTopVect or
Idx oldTopVector+1
jmp CallRoutine
/nothing to do yet...
/exit by vectoring through
/old interrupt routine
/let it rts. . .
Guidlines for Interrupt Level Routines
There are a few general guidelines for any routine that patches into Interrupt Level:
• Keep the routines short Interrupt level is not the place for time-consuming code.
• Stay away from GEOS. Some routines will work correctly at interrupt level and other
won't. Even worse, the ones that won't work might only show this trait after your
product has been released and in the hands of users for months. (It is O.K., though, to
use CallRoutine, as many of the examples in this chapter illustrate.)
• Never clear the interrupt disable bit
Following these guidelines will keep your Interrupt Level routines as innocuous as possible.
6
MalnLoop and Interrupt Level: a Technical Breakdown
Interrupt Level Pseudo-Code
The following pseudo-code diagrams illustrate the general Interrupt Level constructs in each of the
three systems (GEOS 64, GEOS 128, Apple GEOS). This information can be crucial when trying
to track down a subtle interaction between the various levels of GEOS.
GEOS 64 and GEOS 128 Interrupt Level
CBMInterruptLevel:
{
/ • Context Save:
Save out any information about the system configuration that we might destroy V
Save6502Regs(); r save the status of the A. X, Y. and S registers V
SaveGEOSRegsQ; /* save r0-r15 and a few internal variables*/
SaveCBMState(); /* save state of Commodore memory banks V
SetlOInO; /* set RAM 1 and I/O registers in. Much of Kernal
is now inaccessibieV
DblClicksO; T decrement dblClickCount if non-zero V
if (GEOS128)
{ DoMouse(); r GEOS 128 updates mouse here V
DoSetMouseO; /*and also calls SetMouse in mouse driver. SetMouse
doesn't exists in GEOS 64 input drivers.*/
}
DoKeyboardO; r scan the keyboard and add a char to the queue if key pressed V
DoAlarmSndO; r update timer for alarm sound duration */
/ * Application can patch into the following two vectors. The application's routine should
always end by indirectly calling the routine whose address was originally installed in
the vector. Use CallRoutine in the Kernal (it's bank is in) in case the pointer is $0000.
* /
Calllndirect(intTopVector) /* call indirectly through intTopVector. On the C64/128, this
points to InterruptMain. */
Calllndirect(intBotVector) /* call indirectly through intBotVector. This is usually
$0000, which Calllndirect ignores. */
/* Context Res^re: S>^i//?/D
AP5/t>^<:©avB otrt-atTyinformation about the system configuration that we^ might doot fof^/
RestoreCBMStateO
RestoreGEOSRegsO
Restore6502Regs()
r put memory banks back as they were */
r restore r0-r15, etc.*/
r restore A, X, Y, and S registers */
ReturnFromlRQO; T pick up where we left off */
)
7
MainLoop and Interrupt Level: a Technical Breakdown
GEOS 64 and GEOS 128 interruptMain
InteruptMain:
Called through intTopVector under GEOS 64/128. This is *VERY* different from
InterruptMain under Apple GEOS!
InterruptMain:
{
if (GEOS64)
{ DoMouseQ;
}
UpdateProcessesO;
UpdateSleepsO;
UpdatePromptO;
GetNewRandomO;
ReturnO;
/ * GEOS 64 updates mouse here */
/ * Update the process timers */
/ • Update the sleep timers */
/ • Flash/Update the text prompt V
/ * jsr GetRandom in Kernal V
8
MalnLoop and Interrupt Level: a Technical Breakdown
Apple GEOS Interrupt Level
ApplelnterruptLevel:
{
/ * Context Save:
Save out any information about the system configuration that we might destroy V
Save6502Regs(); /* save the status of the A, X, Y, and S registers V
SaveAppleStateO; r save state of Apple memory banks V
/* Set memory configuration to normal/default state V
RamReadOffO;
RamWriteOffO;
Page20ff();
AltZPOffO;
IrqMiddleO; I* main IRQ processing V
/ * Context Restore:
Save out any information about the system configuration that we might destroy V
Restore AppleStateO; /* put memory banks back as they were V
Restore6502Regs(); /* restore A. X, Y. and S registers V
ReturnFromlRQO; /* pick up where we left off V
9
MainLoop and Interrupt Level: a Technical Breakdown
Apple GEOS IrqMiddle
IrqMiddle (APPLE VERSION).
This is *VERY* different from InterruptMain under CBM GEOS!
This is where software generated interrupts are sent.
* /
IntorruptMa io:
{
SaveGEOSRegsO; /* save r0-r15 and a few internal variables*/
/ * Application can patch into the following vector to get control before most of the
Interrupt Level processing has occurred. */
Calllndirect(intTopVector) /* call indirectly through intTopVector. On the Apple this
defaults to $0000, which Calllndirect ignores V
/ * Apple GEOS draws the mouse cursor (soft sprite #0) at interrupt level so that it can
minimize flicker by avoiding the raster beam. However, because diffent interrupt
sources (mouse vs. BSW IRQ Generator) pull the IRQ line low at different times in the
Vblank sequence, the sprite is either drawn earlier or later depending on its position
on the screen. */
if (intSource != BSWIRQ) /* if the BSW IRQ card generated the interrupt... V
{ i f (mouseYPos < 40) ^ if mouse is at the top of the screen... V
{ doMouseLater = TRUE /* then avoid the beam by drawing it later V
}
else
{ AppleSoftMouseServiceO; /* else, draw it now.V
}
}
DblClicksO; /* decrement dblClickCount if non-zero V
DoMouseO; / * update mouse now V
/ • Turn on aux. memory and give the clock driver control V
RamReadOnO; /* switch auxiliary memory in V
RamWrtOnO;
ReadClocklntO; ^ call to aux. memory jump table for clock driver V
RamReadOff(); r put main memory back in^ V
RamWrtOffO;
DoKeyboardO; /* scan the keyboard and add a char to the queue if key pressed V
UpdateProcessesO; / * Update the process timers V
UpdateSleepsO; / * Update the sleep timers V
UpdatePromptO; / * Flash/Update the text prompt V
GetNewRandomO; / * jsr GetRandom in Kernal V
/ * Call the auxiliary device driver interrupt code*/
AuxDIntO;
/ * Application can patch into the following vector to get control after most of the
Interrupt Level processing has occurred. */
1
MainLoop and Interrupt Level: a Technical Breakdown
Calllndirect(intBotVector) /* call indirectly through intBotVector. This is usually
$0000, which Calllndirect ignores. V
/* if the BSW IRQ card generated the interrupt and we haven't done the mouse yet... V
if ({intSource BSWIRQ) && (doMouseLater == TRUE))
{ AppleSoftMouseServiceO; r then draw the mouse now V
)
RestoreGEOSRegsQ; /* restore r0-r15, etc. V
ReturnO;
}
1 1
MainLoop and interrupt Level: a Technical Breakdown
UpdateProcesses
UpdateProcesses:
{
if (numProcesses > 0) / * Only' do this if there are processes in the table V
{
for (EachProcess) /* go through each process in the table V
{
if (Process != FROZEN) /* only if unfrozen... V
{ DecrementTimer(); I* count down one tick V
if (Timer ==0) T if timer timed-out
{ Process = RUNABLE; /* make it runable V
ResetTimerO; /* and reset the counter */
}
}
}
}
ReturnO;
}
UpdateSleeps
UpdateSleeps:
{
if (numSleeping > 0) / * Only do this if there routines are sleeping */
{
for (EachSleeping) /* go through each sleeping routine */
{ .
if (SleepTimer /* if counter not zero, then still asleep! */
{ Decrement ; ; /* so count down one tick V
}
}
}
}
1 2
MainLoop and Interrupt Level: a Technical Breakdown
UpdatePrompt
UpdatePrompt:
{
if (alphaFlag(BIT7) ==1) / * prompt enabled if hi-bit of alphaFlag set */
{
Decrement AlphaFlagTimerO; /* d®c timer in lower 6 bits of alphaFlag V
if ((alphaFlag&$3f) == 0) /* if time to change prompt state V
{
r Toggle the state of the prompt V
if (PromptState ON) /* bit 6 of alphaFlag = 1 V
{ PromptOffO;
}
else
{ PromptOnO;
}
}
ReturnO;
}
DoMouse
DoMouse:
{
UpdateMouseO; / * call input device driver for new positioning V
if (mouseOn(MOUSEON_BIT) == 1) r\\ mouse is on... V
{
FaultCheckO; r check for faults V
r Commodore machines draw the mouse here, Apples don't V
if(GEOS64||GEOS128) /* if CBM machine... V
{
DrawSprite(mousePicture) r copy mouse picture into sprite data tableV
PosSprite{mouseXpox.mouseYpos) /* position the sprite V
if (GEOS64) / * if GEOS 64... V
{ EnablSprite(MOUSE) r always enable the sprite each time "I
}
}
ReturnO;
1 3
MainLoop and Interrupt Level: a Technical Breakdown
AppleSoftMouseService
/* Routine to move/draw the mouse (sprite #0) during interrupt level on the Apple.
GEOS 128 soft-sprite handler does a similar update during MainLoop.*/
AppleSoftMouseService:
{
r Only draw the mouse if sprite #0 is enabled and mouse is not temporarily off V
if ( (mobenble(BIT_0) == 1) && (offFlag(BIT_7) == 0)
{
/* OK to update the mouse, only erase if not yet erased V
if ( offFlag(BIT_6) == 0) ) /* if mouse not yet erased... V
{
/* Has the mouse moved since last time? Only erase if no movement V
if ( ( lastYPos I = (mouseYPos) ) ||
( lastXPos 1= (mouseXPos) ) )
{
EraseSoftMouse(lastXPos,lastYPos); /* erase if mouse moved V
}
}
offFlag a FALSE; T flag: mouse is on and drawn V
/* make current position the old position for erasure next time around */
lastYPos = mouseYPos;
( ^ lastXPos = mouseXPos;
DrawSoftMouse(mouseXPos,mouseYpos); /* draw at new position V
)
ReturnO;
}
1 4
MainLoop and Interrupt Level: a Technical Breakdown
FaultCheck
FaultCheck:
{
/* Check mouse against left constraint and left screen edge*/
if {(mouseXPos < mouseLeft) || (nnouseXPos < 0))
{ mouseXPos = mouseLeft; /* force mouse to constraint*/
faultData(OFFLEFT_BIT) = 1; /* show left fault */
}
/* Check mouse against right constraint and right screen edge*/
if ((mouseXPos > mouseRight) || (mouseXPos > SC_PIX_WIDTH-1))
{ mouseXPos = mouseRight; /* stop mouse at edge */
faultData(OFFRIGHT_BIT) = 1 ; /* show right fault */
}
r Check mouse against top constraint and top screen edge*/
if ((mouseYPos < mouseTop) || (mouseYPos < 0))
{ mouseYPos = mouseTop; /* stop mouse at edge */
faultData(OFFTOP_BIT) = 1; /* show top fault */
}
/* Check mouse against bottom constraint and bottom screen edge*/
if ((mouseYPos > mouseBottom) || (mouseYPos > SC_PIX_HEIGHT-1))
( mouseYPos = mouseBottom; /* stop mouse at edge */
faultData(OFFBOTTOM_BIT) = 1; /* show bottom fault */
}
«
if (mouseOn(MENUON_BIT) ==1) /* if menus on. see if mouse is off current menu */
{
i f ( (mouseYPos < menuTop) ||
(mouseYPos > menuBottom) ||
(mouseXPos < menuLeft) ||
(mouseXPos > menuRight)
) /* if mouse outside any menu edge... */
{ faultData(OFFMENU_BIT) = 1; /* show menu fault */
}
}
ReturnO;
1
MainLoop and Interrupt Level: a Technical Breakdown
MainLoop Level Pseudo-Code
The following pseudo-code diagrams illustrate the general MainLoop Level constructs in each of
the three systems (GEOS 64, GEOS 128, Apple GEOS). This pseudo-code is useful for
determining exacdy how icons, menus, and other event-generating mechanisms interact with your
application.
MainLoop
MainLoop:
{
while (TRUE)
{
if (APPLE)
{ if (offFlag(BIT7) == 1)
{ offFlag = $40;
}
}
r This loop is never ending */
/• Apple specific */
/* If mouse cursor was turned off... */
/* Turn it back on now that weVe in MainLoop V
KeyboardServiceO;
ProcessServiceO;
SleepServiceO;
if (APPLE)
{
r service keyboard and related MainLoop functions V
/* service processes V
/• service sleeping routines */
/* Apple differs here, too*/
r let aux driver's MainLoop routine do what it needs to V
r Get clock driver to set the time and date variables V
AuxDMainO;
ReadClockO;
AppleTimeServiceO; /* service the apple time V
if (intSource == Software) /* if generating software interrupts... V
{
}
}
else
{
InterruptMainO;
}
CBMTimeServiceO;
/* simulate interrupts V
/• service the Commodore time V
Calllndirect(applicationMain); / * Call any application code that NEEDS to be handled
Every MainLoop V
} /• endwhile V
1 6
MainLoop and Interrupt Level: a Technical Breakdown
KeyboardService
KeyboardService:
{
If (C128 II APPLE) r GEOS 128 and Apple GEOS handle sprites here V
{ SoftSprHandlerO;
}
r RUN THROUGH THE BITS IN PRESSFU\G AND DISPATCH AS NECESSARY.
THESE DISPATCHES GO THROUGH VECTORS THAT TYPICALLY DEFAULT TO
GEOS ROUTINES FOR HANDLING THE VARIOUS USER-INPUTS V
/* input device changed vector (currently unused by GEOS) V
if (pressFlag(INPUT_BIT) ==1) r if input device changed V
{
pressFlag(INPUT.BIT) = 0) /* clear flag V
Calllndirect(inputVector) r and go through vector «$0000»V
}
r state of mouse changed vector (mouse moved; state of button changed)
mouseVector usually points to an internal GEOS routine SystemMouseService()*/
if (pressFlag(MOUSE_BIT) ==1) /* if mouse state changed... */
{
pressFlag(MOUSE_BIT) = 0) /* clear flag V
Calllndirect(mouseVector) /* and go through vector «SystemMouseService»*/
/* keyboard character ready
keyVector defaults to $0000. V
if (pressFlag(KEYPRESS_BIT) 1) /* if key in queue... V
{
keyData = GetCharFromQueue(); /* get keypress */
if (QUEUE_EMPTY) /* if no more keys in the queue... V
{
pressFlag(KEYPRESS_BIT) = 0); /* clear flag V
}
Calllndirect(keyVector) r go through vector «$0000»V
r any mouse faults since last time?
mouseFaultVec usually points to an internal GEOS routine SystemFaultServiceQV
if (faultData 1= 0) /* if any faults... V
{
Calllndirect(mouseFaultVec); /* go through vector «SystemFaultService»V
faultData = 0; /* and clear faults afterward V
}
ReturnO;
MainLoop and Interrupt Level: a Technical Breakdown
ProcessService
ProcessService:
{
if (numProcesses > 0) / * If no processes, ignore V
{
for (EachProcess) /* go through each process in the table.
(start with last in table & work backward) V
{
if ((Process == (RUNABLE & -BLOCKED)) /* only if runable & not blocked V
{ Process -RUNNABLE; r clear runable flag V
ProcessEventO; /• and generate a process event by calling the
routine in the table. */
}
}
}
ReturnO;
SleepService
SleepService:
{
if (numSleeping > 0)
{
for (EachSleeping)
if (SleepTimer = 0)
{
RemoveSleepO;
WakeUpO;
}
}
}
ReturnO;
}
/ * If no slee;. -^-^cs V
r go through eacn .. .^i^s in the table.
(start with last in table & work backward) */
/* if counter zero, then time to awake! */
/* remove this sleeper from the internal list V
r and go wake it up*/
1 8
MainLoop and Interrupt Level: a Technical Breakdown
SytemMouseService
SleepService:
{
if ( mouseData(BIT_7) == DOWN ) /* if mouse button down (bit == 0)... V
{
if ( mouseOn(MOUSEON_BIT) ==1 ) T if mouse checking is on... V
{
if ( mouseOn(MENUON_BIT) ==1) /* if menus scanning is on... V
{
/* Check if the mouse is within the currently active menu (level 0/mairi) V
i f ( (mouseYPos > menuTop) &&
(mouseYPos < menuBottom) &&
(mouseXPos > menuLeft) &&
(mouseXPos < menuRight) )
MenuServiceO; /* mouse was pressed on menu, go handle it V
ReturnO; /* Return without checking icons V
}
/* Not on a menu, see if press was on an icon V
if ( mouseOn(ICONSON_BIT) ==1) /* if icon scanning is on... V
{
r search through the icon table looking for a match */
for (Eachlcon)
{
if (icon(OFFJ_PIC) != $0000) / * if icon not disabled... V
{
if (MouseOnlconO TRUE) /* if mouse on top of this icon... V
{
r flash or invert icon as necessary V
if (iconSelFlag(ST_FLASH_BIT)) /* flash icon? V
{ InvertlconO; /* invert once V
Sleep(selectionFlash); /* sleep awhile V
InvertlconO; /* invert back again V
)
else if (iconSleFlag(STJNVERT_BIT)) r invert icon? V
{ InvertlconO; /* just invert */
)
/* check for double click V
if (DBL^CLICK) /* if this is the second click of a dbl click...*/
{ rOH = TRUE; /* set double click flag V
}
else / • else, set single click flag *.
{ rOH = FALSE;
}
r call the icon event routine*/
rOL s icon; /* tell event routine which icon V
Calllndirect(icon(OFFJ_EVENT)); /* generate an event */
1 9
MainLoop and Interrupt Level: a Technical Breakdown
Re .. n{); /* break out of the for loop (check no more icons!) V
}
}
}
}
}
}
/* If we got here, the following is true:
1 ) mouse button was released (as opposed to pressed)
- or -
2 ) mouse was pressed, but not on an icon nor on a menu
V
Calllndirect(otherPressVec); T it's an "other" press., "other" as in something the
system doesn't really care about */
20
MainLoop and Interrupt Level: a Technical Breakdown
SytemFaultService
SystemFaultService:
{
f only deal with faults if the mouse is on, menu scanning is enabled, and we've got a
submenu down... */
if ( (mouseOn(MOUSEON_BIT) == 1) && (mouseOn(MENUON_BIT) ==!)&&
(menuNumber > 0) }
{
if (menuType == CONSTRAINED)
{
/* for constrained menus... */
/* If mouse faulted off the top of a vertical menu or off the left of a horizontal
menu, then we go to the previous menu. Otherwise, the fault is ignored because
the menu is constrained */
if ( (menuType == VERTICAL && faultData(OFFTOP_BIT) == TRUE) ||
(menuType == HORIZONTAL && faultData(OFFLEFT_BIT) == TRUE) )
{
DoPreviousMenuQ;
}
}
else r menuType == UNCONSTRAINED V
{
DoPreviousMenuO; / * always try to go to the previous menu. If mouse didn't
move onto the previous menu, then next pass through
mainloop will see this as a fiault and try to remove
that menu, and so on until we're back to the main menu
* /
}
ReturnO;
}
21
Alphabetical Listing of
Routines
AllocateBlock
lAllocateBlock (Apple, C64, cm)
mid-level disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Allocate a disk block, marking it as in use,
CommcxiQrg:
r6L track number of block (byte).
r6H sector number of block (byte).
Apple:
r6 block number (word).
curDrive
Commodore:
curDirHead
dir2Headt
dirSHeadt
Apple:
curVBlknot
VBMchangedt
numVBMBlkst
this buffer must contain the current directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
r6
Apple:
c
error ($00 = no error); Commodore only: returns BAD_BAM if block
already allocated.
unchanged.
carry flag is set if block is already in use.
Commodorg:
curDirHead
dir2Headt
dirSHeadt
Apple:
curVBIknot
VBMchanged^
BAM updated to reflect newly allocated block.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines.
set to TRUE by VBM cacheing routines to indicate cached
VBM block has changed and needs to be flushed
^used internally by GEOS disk routines; applications generally don't use.
a, y, r7, r8H.
Description: AllocateBlock allocates a single block on this disk by setting the appropriate
flag in the allocation map (the BAM on Commodore computers and the VBM on
Apple computers).
AllocateBlock
Commodore: If the sector is already allocated then a BAD_BAM error is returned.
AllocateBlock does not automatically write out tEe BAM. See PutDirHead
for more information on writing out the BAM.
The Commodore 1541 device drivers do not have a jump table entry for
AllocateBlock. All other device drivers, however, do. The following
subroutine will properly allocate a block on any device, including the 1 54 1 .
NewAllocateBlock — allocate specific block in BAM
with any CBM GEOS device driver.
Pass: r6L,r6H track, sector to allocate
Uses: BAM in curDirHead
Returns: x error status ($00 = success, BAD_BAM
block already in use, etc.)
Destroys: a,y, r7,r8H
******************************************************
.if (C64 I I C128)
NewAllocateBlock :
Idy curDrive
Ida driveType-8,y
and #$0f
cmp #DRV_1571
bcc 1541$
jmp AllocateBlock
1541$:
jsr
beq
Ida
eor
and
sta
Idx
dec
Idx
rts
FindBAMBit
110$
rSH
#$ff
curDirHead, x
curDirHead, X
r7H
curDirHead, x
#$00
get current drive
get drive type
keep only drive format
see if 1571 or above
branch if 1541
else, use driver routine
get BAM bit info
if zero, then it's not free
otherwise, it's free...
get bit mask for BAM
convert to clearing mask
and with BAM byte to clear
bit and show as allocated
and store back,
get base of track's entry
dec # free blocks this track
show no error
exit
Apple:
110$:
Idx
rts
.endif
*BAD BAM
show error
exit
already in use
Apple GEOS did not include AllocateBlock in its jump table until version 2.1.
The following patch places the entry into the jump table, thereby allowing
applications to call AllocateBlock under version 2.0 (which was the first
version of Apple GEOS).
.if (APPLE)
LowSwitch = $fcl6
o_AllocateBlock « $45cl
JMPABS = $4c
VER_2 = $20
; direct entries into Kernal; do not use
; except for authorized patches
; JMP absolute opcode
; version 2.0
PatchAllocateBlock :
2
AllocateBlock
Ida
version ;
get Kernal version number
cmp
#VER_2_0 ;
check against version 2.0
bne
99$ ;
if not v2.0, then no patch necessary
Ida
#JMPABS ,
store jmp LowSwitch into main
sta
AllocateBlock ,
jump table
Ida
#(LowSwitch ,
sta
AllocateBlock+1 ,
Ida
#]LowSwitch ,
sta
AllocateBlock +2
sta
RAMWRT_ON
; switch in aux bank
Ida
#JMPABS
? store jmp o__AllocateBlock into aux
sta
AllocateBlock
; jump table
Ida
# [o_AllocateBlock
sta
AllocateBlock+1
Ida
# ] o_AllocateBlock
sta
AllocateBlock+2
sta
RAMWRT_OFF
; switch back to main bank
99$: rts
; exit
.endif ; (APPLE)
Example:
MoveW
DiskBlock, r6
i
block to allocate
.if (C64 1 1
C128)
jsr
NewAllocateBlock
(see above)
cpx
#BAD_BAM
BAD_BAM means block in use
beq
200$
branch if block already in use
txa
check for other error
beq
150$
branch if no error
jmp
MyDiskError
call error handler with error in
.else / (APPLE)
jsr
AllocateBlock
Allocate the block
php
!
save status of allocation
txa
r
get error status
beq
100$
f
branch if no error
pip
!
error: fix stack
jmp
MyDiskError
f
call error handler with error in
100$:
pip
restore status of allocation
bcs
200$
!
branch if block already in use
.endif
150$: ; block was free and is now allocated
; code to handle new block goes here
200$: ; block is not free...
/ code to handle block already . allocted goes here
MyDiskError: / error occurred...
; code to handle disk errors goes here
.ramsect
DiskBlock .block 2 ; disk block to allocate
.psect
See also: SetNextFree, BlkAlIoc, FreeBlock.
3
AppendRecord
AppendRecord (Apple, C64, cns)
VLIR disk
Function: Adds an empty record after the current record in the index table, moving all
subsequent records down one slot to make roonx
Parameters: none.
Uses:
Returns:
Alters:
Destroys:
Description:
curDrive
nieWrittent
curRecord
fileHeader
Commodore:
curType
curDirHead
dirlHeadt
dirSHeadt
Apple:
curVBlknot
VBMchangedt
numVBMBlkst
if FALSE, assumes record just opened (or updated) and
reads B AWVBM into memory.
current record pointer
VLIR index table stored in this buffer.
GEOS 64 v1 ,3 and later: for detecting REU shadowing,
current dirtciovy header/BAM.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
curRecord
usedRecords
fileWrittent
fileHeader
Commodore:
curDirHead
new record becomes the current record,
incremented by one.
set to TRUE to indicate die file has been altered since last
updated.
new record added to index table.
directory header read in if file Written is FALSE on call.
^used internally by GEOS disk routines; applications generally don't use.
a, y, rOL, rlL, r4.
AppendRecord inserts an empty VLIR record following the current record in
the index table of an open VLIR file, moving all subsequent records down in the
record list. The new record becomes the current record. A VLIR file can have a
up to MAX_VLIR RECS records (127 on the Commodore and 254 on the
Apple). If adding a record exceeds this value, then an OUT^OF^RECORDS
error is returned.
A record added with AppendRecord occupies no disk space until data is written
to it. The new record is marked as empty in the VLIR index table. (When a VLIR
file is first created by SaveFile, all records are marked as unused). Some
applications call AppendRecord repeatedly after creating a new file until an
4
AppendRecord
Note:
Apple:
CBM:
OUT_OF_RECORDS error is retumed This marks all the records as used and
prepares tfiem to accept data with calls to WriteRecord.
AppendRecord does not write the VLIR index table out to the disk. Call
CioseRecordFile or UpdateRecordFiIe to save the index table when all
modifications are complete.
An empty record is marked with $ffff in the VLIR index table (stored in the buffer
at fileHeader). An unused record is marked with $0000. Use PointRecord to
check the status of a particular record (unused, empty, or filled).
An empty record is marked with $ffOO in the VLIR index table (stored in the
buffer at fileHeader). An unused record is marked with $0000. Use
PointRecord to check the status of a particular record (unused, empty, or
fiUed).
Example:
SaveRecord:
LoadW
jsr
txa
bne
Ida
jsr
txa
bne
jsr
LoadW
LoadW
jsr
txa
bne
jsr
rO, IFilename
OpenRecordFile
99$
appendPoint
PointRecord
99$
AppendRecord
r7, #BufStart
r2, #BUFLENGTH
WriteRecord
99$
CioseRecordFile
99$:
rts
pointer to filename
open VLIR file
check open status
exit on error
get record to append to
go to that record
check point status
exit on error
ajppend a record at this point
point at data buffer
bytes in buffer (bufEnd-buf Start)
write buffer to record
get write status
exit on error
close VLIR file
; return with any error in x
.ramsect
appendPoint :
Filename:
BufStart
BUFLENGTH
.psect
.block 1
.block NAME_LENGTH+1
.block 1024
o (* - bufStart)+l
record to append to
holds null-terminated filename
data buffer
length of buffer
See also:
InsertRecord, DeleteRecord, PointRecord.
5
AuxDExit
AuxDExit (Apple)
aux driver!
Function:
De-install and remove the current aux driver.
Parameters: none.
Returns: a bit 7 set if reinitialization required.
Destroys: assume x, y, r0-rl5.
Description: The GEOS deskTop calls AuxDExit prior to loading a new aux driver. This
allows the current aux driver to deinstall itself properly, removing any hooks it
may have placed into the operating system. A RAMdisk aux driver, for example,
would need to remove itself from the device table before it can be replaced. The
GEOS deskTop and the Configure utility, for example, will call AuxDExit prior
to replacing the current auxiliary driver.
If bit 7 of a is set on return, then this indicates that the device table has changed
and a reset is in order. The deskTop, for example, will reinitialize itself if bit 7 is
set. This is equivalent to choosing RESET from the options menu.
Example:
SAMPLE AuxDExit ROUTINE ***
o AuxDExit — Deinstall RamFactor Auxiliary driver
Synopsis :
Called by:
Pass :
Returns: X
A
Before loading another aux driver, control vectors
through the AuxDExit entry in the aux driver's jump
table. This is the AuxDExit routine for the Ram Factor
RAM disk driver. We leave the drive in the drive list
but restore the original ProDOS vector.
Aux driver jump table AuxDExit entry.
Nothing
error status (NOT_IMPLEMENTED is returned if unable to
uninstall
= for no RESET needed
= $80 if reset needed
AUXRESET
AUXNORESET
RamExit :
Ida
sta
Idx
jsr
beq
Idy
Idx
10$:
jsr
$80
= $00
#$ff
DD_Command
curDrive
IsPatched
110$
#AUXNORESET
numD rive's
IsPatched
flag to force RESET function if we change
the drive tables
and for not resetting...
Get current drive
Check current drive against this driver
Can't uninstall current drive, do error
assume no reset necessary
We're OK. go through each drive in the
drive table and if it's a RAM factor,
then restore the old vector
see if this drive is patched
6
AuxDExit
bne
Idy
Ida
sta
Ida
sta
dex
bpl
tya
Idx
rts
Idx
Ida
rts
IsPatched:
Ida
cmp
bne
Ida
cmp
rts
20$:
100$:
110$:
20$
#AUXRESET
auxDevTabLo, x
devTabLo, x
auxDevTabHi, X
devTabHi,x
10$
#N0 ERROR
#NOT_IMPLEMENTED
#AUXNORESET
devTabHi,x
# ] PatchRamFactor
20$
devTabLo, x
# [PatchRamFactor
if not, then skip it
found a patched entry, enable RESET
and put back the real entry point
try next drive
and loop until no more
put RESET flag in accumulator
and return no error
exit
return error
no need to RESET
Pass: device number in X
Returns: result of compare in ST
Check address of this aux patch
against vector in device table for
equality.
exit
7
AuxDInt
AuxDInt (Apple)
aux
driver
Function:
Aux driver Interrupt Level routine.
Parameters:
none.
Returns:
nothing.
Destroys: assume a, x, y, r0-rl5.
Description: Apple GEOS calls AuxDInt during Interrupt Level. This allows an aux driver to
have routines that execute at Interrupt Level. With a hardware interrupt source,
Interrupt Level will execute approximately every vertical blank (60 times per
second).
An aux driver that has no need for Interrupt Level processing should simply
perform an rts.
See also:
AuxDMain.
8
AuxDKeyFilter
AuxDKeyFilter (Apple)
aux driver
Function:
Parameters:
Returns:
Description:
Note:
Aux-driver keypress filter; pre-processes keyboard input so aux driver may
interpret special keystrokes.
a
a
KEY — key as scanned from keyboard circuitry,
translated character or NULL if filtering out
Destroys: x, y
An application does not call AuxDKeyFilter directly. The Apple GEOS
keyboard scanning routine calls AuxDKeyFilter at Interrupt Level immediately
after calling KeyFilter. This allows the aux driver to translate, remap, or filter-
out certain keypresses.
A typical AuxDKeyFilter routine compares the KEY parameter against a list of
specific keypresses. If there is no match, then AuxDKeyFilter returns without
altering the KEY code. If there is a match, AuxDKeyFilter can perform some
action in response and return a different KEY value or a KEY value of NULL.
(A KEY value of NULL effectively filters out the keypress because GEOS
ignores the "null-key" value, never placing the key in the keyboard input queue.)
UKEY is NULL when AuxDKeyFilter is called, then a key was pressed but it
has already been processed by some other prior filter (most likeley KeyFilter)
and should be ignored.
The KEY parameter comes from the Apple hardware register KEYBD_DAT A.
GEOS then sets high-bit is set to reflect the state of the Option or ll key
(keyboards that have one, don't have the other). If bit 7 is set, then that key is
pressed To detect the state of the C5 key, check the OPEN_APPLE hardware
location. ~
Example:
;Check for open-apple key
bit OPEN_APPLE
bmi OpenPressed
; check open apple key status
/branch if pressed
*** SAMPLE AuxDKeyFilter ROUTINE ***
o_AuxDKeyFilter — key filter routine for screen dump aux driver
Synopsis: At each keypress, GEOS vectors through the aux driver's
AuxDKeyFilter jump table entry which points here.
Called by: AuxDKeyFilter entry in Aux driver's jump table.
Pass: key in A
Returns: key value unchanged or NULL if it's the key we're looking
for
MAGIC^KEY = ($80 I '!') /close-apple + shift + 1
o_AuxDKeyFilter :
9
AuxDKeyFllter
99$:
cmp
bne
jsr
Ida
rts
#MAGIC_KEy
99$
DoDump
#NULL
check keypress against our
if no match, then ignore
else, do screen dump
and return a null key
exit
DoDump:
; code to handle screen dump goes here
See also:
KeyFilter.
10
AuxDMain
AuxDMain (Apple)
aux driver!
Function : Aux driver MainLoop Level processing.
Parameters: none.
Returns: nothing.
Destroys: assume a, x, y, r0-rl5.
Description: Apple GEOS calls AuxDMain on every pass through MainLoop. This allows
an aux driver to have MainLoop Level functions.
An aux driver that has no need for MainLoop Level processing should simply
rts.
See also:
AuxDInt.
11
BBMult
BBMult (Apple, C64, C128)
math
Function:
Parameters:
Returns:
Unsigned byte-by-byte multiply: multiplies two unsigned byte operands to
produce an unsigned word result
X OPERANDI — zero-page address of single-byte multiplicand in the
low-byte of a word variable (byte pointer to a word variable).
y 0PERAND2 — zero-page address of the byte multiplier (byte pointer to
a byte variable).
Note: result^ OPERANDI (byte) * 0PERAND2(byte).
X, y, and byte pointed to by OPERANDI unchanged,
word pointed to by OPERANDI contains the word result.
Destroys: a, r7L, r8
Description:
Note:
BBMult is an unsigned byte-by-byte multiplication routine that multiplies two
bytes to produce a 16-bit word result (low/high order). The byte in OPERANDI
is multiplied by the byte in OPERANDI and the result is stored as a word back in
OPERANDI. Note ihoxOPERANDl starts out as a byte parameter but becomes a
word result with the high-byte at OPERAND
Because r7 and r8 are destroyed in the multiplication process, they cannot be
used to hold either operand.
No overflow can occur when multiplying two bytes becuase the result always fits
inaword($ff*$ff = $fe01).
Example:
Multiply rlL by rlH and store the word result in r2
MoveB rlL, r2L ; r2L <- rlL copy of OPERANDI
• Idx #r2L / point to copy of OPERANDI (r2L)
Idx #rlH ; point to 0PERAND2 (rlH)
jsr BBMult ; r2 <- r2L * r2H do multiplication
SeeAlso:
BMult, DMult, Ddiv, DSdiv.
12
Bell (Apple)
utili
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Makes a brief beeping sound through the Apple's internal speaker,
none,
nothing.
x,y
Bell sounds a 1000 Hz signal through the Apple's internal speaker. The sound
lasts approximately 1/1 0th of a second.
Bell does not return until after the full duration of the sound. Interrupts are
disabled during this period. The interrupt-disable status is restored when Bell
returns.
C64 & C128: The following routine provides a bell sound under Commodore GEOS. It is
provided for portability.
.if (064 I I C128) ; only for Commodore versions; use Kernal
; routine on Applf.
Bell — Make a bell sound on C64/128
Author: Dan Kaufman (w Chris Hawley)
(mgl)
Pass: Nothing
Return: Nothing
Destroyed: a
Synopsis: This routine allows you to have the c64 beep when the user
makes a mistake or does something he shouldn't.
sidBase
voicelRegs
« $D400
sidBase
f reqLol
as
voicelRegs
freqHil
voicelRegs+1
PWLol
rs
voicelRegs+2
PWHil
voicelRegs+3
controlRegl
voicelRegs+4
att_decl
voicelRegs+5
sus__rell
ss
voicelRegs+6
FCLo
voicelRegs+7+7+$7
FCHi
voicelRegs +7 +7 +$8
res_filt
voicelRegs+7+7+$9
mode_vol
voicelRegs+7+7+$A
pulse
%01000001
SOUND ON
$30
Bell:
PushB CPU_DATA
LoadB CPU_DATA,#IO IN
/switch to I/O space
13
Bell
LoadB
controlRegl, #0
sta
att__decl
LoadB
mode__vol, #$18
LoadB
sus_rell, #SOUND_ON
LoadW
PWLol,#$800
LoadB
FCLo,#0
sta
FCHi
sta
res__f ilt
LoadB
att_decl,#6
LoadB
sus__rell, #0
LoadB
freqLol,#$DF
LoadB
freqHil,#$25
LoadB
controlRegl, #puise
PopB
CPU__DATA
rts
/twiddle sound chip
; return to memory space
.endif ; (C64 I 1 C128)
Example:
r*** Beep three times ***
r Runs off of MainLoop by using Sleep
BELL_INTERVAL
= (FRAME_
_RATE/10)
approx
1/10 second
BeepThrice :
jsr
Bell
• sound
the bell
LoadW
rO, #BELL_
_INTERVAL
' pause
a bit
jsr
Sleep
jsr
Bell
• sound
the bell again
LoadW
rO,#BELL_
_INTERVAL
• pause
a bit
jsr
Sleep
jmp
Bell
• sound
the bell again
14
BitmapClip
BitmapClip (Apple, C64, cns)
graphics
Function: Place a rectangular subset of a compacted bitmap on the screen.
Parameters:
Uses:
Returns:
Destroys:
Description:
rO DATA — pointer to the compacted bitmap data (word).
rlL XPOS — X card position: pixeLposition /8 (byte).
rlH Y — y-coordinate (byte).
r2L W^WIDTH — clipping window width in cards: pixeLwidth/8 (byte).
r2H W^HEIGHT — height in pixels of clipping window (byte).
rllL DXl — delta-xl: offset of left edge of clipping window in cards from
left edge of full bitmap (byte),
r IIH DX2 — delta-x2: offset of right edge of clipping window in cards from
right edge of full bitmap (byte).
rl2 DYl — delta-yl: offset of top edge of clipping window in pixels from
top edge of full bitmap (word).
where the upper-left corner of the clipped bitmap (the window) is placed at
(XP0S*8, Y). The lower-right corner is at ([XPOS*8]+[WJVIDTH*8],
Y-^W^H EIGHT).
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
nothing.
a, X, y, r0-rl2
BitmapClip uncompacts a rectangular area of a full bitmap, clipping (ignoring)
any data that exists ouside of the desired area. The rectangular subset is called the
clipping window.
15
BitmapClip
The following diagram illustrates the eight BitmapClip parameters:
full compacted bitmap
DYf
(in pixels)
W_HEIGH1
(in pixels)
Note:
C128:
Apple:
clipping window,
eight-pixel
boundaries
DX1
(in cards)
WJA/IDTH
(in cards)
DX2
(in cards)
No checks are made to determine if the data, dimensions, or positions are valid.
Be careful to pass accurate values. Do not pass a value of $00 for either the
WJWIDTH or WJiEIGHT parameters, and pay special attention to the fact that
XPOS, WJWIDTH, DXl, and DX2 are specified in cards (groups of eight pixels
horizontally), not in individual pixels.
It may be helpful to think of DYl as the number of scanlines in the bitmap to skip
initiallly, to think of W_H EIGHT as the number of scanlines to display, to think
of DXl as the number of cards to skip at the beginning of each scanline, to think
of W_WIDTH as the number of cards to display, and to think of DX2 as the
number of bytes to skip at the end of each scanline.
Under GEOS 128, OR'ing DOUBLE^B into the XPOS and W^WIDTH
parameters automatically doubles the x-position and the width of the bitmap
(respecitvely) when running in 80-column mode.
BitmapClip in the first release of GEOS 128 does not call TempHideMouse
to disable the sprites and does not properly double the width when drawing to the
80-column screen. On Kemals where the release byte is greater than $01, these
problems have been fixed
DOUBLE__B may be OR'ed into the WJVIDTH parameter to double the bitmap
width and INAUX_B may be OR'ed into the XPOS parameter to specify
auxiliary memory. "
16
BitmapClip
Example:
**************************************
Displaylmage
Pass :
Destroys :
General purpose routine to display a portion of
compacted bitmap image in a window
pixBuf compacted bitmap image in pseudo-photoscrap
format. Byte is card width of image.
Byte 1 and 2 is the pixel height (word) .
The compacted image data starts at byte 3.
xOffset card index into bitmap to display
yOffset pixel index into bitmap to display
a,x, y, r0-rl2
WINDOW__X = 4
WINDOW_Y = 30
WINDOW_WIDTH » 5
WINDOW__HEIGHT « 60
Displaylmage:
Set up initial parameters **"
LoadW rO,#PixImage
LoadB rlL, #WINDOW__X
LoadB rlH, #WINDOW__Y
LoadB r2L, #WINDOW_WIDTH
LoadB r2H, #WINDOW_HEIGHT
MoveB xOffset^rllL
MoveW yOffset,rl2
;*** Clip to window ***
Ida PixWidth
sec
sbc WINDOW__WIDTH
— following line changed to
— use zero-page copy
10$:
card x-position of window
pixel y-position of window
card width of window
pixel height of window
rO <- compacted picture data (DATA)
rlL <- left edge of window (XPOS)
rlH <- top edge of window (Y)
r2L <- width of window (W_WIDTH)
r2H <- height of window (W__HEIGHT)
rllL <- X offset into bitmap (DX.l)
rl2 <- y offset into bitmap (DYl)
get bitmap width
subtract window width
sbc
xOffset ,
? subtract x-index into bitmap
sbc
rllL
? now we have the right edge clip distance
sta
rllH
? rllH <- right edge clip (DX2)
bpl
10$
? if we're >0, branch to skip x clipping
adc
#WINDOW_WIDTH
? add back the window width
sta
r2L
; ma)ce that the new clip window
LoadB
rllH,#0
? rllH <- $00 (fixes underflow of DX2)
Ida
PixHeight
? subtract window height from bitmap height
sec
? (two byte subtractiqn)
sbc
#WINDOW_HEIGHT
sta
r3L
; store intermediateresult in r3
Ida
PixHeight+1
sbc
#0
sta
r3H
Ida
r3L
; now subtract y index into bitmap
sec
following line changed to
use zero-
page copy
sbc
yOf f set
sbc
rl2L
; (rl2 = yOffset)
sta
r3L
Ida
r3H
following
line changed to
use zero-
page copy
sbc
yOf f set+1
17
BitmapClip
20$:
99$:
ramsect
f fset
• set
- .. ^ -dth
Pixhaight
Piximage
.psect
sbc
rl2H
sta
r3H
bpl
20$
Ida
r3L
adc
#WINDOW__HEIGHT
sta
r2H
jsr
BitmapClip
rts
.block 1
.block 2
.block $800
PixBuf+0
PixBuf+1
PixBuf+3
(rl2 = yOffset)
value in r3H never used after this
branch if no underflow
correct for underflow
display the bitmap with clipping
exit
.:d X index into bitmap (byte)
i^xel y index into bitmap (word)
2K picture buffer
width of picture in cards (byte)
height of picture in pixels (word)
start of bitmap image
18
BitmapUp
BitmapUp^ i BitmapUp (Apple, C64, ci28)
graphics
Function:
Parameters:
Place a compacted bitmap onto the screen.
Uses:
Returns:
Destroys:
Description:
128:
Normal:
rO DATA
rlL
pointer to the compacted bitmap data (word).
XPOS — X card coordinate: pixeLposition /8 (byte).
Y — y-coordinate (byte).
WIDTH — width in cards: pixeLwidth/8 (byte).
HEIGHT — height in pixels (byte).
rlH
r2L
r2H
Inline:
data appears immediately after the jsr i_BitmapUp
.word DATA pointer to the compacted bitmap data,
.byte XPOS x card position: pixeLposition /8.
.byte Y y-coordinate.
.byte WIDTH width in cards: pixeLwidth/8.
.byte HEIGHT height in pixels.
where the upper-left corner of the bitmap is placed at (XP0S*8,Y). The lower-
right corner is at (XPOS*8+WIDTH^8,Y+HEIGHT).
dispBufferOn:
bit? — write to foreground screen if set.
bit 6 — write to background screen if set
nothing.
Commodore:
a, X, y, rO-r9L
Apple;
a, X, y, r0-r2
BitmapUp uncompacts a GEOS compacted bitmap according to the width and
height information and places it at the specified screen position. No checks are
made to detemiine if the data, dimensions, or positions are valid, and bitmaps
which exceed the screen edge will not be clipped. Be careful to pass accurate
values. Do not pass a $00 for the WIDTH or the HEIGHT parameter, and pay
special attention to the fact that both the x-position and the width are specified in
cards (groups of eight pixels horizontally), not in pixels.
Under GEOS 128, OR'ing DOUBLE^B into the XPOS and WIDTH parameters
will automatically double the x-position and the width (respectively) in 80-column
mode. The first release of GEOS 128 did not properly remove the sprites before
placing the bitmap on the screen. The easiest way to correct for this is to always
precede a call to BitmapUp with a call td TempHideMouse. The redundant
call to TempHideMouse when running under later releases is minimal
compared to the number of cycles it takes to decompact and draw the bitmap.
jsr TempHideMouse ; correct for bug in release 1 of GEOS 128
jsr BitmapUp ;then put up the bitmap
19
BitmapUp
Apple:
Example:
See also:
Under Apple GEOS, DOUBLE^B may be OR'ed into the WIDTH paramter to
double the bitmap width and INAUX_B may be OR'ed into the XI parameter to f
specify auxiliary memory. ""
;Put a bitmap up from an address in
/auxiliary memory and doubling the
/picture ' s
width.
.if (APPLE)
LoadW
rO, #MyAuxBitmap
/ rO <- aux address of bitmap
LoadW
rlL, #(MY_CXPOS|INAUX B)
/ r3 <- card x-pos + in-aux
LoadB
rlH,#MY_YPOS
/ rlH <-y-coordinate
LoadB
r2L, # (MY_CWIDTH 1 DOUBLE 1 W)
/ r2L <- card width + double bit
LoadB
r2H,#MY_HEIGHT
/ r2H <- height
jsr
BitmapUp
/ put bitmap on screen
.endif
•k'kitlt'k-k'kic'klfk-tfk'k'k'k'ti-k
*** ShowBitmap ***
******************
For C64, C128, or Apple
if (C128 && C64)
.echo ShowBitmap cannot assemble for both C64 and C128 at the same time
endif
BM_XPOS
BM_YPOS
Bitmap;
(32/8)
20
/card x-pos it ion of bitmap
/y-position of bitmap
BMJWIDTH
BM HEOIT
- PicW
- PicH
ShowBitmap:
Ida
#(STjm_FORE 1 ST_WRjaACK) ,
> use both screens
sta
dispBufferOn i
.if (C128)
' bug fix for 128 release 1
jsr
TenpHideMouse <
remove sprites
•endif
jsr
i^BitmpUp ,
* inline bitmap call
•word
Bitmap ^
♦bitmap address
.byte
(BM XPOSI (DOUBIf: B&(!APPLE*-
-1))); *xpos (can't dbl on apple)
.byte
BMJfPOS
*ypos
.byte
(BM WIDTH (DOUBLE B)
★width
.byte
BM HEIGHT
♦height
card width of bitmap
bitmp height
Place the bitmap on the screen,
loading the registers with
inline data (note double-width
settings) .
90$: rts
BitmapCIip, BitOtherClip, NewBitUp.
exit
20
BitOtherClip
BitOtherClip (Apple, C64, ci28)
graphics
Function: Special version of BitmapCIip that allows the compacted bitmap data to come
from a source other than memory (e.g., from disk).
Parameters: rO BUFFER — pointer to a 1 34-byte buffer area (word).
rlL XPOS — x-position in bytes: pixel j)osition /8 (byte),
r 1 H Y — y-coordinate (byte).
r2L W_WIDTH — width in cards of clipping window: pixeLwidth/8
(byte).
r2H W^HEIGHT — height in pixels of clipping window (byte).
rllL DXl — delta-xl: offset of left edge of clipping window in cards from
left edge of full bitmap (byte),
rl IH DX2 — delta-x2: offset of right edge of clipping window in cards from
right edge of full bitmap (byte).
rl2 DYl — delta-yl: offset of top edge of clipping window in pixels from
top edge of fiill bitmap (word),
r 1 3 APPINPUT — pointer to application-defined input routine. Called each
time a byte from a compacted bitmap is needed; data byte is returned in
the a-register.
rl4 SYNC — pointer to synchronization routine. Called after each bitmap
packet is decompressed. Due to improvements in BitOtherClip, this
routine need only consist of reloading rO with the BUFFER address.
where the upper-left corner of the clipped bitmap (the window) is placed at
(XP0S*8, Y). The lower-right corner is at ([XPOS*8]+[WJVIDTH*8],
Y^WJiEIGHT).
Uses: dispBufferOn:
bit? — write to foreground screen if set.
bit 6 — write to background screen if set
Returns: nothing.
Destroys: a, x, y, r0-rl2, and the 134-byte buffer pointed at by rO.
Description : BitOtherClip allows the application to decompress and display a bitmap without
storing the compressed bitmap in memory. Call BitOtherClip witii the address
of an input routine (APPINPUT). Each time BitOtherClip needs another byte,
it calls this routine. The APPINPUT routine is expected to read data from the disk
or some other device and return a single byte each time it is called.
The basic width, height, position, and clipping window parameters the same as
those for BitmapCIip. Refer to the documentation of that routine for more
information.
BitOtherClip calls the user-supplied APPINPUT routine until it has enough
bytes to form one bitmap packet. APPINPUT must preserve r0-rl3 and return
the data byte in the accumulator. A typical APPINPUT routine saves any registers
it might destroy, calls ReadByte to get a byte from a disk file, places die byte in
the BitOtherClip buffer (pointed at by rO), then returns, as illustrated in the
following example.
21
BitOtherCiip
128:
Apple:
Note:
Example:
22
App Input :
PushW
1^1 1
•save rl, r4, and r5
PushW
• (saved for calls to ReadByte routine
irUSnrr
TO t
Movew
saveRl r rl i
• rl <- saveRl
no vcn
savcKOf ro
• r5 <— saveRS
liOaQn
r4 , fdiSKQlKBut 1
• r4 <- disk buffer we use
jsr
MyReadByte <
• get a byte from the file
* (oyte Is in A)
Sua
error ^
• save any error
i ^ 1 ADD T V \
• Apple needs to use buffer pointer
sua
* that is on Alt zero^page
lay
A 6 n n
#900 ,
' null inalrectlon index
sta
(rO),y
• store byte into buffer
.if (APPLE)
' Apple needs to
sta
ALTZP_OFF
• restore normal zero-page
.endif
MoveW
r5,saveR5 <
• r5 -> saveRS
MoveW
rl^saveRl ,
• rl -> saveRl
PopW
r5
• restore rl, r4, and r5
PopW
r4
PopW
rl
rts
• exit
When BitOtherCiip detects a complete packet, it uncompacts the data from the
buffer to the screen. After the bitmap packet has been uncompacted,
BitOtherCiip calls the SYNC routine supplied by the caller. The SYNC routine
prepares the bitmap buffer for the next packet by reloading rO with the address of
BUFFER and performing an rts.
Sync:
LoadW rO, #ClipBuf fer ; reset the pointer
rts / exit
Under GEOS 128, OR'ing DOUBLE^B into the and W^WIDTH
parameters will automatically double the x-position and the width (respecitvely) in
80-column mode.
DOUBLE B can be OR'ed into the WIDTH paramter to double the bitmap
width andlNAUX B can be OR*ed into the XPOS parameter to specify
auxiliary memory. Also on Apple GEOS, the APPINPUT routine must use the
alternate zero-page version of rO to index into BitOtherClip*s compaction
buffer.
.if (APPLE)
sta
Idy
sta
sta
.endif
ALTZP_ON
#$00
(rO),y
ALTZP OFF
Apple needs to use buffer pointer
that is on Alt zero-page
null indirection index
store byte into buffer
restore normal zero-page
Do not pass a value of $00 for either the WJVIDTH or WJIEIGHT parameters.
*♦* CONSTANTS ***
NO PICTURE « -1 ; no picture error. MUST BE NON-ZERO
;window coordinates and dimensions
BitOtherClip
WIN_CRDX = 5
WIN_CRDWIDTH = 12
WIN^Y =40
WIN HEIGHT = 110
card x-position
card width
y-position
height
*** VARIABLES
.ramsect
saveRl
saveRS
leftOff set
topOf fset
picWidth
picLength
ClipBuffer
.psect
.block
.block
.block
.block
.block
.block
.block 135
DrawPhoto
DESCRIPTION:
temp save for GEOS registers that need to
be preserved between calls to ReadByte
scroll x-index into bitmap
scroll y-index into bitmap
bitmap card width
bitmap card height
BitOtherClip buffer (+1 for safety)
PASSED:
RETURNS:
Reads a picture in from a photo album record and draws it
clipped to a window. Scroll values allow a specific portion
of the bitmap to be shown.
Open VLIR album file with photo scraps in records
curPhoto record to use
leftOffset scroll value on x
topOffset scroll value on y
picWidth
picLenght
X
from photo record
from photo record
error
DrawPhoto:
99$:
jsr
ClearWindow
/ clear the drawing window
jsr
GetPicSize
; get the size of the picture
txa
; check for error
bne
99$
jsr
SetUpPhoto
; set up clipping parameters
/ carry comes back set if we can
Idx
#NO_ERROR
/ no errors yet
bcc
99$
; skip drawing if necessary
jsr
PutUpPhoto
; draw photo from the record
rts
; exit with error in x
• * it it* ^r it it ii*iiit*it it ****** It* Ir** it* * It ir**ii it -kit It It* ****** it* it*
; ClearWindow
/DESCRIPTION: Erase the window areas where we plan to put the bitmap
/PASS: Nothing
/RETURNS: curPattern »
/DESTROYS: CBM: a, x, y, r5-r8,' rll
APPLE: a, x, y, rll
******************************* *********************************
ClearWindow:
LoadB curPattern, #0 /use blank fill pattern
jsr i_Rectangle
.byte WIN_Y
23
BitOtherClip
.byte (WIN_Y+WIN_HEIGHT)
.word {WIN_CRDX * 8)
.word (WIN_CRDX*8 + WIN_CRDWIDTH*8)
rts
SetUpPhoto
DESCRIPTION: Set up clipping regions and other parameters
PASS:
RETURNS:
DESTROYS
***********
SetUpPhoto:
8$:
15$:
picWidth card width of bitmap
picLength height of bitmap
leftOffset card scroll index into bitmap
rightOffset line scroll index into bitmap
carry set « OK to draw
clear = don't draw (lies outside of region.)
rO BitOtherClip buffer
rlL Card x-position of window
rlH y-position of window
r2L number of cards of bitmap to display in window
r2H number of lines of bitmap to display in window
rl2 lines to skip on top
rllL cards to skip on left
rllH cards to skip on right
rO <- buffer for BitOtherClip » s use
rlL <- window's card x-position
rlH <- window's y-position
A <- (picWidth-leftOffset)
(difference between width of
picture and offset into picture)
If offset exceeds width, then skip
over picture draw
; If width to display exceeds width
of bitmap, then display as much as
; will fit in the window.
r2L <- card width to display
A <- (picLength-topOf f set)
(difference between height of
picture and offset into picture)
If offset exceeds height, then skip
over picture draw
If height to display exceeds height
of bitmap, then display as much as
will fit in the window.
r2H <- pixel height to display
rl2 <- lines to skip on top
rllL <- cards to skip on left
LoadW
rO, #ClipBuffer
LoadB
rlL, WIN__CRDX
LoadB
rlH, WIN_Y
Ida
picWidth
sec
sbc
leftOffset
bcc
20$
beq
20$
cmp
#WIN CRDWIDTH
bcc
8$
Ida
#WIN_CRDWIDTH
sta
r2L
Ida
picLength
sec
sbc
topOf f set
bcc
20$
beq
20$
cmp
#WIN HEIGHT
bcc
15$
Ida
#WIN_HEIGHT
sta
r2H
MoveW
topOf fset,rl2
MoveW
leftOffset, rllL
Ida
picWidth -
sec
sbc
r2L
sbc
leftOffset
sta
rllH
rllH <- cards to skip on right
24
BitOtherClip
20$:
clc
rts
sec
rts
flag as OK to draw
exit
flag not to draw
;PutUpPhoto
/DESCRIPTION:
/
/RETURNS:
/
/DESTROYS:
Draw photo from record.
X error
a,x,y,r0-rl5
PutUpPhoto:
99$:
jsr
GetPicSize ,
reload picture length and width
txa
* check for error or no picture
bne
99$
leave on error
jsr
Sync t
• rO <- clipBuffer
LoadW
rl3, #AppInput ,
• rl3 <- Applnput routine
LoadW
rl2, #Sync
• rl2 <- Sync routine
LoadB
error, #NO_ERROR
• start out with no error
jsr
BitOtherclip
? display photo
Idx
error
? put any error into x
rts
? exit
4r 4r ******** *
Applnput
DESCRIPTION:
APPLE:
RETURNS :
Applnput :
PushW
PushW
PushW
MoveW
MoveW
LoadW
jsr
stx
.if (APPLE)
sta
.endif
Idy
sta
.if (APPLE)
sta
.endif
MoveW
MoveW
Bitmap input routine called by BitOtherClip. Returns a single
byte of the uncompacted bitmap.
This routine resides in main memory on the Apple, so the
ClipBuffer should also be in main memory.
bitmap byte in BitOtherClip* s buffer (off of rO)
any error in error
r**************************************************************
rl
r4
r5
saveRl, rl
saveR5, r5
r4,#diskBlkBuf
MyReadByte
error
ALTZP_ON
#$00
(rO),y
ALTZP__OFF
r5, saveRS
rl, saveRl
save rl, r4, and r5
rl <- saveRl
r5 <- saveRS
r4 <- disk buffer we use
get a byte from the file
(byte is in A)
save any error
Apple needs to use buffer pointer
that is on Alt zero-page
null indirection index
store byte into buffer
Apple needs to
restore normal zero-page
r5 -> saveRS
rl -> saveRl
25
BitOtherClip
PopW r5
PopW r4
PopW rl
rts
restore rl, r4, and r5
exit
;Sync
.*****★*★**★**«★★★*****★***★*************★★**★*****************«
/DESCRIPTION: Dumb synchronization routine needed by BitOtherClip
;
Sync:
LoadW rO,#ClipBuffer ; reset the pointer
rts ; exit
/GetPicSize
. *********************************************************************
/DESCRIPTION: Get picture size and other misc. setup for PutUpPhoto
;
•RETURNS: X error
GetPicSize:
PushW
rl
save rl and r4
PushW
r4
Ida
curPhoto ;
get current photo's record number
jsr
PointRecord ;
point to that record
rl <- block# of first record
Ida
rlL ;
make sure there's something there
.if
(APPLE)
ora
rlH
(check both bytes on Apple)
.endif
bne
10$
branch if valid record found
Idx
#N0 PICTURE
' otherwise, flag no picture
Following
line changed to save bytes
bra
40$
' and exit
bne
40$
• unconditional (NO__PICTURE != 0)
10$:
jsr
SetUpReadByte
r prepare for ReadByte
txa
? check status
bne
40$
? exit on error
jsr
ReadSizeBytes
? read the size bytes out of the record
? and store them in the photo size
; variables (error comes back in x)
MoveW
rl, saveRl
; save off rl and r5
MoveW
r5, saveRS
•
Following line removed to let
error propagate back
Idx
#NO_ERROR
; we got this far, no errors found...
40$:
PopW
r4
; restore r4 and r5
PopW
r5
rts
; exit
******* ************************************** ********
SetUpReadByte
********** ********************************** ****** *************************
DESCRIPTION: Set up variables and stuff for ReadByte
STRATEGY:
Special case Apple because it requires an extra step. The first block in
26
BItOtherClip
an Apple VLIR record is actually an index block with pointers to all the
other blocks in the chain. We read this block into the aux memory buffer
INDEXBLOCKBUF so ReadByte has something to work with (this requires that
ReadByte be called from aux memory using JsrToAux) . The general disk
buffer diskBlkBuf is used for the intermediate blocks since it is in
high aux memory and is always visible (thus eliminating the need to
set RWbank) .
PASS:
RETURNS:
APPLE: rl block number of chain's index block
CBM: rlL, rlH Track/sector of first block in chain
rl, r4, r5 set up for ReadByte
X = error code
DESTROYS: a, y
SetUpReadByte:
.if (APPLE)
LoadW
LoadB
jsr
It***********************-*
LoadB
.else ; (CBM)
Idx
.endif
MoveW
LoadW
Ida
sta
sta
rts
r 4, # INDEXBLOCKBUF
RWbank, #AUX
GetBlock
RWbank, #MAIN
#NO_ERROR
r4,rl
r4, diskBlkBuf
#0
r5L
r5H
r4 <- buffer for index block
set disk read to proper bank
read in the chain's index block
(error now in x)
restore disk bank to normal
no error on CBM
rl <- track/sector of 1st block (CBM)
<- index block pointer (APPLE)
r4 <- disk buffer for ReadByte
r5 <- $0000 (for ReadByte)
exit with error in X
MyReadByte
D-ESCRIPTION:
PASS:
RETURNS :
DESTROYS:
MyReadByte :
.if (APPLE)
Ida
Idx
jsr
.else ; (CBM)
jsr
My version of ReadByte that deals with all machine weirdness.
This routine expects to use the general-purpose disk buffer at
diskBlkBuf because, since it is in high-aux on the Apple, it
avoids the bank switching complications.
Call wherever you would normally call ReadByte. Call
SetUpReadByte to set the proper parameters prior to calling.
This would make a good Macro.
Same as ReadByte
Same as ReadByte
Same as ReadByte
******:r^*******************«**4r *********************************
# [ReadByte
#] ReadByte
JsrToAux
ReadByte
APPLE
Call ReadByte from aux memory
so that the aux memory
INDEXBLOCKBUF is visible
; CBM
; just use normal ReadByte
27
BitOtherClip
.endif
rts ; exit
Reads! zeBytes
DESCRIPTION: Read in the first three bytes from the current record and
store them in the size variables.
PASS: File open and system ready for calls to ReadByte.
RETURNS: rl, r4, r5 ready for ReadByte calls to load bitmap data
X error
picWidth card width of bitmap
picLength line height of bitmap
DESTROYS: a, y
*«********************************************************« ************
ReadSizeBytes :
99$:
jsr
sta
txa
bne
jsr
sta
txa
bne
jsr
sta
rts
MyReadByte
picWidth
99$
MyReadByte
picLength
99$
MyReadByte
picLength+1
get photo width
check for error
get photo length (low byte)
check for error
get photo length (high byte)
exit error in x
28
BidGDirEntry
BldGDirEntry (Apple, C64, cns)
mid-level disk
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
Apple:
Example:
Builds a directory entry in memory for a GEOS file using the information in a file
header. Apple GEOS version can also build an entry for a folder (subdirectory).
r6
Commodore:
r2 NUMBLOCKS — number of blocks in file (word).
TSTABLE — pointer to a track/sector list of unused blocks (unused but
allocated in the BAM), usually a pointer to fileTrScTab; BlkAlIoc
can be used to build such a list (word).
FUJEHDR — pointer to GEOS file header (word).
r9
Apple:
r2
r6
r7
r8
r9
NUMBLOCKS — number of blocks in file or $0000 to create a
subdirectory (word).
INDXBLK — if creating a file, block number of sequential-file index
block or VLIR master index block; if creating a subdirectory, key block
number for subdirectory (word).
FUJEB YTES — number of bytes in file (word).
HDBLKNUM — block number of the file's header block (word).
FILEHDR — if creating a file, pointer to GEOS file header, if creating a
subdirectory, pointer to null-terminated name for the subdirectory (up
15 characters plus a NULL); must be in main memory, (word).
Commodore:
r6 pointer to first non-reserved block in track/sector table (BidGDirEntry
reserves one block for the file header and a second block for the index
table if the file is a VLIR file).
dirEntryBuf contains newly-built directory entry.
Commodprg:
a, X, y, rlH.
App le:
a, X, y, r3.
Given a GEOS file header, BidGDirEntry will build a system specific directory
entry suitable for writing to an empty directory slot. BidGDirEntry takes care
of differences between Apple and Ctommodore GEOS.
Most applications create new files by calling SaveFile. SaveFile calls
SetGDirEntry, which calls BidGDirEntry as part of its normal processing.
The Apple version of BidGDirEntry can also be used to build subdirectory
entries by passing $00(X) in r2. The easiest way to create a subdh-ectory is to call
MakeSubDir.
.************************************ ***************************************
;MySetGDirEntry (My Version of Set Geos Directory Entry)
; This routine duplicates the function of the Kernal's SetGDirEntry for
29
BIdGDIrEntry
demonstration purposes. It shows examples of the following routines:
BldGDirEntry
GetFreeDirBlk
UpdateParent
PutBlock
PASS: Same as SetGDirEntry
DESTROYS: Same as SetGDirEntry
.if (APPLE)
DIRCOPYSIZE
.else (CBM)
DIRCOPYSIZE
.endif
= 39
= 30
bytes in directory to copy over
after BldGDirEntry is called
MySetGDirEntry :
jsr
BldGDirEntry ;
build directory entry for GEOS file
jsr
GetFreeDirBlk /
get block with free directory entry
r3 =» 1st byte of free entry
block number of block in rl
txa
test for error code
bne
90$ ;
if error, exit . . .
.if (APPLE)
MoveW
r3,r5 ;
make r5 point to directory entry
.else ; (CBM)
tya
get offset into diskBlkBuf for dir entry
clc
adc
#[diskBlkBuf
and get absolute address in buffer
sta
rSL
Ida
#ldiskBlkBuf
adc
#0
(propagate carry)
sta
r5H
.endif ; (else
CBM)
• (r5 = pointer to dir entry in buffer)
Idy
#DIRCOPYSIZE
• copy over some bytes
10$:
Ida
dirEntryBuf ,y
get byte from directory entry built
sta
(r5) ,y
• store new entry into block buffer
dey
bpl
10$
? loop till copied
jsr
TimeStampEntry
? stamp the dir entry with time & date
LoadW
r4,#diskBlkBuf
; write out the new directory entry
jsr
PutBlock
txa
; get error status
bne
90$
; if error, exit
.if (APPLE)
PushW
Ida
jsr
PopW
rl
#(INC_NUM_FILES
UpdateParent
rl
Update parent directory on Apple
save block number of directory block that
this file entry is stored in
MOD_DATE)
update parent directory's directory entry
restore block number of directory block
that this file entry is saved on
(error status now in x)
.endif ; (APPLE)
90$:
rts
************* ****************************************************** ********
TimeStampEntry
Add time/date stamp to directory entry
30
BldGDirEntry
TimeStampEntry :
.if (C64 1
1 C128) COMMODORE ***
TDSIZE
number of bytes in time/date entry
Idy
fOFF__YEAR ;
otrset to time/aate stamp
10$:
Ida
year-OFF_^YEAR, y ;
get the yr/mo/day/hr/min
sta
Cro) , y ;
store in dir entry
iny
cpy
Jtorr VT A D j-Tne T T
ffUr r __ILAr\+iUbi^hj /
done yet?
bne
1 V 1
if not, loop
rts
.else ; (APPLE)
•www ArrLL
clc
stamp creation date
jsr
StampTimeDate i
sec
stamp moaiiicatlon date
jsr
StampTimeDate ,
rALL inKUUUn to ot ampTimeDate
/ rts
StampTimeDate:
(carry indicates stamp to modify)
Ida
minutes «
get minutes (0—59)
Idy
tOFF__FCTIME ,
• get offset to creation minutes
bcs
110$ 1
if stamping creation time, skip
Idy
fOFF__FMTIME i
get offset to modification minutes
110$:
sta
(r5),y ,
' save hours in directory entry .
Ida
hour 1
' get hours (0-23)
iny
' get offset to hours
sta
»
(ro) , y ,
• save minutes in directory entry
idy
fOr r_rCDATE i
get or t set to mmmdaaaa
bcs
X ^ U V
* if stamping creation time, skip
Idy
120$:
Ida
mont" h
f geu niunL.n yx ±£}
asl
asl
asl
a
asl
a
asl
a
? carry holds month's msb
ora
day
; combine with day to get mmmddddd
sta
(r5),y
; save mmmddddd
iny
; get offset to yyyyyyym
Ida
year
; get year
rol
a
; carry has m's MSB; move it into
; LSB to get yyyyyyym
sta
(r5),y
; save yyyyyyym
rts
; exit
.endif ; ( .else APPLE)
See also: SetGDirEntry.
31
BIkAlloc
BlkAUoC (Apple, C64, C128)
mid-level disk
Function: Allocate enough disk blocks to hold a specified number of bytes.
Parameters: r2
Uses:
Returns:
BYTES — number of bytes to allocate space for. Commodore version
can allocate up to 32,258 bytes (127 CiDmmodore blocks); Apple
version can allocate up to 65,535 ($ffff) bytes (128 ProDOS blocks)
(word).
Commodore:
r6 TSTABLE — pointer to buffer for building out track and sector table of
allocated blocks, usually points to fileTrScTab (word).
curDrive
Commodore:
curDlrHead
dir2Headt
dirSHeadt
interleave^
Applg:
VBMBlknot
numVBMBlkst
curVBlknot
VBMchangedt
currently active disk drive.
this buffer must contain the current directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
desired physical sector interleave (usually 8); used by
setNextFree. Applications need not set this explicitly —
will be set automatically by internal GEOS routines.
Apple GEOS BIkAlloc starts searching for free blocks
beginning with the block that follows the last VBM block,
the block following the last VBM block is found by adding
the value in numVBMBlks to the value in VBMBlkno.
used by VBM cacheing routines,
used by VBM cacheing routines
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
r2 number of blocks allocated to hold BYTES amount of data.
Commodore:
rSL track of last allocated block,
r 3 H sector of last allocated block.
Apple;
r3
last block allocated.
Alters:
Commodore:
curDirHead
dir2Headt
dir3Headt
Applg;
curVBlknot
VBMchangedt
BAM updated to reflect newly allocated blocks.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines.
set to TRUE by VBM cacheing routines to indicate cached
VBM block has changed and needs to be flushed
32
BIkAlloc
^used internally by GEOS disk routines; applications generally don't use.
Destroys: Commodore:
a, y, r4-r8.
Apple;
a, y, r4, r6, r7, r8H.
Description: BIkAlloc allocates enough blocks on the disk for BYTES amount of data. The
GEOS SaveFile and WriteRecord routines call BIkAlloc to allocate multiple
blocks prior to calling WriteFile. Most applications do not call BIkAlloc
direcdy, but rely, instead, on the higher-level SaveFile and WriteRecord.
BIkAlloc calculates the number of blocks needed to store BYTES amount of
data, taking any standard overhead into account (such as the two-byte track/sector
link required in each Commodore block), then calls CalcBlksFree to ensure that
enough free blocks exist on the disk. If there are not enough free blocks to
accomodate the data, BIkAlloc returns an INSUFFICIENT^SPACE error
without allocating any blocks. Otherwise, BIkAlloc calls SetNextFree to
allocate the proper number of unused blocks.
C64 & C128: The Commodore version of BIkAlloc builds out a track and sector table in the
buffer pointed to by TSTABLE. The 256 bytes at fileTrScTab are usually used
for this purpose. When BIkAlloc returns, the table contains a two-byte entry for
each block that was allocated: the first byte is the track and the second byte is the
sector. The last entry in the table has its first byte set to $00, indicating the end of
the table. The second byte of the last entry is an index to the last byte in the last
block. This track/sector list can be passed directiy to WriteFile for use in writing
data to the blocks.
BIkAlloc does not automatically write out the BAM. See PutDirHead for more
information on writing out the BAM. BIkAlloc does not allocate blocks on the
directory track. Refer to GetFreeDirBlk for more information on allocating
directory blocks.
Apple: The Apple version of BIkAlloc builds out a list of allocated blocks in the internal
INDEXBLOCKBUF buffer. This index block is a modified 512-byte ProDOS
sapling index block. The block is divided into two 256-byte portions. The lower
half (bytes through 255) represent the low-bytes of the data blocks and the
upper half (bytes 256 through 511) represent the associated high-bytes.Byte
and byte 256+0 combine to form the block number of the first data block, byte 1
and byte 256+1 combine to form the number of the second data block, and so on
for each allocated block. A block pointer of $0000 ($00 high, $00 low) represents
the end of the list
The last two pointers in the index block — the ones in a standard ProDOS sapling
index that point to the 254tii and 255th blocks in the chain — comprise a four-byte
size value in GEOS. The four-byte value, which represents the number of bytes
stored in the allocated blocks, can be accessed using the following offsets into the
index block:
DSIZEO Low byte
DSIZEl
33
BIkAiloc
DSIZE2
DSIZE3 High byte
BIkAlIoc does not patch the size information into INDEXBLOCKBUF. The
application must, therefore, do this itself before writing the index block to disk.
However, because INDEXBLOCKBUF is in auxiliary memory, applications
cannot patch the index block direcdy from main memory. MoveAuxData can
transfer the 5 12 bytes from auxiliary to a buffer visible from main memory.
LoadW rO, # INDEXBLOCKBUF / copy
LoadW rl, tdliskBlkBuf / to t
LoadW 12, #BLOCKSIZE ; move
Ida #AUXtoMAIN ; copy
jsr MoveAuxData ;
The size information can then be patched
the last two block pointers.
from index blk
imp buffer
a full block
aux to main
into the index block, masquerading as
MoveB dataSize+0,diskBlkBuf +DSIZEO ; transfer size bytes
MoveB dataSize+l^diskBlkBuf+DSIZEl ; (low to high order)
MoveB dataSize+2,diskBlkBuf+DSIZE2 ;
MoveB dataSize+3,diskBlkBuf+DSIZE3
The block can then be transferred back to INDEXBLOCKBUF.
LoadW rO, #diskBlkBuf ; copy from buffer
LoadW rl, # INDEXBLOCKBUF ; back to index block
LoadW t2, #BL0CKSIZE ; move a full block
Ida #MAINtoAUX ; copy main to aux
jsr MoveAuxData ;
Use the index block to write out the appropriate data, perhaps by calling
WriteFile, then use PutBIock to write out the index block to a previously
allocated block.
MoveW yourlndex^rl ; where to write block (you suppy)
LoadW tA, # INDEXBLOCKBUF ; where data is
LoadB RWbank, #AUX ; bank to aux
jsr PutBIock / write out block
LoadB RWbank, #MAIN ; back to main
BlkAlloc does not flush the VBM cache. See PutVBM for more information on
flushing the cache.
Note: For more information on the scheme used to allocate successive blocks, refer to
SetNextFree.
Example:
GrabSomeBlocks :
LoadW* r2,#BUF_SIZE
.if (C64 I I C128)
LoadW r6, #f ileTrSecTab
.endif
jsr
txa
bne
BlkAlloc
99$
number of bytes to allocate
CBM needs buffer to build out table
of links. APPLE will automatically use
INDEXBLOCKBUF
allocate the blocks
check status
and exit on error
34
BIkAlloc
; more code here
99$: rts ;exit
.ramsect
K « 1024 ;. one kilobyte
buffer": .block 5*K ; 5K buffer
BUF_SIZE = (*-buffer)+l ; size of buffer
•psect
For a more detailed example, see WritFile.
See also: NxtBlk Alloc, SetNextFree, GetFreeDirBlk, FreeBIock.
35
BlockProcess
BlOCkPrOCeSS (Apple, C64, C128)
process!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Block a processes events,
X PROCESS — process to block (0 to n-1, where n is the number of
processes in the table) (byte)-
X unchanged.
a
BlockProcess causes MainLoop to ignore the runable flag of a particular
process so that if a process timer reaches zero (causing the process to become
runable) no process event is generated until the process is subsequently
unblocked with a call to UnblockProcess. BlockProcess stops the process at
the MainLoop level. Refer to FreezeProcess to stop the process at the Interrupt
Level.
BlockProcess does not stop the countdown timer, which continues to
decrement at Interrupt Level (assuming the process is not frozen). When the timer
reaches zero, the runable flag is set and the timer is restarted. As long as the
process is blocked, though, MainLoop ignores this runable flag and, therefore,
never generates an event. When a blocked process is later unblockeki, MainLoop
checks the runable flag. If the runable flag was set during the time the process
was blocked, this pending event generates a call to the appropriate service
routine. Only one event is generated when a process is unblocked, even if the
timer reached zero more than once.
If a process is already blocked, a redundant call to BlockProcess has no effect.
SuspendClock:
Idx
jmp
#CLOCK__PROCESS
BlockProcess
X <- process number of the clock
block that parictular process
See also:
UnblockProcess, FreezeProcess.
36
BMult (Apple, C64, C128)
BMult
mathl
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
SeeAIso:
Unsigned word-by-byte multiply: multiplies an unsigned word and an unsigned
byte to produce an unsigned word result
X OPERANDI — zero-page address of word multiplicand (byte pointer to
a word variable).
y OPERAND2 — zero-page address of multiplier (byte pointer to a word
variable — use a word variable; only the low-byte is used in the
multiplication process, but the high-byte of the word is destroyed).
Note: result = OPERANDI (word) * 0PERAND2(byte).
X, y unchanged.
word pointed to by OPERANDI has its high-byte set to $00, and its low-byte
unchanged.
word pointed to by OPERANDI contains the word result,
a, r6-r8.
BMult is an unsigned word-by-byte multiplication routine that multiplies the
word at one zero-page address by the byte at another to produce a 16-bit word
result. BMult operates by clearing the the high-byte of OPERANDI and calling
DMult. The result is stored as a word back in OPERANDI.
Because r6, r7 and r8 are destroyed in the multiplication process, they cannot be
used to hold the operands.
Overflow in the result (beyond 16-bits) is ignored.
Multiply the value in r9 by 87 and store the result back in r9
(rl is destroyed)
Idx #r9 ; point to OPERANDI in r9
LoadB rlL, #87 ; rl <- 87 (0PERAND2)
Idy #rl / point to 0PERAND2 in rl
jsr BBMult / r9 <- r9 * rlL
BBMult, DMult, Ddiv, DSdiv.
37
BootGEOS
BoOtGEOS (C64, C128)
internal I
Function:
Parameters: none.
Returns:
Destroys:
Description
Restart GEOS from a non-GEOS application.
Example:
Does not return,
n/a
BootGEOS provides a method for an non-GEOS to run in the GEOS
environment — starting up from die deskTop and returning to GEOS when done.
The non-GEOS application need only preserve the area of memory between
BootGEOS ($cOOO) and BootGEOS+$7f ($c07f). The rest of the GEOS
Kemal may be overwritten. To reboot GEOS, simply jmp BootGEOS, which
completely reloads the operating system (either from disk in a "boot" procedure or
from a RAM-expansion unit in an "rboot" procedure) and returns to the GEOS
deskTop.
A program can check to see if it was loaded by GEOS by checking the memory
starting at $c006 (bootName) for the ASCII (not CBMASCH) string "GEOS
BOOT". If loaded by GEOS, the program can check bit 5 of $c012
(sysFlgCopy): if this bit is clear, ask the user to insert their GEOS boot disk
before continuing, otherwise a boot disk is not needed because GEOS will rboot
from die RAM expansion unit. To actually return to GEOS, set CPU DATA to
$37 (KRNL BAS 10 IN) on a Commodore 64 and set config to $40
(CKRNL BAS I(T iK) on a Commodore 128, tiien jump to BootGEOS
($cOIO).
BYTESTOSAVE
RBOOT BIT
$80
5
; no. of bytes to save at BootGEOS
; bit in sysFlgCopy to check
OnEntry :
Idx
10$:
Ida
sta
dex
bne
rts
.ramsect
GEOS__save
.psect
#BYTESTOSAVE
BootGEOS-lr X
GEOS_save-l,x
10$
.block BYTESTOSAVE
save bytes GEOS needs so we can use area
START LOOP
copy a byte
count —
if (count !« 0), then loop
ENDLOOP
save area for GEOS restart block
OnExit:
.if (C646&C128)
.echo Warning: expected both C64 and C128 constants TRUE
.endif
Ida
cmp
bit
Ida
bpl
128$:
Ida
sta
version
#$13
64$
cl28Flag '
64$
CKRNL_BAS__IO__IN
config
Get, version of GEOS
If version < 1.3, then branch
Else, test for GEOS 128
If GEOS64, then branch
load 128 memory mapping
38
BootGEOS
bra
200$
Ida
#KRNL_BAS_IO IN ,
' load 64 memory mapping
sta
CPU_DATA
Idx
tBYTESTOSAVE
• restore bytes GEOS needs
to restart
' STARTLOOP
Ida
GEOS_save-l, X
• copy a byte
sta
BootGEOS-l,x
dex
count —
bne
10$
if (count !=» 0) , then
loop
• ENDLOOP
Ida
#(%1«RB00T_BIT)
? check for Rboot flag
and
sysFlgCopy
bne
99$
? if flag is clear, branch
to rboot
jsr
AskForBootDisk
• else, get user to insert
boot disk
jmp
BootGEOS
See also: Firstlnit, StartAppI, GetFile, EnterDeskTop.
39
This page intentionally left blank to maintain right/left (verso/recto)
page ordering. Final version will correct this.
CalcBlksFree (Apple, C64, ci28)
mid-level disk I
Function: Calculate total number of free blocks on disk.
Parameters: Commodore:
rS DIRHEAD — address of directory header, should always point to
curDirHead (word).
Apple:
none.
Uses:
curDrive
Commodore:
dirZHeadt
dirSHeadt
Apple:
curVBlknot
VBMchangedt
numVBMBIkst
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
Returns:
^used internally by GEOS disk routines; applications generally don't use.
r4 number of free blocks.
Applg:
X
error ($00 = no error).
Commodore:
rS unchanged.
r3 in GEOS vl.3 and later: total number of available blocks on empty disk.
This is useful because vl.3 and later support disk devices other than the
1541. GEOS versions earlier than vl.3 leave r3 unchanged.
Destroys: a, y.
Description: CalcBlksFree calculates the number of free blocks available on the disk. An
application can call CalcBlksFree, for example, to tell the user the amount of
free space available on a particular disk. GEOS disk routines that allocate multiple
blocks at once, such as Blk Alloc, call CalcBlksFree to ensure enough free
space exists on die disk to prevent a surprise INSUFFICENT^SPACE error,
midway through the allocation. (This is why it is usually not necessary to check
for sufficent space before saving a file or a VLIR record— die higher level GEOS
disk routines handle this checking automatically.)
C64 & C128: The Commodore version of CaclBlksFr6e looks at the BAM in memory and
counts the number of unallocated blocks. The BAM is stored in the directory
header and the directory header is stored in the buffer at curDirHead. Calling
CalcBlksFree requires first loading rS with the address of curDirHead.
LoadW r5, #curDirHead ; point to the directory header
jsr CalcBlksFree ; before calling CalcBlksFree
1
CalcBlksFree
When checking the total number of blocks (both allocated and free) on a particular
disk device, call CalcBlksFree with r3 loaded with the number of blocks on a
1541 disk device. On GEOS vL3 and above, this number is changed to reflect
the actual number of blocks in the device. On previous versions of GEOS, r3
comes back unchanged.
Apple:
Example:
N1541_BLOCKS
LoadW
LoadW
jsr
= 664
r3, #N1541_BLOCKS
r5, #curDirHeacl
CalcBlksFree
total number of blocks on 1541 devices
assume 1541 block count for vl.2 Kernals
point to the directory header
r3 comes back with total number of blocks
on this device
The Apple version of CalcBlksFree looks through the VBM blocks on the disk
Oarger capacity disks may have more than one) and determines the number of
unallocated blocks by counting the allocation bits.
CheckDiskSpace
DESCRIPTION: Ensures that the current disk has a enough space for a
minimum number of bytes. Does not take into account any
index blocks or other blocks needed to maintain the file
structure. Works with GEOS 64, GEOS 128, and Apple GEOS.
r2 number of bytes we need
X = error if any. If not enough space# returns an
INSUFFICIENT_SPACE error.
a, y, r2, r3, r8, r9
PASSED:
RETURNS:
DESTROYED:
; Number of bytes that can be stored in each block on the disk. Accounts for
; two-byte track/sector link on Commodore versions of GEOS.
BLOCK BYTES = BLOCK SIZE- ( (C64 I 1 128) *2)
CheckDiskSpace
r2 « # of BYTES to check for
Ida
r2L
check if zero bytes requested
ora
r2H ;
beq
80$ ;
if so, exit with no error
LoadW
r3,#BL0CK BYTES ;
r3 <- number of bytes per block.
Idx
#r2 ;
divide r2 by r3 to get number of
Idy
#r3 ;
blocks to hold BYTES
jsr
Ddiv ;
r2 <- r3/r2 ; r8L <- remainder
Ida
r8L ;
Any remainder bytes?
ora
r8H
beq
5$
if not, OK
IncW
r2
otherwise 1 more block needed
5$:
' r2 « BLOCKS needed to hold BYTES
• get number of free blocks on dis
.if (C64I IC128)
• CBM GEOS requires extra step
LoadW
r5,#curDirHead ,
point to directory header
.endif
jsr
CalcBlksFree ,
• r4 <- free blocks on disk
.if (APPLE)
• APPLE GEOS must error check here
txa
check status
bne
100$
branch to exit with error...
.endif
Idx
#INSUFFICIENT_SPACE
; assume not enough space
CmpW
r2,r4
• are there enough free blocks?
2
CalcBlksFree
80$:
100$:
bgt
Idx
rts
100$
#N0 ERROR
if not, asssump. correct, branch,
otherwise, no error
exit
See also:
BIkAlloc, SetNextFree, FreeBlock.
3
CallRoutine
ICallRoutine (Apple, C64, cus)
utility
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Perform a pseudo-subroutine call, checking first for a null address (which will be
ignored).
a [ADDRESS — low byte of subroutine to call.
X ] ADDRESS — high byte of subroutine to call.
where ADDRESS is the address of a subroutine to call.
depends on subroutine at ADDRESS.
depends on subroutine at ADDRESS.
CallRoutine offers a clean and simple way to perform an indirect jsr through a
vector or call a subroutine with an address from a jump table. Before simulatin a
jsr to the address in the x and a registers, it also checks for a null address
($0(XX)). If the address is $(XXX) (x=$00 and a=$(X)), CallRoutine performs rts
without calling any subroutine address. This makes it easy to nullify a vector or
an entry in a jump table by using a $(XXX) value.
GEOS frequentiy uses CallRoutine when calling through vectors. This is why
placing a $00(X) into keyVector, for example, causes GEOS ignore the vector.
Other examples of tiiis usage are intTopVec, intBotVec, and mouse Vector.
CallRoiitine modifies the st register prior to performing the jsr. It, therefore,
cannot be used to call routines that expect processor status flags as parameters
(flags may be returned in the st register, however). CallRoutine may be called
from Interrupt Level (off of routines in IntTopVec and IntBotVec). Do not use
CallRoutine to call inline (i_) routines, as it will not return properly.
HandleCommand
^******-'******<* ******
DESCRIPTION: Given a command number this routine handles dispatching
control to the appropriate routine.
PASSED: y command number
RETURNS: depends on command
DESTROYED: depends on command
***************************************************************************
HandleCommand :
cpy #T0T_CMDS-1
bgt 99$
Idx CMDtabH,y
Ida CMDtabL,y
jsr CallRoutine
99$:
rts
/ check command # against last cmd num
; exit if command is invalid
; get high byte routine address
; get low byte of routine address
; call the routine
s
; exit
; The table below is a collection of the the high/low bytes of the routine
; associated with each command number. If a command is not yet implemented.
4
CallRoutine
; use the UNIMPLEMENTED constant (SOOOO) to have it ignored,
UNIMPLEMENTED » $0000 ; CallRoutine ignores this
CMDtabH:
.byte
.byte
.byte
.byte
.byte
.byte
/high bytes
] UNIMPLEMENTED
ICmdl
]Cmd2
]Cmd3
)Cmd4
ICmdS
command
command 1
command 2
command 3
command 4
command 5
CMDtabL:
.byte
.byte
.byte
.byte
.byte
.byte
;low bytes
[UNIMPLEMENTED
(Cmdl
[Cmd2
(Cmd3
[Cmd4
(Cmd5
command
command
command
command
command
command
TOT CMOS
(CMDtabL-CMDtabH) /total number of commands
See also:
JsrToAux
5
CancelPrInt
CancelPrint (Apple)
printer driver
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
See also:
Cancel printing immediately, clearing any buffers on the printer card or printer,
none.
X STATUS — printer error code; $00 = no error,
assume a, y, r0-r4.
CancelPrint instructs the printer driver to cancel the current printing operation,
clearing any data already accumulated in a buffer on the printer or the printer card.
Its main use is to allow tihe application to have the printer really stop printing if the
user decides to cancel.
The CancelPrint routine does not work properly in the first and second versions
of most Apple printer drivers.
StopPrint.
I
i
6
ChangeDiskDevice
ChangePiskPevice (C64, cns)
very low-level disk]
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Instruct a drive to change its serial device number.
a hffiWDEVNUM — new device number to give current drive (byte).
curDrive drive whose device number will change.
X error ($00 = no error).
curDrive
curDevice
a, y.
NEWDEVNUM.
NEWDEVNUM.
ChangeDiskDevice requests the turbo software to change the serial device
number of the current drive. Most applications have no need to call this routine,
as it is in the realm of low-level disk utilities. ChangeDiskDevice is used
primarily by the deskTop and Configure programs to add, rearrange, and remove
drives.
Be aware that changing the device number merely instructs the turbo software in
the drive to monitor a different serial bus address. Many internal GEOS variables
and disk drivers expect the original device number to remain unchanged
Note: If ChangeDiskDevice is used on a RAMdisk, curDrive and curDevice both
change. However, because of the natiure of the RAMdisk driver, the RAMdisk
does not respond as this new device.
Apple: Apple GEOS has no ChangeDiskDevice equivalent.
See also: SetDevice.
7
ChkDkGEOS
ChkDkGEOS (C64, ci28)
mid-level disk!
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
Check Commodore disk for GEOS format
Apple:
Example:
r5
nothing
isGEOS
st
DIRHEAD — address of directory header, should always point to
curDirHead (word).
set to TRUE if disk is a GEOS disk, otherwise set to
FALSE.
set according to valu in isGEOS.
ChkDkGEOS checks the directory header for the version string that flags it as a
GEOS disk (at OFF^GEOS^ID). The primary difference between a GEOS disk
and a standard Commodore disk is the addition of the off-page directory and the
possiblity of GEOS files on the disk. GEOS files have an additional file header
block that holds the icon image and other information, such as the author name
and permanent name string. To convert a non-GEOS disk into a GEOS disk, use
SetGEOSDisk.
OpenDisk automatically calls ChkDkGEOS. As long as OpenDisk is used
before reading a new disk, applications should have no need to call
ChkDkGEOS.
All ProDOS disks are GEOS compatible.
.if (064 I IC128)
jsr GetDirHead
txa
bne 99$
LoadW r5, #curDirHead
jsr ChkDkGEOS
beq 40$
; code here to handle GEOS disk
bra 99$
50$:
. code here to handle non-GEOS disk
read in the directory header
check status
exit on error
point to directory header
Check for GEOS disk
if not a GEOS disk, branch
; jump to exit
See also:
99$: rts
SetGEOSDisk.
exit
8
ClearCard
ClearCardjAppie)
card driver I
Function: Instructs the interface card to stop transmitting data and clear its internal buffer if
it has such a feature.
Parameters: none.
Returns: x
Destroys: a, y.
Description
Note:
See also:
STATUS — card error code; $00 = no error (byte)
ClearCard instructs the interface card to immediately stop sending data and clear
its internal buffer if it has such a feature. ClearCard is designed to be called by
CancelPrint to abort any buffered print data, but, because this feature is rarely
supported by interface cards, most printer drivers omit this call to save space.
ClearCard must be called after an OpenCard and before a CloseCard.
CancelPrint.
9
ClearMouseMode
CiearMouseMode (Apple, C64, ci28)
mouse/sprite
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
Stop monitoring the input device.
nothing.
nothing.
mouseOn
mobenble
a, X, y, r3L
set to $00, totally disabling all mouse tracking
sprite M) bit cleared by DisablSprite.
ClearMouseMode instructs GEOS to totally disable its monitoring of the input
device. It clears mouseOn to reset mouse tracking to its cleared state and calls
DisablSprite. Applications will normally not have a need to call this routine. It
is the functional opposite of StartMouseMode.
See also:
StartMouseMode, MouseOff.
10
ClearRam
ClearRam (Apple, C64, cm)
memoryl
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Clear a region of memory to $00.
rl
rO
nothing.
ADDR — address of area to clear (word).
COUNT — number of bytes to clear (0 - 64K) (word).
a, y, rO, rl, r2L '
ClearRam clears COUNT bytes starting at ADDR to $00. It useful for
initializing ramsect variable and data sections.
Do not use ClearRam to initalize rO through r2L. Also, for when space is at a
premium, it actually takes fewer bytes to call i_FillRam with a fill value of $00.
initialize buffers and variables to zero
LoadW rO,#varStart ; clear variable space
LoadW rl, # (varEnd-varStart) ;
jsr ClearRam ;
LoadW rO, #heapStart ; clear heap
LoadW rl, # (heapEnd-heapStart) /
jsr ClearRam ;
See also:
FiliRam, InitRam.
11
Clockint
ClOCkInt (Apple)
clock driver!
Function:
Parameters:
Alters:
Destroys:
Description:
Example:
Qock driver Interrupt Level routine. Called by GEOS during Interrupt Level,
none.
(usually) year
month
day
hour
minutes
seconds
assume a, x, y, r0-rl5.
GEOS calls Ciockint during Interrupt Level, which allows a clock driver to
have an Interrrupt Level routine.This facility is used primarily by the software
clock, which expects to be called approximately FRAME RATE times per
second. Every time Clockint gets called, the software clock decrements a
counter that is initialized to FRAME^RATE. When the counter reaches zero,
approximately one second has elapsed.
Hardware clock drivers usually have a Clockint routine that simply performs an
rts.
.if (APPLE) ; clock drivers only exist in Apple GEOS
.★*★ Sample Clockint clock driver routine ***
**************************************************************
;o Clockint
/Synopsis:
This is called at interrupt level for the software clock.
/Author: Andrew Wilson January 1988
/Called by: Interrupt Level through clock driver jump table
/Pass: nothing
/Returns: nothing
/Alters: assume a, x, y, r0-rl5
* *****************************
o ReadClockInt:
Ida
hour
; if nothing set, exit
ora
minutes
ora
seconds
ora
year
ora
month
ora
day
beq
90$
dec
counter t
• have a second's worth of int's occurred
bpl
90$
• branch if it hasn't happened
/ this code
happens once a second.
assuming interrupts weren't shut off
Idx
#FRAME__RATE-1
• counter <- (interrupts/second)-!
stx
counter ' <
Idx
#60-1
? X <- seconds/minute (and min/hr)
• (actually, one less so we can use bge
r branch, which is smaller)
inc
seconds ,
r add one second to clock
12
Clockint
cpx
bge
seconds
90$
; do we add another minute?
; branch if seconds don't roll
; this code happens roughly once a minute, assuming interrupts weren't off
Ida
sta
inc
cpx
bge
#0
seconds
minutes
minutes
90$
; reset seconds
; save the new seconds
; add one to minutes
; do we add another hour?
; branch if minutes don't roll
; this code happens once an hour, assuming interrupts weren't off
sta
inc
Idx
cpx
bge
minutes
hour
#24-1
hour
90$
; reset minutes
/ add another hour to the software clock
; x <- (hours/day) -1
; do we add another day
; branch if hours don't roll
; this code happens once a day, assuming interrupts are off
50$:
sta hour
inc day
Idy month
Ida #28+1
sta febMonth
Ida year
and #%00000011
bne 50$
inc febMonth
Ida daysInMonth-l,y
cmp day
bne 90$
zero hours
add another day
get the current month
febMonth <- days in February+1
check for leap year
(nice and convenient that 4
is a power of 2)
if leap year, then one more day in Feb.
; see if the current day ends the month
; compare
; branch if month doesn't roll
; this code happens once a month, assuming the computer lasts that long...
Idx
stx
inc
Ida
cmp
bit
#1
day
month
month
#12
90$
first day of month
save it
add one month
see if we're past the last month
; this code happens once a year. It rolls over in 1999, and so we'll need
; a new clock driver before then...
90$:
Ida
sta
inc
rts
#1
month
year
first month of the year
new year
exit
See also:
; daysInMonth is the number of days in each month. It actually co/itains
; number of days plus one since we increment days before we check.
daysInMonth: .byte 32
febMonth: .byte 29 ; February is modified on leap years
.byte 32,31,32,31,31,32,31,32,31,32
.endif ; (APPLE)
ReadClock, AuxDInt.
13
CioseCard
CloseCard (Apple)
card driver
Function:
Parameters: none
Returns: x
Destroys: a, y.
Description
Qose access to interface card
STATUS — card error code; $00 = no error (byte)
Example:
CloseCard closes access to the interface card. It is the functional opposite of
OpenCard. The printer driver sends blocks of data to the printer between calls to
OpenCard and CloseCard. The CloseCard routine in most card drivers
simply returns without an error, but printer drivers should always bracket their
access to die card driver between calls to OpenCard and CloseCard.
.if (APPLE) ; card drivers
; Initialize the card
only exist on Apple GEOS
Dsr
txa
bne
InitCard ;
90$
; Open the card so we access the printer
OpenCard
call card driver init routine
check status
branch if error
jsr
txa ;
bne 90$ ;
; Initialize printer
Idy #PRINITCODE ;
jsr OutputByte ;
txa ;
bne 90$ /
; Close the card and exit
jsr CloseCard ;
90$:
rts
.endif ; (APPLE)
call card driver open routine
check status
branch if error
y <- control code to init printer
send through card to printer
check status
branch if error
call card driver close routine
exit with error in x
See also: OpenCard.
14
CloseRecordFile
CloseRecordFile (Apple, C64, cns)
VLIR disk
Function: Close the current VLIR file (updating it in the process) so that another may be
opened
Parameters: none.
Uses:
Returns:
Alters:
curDrive
fileWrittent
fileHeader
fileSize
dirEntryBuf
if FALSE, no updating occurs because file has not been
written to.
VLIR index table stored in this buffer,
total number of disk blocks used in file (includes index
block, GEOS file header, and all records),
directory entry of VLER file.
year, month, day, hours, minutes for date-stamping file.
Cpmrnodorg;
curType
curDirHead
dir2Headt
dir3Headt
A pple:
fileBytes
curVBlknot
VBMchangedt
numVBMBlkst
GEOS 64 V 1.3 and later for detecting REU shadowing,
this buffer must contain the current directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
total number of bytes in file (written to bytes 254, 255, 511,
and 512 of the master index block),
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
set to FALSE to indicate that file hasn*t been altered since
last updated.
used for temporary storage of the directory block.
Destroys:
Description:
C64 & C128:
Example:
See also:
^used internally by GEOS disk routines; applications generally don't use
X error ($00 = no error).
fileWrittent
diskBlkBuf
^used internally by GEOS disk routines; applications generally don't use.
a, y, rl, r4, rS.
CloseRecordFile first calls UpdateRecordFile then closes the VLIR file so
that another may be opened.
Because Commodore GEOS stores the BAM in global memory, the application
must be careful not to corrupt it before the VLIR file is updated or closed. For
more information, refer to UpdateRecordFile.
See example at AppendRecord.
OpenRecordFile, UpdateRecordFile.
15
CmpFString
CmpFString (Apple, C64, ci28)
string!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Compare two fixed-length strings.
X SOURCE — zero-page address of pointer to source string (byte pointer
to a word pointer).
y DEST — zero-page address of pointer to destination string (byte pointer
to a word pointer).
a LEN — length of strings (1-255). A LEN value of $00 will cause
CmpFString to function exacdy like CmpString, expecting a null-
terminated source string.
s t status register flags reflect the result of the comparison.
a, X, y
CmpFString compares the fixed-length string pointed to by SOURCE to the
string of the same length pointed to by DEST.
CmpFString with a LEN value of $00 causes the routine to act exactly like
CmpString.
CmpFString compares each character in the strings until there is a non-matching
pair. The result of the comparison between the non-matching pair is passed back
in the processor status register (st). If the strings match, the z flag is set. This
allows the application to test the result of a string comparison with standard test
and branch operations:
bne branch if strings don't match
beq branch if strings match
bcs branch if source string is greater than or equal to dest string
bee branch if source string is less than dest string
The strings may contain internal NULL'S. These will not terminate the
comparison.
REG SIZE
16
;size of each record
Find:
LoadW
r2,#NUM_RECS
• r2 <- total number of records
LoadW
rO,#Key
• rO <- pointer to keyword
LoadW
rl,#Data ,
• rl <- pointer to start of search list
10$:
• DO
Idx
#rO
X <- source string « key ,
Idy
#rl
y <- dest string * list
Ida
#REC_SIZE
a <- length of each record
jsr
CmpFString <
r compare key with current record
beq
20$
if they match, branch
AddVW
#REC SIZE^rl
otherwise point to the next record
DecW
r2
r2 — (decrement counter)
bne
10$
• WHILE (r2 > 0)
; code to
handle no matches goes here
rts
16
CmpFStrIng
. code to handle a match goes here
rts
Key: .byte "alpha "
Data:
.byte "ZETA
.byte "0123456789ABcDeF" '
.byte "gAMma over beta "
.byte "stewardesses "
.byte "123ABC123abc
.byte "abcdefghi jklmnop"
.byte "qrstuvwxyz012345"
•byte "stewardess "
.byte "beta "
.byte "alpha
.byte "delta "
.byte "steward "
EndData:
NUM__RECS « ( (EndData-Data) /REC_SIZE)
.if ( (Data + NUM_RECS*REC_SIZE) *)
.echo Something is wrong with sort data
.endif
See also: CmpString, CopyFString.
17
CmpStrIng
CmpString (Apple, C64, cns) string]
Function: Compares two null-terminated strings.
Parameters: x SOURCE — zero-page address of pointer to source string (byte pointer
to a word pointer).
y DEST — zero-page address of pointer to destination string (byte pointer
to a word pointer).
Returns: st status register flags reflect the result of the comparison.
Destroys: a, x, y
Description: CmpString compares the null-terminated source string pointed to by SOURCE
to the destination string pointed to by DEST. The strings are compared a byte at a
time until either a mismatch is found or a null is encountered in both strings.
CmpString expects the strings to be the same length; strings of different lengths
are treated as not matching.
CmpString compares each character in the strings until tiiere is a non-matching
pair. The result of the comparison between the non-matching pair is passed back
in the processor status register (st). If the strings match, the z flag is set. This
allows the application to test the result of string comparison with standard test and
branch operations:
bne branch if strings don't match
beq branch if strings match
bcs branch if source string is greater than or equal to dest string
bee branch if source string is less tiian dest string
Note: CmpString cannot compare strings longer than 256 bytes (including the null).
The compare process is aborted after 256 bytes.
Example:
Findi2:
LoadW
rO,#Original
; rO <- pointer to original string
LoadW
rl, #Copy
; rl <- pointer to copy
Idx
#rO
; X <- source string =* key
Idy
#rl
; y <- dest string « list
jsr
CmpString
; compare the strings
beq
20$
/ if they match, branch
code to
handle no matches goes here
rts
code to
TZ3
handle a match
goes here
Origi
.,/ce
"Mark Charles
Heartless", NULL
Copy:
.byte
"Mark Charlie
Heartless", NULL
See also: CmpFString, CopyString.
18
CopyFString (Apple, C64, cns)
string!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Copy a fixed-length string.
X SOURCE — zero-page address of pointer to source string (byte pointer
to a word pointer).
y DEST — zero-page address of pointer to destination buffer (byte pointer
to a word pointer).
a LEN — length of string (1-255). A LEN value of $00 will cause
CopyFString to function exactiy like CopyString, expecting a null-
terminated source string.
Buffer pointed to by DEST contains copy of source string.
a, X, y
CopyFString copies a fixed-length string pointed to by SOURCE to the buffer
pointed to by DEST. If Uie source and destination areas overlap, the source must
be lower in memory for the copy to work properly.
Because the LEN parameter is a one-byte value, CopyFString cannot copy a
string longer tiian 255 bytes. A LEN value of $00 causes CopyFString to act
exacdy like CopyString.
The source string may contain internal NULL'S. These will not terminate the
copy operation.
LoadW
LoadW
Idx
Idy
Ida
jsr
SrcString:
LENSTRING
.ramsect
DestString
•psect
r5, #SrcString
rll,#DestString
#r5
#rll
# LENSTRING
CopyFString
point to start of source string
point to start of destination string
X <- source register address
y <- dest register address
a <- length of string
DestString <- SrcString (copy)
.byte -This is a string", CR, LF
- (*-SrcString)
.blocJc LENSTRING
See also: CopyString, CmpFString, M oveData.
19
CopyFullScreen
CopyFullScreen (Apple)
graphics!
Function:
Parameters:
Destroys:
Description:
Note:
Example:
Copy a rectangle of the full width of the screen to another position vertically.
Operates only on the foreground screen.
rOL SRCYl — top line of source region (byte).
rOH SRCY2 — bottom line of source region (byte).
r3L DESTY — top line of destination (byte).
where (0, SRCYl) defines the upper-left corner of the source rectangle,
(SCJPIXJVIDTH'1,SRCY2) defines the lower-right corner of the source
rectangle, and (Oj:>ESTY) defines the upper-left corner of the destination.
a, X, y, rO, r3L
CopyFullScreen is optimized to quickly copy a rectangular area of the full
width of the screen. It copies the desired lines from the source to the destination
(which may overlap if necessary). The copy only occurs on the foreground
screen.
No clipping at the screen top or bottom is performed; the values passed are
assumed to lie entirely within tiie screen boundaries.
.if (APPLE)
SCROLL_TOP
SCROLL__BOT
SCROLL INC
» SC_PIX_HEIGHT-1
= 2
top line of scroll region
bottom line of scroll region
lines to scroll
ScrollUp:
LoadB rOL, #SCROLL_TOP+SCROLL_INC
LoadB rOH, #SCROLL_BOT
LoadB r3L, #SCROLL_TOP
jmp CopyFullScreen
ScrollDown :
LoadB rOL, #SCROLL__TOP
LoadB rOH, #SCROLL_BOT-SCROLL_INC
LoadB r3L, #SCROLL_TOP+SCROLL_INC
jmp CopyFullScreen
.endif ; (APPLE)
rOL <- top of source
rOH <- bottom of source
r3L <- destination
scroll, let CopyFullScreen rts
rOL <- top of source
rOH <- bottom of source
r3L <- destination
scroll, let CopyFullScreen rts
See also: CopyLine, CopyScreenBlock
20
CopyLine
CopyLine (Apple)
graphics!
Function:
Parameters:
Uses:
Destroys:
Description:
Note:
Example:
See also:
Copy a horizontal line to another pixel location; operates on pixel boundaries.
r 1 SRCXl — x-co6rdinate of left edge of source line (word).
r2 SRCXl — x-coordinate of right edge of source line (word).
rOL SRCY — y-coordinate of source line (byte).
r4 DESTX — x-coordinate of left edge of destination (word).
r3L DESTY — y-coordinate of destination (byte).
where (SRCXl, SRCY) and (SCRC2,SRCY) define the endpoints of the line to
move to (DESTX,DESTY).
dispBufferOn:
bit 7 — copy from foreground screen if set.
bit 6 — copy from background buffer if set
If both bits are set, copy occurs on both screens.
a, X, y
CopyLine copies pixels from a horizontal source line to a destination line. The
source and destination coordinates may lie on any pixel boundary. Pixels will be
shifted if necessary. The source and destination may overlap.
No clipping at the screen edge is performed; the values passed are assumed to lie
entirely within the screen boundaries. Also, the copying is appreciably faster if
the left-edge x-coordinates of the source and destination lie on the same bit-
boundary. That is, if (SRCXl IP ) == {DESTX II 7).
CopyFullScreen, CopyScreenBlock
J
21
CopyScreenBlock
CopyScreenBlock (Apple)
graphics}
Function:
Parameters:
Uses:
Copy a rectangular portion of the screen to another area.
rl SRCXl — x-coordinate of upper-left of source (word),
rOL SRCYl — y-coordinate of upper-left of source (byte)
r2 SRCX2 — x-coordinate of lower-right of source line (word).
rOH SRCY2 — y-coordinate of lower-ri^t of source (byte).
r4 DESTX — x-coordinate of upper-left of destination (word).
r3L DESTY — y-coordinate of upper-left of destination (byte).
where (SRCXl, SRCYl) defines the upper-left corner of the source rectangle,
(SCRCX2,SRCY2) defines the lower-right corner of the source rectangle and
(DESTXJDESTY) defines the upper-left corner of the destination.
dispBufferOn:
bit 7 — copy from foreground screen if set.
bit 6 — copy from background buffer if set
If both bits are set, copy occurs on both screens.
Destroys: a, x, y
Description:
Note:
CopyScreenBlock copies pixels from a source rectangle to a destination
rectangle. The source and destination coordinates may lie on any pixel boundary.
Pixels will be shifted if necessary. The source and destination rectangles may
overlap.
No clipping at the screen edge is performed; the values passed are assumed to lie
entirely within the screen boundaries. Also, the copying is appreciably faster if ^
the left-edge x-coordinates of the source and destination lie on the same internal '
bit-boundary. That is, if (SRCX1%7) == (DESTX%7).
Example:
.if (APPLE)
;*** Window Coordinate Constants ***
WIN__X
WIN_WIDTH
WIN~Y
WIN^HEIGHT
WIN_X2
WIN_Y2
SCROLL^INC
ScrWinUp:
Jsr
LoadB
LoadB
LoadB
jmp
ScrWinDown :
Jsr
= 20
« 85
» 40
- 110
- win_x+win_width
» win"y+win_hieght
- 2
; scroll window up
SetScrXPositions
rOL, #WIN_Y+SCROLL_INC
rOH,#WIN_Y2
r3L, #WIN_Y
CopyScreenBlock
; scroll window down
SetScrXPositions
pixel x-position (left edge)
pixel width
y-position
height
right edge x-position
bottom edge y-position
lines to scroll
set the x-coordinates for scroll
rl <- left edge source
r2 <- right edge source
r4 <- left edge dest (== rl)
rOL <- top of source
rOH <- bottom of source
r3L <- top edge of dest
scroll, let CopyScreenBlock rts
set the x-coordinates for scroll
22
CopyScreenBlock
LoadB rOL, #WIN__Y
LoadB rOH, #WIN_Y2-SCR0LL_INC
LoadB r3L, #WIN_Y+SCROLL_INC
jmp CopyScreenBlock
rl <- left edge source
r2 <- right edge source
r4 <- left edge dest («» rl)
rOL <- top of source
rOH <- bottom of source
r3L <- top edge of dest
scroll, let CopyScreenBlock rts
SetScrXPositions : ; Set the common dimensions for up or down scroll
— Following lines changed to save bytes
LoadW
rl,#WIN_
X
rl <- left edge of source
LoadW
r4,#WIN"
[x
r4 <- left edge of dest
Ida
#[WIN_x"
get low byte of left edge
sta
rlL
and store it in low byte of
sta
r4L
source and dest left edge
Ida
#)WIN_X
do the same with the hi byte
sta
rlH
sta
r4H
LoadW
r2, #WIN_
_X2
• r2 <- right edge of dest
rts
• exit
.endif ; (APPLE)
23
Dabs (Apple, C64, C128)
mathl
Function: Compute absolute value of a two's-complemcnt signed word
Parameters: x OPERAND — zero-page address of word to operate on (byte pointer to a
word variable).
Returns: x,y unchanged
word pointed to by OPERAND contains the absolute value result
Destroys: a
Description: Dabs takes a signed word at a zero-page address and retumes its absolute value.
The address of the word (OPERAND) is passed in x. The absolute value of
OPERAND is returned in OPERAND.
Example:
SeeAlso:
The equation involved is: if (value < 0) then value = -value.
DNegate.
41
Ddec
DdeC (Apple, C64, C128)
mathl
Function:
Decrement a word
Parameters: x
OPERAND — zero-page address of word to decrement (byte pointer to a
word variable).
Returns: x,y unchanged
St z flag is set if resulting word is $(XXX).
zero page word pointed to by OPERAND contains the decremented word.
Destroys: a
Description:
Ddec is a double-precision routine that decrements a 16-bit zero-page word
Oow/high order), llie absolute address of the word is passed in x. If the result of
the decrement is zero, then the the z flag in the status register is set and can be
tested with a subsequent beq or bne. Ddec is useful for loops which require a
two-byte counter.
Example:
COUNT
counter
Ida
sta
Ida
sta
Idx
10$:
nop
jsr
bne
- $fffO
- aO
# (COUNT
counter
# 1 COUNT
counter+1
♦counter
Ddec
10$
/counter value
•pseudoreg to count with
;init pseudoregister
;with counter value
;tell Ddec which zp reg to use
;do nothing in loop
/decrement counter (x > reg addr.)
;loop until done.
42
Ddiv
Ddiv (Apple, C64, C128)
math
Function: Unsigned word-by-word (double-precision) division: divides one unsigned word
by another to produce an unsigned word result
Parameters: x
Returns:
OPERANDI — zero-page address of word dividend (byte pointer to a
word variable).
y 0PERAND2 — zero-page address of word divisor (byte pointer to a
word variable).
Note: result = OPERANDI (word) I OPERAND2(word).
X, y, and word pointed to by OPERANDI unchanged,
word pointed to by OPERANDI contains the result
r8 contains the fractional remainder (word).
Destroys: a, r9
Description: Ddiv is an unsigned word-by-word division routine that divides the word at one
zero-page address (the dividend) by the word at another (the divisor) to produce a
16-bit word result and a 16-bit word fractional remainder The word in
OPERANDI is divided by the word in OPERANDI and the result is stored as a
word back in OPERANDI. The remainder is returned in r8.
Note: Because rS and r9 are used in the division process, they cannot be used to hold
operands.
If the divisor {OPERANDI) is greater than the dividend (OPERANDI), then the
fractional result will be returned as $0000 and OPERANDI will be returned in
rS.
Although dividing by zero is an undefined mathematical operation, Ddiv makes
no attempt to flag this as an error condition and will simply return incorrect
results. If the divisor might be zero, the application should check for tiiis situation
before dividing as in:
Ida
zpage,y
;get low byte of divisor
ora
zpage-»-l,y
/get high byte of divisor
bne
10$
;if either non-zero, go divide
Jmp
OivideByZero
/else, flag error
jmp
Ddiv
/divide (Ddiv will rts)
There is no possibUity of overflow (a result which cannot fit in 16 bits).
Example:
SeeAIso: DSdiv. DMuIt. BMult, BBMult, DivideBySeven.
43
DeleteDir
DeleteDir (Apple)
high-level disk
Function: Delete a subdirectory from the current directory by freeing its directory blocks and
removing its directory entry. The subdirectory must not contain any files to be
deleted
Parameters: rO
DIRNAME — pointer to null-terminated directory name (must be in
main memory.) (word).
Uses:
curDrive
curKBlkno
curVBIknot
VBMchangedt
numVBMBIkst
current directory,
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
Returns:
Alters:
^used internally by GEOS disk routines; applications generally don't use.
X error ($(X) = no error).
diskBlkBuf
curVBIknot
VBMchangedt
used for temporary block storage,
used by VBM cacheing routines.
set to FALSE by VBM cacheing routines to indicate cached
VBM block has already been flushed
Destroys:
^used internally by GEOS disk routines; applications generally don't use.
a, y, rl, r4-r7, r8H.
Description: Given the null-terminated name of an empty subdirectory, DeleteDir will
remove the subdirectory from the disk by deleting its directory entry and calling
FreeDir to free its chain of directory blocks.
DeleteDir first calls FindFile to get the directory entry of the subdirectory. If
the subdirectory does not exist in Ac current directory, a FILE^NOT^FOUND
error is returned. A subdirectory is recognized by a PRO DIR in the CjEOS type
byte in the directory entry (at OFF^FTYPE).
DeleteDir will not delete a subdirectory that has files in it. A
DIR_NOT EMPTY error will be returned. (The number of files in tiie
subdirectoryls stored in the OFFB_FLCNT word of the directory's header.
This maintains this value by calling UpdateParent when files are added or
removed)
C64 & C128: Commodore GEOS does not support a hierarchical file system.
Example:
See also:
DeleteDir, DeleteFile, FreeFile, FreeBIock.
44
DeleteFile
DeleteFile (Apple, C64, ci28)
high-level disk|
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Delete a GEOS file by deleting the its directory entry and freeing all its blocks.
Works on both sequential and VLIR files.
rO FILENAME — pointer to null-terminated name of file to delete (Apple
GEOS: must be in main memory,) (word).
curDrive
Cpmmpijorg;
curType
Apple:
curVBlknot
VBMchangedt
numVBMBlkst
GEOS 64 vl.3 and later for detecting REU shadowing.
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
diskBlkBuf
dirEntryBuf
Commodore:
curDirHead
dir2Headt
dirSHeadt
flleHeader
Apple;
curVBlknot
VBMchangedt
used for temporary block storage,
deleted directory entry.
BAM updated to reflect newly freed blocks.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
temporary storage of index table when deleting a VLIR file.
used by VBM cacheing routines.
set to FALSE by VBM cacheing routines to indicate cached
VBM block has already been flushed
^used internally by GEOS disk routines: applications generally don't use.
Commodore:
a, y, r0-r9.
Apple:
a, y, rl, r2L, r4-r7, rSH, r9.
Given a null-terminated filename, DeleteFile will remove it from the current
directory by deleting its directory entry and calling FreeFile to free all the blocks
in the file.
DeleteFile first calls FindFile to get the directory entry and ensure the file does
in fact exist. If the file specified with FILENAME is not found, a
FILE NOT FOUND error is returned.
45
DeleteFile
C64 & C128: Since Commodore GEOS does not support a hierarchical file system, the "current
directory" is actually the entire disk. The directory entry is deleted by setting its
OFF^CFILE^TYPE byte to $00.
Apple: Will only delete a file from the current directory. To delete a file from another
directory, the application must change directories (refer to GoDirectory for
moving to another directory).
The directory entry is deleted by setting its OFF^FSTORE byte to $00. If this
directory entry is the last in a particular directory block, the block is removed and
the previous directory block's next-block pointer (at OFFB_NXTBLK) is
given the deleted directory's next-block pointer, thereby maintaining the
continuity of the directory block chain.
After deleting the directory entry, DeleteFile calls UpdateParent to update the
status bytes of the parent directory.
DeleteFile cannot delete a subdirectory. To delete a subdirectory, use
DeleteDir.
Example:
See also:
DeleteDir, FreeDir, FreeFile, FreeBIock.
DeleteRecord
DeleteRecord (Apple, C64, ci28)
VLIR disk!
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Removes the current VLIR record from the record list, moving all subsequent
records upward to fiU the slot and freeing all the data blocks associated with the
record.
none.
curDrive
fileWrittent
curRecord
fileHeader
Commodore:
curType
curDirHead
dir2Headt
dir3Headt
Apple;
curVBlknot
VBMchangedt
numVBMBlkst
if FALSE, assumes record just opened (or updated) and
reads B AWVBM into memory.
current record pointer
VLIR index table stored in this buffer.
GEOS 64 V 1.3 and later: for detecting REU shadowing,
current directory header/B AM.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use
X error ($00 = no error).
«
curRecord
fileWrittent
fileHeader
fileSize
Commodore!
curDirHead
dir2Headt
dir3Headt
Apple:
fileBytest
only changed if deleting the last record in the table, in which
case it becomes the new last record,
set to TRUE to indicate the file has been altered since last
updated.
new record added to index table.
decremented to reflect any deleted record blocks.
current directory header/BAM modified to finee blocks.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
decremented to reflea any deleted record data.
^used internally by GEOS disk routines: applications generally don't use.
Applg;
a, y, rl-r2, r4, r6, r7, r8H.
Commodore:
a, y, r0-r9.
47
DeleteRecord
Description: DeleteRecord removes the current record from the record list by moving all
subsequent records upward to fill the current record's slot. Any data blocks
associated with the record are freed
DeleteRecord does not update the B AMATBM and VLIR file information on the
disk. Call CIoseRecordFile or UpdateRecordFile to update the file when
done modifying.
Example:
See also: AppendRecord, InsertRecord.
48
DIsablSprite
DisablSprite (Apple, C64, ci28)
spritel
Function: Disable a sprite so that it is no longer visible.
Parameters: r3L SPRITE — sprite number (byte).
Returns: nothing.
Alters: mobenble
Destroys: a, x
Description: DisablSprite disables a sprite so that it is no longer visible. Although there are
eight sprites available, an application should only directly disable sprite #2
through sprite #7 with DisablSprite. Sprite #0 (the mouse pointer) is always
enabled when GEOS mouse-tracking is enabled (disable mouse-tracking with
mouseOff)* and sprite #1 (the text cursor) should be disabled with PromptOff.
Example:
See also:
EnablSprite, MouseOff, PromptOff, DrawSprite, GetSpriteData,
PosSprite, InitSprite.
DivideBySeven
DivideBySeven (Apple)
graphics
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Quickly divide a word value (between and 649) by seven for direct screen
access graphic operations.
a ]DIVIDEND — high byte of word to divide by seven (byte),
X [DIVIDEND — low byte of word to divide by seven (byte).
a quotient (byte),
y remainder (byte).
X unchanged.
DivideBySeven is a highly specialized divide routine designed for applications
that require direct screen access. The Apple's double high-res screen is based on a
seven-bit byte which requires dividing the x-posirion by seven to calculate the
byte-position. The quotient is the byte position in a scanline and the remainder is
the bit-position in that byte. DivideBySeven uses a series of lookup tables to
quickly calculate the quotient and the remainder.
Although the maximum screen x-position on the Apple is 559
(SC^PIX^WIDTH - 1), DivideBySeven will handle values up to 649 so
that graphics can be generated for 64()-column printer drivers.
The average computational time for DivideBySeven is roughly 21 cycles.
XorPoint — invert a single screen point on Apple.
«
Pass: r3 x-coordinate
rllL y-coordinate
Uses:
dispBuf ferOn
Destroys:
a, X, rS, r6.
XorPoint:
jsr
Idx
jsr
Ida
Idx
jsr
pha
tya
tax
Pla
jsr
Ida
SetCorrectPage
GrBit Table, X
TempHideMouse
rllL
GetScanLine
DivideBySeven
r3H
r3L
/turn off sprites temporarily
;get y-coordinate
;set r5 and r6 with scanline addressses
;get hi of x-coordinate
;get lo of x-coordinate
/calculate byte and bit offsets
/save byte offset
/transfer bit offset to x-register
/to pass to SetCorrectPage
/and put byte offset into a-reg
/ (see GetScanLine reference)
/get pixel bit-mask
/xor pixel in first buffer
/store into both buffers
/if necessary
eor
St a
sta
rts
(r6),y
(r5),y
(r6),y
GrBit Table:
.byte %00000001,%00000010,%00000100,%00001000
50
CONriDENTIAL
DivideBySeven
.byte %00010000,%00100000,%01000000,%10000000
See also: GetScanLine, NormalizeX, DdiV.
51
DMult (Apple, C64, C128)
math
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
SeeAlso:
Unsigned word-by-word (double-precision) multiply: multiplies two unsigned
words to produce an unsigned word result
X OPERANDI — zero-page address of word multiplicand (byte pointer to a
word variable).
y 0PERAND2 — zero-page address of word multiplier (byte pointer to a
word variable).
Note: result^ OPERANDI (word) * OPERAND2(word).
X, y, word pointed to by OPERANDI unchanged,
word pointed to by OPERANDI contains the word result.
a, r6-r8.
DMult is an unsigned word-by-word multiplication routine that multiplies the
word at one zero-page address by the word at another to produce a 16-bit word
result (all stored in low/high order). The word in OPERANDI is multipliod by the
word in OPERANDI and die result is stored as a word back in OPERANDI.
Because r6, r7 and r8 are destroyed in the multiplication process, they cannot be
used to hold the operands.
Overflow in the result (beyond 16-bits) is ignored.
BMult, BBMult, Ddiv, DSdiv.
This page Intentionally left blank to maintain right /left (verso/recto)
page ordering. Final version will correct this.
□negate
Dnegate (Apple, C64, C128) math
Function: Negate a signed word (two's complement sign-switch).
Parameters: x OPERAND — zero-page address of word to operate on (byte pointer to a
word variable).
Returns: x,y unchanged
word pointed to by OPERAND contains the negated word.
Destroys: a
Description: DNegate negates a zero-page word. The absolute address of the word
(OPERAND) is passed in x. The absolute value of OPERAND is returned in
OPERAND.
The operation of this routine is: value = (value ^ $ffff) + 1.
Example:
SeeAlso: Dabs.
52
DoBOp
DoBOp (C128)
memory!
Function : Back-RAM memory move/swap/verify primitive.
Parameters: rO ADDRl — address of first block in application memory (word).
r 1 ADDR2 — address of second block in application memory (word),
r 2 COUNT — number of bytes to operate on (word).
r3L AlBANK— ADDRl bank: = front RAM; 1 = back RAM (byte).
r3H A2B ANK — ADDR2 bank: = front RAM; 1 = back RAM (byte),
y MODE — operation mode:
move from memory at ADDRl to memory at ADDR2.
1
move from memory axADDRl to memory n ADDRl.
1
swap memory at ADDRl with memory at ADDRl.
1
1
verify (compare) memory at ADDRl against memory at ADDR2.
Note: the DoBOp MODE parameter closely matches the low nyblle of the DoRAMOp
CMD parameter.
Returns: r0-r3 unchanged.
When verifying:
X $00 if data matches; $ff if mismatch.
Destroys: a, x, y
Description: DoBOp is a generalized memory primitive for dealing with both memory banks
on the Commodore 128. It is used by MoveBData, SwapBData, and
VerifyBData.
Note: DoBOp should only be used on designated application areas of memory. When
moving memory within the same bank, the destination address must be less than
source address. When swapping memory within the same bank. ADDRl must be
less than i4/?D/?2.
Example:
See also:
MoveBData, SwapBData, VerifyBData, DoRAMOp.
53
DoDlgBox
DoDlgBoX (Apple, C64, C128) dialog box|
Initializes, displays, and begins interaction with a dialog box.
rO DIALOG — pointer to dialog box definition (word).
rS-rlO can be used to send parameters to a dialog box.
rOL return code: typically the number of the system icon clicked on to exit
Note: returns when dialog box exits through RstrFrmDialog.
Destroys: n/a
Description: DoDlgBox saves off the current state of the system, places GEOS in a near-
warmstart state, displays the dialog box according to the definition table (whose
address is passed in rO), and begins tracking the user's interaction with the dialog
box. When the dialog box finishes, the original system state is restored, and
control is returned to the application.
Simple dialog boxes will typically contain a few lines of text and one or two
system icons (such as OK and CANCEL). When the user clicks on one of these
icons, the GEOS system icon routine exits the dialog box with an internal call to
RstrFrmDialog, passing the number of the system icon selected in
sysDBData. RstrFrmDialog restores the system state and copies
sysDBData to rOL.
Function:
Parameters:
Returns:
More complex dialog boxes will have application-defined icons and routines that
get called. These routines, themselves, can choose to load a value into
sysDBData and call RstrFrmDialog.
«
Dialog boxes cannot be nested. That is, a dialog box should never call
DoDlgBox.
Apple: DoDlgBox automatically calls InitForDialog as part of its initialization
sequence.
Note: Part of the system context save within DoDlgBox saves the current stack
pointer. Dialog boxes cannot be nested. DoDlgBox is not reentrant. That is, a
dialog box should never call DoDlgBox.
Example:
See also: RstrFrmDlg, InitForDialog, RestoreSysRam, SaveFG.
54
Dolcons
DoICOnS (Apple, C64, C128)
icon/men
Function: Display and activate an icon table.
Parameters: rO ICONTABLE — pointer to the icon table to use.
Uses: dispBufferOn:
bit 7 — draw icons to foreground screen if set.
bit 6 — draw icons to background screen if set.
Destroys: r0-rl5, a, x, y
Description:
Dolcons takes an icon, draws the enabled icons (those whose
OFF_PIC_ICON word is non-zero) and instructs MainLoop to begin tracking
the user's interaction with the icons. This routine is the only way to install icons.
Every application should install at least one icon, even if only a dummy icon.
If Dolcons is called while another icon table is active, the new icons will take
precedence. The old icons are not erased from the screen before the new ones are
displayed.
Dolcons is a complex routine which affects a lot of system variables and tables.
The following is an outline of its major actions:
1: All enabled icons in the table are drawn to the foreground screen and/or the
background buffer based on the value in dispBufferOn.
2: StartMouseMode is called. If the OFF JC XMOUSE word of the icon
table header is non-zero, then StartMouseMode loads mouseXPosition
and mouse Yposition with the values in the OFF IC XMOUSE and the
OFF IC^^YMOUSE parameters of the icon "table header (see
StartMouseMode for more information).
4: faultData is cleared to $00, indicating no faults.
5: If the MOUSEON^BIT of mouseOn is clear, then die MENUON BIT
is forced to one. Thii is because GEOS assumes that it is in a power-up"state
and that nniouse tracking should be fully enabled. If the MOUSEON BIT bit
is set, GEOS leaves the menu-scan alone, assuming that the currenFstate of
the MENUON^BIT is valid
6: The ICONSON^BIT and MOUSEON BIT bits of mouseOn are set,
thereby enabling icon-scanning. "
When an icon event handler is given control, rOL contains the number of the icon
clicked on (beginning with zero) and rOH contains TRUE if the event is a
double-click or FALSE if the event is a single click.
Example:
See Also: DoMenu.
55
DoinlineReturn
DoInlineReturn (Apple, C64, cus)
utility
Function:
Parameters:
Returns:
Uses:
Destroys:
Description:
Note:
Return from an inline subroutine.
a
DATABYTES — number of inline data bytes following the jsr plus
one(byte).
staj:k top byte on stack is the status register to return (execute a php just before
calling).
(to the inline jsr) x, y unchanged from the jmp DoInlineReturn. st register is
pulled from top of stack with a pip.
returnAddress return address as popped off of stack.
a
DoInlineReturn simulates an rts from an inline subroutine call, properly
skipping over the inline data. Inline subroutines (such as the GEOS routines
which begin with i ) expect parameter data to follow the subroutine call in
memory. For example, the GEOS routine i_Rectangle is called in the following
fashion:
Jsr
.byte
.word
Jsr
XI, X2
i_Rect angle
; subroutine call
/Inline data
FrameRectangle
; returns to here
Now if i_Rectangle were to execute a normal rts, the program counter would
be loaded with the address of the inline data following the subroutine call.
Obviously, inline subroutines need some means to resume processing at the
address following the data. DoInlineReturn Provides this facility. The normal
return address is placed in the global variable returnAddress. This is the return
address as it is popped off the stack, which means it points to the third byte of the
inline jsr (an rts increments the address before resuming control). TTie status
registers is pushed onto the stack with a php, DoInlineReturn is called with
the number of inline data bytes plus one in the accumulator, and control is
returned at the instruction following the inline data.
Inline subroutines operate in a consistent fashion. The first thing one does is pop
the return address off of the stack and store it in returnAddress. It can then
index off of returnAddress as in Ida (return Address),y to access the inline
parameters, where the y-register contains $01 to access the first parameter byte,
$02 to access die second, and so on (not $00, $01, $02, as might be expected
because the address actually points to the third byte of the inline jsr). When
finished, the inline subroutine loads the accumulator with the number of inline
data bytes and executes a jmp DoInlineReturn.
DoInlineReturn must be called with a jmp (not a jsr) or an unwanted return
address will remain on die stack. The x and y registers are not modificnd by
DoInlineReturn and can be used to pass parameters back to the caller. Inline
calls cannot be nested widiout saving the contents cf returnAddress. An inline
routine will not work correctly if not called directly through a jsr (e.g.,
CallRoutine cannot be used to call an inline subroutine).
56
DolnlineReturn
Example:
; Invert icalLine
; Inline version of VertlcalLlne.
;Pass :
; .word xl
; . word x2
; .byte yl
l^VertlcalLine:
V_BYTES - 5 /number of Inline bytes In call
;Save away the inline return address
PopW returnAddress
;Load up VertlcalLlne * s parameters
Idy
Ida
sta
#V_BYTES
(returnAddress) ,y
rllL
;get yl parameter first
10$:
dey
Ida
sta
cpy
bne
(returnAddress) , y
r3L-l,y
#1
10$
/load other params in a loop
/They occupy consecutive GEOS
/pseudoregisters, so this will.
/wor)c correctly
/Now
call VertlcalLlne with registers loaded
jsr VertlcalLlne
/and
do an inline return when we come back
php
Ida #V_BYTES+1
jmp DolnlineReturn /
•save St reg to return
/# of bytes i
/jump to inline return. Do not jsr!
57
DoMenu
DoMenu (Apple, C64, cm)
icon/menu
Function:
Parameters:
Destroys:
Description:
Displays and activates a menu structure.
rO MENU — pointer to the menu structure to display,
a POINTER_OVER — which menu item (numbered starting with zero) to
center the pointer over.
r0-rl3, a, x, y
DoMenu draws the main menu (the first menu in the menu structure) and
instructs MainLoop to begin tracking the user's interaction with the menu. This
routine is the only way to install a menu.
If DoMenu is called while another menu structure is active, the new menu will
take precedence. The old menu is not erased from the screen before the new menu
is displayed. If the new menu is smaller (or at a different position) than the old
menu, parts of the old menu may be left on the screen. A typical way to avoid this
is to erase the old menu with a call to Rectangle, passing the positions of the
main menu rectangle and drawing in a white pattern. However, a more elegant
solution involves calling Recover AlIMenus, which will erase any extant menus
by recovering from the background buffer.
DoMenu is a complex routine which affects a lot of system variables and tables.
The following is an outline of its major actions:
1: Menu level (main menu) is drawn to the foreground screen.
2: StartMouseMode is called. mouseXPosition and mouseYpositlon are
set so that the pointer is centered over the selection number passed in a.
Under Apple GEOS, if the the POINTER.OVER number in tiie accumulator
has its high-bit set, then the mouse will not be repositioned Under GEOS 64
and GEOS 128, DoMenu always forces the mouse to a new position. If you
do not want the mouse moved, surround the call to DoMenu with code to
save and restore the mouse positions. The following code fragment will install
n>enus widiout moving the mouse.
DoMenu2 :
.if (APPLE)
Ida 4$80
jsr DoMenu
.else ; (C64 i I C128)
php
sei
PushH mouseXPos
PushB mouseYPos
Ida «0
jsr DoMenu
PopB mouseYPos
PopW mouseXPos
pip
.endif
rts
;set high-bit so mouse is not repositioned
;put up the menu
; disable interrupts around call
;save mouse x
;save mouse y
; dummy menu value
/install menus (mouse will move)
/restore original mouse y
/restore original mouse x
/restore interrupts
58
DoMenu
3: SIowMouse is called. With a joystick this will kill all accumulated speed in
the pointer, requiring the user to reacceleratc. With a proportional mouse, this
will have no effect
4: fauItData is cleared to $00, indicating no faults.
5: If the MOUSEON^BIT of mouseOn is clear, then the ICONSON^BIT
is forced to one. Thii is because GEOS assumes that it is in a power-upTstate
and that mouse tracking should be fully enabled. If the MOUSEON BIT bit
is set, GEOS leaves the icon-scan alone, assuming that the ICONSON_BIT
is valid.
6: The MENUON_,BIT and MOUSEON^BIT bits of mouseOn are set,
thereby enabling menu-scanning.
7: The mouse fault variables (mouseTop, mouseBottom, mouseLeft, and
mouseRight) are set to the full screen dimensions.
Example:
See Also: Dolcons, GotoFirstMenu, DoPreviousMenu, ReDoMenu.
59
DoneWithIO
DoneWithIO (C64, ci28)
very low-level disk|
Function: Restore system after I/O across the serial bus.
Parameters: none.
Returns: nothing.
Destroys: a, y.
Description: DoneWithIO restores the state of the system after a call to InitForlO. It
restores the interrupt status, turns sprite DMA back on, returns the 128 to its
original clock speed, and switches out the ROM and I/O banks if appropriate
(only on C64).
Disk and printer routines access the serial bus between calls to InitForlO and
DoneWithIO.
Apple: Apple GEOS has no DoneWithIO equivalent
Example: See WriteBIock.
See also: InitForlO.
60
DoPreviousMenu
DoPreviousMenu (Apple, C64, cns)
icon/menu
Function: Retracts the current sub-menu and reactivates menus at the previous level.
Parameters: none.
Destroys: assume rO-rlS, a, x, y
Description:
Note:
Example:
See Also:
DoPreviousMenu is used by a menu event handler to instruct GEOS to back up
one level of menus, erasing the current menu from the foreground screen and
making the parent menu active when control is returned to MainLoop.
menuNumber is decremented.
When using DoPreviousMenu, if the parent menu (the one which will be given
control) is of type UN_CONSTRAINED, then the mouse must be manually
repositioned over the parent menu. This can be done by loading
mouseXPosition and mouseYPosition with values calculated from the menu
structure. If the parent menu is of type CONSTRAINED, then the mouse is
automatically positioned over the selection in the parent menu which led to tiie
sub-menu.
DoPreviousMenu may be called repeatedly to back up more than one level.
Do not call DoPreviousMenu when the menu is at level (menuNumber =
$00). The effects may be disasterous.
DoMenu, GotoFirstMenu, ReDoMenu, RecoverMenu.
61
DoRAMOp
DoRAMOp (C64 vL3 & C128)
memory I
Function:
Parameters:
Returns:
Destroys:
Primitive for communicating with REU (RAM-Expansion Unit) devices.
rO ADDRl — address in Commodore to start (word).
rl ADDR2 — address in REU bank to start (word).
r2 COUNT — number of bytes to operate with (transfer length) (word).
r3L REUB ANK — REU bank number to use (byte).
y CMD — command to send to REU (byte).
r0-r3 unchanged.
X error code:
$00 (no error) or DEV^NOT^FOUND if bank or REU
not available.
REU status byte and'ed with $60
Description: DoRAMOp is a very low-level routine for communicating with a RAM-
expansion unit on a C64 or C128. This routine is a "use at your own risk" GEOS
primitive
DoRAMOp operates with the with the RAM-expansion unit direcdy and handles
all the necessary.communication protocols and clock-speed save/restore (if
necessary).
The CMD parameter is stuffed into the REC Command Register
(EXP_BASE+$01). Although DoRAMOp does no error checking on this
parameter, it expects the high-nybble to be %1001 (transfer with current
configuration and disable FFOO decoding). The lower nybble can be one of the
following:
%00 Transfer from Commodore to REU.
%01 Transfer from REU to Commodore.
%10 Swap.
%11 Verify.
Note: the low nybble of the DoRAMOp CMD parameter closely matches the DoBOp
MODE parameter.
Note: On a Commodore 128, if the VIC chip is mapped to front RAM (with the MMU
VIC bank pointer), the REU will read/write using front RAM. Similarly, if the
VIC chip is mapped to back RAM, the REU will read/write using back RAM. The
REU ignores the stadard bank selection controls on die 8510. GEOS 128 defaults
with die VIC mapped to front RAM.
For more information on the Commodore REU devices, refer to the Commodore
1764 RAM Expansion Module User's Guide or die 170011750 RAM Expansion
Module User's Guide.
Example:
See also: StashRAM, FetchRAM, SwapRAM, DoBOp.
62
DownDlrectory
DownPirectory (Apple)
mid-level disk
Function:
Parameters: r9
Uses:
Returns:
Makes a subdirectory (child directory) in the current directory the new current
directory.
DIRENTRY — pointer to directory entry of subdirectory, usually points
to dirEntryBuf (must be in main memory) (word).
curDrive
curKBlkno
current directory.
X error ($00 = no error),
y pathname status ($00 = OK; BFR^OVERFLOW = pathname longer
than pathnameBuO-
Alters: curKBlkno new current directory.
curDirHead header of new directory.
pathnameBuf^ system pathname buffer updated to reflect new path.
curDirTabLot
curDirTabHit
^used internally by GEOS disk routines; applications generally don't use.
Destroys: a, rl, r4.
Description: DownDirectory moves down one level in the hierarchical file system, making a
specific child directory the current working directOTy.
The directory entry of the subdirectory is a standard data structure returned by
routines such as FindFlle, GetlstDirEntVy and GetNextDirEntry. A
subdirectory has a PRO^DIR (ProDOS directory) GEOS file type.
€64 & C128: Comnxxlore GEOS does not support a hierarchical file system.
Example:
See also: UpDirectory, GoDirectory.
63
PownPirootOFy
IDrawLine (Apple, C64, ci28) graphksl
Function: Draw, clear, or recover a line defined by two arbitrary endpoints.
Parameters: r3 XI — x-coordinate of first endpoint (word).
rllL Yl — y-coordinate of first endpoint (byte).
r4 X2 — x-coordinate of second endpoint (word),
r 1 IH Y2 — y-coordinate of second endpoint (byte).
St MODE:
n c Description
1
X
recover pixel from backKfound screen to forejoound.
1
set Dixel usine dispBufferOn.
clear pixel usine dispBufferOn.
where (XI, Yl) and (X2J2) are the two endpoints of the line.
Uses: if n is set (drawing, not recovering):
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
Returns: status register (S) unchanged
Destroys: Commodore
a, x, y, r3-rl3
Apple
a, X, y, r3, r4, rll
Description: DrawLine will set, clear, or recover the pixels which comprise the line between
two arbitrary endpoints. Setting a pixel sets its bit value to one, clearing a pixel
sets its bit value to zero, and recovering a pixel copies the bit value from the
background buffer to foreground screen.
DrawLine uses the Bresenham DDA (Digital Differential Analyzer) algorithm to
determine the proper points to draw. The line will be drawn correctiy regardless
of which endpoint is used for (Xljl) and which is used for {X2J2). In fact,
the line is reversible: the same line will be drawn even if the endpoints are
swapped.
The carry (c) flag and sign (n) flag in the processor status register (s) are used to
pass information to DrawLine. The following tricks can be used to set or clear
these flags appropriately:
♦ Use sec and cic to set or clear the carry (c) flag.
♦ Use Ida to set the sign (n) flag.
♦ Use Ida #0 to clear the sign (n) flag.
Note:
Calculates each pixel position on the line and calls DrawPoint repeatedly.
■ P uw nDlrcet e Fy
128: Under GEOS 128, or*ing DOUBLE W into theX/ andX2 parameters will
automatically double the x-position in 8D-column mode. Or'ing in ADDl^W will
automatically add 1 to a doubled x-position, (Refer to "GEOS 128 X-posiuon and
Bitmap Doubling" in Chapten@gr@ for more information,)
Example:
See also: HorizontaILIne,VerticaILine, InvertLine, ImprintLine, RecoverLine.
fl ra w Line
DrawPoint (Apple, C64, cm)
graphics
Function:
Parameters:
Set, clear, or recover a single screen point (pixel).
r3 XI — x-coordinate of pixel (word),
r 1 1 L Y 1 — y-coordinate of pixel (byte).
St MODE:
n
c
Description
1
X
recover pixel from backjo-ound screen to foreground.
1
set pixel using dispBufferOn.
clear pixel using dispBufferOn.
Uses:
Returns:
Destroys:
Description:
128:
Example:
See also:
where (XI, Yl) is the coordinate of the point.
when setting or clearing pixels:
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
r3, rllL unchanged.
Commodore
a, X, y, r5-r6
Applg
a, X, y
DrawPoint will set, clear, or recover a single pixel. Setting a pixel sets its bit
value to one, clearing a pixel sets its bit value to zero, and recovering a pixel
copies the bit value from die background buffer to foreground screen.
The carry (c) flag and sign (n) flag in the processor status register (s) are used to
pass information to DrawPoint. The following tricks can be used to set or clear
these flags appropriately:
• Use sec and cic to set or clear the carry (c) flag.
Use Ida #[*! to set the sign (n) flag.
Use Ida #0 to clear the sign (n) flag:
Under CEOS 128, orlng DOUBLE^W into the XI will automatically double
the x-position in 80-colunm mode. OFing in ADD1_W will automatically add 1
to a doubled x-position. (Refer to "CEOS 128 X-po?ition and Bitmap Doubling"
in Chapter.@grtg) for more information.)
TestPoint, DrawLine.
& f awP e i rrt
DrawSprite (Apple, C64, ci28)
sprite
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
C64:
C128:
Apple:
Example:
See also:
Copy a 64-byte sprite image to the internal data buffer that is used for drawing the
sprites.
r3L SPRITE — sprite number (byte).
r4 DATAPTR — pointer to 64-bytes of sprite image data (word),
nothing.
internal sprite image.
Commodore
a, y, r5
Applg
a, y
DrawSprite copies 64-bytes of sprite image data to the internal buffer that is
used for drawing the sprites. DrawSprite does not affect the enabled/disabled
status of a sprite, it only changes the image definition.
Although there are eight sprites available, an application should limit itself to
sprites #2 through #7 because GEOS reserves sprite #0 for the mouse cursor and
sprite #1 for the text prompt.
The 64 bytes are copied to the VIC sprite data area, which is located in memory
immediately after the color matrix. The size information byte (byte 64) is unused
by GEOS 64 but is copied to the data area, nonetheless. A SPRITE value of $00
can be used to change the shape of the mouse cursor.
The data is transferred to the VIC sprite area (regardless of the current graphics
mode). This data is used by the VIC chip in 40-column mode and by the soft-
sprite handler in 80-column mode. The last byte (byte 64) of the sprite definition
is used as the size information byte by the soft-sprite handler. In 80-column
mode, the sprite is not visually updated until the next time the soft-sprite handler
gets control. To change the mouse cursor, the application can use a SPRITE value
of $00 in 40-column mode or call SetMsePic in 80-column mode (doing both is
a simple solution: it will do no harm regardless of the graphics mode).
The data is transferred to an internal sprite area. The last byte (byte 64) of the
sprite definition is used as the size information byte. The sprite is not visually
updated until the next time the soft-sprite handler gets control. The soft-sprite
handler will draw sprite #1 through sprite #7. In no case should the SPRITE
parameter be $00; a value of $00 wUl most likely trample GEOS.
The INAUX_B constant may be or'ed into the SPRITE parameter to indicate
that the DATAPTR parameter is an address in auxiliary memory.
GetSpriteData, PosSprite, EnablSprite, DisablSprite, InitSprite.
DSdiv
DSdiv (Apple, C64, C128)
math I
Function: Signed word-by-word (double-precision) division: divides one two's complement
word by another to produce a signed word result.
Parameters: x OPERANDI — zero-page address of signed word dividend (byte pointer
to a word variable).
y 0PERAND2 — zero-page address of signed word divisor (byte pointer to
a word variable).
Note: result = OPERANDI (word) I OPERAND2(word).
Returns: y unchanged.
r8 the fractional remainder (word).
word pointed to by OPERANDI equals its absolute value.
word pointed to by OPERANDI contains the word result.
Commodore:
X unchanged
Destroys: a, r9
A pple:
X
Description: DSdiv is a signed, two's complement word-by-word division routine that
divides the word in one zero-page pseudoregister (the dividend) by the word in
another (the divisor) to produce a 16-bit word signed result and a 16-bit word
fractional remainder The word in OPERANDI is divided by the word in
OPERANDI and the result is stored as a word back in OPERANDI with the
remainder in r8.
C64 & C128: The remainder is always positive regardless of the sign of the dividend. This will
cause problems with some mathematical operations that expect a signed
remainder. The following code fragment will fixe this problem:
;NewDSdiv:
call as you would
call DSdiv. Returns a
signed remainder.
Destroys x!
sign (remainder) -
sign (dividend)
NewDSdiv :
Ida
zpage,x
;save sign of dividend
php
Jsr
DSdiv
; divide as normal
pip
;then get back sign of dividend back
bpl
20$
/ignore if positive
Idx
«r8
;else, negate remainder
jsr
Dnegate
/(e.g., -10/9 - -1 rem -1)
20$:
rts
The sign of the remainder is the same as the sign of the dividend.
Because r8 and r9 are used in the division process, they cannot be used to hold
the operands.
Apple:
Note:
68
DSdiv
Although dividing by zero is an undefined mathematical operation, DSdiv makes
no attempt to flag this as an error condition and simply returns incorrect results. If
the divisor might be zero, the application should check for this situation before
dividing:
Example:
SeeAlso:
10$:
Ida zpage,y ;get low byte of divisor
ora zpage+l,y ;get high byte of divisor
bne 10$ ;if either non-zero, go divide
jmp DivideByZero ;else, flag error
jmp DSdiv ; divide (DSdiv will rts)
Ddiv, DMult, BMult, BBMuIt, DivideBySeven.
69
I
DShiftLeft
DShiftLeft (Apple, C64, C128)
math
Function:
Parameters:
Returns:
Arithmetically left-shift a zero-page word
X
y
OPERAND — address of the zero-page word to shift (byte pointer to a
word variable).
COUNT — number of times to shift the word left (byte).
a, X unchanged
y #$ff
St c (carry flag) is set with last bit shifted out of word.
zero page address pointed to hy OPERAND contains the shifted word.
Destroys: nothing
Description:
Note:
Example:
SeeAlso:
DShiftLeft is a double-precision math routine that arithmetically left-shifts a 16-
bit zero-page word (low/high order). The absolute address of the word is passed
in X and the number of times to shift the word is passed in y. Zeros are shifted
into the low-order bit
An arithmetic left-shift is useful for quickly multiplying a value by a power of
two. One left-shift will multiply by two, two left-shifts will multiply by four,
three left-shifts will multiply by eight, and so on: value = value ♦ l^ount^
If a COUNT of $00 is specified, the the word will not be shifted.
DSh:ftRight.
70
DShiftRight
DShiftRight (Apple, C64, C128)
math
Function:
Parameters:
Returns:
Arithmetically right-shift a zero-page word.
X
y
OPERAND — zero-page address of word to shift (byte pointer to a word
variable).
COUNT — number of times to shift the word right (byte).
a, X unchanged
y #$ff
St c (carry flag) is set with last bit shifted out of word,
register pointed to by OPERAND contains the shifted word
Destroys: nothing
Description:
Example:
SeeAlso:
DShiftRight is a double-precision routine that arithn^tically right-shifts a 16-bit
zero-page word (low/high order). The address of the word is passed in x and the
number of times to shift the word is passed in y. Zeros are shifted into the high-
order bit.
An arithmetic right-shift is useful for quickly dividing a value by a power of two.
One left-shift will divide by two, two left-shifts will divide by four, three left-
shifts will divide by eight, and so on: value = value / 2^^"^^
DShiftLeft.
71
EnableProcess
EnableProcess (Apple, C64, ci28)
process!
Function:
Parameters:
Returns:
Description:
Example:
Makes a process tunable immediately.
X PROCESS — number of process (0 - n-l, where n is the number of
processes in the table) (byte).
unchanged.
Destroys: a
EnableProcess forces a process to become runable on the next pass through
MainLoop, independent of its timer value.
EnableProcess merely sets the runable flag in the hidden process table. When
MainLoop encounters an unblocked process with this flag set, it will attempt to
generate an event just as if the timer had decremented to zero.
EnableProcess has no priveleged status and cannot override a blocked process.*
However, because it doesn't depend on or affect the current timer value, the
process can become runable even with a frozen timer.
EnableProcess is useful for making sure a process runs at least once,
regardless of the initialized value of the countdown timer. It is also useful for
creatingapplication-defined events which run off of MainLoop: a special process
can be reserved in the data structure but never started with RestartProcess. Any
time the desired event-state is detected, a call to EnableProcess will generate an
event on the next pass through MainLoop. EnableProcess can be called from
Interrupt Level, which allows a condition to be detected at Interrupt Level but
processed during MainLoop.
See also: InitProcesses, RestartProcess, UnfreezeProcess, UnblockProcess.
72
EnablSprite
EnablSprite (Apple, C64, cns)
sprite
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
Example:
See also:
Enable a sprite so that it becomes visible.
r3L SPRITE — sprite number (byte).
nothing.
mobenble
a, X
EnablSprite enables a sprite so that it becomes visible. Although there are eight
sprites available, an application should only directly enable sprites #2 through #7
with EnablSprite. Sprite #0 (the mouse pointer) is enabled through MouseOn
and StartMouseMode, and sprite #1 (the text cursor) should be enabled with
PromptOn.
DisablSprite, MouseUp, PromptOn, DrawSprite, GetSpriteData,
PosSprite, InitSprite.
73
EnterDeskTop
EnterPeskTop (Apple, C64, cus)
Function: Standard application exit to GEOS dcskTop,
Parameters: none.
Returns: never retutms to application.
Description: An application calls EnterDeskTop when it wants to exit to the GEOS deskTop-
EnterDeskTop takes no parameters and looks for a copy of the file
DESK TOP on each drive. Later versions of GEOS are only compatible witii
the correspondingly later revision of the deskTop and will check the version
number in the permanent name string of the DESK TOP file to ensure that it is
in fact a newer version. If after all drives are searched no valid copy of the
deskTop is found, EnterDeskTop will prompt the user to insert a disk witii a
copy of the deskTop on it.
C64 & C128: EnterDeskTop will first search a RAMdisk for a copy of the deskTop to ensure
the fastest loading tin^e.
Apple: EnterDeskTop will first search all non-removable media devices (RAMdisk,
hard disk, etc.) for a copy of the deskTop, then other devices (floppy disk
devices). These devices are searched in the order that they appear on the deskTop,
which corresponds to their order in the expansion slots: a device in slot seven will
be searched before a device in slot six.
Example:
See also: RstrAppl, GetFile.
high-level disk
74
EnterTurbo
EnterTurbo (C64, ci28)
verylow-level disk I
Function:
Parameters:
Uses:
Returns:
Destroys:
Calls:
Description:
Activate disk drive turbo mode,
none.
Apple:
Example:
See also:
curDrive
curType
currently active disk drive.
vl.3+: checks disk type because not all use turbo software.
X
a, y.
error ($00 = no error).
EnterTurbo activates the turbo software in the current drive. If the turbo
software has not yet been downloaded to the drive, EnterTurbo will download
it. The turbo software allows GEOS to perform high-speed serial disk access.
EnterTurbo treats diflferent drive types appropriately. A RAMdisk, for example,
does not use turbo code so EnterTurbo will not attempt to download the turbo
software.
The very-low level Commodore GEOS read/write routines, such as ReadBlock,
WriteBlock, VerWriteBIock, and ReadLink, expect the turbo software to
be active. Call EnterTurbo before calling one of these routines.
Apple GEOS has no EnterTurbo equivalent
See WriteBlock.
ExitTurbo, PurgeTurbo.
75
-&ftt6 rTurbo
EraseCharacter (Apple)
text
Function: Erase a character from the screen, accounting for the current font and style
attributes.
Parameters: a CHAR — character code of character to erase (byte).
r 1 1 XPOS — x-coordinate of left of character (word),
r 1 H YPOS — y-coordinate of character baseline (word).
Uses: same as PutChar.
Returns: rll, rlH unchanged.
Alters: lastWidth width of character just erased
Destroys: Commodore
rlL, r2-rl0, rl2, rl3, a, x, y.
Apple
rlL, r2, a, x, y.
Description: EraseCharacter calculates the widdi of the character and erases it from the
screen using the USELAST character and SmallPutChar.
Note: Uses currentMode to calculate the character width. When deleting multiple
characters, the application will need to take this into account when backspacing
from one style to another. Also, does not always work with characters that are
both bolded and outlined because not all fonts have a wide enough USELAST
character.
See also:
Example:
SmallPutChar, PutChar, PutString.
ExitTurbo
ExitTurbO (C64, cm) very Iow>level disk]
Function: Deactivate disk drive turbo mode.
Parameters: none.
Uses : cur Drive currently active disk drive.
Returns: x error ($00 = no error).
Destroys: a, y.
Description: ExitTurbo deactivates the turbo software in the current drive so that the serial
bus may access another device. SetDevice automatically calls this before
changing devices.
Note: If the turbo software has not been downloaded or is already inactive, ExitTurbo
will do nothing.
Apple: Apple GEOS has no ExitTurbo equivalent.
Example: See WriteBIock.
See also: EnterTurbo, PurgeTurbo.
77
FastDelFile
FastPelFile (C64, cm)
mid-level disk
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
Special Commodore version of DeleteFile that quickly deletes a sequential file
when the track/sector table is available.
r FILENAME — pointer to null-terminated file name (word),
r3 TSTABLE — pointer to track and sector table of file, usually points to
fileTrScTab (word).
curDrive.
curType
curDirHead
dir2Headt
dir3Headt
GEOS 64 vl.3 and later: for detecting REU shadowing,
BAM updated to reflect newly freed blocks.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
X error ($00 = no error),
a, y, rO, r9.
FastDelFile quickly deletes a sequential file by taking advantange of an already
existing tracl^sector table. It first removes the directory entry determined by
FILENAME and calls FreeBIock for each block in a track/sector table at
TSTABLE. The track/sector table is in the standard format, such as that returned
from ReadFile, where every two-byte entry constitutes a track and sector. A
track number of $00 terminates the table.
FastDelFile is fast because it does not need to follow the chain of sectors to
delete the individual blocks. It can do most of the deletion by manipulating the
BAM in memory then writing it out with a call to PutDirHead when done.
FastDelFile will not properly delete VLIR files without considerable work on
the application's part. Because there is no easy way to build a track/sector table
that contains all the blocks in all the records of a VLIR file, it is best to use
DeleteFile or FreeFile for deleting VLIR files or DeleteRecord for deleting a
single record.
FastDelFile calls GetDirHead before freeing any blocks. This will overwrite
any BAM and directory header in memory.
FastDelFile can be used to remove a directory entry without actually freeing any
blocks in the file by passing a dummy track/sector table, where the first byte
(track number) is $00 signifying the end of the table:
;Pass: rJD pointer to filename
E>eleteDirEntry :
LoadW r3,#NullTrScTable ;pass dummy table
jmp FastDelFile ; delete dir entry
; never get here — FastDel returns to caller
This will also work correctly with a VLIR file.
For freeing (deleting) all the blocks in a file widiout removing the directory entry,
refer to FreeFile.
78
Apple: Apple GEOS has no FastDelFile equivalent because the ProDOS blocks are not
linked with internal forward pointers. Use DeleteFile.
Example:
Read sequential file into memory and then delete it
from disk
;Pass: r6 pointer to filename
r7 where to put data
r2 size of buffer (max size of file)
; Returns:
X error code
Destroys:
a, y, r0-r9
Implementation :
Call Findfile to get the directory entry of the
file to load/delete. We pass the directory entry
to GetFHdrlnfo to get the GEOS header block. We
check the header to ensure we* re not trying to
read in a VLIR file. After GetFHdrlnfo, the
parameters are already set up correctly to call
ReadFile (f ileTrScTab+0, f ileTrScTab+1 contains
header block and rl contains first data block) .
Readfile reads in the file's blocks, building out
the remainder of the fileTrScTab, which we pass
to FastDelFile to free all blocks in the file
(including the file header block, which is the
first
entry in the table) .
ReadAndDelete:
MoveW
r6,r0
;save pointer for FastDel
Jsr
FindFile
;find file on disk
txa
;set status flags
bne
96$
; branch on error
LoadW
r9,dirEntryBuf
;get directory entry
jsr
GetFHdrlnfo
;get GEOS file header
txa
;set status flags
bne
96$
/branch on error
Ida
fileHeader+OFF GSTRUCT TYPE
cmp
#VLIR
; check filet ype
bne
10$
; branch if not VLIR
Idx
#STRUCT_MISMAT
; can't load VLIR
bne
96$
/branch always for error
10$:
jsr
ReadFile
;read in file
txa
/else set status flags
bne
96$
/branch on other error
20$:
LoadW
r3,#fileTrScTab
/track/sector tbl
jsr
FastDelFile
/file read OK, delete it!
d6$
rts
/error in x
See also: FreeFile, DeleteFile.
79
FdFTypesInPir (Apple)
high-level disk
Function: Special Apple GEOS version of FindFTypes that will build the filename list
using a directory other than the current directory.
Parameters: r6 BUFFER — pointer to buffer for building-out file list; allow 16 bytes
for each entry in the list (word),
r 1 PERMN AME — pointer to permanent name string to match or $0000 to
ignore permanent name string (word).
r7H MAXETLES — maximum number of filenames to retum, usually used
to prevent overwriting end of BUFFER (must be less than 127). If
INAUX^B is bitwise-or'ed into this parameter, BUFFER will be
treated as'an address in auxiliary memory.
r7L FILETYPE — GEOS file type to search for or WILDCARD, which
will match all types except subdirectories (byte),
rl DIRBLKNO — block number of directory to search (word).
curDrive
X error ($00 = no error).
r7H decremented once for each file name (Apple GEOS: high-bit is always
cleared).
diskBIkBuf used as temporary buffer for directory blocks,
a, y, rO-r2L, r4-r6.
FdFTypesInDir performs the same action as FindFTypes, except that
DIRBLKNO temporarily becomes the current directory. The current directory is
restored before returning.
The data area at BUFFER, where the list is built-out, must be large enough to
accomodate MAXFILES filenames of 16 bytes each.
C64 & C128: Commodore GEOS does not support a hierarchical file system.
Example:
See also: FindFTypes, FndFillnDir.
Uses:
Returns:
Alters:
Destroys:
Description:
CONAkoklisi SAL
FetchRAM
FetchRAM (C64 vi.3 & ci28)
memoryl
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Primitive for transferring data from an REU.
rO CBMDST — address in Commodore to put data (word),
r 1 REUSRC — address in REU bank to start reading (word).
r2 COUNT — number of bytes to fetch (word).
r3L REUS ANK — REU bank number to fetch from (byte).
r0-r3 unchanged.
X error code:
a
y
$00 (no error) or DEV_NOT_FOUND if REUBANK
or REU not available. ~
REU status byte and'ed with $60 ($40 = successful fetch).
FetchRAM moves a block of data from an REU bank into Commodore
memory. This routine is a "use at your own risk" low-level GEOS primitive
FetchRAM uses the DoRAMOp primitive by calling it with a CMD parameter
of %10010001.
Refer to DoRAMOp for notes and warnings.
StashRAM, SwapRAM, VerifyRAM, DoRAMOp, MoveBData.
81
FillRam
FillRam, i FillRam (Apple, C64, ci28)
memory]
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
pais a region of memory with a repeating byte value.
Nomial:
rO COUNT — number of bytes to clear (0 - 64K) (word),
r 1 ADDR — ^address of area to clear (word).
r2L PILL — byte value to fill with (byte).
Inline:
.word CXDUNT — number of bytes to clear (0 - 64K) (word),
.word ADDR — address of area to clear (word),
.byte PELL — byte value to fill with (byte).
r2L unchanged.
a, y, rO, rl
FillRam fills COUNT bytes starting at ADDR with the PILL byte. This routine
is useful for initializing a block of memory to some non-zero or variable value
(for filling a region with $00, use ClearRam).
Do not use FillRam to initialize rO-r2L.
ClearRam, InitRam.
82
FindBAMBit
FindBAMBit (C64, ci28)
m id.level disk
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Get disk block allocation status.
r6L TRACK —track number of block (byte).
r6H SECTOR — sector number of block (byte).
curDrive
curDirHead
dir2Headt
dirSHeadt
this buffer must contain the cunent directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
^used internally by GEOS disk routines; applications generally don't use,
St z flag reflects allocation status (1 = free ; = allocated).
r6 unchanged
1541 drives onlv:
X offset from curDirHead for BAM byte.
r8H mask for isolating BAM bit.
a BAM byte masked with r8H.
r7H offset from curDirHead of byte that holds free blocks on track total.
non-1541 drives:
a, y, r7H. r8H.
1541 drives:
y (a, r7H, and rSH all contain useful values).
FindBAMBit accesses the BAM of the current disk 'in curDirHead) and
returns the allocation status of a particular block. If the BAM bit is zero, then the
block is in-use; if the BAM bit is one, then the block is free. FindBAMBit
returns with the z flag set to reflect the status of the BAM so that a subsequent
bne or beq branch instructions can test the status of a block after calling
FindBAMBit:
Note:
Apple:
Example:
bne
beq
BlocklsFree
or-
BlocklnUse
; branch if block is free
;branch if block is in-use
FindBAMBit will return the allocation status of a block on any disk device,
even those with large or multiple BAMs (such as the 1571 and 1581 disk drives).
Only the 1541 driver, however, will return useful information in a, y, r7H, and
r8H. For an example of using these extra 1541 return values, refer to
AIlocateBlock.
See FindVBMBit.
LoadB
LoadB
jsr
beq
r6L,#TRACK
r6H,#SECT0R
FindBAMBit
BlocklnUse
; get track and sector number
; get allocation status
; branch if already in use
83
FindBAMBit
See also: FindVBMBit, AIlocateBIock, FreeBIock. GetDirHead, PutDirHead.
84
FindFile
FindFilejAppie, C64, ci28)
high-level disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Search for a particular file in the current directory.
r6 FILENAME — pointer to null-terminated name of file of a maximum of
ENTRY^SIZE bytes (not counting null terminator). (Apple GEOS:
must be in main memory.) (word).
curDrive
Commp^^Qre;
curType
Applg:
curKBlkno
GEOS 64 vl.3 and later: for detecting REU shadowing.
current directory.
X error ($(X) = no error).
rl block number (Commodore track/sector) of directory block containing
entry,
r5 pointer into diskBIRBuf to start of directory entry.
diskBIkBuf
dirEntryBuf
a, y, r4, r6.
contains directory block where FILENAME found,
directory entry of file if found.
Given a null-terminated filename, FindFile searches through the current
directory and returns the directory entry in dirEntryBuf. If the file specified
with FILENAME is not found, a FILE_NOT_FOUND error is returned.
C64 & C128: Since Commodore GEOS does not support a hierarchical file systeni, the "current
directory'* is actually the entire disk. The directory entry is deleted by setting its
OFF^CFILE^TYPE byte to $00.
Apple:
Example:
See also:
Only the current directory, the directory specified by curKBlkno, is searched.
To search a directory other than the current one, use FndFillnDir.
FndFillnDir, GetlstDirEntry, GetNxtDirEntry, FindFTypes.
85
FindFTypes
FindFTypes (Apple, C64, cns)
high-level dlskl
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
BuUds a list of files of a particular GEOS type from the current directory,
r6 BUFFER' — pointer to buffer for building-out file list; allow
. ENTRY_SIZE+1 bytes for each entry in the list (word),
r 1 PERMN AME — pointer to permanent name string to match or $0000 to
ignore permanent name string (word).
Commodore:
r7H MAXFILES — maximum number of filenames to return, usually used
to prevent overwriting buffer.
r7L FILETYPE — GEOS file type to search for (byte).
Applg;
r7H
r7L
MAXFILES — maximum number of filenames to return, usually used
to prevent overwriting end of BUFFER (must be less than 127). If
INAUX_B is bitwise-or'ed into this parameter, BUFFER will be
treated as"an address in auxiliary memory.
FILETYPE — GEOS file type to search for or WILDCARD, which
will match all types except subdirectories (byte).
curDrive
Commodore:
curType
Apple:
curKBIkno
GEOS 64 V 1.3 and later for detecting REU shadowing.
current directory.
X error ($00 = no error).
r7H decremented once for each file name (Apple GEOS: high-bit is always
cleared).
diskBlkBuf
used as temporary buffer for directory blocks.
CpqTmQ(jorg;
a, y, rO-r2L, r4, r6.
Apple;
a, y, rO-r2L, r4-r6.
Description: FindFTypes build a list of files that match a particular GEOS file type and,
optionally, a specific permanent name string.
The data area at BUFFER, where the list is built-out, must be large enough to
accomodate MAXFILES filenames of ENTRY_SIZE+1 bytes each.
FindFTypes first clears enough of the area at BUFFER to hold MAXFILES
filenames tiien calls GetlstDirEntry and GetNxtDirEntry to go tiirough each
directory entry in the current directory. When the GEOS file type of a directory
86
FIndFTypes
entry matches the FILETYPE parameter, FindFTypes goes on to check for a
matching permanent name string.
If the PERMNAME parameter is $0000, then this check is bypassed and the
filename is added to the list. If the PERMNAME parameter is non-zero, the null-
terminated string it points to is checked, character-by-character, against the
permanent name string in the file's header block. Although the permanent name
string in the GEOS file header is 16 characters long, the comparison only extends
to the character before the null-terminator in the string at PERMNAME.
Since permanent name strings typically end with Vxjc, where xjc is a version
number (e.g., 2.1), a shorter string can be passed so that the specific version
number is ignored For example, a program called geoQuiz version 1.3 might use
"geoQuiz V1.3" as the permanent name string it gives its data files. When
geoQuiz version 3.0 goes searching for its data files, it can pass a PERMNAME
string of "geoQuiz V" so data files for all versions of the program will be added to
the list
When a match is found, the filename is copied into the list at BUFFER. The
filenames are placed in tJie buffer as they are found (the same order they appear
on the pages of the deskTop notepad). With a small buffer, matching files on
higher-numbered pages may never get added to the list.
C64 & C128: Since Coninxxiore GEOS does not support a hierarchical file system, the "current
directory" is actually the entire disk. The filenames appear in the list null-
terminated even though they are padded with $aO in the directory.
Apple: Only the current directory specified by curKBIkno is searched. To search a
directory other than the current one, use FdFTypesInDir. The filenames in the
list are null-terminated
To search for subdirectories in the current directory, pass PRO DIR as the
FILETYPE. When searching for directories, the permanent string check is
bypassed To match all file types except subdirectories, pass WILDCARD as
the FILETYPE and $0000 for the PERMSTRING parameter.
A filename list created with FindFTypes can be sorted alphabetically with a call
to SortAIpha.
Example:
See also: FdFTypesInDir, FindFile, GetlstDirEntry, GetNxtDirEntry.
87
FindVBMBit
FindVBMBitJAppie)
mid-level diskl
Function:
Uses:
Returns:
Alters:
Destroys:
Get disk block allocation status.
Parameters: r6
BLOCK — block number (word).
VBMBlknot
curVBlknot
VBMchangedt
numVBMBIkst
first VBM block starts here; set initially by OpenDisk
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
St z flag reflects allocation status (1 = fiee; = allocated).
r8H mask for isolating VBM bit
r7 offset to BAM byte in current VBM block.
a BAM byte masked witfi r8H.
r6 unchanged.
curVBlknot
VBMchangedt
Block that contains the VBM bit for BLOCK.
changed to FALSE if VBM cache flushed.
^used internally by GEOS disk routines: applications generally don't use.
y
Description: FindVBMBit accesses the VBM of the current disk and returns the allocation
status of a particular block. If the VBM bit is zero, then the block is in-use; if the
VBM bit is one, tiien the block is free. FindVBMBit returns witir tiie z flag set
to reflect the status of the BAM bit so tiiat a subsequent bne or beq branch
instructions can test the status of a block after calling FindVBMBit:
bne
beq
BloclcIsFree
or-
BlocklnUse
C64 &C128: See FindBAMBit.
Example:
LoadW
jsr
cpx
bne
tay
beq
r6,#BL0CK
FindVBMBit
#NO_ERROR
diskError
BlocklnUse
/branch if block is free
/branch if block is in-use
get block number
get allocation status
check for error
branch on error
check block status
branch if block in use
See also: FindBAMBit, AlIocateBlock, FreeBlock, GetDirHead, PutDirHead.
88
FirstI
Firstlnit (Apple, C64, cm)
internal
Function: Simulates portions of the GEOS coldstart procedure without actually rebooting
GEOS or destroying the application in memory.
Parameters: none
Returns: GEOS variables and system hardware in a coldstart state; stack and application
space unaffected
Destroys: a, x, y, r0-r2
Description: Firstlnit is part of the GEOS coldstart procedure. It initializes nearly all GEOS
variables and data structures (both global and local), including those which are
usually only done once, when GEOS is first booted, such as setting the
configuration variables to a default, power-up state.
GEOS calls this routine intemally. Applications will not find it especially useful.
Note: The GEOS font variables are not reset by Firstlnit; a call to UseSystemFont
may be necessary.
See also: WarmStart, StartAppl.
89
FndFillnDir
FndFillnDir (Apple)
high-level disk!
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Special Apple GEOS version of FindFile that will search for a file in a directory
other than die current directory.
r6 FILENAME — pointer to nuU-terminated name of file (word),
rl DERBLKNO — block number of directory to search (word).
curDrive
X error ($00 = no error).
rl block number of directory block containing entry.
rS pointer into diskBIkBuf to start of directory entry.
diskBIkBuf
dirEntryBuf
a, y, r4-r6.
contains directory block where FILENAME found,
directory entry of file if found.
C64 & C128:
Example:
See also:
FndFillnDir performs the same action as FindFile, except tiiat DIRBLKNO
temporarily becomes the current directory. The current directory is restored before
returning. FndFillnDir returns the directory entry in dirEntryBuf. If the file
specified with FILENAME is not found in the DIRBLKNO directory, a
FILE^NOT^FOUND error is returned.
Commodore GEOS does not support a hierarchical file system.
FindFile, FdFTypesInDir, GoDirectory.
90
FollowChain
FollowChain (C64, cus)
mid-level disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Apple:
Example;
Follow a chain of Commodore disk blocks, building out a track/sector table.
rlL START^TRACK — track number of starting block (byte),
rlH START^SEC — sector number of starting block (byte).
r3 TSTABLE — pointer to buffer for building out track and sector table of
chain, usually points to fileTrScTab (word).
curDrive.
curType
GEOS 64 vl.3 and later for detecting REU shadowing.
X error ($00 = no error). ,
r3 unchanged.
track/sector built-out in buffer pointed to by TSTABLE.
diskBlkBuf
a, y, rl, r4.
used for temporary block storage.
FollowChain constructs a track/sector table for a list of chained blocks on the
disk. It starts with the block passed in START JTR and START^SC and follows
the links until it encounters the last block in the chain. Each block (including the
first block at START JTR, START JSC ) becomes a part of the track/sector table.
Commodore disk blocks are linked together with track/sector pointers. The first
two bytes of each block represent a track/sector pointer to die next block in the
chain. Each sequential file and VLIR record on the disk is actually a chained list
of blocks. FollowChain follows these track/sector links, adding each to the list
at TSTABLE until it encounters a track pointer of $(X), which terminates the
chain. FollowChain adds this last track pointer ($00) and its corresponding
sector pointer (which is actually an index to the last valid byte in the block) to the
track/sector table and returns to the caller.
FollowChain builds a standard track/sector table compatible with routines such
as WriteFile and FastDelFile.
Apple GEOS has no FollowChain equivalent because ProDOS links blocks
together, not by pointers within each block, but by a list of blocks in an index
associated with each sequential file and VLIR record This index is called the
index block and, as its name implies, occupies a single block on die disk.
LoadB
LoadB
LoadW
jsr
txa
bne
rlL,#START_TR
rlH,#START_SC
r3,#fUeTrScTab
FollowChain
HandleError
; start track
; and sector
; buffer for table
; create tr/sc table
; set status flags
; branch if error
See also:
91
i
F^llowChain
IFrameRectangle, i FrameRectangle (Apple, C64, cm) graphics]
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
128:
Draw a rectangular frame (one-pixel thickness).
Normal:
a eight-bit line pattern.
r3 XI — x-coordinate of upper-left (word).
r2L Yl — y-coordinate of upper-left (byte).
r4 X2 — x-coordinate of lower-right (word).
r2H Y2 — y-coordinateof lower-right (byte).
where (XI, Yl) is the upper-left corner of the frame and (X2,Y2) is the lower-
right corner.
Inline:
data appears immediately after the jsr i^FrameRectangle
.byte Yl y-coordinate of upper-left
.byte Y2 y-coordinateof lower-right,
.word XI x-coordinate of upper-left
.word X2 x-coordinate of lower-right.
.byte PATTERN eight-bit line pattern.
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
r2, r3, and r4 unchanged.
Commodore
a, X, y, r5-r9, rll
Apple
a,x, y, rll
FrameRectangle draws a one-pixel rectangular frame on the screen as
determined by the coordinates of the upper-left and lower-right comers. The
horizontal and vertical lines which comprise the frame are drawn with the
specified line pattern.
FrameRectangle operates by calling HorizontalLine and VerticalLine with
the desired line-pattern. As with these two routines, the line pattern is drawn as if
aligned on an eight-pixel boundary. The values of the comer pixels will be
determined by the vertical sides because they are drawn after the hoi:izontal sides.
Because all GEOS coordinates are inclusive, framing a filled rectangle requires
either calling FrameRectangle after calling Rectangle (and thereby
overwriting the perimeter of the filled area) or calling FrameRectangle with
iXl'lJl-l) and (X2+1,Y2+1) as the comer points.
Under GEOS 128, or'ing DOUBLE W into the XI andX2 parameters will
automatically double the x-position in SD-column mode. Or'ing in ADD1_W will
FollowChain
automatically addl to a doubled x-position. (Refer to "GEOS 128 X-position and
Bitmap Doubling" in Chapter.@gr@ for more information.)
Example:
See also: Rectangle, ImprintRectangle, RecoverRectangle, InvertRectangle.
FYeeBlOCkjApple, C64, C128)
mid-level diskl
Function:
Parameters:
Uses:
Returns:
Alters:
Free an allocated disk block.
Commodore:
r6L track number of block to free (byte).
r6H sector number of block to free (byte).
Apple;
r6 block to free (word).
curDrive
Commodore:
curDirHead
dir2Headt
dir3Headt
A pple:
curVBlknot
VBMchangedt
numVBMBIkst
this buffer must contain the current directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use,
X error ($00 = no error); returns BAD_B AM if block already free.
r6L, r6H unchanged. "
Commodore:
curDirHead
dir2Headt
dir3Headt
Apple:
curVBlknot
VBMchangedt
BAM updated to reflect newly allocated block.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines.
set to TRUE by VBM cacheing routines to indicate cached
VBM block has changed and needs to be flushed
Destroys:
Description:
^used internally by GEOS disk routines; applications generally don't use.
a, y, r7, rSH.
FreeBIock tries to free (deallocate) the block number passed in r6. If the block
is already free, then FreeBIock returns a BAD_BAM error.
C64 & C128: FreeBIock was not added to the Commodore GEOS jump table until v 1.3, but it
can be accessed direcdy under GEOS vl.2. The following routine will check the
GEOS version number and act correcdy under GEOS vl.2 and later.
MyFreeBlock — allocate specific block in BAM
with any GEM device driver.
FrameRectangle
• ***************** *«*****4r********* *********************
MyFreeBlock:
Ida
cmp
bne
Jsr
bne
Ida
eor
sta
Idx
inc
Idx
rts
88$:
10$:
Idx
rts
jmp
version
#$12
10$
FindBAMbit
88$
r8h
curOirHead, x
curDirHead, x
r7H
curDirHead, x
»0
#BAD BAM
FreeBlock
check GEOS version number
version 1.2?
if not, go through jump table
r6L « track #
r6h « sector #
Get mask for BAM byte in r8H
offset to track in r7h
offset into bam in X
masked value A
if 1, then not allocated, give error
get mask
flip BAM bit to show available
one more free block
NO ERROR
; BAM ERROR
;vl,3+: go thru jump tbl
FreeBlock does not automatically write out the BAM. See PutDirHead for
more information on writing out the BAM.
Apple: FreeBlock does not automatically flushctiie VBM cache. See PutVBM for more
information on flushing die VBM cache.
Example:
See also: FreeFile, AllocateBlock.
Dir
FreeDir (Apple)
mid-level disk!
Function:
Parameters:
Uses:
Free the chained directory blocks associated with a subdirectory. Does not delete
the subdirectory's directory entry. The subdirectory must be empty.
r9 DIRENTRY — pointer to directory entry of subdirectory being freed,
usually points to dirEntryBuf (must be in main memory.) (word).
curDrive
curVBlknot
VBMchangedt
numVBMBlkst
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
Returns:
Alters:
^used internally by GEOS disk routines; explications generally don't use.
X error ($00 = no error).
diskBIkBuf
curVBlknot
VBMchangedt
used for temporary block storage,
used by VBM cacheing routines.
set to FALSE by VBM cacheing routines to indicate cached
VBM block has already been flushed
Destroys:
Description:
^used internally by GEOS disk routines; applications generally don't use.
a, y, rl, r4, r6, r7, r8H.
Given a valid subdirectory entry, FreeDir will free all the directory blocks
allocated to the subdirectory. The subdirectory's directory entry, however, is left
intaa.
«
The subdirectory entry is a standard data structure returned by routines such as
FIndFile, GetlstDirEntry and GetNextDirEntry. A subdirectory is flagged
by a PRO DIR in the GEOS type byte in the directory entry (at
OFF^FTYPt). FreeDir is called automatically by DeleteDir.
FreeDir will not free the blocks of subdirectory that has files in it. A
DIR^NOT^EMPTY error will be returned. (The number of files in die
subdSrcctoryls stored in the OFFB_FLCNT word of the directory's header.
This maintains this value by calling UpdateParent when files are added or
removed.)
FreeDir flushes die VBM cache.
C64 & C128: Commodore GEOS does not support a hierarchical file system.
Example:
See also: DeleteDir, DeleteFile, FreeFile, FreeBIock.
9 6
FreeFile
FreeFile (Apple, C64, cns)
mid-level disk!
Function:
Parameters:
Uses:
Returns:
Alters:
Free all the blocks in a GEOS file (sequential or VLIR) without deleting the
direaory entry. The GEOS file header and any index blocks are also deleted.
r9 DIRENTRY — pointer to directory entry of file being freed, usually
points to dirEntryBuf (Apple GEOS: must be in main memory.)
(word).
curDrive
Cpmmodgrp;
curType
Apple;
curVBIknot
VBMchanged^
numVBMBlkst
GEOS 64 vL3 and later for detecting REU shadowing.
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines: applications generally don't use.
X error ($(X) = no error).
diskBlkBuf
CpmiTiodorp;
curDirHead
dir2Headt
dirSHeadt
fileHeader
used for temporary block storage.
BAM updated to reflect newly fteed blocks.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
temporary storage of the index table when deleting a VLIR
file.
Destroys:
Applg;
curVBIkno*
VBMchangedt
used by VBM cacheing routines.
set to FALSE by VBM cacheing routines to indicate cached
VBM block has already been flushed
Description:
^used internally by GEOS disk routines;, applications generally don't use.
Cpmmodorp;
a, y, r0-r9.
Apple:
a, y, rl, r2L, r4, r6, r7, r8H, r9.
Given a valid directory entry, FreeFilfe will delete (free) all blocks assocatied
with the file. The GEOS file header and any index blocks associated with the file
are also be freed. The directory entry on the disk, however, is left intact
The directory entry is a standard GEOS data structure returned by routines such
as FindFile, GetlstDirEntry and GetNxtDirEntry. FreeFile is called
automatically by DeleteFile.
97
FreeFile
C64 & C128: FreeFile calls GetDirHead to get the current directory header and BAM into
memory. It then checks at OFF GHDR^PTR in the directory entry for a CEOS
file header block, which it then ffees.
If the file is a sequential file, FreeFile walks the chain pointed at by the
OFF_DE_TR_SC track/sector pointer in the directory header and frtcs all the
bloclcs inlhe chain. FreeFile then calls PutDirHead to write out the new
BAM.
If the file is a VLIR file, the index table (the block pointed to by
OFF JNDEX^PTR) is first read into fileHeader then marked as free in the
BAMT FreeFife then goes through each record. If the record has data in it,
FreeFile walks through the chain, fieeing all the blocks in the record. FreeFile
finishes by calling PutDirHead to write out the new BAM.
When using GetlstDirEntry and GetNxtDirEntry, do not pass FreeFile a
pointer into diskBIkBuf. Copy the full directory entry (DIRENTRY^SIZE
bytes) from diskBIkBuf to another buffer (such as dirEntryBuf) and pass
FreeFile the pointer to that buffer. Otherwise when FreeFile uses
diskBIkBuf it will corrupt the directory entry.
Because FreeFile deletes a block at a time as it follows the chains, it is capable
of deleting files with chains larger than 127 blocks, which is the standard GEOS
limit imposed by the size of TrScTable.
Apple: FreeFile first copies the entire directory entry (ENTRY^SIZE bytes) from
DIRENTRY (in main memory) to an internal buffer in auxiliary memory.
If tiie file is a VLIR file, then FreeFile reads the VLIR index block (the ProDOS
* master index block) into memory and frees all the data blocks in each record. The
VLIR index block and all the individual record index blocks are then deleted.
FreeFile finishes by calling PutVBM to flush the VBM cache.
If the file is a sequential file, FreeFile reads the sequential index block into
memory, frees all assoiciated data blocks,.then frees the index block itself.
FreeFile finishes by calling PutVBM to flush the VBM cache.
FreeFile cannot free a subdirectory. To free a subdirectory, use FreeDir.
Example:
See also: DeleteFile, FreeDir, FreeBlock.
98
FreezeProcess
IFreezeProcess (Apple, C64, ci287
process]
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Freeze a process's countdown timer at its current value.
X PROCESS — number of process (0 - n-1, where n is the number of
processes in the table) (byte).
X
a
unchanged.
FreezeProcess halts a process's countdown timer so that it is no longer
decremented every vblank. Because a frozen timer will never reach zero, the
process will not become runable except through a call to EnableProcess. When
a process is unfrozen with UnFreezeProcess, its timer again begins counting
from the point where it was frozen.
If a process is already frozen, a redundant call to FreezeProcess will have no
effect.
Example:
See also:
UnfreezeProcess, BlockProcess.
GetlstDirEntry
GetlstPirEntry (Apple, C64, ci28)
mid-level disk!
Function:
Parameters:
Uses:
Loads in the first directory block of the current directory and returns a pointer to
the first directory entry within this block.
none.
curDrive
Commodore:
curType
Apple;
curKBlkno
GEOS 64 V 1.3 and later for detecting REU shadowing.
current directory.
Returns:
Alters:
Destroys:
Description:
X error ($00 = no error).
r5 pointer to first directory entry within diskBlkBuf.
diskBlkBuf
a, y, rl, r4.
directory block.
GetlstDirEntry reads in the first directory block of the current directory and
returns with r5 pointing to the first directory entry. GetlstDirEntry is called by
routines like FindFTypes and FindFile.
To get a pointer to subsequent directory entiles, call GetNxtDirEntry.
C64 & C128: Since Conmiodore GEOS does not support a hierarchical file systeni, the "current
directory" is actually the entire disk.
GetlstDirEntry did not appear in the jump table until version 1.3. An
application running under version 1.2 can access GetlstDirEntry by calling
directly into the Kemal. The following subroutine will work on Commodore
GEOS vl. 2 and later:
• *************
; MyGetlstDirEntry — Call instc^&d of GetlstDirEntry
; to work on GEOS vl.2 and later
r
*******************************************************
; EQUATE: vl.2 entry point directly into Kernal. Must
;do a version check before calling.
o_GetlstDirEntry - $c9f7
MyGetlstDirEntry:
Ida version
cmp #$13
bge 10$
jmp o_GetlstDirEntry
10$:
jmp
GetlstDirEntry
; exact entry point
; check version number
/branch if vl.3 or later
/direct call
;go through jump table
\
100
GetlstDirEntry
Apple: GetlstDirEntry did not appear in the jump table until version 2.0, release 3. An
application running under an earlier version can add GetlstDirEntry mto the
jump table with the patch provided in Appendix @@.
Example:
See also: GetNxtDirEntry, FindFTypes.
101
GetBlock
GetBlOCk (Apple, C64, C128)
low-level disk!
Function:
Parameters:
General purpose routine to get a block from current disk.
r4 BUFFER — address of buffer to place block; must be at least
BLOCKSIZE bytes (word).
Commodore:
rlL TRACK — valid track number (byte).
rlH SECrrOR — valid sector on track (byte).
Applg;
rl BLOCK — ProDOS block number (word).
Uses:
curDrive
Commodore:
curType
Apple;
RWbank
currendy active disk drive.
GEOS 64 vl.3 and later for detecting REU shadowing,
bank BUFFER is in (MAIN or AUX).
Returns:
Destroys:
Description:
X error ($00 = no error),
rl, r4 " unchanged
a, y.
GetBlock reads a block from the disk into BUFFER. GetBlock is useful for
implementing disk utility programs and new file structures.
C64 & C128: GetBlock is a higher-level version of ReadBlock. It calls InitForlO,
EnterTurbo, ReadBlock, and DoneWithlO. If an application needs to read
many blocks at once, ReadBlock may offer a faster solution. If the disk is
shadowed, GetBlock will read from the shadow memory, resulting in a faster
transfer.
Apple:
Example:
See also:
The Commodore 1581 driver has a bug that causes its GetBlock to trash rl and
r4.
GetBlock provides the lowest-level block access to a ProDOS compatible
device. It uses the ProDOS device driver READ block command direcdy. Apple
GEOS, for this reason, does not have a ReadBlock equivalent.
PutBlock, ReadBlock.
102
GetCharWidth
GetCharWidth (Apple, C64, cus)
text
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Example:
See also:
Calculate the pixel width of a character as it exists in the font (in its plaintext
form). Ignores any style attributes.
a CHAR — character code of character (byte).
curlndexTable
a character width in pixels.
GetCharWidth calculates the width of the character before any style attributes
are applied. If the character code is less. than 32, $00 is returned. Any other
character code returns the pixel width as calculated from the font data structure.
Because GetCharWidth does not account for style attributes, it is useful for
establishing the number of bits a character occupies in the font data structure.
GetRealSize.
103
GetDimensions
GetDimensions (C64, cns)
printer driver!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Get printer resolution,
none.
a $00 = printer has graphics and text modes; $ff = printer only has text
modes (e.g., daisy wheel printers).
X PGWIDTH — page width in cards: number of 8x8 cards that will fit
horizontally on a page (1-80, standard value is 80 but some printers
only handle 60, 72, or 75).
y PGHEIGHT — page height in cards: number of 8x8 cards that will fit
vertically on a page (1-255, usually 94).
The width and height return values are typically based on an 85" x IV* page
with a 025" margin on all sides, leaving an 8" x 10 J" usable print area.
nothing.
GetDimensions returns the printable page size in cards. At each call to
PrintBuffer, the printer driver will expect at ltdiSXPGWIDTH cards of graphic
data in the 640-byte print buffer. To print an entire page , the application will need
to call PrintBuffer PGHEIGHT times.
Most dot-matrix printers have a horizontal resolution of 80 dots-per-inch and an
eight inch print width. Eight inches at 80 dpi gives 640 addressable dots per
printed line, and 640/8 equals 80 cards per line. GEOS assumes an 80 dpi output
device.
Drivers for printers with a different horizontal resolution will usually return a
PGWIDTH value that reflects some even multiple of the dpi. For example, a
lower resolution 72 dpi printer can only fit 72*8 = 560 dots per line, and 560
dots reduces to 72 cards. PGWIDTH in this case would come back as 72.
A 300 dpi laser printer, however, can accomodate 2,400 dots on an eight inch
line. To scale 80 dpi data to 300 dpi, each pixel is expanded to four times its
normal width. If the printer driver tried to print the full 640 possible dots at this
expanded width, it would lose the last 160 dots because the printer itself can only
handle 2,400 dots in an eight inch space and 640*4 = 2,560. To alleviate this
problem he printer driver truncates the width at the card boundary nearest to
2,400 dots, which happens to be 75 cards. Hence, in this case, PGWIDTH
would come back as 75.
The size, PGHEIGHT, reflects the number of card rows to send through
PrintBuffer to fill a full-page. If more rows are sent, then (depending on the
printer and the driver) the printing will usually continue onto the next page
(pnniing over the perforation on z-fold paper). The application will usually keep
an mtemal card-row counter and call StopPrint to advance to the next page.
It is not necessary to call GetDimensions when printing ASCII text.
Commodore GEOS printer drivers always assume 80 columns by 66 lines.
104
GetDimensions
Apple: This routine is not supported under Apple GEOS. Apple GEOS offers a more
sophisticated printer driver scheme. Refer to GetMode for more information.
See also: StartPrint, StartASCII.
105
GetDirHead
GetPirHead (Apple, C64, cus)
mid-level disk
Function: Read directory header from disk. Commodore GEOS also reads in the BAM.
Parameters: none.
Uses:
curDrive
Commodore:
curType
Applg;
curKBlkno
GEOS 64 vl.3 and later for detecting REU shadowing.
current directory key block.
Returns:
Alters:
X error ($00 = no eiror).
Commodore:
r4 pointer to curDirHead.
curDirHead
Commodore:
dir2Headt
dir3Headt
contains directory header (39 bytes on Apple).
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
Destroys:
^used internally by GEOS disk routines; applications generally don't use.
Comm9<j(3rp;
a, y, rl.
Description:
Appig;
a, y, rl. r4.
GetDirHead reads the directory header into the buffer at curDirHead. Because
of differences in the Commodore and Apple file systems, this can mean different
things. Commodore GEOS places the full directory header block (256 bytes) into
curDirHead. This block also includes the BAM (block allocation map) for the
entire disk. Apple GEOS. on the other hand, only places the 39-byte ProDOS
directory header for the current directory into curDirHead.
C64 & C128: GEOS disks, like the standard Ctommodore disks upon which they are based,
have one directory header. The directory header occupies one full block on the
disk. The Commodore directory header contains information about the disk, such
as the location of the directory blocks, the disk name, and the GEOS version
string (if a GEOS disk). The Commodore directory header also contains the disk
BAM, which flags particular sectors as used or unused
GetDirHead calls GetBlock to read in the directory header block into the
buffer at curDirHead. The directory header block contains the directory header
and the disk BAM (block allocation map). Typically, applications don't call
GetDirHead because the most up-to-date directory header is almost always in
memory (at curDirHead), OpenDisk calls GetDirHead to get it there
106
GetDirHead
initially. Other GEOS routines update it in memory, some calling PutDlrHead to
bring the disk version up to date.
Because Commodore disks store the BAM information in the directory header it is
important that the BAM in memory not get overwritten by an outdated BAM on
the disk. An application that manipulates the BAM in memory (or calls GEOS
routines that do so), must be careful to write the BAM back out (with
PutDirHead) before calling any other routine that might overwrite the copy in
memory. GetDirHead is called by routines such as OpenDisk,
SetGEOSDisk, and GpenRecordFile, etc.
Apple: Apple GEOS disks, like tiie ProDOS disks upon which they are based, have a
directory header for each directory. The header for the root directory is called a
volume directory header and the header for a subdirectory is called a subdirectory
header. These directory headers arc 39-byte structures defined by ProDOS. They
contain such information as the directory name, the date stamp, and read/write
access flags. The directory header does not contain the VBM (volume bit map, the
Apple equivalent of a BAM).
GetDirHead reads in the key block of the current directory (pointed at by
curKBIkno) and copies the 39-byte directory header information to
curDirHead.
Since Apple GEOS does not store the allocation map (VBM) in die directory
header Uke Commodore GEOS, it not necessary to be as careful about rereading
the directory header. For more information on reading the Apple VBM, refer to
GetVBM.
Example:
See also: PutDirHead, GetVBM, PutVBM.
107
GetFHdrlnfo
GetFHdrlnfo (Apple, C64, cns)
mid-level disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Loads the GEOS file header for a particular directory entry.
r9 DIRENTRY — pointer to directory entry of file, usually points to
dirEntryBuf (Apple GEOS: must be in main memory) (word).
curDrive
Commodore:
curType
GEOS 64 vl.3 and later for detecting REU shadowing.
X error ($00 = no error).
r7 load address copied from the O^GHST^ADDR word of the GEOS
file header.
Commodore:
rl
Applg;
rl
track/sector copied from bytes +1 and +2 of the directory entry
(DIRENTRY), This is the track/sector of the first data block of a
sequential file (OFF DE TR SC) or the index table block of a VLIR
file (OFF INDEX TPTff). "
block number of sequential-file index block or VLIR master index block
as copied from the OFF^FINDX byte of the directory entry.
fileHeader
CQmnyyjqrsi
fileTrScTab
a, y, r4.
contains 256-byte GEOS file header.
track/sector of header added to first ♦wo bytes of this table; a
subsequent call to ReadFile or similar routine will augment
this table beginning with the third byte (fileTrScTab+2) so
as not to disrupt this value.
Given a valid directory entry, GetFHdrlnfo will load the GEOS file header into
the buffer at fileHeader.
The directory entry is a standard GEOS data structure returned by routines such
as FindFile, GetlstDirEntry and GetNextDirEntry. GetFHdrlnfo is
called by routines such as LdFile just prior to calling ReadFile (to load in a
sequential file or record zero of a VLIR).
GetFHdrlnfo gets the block number (Commodore track/sector) of the GEOS
file header by looking at the OFF_GHDR_PTR word in the directory entry.
Example:
See also:
108
GetFile
GetFile (Apple, C64, C128)
high-level disk
Function: General-purpose file routine that can load an application, desk accessory, or data
file.
Parameters: r6
FILENAME — pointer to null-terminated filename (word).
Uses:
When loading an application:
rOL LOAD^OFT:
bit 0: load at address specified in file header, application will be
started autmatically
1 load at address in r7; application will not be staned
automatically,
bit?: not passing a data file.
1 r2 and r3 contain pointers to disk and data file names,
bit 6: not printing data file.
printing data file; application should print file and exit
r7 LOAD_ADDR — optional load address, only used if bit of
LOAD JOPT is set (word).
r2 DATA^DISK— only valid if bit 7 or bit 6 of LOAD jOPT is set: pointer
to name of the disk that contains the data file, usually a pointer to one of
the DrxCurDkNm buffers (word).
r3 DATA.FILE — only valid if bit 7 or bit 6 of LOAD jOPT is set: pointer
to name of the data file (word).
When iQ^ding a de?k accessory;
rlOL REGVR^OPTS — no longer used; set to $00 (see below for explanation
(byte).
curDrive
CptpmodoTp;
curType
Apple;
RWbank
GEOS 64 vl.3 and later for detecting REU shadowing.
destination bank (MAIN or AUX); always set to MAIN
when loading an application or desk accessory.
Returns: When loa(iing ap applicatfon;
only returns if alternate load address or disk error.
X error ($(X) = no error).
rO, r2, r3, and r7 unchanged.
When loading a desk accessory:
returns when desk accessory exits with a call to RstrAppl.
X error ($(X) = no error).
When loading a data file:
X error ($(X) = no em)r).
Passes: When loading an application!
warmstarts GEOS and passes the following to the application:
109
GetFile
rO as originally passed to GetFile.
r2 as originally passed to GetFile (use dataDiskName).
r3 as originally passed to GetFile.(use dataFileName).
dataDiskName contains name of data disk if bit 7 of rO is set
dataFileName contains name of data file if bit 6 of rO is set
When loading a desk accessory:
warmstarts GEOS and passes the following:
rIOL as originally passed to GetFile.
When loading a data file:
not applicable.
Alters: When loading an application:
GEOS brought to a warmstart state.
Destroys: a, x, y, rO-rlO (only applies to loading a data file).
Description: GetFile is the preferred method of loading most GEOS files, whether a data file,
application, or desk accessory. (The only exception to this is a VLIR file, which
is better handled with the VLIR routines such as OpenRecordFile and
ReadRecord). Most applications will use GetFile to load and execute desk
accessories when the user clicks on an item in the geos menu. Some applications
will use GetFile to load other applications. The GEOS deskTop, in fact, is just
another application like any odier. Depending on the user's choice of actions —
open an application, open an application's data file, print an applications' data file
— die deskTop sets LOADjOPT, DATA^DISK, DATAJFILE appropriately and
calls GetFile.
GetFile first calls.FindFile to locate die file at FILENAME, then checks the
GEOS file type in the directory entry. If the file is type DESK ACC, then
GetFile calls LdDeskAcc. If die file is type APPLICATIDN or type
AUTO^EXEC, GetFile calls LdApplic. All odier file types are loaded widi
the generic LdFile.
The following GEOS constants can be used to set the LOADjOPT parameter
when loading an application:
ST_LD_AT_.ADDR
Load at address: load application at the address passed in
r7 as opposed to the address in the file header.
ST^LD^DATA
Load data file: aj^lication is being passed the name of a
data file to load.
ST^PR^DATA
Print data file: aiqplication is being passed the name of a
data file to print
Note: The RECVRjOPTS flag used when loading desk accessories originally carried
die following significance:
bit 7: 1 force desk accessory to save foreground screen area and restore it on return to
application.
not necessary for desk accessory to save foreground.
Commodore only;
bit 6: 1 force desk accessory to save color memory and restore it on return to
application.
110
GetFile
not necess^ for desk accessory to save color memory.
However, it was found that the extra code necessary to make desk accessories
save the foreground screen and color memory provided no real benefit because
this context save can just as easily be accomplished from within the application
itself. The RECVRjOPTS flag is set to $00 by all Berkeley Softworks
applications, and desk accessories can safely assume that this will always be the
case. (In fact, future versions of GEOS may force rlOH to $00 before calling
desk accessories just to enforce this standard! )
The application should always set rlOH to $00 and bear the burden of saving and
restoring the foreground screen and the color memory. (Color memory only
applicable to GEOS 64 and GEOS 128 in 40-column mode.)
Apple: Applications and desk accessories arc designed to load into main memory. Ensure
that RWbank contains MAIN before calling GetFile to load anything but a data
file.
Example:
See also: LdFile, LdDeskAcc, LdApplic.
111
GetFreeDirBlk
GetFreeDirBlk (Apple, C64, ci28)
mid-level disk
Function:
Parameters:
Uses:
Search the current directory for an empty, slot for a new directory entry. Allocates
another directory block if necessary.
rlOL DIRPAGE — directory page to begin searching for free slot; each
directory page holds eight files and corresponds to one notepad page on
the GEOS deskTop. The first page is page one.
curDrive
COniniQ<jorg;
curType GEOS 64 vl.3 and later: for detecting REU shadowing.
curDirHead this buffer must contain the current directory header.
dir2Headt (BAM for 1571 and 1581 drives only)
dirSHeadt (BAM for 1581 drive only)
interleave^ desired physical sector interleave (usually 8);. applications
need not set this explicitly — will be set automatically by
internal GEOS routines. Only used when new directory
block is allocated
Returns:
Alters:
Apple:
curKBIkno
curVBlknot
VBMchangedt
numVBMBlkst
current directory,
used by \'BM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
rlOL page number of empty directory slot.
rl block (Commodore track/sector) number of directory block in
diskBlkBuf.
Commodore:
y index to empty directory slot in diskBlkBuf.
Apple;
r3
rlOH
pointer to empty directory slot in diskBlkBuf. This is an absolute
address, not an index into diskBlkBuf.
unused directory entry within block in diskBlkBuf. There are 13
directory entries per ProDOS block, numbered 1-13.
Commodore:
curDirHead
dirlHeadt
dir3Headt
Apple;
curVBlknot
VBMchangedt
BAM updated to reflect newly allocated block!
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines.
set to TRUE by VBM cacheing routines to indicate cached
VBM block has changed and needs to be flushed
112
GetFreeDirBlk
^used internally by GEOS disk routines; applications generally don't use.
Destroys: CpiprTKyjorg:
a, rO, r3, rS, r7-r8.
Apple:
a» r4-r5, r7-r8.
Description: GetFreeDirBlk searches the current directory looking for an empty slot for a
new directpry entry. A single directory page has eight directory slots, and these
eight slots correspond to the eight possible files that can be displayed on a single
GEOS deskTop notepad page.
GetFreeDirBlk starts searching for an empty slot beginning with page number
DIRPAGE. If GetFreeDirBlk reaches the last directory entry without finding
an empty slot, it will try to allocate a new directory block. If DIRPAGE doesn't
yet exist, empty pages are added to the directory structure until the requested page
is reached.
$01 will most often be passed as the DIRPAGE starting page number, so that all
possible directory slots will be searched, starting with the fiirst page. If higher
numbers are used, GetFreeDirBlk won't find empty directory slots on lower
pages and extra directory blocks may be allocated needlessly.
GetFreeDirBlk is called by SetGDirEntry before writing out the directory
entry for a new GEOS file.
C64 & C128: Since Conimodore GEOS does not support a hierarchical file systeni, the "current
directory" is actually the entire disk. A dkectory page corresponds exacdy to a
single sector on the directory track. There is a maximum of 18 directory sectors
(pages) on a Commodore disk. If this 18th page is exceeded, GetFreeDirBlk
will return a FULL^DIRECTORY error.
GetFreeDirBlk allocates blocks by calling SetNextFree to allocate sectors on
the directory track. SetNextFree wUl specid-case the directory track allocations.
Refer to SetNextFree for more information.
GetFreeDirBlk does not automatically write out the BAM. See PutDirHead
for more information on writing out the BAM.
Apple: ProDOS directory blocks (and therefore GEOS directory blocks) contain 13
directory slots. This requires Apple GEOS to map GEOS's eight-entry directory
pages to tiiese 13-entry blocks, sometimes forcing a page to straddle a block
boundary. Most applications need not worry about this straddling as it is made
transparent by GEOS routines such as FindFile.
If an empty directory slot is not found and the end of the last block of the current
directory is reached, GetFreeDirBlk calls SetNextFree to allocate a new
directory block. The number of blocks in a ProEKDS directory is limited only by
space. liF there is no more space on the disk for another directory block, and
INSUFFICIENT^SPACE error is returned.
113
GetFreeOirBlk
GetFreeDirBIk does not automatically flush the VBM cache. See PutVBM
more information on flushing the cache.
Example:
See also: AIlocateBlock, FreeBIock, BIkAIloc.
114
GetLdVars
GetLdVars (Apple)
mid-level disk
Function: Transfers the internal "Ld" variables (those used by LdAppl, LdDeskAcc, and
LdFile) to GEOS pseudoregisters.
Parameters: none.
Returns:
rOL
Destroys:
Description:
r7
r2
r3
rlOL
a.
LOAD.OPT:
bitO: load at address specified in file header; application will be
started autmatically
1 load at address in r7; application will not be started
automatically,
bit?: not passing a data file.
1 r2 and r3 contain pointers to disk and data file names,
bit 6: not ininting data file.
printing data file; application should print ^e and exit
LOAD_ADDR — optional load address, only used if bit of
WADJDPT is set (word).
DATA^DISK — only valid if bit 7 or bit 6 of LOAD JOPT is set: pointer
to name of the disk that contains the data file, usually a pointer to one of
the DrjcCurDkNm buffers (word).
DATA^FILE — only valid if bit 7 or bit 6 of LOAD jOPT is set: pointer
to name of the data file (word).
RECVR.OPTS (byte).
GetLdVars transfers the internal load varaibles to GEOS pseudoregisters.
GetFile, LdApplic, LdDeskAcc, and LdFile call GetLdVars as necessary.
Most applications will not need to call it direcdy.
See also:
SetLdVars.
CONriDCNTUL 1 1 5
GetMode
GetMode (Apple)
printer driver
Function: Get printer resolution and setable attributes.
Parameters: none.
Returns:
Destroys:
Description:
a ASCnWIDTH — page width for ASCII printing (characters per line),
assumes 10 cpi pitch (byte).
X PGWIDTH — page width in cards: number of 8x8 cards that will fit
horizontally on a page (1-80, standard value is 80 but some printers
only handle 60, 72, or 75) (byte). If $00, then this is an older driver:
assume 80 cards.
y PGHEIGHT — page height in cards: number of 8x8 cards that will fit
vertically on a page (1-255, usually 94) (byte).
rO-r2L MODE — flags for possible printer modes and capabilities (five bytes).
The width and height values are typically based on an 85" xU" page with a
025" margin on all sides, leaving an 8" x 105" usable print area.
assume r2H-r4.
GetMode returns information concerning the resolution and capabilites of the
nnntpr
currently installed printer.
Graphic Printing:
At each call to PrintBuffer, the printer driver will expect at leastFGW^/Dr//
cards of linear bitmap data in the 640-byte print buffer. To print an entire page ,
the application will need to call PrintBuffer PGHEIGHT times.
Most dot-matrix printers have a horizontal resolution of 80 dots-per-inch and an
eight inch print width. Eight inches at 80 dpi gives 640 addressable dots per
printed line. Since GEOS printer output is designed to map dirccdy from screen
graphics, it is sometimes useful to think of it in terms of cards (8x8 pixel blocks).
There 80 (640/8) 80 cards per printable line. GEOS always assumes an 80 dpi
output device.
Drivers for printers with a different horizontal resolution will usually return a
PGWIDTH value that reflects some even multiple of the dpi. For example, a
lower resolution 72 dpi printer can only fit 72*8 = 560 dots per line, and 560
dots reduces to 72 cards. PGWIDTH in this case would come back as 72. The
printer driver will only ouput the first 72 cards (560 dots) on each line.
A 300 dpi laser printer, however, can accomodate 2,400 dots on an eight inch
line. To scale 80 dpi data to 300 dpi, each pixel is expanded to four times its
normal width. But 640*4 = 2,560, which is 160 dots more than the printer can
handle. If the printer driver tried to print the full 640 possible dots at this
expanded width, it would lose the last 160 dots. The printer driver truncates the
width at the card boundary nearest to 2,400 dots, which happens to be 75 cards
(75*8*4 = 2400). Hence, in this case, PGWIDTH would come back as 75.
The size, PGHEIGHT, reflects the number of card rows to send through
PrintBuffer to fill a full-page. If more rows are sent, then (depending on Ae
116
GetMode
printer and the driver) the printing will usually continue onto the next page
(printing over the perforation on z-fold paper). The application will usually keep
an internal card-row counter and call StopPrint to advance to the next page.
ASCII Printing;
The printer is capable of printing ASCUWIDTH characters per line and 66 lines
per page.
The MODE W^ue^:
GetMode returns a number of flags in rO-r2L. These flags determine whether a
specific feature is offered by the current printer and its printer driver. These bits
correspond to features that may be set with SetMode:
rOL: (matches currentMode text variable)
bit
description
b7
^underline.
b6
b5
reverse.
b4
^italic.
b3
outline.
b2
^superscript
bl
^subscript
bO
reserved for future use.
(text density)
bit description
b7
+picatype(10 cpi).
b6
^elite type (12 cpi).
b5
^condensed type (16 cpi).
b4
" ^proportional type.
b3
^double height
b2
^half-height
bl
^eighi lines per inch vertical density.
bO
^six lines per inch vertical density.
(miscellaneous features)
bit description
b7
print red or magenta. .
b6
print yellow.
b5
print blue or cyan.
b4
^expanded (double-width) type.
b3
*NLO (near letter quality) type.
b2
CR always linefeeds, preventing manual overstrike by application
bl
reserved for future use.
bO
reserved for future use.
117
GetMode
rlH: (internal font availability)
bit
description
b7
font 7.
b6
font 6.
b5
font 5.
b4
font 4,
b3
font 3.
b2
font 2 (Roman?).
bl
font 1 (Helvetica?).
bO
font (Courier?).
(horizontal graphics density)
bit description
b7
60 dpi.
b6
^SOdpi.
b5
90 dpi.
b4
120 dpi.
b3
180 dpi.
b2
300 dpi.
bl
360 dpi.
bO
reserved for future use.
^This feature implemented in most Berkeley Softworks printer drivers.
C64 & C128: Refer to GetDimensions.
See also: SetMode.
118
GetNextChar
GetNextChar (Apple, C64, cns)
text/keyboard I
Function:
Parameters:
Returns:
Alters:
Destroys:
Retrieve the next character firom the keyboard queue,
none.
a keyboard character code of characer or NULL if no characters available.
pressFIag if the call to GetNextChar removes the last character from
the queue, then the KEYPRESS^BIT is cleared.
Description: GetNextChar checks the keyboard queue for a pending keypress and returns a
non-zero value if one is available. This allows more tihian one character to be
processed without returning to MainLoop.
Example:
See also:
GetString.
119
GetNxtDlrEntry
GetNxtPirEntry (Apple, C64, cm)
mid-level disk
Function:
Parameters:
Uses:
Given a pointer to a directory entry returned by GetlstDirEntry or
GetNxtDirEntry, returns a pointer to the next directory entry..
rS CURDIRENTRY — pointer to current directory entry as returned from
GetlstDirEntry or GetNxtDirEntry; will always be a pointer into
diskBlkBuf (word).
curDrive
diskBlkBuf
Commodore:
curType
must be unaltered from previous call to GetlstDirEntry or
GetNxtDirEntry.
GEOS 64 vl.3 and later, for detecting REU shadowing.
Returns:
Alters:
Destroys:
X error ($00 = no error).
rS pointer to next directory entry within diskBlkBuf.
Commodore:
y non-zero if end of directory reached
directory block.
diskBlkBuf
Ctommodore:
a, rl, r4.
Commodore:
a, y, rl, r4.
Description: GetNxtDirEntry increments rS to point to the next directory entry in
diskBlkBuf. If diskBlkBuf is exceeded, the next directory block is read in
and r5 is returned with an index into this new block. Before calling
GetNxtDirEntry for the first time, call GetlstDirEntry.
C64 & C128: GetNxtDirEntry did not appear in the jump table until version 1.3. An
application running under version 1.2 can access GetNxtDirEntry by calling
directiy into the Kemal. The following subroutine will work on Commodore
GEOS V 1.2 and later:
MyGetNxtDirEntry — Use instead of GetNxtDirEntry
to work on GEOS vl.2 and later
/EQUATE: vl.2 entry point directly into Kernal. Must
;do a version check before calling,
©^GetNxtDirEntry = $calO ; exact entry point
MyGetNxtDirEntry:
Ida version
cmp #$13
bge 10
; check version number
/branch if vl.3 or later
120
GetNxtDirEntry
jmp o_GetNxtDirEntry /direct call
10$:
jmp GetNxtDirEntry ;thru jump table
Apple: GetNxtDirEntry did not appear in the jump table until version 2.0, release 3.
An application running under an earlier version can add GetNxtDirEntry into
the jump table with the patch provided in Appendix @@.
Example:
See also: GetlstDirEntry, FindFTypes.
121
GetOffPageTrSc
GetOffPageTrSc (C64, C128) mid-level diski
Function: Get track and sector of off-page directory.
Parameters: none.
Uses: curDrive
curType GEOS 64 vl.3 and later: for detecting REU shadowing.
Returns: x error ($00 = no error).
y $ff if the disk is not a GEOS disk and therefore has no off-page
directory block, otherwise $00.
rlL track of off-page directory,
r 1 H sector of of f-page directory.
r4 pointer to curDirHead.
Alters:
curDirHead
dir2Headt
dir3Headt
isGEOS
contains directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
set to TRUE if disk is a GEOS disk, otherwise set to
FALSE.
^used internally by GEOS disk routines; applications generally don't use.
Destroys: Commodore:
a, y, rS.
Description: Commodore GEOS disks have an extra directory block somewhere on the disk
called the off-page directory. The GEOS deskTop uses the off-page directory
block to keep track of file icons that have been dragged off of the notepad and
onto the border area of the deskTop. The off-page directory holds up to eight
directory entries.
GetOffPageTrSc reads the directory header into the buffer at curDirHead and
calls ChkDkGEOS to ensure that the disk is a GEOS disk. If the disk is not a
GEOS disk, it returns with $ff in the y register. Otherwise, GetOffPageTrSc
copies the off-page track/sector from the OFF_OP_TR_SC word in the
directory header to rl and returns $00 in y. - - -
Apple: Apple GEOS does not use an off-page directory block. The Apple GEOS
deskTop manages files that are draggai onto the border area entirely in software.
Example:
; Put off-page block into DiskBlkBuf
jsr GetOffPageTrSc ;get of f-page directory block
txa ; check for error
bne 99$ ;
tya ; check for GEOS disk
tax /put in x in case error
bne 99$
LoadW r4,#diskBlkBuf ;get off-page block
jsr Get Block /
99$: rts / return with error in x
122
PutDirHead, GetVBM. PutVBM .
GetOffPageTrSc
123
GetPathname
GetPathnamejAppie)
high-level disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Builds out an ASCII pathname string to any disk directory.
rl PATHBUF — pointer to buffer to place pathnanie (word).
rOL BUFSIZE — size of pathname buffer (byte).
t2 KEYBLKNO — key block of directory to build path for; pass the value
in curKBIkno to get the path of the current directory.
curDrive
X error ($00 = no error).
y pathname status ($00 = OK; BFR_OVERFLOW = pathname longer
than jBC/F5/Z£ bytes).
diskBlkBuf
a, rO-r2L, r4.
used to hold temporary blocks.
GetPathname works backward from the directory specified by KEYBLKNO,
building out a pathname in the buffer pointed to by PATHBUF. The pathname is
built up in ASCII from right to left. If the actual path is larger than BUFSIZE
bytes, the lowest BUFSIZE characters of the path are placed in the buffer and a
BFR^O VERFLOW error is returned.
C64 & C 128 : CtominodoreGEOS does not support a hierarchical file system.
Example:
See also: GoDirectory, UpDirectory, DownDirectory.
124
GetPattern
GetPattern (Apple)
graphics!
Function:
Parameters:
Returns:
Destroys:
Description:
Example:
See also:
Copy an eight-byte GEOS pattern definition to an application's buffer.
a GEOS system pattern number.
rO pointer to eight-byte destination buffer (word).
rO unchanged.
Pattern data in buffer pointed to by rO
a,y
GetPattern downloads an eight-byte pattern definition from auxiliary high
memory to a buffer defined by the application. This is the only convenient way to
gain access to the system pattern definitions under Apple GEOS. To redefine a fill
pattern, use SetUserPattern.
SetPattern, SetUserPattern.
CONriDCNTIAL
125
GetPtrCurDkNm
GetPtrCurPkNm (Apple, C64, cns)
high-level dlsk|
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Get pointer to the current disk name.
X PTR — zero-page address to place pointer (byte pointer to a word
variable).
curDrive
currendy active drive.
X unchanged.
zero-page word at $00,x {PTR) contains a pointer to the current disk name.
GetPtrCurDkNm returns an address that points to the name of the current disk.
Disk names are stored in the Dr;cCurDkNm variables, where x designates the
drive (A, B, C, or D). If drive A is the current drive then GetPtrCurDkNm
would return the address of DrACurDkNm. If drive B is the current drive then
GetPtrCurDkNm would return the address of DrBCurDkNm. And so on.
Although the locations of the Dr;cCurDkNm buffers are at fixed memory
locations, they are not contiguous in memory. It is easier to call
GetPtrCurDkNm than hardcode the addresses into the application. This will
also ensure upward compatibilty with future versions of GE(DS that might support
more drives.
C64: Versions of GEOS before vl.3 only suport two disk drives and therefore only
have two disk name buffers allocated (DrACurDkNm and DrBCurDkNm).
GEOS vl.3 and later support additional drives C and D. GetPtrDkNm will
return the proper pointer values in any version of GEOS as long as.numDrives
does not exceed the number of disk name buffers. Trying to get a pointer to
DrDCurDkNm under GEOS vl.2 will return an invalid pointer because the
buffer does not exist
C64 & C128: Ctommoodore disk names are always a fixed-length 16 character string. If the
name is less than 16 characters, the string is padded with $aO.
Apple:
Example:
See also:
Apple disk names are null-terminated strings of 16 characters or less (counting the
null-temiinator).
126
GetRandom
IGetRandom (Apple, C64, cus)
uti
mt3
Function:
Parameters:
Uses:
Alters:
Destroys:
Description:
Note:
Creates a 16-bit random number,
none.
random seed for next random number,
random contains a new 16-bit random number,
a
GetRandom produces a new pseudorandom (not truly random) number using
the following linear congmential formula:
random = (2*(random+l) // 65521)
(remember: II is the modulaus operator)
The new random number is always less than 65221 and has a fairly even
distribution between and 65521 .
GEOS calls GetRandom during Interrupt Level processing to automatically keep
the random variable updated. If the application needs a random number more
often than random can be updated by the Kemal, then GetRandom must be
called manually
Example:
127
GetRealSize
GetRealSize (Apple, C64, cus)
Function: Calculate the printed size of a character based on any style attributes.
Parameters: a CHAR — character code of character (byte).
X MODE — style mode (as stored in currentMode).
Uses: curHeight
baselineOffset
Apple;
lastWIdth (if character code is USELAST)
Returns: y character width in pucels (with attributes).
X character height in pixels (with attributes),
a character baseline offset (with attributes).
Destroys: nothing.
Calls: GetCharWidth
Description: GetRealSize calculates the width of the character based any style attributes The
character code must be 32 or greater. If the character code is USELAST, the
value in lastWidth is returned. Any other character code returns the pixel width
as calculated from the font data structure and the MODE parameter.
C64 & C128: lastWidth is local to the GEOS Kemal and therefore inaccessible to applications.
It contains the actual width of the most recendy printed character.
See also: GetCharWidth.
Example:
; Calculate size of largest character in current font
Ida #'W' ; capital W is a good choice
Idx #(SET_BOLD|SET_OUTLINE ; widest style combo
jsr GetRealSize ; dimensions come back in x,y
text
128
GetScanLine
GetScanLine (Apple, C64, cm)
graphics]
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Calculate the memory address of a particular screen line.
X Y — y-coordinate of line.
dispBufferOn:
bit 7 — calculate foreground screen address,
bit 6 — calculate background buffer address.
X unchanged.
addresses in rS and r6 based on dispBufferOn status:
bit 7 bit 6 returns
1
1
rS = foreground; i6 s backKround
1
r5. r6 = background
1
r5. i6 =» foreRTOund
error: r5/6 = address of screen center
a
GetScanLine calculates the address of the first byte of a particular screen line.
The routine always places addresses in both rS and r6, depending on the value in
dispBufferOn. This allows an application to automatically manage both
foreground screen and background buffer writes according to the bits set in
dispBufferOn by merely doing any screen stores twice, indirectly off both rS
and r6 as in:
Note: this code is C64 specific (see notes below for 128 and Apple)
128:
Apple:
Idy
Ida
sta
sta
xpos
grByte
(r5),y
(r6),y
byte index into current line
graphics byte to store
store using both indexes
When GEOS 128 is operating in 80-column mode, all foreground writes are sent
through the VDC chip to its local RAM. In this case, the address of the
foreground screen byte is actually an index into VDC RAM for the particular
scanline. For background writes, the address of the background screen byte is an
absolute address in main memory (be aware, though, that the background screen
is broken into two parts and is not a contiguous chunk of memory).
In 40-column mode, GetScanLine operates as it does under GEOS 64.
Because the Apple double hi-res screen is spread across two memory banks, it is
sometimes necessary to enable or disable a given bank before accessing the
screen. The following subroutine >yill swap in the correct memory bank:
Routine to set correct memory bank in Apple
Pass: a - byte index into line (xpos)
Returns: proper memory bank swapped in
y - corrected index into line
129
GetScanLine
/Destroys: a
• *****1ir********«******«4r****«r*ir ************ *******
SetCorrectPage :
Isr a ;xpos/2; low-bit into carry
tay /return correct index in y
bcs 10$ /Is low-bit set?
St a PAGE2__0N / — >N0: swap in aux. memory
rts / return
10$:
sta PAGE2_0FF / — >YES: swap in main memory
rts / return
Example:
130
GetScreenLi
IGetScreenLine (Apple)
graphics
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
Example:
Copies a byte-aligned horizontal line from the screen, in internal format, to an
application's buffer.
rO DATA — address of buffer to copy data to (word).
rlH XINDX — byte in line to begin with (seven-bit Apple screen byte) (byte).
r2L XWIDTH — width in bytes of line (seven-bit Apple screen bytes) (byte).
rIL Y — y-coordinate of line (byte).
where (XINDX*7,Y) and (XINDX^J-^XWIDTHJ) define the endpoints of the
line.
dispBufferOn:
bit 7 — get data from foreground screen if set
bit 6 — get data from background buffer if set.
If both bits are set, foreground screen is used.
rO address of byte following last byte in line.
a, X, y, rO, rlH
GetScreenLine copies bytes direcdy from the screen memory to the specified
buffer. The screen is treated as a contiguous block of bytes even though, in
actuality, alternate bytes lie in different memory banks.
Bytes are copied into the buffer pointed to by rO beginning at the byte-index into
the line stored in rlH.
No clipping at the screen edge is performed; the values passed are assumed to lie
entirely on one screen line.
131
GetSerialNumber
GetSerialNumber (Apple, C64, ci28) internal
Function: Return the 16-bit serial number or pointer to the serial string for the current GEOS
kemaL
Parameters: none.
Returns: Commodore:
rO 16-bit serial number.
Appig;
rO pointer to serial string.
Destroys: a.
Description: GetSerialNumber gives an application access to an unencrypted copy of the
GEOS serial number or serial string for comparison purposes. You cannot change
the actual serial string or number by altering this copy.
132
GetSpriteData
GetSpritePata (Apple)
sprite!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Copies a 64-byte sprite image from the internal data buffer that is used for
drawing the sprites to the application's memory space.
r3L SPRITE — sprite number (byte).
r4 BUFPTR — pointer to 64-byte buffer (word).
sprite data in buffer pointed to by BUFPTR.
a,y
GetSpriteData is the functional opposite of DrawSprite. It copies 64-bytes of
sprite image data from the internal buffer that is used for drawing the sprites to a
buffer in the application memory space.
In no case should the SPRITE parameter be $00; a value of $00 will return
incorrect data.
The INAUX^B constant may be or'ed into the SPRITE parameter to indicate
that the BUFPTR parameter is an address in auxiliary memory.
DrawSprite, PosSprite, EnablSprite, DisablSprite, InitSprite.
133
GetString
GetString (Apple, C64, ci28)
text/keyboard I
Uses:
Returns:
Destroys:
rlL
r2L
rll
rlH
r4
Function: Get a string from the keyboard using a cursor prompt and echoing characters to
the screen as they are typed Runs concurrently with MainLoop.
Parameters: rO BUFR — pointer to string buffer. When called this buffer can
contain a null-terminated default string (if no default string is used,
the first byte of the buffer must be NULL). This buffer must be at
least MAX C//+1 bytes long.
FLAG — "$00 = use system fault routine; $80 = use fault routine
pointed to by r4 (byte).
MAX.CH — maximum number of characters to accept (not
including the nuU-terminator).
XPOS — x-coordinate to begin input (word).
YPOS — y-coordinate of prompt and upper-left of characters. To
calculate this value based on baseline printing position, subtract the
value in baselineOffset from the baseline printing position (byte).
FAULT — optional (see FLAG) pointer to fault routine,
key Vector STRINGDONE — routine to call when the string is terminated by
the user typing a carriage return. $0000 = no routine provided.
at call to GetString:
curHeight for size of text prompt.
baselineOffset for positioning default string relative to prompt
any variables used by PutString.
while accepting characters:
key Vector vectors off of MainLoop through here with characters.
stringX current prompt x-position.
stringY current prompt y-position.
string pointer to start of string buffer,
any variables used by PutChar.
from call to GetString:
keyVector address of SystemStringService.
stringFaultVec address of fault routine being used
StringX starting prompt x-position.
StringY starting prompt y-position.
string BUFR (pointer to start of string buffer).
when done accepting characters:
X length of string; index to null, relative to address in string,
string BUFR (pointer to start of string buffer).
keyVector $0000
StringFaultVec $0000
at call to GetString:
r0-rl3, a, x, y.
Description: GetString installs a character handling routine into keyVector and returns
immediately to the caller. During MainLoop, the string is built up a character at a
time in a buffer. When die user presses [Return], GEOS calls die STRINGDONE
134
GetString
routine with the starting address of the string in string and the length of the
string in the x-register.
The following is a breakdown of what GetString does:
1: Variables local to the.GetString character input routine are initalized. Global
string input variables such as string, stringX, and stringY are also
initialized.
2: PutString is called to output the default input string stored in tiie character
buffer. If no default input string is desired, the first byte of tiie buffer should
be a NULL.
3: The STRINGDONE parameter in key Vector is saved away and the address
of the GetString character routine (SystemStringService) is put into
keyVector.
4: If tiie application supplied a fault routine, install it into StringFaultVec,
otherwise install a default fauh routine.
5: The prompt is initalized by calling InitTextPrompt with the value in
curHeight. PromptOn is also called.
6: Control is returned to the application.
C64 &C128: String is not null-terminated until tiie user presses [Return]. To simulate a
[Return], use die following code:
/Simulate a CR to end GetString
LoadB keyData,#CR /load up a (Return)
Ida keyVector /and go through keyVector
Idx keyVector+1 /so SystemStringService
jsr CallRoutine /thinks it was pressed
Note that tiiis will also terminate tiie GetString input.
Apple: String is always kept null-terminated.
Note: This note courtesy of Bill Coleman.. .Because GetString runs off of
MainLoop, it is a good idea to call GetString from the top level of the
application code and return to MainLoop while characters are being input. That
is, while at the top level of your code you can call GetString like this:
jsr GetString / Start GetString going
rts / and return immediately to MainLoop so
/ that string can be input.
Since the routine specified by the STRINGDONE value stored in key Vector is
called when the user has finished entering the string, that is where your
application should again take control and process the input.
See also: PutChar, PutString, GetNextChar.
Example:
135
GetVBM
GetVBM (Apple)
mid-level disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Note:
Example:
See also:
Read the first (or only) VBM block into the internal VBM cache,
none.
curDrive
VBMBlknot
block number of first VBM block.
error ($00 = no error).
curVBlkno^
VBMchanged^
numVBMBlkst
block loaded into cache.
set to FALSE; indicates current cache matches disk,
number of VBM blocks.
^used internally by GEOS disk routines; applications generally don't use.
a, y, rl, r4.
GetVBM reads the first block of the VBM (volume bit map) into the internal
VBM cache. This cache is inaccessible to applications but is used indirectly by
routines such as SetNextFree. GetVBM is called automatically by OpenDisk
and ReOpenDisk to get a valid VBM block into the cache. Specialized
applications that switch disks or drives without using OpenDisk or
ReOpenDisk, should call GetVBM to erase any VBM bits from a previous
disk tiiat might be lurking in the cache.
For mon information on Apple GEOS VBM-cacheing, refer to PutVBM.
«
GetVBM ignores the VBMchanged flag. The block is always read in from
disk, overwriting whatever is currendy in the cache.
PutVBM, GetDirHead, PutDirHead.
135
GoDirectory
GoDirectory (Apple)
mid-level disk I
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Go to a specific directory on the disk, making it the current directory.
rO KEYBLKNO — block number of this directory's key block (word).
curDrive
curKBlkno
current directory.
X error ($00 = no error).
y pathname stanis ($00 = OK; BFR^OVERFLOW = pathname longer
than pathnameBuf)-
curKBlkno
curDirHead
pathnameBur
curDirTabLot
curDirTabHit
new current directory,
header of new directory.
system pathname buffer updated to reflect new path,
system directory table
^used internally by GEOS disk routines; applications generally don't use.
a, rOL, rl, r2, r4.
Description: GoDirectory makes the directory at KEYBLKNO the current working directory
so that all operations happen within it .
GoDirectory first changes the current key block number, then calls
GetPathname to build-out the full pathname in pathnameBuf. The current
directory header is read in with a call to GetDirHead
€64 & C128: Commodore GEOS does not support a hierarchical file system.
Example:
See also: UpDirectory, DownDirectory.
136
GotoFirstMenu
IGotoFirstMenu (Apple, C64, cm)
icon/menu
Function:
Retracts all sub-menus and reactivates nienus at the main menu level
Parameters: none-
Destroys: assume r0-rl5, a, x, y
Description:
GotoFirstMenu is used by a menu event handler to instruct GEOS to back up
to the main menu level, erasing the current menu and any parent menus (except
the main menu) from the foreground screen, making the main menu active when
control is returned to MainLoop. menuNumber is set to $00.
GotoFirstMenu can be called from a menu event routine at any menu level,
including main menu level. It operates by checking for level zero and calling
DoPreviousMenu in a loop.
Example:
See Also: DoMenu, DoPreviousMenu, ReDoMenu, RecoverAIlMenus.
137
HideOnlyMouse
HideOnlyMouse (Apple, cns)
mouse/sprite!
Function: Temporarily removes the soft-sprite mouse pointer firom the graphics screen.
Parameters: nothing.
Returns:
Uses:
Alters:
Destroys:
Description:
128:
Apple:
Example:
See also:
nothing.
graphMode
offFIag
offFlag
a, X, y, rl-r6
(128 only).
(Apple only).
set to TRUE (Apple only).
HideOnlyMouse temporarily removes the mouse-pointer soft-sprite. It does not
affect any of the other sprites. This can be used as an alternative to
TempHideMouse when only the mouse pointer need be hidden. The mouse
pointer will remain hidden until die next pass through MainLoop. Any
subsequent calls to TempHideMouse before passing through MainLoop
again will not erase any sprites.
In 40-column mode (when bit 7 of graphMode is zero), HideOnlyMouse
exits immediately without affecting the hardware sprites. Also, be aware that any
subsequent GEOS graphic operation will hide any visible sprites by calling
TempHideMouse, so this routine is not especially usefuU if using GEOS
graphics routines.
This routine sets offFlag to TRUE which will stop TempHideMouse from
erasing any sprites until the soft-sprite handling code in MainLoop is
encountered. In some cases this causes problems with graphic operations that
occur off of MainLoop before this code is executed. The easiest solution to this
problem is to avoid using HideOnlyMouse and use TempHideMouse with
noEraseSprites set to TRUE. offFlag can, instead, be set to $40 if die
application wants the GEOS Interrupt Level to redraw the mouse before the
application returns to MainLoop.
TempHideMouse.
140
HorizontalLine
IHorizontalLine (Apple, C64, cns)
graphics!
Function:
Parameters:
Uses:
Returns:
Destroys:
Draw a horizontal line with a repeating bit-pattern.
a PATTERN —eight-bit repeating pattern to use (not a GEOS pattern
number),
r3 XI — x-coordinate of leftmost endpoint (word).
r4 X2 — x-coordinate of rightmost endpoint (woid).
rllL Yl — y-coordinate of line (byte).
where (XI, Yl) cind (Xljl) define the endpoints of the horizontal line.
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
nothing
Commodore
a, X, y, r5-r8, rllH
Apple
a, X, y, rllH
Description: HorizontalLine sets and clears pixels on a single horizontal line according to
the eight-bit repeating pattern. Wherever a 1-bit occurs in the pattern byte, a pixel
is set, and wherever a 0-bit occurs, a pixel is cleared
Bits in'the pattern byte are used left-to-right where bit 7 is at the left .A bit pattern
of % 1 1 1 100(X) would create a horizontal line like:
Note:
128:
Example:
See also:.
The pattern byte is always drawn as if aligned to a card boundary. If the
endpoints of a line do not coincide with card boundaries, then bits are masked off
the appropriate ends. The effect of this is that a pattern is always aligned to
specific pixels, regardless of the endpoints, and that adjacent lines drawn in the
same pattern will align.
To draw patterned horizontal lines using the 8x8 GEOS patterns, draw rectangles
of one-pixel height by calling the GEOS Rectangle routine with identical y-
coordinates.
Under GEOS 128, or'ing DOUBLE W into theXi andX2 parameters will
automatically double the x-posiuon in ^-column mode. Or'ing in ADDl^W will
automatically add 1 to a doubled x-position. (Refer to "GEOS 128 X-posiBon and
Bitmap Doubling" in Chapter.® gr@ for more information.)
VerticalLine, InvertLine, ImprintLine, RecoverLine, DrawLine.
141
Printline
ImprintLine (Apple)
graphics!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Imprints a horizontal line fix)m the foreground screen to the background buffer.
r3 XI — x-coordinate of leftmost endpoint (word).
r4 X2 — x-coordinate of rightmost endpoint (word),
r 1 1 L Y 1 — y-coordinate of line (byte).
where (XI, Yl) and (X2,Y1) define the endpoints of the line to imprint.
nothing
a, X, y
ImprintLine imprints the pixels which fall on the horizontal line whose
coordinates are passed in the GEOS registers. The pixel values are copied from
the foreground screen to the background buffer.
The flags in dispBufferOn are ignored; the pixels are always copied to the
background buffer regardless of the value in this variable.
This routine does not exist in GEOS 64 or GEOS 128. Use ImprintRectangle
with a height of one.
RecoverLine, HorizontalLine, InvertLine,VerticalLine , DrawLine.
142
ImprintRectangle
ImprintRectangle^ i ImprintRectangle (Apple, C64, cns) graphics]
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
128:
Example:
See also:
Imprints the pixels within a rectangular region from the foreground screen to the
background buffer.
Normal:
r3 XI — x-coordinate of upper-left (word).
r2L Yl — y-coordinate of upper-left (byte)-
r4 X2 — x-coordinate of lower-right (word),
r 2 H Y2 — y-coordinate of lower-right (byte).
Inline:
data appears immediately after the jsr i_ImprintRectangle
.byte Yl y-coordinate of upper-left.
.byte Y2 y-coordinate of lower-right,
.word XI x-coordinate of upper-left,
.word X2 x-coordinate of lower-right.
where (XI, Yl) is the upper-left corner of the rectangular area and (X2,Y2) is the
lower-right corner.
nothing
CpmrnodQi?
a, X, y, r5-r8, rllL
Apple
a, x,y, rllL
ImprintRectangle copies the pixels within a rectangular region from the
foreground screen to the background buffer by calling ImprintLine in a loop. A
subsequent call to RecoverRectangle with the same parameters will restore the
rectangle to the foreground screen.
The flags in dispBufferOn are ignored; the pixels are always copied to the
background buffer regaixlless of the value in this variable.
Under GEOS 128, or'ing DOUBLE W into the XI andX2 parameters will
automatically double the x-position in SD-column oKxie. Or'ing in ADDl^W will
automatically add 1 to a doubled x-position. (Refer to "GEOS 128 X-posinon and
Bitmap Doubling" in Chapter.® gr@ for more information.)
RecoverRectangle, Rectangle, InvertRectangle.
143
InfoCard
InfoCard (Apple) card driver
Function: Get information about the cuirent printer card-
Parameters: none.
Returns: x STATUS — card error code; $00 = no error (byte)
y TYPE;
b7
0: seven-bit data card.
1: eight-bit datacard.
b6
0: serial interface card.
1: parallel interface card.
b5
0: card only capable of output
1 : card capable of input and output.
b4
0: does not support StatusCard ready-for-output flag.
1: supports StatusCard ready-for-output flaj?.
b3
0: does not support StatusCard input-ready flag.
1: supports StatusCard input-ready flag.
Destroys: a.
Description: InfoCard returns information about the installed card.
Note: This routine may be called at any time.
Example:
See also: StatusCard.
144
InitCa
InitCard (Apple) card driver}
Function: Initialize printer card-
Parameters: rO-rlL SERIALCONFIG — card configuration information for serial I/O cards;
parallel cards do not use this information (three bytes).
Returns: x STATUS — card error code; $00 = no error (byte)
Destroys: assume a, y.
Description: InitCard performs the basic initialization and configuration of a printer card. A
printer driver will usually perform this operation from InitForPrint. InitCard
configures the printer card with a three-byte set of CONFIG parameters.
The COA/F/G Values:
Most Apple printer cards use die standard 65xx series 6551 ACIA (Asynchronous
Communications Interface Adapter) to communicate between the Apple bus and
the printer. The CONFIG bits directly reflect the available configurations for this
chip. Bits mauriced as unused are either unused on the chip or forced to a specific
state by the card driver. For more information, refer to the RM 65 Family
Asynchronous Communications Interface Adapter (ACIA) Module User's Manual
(Rockwell International).
rOL: control register.
bits description
b7
0:
one stop bit.
1:
1-1/2 stop bits with five data bits and no parity.
one stop bit with eight data bits and parity.
two stop bits in all other cases.
b6-b5
00:
8 data bits.
01:
7 data bits.
10:
6 data bits.
11:
S data bits.
b4
mused.
b3-bO
0000
undefined.
0001
SO baud.
0010
75 baud.
0011
109.92 (110) baud.
0100
134.56 (135) baud.
0101
150 baud.
Olio
300 baud.
0111
600 baud.
1000
1200 baud.
1001
1800 baud.
1010
: 2400baud.
1011
: 3600baud.
1100
: 4800 baud.
1101
: 7200 baud.
1110
: 9600 baud.
nil
: 19200 baud (19.2 Kbaud).
rOH: command register.
145
tCard
bits
description
b7-b6
00
01
10
11
odd parity,
even parity,
marie pari^.
space parity.
b5
1
parity disabled (no parity, ignore b7-b6).
parity enabled.
b4-b0
undefined.
handshaking,
bits description
b7
1
do not check for XOFF.
detect XOFF. wait for XON.
b6-b5
00
11
ignore hardware handshaking,
follow hardware handshaking.
M
must be 1.
b3-bO
must be 000
Most serial printers operate with eight data bits, no parity, and one stop bit Some
printers, like the Apple LaserWriter require two stop bits.
Note : InitCard must be called before OpenCard.
Example:
See also: OpenCard.
148
InltForDial
InitForPialOg (Apple) intcmall
Function: Saves away the state of GEOS as if about to pass control to a dialog box.
Parameters: none.
Returns: system initialized to a near-wamistart state.
Destroys: a,x, y, r0-r4
Description: Prior to displaying a dialog box, DoDIgBox saves away the state of the
application in an internal buffer and then reinitializes GEOS so that the dialog box
runs as if it were an independent application. This allows a dialog box to use
nearly all the facilities of GEOS without disrupting the parent application. This
facility for temporarily suspending the state of GEOS is potentially useful in an
application and can be accessed by calling InitForDialog.
InitForDialog saves off the current system state and then places GEOS in a
near-warmstart state. To return GEOS to its previous state, call
RecoverSysRam.
Note: Calls to InitForDialog cannot be nested because GEOS can only buffer its state
to a depth of one level. A second call to InitForDialog without calling
RecoverSysRam will overwrite the saved state of the system with the current
state. Because DoDIgBox calls InitForDialog as part of its normal operation,
it, too, will overwrite the saved state of the system.
See also: RecoverSysRam.
CONriDCNTlAL
149
InltForlO
InitForlO (C64, ci28)
very low>level disk
Function:
Prepare for I/O across the serial bus-
Parameters:
none.
Returns:
nothing.
Destroys: a, y.
Description: InitForlO prepares the system to perform I/O across the Commodore serial bus.
It disables interrupts, turns sprite DMA off, slows the 128 down to IMhz,
switches in the ROM and I/O banks if necessary, and performs anything other
initialization needai for fast serial transfer.
Call InitForlO before directly accessing the serial port (e.g., in a printer driver)
or before using ReadBIock, WriteBIock, VerWriteBIock, or ReadLink.
To restore the system to its previous state, call DoneWithlO.
Apple:
Apple GEOS has no InitForlO equivalent
Example:
See WriteBIock.
See also:
DoneWithlO, SetDevice.
142
InitForPrInt
InitForPrint (Apple, C64, cns)
Initialize printer. Perform once per document
none.
Commodore
nothing.
Apple
X STATUS — printer error code; $00 = no error.
Commodore
assume a, x, y, r0-rl5.
Applg
assume a, y, r0-rl5.
InitForPrint performs any initialization necessary to prepare the printer for a
GEOS document. Often this involves resetting the printer to bring it into a default
state as well as suppressing automatic margins and perforation skipping.
InitForPrint does not do any initialization specific to graphic or ASCII printing.
Commodore: InitForPrint is also used to set the printer baud rate for serial printers.
Apple: Some printer drivers may try to send a non-printing character to the printer to
ensure that it is ready to accept data. If the printer is not ready, InitForPrint will
return a PR TIME_OUT error. This usually means the printer is switched off
or is not online: Many printer drivers, however, will do no such checking and
have no facility for detecting a printer time-out
See also: StartPrint, StartASCII.
150
printer driver
Function:
Parameters:
Returns:
Destroys:
Description:
InitMouse
InitMoUSe (Apple, C64, C128)
input driver
Function:
Parameters: none.
Returns: nothing
Alters:
Initialize the input device.
Destroys:
Description:
See also:
mouseXPos initialized (typically 8).
mouse YPos initialized (typically 8).
mouseData initialized (typically reflects a released button).
pressFlag initialized (typically set to $00).
assume a, x, y, r0-rl5
GEOS calls InitMouse after first loading an input driver. The input driver is
expected to initialize itself and begin tracking the input device. An application
should never need to call InitMouse.
SlowMouse, UpdateMouse, SetMouse, KeyFilter, StartMouseMode,
MouseUp.
151
InitProcesses
InitProcesses (Apple, C64, cns)
process
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Initialize and install a process data structure.
a NUM_PROC — number of processes in table (byte).
rO PTABLE — pointer to process data structure to use (word).
rO unchanged.
a, X, y, rl
InitProcesses installs and initializes a process data structure. All processes
begin as frozen, so their timers are not decremented during vblank. Processes can
be started individually with RestartProcess after the caU to InitProcesses.
InitProcesses copies the process data structure into an internal area of memory
hidden from the application. GEOS maintains the processes within this intemd
area, keeping track of the event routijie addresses, the timer initialization values
(used to reload the timers after they time-out), the<:urrent value of the timer, and
the state of each process (i.e., frozen, blocked, runable). The application's copy
of the process data structure is no longer needed because GEOS remembers this
information until a subsequent call to InitProcesses.
Although processes are numbered starting with zero, NUMJPROC should be die
actual number of processes in the table. To initialize a process table with four
processes, pass a NUMJPROC value of $04. When refering to those processes
(i.e., when calling routines such as UnblockProcess), use tiie values $00-$03.
Do not call InitProcesses with a NUM PROC value of $00 or a NUMJPROC
value greater than MAX_PROCESSES (the maximum number of processes
allowable). "
To disable process handling, merely freeze all processes or call InitProcesses
with a dummy process data structure.
Sleep, RestartProcess.
152
InitRa
InitRam (Apple, C64, C128) memory
Function : Table driven initialization for variable space and other memory areas.
Parameters: rO TABLE — address of initialization table (word).
Returns: nothing.
Destroys: a, x,y, rO-r2L
Description: InitRam uses a table of data to initialize blocks of memory to preset values. It is
useful for setting groups of variables to specific values. It is especially good at
initializing a group of noncontiguous variables in a "two bytes here, three bytes
there" fashion.
The initialization table that is pointed to by the TABLE parameter is a data
structure made up from the following repeating pattern:
• word addzBss ; start address of this block
.byte count ;nuxnber of bytes to initialize
•byte bytel, byte2fJbytGi^ ; count bytes of data
•word Address^. ; start address for next block
The table is made of blocks that follow the above pattern, count bytes starting at
address are initialized with the next count bytes in the table. (A count value of $00
is treated as 256.) To end the table, use
.word $0000 ;end table
where InitRam expects the next address parameter.
Note : Do not use InitRam to initalize rO-r2L.
Example:
See also: FillRam, ClearRam.
153
InltTextPrompt
InitSprite (Apple)
sprite!
Function:
Parameters:
Returns:
Alters:
Destroys:
Initializes all sprites.
nothing.
nothing.
offFIag set to TRUE.
noEraseSprites set to $00.
all mouse and sprite parameters set to $00.
a, X
Ml
Description: InitSprite is called by the GEOS Kemal during the boot and warmstart
sequences. It is probably not useful to applications.
See also: DrawSprite, GetSpriteData, PosSprite, EnablSprite, DisablSprite.
InitTextPrompt (Apple, C64, cus)
text/keyboard
Function:
Parameters:
Alters:
Destroys:
Description;
See also:
Example:
Initialize sprite #1 for use as a text prompt.
a HEIGHT — pixel height for the prompt (byte)
alphaFlag %10000011
a, X, y.
InitTextPrompt initializes sprite #1 for use as a text prompt. The sprite image is
defined as a one-pixel wide vertical line of HEIGHT pixth. If HEIGHT is large
enough, the double-height sprite flags will be set as necessary. HEIGHT is
usually taken from curHeight so that it reflects the height of the current font.
The text prompt will adopt the color of the nx)use pointer.
PromptOn, PromptOff.
154
InputByte
InputByte (Apple)
card driver!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Get a byte of input from the interface card,
none.
X
y
a,y.
STATUS — card error code; $00 = no error (byte)
DATA — single input byte as read from card.
InputByte returns a byte of data from the card, assuming the card supports two-
way communication. The input-ready flag may be checked with StatusCard
prior to calling InputByte.
InputByte must be called after an OpenCard and before a CloseCard.
Most card drivers always return NO^ERROR from from InputByte due to a
lack of memory to properly handle coinplex error checking.
OutputByte, StatusCard.
155
InsertRecord
InsertRecord (Apple, C64, cus)
VLIR disk
Function: Adds an empty record before the current record in the index table, moving all
subsequent records (including the current record) downward
Parameters: none
Uses:
Returns:
Alters:
Destroys:
Description:
Example:
See also:
curDrive
fileWrittent
curRecord
fileHeader
Commodore:
curType
curDirHead
dir2Headt
dir3Headt
Apple;
curVBlknot
VBMchanged^
numVBMBlkst
if FALSE, assumes record just opened (or updated) and
reads B ANVVBM into memory.
current record pointer
VLIR index table stored in this buffer.
GEOS 64 vl.3 and later for detecting REU shadowing,
current directory header/B AM.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
curRecord new lecord becomes the current record.
flleWritten^ set to TRUE to indicate the file has been altered since last
updated.
fileHeader new record added to index table.
^used internally by GEOS disk routines: explications generally don't use.
a, y. rOL.
InsertRecord attempts to insert an empty VLIR record in front of the current
record in the index table of an open VLIR file, moving all subsequent records
downward in the record Ust. The new record becomes the current record. A VLIR
file can have a maximum of MAX VLIR RECS records. If adding a record
will exceed this value, an OUT^OP^RECORDS error is returned. In the index
table, the new record is marked as useS but empty.
InsertRecord does not update the VLIR file information on disk. Call
CloseRecordFile or UpdateRecordFile to update the file when done
modifying.
AppendRecord, DeleteRecord.
143
interruptMain
InterruptMain (Apple, C64, cns)
Function: Main Interrupt Level processing.
Parameters: none.
Returns: nothing.
Destroys: a, x, y, r0-rl5
Description: InterruptMain is the main GEOS Interrupt Level processing loop and that
means different things on different systems.
C64 & C128: InterruptMain is a subset of the full Interrupt Level process. InterruptMain is
typically called through the IntTopVec. An application could conceivably
jsr InterruptMain to "catch up" on some system updating if interrupts have
been disabled for a considerable period of time. InterruptMain is not re-entrant,
so it is important that interrupts be disabled around the catch-up calls.
Apple: InterruptMain is cuirendy the same as IrqMiddle. It is best to use IrqMiddle
to generate software interrupts because the Apple GEOS InterruptMain may
change in the future to more closely reflect the operation under the Commodore
environment At this time, avoid this jump table entry.
See also: IrqMiddle, MainLoop.
internal
156
InvertLine
InvertLine (Apple, C64, cm)
graphics!
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
128:
Example:
See also:
Invert the pixels on a horizontal line.
r3 XI — x-coordinate of leftmost endpoint (word).
r4 X2 — x-coordinate of rightmost endpoint (woid).
rllL Yl — y-coordinate of line (byte).
where (Xl,Yl)and (X2,Y1) define the endpoints of the line to invert.
dispBufferOn:
bit 7 — invert foreground screen if set
bit 6 — invert background screen if set.
nothing
Commodore
a, X, y, r5-r8
Applg
a, X, y
InvertLine inverts the pixel state of all pixels which fall on the horizontal line
whose coordinates are passed in the GEOS registers. Set pixels become clear, and
clear pixels become set.
If dispBufferOn is set to invert on the foreground and the background screen,
both the foreground and the background screen will get the inverted foreground
pixels. GEOS assumes both screens contain the same image.
Under GEOS 128, or'ing DOUBLE W into theXi andX2 parameters will
automatically double the x-position in SD-column mode. Or*ing in ADDl W will
automatically add 1 to a doubled x-position. (Refer to "GEOS 128 X-posi5on and
Bitmap Doubling" in Chapter.® gr@ for more information.)
VerticalLine, HorizontalLine, ImprintLine, RecoverLine, DrawLine.
157
InvertRectangle
InvertRectangle (Apple, C64, ci28)
graphics!
Function:
Parameters:
Inverts the pixels within a rectangular region.
r3 XI — x-coordinate of upper-left (word).
r2L Y 1 — y-coordinate of upper-left (byte).
r4 X2 — x-coordinate of lower-right (word).
r2 H Y2 — y-coordinate of lower-right (byte).
where (XI, Yl ) is the upper-left corner of the rectangular area and (X2,Y2) is the
lower-right corner.
Uses : dispBufferOn:
bit 7 — invert on foreground screen if set.
bit 6 — invert on background screen if set
Returns: nothing
Destroys: Commodore
a, X, y, r5-r8, rllH
Applg
a, X, y, rllH
Description: InvertRectangle inverts all the pixels within the rectangular area as determined
by the coordinates of the upper-left and lower-right comers. All set pixels become
clear and clear clear pixels become set
InvertRectangle operates by calling InvertLine in a loop.
InvertRectangle is handy to use for indicating a selected object (as GEOS does
with icons) or for flashing an area by inverting a rectangle twice, first inverting
the area and then mverting it back to its original state.
Note: If dispBufferOn is set to invert on the foreground and the background screen,
both the foreground and the background screen will get the inverted foreground
pixels. GEOS assumes both screens contain the same image.
128: Under GEOS 128, or'ing DOUBLE W into theX/ andX2 parameters will
automatically double die x-position in SD-column mode. Or'ing in ADDl W will
automatically add 1 to a doubled x-position. (Refer to "GEOS 128 X-posi"Hon and
Bitmap Doubling" in Chapter.® gr@ for more information.)
Example:
See also: Rectangle, ImprintRectangle, RecoverRectangle, FrameRectangle.
158
IrqMiddle
IrqMiddle (Apple)
internall
Function: Interrupt Level processing.
Parameters: none.
Returns:
Destroys:
Description:
Example:
See also:
nothing,
a, X, y
IrqMiddle is the software-interrupts entry into the Apple GEOS Kemal. When
there is no hardware interrupt source, GEOS generates software interrups by
calling IrqMiddle. In most cases, as long as the application returns to
MainLoop frequently enough, the system degradation will only be minor.
However, applications which do massive anaounts of processing before returning
to MainLoop may need to generate software interrupts periodically.
bit
bne
php
sei
jsr
pip
intSource
10$
IrqMiddle
; check interrupt source
;do nothing if hard interrupts
;else, disable interrupts
;(just in case) because int
;code is not. re-entrant
/software interrupt now!
; restore old interrupt status
10$:
InterruptMain.
159
IsMselnRegion
IsMselnRegion (Apple, C64, ci28)
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
NewIsMselnRegion :
5$:
10$:
Ida
mouseYPos
cmp
r2L
bit
10$
cmp
r2H
bgt
10$
php
sei
cmpW
mouseXPos, r3
bit
5$
cmpW
mouseXPos, r4
bgt
5$
pip
Ida
#TRUE
rts
pip
Ida
#FALSE
rts
mouse
;get mouse y-position
/compare to top edge
/branch if outside
/compare to bottom edge
/branch if outside
/disable interrupts around x check
/so it doesn't change while we're looking
/compare mousex with left edge
/branch if outside
/compare mousex with right edge
/branch if outside
/ (restore interrupts before se.tting st reg)
/return inside region statys
/exit
/ (restore interrupts before setting st reg)
/return outside region status
/exit
Checks to see if the mouse is within a specified rectangular region of the screen.
r3 XI — x-coordinate of upper-left (word),
r2L Yl — y-coordinate of upper-left (byte).
r4 X2 — x-c(X)rdinate of lower-right (word).
r2H Y2 — y-coordinate of lower-right (byte).
where (XI, Yl ) is the upper-left corner of the rectangle and (X2,Y2) is the lower-
right corner.
a TRUE if in region, FALSE if not in region.
st result of loading TRUE or FALSE into the a register.
nothing.
IsMselnRegion tests the position of the mouse against the boundaries of a
rectangular region (passed in the same GEOS registers as the Rectangle
routine). It returns TRUE if the mouse is within the region (inclusive) and
FALSE if the mouse is outside the region. Because the st register reflects the
result of loading TRUE or FALSE into the accumulator, the call can be
followed by a branch instruction that tests the result, such as:
beq InRegion /branch if mouse was in region
-or-
bne Not InRegion /branch if mouse not in region
Interrupts should always be disabled around a call to IsMselnRegion. If the
php-sei-pip method is used, be aware that the pip will reset the st flags. If this
is troublesome, it may warrant creating a new version of IsMselnRegion that
does its own interrupt disable and leaves the values in the st register intact:
160
IsMseinRegi
Example:
LoadW
LoadW
LoadW
LoadW
php
sei
jsr
pip
tax
beq
r3, #windowXl
r2L,#windowYl
r4,#windowX2
r2H, #windowY2
IsMselnRegion
;get coordinates of window's rectangle
/disable interrupts around region check
/check for mouse inside region
;set status flags that pip killed
MouseOutsideWindow /branch if outside window area
161
JsrToAux
JsrToAux (Apple only)
utility
Function:
Parameters:
Returns:
Destroys:
Description:
Example:
See also:
jsr*s to a subroutine in auxiliary memory. Returns to main memory.
a [AUXADDR — low byte of subroutine to call in aux. memory.
X ] AUXADDR — high byte of subroutine to call in aux memory.
where AUXADDR is the address of a subroutine to call in aux. memory
depends on the subroutine.
depends on the subroutine.
JsrToAux performs a jsr to a subroutine in application auxiliary memory.
GEOS will first switch application aux in and application main out, then simulate
a jsr to the address passed in x and a. When the aux memory subroutine returns,
control will resume in main memory. JsrToAux does not check for a null
($0000) address like CallRoutine.
CallRoutine
162
KeyFilter
IKeyFilter (Apple)
input driver
Function:
Parameters:
Returns:
Alters:
Uses:
Destroys:
Description:
Note:
Pre-processes keyboard input for filtering out special characters, translating
others, and updating the mouse variables when positioning keys are pressed.
a
a
KEY — key as scanned from keyboard circuitry,
translated character or NULL if filtering out
mouseXPos
mouseYPos
mouseData
pressFIag
inputData
mouse x-position.
mouse y-position.
state of mouse button.
MOUSE^BIT and INPUT^^BIT set appropriately,
depends on device. "
OPEN^APPLE read-only hardware location; negative if open-apple pressed
assume x, y
The Apple GEOS keyboard scanning routine calls KeyFilter at Interrupt Level
whenever a keypress is detected. This allows the input driver to translate certain
keypresses into mouse movements. KeyFilter has first dibs on any incoming
keypress.
A typical KeyFilter routine will compare the KEY parameter against a table of
specific keypresses. If there is no match, then KeyFilter returns without altering
the KEY ccxie. If there is a match, KeyFilter updates the mouse variables
appropriately and returns a KEY value of NULL. Apple GEOS will ignore the
null-key, never placing it in the keyboard input queue.
IfKEY is already NULL when KeyFilter is called, then the keypress has
already been filtered out by some other prior filter and should be ignored.
An application should not call KeyFilter direcdy; Apple GEOS will call it
automatically at Interrupt Level.
The KEY parameter is not a GEOS key value. It comes almost direcdy from the
Apple hardware register KEYBD^DATA. The only difference is tiiat the high-
bit is set to represent the state oflhe closed-apple key. If bit 7 is set, then the
closed-apple key is pressed. To detect die state of the open-apple key:
bit
bmi
OPEN_APPLE
OpenPressed
/check open apple key status
/branch if pressed
See also: AuxDKeyFilter.
163
LdApplic
LdApplic (Apple, C64, C128)
mid-level disk I
Function:
Parameters:
Uses:
Returns:
Passes:
Alters:
Destroys:
Description:
Load and (optionally) run a GEOS application, passing it the standard application
startup flags as if was launched from the deskTop.
r9 DIRENTRY — pointer to directory entry of file, usually points to
dirEntryBuf (Apple GEOS: must be in main memory) (word).
rOL LOAD.OPT:
bitO: load at address specified in file header; application will be
started automatic^y
load at address in r7; application will not be started
automatically,
not passing a data file.
r2 and r3 contain pointers to disk and data file names,
not printing data file,
printing data file; application should print file and exit
r7 LOAD_ADDR — optional load address, only used if bit of
LO AD jOPT is set (word).
r2 DATA^DISK— only validif bit7orbit6ofL<9i4D_0/Tis setrpointer
to name of the disk that contains the data file, usually a pointer to one of
the DrxCurDkNm buffers (word).
r3 DATA^FELE — only valid if bit 7 or bit 6 of LOAD jOPT is set: pointer
to name of the data file (word).
bit 7:
bit 6:
1
1
curDrive
Commodore:
curType
Applg:
RWbank
GEOS 64 V 1.3 and later: for detecting REU shadowing.
destination bank (MAIN or AUX); set to MAIN when
loading an application.
only returns if alternate load address or disk error.
X error ($00 = no error).
usually doesn't return, but warmstarts GEOS and passes the following:
rO as originally passed to LdApplic.
r2 as originally passed to LdApplic (use dataDiskName).
r3 as originally passed to LdApplic.(use dataFileName).
GEOS brought to a warmstart state.
dataDiskName contains name of data disk if bit 7 of rO is set.
dataFileName contains name of data file if bit 6 of rO is set
a, X, y, r0-rl5.
LdApplic is a mid-level application loading routine called by the higher level
GetFile. Given a directory entry of a GEOS application file, LdApplic will
attempt load it into memory and optionally run it. LdApplic calls LdFile to load
the application into memory: a sequential file is loaded entirely into memory but
164
LdApplic
only record zero of a VLIR file is loaded. Based on the status of bit of
LOADJDPT, optionally runs the application by calling it through StartAppl.
Most applications will not call LdApplic directly but will go indirectly through
GetFile.
Note: Only in extremely odd cases will an alternate load address be specified for an
application. Loading an application at another location is not particularly useful
because it will most likely not run at an address other than its specifiec load
address. When LdApplic returns to the caller, it does so before calling
StartAppl to wamistart GEOS.
Apple: Applications are designed to load and run in main memory. Ensure that RWbank
contains MAIN before calling LdApplic.
Example:
See also: GetFile, LdDeskAcc, LdDeskAcc, StartAppl.
J
165
LdDeskAcc
LdPeskAcC (Apple, C64, C128)
mid-level disk
Function: Load and run a .GEOS desk accessory
Parameters: r9
rlOL
DIRENTRY — pointer to directory entry of file, usually points to
dirEntryBuf (word).
RECVR^OPTS — no longer used; set to $00 (sec below for explanation
(byte).
Uses:
curDrive
Cpmrnodpr?;
curType
Apple;
RWbank
GEOS 64 vl.3 and later: for detecting REU shadowing.
destination bank (MAIN or AUX); set to MAIN when
loading a desk accessory.
Returns:
Passes:
Alters:
returns when desk accessory exits with a call to RstrAppl.
X error ($00 = no error).
warmstarts GEOS and passes the following to the desk accessory:
rlOL as originally passed to LdDeskAcc (should be $(X); see below).
nothing direcdy; desk accessory may alter some buffers that arc not saved
Destroys: a, x, y, r0-rl5.
Description:
Note:
LdDeskAcc is a mid-level desk accessory loading routine called by the higher
level GetFile. Given a directory entry of a GEOS desk accessory file,
LdDeskAcc will attempt load it into memory and run it. When the user closes
the desk accessory, control returns to die calling application.
LdDeskAcc first loads in the desk accessory's file header to get the start and
ending load address. Under GEOS 64 and Apple GEOS, it will then save out the
area of memory between these two addresses to a file on the current disk named
SWAP FILE. The GEOS 128 version saves this area to the 24K desk
accessory swap area in back RAM. Desk accessories larger than 24K cannot be
used under GEOS 128 (to date, there are none); a BFR^OVERFLOW error is
returned.
After saving the overlay area, the dialog box and desk accessory save-variables
are copied to a special area of memory, the current stack pointer is remembered,
and the desk accessory is loaded and executed. When the desk accessory calls
RstrAppl to return to the application, this whole process is reversed to return the
system to a state similar to the one it was in before the desk accessory was called.
The SWAP FILE file is deleted.
Most applications will not call LdDeskAcc directly, but will go indirectly
tiirough GetFile.
The RECVRjOPTS flag originally carried die following significance:
166
LdDeskAcc
C64 :
Apple:
Example:
See also:
bit 7: 1 force desk acxessory to save foreground screen area and restore it on return to
application.
not necessary for desk accessory to save foreground.
Commodore only:
bit 6: 1 force desk accessory to save color memory and restore it on return to
application.
notnecessary for desk accessory to save color memory.
However, it was found that the extra code necessary to make desk accessories
save the foreground screen and color memory provided no real benefit because
this context save can just as easily be accomplished finom within the application
itself. The RECVRjOPTS flag is set to $00 by all Berkeley Softworks
applications, and desk accessories can safely assume that this will always be the
case. (In fact, future versions of GEOS may force rlOH to $00 before calling
desk accessories just to enforce this standard!)
The application should always set rlOH to $00 and bear the burden of saving and
restoring the foreground screen and the color memory. (Color memory only
applicable to GEOS 64 and GEOS 128 in 40-column mode.)
GEOS versions 1.3 and above have a new GEOS file type called
TEMPORARY. When the deskTop first opens a disk, it deletes all files of this
type. The SWAP FILE is a TEMPORARY file.
Desk accessories are designed to load into main memory. Ensure that RWbank
contains MAIN before calling LdApplic.
GetFile, LdApplic, LdFile, RstrAppI, InitForDialog, RstrFrmDialog,
WarmStart.
167
LdFile (Apple, C64, C128)
mid-level disk!
Function:
Parameters:
Uses:
bitO:
Given a directory entry, loads a sequential file or record zero of a VLIR record.
r9 DIRENTRY — pointer to directory entry of file, usually points to
dirEntryBuf (Apple GEOS: must be in main memory) (word).
curDrive
Commodore!
curType
A pp l g;
RWbank
loadOptt
1
loadAddr^
GEOS 64 vl.3 and later for detecting REU shadowing.
destination bank (MAE^ or AUX).
load option:
-load at address specified in file header,
-load at address in loadAddr.
alternate load address.
Returns:
Alters:
^former local variable; applications will generally not use outside of this context.
X error ($00 = no error).
r7 pointer to last byte read into BUFFER plus one.
fileHeader
Cpmmodprp;
fileTrScTab
contains 256-byte GEOS file header. (This is a 512-byte
buffer in Apple GEOS, although only 256 bytes are used in
the GEOS file header for compatibility).
track/secto^ of header in first two bytes of this table
(fileTrScTab+O and fileTrScTab+l); As the file is
loaded, the track/sector pointer to each block is added to die
file track/sector table starting at fiIeTrScTab+2 and
fiIeTrScTab+3.
Destroys:
Apple:
INDEXBLOCKBUF
Apple;
a, y, rl, r4, r7.
index block for file if sequential or record if VLIR
(in auxiliary memory; see ReadFile for information
on accessing this buffer).
Description: LdFile is a mid-level file handling routine called by die higher level GetFile.
Given a directory entry of a sequential file, LdFile will load it into memory.
Given die directory entry of a VLIR file, LdFile will load its record zero into
memory.
Most applications will not call LdFile directiy but will access this routine
indirectiy tiirough GetFile.
168
LdFiie
C64 &C128: All versions of LdFiie to date under Commodore GEOS are unusable because
the load variables that are global under Apple GEOS GoadOpt and loadAddr)
are local to the Kemal and inaccessible to applications. Fortunately this is not a
problem because applications can always go through GetFile to achieve the same
effect
Example:
See also: GetFile, LdApplic, LdDeskAcc, ToB ASIC.
^
169
LoadAuxSet
LoadAuxSet (Apple)
text
Function:
Parameters:
Returns:
Alters:
Begin using a new font that resides in ausiliaiy memory.
rO FONTPTR — aux. memory address of font header
rO unchanged
curHeight
baselineOffset
cardDataPntr
curlndexTable
curSetWidth
height of font
number of pixels ftom top of font to baseline,
pointer to current font image data,
pointer to current font index table,
pixel width of font bitstream in bytes.
Destroys: a, x, y
Description:
Example:
See also:
LoadAuxSet operates cxacdy like LoadCharSet except that it lets the font data
reside in auxiliaiy memory.
LoadCharSet, UseSystemFont.
170
LoadCharSet
LoadCharSet (Apple, C64, cns)
text
Function:
Parameters:
Returns:
Alters:
Begin using a new font.
Destroys:
Description:
Apple:
Example:
See also:
rO
rO
FONTPTR — address of font header. If Apple, address must be in main
memory (word).
curHeight
baselineOffset
cardDataPntr
curlndexTable
curSetWidth
a.y.
unchanged
height of font
number of pixels fiiom top of font to baseline,
pointer to current font image data,
pointer to current font index table,
pixel width of font bitstrcam in bytes.
LoadCharSet uses the data in the character set data structure to initalize the font
variables for the font pointed at by the FONTPTR parameter.
If the font data is stored in auxiliary memory, LoadAuxSet must be used.
LoadAuxSet, UseSystemFont.
171
MainLoop
MainLoop (Apple, C64, cus)
internal I
Function: Direct entiy into the GEOS MainLoop..
Parameters: nothing.
Returns: n/a
Destroys: n/a
Description: Although the term "MainLoop" usually refers to GEOS MainLoop Level
processing, it also represents an entry in the GEOS jump table. By performing a
jmp MainLoop, the application would be returning to the top of the MainLoop
Level without letting it run through its normal course of events. The application is
expected to return to MainLoop Level with an rts, not with a call to MainLoop.
Hence, this jump table entry is not terribly useful to applications and is primarily
used internally by GEOS.
The MainLoop jump table entry is perhaps useful when debugging. The system
could, conceivably, be returned to a "known state" by resetting the stack pointer
and executing a jmp MainLoop. Of course, there is no guarantee that this will
work.
Example:
See also:
Idx t$ff ; reset stack pointer
txs
jmp Mainloop ;try to get back to normal..,
InterruptMain, Firstlnit.
172
MakeSubDIr
MakeSubPir (Apple)
high-level disk
Function:
Parameters:
Creates a subdirectory within the current directory.
rO
DIRNAME — pointer to null-terminated name for directory, maximum
of 16-characters including the null terminator (word).
rlOL DIRPAGE — directory page to begin searching for free slot; each
directory page holds eight files and corresponds to one notepad page on
the GEOS deskTop. The first page is page one (byte).
Uses:
Returns:
Alters:
Destroys:
Description:
curDrive
curKBlkno
current directory.
X error ($00 = no error).
rlOL directory page actually used
r6 block number of key block of new directory.
dirEntryBuf
diskBlkBuf
a, y, r3-r8.
contains newly-built directory entry,
contains directory header just written.
MakeSubDir creates an empty subdirectory in the current directory. Care must
be taken not to create two subdirectories with the same name as MakeSubDir
does not prevent this from happening.
MakeSubDir first calls SetNextFree to allocate the subdirectory's key block
then calls SetGDirEntry to build its directory entry, adding it to the current
directory. MakeSubDir then builds a directory header in diskBlkBuf and
writes it out to the newly-allocated key block.
MakeSubDir Hushes the VBM cache.
€64 & C128: Comnxxiore GEOS does not support a hierarchical file system.
Example:
See also: SetGDirEntry, DeleteDir.
173
MouseOff
MoUSeOff (Apple, C64, C128)
mouse/spritel
Function:
Parameters:
Returns:
Modifies:
Destroys:
Description:
Example:
See also:
Temporarily disables the mouse pointer and GEOS mouse tracking,
nothing.
nothing.
mobenble
mouseOn
a
sprite #0 bit cleared by DisablSprite.
clears the MOUSEON BIT.
MouseOff temporarily disables the mouse cursor and GEOS mouse tracking by
clearing the proper bit in mouseOn and calling DisablSprite. Applications can
call MouseOff temporarily disable the mouse. The mouse can be reenabled to its
previous state by calling MouseUp.
MouseOff» ClearMouseMode.
CONriDCNTIAL
174
MouseUp
MoUSeUp (Apple, C64, C128)
mouse/spritel
Function:
Parameters:
Returns:
Modifies:
Destroys:
Description:
Example:
See also:
Reenables the mouse pointer and GEOS mouse tracking.
nothing.
nothing.
mobenble
mouseOn
a
sets enable bit for sprite #0
sets the MOUSEON BIT.
MouseUp reenables the mouse cursor and GEOS mouse tracking after a call to
MouseOff by setting the proper bits in mouseOn and mobenble.
StartMouseMode calls this routine.
MouseOff, StartMouseMode.
175
MoveAuxData (Apple)
memoryl
Function:
Parameters:
Special version of MoveData that will move data within either main or auxiliary
memory (or from one bank to the other).
rO
rl
r2
a
SOURCE — address of source block in application memory (word).
DEST — address of destination block in application memory (word).
COUNT — number of bytes to move, - 32K (word).
BANKS — which banks to use, based on the following bit fields:
b7 b6 Description
SOURCE and DEST both in main memory.
1
SOURCE in main memory. DEST in auxiliary memory.
1
SOURCE in auxiliary memory, DEST in main memory.
1
1
SOURCE and DEST both in auxiliary memory.
Returns: rO, rl, r2 unchanged.
Destroys: a, x, y
Description:
Note:
Example:
See also:
MoveAuxData (formerly Apple MoveBData) is a block move routine that
allows data to be moved in either main memory, auxiliary memory, or between
main and auxiliary. Like MoveData, it will move up to 32K (32,768 bytes) from
one area of memory to another and the source and destination blocks can overlap.
The move is actually a copy in die sense that the source data remains unalter^
unless the destination area is in the same bank and overlaps the source.
MoveAuxData is especially useful for copying data from main memory to
auxiliary memory or from auxiliary memory to main memory.
«
MoveAuxData should only be used to move data within the application space in
main and auxiliary memory. This area lies in the 48K block affected by RAMRD
andRAMWRT.
MoveData, MoveBData, SwapMainAndAux.
Mov a AuxDota
MOVeBData (CnS) memory
Function: Special version of MoveData that will move data within either front RAM or
back RAM (or from one bank to the other).
Parameters: rO SOURCE — address of source block in application memory (word).
r 1 DEST — address of destination block in application memory (word).
r2 COUNT — number of bytes to move (word).
r3L SRCB ANK — source bank: = back RAM; 1 = front RAM (byte).
r3H DSTBANK — destination bank: = back RAM; 1 = front RAM (byte).
Returns: r0-r3 unchanged.
Destroys: a, x, y
Description: MoveBData is a block move routine that allows data to be moved in either front
RAM, back RAM, or between front and back (bank 1, the front bank, is the
normal GEOS application area). If the SOURCE and DEST areas are in the same
bank and overlap, DEST. must be less than SOURCE.
MoveBData is especially useful for copying data from front RAM to back RAM
or from back RAM to front RAM.
MoveBData uses the DoBOp primitive by calling it with a MODE parameter of
$00.
Note: MoveBData should only be used to move data within the designated application
areas of memory. MoveBData is signifcantiy slower than MoveData and
should be avoided if the move will occur entirely within front RAM.
Example:
See also:
MoveData, MoveAuxData, SwapBData, VerifyBData, DoBOp.
MoveData
MovePata^ i MovePata (Apple, C64, ci28)
memory I
Function:
Parameters:
Returns:
Destroys:
Description:
64 & 128:
64:
128:
Apple:
Moves a block data from one area to another
Normal:
rO SOURCE — address of source block (word),
r 1 DEST — address of destination block (word).
r2 COUNT — number of bytes to move (word).
Inline:
data appears immediately after the jsr i MoveData
.word SOURCE
.word DEST
.word COUNT
rO, rl, r2 unchanged.
a,y
MoveData will move data from one area of memory to another. The source and
destination blocks can overlap in either direction, which makes this routine ideal
for scrolling, insertion sorts, and odier applications that need to move arbitrarily
large areas of memory around. The move is actually a copy in the sense that the
source data remains unaltered unless the destination area overlaps it
If the DMA MoveData option in the Configure program is enabled (GEOS vl.3
and later), MoveData will use part of bank of the installed RAM-expansion
unit for an ultrafast move operation. An application that calls MoveData in the
normal manner will automatically take advantage of this selection. An application
that relies upon a slower MoveData (for timing or other reasons) can disable the
DMA-move by temporarily clearing bit 7 of sysRAMFlg. This bit can also be
used to read the status of the DMA-move configuration.
Due to insufficent error checking in GEOS, do not attempt to move more than
30,976 ($7900) bytes at one time when the DMA-move option is enabled. Break
the move up into multiple calls to MoveData.
Due to insufficent error checking in GEOS, do not attempt to move more than
14,592 ($3900) bytes at one time when the DMA-move option is enabled. Break
the move up into multiple calls to MoveData. MoveData should only be used
to move data within the standard front RAM application space. Use MoveBData
to move memory witiiin back RAM or between front RAM and back RAM.
Because the RAM-expansion unit DMA follows the VIC chip bank select, an
application that is displaying a 40-column screen ft'om back RAM must either
disable DMA-moves or temporarily switch die VIC chip to front RAM before the
MoveData call.
MoveData should only be used to move data within application main memory.
See MoveAuxData for moving data within aux main memory or between
memory banks.
Note:
Do not use MoveData on rOHr6.
178
MoveData
Example:
See also: MoveAuxData, MoveBData, CopyString.
179
NewBltClip
NewBitClip (Apple)
graphics
Function:
Parameters:
A special version of BitmapCIip which allows bitmaps of pixel-widths and
pixel-coordinate x-positioning.
Uses:
Returns:
Destroys:
Description:
Note:
Example:
See also:
rO
r3
rlH
r2
rlL
rllL
rllH
rl2
DATA — pointer to the compacted bitmap data (word).
X — x-position in pixels (word).
Y — y-coordinate (byte).
W_PWE)TH — width in pixels of clipping window (word),
W_HEIGHT — height in pixels of clipping window (byte).
DXl — delta-xl: offset of left edge of clipping window in bytes from left
edge of full bitmap (byte).
DX2 — delta-x2: offset of right edge of clipping window in cards from
right edge of full bitmap (byte). Right pixel-edge of clipping window
rounded upward to the next card boundary.
DYl — delta-y 1: offset of top edge of clipping window in pixels from top
edge of full bitmap (word).
where the upper-left corner of the clipped bitmap (the window) is placed at
(X,Y). The lower-right corner is at (X-^WJ'WIDTH, Y-^WJJEIGHT).
dispBufferOn:
bit? — write to foreground screen if set
bit 6 — write to background screen if set
nothing.
a, X, y, r0-rl2
e
NewBitClip is an enhanced version of BitmapCIip which allows the left edge
of the bitmap to be placed on a pixel boundary and the bitmap to have a pixel-
sized width. It is odierwise identical to BitmapCIip.
No checks are made to determine if the data, dimensions, or positions are valid.
Be careful to pass accurate values.
Pay special attention to the fact that DXl, and DX2 are still specified in cards
(groups of eight pixels horizontally), not in individual pixels.
Do not pass a value of $00 for either the W^PWIDTH or W^HEIGHT
parameters.
DOUBLE B can be or'ed into the W^WIDTH paramter to double the bitmap
width andlNAUX^B can be or'ed into the X parameter to specify auxiliary
memory. For morelnformation, refer to "Apple GEOS Bitmap Doubling and
Aux-memory Bitmaps" in chapter @gn@.
NewBitOtherCIip, BitmapCIip, BitmapUp, BitOtherClip.
180
NewBitOtherClip
NewBitOtherClip (Apple)
graphics!
Function:
Parameters:
Uses:
Returns:
Special version of NewBitCIip that allows the compacted bitmap data to come
from a source other than memory (e.g., from disk).
r BUFFER — pointer to a 1 34-byte buffer area (word).
r3 X — x-position in pixels (word).
rlH Y — y-coordinate (byte).
r2 W^PWIDTH — width in pixels of clipping window (word).
rlL W^HEIGHT — height in pixels of clipping window (byte).
rllL DXl — delta-xl: offset of left edge of clipping window in bytes from left
edge of full bitmap (byte).
rllH DX2 — delta-x2: offset of right edge of clipping window in cards from
right edge of full bitmap (byte). Right pixel-edge of clipping window
rounded upward to the next card boundary,
r 1 2 D Y 1 — delta-y 1 : offset of top edge of clipping window in pixels from top
edge of full bitmap (word).
rl3 APPINPUT — pointer to application-defined input routine. Called each
time a byte from a compacted bitmap is needed; data byte is returned in the
a-register.
rl4 SYNC — pointer to synchronization routine. Called after each bitmap
packet is decompressed. Due to improvements in NewBitOtherClip,
this routine need only consist of reloading rO with the BUFFER address.
where the upper-left corner of the clipped bitmap (the window) is placed at
PC,Y). The lower-right corner is at (X^WJ'WIDTH, Y+WJIEIGHT).
dispBufferOn:
bit? — write to foreground screen if set.
bit 6 — write to background screen if set
nothing.
Destroys: a, x, y, r0-rl2, and the 134-byte buffer pased through rO.
Description:
Sometimes the application will need to display a large bitmap but cannot afford to
store the entire bitmapped object in memory. NewBitOtherClip allows the
application to specify an input routine (APPINPUT) thai returns the next byte of a
compacted bitmap each time it is called
APPINPUT must preserve r0-rl3, it must return die data byte in die a-register,
and it is expected to exit widi an rts. A typical APPINPUT routine might save
r0-rl3, call ReadByte to get a byte from a disk file, restore r0-rl3, load die
data byte into die accumulator, and rts. Note tiiat BitOtherCIipt can be used to
add another level of compression to the compacted bitmap format. The
APPINPUT routine can decompress die data into compacted bitmap format and
pass those bytes back.
The basic widtii, height, position, and clipping window parameters are identical
to NewBitCIip. Refer to the documentation of that routine for more
information.
181
NewBitOtherCllp
NewBitOtherClip calls the APPINPUT routine until it has enough bytes to
form one bitmap packet. BitOtherCIip stores the bytes in the buffer pointed by
BUFFER and then uncompacts the data to the screen. After the bitmap packet has
been uncompacted, BitOtherCIip calls the SYNC routine. This extra call is no
longer particularyAiseful and can merely consist of reloading rO with the
BUFFER address and performing an rts.
Note: DOUBLE^B can be or'ed into the W^WIDTH parameter to double the bitmap
width. "
Before resetting rO when, the SYNC routine must switch in the alternate zero
page:
SYNC:
sta ALTZP_ON ; switch in alt zp
MoveW syncrO,rO ; reload rO
sta ALTZP_OFF ; switch alt zp back out
rts /return from sync
Example:
See also: BitOtherCIip, NewBitClip» BitmapClip, BitmapUp, BitOtherCIip.
182
NewBitOtheFCli p (
NewBitUp, i NewBitUp (Apple) graph»cs|
Function: A special version of BitmapUp that allows bitmaps of pixel-widths and pixel-
coordinate x-positioning.
Parameters: Normal:
rO DATA — pointer to the compacted bitmap data (word).
r3 X — x-coordinate (word).
rlH Y — y-coordinate (byte).
r2 WIDTH — bitmap width in pixels (word).
rlL HEIGHT — bitmap height in pixels (byte).
Inline:
data appears immediately after the jsr i_BmapUp
.word DATA pointer to the compacted bitmap data.
.word X x-coordinate.
.byte Y y-coordinate.
.word WIDTH bitmap width in pixels.
.byte HEIGHT bitmap height in pixels.
Uses: dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
Returns: nothing.
Destroys: a, x, y, r0-r4
Description: NewBitUp uncompacts a GEOS compacted bitmap using the width and height
information and places it at the specified screen position. No checks are made to
determine if the data, dimensions, or positions are valid, and bitmaps which
exceed the screen edge will not be clipped. Be careful to pass accurate values.
NewBitUp differs from BitmapUp in that it allows bitmaps to be of a pixel-
width and to be placed at any pixel postion on the x-axis. The data is still
compacted in card-size (eight-pixel) chunks, but when placed on the screen any
extra pixels (bits) at the right edge are ignored.
Note: Neitiier die WIDTH nor die HEIGHT parameter should be $(X).
DOUBLE B can be or'ed into die WIDTH paramter to double the bitmap width
and INAUX_B can be or'ed into the XI parameter to specify auxiliary memory.
For more information, refer to "Apple GEOS Bitmap Doubling and Aux-memory
Bitmaps" in chapter @gr@.
Example:
See also: BitmapUp, NewBitCIip, NewBitOtherClip.
NewDisk
NewDisk (C64, cns)
mid-level disk
Function:
Parameters: none
Uses:
Returns:
Destroys:
Description:
Note:
Apple:
Example:
See also:
Tell the turbo software that a new disk has been inserted into the drive.
curDrive
curType
drive that disk is in.
GEOS 64 vl.3 and later:
memory is cleared).
for disk shadowing (shadow
error ($00 = no error).
a, y, r0-r3.
NewDisk informs the disk drive turbo software that a new disk has been
inserted into the drive. It first calls EnterTurbo then sends an initialize command
to the turbo code. If the disk is shadowed, the shadow memory is also cleared
NewDisk gets called automatically when.OpenDlsk opens a new disk. An
application that does not deal with anything but the low-level disk routines might
want to call NewDisk instead of OpenDisk to avoid the unnecessary overhead
associated with reading the directory header and initializing internal file-level
variables.
NewDisk has no effect on a RAMdisk. Also, some early versions of the 1541
turbo code leave the disk in the drive spinning after is first loaded. A call to
NewDisk during the application's initialization wiU stop the disk.
Apple GEOS has no NewDisk equivalent
OpenDisk, SetDevice.
184
NextRecord
NextRecord (Apple, C64, cns)
VLIR disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Makes the next record the current record,
none.
flleHeader index table checked to establish whether record exists.
X error ($00 = no error).
y if no error, then a value of $00 here means record is empty,
a new current record number.
Commodore:
rl track/sector of first data block in record.
Appig;
rl block number of record's index block.
curRecord
nothing.
new record number.
Example:
See also:
NextRecord makes the current record plus one the new current record. A
subsequent call to ReadRecord or WriteRecord will operate with this record.
If the record does not exist, then NextRecord returns an INV RECORD
(invalid record) em)r. "
PointRecord, PreviousRecord.
185
NormalizeX
NormalizeX (Ci28)
graphics!
Function: Adjust an x-coordinate to compensate for the higher-resolution 80-column nKxie.
Parameters: x GEOSREG — zero-page address of word-length GEOS register which
contains the word-length X-coordinate to adjust..
Returns: x unchanged.
register passed as GEOSREG parameter contains the adjusted x-coordinate.
Destroys: a
Description:
NormalizeX is used by nearly every GEOS 128 routine that writes to the
screen. It adjusts an x-coordinate (two's complement signed word) based on the
graphics mode (40- or 80-column) and the status of the special bits in the
coordinate. NormalizeX allows an application to run in botii 40- and 80-column
modes with a minimum of programming effort If the proper bits in a 40-column
coordinate is set, NormalizeX will automatically double the value when in 80-
column mode.
Since GEOS graphics operations automatically call NormalizeX to adjust the
coordinates, most applications will not need to call it direcdy.
Bit 15 of the coordinate specifies doubling. Bit 13 adds one to a doubled
coordinate (allowing odd-pixel addressing). Bit 12 is a pseudo-sign bit. Use the
DOUBLE^W and ADD1_W constants to access tiiese bits.
If die coordinate might be negative, the DOUBLE_W and ADDl^W constants
should be exclusive-or'ed into the x-position so""that the sign Ts preserved.
However, if die coordinate is guaranteed to be a positive numl^r, the constants
may simply be or'ed in.
The GEOSREG parameter is an actual zero-page address. Usually this will be a
GEOS register (r0-rl5) or an application's register (a0-al5). If, for example, an
application had a value in r9 which it wanted normalized, it would first exclusive-
or in the special bits, then call NormalizeX in the following manner:
Idx
jsr
#r9 ;load x with addr of r9
NormalizeX /normalize the val in r9
The following breakdown of the word-length x-coordinate illustrates how the
special bits affect the adjustment process.
15 14 13 12 11
I bl5 |bl4|bi7T
10
x-pixel coordinate (b0-bl2)
]
b0-bl2 x-coordinate in pixels (two's comp. number).
bl3 add one to doubled x-coordinatc (flag).
bl4 x-coordinate sign-extension from bl2 (pseudo sign-bit).
b 15 double x-coordinate (flag).
186
NormallzeX
If in 40-column mode, then the special bits arc ignored and the x-coordinatc is
returned to its original state (the state it was in before any special constants were
exclusive-or'ed in).
If in 80-column mode, then the following applies:
bl5
bl4
bl3
Effect
6
n
X value unchanged (nomial positive).
1
1
n
X value unchanged (normal negative).
1
n
X = x*2hi (doubled negative).
1
n
X = x*2+n (doubled positive).
Note:
Example:
For more information, refer to "GEOS 128 X-position and Bitmap Doubling" in
Chapter @gr@.
187
NxtBlkAiloc
NxtB Ik Alloc (Apple, C64, C128)
mid-level disk
Function: Special version of BlkAIIoc that begins allocating from a specific block on the
disk.
Parameters: r2
Uses:
Returns:
Alters:
BYTES — number of bytes to allocate space for (word). Commodore
version can allocate up to 32,258 bytes (127 Commodore blocks);
Apple version can allocate up to 65,536 bytes (128 ProDOS blocks).
Commodore:
r3L START^TR — start allocating from this track (byte).
r3H START^SC — start allocating from this sector (byte).
r6 TSTABLE — pointer to buffer for building out track and sector table of
the newly allocated blocks, usually a position within fileTrScTab
(word).
Apple;
r3 START3LK— start allocating from tiiis block (word).
curDrive
Commodore:
curDirHead
dir2Headt
dir3Headt
interleave^
Apple;
curVBlkno^
VBMchangedt
numVBMBlkst
this buffer must contain the current directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
desired physical sector interleave (usually 8); used by
setNextFree. Applications need not set this explicidy —
will be set automatically by internal GEOS routines.
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; explications generally don't use.
X error ($00 = no eiror).
r2 number of blocks allocated to hold BYTES amount of data.
Commodore:
r3L track of last allocated block.
r3H sector of last allocated block.
Apple;
r3
last block allocated
Commodore:
curDirHead
dir2Headt
dir3Headt
BAM updated to reflect newly allocated blocks.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
188
NxtBlkAlloc
curVBIknot used by VBM cacheing routines.
VBMchangedt set to TRUE by VBM cacheing routines to indicate cached
VBM block has changed and needs to be flushed
^used internally by GEOS disk routines; applications generally don't use.
Destroys: Commodore:
a, y, r4-r8.
Apple:
a, y, r4, r6, r7, rSH,
Description: NxtBlkAlloc begins allocating blocks from a speciflc block on the disk,
allowing a chain of blocks to be appended to a previous chain while still
maintaining the sector interleave. NxtBlkAlloc is essentially a special version of
BlkAlIoc that starts allocating blocks from an arbitrary block on the disk rather
than from a fixed block. NxtBlkAlloc is otherwise identical to BlkAlIoc.
C64 & C128: The Commodore version of NxtBlkAlloc for appending more blocks to a list of
blocks just allocated with BlkAlIoc, thus circumventing the 32,258-byte barrier.
Point TSTABLE at the last entry in a track/sector table (the terminator bytes which
we can overwrite), load the BYTES parameter with the number of bytes left, and
call NxtBlkAlloc. The START TR and START^SC parameters in r3L and
r3H will contain the correct values on return from BlkAlIoc. NxtBlkAlloc
will allocate enough additional blocks to hold BYTES amount of data, appending
them in the track/sector table automatically. This combined list of track and
sectors can then be passed directiy to WriteFile to write data to the full chain of
blocks.
NxtBlkAlloc does not automatically write out the BAM. See PutDirHead for
more information on writing out the BAM. Also, the START 7R parameter
should not be track number of the directory track. Refer to GetFreeDirBlk for
more information on allocating blocks on the directory track.
Apple: The Apple version of NxtBlkAlloc builds out a list of allocated blocks in the
internal indexBIock buffer just as if BlkAlIoc had been called: it starts filling
up the table from the beginning, overwriting any block pointers that may abready
be there. The only difference between BlkAlIoc and NxtBlkAlloc is that
BlkAlIoc forces SetNextFree to start searching for free blocks beginning at
the block following the VBM, whereas NxtBlkAlloc instructs it to stan
searching from the START JBLK block. NxtBlkAlloc could be used to append
blocks to an existing file or record, but the application would need to manually
append the new block pointers (built-out in indexBIock) to the end of the
original index block. For this reason, the Apple GEOS version of NxtBlkAlloc
is not especially useful.
NxtBlkAlloc does not automatically flush the VBM cache. Sec PutVBM for
nx)re information on flushing the cache.
Note: For more information on the scheme used to allocate successive blocks, refer to
SetNextFree.
J Example:
189
NxtBlkAlloc
See also: BIk Alloc, SetNextFree, AIIocateBlock, FreeBlock.
190
OpenCard
OpenCard (Apple)
card driver
Function:
Open printer card for access.
Parameters: none.
Returns:
X
STATUS — card error code; $00 = no eiror (byte)
Destroys: assume a, y.
Description: OpenCard opens access to the printer carcL The printer driver calls this routine
to switch in the printer card's ROMs. This operation may be necessary before
each block of data because another card's ROMs may be enabled (thQ disk
controller ROMs, for example).
The printer driver sends blocks of data to the printer between calls to OpenCard
and CloseCard.
Note:
Do not call OpenCard without having called InitCard.
Example:
See also:
InitCard, CloseCard.
191
OpenDisk
OpenPisk (Apple, C64, cns)
high>levcl disk]
Function:
Parameters:
Uses:
Returns:
Alters:
Open the disk in the cunent drive
Destroys:
none
curDrive
Commodore:
driveType
drive that disk is in.
type of drive to open (for shadowing information).
X error ($00 = no error).
r5 pointer to disk name buffer as returned from GetPtrCurDkNm. This
is a pointer to one of the Dr;cCurDkNm arrays.
DracCurDkNm
curDirHead
Commodore;
isGEOS
dir2Headt
dir3Headt
driveType
Apple;
sysDirBlkno
curKBlkno
totNumBIkst
pathnameBuft
curVBlknot
numVBMBIkst
VBMchangedt
curDirTabLo
curDirTabHi
current disk name array contains disk name,
current directory header.
set to TRUE if disk is a GEOS disk, otherwise set to
FALSE.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
block number of /SYSTEM directory. If system directory
not found on disk, then this number is same as
curKBlkno.
block number of root directory's key block,
total number of blocks in volume,
reset to root directory.
block currendy cached in VOLUMEBITMAP
number of VBM blocks on disk,
set to FALSE,
set to root directory,
set to root directory.
Description:
^used internally by GEOS disk routines; applications generally don't use.
CommQdor;>;
a, y» r0-r4.
Applg;
a, y, rl, r4.
OpenDisk initiates access to the disk in Ae current drive. OpenDisk is meant to
be caUed after a new disk has been inserted into the disk drive. It prepares the
drive and disk variables for deaUng with a new disk. An application will usually
call OpenDisk immediately after calling SetDevice.
192
OpenDisk
Note: Because GEOS uses the same allocation and file buffers for each drive, it is
important to close all files and update the BAMA^BM if necessary (use
PutDirHead or PutVBM, respectively) before accessing another disk.
C64 & C128: OpenDisk first calls NewDisk to tell the disk drive a new disk has been
inserted (if the disk is shadowed, the shadow memory is also cleared).
GetDirHead is then called to load the disk's header block and BAM into
curDirHead. With a valid header block in memory, ChkDkGEOS is called to
check for the GEOS I.D. string and set the isGEOS flag to TRUE if the disk is
a GEOS disk. Finally, OpenDisk copies the disk name string from
curDirHead to the disk name buffer returned by GetPtrCurDkNm.
Apple: Apple GEOS OpenDisk resets the path to the root directory, then reads the disk
header into the curDirHead array. The volume disk name is copied from this
buffer into the disk name buffer returned by GetPtrCurDkNm. This disk name
is also used to build out the initial pathname in pathnames uf (the inital
pathname is a slash 7" character followed by Ae null-terminated disk name.).
OpenDisk also initializes the VBM cache and its associated variables, computing
the total number of VBM blocks and reading the first block into the cache. The
flag VBMchanged is set to FALSE to indicate tiiat the cached VBM block in
memory matches its copy on the disk. When all this is done, OpenDisk searches
the root directory for the /SYSTEM directory (using FndFillnDir) and stores
the resulting block number into sysDirBlkno.
Example:
See also: ReOpenDisk, SetDevice, NewDisk.
193
nRecordFlle
OpenRecordFile (Apple, C64, cns)
VLIR disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Open an existing VUR file for access.
rO FILENAME — pointer to null-terminated name of file (word).
curDrive
CpmrncKlQi?;
curType
Apple:
curKBlkno
GEOS 64 vL3 and later for detecting REU shadowing.
current directory.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
rl block number (Commodore track/sector) of directory block containing
entry.
rS pointer into diskBlkBuf to start of directory entry.
fileHeader
usedRecords
cur Record
fileWrittent
fileSize
dirEntryBuf
Apple;
fileBytes
buffer contains VLIR index table.
number of records in file that are currendy in use.
current record set to 1 by default or -1 ($ff) if there are no
records in the file.
set to FALSE to indicate VLIR file has not been written to.
total number of disk blocks used in file (includes index
block, GEOS file header, and all records),
directory entry of VLIR file.
total number of bytes in file (as picked up from last from
bytes 254, 255, 511, and 512 of the master index block.
^used internally by GEOS disk routines: applications generally don't use.
a, y, rl, r4-r6.
Before accessing the data in a VLIR file, an application must call
OpenRecordFile. OpenRecordFile searches the current directory for
FILENAME and, if it finds it, loads the index table into fileHeader.
OpenRecordFile initalizcs the GEOS VLIR variables (both local and global) to
allow other VLIR routines such as WriteRecord and ReadRecord to access
the file. Only one VLIR file may be open at a time. A previously opened VLIR
file should be closed before opening another.
If an application passes a FILENAME of a non-VLIR file, OpenRecordFile
will renim a STRUCT^MISMATCH error.
Note:
An application can create an empty VLIR file with SaveFile.
194
OpenRecordFile
C64 & C128: Since Commcxiorc GEOS does not support a Mcrarchical fUe system, the "cu^
directory" is actually the entire disk.
Apple: Once a VLIR file is opened, the current directory may be changed without
affecting access to the file because the index information is kept in fileHeader.
Example:
See also: CIoseRecordFile, UpdateRecordFile.
195
OutputByte
OutputByte (Apple)
card driver I
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Put a byte of output data to the interface canL
y DATA — single ouput byte to send to card (byte)
X STATUS — card error code; $00 = no error (byte)
a, y.
OutputByte sends a byte of data to the card. The ready-for-output flag may be
checked with StatusCard prior to calling OutputByte.
OutputByte must be called after an OpenCard and before a CloseCard.
Most card drivers always return NO_ERROR from from OutputByte due to a
lack of memory to properly handle complex error checking.
InputByte, StatusCard.
196
Panic
Panic (Apple, C64, C128)
internal I
Function:
Parameters:
Display "system error" dialog box.
Apple &C»f;
top word on stack is the system error address+2.
top eight bytes on stack are unused, next word on stack is the system error
address+2
Returns:
Description:
Example:
Never returns.
Panic puts up a system error dialog box. It is usually not called directly by an
application. Usually the global GEOS variable BRKVector will contain the
address of this routine When GEOS encounters a brk (opcode: $00) instruction
in memory, it jumps indirecdy through BRKVector with system-specific status
values on die stack. This usually results in a system error dialog box. The hex
address in the dialog box is the address of the offending brk instruction.
An application that patches into BRKVector processes brk instructions on its
own may need to simulate the normal GEOS course of events by performing a
jmp Panic.
Although this is not a typical use, an application can use Panic as a means of
communicating fatal error messages. This may be useful in a beta-test version of a
software product, for example.
FatalError :
use Panic to send a fatal error message to the user
Pass:
rO
Error number
See also:
FatalError:
IncW
IncW
rO
rO
.if (C64 I I APPLE)
PushW rO
.else; (C128)
Idx #5-1
10$:
PushW rO
dex
bne 10$
.endif
jmp Panic
DoDlgBox.
;add 2 to error number
;to compensate for Panic
; apple & c64 only expect an address
;push error number onto stack
;128, however, expects all kinds of internal
; machine-state information (10 bytes total) on the
; stack. It ignores all but the bottomost word.
;place 5 words (10 bytes) total onto stack
;push error number onto stack
; (use error number repeatedly as dummy value)
;loop until all done.
•go put up the panic dialog box
CONnBEhO'lAL
197
1 <J
PointRecord (Apple, C64, ci28)
VLIR disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Make a particular recoijd the current record
a RECORD — ^ record number to make current (byte).
fileHeader index table checked to establish whether record exists.
X error ($00 = no error).
y if no error, then a value of $00 here means record is allocated but not in
use (has no data blocks),
a new current record number.
Commodore:
rl $0000
$ff00
other
Applg;
rl $0000
$ffff
other
curRecord
record is not allocated
record is allocated but not in use (has no data blocks); this
information is already flaged in y.
track/sector of first data block in record
record is not allocated
record is allocated but not in use (has no data blocks); this
information is already flaged in y.
block number of the index block that corresponds to the
record (Apple).
new record number.
nothing.
PointRecord makes RECORD the current record so that a subsequent call to
ReadRecord or WriteRecord will operate with RECORD. VLIR records are
numberd zero tiirough MAX_VLIR_RECS-1.
If the record does not exist (you pass a record number that is larger tiian the
number of currently used records), then PointRecord returns an
INV RECORD (invalid record) error.
Example:
See also: NextRecord, PreviousRecord.
PosSprite
PosSprite (Apple, C64, C128)
spritej
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
C64:
C128:
Apple:
Example:
See also:
Positions a sprite at a new GEOS (x,y) coordinate.
r3L SPRITE — sprite number (byte).
r4 XPOS — x-position of sprite (word).
rSL YPOS — y-position of sprite (byte).
nothing.
mobNxpos
msbNxpos
reqXposN
mobnypos
(64 and 128 only) sprite x-position (lower 8-bits)
(64 and 128 only) sprite x-position (bit 9).
(Apple only) sprite x-position.
(all versions)
where N is the number of the sprite being positioned.
a, X, y, r6
PosSprite positions a sprite using GEOS coordinates (not C64 hardware sprite
coordinates). PosSprite does not affect the enabled/disabled status of a sprite, it
only changes the cuirent position.
Although there are eight sprites available, an application should only directiy
position sprites #2 through #7 with PosSprite. Sprite #0 (the mouse pointer)
should not be repositioned (except, maybe through mouseXPos and
mouse YPos), and sprite #1 (the text cursor) should only be repositioned witii
stringX and stringY.
The positions are translated to C64 hardware coordinates and then stuffed into the
VIC chip's sprite positioning registers. The C64 hardware immediately redraws
the sprite at die new position.
The positions are translated to C64 hardware coordinates and then stuffed into the
VIC chip's sprite positioning registers. This data is used by the VIC chip in 40-
column mode and by the soft-sprite handler in 80-column mode. In 80-column
mode, the sprite is not visually updated until the next time the soft-sprite handler
gets control.
The y-position is stuffed, unaltered, into mobnypos (simulated hardware
register), and the x-position is stuffed, unaltered, into reqXposn. The sprite is
not visually updated until the next time the soft-sprite handler gets control.
DrawSprite, GetSpriteData, EnablSprite, DisablSprite, InitSprite.
199
PreviousRecord
PreviousRecord (Apple, C64, cm)
VLIR disk
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Makes the previous record the current record,
none*
fileHeader index table checked to establish whether record exists.
X error ($00 = no error).
y if no error, then a value of $00 here means record is empty,
a new current record number.
CpmrnQ^ore;
r 1 track/sector of first data block in record
Apple;
rl block number of record's index block.
curRecord
nothing.
new record number.
Example:
See also:
PreviousRecord makes die current record minus one the new current record. A
subsequent call to ReadRecord or WriteRecord will operate with this record.
If the record does not exist, then PreviousRecord returns an INV RECORD
(invalid record) error.
PointRecord, NextRecord.
200
PrintASCIi
Print ASCII (Apple, C64, C128)
printer driver |
Function:
Parameters:
Uses:
Send ASCn string to the printer.
rO PRINTDATA — pointer to null-terminated ASCII string (word).
rl WORKBUF — pointer to a 640-byte work buffer for use by the printer
driver (word). This is the same buffer that was established in
StartASCn and must stay intact throughout the entire page.
Apple
rO
PRINTDATA — pointer to null-terminated ASCII string (word).
Apple
RWbank
the memory bank that the PRINTDATA buffer is in. Valid
settings aie MAIN and AUX.
Cpmm«I(?rp
nothing.
Apple
X STATUS — printer error code; $00 = no error.
Commodore
assume a, x, y, r0-rl5.
Apple
assume a, y, rl-r4.
«
Description: PrintASCIi sends a null-terminated ASCII string to the prinier. The application
must call StartASCII before sending ASCII data to the printer with
PrintASCIi. It is the job of the application to keep track of the number of
possible lines per page and call StopPrint to formfeed when necessary (or
desired).
In order to begin printing on the next line, the string must contain a CR character
to signify a carriage return. A NULL character marks the end of the string.
C64 & C128: The data passed in PRINTDATA is in regular ASCII format (not Conmiodore
ASCII), The text is printed using the printer's standard character set. Some
printer drivers allow switching the printer into high-quality print mode with
SetNLQ. Commodore GEOS printer drivers are set to print 80 characters per
line and 66 lines per page.
The data passed in PRINTDATA is in regular ASCII format. The text is printed
using the printer's standard character set unless some other option has been
selected with the SetMode conmiand. The page width and height can be
determined with GetMode. Because a new line is not staned until a CR
character is encountered an NULL can be inserted mid-string. When
PrintASCIi encounters it and returns, the application can call SetMode to
change the modes mid-line.
Returns:
Destroys:
Apple:
PrintASCII
Example:
See also: PrintASCII, StartPrlnt, StopPrint, InitForPrint.
202
PrintBuffer (Apple, C64, cns)
PrintBuffer
printer driver
Function: Print one cardrow (eight lines) of graphics data.
Parameters: Commodore
rO PRINTDATA — pointer to 640 bytes of graphic data in Commodore
card format (8x8 pixel blocks). This is one row of 80 cards, which
amounts to eight lines of printer data (word),
rl WORKBUF — pointer to the 1,920-byte woric buffer established with
StartPrint (word).
r2 COLRDATA — pointer to 80 bytes of Ci)mmodore card color data (40-
colunm screen format) for the cardrow; pass $0000 for normal black
and white printing (word).
Apple
rO PRINTDATA — pointer to 640 bytes of graphic data in linear bitmap
format This is eight 640-bit rows of printer data (word).
rlL LF.SUPPRESS — set to TRUE to suppress automatic linefeed after
printing buffer (for overlayed printing); normally set to FALSE.
Apple
RWbank the memory bank that the PRINTDATA buffer is in. Valid
settings are MAIN and AUX.
Commodorg
nothing.
Applg
X STATUS — printer error code; $00 = no error.
assume a, x, y, r0-rl5.
Apple
assume a, y, r0-r4.
Description: PrintBuffer prints eight lines of graphic data on the printer. The maximum
width of each line is determined by the capabilites of the printer and its driver.
640 dots per line is standard, but some printers and drivers handle less. The
application can determine the capabilities of the printer with a call to
GetDimensions (Commodore) or GetMode (Apple). If the printer cannot
handle the full 640 dots, PrintBuffer will ignore any pixels at the end of each
line.
The application must call StartPrint before sending graphic data to
' PrintBuffer. It is also the job of the application to keep track of the number of
possible cardrows per page and call StopPrint to formfeed when necessary.
C64 & C128: The data passed in PRINTDATA is in Commodore card format, where data is
stacked into 8x8-pixel blocks. Graphic printer data can be built-up direcdy on the
40-column graphics screen using GEOS routines and sent direcfly to the printer
(calcinating the address using GetScanLine). Because one printer cardrow is
Uses:
Returns:
Destroys:
203
PrIntBuffer
equivalent to two screen caixirows the full 640-dot printer cardrow can be created
using two sequential screen cardrows.The sequential memory organization of the
40-column screen wraps the end of one screen cardrow around to the beginning
of the next screen cardrow. In the 80-column mode of GEOS 128, one screen line
is equivalent to one printer line. However, the data must first be converted from
linear bitmap format into card format (a simple operation). Also, since the
foreground screen can only be accessed indirectiy through the VDC chip, the
printer data is usually built-up in the background screen buffer.
Apple: The data passed in PRINTDATA is in linear bitmap format, where the first 80
bytes represent the 640 bits that are printed on the first line, the next 80 bytes
represent the 640 bits on the next line, and so on to fill out eight lines. Printer data
can be created using the GEOS graphics routines, then converted from Apple
internal screen format to linear bitmap format using GetLine and
GetBackLine.
With the proper printer and driver, color output can be created by setting making
three passes per line, each time printing in a different color (cyan, yellow,
magenta). The first color is set with SetMode and PrintBuffer is called witii
the LF_SUPPRESS flag set to TRUE, which will return the print carriage
without performing an linefeed. The next color can then be printed on top of what
is already there. When calling PrintBuffer for the third time (the last color), set
the LFJUPPRESS flag to FALSE, which will carriage return and linefeed.
Example:
See also: PrintASCII, StartPrint, StopPrint, InitForPrint.
PrOmptOff (Apple, C64, C128)
text/keyboard I
Function:
Parameters:
Alters:
Destroys:
Description:
Example:
See also:
Turn off the prompt (remove the text cursor from the screen),
none.
alphaFlag
a, X, r3L
(($cO & (alphaFlag & $40) I PROMPT.DELAY),wA^re
PROMPT DELAY = 60.
PromptOff removes the text prompt from the screen. To ensure the prompt will
remain invisible until a subsequent call to PromptOn, interrupts must be
disabled before calling PromptOff:
KillPrompt :
php
sei
jsr
LoadB
pip
rts
PromptOff
alphaFlag, #0
;save i status
/disable interrupts
/prompt » off
/clear alpha flag
/restore i status
/exit
InitTextPrompt, PromptOn.
PromptOff -
PrOmptOn (Apple, C64, Cmy ^ text/keyboard
Function: Turn on the prompt (show the text cursor on the screen).
Parameters: none.
Uses : strlngX cursor x-position (word).
stringY cursor y-position (byte).
Alters: alphaFlag (($cO & (alphaFlag I $40) I PROMPT_DELAY),w/z^r^
PROMPT JfELAY = 60.
Destroys: a, x, r3L.
Description: PromptOn makes the text prompt visible and active at the position specified by
stringX and stringY. The prompt will flash once every second
(PROMPT^DELAY). If stringX or StringY are changed, the cursor will
repositioned automatically the next time the cursor flashes. To make the update
immediate, call PromptOn. Before PromptOn is called for the first time,
InitTextPrompt should be called.
See also: InitTextPrompt, PromptOff.
Example:
PurgeTurbo
IPurgeTurbo (C64, cns)
very low«levcl disk]
Function: Completely deactivate and remove disk drive turbo code from current drive,
rctuming to standard Commodore DOS mode.
Parameters: none.
Uses : curDrive currcndy active disk drive.
Returns: x error ($00 = no error).
Destroys: a, y, r0-r3.
Description: PurgeTurbo deactivates and removes the turbo software from the current drive,
returning control of the device to the disk drive's internal ROM software. This
allows access to normal Commodore DOS routines. An application may want to
access the Commodore DOS to perform disk functions not offered by the GEOS
Kemal such as formatting.
Apple: Apple GEOS has no PurgeTurbo equivalent
See also: EnterTurbo, ExitTurbo.
207
PutBlock
PutBlOCk (Apple, C64, C128)
low-level disk]
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
General purpose routine to write a block to disk with verify.
r4 BUFFER — address of buffer to get block from; must be at least
BLOCKSIZE bytes (word).
Commodore:
rlL TRACK — valid track number (byte),
r IH SECTOR — valid sector on track (byte).
Applg;
r 1 BLOCK — ProDOS block number (word).
curDrive currently active disk drive to write to.
Commodore:
curType
GEOS 64 vl.3 and later for detecting REU shadowing.
Applg:
RWbank bank BUFFER is in (MAIN or AUX).
numDiskRetries number of times to attempt rewrite if verify fails. If $(X), no
verify will be perfomied.
X error ($00 = no error),
rl, r4 unchanged
a, y.
PutBlock writes a block from BUFFER to the disk. PutBlock is useful for
implementing disk utility programs and new file structures.
C64 & C128: PutBlock is a higher-level version of WriteBlock. It calls InitForlO,
EnterTurbo, ReadBlock, and DoneWithlO. If an application needs to write
many blocks at once, WriteBlock may offer a faster solution. If the disk is
shadowed, PutBlock will also write the data to the shadow memory.
Apple:
Example:
See also:
PutBlock provides the lowest-level block access to a ProDOS compatible
device. It uses the ProDOS device driver WRITE block command directly.
Apple GEOS, for this reason, does not have a WriteBlock equivalent.
GetBlock, WriteBlock, BIkAlloc.
208
PutChar (Apple, C64, C128)
text
Function:
Parameters:
Uses:
Returns:
Destroys:
Process a single character code (both escape codes and printable characters).
a CHAR — character code (byte).
r 1 1 XPOS — x-coordinate of left of character (word).
r 1 H YPOS — y-coordinate of character baseline (word).
dispBufferOn
currentMode
leftMargin
rightMargin
(following set by
curHeight
baseiineOffset
cardDataPntr
curlndexTable
curSetWidth
display buffers to direct output to.
character style.
left margin to contain character,
right margin to contain characters.
LoadCharSet and LoadAuxSet).
height of current font.
number of pixels from top of font to baseline,
pointer to current font image data,
pointer to current font index table data,
pixel width of font bitstream in bytes.
r 1 1 x-position for next character.
rl H y-position for next character (usually unchanged).
Commodore:
a, X, y, rlL, r2-rl0, rl2, rl3
Applg;
a, X, y, rlL, r2
" Description: PutChar is the basic character handling routine. If the character code is less than
32, PutChar will look-up a routine address in an internal jump table to process
the escape code. Only send implemented escaped codes to PutChar.
If the character code is 32 or greater, PutChar treats it as a printable character.
First it establishes the .printed size of the character with any style attributes
(currentMode) then checks the character position against the bounds in
leftMargin and rightMargin. If the left edge of the character will fall to the left
of leftMargin, then the width of the character is added to the x-position in rll
and PutChar vectors through StringFaultVec. If the right edge of the characer
will fall to the right of rightmargin, then PutChar vectors through
StringFaultVec without altering the x-position. The character is not printed in
either case.
Assuming no margin fault, PutChar will print the character to the screen at the
desired position. Any portion of the character that lies above windowTop or
below windowBottom will not be drawn.
PutChar cannot be used to directly process multi-byte character codes such as
GOTOX or ESC^GRAPHICS unless rO is maintained as a string pointer
when PutChar is called (as it is in PutString). See PutString for more
information.
PutChar
See also: SmallPutChar, PutString, PutDecimal.
i
210
F U I U II ai
PutDecimal (Apple, C64, ci28)
text
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Format and print a 16-bit positive integer.
a FORMAT — formatting codes (byte) — see below.
rO NUM — 16-bit integer to convert and print (word),
rl 1 XPOS — x-coordinate of leftmost digit (word),
r 1 H YPOS — y-coordinate of baseline (word).
same as PutChar.
r 1 1 x-position for next character.
rlH unchanged.
Commodore:
a, X, y, rO, rlL, r2-rl0, rl2, rl3
Applg;
a, X, y, rO, rlL, r2
PutDecimal converts a 16-bit positive binary integer to ASCII and sends the
result to PutChar. The number is formatted based on the FORMAT parameter
bytes in the a-registers as follows:
FORMAT:
NOTE:
Example:
See also:
7 6 5
I b7 I b6 I
bO-b5
b7 justification: 1 = left; = right.
b6 leading zeros: 1 = suppress; = print.
b5-bO field width in pixels (only used if right justifying).
The following constants may be used:
SET LEFTJUST
SET"RIGHTJUST
SET"SUPPRESS
SET^NOSUPPRESS
The maximum 16-bit decimal number is 65535 ($ffff), so the printed number will
never exceed five characters.
PutChar.
PutDirHead
IPutPirHead (Apple, C64, cns)
mid-level disk I
Function: Write directory header to disk. Commodore GEOS also writes out the BAM.
Parameters: none.
Uses:
curDrive
curDirHead
current directory header.
Returns:
Destroys:
Commodore:
curType GEOS 64 vL3 and later for detecting REU shadowing.
dir2Headt (BAM for 1571 and 1581 drives only)
dIrSHeadt (BAM for 1581 drive only)
^used internally by GEOS disk routines; applications generally don't use.
Apple:
curKBlkno current key block to write directory header to.
X error ($00 = no error).
Commodore:
r4 pointer to curDirHead.
Commodore:
a,y, rl.
Appig;
a, y. rl, r4.
Description:
PutDirHead writes the directory header to disk from the buffer at curDirHead.
Because of differences in the Commodore and Apple file systems, this can mean
different things. Commodore GEOS writes out the full directory header block,
including the BAM (block allocation map). Apple GEOS only writes out the 39-
byte ProDOS directory header for die cuntnt directory's key block.
C64 & C128: GEOS disks, like the standard Commodore disks upon which they are based,
have one directory header. The directory header occupies one full block on the
disk. The Commodore directory header contains information about the disk, such
as the location of the directory blocks, the disk name, and the GEOS version
string (if a GEOS disk). The Commodore directory header also contains the disk
BAM, which flags particular sectors as used or unused
PutDirHead calls PutBlock to write out the directory header. block from die
buffer at curDirHead. The directory header block contains the directory header
and the disk BAM (block allocation map). Applications that are working with die
mid- and low-level GEOS disk routines may need to call PutDirHead to update
die BAM on die disk widi die BAM in memory. Many useful, mid-level GEOS
routies, such as BlkAUoc, only update the BAM in memory (for sp^d and ease
of error recovery). When a new fdc is written disk, GEOS allocates die blocks in
the in-memory BAM, writes the blocks out using the track sector table, then, as
die last operation, calls PutDirHead to write die new BAM to die disk. An
212
PutDfrHead
application that uses the mid-level GEOS routines to build its own specialized
disk file functions will need to keep track of the status of the BAM in memory,
writing it to disk as necessary.
It is important that the BAM in menx>ry not get overwritten by an outdated BAM
on the disk. Applications that manipulate the BAM in memory (or calls GEOS
routines that do so), must be careful to write out the new BAM before calling a
routine that might overwrite it. Routines that call GetDirHead include
OpenDisk, SetGEOSDisk, and OpenRecordFile.
GEOS VLIR routines set the global variable fileWritten to TRUE to signal that
the VLIR file has been written to and that the BAM in menx)ry is more recent than
the BAM on the disk. CloseRecordFile checks this flag. If fileWritten is
TRUE, CloseRecordFile calls PutDirHead to write out the new BAM.
Apple: Apple GEOS disks, like the ProDOS disks upon which they are based, have a
directory header for each directory. The header for a root directory is called a
volume directory header and the header for a subdirectory is called a subdirectory >
header. These directory headers are 39-byte structures defined by ProDOS. They
contain such information as the directory (or volume) name, the date stamp, and
any read/write access flags. The directory header does not contain the VBM
(volumen bit map, the Apple equivalent of a BAM).
PutDirHead first reads in the key block of the current directory (pointed at by
curKBIkno) and copies the 39-byte directory header information from
curDirHead to the key block, then rewrites the key block to disk. Only these
39-bytes in the key block are changed.
Since Apple GEOS does not store the allocation map (VBM) in the directory
header 10:e Commodore GEOS, it not necessary to be as careful about rereading
the directory header. PutDirHead only needs to be called when an application
explicidy wants to change the directory header, which few applications (outside
of the deskTop) will ever do. For information on writing the Apple VBM, refer to
PutVBM.
Example:
See also: GetDirHead, GetVBM, PutVBM.
V.
213
PutScreenLine
PutScreenLine (Apple)
graphics!
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Copies data from the application's buffer, in internal format, to a byte-aligned
horizontal line on the screen.
rO DATA — address of buffer to copy data from (word).
rlH XINDX — byte in line to begin with (seven-bit Apple screen byte) (byte).
r2L XWIDIH — width in bytes of line (seven-bit Apple screen bytes) (byte).
rlL Y — y-coordinate of line (byte).
where (XINDX^J.Y) and (XINDX^7+XWIDTH,Y) define the endpoints of the
line.
dispBufferOn:
bit 7 — get data from foreground screen if set
bit 6 — get data from background buffer if set
If both bits are setjoreground screen is used.
rO address of byte following last byte in the buffer.
a, X, y, rO, rlH, r2L, r5-r6
PutScreenLine copies bytes directly from the specified buffer to the screen
memory. The screen is treated as a contiguous block of bytes even though, in
actualiQ^, alternate bytes lie in different memory banks.
Bytes are copied from the buffer pointed to by rO and stored in screen memory
beginning at the byte-index into the line stored in rlH.
No clipping at the screen edge is performed; the values passed are rssumed to lie
entirely on one screen line.
GetScreenLine.
214
■ PulOtiHuiiLiiie
PutString^ i PutString (Apple, C64, cns)
text
Function:
Parameters:
Uses:
Returns:
Destroys:
Calls:
Description:
Print a string to the screen.
Normal;
rO STRING — pointer to string data (word).
r 1 1 XPOS — x-coordinate of left of first character (word).
r 1 H YPOS — y-coordinate for character baselines (word).
Inline:
data appears immediately after the jsr i^PutString
.word XPOS x-coordinate.
.byte YPOS y-coordinate.
.byte STRINGDATA null terminated string (no length limit)
same as PutChar.
r 1 1 x-position for next character.
r 1 H y-position for next character (usually unchanged).
CQmmQjprp
a, X, y, rlL, r2-rl0, rl2, rl3
Apple
a, X, y, rlL, r2
PutChar.
PutString passes a full string of data to PutChar a character at a time. It
maintains rO as a running pointer into the string and so supports multi-byte
escape codes such as GOTOXY.
If a character exceeds one of the margins, PutChar will vector through
stringFaultVec as appropriate. rO, rll, and rlH will all contain useful values
(current string pointer, x-position, and y-position, respectively). For more
information, refer to "String Faults (Left or Right Margin Exceeded)'* in Chapter
XX.
Basic operation of PutString:
PutString:
5$:
Idy
Ida
beq
jsr
IncW
bra
#0
(rO),y
10$
PutChar
;use zero offset
;get character
;exit if NULL terminator
/otherwise process char.
rO
5$
;move to next byte in string
;and loop through again
10$:
rts
/exit
C64 & C128: Unless a special string fault routine is placed in stringFaultVec prior to calling
PutString, a margin fault will be ignored and PutString will attempt to print
the next character.
Pur SriUMC^
PulGereenLIno
Apple: If stringFaultVec contains $0000 when PutString is called, Apple GEOS
installs a temporary string fault routine that fast-forwards through the string to the
null-terminator whenever a fault is generated. stringFaultVec is restored with a
$0000 when PutString exits.
Example:
See also:
PutChar, GraphicsString.
PutVBM (Apple)
P u 1 Q I r i n s
mid-level disk
Function: Flush the currently cached VBM block, writing it out to disk.
Parameters: none.
Uses: curDrive
curVBlkno^ block to write cache to.
Returns: x error ($00 = no error).
Alters : VBM changed^ set to FALSE; indicates current cache matches disk.
^used internally by GEOS disk routines; applications generally don't use.
Destroys: a, y, rl, r4.
Description: PutVBM writes the currently cached VBM block to its proper spot on the disk.
This cache is inaccessible to applications but is used indirecdy by routines such as
SetNextFree. PutVBM is called by high-level GEOS routines to automatically
flush the cache, bringing the copy of the VBM on the disk up-to-date with the
copy in memory. Specialized applications that call mid- and low-level disk
routines may need to flush the cache manually.
Apple GEOS disk routines cache a single VBM block in an internal memory
buffer. This speeds up disk operations by allowing the VBM to be accessed
quickly during multiple-sector disk operations. This parallels the way
Commodore GEOS buffers the BAM in the directory header. In fact, wherever a
Commodore GEOS application calls PutDirHe^d to update the BAM on the
disk, an Apple GEOS application can usually substitute a call to PutVBM.
But there are differences between the Commodore buffering and the Apple
buffering. Because higher-density storage devices (a hard disk, for example) will
have more than one VBM block, the entire VBM cannot be stored in memory.
The Apple GEOS routines that manage the disk cache will automatically flush the
currentiy cached VBM block before loading in another. But if another VBM block
is never loaded, the cache may not necessarily get flushed. For example, some
mid-level routines, such as BlkAlIoc and AllocateBlock, do not explicitly
flush the cache O'ust as their Commodore counterparts do not call PutDirHead),
which may mean that the block in the cache may be more up-to-date than the
block on the disk. An application that uses these mid-level routines should flush
the cache manually with a calls to PutVBM.
The less often the cache is flushed, the faster a multiple-sector disk operation will
run. GEOS VLIR routines, for example, do not flush the cache until
CioseRecord is called. At the very least, the application must be careful to flush
the VBM cache before calling any other routine that might call Get VBM because
GetVBM will overwrite die cached block before it is used to update the disk
copy. GetVBM is called by routines such as OpenDisk and BlkAlIoc.
Note:
PutVBM will write out the cached VBM block even if VBMchanged is
FALSE.
PutVBM
Example:
See also: GetVBM, GetDirHead, PutDirHead.
218
ReadBackLine
ReadBackLine (Apple)
graphics
Function:
Parameters:
Returns:
Destroys:
Description:
Example:
Translates a screen line in the background buffer from internal format to linear
bitmap format
rO DATA — address of buffer to copy data to (word),
r IL Y — y-coordinatc of line (byte).
rO address of byte following last byte in the buffer.
a,x, y, rO
ReadBackLine reads bytes direcdy from the background buffer and converts
them into linear bitmap foraiat in the application's buffer. The buffer pointed to
by DATA must be at least SC PIX WIDTH/7 = 80 bytes long.
219
ReadBlock
ReadBlock (C64, cns)
very low«level disk}
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Apple:
Example:
Very low-level read block from disk.
rlL TRACK — valid track number (byte),
rlH S ECTO R — valid sector on track (byte).
r4 BUFFER — address of buffer of BLOCKSIZE bytes to read block into
(word).
curDrive
curType
currently active disk drive.
GEOS 64 vl.3 and later, for detecting REU shadowing.
error ($00 = no error).
a, y.
ReadBlock reads the block at the specified TRACK and SECTOR into
BUFFER. If the disk is shadowed, ReadBlock will read from the shadow
memory. ReadBlock is a pared down version of GetBlock. It expects the
application to have already called EnterTurbo and InitForlO. By removing
this overhead from GetBlock, multiple sector reads can be accomplished
without the redundant initialization. This is exacdy what happens in many of the
higher-level disk routines that read multiple blocks at once, such as ReadFile.
ReadBlock is useful for multiple-sector disk operations where speed is an issue
and the standard GEOS routines don't offer a decent solution. ReadBlock can
function as the foundation of specialized, high-speed disk routines.
Apple GEOS has no ReadBlock equivalent Use GetBlock instead.
Read sector from disk into diskBlkBuf .
very-low level disk primitives.
Demonstrates use of
Pass:
track
sector
Returns:
X
MyGetBlock:
track number
sector on track
error code
99$:
LoadW
r4,«diskBlkBuf
MoveB
rlLrtrack
MoveB
rlH, sector
jsr
EnterTurbo
txa
bne
99$
jsr
InitForlO
jsr
ReadBlock
jsr
DoneWithIO
rts
; where to get data from
; track number
; sector number
;go into turbo mode
;set status flags
/branch if error found
/prepare for serial I/O
/primitive read block
/restore after I/O done
/ exit
See also: GetBlock, WriteBlock, VerWriteBlock.
220
■R eadBlook
IReadByte (Apple, C64, cns)
mid-level disk
Function: Special version of ReadFile that allows reading a chained list of blocks a byte at
a time-
Parameters: on initial call only:
r4 BLOCKBUF — pointer to temporary buffer of BLOCKSIZE bytes for
use by ReadByte, usually a pointer to diskBlkBuf (Apple GEOS: must
be in main memory) (woid).
rS $0000 (word).
Commodore:
r 1 START^TRSC — track/sector of first data block (word).
App le:
rl INDXBLKPTR — pointer to index buffer that contains index block of
chain to read (must be in main memory) (word).
Uses:
curDrive
Commodore:
curType
Apple:
RWbank
GEOS 64 V 1.3 and later for detecting REU shadowing,
bank BUFFER is in (MAIN or AUX).
Returns:
Destroys:
Description:
a byte returned
X error ($00 = no error).
rl, r4, rS contain internal values that must be preserved between calls to
ReadByte.
ReadByte allows a chain of blocks on the disk to be read a byte at a time. The
first time ReadByte is called, rl, r4, and r5 must contain the proper
parameters. When ReadByte returns without an error, tiic a register will contain
a single byte of data fix^m the chain. To read another byte, call ReadByte again.
Between calls to ReadByte, the application must preserve rl, r4, r5, and the
data area pointed to by BLOCKBUF. Apple GEOS applications must also
preserve the 512-byte index block pointed to by INDXBLKPTR and the status of
RWbank.
ReadByte loads a block into BLOCKBUF and returns a single byte from the
buffer at each call. After returning die last byte in the buffer, ReadByte loads in
the next block in the chain and starts again from the beginning of BLOCKBUF.
This process continues until there are no more bytes in the file. A
BFR OVERFLOW error is then returned.
ReadByte is especially useful for displaying very large bitmaps with
BitOtherCIip and NewBitOtherCIip.
ReadBlock
C64 & C128: Reading a chain a byte at a time under Commodore GEOS involves finding the
first data block and passing its track/sector to ReadFile. The tracl^sector of the
first data block in a sequential file is returned in rl by GetFHdrlnfo. TTie first
data block of a VLIR record is contained in the VLIR^s index table.
Apple: Because the ProDOS filing system is different from the Commodore filing
system, different steps are involved in using ReadByte. The Apple GEOS
version of GEOS expects an entire index block for the chain, not merely an initial
track/sector as the Commodore version does. The index block for a sequential file
is returned in rl by GetFHdrlnfo, but it must be loaded into memory with
GetBIock. The index block for a VLIR record is contained in the VLIR's index
table.
Example:
See also: GetFile, WriteFile, ReadRecord.
ReadClock (Apple)
clock driver
Function: Causes the clock driver to update the global GEOS clock variables with the
current time. Called during MainLoop Level by GEOS.
Parameters: none.
Returns: nothing.
Alters: year
month
day
hour
minutes
seconds
alarmOn
updated firom clock device
updated firom clock device
updated firom clock device
updated from clock device
updated firom clock device
updated firom clock device
if bit 7 set and time for alarm to trigger, then bit 7 is cleared
and bit 6 is set (byte is shifted right once).
Destroys: assume x, y, r0-rl5.
Description: GEOS calls ReadClock during MainLoop Level. ReadClock is expected to
update the global clock variables with the current time. It also checks for an alarm
trigger and sets alarmOn appropriately. (Depending on the clock, an alarm
trigger may be flagged automatically in hardware or may have be generated in
sofD^are by comparing the current time with an internal alarm time.)
See also:
Clockint, SetTimeDate, SetAlarm, ResetAlarm.
223
neadCloek
ReadFile (Apple, C64, ci28)
mid-Ievel disk
Function:
Parameters:
Uses:
Read a chained list of blocks into memory,
r7 BUFFER — pointer to buffer where data will be read into (word).
r2 BUFSIZE — size of buffer Commodore version can read up to 32,258
bytes (127 Commodore blocks); Apple version can read up to the
maximum two-byte number that can be passed in r2: 65,535 ($ffff) bytes
(word).
CpmmpdQTg;
rl START.TRSC— track/sector of first data block (word).
Apple;
r 1 INDXBLXDCK — block number of index block for chain (word).
curDrive
Cpmrnodore;
curType
Apple;
RWbank
GEOS 64 vl.3 and later for detecting REU shadowing,
bank BUFFER is in (MAIN or AUX).
Returns: x error ($00 = no error).
r? pointer to last byte read into BL/FFfi? plus one.
Commodore:
rl if BFR^OVERFLOW error returned, contains the track/sector of the
block that, had it been copied from diskBlkBuf to the application's
buffer space, would have exceeded the size of BUFFER. The process of
copying any extra data from diskBlkBuf to the end of BUFFER is left
to the application. The data starts at diskBlkBuf+2. If no error, then rl
is destroyed.
rSL byte index into fileTrScTab of last entry (last entry = fileTrScTab
plus value in rS).
App le:
r 1 if BFR_OVERFLOW error returned, contains the number of die block
that would have overwritten the end of BUFFER had the entire block been
read direcdy into memory. BUFFER is filled with as much data from the
block as will fit. If no error, then rl is destroyed.
Alters: Commodore:
fileTrScTab As the chain is followed, the track/sector pointer to each
block is added to die file track/sector table. The track and
sector of the first data block is added at fiIeTrScTab+2 and
fiIeTrScTab+3, respectively, because die first two bytes
(fileTrScTab+0 and fileTrScTab+1) are reserved for the
GEOS file header track/sector.
Redi l Cluck
Apple;
INDEXBLOCKBUF index block for chain (in auxiliary memory; see
below for information on accessing this buffer).
Destroys: Apple:
y, (rl), r3-r4 (see above for rl).
CPTnmpdore;
y, (rl), r2-r4 (see above for rl).
Description: ReadFile reads a chain of blocks from the disk into memory at BUFFER.
Although the name implies that it reads "files" into memory, it actually reads a
chain of blocks and doesn't care whether this chain is a sequential file or a VLIR
record — ReadFile merely reads blocks until it encounters the end of the chain
or overflows the memory buffer.
ReadFile can be used to load VLIR records from an unopened VLIR file.
geoWrite, for example, loads different fonts while another VLIR file is open by
looking at all the font file index tables and remembering the index information for
records that contain font data. When a VLIR docimient file is open, geoWrite
can load a different font by passing one of these saved values in rl to ReadFile.
ReadFile will load the font into memory without disturbing the opened VLIR
file.
For reading a file when only the filename is known, use the high-level GetFile.
C64 & C128: The Conimodore filing system links blocks together with track/sector links: each
block has a two-byte track/sector forward-pointer to the next sector in the chain
(or $00/$ff to signal the end). Reading a chain involves passing the first
track/sector to ReadFile. The first block contains a pointer to the next block, and
so on. The whole chain can be followed by reading successive blocks.
ReadFile reads each 256-byte block into diskBlkBuf and copies the 254 data
bytes (possibly less in the last block of the chain) to the BUFFER area and copies
the two-byte track/sector pointer to flleTrScTab. This process is repeated until
the last block is copied into the buffer or when there is more data in diskBlkBuf
than there is room left in BUFFER.
when there is more data in diskBlkBuf than there is room left in BUFFER,
ReadFile returns with a BFR_OVERFLOW error without copying any data
into BUFFER. The applicatioiTcan copy data, starting at diskBlkBuf+2, to fill
the remainder of BUFFER manually.
Because of the limited size of fileTrScTab (256 bytes), ReadFile cannot load
more than 127 blocks of data. (256 total bytes divided by two bytes per
track/sector minus two bytes for the GEOS file header equals 127.) 127 blocks
can hold 127 * 254 = 32,258 bytes of data.
Apple: Unlike die Commodore filing system, die ProDOS filing system links blocks
together with entries in an index block: each entry in the index block holds a two-
byte block number. Going through each entry constitutes walking die chain. For
floadClook
this reason, reading a chain involves passing, not the first data block, but the
block number of the index block.
Apple GEOS first reads the index block into the internal buffer
INDEXBLOCKBUF (in auxiliary memory), then reads in the blocks specified
in the index.
Applications cannot direcdy access the auxiliary buffer INDEXBLOCKBUF.
However, MoveAuxData can be used to copy the block into the appliciation's
memory space if access to it is necessary:
AUXtoMAIN
MAINtoAUX
%10000000
%01000000
LoadW rO, # INDEXBLOCKBUF
LoadW rl, #diskBlkBuf
LoadW r2, #BLOCKSIZE
Ida #AUXtoMAIN
jsr MoveAuxData
;copy from index blk
;to temp buffer
;move a full block
;copy aux to main
Apple GEOS ReadFile could conceivably load up to 65,536 bytes of data into
memory. This is of litde use, however, because the absence of large, usable
memory blocks functionally limits reads to 32K or 64 blocks.
Example:
See also:
GetFile, WriteFile, ReadRecord.
R 9 adFil 9
ReadLink (C64, ci28)
very low-level disk
isk]
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Apple:
Example:
See also:
Read link (first two bytes) from a Commodore disk block
rlL TRACK — valid track number (byte),
r 1 H S ECTO R — valid sector on track (byte).
r4 BUFFER — address of buffer of at least BLOCKSIZE bytes, usually
points to diskBIkBuf (word).
curDrive currently active disk drive.
X error ($00 = no error).
diskBIkBuf
a, y.
ReadLink returns the track/sector link from a disk block as the first two bytes in
BUFFER. The remainder of BUFFER (BLOCKSIZE-2 bytes) may or may not
be altered,
ReadLink is useful for following a multiple-sector chain in order to build a
track/sector table. It mainly of use on 1581 disk drives, which walk through a
chain significantly faster when only the links are read. Routines such as
DeleteFile and FollowChain will automatically take advantage of this
capability of 1581 drives.
Disk drives that do not offer any speed increase through ReadLink will simply
perform a ReadBIock.
Apple GEOS has no ReadLink equivalent; ProDOS blocks are linked by the
index block.
ReadBIock, FollowChain.
Wore; Does *vo«a: isHI Oltr\jsnij (/S€ tt^/umiac^
ReadRecord
ReadRecord (Apple, C64, ci28)
VLIR disk
Function:
Parameters:
Uses:
Read in the current VLIR record.
r7 BUFFER — pointer to start buffer where data will be read into (word),
r2 BUFSIZE — size of buffer: Commodore version can read up to 32,258
bytes (127 Commodore blocks); Apple version can read up to the
maximum two-byte number that can be passed in r2: 65,535 ($ffff) bytes
(word).
curDrive
curRecord
fileHeader
Commodorp;
curType
Apple;
RWbank
current record pointer
index table holds first block of record
GEOS 64 vl.3 and later, for detecting REU shadowing,
bank RECDATA is read into (MAIN or AUX).
Returns:
Alters:
X error ($(X) = no error).
a $00 empty record, no data read.
$ff = record contained data.
r7 pointer to last byte read into BUFFER plus one if not an empty record,
otherwise unchanged.
ComPOdprp;
rl if BFR OVERFLOW error returned, contains the track/sector of the
block tfiat, had it been copied from diskBlkBuf to the application's
buffer space, would have exceeded the size of BUFFER. The process of
copying any extra data from diskBlkBuf to the end of BUFFER is left
to the application. The data starts at diskBlkBuf+2. If no error, then rl
is destroyed
Apple;
rl
if BFR_0 VERFLOW error returned, contains the number of the block
that would have overwritten the end of BUFFER had the entire block been
read directly into memory. BUFFER is filled with as much data fix)m the
block as will fit. If no error, then rl is destroyed.
CpmmcKlorg;
fileXrScTab
As the chain blocks in the record is followed, the track/sector
pointer of each block is added to the file track/sector table.
The track and sector of the first block in the record is added
at fiIeTrScTab+2 and fiIeTrScTab+3. Refer to
ReadFile for more infOTmatibn.
Destroys: Apple:
y, (rl),r3-r4 (see above for rl).
Commodore:
228
ReadRecord
y, (rl), r2-r4 (sec above for rl).
Description: ReadRecord reads the current record into memory at BUFFER. If the record
contains more than BUFSIZE bytes of data, then a BFR_OVERFLOW error is
returned.
ReadRecord calls ReadFile to load the chain of blocks into memory.
Example:
See also: WriteRecord, ReadFile.
229
ReadScanLine
ReadScanLine (Apple)
graphics!
Function:
Parameters:
Returns:
Destroys:
Description:
Example:
Translates a screen line on the foregorund screen from internal format to linear
bitmap format
rO DATA — address of buffer to copy data to (word),
r IL Y — y-coordinatc of line (byte).
rO address of byte following last byte in the buffer,
a,x,y, rO
ReadScanLine reads bytes direcdy from the foreground screen and converts
them into linear bitmap format in the application's buffer. The buffer pointed to
by DATA must be at least SC PIX WIDTH/7 = 80 bytes long.
230
RecoverAIIMe
RecoverAllMenus (Apple, C64, cns)
icon/menu
Function:
Parameters:
Destroys:
Description:
Example:
See Also:
Removes all menus (including the main menu) from the foreground screen by
recovering from the background buffer.
none.
assume r0-rl5, a, x, y
RecoverAllMenus is a very low-level menu routine which recovers the area
obscured by the opened menus from the background buffer. Usually this routine
is only called internally by the higher-level menu routines. It is of little use in
most applications and is included in the jump table mainly for historical reasons.
RecoverAllMenus operates by loading the proper GEOS registers with the
coordinates of the menu rectangles and calling the routine whose address is in
recoverVector (normally RecoverRectangle) repeatedly.
DoPreviousMenu, ReDoMenu, GotoFirstMenu, RecoverMenu.
233
RecoverFG
ReCOVerFG (Apple) graphics/utiUty
Function: Restores a portion of the foreground screen from data saved with SaveFG.
Parameters: rO FGSTRUCT — pointer to an FG data structure (word).
rl FGDATA — pointer to SaveFG data to restore (word).
Returns: Foreground screen restored.
Destroys: a, x, y, rl-r6.
Description: RecoverFG restores a rectangular area of the foreground screen saved with
SaveFG.
FGSTRUCT points to an FG data structure, which is in the following format:
FGSTROCTl :
• word XI ; pixel x-position of left edge
• byte Yl ; pixel y-position of top edge
.word X2 ;pixel x-position of right edge (XI + WIDTH)
.byte HEIGHT ;pixel height (Y2 - Yl)
The FG data structure used to restore an area should be the same as the one used
to save the area.
Example:
See also: SaveFG.
234
RecoverLine (Apple, C64, cns)
graphics
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
128:
Example:
See also:
Recovers a horizontal line from the background buffer to the foreground screen.
r3 XI — x-coordinate of leftmost cndpoint (word).
r4 X2 — x-coordinate of rightmost endpoint (word).
rllL Yl — y-coordinate of line (byte).
where (X1,Y1) and (X2,Y1) define the endpoints of the line to recover.
nothing
Commodore
a, x, y, r5-r8
Applg
a, X, y
RecoverLine recovers the pixels which fall on the horizontal line whose
coordinates are passed in the GEOS registers. The pixel values are copied from
the background buffer to the foreground screen.
The flags in dispBufferOn are ignored; the pixels are always copied to the
foreground screen regardless of the value in this variable.
Under GEOS 128, oring DOUBLE W into theXi andX2 parameters will
automatically double the x-position in SD-column mode. Or*ing in ADDl W will
automatically add 1 to a doubled x-position. (Refer to "GEOS 128 X-posiuon and
Bitmap Doubling" in Chapter.® gr@ for more information.)
ImprintLine, HorizontalLine, InvertLine^VerticalLine , DrawLine.
RecoverMenu
RecoverMenu (Apple, C64, cns)
icon/menu
Function: Removes the current menu from the foreground screen by recovering from the
background buffer.
Parameters: none.
Destroys: assume r0-rl5, a, x, y
Description:
RecoverMenu is a very low-level menu routine which recovers the rectangular
area obscured by the current menu. Usually this routine is only called internally
by the higher-level menu routines such as DoPreviousMenu. It is of little use
in most applications and is included in the jump table mainly for historical
reasons.
RecoverMenu operates by loading the proper GEOS registers with the
coordinates of the current menu's rectangle and calling the routine pointed to by
recoverVector (normally RecoverRectangle).
Example:
See Also: DoPreviousMenu, ReDoMenu, GotoFirstMenu, RecoverAllMenus.
Recover Rectan^e
RecoveriRectangle^ i Recoveif^ectangle (Apple, C64, ci28) graphkTI
Function: Recovers the pixels within a rectangular region fSrom the background buffer to the
foreground screen.
Parameters: Normal:
r3 XI — x-coordinate of upper-left (word).
r2L Y 1 — y-coordinate of upper-left (byte).
r4 X2 — x-coordinate of lower-right (word).
r2H Y2 — y-coordinateof lower-right (byte).
Inline:
data appears immediately after the jsr i_RecoverRectangIe
.byte Yl y-coordinate of upper-left. "
.byte Y2 y-coordinate of lower-right
.word XI x-coordinate of upper-left
.word X2 x-coordinate of lower-right
where (XI, Yl ) is the upper-left corner of the rectangular area and (X2,Y2) is the
lower-right corner.
Returns: r2, r3, and r4 unchanged.
Destroys: Commodore:
a, X, y, r5-r8, rllL
Appig;
a, X, y, rllL
«
Description: RecoverRectangle copies the pixels within a rectangular region from the
background buffer to the foreground screen by calling RecoverLine in a loop.
Note: The flags in dispBufferOn are ignored; the pixels are always copied to the
foreground screen regardless of the value in this variable.
128: Under GEOS 128, orlng DOUBLE W into theX7 andX2 parameters will
automatically double the x-position in SD-column nxxie. (Dr'ing in ADDl W will
automatically add 1 to a doubled x-position. (Refer to "GEOS 128 X-posi'Hon and
Bitmap Doubling" in Chapter.® gr@ for more information.)
Example:
See also:
ImprintRectangle, Rectangle, InvertRectangle.
RecoverSysRam
RecoverSysRam (Apple) int^^
Function: Restores the system state after a call to InitForDialog.
Parameters: none.
Returns: system restored to its prior state.
Destroys: a,x, y, rl, r2, r3Ly r4.
Description: RecoverSysRam restores the state of GEOS that was saved with
InitForDialog.
See also: InitForDialog.
238
RaadScgnl Ine-
[Rectangle, i Rectangle (Apple, C64, cns) graphics!
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
Draw a rectangle in the current fill pattern.
Normal:
r3 XI — x-coordinate of upper-left (word).
r2L Yl — y-coordinate of upper-left (byte).
r4 X2 — x-coordinate of lower-right (word).
r2H Y2 — y-coordinate of lower-right (byte).
where (XI, Yl ) is the upper-left corner of the rectangle and (X2,Y2) is the lower-
right corner.
Inline:
data appears immediately after the jsr i^Rectangle
.byte Yl y-coordinate of upper-left
.byte Y2 y-coordinate of lower-right,
.word X 1 x-coordinate of upper-left
.word X2 x-coordinate of lower-right
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
nothing
Commodore:
a, X, y, r5-r8
Apple:
a, x, y
Rectangle draws a filled rectangle on the screen as determined by the
coordinates of the upper-left and lower-right comers. The rectangle is filled with
the current 8x8 (card-sized) fill pattern.
The 8x8 pattern within the rectangle is drawn as if it were aligned to a card
boundary: that is, the bit-pattem is synchronized with (0,0), and, since the
patterns are 8x8, they are aligned with every eighth pixel thereafter. This allows
the patterns in adjacent or overlapping rectangles to line-up regardless of the
actual pixel positions.
Rectangle operates by calling HorizontalLine in a loop, changing the bit-
pattem byte after every line based on the current 8x8 fill pattern.
Because all GEOS coordinates are inclusive, framing a filled rectangle requires
either calling FrameRectangle after calling Rectangle (and thereby
overwriting the perimeter of the filled area) or calling FrameRectangle with
(Xi-l,y7-l) and (X2+l,y2+l) as the comer points.
128:
Under GEOS 128, or'ing DOUBLE W into theX7 andX2 parameters will
automatically double the x-position in ^D-column mode. Or'ing in ADD1_W will
irgaBScaTTfcfne-
automaticaUy add 1 to a doubled x-position. (Refer to "GEOS 128 X-position and
Bitmap Doubling • in Chapter.@gr@ for more information.)
See also: FrameRectangle, SetPattern. ImprintRectangle. RecoverRectangle
InvertRectangle. * '
ReDoMenu
ReDoMenu (Apple, C64, ci28)
icon/menu
Function:
Parameters: none
Destroys:
Description
Reactivate menus at the current level.
Example:
See Also:
assume r0-rl5, a, x, y
ReDoMenu is used by the application's menu event handler to instruct GEOS to
leave all menus (including the current menu) open when control is returned to
MainLoop. menuNumber is unchanged. Keeping the current menu open
allows anotiier selection to be made immediately.
ReDoMenu will redraw the current menu. If menu event routine changes the text
in the menu (adding a selection asterisk, for example), a call to ReDoMenu will
redraw the menu with the new text wliile leaving the menu open for another
selection.
DoMenu, GotoFirstMenu, DoPreviousMenu.
239
RenameFile
RenameFile (Apple, C64, ci28)
high-level disk|
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Renames a file that is in the current directory.
r6
rO
OLDNAME — pointer to null-terminated name of file as it appean on the
disk (Apple GEOS: must be in main memory) (word).
NEWNAME — pointer to new null-terminated name (Apple GEOS: must
be in main memory) (word).
curDrive
Commodore:
curType
Apple:
curVBlknot
VBMchangedt
numVBMBlkst
GEOS 64 vl.3 and later, for detecting REU shadowing.
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines: applications generally don't use.
X error ($00 = no error).
diskBlkBuf
dirEntryBuf
ComnKxlore:
curDirHead
dirlHeadt
dirSHeadt
Apple;
curVBlkno^
VBMchangedt
used for temporary block storage,
old directory entry.
BAM updated to reflect newly freed blocks.
(BAM for 1571 and 1581,drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines.
set to FALSE by VBM cacheing routines to indicate cached
VBM block has already been flushed
^used internally by GEOS disk routines; applications generally don't use.
a, y, rl, r4-r6.
Description: RenameFile searches the current directory for OLDFILE and changes the name
string in the directory entry to NEWFILE.
RenameFile first calls FindFile to get the directory entry and ensure the
OLDFILE does in fact exist. (If it doesn't exist, a FILE_NOT_FOUND error
is returned.)
The directory entry is read in, the new file name is copied over the old file name,
and the directory entry is rewritten. The date stamp of the file is not changed, but
the modification date stamp of the directory (Apple GEOS only) is updated.
240
RenameFile
When using GetlstDirEntry and GetNextDirEntry to establish the old file
name, do not pass RenameFile a pointer into diskBlkBuf. Copy the file name
from diskBlkBuf to another buffer (such as dirEntryBuf) and pass FreeFile
the pointer to that buffer. Otherwise when FreeFile uses diskBlkBuf it will
corrupt the file name. .
C64 & C128: Since Conirnodorc GEOS does not support a hierarchical file system, the "current
directory" is actually the entire disk. The call to FindFile also reads the BAM in
from disk.
Apple: Will only rename a file in the current directory. To rename a file from another
directory, the application must change directories (refer to GoDirectory for
moving to another directory).
Example:
See also: DeleteDir, FreeDir, FreeFile, FreeBlock.
241
ReOpenDisk
IReOpenPisk (AppieT
high-level disk|
Function:
Parameters:
Uses:
Returns:
Alters:
Reopen a disk to the most recent directory.
Destroys:
Description:
Note:
Example:
See also:
none
curDrive
curDirTabLo
curDirTabHi
drive that disk is in.
last current directory,
last current directory.
X error ($00 = no error).
rS pointer to disk name buffer as returned from GetPtrCurDkNm. This is
a pointer to one of the Dr;cCurDkNm arrays.
DrxCurDkNm
curDirHead
curKBIkno
sysDirBlkno
totNumBlkst
pathnameBur
curVBIknot
numVBMBIkst
VBMchangedt
current disk name array contains disk name.
current directory header.
block number of current directory's key block.
block number of /SYSTEM directory. If system directory
not found on disk, then this number is block of the root
directory.
total number of blocks in volume,
set to last logged directory,
block currently cached,
number of VBM blocks on disk,
set to FALSE.
^used internally by GEOS disk routines; applications generally don't use.
a, y, r0-r2, r4.
ReOpenDisk reopens a disk to its current directory (for each drive, GEOS
keeps track of the block of the current directory).. ReOpenDisk allows an
application to quickly switch back and forth between files on different drives, as
is often the case when an application and its data are on different disks. It saves
the application from calling GoDirectory every time drives are changed. It
otherwise performs the same initialization as OpenDisk.
ReOpenDisk assumes the user has not switched disks since the last time the
drive was accessed. If a new disk is placed in the drive, the current directory
block number associated with the drive will no longer be valid The application
may want remember the volume name when first opening the disk and then
compare the volume name after each call to ReOpenDisk with the original. If
they match, its a fairly safe assumption that the disk has not changed.
Because GEOS uses the same allocation and file buffers for each drive, it is
important to close all files and update tiie VBM (calling PutVBM if necessary)
before accessing another disk.
OpenDisk, SetDevice.
242
ResetAlarm
ResetAlarm (Apple) dock dmerl
Function: Qock driver routine to disable the alamx
Parameters: none.
Returns: nothing.
Alters: alarmOn $00
Destroys: assume a, x, y, r0-rl5.
Description: ResetSetAlarm is a clock driver routine for disabling an alarm.
See also: SetAlarm, SetTimeDate, Ciockint, ReadCIock.
CGNrtBE!NTt4L
243
ResetHandle
ResetHandle (C64, cns) internal I
Function: Internal routine used during the GEOS boot process.
Parameters: none.
Returns: does not return.
Description: ResetHandle is only used during the GEOS boot process. It is not useful to
applications and is documented here only because it exists in the jump table.
See also: BootGEOS.
244
This page intentionally left blank to maintain right/left (verso/recto)
page ordering. Final version will correct this.
RestartProcess
RestartProcess (Apple, C64, ci28) proccssi
Function: Reset a process's timer to its starting value then unblock and unfreeze the
process.
Parameters: x PROCESS — process to restart (0 - n-1, where n is the number of
processes in the table) dbytc).
Returns: x unchanged
Destroys: a
Description: RestartProcess sets a process's countdown timer to its initialization value then
unblocks and unfreezes it Use RestartProcess to initallj^ start a process after a
call to InitProcesses or to rewind a process to the beginning of its cycle.
Note: RestartProcess clears the runable flag associated with the process, thereby
losing any pending call to the process.
RestartProcess should always be used to start a process for the first time
because InitProcesses leaves Ae value of the countdown timer in an unknown
state.
Example:
See also: InitProcesses, EnableProcess, UnfreezeProcess, UnblockProcess.
244
RestoreFontPata (Apple)
RestoreFontData
text
Function:
Parameters:
Returns:
Destroys:
Description:
Example:
See also:
Restore internal font data from saveFontTab,
none.
curHeight
baselineOffset
cardDataPntr
curlndexTable
curSetWidth
a, X.
RestoreFontData reverses the effect of SaveFontData by restoring the
internal font variables from saveFontTab.
SaveFontData.
245
RstrAppI
RstrAppI (Apple, C64, C128)
Function: Standard desk accessory return to application.
Parameters: none.
Uses: curDrive.
Returns: never retutrns to desk accessory.
Description: A desk accessory calls RstrAppI when it wants to return control to the
application that called it. RstrAppI loads the swapped area of memory from the
SWAP FILE, restores the saved state of the system from the internal buffer,
resets the stack pointer to its original position, and returns control to the
application.
It is the job of the desk accessory to ensure that if the current drive (curDrive) is
changed that it be returned to its original value so that RstrAppI can And
SWAP FILE. Under Apple GEOS it is not necessary to save the current
directory.
Note: If a disk error occurs when reading in SWAP FILE, the remainder of the
context switch (restoring the state of the system, etc.) is bypassed and control is
immediately returned to the caller of the desk accessory. The application will have
only a moderate chance to recover, however, because the area of memory that the
desk accessory overlayed may very well include the area where the jsr to
GetFile or LdDeskAcc resides. The return, therefore, may end up in the
middle of desk accessory code.
Example:
See also: StartAppl, GetFile.
high-level disk
246
RstrFrmDialog
RstrFrmPialog (Apple, C64, cns) dialog box|
Function: Exits from a dialog box, restoring the system to the state prior to the call to
DoDlgBox.
Parameters: none.
Returns: Returns to point where DoDlgBox was called. System context is restored. ROL
contains sysDBData return value.
Uses: sysDBData.
Destroys: assume a, x, y, rOH-rlS
Description: RstrFrmDialog allows a custom dialog box routine to exit from the a dialog
box. RstrFrmDialog is typically called internally by the GEOS system icon
dialog box routines. However, it may be called by any dialog box routine to force
an immediate exit
RstrFrmDialog first restores the GEOS system state (context restore) and then
calls indirecdy through recoverVector to remove the dialog box rectangle firom
the screen. The routine in recoverVector is called with the r2-r4 loaded for a
call to RecoverRectangle. By default recoverVector points to
RecoverRectangle, which will automatically recover the foreground screen
from the background buffer. However, if the application is using background
buffer for data, it will need to intercept the recover by placing the address of its
own recover routine in recoverVector. If there is no shadow on the dialog box,
then recoverVector is only called through once with r2-r4 holding the
coordinates of the dialog box rectangle. However, if the dialog box has a
shadow, then recoverVector will be called through two ♦imes: first for the
patterned shadow rectangel and second for the dialog box rectangle. The
application may want to special-case these two recovers when recovering.
If recoverOnce is set to TRUE, RstrFrmDialog will only call through
recoverVector once as if there were no shadow box (even if there is one).
RstrFrmDialog automatically calls RestoreSysRam.
RstrFrmDialog restores the sp register to value it contained at the call to
DoDlgBox just before returning. This allows RstrFrmDialog to be called witii
an arbitrary amount of data on top of the stack (as would be the case if called from
within a subroutine). GEOS will restore the stack pointer properly.
DoDlgBox, InitForDialog, RestoreSysRam, RecoverRectangle,
RestoreFG.
247
Apple:
Note:
Example:
See also:
SaveFG (Apple)
graphics/utility I
Function: Saves a portion of the foreground screen to a buffer.
Parameters: rO FGSTRUCT — pointer to an FG data structure (word).
rl FGBUF — pointer to buffer to place foreground data (word).
Returns: Buffer pointed to by FGBUF contains foreground data in a form that
RestoreFG can restore.
Destroys: a,x, y, rl-r6.
Description: SaveFG saves a rectangular area of the foreground screen to a temporary buffer.
This buffer can later be restored to the foreground screen with RestoreFG. The
SaveFG and RestoreFG duo allow the application to save and restore areas of
the foreground screen without imprinting them to the background buffer. This
capability lets the application use the background buffer for data while still using
dialog boxes and menus, which depend on recovering from the background
buffer. The application need only saveFG the proper areas of the screen prior to
putting up a dialog box or letting a menu drop, patch into recoverVector, and
RestoreFG as necessary.
FGSTRUCT points to an FG data structure, which is in the following format:
.word XI ;pixelx-position of left edge
.byte Yl ;pixel y-position of top edge
.word X2 ;pixel x-position of right edge (XI + WIDTH)
.byte HEIGHT ;pixel height (Y2 - Yl)
The amount of data stored into the buffer at FGBUF depends on die size of the
saved region. The following relationship applies:
bufBytes = HEIGHT ♦ (Xl/7 - X2/7 +1)
Most GEOS applications will reserve 5,712 bytes for the save buffer, which will
hold the largest standard dialog box or about three levels of submenus.
Note: It is useful to set recoverOnce to TRUE when using SaveFG, which will
cause dialog boxes witii shadows to only call through recoverVector once,
rather than the noraial twice.
Example:
See also: RecoverFG.
246
SaveFile
SaveFile (Apple, C64, cns)
high-level diskj
Function:
Parameters:
Uses:
General purpose save file routine that will create a GEOS sequential file and save
a region of memory to it or create an empty GEOS VLIR file.
r9 HEADER — pointer to GEOS file header for file. The first two bytes of
the file header point to the filename (word).
rlOL DIRPAGE — GEOS directory page to begin searching for fiee directory
slot; each directory page holds eight files and corresponds to one
notepad page on the GEOS deskTop. The first page is page one.
curDrive
year, month, day, hours, minutes
for date-stamping file.
Commodore:
curType
interleave^
GEOS 64 vl.3 and later for detecting REU shadowing,
desired physical sector interleave (usually 8);. applications
need not set this explicitly — will be set automatically by
internal GEOS routines.
Returns:
Alters:
Apple;
RWbank
curKBlkno
curVBlknot
VBMchangedt
numVBMBikst
source bank for sequential data and HEADER (MAIN or
AUX).
current directory,
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
r9 pointer to fileHeader, which contains file header block as written to
disk.
Commpdorg;
r6 pointer to fileTrScTab, which contains track/sector table for the file.
dirEntryBuf
diskBlkBuf
curDirHead
Commodore:
fileTrScTab
dir2Headt
dir3Headt
contains newly-built directory entry.
used for temporary storage.
this buffer contains die current directory header.
Contains track/sector table for file as returned from
BlkAUoc. The track and sector of the file header block is at
fileTrScTab+O and fileTrScTab+1. The end of the table
is marked with a track value of $00.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
Applg:
247
SaveFile
INDEXBLOCKBUFt index block for chain as created by BlkAlloc (in
auxiliary memory; see BlkAlloc for information on
accessing it).
^used internally by GEOS disk routines; applications generally don't use.
Destroys: Commodore:
a, y, r0-r8.
Apple:
a, y, rl-r8.
Description: SaveFile is the most general -pupose write data type routine in GEOS. It creates
a new file, either sequential or VLIR. If the file is a sequential file, it will write
out the range of memory specified in the header to disk. If the file is a VLIR file,
it will create an empty file (just a file header and an index table; all records in the
index table are marked as unused).
Not only does the file header pointed to by HEADER act as a prototype for the
file, it also holds all the information needed to create the file. This includes the file
type (SEQ or VLIR) and other pertinent information, such as the start and end
address, which are used when creating a sequential file. The file header pointed to
by HEADER has one element, however, that is changed before it is written to
disk: the first word of the fileheader points to a null-terminated filename string.
SaveFile patches this word in its own copy in fileHeader before it is written to
disk.
SaveFile calls SetGDirEntry and BlkAlloc to construct the basic elements of
the file, then calls WriteFile to put die data into it. After the file is written, the
BAMA^BM is written to disk (PutDirHead under Commodore GEOS;
PutVBM under Apple GEOS.)
Example:
See also: GetFile, GpenRecordFile.
248
SaveFontData
SaveFontPata (Apple)
text!
Function:
Parameters:
Returns:
Uses:
Destroys:
Description:
See also:
Example:
Save internal font data to saveFontTab.
none.
nothing.
curHeight
baselineOffset
cardDataPntr
curlndexTable
curSetWidth
a, X.
SaveFontData saves the internal font variables to the area at saveFontTab.
This allows a font to be temporarily changed and then restored. saveFontTab is
FONTLEN bytes long.
RestoreFontData.
249
SetAlarm
SetAlarm (Apple)
clock driver
Function: Qock driver routine to set the clock's alarm time.
Parameters: rOL HOUR — hour (0-23) (byte),
rOH MINUTE — minute (0-59) (byte).
Returns: nothing.
Alters: alarmOn %10000000 (alarm enabled but not triggered).
Destroys: assume a, x, y, r0-rl5.
Description: SetAlarm is a clock driver routine for setting a new alarm time. Most clock
drivers do no error checking on the parameters and expect valid values.
Note: To be sure the alarm is triggered correcdy, disable interrupts around the call to
SetAlarm.
See also: ResetAIarm, SetTimeDate, Clocklnt, ReadClock.
250
SetDevice
SetDevice (C64, cns)
high'level disk|
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Note:
Establish communication with a new peripheral (disk or printer).
a DEVNUM — DRIVE^A through DRIVE D for disk drives,
PRINTER for serial pnhtcr, or any other valid serial device bus
address (byte).
curDevice currcndy active device.
X error ($00 = no error).
curDevice
curDrive
curType
a. y.
new current device number.
new current drivcnumber if device is a disk drive.
GEOS vl.3 and later: current drive type (copied from
driveType table).
SetDevice changes the currcndy active Commodore device and is used primarily
to switch from one disk drive to another. SetDevice also allows a printer driver
to gain access to the serial bus.
Each I/O device has an associated device number that distinguishes its I/O from
the I/O of other devices. At any given time only one device is active. The active
device is called the current device and to change the current device an application
calls SetDevice.
Because SetDevice was originally designed to switch between serial bus
devices, DEVN^Af reflects the architecture of Commodore serial bus: disk drives
arc numbered 8 through 1 1 and the printer is numbered 4. However, not all I/O
devices are actual serial bus peripherals. A RAMdisk, for example, uses a special
device driver to make a cartridge port RAM-expansion unit emukte a Commodore
disk drive. SetDevice switches between these devices just as if they were daisy-
chained off of the serial bus.
Commodore GEOS up through vl.2 supports two disk devices, DRIVE A and
DRIVE B. Commodore GEOS vl.3 and later supports up to four disk devices,
DRIVE^A through DRIVE^D, within the Kemal disk routiines but not from the
dcskTopT (The current version of the deskTop will never pass numDrives with
a value greater than two.) GEOS always addresses the first drive as DRIVE^A,
the second as DRIVE_B, and so on regardless of the physical device settings?
Because most printers attach to the Commodore through the serial port, printer
drivers wUl call SetDevice with a DEVNUM value of PRINTER to make the
printer the active device.
SetDevice calls ExitTurbo to ensure that the old device is no longer actively
sensing the serial bus then rearranges the device drivers as necessary to make the
new device {DEVNUM) the current device. Witii more than one type of device
attached (e.g., a 1541 and a 1571), Commodore GEOS must switch the internal
device drivers, making die the driver for die selected device active. GEOS stores
251
SetDevice
inactive device drivers in the Conunodore 128 back RAM and in special system
areas in an REU. For these reasons it is important that Commodore GEOS
applications use SetDevice to change the active device. An application should
never direcdy modify curDrive or curDevice.
Apple: SetDevice does not exist in Apple GEOS because die task of switching between
devices is not complicated by daisy-chained I/O devices and inactive device
drivers (as it is on the Commodore computers). To specify a new disk drive,
store the new drive number diiecdy into curDrive.
To make porting disk routines easier, the following Apple equivalent of
SetDevice can be used:
.if (APPLE) /Apple GEOS SetDevice equivalent
SetDevice:
sta curDrive ;make the requested drive current
Idx #NO_ERROR ;and return a good status
rts
•endif
See also: OpenDisk, ChangeDiskDevice.
252
9
SetGDirEntry (Apple, C64, cus)
mid-levd disk
Function: Builds a system specific directory entry from a GEOS file header, date-stamps it,
and writes it out to the current directory. Apple GEOS version will also create and
write out subdirectories.
Parameters: rlOL DIRPAGE — directory page to begin searching for free slot; each
directory page holds eight files and corresponds to one notepad page on
the GEOS deskTop. The first page is page one.
r2 NUMBLOCKS — number of blocks in file (word).
r6 TSTABLE — pointer to a track/sector list of unused blocks (unused but
allocated in the BAM), usually a pointer to fileTrScTab; BlkAUoc
can be used to build such a list (word).
r9 FILEHDR — pointer to GEOS file header (word).
Apple;
r2 NUMBLOCKS — number of blocks in file or $(XXX) to create a
subdirectory (word).
r6 INDXBLK — If creating a file: block number of sequential-file index
block or VLIR master index block. If creating a subdirectory: key block
of subdirectory (word).
r7 FILEB YTES — number of bytes in file (word).
r8 HDBLKNUM — block number of this file's header block (word).
r9 FILEHDR — if creating a file, pointer to GEOS file header, if creating a
subdirectory, pointer to 16-character max. null-terminated name for
subdirectory (16 characters including NULL) (must be in main
memory) (word).
Uses:
curDrive
year, month, day, hours, minutes
for date-stamping file.
curType
curDirHead
dir2Headt
dir3Headt
interleave^
GEOS 64 vl.3 and later, for detecting REU shadowing,
this buffer must contain die current d^ectory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
desired physical sector interleave (usually 8);. applications
need not set this explicitiy — will be set automatically by
internal GEOS routines. Only used when new directory
block is allocated
Returns:
Apple:
curKBIkno
curVBlknot
VBMchanged^
numVBMBlkst
cunent directory,
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($(X) = no error).
253
SetGDIrEntry
Commodore:
r6 pointer to first non-reserved block in track/sector table (SetGDIrEntry
reserves.one block for the file header and a second block for the index
table if the file is a VLIR file).
Appig;
rl
rlOL
rlOH
block number that directory entry was added to.
directory page actually used.
unused directory entry within block in diskBIkBuf. There are 13
directory entries per ProDOS block, numbered 1-13.
Alters:
Destroys:
dirEntryBuf
diskBIkBuf
Commodore:
a, y, rO-rS, r7-r8.
contains newly-built directory entry,
used for temporary storage of the directory block.
Commodore:
a, y, rl, r3-r5, r7-r8.
Description: SetGDirEntry calls BIdGDirEntry to build a system specific directory entry
form the GEOS file header, date-stamps the directory entry, calls
GetFreeDirBlk to find an empty directory slot, and writes the new directory
entry out to disk. The Apple version of SetGDirEntry can also be used to create
subdirectory entries by passing a NUMBLOCKS value of $0000.
Most applications will create new files by calling SaveFile and new
subdirectories by calling MakeSubDir. Both these routines call SetGDirEntry
as part of their normal processing.
Example:
See also:
BIdGDirEntry .
254
SetGEOSDisk
SetGEOSDisk (C64, cns)
high-level disk]
Function:
Convert Commodore disk to GEOS format.
Parameters: none.
Uses:
Returns:
Alters:
curDrive
curType
GEOS 64 vl.3 and later for detecting REU shadowing,
error ($00 = no error).
curDirHead directory header is read from disk.
dir2Headt (BAM for 1571 and 1581 drives only)
dir3Headt (BAM for 1581 drive only)
Destroys: a, y, rOL, rl, r4-r5.
Description:
Apple:
Example:
See also:
SetGEOSDisk converts a standard Commodore disk tinto GEOS format by
writing the GEOS ID string to the directory header (at OFF^GEOS ID) and
creating an off-page directory block. An application can call SetGEOSCisk after
OpenDisk returns the isGEOS flag set to FALSE. Typically the user is
prompted before the conversion.
SetGEOSDisk expects the disk to have been previously opened with
OpenDisk. It first calls GetDirHead to read the directory header into memory
then calls CalcBlksFree to to see if there is block available for the off-page
directory (if there isn't, an INSUFFICIENT^SPACE error is returned).
SetNextFree is then called to allocate the off-page directory block. The off-page
directory block is written with empty directory entries and a pointer to it is placed
in the directory header (at OFF^OP TR SC). Finally PutDirHead is called to
write out the new BAM and directoryTieader.
All ProDOS disks are already GEOS compatible.
ChkDkGEOS.
255
SetLdVars
SetLdVars (Apple)
mid-level disk I
Function:
Parameters:
Sets the internal "Ld" variables (those used by LdAppI, LdDeskAcc, and
LdFile).
rOL LOAD.OPT:
bitO: load at address specified in file header, application will be
started autmadcally
1 load at address in r7; application will not be started
automatically,
bit?: not passing a data file.
1 r2 and r3 contain pointers to disk and data file names,
bit 6: not printing data file.
printing data file; application should print file and exit
r7 LOAD.ADDR — optional load address, only used if bit of
LOADJ)PT is set (word).
r2 DATA^DISK — only valid if bit 7 or bit 6 oiWADJ)PT is set: pointer
to name of the disk tiiat contains the data file, usually a pointer to one of
the DrxCurDkNm buffers (word).
DATA^FILE — only valid if bit 7 or bit 6 olLOADJ)PT is set: pointer
to name of the data file (word).
RECVR^OPTS (byte).
Returns:
Destroys:
Description:
Note:
r3
rlOL
nothing.
SetLdVars sets the internal load variables from GEOS pseudoregisters.
GetFile, LdApplic, LdDeskAcc, and LdFile call SetLdVars as necessary.
Most applications will not need to call it direcdy.
LdDeskAcc does not properly set the internal "Ld** variables when it is called
direcdy (as opposed to indirecdy through GetFile, in which case the variables
are set properly). SetLdVars may be used to properly set the internal "Ld"
variables prior to calling LdDeskAcc.
See also: GetLdVars.
256
COKTIDCNTIAL
SetMode
SetMode (Apple)
printer driver |
Function: Set printer mode.
Parameters: rO-r2L MODE — flags for possible printer modes and capabilities (five bytes).
Returns: x STATUS — printer error code; $00 = no eiror (byte)
Destroys: assume r0-r4.
Description: SetMode allows an application to access special printer capabilities. Features are
selected through five MODE bytes. The bits in the MODE bytes correspond to the
list of available features returned by GetMode.
SetMode operates intelligently. It first compares the requested MODE setting
against the current state of the printer. If a bit setting is different and the driver
supports the associated feature, then the proper codes are sent to the printer to
establish the new mode.
TheA/OPgVaiyes;
bit
description
b7
^underiine.
b6
tbold.
b5
reverse.
M
^italic.
b3
outline.
b2
tsuoerscript
bl
^subscript
bO
reserved for future use.
(text density selection)
bit description
b7
^pica type (10 cpi).
b6
^elite type (12 cpi).
b5
^condensed type (16 cpi).
b4
^proportional type.
b3
^double heishL
b2
^f-heisht
bl
^eisht lines per inch vertical density.
bO
^six lines per inch vertical density.
rOH:
rlL:
(miscellaneous features)
bit description
257
SetMode
b7
print red or masenta.
b6
print yellow.
b5
print blue or cyan.
M
^expanded (double-widih) type.
b3
^NLO (near letter quality) type.
b2
reserved for future use.
bl
reserved for future use.
bO
reserved for future use.
(internal font selection)
bit description
b7
font?.
b6
font 6.
b5
fonts.
b4
font 4.
b3
font 3.
b2
font 2 (Roman?).
bl
font 1 (Helvetica?).
bO
font (Courier?).
(hoTizontal graphics density selection)
bit description
b7
60 dpi.
b6
^SOdpi.
b5
90 dpi.
b4
120 dpi.
b3
180 dpi.
b2
300 dpi.
bl
360 dpi.
bO
reserved for future use.
^This feature implemented in most Berkeley Softworks printer drivers.
Note: Most printer drivers only support a small subset of these features even if the
printer they are driving supports more.
Example:
See also: GetMode, SetNLQ.
258
SetMouse
ISetMouse (Ci28)
input driver
Function:
Input device scan reset.
Parameters:
none.
Returns:
nothing
Destroys: assume a, x, y, r0-rl5
Description: GEOS 128 calls SetMouse during Interrupt Level, immediately after the
keyboard is scanned for a new key, to reset the pot (potentiometer) scanning lines
so that they will recharge with the new value of. It is primarily of use with the
Commodore 1351 mouse, which requires having the pot lines reset regularly.
Other input drivers will have a SetMouse routine that merely performs an rts.
An application should never need to call SetMouse.
See also: SIowMouse, UpdateMouse, InitMouse, KeyFilter.
259
SetMsePic
SetMsePic (Apple, cns)
sprite/mouse!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
Uploads and pre-shifts a new mouse picture for the software sprite handler.
rO MSEPIC —r pointer to 32 bytes of mouse sprite image data or one of the
following special codes:
ARROW Arrow pointer (Apple and C128)
HOURGLASS Busy (Apple only)
nothing.
a, X, y, r0-rl5
The software sprite routines used by GEOS 128 in 80-column mode and Apple
GEOS treat the mouse sprite (sprite #0) differently than the other sprites. Sprite
#0 is optimized and hardcoded to provide reasonable mouse-response while
minimizing the flicker typically associated with erasing and redrawing a fast-
moving object. The mouse sprite is limited to a 16x8 pixel image. The image
includes a mask of the same size and both are stored in a pre-shifted form within
internal GEOS buffers. For these reasons, a new mouse picture must be installed
with SetMsePic (as opposed to a normal DrawSprite). SetMsePic pre-shifts
the image data and lets the soft-sprite mouse routine know of the new image.
SetMsePic accepts one parameter: a pointer to the mask and image data or a
constant value for one of the predefined shapes. If a user-defined shape is used,
the data that MSEPIC points to is in the following fonnat:
16 bytes
16 bytes
16x8 "cookie cutter" mask. Before drawing the software mouse sprite,
GEOS and*s this mask onto the foreground screen. Any zero bits in the
mask, clear the corresponding pixels. One bits do not'affect the screen.
16x8 sprite image. After clearing pixels with the mask data, the sprite
image is or*ed into the area. Any one bits in the sprite image set the
corresponding pixels. Zero bits do not affect the screen.
GEOS treats the each 16-byte field as 8 rows of 16 bits (two bytes per row).
SetMsePic calls HideOnlyMouse.
Put up a new mouse picture
ArrowUp:
LoadW rO, #DnArrow ; point at new image
jsr SetMsePic ; install it
Its
;macro to store a word value in high/low order
.macro , HILO word
.byte J word, [word
• endm
/Mouse picture definition for down-pointing arrow
DnArrow:
260
SetMsePic
;mas)c
HILO %1111111110000000
HILO %1111111001111110
HILXD %0001100111111001
HILO %0110011111100111
HILO %0111111110011111
HILO %01H111110011111
HILO %0111111111101111
HILO %0000000000001111
; image
HILO %0000000000000000
HILO %0000000001111110
HILO %0000000111111000
HILO %0110011111100000
HILO %0111111110000000
HILO %0111111110000000
HILO %0111111111100000
HILO %0000000000000000
See also: TempHideMouse, DrawSprite.
261
SetNewMode
SetNewMode (Ci28)
graphicsj
Function: Changes GEOS 128 from 40-column mode to SO-column mode, or vice-versa.
Parameters: graphMode . GRMODE — new graphics mode to change to:
40-column: GR 40
80-column: GR^80
Returns: nothing.
Destroys: a, x, y, r0-rl5.
Description: SetNewMode changes the operating mode of the Commodore 128.
|40-column mode (graphMode — GR 40)1
1: 8510 clock speed is slowed down to IMhz because VIC chip cannot operate
at2Mhz.
2: rightMargin is set to 319.
3: UseSystemFont is called to begin using the 40-column font
4: 40-column VIC screen is enabled.
5: 80-column VDC screen is set to black on black, effectively disabling it
Example:
180-column mode (graphMode == GR sUTl
1: 8510 clock speed is raised to 2Mhz.
2: rightMargin is set to 639.
3: UseSystemFont is called to begin using die 80-column font
4: 40-column VIC screen is disabled
5: 80-column VDC screen is enabled
ChangeMode :
jsr
Ida
eor
jsr
jsr
rts
GREYPAT
GreyScreen:
jsr
.byte
.byte
GreyScreen
graphMode
«%10000000
SetNewMode
GreyScreen
;grey out old screen
/switch mode by flipping
; 40/80 bit
;and calling SetNewMode
;grey out new screen
;exit
;grey pattern to use
i_GraphicsString
NEWPATTERN, GREYPAT ;set to grey pattern
MOVEPENTO ;put pen in upper left
262
CONriUENTIAL
SetNewMode
.word »x
.byte ;y
.byte RECTANGLETO ;grey out entire screen
.word (SC_40_WIDTH-1) 1 DOUBLE_W| ADD1_W
.byte SC_PIX_HEIGHT
.byte NULL
rts
263
SetNextFree
SetNextFree (Apple, C64, ci28)
mid-level disk I
Function:
Parameters:
Uses:
Returns:
Alters:
Destroys:
Description:
Search for a nearby free block and allocate it.
r3 block (Commodore track/sector) to begin search (woid).
curDrive
Cpmrnodorp;
curDirHead
dir2Headt
dirSHeadt
interleave^
Apple:
curVBlknot
VBMchangedt
numVBMBlkst
totNumBlockst
this buffer must contain the current directory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
desired physical sector interleave (usually 8);. applications
need not set this explicidy — will be set automatically by
internal GEOS routines.
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines,
for detecting last block on disk.
^used internally by GEOS disk routines; explications generally don't use.
X error ($00 = no error).
r3 block (Commodore track/sector) allocated.
Commp<[OTP;
curDirHead
dir2Headt
dirSHeadt
Apple:
curVBIknot
VBMchangedt
BAM updated to reflect newly allocated block.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
used by VBM cacheing routines.
set to TRUE by VBM cacheing routines to indicate cached
VBM block has changed and needs to be flushed
^used internally by GEOS disk routines; applications generally don't use.
Commodore:
a, y, r6-r7, r8H.
Apple;
a, y, r6, r7, rSH.
Given the current block as passed in r3, SetNextFree searches for the next free
block on the disk. The "next" free block is not necessarily adjacent to the previous
block because SetNextFree may interleave the blocks. Proper interleaving
aUows the drive to read and write data as fast as possible because it minimizes the
time the drive spends waiting for a block to spin under the read/write head. It
means, however, that sequential data blocks may not occupy adjacent blocks on
264
SetNextFree
the disk. As long as an application is using the standard GEOS file structuies, this
interleaving should not be apparent
After determining the ideal sector from any interleave calculations, SetNextFree
tries to allocate the block it if it is unused. If the block is used, SetNextFree
picks another nearby sector (jumping to another track if necessary) and calls tries
again. This process continues until a block is actually allocated or the end of the
disk is reached, whichever comes first. If the end of the disk is reached, an
INSUFFICIENT^SPACE error is returned.
Notice that SetNextFree only searches for free blocks starting with the current
block and searching towards the end of the disk. It does not backup to check
other areas of the disk because it assumes they have abeady been filled. (Actually,
under Commodore GEOS,.SetNextFree will backtrack as far back as beginning
of the current track but will not go to any previous tracks.). Usually this is a safe
assumption because SetNextFree is called by BlkAlIoc, which always begins
searching for free blocks from the beginning of the disk.
It is conceivable, however, that an application might want to implement an
AppendRecord function (or something of that sort), which would append a
block of data to an already existing VLIR record without deleting, reallocating,
and then rewriting the record like WriteRecord.
In order to maintain any interleave from the last block in the record to the new
block, the AppendRecord routine passes the track and sector of the last block in
the record to SetNextFree. SetNextFree will start searching from this block.
If a free block cannot be found, an INSUFFICIENT SPACE error is
returned. Since SetNextFree only searched from the currenttlock to the end of
the disk, the possiblility exists that a free block lies somewhere on a previous,
still unchecked disk area. The following alternative to SetNextFree will
circumvent this problem:
My Set Next Free:
;Look for a free block starting at the current block
;so that we continue the interleave if possible
jsr SetNextFree ; look for block to allocate
cpx #INSOFFICENT_SPACE ; check for no blocks
beq 10$ /start from beginning if none
rts ;exit on any other error or
; valid block found.
;We got an insufficient space error. Start the search
; again from the beginning of the disk.
10$:
APPLE
LoadW
r3,#0
/start at block
;CBM
LoadB
r3H,#0
/always sector
Idx
#1
/assume track 1
Idy
curDrive
/but special case 1581
Ida
driveType-8,y
/because of outer /inner track
and
#$0f
/searching scheme
cmp
#DRV_1581
bne
20$
/branch if not 1581
Idx
#39
/1581 counts down on inner (39-1)
/then up on outer (41-80)
265
SetNextFree
stx r3L /track number
•endif
jmp SetNextFree ;go search, let it return
C64 & C128: SetNextFree uses the value in interleave to establish the ideal next sector. A
good interleave will arrange successive sectors so as to minimize the time the
drive spends stepping the read/write head and waiting for the desired sector to
spin around. The value in interleave is usually set by the Configure program
and internally by GEOS disk routines. The application will usually not need to
worry about the value in interleave.
Because Commodore disks store the directory on special tracks, SetNextFree
will automatically skip over these special tracks unless r3L is started on one of
these tracks, in which case SetNextFree assumes that this was intentional and a
block on the directory track is allocated. (This is exactly how GetFreeDirBlk
operates.) The directory blocks for various drives can be determined by the
following constants:
1S81
DIR
1581 TRACK
(one track)
1541
DIR
TRACK
(one track)
1571
DIR
TRACK
(two tracks)
DIR"
:track+n_tracks
SetNextFree does not automatically write oiit the BAM. See PutDirHead for
more information on writing out the BAM
Apple: The Apple version of SetNextFree does no interleave calculations because
ProDOS devices handle physical interleaving when they map block numbers to
physical sectors. SetNextFree on the Apple merely increments the block
number.
SetNextFree does' not automatically flush tiie VBM cache. 3ee PutVBM for
more information on flushing the cache.
Example:
See also: AllocateBIock, FreeBiock, BlkAlloc.
266
SetNLQ
SetNLQ (C64, C128)
printer driver |
Function: Enter high-quality printing mode.
Parameters: rl
WORKBUF — pointer to a 640-byte work buffer for use by the printer
driver (word).
Returns: nothing.
Destroys: assume a, x, y, r0-rl5.
Description: SetNLQ sends the appropriate control codes to place the printer into high-quality
print mode (as opposed to the default draft mode). SetNLQ is called after
StartASCn has been called to enable text output
See also:
StartASCII, PrintASCII, SetMode.
267
SetPattern
SetPattern (Apple, C64, cns)
graphics]
Function:
Parameters:
Returns:
Alters:
Destroys:
Description:
Apple:
Example:
See also:
Set the current fill pattern.
a GEOS system pattern number (must be between and 3 1 ) (byte),
nothing.
curPattern Contains an address pointing to the eight-byte pattern,
a
Sets the current fill pattern. There are 34 system patterns (numbered 0-33) in
GEOS 64 and GEOS 128; Apple GEOS adds a 35th, user-defined pattern
(number 34). Unfortunately, SetPattern will only work correcdy with patterns
numbered 0-31. To access higher number patterns, call SetPattern with a value
of 31 and add 8 to curPatttern to access pattern 32, add 16 to access pattern 33,
and so on.
Although curPattern will contain a valid address, it is an address in auxiliary-
high memory, and this memory bank is all but inaccessible to user applications.
Use GetPattern and SetUserPattern to access the pattern data.
GetPattern, SetUserPattern.
268
SetTimeDate
SetTimeDate (Apple)
clock driver I
Function: Qock driver routine to set the clock's time and date.
Parameters: rOL YEAR — ^.current year (calendar year -19(X)) (byte).
rOH MONTH — current month (Q-12) (byte).
rlL DAY — day of month (1-28, 29, 30, 3 1) (byte).
rlH HOUR — hour (0-23) (byte).
r2L MINUTE — minute (0-59) (byte).
r2H SECOND — seconds (0-59) (byte).
Returns: nothing.
Destroys: assume a, x, y, r0-rl5.
Description: SetTimeDate is a clock driver routine for setting a new time and date. Most
clock drivers do no error checking on the parameters and expect valid values
(passing a nonexistent day in a month is a no-no).
Note: To be sure the time is set correctly, disable interrupts around the call to
SetTimeDate.
See also: ReadClock, Clocklnt, SetAlarm, ResetAIarm.
270
SetUserPattern
ISetUserPattern (AppieT
graphics]
Function:
Parameters:
returns:
Alters:
Destroys:
Description:
Example:
See also:
Upload an cight-byte pattern definition to a GEOS system pattern.
a GEOS system pattern number to alter.
rO pointer to eight-byte pattern definition (word).
nothing.
curPattern
a,y
altered so that the new pattern becomes the current pattern.
rO is unchanged.
SetUserPattern uploads an eight-byte pattern definition to the system pattern
space in auxiliary high memory. This is the only convenient way to modify the
system pattern definitions under Apple GEOS.
GetPattern, SetPattern.
271
Sleep
Sleep (Apple, C64, C128)
process
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Pause execution of a subroutine ("go to sleep") for a given time interval.
rO DELAY — number of vblanks to sleep (word),
nothing: does not return direcdy to caller (see description below).
a,x, y
Sleep stops executing the current subroutine, forcing an early rts to the routine
one level lower, essentially putting the current routine "to sleep." At Interrupt
Level, the DELAY value assocated with each sleeping routine is decremented.
When the the DELAY value reaches zero, MainLoop- removes the sleeping
routine from the sleep table and perfomrs a jsr to the instruction following the
original jsr Sleep, expecting a subsequent rts to return control back to
MainLoop. For example, in the normal course of events, MainLoop might call
an icon event service routine (after an icon is clicked on). This service routine can
perform a jsr Sleep. Sleep will force an early rts, which, in this case,
happens to return control to MainLoop. When the routine awakes (after DELAK
vblanks have occurred), MainLoop performs a jsr to the instruction that follows
tiie original jsr Sleep. When this wake-up jsr occurs, it occurs at some later
time the contents of the processor registers and GEOS pseudoregisters are
uninitialized. A subsequent rts will return to MainLoop.
Sleeping in Detail:
\: The application calls Sleep with a jsr Sleep. The jsr places a return
address on the stack and transfers the processor to the Sleep routine.
2: Sleep pulls the return address (top two bytes) from the stack and places those
values along with the DELAY parameter in an internal sleep table.
4: Sleep exectues an rts. Smce the original caller's return address has been
pulleid from the stack and saved in the sleep table, this rts uses the next two
bytes on the stack, which it assunxs comprise a valid return address. (Note: it
is imperitive that tiiis is in fact a return address; do not save any values on die
stack before calling Sleep.)
5: At Interrupt Level GEOS decrement sthe sleep timer until it reaches zero.
6: On every pass, MainLoop checks the sleep timers. If one is zero, then it
removes that sleeping routine from the table, adds one to the return address it
pulled from the stack (so it points to the instruction following the
jsr Sleep), and jsr's to this address. Because no context information is
saved along with the sleep address, the awaking routine cannot depend on any
values on the stack, in the GEOS pseudoregisters, or in the processor's
registers.
A DELAY value of $0(XX) will cause the routine to sleep only until the next pass
through MainLoop.
CONflDENTIAL
272
Sleep
When debugging an application, be aware that Sleep alters the nonnal flow of
control-
Example:
See also: InitProcesses*
273
SlowMouse
SlOWMOUSe (Apple, C64, C128) input driver|
Function: Kills any accumulated speed in a non-proportional input device.
Parameters: none.
Returns: nothing
Alters: internal input-driver speed variables, if any.
Destroys: assume a, x, y, rO-rlS
Description: Input drivers for non-proportional input devices, such as a joystick, will often
internally associate a speed and velocity with movement This way the pointer can
speed up when the user is trying to move large distances. SlowMouse will tell
the input driver to kill any accumulated speed, effectively stopping the pointer at a
specific location and forcing it to regain momentum. Depending on the input
driver, SlowMouse may or may not have an effect on the pointer's movement
The standard mouse driver, for example, simply performs an rts but some other
input driver may actually copy the value in minMouseSpeed to its own internal
speed variable.
GEOS calls SlowMouse when it drops menus down. A driver that has velocity
variables should adjust the current speed so that the pointer does not immediately
jump off Ae menu. An application may want to call SlowMouse when the user
is required to make precise movements.
See also: UpdateMouse, InitMouse, SetMouse, KeyFilter.
274
SmailPutChar
ISmallPutChar (Apple, C64, cns)
text!
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Print a single character without the PutChar overhead
a CHAR — character code (byte).
r 1 1 XPOS — x-coordinate of left of character (word).
rlH YPOS — y-coordinate of character baseline (word).
same as PutChar.
rl 1 x-position for next character.
rlH unchanged
CpmmodQT?;
a, X, y, rlL, r2-rl0, rl2, rl3
Apple:
a, x, y, rlL, r2
SmailPutChar is a bare bones version of PutChar. SmailPutChar will not
handle escape codes, does no margin faulting, and does not normalize the x-
coordinates on GEOS 128.
SmailPutChar will assume the character code is a valid and printable character
Any portion of the character that lies above windowTop or below
windowBottom will not be drawn. If a character lies partially outside of
leftMargin or rightMargin, SmailPutChar will only print the portion of the
character lies within the margins. SmailPutChar will also accept small negative
values for the character x-position, allowing characters to be clipped at the left
screen edge.
Partial character clipping at die left margin, including negative x-postion clipping,
is not supported by early versions of GEOS 64 (earlier than vl.4) — the entire
character is clipped instead. Full left-margin clipping is supported on all other
versions of GEOS: GEOS 64 vl.4 and above, GEOS 128 (both in 64 and 128
mode), and Apple GEOS.
Like PutChar, 159 is the maximum CHAR value tfiat SmailPutChar will
handle correctiy. Most fonts will not have characters for codes beyond 129.
PutChar, PutString.
r J
275
SoftSprHandler
SoftSprHandler (Apple)
sprite
Function: Software. sprite handler.
Parameters: none.
Uses:
Returns:
Alters:
Destroys:
Description:
Note:
mobenble
moby2
niobx2
reqlxpos-reqTxpos
moblypos-mob7ypos
nothing.
of f Fla g $40 Flag to Redraw mouse at next interrupt,
a, X, y, r0-rl5
SoftSprHandler is the routine MainLoop calls to update die software sprites.
This involves redrawing them if diey have been temporarily removed (by a call to
TempHideMouse, perhaps) or erasing and redrawing them if they have moved.
An application will normally have no need to call this routine direcdy, assuming
MainLoop is being returned to normally.
This is where sprites are physically repositioned. A call to PosSprite, for
example, only updates the reqXposN and mobNYpos request position
variables associated with the sprite. The actual physical position does not change
until SoftSprHandler is called (usually at MainLoop) to redraw the sprites.
SoftSprHai\.dIer draws higher numbered sprites first so that sprites with lower
numbers will appear on top of sprites with higher numbers. Sprite #5, for
example, will appear on top of sprite #4 when they are drawn together.
SoftSprHandler does not use reqXposO and mobOypos because the mouse
sprite is redrawn at intenrupt level.
See also: TempHideMouse, HideOnlyMouse.
276
SortAlpha
SortAlpha (Apple)
utility
Function: Casc-inscnsitive alphanumeric sort
Parameters: rO LIST — pointer to unsorted list (word).
rl NUMRECS — number of 16-byte records in the list
Returns: list sorted
Destroys: a, x, y, rl-r4.
Description:
Note:
SortAlpha sorts an arbitrarily large list of 16-byte ASCII records. The record
size is currendy fixed at 16-bytes (the number of characters in a GEOS filename),
although future versions of Apple GEOS will probably make the record size
variable.
SortAlpha uses a selection sort algorithm, which works well with small records
and has a running time proportional to NUMREC^. SortAlpha ignores letter
case in its comparisons.
SortAlpha correctiy handles the trivial cases where NUMRECS is either zero or
one.
Example:
REC_SI2E — 16
LoadW
LoadW
jsr
rts
/always 16 in Apple GEOS vl.O
rO^lData ;point to record list
rl,#NDM_RECS /number of records to sort
SortAlpha :qo sort them
;exit
Data:
.byte "ZETA "
.byte -0123456789ABcDeF'«
.byte "gAMma over beta **
.byte "stewardesses "
.byte -123ABC123abc
.byte "abcdefghi jklmnop"
.byte ••qrstuvwxy2012345''
.byte "stewardess *"
.byte "beta
.byte "alpha "
.byte "delta "
.byte "steward
NUM^RECS - ((*-Data)/REC_SIZE)
.if"" ( (Data + NUM_RECS*REC_SIZE) !- *)
.echo Something is wrong with sort data
.endif
277
StartAppI (Apple, C64, C128)
mid-level disk!
Function: Warmstart GEOS and start an application that is already loaded into memory.
Parameters: These are all passed on to the application being started.
rOL
Tl
r3
START.ADDR — start address of application (word).
OPTIONS :
bit?: not passing a data file.
1 r2 and r3 contain pointen to disk and data file names,
bit 6: not printing data file.
printing data file; application should print file and exit
DATA^DISK — only valid if bit 7 or bit 6 of OPTIONS is set: pointer
to name of the disk that contains the data file, usually a pointer to one of
the Dr;cCurDkNm buffers (word).
DATA.FILE — only valid if bit 7 or bit 6 of OPTION is set: pointer to
name of the data file (word).
Returns:
Passes:
never retutrns.
warmstarts GEOS and passes the following to the application at START^ADDR:
rO as originally passed to StartAppI.
r2 as originally passed to StartAppI (use dataDiskName).
r3 as originally passed to StartAppl.(use dataFileName).
dataDiskName contains name of data disk if bit 7 of rO is set.
dataFileName contains name of data file if bit 6 of rO is set
Alters : GEOS brought to a warmstart state.
Destroys: n/a
Description:
Example:
See also:
StartAppI warmstarts GEOS and jsr's to START_ADDR as if the application
had been loaded from the deskTop. GetFile and LdAppIic call StartAppI
automatically when loading an application.
StartAppI is useful for bringing an application back to its startup state. It
completely warmstarts GEOS, resetting variables, intializing tables, clearing the
processor stack, and executing the application's initialization code with a jsr from
MainLoop.
LdAppIic, GetFile, WarmStart.
282
StartASCII
StartASCII (Apple, C64, cm)
printer driver I
Function: Enable ASCII text mode printing.
Parameters:
Commodore
rl WORKBUF — pointer to a 640-byte work buffer for use by the printer
driver.(word). PrintASCII uses this work area as an intermediate
buffer, the buffer must stay intact throughout the entire page.
Apple
none.
Returns:
Destroys:
STATUS — printer error code; $00 = no error.
Description:
Commodore
assume a, y, r0-rl5.
Applg
assume a, y, r0-r4.
StartASCII enables ASCII text mode printing. An application calls
StartASCII at the beginning of each page. It assumes that InitForPrint has
already been called to initialize the printer.
C64 & C128: StartASCII takes control of the serial bus by opening a fake Commodore file
structure and requests the printer (device 4) to enter listen mode. It then sends the
proper control sequences to place the printer into text mode.
Apple:
Example:
StartASCII sends the proper control sequences to place the printer into ASCII
mode. It reestablishes the proper text mode as set by SetMode, but it does not
reset the printer. This allows an application to mix graphics and ASCII text on the
same page.
See also: PrintASCII, StopPrint, StartPrint
279
StartMouseMode
StartMoUSeMode (Apple, C64, C128) mouse/sprite|
Function: Instructs GEOS to start or restart its monitoring of the input device (usually a
mouse but depending on the input driver may be a joystick or other device).
MOUSEX — x-position to start mouse at (word) If this parameter is
$(X)00, then the mouse position is not changed and the mouse velocity is
not altered
MOUSEY — y-position to start mouse at (byte),
cany flag: = same as setting MOUSEX to $0(XX).
1= no effect
Parameters: rll
y
St
loaded with address of SystemMouseService.
loaded with address of SystemFaultService.
$00
MOUSEON^BIT set by MouseUp.
sprite #0 bit set by MouseUp.
Destroys: a, x, y, r0-rl5
Description: StartMouseMode Instructs GEOS to start or restart its monitoring of the input
device. Most normal GEOS applications will not need to call this routine because
it is called internally by both DoMenu and Dolcons. If an application is not
using icons nor menus, it should call StartMouseMode during its initialization.
StartMouseMode does the following:
1: If the carry flag is set and the MOUSEX parameter is non-zero, then
MOUSEX is copied into mouseXPos, AfOt/5£y is copied into
mouseYPos, and the input driver SlowMouse routine is called. If running
under GEOS 128, MOUSEX is first passed through NormalizeX before
getting loaded into mouseXPos.
Alters: mouseVector
mouseFauItVec
faultData
mouseXPos
mouseYPos
mouseOn
mobenble
2: The address of the internal SystemMouseService routine is loaded into
mouseVector and the address of the internal SystemFaultService routine
is loaded into mouseFauItVec.
3: A $00 is stored into faultData, clearing any mouse faults.
4: MouseUp is called to enable the mouse.
64 & 128: If the mouse will be repositioned, then disable interrupts around the call to
StartMouseMode. It is not necessary to disable intermpts under Apple GEOS.
Example:
/Intialize the mouse and start it at screen center
Mouselnit:
LoadW rllr#(SC_PIX_WIDTH/2) ; screen center
Idy * (SC_PIx2hEIGHT/2)
sec ;set to move mouse
.if (C64 I I C128)
278
StartMouseMode
php
sei
jsr StartMouseMode
pip
•else ; (APPLE)
jsr StartMouseMode
.endif
rts
See also: ClearMouseMode, MouseUp, MouseOff, SlowMouse, DoMenu,
Dolcons, TempHideMouse, HideOnlyMouse.
279
StartPrint
StartPrint (Apple, C64, ci28)
printer driver |
Function: Enable graphics-mode printing-
Parameters:
CbmmcKjQrp
rl WORKBUF — pointer to a 1,920-byte work buffer for use by the
printer driver. (word). PrintBuffer uses this work area as an
intermediate buffer, this buffer must stay intact throughout the entire
page.
Apple
hone.
Returns:
Destroys:
STATUS — printer error code; $00 = no error.
Description:
assume a, y, r0-rl5.
Apple
assume a, y, r0-r4.
StartPrint enables graphic printing. An application calls StartPrint at the
beginning of each page. It assumes that InitForPrint has already been called to
initialize the printer.
C64 & C128: StartPrint takes control of the serial bus by opening a fake Commodore file
structure and requests the printer (device 4) to enter listen mode. It then sends the
proper control swiuences to place the printer into graphics nxxle.
Apple:
Example:
See also:
StartPrint sends the proper control sequences to place the printer into graphics
mode. It reestablishes the proper graphics mode as set by SetMode, but it does
not reset the printer. This aUows an application to mix ASCII text and graphics on
the same page.
StopPrint, StartASCII.
283
StashRAM
StashRAM (C64 vi.3 & ci28)
memory
Function: Primitive for transferring data to an REU,
Parameters: rO CBMSRC — address in Conimodore to start reading (word).
r 1 REUDST — address in REU bank to put data (word).
r2 COUNT — number of bytes to stash (word),
r3L REUB ANK — REU bank number to stash to (byte).
r0-r3 unchanged.
X error code: $00 (no error) or DEV_NOT_FOUND if bank or REU
not available. "
a REU status byte and'ed with $60 ($40 = successful stash).
Destroys: y
Description: StashRAM moves a block of data from Commodore memory into an REU
bank. This routine is a "use at your own risk" low-level GEOS primitive
StashRAM uses the DoRAMOp primitive by calling it with a CMD parameter
of%10010000.
See also: FetchRAM, SwapRAM, VerifyRAM, DoRAMOp, MoveBData.
Note:
Refer to DoRAMOp for notes and warnings.
Example:
280
This page intentionally left blank to maintain right/left (verso/recto)
page ordering. Final version will correct this.
StatusCard
StatusCard (Apple)
card driver!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Get the current input/output status of the printer card,
none.
X
St
a, y.
STATUS — card error code; $00 = no error (byte)
sign flag: set if card ready to accept output,
carry flag: set if card has input ready.
StatusCard returns information about the current state of the card. The input-
ready and ready-for-output flags are only valid if the card is capable of returning
this type of information. This capability can be checked with a call to InfoCard.
StatusCard must be called after an OpenCard and before a CloseCard.
InfoCard.
284
StopPrint
IStOpPrint (Apple, C64, C128)
printer driver |
Function:
Parameters:
Returns:
Destroys:
Flush output buffer and formfeed the printer (called at the end of each page).
Commodore
rO TEMPBUF — pointer to a 640-byte area of memory that can be set to
$00 (word).
rl WORKBUF — pointer to a 1,920-byte work buffer used by
PrintBuffer (word).
Applg
rlL
Apple
X
FF.SUPPRESS — set to TRUE to suppress automatic formfeed after
flushing the buffer, normally set to FALSE.
STATUS — printer error code; $00 = no enror.
Description:
C64 & C128:
Apple:
Example:
See also:
ComtnwlQrp
assume a, x, y, r0-rl5.
Apple
assume a, y, r0-r4.
StopPrint instructs the printer driver to flush any internal buffers and end the
page.
StopPrint ends both graphic and ASCII printing.
Commodore GEOS printer drivers always formfeed when StopPrint is called.
Apple GEOS printer drivers can suppress the normal StopPrint formfeed,
thereby flushing the print buffers but allowing the application to resume printing
at the cuirent Une. This way ASCII text and graphics can be mixed on a page with
alternating calls to StartASCII. StopPrint, and StartPrint.
StartPrint. StartASCII.
285
SwapBOata
SwapBData (C128) memoryl
Function: Swaps two regions of memory within either front RAM or back RAM (or
between one and the other).
Parameters: rO ADDRl — address of first block in application memory (word).
r 1 ADDRl — address of second block in application memory (word).
r2 COUNT — number of bytes to swap (word).
r3L AlBANK— ADDRl bank: = front RAM; 1 = back RAM (byte).
r3H A2BANK — ADD/?2 bank: = front RAM; 1 = back RAM (byte).
Returns: rO-r3 unchanged.
Destroys: a, x, y
Description: SwapBData is a block swap routine that allows data to be swapped in either
front RAM, back RAM, or between front and back. If the ADDRl and ADDRl
areas are in the same bank and overlap, ADDRl. must be less than ADDRl.
SwapBData is especially useful for swapping data from front RAM to back
RAM or from back RAM to front RAM.
SwapBData uses the DoBOp primitive by calling it with a MODE parameter of
$02.
Note: SwapBData should only be used to swap data within the designated application
areas of memory.
Example:
See also: MoveBData, VerifyBData, DoBOp.
286
SwapMainAndAux
ISwapMainAndAux (Apple)
memory I
Function:
Parameters:
Destroys:
Description:
Example:
See also:
Swaps a block of memory on a byte-by-bytc basis between application main
memory and application aux memory.
r SOURCE — address of block to swap (word).
r2 COUNT— number of bytes to swap (0~48K).
a, y» rO, rlL, r2
SwapMalnAux swaps a block of bytes that lie at the same address in both main
and auxiliary application memory. This is really only useful in the area between
$6000 and $8C<X), where application main and application aux memory occupy
the same address space.
MoveAuxData, MoveBData, SwapBData, SwapRAM.
287
SwapRAM
SwapRAM (C64 vL3 & cns)
memoryl
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Primitive for swapping data between Commodore memory and an REU,
rO CBMADDR — address in Commodore to swap (word),
rl REUADDR — address in REU to swap (word).
r2 COUNT — number of bytes to swap (word).
r3L REUS ANK — REU bank number to fetch from (byte).
r0-r3 unchanged.
X em)rcode: $00 (no error) or DEV^NOT^FOUND if REUBANK
or REU not available. "
a REU status byte and'ed with $60 ($40 = successful swap).
SwapRAM swaps a block of data in an REU bank with a block of data in
Commodore memory. This routine is a "use at your own risk" low-level GEOS
primitive
SwapRAM uses the DoRAMOp primitive by calling it with a CMD parameter
of % 10010010.
Refer to DoRAMOp for notes and warnings.
StashRAM, FetchRAM, VerifyRAM, DoRAMOp, SwapBData.
288
TempHideMouse
TempHideMouse (Apple, ci28)
mouse/sprite]
Function: Temporarily removes soft-sprites and the mouse pointer from the graphics screen.
Parameters: nothing.
Returns:
Uses:
Alters:
Description:
128:
Apple:
Example:
See also:
nothing.
graphMode
offFlag
noEraseSprites
offFlag
(128 only).
(Apple only).
(Apple only).
set to TRUE (Apple only).
Destroys: a, x
TempHideMouse temporarily removes all soft-sprites (mouse pointer and
sprites 2-7) unless they are already removed. This routine is called by all GEOS
graphics routines prior to drawing to the graphics screen so that software sprites
don't interfere with the graphic operations. An application that needs to do direct
screen access should call tins routine prior to modifying screen memory.
The sprites will remain hidden until the next pass through MainLoop.
In 40-column mode (bit 7 of graphMode is zero), TempHideMouse exits
immediately without affecting the hardware sprites.
If bit 7 of offFlag is set, offFlag is set to TRUE (reaffirming the fact that the
sprites and mouse are marked as hidden) and exits without affecting any sprites.
If noEraseSprites is set to TRUE, sprites 2-7 are not erased from the screen.
This is useful for keeping sprites on the screen (and, therefore, avoiding any
flicker) if the application is confident that the graphic operation will not be in the
area of a sprite.
HideOnlyMouse.
289
TestPoint
TeStPoint (Apple, C64, C128)
Function: Test and return the value of a single point (pixel).
Parameters: r3 XI — x-co6ridnate of pixel (word).
rllL Yl — y-coordinate of pixel (byte).
where (XI, Yl) is the coordinate of the point to test.
Uses: dispBufferOn
bit 6 — if set, test pixel in foreground screen,
bit 7 — if set, test pixel in background buffer.
(If both bit 6 and bit 7 are set, then only the pixel in the background
screen is tested.).
Returns: r3, rllL unchanged.
s t carry flag set if point set; cleared if point clear.
Destroys: a, x, y, r5-r6
Description: TestPoint will test a pixel in either the foreground screen or the background
buffer (or both simultaneously) and return the pixel's status by either setting or
clearing the carry (x) flag accordingly. The jsr TestPoint is usually followed
immediately by a bcc or bcs so that a set or clear pixel may be handled
appropriately.
128: Under GEOS 128, or'ing DOUBLE W into the XI will automatically double
the x-position in 80-column mode. 0?ing in ADDl W will automatically add 1
to a doubled x-position. (Refer to "GEOS 128 X-po?ition and Bitmap Doubling"
in Chapter.® gitg) for more information.)
Example:
See also: DrawPoint.
graphics
290
ToBasiC (€64^128)
utility
Function: Removes GEOS and passes control to Commodore BASIC with the option of
loading a non-GEOS program file (BASIC or assembly-language) and/or
executing a BASIC command
Parameters: rO
rS
r7
CMDSTRING — pointer to null-terminated command string to send to
BASIC interpreter.
DIR.ENTRY — pointer to the directory entry of a standard Commodore
file (PRG file type), which itself can be either a BASIC or ASSEMBLY
GEOS-type file. If this parameter is $0000, then no file will be loaded.
LOADADDR — if rS is non-zero, then this is the file load address. For a
BASIC program, this is typically $801. If rS is zero and a tokenized
BASIC program is akeady in memory, then this value should point just
past the last byte in the program. If rS is zero and no program is in
memory, this value should be $803, and the three bytes at $80O-$802
should be $00.
Returns: n/a
Destroys: n/a
Description: ToBasic gives a GEOS application the ability to run a standard Commodore
assembly-language or BASIC program. It removes GEOS, switches in the
BASIC ROM and I/O bank, loads an optional file, and sends an optional
command to the BASIC interpreter.
Once ToBasic has executed, there is no way to return directly to the GEOS
environment unless the RAM areas from $cOOO through $c07f are preserved
(those bytes may be saved and restored later). To return to GEOS, the called
program can execute a jump to $cOOO (BootGEOS).
A program in the C64 environment can check to see if it was loaded by GEOS by
checking the memory starting at $c006 for the ASCII (not CBMASCH) string
"GEOS BOOT'. If loaded by GEOS, the program can check bit 5 of $c012: if
this bit is set, ask the user to insert their GEOS boot disk; if this bit is clear,
GEOS will reboot from the RAM expansion unit To actually return to GEOS, set
CPU DATA to $37 (KRNL BAS 10 IN) and jump to $cOOO
(BootGEOS). - - -
Example:
LoadBASIC:
Loads a Conunodore BASIC program and starts it
running. Assumes that the program is a standard BASIC
file that loads at $801. This example does little
error checking.
Pass:
r5
pointer to BASIC program's directory
entry.
LoadBASIC:
LoadW
LoadW
rO, IRunCommand
r7,#$801
; point at command string
/assume standard address
291
jsr ToBasic
brJc
/expect to not return
/should never get here
/Text command to send to BASIC interpeter so BASIC
/program is started up properly,
RunCommand:
.byte "RUN", NULL
UnblockProcess
lUnblockProcess (Apple, C64, cns)
process!
Function:
Parameters:
Returns:
Destroys:
Description:
Note:
Example:
See also:
Allow a process's events to go through.
X PROXIES S — number of process (0 - n-1, where n is the number of
processes in the table) (byte).
X unchanged
UnblockProcess causes MainLoop to again recognize a process's runable
flag so that if a process timer reaches zero (causing the process to become
runable) an event will be generated
Because the GEOS Intemipt Level continues to decrement the countdown timer as
long as the process is not frozen, a process may become runable while it is
blocked. As long as the process is blocked, however, MainLoop will ignore the
runable flag. When the process is subsequently unblocked, MainLoop will
recognize a set runable flag as a pending event and call the appropriate service
routine. Multiple pending events are ignored: if a blocked process's timer reaches
zero more than once, only one event will be generated when it is unblocked. To
prevent a pending event from happening, use RestartProcess to unblock the
process.
If a process is not blocked an unnecessary call to UnblockProcess will have
no effect
BlockProcess, UnfreezeProcess, EnableProcess, RestartProcess.
293
UnfreezeProcess
UnfreezeProcess (Apple, C64, ci28) processi
Function: Resume (unfreeze) a process's countdown timer.
Parameters: x PROCESS — number of process (0 - where n is the number of
processes in the table) (byte).
Returns: x unchanged
Destroys: a
Description: UnfreezeProcess causes a frozen process's countdown timer to resume
decrementing. The value of the timer is unchanged; it begins decrementing again
from the point where it was frozen. If a process is not frozen, a call to
UnfreezeProcess will have no effect.
Note: If a process is not frozen, a call to UnfreezeProcess will have no effect.
Example:
See also: FreezeProcess, BlockProcess.
294
UpdateMouse
UpdateMouse (Apple, C64, cns)
input driver!
Function: Update the mouse variables based on any changes in the state of the input device.
Parameters: Commodore:
none.
Appig;
St cany flag:
1
interrupt was caused by mouse card
interrrupt was not caused by mouse card
Returns:
Alters:
nothing
mouseXPos
mouseYPos
mouseData
pressFlag
inputData
mouse x-position.
mouse y-position.
state of mouse button: high bit set if button is released; clear
if pressed
MOUSE^BIT and INPUT^BIT set appropriately,
depends on device.
Destroys: assume a, x, y, r0-rl5
Description: GEOS calls UpdateMouse at Interrupt Level to update the GEOS mouse
variables with the actual state of the input device. An application should never
need to call UpdateMouse.
A typical input driver's UpdateMouse routine will scan the device hardware and
update MouseXPos and MouseYPos with new positions if the coordinates
have changed It will also update mouseData with the current state of the input
button (high-bit set if released; cleared if pressed) ani set MOUSE BIT in
pressFlag if the button state has changed since the last call to UpdatelVlouse.
The four byte inputData field, which was originally for device-dependent
information, has adopted the following standard offsets:
inputData+0
(byte) 8-position device direction (joystick direction; mouse
drivers convet a moving mouse to an appropriate direction):
2
3 I 1
6
inputData-f 1 (byte) cuircnt speed (Comnaodore joystick drivers only).
Standard GEOS input drivers should set the INPIIT_BIT of pressFlag if
inputData+O has changed since the last time UpdateMouse was called.
295
UpdateMouse
Because most GEOS applications leave in put Vector set to its default $0000
value, setting this bit will usually have no effect
Apple: The Apple GEOS version of UpdateMouse will treat mouseYPos as a two-
byte value, propagating any underflow into the high-byte at mouseYPos+1.
TTiis gives the subsequent mouse-fault check enough precision to detect whether
the user moved the mouse off the top or the bottom of the screen (a negative
number = off the top edge). The GEOS mouse fault routine will always clear this
high-byte after constraining the mouse to the screen edges.
See also: SIowMouse, InitMouse, SetMouse, KeyFilter.
296
UpdateParent
UpdateParent (Apple)
mid-level disk
Function: Update data om current directory header.
Parameters: a
UPDATE^FLAGS — operations to perform (word).
DEC NUM FILES — decrement file count
INC NUM FILES
MOD DATE
CREATE DATE
DEC DIR BLKS
DEC^DIR^BLKS
— increment file count
— update modification date.
— set creation.
— decrement directory block count
_ — increment directory block count
multiple changes can be made in one call by bitwise or'ing these constants
together.
Uses:
Returns:
Alters:
curDirHead
should contain current directory header.
X
rlOL
error ($00 = no error),
directory page actually used.
curDirHead
diskBlkBuf
contains newly-changed current directory header,
contains newly-changed parent directory header unless
current directory is volume directory (in which case there is
no parent header).
Destroys: a, y, rl, r4, r5.
Description:
UpdateParent upates the current and parent directory headers according to the
flags passed in UPDATEJPLAGS. Whenever a the contents of a subdirectory are
altered — whether adding or deleteing files or other subdirectores — the current
and parent directory headers need to be updated to reflect their new contents. The
high-level GEOS routines will automatically call UpdateParent when they alter
the contents of a subdirectory.
C64 & C128: Commodore GEOS does not support a hierarchical file system.
Example:
297
UpdateRecordFIle
UpdateRecordFile (Apple, C64, cm)
VLIR disk
Function: Update the disk copy of the VLIR index table, BAM or VBM, and otfier VLIR
information such as the file's time/date-stamp. This update only takes place if the
file has changed since opened or last updated.
Parameters: none.
Uses:
Returns:
Alters:
curDrive
fileWrittent
fileHeader
fileSize
dirEntryBuf
if FALSE, no updating occurs because file has not been
written to.
VLIR index table stored in this buffer,
total number of disk blocks used in file (includes index
block, GEOS file header, and all records),
directory entry of VLIR file.
year, month, day, hours, minutes for date-stamping file.
Cpmmodorp;
curType
curDirHead
dir2Headt
dir3Headt
Applg;
fileBytes
curVBlkno*
VBMchanged^
numVBMBlkst
GEOS 64 vl.3 and later, for detecting REU shadowing,
this buffer must contain the current d^tory header.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
total number of bytes in file (written to bytes 254, 255, 511,
and 5 1 2 of the master index block),
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
fileWrittent set to FALSE to indicate that file hasn't been altered since
last updated.
^used internally by GEOS disk routines; applications generally don't use.
Destroys: a, y, rl, r4, r5.
Description:
UpdateRecordFile checks the fileWritten flag. If die flag is TRUE, which
indicates the file has been altered since it was last updated, UpdateRecordFile
writes the various tables kept in memory out to disk (e.g., index table,
B AMA^BM) and time/date-stamps the directory entry. If the fileWritten flag is
FALSE, it docs nothing.
UpdateRecord writes out the index block, adds the time/date-stamp and
(ileSize information to the directory entry, and writes out the new BAM/VBM
witfi a call to PutDirHead or PutVBM (Commodore GEOS and Apple GEOS,
respectively).
298
UpdateRecordFile
C64 & C128: Because Commodore GEOS stores the BAM in global memory, the application
must be careful not to corrupt it before the VLIR file is updated. If the
fileWritten flag is TRUE and the BAM is reread from disk, the old copy (on
disk) will overwrite the current copy in memory. In the normal use of VLIR disk
routines, where a file is opened, altered, then closed before any other disk
routines are executued, ho conflicts will arise.
Example:
See also: CloseRecordFile, OpenRecordFile.
UpDirectory
UpDirectory (Apple)
high-level diskl
Function:
Parameters:
Uses:
Returns:
Alters:
Makes the parent directory the current directory,
none.
curDrive
curKBIkno
current directory.
X error ($00 = no error).
y pathname status ($00 = OK; BFR^OVERFLOW = pathname longer
than pathnameBuO-
curKBIkno
curDirHead
pathnameBur
curDirTabLo^
curDirTabHit
new current directory,
header of new directory.
system pathname buffer updated to reflect new path.
Destroys:
^used internally by GEOS disk routines: applications generally don't use.
a, rOL, rl, r2, r4.
Description: UpDirectory moves up one level in the hierarchical file system, making the
parent directory the current working directory. If UpDirectory is called when
the root directory is active, an AT_ROOT_DER error is returned.
UpDirectory first changes the current key block number, then updates the
pathname in pathnameBuf calling GetPathname if necessary. The current
directory header is read in with a call to GetDirHead
C64 & C128: Commodore GEOS does not support a hierarchical file system.
Example:
See also: SetGDirEntry, DeleteDir.
300
UseSystemFont
lUseSystemFont (Apple, C64, ci28) text|
Function: Begin using default system font (BSW 9)
Parameters: none.
Returns: nothing.
Alters: curHeight height of font
baselineOffset number of pixels fix>m top of font to baseline.
cardDataPntr pointer to current font image data,
cu r In dexTa ble pointer to current font index table.
curSetWidth pixel width of font bitstream in bytes.
Destroys: a» x, y, rO.
Description: UseSystemFont calls LoadCharSet with the address of the always-resident
BSW 9 font. .
128 : In 80-column mode a double-width BSW 9 font is substituted.
Example:
See also: LoadCharSet, LoadAuxSet.
o
301
VerifyBData
VerifyBData (Ci28)
Function: Compares (verifies) two regions of memory against each other. The regions may
either be in firont RAM or back RAM (or one in front and the other in back).
Parameters: rO ADDRl — address of first block in application memory (word).
rl ADDR2 — address of second block in application memory (word).
r2 COUNT — number of bytes to compare/verify (word).
r3L AlBANK— ADD/?7 bank: = front RAM; 1 = back RAM (byte).
r3H A2B ANK — ADDRl bank: = front RAM; 1 = back RAM (byte).
Returns: r0-r3 unchanged.
X $00 if data matches; $ff if mismatch.
Destroys: a, y
Description: VerifyBData is a blpck verify routine that allows the data in one region of
memory to be compared to the data in another region in memory. The regions
may be in either front RAM, back RAM, or in front and back. The ADDRl and
ADDRl areas may overlap even if they are in the same bank.
VerifyBData uses the DoBOp primitive by calling it with a MODE parameter
of $03.
Note: VerifyBData should only be used to compare data within the designated
application areas of memory.
Example:
Ss^^ also: MoveBData, SwapBData, DoBOp.
302
VerifyRAM
VerifyRAM (C64 vu & cns) mtl^
Function: Primitive for verifying (comparing) data in Commodore memory with data in an
REU.
Parameters: rO CBMADDR — address in Commodore to start (word)-
rl REUADDR — address in REU bank to start (word).
r2 COUNT — number of bytes to verify/compare (word).
r3L REUS ANK — REU bank number to compare with (byte).
Returns: r0-r3 unchanged.
X error code: $00 (no error) or DEV_NOT_FOUND if bank or REU
not available. "
a REU status byte and*ed with $60: $40 data match
$20 data mismatch
Destroys: y
Description: VerifyRAM compares a block of data in Commodore memory with a block of
data in an REU bank. This routine is a "use at your own risk" low-level GEOS
primitive
VerifyRAM uses the DoRAMOp primitive by calling it with a CMD parameter
of %10010011.
Note: Refer to DoRAMOp for notes and warnings.
Example:
See also: StashRAM, FetchRAM, SwapRAM, DoRAMOp, VerifyBData.
303
VerticaiLine
VerticalLine (Apple, C64, cns)
graphics
Function:
Parameters:
Draw a vertical line with a repeating bit-pattern.
a eight-bit repeating pattern to use (not a GEOS pattern number).
r4 XI — x-coordinate of line (word),
r3L Yl — y-coordinate of topmost endpoint (byte).
r3 H Y2 — y-coordinate of bottomost endpoint (byte).
where (X1,Y1) and (XI, Y2) define the endpoints of the vertical line.
dispBufferOn:
bit 7 — write to foreground screen if set.
bit 6 — write to background screen if set
r3L, r3H, r4 unchanged.
Commodore:
a, X, y, r5L-r8L
Apple;
a, X, y
Description: VerticalLine sets and clears pixels on a single vertical line according to the
eight-bit repeating pattern. Wherever a 1-bit occurs in the pattern byte, a pixel is
set, and wherever a 0-bit occurs, a pixel is cleared.
Bits in the pattern byte are used top-to-bottom, where bit 7 is at the top.A bit
pattern of % 1 1 1 10000 would create a vertical line like:
Uses:
Returns:
Destroys:
I
i
The pattern byte is always drawn as if aligned to a card boundary. If the
endpoints of a line do not coincide with card boundaries, then bits are masked off
the appropriate ends. The effect of this is that a pattern is always aligned to
specific pixels, regardless of the endpoints, and that adjacent lines drawn in the
same pattern align.
Note: To draw patterned vertical lines using the 8x8 GEOS patterns, draw rectangles of
one-pixel width by calling the GEOS Rectangle routine with identical x-
coordinates.
304
VerWriteBlock
VerWriteBIock (C64, C128) very low-level disk I
Function: Very low-level verify block on disk.
Parameters: rlL TRACK — valid track number (byte).
rlH SE CTO R — valid sector on track (byte).
r4 BUFFER — address of buffer of BLOCKSIZE bytes that contains data
that should be on this sector (word).
Uses: curDrive currently active disk drive.
curType GEOS 64 v 1.3 and later for detecting REU shadowing.
Returns: x error ($00 = no error).
Destroys: a» y.
Description: VerWriteBIock verifies the validity of a recently written block. If the block
does not verify, the block is rewritten by calling WriteBlock. VerWriteBIock
is a low-level disk routine and expects the application to have already called
EnterTurbo and InitForlO.
VerWriteBIock can be used to accelerate die verifies that accompany multiple-
sector writes by first writing all the sectors and then verifying tiiem. This is often
faster than verifying a sector immediately after writing it b5:ause when writing
sequential sectors, the GEOS turbo code will catch the sector interleave. If a
sector is written and then immediately verified, the turbo code will need to wait
for the disk to make one complete revolution before die newly- written sector will
again pass under the read/write head. By writing all the sectors first and catching
the interleave, then verifying all the sectors (again, catching die interleave), the
dead time when the turbo code i:> Waiting for the disk to spin around is
minimized. Many of the higher-level disk routines that write multiple blocks do
just this.
VerWriteBIock is useful for multiple-sector disk operations where speed is an
issue and the standard GEOS routines don't offer a decent solution.
VerWriteBIock can function as the foundation of specialized, high-speed disk
routines.
Note: VerWriteBIock docs not always do a byte-by-byte compare with the data in
BUFFER. Some devices, such as the Commodore 1541, can do a cyclic
redundancy check on the data in the block, and this intemal checksum is sufficient
evidence of a good write. Other devices, such as RAM-expansion units, have
built-in bytc-by-byte verifies.
Apple: VerWriteBIock docs not exist in Apple GEOS. To verify a block, read it into a
general purpose buffer (diskBlkBuf, for example). If the block reads without
an error, it verified. The ProDos device driver does its own checksum on data
blocks, so a bytc-by-byte comparison of the data isn't necessary to determine if
the block was properly written — rereading the block without an error is
sufficient evidence of a good write. See PutBIock for more information.
Example: Sec WriteBlock.
VerWriteBlock
See also: WriteBlock, PutBIock.
307
WarmStart
WarmStart (Apple) Internal
Function: Executes portions of the GEOS warmstart procedure (the same warmstart
executed before a new application, desk accessory, or dialog box is started up).
Parameters: none
Returns: GEOS variables in a warmstart state; stack and application space unaffected
Destroys: a, x, y, r0-r2
Description: WarmStart is part of the GEOS warmstart procedure. It resets some GEOS
variables and data structures (both global and local) to their default state, the state
they are in when an application, desk accessory, or dialog box is started up.
GEOS calls WarmStart internally, and is of Uttie use to an application. An
application that needs to place GEOS in a warmstart state (for restarting, for
example), is better off using StartAppI.
See also: Firstlnit, StartAppI.
308
WriteBiock
WriteBlock (C64, ci28)
very low«level disk]
Function:
Parameters:
Uses:
Returns:
Destroys:
Description:
Apple:
Example:
Very low-level write block to disk.
rlL TRACK — valid track number (byte).
rlH S ECTO R — valid sector on track (byte).
r4 BUFFER — address of buffer of BLOCKSIZE bytes that contains data
to write out (word).
curDrive
curType
currently active disk drive.
GEOS 64 vl.3 and later for detecting REU shadowing.
error ($00 = no error).
a, y.
WriteBlock writes the block at BUFFER to the specified TRACK and
SECTOR. If the disk is shadowed, WriteBlock will also write the data to the
shadow memory. WriteBlock is pared down version of PutBlock. It expects
the application to have already called EnterTurbo and InitForlO, and it does
not vcnfy the data after writing it
WriteBlock can be used to accelerate multiple-sector writes and their
accompanying verifies by writing all the sectors first and then verifying them.
TTiis is often faster than verifying a sector immediately after writing it because
when writing sequential sectors, the GEOS turbo coidc will catch the sector
interleave. If a sector is written and then immediately verified, the turbo code will
need to wait for the disk to make one complete revolution before the newly-
written sector will again pass under the read/write head. By writing all the sex:tors
first and catching the interleave, then verifying all the sectors (again, catchirg tfie
interleave), the dead time when the turbo code is waiting for the disk to spin
around is minimized Many of the higher-level disk routines that write multiple
blocks do just this.
WriteBlock is useful for multiple-sector disk operations where speed is an issue
and the standard GEOS routines don't offer a decent solution. WriteBlock can
function as the foundation of specialized, high-sp^d disk routines.
Apple GEOS has no WriteBlock equivalent Use PutBlock instead. To write a
block without verifying the data, set numDiskRetries to $00 before calling
PutBlock. See PutBlock for more information.
;Write sector from diskBlkBuf to disk and then verify
if necessary.
Pass:
track
sector
verify
Returns:
X
track number
sector on track
verify data? (TRUE
error code
YES)
309
WriteBlock
MyPutBlock :
80$:
99$:
Loaaw
MoveB
r xJ^r uracK
i WJLOlwl\ ilUlllMCX
noveo
ifi©ctor number
jsr
;ao Into turbo tnocie
txa
;set status flags
bne
99$
/branch if error found
jsr
InitFbrlO
/prepare for serial I/O
jsr
WriteBlock
/primitive write block
tixa
/set status flags
bne
80$
/branch if error found
Ida
verify
/check verify flag
beq
80$
/branch if not verifying
jsr
VerWriteBlock
/verify block we wrote
jsr
DoneWithIO
/restore after I/O done
rts
/exit
See also: PutBIock, ReadBlock, VerWriteBlock.
310
WriteFile
WriteFile (Apple, C64, cns)
mid-level disk
Function: Write data to a chained list of disk blocks.
Parameters: r7 DATA — pointer to start of data (word).
Commodore:
r6 TSTABLE — pointer to a track/sector list of blocks to wnte data to
(unused but allocated in the BAM), usually a pointer to
fi!eTrScTab+2; BlkAUoc can be used to build such a list. Apple
GEOS uses the table in INDEXBLOCKBUF (word).
Uses:
curDrive
CQiinmcK^prg;
curType
GEOS 64 vl.3 and later for detecting REU shadowing.
Returns:
Destroys:
Appig;
RWbank bank BUFFER is in (MAIN or AUX).
INDEXBLOCKBUF index block for chain (in auxiliary memory; see
below for information on accessing this buffer).
X error ($00 = no error).
Apple;
a, y, rl, r4.
Commodorg;
• a, y, rl-r2, r4, r6-r7.
Description: WriteFile writes data from memory to disk. The disk blocks are verified, and
any blocks that don't verify are rewritten.
Although the name "WriteFile" implies that it writes "files," it actually writes a
chain of blocks and doesn't care if this chain is an entire sequential file or merely
a VLIR record.
C64 & C128: WriteFile uses the track/sector table at TSTABLE as a list of linked blocks that
comprise the chain. The end of the chain is marked with a track/sector pointer of
$00,$ff. WriteFile copies the next 254 bytes from the data area to
diskBlkBuf+2, looks two-bytes ahead in the TSTABLE for the pointer to the
next track/sector, and copies those two-bytes to dskBIkBuf+0 and
dskBlkBuf+1. WriteFile then writes this block to disk. This is repeated until
the end of the chain is reached
WriteFile does not flush the BAM (it does not alter it eidier — it assumes the
blocks in the track/sector table have already b^n allocated). See BlkAUoc,
SetNextFree, and AlIocateBIock for information on allocating blocks. See
PutDirHead for more information on writing out the BAM.
Apple:
Apple GEOS uses the internal index block buffer INDEXBLOCKBUF (in
aujoliary memory) as a list of blocks that comprise the chain. Applications cannot
311
WriteFile
directly access this buffer, but MoveAuxData can be used to copy the index
block from the appliciation's memory space to INDEXBLOCKBUF:
AOXtoMAIN
MAINtoAOX
LoadW
LoadW
LoadW
Ida
jsr
%10000000
— %01000000
rO, ImylndexBlock
rl, # INDEXBLOCKBUF
r2, «BLOCKSIZ£
#MAINtoAOX
MoveAuxData
;copy from app. main
;to temp high aux
;move a full block
;copy main to aux
WriteFile does not write the index block out to disk,
WriteFile does not flush the VBM cache (it does not alter it either — it assumes
the blocks in the index block have akeady been allocated). See BlkAlIoc,
SetNextFree, and AlIocateBIock for information on allocating blocks. See
PutVBM for more information on flushing the VBM cache.
WriteFile first writes the blocks out in a tight loop, then makes a second pass,
rereading each into diskBikBuf to verify the data. If a verify error occurs, the
entire file is rewritten.
Example:
See also:
SaveFile, WriteRecord, ReadFile.
312
WriteRecord
WriteRecord (Apple, C64, ci28)
VLIR disk
Function:
Write data to the cunent VLER record.
Parameters: r2
Uses:
Returns:
Alters:
r7
BYTES — data bytes to write to record. Commodore version can write
up to 32,258 bytes (127 Commodore blocks); Apple version can write
up to 64,512 (126 ProDOS blocks) (word).
RECD ATA — pointer to start of record data (word).
curDrive
nieWrittent
curRecord
fileHeader
Cpmmcxlprp;
curType
curDirHead
dir2Headt
dirSHeadt
App le:
RWbank
curVBikno+
VBMchangedt
numVBMBIkst
if FALSE, assumes record just opened (or updated) and
reads BAMATBM into memory.
current record pointer.
VLIR index table stored in this buffer.
GEOS 64 vl.3 and later for detecting REU shadowing,
current directory header/B AM.
(BAM for 1571 and 1581 drives only)
(BAM for 1581 drive only)
bank RECD ATA is written from (MAIN or AUX).
used by VBM cacheing routines,
used by VBM cacheing routines,
used by VBM cacheing routines.
^used internally by GEOS disk routines; applications generally don't use.
X error ($00 = no error).
fileWrittent
fileHeader
fileSize
Commodore:
fileTrScTab
curDirHead
dir2Headt
dirSHeadt
Applg;
fileBytes
set to TRUE to indicate the file has been altered since last
updated
index table adjusted to point to new chain of blocks for
current record.
adjusted to reflect new size of file.
Contains track/sector table for record as returned from
B Ik Alloc. The track and sector of the first block in the
record is at fileTrScTab+0 and fileTrScTab+l. The end
of the table is marked with a track value of $00.
current directory header/B AM modified by write operation.
(BAM for 1571 and 1581 drives only)
(BAMfor 1581 drive only)
adjusted to reflect new size of file.
^used internally by GEOS disk routines; applications generally don't use.
313
WriteRecord
Destroys:
Description:
Note:
Apple:
Apple:
a, y, rl-r4, r6, r7, r8H.
ComiTiodgre;
a, y, r0-r9.
WriteRecord writes data to the current record All blocks previously associated
with the record are freed. BIkAIloc is then used to allocate enough new blocks
to hold BYTES amount of data (Apple GEOS will allocate one ProDOS index
block in addition to the data blocks). The data is then written to the chain of
sectors by calling WriteFile. The flleSize variable is updated to reflect the new
size of the file. Apple GEOS also updates fileBytes*
WriteRecord does does not write the BAMA^BM and internal VLIR file
information to disk. Call CIoseRecordFile or UpdateRecordFiie when done
to update the disk with this information.
WriteRecord correctly handles the case where the number of bytes to write
{BYTES, R2) is zero. The record is freed and marked as allocated but not in use.
When WriteRecord returns, the index block of the record just written is in the
aux. memory buffer INDEXBLOCKBUF. Applications cannot access this
buffer direcdy. MoveAuxData can be used, however, to copy the block into the
appliciation's memory space if access to it is necessary:
AUXtoMAIN
MAINtoAUX
LoadW
LoadW
LoadW
Ida
jsr
%10000000
== %01000000
rO, # INDEXBLOCKBUF
rl, #diskBlkBuf
r2, #BLOCKSIZE
#APXtoMAIN
MoveAuxData
/copy from index blk
;to tiemp buffer
;move a full block
;copy aux to main
Example:
See also:
ReadRecord, WriteFile.
314
GEOS Quick Reference
Name
€64
C128
Apple
Description
AllocateBIock
$9048
S9048
S0300
Mark a disk block as in-use.
AppendRecord
$c289
$c289
S0330
Insert a new VLIR record after the current record.
AuxDExil
n/a
n/a
Sefa9
Aux-driver deinstall and exit routine.
AuxDInt
n/a
n/a
Sefa3
Aux-driver interrupt level routine.
AuxDKevFilter
n/a
n/a
Sefa6
Aux-driver keypress filter.
AuxDMain
n/a
n/a
SefaO
Aux-driver MainLoop level routine.
BBMult
$cl60
Scl60
Sfecc
Byte by byte (single-precision) unsigned multiply.
Bell
n/a
n/a
Sff86
1000 Hz Bell sound.
BitmapClip
$c2aa
Sc2aa
SfeSa
Display a compacted bitmap, clipping to a sub-window.
BiimapUp
$cl42
$cl42
Sfe54
Display a compacted bitmap without clipping.
BilOlherClip
$c2c5
$c2c5
SfeSd
BitmapClip with data coming from elsewhere (e.g.. disk)
BldGDirEntiy
$clf3
$clf3
$036f
Build a GEOS directory entry in memory.
BlkAlIoc
Sclfc
Sclfc
S0351
Allocate space on disk.
BlockProcess
SclOc
SclOc
$feb4
Block process from running. Does not freeze timer.
BMuIt
$cl63
$cl63
Sfecf
Byte by word unsigned multiply.
BootGEOS
ScOOO
ScOOO
n/a
Reboot GEOS. Requires only 128 bytes at ScOOO.
CalcBlksFree
Scldb
Scldb
$0324
Calculate total number of free disk blocks.
CallRouline
$cld8
Scld8
$ff08
pseudo-subroutine call. $0000 aborts call.
CancelPrinl
n/a
n/a
$6018
Cancel printing, clearing printer and I/O card buffers.
ChangeDiskDevice
$c2bc
Sc2bc
n/a
Instruct CBM drive to change its serial device address.
ChkDkGEOS
Sclde
Sclde
n/a
Check CBM disk for GEOS format.
ClearCard
n/a
n/a
$6715
Clear any buffered I/O operations.
ClearMouseMode
Scl9c
Scl9c
$fe9f
Slop input device monitoring.
ClearRam
$cl78
$cl78
$fefc
Clear memory to $00.
Clocklni
n/a
n/a
$0803
Clock driver interrupt level routine.
CloseCard
n/a
n/a
$670c
Close access to I/O card.
CloseRecordFile
$c277
$c277
$0333
Qosc currently open VLIR file.
CmpFString
$c26e
$c26e
$fefO
Compare two fixed-length strings.
CmpString
$c26b
Sc26b
$feed
Compare two null-terminated strings.
CopyFString
$c268
Sc268
Sfeea
Copy a fixed-length string.
Copy Full Screen
n/a
n/a
$ff92
Fast vertical screen copy.
CopyLinc
n/a
n/a
SffSf
Bit-boundary horizontal line copy.
CopyScreenBlock
n/a
n/a
$ff5c
Bit-boundary rectangle copy.
Copy String
$c256
Sc256
$fee7
Copy a null-terminated string.
CRC
$c20e
Sc20e
$ffl4
Cyclic Reduncancy Check calculation.
Dabs
$cl6f
$cl6f
$fedb
Double -precision signed absolute value.
Ddec
$cl75
$cl75
$feel
Double-prccison unsigned decrement.
Ddiv
$cl69
$cl69
$fed5
Double-precision unsigned division.
DeleteDir
n/a
n/a
$037c
Delete directory.
DeleteFile
$c238
$c238
$0357
Delete file.
DeleteRecord
$c283
Sc283
$0336
Delete current VLIR record.
DisablSprile
$cld5
Scld5
$feab
Disable sprite.
DivideBySeven
n/a
n/a
$ff68
Quick division by seven for direct screen access.
DMull
$cl66
$cl66
$fed2
Double-precision unsigned multiply.
Dnegate
$cl72
Scl72
Sfede
Double-precision signed negation.
DoBOp
n/a
$c2ec
n/a
C128-backram memory primitive.
DoDlgBox
$c256
Sc256
Sffl7
Display and begin interaction with dialog box.
Dolcons
$cl5a
Scl5a
$feOc
display and begin interaction with icons.
DoInlineRetum
Sc2a4
Sc2a4
$fe09
Return from inline subroutine.
DoMenu
$cl51
SclSl
$feOf
Display and begin interaction with menus.
DoneWithIO
$c25f
Sc25f
n/a
Restore system after I/O across CBM serial bus.
DoPreviousMenu
$cl90
$cl90
$fel5
Retract sub-menu and reactivate menus up one level.
DoRAMOp
$c2d4
Sc2d4
n/a
CBM RAM-expansion unit access primitive.
DownDirectory
n/a
n/a
$0381
Open subdirectory.
DrawLine
$cl30
Scl30
$fe33
Draw, clear, or recover line between two endpoints.
DrawPoint
$cl33
Scl33
$fe21
Draw, clear, or recover a sinf^le screen point.
DrawSprite
Sclc6
Sclc6
$fea2
Define sprite image.
1
GEOS Quick Ref-
Name C64 C128 Apple Description
Uouiv
sir 1
LAJUDiC'prcvlslUlX algllCvX UlViSIUIl*
rVMihlA.nrACicinn l^ft chift /7Ame chiftA/1 ^n^
Li/\^UUlcpi wwiaiv/ix icil 911111 ^^ClUa 911111CU Ul^«
1111 llxl {^UL
$c262
$c262
Sfec9
Oouble-Drecision richt shift (7&t(^^ shifted in^
(KTWUk'tW 1^1 W^iA IV/tl I Jlll&fc dlUlbWU lily*
$cl09
$cl09
$fec3
Make a process ninable immediately.
Ciiauiopn W
Scld2
$cld2
t91 vOO
Fnable snrite
cnicr L</CdJv,i \jy
Sc22c
$c22c
Sff59
l^ave annlication and return to GPOS rfe^VTmi
cnici 1 uruo
Sc9l4
n'/fl
11/ tt
Artivflt^ r^RM Hiclf tiirtv^ nn nirrAnt HriVA
/^wlXvttVC ^X^ITI V41dl^ lUX U\/ Ull VUXIwlll UXi*v*
n/a
n/a
$ff3e
Frase text character from screen
CaH 1 lUUU
$c232
$c232
n/a
Deactivate CBM dislc turbo on current drive
$c244
Sc244
n/a
Ouiclc file delete ^renuires full track/sector Hst^
I7Tvrr%A e Tn D 1 r
1 ur 1 ypcsini«/ix
11/ a
n/a
11/ a
S0363
FinH fllAC in rfirActorv nthAr fhsin nirrAnf rfir<»/*torv
rUlU X11C9 Xil UtiCWlWljr VJUICl UIOJI WUllClll vlllCvlvljT*
CptrViR AM
Sc2cb
Sc2cb
n/a
Transfer data from CRM R AM-exnansion unit
$cl7b
$cl7b
$feff
Fill memorv with a tiarticular bvte
r inoD Mjvi o 1 1
Sc2ad
n/a
Get allocation statue of narticular CRM disk block
vjwv oitv^ttuvit dMiiua %jl pcuuwuittx y^oiyk ui9iw l/jv/wil*
rinanie
SclOb
SclOb
S0369
^Anrrh for a nnrtinilaT* filA
rinur i ypes
S0366
FinH all files of a nartimlar GFO^ tvTV*
1 liiu cux xuca vix a }j<uuvui<u vJbvyo ijr^^*
Firiii V dviJDii
11/ a
n/a
$03 6c
Get allocation status of narticular ProDOS disk block
nrsiinii
$c271
$c271
$ffll
GFOS startUD entrv ooint
rnariiinjL/ir
n /a
11/ A
n /fl
11/ a
S036c
Finrf a file in a directorv other than current rfirectorv
roiiuw\^naiTi
$c905
n/a
Follow chain of f^R^4 sectors hiiilHina traclf /sector table
rraiTic ivcciajigic
«9ir 1^1
TV*aw a rActanaular frame ^011flinA^
§1^1 aw a icvuuif^uiax xiOJiic yuuiiiiicy*
$039fl
«9w J ^tt
Mflrlr a Hislr hloclr as not.in.iicA
ivinxiw tf uisjw uiiyviw sd iivi*iJi"U9C»
rreeuir
n/fl
n/a
n/a
^uJ ua
Ptaa all hlnoVc accf%/*i9tAH u/itK o eiiYv4irA/^f/^T\/
nCC all UlUvKa odbUCIalCU Wiui a suuuirvduiy.
FrecFile
«9 vJ J tt
FrAA all hlocire accocatiatAH ti/ith a filA
1 ICC OJX Ulv/Ui^a ttddU^aiialcu wiui tt XllC*
FrcczcProcess
1 1 ^
SIfAhfl
PaiiCA a nrfYCACC cmmtHi^u/n ftmA^
1 ausc tt piuwcaa vuumuuwii uinci*
vj c 1 1 s 1 1^ I r cn uy
S039c
Ga? first HirAcforv Antrv
VJCi XlXdi UlXCvlUljr ClllXjr*
S0300
RabH sinolA Hislr hloclr info mAmorv
xxcau dxiigic vxiaiw uiuviw xiiiu iiiciiiuiy*
«91CO /
GnlciilatA wiHth of characfAT vi/ithoiif ct\/lA attrihiitAC
Vvttiii^uiaic wiuui ux wiittittwici wiuiuuL aijic aiuiuuicSt
At III An c t An c
d> # 7V/V
n /fl
11/ tt
GAt GT)M nrintAr nnoe HimAnsione
wci \^ovn piiiiicx pa^c uiiiiciuiuua*
/^Atr\trUA4<4
vjciL/irneau
S0379
RAttH HirActorv hAaHAT into mATTmr\/
ixcau uiicviuxjr iicttvici xiiiu luciiiury*
O At P14 rfrTn f r>
$c92Q
S0390
«9 V J 7 W
RAaH a GFO^ file hearlAr into mAmnrv
xvcttu tt vjbvyo xxic iicaucx xiiiw iiiciiiuiy«
vjcinie
S030f
Load GEOS file
nAtFrAAnirRIk
VJCltiCCLi/lI OlIW
$clf6
$clf6
$0375
Find an emotv directorv slot
1 iiiu cut ^tn\jvy uiiv>wv\jijr ^tw^* ^
VJCULAA T <U 9
n/a
n/a
$ff44
Transfer internal Ld variables to GEOS nseudorecisters
n/a
n/a
$6012
Return current orintcr resolution anH setahle attributes
GetNextChar
Sc2a7
Sc2a7
$fe75
Get next character from character aueue
OptMY tnirFntrv
$9033
$9033
$039c
Get directorv entrv other than first
GAtPatViTiAmA
n/a
n/a
$0384
Return current oath strini?
r«AtPflttf>m
VJvll Alien t
n/a
n/a
$ff7d
Get eieht-bvte GEOS nattem definition
$c298
$c298
$ff56
Return nointer to current disk name
vjcilx aJiQOTTl
SIrl 87
Sfee4
«91CC*T
f^alcitlatA nAU/ ranHom numt^r
\^aiwuiaic new xaJiuuiii iiuiiiia?i*
«9U i U 1
$clbl
$fe84
Calculate actual character si7e with attributes
«9V X .^V
$fe66
CalciilatA ccanlinA aHHrACC
v^ttiwuittic a^ojiiiiic Buvxxcaa*
^AtQ^^AAnT inA
n/fl
n/ tt
n /o
11/ tt
Sff62
. Conv Annie ccrAAn Hata to huff at
' VfUpjr /^ppiC 9V1CC11 UBltt lU uuxxcx*
^AtC Ariiil^iimKAT
«JW X7U
$4b38
Return GFO^ CArial number or nointer to namA ctrino
ixwiuiii VifCrWO 5Ciiax iiixjiiucx ui puxiiici uj jittjiic auuij^.
r^At^TYrif ADfttn
.11/ a
n /tt
11/ tt
$ff6e
Get cnrifA imnoe Hafa
vjci dpi lie xjiittj^c uaitt*
OAiQtrino
VJcio u lliK
Sclba
t9W X l/tt
$fe72
Get 'strinv innut from user
VJCt SUlllJ^ llipUL XlVIXII U9wl»
nAtVRM
n/a
n /tt
11/ tt
$03 le
Read first VRM block into VRM cache
ixwau xiidi T oivx v/ivAi'^ liiiv/ TijiTX va^iic*
vjo L/ireciury
n/a
n/fl
11/ tt
$03 9 f
Go Hirectorv to a STV*cific suhHirActoin/
vjv uxxcviuxy lu tt d^i^vtxxw dui/uixcviuiy*
ftotoPircf K^Ami
vju lu ni^ uviciiu
Sclbd
$fel8
Retract all sub.menus and reactivate at main level
i\vu aw oil auu iiiwiius oiiu icawixvttic tti iiiaxii iwvei*
vjiapnicso u
X JO
Sfe60
pYACIltA o ctTincT of (TTanhicc rommanrle
bACvuic tt SIX Ills ^k {^lapiiiva vununaiius*
HideOnlyMouse
n/a
$c2f2
$ff7a
Temporarily remove soft-sprite mouse pointer.
Horizontal Line
Sells
$cll8
$fe27
Draw a patterned horizontal line.
i_BitmapUp
Sclab
$clab
$fe57
Inline BiimapUp.
i_FillRam
Sclb4
$clb4
$ff02
Inline FillRam.
i_FrameReciangle
Scla2
$cla2
$fe42
Inline FrameRectangle.
i_GraphicsString
SclaS
$cla8
$fe63
Inline GraphicsString.
iJmprintRectangle
Sc253
Sc253
$fe51
Inline ImprintRectangle.
2
GEOS Quick Reference
Name C64 C128 Apple Description
i MoveData
$clb7
$clb7
$fef9
Inline MoveData.
i NewBitUo
n/a
n/a
$ff9c
Inline NewBilUp.
LPuiSlring
Sclae
$clae
$fe6c
Inline PutString.
i RecoverRectanKle
$cla5
$cla5
$fe4b
Inline RecoverRectanRlc.
i Rectanf^le
$cl9f
$cl9f
$fe3c
Inline Rectangle.
ImprintLine
n/a
n/a
$ff8f
Imprint horizontal line to background buffer.
ImprinlRectanKle
$c250
$c250
$fe4e
Imprint rectangular area to background buffer.
InfoCard
n/a
n/a
$670f
Get I/O card attributes.
InitCard
n/a
n/a
$6700
Intialize I/O card.
InilForDialoK
n/a
n/a
$ff4a
Internal pre-dialog box intialization.
InitForlO
$c25c
$c25c
n/a
Prepare CBM system for I/O across serial bus.
InitForPrint
$7900
$7900
$6000
Initialize printer (once per document).
InitMouse
$fe80
$fe80
$fOOO
Initialize input device.
InitProcesses
$cl03
$cl03
$feae
Intialize processes.
InilRam
$cl81
$cl81
$ff05
Initialize memory areas from table.
InitSprile
n/a
n/a
$ff32
Initialize software sprites.
InitTexiPrompl
SclcO
$clcO
$fe78
Initialize text prompt.
InputByle
n/a
n/a
$6709
Read byte from I/O card.
InseriRecord
Sc286
$c286
$0339
Insert new VLIR record in front of cuncnt record.
IntemiptMain
SclOO
$clOO
$fe03
Main interrupt level processing.
InvcrtLine
Scllb
$cllb
$fe2d
Invert the pixels on a horizontal screen line.
InvertRectangle
$cl2a
$cl2a
$fe45
Invert the pixels in a rectangular screen area.
IrqMiddle
n/a
n/a
$ff20
Software interrupts entry point.
IsMselnRej^ion
$c2b3
$c2b3
$fe9c
Check if mouse is within a screen region.
JsrToAux
n/a
n/a
$03b4
Call aux -memory subroutine.
KeyFiller
n/a
n/a
$f009
Input driver keypress filter.
LdApplic
$c21d
Sc21d
$03 8d
Load GEOS application.
LdDeskAcc
$c217
$c217
$035d
Load GEOS desk accessory.
LdFile-
$c211
$c211
$0312
Load GEOS data file.
IjoadAuxSet
n/a
n/a
$fn7
Use aux-memory character set.
LoadCharSet
Sclcc
$clcc
$fe8a
Use main-memory character set.
MainLoop
$clc3
$clc3
$feOO
GEOS MainLoop processing.
MakeSubDir
n/a
n/a
$0387
Create ProDOS subdirectory.
MouseOff
Scl8d
$cl8d
$fe96
Disable mouse pointer and GEOS mouse tracking.
MouscUp
$cl8a
$cl8a
$fe99
Enable mouse pointer and GEOS mouse tracking.
MoveAuxData
n/a
n/a
$ff6b
Apple aux-memory memory move routine.
MoveBData
n/a
$c2e3
n/a
128 backram memory move routine.
MoveData
$cl7c
$cl7e
$fcf6
Memory move routine.
NewBitClip
n/a
n/a
$ff95
Bit-boundary BitmapClip.
NewBitOlherClip
n/a
n/a
$ffOe
Bit-boundary BiiOtherClip.
NewBiiUp
n/a
n/a
$ffld
Bit-boundary BitmapUp.
NewDisk
Sclel
$clel
n/a
Tell CBM disk turbo software that a new disk is in drive.
NexiRecord
Sc27a
$c27a
$0336
Make next VLIR the cuncnt record.
NormalizeX
n/a
$c2e0
n/a
Normalize CI 28 X-coordinates for 40/80 modes.
NxtBlkAlloc
$c24d
$c24d
$0354
Version of BlkAlloc diat starts at a specific block.
OpenCard
n/a
n/a
$6703
Open I/O card for access.
OpenDisk
$c2al
$c2al
$0399
Open disk in current drive.
OpenRecordFile
$c274
$c274
$033f
Open VLIR file on current disk.
OuipuiByte
n/a
n/a
$6706
Write byte to I/O card.
Panic
$c2c2
$c2c2
$fef3
System-error dialog box.
PointRecord
$e280
$c280
$0342
Make specific VUR record the current record.
PosSprite
$clcf
$clcf
$fea5
Position sprite.
PreviousRecord
$c27d
$c27d
$0345
Make previous VLIR record the current record.
PrinlASCU
$790f
$790f
$600c
Send ASCII data to printer.
PrintBuffer
$7906
$7906
$6009
Send graphics data to printer.
PromptOff
$c29c
$c29e
$fe7c
Turn off text prompt.
PrompiOn
$c29b
$c29b
$fe7b
Turn on text prompt.
PurgeTurbo
$c235
$c235
n/a
Remove CBM disk turbo software from drive.
3
GEOS Quick Reference
Apple
L/cScripiion
PutBlock
$cle7
$cle7
C Al Al
$0303
Write singel disk block from memory.
PutChar
$Cl45
$Cl45
SfeSl
Display a single character to screen.
PutDecimal
Cm 1 QA
ChClo4
5Clo4
5teof
Format and display an unsigned double-precison number.
PulDirrleaa
^^OA t>
«>cz4a
%bc24a
C Al 11m.
50370
Write directory header to disk.
PutScreenLine
n/a
n/a
5lio5
Copy buffer data to Apple screen memory.
PutString
)Cl4o
5Cl4o
5ieoy
Print string of characters to screen.
PUlVBM
n/a
n/a
CA10 1
50321
Flush VBM cache; write currently cached block to disk.
ReadBackLine
n/a
n/a
cm A
511/4 .
Get data from background screen in linear bitmap format.
ReadBlocK
ScZla
shc2la
n/a
CBM get disk block primitive.
ReadByte
ChCZDO
OCZDO
Read disk file a byte at a time.
ReadCIocK
n/a
n/a
CAQ AA
50oOO
Update ObUo time/date variables from clock hardware.
Read rile
)ClIi
5CllL
CA1 1 <
50J ID
Read chained list of blocks into memory.
ReadLinx
CQAy* U
Q Ail U
n/a
DmoJ f^^\M CwMmI* /oMM^MM IZ^tv
Keaa k^dM tracK/sector iiruc.
Read Record
$c2oc
$c2oC
CA1 O
50348
Read current VLIR record into memory.
ReadScanLme
n/a
n/a
5ll95
Get data from foreground screen in linear bitmap format.
RecoverAllMenus
5cl57
$C1D7
CTmI M
5iele
Recover all menus from background buffer.
RecoverFG
n/a
n/a
CA'5 «M
503 ae
Restores foreground screen from data created with SaveFG.
RecoverLine
«hci le
Pm 11m
5ci le
5iejo
Recover horizontal screen line from background buffer.
RecoverMenu
JiCl j4
C*»1 CA
v>Cl J4
^tei
Recover single menu from background buffer.
RecoverRectangle
)ciza
C/*1
5ie4o
Recover rectangular screen area from background buffer.
RecoverSysRam
n/a
n/a
5tl53
Restore system after dialog box or desk accessory.
Rectangle
Scl24
Cm 1 i4
5cl24
5ie39
Draw a filled rectangle.
ReDoMenu
Scl93
ff ^ 1 A1
$cl93
5iel2
Reactivate menus at the current level.
Renamerile
$c23*^
Sc2j9
C A*! 0*5
50393
Rename ObUo disk rile.
ReOpenDisk
n/a
n/a
C Al
503 a2
Reopen disk to previous directory.
ReseiAlarm
n/a
n/a
C AO Am
50oOC
Disable clock driver alarm.
ResetHandle
5cv}03
CmAAI
5 c 003
n/a
Internal bootstrap entry point.
RestartProcess
SclOo
C M 1 A^
5clOo
5reDl
Unblock, unfreeze, and restart process.
ResloreFontData
n/a
n/a
c en o
5ir3o
Restore font variables from saveFontTab.
RstrAppl
Sc23e
5c23e
C A1 ^ A
50360
Leave desk accessory and return to calling application.
RstrFrmDialog
Sc2bf
$c2bi
$rila
Exit dialog box.
SaveFG
n/a
n/a
CA1 >U
503aD
Save foreground screen data for RestoreFG.
5aveFile
Scled
CmI m,J
Scled
CA1 1 O
503 1 5
Save/create a ObUS file.
• SaveFontData
n/a
n/a
cm<
Copy font variables to saveFontTab.
SetAlann
n/a
n/a
ff AQ AA
50ooy
Set clock driver alarm.
SeiDevice
^CZDU
5CxD0
n/a
Establish communication with a new serial device.
SetGDirEntry
$ClfO
Cm 1 fi\
5clrO
CAO "7U
5037D
Create and save a new GEOS directory entry.
SetGEOSDisk
Sclea
CmI mm
5clea
. /m
n/a
Convert normal CoM disk mto GEOS format disk.
SelLdVars
n/a
n/a
5li47
Set internal Ld variables from GEOS pseudoregisters.
SetMode
n/a
n/a
C ^ A t C
$6015
Set print mode.
SetMouse
n/a
5feoy
n/a
Reset input device scanning circutry.
SeiMsePic
n/a
5c2da
5rr2i
Set and preshift new soft-sprite mouse picture.
SetNewMode
n/a
5c2da
n/a
Lnange UbUo 12o graphics mode (40/80 switch).
SeiNextFree
ff-^'^ A'^
Sc292
5c292
CA1U
5032a
Search for nearby free disk block and allocate it.
SetNLQ
57915
(PT A 1 <
$7915
n/a
Begin near-letter quality printing.
SeiPaitem
$cl39
$cl39
5iejo
Set current fill pattern.
SetTimeDate
n/a
n/a
C AO AiC
50oOO
Set clock driver time and date.
SeiUserPattem
n/a
n/a
5lIoO
ueime new ubUo pattern image.
Sleep
$clV9
CmI AA
5cl99
5teco
Put current subroutine to sleep for a specified time.
SlowMouse
$feo3
Sfe83
5 too J
Reset mouse velocity* variables.
SmallPuiChar
$C2U2
Cm'^ A*^
5c202
5ievo
Fast character print routine.
SoitSprHandler
n/a
n/a
5li2C
Apple soft- sprite drawing routine.
SorlAlpna
n/a
n/a
CAI A<
50 J a3
Insertion sort.
StartAppl
$c22f
$c22f
$fe06
Warmstart GEOS and start application in memory.
StartASCn
$7912
$7912
$6006
Begin ASCII mode printing.
StartMouseMode
$cl4e
$cl4e
$fe93
Start monitoring input device.
SiartPrint.
$7903
$7903
$6003
Begin graphics mode printing.
StashRAM
$c2c8
$c2c8
n/a
Transfer memory to CBM RAM-expansion unit.
4
GEOS Quick Reference
Name
C64
C128
Apple
Description
StatusCard
n/a
n/a
$6712
Get current status of I/O card.
StopPrint
$7909
$7909
$600f
End page of printer output.
SwapBData
n/a
$c2e6
n/a
C128 memory swap between front/back ram.
SwapMainAndAux
n/a
n/a
$ff71
Apple memory swap between main and aux.
SwapRAM
$c2ce
$c2ce
n/a
CBM RAM -expansion unit memory swap.
TempHideMousc
n/a
$c2d7
$ff29 .
Hide soft-sprites before direct screen access.
TestPoint
$cl3f
$cl3f
$fe24
Test status of single screen point (on or off?).
ToBasic
$c241
$c241
n/a
Call Commodore BASIC.
UnblockProcess
SclOf
$clOf
$fcb7
Unblock a blocked process, allowing it to run again.
UnfrcezeProcess
Scll5
$cll5
$febd
Unpause a frozen process timer.
UpdateMouse
$fe86
$fe86
$f006
Update mouse variables from input device.
UpdateParent
n/a
n/a
$03 b7
Update parent directory to reflect any changes.
UpdateRecordFile
$c295
$c295
$034b
Update currently open VLIR file without closing it.
UpDireciory
n/a
n/a
$03 8 a
Close current directory and move up one level.
UseSystemFont
$cl4b
$cl4b
$fe8d
Use default system font (BSW 9).
VerifyBData
n/a
$c2e9
n/a
CI 28 backram verfiy.
VerifyRAM
$c2dl
$c2dl
n/a
CBM RAM-expansion unit verify.
VerticalLine
$cl21
$cl21
$fe2a
Draw a patterned vertical line.
VerWriteBlock
$c223
$c223
n/a
CBM disk block verify primitive.
WarmStart
n/a
n/a
$ff4d
Bring GEOS to a warmstart state.
WriieBlock
$c220
$c220
n/a
CBM write disk block primitive.
WriieFilc
$clf9
$clf9
$03 lb
Write chained list of blocks to disk.
WrileRecord
$c28f
$c28f
$034c
Write current VLIR record to disk.
NOTES: The following routines have had there names changed to avoid confusion and/or make them unique in
the first eight characters:
Ctfmnt Namg
Clocklnt
CopyLine
i.NewBitUp
LoadAuxSet
MoveAuxData
Fgrmgrly
ReadQockInt
CopyScreenLinc
i_NewBitmapUp
LoadAuxCharSet
MoveBData
Current Namg
NewBitClip
NewBitUp
PutChar
RstrFrmDialog
SetMsePic
Fgrmgrly
NewBitmapClip
NewBitmapUp
Putchar
RstrFrmDialogue
SetMousePicture
CBM
Apple: The following routines were not added to the jump table until version 2.0.3 (version 2.0. release 3).
To call these routines in v2.0.2 (the initial public release) requires a patch to the jump ubles.
NewBitOtherClip, i.NewBitUp, AUocatcBloct GetlstDirEniry, GetNxtDirEntiy
The following routines do not have jump table entries in the 1541 device driver. The device type must
be checked before calling any of these routines. Sec the actual routine reference for more information
and 1541 alternatives.
AllocateBlock. ReadLink
The following routines do not exist in version 1.2 and below of CBM GEOS:
GetlstDirEntry. GetNxiDirEntry, FreeBlock .
They require calling directly into the GEOS Kemal. See the actual routine reference for more
information.
5
file! kernalPatch, page 0, tiae Tue Apr 19 12>58U} 1988
APPLE CEOS «2.0.2 KERNAL PATCH (reuision 3)
Hatt Loueless
Robert Boudidge
April 6, 1988
Reuision History
ssssssssssssssss
03/22/88 il/rb First hacked up
03/23/88 al/rb Fixed aux/»ain snafu
04/06/88 al/rb Added iJeuBitaapUp for 'ol uargas.
04/08/88 aau Used oatch and aade aisc bug fixes. Called routine
i NeuBitaaptlp and it seesed to work fine.
4/18/88 aau CKanged references to GetNextDirEntry to EetHxtOirEntry.
Notes This patch inforaation has not yet been thoroughly tested. If anybody has probleas, please direct thea to Robert
and/or Hatt.
The fol loving routines were inaduertently left out of the Apple GEOS juap table in the first production release (u2.0, rel. !]•
HevBitOtherClip
AllocateBlock
GetlstDirEntry
GetNxtOirEntry
i NeuBitaapUp
Applications that uish to use these routines aust patch the Kernal ]uap tables in order to run under v2.0, rel. 2.
Startino uith u2.0, release 3, these routines^are guaranteed to be in «he^)uap table. Applications flUST check the
nuaber Before patching in order to be coapatible uith future versions of Apple GEOS
The following unused juap table slots uill be used'
version
HeuBitOtherClip
AllocateBlock
GetlstDirEntry
GetNxtOirEntry
i HeuBitaapUp
SffOe
I 030c
i;039i
i;039c
$ff9e
old ToBasic]
old ReadChain)
old ChkOkGEOS
old SetGEOSOisk)
old ageos RaaDD)
These equates uill not change and uill ensure an application is upuard coapatible uith future versions of Apple GEOS.
Patch info for u2.0, release 2i
Routine
sssssss
HeuBitOtherClip
AllocateBlock
GetlstDirEntry
GetNxtOirEntry
iJetBitaapUp
Address
ssssssm
IffOe
030c
0396
039c
ff9e
In aux
ap Sdf9a
ap i45cl
ap 4e<6
ap i4e78
ap Panic
In aain
sr ifcl6
sr l0900
sr S0900
sr i0900
, sr iecb3
aux > altzp)
aux « raaurt
aux • raaurt
aux • raaurt
aux » raaurt
(Note that i NeuBitaapUp cannot be run uhile the alternate zero page (ALTZP JH) is suitched in. The juap table entry
juaps to the Panic routine. This routine aust be called uhen the aain zero page is in.)
And in codes
;Patch
ffiiiff
Patch GEOS v2.0.2
It" EQUATES
^Locations in juap table
HeuBitOtherClip • $ff0e
AllocateBlock « $030c
GetlstDirEntry - $0396
GetNxtOirEntry ' i039c
i.HeuBitaapUp « $ff9e
lOirect entry points into v2.0.2 kernal
j.NeuBitOtherClip * Sdf9a
oJllocateBlock ■ i45cl
GetlstDirEntry « l4e66
©"GetNxtOirEntry • i4e78
iT HeuBitaapUp « iecb3
;pixe1 boundary version of BitOtherClip
lal locate block in VBH (opposite of FreeBlock)
iget 1st directory entry in current directory
iqet next directory entry
100 an inline HeuBitaapUp. Hike likes this call.
SuitchAllRegs
mi
ifor aux-high bank graphics switch
fi1e> kernalPatch, page 1, tiK Tue Apr 19 12<58:45 1968
LouSuitch • $0900 if or aux bank (low juip table)
GOODJERSION « S20 {version 2.0.3 does not need to be patched
GOOOJELEASE • $03 ^
.■aero PatchJapTable dest, source (copies three bytes froi source to dest
Ida source
sta dest
Ida source^l
sta destM
Ida source^2
sta dest^2
.endi
$Notet Can be lunged to use less bytes by table driving the patch. Done this uay here for
I demonstration purposes only.
Patch*
I Check version to ensure that ue don't patch Kernals that are already
t fixed, ye check for version 2.0.3 (good version) explicitly because
f 2.0.2 is the first release of the Apple Kernal and 2.0.3 has the fixes
i in it.
Ida version
csp tGOODJERSION
bne 10$ 'ibranch if current version >2.0. If
I not then it is 3.xx uhich is fixed.
Ida release
cnp tGOODJELEASE
bge 10$ (branch if this release >* good release
bra 20$ ibra to do the patch
10$t
rts
fThis is a version that needs to be patched. Go patch it.
ffirst patch addresses in nain
20$«
PatchJMpTbl NeuBitOtherClip, n HeuBitPatch
PatchJipTbl AllocateBlock, fl AllocBIkPatch
PatchJnpTbl GetlstDirEntry, H GetlstPatch
PatchJapTbl GetHxtDirEntry? fl'GetNxtPatch
PatchJipTbl i.NeuBitiapUp, fIjNeuBitiapUp
fpatch graphics in high auxiliary
sta ALTZPJN I suit ch in high aux
PatchJnpTbl NeuBitOtherClip. A HeuBitPatch
Patch Jap Tb I i NeuBitaapUp, A iHeuBitaapUp
sta AUTZPJFF " ; suitch out high aux
(patch others in nornal aux
sta RAfiyRTJN I send urites to aux bank
PatchJnpTbl . AllocateBlock, A AllocBIkPatch I read froa aain, write to aux
PatchJapTbl GetlstDirEntry, K GetlstPatch \ read froa aain, write to aux
PatchJapTbl GetNxtDirEntry, AjetNxtPatch ( read froa aain, write to aux
sta RAHURTJFF I send urites back to aain
99$:
rts
fflain aeaory patches
n NeuBitPatcht
jsr SwitchAIIRegs
n AllocBlkPatchi
tl-GetlstPatchi
nlGetNxtPatch*
jap LowSwitch
n.iNeyBitaapUps
jap ii.HeuBitaapUp
iAux aeaory patches
A.NeuBitPatcM
jap j NeuBitOtherClip
AJllocBlkPatch"
jap AilocateBlock
A GetlstPatchi "
file' kcrnalPatch, page 2, tiie Tuc Apr 19 12558M3 1988
jip GetlstDirEntry
flJetHxtPdUh« " , ^
EetHxtDirEntry
lap o.betnxcuirtniry
A iHeuBi{aapUp>
jip Panic 5can't call this routine froi aux •e«ory.
This page Intentionally left blank to maintain right/left (verso/recto)
page ordering. Final version will correct this.
Mtn^t R^'ftin'^'' (^niirth f *'* ' "'^l ) 5/2/88
11:18 AM
GEOS Text Escape Character Codes
Code Constant Description
NULLV
String termination character.
1
unused
2
unused
3
unused
4
J
unused
D
6
t
unused
7
unused
8
BACKSPACE
erase tne previous cnaracter (APP^g vjcuo uses me wiain ui lasiwiain;.
9
rORWARDSrALb
rfot unpiemenieci in kjcUo oh or %jt,uo i^o. iviovc current pruiung
position rightwaid the width of a space character. This escape code is used
K\/ oAnVk/ritA tn ri*nrf»c^nf A tnH TAR cnnctflnt^
10
LF
Linefeed: move current printing position down one line (value in
currentHeight).
1 1
HOME
Move current printing position to upper-left screen comer.
12
T mf Txrr?
UPLINE
Move current printing position up one line (value in currentHeight).
inis escape cooe is usevi oy geoTYmc lo represeiii a pagc-urca& ^uac
PAGE BREAK constant).
1 D
carnage reium. move currcni priiiLijig posiuon uowii une iinc oiiu uvci w
the left margin (value in leftMargin).
1 A
T^AOin iinHArlinmfy
OCJ^lIl UllUCillllUI}^.
15
UUNEOFF
End underlining.
16
ESC.GRAPfflCS ¥
Escape code for graphics string: remainder of this string is treated as input
lO uie vvrapnicsoirinK rouiine.
1 /
unintp lenient ed This escape code is ignored by GEOS text routines. This
ACCiinA ccsAa ic iice<l Hv o^cs^^ryt^ Xf\ rAnrpcAnt a nilAr Acr^anA ^iicp
ESC RULER constant).
18
REVON
Begin reverse video printing (white on black).
19
REVOFF
End reverse video printing.
20
GOTOX Y
Change the x^coordinate of the current printing position to the word value
stored in the following two bytes.
21
GOTOY ¥
Change the y-coordinate of the current printing position to the byte value
in the following byte.
22
GOTOXY ¥
Change the x-coordinate of the current printing position to the word value
stored in the following two bytes and change the y-coordinate to the value
in the third byte.
23
NEWCARDSET ¥
unimplemented. This does nothing but skip over the following two bytes.
24
BOLDON
Begin boldface printing.
25
ITAUCON
Begin italicized printing.
26
OimiNEON
Begin outlined printing.
27
PLAINTEXT
Begin plain text printing (turns off all type style attributes).
28
t
unused
29
t
unused
30
t
unused
31
t
unused
tshould never be sent to a GEOS text routine unless the application is running under a future version of
GEOS that explicitly supports this character code.
^For use with PutString; not directly supported by PutChar.
1
5/2/88
11:18 AM
GEOS ASCII Character Codes
Code
Character
Code
Character
32
space
65
A
97
a
33
1
66
B
98
b
34
n
67
C
99
c
35
#
68
D
100
d
36
$
69
E
101
e
37
%
70
F
102
f
38
71
G
103
39
1
72
H
1 /\A
104
h
40
(
73
I
105
i
41
)
74
J
106
i
A O
42
75
K
107
k
43
+
76
L
108
1
A A
44
77
M
109
m
A C
45
78
N
110
n
46
79
111
47
80
P
112
i4 O
48
U
81
9
113
q
4y
1
82
R
11/1
114
r
50
2
83
S
lie
115
s
51
3
84
T
116
t
52
A
4
85
U
117
u
53
5
86
V
1 1 o
lis
V
j4
87
W
110
w
55
7
88
X
IZU
X
56
8
89
Y
121
y
57
9
90
Z
122
z
58
91
[
123
f
59
92
\
124
1
60
<
93
1
125
)
61
94
A
126
62
>
95
127
deletion character
63
7
96
USELAST
64
(a
128
short-cut key:
SHORTCUT
2
file! ageosU2.0.2JernalPatch, page 0, tiae Thu Har 24 10:57202 1988
■ >
iifi UPDATES PREUIOUS PATCH INFORHflTION HAD BANK INFORHATION SUITCHED
iiif USE THIS VERSION TO PATCH KERNAL AND DISREGARD EARLIER i«>i
APPLE GEOS V2.0.2 KERNAL PATCH (revision 2)
Hatt Loveless
flarch 23, 1988
Note: This patch inforaation has not yet been thoroughly tested. If anybody has problens, please direct then to Robert
and/or Hatt,
The following routines were inadvertently left out. of the Apple GEOS jump table in the first production release (u2.0, rel. 2)
NeuBitOtherClip
AllocateBlock
GetlstOirEntry
GetNextDirEntry
Applications that wish to use these routines Must patch the Kernal junp tables in order to run under v2.0, rel. 2.
Starting with v2.0, release 3, these routines are guaranteed to be in the juap table. Applications tlUST check the version
nunber before patching in order to be conpatible with future versions of Apple GEOS.
The following unused junp table slots uill be used>
NeuBitOtherClip iffOe
AllocateBlock i050c
GetlstOirEntry i0396
GetNextDirEntry $039c
old ToBasic)
old ReadChain)
old ChkDkGEOS)
old SetGEOSDisk)
These equates uill not change and uill ensure an application is upward conpatible with future versions of Apple GEOS.
Patch info for v2.0, release 2*
Routine Address In aux In nain
8ZSSSSS SSSSS3X SSS3Z3SSS SSSSSSSS
NeuBitOtherClip SffOe m Sdf9a isr SfcK (aux » altzp)
AllocateBl&ck i030c Imp i45cl Isr i0900 aux * ranwrt)
GetlstOirEntry 40396 pp f4e66 jsr i0900 aux « raaurt
GetNextDirEntry $039c jnp $4e78 jsr ^0900 (aux « raniwrt)
And in codes
;ffii«i«ifliffffiiiiiffiiiiiiiiiiiiiif fiiif iiffiiffiiiiiiif«iiiiiit««i«iiii«ifiiitfifiiiiiiiffiiifiifi«
HewBitOtherCIip » iffOe ;pixel boundary version of BitOtherClip
AllocateBlock ' i030c lal locate block in UBI1 (opposite of FreeBlock)
GetlstOirEntry « f0396 ;get 1st directory entry in current directory
GetNextDirEntry » $039c 5get next directory entry
fOirect entry points into u2.0.2 kernal
j NeuBitOtherClip - idf9a
AllocateBlock > i45cl
GetlstOirEntry * Ue6i
oJetNextOir Entry » $4e78
SuitchAllRegs " ^fcl6 ;for aux-high bank qraph^ics switch
LowSwitch ' $0900 ;for aux bank (low junp table)
GOOD VERSION ' $20 iversion 2.0.3 does not need to be patched
GOODlRELEASE « $03
.nacro PatchJapTable dest, source icopies three bytes froa source to dest
Ida source
sta dest
Ida source*!
sta dest*l
Ida source*2
sta dest*2
) .endn
iNote: Can be nunged to use less bytes by table driving the patch. Done this way here for
I demonstration purposes only.
Patch?
fCheck version to ensure that we don't patch Kernals that are already fixed
Ida version
file* ageosVZ.O.Z.KernalPatch, page 1, tine Thu flar 24 10:57:02 1988
bq^ m ibranch if current version >« good version
Ida release
cap IGOOOJELEflSE , ^ ,
5g^ J9] ;branch if current release >« good release
;Thi5 is a version that needs to be patched. Go patch it.
;fir5t patch addresses in Haln
"^PatchJalpTbl NevBitOtherClip, fl NeuBitPatch
PatchJwpTbl flllocateBlock, H ftTlocBIkPatch
PatchJmpTbl GetlstDirEntry, A GetlstPatch
PatchJapTbl GetHextOirEntry, RjetNextPatch
5Datch qraphics in high auxiliary ^ l . c. l
PatchJrapTbl NeuBitOtherClip, flJeuBitPatch
sta . flLTZPJFF 5 switch out high aux
5patch others in nor.al aux^^^ ^ ^^^^ ^^.^^^ ^^^^^
PatchJmpTbl flllocateBlock, fl flllocBlkPatch 5 read froa aain, urite to aux
PatchJapTbl GetlstOirEntry, ff JetlstPatch ; read froa aain, urite to aux
PatchJapTbl GetHextOirEntry, flJetNextPatch I read froa aain, write to aux
RfltliiRT OFF « send writes back to aain
99$:
sta
rts
;Hain aemory patches
(1 NeuBitPatch:
jsr SuitchflllRegs
n flllocBlkPatch:
nletlstPatch:
n"GetNextPatch:
jap LowSuitch
;ftux aeaory patches
fl NeuBitPatch: . ^ _ . . ...
imp ] NeuBitOtherClip
fl flllocBlkPatch:
jnp flllocateBlock
flJetlstPatch: " ^ ^. ^
* jap GetlstOirEntry
fl GetHextPatch:
jmp GetHextOirEntry
files forfipplications/diskRH, page 0, time Hon Feb 22 10:22:24 1988
Summary of desired disk read/write operations and what routines to call
Read a block from disk into FlfllN memory, qiuen block number
ReadBlock or GetBlock with RUbank set to SHAIN (default)
Read a block from disk into DUX memory, given block number
ReadBlock or GetBlock uith RVbank set to lAliX (set, call, reset)
ilrite a block from HfllN memory to disk, given block number
UriteBlock or PutBlock uith RUbank set to IIII^IN (default)
Urite a block from AUX memory to disk, given block number
yriteBlock or PutBlock uith RUbank set to tflUX (set, call, reset)
Read (and execute, if possible) a SEQUENTIAL file into HRIH memory, given its
filename
GetFile uith RVbank set to miH (default)
Reed a SEQUENTIAL data file into AUX memory, given its filename (filename must
be in nAIN) (note: datafiles only? cannot read Desk Accessories or Applications
into AUX and have them execute)
GetFile uith RUbank set to tAUX (set, call, reset)
Read a SEQUENTIAL file into flAIN memory, given its directory entry
LdFile uith RUbank set to inAIN (default)
Read a SEQUENTIAL file into AUX memory, given its directory entry (directory
entry must be in flAIN)
LdFile uith RUbank set to lAUX (set, call, reset)
Open a VLIR file and read (and execute, if possible) it's first record into
HhIN memory, given its filename
GetFile uith RUbank set to SHAIN (default)
Open a ULIR data file and read it's first record into AUX memory, given its
filename (filename must be in tIAIN) (note: cannot run OA's or ftpplic's in AUX)
GetFile uith RUbank set to DhUX (set, call, reset)
Read current ULIR record into flAIN memory
ReadRecord uith RUbank set to ttlAIN (default)
Read current ULIR record into AUX memory, given record number
ReadRecord uith RUbank set to im (set, call, reset)
Read a single VLIR record into RAIN memory, given record number
PointRecord then ReadRecord uith RUbank set to tllAIN (default)
Read a single VLIR record into AUX memory, given record number
PointRecord then ReadRecord uith ftUbank set to |AUX (set, call, reset)
Read a single VLIR record into nAIN memory, given block number of record's
index block (must handle VLIR variables yourself)
Readhle uith RUbank set to inAIN (default)
Read a single VLIR record into AUX memory, given block number of record's
index blocR [must handle VLIR variables yourself)
ReadFile uith RUbank set to lAUX (default)
Urite an indexed 'chain' from HAIN memory, given a pre-al located index table
(in internal indexBlock buffer)
UriteFile uith RUbank set to tllAIN (default)
Urite an indexed 'chain' from AUX memory, given a pre-al located index table
(in internal indexBlock buffer)
UriteFile uith RUbank set to lAUX (set, call, reset)
Urite a file from flAIN memory, given the header block for it
SaveFile uith RUbank set to ItlAIH (default)
Urite a file from AUX memory, given the header block for it
SaveFile uith RUbank set to tAUX (set, call, reset)
Urite current VLIR record from RAIN memory
UriteRecord uith RUbank set to StIflIN (default)
Urite current VLIR record from AUX memory, given record number
UriteRecord uith RUbank set to lAUX (set, call, reset)
.7 *
reset)
1
file: General/SYSTEHdir, page 0, time Hon Feb 22 10:21:51 1988
Specifications proposal for inplementation of /SYSTEH directory
10/27/87
All disks from uhich the flppIeGEOS DeskTop runs an application will
either already have a /SYSTEM directory or have one created. The /SYSTEM
directory (a subdirectory nawed SYSTEM of the root directory) is a special
GEOS subdirectory where systea data files (files of type SYblEM, scraps, and
fonts), desk accessories, and applications can reside. In addition to the
/SYSTttt directory, these kinds of files can also reside anywhere else on any
other directory on the disk.
Kernals
The kernal support planned for the /SYSTEM directory is in the routine
OpenOisk. In addition to its normal function, OpenOisk will also find the
/System direcotry and store the block number of it's key block in the global
variable sysDirBlkno. If there is no /SYSTEM directory found, a wilt be
returned in this word.
Another place where kernal support laiqht be needed is with Desk
Accessories. Uhen a desk accessory is run, it will be assumed that the
current directory will be the directory with the desk accessory (i.e. that
the Desktop and applications will do a GoOirectory before LdOeskAcc or GetFile).
If no change are made to the desk accessory routines, the OA's Swap File will
be saved to the current directory. If the desk accessory were to change the
current directory, then when RstrAppl is called, RstrAppI will not know where
to find the Swap File. The solution to this is to always save and load the
Swap File to/from a fixed location, either the /SYSTEM directory or the root
directory. This will require that both LdOeskAcc and RstrAppl make calls to
GoOirectory to make to the root directory or the /SYSTEM the current directory.
Unfortunately, this will increase overall desk accessory access time.
Applications:
Application handling of the /SYSTEM directory is flexible. It is up
to each application to determine how much support for the /SYSTEM directory
is necessaru. For example, if scraps are supported, then they should be saved
and loaded from the /SYSTEM directory. This is not mandatory, as the saving
and directory oanrpulation must be done by the application, but this allows
other applications to find them. To actually save something to the /SYSTEM
directory will be very simple. Merely use the following code:
Pushy curKBlkno
MoveV sysDirBlkno, rO
isr GoOirectory
txa
bne ErrorHandle
(set up registers for SaueFile)
isr SaveFile
txa
bne ErrorHandle
Popy rO
isr GoOirectory
txa
bne ErrorHandle
fsave current directory
•goto to /SYSTEM directory
•check for errors!
•fSave file to /SYSTEM directory
icheck for errors!
;pop saved curKBlkno into rO
•return to original directory
•check for errors!
For fonts and desk accessories, an application also has a choice of
using any directory or group of directories ic wants. However, to be consistent
with other appUcations it is suggested that only the current directory and the
/SYSTEM directory be used. Then, when a font or desk accessory is to be loaded,
the above code could be used by replacing SaveFile with GetFile. GetFile will
automatically determine whether to use LdOeskAcc or LdFile.
yhen an application wants to gather a list of desk accessories (for the
GEOS menu) or fonts available, it wilt have to do a FindFTypes with both the
current directory and the /SYSTEM directory. Since the /SYSTEM directory is
known from the global variable sysDirBlkno, this is an ideal situation to use
the new Kernal routine FdFTypesInOir which searches in a given directory. The
application will have to keep track of which of the files it finds are from
the /SYSTEM directory and which are from the current directory so it can switch
to the correct directory when it wants to load an arbitrary file from the list.
The sample application will handle this for the desk accessories in the GEOS
menu. This will probably be all that most applications will need.
file! General/SYSTEfidir, pace I, time Hon Feb 22 10?21j51 1988
fin application's data files can, of course, be loaded and saued to any
directory that the application desires, but again, for consistency, only the
current directory should be used. Uhen opening a data file at the start of an
application, the standard NEyDBGETFILES dialog'box routine can be used. The
desktop will aaintain this interface by going to the directory of a data
file that is double-clicked on uhen the parent application is launched.
Desktop**
The Desktop will deal uith the /SYSTEH directory to a greater extent
than either the Kernal or applications.
In addition to hauing to nanaqe the list of Desk Accessories in the
GEOS menu and setting of the current directory for double-clicked data files
mentioned aboue, the desktop will also have to create the /SYSTEfl directory
if none exists, manage a list of applications for a new menu item, handle
dialog boxes with application and desk accessory selection boxes for new
uieu-By-text modes, and qettina printer drivers, input drivers, preference,
and configuration files from tne /SYSTEH directory.
file: forKernal/RUile, page 0, tiae (Ion Feb 22 10:22:25 1988
Interleauing issues
\ The Main issue uith reading and writing files is whether we will be
' able to 'catch the interleave', ft ProOOS disk^s physical sectors are
contiguous, but a ProDOS block, which is Biade up of two sectors has both
inter-block interleauinq and intra-block interleauing. Inter-block
interleauing seperates the two sectors of each block by a single sector.
Intra-block interleauing seperates the two sectors of a block (in addition to
the inter-block interleauinq sector in between theml by a single sector.
The disk spins at 300 rpm and the ftpple 650l runs a 1 Hhz so there are
200,000 cycles per reuolution. fit 16 sectors per track, this works out to
about 12,500 cycles per sector. This means that we haue about 12,500 cycles to
process both between fetching the two sectors of a block (while we're in the
deuice driver) and between fetching contiguous blocks (while in the read and
write file routines).
The deuice driuer is such that there will be uery little tifine to
process data if the interleave is to be taken aduantage of. This means there
must be uery little overhead between calls to ReadBlock (or one of the related
routines) during Readfile or between calls to llriteBlock during llriteFile.
The obuious solution is read or write blocks directly to the
destination address or directly from the source address. The problen with this
is that if complete blocks are read into a destination buffer, bytes after the
end of the buffer will be trashed if the buffer is not a multiple of the block
and the size of the ualid data in the file being read is the sane size as the
buffer. ^
The method used by appleGEOS ReadFile eliminates this Droblem and still
can read blocks directly into their destination. Since a complete list of the
blocks in the file is available beforehand, all blocks but the last can be read
directly into the destination while the final block can be read into some
intermediate buffer for partial copying to the destination. This is done by
scanning ahead in the list of file blocks. This allows us to catch the
interleave if the blocks of a file are contiguous. For the last block, there
will be no more blocks to read, so catchinq the interleave is not important.
This works with reading into both the HfllN'and flUX banks of memory.
For ilriteFile, such a scheme is not possible because the disk routines
can only write to disk from ftUX memory. Therefore, every 512-byte block of
flAIN memory that is to be written to disk must first be copied to HIGH memory
or AUX memory. Vriting from RUX memory can be done without missing the
interleave because no copying is necessary. But writing from HftlN memory
requires copyinq of 512 bytes, which along with the fact that the deuice driuer
has to do work before writing a block eliminates the possibility of catching the
interleave.
file: forKernal/RyjiIe2, page 0, tiwe Hon Feb 22 10:22:25 1988
Oeffiory features of file reading and writing routines
Kith the 128K flpple couies the picture of that 128K mettory as t«o
individual 64K baniis. This liaits the use of the memory because switching
between the two banks in an organized manner is non-trivial.
To alleviate this probiera and still provide the flexibility that more
memory allows, the appleGEDS disk routines allowing reading and writing files
from both the I1AIN and AUXILIARY banks, fl flag, RHbank, controls which bank
files will be read/written to/froia. Generally, this flag will be set to flfllN
for normal applications work.
files forKernal/VBiVoutines, page 0, time Hon Feb 22 10!22s25 1988
The GEOS/Comnodore Block fli location Hap (Bflfl) is replaced uith the
ProOOS Volune Bit flap (VBtl) in the Apple version of GEOS. The VBI1 has the
same function as the BflU, showing uhich blocks on a disk are allocated and
^ uhich are free to be allocated. There are, houeuer, seueral changes in the
f allocation nap foroiat and in the routines that deal uith it.
The UBn is configured as one or nore blocks on the disk it naps. Each
byte of each block represents the status of 8 blocks on the disk, iiithin a
byte, the bits are »apped HSB->LSB to blocks X->X*7 uhere X is some nultiple of
8. So, for example, the first byte of the UBfl represents disk blocks to 7.
Each additional byte represents the next 8 blocks on the disk.
The UBM is allotted at least one block on the disk. So euen if the VBH
reguires only 35 bytes (as it does on a 143K 5.25" flopoy), it use and entire
5iZ-byte block. Since blocks contain 512 bytes, this aiious a single l/Bfl block
to represent (8«512=j 4096 disk blocks. This is the case for 143.K 5.25'
floppies and 800K 3.$' microfloppies. Hard disks, uith upwards of 5 megabytes,
uili require more than on VBH block.
In a normal ProDOS formatted disk, the UBtl usually begins at block i.
For multiple block UBHs, the other blocks occupy blocks sequentially after
block 6. These blocks are allocated at format time, and the size or a disk
is fixed, so there can be no problem uith ever needing to allocate more VBM
blocks.
Therefore, the differences between the ProOOS UBfl and the Commodore Bflfl
are its location, its possible size, and its format. The location of the VBfl
is not in the directory header. The size of the VBfl, although fixed for a
giuen drive type, is different for different capacity driues. The VBH does
not contain a count of free blocks.
These differences affect the GEOS disk routines that deal uith the
m/m. These routines ares CalcBlksFree. FreeBlock, SetNextFree, SetlfFree,
and FindUBIIBit (FindBflHBitl. For example, CalcBlksFree can no longer just
add up the number of free blocks per track (which is stored in the Commodore
Bflfl). In the Apple version, CalcBlksFree has to explicitly check each bit of
the VBfl, and do the appropriate calculations to determine the number of free
blocks on a disk. It might even have to read in another disk block.
The routines, as a group have changed because of a combination of two
of the differences, the location and the size. The routines now employ a type
of cache for the VBtl. The routines have a single block buffer in memory that
it uses to hold the 'current' VBfl block. This makes sense in multiple«block
VBHs, but uith 143K 5.25' floppies and BOOK 3.5' microfloppies, this buffer
aluays holds the one and only llBfl block. The routines aluays maintain a correct
copy of the current VBfl block in the buffer. Ilheneuer access is needed to a
different VBfl block, the current block, if it has changed, is uritten out to
disk before reading in the neu block.
■»?::
ii::
s;Oiu
;
; KE?>^L
BACKGROUND SCREEN
j^f^PLlCA'IO^ SFhCE
1
1
i
1
i
i
KEiv^iA-^E-^ITE E^F'ESr ,
FCri:TC-'.^i' SCr.EE.\ ^
liCRE ^ERf-^1 i
r1f\?
»=■::»: -
5:;oo -
5e:c: -
5kC0 -
s;-iv -
5^::: -
-
-
5:;:: -
5-::: -
i-::: -
Ji::: -
I/O iFACE
r::.E}RD.N? sC^-EE^.
5 i^.
! •■
1"
w
i
! I
I 2-^
! :
! I
; i
; ■
- /;-
/I
■i-
KErj''(Ai.
AFFL!C«TI^ iFrCE
\
A
2
f
o
J
a-
-a.
»N»:VT JS'jii^
NSJD3.
030
Z 'PAGE
VDOO
C'20:,
6C500
1)6 \!U5^ S
D 3
dcc<)
I
ceo
^ ^^-X€>\ "Ro vJT 1 ^£5 (£000 - FPT=?
<<<
OCO
UTiLi"r\,sS
MAIM
p£oo
£&:>!}
62,00
t.Cac
9^00
'2/ o
'2^ Eii:
L0CA.i-
IB \CoM^
I coo
0&«5O
020)
OCcO
TA3^£S -6<soo t\o)C)
ceo
•41
M16C
42®
•
i
!
1
1
1
1
I>£oO
F OMT3
•
<<<
2 = 3
ceo
sna :
f» J-. -- •
«
^— ^
<
T
E
5
•
• -
files ftppleSpriteGuide, page 0, tiae Thu Mar 24 IZsJl^U 1988
Files flppleSpriteGuide (128sprtte6uide)
Author: Jin OeFrisco
Date: 14 January 1987
Purpose: This file explains what needs to be done to convert
the portions of C64 6E0S applications that deal uith
sprites to run under Apple GEOS.
Baci^ground Info:
The C64 contains a chip to handle sprites in hardware.
Unfortunately, this chip is not available on the Apple,
so the functions of that chip have been sinulated in
software that is included in the kernal. Host of
the capabilities of the VIC chip haue been taken care
of, and if you are not doing exotic things uith sprites
your code nay work uith one or tuo changes.
The aaior changes include: sprite (the cursor) is
treated differently than any other sprite. The code
for this beast has been optiaized to get reasonably
fast nouse response, uith a resulting loss in
functionality. You cannot double the cursor's size in
either x or y. You cannot change the color of the
cursor. The size of the cursor is liiited to 16-pixel5
uide and 8 lines high. One added feature is the ability
to add a uhite outline to the picture that is used for
the cursor. This allows it to be seen while nouing
ouer a black background.
For the other 7 sprites, all the capabilities have been
emulated except for color and collision detection. In
addition, the <4th byte of the sprite picture definition
(previously unused] is now used to provide soae size
info about the sprite. This is used to optiaize the
drawing code.
To change your code over, look over the following list
of possible problen areas. This list will be updated
as Bore probiens are found, and you should add an entry
when you cone up with a new one.
Q
file: flppIeSpriteGuide, page 1, tine Thu flar 24 12:51:16 1988
Sprite Problen Areas:
To make sure your sprite code «iH run under fippleGEOS, read ouer the
following lisl. If you see a problen that applies to your application,
take the appropriate corrective action. If you encounter a problen
that is not listed belou, add a solution when you cose up wich one (or
state that a solution is not possible).
PROBLEM SOLUTION
l/riting directly to the screen
Change the cursor picture (sprite 0)
Use a large picture for the cursor.
All sprite picture data
Since the old sprite were handled with
hardware, writing to the screen uasn^t
a problen. If you do it (systeiB calls
NOT included), then call 'TenpHidedouse'
before the write. This will erase the
cursor and any sprites you haue enabled.
You don^t haue to do anything to get
then back, this is done autonatically
during the next eain loop.
This should be done with the new call
■SettlousePicture'. The source for
this routine is in /staff/jim/applegeos/
Sprite/softSprites. There is a liuit to
the size of che cursor to 16 pixels wide
and 8 lines high, and you cannot use
■double in x or y'.
You should discontinue using sprite
for this. Uhen you need to change the
arrow to something large, disable sprite
and use another sprite that tracks the
fBousePosition uariables. Right now, the
only way to disable sprite is to giue
it a null picture or clear the low bit
of mobenble. , A "disable aouse" call
should be added soon.
All picture data should be adjusted to
include the 64th byte. This byte has
size inforoation that is read by the
software sprite routines, euen if they
are garbage ualues. The foraat of this
byte is: nigh bit set iieans that the
sprite is no sore that 8 pixels wide
(this neans it can be shifted 7 tines
and still be contained in 2 bytes). The
rest of the byte is a count of the scan
lines in the sprite. You can either
include this info as part of the picture
definition, or stuff it into the right
place with sone special code.
file: AppleSpriteGuide, page 2, tiae Thu Har 24 12:51:16 1768
PROBLEfl
SOLUTION
Uriting directly to the VIC chip
Reading ualues froo the VIC chip
This is generally ok, since the sprite
enulation routines take the position
and doubling info froa the registers on
the VIC chip,. with the exception of the
X position. The VIC chip allows 9 bits
for X positions, uhich is not enough
for a 560-wide screen. You should write
the X position to the qlobal variables
•reqXposO, regXposl...' (request x pos).
These are full words, in consecutive
locations. Better yet, use the
■PosSprite' call in the kernel.
This is also ok for the status ualues
and for the y position. The x oosition
should be read froa the reqXposO regs.
Using VIC chip collision detection There is none.
Uriting to the VIC chip for calling
PosSpnte, EnablSorite, DisablSprire)
at interrupt level
Turning the nouse On/Off
Don't do it. Since the sprites are
drawn at aain loop, this causes subtle,
irreproducable tiainq bugs that are
impossible to oet out. It is all right
to change the House's position here,
since the aouse is drawn at interrupt
level also.
The aouse cursor is the only ■sprite'
that is drawn at interrupt level.
There is now a byte (called offFlag)
that is used to tell the interrupt code
what the status of the nouse currently
is. Uhen TeapHidetlouse (or any graphics
routine) is called, the nouse is erased
fron the screen. The value $80 is stored
in offFlag tq. tell the interrupt code
not to draw the aouse. Uhile the value
in offFlag is $80, the aouse will NOT be
redrawn or erased. Uhen we wish to have
the aouse redrawn, we store the value
^40 in offFlag, which tells the
interrupt code to resuae drawing the
aouse. nain Loop stores this value in
offFlag when the application returns to
it. A value of $00 In offFlag allows the
interrupt code to function noraally
(erase and redraw the aouse whenever
necessary) and is stored there by the
interrupt code.
file! changes, fonts, page 0, time Thu Har 24 12j52!02 1988
Font changes'
Now the systet font is located in auxilliary aeiiory. There is plenty of
space on the aux side, so the apolications uill probably want to use it for
holding the font data. Certain flags need to be set to tell the font routines
that the fonts are in auxilliary aenory. If the font is in nain nefBory, the
application should call LoadCharSet as usual. But, if the font is in auxilliary
nenory, it should call LoadAuxCharSet, uhich sets a bunch of flags and uars for
the font routined.
Most of the font uariables still exist in flppleGEOS. Three variables
lie in sain nenory where the application can easily access then:
baselineOffset
currentSetliidth
currentHeight
Tuo of the uariables lie in the alternate zero page:
currentlndexTable
cardDataPo inter
If the application needs to access these. It nust first do a 'sta ALTZP ON' and
then access then, and then do a "sta flLTzPJFFV Remember that ALL of tHe aain
(application) zero page and stack is swapped out here, so it cannot be accessed
until the 'sta ftLTZPJFF' is executed.
file: changes. db, page 0, tine Thu Har 24 12:51:40 1988
This file contains the lany changes iade in the dialog box routines:
DBUSRROUTIHE: He nou assune that only ONE DBUSRROUTINE call is lade
per dialog box. This call is nou nade AFTER the icons are displayed. This nakes
It possible to use DBUSRROUTINE to put stuff up ouer the icons...
DBGETFILES: Holding the button doun on the scroll icon aakes the
scrolling continue. Ho Hui... Also, the buffer that holds the filenanes is in
auxilliary tenory, and uill hold 32 filenanes.
DBGETNflriES: This is exactly like DBGETFILES except that the user
passes the address of a routine to load a buffer with the nanes to be displayed.
This routine should:
Clear out the buffer in auxilliary aienory froa $7B00 - $7B50
Clear the hiqh bit of r7H and decrenent r7H for each nane stuck in
the Duffer.
Put up to 32 file naaes in the buffer (starting at $7600 in aux nen)
The names nay be up to 15 characters long, ^ a null terninator.
fl buffer can be cleared in auxilliary nenory by doing a 'sta RflHilRT ON'
before the call to ClearRan and a 'sta RfirtllRtJFF' afterwarls.
The Dialog Box table entry for this routine is as follows:
.byte DBGETNfinES
.uord Address of routine to get names
•byte xpos.offset of file box from corner of DB
.byte yposloffset of file box froa corner of DB
NEUDBGETFILES: This routine has a whole slew of fun new features...
You can see the spec file for a description. Here is what you need to know to
use it:
The NEUDBGETFILES dialog box puts up its own OPEN icon. But the
application can treat it as if it were its own OPEN icon.
The NEUDBGETFILES box returns the selected file naae in the same Banner
as DBGETFILES does... It also returns the directory block in
which the file lies in the global variable curKBlkno.
The NEUDBGETFILES table entry is of the following format:
.byte NEUDBGETFILES
.byte file box x offset
.byte file box y offset
.byte open icon x offset (bytes)
.byte open icon y offset
.byte directory icon/pathnaae text x offset
.byte directory icon/pathnaae text y offset
ICONS: There were aany new system icons added also. The complete list
is now:
CANCEL,flK,YES,NO,OPEN,DISK,ORIVE,QUIT,CREATE and IGNORE
These can be used by applications outside of the dialog boxes.
They lie in auxilliary aemory, and their addresses are equated
to the constants: CANCELJCNJDDRESS.OKJCNJDDRESS, etc...
Also, the dialog boxes nou allow 16 icons to be displayed!
file? changes, string, page 0, tiae Thu Har 24 IZ^SJOO 1?88
For PutString!
ft change has been aade in PutString to fix a snail •bug". In M4 GEOS,
?[1^S?C!59 ^loes not handle any yarqin faults (i.e. If ue attewpf to print out
•»Byni;, and only fits, PutString uill keep trying to output characters
until the end of the string is reached). Now, PutString uill test to see if
there is a user specified StringFauItVector. If not (StrinqFaultUector « SOOOO),
then It uill put its oun StringFauItVector in, uhich uill aerely exit the
PutString routine when the aargin is reached.
ft change has been aade in GetString. SystenStringSeruice nou always
null-terninates the string in the buffer (i.e. even while the user is inputtinq
the string, it is null-terainated).
files changes. icons, page 0, tine Thu tlar 24 12:53:28 1788
This file contains the changes »ade in the icon and senu routines.
Icons:
The icon pictures can nou be 'double uidth' and can also lie in
aux nenory. Also, the icon routines currently noue the nouse
when they are run. This option can be disabled. Uithin the
table, flags are set to show that these options are active.
These flags ares
.word XPositionOf House $Set high bit to disable eouse
; Boue
.byte XJOSJCON 5Set high bit to signify that
Uhe icon picture lies in
I'auxilliary Beaory
.byte BytellidthOflcon ;Set hiqh bit to signify that
;ue uant the icon data to be
I'double-uidth
Menus:
DoHenu currently places the nouse ouer the nenu iten passed
in the accunulator... Nou, if the ualue in the accunuiator is
negative, the Doftenu routine does not noue the louse.
file! changes. grapp
ccs 0, tiw Thu Har 24 12:53:25 1988
For bitnaps:
There are nr-r :yo entry points to the bitmap routines. The old ones
still work (BitnapCi BitnapOp. etc). There are now also new routines with
a new format (Neubit:>:-::DCnp, HeuBitoapUp). This fornat allows routines to
place bitmaps on a pixel boundary and to let a bitnap haue a pixel width.
The pixel width convention is as follows:
flssuning a bitmap with a pixel width of 11, the first line is represented by
X's and the second line is represented by Ts; The bitmaps must lie in memory
as follows:
byte 10: XXXXXXXX
byte «1: XXXUUUUU ;The pixel boundary lies within a byte
byte 12: YYYYYm ? so the remainder of the byte will be
byte t3: YYYUUUUU ; ignored (U stands for unused bits)
Also, the BitmapUp routines allow the icons to be doubled in width. To
use this option, set the high bit (bit 7) in the high byte of the pixel width
(for NewBitmapUp) or the high bit in the byte width (for BitmapUp). The
routine will double the width of the bitmap, but not the x coordinate of the
bitmap .Also, the routines allow the bitmap to be in auxilliary ram. To enable
this option, set the high bit in the x coordinate.
The parameters that are passed to the routines have changed. These
changes are described here:
ffff««fi»«ililiifliifiliiiilili«iii«iii««il««i«ilii«««««»«ii«iiliiilifi««li««ii*
Parameters for BitmapUp:
Pass:
rO - pointer to the bit mapped data
rlL - x byte position for the bit mapped data (0-69)
NOTE: if bit 7 is set in rlL, the bitmap is in aux. ram
rlH - y pixel position for the bit mapped data (0-191)
r2L - wUth in bytes of the bit mapped data (0-/0)
NOTE: if bit 7 is set in rzL, the icon is doubled in X
(bitmap width is doubled)
r2H - height in pixels of the bit mapped data (1-192)
Pass: (inline)
.word dataPointer
.byte xCoord
.byte yCoord
.byte width
.byte height
Parameters for NewBitmapUp:
Pass:
rO - pointer to the bit mapped data
rlL - height in pixels of the bit mapped data (1-192)
rlH - y pixel position for the bit mapped data (0-191)
r2 - width in pixels of the bit mapped data (0-560)
NOTE: if bit 7 is set in r2H, the icon is doubled in X
(bitmap width is doubled)
r3 - x pixel position tor the bit mapped data (0-559)
NOTE: if bit 7 is set in r3H, the bitmap is in aux. ran
Pass: (inline)
.word dataPointer
.word xCoord
.byte yGoord
.word width
.byte height
...c- uiioiii^ca.ijrdpnics, page 1, time Thu flar 24 12S53525 1988
li«liilltl«fii«iilililfffliliif|ffffilf|«||iiliiifiiiiltli«iii|f|«t|«s||«f|||tsi||«t
Paraneters for BitBapCMp:
Passs
rO - pointer to the bit Mapped data
rlL - X byte position for the bit tapped data (0-691
, , NOTEj if bit 7 is set in rlL, the bitnap is in aux. ran
rlH - y pixel position for the bit napped data (0-192)
r2L - width in bytes of the bit lapped data (to print) (0-70)
NOTE* if bit T is set in r2L, the icon is doubled in X
(bitnap width is doubted)
r2H - height in pixels of the bit napped data (to print) (1-192)
rllL - nunber of bytes to skip each row
rllH - number of bytes to sliip after printing each row
rl2 - nunber of lines to skip before printing
Parameters for NeuBitnapClip-'
Pass!
rO - pointer to the bit napped data
rlL - height in pixels of the bit napped data (to print) (1-192)
rlH - y pixel position for the bit napped data (0-192)
r2 - width in pixels of the bit napped data (to print) (0-560)
NOTE: if bit 7 is set in r2H, the icon is doubled in X
(bitnap width is doubled)
r3 - X pixel position for the bit napped data (0-559)
NOTE: if bit 7 is set in rJH, the bitnap is in aux. ran
rllL - nunber of bytes to skip each row
rllH - nunber of bytes to skip after printing each row
rl2 - nunber of lines to skip before printing
»ifiiiiii«iiiiii»iiiiiiiiitiii§i«iiiiiiiiiiiifiiiii«iiif fiifiii«itt«m)iiiiii,iim
file: RUblock, page 0, ti»e Thu flar 24 12:06:27 1988
•iilifilfiiffiiifilillllllfifiliilfililillffflfiff lifffillXliillfiliiilliiS
ReadBlock
synopsis
prouides the Apple equiualent of the Coo»odcre's lotf level
routine
Authors
Brian Chin February 1988
Called by: ^
Pass:
rl — block nuaber
r4 — buffer address
RVbank — bank to use
Accesses:
curDriue — drive to read block from
Returns:
X — disk error
Alters:
y
Calls:
GetBlock
«iiififffi«ifffiiii«iifiiiiiiif«fiiffiiiii«ii«ifffffiif«iiiiiiitiiiii«iifiii
ReadBlock:
jmp GetBlock ithese are equaivalent routines
file: RUblock, page 1, tine Thu flar 24 12:06:29 1988
;iiiiifiiiiiifi<iiifffi«iiffffiiiiiifffiiiiiiffiiiiiiiiifiiii«iiiiiiiii«s«ifis
s UriteBIock
$ synopsis
; provides the Apple equivalent of the Comodore's lou level
I routine
; Author:
; Brian Chin February 198B
; Called by: ^
; Pass: •
I rl — block nuttber
; r4 — buffer address
; Rybank — bank to use
f Accesses:
\ curOrive — drive to read block frou
f Returns:
; X — disk error
; Alters:
; a, y
Calls:
PutBIock
iififfiifff<iiii«fffif«i«ii«iiiiffiiiiiiftiififiiiiiiiffifi«iiiii««iftf liiitii
VriteBlock:
PushB nunDiskRetries ;save global retry count
LoadB nuBjOiskRetries.lO Jset to zero for no retries
isr PutBIock ;put block to disk u/o retries
PopB nunDiskRetries ;restore nuaber of retries
rts ;return with error fron PutBIock
file: Ryblock, page 2, tioe Thu Har 24 12!0i!29 1988
;«ffiiiiiiiififiiffffiiiiffiiiiiiffifiiiiiiiiiiiffiiiiii«iiii«iifi««iifiiiii««f
; l/erUriteBlock
$ synopsis
I provides the equivalent of the Connodore GEOS Kerna]
; routine
Authors
Brian Chin February 1988
Called by: ^
Passs
rl — blocli number
r4 — buffer address
RUbank — bank to use
flccessess
curDriue — drive to urite
nuffiOiskRetries — global retry count
Returns:
X — disk error status
filters!
a, y
Calls:
ReadBlock (Kernal routine)
IfriteBlock (routine above)
lffiffffffil«ff««illf«iiiil«||f|«ili««iff||fiSiiii||iii|f|fiiliifilfiliiflfif
generalBuf
VerVriteBlock:
{address of KernaTs internal diks buffer in
; AUXILIflRY aeaory
10$:
90$:
PushB
Idx
Ida
beq
PushU
PushB
Loady
LoadB
PopB
PopV
txa
beq
dec
jsr
txa
beq
PopB
rts
nunDiskRetries ;save global retry count
to ;assuoe no error in case of no retries
nunDiskRetries ijet global retry count
90$ tif no retries, do nothing
r4 isave buffer address
RUbank ;save bank status
r4.SgeneralBuf ;use Kernal internal block buffer
RUbank, tflUX
ReadBlock ;read block to verify it
RUbank , irestore bank status
r4 irestore buffer address
90$ 5if no error, exit
nunDiskRetries iadjust retry count to indicate upcoiing attenpt
UriteBlock icall our urite block routine (above) that
I does no retries
10$ ;if no error, Iood back to verify it
tif error, exit ioiBediately
nunDiskRetries
files print0ut2.agl, page 0, tin Thu Har 24 11M4--J4 1?88
CEOS Variable docuDentation
Preliainary release 3/23/88
file-' printGut2.ng], page 1, tine Thu Har 24 11:46:54 1988
iiauic *
alarnSetFlao
PnrMor 1 ii S
roiRcr ly*
nuurcds *
w 1 fcC
Byte
Default:
FALSE
javcu! *
No
Oacr r 1 nf 1 nn S
Uc9cr ipw luii*
TPIir if thp fllArn <pf! fnr npn< fn nnnitnr p1<(p FOI
Note:
Name:
a larnTtttUector
Ffirtt^r lui
1 U 1 Mw 1 » y
AdHr^s^:
nuui
C64: §84ad C128: $84ad Aoole: $0212
Size:
Vord
Default:
Saued?:
Yes
uescr ipv lon*
dUQic?? or d scrviwC iDUbinc lur wne aidrni wiuCR biRic ouv
(ringing, graphic etc.) that the application can use if
nprp<cAru
tlwbk^^Ql y »
Note:
liU Ww *
Nane:
alphaFlag
Formerly:
•
Address:
C64: $84b4 C128: $84b4 Apple: $0225
Size:
Byte
Default:
if not gettinq text input
llxxxxxx if getting text input, where xxxxx are counter bits
Saued?:
Yes
uescr ipc lon*
n^n fnr ;i1nhAniimpr ir ^trinfl infiut
r idQ lUi a ipndnuoici lu ^wi in^ mpuv
bit 0-5 - Counter before pronpt flashes
bit 6 ' Flag indicating prompt is visible
bit 7 - Flag indicating alphanuiseric input is on
Note:
liuulC ■
rinnfldin
r r
Fflrn^r 1u:
1 u 1 Hci • y
addI icdtiontlain
nuui C^T> *
C64: S849b C128: S849b Apple: $0200
Size:
Hord
uerauii*
Saued?:
No
Description:
Vector that allows applications to include their own sain loop
code. The code pointed to by appftain will run at the end of
every EEOS lainloop.
Note:
files print0ut2.agl, page 2, ti»e Thu Har 24 ll!46s34 1?88
Nane:
backBufPtr
Foraerlys
flddresss
C64: NA Ci28: $131b Apple: $9d7c
Q 1 70 ■
W 1 4C*
16 bytes
Default:
None
Saved?:
No
Description:
Screen pointer where the back buffer cane from.
Resides in back ran of C128 and Apple.
Note:
Name:
bakclrO. bakclrl, bakclr2, bakclr3
For»erIy:
Address:
C<4: $do21 - 4do24 respectiuely
C12a: ^do2l - sdo24 resoectiuelu
Apple: NA
Size:
1 Byte each
Uetau It*
davcuf *
No
nu
ucscr ip V lun*
RArknrniinrl colors 0*3
nu wc*
Name:
backXBufNuR
Foraerly:
Address:
C64: NA C128: n32b Apple: $d98c
Size:
8 bytes
Default:
Hone
ddueof *
no
vcscr ip V 1 on*
For fiArh ^nritp thpr# W nnp hutp h^rp for hou Bdnu hutffS
rUI cavil l*Ct WIICIC I9 UIIC uyvc IICI C i ui nwv waiiy wywb7
wide the corresponding sprite is.^ Used by C128 and Apple
9ulW VC iVIU*illC9 QIIU iC9l III VOWR I BUi •
nu wc •
Naae:
backYBufHuB
Formerly:
Address:
C64: Hfl C128S $1333 Apples $d994
Size:
8 bytes
Default:
None
Saved?:
Ho
Description: For each sprite, there is one byte here for hou nany scanlines
high the corresponding sprite. Used by C128 and Apple soft
sprite routines and resides in back raa.
Note:
Nane: bootNaeie
file: printOutZ.ngl, page 3, tine Thu flar 24 11:46:34 1988
rorBicr ly*
nuui
c^4: scoo^ C17A: ^roo/( Onnip: <rnn?
9 But?^
Default:
6E0S BOOT
Saued?:
Ho
Description:
This is the start of the 'GEOS BOOT' string.
Note:
naUK *
Foraerly:
Address:
C64: $84af C128: $84af Apple: $0214
Size:
Uord
Default:
Coraroodore - SCf85
Apple - $FEF}
Saved?:
Yes
Descr iot ion:
Vector to the routine that is called uhen a RRK in^t:riirf inn i<
encountered. The default is to the operating systeia
'^u^tpii Prrnr' Hitilnfi hnv rniitinp
wy^wcii bi 1 UI uiaiuu uua iuuviiic*
no vc*
naioc *
hif iipr
UK vcu
Forner tu*
Address:
iiu w 1 www
C64: $0916 C128: i316 Aoole: NA
WW* Y"^*** W4fcW y^*W IllrlrlW lilt
Size:
Uord
Default:
????????
Saued?:
No
Description:
BRK instruction uector for uhen ROfls ar? switched in.
Note:
Nafoe:
basel ineOffset
rnrnpr 1 ii s
1 ui ifici 1 y *
nuui *
C^d: C128: £76 floole: §0218
Size:
Byte
Default:
$06 - for BSy 9 font
daUcUf*
ICS
UC^bl 1 U V lull *
Offset frnn tnn line to hA<p1inp in character <pt i p \t
U i 1 9C« 1 I UHI WUU 1 1 liw WU Ua^C llllw lit wtiuiow 9C b* ItCt IV
changes as fonts change.
Note:
Nane:
CPUJATA
For»er1y:
Address:
C64: $0001 C128: NA Apple: NA
file! printOutZ.agl, page 4, tiae Thu Mar 24 11j4<!34 1988
Size5
Default:
Saved?!
Description!
Uord
RAnj4K ($30)
No
Address of 6510 data register that controls the hardware nenoru
nap of the C64. The following constants are used with CPU.DfiTA.
Value
10 IH
RAH 64K
KRNU BAS 10 IN
KRNnO TN "
dapping
<0K RAH, 4K I/O space
64K RAH
both Kernal and basic ROtIs napped into s^ory
Kernal ROM and I/O space napped into menory
Note!
Name!
Foraerly!
Address!
Size!
Default!
Saved?!
Description!
Note!
CPUJOR
C64! $0000 C128! NA Apple: NA
Byte
No
address of 6510 data direction register
Nane:
Foriaerly!
Address:
Size:
Default!
Saved?:
Description:
Note:
cardDataPntr
cardOataPointer
C64: $2c C128: $2c Apple: $60
Uord
Coottodore: $D2DC - for BSil 9 font
Apple: $0150 - for BSU 9 font
Yes
This is a pointer to the actual card graphics data for the
current font in use
Naote:
Fornerly:
Address:
Size:
Default:
Saved?:
Description:
Note:
Nane:
curDirHead
C64: $8200 C128! $8200 Apple: $FA80
Conaodore - 256 bytes
Apple - 39 bytes
$00
No
For Coflttodore, it is the buffer containing header infomation
for the disk in currently selected drive.
On the Apple, curOirHead contains the header of the current
directory. Initialized to all zeros.
curDevice
file! print0ut2.ngl, page 5, tine Thu tiar 24 ll!46!34 1?B8
Formerly!
Address!
C64: m C128: $ba Apple: NA
Size!
Byte
Default!
Comaodore « $08
Saved?!
No
Description!
This holds the current serial deuice number. See curDrive
for Bore information
Note!
Nane:
curDriue
For«erly!
Address!
Ci4! $8489 C128: $8489 Apple: $F<Od
Size!
Byte
Default!
Commodore - $08
Apple = $00
Saued?!
No
Description!
Holds the deuice number of the currently actiue disk drive.
For Commodore, allowed values are 8 - 11. For Apple, drives
are numbered 0-3.
Note!
Name!
curEnable
Fornerly!
Address!
C64! NA C128: $1300 Apple: $0951
Size!
Byte
Default!
None
Saued?!
No
Description!
This is an image of the C<4 mobenble register. Used for C128
and Apple soft sprites.
Note:
Hairie!
curHeight
Foroerly!
currentHeight
Address!
C64: $29 C128: $29 Apple: $021B
Size!
Byte
Default:
$09 for BSB 9 font
Saued?!
Yes
Description:
Used to. hold the card height in pixels of the current font in
use.
Note!
Nane!
curlndexTable
Formerly!
currentlndexTable
Address!
C64: $2a C128: $2a Apple: $005E
file: print0ut2.figl, page 6, tiK Thu liar 24 11:4604 1988
Sizes Word
Default: CoBuiodore: $D218 for BSU 9 font
Apple: $0C08 for BSy 9 font
Saved?: Yes
Description: curlndexTable points to the table of sizes, in bytes, of each
card in of the current font. On the Apple, this variable only
exists in the back ran zero page. Aponcations nust switch
zero pages before accessing it directly.
Hote:
Nafoe:
curnobx2
Fomerly:
Address:
C64: HA C128: $1302 Apple: $D953
Size:
Byte
Default:
None
Saued?:
No
Description:
Imaoe of the C64 Bobx2 register. Used for C128 and Apple
soft sprites. Resides in back ran.
Note:
Narne:
curnoby2
Foroerly:
Address:
C<4: NA C128: $1301 Apple: $0952
Size:
Byte
Default:
None
Saued?:
No
Description:
Inaqe of of C64 Roby2 register. Used for C128 and Apple
soft sprites. Resides in back ran.
Note:
Nane:
curPattern
Foraerly:
currentPattern
Address:
W4: $22 C128: $22 Apple: $022c
Size:
yord
Default:
$0010
Saved?:
Yes
Description:
curPattern points to the first byte of the graphics data for the
current pattern in use.
Note:
Each pattern is 1 byte wide and 8 bytes bytes high, to give an
8 by 8 bit pattern.
Apple: The location of patterns pointed t/ bu cLrPattern is in
back raiB and should not be accessed directTyr^See SetPattern
and GetPattern.
Hai&e: curRecord
Formerly:
files printOutZ.ngl, page 7, tiae Thu flar 24 ll!4i!34 1988
flddresss C<4: $849i C128: $8496 Apple: $f<18
Sizes Byte
Default: $00
Saued?: No
Descriptions Holds the current record number for an open ULIR file.
Note: Uhen a VLIR file is opened, using OpenRecordFile, curRecord is
set to if there is at least 1 record in the file, or -1 if
their are no records.
HaiBes
Former lys
fiddresss
Size:
Default:
Saued?:
Descriptions
currentHode
C64s $2e C128: $2e Apple: $021C
Byte
$00
Yes
Holds the current text drawing node. Each bit is a flag for a
drawing style. If set, that style is actiue, if clear it is
inactiue. The bit usage and constants for naninuplating these
bits are as follows.
Bit Style Constant
b7: Underline flag SET UNDERLINE - XIOOOOOOO
b6: Bold flag SETlOLO « XOIOOOOOO
b5: Reuerse flag SETlEUERSE « XOOIOOOOO
b4s Italics flag SETlTflLIC = MOOIOOOO
b3s Outline flag SEFOJITLINE « XOOOOIOOO
b2s Superscript flag SET"SUPERSCRIPT=J:00000100
bis Subscript flag SET SUBSCRIPT - XOOOOOOIO
bO: Unused
Clears all flags (plain text) SETJLAINTEXT = WOOOOOOO
Any combination of flags can be set or clear. If current
node is plaintext, all flags are clear.
Constants that can be used within text strings themselues that
affect currentflode ares
UNDERLINEON, UNDERLINEOFF, REUERSEON, REVERSEOFF, BOLDON,
ITflLICON, OUTLINEON, PLAINTEXT
Note:
Natte: curSetVidth
Formerly: currentSetllidth
Address: C64: $27 C128s $27 Apples $219
Sizes llord
Defaults Coonodores $005c
Apples $0051
Saued? s Yes
Descriptions Holds the card width in pixels for the current font
Notes
Na»es curType
Formerly:
file: printOutZ.agl, page 8, tine Thu flar 24 11:46:34 19B8
Address: C64: $88ci C128: $88c6 Apple: Nfl
^Size: Byte
Default: Disk type of driue 8 for Comnodore
Saued?: Ho
Description: Holds the current disk type. This ualge is copied fron
driueType for quicker access to the current drive
b7: Set if the disk is a RAH disk
b6: Set if using disk shadouing
Only one of bit 6 or 7 nay be set. Other constants used with
curlype are
DRUjULL "0 No driue present at this device address
DRU 1541 > 1 Driue type Conmodore 1541
DRU 1571 « 2 Drive type Connodore 1571
DRVJ581 « 3 Drive type Comaodore 1581
Note:
Naoe: curXposO I q \^^f[f^
Forserly:
Address: C64: NA C128: /<1303/ Apple: $0954
Size: 16 bytes ^ 7
Default: None
Saved?: No
Description: The current X positions of the C128 and Apple soft sprites.
Resides in back ran.
Note:
Nane:
Formerly:
curYposO I ^ \r^(£Ky>^
Address:
C<4: NA C128:/il313y Apple: $0964
Size:
Default:
None
Saved?:
No
Description:
The current Y positions for the C128 and Apple soft sprites.
Resides in back ran.
Note:
Nai&e:
devUnitTab
Fornerly:
Address:
C64: NA C128: NA Apple: $FAEF
Size:
4 Bytes
Default:
$60 in each byte
Saved?:
No
Description:
The ProDos unit nuabers of the four possible devices are kept
here. Used for conaunicating with the device drivers.
Note:
deuTabHi
file: printOutZ.ag], page ?, tine Thu Har 24 11:46:34 1988
Fornerly:
fiddress:
Cj4: NA C128: NA
Apple: deuTabHi - $FA£7, devTabLo - $FAEB
Size!
4 Bytes each
Default:
deuTabHi - $D0 in each byte, devTabLo - $00 in each byte
Saved?:
No •
Description:
For the Apple, these are the high and lou bytes of the four
possible device drivers.
Note:
Naoe:
dirBUno
Foraerly:
Address:
C64: NA C128: NA Apple: $F620
Size:
Uord
Default:
$02
Saved?:
No
Description:
Block number of the key block of the directory containing
this file's entry.
Note:
Name:
dirPtr
Formerly:
Address:
C64: NA C128: NA Apple: $F622
Size:
Uord
Default:
$00
Saved?:
No
Description:
Pointer into diskBlkBuf for this file's entry.
Note:
Haiae:
diskBlkBuf
Fornerly:
Address:
C64: $8000 C128: $8000 Apple: $F659
Size:
Comaodore - 256 bytes
Apple - 512 bytes
Default:
$00
Saved?:
No
Description:
Eeneral disk block buffer. Initialized to all zeros.
Note:
Nai&e:
doRestFlag
Formerly:
Address:
C64: NA C128: $lb54 Apple: $DBld
Size:
Byte
files print0ut2.Bgl, page 10, tine Thu tlar 24 11546J34 1988
Defaults
Saued?s
Description*
Note!
FALSE »
No
Flag needed because of overlapping soft sprite problens on C128
and Apple. Set to TRUE if ue see a sprite that needs to be
redrawn and therefore all higher numbered sprites need to be
redrawn as well. Resides in back Raa.
Naoie:
Fornerly!
Address:
Size!
Default!
Saved?!
Description!
Note!
driueType
C64! $848e C128! $848e Apple: $FAF3
4 bytes.
Set to type of drive 8 on Connodore or drive on Apple.
No
There are 4 bytes at location driveType, one for each of four
possible drives.
For CofWBodore, each byte has the following for»at!
b7: Set if drive is RAH DISK
h6' Set if Shadowed disk
Only 1 of bit 7 or bit 6 aay be set
Constants and values used for drive types are
Constant Value Type
DRV NULL No drive present at this device address
DRU'"1541 1 Drive type Commodore 1541
DRri571 2 Drive type Commodore 1571
DRVJ^Bl 3 Drive type Commodore 1581
For Apple, the only differences between drive types is whether
the drive media is removable (e.g. floppy) or non-removable
(e.g. hard drive). The bit usage is as follows:
b7! set if disk medium is removable
b6! set if device is interruptable
b5,4! number of drives on the device (0-3)
b3! device driver supports format
b2! device driver supports write
bl: device driver supports read
bO: device driver supports status call
Th
d
his bit usage conforms to the information ProDos keeps about
isk drives. 6E0S, however, only makes use of bits 7 and 3.
Name! drSizeLo, drSizeHi
Formerly! driveSizeLo, driveSizeHI
Address: C<4! NA C128! NA
Apple: drSizelo - $ FAF7, driveSizeHi - $FAFB
Size: 4 Bytes each
Defaults Hone
Saved?! Ho
Descriptions The low and high bytes of the sizes of the four possible
device sizes.
Note:
file! print0ut2.ac'
, tine Thu tlar 24 11:4^:34 1788
Kane:
disi^^ j
Forftcrlys
Address^
C44: ^^43a Ci28: $848a Apple: $F617
Sizes
Byte
Default:
TRUE (§FF)
Saved? 5
No
Description:
Set to TRUE or FALSE to indicate ubether a disi is currently
open .
Note*
Name:
DrflCurOliNa
Forsier lys
Address!
Cj4< $841e C128s $841e AddIc: i?M7
Size*
Commodore • 18 bvtes
Apple - 14 bytes
Default:
None
Saved?:
No
Descr iot ion:
This is the disk name of the current disk in drive A.
Illl^ 1^ vllW II WUIW wl «IIW WWIIWIlV Ul^n III Wl IVW 111
Commodore - padded uith $A0
Annlp *- nAHHpri uitK ADO
nuu ic pauucu m i vii yvv
Note:
Na»e:
DrBCurDkN«
Fo(»erIy:
Address:
C44: $8430 C128: $8430 Apple: $FAB7
Commodore " 18 butes
Apple - 14 bytes
Default:
None
Saved?:
No
np<rr 1 inn ■
Thi< 1^ thp di^k nAfhP flf the current di^k in drive B.
11119 19 Vllu U 1 9K llQUtC U 1 VllW WUIIwllV UI9I^ III Ul IVw U*
Commodore - padded yith $A0
Anole " oadded uith SOO
nupiw VHUucu w 1 VII
Nntp:
Nase:
dataFileName
Foraer ly:
Address:
C44: $8442 C128: $8442 Apple: $02A4
Size:
Cnnnndore * 17 bvtes
bUIWiiWUUI C *•
Apple - 14 bytes
Aof All If!
uerau IV*
Mil AM
none
Saved?:
Hp
Description:
This is the naee of a data to open. The name is passed to the
parent application so the file can be openned.
Note:
file: printOutZ.sgl, page 12, tine Thu Har 24 11:46:34 1788
Hane:
) For»erly:
Address:
Size:
Default:
Saved?:
Description:
Note:
dataDiskNane
C64: $8453 C128: $8453 Apple: $02B4
Com&odore - 18 bytes
Apple - li bytes
Hone
Ho
Holds the disk nane that an application's data file is on.
Name:
Foraerly:
Address:
Size:
Default:
Sayed?:
Description:
Naiie:
Formerly:
Address:
Size:
Default:
Saved?:
Description:
Hote:
dispBufferOn
displayBufferOn
C64: $002f C128: $002f Apple: $021d
byte
(STJRJORE I STJRJACK) « $cO
yes
Routes graphic and text operations to either the foreground
screen, background buffer, or both simultaneously.
b?:
bi:
b5:
1 « draw to foreground screen buffer
1 draw to background buffer
1 « limit GetStnng text entry to foreground screen.
" GetString text entry will use b7,bi
b4-bO: reserved for future usei should always be
Use ST HRJORE (write to foreground) and STJRJACK (write
to background) to access these bits.
Note: !(OOxxxxxxxx is an undefined state and will result in sending
most graphic operations to the center of the dtspaly area.
day
C64: $8518 C128: $8518 Apple: $F202
Byte
20
Ho
Holds the value for current day.
Name:
Formerly:
Address:
Size:
Default:
Saved?:
Descriptions
dIgBoxRamBuf
C64: $851f C128: $851f Apple: $F381
Commodore - 417 Bytes
Apple - 64? Bytes
Hone
Yes
This is the buffer for variables that are saved when desk
accessories or dialog boxes are run.
file: printOutZ.ngl, page 13, tine Thu liar 24 ll:4j:}4 1988
Note:
nai8C *
UI ivcuava
PflrikPr 1 11 *
1 ui ■ici 1 y "
Address'
C64: $88bf C128: $88bf Apple: NA
Size:
4 bytes
UCI uU 1 b *
None
gdvcQ! *
No
liU
Dp^cr lot ion*
UC9Wi 1 U W 1 Uli
One bute is rss^rupd for each disk dr iup. to bp us^d hu th^
the disk driver. Each driver nay use it differently.
Note:
nanic *
dbiriirkCniin^
UU lb 1 IwKbUUIIW
r oriBcr ly •
Address:
C64: $8515 C128: $8515 Apple: $0258
Size:
Byte
Default:
$00
Saued?:
No
Description:
Used to deteraine uhen an icon is double clicked on. Vhen an
icon is selected, dblClickCount is loaded with a value of
LLXLN^tuuni i/V|. OD it 1 iCRLounw IS vnen oecreDcnieQ eacn
interrupt. If the value is non-zero uhen the icon is again
ep1orfp<4 fhpn fhp Wmihlo rlirk flan frOUl i< nAft<o<4 fn fko
service routine with a value of TRUE. If the dblClickCount
variable is zero uhen the icon is clicked on, then the flag is
passed uith a value of FALSE.
Note:
Nase:
DrCCurDkNn
Foriaerly:
Address:
C<4: $88dc C128: $88dc Apple: $FAC7
Size: .
CorDinodore - 18 bytes
AddIc " 16 bvtes
UCI au 1 w *
Nonp
nunc
wOVCU ! *
No
Dp^rr \ nt. \ nn S
Vw3Wi iUblUII*
Thi^ i^ the disk n^ftp nf thp current disk in driup T
Commodore - padded uith $A0
Onnip - n^ddpd uith ^nO
nUU IC uaUUCU 9 1 Wll y VV
Note:
Haoe:
OrOCurOkHi
Forwrlys
Address:
C64: $88ee C128: $88ee Apple: $FflD7
Size:
Comodore - 18 bytes
Apple - U bytes
Default:
None
Saued?:
No
file: printOutZ.agl, page 14, tiM Thu liar 24 11:46:34 1988
Dp^rr intionS
Thi^ 1^ thp fii^k rififiP nf thp nirrpnt rfi<ir in ilrfiip
11119 19 WIIC UI9ft lianC Ul VIIC bUIICIIW Ul9ft III Ul IVC w*
Cottttodore - padded with $A0
Aoole ~ oadded uith SOO
Nntp:
Name:
dirEfltryBuf
FoFBGr ]y*
Address:
C<4s $8400 C128S $8400 Apoles $FA59
Size*
CoQtnodore ~ 25^
Apple - 39 bytes
$00
Saued?:
Ho
Descriptions
Buffer used to build a file's directory entry. Initialized to
a}] zpro^
all fcCi wjt
Note:
Name-*
dir2Head
ForaerlyJ
Address:
C<4: $8900 C128: $8900 Apple: Nfl
Sizes
Conaodore - 256 bytes
Defaults
None
Saued?!
No
Descriptions
This is the 2nd directory header block used for larger capacity
disli driues (e.g. Coounodore 1571)
Notes
«
Nanes
dateCopy
Fornerlys
Addresss
C64S $C018 C128S $C018 Apples NA
Sizes
3 bytes
Defaults
Sane as variables year, lonth, day
wU vwu :
No
liU
Dp^cr i ot ion!
Thi< i< A cfiQU of thff ^u^tpfi udr iahl#^ for uesr annth AnA Aau
11119 19 a biiwy Ul viiw 9y9irwM vul iauic9 i wi ywai | hiuiiwiI| qiiu uoyi
Notes
Nanes
extclr
Forterlys
Addresss
C64: $0020 Ci28: $0020 Apple: NA
Sizes
Byte
Defaults
$FB
Saued? s
No
Descriptions
Holds ualue for exterior (border) color.
Notes
file: printOutZ.agl, page 15, tiae Thu flar 24 11j4<:54 1988
Nane:
former ly!
Address^
Sizes
Defaults
Saved?:
Description-*
fauitOata
C64: $84b6 C128: $84b6 Apple: $0227
Byte
$00
Yes
Holds information about mouse faults. House faults occur when
the mouse attempts to aoue outside the bounds set by mouseLeft,
aouseRight, mouselop, and mouseBotton. fl fault is also
signalled when the mouse is outside the current menu area. The
bits for signalling are used as follouss
Bit Fault
b/s mouse fault up
h6' mouse fault down
b5: mouse fault, left
b4: mouse fault right
b5: menu fault
Constant for bit access
OFFTOP BIT
OFFBOTlOn BIT
OFFLEFT BIT
OFFRIGHT BIT
OFFtlENU BIT
Notes
Names
Formerly:
Addresss
Sizes
Defaults
Saued?s
Descriptions
Notes
f ileHeader
Cj4s $8100 C128S $8100 Apples $F857
Commodore - 256 bytes
Apple - 512 bytes
$00
No
Buffer used to hold the header block for a 6E0S file.
Names
Formerlys
Address:
Sizes
Defaults
Saved?:
Description:
Note:
f ileSize
C64: $8499 C128: $8499 Apple: $F<1B
Uord
None
No
This is the current size (in blocks) of a file. It is pulled
in from and written to the file's directory entry.
Name:
Formerlys
Addresss
Sizes
Defaults
Saved? s
Descriptions
fileTrScTab
C64s $8300 C128S $8300 Apples NA
25< Bytes
$00
No
For Commodore, it is the buffer used to hold the track and
file: printOutZ.tgl, page li, tine Thu Flar 24 lls46:54 1?88
Hote:
sector chain for a file of ■axinue size of 32258 bytes.
Nai&e:
Fomerlys
ftddresss
Size*
Default:
Saved?:
Description:
Notes
C128: $8498 Apple: $F£1A
fileyritten
C£4: $8498
Byte
None
No
Flag indicating if a if the currently open file has been uritten
to since the last update of its index table and the Bfttl.
Nai&e:
Foraerlys
Address:
Size:
Default:
Saued?:
Description:
Note:
firstBoot
C64: $88c5 C128: $88c5 Apple: $0281
Byte
See below
Ho
This flag is changed fron to $FF uhen the desklop coaes up
after booting.
f^ntOata
saueFontTab
rrl850C C128: $850c Appl
9 bytes
None
No
Description: Buffer for sauing the user active font table uhen going into
nenus.
Note:
"JntTable ^
cardDat|
4: $26 C128: $26
8 bytes
Default font information
Yes
Appl
<™2
Saued?:
Description: fontTable is a label for the beginning of variables for the
current font in use. These variables are baselineOffset,
curSetllidth. curHeight, curlndexTable, and cardOataPntr.
For more inroraation, see docusentation on these variables.
Note:
file: print0ut2.ig], page 17, tine Thu Har 24 11:46:34 1988
Nane:
grcntrll
Foraerlys
Address:
C64: $0011 C128: $0011 Apple: NA
Size:
Byte
Default:
$55
Saued?:
Ho
Hacr p 1 nf 1 nn S
UC^Ci ip V lUit*
ijiapiiius buiiwiui icijoicr ffi| ic bpu raster/ ctii/oiut/ucn/ngCL/y
scroll bits defined for use with above reg.
st^eca « S40
<f KmM s 470
St Jen « 510
st 25rou « 508
Note:
Nane:
grcntrl2
Formerly:
Address:
C64: $0016 C128: $0016 Apple: NA
Size:
Byte
Default:
$AA
Saued?:
no
Description:
graphics control register 12, ie: RES/flCfl/CSEL/x scroll bits
t nt%A 91%^ Ilea iii^K AnAiia
QcrineQ ror use uicn aoove reg.
St.BCBI = 510
Note:
Name:
grirq
Formerly:
Address:
C64: $0019 C12B: $001? Apple: NA
Size:
Byte
Default:
$42 .
jovcu : *
Nn
no
Hpcrr {nt inn*
nrdohic^ chin intprriini! fpti\^tpr
ilU wc*
Nane:
grirqen
ForBerly:
Address:
C64> $d01a C128: $d01a Apple: NA
Size:
Byte
Default:
$24
Saved?:
No
Description:
graphics chip interrupt enable register
bit to enable raster interrupt in grirqen is bit
St rasen » $01
Note:
files printOutZ.ng), page 18, tine Thu Mar 24 11:46:54 1988
Name:
Fornierlys
Address:
Size:
Default:
Saued?:
Description:
Note:
grnenptr
C64: $d018^ C128: $d018 Apple: NA
Byte
No
graphics nenory pointer Vni3-UniO|CB13-CBll. ie video satrix
and character base.
Name:
Fornerly:
Address:
Size:
Default:
Saved?:
Description:
Note:
hour
C64: $8519 C128: $8519 Apple: $F203
Byte
12
Ho
Variable for hour
Name:
Formerly:
Address:
Size:
Default:
Saved?:
Description:
C128: $84b5 Apple: $0226
iconSelFlag
C64: $84b5
Byte
$00
Yes
This RAH variable contains flag bits in b7 and b6 to specify
how the systes should indicate icon selection to the user, if
no bits are set, then the systett toes nothing to indicate icon
selection, and the service routine is sinply called.
The possible flags are:
ST FLASH « $80 \ flash the icon
STiINVERT « $40 ; invert the selected icon
If ST FLASH is set, the ST INVERT flag is ignored and the icon
flashes but is not inverted when the prograttner's routine is
called. If ST INVERT is set, and STJLASR is CLEAR, then the
icon uill be Inverted uhen the prograiMier's routine is called.
Note:
Name:
Formerly:
Address:
Size:
Default:
Saved?:
Description:
indexBlkno
Apple: $F624
C64: NA C128: NA
Uord
$00
No
Block number of the VLIR index table (ProDos master index
file* print0ut2.«gl, page 19, tiae Thu flar 24 11J44SJ4 1988
block).
Note«
Name:
inputData
FortterlyJ
Address:
C64: $8506 C128: $8506 Apple: $0247
Size:
4 bytes
Default:
None
Saued?:
No
Description:
This is where input driuers pass deuice specific inforaation to
applications that want it.
Note:
Nane:
inputDeuNarse
forwerly:
Address:
C64: $88cb C128: $88cb Apple: $08CC
Size:
Comnodore - 17 bytes
Apple - 16 Bytes
Default:
None
Saued?:
No
Description:
String that holds the name of the current input deuice.
e.g. Conn nOUSE for coflinodore mouse.
Note:
Name:
inputVector
Foriaerly:
Address:
C64: $84a5 C128: $84a5 Apple< $020A
Size:
Uord
Default:
$00
Saued?:
No
Description:
Pointer to routine to call on input deuice change.
Note:
Haine:
intfiotVector
Forfterly:
interruptBottoaVector
Address:
C64: $849f C128: $849f Apple: $0204
Size:
Hord
Default:
$00
Saued?:
No
Description:
Vector to routine to call after the operating systea interrupt
code has run. This allows applications to haue interrupt leuel
routines.
Hote:
file: print0ut2.ag1, page 20, tine Thu flar 24 li:4i:34 1788
Watae'' intlopVector
Fornerlys interruptTopVector
Address!
Ci4: $849d C128: $849d Apple: ^0202
Size:
Uord
uciau 1 V *
Y V V
wQVCU : *
No
Dp^cr iotion*
Vector to routine to call before operating systen interrupt
code is run. It allous applications to interrupt leuel
routines.
llU bC*
Name:
intSource
Foraerly!
interruptSource
Address:
C64: NA C128: NA Apple: $02C6
Rut?
Default:
None
Saued?:
No
Description:
Byte to indicate where interrupts are coning fron on the Apple.
$oO indicates nouse card
^40 indicates interrupt nanagenent card
$00 indicates software interrupts
Note:
Nane:
interleaue
Forierly:
nuui ww9*
C64: i848c C128: $848c Aoole: NA
Size:
Byte
Defaults
$08
Saued?:
No
Description:
Vartabje used by BIkAlloc routine as the desired interleaue uhen
ocicwwiitM 1 1 cc uiuwiks 1 III a ui3i^ Liiaiii*
liU *
Nane:
inuertBuffer
Fornerly:
CM: NA ri7A: ^Irpd Annlp: Nfl
but" iin wi4D* yiucu nupic* nn
Size:
80 Bytes
Default:
None
Saued?:
No
Description:
Buffer area used to speed up the 80 colunn InuertLine routine.
Resides in back Ran.
Hote:
Naoie:
irquec
Fornerly:
file: printOutZ.sgl, page 21, tisie Thu Har 24 11:46:54 1?88
Address:
C64: $0314 C128: $514 Apple: HA
Size:
Uord
Default:
$?5fd
Saued?:
No
Description:
irq uector.
Hote:
Haiae:
isGEOS
Fornerly:
Address:
C64: $848b C128: $849b Apple: HA
Size:
Byte
Default:
Disk dependent
Saued?:
No
Description:
Flag to indicate whether the current disk is a GEOS disk.
Note:
Haine:
keyData
Fornerly:
Address:
C64: $8504 C128: $8504 Apple: $0245
Size:
Byte
Default:
$00
Saued?:
No
Description:
Holds the ASCII ualue of the current last key that uas pressed.
Used by keyboard seruice routines.
Note:
Nane:
keyUector
Foraerly:
Address:
C64: $84a5 C128: $84a5 Apple: $0208
Size:
Uord
Default:
Comnodore - $26A1
Apple - $416D
Saued?:
Yes
Description:
Uector to routine to call on keypress
Note:
Natae:
leftHargin
Fornerly:
nUUl *
C'64: $0055 C128: $0055 Apple: $0220
Size:
yord
Default:
$00
Saued?:
Yes
file: printOutZ.figl, page 22, tine Thu liar 24 11:46:34 1988
Description:
Leftmost point for writing characters. Doing a carriage
return uiil return to this point.
Note:
Nane:
BachineType
Foraerly:
Address:
C64: NA C128: NA Apple: $02C4
Size:
Byte
Default:
None
Saved?:
No
Description:
Type of Apple nachine. Values are:
^00: He
$80: lie or something else
Note:
Nane:
eaxflouseSpeed
Fornerly:
saxifiuiDnouseSpeed
(Iddress:
C64: $8$01 C128: $8501 Apple: $027D
Size:
Byte
Default:
$7f (127)
Saved?:
No
Description:
llaxiiDUtt speed for nouse cursor.
Note:
Nai&e:
BcnclrO, BCDctrl
Formerly:
Address:
C64: $d025, $d026
C128: $d025, $d026
Apple: NA
Size:
1 Byte each
Default:
None
Saved?:
No
Description:
These are the variables for Bulti-color node colors
and 1 respectively on the Connodore.
Note:
Hane:
nenuNuttber
Foraerly:
Address:
C64: $84b7 C128: $84b7 Apple: $0228
Size:
Bvte
Default:
$00
Saved?:
No
Description:
Nunber of currently uorking aenu
file! print0ut2.»gl, page 23, tiiae Thu Mar 24 lUUi3A 1988
Notes
Ha»es
ttinflouseSpeed
foraerlys
niniKunflouseSpeed
flddress-'
Ci4! $8502 C128! $8502 Apple: $027E
Size!
Byte
Default!
He (30)
OdUCU! *
Nn
no
np<rr intionS
nininuii ^nppH fnr nnii<sP nircnr
Note!
Name!
ninutes
Foroerly!
Address!
C«! $851a C128! $85Ia Apple: $F204
Size!
Byte
Default!
$00
Saued?!
No
Description!
Variable for ainutes for tine of day clock.
Note!
llaiUC *
(nnhOrlr nnhlrlr nnhJrlr nnK^rlr itnhArlr- mnK^rlr
0)ob6clr, Bob7clr
Foriaerlyi
Address!
C64i $d027 - $d02e
Apple: NA
Size!
1 Byte each
ucrdu 1 w *
none
Sdupd?!
Uwvcu : *
No
liU
uescr ipwion*
inese are ine colors or vne o oojecws ^spriiesj on LoiD&oooret
Note!
Nai&e!
nobOxpos, nobOypos, noblxpos, noblypos, Aob7xpos, Bob7ypos
Fornerly!
Address!
C64: $0000 - $DOOF
Apple: Nfl~ r/t(A
W i bC *
1 Rutp pArh
* uy vc cavil
Default!
None
Saved?:
Ho
Description!
These are the x any y positions of sprites 10 to 17
respectively.
Note:
ttobbakcQl
file: printOut2.ngl, page 24, tine Thu flar 24 11:46:54 1988
For»erly:
Address:
C64: $d01f C128: $d01f Apple: NA
Size:
Byte
Default:
None
Saued?:
No
Description:
sprite to baciiground collision register for Connodore.
Note:
ndiDC *
pArnor In •
r ur mci ly •
nuui *
Ci4: idol$ C128: id015 Apple: $0818
Size:
Byte
Default:
$01
Saued?:
No
Description:
sprite enable bits
Note:
NafDe:
Biobncm
r ornpr 1u*
Address:
n M v« 1 www
C64: $d01c C128: $d01c Apple: NA
Size:
Byte
Default:
$00
Saued?:
No
Description:
sprite nulti-color node select
Note:
Nane:
Bobnobcol
Forn^r 1u*
Address:
C64: $d01e C128: $d01e Apple: NA
Size:
Byte
Default:
§00
Saued?:
No
Description:
object to object collision register
Note:
Nai&e:
nnhor lor
Fornerly:
Address:
C64: $d01b C128S $d01b Apple: HA
Size:
Byte
Default:
$00
Saued?:
No
file: printOutZ.agl, page 25, tiae Thu flar 24 11:46:34 1?88
Description:
object to background priority
Note:
Naitte:
Bobx2, BobyZ
Forierly:
Address:
C64: $d01d, d017 respectively
LlZo* $dOId, dOu respectively
Apple: $0819, $081A
Size:
1 Byte each
Default:
$00
Saved?:
No
Description:
Double object size in x and y respectively
Note:
Haoe:
Bonth
Foraerly:
Address:
Ci4: $8517 C128: $8517 Apple: $F201
Size:
Byte
Default:
$09
Saued?:
No
Description:
Holds Bonth for time of day clock
Note:
Name:
BouseAccel
Foraerly:
BOuseAcceleration
Address:
C64: $8503 C128: $8503
Size:
Byte
Default:
$75 (127)
Saved?:
No
Description:
Acceleration of aouse cursor
Note:
Nane: BOuseBottoa
Foraerly:
Address: C64: $84b9 C128: $84b9 Apple: $0058
Size: Byte
Default: C64 - 199
Apple - 191
Saved?: Yes
Description: Bottoa Bost position for aouse cursor. Noraally set to bottoa
of the screen.
Note:
flies print0ut2.igt, page 26, tiae Thu Har 24 Ui46s34 1988
BOUseFaultUec
Foroerlys
BOUseFaultUector
Address!
C64: ^84a7 0128: $84a7 Apple: $020C
Size!
Uord
Default!
Systen handling routine
Saved?!
Yes
Description!
Vector to routine to call uhen laouse goes outside region
defined for nouse position or when louse goes off of a aenu.
Note!
Naine!
wouseLeft
.ForiBerly!
Address!
C64! $84ba C128i $84ba Apple: $0059
Size!
Vord
Default!
$00
jdvCU : *
Yes
Descr iotion!
Left Bost position for Bouse
Note!
Name!
nouseOn
Foroerly!
Address!
C64! $30 C128: $30 Apple: $0050
Size!
Byte
Default:
$E0
Saued?!
Yes
Description!
Flag indicating that the Bouse is Bode is on. Bit usage and
constants for accessing theB are as follows
Bit flode Constant
b?! Bouse on if set SET HOUSEOH » UOOOOOOO
b6! nenus on if set SErriENUON » XOIOOOOOO
b5! icons on if set SETlICONSOH « ZOOIOOOOO
b4 " bO not used
Note!
Nane!
BOUsePicData
FortDerly!
Address!
W4: $84cl C128! $84cl Apple: NA
Size!
64 bytes
Default!
BOUse pointer picture
Saued?!
No
Description!
64 byte array for the Bouse sprite picture on CoBBodore
Note:
Naae:
BouseRight
files print0ut2.BgU page 27, tiae Thu flar 24 11:4<:34 1988
ForaerlyJ
ftddressJ
C64: $84bc C128: $84bc Apple« $005B
Size*
Uord
Default:
C<4 - 319
ClZo - 65/
Apple - 559
2)auedf •
les
Description!
Right Bost position for Bouse.
note-
Nantes
BiouseSaue
fornerlys
Address''
Ci4s NA C128S $1655 Apples $EE53
Sizes
24 Bytes
Defaults
None
Saued?s
No
Descriptions
Screen data for what is beneath nouse soft sprite. Resides in
Dacx Kan.
notes
Names
BouseTop
Foroerlys
flddresss
C64S $84b8 C128S $84b8 Apples $0057
Sizes
Byte
Defaults
$00
SauedfS
Yes
Descriptions
Top Bost position for aouse
Notes
Nases
BouseUector
Foraerlys
flddresss
C64: $84al C128s $84al Apples $020i
Sizes
Uord
Defaults
Systen routine for icons, nenus, etc.
Saued?s
Yes
Descriptions
Routine to call on a Bouse key press
Note:
Nane*
BOUseXPos
Foraerlys
BOUseXPosition
Address:
Ci4s $3a C128: $5a Apples $0241
Size:
Uord
files printOutZ.agl, page 28, tine Thu Har 24 11:46:34 1988
Default:
None
Saved?:
No
Description:
House X position
Note:
Name:
■ouseYPos
Foraerly:
RouseYPosition
Address:
C64: $3c C128: $3c Apple: $0243
Size:
Byte — '
Default:
None
Saved?:
No
Description:
House Y position
Note:
Nane:
BOUseXOffset
Formerly:
Address:
C64: NA C128: NA Apple: $0229
Size:
yord
Default:
$00
Saved?:
No
Description:
Offset froB nouseXPos to draw BOuse sprite. Froa -$8000
to $7fff
Note:
Nafie:
BouseYOffset
Foraerly:
Address:
C64: $ C128: $ Apple: $022B
Size:
Byte
Default:
$00
Saved?:
No
Description:
Offset froB BouseYPos to draw the souse sprite. FroB -128 to
127
Note:
Nane:
Bsbxpos
Fornerly:
Address:
C64S $d010 C12B: $d010 Apple: NA
Size:
Byte
^^.y Default:
Saved?:
Description:
Note:
file: print0ut2.»gl, page 29, tine Thu liar 24 11:46:34 1988
Naoe:
BsePicPtr
for»erIy:
BousePicture
Address:
C<4: $31 C12B: $31 Apple: HA
Size:
Uord
Default:
$84cl
Saued?:
Yes
Description:
pointer to the nouse graphics data
Note:
Naise:
Formerly:
Address:
Size:
Default:
Saved?:
Description:
Note:
C128: $c010 Apple: $EOOD
nationality.
C64: $c010
Byte
- American
No
Byte to hold nationality of Kernal. Values are:
American
1 German
2 French (France S Belqiun)
3 Dutch
4 Italian
5 Swiss (Switzerland)
6 Spanish
7 Portugese
8 Finnish (Finland)
9 UK
Norwegian (Norway)
11 Danish (Denmark)
12 for Swedish
Name:
nmiuec
Formerly:
Address:
Ci4: $0318 C128: $318 Apple: NA
Size:
Uord
Default:
$90c9
Saued?:
Ho
Description:
NUI vector
Note:
Name:
noEraseSprites
Formerly:
Address:
C64: HA C128: HA Apple: $0240
Size:
Byte
Default:
FALSE » $00
Saued?:
Ho
Description:
Flag to stop routine TempHideftouse from erasing sprites 12 -
file: print0ut2.ng1g page 30, tine Thu Mar 24 11:46:34 1788
17. Set bit V (set to $80) to signal not to erase sprites.
Note:
Nane:
Forwerly:
Address:
Size:
Default:
Saued?:
Description:
Note:
nunDriues
C64: $848d C128: $848d Apple: '$F60E
Byte
Drive dependent
Ho
Set to nunber of drives on the syste«
Name:
Formerly:
Address:
Size:
Default:
Saued?:
Description:
Note:
objOPointer, objlPointer, obj2Pointer, obj3Pointer, obj4Pointer,
objSPointer, obj6Pointer, obj7Pointer
Ci4: $8ff8 - $8fff
C128: $8ff8 - $8fff
Apple: NA
1 Byte each
objOPointer is set to louse cursor picture
Ho
Pointers to the picture data for sprites
Hafse:
Formerly:
Address:
Size:
Default:
Saued?:
Description:
Hote:
^^^^ Hame:
C128: HA Apple: $027C
offFlag
C64: NA
Byte
FALSE » $00
Ho
Flag telling uhether the louse needs to be redraun. It is used
as follows:
Value
$80 iouse is erased; do not redraw it during interrupt
aouse is erased; OK to redrau it next interrupt
$40
$00
nornal: iouse is displayed. (Rust be erased before
draun at a new position.)
$ff (negatiue/set to TRUE anytiae TettpHidedouse is called)
otherPressVec
Fomerly: otherPressVector
Address: C64: $84a7 C128: $e4a7 Apple: $020E
Size: Uord
file! printOutZ.agl, page 31, tiie Thu Har 24 ll!4i:34 1988
Default t
$00
Saved? s
Yes
Descriptions
Vector to routine that is called uhen the louse button is
pressed and it is not on either a aenu or an icon.
Note:
Hane:
pressFlag
Forwrlys
Address!
C64s $39 C128! $39 Apple! $08FE
Size!
Byte
Default:
$00
Saved?!
No
Descriptions
Flag to indicate that a neu key has been pressed. Bit usage!
b7: key data is neu ^
b<! disk data is neu f ■ -
b5! Bouse data is neu
Note!
Naoe!
PrntFilenaiae
Forierly!
Address!
C64! $8465 C128! $8465 Apples $08AC
Size?
Cownodore - 17 bytes
Default!
None
Saved?.!
«
No
Description!
Name of the current printer driver
Note!
•
Naie!
PrntOiskNane
Fornerly!
Address!
C64S $847i C128S $8476 Apples NA
Size!
Conmodore - 18 bytes
Default!
None
Saved?!
No
Description!
Disk na»e that current printer driver is on
Note!
Nane!
ranBase
Formerly!
Addr^^s!
nuui
C64s i88c7 C128! $88c7 flpples NA
Size!
4 bytes
Default!
None
Saved?!
No
file: printOutZ.igl, page 32, tine Thu Har 24 11:46:34 1?88
Description:
RAH bank for each disk drive to use if the driue type is either
» RAH Di^k or Shadoued Driue
note*
Name:
ranExpSize
Foraerly:
Address:
Ci4: $88c3 C128: $88c3 Apple: NA
Size:
Byte
Default:
RAH driue dependent
saueo: •
no
uescr ipt lon*
Dyvc lor nuoiuci or laii uoiik? avaiiauic iii nan CApaii^ioii uiiiv*
Naoe:
randon
Foraerly:
Address:
Ci4: $850a C128: $850a Apple: $024C
Size:
Vord
Default:
None
oauedf •
no
vC3l#l 1 U W 1 Ull *
UArifihlp incrpfipntpd PAch intprruot to o^n^ratp a rArtAnin niifshpr
vol lOUiw lllwi wWCII WwU wQwII III vwl 1 UU w « U UwllCI BWC O iOIIUUH IIUIhUCI
note'
Name:
rasreg
Foraerly:
Address:
C64: $d012 C128: $d012 Apple: NA
Size:
Byte
Default:
None
^avcu: *
Nn
no
uescr ipx ion*
raster register
Naae:
RecouerVector
Foraerly:
Address:
C64: $84bl C128: $84bl Apple: $0216
Size:
Hord
Default:
Points to RecouerRectangle routine
Saued?:
Yes
Description:
Pointer to routine that is called to recouer the background
behind nenus and dialogue boxes. Noraally this routine is
RecouerRectangle, but the user can supply his oun routine.
Note:
Name: returnAddress
file! print0ut2.agl, page 33, tiae Thu Har 24 11:46:34 1988
Forierlys
Address:
C64: $3d ' C128: $3d Apple: $0064
Size:
Vord •
Default:
None
Saved?:
Ho
Description:
Address to return to from in-line call
Note:
iiaiuc *
Ttin)ll\n<(\ rDAVnnel paiiVnne? »csaVam«7 •M^V»j%«it
reqAposy, reqAposi, reqAposz, reqApos^, reqXpo54,
reqXposS, reqXpos6, reqXpos?
Formerly:
Address:
C64: NA C128: NA Apple: See below
Size:
Tuo Bytes each
Default:
None
Saved?:
No
Description:
These variables correspond to the Coaaodore VIC chip registers
for sprite X positions. They reside at:
reoXna^O ^0800
reqXposl ^0802
reqXpos2 i0804
1 cuAuu^y ovuvo
reqXpos4 f0808
1 w«^opu9y 9vUVCl
reqXpos6 i080c
1 CUApUPr yVOVC
Note:
Name:
rightHargin
Foriierly:
Address:
C64: $37 C128: $37 Apple: $0222
Size:
Hord
Default:
C64 - 31?
C128 - 639
Apple - 559
waveor *
Yp<
ICS
i/csur ipw ion*
Thp rinhtnn^t Doint for uritino characters. If an Attpmnt i<
Bade to urite past riqhtHargin, the routine pointed to by
Qf r innrAiilfUpr i< PftliPd.
3 wi inur du 1 bVCw i^ waiicut
noic*
Naoe:
saveFontTab
rnrnpr luS
r ui nci 1 y "
C64: $850c C128: ^A^Oc Aoole: $024E
Size:
Cowodore - 9 bytes
Apple - 10 Bytes
Default:
None
Saved?:
Ho
Description:
Uhen a aenu is selected, the users active font table is saved
in this buffer.
file: print0ut2.Bg1, page 34, tiK Thu Har 24 ll:4i:34 1988
Note:
Nane:
forwrlys
Address!
Size«
Defaults
Saved? 8
Description'
Note:
sauedaobyZ
C64: $88bb C128: $88bb Apple; NA
Byte
None
Yes
Saued ualue of Boby2 for context sauing done when dialogue boxes
and desli accessories run. Because this was left out of the
original 6E0S saue code, it uas put here so it remains
conpatible with desk accessories, etc. that use the size of
TOTJRAtlJAVED for how what gets saued.
Nai&e:
foraerlys
Address*'
Size:
Default:
Saued?:
Description:
Note:
scrSOcolors
C64: NA
Byte
None
No
C128: $88bd Apple: NA
Screen colors for 80 coluan node on the C128. It is a copy of
reg 26 in the UDC. ^
Naiae:
Foroerly:
Address:
Size:
Default:
Saved?:
Description:
Note:
scrBOpolar
C128: $88bc Apple: NA
C64: NA
Byte
None ??
No
Copy of reg 24 in the UDC for the C128
Naae:
Fomerly:
Address:
Size:
Default:
Saued?:
Description:
Note:
screencolors
C64: $851e C128: $851e Apple: NA
Byte
$BF (1?1)
No
Default screen colors
Naae:
seconds
file: printOutZ.ngl, page 35, tiie Thu Kdr 24 11:46:34 1?88
For»erly:
Address:
Ci4: $851b C128: $851b Apple' $F205
Size:
Byte
Default:
$00
Saued?:
Ho
Description:
Seconds variable for the tine of day clock.
Note:
Nane:
selectionFlash
Forwerly:
Address:
C64: $84b3 C128: $84b3 Apple: $0224
Size:
Bute
Default:
SLECTIONJELAY « $0A (10)
Saved?:
Yes
Description:
Variable for the speed at uhich nenu iteas and icons are
flashed.
Note:
Kane:
shiftBuf
Foraerly:
Address:
C64: NA C128: $lb45 Apple: $0070
Size:
7 bytes
Default:
None
Saued?:
No
Description:
Buffer for shifting/doubling sprites. Located in back Raa.
Note:
Nar&e:
shiftOutBuf
Formerly:
Address:
C64: NA C128: $lb4c Apple: $0078
Size:
7 Bytes
Default:
None
Saued?:
No
Description:
Buffer for shifting/doubling/oring sprites. Located in back
Raa.
Note:
HaiBe:
sizeFlags
Foraerly:
Address:
C64: NA C128: $lb53 Apple: $DB1C
Size:
Byte
Default:
None
file: printOutZ.igl, page 36, tiM Thu Har 24 11:46:34 1788
Sdued?s
Descriptions
Note*
No
height of sprite | 9-pixel flag this is grabbed froi the 64th
byte of the sprite definition. The high bit is set if the
sprite is only 9 pixels wide. The rest of the byte is a
count of scan lines.
Nanes
Foraerly*
Address*'
Size:
Default!
Saved?!
Description!
Note!
softZeros
C64! Nft
192 Bytes
None
No
C128! $lb6d Apple! $DOEO
Buffer used for putting sprite bitmaps uo on screen without
disturbing background. Resides in back RaM.
NaiDe!
fori&erly!
Address!
Size!
Default!
Saued?!
Description!
Note! •
softOnes
C64! NA
192 Bytes
None
No
C128! $lc2d Apple! $D0OO
Buffer used for putting sprite bitnaps uo on
disturbing background. Resides in back Ran.
on screen without
Naae!
Foraerly!
Address!
Size!
Default!
Saued?!
Description!
Note!
sprOpic, sprlpic, spr2pic, spr3pic, spr4pic, spr5pic,
spr6pic, sprZpic
C64! $8a00 - 8bc0 respectively
C128! ^8a00 - 8bc0 respectively
Apple! NA
64 bytes each
sprOpic is used for souse picture
No
This is uhere the graphics data for sprites - 7 are kept on
the C64.
Name!
Foroerly!
Address!
Size:
Default!
ssprlback, sspr2back, sspr3back, sspr4back, ssprSback,
sspr6back, sspr7back
C64: NA
C128: See belou
Apple: $5600
Commodore - 294 bytes each
Apple - 336 bytes each
None
file: printOutZ.ig], page 37, tioe Thu Har 24 11:46:34 1988
Saued?:
Descriptions
Ho
For each of the soft sprites tl - 17, there is a buffer in the
back Raci for sauinq the screen behind the sprites. The
nouse (sprite 10) is handled seperately. Locations for the
buffers are*
Comodore:
ssprlback*
ssprZback>
sspr3back>
sspr4backs
sspr5back:
sspr6back:
S5pr7back:
Apple:
ssprlbackx
sspr2back:
S5pr3back:
sspr4back:
ssprSback:
S5pr6back:
sspr7backs
5133b
1461
1587
16ad
17d3
hif?
half
S56d0
15820
S5970
§5ac0
^5cl0
I5d60
bebO
Each buffer is 7 butes wide by 42 scanlines high (292 bytes) on
the Contfflodore and 8 bytes vide by 42 scanlines high for Apple
soft sprites. The extra byte is needed because of the App
7 bit screen bytes. These buffers are large enough to hol_
largest possible sprite size (doubled in both x and y) and
include an extra byte in width to save stuff on byte boundar
es
d the
Haoe:
string
Forrerly:
Address:
C64: $24 C128: $24 Apple: $0053
Size:
Word
Default:
None
Saved?:
Yes
Description:
Used by GEOS as a pointer to string destinations for routines
such as GetString.
Note:
Haoe:
StringFaultVec
Foraerly:
StringFaultVector
Address:
C64: $84ab C128: $84db Apple: $0210
Size:
Uord
Default:
$00
Saved?:
Yes
Description:
Vector called when an attenpt is aade to write a character
past rightflargin.
Note:
Haf&e:
stringX
Fornerly:
Address:
C64: $84be C128: $84be Apple: $022E
Size:
Uord
Default:
None
file; printOutZ.ngl, page 36, tiie Thu liar 24 11:46:34 1788
Sailed?!
Yes
Descriptions
The X position for string input
Note:
Nane:
stringY
Fomerly:
Address:
C64: $84c0 C12B: $84c0 Apple: $0230
Size:
Byte
Default:
None
Saued?:
Yes
Description:
The Y position for string input
Note:
Natr«:
sysDBData
Fortter 1y:
Address:
C64: i851d C128: i851d Aoole: i0259.
Size:
Byte
Default:
None
Saued?:
NA
Description:
Variable that is used internally to indicate which icon caused
a return to the application (froi a dialogue box). The actual
data is returned to the user in rOL.
Note:
Nane:
sysFIqCopy
Forier ]y:
Address:
C<4: ic012 C128: $c012 ' AoDle: NA
Size:
Byte
Default:
None
Saued?:
No
Description:
This is a copy of the sysRAMFlg that is saued here when going
into basic on Conaodore. See sysRAIIFlg for lore infornation.
Note:
Nane:
sysRAHFlg
F ori^r lus
Address:
C64: $88c4 C128: i88c4 Aoole: NA
Size:
Byte
Default:
None
Saued?:
No
Description:
If RAtI expansion in. Bank is reserued for the kernaTs use.
This byte contains flags designating its usage:
Bit 7: if 1, $0000-$78FF used by lloueData routine
file: printOutZ.agI, page 39, tine Thu Har 24 11:46:34 1988
Bit 6i \f 1, $8300-$B8FF holds disk driuers for drives A
throuoh C
Bit 5^ if 1. V'OH^DFF is loaded uith GEOS raa area
i8400-$88FF by ToBasic routine when going to BASIC.
Bit 4: if 1, i7E00-$82FF is loaded uith reboot code by a
setup AUTO-EXEC file, which is loaded by the restart
code in GEOS at $C000 if this flag is set, at $6000,
instead of loading GEOS BOOT. Also, the area
$B900-$FC3F is saued for the kernal for fast re-boot
without sustea disk (depending on setup file). This
area should be updated uhe^ input deuices are changed
(inpleaented in 1/1.3 deskTop).
Note:
Coinfliodore only
nasic*
tntNiinRIk^
rorBicr ly •
Address:
riA» NO ri7Q2 NO Onnlo! drXflR
104* iiH tiiO" iiH nppie* ^rouo
Size:
UnrA
■oro
Default:
$llo
p ..... •
Saued?:
no
uescr ipc ion*
lOvai nuiiDcr or diucks in currenb voiuibc.
Note:
Nai&e:
bUroor lags
r orBier ly •
Address:
Si7p:
4 bytes
npf Atlit:
Nnrtp
llllllC
«
oavcQ: ■
Nn
nu
UCdwi ipw lull*
Thp turbo state flaos for driues 8 throuoh 11 on Coaaodore
Note:
nacie*
iicoHPemrnc
r orBier ly •
HOflress-
rXAs 6flA97 ri7fl: ^ftA97 finnlp:
LOH* 90**7r Ul&O* 90H7r npplc* 9rOi/
3 1 Zc*
oy wc
uefault:
AAA
$U0
Saued?:
No
Description:
Holds the nunber of records in an open ULIR file
Note:
Haote:
udcClrflode
Forserly:
Address:
C64: NA C128: $88be Apple: NA
Size:
Byte
Default:
Hone ??
Saued?:
No
file: printout!. ng], page 40, tioie Thu flar 24 11:46:34 198B
Description: Holds the current color sode for C128 color routines.
) Note: ' ;.:
nafDe-
version . »
tn^MA^ lit!
roriier ly'
ftddress:
C<4: $cOOf C12B: $cOOf Apple: '$EoW '
Size:
Byte
Default:
Hone
Saved?:
No
Description:
Holds byte indicating uhat version of EEOS is running.
Note:
na/Be«
uindouTop
L #1 ^ Aft A ^ 1 1 1 9
r orioer ly •
Address:
U^'' $33 C128: $33 Apple' $021E
Size:
Byte
Default:
$00
Saued?:
Yes
Description:
Top line of uindou for text clipping
Note:
naioe*
year
rorBer ly •
Address:
Ci4: $B5U C128: $8516 Apple' $F200
Size:
Byte
Default:
86
Saued?:
No
Description:
Holds the year for the tine of day clock.
Note: