def compile(code, path): cart = Cartridge() cart.path = path tokens = lexical(code) ast = syntax(tokens) opcodes = semantic(ast, True, cart) return opcodes
def test_asm_compiler(self): cart = Cartridge() cart.path = 'fixtures/movingsprite/' opcodes = semantic(self.ast, True, cart=cart) self.assertIsNotNone(opcodes) bin = ''.join([chr(opcode) for opcode in opcodes]) f = open('fixtures/movingsprite/movingsprite.nes', 'rb') content = f.read() f.close() self.assertHexEquals(content, bin)
def assertAsmResults(self, source_file, bin_file): path = 'fixtures/nerdynights/background/' f = open(path + source_file) code = f.read() f.close() tokens = lexical(code) ast = syntax(tokens) cart = Cartridge() cart.path = 'fixtures/nerdynights/background/' opcodes = semantic(ast, True, cart=cart) self.assertIsNotNone(opcodes) bin = ''.join([chr(opcode) for opcode in opcodes]) f = open(path + bin_file, 'rb') content = f.read() f.close() self.assertHexEquals(content, bin)
def semantic(ast, iNES=False, cart=None): if cart is None: cart = Cartridge() labels = get_labels(ast) address = 0 # translate statments to opcode for leaf in ast: if leaf['type'] == 'S_RS': labels[leaf['children'][0]['value']] = cart.rs cart.rs += get_value(leaf['children'][2]) elif leaf['type'] == 'S_DIRECTIVE': directive = leaf['children'][0]['value'] if len(leaf['children']) == 2: argument = get_value(leaf['children'][1], labels) else: argument = leaf['children'][1:] if directive in directive_list: directive_list[directive](argument, cart) else: raise Exception('UNKNOW DIRECTIVE') else: if leaf['type'] in ['S_IMPLIED', 'S_ACCUMULATOR']: instruction = leaf['children'][0]['value'] address = False elif leaf['type'] == 'S_RELATIVE': instruction = leaf['children'][0]['value'] address = get_value(leaf['children'][1], labels) elif leaf['type'] == 'S_IMMEDIATE_WITH_MODIFIER': instruction = leaf['children'][0]['value'] modifier = leaf['children'][1]['value'] address = get_value(leaf['children'][3], labels) if modifier == '#LOW': address = (address & 0x00ff) elif modifier == '#HIGH': address = (address & 0xff00) >> 8 elif leaf['type'] in [ 'S_RELATIVE', 'S_IMMEDIATE', 'S_ZEROPAGE', 'S_ABSOLUTE', 'S_ZEROPAGE_X', 'S_ZEROPAGE_Y', 'S_ABSOLUTE_X', 'S_ABSOLUTE_Y' ]: instruction = leaf['children'][0]['value'] address = get_value(leaf['children'][1], labels) elif leaf['type'] in ['S_INDIRECT_X', 'S_INDIRECT_Y']: instruction = leaf['children'][0]['value'] address = get_value(leaf['children'][2], labels) address_mode = address_mode_def[leaf['type']]['short'] opcode = opcodes[instruction][address_mode] if address_mode != 'sngl' and address_mode != 'acc': if 'rel' == address_mode: address = 126 + (address - cart.pc) if address == 128: address = 0 elif address < 128: address = address | 0b10000000 elif address > 128: address = address & 0b01111111 if address_mode_def[leaf['type']]['size'] == 2: cart.append_code([opcode, address]) else: arg1 = (address & 0x00ff) arg2 = (address & 0xff00) >> 8 cart.append_code([opcode, arg1, arg2]) else: cart.append_code([opcode]) # nes_code = [] if iNES: return cart.get_ines_code() else: return cart.get_code()
def setUp(self): self.cart = Cartridge()