VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

EGA FLAND seems to run, but somehow it fails to actually load the plane 0 and plane 1 data from the files?

Is anything known how it performs this loading?

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

Reply 1 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member

Nothing special that I can see - but I suspect you might be making some assumptions about text mode.

Normal text mode puts the CRTC in word mode, with the sequencer and graphics controller in Odd/Even mode
FLAND puts the CRTC in byte mode, and the sequencer and graphics controller are set for sequential mode.

This will affect how the characters it writes into memory are mapped.

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

Reply 2 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 16:12:
Nothing special that I can see - but I suspect you might be making some assumptions about text mode. […]
Show full quote

Nothing special that I can see - but I suspect you might be making some assumptions about text mode.

Normal text mode puts the CRTC in word mode, with the sequencer and graphics controller in Odd/Even mode
FLAND puts the CRTC in byte mode, and the sequencer and graphics controller are set for sequential mode.

This will affect how the characters it writes into memory are mapped.

Does it instruct MS-DOS to write directly the read file contents into VRAM?

I see lots of INT 21h function AX=1A1Ah followed by INT 21h function AX=2121h (memory at DS:BX=2)?

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

Reply 3 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-24, 16:29:

Does it instruct MS-DOS to write directly the read file contents into VRAM?

I see lots of INT 21h function AX=1A1Ah followed by INT 21h function AX=2121h (memory at DS:BX=2)?

Yes, it does. It sets the map mask register to isolate the appropriate plane, then Int 21h 3F to read two blocks of 8000h with destination A0000 and A8000.

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

Reply 4 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member

btw, if you want to eliminate the whole drive a/b business, just load up fland.exe in a hex editor. At FF21 you will find the names of several files with a 'b' drive specifier. Change b to a. Voila, now fland will run off a single disk.

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

Reply 5 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 16:43:

btw, if you want to eliminate the whole drive a/b business, just load up fland.exe in a hex editor. At FF21 you will find the names of several files with a 'b' drive specifier. Change b to a. Voila, now fland will run off a single disk.

You're right. I see it reading the attr file to .... HUH????? DMA channel 2 is writing to the VRAM memory area that's unmapped for DMA controllers (they can only access normal memory)?
Edit: Ah. It's the floppy read DMA transfer reading from floppy directly to the VRAM.
But UniPCemu doesn't support DMA transfers from/to memory mapped hardware, so that fails (black hole)!

Edit: Just made DMA capable of accessing video memory and BIOS ROM (just not CPU internal things like APIC and some special reserved memory areas (like SMRAM)).

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

Reply 6 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member

One fun thing about DMA to VRAM is that technically, we need to account for the CGA wait states when performing the transfer. The DMA controller obeys the READY line in a similar way that the CPU does. I don't emulate this yet - just means that things will get put in VRAM faster than they should on hardware.

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

Reply 7 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 17:55:

One fun thing about DMA to VRAM is that technically, we need to account for the CGA wait states when performing the transfer. The DMA controller obeys the READY line in a similar way that the CPU does. I don't emulate this yet - just means that things will get put in VRAM faster than they should on hardware.

UniPCemu already does obey the READY line in it's DMA controller already (when I implemented it on the CPU, I also implemented it into the DMA controller).

Edit: EGA fantasy land loads properly now! 😁

Filename
51-UniPCemu_EGAfanyasylandisalive.png
File size
4.1 KiB
Downloads
No downloads
File comment
UniPCemu running EGA fantasy land!
File license
Fair use/fair dealing exception
Last edited by superfury on 2024-02-24, 17:59. 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 8 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-24, 17:57:
GloriousCow wrote on 2024-02-24, 17:55:

One fun thing about DMA to VRAM is that technically, we need to account for the CGA wait states when performing the transfer. The DMA controller obeys the READY line in a similar way that the CPU does. I don't emulate this yet - just means that things will get put in VRAM faster than they should on hardware.

UniPCemu already does obey the READY line in it's DMA controller already (when I implemented it on the CPU, I also implemented it into the DMA controller).

Just curious, what was your approach to handling DRAM refresh DMA? How does your CPU know when that is about to occur to have it trigger on the appropriate cycle?

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

Reply 9 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 17:59:
superfury wrote on 2024-02-24, 17:57:
GloriousCow wrote on 2024-02-24, 17:55:

