ベーシックマスターのソフトウェア(7)1200bps Turbo ROM(2)
「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'







ディスカッション
コメント一覧
まだ、コメントがありません