⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nls.c

📁 开源DOS的C代码源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -