bf17 icon

NoRAL - interpreter

bf17 | PRO | 09/05/17 04:36:03 PM UTC | 0 ⭐ | 489 👁️ | Never ⏰ | []
Python |

8.1 KB

|

None

|

0 👍

/

0 👎

# 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