git @ Cat's Eye Technologies SixtyPical / 9b912de
Accessing zero-page with `ld` and `st` generates zero-page opcodes. Chris Pressey 3 years ago
4 changed file(s) with 34 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
88 * Specifying multiple SixtyPical source files will produce a single
99 compiled result from their combination.
1010 * Added `nop` opcode, which compiles to `NOP` (mainly for timing.)
11 * Accessing zero-page with `ld` and `st` generates zero-page opcodes.
1112 * Rudimentary support for Atari 2600 prelude in a 4K cartridge image,
1213 and start of an example program in `eg/atari2600` directory.
1314
115115 jsr display_frame
116116 ;;; jsr read_joystick
117117 jmp main
118 rts ;;;
118119
119120 ;
120121 ; Vertical blank routine.
6666 return static_label
6767 return self.labels[name]
6868
69 def absolute_or_zero_page(self, label):
70 if label.addr and label.addr < 256:
71 return ZeroPage(label)
72 else:
73 return Absolute(label)
74
6975 # visitor methods
7076
7177 def compile_program(self, program):
176182 elif isinstance(src, IndirectRef) and isinstance(src.ref.type, PointerType):
177183 self.emitter.emit(LDA(IndirectY(self.get_label(src.ref.name))))
178184 else:
179 self.emitter.emit(LDA(Absolute(self.get_label(src.name))))
185 self.emitter.emit(LDA(self.absolute_or_zero_page(self.get_label(src.name))))
180186 elif dest == REG_X:
181187 if src == REG_A:
182188 self.emitter.emit(TAX())
185191 elif isinstance(src, IndexedRef) and src.index == REG_Y:
186192 self.emitter.emit(LDX(AbsoluteY(self.get_label(src.ref.name))))
187193 else:
188 self.emitter.emit(LDX(Absolute(self.get_label(src.name))))
194 self.emitter.emit(LDX(self.absolute_or_zero_page(self.get_label(src.name))))
189195 elif dest == REG_Y:
190196 if src == REG_A:
191197 self.emitter.emit(TAY())
194200 elif isinstance(src, IndexedRef) and src.index == REG_X:
195201 self.emitter.emit(LDY(AbsoluteX(self.get_label(src.ref.name))))
196202 else:
197 self.emitter.emit(LDY(Absolute(self.get_label(src.name))))
203 self.emitter.emit(LDY(self.absolute_or_zero_page(self.get_label(src.name))))
198204 else:
199205 raise UnsupportedOpcodeError(instr)
200206 elif opcode == 'st':
214220 REG_X: AbsoluteX,
215221 REG_Y: AbsoluteY,
216222 }[dest.index]
217 label = self.get_label(dest.ref.name)
223 operand = mode_cls(self.get_label(dest.ref.name))
218224 elif isinstance(dest, IndirectRef) and isinstance(dest.ref.type, PointerType):
219 mode_cls = IndirectY
220 label = self.get_label(dest.ref.name)
221 else:
222 mode_cls = Absolute
223 label = self.get_label(dest.name)
224
225 if op_cls is None or mode_cls is None:
225 operand = IndirectY(self.get_label(dest.ref.name))
226 else:
227 operand = self.absolute_or_zero_page(self.get_label(dest.name))
228
229 if op_cls is None:
226230 raise UnsupportedOpcodeError(instr)
227 self.emitter.emit(op_cls(mode_cls(label)))
231 self.emitter.emit(op_cls(operand))
228232 elif opcode == 'add':
229233 if dest == REG_A:
230234 if isinstance(src, ConstantRef):
110110 = $080D LDA #$64
111111 = $080F STA $0400
112112 = $0812 RTS
113
114 Accesses to memory locations in zero-page with `ld` and `st` use zero-page addressing.
115
116 | byte screen @ 100
117 |
118 | routine main
119 | inputs screen
120 | outputs screen
121 | trashes a, z, n
122 | {
123 | ld a, screen
124 | st a, screen
125 | }
126 = $080D LDA $64
127 = $080F STA $64
128 = $0811 RTS
113129
114130 Memory location with initial value.
115131