1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-07 06:29:32 +00:00

Compile byte-table add, sub, cmp, and, or, xor, shl, shr, inc, dec.

This commit is contained in:
Chris Pressey 2018-04-18 16:32:12 +01:00
parent 5fcbfa1d21
commit bc91ef1602
5 changed files with 100 additions and 13 deletions

View File

@ -10,6 +10,9 @@ History of SixtyPical
assigning a routine to a vector with a "wider" type.
* Support for `copy [ptra]+y, [ptrb]+y` to indirect LDA indirect STA.
* Support for `shl foo` and `shr foo` where `foo` is a byte storage.
* Support for `I a, btable + x` where `I` is `add`, `sub`, `cmp`,
`and`, `or`, or `xor`
* Support for `I btable + x` where `I` is `shl`, `shr`, `inc`, `dec`
0.15
----

View File

@ -69,13 +69,8 @@ Documentation
TODO
----
### Save registers on stack
This preserves them, so that, semantically, they can be used later even though they
are trashed inside the block.
### And at some point...
* Save registers on stack: this preserves them, so that, semantically, they can be used later even though they
are trashed inside the block.
* `low` and `high` address operators - to turn `word` type into `byte`.
* Related: can we simply view a (small) part of a buffer as a byte table? If not, why not?
* Related: add constant to buffer to get new buffer. (Or to table, but... well, maybe.)
@ -84,7 +79,6 @@ are trashed inside the block.
* `static` pointers -- currently not possible because pointers must be zero-page, thus `@`, thus uninitialized.
* Question the value of the "consistent initialization" principle for `if` statement analysis.
* `interrupt` routines -- to indicate that "the supervisor" has stored values on the stack, so we can trash them.
* Add absolute-indexed for add, sub, and, or, xor, shl, shr
* Automatic tail-call optimization (could be tricky, w/constraints?)
[VICE]: http://vice-emu.sourceforge.net/

View File

