From 76daa17640944d439a1a0d611a8cd59d9418d05f Mon Sep 17 00:00:00 2001 From: gryf Date: Fri, 20 Sep 2019 18:00:03 +0200 Subject: [PATCH] Added support for .d81 images. --- README.rst | 17 +++++++++-------- uc1541 | 35 +++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/README.rst b/README.rst index cd9010f..6608e1b 100644 --- a/README.rst +++ b/README.rst @@ -11,16 +11,16 @@ Features ======== * view, remove, copy files in and out of the image -* support for read from and write to d64 images +* support for read from and write to d64, d71 and d81 images * gzipped disk images support * onfly characters remapping (see below) Remarks ======= -Due to different way of representing file entries on regular D64 disk images, -there could be issues with filenames that are transfered from/to the image. -Following rules was applied to represent a single file entry: +Due to different way of representing file entries on regular Commodore disk +images, there could be issues with filenames that are transfered from/to the +image. Following rules was applied to represent a single file entry: 1. An extension is attached to the end of a filename depending on a file type. Possible extensions are: ``prg``, ``del``, ``seq``, ``usr`` and ``rel``. @@ -30,7 +30,7 @@ Following rules was applied to represent a single file entry: 3. Every slash character (``/``) will be replaced by pipe character (``|``). 4. Leading space will be replaced by tilda (``~``). -While copying from D64 image to filesystem, filenames will be stored as they +While copying from disk image to filesystem, filenames will be stored as they are seen on a listing. While copying from filesystem to D64 image, filename conversion will be done: @@ -43,8 +43,8 @@ While copying from filesystem to D64 image, filename conversion will be done: Representation of a directory can be sometimes confusing - in case when one copied file without extension it stays there in such form, till next access -(after flushing VFS). Also file sizes are not accurate, since D64 directory -entries have sizes stored as 256 bytes blocks. +(after flushing VFS). Also file sizes are not accurate, since directory entries +in CBM format have sizes stored as 256 bytes blocks. Screens below shows how it looks like on real C64 machine and its representation on Midnight Commander listing. @@ -67,7 +67,7 @@ Installation * add or change entry for files handle in ``~/.config/mc/mc.ext``:: # Disk images for Commodore computers (VIC20, C64, C128) - regex/\.(d64|D64|d6z|D6z|d6Z|D6Z)$ + regex/\.([dD]64|[dD]6[zZ]|[dD]71|[dD]7[zZ]|[dD]81|[dD]8[zZ])$ Open=%cd %p/uc1541:// View=%view{ascii} c1541 %f -list Extract=c1541 %f -extract @@ -87,6 +87,7 @@ script behaviour: Changelog ========= +* **3.3** Added support for .d71 and .d81 disk images. * **3.2** Changed shebang to ``python`` executable instead of ``python3`` * **3.1** Argparse on Python3 have different behaviour, where if no subcommand is provided, it will pass anyway. Fixed. diff --git a/uc1541 b/uc1541 index 2bd332a..b59e509 100755 --- a/uc1541 +++ b/uc1541 @@ -3,8 +3,8 @@ UC1541 Virtual filesystem Author: Roman 'gryf' Dobosz -Date: 2019-09-15 -Version: 3.2 +Date: 2019-09-20 +Version: 3.3 Licence: BSD source: https://bitbucket.org/gryf/uc1541 mirror: https://github.com/gryf/uc1541 @@ -68,8 +68,9 @@ def _ord(string_or_int): def _get_raw(dimage): - """Try to get contents of the D64 image either it's gzip compressed or - not.""" + """ + Try to get contents of the D64 image either it's gzip compressed or not. + """ raw = None with gzip.open(dimage, 'rb') as fobj: # Although the common approach with gzipped files is to check the @@ -136,8 +137,8 @@ class Disk(object): 0b011: 'usr', 0b100: 'rel'} - OFFSET_MAP = {} DIR_TRACK = 18 + DIR_SECTOR = 1 def __init__(self, raw): """ @@ -188,8 +189,9 @@ class Disk(object): return False if self.next_track is None: - LOG.debug("Going to the track: 18,1") - offset = self._get_offset(self.DIR_TRACK, 1) + LOG.debug("Going to the track: %s, %s", self.DIR_TRACK, + self.DIR_SECTOR) + offset = self._get_offset(self.DIR_TRACK, self.DIR_SECTOR) else: offset = self._get_offset(self.next_track, self.next_sector) LOG.debug("Going to the track: %s,%s", self.next_track, @@ -198,7 +200,7 @@ class Disk(object): self.current_sector_data = self.raw[offset:offset + SECLEN] # Guard for reading data out of bound - that happened for discs which - # store only raw data, even on 18 track + # store only raw data, even on directory track if not self.current_sector_data: return False @@ -367,6 +369,23 @@ class D81(Disk): """ Implement d81 directory reader """ + DIR_TRACK = 40 + DIR_SECTOR = 3 + FILE_TYPES = {0b000: 'del', + 0b001: 'seq', + 0b010: 'prg', + 0b011: 'usr', + 0b100: 'rel', + 0b101: 'cbm'} + + def _get_offset(self, track, sector): + """ + Return offset (in bytes) for specified track and sector. In d81 is + easy, since we have 80 tracks with 40 sectors for 256 bytes each. + """ + # we wan to go to the beginning (first sector) of the track, not it's + # max, so that we need to extract its amount. + return (track * 40 - 40) * SECLEN + sector * SECLEN class Uc1541(object):