VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I'm trying to convert my emulator (UniPCemu) to use cycle-accurate Floppy disk timings (using a single timing handler, which counts time in nanoseconds, based on the timeouts specified).

https://bitbucket.org/superfury/unipcemu/src/ … ppy.c?at=master

The updateFloppy gets passed the time executed by the CPU each instruction for timing itself(in nanoseconds).

Anyone can point me into a direction to implement correct floppy disk timings (head load/unload and step rate timings, how to apply them)?

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

Reply 1 of 15, by elianda

User metadata
Rank l33t
Rank
l33t

Maybe move the discussion to the Kryoflux forums. They basically get those timing values from the Reader Hardware so they should know them as well as their standard deviation. They can probably also provide a suitable image format as simple binary images do not include any disk mastering information which would be required if you do a more exact emulation.

Retronn.de - Vintage Hardware Gallery, Drivers, Guides, Videos. Now with file search
Youtube Channel
FTP Server - Driver Archive and more
DVI2PCIe alignment and 2D image quality measurement tool

Reply 2 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've implemented basic step rate timings(and calculations for head load/unload). I've applied the step rate to the seek/recalibrate commands and fixed them in the latest commits.

https://bitbucket.org/superfury/unipcemu/src/ … ppy.c?at=master

I'm still wondering about the timings of reading/writing sector data. I cannot find anything apart from the head (un)load timings in that case. Anyone knows how long it takes to read/write a sector(and multiple sectors in a row)? What are those timings? I cannot find anything in the 82077AA manuals.

Edit: Looking at Bochs:

 // time to write one sector at 300 rpm
sector_time = 200000 / BX_FD_THIS s.media[drive].sectors_per_track;
bx_pc_system.activate_timer(BX_FD_THIS s.floppy_timer_index, sector

Since the value in sector_time seems to be usec, that means 200usec per full rotation? So it takes that long to buffer a full cylinder to transfer from the floppy disk? So add the head load time to the first sector transferred only for the correct timings?

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

Reply 3 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

So does that mean that at 300 rpm, every round actually reads a whole track? Since the time for a round is divided by the amount of sectors per track/cylinder, does that mean that it simply differs in speed by only reading one track for each time the floppy disk turns 360 degrees? This happens no matter what the density(sectors per track times average bytes per sector)?

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

Reply 4 of 15, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

Yeah 300 RPM is 5 Hz, so each track repeats under the head every 200ms. So basically when the controller tries to read a sector, or multiple sectors, it has to wait until the correct sector happens to move under the head and then it can read one or multiple sectors.

But there's two things (maybe you don't need to emulate these but anyway), the sectors might be interleaved so even if you could read 18 sequential sectors from one track in one rotation of a floppy, if you order the sectors physically from 18 to 1 instead of from 1 to 18, then the disk needs to rotate 18 times to read them in correct order. Some games might use this for detecting if it is running on a copy or factory formatted disk, if it takes too little time to read a whole sector.

And physically a track has an index mark, some pre/post gaps between sectors and a sector consists of two portions, one that tells which sector is next and then after some gap there is the data of the sector. These are all specified for different floppy formats.

Reply 5 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

So if I understand this correctly:

- The heads can be read sequentially (top/bottom of the disk), directly after each other(Sequential floppy LBA addressing).
- The track/cylinder are the rings from the outside to the inside of the platter.
- The sector is a pie slice of the track, which can thus be read both sides at the same time(Multi Track)?

https://upload.wikimedia.org/wikipedia/common … _Sector.svg.png

Also, the size and location/order of a sector on the ring called track/cylinder might be random, defined by the formatted layout?

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

Reply 6 of 15, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

Yes, and the order is for a given track, you can first read all sectors with head 0, then just switch to read all sectors with head 1, before moving on to next track.

superfury wrote:

Also, the size and location/order of a sector on the ring called track/cylinder might be random, defined by the formatted layout?

Might be. To the floppy drive, or to the floppy itself, a track is just a looping stream of magnetic pulses, and the controller has to work with that under software control. There was also few tape drives that could be connected to the floppy interface.

Reply 7 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

