Skip to content

Commit

Permalink
Make opcode (actually) abstract (#132)
Browse files Browse the repository at this point in the history
* Make the base opcode class abstract

Makes the base opcode class abstract, and all required methods of the base
opcode.

This requires that all subclasses of opcode implement each of the methods
of the class.

* Add some methods of opcodes that did not implement abstract base methods
  • Loading branch information
Chris-Johnston committed Jan 2, 2019
1 parent 738c9d5 commit ebd866a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
13 changes: 12 additions & 1 deletion easier68k/core/opcodes/cmp.py
Expand Up @@ -294,4 +294,15 @@ def disassemble_instruction(cls, data: bytes) -> Opcode:
dest = AssemblyParameter(EAMode.DRD, register_bin)

# make a new reference of this type
return cls([src, dest], size)
return cls([src, dest], size)

@classmethod
def from_str(self, command: str, parameters: str):
"""
Parses a CMP from text.
:param command: The command itself 'CMP.L' 'CMP', etc.
:param parameters: The parameters after the command
:return: The parsed command
"""
return opcode_util.n_param_from_str(command, parameters, Cmp, 2, OpSize.WORD)
19 changes: 18 additions & 1 deletion easier68k/core/opcodes/cmpi.py
Expand Up @@ -303,4 +303,21 @@ def disassemble_instruction(cls, data: bytes) -> Opcode:
dest = parse_ea_from_binary(ea_mode_binary, ea_reg_bin, size, True, data[words_used * 2:])[0]

# make a new reference of this type
return cls([src, dest], size)
return cls([src, dest], size)

def __str__(self):
return 'CMPI Size {}, Src {}, Dest {}'.format(self.size, self.src, self.dest)

@classmethod
def from_str(self, command: str, parameters: str):
"""
Parses a CMPI from text.
>>> str(Cmpi.from_str('CMPI.B', '#1337, D1'))
'CMPI Size OpSize.BYTE, Src EA Mode: EAMode.IMM, Data: 1337, Dest EA Mode: EAMode.DRD, Data: 1'
:param command: The command itself 'CMPI' 'CMPI.B', etc.
:param parameters: The parameters after the command
:return: The parsed command
"""
return opcode_util.n_param_from_str(command, parameters, Cmpi, 2, OpSize.WORD)
11 changes: 11 additions & 0 deletions easier68k/core/opcodes/dc.py
Expand Up @@ -402,3 +402,14 @@ def from_str(cls, command: str, parameters: str):
params.append(int(hexed[i:i + 2], 16))

return cls(params, size)

@classmethod
def disassemble_instruction(cls, data: bytes) -> Opcode:
"""
Disassembles the instuction into an instance of the DC class
"""
# DC is a directive for the assembler, so it has no representaiton
# as bytes
pass


29 changes: 22 additions & 7 deletions easier68k/core/opcodes/opcode.py
@@ -1,18 +1,27 @@
from ...simulator.m68k import M68K
from abc import ABC, ABCMeta, abstractmethod

class Opcode(metaclass=ABCMeta):
"""
Abstract
The base class for all Opcodes. Each opcode is responsible for a few actions like
assembling instructions into hex,
executing itself in the simulator,
checking if a string matches the syntax of the opcode,
getting the length of this command in memory,
validating if the parameters for a command are valid,
and disassembling the instruction from bytes.
"""

class Opcode:
pass


class Opcode:
@abstractmethod
def assemble(self) -> bytes:
"""
Assembles this opcode into hex to be inserted into memory
:return: The hex version of this opcode
"""
pass

@abstractmethod
def execute(self, simulator: M68K):
"""
Executes this command in a simulator
Expand All @@ -21,10 +30,12 @@ def execute(self, simulator: M68K):
"""
pass

@abstractmethod
def __str__(self):
return "Generic command base"

@classmethod
@abstractmethod
def command_matches(cls, command: str) -> bool:
"""
Checks whether a command string is an instance of this command type
Expand All @@ -34,6 +45,7 @@ def command_matches(cls, command: str) -> bool:
pass

@classmethod
@abstractmethod
def get_word_length(cls, command: str, parameters: str) -> int:
"""
Gets what the end length of this command will be in memory
Expand All @@ -42,8 +54,9 @@ def get_word_length(cls, command: str, parameters: str) -> int:
:return: The length of the bytes in memory in words
"""
pass

@classmethod
@abstractmethod
def is_valid(cls, command: str, parameters: str) -> (bool, list):
"""
Tests whether the given command is valid
Expand All @@ -54,7 +67,8 @@ def is_valid(cls, command: str, parameters: str) -> (bool, list):
"""

@classmethod
def disassemble_instruction(cls, data: bytes) -> Opcode:
@abstractmethod
def disassemble_instruction(cls, data: bytes):
"""
Parses some raw data into an instance of the opcode class
Expand All @@ -66,6 +80,7 @@ def disassemble_instruction(cls, data: bytes) -> Opcode:
pass

@classmethod
@abstractmethod
def from_str(cls, command: str, parameters: str):
"""
Parses a command from text
Expand Down

0 comments on commit ebd866a

Please sign in to comment.