TD4 の場合

GMC-4との比較で見る TD4

「CPUの創りかた」のCPU "TD4" と、 「学研:大人の科学」 の CPU "GMC-4"は、どちらも 4bit CPU ですがアーキテクチャはかなり違います。その比較を下に示してお きます。

TD4 GMC-4
ワード長(処理の単位)8bit4bit
ワード構成opcode(4) + oprand(4) opcode(4) or oprand(4)
命令長(処理の単位)1ワード(固定)1〜3ワード(可変)

あと、TD4 は、高々 16バイトしかメモリを持たない学習用のCPU(回路)なの で実用を求めるのはやぼなのですが、一般的なCPUと根本的に違うところを示し ておきます。

例えばのプログラム

という非常に制約のある中で、プログラムの例を示します。

VBA で

A = Input("")
For i = A To 15
  For B = 0 To 15
    ' 特に何もしない、つまり16ステップ分の時間だけ待つ
  Next
Next
MsgBox("ブザー")

というプログラムに対応するアセンブリ言語(機械語+α)は、以下のように なるでしょう。

# 外部(DIP4sw)から入力してAレジスタにおく
    IN A
#
# Bレジスタを0にする
L0: MOV B 0
#
# Bレジスタに1を足す
L1: ADD B 1
#
# もし桁あふれしなければL1に飛ぶ(Bが16になるまで繰り返す)
    JNC L1
#
# Aレジスタに1を足す
    ADD A 1
#
# もし桁あふれしなければL0に飛ぶ(Aが16になるまで繰り返す)
    JNC L0
#
# 4を出力する(とブザーがなる、ように回路が組まれている)
    OUT 4
#
# 無条件に L0 に飛ぶ
    JMP L0

「例えば」のアセンブル結果(機械語、16進数表記)

20
70
51
E2
01
E1
B4
F1

アセンブラ(変換プログラム in Python)

#! /usr/bin/env python3
# 
# 	...modified on 2019.04.13 (06:17)
# 
# TD4 assembler
#
Opcodes='''
MOV A Im  3i
MOV B Im  7i
MOV A B   10
MOV B A   40
ADD A Im  0i
ADD B Im  5i
IN  A     20
IN  B     60
OUT Im    Bi
OUT B     90
JMP Im    Fi
JNC Im    Ei
'''
import sys,re
class td4as:
  lines = []
  labels = {}
  def __init__(self, ls):
      self.lines = ls
  def p(self):
      for l in self.lines:
          print('## '+l)
  def plbls(self):
          print(self.labels)
  def parselabels(self):
      i = 0
      for l in self.lines:
          _s = l.split()
          if _s[0] == "#":
              continue
          if _s[0].find(':') > 0:
             self.labels[_s[0].rstrip(':')] = i
          i += 1
  def parselines(self):
      c.parselabels()
      for l in self.lines:
          _s = l.split()
          if _s[0] == "#":
              continue
          if _s[0].find(':') > 0:
              _s.pop(0)
          #
          if _s[0] == 'MOV':
              if _s[1] == 'A':
                  if _s[2] == 'B':
                      print('10')
                  else:
                      print('3'+_s[2])
              else: # 'B'
                  if _s[2] == 'A':
                      print('40')
                  else:
                      print('7'+_s[2])
          elif _s[0] == 'ADD':
              if _s[1] == 'A':
                  print('0'+_s[2])
              else: # 'B'
                  print('5'+_s[2])
          elif _s[0] == 'IN':
              if _s[1] == 'A':
                  print('20')
              else: # 'B'
                  print('60')
          elif _s[0] == 'OUT':
              if _s[1] == 'B':
                  print('90')
              else: # 'Im'
                  print('B'+_s[1])
          elif _s[0] == 'JMP':
              print('F'+str(self.labels[_s[1]]))
          elif _s[0] == 'JNC':
              print('E'+str(self.labels[_s[1]]))
          else:
              print('#> No opcode: '+_s[0])

if __name__ == '__main__':
  avs = sys.argv
  ls = []
  if len(avs) > 1:
    inf = open(avs[1], 'r')
  else:
    inf = sys.stdin
  for l in inf:
      ls.append(l.rstrip())
  c = td4as(ls)
  c.parselines()

目次にもどる