easier68k.core.util package¶
Submodules¶
easier68k.core.util.conversions module¶
easier68k.core.util.find_module module¶
easier68k.core.util.input module¶
easier68k.core.util.opcode_util module¶
-
easier68k.core.util.opcode_util.
check_valid_command
(command: str, template: str, can_take_size=True, valid_sizes=[<OpSize.LONG: 4>, <OpSize.WORD: 2>, <OpSize.BYTE: 1>]) → bool[source]¶ Checks whether this command is valid
>>> check_valid_command("MOVE.B", "MOVE") True
>>> check_valid_command("MOVE", "MOVE") True
>>> check_valid_command("MOV", "MOVE") False
>>> check_valid_command("LEA", "LEA", can_take_size=False) True
>>> check_valid_command("LEA.B", "LEA", can_take_size=False) False
>>> check_valid_command("MOVEA.W", "MOVEA", valid_sizes=[OpSize.WORD, OpSize.LONG]) True
>>> check_valid_command("MOVEA.B", "MOVEA", valid_sizes=[OpSize.WORD, OpSize.LONG]) False
Parameters: - command – The command to check
- template – The type of command we’re checking for (like ‘MOVE’, ‘LEA’, etc.)
- can_take_size – Whether this command takes a size argument or not
Returns: Whether this command is valid or not
-
easier68k.core.util.opcode_util.
command_matches
(command: str, template: str) → bool[source]¶ >>> command_matches("MOVE.B", "MOVE") True
>>> command_matches("MOVE", "MOVE") True
>>> command_matches("MOV", "MOVE") False
>>> command_matches("MOV.B", "MOVE") False
Handles the typical checking of a command string (like ‘MOVE.B’, ‘LEA’, etc.). NOTE: this will match some error conditions, this just does the broadest possible checks. The main one is that this doesn’t check for more than 1 period (MOVE.B.W, for example) or check for valid sizes/lack of sizes. The assumption is that this will be handled in the actual parsing methods for proper error handling. :param command: The command string to parse :param template: The template to check with :return: Whether the command matches
-
easier68k.core.util.opcode_util.
ea_to_binary_post_op
(ea: easier68k.core.enum.ea_mode.EAMode, size: easier68k.core.enum.op_size.OpSize) → easier68k.core.models.memory_value.MemoryValue[source]¶ Gets the binary (if any) of an EA Mode to append after the command itself. For example, if we were to do ‘MOVE.B #$42, D0’, the immediate would need to be appended after the command: this returns the part that needs to be appended.
>>> str(ea_to_binary_post_op(parse_assembly_parameter('#$42'), OpSize.BYTE)) 'WORD MemoryValue 0x42'
>>> str(ea_to_binary_post_op(parse_assembly_parameter('D0'), OpSize.WORD)) 'None'
>>> str(ea_to_binary_post_op(parse_assembly_parameter('#$42'), OpSize.LONG)) 'LONG MemoryValue 0x42'
>>> str(ea_to_binary_post_op(parse_assembly_parameter('($242).W'), OpSize.WORD)) 'WORD MemoryValue 0x242'
>>> str(ea_to_binary_post_op(parse_assembly_parameter('($242).L'), OpSize.LONG)) 'LONG MemoryValue 0x242'
>>> str(ea_to_binary_post_op(parse_assembly_parameter('#-1'), OpSize.BYTE)) 'WORD MemoryValue 0xffff'
>>> str(ea_to_binary_post_op(parse_assembly_parameter('#-113442343'), OpSize.LONG)) 'LONG MemoryValue 0xf93d01d9'
Parameters: - ea – The effective address that needs to be converted
- size – The size of the operation
Returns: The binary that needs to be appended, in string form (or an empty string)
-
easier68k.core.util.opcode_util.
get_size
(command: str, default_size=<OpSize.WORD: 2>) → easier68k.core.enum.op_size.OpSize[source]¶ Gets the size of a command, or supplies the default size
>>> get_size("MOVE.B") <OpSize.BYTE: 1>
>>> get_size("MOVE") <OpSize.WORD: 2>
>>> get_size("MOVE", default_size=OpSize.BYTE) <OpSize.BYTE: 1>
Parameters: - command – The command string to parse
- default_size – The default size if no size is found
Returns: The size of the command
-
easier68k.core.util.opcode_util.
n_param_from_str
(command: str, parameters: str, opcode_cls, n: int = 2, default_size: easier68k.core.enum.op_size.OpSize = <OpSize.WORD: 2>)[source]¶ Parses a command from text. Note that this assumes that is_valid has already been run and was successful.
Parameters: - command – The command itself (e.g. ‘MOVE.B’, ‘LEA’, etc.)
- parameters – The parameters after the command (such as the source and destination of a move)
- opcode_cls – The class of opcode we’re parsing to
- n – The number of parameters to parse
- default_size – The default size if no size is specified, or None if this is an unsized opcode
Returns: The parsed command
-
easier68k.core.util.opcode_util.
n_param_is_valid
(command: str, parameters: str, opcode: str, n: int = 2, valid_sizes=[<OpSize.LONG: 4>, <OpSize.WORD: 2>, <OpSize.BYTE: 1>], default_size=<OpSize.WORD: 2>, param_invalid_modes=[]) -> (<class 'bool'>, <class 'list'>)[source]¶ Tests whether the given command is valid
Parameters: - command – The command itself (e.g. ‘MOVE.B’, ‘LEA’, etc.)
- parameters – The parameters after the command (such as the source and destination of a move)
- opcode – The opcode to check for (‘MOVE’, ‘LEA’, etc.)
- valid_sizes – valid sizes of the command (empty list or None for no size)
- default_size – the default size for the command (can be None if it doesn’t take a command)
- n – the number of parameters to parse
- param_invalid_modes – list of lists of invalid parameter modes (in order)
Returns: Whether the given command is valid and a list of issues/warnings encountered
easier68k.core.util.parsing module¶
-
easier68k.core.util.parsing.
from_str_util
(command: str, parameters: str) -> (<enum 'OpSize'>, <class 'list'>, <class 'list'>)[source]¶ Util method for from_str Splits the command into both parts, gets the normalized size and splits the parameters
>>> from_str_util('MOVE.B', '#123, D0') (<OpSize.BYTE: 1>, ['#123', 'D0'], ['MOVE', 'B'])
>>> from_str_util('FAKEOP', '$AAAA, #123, $AAAA') (<OpSize.WORD: 2>, ['$AAAA', '#123', '$AAAA'], ['FAKEOP'])
>>> from_str_util('NOPARAM.L', '') (<OpSize.LONG: 4>, [''], ['NOPARAM', 'L'])
Parameters: - command – the command str
- parameters – the parameters str
Returns: size {str}, params {list} of str, parts - both sides of the command after split
-
easier68k.core.util.parsing.
get_label
(line: str) → str[source]¶ Returns the label from a line (if it has one, if not returns None)
>>> get_label('test DC.B $0A') 'test'
>>> get_label(';test DC.B $0A') # should return nothing
>>> get_label(' BEQ test') # should return nothing
Parameters: line – The line to get the label from Returns: The label in the line
-
easier68k.core.util.parsing.
get_opcode
(line: str) → str[source]¶ Gets the opcode out of a line (with or without label)
>>> get_opcode('start EQU $400') 'EQU'
>>> get_opcode(' MOVE.B D0, D1') 'MOVE.B'
>>> get_opcode('; start EQU $400') ''
Parameters: line – The line to get the opcode from Returns: The opcode found in said line
-
easier68k.core.util.parsing.
has_label
(line: str) → bool[source]¶ Returns whether or not this line has a label in it (basically if it starts with a space or not) :param line: The line to test :return: Whether the test line has a label in it
>>> has_label('data DC.B $A3') True
>>> has_label(' BEQ test') False
>>> has_label(' TRAP #15') False
>>> has_label(';start EQU $400') False
-
easier68k.core.util.parsing.
parse_assembly_parameter
(addr: str) → easier68k.core.models.assembly_parameter.AssemblyParameter[source]¶ Parses an effective addressing mode (such as D0, (A1), #$01) and makes a new AssemblyParameter
>>> parse_assembly_parameter('D') Traceback (most recent call last): ... AssertionError
>>> str(parse_assembly_parameter('D3')) 'EA Mode: EAMode.DRD, Data: 3'
>>> str(parse_assembly_parameter('A6')) 'EA Mode: EAMode.ARD, Data: 6'
>>> str(parse_assembly_parameter('(A4)')) 'EA Mode: EAMode.ARI, Data: 4'
>>> str(parse_assembly_parameter('(A2)+')) 'EA Mode: EAMode.ARIPI, Data: 2'
>>> str(parse_assembly_parameter('(A2)-')) # Invalid, can't do "post-decrement" Traceback (most recent call last): ... AssertionError
>>> str(parse_assembly_parameter('($45).W')) 'EA Mode: EAMode.AWA, Data: 69'
>>> str(parse_assembly_parameter('(%01010111).L')) 'EA Mode: EAMode.ALA, Data: 87'
>>> str(parse_assembly_parameter('#$FF')) 'EA Mode: EAMode.IMM, Data: 255'
>>> str(parse_assembly_parameter('#$ABCD')) 'EA Mode: EAMode.IMM, Data: 43981'
>>> str(parse_assembly_parameter('#-1')) 'EA Mode: EAMode.IMM, Data: -1'
>>> str(parse_assembly_parameter('#-100')) 'EA Mode: EAMode.IMM, Data: -100'
>>> str(parse_assembly_parameter('-(A2)')) 'EA Mode: EAMode.ARIPD, Data: 2'
-
easier68k.core.util.parsing.
parse_literal
(literal: str) → int[source]¶ Parses a literal (aka “1234” or “$A0F” or “%1001”)
>>> parse_literal('$BA1') 2977
>>> parse_literal('%01010111') 87
>>> parse_literal('57') 57
>>> parse_literal('400') 400
>>> parse_literal('-100') -100
>>> parse_literal('-1') -1
Parameters: literal – A string containing the literal to parse Returns: The parsed literal (a bytearray type)
-
easier68k.core.util.parsing.
strip_comments
(line: str) → str[source]¶ Removes all comments from a line (basically makes this line into the ‘compiler’ version)
>>> strip_comments('label TRAP #15 * This does a thing') 'label TRAP #15 '
>>> strip_comments(' ORG start ;label') ' ORG start '
>>> strip_comments('; ADD D0, D1 * asdf') ''
Parameters: line – The line to strip comments from Returns: The stripped line
-
easier68k.core.util.parsing.
strip_label
(line: str) → str[source]¶ Strips the label from a line, isolating the rest of the line (side effect: also strips comments)
>>> strip_label('ORG start') 'start'
>>> strip_label('RTS ;comm') ''
>>> strip_label(';all commented') ''
>>> strip_label('MOVE D0, D1 * Moves D0 into D1') 'D0, D1 '
Parameters: line – The line to strip the label from Returns: The stripped line
-
easier68k.core.util.parsing.
strip_opcode
(line: str) → str[source]¶ Strips the opcode from a line
>>> strip_opcode('start EQU $400') '$400'
>>> strip_opcode(' MOVE.B D0, D1') 'D0, D1'
>>> strip_opcode(' RTS') ''
>>> strip_opcode('start EQU $400 ; comments!') '$400'
Parameters: line – The line to strip the opcode from Returns: The line with the opcode stripped (as well as comments and labels)
easier68k.core.util.split_bits module¶
-
easier68k.core.util.split_bits.
split_bits
(word: int, amounts: list)[source]¶ takes in a word and a list of bit amounts and returns the bits in the word split up. See the doctests for concrete examples
>>> [bin(x) for x in split_bits(0b1001111010000001, [16])] ['0b1001111010000001']
>>> [bin(x) for x in split_bits(0b1001111010000001, [8,8])] ['0b10011110', '0b10000001']
not the whole 16 bits! >>> [bin(x) for x in split_bits(0b1001111010000001, [8])] Traceback (most recent call last): AssertionError: expected to split exactly one word
This is a test splitting MOVE.B (A1),D4 >>> [bin(x) for x in split_bits(0b0001001010000100, [2,2,3,3,3,3])] [‘0b0’, ‘0b1’, ‘0b1’, ‘0b10’, ‘0b0’, ‘0b100’]