First post, by carlostex
- Rank
- l33t
Hi there!
Tandy 3 voice sound on an AT class computer (286+) always faced the second DMA controller problem. As you know, on the IBM AT and following clones a second Intel 8237 DMA controller was placed on port 0C0h, right where IBM PC/Jr and Tandy 1000 PC's ha the 3 voice chip. So AT users with homebrew Tandy cards, had commonly their cards set to port 2C0h. Port 1E0h, as with later Tandy PC's, which the Tandy 1000 RSX and the 2500XL, kept the PSSJ but relocated to port 1E0h. Later Tandy PC's thus had their compatibility broken with older software.
Enter the software solution. Through the years we got redirection utilities, for both the ISA cards and the TNDLPT device. Recently, i was discussing here on VOGONS about repatching for the INT C0h trick. This is a better approach than the TSR method as port trapping is made completely unnecessary, no need for QEMM or EMM386! However, i started to be a bit more ambitious... Why not patch for a 2 byte port? Directly to port 2C0h... Possible? Why is this difficult?
As some of you might know with only 2 bytes you can do this:
E6 C0 -> OUT C0, AL
With only 2 bytes you spit out the data that is on AL right directly to the Tandy chip I/O port.
Now for a 2 byte port like 2c0h?
52 -> PUSH DX
BAC002 -> MOV DX, 2c0
EE -> OUT DX, AL
5A -> POP DX
Ouch... that's 6 bytes... One can try and remove saving DX into the stack but it's still 4 bytes and there's situations you can't simply destroy what's on DX, as it might be needed later. So the options:
Option 1:
Find some empty space within the segment where we can jump and create our patch code. Short jumps are 2 bytes long which fit but 99% of the time there's no space around the +- 128 bytes. So better do a CALL, but that's 3 bytes. So that requires this, like the following example:
8AC4
E6C0
We now have 4 bytes to do a CALL and there will be a NOP left over:
E8 xx xx -> CALL to .... (wherever we find the space without effing up)
90
and the patched code will look like this:
8AC4
52
BAC002
EE
5A
C3 -> RETURN BACK to the caller, will land on that stray NOP (which is fine)
Above is fine as long as it's within the same segment, or you're not overwriting reserved space for something else.
Option 2:
Now this one is a LOT more work, but it's ALWAYS better. It's common, (at least a lot of games have them) to find multiple 2 byte SHIFT instructions like so:
D0E0 -> SHL AL, 1
D0E0 -> SHL AL, 1
D0E0 -> SHL AL, 1
D0E0 -> SHL AL, 1
Why not SHL AL, 4?
C0E004 -> SHL AL, 4
and like that we save 5 bytes!!!! OK this will require the 186 instruction set but who cares? XT systems can use port 0C0h anyway....
We're not out of the woods yet, so i need to carefully rewrite ALL instructions realign jumps and calls in between always cross referencing every instruction!
But it works, and soon enough i reach the E6 C0 instruction and i have enough space to patch! Sometimes i have to use a combination of both methods!
Honestly, it's a lot of work...but i don't mind. I'm actually enjoying doing this. A bit masochistic, but it has been an enriching experience. I still face some difficulties though...dreaded ENCRYPTION. Some files are packed/encrypted and it's impossible to patch otherwise. For EA stuff with their LIB files, or DYNAMIX VOL files, SSI with their DAX files, all of those use some kind of compression / encryption that makes it impossible to patch. I have found an unpacking utility for EA LIB files for instance, but the game is expecting to find the packed file during runtime and it completely ignores the unpacked file in the directory. So this would need either some tool to encrypt back the file after i had it patched. These ones are super frustrating because without any encryption it is possible to patch 95% of the time.
So what is the progress at the moment? Well... I have quite a few games patched, i would say around 30 titles or so, which include the classics most everyone likes.
The patches are available at the OLDSKOOL FTP, exactly where my old patches that defeat detection could be found. At the root, you'll now find a folder called ISA with 2 subfolders. One for port 1E0 (great for the AT Tandy PC's) and port 2C0. Some readme's are also included where i thought it would make sense. This is still a WIP, and i guarantee more games will be patched. It is absolutely great to just launch a game not having to depend on any TSR's or redirection tricks, installing INT handlers etc... Just run and go!
I honestly hope that in the future we will see an ISA card that consolidates other similar standards, a single ISA card that would tackle Tandy, CMS, Innovation and Covox Sound Master.