One fun thing about DMA to VRAM is that technically, we need to account for the CGA wait states when performing the transfer. The DMA controller obeys the READY line in a similar way that the CPU does. I don't emulate this yet - just means that things will get put in VRAM faster than they should on hardware.

UniPCemu already does obey the READY line in it's DMA controller already (when I implemented it on the CPU, I also implemented it into the DMA controller).

Just curious, what was your approach to handling DRAM refresh DMA? How does your CPU know when that is about to occur to have it trigger on the appropriate cycle?

UniPCemu's CPU and DMA both use the same kind of memory handling basically. Stuff like delays are handled in exactly the same way (with regards to the waitstates at least).

The CPU checks when starting any memory transfer a variable that indicates which device has bus control (PCI(IDE) or DMA or CPU(lowest priority)). The DMA and PCI overruling the CPU in priority (DMA/PCI > CPU).

Edit: Hmmm... I don't think I see pel panning so far? Are interrupts used with said demo? IRQ is lowered and vertical retrace end register is set to 10h.

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

Reply 10 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-24, 18:04:

UniPCemu's CPU and DMA both use the same kind of memory handling basically. Stuff like delays are handled in exactly the same way (with regards to the waitstates at least).

The CPU checks when starting any memory transfer a variable that indicates which device has bus control (PCI(IDE) or DMA or CPU(lowest priority)). The DMA and PCI overruling the CPU in priority (DMA/PCI > CPU).

But is this updated per cycle? A DMA transfer may not be active when the CPU begins an instruction, but sometime after, and impact transfers for that instruction.

superfury wrote on 2024-02-24, 18:04:

Edit: Hmmm... I don't think I see pel panning so far? Are interrupts used with said demo? IRQ is lowered and vertical retrace end register is set to 10h.

The pel panning is done in the IRQ2 ISR. If the bottom window is moving up and down smoothly, you should already be handling that...

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

Reply 11 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 18:27:
But is this updated per cycle? A DMA transfer may not be active when the CPU begins an instruction, but sometime after, and imp […]
Show full quote
superfury wrote on 2024-02-24, 18:04:

UniPCemu's CPU and DMA both use the same kind of memory handling basically. Stuff like delays are handled in exactly the same way (with regards to the waitstates at least).

The CPU checks when starting any memory transfer a variable that indicates which device has bus control (PCI(IDE) or DMA or CPU(lowest priority)). The DMA and PCI overruling the CPU in priority (DMA/PCI > CPU).

But is this updated per cycle? A DMA transfer may not be active when the CPU begins an instruction, but sometime after, and impact transfers for that instruction.

superfury wrote on 2024-02-24, 18:04:

Edit: Hmmm... I don't think I see pel panning so far? Are interrupts used with said demo? IRQ is lowered and vertical retrace end register is set to 10h.

The pel panning is done in the IRQ2 ISR. If the bottom window is moving up and down smoothly, you should already be handling that...

The bottom window is moving up and down, but it looks to be in character clocks or something like that?
I don't ever see it writing the PEL panning register at all.

