MS-DOS 6.22 NLSFUNC and CHCP Translation Tables

This article examines how MS-DOS 6.22 processes character translation tables through the coordinated actions of the NLSFUNC driver and the CHCP command. It details how the operating system accesses COUNTRY.SYS, parses localized translation structures, updates internal DOS kernel pointers via interrupt services, and coordinates with device drivers to apply system-wide character mappings.

Core Architectural Components

National Language Support (NLS) in MS-DOS 6.22 relies on three primary components to manage character sets and translation:

  1. COUNTRY.SYS: A binary resource file containing Country Information blocks, code page identifiers, collating tables, uppercase (monocase) translation tables, and Double-Byte Character Set (DBCS) vectors.
  2. NLSFUNC.EXE: A terminate-and-stay-resident (TSR) utility that acts as an intermediary between DOS and COUNTRY.SYS. It hooks the Multiplex Interrupt (INT 2Fh) to provide extended NLS services that are not resident in the default DOS kernel.
  3. CHCP (Change Code Page): The user-facing command that requests a global switch of the active hardware and software code pages.

Initialization via NLSFUNC

The MS-DOS kernel maintains a default Country Information table configured during boot via the COUNTRY= directive in CONFIG.SYS. However, the base kernel cannot parse arbitrary code pages dynamically from disk without external assistance.

When executed, NLSFUNC hooks INT 2Fh using multiplex identifier 14h. It stores the path to COUNTRY.SYS (specified either in CONFIG.SYS or as a command-line argument) in memory. When resident, NLSFUNC intercepts the internal DOS code page switching calls, enabling the system to read and load alternative character translation tables on demand.

The CHCP Execution Flow

When a user executes CHCP <code_page>, the system initiates a synchronized chain of system interrupts:

  1. Global Code Page Request: CHCP invokes DOS Interrupt 21h, Service 6602h (Set Global Code Page), passing the requested code page ID in the BX register.
  2. Hardware Notification: The DOS kernel broadcasts the request to registered character devices (such as CON managed by DISPLAY.SYS and PRN managed by PRINTER.SYS) using Generic IOCTL requests (INT 21h, Function 440Ch, Category 03h, Code 4Ah - Select Code Page). This prompts the display adapter and printer to switch their active font tables.
  3. Internal Multiplex Call: The kernel issues INT 2Fh, Function 1404h (Change Code Page) to communicate with NLSFUNC.

Table Parsing and Extraction from COUNTRY.SYS

Upon intercepting INT 2Fh, AX=1404h, NLSFUNC performs the file-level retrieval:

  • Header Lookup: NLSFUNC opens COUNTRY.SYS and traverses its file header, which consists of records pairing country codes and code page IDs with file offsets.
  • Component Table Extraction: It locates the specific entry matching the target code page and extracts three essential character mapping tables:
    • Uppercase Table: A 130-byte structure. The first two bytes define the table length (usually 128 bytes), followed by the uppercase mappings for ASCII values 80h through FFh.
    • Lowercase-to-Uppercase Filename Table: A dedicated mapping table that maps invalid and valid characters for FAT directory entries.
    • Collating Sequence Table: A 256-byte array that defines the relative sort values for all ASCII characters from 00h to FFh, used by commands like SORT.EXE.
    • DBCS Vector: A table of boundary byte ranges used to identify multi-byte characters in Asian language editions.

Memory Commitment and Kernel Pointer Updates

Once the tables are read from disk:

  1. Buffer Allocation: NLSFUNC places the unpacked translation data into its own resident memory buffers or into designated system memory buffers managed by the DOS operating system.
  2. DOS Internal Pointer Reassignment: NLSFUNC interfaces with the DOS kernel to overwrite the active translation table pointers. It updates the internal DOS Country Information structure (accessible to applications via INT 21h, Function 65h - Get Extended Country Information).
  3. Validation: If the code page is successfully applied to both the DOS kernel tables and the device drivers, the global code page variable stored in the DOS data segment is updated to reflect the new ID.

Runtime Character Translation

After CHCP and NLSFUNC complete the update, character processing changes globally across all applications relying on DOS system calls:

  • File System Operations: When a file is created or accessed, DOS converts lowercase characters to uppercase for the 8.3 filename entry. The kernel retrieves the character byte, checks if it falls within the extended ASCII range (>= 80h), subtracts 80h to find the array offset, and extracts the replacement character from the active uppercase table.
  • String Comparison and Case Conversion: Software using INT 21h, Function 6521h (Capitalize Character) or 6522h (Capitalize String) executes against the newly registered uppercase table, ensuring that language-specific accented characters are converted accurately according to the active code page.