acdasm
acdasm is the AppleCommander disassembler. It is embedded within the AppleCommander application as well as the acx tool. However, the dedicated tool has more control over its capabilities. The downloads can be found at the acdasm project.
$ acdasm --help
Usage: acdasm [-hV] [--debug] [--[no-]descriptions] [--[no-]labels]
[-a=<startAddress>] [-n=<length>] [--offset=<offset>]
[-l=<library>[,<library>...]]... [--codefile | --6502s | --65c02
| --6502x | --sweet16 | --pcode | --6502 | --z80] <file>
AppleCommander Disassembler.
<file> File to disassemble.
Options:
-a, --addr, --origin=<startAddress>
Set start address for application.
--debug Print stack traces
--[no-]descriptions Include opcode descriptions.
-h, --help Show this help message and exit.
-l, --library=<library>[,<library>...]
Select which library labels to load. Each CPU has
a default set. Use 'All' to select all. 'None'
may also be used to turn library labels off.
--[no-]labels Show or hide labels.
-n, --length=<length> Disassembly length bytes.
--offset=<offset> Skip offset bytes into binary before disassembling.
-V, --version Print version information and exit.
CPU Selection:
--6502 MOS 6502.
--6502s, --6502S MOS 6502 with SWEET16 switching.
--6502x, --6502X MOS 6502 + 'illegal' instructions.
--65c02, --65C02 WDC 65C02.
--codefile, --CODEFILE Apple Pascal CODEFILE
--pcode, --PCODE Apple Pascal p-code
--sweet16, --SWEET16 SWEET16.
--z80, --Z80 Zilog Z80.
Processor Defaults:
Default Value 6502 6502X 6502S 65C02 SWEET-16 Z80 P-CODE
--------------------- ----- ----- ----- ----- -------- ----- ------
Start Address $0300 $0300 $0300 $0300 $0300 0100H $0000
Library Labels All All All All All None None
Max Bytes/Instruction 3 3 3 3 3 5 8
Show Descriptions? No No No No No No Yes
Library Groups:
F800, Applesoft, ProDOS, DOS, DISKII, Softswitches
Sample runs:
$ acdasm --6502 --addr 0x2a0 COPY.OBJ0.bin
02A0- AD D8 03 LDA $03D8
02A3- 85 3D STA A1H
02A5- A9 68 LDA #$68
02A7- 85 3C STA A1L
02A9- AD D0 02 LDA L02D0
02AC- A0 00 LDY #$00
02AE- 91 3C STA (A1L),Y
02B0- C8 INY
02B1- C8 INY
02B2- AD CE 02 LDA L02CE
...
$ acdasm --Z80 DUMP.COM.bin
0100- 21 00 00 LD HL,0000H
0103- 39 ADD HL,SP
0104- 22 15 02 LD (L0215),HL
0107- 31 57 02 LD SP,0257H
010A- CD C1 01 CALL L01C1
010D- FE FF CP A,FFH
010F- C2 1B 01 JP NZ,L011B
0112- 11 F3 01 LD DE,01F3H
0115- CD 9C 01 CALL L019C
0118- C3 51 01 JP L0151
...
The 6502/SWEET16 switching mode will switch to SWEET16 mode if a JSR $F689 occurs in code and switch back to 6502 mode when a SWEET16 RTN instruction is encountered:
$ acdasm --6502s renumber.bin
0300- 20 89 F6 JSR $F689
0303- .SWEET16
0303- 11 CA 00 SET R1,#$00CA
0306- 61 LDD @R1
0307- 31 ST R1
0308- 12 0A 00 SET R2,#$000A
030B- 13 4C 00 SET R3,#$004C
030E- 63 LDD @R3
030F- 33 ST R3
0310- 14 DE 03 SET R4,#$03DE
0313- 21 L0313 LD R1
0314- D3 CPR R3
0315- 03 0E BC L0325
0317- 41 LD @R1
0318- 35 ST R5
0319- 24 LD R4
031A- A2 ADD R2
031B- 34 ST R4
031C- 71 STD @R1
031D- F1 DCR R1
031E- F1 DCR R1
031F- F1 DCR R1
0320- 21 LD R1
0321- A5 ADD R5
0322- 31 ST R1
0323- 01 EE BR L0313
0325- 00 L0325 RTN
0326- .6502
0326- 60 RTS
Labels can also be toggled off:
$ acdasm --sweet16 sw16.sample2.bin
0300- 11 00 0A SET R1,#$0A00
0303- 12 80 0A SET R2,#$0A80
0306- 13 23 00 SET R3,#$0023
0309- 41 L0309 LD @R1
030A- 52 ST @R2
030B- F3 DCR R3
030C- 07 FB BNZ L0309
030E- 00 RTN
Finally, Apple Pascal can be dumped as well. Note that "p-code" expects just p-code up to and including the jump table. The codefile will be more useful:
$ acdasm --codefile HELLOWORLD.CODE.bin
>> Seg #01: FROM=$0200, TO=$0232, N='HELLOWOR', LINKED , T=$0000, M=P_CODE_LSB, Ver=6
> Proc#1, Lex Lvl 0, Enter $0200, Exit $0222, Param 4, Data 0, JTAB=$0224
0200- D7 NOP ; No operation
0201- D7 NOP ; No operation
0202- B6 01 03 LOD 1,3 ; Load intermediate word
0205- A6 0C 48 45 4C 4C 4F 20 LSA 'HELLO WORLD!' ; Load constant string address
020D- 57 4F 52 4C 44 21
0213- D7 NOP ; No operation
0214- 00 SLDC 0 ; Short load one-word constant
0215- CD 00 13 CXP 0,19 ; Call external procedure
0218- 9E 00 IOC ; IO Check (checks IORESULT)
021A- B6 01 03 LOD 1,3 ; Load intermediate word
021D- CD 00 16 CXP 0,22 ; Call external procedure
0220- 9E 00 IOC ; IO Check (checks IORESULT)
0222- C1 00 RBP 0 ; Return from base procedure
... and the same invoking just p-code:
$ acdasm --pcode HELLOWORLD.CODE.bin --offset 0x200 --length 0x24
0200- D7 NOP ; No operation
0201- D7 NOP ; No operation
0202- B6 01 03 LOD 1,3 ; Load intermediate word
0205- A6 0C 48 45 4C 4C 4F 20 LSA 'HELLO WORLD!' ; Load constant string address
020D- 57 4F 52 4C 44 21
0213- D7 NOP ; No operation
0214- 00 SLDC 0 ; Short load one-word constant
0215- CD 00 13 CXP 0,19 ; Call external procedure
0218- 9E 00 IOC ; IO Check (checks IORESULT)
021A- B6 01 03 LOD 1,3 ; Load intermediate word
021D- CD 00 16 CXP 0,22 ; Call external procedure
0220- 9E 00 IOC ; IO Check (checks IORESULT)
0222- C1 00 RBP 0 ; Return from base procedure