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

Add word (constant or memory loc) to pointer (unchecked for now).

This commit is contained in:
Chris Pressey 2017-12-07 14:14:43 +00:00
parent a4fd0e590b
commit 75cf18d3a2
6 changed files with 87 additions and 9 deletions

View File

@ -5,6 +5,8 @@ History of SixtyPical
---
* Add word (constant or memory location) to word memory location.
* Add word to pointer (unchecked for now).
* Implementation: `--debug` shows some extra info during analysis.
0.8
---

View File

@ -42,8 +42,6 @@ TODO
### Operations on 16 bit values
Add word (constant or memory location) to pointer. (Not necessarily range-checked yet though.)
Compare word (constant or memory location) with memory location or pointer. (Maybe?)
And then write a little demo "game" where you can move a block around the screen with

View File

@ -255,16 +255,22 @@ class Analyzer(object):
context.assert_meaningful(src)
context.set_written(dest)
elif opcode == 'add':
context.assert_meaningful(src, dest, FLAG_C)
if src.type == TYPE_BYTE:
self.assert_type(TYPE_BYTE, src, dest)
context.assert_meaningful(src, dest, FLAG_C)
context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
else:
self.assert_type(TYPE_WORD, src, dest)
context.assert_meaningful(src, dest, FLAG_C)
context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
context.set_touched(REG_A)
context.set_unmeaningful(REG_A)
self.assert_type(TYPE_WORD, src)
if dest.type == TYPE_WORD:
context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
context.set_touched(REG_A)
context.set_unmeaningful(REG_A)
elif isinstance(dest.type, PointerType):
context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
context.set_touched(REG_A)
context.set_unmeaningful(REG_A)
else:
self.assert_type(TYPE_WORD, dest)
elif opcode == 'sub':
self.assert_type(TYPE_BYTE, src, dest)
context.assert_meaningful(src, dest, FLAG_C)

View File

@ -147,7 +147,7 @@ class Compiler(object):
self.emitter.emit(ADC(Immediate(Byte(src.value))))
else:
self.emitter.emit(ADC(Absolute(self.labels[src.name])))
elif isinstance(dest, LocationRef) and dest.type == TYPE_WORD and src.type == TYPE_WORD:
elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
if isinstance(src, ConstantRef):
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(dest_label)))
@ -167,6 +167,26 @@ class Compiler(object):
self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
else:
raise UnsupportedOpcodeError(instr)
elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and isinstance(dest.type, PointerType):
if isinstance(src, ConstantRef):
dest_label = self.labels[dest.name] # this. is. zero-page.
self.emitter.emit(LDA(ZeroPage(dest_label)))
self.emitter.emit(ADC(Immediate(Byte(src.low_byte()))))
self.emitter.emit(STA(ZeroPage(dest_label)))
self.emitter.emit(LDA(ZeroPage(Offset(dest_label, 1))))
self.emitter.emit(ADC(Immediate(Byte(src.high_byte()))))
self.emitter.emit(STA(ZeroPage(Offset(dest_label, 1))))
elif isinstance(src, LocationRef):
src_label = self.labels[src.name]
dest_label = self.labels[dest.name] # this. is. zero-page.
self.emitter.emit(LDA(ZeroPage(dest_label)))
self.emitter.emit(ADC(Absolute(src_label)))
self.emitter.emit(STA(ZeroPage(dest_label)))
self.emitter.emit(LDA(ZeroPage(Offset(dest_label, 1))))
self.emitter.emit(ADC(Absolute(Offset(src_label, 1))))
self.emitter.emit(STA(ZeroPage(Offset(dest_label, 1))))
else:
raise UnsupportedOpcodeError(instr)
else:
raise UnsupportedOpcodeError(instr)
elif opcode == 'sub':

View File

@ -440,6 +440,36 @@ You can `add` a word memory location to another word memory location.
| }
? ForbiddenWriteError: a in main
You can `add` a word memory location, or a constant, to a pointer.
| pointer ptr
| word delta
| routine main
| inputs ptr, delta
| outputs ptr
| trashes a, c, z, v, n
| {
| st off, c
| add ptr, delta
| add ptr, word 1
| }
= ok
`add`ing a word memory location, or a constant, to a pointer, trashes `a`.
| pointer ptr
| word delta
| routine main
| inputs ptr, delta
| outputs ptr
| trashes c, z, v, n
| {
| st off, c
| add ptr, delta
| add ptr, word 1
| }
? ForbiddenWriteError: a in main
### sub ###
Can't `sub` from or to a memory location that isn't initialized.

View File

@ -437,3 +437,25 @@ Read through a pointer.
| copy [ptr] + y, foo
| }
= 00c0a000a91085fea9c085ffb1fe8d12c060
Add a word memory location, and a literal word, to a pointer, and then read through it.
Note that this is *not* range-checked. (Yet.)
| buffer[2048] buf
| pointer ptr @ 254
| byte foo
| word delta
|
| routine main
| inputs buf
| outputs y, foo, delta
| trashes a, z, n, ptr
| {
| copy 619, delta
| ld y, 0
| copy ^buf, ptr
| add ptr, delta
| add ptr, word 1
| copy [ptr] + y, foo
| }
= 00c0a9028d38c0a96b8d39c0a000a93485fea9c085ffa5fe6d38c085fea5ff6d39c085ffa5fe690185fea5ff690085ffb1fe8d36c060