石原 博の覚書

電子工作に関する日々の覚書を記載します

PL/M

2021-10-31 16:12:27 | 日記

CUGにも幾つかPL/Mでかかれたプログラムがある。PL/MコンパイラをコンパイルするにはFortranコンパイラが必要なので、Linux上でgfortranを使用し動かしてみた。

(1)The Unofficial CP/M Web Siteから「PLM compiler source 」をダウンロードし展開
(2)本体はPLM81.FORとPLM82.FOR
  gfortran PLM81.FOR -o plm81
    gfortran PLM82.FOR -o plm82
   ソースの最後にCP/MのEOFである01AHがあるのでエラーになるが、それを除いてコンパイル。いろいろWarningが出るが無視。
(3)使い方が良くわからなったが、同サイト上の「PL/M-80 compiler for DOS Box: 500K」を展開してみたところ、以下のDOSのバッチファイルがあった。つまり入力ファイルも出力ファイルもファイル名は固定ということ。(fort.1は良くわからないけど)

===PLM80.BAT===
Rem This setup created by mr.collis@physics.org 31/03/2008
copy %1.plm fort.2
echo rubbish  > fort.1
plm81

rename fort.16 fort.4
rename fort.17 fort.7
plm82
copy fort.17 %1.hex
===============

linuxでは以下のスクリプトを作成。(改行をCR/LFにするのもsedで組み込んだ)
===plm80===
#!/bin/sh
cp $1.PLM fort.2
echo rubbish > fort.1
./plm81

mv fort.16 fort.4
mv fort.17 fort.7
./plm82
sed 's/$/\r/g' fort.17 > $1.HEX
===========

./plm80 PLMSAMP としてコンパイルすればPLMSAMP.HEXが生成される。(付属していたPLMSAMP.HEXと一致することを確認)

これをCP/MでLOADすれば動くはず。ところがエラー「ERROR: INVERTED LOAD ADDRESS, LOAD ADDRESS 0010」
HEXファイルを調べてみると、ロード場所が0010スタート。良く見るとPLMSAMP.PLM内で、「10H:  /*  IS THE ORIGIN OF THIS PROGRAM */」となっている。ソースを修正 (10H->100H)しコンパイルし、CP/Mでロード
  
>load PLMSAMP.HEX

FIRST ADDRESS 0100
LAST  ADDRESS 0381
BYTES READ    0282
RECORDS WRITTEN 06

ところが、実行するとエラー。もう一度ソースを良く読むと、なんと出力ルーチンがアドレスで指定されている。

    /* PRINT USING INTELLEC MONITOR */                                          
PRINT$CHAR: PROCEDURE (CHAR);                                                   
    DECLARE CHAR BYTE;                                                          
    DECLARE IOCO LITERALLY '3809H';                                             
    GO TO IOCO;                                                                 
    END PRINT$CHAR;                      

fort.12がリストファイルなので、該当するPRINT$CHARルーチンを探すと、0197Hとなっている。DDTでHEXファイルを確認すると、
  0197  LXI  H,03E1
  019A  MOV  M,C
  019B  JMP  3809
  019E  RET  

0x3809に出力ルーチンを作れば良いのだが、Cregを出力すれば良いのか? どのレジスタを保存すべきか? よくわからない。出来るだけ安全サイドでBDOSコールルーチンを作る。

===COUT.ASM===
;--CP/M interface---------------
BDOS EQU 5

ORIGIN EQU 3809H
;
 ORG ORIGIN
COUT: PUSH H
 PUSH D
 PUSH B
 PUSH PSW
 MOV E,C
 MVI C,2
 CALL BDOS
 POP PSW
 POP B
 POP D
 POP H
 RET
;

これを使用して
>asm COUT
CP/M ASSEMBLER - VER 2.0
3818
000H USE FACTOR
END OF ASSEMBLY

RunCPM Version 5.3 (CP/M 2.2 60K)

>ddt COUT.HEX
DDT VERS 1.4
NEXT  PC
3818 0000
-I PLMSAMP.HEX
-R
NEXT  PC
3818 0000
-G100

SAVE 38 PLMSAMP.COM とすればCOMファイルが出来る。 動作確認が出来た。