Today, 2003-12-28, I finished the F system. Of course, all the bugs and ugly solutions are still waiting to be fixed, but at least I have a working system. I thought this might be a good time to start documenting the project. After all, it is a school project, and the teachers explicitly stated that the process and not just the end product matters. I have a feeling they would not just accept over 5000 lines of undocumented code.
This document assumes that you are familiar with x86 assembly and some basic Forth concepts.
About F - what it is, and what it isn't.F is a Forth system, meaning that large parts of the system are written in the programming language Forth, its command shell is a Forth interpreter and some of the design is inspired by traditional Forth philosophy. I will try to motivate the deciscion to make a Forth system before I explain in more detail what the system does.
Forth programmers are in general minimalists. The inventor of Forth, Charles Moore, is a fanatic minimalist. Forth systems are, of that reason, often quite minimalistic. Yet they are powerful little systems. Because of its unique (among commonly used languages, such as C, Pascal and BASIC) extensibility, Forth can be used for everything from low-level tasks to complex object systems.
A Forth system (which often is both a compiler and an interpreter - this combination, unknown to C programmers, is what makes Forth so powerful) can be implemented on very small computers. One example is my own MTV system, a virtual machine for AVR microcontrollers with as little as 512 bytes of RAM (and a few kB of flash memory for program code). On this tiny one-chip computer you can run a combined compiler and interpreter! For us who are used to computers with 1GB in RAM and a hundred times that in hard disk space, those numbers are interesting. They say something about what kind of computer resources we really need for certain tasks.
I started programming in 1997, using Microsoft QBasic. The language is not very advanced but the interpreter (QBasic doesn't have any free compiler) takes a lot of space and is very slow. Now I realize my Forth system can do more than QBasic, and faster! Yet I wrote it in a few weeks, and its fits in less than 32kB. And that includes the operating system. There are of course many Forth systems that are much more well-designed than F, but I now realize that I wouldn't have needed MS-DOS and QBasic (together they take several megabytes) to have fun. A small Forth system could have done a lot more, much faster, using a fraction of the system resources used by DOS and QBasic.
F basically consists of:
The operating system kernel is not of any major interest. There is nothing really exciting about it, as it is just a bunch of assembly language functions to deal with the PC hardware.
The Forth compiler, on the other hand, is what makes F a bit special. When the system is booted, the operating system kernel is loaded. After initializing the hardware, it will start the Forth compiler, which compiles the system core. Parts of the compiler are now compiled, along with some hardware drivers (floppy disk) and the "file system". Once this is done (which should be quite soon - the whole compilation process only takes a second on my old 486 laptop) you will face the Forth prompt. You write a line of code, press enter, and the compiler/interpreter will take care of it. In fact, all the "system commands" are pieces of Forth code! This gives you very powerful "shell scripting" possibilities, since the "shell" is actually the compiler/interpreter.
Now to the sad part. What is F can not do? In theory, it can do just about anything you tell it to do. But as the system looks now, you have enough to write and run your own programs. This is everything Forth programmers need, but let's face it, at least 99.99% of all humans are outside that group.
As if that wasn't enough, most of F could be done better. The "file system" is a big joke. It usually works, but that's about it. It's slow, poorly designed, ugly in general, etc.. It has hard-coded support for floppy drives, modifying it for use with both floppy disks and hard disks would require some work. The editor is small (about 250 lines of Forth code), maybe a bit too small to be really useful. The most serious problem is the file system, if I'm going to continue this project once my school project is done, this will be the first thing I fix!
Description of F - file by file
Kernel | |
---|---|
crt.asm | Text mode functions |
gdt.asm | GDT functions - used to initialize the memory system of the CPU |
idt.asm | Interrupt handling |
ipc.asm | Interprocess communication, for sending messages between processes |
irq.asm | Initalization of the interrupt controller |
kbd.asm | Keyboard driver |
keymap_de/se/us.asm | German, Swedish and US keyboard layouts. |
newmm.asm | Memory allocator |
pit.asm | PIT initialization, used for multitasking and timing |
proc.asm | Multitasking |
timer.asm | Another part of the multitasking/timing system |
Forth compiler and dictionary | |
---|---|
compiler.asm | The Forth compiler |
core.asm | A collection of really basic Forth words |
coredict.asm | Don't look at this file ;-) It's just an ugly hack to create the core dictionary |
coreheader.asm | Macro to create headers for the core dictionary |
cpu.asm | Forth interface to the "cli" and "sti" instructions |
crtforth.asm | Forth interface to crt.asm |
dict.asm | Dictionary functions (only the "hash" word in here, there's more in core.f) |
ipcforth.asm | Forth interface to ipc.asm |
jump.asm | A few Forth words for jumping around |
kbdforth.asm | Forth interface to kbd.asm |
logic.asm | Logic operators |
math.asm | Arithmetics |
mem.asm | Various memory accessing words |
mmforth.asm | Forth interface to newmm.asm |
mtforth.asm | Forth multitasking words |
ports.asm | Forth interface to the "in" and "out" instructions |
stack.asm | Stack managment words |
timerforth.asm | Forth interface to timer.asm |
var.asm | Variable related words (more in core.f) |
There are two more files of importance, f.asm and core.f. The former is simply the entry point of the kernel, which fires up the compiler. core.f is the Forth part of the system, and is compiled at boot. It consists of basic Forth words which aren't implemented in the kernel (e.g. variables and loops), floppy disk driver, "file system" code and a text editor. It is rather well-commented, and I advice you to have a look at it.