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
25 USER_INPUT_THREAD
= True # ask for user input?
26 USER_INPUT_INIT
= 8 # initialize input to this
28 trit_integer
= {"i": -1, "0":0, "1":1}
30 # Lookup a register's name by address
45 # Thread that gets input from user
46 class CPUInput (threading
.Thread
):
51 print "Register Status: %s :" % registers
,
54 user_input
= raw_input('Input value for IN:')
62 if cont_exec
== TERMINATE
:
67 digit
= int(user_input
)
69 print "invalid input: %s (%s)" % (user_input
, e
)
72 if digit
>= -4 and digit
<= 4:
73 registers
["IN"] = digit
75 print """invalid input: %s""" % user_input
78 ''' Busy wait lock to avoid race conditions.
79 This function retrieves the lock.
88 ''' This function releases the lock.
99 if len(sys
.argv
) < 2 or len(sys
.argv
) > 2:
100 print """usage: %s program.3
101 input file: program.3 - machine code
105 if (sys
.argv
[1])[len(sys
.argv
[1])-1:] != "3":
106 print """\'%s\' is an invalid filetype""" % sys
.argv
[1]
110 codefile
= file(sys
.argv
[1], "rt")
111 tritstream
= codefile
.readline()
113 # check for errors in file
115 print """\'%s\' files is empty""" % (sys
.argv
[1])
119 if not i
in trit_integer
:
120 print """invalid char \'%s\' in file \'%s\'""" % (i
, sys
.argv
[1])
123 if len(tritstream
) != 9:
124 print """3 instructions must be provided in \'%s\'""" % (sys
.argv
[1])
127 # memory, registers, and program counter
134 # decode instructions from file
135 for i
in range(-1, 2):
137 memory
[i
] = Decoder(tritstream
)
138 tritstream
= tritstream
[3:]
140 # start user input thread
141 if USER_INPUT_THREAD
:
145 registers
["IN"] = USER_INPUT_INIT
148 # execute instructions
152 registers
["PC"] = Execute(memory
)
156 if cont_exec
== TERMINATE
:
167 def Decoder(tritstream
):
168 """ Decode a single instruction.
169 tristream: stream of trits will only process the first 3 trits.
170 return: dictionary containing the operation
172 inst
= {"op":trit_integer
[tritstream
[0]]}
175 if inst
["op"] == -1 or inst
["op"] == 1:
182 inst
["src1"] = trit_integer
[tritstream
[1]]
183 print "%2d," % inst
["src1"],
184 inst
["src2"] = trit_integer
[tritstream
[2]]
185 print "%2d" % inst
["src2"]
188 elif inst
["op"] == 0:
190 inst
["src1"] = trit_integer
[tritstream
[1]]
191 inst
["src2"] = trit_integer
[tritstream
[2]]
192 inst
["immed"] = 3*inst
["src1"] + inst
["src2"]
193 print "%2d" % inst
["immed"]
198 """ Execute one instruction.
199 memory: were decoded instructions are stored
200 registers: contains registers and their values
201 returns: new program counter, to be stored in registers["PC"]
204 op
= (memory
[registers
["PC"]])["op"]
208 src1
= (memory
[registers
["PC"]])["src1"]
209 src2
= (memory
[registers
["PC"]])["src2"]
210 if registers
[register_name
[src1
]] < registers
[register_name
[src2
]]:
212 elif registers
[register_name
[src1
]] > registers
[register_name
[src2
]]:
216 new_pc
= registers
["PC"] + 1
219 registers
["A"] = (memory
[registers
["PC"]])["immed"]
220 new_pc
= registers
["PC"] + 1
223 if registers
["S"] == 0:
224 new_pc
= (memory
[registers
["PC"]])["src1"]
226 new_pc
= (memory
[registers
["PC"]])["src2"]
233 if __name__
== "__main__":