diff --git a/HISTORY.md b/HISTORY.md index e2c2dbc..10a7bf1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ History of SixtyPical * Specifying multiple SixtyPical source files will produce a single compiled result from their combination. * Added `nop` opcode, which compiles to `NOP` (mainly for timing.) +* Accessing zero-page with `ld` and `st` generates zero-page opcodes. * Rudimentary support for Atari 2600 prelude in a 4K cartridge image, and start of an example program in `eg/atari2600` directory. diff --git a/eg/atari2600/atari-2600-example.oph b/eg/atari2600/atari-2600-example.oph index ae33962..8ab1c3f 100644 --- a/eg/atari2600/atari-2600-example.oph +++ b/eg/atari2600/atari-2600-example.oph @@ -116,6 +116,7 @@ main: jsr display_frame ;;; jsr read_joystick jmp main + rts ;;; ; ; Vertical blank routine. diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index b02e717..c4f6d87 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -67,6 +67,12 @@ class Compiler(object): return static_label return self.labels[name] + def absolute_or_zero_page(self, label): + if label.addr and label.addr < 256: + return ZeroPage(label) + else: + return Absolute(label) + # visitor methods def compile_program(self, program): @@ -177,7 +183,7 @@ class Compiler(object): elif isinstance(src, IndirectRef) and isinstance(src.ref.type, PointerType): self.emitter.emit(LDA(IndirectY(self.get_label(src.ref.name)))) else: - self.emitter.emit(LDA(Absolute(self.get_label(src.name)))) + self.emitter.emit(LDA(self.absolute_or_zero_page(self.get_label(src.name)))) elif dest == REG_X: if src == REG_A: self.emitter.emit(TAX()) @@ -186,7 +192,7 @@ class Compiler(object): elif isinstance(src, IndexedRef) and src.index == REG_Y: self.emitter.emit(LDX(AbsoluteY(self.get_label(src.ref.name)))) else: - self.emitter.emit(LDX(Absolute(self.get_label(src.name)))) + self.emitter.emit(LDX(self.absolute_or_zero_page(self.get_label(src.name)))) elif dest == REG_Y: if src == REG_A: self.emitter.emit(TAY()) @@ -195,7 +201,7 @@ class Compiler(object): elif isinstance(src, IndexedRef) and src.index == REG_X: self.emitter.emit(LDY(AbsoluteX(self.get_label(src.ref.name)))) else: - self.emitter.emit(LDY(Absolute(self.get_label(src.name)))) + self.emitter.emit(LDY(self.absolute_or_zero_page(self.get_label(src.name)))) else: raise UnsupportedOpcodeError(instr) elif opcode == 'st': @@ -215,17 +221,15 @@ class Compiler(object): REG_X: AbsoluteX, REG_Y: AbsoluteY, }[dest.index] - label = self.get_label(dest.ref.name) + operand = mode_cls(self.get_label(dest.ref.name)) elif isinstance(dest, IndirectRef) and isinstance(dest.ref.type, PointerType): - mode_cls = IndirectY - label = self.get_label(dest.ref.name) + operand = IndirectY(self.get_label(dest.ref.name)) else: - mode_cls = Absolute - label = self.get_label(dest.name) + operand = self.absolute_or_zero_page(self.get_label(dest.name)) - if op_cls is None or mode_cls is None: + if op_cls is None: raise UnsupportedOpcodeError(instr) - self.emitter.emit(op_cls(mode_cls(label))) + self.emitter.emit(op_cls(operand)) elif opcode == 'add': if dest == REG_A: if isinstance(src, ConstantRef): diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index ee26696..759a474 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -112,6 +112,22 @@ Memory location with explicit address. = $080F STA $0400 = $0812 RTS +Accesses to memory locations in zero-page with `ld` and `st` use zero-page addressing. + + | byte screen @ 100 + | + | routine main + | inputs screen + | outputs screen + | trashes a, z, n + | { + | ld a, screen + | st a, screen + | } + = $080D LDA $64 + = $080F STA $64 + = $0811 RTS + Memory location with initial value. | byte lives : 3