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
23 USER_INPUT_THREAD
= True # ask for user input?
24 USER_INPUT_INIT
= 8 # initialize input to this
26 trit_integer
= {"i": -1, "0":0, "1":1}
28 # Lookup a register's name by address
43 # Thread that gets input from user
44 class CPUInput (threading
.Thread
):
49 print "Register Status: %s :" % registers
,
52 user_input
= raw_input('Input value for IN:')
65 digit
= int(user_input
)
67 print "invalid input: %s (%s)" % (user_input
, e
)
70 if digit
>= -4 and digit
<= 4:
71 registers
["IN"] = digit
73 print """invalid input: %s""" % user_input
76 ''' Busy wait lock to avoid race conditions.
77 This function retrieves the lock.
86 ''' This function releases the lock.
97 if len(sys
.argv
) < 2 or len(sys
.argv
) > 2:
98 print """usage: %s program.3
99 input file: program.3 - machine code
103 if (sys
.argv
[1])[len(sys
.argv
[1])-1:] != "3":
104 print """\'%s\' is an invalid filetype""" % sys
.argv
[1]
108 codefile
= file(sys
.argv
[1], "rt")
109 tritstream
= codefile
.readline()
111 # check for errors in file
113 print """\'%s\' files is empty""" % (sys
.argv
[1])
117 if not i
in trit_integer
:
118 print """invalid char \'%s\' in file \'%s\'""" % (i
, sys
.argv
[1])
121 if len(tritstream
) != 9:
122 print """3 instructions must be provided in \'%s\'""" % (sys
.argv
[1])
125 # memory, registers, and program counter
132 # decode instructions from file
133 for i
in range(-1, 2):
135 memory
[i
] = Decoder(tritstream
)
136 tritstream
= tritstream
[3:]
138 # start user input thread
139 if USER_INPUT_THREAD
:
143 registers
["IN"] = USER_INPUT_INIT
146 print "Press Ctrl-D to terminate"
147 # execute instructions
151 registers
["PC"] = Execute(memory
)
166 def Decoder(tritstream
):
167 """ Decode a single instruction.
168 tristream: stream of trits will only process the first 3 trits.
169 return: dictionary containing the operation
171 inst
= {"op":trit_integer
[tritstream
[0]]}
174 if inst
["op"] == -1 or inst
["op"] == 1:
181 inst
["src1"] = trit_integer
[tritstream
[1]]
182 print "%2d," % inst
["src1"],
183 inst
["src2"] = trit_integer
[tritstream
[2]]
184 print "%2d" % inst
["src2"]
187 elif inst
["op"] == 0:
189 inst
["src1"] = trit_integer
[tritstream
[1]]
190 inst
["src2"] = trit_integer
[tritstream
[2]]
191 inst
["immed"] = 3*inst
["src1"] + inst
["src2"]
192 print "%2d" % inst
["immed"]
197 """ Execute one instruction.
198 memory: were decoded instructions are stored
199 registers: contains registers and their values
200 returns: new program counter, to be stored in registers["PC"]
203 op
= (memory
[registers
["PC"]])["op"]
207 src1
= (memory
[registers
["PC"]])["src1"]
208 src2
= (memory
[registers
["PC"]])["src2"]
209 if registers
[register_name
[src1
]] < registers
[register_name
[src2
]]:
211 elif registers
[register_name
[src1
]] > registers
[register_name
[src2
]]:
215 new_pc
= registers
["PC"] + 1
218 registers
["A"] = (memory
[registers
["PC"]])["immed"]
219 new_pc
= registers
["PC"] + 1
222 if registers
["S"] == 0:
223 new_pc
= (memory
[registers
["PC"]])["src1"]
225 new_pc
= (memory
[registers
["PC"]])["src2"]
232 if __name__
== "__main__":