Add new files and update cvs with patches and changes

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@61 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Jim Tabor 2000-08-06 05:50:17 +00:00
parent 52ba720063
commit 0fddf1f848
24 changed files with 1795 additions and 841 deletions

View File

@ -1,240 +0,0 @@
/****************************************************************/
/* */
/* 001-437.nls */
/* DOS-C */
/* */
/* National Languge Support USA Code Page */
/* */
/* Copyright (c) 1996 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* Copyright (c) 1996 */
/* Steffen Kaiser */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* 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. */
/****************************************************************/
/* $Logfile: D:/dos-c/src/kernel/001-437.nlv $ */
#ifdef VERSION_STRINGS
static BYTE *RcsId = "$Header$";
#endif
/*
* $Log$
* Revision 1.3 2000/05/25 20:56:20 jimtabor
* Fixed project history
*
* Revision 1.2 2000/05/08 04:29:59 jimtabor
* Update CVS to 2020
*
* Revision 1.1.1.1 2000/05/06 19:34:53 jhall1
* The FreeDOS Kernel. A DOS kernel that aims to be 100% compatible with
* MS-DOS. Distributed under the GNU GPL.
*
* Revision 1.2 2000/03/09 06:07:10 kernel
* 2017f updates by James Tabor
*
* Revision 1.1.1.1 1999/03/29 15:40:36 jprice
* New version without IPL.SYS
*
* Revision 1.2 1999/01/22 04:13:25 jprice
* Formating
*
* Revision 1.1.1.1 1999/01/20 05:51:01 jprice
* Imported sources
*
*
* Rev 1.2 29 May 1996 21:03:46 patv
* bug fixes for v0.91a
*
* Rev 1.1 19 Feb 1996 4:34:48 patv
* Corrected typo
*
* Rev 1.0 19 Feb 1996 3:37:48 patv
* Initial revision.
*/
/* This initialization segment is included into the file where needed. */
/* It's cuurently included in the following file: nls.c. */
{
{
{
0, 0, 0, 0, 0, 0, 0, 0
}
,
"\\COUNTRY.SYS",
437,
6,
{
{
(VOID FAR *) & nlsInfo.upNCsize, 2
}
,
{
(VOID FAR *) & nlsInfo.upFCsize, 4
}
,
{
(VOID FAR *) & nlsInfo.nlsFn, 5
}
,
{
(VOID FAR *) & nlsInfo.collSize, 6
}
,
{
(VOID FAR *) & nlsInfo.nlsExtCtryInfo.countryCode, 1
}
,
{
(VOID FAR *) & nlsInfo.dbcSize, 7
}
}
,
1, /* country code */
437, /* code page */
{
0, /* date format */
{
/* currency string */
'$', '\x00', '\x00', '\x00', '\x00', /* 0 - 4 */
}
,
{ /* thousand separator */
',', '\x00' /* 0 - 1 */
}
,
{ /* decimal point */
'.', '\x00' /* 0 - 1 */
}
,
{ /* date separator */
'-', '\x00' /* 0 - 1 */
}
,
{ /* time separator */
':', '\x00' /* 0 - 1 */
}
,
0, /* currency format */
2, /* currency prescision */
0, /* time format */
CharMapSrvc, /* upcase function */
{ /* data separator */
',', '\x00' /* 0 - 1 */
}
}
}
,
'Y', 'N', /* Yes/No prompt characters */
128, /* upcase table */
{
'\x80', '\x9a', 'E', 'A', '\x8e', 'A', '\x8f', '\x80' /* 0 - 7 */
,'E', 'E', 'E', 'I', 'I', 'I', '\x8e', '\x8f' /* 8 - 15 */
,'\x90', '\x92', '\x92', 'O', '\x99', 'O', 'U', 'U' /* 16 - 23 */
,'Y', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f' /* 24 - 31 */
,'A', 'I', 'O', 'U', '\xa5', '\xa5', '\xa6', '\xa7' /* 32 - 39 */
,'\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf' /* 40 - 47 */
,'\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7' /* 48 - 55 */
,'\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf' /* 56 - 63 */
,'\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7' /* 64 - 71 */
,'\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf' /* 72 - 79 */
,'\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7' /* 80 - 87 */
,'\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf' /* 88 - 95 */
,'\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7' /* 96 - 103 */
,'\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef' /* 104 - 111 */
,'\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7' /* 112 - 119 */
,'\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' /* 120 - 127 */
}
,
128, /* file name upcase table */
{
'\x80', '\x9a', 'E', 'A', '\x8e', 'A', '\x8f', '\x80' /* 0 - 7 */
,'E', 'E', 'E', 'I', 'I', 'I', '\x8e', '\x8f' /* 8 - 15 */
,'\x90', '\x92', '\x92', 'O', '\x99', 'O', 'U', 'U' /* 16 - 23 */
,'Y', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f' /* 24 - 31 */
,'A', 'I', 'O', 'U', '\xa5', '\xa5', '\xa6', '\xa7' /* 32 - 39 */
,'\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf' /* 40 - 47 */
,'\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7' /* 48 - 55 */
,'\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf' /* 56 - 63 */
,'\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7' /* 64 - 71 */
,'\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf' /* 72 - 79 */
,'\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7' /* 80 - 87 */
,'\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf' /* 88 - 95 */
,'\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7' /* 96 - 103 */
,'\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef' /* 104 - 111 */
,'\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7' /* 112 - 119 */
,'\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' /* 120 - 127 */
}
,
256, /* collating sequence table */
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07' /* 0 - 7 */
,'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f' /* 8 - 15 */
,'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17' /* 16 - 23 */
,'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f' /* 24 - 31 */
,' ', '!', '"', '#', '$', '%', '&', '\'' /* 32 - 39 */
,'(', ')', '*', '+', ',', '-', '.', '/' /* 40 - 47 */
,'0', '1', '2', '3', '4', '5', '6', '7' /* 48 - 55 */
,'8', '9', ':', ';', '<', '=', '>', '?' /* 56 - 63 */
,'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G' /* 64 - 71 */
,'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' /* 72 - 79 */
,'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' /* 80 - 87 */
,'X', 'Y', 'Z', '[', '\\', ']', '^', '_' /* 88 - 95 */
,'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G' /* 96 - 103 */
,'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' /* 104 - 111 */
,'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' /* 112 - 119 */
,'X', 'Y', 'Z', '{', '|', '}', '~', '\x7f' /* 120 - 127 */
,'C', 'U', 'E', 'A', 'A', 'A', 'A', 'C' /* 128 - 135 */
,'E', 'E', 'E', 'I', 'I', 'I', 'A', 'A' /* 136 - 143 */
,'E', 'A', 'A', 'O', 'O', 'O', 'U', 'U' /* 144 - 151 */
,'Y', 'O', 'U', '$', '$', '$', '$', '$' /* 152 - 159 */
,'A', 'I', 'O', 'U', 'N', 'N', '\xa6', '\xa7' /* 160 - 167 */
,'?', '\xa9', '\xaa', '\xab', '\xac', '!', '"', '"' /* 168 - 175 */
,'\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7' /* 176 - 183 */
,'\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf' /* 184 - 191 */
,'\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7' /* 192 - 199 */
,'\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf' /* 200 - 207 */
,'\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7' /* 208 - 215 */
,'\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf' /* 216 - 223 */
,'\xe0', 'S', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7' /* 224 - 231 */
,'\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef' /* 232 - 239 */
,'\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7' /* 240 - 247 */
,'\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' /* 248 - 255 */
}
,
0, /* no DBC support */
0, /* DBC end marker */
{
22, /* size of permittable character structure */
1, /* reserved */
'\x00', '\xff', /* first/last permittable character */
0, /* reserved */
'\x00', ' ', /* first/last excluded character */
2, /* reserved */
14, /* number of separators */
{ /* separators */
'.', '"', '/', '\\', '[', ']', ':', '|', /* 0 - 7 */
'<', '>', '+', '=', ';', ',' /* 8 - 13 */
}
}
}

View File

@ -39,6 +39,9 @@ static BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.6 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.5 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -148,12 +151,14 @@ static BYTE FAR *lpOldLast;
static BYTE FAR *upOldLast;
static COUNT nCfgLine;
static COUNT nPass;
static COUNT UmbState;
static BYTE szLine[256];
static BYTE szBuf[256];
int singleStep = 0;
INIT VOID zumcb_init(mcb FAR * mcbp, UWORD size);
INIT VOID mumcb_init(mcb FAR * mcbp, UWORD size);
INIT VOID Buffers(BYTE * pLine);
INIT VOID sysScreenMode(BYTE * pLine);
@ -201,7 +206,7 @@ static struct table commands[] =
{"country", 1, Country},
{"device", 2, Device},
{"devicehigh", 2, DeviceHigh},
{"dos", 1, Dosmem},
{"dos", 2, Dosmem},
{"fcbs", 1, Fcbs},
{"files", 1, Files},
{"lastdrive", 1, Lastdrive},
@ -229,6 +234,8 @@ INIT void PreConfig(void)
{
/* Set pass number */
nPass = 0;
VgaSet = 0;
UmbState = 0;
/* Initialize the base memory pointers */
lpOldLast = lpBase = AlignParagraph((BYTE FAR *) & last);
@ -301,9 +308,6 @@ INIT void PreConfig(void)
/* Also, run config.sys to load drivers. */
INIT void PostConfig(void)
{
COUNT tmp = 0xc000;
/* Set pass number */
nPass = 2;
/* compute lastdrive ... */
@ -368,19 +372,6 @@ INIT void PostConfig(void)
FP_SEG(lpBase), FP_OFF(lpBase));
#endif
if(uppermem_link)
{
upBase = MK_FP(tmp , 0);
uppermem_root = FP_SEG(upBase) + ((FP_OFF(upBase) + 0x0f) >> 4);
umcb_init((mcb FAR *) (MK_FP(uppermem_root, 0)), 0 );
upBase += 16;
#ifdef DEBUG
printf("UMB Allocation completed: top at 0x%04x:0x%04x\n",
FP_SEG(upBase), FP_OFF(upBase));
#endif
}
}
@ -403,15 +394,34 @@ INIT VOID configDone(VOID)
mcb_init((mcb FAR *) (MK_FP(first_mcb, 0)),
(ram_top << 6) - first_mcb - 1);
if(uppermem_link)
if(UmbState == 1)
{
uppermem_root = FP_SEG(upBase) + ((FP_OFF(upBase) + 0x0f) >> 4);
zumcb_init((mcb FAR *) (MK_FP(uppermem_root, 0)),
(UMB_top << 6) - uppermem_root - 1);
mumcb_init((mcb FAR *) (MK_FP(0x9fff, 0)),
umb_start - 0x9fff);
/* make last end of mem block normal with SC */
mumcb_init((mcb FAR *) (MK_FP(uppermem_root, 0)),
(FP_SEG(upBase) + ((FP_OFF(upBase) + 0x0f) >> 4)) - uppermem_root - 1);
uppermem_root = FP_SEG(upBase) + ((FP_OFF(upBase) + 0x0f) >> 4);
zumcb_init((mcb FAR *) (MK_FP(uppermem_root, 0)),
(umb_start + UMB_top ) - uppermem_root - 1);
upBase += 16;
}
#ifdef DEBUG
printf("UMB Allocation completed: top at 0x%04x:0x%04x\n",
FP_SEG(upBase), FP_OFF(upBase));
#endif
/* The standard handles should be reopened here, because
we may have loaded new console or printer drivers in CONFIG.SYS */
}
INIT VOID DoConfig(VOID)
@ -484,6 +494,37 @@ INIT VOID DoConfig(VOID)
while (!bEof && *pLine != EOF)
{
/*
Do it here in the loop.
*/
if(UmbState == 2){
if(!Umb_Test()){
UmbState = 1;
upBase = MK_FP(umb_start , 0);
uppermem_root = umb_start;
/* master sig for umb region with full size */
umcb_init((mcb FAR *) upBase, UMB_top );
upBase += 16;
/* reset root */
uppermem_root = FP_SEG(upBase) + ((FP_OFF(upBase) + 0x0f) >> 4);
/* setup the real mcb for the devicehigh block */
zumcb_init((mcb FAR *) (MK_FP(uppermem_root, 0)), UMB_top - 1);
upBase += 16;
#ifdef DEBUG
printf("UMB Allocation completed: top at 0x%04x:0x%04x\n",
FP_SEG(upBase), FP_OFF(upBase));
#endif
}
}
for (pTmp = pLine; pTmp - szLine < LINESIZE; pTmp++)
{
if (*pTmp == '\r' || *pTmp == EOF)
@ -676,22 +717,17 @@ INIT static VOID Lastdrive(BYTE * pLine)
Config.cfgLastdrive = max(Config.cfgLastdrive, drv);
}
/*
UmbState of confidence, 1 is sure, 2 maybe, 4 unknown and 0 no way.
*/
INIT static VOID Dosmem(BYTE * pLine)
{
COUNT tmp;
COUNT FAR * u = MK_FP(0xc000, 0);
if(UmbState == 0){
uppermem_link = 0;
uppermem_root = 0;
GetStringArg(pLine, szBuf);
uppermem_link = strcmp(szBuf, "UMB") ? 1 : 0;
if(uppermem_link)
{
tmp = *u;
*u = 0x1234;
if(*u == 0x1234)
*u = tmp;
else
uppermem_link = 0;
UmbState = strcmp(szBuf, "UMB") ? 2 : 0;
}
}
@ -827,7 +863,7 @@ INIT static VOID Break(BYTE * pLine)
INIT static VOID DeviceHigh(BYTE * pLine)
{
if(uppermem_link)
if(UmbState == 1)
{
LoadDevice(pLine, UMB_top, TRUE);
}
@ -1036,23 +1072,34 @@ INIT VOID
mcbp->m_type = MCB_LAST;
mcbp->m_psp = FREE_PSP;
/* if(UmbState == 1)*/
mcbp->m_size = (size - 1);
/*
mcbp->m_size = size;
*/
for (i = 0; i < 8; i++)
mcbp->m_name[i] = '\0';
mem_access_mode = FIRST_FIT;
}
/* master umb sig */
INIT VOID
umcb_init(mcb FAR * mcbp, UWORD size)
{
COUNT i;
static char name[8] = "UMB ";
mcbp->m_type = 0x4d;
mcbp->m_psp = 0x08;
mcbp->m_type = MCB_LAST;
mcbp->m_psp = (UWORD) FP_SEG( mcbp );
mcbp->m_psp++;
mcbp->m_size = size;
for (i = 0; i < 8; i++)
mcbp->m_name[i] = name[i];
}
INIT VOID
zumcb_init(mcb FAR * mcbp, UWORD size)
{
@ -1061,6 +1108,19 @@ INIT VOID
mcbp->m_psp = FREE_PSP;
mcbp->m_size = size;
}
INIT VOID
mumcb_init(mcb FAR * mcbp, UWORD size)
{
COUNT i;
static char name[8] = "SC\0\0\0\0\0\0";
mcbp->m_type = MCB_NORMAL;
mcbp->m_psp = 8;
mcbp->m_size = size;
for (i = 0; i < 8; i++)
mcbp->m_name[i] = name[i];
}
#endif
INIT VOID
@ -1071,3 +1131,4 @@ INIT VOID
strcpy(d, s);
}

38
kernel/config.h Normal file
View File

@ -0,0 +1,38 @@
/****************************************************************/
/* */
/* config.h */
/* DOS-C */
/* */
/* Global data structures and declarations */
/* */
/* Copyright (c) 2000 */
/* Steffen Kaiser */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* 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. */
/****************************************************************/
#ifdef DEBUG
/* Enable debugging of NLS part */
/* Caution: Enabling NLS debugging usually generates
_a_lot_ of noise. */
/*& #define NLS_DEBUG */
#endif

View File

@ -34,6 +34,9 @@ static BYTE *dosfnsRcsId = "$Id$";
/*
* $Log$
* Revision 1.8 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.7 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -814,6 +817,15 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode)
WORD i;
COUNT drive, result;
/* /// Added to adjust for filenames which begin with ".\"
The problem was manifesting itself in the inability
to run an program whose filename (without the extension)
was longer than six characters and the PATH variable
contained ".", unless you explicitly specified the full
path to the executable file.
Jun 11, 2000 - rbc */
if ( (fname[0] == '.') && (fname[1] == '\\') ) fname += 2;
/* test if mode is in range */
if ((mode & ~SFT_OMASK) != 0)
return DE_INVLDACC;
@ -1170,7 +1182,17 @@ COUNT DosGetFattr(BYTE FAR * name, UWORD FAR * attrp)
return result;
}
if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV)
/* /// Added check for "d:\", which returns 0x10 (subdirectory) under DOS.
- Ron Cemer */
if ( (PriPathName[0] != '\0')
&& (PriPathName[1] == ':')
&& ( (PriPathName[2] == '/') || (PriPathName[2] == '\\') )
&& (PriPathName[3] == '\0') ) {
*attrp = 0x10;
return SUCCESS;
}
if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV)
{
last_cds = current_ldt;
current_ldt = &CDSp->cds_table[drive];
@ -1180,8 +1202,21 @@ COUNT DosGetFattr(BYTE FAR * name, UWORD FAR * attrp)
*attrp = srfa[0];
}
else {
result = dos_getfattr(name, attrp);
/* /// Use truename()'s result, which we already have in PriPathName.
I copy it to tmp_name because PriPathName is global and seems
to get trashed somewhere in transit.
The reason for using truename()'s result is that dos_?etfattr()
are very low-level functions and don't handle full path expansion
or cleanup, such as converting "c:\a\b\.\c\.." to "C:\A\B".
- Ron Cemer
*/
BYTE tmp_name[128];
int i;
for (i = 0; PriPathName[i] != '\0'; i++) tmp_name[i] = PriPathName[i];
tmp_name[i] = '\0';
result = dos_getfattr(tmp_name, attrp);
}
/* Sorry Ron someone else found this, see history.txt */
return result;
}
@ -1214,7 +1249,16 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD FAR * attrp)
current_ldt = last_cds;
}
else {
result = dos_setfattr(name, attrp);
/* /// Use truename()'s result, which we already have in PriPathName.
I copy it to tmp_name because PriPathName is global and seems
to get trashed somewhere in transit.
- Ron Cemer
*/
BYTE tmp_name[128];
int i;
for (i = 0; PriPathName[i] != '\0'; i++) tmp_name[i] = PriPathName[i];
tmp_name[i] = '\0';
result = dos_setfattr(name, attrp);
}
return result;
}
@ -1362,9 +1406,16 @@ struct dhdr FAR * IsDevice(BYTE FAR * fname)
SecPathName[i] = ' ';
SecPathName[i] = 0;
/* if we have an extension, can't be a device */
/* /// BUG!!! This is absolutely wrong. A filename of "NUL.LST" must be
treated EXACTLY the same as a filename of "NUL". The existence or
content of the extension is irrelevent in determining whether a
filename refers to a device.
- Ron Cemer
// if we have an extension, can't be a device <--- WRONG.
if (*froot != '.')
{
*/
for (dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp->dh_next)
{
if (fnmatch((BYTE FAR *) SecPathName, (BYTE FAR *) dhp->dh_name, FNAME_SIZE, FALSE))
@ -1372,7 +1423,7 @@ struct dhdr FAR * IsDevice(BYTE FAR * fname)
return dhp;
}
}
}
return (struct dhdr FAR *)0;
}

