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...
1 comment:
Thanks for sharing your memories. The DEC-100B is not completely dead... MESS developers are trying to revive it, and would be glad to get expert advice at http://forums.bannister.org/ubbthreads.php?ubb=showflat&Number=75773&page=8
Interrupt logic is still a bit unclear, and the only attempt (so far) to emulate the DEC is DOS based - and incomplete - see
http://rainbow-100.com/archives/73/
P.S.: how about some source code in your blog - or a contribution to the Rainbow 100 archives? ;-)
P.P.S.: hope the links are OK. I am not associated with any of the sites!
Post a Comment