ASSEMBLER DEBUGGER EDITOR
... all neatly packaged on one chip
IT has taken several weeks to prepare this review of ADE, the
Assembler, Debugger and Editor that comes on a chip. Anything
less would not have done it justice.
The system comes in a box containing a 160 page manual, the
chip, a system utilities and demo disc and instructions on inserting
the eprom.
The manual is well written and produced. It has three major
sections — one each on the Assembler, the Editor and Spy, the
debugger - together with a collection of highly useful appendices
and quick reference guides.
It also contains the formatting commands, a reference for the
6502 instruction set, a programming description of the sideways
ROM format, an operating system summary giving the *FX/OSBYTE
calls, the other OS calls and the vectors and a summary of the
VDU codes.
The final appendix describes the software supplied on the system
disc.
The system has a command level from which the component program
may be called, although they can be entered with any ROM in control.
The first part of the manual describes this command level and
the new * commands the chip provides (see Table I).
|
*ADE
|
Selects the ADE chip.
|
|
*ASM
|
Invokes the assembler.
|
|
*BRK
|
Enables breakpoints; when a BREAK code is met by the 6502,
the debugger Spy is entered automatically.
|
|
*CTRLF
|
While entering data from the keyboard, CTRL+F will put
you into Spy.
|
|
*EDIT
|
Enters the editor.
|
|
*FX100
|
To enter Spy either from a user program or command level.
|
|
*HELP ADE
|
Prints the version number and this list of commands.
|
|
*LST
|
Invokes the Spy disassembler.
|
|
*MODE
|
Changes the screen mode.
|
|
*NOBRK
|
Reverse of the *BRK command.
|
|
*NOCTRLF
|
Reverses the *CTRLF command.
|
|
*SPY
|
Enters the debugger.
|
Table I: ADE * commands
In command mode the asterisk is supplied for you as the prompt.
The assembler uses the standard mnemonics and forms of addressing
— these are the same as the assembler in Basic. But as it doesn't
have Basic to do the arithmetic and set up the labels - as Basic
variables - there are some differences.
With the built in assembler, the labels can be of any length
up to 255 characters, and all the characters will be taken into
account. In the ADE assembler, the labels may be of any length
— you can imagine why I haven't checked this — but only the first
six characters are kept. The first character need not be a period.
Thus two labels with the same first six characters will be taken
to be the same. I think this is an unfortunate restriction, but
you do get used to it.
Using the built-in assembler, to pass an address to an OS routine
through the X and Y registers requires the code:
LDX#ADDR MOD 256
LDY#ADDR DIV 256
in the ADE assembler it is much simpler:
LDX#>ADDR
LDY#<ADDR
Also instead of using P% to represent the first byte of the
current instruction in an operand you use * instead. Apart from
that, unlike the Basic assembler, the arithmetic which can be
used in an operand does not allow:
LDX#ATN(PI*0.5)
instead of:
LDX#1
but it does allow an unusual number of operators (see Table
II). More in fact than many mainframe assemblers, and it seems
very unlikely that a programmer will find himself short.
|
+
|
Addition
|
|
—
|
Subtraction
|
|
*
|
Multiplication (as well as current address)
|
|
/
|
Division (Basic DIV)
|
|
£
|
Modulus (Basic MOD)
|
|
&
|
Bitwise AND (Basic AND)
|
|
;
|
Bitwise OR (Basic OR)
|
|
=
|
Logical equals with true being -1 and false 0 as in Basic
|
|
>
|
Logical greater than (as well as lsb)
|
|
<
|
Logical less than (as well as msb)
|
|
~
|
Bitwise NOT (1's complement)
|
|
—
|
Unary minus (two's complement)
|
Table II: Assembler arithmetic operators
In operands, numbers are taken to be decimal unless they are
prefixed with an & or a $, when they are taken to be hexadecimal.
As well as this you can use binary numbers by prefixing them with
a %, which can save hard-to-trace errors in setting VIA or ACIA
registers.
|
Decimal numbers
|
0 to 65535
|
|
Hexadecimal numbers
|
& or $ followed by up to 4 hex digits
|
|
Binary numbers
|
% followed by up to 16 0s or 1s
|
|
Ascii character
|
Apostrophe, followed by a printing character followed by
an optional apostrophe
|
Table III: Assembler constants
The various fields of an instruction will normally be separated
by a TAB character which both the assembler and the editor interpret
with the tab stops being spaced at eight column intervals.
As it is only one character, rather than several spaces as in
the Basic assembler, a considerable amount of space in the source
file can be saved compared to the same file, as neatly formatted,
in Basic.
Comments can be started in a number of ways. A * in the column
denotes a line which is pure comment and either a semicolon or
a backslash can be used to denote a comment field at the end of
an instruction line.
Both the semicolon and the backslash can also be used, instead
of *, in column 1 to start a comment line, which makes converting
Basic programs to ADE format much easier.
There are also a set of pseudo-ops to set the origin, create
constants and so on.
Basic II allows the use of EQUB, EQUW, EQUD and EQUS to create
bytes, 16 bit words, 32 bit words and strings.
This has always seemed a strange choice as traditionally EQU
has been used to set a constant value like the address of OSWRCH.
In this assembler rather more usual forms have been used (see
Table IV).
|
ORG
|
Set the address where the first byte of code will be.
|
|
EXEC
|
Set the execution address for the code.
|
|
EQU
|
Assigns a value to its label, like OSWRCH EQU &FFEE.
|
|
LST
|
Used to turn listing on and off during assembly.
|
|
TTL
|
Causes a title to be printed at the top of each page of
listing.
|
|
ASC
|
Defines a string, ¦ may be used to put control characters
into the string and ~ may be used to set bit 7 of the following
character.
|
|
STR
|
As ASC but the string has a carriage return added to the
end (MOS likes it).
|
|
DFB
|
Create a byte constant. Unlike EQUB more than one may be
defined in a line.
|
|
DW
|
Create a 16 bit word constant. Again, more than one may
be defined on a line.
|
|
DDB
|
Create a 16 bit constant but with the most significant
byte first, contrary to normal 6502 practice.
|
|
DS
|
Used to allocate 1 or more bytes for a buffer (for instance).
|
|
HEX
|
Create a byte constant like DFB but all the numbers are
assumed, by default, to be hex.
|
Table IV: Assembler pseudo-ops
The pseudo-op DS, though it is intended to reserve space which
is initially empty - that is, filled with garbage - will actually
be filled with zero bytes.
This comes from the DFS only being able to load programs consisting
of a contiguous sequence of bytes. There is no provision for holes.
There is a useful assembler directive DSECT, which allows addresses
to be allocated in a region of memory separated from the main
code, thus helping to overcome the no-hole difficulty.
For instance, to define zero-page usage for a program you could
write:
DSECT
ORG &70
PTR DS 2
BUFPTR DS 2
COUNT DS 1
DEND
which defines a general (scratch) pointer address in &70
and &71, a pointer into the buffer in &72 and &73
and a count in &74. Within a DSECT DS doesn't create zero
bytes and won't cause problems.
One of the most extraordinary things about this assembler is
that it contains both conditional assembly and macros.
Conditional assembly allows the assembler to test a condition
while it is assembling the program and, depending on whether the
condition is true or false, assemble a part of the program, or
not.
In fact it has an IF, THEN and ELSE structure so a test can
assemble one or other of two bits of code depending on one condition.
To assemble a common piece of code for either the BBC Model
A or B, the definition of top of memory addresses could be made
conditional on whether a symbol called MODEL had been set to A
or B.
The value would be set at the top of the program. To assemble
a Model A version of the program it would be set to A. Anything
else in the program which was model dependent - such as timing
-could use conditional assembly to choose either VIA timing or
a code loop.
Connected with this is a QUERY directive, which allows an even
more immediate control of the assembly. The value of the label
on the QUERY directive is assigned a value which is typed in in
response to a prompt during pass 1 of the assembly.
Macros allow the programmer to code frequently used chunks of
code once only and then, by using the macro name as an instruction,
to get the code inserted in the assembly without any copying errors.
For instance, incrementing a 16 bit location is a piece of code
which may be used several times in different parts of a program.
The macro — given in the manual as an example - which replaces
all these separate copies of the same code is:
INCW MACRO
INC @1
BNE .INCW
INC @I + 1
.INCW
ENDM
The operand @ 1 represents the macro parameter and the code
will be generated differently, depending on whether it is a location
in zero page or an absolute address. A macro can have up to nine
parameters.
A useful library of macros is given on the system disc and a
LIBRARY program is included. So the macro library can be updated
to contain your own favourites.
The editor is all things to all men. If you prefer to enter
commands like "Move n characters" or "Delete n
lines" you can, because almost all the commands may be entered
either by using the function or cursor keys or as commands.
A printed function key slip is provided for use with the editor.
Apart from the cursor keys and commands to move, delete and copy
blocks of marked text, this is all you need. It is easy to use,
and in my opinion is better than the Wordwise editor.
It is not possible to include here a list of the functions available
with the editor. Suffice to say that with about 60 editing commands,
eight file commands and about 20 formatting commands, no one will
find the editor restrictive.
It starts in insert mode where every character typed pushes
the character underneath the cursor to the right to give itself
room.
You can change to overwrite mode if you find it more convenient
and toggle back and forth as needed.
There are commands (or function keys) to go to the start of
the text or to the end and to go forward or back a page or word.
At first the method of getting from one line to the next seems
odd. Up cursor sends it to the start of the current line and you
either have to use back cursor to get to the end of the previous
line or up cursor again and forward cursor. You can't go from
a character on one line directly to the character above or below
it.
Pressing back arrow while at the beginning of a line sends the
cursor to the end of the previous line.
You can delete lines, words or characters with a function key
and insert lines as well.
As part of the formatting function, to activate printer functions
you can enter control characters into the text by pressing a function
key and then entering a character from A to Z, plus the five characters
after Z to underscore.
But as CTRL-@ (NUL) is not permitted, owners of MX-80s will
find that they cannot turn off underline.
The formatter does not have all the commands that Wordwise or
View have - they boast a whole ROM to themselves — but it is sufficiently
versatile to have produced the manual accompanying ADE.
As well as the commands to fill and justify, leave unjustified,
indent, centre and so on, it also has a command to align text
down the right margin which does not appear in either Wordwise
or View.
But it doesn't have any commands to set up headers or footers.
Nor does it appear to have any means of printing the page number,
though the pages are counted.
The filing commands allow the editor to be entered before a
file is read in to edit. This also allows one file to be appended
or inserted in another file. The normal way of using the editor,
however, is to enter it with: *EDIT filename which will do an
automatic backup of the file.
When the edit is complete the original file is renamed to directory
B (for backup) and the newly edited version is given 'filename'.
So at all times you have the old version of the file safe in case
something happens to the new version.
No longer do you have to remember to write the file to a new
name every time you save it. It's all done for you and you can
get on with designing the pounds while it looks after the pennies.
The section on the editor ends with two pages of error messages,
what they mean and what action to take.
The debugger, Spy, is normally entered by the command *SPY.
But it may also be entered from programs by using *FX100 - or
the equivalent OSBYTE form - or typing a CTRL-F when the program
is waiting for input.
On entry the contents of all the registers, including the program
counter (PC), the stack pointer (SP) and 64 bytes of memory are
displayed on the screen with the registers in a column on the
top left and the 64 bytes of memory in the middle.
Below this there are four lines, which scroll separately, for
command entry. For the SP and PC registers the contents of the
eight bytes before and after the address is also displayed.
The memory block is in lines of eight bytes preceded by the
address of the first byte of each line. The address of the fourth
line is picked out as the current address and the byte it addresses
can be given a new value simply by entering the value and pressing
Return (see Table V).
|
TAB
|
Toggle display between Ascii and hex.
|
|
L
|
Toggle display between disassembled instructions and hex.
|
|
M
|
Set current address (as 1900M to set it to &1900).
|
|
RETURN
|
Advance current address by 1.
|
|
+
|
Advance current address by 8 (; also serves).
|
|
/
|
Take current address back 1.
|
|
-
|
Take current address back 8.
|
|
U
|
Change current address to the same as PC.
|
|
@
|
Change PC to be the same as the current address.
|
|
I
|
Set the current address to the address pointed to.
|
|
R
|
Set the current address to the (relative) address in a
branch instruction.
|
|
G
|
Search for byte pattern.
|
|
N
|
Search for the next occurrence of the byte pattern.
|
|
hex
|
Change the byte pointed to by the current address to hex.
|
|
"
|
Type characters into memory starting at the current address.
|
|
P
|
Fill and test memory block.
|
|
S
|
Shift memory block.
|
|
V
|
Verify two blocks of memory.
|
|
.
|
Make the next displayed register the current register.
|
|
hex.
|
Alter the contents of the current register to hex.
|
|
Z
|
Execute the instruction pointed at by PC and stop (single
step).
|
|
J
|
Jump to the given address and execute the routine (using
JSR and Return).
|
|
K
|
Continue program execution from PC.
|
Table V: Spy commands
The memory display can be toggled between Ascii and hexadecimal,
and between hexadecimal and disassembled instructions at the touch
of a key.
Further instructions allow the current address to be changed
and also move it forwards or backwards one location or in steps
of eight.
The contents of any register may be changed by moving the current
register pointer (the . command) and entering a new number followed
by a period. The program counter may be altered to the current
address, and contrariwise, the current address may be set to the
contents of the PC.
The debugger performs admirably. To set breakpoints you have
to set the first byte of the instruction to &00 yourself and,
to continue, you have to change it back again afterwards.
I would have preferred this to have been automatic, but in practice
it was no great obstacle.
I would also have liked to see a way of skipping across JSRs
while single stepping, but this again can be done by setting a
breakpoint the other side of the JSR.
The utility disc contains the source of the macro librarian,
the macro library, a demo of the system and of the formatter used
in the editor. The librarian and macro library are also in object
code.
The librarian is used to create, alter or update any macro library,
not only SYSLIB on the disc.
The source code of all four programs can serve as a tutorial
in advanced assembler programming for the BBC Micro and in the
use of the system.
There is also a demo program which simulates keyboard entry
into the system, showing some of the commands and their effects.
To conclude, it is impossible to describe the ADE system adequately
in the space of a review. I can only hope to give the reader enough
information to decide whether or not it will be of use.
After having used it intensively for several weeks, I would
say that if you frequently write programs of 50 or more lines
of assembler and your piggy bank will stand it, then buy this
excellent system.