The time I really badly implemented 8086

This is a story from the time before time, when I was in high school in Italy. My high school was a technical high school that had both programming and “systems” classes — “systems” being a shorthand for “Information processing and communication systems”, which encompassed a bit of state machine theory, networking, low level computing, and… well, turns out that it matched fairly well with Feynman Lectures On Computation, which is the book I’m reading now during the quarantine. It also included a bit of “basic computer literacy”, given that the first laboratory tasks was re-typing some math textbook pages in Microsoft Word (and not even requiring to use Equation Editor!)

I think it was on our fourth year of high school (second year of systems), that the classroom topics geared towards CPU, memory access, and so on, while laboratory became both interesting and annoying at the same time: we started learning about assembly language, but also we started that by manually assembling binaries: we were first given, then required to write, simple assembly programs, then using a paper reference tables of instructions-to-opcodes asked to write the COM file for it.

This didn’t go at all into explaining how opcodes work, things like operand selections, or even explaining why accessing the AL/AX registers is so much faster. It was just a manual translation table that a certain operation would then become a fixed set of bytes. This is why I found most of those lessons annoying at first.

Eventually, we graduated to using MASM. Which was also a bit annoying for me because at home I only had access to NASM, but it was at least a bit more interesting at the same time. Unfortunately around that time we also were introduced to how we would be testing some more features of low-level program writing: I/O and peripheral control were going to be explained and exercised through a complicated Rube Goldberg machine that consisted of:

  1. Create the COM/binary file on one of our lab machines, either through the aforementioned manual translation, or MASM.
  2. Load the binary file onto a floppy disk.
  3. Get the floppy disk onto the single 486 machine for the lab that has an EPROM programmer attached to it. One machine, for the whole 20 people class.
  4. Flash the binary onto an EPROM (nope, not EEPROM!).
  5. Put the EPROM back onto an 8086 motherboard, which had been jury-rigged to act as effectively an embedded micro, with a few LEDs, buttons, and step motors attached to it.

You can imagine that this was quite a waste of time overall, and also had one of the worst iteration speeds. Having always thought that the best way to learn something is to try doing it differently all the time, it was a frustrating experience, but one that I wanted to get something good out of.

So, without consulting any teacher, I sat down at my home computer, with a copy of Borland C++ Builder, a complete edition given away for free by an Italian magazine at the time, and started looking at how to simulate the 8086 CPU with a C++ program.

At that point I had barely any idea of what I was doing — I had used Borland C++ Builder already to make simple clicky-button programs for myself, but not only I had not shared them with anyone at all, but also they were pretty much horrible quality. I had also no idea how the CPU actually worked. The explanations in class had been extremely high-level and handwavey, and the registers have been always sorted as AX, BX, CX, DX.

What I did end up doing was ordering a copy of Intel’s Architecture Manuals (back when Intel still mailed them to you in print copy!) and poured hours and hours on them. Still with not much of a clue of what I was doing, but I did manage at the end to implementa janky, but usable simulator for the 8086. I originally planned to implement the I/O states so that I could simulate the step motor, but I never went down that route — instead it just executed the given program, and printed out at the end the state of all registers, and of memory.

I didn’t know about segmented memory, so I had a very naive implementation of the segment registers, but it turned out to be good enough for preparing the exercises at home, and not having to go “back to the centre” (where the motherboard contraption was) more than once per exercise.

I’m afraid I don’t know if I still have the sources anywhere. If I ever will find them again, I’ll probably publish them, despite me looking very silly. It was an usable tool for me, but not just for me — my teacher was impressed and, for the following few years, he used it himself, although I’m not sure if he did that to design the exercises or grade them. I know that a couple of years after I left school they eventually dismissed the Rube Goldberg machine in favour of PIC, but I honestly have no idea if they ended up just giving every station a programmer, or if they still required to take turns.

