kevinboone/cpm-cal

Simplify linking ?

Closed this issue · 5 comments

I like your style (and I may borrow some of your ideas) but I was wondering if you knew that you can automatically link in relocatable object files using .REQUEST ?

e.g

.REQUEST    CONIO

Using this feature of the Microsoft Macro assembler might allow you to simplify the link command making it a little easier to rebuild the binary on CPM itself...

I hadn't seen that construction before, and the Macro80 manual didn't give me much help:

".REQUEST sends a request to the LINK-80 Loader to search the file names in the list for undefined globals before searching the FORTRAN library. "

So please feel free to elaborate. I'm all in favour of simplifying things.

Instead of using

A> link main,conio,intmath,string,mem,clargs,date,romwbw,cal/n/e

You would use .REQUEST in the main program source to tell the linker to resolve any undefined globals using the specified object files.

.REQUEST CONIO,INTMATH,STRING,MEM,CLARGS,DATE,ROMWBW

Multiple filenames can be separated by commas or specified using separate statements.

This should allow you to use the following command when linking.

A> link main,cal/n/e

I say should simply because after 30 years, I'm not at all sure of the linker syntax you need if the name of the main file and entry point is not the same as the output filename...

To tidy things up a bit I use the following macro (which I define at the same time as all the symbols I use).

USING           MACRO   Lib_1,Lib_2,Lib_3,Lib_4,Lib_5,Lib_6,Lib_7,Lib_8
                IFNB    <Lib_1>
.REQUEST        Lib_1
                ENDIF
                IFNB    <Lib_2>
.REQUEST        Lib_2
                ENDIF
                IFNB    <Lib_3>
.REQUEST        Lib_3
                ENDIF
                IFNB    <Lib_4>
.REQUEST        Lib_4
                ENDIF
                IFNB    <Lib_5>
.REQUEST        Lib_5
                ENDIF
                IFNB    <Lib_6>
.REQUEST        Lib_6
                ENDIF
                IFNB    <Lib_7>
.REQUEST        Lib_7
                ENDIF
                IFNB    <Lib_8>
.REQUEST        Lib_8
                ENDIF
                ENDM
;

I used to think this made the code look neater and easier to understand, but I suspect that is only really because it suits my coding style.

		INCLUDE SYMBOLS
;
		USING	SQRTI
		USING	PUTS, PUTC, PUTI,
		USING	INITF, OPENF, CLOSEF, WRITEF, BDOS

I have used separate object files for every function in this example, but functions that share common code are best grouped together.

"before searching the FORTRAN library. "

You can ignore the bit about the FORTRAN library if you are only using MACRO. I remember it confused me for a quite while as well... 😄

OK -- so I added to main.asm:

    .request conio
    .request clargs
    .request intmath
    .request date
    .request string
    .request romwbw
    .request mem

I had to change the linker line to

    l80 /p:100,main,cal/n/e

Without the /p directive, the linker was generating calls to addresses that were 256 bytes too small, before the TPA.

To be honest, I don't understand the relationship between ORG, ASEG, and /P. So, again, I have arrived at something that works (for me) by trial-and-error.

I like the idea of being able to list the linker dependencies in the source, rather than on the command line. A problem I often have is that I end up with a linker command line that is too long for CP/M.

Comments welcome.

Thank you for the suggestion, which I have adopted.