From e41dd1aa0198e0aeaa495d710937e70b191d605e Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Fri, 24 Nov 2017 13:09:10 +0000 Subject: [PATCH] Attempt to add Zero Page addressing; the emitter may need rethink. --- README.markdown | 11 ++++++++--- src/sixtypical/compiler.py | 11 +++++++++-- src/sixtypical/emitter.py | 4 ++++ src/sixtypical/gen6502.py | 16 +++++++++++++++- tests/SixtyPical Compilation.md | 16 ++++++++++++++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 60d8a55..b38da83 100644 --- a/README.markdown +++ b/README.markdown @@ -49,13 +49,18 @@ A `pointer` is implemented as a zero-page memory location, and accessing the buffer pointed to is implemented with "indirect indexed" addressing, as in LDA ($02), Y + STA ($02), Y We will likely have a new mode of `copy` for this, like - copy 100, [ptr] + y + copy ^buf, ptr // this is the only way to initialize a pointer + add ptr, 4 // ok, but only if it does not exceed buffer's size + ld y, 0 // you must set this to something yourself + copy [ptr] + y, byt // read memory through pointer, into byte + copy 100, [ptr] + y // write memory through pointer (still trashes a) -where `ptr` is a user-defined storage location of `pointer` type, and `+ y` -is mandatory (and you can/should set it to zero yourself if you want.) +where `ptr` is a user-defined storage location of `pointer` type, and the +`+ y` part is mandatory. This instruction will likely be unchecked, at least to start. Basically, this is to allow us to write to the `byte buffer[2048]` known as "the screen", diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 049504e..6f58e90 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -8,7 +8,7 @@ from sixtypical.model import ( ) from sixtypical.emitter import Byte, Label, Offset, LowAddressByte, HighAddressByte from sixtypical.gen6502 import ( - Immediate, Absolute, AbsoluteX, AbsoluteY, Indirect, IndirectY, Relative, + Immediate, Absolute, AbsoluteX, AbsoluteY, ZeroPage, Indirect, IndirectY, Relative, LDA, LDX, LDY, STA, STX, STY, TAX, TAY, TXA, TYA, CLC, SEC, ADC, SBC, ROL, ROR, @@ -299,7 +299,14 @@ class Compiler(object): self.emitter.emit(LDA(Absolute(Offset(src_label, 1)))) self.emitter.emit(STA(Absolute(Offset(dest_label, 1)))) elif isinstance(src.type, BufferType) and isinstance(dest.type, PointerType): - raise NotImplementedError('zeropage') + # TODO: this maybe should not be the 'copy' opcode at all that means this + src_label = self.labels[src.name] + dest_label = self.labels[dest.name] + self.emitter.emit(LDA(Immediate(HighAddressByte(src_label)))) + self.emitter.emit(STA(ZeroPage(dest_label))) + self.emitter.emit(LDA(Immediate(LowAddressByte(src_label)))) + #self.emitter.emit(STA(ZeroPage(Offset(dest_label, 1)))) + self.emitter.emit(STA(ZeroPage(dest_label))) elif isinstance(src.type, VectorType) and isinstance(dest.type, VectorType): src_label = self.labels[src.name] dest_label = self.labels[dest.name] diff --git a/src/sixtypical/emitter.py b/src/sixtypical/emitter.py index 5ae2225..651d15e 100644 --- a/src/sixtypical/emitter.py +++ b/src/sixtypical/emitter.py @@ -61,6 +61,10 @@ class Label(Emittable): assert self.addr is not None, "unresolved label: %s" % self.name return Byte(self.addr - (addr + 2)).serialize() + def serialize_as_zero_page(self, offset=0): + assert self.addr is not None, "unresolved label: %s" % self.name + return Byte(self.addr + offset).serialize() + def __repr__(self): addrs = ', addr=%r' % self.addr if self.addr is not None else '' return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs) diff --git a/src/sixtypical/gen6502.py b/src/sixtypical/gen6502.py index cad4be0..b72471e 100644 --- a/src/sixtypical/gen6502.py +++ b/src/sixtypical/gen6502.py @@ -58,6 +58,18 @@ class AbsoluteY(Absolute): pass +class ZeroPage(AddressingMode): + def __init__(self, value): + assert isinstance(value, (Label, Offset)) + self.value = value + + def size(self): + return 1 + + def serialize(self, addr=None): + return self.value.serialize_as_zero_page() + + class Indirect(AddressingMode): def __init__(self, value): assert isinstance(value, Label) @@ -76,7 +88,7 @@ class IndirectY(AddressingMode): self.value = value def size(self): - return 2 + return 1 def serialize(self, addr=None): return self.value.serialize() @@ -257,6 +269,7 @@ class LDA(Instruction): AbsoluteX: 0xbd, AbsoluteY: 0xb9, IndirectY: 0xb1, + ZeroPage: 0xa5, } @@ -334,6 +347,7 @@ class STA(Instruction): AbsoluteX: 0x9d, AbsoluteY: 0x99, IndirectY: 0x91, + ZeroPage: 0x85, } diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index 2864447..b0e5398 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -341,3 +341,19 @@ goto. | goto bar | } = 00c0a0c84c06c060a2c860 + +Buffers and pointers. + + > | buffer[2048] buf + > | pointer ptr : 254 + > | + > | routine main + > | inputs buf + > | outputs buf, y + > | trashes a, z, n, ptr + > | { + > | ld y, 0 + > | copy buf, ptr + > | // copy 123, [ptr] + y + > | } + > = 00c0a000a90b850dc0a9c0850ec060