1. Whenever we
learn where things are in the memory map (internal
or external RAM or internal or external device) we
create an
entry in the disassembler control file so that the next time we run the
dasm batch file we'll have an easier to understand english language
name rather than a number.
2. When we figure out how things are working in the code we
can add comments to the commented disassembly file so we'll
remember what was going on the next time we look at this section of
code (or when it happens to be used again - say as a subroutine)
This will be an iterative process until we've figured out the whole
EPROM binary. That's all there is to it !
gecudiss.txt
& gecudctl.txt
The disassembler control file(s) deserves a little extra detail.
The most important thing that happens in the control file is the
creation of
the memory map for the disassembler. In the 1
st
pass of the
disassembler (diss.bat) we don’t know anything about the
system so all that we
have in there is the input and output file names. Have a look at
gecudiss.txt
and here’s what you’ll find:
input gecu.bin
output
gecu.dis
Note that the disassembler uses “;” for its comment
character. If you want to add comment information to the control file
you have
to use the ; character. Everything after the “;” is
ignored.
Control file commands
The following commands, all within the control file, tell
the disassembler information about the binary image it will process.
The more information
that can be determined and supplied here, the better the resulting
disassembly
will be. Optional parameters are enclosed in square [ ] brackets.
| Label
<addr>
<name> |
Assign a label
<name> to address <addr>. |
| Entry
<addr>
[<name>] |
Provide a code entry point
<addr>
with optional label <name>. The code seeking
algorithm
scans
memory for these locations, and automatically adds new entry points as
branch
and call instructions are encountered. When no new entry points are
added in a
single pass, then the disassembler has completed the code seek
phase |
| Indirect
<addr>
[<name> [ <here>]] |
Define a
pointer to to an (indirect) address. An indirect address is a
16 bit quantity (ie. word, or two bytes) that
is used
by the processor to form a target (jump or call) address.
The word at memory address <addr> points to an
address that is
tagged as an entry point, and the optional
<name> is the label
for this address. And finally, <here> will be tagged
as a data word.
The ordering of labels was chosen to maintain compatibility with
existing
disassemblers. |
| Vectors
<addr>
<count> [<name>
[<here>]] |
Define
a range of indirect addresses, as would
be
produced by a jump table, or list of procedure addresses. The number of
data
words (or vectors) is defined by <count>. The optional
<name>,
if supplied, is used to create a label, for each indirect address, of
the form <name>_NN
where
NN starts from 00. The optional <here> is the
address (ie.
<addr>) of the word table. Note that NN is one less than
<count>. |
| Bytes
<addr>
<count> [<name>] |
Define
a
byte table at <addr> of <count>
length. |
| Words
<addr>
<count> [<name>] |
Define
a
word table at <addr> of <count>
length |
Mnemonics
And finally on the
disassembler topic please note the following differences about
the way the Tech
Edge disassembler presents the mnemonics compared to those specified by
Motorola for the processor.
|
DHC11's Mnemonics
|
Motorola's
|
Function Performed
|
|
call
|
JSR
|
Call
|
|
callr
|
BSR
|
Call Relative (short call)
|
|
cmpD, cmpX cmpY
|
CP?
|
Compare (16 bit register)
|
|
decX, decY, decS
|
DE?
|
Decrement (16 bit register)
|
|
di
|
SEI
|
Disable Interrupts
|
|
ei
|
CLI
|
Enable Interrupts
|
| incX, incY, incS |
IN? |
Increment
(16 bit register) |
|
jr
|
BRA
|
Jump Relative (short jump)
|
|
push, pushB, pushX, pushY
|
PSH?
|
Push on to stack
|
|
popA, popB, popX, popY
|
PUL?
|
Pop off stack
|
|
ret
|
RTS
|
Return (from subroutine)
|
|
reti
|
RTI
|
Return From Interrupt
|
|
xorA, xorB
|
EOR?
|
eXclusive Or
|
As you can see, DHC11's
mnemonics use, at most, one extra character, but this makes their
meaning much
clearer, and is closer to a majority of other assembler syntaxes. In
addition,
the mnemonics are displayed in a mixed case that is designed to
highlight the
registers use by the instruction. For example, LDA, the Load A
instruction is
displayed as
ldA
to emphasise that the
A register is used in this
ld
instruction.
The
tAB
and
xgDY
are examples of
instructions that use two registers in the one mnemonic.