{"id":20685394,"url":"https://github.com/yas-sim/floppy_image_library_d88_d77","last_synced_at":"2026-03-07T23:30:46.971Z","repository":{"id":258600478,"uuid":"861183078","full_name":"yas-sim/floppy_image_library_d88_d77","owner":"yas-sim","description":"A Python library intended to be used for manipulating the D88/D77 floppy disk image files for emulators.","archived":false,"fork":false,"pushed_at":"2024-10-17T13:44:40.000Z","size":256,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-17T23:44:25.725Z","etag":null,"topics":["d77","d88","disk-image","emulator","f-basic","filesystem","floppy-disk-images","fm-7","fm77av","fujitsu-8bit","xm7"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yas-sim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-22T08:18:05.000Z","updated_at":"2024-10-17T13:44:44.000Z","dependencies_parsed_at":"2024-10-20T15:39:47.067Z","dependency_job_id":null,"html_url":"https://github.com/yas-sim/floppy_image_library_d88_d77","commit_stats":null,"previous_names":["yas-sim/floppy_image_library_d88_d77"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yas-sim/floppy_image_library_d88_d77","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yas-sim%2Ffloppy_image_library_d88_d77","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yas-sim%2Ffloppy_image_library_d88_d77/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yas-sim%2Ffloppy_image_library_d88_d77/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yas-sim%2Ffloppy_image_library_d88_d77/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yas-sim","download_url":"https://codeload.github.com/yas-sim/floppy_image_library_d88_d77/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yas-sim%2Ffloppy_image_library_d88_d77/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30237329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T23:24:20.706Z","status":"ssl_error","status_checked_at":"2026-03-07T23:21:10.486Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["d77","d88","disk-image","emulator","f-basic","filesystem","floppy-disk-images","fm-7","fm77av","fujitsu-8bit","xm7"],"created_at":"2024-11-16T22:27:10.437Z","updated_at":"2026-03-07T23:30:46.942Z","avatar_url":"https://github.com/yas-sim.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Floppy disk image manipulation library\r\n(WIP)  \r\nThis libray is intended to be used for manipulating the floppy disk images for emulators.  \r\nInitial target is to support D88/D77 floppy disk image format.  \r\n\r\nNOTICE: CLI commands and file system only supports Fujitsu FM-7 series disk BASIC foromat disks.   \r\n\r\n----------------------------\r\n\r\n## CLI commands:\r\n\r\n### `fmdir.py`\r\n**Description**: Show directory entries of an FM-7 DISK BASIC disk in D88/D77 image file.  \r\n\r\n```sh\r\noptions:\r\n  -h, --help            show this help message and exit\r\n  -f FILE, --file FILE  D88/D77 image file name\r\n  -n IMAGE_NUMBER, --image_number IMAGE_NUMBER\r\n                        Specify target image number (if the image file contains multiple images). Default=0\r\n  --original            Display the original file name\r\n  -v, --verbose         Verbose flag\r\n```\r\n\r\nCommand line examples:\r\n```sh\r\npython fmdir.py -f fb3l2.d77 -n 0\r\n  0 DFMCD    2 B S   0    2\r\n  1 MCOPY    2 B S   1    4\r\n  2 SYSDSK   0 B S   2    6\r\n  3 VOLCOPY  0 B S   3    5\r\n  4 AUTOUTY  0 B S   4    3\r\n  5 PFDEF    0 B S   5    9\r\n  6 SYSUTY   0 B S   7   39\r\n  :   :       :\r\n 34 TEST     1 A S  68    3\r\n 35 WOMAN    1 A S  69   37\r\n 36 KOMACHI  1 A S  74   48\r\n ```\r\n\r\n\r\n### `fmread.py`\r\n\r\n**Description**: Read a file from an FM-7 DISK BASIC disk in D88/D77 image file.  \r\n\r\n```sh\r\noptions:\r\n  -h, --help            show this help message and exit\r\n  -f FILE, --file FILE  D88/D77 image file name\r\n  -n IMAGE_NUMBER, --image_number IMAGE_NUMBER\r\n                        Specify target image number (if the image file contains multiple images). Default=0\r\n  -s SOURCE, --source SOURCE\r\n                        Source file name in the image file to read.\r\n  -i INDEX, --index INDEX\r\n                        Directory index number to specify the target file to read.\r\n  -d DESTINATION, --destination DESTINATION\r\n                        Destination (destination) file name. When omitted, the source file name and file attributes are used to generate the destination file name.\r\n  -v, --verbose         Verbose flag\r\n  --decode_basic        Decode BASIC IR code and store it as a plain text file.\r\n  --srecord             Convert a machine code file contents to Motorola S-record format.\r\n  --yaml                Convert a machine code file contents to YAML format.\r\n  --json                Convert a machine code file contents to JSON format.\r\n  ```\r\nCommand line examples: \r\n\r\nRead a file from the image #0 in '`image.d88`' and write it to '`GAME.dat`'. The file extension represents the source file attributes. The final output file name would be something like '`game.dat.0BS`'.\r\n```sh\r\npython fmread.py -f image.d88 -n 0 -s GAME -d GAME.dat\r\n```\r\nRead a file from the image #0 in '`image.d77`'. The output file name will be generated based on the read file name and its attributes. The final output file name would be something like '`GAME.0BS`'.\r\n```sh\r\npython fmread.py -f image.d88 -n 0 -i 1\r\n```\r\n\r\n### `fmwrite.py`  \r\n**Description**: Write a file to an FM-7 DISK BASIC disk in D88/D77 image file.  \r\n\r\n```sh\r\noptions:\r\n  -h, --help            show this help message and exit\r\n  -f FILE, --file FILE  D88/D77 image file name\r\n  -n IMAGE_NUMBER, --image_number IMAGE_NUMBER\r\n                        Specify target image number (if the image file contains multiple images). Default=0\r\n  -s SOURCE, --source SOURCE\r\n                        Source file name to be written to the image file.\r\n  -v, --verbose         Verbose flag\r\n```\r\n\r\nCommand line examples:\r\nWrite '`GAME.0AS` file to the `test.d88` image file.\r\n```sh\r\npython fmwrite.py -f test.d88 -s GAME.0AS\r\n```\r\n\r\n### `fmmakedisk.py`  \r\n\r\nCreate a D88 new image file. The new image file contains only one disk image. The disk image will be formatted in FM-7 DISK BASIC format.  \r\n```sh\r\noptions:\r\n  -h, --help            show this help message and exit\r\n  -f FILE, --file FILE  D88/D77 image file name\r\n  -v, --verbose         Verbose flag\r\n  ```\r\n\r\n----------------------------\r\n\r\n## Library API document  \r\nYou can find a simple API document [here](./html_docs/index.html).\r\n\r\n----------------------------\r\n### 'FD_IMAGE' and its derivative classes\r\nThis class represents a floppy disk image file that may contain multiple floppy disk information.\r\n|Name|Description|Note|\r\n|---|---|---|\r\n|`self.images[]`|List of `FLOPPY_DISK` objects||\r\n\r\n\r\n### 'FLOPPY_DISK' and derivative classes\r\nThis class represents the data of a single floppy disk.\r\n|Name|Description|Note|\r\n|---|---|---|\r\n|`self.disk_name`|Disk name|16 characters max|\r\n|`self.write_protect`|Write protect flag|0x00: No protect\u003cbr\u003e0x10: Write protected|\r\n|`self.disk_type`|Disk type|0x00: 2D\u003cbr\u003e0x10: 2DD\u003cbr\u003e0x20: 2HD|\r\n|`self.tracks[[],[],[],...]`|Track data|A list consists of lists of 'sector data'|\r\n\r\n\r\n\r\n### Sector data\r\n|Name|Description|Note|\r\n|---|---|---|\r\n|`sect_idx`|Index number of the sector|Sector number in a track. Starts with 0.|\r\n|`C`|Cylinder #||\r\n|`H`|Head #||\r\n|`R`|Sector ID||\r\n|`N`|Sector size|0:128, 1:256, 2:512, 3:1024|\r\n|`num_sectors`|Number of sectors in the track. In the D88 format, every sector contains this num_sectors data (although it's redundant).|\r\n|`density`|Data density|0x00:Double\u003cbr\u003e0x40:Single|\r\n|`data_mark`|Data mark|0x00: Normal data mark\u003cbr\u003e0x10: Deleted data mark|\r\n|`status`|Status|0x00: No error\u003cbr\u003e0x10: No error (DDM)\u003cbr\u003e0a0: ID CRC error\u003cbr\u003e0xb0: Data CRC error\u003cbr\u003e0xe0: No address mark\u003cbr\u003e0xf0: No data mark|\r\n|`data_size`|Size of the sector data||\r\n|`sect_data[]`|Actual sector data (bytearray)|\r\n\r\n\r\n-------------------------------------------\r\n\r\n## D88 Image Format Specification\r\n\r\nAll numerical data are stored in little-endien byte order.\r\n\r\n|Section Name|Description|Note|\r\n|---|---|---|\r\n|Header|Header|Contains disk attributes (0x02b0 bytes)|\r\n|Track data[]|Array of track data|D88 format supports 164 tracks|\r\n\r\n### D88 Image Format Header Structure  \r\nHeader size = 0x20 + 0x04 * 164 = 0x2b0\r\n|Offset|Size|Description|Note|\r\n|---|---|---|---|\r\n|0x00|0x11|Disk image name|Ascii code. The last byte (17th) must be 0x00|\r\n|0x11|0x09|Padding|Filled with 0x00|\r\n|0x1a|0x01|Write protect flag|0x00:Not protected\u003cbr\u003e0x10:Write protected|\r\n|0x1b|0x01|Disk density|0x00:2D\u003cbr\u003e0x10:2DD\u003cbr\u003e0x20:2HD|\r\n|0x1c|0x04|Disk image size|This includes header and all track data.|\r\n|0x20|0x04[164]|Track offset table|Offset to the track data from the top of the image data. This table contains offset for 164 track data|\r\n\r\n### D88 Track Data Structure  \r\n|Offset|Size|Descriptor|Note|\r\n|---|---|---|---|\r\n|0x00|0x01|C||\r\n|0x01|0x01|H||\r\n|0x02|0x01|R||\r\n|0x03|0x01|N||\r\n|0x04|0x02|Number of sectors in this track||\r\n|0x06|0x01|Encoding density|0x00:MFM (double)\u003cbr\u003e0x40:FM (single)|\r\n|0x07|0x01|Data Mark|0x00:Normal data mark\u003cbr\u003e0x10:Deleted data mark|\r\n|0x08|0x01|Read status|0x00:No error\u003cbr\u003e0x10:No error(DDM)\u003cbr\u003e0xa0:ID CRC error\u003cbr\u003e0xb0:Data CRC error\u003cbr\u003e0xe0:No address mark\u003cbr\u003e0xf0:No data mark|\r\n|0x09|0x05|Padding||\r\n|0x0e|0x02|Data size of this sector||\r\n|0x10|(Data size of this sector)|Sector data||\r\n\r\n--------------------------------------------------------------\r\n\r\n## F-BASIC disk map\r\nIn this table, track = C*2+H. The sector number starts from 1 (the 1stsector on a track is 1).  \r\n|track|sector|description|note|\r\n|---|---|---|---|\r\n|0|1-2|IPL|Initial program loader|\r\n|0|3|ID|Disk identification data. The sector start with 'SYS'.|\r\n|0|4-16|Reserve||\r\n|1|1-16|Disk BASIC code||\r\n|2|1|FAT||\r\n|2|2-3|Reserve||\r\n|2|4-16|Directory||\r\n|3|1-16|Directory||\r\n\r\n### Cluster in F-BASIC  \r\nF-BASIC manages data in a unit of cluster. Each cluster consists of 8 sectors. The cluster 0 starts from track 4 (C=2, H=0).\r\n\r\n### FAT in F-BASIC\r\nOne byte in the FAT represents a cluster. The FAT starts from 6th byte in the FAT (The top 5 bytes are reserved).\r\n\r\n|offset|size|description|note|\r\n|----|----|----|----|\r\n|0x00|0x05|Reserve||\r\n|0x05|0x98|FAT table|For 152 clusters.\u003cbr\u003e0x00-0x97: In-use. Indicating next cluster number.\u003cbr\u003e0xc0-0xc7: In-use, and indicating the last cluster of the cluster chain. The lower 4-bits represents the number of sectores used in the last cluster.\u003cbr\u003e0xfd: No sectors are used in this cluster.\u003cbr\u003e0xfe: Reserved for system use.\u003cbr\u003e0xff: Not in-use.|\r\n\r\n### Directory entry in F-BASIC  \r\n\r\nA directory entry consists of 32 bytes of data.  \r\nWhen a file is deleted, the top of the file name is set to 0x00, and the used clusters are freed (FAT chain is cleard with 0xff).\r\n|offset|size|description|note|\r\n|----|----|----|----|\r\n|0x00|0x08|File name||\r\n|0x08|0x03|reserved||\r\n|0x0b|0x01|File type|0x00:BASIC text\u003cbr\u003e0x01:BASIC data\u003cbr\u003e0x02:Machine code|\r\n|0c0c|0x01|ASCII flag|0x00:Binary\u003cbr\u003e0xff:ASCII|\r\n|0c0d|0x01|Random access flag|0x00:Sequential\u003cbr\u003e0xff:Random access|\r\n|0x0e|0x01|The first cluster number||\r\n|0x0f|0x11|reserved|\r\n\r\n-----------------------------\r\n## Bin list\r\n- ☑ Image write back\r\n- ☑ New image creation\r\n- ☑ File attribute check on write_file\r\n- ☑ Disk full detection on wite_file\r\n- ☐ Sector read error handling\r\n- ☑ File access by dir_idx\r\n- ☐ File access CLI commands\r\n- ☐ Motorola-S decoding encoding\r\n- ☑ Image serialization\r\n- ☑ Image deserialization\r\n- ☐ GUI ?\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyas-sim%2Ffloppy_image_library_d88_d77","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyas-sim%2Ffloppy_image_library_d88_d77","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyas-sim%2Ffloppy_image_library_d88_d77/lists"}