{Low,High}AddressByte emittables to fix copy, make indirect call!
Chris Pressey
9 years ago
6 | 6 | RoutineType, VectorType, |
7 | 7 | REG_A, REG_X, REG_Y, FLAG_C |
8 | 8 | ) |
9 | from sixtypical.emitter import Byte, Label, Offset | |
9 | from sixtypical.emitter import Byte, Label, Offset, LowAddressByte, HighAddressByte | |
10 | 10 | from sixtypical.gen6502 import ( |
11 | 11 | Immediate, Absolute, AbsoluteX, AbsoluteY, Indirect, Relative, |
12 | 12 | LDA, LDX, LDY, STA, STX, STY, |
266 | 266 | self.compile_block(instr.block) |
267 | 267 | self.emitter.emit(CLI()) |
268 | 268 | elif opcode == 'copy': |
269 | if isinstance(src.type, (RoutineType, VectorType)) and \ | |
270 | isinstance(dest.type, VectorType): | |
269 | if isinstance(src.type, VectorType) and isinstance(dest.type, VectorType): | |
271 | 270 | src_label = self.labels[src.name] |
272 | 271 | dest_label = self.labels[dest.name] |
273 | 272 | self.emitter.emit(LDA(Absolute(src_label))) |
274 | 273 | self.emitter.emit(STA(Absolute(dest_label))) |
275 | 274 | self.emitter.emit(LDA(Absolute(Offset(src_label, 1)))) |
276 | 275 | self.emitter.emit(STA(Absolute(Offset(dest_label, 1)))) |
276 | elif isinstance(src.type, RoutineType) and isinstance(dest.type, VectorType): | |
277 | src_label = self.labels[src.name] | |
278 | dest_label = self.labels[dest.name] | |
279 | self.emitter.emit(LDA(Immediate(HighAddressByte(src_label)))) | |
280 | self.emitter.emit(STA(Absolute(dest_label))) | |
281 | self.emitter.emit(LDA(Immediate(LowAddressByte(src_label)))) | |
282 | self.emitter.emit(STA(Absolute(Offset(dest_label, 1)))) | |
277 | 283 | else: |
278 | 284 | raise NotImplementedError(src.type) |
279 | 285 | else: |
81 | 81 | return "%s(%r, %r)" % (self.__class__.__name__, self.label, self.offset) |
82 | 82 | |
83 | 83 | |
84 | class HighAddressByte(Emittable): | |
85 | def __init__(self, label): | |
86 | assert isinstance(label, Label) | |
87 | self.label = label | |
88 | ||
89 | def size(self): | |
90 | return 1 | |
91 | ||
92 | def serialize(self, addr=None): | |
93 | return self.label.serialize()[0] | |
94 | ||
95 | def __repr__(self): | |
96 | return "%s(%r)" % (self.__class__.__name__, self.label) | |
97 | ||
98 | ||
99 | class LowAddressByte(Emittable): | |
100 | def __init__(self, label): | |
101 | assert isinstance(label, Label) | |
102 | self.label = label | |
103 | ||
104 | def size(self): | |
105 | return 1 | |
106 | ||
107 | def serialize(self, addr=None): | |
108 | return self.label.serialize()[1] | |
109 | ||
110 | def __repr__(self): | |
111 | return "%s(%r)" % (self.__class__.__name__, self.label) | |
112 | ||
113 | ||
114 | # - - - - | |
115 | ||
116 | ||
84 | 117 | class Emitter(object): |
85 | 118 | def __init__(self, addr): |
86 | 119 | self.accum = [] |
0 | 0 | """Emittables for 6502 machine code.""" |
1 | 1 | |
2 | from sixtypical.emitter import Emittable, Byte, Label, Offset | |
2 | from sixtypical.emitter import Emittable, Byte, Label, Offset, LowAddressByte, HighAddressByte | |
3 | 3 | |
4 | 4 | |
5 | 5 | class AddressingMode(Emittable): |
27 | 27 | |
28 | 28 | class Immediate(AddressingMode): |
29 | 29 | def __init__(self, value): |
30 | assert isinstance(value, Byte) | |
30 | assert isinstance(value, (Byte, LowAddressByte, HighAddressByte)) | |
31 | 31 | self.value = value |
32 | 32 | |
33 | 33 | def size(self): |
81 | 81 | return self.value.serialize_relative_to(addr) |
82 | 82 | |
83 | 83 | |
84 | # - - - - | |
85 | ||
86 | ||
84 | 87 | class Instruction(Emittable): |
85 | 88 | def __init__(self, operand=None): |
86 | 89 | self.operand = operand or Implied() |