BRANCH NEVER And QUIF Assembling On SuperPET
Richard Mansfield Assistant Editor
Ever hear of QUIF? Or HI, ISUPPER, STOI, FSEEK, TABLELOO, COMA, ORB, PULB, SEX, COMB, or BRA? These are some of the 6809 mnemonics, utilities library macros, and "structured programming" statements available to you when you assemble on the SuperPET. The Waterloo 6809 Assembler permits machine language programming which is somewhat like programming in higher level languages. Along with the Assembler is an Editor, a Linker (to connect modules), and a monitor.
Making the transition to this assembler involves two major adjustments: you are now working with a 6809 and you are using a complicated assembler. If you are accustomed to working with simple assemblers (Supermon, Extramon, Micromon, or others), you will be baffled at first by the requirements of this assembler. Before looking into the significant differences between 6809 and our familiar 6502, let's see what is required if you decide you want to place the letter "a" in the upper left corner of your screen.
Simple 6502 Version: 0360 LDA#$41 0362 STA$8000 0365 BRK Waterloo 6809 Assembler Version: Ida #'a sta $8000 swi end
SWI means software interrupt and resembles BRK on the 6502. (There are three software interrupts available: SWI, SWI2, and SWI3.) The apostrophe allows you to enter the actual letter which will be translated into the correct value for you. Otherwise, it's fairly simple at this point. You are in the Editor here (no need for addresses yet — they will be created later). The creation of your final, "object" code takes several steps: you must save this "file" to disk by typing p (for PUT) name.asm. Then, when the ASM file is on disk, you type BYE to get into the menu and select a (assemble) and you are asked for the filename, so you type: name. (It adds the ".asm" for you.)
The assembler makes two new files on the disk: name.4 st and name.bO9. The first is a fairly straightforward listing of the source code with line numbers, object codes, mnemonics, and any comments separated into appropriate fields on screen. Name.bO9 is a file containing the object code to be used later by the Linker.
Your next step is to return to the Editor and make a fourth file:
"name" org$1000 "name.bO9"
and PUT it to disk under the title "name.cmd." The first line here names the "load module," the second line defines the starting address of the object code, and the third line names the object code file to be used in the linking process.
Then you type BYE again, select Linker from the menu, and type: name. (The linker will add ".cmd" to the name.) The linker creates two more files (for a total of six): name.mod (executable load module) and name.map (tells how name.bO9 was mapped into name.mod).
Now you are ready to run your program. You enter the monitor by typing "M" from the menu and then type: 1 name.mod (to load the "module"). You can then type : g 1000 and, voila!, an "a" appears on your screen.
The Monitor And Linker
Like TIM (the resident monitor on PET/CBM computers) the SuperPET monitor has several commands which are useful for debugging (Bank, Clear, Dump, Fill, Go, Modify, Passthrough, Quit, Registers, Stop, and Translate). "Bank" allows you to access any of the 16 banks of upper RAM for reading or writing. "Stop" sets breakpoints and "Clear" clears them. "Dump" is equivalent to "M" on TIM. "Modify" permits the same changes as "Dump," but in the form M ff 12 33 (where the byte at $OOff now becomes $12, $0100 becomes $33). "Quit" is like TIM's "x." "Passthrough" sends all input to a host computer and permits all output from the host to appear on screen.
"Translate" is a disassembly. Curiously, there is no provision for single-stepping or for SAVEing from the monitor. A single-step program exists (it was used at Waterloo to create the SuperPET languages), but it was not included in the monitor. As for SAVE, it was planned, evidently, that modules should be only created from the upper levels of the development system, following the steps outlined above which result in six files per module. The linker knits the relocatable object modules (name.bO9) into longer executable load modules. The linker is invoked by creating the name.cmd file mentioned above and including various commands in this file. "Org" specifies the desired starting address for the code. "Banksize" defaults to $1000 if not specified and "Bankorg" defaults to $9000. Programs or modules may be loaded into specified banks with the "Bank" command. To merge external routines from the system library (or from your personal library of modules), use the "Include" command. Finally, "Export" sets aside some memory (Export bytespace = $7b00) which is named "bytespace" and reserved for tables, etc. Following its definition, "bytespace" can be referenced by any routine using the statement: xref bytespace.
The 6809
As Figure 1 illustrates, the most obvious novelties in the 6809 are the addition of Accumulator B, the second (User) Stack, a Direct Page register, and half-carry, fast IRQ, and Entire State Saved condition flags. In addition, of course, the Y, X, and Accumulator registers and the stack pointers are expanded to 16 bits. Some of these improvements facilitate simplified addressing since a 16 bit register can address an entire 64K. Likewise, a stack can now be located anywhere in memory and be of any size desired. The A and B Accumulators can be concatenated to form Accumulator D (A is the MSB). This allows 16 bit addition, subtraction, compare, and so forth, via a single mnemonic.
The S stack pointer is used for JSRs and interrupts as expected, but the U stack pointer is controlled completely by the user and is unaffected by hardware status. This permits variables to be passed between routines.
The direct page register (normally 0) is used to form the MSB of an effective address during "direct addressing." The offset is the byte following the direct addressing mode opcode. This is like the familiar zero page addressing, but with the added ability to set "zero" at any page. A half-carry is a carry from bit three during eight-bit addition. There is a fast interrupt request line which can be masked with the fast IRQ flag. The entire-state-saved flag signals that all registers (not simply the program counter and CC) have been saved on the stack.
Figure 1.Branch Never: Addressing and New Instructions
In addition to the familiar 6502 modes, the 6809 includes "Direct" addressing, "Long Relative" (16 bit relative, position independent), and various indexed and indirect modes including auto-increment and decrement by one or two bytes at a time. The efficiency inherent in 16 bit manipulations, new addressing modes, and new instructions permits greater programming freedom than is possible on the 6502. For example, the 6502 has approximately 56 mnemonics where the 6809 has nearly twice as many. (Mnemonic counts will vary depending on whether such instructions as ROL and ROL Accumulator are counted as distinct instructions.)
Among the more interesting new instructions is SWI (the entire machine state is saved and control is transferred through the vector at $FFFA-B. SWI2 is the same except that the IRQ masks flags are not set and the vector is $FFFA4-5). SEX means sign extended. BRA is branch always. Perhaps the most enigmatic new instruction is BRN, Branch Never. Though hundreds of uses for this spring to mind immediately, the assembler manual suggests that it can be used if you should become tired of NOP.
MUL multiplies accumulators A and B (unsigned) and stores the result in the D (A + B) accumulator. COMA and COMB complement these accumulators. ORB P inclusive ORs the value addressed by P, with B.
Assembler Expressions
The assembler provides for extensive programming options through lables, external references, libraries, macros, operators, conditional assembly, etc. QUIF? It's Quit IF, one of the structured programming statements. HI is a condition which follows QUIF and is true if the carry and zero flags are both clear. Other statements are: IF, ENDIF, ELSE, GUESS, ADMIT, ENDGUESS, LOOP, ENDLOOP, and UNTIL. Like their counterparts in other languages, these statements can be used in the assembler, if that is your preference.
Also, a library of common routines is included and can be called into a program by typing the reference name followed b> an "underbar" character, an underline which is created by hitting the back-arrow key. ISDELIM checks to see if the character in question is a delimiter (not alphabetic or numeric). STOI converts a decimal string to an integer. ISUPPER sees if you have an uppercase alphabetic character. FSEEK finds a record in a random file. In all, there are 67 library modules. The first parameter is passed on D, the rest on the stack. Results come back in D.
The "structured programming" statements, 100 mnemonics, 67 library names, 17 addressing modes, 96K, two stacks, 16 memory banks. It's a bit of a transition. Nevertheless, 16 bit addressing, the freedom to MUL at will, and numerous other advantages all combine to make the 6809 option on the SuperPET exciting and promising for machine language programming.