PC-copy 64
What is it?
Create GCR-images of a floppy by reading the data (almost) directly from the surface itself.(Still an idea I'm working out )
C64-emulators mostly use D64-files as diskimages of original C64-floppies. Such an image only contains the data of a floppy. A real floppy does not only contain data but also things as blockheaders, dataheaders and SYNC-characters. To make it even more difficult, the data itself is GCR-coded. But sometimes you need ALL the bytes from a disk. Most times in case of a disk with an copy protection.
Creating such a 1-to-1 diskimage can done by connecting a 1541 directly to a PC using a X1541-cable or, much faster, a XP1541-cable. But it still involves some very intelligent ie. difficult programming of the 1541. Maybe such a program already exists but then I still wonder if it is capable of handling all the devilish copy protections that I know off.
So the idea raised to use a way of reading the disk nobody has thought about before (AFAIK): reading the data directly from port A of 6522#2 using the LPT-port of a PC!
History
The idea raised while working at PC-Flop . This project has as goal to let a PC emulating the actual floppydrive: the mechanical drive and some electronics is removed and replaced by a cable connected to the LPT-port of the PC. Instead of storing the data on a floppy disk, the data is stored by the PC on the harddisk. This is done in such a way that certain features used by copy protections are covered.The normal procedure of copying files would be loading files from disk using an original 1541 and storing them on the PC-Flop-drive. The needed time depends on the PRG used to perform the job.
If you read the document about transferring data from/to a floppy disk, you'll see that all the data passes port A of the 6522. So my idea was to read the data directly from the pins of port A by the PC.
Theory
My very first idea was only using a cable. But during the process of writing this document, I discovered that that most likely was impossible because of two problems.- The distance between two bits varies from three to four uSec. This is also the time the data on port A is valid. In this time the PC has to detect that the data is valid and to read it then. But there is no guarantee that this is the valid byte. So I needed to latch the data like the 6522 does. A 74ALS574 latches 8 bits whenever a positive edge occurs on its clock-input. The "byte ready"-signal is a negative edge so we need to invert this first. Thus we also need an inverter.
- Then I found out that SYNC-characters don't generate a "Byte ready"-signal. As long as there are 10 ones in a row, UC3 won't count as it is constantly in a pre-load state. At this moment I only have a software solution.
Realisation (partly theory for the moment !)
First we need an inverter. We could add another IC but studying the schematic of the 1540 reveals that UC7, a 74LS02 NOR, has a free gate: #1, pin 1, 2 and 3. Disconnect pin 1 and 2 from ground and we have our inverter.The 1541 (#1540049-02 rev. B) has two free inverter-gates: UA1 #4 (44LS14) and UC5 #3 (74LS04). I don't know if the inputs have been connected to GND.
At this moment I cannot tell you if the boards of the 1541C and 1541-II have any free inverter-gates. If not, then we have to add a 74LS04 and to use one of its gates.
Whatever inverter-gate we use, its input has to be connected to the "Byte ready"-signal at pin 40 of 6522#2.
We add the 74ALS574 to the board by piggybacking it on top of 6522#2 by connecting pin 2..9 of the 574 with pin 2..9 of 6522#2. Pin 20 is connected to +5V and pin 1 and 10 are connected to ground. Pin 11 has to be connected to the output of the inverter mentioned above. Pin 12 to 19 are connected to the cable leading to the LPT-port.
The following pins of 6522#2 are connected to the cable as well:
6522 LPT
Name Meaning pin name pin
---- ------- --- ---------- ---
CA1 BRDY 40 Acknowl. 10 (I)
PB7 SYNC 17 Busy 11 (I)
PB0 Stp1 10 Select 13 (I)
PB1 Stp0 11 Paper out 12 (I)
3BC,378,278 = Printerdata
3BD,379,279 = Printerstatus
bit 0 = not used
bit 1 = not used
bit 2 = not used
bit 3 = error (15)
bit 4 = select (13)
bit 5 = paper end (12)
bit 6 = acknowledge (10)
bit 7 = busy (11)
3BE,37A,27A = Printercontrol
bit 0 = strobe (1)
bit 1 = autofeed (14)
bit 2 = Initialise (16)
bit 3 = select out (17)
bit 4 = enable IRQ7
bit 5 = dataport direction
bit 6 = not used
bit 7 = not used
Control after reset: $CC
The software
We need software for the C= host as well as for the PC.- C=
The PRG for the C= can be a Basic program which sends a small ML-program to the 1541 and commands the drive to execute it. The ML start the drive motor, positions the head above track 18 and then above track 1, waits for two seconds and then steps to each (half-) track with intervals of a second. When at track 41 (???) it positions the head above track 18 and stops the drive motor. - PC
The PC waits until the head starts to move and then stops moving for at least one second. This is the signal for the PC to save the data read at port A into a 16 KB-buffer the moment the "Byte ready"-signal occurs.
And now the SW-solution to determine how long the gap with SYNC-chars is. The time between the moment the SYNC-signal becomes active and the first "Byte ready"-signal is measured. We know the time between two bits so the number of bits can be calculated. We have to subtract the value eight for the last byte and the number of ones the last valid byte was ending with. The resulting number is divided by eight and we have the number of bytes.
Realisation (the practice)
Unfortunately I haven't good news until so far. I started with a simple BASIC-PRG on my C64 that does nothing else poking values into the memorymap of the 1541 using the "M-R"- and "M-W"-command. This way enabled me to start/stop the drivemotor, to change the track and to change the "Density Select". A small ML-PRG did nothing else then monitoring the BREADY line and putting the read value in a 16 KB-array. The problem is that I simply do not recognise the data the PC has read. I know the header of every sector contains five $55 bytes in a row. I simply don't find them :( So what is going wrong ????(to be continued....)
Let the PC take control.....
As stated above, we need a program for the PC as well as for the C= . Why not let the PC take control of the drive? In that case the PC decides what track will be read at what frequency. The hardware will be manipulated in such a way that cannot be used in the normal way. So the alterations have to be done in such a way that it can be undone.The only thing we have to do is to place two extra sockets between the 6522 and its original socket. All pins are connected to each other by means of soldering with the exception of:
- PA0..7 (pin 2..9, bidir.): used to transfer data
- CB2 (pin 19, out): direction of the data (H: read, L: write)
- PB0..1 (pin 10..11, out): lines to steer the steppingmotor
- PB2 (pin 12, out): motor on/off
- PB5..6 (pin 15..16, out): lines to select density
- CA2 (pin 39, out): disable SO-input of 6502
As you can see there are 8 bi-directional lines and 7 outputs. A bi-directional printer port of a PC has 8 bi-directional lines, 5 inputs and 4 outputs. You can see this doesn't match.
We don't need to disable the SO-input of the 6502 so we can tie to line, NOT the pin, to +5V. We only want to read data so the line to CB2 can be connected to +5V as well. If we install a switch for turning on/off the drivemotor manually, we reduced the needed signals to four.
The following table shows all the needed connections. But again, the lines towards the pins are meant, NOT the pins themselves !!!
6522 LPT
Name Meaning pin name pin
---- ------- --- ---------- ---
CA1 BRDY 40 Acknowl. 10 (I)
PB7 SYNC 17 Busy 11 (I)
PB0 Stp1 10 Strobe 1 (O)
PB1 Stp0 11 Auto feed 14 (O)
PB5 DS0 15 Initialise 16 (O)
PB6 DS1 16 Select out 17 (O)
3BC,378,278 = Printerdata
3BD,379,279 = Printerstatus
bit 0 = not used
bit 1 = not used
bit 2 = not used
bit 3 = error (15)
bit 4 = select (13)
bit 5 = paper end (12)
bit 6 = acknowledge (10)
bit 7 = busy (11)
3BE,37A,27A = Printercontrol
bit 0 = strobe (1)
bit 1 = autofeed (14)
bit 2 = Initialise (16)
bit 3 = select out (17)
bit 4 = enable IRQ7
bit 5 = dataport direction
bit 6 = not used
bit 7 = not used
Control after reset: $CC
I could now starting theorising about the software but that is IMHO a little bit to pre-mature right now.
Having questions or comment? You want more Info?
You can email me here.