見出し画像

CP/M-68Kを移植していく Part 2

CP/M の入手先

OPERATING SYSTEMS に、CP/M-68K 1.3 のバイナリがあります。
ZIPを解凍したら9個のディスクイメージが得られます。DISK8の中にある CPM15000.SR が、CCP と BDOS をまとめたものです。これにBIOSを作ってリンクすれば、移植はOKのはずです。リンクに必要なアドレスは、同じディスクイメージ中の CPM15000.MAP を参照すると得られます。

バイナリデータを取り出す
CPM15000.SRは、モトローラSレコードフォーマットです。バイナリデータを得るには変換ツールが必要なわけですが、よくわからなかったので、Wikipedia でSレコードの情報を調べて Python で変換ツールを作りました。

#! /usr/bin/env python3

import sys

args = sys.argv

if len(args) != 3:
    print('Usage : sr2bin srfile binfile')
    exit(1)

inf =  open(args[1], 'r')
lines = inf.readlines()

outf = open(args[2], 'wb')

# S record format
# S2 24 015000 4EF9000150504EF90001504A2043502F4D2D36384B2056312E3320434F505952 F6

addr = 0
dsize = 0
data = ''
for rec in lines:
    type = rec[:2]
    size = int(rec[2:4], 16)
    
    if type == 'S2':
        data = rec[10:10 + size * 2 - 8]
        dsize = len(data) // 2
    elif type == 'S9':
        break

    for offset in range(dsize):
        bdata = int(data[offset * 2:offset * 2 + 2], 16).to_bytes(1)
        outf.write(bdata)
        addr += 1

for offset in range(0x6000 - addr):
    outf.write(0xff.to_bytes(1))

inf.close()
outf.close()

この変換ツールはかなり手抜きで、アドレスは連続していると仮定し、チェックサムも確認せずゴリゴリ変換します。変換の最後に、サイズが24576バイトになるように後ろに0を埋めています。これはリンクに都合が良いためです。

BIOS とのリンク
CPM15000は、メモリ上で0x15000から配置される CCP + BDOS です。 CPM15000.MAP を見てみると、下のようになっています。

_submit 	   1A244 global bss
_morecmd	   1A246 global bss
_autost 	   1A1BE global bss
_usercmd	   1A1BF global bss
_ccp    	   150BC global text
_patch  	   1A248 global bss
cpm     	   15000 global text
_bdos   	   150CA global text
         :  
               :
_init   	   1B000 equ global abs
               :

cpm のアドレスが 0x15000 になっています。リンクに重要なのは、BIOSの先頭アドレスの_init と、CCPのエントリポイントの_ccp です。ちょっとまだ確証はないのですが、BIOSは、0x1B000 から始まり、WARM BOOT で _CCPにジャンプするコードを書くだけでOKのようです。
先のSレコードからバイナリデータに変換するコードで、24576バイトに調整しているのは、CPM15000 と BIOS とのリンクを単純にファイル結合だけで済むようにできるからです。
CP/M-8000 を移植したときの苦労を考えると、ちょっと信じられないくらい簡単なので、本当にこれだけなのか?まだ確証が持ててないのですが。


いいなと思ったら応援しよう!