mirror of https://github.com/FDOS/kernel.git
636 lines
29 KiB
C++
636 lines
29 KiB
C++
/****************************************************************/
|
||
/* */
|
||
/* NLS.H */
|
||
/* FreeDOS */
|
||
/* */
|
||
/* National Language Support data structures */
|
||
/* */
|
||
/* Copyright (c) 2000 */
|
||
/* Steffen Kaiser */
|
||
/* All Rights Reserved */
|
||
/* */
|
||
/* This file is part of FreeDOS. */
|
||
/* */
|
||
/* DOS-C is free software; you can redistribute it and/or */
|
||
/* modify it under the terms of the GNU General Public License */
|
||
/* as published by the Free Software Foundation; either version */
|
||
/* 2, or (at your option) any later version. */
|
||
/* */
|
||
/* DOS-C is distributed in the hope that it will be useful, but */
|
||
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||
/* the GNU General Public License for more details. */
|
||
/* */
|
||
/* You should have received a copy of the GNU General Public */
|
||
/* License along with DOS-C; see the file COPYING. If not, */
|
||
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||
/* Cambridge, MA 02139, USA. */
|
||
/****************************************************************/
|
||
|
||
/* one byte alignment */
|
||
#include <algnbyte.h>
|
||
|
||
/*
|
||
* Description of the organization of NLS information -- 2000/02/13 ska
|
||
*
|
||
* Glossar:
|
||
* NLS package -- NLS information incl. any code required to access or
|
||
* correctly interprete this particular information
|
||
*
|
||
* Abbreviation:
|
||
* (NLS) pkg -- NLS package
|
||
*
|
||
* The code included into the kernel does "only" support NLS packages
|
||
* structurally compatible with the one of the U.S.A. / CP437.
|
||
* I guess that most NLS packages has been tweaked to be compatible,
|
||
* so that this is not a real limitation, but for all other packages
|
||
* the external NLSFUNC can supply every piece of code necessary.
|
||
* To allow this the interface between the kernel and NLSFUNC has been
|
||
* extended; at the same time the interface has been reduced, because some
|
||
* of the API functions do not seem to offer any functionality required
|
||
* for now. This, however, may be a misinterpretation because of
|
||
* lack of understanding.
|
||
*
|
||
* The supported structure consists of the following assumptions:
|
||
* 1) The pkg must contain the tables 2 (Upcase character), 4
|
||
* (Upcase filename character) and 5 (filename termination
|
||
* characters); because they are used internally.
|
||
* 2) The tables 2 and 4 must contain exactly 128 (0x80) characters.
|
||
* The character at index 0 corresponses to character 128 (0x80).
|
||
* The characters in the range of 0..0x7f are constructed out of
|
||
* the 7-bit US-ASCII (+ control characters) character set and are
|
||
* upcased not through the table, but by the expression:
|
||
* (ch >= 'a' && ch <= 'z')? ch - 'a' + 'A': ch
|
||
* with: 'a' == 97; 'z' == 122; 'A' == 65
|
||
* 3) The data to be returned by DOS-65 is enlisted in the
|
||
* nlsPointer[] array of the nlsPackage structure, including
|
||
* the DOS-65-01 data, which always must be last entry of the
|
||
* array.
|
||
* 4) DOS-38 returns the 34 bytes beginning with the byte at offset
|
||
* 4 behind the size field of DOS-65-01.
|
||
*
|
||
* It seems that pure DOS can internally maintain two NLS pkgs:
|
||
* NLS#1: The hardcoded pkg of U.S.A. on CP437, and
|
||
* NLS#2: the pkg loaded via COUNTRY= from within CONFIG.SYS.
|
||
* I do interprete this behaviour as follows:
|
||
* CONFIG.SYS is read in more passes; before COUTRY= can be evaluated,
|
||
* many actions must be performed, e.g. to load kernel at all, open
|
||
* CONFIG.SYS and begin reading. The kernel requires at least two
|
||
* NLS information _before_ COUNTRY= has been evaluated - both upcase
|
||
* tables. To not implement the same function multiple times, e.g.
|
||
* to upcase with and without table, the kernel uses the default
|
||
* NLS pkg until a more appropriate one can be loaded and hopes that
|
||
* the BIOS (and the user) can live with its outcome.
|
||
* Though, theoretically, the hardcoded NLS pkg could be purged
|
||
* or overwritten once the COUNTRY= statement has been evaluated.
|
||
* It would be possible that this NLS pkg internally performs different
|
||
* purposes, for now this behaviour will be kept.
|
||
*
|
||
* The current implementation extends the above "two maintained
|
||
* NLS pkgs" into that the kernel chains all NLS pkgs loaded in
|
||
* memory into one single linked list. When the user does neither
|
||
* wants to load other NLS pkgs without executing NLSFUNC and the
|
||
* loaded NLS pkgs do not contain code themselves, no other code is
|
||
* required, but some memory to store the NLS pkgs into.
|
||
*
|
||
* Furthermore, because the kernel needs to include the code for the
|
||
* hardcoded NLS pkg anyway, every NLS pkg can use it; so only
|
||
* NLS pkgs that structurally differ from U.S.A./CP437 actually need
|
||
* to add any code and residently install the MUX handler for NLSFUNC.
|
||
* This technique reduces the overhead calling the MUX handler, when
|
||
* it is not needed.
|
||
* However, NLSFUNC is always required if the user wants to return
|
||
* information about NLS pkgs _not_ loaded into memory.
|
||
*
|
||
*=== Attention: Because the nlsInfoBlock structure differs from the
|
||
*=== the "traditional" (aka MS) implementation, the MUX-14 interface
|
||
*=== is _not_ MS-compatible, although all the registers etc.
|
||
*=== do conform. -- 2000/02/26 ska
|
||
*
|
||
* Previous failed attempts to implement NLS handling and a full-
|
||
* featured MUX-14 supporting any-structured NLS pkgs suggest
|
||
* to keep the implement as simple as possible and keep the
|
||
* optimization direction off balance and to tend toward either
|
||
* an optimization for speed or size.
|
||
*
|
||
* The most problem is that the MUX interrupt chain is considered
|
||
* highly overcrowded, so if the kernels invokes it itself, the
|
||
* performance might decrease dramatically; on the other side, the
|
||
* more complex the interface between kernel and a _probably_ installed
|
||
* external NLSFUNC becomes the more difficult all the stuff is becoming
|
||
* and, most importantly, the size grows unnecessarily, because many
|
||
* people don't use NLSFUNC at all.
|
||
*
|
||
* The kernel uses the NLS pkg itself for two operations:
|
||
* 1) DOS-65-2x and DOS-65-Ax: Upcase character, string, memory area, &
|
||
* 2) whenever a filename is passed into the kernel, its components
|
||
* must be identified, invalid characters must be detected
|
||
* and, finally, all letters must be uppercased.
|
||
* I do not consider operation 1) an action critical for performance,
|
||
* because traditional DOS programming praxis says: Do it Yourself; so
|
||
* one can consider oneself lucky that a program aquires the upcase
|
||
* table once in its life time (I mean: lucky the program calls NLS at all).
|
||
* Operation 2), in opposite, might dramatically reduce performance, if
|
||
* it lacks proper implementations.
|
||
*
|
||
* Straight forward implementation:
|
||
* The basic implementation of the NLS channels all requests of DOS-65,
|
||
* DOS-66, and DOS-38 through MUX-14. Hereby, any external program, such
|
||
* as NLSFUNC, may (or may not) install a piece of code to filter
|
||
* one, few, or all requests in order to perform them itself, by default
|
||
* all requests will end within the root of the MUX interrupt, which is
|
||
* located within the kernel itself. An access path could look like this:
|
||
* 1. Call to DOS-65-XX, DOS-66-XX, or DOS-38.
|
||
* 2. The kernel is enterred through the usual INT-21 API handler.
|
||
* 3. The request is decoded and one of the NLS.C function is called.
|
||
* 4. This function packs a new request and calls MUX-14.
|
||
* 5. Every TSR/driver hooking INT-2F will check, if the request is
|
||
* directed for itself;
|
||
* 5.1. If not, the request is passed on to the next item of the MUX
|
||
* interrupt chain;
|
||
* 5.2. If so, the TSR, e.g. NLSFUNC, tests if the request is to be
|
||
* performed internally;
|
||
* 5.2.1. If so, the request is performed and the MUX-14 call is
|
||
* terminated (goto step 8.)
|
||
* 5.2.2. If not, the request is passed on (see step 5.1.)
|
||
* 6. If all TSRs had their chance to filter requests, but none decided
|
||
* to perform the request itself, the kernel is (re-)enterred
|
||
* through its INT-2F (MUX) API handler.
|
||
* 7. Here the request is decoded again and performed with the kernel-
|
||
* internal code; then the MUX-14 call is terminated.
|
||
* 8. When the MUX-14 call returns, it has setup all return parameters
|
||
* already, so the INT-21 call is terminated as well.
|
||
*
|
||
* Note: The traditional MUX-14 is NOT supported to offer functionality
|
||
* to the kernel at the first place, but to let the kernel access and
|
||
* return any values they must be loaded into memory, but the user may
|
||
* request information through the DOS-65 interface of NLS pkgs _not_
|
||
* already loaded. Theoretically, NLSFUNC needs not allocate any internal
|
||
* buffer to load the data into, because the user already supplied one;
|
||
* also if the kernel would instruct NLSFUNC to load the requested
|
||
* NLS pkg, more memory than necessary would be allocated. However, all
|
||
* except subfunction 1 return a _pointer_ to the data rather than the
|
||
* data itself; that means that NLSFUNC must cache the requested data
|
||
* somewhere, but how long?
|
||
*
|
||
* Performance tweaks:
|
||
* When the system -- This word applies to the combination of kernel and
|
||
* any loaded MUX-14 extension <20> la NLSFUNC here. -- uppercases
|
||
* _filenames_, it must perform a DOS-65-A2 internally. In the basic
|
||
* implementation this request would be channeled through MUX-14, even
|
||
* if there is no external NLSFUNC at all. Also, when a NLS pkg had
|
||
* been loaded by the kernel itself, it complies to above mentioned
|
||
* rules and it is very unlikely that it is necessary to probe if
|
||
* a MUX-14 TSR might want to perform the request itself. Therefore
|
||
* each NLS pkg contains some flags that allow the kernel to bypass
|
||
* the MUX-14 request and invoke the proper function directly. Both
|
||
* default NLS pkgs will have those flags enabled, because they are
|
||
* already loaded into memory and must comply to the rules.
|
||
*
|
||
* Note: Those flags do not alter the way the request is actually
|
||
* performed, but the MUX-14 call is omitted only (steps 4. through 6.).
|
||
*
|
||
* ======= Description of the API
|
||
*
|
||
* There are three APIs to be supported by NLS:
|
||
* 1) DOS API: DOS-38, DOS-65, DOS-66;
|
||
* 2) MUX-14, and
|
||
* 3) internal: upcasing filenames.
|
||
*
|
||
* 1) and 2) address the used NLS pkg by the country code / codepage pair.
|
||
* 3) uses the currently active NLS pkg only; furthermore, these functions
|
||
* more or less match DOS-64-A*. Therefore, the NLS system merges the
|
||
* interfaces 1) and 3) and offers function suitable for both ones.
|
||
*
|
||
* Both 1) and 3) must channel the request through the MUX chain, if
|
||
* appropriate, whereas 2) is the back-end and does natively process the
|
||
* request totally on its own.
|
||
*
|
||
* The API of 1) and 3) consists of:
|
||
* + DosUpChar(), DosUpString(), and DosUpMem(): to upcase an object
|
||
* (DOS-65-2[0-2]);
|
||
* + DosYesNo(): to check a character, if it is the yes or no prompt
|
||
* (DOS-65-23);
|
||
* + DosUpFChar(), DosUpFString(), and DosUpFMem(): to upcase an object
|
||
* for filenames (DOS-65-A[0-2]);
|
||
* + DosGetData(): to retreive certain information (DOS-38, all the
|
||
* other DOS-65-** subfunctions);
|
||
* + DosSetCountry(): to change the currently active country code
|
||
* (DOS-38);
|
||
* + DosSetCodepage(): to change the currently active codepage (DOS-66).
|
||
*
|
||
* The API of 2) consists of:
|
||
* + syscall_MUX14().
|
||
* This function is invoked for all MUX-14 requests and recieves the
|
||
* registers of the particular INT-2F call, it will then decode the
|
||
* registers and pass the request forth to a NLS-internal interface
|
||
* consisting of the following "static" functions:
|
||
* + nlsUpMem(): called for DosUp*(),
|
||
* + nlsUpFMem(): called for DosUpF*(),
|
||
* + nlsYesNo(): called for DosYesNo(),
|
||
* + nlsGetData(): called for DosGetData(),&
|
||
* + nlsSetPackage(): called for DosSetCountry() and DosSetCodepage().
|
||
* In opposite of the APIs 1) through 3) the NLS-internal functions address
|
||
* the NLS pkg to operate upon by a (struct nlsInfoBlock *) pointer.
|
||
*
|
||
* This designs supports to easily implement to bypass the MUX chain to
|
||
* speed up especially the internal API to upcase filenames, because
|
||
* the Dos*() functions can decide do not pass the request through MUX,
|
||
* but directly call the nls*() function instead. This way it is ensured
|
||
* that the performed actions are the same in both cases and, with repect
|
||
* to the functions that operate with the currently active NLS pkg, the
|
||
* performance is rather high, because one can use the globally available
|
||
* pointer to the current NLS pkg and need not search for a country code/
|
||
* codepage pair.
|
||
*
|
||
* ======== Compile-time options
|
||
*
|
||
* Win9x supports to change the individual portions of a NLS pkg
|
||
* through DOS-65-00; also there are no references what happens when
|
||
* a program changes the areas addressed by returned pointers. The
|
||
* current implementation does _not_ support changes of the NLS pkg
|
||
* except by invoking DOS-38 (Set Country Code) or DOS-66 (Set Codepage).
|
||
* Future implementations might offer this ability; to reduce the
|
||
* overhead introduced by this feature, the macro NLS_MODIFYABLE_DATA
|
||
* enables the appropriate code.
|
||
* NLS_MODIFYABLE_DATA is *disabled* by default.
|
||
*
|
||
* The tables 2 and 4 (upcase tables) are accessed relatively often,
|
||
* but theoretically these tables could be located at any position
|
||
* of the pointer array. If the macro NLS_REORDER_POINTERS is enabled,
|
||
* both NLSFUNC and the internal loader will reorder the pointers
|
||
* array so that mandatory tables are located at predictable indexes.
|
||
* This removes that the kernel must search for the table when
|
||
* one of the DOS-65-[2A]x functions is called or a filename has been
|
||
* passed in (which must be uppercased to be suitable for internal
|
||
* purpose). However, when some program try to tweak the internal
|
||
* tables this assumption could be wrong.
|
||
* This setting has any effect only, if the kernel tries to access
|
||
* information itself; it is ignored when the user calls DOS-65-0x
|
||
* to return such pointer.
|
||
* NLS_REORDER_POINTERS is *enabled* by default.
|
||
* UPDATE: With NLS_REORDER_POINTERS, now table 7 (DBCS) is also
|
||
* expected to be located at a predictable index. -- eca
|
||
*/
|
||
|
||
/* Define if some user program possibly modifies the value of the internal
|
||
tables or the DOS-65-00 (Set Country Information) API function
|
||
is to be supported. */
|
||
/* Currently unimplemented! -- 2000/02/13 ska*/
|
||
/* #define NLS_MODIFYABLE_DATA */
|
||
|
||
/* Define if the pointer array shall be reordered to allow a quick
|
||
access to often used and mandatoryly present tables. */
|
||
#define NLS_REORDER_POINTERS
|
||
|
||
/*
|
||
* How the kernel and NLSFUNC communicate with each other
|
||
*/
|
||
/* Must be pased to and returned by NLSFUNC upon MUX-14-00 */
|
||
#define NLS_FREEDOS_NLSFUNC_ID 0x534b
|
||
/* What version of nlsInfo and accompanying associations
|
||
Must be passed to NLSFUNC upon MUX-14-00 to identify the
|
||
correct kernel to the tools. */
|
||
#define NLS_FREEDOS_NLSFUNC_VERSION 0xFD02
|
||
/* Represents a call to DOS-38 within DOS-65 handlers.
|
||
Current implementation relys on 0x101! */
|
||
#define NLS_DOS_38 0x101
|
||
/* NLSFUNC may return NLS_REDO to instruct the kernel to
|
||
try to perform the same action another time. This is most
|
||
useful if the kernel only loads the NLS pkg into memory so
|
||
the kernel will find it and will process the request internally
|
||
now. */
|
||
#define NLS_REDO 353
|
||
|
||
/* Codes of the subfunctions of external NLSFUNC */
|
||
#define NLSFUNC_INSTALL_CHECK 0
|
||
#define NLSFUNC_DOS38 4
|
||
#define NLSFUNC_GETDATA 2
|
||
#define NLSFUNC_DRDOS_GETDATA 0xfe
|
||
#define NLSFUNC_LOAD_PKG 3
|
||
#define NLSFUNC_LOAD_PKG2 1
|
||
#define NLSFUNC_UPMEM 0x22
|
||
#define NLSFUNC_YESNO 0x23
|
||
#define NLSFUNC_FILE_UPMEM 0xa2
|
||
|
||
/* The NLS implementation flags encode what feature is in effect;
|
||
a "1" in the bitfield means that the feature is active.
|
||
All currently non-defined bits are to be zero to allow future
|
||
useage. */
|
||
#define NLS_CODE_MODIFYABLE_DATA 0x0001
|
||
#define NLS_CODE_REORDER_POINTERS 0x0002
|
||
|
||
/* NLS package useage flags encode what feature is in effect for this
|
||
particular package:
|
||
a "1" in the bitfield means that the feature is active/enabled.
|
||
All currently non-defined bits are to be zero to allow future
|
||
useage. */
|
||
#define NLS_FLAG_DIRECT_UPCASE 0x0001 /* DOS-65-2[012], */
|
||
#define NLS_FLAG_DIRECT_FUPCASE 0x0002 /* DOS-65-A[012], internal */
|
||
#define NLS_FLAG_DIRECT_YESNO 0x0004 /* DOS-65-23 */
|
||
#define NLS_FLAG_DIRECT_GETDATA 0x0008 /* DOS-65-XX, DOS-38 */
|
||
|
||
#define NLS_FLAG_HARDCODED (NLS_FLAG_DIRECT_UPCASE \
|
||
| NLS_FLAG_DIRECT_FUPCASE \
|
||
| NLS_FLAG_DIRECT_YESNO \
|
||
| NLS_FLAG_DIRECT_GETDATA)
|
||
|
||
/* No codepage / country code given */
|
||
#define NLS_DEFAULT ((UWORD)-1)
|
||
|
||
struct CountrySpecificInfo {
|
||
short CountryID; /* = W1 W437 # Country ID & Codepage */
|
||
short CodePage;
|
||
short DateFormat; /* Date format: 0/1/2: U.S.A./Europe/Japan */
|
||
char CurrencyString[5]; /* '$' ,'EUR' */
|
||
char ThousandSeparator[2]; /* ',' # Thousand's separator */
|
||
char DecimalPoint[2]; /* '.' # Decimal point */
|
||
char DateSeparator[2]; /* '-' */
|
||
char TimeSeparator[2]; /* ':' */
|
||
char CurrencyFormat; /* = 0 # Currency format (bit array)
|
||
0Fh BYTE currency format
|
||
bit 2 = set if currency symbol replaces decimal point
|
||
bit 1 = number of spaces between value and currency symbol
|
||
bit 0 = 0 if currency symbol precedes value
|
||
1 if currency symbol follows value
|
||
*/
|
||
char CurrencyPrecision; /* = 2 # Currency precision */
|
||
char TimeFormat; /* = 0 # time format: 0/1: 12/24 houres */
|
||
};
|
||
|
||
/*
|
||
* This is the data in the exact order returned by DOS-65-01
|
||
*/
|
||
struct nlsExtCntryInfo {
|
||
UBYTE subfct; /* always 1 */
|
||
WORD size; /* size of this structure
|
||
without this WORD itself */
|
||
WORD countryCode; /* current country code */
|
||
WORD codePage; /* current code page (CP) */
|
||
|
||
/*
|
||
* This is the data in the exact order as to return on
|
||
* DOS-38; it is also the most (important) part of DOS-65-01
|
||
*/
|
||
/* Note: The ASCIZ strings might become
|
||
a totally different understanding with
|
||
DBCS (Double Byte Character Support) */
|
||
WORD dateFmt; /* order of portions of date
|
||
0: mm/dd/yyyy (USA)
|
||
1: dd/mm/yyyy (Europe)
|
||
2: yyyy/mm/dd (Japan)
|
||
*/
|
||
char curr[5]; /* ASCIZ of currency string */
|
||
char thSep[2]; /* ASCIZ of thousand's separator */
|
||
char point[2]; /* ASCIZ of decimal point */
|
||
char dateSep[2]; /* ASCIZ of date separator */
|
||
char timeSep[2]; /* ASCIZ of time separator */
|
||
BYTE currFmt; /* format of currency:
|
||
bit 0: currency string is placed
|
||
0: before number
|
||
1: behind number
|
||
bit 1: currency string and number are
|
||
separated by a space
|
||
0: No
|
||
1: Yes
|
||
bit 2: currency string replaces decimal
|
||
sign
|
||
0: No
|
||
1: Yes
|
||
*/
|
||
BYTE prescision; /* of monetary numbers */
|
||
BYTE timeFmt; /* time format:
|
||
0: 12 hours (append AM/PM)
|
||
1: 24 houres
|
||
*/
|
||
intvec upCaseFct; /* far call to a function upcasing the
|
||
character in register AL */
|
||
char dataSep[2]; /* ASCIZ of separator in data records */
|
||
};
|
||
|
||
struct nlsPointer { /* Information of DOS-65-0X is addressed
|
||
by a pointer */
|
||
UBYTE subfct; /* number of the subfunction */
|
||
VOID FAR *pointer; /* the pointer to be returned when the subfunction
|
||
of DOS-65 is called (Note: won't work for
|
||
subfunctions 0, 1, 0x20, 0x21, 0x22, 0x23,
|
||
0xA0, 0xA1,& 0xA2 */
|
||
};
|
||
|
||
struct nlsPackage { /* the contents of one chain item of the
|
||
list of NLS packages */
|
||
struct nlsPackage FAR *nxt; /* next item in chain */
|
||
UWORD cntry, cp; /* country ID / codepage of this NLS pkg */
|
||
int flags; /* direct access and other flags */
|
||
/* Note: Depending on the flags above all remaining
|
||
portions may be omitted, if the external NLSFUNC-like
|
||
MUX-14 processor does not require them and performs
|
||
all actions itself, so that the kernel never tries to
|
||
fetch this information itself. */
|
||
UWORD yeschar; /* yes / no character DOS-65-23 */
|
||
UWORD nochar;
|
||
unsigned numSubfct; /* number of supported sub-functions */
|
||
struct nlsPointer nlsPointers[5]; /* may grow dynamically */
|
||
struct nlsExtCntryInfo nlsExt;
|
||
};
|
||
|
||
struct nlsDBCS { /* The internal structure is unknown to me */
|
||
UWORD numEntries;
|
||
UWORD dbcsTbl[4]; /* I don't know max size but it should need
|
||
at least 3 words (6 bytes)
|
||
({0x81,0x9f,0xe0,0xfc,0,0} for CP932-Japan)
|
||
-- lpproj 2014/10/27 */
|
||
};
|
||
|
||
struct nlsCharTbl {
|
||
/* table containing a list of characters */
|
||
UWORD numEntries; /* number of entries of this table.
|
||
If <= 0x80, the first element of
|
||
the table corresponse to character 0x80 */
|
||
unsigned char tbl[1]; /* grows dynamically */
|
||
};
|
||
#define nlsChBuf(len) struct nlsCharTbl##len { \
|
||
UWORD numEntries; \
|
||
unsigned char tbl[len]; \
|
||
}
|
||
nlsChBuf(128);
|
||
nlsChBuf(256);
|
||
|
||
/* in file names permittable characters for DOS-65-05 */
|
||
struct nlsFnamTerm {
|
||
WORD size; /* size of this structure */
|
||
BYTE dummy1;
|
||
char firstCh, lastCh; /* first, last permittable character */
|
||
BYTE dummy2;
|
||
char firstExcl, lastExcl; /* first, last excluded character */
|
||
BYTE dummy3;
|
||
BYTE numSep; /* number of file name separators */
|
||
char separators[1]; /* grows dynamically */
|
||
};
|
||
|
||
struct nlsInfoBlock { /* This block contains all information
|
||
shared by the kernel and the external NLSFUNC program */
|
||
char FAR *fname; /* filename from COUNTRY=;
|
||
maybe tweaked by NLSFUNC */
|
||
UWORD sysCodePage; /* system code page */
|
||
unsigned flags; /* implementation flags */
|
||
#ifdef __GNUC__
|
||
/* need to initialize using explicit segment/offset */
|
||
union {
|
||
struct { struct nlsPackage *off; char *seg; };
|
||
struct nlsPackage FAR *p;
|
||
} actPkg, chain;
|
||
#define actPkg actPkg.p
|
||
#define chain chain.p
|
||
#else
|
||
struct nlsPackage FAR *actPkg; /* current NLS package */
|
||
struct nlsPackage FAR *chain; /* first item of info chain --
|
||
hardcoded U.S.A./CP437 */
|
||
#endif
|
||
};
|
||
|
||
extern struct nlsInfoBlock ASM nlsInfo;
|
||
extern struct nlsPackage DOSFAR ASM nlsPackageHardcoded;
|
||
extern BYTE FAR hcTablesStart[], hcTablesEnd[];
|
||
|
||
/***********************************************************************
|
||
***** Definitions & Declarations for COUNTRY.SYS **********************
|
||
***********************************************************************/
|
||
|
||
/* Note: These definitions are shared among all tools accessing the
|
||
COUNTRY.SYS file as well -- 2000/06/11 ska*/
|
||
|
||
/* File structure:
|
||
S0: Base (Primary) structure -- file header
|
||
Offset Size Meaning
|
||
0 array ID string "FreeDOS COUNTRY.SYS v1.0\r\n"
|
||
26 array Copyright etc. (plain 7bit ASCII text)
|
||
26+N 2byte \x1a\0
|
||
26+N+2 array padded with \0 upto next offset
|
||
128 word number of country/codepage pairs (N1)
|
||
130 8byte country code / codepage entries (S1)
|
||
130+8*N1 end of array
|
||
===
|
||
S1: structure of country/codepage pair
|
||
Offset Size Meaning
|
||
0 dword relative position of table definition (S2)
|
||
4 word codepage ID
|
||
6 word country code
|
||
8 end of structure
|
||
===
|
||
S2: table definition of one country/codepage pair
|
||
Offset Size Meaning
|
||
0 word number of function entries (N2)
|
||
2 8byte function definition (S3)
|
||
2+8*N2 end of array
|
||
===
|
||
S3: function definition
|
||
Offset Size Meaning
|
||
0 dword relative position of function data (see S4)
|
||
4 word number of bytes of data
|
||
6 byte function ID (same as passed to DOS-65-XX)
|
||
7 byte reserved for future use (currently 0 (zero))
|
||
8 end of structure
|
||
===
|
||
S4: function data
|
||
In opposite of the structures and arrays, the function data
|
||
is just a structure-less stream of bytes, which is used as it is.
|
||
Currently no validation check is performed over this data.
|
||
That means, for instance, that a definition of function 2 (upcase
|
||
table) has length 130 and the data consists of a word value with
|
||
the length (128) and 128 bytes individual information.
|
||
That way the DBCS is implemented exactly the same way as all the
|
||
other tables; the only exception is pseudo-table 0x23.
|
||
===
|
||
"relative position" means this DWord specifies the amount of bytes
|
||
between end of the current structure and the data the pointer is
|
||
referring to. This shall enable future implementations to embed
|
||
COUNTRY.SYS into other files.
|
||
*/
|
||
|
||
#define CSYS_FD_IDSTRING "FreeDOS COUNTRY.SYS v1.0\r\n\x1a"
|
||
|
||
#if 0
|
||
struct csys_function { /* S3: function definition */
|
||
UDWORD csys_rpos; /* relative position to actual data */
|
||
UWORD csys_length;
|
||
UBYTE csys_fctID; /* As passed to DOS-65-XX */
|
||
UBYTE csys_reserved1; /* always 0, reserved for future use */
|
||
};
|
||
|
||
struct csys_ccDefinition { /* S1: country/codepage reference */
|
||
UDWORD csys_rpos; /* moving the 4byte value to the front
|
||
can increase performance */
|
||
UWORD csys_cp;
|
||
UWORD csys_cntry;
|
||
};
|
||
#endif
|
||
|
||
struct csys_ccDefinition { /* country/codepage reference */
|
||
UDWORD csys_pos; /* moving the 4byte value to the front
|
||
can increase performance */
|
||
UWORD csys_cntry;
|
||
UWORD csys_cp;
|
||
UWORD csys_size1; /* size of nlsPackage struct rpos is pointing to */
|
||
|
||
/* initially the object rpos is pointing to conforms to a
|
||
struct nlsPackage, where:
|
||
struct nlsPackage FAR *nxt; is missing
|
||
UWORD cntry, cp; is missing
|
||
int flags; is NLS_FLAG_HARDCODED, if the
|
||
kernel is to handle the data of its own
|
||
UWORD yeschar; is filled
|
||
UWORD nochar; is filled
|
||
unsigned numSubfct; is filled
|
||
struct nlsPointer nlsPointers[1]; is filled
|
||
the pointer member is the absolute
|
||
position of the data within the file
|
||
of this structure:
|
||
UWORD count
|
||
count bytes
|
||
The "count" value is not a part
|
||
of the data itself.
|
||
Also: The data must be ordered corresponding to
|
||
NLS_CODE_REORDER_POINTERS.
|
||
Also: The last nlsPointer is subfct #1 _incl_ all its
|
||
data [is the extended country information: struct nlsExtCntryInfo]
|
||
*/
|
||
};
|
||
|
||
struct csys_numEntries { /* helper structure for "number of entries" */
|
||
UWORD csys_entries;
|
||
};
|
||
|
||
/* Header of the COUNTRY.SYS file */
|
||
struct nlsCSys_fileHeader { /* COUNTRY.SYS header */
|
||
unsigned char csys_idstring[sizeof(CSYS_FD_IDSTRING)];
|
||
UWORD csys_maxTotalSize; /* maximal size of the total amount of
|
||
any individual definition, that includes
|
||
the nlsPackage skeleton and the sum of
|
||
all bytes required to load all the
|
||
subfunctions individually.
|
||
--> The code is to allocate maxTotalSize
|
||
and load any country definition of this
|
||
file into this buffer without any
|
||
overflow. */
|
||
DWORD csys_posIndex; /* absolute position of index table */
|
||
};
|
||
|
||
/* Structure created by CountryInfoLoad() */
|
||
struct nlsCSys_loadPackage {
|
||
UWORD csys_size;
|
||
struct nlsPackage csys_pkg;
|
||
};
|
||
|
||
/* standard alignment */
|
||
#include <algndflt.h>
|
||
|
||
#ifdef DEBUG
|
||
/* Enable debugging of NLS part */
|
||
|
||
/* Caution: Enabling NLS debugging usually generates
|
||
_a_lot_ of noise. */
|
||
/*& #define NLS_DEBUG */
|
||
|
||
#endif
|