ROPOKO 移植版紹介特設ページ



MZ-700 をオリジナルとする話題沸騰のアドベンチャーゲームを

PC-6001mk2 以降 / PC-8801mk2SR 以降でも遊べる!ということをお伝えするページです。



■ 移植キットはこちらからどうぞ

オリジナル版は Tookato 氏の Booth サイトより購入できます。
移植キットは ver. 1.3.1 に対応しています。
https://tookato.booth.pm/items/3736517


PC-6001mk2 以降は以下のページから。
https://github.com/meltycode/ROPOKO60

PC-8801mk2SR 以降は以下のページから。
https://github.com/meltycode/ROPOKO88


移植キットは無料です。使用方法と注意書きをよく読んでお使いください。

■ 移植版についての小話

色々小ネタはあるのですが、専門的な上に局所的な話でしかないので思い出したら書きます。

MZ の方で面白かったのは、例えば「◢」のキャラを左右反転したら「◣」にするなど、各文字に対応が記述されており、
これによって線対称のパーツは半分だけデータを持っておけばよい省データ構造になっていたことでした。


PC88 の描画は以下のようになっています。


;a=character
;c=attribute
n_putchr:
    or        a
    jp        z,n_put00    ;$00=空白
    cp        $43
    jp        z,n_put43    ;$43=■
    cp        $EF
    jp        z,n_putEF    ;$EF=網掛

    push      de
    cp        $C0                       ;かなバンク $C0-$FF にフォント2倍テーブルを上書きしているのでカナバンクに読み替え
    jr        c,.safe
    res       7,c
.safe:
    ld        l,a
    ld        h,$F0 >> 3                ;<< 3 したときに $F000 + a * 8 になるように

    ld        a,c
    and       %01110111
    ld        (WorkAtr),a
    xor       c                        ;アトリビュートの bit7=1 なら小文字/ひらがなバンクへ($F800-)
    jp        p,.skip
    inc       h                        ;$F8 >> 3 相当
.skip:
    add       hl,hl
    add       hl,hl
    add       hl,hl                    ;hl=font address

    ld        d,BitTable >> 8          ;de=BitTable 256byte * 2 ビットパターンを横 2 倍にする
    ld        bc,FontBuffer            ;8byte * 2 PC88 用のフォントビットパターン格納バッファ. 16byte 桁上がりしない前提で inc c 使用.

    ld        a,%00001001              ;bit7=0:音源割込可 bit6=0:Non-ALU bit5=0:デジタル/アナログ mode bit4=0:TVRAM bit32=10:アナログ bit10:内部EROMバンク
    out       ($32),a

        rept    7
    ld        e,(hl)                    ;元ビットパターン
    ld        a,(de)                    ;左側
    ld        (bc),a
    inc       c                        ;buffer++
    inc       d                        ;-> BitTable.r

    ld        a,(de)                    ;右側
    ld        (bc),a
    inc       c                        ;buffer++
    dec       d                        ;-> BitTable.l
    inc       l                        ;fontdata++
        endm
    ld        e,(hl)
    ld        a,(de)
    ld        (bc),a
    inc       c                        ;buffer++
    inc       d                        ;-> BitTable.r
    ld        a,(de)
    ld        (bc),a

    ld        a,%01011001              ;bit7=0:音源割込可 bit6=1:ALU mode bit5=0:デジタル/アナログ mode bit4=1:Main RAM bit32=10:アナログ bit10:内部EROMバンク
    out       ($32),a

    pop       hl                       ;hl=VRAM
;ここまででバッファへのコピー完了

;--------------------------------------------------------------------------------------------------
;%_fff_bbb
;b=1 の場合、消去フェーズで OR で 1 を書き込む -> 該当プレーン全て 1 に
;b=0 の場合、消去フェーズで not AND で 1 を書き込む -> 該当プレーン全て 0 に
;
;b=0 f=1 の場合、書き込むフェーズで OR で 0->0 1->1
;b=1 f=0 の場合、書き込むフェーズで not AND で 0->1 1->0
;b=0 f=0 の場合、書き込むフェーズで NOP で 0->0 1->0
;b=1 f=1 の場合、書き込むフェーズで NOP で 0->1 1->1

;hl=vram(PC88)
DrawFont:
;   ld        a,%10000000              ;bit54=00 ポート$34の設定を使ったライト
;   out       ($35),a

    ld        a,(WorkAtr)
    and       %00000111                ;GRB プレーンに対して %xxx0xxx1 (BC のみ有) は OR オペレーション
    out       ($34),a                  ;GRB プレーンに対して %xxx0xxx0 (共になし) は not AND オペレーション

;消去フェーズ
;BC=1 の場合、OR で 1 を書き込み、該当プレーンのビットをセットする
;BC=0 の場合、not AND で 1 を書き込み、該当プレーンのビットをリセットする
    push      hl

    ld        a,$FF
    ld        bc,79
    rept    7
    ld        (hl),a                   ;左側
    inc       l
    ld        (hl),a                   ;右側
    add       hl,bc
    endm
    ld        (hl),a
    inc       l
    ld        (hl),a

