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
前へ
次へ
ホームページトップへ戻る