Pythonで書かれたSHマイコンのフラッシュライターに合わせて、DisktoolもPythonで開発しました。
また、Pythonのツールにより、このスクリプトは単一の実行ファイルに変換できますので、簡単に再配布可能といなっています。
import sys
from sys import exit
import os
from os.path import expanduser
import glob
import tkinter as tk
from tkinter import ttk
import tkinter.filedialog
from tkinter import filedialog
def loadfile(mot):
listbox.delete(0, tk.END)
motfile = path + '/' + combobox.get() + '/' + mot + '.mot'
home = expanduser("~")
fld = filedialog.askdirectory(initialdir = home)
if len(fld) > 0:
diskfile = fld + '.mot'
files = os.listdir(fld)
addr = readAddress(motfile)
if addr == 0:
status.set('Ignore system file')
return
writeSystem(diskfile, motfile)
for f in files:
fpath = os.path.join(fld, f)
if os.path.isfile(fpath):
listbox.insert(tkinter.END, f)
addr = writeApp(diskfile, fpath, addr)
s = 'S214' + format(addr, '06X')
for i in range(16):
s = s + "FF"
fw = open(diskfile, 'a')
fw.write(makeCheckSum(s) + '\n')
fw.close()
status.set(os.path.basename(diskfile) + ' is generated.')
def writeApp(diskfile, appfile, address):
offset = address
filename = os.path.basename(appfile)
namesize = len(filename)
filesize = os.path.getsize(appfile)
s = 'S2{0:02X}{1:06X}'.format(namesize + 5, offset)
for i in range(len(filename)):
code = ord(filename[i])
s = s + format(code, '02X')
s1 = s + '00'
offset = offset + len(filename) + 1
s = 'S208{0:06X}'.format(offset)
s = s + format(filesize % 0x100, '02X')
s = s + format((filesize % 0x10000) // 0x100, '02X')
s = s + format((filesize % 0x1000000) // 0x10000, '02X')
s = s + format(filesize // 0x1000000, '02X')
s2 = s;
offset = offset + 4;
fr = open(appfile, 'rb')
fw = open(diskfile, 'a')
fw.write(makeCheckSum(s1) + '\n')
fw.write(makeCheckSum(s2) + '\n')
count = 0
while True:
ch = fr.read(1)
if len(ch) == 0:
break
if count > 15:
s = 'S214' + s
fw.write(makeCheckSum(s) + '\n')
count = 0
if count == 0:
s = format(offset, '06X')
code = ord(ch)
s = s + format(code, '02X')
offset = offset + 1
count = count + 1
s = 'S2' + format(count + 4, '02X') + s
fw.write(makeCheckSum(s) + '\n')
fw.close()
fr.close()
return offset
def makeCheckSum(srec):
chksum = 0
for i in range(2, len(srec), 2):
code = int(srec[i : i + 2], 16)
chksum = chksum + code
chksum = ~chksum
b = chksum % 256
return srec + format(b, '02X')
def select_load():
loadfile('mes2')
def select_core():
loadfile('core')
def click_load(event):
root.after(1, select_load)
def click_core(event):
root.after(1, select_core)
def select_quit(event):
exit()
def select_combo(event):
inifile = path + '/disktool.ini'
fw = open(inifile, 'w')
fw.write('Select:' + combobox.get() + '\n')
fw.close()
def writeSystem(diskfile, mesfile):
with open(mesfile, mode='r') as fi, open(diskfile, mode='w') as fw:
for line in fi:
fw.write(line)
def readAddress(mesfile):
data = '';
s1 = ''
s2 = ''
s3 = ''
count = 64;
offset = 0;
addr = 0;
leng = 16;
index = 0;
with open(mesfile, mode='r') as f:
for line in f:
line = line.strip()
if line[0:2] == 'S1':
leng = int(line[2:4], 16) - 3
addr = int(line[4:8], 16)
s1 = line[8:8 + leng * 2]
elif line[0:2] == 'S2':
leng = int(line[2:4], 16) - 4
addr = int(line[4:10], 16)
s1 = line[10:10 + leng * 2]
elif line[0:2] == 'S3':
leng = int(line[2:4], 16) - 5
addr = int(line[4:12], 16)
s1 = line[12:12 + leng * 2]
else:
continue
if offset != 0 and (offset + leng) != addr:
break
data = data + s1
for i in range(leng - 3):
s2 = data[index * 2 : index * 2 + 8]
if s2 == '12345678':
s3 = data[index * 2 - 6 : index * 2]
return int(s3, 16)
if s2 == '78563412':
s3 = data[index * 2 - 4 : index * 2 - 2]
s3 = s3 + data[index * 2 - 6 : index * 2 - 4]
s3 = s3 + data[index * 2 - 8 : index * 2 - 6]
return int(s3, 16)
index = index + 1
offset = addr
return 0
path = os.path.dirname(sys.executable)
#path = '.'
files = os.listdir(path)
motlist = []
for f in files:
motpath = os.path.join(path, f)
if os.path.isdir(motpath):
is_file1 = os.path.isfile(motpath + '/mes2.mot')
is_file2 = os.path.isfile(motpath + '/core.mot')
if is_file1 and is_file2:
motlist.append(f)
if len(motlist) == 0:
exit()
root = tk.Tk()
root.title('Disktool')
root.geometry('170x300')
canvas1 = tk.Canvas(root, height = 0)
canvas1.pack(fill = tk.X, side='top')
load = tk.Button(root, text='Load')
load.bind('<ButtonPress>', click_load)
load.pack(in_=canvas1, side='left')
core = tk.Button(root, text='Core')
core.bind('<ButtonPress>', click_core)
core.pack(in_=canvas1, side='left')
quit = tk.Button(root, text='Quit')
quit.bind('<ButtonPress>', select_quit)
quit.pack(in_=canvas1, side='left')
style = ttk.Style()
style.configure("office.TCombobox", padding=2)
v = tk.StringVar()
combobox = ttk.Combobox(root, textvariable=v, values=motlist, width=12, style="office.TCombobox")
combobox.bind('<<ComboboxSelected>>', select_combo)
combobox.pack(fill = tk.X, side = 'top')
combobox.set(motlist[0])
inifile = path + '/disktool.ini'
is_file = os.path.isfile(inifile)
if is_file:
with open(inifile, mode='r') as f:
for line in f:
line = line.strip()
lines = line.split(':')
if lines[0] == 'Select':
combobox.set(lines[1])
listbox = tk.Listbox(root)
listbox.pack(expand = True, fill = tk.Y)
status = tk.StringVar()
status.set('')
label = tk.Label(root, textvariable=status)
label.pack(side='bottom')
root.mainloop()