Mercurial > hg > ede
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
--- /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 +
--- 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 -
--- /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
--- /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 + }
--- /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
--- 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
--- /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) { +}
--- /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: