Rom Review

Assembler Debugger Editor
System Software


... 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).


Selects the ADE chip.


Invokes the assembler.


Enables breakpoints; when a BREAK code is met by the 6502, the debugger Spy is entered automatically.


While entering data from the keyboard, CTRL+F will put you into Spy.


Enters the editor.


To enter Spy either from a user program or command level.


Prints the version number and this list of commands.


Invokes the Spy disassembler.


Changes the screen mode.


Reverse of the *BRK command.


Reverses the *CTRLF command.


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:


in the ADE assembler it is much simpler:


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:


instead of:


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.





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).


Set the address where the first byte of code will be.


Set the execution address for the code.


Assigns a value to its label, like OSWRCH EQU &FFEE.


Used to turn listing on and off during assembly.


Causes a title to be printed at the top of each page of listing.


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.


As ASC but the string has a carriage return added to the end (MOS likes it).


Create a byte constant. Unlike EQUB more than one may be defined in a line.


Create a 16 bit word constant. Again, more than one may be defined on a line.


Create a 16 bit constant but with the most significant byte first, contrary to normal 6502 practice.


Used to allocate 1 or more bytes for a buffer (for instance).


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:

ORG &70

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:

INC @1
INC @I + 1

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).


Toggle display between Ascii and hex.


Toggle display between disassembled instructions and hex.


Set current address (as 1900M to set it to &1900).


Advance current address by 1.


Advance current address by 8 (; also serves).


Take current address back 1.


Take current address back 8.


Change current address to the same as PC.


Change PC to be the same as the current address.


Set the current address to the address pointed to.


Set the current address to the (relative) address in a branch instruction.


Search for byte pattern.


Search for the next occurrence of the byte pattern.


Change the byte pointed to by the current address to hex.


Type characters into memory starting at the current address.


Fill and test memory block.


Shift memory block.


Verify two blocks of memory.


Make the next displayed register the current register.


Alter the contents of the current register to hex.


Execute the instruction pointed at by PC and stop (single step).


Jump to the given address and execute the routine (using JSR and Return).


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.