changeset 28:6d32e54e5c16

emulator overhauled really, new a better memory structure also cleaned up the file system some what.
author james <jb302@eecs.qmul.ac.uk>
date Fri, 11 Apr 2014 14:38:09 +0100
parents a542cd390efd
children 83e80c2c489c
files asm/__init__.py asm/__init__.pyc asm/asm.py asm/language.py asm/language.pyc assembler/.language.py.swp assembler/assembler.py assembler/language.py assembler/language.pyc build.sh dbg/__init__.py dbg/__init__.pyc dbg/cli.py dbg/dbg.py dbg/dbg.pyc doc/general/.~lock.elb816_opcodes.ods# emu/iset.c emu/iset.h emu/main.c emu/mem.c emu/mem.h emulator/a.out emulator/dbgi.h emulator/emu.c emulator/iset.c emulator/iset.h emulator/main.c emulator/mem.c emulator/mem.h tests/a.out tests/asm/a.out tests/asm/full.asm tests/emu/test.c tests/emu/test_mem tests/emu/test_mem.bin tests/emu/test_mem.c tests/full.asm
diffstat 35 files changed, 1980 insertions(+), 1984 deletions(-) [+]
line wrap: on
line diff
Binary file asm/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/asm.py	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,215 @@
+#!/usr/bin/env python2
+# assembler.py
+import struct
+import sys
+from language import *
+
+# take source file and return preprocessed assembly code
+# for each non-empty line in the file:
+#   remove comments from source
+#   replace equated strings
+#   store label definitions and remove label from source
+#   store new equates
+#   make hashable format symbol from arguments
+#   identify and save constant data
+#   save instruction, arguments, symbol and data to list
+# also prepares org and db instructions for second_pass()
+def first_pass(f):
+    asm = []
+    labels = {}
+    equates = {}
+    pc = 0
+    
+    # read file into list, remove blank line
+    f.seek(0)
+    source_code = filter(lambda l: l != '\n', f.readlines())  
+    
+    # <line> ::= [<statement>] [";"<comment>] <EOL>
+    for line in source_code:  
+        try:
+            # remove trailing whitespace and comments
+            line = line.strip()
+            for i in range(len(line)):
+                if line[i] == ';':
+                    line = line[:i]
+                    break
+            
+            # <statement> ::= [ <label> ":"] <mnemonic> [<arguments>]
+            #                 | <label> ":"
+            #                 | "EOF"
+            statement = line.split()
+            if not statement:
+                continue
+
+            # replace equated strings
+            # because this happens on the first pass
+            # equates must be assigned before they are used
+            i = 1
+            for s in statement[1:]:
+                # replace any equates already stored
+                # remove prefixes and suffixes before attempting to replace
+                prefix = suffix = ''
+                # prefixes
+                if s[0] in ids:
+                    prefix = prefix + s[0]
+                    s = s[1:]
+                if s[0] == '(':
+                    prefix = prefix + s[0]
+                    s = s[1:]
+                # suffixes
+                if s and (s[-1] == ','):
+                    suffix = suffix + s[-1]
+                    s = s[:-1]
+                if s and (s[-1] == ')'):
+                    suffix = s[-1] + suffix
+                    s = s[:-1]
+                # replace and put removed characters back
+                if s in equates:
+                    statement[i] = prefix + equates[s] + suffix
+                # labels can be used in equates but they have
+                # to be assigned before they are used as well
+                elif s in labels:
+                    if statement[0] in rinst:
+                        statement[i] = prefix + str(labels[s] - pc) + suffix
+                    else:
+                        statement[i] = prefix + str(labels[s]) + suffix
+                i = i + 1                   
+            
+            # deal with org
+            if statement[0].lower() == 'org':
+                asm.append(['org', statement[1:], ('',), ''])
+                pc = stoi(statement[1])
+                continue
+            # if needed update index and remove label 
+            elif statement[0][-1] == ':':
+                labels[statement[0][:-1]] = pc;
+                del statement[0]
+            # store equates
+            # these are case sensative
+            elif (len(statement) >= 3) and (statement[1].lower() == 'equ'):
+                equates[statement[0]] = ' '.join(statement[2:])
+                continue
+                
+            if not statement:
+                continue
+            
+            # <statement> ::= <mnemonic> [<arguments>]
+            mne = statement[0].lower()
+            args = ''.join(statement[1:]).split(',')
+        
+            # deal with db
+            if mne == 'db':
+                const = ''
+                for a in args:
+                    data = tokenize(mne, ['#' + a])[1]
+                    # deal with leading zeros
+                    # skip zeros unless zero is the 
+                    # only number
+                    if data == '\x00\x00':
+                        const = const + '\x00'
+                        continue
+                    i = 0
+                    for c in data:
+                        if c == '\x00':
+                            i = i + 1
+                        else:
+                            pass
+                    const = const + data[i:]
+                asm.append([mne, args, ('',), const])
+                pc = pc + len(const)
+                continue
+            
+            # tokenize
+            sym, const = tokenize(mne, args)
+            asm.append([mne, args, sym, const])
+            # increase pc
+            width = iset[mne][sym][1]
+            pc = pc + width
+        
+        except:
+            print ' ** first pass error **\nline:\n', line
+            raise
+    
+    return asm, labels
+
+# take a preprocessed object asm and write machine code to binary file
+# for each line of asm:
+#   check if it's an org or db command deal with it accordingly
+#   check if arguments are labels and replace with value
+#   write instruction to file
+def second_pass(f, asm, labels):
+    pc = 0
+
+    for line in asm:
+        f.seek(pc)
+        mne, args, sym, const = line
+    
+        try:
+            # deal with org and db
+            if mne == 'org':
+                pc = stoi(args[0])
+                continue
+            elif mne == 'db':
+                f.write(const)
+                pc = pc + len(const)
+                continue
+            
+            # replace labels with addresses
+            i = 0
+            for a in args:
+                if not a:
+                    continue
+                elif (sym[i] == 'label') or (sym[i] == '@label'):
+                    # labeled pointer uglyness
+                    if (a[0] == '@') and (a[1:] in labels):
+                        args[i] = '@' + str(labels[a[1:]])
+                        const = const + tokenize(mne, [args[i]])[1]
+                    else:
+                        # check if constant needs to be a relative address
+                        if mne in rinst:
+                            args[i] = str(labels[a] - pc)
+                        else:
+                            args[i] = str(labels[a])
+                        const = const + tokenize(mne, [args[i]])[1]  
+                i = i + 1
+            
+            # assemble to file
+            op, width = iset[mne][sym]
+            # theres gotta be a better way do deal with paged addresses
+            if mne in ['pcall', 'pjmp']:
+                op = op | ((stoi(args[0]) &  0x7FF) >> 8)
+                const = const[-1]
+            f.write(struct.pack('>B', op))
+            
+            # pad if needed
+            # i don't think this ever happens
+            #for i in range(width - len(const) - 1):
+            #    f.write(struct.pack('>B', 0))
+            
+            # check length and write constant or throw error
+            of = len(const) - width + 1
+            if of > 0:
+                if const[0] == ('\x00'):
+                    const = const[of:]
+                else:
+                    raise ValueError
+            f.write(const)
+            pc = pc + width
+        
+        except:
+            print '** second pass error **\nline:\n', line
+            raise
+
+    return f
+    
+if __name__ == '__main__':
+    f = open(sys.argv[1], 'r')
+    try:
+        b = open(sys.argv[2], 'wb')
+    except IndexError:
+        b = open('a.out', 'wb')
+    asm, labels = first_pass(f)
+    b = second_pass(b, asm, labels)
+    f.close()
+    b.close()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/language.py	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,357 @@
+#!/usr/bin/env python
+# language.py
+import struct
+
+# identifiers: immediate ints, pointers
+ids = ['#', '@']
+
+# valid reserved arguments for this instruction set
+vargs = ('', '@a+dptr', 'dptr', 'bs', '@a+pc', 
+         'a', 'c','r0', 'r1', 'r2', 'r3', 'ie',
+         'sp', 'flags', 'dpl', 'dph', '@dptr',
+         'sph', 'spl')
+
+# instructions that use relative addresses
+rinst = ('djnz', 'cjne', 'sjmp', 'jz', 'jnz', 
+         'jc', 'jnc', 'jpo', 'jpe', 'js', 'jns')
+
+# dictionary embedded dictionaries?
+#     for every mnemonic in the instruction set index
+#     there is an index of possible argument formats (symbols)
+#     with corresponding op codes and width
+iset =  {    'add': {    ('a', 'data'): [166, 2],
+                         ('a', '@dptr'): [167, 1],
+                         ('a', 'dph'): [164, 1],
+                         ('a', 'dpl'): [165, 1],
+                         ('a', 'r0'): [160, 1],
+                         ('a', 'r1'): [161, 1],
+                         ('a', 'r2'): [162, 1],
+                         ('a', 'r3'): [163, 1]},
+             'addc': {    ('a', 'data'): [174, 2],
+                          ('a', '@dptr'): [175, 1],
+                          ('a', 'dph'): [172, 1],
+                          ('a', 'dpl'): [173, 1],
+                          ('a', 'r0'): [168, 1],
+                          ('a', 'r1'): [169, 1],
+                          ('a', 'r2'): [170, 1],
+                          ('a', 'r3'): [171, 1]},
+             'anl': {    ('a', 'data'): [134, 2],
+                         ('a', '@dptr'): [135, 1],
+                         ('a', 'dph'): [132, 1],
+                         ('a', 'dpl'): [133, 1],
+                         ('a', 'r0'): [128, 1],
+                         ('a', 'r1'): [129, 1],
+                         ('a', 'r2'): [130, 1],
+                         ('a', 'r3'): [131, 1]},
+             'cjne': {    ('a', 'data', 'label'): [223, 3],
+                          ('a', 'data', 'rel8'): [223, 3],
+                          ('r0', 'data', 'label'): [212, 2],
+                          ('r0', 'data', 'rel8'): [212, 2],
+                          ('r1', 'data', 'label'): [213, 2],
+                          ('r1', 'data', 'rel8'): [213, 2],
+                          ('r2', 'data', 'label'): [214, 2],
+                          ('r2', 'data', 'rel8'): [214, 2],
+                          ('r3', 'data', 'label'): [215, 2],
+                          ('r3', 'data', 'rel8'): [215, 2]},
+             'clr': {    ('bs',): [11, 1], ('c',): [9, 1], ('ie',): [13, 1]},
+             'cpl': {    ('a',): [15, 1], ('c',): [14, 1]},
+             'da': {    ('a',): [250, 1]},
+             'dec': {    ('a',): [159, 1], ('dptr',): [157, 1]},
+             'div': {    ('r0', 'r1'): [249, 1]},
+             'djnz': {    ('r0', 'label'): [208, 2],
+                          ('r0', 'rel8'): [208, 2],
+                          ('r1', 'label'): [209, 2],
+                          ('r1', 'rel8'): [209, 2],
+                          ('r2', 'label'): [210, 2],
+                          ('r2', 'rel8'): [210, 2],
+                          ('r3', 'label'): [211, 2],
+                          ('r3', 'rel8'): [211, 2]},
+             'hlt': {    ('',): [255, 1]},
+             'in': {    ('a', 'addr'): [252, 2]},
+             'inc': {    ('a',): [158, 1], ('dptr',): [156, 1]},
+             'int': {    ('addr',): [254, 2]},
+             'jc': {    ('label',): [226, 2], ('rel8',): [226, 2]},
+             'jmp': {    ('@a+dptr',): [221, 1], ('@dptr',): [222, 1]},
+             'jnc': {    ('label',): [227, 2], ('rel8',): [227, 2]},
+             'jns': {    ('label',): [231, 2], ('rel8',): [231, 2]},
+             'jnz': {    ('label',): [225, 2], ('rel8',): [225, 2]},
+             'jpe': {    ('label',): [229, 2], ('rel8',): [229, 2]},
+             'jpo': {    ('label',): [228, 2], ('rel8',): [228, 2]},
+             'js': {    ('label',): [230, 2], ('rel8',): [230, 2]},
+             'jz': {    ('label',): [224, 2], ('rel8',): [224, 2]},
+             'laf': {    ('',): [18, 1]},
+             'lcall': {    ('addr',): [217, 3], ('label',): [217, 3]},
+             'ljmp': {    ('addr',): [216, 3], ('label',): [216, 3]},
+             'mov': {    ('@addr', 'a'): [29, 3],
+                         ('@dptr', 'a'): [31, 1],
+                         ('@dptr', 'dph'): [36, 1],
+                         ('@dptr', 'dpl'): [37, 1],
+                         ('@dptr', 'r0'): [32, 1],
+                         ('@dptr', 'r1'): [33, 1],
+                         ('@dptr', 'r2'): [34, 1],
+                         ('@dptr', 'r3'): [35, 1],
+                         ('@dptr', 'sph'): [38, 1],
+                         ('@dptr', 'spl'): [39, 1],
+                         ('@label', 'a'): [29, 3],
+                         ('a', 'data'): [21, 2],
+                         ('a', '@a+dptr'): [26, 1],
+                         ('a', '@a+pc'): [27, 1],
+                         ('a', '@addr'): [28, 3],
+                         ('a', '@dptr'): [30, 1],
+                         ('a', '@label'): [28, 3],
+                         ('a', 'addr'): [24, 3],
+                         ('a', 'dph'): [60, 1],
+                         ('a', 'dpl'): [61, 1],
+                         ('a', 'label'): [24, 3],
+                         ('a', 'r0'): [56, 1],
+                         ('a', 'r1'): [57, 1],
+                         ('a', 'r2'): [58, 1],
+                         ('a', 'r3'): [59, 1],
+                         ('a', 'sph'): [62, 1],
+                         ('a', 'spl'): [63, 1],
+                         ('addr', 'a'): [25, 3],
+                         ('dph', 'data'): [44, 2],
+                         ('dph', '@dptr'): [100, 1],
+                         ('dph', 'a'): [52, 1],
+                         ('dph', 'dpl'): [101, 1],
+                         ('dph', 'r0'): [96, 1],
+                         ('dph', 'r1'): [97, 1],
+                         ('dph', 'r2'): [98, 1],
+                         ('dph', 'r3'): [99, 1],
+                         ('dph', 'sph'): [102, 1],
+                         ('dph', 'spl'): [103, 1],
+                         ('dpl', 'data'): [45, 2],
+                         ('dpl', '@dptr'): [109, 1],
+                         ('dpl', 'a'): [53, 1],
+                         ('dpl', 'dph'): [108, 1],
+                         ('dpl', 'r0'): [104, 1],
+                         ('dpl', 'r1'): [105, 1],
+                         ('dpl', 'r2'): [106, 1],
+                         ('dpl', 'r3'): [107, 1],
+                         ('dpl', 'sph'): [110, 1],
+                         ('dpl', 'spl'): [111, 1],
+                         ('dptr', 'data'): [23, 3],
+                         ('dptr', 'sp'): [19, 1],
+                         ('label', 'a'): [25, 3],
+                         ('r0', 'data'): [40, 2],
+                         ('r0', '@dptr'): [64, 1],
+                         ('r0', 'a'): [48, 1],
+                         ('r0', 'dph'): [68, 1],
+                         ('r0', 'dpl'): [69, 1],
+                         ('r0', 'r1'): [65, 1],
+                         ('r0', 'r2'): [66, 1],
+                         ('r0', 'r3'): [67, 1],
+                         ('r0', 'sph'): [70, 1],
+                         ('r0', 'spl'): [71, 1],
+                         ('r1', 'data'): [41, 2],
+                         ('r1', '@dptr'): [73, 1],
+                         ('r1', 'a'): [49, 1],
+                         ('r1', 'dph'): [76, 1],
+                         ('r1', 'dpl'): [77, 1],
+                         ('r1', 'r0'): [72, 1],
+                         ('r1', 'r2'): [74, 1],
+                         ('r1', 'r3'): [75, 1],
+                         ('r1', 'sph'): [78, 1],
+                         ('r1', 'spl'): [79, 1],
+                         ('r2', 'data'): [42, 2],
+                         ('r2', '@dptr'): [82, 1],
+                         ('r2', 'a'): [50, 1],
+                         ('r2', 'dph'): [84, 1],
+                         ('r2', 'dpl'): [85, 1],
+                         ('r2', 'r0'): [80, 1],
+                         ('r2', 'r1'): [81, 1],
+                         ('r2', 'r3'): [83, 1],
+                         ('r2', 'sph'): [86, 1],
+                         ('r2', 'spl'): [87, 1],
+                         ('r3', 'data'): [43, 2],
+                         ('r3', '@dptr'): [91, 1],
+                         ('r3', 'a'): [51, 1],
+                         ('r3', 'dph'): [92, 1],
+                         ('r3', 'dpl'): [93, 1],
+                         ('r3', 'r0'): [88, 1],
+                         ('r3', 'r1'): [89, 1],
+                         ('r3', 'r2'): [90, 1],
+                         ('r3', 'sph'): [94, 1],
+                         ('r3', 'spl'): [95, 1],
+                         ('sp', 'data'): [22, 3],
+                         ('sp', 'dptr'): [20, 1],
+                         ('sph', 'data'): [46, 2],
+                         ('sph', '@dptr'): [118, 1],
+                         ('sph', 'a'): [54, 1],
+                         ('sph', 'dph'): [116, 1],
+                         ('sph', 'dpl'): [117, 1],
+                         ('sph', 'r0'): [112, 1],
+                         ('sph', 'r1'): [113, 1],
+                         ('sph', 'r2'): [114, 1],
+                         ('sph', 'r3'): [115, 1],
+                         ('sph', 'spl'): [119, 1],
+                         ('spl', 'data'): [47, 2],
+                         ('spl', '@dptr'): [127, 1],
+                         ('spl', 'a'): [55, 1],
+                         ('spl', 'dph'): [124, 1],
+                         ('spl', 'dpl'): [125, 1],
+                         ('spl', 'r0'): [120, 1],
+                         ('spl', 'r1'): [121, 1],
+                         ('spl', 'r2'): [122, 1],
+                         ('spl', 'r3'): [123, 1],
+                         ('spl', 'sph'): [126, 1]},
+             'mul': {    ('r0', 'r1'): [248, 1]},
+             'nop': {    ('',): [0, 1]},
+             'orl': {    ('a', 'data'): [142, 2],
+                         ('a', '@dptr'): [143, 1],
+                         ('a', 'dph'): [140, 1],
+                         ('a', 'dpl'): [141, 1],
+                         ('a', 'r0'): [136, 1],
+                         ('a', 'r1'): [137, 1],
+                         ('a', 'r2'): [138, 1],
+                         ('a', 'r3'): [139, 1]},
+             'out': {    ('addr', 'a'): [253, 2]},
+             'pcall': {    ('addr',): [207, 2], ('label',): [200, 2]},
+             'pjmp': {    ('addr',): [199, 2], ('label',): [192, 2]},
+             'pop': {    ('a',): [246, 1],
+                         ('dph',): [244, 1],
+                         ('dpl',): [245, 1],
+                         ('flags',): [247, 1],
+                         ('r0',): [240, 1],
+                         ('r1',): [241, 1],
+                         ('r2',): [242, 1],
+                         ('r3',): [243, 1]},
+             'push': {    ('a',): [238, 1],
+                          ('dph',): [236, 1],
+                          ('dpl',): [237, 1],
+                          ('flags',): [239, 1],
+                          ('r0',): [232, 1],
+                          ('r1',): [233, 1],
+                          ('r2',): [234, 1],
+                          ('r3',): [235, 1]},
+             'ret': {    ('',): [218, 1]},
+             'reti': {    ('',): [219, 1]},
+             'rl': {    ('a',): [152, 1]},
+             'rlc': {    ('a',): [153, 1]},
+             'rr': {    ('a',): [154, 1]},
+             'rrc': {    ('a',): [155, 1]},
+             'set': {    ('bs',): [10, 1], ('c',): [8, 1], ('ie',): [12, 1]},
+             'sfa': {    ('',): [17, 1]},
+             'sjmp': {    ('label',): [220, 2], ('rel8',): [220, 2]},
+             'sub': {    ('a', 'data'): [182, 2],
+                         ('a', '@dptr'): [183, 1],
+                         ('a', 'dph'): [180, 1],
+                         ('a', 'dpl'): [181, 1],
+                         ('a', 'r0'): [176, 1],
+                         ('a', 'r1'): [177, 1],
+                         ('a', 'r2'): [178, 1],
+                         ('a', 'r3'): [179, 1]},
+             'subb': {    ('a', 'data'): [190, 2],
+                          ('a', '@dptr'): [191, 1],
+                          ('a', 'dph'): [188, 1],
+                          ('a', 'dpl'): [189, 1],
+                          ('a', 'r0'): [184, 1],
+                          ('a', 'r1'): [185, 1],
+                          ('a', 'r2'): [186, 1],
+                          ('a', 'r3'): [187, 1]},
+             'xcsd': {    ('',): [16, 1]},
+             'xrl': {    ('a', 'data'): [150, 2],
+                         ('a', '@dptr'): [151, 1],
+                         ('a', 'dph'): [148, 1],
+                         ('a', 'dpl'): [149, 1],
+                         ('a', 'r0'): [144, 1],
+                         ('a', 'r1'): [145, 1],
+                         ('a', 'r2'): [146, 1],
+                         ('a', 'r3'): [147, 1]}}
+
+# take interger representation as string and return int:
+# supports:
+#   decimal (no prefix)
+#   octal (0)
+#   hex (0x) 
+#   binary (0b)
+# return 'NaN' if it is none of the above
+def stoi(s):
+    try:
+        return int(s, 0)
+    except:
+        return 'NaN'
+
+
+# take a mnemonic and it's arguments
+# identify constant data:
+#   pack that data into a bit string
+# return hashable format symbol and data
+def tokenize(mne, args):
+    sym = []
+    data = ''
+
+    for a in args:
+        # tokenize reserved arguments immediatly (not case sensitive)
+        # determine arg type and remove identifier if needed
+        # unprefixed arguments are addresses so this is the default
+        arg_type = 'addr'
+        if a.lower() in vargs:
+            sym.append(a.lower())
+            continue
+        elif a[0] in ids:
+            arg_type = a[0]
+            a = a[1:]
+        
+        # evaluate inline calculations
+        if (a[0] == '(') and (a[-1] == ')'):
+            a = str(eval(a[1:-1]))
+        # evaluate strings
+        elif (a[0] == '\'') and (a[-1] == '\''):
+            if len(a) == 3:
+                a = str(struct.unpack('>B', a[1:-1])[0])
+            elif len(a) == 4:
+                a = str(struct.unpack('>H', a[1:-1])[0])
+            else:
+                data = a[1:-1]
+                continue
+
+        # non-numbers must be a label or a source code error
+        if stoi(a) == 'NaN':
+            if arg_type == '@':
+                sym.append('@label')
+                continue
+            else:
+                sym.append('label')
+                continue   
+        # check if numbers are negative and remove sign if needed
+        elif a[0] == '-':
+            is_neg = 1
+            a = a[1:]
+        else:
+            is_neg = 0
+        
+        # abolsute addresses and immediate ints are
+        # are always 16 bits. second_pass() checks
+        # if values are too long for instruction.
+        # addresses
+        if arg_type == 'addr':
+            if mne in rinst:
+                sym.append('rel8')
+                fmt = '>b'
+            else:
+                sym.append('addr')
+                fmt = '>H'
+            val = stoi(a)
+            data = data + struct.pack(fmt, val)
+            continue
+        # immediate ints (signed when negative)
+        elif arg_type == '#':
+            sym.append('data')
+            if is_neg:
+                val = stoi('-' + a)
+                fmt = '>h'
+            else:
+                val = stoi(a)
+                fmt = '>H'
+            data = data + struct.pack(fmt, val)
+            continue
+        # pointers
+        elif arg_type == '@':
+            sym.append('@addr')
+            val = stoi(a)
+            data = data + struct.pack('>H', val)
+            continue
+
+    return tuple(sym), data
+
Binary file asm/language.pyc has changed
Binary file assembler/.language.py.swp has changed
--- a/assembler/assembler.py	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-#!/usr/bin/env python2
-# assembler.py
-import struct
-import sys
-from language import *
-
-# take source file and return preprocessed assembly code
-# for each non-empty line in the file:
-#   remove comments from source
-#   replace equated strings
-#   store label definitions and remove label from source
-#   store new equates
-#   make hashable format symbol from arguments
-#   identify and save constant data
-#   save instruction, arguments, symbol and data to list
-# also prepares org and db instructions for second_pass()
-def first_pass(f):
-    asm = []
-    labels = {}
-    equates = {}
-    pc = 0
-    
-    # read file into list, remove blank line
-    f.seek(0)
-    source_code = filter(lambda l: l != '\n', f.readlines())  
-    
-    # <line> ::= [<statement>] [";"<comment>] <EOL>
-    for line in source_code:  
-        try:
-            # remove trailing whitespace and comments
-            line = line.strip()
-            for i in range(len(line)):
-                if line[i] == ';':
-                    line = line[:i]
-                    break
-            
-            # <statement> ::= [ <label> ":"] <mnemonic> [<arguments>]
-            #                 | <label> ":"
-            #                 | "EOF"
-            statement = line.split()
-            if not statement:
-                continue
-
-            # replace equated strings
-            # because this happens on the first pass
-            # equates must be assigned before they are used
-            i = 1
-            for s in statement[1:]:
-                # replace any equates already stored
-                # remove prefixes and suffixes before attempting to replace
-                prefix = suffix = ''
-                # prefixes
-                if s[0] in ids:
-                    prefix = prefix + s[0]
-                    s = s[1:]
-                if s[0] == '(':
-                    prefix = prefix + s[0]
-                    s = s[1:]
-                # suffixes
-                if s and (s[-1] == ','):
-                    suffix = suffix + s[-1]
-                    s = s[:-1]
-                if s and (s[-1] == ')'):
-                    suffix = s[-1] + suffix
-                    s = s[:-1]
-                # replace and put removed characters back
-                if s in equates:
-                    statement[i] = prefix + equates[s] + suffix
-                # labels can be used in equates but they have
-                # to be assigned before they are used as well
-                elif s in labels:
-                    if statement[0] in rinst:
-                        statement[i] = prefix + str(labels[s] - pc) + suffix
-                    else:
-                        statement[i] = prefix + str(labels[s]) + suffix
-                i = i + 1                   
-            
-            # deal with org
-            if statement[0].lower() == 'org':
-                asm.append(['org', statement[1:], ('',), ''])
-                pc = stoi(statement[1])
-                continue
-            # if needed update index and remove label 
-            elif statement[0][-1] == ':':
-                labels[statement[0][:-1]] = pc;
-                del statement[0]
-            # store equates
-            # these are case sensative
-            elif (len(statement) >= 3) and (statement[1].lower() == 'equ'):
-                equates[statement[0]] = ' '.join(statement[2:])
-                continue
-                
-            if not statement:
-                continue
-            
-            # <statement> ::= <mnemonic> [<arguments>]
-            mne = statement[0].lower()
-            args = ''.join(statement[1:]).split(',')
-        
-            # deal with db
-            if mne == 'db':
-                const = ''
-                for a in args:
-                    data = tokenize(mne, ['#' + a])[1]
-                    # deal with leading zeros
-                    # skip zeros unless zero is the 
-                    # only number
-                    if data == '\x00\x00':
-                        const = const + '\x00'
-                        continue
-                    i = 0
-                    for c in data:
-                        if c == '\x00':
-                            i = i + 1
-                        else:
-                            pass
-                    const = const + data[i:]
-                asm.append([mne, args, ('',), const])
-                pc = pc + len(const)
-                continue
-            
-            # tokenize
-            sym, const = tokenize(mne, args)
-            asm.append([mne, args, sym, const])
-            # increase pc
-            width = iset[mne][sym][1]
-            pc = pc + width
-        
-        except:
-            print ' ** first pass error **\nline:\n', line
-            raise
-    
-    return asm, labels
-
-# take a preprocessed object asm and write machine code to binary file
-# for each line of asm:
-#   check if it's an org or db command deal with it accordingly
-#   check if arguments are labels and replace with value
-#   write instruction to file
-def second_pass(f, asm, labels):
-    pc = 0
-
-    for line in asm:
-        f.seek(pc)
-        mne, args, sym, const = line
-    
-        try:
-            # deal with org and db
-            if mne == 'org':
-                pc = stoi(args[0])
-                continue
-            elif mne == 'db':
-                f.write(const)
-                pc = pc + len(const)
-                continue
-            
-            # replace labels with addresses
-            i = 0
-            for a in args:
-                if not a:
-                    continue
-                elif (sym[i] == 'label') or (sym[i] == '@label'):
-                    # labeled pointer uglyness
-                    if (a[0] == '@') and (a[1:] in labels):
-                        args[i] = '@' + str(labels[a[1:]])
-                        const = const + tokenize(mne, [args[i]])[1]
-                    else:
-                        # check if constant needs to be a relative address
-                        if mne in rinst:
-                            args[i] = str(labels[a] - pc)
-                        else:
-                            args[i] = str(labels[a])
-                        const = const + tokenize(mne, [args[i]])[1]  
-                i = i + 1
-            
-            # assemble to file
-            op, width = iset[mne][sym]
-            # theres gotta be a better way do deal with paged addresses
-            if mne in ['pcall', 'pjmp']:
-                op = op | ((stoi(args[0]) &  0x7FF) >> 8)
-                const = const[-1]
-            f.write(struct.pack('>B', op))
-            
-            # pad if needed
-            # i don't think this ever happens
-            #for i in range(width - len(const) - 1):
-            #    f.write(struct.pack('>B', 0))
-            
-            # check length and write constant or throw error
-            of = len(const) - width + 1
-            if of > 0:
-                if const[0] == ('\x00'):
-                    const = const[of:]
-                else:
-                    raise ValueError
-            f.write(const)
-            pc = pc + width
-        
-        except:
-            print '** second pass error **\nline:\n', line
-            raise
-
-    return f
-    
-if __name__ == '__main__':
-    f = open(sys.argv[1], 'r')
-    try:
-        b = open(sys.argv[2], 'wb')
-    except IndexError:
-        b = open('a.out', 'wb')
-    asm, labels = first_pass(f)
-    b = second_pass(b, asm, labels)
-    f.close()
-    b.close()
-
--- a/assembler/language.py	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,369 +0,0 @@
-#!/usr/bin/env python
-# language.py
-import struct
-
-# identifiers: immediate ints, pointers
-ids = ['#', '@']
-
-# valid reserved arguments for this instruction set
-vargs = ('', '@a+dptr', 'dptr', 'bs', '@a+pc', 
-         'a', 'c','r0', 'r1', 'r2', 'r3', 'ie',
-         'sp', 'flags', 'dpl', 'dph', '@dptr',
-         'sph', 'spl')
-
-# instructions that use relative addresses
-rinst = ('djnz', 'cjne', 'sjmp', 'jz', 'jnz', 
-         'jc', 'jnc', 'jpo', 'jpe', 'js', 'jns')
-
-# dictionary embedded dictionaries?
-#     for every mnemonic in the instruction set index
-#     there is an index of possible argument formats (symbols)
-#     with corresponding op codes and width
-iset =  {    'add': {    ('a', 'data'): [166, 2],
-                         ('a', '@dptr'): [167, 1],
-                         ('a', 'dph'): [164, 1],
-                         ('a', 'dpl'): [165, 1],
-                         ('a', 'r0'): [160, 1],
-                         ('a', 'r1'): [161, 1],
-                         ('a', 'r2'): [162, 1],
-                         ('a', 'r3'): [163, 1]},
-             'addc': {    ('a', 'data'): [174, 2],
-                          ('a', '@dptr'): [175, 1],
-                          ('a', 'dph'): [172, 1],
-                          ('a', 'dpl'): [173, 1],
-                          ('a', 'r0'): [168, 1],
-                          ('a', 'r1'): [169, 1],
-                          ('a', 'r2'): [170, 1],
-                          ('a', 'r3'): [171, 1]},
-             'anl': {    ('a', 'data'): [134, 2],
-                         ('a', '@dptr'): [135, 1],
-                         ('a', 'dph'): [132, 1],
-                         ('a', 'dpl'): [133, 1],
-                         ('a', 'r0'): [128, 1],
-                         ('a', 'r1'): [129, 1],
-                         ('a', 'r2'): [130, 1],
-                         ('a', 'r3'): [131, 1]},
-             'cjne': {    ('a', 'data', 'label'): [223, 3],
-                          ('a', 'data', 'rel8'): [223, 3],
-                          ('r0', 'data', 'label'): [212, 2],
-                          ('r0', 'data', 'rel8'): [212, 2],
-                          ('r1', 'data', 'label'): [213, 2],
-                          ('r1', 'data', 'rel8'): [213, 2],
-                          ('r2', 'data', 'label'): [214, 2],
-                          ('r2', 'data', 'rel8'): [214, 2],
-                          ('r3', 'data', 'label'): [215, 2],
-                          ('r3', 'data', 'rel8'): [215, 2]},
-             'clr': {    ('bs',): [11, 1], ('c',): [9, 1], ('ie',): [13, 1]},
-             'cpl': {    ('a',): [15, 1], ('c',): [14, 1]},
-             'da': {    ('a',): [250, 1]},
-             'dec': {    ('a',): [159, 1], ('dptr',): [157, 1]},
-             'div': {    ('r0', 'r1'): [249, 1]},
-             'djnz': {    ('r0', 'label'): [208, 2],
-                          ('r0', 'rel8'): [208, 2],
-                          ('r1', 'label'): [209, 2],
-                          ('r1', 'rel8'): [209, 2],
-                          ('r2', 'label'): [210, 2],
-                          ('r2', 'rel8'): [210, 2],
-                          ('r3', 'label'): [211, 2],
-                          ('r3', 'rel8'): [211, 2]},
-             'hlt': {    ('',): [255, 1]},
-             'in': {    ('a', 'addr'): [252, 2]},
-             'inc': {    ('a',): [158, 1], ('dptr',): [156, 1]},
-             'int': {    ('addr',): [254, 2]},
-             'jc': {    ('label',): [226, 2], ('rel8',): [226, 2]},
-             'jmp': {    ('@a+dptr',): [221, 1], ('@dptr',): [222, 1]},
-             'jnc': {    ('label',): [227, 2], ('rel8',): [227, 2]},
-             'jns': {    ('label',): [231, 2], ('rel8',): [231, 2]},
-             'jnz': {    ('label',): [225, 2], ('rel8',): [225, 2]},
-             'jpe': {    ('label',): [229, 2], ('rel8',): [229, 2]},
-             'jpo': {    ('label',): [228, 2], ('rel8',): [228, 2]},
-             'js': {    ('label',): [230, 2], ('rel8',): [230, 2]},
-             'jz': {    ('label',): [224, 2], ('rel8',): [224, 2]},
-             'laf': {    ('',): [18, 1]},
-             'lcall': {    ('addr',): [217, 3], ('label',): [217, 3]},
-             'ljmp': {    ('addr',): [216, 3], ('label',): [216, 3]},
-             'mov': {    ('@addr', 'a'): [29, 3],
-                         ('@dptr', 'a'): [31, 1],
-                         ('@dptr', 'dph'): [36, 1],
-                         ('@dptr', 'dpl'): [37, 1],
-                         ('@dptr', 'r0'): [32, 1],
-                         ('@dptr', 'r1'): [33, 1],
-                         ('@dptr', 'r2'): [34, 1],
-                         ('@dptr', 'r3'): [35, 1],
-                         ('@dptr', 'sph'): [38, 1],
-                         ('@dptr', 'spl'): [39, 1],
-                         ('@label', 'a'): [29, 3],
-                         ('a', 'data'): [21, 2],
-                         ('a', '@a+dptr'): [26, 1],
-                         ('a', '@a+pc'): [27, 1],
-                         ('a', '@addr'): [28, 3],
-                         ('a', '@dptr'): [30, 1],
-                         ('a', '@label'): [28, 3],
-                         ('a', 'addr'): [24, 3],
-                         ('a', 'dph'): [60, 1],
-                         ('a', 'dpl'): [61, 1],
-                         ('a', 'label'): [24, 3],
-                         ('a', 'r0'): [56, 1],
-                         ('a', 'r1'): [57, 1],
-                         ('a', 'r2'): [58, 1],
-                         ('a', 'r3'): [59, 1],
-                         ('a', 'sph'): [62, 1],
-                         ('a', 'spl'): [63, 1],
-                         ('addr', 'a'): [25, 3],
-                         ('dph', 'data'): [44, 2],
-                         ('dph', '@dptr'): [100, 1],
-                         ('dph', 'a'): [52, 1],
-                         ('dph', 'dpl'): [101, 1],
-                         ('dph', 'r0'): [96, 1],
-                         ('dph', 'r1'): [97, 1],
-                         ('dph', 'r2'): [98, 1],
-                         ('dph', 'r3'): [99, 1],
-                         ('dph', 'sph'): [102, 1],
-                         ('dph', 'spl'): [103, 1],
-                         ('dpl', 'data'): [45, 2],
-                         ('dpl', '@dptr'): [109, 1],
-                         ('dpl', 'a'): [53, 1],
-                         ('dpl', 'dph'): [108, 1],
-                         ('dpl', 'r0'): [104, 1],
-                         ('dpl', 'r1'): [105, 1],
-                         ('dpl', 'r2'): [106, 1],
-                         ('dpl', 'r3'): [107, 1],
-                         ('dpl', 'sph'): [110, 1],
-                         ('dpl', 'spl'): [111, 1],
-                         ('dptr', 'data'): [23, 3],
-                         ('dptr', 'sp'): [19, 1],
-                         ('label', 'a'): [25, 3],
-                         ('r0', 'data'): [40, 2],
-                         ('r0', '@dptr'): [64, 1],
-                         ('r0', 'a'): [48, 1],
-                         ('r0', 'dph'): [68, 1],
-                         ('r0', 'dpl'): [69, 1],
-                         ('r0', 'r1'): [65, 1],
-                         ('r0', 'r2'): [66, 1],
-                         ('r0', 'r3'): [67, 1],
-                         ('r0', 'sph'): [70, 1],
-                         ('r0', 'spl'): [71, 1],
-                         ('r1', 'data'): [41, 2],
-                         ('r1', '@dptr'): [73, 1],
-                         ('r1', 'a'): [49, 1],
-                         ('r1', 'dph'): [76, 1],
-                         ('r1', 'dpl'): [77, 1],
-                         ('r1', 'r0'): [72, 1],
-                         ('r1', 'r2'): [74, 1],
-                         ('r1', 'r3'): [75, 1],
-                         ('r1', 'sph'): [78, 1],
-                         ('r1', 'spl'): [79, 1],
-                         ('r2', 'data'): [42, 2],
-                         ('r2', '@dptr'): [82, 1],
-                         ('r2', 'a'): [50, 1],
-                         ('r2', 'dph'): [84, 1],
-                         ('r2', 'dpl'): [85, 1],
-                         ('r2', 'r0'): [80, 1],
-                         ('r2', 'r1'): [81, 1],
-                         ('r2', 'r3'): [83, 1],
-                         ('r2', 'sph'): [86, 1],
-                         ('r2', 'spl'): [87, 1],
-                         ('r3', 'data'): [43, 2],
-                         ('r3', '@dptr'): [91, 1],
-                         ('r3', 'a'): [51, 1],
-                         ('r3', 'dph'): [92, 1],
-                         ('r3', 'dpl'): [93, 1],
-                         ('r3', 'r0'): [88, 1],
-                         ('r3', 'r1'): [89, 1],
-                         ('r3', 'r2'): [90, 1],
-                         ('r3', 'sph'): [94, 1],
-                         ('r3', 'spl'): [95, 1],
-                         ('sp', 'data'): [22, 3],
-                         ('sp', 'dptr'): [20, 1],
-                         ('sph', 'data'): [46, 2],
-                         ('sph', '@dptr'): [118, 1],
-                         ('sph', 'a'): [54, 1],
-                         ('sph', 'dph'): [116, 1],
-                         ('sph', 'dpl'): [117, 1],
-                         ('sph', 'r0'): [112, 1],
-                         ('sph', 'r1'): [113, 1],
-                         ('sph', 'r2'): [114, 1],
-                         ('sph', 'r3'): [115, 1],
-                         ('sph', 'spl'): [119, 1],
-                         ('spl', 'data'): [47, 2],
-                         ('spl', '@dptr'): [127, 1],
-                         ('spl', 'a'): [55, 1],
-                         ('spl', 'dph'): [124, 1],
-                         ('spl', 'dpl'): [125, 1],
-                         ('spl', 'r0'): [120, 1],
-                         ('spl', 'r1'): [121, 1],
-                         ('spl', 'r2'): [122, 1],
-                         ('spl', 'r3'): [123, 1],
-                         ('spl', 'sph'): [126, 1]},
-             'mul': {    ('r0', 'r1'): [248, 1]},
-             'nop': {    ('',): [0, 1]},
-             'orl': {    ('a', 'data'): [142, 2],
-                         ('a', '@dptr'): [143, 1],
-                         ('a', 'dph'): [140, 1],
-                         ('a', 'dpl'): [141, 1],
-                         ('a', 'r0'): [136, 1],
-                         ('a', 'r1'): [137, 1],
-                         ('a', 'r2'): [138, 1],
-                         ('a', 'r3'): [139, 1]},
-             'out': {    ('addr', 'a'): [253, 2]},
-             'pcall': {    ('addr',): [207, 2], ('label',): [200, 2]},
-             'pjmp': {    ('addr',): [199, 2], ('label',): [192, 2]},
-             'pop': {    ('a',): [246, 1],
-                         ('dph',): [244, 1],
-                         ('dpl',): [245, 1],
-                         ('flags',): [247, 1],
-                         ('r0',): [240, 1],
-                         ('r1',): [241, 1],
-                         ('r2',): [242, 1],
-                         ('r3',): [243, 1]},
-             'push': {    ('a',): [238, 1],
-                          ('dph',): [236, 1],
-                          ('dpl',): [237, 1],
-                          ('flags',): [239, 1],
-                          ('r0',): [232, 1],
-                          ('r1',): [233, 1],
-                          ('r2',): [234, 1],
-                          ('r3',): [235, 1]},
-             'ret': {    ('',): [218, 1]},
-             'reti': {    ('',): [219, 1]},
-             'rl': {    ('a',): [152, 1]},
-             'rlc': {    ('a',): [153, 1]},
-             'rr': {    ('a',): [154, 1]},
-             'rrc': {    ('a',): [155, 1]},
-             'set': {    ('bs',): [10, 1], ('c',): [8, 1], ('ie',): [12, 1]},
-             'sfa': {    ('',): [17, 1]},
-             'sjmp': {    ('label',): [220, 2], ('rel8',): [220, 2]},
-             'sub': {    ('a', 'data'): [182, 2],
-                         ('a', '@dptr'): [183, 1],
-                         ('a', 'dph'): [180, 1],
-                         ('a', 'dpl'): [181, 1],
-                         ('a', 'r0'): [176, 1],
-                         ('a', 'r1'): [177, 1],
-                         ('a', 'r2'): [178, 1],
-                         ('a', 'r3'): [179, 1]},
-             'subb': {    ('a', 'data'): [190, 2],
-                          ('a', '@dptr'): [191, 1],
-                          ('a', 'dph'): [188, 1],
-                          ('a', 'dpl'): [189, 1],
-                          ('a', 'r0'): [184, 1],
-                          ('a', 'r1'): [185, 1],
-                          ('a', 'r2'): [186, 1],
-                          ('a', 'r3'): [187, 1]},
-             'xcsd': {    ('',): [16, 1]},
-             'xrl': {    ('a', 'data'): [150, 2],
-                         ('a', '@dptr'): [151, 1],
-                         ('a', 'dph'): [148, 1],
-                         ('a', 'dpl'): [149, 1],
-                         ('a', 'r0'): [144, 1],
-                         ('a', 'r1'): [145, 1],
-                         ('a', 'r2'): [146, 1],
-                         ('a', 'r3'): [147, 1]}}
-
-# take interger representation as string and return int:
-# supports:
-#   decimal (no prefix)
-#   octal (0)
-#   hex (0x) 
-#   binary (0b)
-# return 'NaN' if it is none of the above
-def stoi(s):
-    try:
-        if s[0] == '0':
-            return int(s, 8)
-        else:
-            raise 
-    except:
-        try:
-           return int(s)
-        except ValueError:
-            try:
-                return int(s, 16)
-            except ValueError:
-                try:
-                    return int(s, 2)
-                except ValueError:
-                    return 'NaN'
-
-
-# take a mnemonic and it's arguments
-# identify constant data:
-#   pack that data into a bit string
-# return hashable format symbol and data
-def tokenize(mne, args):
-    sym = []
-    data = ''
-
-    for a in args:
-        # tokenize reserved arguments immediatly (not case sensitive)
-        # determine arg type and remove identifier if needed
-        # unprefixed arguments are addresses so this is the default
-        arg_type = 'addr'
-        if a.lower() in vargs:
-            sym.append(a.lower())
-            continue
-        elif a[0] in ids:
-            arg_type = a[0]
-            a = a[1:]
-        
-        # evaluate inline calculations
-        if (a[0] == '(') and (a[-1] == ')'):
-            a = str(eval(a[1:-1]))
-        # evaluate strings
-        elif (a[0] == '\'') and (a[-1] == '\''):
-            if len(a) == 3:
-                a = str(struct.unpack('>B', a[1:-1])[0])
-            elif len(a) == 4:
-                a = str(struct.unpack('>H', a[1:-1])[0])
-            else:
-                data = a[1:-1]
-                continue
-
-        # non-numbers must be a label or a source code error
-        if stoi(a) == 'NaN':
-            if arg_type == '@':
-                sym.append('@label')
-                continue
-            else:
-                sym.append('label')
-                continue   
-        # check if numbers are negative and remove sign if needed
-        elif a[0] == '-':
-            is_neg = 1
-            a = a[1:]
-        else:
-            is_neg = 0
-        
-        # abolsute addresses and immediate ints are
-        # are always 16 bits. second_pass() checks
-        # if values are too long for instruction.
-        # addresses
-        if arg_type == 'addr':
-            if mne in rinst:
-                sym.append('rel8')
-                fmt = '>b'
-            else:
-                sym.append('addr')
-                fmt = '>H'
-            val = stoi(a)
-            data = data + struct.pack(fmt, val)
-            continue
-        # immediate ints (signed when negative)
-        elif arg_type == '#':
-            sym.append('data')
-            if is_neg:
-                val = stoi('-' + a)
-                fmt = '>h'
-            else:
-                val = stoi(a)
-                fmt = '>H'
-            data = data + struct.pack(fmt, val)
-            continue
-        # pointers
-        elif arg_type == '@':
-            sym.append('@addr')
-            val = stoi(a)
-            data = data + struct.pack('>H', val)
-            continue
-
-    return tuple(sym), data
-
Binary file assembler/language.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build.sh	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,5 @@
+#!/bin/bash
+gcc -std=c89 emu/main.c emu/mem.c -o bin/emu
+killall emu;
+rm out;
+ipython -i dbg/dbg.py
Binary file dbg/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbg/cli.py	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,12 @@
+from assembler.language import *
+from struct import pack
+#from debugger import dbg
+
+while True:
+    c = raw_input().lower().split()
+    mne = c[0]
+    args = ''.join(c[1:]).split(',')
+    sym, data = tokenize(mne, args)
+    op = pack('>B', iset[mne][sym][0])
+    print op, data
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbg/dbg.py	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+# dbg.py - debug client
+import struct
+import os, sys
+from subprocess import Popen, PIPE, STDOUT
+
+emu = Popen(['./a.out'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
+
+def snd(m):
+    emu.stdin.write(struct.pack('>B', m))
+
+def rcv():
+    with open('out', 'r') as f:
+        c = f.read()
+    return c
+
+def step():
+    snd(0x00)
+
+def run():
+    snd(0x01)
+
+def set_reg(reg, data):
+    snd(0x02)
+    snd(reg)  # reg
+    snd(data) # data
+
+def get_reg(reg):
+    snd(0x03)
+    snd(reg)  # reg
+    #return rcv()
+
+def set_flag(flag, on):
+    snd(0x04)
+    if on == 0:
+        snd(flag)
+        snd(0)
+    else:
+        snd(flag)
+        snd(1)
+
+def get_flag(flag):
+    snd(0x05)
+    snd(flag)
+    #return rcv()
+
+def set_block(addrh, addrl, lenh, lenl, data):
+    snd(0x06)
+    snd(addrh) # address high byte
+    snd(addrl) # address low byte
+    snd(lenh)
+    snd(lenl)
+    for b in data:
+        snd(b) # data
+
+def get_block(addrh, addrl, lenh, lenl):
+    block = []
+    snd(0x07)
+    snd(addrh) # address high byte
+    snd(addrl) # address low byte
+    snd(lenh)  
+    snd(lenl) 
+    #lc = 0
+    #while lc != l:
+    #    lc = os.path.getsize('out');
+    #return rcv()
+
+registers = {   
+        'r0':0,
+        'r1':1,
+        'r2':2,
+        'r3':3,
+        'dph':4,
+        'dpl':5,
+        'sph':6,
+        'spl':7,
+        'a':8,
+        'flags':9
+        }
+
+cmds = {
+        'step':step,
+        'run':run,
+        'sr':set_reg,
+        'gr':get_reg,
+        'sf':set_flag,
+        'gf':get_flag,
+        'sb':set_block,
+        'gb':get_block
+        }
Binary file dbg/dbg.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/general/.~lock.elb816_opcodes.ods#	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,1 @@
+,jmz,xthUnk,06.04.2014 22:58,file:///home/jmz/.config/libreoffice/4;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emu/iset.c	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,427 @@
+/* iset.c
+ * IR functions */
+#include <stdlib.h>
+#include "iset.h"
+#include "mem.h"
+
+/* useful macros */
+#define NNN (IR & 0x07)
+#define MMM ((IR & 0x38) >> 3)
+
+/* 0x00 - NOP */
+void
+NOP(void) {    
+}
+
+/* 0x08 - SET C
+ * 0x0A - SET BS
+ * 0x0C - SET IE */
+void
+SET(void) {
+    switch (IR) {
+        
+        case 0x08:
+            set_flag(0x07, 0x01);
+            break;
+        
+        case 0x0A:
+            set_flag(0x00, 0x01);
+            break;
+        
+        case 0x0C:
+            set_flag(0x01, 0x01);
+            break;
+        
+        default:
+            break;
+    }
+}
+
+/* 0x09 - CLR C
+ * 0x0B - CLR BS
+ * 0x0D - CLR IE */
+void
+CLR(void) {
+    switch (IR) {
+        
+        case 0x09:
+            set_flag(0x07, 0x00);
+            break;
+        
+        case 0x0B:
+            set_flag(0x00, 0x00);
+            break;
+        
+        case 0x0D:
+            set_flag(0x01, 0x00);
+            break;
+        
+        default:
+            break;
+    }    
+}
+
+/* 0x0E - CPL C
+ * 0x0F - CPL A */
+void
+CPL(void) {
+    switch (IR) {
+        
+        case 0x0E:
+            if (get_flag(0x07) == 0) {
+                set_flag(0x07, 0x01);
+            }
+            else {
+                set_flag(0x07, 0x00);
+            }
+        
+        case 0x0F:
+            A = ~A;
+            break;
+        
+        default:
+            break;
+    }
+}
+
+/* 0x10 - XCSD */
+void
+XCSD(void) {
+    tmpw = get_wide(SP);
+    set_wide(SP, get_wide(DPTR));
+    set_wide(DPTR, tmpw);
+}
+
+/* 0x11 - SFA */
+void
+SFA(void) {
+    A = flags;
+}
+
+/* 0x12 - LAF */
+void
+LAF(void) {
+    flags = A;   
+}
+
+/* 0b00010XXX - special MOVs
+ * 0b00011XXX - direct, indirect and indexed MOVs
+ * 0b00100nnn - register-indirect MOVs - MOV @DPTR, Rn
+ * 0b00101nnn - immediate movs - MOV Rn, #data8
+ * 0b00110nnn - MOV Rn, A
+ * 0b00111nnn - MOV A, Rn
+ * 0b01mmmnnn - 64 register move instructions
+ *
+ * this is a mess */
+void
+MOV(void) {
+    switch (IR & 0x40) {
+       
+        case 0x00:
+            switch (IR & 0xF8) {
+                
+                /* 0b00010XXX */
+                case 0x10:
+                    switch (NNN) {
+                        
+                        /* MOV DPTR, SP */
+                        case 3:
+                            set_wide(DPTR, get_wide(SP));
+                            break;
+                        
+                        /* MOV SP, DPTR */
+                        case 4:
+                            set_wide(SP, get_wide(DPTR));
+                            break;
+                        
+                        /* MOV A, #data8 */
+                        case 5:
+                            A = fetch();
+                            break;
+                        
+                        /* MOV SP, #data16 */
+                        case 6:
+                            set_wide(SP, fetch_wide());
+                            break;
+                        
+                        /* MOV DPTR, #data16 */
+                        case 7:
+                            set_wide(DPTR, fetch_wide());
+                            break;
+                        
+                        default:
+                            break;
+                    }
+                    break;
+                
+                /* 0b00011XXX */
+                case 0x18:
+                    switch (NNN) {
+                        
+                        /* MOV A, addr16 */
+                        case 0:
+                            set_wide(TMP, fetch_wide());
+                            A = mem[get_wide(TMP)];
+                            break;
+                        
+                        /* MOV addr16, A */
+                        case 1:
+                            set_wide(TMP, fetch_wide());
+                            mem[get_wide(TMP)] = A;
+                            break;
+                        
+                        /* MOV A, @A+DPTR */
+                        case 2:
+                            A = mem[A + get_wide(DPTR)];
+                            break;
+                        
+                        /* MOV A, @A+PC */
+                        case 3:
+                            A = mem[A + get_wide(PC)];
+                            break;
+                        
+                        /* MOV A, @addr16 */
+                        case 4:
+                            set_wide(TMP, fetch_wide());
+                            A = mem[mem[get_wide(TMP)]];
+                            break;
+                        
+                        /* MOV @addr16, A */ 
+                        case 5:
+                            set_wide(TMP, fetch_wide());
+                            mem[mem[get_wide(TMP)]] = A;
+                            break;
+                        
+                        /* MOV A, @DPTR */
+                        case 6:
+                            A = mem[get_wide(DPTR)];
+                            break;
+                        
+                        /* MOV @DPTR, A */
+                        case 7:
+                            mem[get_wide(DPTR)] = A;
+                            break;
+                        
+                        default:
+                            break;
+                    }
+                    break;
+                
+                /* 0b00100nnn */
+                case 0x20:
+                    break;
+                
+                /* 0b00101nnn */
+                case 0x28:
+                    break;
+                
+                /* 0b00110nnn */
+                case 0x30:
+                    break;
+                
+                /* 0b00111nnn */
+                case 0x38:
+                    break;
+                
+                default:
+                    break;
+                }
+            break;
+        
+        /* 0b01mmmnnn */
+        case 0x40:
+            break;
+        
+        default:
+            break;
+    }
+}
+
+void
+ANL(void) {
+}
+
+void
+ORL(void) {
+}
+
+void
+XRL(void) {
+
+}
+
+/* 0x98 - RL A */
+void
+RL(void) {
+    A = (A << 1) | (A >> 7);
+}
+
+/* 0x99 - RLC A */
+void
+RLC(void) {
+    /* implement me */
+}
+
+/* 0x9A - RR A */
+void
+RR(void) {
+    A = (A >> 1) | (A << 7);
+}
+
+/* 0x9B - RRC A */
+void
+RRC(void) { 
+    /* implement me */
+}
+
+/* 0x9C - INC DPTR
+ * 0x9E - INC A */
+void
+INC(void) {    
+}
+
+/* 0x9D - DEC DPTR
+ * 0x9F - DEC A */
+void
+DEC(void) {
+}
+
+void
+ADD(void) {
+}
+
+void
+ADDC(void) {
+/* implement me */    
+}
+
+void
+SUB(void) {
+}
+
+void
+SUBB(void) {
+    /* implement me */
+}
+
+void
+PJMP(void) {
+    /* implement me */
+}
+
+void
+PCALL(void) {
+    /* implement me */
+}
+
+/* 0xD0 - DJNZ R0, rel8
+ * 0xD1 - DJNZ R1, rel8
+ * 0xD2 - DJNZ R2, rel8
+ * 0xD3 - DJNZ R3, rel8 */
+void
+DJNZ(void) {
+}
+
+void
+CJNE(void) {
+}
+
+/* 0xD8 - LJMP addr16 */
+void
+LJMP(void) {
+}
+
+void
+LCALL(void) {
+    /* implement me */
+}
+
+void
+RET(void) {
+    /* implement me */
+}
+
+void
+RETI(void) {
+    /* implement me */
+}
+
+/* 0xDC - SJMP rel8 */
+void
+SJMP(void) {
+}
+
+/* 0xDD - JMP @A+DPTR
+ * 0xDE - JMP @DPTR */
+void
+JMP(void) {
+}
+
+void
+JZ(void) {   
+}
+
+void
+JNZ(void) {
+}
+
+void
+JC(void) {   
+}
+
+void
+JNC(void) {   
+}
+
+void
+JPO(void) {   
+}
+
+void
+JPE(void) {
+}
+
+void
+JS(void) {    
+}
+
+void
+JNS(void) {
+}
+
+void
+PUSH(void) {
+}
+
+void
+POP(void) { 
+}
+
+void
+MUL(void) {    
+}
+
+void
+DIV(void) {   
+}
+
+void
+DA(void) {    
+}
+
+void
+IN(void) {   
+}
+
+void
+OUT(void) {
+}
+
+void
+INT(void) {    
+}
+
+/* 0xFF - HLT */
+void
+HLT(void) {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emu/iset.h	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,154 @@
+/* iset.h
+ * op function definitions */
+#ifndef ISET_H
+#define ISET_H
+
+/* instruction pointer table */
+void (*iset[256])(void);
+
+void
+JNS(void);
+
+void
+LJMP(void);
+
+void
+SET(void);
+
+void
+JPO(void);
+
+void
+ANL(void);
+
+void
+JNZ(void);
+
+void
+HLT(void);
+
+void
+RRC(void);
+
+void
+POP(void);
+
+void
+JNC(void);
+
+void
+SUBB(void);
+
+void
+PCALL(void);
+
+void
+IN(void);
+
+void
+INC(void);
+
+void
+XRL(void);
+
+void
+SUB(void);
+
+void
+RR(void);
+
+void
+SJMP(void);
+
+void
+RETI(void);
+
+void
+RET(void);
+
+void
+INT(void);
+
+void
+ADD(void);
+
+void
+ADDC(void);
+
+void
+RL(void);
+
+void
+MUL(void);
+
+void
+JC(void);
+
+void
+JMP(void);
+
+void
+DJNZ(void);
+
+void
+CLR(void);
+
+void
+JZ(void);
+
+void
+JPE(void);
+
+void
+LAF(void);
+
+void
+MOV(void);
+
+void
+RLC(void);
+
+void
+JS(void);
+
+void
+ORL(void);
+
+void
+CJNE(void);
+
+void
+XCSD(void);
+
+void
+LCALL(void);
+
+void
+DA(void);
+
+void
+NOP(void);
+
+void
+SFA(void);
+
+void
+CPL(void);
+
+void
+PUSH(void);
+
+void
+DIV(void);
+
+void
+DEC(void);
+
+void
+OUT(void);
+
+void
+PJMP(void);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emu/main.c	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,208 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MAIN
+#include "mem.h"
+#include "iset.h"
+
+/* fill instruction table 
+ * MCS-51 - this needs to be stored in code memory */
+void (*iset[256])(void) = {
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+    SET, CLR, SET, CLR, SET, CLR, CPL, CPL,
+    XCSD, SFA, LAF, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
+    ANL, ANL, ANL, ANL, ANL, ANL, ANL, ANL,
+    ORL, ORL, ORL, ORL, ORL, ORL, ORL, ORL,
+    XRL, XRL, XRL, XRL, XRL, XRL, XRL, XRL,
+    RL, RLC, RR, RRC, INC, DEC, INC, DEC,
+    ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD,
+    ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC,
+    SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
+    SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB,
+    PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP,
+    PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL,
+    DJNZ, DJNZ, DJNZ, DJNZ, CJNE, CJNE, CJNE, CJNE,
+    LJMP, LCALL, RET, RETI, SJMP, JMP, JMP, CJNE,
+    JZ, JNZ, JC, JNC, JPO, JPE, JS, JNS,
+    PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH,
+    POP, POP, POP, POP, POP, POP, POP, POP,
+    MUL, DIV, DA, NOP, IN, OUT, INT, HLT
+};
+
+BYTE run;
+WIDE ac;
+BYTE args[4];
+
+/* don't need the file on the MCS-51 version */
+FILE *fp;
+void
+snd(BYTE c) {
+    /* putchar(c); */
+    fp = fopen("out", "a");
+    fputc(c, fp);
+    fclose(fp);
+}
+
+BYTE
+rcv(void) {
+    return getchar();
+}
+
+void
+step(void) {
+    IR = fetch();
+    (*iset[IR])();
+}
+
+void
+boot(void) {
+    run = 0;
+}
+
+
+void dbgi() {
+    if (run == 0) {
+        switch (rcv()) {
+
+            /* step */
+            case 0x00:
+                step();
+                break;
+
+            /* run */
+            case 0x01:
+                run = 1;
+                break;
+
+            /* set reg */
+            case 0x02:
+                args[0] = rcv(); /* reg */
+                args[1] = rcv(); /* val */
+                regs[args[0]] = args[1];
+                break;
+
+            /* get reg */
+            case 0x03:
+                args[0] = rcv(); /* reg */
+                snd(regs[args[0]]);
+                break;
+
+            /* set flag */
+            case 0x04:
+                args[0] = rcv(); /* flag */
+                args[1] = rcv(); /* on? */
+                set_flag(args[0], args[1]);
+                break;
+    
+            /* get flag */
+            case 0x05:
+                args[0] = rcv(); /* flag */
+                snd(get_flag(args[0]));
+                break;
+
+            /* write mem block */
+            case 0x06:
+                args[0] = rcv(); /* addr high */
+                args[1] = rcv(); /* addr low */
+                args[2] = rcv(); /* length high */
+                args[3] = rcv(); /* length low */
+                tmpw = args[1] | (args[0] << 8);           
+                for (ac = tmpw; ac < (tmpw + (args[3] | (args[2] << 8))); ac++) {
+                    if (ac >= 0xFFFF) {
+                        break;
+                    }
+                    mem[ac] = rcv();
+                }
+                break;
+
+            /* read mem block */
+            case 0x07:
+                args[0] = rcv(); /* addr high */
+                args[1] = rcv(); /* addr low */
+                args[2] = rcv(); /* length high */
+                args[3] = rcv(); /* length low */
+                tmpw = args[1] | (args[0] << 8);
+                for (ac = tmpw; ac < (tmpw + (args[3] | (args[2] << 8))); ac++) {
+                    if (ac >= 0xFFFF) {
+                        break;
+                    }
+                    snd(mem[ac]);
+                }
+                break;
+
+            /* get A */
+            case 0x09:
+                snd(A);
+            
+            /* get flags */
+            case 0x0F:
+                snd(flags);
+            
+            /* get instruction register */
+            case 0x10:
+                snd(IR);
+       }
+    }
+}
+
+void 
+main(void) {
+    
+    A = 0xAA;
+    IR = 0x12;
+    
+    unsigned char i;
+    for (i = 0 ; i < 8 ; i++) {
+        set_flag(i, 1);
+    }
+    
+    set_wide(DPTR, 0xDE1D);
+    set_wide(PC, 0xBEFA);
+    set_wide(SP, 0xADEA);
+    set_wide(TMP, 0xEFC3);
+    
+    for (i = 0; i < 4; i++) {
+        regs[i] = i; 
+    }
+
+    for (i = 8; i < 0x0C; i++) {
+        regs[i] = 0x10 | (i - 8);
+    }
+    
+    /* 0xAA 0x12 0xFF 
+     * 0x00 0x01 0x02 0x03
+     * 0xDE 0xAD 0xBE 0xFF
+     * 0x10 0x11 0x12 0x13
+     * 0x1D 0xEA 0xFA 0xC3 */
+    
+    putchar(A);
+    putchar(IR);
+    putchar(flags);
+
+    for (i = 0; i < 0x10; i++) {
+        putchar(regs[i]);
+    }
+
+    unsigned short int data_pointer = get_wide(DPTR);
+    unsigned short int program_counter = get_wide(PC);
+    unsigned short int stack_pointer = get_wide(SP);
+    unsigned short int temp = get_wide(tmp);
+    
+
+
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emu/mem.c	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,67 @@
+/* mem.c
+ * functions for accessing emulator memory */
+#include "mem.h"
+
+/* get flag value
+ * if invalid flag is requested value is 0 */
+BYTE
+get_flag(BYTE flag) {
+    if (flag > 7) {
+        return 0;
+    }
+    else {
+        return GBIT(flags, flag);
+    }
+}
+
+/*  set flag to 0 if on == 0
+ *  otherwise set flag to 1 */
+void
+set_flag(BYTE flag, BYTE on) {
+    if (flag <= 7) {
+        switch (on) {
+            
+            case 0:
+                flags = CBIT(flags, flag);
+
+            default:
+                flags = SBIT(flags, flag);
+        }
+    }
+}
+
+WIDE
+get_wide(BYTE reg) {
+    /* low | (high << 8) */
+    return (regs[reg + 12] | (regs[reg + 4] << 8));
+}
+
+void
+set_wide(BYTE reg, WIDE val) {
+    regs[reg + 4] = (val >> 8) & 0xFF; /* high */
+    regs[reg + 12] = val & 0xFF; /* low */
+}
+
+void 
+inc_pc(BYTE n) {
+    if ((regs[PCL] + n) > 0xFF) {
+        regs[PCH]++;
+    }
+    regs[PCL] += n;
+}
+
+BYTE 
+fetch(void) {
+    BYTE val = mem[get_wide(PC)];
+    inc_pc(1);
+    return val;
+}
+
+WIDE
+fetch_wide(void) {
+    WIDE val = mem[get_wide(PC)] | (mem[get_wide(PC + 1)] << 8);
+    inc_pc(2);
+    return val;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emu/mem.h	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,110 @@
+/* mem.h */
+#ifndef MEM_H
+#define MEM_H
+
+#if defined MAIN
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+
+/* 8 bit register encodings */
+#define R0   (0 | (get_flag(0) << 3))
+#define R1   (1 | (get_flag(0) << 3))
+#define R2   (2 | (get_flag(0) << 3))
+#define R3   (3 | (get_flag(0) << 3))
+#define DPH  4
+#define SPH  5
+#define PCH  6 
+#define TMPH 7
+#define DPL  12
+#define SPL  13
+#define PCL  14
+#define TMPL 15
+
+/* 16 bit register encodings */ 
+#define DPTR 0 
+#define SP   1 
+#define PC   2 
+#define TMP  3 
+ 
+/* flag bits numbered from LSB -> MSB 
+ *  7 6 5  4 3 2  1  0 
+ *  C Z AC P S OV IE BS */
+#define BS 0
+#define IE 1
+#define OV 2
+#define S  3
+#define P  4
+#define AC 5
+#define Z  6
+#define C  7
+
+/* for getting and setting flags */ 
+#define GBIT(byte, n) (byte & (0x01 << n) ? 1 : 0)  
+#define SBIT(byte, n) (byte | (0x01 << n)) 
+#define CBIT(byte, n) (byte ^ (0x01 << n)) 
+
+typedef unsigned char BYTE;
+typedef unsigned short WIDE;
+
+/* these are needed for some operations */
+EXTERN BYTE tmpb;
+EXTERN WIDE tmpw;
+
+EXTERN BYTE IR;
+EXTERN BYTE A;
+EXTERN BYTE flags;
+
+/*  0x00 0b0000 r0 bank 0
+    0x01 0b0001 r1 bank 0
+    0x02 0b0010 r2 bank 0
+    0x03 0b0011 r3 bank 0
+    0x04 0b0100 dph
+    0x05 0b0101 sph
+    0x06 0b0110 pch
+    0x07 0b0111 tmph
+    0x08 0b1000 r0 bank 1
+    0x09 0b1001 r1 bank 1
+    0x0A 0b1010 r2 bank 1
+    0x0B 0b1011 r3 bank 1
+    0x0C 0b1100 dpl
+    0x0D 0b1101 spl
+    0x0E 0b1110 pcl
+    0x0F 0b1111 tmpl */
+EXTERN BYTE regs[0x10];
+
+/* 64K Von Neumann memory */
+EXTERN BYTE mem[0x10000];
+
+/* functions to dealing with flags */
+EXTERN BYTE
+get_flag(BYTE flag);
+
+EXTERN void
+set_flag(BYTE byte, BYTE on);
+
+/* functions for dealing with 16-bit registers
+ * access the 16 bit registers.
+ * register map for these function:
+ *   0b00 dptr
+ *   0b01 sp
+ *   0b10 pc
+ *   0b11 tmp */
+EXTERN WIDE
+get_wide(BYTE reg);
+
+EXTERN void
+set_wide(BYTE reg, WIDE val);
+
+/* functions to fetch data at PC */
+EXTERN void
+inc_pc(BYTE n);
+
+EXTERN BYTE
+fetch();
+
+EXTERN WIDE
+fetch_wide();
+
+#endif
Binary file emulator/a.out has changed
--- a/emulator/dbgi.h	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-/* dbgi.h
- * debug interface definitions */
-#ifndef DBGI_H
-#define DBGI_H
-
-BYTE dbgchar;
-
-#endif
--- a/emulator/emu.c	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/* emu.c
- * emulation start up and fetch/decode/execute loop */
-#include <stdio.h>
-#include <string.h>
-#include "mem.h"
-#include "iset.h"
-
-/* fill instruction table 
- * MCS-51 - this needs to be stored in code memory */
-ITABLE itable = {
-    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
-    SET, CLR, SET, CLR, SET, CLR, CPL, CPL,
-    XCSD, SFA, LAF, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
-    ANL, ANL, ANL, ANL, ANL, ANL, ANL, ANL,
-    ORL, ORL, ORL, ORL, ORL, ORL, ORL, ORL,
-    XRL, XRL, XRL, XRL, XRL, XRL, XRL, XRL,
-    RL, RLC, RR, RRC, INC, DEC, INC, DEC,
-    ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD,
-    ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC,
-    SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
-    SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB,
-    PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP,
-    PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL,
-    DJNZ, DJNZ, DJNZ, DJNZ, CJNE, CJNE, CJNE, CJNE,
-    LJMP, LCALL, RET, RETI, SJMP, JMP, JMP, CJNE,
-    JZ, JNZ, JC, JNC, JPO, JPE, JS, JNS,
-    PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH,
-    POP, POP, POP, POP, POP, POP, POP, POP,
-    MUL, DIV, DA, NOP, IN, OUT, INT, HLT
-};
-
-void 
-step(void) {
-    op = fetch();
-    itable.iset[op]();
-    registers.PC++;
-}
-
-void 
-main(void) {
-    for (;;) { 
-        step();
-    }
-}
-
--- a/emulator/iset.c	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,663 +0,0 @@
-/* iset.c
- * op functions */
-#include <stdlib.h>
-#include "iset.h"
-#include "mem.h"
-
-/* useful macros */
-#define BANK (registers.flags & 0x01)
-#define CARRY ((registers.flags & 0x08) >> 3)
-#define NNN (op & 0x07)
-#define MMM ((op & 0x38) >> 3)
-
-/* temp registers for various instructions */
-
-/* 0x00 - NOP */
-void
-NOP(void) {    
-}
-
-/* 0x08 - SET C
- * 0x0A - SET BS
- * 0x0C - SET IE */
-void
-SET(void) {
-    switch (op) {
-        
-        case 0x08:
-            registers.flags = registers.flags | 0x80;
-            break;
-        
-        case 0x0A:
-            registers.flags = registers.flags | 0x01;
-            break;
-        
-        case 0x0C:
-            registers.flags = registers.flags | 0x02;
-            break;
-        
-        default:
-            break;
-    }
-}
-
-/* 0x09 - CLR C
- * 0x0B - CLR BS
- * 0x0D - CLR IE */
-void
-CLR(void) {
-    switch (op) {
-        
-        case 0x09:
-            registers.flags = registers.flags & 0xF7;
-            break;
-        
-        case 0x0B:
-            registers.flags = registers.flags & 0xFE;
-            break;
-        
-        case 0x0D:
-            registers.flags = registers.flags & 0xFD;
-            break;
-        
-        default:
-            break;
-    }    
-}
-
-/* 0x0E - CPL C
- * 0x0F - CPL A */
-void
-CPL(void) {
-    switch (op) {
-        
-        case 0x0E:
-            if (CARRY) {
-                registers.flags = registers.flags | 0x80;
-            }
-            else {
-                registers.flags = registers.flags & 0xF7;
-            }
-            break;
-        
-        case 0x0F:
-            registers.A = ~registers.A;
-            break;
-        
-        default:
-            break;
-    }
-}
-
-/* 0x10 - XCSD */
-void
-XCSD(void) {
-    tmpw = get_SP();
-    set_SP(get_DPTR());
-    set_DPTR(tmpw);
-}
-
-/* 0x11 - SFA */
-void
-SFA(void) {
-    registers.A = registers.flags;
-}
-
-/* 0x12 - LAF */
-void
-LAF(void) {
-    registers.flags = registers.A;   
-}
-
-/* 0b00010XXX - special MOVs
- * 0b00011XXX - direct, indirect and indexed MOVs
- * 0b00100nnn - register-indirect MOVs - MOV @DPTR, Rn
- * 0b00101nnn - immediate movs - MOV Rn, #data8
- * 0b00110nnn - MOV Rn, A
- * 0b00111nnn - MOV A, Rn
- * 0b01mmmnnn - 64 register move instructions
- *
- * this is a mess */
-void
-MOV(void) {
-    switch (op & 0x40) {
-       
-        case 0x00:
-            switch (op & 0xF8) {
-                
-                /* 0b00010XXX */
-                case 0x10:
-                    switch (NNN) {
-                        
-                        /* MOV DPTR, SP */
-                        case 3:
-                            set_DPTR(get_SP());
-                            break;
-                        
-                        /* MOV SP, DPTR */
-                        case 4:
-                            set_SP(get_DPTR());
-                            break;
-                        
-                        /* MOV A, #data8 */
-                        case 5:
-                            PC++;
-                            registers.A = fetch();
-                            break;
-                        
-                        /* MOV SP, #data16 */
-                        case 6:
-                            PC++;
-                            set_SP(fetch_wide());
-                            PC++;
-                            break;
-                        
-                        /* MOV DPTR, #data16 */
-                        case 7:
-                            PC++;
-                            set_DPTR(fetch_wide());
-                            PC++;
-                            break;
-                        
-                        default:
-                            break;
-                    }
-                    break;
-                
-                /* 0b00011XXX */
-                case 0x18:
-                    switch (NNN) {
-                        
-                        /* MOV A, addr16 */
-                        case 0:
-                            PC++;
-                            registers.A = memory[fetch_wide()];
-                            PC++;
-                            break;
-                        
-                        /* MOV addr16, A */
-                        case 1:
-                            PC++;
-                            memory[fetch_wide()] = registers.A;
-                            PC++;
-                            break;
-                        
-                        /* MOV A, @A+DPTR */
-                        case 2:
-                            registers.A = memory[registers.A + get_DPTR()];
-                            break;
-                        
-                        /* MOV A, @A+PC */
-                        case 3:
-                            registers.A = memory[registers.A + PC];
-                            break;
-                        
-                        /* MOV A, @addr16 */
-                        case 4:
-                            PC++;
-                            registers.A = memory[memory[fetch_wide()]];
-                            PC++;
-                            break;
-                        
-                        /* MOV @addr16, A */ 
-                        case 5:
-                            PC++;
-                            memory[memory[fetch_wide()]] = registers.A;
-                            PC++;
-                            break;
-                        
-                        /* MOV A, @DPTR */
-                        case 6:
-                            registers.A = memory[get_DPTR()];
-                            break;
-                        
-                        /* MOV @DPTR, A */
-                        case 7:
-                            memory[get_DPTR()] = registers.A;
-                            break;
-                        
-                        default:
-                            break;
-                    }
-                    break;
-                
-                /* 0b00100nnn */
-                case 0x20:
-                    memory[get_DPTR()] = get_R(NNN, BANK);
-                    break;
-                
-                /* 0b00101nnn */
-                case 0x28:
-                    /* store immediate data in op */
-                    PC++;
-                    set_R(NNN, BANK, fetch());
-                    break;
-                
-                /* 0b00110nnn */
-                case 0x30:
-                    set_R(NNN, BANK, registers.A);
-                    break;
-                
-                /* 0b00111nnn */
-                case 0x38:
-                    registers.A = get_R(NNN, BANK);
-                    break;
-                
-                default:
-                    break;
-                }
-            break;
-        
-        /* 0b01mmmnnn */
-        case 0x40:
-            /* if mmm == nnn: MOV Rm, @DPTR */
-            if (MMM == NNN) {
-                set_R(NNN, BANK, memory[get_DPTR()]);
-            }
-            /* else: MOV Rm, Rn */
-            else {
-                set_R(MMM, BANK, get_R(NNN, BANK));
-            }
-            break;
-        
-        default:
-            break;
-    }
-}
-
-void
-ANL(void) {
-    /* 0x80 - ANL A, R0
-     * 0x81 - ANL A, R1
-     * 0x82 - ANL A, R2
-     * 0x83 - ANL A, R3
-     * 0x84 - ANL A, DPH
-     * 0x85 - ANL A, DPL */
-    if (NNN <= 5) {
-        registers.A = registers.A & get_R(NNN, BANK);
-    }
-    else {
-        switch (NNN) {
-            
-            /* 0x86 - ANL A, #data8 */
-            case 6:
-                PC++;
-                registers.A = registers.A & fetch();
-                break;
-            
-            /* 0x87 - ANL A, @DPTR */
-            case 7:
-                registers.A = registers.A & memory[get_DPTR()];
-            
-            default:
-                break;
-        }
-    }
-}
-
-void
-ORL(void) {
-    /* 0x88 - ORL A, R0
-     * 0x89 - ORL A, R1
-     * 0x8A - ORL A, R2
-     * 0x8B - ORL A, R3
-     * 0x8C - ORL A, DPH
-     * 0x8D - ORL A, DPL */
-    if (NNN <= 5) {
-        registers.A = registers.A | get_R(NNN, BANK);
-    }
-    else {
-        switch (NNN) {
-            
-            /* 0x8E - ORL A, #data8 */
-            case 6:
-                PC++;
-                registers.A = registers.A | fetch();
-                break;
-            
-            /* 0x8F - ORL A, @DPTR */
-            case 7:
-                registers.A = registers.A | memory[get_DPTR()];
-            
-            default:
-                break;
-        }
-    }
-}
-
-void
-XRL(void) {
-    /* 0x90 - XRL A, R0
-     * 0x91 - XRL A, R1
-     * 0x92 - XRL A, R2
-     * 0x93 - XRL A, R3
-     * 0x94 - XRL A, DPH
-     * 0x95 - XRL A, DPL */
-    if (NNN <= 5) {
-        registers.A = registers.A ^ get_R(NNN, BANK);
-    }
-    else {
-        switch (NNN) {
-            
-            /* 0x96 - XRL A, #data8 */
-            case 6:
-                PC++;
-                registers.A = registers.A ^ fetch();
-                break;
-            
-            /* 0x97 - XRL A, @DPTR */
-            case 7:
-                registers.A = registers.A ^ memory[get_DPTR()];
-            
-            default:
-                break;
-        }
-    }
-}
-
-/* 0x98 - RL A */
-void
-RL(void) {
-    registers.A = (registers.A << 1) | (registers.A >> 7);
-}
-
-/* 0x99 - RLC A */
-void
-RLC(void) {
-    /* implement me */
-}
-
-/* 0x9A - RR A */
-void
-RR(void) {
-    registers.A = (registers.A >> 1) | (registers.A << 7);
-}
-
-/* 0x9B - RRC A */
-void
-RRC(void) { 
-    /* implement me */
-}
-
-/* 0x9C - INC DPTR
- * 0x9E - INC A */
-void
-INC(void) {    
-    switch (op) {
-        
-        case 0x9C:
-            tmpw = get_DPTR();
-            set_DPTR(tmpw + 1);
-            break;
-        
-        case 0x9E:
-            registers.A++;
-            break;
-        
-        default:
-            break;
-    }
-}
-
-/* 0x9D - DEC DPTR
- * 0x9F - DEC A */
-void
-DEC(void) {
-    switch (op) {
-        
-        case 0x9D:
-            tmpw = get_DPTR();
-            set_DPTR(tmpw - 1);
-            break;
-        
-        case 0x9F:
-            registers.A--;
-            break;
-        
-        default:
-            break;
-    }
-}
-
-void
-ADD(void) {
-    /* 0xA0 - ADD A, R0
-     * 0xA1 - ADD A, R1
-     * 0xA2 - ADD A, R2
-     * 0xA3 - ADD A, R3
-     * 0xA4 - ADD A, DPH
-     * 0xA5 - ADD A, DPL */
-    if (NNN <= 5) {
-        registers.A = registers.A + get_R(NNN, BANK);
-    }
-    else {
-        switch (NNN) {
-            
-            /* 0xA6 - ADD A, #data8 */
-            case 6:
-                PC++;
-                registers.A = registers.A + fetch();
-                break;
-            
-            /* 0xA7 - ADD A, @DPTR */
-            case 7:
-                registers.A = registers.A + memory[get_DPTR()];
-            
-            default:
-                break;
-        }
-    }
-}
-
-void
-ADDC(void) {
-/* implement me */    
-}
-
-void
-SUB(void) {
-    /* 0xB0 - SUB A, R0
-     * 0xB1 - SUB A, R1
-     * 0xB2 - SUB A, R2
-     * 0xB3 - SUB A, R3
-     * 0xB4 - SUB A, DPH
-     * 0xB5 - SUB A, DPL */
-    if (NNN <= 5) {
-        registers.A = registers.A - get_R(NNN, BANK);
-    }
-    else {
-        switch (NNN) {
-            
-            /* 0xB6 - SUB A, #data8 */
-            case 6:
-                PC++;
-                registers.A = registers.A - fetch();
-                break;
-            
-            /* 0xB7 - SUB A, @DPTR */
-            case 7:
-                registers.A = registers.A - memory[get_DPTR()];
-            
-            default:
-                break;
-        }
-    }
-}
-
-void
-SUBB(void) {
-    /* implement me */
-}
-
-void
-PJMP(void) {
-    /* implement me */
-}
-
-void
-PCALL(void) {
-    /* implement me */
-}
-
-/* 0xD0 - DJNZ R0, rel8
- * 0xD1 - DJNZ R1, rel8
- * 0xD2 - DJNZ R2, rel8
- * 0xD3 - DJNZ R3, rel8 */
-void
-DJNZ(void) {
-    /* decrement reg */
-    tmpb = get_R(op & 0x03, BANK);
-    tmpb--;
-    set_R(op & 0x03, BANK, tmpb);
-    /* jump if not zero */
-    PC++;
-    if (tmpb != 0) {
-        tmpb = fetch();
-        PC = PC + (signed char)tmpb - 1;
-    }
-
-}
-
-void
-CJNE(void) {
-    /* fetch data */
-    PC++;
-    tmpb = fetch();
-    PC++;
-
-    /* 0xD4 - CJNE R0, data8, rel8
-     * 0xD5 - CJNE R1, data8, rel8
-     * 0xD6 - CJNE R2, data8, rel8
-     * 0xD7 - CJNE R3, data8, rel8 */
-    if ((op & 0x0F) <= 7) {
-        /* jump if not equal to reg */
-        if (tmpb != get_R(op & 0x03, BANK)) {
-            tmpb = fetch();
-            PC = PC + (signed char)tmpb -1;
-        }
-    }
-    /* 0xDF - CJNE A, data8, rel8  */
-    else if ((op & 0x0F) == 0x0F) {
-        /* jump if not equal to A */
-        if (tmpb != registers.A) {
-            tmpb = fetch();
-            PC = PC + (signed char)tmpb -1;
-        }
-    }
-}
-
-/* 0xD8 - LJMP addr16 */
-void
-LJMP(void) {
-    PC++;
-    PC = fetch_wide() - 1;
-}
-
-void
-LCALL(void) {
-    /* implement me */
-}
-
-void
-RET(void) {
-    /* implement me */
-}
-
-void
-RETI(void) {
-    /* implement me */
-}
-
-/* 0xDC - SJMP rel8 */
-void
-SJMP(void) {
-    PC++;
-    tmpb = fetch();
-    PC = PC + (signed char)tmpb - 1;
-}
-
-/* 0xDD - JMP @A+DPTR
- * 0xDE - JMP @DPTR */
-void
-JMP(void) {
-    switch (op) {
-        case 0xDD:
-            PC = registers.A + get_DPTR() - 1;
-            break;
-        case 0xDE:
-            PC = get_DPTR() - 1;
-            break;
-        default:
-            break;
-    } 
-}
-
-void
-JZ(void) {   
-}
-
-void
-JNZ(void) {
-}
-
-void
-JC(void) {   
-}
-
-void
-JNC(void) {   
-}
-
-void
-JPO(void) {   
-}
-
-void
-JPE(void) {
-}
-
-void
-JS(void) {    
-}
-
-void
-JNS(void) {
-}
-
-void
-PUSH(void) {
-}
-
-void
-POP(void) { 
-}
-
-void
-MUL(void) {    
-}
-
-void
-DIV(void) {   
-}
-
-void
-DA(void) {    
-}
-
-void
-IN(void) {   
-}
-
-void
-OUT(void) {
-}
-
-void
-INT(void) {    
-}
-
-/* 0xFF - HLT */
-void
-HLT(void) {
-    exit(0);
-}
--- a/emulator/iset.h	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/* iset.h
- * op function definitions */
-#ifndef ISET_H
-#define ISET_H
-
-/* current opcode */
-unsigned char op;
-
-/* temp registers for various instructions */
-unsigned char tmpb;
-unsigned short tmpw;
-
-/* instruction pointer table */
-typedef struct {
-    void (*iset[256])(void);
-} ITABLE;
-
-void
-JNS(void);
-
-void
-LJMP(void);
-
-void
-SET(void);
-
-void
-JPO(void);
-
-void
-ANL(void);
-
-void
-JNZ(void);
-
-void
-HLT(void);
-
-void
-RRC(void);
-
-void
-POP(void);
-
-void
-JNC(void);
-
-void
-SUBB(void);
-
-void
-PCALL(void);
-
-void
-IN(void);
-
-void
-INC(void);
-
-void
-XRL(void);
-
-void
-SUB(void);
-
-void
-RR(void);
-
-void
-SJMP(void);
-
-void
-RETI(void);
-
-void
-RET(void);
-
-void
-INT(void);
-
-void
-ADD(void);
-
-void
-ADDC(void);
-
-void
-RL(void);
-
-void
-MUL(void);
-
-void
-JC(void);
-
-void
-JMP(void);
-
-void
-DJNZ(void);
-
-void
-CLR(void);
-
-void
-JZ(void);
-
-void
-JPE(void);
-
-void
-LAF(void);
-
-void
-MOV(void);
-
-void
-RLC(void);
-
-void
-JS(void);
-
-void
-ORL(void);
-
-void
-CJNE(void);
-
-void
-XCSD(void);
-
-void
-LCALL(void);
-
-void
-DA(void);
-
-void
-NOP(void);
-
-void
-SFA(void);
-
-void
-CPL(void);
-
-void
-PUSH(void);
-
-void
-DIV(void);
-
-void
-DEC(void);
-
-void
-OUT(void);
-
-void
-PJMP(void);
-
-#endif
-
--- a/emulator/main.c	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#include <stdio.h>
-#include "mem.h"
-
-typedef struct {
-        void (*iset[256])(void);
-} ITABLE;
-
-void 
-main(void) {
-
--- a/emulator/mem.c	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/* mem.c
- * functions for accessing emulator memory */
-#include "mem.h"
-
-/* for getting flags */
-#define GBIT(byte, n) (byte & (0x80 >> n) ? 1 : 0) 
-/* for setting flags */
-#define SBIT(byte, n) (byte & ((0x7F >> n) | (0xFF << (8 - n))))
-
-BYTE
-fetch(void) {
-    return memory[registers.PC];
-}
-
-WIDE
-fetch_wide(void) {
-    return (memory[registers.PC] << 8) | memory[registers.PC + 1];
-}
-
-BYTE
-read_mem(WIDE addr) {
-    return memory[addr];
-}
-
-void
-write_mem(WIDE addr, BYTE data) {
-    memory[addr] = data;
-}
-
-
-BYTE
-get_flag(BYTE n) {
-    if (n > 7) {
-        return 0;
-    }
-    else {
-        return GBIT(registers.flags, n);
-    }
-}
-
-/* MCS-51 - bit type can be used here */
-void
-set_flag(BYTE flag, BYTE n) {
-    if (n <= 7) {
-        SBIT(registers.flags, n)
-    }
-}
-
-BYTE
-get_R(BYTE reg, BYTE bank) {
-    if (reg <= 3) {
-        if (bank == 0) {
-            return registers.R[reg];
-        }
-        else {
-            return registers.R[reg + 0x03];
-        }
-    }
-    else {
-        switch (reg) {
-            
-            case 0x04:
-                return registers.DPH;
-            
-            case 0x05:
-                return registers.DPL;
-            
-            case 0x06:
-                return registers.SPH;
-            
-            case 0x07:
-                return registers.SPL;
-            
-            case 0x08:
-                return registers.A;
-                break;
-           
-            default:
-                return 0;
-        }
-    }
-}
-
-void
-set_R(BYTE reg, BYTE bank, BYTE data) {
-    if (reg <= 3) {
-        if (bank == 0) {
-            registers.R[reg] = data;
-        }
-        else {
-            registers.R[reg + 0x03] = data;
-        }
-    }
-    else {
-        switch (reg) {
-            
-            case 0x04:
-                registers.DPH = data;
-                break;
-            
-            case 0x05:
-                registers.DPL = data;
-                break;
-            
-            case 0x06:
-                registers.SPH = data;
-                break;
-            
-            case 0x07:
-                registers.SPL = data;
-                break;
-            
-            case 0x08:
-                registers.A = data;
-                break;
-            
-            default:
-                break;
-        }
-    }
-}
-
-WIDE
-get_DPTR(void) {
-    return (((WIDE)registers.DPH) << 8) | registers.DPL;
-}
-
-void
-set_DPTR(WIDE data) {
-    registers.DPH = (BYTE)((data & 0xFF00) >> 8);
-    registers.DPL = (BYTE)(data & 0x00FF);
-}
-
-WIDE
-get_SP(void) {
-    return (((WIDE)registers.SPH) << 8) | registers.SPL;
-}
-
-void
-set_SP(WIDE data) {
-    registers.SPH = (BYTE)((data & 0xFF00) >> 8);
-    registers.SPL = (BYTE)(data & 0x00FF);
-}
-
--- a/emulator/mem.h	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*  mem.h
- *  emultor memory structure and access function definitions  */
-#ifndef MEM_H
-#define MEM_H
-
-/* data types
- *  - 8 bit BYTE
- *  - 16 bit WIDE */
-typedef unsigned char BYTE;
-typedef unsigned short WIDE;
-
-/* emulator memory
- *  
- * 8 bit registers:
- *   bank 0: R[0x00 - 0x02]
- *   bank 1: R[0x03 - 0x06] 
- *   DPH, DPL
- *   SPH, SPL
- *   A
- *   flags 
- *
- * 16 bit registers:
- *   DPTR
- *   SP 
- *
- * 64KB Von Neumann memory */
-
-/* program counter stored seperately for ease of use */
-WIDE PC;
-
-struct
-registers {
-    BYTE R[0x06];
-    /* DPTR */
-    BYTE DPH;
-    BYTE DPL;
-    /* SP */
-    BYTE SPH;
-    BYTE SPL;
-    BYTE A;
-    /* 7 6 5  4 3 2  1  0
-     * C Z AC P S OV IE BS */
-    BYTE flags;
-} registers;
-
-BYTE
-memory[0x10000];
-
-/* memory access function definitions
- *  - fetch() returns BYTE
- *  - fetch_wide() returns WIDE
- *  - read_mem(WIDE) returns BYTE
- *  - write_mem(WIDE, BYTE)
- *  - get_flag(BYTE)
- *  - get_R(BYTE, BOOL) returns BYTE
- *  - set_R(BYTE, BOOL, BYTE)
- *  - get_DPTR() returns WIDE
- *  - set_DPTR(WIDE)
- *  - get_SP() returns WIDE
- *  - set_SP(WIDE) */
-BYTE
-fetch(void);
-
-WIDE
-fetch_wide(void);
-
-BYTE
-read_mem(WIDE addr, WIDE len);
-
-void
-write_mem(WIDE addr, WIDE len, BYTE data);
-
-/* MCS-51 - can use bit type here */
-BYTE
-get_flags(BYTE flag);
-
-BYTE
-get_R(BYTE reg, BYTE bank);
-
-void
-set_R(BYTE reg, BYTE bank, BYTE data);
-
-WIDE
-get_DPTR(void);
-
-void
-set_DPTR(WIDE data);
-
-WIDE
-get_SP(void);
-
-void
-set_SP(WIDE data);
-
-#endif
Binary file tests/a.out has changed
Binary file tests/asm/a.out has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/asm/full.asm	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,259 @@
+zero:
+db 'DB', 0104, 66, 0x4442, (0 + zero), zero
+data8 EQU 0x42
+data16 EQU ((0x2BAB * 2) - data8 + 0x01 + data8)
+port_addr EQU 'P'
+vect8 EQU 'V'
+
+NOP
+SET C
+CLR C
+SET BS
+CLR BS
+SeT iE
+CLR IE
+CPL C
+CPL A
+XCSD
+SFA
+LAF
+MOV DPTR, SP
+MOV SP, DPTR
+MOV A, #'B'
+MOV SP, #'WW'
+MOV DPTR, #data16
+MOV A, addr16
+MOV addr16, A
+MOV A, @A+DPTR
+MOV A, @A+PC
+MOV A, @addr16
+MOV @addr16, A
+MOV A, @DPTR
+MOV @DPTR, A
+MOV @DPTR, R0
+MOV @DPTR, R1
+MOV @DPTR, R2
+MOV @DPTR, R3
+MOV @DPTR, DPH
+MOV @DPTR, DPL
+MOV @DPTR, SPH
+MOV @DPTR, SPL
+MOV R0, #data8
+MOV R1, #data8
+MOV R2, #data8
+MOV R3, #data8
+MOV DPH, #data8
+MOV DPL, #data8
+MOV SPH, #data8
+MOV SPL, #data8
+MOV R0, A
+MOV R1, A
+MOV R2, A
+MOV R3, A
+MOV DPH, A
+MOV DPL, A
+MOV SPH, A
+MOV SPL, A
+MOV A, R0
+MOV A, R1
+MOV A, R2
+MOV A, R3
+MOV A, DPH
+MOV A, DPL
+MOV A, SPH
+MOV A, SPL
+MOV R0, @DPTR
+MOV R0, R1
+MOV R0, R2
+MOV R0, R3
+MOV R0, DPH
+MOV R0, DPL
+MOV R0, SPH
+MOV R0, SPL
+MOV R1, R0
+MOV R1, @DPTR
+MOV R1, R2
+MOV R1, R3
+MOV R1, DPH
+MOV R1, DPL
+MOV R1, SPH
+MOV R1, SPL
+MOV R2, R0
+MOV R2, R1
+MOV R2, @DPTR
+MOV R2, R3
+MOV R2, DPH
+MOV R2, DPL
+MOV R2, SPH
+MOV R2, SPL
+MOV R3, R0
+MOV R3, R1
+MOV R3, R2
+MOV R3, @DPTR
+MOV R3, DPH
+MOV R3, DPL
+MOV R3, SPH
+MOV R3, SPL
+MOV DPH, R0
+MOV DPH, R1
+MOV DPH, R2
+MOV DPH, R3
+MOV DPH, @DPTR
+MOV DPH, DPL
+MOV DPH, SPH
+MOV DPH, SPL
+MOV DPL, R0
+MOV DPL, R1
+MOV DPL, R2
+MOV DPL, R3
+MOV DPL, DPH
+MOV DPL, @DPTR
+MOV DPL, SPH
+MOV DPL, SPL
+MOV SPH, R0
+MOV SPH, R1
+MOV SPH, R2
+MOV SPH, R3
+MOV SPH, DPH
+MOV SPH, DPL
+MOV SPH, @DPTR
+MOV SPH, SPL
+MOV SPL, R0
+MOV SPL, R1
+MOV SPL, R2
+MOV SPL, R3
+MOV SPL, DPH
+MOV SPL, DPL
+MOV SPL, SPH
+MOV SPL, @DPTR
+ANL A, R0
+ANL A, R1
+ANL A, R2
+ANL A, R3
+ANL A, DPH
+ANL A, DPL
+ANL A, #data8
+ANL A, @DPTR
+ORL A, R0
+ORL A, R1
+ORL A, R2
+ORL A, R3
+ORL A, DPH
+ORL A, DPL
+ORL A, #data8
+ORL A, @DPTR
+XRL A, R0
+XRL A, R1
+XRL A, R2
+XRL A, R3
+XRL A, DPH
+XRL A, DPL
+XRL A, #data8
+XRL A, @DPTR
+RL A
+RLC A
+RR A
+RRC A
+INC DPTR
+DEC DPTR
+INC A
+DEC A
+ADD A, R0
+ADD A, R1
+ADD A, R2
+ADD A, R3
+ADD A, DPH
+ADD A, DPL
+ADD A, #data8
+ADD A, @DPTR
+ADDC A, R0
+ADDC A, R1
+ADDC A, R2
+ADDC A, R3
+ADDC A, DPH
+ADDC A, DPL
+ADDC A, #data8
+ADDC A, @DPTR
+SUB A, R0
+SUB A, R1
+SUB A, R2
+SUB A, R3
+SUB A, DPH
+SUB A, DPL
+SUB A, #data8
+SUB A, @DPTR
+SUBB A, R0
+SUBB A, R1
+SUBB A, R2
+SUBB A, R3
+SUBB A, DPH
+SUBB A, DPL
+SUBB A, #data8
+SUBB A, @DPTR
+PJMP addr16
+PJMP addr16
+PJMP addr16
+PJMP addr16
+PJMP addr16
+PJMP addr16
+PJMP addr16
+PJMP addr16
+PCALL addr16
+PCALL addr16
+PCALL addr16
+PCALL addr16
+PCALL addr16
+PCALL addr16
+PCALL addr16
+PCALL addr16
+DJNZ R0, rel8
+DJNZ R1, rel8
+DJNZ R2, rel8
+DJNZ R3, rel8
+CJNE R0, #data8, rel8
+CJNE R1, #data8, rel8
+CJNE R2, #data8, rel8
+CJNE R3, #data8, rel8
+LJMP addr16
+LCALL addr16
+RET
+RETI
+SJMP rel8
+JMP @A+DPTR
+JMP @DPTR
+CJNE A, #data8, rel8
+JZ rel8
+JNZ rel8
+JC rel8
+JNC rel8
+JPO rel8
+JPE rel8
+JS rel8
+JNS rel8
+PUSH R0
+PUSH R1
+PUSH R2
+PUSH R3
+PUSH DPH
+PUSH DPL
+PUSH A
+PUSH FLAGS
+POP R0
+POP R1
+POP R2
+POP R3
+POP DPH
+POP DPL
+POP A
+POP FLAGS
+MUL R0, R1
+DIV R0, R1
+DA A
+IN A, port_addr
+OUT port_addr, A
+INT vect8
+HLT
+
+ORG 0x0161
+rel8:
+addr16:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/emu/test.c	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void
+main(void) {
+}
Binary file tests/emu/test_mem has changed
Binary file tests/emu/test_mem.bin has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/emu/test_mem.c	Fri Apr 11 14:38:09 2014 +0100
@@ -0,0 +1,70 @@
+#include <stdio.h>
+
+#define MAIN
+#include "mem.h"
+
+void
+main(void) {
+    A = 0xAA;
+    IR = 0x12;
+
+    unsigned char i;
+    for (i = 0 ; i < 8 ; i++) {
+        set_flag(i, 1);
+    }
+    
+    set_wide(DPTR, 0xDE1D);
+    set_wide(SP, 0xADEA);
+    set_wide(PC, 0xBEFA);
+    set_wide(TMP, 0xEFC3);
+    
+    for (i = 0; i < 4; i++) {
+        regs[i] = i;
+    }
+        
+    for (i = 8; i < 0x0C; i++) {
+        regs[i] = 0x10 | (i - 8);
+    }
+    
+    /* 0xAC 0x12 0xFF 
+     * 0x00 0x01 0x02 0x03
+     * 0xDE 0xAD 0xBE 0xFF
+     * 0x10 0x11 0x12 0x13
+     * 0x1D 0xEA 0xFA 0xC3 
+     * 0xDE 0x1D 0xBE 0xFA 
+     * 0xAD 0xEA 0xEF 0xC3*/
+
+    putchar(A);
+    putchar(IR);
+    putchar(flags);
+
+    for (i = 0; i < 0x10; i++) {
+        putchar(regs[i]);
+    }
+    
+    unsigned short int data_pointer = get_wide(DPTR);
+    unsigned short int program_counter = get_wide(PC);
+    unsigned short int stack_pointer = get_wide(SP);
+    unsigned short int temp = get_wide(TMP);
+    
+    putchar((data_pointer >> 8) & 0xFF);
+    putchar(data_pointer & 0xFF);
+    putchar((program_counter >> 8) & 0xFF);
+    putchar(program_counter & 0xFF);
+    putchar((stack_pointer >> 8) & 0xFF);
+    putchar(stack_pointer & 0xFF);
+    putchar((temp >> 8) & 0xFF);
+    putchar(temp & 0xFF);
+    
+    
+    int ac;
+    for (ac = 0 ; ac < 0x10000 ; ac++) {
+        mem[ac] = ac & 0xFF;
+    }
+    for (ac = 0 ; ac < 0x10000 ; ac++) {
+        putchar(fetch());
+    }
+}
+
+
+
--- a/tests/full.asm	Wed Apr 02 14:11:50 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-zero:
-db 'DB', 0104, 66, 0x4442, (0 + zero), zero
-data8 EQU 0x42
-data16 EQU ((0x2BAB * 2) - data8 + 0x01 + data8)
-port_addr EQU 'P'
-vect8 EQU 'V'
-
-NOP
-SET C
-CLR C
-SET BS
-CLR BS
-SeT iE
-CLR IE
-CPL C
-CPL A
-XCSD
-SFA
-LAF
-MOV DPTR, SP
-MOV SP, DPTR
-MOV A, #'B'
-MOV SP, #'WW'
-MOV DPTR, #data16
-MOV A, addr16
-MOV addr16, A
-MOV A, @A+DPTR
-MOV A, @A+PC
-MOV A, @addr16
-MOV @addr16, A
-MOV A, @DPTR
-MOV @DPTR, A
-MOV @DPTR, R0
-MOV @DPTR, R1
-MOV @DPTR, R2
-MOV @DPTR, R3
-MOV @DPTR, DPH
-MOV @DPTR, DPL
-MOV @DPTR, SPH
-MOV @DPTR, SPL
-MOV R0, #data8
-MOV R1, #data8
-MOV R2, #data8
-MOV R3, #data8
-MOV DPH, #data8
-MOV DPL, #data8
-MOV SPH, #data8
-MOV SPL, #data8
-MOV R0, A
-MOV R1, A
-MOV R2, A
-MOV R3, A
-MOV DPH, A
-MOV DPL, A
-MOV SPH, A
-MOV SPL, A
-MOV A, R0
-MOV A, R1
-MOV A, R2
-MOV A, R3
-MOV A, DPH
-MOV A, DPL
-MOV A, SPH
-MOV A, SPL
-MOV R0, @DPTR
-MOV R0, R1
-MOV R0, R2
-MOV R0, R3
-MOV R0, DPH
-MOV R0, DPL
-MOV R0, SPH
-MOV R0, SPL
-MOV R1, R0
-MOV R1, @DPTR
-MOV R1, R2
-MOV R1, R3
-MOV R1, DPH
-MOV R1, DPL
-MOV R1, SPH
-MOV R1, SPL
-MOV R2, R0
-MOV R2, R1
-MOV R2, @DPTR
-MOV R2, R3
-MOV R2, DPH
-MOV R2, DPL
-MOV R2, SPH
-MOV R2, SPL
-MOV R3, R0
-MOV R3, R1
-MOV R3, R2
-MOV R3, @DPTR
-MOV R3, DPH
-MOV R3, DPL
-MOV R3, SPH
-MOV R3, SPL
-MOV DPH, R0
-MOV DPH, R1
-MOV DPH, R2
-MOV DPH, R3
-MOV DPH, @DPTR
-MOV DPH, DPL
-MOV DPH, SPH
-MOV DPH, SPL
-MOV DPL, R0
-MOV DPL, R1
-MOV DPL, R2
-MOV DPL, R3
-MOV DPL, DPH
-MOV DPL, @DPTR
-MOV DPL, SPH
-MOV DPL, SPL
-MOV SPH, R0
-MOV SPH, R1
-MOV SPH, R2
-MOV SPH, R3
-MOV SPH, DPH
-MOV SPH, DPL
-MOV SPH, @DPTR
-MOV SPH, SPL
-MOV SPL, R0
-MOV SPL, R1
-MOV SPL, R2
-MOV SPL, R3
-MOV SPL, DPH
-MOV SPL, DPL
-MOV SPL, SPH
-MOV SPL, @DPTR
-ANL A, R0
-ANL A, R1
-ANL A, R2
-ANL A, R3
-ANL A, DPH
-ANL A, DPL
-ANL A, #data8
-ANL A, @DPTR
-ORL A, R0
-ORL A, R1
-ORL A, R2
-ORL A, R3
-ORL A, DPH
-ORL A, DPL
-ORL A, #data8
-ORL A, @DPTR
-XRL A, R0
-XRL A, R1
-XRL A, R2
-XRL A, R3
-XRL A, DPH
-XRL A, DPL
-XRL A, #data8
-XRL A, @DPTR
-RL A
-RLC A
-RR A
-RRC A
-INC DPTR
-DEC DPTR
-INC A
-DEC A
-ADD A, R0
-ADD A, R1
-ADD A, R2
-ADD A, R3
-ADD A, DPH
-ADD A, DPL
-ADD A, #data8
-ADD A, @DPTR
-ADDC A, R0
-ADDC A, R1
-ADDC A, R2
-ADDC A, R3
-ADDC A, DPH
-ADDC A, DPL
-ADDC A, #data8
-ADDC A, @DPTR
-SUB A, R0
-SUB A, R1
-SUB A, R2
-SUB A, R3
-SUB A, DPH
-SUB A, DPL
-SUB A, #data8
-SUB A, @DPTR
-SUBB A, R0
-SUBB A, R1
-SUBB A, R2
-SUBB A, R3
-SUBB A, DPH
-SUBB A, DPL
-SUBB A, #data8
-SUBB A, @DPTR
-PJMP addr16
-PJMP addr16
-PJMP addr16
-PJMP addr16
-PJMP addr16
-PJMP addr16
-PJMP addr16
-PJMP addr16
-PCALL addr16
-PCALL addr16
-PCALL addr16
-PCALL addr16
-PCALL addr16
-PCALL addr16
-PCALL addr16
-PCALL addr16
-DJNZ R0, rel8
-DJNZ R1, rel8
-DJNZ R2, rel8
-DJNZ R3, rel8
-CJNE R0, #data8, rel8
-CJNE R1, #data8, rel8
-CJNE R2, #data8, rel8
-CJNE R3, #data8, rel8
-LJMP addr16
-LCALL addr16
-RET
-RETI
-SJMP rel8
-JMP @A+DPTR
-JMP @DPTR
-CJNE A, #data8, rel8
-JZ rel8
-JNZ rel8
-JC rel8
-JNC rel8
-JPO rel8
-JPE rel8
-JS rel8
-JNS rel8
-PUSH R0
-PUSH R1
-PUSH R2
-PUSH R3
-PUSH DPH
-PUSH DPL
-PUSH A
-PUSH FLAGS
-POP R0
-POP R1
-POP R2
-POP R3
-POP DPH
-POP DPL
-POP A
-POP FLAGS
-MUL R0, R1
-DIV R0, R1
-DA A
-IN A, port_addr
-OUT port_addr, A
-INT vect8
-HLT
-
-ORG 0x0161
-rel8:
-addr16: