Updates:
- 2025-11-20 – Thanks to a comment from Jerry Stratton, I have the start of a disassembly for the “DOS” code which would load at $2600. Article updated with what I have, so far.
- 2025-11-21 – Updating assembly to include the raw bytes that were used.
- 2025-11-21 – Updating the assembly again, using a tool John Linville pointed me to.
- 2025-11-21 – Removing asm from this page and linking to the GitHub link instead.
To this date I still think one of the most useful products Sub-Etha Software ever created was MultiBoot. For CoCo hard drive users of the era, most of us had to boot from a floppy disk. That boot disk would contain the necessary drivers to access the hard drive. With boot files, “one size does not fit all” so most of us had a stack of them — one for running a BBS with serial drivers installed, one with the Sierra Online drivers for playing those games, one with all the graphics drivers for that stuff, etc.
MultiBoot allowed putting multiple boot files on one floppy disk. Type “DOS” and a menu is displayed. Choose the one you want, then that boot file is made active and the process continues.
MultiBoot was written by myself and Sub-Etha co-founder, Terry S. Todd. I wrote the OS-9 frontend in C, and Terry wrote the actual MultiBoot code in RS-DOS assembly. He would then provide that code to me as data, then my C front end program would “install” it by copying it out to the boot sector of the boot disk.
That code looks like this in the MultiBoot source code:
char mb_sec34_1[] = { /* Terry's RS-DOS DOS startup code... 50 bytes */
79,83,134,13,151,211,204,56,0,221,209,12,211,142,0,234,204,2,0,237,132,
134,33,214,211,237,2,220,209,237,4,173,159,192,4,109,6,38,8,76,129,61,37,
221,126,57,0,126,215,9
};
char mb_sec33_15[] = { /* Terry's RS-DOS MultiBoot code V1.12... 512 Bytes */
142,56,0,16,142,38,0,236,129,237,161,140,57,0,37,247,23,1,152,23,1,171,
32,32,32,32,32,32,32,32,77,117,108,116,105,66,111,111,116,32,86,49,46,49,
50,13,32,98,121,32,84,101,114,114,121,32,84,111,100,100,32,38,32,65,108,
108,101,110,32,72,117,102,102,109,97,110,13,32,32,32,32,32,67,111,112,121,
114,105,103,104,116,32,40,67,41,32,49,57,57,51,32,98,121,13,32,32,32,32,
32,32,32,83,117,98,45,69,116,104,97,32,83,111,102,116,119,97,114,101,13,
0,16,142,5,192,16,159,136,23,1,53,32,32,32,32,32,85,115,101,32,85,80,47,
68,79,87,78,32,116,111,32,115,99,114,111,108,108,13,91,69,78,84,69,82,93,
32,83,101,108,101,99,116,115,32,32,32,91,66,82,69,65,75,93,32,81,117,105,
116,115,0,246,58,235,23,1,16,206,4,164,246,58,255,16,39,0,209,240,58,235,
193,8,37,2,198,8,52,20,223,136,189,58,208,53,20,48,136,32,51,200,32,90,
38,238,182,58,234,176,58,235,198,32,61,195,4,163,31,1,134,106,167,132,16,
190,58,253,49,63,38,5,50,98,22,0,151,173,159,160,0,39,241,198,96,231,132,
198,255,129,94,39,17,129,10,39,36,129,13,39,62,129,3,38,197,15,113,126,
140,27,182,58,234,39,187,247,1,85,74,183,58,234,177,58,235,36,3,122,58,
235,22,255,126,182,58,234,76,177,58,255,36,160,247,1,86,183,58,234,182,
58,235,139,7,177,58,234,36,228,124,58,235,32,223,246,58,234,92,141,112,
48,27,52,16,142,0,234,204,2,0,237,132,204,0,1,237,2,204,1,218,237,4,173,
159,192,4,109,6,38,79,16,174,4,49,168,21,53,64,198,5,166,192,167,160,90,
38,249,134,3,167,132,173,159,192,4,109,6,38,50,126,38,2,134,87,183,149,
201,134,16,183,255,34,204,63,0,253,255,188,189,246,82,126,169,40,174,228,
166,128,39,6,173,159,160,2,32,246,175,228,57,166,128,39,251,173,159,160,
2,32,246,126,215,9,142,59,0,93,39,236,48,136,32,90,38,250,57,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,0
};
Are there any 6809 disassembler gurus out there that might take this data and reverse it back into 6809 assembly source code?
Sadly, the only source code from Terry that I have found is that for his MultiBasic product. I cannot even find the master disks for his InfoPatch, and I do not think I ever had sources to ShadowBBS, OS9Term or anything else he wrote.
Thank you for your attention to this matter.
Disassemblies
The “DOS” code would load into memory at &H2600. The first two bytes must be “OS”, and indeed that matches the first two bytes in the data. Per a suggestion from Jerry Stratton, I wrote a program to POKE this data into memory, then used EDTASM Z-BUG to disassemble and do a bit of cleanup.
Where the “??” comment is was something Z-BUG could not decode. There is a value of 2 there. No cluck. BUT, I see a reference to DSKCON (C004) so I am betting if I look up how that works some of this code might make sense.
Help is appreciated!
NOTE: This is now updated using the f9dasm disassembler that John Linville pointed me to:
https://github.com/Arakula/f9dasm
Closer!
DOS Assembly (f9dasm)
https://github.com/allenhuffman/SubEthaSoftware/blob/main/OS-9/MultiBoot/asm/dos.asm
Multiboot Assembly (f9dasm)
https://github.com/allenhuffman/SubEthaSoftware/blob/main/OS-9/MultiBoot/asm/multiboot.asm
Updates
Tim Lindner pointed me to his online javascript disassembler. It did a great job right in the web browser:

Does this make any sense? This is from a quick & dirty disassembler, and it is very likely that I have missed some important steps.
/* Terry’s RS-DOS DOS startup code… 50 bytes */
4F CLRA
53 COMB
86 LDA 0D
97 STA D3
CC LDD 3800
DD STD D1
0C INC D3
8E LDX 00EA
CC LDD 0200
ED STD 84
86 LDA 21
D6 LDB D3
ED STD 02
DC LDD D1
ED STD 04
AD JSR 9F
C0 SUBB 04
6D TST 06
26 BNE 08
4C INCA
81 SUBA 3D
25 BCS 00
DD STD 7E
39 RTS
00 NEG 7E
D7 STB 09
/* Terry’s RS-DOS MultiBoot code V1.12… 512 Bytes */
8E LDX 3800
108E LDY 2600
EC LDD 81
ED STD A1
8C CMPX 3900
25 BCS F7
17 LBSR 0198
17 LBSR 01AB
/* At this point it goes into ASCII text; and may even have gone into it earlier. */
Hey, thanks! What did you use to do this? I assume we had disassemblers that ran on the CoCo “back in the day”, so there must be some modern ones that run on PC/Mac/Linux today?
Let me see if I can make something built. The “DOS” startup code is probably the stuff that loads when you type “DOS” in Disk BASIC. If I recall, it must start with the characters “O” and “S”. Uppercase “O” is 0x4F, and uppercase “S” is 0x53, which matches the CLRA and CLRB op codes in the disassembly (thank you for including the actual bytes or I would have not been able to recognize that).
I seem to recall that his “DOS” code would have a menu system so I expect there to be calls to the CHROUT ROM routine (A000? A002? indirect jump) and keyboard input to select a menu option (so I guess both should appear somewhere). Once selected, I think it then rewrote sector 0 (LSN0 for OS-9) to point to that boot file. There must be some calls to ROM routines that read disk sectors and write them back as well.
Off we go…
I used Lance Leventhal’s table in the back of his Assembly Language Programming to write a Perl script to take comma-delimited numbers and try to turn them into assembly. Once data starts, however, it will produce gibberish, and if data is interweaved with code, it can’t know when that needs to start. Or if I can, it is beyond my current ability.
JSR 9F?
“THIS ROUTINE PICKS UP THE NEXT INPUT CHARACTER FROM BASIC. THE ADDRESS OF THE NEXT BASIC BYTE TO BE INTERPRETED IS STORED AT CHARAD.”
I know Terry had really gotten deep into the ROM disassemblies, and had all kinds of POKEs and EXECs he’d show me to do things. There is no telling where this is going to go . . .
The stuff starting with NEG $86 looks like there’s an extra NUL byte in the code you disassembled. The $86 in NEG $86 would be “LDA immediate”. The $ED in “ADDD $ED” combined with the mysterious $02 would be “STD 2,x”. You may have additional extra or corrupted bytes in your code stream starting at L2630.
Z-BUG did that. Using the tool John Linville pointed me to did a much better job, once I learned how to massage the output a bit. I am updating the post right now.
Same bytes ran through f9dasm worked much better, correctly getting the STD 2,X that Z-BUG misinterpreted (as did the perl tool). Whatever they think it is, they both agree.
Finding out the ORG address is proving tricky on the second part. I know the first code is for the “DOS” track so it has to load at $2600. But now I need to figure out how we did this – DOS would have had to run “our” front end code, and that code took care of swapping out the boot file LSN0 entries based on reading the info from some spot on the disk.
Fun.
F9DASM – 6800/6801/6802/6803/6808/6809 / 6301/6303/6309 Disassembler
https://github.com/Arakula/f9dasm
That tools works great for this sort of thing. You should give it a try!
Thanks, John! I’m off to check it out now…
Wow, this is a heck of a tool. Thank you so much.
f9dasm is very cool, especially with the “info” file. But it seems to make up op codes. Is DEY a thing? Pseudo op like FCS or something? It made these two entries:
LDY M3AFD ;3A04: 10 BE 3A FD '..:.'
Z3A08 DEY ;3A08: 31 3F '1?'
BNE Z3A11 ;3A0A: 26 05 '&.'
LEAX -$05,X ;3A6D: 30 1B '0.'
PSHX ;3A6F: 34 10 '4.'
LDX #DCOPC ;3A71: 8E 00 EA '...'
I know my 6809 knowledge is very basic, but PSHX does not seem to be a thing, either?