1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-02-19 20:30:45 +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, TYPE_BIT, TYPE_ROUTINE, TYPE_VECTOR,
REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C 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 ( from sixtypical.gen6502 import (
Immediate, Absolute, AbsoluteX, AbsoluteY, Relative, Immediate, Absolute, AbsoluteX, AbsoluteY, Relative,
LDA, LDX, LDY, STA, STX, STY, LDA, LDX, LDY, STA, STX, STY,
@ -243,10 +243,12 @@ class Compiler(object):
self.emitter.emit(CLI()) self.emitter.emit(CLI())
elif opcode == 'copy': elif opcode == 'copy':
if src.type in (TYPE_ROUTINE, TYPE_VECTOR) and dest.type == TYPE_VECTOR: if src.type in (TYPE_ROUTINE, TYPE_VECTOR) and dest.type == TYPE_VECTOR:
self.emitter.emit(LDA(Absolute(self.labels[src.name]))) src_label = self.labels[src.name]
self.emitter.emit(STA(Absolute(self.labels[dest.name]))) dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(self.labels[src.name].clone(offset=1)))) self.emitter.emit(LDA(Absolute(src_label)))
self.emitter.emit(STA(Absolute(self.labels[dest.name].clone(offset=1)))) 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: else:
raise NotImplementedError(src.type) raise NotImplementedError(src.type)
else: else:

View File

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

View File

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

View File

@ -224,3 +224,40 @@ Indexed access.
| ld a, many + x | ld a, many + x
| } | }
= 00c0a200a9009d0dc0bd0dc060 = 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