Skip to content

Instantly share code, notes, and snippets.

@tako2
Created January 18, 2023 01:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tako2/084724ff2790009811325fda5da07ac1 to your computer and use it in GitHub Desktop.
Save tako2/084724ff2790009811325fda5da07ac1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from optparse import OptionParser
import sys
import os
#==============================================================================
def put_chunk(f, chunk):
checksum = ((~sum(chunk)) + 1) & 0xff
f.write(b'\x3a')
f.write(chunk)
f.write(bytes([checksum]))
#==============================================================================
def put_header(f, addr):
chunk = addr.to_bytes(2, byteorder='big')
put_chunk(f, chunk)
#==============================================================================
def put_terminator(f):
f.write(b'\x3a\x00\x00')
#==============================================================================
def funckey(text):
key = bytes(text, 'ascii') + b'\x00' * 16
return key[:16]
#==============================================================================
def output_ipl(f, text):
ipl = b'\x01\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
ipl += b'\x00\x01\x01\x79'
ipl += funckey('Hi,')
ipl += funckey('Please')
ipl += funckey('wait a')
ipl += funckey('second')
ipl += b'....'
ipl += bytes(text, 'ascii') + b'\x00'
put_header(f, 0xea68)
put_chunk(f, bytes([len(ipl)]) + ipl)
put_terminator(f)
print('[0xEA68-0x{:X}] IPL'.format(0xea68+len(ipl)-1), '"'+text.replace('\r', ' ')+'"')
#==============================================================================
def output_bin(f, bin_file, addr):
put_header(f, addr)
size = 0;
with open(bin_file, 'rb') as bin_f:
while True:
data = bin_f.read(255)
if len(data) == 0:
break
size += len(data)
put_chunk(f, bytes([len(data)]) + data)
put_terminator(f)
print('[0x{:X}-0x{:X}]'.format(addr, addr+size-1), bin_file)
#==============================================================================
def main(opts, args):
if len(args) < 1:
return False
filelist = []
while len(args) > 0:
file = args[0]
args = args[1:]
if len(args) == 0:
# args error
print('No Address of', file)
return False
addr = args[0]
args = args[1:]
addr = int(addr, 16)
if addr < 0 or addr >= 0x10000:
# address error
print(hex(addr), 'is not between 0x0000 to 0xFFFF;')
return False
filelist.append((file, addr))
# -------------------------------------------------------------------------
print('Create', opts.out_file, '...')
out_f = open(opts.out_file, 'wb')
if not opts.noipl:
if opts.ipl_file is None:
ipl_text = 'L\r' * len(filelist)
ipl_text += 'G' + hex(filelist[0][1])[2:] + '\r' # exec address
else:
ipl_text = '\x02'
with open(opts.ipl_file, 'r') as f:
while True:
line = f.readline()
if not line:
break
ipl_text += line.rstrip() + '\r'
ipl_text += '\r'
output_ipl(out_f, ipl_text)
for fset in filelist:
output_bin(out_f, fset[0], fset[1])
out_f.close()
print('Finished')
return True
#==============================================================================
if __name__ == '__main__':
parser = OptionParser(usage='Usage: %prog ([options]) [.bin file] and [address] ...')
parser.add_option('-o', type='string', dest='out_file', default='a.cmt',
help='output cmt to OUTPUT (default a.cmt)',
metavar='OUTPUT')
parser.add_option('-i', '--ipl', type='string', dest='ipl_file',
default=None, metavar='IPL',
help='load IPL from text file')
parser.add_option('-n', '--noipl',
action='store_true', dest='noipl', default=False,
help='No IPL')
opts, args = parser.parse_args()
if not main(opts, args):
print()
parser.print_help()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment