(back to project list)

ProSel-8 Utility Disassembly

Glen Bredon wrote several Apple II utilities, including the Merlin assembler, DOS Master, ProSel-8, and ProSel-16.

I took a look at one of the ProSel-8 utilities, Cat.Doctor. It does some fairly complex shuffling when it starts up, so I did a quick disassembly to evaluate the updated address region code in SourceGen v1.8. I haven't done much in terms of explaining what the bulk of the code does, but it's a good starting point for anybody who wants to dig in. This is not a finished disassembly project.

The code uses inline data for ProDOS-8 calls, SmartPort calls, and string formatting (high-ASCII null-terminated strings with embedded HTAB values). The latter is likely common to the various ProSel-8 utilities, so I wrote a script to handle it.

ProSel-8 is copyright 1990 Glen Bredon.


CAT.DOCTOR / CD.EXT memory map

The Cat.Doctor.Combo data file is a concatentation of CAT.DOCTOR and CD.EXT. The former is the executable, the latter is a code overlay loaded by the main program when it first launches. Calls are made in both directions, so it's easiest to work with them in a single binary.

If CD.EXT can't be loaded, or auxillary memory isn't available, the features implemented by it aren't available from the menu.

Here's the address map summary from the project, which shows how sections of the file are arranged in memory:

+000000  +- start
+000000  | +- start
         | |  $2000 - $2002  length=3 ($0003)
+000003  | | +- start 'LBE80'  pre='src_2003'
         | | |  $be80 - $beff  length=128 ($0080)
+000082  | | +- end
         | | 
         | |  $2083 - $21a7  length=293 ($0125)
+0001a8  | | +- start 'LBD00'  pre='src_21a8'
         | | |  $bd00 - $bd16  length=23 ($0017)
+0001be  | | +- end
         | | 
         | |  $21bf - $2226  length=104 ($0068)
+000226  | +- end
         | 
+000227  | +- start 'MainEntry'  pre='src_2227'
         | |  $0800 - $2f75  length=10102 ($2776)
+00299c  | +- end
         | 
+00299d  | +- start 'LBE00'  pre='src_499d'
         | |  $be00 - $be7d  length=126 ($007e)
+002a1a  | +- end
         | 
+002a1b  | +- start 'LD000'  pre='src_4a1b'
         | |  $d000 - $d0fd  length=254 ($00fe)
+002b18  | +- end
         | 
+002b19  | +- start 'unref_d400?'  pre='src_4b19'
         | |  $d400 - $ddf5  length=2550 ($09f6)
+00350e  | +- end
         | 
+00350e  +- end

+00350f  +- start 'L4000'
         |  $4000 - $52ff  length=4864 ($1300)
+00480e  +- end

The map is complicated slightly by the JMP $2083 at the very start, because $2083 appears in two different places: the initialization code, and the relocated main program. The intended target is at +000083 in the init code, but if you just establish a simple list of address regions you create an ambiguous situation. The address at +001aaa is also a viable candidate, so whether or not the disassembly comes out as desired depends on the resolution algorithm.

The ambiguity was resolved here by wrapping the initialization code in a separate address region, from +000000 to +000226. This ensures that the JMP is resolved to the nearby instance.

It looks a little weird in the source file to have two .addrs $2000 pseudo-ops right next to each other. The one that spans the entire CAT.DOCTOR binary is required, though, because we need to establish addresses for the pre-labels. For example, src_499d is at address $499d before the code is relocated, but we wouldn't know that without establishing that the file started at $2000.


Copyright 2021 by Andy McFadden