ベーシックマスターのソフトウェア(7)1200bps Turbo ROM(2)

BASICMASTER, 昔のパソコン

「1200bps Turbo ROM」の続き。今回は 1200bps Turbo ROM内のカセットI/Oルーチンについて。

1200bps化するためのキモは、出力する波数を1/4に減らすことである。

BMUGで配布されていた1200bpsルーチンは、モニタルーチンの波数を素直に減らしていたが、TurboROMは大幅にコードが書き換わっていてわかりにくい。

例えば、カセット入力時にスピーカーから音を出すために、$EE80に書き込みを行っていて、入力なのに書きこみがあって混乱する。

わざわざ広告で宣伝している機能なんだけど、これ必要な機能なのだろうか……

月刊I/O 1982年10月号 p.15 日立家電販売広告 より引用


1200bps 1バイト読み取りルーチン

1バイト読み込みルーチンの実体は$E703からだが、モニタの他の箇所からは$E633のJMP命令を経由して呼ばれている(メモリ節約のため)。

入力ルーチンなのに $EE80に書き込みを行っているのは、前述のようにカセットI/O時にスピーカーから音を出すため。

$E709のループで スタートビットが来るのを待ち、その後 $004C にストアされた数だけループして待つ。
$4B,$4Cの値は、テープスピードの変化に追従するために、プリアンブル部で調整している(と、思う。まだちゃんと理解できていない)。

もう一度$EE80をチェックし、ビットが立っていたら何もしないで帰る。2回チェックしてノイズを除去している。

その後、1bitずつ読み込みを行う。1bitあたりの待ち時間は$004Bに入っている。

ループ回数はストップビットも入れて9回。データとして必要なのは8bitなので、最後にROLAでストップビットをCarryに追い出している。

JSR $E703のあと Carryが立っていれば、ストップビット無しのエラーである。


ZE633   JMP     ZE703                    ;E633: 7E E7 03       '~..'
	:
ZE703   PSHB                             ;E703: 37             '7'
        LDAB    #$0F                     ;E704: C6 0F          '..'
        STAB    MEE80                    ;E706: F7 EE 80       '...'
ZE709   LDAB    MEE80                    ;E709: F6 EE 80       '...'
        BMI     ZE709                    ;E70C: 2B FB          '+.'
        LDAB    M004C                    ;E70E: D6 4C          '.L'
ZE710   DECB                             ;E710: 5A             'Z'
        BNE     ZE710                    ;E711: 26 FD          '&.'
        TST     MEE80                    ;E713: 7D EE 80       '}..'
ZE716   BMI     ZE732                    ;E716: 2B 1A          '+.'
        CLR     MEE80                    ;E718: 7F EE 80       '...'
        LDAB    #$09                     ;E71B: C6 09          '..'
ZE71D   PSHB                             ;E71D: 37             '7'
        LDAB    M004B                    ;E71E: D6 4B          '.K'
ZE720   DECB                             ;E720: 5A             'Z'
        BNE     ZE720                    ;E721: 26 FD          '&.'
        TST     MEE80                    ;E723: 7D EE 80       '}..'
        BMI     ZE72A                    ;E726: 2B 02          '+.'
        BRA     ZE72C                    ;E728: 20 02          ' .'
ZE72A   SEC                              ;E72A: 0D             '.'
        NOP                              ;E72B: 01             '.'
ZE72C   RORA                             ;E72C: 46             'F'
        PULB                             ;E72D: 33             '3'
        DECB                             ;E72E: 5A             'Z'
        BNE     ZE71D                    ;E72F: 26 EC          '&.'
        ROLA                             ;E731: 49             'I'
ZE732   PULB                             ;E732: 33             '3'
        RTS                              ;E733: 39             '9'


1bit出力ルーチン

Carry bitの内容を1bit出力する。上位ルーチンでBレジスタを使っているので、このルーチンでは Aレジスタしか使わない。

$E74Cと$E7CCが 2.4KHz 2波と1.2KHz 1波の出力を行っている。


ZE7B9   TPA                              ;E7B9: 07             '.'
        PSHA                             ;E7BA: 36             '6'
        LDAA    #$11                     ;E7BB: 86 11          '..'
ZE7BD   DECA                             ;E7BD: 4A             'J'
        BNE     ZE7BD                    ;E7BE: 26 FD          '&.'
        PULA                             ;E7C0: 32             '2'
        TAP                              ;E7C1: 06             '.'
        BCS     ZE7CC                    ;E7C2: 25 08          '%.'
ZE7C4   BSR     ZE7DB                    ;E7C4: 8D 15          '..'
        BSR     ZE7DF                    ;E7C6: 8D 17          '..'
        BSR     ZE7DF                    ;E7C8: 8D 15          '..'
        BRA     ZE7D4                    ;E7CA: 20 08          ' .'
ZE7CC   BSR     ZE7DF                    ;E7CC: 8D 11          '..'
        BSR     ZE7DB                    ;E7CE: 8D 0B          '..'
        BSR     ZE7DF                    ;E7D0: 8D 0D          '..'
        NOP                              ;E7D2: 01             '.'
        NOP                              ;E7D3: 01             '.'
ZE7D4   PULA                             ;E7D4: 32             '2'
        PSHA                             ;E7D5: 36             '6'
        CLRA                             ;E7D6: 4F             'O'
        STAA    MEE80                    ;E7D7: B7 EE 80       '...'
        RTS                              ;E7DA: 39             '9'
ZE7DB   LDAA    #$00                     ;E7DB: 86 00          '..'
        BRA     ZE7E3                    ;E7DD: 20 04          ' .'
ZE7DF   LDAA    #$0F                     ;E7DF: 86 0F          '..'
        NOP                              ;E7E1: 01             '.'
        NOP                              ;E7E2: 01             '.'
ZE7E3   STAA    MEE80                    ;E7E3: B7 EE 80       '...'
        LDAA    #$16                     ;E7E6: 86 16          '..'
ZE7E8   DECA                             ;E7E8: 4A             'J'
        BNE     ZE7E8                    ;E7E9: 26 FD          '&.'
        RTS                              ;E7EB: 39             '9'


1バイト出力ルーチン

Bレジスタに出力したい値を読み込んで、RORBで下から1bitずつ出力していく。

$E7A9の SECはストップビットの分の設定。

ループカウントも SECで設定したビットが無くなるまで(ストップビットを送るまで)のシフトになっていて、ループカウンタを省略している。


ZE79E   LDAB    $01,X                    ;E79E: E6 01          '..'
ZE7A0   LDAA    #$0E                     ;E7A0: 86 0E          '..'
ZE7A2   DECA                             ;E7A2: 4A             'J'
        BNE     ZE7A2                    ;E7A3: 26 FD          '&.'
        NOP                              ;E7A5: 01             '.'
        BSR     ZE7C4                    ;E7A6: 8D 1C          '..'
        NOP                              ;E7A8: 01             '.'
        SEC                              ;E7A9: 0D             '.'
        RORB                             ;E7AA: 56             'V'
ZE7AB   BSR     ZE7B9                    ;E7AB: 8D 0C          '..'
        LSRB                             ;E7AD: 54             'T'
        BNE     ZE7AB                    ;E7AE: 26 FB          '&.'
        BSR     ZE7B9                    ;E7B0: 8D 07          '..'
        NOP                              ;E7B2: 01             '.'
        NOP                              ;E7B3: 01             '.'
        SEC                              ;E7B4: 0D             '.'
        BSR     ZE7B9                    ;E7B5: 8D 02          '..'
        INX                              ;E7B7: 08             '.'
        RTS                              ;E7B8: 39             '9'