Making Obsolete Code Run Again: The mxass 6502 Cross Assembler

Here’s the challenge: Take code that you wrote some 20 years ago in an obsolete programming language for an obsolete platform, make it run on a modern system (without emulation!)… and actually make it useful!

In 1995, I started developing a 6502 Cross Assembler for MS-DOS, in my then favorite languages: PowerBASIC for the bulk of it, and lots of 8086 inline assembly to speed up string operations. I mostly used it for my own C64 projects, and I was very proud of its speed: A fraction of a second to produce several KB of binary code on a 386.

In September 1996, I decided that Turbo Pascal was actually the better language, and converted the source line by line, but keeping all the inline assembly. Development continued until June 1998.

In January 2008, I rediscovered the source and wanted to see whether it could be ported to run on modern computers. I used p2c to convert the Pascal source into C, and spend two days cleaning up the C and rewriting the assembly in C until it correctly compiled my regression test – but the code was still using Pascal strings, for example.

Recently, I dug into my floppy disk collection to recover as many revisions of the source as possible, converted the whole (surviving) history into a git repository, and put it on

The C version of mxass should run on any modern operating system, and it’s actually a useful piece of software, with some unique features. It supports 6502 with illegal opcodes, 65816 and Z80 assembly, and it tries to be backwards compatible with the “64’er” set of assemblers (Hypra-Ass, Giga-Ass, Vis-Ass, Assblaster, F8-Assblaster), in fact, F8-Assblaster source printed to a file in an emulator should assemble with very few changes.

That said, please do not use it for new projects. Use cc65 for that.

What is the oldest source you have written for an obsolete platform that have ported forward to modern systems?

6 thoughts on “Making Obsolete Code Run Again: The mxass 6502 Cross Assembler”

  1. Interesting, I recall evaluating mxass when looking for a crossassembler back in the 90s. I’m afraid it lost out to dasm :)

    I’m a big fan of reevaluating what software I use at least once per decade, but one tool that I still keep around is my two-column binary compare tool I originally wrote in AmigaE back in 1996 or so, and ported to C some time later.

  2. Only small note: If you use FreePascal (included as package in many Linux distributions), you can directly compile to one of maybe 20 platforms or 6 processors including ARM.

  3. Back in the day I owned a Commodore franchise in Vancouver BC called Prominico Industrial Electronics.

    We specialized in writing extensions to Commodore Basic and selling them in the form of UV PROMS that plugged into the extra slots in the original PETS. We sold a Sort Rom, a Visual Disc Manager and a Business extension that included form design using the PET graphics and formatted input among other functions.

    But to get to the point we had to disassemble the roms to work our magic and we were helped by a friend named Bill Syler and his tools. He is best known for porting StarWars to the PET while he worked for Commodore. He came with Chuck Peddle from MOS Tech when it was acquired by CBM.

    In the process we uncovered a bug in the F Multiply routines that I think is still in the source code posted.

    Gates did two neat tricks in the FMulDiv routines first he economized space by re-using parts of the multiply routine for division. A flag set at the beginning direct the flow between Mul and Div. The second was to test if some bytes of the multiplyer mantissa were zero. For each byte that is a zero he performs a byte shift of the accumulator instead of 8 single bit shifts which takes many times longer. Unfortunately if the two middle bytes of the mantissa are both zero the div/mul flag gets flipped and the routine processes the last byte of the mantissa as a Division resulting in an error in the last 2 or so places if I recall correctly.

    The upshot is that there are 65k floating point numbers that multiply incorrectly .

    I asked Bill Gates some years later at Comdex if he was aware of the error and he said no. I’m still not sure if he was amused or annoyed by the question.

    Given that the 5 byte floating point numbers gave about 9 decimal digits of precision the error was of little practical concern. If you were manipulating dollar amounts it would only bite you for very large amounts and most engineering calculations don’t need that degree of precision so I doubt any bridges have collapsed as a result. There were some cases where is become a concern though. If you were using an iterative method to estimate an integral for instance and one of your constants happened to be a bad number, the accumulated error could be significant.

    Anyway just some 6502 BASIC trivia. I did look at the source but without cracking open a 6502 manual to refresh my memory I am not 100% certain that this source contains the error. If anyone cares to look harder I’d be curios to hear the result. I think the problem shows up in the routine labels mulshf where the byte wide shift occurs.

    PS Notice where Bill comments in the source about how the single bit shifts of the accumulator are “;SLOW AS A TURTLE !”. I gather he was quite proud of himself for coming up with the byte wide shift optimization.

  4. Over the past 30+ years I’ve lost a tremendous amount of code I’ve written, mostly to bad drives (and floppies), but some to attrition… I’ve learned to enjoy it. Less stuff to worry about – that nagging feeling that you should get code off that old drive, if only you had the right cable… Not anymore…

    The important code gets re-written or resurrected in other ways, the unimportant code dies quietly.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.