Skip to content

NLS: Upcase function address was lost after loading country.sys - #275

Open
andrewbird wants to merge 1 commit into
FDOS:masterfrom
andrewbird:country-01
Open

andrewbird wants to merge 1 commit into
FDOS:masterfrom
andrewbird:country-01

Conversation

@andrewbird

@andrewbird andrewbird commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

After loading country.sys the Upcase function address was being zeroed out rather than updated correctly. Traced to a NEAR/FAR pointer mismatch. Discovered whilst looking for the cause of #269

Using the Dosemu2 test suite command test/test_dosemu.py FRDOSGITTestCase.test_get_country

Before:

INFO: sym_currency = '0x9c,0x00,0x00,0x00,0x00'
INFO: sep_thousand = ','
INFO: sep_decimal = '.'
INFO: sep_date = '/'
INFO: sep_time = ':'
INFO: fmt_currency = '0'
INFO: num_curdigits = '2'
INFO: fmt_time = '1'
INFO: func_upcase = '0000:0000'
INFO: sep_datalist = ','
<crash>

After:

INFO: sym_currency = '0x9c,0x00,0x00,0x00,0x00'
INFO: sep_thousand = ','
INFO: sep_decimal = '.'
INFO: sep_date = '/'
INFO: sep_time = ':'
INFO: fmt_currency = '0'
INFO: num_curdigits = '2'
INFO: fmt_time = '1'
INFO: func_upcase = '00D9:1338'
INFO: sep_datalist = ','
INFO: upcased_char = 'B'

Tested with Ia16-gcc and Watcom compilers only.

After loading country.sys the Upcase function address was being zeroed
out rather than updated correctly. Traced to a NEAR/FAR pointer
mismatch. Discovered whilst looking for the cause of
FDOS#269

Using the Dosemu2 test suite command
`test/test_dosemu.py FRDOSGITTestCase.test_get_country`

Before:
INFO: fmt_date = '1'
INFO: sym_currency = '0x9c,0x00,0x00,0x00,0x00'
INFO: sep_thousand = ','
INFO: sep_decimal = '.'
INFO: sep_date = '/'
INFO: sep_time = ':'
INFO: fmt_currency = '0'
INFO: num_curdigits = '2'
INFO: fmt_time = '1'
INFO: func_upcase = '0000:0000'
INFO: sep_datalist = ','
<crash>

After:
INFO: fmt_date = '1'
INFO: sym_currency = '0x9c,0x00,0x00,0x00,0x00'
INFO: sep_thousand = ','
INFO: sep_decimal = '.'
INFO: sep_date = '/'
INFO: sep_time = ':'
INFO: fmt_currency = '0'
INFO: num_curdigits = '2'
INFO: fmt_time = '1'
INFO: func_upcase = '00D9:1338'
INFO: sep_datalist = ','
INFO: upcased_char = 'B'

Tested with Ia16-gcc and Watcom compilers only.
@ecm-pushbx

Copy link
Copy Markdown
Contributor

LGTM, assuming you tested this. Although, your description of the problem, "a NEAR/FAR pointer mismatch", doesn't account for the +2 that you had to add.

@ecm-pushbx

Copy link
Copy Markdown
Contributor

If it was previously handled as a wrong + near pointer, did the write corrupt memory in some other segment?

@andrewbird

Copy link
Copy Markdown
Contributor Author

did the write corrupt memory in some other segment?

Well it was writing somewhere so quite possibly, but I didn't find where only that it didn't change what it should have.

Tested fine with the dosemu2 test_get_country https://github.com/dosemu2/dosemu2/blob/devel/test/func_country.py. It was a little late last night for me, so I'll run the full test suite now and check nothing new breaks, but I doubt it as that code path is only run if country.sys is loaded, and I don't do that anywhere else in the tests.

@ecm-pushbx

Copy link
Copy Markdown
Contributor

The patch breaks gcc-ia16 build exactly in the way the bug was originally reported. 21.6501.bx=FFFF.dx=FFFF returns the function pointer as 0:0 and VC v4.05 crashes.

@ecm-pushbx

Copy link
Copy Markdown
Contributor

Prior to patch, gcc-ia16 build works for me.

@andrewbird

Copy link
Copy Markdown
Contributor Author

How strange, both gcc-ia16 and watcom fail without the patch for me and pass with it (but I only tested with int21/38h). So it looks like more work to do then, I'll convert to draft. Thanks!

@andrewbird
andrewbird marked this pull request as draft October 30, 2026 11:24
@andrewbird

Copy link
Copy Markdown
Contributor Author

@ecm-pushbx I thought I'd better write some more tests to see if I can replicate your experience, however I don't see where the upcase function is supposed to be returned in int21/6501. Here's the RBIL https://github.com/LoopZ/TheList/blob/main/source/Interrupt%20List/INT%2021%20DOS%20Function%20Calls/INT%202165%20DOS%2033%20GET%20EXTENDED%20COUNTRY%20INFORMATION.txt . What tool did you use to see the missing value?

@ecm-pushbx

Copy link
Copy Markdown
Contributor

As to how to query the data using 21.65, see https://github.com/LoopZ/TheList/blob/main/source/Interrupt%20List/INT%2021%20DOS%20Function%20Calls/INT%202165%20DOS%2033%20GET%20EXTENDED%20COUNTRY%20INFORMATION.txt#L44 - the 21.38 data is included at offset 7 for info ID = 1.

I placed everything in a directory at https://pushbx.org/ecm/test/20261030/

