2014年7月10日木曜日

とりあえず最低限の機能を実装した仮想CPU

とりあえずRubyを使って以下のように試作してみた。

本来オブジェクト指向言語なので、CPUクラスを作って、プロパティとしてレジスターとか個々の要素やモジュールを設定し、メソッドとして命令やその動作を実装すればよいが、何だかPerlのような使い方で、オブジェクト指向どころか構造かさえしていないが、思いついたところまで書いてみた。

メモリ管理やI/Oをどう表現するかはいいアイデアが出ないので、また気が向いたら考えたい。

#==========

# MyCPU running with Assembler

inbuf = "abc" ;
artmp = Array.new ;

regA = 0 ;
regB = 0 ;
flgC = 0 ;
flgZ = 0 ;
tmpvar = 0 ;

while inbuf != "byr" do
  print "--> " ;
  inbuf = gets.chomp ;
  artmp = inbuf.split(" ") ;

### Print function for debug ################
  print "Input[0] is ", artmp[0], "\n" ;
  print "Input[1] is ", artmp[1], "\n" ;
  print "Input[2] is ", artmp[2], "\n" ;
#############################################

if artmp[0] == "ADD" && artmp[1] == "A" && artmp[2] == "B" then
     regA = regA + regB ;

     if regA > 255 then
        flgC = 1 ;
     end

 elsif artmp[0] == "ADD" && artmp[1] == "A" && artmp[2] != "B" then
     regA = regA + artmp[2].to_i ;

     if regA > 255 then
        flgC = 1 ;
     end

 elsif artmp[0] == "ADD" && artmp[1] == "B" then
     regB = regB + artmp[2].to_i ;

     if regB > 255 then
        flgC = 1 ;
     end

### MIN ###
 elsif artmp[0] == "MIN" && artmp[1] == "A" && artmp[2] == "B" then
     regA = regA - regB ;

     if regA < 0 then
        flgZ = 1 ;
     end

 elsif artmp[0] == "MIN" && artmp[1] == "A" && artmp[2] != "B" then
     regA = regA - artmp[2].to_i ;

     if regA < 0 then
        flgZ = 1 ;
     end

 elsif artmp[0] == "MIN" && artmp[1] == "B" then
     regB = regB - artmp[2].to_i ;

     if regB < 0 then
        flgZ = 1 ;
     end


### LOAD ###
 elsif artmp[0] == "LD" && artmp[1] == "A" && artmp[2] != "B" then
     regA = artmp[2].to_i ;
 elsif artmp[0] == "LD" && artmp[1] == "B" then
     regB = artmp[2].to_i ;
 elsif artmp[0] == "SWP" then
     tmpvar = regA ;
     regA = regB ;
     regB = tmpvar ;
 elsif artmp[0] != nil then
     print "Code unknown!\n" ;
     break ;
end

# Display values of registers & flags
  print "A: ", regA, "\t", "B: ", regB, "\n" ;

  if flgC == 0 then
     print "Carry: Inactive / " ;
  else
     print "Carry: Active / " ;
  end

# ここはメモリがないと意味がないので、まだ実装していない
  if flgZ == 0 then
     print "Zero: non-Zero\t" ;
  else
     print "Zero: Zero\t" ;
  end

  print "\n" ;
end


0 件のコメント:

コメントを投稿