View File

@ -36,6 +36,9 @@ static BYTE *fatdirRcsId = "$Id$";
/*
* $Log$
* Revision 1.9 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.8 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -291,7 +294,7 @@ struct f_node FAR *dir_open(BYTE FAR * dirname)
/* find the entry... */
i = FALSE;
upFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);
DosUpFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);
while (dir_read(fnp) == DIRENT_SIZE)
{
@ -592,7 +595,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE FAR * name)
/* current directory, do a seek and read, then close the fnode. */
/* Start out by initializing the dirmatch structure. */
dmp->dm_drive = default_drive;
dmp->dm_drive = default_drive ;
dmp->dm_entry = 0;
dmp->dm_cluster = 0;
@ -609,7 +612,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE FAR * name)
*/
if (nDrive >= 0)
{
dmp->dm_drive = nDrive;
dmp->dm_drive = nDrive ;
}
else
nDrive = default_drive;
@ -652,7 +655,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE FAR * name)
SearchDir.dir_ext[i] = ' ';
/* Convert everything to uppercase. */
upFMem(SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE);
DosUpFMem(SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE);
/* Copy the raw pattern from our data segment to the DTA. */
fbcopy((BYTE FAR *) SearchDir.dir_name, dmp->dm_name_pat,
@ -666,6 +669,56 @@ COUNT dos_findfirst(UCOUNT attr, BYTE FAR * name)
return SUCCESS;
}
/* /// Added code here to do matching against device names.
DOS findfirst will match exact device names if the
filename portion (excluding the extension) contains
a valid device name.
Credits: some of this code was ripped off from truename()
in newstuff.c.
- Ron Cemer */
if (!(attr & D_VOLID)) {
char Name[FNAME_SIZE];
int d, wild = 0;
for (d = 0; d < FNAME_SIZE; d++) {
if ((Name[d] = SearchDir.dir_name[d]) == '?') {
wild = 1;
break;
}
}
if (!wild) {
struct dhdr FAR *dhp;
for (dhp = (struct dhdr FAR *)&nul_dev;
dhp != (struct dhdr FAR *)-1;
dhp = dhp->dh_next) {
if (fnmatch
((BYTE FAR *)&Name,
(BYTE FAR *)dhp->dh_name,
FNAME_SIZE,
FALSE)) {
/* Found a matching device. */
dmp->dm_entry = 0;
dmp->dm_cluster = 0;
dmp->dm_flags.f_dmod = 0;
dmp->dm_flags.f_droot = 0;
dmp->dm_flags.f_dnew = 0;
dmp->dm_flags.f_ddir = 0;
dmp->dm_flags.f_dfull = 0;
dmp->dm_dirstart = 0;
dmp->dm_attr_fnd = D_DEVICE;
dmp->dm_time = dos_gettime();
dmp->dm_date = dos_getdate();
dmp->dm_size = 0L;
for (d = 0; ( (d < FNAME_SIZE) && (Name[d] != ' ') ); d++)
dmp->dm_name[d] = Name[d];
dmp->dm_name[d] = '\0';
return SUCCESS;
}
}
}
}
/* /// End of additions. - Ron Cemer */
/* Now search through the directory to find the entry... */
/* Special handling - the volume id is only in the root */
/* directory and only searched for once. So we need to open */
@ -741,6 +794,9 @@ COUNT dos_findnext(void)
/* assign our match parameters pointer. */
dmp = (dmatch FAR *) dta;
/* /// findnext will always fail on a device name. - Ron Cemer */
if (dmp->dm_attr_fnd == D_DEVICE) return DE_FILENOTFND;
/*
* The new version of SHSUCDX 1.0 looks at the dm_drive byte to
* test 40h. I used RamView to see location MSD 116:04be and
@ -752,7 +808,7 @@ COUNT dos_findnext(void)
* So, assume bit 6 is redirector and bit 7 is network.
* jt
*/
nDrive = dmp->dm_drive & 0x1f;
nDrive = dmp->dm_drive & 0x1f;
if (nDrive > (lastdrive -1)) {
return DE_INVLDDRV;
@ -780,7 +836,7 @@ COUNT dos_findnext(void)
/* Force the fnode into read-write mode */
fnp->f_mode = RDWR;
if (dmp->dm_drive > (lastdrive -1)) {
if (dmp->dm_drive > (lastdrive)) {
return DE_INVLDDRV;
}
/* Select the default to help non-drive specified path */

View File

@ -36,6 +36,9 @@ BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.6 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.5 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -377,9 +380,9 @@ static struct f_node FAR *
}
/* Convert the name into an absolute name for comparison... */
upFMem((BYTE FAR *) dname, strlen(dname));
upFMem((BYTE FAR *) fname, FNAME_SIZE);
upFMem((BYTE FAR *) fext, FEXT_SIZE);
DosUpFString((BYTE FAR *) dname);
DosUpFMem((BYTE FAR *) fname, FNAME_SIZE);
DosUpFMem((BYTE FAR *) fext, FEXT_SIZE);
return fnp;
}

View File

