電子ブロック工房 / Z80 https://www.rad51.net/blog/mycom/ IC・トランジスタで出来たコンピューターを設計・製作するためのブログ / Z80で遊ぶ ja Jeans CMS © Weblog http://backend.userland.com/rss https://www.rad51.net/jeans/skins/jeans/images/jeans2.gif 電子ブロック工房 https://www.rad51.net/blog/mycom/ KM-Z80 midi 進捗:Fuzix https://www.rad51.net/blog/mycom/?itemid=960 KM-Z80 midi 用のアプリケーション第三弾、FZ/KM midi (Fuzix 実行環境)を製作中。特徴は、次の通り。

1)Fuzix ver 0.3 (Tom's SBC用) が走る。
2)ディスプレイは液晶表示(NTSCビデオは非対応)
3)Fuzix内ではRAM領域に64K bytesを割り当て
4)USBメモリー上のディスクイメージファイルを仮想ドライブとして使用
5)仮想ドライブは、128 Mbytes のサイズ

実行中の様子。
2019-11-01-fuzix.jpg
使用方法は、FZ/KM webとほぼ同じ。

ソースコードの管理は、GitHubで行なっている
ダウンロードも、GitHubから

readme.txtに書いたとおり、起動の際は http://www.fuzix.org/ からTom's SBC用のディスクイメージファイルをダウンロードし、ファイル名を「FUZIXIMG.IDE」に変更してUSBメモリーにコピーして使用の事。なお、このディスクイメージファイルは、別記事に書いたとおり、編集したりファイルの追加や取り出しをしたりする事ができる。

ここでエミュレートしているPCは、Tom's SBCと呼ばれている物で、以下の特徴がある。

・RAMを64Kb、ROMを64Kb実装。
・クロックは、3.6864 MHz。
・I/Oポート38h-3Fhにラッチが接続されている。D0のみを使う。
・ラッチは、リセット時に全て出力L
・38hへの出力0で0000h-3FFFhにROM選択、1でRAM選択
・3FhはROMのA14に接続
・3EhはおそらくROMのA15に接続
・I/Oポート00h-03hはシリアル入出力。04h-07hも同じ
・I/Oポート10h-17hは、コンパクトフラッシュ制御

KM-Z80では、Z80のエミュレーションで、56KbのRAMしか割り当てする事ができない。そこで、足りない8Kbに付いては、スワップメモリーとしてファイルに落とす事で実現している。このため、実行が少し遅くなる。

起動におよそ一分半、シャットダウンにおよそ二分弱かかる。電源を切る前は、シャットダウン動作(shutdown)を、必ず行なう事。これを行なわずに電源を切ると、次回起動時にファイルシステムがちゃんと認識されなくなるので、注意。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=960 Fri, 01 Nov 2019 16:21:21 PDT ITEM960_20191101
KM-BASIC for MZ80K/MZ-700 ver 0.8を公開 https://www.rad51.net/blog/mycom/?itemid=918 http://www.vector.co.jp/soft/other/other/se499422.html

主な変更点は、以下の4つの関数を追加したことです。
・VAL()
・DEC$()
・INKEY()
・INPUT$()

初期のバージョンは、ユーザーからの入力を受け付ける機能がなく、そういったプログラムはマシン語を挿入するなどしないと出来ませんでした。これはうっかりしていました。Star Trek(ゲーム)でも作ろうかなと思って色々見ていた時に気がついた次第です。
今回のバージョンでそれを導入したので、ある程度のプログラムならまともに書けるようになったかなと思っています。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=918 Thu, 10 Dec 2015 11:58:30 PST ITEM918_20151210
KM-BASIC for MZ-80K/MZ-700 ver 0.6.8 https://www.rad51.net/blog/mycom/?itemid=866 Vectorでも公開の手続きを取りましたので、近日中にそちらにも現れるはずです。

ダウンロードはこちらから(ver 0.6.8)。
ダウンロードは、Vectorから

以下、readme.txtからです。

********************************************

           KM-BASIC ver 0.6.7-beta
       for KM-Z80/MZ-80K/MZ-80C/MZ-700

    Copyright (C) 2012 Katsumi Morimatsu

       kmorimatsu@users.sourceforge.jp
  http://hp.vector.co.jp/authors/VA016157/

********************************************

このライブラリはフリーソフトウェアです。あなたはこれを、フリーソフトウェ
ア財団によって発行されたGNU 劣等一般公衆利用許諾契約書(バージョン2.1 
か、希望によってはそれ以降のバージョンのうちどれか)の定める条件の下で
再頒布または改変することができます。

