mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-01-23 10:30:16 +00:00
Compile byte-table add, sub, cmp, and, or, xor, shl, shr, inc, dec.
This commit is contained in:
parent
5fcbfa1d21
commit
bc91ef1602
@ -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
|
||||
----
|
||||
|
@ -69,13 +69,8 @@ Documentation
|
||||
TODO
|
||||
----
|
||||
|
||||
### Save registers on stack
|
||||
|
||||
This preserves them, so that, semantically, they can be used later even though they
|
||||
* 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...
|
||||
|
||||
* `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/
|
||||
|
@ -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))))
|
||||
|
||||
|
@ -211,6 +211,7 @@ class CPY(Instruction):
|
||||
class DEC(Instruction):
|
||||
opcodes = {
|
||||
Absolute: 0xce,
|
||||
AbsoluteX: 0xde,
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user