The following assumes:
| Command | Description |
|---|---|
| mk | maintains (makes) related files; keeps everything in order, saves a lot of time, highly recommended |
| h180 as | Hitachi 64180 assembler; assembles a .s source file into a .o object file |
| h180 ld | Hitachi 64180 linker; links .o object files into a single a.out executable file |
| mcpload | Loads an executable file into RAM on the development board |
This generates a number of object files, one for each source file, with names file.o.
This creates a file called a.out.
MANPATH=/sys/man/cross man 1 as MANPATH=/sys/man/cross man 1 ldon Atlas. See also Summary of h180/z80 as assembly language by Charles Forsyth. Although this describes a z80 assembler, the syntax and directives are identical, and the z80 opcodes are a proper subset of the 64180 opcodes. The extra 64180 (z180) instructions are documented in Chapter 13 of the z180 Users' Manual.
There is one matter which Forsyth and the manual pages do not fully address (pun). The assembler and linker know about two ``segments'', called text and bss. In an EPROM-based system, text corresponds to EPROM and bss corresponds to RAM. In our case, we assume that the program lives in RAM, so text and bss correspond to different parts of RAM, viz. the program and constant data (text) and the storage for variables (bss).
The assembler directives .text and .bss mean ``assemble the following into the text segment'' and ``assemble the following into the bss segment'' respectively. You start off in the text segment. To allocate storage for variables, write, e.g.,
.bss lab1: .space 2 stack: .space stksizeThis example allocates a block of 2 contiguous bytes labelled with the name lab1 and stksize contiguous bytes labelled with the name stack. You can then use lab1 and stack just like any other assembly-time symbol to refer to the start of the allocated space.
The linker collects all such definitions together and assigns appropriate addresses to them. Addresses are allocated consecutively within each segment, with no gaps.
How does the linker know where to put the segments? You tell it, using the -T and -C command-line options, the arguments after which specify the start address (in hex) of the text and bss segments, respectively.
This method much better than using .set. Why do the address arithmetic yourself when you can get the linker to do it for you? In particular, it is almost essential to use this method if your program is split among several separately-assembled source files. Furthermore, your program can be ``re-targeted'' to an EPROM-based system by simply changing the numbers after -T and -C. There are however occasional exceptions in which .set is preferable, e.g. when allocating a circular buffer on a page boundary.
Bytes allocated in the bss segment are uninitialized: you may not assemble data into the bss segment, and the linker does not store any data in the a.out file at the addresses it allocates.
Don't forget to write .text to return to the text segment after an excursion to the bss segment.
The .data directive is mentioned in the documentation, but I myself have never found a use for it.
Do not use .org in your programs, except in highly unusual circumstances, because it can interfere with the linker's attempts to assign addresses for code and data.
Once you have generated your executable (linked program) file, you can load its contents into the RAM of the MCP 64180 board by giving the command:
The manual page is accessible by
# mkfile for pulse monitor # AJF January 1994 # updated for 64180 board, Dec. 1998 BUILTINS = objs = pulse.o interface.o coro.o pulsemon.out: $objs h180 ld -C 8000 $objs mv a.out pulsemon.out %.o: %.s h180 as $stem.s mv a.out $stem.o |
A summary of commands follows:
| B | Enters the Basic interpreter, initializing program, variables, and arrays. |
| D | Downloads Intel hex format through the terminal port. |
| G <w1> | Go, begins execution at address <w1>. |
| H | Help, displays list of commands. |
| L | Loads from tape, indicates record count when done (in hex). |
| M <w1>,<w2> | Displays Memory from <w1> to <w2>. |
| R | Re-enters Basic, preserving the existing program. Should not be used when the system is first turned on. |
| S <w1> XX-<b2> | Substitutes into memory, starting at address <w1>. Displays contents as XX, entering <b2> will replace XX and advance to the next. Entering a space will skip to the next, without changing, and a carriage-return will exit to monitor. |
| T | Enters Terminal mode. Simulates an ASCII terminal operating in full duplex mode. Serial port is tape port. |
| U <w> | Initializes the 8251 Usart with the value <w>. See Intel 8251 documentation. |
| W <w1>,<w2> | Writes memory from <w1> to <w2> to tape. |
(The table above is taken from ``The Micro Basic Monitor'', chap. 9 of ``Micro Basic Users' Guide'' by Dave Dunfield, adapted by AJF. Some commands are not implemented.)
15 Jan 1999