このライブラリは有用であることを願って頒布されますが、*全くの無保証* 
です。商業可能性の保証や特定の目的への適合性は、言外に示されたものも含
め全く存在しません。詳しくはGNU 劣等一般公衆利用許諾契約書をご覧くださ
い。
 
あなたはこのライブラリと共に、GNU 劣等一般公衆利用許諾契約書の複製物を
一部受け取ったはずです。もし受け取っていなければ、フリーソフトウェア財
団まで請求してください(宛先は the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA)。

GNU 劣等一般公衆利用許諾契約書(バージョン2.1)の非公式な日本語訳は、
次のURLで閲覧することができるかもしれません。
http://www.opensource.gr.jp/lesser/lgpl.ja.html

LGPL(v2.1)に基づくフリーソフトウェアとして扱われる限り再頒布可能です。

<概要>
KM-BASICは、MZ-80K/MZ-80C/MZ-700及びKM-Z80で使用可能な、整数型BASICです。
インタープリターですが、JITコンパイル形式で実行されるので、通常のインター
プリターより速く動作します。エディターは古のBASICと同じ、行番号形式です。

<序論>
MZ-80Kは、SHARPが1978年に発売した、8bitパーソナルコンピューターです。発
売当時、ほぼ同時期に発売された日立のベーシックマスターや、少し遅れて販売
されたNECのPC-8001と並んで、高級言語であるBASICを個人のレベルで使えるマイ
クロコンピューターとして、一世風靡しました。

MZ-80Kには、マウスなどのポインティングデバイスはなかったものの、文字や
グラフィックを表示・入力するためのディスプレイやキーボードを備え、当時高
性能のCPUであったZ80が、これまた当時は大容量であった20 KBのRAMで動きまし
た。

外部記憶装置としてカセットテープレコーダーが付属していました。読み書きの
速度は平均で1400ボーであり、これは当時の主流であったカンザスシティスタン
ダードの300ボートと比べて、夢のような速度でした。また、レコーダーが本体に
付属しているために読み書きの安定性も抜群でした。

このように、MZ-80Kは、今日のパーソナルコンピューターが持つ基本特性を、小
規模であるものの、ほとんど備えており、日本のパーソナルコンピューターのさ
きがけとも言える存在です。他方で、その構造はいたってシンプルであり、その
全回路図が公開されていました。MZ-80Kのこういった特性は、コンピューターの
動作原理を理解するうえで、貴重なものです。パーソナルコンピューターはその
後、発展に発展を遂げ、非常に複雑になりました。現在では、個人のレベルでこ
ういったコンピューターの全体像を把握することは、プロの方々でも難しいと言
えるでしょう。

今日、MZ-80K本体を購入することはかなり難しくなっています(まれにオーク
ションに出品されることがあります)。しかし、そのアッパーコンパチブルであ
るMZ-700のエミュレーター(MZ-700 Emulator MZ700WIN For Windows)が公開され
ているので、現在でもそれがどんなものであったのかを伺い知ることが出来ます。
また、拙作のMZ-80Kレプリカ(KM-Z80; 回路図及びプログラムを公開済み)を作
成すれば、MZ-80Kの動作環境を再現することが出来ます。

こういったエミュレーターやレプリカなどを利用する上でしばしば問題になる
のが、その上で動作するプログラムです。ROM上にある基本プログラム(ここで
は、モニタープログラムと呼ぶことにします)は、コンピューターの動作に必須
ですが、それを販売した会社(MZ-80Kの場合は、SHARP)が著作権を有するため、
オリジナルのコンピューターを有しているのでない限り、使用することが出来ま
せん。Apple Iのレプリカの場合、モニタープログラムを作成した技術者から許
可を得ることで、この問題をクリアーしています。MZ80Kの場合、オリジナルの
モニタープログラム(SP-1002)とは著作権の異なるモニタープログラムが公表さ
れており(MZ-NEW MONITER)、それを用いることでこの問題をクリアーしていま
す。

MZ-80Kのようなレトロコンピューターを考える上で、高級言語であるBASICは
切っても切り離せない存在です。MZ-80K用には、SHARPオリジナルのSP-5010や
SP-5030、ハドソンソフトのHu-BASICなどがあります。いずれもカセットテープ
に入った状態で販売されていましたが、今日、こういったソフトウェアを入手
することはほとんど不可能です。

