Source code for easier68k.simulator.memory

"""
Represents all of the memory for the 68k
This should be able to be serialized/deserialized
and accessed completely
"""

from ..core.enum.register import Register
from ..core.enum.condition import Condition
from ..core.enum.condition_status_code import ConditionStatusCode
from ..core.enum.system_status_code import SystemStatusCode
from ..core.models.list_file import ListFile
import typing
from ..core.models.memory_value import MemoryValue
from ..core.enum.op_size import OpSize

[docs]class UnalignedMemoryAccessError(Exception): pass
[docs]class OutOfBoundsMemoryError(Exception): pass
[docs]class AssignWrongMemorySizeError(Exception): pass
[docs]class Memory: def __validateLocation(self, size: OpSize, location: int): """ Helper function which throws an error if the location is either not aligned or out of bounds """ if not isinstance(size, OpSize): size = OpSize(size) if(location % size.get_number_of_bytes() != 0): raise UnalignedMemoryAccessError if(location < 0 or (location + size.get_number_of_bytes()) > len(self.memory)): raise OutOfBoundsMemoryError def __init__(self): """ Constructor """ # all of the memory that is stored by the device # 16777216 = 2^24 # it is the number of bytes easy68K uses. self.memory = bytearray(16777216)
[docs] def save_memory(self, file : typing.BinaryIO): """ saves the raw memory into the designated file NOTE: file must be opened as binary or this won't work """ file.write(self.memory)
[docs] def load_memory(self, file : typing.BinaryIO): """ Loads the raw memory from the designated file This includes programs NOTE: file must be opened as binary or this won't work """ self.memory = bytearray(file.read())
[docs] def load_list_file(self, list_file: ListFile): """ Load List File load the contents of a list file into memory using the locations specified inside of the list file starting location, registers, etc... (anything which is not data) is ignored :param list_file: :return: """ # for all of the locations, load the contents into memory for key, value in list_file.data.items(): # internally stored as a string for json compatibility # so convert back into an integer to represent the index location = int(key) # decode the data into a ByteArray # and then set it values = bytearray.fromhex(value) for i in range(0, len(values), 1): # set one byte at a time val = MemoryValue(OpSize.BYTE, bytes=values[i:i+1]) self.set(OpSize.BYTE, location + i, val)
[docs] def get(self, size: OpSize, location: int) -> MemoryValue: """ gets the memory at the given location index of size """ if not isinstance(size, OpSize): size = OpSize(size) self.__validateLocation(size, location) ret = MemoryValue(size) end = location + size.value b = None try: b = self.memory[location:end] except TypeError: pass ret.set_value_bytes(b) return ret
[docs] def set(self, size: OpSize, location: int, value: MemoryValue): """ sets the memory at the given location index of size """ if not isinstance(value, MemoryValue): raise AssertionError("The value parameter must be of type MemoryValue") if not isinstance(size, OpSize): size = OpSize(size) self.__validateLocation(size, location) if value.get_size() != size: raise AssignWrongMemorySizeError self.memory[location:location+size.get_number_of_bytes()] = value.get_value_bytes()