VOGONS


EXMS86 (XMS for your 8086)

Topic actions

Reply 40 of 74, by mateusz.viste

User metadata
Rank Member
Rank
Member

@Sneakernets - here is the 0.9.2 beta 2 version. No major changes, just cleanup and some refactorization. It fails some of my tests and I struggle to know if it's because of the virtualization or if it would also fail on real hardware. I've included a test program. Would you mind running it on your PC and tell me what it says? The program performs a set of XMS copying tests and displays the results (OK/ERROR) for each.

http://mateusz.fr

Reply 41 of 74, by mateusz.viste

User metadata
Rank Member
Rank
Member

I have released EXMS86 v0.9.2. EXMS86 does all kinds of little things that are supposed to be done by the EMS 4.0 cards, like far pointer normalization, segmentation of multiple-pages transfers and such (at the cost of slightly worse performances and increased memory footprint).

EXMS86 works perfectly now on my wonky virtual setup so hopefully it should work on hardware as well. I tested it with DOSMid, Wolf3D, FreeCOM, and my own custom suite of XMS tests.

http://mateusz.fr

Reply 42 of 74, by mkarcher

User metadata
Rank l33t
Rank
l33t
mateusz.viste wrote on 2025-07-24, 10:12:

I think that such games are very unlikely to work on an 8086, because of the common assumption that "XMS = 386+".

XMS = 386+ would be a very strange assumption. But the assumption that any system that has an XMS driver contains a 286 processor seems reasonable, as the point of the Extended Memory Specification is to manage memory that is mapped into the processor space above 1MB, and such memory did not exist before the 286.

Using the XMS API like a RAM disk that can read and write blocks into a "black box" clearly makes sense for real-mode DOS software (and that's why EXMS86 works), but limiting XMS to that use is in no way specification compliant. Real XMS up to 16MB might for example be used for DMA transfers. I wonder whether any 286 game loaded Sound Blaster samples into XMS, and directly played them from XMS. At the moment, this sounds like a very clever idea to me, as this means that the samples are directly accessible for the DMA system and take up zero space in precious conventional memory.

Reply 43 of 74, by mateusz.viste

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-07-25, 21:30:

Using the XMS API like a RAM disk that can read and write blocks into a "black box" clearly makes sense for real-mode DOS software (and that's why EXMS86 works), but limiting XMS to that use is in no way specification compliant.

EXMS86 is compliant to the XMS 2.0 spec. It does not implement *all* of it, but that's not mandatory - the spec explicitly states that "Developers should keep in mind that some of the XMS API functions may not be implemented by all drivers and will return failure in all cases."
For example EXMS86 has no support for XMS functions related to HMA, UMB and A20. It also does not support the call "give me the physical location of the XMS memory allocated to my handle".

mkarcher wrote on 2025-07-25, 21:30:

Real XMS up to 16MB might for example be used for DMA transfers. I wonder whether any 286 game loaded Sound Blaster samples into XMS, and directly played them from XMS. At the moment, this sounds like a very clever idea to me, as this means that the samples are directly accessible for the DMA system and take up zero space in precious conventional memory.

Sounds plausible, yes, albeit there is one difficulty: DMA cannot cross 64K boundaries, so it would require a bit of heavy lifting to locate a proper place in the XMS space. It would also require to "lock" the XMS handle to ensure the driver will not relocate the data at some inconvenient time... but the spec says that "Locked blocks should be unlocked as soon as possible", so I wonder how that would play out in practice.

http://mateusz.fr

Reply 44 of 74, by Baron von Riedesel

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-07-25, 21:30:

I wonder whether any 286 game loaded Sound Blaster samples into XMS, and directly played them from XMS. At the moment, this sounds like a very clever idea to me, as this means that the samples are directly accessible for the DMA system and take up zero space in precious conventional memory.

From my work on vsbhda I know that "Legend of Kyrandia 2" and "Sword and Fairy 1" use XMS memory for a SB sound buffer. Both games don't check whether the physical address returned by the XMS lock function is within the first 16 MB of the address space.

Reply 45 of 74, by mkarcher

User metadata
Rank l33t
Rank
l33t
Baron von Riedesel wrote on 2025-07-26, 04:53:

From my work on vsbhda I know that "Legend of Kyrandia 2" and "Sword and Fairy 1" use XMS memory for a SB sound buffer. Both games don't check whether the physical address returned by the XMS lock function is within the first 16 MB of the address space.

Thanks for your input. I am surprised to head that this applies to a game released in 1993 and a game release in 1995(!). In 1995, everyone should have heard about PCs with a processor that has an address space bigger than 16M, albeit the typical RAM amount still was 8 to 16MB, so I think this explains why the manufacturer still got away with it.

BTW, as you mention VSBHDA: Last week I submitted https://github.com/crazii/SBEMU/pull/163 , which you might be interested in as well.

Reply 46 of 74, by Baron von Riedesel

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-07-26, 07:25:

BTW, as you mention VSBHDA: Last week I submitted https://github.com/crazii/SBEMU/pull/163 , which you might be interested in as well.

Indeed Interesting! As it happens, I own such a board - a cheap Medion MB. I used it trying to make sound work in sbemu for ES1731, but I didn't got it working ( neither with sbemu nor in Win9x ), so I assumed it's dysfunctional and gave up.

Reply 47 of 74, by Jo22

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2025-07-25, 21:30:
mateusz.viste wrote on 2025-07-24, 10:12:

I think that such games are very unlikely to work on an 8086, because of the common assumption that "XMS = 386+".

XMS = 386+ would be a very strange assumption. But the assumption that any system that has an XMS driver contains a 286 processor seems reasonable, as the point of the Extended Memory Specification is to manage memory that is mapped into the processor space above 1MB, and such memory did not exist before the 286.

Using the XMS API like a RAM disk that can read and write blocks into a "black box" clearly makes sense for real-mode DOS software (and that's why EXMS86 works), but limiting XMS to that use is in no way specification compliant. Real XMS up to 16MB might for example be used for DMA transfers. I wonder whether any 286 game loaded Sound Blaster samples into XMS, and directly played them from XMS. At the moment, this sounds like a very clever idea to me, as this means that the samples are directly accessible for the DMA system and take up zero space in precious conventional memory.

What comes to mind..

The PCE emulator provides XMS for an emulated 8088/8086 XT class system.
I haven't really checked the sources, though, so I don’t know how it's implemented.

The AST Rampage series of memory boards had a rex.sys driver that seemingly converted EMS/XMA (as provided by remm.sys driver) to Extended Memory (int15h BIOS function, not XMS).

E.3 Extended Memory Emulator - REX.SYS
REX interfaces with the REMM program to make Rampage 286 expanded memory act like extended memory.
This allows you to use AST's fASTdisk, SuperDrive, and SuperSpool (also IBM DOS 3.x VDISK.SYS utility with the "/E" option) to
create RAM disks or a print spooler in Rampage 286 expanded memory which emulates extended memory.
[..]
REX intercepts calls on read-only memory basic input/output system (ROM BIOS) functions designed for extended memory
use, and interfaces them to the REMM software so that they can use Rampage 286 expanded memory As with applications
that use the REMM software, program code portions of the SuperPak programs must reside in the 640 KB of PC-AT memory.
However, data associated with SuperPak utilities can use Rampage 286 expanded memory.

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 48 of 74, by mateusz.viste

User metadata
Rank Member
Rank
Member

EXMS86 v0.9.3 is out!

It is EMS 3.2 compliant now. Yay. :-)

The next version will probably not happen before some time as I'm quite content with how it works now. It's likely that the next one will be a final 1.0 that is only slightly polished - like a little bit faster, somewhat smaller, better documented, etc.

http://mateusz.fr

Reply 49 of 74, by digger

User metadata
Rank Oldbie
Rank
Oldbie
Baron von Riedesel wrote on 2025-07-26, 04:53:
mkarcher wrote on 2025-07-25, 21:30:

I wonder whether any 286 game loaded Sound Blaster samples into XMS, and directly played them from XMS. At the moment, this sounds like a very clever idea to me, as this means that the samples are directly accessible for the DMA system and take up zero space in precious conventional memory.

From my work on vsbhda I know that "Legend of Kyrandia 2" and "Sword and Fairy 1" use XMS memory for a SB sound buffer. Both games don't check whether the physical address returned by the XMS lock function is within the first 16 MB of the address space.

That must have been a typical trick employed by Westwood Studios then, since Dune II also requires XMS in order to play back digital samples.

How would it work on 8-bit DMA, though? Doesn't only high DMA have access to the full 16MB of memory?

Reply 50 of 74, by mateusz.viste

User metadata
Rank Member
Rank
Member

I looked at "Legend of Kyrianda", book 1 - apparently it uses XMS when available, and if no XMS it uses only conventional memory. When starting with EXMS86 it says "taking advantage of extended memory", so it seems to be one of those that work with XMS when available, do not care about EMS and runs in degraded mode when no XMS is found. The game seems to work fine with EXMS86, albeit I didn't play much. Looks fun, though. Not sure it's 8086 compatible, I only tested it in DOSBox with XMS provided by EXMS86.

http://mateusz.fr

Reply 51 of 74, by mkarcher

User metadata
Rank l33t
Rank
l33t
digger wrote on 2025-07-29, 09:26:
Baron von Riedesel wrote on 2025-07-26, 04:53:

From my work on vsbhda I know that "Legend of Kyrandia 2" and "Sword and Fairy 1" use XMS memory for a SB sound buffer. Both games don't check whether the physical address returned by the XMS lock function is within the first 16 MB of the address space.

That must have been a typical trick employed by Westwood Studios then, since Dune II also requires XMS in order to play back digital samples.

How would it work on 8-bit DMA, though? Doesn't only high DMA have access to the full 16MB of memory?

No, on the IBM AT (and up), all 7 ISA DMA channel can access the full 16 MB of memory. The low DMA channels can address data from one out of 256 run-time selectable "pages" of 64K each, and the high DMA channels can address data from one out of 128 run-time selectable "pages" of 128K each. The PC/XT only had 16 pages of 64K each on its three DMA channels. EISA extended the DMA addressable space to 4G, and some ISA chipsets copied part of the EISA design, but generally, ISA DMA kept being limited to the original 16M already supported by the AT.

Reply 52 of 74, by weedeewee

User metadata
Rank l33t
Rank
l33t
mkarcher wrote on 2025-07-29, 14:51:
digger wrote on 2025-07-29, 09:26:
Baron von Riedesel wrote on 2025-07-26, 04:53:

From my work on vsbhda I know that "Legend of Kyrandia 2" and "Sword and Fairy 1" use XMS memory for a SB sound buffer. Both games don't check whether the physical address returned by the XMS lock function is within the first 16 MB of the address space.

That must have been a typical trick employed by Westwood Studios then, since Dune II also requires XMS in order to play back digital samples.

How would it work on 8-bit DMA, though? Doesn't only high DMA have access to the full 16MB of memory?

No, on the IBM AT (and up), all 7 ISA DMA channel can access the full 16 MB of memory. The low DMA channels can address data from one out of 256 run-time selectable "pages" of 64K each, and the high DMA channels can address data from one out of 128 run-time selectable "pages" of 128K each. The PC/XT only had 16 pages of 64K each on its three DMA channels. EISA extended the DMA addressable space to 4G, and some ISA chipsets copied part of the EISA design, but generally, ISA DMA kept being limited to the original 16M already supported by the AT.

Are both low (0-3) and high 4-7 dma channels capable of 8 and 16 bit wide transfers ?

Right to repair is fundamental. You own it, you're allowed to fix it.
How To Ask Questions The Smart Way
Do not ask Why !
https://www.vogonswiki.com/index.php/Serial_port

Reply 53 of 74, by mkarcher

User metadata
Rank l33t
Rank
l33t
weedeewee wrote on 2025-07-29, 15:12:

Are both low (0-3) and high 4-7 dma channels capable of 8 and 16 bit wide transfers ?

On AT-compatible systems: No. The 16 bit transfers work by connecting the address lines of the second Intel 8237A DMA controller (that provides DMA channels 5 to 7) shifted by one bit, so that controller addresses and counts words instead of bytes. This is hardwired.

On EISA-compatible systems: Yes. The EISA DMA controller is way more flexible and capable than the combination of two discrete Intel 8237A chips combined with some glue logic. Every channel can be set to 8, 16 or 32 bit operation, with the default configuration being channels 0-3 set to 8-bit operation and channels 5-7 set to 16-bit operation, counting in words. An EISA DMA controller also supports scatter/gather DMA, can disable the obnoxious 64K/128K barrier of the XT/AT DMA subsystem and can generate interrupts related to DMA transfers independently of the device that requests the DMA data.

Reply 54 of 74, by weedeewee

User metadata
Rank l33t
Rank
l33t
mkarcher wrote on 2025-07-29, 19:05:
weedeewee wrote on 2025-07-29, 15:12:

Are both low (0-3) and high 4-7 dma channels capable of 8 and 16 bit wide transfers ?

On AT-compatible systems: No. The 16 bit transfers work by connecting the address lines of the second Intel 8237A DMA controller (that provides DMA channels 5 to 7) shifted by one bit, so that controller addresses and counts words instead of bytes. This is hardwired.

On EISA-compatible systems: Yes. The EISA DMA controller is way more flexible and capable than the combination of two discrete Intel 8237A chips combined with some glue logic. Every channel can be set to 8, 16 or 32 bit operation, with the default configuration being channels 0-3 set to 8-bit operation and channels 5-7 set to 16-bit operation, counting in words. An EISA DMA controller also supports scatter/gather DMA, can disable the obnoxious 64K/128K barrier of the XT/AT DMA subsystem and can generate interrupts related to DMA transfers independently of the device that requests the DMA data.

so, on isa systems, dma 0-3 can only do 8 bit transfers, and dma 4-7 only does 16 bit transfers ?
That's the way I remember it.

Right to repair is fundamental. You own it, you're allowed to fix it.
How To Ask Questions The Smart Way
Do not ask Why !
https://www.vogonswiki.com/index.php/Serial_port

Reply 55 of 74, by mkarcher

User metadata
Rank l33t
Rank
l33t
weedeewee wrote on 2025-07-29, 19:37:

so, on isa systems, dma 0-3 can only do 8 bit transfers, and dma 4-7 only does 16 bit transfers ?
That's the way I remember it.

DMA 4 can not do any transfer, as the first channel on the "16-bit controller" is connected to the "upstream port" of the "8-bit controller". This means whenever a transfer on channels 0 to 3 happens, the 8-bit controller requests a transfer on "channel 4", which causes the "16-bit controller" to request the bus from the processor. Once the 16-bit controller owns the bus, it signals bus ownership to the 8-bit controller, which then generates the 8-bit transfer. The 16-bit controller does not interfere, because channel 4 is set into "cascade/bus master" mode, in which the DMA controller is only used for bus arbitration, but the bus requestor then performs DMA on its own.

DMA 0 to 3 can do 8-bit transfers, and DMA 5 to 7 can do 16-bit transfers.

On the PC and XT, DMA 0 was used to generate refresh cycles: The timer periodically asked the DMA controller to "do a transfer on channel 0" (it asserts DRQ0), and as as soon as the DMA controller signalled that channel 0 is now performing a transfer (it asserts DACK0), the mainboard logic used the address driven by the DMA controller to refresh one row of memory. On the AT, memory refresh was implemented in dedicated logic, so DMA 0 got a general-purpose channel. As there was no general purpose "DMA 0" on the PC/XT, the 8-bit ISA connector does not have DRQ0 and DACK0, those signals are on the 16-bit ISA extension, even though this is an 8-bit channel.

Reply 56 of 74, by weedeewee

User metadata
Rank l33t
Rank
l33t
mkarcher wrote on 2025-07-29, 20:35:
DMA 4 can not do any transfer, as the first channel on the "16-bit controller" is connected to the "upstream port" of the "8-bit […]
Show full quote
weedeewee wrote on 2025-07-29, 19:37:

so, on isa systems, dma 0-3 can only do 8 bit transfers, and dma 4-7 only does 16 bit transfers ?
That's the way I remember it.

DMA 4 can not do any transfer, as the first channel on the "16-bit controller" is connected to the "upstream port" of the "8-bit controller". This means whenever a transfer on channels 0 to 3 happens, the 8-bit controller requests a transfer on "channel 4", which causes the "16-bit controller" to request the bus from the processor. Once the 16-bit controller owns the bus, it signals bus ownership to the 8-bit controller, which then generates the 8-bit transfer. The 16-bit controller does not interfere, because channel 4 is set into "cascade/bus master" mode, in which the DMA controller is only used for bus arbitration, but the bus requestor then performs DMA on its own.

DMA 0 to 3 can do 8-bit transfers, and DMA 5 to 7 can do 16-bit transfers.

On the PC and XT, DMA 0 was used to generate refresh cycles: The timer periodically asked the DMA controller to "do a transfer on channel 0" (it asserts DRQ0), and as as soon as the DMA controller signalled that channel 0 is now performing a transfer (it asserts DACK0), the mainboard logic used the address driven by the DMA controller to refresh one row of memory. On the AT, memory refresh was implemented in dedicated logic, so DMA 0 got a general-purpose channel. As there was no general purpose "DMA 0" on the PC/XT, the 8-bit ISA connector does not have DRQ0 and DACK0, those signals are on the 16-bit ISA extension, even though this is an 8-bit channel.

Yes, exactly.

Right to repair is fundamental. You own it, you're allowed to fix it.
How To Ask Questions The Smart Way
Do not ask Why !
https://www.vogonswiki.com/index.php/Serial_port

Reply 57 of 74, by digger

User metadata
Rank Oldbie
Rank
Oldbie
mkarcher wrote on 2025-07-29, 14:51:

No, on the IBM AT (and up), all 7 ISA DMA channel can access the full 16 MB of memory. The low DMA channels can address data from one out of 256 run-time selectable "pages" of 64K each, and the high DMA channels can address data from one out of 128 run-time selectable "pages" of 128K each. The PC/XT only had 16 pages of 64K each on its three DMA channels. EISA extended the DMA addressable space to 4G, and some ISA chipsets copied part of the EISA design, but generally, ISA DMA kept being limited to the original 16M already supported by the AT.

That's the cool thing about this forum. I keep learning new stuff from the DOS PC era. Thanks. 🙂

Wasn't it still the case that ISA DMA was kind of a bottleneck, especially on anything faster than a 286, since it always had to access the system RAM at 5MHz?

It's kind of disappointing that it ended up being the primary I/O method for playing back digitized audio samples on popular sound cards back in the day, causing major headaches w.r.t. DOS sound compatibility once PCs moved beyond ISA slots.

If I understand correctly, from the 386 and up, this became such a bottleneck, that even driving a Covox-like dumb LPT DAC directly would be take up less overhead than relying on ISA DMA for digital sound playback. Or does that deserve more nuance?

Reply 58 of 74, by wierd_w

User metadata
Rank Oldbie
Rank
Oldbie

So... Since these games rely on isa dma being able to select a region of memory the cpu can actually talk to (which is limited to a 1mb space on an 8088/8086), and the game *cannot know* what this chunk of memory's physical address will be without the XMM telling it so, a kludge presents itself.

The XMM reports the location of the EMS pageframe for servicing these DMA calls, rather than a logical XMS virtual address. It uses the virtual address to keep track of which EMS page needs to be in the frame, and ensures that this page is active before DMA triggers. The DMA reads from the frame, then ends. It gets the expected data, and nobody has to know different.

On an 8086 system, the xms locked location cannot be outside 1mb, because there are not any physical address lines above this for the dma controller to even assert.

Trapping for 'above 1mb' on xms lock requests, and keeping some housekeeping data about this for just 'in time' page switches 'might work'?

Eg, for addresses above 1mb, the XMM reports an address for the locked block that, if you strip off the top address bits (because there are no lines to carry them anyway!) 'Just so happens' to be the address of the pageframe in the 1mb space.

The DMA chip accepts the address bits its actually capable of servicing, and reads from the pageframe.

??

There isn't a real reason the XMS memory reported by this manager has to be 'contiguous'. 'Memory hole at 16mb' was a real thing on AT machines, after all.

Reply 59 of 74, by mateusz.viste

User metadata
Rank Member
Rank
Member
wierd_w wrote on 2025-07-30, 15:00:

So... Since these games rely on isa dma being able to select a region of memory the cpu can actually talk to (which is limited to a 1mb space on an 8088/8086), and the game *cannot know* what this chunk of memory's physical address will be without the XMM telling it so, a kludge presents itself.

It would be nice to know what applications exactly need a kludge in the first. Ie. applications that are 8086-compatible AND XMS-capable AND EMS-unaware AND use DMA-over-XMS.
The "Legend of Kyrandia 2" has been mentioned earlier, but it's a 200M download so I somehow doubt it's 8086-compatible. I've checked the first part though, and it works well with EXMS86 (sound included).

wierd_w wrote on 2025-07-30, 15:00:

The XMM reports the location of the EMS pageframe for servicing these DMA calls, rather than a logical XMS virtual address. It uses the virtual address to keep track of which EMS page needs to be in the frame, and ensures that this page is active before DMA triggers. The DMA reads from the frame, then ends. It gets the expected data, and nobody has to know different.

Problem: there may be other users of the EMS subsystem. Like some disk caches or what not. EXMS86 is supposed to leave the page frame intact when it returns, so it does not disturb others.

http://mateusz.fr