VOGONS


First post, by anetanel

User metadata
Rank Member
Rank
Member

I backed up an old kids software floppy that uses Eliashim's CodeSafe protection, with Kryoflux, and converted the image to a PSI file.
These are the commands that I used:

pfi /Users/netanel/Documents/Floppies/ktavkat/track00.0.raw ktavkat.pfi
pfi ktavkat.pfi -p decode pri ktavkat.pri
pri ktavkat.pri -p decode mfm ktavkat.psi

I'm able to load the PSI file in PCE, but when running the executable (k.exe), it seems that the floppy controller is sent an illegal command and errors.
The error message in the emulator console is:

E8272: CMD=71 D=? INVALID

in the emulator window, the copy protection displays an error "Floppy Disk Controller Failure", and any further access to the floppy hangs the emulator, and repeating error messages appear in console:

0000:2F2C: undefined operation [C8 a5]
0000:2F2E: undefined operation [C8 a5]
0000:2F30: undefined operation [C8 a5]
0000:2FCD: undefined operation [66 02]
0000:2FD4: undefined operation [67 03]

I had success loading another copy protected floppy image (Loom) in PCE, so I know that my method should work.
I'm also able to write the flux backup back to an empty floppy, and it works on a real 386 machine. So the backup is file too.

Digging a bit in the emulator code, it seems that whatever CMD=71 is, it is not implemented in the floppy controller emulator.

(e8727.c)

static
void cmd_invalid (e8272_t *fdc)
{
#if E8272_DEBUG >= 0
fprintf (stderr, "E8272: CMD=%02X D=? INVALID\n", fdc->cmd[0]);
#endif

fdc->res[0] = 0x80;

cmd_result (fdc, 1);
}


static struct {
unsigned char mask;
unsigned char val;
unsigned cnt;
void (*start_cmd) (e8272_t *fdc);
} cmd_tab[] = {
{ 0x1f, 0x06, 9, cmd_read },
{ 0x1f, 0x0c, 9, cmd_read_deleted },
{ 0x1f, 0x02, 9, cmd_read_track },
{ 0x3f, 0x0a, 2, cmd_read_id },
{ 0x3f, 0x05, 9, cmd_write },
{ 0x3f, 0x0d, 6, cmd_format },
{ 0xff, 0x07, 2, cmd_recalibrate },
{ 0xff, 0x0f, 3, cmd_seek },
{ 0xff, 0x08, 1, cmd_sense_int_status },
{ 0xff, 0x04, 2, cmd_sense_drive_status },
{ 0xff, 0x03, 3, cmd_specify },
{ 0x00, 0x00, 1, cmd_invalid }
};

I was not able to find (yet) what 71 is. My C skills are very rudimentary, and I'm not sure even if this is 71 in decimal or hex...
I've attached the PSI file, for anyone to take a shot at it.
Any help is appreciated!

Attachments

Reply 1 of 21, by GloriousCow

User metadata
Rank Member
Rank
Member

If we use the command mask 1F, 71 & 1F = 11. 11 is not a valid command that I am aware of. Programming the FDC involves writing several bytes in succession for the operands of different commands. If an earlier command was valid but not implemented and its operands ignored, then its possible that the unhandled operands could get interpreted as new commands. But that's speculation without looking at the source code. Do any of the listed cmd_* functions appear to be stubs?

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 2 of 21, by myne

User metadata
Rank Member
Rank
Member

Don't know if this will help
https://www.ardent-tool.com/floppy/Floppy_Programming.html

Might be barking up the wrong tree, but it looks like 7h is calibrate drive.

Things I built:
Mechwarrior 2 installer for Windows 10/11 Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11 auto-install iso template (for vmware)
Script to backup Win9x\ME drivers from a working install

Reply 3 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++
myne wrote on 2024-05-27, 00:57:

Don't know if this will help
https://www.ardent-tool.com/floppy/Floppy_Programming.html

Might be barking up the wrong tree, but it looks like 7h is calibrate drive.

71h on a ATA hard disk is seek using head 1?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 21, by myne

User metadata
Rank Member
Rank
Member

"Recalibrate command = 0x7
First parameter byte = drive number = 0 to 3."

https://wiki.osdev.org/Floppy_Disk_Controller

Again, I have no idea what I'm on about, but that looks like it wants to recalibrate b:

Maybe?

It seems like it's going to be wrong because who writes a game requiring it to be on a specific drive letter, but I guess the way to test is to try 2 drives in the emulator and see if it changes.

Things I built:
Mechwarrior 2 installer for Windows 10/11 Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11 auto-install iso template (for vmware)
Script to backup Win9x\ME drivers from a working install

Reply 5 of 21, by anetanel

User metadata
Rank Member
Rank
Member
GloriousCow wrote on 2024-05-26, 17:59:

If we use the command mask 1F, 71 & 1F = 11. 11 is not a valid command that I am aware of. Programming the FDC involves writing several bytes in succession for the operands of different commands. If an earlier command was valid but not implemented and its operands ignored, then its possible that the unhandled operands could get interpreted as new commands. But that's speculation without looking at the source code. Do any of the listed cmd_* functions appear to be stubs?

I'm not sure what stubs means 😅
The source code is available here:
http://www.hampa.ch/pub/pce/pre/pce-20240122- … 5a67b2a9.tar.gz
Sadly the project is not hosted in github or such platform. There are forks of it in github, but as far as I can tell, they are all several years old, and there are changes (including in the e8727.c file) that were not merged yet.

EDIT:
I think I understand what you mean by stubs.
As far as I can understand, all the functions in the cmd_tab are implementet with actual code in them.

Last edited by anetanel on 2024-05-27, 07:34. Edited 1 time in total.

Reply 6 of 21, by anetanel

User metadata
Rank Member
Rank
Member
myne wrote on 2024-05-27, 03:08:
"Recalibrate command = 0x7 First parameter byte = drive number = 0 to 3." […]
Show full quote

"Recalibrate command = 0x7
First parameter byte = drive number = 0 to 3."

https://wiki.osdev.org/Floppy_Disk_Controller

Again, I have no idea what I'm on about, but that looks like it wants to recalibrate b:

Maybe?

It seems like it's going to be wrong because who writes a game requiring it to be on a specific drive letter, but I guess the way to test is to try 2 drives in the emulator and see if it changes.

I configured the emulator to use only 2 floppy drives instead of the default 4, and mounted the image on both drives. I tried running the executable from both drives, but got the same errors.

Reply 7 of 21, by anetanel

User metadata
Rank Member
Rank
Member

I recompiled the emulator with E8272_DEBUG set to 5. This is the output around the error:

E8272: read data: FB
E8272: read data: 00
E8272: read data: 00
E8272: read data: 00
E8272: read data: 00
E8272: read data: 00
E8272: read data: 00
E8272: TC
E8272: CMD=42 D=0 READ TRACK TC
E8272: irq = 1
E8272: get 0004 -> d0
E8272: irq = 0
E8272: get result (04)
E8272: read data: 04
E8272: get 0005 -> 04
E8272: get 0004 -> d0
E8272: get result (04)
E8272: read data: 04
E8272: get 0005 -> 04
E8272: get 0004 -> d0
E8272: get result (00)
E8272: read data: 00
E8272: get 0005 -> 00
E8272: get 0004 -> d0
E8272: get result (27)
E8272: read data: 27
E8272: get 0005 -> 27
E8272: get 0004 -> d0
E8272: get result (00)
E8272: read data: 00
E8272: get 0005 -> 00
E8272: get 0004 -> d0
E8272: get result (05)
E8272: read data: 05
E8272: get 0005 -> 05
E8272: get 0004 -> d0
E8272: get result (06)
E8272: read data: 06
E8272: get 0005 -> 06
E8272: get 0004 -> 80
E8272: get 0004 -> 80
E8272: set 0005 <- 71
E8272: CMD=71 D=? INVALID
E8272: get 0004 -> d0
E8272: get 0004 -> d0
E8272: get 0004 -> d0
.
.

The last line is repeated around 65k time....
I need to try and make sense of it.

Reply 8 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

If you can convert the disk image to a .imd disk image file, you can try it in UniPCemu.
UniPCemu tries to emulate the physical disk layout (including seeking etc.), maybe that's going wrong somehow?
It might be reading the entire track incorrectly (wrong sector orders etc.)? Since it uses a read track command (as opposed to read sector)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 21, by anetanel

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-05-27, 10:31:

