mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-02-12 20:30:27 +00:00
Support copy'ing a word constant to a word location. Joystick eg.
This commit is contained in:
parent
feb5729ab9
commit
22cc7bfc11
@ -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
49
eg/joystick.60p
Normal 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
|
||||
}
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user