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

Tired: copy [ptr]+y, a. Wired: ld a, [ptr]+y.

This commit is contained in:
Chris Pressey 2018-02-08 11:58:24 +00:00
parent 34daad0e56
commit f92e1f15bf
6 changed files with 40 additions and 24 deletions

View File

@ -1,6 +1,12 @@
History of SixtyPical
=====================
0.12
----
* `copy` is now understood to trash `a`, thus `copy ..., a` is not valid.
Indirect addressing is supported in `ld`, as in `ld a, [ptr] + y`, to compensate.
0.11
----

View File

@ -148,7 +148,7 @@ buffer pointed to is implemented with "indirect indexed" addressing, as in
LDA ($02), Y
STA ($02), Y
There are extended modes of `copy` for using these types of memory location.
There are extended instruction modes for using these types of memory location.
See `copy` below, but here is some illustrative example code:
copy ^buf, ptr // this is the only way to initialize a pointer
@ -238,6 +238,18 @@ If and only if src is a byte table, the index-memory-location must be given.
Some combinations, such as `ld x, y`, are illegal because they do not map to
underlying opcodes.
There is another mode of `ld` which reads into `a` indirectly through a pointer.
copy [<src-memory-location>] + y, <dest-memory-location>
The memory location in this syntax must be a pointer.
This syntax copies the contents of memory at the pointer (offset by the `y`
register) into a register (which must be the `a` register.)
In addition to the constraints above, `y` must be initialized before
this mode is used.
### st ###
st <src-memory-location>, <dest-memory-location> [+ <index-memory-location>]

View File

@ -284,7 +284,7 @@ define player_logic logic_routine
ld y, 0
// check collision.
copy [ptr] + y, a
ld a, [ptr] + y
// if "collision" is with your own self, treat it as if it's blank space!
cmp a, 81
if z {
@ -337,7 +337,7 @@ define enemy_logic logic_routine
ld y, 0
// check collision.
copy [ptr] + y, a
ld a, [ptr] + y
// if "collision" is with your own self, treat it as if it's blank space!
cmp a, 82
if z {

View File

@ -246,14 +246,20 @@ class Analyzer(object):
raise TypeMismatchError('%s and %s in %s' %
(src.ref.name, dest.name, self.current_routine.name)
)
context.assert_meaningful(src.index)
context.assert_meaningful(src, src.index)
elif isinstance(src, IndirectRef):
raise NotImplementedError
# copying this analysis from the matching branch in `copy`, below
if isinstance(src.ref.type, PointerType) and dest.type == TYPE_BYTE:
pass
else:
raise TypeMismatchError((src, dest))
context.assert_meaningful(src.ref, REG_Y)
elif src.type != dest.type:
raise TypeMismatchError('%s and %s in %s' %
(src.name, dest.name, self.current_routine.name)
)
context.assert_meaningful(src)
else:
context.assert_meaningful(src)
context.set_written(dest, FLAG_Z, FLAG_N)
elif opcode == 'st':
if instr.index:
@ -419,7 +425,6 @@ class Analyzer(object):
context.set_written(dest.ref)
elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef):
context.assert_meaningful(src.ref, REG_Y)
# TODO this will need to be more sophisticated. the thing ref points to is touched, as well.
context.set_written(dest)
elif isinstance(src, LocationRef) and isinstance(dest, IndexedRef):
context.assert_meaningful(src, dest.ref, dest.index)
@ -436,15 +441,7 @@ class Analyzer(object):
context.set_written(dest)
context.set_touched(REG_A, FLAG_Z, FLAG_N)
context.set_unmeaningful(FLAG_Z, FLAG_N)
# FIXME: this is just to support "copy [foo] + y, a". consider disallowing `a` as something
# that can be used in `copy`. should be using `st` or `ld` instead, probably.
if dest == REG_A:
context.set_touched(REG_A)
context.set_written(REG_A)
else:
context.set_unmeaningful(REG_A)
context.set_unmeaningful(REG_A, FLAG_Z, FLAG_N)
elif opcode == 'with-sei':
self.analyze_block(instr.block, context)

View File

@ -135,6 +135,10 @@ class Compiler(object):
self.emitter.emit(LDA(AbsoluteX(self.labels[src.name])))
elif isinstance(src, IndexedRef) and src.index == REG_Y:
self.emitter.emit(LDA(AbsoluteY(self.labels[src.name])))
elif isinstance(src, IndirectRef) and isinstance(src.ref.type, PointerType):
self.emitter.emit(LDA(IndirectY(self.labels[src.ref.name])))
elif isinstance(src, IndirectRef) and src.index == REG_Y:
self.emitter.emit(LDA(AbsoluteY(self.labels[src.name])))
else:
self.emitter.emit(LDA(Absolute(self.labels[src.name])))
elif dest == REG_X:
@ -385,10 +389,7 @@ class Compiler(object):
else:
raise NotImplementedError((src, dest))
elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef):
if dest == REG_A and isinstance(src.ref.type, PointerType):
src_label = self.labels[src.ref.name]
self.emitter.emit(LDA(IndirectY(src_label)))
elif dest.type == TYPE_BYTE and isinstance(src.ref.type, PointerType):
if dest.type == TYPE_BYTE and isinstance(src.ref.type, PointerType):
src_label = self.labels[src.ref.name]
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(IndirectY(src_label)))

View File

@ -1601,8 +1601,8 @@ Read through a pointer.
| }
= ok
Read through a pointer to the `a` register. Note that
this is done with `ld`, not `copy`.
Read through a pointer to the `a` register. Note that this is done with `ld`,
not `copy`.
| buffer[2048] buf
| pointer ptr
@ -1610,8 +1610,8 @@ this is done with `ld`, not `copy`.
|
| routine main
| inputs buf
| outputs foo
| trashes a, y, z, n, ptr
| outputs a
| trashes y, z, n, ptr
| {
| ld y, 0
| copy ^buf, ptr