VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

Somehow, when the CD-ROM is switched(based on an commit of dosbox's IDE emulation), the OS (VIDE-CDD.SYS+MSCDEX) won't issue any REQUEST SENSE command?

It also doesn't re-read anything on the disk ans display the new disk using DIR on MS-DOS?

https://bitbucket.org/superfury/unipcemu/src/ … /hardware/ide.c

I even just changed the Unit Attention and Error Register bits to stay unchanged as they should(until a Request Sense is received), according to the documentation, but it has no effect?

Can anyone see what's going wrong?

Last edited by superfury on 2019-07-15, 12:02. Edited 1 time in total.

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

Reply 2 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Not directly. Only when a command is issued that throws an error(the common spin response)?

When exactly is it supposed to throw an interrupt? During the timer of any or some of the CD-ROM swapper states? (SpinDown, SpinUp, CDInserted)

When starting the CDInserted handler timeout?

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

Reply 3 of 33, by Stenzek

User metadata
Rank Newbie
Rank
Newbie

Hmm. Not sure exactly, I have it triggering when new media is "inserted". I recall having similar issues (it not showing the new directory), not sure if this was the only thing which fixed it.

At least with the OAKCDROM driver I'm using, the "test unit ready" command which is sent after the DIR command determines if it refreshes or not. When the disc has changed, it should set the error bit, with the sense key set to UNIT_ATTENTION, and the additional status code set to MEDIA_MAY_HAVE_CHANGED. Just tested, and the directory is updated even if the interrupt isn't raised, so the critical point here is that command failing.

Reply 4 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

I have just implemented the interrupt for disk changes as you've posted. Although it's still unknown how the active drive (DRV) bit effects on that are handled? What if the other drive is active?

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

Reply 5 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... http://www.t10.org/ftp/t10/document.94/94-194r1.pdf seems interesting on that part? Status register bit IDX determines cause of interrupt, with interrupts not being DRV-bound?

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

Reply 6 of 33, by Stenzek

User metadata
Rank Newbie
Rank
Newbie

To be honest, that confused me a bit too. I guess the driver has to work out which device caused the interrupt by checking the status bits.

However, I still suspect your problem is due to not erroring out on the test unit status command.

Edit: Should mention, if you're firing the interrupt, probably should still set the "interrupt reason" in the sector count register.

Reply 7 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just implemented the IDX bit to function as an interrupt pending bit for ATAPI drives(always 0 in ATA drives). Interrupts now filter for DRV for ATA drives, but don't filter for ATAPI interrupts being raised(other than the Device Control Register bits).

So reading an causative ATAPI drive after an IRQ being raised returns 1 if it's waiting for acnowledge.

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

Reply 9 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Even if so, it won't hurt any software(usually it ignores it afaik)?

Still no Request Sense after any error? The error bit is properly set, as well as error register's bits afaik? And then an interrupt is raised? But still no Request Sense is issued?

Perhaps a an issue with the CPU? Although I've pretty much checked everything multiple times already and can't find any errors in execution?

The interrupt reason is 03h, because it's the start of a simulated result phase, as an error? The Check Condition(ERROR bit in the status register) is also set, only cleared by a Request Sense command(no caching of multiple sense packets through, new sense packets overwrite the existing one on any error)?

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

Reply 10 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Btw, what happens when data is written/read from the data ports(base+0) after an ATA/ATAPI command completes or is past the I/O phase(DRQ=0)? New command data for packets?

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

Reply 11 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... https://www.kernel.org/doc/htmldocs/libata/at … Exceptions.html says that on errors, the Error bit in the status register is set(bit 0 of the status register) and that the ABRT bit is cleared, or that it's set? What does the ABRT need to be with ATAPI devices receiving invalid packet commands or erroring out on them? My emulator currently sets the ABRT bit? Is that the issue? Or is it only supposed to be set with aborted commands? If so, only the ATA command register ones or the Packet ones too? Whst about the indirect one(the disk change one)?

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

Reply 12 of 33, by Stenzek

User metadata
Rank Newbie
Rank
Newbie

Here's a trace from my emulator for a "dir" command after swapping discs. The first command is the "test unit ready", and the final command is the re-reading of the TOC.

[   10.8132] T/HW::HDC: ATA 0/1 write control register <- 0x08
[ 10.8137] T/HW::HDC: ATA write drive select 0xB0 (drive 1)
[ 10.8142] T/HW::HDC: ATA 0/1 read alternate status register <- 0x50
[ 10.8146] T/HW::HDC: ATA write command block features 0x00
[ 10.8151] T/HW::HDC: ATA write command block sector count 0x00
[ 10.8156] T/HW::HDC: ATA write command block sector number 0x00
[ 10.8160] T/HW::HDC: ATA write command block cylinder low 0x00
[ 10.8173] T/HW::HDC: ATA write command block cylinder high 0x00
[ 10.8177] T/HW::HDC: ATA write drive select 0xB0 (drive 1)
[ 10.8182] T/HW::HDC: ATA 0/1 write command register <- 0xA0
[ 10.8187] T/HW::ATACDROM: ATA drive 0/1 command register <- 0xA0
[ 10.8193] T/HW::ATACDROM: Executing ATAPI command 0xA0 on drive 0/1
[ 10.8199] T/HW::HDC: ATA 0/1 read alternate status register <- 0x58
[ 10.8203] T/HW::HDC: ATA 0/1 read alternate status register <- 0x58
[ 10.8208] T/HW::HDC: ATA 0/1 read status register <- 0x58
[ 10.8213] T/HW::HDC: ATA 0/1 read sector count <- 0x01
[ 10.8217] T/HW::HDC: ATA 0/1 read alternate status register <- 0x58
[ 10.8222] T/HW::ATACDROM: ATAPI PACKET received from host of 12 bytes
[ 10.8226] T/HW::CDROM: CDROM executing command 0x00 length 12
[ 10.8232] D/HW::CDROM: CDROM test unit ready
[ 10.8236] B/HW::CDROM: Raising CDROM interrupt
[ 10.8240] T/HW::ATADevice: Raising ATA interrupt line 0/1
[ 10.8245] T/CPU_X86::CPU: IRQ line signaled
[ 10.8249] T/CPU_X86::CPU: IRQ line signaled
[ 10.8254] T/CPU_X86::CPU: Hardware interrupt 118
[ 10.8269] D/HostInterface: Key scancode 54 up
[ 10.8274] T/i8259_PIC: EOI interrupt 6
[ 10.8279] T/i8259_PIC: EOI interrupt 2
[ 10.8283] T/HW::HDC: ATA 0/1 read status register <- 0x41
[ 10.8288] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8292] T/i8259_PIC: PIC 1 mask 0x8F
[ 10.8297] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8301] T/i8259_PIC: PIC 1 mask 0xCF
[ 10.8305] T/HW::HDC: ATA 0/1 read sector count <- 0x03
[ 10.8310] T/HW::HDC: ATA 0/1 read status register <- 0x41
[ 10.8315] T/HW::HDC: ATA 0/1 read error register <- 0x60
[ 10.8320] T/HW::HDC: ATA 0/1 read alternate status register <- 0x41
[ 10.8324] T/HW::HDC: ATA write command block features 0x00
[ 10.8329] T/HW::HDC: ATA write command block sector count 0x00
[ 10.8334] T/HW::HDC: ATA write command block sector number 0x00
[ 10.8339] T/HW::HDC: ATA write command block cylinder low 0x12
[ 10.8343] T/HW::HDC: ATA write command block cylinder high 0x00
[ 10.8347] T/HW::HDC: ATA write drive select 0xB0 (drive 1)
[ 10.8352] T/HW::HDC: ATA 0/1 write command register <- 0xA0
[ 10.8371] T/HW::ATACDROM: ATA drive 0/1 command register <- 0xA0
[ 10.8375] T/HW::ATACDROM: Executing ATAPI command 0xA0 on drive 0/1
[ 10.8380] T/HW::HDC: ATA 0/1 read alternate status register <- 0x48
[ 10.8385] T/HW::HDC: ATA 0/1 read alternate status register <- 0x48
[ 10.8389] T/HW::HDC: ATA 0/1 read status register <- 0x48
[ 10.8394] T/HW::HDC: ATA 0/1 read sector count <- 0x01
[ 10.8398] T/HW::HDC: ATA 0/1 read alternate status register <- 0x48
[ 10.8403] T/HW::ATACDROM: ATAPI PACKET received from host of 12 bytes
[ 10.8407] T/HW::CDROM: CDROM executing command 0x03 length 12
[ 10.8412] D/HW::CDROM: CDROM sense interrupt length 18
[ 10.8416] B/HW::CDROM: Raising CDROM interrupt
[ 10.8421] T/HW::ATADevice: Raising ATA interrupt line 0/1
[ 10.8425] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8431] T/i8259_PIC: PIC 1 mask 0x8F
[ 10.8435] T/CPU_X86::CPU: IRQ line signaled
[ 10.8440] T/CPU_X86::CPU: IRQ line signaled
Show last 49 lines
[   10.8445] T/CPU_X86::CPU: Hardware interrupt 118
[ 10.8450] T/i8259_PIC: EOI interrupt 6
[ 10.8465] T/i8259_PIC: EOI interrupt 2
[ 10.8470] T/HW::HDC: ATA 0/1 read status register <- 0x48
[ 10.8475] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8479] T/i8259_PIC: PIC 1 mask 0xCF
[ 10.8484] T/HW::HDC: ATA 0/1 read sector count <- 0x02
[ 10.8488] T/HW::HDC: ATA 0/1 read status register <- 0x48
[ 10.8493] T/HW::HDC: ATA 0/1 read cylinder low <- 0x12
[ 10.8497] T/HW::HDC: ATA 0/1 read cylinder high <- 0x00
[ 10.8502] T/HW::ATADevice: Raising ATA interrupt line 0/1
[ 10.8507] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8512] T/i8259_PIC: PIC 1 mask 0x8F
[ 10.8516] T/CPU_X86::CPU: IRQ line signaled
[ 10.8520] T/CPU_X86::CPU: IRQ line signaled
[ 10.8525] T/CPU_X86::CPU: Hardware interrupt 118
[ 10.8530] T/i8259_PIC: EOI interrupt 6
[ 10.8535] T/i8259_PIC: EOI interrupt 2
[ 10.8539] T/HW::HDC: ATA 0/1 read status register <- 0x50
[ 10.8544] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8548] T/i8259_PIC: PIC 1 mask 0xCF
[ 10.8553] T/HW::HDC: ATA 0/1 read sector count <- 0x03
[ 10.8570] T/HW::HDC: ATA 0/1 read status register <- 0x50
[ 10.8574] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8579] T/i8259_PIC: PIC 1 mask 0x8F
[ 10.8583] T/HW::HDC: ATA 1/0 read alternate status register <- 0x50
[ 10.8591] T/HW::HDC: ATA 0/1 write control register <- 0x08
[ 10.8596] T/HW::HDC: ATA write drive select 0xB0 (drive 1)
[ 10.8601] T/HW::HDC: ATA 0/1 read alternate status register <- 0x50
[ 10.8606] T/HW::HDC: ATA write command block features 0x00
[ 10.8611] T/HW::HDC: ATA write command block sector count 0x00
[ 10.8616] T/HW::HDC: ATA write command block sector number 0x00
[ 10.8621] T/HW::HDC: ATA write command block cylinder low 0x0C
[ 10.8625] T/HW::HDC: ATA write command block cylinder high 0x00
[ 10.8630] T/HW::HDC: ATA write drive select 0xB0 (drive 1)
[ 10.8635] T/HW::HDC: ATA 0/1 write command register <- 0xA0
[ 10.8639] T/HW::ATACDROM: ATA drive 0/1 command register <- 0xA0
[ 10.8643] T/HW::ATACDROM: Executing ATAPI command 0xA0 on drive 0/1
[ 10.8648] T/HW::HDC: ATA 0/1 read alternate status register <- 0x58
[ 10.8653] T/HW::HDC: ATA 0/1 read alternate status register <- 0x58
[ 10.8669] T/HW::HDC: ATA 0/1 read status register <- 0x58
[ 10.8674] T/HW::HDC: ATA 0/1 read sector count <- 0x01
[ 10.8680] T/HW::HDC: ATA 0/1 read alternate status register <- 0x58
[ 10.8686] T/HW::ATACDROM: ATAPI PACKET received from host of 12 bytes
[ 10.8692] T/i8259_PIC: PIC 0 mask 0xB8
[ 10.8697] T/i8259_PIC: PIC 1 mask 0x8F
[ 10.8745] T/HW::CDROM: CDROM executing command 0x43 length 12
[ 10.8751] D/HW::CDROM: CDROM read TOC msf=1,start_track=0,format=1,max_length=12

Reply 13 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmmm... Thinking about it, after such an error interrupt timeout is started, the status register js 0x00 with bit 0 toggled on, thus 0x01. Then, for any reads following it, it becomes a normal value again, taking into account any other timings...

Perhaps I should change the clearing of the status register to 0x40 instead, then verify if the next one is actually 0x41 as well? That seems to be the error trigger?

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

Reply 14 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just modified the status register to display a proper 0x41 when reporting errors.

But now, when a disk drive errors out on command 0x00(due to it not being present), the VIDE-CDD.SYS driver won't detect the CD-ROM drive anymore? Still no Request Sense command?

Also a long delay occurs when detecting that CD-ROM drive(not for a inserted CD-ROM)?

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

Reply 15 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Sector count reports 0 after said interrupt error detection? Hmmm... It's supposed to be 3? Then it starts to hang?
Edit: Whoops, a missing interrupt reason generation in that case!

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

Reply 16 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just thinking about something I see while rebooting. The BIOS resets the ATA and ATAPI controllers in the compatible way. But when an ATAPI controller has been made responsive to I/O(by means of a valid ATAPI command), won't it respond to the BIOS like a normal ATA hardware(since all registers are then writable)?

Or is it supposed to behave like a locked controller(STATUS REGISTER being 0, all other registers being read-only zeroed) when it receives an ATA reset command?

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

