16ビットマイコンボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第82回]
●8086版BASICシステムサブルーチン(2)
8086版BASICシステムサブルーチンは[第71回]でお見せしました。
アドレス、機能はND80Z3.5のZB3BASICと同じ内容です。
ただCPUが違いますから使用するレジスタは当然異なります。
Z80の場合にはユーザーがマシン語プログラムを書いて、その中でシステムサブルーチンをコールして使うことができます。
しかしAM188(CPUコアは8088互換)の場合にはせっかくのシステムサブルーチンを使おうとしても、残念ながらZ80のように簡単にコールして使うわけにはいきません。
そこにはセグメントの壁が立ちはだかっています。
システムサブルーチンはCS(コードセグメント)で指定するエリアに置かれています。
同じCSのメモリ範囲にあるシステムプログラムはシステムサブルーチンをCALL命令でコールして使うことができます。
一方ユーザーエリアはデータの読み書きを多く行ないますからDS(データセグメント)で指定するメモリアドレスになります。
システムプログラムが大きいために、CS=DSにするわけにはいきません(セグメントのサイズは64KBです)。
システムの起動時にはCS=F0000(つまりF0000〜FFFFFのメモリ範囲)でDS=00000(00000〜0FFFFのメモリ範囲)なので両者は完全に分かれています。
そしてJPコマンドでユーザーのマシン語プログラムにジャンプするときだけ、CS=00000にして、ユーザプログラムを実行できるようにします。
8086(8088も同じ)はCSの範囲にあるプログラムしか実行することができません。
このときシステムサブルーチンはCSの範囲外となるため、ユーザプログラムからはCALLすることはできません。
[第71回]を書いた時点でそのことはわかっていたのですが、それをどうするかについて、まだ腹が決まっていませんでしたので、それについては今まで何も書きませんでした。
結局。
こういう場合にMSDOSが採用したのと同じ方法しかないなあ、という結論になりました。
MSDOSの場合、システムサブルーチンをユーザープログラムで使いたいときはINT 21を使います。
具体的にはAHレジスタにサブルーチンを指定するb入れて、そのほかパラメータが必要なときは、所定のレジスタに必要な値を入れた上でINT 21を実行します。
INT 21については[第22回]でほんの少し書いています。
それではMSDOSと同じようにINT 21を使うか、ということなのですが、いずれMSDOS互換システムも作りたいと思っていますので、そうするとここでINT 21を使うわけにはいきません。
INT 21を使わなくとも、まだINT 22〜INT FFまで自由に使えるのですから、あえてINT 21にこだわる必要はありません。
ということで、INT 22を使うことにしました。
使い方はINT 21と同じです。
システムサブルーチンの先頭から順番に番号をつけて、その番号をAHレジスタに入れてINT 22を実行します。
本日はちょっと時間がありませんから、具体的な使い方などについては次回に書くことにします。
今回は[第71回]のシステムサブルーチンの表にAHレジスタに入れる値(連番)を付加したものをお見せします。
表中記載のないものや、機能の欄にx印のついているものは、ずっと以前にZB3BASICのもとになったBASICシステムでは機能していたものの、現在は機能していないサブルーチンです。
| AH | アドレス | サブルーチン名(ニーモニック) | 機能 | 使用レジスタ |
| 00 | 1000 | ROMST | 8086版BASICにエントリする。全ての設定が初期化される | |
| 01 | 1003 | |||
| 02 | 1006 | SCEDT | x | |
| 03 | 1009 | |||
| 04 | 100C | SCRL | x | |
| 05 | 100F | CLR | 画面クリア | AL |
| 06 | 1012 | |||
| 07 | 1015 | ADISP | ALレジスタの値(ASCIIコード)を画面に表示する | AL |
| 08 | 1018 | DEDP | (DI)の値(ASCII)から後ろの文字列を(DI)=0Dかまたは(DI)=ALになるまで画面に表示する | AX、DI |
| 09 | 101B | CRLF | 改行する | AL |
| 0A | 101E | DPKIN | x | |
| 0B | 1021 | PRTR | x | |
| 0C | 1024 | SPJMP | (DI)→AL、AL=20ならDI=DI+1、AL≠20まで繰り返し | AL、DI |
| 0D | 1027 | HDCMP | SI−DIを計算、結果によってC、Z、Sフラグが変化する。SIは変化しない | SI、DI |
| 0E | 102A | HOWDP | HOW?表示後システムに戻る | |
| 0F | 102D | SRYDP | SORRY表示後システムに戻る | |
| 10 | 1030 | WHTDP | WHAT?表示後システムに戻る | |
| 11 | 1033 | REENT | システムに戻る | |
| 12 | 1036 | DECIN | (DI)の値から後ろの数値(ASCII、30〜39)を非数値になるまで読んで2進数に変換してSIにいれる | AL、BH、DX、SI、DI |
| 13 | 1039 | SPCDP | 1桁の空白を表示する | AL |
| 14 | 103C | INKEY | x | |
| 15 | 103F | ASHX1 | ASCII→HEX1桁変換。ALの値が30−39、41−46のとき00−09、0A−0FをALに入れる | AL |
| 16 | 1042 | ASHX2 | ASCII→HEX2桁変換。DXの値(ASCII2桁)をHEXに変換、DHに入れる | AL、DX |
| 17 | 1045 | ASHX4 | ASCII→HEX4桁変換。(DI)〜(DI+3)の値(ASCII4桁)をHEXに変換、DXに入れる。実行後DI=DI+4になる | AL、BH、DX、DI |
| 18 | 1048 | HXDP1 | ALの値(下位4ビット)を16進数1桁で表示する | AL |
| 19 | 104B | HXDP2 | DHの値を16進数2桁で表示する | AL、DH |
| 1A | 104E | HXDP4 | DXの値を16進数4桁で表示する | AL、DX |
| 1B | 1051 | ADRD | (DI)〜(DI+8)の値”aaaa,bbbb”(aaaa、bbbbはASCII表現の16進数)を読み、BX=aaaa、DX=bbbbにする。実行後DI=DI+9になる。 | AL、BX、DX、DI |
| 1C | 1054 | BREAK | x | |
| 1D | 1057 | BRSP | x | |
| 1E | 105A | LDISP | BASIC1行表示 | |
| 1F | 105D | DECDP | SIの値を符号付10進数で表示する | AL、BX、DX、SI |
| 20 | 1060 | HLNEG | SIが負数のとき−SI→SI、BHのビット7を反転する | BH、SI |
| 21 | 1063 | DIV | SI/DI→BX 余りはSIに。計算後DIは変化しない | AX、BX、DX、SI、DI |
| 22 | 1066 | BITDP | ALの値をビット表示する | AL、BX |
| 23 | 1069 | LDSP1 | BASIC1行表示 | |
| 24 | 106C | ATMKCK | x | |
| 25 | 106F | HLNG2 | −SI→SI、BHのビット7を反転する | BH、SI |
| 26 | 1072 | LSRC1 | BASIC行サーチ | |
| 27 | 1075 | LSRC2 | BASIC行サーチ | |
| 28 | 1078 | LSRC0 | BASIC行サーチ | |
| 29 | 107B | CRLF | 改行する | AL |
| 2A | 107E | ASH22 | ASCII→HEX2桁変換。(DI)〜(DI+1)の値(ASCII2桁)をHEXに変換、AL、DLに入れる。実行後DI=DI+2になる | AL、DI、DX |
| 2B | 1081 | MOVE | (BX)〜(SI)の値を(DI)〜にCOPYする | BX、CX、SI、DI |
| 2C | 1084 | ADRD3 | (DI)〜(DI+13)の値”aaaa,bbbb,cccc”(aaaa、bbbb、ccccはASCII表現の16進数)を読み、BX=aaaa、SI=bbbb、DI=ccccにする。 | AL、BX、DX、SI、DI |
| 2D | 1087 | DINS | (DI)の値から後ろの数値(ASCII、30〜39)を非数値になるまで読んで2進数に変換してDXにいれる。オーバフローしたときはDH=FFになる | AL、BX、DX、DI |
| 2E | 108A | BRKCK | x | |
| 2F | 108D | CLRNT | x | |
| 30 | 1090 | BRSP2 | x | |
| 31 | 1093 | LSC0 | BASIC行サーチ | |
| 32 | 1096 | LSC1 | BASIC行サーチ | |
| 33 | 1099 | LSC2 | BASIC行サーチ | |
| 34 | 109C | VDPS | BASIC変数名表示 | |
| 35 | 109F | CMDP | BASICコマンド名表示 | |
| 36 | 10A2 | LDSP2 | BASIC1行表示(行番号より後ろ) | |
| 37 | 10A5 | PRT0 | 82C55に接続したセントロニクスプリンタにAの値(ASCII)を1字印刷 | AL |
| 38 | 10A8 | ERRDP | ERR:に続いてAの値が10進数2桁で表示される | AX、BX、DX、SI、DI |
| 39 | 10AB | ADSPS | Aレジスタの値(ASCIIコード)を画面に表示する | |
| 3A | 10AE | SIN | ND80Zモニタのシリアル入力ルーチンをCALLする | AL |
表中BASIC行、BASIC命令などに関係するサブルーチンはBASICの編集、実行に使用されるサブルーチンなので汎用としては使えません。
私自身の備忘録も兼ねているため表中に記載しましたが、特殊目的のため詳細については省略しています。
16ビットマイコンボードの製作[第82回]
2018.9.8upload
前へ
次へ
ホームページトップへ戻る