If you can convert the disk image to a .imd disk image file, you can try it in UniPCemu.
UniPCemu tries to emulate the physical disk layout (including seeking etc.), maybe that's going wrong somehow?
It might be reading the entire track incorrectly (wrong sector orders etc.)? Since it uses a read track command (as opposed to read sector)?

I'll give it a shot. I'll need to use my windows machine, as I don't see a Mac OS version.

Reply 10 of 21, by coolhaken

User metadata
Rank Newbie
Rank
Newbie

Is it possible that there are some hidden data in sector gaps, and this app use it as part of future FDC operation code ?
A psi image will not include hidden data in sector gaps unless doing some manually conversion.
Can you upload the kryoflux raws for testing ?

Reply 11 of 21, by anetanel

User metadata
Rank Member
Rank
Member
coolhaken wrote on 2024-05-28, 11:00:

Is it possible that there are some hidden data in sector gaps, and this app use it as part of future FDC operation code ?
A psi image will not include hidden data in sector gaps unless doing some manually conversion.
Can you upload the kryoflux raws for testing ?

Sure!
I had to split the files. Just remove the last 7z extension.

Attachments

  • Filename
    Archive.7z.002.7z
    File size
    1.45 MiB
    Downloads
    28 downloads
    File license
    Public domain
  • Filename
    Archive.7z.001.7z
    File size
    4.77 MiB
    Downloads
    32 downloads
    File license
    Public domain

Reply 12 of 21, by Battler

User metadata
Rank Member
Rank
Member
GloriousCow wrote on 2024-05-26, 17:59:

If we use the command mask 1F, 71 & 1F = 11. 11 is not a valid command that I am aware of. Programming the FDC involves writing several bytes in succession for the operands of different commands. If an earlier command was valid but not implemented and its operands ignored, then its possible that the unhandled operands could get interpreted as new commands. But that's speculation without looking at the source code. Do any of the listed cmd_* functions appear to be stubs?

If the 71 is decimal, that would be 45h which & 1Fh would be 05h, which is the write command.

Edit: No, it's 71h, so hex. Then it would indeed be command 11h, which is the SCAN EQUAL command.

Edit #2: The upper 3 bits for the SCAN EQUAL command are: MT (multi-track = read both sides), MF (1 = MFM, 0 = FM), SK (skip sectors with the wrong kind of address mark). So 71h is SCAN EQUAL with MF and SK set. I believe some Intel FDC's don't implement the three SCAN commands (11h = SCAN EQUAL, 19h = SCAN LOW OR EQUAL, and 1Dh = SCAN HIGH OR EQUAL).

Reply 13 of 21, by coolhaken

User metadata
Rank Newbie
Rank
Newbie

The psi image converted from kryoflux dump works.
Attached.

pce0002.png
Filename
pce0002.png
File size
1.81 KiB
Views
894 views
File license
Public domain
pce0003.png
Filename
pce0003.png
File size
715 Bytes
Views
894 views
File license
Public domain
Filename
disk.7z
File size
168.13 KiB
Downloads
21 downloads
File license
Public domain

Reply 14 of 21, by anetanel

User metadata
Rank Member
Rank
Member
coolhaken wrote on 2024-05-29, 11:55:
The psi image converted from kryoflux dump works. Attached. pce0002.png pce0003.png disk.7z […]
Show full quote

The psi image converted from kryoflux dump works.
Attached.
pce0002.png
pce0003.png
disk.7z

Amazing!
Can you elaborate what you did?
Is this running in PCE?

Reply 15 of 21, by coolhaken

User metadata
Rank Newbie
Rank
Newbie

Yes, this is running in PCE.

Do the following steps,

pfi track00.0.raw -s weak-bits 1 -p decode pri disk.pri
pri disk.pri -p decode mfm disk1.psi
pri disk.pri -c 7 -s mfm-min-size 8192 -p decode mfm disk.psi
psi disk.psi -r 0-6 0-1 all -m disk1.psi disk.psi
psi disk.psi -r 8-39 0-1 all -m disk1.psi disk.psi
psi disk.psi -r 7 0-1 all -e crc-data 0 disk.psi
psi disk.psi -p comment-set "" disk.psi

Then you can get the working psi image.

Reply 16 of 21, by anetanel

