git @ Cat's Eye Technologies SixtyPical / b6bb645
Implement compiling `if`, but we need relative addressing first. Chris Pressey 6 years ago
3 changed file(s) with 67 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
66 )
77 from sixtypical.emitter import Label, Byte
88 from sixtypical.gen6502 import (
9 Immediate, Absolute,
9 Immediate, Absolute, Relative,
1010 LDA, LDX, LDY, STA, STX, STY,
1111 CLC, SEC, ADC, SBC, ROL, ROR,
12 RTS, JSR,
1312 INC, INX, INY, DEC, DEX, DEY,
1413 CMP, CPX, CPY, AND, ORA, EOR,
14 BCC, BNE,
15 JMP, JSR, RTS,
1516 )
1617
1718
5758
5859 def compile_block(self, block):
5960 assert isinstance(block, Block)
60 label = self.emitter.make_label()
6161 for instr in block.instrs:
6262 self.compile_instr(instr)
63 return label
6463
6564 def compile_instr(self, instr):
6665 assert isinstance(instr, Instr)
167166 label = self.labels[instr.name]
168167 self.emitter.emit(JSR(Absolute(label)))
169168 elif opcode == 'if':
170 raise NotImplementedError
169 cls = {
170 'c': BCC,
171 'z': BNE,
172 }.get(src.name)
173 if cls is None:
174 raise UnsupportedOpcodeError(instr)
175 else_label = Label('else_label')
176 self.emitter.emit(cls(Relative(else_label)))
177 self.compile_block(instr.block1)
178 if instr.block2:
179 end_label = Label('end_label')
180 self.emitter.emit(JMP(Absolute(end_label)))
181 self.emitter.resolve_label(else_label)
182 self.compile_block(instr.block2)
183 self.emitter.resolve_label(end_label)
184 else:
185 self.emitter.resolve_label(else_label)
171186 else:
172187 raise NotImplementedError
66 def size(self):
77 """Size of the operand for the mode (not including the opcode)"""
88 raise NotImplementedError
9
10 def __repr__(self):
11 return "%s(%r)" % (self.__class__.__name__, self.value)
912
1013
1114 class Implied(AddressingMode):
3033 def serialize(self):
3134 return self.value.serialize()
3235
33 def __repr__(self):
34 return "%s(%r)" % (self.__class__.__name__, self.value)
35
3636
3737 class Absolute(AddressingMode):
3838 def __init__(self, value):
4545 def serialize(self):
4646 return self.value.serialize()
4747
48 def __repr__(self):
49 return "%s(%r)" % (self.__class__.__name__, self.value)
48
49 class Relative(AddressingMode):
50 def __init__(self, value):
51 assert isinstance(value, (Byte, Label))
52 self.value = value
53
54 def size(self):
55 return 1
56
57 def serialize(self):
58 # HA
59 return chr(0xff)
5060
5161
5262 class Opcode(Emittable):
8090 }
8191
8292
93 class BCC(Opcode):
94 opcodes = {
95 Relative: 0x90,
96 }
97
98
99 class BNE(Opcode):
100 opcodes = {
101 Relative: 0xd0,
102 }
103
104
83105 class CLC(Opcode):
84106 opcodes = {
85107 Implied: 0x18
150172 }
151173
152174
175 class JMP(Opcode):
176 opcodes = {
177 Absolute: 0x4c,
178 }
179
180
153181 class JSR(Opcode):
154182 opcodes = {
155183 Absolute: 0x20,
117117 | shr a
118118 | }
119119 = 00c0a900a200a0008d46c08e46c08c46c0381869016d46c0e901ed46c0ee46c0e8c8ce46c0ca8829ff2d46c009ff0d46c049ff4d46c0c901cd46c0e001ec46c0c001cc46c02a6a60
120
121 Compiling `if`.
122
123 | routine main
124 | trashes a, x, y, z, n, c, v
125 | {
126 | ld a, 0
127 | if z {
128 | ld y, 1
129 | } else {
130 | ld y, 2
131 | }
132 | }
133 = 00c0