Call defined routines.
Chris Pressey
9 years ago
27 | 27 | optparser = OptionParser(__doc__.strip()) |
28 | 28 | |
29 | 29 | optparser.add_option("--analyze", |
30 | action="store_true", dest="analyze", default=False, | |
30 | action="store_true", | |
31 | 31 | help="") |
32 | optparser.add_option("--basic-header", | |
33 | action="store_true", dest="basic_header", default=False, | |
32 | optparser.add_option("--basic-prelude", | |
33 | action="store_true", | |
34 | 34 | help="") |
35 | 35 | optparser.add_option("--compile", |
36 | action="store_true", dest="compile", default=False, | |
36 | action="store_true", | |
37 | 37 | help="") |
38 | 38 | optparser.add_option("--debug", |
39 | action="store_true", dest="debug", default=False, | |
39 | action="store_true", | |
40 | 40 | help="") |
41 | 41 | optparser.add_option("--traceback", |
42 | action="store_true", dest="traceback", default=False, | |
42 | action="store_true", | |
43 | 43 | help="") |
44 | 44 | optparser.add_option("--execute", |
45 | action="store_true", dest="execute", default=False, | |
45 | action="store_true", | |
46 | 46 | help="") |
47 | 47 | |
48 | 48 | (options, args) = optparser.parse_args(sys.argv[1:]) |
64 | 64 | |
65 | 65 | if options.compile: |
66 | 66 | start_addr = 0xc000 |
67 | header = [] | |
68 | if options.basic_header: | |
67 | prelude = [] | |
68 | if options.basic_prelude: | |
69 | 69 | start_addr = 0x0801 |
70 | header = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32, | |
71 | 0x30, 0x36, 0x31, 0x00, 0x00, 0x00] | |
70 | prelude = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32, | |
71 | 0x30, 0x36, 0x31, 0x00, 0x00, 0x00] | |
72 | 72 | emitter = Emitter(start_addr) |
73 | 73 | # we are outputting a .PRG, so output the load address first |
74 | emitter.emit(Word(start_addr)) | |
75 | for byte in header: | |
74 | emitter.emit_header(Word(start_addr)) | |
75 | for byte in prelude: | |
76 | 76 | emitter.emit(Byte(byte)) |
77 | 77 | compiler = Compiler(emitter) |
78 | 78 | compiler.compile_program(program) |
1 | 1 | |
2 | 2 | SRC=$1 |
3 | 3 | OUT=/tmp/a-out.prg |
4 | bin/sixtypical --analyze --compile --basic-header $SRC > $OUT || exit 1 | |
4 | bin/sixtypical --analyze --compile --basic-prelude $SRC > $OUT || exit 1 | |
5 | 5 | x64 $OUT |
6 | 6 | rm -f $OUT |
29 | 29 | if routine.addr is not None: |
30 | 30 | label.set_addr(routine.addr) |
31 | 31 | self.labels[routine.name] = label |
32 | ||
33 | self.compile_routine(self.routines['main']) | |
32 | 34 | for routine in program.routines: |
33 | self.compile_routine(routine) | |
35 | if routine.name != 'main': | |
36 | self.compile_routine(routine) | |
34 | 37 | |
35 | 38 | def compile_routine(self, routine): |
36 | 39 | assert isinstance(routine, Routine) |
37 | 40 | if routine.block: |
41 | self.emitter.resolve_label(self.labels[routine.name]) | |
38 | 42 | self.compile_block(routine.block) |
39 | 43 | self.emitter.emit(RTS()) |
40 | 44 | |
56 | 60 | if isinstance(src, ConstantRef): |
57 | 61 | self.emitter.emit(LDA(Immediate(Byte(src.value)))) |
58 | 62 | else: |
59 | self.emitter.emit(LDA(Absolute(src.label))) | |
63 | self.emitter.emit(LDA(Absolute(self.labels[src.name]))) | |
60 | 64 | elif dest == REG_X: |
61 | pass | |
65 | if isinstance(src, ConstantRef): | |
66 | self.emitter.emit(LDX(Immediate(Byte(src.value)))) | |
67 | else: | |
68 | self.emitter.emit(LDX(Absolute(self.labels[src.name]))) | |
62 | 69 | elif dest == REG_Y: |
63 | pass | |
70 | if isinstance(src, ConstantRef): | |
71 | self.emitter.emit(LDY(Immediate(Byte(src.value)))) | |
72 | else: | |
73 | self.emitter.emit(LDY(Absolute(self.labels[src.name]))) | |
64 | 74 | else: |
65 | 75 | raise UnsupportedOpcodeError(instr) |
66 | 76 | elif opcode == 'st': |
69 | 79 | elif dest == FLAG_C and src == ConstantRef(1): |
70 | 80 | self.emitter.emit(SEC()) |
71 | 81 | elif src == REG_A: |
72 | self.emitter.emit(STA(Absolute(dest.label))) | |
82 | self.emitter.emit(STA(Absolute(self.labels[dest.name]))) | |
73 | 83 | elif src == REG_X: |
74 | self.emitter.emit(STX(Absolute(dest.label))) | |
84 | self.emitter.emit(STX(Absolute(self.labels[dest.name]))) | |
75 | 85 | elif src == REG_Y: |
76 | self.emitter.emit(STY(Absolute(dest.label))) | |
86 | self.emitter.emit(STY(Absolute(self.labels[dest.name]))) | |
77 | 87 | else: |
78 | 88 | raise UnsupportedOpcodeError(instr) |
79 | 89 | elif opcode == 'add': |
75 | 75 | self.accum.append(thing) |
76 | 76 | self.addr += thing.size() |
77 | 77 | |
78 | def emit_header(self, *things): | |
79 | """Does not advance the address counter""" | |
80 | for thing in things: | |
81 | if isinstance(thing, int): | |
82 | thing = Byte(thing) | |
83 | self.accum.append(thing) | |
84 | ||
78 | 85 | def serialize(self, stream): |
79 | 86 | for emittable in self.accum: |
80 | 87 | stream.write(emittable.serialize()) |
44 | 44 | | call chrout |
45 | 45 | | } |
46 | 46 | = 00c0a94120d2ff60 |
47 | ||
48 | Call defined routine. | |
49 | ||
50 | | routine foo | |
51 | | outputs a, x, y | |
52 | | trashes z, n | |
53 | | { | |
54 | | ld a, 0 | |
55 | | ld x, 0 | |
56 | | ld y, 0 | |
57 | | } | |
58 | | | |
59 | | routine main | |
60 | | trashes a, x, y, z, n | |
61 | | { | |
62 | | call foo | |
63 | | } | |
64 | = 00c02004c060a900a200a00060 |