git @ Cat's Eye Technologies SixtyPical / c5998ed
Compile `repeat` loops. Chris Pressey 6 years ago
7 changed file(s) with 72 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
1717 ---
1818
1919 Added ability to compile to 6502 machine code and output a `PRG` file.
20
21 0.4
22 ---
23
24 Added `repeat` loops to the language.
3333 For 0.4:
3434
3535 * `if not`.
36 * `while` loops.
37 * `repeat` loops.
3836 * explicitly-addressed memory locations
3937
4038 For 0.5:
7373
7474 # we are outputting a .PRG, so we output the load address first
7575 # we don't use the Emitter for this b/c not part of addr space
76 fh.write(Word(start_addr).serialize(0))
76 if not options.debug:
77 fh.write(Word(start_addr).serialize(0))
7778
7879 emitter = Emitter(start_addr)
7980 for byte in prelude:
0 routine chrout
1 inputs a
2 trashes a
3 @ 65490
4
5 routine main
6 trashes a, y, z, n, c
7 {
8 ld y, 65
9 repeat {
10 ld a, y
11 call chrout
12 inc y
13 cmp y, 91
14 } until z
15 }
88 from sixtypical.gen6502 import (
99 Immediate, Absolute, Relative,
1010 LDA, LDX, LDY, STA, STX, STY,
11 TAX, TAY, TXA, TYA,
1112 CLC, SEC, ADC, SBC, ROL, ROR,
1213 INC, INX, INY, DEC, DEX, DEY,
1314 CMP, CPX, CPY, AND, ORA, EOR,
14 BCC, BNE,
15 BCC, BCS, BNE, BEQ,
1516 JMP, JSR, RTS,
1617 )
1718
6970
7071 if opcode == 'ld':
7172 if dest == REG_A:
72 if isinstance(src, ConstantRef):
73 if src == REG_X:
74 self.emitter.emit(TXA())
75 elif src == REG_Y:
76 self.emitter.emit(TYA())
77 elif isinstance(src, ConstantRef):
7378 self.emitter.emit(LDA(Immediate(Byte(src.value))))
7479 else:
7580 self.emitter.emit(LDA(Absolute(self.labels[src.name])))
7681 elif dest == REG_X:
77 if isinstance(src, ConstantRef):
82 if src == REG_A:
83 self.emitter.emit(TAX())
84 elif isinstance(src, ConstantRef):
7885 self.emitter.emit(LDX(Immediate(Byte(src.value))))
7986 else:
8087 self.emitter.emit(LDX(Absolute(self.labels[src.name])))
8188 elif dest == REG_Y:
82 if isinstance(src, ConstantRef):
89 if src == REG_A:
90 self.emitter.emit(TAY())
91 elif isinstance(src, ConstantRef):
8392 self.emitter.emit(LDY(Immediate(Byte(src.value))))
8493 else:
8594 self.emitter.emit(LDY(Absolute(self.labels[src.name])))
183192 self.emitter.resolve_label(end_label)
184193 else:
185194 self.emitter.resolve_label(else_label)
195 elif opcode == 'repeat':
196 cls = {
197 'c': BCC,
198 'z': BNE,
199 }.get(src.name)
200 if cls is None:
201 raise UnsupportedOpcodeError(instr)
202 top_label = self.emitter.make_label()
203 self.compile_block(instr.block)
204 self.emitter.emit(cls(Relative(top_label)))
186205 else:
187206 raise NotImplementedError
9898 }
9999
100100
101 class BCS(Opcode):
102 opcodes = {
103 Relative: 0xb0,
104 }
105
106
107 class BEQ(Opcode):
108 opcodes = {
109 Relative: 0xf0,
110 }
111
112
101113 class BNE(Opcode):
102114 opcodes = {
103115 Relative: 0xd0,
143143 | }
144144 | }
145145 = 00c0a900d002a00160
146
147 Compiling `repeat`.
148
149 | routine main
150 | trashes a, y, z, n, c
151 | {
152 | ld y, 65
153 | repeat {
154 | ld a, y
155 | inc y
156 | cmp y, 91
157 | } until z
158 | }
159 = 00c0a04198c8c05bd0fa60