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

Support copy'ing a word constant to a word location. Joystick eg.

This commit is contained in:
Chris Pressey 2017-11-20 15:18:21 +00:00
parent feb5729ab9
commit 22cc7bfc11
5 changed files with 96 additions and 19 deletions

View File

@ -75,13 +75,13 @@ two hundred and fifty-six byte constants,
and sixty-five thousand five hundred and thirty-six word constants,
0
1
word 0
word 1
...
65535
word 65535
Note that all byte constants serve double duty as word constants in that
context.
Note that if a word constant is between 256 and 65535, the leading `word`
token can be omitted.
### User-defined ###

49
eg/joystick.60p Normal file
View File

@ -0,0 +1,49 @@
word screen @ 1024
byte joy2 @ $dc00
word delta
routine read_stick
inputs joy2
outputs delta
trashes a, x, z, n
{
ld x, joy2
ld a, x
and a, 1 // up
if z {
copy $ffd8, delta // -40
} else {
ld a, x
and a, 2 // down
if z {
copy word 40, delta
} else {
ld a, x
and a, 4 // left
if z {
copy $ffff, delta // -1
} else {
ld a, x
and a, 8 // right
if z {
copy word 1, delta
} else {
copy word 0, delta
}
}
}
}
}
routine main
inputs joy2
outputs delta
trashes a, x, z, n, screen
{
repeat {
call read_stick
copy delta, screen
ld a, 1
} until z
}

View File

@ -119,6 +119,8 @@ class Context(object):
elif isinstance(ref, LocationRef):
if ref not in self._meaningful:
message = '%s in %s' % (ref.name, self.routine.name)
if kwargs.get('message'):
message += ' (%s)' % kwargs['message']
raise exception_class(message)
else:
raise NotImplementedError(ref)
@ -128,6 +130,8 @@ class Context(object):
for ref in refs:
if ref not in self._writeable:
message = '%s in %s' % (ref.name, self.routine.name)
if kwargs.get('message'):
message += ' (%s)' % kwargs['message']
raise exception_class(message)
def set_touched(self, *refs):
@ -270,9 +274,13 @@ class Analyzer(object):
# probably not; if it wasn't meaningful in the first place, it
# doesn't really matter if you modified it or not, coming out.
for ref in context1.each_meaningful():
context2.assert_meaningful(ref, exception_class=InconsistentInitializationError)
context2.assert_meaningful(
ref, exception_class=InconsistentInitializationError, message='initialized in block 1 but not in block 2'
)
for ref in context2.each_meaningful():
context1.assert_meaningful(ref, exception_class=InconsistentInitializationError)
context1.assert_meaningful(
ref, exception_class=InconsistentInitializationError, message='initialized in block 2 but not in block 1'
)
context.set_from(context1)
elif opcode == 'repeat':
# it will always be executed at least once, so analyze it having

View File

@ -276,17 +276,29 @@ class Compiler(object):
self.emitter.emit(CLI())
elif opcode == 'copy':
if src.type == TYPE_BYTE and dest.type == TYPE_BYTE:
src_label = self.labels[src.name]
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(src_label)))
self.emitter.emit(STA(Absolute(dest_label)))
if isinstance(src, ConstantRef):
raise NotImplementedError
else:
src_label = self.labels[src.name]
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(src_label)))
self.emitter.emit(STA(Absolute(dest_label)))
elif src.type == TYPE_WORD and dest.type == TYPE_WORD:
src_label = self.labels[src.name]
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(src_label)))
self.emitter.emit(STA(Absolute(dest_label)))
self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
if isinstance(src, ConstantRef):
dest_label = self.labels[dest.name]
hi = (src.value >> 8) & 255
lo = src.value & 255
self.emitter.emit(LDA(Immediate(Byte(hi))))
self.emitter.emit(STA(Absolute(dest_label)))
self.emitter.emit(LDA(Immediate(Byte(lo))))
self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
else:
src_label = self.labels[src.name]
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(src_label)))
self.emitter.emit(STA(Absolute(dest_label)))
self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
elif isinstance(src.type, VectorType) and isinstance(dest.type, VectorType):
src_label = self.labels[src.name]
dest_label = self.labels[dest.name]

View File

@ -138,7 +138,13 @@ class Parser(object):
self.scanner.scan()
return loc
elif self.scanner.on_type('integer literal'):
loc = ConstantRef(TYPE_BYTE, int(self.scanner.token))
value = int(self.scanner.token)
type_ = TYPE_WORD if value > 255 else TYPE_BYTE
loc = ConstantRef(type_, value)
self.scanner.scan()
return loc
elif self.scanner.consume('word'):
loc = ConstantRef(TYPE_WORD, int(self.scanner.token))
self.scanner.scan()
return loc
else:
@ -219,7 +225,9 @@ class Parser(object):
src = self.locexpr()
self.scanner.expect(',')
dest = self.locexpr()
return Instr(opcode=opcode, dest=dest, src=src)
i = Instr(opcode=opcode, dest=dest, src=src)
#print repr(i)
return i
elif self.scanner.consume("with"):
self.scanner.expect("interrupts")
self.scanner.expect("off")