After reading through a few papers on how Plan 9 supports every major system service via a true filesystem interface (making Unix look pathetically archaic in comparison). And, I got to thinking: Commodore had Plan 9 beat by 10 or more years. There were only two things that were critically lacking, and one not-really-quite-so-critical thing.
First, in Commodore's kern
el (sorry, but I refuse to use the CBM-misspelt name
), all I/O is performed over a byte-stream service. This is precisely the same interface as Plan 9. This is
theoretically the same class of service that Unix also offers, but over time, Unix (instead of making use of special control files like Plan 9 does) introduced such meta-operations as
ioctl(), fctl(), sockopt(), etc. In both the Commodore and the Plan 9 universes, this is done using special control files.
I therefore did some research on the Commodore Kernel, and found out that there were only ten or so kernel functions that were truely "portable" (in the sense that you could implement them on virtually any microprocessor). Of these, however, only six require any significant porting effort (by which, I mean having to spend more than two hours writing the code for the new platform):
OPEN, CLOSE, CHKIN, CHKOUT, CHRIN, and
CHROUT. The remainder are utility functions such as
CLALL that are so trivial to port that they don't require any significant porting effort.
It is also interesting that these functions assume all devices are GPIB devices. And, it just so happens that all of them are vectored through RAM, thus allowing for future capabilities (like, mapping devices 32-63 to a second IEEE-488 bus, for example). Well, what happens if we define a pseudo-device 255 such that it's filename space happens to be a generic, hierarchial namespace?
I am attempting to implement such an extension now, and it's being defined for the Commodore 64 for the time being. I suspect that it would be easy to port to the +4, Commodore 128, and for that matter,
even a PET or VIC-20. This new subsystem is called
Colonel.
Initial estimates indicates that Colonel can fit in 2KB of space or less, not including dynamic data (like device node structures), thus making it viable also for an unexpanded VIC-20. Barely.
I'm writing the sources using
noweb, a literate programming tool. This will therefore allow me to fully document the internal structure of the software in a way that no other Commodore documentation has been able to provide in the past. Indeed, looking at the Linux sources sure isn't helpful in determining how its VFS system is implemented. The book that will result from this will be very enlightening. English only, I'm afraid, as I'm only English literate.
I posit, therefore, that the Commodore Kernel already makes an ideal "BIOS" of sorts for a standard, 6502-targeted CP/M-like operating system. All that needs to really be written is a replacement for BASIC which serves as the command-line shell.
For those platforms which do not have the Commodore Kernel in place already, let it be known that the overwhelming majority of the Commodore Kernel functions are related to either the screen editor, or to
hardware specific functionality (e.g., IEEE-488 or IEC buses, reading/writing the VDC chip in the Commodore 128 and B-series computers, etc). Therefore, they're relatively rarely used, and the programs that do use them make obvious assumptions about the underlying hardware. Thus, we can claim that the Commodore Kernel
really consists only of OPEN, CLOSE, CHKIN, CHKOUT, CHRIN, CHROUT, CLALL, SETNAM, SETLFS, and maybe even READST. The rest are user interface amenities or utility functions to help with lower level I/O facilities (e.g., bit-banging the serial IEC bus). With so few core functions, it should be quite possible to "port" the Kernel to other 6502 platforms easily. Thus, as with CP/M, the "BIOS" (kernel) is implementation dependent, while the BDOS and other layers on top of it are relatively portable.
Anyway, enough background. The basic idea in Colonel is the implementation of a hierarchial, uniform namespace with support for installable device drivers that run locally on the machine. This flat space is assigned pseudo-device 255. For example, here is a simple
hypothetical BASIC 2.0 program that makes use of the mouse (assumes Colonel and a mouse driver are already loaded):
Code:
10 PRINT "{clrhome}CLICK ON [QUIT] TO EXIT."
20 Q=0:REM QUIT INDICATOR
30 OPEN 1,255,0,"DEVS:MOUSE:0"
40 IF Q<>0 THEN GOTO 90
50 INPUT#1,X,Y,B
60 PRINT "{home}{down}X=";X;"Y=";Y;"B=";B
70 IF B<>0 THEN Q=1
80 GOTO 40
90 CLOSE 1
Colon is used instead of the slash since CBM-DOS lets slashes appear in filenames. I didn't use a comma because, as with VMS, the comma appears to be used to append
options to specific arguments (e.g., OPEN 1,8,1,"COLONEL
,P,W").
Anyway, you get the idea. Drivers are selected based on longest match of the given filename. The filename is available in its entirety for the driver to examine (for example, the driver itself may be bound only to DEVS:MOUSE, treating the :0 suffix as a parameter for something -- in this case, which port the mouse would be hooked into).
This should work also with LOAD and SAVE as well. In fact, a better form of directory support should be implementable with yet another special driver:
Code:
LOAD"CATALOG:DEVS",255
LIST
could be used to get a directory listing of what's currently inside the DEVS directory.
Since the C64 lacks any concept of "current directory," it follows that all paths specified are inherently anchored at the Colonel's root namespace. Therefore, there is no need for a leading colon (contrast with Unix, where to specify an absolute path, you need to specify the leading slash). Support for "current directories" shouldn't be too hard to implement, but at this stage of the game, I don't yet see any need for it.
Just giving an update on my rationale and thinking processes. I'll update here once I finish Colonel to a point where it's usable.