# File: nim.py from Tkinter import * # from random import random master = Tk() # Fonts intFont = "Helvetica 18" binaryFont = "Courier 18" opFont = "Helvetica 18" # Inputs/outputs byte = [False]*8 # mem = [byte]*64 # mem = [[random()<0.5 for i in range(8)] for j in range(64)] pc = byte acc = byte # Assembler! def intToByte(n): return [1==n%(2**(8-i))/(2**(7-i)) for i in range(8)] def SET(v): return intToByte(v) def ADD(v): return intToByte(64+v) def JZR(v): return intToByte(128+v) def STO(v): return intToByte(128+64+v) aLoc = 12 bLoc = 13 cLoc = 14 nextLoc = 10 doneLoc = 11 prog = [SET(0), ADD(aLoc), JZR(nextLoc), # if a = 0, goto next SET(0), ADD(bLoc), JZR(nextLoc), # if b = 0, goto next SET(1), STO(cLoc), # c = 1 SET(0), JZR(doneLoc), # goto done STO(cLoc), # NEXT: c = 0 JZR(doneLoc), # DONE: goto done intToByte(1), intToByte(0), intToByte(2)] mem = prog + [byte]*(64-len(prog)) # One logical cycle # [mem,pc,acc] = cycle([mem,pc,acc]) def cycle(input): [mem,pc,acc] = input ir = memlookup(pc,mem) pcnew = ifthenelse8((ir[0] and not ir[1]) and equal8(acc, intToByte(0)), [False, False, ir[2], ir[3], ir[4], ir[5], ir[6], ir[7]], addbyte(pc, intToByte(1))) # note the sign extension! (to allow for negation) accnew = ifthenelse8(not ir[0] and not ir[1], [ir[2], ir[2], ir[2], ir[3], ir[4], ir[5], ir[6], ir[7]], acc) accnewnew = ifthenelse8(not ir[0] and ir[1], addbyte(acc, memlookup([False, False, ir[2], ir[3], ir[4], ir[5], ir[6], ir[7]],mem)), accnew) memnew = memwrite(ir[0] and ir[1],[False, False, ir[2], ir[3], ir[4], ir[5], ir[6], ir[7]],mem,acc) return [memnew,pcnew,accnewnew] # Update the display def update(input): [mem,pc,acc] = input # print "update", pc, acc, "memlen", len(mem) for add in range(64): memint[add].delete(0,END) memint[add].insert(INSERT, byteToInt(mem[add])) membinary[add].configure(text=byteToBinary(mem[add])) memop[add].configure(text=byteToOp(mem[add]),bg="white") pcint.configure(text=byteToInt(pc)) accint.configure(text=byteToInt(acc)) memop[byteToInt(pc)].configure(bg="red") def byteToInt(byte): return sum([2**(7-i) * byte[i] for i in range(8)]) def byteToBinary(byte): return ''.join(["0"*(not b)+"1"*b for b in byte]) def byteToOp(byte): op = byte[0]*2+byte[1] const = byte[2]*32+byte[3]*16+byte[4]*8+byte[5]*4+byte[6]*2+byte[7] if (op == 0): return "ACC = " + str(const) if (op == 1): return "ACC = ACC + mem[" + str(const) + "]" if (op == 2): return "if ACC == 0: PC = " + str(const) # if (op == 3): return "mem[" + str(const) + "] = ACC" # Create the display memint = [0]*64 membinary = [0]*64 memop = [0]*64 # functions: byteToInt, byteToBits, byteToOp for colgrp in range(3): for row in range(23): add = colgrp*23+row if add < 64: Label(master, text=add, font=intFont, anchor=E,width=2,bg="gray",fg="white").grid(column=colgrp*4+0,row=row) memint[add] = Entry(master, font=intFont, width=3) memint[add].insert(INSERT, byteToInt(mem[add])) memint[add].grid(column=colgrp*4+1,row=row) def setMem(event, add=add): global mem global pc global acc newval = int(memint[add].get()) mem[add] = intToByte(newval) update([mem,pc,acc]) memint[add].bind('',setMem) membinary[add] = Label(master, text=byteToBinary(mem[add]), font=binaryFont, fg="gray") membinary[add].grid(column=colgrp*4+2,row=row) memop[add] = Label(master, text=byteToOp(mem[add]), font=opFont) memop[add].grid(column=colgrp*4+3,row=row) memop[add].configure(anchor=W, width=20) Label(master, text="PC", font=intFont).grid(row=18,column=2*4+0) pcint = Label(master, text=byteToInt(pc), font=intFont, width=3) pcint.grid(column=2*4+1,row=18) Label(master, text="ACC", font=intFont).grid(row=19,column=2*4+0) accint = Label(master, text=byteToInt(acc), font=intFont, width=3) accint.grid(column=2*4+1,row=19) def click(): global mem global pc global acc [mem,pc,acc] = cycle([mem,pc,acc]) update([mem,pc,acc]) Button(master, text="cycle", command=click,font=intFont).grid(row=20,column=2*4+2) # Label(master, text="MLMLML", font=intFont, bg = "blue").grid(row=21,column=2*4+2) # Logic Functions def addc(a,b,c): bit = (a and not b and not c) or (not a and b and not c) or (not a and not b and c) or (a and b and c) carry = (a and b and not c) or (a and not b and c) or (not a and b and c) or (a and b and c) return([carry, bit]) def addbyte(x,y): z = [False]*8 sum7 = addc(x[7],y[7],0) z[7] = sum7[1] sum6 = addc(x[6],y[6],sum7[0]) z[6] = sum6[1] sum5 = addc(x[5],y[5],sum6[0]) z[5] = sum5[1] sum4 = addc(x[4],y[4],sum5[0]) z[4] = sum4[1] sum3 = addc(x[3],y[3],sum4[0]) z[3] = sum3[1] sum2 = addc(x[2],y[2],sum3[0]) z[2] = sum2[1] sum1 = addc(x[1],y[1],sum2[0]) z[1] = sum1[1] sum0 = addc(x[0],y[0],sum1[0]) z[0] = sum0[1] return z def ifthenelse8(bit, byte1, byte2): return [(byte1[0] and bit) or (byte2[0] and not bit), (byte1[1] and bit) or (byte2[1] and not bit), (byte1[2] and bit) or (byte2[2] and not bit), (byte1[3] and bit) or (byte2[3] and not bit), (byte1[4] and bit) or (byte2[4] and not bit), (byte1[5] and bit) or (byte2[5] and not bit), (byte1[6] and bit) or (byte2[6] and not bit), (byte1[7] and bit) or (byte2[7] and not bit)] # match two bits def equal(bit1, bit2): return ((bit1 and bit2) or (not bit1 and not bit2)) # match two bytes def equal8(byte1, byte2): # print "eq", byte1, byte2 return (equal(byte1[0],byte2[0]) and equal(byte1[1],byte2[1]) and equal(byte1[2],byte2[2]) and equal(byte1[3],byte2[3]) and equal(byte1[4],byte2[4]) and equal(byte1[5],byte2[5]) and equal(byte1[6],byte2[6]) and equal(byte1[7],byte2[7])) def memlookup(add, mem): mem00 = mem[0] mem01 = ifthenelse8(equal8(intToByte( 1),add), mem[ 1], mem00) mem02 = ifthenelse8(equal8(intToByte( 2),add), mem[ 2], mem01) mem03 = ifthenelse8(equal8(intToByte( 3),add), mem[ 3], mem02) mem04 = ifthenelse8(equal8(intToByte( 4),add), mem[ 4], mem03) mem05 = ifthenelse8(equal8(intToByte( 5),add), mem[ 5], mem04) mem06 = ifthenelse8(equal8(intToByte( 6),add), mem[ 6], mem05) mem07 = ifthenelse8(equal8(intToByte( 7),add), mem[ 7], mem06) mem08 = ifthenelse8(equal8(intToByte( 8),add), mem[ 8], mem07) mem09 = ifthenelse8(equal8(intToByte( 9),add), mem[ 9], mem08) mem10 = ifthenelse8(equal8(intToByte(10),add), mem[10], mem09) mem11 = ifthenelse8(equal8(intToByte(11),add), mem[11], mem10) mem12 = ifthenelse8(equal8(intToByte(12),add), mem[12], mem11) mem13 = ifthenelse8(equal8(intToByte(13),add), mem[13], mem12) mem14 = ifthenelse8(equal8(intToByte(14),add), mem[14], mem13) mem15 = ifthenelse8(equal8(intToByte(15),add), mem[15], mem14) mem16 = ifthenelse8(equal8(intToByte(16),add), mem[16], mem15) mem17 = ifthenelse8(equal8(intToByte(17),add), mem[17], mem16) mem18 = ifthenelse8(equal8(intToByte(18),add), mem[18], mem17) mem19 = ifthenelse8(equal8(intToByte(19),add), mem[19], mem18) mem20 = ifthenelse8(equal8(intToByte(20),add), mem[20], mem19) mem21 = ifthenelse8(equal8(intToByte(21),add), mem[21], mem20) mem22 = ifthenelse8(equal8(intToByte(22),add), mem[22], mem21) mem23 = ifthenelse8(equal8(intToByte(23),add), mem[23], mem22) mem24 = ifthenelse8(equal8(intToByte(24),add), mem[24], mem23) mem25 = ifthenelse8(equal8(intToByte(25),add), mem[25], mem24) mem26 = ifthenelse8(equal8(intToByte(26),add), mem[26], mem25) mem27 = ifthenelse8(equal8(intToByte(27),add), mem[27], mem26) mem28 = ifthenelse8(equal8(intToByte(28),add), mem[28], mem27) mem29 = ifthenelse8(equal8(intToByte(29),add), mem[29], mem28) mem30 = ifthenelse8(equal8(intToByte(30),add), mem[30], mem29) mem31 = ifthenelse8(equal8(intToByte(31),add), mem[31], mem30) mem32 = ifthenelse8(equal8(intToByte(32),add), mem[32], mem31) mem33 = ifthenelse8(equal8(intToByte(33),add), mem[33], mem32) mem34 = ifthenelse8(equal8(intToByte(34),add), mem[34], mem33) mem35 = ifthenelse8(equal8(intToByte(35),add), mem[35], mem34) mem36 = ifthenelse8(equal8(intToByte(36),add), mem[36], mem35) mem37 = ifthenelse8(equal8(intToByte(37),add), mem[37], mem36) mem38 = ifthenelse8(equal8(intToByte(38),add), mem[38], mem37) mem39 = ifthenelse8(equal8(intToByte(39),add), mem[39], mem38) mem40 = ifthenelse8(equal8(intToByte(40),add), mem[40], mem39) mem41 = ifthenelse8(equal8(intToByte(41),add), mem[41], mem40) mem42 = ifthenelse8(equal8(intToByte(42),add), mem[42], mem41) mem43 = ifthenelse8(equal8(intToByte(43),add), mem[43], mem42) mem44 = ifthenelse8(equal8(intToByte(44),add), mem[44], mem43) mem45 = ifthenelse8(equal8(intToByte(45),add), mem[45], mem44) mem46 = ifthenelse8(equal8(intToByte(46),add), mem[46], mem45) mem47 = ifthenelse8(equal8(intToByte(47),add), mem[47], mem46) mem48 = ifthenelse8(equal8(intToByte(48),add), mem[48], mem47) mem49 = ifthenelse8(equal8(intToByte(49),add), mem[49], mem48) mem50 = ifthenelse8(equal8(intToByte(50),add), mem[50], mem49) mem51 = ifthenelse8(equal8(intToByte(51),add), mem[51], mem50) mem52 = ifthenelse8(equal8(intToByte(52),add), mem[52], mem51) mem53 = ifthenelse8(equal8(intToByte(53),add), mem[53], mem52) mem54 = ifthenelse8(equal8(intToByte(54),add), mem[54], mem53) mem55 = ifthenelse8(equal8(intToByte(55),add), mem[55], mem54) mem56 = ifthenelse8(equal8(intToByte(56),add), mem[56], mem55) mem57 = ifthenelse8(equal8(intToByte(57),add), mem[57], mem56) mem58 = ifthenelse8(equal8(intToByte(58),add), mem[58], mem57) mem59 = ifthenelse8(equal8(intToByte(59),add), mem[59], mem58) mem60 = ifthenelse8(equal8(intToByte(60),add), mem[60], mem59) mem61 = ifthenelse8(equal8(intToByte(61),add), mem[61], mem60) mem62 = ifthenelse8(equal8(intToByte(62),add), mem[62], mem61) mem63 = ifthenelse8(equal8(intToByte(63),add), mem[63], mem62) return mem63 def memwrite(active, add, mem, val): return [ ifthenelse8(active and equal8(intToByte( 0),add), val, mem[ 0]), ifthenelse8(active and equal8(intToByte( 1),add), val, mem[ 1]), ifthenelse8(active and equal8(intToByte( 2),add), val, mem[ 2]), ifthenelse8(active and equal8(intToByte( 3),add), val, mem[ 3]), ifthenelse8(active and equal8(intToByte( 4),add), val, mem[ 4]), ifthenelse8(active and equal8(intToByte( 5),add), val, mem[ 5]), ifthenelse8(active and equal8(intToByte( 6),add), val, mem[ 6]), ifthenelse8(active and equal8(intToByte( 7),add), val, mem[ 7]), ifthenelse8(active and equal8(intToByte( 8),add), val, mem[ 8]), ifthenelse8(active and equal8(intToByte( 9),add), val, mem[ 9]), ifthenelse8(active and equal8(intToByte(10),add), val, mem[10]), ifthenelse8(active and equal8(intToByte(11),add), val, mem[11]), ifthenelse8(active and equal8(intToByte(12),add), val, mem[12]), ifthenelse8(active and equal8(intToByte(13),add), val, mem[13]), ifthenelse8(active and equal8(intToByte(14),add), val, mem[14]), ifthenelse8(active and equal8(intToByte(15),add), val, mem[15]), ifthenelse8(active and equal8(intToByte(16),add), val, mem[16]), ifthenelse8(active and equal8(intToByte(17),add), val, mem[17]), ifthenelse8(active and equal8(intToByte(18),add), val, mem[18]), ifthenelse8(active and equal8(intToByte(19),add), val, mem[19]), ifthenelse8(active and equal8(intToByte(20),add), val, mem[20]), ifthenelse8(active and equal8(intToByte(21),add), val, mem[21]), ifthenelse8(active and equal8(intToByte(22),add), val, mem[22]), ifthenelse8(active and equal8(intToByte(23),add), val, mem[23]), ifthenelse8(active and equal8(intToByte(24),add), val, mem[24]), ifthenelse8(active and equal8(intToByte(25),add), val, mem[25]), ifthenelse8(active and equal8(intToByte(26),add), val, mem[26]), ifthenelse8(active and equal8(intToByte(27),add), val, mem[27]), ifthenelse8(active and equal8(intToByte(28),add), val, mem[28]), ifthenelse8(active and equal8(intToByte(29),add), val, mem[29]), ifthenelse8(active and equal8(intToByte(30),add), val, mem[30]), ifthenelse8(active and equal8(intToByte(31),add), val, mem[31]), ifthenelse8(active and equal8(intToByte(32),add), val, mem[32]), ifthenelse8(active and equal8(intToByte(33),add), val, mem[33]), ifthenelse8(active and equal8(intToByte(34),add), val, mem[34]), ifthenelse8(active and equal8(intToByte(35),add), val, mem[35]), ifthenelse8(active and equal8(intToByte(36),add), val, mem[36]), ifthenelse8(active and equal8(intToByte(37),add), val, mem[37]), ifthenelse8(active and equal8(intToByte(38),add), val, mem[38]), ifthenelse8(active and equal8(intToByte(39),add), val, mem[39]), ifthenelse8(active and equal8(intToByte(40),add), val, mem[40]), ifthenelse8(active and equal8(intToByte(41),add), val, mem[41]), ifthenelse8(active and equal8(intToByte(42),add), val, mem[42]), ifthenelse8(active and equal8(intToByte(43),add), val, mem[43]), ifthenelse8(active and equal8(intToByte(44),add), val, mem[44]), ifthenelse8(active and equal8(intToByte(45),add), val, mem[45]), ifthenelse8(active and equal8(intToByte(46),add), val, mem[46]), ifthenelse8(active and equal8(intToByte(47),add), val, mem[47]), ifthenelse8(active and equal8(intToByte(48),add), val, mem[48]), ifthenelse8(active and equal8(intToByte(49),add), val, mem[49]), ifthenelse8(active and equal8(intToByte(50),add), val, mem[50]), ifthenelse8(active and equal8(intToByte(51),add), val, mem[51]), ifthenelse8(active and equal8(intToByte(52),add), val, mem[52]), ifthenelse8(active and equal8(intToByte(53),add), val, mem[53]), ifthenelse8(active and equal8(intToByte(54),add), val, mem[54]), ifthenelse8(active and equal8(intToByte(55),add), val, mem[55]), ifthenelse8(active and equal8(intToByte(56),add), val, mem[56]), ifthenelse8(active and equal8(intToByte(57),add), val, mem[57]), ifthenelse8(active and equal8(intToByte(58),add), val, mem[58]), ifthenelse8(active and equal8(intToByte(59),add), val, mem[59]), ifthenelse8(active and equal8(intToByte(60),add), val, mem[60]), ifthenelse8(active and equal8(intToByte(61),add), val, mem[61]), ifthenelse8(active and equal8(intToByte(62),add), val, mem[62]), ifthenelse8(active and equal8(intToByte(63),add), val, mem[63])] # START THE UI update([mem,pc,acc]) master.mainloop()