initial upload
This commit is contained in:
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
# Convert PDP-8 .bin format files to ILDEC .oct format
|
||||
# Created by Luxferre in 2026, released into the public domain
|
||||
|
||||
import sys
|
||||
|
||||
def print_error(msg):
|
||||
sys.stderr.write(f"Error: {msg}\n")
|
||||
|
||||
def convert_bin_to_oct(input_path, output_path):
|
||||
# Initialize memory to 0
|
||||
memory = [0] * 4096
|
||||
|
||||
try:
|
||||
with open(input_path, "rb") as f:
|
||||
bytes_data = f.read()
|
||||
except Exception as e:
|
||||
print_error(f"Failed to read input file '{input_path}': {e}")
|
||||
return False
|
||||
|
||||
current_address, data_frames = 0, []
|
||||
for b in bytes_data:
|
||||
if b != 0xFF:
|
||||
if b & 0x80 and not (b & 0x40) and len(data_frames) > 1:
|
||||
break
|
||||
if not (b & 0x80):
|
||||
data_frames.append(b)
|
||||
|
||||
if len(data_frames) < 2:
|
||||
print_error("No valid binary data frames found in the input file.")
|
||||
return False
|
||||
|
||||
words_loaded = 0
|
||||
for i in range(0, len(data_frames) - 2, 2):
|
||||
word = ((data_frames[i] & 0x3F) << 6) | (data_frames[i+1] & 0x3F)
|
||||
if data_frames[i] & 0x40:
|
||||
current_address = word
|
||||
else:
|
||||
memory[current_address] = word
|
||||
words_loaded += 1
|
||||
current_address = (current_address + 1) & 0xFFF
|
||||
|
||||
# Output to .oct format
|
||||
try:
|
||||
with open(output_path, 'w') as f:
|
||||
for addr in range(4096):
|
||||
if memory[addr] != 0:
|
||||
f.write(f"{addr:04o}: {memory[addr]:04o}\n")
|
||||
except Exception as e:
|
||||
print_error(f"Failed to write output file: {e}")
|
||||
return False
|
||||
|
||||
print(f"Successfully converted '{input_path}' to '{output_path}' ({words_loaded} words loaded).")
|
||||
return True
|
||||
|
||||
def main():
|
||||
args = sys.argv if hasattr(sys, 'argv') else []
|
||||
if len(args) < 2 or len(args) > 3:
|
||||
print("Usage: python3 bin2oct.py <input_bin_file> [output_oct_file]")
|
||||
sys.exit(1)
|
||||
|
||||
input_path = args[1]
|
||||
if len(args) == 3:
|
||||
output_path = args[2]
|
||||
else:
|
||||
# Generate default output name by replacing extension with .oct
|
||||
dot_idx = input_path.rfind('.')
|
||||
slash_idx = max(input_path.rfind('/'), input_path.rfind('\\'))
|
||||
if dot_idx > slash_idx:
|
||||
output_path = input_path[:dot_idx] + ".oct"
|
||||
else:
|
||||
output_path = input_path + ".oct"
|
||||
|
||||
success = convert_bin_to_oct(input_path, output_path)
|
||||
if not success:
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user