Thursday, March 20, 2014

Reading and Writing diskettes with Cromemco cscopy


Overview
Moving data between Vintage Cromemco computers and modern day 21st century Linux/OSX/Windows computers is non trivial.

Apart from transmission over serial cables which in practice is limited to about 4800 bits per second  (bps) we have one other practical option.




The 360K Floppy Disk.

cscopy is a utility program which can take a DOS formatted 360K diskette and read and write to it on the Cromemco computer.

Although


  • Vintage computers often used the Western Digital WS FD179X floppy controller hardware.   This is somewhat incompatible with the more modern PC hardware chips
  • Many modern PC's don't have any floppy drives or hardware at all and in some of the latest BIOS there is no floppy support
  • If PC's do provide floppy support it is for 3.5" 1.44 MB diskettes which are over 10 years too young for Cromemco computers
  • Assuming you do have a 360K floppy drive attached to your PC, modern Windows OS don't fully support it, nor Linux   (I will cover this in depth in a later article)

Assumptions
We will try to use the most common
IBM PC  360K Disk Format == 
40 tracks
9, 512 byte sectors per track
300 RPM
Double Sided
Double Density MFM recording
Data Rate 250K

There were other formats
a) 8 instead of 9, 512 byte sectors per track leading to 320K disks
b) My liked IBM Internal Dos 3.11.  This managed to squeeze 10, 512 byte sectors onto each track, meaning your disks were not readable outside IBM.

Now lets compare the special Cromix UNIFORM disk format, available only with its 68000 Cromix (I mean not available on Z80 Cromix)


USDSDDST 40 tracks, 300RPM, double sided, 9 sectors per track, 512 bytes per sector,  250K DD throughout

initflop  -u 512 -v /dev/usfda
Device name: /dev/usfda
Rotational speed:       301 RPM
Uniform disk with 512 byte sectors
Double sided    Double density
First cylinder: 0.
Last cylinder: 39.
All surfaces

Surface,Cylinder
1       11

In practice I had better luck formatting the interchange diskette on the PC side  (under my OS which is Windows 2012 Storage Server)


Once initialised, placing disk into Cromemco
cscopy -l
   name         size  cluster  attributes    modified time


Disk space available: 362496 bytes


Writing to Floppy at Cromix Side
d /bin
cscopy -vw [a-h]**
DOS File System:  /dev/dos_drive (device file)
Configuration:    2 Sides, 9 Sectors per track, 40 Tracks

access.bin       1493 bytes copied
account.bin      5598 bytes copied
blink.bin        5173 bytes copied
boot.bin         1467 bytes copied
ccall.bin        8385 bytes copied
cdoscopy.bin    12400 bytes copied


If you only have a few small files to transfer simply take the disk to the PC and read using Explorer.  The same can be done in reverse, write files from PC to diskette on PC. Take to Cromemco and use cscopy to read the files instead  (cscopy -v file1 file2 ...)


Writing Long Names
Since the older DOS diskette filesystem in 1986 could only handle 8.3 filenames, to package Cromix names it's best to put the files inside a tar package, then split this package into files of diskette sizes.

This also avoids your PC capitalising names which is quite annoying. I'll show an example here were the tar file is bigger than a diskette, so once made we need to split into chunks ...


ftar -cuv /tmp/bindir.tar .
# note -k option does not work so not used

Not dumped: "."

Creating "./boot.bin" 1,467 bytes
Creating "./copy.bin" 3,834 bytes
Creating "./cptree.bin" 7,319 bytes
Creating "./dcheck.bin" 5,988 bytes
Creating "./diskinfo.bin" 7,288 bytes
Creating "./dump.bin" 6,155 bytes
Creating "./echo.bin" 897 bytes
Creating "./free.bin" 2,887 bytes
Creating "./ftar.bin" 17,892 bytes
Creating "./icheck.bin" 7,506 bytes
Creating "./idump.bin" 5,054 bytes
Creating "./initflop.bin" 10,153 bytes
Creating "./inithard.bin" 15,708 bytes
....
Creating "./patchbug.bin" 3,702 bytes
Creating "./link68.bin" 31,232 bytes
Creating "./scitoh.com" 9,984 bytes
Creating "./debug.com" 9,984 bytes
Creating "./cscopy.bin" 55,808 bytes
system[54] ftar -cuv -k 354 /tmp/bindir.tar .
system[54] ls -l /tmp

Directory: /tmp
    786,432    1   rewa re-- re-- system      Mar-18 03:08  bindir.tar


split -b 708 bindir.tar bindir
ls -l
    362,496    1   rewa re-- re-- system      Mar-18 03:24  bindir.aa
    362,496    1   rewa re-- re-- system      Mar-18 03:25  bindir.ab
     61,440    1   rewa re-- re-- system      Mar-18 03:25  bindir.ac
    786,432    1   rewa re-- re-- system      Mar-18 03:08  bindir.tar

Now transfer the files onto diskette

I timed each transfer at about 3.25 minutes thus:

time;cscopy -vw bindir.aa; time
       Wednesday, March 19, 2014            03:49:47
DOS File System:  /dev/dos_drive (device file)
Configuration:    2 Sides, 9 Sectors per track, 40 Tracks

bindir.aa      362496 bytes copied

       Wednesday, March 19, 2014            03:53:09


And a Copy at the PC side with cygwin takes about 36 seconds
mbennett@littlepaw /tmp
$ mount
C:/cygwin/bin on /usr/bin type ntfs (binary,auto)
C:/cygwin/lib on /usr/lib type ntfs (binary,auto)
C:/cygwin on / type ntfs (binary,auto)
A: on /cygdrive/a type vfat (binary,user)
C: on /cygdrive/c type ntfs (binary,posix=0,user,noumount,auto)
mbennett@littlepaw /tmp
$ time cp /cygdrive/a/bindir.aa .

real    0m35.965s
user    0m0.015s

sys     0m0.015s

The aggregates are now combined using command line 
copy /b 
command or just using cygwin cat

cat bindir.aa bindir.ab bindir.ac  > bindir.tar

Finally winrar or cygwin tar may be used to unpack


mbennett@littlepaw /tmp
$ tar -tvf bindir.tar
-rwx------ 32767/32767    1467 1988-08-11 23:57 ./boot.bin
-rwx--x--x 0/0            3834 1988-08-12 00:04 ./copy.bin
-rwx--x--x 0/0            7319 1988-08-12 00:04 ./cptree.bin
-rwx--x--x 32767/32767    5988 1988-08-12 00:05 ./dcheck.bin
-rwx------ 32767/32767    7288 1988-08-12 00:07 ./diskinfo.bin
-rwx--x--x 32767/32767    6155 1988-08-12 00:07 ./dump.bin
-rwx--x--x 32767/32767     897 1988-08-12 00:07 ./echo.bin
...
-rwx--x--x 32767/32767    2182 1988-08-12 00:29 ./who.bin
-rwx--x--t 0/0           16967 1988-08-12 00:30 ./z80.bin
hrwx--x--x 32767/32767       0 1988-08-12 00:09 ./h.bin link to ./help.bin
-rwx--x--x 0/0           11807 1987-08-21 01:28 ./pckt.bin
-rwx--x--x 32767/32767    6944 1988-08-12 00:18 ./patch.bin
-rwx--x--x 32767/32767   19980 1988-08-12 00:04 ./convobj.bin
-rwx--x--x 0/0            3434 1988-08-12 00:14 ./lstat.bin
-rwx--x--x 32767/32767    3702 1988-08-12 00:18 ./patchbug.bin
-rwxr-xr-x 0/0           31232 2014-03-16 22:13 ./link68.bin
-rwxr-xr-x 0/0            9984 2014-03-16 22:21 ./scitoh.com
-rwxr-xr-x 0/0            9984 2014-03-17 05:37 ./debug.com
-rwx--x--x 0/0           55808 1986-08-12 11:34 ./cscopy.bin
tar: A lone zero block at 1536


Links
Western Digital FD179X Application Notes

ManPage
CScopy-c version  3.02: reads/writes DOS diskettes from CROMIX-PLUS
Copyright (c) 1986 S. J. Gross, Cipher Systems, Box 6105, Stanford, CA 94305
August 12, 1986         Licensed by Cipher Systems.     All Rights Reserved.
usage:  cscopy {options} <first-file> ... <last-file>
option: -a <attributes> set or alter attributes (+-avshr) of DOS file(s)
        -b <boot-file> copy boot block to or from boot-file
        -c correct line terminator during file transfer, DOS:crlf, Cromix:lf
        -d <dos-device> specify DOS diskette device (default /dev/dos_drive)
        -e erase DOS file(s)
        -f force existing file(s) to be overwritten
        -g use group id for DOS attribute bits
        -i initialize DOS diskette
        -l list DOS directory
        -m## make DOS file system #(1|2) sides #(8|9) sectors on diskette
        -n make new DOS directory with path name specified in -p option
        -o <dos-disk-file> specify ordinary file to be used as DOS diskette
        -p <dos-path> specify DOS directory path name on DOS file system
        -q suppress warning and confirmation of hazardous operations
        -r <old-name> <new-name> rename DOS file(s)
        -s# <bios-name> <dos-name> DOS #(2|3) system disk: system file names
        -v verbose
        -w copy to DOS diskette

        -- end of options



cscopy Messages

Cannot open %s file "%s" for use as DOS file system
DOS subdirectory:
ordinary file
device file
DOS File System:  %s (%s)
Configuration:    %1d Sides, %1d Sectors per track, %2d Tracks%s%s
Cannot find file "%s" on DOS file system
No file(s) specified to copy or modify
Cannot find file "%s" on DOS file system
Warning: Cannot modify directory attribute for DOS file "%s"
Cannot find file "%s" on DOS file system
Cannot erase DOS directory "%s"
Erasing empty DOS directory "%s"
Freeing cluster %03x, next is %03x
DOS file %s, deleted, %d bytes, %d clusters freed
DOS sub-directory path: %s
Cannot find file "%s" on DOS file system
No files given to rename
More than two file names specified: %s %s %s ...
Rename requires one old name and one new name per command
Wild card arguments must be enclosed in quotes e.g. "*.bak" "*.old"
No new name given for old name "%s"
Cannot find file "%s" on DOS file system
renaming "%s" as "%s"
Cannot rename "%s" to "%s".
File "%s" already exists.
No files renamed.
Not a DOS directory "%s" in DOS file system "%s"
dosblk: %06x, Track: %02x, Side: %x, Sector: %02x
crxblk: %06x, Track: %02x, Side: %x, Sector: %02x
Internal error: dosfread call must have size = 1, was %d
Requesting %6xh bytes from DOS byte %04x (crx %04x) to memory %08x
Transferring %6xh bytes from DOS byte %04x (crx %04x) to memory %08x
Transfer error for DOS file:
Internal error: dosfwrite call must have size = 1, was %d
requesting %6xh bytes from memory %08x to DOS byte %04x (crx %04x)
Transferring %6xh bytes from memory %08x to DOS byte %04x (crx %04x)
Seek error while writing DOS file
Error writing DOS file system
nwrote = %xh, bytestowrite = %xh, fp = %08xh
Internal error: opendos called with dos file already open
Group attribute option (-g) restricted to user 0 only
Cannot create %s file "%s"
Cannot make DOS file system
%s file "%s" already exists
Cannot make DOS file system
DOS file system: "%s" is not a small DS DD uniform floppy
Access to DOS file system "%s" denied for requested operation
Cannot access mounted device: "%s"
DOS file system: "%s" is write protected
Cannot seek to DOS File Allocation Table at byte %0xh
Not a DOS file system
Invalid DOS File Allocation Table
Not a DOS file system
Not a DOS file system
Unsupported DOS media descriptor byte: %02xh%s
Cannot seek to DOS File Allocation Table at byte %0xh
Not a DOS file system
Cannot read DOS file allocation tables
File Allocation Tables are not consistent
Cannot modify disk with inconsistent DOS File Allocation Tables
Using first copy of DOS File Allocation Table
Error accessing DOS file "%s"
Disk error detected on DOS file system during final close
DOS file system: "%s" is not a small DS DD uniform floppy
Cannot initialize disk
Cannot re-open device "%s" after initialization
cluster %03x, block %d, dosblock %03x, crxblock %03x, Start byte is: %06x
Cannot position to byte %xh on DOS file system
Error reading DOS file system for file "%s"
Read %d bytes of %d requested
total clusters = %04xh
Found free cluster at %04xh, linking to cluster %04xh
Cannot find free cluster before cluster %04xh
total clusters = %04xh
Internal error: FAT modification with illegal cluster: %d
Illegal cluster in FAT: %d
Cannot write allocation table to DOS file system
Error writing allocation table to DOS file system wrote %d bytes of %d
Error writing allocation table to DOS file system wrote %d bytes of %d
Error reading DOS directory "%s"
Error reading DOS directory
Error writing DOS directory
cluster %03x, block %d, dosblock %03x, crxblock %03x, Start byte is: %06x
Cannot position to byte %xh on DOS file system
Error writing DOS sub-directory file "%s"
  on DOS file system "%s"
   name         size  cluster  attributes    modified time