そこで、MZ-700エミュレーターやMZ-80Kレプリカ上で使用可能なBASICを、独
自に作成することにしました。オープンソースのフリーソフトウェアとして公
開しますので、どなたでも自由に使用でき、また、改変する事も可能です。ア
センブラではなく、Cを使って開発しましたので、コンパクトさには欠けます
が、改変して使用することが容易です。

<使用方法>
添付のrelease.mztファイルを、まるくん(さん)製作のMZ-700 Emulatorで使用
するか、のりのりさん製作のmzt2wavを用いてwavファイルに変換し、MZ-80Kなど
の実機で使用してください。MZ-700 Emulator及びmzt2wavの入手先は、このファ
イル末尾の「参考リンク」にあります。

KM-BASICをロードすると、

LOADING KM-BASIC
BASIC KM-1000
3FB6-CFFF
36938 BYTES FREE

と表示され(数字部分はバージョンと環境に依存)BASICプログラムを入力可能な
状態になります。行番号に続けてコードを入力することで、プログラムの編集が
可能です。行番号を省いてコードだけを入力すると、そのコードがそのまま実行
されます。

<利用可能な変数型>
利用できる変数の型は、16ビット符号付整数(-32768 ~ +32767)と、40文字以
下の文字列の2種類です。文字列の末端部には0x0Dが付加されます。

A-Zの26個の整数型変数が利用可能です。文字列として扱う場合はA$のように記
述します。ただし、A(整数型)とA$(文字列型)を同時に使用することは出来ま
せん。

整数型の定数は、10進法で記述します。16進法を使う場合、「$1200」のよう
に、頭に「$」を付加してください。

文字列方の定数は、「"」で囲って記述してください。「"」を使用する場合は、
「CHR$($22)」のように記述することが出来ます。

<命令>
以下、x, y, zは整数値を、x$, y$, z$は文字列を指します。xxx, yyy, zzz, www
は任意のステートメントを指します。[ ]は省略可能で有る事を示します。

命令同士を「:」で区切ることにより、一行で複数のコマンドを処理すること
が出来ます。

LIST [xxx] [-] [yyy]
	xxx行目からyyy行目までのプログラムを表示する。
RUN [xxx]
	プログラムを実行する(指定された場合、xxx行目から)
SAVE
	プログラムをカセットテープに保存する。
LOAD
	プログラムをカセットテープから呼び出す。
NEW
	プログラムを消去する
BYE
	MONITORプロンプトに戻る
REM xxx
	何も実行しない
[LET] x=yyy
	yで示された計算結果を、xに代入する。「LET」は省略可。
[LET] x$=yyy
	yyyで示された文字列(もしくは連結結果)を、x$に代入する。「LET」は省略可。
DIM xxx [, yyy [, zzz [, ... ]]]
	整数型の一次元配列を割り当てる。
	xxx,yyy,zzzは、例えば「A(10)」のように記述する。この場合、A(0)から
	A(10)までの11個の整数型変数が確保される。
CLEAR
	すべての文字列型変数と整数型配列を破棄し、整数値を0とする。
PRINT [ xまたはx$ [ ,または; [ yまたはy$ [ ... ]]]]
	ディスプレイに、整数値または文字列を表示する。「;」を使用した場合、
	次の表示が続けて行われる。「,」を使用した場合、10文字ずつに区切っ
	て表示される。どちらも使用しない場合、次の表示は行を変えて行われる。
POKE x,y
	xで示される物理的アドレスに、yで示される値(1バイト値)を書き込む。
EXEC xxx[yyy[zzz[...]]]
	機械語を実行する。ただし、xxx,yyy,zzzは2文字のHEXで示された1バイト値。
IF x THEN yyy [ ELSE zzz ]
	xが0以外のとき、yyyを、0のときzzzを実行
FOR x=yyy TO zzz [ STEP www ]
NEXT
	yyyで示された計算結果をxに代入し、xの値がzzzになるまで次のNEXT文までの
	ステートメントを、繰り返し実行する。繰り返しのたび、xの値はwwwずつ増加
	する(省略された場合は1ずつ)。「NEXT」の次に何も記述しないことに注意。
GOTO xxx
	xxx行目に移動する。
GOSUB xxx
	現在の実行位置を記憶し、xxx行目に移動する。
RETURN
	最後に実行されたGOSUB文の次のステートメントに移動する。
END
	BASICプロンプトに戻る

<関数>
以下、x, y, zは整数値を、x$, y$, z$は文字列を指します。[ ]は省略可能で有る事
を示します。

