diff --git a/eg/add-pass.60p b/eg/add-pass.60p index 16a18ab..65c69f1 100644 --- a/eg/add-pass.60p +++ b/eg/add-pass.60p @@ -1,4 +1,4 @@ -routine add_four +routine main inputs a outputs a trashes c, z, n, v diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 5f53c9a..7402e63 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -8,7 +8,8 @@ from sixtypical.model import ( from sixtypical.emitter import Label, Byte from sixtypical.gen6502 import ( Immediate, Absolute, - LDA, LDX, LDY, STA, STX, STY, CLC, SEC, ADC, RTS, JSR + LDA, LDX, LDY, STA, STX, STY, CLC, SEC, ADC, RTS, JSR, + INC, INX, INY, DEC, DEX, DEY, ) @@ -24,6 +25,11 @@ class Compiler(object): def compile_program(self, program): assert isinstance(program, Program) + + for defn in program.defns: + label = Label(defn.name) + self.labels[defn.name] = label + for routine in program.routines: self.routines[routine.name] = routine label = Label(routine.name) @@ -36,6 +42,10 @@ class Compiler(object): if routine.name != 'main': self.compile_routine(routine) + for defn in program.defns: + label = self.labels[defn.name] + self.emitter.resolve_bss_label(label) + def compile_routine(self, routine): assert isinstance(routine, Routine) if routine.block: @@ -92,15 +102,31 @@ class Compiler(object): if isinstance(src, ConstantRef): self.emitter.emit(ADC(Immediate(Byte(src.value)))) else: - self.emitter.emit(ADC(Absolute(src.label))) + self.emitter.emit(ADC(Absolute(self.labels[src.name]))) else: raise UnsupportedOpcodeError(instr) elif opcode == 'sub': - raise NotImplementedError + if dest == REG_A: + if isinstance(src, ConstantRef): + self.emitter.emit(SBC(Immediate(Byte(src.value)))) + else: + self.emitter.emit(SBC(Absolute(self.labels[src.name]))) + else: + raise UnsupportedOpcodeError(instr) elif opcode == 'inc': - raise NotImplementedError + if dest == REG_X: + self.emitter.emit(INX()) + elif dest == REG_Y: + self.emitter.emit(INY()) + else: + self.emitter.emit(INC(Absolute(self.labels[dest.name]))) elif opcode == 'dec': - raise NotImplementedError + if dest == REG_X: + self.emitter.emit(DEX()) + elif dest == REG_Y: + self.emitter.emit(DEY()) + else: + self.emitter.emit(DEC(Absolute(self.labels[dest.name]))) elif opcode == 'cmp': raise NotImplementedError elif opcode == 'and': diff --git a/src/sixtypical/emitter.py b/src/sixtypical/emitter.py index 2788d5a..cada7c8 100644 --- a/src/sixtypical/emitter.py +++ b/src/sixtypical/emitter.py @@ -95,3 +95,9 @@ class Emitter(object): def resolve_label(self, label): label.set_addr(self.addr) + + def resolve_bss_label(self, label): + """Set the given label to be at the current address and + advance the address for the next label, but don't emit anything.""" + self.resolve_label(label) + self.addr += label.size() diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index f5c414b..1d2b054 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -63,3 +63,16 @@ Call defined routine. | call foo | } = 00c02004c060a900a200a00060 + +Access a defined memory location. + + | byte foo + | + | routine main + | trashes a, y, z, n, foo + | { + | ld y, 0 + | st y, foo + | ld a, foo + | } + = 00c0a0008c09c0ad09c060