1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-02-16 15:30:26 +00:00

Solve this by defining an Offset emittable.

This commit is contained in:
Chris Pressey 2015-10-19 08:55:47 +01:00
parent e3fe337730
commit 04de73d04d
4 changed files with 76 additions and 21 deletions

View File

@ -6,7 +6,7 @@ from sixtypical.model import (
TYPE_BIT, TYPE_ROUTINE, TYPE_VECTOR,
REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
)
from sixtypical.emitter import Label, Byte
from sixtypical.emitter import Byte, Label, Offset
from sixtypical.gen6502 import (
Immediate, Absolute, AbsoluteX, AbsoluteY, Relative,
LDA, LDX, LDY, STA, STX, STY,
@ -243,10 +243,12 @@ class Compiler(object):
self.emitter.emit(CLI())
elif opcode == 'copy':
if src.type in (TYPE_ROUTINE, TYPE_VECTOR) and dest.type == TYPE_VECTOR:
self.emitter.emit(LDA(Absolute(self.labels[src.name])))
self.emitter.emit(STA(Absolute(self.labels[dest.name])))
self.emitter.emit(LDA(Absolute(self.labels[src.name].clone(offset=1))))
self.emitter.emit(STA(Absolute(self.labels[dest.name].clone(offset=1))))
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))))
else:
raise NotImplementedError(src.type)
else:

View File

@ -17,7 +17,7 @@ class Byte(Emittable):
def size(self):
return 1
def serialize(self, addr):
def serialize(self, addr=None):
return chr(self.value)
def __repr__(self):
@ -32,7 +32,7 @@ class Word(Emittable):
def size(self):
return 2
def serialize(self, addr):
def serialize(self, addr=None):
word = self.value
low = word & 255
high = (word >> 8) & 255
@ -53,19 +53,35 @@ class Label(Emittable):
def size(self):
return 2
def serialize(self, addr):
def serialize(self, addr=None, offset=0):
assert self.addr is not None, "unresolved label: %s" % self.name
return Word(self.addr).serialize(addr)
return Word(self.addr + offset).serialize()
def serialize_relative_to(self, addr):
assert self.addr is not None, "unresolved label: %s" % self.name
return Byte(self.addr - (addr + 2)).serialize(addr)
return Byte(self.addr - (addr + 2)).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)
class Offset(Emittable):
def __init__(self, label, offset):
assert isinstance(label, Label)
self.label = label
self.offset = offset
def size(self):
self.label.size()
def serialize(self, addr=None):
return self.label.serialize(offset=self.offset)
def __repr__(self):
return "%s(%r, %r)" % (self.__class__.__name__, self.label, self.offset)
class Emitter(object):
def __init__(self, addr):
self.accum = []

View File

@ -1,14 +1,14 @@
"""Emittables for 6502 machine code."""
from sixtypical.emitter import Emittable, Byte, Word, Label
from sixtypical.emitter import Emittable, Byte, Word, Label, Offset
class AddressingMode(object):
class AddressingMode(Emittable):
def size(self):
"""Size of the operand for the mode (not including the opcode)"""
raise NotImplementedError
def serialize(self, addr):
def serialize(self, addr=None):
raise NotImplementedError
def __repr__(self):
@ -19,7 +19,7 @@ class Implied(AddressingMode):
def size(self):
return 0
def serialize(self, addr):
def serialize(self, addr=None):
return ''
def __repr__(self):
@ -34,20 +34,20 @@ class Immediate(AddressingMode):
def size(self):
return 1
def serialize(self, addr):
return self.value.serialize(addr)
def serialize(self, addr=None):
return self.value.serialize()
class Absolute(AddressingMode):
def __init__(self, value):
assert isinstance(value, Label)
assert isinstance(value, (Label, Offset))
self.value = value
def size(self):
return 2
def serialize(self, addr):
return self.value.serialize(addr)
def serialize(self, addr=None):
return self.value.serialize()
class AbsoluteX(Absolute):
@ -66,7 +66,7 @@ class Relative(AddressingMode):
def size(self):
return 1
def serialize(self, addr):
def serialize(self, addr=None):
return self.value.serialize_relative_to(addr)
@ -77,7 +77,7 @@ class Opcode(Emittable):
def size(self):
return 1 + self.operand.size() if self.operand else 0
def serialize(self, addr):
def serialize(self, addr=None):
return (
chr(self.opcodes[self.operand.__class__]) +
self.operand.serialize(addr)

View File

@ -224,3 +224,40 @@ Indexed access.
| ld a, many + x
| }
= 00c0a200a9009d0dc0bd0dc060
Copy instruction..
| vector bar
| vector baz
|
| routine main
| inputs baz
| outputs bar
| trashes a, n, z
| {
| copy baz, bar
| }
= 00c0ad0fc08d0dc0ad10c08d0ec060
Copy instruction inside interrupts off block.
| vector bar
|
| routine foo
| inputs x
| outputs x
| trashes z, n
| {
| inc x
| }
|
| routine main
| inputs foo
| outputs bar
| trashes a, n, z
| {
| with interrupts off {
| copy foo, bar
| }
| }
= 00c078ad0fc08d11c0ad10c08d12c05860e860