diff --git a/bin/sixtypical b/bin/sixtypical index 03013b5..b6d8b6c 100755 --- a/bin/sixtypical +++ b/bin/sixtypical @@ -28,22 +28,22 @@ if __name__ == '__main__': optparser = OptionParser(__doc__.strip()) optparser.add_option("--analyze", - action="store_true", dest="analyze", default=False, + action="store_true", help="") - optparser.add_option("--basic-header", - action="store_true", dest="basic_header", default=False, + optparser.add_option("--basic-prelude", + action="store_true", help="") optparser.add_option("--compile", - action="store_true", dest="compile", default=False, + action="store_true", help="") optparser.add_option("--debug", - action="store_true", dest="debug", default=False, + action="store_true", help="") optparser.add_option("--traceback", - action="store_true", dest="traceback", default=False, + action="store_true", help="") optparser.add_option("--execute", - action="store_true", dest="execute", default=False, + action="store_true", help="") (options, args) = optparser.parse_args(sys.argv[1:]) @@ -65,15 +65,15 @@ if __name__ == '__main__': if options.compile: start_addr = 0xc000 - header = [] - if options.basic_header: + prelude = [] + if options.basic_prelude: start_addr = 0x0801 - header = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32, - 0x30, 0x36, 0x31, 0x00, 0x00, 0x00] + prelude = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32, + 0x30, 0x36, 0x31, 0x00, 0x00, 0x00] emitter = Emitter(start_addr) # we are outputting a .PRG, so output the load address first - emitter.emit(Word(start_addr)) - for byte in header: + emitter.emit_header(Word(start_addr)) + for byte in prelude: emitter.emit(Byte(byte)) compiler = Compiler(emitter) compiler.compile_program(program) diff --git a/loadngo.sh b/loadngo.sh index 2182ca2..ed2a1bb 100755 --- a/loadngo.sh +++ b/loadngo.sh @@ -2,6 +2,6 @@ SRC=$1 OUT=/tmp/a-out.prg -bin/sixtypical --analyze --compile --basic-header $SRC > $OUT || exit 1 +bin/sixtypical --analyze --compile --basic-prelude $SRC > $OUT || exit 1 x64 $OUT rm -f $OUT diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index df83c54..5f53c9a 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -30,12 +30,16 @@ class Compiler(object): if routine.addr is not None: label.set_addr(routine.addr) self.labels[routine.name] = label + + self.compile_routine(self.routines['main']) for routine in program.routines: - self.compile_routine(routine) + if routine.name != 'main': + self.compile_routine(routine) def compile_routine(self, routine): assert isinstance(routine, Routine) if routine.block: + self.emitter.resolve_label(self.labels[routine.name]) self.compile_block(routine.block) self.emitter.emit(RTS()) @@ -57,11 +61,17 @@ class Compiler(object): if isinstance(src, ConstantRef): self.emitter.emit(LDA(Immediate(Byte(src.value)))) else: - self.emitter.emit(LDA(Absolute(src.label))) + self.emitter.emit(LDA(Absolute(self.labels[src.name]))) elif dest == REG_X: - pass + if isinstance(src, ConstantRef): + self.emitter.emit(LDX(Immediate(Byte(src.value)))) + else: + self.emitter.emit(LDX(Absolute(self.labels[src.name]))) elif dest == REG_Y: - pass + if isinstance(src, ConstantRef): + self.emitter.emit(LDY(Immediate(Byte(src.value)))) + else: + self.emitter.emit(LDY(Absolute(self.labels[src.name]))) else: raise UnsupportedOpcodeError(instr) elif opcode == 'st': @@ -70,11 +80,11 @@ class Compiler(object): elif dest == FLAG_C and src == ConstantRef(1): self.emitter.emit(SEC()) elif src == REG_A: - self.emitter.emit(STA(Absolute(dest.label))) + self.emitter.emit(STA(Absolute(self.labels[dest.name]))) elif src == REG_X: - self.emitter.emit(STX(Absolute(dest.label))) + self.emitter.emit(STX(Absolute(self.labels[dest.name]))) elif src == REG_Y: - self.emitter.emit(STY(Absolute(dest.label))) + self.emitter.emit(STY(Absolute(self.labels[dest.name]))) else: raise UnsupportedOpcodeError(instr) elif opcode == 'add': diff --git a/src/sixtypical/emitter.py b/src/sixtypical/emitter.py index e50ef7b..2788d5a 100644 --- a/src/sixtypical/emitter.py +++ b/src/sixtypical/emitter.py @@ -76,6 +76,13 @@ class Emitter(object): 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): for emittable in self.accum: stream.write(emittable.serialize()) diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index 5d5c26b..f5c414b 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -45,3 +45,21 @@ Call extern. | call chrout | } = 00c0a94120d2ff60 + +Call defined routine. + + | routine foo + | outputs a, x, y + | trashes z, n + | { + | ld a, 0 + | ld x, 0 + | ld y, 0 + | } + | + | routine main + | trashes a, x, y, z, n + | { + | call foo + | } + = 00c02004c060a900a200a00060