mirror of
https://github.com/iKarith/cppo-ng.git
synced 2024-06-13 22:29:26 +00:00
Port legacy.py to use the ByteBuffer
We still haven't changed any of how cppo-ng fundamentally works here (aside from fixing things I definitely had broken--and there's some code I still find questionable), but g.image_data is now gone. One g.var down, all the rest still to go.
This commit is contained in:
parent
22b290e3ca
commit
49ba8598cb
277
blocksfree/legacy.py
Executable file → Normal file
277
blocksfree/legacy.py
Executable file → Normal file
|
@ -67,7 +67,6 @@ class Globals:
|
||||||
|
|
||||||
g = Globals()
|
g = Globals()
|
||||||
|
|
||||||
g.image_data = b''
|
|
||||||
g.out_data = bytearray(b'')
|
g.out_data = bytearray(b'')
|
||||||
g.ex_data = None
|
g.ex_data = None
|
||||||
|
|
||||||
|
@ -190,25 +189,25 @@ def getStartPos(arg1, arg2):
|
||||||
+ (39 * ((arg2 + (arg2 > 11)) % 13))
|
+ (39 * ((arg2 + (arg2 > 11)) % 13))
|
||||||
+ (4 if arg2 > 11 else 43) )
|
+ (4 if arg2 > 11 else 43) )
|
||||||
|
|
||||||
def getStorageType(arg1, arg2):
|
def getStorageType(disk, arg1, arg2):
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
firstByte = g.image_data[start]
|
firstByte = disk.buffer.read1(start)
|
||||||
return (int(firstByte != 255)*2 if g.dos33 else (firstByte//16))
|
return (int(firstByte != 255)*2 if g.dos33 else (firstByte//16))
|
||||||
|
|
||||||
def getFileName(arg1, arg2):
|
def getFileName(disk, arg1, arg2):
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
fileNameLo = bytearray()
|
fileNameLo = bytearray()
|
||||||
fileNameHi = g.image_data[sli(start+3, 30)]
|
fileNameHi = disk.buffer.read(start + 3, 30)
|
||||||
for b in fileNameHi:
|
for b in fileNameHi:
|
||||||
fileNameLo.append(b & 0x7f)
|
fileNameLo.append(b & 0x7f)
|
||||||
fileName = bytes(fileNameLo).rstrip()
|
fileName = bytes(fileNameLo).rstrip()
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
firstByte = g.image_data[start]
|
firstByte = disk.buffer.read1(start)
|
||||||
entryType = firstByte//16
|
entryType = firstByte//16
|
||||||
nameLength = firstByte - entryType*16
|
nameLength = firstByte - entryType*16
|
||||||
fileName = g.image_data[sli(start+1, nameLength)]
|
fileName = disk.buffer.read(start + 1, nameLength)
|
||||||
caseMask = getCaseMask(arg1, arg2)
|
caseMask = getCaseMask(disk, arg1, arg2)
|
||||||
if caseMask and not g.casefold_upper:
|
if caseMask and not g.casefold_upper:
|
||||||
fileName = bytearray(fileName)
|
fileName = bytearray(fileName)
|
||||||
for i in range(0, len(fileName)):
|
for i in range(0, len(fileName)):
|
||||||
|
@ -217,20 +216,20 @@ def getFileName(arg1, arg2):
|
||||||
fileName = bytes(fileName)
|
fileName = bytes(fileName)
|
||||||
return fileName
|
return fileName
|
||||||
|
|
||||||
def getCaseMask(arg1, arg2):
|
def getCaseMask(disk, arg1, arg2):
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
caseMaskDec = unpack_u16le(g.image_data, start + 28)
|
caseMaskDec = unpack_u16le(disk.buffer.read(start + 28, 2))
|
||||||
if caseMaskDec < 32768:
|
if caseMaskDec < 32768:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return format(caseMaskDec - 32768, '015b')
|
return format(caseMaskDec - 32768, '015b')
|
||||||
|
|
||||||
def getFileType(arg1, arg2):
|
def getFileType(disk, arg1, arg2):
|
||||||
if g.src_shk:
|
if g.src_shk:
|
||||||
return arg2.split('#')[1][0:2]
|
return arg2.split('#')[1][0:2]
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
d33fileType = g.image_data[start+2]
|
d33fileType = disk.buffer.read1(start + 2)
|
||||||
if (d33fileType & 127) == 4:
|
if (d33fileType & 127) == 4:
|
||||||
return '06' # BIN
|
return '06' # BIN
|
||||||
elif (d33fileType & 127) == 1:
|
elif (d33fileType & 127) == 1:
|
||||||
|
@ -240,22 +239,20 @@ def getFileType(arg1, arg2):
|
||||||
else:
|
else:
|
||||||
return '04' # TXT or other
|
return '04' # TXT or other
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
return b2a_hex(g.image_data[start+16:start+17]).decode()
|
return format(disk.buffer.read1(start + 16), '02x')
|
||||||
|
|
||||||
def getAuxType(arg1, arg2):
|
def getAuxType(disk, arg1, arg2):
|
||||||
if g.src_shk:
|
if g.src_shk:
|
||||||
return arg2.split('#')[1][2:6]
|
return arg2.split('#')[1][2:6]
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
fileType = getFileType(arg1, arg2)
|
fileType = getFileType(disk, arg1, arg2)
|
||||||
if fileType == '06': # BIN (B)
|
if fileType == '06': # BIN (B)
|
||||||
# file address is in first two bytes of file data
|
# file address is in first two bytes of file data
|
||||||
fileTSlist = list(g.image_data[sli(start+0,2)])
|
fileTSlist = list(disk.buffer.read(start, 2))
|
||||||
fileStart = list(g.image_data[sli(ts(fileTSlist)+12,2)])
|
fileStart = list(disk.buffer.read(ts(fileTSlist)+12, 2))
|
||||||
return (
|
file_addr = unpack_u16le(disk.buffer.read(ts(fileStart), 2))
|
||||||
b2a_hex(g.image_data[sli(ts(fileStart)+1,1)]) +
|
return format(file_addr, '04x')
|
||||||
b2a_hex(g.image_data[sli(ts(fileStart),1)])
|
|
||||||
).decode()
|
|
||||||
elif fileType == 'FC': # BAS (A)
|
elif fileType == 'FC': # BAS (A)
|
||||||
return '0801'
|
return '0801'
|
||||||
elif fileType == 'FA': # INT (I)
|
elif fileType == 'FA': # INT (I)
|
||||||
|
@ -263,27 +260,27 @@ def getAuxType(arg1, arg2):
|
||||||
else: # TXT (T) or other
|
else: # TXT (T) or other
|
||||||
return '0000'
|
return '0000'
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
return format(unpack_u16le(g.image_data, start + 31), '04x')
|
return format(unpack_u16le(disk.buffer.read(start + 31, 2)) , '04x')
|
||||||
|
|
||||||
def getKeyPointer(arg1, arg2):
|
def getKeyPointer(disk, arg1, arg2):
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
return list(g.image_data[sli(start,2)])
|
return list(disk.buffer.read(start, 2))
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
return unpack_u16le(g.image_data, start + 17)
|
return unpack_u16le(disk.buffer.read(start + 17, 2))
|
||||||
|
|
||||||
def getFileLength(arg1, arg2):
|
def getFileLength(disk, arg1, arg2):
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
fileType = getFileType(arg1, arg2)
|
fileType = getFileType(disk, arg1, arg2)
|
||||||
fileTSlist = list(g.image_data[sli(start,2)])
|
fileTSlist = list(disk.buffer.read(start, 2))
|
||||||
fileStart = list(g.image_data[sli(ts(fileTSlist)+12,2)])
|
fileStart = list(disk.buffer.read(ts(fileTSlist) + 12, 2))
|
||||||
if fileType == '06': # BIN (B)
|
if fileType == '06': # BIN (B)
|
||||||
# file length is in second two bytes of file data
|
# file length is in second two bytes of file data
|
||||||
file_size = unpack_u16le(g.image_data, ts(fileStart) + 2) + 4
|
file_size = unpack_u16le(disk.buffer.read(ts(fileStart) + 2, 2)) + 4
|
||||||
elif fileType == 'FC' or fileType == 'FA': # BAS (A) or INT (I)
|
elif fileType == 'FC' or fileType == 'FA': # BAS (A) or INT (I)
|
||||||
# file length is in first two bytes of file data
|
# file length is in first two bytes of file data
|
||||||
file_size = unpack_u16le(g.image_data, ts(fileStart)) + 2
|
file_size = unpack_u16le(disk.buffer.read(ts(fileStart), 2)) + 2
|
||||||
else: # TXT (T) or other
|
else: # TXT (T) or other
|
||||||
# sadly, we have to walk the whole file
|
# sadly, we have to walk the whole file
|
||||||
# length is determined by sectors in TSlist, minus wherever
|
# length is determined by sectors in TSlist, minus wherever
|
||||||
|
@ -296,7 +293,7 @@ def getFileLength(arg1, arg2):
|
||||||
while not endFound:
|
while not endFound:
|
||||||
pos = ts(nextTSlistSector)
|
pos = ts(nextTSlistSector)
|
||||||
for tsPos in range(12, 256, 2):
|
for tsPos in range(12, 256, 2):
|
||||||
cur_ts_pair = list(g.image_data[sli(pos+tsPos,2)])
|
cur_ts_pair = list(disk.buffer.read(pos + tsPos, 2))
|
||||||
if ts(cur_ts_pair) != 0:
|
if ts(cur_ts_pair) != 0:
|
||||||
file_size += 256
|
file_size += 256
|
||||||
prevTSpair = cur_ts_pair
|
prevTSpair = cur_ts_pair
|
||||||
|
@ -305,7 +302,7 @@ def getFileLength(arg1, arg2):
|
||||||
endFound = True
|
endFound = True
|
||||||
break
|
break
|
||||||
if not lastTSpair:
|
if not lastTSpair:
|
||||||
nextTSlistSector = list(g.image_data[sli(pos+1,2)])
|
nextTSlistSector = list(disk.buffer.read(pos + 1, 2))
|
||||||
if nextTSlistSector[0]+nextTSlistSector[1] == 0:
|
if nextTSlistSector[0]+nextTSlistSector[1] == 0:
|
||||||
lastTSpair = prevTSpair
|
lastTSpair = prevTSpair
|
||||||
endFound = True
|
endFound = True
|
||||||
|
@ -315,15 +312,15 @@ def getFileLength(arg1, arg2):
|
||||||
# now find out where the file really ends by finding the last 00
|
# now find out where the file really ends by finding the last 00
|
||||||
for offset in range(255, -1, -1):
|
for offset in range(255, -1, -1):
|
||||||
#print("pos: {#b}".format(pos))
|
#print("pos: {#b}".format(pos))
|
||||||
if g.image_data[pos+offset] != 0:
|
if disk.buffer.read1(pos + offset) != 0:
|
||||||
file_size += (offset + 1)
|
file_size += (offset + 1)
|
||||||
break
|
break
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
file_size = unpack_u24le(g.image_data, start + 21)
|
file_size = unpack_u24le(disk.buffer.read(start + 21, 3))
|
||||||
|
|
||||||
return file_size
|
return file_size
|
||||||
|
|
||||||
def getCreationDate(arg1, arg2):
|
def getCreationDate(disk, arg1, arg2):
|
||||||
#outputs prodos creation date/time as Unix time
|
#outputs prodos creation date/time as Unix time
|
||||||
# (seconds since Jan 1 1970 GMT)
|
# (seconds since Jan 1 1970 GMT)
|
||||||
#or None if there is none
|
#or None if there is none
|
||||||
|
@ -333,9 +330,9 @@ def getCreationDate(arg1, arg2):
|
||||||
return None
|
return None
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
return date_prodos_to_unix(g.image_data[start+24:start+28])
|
return date_prodos_to_unix(disk.buffer.read(start + 24, 4))
|
||||||
|
|
||||||
def getModifiedDate(arg1, arg2):
|
def getModifiedDate(disk, arg1, arg2):
|
||||||
#outputs prodos modified date/time as Unix time
|
#outputs prodos modified date/time as Unix time
|
||||||
# (seconds since Jan 1 1970 GMT)
|
# (seconds since Jan 1 1970 GMT)
|
||||||
#or None if there is none
|
#or None if there is none
|
||||||
|
@ -346,20 +343,20 @@ def getModifiedDate(arg1, arg2):
|
||||||
return None
|
return None
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
start = getStartPos(arg1, arg2)
|
start = getStartPos(arg1, arg2)
|
||||||
return date_prodos_to_unix(g.image_data[start+33:start+27])
|
return date_prodos_to_unix(disk.buffer.read(start + 33, 4))
|
||||||
|
|
||||||
def getVolumeName():
|
def getVolumeName(disk):
|
||||||
return getWorkingDirName(2)
|
return getWorkingDirName(disk, 2)
|
||||||
|
|
||||||
def getWorkingDirName(arg1, arg2=None):
|
def getWorkingDirName(disk, arg1, arg2=None):
|
||||||
# arg1:block, arg2:casemask (optional)
|
# arg1:block, arg2:casemask (optional)
|
||||||
start = arg1 * 512
|
start = arg1 * 512
|
||||||
firstByte = g.image_data[start+4]
|
firstByte = disk.buffer.read1(start + 4)
|
||||||
entryType = firstByte//16
|
entryType = firstByte // 16
|
||||||
nameLength = firstByte - entryType*16
|
nameLength = firstByte - entryType * 16
|
||||||
workingDirName = g.image_data[sli(start+5, nameLength)]
|
workingDirName = disk.buffer.read(start + 5, nameLength)
|
||||||
if entryType == 15: # volume directory, get casemask from header
|
if entryType == 15: # volume directory, get casemask from header
|
||||||
caseMaskDec = unpack_u16le(g.image_data, start + 26)
|
caseMaskDec = unpack_u16le(disk.buffer.read(start + 26, 2))
|
||||||
if caseMaskDec < 32768:
|
if caseMaskDec < 32768:
|
||||||
caseMask = None
|
caseMask = None
|
||||||
else:
|
else:
|
||||||
|
@ -374,7 +371,7 @@ def getWorkingDirName(arg1, arg2=None):
|
||||||
workingDirName = bytes(workingDirName)
|
workingDirName = bytes(workingDirName)
|
||||||
return workingDirName
|
return workingDirName
|
||||||
|
|
||||||
def getDirEntryCount(arg1):
|
def getDirEntryCount(disk, arg1):
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
entryCount = 0
|
entryCount = 0
|
||||||
nextSector = arg1
|
nextSector = arg1
|
||||||
|
@ -382,26 +379,26 @@ def getDirEntryCount(arg1):
|
||||||
top = ts(nextSector)
|
top = ts(nextSector)
|
||||||
pos = top+11
|
pos = top+11
|
||||||
for e in range(0, 7):
|
for e in range(0, 7):
|
||||||
if g.image_data[pos] == 0:
|
if disk.buffer.read1(pos) == 0:
|
||||||
return entryCount # no more file entries
|
return entryCount # no more file entries
|
||||||
else:
|
else:
|
||||||
if g.image_data[pos] != 255:
|
if disk.buffer.read1(pos) != 255:
|
||||||
entryCount += 1 # increment if not deleted file
|
entryCount += 1 # increment if not deleted file
|
||||||
pos += 35
|
pos += 35
|
||||||
nextSector = list(g.image_data[sli(top+1,2)])
|
nextSector = list(disk.buffer.read(top + 1, 2))
|
||||||
if nextSector == [0,0]: # no more catalog sectors
|
if nextSector == [0,0]: # no more catalog sectors
|
||||||
return entryCount
|
return entryCount
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
start = arg1 * 512
|
start = arg1 * 512
|
||||||
return unpack_u16le(g.image_data, start + 37)
|
return unpack_u16le(disk.buffer.read(start + 37, 2))
|
||||||
|
|
||||||
def getDirNextChunkPointer(arg1):
|
def getDirNextChunkPointer(disk, arg1):
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
start = ts(arg1)
|
start = ts(arg1)
|
||||||
return list(g.image_data[sli(start+1,2)])
|
return list(disk.buffer.read(start + 1, 2))
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
start = arg1 * 512
|
start = arg1 * 512
|
||||||
return unpack_u16le(g.image_data, start + 2)
|
return unpack_u16le(disk.buffer.read(start + 2, 2))
|
||||||
|
|
||||||
def toProdosName(name):
|
def toProdosName(name):
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -431,7 +428,7 @@ def sli(start, length=1, ext=None):
|
||||||
|
|
||||||
# --- main logic functions
|
# --- main logic functions
|
||||||
|
|
||||||
def copyFile(arg1, arg2):
|
def copyFile(arg1, arg2, disk):
|
||||||
#arg1/arg2:
|
#arg1/arg2:
|
||||||
# ProDOS : directory block / file index in overall directory
|
# ProDOS : directory block / file index in overall directory
|
||||||
# DOS 3.3 : [track, sector] / file index in overall VTOC
|
# DOS 3.3 : [track, sector] / file index in overall VTOC
|
||||||
|
@ -451,26 +448,26 @@ def copyFile(arg1, arg2):
|
||||||
with open(os.path.join(arg1, (arg2 + "r")), 'rb') as infile:
|
with open(os.path.join(arg1, (arg2 + "r")), 'rb') as infile:
|
||||||
g.ex_data += infile.read()
|
g.ex_data += infile.read()
|
||||||
else: # ProDOS or DOS 3.3
|
else: # ProDOS or DOS 3.3
|
||||||
storageType = getStorageType(arg1, arg2)
|
storageType = getStorageType(disk, arg1, arg2)
|
||||||
keyPointer = getKeyPointer(arg1, arg2)
|
keyPointer = getKeyPointer(disk, arg1, arg2)
|
||||||
fileLen = getFileLength(arg1, arg2)
|
fileLen = getFileLength(disk, arg1, arg2)
|
||||||
if storageType == 1: #seedling
|
if storageType == 1: #seedling
|
||||||
copyBlock(keyPointer, fileLen)
|
copyBlock(disk, keyPointer, fileLen)
|
||||||
elif storageType == 2: #sapling
|
elif storageType == 2: #sapling
|
||||||
processIndexBlock(keyPointer)
|
processIndexBlock(disk, keyPointer)
|
||||||
elif storageType == 3: #tree
|
elif storageType == 3: #tree
|
||||||
processMasterIndexBlock(keyPointer)
|
processMasterIndexBlock(disk, keyPointer)
|
||||||
elif storageType == 5: #extended (forked)
|
elif storageType == 5: #extended (forked)
|
||||||
processForkedFile(keyPointer)
|
processForkedFile(disk, keyPointer)
|
||||||
if g.prodos_names:
|
if g.prodos_names:
|
||||||
# remove address/length data from DOS 3.3 file data if ProDOS target
|
# remove address/length data from DOS 3.3 file data if ProDOS target
|
||||||
if getFileType(arg1, arg2) == '06':
|
if getFileType(disk, arg1, arg2) == '06':
|
||||||
g.out_data = g.out_data[4:]
|
g.out_data = g.out_data[4:]
|
||||||
elif (getFileType(arg1, arg2) == 'FA'
|
elif (getFileType(disk, arg1, arg2) == 'FA'
|
||||||
or getFileType(arg1, arg2) == 'FC'):
|
or getFileType(disk, arg1, arg2) == 'FC'):
|
||||||
g.out_data = g.out_data[2:]
|
g.out_data = g.out_data[2:]
|
||||||
|
|
||||||
def copyBlock(arg1, arg2):
|
def copyBlock(disk, arg1, arg2):
|
||||||
#arg1: block number or [t,s] to copy
|
#arg1: block number or [t,s] to copy
|
||||||
#arg2: bytes to write (should be 256 (DOS 3.3) or 512 (ProDOS),
|
#arg2: bytes to write (should be 256 (DOS 3.3) or 512 (ProDOS),
|
||||||
# unless final block with less)
|
# unless final block with less)
|
||||||
|
@ -478,7 +475,13 @@ def copyBlock(arg1, arg2):
|
||||||
if arg1 == 0:
|
if arg1 == 0:
|
||||||
outBytes = bytes(arg2)
|
outBytes = bytes(arg2)
|
||||||
else:
|
else:
|
||||||
outBytes = g.image_data[sli(ts(arg1) if g.dos33 else arg1*512, arg2)]
|
if g.dos33:
|
||||||
|
outBytes = disk.buffer.read(ts(arg1), arg2)
|
||||||
|
else:
|
||||||
|
outBytes = disk.buffer.read(arg1 * 512, arg2)
|
||||||
|
# FIXME: Sort out the read-one vs. read-many problem later
|
||||||
|
if type(outBytes) == int:
|
||||||
|
outBytes = bytes((outBytes))
|
||||||
if g.resourceFork > 0:
|
if g.resourceFork > 0:
|
||||||
if g.use_appledouble or g.use_extended:
|
if g.use_appledouble or g.use_extended:
|
||||||
offset = (741 if g.use_appledouble else 0)
|
offset = (741 if g.use_appledouble else 0)
|
||||||
|
@ -495,7 +498,7 @@ def copyBlock(arg1, arg2):
|
||||||
] = outBytes
|
] = outBytes
|
||||||
g.activeFileBytesCopied += arg2
|
g.activeFileBytesCopied += arg2
|
||||||
|
|
||||||
def process_dir(arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
def process_dir(disk, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
||||||
# arg1: ProDOS directory block, or DOS 3.3 [track,sector]
|
# arg1: ProDOS directory block, or DOS 3.3 [track,sector]
|
||||||
# for key block (with directory header):
|
# for key block (with directory header):
|
||||||
# arg2: casemask (optional), arg3:None, arg4:None, arg5:None
|
# arg2: casemask (optional), arg3:None, arg4:None, arg5:None
|
||||||
|
@ -516,9 +519,9 @@ def process_dir(arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
||||||
else:
|
else:
|
||||||
e = 0
|
e = 0
|
||||||
pe = 0
|
pe = 0
|
||||||
entryCount = getDirEntryCount(arg1)
|
entryCount = getDirEntryCount(disk, arg1)
|
||||||
if not g.dos33:
|
if not g.dos33:
|
||||||
workingDirName = getWorkingDirName(arg1, arg2).decode("L1")
|
workingDirName = getWorkingDirName(disk, arg1, arg2).decode("L1")
|
||||||
g.DIRPATH = g.DIRPATH + "/" + workingDirName
|
g.DIRPATH = g.DIRPATH + "/" + workingDirName
|
||||||
if g.PDOSPATH_INDEX:
|
if g.PDOSPATH_INDEX:
|
||||||
if g.PDOSPATH_INDEX == 1:
|
if g.PDOSPATH_INDEX == 1:
|
||||||
|
@ -530,25 +533,26 @@ def process_dir(arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
||||||
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
||||||
#else: print(g.DIRPATH)
|
#else: print(g.DIRPATH)
|
||||||
while pe < entryCount:
|
while pe < entryCount:
|
||||||
if getStorageType(arg1, e) > 0:
|
if getStorageType(disk, arg1, e) > 0:
|
||||||
#print(pe, e, entryCount)
|
#print(pe, e, entryCount)
|
||||||
processEntry(arg1, e)
|
processEntry(disk, arg1, e)
|
||||||
pe += 1
|
pe += 1
|
||||||
e += 1
|
e += 1
|
||||||
if not (e + (0 if g.dos33 else (e>11)) ) % (7 if g.dos33 else 13):
|
if not (e + (0 if g.dos33 else (e>11)) ) % (7 if g.dos33 else 13):
|
||||||
process_dir(
|
process_dir(
|
||||||
getDirNextChunkPointer(arg1), entryCount, e,
|
disk,
|
||||||
|
getDirNextChunkPointer(disk, arg1), entryCount, e,
|
||||||
workingDirName, pe)
|
workingDirName, pe)
|
||||||
break
|
break
|
||||||
|
|
||||||
def processEntry(arg1, arg2):
|
def processEntry(disk, arg1, arg2):
|
||||||
# arg1=block number, [t,s] if g.dos33=True, or subdir name if g.src_shk=1
|
# arg1=block number, [t,s] if g.dos33=True, or subdir name if g.src_shk=1
|
||||||
# arg2=index number of entry in directory, or file name if g.src_shk=1
|
# arg2=index number of entry in directory, or file name if g.src_shk=1
|
||||||
|
|
||||||
#print(getFileName(arg1, arg2), getStorageType(arg1, arg2),
|
#print(getFileName(disk, arg1, arg2), getStorageType(disk, arg1, arg2),
|
||||||
# getFileType(arg1, arg2), getKeyPointer(arg1, arg2),
|
# getFileType(disk, arg1, arg2), getKeyPointer(disk, arg1, arg2),
|
||||||
# getFileLength(arg1, arg2), getAuxType(arg1, arg2),
|
# getFileLength(disk, arg1, arg2), getAuxType(disk, arg1, arg2),
|
||||||
# getCreationDate(arg1, arg2), getModifiedDate(arg1, arg2))
|
# getCreationDate(disk, arg1, arg2), getModifiedDate(disk, arg1, arg2))
|
||||||
|
|
||||||
eTargetName = None
|
eTargetName = None
|
||||||
g.ex_data = None
|
g.ex_data = None
|
||||||
|
@ -559,17 +563,17 @@ def processEntry(arg1, arg2):
|
||||||
g.activeFileName = g.activeFileName.upper()
|
g.activeFileName = g.activeFileName.upper()
|
||||||
origFileName = g.activeFileName
|
origFileName = g.activeFileName
|
||||||
else: # ProDOS or DOS 3.3 image
|
else: # ProDOS or DOS 3.3 image
|
||||||
g.activeFileName = getFileName(arg1 ,arg2).decode("L1")
|
g.activeFileName = getFileName(disk, arg1 ,arg2).decode("L1")
|
||||||
origFileName = g.activeFileName
|
origFileName = g.activeFileName
|
||||||
if g.prodos_names:
|
if g.prodos_names:
|
||||||
g.activeFileName = toProdosName(g.activeFileName)
|
g.activeFileName = toProdosName(g.activeFileName)
|
||||||
g.activeFileSize = getFileLength(arg1, arg2)
|
g.activeFileSize = getFileLength(disk, arg1, arg2)
|
||||||
|
|
||||||
if (not g.PDOSPATH_INDEX or
|
if (not g.PDOSPATH_INDEX or
|
||||||
g.activeFileName.upper() == g.PDOSPATH_SEGMENT.upper()):
|
g.activeFileName.upper() == g.PDOSPATH_SEGMENT.upper()):
|
||||||
|
|
||||||
# if ProDOS directory, not file
|
# if ProDOS directory, not file
|
||||||
if not g.src_shk and getStorageType(arg1, arg2) == 13:
|
if not g.src_shk and getStorageType(disk, arg1, arg2) == 13:
|
||||||
if not g.PDOSPATH_INDEX:
|
if not g.PDOSPATH_INDEX:
|
||||||
g.target_dir = g.target_dir + "/" + g.activeFileName
|
g.target_dir = g.target_dir + "/" + g.activeFileName
|
||||||
g.appledouble_dir = g.target_dir + "/.AppleDouble"
|
g.appledouble_dir = g.target_dir + "/.AppleDouble"
|
||||||
|
@ -581,7 +585,8 @@ def processEntry(arg1, arg2):
|
||||||
if g.PDOSPATH_SEGMENT:
|
if g.PDOSPATH_SEGMENT:
|
||||||
g.PDOSPATH_INDEX += 1
|
g.PDOSPATH_INDEX += 1
|
||||||
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
||||||
process_dir(getKeyPointer(arg1, arg2), getCaseMask(arg1, arg2))
|
process_dir(disk, getKeyPointer(disk, arg1, arg2),
|
||||||
|
getCaseMask(disk, arg1, arg2))
|
||||||
g.DIRPATH = g.DIRPATH.rsplit("/", 1)[0]
|
g.DIRPATH = g.DIRPATH.rsplit("/", 1)[0]
|
||||||
if not g.PDOSPATH_INDEX:
|
if not g.PDOSPATH_INDEX:
|
||||||
g.target_dir = g.target_dir.rsplit("/", 1)[0]
|
g.target_dir = g.target_dir.rsplit("/", 1)[0]
|
||||||
|
@ -602,7 +607,7 @@ def processEntry(arg1, arg2):
|
||||||
dirPrint + filePrint
|
dirPrint + filePrint
|
||||||
+ ("+" if (g.shk_hasrf
|
+ ("+" if (g.shk_hasrf
|
||||||
or (not g.src_shk
|
or (not g.src_shk
|
||||||
and getStorageType(arg1, arg2) == 5))
|
and getStorageType(disk, arg1, arg2) == 5))
|
||||||
else "")
|
else "")
|
||||||
+ ((" [" + origFileName + "] ")
|
+ ((" [" + origFileName + "] ")
|
||||||
if (g.prodos_names
|
if (g.prodos_names
|
||||||
|
@ -617,17 +622,17 @@ def processEntry(arg1, arg2):
|
||||||
eTargetName = arg2
|
eTargetName = arg2
|
||||||
else: # ProDOS image
|
else: # ProDOS image
|
||||||
eTargetName = (g.target_name + "#"
|
eTargetName = (g.target_name + "#"
|
||||||
+ getFileType(arg1, arg2).lower()
|
+ getFileType(disk, arg1, arg2).lower()
|
||||||
+ getAuxType(arg1, arg2).lower())
|
+ getAuxType(disk, arg1, arg2).lower())
|
||||||
# touch(g.target_dir + "/" + g.target_name)
|
# touch(g.target_dir + "/" + g.target_name)
|
||||||
if g.use_appledouble:
|
if g.use_appledouble:
|
||||||
makeADfile()
|
makeADfile()
|
||||||
copyFile(arg1, arg2)
|
copyFile(arg1, arg2, disk)
|
||||||
saveName = (g.target_dir + "/"
|
saveName = (g.target_dir + "/"
|
||||||
+ (eTargetName if eTargetName else g.target_name))
|
+ (eTargetName if eTargetName else g.target_name))
|
||||||
save_file(saveName, g.out_data)
|
save_file(saveName, g.out_data)
|
||||||
d_created = getCreationDate(arg1, arg2)
|
d_created = getCreationDate(disk, arg1, arg2)
|
||||||
d_modified = getModifiedDate(arg1, arg2)
|
d_modified = getModifiedDate(disk, arg1, arg2)
|
||||||
if not d_modified:
|
if not d_modified:
|
||||||
d_modified = (d_created
|
d_modified = (d_created
|
||||||
or int(datetime.datetime.today().timestamp()))
|
or int(datetime.datetime.today().timestamp()))
|
||||||
|
@ -643,8 +648,8 @@ def processEntry(arg1, arg2):
|
||||||
#set type/creator
|
#set type/creator
|
||||||
g.ex_data[653] = ord('p')
|
g.ex_data[653] = ord('p')
|
||||||
g.ex_data[654:657] = bytes.fromhex(
|
g.ex_data[654:657] = bytes.fromhex(
|
||||||
getFileType(arg1, arg2)
|
getFileType(disk, arg1, arg2)
|
||||||
+ getAuxType(arg1, arg2))
|
+ getAuxType(disk, arg1, arg2))
|
||||||
g.ex_data[657:661] = b'pdos'
|
g.ex_data[657:661] = b'pdos'
|
||||||
save_file(ADfile_path, g.ex_data)
|
save_file(ADfile_path, g.ex_data)
|
||||||
touch(saveName, d_modified)
|
touch(saveName, d_modified)
|
||||||
|
@ -660,30 +665,30 @@ def processEntry(arg1, arg2):
|
||||||
g.target_name = None
|
g.target_name = None
|
||||||
#else print(g.activeFileName + " doesn't match " + g.PDOSPATH_SEGMENT)
|
#else print(g.activeFileName + " doesn't match " + g.PDOSPATH_SEGMENT)
|
||||||
|
|
||||||
def processForkedFile(arg1):
|
def processForkedFile(disk, arg1):
|
||||||
# finder info except type/creator
|
# finder info except type/creator
|
||||||
fInfoA_entryType = g.image_data[9]
|
fInfoA_entryType = disk.buffer.read1(9)
|
||||||
fInfoB_entryType = g.image_data[27]
|
fInfoB_entryType = disk.buffer.read1(27)
|
||||||
if fInfoA_entryType == 1:
|
if (fInfoA_entryType == 1):
|
||||||
g.image_data[661:669], g.image_data[18:26]
|
disk.buffer.write(disk.buffer.read(18, 8), 661, 8)
|
||||||
elif fInfoA_entryType == 2:
|
elif (fInfoA_entryType == 2):
|
||||||
g.image_data[669:685], g.image_data[10:26]
|
disk.buffer.write(disk.buffer.read(10, 16), 669, 16)
|
||||||
if fInfoB_entryType == 1:
|
if (fInfoB_entryType == 1):
|
||||||
g.image_data[661:669], g.image_data[36:44]
|
disk.buffer.write(disk.buffer.read(36, 8), 661, 8)
|
||||||
elif fInfoB_entryType == 2:
|
elif (fInfoB_entryType == 2):
|
||||||
g.image_data[669:685], g.image_data[28:44]
|
disk.buffer.write(disk.buffer.read(28, 16), 669, 16)
|
||||||
|
|
||||||
for f in (0, 256):
|
for f in (0, 256):
|
||||||
g.resourceFork = f
|
g.resourceFork = f
|
||||||
g.activeFileBytesCopied = 0
|
g.activeFileBytesCopied = 0
|
||||||
forkStart = arg1 * 512 # start of Forked File key block
|
forkStart = arg1 * 512 # start of Forked File key block
|
||||||
#print("--" + forkStart)
|
#print("--" + forkStart)
|
||||||
forkStorageType = g.image_data[forkStart+f]
|
forkStorageType = disk.buffer.read1(forkStart + f)
|
||||||
forkKeyPointer = unpack_u16le(g.image_data, forkStart + f + 1)
|
forkKeyPointer = unpack_u16le(disk.buffer.read(forkStart + f + 1, 2))
|
||||||
forkFileLen = unpack_u24le(g.image_data, forkStart + f + 5)
|
forkFileLen = unpack_u24le(disk.buffer.read(forkStart + f + 5, 3))
|
||||||
g.activeFileSize = forkFileLen
|
g.activeFileSize = forkFileLen
|
||||||
if g.resourceFork > 0:
|
if g.resourceFork > 0:
|
||||||
rsrcForkLen = unpack_u24le(g.image_data, forkStart + f + 5)
|
rsrcForkLen = unpack_u24le(disk.buffer.read(forkStart + f + 5, 3))
|
||||||
#print(">>>", rsrcForkLen)
|
#print(">>>", rsrcForkLen)
|
||||||
if g.use_appledouble or g.use_extended:
|
if g.use_appledouble or g.use_extended:
|
||||||
print(" [resource fork]")
|
print(" [resource fork]")
|
||||||
|
@ -692,43 +697,43 @@ def processForkedFile(arg1):
|
||||||
else:
|
else:
|
||||||
print(" [data fork]")
|
print(" [data fork]")
|
||||||
if forkStorageType == 1: #seedling
|
if forkStorageType == 1: #seedling
|
||||||
copyBlock(forkKeyPointer, forkFileLen)
|
copyBlock(disk, forkKeyPointer, forkFileLen)
|
||||||
elif forkStorageType == 2: #sapling
|
elif forkStorageType == 2: #sapling
|
||||||
processIndexBlock(forkKeyPointer)
|
processIndexBlock(disk, forkKeyPointer)
|
||||||
elif forkStorageType == 3: #tree
|
elif forkStorageType == 3: #tree
|
||||||
processMasterIndexBlock(forkKeyPointer)
|
processMasterIndexBlock(disk, forkKeyPointer)
|
||||||
#print()
|
#print()
|
||||||
g.resourceFork = 0
|
g.resourceFork = 0
|
||||||
|
|
||||||
def processMasterIndexBlock(arg1):
|
def processMasterIndexBlock(disk, arg1):
|
||||||
processIndexBlock(arg1, True)
|
processIndexBlock(disk, arg1, True)
|
||||||
|
|
||||||
def processIndexBlock(arg1, arg2=False):
|
def processIndexBlock(disk, arg1, arg2=False):
|
||||||
#arg1: indexBlock, or [t,s] of track/sector list
|
#arg1: indexBlock, or [t,s] of track/sector list
|
||||||
#arg2: if True, it's a Master Index Block
|
#arg2: if True, it's a Master Index Block
|
||||||
pos = 12 if g.dos33 else 0
|
pos = 12 if g.dos33 else 0
|
||||||
bytesRemaining = g.activeFileSize
|
bytesRemaining = g.activeFileSize
|
||||||
while g.activeFileBytesCopied < g.activeFileSize:
|
while g.activeFileBytesCopied < g.activeFileSize:
|
||||||
if g.dos33:
|
if g.dos33:
|
||||||
targetTS = list(g.image_data[sli(ts(arg1)+pos,2)])
|
targetTS = list(disk.buffer.read(ts(arg1) + pos, 2))
|
||||||
#print('{02x} {02x}'.format(targetTS[0], targetTS[1]))
|
#print('{02x} {02x}'.format(targetTS[0], targetTS[1]))
|
||||||
bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied)
|
bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied)
|
||||||
bs = (bytesRemaining if bytesRemaining < 256 else 256)
|
bs = (bytesRemaining if bytesRemaining < 256 else 256)
|
||||||
copyBlock(targetTS, bs)
|
copyBlock(disk, targetTS, bs)
|
||||||
pos += 2
|
pos += 2
|
||||||
if pos > 255:
|
if pos > 255:
|
||||||
# continue with next T/S list sector
|
# continue with next T/S list sector
|
||||||
processIndexBlock(list(g.image_data[sli(ts(arg1)+1,2)]))
|
processIndexBlock(disk, list(disk.buffer.read(ts(arg1) + 1, 2)))
|
||||||
else: # ProDOS
|
else: # ProDOS
|
||||||
# Note these are not consecutive bytes
|
# Note these are not consecutive bytes
|
||||||
targetBlock = (g.image_data[arg1*512+pos] +
|
targetBlock = (disk.buffer.read1(arg1 * 512 + pos) +
|
||||||
g.image_data[arg1*512+pos+256]*256)
|
disk.buffer.read1(arg1 * 512 + pos+256) * 256)
|
||||||
if arg2:
|
if arg2:
|
||||||
processIndexBlock(targetBlock)
|
processIndexBlock(disk, targetBlock)
|
||||||
else:
|
else:
|
||||||
bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied)
|
bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied)
|
||||||
bs = bytesRemaining if bytesRemaining < 512 else 512
|
bs = bytesRemaining if bytesRemaining < 512 else 512
|
||||||
copyBlock(targetBlock, bs)
|
copyBlock(disk, targetBlock, bs)
|
||||||
pos += 1
|
pos += 1
|
||||||
if pos > 255:
|
if pos > 255:
|
||||||
break # go to next entry in Master Index Block (tree)
|
break # go to next entry in Master Index Block (tree)
|
||||||
|
@ -936,43 +941,42 @@ def run_cppo():
|
||||||
elif (os.path.isfile(os.path.join(dirName, (fname + "r")))):
|
elif (os.path.isfile(os.path.join(dirName, (fname + "r")))):
|
||||||
g.shk_hasrf = True
|
g.shk_hasrf = True
|
||||||
if not rfork:
|
if not rfork:
|
||||||
processEntry(dirName, fname)
|
processEntry(disk, dirName, fname)
|
||||||
shutil.rmtree(unshkdir, True)
|
shutil.rmtree(unshkdir, True)
|
||||||
quit_now(0)
|
quit_now(0)
|
||||||
|
|
||||||
# end script if SHK
|
# end script if SHK
|
||||||
|
|
||||||
g.image_data = load_file(disk.pathname)
|
|
||||||
|
|
||||||
# detect if image is 2mg and remove 64-byte header if so
|
# detect if image is 2mg and remove 64-byte header if so
|
||||||
if disk.ext in ('.2mg', '.2img'):
|
if disk.ext in ('.2mg', '.2img'):
|
||||||
g.image_data = g.image_data[64:]
|
# FIXME: Seriously STOP doing this...
|
||||||
|
disk.buffer._buf = disk.buffer._buf[64:]
|
||||||
|
|
||||||
# handle 140k disk image
|
# handle 140k disk image
|
||||||
if len(g.image_data) == 143360:
|
if len(disk.buffer) == 143360:
|
||||||
LOG.debug("140k disk")
|
LOG.debug("140k disk")
|
||||||
prodos_disk = False
|
prodos_disk = False
|
||||||
fix_order = False
|
fix_order = False
|
||||||
# is it ProDOS?
|
# is it ProDOS?
|
||||||
if g.image_data[sli(ts(0,0), 4)] == b'\x01\x38\xb0\x03':
|
if disk.buffer.read(ts(0, 0), 4) == b'\x01\x38\xb0\x03':
|
||||||
LOG.debug("detected ProDOS by boot block")
|
LOG.debug("detected ProDOS by boot block")
|
||||||
if g.image_data[sli(ts(0,1)+3, 6)] == b'PRODOS':
|
if disk.buffer.read(ts(0, 1) + 3, 6) == b'PRODOS':
|
||||||
LOG.debug("order OK (PO)")
|
LOG.debug("order OK (PO)")
|
||||||
prodos_disk = True
|
prodos_disk = True
|
||||||
elif g.image_data[sli(ts(0,14)+3, 6)] == b'PRODOS':
|
elif disk.buffer.read(ts(0, 14) + 3, 6) == b'PRODOS':
|
||||||
LOG.debug("order needs fixing (DO)")
|
LOG.debug("order needs fixing (DO)")
|
||||||
prodos_disk = True
|
prodos_disk = True
|
||||||
fix_order = True
|
fix_order = True
|
||||||
# is it DOS 3.3?
|
# is it DOS 3.3?
|
||||||
else:
|
else:
|
||||||
LOG.debug("it's not ProDOS")
|
LOG.debug("it's not ProDOS")
|
||||||
if g.image_data[ts(17,0)+3] == 3:
|
if disk.buffer.read1(ts(17, 0) + 3) == 3:
|
||||||
vtocT, vtocS = g.image_data[sli(ts(17,0) + 1,2)]
|
vtocT, vtocS = disk.buffer.read(ts(17,0) + 1, 2)
|
||||||
if vtocT < 35 and vtocS < 16:
|
if vtocT < 35 and vtocS < 16:
|
||||||
LOG.debug("it's DOS 3.3")
|
LOG.debug("it's DOS 3.3")
|
||||||
g.dos33 = True
|
g.dos33 = True
|
||||||
# it's DOS 3.3; check sector order next
|
# it's DOS 3.3; check sector order next
|
||||||
if g.image_data[ts(17,14)+2] != 13:
|
if disk.buffer.read1(ts(17, 14) + 2) != 13:
|
||||||
LOG.debug("order needs fixing (PO)")
|
LOG.debug("order needs fixing (PO)")
|
||||||
fix_order = True
|
fix_order = True
|
||||||
else:
|
else:
|
||||||
|
@ -985,9 +989,10 @@ def run_cppo():
|
||||||
fix_order = True
|
fix_order = True
|
||||||
if fix_order:
|
if fix_order:
|
||||||
LOG.debug("fixing order")
|
LOG.debug("fixing order")
|
||||||
g.image_data = dopo_swap(g.image_data)
|
# FIXME
|
||||||
|
disk.buffer._buf = dopo_swap(disk.buffer._buf)
|
||||||
#print("saving fixed order file as outfile.dsk")
|
#print("saving fixed order file as outfile.dsk")
|
||||||
#save_file("outfile.dsk", g.image_data)
|
#save_file("outfile.dsk", disk.buffer._buf)
|
||||||
#print("saved")
|
#print("saved")
|
||||||
|
|
||||||
if not prodos_disk and not g.dos33:
|
if not prodos_disk and not g.dos33:
|
||||||
|
@ -1016,7 +1021,7 @@ def run_cppo():
|
||||||
makedirs(g.appledouble_dir)
|
makedirs(g.appledouble_dir)
|
||||||
if not g.extract_file:
|
if not g.extract_file:
|
||||||
print("Extracting into " + disk_name)
|
print("Extracting into " + disk_name)
|
||||||
process_dir(list(g.image_data[sli(ts(17,0)+1,2)]))
|
process_dir(disk, list(disk.buffer.read(ts(17, 0) + 1, 2)))
|
||||||
if g.extract_file:
|
if g.extract_file:
|
||||||
print("ProDOS file not found within image file.")
|
print("ProDOS file not found within image file.")
|
||||||
quit_now(0)
|
quit_now(0)
|
||||||
|
@ -1040,16 +1045,16 @@ def run_cppo():
|
||||||
g.appledouble_dir = (g.target_dir + "/.AppleDouble")
|
g.appledouble_dir = (g.target_dir + "/.AppleDouble")
|
||||||
if g.use_appledouble and not os.path.isdir(g.appledouble_dir):
|
if g.use_appledouble and not os.path.isdir(g.appledouble_dir):
|
||||||
mkdir(g.appledouble_dir)
|
mkdir(g.appledouble_dir)
|
||||||
process_dir(2)
|
process_dir(disk, 2)
|
||||||
print("ProDOS file not found within image file.")
|
print("ProDOS file not found within image file.")
|
||||||
quit_now(2)
|
quit_now(2)
|
||||||
else:
|
else:
|
||||||
if not g.catalog_only:
|
if not g.catalog_only:
|
||||||
g.target_dir = (g.target_dir + "/" + getVolumeName().decode())
|
g.target_dir = (g.target_dir + "/" + getVolumeName(disk).decode())
|
||||||
g.appledouble_dir = (g.target_dir + "/.AppleDouble")
|
g.appledouble_dir = (g.target_dir + "/.AppleDouble")
|
||||||
if not os.path.isdir(g.target_dir):
|
if not os.path.isdir(g.target_dir):
|
||||||
makedirs(g.target_dir)
|
makedirs(g.target_dir)
|
||||||
if g.use_appledouble and not os.path.isdir(g.appledouble_dir):
|
if g.use_appledouble and not os.path.isdir(g.appledouble_dir):
|
||||||
makedirs(g.appledouble_dir)
|
makedirs(g.appledouble_dir)
|
||||||
process_dir(2)
|
process_dir(disk, 2)
|
||||||
quit_now(0)
|
quit_now(0)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user