User metadata
Rank Member
Rank
Member
coolhaken wrote on 2024-05-29, 12:09:
Yes, this is running in PCE. […]
Show full quote

Yes, this is running in PCE.

Do the following steps,

pfi track00.0.raw -s weak-bits 1 -p decode pri disk.pri
pri disk.pri -p decode mfm disk1.psi
pri disk.pri -c 7 -s mfm-min-size 8192 -p decode mfm disk.psi
psi disk.psi -r 0-6 0-1 all -m disk1.psi disk.psi
psi disk.psi -r 8-39 0-1 all -m disk1.psi disk.psi
psi disk.psi -r 7 0-1 all -e crc-data 0 disk.psi
psi disk.psi -p comment-set "" disk.psi

Then you can get the working psi image.

errr.... wot? 🤯

Could you explain how you came up with these parameters?
Is it tailored to this disk, or is it something that should work for all backups?

Reply 17 of 21, by coolhaken

User metadata
Rank Newbie
Rank
Newbie

This is for Eliashim's CodeSafe protection locate on track 7.

pfi track00.0.raw -s weak-bits 1 -p decode pri disk.pri
// convert KF raws to the bitstream pri format and detect weak bits.

pri disk.pri -p decode mfm disk1.psi

pri disk.pri -c 7 -s mfm-min-size 8192 -p decode mfm disk.psi
// decode only track 7 and read 8192 bytes for every sector, thus data in sector gaps will be included.

psi disk.psi -r 0-6 0-1 all -m disk1.psi disk.psi
// merge all data of track 0 to track 6 to the destination disk.psi

psi disk.psi -r 8-39 0-1 all -m disk1.psi disk.psi
// merge all data of track 8 to track 39 to the destination disk.psi

psi disk.psi -r 7 0-1 all -e crc-data 0 disk.psi
// clear the crc-data flag on track 7 caused by reading 8192 bytes.

psi disk.psi -p comment-set "" disk.psi
// clear the comment generated by DTC.

Reply 18 of 21, by anetanel

User metadata
Rank Member
Rank
Member
coolhaken wrote on 2024-05-30, 11:37:
This is for Eliashim's CodeSafe protection locate on track 7. […]
Show full quote

This is for Eliashim's CodeSafe protection locate on track 7.

pfi track00.0.raw -s weak-bits 1 -p decode pri disk.pri
// convert KF raws to the bitstream pri format and detect weak bits.

pri disk.pri -p decode mfm disk1.psi

pri disk.pri -c 7 -s mfm-min-size 8192 -p decode mfm disk.psi
// decode only track 7 and read 8192 bytes for every sector, thus data in sector gaps will be included.

psi disk.psi -r 0-6 0-1 all -m disk1.psi disk.psi
// merge all data of track 0 to track 6 to the destination disk.psi

psi disk.psi -r 8-39 0-1 all -m disk1.psi disk.psi
// merge all data of track 8 to track 39 to the destination disk.psi

psi disk.psi -r 7 0-1 all -e crc-data 0 disk.psi
// clear the crc-data flag on track 7 caused by reading 8192 bytes.

psi disk.psi -p comment-set "" disk.psi
// clear the comment generated by DTC.

Very interesting. Thank you for the explanation!
So if I understand correctly, the problem with my method of creating the PSI file, was that I did not instruct psi to read ALL the data on the disk, but rather only the data from the expected "normal" sectors, and not the data between the sectors that is part of the protection?
It is possible to somehow always read all the data, without knowing in advance where the protection is?

Reply 19 of 21, by coolhaken

User metadata
Rank Newbie
Rank
Newbie

Although we can store more data in a psi image, it is not accurately.
True sector size is vary and basically not 8192 bytes.
Some protection method may check lenth of gaps, and some others may check CRC-error flag.
Another flaw is such a psi image will be in large size.
Manually converting psi images is only an interim solution.

All you need is a pri image, it contains everything, but PCE doesn't support it directly for now.

There are similar image format, such as .mfm, .hfe, .hfe3, .tc, .86f.
HxC floppy emulator software can help you to convert KF dumps to .mfm and .hfe file.

MAME supports .mfm, 86Box supports .mfm, .hfe and it's native .86f format.
However, none of the above emulators fully simulates the operation of FDC.

You can report an issue on 86Box's github and expect it will support Eliashim's CodeSafe and more protection types someday.