📄 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 DosUpMemVOID 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 DosGetCountryInformationCOUNT 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 DosSetCountryCOUNT 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 + -