diff --git a/bin/sixtypical b/bin/sixtypical index b6d8b6c..7b9e550 100755 --- a/bin/sixtypical +++ b/bin/sixtypical @@ -64,15 +64,19 @@ if __name__ == '__main__': sys.exit(1) if options.compile: + fh = sys.stdout start_addr = 0xc000 prelude = [] if options.basic_prelude: start_addr = 0x0801 prelude = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32, 0x30, 0x36, 0x31, 0x00, 0x00, 0x00] + + # we are outputting a .PRG, so we output the load address first + # we don't use the Emitter for this b/c not part of addr space + fh.write(Word(start_addr).serialize(0)) + emitter = Emitter(start_addr) - # we are outputting a .PRG, so output the load address first - emitter.emit_header(Word(start_addr)) for byte in prelude: emitter.emit(Byte(byte)) compiler = Compiler(emitter) @@ -80,7 +84,7 @@ if __name__ == '__main__': if options.debug: print repr(emitter.accum) else: - emitter.serialize(sys.stdout) + emitter.serialize(fh) if options.execute: context = eval_program(program) diff --git a/eg/call.60p b/eg/call.60p new file mode 100644 index 0000000..bfa0b89 --- /dev/null +++ b/eg/call.60p @@ -0,0 +1,18 @@ +routine chrout + inputs a + trashes a + @ 65490 + +routine print + trashes a, z, n +{ + ld a, 65 + call chrout +} + +routine main + trashes a, z, n +{ + call print + call print +} diff --git a/eg/conditional.p60 b/eg/conditional.p60 new file mode 100644 index 0000000..eb5711c --- /dev/null +++ b/eg/conditional.p60 @@ -0,0 +1,26 @@ +routine chrout + inputs a + trashes a + @ 65490 + +routine main + trashes a, x, y, z, n, c, v +{ + ld a, 0 + if z { + ld a, 89 + call chrout + } else { + ld a, 78 + call chrout + } + + ld a, 1 + if z { + ld a, 89 + call chrout + } else { + ld a, 78 + call chrout + } +} diff --git a/eg/conditional2.p60 b/eg/conditional2.p60 new file mode 100644 index 0000000..444de48 --- /dev/null +++ b/eg/conditional2.p60 @@ -0,0 +1,25 @@ +routine chrout + inputs a + trashes a + @ 65490 + +routine main + trashes a, x, y, z, n, c, v +{ + ld a, 0 + if z { + ld a, 89 + call chrout + ld a, 1 + } + + ld a, 65 + call chrout + + ld a, 1 + if z { + ld a, 89 + call chrout + ld a, 1 + } +} diff --git a/eg/memloc.p60 b/eg/memloc.p60 new file mode 100644 index 0000000..f8886ce --- /dev/null +++ b/eg/memloc.p60 @@ -0,0 +1,24 @@ +byte foo + +routine chrout + inputs a + trashes a + @ 65490 + +routine print + inputs foo + trashes a, z, n +{ + ld a, foo + call chrout +} + +routine main + trashes a, y, z, n, foo +{ + ld y, 65 + st y, foo + call print + inc foo + call print +} diff --git a/src/sixtypical/emitter.py b/src/sixtypical/emitter.py index 6aef9be..66e9126 100644 --- a/src/sixtypical/emitter.py +++ b/src/sixtypical/emitter.py @@ -57,6 +57,10 @@ class Label(Emittable): assert self.addr is not None, "unresolved label: %s" % self.name return Word(self.addr).serialize(addr) + def serialize_relative_to(self, addr): + assert self.addr is not None, "unresolved label: %s" % self.name + return Byte(self.addr - (addr + 2)).serialize(addr) + def __repr__(self): addrs = ', addr=%r' % self.addr if self.addr is not None else '' return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs) @@ -71,18 +75,9 @@ class Emitter(object): def emit(self, *things): for thing in things: - if isinstance(thing, int): - thing = Byte(thing) self.accum.append(thing) self.addr += thing.size() - def emit_header(self, *things): - """Does not advance the address counter""" - for thing in things: - if isinstance(thing, int): - thing = Byte(thing) - self.accum.append(thing) - def serialize(self, stream): addr = self.start_addr for emittable in self.accum: diff --git a/src/sixtypical/gen6502.py b/src/sixtypical/gen6502.py index 47a6a8b..bfa6d19 100644 --- a/src/sixtypical/gen6502.py +++ b/src/sixtypical/gen6502.py @@ -59,9 +59,7 @@ class Relative(AddressingMode): return 1 def serialize(self, addr): - # XXX serialize value relatively - return chr(0xff) - return self.value.serialize(addr) + return self.value.serialize_relative_to(addr) class Opcode(Emittable): diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index bbc343a..bdf7b4c 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -131,4 +131,16 @@ Compiling `if`. | ld y, 2 | } | } - = 00c0 + = 00c0a900d005a0014c0bc0a00260 + +Compiling `if` without `else`. + + | routine main + | trashes a, x, y, z, n, c, v + | { + | ld a, 0 + | if z { + | ld y, 1 + | } + | } + = 00c0a900d005a0014c0bc0a00260