5 # 3-trit Computer Simulator
6 # usage: logicCpu program.3
7 # This program simulates the hardware of the 3 trit computer we are
8 # developing. Input to the program is a ".3" file which should contain
9 # three encoded instructions to simulate on the first line. Once started,
10 # the user may interactively change the "IN" register at any time.
11 # Execution begins with instruction at program counter 0.
13 import sys
, os
, threading
, time
, signal
15 # for safe termination
27 USER_INPUT_THREAD
= True # ask for user input?
28 USER_INPUT_INIT
= 8 # initialize input to this
30 trit_integer
= {"i": -1, "0":0, "1":1}
32 # Lookup a register's name by address
47 # Thread that gets input from user
48 class CPUInput (threading
.Thread
):
51 print "Register Status: %s :" % registers
,
54 user_input
= raw_input('Input value for IN:')
64 if cont_exec
== TERMINATE
:
69 digit
= int(user_input
)
71 print "invalid input: %s (%s)" % (user_input
, e
)
74 if digit
>= -4 and digit
<= 4:
75 registers
["IN"] = digit
77 print """invalid input: %s""" % user_input
80 ''' Busy wait lock to avoid race conditions.
81 This function retrieves the lock.
90 ''' This function releases the lock.
100 if len(sys
.argv
) < 2 or len(sys
.argv
) > 2:
101 print """usage: %s program.3
102 input file: program.3 - machine code
106 if (sys
.argv
[1])[len(sys
.argv
[1])-1:] != "3":
107 print """\'%s\' is an invalid filetype""" % sys
.argv
[1]
111 codefile
= file(sys
.argv
[1], "rt")
112 tritstream
= codefile
.readline()
114 # check for errors in file
116 print """\'%s\' files is empty""" % (sys
.argv
[1])
120 if not i
in trit_integer
:
121 print """invalid char \'%s\' in file \'%s\'""" % (i
, sys
.argv
[1])
124 if len(tritstream
) != 9:
125 print """3 instructions must be provided in \'%s\'""" % (sys
.argv
[1])
128 # memory, registers, and program counter
135 # decode instructions from file
136 for i
in range(-1, 2):
138 memory
[i
] = Decoder(tritstream
)
139 tritstream
= tritstream
[3:]
141 # start user input thread
142 if USER_INPUT_THREAD
:
146 registers
["IN"] = USER_INPUT_INIT
149 # execute instructions
153 registers
["PC"] = Execute(memory
)
157 if cont_exec
== TERMINATE
:
168 def Decoder(tritstream
):
169 """ Decode a single instruction.
170 tristream: stream of trits will only process the first 3 trits.
171 return: dictionary containing the operation
173 inst
= {"op":trit_integer
[tritstream
[0]]}
176 if inst
["op"] == -1 or inst
["op"] == 1:
183 inst
["src1"] = trit_integer
[tritstream
[1]]
184 print "%2d," % inst
["src1"],
185 inst
["src2"] = trit_integer
[tritstream
[2]]
186 print "%2d" % inst
["src2"]
189 elif inst
["op"] == 0:
191 inst
["src1"] = trit_integer
[tritstream
[1]]
192 inst
["src2"] = trit_integer
[tritstream
[2]]
193 inst
["immed"] = 3*inst
["src1"] + inst
["src2"]
194 print "%2d" % inst
["immed"]
199 """ Execute one instruction.
200 memory: were decoded instructions are stored
201 registers: contains registers and their values
202 returns: new program counter, to be stored in registers["PC"]
205 op
= (memory
[registers
["PC"]])["op"]
209 src1
= (memory
[registers
["PC"]])["src1"]
210 src2
= (memory
[registers
["PC"]])["src2"]
211 if registers
[register_name
[src1
]] < registers
[register_name
[src2
]]:
213 elif registers
[register_name
[src1
]] > registers
[register_name
[src2
]]:
217 new_pc
= registers
["PC"] + 1
220 registers
["A"] = (memory
[registers
["PC"]])["immed"]
221 new_pc
= registers
["PC"] + 1
224 if registers
["S"] == 0:
225 new_pc
= (memory
[registers
["PC"]])["src1"]
227 new_pc
= (memory
[registers
["PC"]])["src2"]
234 if __name__
== "__main__":