The main piece of work that is still necessary for GEOS is a proper filesystem interface.
Current Status
Since it is derived from the C64 version, X16 GEOS currently assumes the SD card is a 1541 disk. Nice for a proof of concept, because you can pass -sdcard APPS64.D64 to the emulator command line and it'll boot into "Desk Top". But users aren't going to waste their 32 GB SD card by using them as a single 170 KB disk.
The Problem
The Commodore version of GEOS, which the X16's version is based on, depends a lot on the "BAM" filesystem (1541, 1571, 1581, CMD FD, CMD HD). This happens on the following layers:
The plug-in disk driver (1541, 1571, ...) abstracts block reading/writing, block allocation and the directory structure.
The generic filesystem handler deals directly with BAM-features like block chaining, the VLIR format and the directory entry format.
This is exposed through a 3-layer API:
a) low-level API: interfaces the block reading and writing functions of (1)
b) mid-level API: interfaces with block allocation, directory structure of (1), adds logic on top
c) high-level API: abstract enumerating, reading, writing files
Some applications decode parts of the filesystem manually and rely on the VLIR on-disk format. (Because GEOS can only handle one VLIR file at a time, geoWrite reads overlays from its own executables manually, for example.)
While it would be okay to rewrite (1) and (2) and patch applications (4), the fact that some the API (3b) is BAM-based (similar to CP/M FCBs) makes this tricky.
Approaches
BAM Disk Images
A simple solution would be to use disk images on top of FAT. But this carries a lot of legacy baggage and makes it very hard to exchange files with modern systems. Also, the maximum size of BAM-like filesystems is 16 MB (255 tracks of 256 sectors of 256 bytes).
(The X16 isn't about recreating the past and being compatible, but about making new retro development easy, so we shouldn't be too worried about compatibility. In other words: X16 GEOS is not there to run the full C64 GEOS catalog – it's there to be able to write new GEOS applications on nicer hardware.)
Apple-like Port
There was an Apple II version of GEOS that worked on top of the ProDOS filesystem, with 512 byte blocks, different block linking, different allocation tables, a different directory entry format – and subdirectory support! This was so different that applications weren't binary compatible between Commodore and Apple, but they could be 99% the same code, plus some #ifdefs.
We could port GEOS to FAT like it has been ported to ProDOS: Keep the high-level API the same, keep the rest of the API the same in spirit, but change all necessary details, and add functions. This will make some applications incompatible, but is a very clean solution.
In-between
There is a way to retain some more compatibility without going into great lengths. Examples:
BAM defines a 30 byte directory entry structure, which is exposed by the GEOS APIs. We could keep this format the same and declare it the API's directory entry interchange format: The filesystem code will convert to and from this format when reading/writing actual entries from/to disk.
Similarly, the 256 byte dir header, containing the disk name, can be virtualized.
Block pointers ("Track/Sector") could be virtualized.
The GEOS Disk API
VLIR Level
API
Description
OpenRecordFile
Open an existing VLIR file for access given its filename.
CloseRecordFile
Update the VLIR file's IndexTable and the disk BAM. indicate no open VLIR file.
UpdateRecordFile
Update the VLIR file's IndexTable, disk BAM, and Time/date stamp.
PreviousRecord NextRecord PointRecord
Adjust current record pointer to the previous, next, or to a specific record in the vlir file.
DeleteRecord
Deletes current record and leaves curRecord pointing to the following record.
WriteRecord
Writes contents of memory area out to Current Record.
ReadRecord
Reads Current Record into memory.
These are sufficiently high-level that they should work with any underlying filesystem. These are the core APIs used by document-based applications.
High-Level Disk Routines
API
Description
Comment
GetPtrCurDkNm
Returns a pointer to a buffer containing the name of the disk
easy
SetGEOSDisk
Converts a normal C64 DOS disk to a GEOS disk
trivial
CheckDkGEOS
Checks to see if the current disk is a GEOS disk
trivial
FindFTypes
Generates a list of all files on the disk of a specific type
easy
GetFile
Launch app/desk accessory or open file in app
no change
FindFile
Searches the disk for the file, returns its Directory Entry
"Directory Entry" virtualization
DeleteFile
Deletes a file from the disk
easy
SaveFile
Saves a GEOS file to disk
"T/S" virtualization
RenameFile
Gives a file a new name
easy
CalcBlocksFree
See how many free block there are left on disk
65535 blocks (16 MB) limit
Intermediate Routines
API
Description
Comment
FindFile
Returns a file's Directory Entry.
"Directory Entry" virtualization
GetBlock
Reads a block from disk.
not useful
PutBlock
Write a block to disk, and verifies it.
not useful
GetFHdrInfo
Given a Directory Entry, fetches the file's File Header block.
"Directory Entry" virtualization
ReadFile
Reads a track/sector linked chain of blocks from disk.
"T/S" virtualization
WriteFile
Writes memory data out to a linked chain of blocks on disk.
"T/S" virtualization (b)
ReadByte
Simulates reading a byte at a time from a chain of blocks.
"T/S" virtualization
GetDirHead
Read the Directory Header and BAM from disk.
"Dir Head" virtualization
PutDirHead
Writes the Directory Header and BAM back to disk.
"Dir Head" virtualization
NewDisk
Initialize the drive.
trivial
LdApplic
Loads and runs a GEOS application.
unchanged?
LdDeskAcc
Loads and runs a GEOS desk accessory.
unchanged?
LdFile
Loads a GEOS file.
unchanged?
GetFreeDirBlk
Get a free Dir. Entry. Allocate a new Dir. Block if necessary.
"T/S" virtualization? (b)
BlkAlloc NxtBlkAlloc
Allocate a chain of blocks on the disk.
"T/S" virtualization? (a) (b)
SetNextFree
Allocates a free block on disk.
"T/S" virtualization?
FreeBlock
Frees up one block on disk.
"T/S" virtualization? (b)
SetGDirEntry BldGDirEntry
Create a Directory Entry from a Header Block.
"T/S" virtualization? (a) (b)
FollowChain
Create the tr/sec list in fileTrScTab for a chain of blocks.
"Directory Entry" virtualization (a) (b)
FastDelFile
Frees blocks indicated by the tr/sec list in fileTrScTab.
not useful (a) (b)
FindBAMBit
Returns information about a block.
"T/S" virtualization? (b)
FreeFile
Free all blocks in a file. Leave the Directory Entry intact.
not useful (a) (b)
ChangeDiskDevice
Changes the device number (8 or 9) the drive responds to.
not useful (b)
(a)These APIs are not called by Desk Top (a very low-level app!)
(b)These APIs are not called by geoWrite.
These should give an indication that some APIs are not common in applications.
The main piece of work that is still necessary for GEOS is a proper filesystem interface.
Current Status
Since it is derived from the C64 version, X16 GEOS currently assumes the SD card is a 1541 disk. Nice for a proof of concept, because you can pass
-sdcard APPS64.D64
to the emulator command line and it'll boot into "Desk Top". But users aren't going to waste their 32 GB SD card by using them as a single 170 KB disk.The Problem
The Commodore version of GEOS, which the X16's version is based on, depends a lot on the "BAM" filesystem (1541, 1571, 1581, CMD FD, CMD HD). This happens on the following layers:
While it would be okay to rewrite (1) and (2) and patch applications (4), the fact that some the API (3b) is BAM-based (similar to CP/M FCBs) makes this tricky.
Approaches
BAM Disk Images
A simple solution would be to use disk images on top of FAT. But this carries a lot of legacy baggage and makes it very hard to exchange files with modern systems. Also, the maximum size of BAM-like filesystems is 16 MB (255 tracks of 256 sectors of 256 bytes).
(The X16 isn't about recreating the past and being compatible, but about making new retro development easy, so we shouldn't be too worried about compatibility. In other words: X16 GEOS is not there to run the full C64 GEOS catalog – it's there to be able to write new GEOS applications on nicer hardware.)
Apple-like Port
There was an Apple II version of GEOS that worked on top of the ProDOS filesystem, with 512 byte blocks, different block linking, different allocation tables, a different directory entry format – and subdirectory support! This was so different that applications weren't binary compatible between Commodore and Apple, but they could be 99% the same code, plus some #ifdefs.
We could port GEOS to FAT like it has been ported to ProDOS: Keep the high-level API the same, keep the rest of the API the same in spirit, but change all necessary details, and add functions. This will make some applications incompatible, but is a very clean solution.
In-between
There is a way to retain some more compatibility without going into great lengths. Examples:
The GEOS Disk API
VLIR Level
OpenRecordFile
CloseRecordFile
UpdateRecordFile
PreviousRecord
NextRecord
PointRecord
DeleteRecord
WriteRecord
ReadRecord
These are sufficiently high-level that they should work with any underlying filesystem. These are the core APIs used by document-based applications.
High-Level Disk Routines
GetPtrCurDkNm
SetGEOSDisk
CheckDkGEOS
FindFTypes
GetFile
FindFile
DeleteFile
SaveFile
RenameFile
CalcBlocksFree
Intermediate Routines
FindFile
GetBlock
PutBlock
GetFHdrInfo
ReadFile
WriteFile
ReadByte
GetDirHead
PutDirHead
NewDisk
LdApplic
LdDeskAcc
LdFile
GetFreeDirBlk
BlkAlloc
NxtBlkAlloc
SetNextFree
FreeBlock
SetGDirEntry
BldGDirEntry
FollowChain
FastDelFile
FindBAMBit
FreeFile
ChangeDiskDevice
(a)These APIs are not called by Desk Top (a very low-level app!) (b)These APIs are not called by geoWrite. These should give an indication that some APIs are not common in applications.
The Most Primitive Level