📄 nls.c
字号:
VOID nlsCPchange(UWORD cp)
{
UNREFERENCED_PARAMETER(cp);
put_string("\7\nchange codepage not yet done ska\n");
}
/*
* Changes the current active codepage or cntry
*
* Note: Usually any call sees a value of -1 (0xFFFF) as "the current
* country/CP". When a new NLS pkg is loaded, there is however a little
* difference, because one could mean that when switching to country XY
* the system may change to any codepage required.
* Example:
* MODE has prepared codepages 437 and 850.
* The user loaded a 2nd NLS pkg via CONFIG.SYS with:
* COUNTRY=49,850,C:\COUNTRY.SYS
* By default, the kernel maintains the hardcoded 001,437 (U.S.A./CP437)
* After the Country statement the system switches to codepage 850.
* But when the user invokes DOS-38-01/DX=FFFF (Set Country ID to 1)
* the system _must_ switch to codepage 437, because this is the only
* NLS pkg loaded.
* Therefore, setPackage() will substitute the current country ID, if
* cntry==-1, but leaves cp==-1 in order to let NLSFUNC choose the most
* appropriate codepage on its own.
*/
STATIC COUNT nlsSetPackage(struct nlsPackage FAR * nls)
{
if (nls->cp != nlsInfo.actPkg->cp) /* Codepage gets changed -->
inform all character drivers thereabout.
If this fails, it would be possible that the old
NLS pkg had been removed from memory by NLSFUNC. */
nlsCPchange(nls->cp);
nlsInfo.actPkg = nls;
return SUCCESS;
}
STATIC COUNT DosSetPackage(UWORD cp, UWORD cntry)
{
struct nlsPackage FAR *nls; /* NLS package to use to return the info from */
/* nls := NLS package of cntry/codepage */
if ((nls = searchPackage(cp, cntry)) != NULL)
/* OK the NLS pkg is loaded --> activate it */
return nlsSetPackage(nls);
/* not loaded --> invoke NLSFUNC to load it */
return muxLoadPkg(cp, cntry);
}
STATIC void nlsUpMem(struct nlsPackage FAR * nls, VOID FAR * str, int len)
{
log(("NLS: nlsUpMem()\n"));
upMMem(getCharTbl2(nls), (UBYTE FAR *) str, len);
}
STATIC void nlsFUpMem(struct nlsPackage FAR * nls, VOID FAR * str, int len)
{
log(("NLS: nlsFUpMem()\n"));
upMMem(getCharTbl4(nls), (UBYTE FAR *) str, len);
}
STATIC VOID xUpMem(struct nlsPackage FAR * nls, VOID FAR * str,
unsigned len)
/* upcase a memory area */
{
log(("NLS: xUpMem(): cp=%u, cntry=%u\n", nls->cp, nls->cntry));
if (nls->flags & NLS_FLAG_DIRECT_UPCASE)
nlsUpMem(nls, str, len);
else
muxBufGo(NLSFUNC_UPMEM, 0, nls->cp, nls->cntry, len, str);
}
STATIC int nlsYesNo(struct nlsPackage FAR * nls, unsigned char ch)
{
log(("NLS: nlsYesNo(): in ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
xUpMem(nls, MK_FP(_SS, &ch), 1); /* Upcase character */
/* Cannot use DosUpChar(), because
maybe: nls != current NLS pkg
However: Upcase character within lowlevel
function to allow a yesNo() function
catched by external MUX-14 handler, which
does NOT upcase character. */
log(("NLS: nlsYesNo(): upcased ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
if (ch == nls->yeschar)
return 1;
if (ch == nls->nochar)
return 0;
return 2;
}
/********************************************************************
***** DOS API ******************************************************
********************************************************************/
BYTE DosYesNo(unsigned char ch)
/* returns: 0: ch == "No", 1: ch == "Yes", 2: ch crap */
{
if (nlsInfo.actPkg->flags & NLS_FLAG_DIRECT_YESNO)
return nlsYesNo(nlsInfo.actPkg, ch);
else
return muxYesNo(ch);
}
#ifndef DosUpMem
VOID DosUpMem(VOID FAR * str, unsigned len)
{
xUpMem(nlsInfo.actPkg, str, len);
}
#endif
/*
* This function is also called by the backdoor entry specified by
* the "upCaseFct" member of the Country Information structure. Therefore
* the HiByte of the first argument must remain unchanged.
* See NLSSUPT.ASM -- 2000/03/30 ska
*/
unsigned char ASMCFUNC DosUpChar(unsigned char ch)
/* upcase a single character */
{
log(("NLS: DosUpChar(): in ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
DosUpMem(MK_FP(_SS, &ch), 1);
log(("NLS: DosUpChar(): upcased ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
return ch;
}
VOID DosUpString(char FAR * str)
/* upcase a string */
{
DosUpMem(str, fstrlen(str));
}
VOID DosUpFMem(VOID FAR * str, unsigned len)
/* upcase a memory area for file names */
{
#ifdef NLS_DEBUG
unsigned c;
log(("NLS: DosUpFMem(): len=%u, %04x:%04x=\"", len, FP_SEG(str),
FP_OFF(str)));
for (c = 0; c < len; ++c)
printf("%c", str[c] > 32 ? str[c] : '.');
printf("\"\n");
#endif
if (nlsInfo.actPkg->flags & NLS_FLAG_DIRECT_FUPCASE)
nlsFUpMem(nlsInfo.actPkg, str, len);
else
muxUpMem(NLSFUNC_FILE_UPMEM, str, len);
}
unsigned char DosUpFChar(unsigned char ch)
/* upcase a single character for file names */
{
DosUpFMem(MK_FP(_SS, & ch), 1);
return ch;
}
VOID DosUpFString(char FAR * str)
/* upcase a string for file names */
{
DosUpFMem(str, fstrlen(str));
}
/*
* Called for all subfunctions other than 0x20-0x23,& 0xA0-0xA2
* of DOS-65
*
* If the requested NLS pkg specified via cntry and cp is _not_
* loaded, MUX-14 is invoked; otherwise the pkg's NLS_Fct_buf
* function is invoked.
*/
COUNT DosGetData(int subfct, UWORD cp, UWORD cntry, UWORD bufsize,
VOID FAR * buf)
{
struct nlsPackage FAR *nls; /* NLS package to use to return the info from */
log(("NLS: GetData(): subfct=%x, cp=%u, cntry=%u, bufsize=%u\n",
subfct, cp, cntry, bufsize));
if (!buf || !bufsize)
return DE_INVLDDATA;
if (subfct == 0) /* Currently not supported */
return DE_INVLDFUNC;
/* nls := NLS package of cntry/codepage */
if ((nls = searchPackage(cp, cntry)) == NULL
|| (nls->flags & NLS_FLAG_DIRECT_GETDATA) == 0)
{
/* If the NLS pkg is not loaded into memory or the
direct-access flag is disabled, the request must
be passed through MUX */
return (subfct == NLS_DOS_38)
? mux38(nls->cp, nls->cntry, bufsize, buf)
: mux65(subfct, nls->cp, nls->cntry, bufsize, buf);
}
/* Direct access to the data */
return nlsGetData(nls, subfct, buf, bufsize);
}
/*
* Called for DOS-38 get info
*
* Note: DOS-38 does not receive the size of the buffer; therefore
* it is assumed the buffer is large enough as described in RBIL,
* which is 34 bytes _hardcoded_.
*/
/* TE 05/04/01
* NETX calls Int 21 AX=3800
* and gives a buffer of (at most) 0x20 bytes
* MSDOS 6.2 copies only 0x18 bytes
* RBIL documents 0x18 bytes and calls 10 bytes 'reserved'
* so we change the amount of copied bytes to 0x18
*/
#ifndef DosGetCountryInformation
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf)
{
return DosGetData(NLS_DOS_38, NLS_DEFAULT, cntry, 0x18, buf);
}
#endif
/*
* Called for DOS-38 set country code
*/
#ifndef DosSetCountry
COUNT DosSetCountry(UWORD cntry)
{
return DosSetPackage(NLS_DEFAULT, cntry);
}
#endif
/*
* Called for DOS-66-01 get CP
*/
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP)
{
*sysCP = nlsInfo.sysCodePage;
*actCP = nlsInfo.actPkg->cp;
return SUCCESS;
}
/*
* Called for DOS-66-02 set CP
* Note: One cannot change the system CP. Why it is necessary
* to specify it, is lost to me. (2000/02/13 ska)
*/
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP)
{
if (sysCP == NLS_DEFAULT || sysCP == nlsInfo.sysCodePage)
return DosSetPackage(actCP, NLS_DEFAULT);
return DE_INVLDDATA;
}
/********************************************************************
***** MUX-14 API ***************************************************
********************************************************************/
/* Registers:
AH == 14
AL == subfunction
BX == codepage
DX == country code
DS:SI == internal global nlsInfo
ES:DI == user block
Return value: AL register to be returned
if AL == 0, Carry must be cleared, otherwise set
*/
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS)
{
struct nlsPackage FAR *nls; /* addressed NLS package */
UNREFERENCED_PARAMETER(flags);
UNREFERENCED_PARAMETER(cs);
UNREFERENCED_PARAMETER(ip);
UNREFERENCED_PARAMETER(ds);
UNREFERENCED_PARAMETER(es);
UNREFERENCED_PARAMETER(si);
log(("NLS: MUX14(): subfct=%x, cp=%u, cntry=%u\n", AL, BX, DX));
if ((nls = searchPackage(BX, DX)) == NULL)
return DE_INVLDFUNC; /* no such package */
log(("NLS: MUX14(): NLS pkg found\n"));
switch (AL)
{
case NLSFUNC_INSTALL_CHECK:
BX = NLS_FREEDOS_NLSFUNC_ID;
return SUCCESS; /* kernel just simulates default functions */
case NLSFUNC_DOS38:
return nlsGetData(nls, NLS_DOS_38, MK_FP(ES, DI), 34);
case NLSFUNC_GETDATA:
return nlsGetData(nls, BP, MK_FP(ES, DI), CX);
case NLSFUNC_DRDOS_GETDATA:
/* Does not pass buffer length */
return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
case NLSFUNC_LOAD_PKG:
case NLSFUNC_LOAD_PKG2:
return nlsSetPackage(nls);
case NLSFUNC_YESNO:
return nlsYesNo(nls, CL);
case NLSFUNC_UPMEM:
nlsUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS;
case NLSFUNC_FILE_UPMEM:
#ifdef NLS_DEBUG
{
unsigned j;
BYTE FAR *p;
log(("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", CX, ES, DI));
for (j = 0, p = MK_FP(ES, DI); j < CX; ++j)
printf("%c", p[j] > 32 ? p[j] : '.');
printf("\"\n");
}
#endif
nlsFUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS;
}
log(("NLS: MUX14(): Invalid function %x\n", AL));
return DE_INVLDFUNC; /* no such function */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -