Jaap's Psion II Page

ASSEMBLER PAK

for the

PSION
Organiser

A. Starting up B. Main menu C. Some Conventions D. Printer output E. Starting address F. Dump G. Unassem H. Assem I. Step J. Copy K. Patch L. Some applications Appendix A: Standard opcodes (6303X) Appendix B: Specific assembler directives Appendix C: The structure of 6800(6303X) processors Appendix D: Memory map Appendix E: ASCII table


A. Starting up


B. Main menu

After a welcome-screen disappears, we see the

MAIN MENU : Dump Assem Step  Unass Copy Patch

First we give a short explanation for each option which will be discussed in more detail later on.
Most options can send output to a Printer.

Dump:Shows the memory contents, in ASCII and in hexadecimal format. (printer output is possible)
Assem:With the built-in mini-assembler you can create your own machine code : either you key in the source directly with immediate compilation, or you can create a source file and compile it later. Besides the use of standard 6303X mnemonics (6800 compatible), you can use (branch) labels and some specific assembler directives.
Step :Execute your program STEPWISE, and test it by watching the contents of registers, stack and flags. This powerful option offers more debugging capabilities which will be discussed later.
Unass:Disassemble code into readable instructions.
Copy :Copy memory from one place to another
Patch:Change the contents of memory locations.
On/Clear:Stop or return to the previous menu

C. Some conventions

  1. All numbers (addresses, bytes or words) are displayed or must he entered in HEXADECIMAL form.
  2. An "address" is a number in the range 0 to FFFF, (sometimes called a "word"). A "byte" is a value in the range 0 .. FF.
  3. A "label" replaces one specific address. It has max 8 letters or digits and was ENDS WITH A COLON (:) In this assembler, labels are exclusively used to indicate "branch addresses" which are used in "relative" addressing mode. The indicated addresses must lie within a distance less than 128 bytes from the program counter (see appendix).
  4. In the appendix you will find a list with usable mnemonics. These can be used in 5 addressing modes:

    "Implied" eg. PSHX, DECA

    "Immediate" eg. LDD %1234, LDAB %6C
    (the % sign must be in front!!!!!)

    "Relative" eg. BRA L1:, BRS 23, BNE 3987
    (L1: is an address referenced by a label, 23 is an offset and 3987 is an explicit branch address)

    "Direct" eg. STAB 67
    (the operand is an address in the "zero- page"; no label may be used here!)

    "indexed" eg. LDAB 3,X
    (add 3 to the contents of the X-register to find the effective address)

    "Extended" eg. JSR 42AB
    (the operand is a 2-byte address, no label!)

    More information about mnemonics and addressing modes can be found in the Hitachi/Motorola manual, in Appendix C, or in every book that introduces to assembly language programming.

  5. When experimenting with the Assembler pak, always take precautions! Some areas can be dangerous, can cause TRAPS and cause the Organiser to hang!!! Since in such cases all RAM - data is lost, it is wise to start with an "empty" Organiser. (or first copy your vital programs and data in A: to another pak before starting)
    • In the ROM area, which covers addresses 8000 to FFFF patching or stepwise execution is impossible, though you can examine that code with DUMP or unassemble. To try out some things in ROM, first copy a ROM block to a sale RAM area.
    • In the RAM area too some areas are reserved and can cause TRAPS. Roughly, a "safe" area lies between addresses 3000 and 5000. See the appendix for exact information.

D. Printer output

When a Comms Link Interface is detected, most options (except COPY and PATCH) can send output to a connected Printer.

Each time a starting address is requested, you can toggle the printer status with the mode key:

To switch printer output OFF:

eg.

Addr.(hex):2345  PRINTER is ON

pressing <MODE>:

Addr.(hex):2345  PRINTER is OFF

To switch printer output ON:

Addr.(hex):2345  PRINTER is OFF

Switching the printer ON works in 2 steps:

  1. Press the <MODE> key and a new screen appears

    OUTPUT to PINTER Auto(y/n)?:_

  2. With a "Y" answer, output is sent UNINTERRUPTED to the printer; in the other case, each line is sent after pressing the <EXE> key.

N.B. When printer output is desired, always first check connections and proper SETUP before starting the program!


E. Starting address

Addr.(hex):_   PRINTER is OFF

The choice of a starting address is very important: dumping, disassembling, compiling, or stepping all start from that point. In most cases a default address is suggested (eg. the last one or a safe one) which may be changed. (careful !)

To change an address, use the normal OPL editing facilities: the easiest way is by first pressing <ON/CLEAR>, which blanks the current address, and key in your new address, ending with <EXE>. (the arrow keys and <DEL> may be used too)

Now we explain the other options from the main menu:


F. Dump

eg. To look at the memory data starting at address 2414 (first fill in the address)

2414:ASSEM   415353454d000004 ← 8 ASCII signs
← 8 (hex) bytes

Press EXE

241C:FIND 9 S   46494E44E6390453

Press EXE

2424:AVE 6 DI   415645E636054449

etc.

EXE: Shows the next 8 bytes and ASCII signs

ON/CLEAR: Return to main menu.

N.B. The first 31 ASCII characters (see ASCII table in Appendix E) are indicated by a SPACE character.


G. Unassem

From a specified starting address, code is disassembled on the top line with the corresponding bytes on the second line.
Press <EXE> to see the next instruction, return to the main menu with <ON/CLEAR>.

Eg. disassembly of the code at 8116:

8116:LDD 5E   DC 5E

Press EXE

8118:DECA   4A

Press EXE

8119:STD 2065   FD 20 65

Press EXE

811C:STD A5   DD A5

etc.

ON/CLEAR: Return to main menu

N.B. Most system calls (OS instructions) are translated in readable form.

eg. OS BZ$BELL
(see Psion techn. ref. manual)


H. Assem

Assembling is the transformation (or compilation) of some "source" code (with mnemonics, labels etc.) to executable 6303X machine code. After successful compilation, the resulting machine code (object code) can be viewed, disassembled or tested with this program. (see other options)

Entering the source code can be done in 2 ways:

Direct or File?_

Answer with "D" or "F" or use the arrow keys with <EXE>.

Direct

Key in the source lines immediately (first specify a starting address) and the code will be generated after each line (some forward references are filled in at the end). Possible errors are flagged immediately and the line must be re-entered.
Stop with an empty line or with the <ON/CLEAR> key.

N.B. Examine or test your code with other options from the main menu. (see further)

File

Prepare your source code within a file and compile it afterwards from a starting address. When specifying a filename, enter a pak - and filename.
(use OPL syntax: change the pakname with the <MODE> key!)

There are several FILE possibilities here!
Choose from a sub-menu:

Compile Edit New List Delete Dir

Compile:Compile an EXISTING source file. After specifying a starting address (a suitable one is proposed), the source lines will be compiled. When an error occurs, the erroneous line (+ line number) is displayed with an error message. In such a case, you may correct the error and re-compile. After a successful compilation, the source + object code may be saved, just like an OPL procedure.
Edit :Edit an EXISTING source file using the same editing commands as if you where editing an OPL source file! At the end you can SAVE it or QUIT.
New :Create a new file
List :List the source to a printer (if connected)
Delete :Delete an existing file
Dir :Show existing files ("true" OPL files are displayed too!!)

File structures in Assembler Pak:

Assembler source files are treated like usual OPL source files: so you can prepare them on a PC and send them via Comms Link to the organiser. Both contain a source part and a code part (either can be empty). The code parts are totally different: OPL doesn't recognize mnemonics at all, so you can't TRANSLATE an assembler source file from the PROG menu !
The structure of an OPL procedure is retained: every assembler source file starts with a label which is the procedure name ending with a colon. (you can use that first label to branch to the start in your program!)

Structure of a source line

[label] [instruction+space] [operand][;comments]
(items between square brackets are optional)

Rules

Examples

Addr.mode --------- ;dummy program comments are free L1: LDAB %12 IMMediate BRA L2: RELative DW 1234 Ass.instr DB 89 Ass.instr DC0 "ABCDEFGH" Ass.instr L3: INCB ; B=B+1 IMPlied BNE L1: RELative L2: JSR 1234 EXTended PSHX IMPlied LDD 3,X INDexed JMP 0,X INDexed STAB 67 DIRect LDX %4000 IMMediate L4: OS KB$GETK System Call RTS ;stop IMPlied

Compilation errors

When an error occurs during compilation:

Error Messages


I. Step

With this option you can watch and test the execution of machine code (first specify a starting address). After choosing this option the first STEP screen is displayed: on the top line, it shows the program counter with the instruction that will be executed AFTER pressing the <EXE> key; (the first line always shows the NEXT instruction). On the second line, the ACTUAL contents of registers, flags and stack pointer are shown.

Let us illustrate it with a small program

Program

Suppose we want to fill 2 areas in memory with some fixed values: starting at 4000 we put 5 bytes with value FE; starting at 4005 we put 5 bytes with value FF. When the first filling is completed we hear a beep.

The source could be something like this:

LDX %4000 LDD %FE05 LOOP: STAA 0,X INX DECB BEQ OK: BRA LOOP: OK: PSHX PSHA PSHB BEL: OS BZ$BELL PULB PULA PULX INCA BEQ END: LDAB %02 BRA LOOP: END: NOP

Let us prepare the source!

choose the ASSem option

N.B. When the Printer is ON, compilation can be followed: line number, object code and source are printed!

Verify your source code

You can always control your input by LISTing the source file to a printer or by disassembling the code from your starting address: (choose the Unassem option and keep pressing <EXE>)

3000:LDX %4000 CE 40 00 3003:LDD %FE05 CC FE 05 3006:STAA 0,X A7 00 3008:INX 08 3009:DECB 5A 300A:BEQ 300E 27 03 300C:BRA 3006 20 FB 300E:PSHX 3C 300F:PSHA 37 3010:PSHB 36 3011:OS BZ$BELL 3F 0E 3013:PULB 33 3014:PULA 32 3015:PULX 38 3016:INCA 4C 3017:BEQ 301D 27 04 3019:LDAB %02 C6 02 301B:BRA 3006 20 E9 301D:NOP 01

Note that the branch addresses are filled in!!

STEPwise execution

Choose the STEP option from the main menu and specify your starting address (probably 3000).
A first typical STEP screen is displayed:

3000:LDX %4000   0000:0000:140:c0 → Program counter with next instruction
^^^^ ^^^^ ^^^ ^^ AABB XXXX SP CC or DDDD → A,B (D) AND X registers, stack pointer and CC

Remember:

Upper line = NEXT instruction to be executed
Lower line = Actual contents of

N.B. When the first STEP screen appears, no instruction has been executed yet and the second line shows default or starting values (which may be altered with the R command: see further)

Execution

To execute the instruction on the top line, press <EXE> and watch the effect on the second line:

Keep pressing the <EXE> key and follow the execution of the program (here until a NOP instruction is reached at 301D)

Extra possibilities: the STEP subcommands

In STEP mode there are 9 keys that give you complete debugging capabilities. Press the <MODE> key to see them:

EXE=Step A=Adres PC X=skip B=Break at J=Step routine D=Dump R=Registers P=Patch

Achoose another address for the PC (program counter)
Fill in a new value and the PC is changed immediately
Xskip the shown (=next) instruction
Bset a breakpoint.

After filling in an address (for the PC), execution starts immediately and uninterrupted until the specified address is reached.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WHEN THIS BREAK-ADDRESS CANNOT BE REACHED THE ORGANISER HANGS ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Jexecute a complete subroutine without stepping through its details (used with JSR and BSR)
Ddump memory staring from a given address (works like the dump option from the main menu)
Rchange the actual contents of registers, stack or condition code.
First specify the item and fill in the value:
Register:_ (A,B,D,X,SP or CC)
Value: _ (specify a (hex) value)
Ppatch memory starting from a given address (analogous with the same main menu option.

PS. To return to the STEP screen from any subcommand, press the <ON/CLEAR> key

Debugging of the example program

First choose the STEP option + address 3000

3000:LDX %4000   0000:0000:140:c0 → to be executed
→ starting values
!!!!

Press EXE to execute LDX %4000 and watch the X register!

3003:LDD %FE05   0000:4000:140:c0 → next instr.:
→ X is filled in !

Press EXE

3006:STAA 0,X   FE05:4000:140:c0 → save A at 4000
→ D is filled in

Press EXE

3006:STAA 0,X   FE05:4000:140:c0

N.B. Has address 4000 been filled in with vale FE ? Control this with subcommand "D" (dump) and look at the contents of memory location 4000. Return to the STEP screen with <ON/CLEAR>.

Press EXE etc.
....................
....................
....................

300E:PSHX   FE00:4005:140:c0 → Save the X reg.
→ D is filled

Press EXE. Watch the stack pointer!
....................
....................
....................

3011:OS BZ$BELL  0000:0000:140:c0 → short beep system call

Press EXE
....................
....................
....................

301D:NOP   0000:0000:140:c0 → last "dummy" instruction marks the end

Hints and tips when using the STEP option:

  1. From the stack pointer, which does not change very much, only the 3 last digits are shown (the first digit is 2)
  2. EVERY instruction is executed stepwise: to skip a number of instructions (and still execute them), set a breakpoint (B) or execute a subroutine with the "J" command.
  3. As stated before, careless use can easily cause TRAPS and cause the machine to hang!! Avoid dangerous areas!! The so-called "zero page variables" and other system variables starting from address 2000 are used intensively by the Organiser itself. Some of these variables may even change between two steps! For more details consult the Technical Ref. Manual.(the use of breakpoints can help sometimes...)
  4. To execute your program as a whole. first choose the starting address, eventually fill in some starting values (like the contents of the D register, which is passed as an input parameter in OPL calls), and set a Breakpoint at the (expected!) exit. (usually an RTS instruction)

J. Copy

To copy from one area to another, you must specify

source address ( From: )
number of bytes( #: )
target address ( To: )

Example:

From:C000 #:200  To:3000

N.B. Although the program will prevent dangerous COPY actions, always take care with this operation!!


K. Patch

From a specified starting address you can change memory contents in (B)yte format or in (C)haracter format:

(B)yte/(C)har: _ (enter B or C)

Eg. to change bytes from address 3000: (space=unchanged)

3000:55 55 55 55 :12 34 FF
(3000 has now 12,34,55,FF)

<EXE> (gives the next 4 bytes)

3004:55 55 55 55 : (unchanged)

To change text:

eg. :

3010:ABCDEFGH:   :12345678
(type the new text exactly under it)

EXE: Next ASCII - INPUT etc.

Always return to the main menu with <ON/CLEAR>.


L. Applications in OPL

  1. Each compiled and saved assembly procedure follows OPL structures. It consists of 2 parts: a code part, which contains the 6303X machinecode and a source part, which contains the source code. (for the "specialists": each file is saved as a 83 - typed blockfile)
  1. Parameters are passed like in a USR routine: - the (integer) input parameter, which must be placed between parentheses after the procedure name, is transferred to the D register. (when no input parameter is needed, fill in a 0 value) - from the X register, the routine gives an integer back to the calling program.

    Example 1

    Sourcefile "P1"

    P1:xgdx ;input in X inx ;x=x+1 rts ;return X

    After compilation, when used in an OPL procedure:

    PRINT P1:(21)

    will print the number 22!

    Example 2

    Boot:os dv$boot rts

    Here a call with boot:(0) will boot all devices.

  1. Each routine must return to the calling OPL procedure with a RTS instruction. (With the same stack pointer)
  1. You can copy (eg object only) to other paks: to use an assembler procedure in OPL, just the Object code is needed.
  1. Prepare larger source codes on a PC, and send them (Comms) to the Organiser. Then compile and save them with Assembler pak.
  1. To transfer a compiled Assembler procedure to a PC (eg to use it with "BLDPak"), first UNMAKE it to the PC: the source and codefiles will then separately be present (OPL and OB3) on the PC for later use.
  1. USR in OPL can be completely replaced by a suitable assembler procedure. No variables are needed to hold addresses and strings to put in the data. No more strange POKES: the source code remains with the procedure!

Appendix A: Standard opcodes (6303X)

Mnem Hex Mode L Mnem Hex Mode L Mnem Hex Mode L --------------------------------------------------------- ABA 1B IMP 1 BITB D5 DIR 2 INC 6C IND 2 BLE 2F REL 2 BITB E5 IND 2 INC 7C EXT 3 ABX 3A IMP 1 BITB F5 EXT 3 INCA 4C IMP 1 ADCA 89 IMM 2 BLE 2F REL 2 INCB 3C IMP 1 ADCA 99 DIR 2 BLS 23 REL 2 INS 31 IMP 1 ADCA A9 IND 2 BLT 2D REL 2 INX 08 IMP 1 ADCA B9 EXT 3 BMI 2B REL 2 JMP 6E IND 2 ADCB C9 IMM 2 BNE 26 REL 2 JMP 7E EXT 3 ADCB D9 DIR 2 BPL 2A REL 2 JSR 9D DIR 2 ADCB E9 IND 2 BRA 20 REL 2 JSR AD IND 2 ADCB F9 EXT 3 BRN 21 REL 2 JSR BD EXT 3 ADDA 8B IMM 2 BSR 8D REL 2 LDAA 86 IMM 2 ADDA 9B DIR 2 BVC 28 REL 2 LDAA 96 DIR 2 ADDA AB IND 2 BVS 29 REL 2 LDAA A6 IND 2 ADDA BB EXT 3 CBA 11 IMP 1 LDAA B6 EXT 3 ADDB CB IMM 2 CLC 0C IMP 1 LDAB C6 IMM 2 ADDB DB DIR 2 CLI 0E IMP 1 LDAB D6 DIR 2 ADDB EB IND 2 CLR 6F IND 2 LDAB E6 IND 2 ADDB FB EXT 3 CLR 7F EXT 3 LDAB F6 EXT 3 ADDD B3 EXT 3 CLRA 4F IMP 1 LDD BC EXT 3 ADDD C3 IMM 3 CLRB 5F IMP 1 LDD CC IMM 3 ADDD D3 DIR 2 CLV 0A IMP 1 LDD DC DIR 2 ADDD E3 IND 3 CMPA 81 IMM 2 LDD EC IND 2 ADDD F3 EXT 3 CMPA 91 DIR 2 LDD FC EXT 3 AIM 61 IND 3 CMPA A1 IND 2 LDS 8E IMM 3 AIM 71 DIR 3 CMPA B1 EXT 3 LDS 9E DIR 2 ANDA 84 IMM 2 CMPB C1 IMM 2 LDS AE IND 2 ANDA 94 DIR 2 CMPB D1 DIR 2 LDS BE EXT 3 ANDA A4 IND 2 CMPB E1 IND 2 LDX CE IMM 3 ANDA B4 EXT 3 CMPB F1 EXT 3 LDX DE DIR 2 ANDB C4 IMM 2 COM 63 IND 2 LDX EE IND 2 ANDB D4 DIR 2 COM 73 EXT 3 LDX FE EXT 3 ANDB E4 IND 2 COMA 43 IMP 1 LSR 64 IND 2 ANDB F4 EXT 3 COMB 53 IMP 1 LSR 74 EXT 3 ASL 68 IND 2 CPX 8C IMM 3 LSRA 44 IMP 1 ASL 78 EXT 3 CPX 9C DIR 2 LSRB 54 IMP 1 ASLA 48 IMP 1 CPX AC IND 2 LSRD 04 IMP 1 ASLB 58 IMP 1 DAA 19 IMP 1 MUL 3D IMP 1 ASLD 05 IMP 1 DEC 6A IND 2 NEG 60 IND 2 ASR 67 IND 2 DEC 7A EXT 3 NEG 70 EXT 3 ASR 77 EXT 3 DECA 4A IMP 1 NEGA 40 IMP 1 ASRA 47 IMP 1 DECB 5A IMP 1 NEGB 50 IMP 1 ASRB 57 IMP 1 DES 34 IMP 1 NOP 01 IMP 1 BCC 24 REL 2 DEX 09 IMP 1 OIM 62 IND 3 BCD 25 REL 2 EIM 65 IND 3 OIM 72 DIR 3 BEQ 27 REL 2 EIM 75 DIR 3 ORAA 8A IMM 2 BGE 2C REL 2 EORA 88 IMM 2 ORAA 9A DIR 2 BGT 2E REL 2 EORA 98 DIR 2 ORAA AA IND 2 BHI 22 REL 2 EORA A8 IND 2 ORAA BA EXT 3 BITA 85 IMM 2 EORA B8 EXT 3 ORAB CA IMM 2 BITA 95 DIR 2 EORB C8 IMM 2 ORAB DA DIR 2 BITA A5 IND 2 EORB D8 DIR 2 ORAB EA IND 2 BITA B5 EXT 3 EORB E8 IND 2 ORAB FA EXT 3 BITB C5 IMM 2 EORB F8 EXT 3 PSHA 36 IMP 1

Mnem Hex Mode L Mnem Hex Mode L Mnem Hex Mode L --------------------------------------------------------- PSHB 37 IMP 1 SWI 3F IMP 2 PSHX 3C IMP 1 TAB 16 IMP 1 PULA 32 IMP 1 TAP 06 IMP 1 PULB 33 IMP 1 TBA 17 IMP 1 PULX 38 IMP 1 TIM 6B IND 3 ROL 69 IND 2 TIM 7B DIR 3 ROL 79 EXT 3 TPA 07 IMP 1 ROLA 49 IMP 1 TRAP 00 IMP 1 ROLB 59 IMP 1 TST 6D IND 2 ROR 66 IND 2 TST 7D EXT 3 ROR 76 EXT 3 TSTA 4D IMP 1 RORA 46 IMP 1 TSTB 5D IMP 1 RORB 56 IMP 1 TSX 30 IMP 1 RTI 3B IMP 1 TXS 35 IMP 1 RTS 39 IMP 1 WAI 3E IMP 1 SBA 10 IMP 1 XGDX 18 IMP 1 SBCA 82 IMM 2 SBCA 92 DIR 2 SBCA A2 IND 2 SBCA B2 EXT 3 SBCB C2 IMM 2 SBCB D2 DIR 2 SBCB E2 IND 2 SBCB F2 EXT 3 SEC 0D IMP 1 SEI 0F IMP 1 SEV 0B IMP 1 SLP 1A IMP 1 STAA 97 DIR 2 STAA A7 IND 2 STAA B7 EXT 3 STAB D7 DIR 2 STAB E7 IND 2 STAB F7 EXT 3 STD DD DIR 2 STD ED IND 2 STD FD EXT 3 STS 9F DIR 2 STS AF IND 2 STS BF EXT 3 STX DF DIR 2 STX EF IND 2 STX FF EXT 3 SUBA 80 IMM 2 SUBA 90 DIR 2 SUBA A0 IND 2 SUBA B0 EXT 3 SUBB C0 IMM 2 SUBB D0 DIR 2 SUBB E0 IND 2 SUBB F0 EXT 3 SUBD 83 IMM 3 SUBD 93 DIR 2 SUBD A3 IND 2


Appendix B: Specific assembler directives

InstructionoperandExample
DBbyteDB 34
Purpose: Put specific byte values into your code
DWwordDW 1234
Purpose: generation of specific words (2 byte values)
DCASCII textDC "No length"
Purpose: put text into your code (no length)
DCLASCII textDCL "ASSEMBLER"
Purpose: put text in your code (length byte in front)
DC0ASCII textDC0 "This is text"
Purpose: put text in your code (terminated with 0)
;; comments are free
Purpose: put remarks in your source code

Appendix C: The structure of 6800(6303X) processors

A detailed discussion can be found in the manufacturers' databooks (Hitachi, Motorola etc.)

a) Registers

c) Addressing modes

  1. Inherent or implied

    The operand is 1 byte
    eg. PSHX, TSTA, INCB, RTS

  2. Immediate

    the operand is one word or one byte (in this assembler preceded by a % sign)
    eg. LDAA %12, LDX %FFFF

  3. Direct

    the operand is an address in the zero-page (0-FF)
    eg. STAA 67, LDX 3D

  4. Extended

    the operand is a word (2 byte address)
    eg. LDAB 4CFF, LDD 1234

  5. Relative

    the operand is ONE byte (offset) which references an address. This address is found by adding (subtracting) the PC and the offset. The resulting destination D must lie: PC -125 <= D <= PC + 129

    In this assembler you my indicate this branch address

    • with a label (8 chars ending with a colon)
    • with an offset (1 byte)
    • with a word (the destination address)
  6. Indexed

    The operand is one byte, followed with ",X" and indicates an address: to find this address, add the specified byte to the contents of the X register.
    eg. STAB 13,X or JSR 0,x


(Appendices D and E missing)