Source code for eight_bit_computer.decimal_display

"""
Generate the data for the decimal display rom.
"""

from .language_defs import (
    SEGMENT_TO_BIT, CHARACTER_TO_SEGMENTS, CHAR_INDEX_TO_DIGIT_INDEX,
    DISPLAY_OPTIONS
    )
from .number_utils import number_to_bitstring
from . import bitdef
from .data_structures import RomData


[docs]def gen_display_romdatas(): """ Generate the romdatas that make up the display rom Returns: list(RomData): List of romdatas (unsorted) that make up the display rom. """ romdatas = [] for raw_value in range(256): twos_comp_raw_value = to_2s_compliment(raw_value) # Generate unsigned decimal unsigned_decimal_str = "{number:>4d}".format(number=raw_value) romdatas.extend( assemble_romdata( raw_value, unsigned_decimal_str, DISPLAY_OPTIONS["DECIMAL"], DISPLAY_OPTIONS["UNSIGNED"], ) ) # Generate twos compliment decimal twos_comp_decimal_str = "{number:>4d}".format( number=twos_comp_raw_value ) romdatas.extend( assemble_romdata( raw_value, twos_comp_decimal_str, DISPLAY_OPTIONS["DECIMAL"], DISPLAY_OPTIONS["TWOS_COMP"], ) ) # Generate unsigned hex unsigned_hex_str = "{number:>4X}".format(number=raw_value) romdatas.extend( assemble_romdata( raw_value, unsigned_hex_str, DISPLAY_OPTIONS["HEX"], DISPLAY_OPTIONS["UNSIGNED"], ) ) # Generate twos compliment decimal twos_comp_hex_str = "{number:>4X}".format( number=twos_comp_raw_value ) romdatas.extend( assemble_romdata( raw_value, twos_comp_hex_str, DISPLAY_OPTIONS["HEX"], DISPLAY_OPTIONS["TWOS_COMP"], ) ) return romdatas
[docs]def to_2s_compliment(value): """ Convert an unsigned value to it's 2's compliment equivalent. Args: value (int): The unsigned 8 bit value (0-255) to convert Returns: int: The 2's compliment equivalent. """ if value > 127: return value - 256 else: return value
[docs]def assemble_romdata(raw_value, disp_chars, base_bitdef, binary_mode_bitdef): """ Assemble the romdatas for the given display configuration. Args: raw_value (int): The unsigned 8 bit value to convert to display rom values. disp_chars (string): The display characters that will make up this value on the seven segment displays base_bitdef (str): A bitdef signifying which base the display should be in - hex or decimal. Forms part of the address of the rom. binary_mode_bitdef (str): Whether the raw value should be displayed in unsigned or two's compliment interpreted value. Returns: list(RomData): List of the romdatas that make up this display configuration. """ romdatas = [] for index, character in enumerate(disp_chars): address = bitdef.merge([ value_to_addr_bitdef(raw_value), base_bitdef, binary_mode_bitdef, CHAR_INDEX_TO_DIGIT_INDEX[index] ]) data = character_to_bitdef(character) romdatas.append(RomData(address=address, data=data)) return romdatas
[docs]def value_to_addr_bitdef(value): """ Place the bitdef of the value in the address bitdef. The address bitdef is 15 bits wide but the value is only 8. Pad this to the correct size by forcing the 3 unused bits in the 3 most significate places to be zero and leaving 4 bits for the base and interpretation (unsigned vs 2's compliment) in the next most significant bits. The valye goes in the 8 least significant bits. Args: value (int): Unsigned 8 bit value (0-255) to place in the address bitdef. Returns: str: Address bitdef with value in place. """ addr_bitdef = "000....{value_bitdef}".format( value_bitdef=number_to_bitstring(value) ) return addr_bitdef
[docs]def character_to_bitdef(character): """ Generate a bitdef for the given character. Bitdefs are mapped to correspond to a 5641AH 7 segment display:: A - - - | | F| |B | G | - - - | | E| |C | | - - - D A = 0000 0001 B = 0000 0010 C = 0000 0100 D = 0000 1000 E = 0001 0000 F = 0010 0000 G = 0100 0000 Args: character (str): Character to get the bidef for. Returns: str: Bitdef that represents the segments to illuminate for that character. Raises: ValueError: If the character to convert isn't supported. """ if character not in CHARACTER_TO_SEGMENTS: msg = ( "Cannot convert {input_char} to a bitdef for seven segment " "display. Valid characters are:\n {valid_chars}.".format( input_char=character, valid_chars=", ".join(CHARACTER_TO_SEGMENTS) ) ) raise ValueError(msg) char_bitdef = bitdef.merge( [ SEGMENT_TO_BIT[segment] for segment in CHARACTER_TO_SEGMENTS[character] ] ) char_bitdef = bitdef.fill(char_bitdef, "0") return char_bitdef