What happens when a multitrack read is executed on side 1? Side 0 reads/writes automatically continue reading/writing side 1 when EOT is reached, finally finishing leaving it at the next track, side 0. But what happens during a EOT MT read/write on side 1(Read sectors wirh MT on head 1)? Does it read side 1, then side 0 of the same track, finishing by leaving it in a state of side 1 on the next track? So essentially EOT which sets the head to the original head finishes the command and increases the track/cylinder number?

So:
Normal read until EOT: Reada track using specified head. Track is increased, Head set and left at used head.
MT read until EOT on head 0: Track is read on head 0 sector n until EOT. Head becomes 1. Track is read on head 1 sector 1 to EOT. Head becomes 0 causing the command to finish and track to be increased.
MT read until EOT on head 1: Track is read on head 1 sector n until EOT. Head becomes 0. Track is read on head 0 sector 1 to EOT. Head becomes 1 causing the command to finish and track to be increased.

Is that behaviour correct?

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

Reply 10 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

What happens when a MT read on side 1 is issued? Does it read side 0 of the same track after it and finish, giving the result of side 1, next track?

Btw, when is the head reloaded during implicit seek and read/write sectors? Is it first loaded, then seeking, then reading/writing? Or is it seeking, then loading, then reading/writng?

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

Reply 11 of 15, by crazyc

User metadata
Rank Member
Rank
Member
superfury wrote:

What happens when a MT read on side 1 is issued? Does it read side 0 of the same track after it and finish, giving the result of side 1, next track?

Multitrack reads end at eot on side 1.

superfury wrote:

Btw, when is the head reloaded during implicit seek and read/write sectors? Is it first loaded, then seeking, then reading/writing? Or is it seeking, then loading, then reading/writng?

Presumably, it'll act as if it did an explicit seek followed by a read but it's not documented so you'd have to try it on a real device.

Reply 12 of 15, by Scali

User metadata
Rank l33t
Rank
l33t

Some half-related info:
- A cute trick done eg on Atari ST was to use custom disk routines where you'd read one side first, then the other. As a result, the 'clicks' for moving the head from one track to the next sounded twice as fast as normal.
- On Amiga, there was no way to read a single sector. Since it only takes 200 ms to read a full track, this was negligible compared to the search to that track.
Therefore, the Amiga would always read or write an entire track to disk, even if you modified only a single sector.
This allowed them to apply an optimization: the track could be considered a ringbuffer of sectors. This meant that it didn't matter where you'd start to read or write on disk. You'd just read the whole track in memory, starting from an arbitrary sector. You could then do a quick scan through memory to find the first sector in the track.
When writing back the track, you could again just write the whole ringbuffer to the disk immediately. This meant that you didn't have to wait for the appropriate sector to appear under the head.
- Floppies are somewhat speed-sensitive. No floppy drive will spin at *exactly* 300 rpm. You'd have some amount of deviation from one drive to the next. So you won't need true cycle-accurate emulation of the whole floppy drive. Perhaps not even for the controller itself. As long as you're 'in the ballpark', things should work fine.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 13 of 15, by elianda

User metadata
Rank l33t
Rank
l33t

I mean the Kryoflux images are basically the times between magnetization changes. So you could make one thread simulate the rotating disk by just setting the currently visible magnetization to the head(s). With slightly more effort you can even implement a slow rotation start/stop as well as a slightly variable final speed and stepper times that are also a bit different each time. You can even change the sampled streams after one rotation as typically tracks are sampled five times.
In reality the exact timing is also not the same for each rotation. Even if you step to a track the head never lands at the same ideal position and this can change the magnetization timing as well.

On controller side you can read the magnetization the head 'sees' that the other thread generated with timing given by the image streams. I think this helps already greatly to get an accurate emulation. All the assumptions that there is already a certain disk structure present is a strong simplification. In reality you can image a paper disk or change the disk to another one while a program reads, which is btw used for automatic disk change detection also on PC by some programs.

Retronn.de - Vintage Hardware Gallery, Drivers, Guides, Videos. Now with file search
Youtube Channel
FTP Server - Driver Archive and more
DVI2PCIe alignment and 2D image quality measurement tool

Reply 14 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

The different disk images use 300 RPM as a default, except 1.2MB 5" floppy disk images, which use 360RPM. Although the read/write speeds aren't implemented yet(Only seek times for seek and recalibrate commands atm).

