git @ Cat's Eye Technologies SixtyPical / 04de73d
Solve this by defining an `Offset` emittable. Chris Pressey 6 years ago
4 changed file(s) with 78 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
55 TYPE_BIT, TYPE_ROUTINE, TYPE_VECTOR,
66 REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
77 )
8 from sixtypical.emitter import Label, Byte
8 from sixtypical.emitter import Byte, Label, Offset
99 from sixtypical.gen6502 import (
1010 Immediate, Absolute, AbsoluteX, AbsoluteY, Relative,
1111 LDA, LDX, LDY, STA, STX, STY,
242242 self.emitter.emit(CLI())
243243 elif opcode == 'copy':
244244 if src.type in (TYPE_ROUTINE, TYPE_VECTOR) and dest.type == TYPE_VECTOR:
245 self.emitter.emit(LDA(Absolute(self.labels[src.name])))
246 self.emitter.emit(STA(Absolute(self.labels[dest.name])))
247 self.emitter.emit(LDA(Absolute(self.labels[src.name].clone(offset=1))))
248 self.emitter.emit(STA(Absolute(self.labels[dest.name].clone(offset=1))))
245 src_label = self.labels[src.name]
246 dest_label = self.labels[dest.name]
247 self.emitter.emit(LDA(Absolute(src_label)))
248 self.emitter.emit(STA(Absolute(dest_label)))
249 self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
250 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
249251 else:
250252 raise NotImplementedError(src.type)
251253 else:
1616 def size(self):
1717 return 1
1818
19 def serialize(self, addr):
19 def serialize(self, addr=None):
2020 return chr(self.value)
2121
2222 def __repr__(self):
3131 def size(self):
3232 return 2
3333
34 def serialize(self, addr):
34 def serialize(self, addr=None):
3535 word = self.value
3636 low = word & 255
3737 high = (word >> 8) & 255
5252 def size(self):
5353 return 2
5454
55 def serialize(self, addr):
55 def serialize(self, addr=None, offset=0):
5656 assert self.addr is not None, "unresolved label: %s" % self.name
57 return Word(self.addr).serialize(addr)
57 return Word(self.addr + offset).serialize()
5858
5959 def serialize_relative_to(self, addr):
6060 assert self.addr is not None, "unresolved label: %s" % self.name
61 return Byte(self.addr - (addr + 2)).serialize(addr)
61 return Byte(self.addr - (addr + 2)).serialize()
6262
6363 def __repr__(self):
6464 addrs = ', addr=%r' % self.addr if self.addr is not None else ''
6565 return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs)
66
67
68 class Offset(Emittable):
69 def __init__(self, label, offset):
70 assert isinstance(label, Label)
71 self.label = label
72 self.offset = offset
73
74 def size(self):
75 self.label.size()
76
77 def serialize(self, addr=None):
78 return self.label.serialize(offset=self.offset)
79
80 def __repr__(self):
81 return "%s(%r, %r)" % (self.__class__.__name__, self.label, self.offset)
6682
6783
6884 class Emitter(object):
00 """Emittables for 6502 machine code."""
11
2 from sixtypical.emitter import Emittable, Byte, Word, Label
3
4
5 class AddressingMode(object):
2 from sixtypical.emitter import Emittable, Byte, Word, Label, Offset
3
4
5 class AddressingMode(Emittable):
66 def size(self):
77 """Size of the operand for the mode (not including the opcode)"""
88 raise NotImplementedError
99
10 def serialize(self, addr):
10 def serialize(self, addr=None):
1111 raise NotImplementedError
1212
1313 def __repr__(self):
1818 def size(self):
1919 return 0
2020
21 def serialize(self, addr):
21 def serialize(self, addr=None):
2222 return ''
2323
2424 def __repr__(self):
3333 def size(self):
3434 return 1
3535
36 def serialize(self, addr):
37 return self.value.serialize(addr)
36 def serialize(self, addr=None):
37 return self.value.serialize()
3838
3939
4040 class Absolute(AddressingMode):
4141 def __init__(self, value):
42 assert isinstance(value, Label)
42 assert isinstance(value, (Label, Offset))
4343 self.value = value
4444
4545 def size(self):
4646 return 2
4747
48 def serialize(self, addr):
49 return self.value.serialize(addr)
48 def serialize(self, addr=None):
49 return self.value.serialize()
5050
5151
5252 class AbsoluteX(Absolute):
6565 def size(self):
6666 return 1
6767
68 def serialize(self, addr):
68 def serialize(self, addr=None):
6969 return self.value.serialize_relative_to(addr)
7070
7171
7676 def size(self):
7777 return 1 + self.operand.size() if self.operand else 0
7878
79 def serialize(self, addr):
79 def serialize(self, addr=None):
8080 return (
8181 chr(self.opcodes[self.operand.__class__]) +
8282 self.operand.serialize(addr)
223223 | ld a, many + x
224224 | }
225225 = 00c0a200a9009d0dc0bd0dc060
226
227 Copy instruction..
228
229 | vector bar
230 | vector baz
231 |
232 | routine main
233 | inputs baz
234 | outputs bar
235 | trashes a, n, z
236 | {
237 | copy baz, bar
238 | }
239 = 00c0ad0fc08d0dc0ad10c08d0ec060
240
241 Copy instruction inside interrupts off block.
242
243 | vector bar
244 |
245 | routine foo
246 | inputs x
247 | outputs x
248 | trashes z, n
249 | {
250 | inc x
251 | }
252 |
253 | routine main
254 | inputs foo
255 | outputs bar
256 | trashes a, n, z
257 | {
258 | with interrupts off {
259 | copy foo, bar
260 | }
261 | }
262 = 00c078ad0fc08d11c0ad10c08d12c05860e860