PEEK(x)
	xで示される物理アドレスから1バイト読み取り、返す。
RND()
	0から32767までの擬似乱数を返す。
ABS(x)
	xの絶対値を返す。
SGN(x)
	xの符号(-1, 0, または1)を返す。
NOT(x)
	x=0の場合に1を、そうでない場合に0を返す。
ASC(x$)
	文字列の最初の一文字の、アスキーコードを返す。
LEN(x$)
	文字列の長さを返す。
STRNCMP(x$,y$,z)
	2つの文字列のうちz文字を比較し、結果を返す。同じ文字列の場合は0。
CHR$(x)
	xをアスキーコードとする文字を返す。
HEX$(x [,y])
	xの値を、16進数の文字列として返す。yが指定された場合、yバイト長の
	文字列になる。
A$(x [,y])など
	xの値が0の場合、文字列全体を返す。
	xの値が精の場合、xで示される位置より右側の文字列を返す。
	xの値が負のとき、文字列の右側x文字を返す。
	yが指定された場合、y文字分の文字列を返す。

<演算子>
x + y
	整数加算
x - y
	整数減算
x * y
	整数乗算
x / y
	整数除算
x % y
	整数剰余
x = y
	2つの整数値が等しい場合に1、そうでないときに0
x != y
	2つの整数値が等しい場合に0、そうでないときに1
x < y
	xがyより小さい場合に1、そうでないときに0
x <= y
	xがyより小さいか等しい場合に1、そうでないときに0
x > y
	xがyより多きい場合に1、そうでないときに0
x >= y
	xがyより多きいか等しい場合に1、そうでないときに0
x AND y
	xとyの値のビットごとの AND(論理積でないことに注意)
x OR y
	xとyの値のビットごとの OR
x XOR y
	xとyの値のビットごとの XOR
x$ + y$
	文字列の連結(LET文でのみ使用可)

<参考リンク>

「Enri's Home PAGE (mz-80K)」
http://www2.odn.ne.jp/~haf09260/Mz80k/EnrMzk.htm
Enriさんのページ。MZ-80Kに関して、さまざまな解析がなされている。MZ-80Kの
回路図も公開されている。

「MZ-700 Emulator MZ700WIN For Windows」
http://retropc.net/mz-memories/mz700/
MZ-700エミュレーターを紹介している、まるくん(さん)のページ。
"MZ-NEW MONITOR"と"mzt2wav"のダウンロードも、こちら。

「KM-Z80(MZ-80K互換マイコン)紹介編」
http://www.rad51.net/blog/mycom/index.php?itemid=846
拙作のMZ-80K互換マイコンの紹介ページ。
]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=866 Thu, 20 Sep 2012 14:27:28 PDT ITEM866_20120920
SAVE/LOADを実装 https://www.rad51.net/blog/mycom/?itemid=865
2012-09-07-saveload.png

これで、完成かな。後は、コードを見直してファイルサイズを小さくすることぐらい(今のものでも、12 KBytes以内に収まっている)。近いうちに、Vectorにでもアップロードして、公開しよう。 ]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=865 Fri, 07 Sep 2012 17:47:04 PDT ITEM865_20120907
関数を幾つか実装 https://www.rad51.net/blog/mycom/?itemid=864
2012-07-31-funcs.png

実装したのは、ABS/SGN/NOT/ASC/LENの5つ。これに加えてSTRNCMPを実装すれば、ほぼ予定通りの機能を持ったBASICがとりあえず完成する。12kb以内には収まりそうだ。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=864 Tue, 31 Jul 2012 19:56:48 PDT ITEM864_20120731
擬似乱数を実装 https://www.rad51.net/blog/mycom/?itemid=863
2012-07-31-rnd.png

はじめ、stdlib.hにあるrand()関数を使用しようとしたが、スタティック変数の初期化部分が現在のSDCCを使用したMZ-80用のプログラミングにあわないため、自分で書くことにした。よく使われる32ビット整数に定数を掛けて定数を足すやり方で実装しようとしたところ、32ビット演算用のCのライブラリの大きさなのだかの理由で、2kbの大きさになってしまった。コードがこんなに大きくては使えない。色々調べた結果、Microchip社のMathユーティリティ(AN544)に載っている方法を採用することになった。該当部分のコードは、以下のとおり。

