by Berkeley Softworks, reverse engineered by Maciej Witkowiak, Michael Steil.
GEOS is a graphical user interface for 6502-based computers. In the 1980s, it was commercially available for the Commodore 64, 128 and Plus/4 as well as the Apple II.
GEOS has extremly low hardware requirements:
With just 20 KB of binary code, the GEOS "KERNAL" has the following features:
The default shell of GEOS is deskTop, a file manager an application launcher.
Several powerful applications are available for GEOS, including
The cc65 compiler suite allows writing GEOS applications in C or assembly.
This is the reverse engineered source code of the KERNAL (plus disk and input drivers) of the English version of GEOS 2.0 for Commodore 64 and Commodore 128.
The source has been heavily reorganized and modularized, nevertheless, a standard compile will generate binaries that are identical with the GEOS 64 2.0 and GEOS 128 2.0 distribution binaries.
Optionally, the following features that were not part of the original GEOS 2.0 can be enabled for GEOS64:
Without pucrunch/c1541, you can still build an uncompressed KERNAL binary image.
Run make
to build the original "BSW" GEOS for C64. This will create the following files in directory build/bsw
:
kernal.bin
, lokernal.bin
, init.bin
drv1541.bin
, drv1571.bin
, drv1581.bin
amigamse.bin
, joydrv.bin
, lightpen.bin
, mse1351.bin
, koalapad.bin
, pcanalog.bin
SYS 49155
): kernal_combined.prg
RUN
): kernal_compressed.prg
geos.d64
If you have the cbmfiles.com GEOS64.D64
image in the current directory, the disk image will be based on that one, with the GEOS
and GEOBOOT
files deleted and the newly built kernel added. Otherwise, it will be a new disk image with the kernel, and, if you have a desktop.cvt
file in the current directory, with DESK TOP
added.
The build system supports the following variants:
bsw
(default): Berkeley Softworks GEOS 64 2.0 variantcbmfiles
: The cbmfiles.com version. It starts out with a different date, and has some variables in the kernel pre-filled.gateway
: The patched KERNEL shipped by gateWay 2.51. It contains a slightly modified BSW font, has the Panic
code replaced with code to swap the disk driver on a RESTORE press, and it loads GATEWAY
instead of DESK TOP
as the shell.wheels
: The Wheels 64 variant. It is heavily patched, optimized for size and speed, and contains additional features. It requires a RAM extension. The current version compiles into the same binary, but won't actually run because of missing boot code. More work is needed here.bsw128
: Berkeley Softworks GEOS 128 2.0 variant, i.e. GEOS for C128 with 128 KB RAM and VDC 640px width support. This needs some more work to actually boot.custom
: See below.You can build a specific variant like this:
make VARIANT=<variant>
All output will be put into build/<variant>
.
By default, the KERNAL image will contain the Commodore 1541 disk driver (drv1541
) and the joystick input driver (joydrv
). You can specify different drivers to be included like this:
make DRIVE=<drive> INPUT=<input>
Supported drives are drv1541
, drv1571
and drv1581
. Supported input devices are amigamse
, joydrv
, koalapad
, lightpen
, mse1351
and pcanalog
.
The KERNAL variant custom
is meant for your experimentation. Inside the .ifdef custom
section in config.inc
, you can toggle several compile time options:
removeToBASIC = 1
: Don't include the ToBASIC code required for deskTop to launch non-GEOS applications, in order to save RAM for code.use2MHz = 1
: Switch a C128 in C64 mode to 2 MHz outside of the visible screen.usePlus60K = 1
: Enable support for the +60K RAM expansion.useRamCart64 = 1
, useRamCart128 = 1
: Enable support for the Ram Cart expansion. With RAM expansion support, GEOS will use the extra RAM for caching deskTop and for holding the swap area when running desk accessories. GEOS will show an error at startup and reset the system if support for a particular memory expansion is enabled but it is not available.
Note that the changing settings and adding code may cause certain memory areas to overflow. In this case, you can try moving segments between the LOKERNAL
and KERNAL
areas. The file kernal.map
in the build output will give you an idea about the sizes of segments. The custom
variant starts out with about 550 bytes of usable memory in the KERNAL
area.
Makefile
config.inc
: kernel config optionsregress.sh
: script that compares output with referencedrv/
: disk drive driver sourceinc/
: include files: macros and symbolsinput/
: input driver sourcekernal/
: kernal sourcereference/
: original binaries from the cbmfiles.com versionGreat care was taken to split the KERNAL into small, independent components. This division does not necessarily match the layout of the original binary code, but with the help of .segments
, the layout in the binary does not have to match the layout in source.
The goal of this division of the source was to keep the number of .imports
minimal (i.e. to make individual source files as self-contained and independent as possible).
One example of this is the file system and application/accessory loading code. In the original GEOS KERNAL binary, they were not separate, but here, the file system code is in filesys.s
and the loading code is in load.s
, with only two symbol dependencies.
Another example is the ToBasic
logic: In the original kernel, it the binary code was split, a part resided between the header and the jump table ($C000-$C0FF), and different part was in the "lokernal" area ($9000-$9FFF). In the source, both parts are in the same file tobasic.s
.
In case you want to adapt the source for other 6502-based systems, you will want to know which parts have C64 dependencies.
All C64-specific code can be easily recognized: Since all C64 symbols have to be imported from c64.inc
, you can tell which source files have C64 depencency by looking for that include. Remove the include to see which parts of the code are platform-specific.
InitTextPrompt
in conio.s
, for example, accesses sprites directly, in the middle of hardware-independent code.
The GEOS KERNAL has a quite complicated memory layout:
The header and the jump table must be at $C000 and $C100, respectively. Together with the graphics bitmap at $A000, this partitions the KERNAL into four parts: lokernal, below header, between header and jump table, and above jump table.
The linker config file positions the segments from the source files into these parts. If the code of any segment changes, the header and the jump table will remain at their positions. If a part overruns, the linker will report and error, and you can consult the kernal.map
output file to find out where to best put the extra code.
But it gets more complicated: Code between $D000 and $DFFF is under the I/O registers, so it cannot enable the I/O area to access hardware. The macro ASSERT_NOT_BELOW_IO
makes sure that the current code is not under the I/O area. Existing code uses this macro just befor turning on the I/O area and just after turning it off. New code should use this macro, too.
_
. (This hasn't been done consistently yet.)@
notation.The original GEOS was copy protected in three ways:
Pull requests are greatly appreciated. Please keep in mind that a default build should always recreate the orginal binaries, so for smaller changes use conditional assembly using .if
, and for larger changes create new source files that are conditionally compiled.
The following command line will build the bsw
and wheels
variants of GEOS and compare the resulting binaries with reference binaries:
make regress
boot.s
should be based on the original GEOS versionboot.s
font.s
and graph.s
codeDlgBox
to support more than 16 filesFor the underlying work on GEOS, please respect its license.
The intellectual property added by the reverse-engineering and the subsequent improvements is in the public domain, but the authors request to be credited.
GEOS was initially developed by Berkeley Softworks in 1985-1988.
The original reverse-engineering was done by Maciej 'YTM/Elysium' Witkowiak in 1999-2002, targeted the ACME assembler and was released as GEOS 2000, which included several code optimizations and code layout differences.
In 2015/2016, Michael Steil ported the sources to cc65, reconstructed the original code layout, did some more reverse-engineering and cleanups, and modularized the code aggressively.