@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.6 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.5 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -223,7 +226,7 @@ WORD FcbParseFname(int wTestMode, BYTE FAR ** lpFileName, fcb FAR * lpFcb)
/* Now check for drive specification */
if (*(*lpFileName + 1) == ':')
{
REG BYTE Drive = upChar(**lpFileName);
REG BYTE Drive = DosUpFChar(**lpFileName);
/* non-portable construct to be changed */
if (Drive < 'A' || Drive > 'Z')
@ -299,7 +302,7 @@ BYTE FAR *GetNameField(BYTE FAR * lpFileName, BYTE FAR * lpDestField,
}
if (*lpFileName == '?')
*pbWildCard = TRUE;
*lpDestField++ = upChar(*lpFileName++);
*lpDestField++ = DosUpFChar(*lpFileName++);
++nIndex;
}
@ -476,7 +479,6 @@ BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
/* check for a device */
/* if we have an extension, can't be a device */
if (IsDevice(PriPathName) || (lpFcb->fcb_recsiz == 0))
{
return FALSE;
@ -645,7 +647,6 @@ BOOL FcbCreate(xfcb FAR * lpXfcb)
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
/* check for a device */
/* if we have an extension, can't be a device */
dhp = IsDevice(PriPathName);
if (dhp)
{
@ -781,7 +782,6 @@ BOOL FcbOpen(xfcb FAR * lpXfcb)
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
/* check for a device */
/* if we have an extension, can't be a device */
dhp = IsDevice(PriPathName);
if (dhp )
{
@ -858,7 +858,6 @@ BOOL FcbDelete(xfcb FAR * lpXfcb)
}
/* check for a device */
/* if we have an extension, can't be a device */
if (IsDevice(PriPathName))
{
return FALSE;
@ -897,7 +896,6 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
/* check for a device */
/* if we have an extension, can't be a device */
if (IsDevice(PriPathName))
{
return FALSE;
@ -1108,7 +1106,7 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
dta = (BYTE FAR *) & Dmatch;
/* Next initialze local variables by moving them from the fcb */
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
if (lpXfcb->xfcb_flag == 0xff)
{
wAttr = lpXfcb->xfcb_attrib;
@ -1118,8 +1116,10 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
else
wAttr = D_ALL;
*lpDir++ = PriPathName[0] - 'A';
if (dos_findfirst(wAttr, PriPathName) != SUCCESS)
*lpDir++ = FcbDrive;
if (dos_findfirst(wAttr, SecPathName) != SUCCESS)
{
dta = lpPsp->ps_dta;
return FALSE;
@ -1129,16 +1129,19 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
lpFcb->fcb_dirclst = Dmatch.dm_cluster;
lpFcb->fcb_diroff = Dmatch.dm_entry;
/*
This is undocumented and seen using Pcwatch.
This is undocumented and seen using Pcwatch and Ramview.
The First byte is the current directory count and the second seems
to be the attribute byte.
*/
lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date.*/
#if 0
lpFcb->fcb_cublock = Dmatch.dm_entry;
lpFcb->fcb_cublock *= 0x100;
lpFcb->fcb_cublock += wAttr;
#endif
dta = lpPsp->ps_dta;
return TRUE;
}
@ -1157,7 +1160,7 @@ BOOL FcbFindNext(xfcb FAR * lpXfcb)
dta = (BYTE FAR *) & Dmatch;
/* Next initialze local variables by moving them from the fcb */
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
if ((xfcb FAR *) lpFcb != lpXfcb)
{
wAttr = lpXfcb->xfcb_attrib;
@ -1169,10 +1172,10 @@ BOOL FcbFindNext(xfcb FAR * lpXfcb)
/* Reconstrct the dirmatch structure from the fcb */
*lpDir++ = FcbDrive;
Dmatch.dm_drive = FcbDrive ? FcbDrive - 1 : default_drive;
Dmatch.dm_drive = lpFcb->fcb_sftno;
fbcopy(lpFcb->fcb_fname, (BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
upFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
Dmatch.dm_attr_srch = wAttr;
Dmatch.dm_entry = lpFcb->fcb_diroff;
@ -1188,13 +1191,17 @@ BOOL FcbFindNext(xfcb FAR * lpXfcb)
MoveDirInfo((dmatch FAR *) & Dmatch, (struct dirent FAR *)lpDir);
lpFcb->fcb_dirclst = Dmatch.dm_cluster;
lpFcb->fcb_diroff = Dmatch.dm_entry;
dta = lpPsp->ps_dta;
lpFcb->fcb_sftno = Dmatch.dm_drive;
#if 0
lpFcb->fcb_cublock = Dmatch.dm_entry;
lpFcb->fcb_cublock *= 0x100;
lpFcb->fcb_cublock += wAttr;
#endif
dta = lpPsp->ps_dta;
return TRUE;
}
#endif

View File

@ -36,8 +36,8 @@ static BYTE *Globals_hRcsId = "$Id$";
/*
* $Log$
* Revision 1.4 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
* Revision 1.5 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.3 2000/05/25 20:56:21 jimtabor
* Fixed project history
@ -180,6 +180,7 @@ static BYTE *Globals_hRcsId = "$Id$";
#include "error.h"
#include "version.h"
#include "network.h"
#include "config.h"
/* JPP: for testing/debuging disk IO */
/*#define DISPLAY_GETBLOCK */
@ -424,6 +425,7 @@ extern BYTE NetDelay,
extern UWORD
first_mcb, /* Start of user memory */
UMB_top,
umb_start,
uppermem_root; /* Start of umb chain ? */
extern struct dpb
FAR *DPBp; /* First drive Parameter Block */
@ -462,6 +464,7 @@ extern BYTE
CritErrLocus,
CritErrAction,
CritErrClass,
VgaSet,
njoined; /* number of joined devices */
extern UWORD Int21AX;
@ -609,8 +612,17 @@ GLOBAL struct config
BYTE cfgLastdrive; /* last drive */
BYTE cfgStacks; /* number of stacks */
UWORD cfgStackSize; /* stacks size for each stack */
}
Config
/* COUNTRY=
In Pass #1 these information is collected and in PostConfig()
the NLS package is loaded into memory.
-- 2000/06/11 ska*/
WORD cfgCSYS_cntry; /* country ID to be loaded */
WORD cfgCSYS_cp; /* requested codepage; NLS_DEFAULT if default */
BYTE cfgCSYS_fnam[NAMEMAX]; /* filename of COUNTRY= */
WORD cfgCSYS_memory; /* number of bytes required for the NLS pkg;
0 if none */
VOID FAR *cfgCSYS_data; /* where the loaded data is for PostConfig() */
} Config
#ifdef MAIN
=
{
@ -623,6 +635,12 @@ Config
NLAST,
NSTACKS,
128
/* COUNTRY= is initialized within DoConfig() */
,0 /* country ID */
,0 /* codepage */
,"" /* filename */
,0 /* amount required memory */
,0 /* pointer to loaded data */
};
#else
;

View File

@ -30,6 +30,9 @@
; $Id$
;
; $Log$
; Revision 1.6 2000/08/06 05:50:17 jimtabor
; Add new files and update cvs with patches and changes
;
; Revision 1.5 2000/06/21 18:16:46 jimtabor
; Add UMB code, patch, and code fixes
;
@ -83,9 +86,13 @@
;
%include "segs.inc"
%include "stacks.inc"
segment _TEXT
extern _nul_dev:wrt DGROUP
extern _nul_dev:wrt DGROUP
extern _umb_start:wrt DGROUP
extern _UMB_top:wrt DGROUP
extern _syscall_MUX14:wrt _TEXT
global _int2f_handler
_int2f_handler:
@ -107,8 +114,27 @@ Int2f3:
cmp ah,10h ; SHARE.EXE interrupt?
je Int2f1 ; yes, do installation check
cmp ah,14h ; NLSFUNC.EXE interrupt?
je Int2f1 ; yes, do installation check
iret ; Default, interrupt return
jne Int2f?iret ; yes, do installation check
Int2f?14: ;; MUX-14 -- NLSFUNC API
;; all functions are passed to syscall_MUX14
push bp ; Preserve BP later on
PUSH$ALL
call _syscall_MUX14
pop bp ; Discard incoming AX
push ax ; Correct stack for POP$ALL
POP$ALL
mov bp, sp
or ax, ax
jnz Int2f?14?1 ; must return set carry
;; -6 == -2 (CS), -2 (IP), -2 (flags)
;; current SP = on old_BP
and BYTE [bp-6], 0feh ; clear carry as no error condition
pop bp
iret
Int2f?14?1: or BYTE [bp-6], 1
pop bp
Int2f?iret:
iret
;
;return dos data seg.
@ -285,3 +311,97 @@ int2f_call:
pop bp
pop bp
ret
;
; Test to see if a umb driver has been loaded.
;
; From RB list and Dosemu xms.c.
;
; Call the XMS driver "Request upper memory block" function with:
; AH = 10h
; DX = size of block in paragraphs
; Return: AX = status
; 0001h success
; BX = segment address of UMB
; DX = actual size of block
; 0000h failure
; BL = error code (80h,B0h,B1h) (see #02775)
; DX = largest available block
;
; (Table 02775)
; Values for XMS error code returned in BL:
; 00h successful
; 80h function not implemented
; B0h only a smaller UMB is available
; B1h no UMB's are available
; B2h UMB segment number is invalid
;
;
global _Umb_Test
_Umb_Test
push bp
mov bp,sp
push es
push ds
push dx
push bx
mov ax,DGROUP
mov ds,ax
mov ax,4300h ; is there a xms driver installed?
int 2fh
cmp al,80h
jne umbt_error
mov ax,4310h
int 2fh
push es ; save driver entry point
push bx
mov dx,0xffff ; go for broke!
mov ax,1000h ; get the umb's
push cs ; setup far return
push word umbt1
push es ; push the driver entry point
push bx
retf ; Call the driver
umbt1:
;
; bl = 0xB0 and ax = 0 so do it again.
;
cmp bl,0xb0 ; fail safe
je umbtb
add sp,4
jmp umbt_error
umbtb:
and dx,dx ; if it returns a size of zero.
jne umbtc
add sp,4
jmp umbt_error
umbtc:
pop bx ; restore driver entry
pop es
mov ax,1000h ; dx set with largest size
push cs
push word umbt2
push es
push bx
retf
umbt2:
cmp ax,1
jne umbt_error
mov word [_umb_start], bx ; save the segment
mov word [_UMB_top], dx ; and the true size
umbt_error: dec ax
pop bx
pop dx
pop ds
pop es
pop bp
retf ; this was called FAR.

View File

@ -36,6 +36,9 @@ BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.9 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.8 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -194,12 +197,15 @@ static VOID StartTrace(VOID);
static bTraceNext = FALSE;
#endif
#if 0 /* Very suspicious, passing structure by value??
Deactivated -- 2000/06/16 ska*/
/* Special entry for far call into the kernel */
#pragma argsused
VOID FAR int21_entry(iregs UserRegs)
{
int21_handler(UserRegs);
}
#endif
/* Normal entry. This minimizes user stack usage by avoiding local */
/* variables needed for the rest of the handler. */
@ -342,25 +348,7 @@ dispatch:
r->FLAGS |= FLG_CARRY;
break;
#if 0
/* Moved to simulate a 0x4c00 -- 1999/04/21 ska */
/* Terminate Program */
case 0x00:
if (cu_psp == RootPsp)
break;
else if (((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
break;
tsr = FALSE;
return_mode = break_flg ? 1 : 0;
return_code = r->AL;
if (DosMemCheck() != SUCCESS)
panic("MCB chain corrupted");
#ifdef TSC
StartTrace();
#endif
return_user();
break;
#endif
/* case 0x00: --> Simulate a DOS-4C-00 */
/* Read Keyboard with Echo */
case 0x01:
@ -862,11 +850,11 @@ dispatch:
if (0xffff == r->DX) {
/* Set Country Code */
if((rc = setCountryCode(cntry)) < 0)
if((rc = DosSetCountry(cntry)) < 0)
goto error_invalid;
} else {
/* Get Country Information */
if((rc = getCountryInformation(cntry, MK_FP(r->DS, r->DX))) < 0)
if((rc = DosGetCountryInformation(cntry, MK_FP(r->DS, r->DX))) < 0)
goto error_invalid;
r->AX = r->BX = cntry;
}
@ -1277,23 +1265,35 @@ dispatch:
break;
case 0x01:
/* if (((COUNT) r->BX) < 0 || r->BX > 2)
goto error_invalid;
else
{ */
{
switch (r->BX)
{
case LAST_FIT:
case LAST_FIT_U:
case LAST_FIT_UO:
case LARGEST:
case BEST_FIT:
case BEST_FIT_U:
case BEST_FIT_UO:
case FIRST_FIT:
case FIRST_FIT_U:
case FIRST_FIT_UO:
mem_access_mode = r->BX;
break;
mem_access_mode = r->BX;
default:
goto error_invalid;
}
}
r->FLAGS &= ~FLG_CARRY;
/* }*/
break;
break;
case 0x02:
r->AL = uppermem_link;
break;
case 0x03:
uppermem_link = r->BL;
DosUmbLink(r->BL);
break;
default:
@ -1510,31 +1510,39 @@ dispatch:
case 0x65:
switch(r->AL) {
case 0x20: /* upcase single character */
r->DL = upChar(r->DL);
r->DL = DosUpChar(r->DL);
break;
case 0x21: /* upcase memory area */
upMem(MK_FP(r->DS, r->DX), r->CX);
DosUpMem(MK_FP(r->DS, r->DX), r->CX);
break;
case 0x22: /* upcase ASCIZ */
upString(MK_FP(r->DS, r->DX));
DosUpString(MK_FP(r->DS, r->DX));
break;
case 0xA0: /* upcase single character of filenames */
r->DL = upFChar(r->DL);
r->DL = DosUpFChar(r->DL);
break;
case 0xA1: /* upcase memory area of filenames */
upFMem(MK_FP(r->DS, r->DX), r->CX);
DosUpFMem(MK_FP(r->DS, r->DX), r->CX);
break;
case 0xA2: /* upcase ASCIZ of filenames */
upFString(MK_FP(r->DS, r->DX));
DosUpFString(MK_FP(r->DS, r->DX));
break;
case 0x23: /* check Yes/No response */
r->AX = yesNo(r->DL);
r->AX = DosYesNo(r->DL);
break;
default:
if ((rc = extCtryInfo(
if ((rc = DosGetData(
r->AL, r->BX, r->DX, r->CX,
MK_FP(r->ES, r->DI))) < 0)
goto error_exit;
MK_FP(r->ES, r->DI))) < 0) {
#ifdef NLS_DEBUG
printf("DosGetData() := %d\n", rc);
#endif
goto error_exit;
}
#ifdef NLS_DEBUG
printf("DosGetData() returned successfully\n", rc);
#endif
break;
}
r->FLAGS &= ~FLG_CARRY;
@ -1546,10 +1554,10 @@ dispatch:
switch (r->AL)
{
case 1:
rc = getCodePage(&r->BX, &r->DX);
rc = DosGetCodepage(&r->BX, &r->DX);
break;
case 2:
rc = setCodePage(r->BX, r->DX);
rc = DosSetCodepage(r->BX, r->DX);
break;
default:

View File

@ -28,6 +28,9 @@
; $Id$
;
; $Log$
; Revision 1.5 2000/08/06 05:50:17 jimtabor
; Add new files and update cvs with patches and changes
;
; Revision 1.4 2000/06/21 18:16:46 jimtabor
; Add UMB code, patch, and code fixes
;
@ -307,7 +310,8 @@ deblock_seg dw 0 ; 0056 (offset always zero)
times 3 db 0 ; 0058 unknown
dw 0 ; 005B unknown
db 0, 0FFh, 0 ; 005D unknown
db 0 ; 0060 unknown
global _VgaSet
_VgaSet db 0 ; 0060 unknown
dw 0 ; 0061 unknown
global _uppermem_link
_uppermem_link db 0 ; 0063 upper memory link flag
@ -315,7 +319,8 @@ _uppermem_link db 0 ; 0063 upper memory link flag
_UMB_top dw 0 ; 0064 unknown UMB_top will do for now
global _uppermem_root
_uppermem_root dw 0FFFFh ; 0066 dmd_upper_root
dw 0 ; 0068 para of last mem search
global _umb_start
_umb_start dw 0 ; 0068 para of last mem search
SysVarEnd:

View File

@ -5,6 +5,9 @@
#
# $Log$
# Revision 1.4 2000/08/06 05:50:17 jimtabor
# Add new files and update cvs with patches and changes
#
# Revision 1.3 2000/05/25 20:56:21 jimtabor
# Fixed project history
#
@ -119,10 +122,10 @@ INCLUDEPATH = ..\HDR
#AFLAGS = /Mx /DSTANDALONE=1 /I..\HDR
NASMFLAGS = -i../hdr/
LIBS =..\LIB\DEVICE.LIB ..\LIB\LIBM.LIB
CFLAGS = -1- -O -Z -d -I..\hdr -I. \
-D__STDC__=0;DEBUG;KERNEL;I86;PROTO;ASMSUPT
#CFLAGS = -1- -O -Z -d -I..\hdr -I. \
# -D__STDC__=0;KERNEL;I86;PROTO;ASMSUPT
# -D__STDC__=0;DEBUG;KERNEL;I86;PROTO;ASMSUPT
CFLAGS = -1- -O -Z -d -I..\hdr -I. \
-D__STDC__=0;KERNEL;I86;PROTO;ASMSUPT
INITCFLAGS = $(CFLAGS) -zAINIT -zCINIT_TEXT -zPIGROUP
HDR=../hdr/
@ -244,6 +247,8 @@ io.obj: io.asm segs.inc
irqstack.obj: irqstack.asm
nls_hc.obj: nls_hc.asm segs.inc
nlssupt.obj: nlssupt.asm segs.inc
procsupt.obj: procsupt.asm segs.inc $(HDR)stacks.inc
@ -399,10 +404,10 @@ nls.obj: nls.c $(HDR)portab.h globals.h $(HDR)device.h $(HDR)mcb.h \
$(HDR)pcb.h $(HDR)date.h $(HDR)time.h $(HDR)fat.h $(HDR)fcb.h \
$(HDR)tail.h $(HDR)process.h $(HDR)dcb.h $(HDR)sft.h $(HDR)cds.h \
$(HDR)exe.h $(HDR)fnode.h $(HDR)dirmatch.h $(HDR)file.h \
$(HDR)clock.h $(HDR)kbd.h $(HDR)error.h $(HDR)version.h proto.h \
001-437.nls
$(HDR)clock.h $(HDR)kbd.h $(HDR)error.h $(HDR)version.h proto.h
nls_hc.obj: nls_hc.c globals.h $(HDR)portab.h $(HDR)nls.h
# \
# 001-437.nls
prf.obj: prf.c $(HDR)portab.h

View File

@ -39,6 +39,9 @@ static BYTE *mainRcsId = "$Id$";
/*
* $Log$
* Revision 1.7 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.6 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -193,8 +196,8 @@ INIT static VOID init_kernel(void)
/* Init oem hook - returns memory size in KB */
ram_top = init_oem();
UMB_top = 3; /* testing for now*
UMB_top = 0;
umb_start = 0;
/* Fake int 21h stack frame */
user_r = (iregs FAR *) DOS_PSP + 0xD0;

View File

@ -35,6 +35,9 @@ static BYTE *memmgrRcsId = "$Id$";
/*
* $Log$
* Revision 1.5 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.4 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -185,8 +188,15 @@ COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize)
/* Initialize */
p = para2far(first_mcb);
biggestSeg = foundSeg = NULL;
if((mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link) {
if(uppermem_root)
p = para2far(uppermem_root);
}
/* Search through memory blocks */
FOREVER
{
@ -196,7 +206,7 @@ COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize)
if (mcbFree(p))
{ /* unused block, check if it applies to the rule */
if (joinMCBs(p) != SUCCESS) /* join following unused blocks */
if (joinMCBs(p) != SUCCESS) /* join following unused blocks */
return DE_MCBDESTRY; /* error */
if (!biggestSeg || biggestSeg->m_size < p->m_size)
@ -208,6 +218,8 @@ COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize)
switch (mode)
{
case LAST_FIT: /* search for last possible */
case LAST_FIT_U:
case LAST_FIT_UO:
default:
foundSeg = p;
break;
@ -218,14 +230,19 @@ COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize)
break;
case BEST_FIT: /* first, but smallest block */
case BEST_FIT_U:
case BEST_FIT_UO:
if (!foundSeg || foundSeg->m_size > p->m_size)
/* better match found */
foundSeg = p;
break;
case FIRST_FIT: /* first possible */
case FIRST_FIT: /* first possible */
case FIRST_FIT_U:
case FIRST_FIT_UO:
foundSeg = p;
goto stopIt; /* OK, rest of chain can be ignored */
}
}
}
@ -254,7 +271,8 @@ stopIt: /* reached from FIRST_FIT on match */
/* foundSeg := pointer to allocated block
p := pointer to MCB that will form the rest of the block
*/
if (mode == LAST_FIT)
if (
(mode == LAST_FIT)||(mode == LAST_FIT_UO)||(mode == LAST_FIT_U))
{
/* allocate the block from the end of the found block */
p = foundSeg;
@ -310,7 +328,6 @@ COUNT FAR init_call_DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FA
COUNT DosMemLargest(UWORD FAR * size)
{
REG mcb FAR *p;
mcb FAR *q;
COUNT found;
/* Initialize */
@ -376,6 +393,7 @@ COUNT DosMemFree(UWORD para)
#if 0
/* Moved into allocating functions -- 1999/04/21 ska */
/* Now merge free blocks */
for (p = (mcb FAR *) (MK_FP(first_mcb, 0)); p->m_type != MCB_LAST; p = q)
{
/* make q a pointer to the next block */
@ -469,6 +487,7 @@ COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
COUNT DosMemCheck(void)
{
REG mcb FAR *p;
REG mcb FAR *u;
/* Initialize */
p = para2far(first_mcb);
@ -483,13 +502,13 @@ COUNT DosMemCheck(void)
/* not corrupted - but not end, bump the pointer */
p = nxtMCB(p);
}
return SUCCESS;
}
COUNT FreeProcessMem(UWORD ps)
{
mcb FAR *p;
mcb FAR *p, FAR *u;
COUNT x = 0;
/* Initialize */
p = para2far(first_mcb);
@ -501,12 +520,14 @@ COUNT FreeProcessMem(UWORD ps)
DosMemFree(FP_SEG(p));
/* not corrupted - if last we're OK! */
if (p->m_type == MCB_LAST)
return SUCCESS;
if (p->m_type == MCB_LAST){
if(x)
return DE_MCBDESTRY;
return SUCCESS;
}
p = nxtMCB(p);
}
return DE_MCBDESTRY;
}
@ -536,7 +557,6 @@ COUNT DosGetLargestBlock(UWORD FAR * block)
if (p->m_type == MCB_LAST)
break;
p = nxtMCB(p);
}
*block = sz;
return SUCCESS;
@ -545,7 +565,8 @@ COUNT DosGetLargestBlock(UWORD FAR * block)
VOID show_chain(void)
{
mcb FAR *p = para2far(first_mcb);
mcb FAR *p, FAR *u;
p = para2far(first_mcb);
for (;;)
{
@ -579,4 +600,49 @@ VOID _fmemcpy(BYTE FAR * d, BYTE FAR * s, REG COUNT n)
*d++ = *s++;
}
VOID DosUmbLink(BYTE n)
{
REG mcb FAR *p;
REG mcb FAR *q;
if(uppermem_root){
q = p = para2far(first_mcb);
if(uppermem_link){
while ( p != (mcb FAR *) para2far(0x9fff) )
{
if (!mcbValid(p))
goto DUL_exit;
q = p;
p = nxtMCB(p);
}
printf("M end at 0x%04x:0x%04x\n", FP_SEG(q), FP_OFF(q));
if(q->m_type == MCB_NORMAL)
q->m_type = MCB_LAST;
}
else
{
while( q->m_type != MCB_LAST)
{
if (!mcbValid(q))
goto DUL_exit;
q = nxtMCB(q);
}
printf("Z end at 0x%04x:0x%04x\n", FP_SEG(q), FP_OFF(q));
if(q->m_type == MCB_LAST)
q->m_type = MCB_NORMAL;
}
uppermem_link = n;
}
DUL_exit:
return;
}
#endif

View File

@ -36,6 +36,9 @@ static BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.7 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.6 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -118,7 +121,7 @@ UCOUNT Remote_RW(UWORD func, UCOUNT n, BYTE FAR * bp, sft FAR * s, COUNT FAR * e
COUNT Remote_find(UWORD func, BYTE FAR * name, REG dmatch FAR * dmp )
{
COUNT i, x;
char FAR *p, *q;
char FAR *p, FAR *q;
VOID FAR * test;
struct dirent FAR *SDp = (struct dirent FAR *) &SearchDir;

View File

@ -31,6 +31,9 @@ static BYTE *mainRcsId = "$Id$";
/*
* $Log$
* Revision 1.8 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.7 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
*
@ -217,7 +220,7 @@ COUNT get_verify_drive(char FAR *src)
}
else
drive = default_drive;
if ((drive < 0) || (drive > (lastdrive - 1))) {
if ((drive < 0) || (drive > lastdrive)) {
drive = DE_INVLDDRV;
}
return drive;
@ -233,9 +236,10 @@ COUNT get_verify_drive(char FAR *src)
COUNT truename(char FAR * src, char FAR * dest, COUNT t)
{
static char buf[128] = "A:\\\0\0\0\0\0\0\0\0\0";
static char Name[8] = " ";
/* /// Changed to FNAME_SIZE from 8 for cleanliness. - Ron Cemer */
static char Name[FNAME_SIZE];
char *bufp = buf + 3;
COUNT i, n, x = 2;
COUNT i, n, rootEndPos = 2; /* renamed x to rootEndPos - Ron Cemer */
struct cds FAR *cdsp;
struct dhdr FAR *dhp;
BYTE FAR *froot;
@ -251,7 +255,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
{
buf[0] = (src[0] | 0x20) + 'A' - 'a';
if (buf[0] > (lastdrive - 1) + 'A')
if (buf[0] > lastdrive + 'A')
return DE_PATHNOTFND;
src += 2;
@ -259,6 +263,16 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
else
buf[0] = default_drive + 'A';
/* /// Added to adjust for filenames which begin with ".\"
The problem was manifesting itself in the inability
to run an program whose filename (without the extension)
was longer than six characters and the PATH variable
contained ".", unless you explicitly specified the full
path to the executable file.
Jun 11, 2000 - rbc */
/* /// Changed to "while" from "if". - Ron Cemer */
while ( (src[0] == '.') && (src[1] == '\\') ) src += 2;
i = buf[0] - 'A';
/*
Code repoff from dosfns.c
@ -277,23 +291,50 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
for (; d < FNAME_SIZE; d++)
Name[d] = ' ';
/* /// Bugfix: NUL.LST is the same as NUL. This is true for all
devices. On a device name, the extension is irrelevant
as long as the name matches.
- Ron Cemer */
#if (0)
/* if we have an extension, can't be a device */
if (*froot != '.')
{
#endif
for (dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp->dh_next)
{
if (fnmatch((BYTE FAR *) &Name, (BYTE FAR *) dhp->dh_name, FNAME_SIZE, FALSE))
{
buf[2] ='/';
for (d = 0; d < FNAME_SIZE; d++){
if(Name[d] == 0x20)
goto exit_tn;
/* /// Bug: should be only copying up to first space.
- Ron Cemer
for (d = 0; d < FNAME_SIZE || Name[d] == ' '; d++) */
for (d = 0; ( (d < FNAME_SIZE) && (Name[d] != ' ') ); d++)
*bufp++ = Name[d];
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
DOS will also return C:/NUL.??? if you pass NUL.* in.
Code added here to support this.
- Ron Cemer */
while ( (*froot != '.') && (*froot != '\0') ) froot++;
if (*froot) froot++;
if (*froot) {
*bufp++ = '.';
for (i = 0; i < FEXT_SIZE; i++) {
if ( (*froot == '\0') || (*froot == '.') )
break;
if (*froot == '*') {
for (; i < FEXT_SIZE; i++) *bufp++ = '?';
break;
}
*bufp++ = *froot++;
}
}
/* /// End of code additions. - Ron Cemer */
goto exit_tn;
}
}
#if (0)
}
#endif
cdsp = &CDSp->cds_table[i];
current_ldt = cdsp;
@ -309,7 +350,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
{
fsncopy((BYTE FAR *) & cdsp->cdsCurrentPath[0], (BYTE FAR *) & buf[0], cdsp->cdsJoinOffset);
bufp = buf + cdsp->cdsJoinOffset;
x = cdsp->cdsJoinOffset;
rootEndPos = cdsp->cdsJoinOffset; /* renamed x to rootEndPos - Ron Cemer */
*bufp++ = '\\';
}
@ -327,6 +368,19 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
src++;
move_name:
/* /// The block inside the "#if (0) ... #endif" is
seriously broken. New code added below to replace it.
This eliminates many serious bugs, specifically
with FreeCOM where truename is required to work
according to the DOS specification in order for
the COPY and other file-related commands to work
properly.
This should be a major improvement to all apps which
use truename.
- Ron Cemer */
#if (0)
/*
* The code here is brain dead. It works long as the calling
* function are operating with in normal parms.
@ -384,7 +438,7 @@ move_name:
for (bufp -= 2; *bufp != '\\'; bufp--)
{
if (bufp < buf + x) /* '..' illegal in root dir */
if (bufp < buf + rootEndPos) /* '..' illegal in root dir */
return DE_PATHNOTFND;
}
src++;
@ -413,9 +467,115 @@ move_name:
break;
}
}
/* remove trailing backslashes */
while (bufp[-1] == '\\')
--bufp;
#endif
/* /// Beginning of new code. - Ron Cemer */
bufp--;
{
char c, *bufend = buf+(sizeof(buf)-1);
int gotAnyWildcards = 0;
int seglen, copylen, state;
while ( (*src) && (bufp < bufend) ) {
/* Skip duplicated slashes. */
while ( (*src == '/') || (*src == '\\') ) src++;
if (!(*src)) break;
/* Find the end of this segment in the source string. */
for (seglen = 0; ; seglen++) {
c = src[seglen];
if ( (c == '\0') || (c == '/') || (c == '\\') )
break;
}
if (seglen > 0) {
/* Ignore all ".\" or "\." path segments. */
if ( (seglen != 1) || (*src != '.') ) {
/* Apply ".." to the path by removing
last path segment from buf. */
if ( (seglen==2) && (src[0] == '.') && (src[1] == '.') ) {
if (bufp > (buf+rootEndPos)) {
bufp--;
while ( (bufp > (buf+rootEndPos))
&& (*bufp != '/')
&& (*bufp != '\\') )
bufp--;
}
} else {
/* New segment. If any wildcards in previous
segment(s), this is an invalid path. */
if (gotAnyWildcards) return DE_PATHNOTFND;
/* Append current path segment to result. */
*(bufp++) = '\\';
if (bufp >= bufend) break;
copylen = state = 0;
for (i=0; ( (i < seglen) && (bufp < bufend) ); i++) {
c = src[i];
gotAnyWildcards |= ( (c == '?') || (c == '*') );
switch (state) {
case 0: /* Copying filename (excl. extension) */
if (c == '*') {
while (copylen < FNAME_SIZE) {
*(bufp++) = '?';
if (bufp >= bufend) break;
copylen++;
}
copylen = 0;
state = 1; /* Go wait for dot */
break;
}
if (c == '.') {
*(bufp++) = '.';
copylen = 0;
state = 2; /* Copy extension next */
break;
}
*(bufp++) = c;
copylen++;
if (copylen >= FNAME_SIZE) {
copylen = 0;
state = 1; /* Go wait for dot */
break;
}
break;
case 1: /* Looking for dot so we can copy exten */
if (src[i] == '.') {
*(bufp++) = '.';
state = 2;
}
break;
case 2: /* Copying extension */
if (c == '*') {
while (copylen < FEXT_SIZE) {
*(bufp++) = '?';
if (bufp >= bufend) break;
copylen++;
}
i = seglen; /* Done with segment */
break;
}
if (c == '.') {
i = seglen; /* Done with segment */
break;
}
*(bufp++) = c;
copylen++;
if (copylen >= FEXT_SIZE) {
i = seglen; /* Done with segment */
break;
}
break;
}
}
}
}
} /* if (seglen > 0) */
src += seglen;
if (*src) src++;
} /* while ( (*src) && (bufp < bufend) ) */
}
/* /// End of new code. - Ron Cemer */
if (bufp == buf + 2)
++bufp;
@ -425,7 +585,7 @@ exit_tn:
*bufp++ = 0;
/* finally, uppercase everything */
upString(buf);
DosUpString(buf);
/* copy to user's buffer */
fbcopy(buf, dest, bufp - buf);

View File

@ -5,7 +5,7 @@
/* */
/* National Languge Support functions and data structures */
/* */
/* Copyright (c) 1995, 1996, 2000 */
/* Copyright (c) 2000 */
/* Steffen Kaiser */
/* All Rights Reserved */
/* */
@ -27,10 +27,16 @@
/* Cambridge, MA 02139, USA. */
/****************************************************************/
/*
* Note 1: Some code assume certains prerequisites to be matched,
* e.g. character tables exactly 128 bytes long; I try to keep\
* track of these conditions within comments marked with:
* ==ska*/
#include "portab.h"
#include "globals.h"
#include "intr.h"
#include "nls.h"
#include "pcb.h"
#include <nls.h>
#ifdef VERSION_STRINGS
static BYTE *RcsId = "$Id$";
@ -38,134 +44,173 @@ static BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.3 2000/05/25 20:56:21 jimtabor
* Fixed project history
* Revision 1.4 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.2 2000/05/08 04:30:00 jimtabor
* Update CVS to 2020
*
* Revision 1.1.1.1 2000/05/06 19:34:53 jhall1
* The FreeDOS Kernel. A DOS kernel that aims to be 100% compatible with
* MS-DOS. Distributed under the GNU GPL.
*
* Revision 1.8 2000/03/17 22:59:04 kernel
* Steffen Kaiser's NLS changes
* Revision 1.1 2000/03/23 02:44:21 ska
* Initial revision
*
*/
#ifdef NLS_REORDER_POINTERS
#define getTable2 (&nlsInfo.actPkg->nlsPointer[0].pointer)
#define getTable4 (&nlsInfo.actPkg->nlsPointer[1].pointer)
/*
* assertDSeqSS() - test if DS == SS
* Otherwise pointers to local variables (that ones on the stack) will
* be referenced via DS, which will cause to use wrong values.
*/
#ifdef NLS_DEBUG
#define assertDSeqSS() if(_DS != _SS) assertDSneSS();
void assertDSneSS(void)
{ panic("DS unequal to SS");
}
#define log(a) printf a
#define log1(a) printf a
#else
#define getTable2 getTable(2)
#define getTable4 getTable(4)
#define assertDSeqSS()
#define log(a)
#ifdef NDEBUG
#define log1(a)
#else
#define log1(a) printf a
#endif
#endif
struct nlsInfoBlock nlsInfo = {
(char FAR *)0 /* filename to COUNTRY.SYS */
,437 /* system code page */
/* Implementation flags */
,0
#ifdef NLS_MODIFYABLE_DATA
| NLS_CODE_MODIFYABLE_DATA
#endif
#ifdef NLS_REORDER_POINTERS
| NLS_CODE_REORDER_POINTERS
#endif
,&nlsPackageHardcoded /* hardcoded first package */
,&nlsPackageHardcoded /* first item in chain */
};
/* getTableX return the pointer to the X'th table; X==subfct */
/* subfct 2: normal upcase table; 4: filename upcase table */
#ifdef NLS_REORDER_POINTERS
#define getTable2(nls) ((nls)->nlsPointers[0].pointer)
#define getTable4(nls) ((nls)->nlsPointers[1].pointer)
#else
#define getTable2(nls) getTable(2, (nls))
#define getTable4(nls) getTable(4, (nls))
#define NEED_GET_TABLE
#endif
#ifdef NLS_CACHE_POINTERS
#define normalCh nlsInfo.upTable
#define fileCh nlsInfo.fnamUpTable
#else
#define normalCh getTable2
#define fileCh getTable4
#endif
#define yesChar nlsInfo.actPkg->yeschar
#define noChar nlsInfo.actPkg->nochar
/*== both chartables must be 128 bytes long and lower range is
identical to 7bit-US-ASCII ==ska*/
#define getCharTbl2(nls) \
(((struct nlsCharTbl FAR*)getTable2(nls))->tbl - 0x80)
#define getCharTbl4(nls) \
(((struct nlsCharTbl FAR*)getTable4(nls))->tbl - 0x80)
#define NLS_MUX_COUNTRY_INFO(nls) ((nls)->muxCallingFlags & NLS_FLAG_INFO)
#define NLS_MUX_POINTERS(nls) ((nls)->muxCallingFlags & NLS_FLAG_POINTERS)
#define NLS_MUX_YESNO(nls) ((nls)->muxCallingFlags & NLS_FLAG_YESNO)
#define NLS_MUX_EXTERNAL_UP(nls) ((nls)->muxCallingFlags & NLS_FLAG_UP)
#define NLS_MUX_EXTERNAL_FUP(nls) ((nls)->muxCallingFlags & NLS_FLAG_FUP)
/********************************************************************
***** MUX calling functions ****************************************
********************************************************************/
static COUNT muxGo(int subfct, struct REGPACK *rp)
{ rp->r_si = FP_OFF(&nlsInfo);
rp->r_ds = FP_SEG(&nlsInfo);
rp->r_ax = 0x1400 | subfct;
/*== DS:SI _always_ points to global NLS info structure <-> no
* subfct can use these registers for anything different. ==ska*/
static COUNT muxGo(int subfct, iregs *rp)
{
log( ("NLS: muxGo(): subfct=%x, cntry=%u, cp=%u, ES:DI=%04x:%04x\n", subfct
, rp->DX, rp->BX, rp->ES, rp->DI) );
rp->SI = FP_OFF(&nlsInfo);
rp->DS = FP_SEG(&nlsInfo);
rp->AX = 0x1400 | subfct;
intr(0x2f, rp);
return rp->r_ax;
log( ("NLS: muxGo(): return value = %d\n", rp->AX) );
return rp->AX;
}
/*
* Call NLSFUNC to load the NLS package
*/
COUNT muxLoadPkg(UWORD cp, UWORD cntry)
{ struct REGPACK r;
{ iregs r;
assertDSeqSS(); /* because "&r" */
/* Return the al register as sign extended: */
/* 0x1400 == not installed, ok to install */
/* 0x1401 == not installed, not ok to install */
/* 0x14FF == installed */
r.r_bx = 0; /* make sure the NLSFUNC ID is updated */
r.BX = 0; /* make sure the NLSFUNC ID is updated */
if(muxGo(0, &r) != 0x14ff)
return DE_FILENOTFND; /* No NLSFUNC --> no load */
if(r.r_bx != NLS_FREEDOS_NLSFUNC_ID)
return DE_INVLDACC;
if(r.BX != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */
return DE_INVLDACC; /* This magic number */
/* OK, the correct NLSFUNC is available --> load pkg */
r.r_dx = cntry;
r.r_bx = cp;
return muxGo(NLS_NLSFUNC_LOAD_PKG, &r);
/* If BX == -1 on entry, NLSFUNC updates BX to the codepage loaded
into memory. The system must then change to this one later */
r.DX = cntry;
r.BX = cp;
return muxGo(NLSFUNC_LOAD_PKG, &r);
}
static int muxBufGo(int subfct, int bp, UWORD cp, UWORD cntry, UWORD bufsize
, BYTE FAR *buf)
{ struct REGPACK r;
, VOID FAR *buf)
{ iregs r;
r.r_bx = cntry;
r.r_dx = cp;
r.r_es = FP_SEG(*buf);
r.r_di = FP_OFF(*buf);
r.r_cx = bufsize;
r.r_bp = bp;
assertDSeqSS(); /* because "&r" */
log( ("NLS: muxBufGo(): subfct=%x, BP=%u, cp=%u, cntry=%u, len=%u, buf=%04x:%04x\n",
subfct, bp, cp, cntry, bufsize, FP_SEG(buf), FP_OFF(buf)) );
r.DX = cntry;
r.BX = cp;
r.ES = FP_SEG(buf);
r.DI = FP_OFF(buf);
r.CX = bufsize;
r.BP = bp;
return muxGo(subfct, &r);
}
#define mux38(cp,cc,bs,b) muxBufGo(4, 0, (cp), (cc), (bs), (b))
#define mux65(s,cp,cc,bs,b) muxBufGo(2, (s), (cp), (cc), (bs), (b))
#define muxUpMem(s,l,f) muxBufGo((f), 0, NLS_DEFAULT, NLS_DEFAULT, l, s)
#define mux38(cp,cc,bs,b) muxBufGo(4, 0, (cp), (cc), (bs), (b))
#define muxYesNo(ch) muxBufGo(NLSFUNC_YESNO,0, NLS_DEFAULT, NLS_DEFAULT, (ch), 0)
#define muxUpMem(s,b,bs) muxBufGo((s),0, NLS_DEFAULT,NLS_DEFAULT, (bs), (b))
static int muxYesNo(int ch)
{ struct REGPACK r;
r.r_cx = ch;
return muxGo(NLS_NLSFUNC_YESNO, &r);
}
/********************************************************************
***** Helper functions**********************************************
********************************************************************/
/*
* Search the NLS package within the chain
* Also resolves the default values (-1) into the current
* Search for the NLS package within the chain
* Also resolves the default values (-1) into the currently
* active codepage/country code.
*/
struct nlsPackage FAR *searchPackage(UWORD *cp, UWORD *cntry)
static struct nlsPackage FAR *searchPackage(UWORD cp, UWORD cntry)
{ struct nlsPackage FAR *nls;
if(*cp == NLS_DEFAULT)
*cp = nlsInfo.actPkg->cntryInfo.codePage;
if(*cntry == NLS_DEFAULT)
*cntry = nlsInfo.actPkg->cntryInfo.countryCode;
if(cp == NLS_DEFAULT)
cp = nlsInfo.actPkg->cp;
if(cntry == NLS_DEFAULT)
cntry = nlsInfo.actPkg->cntry;
nls = &nlsInfo.chain;
while((nls->cntryInfo.codePage != *cp
|| nls->cntryInfo.countryCode != *cntry)
nls = nlsInfo.chain;
while((nls->cp != cp || nls->cntry != cntry)
&& (nls = nls->nxt) != NULL);
return nls;
}
struct nlsPointerInf FAR *locateSubfct(struct nlsPackage FAR *nls
, UBYTE subfct)
/* For various robustnesses reasons and to simplify the implementation
at other places, locateSubfct() returns NULL (== "not found"),
if nls == NULL on entry. */
static VOID FAR *locateSubfct(struct nlsPackage FAR *nls, int subfct)
{ int cnt;
struct nlsPointerInf FAR *p;
struct nlsPointer FAR *p;
for(cnt = nls->numSubfct, p = &nls->nlsPointer[0]
if(nls) for(cnt = nls->numSubfct, p = &nls->nlsPointers[0]
; cnt--; ++p)
if(p->subfct == subfct)
if(p->subfct == (UBYTE)subfct)
return p;
return NULL;
@ -173,18 +218,23 @@ struct nlsPointerInf FAR *locateSubfct(struct nlsPackage FAR *nls
#ifdef NEED_GET_TABLE
/* search the table (from a subfct) from the active package */
struct nlsPointerInf FAR *getTable(UBYTE subfct)
{ struct nlsPointerInf FAR *poi;
/* Note: Because this table returns the pointers for stuff of
*internal* purpose, it seems to be more comfortable that this
function is guaranteed to return valid pointers, rather than
to let the user (some kernel function) deal with non-existing
tables -- 2000/02/26 ska*/
static VOID FAR *getTable(UBYTE subfct, struct nlsPackage FAR *nls)
{ struct nlsPointer FAR *poi;
if((poi = locateSubfct(nlsInfo.actPkg, subfct)) != NULL)
if((poi = locateSubfct(nls, subfct)) != NULL)
return poi;
/* Failed --> return the hardcoded table */
switch(subfct) {
case 2: return &nlsUpHardcodedTable;
case 4: return &nlsFnameUpHardcodedTable;
case 5: return &nlsFnameTermHardcodedTable;
case 6: return &nlsCollHardcodedTable;
/* case 5: return &nlsFnameTermHardcodedTable; */
/* case 6: return &nlsCollHardcodedTable; */
}
}
#endif
@ -192,94 +242,312 @@ struct nlsPointerInf FAR *getTable(UBYTE subfct)
/*
* Copy a buffer and test the size of the buffer
* Returns SUCCESS on success; DE_INVLDFUNC on failure
*
* Efficiency note: This function is used as:
* return cpyBuf(buf, bufsize, ...)
* three times. If the code optimizer is some good, it can re-use
* the code to push bufsize, buf, call cpyBuf() and return its result.
* The parameter were ordered to allow this code optimization.
*/
static COUNT cpyBuf(UBYTE FAR *dst, UBYTE FAR *src
, UWORD srclen, UWORD dstlen)
static COUNT cpyBuf(VOID FAR *dst, UWORD dstlen
, VOID FAR *src, UWORD srclen)
{
if(srclen <= dstlen) {
_fmemcpy((BYTE FAR*)dst, (BYTE FAR*)src, srclen);
_fmemcpy(dst, src, srclen);
return SUCCESS;
}
return DE_INVLDFUNC; /* buffer too small */
}
/*
* This function assumes that 'map' is adjusted such that
* map[0x80] is the uppercase of character 0x80.
*== 128 byte chartables, lower range conform to 7bit-US-ASCII ==ska*/
static VOID upMMem(UBYTE FAR *map, UBYTE FAR * str, unsigned len)
{
REG unsigned c;
#ifdef NLS_DEBUG
UBYTE FAR *oldStr;
unsigned oldLen;
oldStr = str;
oldLen = len;
log( ("NLS: upMMem(): 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 (len)
do
{
if ((c = *str) >= 'a' && c <= 'z')
*str += 'A' - 'a';
else if (c > 0x7f)
*str = map[c];
++str;
}
while (--len);
#ifdef NLS_DEBUG
printf("NLS: upMMem(): result=\"");
for(c = 0; c < oldLen; ++c)
printf("%c", oldStr[c] > 32? oldStr[c]: '.');
printf("\"\n");
#endif
}
/********************************************************************
***** Lowlevel interface *******************************************
********************************************************************/
/* GetData function used by both the MUX-callback function and
the direct-access interface.
subfct == NLS_DOS_38 is a value > 0xff in order to not clash
with subfunctions valid to be passed as DOS-65-XX. */
static int nlsGetData(struct nlsPackage FAR *nls, int subfct, UBYTE FAR *buf
, unsigned bufsize)
{ VOID FAR *poi;
log( ("NLS: nlsGetData(): subfct=%x, bufsize=%u, cp=%u, cntry=%u\n",
subfct, bufsize, nls->cp, nls->cntry) );
/* Theoretically tables 1 and, if NLS_REORDER_POINTERS is enabled,
2 and 4 could be hard-coded, because their
data is located at predictable (calculatable) locations.
However, 1 and subfct NLS_DOS_38 are to handle the same
data and the "locateSubfct()" call has to be implemented anyway,
in order to handle all subfunctions.
Also, NLS is often NOT used in any case, so this code is more
size than speed optimized. */
if((poi = locateSubfct(nls, subfct)) != NULL) {
log( ("NLS: nlsGetData(): subfunction found\n") );
switch(subfct) {
case 1: /* Extended Country Information */
return cpyBuf(buf, bufsize, poi
, ((struct nlsExtCntryInfo FAR*)poi)->size + 3);
case NLS_DOS_38: /* Normal Country Information */
return cpyBuf(buf, bufsize
, &(((struct nlsExtCntryInfo FAR*)poi)->dateFmt)
, 34); /* standard cinfo has no more 34 _used_ bytes */
default:
/* All other subfunctions just return the found nlsPoinerInf
structure */
return cpyBuf(buf, bufsize, poi, sizeof(struct nlsPointer));
}
}
/* The requested subfunction could not been located within the
NLS pkg --> error. Because the data corresponds to the subfunction
number passed to the API, the failure is the same as that a wrong
API function has been called. */
log( ("NLS: nlsGetData(): Subfunction not found\n") );
return DE_INVLDFUNC;
}
VOID nlsCPchange(UWORD cp)
{ printf("\7\nSorry, to change the codepage is not implemented, yet.\n\
Hope it's OK to proceed ignoring this call.\n-- 2000/02/26 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)
{
assertDSeqSS(); /* because "&ch" */
log( ("NLS: nlsYesNo(): in ch=%u (%c)\n", ch, ch>32? ch: ' ') );
xUpMem(nls, &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 DosUpChar(unsigned char ch)
/* upcase a single character */
{
assertDSeqSS(); /* because "&ch" */
log( ("NLS: DosUpChar(): in ch=%u (%c)\n", ch, ch>32? ch: ' ') );
DosUpMem((UBYTE FAR*)&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 */
{
assertDSeqSS(); /* because "&ch" */
DosUpFMem((UBYTE FAR*)&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 extCtryInfo(int subfct, UWORD codepage
, UWORD cntry, UWORD bufsize, UBYTE FAR * buf)
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 */
int rc;
int muxOnCntryInfo, muxOnPointer;
struct nlsPointerInf FAR *poi;
if(!buf)
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(&codepage, &cntry)) == NULL)
/* requested NLS package is not loaded -->
pass the request to NLSFUNC */
muxOnCntryInfo = muxOnPointer = TRUE;
else {
muxOnCntryInfo = NLS_MUX_COUNTRY_INFO(nls);
muxOnPointer = NLS_MUX_POINTERS(nls);
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);
}
if(subfct == 1) { /* return Extended Country Information */
if(muxOnCntryInfo)
return mux65(1, codepage, cntry, bufsize, buf);
return cpyBuf(buf, (BYTE FAR*)&nls->cntryInfo
, nls->cntryInfo.size + 3, bufsize);
}
if(subfct == NLS_DOS_38) { /* return Country Information */
if(muxOnCntryInfo)
return mux38(codepage, cntry, bufsize, buf);
return cpyBuf(buf, (BYTE FAR*)&nls->cntryInfo.dateFmt
, nls->cntryInfo.size - 4, bufsize);
}
if(muxOnPointer)
return mux65(subfct, codepage, cntry, bufsize, buf);
/* any other subfunction returns a pointer to any sort
of data; the pointer is located within the nlsPointers
array */
if((poi = locateSubfct(nls, subfct)) != NULL)
return cpyBuf(buf, (UBYTE FAR *)poi
, sizeof(struct nlsPointerInf), bufsize);
return DE_INVLDFUNC;
/* Direct access to the data */
return nlsGetData(nls, subfct, buf, bufsize);
}
/*
* Changes the current active codepage or cntry
*/
static COUNT setPackage(UWORD cp, UWORD cntry)
{ struct nlsPackage FAR*nls; /* NLS package to use to return the info from */
int rc;
/* nls := NLS package of cntry/codepage */
if((nls = searchPackage(&cp, &cntry)) == NULL) {
/* not loaded --> invoke NLSFUNC to load it */
if((rc = muxLoadPkg(cp, cntry)) != SUCCESS)
return rc;
if((nls = searchPackage(&cp, &cntry)) == NULL)
/* something went wrong */
return DE_INVLDFUNC;
}
nlsInfo.actPkg = nls;
#ifdef NLS_CACHE_POINTERS
/* Fill the quick-access pointers */
nlsInfo.fnamUpTable = getTable4->pointer - 0x80;
nlsInfo.upTable = getTable2->pointer - 0x80;
#endif
return SUCCESS;
}
/*
* Called for DOS-38 get info
@ -288,121 +556,100 @@ static COUNT setPackage(UWORD cp, UWORD cntry)
* it is assumed the buffer is large enough as described in RBIL,
* which is 34 bytes _hardcoded_.
*/
COUNT getCountryInformation(UWORD cntry, BYTE FAR *buf)
{ return extCtryInfo(NLS_DOS_38, NLS_DEFAULT, cntry, 34, buf);
#ifndef DosGetCountryInformation
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR *buf)
{ return DosGetData(NLS_DOS_38, NLS_DEFAULT, cntry, 34, buf);
}
#endif
/*
* Called for DOS-38 set country code
*/
COUNT setCountryCode(UWORD cntry)
{ return setPackage(NLS_DEFAULT, cntry);
#ifndef DosSetCountry
COUNT DosSetCountry(UWORD cntry)
{ return DosSetPackage(NLS_DEFAULT, cntry);
}
#endif
/*
* Called for DOS-66-01 get CP
*/
COUNT getCodePage(UWORD FAR* actCP, UWORD FAR*sysCP)
COUNT DosGetCodepage(UWORD FAR* actCP, UWORD FAR* sysCP)
{ *sysCP = nlsInfo.sysCodePage;
*actCP = nlsInfo.actPkg->cntryInfo.codePage;
*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 setCodePage(UWORD actCP, UWORD sysCP)
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP)
{ if(sysCP == NLS_DEFAULT || sysCP == nlsInfo.sysCodePage)
return setPackage(actCP, NLS_DEFAULT);
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
static VOID upMMem(unsigned char FAR *map, unsigned char FAR * str
, unsigned len)
{
REG unsigned c;
Return value: AL register to be returned
if AL == 0, Carry must be cleared, otherwise set
*/
#pragma argsused
UWORD syscall_MUX14(DIRECT_IREGS)
{ struct nlsPackage FAR*nls; /* addressed NLS package */
if (len)
do
{
if ((c = *str) >= 'a' && c <= 'z')
*str += 'A' - 'a';
else if (c > 0x7f)
*str = map[c & 0x7f];
++str;
}
while (--len);
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");
}
BYTE yesNo(unsigned char ch)
/* returns: 0: ch == "No", 1: ch == "Yes", 2: ch crap */
{
if(NLS_MUX_YESNO(nlsInfo.actPkg))
return muxYesNo(ch);
ch = upChar(ch);
if (ch == noChar)
return 0;
if (ch == yesChar)
return 1;
return 2;
}
VOID upMem(unsigned char FAR * str, unsigned len)
/* upcase a memory area */
{
#ifndef NLS_CACHE_POINTERS
if(NLS_MUX_EXTERNAL_UP(nlsInfo.actPkg)) {
muxUpMem(str, len, NLS_NLSFUNC_UP);
return;
}
#endif
upMMem(normalCh, str, len);
}
unsigned char upChar(unsigned char ch)
/* upcase a single character */
{ unsigned char buf[1];
*buf = ch;
upMem((BYTE FAR*)buf, 1);
return *buf;
}
VOID upString(unsigned char FAR * str)
/* upcase a string */
{
upMem(str, fstrlen(str));
}
VOID upFMem(unsigned char FAR * str, unsigned len)
/* upcase a memory area for file names */
{
#ifndef NLS_CACHE_POINTERS
if(NLS_MUX_EXTERNAL_FUP(nlsInfo.actPkg)) {
muxUpMem(str, len, NLS_NLSFUNC_FUP);
return;
nlsFUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS;
}
#endif
upMMem(fileCh, str, len);
log( ("NLS: MUX14(): Invalid function %x\n", AL) );
return DE_INVLDFUNC; /* no such function */
}
unsigned char upFChar(unsigned char ch)
/* upcase a single character for file names */
{ unsigned char buf[1];
*buf = ch;
upFMem((BYTE FAR*)buf, 1);
return *buf;
}
VOID upFString(unsigned char FAR * str)
/* upcase a string for file names */
{
upFMem(str, fstrlen(str));
}

109
kernel/nls_hc.asm Normal file
View File

@ -0,0 +1,109 @@
; Hardcoded DOS-NLS information for country = 1, codepage = 437
; This is an automatically generated file!
; Any modifications will be lost!
; Prerequisites:
;; ==> Assuming that data of tables remains constant all the time
;; ==> Reordering tables 1, 2, 4 and 5
%include "segs.inc"
segment _DATA
GLOBAL _nlsPackageHardcoded
_nlsPackageHardcoded:
DB 000h, 000h, 000h, 000h, 001h, 000h, 0b5h, 001h
DB 00fh, 000h, 059h, 04eh, 006h, 000h
DB 002h
DW ?table2, SEG ?table2
DB 004h
DW ?table4, SEG ?table4
DB 005h
DW ?table5, SEG ?table5
DB 006h
DW ?table6, SEG ?table6
DB 007h
DW ?table7, SEG ?table7
GLOBAL _nlsCountryInfoHardcoded
_nlsCountryInfoHardcoded:
DB 001h
?table1:
DB 01ch, 000h, 001h, 000h, 0b5h, 001h, 000h, 000h
DB 024h, 000h, 000h, 000h, 000h, 02ch, 000h, 02eh
DB 000h, 02dh, 000h, 03ah, 000h, 000h, 002h, 000h
DB 0e8h, 058h, 000h, 000h, 02ch, 000h
GLOBAL _hcTablesStart
_hcTablesStart:
GLOBAL _nlsFUpcaseHardcoded
_nlsFUpcaseHardcoded:
?table4:
GLOBAL _nlsUpcaseHardcoded
_nlsUpcaseHardcoded:
?table2:
DB 080h, 000h, 080h, 09ah, 045h, 041h, 08eh, 041h
DB 08fh, 080h, 045h, 045h, 045h, 049h, 049h, 049h
DB 08eh, 08fh, 090h, 092h, 092h, 04fh, 099h, 04fh
DB 055h, 055h, 059h, 099h, 09ah, 09bh, 09ch, 09dh
DB 09eh, 09fh, 041h, 049h, 04fh, 055h, 0a5h, 0a5h
DB 0a6h, 0a7h, 0a8h, 0a9h, 0aah, 0abh, 0ach, 0adh
DB 0aeh, 0afh, 0b0h, 0b1h, 0b2h, 0b3h, 0b4h, 0b5h
DB 0b6h, 0b7h, 0b8h, 0b9h, 0bah, 0bbh, 0bch, 0bdh
DB 0beh, 0bfh, 0c0h, 0c1h, 0c2h, 0c3h, 0c4h, 0c5h
DB 0c6h, 0c7h, 0c8h, 0c9h, 0cah, 0cbh, 0cch, 0cdh
DB 0ceh, 0cfh, 0d0h, 0d1h, 0d2h, 0d3h, 0d4h, 0d5h
DB 0d6h, 0d7h, 0d8h, 0d9h, 0dah, 0dbh, 0dch, 0ddh
DB 0deh, 0dfh, 0e0h, 0e1h, 0e2h, 0e3h, 0e4h, 0e5h
DB 0e6h, 0e7h, 0e8h, 0e9h, 0eah, 0ebh, 0ech, 0edh
DB 0eeh, 0efh, 0f0h, 0f1h, 0f2h, 0f3h, 0f4h, 0f5h
DB 0f6h, 0f7h, 0f8h, 0f9h, 0fah, 0fbh, 0fch, 0fdh
DB 0feh, 0ffh
GLOBAL _nlsFnameTermHardcoded
_nlsFnameTermHardcoded:
?table5:
DB 016h, 000h, 08eh, 000h, 0ffh, 041h, 000h, 020h
DB 0eeh, 00eh, 02eh, 022h, 02fh, 05ch, 05bh, 05dh
DB 03ah, 07ch, 03ch, 03eh, 02bh, 03dh, 03bh, 02ch
GLOBAL _nlsCollHardcoded
_nlsCollHardcoded:
?table6:
DB 000h, 001h, 000h, 001h, 002h, 003h, 004h, 005h
DB 006h, 007h, 008h, 009h, 00ah, 00bh, 00ch, 00dh
DB 00eh, 00fh, 010h, 011h, 012h, 013h, 014h, 015h
DB 016h, 017h, 018h, 019h, 01ah, 01bh, 01ch, 01dh
DB 01eh, 01fh, 020h, 021h, 022h, 023h, 024h, 025h
DB 026h, 027h, 028h, 029h, 02ah, 02bh, 02ch, 02dh
DB 02eh, 02fh, 030h, 031h, 032h, 033h, 034h, 035h
DB 036h, 037h, 038h, 039h, 03ah, 03bh, 03ch, 03dh
DB 03eh, 03fh, 040h, 041h, 042h, 043h, 044h, 045h
DB 046h, 047h, 048h, 049h, 04ah, 04bh, 04ch, 04dh
DB 04eh, 04fh, 050h, 051h, 052h, 053h, 054h, 055h
DB 056h, 057h, 058h, 059h, 05ah, 05bh, 05ch, 05dh
DB 05eh, 05fh, 060h, 041h, 042h, 043h, 044h, 045h
DB 046h, 047h, 048h, 049h, 04ah, 04bh, 04ch, 04dh
DB 04eh, 04fh, 050h, 051h, 052h, 053h, 054h, 055h
DB 056h, 057h, 058h, 059h, 05ah, 07bh, 07ch, 07dh
DB 07eh, 07fh, 043h, 055h, 045h, 041h, 041h, 041h
DB 041h, 043h, 045h, 045h, 045h, 049h, 049h, 049h
DB 041h, 041h, 045h, 041h, 041h, 04fh, 04fh, 04fh
DB 055h, 055h, 059h, 04fh, 055h, 024h, 024h, 024h
DB 024h, 024h, 041h, 049h, 04fh, 055h, 04eh, 04eh
DB 0a6h, 0a7h, 03fh, 0a9h, 0aah, 0abh, 0ach, 021h
DB 022h, 022h, 0b0h, 0b1h, 0b2h, 0b3h, 0b4h, 0b5h
DB 0b6h, 0b7h, 0b8h, 0b9h, 0bah, 0bbh, 0bch, 0bdh
DB 0beh, 0bfh, 0c0h, 0c1h, 0c2h, 0c3h, 0c4h, 0c5h
DB 0c6h, 0c7h, 0c8h, 0c9h, 0cah, 0cbh, 0cch, 0cdh
DB 0ceh, 0cfh, 0d0h, 0d1h, 0d2h, 0d3h, 0d4h, 0d5h
DB 0d6h, 0d7h, 0d8h, 0d9h, 0dah, 0dbh, 0dch, 0ddh
DB 0deh, 0dfh, 0e0h, 053h, 0e2h, 0e3h, 0e4h, 0e5h
DB 0e6h, 0e7h, 0e8h, 0e9h, 0eah, 0ebh, 0ech, 0edh
DB 0eeh, 0efh, 0f0h, 0f1h, 0f2h, 0f3h, 0f4h, 0f5h
DB 0f6h, 0f7h, 0f8h, 0f9h, 0fah, 0fbh, 0fch, 0fdh
DB 0feh, 0ffh
GLOBAL _nlsDBCSHardcoded
_nlsDBCSHardcoded:
?table7:
DB 000h, 000h, 000h, 000h
GLOBAL _hcTablesEnd
_hcTablesEnd:
END

View File

@ -1,194 +0,0 @@
/****************************************************************/
/* */
/* nls_hc.c */
/* FreeDOS */
/* */
/* National Languge Support hardcoded NLS package */
/* */
/* Copyright (c) 2000 */
/* Steffen Kaiser */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* 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. */
/****************************************************************/
#include "portab.h"
#include "globals.h"
#define NLS_NO_VARS
#include "nls.h"
#undef NLS_NO_VARS
#define NLS_HARDCODED US
#define NLS_POINTERS 5
#define NLS_FNAMSEPS 14
#define NLS_DBCSENTR 1
#include "nls.h"
/*
* Hardcoded NLS package for U.S.A. CP437
*/
struct nlsCharTbl128 nlsUpHardcodedTable = {
128, /* upcase table */
{
'\x80' ,'\x9a' ,'E' ,'A' ,'\x8e' ,'A' ,'\x8f' ,'\x80' /* 0 - 7 */
,'E' ,'E' ,'E' ,'I' ,'I' ,'I' ,'\x8e' ,'\x8f' /* 8 - 15 */
,'\x90' ,'\x92' ,'\x92' ,'O' ,'\x99' ,'O' ,'U' ,'U' /* 16 - 23 */
,'Y' ,'\x99' ,'\x9a' ,'\x9b' ,'\x9c' ,'\x9d' ,'\x9e' ,'\x9f' /* 24 - 31 */
,'A' ,'I' ,'O' ,'U' ,'\xa5' ,'\xa5' ,'\xa6' ,'\xa7' /* 32 - 39 */
,'\xa8' ,'\xa9' ,'\xaa' ,'\xab' ,'\xac' ,'\xad' ,'\xae' ,'\xaf' /* 40 - 47 */
,'\xb0' ,'\xb1' ,'\xb2' ,'\xb3' ,'\xb4' ,'\xb5' ,'\xb6' ,'\xb7' /* 48 - 55 */
,'\xb8' ,'\xb9' ,'\xba' ,'\xbb' ,'\xbc' ,'\xbd' ,'\xbe' ,'\xbf' /* 56 - 63 */
,'\xc0' ,'\xc1' ,'\xc2' ,'\xc3' ,'\xc4' ,'\xc5' ,'\xc6' ,'\xc7' /* 64 - 71 */
,'\xc8' ,'\xc9' ,'\xca' ,'\xcb' ,'\xcc' ,'\xcd' ,'\xce' ,'\xcf' /* 72 - 79 */
,'\xd0' ,'\xd1' ,'\xd2' ,'\xd3' ,'\xd4' ,'\xd5' ,'\xd6' ,'\xd7' /* 80 - 87 */
,'\xd8' ,'\xd9' ,'\xda' ,'\xdb' ,'\xdc' ,'\xdd' ,'\xde' ,'\xdf' /* 88 - 95 */
,'\xe0' ,'\xe1' ,'\xe2' ,'\xe3' ,'\xe4' ,'\xe5' ,'\xe6' ,'\xe7' /* 96 - 103 */
,'\xe8' ,'\xe9' ,'\xea' ,'\xeb' ,'\xec' ,'\xed' ,'\xee' ,'\xef' /* 104 - 111 */
,'\xf0' ,'\xf1' ,'\xf2' ,'\xf3' ,'\xf4' ,'\xf5' ,'\xf6' ,'\xf7' /* 112 - 119 */
,'\xf8' ,'\xf9' ,'\xfa' ,'\xfb' ,'\xfc' ,'\xfd' ,'\xfe' ,'\xff' /* 120 - 127 */
}
};
struct nlsCharTbl128 nlsFnameUpHardcodedTable = {
128, /* file name upcase table */
{
'\x80' ,'\x9a' ,'E' ,'A' ,'\x8e' ,'A' ,'\x8f' ,'\x80' /* 0 - 7 */
,'E' ,'E' ,'E' ,'I' ,'I' ,'I' ,'\x8e' ,'\x8f' /* 8 - 15 */
,'\x90' ,'\x92' ,'\x92' ,'O' ,'\x99' ,'O' ,'U' ,'U' /* 16 - 23 */
,'Y' ,'\x99' ,'\x9a' ,'\x9b' ,'\x9c' ,'\x9d' ,'\x9e' ,'\x9f' /* 24 - 31 */
,'A' ,'I' ,'O' ,'U' ,'\xa5' ,'\xa5' ,'\xa6' ,'\xa7' /* 32 - 39 */
,'\xa8' ,'\xa9' ,'\xaa' ,'\xab' ,'\xac' ,'\xad' ,'\xae' ,'\xaf' /* 40 - 47 */
,'\xb0' ,'\xb1' ,'\xb2' ,'\xb3' ,'\xb4' ,'\xb5' ,'\xb6' ,'\xb7' /* 48 - 55 */
,'\xb8' ,'\xb9' ,'\xba' ,'\xbb' ,'\xbc' ,'\xbd' ,'\xbe' ,'\xbf' /* 56 - 63 */
,'\xc0' ,'\xc1' ,'\xc2' ,'\xc3' ,'\xc4' ,'\xc5' ,'\xc6' ,'\xc7' /* 64 - 71 */
,'\xc8' ,'\xc9' ,'\xca' ,'\xcb' ,'\xcc' ,'\xcd' ,'\xce' ,'\xcf' /* 72 - 79 */
,'\xd0' ,'\xd1' ,'\xd2' ,'\xd3' ,'\xd4' ,'\xd5' ,'\xd6' ,'\xd7' /* 80 - 87 */
,'\xd8' ,'\xd9' ,'\xda' ,'\xdb' ,'\xdc' ,'\xdd' ,'\xde' ,'\xdf' /* 88 - 95 */
,'\xe0' ,'\xe1' ,'\xe2' ,'\xe3' ,'\xe4' ,'\xe5' ,'\xe6' ,'\xe7' /* 96 - 103 */
,'\xe8' ,'\xe9' ,'\xea' ,'\xeb' ,'\xec' ,'\xed' ,'\xee' ,'\xef' /* 104 - 111 */
,'\xf0' ,'\xf1' ,'\xf2' ,'\xf3' ,'\xf4' ,'\xf5' ,'\xf6' ,'\xf7' /* 112 - 119 */
,'\xf8' ,'\xf9' ,'\xfa' ,'\xfb' ,'\xfc' ,'\xfd' ,'\xfe' ,'\xff' /* 120 - 127 */
}
};
struct nlsFnamTermUS nlsFnameTermHardcodedTable = {
22, /* size of permittable character structure */
1, /* reserved */
'\x00' ,'\xff', /* first/last permittable character */
0, /* reserved */
'\x00' ,' ', /* first/last excluded character */
2, /* reserved */
14, /* number of separators */
{ /* separators */
'.' ,'"' ,'/' ,'\\','[' ,']' ,':' ,'|', /* 0 - 7 */
'<' ,'>' ,'+' ,'=' ,';' ,',' /* 8 - 13 */
}
};
struct nlsCharTbl256 nlsCollHardcodedTable = {
256, /* collating sequence table */
{
'\x00' ,'\x01' ,'\x02' ,'\x03' ,'\x04' ,'\x05' ,'\x06' ,'\x07' /* 0 - 7 */
,'\x08' ,'\x09' ,'\x0a' ,'\x0b' ,'\x0c' ,'\x0d' ,'\x0e' ,'\x0f' /* 8 - 15 */
,'\x10' ,'\x11' ,'\x12' ,'\x13' ,'\x14' ,'\x15' ,'\x16' ,'\x17' /* 16 - 23 */
,'\x18' ,'\x19' ,'\x1a' ,'\x1b' ,'\x1c' ,'\x1d' ,'\x1e' ,'\x1f' /* 24 - 31 */
,' ' ,'!' ,'"' ,'#' ,'$' ,'%' ,'&' ,'\'' /* 32 - 39 */
,'(' ,')' ,'*' ,'+' ,',' ,'-' ,'.' ,'/' /* 40 - 47 */
,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' /* 48 - 55 */
,'8' ,'9' ,':' ,';' ,'<' ,'=' ,'>' ,'?' /* 56 - 63 */
,'@' ,'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' /* 64 - 71 */
,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' /* 72 - 79 */
,'P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' /* 80 - 87 */
,'X' ,'Y' ,'Z' ,'[' ,'\\',']' ,'^' ,'_' /* 88 - 95 */
,'`' ,'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' /* 96 - 103 */
,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' /* 104 - 111 */
,'P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' /* 112 - 119 */
,'X' ,'Y' ,'Z' ,'{' ,'|' ,'}' ,'~' ,'\x7f' /* 120 - 127 */
,'C' ,'U' ,'E' ,'A' ,'A' ,'A' ,'A' ,'C' /* 128 - 135 */
,'E' ,'E' ,'E' ,'I' ,'I' ,'I' ,'A' ,'A' /* 136 - 143 */
,'E' ,'A' ,'A' ,'O' ,'O' ,'O' ,'U' ,'U' /* 144 - 151 */
,'Y' ,'O' ,'U' ,'$' ,'$' ,'$' ,'$' ,'$' /* 152 - 159 */
,'A' ,'I' ,'O' ,'U' ,'N' ,'N' ,'\xa6' ,'\xa7' /* 160 - 167 */
,'?' ,'\xa9' ,'\xaa' ,'\xab' ,'\xac' ,'!' ,'"' ,'"' /* 168 - 175 */
,'\xb0' ,'\xb1' ,'\xb2' ,'\xb3' ,'\xb4' ,'\xb5' ,'\xb6' ,'\xb7' /* 176 - 183 */
,'\xb8' ,'\xb9' ,'\xba' ,'\xbb' ,'\xbc' ,'\xbd' ,'\xbe' ,'\xbf' /* 184 - 191 */
,'\xc0' ,'\xc1' ,'\xc2' ,'\xc3' ,'\xc4' ,'\xc5' ,'\xc6' ,'\xc7' /* 192 - 199 */
,'\xc8' ,'\xc9' ,'\xca' ,'\xcb' ,'\xcc' ,'\xcd' ,'\xce' ,'\xcf' /* 200 - 207 */
,'\xd0' ,'\xd1' ,'\xd2' ,'\xd3' ,'\xd4' ,'\xd5' ,'\xd6' ,'\xd7' /* 208 - 215 */
,'\xd8' ,'\xd9' ,'\xda' ,'\xdb' ,'\xdc' ,'\xdd' ,'\xde' ,'\xdf' /* 216 - 223 */
,'\xe0' ,'S' ,'\xe2' ,'\xe3' ,'\xe4' ,'\xe5' ,'\xe6' ,'\xe7' /* 224 - 231 */
,'\xe8' ,'\xe9' ,'\xea' ,'\xeb' ,'\xec' ,'\xed' ,'\xee' ,'\xef' /* 232 - 239 */
,'\xf0' ,'\xf1' ,'\xf2' ,'\xf3' ,'\xf4' ,'\xf5' ,'\xf6' ,'\xf7' /* 240 - 247 */
,'\xf8' ,'\xf9' ,'\xfa' ,'\xfb' ,'\xfc' ,'\xfd' ,'\xfe' ,'\xff' /* 248 - 255 */
}
};
struct nlsDBCSUS nlsDBCSHardcodedTable = {
0, /* no DBC support */
0, /* DBC end marker */
};
struct nlsInfoBlockUS nlsInfo = {
(char FAR*)NULL /*fname*/
,437 /*sysCodePage*/
,(struct nlsPackage FAR*)&nlsInfo.chain /* actPkg */
#ifdef NLS_CACHE_DATA
,(struct nlsCharTbl FAR*)&nlsFnameUpHardcodedTable
,(struct nlsCharTbl FAR*)&nlsUpHardcodedTable
#endif
, /* hardcoded nlsPackageUS */ {
(struct nlsPackage FAR*)NULL /* nxt */
,0 /* MUX calling flags */
, /* Extended Country Information */ {
1, /* subfct */
0x26, /* size */
1, /* country code */
437, /* code page */
0, /* date format */
{
/* currency string */
'$','\x00','\x00','\x00','\x00', /* 0 - 4 */
},
{ /* thousand separator */
',' ,'\x00' /* 0 - 1 */
},
{ /* decimal point */
'.' ,'\x00' /* 0 - 1 */
},
{ /* date separator */
'-' ,'\x00' /* 0 - 1 */
},
{ /* time separator */
':' ,'\x00' /* 0 - 1 */
},
0, /* currency format */
2, /* currency prescision */
0, /* time format */
CharMapSrvc, /* upcase function */
{ /* data separator */
',','\x00' /* 0 - 1 */
}
}
, 'Y', 'N' /* yes / no */
, 5 /* num of subfunctions */
, /* subfunctions */ {
{ 2, (VOID FAR*)&nlsUpHardcodedTable } /* #0 */
, { 4, (VOID FAR*)&nlsFnameUpHardcodedTable } /* #1 */
, { 5, (VOID FAR*)&nlsFnameTermHardcodedTable } /* #2 */
, { 6, (VOID FAR*)&nlsCollHardcodedTable } /* #3 */
, { 7, (VOID FAR*)&nlsDBCSHardcodedTable } /* #4 */
}
}
};

388
kernel/nls_load.c Normal file
View File

@ -0,0 +1,388 @@
/****************************************************************/
/* */
/* nls_load.c */
/* FreeDOS */
/* */
/* National Languge Support functions and data structures */
/* Load an entry from FreeDOS COUNTRY.SYS file. */
/* */
/* 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. */
/****************************************************************/
#include "portab.h"
#include "globals.h"
//#include "pcb.h"
#include <nls.h>
#ifdef VERSION_STRINGS
static BYTE *RcsId = "$Id$";
#endif
/*
* $Log$
* Revision 1.1 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
*/
#define filename Config.cfgCSYS_fnam
#define cntry Config.cfgCSYS_cntry
#define cp Config.cfgCSYS_cp
static int err(void)
{
printf("Syntax error in or invalid COUNTRY.SYS: \"%s\"\n"
, filename);
return 0;
}
#define readStruct(s) readStructure(&(s), sizeof(s), fd)
static int readStructure(void *buf, int size, COUNT fd)
{ if(dos_read(fd, buf, size) == size)
return 1;
return err();
}
/* Evaluate each argument only once */
#define readFct(p,f) readFct_((p), (f), fd)
int readFct_(void *buf, struct csys_function *fct, COUNT fd)
{ if(dos_lseek(fd, fct->csys_rpos, 0) >= 0)
return readStructure(buf, fct->csys_length, fd);
return err();
}
#define seek(n) rseek((LONG)(n), fd)
static rseek(LONG rpos, COUNT fd)
{ if(dos_lseek(fd, rpos, 1) >= 0)
return 1;
return err();
}
COUNT csysOpen(void)
{ COUNT fd;
struct nlsCSys_fileHeader header;
if((fd = dos_open((BYTE FAR*)filename, 0)) < 0) {
printf("Cannot open: \"%s\"\n", filename);
return 1;
}
if(dos_read(fd, &header, sizeof(header)) != sizeof(header);
|| strcmp(header.csys_idstring, CSYS_FD_IDSTRING) != 0
|| dos_lseek(fd, (LONG)sizeof(csys_completeFileHeader), 0)
!= (LONG)sizeof(csys_completeFileHeader)) {
printf("No valid COUNTRY.SYS: \"%s\"\n\nTry NLSFUNC /i %s\n"
, filename, filename);
dos_close(fd);
return -1;
}
return fd;
}
/* Searches for function definition of table #fctID and
moves it at index idx */
static int chkTable(int idx, int fctID, struct csys_function *fcts
, int numFct)
{ struct csys_function *fct, hfct;
int i;
for(i = 0, fct = fcts; i < numFct; ++i, ++fct)
if(fct->csys_fctID == fctID) {
/* function found */
if(i == idx) /* already best place */
return 1;
/* Swap both places */
memcpy(&hfct, fct, sizeof(hfct));
memcpy(fct, &fcts[idx], sizeof(hfct));
memcpy(&fcts[idx], &hfct, sizeof(hfct));
return 1;
}
printf("Mandatory table %u not found.\n", fctID);
return 0;
}
/*
* Description of the algorithm the COUNTRY= information is loaded.
1) LoadCountry() is activated in pass 1, because it offers the functionality
how to upcase characters to the kernel, it should be activated as
soon as possible within processing CONFIG.SYS.
2) The method to locate the actual data within COUNTRY.SYS is pretty
basic and straight forward; so no detailed description here.
3) To reduce permanent memory useage the option NLS_MODIFYABLE_DATA
controls whether or not the loaded NLS pkg may be modified. By default,
modifying this data is _not_ supported.
The reason is to allow to re-use already loaded data, e.g. to use the
same physical table for #2 (normal upcase) and #4 (filename upcase).
NLSFUNC even can re-use the data loaded via COUNTRY= and the hardcoded data.
4) The problem is that even without point 3) it is not easily possible to
pre-judge how many bytes the NLS pkg will allocate in memory, because
this NLS implementation wants to support a wider range of NLS pkgs; because
neither the number of subfunctions nor the size of the data per subfunction
is fixed globally.
Therefore, the package is built-up incrementally:
4.1) First all function definition structures (S3) are read into memory.
While doing so the position field is transformed into the absolute
position within COUNTRY.SYS.
4.2) Then they are checked if a subfunction is defined more than once.
4.3) Then the entries are sorted in that way that tables 0x23, 1, 2, 4 and 5
lead the table in that order.
4.4) Then the basic nlsPackage with as many entries within nlsPointers[]
is allocated as there are function definitions left (minus one as the
pseudo-table 0x23 does not require an entry).
4.5) Pseudo-table 0x23 is installed.
4.6) Table 1 is installed at the very end of the nlsPointers[] array.
4.7) In the order all remaining function definitions are installed in
the same order as in the other array.
5) "Installing" means (except table 0x23):
5.1) Enlarge the nlsPackage structure to hold the necessary bytes of the
function definition (member csys_length).
5.2) Only if NLS_MODIFYABLE_DATA is _not_ defined and table is not #1:
The loaded data is compared to already loaded data and if such pattern is
already found in memory, a pointer to that memory area is used and the
loaded data is discarded.
First the local data is searched through, then the area of the hardcoded
NLS pkg.
Efficiency: function definitions with the same file position can automatically
use the same memory area.
6) When all function definitions are loaded, the nlsPackage structure is
tightly filled without any pad bytes; two areas are wasted:
a) The area containing the S3 structures, and
b) probably the last loaded data could be found within the memory already,
so the nlsPackage structure is larger than necessary.
8) But the memory allocation in pass 1 is temporary anyway, because in
the PostConfig() phase, all memory allocations are revoked and created
anew. At this point -- immediately after revoking all memory and
_before_ allocating any new memory -- the NLS pkg is located completely
within memory and one knows exactly which bytes to spare, and which data
can share the same physical memory; but if the normal PostConfig()
process would go on, this information would be lost, because it could be
overwritten.
==> Therefore the almost first operation within PostConfig() is to
move the NLS pkg upto the top (base?) of memory, thus, making sure
it is not overwritten and one need not re-load all the structures from
memory and, by doing so, loose the information which memory can be shared.
9) Once this operation has been completed, the NLS pkg is joined into the
nlsInfo chain of loaded packages and is made active.
===
To ease implementation the value of FP_SEG(nlsPointers[].pointer) != 0,
if the pointer refers to an absolute place, whereas FP_SEG() == 0,
indicates that the FP_OFF(...) is the offset base-relative to the data
offset; which is base-relative to the "nls" pointer.
*/
int csysLoadPackage(COUNT fd)
{ struct csys_numEntries entries;
struct csys_ccDefinition entry;
struct csys_function *fcts;
struct nlsPackage *nls;
struct nlsPointer *poi;
int highmark, numFct, i, j;
int totalSize;
#ifndef NLS_MODIFYABLE_DATA
BYTE FAR * p;
#endif
#define numE entries.csys_entries
#define bufp(offset) (((BYTE*)nls) + (offset))
#define fct fcts[numFct]
/* When this function is called, the position of the file is
at offset 128 (number of country/codepage pairs) */
if(!readStruct(entries))
return 0;
while(numE--) {
if(!readStruct(entry))
return 0;
if(entry.csys_cntry == cntry
&& (cp == NLS_DEFAULT || entry.csys_cp == cp)) {
/* Requested entry found! */
if(!seek(entry.csys_rpos)
|| !readStruct(entries))
return 0;
/* Now reading the function definitions at this position */
if(numE < 5) {
printf("Syntax error in COUNTRY.SYS: Too few subfunctions\n");
return 0;
}
/* If the file structure is good, each but one entry (0x23) is
one item within nlsPointers[] array */
fcts = KernelAlloc(sizeof(struct csys_function) * numE);
numFct = 0; /* number of already loaded fct definition */
totalSize = 0;
{
if(!readStruct(fct))
return 0;
switch(fct.csys_fctID) {
case 0: case 0x20: case 0x21: case 0x22:
case 0xA0: case 0xA1: case 0xA2:
printf("Invalid subfunction %u ignored", fct.csys_fctID);
continue;
case 0x23:
if(fct.csys_length != 2) {
printf("Pseudo-table 35 length mismatch\n");
continue;
}
}
/* Search if the subfunction is already there */
for(j = 0; j < numFcts && fcts[j].csys_fctID != fct.csys_fctID
; ++j);
if(j != numFct) {
printf("Subfunction %u defined multiple times, ignored\n"
, fct.csys_fctID);
continue;
}
/* OK --> update the rpos member */
fct.csys_rpos += dos_ltell(fd);
totalSize += fct.csys_length;
++numFct;
} while(--numE);
/* i is the number of available function definition */
/* check if all mandatory tables are loaded, at the same
time re-order the function definitions like that:
0x23, 1, 2, 4, 5
*/
/* That's automatically a check that more than 3 definitions
are available */
if(!chkTable(0, 0x23, fcts, numFct) /* pseudo-table 0x23 yes/no */
|| !chkTable(1, 1, fcts, numFct) /* ext cntry info */
|| !chkTable(2, 2, fcts, numFct) /* normal upcase */
|| !chkTable(3, 4, fcts, numFct) /* filename upcase */
|| !chkTable(4, 5, fcts, numFct)) /* filename terminator chars */
return 0;
/* Begin the loading process by to allocate memory as if
we had to load every byte */
/* One nlsPointers structure is already part of nlsPackage;
two function definitions need no nlsPointers entry (0x32, 1);
one additional byte is required by table 1, but which is
already within totalSize as the length of pseudo-table
0x23 has been counted. */
nls = KernelAlloc((data = sizeof(nlsPackage)
+ (numFct - 3) * sizeof(struct nlsPointer)) + totalSize);
/* data := first byte not used by the control area of
the nlsPackage structure; at this point it is the
offset where table #1 is to be loaded to*/
/* Install pseudo-table 0x23 */
if(!readFct((BYTE*)&nls->yeschar, fcts))
return 0;
nls->numSubfct = numFct - 1; /* pseudo-table 0x23 */
/* Install table #1 has it must overlay the last nlsPointers[]
item */
*bufp(data) = 1; /* table #1 starts with the subfctID
then the data from the file follows */
if(!readFct(bufp(++data), ++fcts))
return 0;
data += fcts->csys_length; /* first byte of local data area */
highmark = data; /* first unused byte */
for(j = 0, poi = nls->nlsPointers; j < numFct - 1; ++j, ++poi) {
/* consecutively load all functions */
if(!readFct(bufp(data), ++fcts))
return 0;
poi->subfct = fcts->csys_fctID;
/* Now the function data is located at the current top of
used memory and, if allowed, the other memory is
tested, if such image is already loaded */
#ifndef NLS_MODIFYABLE_DATA
/* Try to locate the contents of the buffer */
/** brute force **/
/* For the standard tables one need to match tables
2 and 4 only. */
for(i = data; i + fcts->csys_length < highmark; ++i) {
if(memcmp(bufp(i), bufp(highmark), fcts->csys_length)
== 0) {
/* found! */
/* ==> leave highmark untouch, but modify pointer */
poi->pointer = MK_FP(0, i);
/* the segment portion == 0 identifies this pointer
as local within the current data area */
goto nxtEntry;
}
}
/* Now try the hardcoded area */
for(p = hcTablesStart; p < hcTablesEnd - fcts->csys_length
; ++p) {
if(fmemcmp(p, bufp(highmark), fcts->csys_length) == 0) {
/* found! */
/* ==> leave highmark untouch, but modify pointer */
poi->pointer = p;
/* the segment portion != 0 identifies this is an
absolute pointer */
goto nxtEntry;
}
}
#endif
/* Either not found or modifyable data allowed */
poi->pointer = MK_FP(0, highmark); /* local address */
highmark += fcts->csys_length; /* need to keep the data */
nxtEntry:
}
/* how many memory is really required */
Country.cfgCSYS_memory = highmark;
Country.cfgCSYS_data = nls;
return 1;
}
}
#undef numE
if(cp == NLS_DEFAULT)
printf("No definition of country ID %u in file \"%s\"\n",
cntry, filename);
else
printf("No definition of country ID %u for codepage %u in file \"%s\"\n",
cntry, cp, filename);
return 0;
}
INIT BOOL LoadCountryInfo(char *fnam)
{ COUNT fd;
int rc;
if(strlen(fnam) < sizeof(filename)) {
strcpy(filename, fnam);
if((fd = csysOpen()) >= 0) {
rc = csysLoadPackage(fd);
dos_close(fd);
return rc;
}
} else
printf("Filename too long\n");
return 0;
}

View File

@ -29,6 +29,9 @@
; $Id$
;
; $Log$
; Revision 1.4 2000/08/06 05:50:17 jimtabor
; Add new files and update cvs with patches and changes
;
; Revision 1.3 2000/05/25 20:56:21 jimtabor
; Fixed project history
;
@ -95,10 +98,10 @@ _CharMapSrvc:
push cx
push bx
mov dx, DGROUP
mov ds, dx
push ax ; arg of _upChar
mov ax, DGROUP
mov ds, ax
push ax
call _upChar
;add sp, byte 2 // next POP retrieves orig AX

View File

@ -34,8 +34,8 @@ static BYTE *Proto_hRcsId = "$Id$";
/*
* $Log$
* Revision 1.5 2000/06/21 18:16:46 jimtabor
* Add UMB code, patch, and code fixes
* Revision 1.6 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.4 2000/05/26 19:25:19 jimtabor
* Read History file for Change info
@ -374,6 +374,7 @@ COUNT DosMemCheck(void);
COUNT FreeProcessMem(UWORD ps);
COUNT DosGetLargestBlock(UWORD FAR * block);
VOID show_chain(void);
VOID DosUmbLink(BYTE n);
VOID mcb_print(mcb FAR * mcbp);
VOID _fmemcpy(BYTE FAR * d, BYTE FAR * s, REG COUNT n);
@ -385,19 +386,26 @@ VOID bcopy(REG BYTE * s, REG BYTE * d, REG COUNT n);
__FAR_WRAPPER(VOID, fbcopy, (REG VOID FAR * s, REG VOID FAR * d, REG COUNT n))
/* nls.c */
COUNT extCtryInfo(int subfct, UWORD codepage,
UWORD cntry, UWORD bufsize, UBYTE FAR * buf);
BYTE yesNo(unsigned char ch);
unsigned char upChar(unsigned char ch);
VOID upString(unsigned char FAR * str);
VOID upMem(unsigned char FAR * str, unsigned len);
unsigned char upFChar(unsigned char ch);
VOID upFString(unsigned char FAR * str);
VOID upFMem(unsigned char FAR * str, unsigned len);
COUNT setCountryCode(UWORD cntry);
COUNT getCountryInformation(UWORD cntry, BYTE FAR *buf);
COUNT getCodePage(UWORD FAR* actCP, UWORD FAR*sysCP);
COUNT setCodePage(UWORD actCP, UWORD sysCP);
BYTE DosYesNo(unsigned char ch);
#ifndef DosUpMem
VOID DosUpMem(VOID FAR * str, unsigned len);
#endif
unsigned char DosUpChar(unsigned char ch);
VOID DosUpString(char FAR *str);
VOID DosUpFMem(VOID FAR *str, unsigned len);
unsigned char DosUpFChar(unsigned char ch);
VOID DosUpFString(char FAR *str);
COUNT DosGetData(int subfct, UWORD cp, UWORD cntry
, UWORD bufsize, VOID FAR * buf);
#ifndef DosGetCountryInformation
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR *buf);
#endif
#ifndef DosSetCountry
COUNT DosSetCountry(UWORD cntry);
#endif
COUNT DosGetCodepage(UWORD FAR* actCP, UWORD FAR* sysCP);
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
UWORD syscall_MUX14(DIRECT_IREGS);
/* prf.c */
VOID put_console(COUNT c);
@ -460,6 +468,8 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t);
COUNT int2f_Remote_call(UWORD func, UWORD b, UCOUNT n, UWORD d, VOID FAR * s, UWORD i, VOID FAR * data);
COUNT QRemote_Fn(char FAR * s, char FAR * d);
COUNT FAR Umb_Test(void);
UWORD get_machine_name(BYTE FAR * netname);
VOID set_machine_name(BYTE FAR * netname, UWORD name_num);
UCOUNT Remote_RW(UWORD func, UCOUNT n, BYTE FAR * bp, sft FAR * s, COUNT FAR * err);
@ -467,6 +477,9 @@ COUNT Remote_find(UWORD func, BYTE FAR * name, REG dmatch FAR * dmp);
/* procsupt.asm */
VOID INRPT FAR exec_user(iregs FAR * irp);
#define strcpy(d, s) scopy(s, d)
/* detect.c */
unsigned long FAR is_dosemu(void);
#define strcpy(d, s) scopy(s, d)

View File

@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.5 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.4 2000/05/26 19:25:19 jimtabor
* Read History file for Change info
*
@ -661,8 +664,14 @@ static COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
/* + long2para((LONG) sizeof(psp)); ?? -- 1999/04/21 ska */
if (exe_size > asize)
exe_size = asize;
}
/* /// Removed closing curly brace. We should not attempt to allocate
memory if we are overlaying the current process, because the new
process will simply re-use the block we already have allocated.
This was causing execl() to fail in applications which use it to
overlay (replace) the current exe file with a new one.
Jun 11, 2000 - rbc
} */
/* Allocate our memory and pass back any errors */
/* We can still get an error on first fit if the above */
/* returned size was a bet fit case */
@ -694,6 +703,18 @@ static COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
else
/* with no error, we got exactly what we asked for */
asize = exe_size;
/* /// Added open curly brace and "else" clause. We should not attempt
to allocate memory if we are overlaying the current process, because
the new process will simply re-use the block we already have allocated.
This was causing execl() to fail in applications which use it to
overlay (replace) the current exe file with a new one.
Jun 11, 2000 - rbc */
}
else
asize = exe_size;
/* /// End of additions. Jun 11, 2000 - rbc */
if (mode != OVERLAY)
{
/* memory found large enough - continue processing */

View File

@ -27,6 +27,9 @@
***************************************************************/
/* $Log$
* Revision 1.4 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
* Revision 1.3 2000/05/25 20:56:23 jimtabor
* Fixed project history
*