Some of the things that I learned while trying to implement this are still clearly stuck in my head. For instance this was the first time I tried using function pointers, and figured out that function pointers for C++ methods are not a great idea.

I have actually had this in mind when I was looking at hacking my laptop’s keyboard. Since I couldn’t find enough 8051 tools at the time, I was considering writing my own disassembler and simulator. I might even still do that, despite me not having that laptop anymore, since I’m going to be using 8051 for my art project. But in this case, I would probably just do it in Python, speed is definitely not the issue at hand here.

Working under Windows, my personal hell

If I am to go to hell, I know already what it will look like: no Linux, no Mac OS X or any other Unix. Just Windows and (maybe) OS/2. And I’m still a programmer. And a system administrator at the same time.

It so happens that my current job requires me to work under Windows, to develop software, well, for Windows. For a series of reason that I don’t want to start explaining here, I decided to go with Borland, sorry, CodeGear C++ Builder as IDE rather than Microsoft’s or Qt. The main problem is that the software ha to be redistributed as proprietary, and cannot relay on stuff like .NET framework (otherwise I could have easily completed it already using Visual C# Express).

I have to admit I find myself way more comfortable with Borland, sorry, CodeGear rather than Microsoft’s sorta-C++ environment, mostly because I learnt real programming with BCB 3 (I had a “personal” license that was given for free with an old magazine years ago). I don’t really like much of the orientation that CodeGear has, but at least I can work with it without going crazy, which is decent anyway.

What is the problem? Well I didn’t have a Windows installation for about five years before, and my last license of Windows was Windows 95; I had to buy a Windows XP license (and it still costs €400 even though it has been released more than five years ago by now), and a license of CodeGear C++ Builder (electronic copy costs €100 less, but it still costs almost one grand). Then I had to get used again to working with VCL.

Not a big deal, mind you, but it reminds me why I so much like Qt, GCC and Emacs. Sure I could use these three on Windows, but not for what I need to do :/

On the other hand, I was able to use a piece of free software to save some of my time: rather than using the XML Writer interface as exported by MS XML services, I built libxml2 (which strangely enough supports Borland compiler natively) and used that, it features a very similar interface, but way nicer. The XPath interface is a bit messy (I was unable to find a way to execute recursive XPaths, that is, after finding a node through XPath, I couldn’t find how to run a second XPath on that, so i had to complete the task with sequential access; if anybody knows how to do that I’d be glad to know). I sincerely find libxml2 could use some better API documentation, if I have more time I’ll gladly see to write it.

But it’s not even done here. I decided that running the virtual machine on a virtual disk on the laptop was being too slow, so I decided to use BootCamp to install on the real disk and use that through Parallels. Reinstalling everything is a pain especially when Windows seem to require ten runs of Windows Update to get the updates right. And users complain about having to use --resume --skipfirst with Gentoo from time to time ;)

Right now I am storing my work data on a virtual hard drive still, as I couldn’t give enough space on the real disk for Windows, and of course Windows does not support the GPT partition scheme I use on the external Firewire drive. It’s frustrating that I can share that disk just fine with Linux and OSX but I’d need another hard drive to get it to share data with Windows. I suppose I should write that off for the future.

Using Parallels shared folder feature, by the way, seems to be quite impossible with development environments: .NET based stuff won’t run the applications with full privileges because they are seen as coming through the network; CodeGear RAD Studio tries to validate the hostname (.PSF) and as it is invalid it fails to open any file that resides on it (unless you map it to a network drive), the Borland Incremental Linker (ilink32) fails because Parallels uses case-sensitive lookup for files, while ilink32 looks for all-caps filenames (MainUnit.cpp becomes MainUnit.obj, but the linker looks for MAINUNIT.OBJ).

I should probably put the subversion repository for my work on Enterprise, but I don’t wan to access it through SSh as it would mean adding a private key able to access Enterprise to Windows…

I sincerely hope my next jobs will stay under Linux for a while, after these two are done :)