diff options
Diffstat (limited to 'atk16-utils')
| -rw-r--r-- | atk16-utils/charmem.py | 63 | ||||
| -rw-r--r-- | atk16-utils/convert_ttf.py | 52 | ||||
| -rw-r--r-- | atk16-utils/dig_install.py | 60 | ||||
| -rw-r--r-- | atk16-utils/pad_bin.py | 59 | ||||
| -rwxr-xr-x | atk16-utils/ucode.py | 112 |
5 files changed, 0 insertions, 346 deletions
diff --git a/atk16-utils/charmem.py b/atk16-utils/charmem.py deleted file mode 100644 index aaac122..0000000 --- a/atk16-utils/charmem.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 -# Generate .bin file with ATK16 CPU TPU charmem data - -# Addressed by _CCC CCCC CYYY -# Data width 8bit: ___X XXXX -# where _ = unused, C = 8bit character code, Y = character y coordinate, X = pixel value - -import sys - -if len(sys.argv) != 2: - print("usage: charmem.py <outfile.bin>") - sys.exit(1) - -outfile_path = sys.argv[1] - -with open("charset.txt", "r") as f: - lines = [s.strip("\n") for s in f.readlines()] - -header_chars = lines[0] - -charset: list[list[str]] = [] - -CHAR_HEIGHT = 8 -CHAR_WIDTH = 8 - -i = 0 -while i < len(lines): - i += 1 # skip comment line - char = lines[i:i+CHAR_HEIGHT] - for row in char: - if len(row) != CHAR_WIDTH: - raise Exception(f"char row number {i} has width != {CHAR_WIDTH}: {len(row)}\n" + row + "\n" + "\n".join(char)) - charset.append(char) - i += CHAR_HEIGHT + 1 - -CHAR_N = len(charset) - -TOTAL_BYTEARRAY_SIZE = CHAR_N * CHAR_HEIGHT - -def string_to_byte(input_string: str): - # Replace spaces with '0' and '#' with '1' - binary_string = input_string.replace(' ', '0').replace('█', '1') - - assert(len(input_string) == CHAR_WIDTH) - - # Check if the string contains only '0' or '1' - if not all(c in '01' for c in binary_string): - raise ValueError("Input string must contain only spaces and '█' characters.") - - # Convert the binary string to an unsigned integer byte - return int(binary_string[::-1], 2) - - -res_b = bytearray(TOTAL_BYTEARRAY_SIZE) -for cn, char in enumerate(charset): - for cy in range(0, CHAR_HEIGHT): - addr = (cn << 3) + cy - byte = string_to_byte(char[cy]) - print(f"{byte:>08b}") - res_b[addr] = byte - -with open(outfile_path, "wb") as f: - f.write(res_b) diff --git a/atk16-utils/convert_ttf.py b/atk16-utils/convert_ttf.py deleted file mode 100644 index c1135cb..0000000 --- a/atk16-utils/convert_ttf.py +++ /dev/null @@ -1,52 +0,0 @@ -from PIL import Image, ImageFont, ImageDraw - -import sys - -if len(sys.argv) != 3: - print("usage: convert_ttf.py <infile.ttf> <outfile.txt>") - sys.exit(1) - -# Define the font file and size -font_file = sys.argv[1] -out_file = sys.argv[2] -font_size = 8 # 8x8 pixels - -# Create a font object -font = ImageFont.truetype(font_file, font_size) - - -# backspace 0x8, tab 0x9, newline 0xA, space 0x20 - -# Define the characters to render -#characters = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ' - -def to_char_code(i: int) -> str: - if i == 10: - return " " - return chr(i) - -characters = [to_char_code(i) for i in range(0, 256)] - - -# Open a file to write the bitmaps to -with open(out_file, 'w') as bitmap_file: - for char_idx, char in enumerate(characters): - # Create a new image with a white background - image = Image.new('1', (8, 8), 1) - - # Create a drawing context - draw = ImageDraw.Draw(image) - - # Draw the character - draw.text((0, 0), char, font=font, fill=0) - - # Convert the image to a list of 0's and 1's - pixels = image.getdata() - bitmap = [1 if pixel == 0 else 0 for pixel in pixels] - - # Write the bitmap to the file - bitmap_file.write(f'Character {char_idx}: {char}\n') - for i in range(0, 64, 8): - row = bitmap[i:i+8] - bitmap_file.write(''.join(str(bit) for bit in row) + '\n') - bitmap_file.write('\n') diff --git a/atk16-utils/dig_install.py b/atk16-utils/dig_install.py deleted file mode 100644 index c32229b..0000000 --- a/atk16-utils/dig_install.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python3 -# Install a generated .bin file into a memory chip in a .dig circuit file - -import sys -from typing import cast -import xml.etree.ElementTree as ET - -if len(sys.argv) != 4: - print("usage: dig_install.py <infile.bin> <circuitfile.dig> <chip_label>") - sys.exit(1) - -infile = sys.argv[1] -circuitfile = sys.argv[2] -chip_label = sys.argv[3] - -with open(infile, "rb") as f: - program_bytes = f.read() - -i = 0 -program_words: list[str] = [] -while i < len(program_bytes): - hi_byte = program_bytes[i] - lo_byte = program_bytes[i + 1] - word = f"{hi_byte:>02x}{lo_byte:>02x}" - #print(word) - program_words.append(word) - i += 2 - -program_data = ",".join(program_words) -print("program_data:", program_data) - -tree = ET.parse(circuitfile) -root = tree.getroot() - -# Iterate through each 'visualElement' element -def find_data_element(root: ET.Element) -> ET.Element: - is_correct_visual_element = False - for visual_element in root.findall('.//visualElement'): - element_attributes = visual_element.find('elementAttributes') - if element_attributes is None: continue - - entries = list(element_attributes) - for entry in entries: - strings = entry.findall("string") - is_label_entry = len(strings) == 2 and strings[0].text == "Label" and strings[1].text == chip_label - if is_label_entry and not is_correct_visual_element: - is_correct_visual_element = True - continue - - is_data_entry = len(strings) == 1 and strings[0].text == "Data" - if is_data_entry and is_correct_visual_element: - data_element = entry.findall("data")[0] - return data_element - - raise Exception(f"No data entry matching label {chip_label} found in tree") - -data_element = find_data_element(root) -data_element.text = program_data - -tree.write(circuitfile)
\ No newline at end of file diff --git a/atk16-utils/pad_bin.py b/atk16-utils/pad_bin.py deleted file mode 100644 index 9f014d1..0000000 --- a/atk16-utils/pad_bin.py +++ /dev/null @@ -1,59 +0,0 @@ -import os - -def pad_binary(file_path, target_size) -> int: - """ - Pads a binary file with zeros until it reaches a specified size in KiB. - - :param file_path: Path to the binary file to be padded. - :param target_size: Target size in bytes. - """ - - # Check current file size - current_size = os.path.getsize(file_path) - - # Calculate needed padding - padding_size = target_size - current_size - - # Append zeros if needed - if padding_size > 0: - with open(file_path, 'ab') as file: - file.write(b'\x00' * padding_size) - - return padding_size - -def convert_size_to_bytes(size_str: str) -> int: - """ - Converts a size string with K, M, or G suffix to bytes. - - :param size_str: Size string (e.g., "64K", "1M", "2G"). - :return: Size in bytes. - """ - size_str = size_str.upper() - if size_str.endswith('K'): - return int(size_str[:-1]) * 1024 - elif size_str.endswith('M'): - return int(size_str[:-1]) * 1024 ** 2 - elif size_str.endswith('G'): - return int(size_str[:-1]) * 1024 ** 3 - else: - return int(size_str) - -if __name__ == "__main__": - import argparse - - # Setup argument parser - parser = argparse.ArgumentParser(description='Pad a binary file with zeros until it reaches a specified size.') - parser.add_argument('file', type=str, help='Path to the binary file to be padded.') - parser.add_argument('--to', dest='size', type=str, help='Target size (e.g., 64K, 1M, 2G).', required=True) - - args = parser.parse_args() - - # Convert size argument to bytes - target_size_bytes = convert_size_to_bytes(args.size) - - padded_bytes_n = pad_binary(args.file, target_size_bytes) - - if padded_bytes_n > 0: - print(f"File has been padded with {padded_bytes_n} zeros.") - else: - print("File is already equal to or larger than the target size. No padding added.") diff --git a/atk16-utils/ucode.py b/atk16-utils/ucode.py deleted file mode 100755 index 22a2ce2..0000000 --- a/atk16-utils/ucode.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env python3 -# Generate .bin file with ATK16 CPU microcode - -# Addressed by OOOO BUUU -# where O = opcode, B = branch flag, U = microsequencer value - -import sys - -if len(sys.argv) != 2: - print("usage: ucode.py <outfile.bin>") - sys.exit(1) - -outfile_path = sys.argv[1] - -PC_CO = 1 << 0 -PC_IE = 1 << 1 -PC_OE = 1 << 2 -MAR_IE = 1 << 3 -MEM_IE = 1 << 4 -MEM_OE = 1 << 5 -RW_IE = 1 << 6 -R1_OE = 1 << 7 -R2_OE = 1 << 8 -IR_IE = 1 << 9 -IM_M = 1 << 10 -LI_OE = 1 << 11 -ALU_OE = 1 << 12 -FR_IE = 1 << 13 -HALT = 1 << 14 -US_RS = 1 << 15 -ISRA_OE = 1 << 16 -IM_DS = 1 << 17 -IM_EN = 1 << 18 -IPC_IE = 1 << 19 -IPC_OE = 1 << 20 -NOP5 = 1 << 21 -NOP6 = 1 << 22 -NOP7 = 1 << 23 - -BRANCH_FLAG_STATES_N = 2 -UCODE_N: int = 2**3 -CONTROL_WORD_SIZE = 3 - -def not_branch(bs: list[int]) -> list[list[int]]: - return BRANCH_FLAG_STATES_N * [bs] - -def branch(false_branch: list[int], true_branch: list[int]) -> list[list[int]]: - return [false_branch, true_branch] - -fetch = [PC_OE|MAR_IE, MEM_OE|IR_IE|PC_CO] - -def nop(): - return not_branch([*fetch, US_RS, 0, 0, 0, 0, 0]) - -ucode = [ - # ALR 0000 TTTL LLRR RSSS - not_branch([*fetch, ALU_OE|FR_IE|RW_IE, US_RS, 0, 0, 0, 0]), - # ALI 0001 TTTL LLII ISSS - not_branch([*fetch, IM_M|ALU_OE|FR_IE|RW_IE, US_RS, 0, 0, 0, 0]), - # LDR 0010 TTTR RRXX XXXX - not_branch([*fetch, R1_OE|MAR_IE, MEM_OE|RW_IE, US_RS, 0, 0, 0]), - # STR 0011 XXXL LLRR RXXX - not_branch([*fetch, R1_OE|MAR_IE, R2_OE|MEM_IE, US_RS, 0, 0, 0]), - # LDI 0100 TTTI IIII IIII - not_branch([*fetch, LI_OE|RW_IE, US_RS, 0, 0, 0, 0]), - # JPR 0101 XXXR RRXX XXXX - not_branch([*fetch, R1_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # JPI 0110 XXXI IIII IIII - not_branch([*fetch, IM_M|LI_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # BRR 0111 XFFR RRXX XXXX - branch([*fetch, US_RS, 0, 0, 0, 0, 0], - [*fetch, R1_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # BRI 1000 XFFI IIII IIII - branch([*fetch, US_RS, 0, 0, 0, 0, 0], - [*fetch, IM_M|LI_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # LPC 1001 TTTX XXXX XXXX - not_branch([*fetch, PC_OE|RW_IE, US_RS, 0, 0, 0, 0]), - # NOP 1010 XXXX XXXX XXXX - nop(), - # NOP 1011 XXXX XXXX XXXX - nop(), - # ISRP0 1100 XXXX XXXX XXXX - not_branch([IM_EN|PC_OE|IPC_IE, ISRA_OE|MAR_IE, MEM_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # ISRP1 1101 XXXX XXXX XXXX - not_branch([IM_EN|PC_OE|IPC_IE, ISRA_OE|MAR_IE, MEM_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # RTI 1110 XXXX XXXX XXXX - not_branch([*fetch, IM_DS|IPC_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # HLT 1111 XXXX XXXX XXXX - not_branch([*fetch, HALT, 0, 0, 0, 0, 0]), -] - -INST_N = len(ucode) -TOTAL_BYTEARRAY_SIZE = INST_N * BRANCH_FLAG_STATES_N * UCODE_N * CONTROL_WORD_SIZE - -res_b = bytearray(TOTAL_BYTEARRAY_SIZE) - -for i in range(INST_N): - for j in range(BRANCH_FLAG_STATES_N): - for k in range(UCODE_N): - for l in range(CONTROL_WORD_SIZE): - idx = l + \ - k * CONTROL_WORD_SIZE + \ - j * CONTROL_WORD_SIZE * UCODE_N + \ - i * CONTROL_WORD_SIZE * UCODE_N * BRANCH_FLAG_STATES_N - cword = ucode[i][j][k] - assert len(ucode[i][j]) == 8 - cbyte = (cword >> (8 * (CONTROL_WORD_SIZE - l - 1))) & 0xff - print(f"inst: {i:>04b}, idx: {idx:>04x}, cbyte: {cbyte:>08b}") - res_b[idx] = cbyte - -with open(outfile_path, "wb") as f: - f.write(res_b) |
