シミュレーション

4 bit CPU 設計

2012年11月7日

TK-80のエミュレーターをHTML5で作成したことは、思わぬ副産物をもたらした。

2012-11-07-zk40web02.png

このブログの副題は「IC・トランジスタで出来たコンピューターを設計・製作するためのブログ」。そう、元々はCPUを自作するために始めたのが、このブログである。後の制作(半田付け)を可能にするために、必要最小限のスペック、すなわち4ビット(もしくは6ビット)のCPUを考えている。TK-80のエミュレーターが完成して数日経ったとき、新しい4ビットCPUのアイデアがふと頭に浮かんだのである。それも夜中、寝ている最中に突然(夢の中というわけではなく、夜中に目がさめた瞬間にぼんやりと)。

そのアイデアを週末まで温めておき、土曜日からエミュレーターのプログラミングを始めると、なんと2日で(週末中に)出来てしまった。しかも、そのCPU上で動くモニタープログラムを含めて。それが動いている様子が、上に挙げたスナップショットである。見かけはTK-80のエミュレーターとほとんど変わらないが、これは4ビットCPUで動いている。

以下、CPUエミュレーション担当JavaScriptのコメントから。
/*
CPU specifications:

Address: 12 bits
Data: 4 bits

Total 16384 bits (2048 bytes)

Resisters:
	A:	4 bits (Accumulator)
	B:	4 bits (General)
	C:	4 bits (General)
	H:	4 bits (Index high)
	L:	4 bits (Index low)
	F:	2 bits (flags: C and Z)
	PC:	11 bits (program counter)
	SP: 6 bits (stack pointer)

Segment resisters:
	S: 6 bits (upper of jump commands)

Mnemonic

0x00-0x07:	LD A,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x00     :	NOP
0x08-0x0f:	LD B,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x09     :	RET
0x10-0x17:	LD C,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x12     :	in A,(C)
0x18-0x1f:	LD (HL),x (x=A, B, C, (HL), H, L, Sh, Sl)
0x1b     :	out (C),A
0x20-0x27:	LD H,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x24     :	if Z
0x28-0x2f:	LD L,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x2d     :	if NZ
0x30-0x37:	LD Sh,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x36     :	if C
0x37     :  ???
0x38-0x3f:	LD Sl,x (x=A, B, C, (HL), H, L, Sh, Sl)
0x3e     :  ???
0x3f     :  if NC
0x40-0x47:	inc x (x=A, B, C, (HL), H, L, Sh, Sl)
0x48-0x4f:	dec x (x=A, B, C, (HL), H, L, Sh, Sl)
0x50-0x57:	push x (x=A, B, C, F, H, L, Sh, Sl)
0x58-0x5f:	pop x (x=A, B, C, F, H, L, Sh, Sl)
0x60-0x63:	ADD A,x (x=A, B, C, or (HL))
0x64-0x67:	SUB A,x (x=A, B, C, or (HL))
0x68-0x6b:	ADC A,x (x=A, B, C, or (HL))
0x6c-0x6f:	SBC A,x (x=A, B, C, or (HL))
0x70-0x73:	AND A,x (x=A, B, C, or (HL))
0x74-0x77:	OR  A,x (x=A, B, C, or (HL))
0x78-0x7b:	CP  A,x (x=A, B, C, or (HL))
0x7c-0x7f:	XOR A,x (x=A, B, C, or (HL))
0x80-0xbf:	LD S with 6 bits operand (skip flag does not change after this operation)
0xc0-0xff:	Jump/Call with 5 bits operand (MLB: Jump or Call)

Notes:

1) Skip flag may be set after "if" command.
If it is set, the next operation is skipped.

2) "LD S,xx" followed by "JP"/"CALL"/"LD x,Sl" can be recognized as 4 word commands.
To do this with "if" command, "LD S,xx" command does not change the status of skip flag.

3) "SL" (shift left) is the same as "ADD A".
"RL" (rotate left) is the same as "ADC A".
"SR" (shift right) is the same as "ADD A", "ADC A", "ADC A", and "ADC A".
"RR" (rotate right) is the same as ""ADC A", "ADC A", "ADC A", and "ADC A".

4) When loading to Sl, upper 2 bits will be set to 0.
On the other hand, when loading to Sh, lower 2 bits will be kept.

*/

アキュムレーター(A)に加え、汎用のレジスターが2つ(B, C)。それに、インデックス用のレジスタ(HL)の構成で、4ビットのCPUだ。リテラルは、セグメント(アドレスの上位)指定を兼ねた6ビットのSレジスタを介してやりとりする。アドレス空間は12ビット。ジャンプ命令の際は、上位6ビットをSレジスタで、下位6ビットをリテラル値で指定する。スタックポインタは6ビットぐらいで良いだろう。これでも、64ワード長(32バイト)で、20段のCALL命令に対応する。フラグは、例によってゼロとキャリーの2つだけ。

すべての命令は8ビットの固定長。256種の命令のうち、64をジャンプ命令に、64をSレジスタへのリテラル値の代入に、残りの128を各種命令用に使った。命令が固定長であるのはポイントで、汎用ロジックでの回路の簡略化につながる。

実は、この仕様は一時的な物で、次のバージョンではSレジスタが4ビットと、さらに簡略化された物になる予定。いよいよ、4ビットCPUの自作が、目に見える形になりそうだ。

また、今後のバージョンでは、ハンドアセンブルの簡便さ(及びマシン語の可読性の良さ)は諦めることにした。別途アセンブラを作成してあるので、それを使ってプログラミングすればよく、出来たマシン語オブジェクトの可読性は二の次ということになる。それよりも、汎用ロジックでのCPUの回路をより簡便化することに重きを置いている。

自分のメモとバックアップを兼ねて: ver 0.2のダウンロードはこちらから

コメント

コメントはありません

コメント送信