The Magic Schoolbook O.S. Project

News: MSB-OS now has a hex mode for those who don't like decimals.

Machine Editor 2 - shows indexed machine code

More screenshots

The latest disk image of MSB-OS is available here (right-click on the link and choose an option such as "save target as"). This file is not a picture, but simply holds the entire content of a floppy disk so that it can be copied onto a physical floppy disk at your end (boot sector, directory and all). This way of doing things completely removes the need to send disks through the post. Alternatively, the disk image can be used directly by a PC simulator program without you needing to copy it onto a physical floppy disk. [Previous version.]

If you want to run it directly on a computer, you will need to use a program such as Rawwrite to get it onto a floppy disk. Once you've done that, it should be possible to boot any PC (386 or later) with it. A safer option (if you're worried about possible damage that it might do) is to run it through a PC simulator on your PC, and the best one to use for that is probably Bochs (click on "see all releases" to reach the download - the links that look as if they should lead to it just take you round in circles). That is what most people do these days when trying out new operating systems - Bochs lets you run an OS in a cage so that it can't damage your machine if there's something wrong with it. Bochs runs like any other Windows application and will not mess up your machine in any way. It's also a very compact program which runs in a small window on your screen. If you have any doubts about it, check out and you'll soon realise that it is a very well respected program in the community of operating system developers.

I'll now give you an overview of what MSB-OS does and explain how it came to be.

What can you do with it?

MSB-OS gives you an fantastic view of the inner workings of a computer, and it also teaches you how to program directly in machine code, giving you the best possible idea of what's going on behind any programming language (and bear in mind that even assembler keeps a lot hidden from you). MSB-OS lets you program at the lowest possible level, but it also makes it really easy - you may have heard a lot of talk about the extreme difficulty of programming in machine code, but MSB-OS uses indexed machine code so that whenever an edit causes code to move it is automatically updated to run in its new location, and it also allows you to name variables and routines so that code can be linked to them simply by typing in their names - the big difficulties of direct machine code programming have thus been eliminated, and the result is an efficient and fun programming environment where you always see exactly what you get.

The name

MSB stands for both Magic Schoolbook and "most significant byte" (a programming term), but I should make it clear straight away that the name MSB-OS is not necessarily going to last - I have a better name planned for it, but it costs a lot of money to protect a name and I really don't want to spend that at this point in time.


I originally wrote a little operating system to run on the ZX Spectrum+3, creating all the program code as machine code instructions held in data statments within a Basic program. All I had to go on was the manual with its list of machine code numbers and mnemonics at the back, plus a few magazines for the Amstrad PCW (called 8000+), one of which had a diagram of the Z80 register set (the part of the processor where data is acted on) and a few examples of how to use the assembler that comes with CP/M. I found an instruction in Basic which could be used to run machine code starting from a specific address, so I did some little experiments by poking instructions into memory and then running them, making sure I put a 201 at the end to return control to Basic. Bit by bit, or rather byte by byte, I worked out what most of the instructions did just through trial and error, though helped initially by running the magazine examples on the Amstrad to see what numbers their mnemonics were converted into - that enabled me to match up a few known instructions to the Spectrum mnemonics which were radically different.

I created increasingly complex pieces of machine code program to do various simple things and eventually built up the confidence to have go at putting together a little operating system, the idea being to create an indexed machine code programming environment which would let me bypass Basic and automate the updating of addresses in the code whenever an edit resulted in code being moved to a new location in memory. It took practically all the memory available in the Specrtum+3 just to hold my Basic program of data statements, and it began to behave unreliably towards the end, often deleting half a data statement without any sign that it had done so, so the process became a bit of a nightmare by the end. Fortunately, I completed the task and ended up saving my machine code program in a 4K array which could be loaded in directly from Basic. I then loaded it into a second location in memory and adjusted it to run in the new location, thereby giving me two versions of it which could modify and save each other. From that point on, I could do all my programming in machine code without having to use anyone else's system other than to load the two arrays into memory and save them back to disk at the end if I modified them.

I had planned to do artificial intelligence work on top of it, but there wasn't a lot of memory space on the Spectrum, so I decided to port everything to the Amstrad PCW. I created a third version of my program on the Spectrum+3 but modified so that it would tie in with the different ways the PCW handled hardware, though I relied on CP/M to load it in from disk and never got it to the point where it could boot itself directly on that machine, although I did write the boot sector code that would have done the job. The trouble was that by this time the PCW was becoming obsolete and I couldn't get hold of extra memory for it, added to which the memory had to be switched in and out of a 64K active zone in 16K blocks, so it was problematic. I decided to switch to the PC and start from scratch.

So, it was back to data statements again, this time using Qbasic to hold them and post the code into memory. Rather than just translating all my old code from Z80 to 8086 instructions, I began by making sure I could handle the extra complications of the PC, and that meant being able to switch the processor into "Protected Mode", thereby allowing 32-bit programming and escaping from the nightmare of "Real Mode" which I had every desire not to work with. It took a lot of hunting on the Web to find enough information on how to do this, and a fair bit of trial and error was required in addition, but I got there in the end and without copying or even seeing anyone else's code. The next step was to try to communicate with the floppy disk control chip, so I translated my own completely untested Z80 device driver for floppy disk drives and tried it out to see if I could read and write sectors. It was surprisingly easy, and I designed my own floppy disk format too so that I could save files to the nearest sector rather than using the 1K or 2K datablocks of MS-Dos and CP/M. I managed to fit my device driver into the boot sector where it would run in 32-bit mode to load the rest of the operating system, so the BIOS was only used to load the boot sector. I then set about building my PC operating system and after a lot of struggles eventually got it to the point where it could boot from a floppy and then modify and save itself back to floppy.

