HD6303で電大版TINY BASIC [6801]
引き続き68系。
最初に作った基板HD6301/6303ボード。
ワンチップモードでのみ動作確認までだったが、実はその後外部ROM/RAM実装でLILBUGモニタの動作確認までOK。
すっかり間が空いてどこまで書いたかも忘れている。
CPUはHD6303Rに。オーバークロックでも動作するのだが、供給クロックを3MHzに。つまり動作クロックは0.75MHz。
実際は3.2MHzほどでているので0.8MHz動作。
こんな感じです。
このボードに前回MC6802ボードに搭載した電大版TINY BASICを入れる。
オリジナルソースをベースとせず、MC6802ボード用に変更したソースをベースにした。
元々MC6800系のBASICだから、MC6802ボードでは割込使用送受信関係ではまったとはいえ、それ以外は比較的簡単に移植できたがMC6801系は色々と変更部分がでてくる。
8bitの6800系はゼロページエリアが重要で、電大版Tiny BASICもワークエリアはゼロページが前提になっているが、
・ワンチップマイコンであるMC6801系はそのゼロページにペリフェラルI/Oのレジスタ群が存在する。
・せっかく搭載したLILBUGなのでそれベースにTINY BASICを動かすつもりだが、LILBUGはMIKBUGと比較して機能が豊富な分ワークエリアも多くとる。
・実は送受信関係のバッファ操作のためのワークもゼロページにとってしまっている。
・I/OレジスタとLILBUGのワークの除いて、BASIC用の変数A~Zのアドレス($82~52バイト)を固定して確保する必要がある。
I/Oレジスタ($0~固定)とLILBUG、独自ワークエリアとTINY BASICのワーク全てあわせて256バイトに収めること自体は可能だが、TINY BASICは特定のワーク変数からの相対位置をみていたりヘタに動かせない部分がある。
そういった制約の中で色々配置を換えて移植してみた。
ベースは前回のMC6802のものでゼロページ以外のメモリ配置はほぼ同じ。モニタがMIKBUGからLILBUGになったぐらい。
実はFORループ処理用のスタックが$0100になっており、つまりFORスタックはゼロページなのだが、これはMC6802ボードへの移植時にゼロページ外に出している。
今回はソースリストでのラベルBUFFER部分をゼロページ外に出すことにした。
これはキーボードから入力された文字を一時的にためていくところ。領域も比較的大きいので外に出す意味は大きい。
ただし、この部分が一番ワークの相対位置関係が決まってヘタに動かせない部分でもある。
このワーク部分のオリジナルソースを抜粋
ORGからBUFENDまでは色々ワーク変数があり、さらにBUFENDからBUFFERまでは別のワーク変数が4バイト存在するが省略。
ワークエリアが$1Aから始まっているのはA~Zの変数領域が$82からになるようにするため。
BUFENDにはBUFFERに入力された最後尾のアドレスが入る。
EXSPは計算等に使うスタック。変数のアドレスをEXSPが示す領域にプッシュ/ポップして計算処理をする。
実際はスタックに入れてプッシュ/ポップではなくインデクスレジスタに入れて、だが。
EXSPの初期値には自身のアドレスであるEXSTKが入る。
位置関係が固定されている最初のポイントがここで、スタックオーバーの判定にBUFENDと比較される。ようするにEXSPがバッファラスト(BUFEND)まできたらスタックオーバー。
その部分
これが下限チェックで上限チェックはこちら
ちにみに最大入力判定をBUFFER+70としているので、計算スタックの最小は10バイトと想定している模様。
この部分を確保したスタック領域の先頭、末尾か?で行うように変更。
EXSPの次の52バイトが変数A~Zの領域で$0082~の固定領域となっている。
入力行解析時、それが変数なら1bit左シフトし(Aなら$41→$82)変数アドレスを設定しているが、実は上位アドレスとしてBUFENDの中の値を設定している。
その部分の抜粋
アキュムレータAには文字コードが入っていて1bit左シフト下値が変数の下位アドレス。
アキュムレータBにBUFEND、つまりバッファ使用領域最後尾、n文字入力していたらアドレスBUFFER+nの上位を入れている。
これより変数領域はBUFFERと同じ上位アドレスで下位が$82からの52バイト、かつBUFFERの領域が256バイト境界をまたがないなら構わないことになる。
実際、「マイコンてづくり塾」のΛ-1の電大版TINY BASICは、BUFFERからまとめて$E400に配置している。
ただ本のソースリストは
となっていて、
これはリストのタイプミスなのか、それとも本当にそうしてしまっているのか、変数領域は$F482からになっていないし、にもかかわらず変数のアドレス算出はアルファベットの文字コードをASLAとオリジナルのまま。もっとも、$F4xxの領域はそれら以外に使ってないので、プログラムの想定通りではないが問題なく動くだろうとは思う。
話が少しそれたが、変数領域はゼロページのままにしておくので、BUFENDの値を入れずに固定値0を設定するように変更(CLRB)。
大きな変更は以上。
一部ワークエリアをゼロページ外に移したので、相対ジャンプが範囲外になってしまう所等を修正。
結局、一番動かしにくいワーク領域を移動させてしまったが、以上の修正で動作OK。
修正ではないがMC6801のタイマも動かしていて、約10ms周期で割込を掛けているがついでに変数Tをカウントアップするようにしてみた。
何かのベンチマークテスト用。
あと、これはMC6802版からだがBASICだけでなくモニタも含めて、改行をLFに統一。
オリジナルは入力の改行判定はCR。改行出力はCR+LFを送信している。
MC6802ボード用に修正した時点からそうだが、シリアルの送受信キューはともに256バイトと余裕たっぷりにとっているし、スタック領域変更ついでに多めにとったし、限られたリソースでBASICを動かすというTINY BASICの趣旨には反しているけども、今だからできる贅沢かな?
最初に作った基板HD6301/6303ボード。
ワンチップモードでのみ動作確認までだったが、実はその後外部ROM/RAM実装でLILBUGモニタの動作確認までOK。
すっかり間が空いてどこまで書いたかも忘れている。
CPUはHD6303Rに。オーバークロックでも動作するのだが、供給クロックを3MHzに。つまり動作クロックは0.75MHz。
実際は3.2MHzほどでているので0.8MHz動作。
こんな感じです。
このボードに前回MC6802ボードに搭載した電大版TINY BASICを入れる。
オリジナルソースをベースとせず、MC6802ボード用に変更したソースをベースにした。
元々MC6800系のBASICだから、MC6802ボードでは割込使用送受信関係ではまったとはいえ、それ以外は比較的簡単に移植できたがMC6801系は色々と変更部分がでてくる。
8bitの6800系はゼロページエリアが重要で、電大版Tiny BASICもワークエリアはゼロページが前提になっているが、
・ワンチップマイコンであるMC6801系はそのゼロページにペリフェラルI/Oのレジスタ群が存在する。
・せっかく搭載したLILBUGなのでそれベースにTINY BASICを動かすつもりだが、LILBUGはMIKBUGと比較して機能が豊富な分ワークエリアも多くとる。
・実は送受信関係のバッファ操作のためのワークもゼロページにとってしまっている。
・I/OレジスタとLILBUGのワークの除いて、BASIC用の変数A~Zのアドレス($82~52バイト)を固定して確保する必要がある。
I/Oレジスタ($0~固定)とLILBUG、独自ワークエリアとTINY BASICのワーク全てあわせて256バイトに収めること自体は可能だが、TINY BASICは特定のワーク変数からの相対位置をみていたりヘタに動かせない部分がある。
そういった制約の中で色々配置を換えて移植してみた。
ベースは前回のMC6802のものでゼロページ以外のメモリ配置はほぼ同じ。モニタがMIKBUGからLILBUGになったぐらい。
実はFORループ処理用のスタックが$0100になっており、つまりFORスタックはゼロページなのだが、これはMC6802ボードへの移植時にゼロページ外に出している。
今回はソースリストでのラベルBUFFER部分をゼロページ外に出すことにした。
これはキーボードから入力された文字を一時的にためていくところ。領域も比較的大きいので外に出す意味は大きい。
ただし、この部分が一番ワークの相対位置関係が決まってヘタに動かせない部分でもある。
このワーク部分のオリジナルソースを抜粋
ORG | $1A | |
BUFEND | RMB | 2 |
BUFFER | RMB | 80 |
EXSTK | EQU | * |
EXSP | RMB | 2 |
RMB | 52 |
ORGからBUFENDまでは色々ワーク変数があり、さらにBUFENDからBUFFERまでは別のワーク変数が4バイト存在するが省略。
ワークエリアが$1Aから始まっているのはA~Zの変数領域が$82からになるようにするため。
BUFENDにはBUFFERに入力された最後尾のアドレスが入る。
EXSPは計算等に使うスタック。変数のアドレスをEXSPが示す領域にプッシュ/ポップして計算処理をする。
実際はスタックに入れてプッシュ/ポップではなくインデクスレジスタに入れて、だが。
EXSPの初期値には自身のアドレスであるEXSTKが入る。
位置関係が固定されている最初のポイントがここで、スタックオーバーの判定にBUFENDと比較される。ようするにEXSPがバッファラスト(BUFEND)まできたらスタックオーバー。
その部分
LDX | EXSP | |
DEX | ||
DEX | ||
CPX | BUFEND | |
BEQ | ERR180 |
これが下限チェックで上限チェックはこちら
LDX | EXSP | |
CPX | #EXSTK | |
BEQ | ERR180 |
ちにみに最大入力判定をBUFFER+70としているので、計算スタックの最小は10バイトと想定している模様。
この部分を確保したスタック領域の先頭、末尾か?で行うように変更。
EXSPの次の52バイトが変数A~Zの領域で$0082~の固定領域となっている。
入力行解析時、それが変数なら1bit左シフトし(Aなら$41→$82)変数アドレスを設定しているが、実は上位アドレスとしてBUFENDの中の値を設定している。
その部分の抜粋
TSTV | BSR | SKB8 |
CMPA | #$40 | |
BEQ | ARRAY | |
CMPA | #'A | |
BCS | NOTV | |
CMPA | #'Z | |
BHI | NOTV | |
ASLA | ||
LDAB | BUFEND | |
INX | ||
RTS |
アキュムレータAには文字コードが入っていて1bit左シフト下値が変数の下位アドレス。
アキュムレータBにBUFEND、つまりバッファ使用領域最後尾、n文字入力していたらアドレスBUFFER+nの上位を入れている。
これより変数領域はBUFFERと同じ上位アドレスで下位が$82からの52バイト、かつBUFFERの領域が256バイト境界をまたがないなら構わないことになる。
実際、「マイコンてづくり塾」のΛ-1の電大版TINY BASICは、BUFFERからまとめて$E400に配置している。
ただ本のソースリストは
F400 | BUFFER | RMB | 80 |
EXSTK | EQU | * | |
F450 | EXSP | RMB | 2 |
F452 | RMB | 52 |
となっていて、
これはリストのタイプミスなのか、それとも本当にそうしてしまっているのか、変数領域は$F482からになっていないし、にもかかわらず変数のアドレス算出はアルファベットの文字コードをASLAとオリジナルのまま。もっとも、$F4xxの領域はそれら以外に使ってないので、プログラムの想定通りではないが問題なく動くだろうとは思う。
話が少しそれたが、変数領域はゼロページのままにしておくので、BUFENDの値を入れずに固定値0を設定するように変更(CLRB)。
大きな変更は以上。
一部ワークエリアをゼロページ外に移したので、相対ジャンプが範囲外になってしまう所等を修正。
結局、一番動かしにくいワーク領域を移動させてしまったが、以上の修正で動作OK。
修正ではないがMC6801のタイマも動かしていて、約10ms周期で割込を掛けているがついでに変数Tをカウントアップするようにしてみた。
何かのベンチマークテスト用。
あと、これはMC6802版からだがBASICだけでなくモニタも含めて、改行をLFに統一。
オリジナルは入力の改行判定はCR。改行出力はCR+LFを送信している。
MC6802ボード用に修正した時点からそうだが、シリアルの送受信キューはともに256バイトと余裕たっぷりにとっているし、スタック領域変更ついでに多めにとったし、限られたリソースでBASICを動かすというTINY BASICの趣旨には反しているけども、今だからできる贅沢かな?