;フォント書き込みフェーズ
;   ld        b,0                      ;ALU $34 レジスタ に設定する値
    ld        a,(WorkAtr)
    ld        c,a

    and       %00010001
    jp        pe,.b03                  ;xxx0xxx0 / xxx1xxx1 両対応
    rrca
    jr        c,.r                     ;B=not AND  (b0 のみ 1 = BC のみ)
;   set       0,b
    inc       b                        ;B=OR (b4 のみ 1 = FC のみ)
    jr        .r
.b03:
    ld        b,%00010001              ;B=NOP (消去フェーズで書き込んだ VRAM のまま)
.r:
    ld        a,c
    and       %00100010
    jp        pe,.r03
    bit       1,a
    jr        nz,.g                    ;R=not AND
    set       1,b                      ;R=OR
    jr        .g
.r03:
    set       1,b
    set       5,b                      ;B=NOP
.g:
    ld        a,c
    and       %01000100
    jp        pe,.g03
    bit       2,a
    jr        nz,.out                  ;G=not AND
    set       2,b                      ;G=OR
    jr        .out
.g03:
    set       2,b
    set       6,b                      ;G=NOP
.out:
    ld        a,b
    out       ($34),a                  ;ALU オペレーション

    pop       hl                       ;hl=VRAM Adr
    ld        bc,79

    di
    ld        (.stack + 1),sp          ;自己書き換え
    ld        sp,FontBuffer

        rept    7
    pop       de
    ld        (hl),e
    inc       l
    ld        (hl),d
    add       hl,bc
        endm

    pop       de
    ld        (hl),e
    inc       l
    ld        (hl),d

.stack:
    ld        sp,$0000
    ei
    ret

WorkAtr:      db    0                  ;アトリビュート値(MZ)


MZ の文字コード 1byte + アトリビュート 1byte が PC88 グラフィックの場合、横 16ドット(2byte) * 縦 8 ドット(8byte) * 8 色(x3) = 48byte も描きこまなければならず高速化が求められます。
MZ の元のコードでは実 VRAM のほかにバックバッファを持っており、キャラクタと背景パーツを合成したのち実 VRAM に転送する方式を取っています。
なので、ロポコが動くとメイン画面の 40x18 文字とアトリビュート合計で 1440 byte が転送されることになり、PC88 では一歩歩くだけで相当な負荷になります。

描画には 88SR 以降で搭載された ALU 機能を使っています。
ALU 機能では MZ の「背景色と文字色それぞれ選べる」という仕様を利用して、背景色で塗りつぶしたあと文字色で描画しなおすという方法をとりました。

また、頻出する「空白」「■」「網掛」キャラに関してはフォントデータを参照せず、直書き用の専用描画にして速度アップを図っています。

改良案としては、差分アップデートが考えられます。
PC88 独自のバッファを持っておき、更新されたところだけフラグを立てて再描画する方式です。
が、これはメモリ不足により断念しました。

また、フォントデータは 8 ドット(1byte) * 8 ドット(8byte) で持っているので PC88 版は毎文字、横 2 倍にする処理を挟んでいます。
これも最初から横 2 倍にしたデータで持っておけば恩恵が大きかったと思います。


音楽について。
MZ は 8253 という単音かつ音量調節も無いビープ音源を持っています。
音源ドライバは 20Hz で駆動されていて、演奏データは音長と音程に分かれています。

L2A8E:	;len start:$2A8E end:$2A9E
	db	$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
	db	$D9
L2AC3:	;seq start:$2AC3 end:$2AE2
	dw	$08EB,$07F2,$08EB,$07F2,$08EB,$07F2,$08EB,$0714,$08EB,$07F2,$08EB,$07F2,$08EB,$07F2,$08EB,$0714 


音楽として使えるオクターブ範囲も狭いので、慣れてくると 16 進数を見るだけで音程が浮かんでくるようになります。
PC60/PC88 では PSG 音源で演奏することになります。データを最初から変換しておけば負荷もかからないのですが、それほど手間でも無いので逐次変換しています。


;b = PSG reg(ch0=$00 ch1=$02)
;hl=input MZ value
ConvFRQ:
    add       hl,hl
    add       hl,hl

    ld        c,29                     ;7.17056290064102564 << 2 
    call      div168u

    ld        c,PSGREG
    out       (c),b                    ;R.0 / R.2
    inc       c
    out       (c),l
    dec       c

    inc       b
    out       (c),b                    ;R.1 / R.3
    inc       c
    out       (c),h
    dec       c

    srl       b
    set       3,b                      ;R.8 / R.9
    out       (c),b
    inc       c
    ld        a,10                     ;仮音量
    out       (c),a
    ret


音痴を避けるべく、ちょっとだけ精度を稼いでいます。
MZ は 894886.25Hz の分周、P6/88 は 124800Hz の分周なので 894886.25 / 124800 = 7.17... となります。


■ ヒント?

・マップは書いた方が良いです。行ったことのない部屋や様子の変わった部屋が把握できます。
・昔の PC ゲーム知識(割と濃い目の)が必要になりますが、ググればなんとか。詳しい人がいれば…。
・MZ のキーボード写真とかあると良いかもしれません。

▲ TOP