void getRand(){
	__asm
		LD HL,(#_g_seed)
		LD B,#15
		
	loop:
		LD A,H
		RLA    // bit 14 of HL will be in bit 7 of A
		XOR H  // XOR of bits 15 and 14 of HL will be in bit 7 of A
		RLA    // XOR of bits 15 and 14 of HL will be in carry bit
		RLA    // XOR of bits 15 and 14 of HL will be in bit 0 of A
		LD D,A // Store XOR value in D register
		LD A,H // bit 12 of HL will be in bit 4 of A
		RRA    // bit 12 of HL will be in bit 3 of A
		XOR L  // XOR of bits 12 and 3 of HL will be in bit 3 of A
		RRA    // XOR of bits 12 and 3 of HL will be in bit 2 of A
		RRA    // XOR of bits 12 and 3 of HL will be in bit 1 of A
		RRA    // XOR of bits 12 and 3 of HL will be in bit 0 of A
		XOR D
		AND #0x01
		ADD HL,HL
		OR L
		LD L,A
		DJNZ loop
		
		LD (#_g_seed),HL
		LD A,H
		AND #0x7F
		LD D,A
		LD E,L
	__endasm;
}

ビット15, 14, 12, 3のXORを取り、それをビット0に入れるような方法で左シフトする。この変換を1回行っただけだと、発生する乱数が前の乱数の2倍に近いような値に偏るため、15回演算した後に下位15ビット(0-32767)を返すようにしてある。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=863 Tue, 31 Jul 2012 14:01:46 PDT ITEM863_20120731
DIM文及びPEEK/POKE文を実装 https://www.rad51.net/blog/mycom/?itemid=862
2012-07-30-dim.png

2012-07-30-peekpoke.png

これらの機能は、文法的には異なるが、機能としては似通っている。DIM文では、指定された長さの領域のメモリが確保され、そのメモリへのポインタが変数に代入される。Cにおける、(int*)のように、働く。ここでintは16ビット整数であるので、配列の使用は、16ビット整数値のメモリへの読み書きと同義である。他方、PEEK()とPOKE()は、8ビット整数の読み書きに相当する。

「DIM A(10)」と記述すると、A(0)からA(10)までの、11個の変数が確保される。従って、添え字を0から始めても1から始めても、問題なく動作する。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=862 Mon, 30 Jul 2012 14:22:57 PDT ITEM862_20120730
IF/GOSUB文を実装 https://www.rad51.net/blog/mycom/?itemid=861
2012-07-30-ifgosub.png

IF文は、整数値が0が否かで分岐する仕様。 別途、比較演算子(=, !=, <, >, <=, >=)を実装しているので、それを使うことになる。

GOSUB-RETURNは、アセンブラのCALL-RETにそのまま対応している。スタックの許容範囲内で、入れ子的に使用することが可能。スタックを用いているのは、他にFOR-NEXTや整数値演算部分がある。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=861 Mon, 30 Jul 2012 11:43:33 PDT ITEM861_20120730
RUN命令を実装 https://www.rad51.net/blog/mycom/?itemid=860
2012-07-26-run.png

「RUN」命令部分のコードは簡単に書いたのだが、行をまたいでのプロセス移動の実装に少し時間がかかった。始め、「FOR」命令を使用した時の挙動が思うようにいかず、ここの部分のデバッグにはMZxx_internetという、ステップ実行ができるMZのエミュレーターを使わせていただいた。

あとは、しらみつぶしに実装してくだけ。ステートメントは、

・IF
・GOSUB
・RETURN
・DIM
・REM
・POKE
・CALL
・EXEC

といったところ。関数は

・NOT
・STRNCMP
・ABS
・ASC
・LEN
・SGN
・RND
・PEEK

あたり。現在9kbぐらいの大きさになっているが、最終的には12kbぐらいになるかもしれない。機能の割には大きいプログラムになってしまったが、Cで書いているので仕方がない。今時、この規模のプログラムをアセンブラーで書く気にはなれないし。

ところで、3万回ループをFOR分で実行してみると、凡そ6秒かかる。MZ-80K用の普通のBASICインタープリターのおよそ3-4倍の速度。まずまずか。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=860 Thu, 26 Jul 2012 11:37:23 PDT ITEM860_20120726
エディターが完成 https://www.rad51.net/blog/mycom/?itemid=859
2012-07-24-editor.png

「RUN」命令はまだ。「RUN」が実行できるようになれば、後は各ステートメントのコンパイルルーチンをしらみつぶしに実装していくだけだ。完成が近づいてきた。]]>
Z80 https://www.rad51.net/blog/mycom/?itemid=859 Tue, 24 Jul 2012 17:09:59 PDT ITEM859_20120724