VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

When I look at the FDC documentation, it says some interesting things:
http://cpctech.cpc-live.com/docs/upd765a/necfdc.htm

In ST1:

D7 EN
(End of Cylinder) When the FDC tries to access a sector beyond the final Sector of a Cylinder, this flag is set.

When does this happen? Doesn't the FDC just start once it reaches index, then tries to read(which can't find the CHS on the disk, reaches index again, then errors out with D0 and D2 set(as well as ST2's D0 set)?
Also, what happens when the sectors are scattered accross the disk? Does this case happen in that case as well? What does it consider the 'final Sector of a Cylinder'? Are the sectors that are read required to be next to each other in ascending Sector ID order for this bit not to be set? What about deleted sectors?

In ST2:

D4 WC
(Wrong Cylinder) This bit is related with the ND bit, and when the contents of C(3) on the medium is different from that stored in the IDR, this flag is set.

And

D1 BC
(Bad Cylinder) This bit is related with the ND bit, when the contents of C on the mdeium is different from that stored in the IDR and the contents of C is &FF, then this flag is set.

But, since C won't match when it's not the specified sector ID(which is the combination of C/H/S values in the sector ID on the disk), what happens in that case? Isn't it usually skipped, since the sector ID doesn't match in total(which means CHS doesn't match the requested CHS?)?

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

Reply 2 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

What do you mean with EOT being reached? The final sector on the track or the final sector of any transfer? UniPCemu will terminate the transfer in the following cases:
- Terminal count is set during a DMA transfer.
- EOT is reached(6th byte in the buffer instead of physical amount of sectors per track(which only happens in DMA with MT set)) in non-DMA mode, non-DMA mode and either MT on head 1 or MT=0.

Those are the conditions for the transfer to change to result phase.

I've noticed that the Windows NT 3.1 seems to set TC to after a few sectors(1 for single-sector transfers) and always sets EOT in the 6th byte of the command to a non-changing value(18 I believe)?

Edit: Also, won't WC cause it to error out to result phase? Since the cylinder ID doesn't match the requested C/H/S, it'll probably just skip the sector searching for the specified C/H/S until it either reaches it within 2 index holes being passed(giving said sector instead), otherwise erroring out with bits 2/0 and ST2 bit 0 being set, due it to not finding the Sector ID(which is the C/H/S of the sector on the disk's sector header)?

Everybody keeps saying EOT is the last sector ID it will read, but either this is correct and Windows NT 3.1 goes horribly wrong somehow, or Windows NT 3.1 is correct and the documentation on EOT is incorrect?
Also, the definition of EOT is already broken by most emulators with regards to MT and DMA being used together(like Bochs). It will simply keep running until TC is reached, ignoring EOT in the parameters?
Although I can't remember where I've read that. I believe it's somewhere in the Linux source code it's said that.

Edit: OK. MS-DOS is the same. It sets EOT to 18, then sets up a DMA transfer for 512 bytes only, then executes it, which sets that bit in the register?
Now it can't seem to read the disk properly anymore?
Edit: OK. That was a formatted corrupted disk image(first track formatted, then aborting the formatting process because nformat crashed.

Now I'm curious what Windows NT 3.1 does...
Edit: Hmmm... The first setup disk doesn't boot anymore?

Edit: Yup. It's set incorrectly during Windows NT boot. EOT=0xF in that case, while it requires a proper 0x12 to boot properly.
Edit: Just confirmed that. It sets it up for EOT=0xF, which fails booting when obeyed(it doesn't obey it according to linux's floppy driver). Restoring that behaviour makes it boot again.

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

Reply 3 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

It's now implemented correctly(with some bugs fixed). EOT is handled as before, but with slight improvements regarding non-DMA mode.
EN is now properly set as you've said.

WC isn't currently handled (set) yet, as I don't know how that actually works on the FDC. In what exact case is it set? The C/H/S ID on the disk sector is matched against the requested one(from the command bytes 2(C),3(H),4(S)). Isn't C/H/S on the disk skipped when it doesn't match the bytes in the command(or the same command, but with increased byte 4 for the subsequent sectors(multiple sector mode))? Otherwise, it would easily error out when reading multiple sectors(multi sector reads as it calls it) with the sectors being interleaved on the disk or something like that? Then it can't read more than 1 sector off the disk? It also says 'not found within two index holes' (roughly), so if a sector isn't found after two index holes pass detection, it's aborted. So that would say that individual sectors can be read when interleaving, but multiple sectors can't be read with a single command, erroring out after 1 sector always(because the sectorID doesn't match for the next sector on the physical disk)? Or am I interpreting it incorrectly?

So, easily said, does it just compare the full C/H/S ID on the disk for the first sector read/written, then requiring the sectors after that during a multi-sector read/write for the same operation to be ascending(with the exception to the SK bit behaviour)? Or does it re-scan the whole track for each sector(1. wait for index, 2. wait for sector ID match(read and succeed when matched), 3. wait for index(if sector wasn't previously found, error out))?

Edit: After fixing the format for IMD images for the final track to not error out trying to read another disk ID from the disk image after the track to format(which is at EOF), the formatting process works properly in Windows NT, finishing without issues it seems.

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

Reply 4 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. After switching floppy disks after formatting, more issues occur. It seems to try using Implicit Seek, which sets the Seek End bit anyways, even during the Read ID command. It doesn't like that.
Also, just changed the Read ID command to no longer perform Implied Seeks(as it doesn't have anything to imply, not even the current logical idea of it's track it has(which is returned by the Sense Interrupt command), which it was using as the destination for the Read ID's Implicit Seek).

Edit: That seems to have fixed the changing behaviour of Windows NT 3.1. It can now properly read, write and format said floppy disks! 😁 (At least on drive A, drive B still seems to have some unresolved issues(currently working on that one))

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

Reply 5 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just implemented the floppy Read Track command. It behaves just like the Read Data command(uses the same code), except that it flat out ignores the Sector part of the ID. The head and track part of the ID are still used as normal skipping when read from the DSK/IMD disk images, though.

Edit: Just found out that I was trying a 2.88MB disk image with the FDC. But the FDC was made so that 2.88MB only supports the 1M rate and not the used lower rates. Fixing it to allow the lower rates should theoretically fix it's reading issue. Otherwise, the B drive seems to run without issues seen.

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

Reply 6 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

It makes me think about something, though. What effect does the speed setting(250/300/500/1M) have on the actual floppy transfer, besides speed? Will transfers fail in specific cases? If so, when?

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

Reply 7 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. This is weird. When trying to run CheckIt! Diagnostics from a floppy disk, it will fault which will double fault from V86 mode it seems, then said double fault handling will try to task switch as it's handler(double fault task switch handler is usual in most modern OSes), where the double fault exception handling faulting will trigger a page fault somehow(which it shouldn't) on the kernel space. And the page fault handling is somehow not addressed further up the same function(before starting the switching out of the process)? Weird?

Anyone can see what's going wrong? It's the code in https://bitbucket.org/superfury/unipcemu/src/ … /multitasking.c , which handles all TSS-based task switching and related #TS exception starting.

It's kind of weird a triple fault seems to occur while handling the saving of the TSS? Since the TSS should have already checked said access to be valid before starting the transaction?

Edit: Just changed the exception handlers that aren't for the current instruction itself(like #GP, #TS, #NP etc.), when faulting on CPL checks for the interrupt vector to ignore the CPL, since it isn't a plain INT instruction causing this.

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

Reply 8 of 14, by crazyc

User metadata
Rank Member
Rank
Member
superfury wrote on 2020-04-08, 23:46:

It makes me think about something, though. What effect does the speed setting(250/300/500/1M) have on the actual floppy transfer, besides speed? Will transfers fail in specific cases? If so, when?

It will fail with missing address mark because it will see the index but won't be able to read the data.

WC isn't currently handled (set) yet, as I don't know how that actually works on the FDC. In what exact case is it set?

It will be set when a sector address doesn't match the cylinder. The read could still succeed though if there is a matching sector on the track. I don't know if it's cleared when a sector cylinder does match because I've never seen a disk with different cylinder ids on a single track.

Reply 9 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

But what I mainly want to know is: what happens when sector numbers and the matching heads aren't in ascending order on the disk? Will it start out for the first sector of the transfer to match exactly(if found on the track), then keep reading the next sector after it on the disk until a mismatch C/H/S occurs(when it'll set said bit and/or abort) or until it's finished?

It should be easily verified by formatting a track using a simple interleaved format, then trying to read/write multiple sectors?

Edit: Just implemented said behaviour. It will now actually start at the index hole for a track switch or Seek/Recalibrate command, then start looking for the sector until the index hole is encountered again. If it didn't find it, it'll fail and error out immediately. Otherwise, it'll read the first sector and increase the sector number. Then subsequent sector numbers won't scan the entire track anymore, just looking at the disk's sector after the last read sector. If the sector ID doesn't match, it'll error out, otherwise succeed. And of course, sector IDs will roll over, so once the index hole is reached again, it'll read the first sector ID off the track again, which will make it error out because the Sector ID doesn't match.
And of course, the Read Track/Read Diagnostics command(depending on the documentation what it's called) will ignore the sector number of the Sector ID but act the same with regards to the Head and Cylinder values on the physical disk.
The normal static disk images(.ima or .img disk images) will of course assume ascending order always, only erroring out when reaching physical EOT(because they can't have custom sector IDs on the disk).
The IMD and DSK disk images do actually support this new method of processing 😁

I've tested it with my formatted IMD disk image(using Windows NT 3.1 to format it, since MS-DOS format.com seems to always crash atm(seemingly during an IRQ0 or perhaps FDC IRQ), displaying weird data characters on the (S)VGA text display).

The WC bit is now set when the cylinder doesn't match during the sector ID verification after the first read sector during multi-sector operation.
Otherwise, ST1 bit 3 and ST2 bit 1 are set, with ST1 bit 1 being set too if two index holes are encountered while searching and not finding the Sector ID(C/H/S value combination, with S being ignored during the Read Diagnostic/Read Track command).

Would that be correct behaviour?

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

Reply 10 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Then what about D1 BC (Bad Cylinder)? It says something about requesting C=&FF in the command parameters or am I misreading that? What's &FF? FFh?

Edit: According to http://www.isdaman.com/alsos/hardware/fdc/floppy.htm, it's indeed FFh on the disk's track ID being encountered.

Implemented that behaviour on top of the already existing WC logic(uses the same primary if-clause, since it's also a mismatch of Track ID on disk after all).

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

Reply 11 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just have been thinking. What happens when a Read ID command is executed with no floppy disk inserted in the drive? Will it simply hang the controller(just like undefined/unknown commands)? Or will it return something special?

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

Reply 12 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

Edit: OK. I see it reading the first sector(s) off the floppy disk now in Windows 95's command prompt(command.com) when performing the dir command on the floppy disk(executing "dir a:" ). The FDC reports ST0=0, ST1=0x80, ST2=0, after which Windows 95 seems to disapprove of it and retries it 3 times.

UniPCemu clears ST0's Seek End bit when executing the command correctly. When I look at Bochs, it leaves said bit alone(except when erroring out, in which case it clears it due to reloading ST0 completely).
I'll try to retry it with ST0's SE bit left alone...
Anyone knows the correct behaviour of that bit with the Read Data/Write Data command?
According to Bochs, the Write Data command does actually always clear the ST0.SE bit, but is that correct behaviour?

Edit: OK. Letting it leave ST0.SE alone when reading and not erroring out and not setting ST1.EN when not matching TC and EOT makes Windows 95 properly read the disk?

Edit: Modified it to properly report ST1.EN when matching the case you mentioned earlier only(currently was doing it for the opposite TC case(not TC and not EOT instead of TC and not EOT)).

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

Reply 13 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Just found another small bug: ST0 wasn't properly being set when executing the format track command. It was left with it's old value remaining, as I noticed with the command being executed on Windows NT 3.1.

Edit: Found another bug with the Read ID command not properly resetting ST1 and ST2 with their improved handling, causing it to return a wrong ST1/ST2 register value in some cases(Like with End of Cylinder(EC bit in ST1) still from an earlier command set when it shouldn't).

Edit: Huh? The formatting fails somehow, because TC isn't set after 12 sectors being formatted, causing it to error out with EC=1 and ST0 bits 6-7=01h? So effectively, the EC case is ignored for the Format Track command(only counts for the other data commands)?

So, with the format track command, an exception is made: the End of Cylinder case isn't made for that command(just for the normal read data/write data commands). Both TC and EOT will effectively complete the command and the format will finish normally without errors(unless things like formatting write errors occur).
Bochs' source code seems to confirm that behaviour.

Edit: OK. Windows 95's unformatted disk detection seems to be a bit different compared to Windows NT. It doesn't report the disk(after the Read ID command) as unformatted, but instead reports a "General failure reading drive" with the option to abort/retry/fail following it. Although that just might be a Windows 95 oddity(or MS-DOS one).

Format.com does, however, actually format the tracks when executing format.com on the drive(normal format, not specifying unconditional format like MS-DOS 6.22 required). Still need to re-test MS-DOS 6.22 on that, though.

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

Reply 14 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Both Windows 95 and Windows NT 3.1 seem to be able to correctly read and format the floppy disks provided(either IMA/IMG static disk images and IMD disk images(unformatted and formattted))! 😁

All that's left to test is MS-DOS 6.22 itself.

Edit: Tried running CheckIt diagnostics 3.0 from a floppy disk from within Windows 95. It made Windows 95 return to pure DOS mode, run the software properly, then start Windows 95 back up. So it's working properly(just the remainder of Windows 95 issues to sort out, like Explorer.exe crashing).

At least the Program Manager doesn't crash, so Windows 95's kernel components etc. can still be checked for bugs.

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