An old-school hack remembered

Way back in the days of yore, when Turbo C++ had just came out, I was using a DEC Rainbow 100B+. For those not old enough to recall, this was a machine that came out in 1985 with software that came out in about 1990. Boreland had done a good job of not using all the IBM BIOS calls, so its compilers and such were useful on the Rainbow. The Rainbow had an 8088 processor in it, but wasn't IBM Compatible (being released at about the same time the IBM PC was). The Rainbow was better in a lot of ways, which is how I wound up with it, but worse in other ways...

However, Boreland hadn't done a perfect job. They had used an unused software interrupt (INT 18h) for memory management of the compiler. Early versions of the Turbo C++ used it in only a few places. Patches quickly appeared in the Rainbow community to allow one to run TurboC++ on the Rainbow. These patches were about a hundred lines of code and just patched the offending INT calls to use a different vector (one that was unused on the Rainbow).

I had seen these patches, and when my job was using C++, I thought it would be cool to be able to compile code for it at home. I went out and bought Turbo C++, only to discover it was a newer version of the compiler than the one the patches were for. They just didn't work. So I wrote the author of the patches, who seemed a little put out with me for asking so soon after the compiler was released. Feeling a little bad for not having given more to the online Rainbow community that had given me so much cool software, I resolved to create patches myself and post them.

To make a long story short, I failed. The code was too complicated in the new version for someone of my meager skills (at the time) to produce patches. The calls were all over the code, and the sequence of bytes that invoked INT 18h were in many places that turned out to be data.

Being young, and still struggling to make ends meet, I wasn't about to let this get in my way. I didn't want to have wasted that $80 on software I couldn't use and now couldn't return. Buying a new machine was out of the budget at the time. So I came up with a clever hack, which I'll describe now.

On the DEC Rainbow, INT 18 was used for video output. So when the compiler ran, it would call INT18, which would then dive into the BIOS with loco registers crashing the machine, or just not working. The trick turned out to be simple. I used a TSR to fake things out. The TSR would load at an address that could be known at run time. This TSR hooked into the MS-DOS interrupt vector which was used to set interrupt vectors and into the interrupt vector that was called when a progam terminated. I also hooked into the INT 18h interrupt vector to vector calls to it through my code. When a normal program would run, it would get the system's INT 18h call, and all the video would work. This let me run my editors, terminal emulators and games without rebooting. When Turbo C++ would run, it would install its own INT 18 handler to do its thing. My program intercepted this call and just saved the target for later use rather than writing it into low memory to give it effect. Later, when an INT 18 call happened, I'd check the calling address. If it was at or below my TSR or in the ROM BIOS, then I know it was something in the system making the call and I called the original INT 18 handler. If it was above my address, I knew it was boreland's compiler and would call the address it had tried to install earlier. When the turbo C++ terminated, I'd reset things to the initial state.

I did this trick almost 18 years ago now, yet it still strikes me as a clever way around a problem. The program took me an afternoon to write and debug, yet provided me with years of useful service until I retired the Rainbow...


Building a bootable ARM SD

A few weeks ago, I wrote up how to make a bootable i386 image. People have been asking me to extend it for my ARM platform.

Here are the instructions for a hypothetical box that has a boot loader that can load an image from a FAT partition of a SD card, and FreeBSD runs off of a ufs partition on the SD card. This will be for a big endian ARM target, based on the AVILA kernel. I'm also assuming that this platform doesn't use FreeBSD's normal /boot/loader.
  1. setenv MAKEOBJDIRPREFIX /blah
  2. setenv TARGET arm
  3. setenv TARGET_ARCH arm
  4. setenv TARGET_CPU xscale
  5. make buildworld
  6. make buildkernel KERNCONF=AVILA
  7. fdisk -I da0
  8. fdisk -f disk-partitions da1
  9. newfs -t msdos /dev/da0s1
  10. bsdlabel -w da0s2 auto
  11. newfs /dev/da0s2a
  12. mount /dev/da0s2a /mnt
  13. make installworld DESTDIR=/mnt
  14. make installkernel DESTDIR=/mnt KERNCONF=AVILA INSTALL_NODEBUG=t
  15. make distrib-dirs DESTDIR=/mnt
  16. make distribution DESTDIR=/mnt
  17. echo /dev/da0s2a / ufs rw 1 1 > /mnt/etc/fstab
  18. echo ifconfig_DEFAULT=DHCP > /mnt/etc/rc.conf
  19. echo hostname=demo >> /mnt/etc/rc.conf
  20. cp /mnt/boot/kernel/kernel /tmp
  21. umount /mnt
  22. mount -t msdos /dev/da0s1 /mnt
  23. cp /tmp/kernel /mnt
  24. umount /mnt
In step 8, one needs to have a special file. Here's what I use, but one needs to automate it a little more. Here's a hand-tuned one that I used for a 1GB SD card I had laying around.

# partition table
g c940 h32 s63
p 1 6 63 201537
p 2 165 201600 1780128

Clearly, one needs to tune the above for their specific part. NanoBSD tries to automate this process, but that is beyond the scope of this posting.

Update: fixed step 17.


Article about my past life

Wired has a great article about the high precision hobbyist timing community. These folks are less fanatical about timing than the professionals, but not by much. You know you are a true time geek when you understand the joke in Tom's quote from the article about his trip to a tall mountain near his home "It was the best extra 22 nanoseconds I've ever spent with the kids." Check it out here.


Cisco and Observations of a new Mac user.

Last week I started at Cisco. The entire week I tried to figure out how to drink from a fire hose without getting hurt. This week, I'll be learning where to go for help with fire hose related injuries. :-).

Seriously, I've joined a very dynamic and energetic group here at Cisco. The job so far has been a blast, and I'm really enjoying the work. We're at the early stages of many things in my group, so it would be a little premature to talk about them right now. since Cisco hires a lot of people, they have managed to optimize the typical new-hire HR madness enough that I was able to get something accomplished last week.

And I even found time to tweak the new MacBook Pro that showed up on my doorstep. This is the first employer provided laptop that I've had in at least 15 years. The last one was a Tadpole Sparcstation II class machine... I knew that Apple had done a great job on the GUI, but when I was able to setup printers and get onto my Samba shares without doing more than a few key clicks to accept automatically discovered items, I was hooked. On my Windows box that I keep around for the rest of the family, these two activities took me a couple of days of hacking to get barely working some of the time. OS X Leopard just works, and I have all the unix tools I know and love.