mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 02:17:36 +08:00
Dynamically allocate the second half of the SFT table, zero memory to avoid problems. Windows 3.1 is still pefectly happy with it
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
Next:
|
||||
- DOS kernel: Remove fixed hacks for SFT and dynamically allocate the
|
||||
second SFT table for the last N - 5 file handles. Add code to zero
|
||||
SFT table memory to ensure that random data doesn't cause issues.
|
||||
Windows 3.1 is still perfectly fine with it, so the SFT table update
|
||||
and cleanup is complete. (joncampbell123).
|
||||
- DOS kernel: Move the magic "CON" strings into the first SFT and
|
||||
mimic the 5 default open file handles that every DOS process starts
|
||||
with: CON CON CON AUX PRN. Windows 3.1 is still happy with it, which
|
||||
|
@@ -126,7 +126,7 @@ void DOS_InfoBlock::SetLocation(uint16_t segment) {
|
||||
sSave(sDIB,nulString[6],(uint8_t)0x20);
|
||||
sSave(sDIB,nulString[7],(uint8_t)0x20);
|
||||
|
||||
#if 1 // FIXME: The new code imported from DOSBox Staging is causing Windows 3.1 to crash on exit, so this old code remains active until that can be fixed
|
||||
#if 1
|
||||
/* Create a fake SFT, so programs think there are 100 file handles.
|
||||
* NTS: The INFO block is only given 0x20 paragraphs (0x200 = 512 bytes) which is only enough for a 5-entry SFT table,
|
||||
* however that's what MS-DOS does anyway. For any value of FILES you specify, the first SFT is 5 entries and the
|
||||
@@ -136,9 +136,16 @@ void DOS_InfoBlock::SetLocation(uint16_t segment) {
|
||||
* The table must be 5, or else it extends into other DOS kernel structures and memory corruption might happen. */
|
||||
if (DOS_FILES < 6) E_Exit("[dos] files= setting is too small");
|
||||
|
||||
/* Secondary table */
|
||||
unsigned int tbl2_seg = DOS_GetMemory((SftHeaderSize+(SftEntrySize*(DOS_FILES-5))+0xFu)/16u,"SFT secondary table");
|
||||
|
||||
uint16_t sftOffset=0xCC; /* this offset is fixed according to MS-DOS 5.0, MS-DOS 6.22, Windows 95, etc. */
|
||||
|
||||
/* zero out the table */
|
||||
for (unsigned int i=sftOffset;i < 0x200;i++) real_writeb(segment,i,0);
|
||||
|
||||
sSave(sDIB,firstFileTable,RealMake(segment,sftOffset));
|
||||
real_writed(segment,sftOffset+0x00,RealMake(segment+0x26,0)); //Next File Table
|
||||
real_writed(segment,sftOffset+0x00,RealMake(tbl2_seg,0)); //Next File Table
|
||||
real_writew(segment,sftOffset+0x04,5); //File Table supports 5 files
|
||||
|
||||
if ((sftOffset+SftHeaderSize+(5*SftEntrySize)) > 0x200) E_Exit("Primary SFT is too big");
|
||||
@@ -156,10 +163,10 @@ void DOS_InfoBlock::SetLocation(uint16_t segment) {
|
||||
real_writed(segment,sftOffset+SftHeaderSize+(SftEntrySize*3)+0x20,0x20585541); // AUX
|
||||
real_writed(segment,sftOffset+SftHeaderSize+(SftEntrySize*4)+0x20,0x204e5250); // PRN
|
||||
|
||||
// FIXME: This must be segment+0x26 (DOS_CONSTRING_SEG-2) because some magic "CON" strings must be written there
|
||||
// to make Windows 3.1 happy.
|
||||
real_writed(segment+0x26,0x00,0xffffffff); //Last File Table
|
||||
real_writew(segment+0x26,0x04,DOS_FILES-5); //File Table supports DOS_FILES-5 files
|
||||
/* zero out the table */
|
||||
for (unsigned int i=0;i < (SftHeaderSize+(SftEntrySize*(DOS_FILES-5)));i++) real_writeb(tbl2_seg,i,0);
|
||||
real_writed(tbl2_seg,0x00,0xFFFFFFFFu);
|
||||
real_writew(tbl2_seg,0x04,DOS_FILES-5);
|
||||
|
||||
#else
|
||||
/* Imported from dosbox-staging/dosbox-staging#3680 */
|
||||
|
Reference in New Issue
Block a user