老问题,但这可能对那些仍在寻找的人有用。我在我的 Ampro Little Board 上检查了这一点,该板在 CP/M 2.2 上运行 1980 M80/L80。
您可以在起始 .MAC 文件中使用 ASEG(绝对)指令,将 0D000H 指定为 org,然后引用外部模块。只要这些外部模块不包含 DSEG 或 PSEG 指令,您就应该能够将它们全部链接在一起,并以 0D000H 作为起始地址。例如
; TEST.MAC
ASEG
ORG 0D000H
public tstart
tstart:
...
call myfoo## ; call routine myfoo in external module foo.rel
...
end tstart
组装它:
M80 TEST,=TEST
将其与 foo.rel 链接并在输出中使用 /X 以生成 .HEX 文件 (TEST.HEX):
L80 TEST,FOO,TEST/N/X/E
如果您检查生成的 .HEX 文件,您应该会看到起始地址是 0D000H。顺便说一句:如果您不使用 /X 选项,则带有 /N/E 的 L80 将生成一个 .COM,其中所有代码都使用偏移量 0D000H 链接,除非您还包含 .phase 指令。例如:
; TEST.MAC
ASEG
ORG 100H
.phase 0D000H
public tstart
tstart:
...
call myfoo## ; call routine myfoo in external module foo.rel
...
end tstart
链接以制作 .COM 而不是 .HEX:
L80 TEST,FOO,TEST/N/E <== note no '/X'
您无法运行它,但您可以认为 .COM 文件实际上是填充到最近的 128 字节边界的 .BIN(假设您的 CP/M 使用分配 128 字节块的典型方法)。您可以通过对 .COM 文件执行 DUMP 来确认结果。如果代码很短,它还可能包含未被您的代码覆盖的 L80 加载程序代码的剩余部分。
请注意,您还可以使用带有 org 0100H 的 ASEG 方法来制作常规的 CP/M .COM。在这种情况下,您不需要使用 .phase 假设您的代码的开头是 100H。