# python 3 on Pythonista, iPad Pro
# latest update: 20180809
'''
Memory: 0000 - ffff
Program Counter 0000 - 0001 (starts at 0200)
Carry Flag 0002
Zero Flag 0003
Top of Stack 0004
Stack 0005 - 00ff 251 bytes
Screen Memory 0100 - 01ff 32 x 8, 256 bytes
Start of program memory: 0200
'''
from array import array
mem = array('B')
mem = [0] * 0x10000
start_of_prog = prog_mem = pc = 0x0200
prog_list = ""
complete_listing = ""
dest = 0
src = 0
ind_src = 0 #indirect source used in mvi
scr_char = 0
sp = 5 # start of stack memory, variable for incase it changes
# definitions -------------------------
def sto_pc(): #put pc into memory as if it was used from there
mem[0] = pc >> 8
mem[1] = pc & 255
def show_registers():
print()
print("Program Counter: ", '{:04x}'.format(pc))
print("Zero Flag: ", '{:02x}'.format(mem[3]))
print("Carry Flag: ", '{:02x}'.format(mem[2]))
print("Stack Pointer: ", '{:02x}'.format(mem[4]))
def printable(n):
if((n>31 and n<127)):
return(True)
else:
return(False)
def show_screen():
print()
print("+--------Screen Display----------+")
for i in range(8):
print("|", end = "")
for j in range(32):
scr_char = mem[256 + i * 32 + j]
if(printable(scr_char)):
print(chr(scr_char), end = "")
else:
print(" ", end = "")
print("|")
print("+" + "-" * 32 + "+\n", end = "")
def show_stack():
print()
for i in range(0, 8):
print('{:02x}'.format(mem[i + 5]) + " ", end = "")
print()
for i in range(8, 16):
print('{:02x}'.format(mem[i + 5]) + " ", end = "")
print()
for i in range(16, 24):
print('{:02x}'.format(mem[i + 5]) + " ", end = "")
print()
def debug_listing():
print()
for i in range(512, prog_mem):
print('{:04x}'.format(i), '{:02x}'.format(mem[i]))
i += 1
# read program into memory
#f = open(input("NoRAL file: "), 'r')
f = open("a.txt", 'r')
for line in f:
if(line[:1] != "#"): # check for comments
for word in line.split():
prog_list = prog_list + " " + word
f.close()
# convert mnemonics to opcodes and memory references
for word in prog_list.split():
if (word == "add"):
mem[prog_mem] = 1
prog_mem += 1
elif(word == "and"):
mem[prog_mem] = 2
prog_mem += 1
elif(word == "jmp"):
mem[prog_mem] = 3
prog_mem += 1
elif(word == "jpc"):
mem[prog_mem] = 4
prog_mem += 1
elif(word == "jpz"):
mem[prog_mem] = 5
prog_mem += 1
elif(word == "jsr"):
mem[prog_mem] = 6
prog_mem += 1
elif(word == "mov"):
mem[prog_mem] = 7
prog_mem += 1
elif(word == "nop"):
mem[prog_mem] = 8
prog_mem += 1
elif(word == "not"):
mem[prog_mem] = 9
prog_mem += 1
elif(word == "orr"):
mem[prog_mem] = 10
prog_mem += 1
elif(word == "pop"):
mem[prog_mem] = 11
prog_mem += 1
elif(word == "psh"):
mem[prog_mem] = 12
prog_mem += 1
elif(word == "ret"):
mem[prog_mem] = 13
prog_mem += 1
elif(word == "shl"):
mem[prog_mem] = 14
prog_mem += 1
elif(word == "shr"):
mem[prog_mem] = 15
prog_mem += 1
elif(word == "sto"):
mem[prog_mem] = 16
prog_mem += 1
elif(word == "sub"):
mem[prog_mem] = 17
prog_mem += 1
elif(word == "inc"):
mem[prog_mem] = 18
prog_mem += 1
elif(word == "dec"):
mem[prog_mem] = 19
prog_mem += 1
elif(word == "mvi"):
mem[prog_mem] = 20
prog_mem += 1
elif(word == "get"):
mem[prog_mem] = 21
prog_mem += 1
elif(word == "dsp"):
mem[prog_mem] = 22
prog_mem += 1
elif(word == "brk"):
mem[prog_mem] = 0
prog_mem += 1
else:
if(len(word) == 4): # 2 byte memory references
mem[prog_mem] = int(word[:2], 16)
prog_mem += 1
mem[prog_mem] = int(word[2:], 16)
prog_mem += 1
else: # 1 byte memory references
mem[prog_mem] = int(word, 16)
prog_mem += 1
print()
# interpret instructions
# xxx dest src
# reset pc to start_of_prog
pc = start_of_prog
while True:
dest = mem[pc + 1] * 256 + mem[pc + 2]# these are used for most
src = mem[pc + 3] * 256 + mem[pc + 4]# of the instructions
#add 01
if(mem[pc] == 1):
mem[2] = int((mem[dest] + mem[src]) != (mem[dest] + mem[src]) % 256)
mem[dest] = (mem[dest] + mem[src] + mem[2]) % 256
mem[3] = int(mem[dest] == 0)
pc += 5
#and 02
elif(mem[pc] == 2):
mem[dest] = mem[dest] & mem[src]
mem[3] = int(mem[dest] == 0)
pc += 5
#jmp 03
elif(mem[pc] == 3):
pc = dest
#jpc 04
elif(mem[pc] == 4):
if(mem[2] == 1):
pc = dest
else:
pc += 3
#jpz 05
elif(mem[pc] == 5):
if(mem[3] == 1):
pc = dest
else:
pc += 3
#jsr 06
elif(mem[pc] == 6):
mem[sp + mem[4]] = int(pc / 256) % 256
mem[4] += 1 # stack pointer
mem[sp + mem[4]] = (pc % 256) + 3
mem[4] += 1
pc = dest
#mov 07
elif(mem[pc] == 7):
mem[dest] = mem[src]
mem[3] = int(mem[dest] == 0)
pc += 5
#nop 08
elif(mem[pc] == 8):
pc += 1
#not 09
elif(mem[pc] == 9):
mem[dest] = (255 - mem[dest]) % 256
mem[3] = int(mem[dest] == 0)
pc += 3
#orr 0a
elif(mem[pc] == 10):
mem[dest] = mem[dest] | mem[src]
mem[3] = int(mem[dest] == 0)
pc += 5
#pop 0b
elif(mem[pc] == 11):
mem[4] -= 1
mem[dest] = mem[mem[4] + 5]
mem[3] = int(mem[dest] == 0)
pc += 3
#psh 0c
elif(mem[pc] == 12):
mem[mem[4] + 5] = mem[dest]
mem[4] += 1
pc += 3
#ret 0d
elif(mem[pc] == 13):
mem[4] -= 2
pc = mem[sp + mem[4]] * 256 + mem[sp + 1 + mem[4]]
#shl 0e
elif(mem[pc] == 14):
mem[2] = int((mem[dest] & 128) > 0)
mem[dest] = (mem[dest] << 1) % 256
mem[3] = int(mem[dest] == 0)
pc += 3
#shr 0f
elif(mem[pc] == 15):
mem[2] = mem[dest] & 1
mem[dest] = mem[dest] >> 1
mem[3] = int(mem[dest] == 0)
pc += 3
#sto 10
elif(mem[pc] == 16):
src = pc + 3
mem[dest] = mem[pc + 3]
mem[3] = int(mem[dest] == 0)
pc += 4
#sub 11
elif(mem[pc] == 17):
mem[2] = int((mem[dest] - mem[src]) != (mem[dest] - mem[src]) % 256)
mem[dest] = (mem[dest] - mem[src] - mem[2]) % 256
mem[3] = int(mem[dest] == 0)
pc += 5
#inc 12
elif(mem[pc] == 18):
mem[2] = int((mem[dest] + 1) != (mem[dest] + 1) % 256)
mem[dest] = (mem[dest] + 1) % 256
mem[3] = int(mem[dest] == 0)
pc += 3
#dec 13
elif(mem[pc] == 19):
mem[2] = int((mem[dest] - 1) != (mem[dest] - 1) % 256)
mem[dest] = (mem[dest] - 1) % 256
mem[3] = int(mem[dest] == 0)
pc += 3
#mvi 14 - absolute, indirect
elif(mem[pc] == 20):
ind_src = mem[src] * 256 + mem[src + 1]
mem[dest] = mem[ind_src]
mem[3] = int(mem[dest] == 0)
pc += 5
#get 15 - m1(absolute) = input decimal number mod 256
elif(mem[pc] == 21):
mem[dest] = int(input("Enter Decimal Number: ")) % 256
mem[3] = int(mem[dest] == 0)
pc += 3
#dsp 16 - display during program execution
elif(mem[pc] == 22):
show_registers()
show_screen()
pc += 1
#brk 00 - or no more instructions
else:
if(mem[pc] == 0):
pc += 1
show_registers()
# show_stack()
show_screen()
# debug_listing()
break
Comments