Disassembling Machine Language Programs Without Leaving BASIC
John R. Vokey and H. Cem Kaner McMaster University Hamilton, Canada
One of the nice features of the Apple computer is that it has a built in mini-assembler and disassembler. The mini-assembler is all you need for entry of short machine language programs. In fact, for short programs, this free piece of software has proven more flexible and less error prone than two of the "full blown" assemblers we have purchased. The disassembler is useful for programs of any length. If you have a machine language program in memory, the disassembler will translate the program's code from meaningless hexadecimal numbers into an assembly language listing. The listing includes no labels, just instructions and addresses, but this is still quite informative. It is not too hard, for example, to decode fairly large sections of the code underlying Applesoft from such listings.
The standard approach to using the mini-assembler and disassembler is to jump into the monitor (via CALL -151 from either BASIC) and to work from there. These steps are well described in your Apple II Reference Manual. However, it is also possible to access some of these monitor commands from BASIC. The one line Applesoft program below allows you to disassemble machine code anywhere in memory without ever leaving BASIC. This is especially convenient if you are trying to debug a machine language subroutine which will be CALLed from BASIC. You can change the routine using POKEs, examine the changes using this line in your CALLing program, and test the changed version's behavior, all without leaving Applesoft.
The program works by passing the user-specified START location of the code to be disassembled to the monitor program counter (labelled PC in the program). It then calls the monitor LIST subroutine which we label disassemble in the program. This routine disassembles the next 20 lines of machine code, incrementing the monitor program counter locations appropriately, and returns control to BASIC. The BASIC program then compares the value of the monitor program counter to the user specified value FINISH. If there is more to be done before location FINISH is reached, the program waits until you press any key, then continues the listing. Once FINISH is reached, the program ends.
As an example of the use of the program, if you set START to 65118 and set FINISH to 65140, you will disassemble the disassembler.
1000 DISASSEMBLE = 65121: PC = 58: POKE PC, START - INT (START / 256) * 256: POKE PC + 1, START / 256: FOR I = 0 TO 1: HOME: CALL DISASSEMBLE : PRINT : PRINT TAB (13); "<PRESS ANY KEY>" :GET Z$ : I = (PEEK (PC + 1) * 256 + PEEK (PC)) > FINISH: NEXT I