This includes the kernel file with your patch, built using the gcc-ia16 toolchain on our server.

Here's the log showing how to query the internationalisation data using both 21.6501 and 21.38:

-t=100
AX=6501 BX=0031 CX=0200 DX=0400 SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0103 NV UP EI PL ZR NA PE NC
2A2F:0103 BAFFFF            mov     dx, FFFF
-
AX=6501 BX=0031 CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0106 NV UP EI PL ZR NA PE NC
2A2F:0106 BBFFFF            mov     bx, FFFF
-
AX=6501 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0109 NV UP EI PL ZR NA PE NC
2A2F:0109 B90002            mov     cx, 0200
-
AX=6501 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=010C NV UP EI PL ZR NA PE NC
2A2F:010C BF0002            mov     di, 0200
-
AX=6501 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=010F NV UP EI PL ZR NA PE NC
2A2F:010F F9                stc
-
AX=6501 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0110 NV UP EI PL ZR NA PE CY
2A2F:0110 CD21              int     21
-
AX=6501 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0112 NV UP EI PL ZR NA PE NC
2A2F:0112 CC                int3
-
Unexpected breakpoint interrupt
AX=6501 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0113 NV UP EI PL ZR NA PE NC
2A2F:0113 B80038            mov     ax, 3800
-d es:di l 40
2A2F:0200  01 1C 00 31 00 5A 03 01-00 D5 00 00 00 00 2E 00 ...1.Z..........
2A2F:0210  2C 00 2E 00 3A 00 03 02-01 00 00 00 00 2C 00 20 ,...:........,.
2A2F:0220  20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20
2A2F:0230  20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20
-

-t
AX=3800 BX=FFFF CX=0200 DX=FFFF SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0116 NV UP EI PL ZR NA PE NC
2A2F:0116 BA0004            mov     dx, 0400
-
AX=3800 BX=FFFF CX=0200 DX=0400 SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=0119 NV UP EI PL ZR NA PE NC
2A2F:0119 F9                stc
-
AX=3800 BX=FFFF CX=0200 DX=0400 SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=011A NV UP EI PL ZR NA PE CY
2A2F:011A CD21              int     21
-
AX=0031 BX=0031 CX=0200 DX=0400 SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=011C NV UP EI PL ZR NA PE NC
2A2F:011C 90                nop
-
AX=0031 BX=0031 CX=0200 DX=0400 SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=011D NV UP EI PL ZR NA PE NC
2A2F:011D CC                int3
-
Unexpected breakpoint interrupt
AX=0031 BX=0031 CX=0200 DX=0400 SP=FFFE BP=0000 SI=0000 DI=0200
DS=2A2F ES=2A2F SS=2A2F CS=2A2F IP=011E NV UP EI PL ZR NA PE NC
2A2F:011E 90                nop
-d ds:dx l 40
2A2F:0400  01 00 D5 00 00 00 00 2E-00 2C 00 2E 00 3A 00 03 .........,...:..
2A2F:0410  02 01 00 00 00 00 2C 00-20 20 20 20 20 20 20 20 ......,.
2A2F:0420  20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20
2A2F:0430  20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20
-

And here's the kernel patch I applied (failing), which should match yours:

ulukai2:~/proj/kernel$ ls -lgG bin/kernel.sys kernel/config.c
-rw-r--r-- 1 81652 Oct 30 10:24 bin/kernel.sys
-rw-r--r-- 1 76740 Oct 30 10:24 kernel/config.c
ulukai2:~/proj/kernel$ git diff
diff --git a/kernel/config.c b/kernel/config.c
index e3470f6..63febef 100644
--- a/kernel/config.c
+++ b/kernel/config.c
@@ -1664,7 +1664,7 @@ err:printf("%s has invalid format\n", filename);
                   /* skip length ^*/  subf_data.length);
           if (hdr[i].id == 1) {
               /* fixup user callable address in case we overwrote it */
-              ((struct CountrySpecificInfo *)ptable)->CharMapFn = CharMapFn;
+              ((struct CountrySpecificInfo FAR *)ptable + 2)->CharMapFn = CharMapFn;
           }
       }
     }
ulukai2:~/proj/kernel$

@ecm-pushbx

Copy link
Copy Markdown
Contributor

Argh! I forgot parens around the addition. Retesting now.

@ecm-pushbx

Copy link
Copy Markdown
Contributor

Okay, it ran fine with the proper patch. That still leaves the mystery of how it could have worked prior to this patch.

@ecm-pushbx

Copy link
Copy Markdown
Contributor

Aaaaand I cannot reproduce the lack of failure on an earlier revision - 12f4f7d No idea how I got the wrong result (no failure) earlier.

@ecm-pushbx

Copy link
Copy Markdown
Contributor

So yeah, LGTM and tested every which way now. Proper patch applied rather than a fool trying to manually copy it into her repo makes this work as expected.

@ecm-pushbx
ecm-pushbx marked this pull request as ready for review October 30, 2026 20:28
@andrewbird

Copy link
Copy Markdown
Contributor Author

@ecm-pushbx Thanks for looking at it again, and for your info about int21/6501 too. I'm going to extend the dosemu2 test for 6501 anyway now, so it'll be good to get confirmation that way as well.

@andrewbird

andrewbird commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

So I'm happy that the int21/6501 returns the same data. I did notice a problem with the 6501 specific fields and CX register regarding sizes (they are different from MS and OpenDOS), but that's a subject for another issue/PR I think. Thanks again for your help!

@andrewbird
andrewbird requested a review from PerditionC October 31, 2026 11:40

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants