80-Bus News

  

Spring 1985 · Volume 4 · Issue 1

Page 27 of 31

Things your Mother never told you about M80 and L80

by D.W.Parkinson

Having looked at some of the comments on returned 80-BUS questionnaires, this article will please some readers, but irritate others. I trust that those that don’t use CP/M-80 and Microsoft’s M80 and L80 package will bear with me – after all this article may prompt you to go back and read about the more obscure features of your assembler/​high level language. The article assumes that the reader has a reasonable working knowledge of M80 and L80.

Microsoft’s M80

First I’ll start with Microsoft’s M80 macro assembler. (CAVEAT – The features exploited in these examples are present in release 3.44 of the assembler (09 Dec 1981) and do not necessarily apply to earlier releases.)

M80 includes a pseudo-op — ‘.printx’ — that prints a message on the system console whenever it is encountered during an assembly. If you ever assemble large files, then this can be used to keep you informed of the progress of the assembly and is a useful indicator that things are progressing as they should. The syntax of the command is:

.printx <marker><text><marker>
e.g. .printx ★ I/O section reached ★

i.e. Following the ‘.printx’ command M80 takes the first non-space (or non-tab) character that it finds, and then sends that character and the following text to the console. It stops when it sees the same marker character again. I tend to use the ‘★’ character as my marker.

As well as indicating when certain ‘landmarks’ are reached, it can be used to confirm that the assembler is actually doing what you think it is doing, and also that your assembled program matches any particular system requirements. The former obviously covers the case where an assembler program utilizes the conditional assembly feature of M80, and confirms that you have your conditional flags set correctly. (If you have several slightly different versions of a program to match differing environments, then it is easier to maintain one copy of the program than several.) In the latter case, you may require a certain point of your program to fall at a particular address. This can be done with an ‘ORG’ statement, but you may inadvertently add some extra code to the start of the program some months later, forgetting that this will cause one bit of code to overlay another later on in the program!
e.g.

ifdef Nascom ; If we have defined Nascom version
.printx ★ Nascom version ★
else
.printx ★ Gemini version ★
endif

&

....      ; End of section of code
ret
if $.GE.66h ; Check it ends before start of NMI routine
.printx ★ ++++ error NMI routine clobbered +++++ ★
endif
org 66h
; Start of NMI routine
.....

Occasionally you may want to know the size of a program — perhaps it has to fit within an EPROM. In the past I used to enter a single line at the end of the program consisting of the one word ‘error’. The assembler always threw this out as an error, and from the error message I could see the address that the program had reached. With version 3.44 of M80 a much better way of achieving this effect appeared. It makes use of the macro feature of M80 together with parameter substitution.

Suppose you are assembling a program and want to know several things:

(i)   The length of the code segment of the program.
(ii)   the length of the data segment of the program.
(iii)   the length of a particular routine within the program. (Perhaps in some circumstances it might have to be overlayed by an alternative routine.)

There are two steps you have to take to achieve this:

Step 1 is to ensure that you have labels within the program to which the assembler will assign the appropriate values. (e.g. ‘lcode equ $-start’ at the end of the code segment.)
Step 2 is to create a macro to print out what you want to see:
e.g.

show   macro   a,b,c
.printx ★ Program code length is a bytes ★
.printx ★ Program data length is b bytes ★
.printx ★ Access subroutine length is c bytes ★
endm

If you use the macro in the normal way (show lcode,​ldata,​alength) the result would be the useless messages

★ program code length is lcode bytes ★

… and so on, with just the direct substitution of

Page 27 of 31