The bottom window seems to be at odd locations though (during the island the final row seems to be displaying a part of the (last?) scanline only. Then, showing the island shows a weird bottom screen? It isn't hidden?

UniPCemu triggers IRQ2 on XT machines (9 on AT).

IRQ2 is raised when vertical retrace starts, with Vertical Retrace end register bit 4 set and bit 5 cleared (setting the flipflop). It's set and not changing afterwards?

Clearing Vertical Retrace End register bit 4 clears the interrupt flipflop.

The flipflop being set(1)/cleared(0) is reported on Input Status #0 register bit 7, inverted on EGA (not on (S)VGA).

Last edited by superfury on 2024-02-24, 18:51. 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 12 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-24, 18:39:

IRQ2 is raised when vertical retrace starts, with Vertical Retrace end register bit 4 set and bit 5 cleared (setting the flipflop). It's set and not changing afterwards?

Lower it at the end of vertical retrace. I know that seems counterintuitive since there's a bit to lower it as well...

EDIT: I'm not 100% sure this is correct, but I had similar behavior and this is what fixed it. I'll need to look at the schematic again to know for sure.

EDIT2: Well, looking at the diagram the IRQ2 line is directly connected to CRTC, so it could do whatever. I'd have to stick my scope on it and see if it clears automatically at vsync without resetting that register bit.

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

Reply 13 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 18:50:
Lower it at the end of vertical retrace. I know that seems counterintuitive since there's a bit to lower it as well... […]
Show full quote
superfury wrote on 2024-02-24, 18:39:

IRQ2 is raised when vertical retrace starts, with Vertical Retrace end register bit 4 set and bit 5 cleared (setting the flipflop). It's set and not changing afterwards?

Lower it at the end of vertical retrace. I know that seems counterintuitive since there's a bit to lower it as well...

EDIT: I'm not 100% sure this is correct, but I had similar behavior and this is what fixed it. I'll need to look at the schematic again to know for sure.

EDIT2: Well, looking at the diagram the IRQ2 line is directly connected to CRTC, so it could do whatever. I'd have to stick my scope on it and see if it clears automatically at vsync without resetting that register bit.

Just found out that UniPCemu inverted the vertical retrace interrupt flipflop on bit 7 of the Input Status Register #0 on the EGA? So 0 was interrupt raised and 1 for interrupt lowered?

Documentation says (input status #0 register):

CRT Interrupt-A logical 1 indicates video is
being displayed on the CRT screen; a logical 0
indicates that vertical retrace is occurring.

https://pdos.csail.mit.edu/6.828/2004/reading … doc/EGAREGS.TXT basically says the opposite?

Edit: I see interrupts being triggered multiple times? During the screen displaying the first message, it's disabled using the interrupt controller (IMR disables IRQ2, which is left raised)?

Last edited by superfury on 2024-02-24, 19:53. 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 14 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member

Good catch. The input status #0 register is implemented via 74LS367 hex bus driver. CRTINT from the CRTC goes directly here, and mapped to bit 7. I don't see it inverted anywhere.
CHIPS documentation on their clone CRTC says that CRTINT is active-high.

Wouldn't be the first time IBM documentation was wrong.

Could be why FLAND didn't automatically clear the interrupt - it expected the correct status bit before clearing.

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

Reply 15 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member

This has some additional interesting implications. Since the ISR bit is driven by CRTINT from the CRTC and not the VSYNC pin, if we disable interrupts it would seem we actually can't detect vsync at all?

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

Reply 16 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 20:03:

This has some additional interesting implications. Since the ISR bit is driven by CRTINT from the CRTC and not the VSYNC pin, if we disable interrupts it would seem we actually can't detect vsync at all?

Other than reading the Input Status #0 register of course?

Last edited by superfury on 2024-02-24, 20:30. 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 17 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-24, 20:23:
GloriousCow wrote on 2024-02-24, 20:03:

This has some additional interesting implications. Since the ISR bit is driven by CRTINT from the CRTC and not the VSYNC pin, if we disable interrupts it would seem we actually can't detect vsync at all?

Other than reading the Input Status #0 register of course?

my statement was directly about the input status register. was i unclear?

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

Reply 18 of 26, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-24, 20:26:
superfury wrote on 2024-02-24, 20:23:
GloriousCow wrote on 2024-02-24, 20:03:

This has some additional interesting implications. Since the ISR bit is driven by CRTINT from the CRTC and not the VSYNC pin, if we disable interrupts it would seem we actually can't detect vsync at all?

Other than reading the Input Status #0 register of course?

my statement was directly about the input status register. was i unclear?

You're right.

What about the 8259 IRR register? UniPCemu has IRR2 raised (it's parallel interrupt lines), so the line is actually raised.
But the IMR register bit 2 is s, so the IRR isn't set somehow? IMR is BCh.

Last edited by superfury on 2024-02-24, 21:03. 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 19 of 26, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-24, 20:55:

What about the 8259 IRR register? UniPCemu has IRR2 raised (it's parallel interrupt lines), so the line is actually raised.
But the IMR register bit 2 is s, so the IRR isn't set somehow? IMR is BCh.

If you turn off vsync interrupts in the CRTC, then I assume CRTINT is not produced. Therefore you have no interrupts, the PIC doesn't get involved, and crucially, bit 7 in the input status register isn't driven by anything, so you can't detect vsync anymore. That's all I was saying.

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