マイコン独立大作戦
CRT/VGAIF+KEYIF+SDCARDIFボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
WindowsパソコンにUSB接続して使う現行方式はそれなりに便利ではありますが、ときとしてWindows
のしがらみから開放されて、小さいながらも独立した一個のパソコンとして機能したいと思うこともあります。
昔はそれが普通のことだったのですが、安価なCRTディスプレイが生産中止となって久しい今日ではそれ
は叶わぬことと諦めていたのですが…。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[総合第16回]
●画面表示テストプログラム
前回はAM188マイコンボードで実行するVGA画面表示テストプログラムをお見せしました。
AM188は8086互換CPUなので8086のアセンブラプログラムです。
8080やZ80の機械語とは違って8086の機械語は命令数が非常に多く、またJMP命令が相対ジャンプ命令なので8080やZ80のように機械語で直接プログラムを組むのは困難です。
アセンブラのニーモニック命令を使ってソースプログラムを作成してから、それを8086アセンブラで機械語プログラムに翻訳します。
ここで使っております8086アセンブラも以前に自作した当社オリジナルのアセンブラです。
この8086アセンブラもAM188マイコンボードの付属ソフトとするつもりです。
前回はプログラムリストをお見せしただけで終ってしまいましたので、今回はその説明をいたします。
2017/2/18 7:225 vgatest1.LST [00001] ;;; display test [00002] ;17/2/18 [00003] ; [00004] ORG=8000 [00005] ; [00006] START=F055 [00007] ; [00008] 8000 BAD080 MOV DX,80D0 [00009] 8003 B0FF MOV AL,FF [00010] 8005 EE OUT DX,AL [00011] 8006 BB00F8 MOV BX,F800 [00012] 8009 881F LOOP:MOV [BX],BL [00013] 800B 43 INC BX [00014] 800C 81FBD0FF CMP BX,FFD0 [00015] 8010 75F7 JNZ LOOP <8009> [00016] 8012 B000 MOV AL,00 [00017] 8014 EE OUT DX,AL [00018] 8015 EA55F000F0 JMPF F000:START [00019] ; LOOP =8009 START =F055 |
8086のアセンブラニーモニックは8080よりも分かり易いように思います。
8080ではMOV命令がオペランドの種類によって、MVI、LXIやLDAXなど個別のニーモニックになっていて、そこが面倒でした。
その点Z80アセンブラは全てをLDで統一してしまいました。
おそらく8080アセンブラの教訓でしょうか、8086アセンブラではすべてをMOVに統一しています。
命令の種類は多いのですが、普通よく使う命令として数をしぼれば、意外と使い易いのではと思います。
とはいえいろいろ約束事がありますから、それを少しずつ覚えながらプログラミングに慣れていく必要があります。
それではプログラムの説明です。
最初にIOアドレス80D0にFFを出力しています。
8086のIOアドレスは16ビットですが、AM188マイコンボードでは8080やZ80との互換性を考えて下位8ビットしか使いません。
モニタプログラムの起動時に上位8ビットは80Hに初期設定してあります。
8086のOUT命令ではアドレス指定はDXレジスタしか使えません。
またデータはAX(16ビット値)かAL(8ビット値)のみしか使えません。
OUT DX,AXまたはOUT DX,ALのどちらかを使います。
アドレスD0HにFFHをOUTすると、CRT/VGAインターフェースボード上のVRAM(アドレスF800〜FFCF)に書き込みができるようになります。
D0Hに00をOUTすると書き込み禁止状態になります。
マイコンボード上のRAMも同じアドレスでアクセスできるのですが、こちらは常時READ/WRITE可能で書き込み禁止にはなりません。
CRT/VGAインターフェースボード上のVRAMはWRITEオンリーで読み出しはできません。
D0HにFFHがOUTされると00がOUTされるまでの間はF800〜FFCFのアドレス範囲にデータを書き込むとマイコンボード上のRAMとCRT/VGAインターフェースボード上のVRAMに共に同じデータが書き込まれます。
VRAMに書かれたデータは直ちにその値を文字コードとするキャラクタが該当する画面上に表示されます。
F800〜FFCFのアドレス範囲をREADするとVRAMからではなくて、マイコンボード上のRAMから値が読み出されますが、先にそのアドレスに対して書き込みが実行されていれば、読み出される値はVRAMに書かれた値と一致しているはずです。
プログラムの説明に戻ります。
8086の命令ではメモリのアクセスは直接アドレスを指定することもレジスタでアドレスを指定して行なうこともできます。
ここではBXレジスタを使ってアドレスを指定しています。
MOV [BX],BL
でBXレジスタの下位8ビット(BL)の値がVRAMに書き込まれます。
そのあとINC BXでBXの値を+1し、その値がFFD0になるまでLOOPに戻って処理を続けます。
8080やZ80ではレジスタの値の比較は8ビットのみ可能で、しかもAレジスタに限って可能でした。
8086はそのような制約がないため、このプログラム例のように楽にプログラムできます。
CMP BX,FFD0
はBXの値をFFD0と比較しています。
比較はレジスタの値から置数の値を減算することで行なわれますが、レジスタの値は変化しません。
結果によってZ(ゼロ)フラグやC(キャリーフラグ)、S(サイン)フラグなどがセット、リセットされます。
次のJNZ LOOPによってCMP命令の結果が一致するまで(Zフラグがセットされるまで)LOOPへのジャンプが行なわれます。
JNZはJmp if Not Zeroです。
リストのJNZ LOOPの機械語命令を見てください。
75F7になっています。
75はJNZの機械語命令コードでF7がジャンプ先アドレスを示しています。
アドレス8009へのジャンプ命令ですが8009という値は使われません。
8080では必ず直接アドレスを指定しました。
Z80ではJR命令が8086と同じように相対ジャンプ命令でした。
8086の相対ジャンプ命令はそのジャンプ命令が置かれたアドレス位置から前にまたは先にどれだけジャンプするかを符号付8ビット2進数で示します。
こうすることでリロケータブル(再配置可能)なプログラムにすることができますが、移動するバイト数を計算で求めなければならないため、8080のようなハンドアセンブルは困難です。
8086アセンブラはJMP先にラベルを指定すれば、アセンブラが移動バイト数を算出してくれます。
ただそれだけだと、あとでデバッグのときにいちいち飛び先を変数テーブルで確認しなければならないので、利便性を考慮して、当社オリジナルの8086アセンブラではJMP先のアドレスがアセンブル時に<>で書き加えられます。
上のリストではソース部に<8009>と表記されていますが、これはアセンブル時にアセンブラによって追記されたもので、ソースプログラムにはありません。
参考までに、ソースプログラムを下に示します。
;;; display test ;17/2/18 ; ORG=8000 ; START=F055 ; MOV DX,80D0 MOV AL,FF OUT DX,AL MOV BX,F800 LOOP:MOV [BX],BL INC BX CMP BX,FFD0 JNZ LOOP MOV AL,00 OUT DX,AL JMPF F000:START ; |
説明が長くなってしまいました。
もうあと少し続きがあるのですが、時間がなくなってしまいました。
続きは次回にいたします。
CRT/VGAIF+KEYIF+SDCARDIFボードの製作[総合第16回]
2017.2.23upload
前へ
次へ
ホームページトップへ戻る