Disk space available: %d bytes
Comparing "%s" with "%s"
DOS file system full while writing file "%s%s%s"
Addentry: "%s"
No room in DOS directory for file "%s"
Cannot extend DOS directory "%s"
Dos file system full while writing file "%s\%s"
Track: %02x, Side: %x, Sector: %02x
crxblk: %06x, Track: %02x, Side: %x, Sector: %02x
Internal error: dosfread call must have size = 1, was %d
Requesting %6xh bytes from DOS byte %04x (crx %04x) to memory %08x
Transferring %6xh bytes from DOS byte %04x (crx %04x) to mem


HomeWork: Investigate the Cromemco Disk Format

A small sidetrack and just interesting.  It asks you to consider what is on the header of a regular Cromemco, i.e.  non Uniform Disk

Most computers of the time including Cromemco used a diskette format whereby the first track, track 0 was encoded using Single Density i.e. FM modulation recording.

Cromemco was no exception, and their first track was FM containing a special boot block and disk identifier

Let's look at a typical disk of the time  (in fact disk 035 from my archive)

# IMDU converting .IMD disk to .DSK so I can open it on a regular winhex 
# then Cromemco Z80 Debugger windows

0035 SMDSDDST
Assuming 1:1 for Binary output
 0/0 250 kbps SD  18x128
 0/1 250 kbps DD  10x512
80 tracks(40/40), 808 sectors (157 Compressed)



Here is the hex representation of the start sector 1, track 0, side 0 of the disk

It's actually part data .. do you see the signature SMDSDD meaning SMall diskette Double Sided and Double Density

When you power on the Cromemco system the boot PROM on the Disk controller is active.  RDOS (Resident Disk Operating System),  that monitor on the disk controller runs code like this  (see this manual)  

You see how this actually reads the first sector from the floppy disk into 0x0080 and then executes it.

To help you I disassembled the code I saw above ...

-l 80
0080  LD   A,01
0082  OUT  40,A
0084  JR   C,008A
0086  SUB  A,A
0087  EX   AF,AF'
0088  LD   D,21
008A  LD   E,7F
008C  LD   HL,0100
008F  LD   BC,020F
0092  LD   A,E
0093  OUT  04,A
0095  BIT  1,E
0097  JR   Z,00AE
0099  LD   A,D
009A  OUT  34,A
009C  LD   A,C
009D  OUT  30,A
009F  SUB  A,A
00A0  DEC  A
00A1  JR   NZ,00A0
00A3  IN   A,34
00A5  RRA
00A6  JR   NC,00A3
00A8  IN   A,30
00AA  AND  A,98
00AC  JR   NZ,0080
00AE  LD   A,B
00AF  OUT  32,A
00B1  LD   A,D
00B2  OR   A,80
00B4  OUT  34,A
00B6  LD   C,33
00B8  LD   A,9C
00BA  OUT  30,A
00BC  IN   A,34
00BE  RRA
00BF  JR   C,00C5
00C1  INI
00C3  JR   00BC
00C5  IN   A,30
00C7  BIT  4,A
00C9  JR   Z,0080
00CB  LD   A,96
00CD  SUB  A,L
00CE  LD   A,19
00D0  SBC  A,H
00D1  JR   C,0100
00D3  LD   A,(00FC)
00D6  CP   A,44
00D8  JR   NZ,00DC
00DA  SET  6,D
00DC  LD   B,01
00DE  LD   A,(00FA)
00E1  CP   A,44
00E3  JR   NZ,00E9

00E5  LD   A,E
00E6  XOR  A,02
00E8  LD   E,A
00E9  LD   C,5F

00EB  JR   0092





Study the RDOS 1.0 manual 1978   Turn to page 8 and look at the 1K disassembly of the monitor PROM.   From that PDF you will see fully how the hex at 0x0076 starts the boot of the computer.

Next consult the 4FDC disk controller manual and turn to page 21 or thereabouts.    Correlate the values written in the above assembler IN and OUT instructions

easy example ..

LD   A,01                                                                 
OUT  40,A 

What does the binary 01 written to port 40 do?