5

I've been doing some hobby work reverse-engineering vintage synthesizer ROMs from the early 80s, and I'm curious about what kind of development tools the original engineers may have used. Normally this would be a bit too vague of a question, but I have a few interesting clues.

One of the ROMs I've disassembled is the Yamaha DX9 (Available here). This device features a Hitachi 6303 CPU. This ROM contains some interesting 'junk' left over from the development process, including fragments of what appears to be a symbol table, and some code for another system (Possibly the development system). These fragments appear in conspicuous places, such as at the end of a string table, and between the top of the code, and the vector table at the top of the address space.

Each entry in the symbol table consists of a "`" character (ASCII 0x60, backtick)) followed by a 6 character label, a 16-bit offset, and a terminating '0'. At first I didn't recognize the significance of the strings, but then noticed that the labels actually describe the code pointed to by the offset. So it's very clearly a symbol table. The attached screenshot shows a fragment of the symbol table (with my own added labels substituted for the offsets they correspond to).

A screenshot of the junk symbol data in a disassembler

Here's a view of the binary data for one of these entries.

Binary view of one of the symbol entries

The 2-byte offset following the CERR$ label is 0xC7A3. At offset 0xC7A3 in the ROM address space (not the ROM binary itself. The ROM is loaded at offset 0xC000 into the memory space) is the null-terminated for a MIDI checksum error, as illustrated by the following screenshot.

Screenshot of the destination pointed to by a symbol's offset

I've looked through all the contemporary Motorola 680x development tool manuals I can find on bitsavers.org, including the material for the Motorola EXORciser. All of their assemblers have the same limitation of 6 character labels, but I can't find anything indicating they produce a symbol table output in this format. The Motorola 680x assembler even mentions an 8-byte symbol table entry, whereas this is clearly 10-bytes.

There's a big block of 680x code left over in the binary (Starting around 0xC84D in the address space) that appears to be for another device, as the RAM addresses used don't correspond to the address space in the DX9. It looks like they reference RAM in the 0x4000-0x6000 range, which doesn't really correspond with any of the development systems I can find documented like the EXORciser, or any in-memory monitor.

If anyone has any insight they could share which could help me identify what development tools might have been used, I'd really appreciate it.

8
  • These blocks might as well be remainders in the PC's memory when the hex or binary file for the ROM was generated. Can one base assumptions on that? -- Why specifically is the tool relevant for you? Machine code can be generated by any assembler. Oct 13, 2023 at 6:11
  • Yes, that's exactly what I imagine they are. Based upon the name/offset combination, they're clearly some kind of artifact of the assembly process. I can't really say for sure what it is, but it does resemble a symbol table. I figured I'd ask in case this jumped out to anyone. I'm just interested in understanding more about the development process of these vintage synths.
    – ajxs
    Oct 13, 2023 at 7:29
  • Do you have access to any service manuals for the unit in question? There might be that a service technician could connect with a serial cable and get inforamtion from the unit. Some programmers could make a suprisingly advaned debug tool in just a couple of kiBi of ROM.
    – UncleBod
    Oct 13, 2023 at 8:17
  • 1
    The 0x60 may also be the type of the entry in the table, or some other information about the entry, and not an actual backtick. Are any of those development tools still available as binaries somewhere? One way to find out would be to run them in some emulator, let them assemble something, and examine the memory.
    – dirkt
    Oct 13, 2023 at 8:24
  • The development process as such does not really depend on the tool they used. A development process always starts with requirements, architecture, design, and ends with tests (in what form ever). The tool comes into play only in the left out phase in between, the implementation. And I think that any assembler can be used for the same process. You might want to clarify what your goal or your target is. For me it is perfectly OK to be curious about the tool, but "process" is a misleading term here, I think. Oct 13, 2023 at 9:11

1 Answer 1

2

I think you may be misunderstanding the differing levels at which these things exist.

A symbol table for an assembler (the "assembler" level) would not usually make its way into the code in any way, it's purely something needed during the assembling phase so that the assembler can properly encode instructions that use the labels. After that, it's no longer useful except possibly for debugging purposes (but, in that case, it still wouldn't be needed in the code itself, more likely being in a separate map file).

The table in your question looks more like what you would simply do at the "application" (1) level with some pseudo-ops to define strings and integral values (such as with the fcc/fdd/fdb pseudo-ops).

The character data generated with fcc would almost certainly not have the same limits as per the assembler labels, since you would want to use it for much larger strings such as:

"Disk is loading..."
"Please insert cassette and press PLAY followed by ENTER."
"+----------+"

The fact that your disassembler tool generates labels larger than six characters (like str_Cflash) in no way affects the code that was the original source that created the machine code.


(1) Keep in mind that, when I say application level, I mean the thing being created by the assembler, rather than the assembler itself. In this context, that also means the ROM code, not just an application written by a user to run using that ROM code.

Whoever wrote the ROM code may well have used an assembler with a six-character label limit but that does not apply to the strings they can use for their own "labels" (that you see the disassembly for).

By way of example, the following (pseudo-)assembler code may have such a limit but it constructs an application table with no such limit:

; Translate error codes to text.
; Format is code, text, zero-terminator.
; Code of zero marks end of table.
; Idea is same for any table, including one which maps
; CERR$ to str_MidiCsumErr :-)

table:   db 1, "Out of memory", 0
         db 2, "Cannot open file", 0
         db 0

So the assembler label table may need to be restricted to six characters or less, but the "symbol table" at application level would not have that restriction on its string values.

In other words, the limit is a property of the assembler, not the code you're writing with the assembler (including the ROM).


And, in the event they are simply stuff left lying around in memory (the real symbol table from the assembler), there's a good chance a company like Yamaha may have had their own in-house one or used one that hasn't survived any of the great software purges that have happened :-)

I consider it unlikely (but can't say for certain) since it would probably mean either:

  • they developed on the system they were deploying to (rather than cross-compilation); or
  • there was leakage from their development system into the ROMS they were creating.
3
  • 2
    I've been calling this a symbol table because the 2-byte offset following the 6-character label is clearly an offset into the fully assembled ROM address space. If this was indeed something done at the application level, I wouldn't expect to see that. Maybe the fact that the screenshot shows a reference to my labels, rather than the original offsets into the ROM address space, has confused things. These strings are not referenced in the code, and they clearly correspond to the offsets. CERR$ points to the MIDI checksum error string. CHKSUM points to the checksum remainder byte.
    – ajxs
    Oct 13, 2023 at 7:34
  • 1
    @ajxs: that comment doesn't really change things. I'll clarify the answer.
    – paxdiablo
    Oct 13, 2023 at 9:47
  • 3
    I think it’s fairly common for runtime detritus to end up in otherwise-unoccupied space in assembler outputs in that era; with limited memory and limited processing comes the reuse of buffers, without the expenditure of clearing them first.
    – Tommy
    Oct 13, 2023 at 13:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .