前回 6502CPUを秋月電子Bタイプユニバーサル基板へ搭載して動かすことができました。また、参考にしたGrantさんの回路とアドレスを合わせてあったので Grant’s BASIC 6502も動作確認できました。今後6502CPUの機械語プログラムを行うためにも、ぜひ機械語モニターを動かしてみたいところであります。
Universal Monitor for 6502を動かす
ソースディレクトリ構成
6502CPUで動く機械語モニターですが、Electrelicさん作のUniversal Monitorがソースつきで公開されていて機能も充実していますので、MC6850シリアルに対応してみたいと思いました。
上記のダウンロードページで「最新版」のソースをいただいてきて展開してみると、6502
というどんぴしゃのディレクトリがありまして、以下のような構成となっています。
.
├── 6502
├── config (構成定義ファイル)
└── dev (各種デバイス用ドライバ)
config
ディレクトリにある config.inc
には各種デバイス用ドライバで使うデバイスの入出力アドレスシンボル、初期化定数が定義されています。
dev
ディレクトリには、デバイスに合わせた入出力ルーチンが定義されたモジュールが入っています。
これらを修正してmake
してあげれば動くはず。ちなみにアセンブラはわたしが以前から使っている The Macro Assembler AS を使われています。
構成定義へMC6850用定義を追加
以下のようなかたちで、MC6850用定義を追加しました。条件アセンブリの構文としては 1
にしたところが有効で 0
にしたところは無効になるようです。
USE_DEV_6551 = 0
:
:
USE_DEV_6850 = 1
IF USE_DEV_6850
;;
ACIACS: EQU $A000 ; CTL Register
ACIADT: EQU $A001 ; DATA Register
ACIA_V1: EQU $03 ; RESET
ACIA_V2: EQU $15 ; Control: 8bit, 9600bps
ENDIF
:
:
USE_DEV_EMILY = 0
MC6850シリアルLSI(ACIA)の$A000(コントロールレジスター)と$A001(データレジスター)の番地に名前をつけます。今回のシステムはメモリーマップドI/Oなのでメモリーの一部の番地にI/Oチップがつながっているのです。
また、初期化用の値として2つのEQU定義を追加します。
MC6850(ACIA)用ドライバモジュール
次にconfig.inc
で定義したシンボルを使って、MC6850(ACIA)用ドライバモジュールを作ります。以下のように、INIT(初期化)、CONIN(1文字入力)、CONST(ステータスチェック)、CONOUT(1文字出力)の4ルーチンを定義するかたちになります。
;;;
;;; MCS6850 Console Driver
;;;
INIT:
LDA #ACIA_V1
STA ACIACS
LDA #ACIA_V2
STA ACIACS
RTS
CONIN:
LDA ACIACS
AND #$01
BEQ CONIN
LDA ACIADT
RTS
CONST:
LDA ACIACS
AND #$01
RTS
CONOUT:
PHA
CO0:
LDA ACIACS
AND #$02
BEQ CO0
PLA
STA ACIADT
RTS
MC6850のコントロールについては、SBC6800データパックのACIA版MIKBUGのソースを参考にさせていただきました。
- 初期化は
config.inc
で定義した$03(マスターリセット)と$15(8bit/ノンパリ/ストップビット1+1/16分周)を、MC6850(ACIA)のコントロールレジスターへ出力します。 - 1文字入力はACIAのコントロールレジスターをチェックして$01(Receive Data Register Full)が立つのを待ってデータレジスターから読み出します。
- ステータスチェックはACIAのステータスレジスター(コントロールレジスター)の$01(Receive Data Register Full)が立っているかどうかをアキュームレーターへ入れて返します。
- 1文字出力は、アキュームレーターに渡ってきた文字コードをACIAのデータレジスターへ出力します。送信前にステータスレジスターに$02(Transmit Data Register Empty)が立っていることを確認します。
makefileへの追加 & make実行
MC6850(ACIA)用デバイスルーチンを追加しましたので、makefileの以下の行にdev_6850.asm
を追記します。
devs := dev/dev_6551.asm dev/dev_emily.asm dev/dev_6850.asm
さて、あとはMacやLinuxの場合はGNU makeで make
コマンドでビルドできることになりますが、ここでいつもりハマりにはいりまして….以下のようなエラーで悩まされました。
6502CPUの条件ブランチ命令は8bitの範囲(-128〜+127バイトの範囲)でしか飛べません。Z80の相対ジャンプJR命令みたいな感じ。でも、どうみても近場のアドレスなのにToo BIG
だというエラーなわけで悩みました。
実は、コンパイラのビルドに起因するバグだったようで、そのときの私のMacに入っていたASLが2019-09-25 [1.42 Bld 150]
、最新は2020-04-05 [1.42 Bld 162]
です。
Windows版としてバイナリ配布されているasw(v1.42 Bld 162)を使ってアセンブリしたところ、何事もなくビルドが成功しました。….orz なんてことだ…
前方にあるラベルへのブランチが、ことごとくエラーとなっていたみたいです。
ROM焼きと稼働確認
若干のハマりはありましたが、ビルドに成功してIntelHex形式のオブジェクトデータができましたので、いつものTL866CSを使って256kBフラッシュROM(28C256型)に書き込みしまして稼働確認をしました。
ちなみに28C256型フラッシュROMへ書き込む際は、UniversalMonitorのIntelHexが$Fx00の場合、TL866CSの書き込みソフトでロードする際に $7×00へ読み込むと良いです。
以下がUniversal Monitor for 6502CPUのROMを搭載したマイコンの写真と、稼働させたときのTeraTERMのスクリーンショットです。
次回はLチカ
わたしの6502マイコン用としてビルドしたUniversal MonitorのソースとIntelHexファイルはgithubに添付してあります。ご参考まで。
機械語モニターが動いたので、次は6502CPUの機械語プログラムを作ってtomi9さん作のSBC-IOを使ってLEDチカチカ(Lチカ)させてみたいと思います。
その顛末はまた次回以降で…
コメント