@ -244,6 +244,8 @@ class Compiler(object):
if dest == REG_A:
if isinstance(src, ConstantRef):
self.emitter.emit(ADC(Immediate(Byte(src.value))))
elif isinstance(src, IndexedRef):
self.emitter.emit(ADC(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
else:
self.emitter.emit(ADC(Absolute(self.get_label(src.name))))
elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
@ -292,6 +294,8 @@ class Compiler(object):
if dest == REG_A:
if isinstance(src, ConstantRef):
self.emitter.emit(SBC(Immediate(Byte(src.value))))
elif isinstance(src, IndexedRef):
self.emitter.emit(SBC(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
else:
self.emitter.emit(SBC(Absolute(self.get_label(src.name))))
elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
@ -316,10 +320,6 @@ class Compiler(object):
raise UnsupportedOpcodeError(instr)
else:
raise UnsupportedOpcodeError(instr)
elif opcode == 'inc':
self.compile_inc(instr, instr.dest)
elif opcode == 'dec':
self.compile_dec(instr, instr.dest)
elif opcode == 'cmp':
self.compile_cmp(instr, instr.src, instr.dest)
elif opcode in ('and', 'or', 'xor',):
@ -331,10 +331,16 @@ class Compiler(object):
if dest == REG_A:
if isinstance(src, ConstantRef):
self.emitter.emit(cls(Immediate(Byte(src.value))))
elif isinstance(src, IndexedRef):
self.emitter.emit(cls(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
else:
self.emitter.emit(cls(self.absolute_or_zero_page(self.get_label(src.name))))
else:
raise UnsupportedOpcodeError(instr)
elif opcode == 'inc':
self.compile_inc(instr, instr.dest)
elif opcode == 'dec':
self.compile_dec(instr, instr.dest)
elif opcode in ('shl', 'shr'):
cls = {
'shl': ROL,
@ -342,6 +348,8 @@ class Compiler(object):
}[opcode]
if dest == REG_A:
self.emitter.emit(cls())
elif isinstance(dest, IndexedRef):
self.emitter.emit(cls(self.addressing_mode_for_index(dest.index)(self.get_label(dest.ref.name))))
else:
self.emitter.emit(cls(self.absolute_or_zero_page(self.get_label(dest.name))))
elif opcode == 'call':
@ -389,6 +397,9 @@ class Compiler(object):
raise UnsupportedOpcodeError(instr)
if isinstance(src, ConstantRef):
self.emitter.emit(cls(Immediate(Byte(src.value))))
elif isinstance(src, IndexedRef):
# FIXME might not work for some dest's (that is, cls's)
self.emitter.emit(cls(self.addressing_mode_for_index(src.index)(self.get_label(src.ref.name))))
else:
self.emitter.emit(cls(Absolute(self.get_label(src.name))))
@ -398,6 +409,8 @@ class Compiler(object):
self.emitter.emit(INX())
elif dest == REG_Y:
self.emitter.emit(INY())
elif isinstance(dest, IndexedRef):
self.emitter.emit(INC(self.addressing_mode_for_index(dest.index)(self.get_label(dest.ref.name))))
else:
self.emitter.emit(INC(Absolute(self.get_label(dest.name))))
@ -407,6 +420,8 @@ class Compiler(object):
self.emitter.emit(DEX())
elif dest == REG_Y:
self.emitter.emit(DEY())
elif isinstance(dest, IndexedRef):
self.emitter.emit(DEC(self.addressing_mode_for_index(dest.index)(self.get_label(dest.ref.name))))
else:
self.emitter.emit(DEC(Absolute(self.get_label(dest.name))))

View File

@ -211,6 +211,7 @@ class CPY(Instruction):
class DEC(Instruction):
opcodes = {
Absolute: 0xce,
AbsoluteX: 0xde,
}

View File

@ -220,6 +220,8 @@ Initialized byte table, initialized with list of byte values.
Initialized word table, initialized with list of word values.
FIXME wait, is this not a word table[4]?
| word table[8] message : 65535, 0, 127
|
| routine main
@ -313,6 +315,78 @@ Some instructions.
= $0855 ROR $0859
= $0858 RTS
Some instructions on tables. (1/3)
| byte table[256] many
|
| routine main
| inputs many
| outputs many
| trashes a, x, c, n, z, v
| {
| ld x, 0
| ld a, 0
| st off, c
| add a, many + x
| sub a, many + x
| cmp a, many + x
| }
= $080D LDX #$00
= $080F LDA #$00
= $0811 CLC
= $0812 ADC $081C,X
= $0815 SBC $081C,X
= $0818 CMP $081C,X
= $081B RTS
Some instructions on tables. (2/3)
| byte table[256] many
|
| routine main
| inputs many
| outputs many
| trashes a, x, c, n, z
| {
| ld x, 0
| ld a, 0
| and a, many + x
| or a, many + x
| xor a, many + x
| }
= $080D LDX #$00
= $080F LDA #$00
= $0811 AND $081B,X
= $0814 ORA $081B,X
= $0817 EOR $081B,X
= $081A RTS
Some instructions on tables. (3/3)
| byte table[256] many
|
| routine main
| inputs many
| outputs many
| trashes a, x, c, n, z
| {
| ld x, 0
| ld a, 0
| st off, c
| shl many + x
| shr many + x
| inc many + x
| dec many + x
| }
= $080D LDX #$00
= $080F LDA #$00
= $0811 CLC
= $0812 ROL $081F,X
= $0815 ROR $081F,X
= $0818 INC $081F,X
= $081B DEC $081F,X
= $081E RTS
Compiling `if`.
| routine main
@ -525,7 +599,7 @@ Indexed access.
= $0814 LDA $0819,X
= $0817 RTS
Byte tables take up 256 bytes in memory.
Byte tables take up, at most, 256 bytes in memory.
| byte table[256] tab1
| byte table[256] tab2