mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
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:
parent
52ba720063
commit
0fddf1f848
@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
135
kernel/config.c
135
kernel/config.c
@ -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
38
kernel/config.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
;
|
||||
|
126
kernel/int2f.asm
126
kernel/int2f.asm
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
725
kernel/nls.c
725
kernel/nls.c
@ -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
109
kernel/nls_hc.asm
Normal 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
|
194
kernel/nls_hc.c
194
kernel/nls_hc.c
@ -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
388
kernel/nls_load.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user