Strange enough: it seems to abort the transfer of data on the Generic Super PC/Turbo XT BIOS v2.6?

The log of booting MS-DOS from hard disk on XT emulation, then "dir a:", which fails with a not ready error.

00:00:36:31.04604: FLOPPY: Write DOR=0C
00:00:50:47.05184: FLOPPY: Write DOR=0C
00:00:52:99.01604: FLOPPY: Write DOR=08
00:00:52:99.02040: FLOPPY: Reset requested by DOR!
00:00:52:99.02056: FLOPPY: Write DOR=0C
00:00:52:99.02064: FLOPPY: Activation requested by DOR!
00:00:52:99.02488: FLOPPY: MSR changed: 80
00:00:52:99.02736: FLOPPY: Read MSR=80
00:00:52:99.02816: FLOPPY: Command byte sent: 08
00:00:52:99.02820: FLOPPY: executing command: 08
00:00:52:99.02840: FLOPPY: Reset Sense Interrupt, pending drive 0/4...
00:00:52:99.02856: FLOPPY: Sense interrupt: ST0=C0, Currentcylinder=00
00:00:52:99.02916: FLOPPY: MSR changed: d0
00:00:52:99.02916: FLOPPY: Read MSR=D0
00:00:52:99.02932: FLOPPY: Reading result byte 1/2=C0
00:00:52:99.02972: FLOPPY: Read MSR=D0
00:00:52:99.03004: FLOPPY: Read MSR=D0
00:00:52:99.03020: FLOPPY: Reading result byte 2/2=00
00:00:52:99.03056: FLOPPY: MSR changed: 80
00:00:52:99.03060: FLOPPY: Read MSR=80
00:00:52:99.03112: FLOPPY: Read MSR=80
00:00:52:99.03132: FLOPPY: Command byte sent: 03
00:00:52:99.03136: FLOPPY: Reset for all drives has been finished!
00:00:52:99.03168: FLOPPY: MSR changed: 90
00:00:52:99.03168: FLOPPY: Read MSR=90
00:00:52:99.03184: FLOPPY: Parameter sent: CF(#1/2)
00:00:52:99.03216: FLOPPY: Read MSR=90
00:00:52:99.03232: FLOPPY: Parameter sent: 02(#2/2)
00:00:52:99.03252: FLOPPY: executing command: 03
00:01:03:15.04640: FLOPPY: Write DOR=0C
00:01:08:87.09216: FLOPPY: Write DOR=1C
00:01:08:87.09968: FLOPPY: MSR changed: 80
00:01:08:87.09968: FLOPPY: Read MSR=80
00:01:08:87.09992: FLOPPY: Command byte sent: 07
00:01:08:88.00024: FLOPPY: MSR changed: 90
00:01:08:88.00024: FLOPPY: Read MSR=90
00:01:08:88.00040: FLOPPY: Parameter sent: 00(#1/1)
00:01:08:88.00048: FLOPPY: executing command: 07
00:01:08:89.07112: FLOPPY: MSR changed: 80
00:01:08:89.07320: FLOPPY: Read MSR=80
00:01:08:89.07352: FLOPPY: Command byte sent: 0F
00:01:08:89.07384: FLOPPY: MSR changed: 90
00:01:08:89.07384: FLOPPY: Read MSR=90
00:01:08:89.07400: FLOPPY: Parameter sent: 00(#1/2)
00:01:08:89.07432: FLOPPY: Read MSR=90
00:01:08:89.07448: FLOPPY: Parameter sent: 00(#2/2)
00:01:08:89.07448: FLOPPY: executing command: 0F
00:01:08:90.08624: FLOPPY: MSR changed: 80
00:01:08:90.08856: FLOPPY: Read MSR=80
00:01:08:90.08888: FLOPPY: Command byte sent: 08
00:01:08:90.08888: FLOPPY: executing command: 08
00:01:08:90.08896: FLOPPY: Sense interrupt: ST0=20, Currentcylinder=00
00:01:08:90.08928: FLOPPY: MSR changed: d0
00:01:08:90.08936: FLOPPY: Read MSR=D0
00:01:08:90.08952: FLOPPY: Reading result byte 1/2=20
00:01:08:90.08984: FLOPPY: Read MSR=D0
00:01:08:90.09016: FLOPPY: Read MSR=D0
00:01:08:90.09032: FLOPPY: Reading result byte 2/2=00
00:01:08:90.09072: FLOPPY: MSR changed: 80
00:01:08:90.09072: FLOPPY: Read MSR=80
Show last 214 lines
00:01:08:91.00880: FLOPPY: Read MSR=80
00:01:08:91.00896: FLOPPY: Command byte sent: E6
00:01:08:91.00936: FLOPPY: MSR changed: 90
00:01:08:91.00944: FLOPPY: Read MSR=90
00:01:08:91.00952: FLOPPY: Parameter sent: 00(#1/8)
00:01:08:91.00984: FLOPPY: Read MSR=90
00:01:08:91.01000: FLOPPY: Parameter sent: 00(#2/8)
00:01:08:91.01024: FLOPPY: Read MSR=90
00:01:08:91.01032: FLOPPY: Parameter sent: 00(#3/8)
00:01:08:91.01056: FLOPPY: Read MSR=90
00:01:08:91.01072: FLOPPY: Parameter sent: 02(#4/8)
00:01:08:91.01096: FLOPPY: Read MSR=90
00:01:08:91.01112: FLOPPY: Parameter sent: 02(#5/8)
00:01:08:91.01136: FLOPPY: Read MSR=90
00:01:08:91.01144: FLOPPY: Parameter sent: 09(#6/8)
00:01:08:91.01168: FLOPPY: Read MSR=90
00:01:08:91.01184: FLOPPY: Parameter sent: 2A(#7/8)
00:01:08:91.01208: FLOPPY: Read MSR=90
00:01:08:91.01216: FLOPPY: Parameter sent: FF(#8/8)
00:01:08:91.01224: FLOPPY: executing command: 06
00:01:08:91.01224: FLOPPY: Read sector #1
00:01:08:91.01232: FLOPPY: Sector size: 512 bytes
00:01:08:91.01232: FLOPPY: Requesting transfer for 512 bytes.
00:01:08:91.01296: FLOPPY: Start transfer of data (DMA: 1)...
00:01:10:22.08488: FLOPPY: Write DOR=18
00:01:10:22.08896: FLOPPY: Reset requested by DOR!
00:01:10:22.08904: FLOPPY: Write DOR=1C
00:01:10:22.08912: FLOPPY: Activation requested by DOR!
00:01:10:22.09352: FLOPPY: MSR changed: 80
00:01:10:22.09736: FLOPPY: Read MSR=80
00:01:10:22.09768: FLOPPY: Command byte sent: 08
00:01:10:22.09768: FLOPPY: executing command: 08
00:01:10:22.09776: FLOPPY: Reset Sense Interrupt, pending drive 0/4...
00:01:10:22.09784: FLOPPY: Sense interrupt: ST0=C0, Currentcylinder=00
00:01:10:22.09824: FLOPPY: MSR changed: d0
00:01:10:22.09832: FLOPPY: Read MSR=D0
00:01:10:22.09848: FLOPPY: Reading result byte 1/2=C0
00:01:10:22.09880: FLOPPY: Read MSR=D0
00:01:10:22.09912: FLOPPY: Read MSR=D0
00:01:10:22.09928: FLOPPY: Reading result byte 2/2=00
00:01:10:22.09968: FLOPPY: MSR changed: 80
00:01:10:22.09968: FLOPPY: Read MSR=80
00:01:10:23.00024: FLOPPY: Read MSR=80
00:01:10:23.00048: FLOPPY: Command byte sent: 03
00:01:10:23.00048: FLOPPY: Reset for all drives has been finished!
00:01:10:23.00096: FLOPPY: MSR changed: 90
00:01:10:23.00104: FLOPPY: Read MSR=90
00:01:10:23.00128: FLOPPY: Parameter sent: DF(#1/2)
00:01:10:23.00192: FLOPPY: Read MSR=90
00:01:10:23.00224: FLOPPY: Parameter sent: 02(#2/2)
00:01:10:23.00240: FLOPPY: executing command: 03
00:01:10:23.02928: FLOPPY: Write DOR=1C
00:01:10:23.03272: FLOPPY: MSR changed: 80
00:01:10:23.03272: FLOPPY: Read MSR=80
00:01:10:23.03296: FLOPPY: Command byte sent: 07
00:01:10:23.03352: FLOPPY: MSR changed: 90
00:01:10:23.03360: FLOPPY: Read MSR=90
00:01:10:23.03384: FLOPPY: Parameter sent: 00(#1/1)
00:01:10:23.03384: FLOPPY: executing command: 07
00:01:10:24.08928: FLOPPY: MSR changed: 80
00:01:10:24.09240: FLOPPY: Read MSR=80
00:01:10:24.09264: FLOPPY: Command byte sent: 0F
00:01:10:24.09304: FLOPPY: MSR changed: 90
00:01:10:24.09304: FLOPPY: Read MSR=90
00:01:10:24.09320: FLOPPY: Parameter sent: 00(#1/2)
00:01:10:24.09352: FLOPPY: Read MSR=90
00:01:10:24.09368: FLOPPY: Parameter sent: 00(#2/2)
00:01:10:24.09368: FLOPPY: executing command: 0F
00:01:10:26.04168: FLOPPY: MSR changed: 80
00:01:10:26.04368: FLOPPY: Read MSR=80
00:01:10:26.04392: FLOPPY: Command byte sent: 08
00:01:10:26.04400: FLOPPY: executing command: 08
00:01:10:26.04408: FLOPPY: Sense interrupt: ST0=20, Currentcylinder=00
00:01:10:26.04440: FLOPPY: MSR changed: d0
00:01:10:26.04440: FLOPPY: Read MSR=D0
00:01:10:26.04456: FLOPPY: Reading result byte 1/2=20
00:01:10:26.04488: FLOPPY: Read MSR=D0
00:01:10:26.04520: FLOPPY: Read MSR=D0
00:01:10:26.04544: FLOPPY: Reading result byte 2/2=00
00:01:10:26.04584: FLOPPY: MSR changed: 80
00:01:10:26.04584: FLOPPY: Read MSR=80
00:01:10:29.03472: FLOPPY: Read MSR=80
00:01:10:29.03496: FLOPPY: Command byte sent: E6
00:01:10:29.03536: FLOPPY: MSR changed: 90
00:01:10:29.03536: FLOPPY: Read MSR=90
00:01:10:29.03560: FLOPPY: Parameter sent: 00(#1/8)
00:01:10:29.03608: FLOPPY: Read MSR=90
00:01:10:29.03616: FLOPPY: Parameter sent: 00(#2/8)
00:01:10:29.03656: FLOPPY: Read MSR=90
00:01:10:29.03672: FLOPPY: Parameter sent: 00(#3/8)
00:01:10:29.03704: FLOPPY: Read MSR=90
00:01:10:29.03720: FLOPPY: Parameter sent: 04(#4/8)
00:01:10:29.03744: FLOPPY: Read MSR=90
00:01:10:29.03760: FLOPPY: Parameter sent: 02(#5/8)
00:01:10:29.03784: FLOPPY: Read MSR=90
00:01:10:29.03800: FLOPPY: Parameter sent: 09(#6/8)
00:01:10:29.03824: FLOPPY: Read MSR=90
00:01:10:29.03832: FLOPPY: Parameter sent: 2A(#7/8)
00:01:10:29.03856: FLOPPY: Read MSR=90
00:01:10:29.03872: FLOPPY: Parameter sent: FF(#8/8)
00:01:10:29.03872: FLOPPY: executing command: 06
00:01:10:29.03872: FLOPPY: Read sector #3
00:01:10:29.03888: FLOPPY: Sector size: 512 bytes
00:01:10:29.03896: FLOPPY: Requesting transfer for 512 bytes.
00:01:10:29.03992: FLOPPY: Start transfer of data (DMA: 1)...
00:01:11:62.00016: FLOPPY: Write DOR=18
00:01:11:62.00368: FLOPPY: Reset requested by DOR!
00:01:11:62.00376: FLOPPY: Write DOR=1C
00:01:11:62.00384: FLOPPY: Activation requested by DOR!
00:01:11:62.00680: FLOPPY: MSR changed: 80
00:01:11:62.00880: FLOPPY: Read MSR=80
00:01:11:62.00912: FLOPPY: Command byte sent: 08
00:01:11:62.00912: FLOPPY: executing command: 08
00:01:11:62.00920: FLOPPY: Reset Sense Interrupt, pending drive 0/4...
00:01:11:62.00928: FLOPPY: Sense interrupt: ST0=C0, Currentcylinder=00
00:01:11:62.00960: FLOPPY: MSR changed: d0
00:01:11:62.00960: FLOPPY: Read MSR=D0
00:01:11:62.00976: FLOPPY: Reading result byte 1/2=C0
00:01:11:62.01016: FLOPPY: Read MSR=D0
00:01:11:62.01048: FLOPPY: Read MSR=D0
00:01:11:62.01064: FLOPPY: Reading result byte 2/2=00
00:01:11:62.01096: FLOPPY: MSR changed: 80
00:01:11:62.01104: FLOPPY: Read MSR=80
00:01:11:62.01152: FLOPPY: Read MSR=80
00:01:11:62.01168: FLOPPY: Command byte sent: 03
00:01:11:62.01176: FLOPPY: Reset for all drives has been finished!
00:01:11:62.01216: FLOPPY: MSR changed: 90
00:01:11:62.01216: FLOPPY: Read MSR=90
00:01:11:62.01232: FLOPPY: Parameter sent: DF(#1/2)
00:01:11:62.01264: FLOPPY: Read MSR=90
00:01:11:62.01280: FLOPPY: Parameter sent: 02(#2/2)
00:01:11:62.01288: FLOPPY: executing command: 03
00:01:11:62.06200: FLOPPY: Write DOR=1C
00:01:11:62.06536: FLOPPY: MSR changed: 80
00:01:11:62.06544: FLOPPY: Read MSR=80
00:01:11:62.06552: FLOPPY: Command byte sent: 07
00:01:11:62.06576: FLOPPY: MSR changed: 90
00:01:11:62.06576: FLOPPY: Read MSR=90
00:01:11:62.06592: FLOPPY: Parameter sent: 00(#1/1)
00:01:11:62.06600: FLOPPY: executing command: 07
00:01:11:63.08672: FLOPPY: MSR changed: 80
00:01:11:63.08976: FLOPPY: Read MSR=80
00:01:11:63.09000: FLOPPY: Command byte sent: 0F
00:01:11:63.09032: FLOPPY: MSR changed: 90
00:01:11:63.09040: FLOPPY: Read MSR=90
00:01:11:63.09056: FLOPPY: Parameter sent: 00(#1/2)
00:01:11:63.09088: FLOPPY: Read MSR=90
00:01:11:63.09104: FLOPPY: Parameter sent: 00(#2/2)
00:01:11:63.09104: FLOPPY: executing command: 0F
00:01:11:65.00984: FLOPPY: MSR changed: 80
00:01:11:65.01184: FLOPPY: Read MSR=80
00:01:11:65.01208: FLOPPY: Command byte sent: 08
00:01:11:65.01216: FLOPPY: executing command: 08
00:01:11:65.01216: FLOPPY: Sense interrupt: ST0=20, Currentcylinder=00
00:01:11:65.01264: FLOPPY: MSR changed: d0
00:01:11:65.01264: FLOPPY: Read MSR=D0
00:01:11:65.01280: FLOPPY: Reading result byte 1/2=20
00:01:11:65.01320: FLOPPY: Read MSR=D0
00:01:11:65.01352: FLOPPY: Read MSR=D0
00:01:11:65.01368: FLOPPY: Reading result byte 2/2=00
00:01:11:65.01400: FLOPPY: MSR changed: 80
00:01:11:65.01408: FLOPPY: Read MSR=80
00:01:11:67.09880: FLOPPY: Read MSR=80
00:01:11:68.00176: FLOPPY: Command byte sent: E6
00:01:11:68.00224: FLOPPY: MSR changed: 90
00:01:11:68.00224: FLOPPY: Read MSR=90
00:01:11:68.00240: FLOPPY: Parameter sent: 00(#1/8)
00:01:11:68.00312: FLOPPY: Read MSR=90
00:01:11:68.00328: FLOPPY: Parameter sent: 00(#2/8)
00:01:11:68.00360: FLOPPY: Read MSR=90
00:01:11:68.00376: FLOPPY: Parameter sent: 00(#3/8)
00:01:11:68.00408: FLOPPY: Read MSR=90
00:01:11:68.00424: FLOPPY: Parameter sent: 02(#4/8)
00:01:11:68.00456: FLOPPY: Read MSR=90
00:01:11:68.00480: FLOPPY: Parameter sent: 02(#5/8)
00:01:11:68.00504: FLOPPY: Read MSR=90
00:01:11:68.00520: FLOPPY: Parameter sent: 09(#6/8)
00:01:11:68.00536: FLOPPY: Read MSR=90
00:01:11:68.00552: FLOPPY: Parameter sent: 2A(#7/8)
00:01:11:68.00576: FLOPPY: Read MSR=90
00:01:11:68.00584: FLOPPY: Parameter sent: FF(#8/8)
00:01:11:68.00600: FLOPPY: executing command: 06
00:01:11:68.00600: FLOPPY: Read sector #1
00:01:11:68.00608: FLOPPY: Sector size: 512 bytes
00:01:11:68.00608: FLOPPY: Requesting transfer for 512 bytes.
00:01:11:68.00672: FLOPPY: Start transfer of data (DMA: 1)...
00:01:12:99.06000: FLOPPY: Write DOR=18
00:01:12:99.06392: FLOPPY: Reset requested by DOR!
00:01:12:99.06400: FLOPPY: Write DOR=1C
00:01:12:99.06408: FLOPPY: Activation requested by DOR!
00:01:12:99.06904: FLOPPY: MSR changed: 80
00:01:12:99.07152: FLOPPY: Read MSR=80
00:01:12:99.07176: FLOPPY: Command byte sent: 08
00:01:12:99.07176: FLOPPY: executing command: 08
00:01:12:99.07192: FLOPPY: Reset Sense Interrupt, pending drive 0/4...
00:01:12:99.07200: FLOPPY: Sense interrupt: ST0=C0, Currentcylinder=00
00:01:12:99.07376: FLOPPY: MSR changed: d0
00:01:12:99.07384: FLOPPY: Read MSR=D0
00:01:12:99.07424: FLOPPY: Reading result byte 1/2=C0
00:01:12:99.07544: FLOPPY: Read MSR=D0
00:01:12:99.07600: FLOPPY: Read MSR=D0
00:01:12:99.07656: FLOPPY: Reading result byte 2/2=00
00:01:12:99.07752: FLOPPY: MSR changed: 80
00:01:12:99.07760: FLOPPY: Read MSR=80
00:01:12:99.07856: FLOPPY: Read MSR=80
00:01:12:99.07872: FLOPPY: Command byte sent: 03
00:01:12:99.07880: FLOPPY: Reset for all drives has been finished!
00:01:12:99.07920: FLOPPY: MSR changed: 90
00:01:12:99.07928: FLOPPY: Read MSR=90
00:01:12:99.07952: FLOPPY: Parameter sent: DF(#1/2)
00:01:12:99.07992: FLOPPY: Read MSR=90
00:01:12:99.08008: FLOPPY: Parameter sent: 02(#2/2)
00:01:12:99.08024: FLOPPY: executing command: 03
00:01:15:17.03280: FLOPPY: Write DOR=0C

Code used:
https://bitbucket.org/superfury/unipcemu/src/ … ppy.c?at=master

It seems to start the DMA transfer, but it is either never transferred, or the transfer has a problem(there isn't the required message that the transfer has finished ("FLOPPY: Finished transfer of data (1 sectors)" to be exact). So could this mean a problem with DMA transfers?

Edit: It seems the DMA controller had a little problem with the last conversion to the new byte addressing replacement of bitfields. It was anding the mode control register with C0 and checking the resulting value against 4 and 8. This is, of course, supposed to be anding with C instead. Now DMA transfers function properly again, and the XT can read the floppy disk properly again:)

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

Reply 15 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've improved the floppy disk emulation a bit. It now should properly step to cylinder 0 using timed stepping during recalibrate, and to cylinder X during seek.

https://bitbucket.org/superfury/unipcemu/src/ … ppy.c?at=master

Somehow, it still doesn't find the correct cylinder when seeking? The Sense Interrupt still returns 0x00 in all cases?

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