Reply 18 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Does that also happen with a reset by a SRST on a PACKET device(e.g. CD-ROM)? Is the CD-ROM drive returned to 'read-only mode' (the registers being unwritable until an ATAPI(PACKET/IDENTIFY PACKET DEVICE) command is given)?

Or are ATAPI drives supposed to ignore SRST?

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

Reply 19 of 33, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmmm... I execute the dir command on the CD-ROM drive before the drive has begun it's insert-spinup-spindown stages? I see it executing a read sectors command, which spins up the drive after that? No re-reading of anything though?

The status register=0x41, error register=0x20. I see the IRQ being raised for the read sectors command? Lots of nothingness? No re-reading of any TOC?
Edit: It eventually spins down again due to the timeout on the spinning drive.

Edit: I DO see it re-reading sector number 0x10 however(after failing out to the MS-DOS prompt after a HUGE delay during the Read Sectors(10) command)?
Edit: Eventually, it spins down the drive due to transfer inactivity(I've made it so that spinning up the drive stays spinned up until nothing more is done with the drive for a set amount of time(the spin down timeout)). So reading more sectors sequentially will keep the timer reset(set to the amount of time), while not transferring more sectors will cause the timer to spin down at 10 seconds after the last sector being read. Inactivity will count down said timer and when it underflows(becomes less than 0.0) the drive is spinned down(thus requiring a new spinup for it to be read, which is done by new commands(except command 0x00 and 0x03 and the mode commands) and more sectors being transferred(when a new sector is completely read into the sector buffer).

Oof, it will eventually abort with a "CDR101: Not ready reading drive X Abort, Retry, Fail?" while it's still in the middle of transferring said sector(sector 0x10(16 decimal), the volume record). Any retries after that will of course fail it because it keeps waiting for it to become a command ready status?

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