git @ Cat's Eye Technologies SixtyPical / bc91ef1
Compile byte-table add, sub, cmp, and, or, xor, shl, shr, inc, dec. Chris Pressey 3 years ago
5 changed file(s) with 100 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
99 assigning a routine to a vector with a "wider" type.
1010 * Support for `copy [ptra]+y, [ptrb]+y` to indirect LDA indirect STA.
1111 * Support for `shl foo` and `shr foo` where `foo` is a byte storage.
12 * Support for `I a, btable + x` where `I` is `add`, `sub`, `cmp`,
13 `and`, `or`, or `xor`
14 * Support for `I btable + x` where `I` is `shl`, `shr`, `inc`, `dec`
1215
1316 0.15
1417 ----
6868 TODO
6969 ----
7070
71 ### Save registers on stack
72
73 This preserves them, so that, semantically, they can be used later even though they
74 are trashed inside the block.
75
76 ### And at some point...
77
71 * Save registers on stack: this preserves them, so that, semantically, they can be used later even though they
72 are trashed inside the block.
7873 * `low` and `high` address operators - to turn `word` type into `byte`.
7974 * Related: can we simply view a (small) part of a buffer as a byte table? If not, why not?
8075 * Related: add constant to buffer to get new buffer. (Or to table, but... well, maybe.)
8378 * `static` pointers -- currently not possible because pointers must be zero-page, thus `@`, thus uninitialized.
8479 * Question the value of the "consistent initialization" principle for `if` statement analysis.
8580 * `interrupt` routines -- to indicate that "the supervisor" has stored values on the stack, so we can trash them.
86 * Add absolute-indexed for add, sub, and, or, xor, shl, shr
8781 * Automatic tail-call optimization (could be tricky, w/constraints?)
8882
8983 [VICE]: http://vice-emu.sourceforge.net/
243243 if dest == REG_A:
244244 if isinstance(src, ConstantRef):
245245 self.emitter.emit(ADC(Immediate(Byte(src.value))))
246 elif isinstance(src, IndexedRef):
247 self.emitter.emit(ADC(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
246248 else:
247249 self.emitter.emit(ADC(Absolute(self.get_label(src.name))))
248250 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
291293 if dest == REG_A:
292294 if isinstance(src, ConstantRef):
293295 self.emitter.emit(SBC(Immediate(Byte(src.value))))
296 elif isinstance(src, IndexedRef):
297 self.emitter.emit(SBC(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
294298 else:
295299 self.emitter.emit(SBC(Absolute(self.get_label(src.name))))
296300 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
315319 raise UnsupportedOpcodeError(instr)
316320 else:
317321 raise UnsupportedOpcodeError(instr)
318 elif opcode == 'inc':
319 self.compile_inc(instr, instr.dest)
320 elif opcode == 'dec':
321 self.compile_dec(instr, instr.dest)
322322 elif opcode == 'cmp':
323323 self.compile_cmp(instr, instr.src, instr.dest)
324324 elif opcode in ('and', 'or', 'xor',):
330330 if dest == REG_A:
331331 if isinstance(src, ConstantRef):
332332 self.emitter.emit(cls(Immediate(Byte(src.value))))
333 elif isinstance(src, IndexedRef):
334 self.emitter.emit(cls(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
333335 else:
334336 self.emitter.emit(cls(self.absolute_or_zero_page(self.get_label(src.name))))
335337 else:
336338 raise UnsupportedOpcodeError(instr)
339 elif opcode == 'inc':
340 self.compile_inc(instr, instr.dest)
341 elif opcode == 'dec':
342 self.compile_dec(instr, instr.dest)
337343 elif opcode in ('shl', 'shr'):
338344 cls = {
339345 'shl': ROL,
341347 }[opcode]
342348 if dest == REG_A:
343349 self.emitter.emit(cls())
350 elif isinstance(dest, IndexedRef):
351 self.emitter.emit(cls(self.addressing_mode_for_index(dest.index)(self.get_label(dest.ref.name))))
344352 else:
345353 self.emitter.emit(cls(self.absolute_or_zero_page(self.get_label(dest.name))))
346354 elif opcode == 'call':
388396 raise UnsupportedOpcodeError(instr)
389397 if isinstance(src, ConstantRef):
390398 self.emitter.emit(cls(Immediate(Byte(src.value))))
399 elif isinstance(src, IndexedRef):
400 # FIXME might not work for some dest's (that is, cls's)
401 self.emitter.emit(cls(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
391402 else:
392403 self.emitter.emit(cls(Absolute(self.get_label(src.name))))
393404
397408 self.emitter.emit(INX())
398409 elif dest == REG_Y:
399410 self.emitter.emit(INY())
411 elif isinstance(dest, IndexedRef):
412 self.emitter.emit(INC(self.addressing_mode_for_index(dest.index)(self.get_label(dest.ref.name))))
400413 else:
401414 self.emitter.emit(INC(Absolute(self.get_label(dest.name))))
402415
406419 self.emitter.emit(DEX())
407420 elif dest == REG_Y:
408421 self.emitter.emit(DEY())
422 elif isinstance(dest, IndexedRef):
423 self.emitter.emit(DEC(self.addressing_mode_for_index(dest.index)(self.get_label(dest.ref.name))))
409424 else:
410425 self.emitter.emit(DEC(Absolute(self.get_label(dest.name))))
411426
210210 class DEC(Instruction):
211211 opcodes = {
212212 Absolute: 0xce,
213 AbsoluteX: 0xde,
213214 }
214215
215216
218218 = $081A BRK
219219
220220 Initialized word table, initialized with list of word values.
221
222 FIXME wait, is this not a word table[4]?
221223
222224 | word table[8] message : 65535, 0, 127
223225 |
312314 = $0855 ROR $0859
313315 = $0858 RTS
314316
317 Some instructions on tables. (1/3)
318
319 | byte table[256] many
320 |
321 | routine main
322 | inputs many
323 | outputs many
324 | trashes a, x, c, n, z, v
325 | {
326 | ld x, 0
327 | ld a, 0
328 | st off, c
329 | add a, many + x
330 | sub a, many + x
331 | cmp a, many + x
332 | }
333 = $080D LDX #$00
334 = $080F LDA #$00
335 = $0811 CLC
336 = $0812 ADC $081C,X
337 = $0815 SBC $081C,X
338 = $0818 CMP $081C,X
339 = $081B RTS
340
341 Some instructions on tables. (2/3)
342
343 | byte table[256] many
344 |
345 | routine main
346 | inputs many
347 | outputs many
348 | trashes a, x, c, n, z
349 | {
350 | ld x, 0
351 | ld a, 0
352 | and a, many + x
353 | or a, many + x
354 | xor a, many + x
355 | }
356 = $080D LDX #$00
357 = $080F LDA #$00
358 = $0811 AND $081B,X
359 = $0814 ORA $081B,X
360 = $0817 EOR $081B,X
361 = $081A RTS
362
363 Some instructions on tables. (3/3)
364
365 | byte table[256] many
366 |
367 | routine main
368 | inputs many
369 | outputs many
370 | trashes a, x, c, n, z
371 | {
372 | ld x, 0
373 | ld a, 0
374 | st off, c
375 | shl many + x
376 | shr many + x
377 | inc many + x
378 | dec many + x
379 | }
380 = $080D LDX #$00
381 = $080F LDA #$00
382 = $0811 CLC
383 = $0812 ROL $081F,X
384 = $0815 ROR $081F,X
385 = $0818 INC $081F,X
386 = $081B DEC $081F,X
387 = $081E RTS
388
315389 Compiling `if`.
316390
317391 | routine main
524598 = $0814 LDA $0819,X
525599 = $0817 RTS
526600
527 Byte tables take up 256 bytes in memory.
601 Byte tables take up, at most, 256 bytes in memory.
528602
529603 | byte table[256] tab1
530604 | byte table[256] tab2