SBC6303でズンドコチェック

ズンドコチェック実行画面 HD6301/HD6303

先日、UFT-8文字コードをターミナルに送ってあげればSBC6303でも日本語表示できることに気がつきました。

そこで今さらですがSBC6303で「ズンドコチェック」を日本語表記で実装してみます。

「ズンドコチェック」とは2016年に流行ったプログラムです

さまざまな言語で実装され、中にはPalo Alto Tiny BASICやZ80アセンブラなんてのもありました。

ズンドコチェックの実装

手順は以下の通りです。

  1. 2値の乱数を発生させる
  2. 乱数に応じて「ズン」あるいは「ドコ」を出力する
  3. 「ドコ」の前に「ズン」が4回以上出力されていたら「キ・ヨ・シ!」を出力して終了
  4. 3回以下であれば先頭に戻る

短いコードなので下記に全てを示します。

; zundoko program

        .cr     6301
        .lf     zundoko
        .tf     zundoko.s19,s19

; ********************************************************************
; * Include Files                                                    *
; ********************************************************************
        .in     HD6303R_chip.def
        .in     service_routine.def

; ********************************************************************
; * 変数 Variables                                                   *
; ********************************************************************
        .sm     RAM
        .or     $80
ZunCount        .bs     1       ; zunカウンタ
RndNumber       .bs     2       ; 乱数

; ********************************************************************
; * Program Start                                                    *
; ********************************************************************
        .sm     CODE
        .or     PROGRAM_START

start:  ldx     #MSG_START
        jsr     write_line
        jsr     read_char

set_seed:
.top    ldd     <FRC            ; Free run timer 読み出し
        beq     :top            ; Seedはゼロ以外
        std     <RndNumber

zundoko_check:
.top    clr     ZunCount
.loop   bsr     xorshift_16
        bmi     :doko
        ; 乱数が正数だったら
        ldx     #MSG_ZUN        ; print"zun"
        jsr     write_line
        inc     ZunCount        ; zunカウンタ += 1
        bra     :loop
.doko   ; 乱数が負数だったら
        ldx     #MSG_DOKO       ; print"doko"
        jsr     write_line
        tim     #%11111100,<ZunCount
        bne     :end
        ; zunカウンタ < 4
        bra     :top            ; zunカウンタ = 0
.end    ; zunカウンタ >= 4
        ldx     #MSG_KIYOSHI    ; print"kiyoshi"
        jsr     write_line
        bra     start


MSG_START       .az     "Hit any key.",#CR,#LF
MSG_ZUN         .hs     e382bae383b3.20.00 ; "ズン ",0
MSG_DOKO        .hs     e38389e382b3.20.00 ; "ドコ ",0
MSG_KIYOSHI     .hs     e382ade383bbe383a8e383bbe382b7efbc81 ; "キ・ヨ・シ!"
                .hs     0d0a.0d0a.00 ; "\n\n",0

; 16-bit xorshift pseudorandom number generator
xorshift_16:
        ldab    <RndNumber
        lsrb
        ldab    <RndNumber+1
        rorb
        eorb    <RndNumber
        stab    <RndNumber
        rorb
        eorb    <RndNumber+1
        stab    <RndNumber+1
        tba
        eora    <RndNumber
        staa    <RndNumber
        rts

こんな感じですね。

乱数の発生

何かキーを押してもらってプログラムをスタートします(27行目)。
その際にFRCの値を乱数のシード値とします(32行目)。
Xorshiftのシード値はゼロ以外でないといけないので、ゼロの場合はもう一度読み込みます(33行目)。

「ズン」「ドコ」「キ・ヨ・シ!」を出力する

xorshift_16ルーチンを呼ぶとDレジスタに$0001から$ffffまでの乱数が返ってきます。2値でいいので、Nフラグ(MSB)を見て分岐させます(39行目)。
「ズン」を出力するたびにカウンタ(ZunCount)を+1します。
「ドコ」を出力したらカウンタを確認して4以上になっていたら「キ・ヨ・シ!」を出力して終了します。3以下であればカウンタをクリアして先頭に戻ります。

4以上を判断するのにtim #%11111100,<ZunCountとしています。
4は二進数で表すと%00000100です。つまりカウンタの上位6ビットのいずれかが”1″になっているかどうかで4以上かどうか判断できます。
tim命令でZunCountと%11111100のANDを取り、Zフラグが立っていれば4未満、立っていなければ4以上です。

文字列について

SB-Assembler.ASディレクティブはASCIIコードしか解釈しないようです。

しょうがないのでPythonでやっつけの変換プログラムを作りました。

string = 'ズンドコキ・ヨ・シ!'
for i in string.encode('utf-8'):
        s = str(hex(i))
        print(s[2:4], end='')

# result
# e382bae383b3e38389e382b3e382ade383bbe383a8e383bbe382b7efbc81

この結果を.HSディレクティブで定義します。

そのうち、もう少しまともな変換ツールを作りたいです。

実行します

ズンドコチェックの結果

3回試してみましたが、うまく表示されました!

コメント

タイトルとURLをコピーしました