My programming system

Since writing my OS I've used it extensively as a platform for my artificial intelligence work, but I've also written a text editor and a sudoku solving program, both written directly in machine code. My programming system makes machine code programming much easier than assembler, and I reckon it's just as easy as using a programming language - I have lots of routines which I can call to do simple things, so if I type in "232" and get the indexing system to provide the 4-byte jump distance to a routine called "rt", I end up with five bytes in memory and ready to run, and when it does run it will move the cursor to the right. I called my programming system Machine Editor because it allows you to edit the memory of the machine at will - you can go anywhere, see a screenful of numbers, including indexed names if it's looking at program code, you can watch variables changing as code runs, and you can even modify code while that code's actively running (though you have to know what you're doing if you want to avoid a crash). My operating system gives you an amazing view of a computer in action, and if you run my debugging program (Monitor) you can watch indexed machine code run through the register set of the CPU byte by byte, seeing all the names go through along with the numbers (which are all in human-friendly base 10 which is far easier to read than hex, although a hex mode has just been added so you can do it the hard way if you prefer).

It's really easy to write a program with MSB-OS: you just go into Machine Editor, search for eoc (end of code) in any cell of program code (code cells are typically 16, 32 or 64K in size, though they can be any multiple of 1024 bytes), move eoc to make some space in front of it to write your code in, then type numbers in. If you want to run your code through the monitor, you simply start it with 232 mntr (the indexing system provides the jump distance and puts the letters "mntr" over the first of the four bytes added in. If you put 150 151 151 150 195 at the end of your code it will switch out of Monitor and return control to Machine Editor. To run your code, just put the cursor on the first byte and type "r" followed by the Return key. Any variables you need can be put before or after your code, each one given a name so that you can link to it from your code. Once a program is complete you can move all the variables down to the bottom of the code cell and make sure they line up in such a way as not to slow the machine down, though for education purposes, or if you're planning to modify the code again, it may make sense to leave them right next to the code so that it's easier to see what's going on.

The plan now

What I want to do now is make my OS available for people to play with, and as the code is 100% mine I'm able to allow them to use it in any way they please (just so long as they aren't making money from it, in which case I would want my fair share, and the same for anyone else whose code is involved), though I will be developing more complex levels of the OS which people won't be allowed to copy or see the documentation for (related to my A.I. work). If you use any of my code in a project of your own, you must acknowledge the fact that you have done so in a manner such as stating on the screen at boot time who the authors are.

My hope is that other people will join the project and help improve the operating system, adding new capability to it, but always with the aim that the code created should be open for anyone to do whatever they want to with it on the basis described above, and that includes using it as a core for a closed OS of their own. The key thing is that people should be able to learn how all aspects of operating systems and PCs work without the knowledge thus acquired restricting them in any way through copyright problems if they then develop necessarily similar code of their own. If you don't want your contributions to the project to be copied by others on the basis of what I've just said above, don't get invovled with the project. The people I want to work with on this are probably other people who are trying to build their own OS, so if we all team up and work on different bits, we can improve the capability of all our OSes at the same time at a much higher rate than by working alone. I personally don't want to copy anyone else's code at all and it may be everyone else will feel the same way, but there's still a lot to be gained from sharing knowledge of how different bits of hardware work and how an OS is supposed to communicate with them. I am not so bothered about writing my own device drivers for every possible piece of equipment that might be in or attached to a PC, so I'd be quite happy to bolt on other people's code for that. I'm pushed for time because of other work, but one priority is to try to get away from using floppy disks and to use little USB flash drives instead without having to do so via the BIOS. I've got hold of a lot of USB documentation, but it's going to be quite some task going through it all to work out what to do with it.

I only recently found the osdev site for OS writers, and it's thanks to the people there that I've found out how to make an OS available over the Web, so if you're interested in the idea of writing one of your own you should have a look at the Wiki there - it hands you almost everything you need to know on a plate, saving you from the years of research and trial-and-error experimentation that I had to do when I originally wrote mine.

It may be a while before anything else appears here, but in the meantime you can email me at osproject at magicschoolbook dot com. I'm going to write up all the code properly so that other people can understand it and modify it if they wish to, and then I'll sort out more of the incomplete code so that things like the inter-cell linkages work properly in all directions.

Some of the major faults needing to be put right

EBDA can be written over (I didn't know there was such a thing until recently); machine directory assumes machine has 4MB RAM and doesn't allocate anything beyond that point (because I've done all my work on a machine with 4MB RAM and haven't got round to modifying it for other machines - I was planning to probe for memory, but now know not to); floppy disk code doesn't check to see if there's enough room on the disk to save a file to (as I haven't got to the point where I'm in danger of filling one); haven't yet implemented a proper system for allocating memory for data files - it only does it properly for program code (e.g. a fixed amount of space is given to text editor documents regardless of file size, so a document could outgrow the available space and there's no check made to see if it does - hasn't been a problem for me so far as I've known to keep text files small, but it's just one more thing in a long list of things that need to be done which I haven't got round to yet); etc.