I have been dumping my OS65D diskettes using the C3dump utility (http://osi.marks-lab.com/software/tools.html) and capturing the disk images via the serial port. The result is a text file with the disk image saved as ascii hex. I wanted to convert them to binary but more importantly I needed to make sure the disk image was valid with all the correct track/sector formatting. With a little time and C code, the result is the OSI Disk Dump utility.
The program ONLY works on OS65D disk images from 8 inch floppies. I have a few things hardcoded (i.e. 77 tracks) that are specific to 8 inch floppies. It will NOT work on 5.25 inch disk images and will NOT work on OS65U disk images.
BTW.... here are my notes on OS65D disk format, directories, and source files
The help instructions and example usage are listed below. This is a command line utility controlled with either long or short option flags.
The key options are the -e|--examine to examine track/sector information, -d|--directory to display the disk directory, -c|--content to display content and -o|--output to write image to a file. The other options modify the behaviour of these key options.
The examine option can be used to explore the disk image. Examine will display the track/sector information and "guess" at what type of content is on the track. The "guess" algorithms are not sophisticated so do not expect perfection. Adding --verbose to the examine option will display a bit of the track data in hex.
Track 1 Offset: 000f00 Size: 0x0f00 bytes (3840)
Header : 0x000f0b 43 57 01 58
Sector1: 0x000f0f Pages: 5 76 01 05....47 53 - MACHINE CODE
Sector2: 0x001414 Pages: 5 76 02 05....47 53 - MACHINE CODE
Tracks can be specified as:
+ single track: "-t 9" or "--track 9"
+ range of tracks: "-t 0-8" or "--track 0-8"
+ entire disk: "-t all" or "-t 99" or "--track all"
The content option will display the track/sector data in various formats. Hex data is the default. If the track is Basic you can use "--list basic" to see the contents as source code. If the track is assembler source code you can see the content with "--list asm". If the source code is saved across multiple tracks, both these format options will try to load the entire source before displaying results. Be careful using these options on non-source code as the results will be gibberish. The "--list raw" option will display the entire track including the track/sector header bytes in colour. Assuming you are on a ANSI terminal the track header bytes will be green, the sector head will be yellow, the sector footer will be cyan. Some disk images have a few "extra mystery" bytes, these are coloured red.
When writing binary files all the "mystery" characters are removed so that the image is a clean OS65D image. All trackes are padded to be 15 pages long (3840 bytes) and this include all the header format bytes. The OS65D manual says the max sector size is 12 pages. But I noticed many images are padded to be 15 pages. The images are padded with 0xea which is the 6502 NOP instruction. I used this as it is easier to spot than 0x00 which seem to be the favorite default padding byte.
To convert and write the image as binary:
osidd -o outputfilename -b diskimagefile
osidd --output outputfilename --binary diskimagefile
.
.
Hex ascii files are also padded to 15 pages with 0xea bytes. They have a blank line between each sector.
To convert and write the image as ascii hex:
osidd -o outputfilename -a diskimagefile
osidd --output outputfilename --ascii dis
BTW: the file will have unix end-of-line characters, Line Feed "0x0a"
The program was developed on Mint Linux and should compile on any distro with gcc installed. There only dependancies are the standard libraries. A simple "make" should build the program. "make install" will copy the binary to the users $HOME/bin directory.
As for Windows.... this code will compiled and run using Cygwin. You will need to make sure you have "gcc" and "make" installed to compile. I found that the version of gcc on cygwin was different than on Linux and it gave me extra warnings (I did not fix these, sorry). The code still compiled and worked.
The code is available on Github
osidd - OSI Disk Dump
+scan OSI disk image for valid tracks/sector format
+convert disk image from ascii to binary
+display directory information
+display content from tracks
Usage osidd [options] FILE
-e --examine : examine all tracks for valid headers/sectors
-t --track n : track to examine, can be a range 0-4 or all (default)
-d --directory : display directory listing from disk image
-o --output fname : write image to output file
-a --ascii : write disk image in ascii hex
-b --binary : write disk image in binary (default output format)
-c --content : display content of track/sector
-l --list type : list track as basic, asm, hex or raw
--nocolour : turn off colour highlight for raw output
-v, --verbose : enable verbose output
--help : display help and exit
--version : print version information and exit
When displaying content the application will guess the format type.
The format will be one of Basic, Assembler, Data (hex).
This guess can be overridden by the list option. Overriding the with
the wrong format can icreate some very messy output.
The raw format will display the entire track including format bytes with
colour highlights; green=track header, yellow=sector header,
cyan=sector footer, red=filler bytes that are not part of the OS65D format
john@xtrail$ osidd -d micro.img
OS-65D VERSION 3.2
-- DIRECTORY --
FILE NAME TRACK RANGE
------------------------
OS65D3 0 - 8
BEXEC* 9 - 9
CHANGE 10 - 10
CREATE 13 - 14
DELETE 15 - 15
DIR 16 - 16
DIRSRT 17 - 17
RANLST 18 - 19
RENAME 20 - 20
SECDIR 21 - 21
SEQLST 22 - 23
TRACE 24 - 24
ZERO 25 - 26
DUMP 27 - 32
EXMON 33 - 37
MON 38 - 41
WORK1 42 - 45
ROM 46 - 48
MAYOR 49 - 51
TRACE$ 52 - 52
FORTH 53 - 57
BUFFER 58 - 61
MON2 62 - 67
41 ENTRIES FREE OUT OF 64
john@xtrail$ osidd -e -t 0-4 disk.img
Track 0 Offset: 000000 Size: 0x0f00 bytes (3840)
Header 0x000000 22 00 08
Load Address: 0x2200 Pages: 8
Track 1 Offset: 000f00 Size: 0x0f00 bytes (3840)
Header : 0x000f0b 43 57 01 58
Sector1: 0x000f0f Pages: 5 76 01 05....47 53 - MACHINE CODE
Sector2: 0x001414 Pages: 5 76 02 05....47 53 - MACHINE CODE
Track 2 Offset: 001e00 Size: 0x0f00 bytes (3840)
Header : 0x001e0c 43 57 02 58
Sector1: 0x001e10 Pages:11 76 01 0b....47 53 - MACHINE CODE
Track 3 Offset: 002d00 Size: 0x0f00 bytes (3840)
Header : 0x002d0b 43 57 03 58
Sector1: 0x002d0f Pages:11 76 01 0b....47 53 - MACHINE CODE
Track 4 Offset: 003c00 Size: 0x0f00 bytes (3840)
Header : 0x003c0b 43 57 04 58
Sector1: 0x003c10 Pages:11 76 01 0b....47 53 - MACHINE CODE
john@xtrail$ osidd -ev -t 10 disk.img
Disk Image: 295680 bytes (0x048300)
Track 10 Offset: 009600 Size: 0x0f00 bytes (3840)
Header : 0x00960b 43 57 10 58
Sector1: 0x00960f Pages:11 76 01 0b....47 53 - BASIC
Data: Sector 1
000000 7f 31 2a 34 01 00 8d 31 05 00 44 56 ab 31 3a 20 |.1*4...1..DV.1: |
000010 88 32 30 00 a6 31 0a 00 84 20 22 44 45 56 49 43 |.20..1... "DEVIC|
000020 45 20 4e 55 4d 42 45 52 22 3b 44 56 00 ac 31 14 |E NUMBER";DV..1.|
000030 00 8e 00 b5 31 1e 00 4e 46 ab 30 00 c2 31 28 00 |....1..NF.0..1(.|
john@xtrail$ osidd -c -t 10 disk.img
Track10: Sector1: Pages: 0x0b (11) BASIC
003179 7f 31 2a 34 01 00 8d 31 05 00 44 56 ab 31 3a 20 |.1*4...1..DV.1: |
003189 88 32 30 00 a6 31 0a 00 84 20 22 44 45 56 49 43 |.20..1... "DEVIC|
003199 45 20 4e 55 4d 42 45 52 22 3b 44 56 00 ac 31 14 |E NUMBER";DV..1.|
0031a9 00 8e 00 b5 31 1e 00 4e 46 ab 30 00 c2 31 28 00 |....1..NF.0..1(.|
0031b9 50 4e ab 31 31 38 39 37 00 e6 31 32 00 95 20 9e |PN.11897..12.. .|
0031c9 41 28 58 29 ab 31 30 a5 ae 28 58 a6 31 36 29 a3 |A(X).10..(X.16).|
0031d9 58 a4 31 36 a5 ae 28 58 a6 31 36 29 00 ec 31 10 |X.16..(X.16)..1.|
0031e9 27 8e 00 08 32 1a 27 8e 20 50 52 49 4e 54 20 41 |'...2.'. PRINT A|
0031f9 20 44 49 52 45 43 54 4f 52 59 20 4f 55 54 00 0e | DIRECTORY OUT..|
003209 32 24 27 8e 00 3a 32 2e 27 97 3a 97 3a 97 3a 97 |2$'..:2.'.:.:.:.|
003219 20 23 44 56 20 3a 97 20 23 44 56 2c 22 4f 53 2d | #DV :. #DV,"OS-|
003229 36 35 44 20 56 45 52 53 49 4f 4e 20 33 2e 32 22 |65D VERSION 3.2"|
003239 00 5f 32 33 27 97 20 23 44 56 2c 22 20 2d 2d 20 |._23'. #DV," -- |
003249 44 49 52 45 43 54 4f 52 59 20 2d 2d 22 20 3a 20 |DIRECTORY --" : |
003259 97 20 23 44 56 00 84 32 38 27 97 20 23 44 56 2c |. #DV..28'. #DV,|
003269 22 46 49 4c 45 20 4e 41 4d 45 20 20 20 20 54 52 |"FILE NAME TR|
003279 41 43 4b 20 52 41 4e 47 45 22 00 a9 32 42 27 97 |ACK RANGE"..2B'.|
003289 20 23 44 56 2c 22 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d | #DV,"----------|
003299 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 22 00 |--------------".|
0032a9 c2 32 4c 27 94 20 21 20 22 43 41 4c 4c 20 32 45 |.2L'. ! "CALL 2E|"
john@xtrail ~/src/osi $ osidd -c -t 10 -l basic disk.img
<317f> Start Address
<318d> 5 DV=1: GOTO20
<31a6> 10 INPUT "DEVICE NUMBER";DV
<31ac> 20 REM
<31b5> 30 NF=0
<31c2> 40 PN=11897
<31e6> 50 DEF FNA(X)=10*INT(X/16)+X-16*INT(X/16)
<31ec> 10000 REM
<3208> 10010 REM PRINT A DIRECTORY OUT
<320e> 10020 REM
<323a> 10030 PRINT:PRINT:PRINT:PRINT #DV :PRINT #DV,"OS-65D VERSION 3.2"
<325f> 10035 PRINT #DV," -- DIRECTORY --" : PRINT #DV
<3284> 10040 PRINT #DV,"FILE NAME TRACK RANGE"
<32a9> 10050 PRINT #DV,"------------------------"
<32c2> 10060 SAVE ! "CALL 2E79=08,1"
<32ce> 10070 GOSUB 11000
<32e7> 10080 SAVE ! "CALL 2E79=08,2"
<32f3> 10090 GOSUB 11000
<3329> 10130 PRINT #DV : PRINT #DV,NF;"ENTRIES FREE OUT OF 64" : PRINT #DV
<332f> 10140 END
<3335> 11000 REM
<3364> 11010 REM READ DIRECTORY OUT OF BUFFER INTO ARRAYS
<336a> 11020 REM
<3382> 11040 FOR I=PN TO PN+248 STEP 8
<33a4> 11050 IF PEEK(I)=35 THEN NF=NF+1 : GOTO 11130
<33ae> 11060 N$=""
<33be> 11070 FOR J=I TO I+5
<33d0> 11080 N$=N$+CHR$(PEEK(J))
<33d8> 11090 NEXT J
<33ff> 11100 PRINT #DV,N$;TAB(12);FNA(PEEK(I+6));TAB(16);"-";
<3419> 11110 PRINT #DV,TAB(17);FNA(PEEK(I+7))
<3421> 11130 NEXT I
<3427> 11140 RETURN
<342a> End Address
Track Header = Green S ector Header = Yellow S ector Footer = Cyan Mystery Bytes = Red
Mystery bytes seem to be spurious bytes after the index hole and before the track header and sometime between sectors.
2016/01/02