COUNTRY.SYS & NLSFUNC support added: Lucho, Eduardo.
32RTM and BRUN45 incompatibilities fixed by Michael. ZIP drive serial numbers now work: bug fix by Lucho. Small clean-ups and optimisations by Lucho & Arkady. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1023 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
31a4275854
commit
a6b468389b
@ -1,3 +1 @@
|
||||
@echo off
|
||||
echo Welcome to FreeDOS (http://www.freedos.org)!
|
||||
path=a:\
|
||||
@echo Welcome to FreeDOS (http://www.freedos.org)!
|
||||
|
@ -1,5 +1 @@
|
||||
rem dos=high
|
||||
rem device=fdxms.sys (or himem.sys)
|
||||
files=20
|
||||
buffers=20
|
||||
rem screen=0x12
|
||||
;
|
||||
|
@ -30,6 +30,13 @@
|
||||
; |BOOT SEC|
|
||||
; |RELOCATE|
|
||||
; |--------| 1FE0:7C00
|
||||
; |LBA PKT |
|
||||
; |--------| 1FE0:7BC0
|
||||
; |--------| 1FE0:7BA0
|
||||
; |BS STACK|
|
||||
; |--------|
|
||||
; |4KBRDBUF| used to avoid crossing 64KB DMA boundary
|
||||
; |--------| 1FE0:63A0
|
||||
; | |
|
||||
; |--------| 1FE0:3000
|
||||
; | CLUSTER|
|
||||
@ -95,24 +102,24 @@ Entry: jmp short real_start
|
||||
|
||||
times 0x3E-$+$$ db 0
|
||||
|
||||
%define loadsegoff_60 bp+loadseg_off-Entry
|
||||
%define loadseg_60 bp+loadseg_seg-Entry
|
||||
; using bp-Entry+loadseg_xxx generates smaller code than using just
|
||||
; loadseg_xxx, where bp is initialized to Entry, so bp-Entry equals 0
|
||||
%define loadsegoff_60 bp-Entry+loadseg_off
|
||||
%define loadseg_60 bp-Entry+loadseg_seg
|
||||
|
||||
;%define LBA_PACKET bp+0x42
|
||||
; db 10h ; size of packet
|
||||
; db 0 ; const
|
||||
; dw 1 ; number of sectors to read
|
||||
%define LBA_PACKET bp-0x40
|
||||
%define LBA_SIZE word [LBA_PACKET]
|
||||
%define LBA_SECNUM word [LBA_PACKET+2]
|
||||
%define LBA_OFF LBA_PACKET+4
|
||||
%define LBA_SIZE word [LBA_PACKET] ; size of packet, should be 10h
|
||||
%define LBA_SECNUM word [LBA_PACKET+2] ; number of sectors to read
|
||||
%define LBA_OFF LBA_PACKET+4 ; buffer to read/write to
|
||||
%define LBA_SEG LBA_PACKET+6
|
||||
%define LBA_SECTOR_0 word [LBA_PACKET+8 ]
|
||||
%define LBA_SECTOR_0 word [LBA_PACKET+8 ] ; LBA starting sector #
|
||||
%define LBA_SECTOR_16 word [LBA_PACKET+10]
|
||||
%define LBA_SECTOR_32 word [LBA_PACKET+12]
|
||||
%define LBA_SECTOR_48 word [LBA_PACKET+14]
|
||||
|
||||
|
||||
%define READBUF 0x63A0 ; max 4KB buffer (min 2KB stack), == stacktop-0x1800
|
||||
%define READADDR_OFF BP-0x60-0x1804 ; pointer within user buffer
|
||||
%define READADDR_SEG BP-0x60-0x1802
|
||||
|
||||
%define PARAMS LBA_PACKET+0x10
|
||||
%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
|
||||
@ -133,7 +140,7 @@ real_start:
|
||||
cld
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov bp, 0x7c00
|
||||
mov bp, BASE
|
||||
|
||||
|
||||
; a reset should not be needed here
|
||||
@ -171,6 +178,8 @@ dont_use_dl: ; no, rely on [drive] written by SYS
|
||||
|
||||
mov LBA_SIZE, 10h
|
||||
mov LBA_SECNUM,1 ; initialise LBA packet constants
|
||||
mov word [LBA_SEG],ds
|
||||
mov word [LBA_OFF],READBUF
|
||||
|
||||
|
||||
; GETDRIVEPARMS: Calculate start of some disk areas.
|
||||
@ -223,7 +232,7 @@ dont_use_dl: ; no, rely on [drive] written by SYS
|
||||
mov di, word [RootDirSecs]
|
||||
les bx, [loadsegoff_60] ; es:bx = 60:0
|
||||
call readDisk
|
||||
les di, [loadsegoff_60] ; es:di = 60:0
|
||||
les di, [loadsegoff_60] ; es:di = 60:0
|
||||
|
||||
|
||||
; Search for KERNEL.SYS file name, and find start cluster.
|
||||
@ -356,7 +365,8 @@ show: pop si
|
||||
ret
|
||||
|
||||
boot_error: call show
|
||||
db "Error! Hit a key to reboot."
|
||||
; db "Error! Hit a key to reboot."
|
||||
db "Err."
|
||||
|
||||
xor ah,ah
|
||||
int 0x13 ; reset floppy
|
||||
@ -377,8 +387,8 @@ readDisk: push si
|
||||
|
||||
mov LBA_SECTOR_0,ax
|
||||
mov LBA_SECTOR_16,dx
|
||||
mov word [LBA_SEG],es
|
||||
mov word [LBA_OFF],bx
|
||||
mov word [READADDR_SEG], es
|
||||
mov word [READADDR_OFF], bx
|
||||
|
||||
call show
|
||||
db "."
|
||||
@ -409,7 +419,7 @@ read_next:
|
||||
lea si,[LBA_PACKET]
|
||||
|
||||
; setup LBA disk block
|
||||
mov LBA_SECTOR_32,bx
|
||||
mov LBA_SECTOR_32,bx ; bx is 0 if extended 13h mode supported
|
||||
mov LBA_SECTOR_48,bx
|
||||
|
||||
mov ah,042h
|
||||
@ -459,22 +469,33 @@ read_normal_BIOS:
|
||||
or cl, ah ; merge sector into cylinder
|
||||
inc cx ; make sector 1-based (1-63)
|
||||
|
||||
les bx,[LBA_OFF]
|
||||
les bx,[LBA_OFF]
|
||||
mov ax, 0x0201
|
||||
do_int13_read:
|
||||
mov dl, [drive]
|
||||
int 0x13
|
||||
jc boot_error ; exit on error
|
||||
mov ax, word [bsBytesPerSec]
|
||||
div byte[LBA_PACKET] ; luckily 16 !!
|
||||
add word [LBA_SEG], ax
|
||||
|
||||
mov ax, word [bsBytesPerSec]
|
||||
|
||||
push di
|
||||
mov si,READBUF ; copy read in sector data to
|
||||
les di,[READADDR_OFF] ; user provided buffer
|
||||
mov cx, ax
|
||||
; shr cx, 1 ; convert bytes to word count
|
||||
; rep movsw
|
||||
rep movsb
|
||||
pop di
|
||||
|
||||
shr ax, 4 ; adjust segment pointer by increasing
|
||||
add word [READADDR_SEG], ax ; by paragraphs read in (per sector)
|
||||
|
||||
add LBA_SECTOR_0, byte 1
|
||||
adc LBA_SECTOR_16, byte 0 ; DX:AX = next sector to read
|
||||
dec di ; if there is anything left to read,
|
||||
jnz read_next ; continue
|
||||
|
||||
mov es,word [LBA_SEG]
|
||||
les bx, [READADDR_OFF]
|
||||
; clear carry: unnecessary since adc clears it
|
||||
pop si
|
||||
ret
|
||||
@ -484,3 +505,32 @@ do_int13_read:
|
||||
filename db "KERNEL SYS",0,0
|
||||
|
||||
sign dw 0xAA55
|
||||
|
||||
%ifdef DBGPRNNUM
|
||||
; DEBUG print hex digit routines
|
||||
PrintLowNibble: ; Prints low nibble of AL, AX is destroyed
|
||||
and AL, 0Fh ; ignore upper nibble
|
||||
cmp AL, 09h ; if greater than 9, then don't base on '0', base on 'A'
|
||||
jbe .printme
|
||||
add AL, 7 ; convert to character A-F
|
||||
.printme:
|
||||
add AL, '0' ; convert to character 0-9
|
||||
mov AH,0x0E ; show character
|
||||
int 0x10 ; via "TTY" mode
|
||||
retn
|
||||
PrintAL: ; Prints AL, AX is preserved
|
||||
push AX ; store value so we can process a nibble at a time
|
||||
shr AL, 4 ; move upper nibble into lower nibble
|
||||
call PrintLowNibble
|
||||
pop AX ; restore for other nibble
|
||||
push AX ; but save so we can restore original AX
|
||||
call PrintLowNibble
|
||||
pop AX ; restore for other nibble
|
||||
retn
|
||||
PrintNumber: ; Prints (in Hex) value in AX, AX is preserved
|
||||
xchg AH, AL ; high byte 1st
|
||||
call PrintAL
|
||||
xchg AH, AL ; now low byte
|
||||
call PrintAL
|
||||
retn
|
||||
%endif
|
||||
|
@ -4,10 +4,13 @@ please email the current kernel maintainer so we can add you to the list!
|
||||
|
||||
Thanks to all the following for contributing to the FreeDOS kernel:
|
||||
|
||||
Aitor Santamaria (aitor.sm@wanadoo.es)
|
||||
Arkady Belousov (ark@mos.ru)
|
||||
Bart Oldeman (bart@dosemu.org)
|
||||
Bernd Blaauw (bblaauw@home.nl)
|
||||
Brian Reifsnyder (reifsnyderb@mindspring.com)
|
||||
Charles Dye (raster@highfiber.com)
|
||||
Eduardo Casino (eduardo@terra.es)
|
||||
Eric Auer (eric@coli.uni-sb.de)
|
||||
Eric Biederman (ebiederm+eric@ccr.net)
|
||||
Eric Luttmann (ecl@users.sourceforge.net)
|
||||
|
@ -277,6 +277,7 @@
|
||||
* inthndlr.c
|
||||
- fix: INT21/3301 now returns in DL low bit of input value (as in MS-DOS).
|
||||
- callerARG1 declared as xreg instead UWORD.
|
||||
* fcbfns.c: FatGetDrvData() and FcbParseFname() optimised
|
||||
+ Changes Bernd, Aitor, & Arkady
|
||||
* config.c
|
||||
- source: (Bernd) the codepage table rewritten into a smaller layout.
|
||||
@ -285,6 +286,8 @@
|
||||
* exeflat.c
|
||||
- fix: eliminated warning by explicit cast.
|
||||
- reduced trailer, added to UPXed kernel.
|
||||
- allow processing of files with 0 relocations
|
||||
- UPX trailer no longer depends on load segment
|
||||
* segs.inc
|
||||
- fix: for MSVC CONST segment should be class CONST, not DATA.
|
||||
* dsk.c
|
||||
@ -293,15 +296,46 @@
|
||||
- optimize and make more user friendly instead of retrying endlessly
|
||||
* sys.c
|
||||
- change OEM Name field to FRDOS4.1 per Eric Auer for better compatibility.
|
||||
- added fat32readwrite int return type, now required by OpenWatcom 1.3
|
||||
* ludivmul.inc
|
||||
- 32-bit division code for 386-enabled Watcom kernel.
|
||||
* inthndlr.c
|
||||
- fix: for INT21/5F07 and 5F08, before changing bit CDSPHYSDRV,
|
||||
MS-DOS checks if physical device associated with drive letter. Without
|
||||
this check MS-FORMAT under FreeDOS was destroys RAMDISK.
|
||||
- zero serial number of Int 21h/30h (else buggy 32RTM thrashed stack)
|
||||
- set AX = ES after Int 21h/4Ah (undocumented but expected by BRUN45)
|
||||
(the last 2 changes needed to fix bugs discovered by Michael Devore)
|
||||
- added Int 2Fh/2Fh processing to set DOS version as per MS-DOS 4.0
|
||||
* autoexec.bat now single-line for FreeCOM compatibility when EOL=LF
|
||||
* config.sys: all commands removed as they were close to defaults
|
||||
* contrib.txt: added Aitor Santamaria, Bernd Blaauw and Eduardo Casino
|
||||
* country.asm / country.sys support now replaces hard-coded data
|
||||
* 8 countries added to country.asm: GR, RO, AT, KR, TR, IN, M.East, IL
|
||||
* dyninit.c: unused function DynFree() commented out
|
||||
* fattab.c: ISFAT32 function removed (now macro), "wasfree" optimised
|
||||
* globals.h: __TIME__ removed - no two kernels released on same day
|
||||
* intr.asm: lseek() added (necessary for COUNTRY.SYS processing)
|
||||
* ioctl.c:
|
||||
- r_si/r_di contents added as documented in PC-DOS Technical Update
|
||||
- r_unit now set to dpb_subunit (allows ZIP disk serial number)
|
||||
* main.c:
|
||||
- copyright message cleanup, now shows URL for the full GNU GPL text
|
||||
- (with Bart) LoL pointer made const (saves some size for Watcom)
|
||||
- InitializeAllBPBs() kludge removed (no longer needed - verified)
|
||||
- revision sequence now initialised along with DOS version in LoL
|
||||
- CheckContinueBootFromHardDisk() function code and text cleaned up
|
||||
* makefile: object files reordered to gain ~300B packed size
|
||||
* portab.h: pragma aux default to gain ~800B unpacked size (Watcom)
|
||||
(the last 2 changes proposed by Bart Oldeman)
|
||||
+ Changes Eduardo
|
||||
* inthndlr.c: added Int 2Fh/26-29h processing for NLSFUNC (with Lucho)
|
||||
* nls.c: MuxLoadPkg(), MuxGo() functions modified for NLSFUNC
|
||||
+ Changes Jeremy
|
||||
* config.txt
|
||||
- update to include all CONFIG.SYS options (except ANYDOS)
|
||||
* exeflat.c
|
||||
- show usage also when number of arguments incorrect
|
||||
*** Sync - Stable Build 2035 ***
|
||||
|
||||
2004 May 30 - Build 2035
|
||||
|
1
filelist
1
filelist
@ -77,6 +77,7 @@
|
||||
*/*/kernel/config.c
|
||||
*/*/kernel/config.h
|
||||
*/*/kernel/console.asm
|
||||
*/*/kernel/country.asm
|
||||
*/*/kernel/dosfns.c
|
||||
*/*/kernel/dosidle.asm
|
||||
*/*/kernel/dosnames.c
|
||||
|
@ -374,7 +374,8 @@ typedef struct {
|
||||
struct {
|
||||
UBYTE _r_cat; /* Category code */
|
||||
UBYTE _r_fun; /* Function code */
|
||||
UBYTE unused[4]; /* SI or DI contents or DS:reqhdr */
|
||||
UWORD _r_si; /* Contents of SI and DI */
|
||||
UWORD _r_di; /* (PC DOS 7 Technical Update, pp 104,105) */
|
||||
union
|
||||
{
|
||||
struct gblkio FAR *_r_io;
|
||||
@ -424,6 +425,8 @@ typedef struct {
|
||||
/* generic IOCTL and IOCTL query macros */
|
||||
#define r_cat _r_x._r_gen._r_cat
|
||||
#define r_fun _r_x._r_gen._r_fun
|
||||
#define r_si _r_x._r_gen._r_si
|
||||
#define r_di _r_x._r_gen._r_di
|
||||
#define r_rw _r_x._r_gen._r_par._r_rw
|
||||
#define r_io _r_x._r_gen._r_par._r_io
|
||||
#define r_fv _r_x._r_gen._r_par._r_fv
|
||||
|
@ -123,6 +123,10 @@ unsigned short getSS(void);
|
||||
#pragma aux getSS = "mov dx,ss" value [dx] modify exact[dx];
|
||||
/* enable Possible loss of precision warning for compatibility with Borland */
|
||||
#pragma enable_message(130)
|
||||
#if !defined(FORSYS) && !defined(EXEFLAT)
|
||||
#pragma aux default parm [ax dx cx] modify [ax dx es fs] /* min.unpacked size */
|
||||
/* #pragma aux default parm [ax dx] modify [ax bx cx dx es fs]min.packed size */
|
||||
#endif
|
||||
|
||||
#if _M_IX86 >= 300 || defined(M_I386)
|
||||
#define I386
|
||||
|
190
kernel/config.c
190
kernel/config.c
@ -1152,38 +1152,103 @@ STATIC void Fcbs(PCStr p)
|
||||
* matching the specified code page and country code, and loads
|
||||
* the corresponding information into memory. If code page is 0,
|
||||
* the default code page for the country will be used.
|
||||
*
|
||||
* Returns TRUE if successful, FALSE if not.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
STATIC void LoadCountryInfo(CStr filename, int ccode, int cpage)
|
||||
{
|
||||
say("Sorry, the COUNTRY= statement has been temporarily disabled\n");
|
||||
/* COUNTRY.SYS file data structures - see RBIL tables 2619-2622 */
|
||||
|
||||
UNREFERENCED_PARAMETER(cpage);
|
||||
UNREFERENCED_PARAMETER(ccode);
|
||||
UNREFERENCED_PARAMETER(filename);
|
||||
struct { /* file header */
|
||||
char name[8]; /* "\377COUNTRY.SYS" */
|
||||
char reserved[11];
|
||||
ULONG offset; /* offset of first entry in file */
|
||||
} header;
|
||||
struct { /* entry */
|
||||
int length; /* length of entry, not counting this word, = 12 */
|
||||
int country; /* country ID */
|
||||
int codepage; /* codepage ID */
|
||||
int reserved[2];
|
||||
ULONG offset; /* offset of country-subfunction-header in file */
|
||||
} entry;
|
||||
struct { /* subfunction header */
|
||||
int length; /* length of entry, not counting this word, = 6 */
|
||||
int id; /* subfunction ID */
|
||||
ULONG offset; /* offset within file of subfunction data entry */
|
||||
} subf_hdr;
|
||||
struct { /* subfunction data */
|
||||
char signature[8]; /* \377CTYINFO|UCASE|LCASE|FUCASE|FCHAR|COLLATE|DBCS */
|
||||
int length; /* length of following table in bytes */
|
||||
} subf_data;
|
||||
struct CountrySpecificInfo country;
|
||||
int fd, entries, count, i, j;
|
||||
|
||||
return FALSE;
|
||||
if ((fd = open(filename, 0)) < 0)
|
||||
{
|
||||
printf("%s not found\n", filename);
|
||||
return;
|
||||
}
|
||||
if (read(fd, &header, sizeof(header)) < sizeof(header))
|
||||
{
|
||||
printf("Can't read %s\n", filename);
|
||||
goto ret;
|
||||
}
|
||||
if (memcmp(&header.name, "\377COUNTRY", 8))
|
||||
{
|
||||
err:printf("%s has invalid format\n", filename);
|
||||
goto ret;
|
||||
}
|
||||
if (lseek(fd, header.offset) == 0xffffffffL
|
||||
|| read(fd, &entries, sizeof(entries)) < sizeof(entries))
|
||||
goto err;
|
||||
for (i = 0; i < entries; i++)
|
||||
{
|
||||
if (read(fd, &entry, sizeof(entry)) < sizeof(entry) || entry.length != 12)
|
||||
goto err;
|
||||
if (entry.country != ccode || entry.codepage != cpage && cpage)
|
||||
continue;
|
||||
if (lseek(fd, entry.offset) == 0xffffffffL
|
||||
|| read(fd, &count, sizeof(count)) < sizeof(count))
|
||||
goto err;
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
if (read(fd, &subf_hdr, sizeof(subf_hdr)) < sizeof(subf_hdr)
|
||||
|| subf_hdr.length != 6)
|
||||
goto err;
|
||||
if (subf_hdr.id != 1)
|
||||
continue;
|
||||
if (lseek(fd, subf_hdr.offset) == 0xffffffffL
|
||||
|| read(fd, &subf_data, sizeof(subf_data)) < sizeof(subf_data)
|
||||
|| memcmp(&subf_data.signature, "\377CTYINFO", 8))
|
||||
goto err;
|
||||
if (read(fd, &country, sizeof(country)) < sizeof(country))
|
||||
goto err;
|
||||
if (country.CountryID != entry.country
|
||||
|| country.CodePage != entry.codepage && cpage)
|
||||
continue;
|
||||
i = nlsCountryInfoHardcoded.C.CodePage;
|
||||
fmemcpy(&nlsCountryInfoHardcoded.C, &country,
|
||||
min(sizeof(country), subf_data.length));
|
||||
nlsCountryInfoHardcoded.C.CodePage = i;
|
||||
goto ret;
|
||||
}
|
||||
}
|
||||
printf("couldn't find country info for country ID %u\n", ccode);
|
||||
ret:
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Format: COUNTRY [=] countryCode [, [codePage] [, filename]] */
|
||||
STATIC void Country(PCStr p)
|
||||
{
|
||||
int ccode;
|
||||
/*PCStr filename = "";*/
|
||||
PCStr filename = "\\COUNTRY.SYS";
|
||||
|
||||
p = GetNumArg(p);
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
ccode = numarg;
|
||||
/* currently 'implemented' COUNTRY=nnn only */
|
||||
|
||||
#if 0
|
||||
numarg = NLS_DEFAULT;
|
||||
numarg = 0;
|
||||
p = skipwh(p);
|
||||
if (*p == ',')
|
||||
{
|
||||
@ -1204,9 +1269,8 @@ STATIC void Country(PCStr p)
|
||||
CfgFailure(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
LoadCountryInfoHardCoded(/*filename*/"", ccode, /*numarg*/NLS_DEFAULT);
|
||||
LoadCountryInfo(filename, ccode, numarg);
|
||||
}
|
||||
|
||||
/* Format: STACKS [=] stacks [, stackSize] */
|
||||
@ -1937,100 +2001,6 @@ STATIC void CfgMenuColor(PCStr p)
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
National specific things.
|
||||
this handles only Date/Time/Currency, and NOT codepage things.
|
||||
Some may consider this a hack, but I like to see 24 Hour support. tom.
|
||||
*********************************************************************************/
|
||||
|
||||
#define _DATE_MDY 0 /* mm/dd/yy */
|
||||
#define _DATE_DMY 1 /* dd.mm.yy */
|
||||
#define _DATE_YMD 2 /* yy/mm/dd */
|
||||
|
||||
#define _TIME_12 0
|
||||
#define _TIME_24 1
|
||||
|
||||
struct CountrySpecificInfo specificCountriesSupported[] = {
|
||||
|
||||
/* table rewritten by Bernd Blaauw
|
||||
Country ID : international numbering
|
||||
Codepage : codepage to use by default
|
||||
Date format : M = Month, D = Day, Y = Year (4digit); 0=USA, 1=Europe, 2=Japan
|
||||
Currency : $ = dollar, EUR = EURO (ALT-128), United Kingdom uses the pound sign
|
||||
Thousands : separator for thousands (1,000,000 bytes; Dutch: 1.000.000 bytes)
|
||||
Decimals : separator for decimals (2.5KB; Dutch: 2,5KB)
|
||||
Datesep : Date separator (2/4/2004 or 2-4-2004 for example)
|
||||
Timesep : usually ":" is used to separate hours, minutes and seconds
|
||||
Currencyf : Currency format (bit array)
|
||||
Currencyp : Currency precision
|
||||
Timeformat : 0=12 hour format (AM/PM), 1=24 hour format (16:12 means 4:12 PM)
|
||||
|
||||
ID CP Date currency 1000 0.1 date time C digit time Locale/Country contributor
|
||||
------------------------------------------------------------------------------------------------------------- */
|
||||
{ 1,437,_DATE_MDY,"$" ,",",".", "/", ":", 0 , 2,_TIME_12}, /* United States */
|
||||
{ 2,863,_DATE_YMD,"$" ,",",".", "-", ":", 0 , 2,_TIME_24}, /* Canadian French */
|
||||
{ 3,850,_DATE_MDY,"$" ,",",".", "/", ":", 0 , 2,_TIME_12}, /* Latin America */
|
||||
{ 7,866,_DATE_DMY,"RUB" ," ",",", ".", ":", 3 , 2,_TIME_24}, /* Russia Arkady V. Belousov */
|
||||
{ 31,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Dutch Bart Oldeman */
|
||||
{ 32,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Belgium */
|
||||
{ 33,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* France */
|
||||
{ 34,850,_DATE_DMY,"EUR" ,".","'", "-", ":", 0 , 2,_TIME_24}, /* Spain Aitor Santamaria Merino */
|
||||
{ 36,850,_DATE_DMY,"$HU" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Hungary */
|
||||
{ 38,850,_DATE_DMY,"$YU" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Yugoslavia */
|
||||
{ 39,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Italy */
|
||||
{ 41,850,_DATE_DMY,"SF" ,".",",", ".", ":", 0 , 2,_TIME_24}, /* Switserland */
|
||||
{ 42,850,_DATE_YMD,"$YU" ,".",",", ".", ":", 0 , 2,_TIME_24}, /* Czech & Slovakia */
|
||||
{ 44,850,_DATE_DMY,"\x9c" ,".",",", "/", ":", 0 , 2,_TIME_24}, /* United Kingdom */
|
||||
{ 45,850,_DATE_DMY,"DKK" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Denmark */
|
||||
{ 46,850,_DATE_YMD,"SEK" ,",",".", "-", ":", 0 , 2,_TIME_24}, /* Sweden */
|
||||
{ 47,850,_DATE_DMY,"NOK" ,",",".", ".", ":", 0 , 2,_TIME_24}, /* Norway */
|
||||
{ 48,850,_DATE_YMD,"PLN" ,",",".", ".", ":", 0 , 2,_TIME_24}, /* Poland Michael H.Tyc */
|
||||
{ 49,850,_DATE_DMY,"EUR" ,".",",", ".", ":", 1 , 2,_TIME_24}, /* German Tom Ehlert */
|
||||
{ 54,850,_DATE_DMY,"$ar" ,".",",", "/", ":", 1 , 2,_TIME_12}, /* Argentina */
|
||||
{ 55,850,_DATE_DMY,"$ar" ,".",",", "/", ":", 1 , 2,_TIME_24}, /* Brazil */
|
||||
{ 61,850,_DATE_MDY,"$" ,".",",", "/", ":", 0 , 2,_TIME_24}, /* Int. English */
|
||||
{ 81,932,_DATE_YMD,"\x81\x8f",",",".", "/", ":", 0 , 2,_TIME_12}, /* Japan Yuki Mitsui */
|
||||
{351,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Portugal */
|
||||
{358,850,_DATE_DMY,"EUR" ," ",",", ".", ":",0x3, 2,_TIME_24}, /* Finland wolf */
|
||||
{359,855,_DATE_DMY,"BGL" ," ",",", ".", ":", 3 , 2,_TIME_24}, /* Bulgaria Luchezar Georgiev */
|
||||
{380,848,_DATE_DMY,"UAH" ," ",",", ".", ":", 3 , 2,_TIME_24}, /* Ukraine Oleg Deribas */
|
||||
};
|
||||
|
||||
STATIC void LoadCountryInfoHardCoded(CStr filename, int ccode, int cpage)
|
||||
{
|
||||
struct CountrySpecificInfo *country;
|
||||
UNREFERENCED_PARAMETER(cpage);
|
||||
UNREFERENCED_PARAMETER(filename);
|
||||
|
||||
/* printf("cntry: %u, CP%u, file=\"%s\"\n", ccode, cpage, filename); */
|
||||
|
||||
for (country = specificCountriesSupported;
|
||||
country < ENDOF(specificCountriesSupported);
|
||||
country++)
|
||||
{
|
||||
if (country->CountryID == ccode)
|
||||
{
|
||||
int codepagesaved = nlsCountryInfoHardcoded.C.CodePage;
|
||||
fmemcpy(&nlsCountryInfoHardcoded.C,
|
||||
country,
|
||||
min(nlsCountryInfoHardcoded.TableSize, sizeof *country));
|
||||
nlsCountryInfoHardcoded.C.CodePage = codepagesaved;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("could not find country info for country ID %u\n"
|
||||
"current supported countries are ", ccode);
|
||||
|
||||
for (country = specificCountriesSupported;
|
||||
country < ENDOF(specificCountriesSupported);
|
||||
country++)
|
||||
{
|
||||
printf("%u ", country->CountryID);
|
||||
}
|
||||
say("\n");
|
||||
}
|
||||
|
||||
/* ****************************************************************
|
||||
** implementation of INSTALL=NANSI.COM /P /X /BLA
|
||||
*/
|
||||
|
402
kernel/country.asm
Normal file
402
kernel/country.asm
Normal file
@ -0,0 +1,402 @@
|
||||
; A rudimentary COUNTRY.SYS for FreeDOS
|
||||
; Handles only Date/Time/Currency, and NOT codepage things [yet]
|
||||
; Compatible with COUNTRY.SYS of MS-DOS, PC-DOS, PTS-DOS, OS/2, Win9x, WinNT
|
||||
; File format described in RBIL tables 2619-2622
|
||||
;
|
||||
; Created as a kernel table by Tom Ehlert
|
||||
; Reformatted and commented by Bernd Blaauw
|
||||
; Separated from the kernel by Luchezar Georgiev
|
||||
; Amended by many contributors (see names below)
|
||||
|
||||
; file header
|
||||
|
||||
db 0FFh,"COUNTRY",0,0,0,0,0,0,0,0,1,0,1 ; reserved and undocumented values
|
||||
dd ent ; first entry
|
||||
ent dw 35; number of entries - don't forget to update when adding a new country
|
||||
|
||||
; entries
|
||||
; (size, country, codepage, reserved(2), offset)
|
||||
|
||||
__us dw 12, 1,437,0,0
|
||||
dd _us
|
||||
__ca dw 12, 2,863,0,0
|
||||
dd _ca
|
||||
__la dw 12, 3,850,0,0
|
||||
dd _la
|
||||
__ru dw 12, 7,866,0,0
|
||||
dd _ru
|
||||
__gr dw 12, 30,869,0,0
|
||||
dd _gr
|
||||
__nl dw 12, 31,850,0,0
|
||||
dd _nl
|
||||
__be dw 12, 32,850,0,0
|
||||
dd _be
|
||||
__fr dw 12, 33,850,0,0
|
||||
dd _fr
|
||||
__es dw 12, 34,850,0,0
|
||||
dd _es
|
||||
__hu dw 12, 36,852,0,0
|
||||
dd _hu
|
||||
__yu dw 12, 38,852,0,0
|
||||
dd _yu
|
||||
__it dw 12, 39,850,0,0
|
||||
dd _it
|
||||
__ro dw 12, 40,852,0,0
|
||||
dd _ro
|
||||
__ch dw 12, 41,850,0,0
|
||||
dd _ch
|
||||
__cz dw 12, 42,852,0,0
|
||||
dd _cz
|
||||
__at dw 12, 43,850,0,0
|
||||
dd _at
|
||||
__uk dw 12, 44,850,0,0
|
||||
dd _uk
|
||||
__dk dw 12, 45,865,0,0
|
||||
dd _dk
|
||||
__se dw 12, 46,850,0,0
|
||||
dd _se
|
||||
__no dw 12, 47,865,0,0
|
||||
dd _no
|
||||
__pl dw 12, 48,852,0,0
|
||||
dd _pl
|
||||
__de dw 12, 49,850,0,0
|
||||
dd _de
|
||||
__ar dw 12, 54,850,0,0
|
||||
dd _ar
|
||||
__br dw 12, 55,850,0,0
|
||||
dd _br
|
||||
__au dw 12, 61,437,0,0
|
||||
dd _au
|
||||
__jp dw 12, 81,932,0,0
|
||||
dd _jp
|
||||
__kr dw 12, 82,934,0,0
|
||||
dd _kr
|
||||
__tk dw 12, 90,850,0,0
|
||||
dd _tk
|
||||
__in dw 12, 91,437,0,0
|
||||
dd _in
|
||||
__pt dw 12,351,860,0,0
|
||||
dd _pt
|
||||
__fi dw 12,358,850,0,0
|
||||
dd _fi
|
||||
__bg dw 12,359,855,0,0
|
||||
dd _bg
|
||||
__ua dw 12,380,848,0,0
|
||||
dd _ua
|
||||
__me dw 12,785,864,0,0
|
||||
dd _me
|
||||
__il dw 12,972,862,0,0
|
||||
dd _me
|
||||
|
||||
; subfunction headers (so far only for subfunction 1, "CTYINFO")
|
||||
; (count, size, id, offset)
|
||||
; add ofher subfunctions after each one
|
||||
|
||||
_us dw 1,6,1
|
||||
dd us
|
||||
_ca dw 1,6,1
|
||||
dd ca
|
||||
_la dw 1,6,1
|
||||
dd la
|
||||
_ru dw 1,6,1
|
||||
dd ru
|
||||
_gr dw 1,6,1
|
||||
dd gr
|
||||
_nl dw 1,6,1
|
||||
dd nl
|
||||
_be dw 1,6,1
|
||||
dd be
|
||||
_fr dw 1,6,1
|
||||
dd fr
|
||||
_es dw 1,6,1
|
||||
dd sn
|
||||
_hu dw 1,6,1
|
||||
dd hu
|
||||
_yu dw 1,6,1
|
||||
dd yu
|
||||
_it dw 1,6,1
|
||||
dd it
|
||||
_ro dw 1,6,1
|
||||
dd ro
|
||||
_ch dw 1,6,1
|
||||
dd sw
|
||||
_cz dw 1,6,1
|
||||
dd cz
|
||||
_at dw 1,6,1
|
||||
dd as
|
||||
_uk dw 1,6,1
|
||||
dd uk
|
||||
_dk dw 1,6,1
|
||||
dd dk
|
||||
_se dw 1,6,1
|
||||
dd se
|
||||
_no dw 1,6,1
|
||||
dd no
|
||||
_pl dw 1,6,1
|
||||
dd pl
|
||||
_de dw 1,6,1
|
||||
dd de
|
||||
_ar dw 1,6,1
|
||||
dd ar
|
||||
_br dw 1,6,1
|
||||
dd br
|
||||
_au dw 1,6,1
|
||||
dd au
|
||||
_jp dw 1,6,1
|
||||
dd np
|
||||
_kr dw 1,6,1
|
||||
dd kr
|
||||
_tk dw 1,6,1
|
||||
dd tk
|
||||
_in dw 1,6,1
|
||||
dd ia
|
||||
_pt dw 1,6,1
|
||||
dd pt
|
||||
_fi dw 1,6,1
|
||||
dd fi
|
||||
_bg dw 1,6,1
|
||||
dd bg
|
||||
_ua dw 1,6,1
|
||||
dd ua
|
||||
_me dw 1,6,1
|
||||
dd me
|
||||
_il dw 1,6,1
|
||||
dd me
|
||||
|
||||
%define MDY 0 ; month/day/year
|
||||
%define DMY 1 ; day/month/year
|
||||
%define YMD 2 ; year/month/day
|
||||
|
||||
%define _12 0 ; time as AM/PM
|
||||
%define _24 1 ; 24-hour format
|
||||
|
||||
; Country ID : international numbering
|
||||
; Codepage : codepage to use by default
|
||||
; Date format : M = Month, D = Day, Y = Year (4digit); 0=USA, 1=Europe, 2=Japan
|
||||
; Currency : $ = dollar, EUR = EURO (ALT-128), UK uses the pound sign
|
||||
; Thousands : separator for 1000s (1,000,000 bytes; Dutch: 1.000.000 bytes)
|
||||
; Decimals : separator for decimals (2.5 KB; Dutch: 2,5 KB)
|
||||
; Datesep : Date separator (2/4/2004 or 2-4-2004 for example)
|
||||
; Timesep : usually ":" is used to separate hours, minutes and seconds
|
||||
; Currencyf : Currency format (bit array)
|
||||
; bit 2 = set if currency symbol replaces decimal point
|
||||
; bit 1 = number of spaces between value and currency symbol
|
||||
; bit 0 = 0 if currency symbol precedes value
|
||||
; 1 if currency symbol follows value
|
||||
; Currencyp : Currency precision
|
||||
; Time format : 0=12 hour format (AM/PM), 1=24 hour format (4:12 PM is 16:12)
|
||||
;
|
||||
; ID CP DF currency 1000 0.1 DS TS CF Pr TF Country/Locale Contributor
|
||||
;------------------------------------------------------------------------------
|
||||
us db 0FFh,"CTYINFO"
|
||||
dw 22; length
|
||||
dw 1,437,MDY
|
||||
db "$",0,0,0,0
|
||||
dw ",",".", "-",":"
|
||||
db 0,2,_12; United States
|
||||
ca db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 2,863,YMD
|
||||
db "$",0,0,0,0
|
||||
dw " ",",", "-",":"
|
||||
db 3,2,_24; Canadian French
|
||||
la db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 3,850,DMY
|
||||
db "$",0,0,0,0
|
||||
dw ",",".", "/",":"
|
||||
db 0,2,_12; Latin America
|
||||
ru db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 7,866,DMY
|
||||
db "RUB",0,0
|
||||
dw " ",",", ".",":"
|
||||
db 3,2,_24; Russia Arkady V. Belousov
|
||||
gr db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 30,869,DMY
|
||||
db "EYP",0,0
|
||||
dw ".",",", "/",":"
|
||||
db 1,2,_12; Greece
|
||||
nl db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 31,850,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", "-",":"
|
||||
db 0,2,_24; Netherlands Bart E. Oldeman
|
||||
be db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 32,850,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", "/",":"
|
||||
db 0,2,_24; Belgium
|
||||
fr db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 33,850,DMY
|
||||
db "EUR",0,0
|
||||
dw " ",",", ".",":"
|
||||
db 0,2,_24; France
|
||||
sn db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 34,850,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", "/",":"
|
||||
db 0,2,_24; Spain Aitor S. Merino
|
||||
hu db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 36,852,YMD
|
||||
db "Ft",0,0,0
|
||||
dw " ",",", ".",":"
|
||||
db 3,2,_24; Hungary
|
||||
yu db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 38,852,YMD
|
||||
db "Din",0,0
|
||||
dw ".",",", "-",":"
|
||||
db 2,2,_24; Yugoslavia
|
||||
it db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 39,850,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", "/","."
|
||||
db 0,2,_24; Italy
|
||||
ro db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 40,852,YMD
|
||||
db "Lei",0,0
|
||||
dw ".",",", "-",":"
|
||||
db 0,2,_24; Romania
|
||||
sw db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 41,850,DMY
|
||||
db "Fr.",0,0
|
||||
dw "'",".", ".",","
|
||||
db 2,2,_24; Switzerland
|
||||
cz db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 42,852,YMD
|
||||
db "KCs",0,0
|
||||
dw ".",",", "-",":"
|
||||
db 2,2,_24; Czechoslovakia
|
||||
as db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 43,850,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", ".","."
|
||||
db 0,2,_24; Austria
|
||||
uk db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 44,850,DMY
|
||||
db 9ch,0,0,0,0
|
||||
dw ",",".", "/",":"
|
||||
db 0,2,_24; United Kingdom
|
||||
dk db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 45,865,DMY
|
||||
db "kr",0,0,0
|
||||
dw ".",",", "-","."
|
||||
db 2,2,_24; Denmark
|
||||
se db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 46,850,YMD
|
||||
db "Kr",0,0,0
|
||||
dw " ",",", "-","."
|
||||
db 3,2,_24; Sweden
|
||||
no db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 47,865,DMY
|
||||
db "Kr",0,0,0
|
||||
dw ".",",", ".",":"
|
||||
db 2,2,_24; Norway
|
||||
pl db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 48,852,YMD
|
||||
db "Z",88h,0,0,0
|
||||
dw ".",",", "-",":"
|
||||
db 0,2,_24; Poland Michal H. Tyc
|
||||
de db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 49,850,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", ".","."
|
||||
db 1,2,_24; Germany Tom Ehlert
|
||||
ar db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 54,850,DMY
|
||||
db "$",0,0,0,0
|
||||
dw ".",",", "/","."
|
||||
db 0,2,_24; Argentina
|
||||
br db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 55,850,DMY
|
||||
db "Cr$",0,0
|
||||
dw ".",",", "/",":"
|
||||
db 2,2,_24; Brazil
|
||||
au db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 61,437,DMY
|
||||
db "$",0,0,0,0
|
||||
dw ",",".", "-",":"
|
||||
db 0,2,_12; Australia
|
||||
np db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 81,932,YMD
|
||||
db 81h,8fh,0,0,0
|
||||
dw ",",".", "-",":"
|
||||
db 0,0,_24; Japan Yuki Mitsui
|
||||
kr db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 82,934,YMD
|
||||
db 5Ch,0,0,0,0
|
||||
dw ",",".", ".",":"
|
||||
db 0,0,_24; Korea
|
||||
tk db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 90,850,DMY
|
||||
db "TL",0,0,0
|
||||
dw ".",",", "/",":"
|
||||
db 4,2,_24; Turkey
|
||||
ia db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 91,437,DMY
|
||||
db "Rs",0,0,0
|
||||
dw ".",",", "/",":"
|
||||
db 0,2,_24; India
|
||||
pt db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 351,860,DMY
|
||||
db "EUR",0,0
|
||||
dw ".",",", "-",":"
|
||||
db 0,2,_24; Portugal
|
||||
fi db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 358,850,DMY
|
||||
db "EUR",0,0
|
||||
dw " ",",", ".","."
|
||||
db 3,2,_24; Finland Wolf
|
||||
bg db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 359,855,DMY
|
||||
db "BGL",0,0
|
||||
dw " ",",", ".",","
|
||||
db 3,2,_24; Bulgaria Luchezar Georgiev
|
||||
ua db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 380,848,DMY
|
||||
db "UAH",0,0
|
||||
dw " ",",", ".",":"
|
||||
db 3,2,_24; Ukraine Oleg Deribas
|
||||
me db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 785,864,DMY
|
||||
db 0A4h,0,0,0,0
|
||||
dw ".",",", "/",":"
|
||||
db 3,3,_12; Middle East
|
||||
il db 0FFh,"CTYINFO"
|
||||
dw 22
|
||||
dw 972,862,DMY
|
||||
db 99h,0,0,0,0
|
||||
dw ",",".", " ",":"
|
||||
db 2,2,_24; Israel
|
||||
|
||||
db "FreeDOS" ; trailing, as recommended by RBIL
|
130
kernel/dosfns.c
130
kernel/dosfns.c
@ -96,6 +96,13 @@ STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
|
||||
/* get current directory structure for drive
|
||||
return NULL if the CDS is not valid or the
|
||||
drive is not within range */
|
||||
struct cds FAR *get_cds1(unsigned drv)
|
||||
{
|
||||
if (drv-- == 0) /* 0 = A:, 1 = B:, ... */
|
||||
drv = default_drive;
|
||||
return get_cds(drv);
|
||||
}
|
||||
|
||||
struct cds FAR *get_cds(unsigned drive)
|
||||
{
|
||||
struct cds FAR *cdsp;
|
||||
@ -106,9 +113,9 @@ struct cds FAR *get_cds(unsigned drive)
|
||||
cdsp = &CDSp[drive];
|
||||
flags = cdsp->cdsFlags;
|
||||
/* Entry is disabled or JOINed drives are accessable by the path only */
|
||||
if (!(flags & CDSVALID) || (flags & CDSJOINED) != 0)
|
||||
return NULL;
|
||||
if (!(flags & CDSNETWDRV) && cdsp->cdsDpb == NULL)
|
||||
if ((flags & CDSVALID) == 0 ||
|
||||
(flags & CDSJOINED) != 0 ||
|
||||
(flags & CDSNETWDRV) == 0 && cdsp->cdsDpb == NULL)
|
||||
return NULL;
|
||||
return cdsp;
|
||||
}
|
||||
@ -308,9 +315,13 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
|
||||
}
|
||||
}
|
||||
|
||||
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
|
||||
int SftSeek(int sft_idx, LONG new_pos, unsigned mode)
|
||||
{
|
||||
return _SftSeek(idx_to_sft(sft_idx), new_pos, mode);
|
||||
}
|
||||
|
||||
int _SftSeek(sft FAR *s, LONG new_pos, unsigned mode)
|
||||
{
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
if (FP_OFF(s) == (size_t) -1)
|
||||
return DE_INVLDHNDL;
|
||||
|
||||
@ -322,7 +333,6 @@ COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
|
||||
|
||||
if (s->sft_flags & SFT_FSHARED)
|
||||
{
|
||||
/* SEEK_SET handled below (s->sft_posit=new_pos) */
|
||||
if (mode == SEEK_CUR)
|
||||
{
|
||||
new_pos += s->sft_posit;
|
||||
@ -361,20 +371,6 @@ COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode)
|
||||
{
|
||||
int sft_idx = get_sft_idx(hndl);
|
||||
COUNT result;
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
result = SftSeek(sft_idx, new_pos, mode);
|
||||
if (result == SUCCESS)
|
||||
{
|
||||
return idx_to_sft(sft_idx)->sft_posit;
|
||||
}
|
||||
return (ULONG)-1;
|
||||
}
|
||||
|
||||
STATIC long get_free_hndl(void)
|
||||
{
|
||||
psp FAR *p = MK_FP(cu_psp, 0);
|
||||
@ -764,28 +760,22 @@ COUNT DosClose(COUNT hndl)
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
UWORD * bps, UWORD * nc)
|
||||
UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)
|
||||
{
|
||||
/* navc==NULL means: called from FatGetDrvData, fcbfns.c */
|
||||
struct dpb FAR *dpbp;
|
||||
struct cds FAR *cdsp;
|
||||
COUNT rg[4];
|
||||
UWORD spc;
|
||||
|
||||
/* next - "log" in the drive */
|
||||
drive = (drive == 0 ? default_drive : drive - 1);
|
||||
|
||||
/* first check for valid drive */
|
||||
*spc = -1;
|
||||
cdsp = get_cds(drive);
|
||||
|
||||
if (cdsp == NULL)
|
||||
return FALSE;
|
||||
/* first check for valid drive */
|
||||
if ((cdsp = get_cds1(drive)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
COUNT rg[4];
|
||||
if (remote_getfree(cdsp, rg) != SUCCESS)
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
/* for int21/ah=1c:
|
||||
Undoc DOS says, its not supported for
|
||||
@ -794,21 +784,15 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
the redirector can provide all info
|
||||
- Bart, 2002 Apr 1 */
|
||||
|
||||
if (navc != NULL)
|
||||
{
|
||||
*navc = (COUNT) rg[3];
|
||||
*spc &= 0xff; /* zero out media ID byte */
|
||||
}
|
||||
|
||||
*spc = (COUNT) rg[0];
|
||||
*nc = (COUNT) rg[1];
|
||||
*bps = (COUNT) rg[2];
|
||||
return TRUE;
|
||||
*bps = rg[2];
|
||||
*nc = rg[1];
|
||||
if (navc)
|
||||
*navc = rg[3];
|
||||
return rg[0];
|
||||
}
|
||||
|
||||
dpbp = cdsp->cdsDpb;
|
||||
if (dpbp == NULL)
|
||||
return FALSE;
|
||||
if ((dpbp = cdsp->cdsDpb) == NULL)
|
||||
return -1;
|
||||
|
||||
if (navc == NULL)
|
||||
{
|
||||
@ -816,56 +800,60 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
flush_buffers(dpbp->dpb_unit);
|
||||
dpbp->dpb_flags = M_CHANGED;
|
||||
}
|
||||
|
||||
if (media_check(dpbp) < 0)
|
||||
return FALSE;
|
||||
/* get the data available from dpb */
|
||||
*spc = (dpbp->dpb_clsmask + 1);
|
||||
return -1;
|
||||
|
||||
/* get the data available from dpb */
|
||||
spc = dpbp->dpb_clsmask + 1;
|
||||
*bps = dpbp->dpb_secsize;
|
||||
|
||||
/* now tell fs to give us free cluster */
|
||||
/* count */
|
||||
#ifdef WITHFAT32
|
||||
if (ISFAT32(dpbp))
|
||||
{
|
||||
ULONG cluster_size, ntotal, nfree;
|
||||
|
||||
/* we shift ntotal until it is equal to or below 0xfff6 */
|
||||
cluster_size = (ULONG) dpbp->dpb_secsize << dpbp->dpb_shftcnt;
|
||||
ntotal = dpbp->dpb_xsize - 1;
|
||||
if (navc != NULL)
|
||||
/* now tell fs to give us free cluster count */
|
||||
if (navc)
|
||||
nfree = dos_free(dpbp);
|
||||
|
||||
/* we shift ntotal until it is equal to or below 0xfff6 */
|
||||
while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000)
|
||||
{
|
||||
cluster_size <<= 1;
|
||||
*spc <<= 1;
|
||||
spc <<= 1;
|
||||
ntotal >>= 1;
|
||||
nfree >>= 1;
|
||||
}
|
||||
/* get the data available from dpb */
|
||||
*nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) ntotal;
|
||||
|
||||
/* now tell fs to give us free cluster */
|
||||
/* count */
|
||||
if (navc != NULL)
|
||||
*navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) nfree;
|
||||
return TRUE;
|
||||
*nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UWORD) ntotal;
|
||||
if (navc)
|
||||
*navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UWORD) nfree;
|
||||
return spc;
|
||||
}
|
||||
#endif
|
||||
/* a passed nc of 0xffff means: skip free; see FatGetDrvData
|
||||
fcbfns.c */
|
||||
if (*nc != 0xffff)
|
||||
*navc = (COUNT) dos_free(dpbp);
|
||||
|
||||
*nc = dpbp->dpb_size - 1;
|
||||
if (*spc > 64)
|
||||
/* now tell fs to give us free cluster count */
|
||||
if (navc)
|
||||
*navc = (UWORD) dos_free(dpbp);
|
||||
if (spc > 64)
|
||||
{
|
||||
/* fake for 64k clusters do confuse some DOS programs, but let
|
||||
others work without overflowing */
|
||||
*spc >>= 1;
|
||||
*navc = ((unsigned)*navc < FAT_MAGIC16 / 2) ? ((unsigned)*navc << 1) : FAT_MAGIC16;
|
||||
*nc = ((unsigned)*nc < FAT_MAGIC16 / 2) ? ((unsigned)*nc << 1) : FAT_MAGIC16;
|
||||
spc >>= 1;
|
||||
if (*nc > FAT_MAGIC16 / 2)
|
||||
*nc = FAT_MAGIC16;
|
||||
else
|
||||
*nc <<= 1;
|
||||
if (navc)
|
||||
if (*navc > FAT_MAGIC16 / 2)
|
||||
*navc = FAT_MAGIC16;
|
||||
else
|
||||
*navc <<= 1;
|
||||
}
|
||||
return TRUE;
|
||||
return spc;
|
||||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
|
@ -82,11 +82,13 @@ void far *DynAlloc(char *what, unsigned num, unsigned size)
|
||||
return now;
|
||||
}
|
||||
|
||||
/*
|
||||
void DynFree(void *ptr)
|
||||
{
|
||||
struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn));
|
||||
Dynp->Allocated = (char *)ptr - (char *)Dynp->Buffer;
|
||||
}
|
||||
*/
|
||||
|
||||
void FAR * DynLast()
|
||||
{
|
||||
|
@ -44,13 +44,6 @@ static BYTE *RcsId =
|
||||
cluster number rather than overwriting it */
|
||||
#define READ_CLUSTER 1
|
||||
|
||||
#ifndef ISFAT32
|
||||
int ISFAT32(struct dpb FAR * dpbp)
|
||||
{
|
||||
return _ISFAT32(dpbp);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct buffer FAR *getFATblock(struct dpb FAR * dpbp, CLUSTER clussec)
|
||||
{
|
||||
struct buffer FAR *bp = getblock(clussec, dpbp->dpb_unit);
|
||||
@ -125,7 +118,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
struct buffer FAR *bp;
|
||||
unsigned idx;
|
||||
unsigned secdiv;
|
||||
unsigned char wasfree;
|
||||
unsigned char wasfree = 0;
|
||||
CLUSTER clussec = Cluster1;
|
||||
CLUSTER max_cluster = dpbp->dpb_size;
|
||||
|
||||
@ -207,7 +200,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
if (bp1 == 0)
|
||||
return 1; /* the only error code possible here */
|
||||
|
||||
if (Cluster2 != READ_CLUSTER)
|
||||
if ((unsigned)Cluster2 != READ_CLUSTER)
|
||||
bp1->b_flag |= BFR_DIRTY | BFR_VALID;
|
||||
|
||||
fbp1 = &bp1->b_buffer[0];
|
||||
@ -232,11 +225,8 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
return LONG_BAD;
|
||||
return cluster;
|
||||
}
|
||||
|
||||
wasfree = 0;
|
||||
if (cluster == FREE)
|
||||
wasfree = 1;
|
||||
|
||||
wasfree++;
|
||||
cluster = res;
|
||||
}
|
||||
|
||||
@ -245,7 +235,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
cluster2 = (unsigned)Cluster2 & 0x0fff;
|
||||
|
||||
/* Now pack the value in */
|
||||
if ((unsigned)Cluster1 & 0x01)
|
||||
if (Cluster1 & 0x01)
|
||||
{
|
||||
cluster &= 0x000f;
|
||||
cluster2 <<= 4;
|
||||
@ -276,9 +266,8 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
/* Finally, put the word into the buffer and mark the */
|
||||
/* buffer as dirty. */
|
||||
fputword(&bp->b_buffer[idx * 2], (UWORD)Cluster2);
|
||||
wasfree = 0;
|
||||
if (res == FREE)
|
||||
wasfree = 1;
|
||||
wasfree++;
|
||||
}
|
||||
#ifdef WITHFAT32
|
||||
else if (ISFAT32(dpbp))
|
||||
@ -296,9 +285,8 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
/* Finally, put the word into the buffer and mark the */
|
||||
/* buffer as dirty. */
|
||||
fputlong(&bp->b_buffer[idx * 4], Cluster2);
|
||||
wasfree = 0;
|
||||
if (res == FREE)
|
||||
wasfree = 1;
|
||||
wasfree++;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
@ -310,9 +298,9 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
{
|
||||
int adjust = 0;
|
||||
if (!wasfree)
|
||||
adjust = 1;
|
||||
adjust++;
|
||||
else if (Cluster2 != FREE)
|
||||
adjust = -1;
|
||||
adjust--;
|
||||
#ifdef WITHFAT32
|
||||
if (ISFAT32(dpbp) && dpbp->dpb_xnfreeclst != XUNKNCLSTFREE)
|
||||
{
|
||||
|
@ -50,29 +50,27 @@ STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
|
||||
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
|
||||
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
||||
|
||||
static dmatch Dmatch;
|
||||
|
||||
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
|
||||
UBYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
|
||||
{
|
||||
static BYTE mdb;
|
||||
/* get the data available from dpb */
|
||||
UWORD spc = DosGetFree(drive, NULL, bps, nc);
|
||||
if ((*pspc = lobyte(spc)) == 0xff)
|
||||
return NULL;
|
||||
|
||||
/* get the data available from dpb */
|
||||
if (DosGetFree(drive, spc, NULL, bps, nc))
|
||||
if (drive-- == 0) /* 0 = A:, 1 = B:, ... */
|
||||
drive = default_drive;
|
||||
|
||||
/* Point to the media desctriptor for this drive */
|
||||
{
|
||||
struct dpb FAR *dpbp = get_dpb(drive == 0 ? default_drive : drive - 1);
|
||||
/* Point to the media desctriptor for this drive */
|
||||
if (dpbp == NULL)
|
||||
{
|
||||
mdb = *spc >> 8;
|
||||
*spc &= 0xff;
|
||||
return &mdb;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (BYTE FAR *) & (dpbp->dpb_mdb);
|
||||
}
|
||||
struct dpb FAR *dpbp;
|
||||
if ((dpbp = get_dpb(drive)) != NULL)
|
||||
return &dpbp->dpb_mdb;
|
||||
}
|
||||
|
||||
{
|
||||
static UBYTE mdb = 0;
|
||||
return &mdb;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define PARSE_SEP_STOP 0x01
|
||||
@ -85,7 +83,7 @@ BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
|
||||
#define PARSE_RET_BADDRIVE 0xff
|
||||
|
||||
#ifndef IPL
|
||||
UWORD FcbParseFname(int *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb)
|
||||
ofs_t FcbParseFname(UBYTE *wTestMode, const char FAR * lpFileName, fcb FAR * lpFcb)
|
||||
{
|
||||
WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;
|
||||
|
||||
@ -157,7 +155,9 @@ UWORD FcbParseFname(int *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb
|
||||
GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
|
||||
FEXT_SIZE, (BOOL *) & wRetCodeExt);
|
||||
|
||||
*wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
||||
*wTestMode = PARSE_RET_WILD;
|
||||
if (!(wRetCodeName | wRetCodeExt))
|
||||
*wTestMode = PARSE_RET_NOWILD;
|
||||
return FP_OFF(lpFileName);
|
||||
}
|
||||
|
||||
@ -539,13 +539,14 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
|
||||
else do
|
||||
{
|
||||
/* 'A:' + '.' + '\0' */
|
||||
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1];
|
||||
char loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1];
|
||||
fcb LocalFcb;
|
||||
BYTE *pToName;
|
||||
const BYTE FAR *pFromPattern = Dmatch.dm_name;
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
FcbParseFname(&i, pFromPattern, &LocalFcb);
|
||||
loc_szBuffer [0] = 0; /* dummy place */
|
||||
FcbParseFname((UBYTE*)loc_szBuffer, pFromPattern, &LocalFcb);
|
||||
/* Overlay the pattern, skipping '?' */
|
||||
/* I'm cheating because this assumes that the */
|
||||
/* struct alignments are on byte boundaries */
|
||||
@ -630,6 +631,10 @@ VOID FcbCloseAll()
|
||||
DosCloseSft(idx, FALSE);
|
||||
}
|
||||
|
||||
/* TE suggest, that there was not enough space on stack for
|
||||
Dmatch in FcbFindFirstNext() --avb */
|
||||
static dmatch Dmatch;
|
||||
|
||||
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||
{
|
||||
void FAR *orig_dta = dta;
|
||||
@ -691,4 +696,3 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -217,7 +217,7 @@ GLOBAL const BYTE ASM os_release[]
|
||||
= "DOS-C version %d.%d Beta %d [FreeDOS Release] (Build %d).\n"
|
||||
#endif
|
||||
= "FreeDOS kernel version " KERNEL_VERSION_STRING
|
||||
" (Build " KERNEL_BUILD_STRING ") [" __DATE__ " " __TIME__ "]\n"
|
||||
" (Build " KERNEL_BUILD_STRING ", " __DATE__ ")\n"
|
||||
#if 0
|
||||
"For technical information and description of the DOS-C operating system\n\
|
||||
consult \"FreeDOS Kernel\" by Pat Villani, published by Miller\n\
|
||||
|
@ -158,6 +158,7 @@ unsigned ASMPASCAL read(int fd, void *buf, unsigned count);
|
||||
int ASMPASCAL open(const char *pathname, int flags);
|
||||
int ASMPASCAL close(int fd);
|
||||
int ASMPASCAL dup2(int oldfd, int newfd);
|
||||
ULONG ASMPASCAL lseek(int fd, long position);
|
||||
seg ASMPASCAL allocmem(UWORD size);
|
||||
void ASMPASCAL init_PSPSet(seg psp_seg);
|
||||
int ASMPASCAL init_DosExec(int mode, exec_blk *, CStr);
|
||||
@ -246,7 +247,7 @@ enum { ASK_ASK = 0x01, /* ?device= device?= */
|
||||
|
||||
extern UBYTE askCommand;
|
||||
|
||||
extern struct lol FAR *LoL;
|
||||
extern struct lol FAR * const LoL;
|
||||
|
||||
extern struct dhdr DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */
|
||||
|
||||
|
@ -411,13 +411,6 @@ dispatch:
|
||||
}
|
||||
/* Clear carry by default for these functions */
|
||||
|
||||
/* see PATCH TE 5 jul 04 explanation at end */
|
||||
if (ErrorMode && lr.AH > 0x0c && lr.AH != 0x30 && lr.AH != 0x59)
|
||||
{
|
||||
ErrorMode = 0;
|
||||
fnode[0].f_count = 0; /* don't panic - THEY ARE unused !! */
|
||||
fnode[1].f_count = 0;
|
||||
}
|
||||
|
||||
/* Check for Ctrl-Break */
|
||||
if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b))
|
||||
@ -616,14 +609,12 @@ dispatch:
|
||||
|
||||
/* Get Drive Data */
|
||||
case 0x1c:
|
||||
{
|
||||
BYTE FAR *p;
|
||||
|
||||
p = FatGetDrvData(lr.DL, &lr.AX, &lr.CX, &lr.DX);
|
||||
lr.DS = FP_SEG(p);
|
||||
lr.BX = FP_OFF(p);
|
||||
}
|
||||
{
|
||||
UBYTE FAR *p = FatGetDrvData(lr.DL, &lr.AL, &lr.CX, &lr.DX);
|
||||
lr.DS = FP_SEG(p);
|
||||
lr.BX = FP_OFF(p);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get default DPB */
|
||||
/* case 0x1f: see case 0x32 */
|
||||
@ -669,9 +660,7 @@ dispatch:
|
||||
|
||||
/* Parse File Name */
|
||||
case 0x29:
|
||||
rc = 0;
|
||||
lr.SI = FcbParseFname(&rc, MK_FP(lr.DS, lr.SI), FP_ES_DI);
|
||||
lr.AL = rc;
|
||||
lr.SI = FcbParseFname(&lr.AL, MK_FP(lr.DS, lr.SI), FP_ES_DI);
|
||||
break;
|
||||
|
||||
/* Get Date */
|
||||
@ -709,10 +698,8 @@ dispatch:
|
||||
case 0x30:
|
||||
lr.AL = os_setver_major;
|
||||
lr.AH = os_setver_minor;
|
||||
lr.BH = OEM_ID;
|
||||
lr.CH = REVISION_MAJOR; /* JPP */
|
||||
lr.CL = REVISION_MINOR;
|
||||
lr.BL = REVISION_SEQ;
|
||||
lr.BX = (OEM_ID << 8) | REVISION_SEQ;
|
||||
lr.CX = 0; /* serial number must be 0 or buggy 32RTM thrashes stack! */
|
||||
|
||||
if (ReturnAnyDosVersionExpected)
|
||||
{
|
||||
@ -801,7 +788,7 @@ dispatch:
|
||||
|
||||
/* Dos Get Disk Free Space */
|
||||
case 0x36:
|
||||
DosGetFree(lr.DL, &lr.AX, &lr.BX, &lr.CX, &lr.DX);
|
||||
lr.AX = DosGetFree(lr.DL, &lr.BX, &lr.CX, &lr.DX);
|
||||
break;
|
||||
|
||||
/* Undocumented Get/Set Switchar */
|
||||
@ -900,19 +887,15 @@ dispatch:
|
||||
|
||||
/* Dos Seek */
|
||||
case 0x42:
|
||||
if (lr.AL > 2)
|
||||
goto error_invalid;
|
||||
lrc = DosSeek(lr.BX, (LONG)((((ULONG) (lr.CX)) << 16) | lr.DX), lr.AL);
|
||||
if (lrc == -1)
|
||||
{
|
||||
sft FAR *s = get_sft(lr.BX);
|
||||
if ((rc = _SftSeek(s, MK_ULONG(lr.CX, lr.DX), lr.AL)) >= SUCCESS)
|
||||
{
|
||||
lrc = DE_INVLDHNDL;
|
||||
lr.DX = hiword (s->sft_posit);
|
||||
lr.AX = loword (s->sft_posit);
|
||||
}
|
||||
else
|
||||
{
|
||||
lr.DX = (UWORD)(lrc >> 16);
|
||||
lrc = (UWORD) lrc;
|
||||
}
|
||||
goto long_check;
|
||||
goto short_check;
|
||||
}
|
||||
|
||||
/* Get/Set File Attributes */
|
||||
case 0x43:
|
||||
@ -1003,6 +986,7 @@ dispatch:
|
||||
panic("after 4a: MCB chain corrupted");
|
||||
goto error_exit;
|
||||
}
|
||||
lr.AX = lr.ES; /* Undocumented MS-DOS behaviour expected by BRUN45! */
|
||||
break;
|
||||
|
||||
/* Load and Execute Program */
|
||||
@ -1242,7 +1226,7 @@ dispatch:
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
if (lr.AL == 7 || lr.AL == 8)
|
||||
if (inrange(UBYTE, lr.AL, 7, 8))
|
||||
{
|
||||
if (lr.DL < lastdrive)
|
||||
{
|
||||
@ -1660,6 +1644,9 @@ struct int2f12regs {
|
||||
*/
|
||||
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
{
|
||||
COUNT rc;
|
||||
long lrc;
|
||||
|
||||
if (r.AH == 0x4a)
|
||||
{
|
||||
size_t size = 0, offs = 0xffff;
|
||||
@ -1760,11 +1747,14 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
break;
|
||||
|
||||
case 0x13: /* uppercase character */
|
||||
{
|
||||
/* for now, ASCII only because nls.c cannot handle DS!=SS */
|
||||
r.AL = r.callerARG1.b.l;
|
||||
if (_islower(r.AL))
|
||||
r.AL -= (UBYTE)('a' - 'A');
|
||||
UBYTE ch = r.callerARG1.b.l;
|
||||
if (_islower(ch))
|
||||
ch -= (UBYTE)('a' - 'A');
|
||||
r.AL = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x16:
|
||||
/* get address of system file table entry - used by NET.EXE
|
||||
@ -1869,20 +1859,49 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
r.CX = fstrlen(MK_FP(r.DS, r.SI)) + 1;
|
||||
break;
|
||||
|
||||
case 0x26: /* open file */
|
||||
r.FLAGS &= ~FLG_CARRY;
|
||||
CritErrCode = SUCCESS;
|
||||
lrc = DosOpen(MK_FP(r.DS, r.DX), O_LEGACY | O_OPEN | r.CL, 0);
|
||||
goto long_check;
|
||||
|
||||
case 0x27: /* close file */
|
||||
r.FLAGS &= ~FLG_CARRY;
|
||||
CritErrCode = SUCCESS;
|
||||
rc = DosClose(r.BX);
|
||||
goto short_check;
|
||||
|
||||
case 0x28: /* move file pointer */
|
||||
/*
|
||||
* RBIL says: "sets user stack frame pointer to dummy buffer,
|
||||
* moves BP to AX, performs LSEEK, and restores frame pointer"
|
||||
* We obviously don't do it like that. Does this do any harm?! --L.G.
|
||||
*/
|
||||
r.FLAGS &= ~FLG_CARRY;
|
||||
CritErrCode = SUCCESS;
|
||||
if (r.BP < 0x4200 || r.BP > 0x4202)
|
||||
goto error_invalid;
|
||||
{
|
||||
sft FAR *s = get_sft(r.BX);
|
||||
if ((rc = _SftSeek(s, MK_ULONG(r.CX, r.DX), r.BP & 0xff)) >= SUCCESS)
|
||||
{
|
||||
r.DX = hiword (s->sft_posit);
|
||||
r.AX = loword (s->sft_posit);
|
||||
}
|
||||
}
|
||||
goto short_check;
|
||||
|
||||
case 0x29: /* read from file */
|
||||
r.FLAGS &= ~FLG_CARRY;
|
||||
CritErrCode = SUCCESS;
|
||||
lrc = DosRead(r.BX, r.CX, MK_FP(r.DS, r.DX));
|
||||
goto long_check;
|
||||
|
||||
case 0x2a: /* Set FastOpen but does nothing. */
|
||||
|
||||
r.FLAGS &= ~FLG_CARRY;
|
||||
break;
|
||||
|
||||
/* 0x26-0x29 & 0x2B, internal functions necessary for NLSFUNC */
|
||||
case 0x26: /* Open File */
|
||||
case 0x27: /* Close File */
|
||||
case 0x28: /* Move File Pointer */
|
||||
case 0x29: /* Read From File */
|
||||
case 0x2B: /* IOctl */
|
||||
r.FLAGS |= FLG_CARRY; /* Not implemented yet! */
|
||||
break;
|
||||
|
||||
case 0x2c: /* added by James Tabor For Zip Drives
|
||||
Return Null Device Pointer */
|
||||
/* by UDOS+RBIL: get header of SECOND device driver in device chain,
|
||||
@ -1897,6 +1916,19 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
doesn't work!! */
|
||||
break;
|
||||
|
||||
case 0x2f:
|
||||
if (r.DX)
|
||||
{
|
||||
os_setver_major = r.DL;
|
||||
os_setver_minor = r.DH;
|
||||
}
|
||||
else
|
||||
{
|
||||
os_setver_major = os_major;
|
||||
os_setver_minor = os_minor;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (r.AL <= 0x31)
|
||||
{
|
||||
@ -1906,6 +1938,25 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
r.FLAGS |= FLG_CARRY;
|
||||
}
|
||||
}
|
||||
return;
|
||||
long_check:
|
||||
if (lrc >= SUCCESS)
|
||||
{
|
||||
r.AX = (UWORD)lrc;
|
||||
return;
|
||||
}
|
||||
rc = (int)lrc;
|
||||
short_check:
|
||||
if (rc < SUCCESS)
|
||||
goto error_exit;
|
||||
return;
|
||||
error_invalid:
|
||||
rc = DE_INVLDFUNC;
|
||||
error_exit:
|
||||
r.AX = -rc;
|
||||
if (CritErrCode == SUCCESS)
|
||||
CritErrCode = r.AX; /* Maybe set */
|
||||
r.FLAGS |= FLG_CARRY;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -245,6 +245,24 @@ DUP2:
|
||||
push ax ; ret address
|
||||
mov ah, 46h
|
||||
jmp short common_int21
|
||||
|
||||
;
|
||||
; ULONG ASMPASCAL lseek(int fd, long position);
|
||||
;
|
||||
global LSEEK
|
||||
LSEEK:
|
||||
pop ax ; ret address
|
||||
pop dx ; position low
|
||||
pop cx ; position high
|
||||
pop bx ; fd
|
||||
push ax ; ret address
|
||||
mov ax,4200h ; origin: start of file
|
||||
int 21h
|
||||
jnc seek_ret ; CF=1?
|
||||
sbb ax,ax ; then dx:ax = -1, else unchanged
|
||||
sbb dx,dx
|
||||
seek_ret:
|
||||
ret
|
||||
|
||||
;
|
||||
; void ASMPASCAL init_PSPSet(seg psp_seg);
|
||||
|
@ -92,8 +92,9 @@ COUNT DosDevIOctl(lregs * r)
|
||||
|
||||
sft FAR *s;
|
||||
struct dhdr FAR *dev;
|
||||
struct dpb FAR *dpbp;
|
||||
unsigned attr, flags;
|
||||
UBYTE cmd;
|
||||
UBYTE cmd, unit;
|
||||
|
||||
switch (r->AL)
|
||||
{
|
||||
@ -141,8 +142,6 @@ COUNT DosDevIOctl(lregs * r)
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x11:
|
||||
{
|
||||
struct dpb FAR *dpbp;
|
||||
/*
|
||||
Line below previously returned the deviceheader at r->bl. But,
|
||||
DOS numbers its drives starting at 1, not 0. A=1, B=2, and so
|
||||
@ -154,25 +153,23 @@ COUNT DosDevIOctl(lregs * r)
|
||||
#define NDN_HACK
|
||||
#ifdef NDN_HACK
|
||||
/* NDN feeds the actual ASCII drive letter to this function */
|
||||
UBYTE unit = (r->BL & 0x1f) - 1;
|
||||
unit = (r->BL & 0x1f) - 1;
|
||||
#else
|
||||
UBYTE unit = r->BL - 1;
|
||||
unit = r->BL - 1;
|
||||
#endif
|
||||
if (unit == 0xff)
|
||||
unit = default_drive;
|
||||
CharReqHdr.r_unit = unit;
|
||||
if (unit == 0xff)
|
||||
unit = default_drive;
|
||||
|
||||
if ((dpbp = get_dpb(unit)) == NULL)
|
||||
{
|
||||
if (r->AL != 0x09)
|
||||
return DE_INVLDDRV;
|
||||
attr = ATTR_REMOTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev = dpbp->dpb_device;
|
||||
attr = dev->dh_attr;
|
||||
}
|
||||
if ((dpbp = get_dpb(unit)) == NULL)
|
||||
{
|
||||
if (r->AL != 0x09)
|
||||
return DE_INVLDDRV;
|
||||
attr = ATTR_REMOTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev = dpbp->dpb_device;
|
||||
attr = dev->dh_attr;
|
||||
}
|
||||
} /* switch */
|
||||
|
||||
@ -186,6 +183,8 @@ COUNT DosDevIOctl(lregs * r)
|
||||
{
|
||||
CharReqHdr.r_cat = r->CH; /* category (major) code */
|
||||
CharReqHdr.r_fun = r->CL; /* function (minor) code */
|
||||
CharReqHdr.r_si = r->SI; /* contents of SI and DI */
|
||||
CharReqHdr.r_di = r->DI;
|
||||
CharReqHdr.r_io = MK_FP(r->DS, r->DX); /* parameter block */
|
||||
}
|
||||
else
|
||||
@ -194,6 +193,7 @@ COUNT DosDevIOctl(lregs * r)
|
||||
CharReqHdr.r_trans = MK_FP(r->DS, r->DX);
|
||||
}
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_unit = dpbp->dpb_subunit;
|
||||
CharReqHdr.r_status = 0;
|
||||
|
||||
switch (r->AL)
|
||||
@ -256,7 +256,7 @@ COUNT DosDevIOctl(lregs * r)
|
||||
|
||||
case 0x09:
|
||||
{
|
||||
const struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit);
|
||||
const struct cds FAR *cdsp = get_cds(unit);
|
||||
if (cdsp == NULL)
|
||||
return DE_INVLDDRV;
|
||||
if (cdsp->cdsFlags & CDSSUBST)
|
||||
|
@ -36,12 +36,12 @@ static BYTE *mainRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
/* The Holy Copyright Message. Do NOT remove it or you'll be cursed forever! */
|
||||
|
||||
static char copyright[] =
|
||||
"(C) Copyright 1995-2004 Pasquale J. Villani and The FreeDOS Project.\n"
|
||||
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
|
||||
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
|
||||
"GNU General Public License as published by the Free Software Foundation;\n"
|
||||
"either version 2, or (at your option) any later version.\n";
|
||||
"Copyright 1995-2004 Pasquale J. Villani and The FreeDOS Project.\n"
|
||||
"This free software has ABSOLUTELY NO WARRANTY and is licensed under\n"
|
||||
"the GNU General Public License (http://www.gnu.org/licenses/gpl.html)\n\n";
|
||||
|
||||
struct _KernelConfig InitKernelConfig BSS_INIT({0});
|
||||
|
||||
@ -67,7 +67,7 @@ __segment DosTextSeg = 0;
|
||||
|
||||
#endif
|
||||
|
||||
struct lol FAR *LoL = &DATASTART;
|
||||
struct lol FAR * const LoL = &DATASTART;
|
||||
|
||||
void ASMCFUNC FreeDOSmain(void)
|
||||
{
|
||||
@ -132,26 +132,6 @@ void ASMCFUNC FreeDOSmain(void)
|
||||
init_call_p_0(&Config); /* execute process 0 (the shell) */
|
||||
}
|
||||
|
||||
/*
|
||||
InitializeAllBPBs()
|
||||
or MakeNortonDiskEditorHappy()
|
||||
it has been determined, that FDOS's BPB tables are initialized,
|
||||
only when used (like DIR H:).
|
||||
at least one known utility (norton DE) seems to access them directly.
|
||||
ok, so we access for all drives, that the stuff gets build
|
||||
*/
|
||||
void InitializeAllBPBs(VOID)
|
||||
{
|
||||
static char filename[] = "A:-@JUNK@-.TMP";
|
||||
int drive, fileno;
|
||||
for (drive = 'C'; drive < 'A' + LoL->nblkdev; drive++)
|
||||
{
|
||||
filename[0] = drive;
|
||||
if ((fileno = open(filename, O_RDONLY)) >= 0)
|
||||
close(fileno);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void PSPInit(void)
|
||||
{
|
||||
psp _seg *p = MK_SEG_PTR(psp, DOS_PSP);
|
||||
@ -267,6 +247,7 @@ STATIC void init_kernel(void)
|
||||
|
||||
LoL->os_setver_major = LoL->os_major = MAJOR_RELEASE;
|
||||
LoL->os_setver_minor = LoL->os_minor = MINOR_RELEASE;
|
||||
LoL->rev_number = REVISION_SEQ;
|
||||
|
||||
/* move kernel to high conventional RAM, just below the init code */
|
||||
#ifdef __WATCOMC__
|
||||
@ -320,8 +301,6 @@ STATIC void init_kernel(void)
|
||||
|
||||
configDone();
|
||||
|
||||
InitializeAllBPBs();
|
||||
|
||||
DoInstall();
|
||||
}
|
||||
|
||||
@ -652,34 +631,12 @@ static int EmulatedDriveStatus(int drive,char statusOnly)
|
||||
|
||||
STATIC void CheckContinueBootFromHarddisk(void)
|
||||
{
|
||||
char *bootedFrom = "Floppy/CD";
|
||||
|
||||
if (InitKernelConfig.BootHarddiskSeconds <= 0)
|
||||
if (InitKernelConfig.BootHarddiskSeconds <= 0 /* feature disabled */
|
||||
|| LoL->BootDrive >= 3 && EmulatedDriveStatus(0x80,1)) /* booted from HD */
|
||||
return;
|
||||
|
||||
if (LoL->BootDrive >= 3)
|
||||
{
|
||||
#if 0
|
||||
if (EmulatedDriveStatus(0x80,1))
|
||||
#endif
|
||||
/* already booted from HD */
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (EmulatedDriveStatus(0x00,1))
|
||||
#endif
|
||||
bootedFrom = "Floppy";
|
||||
}
|
||||
|
||||
printf("\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" Hit any key within %d seconds to continue booot from %s\n"
|
||||
" Hit 'H' or wait %d seconds to boot from Harddisk\n",
|
||||
InitKernelConfig.BootHarddiskSeconds,
|
||||
bootedFrom,
|
||||
printf("\n\nTo boot from hard disk, press 'H' or wait %d seconds\n"
|
||||
"To boot from floppy/CD, press any other key NOW!\n",
|
||||
InitKernelConfig.BootHarddiskSeconds);
|
||||
|
||||
if (GetBiosKey(InitKernelConfig.BootHarddiskSeconds))
|
||||
|
@ -14,24 +14,20 @@ HDR=../hdr/
|
||||
# files (only 9 directly accessible parameters).
|
||||
|
||||
# Order of linking is important: first kernel.asm, last INIT code.
|
||||
|
||||
OBJS1=kernel.obj entry.obj io.obj console.obj serial.obj printer.obj dsk.obj \
|
||||
sysclk.obj
|
||||
OBJS2=asmsupt.obj execrh.obj nlssupt.obj procsupt.obj dosidle.obj int2f.obj \
|
||||
nls_hc.obj
|
||||
OBJS3=apisupt.obj intr.obj irqstack.obj blockio.obj chario.obj systime.obj \
|
||||
error.obj
|
||||
OBJS4=break.obj dosfns.obj fatdir.obj fatfs.obj fattab.obj fcbfns.obj \
|
||||
inthndlr.obj
|
||||
OBJS5=ioctl.obj dosnames.obj memmgr.obj task.obj newstuff.obj nls.obj network.obj
|
||||
OBJS6=prf.obj misc.obj strings.obj syspack.obj lfnapi.obj iasmsupt.obj
|
||||
OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj \
|
||||
initdisk.obj initclk.obj
|
||||
OBJS1=kernel.obj entry.obj intr.obj irqstack.obj apisupt.obj io.obj console.obj
|
||||
OBJS2=printer.obj serial.obj dosidle.obj execrh.obj asmsupt.obj int2f.obj \
|
||||
nlssupt.obj
|
||||
OBJS3=nls_hc.obj procsupt.obj dsk.obj error.obj blockio.obj chario.obj break.obj
|
||||
OBJS4=fatfs.obj fatdir.obj fattab.obj dosfns.obj fcbfns.obj inthndlr.obj
|
||||
OBJS5=ioctl.obj memmgr.obj task.obj newstuff.obj dosnames.obj nls.obj
|
||||
OBJS6=prf.obj network.obj sysclk.obj lfnapi.obj systime.obj initclk.obj
|
||||
OBJS7=initdisk.obj inithma.obj main.obj config.obj iprf.obj dyninit.obj \
|
||||
iasmsupt.obj
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7)
|
||||
|
||||
# Explicit Rules #######################################################
|
||||
|
||||
all: ..\bin\$(TARGET).sys
|
||||
all: ..\bin\$(TARGET).sys ..\bin\country.sys
|
||||
|
||||
..\bin\$(TARGET).sys: $(TARGET).lnk $(OBJS) $(LIBS) ..\utils\exeflat.exe
|
||||
$(LINK) @$(TARGET).lnk;
|
||||
@ -39,6 +35,9 @@ all: ..\bin\$(TARGET).sys
|
||||
..\utils\exeflat kernel.exe $*.sys $(LOADSEG) -S0x10 -S0x8B $(UPXOPT)
|
||||
copy $*.sys ..\bin\kernel.sys
|
||||
|
||||
..\bin\country.sys: country.asm
|
||||
$(NASM) -o $*.sys country.asm
|
||||
|
||||
# XXX: This is a very ugly way of linking the kernel, forced upon us by the
|
||||
# inability of Turbo `make' 2.0 to perform command line redirection. --ror4
|
||||
|
||||
|
30
kernel/nls.c
30
kernel/nls.c
@ -109,7 +109,7 @@ STATIC COUNT muxGo(int subfct, UWORD bp, UWORD cp, UWORD cntry, UWORD bufsize,
|
||||
/*
|
||||
* Call NLSFUNC to load the NLS package
|
||||
*/
|
||||
COUNT muxLoadPkg(UWORD cp, UWORD cntry)
|
||||
COUNT muxLoadPkg(int subfct, UWORD cp, UWORD cntry)
|
||||
{
|
||||
UWORD id; /* on stack, call_nls in int2f.asm takes care of this
|
||||
* if DS != SS */
|
||||
@ -128,8 +128,8 @@ COUNT muxLoadPkg(UWORD cp, UWORD cntry)
|
||||
NLSFUNC ID. If not NULL, call_nls will set *id = BX on return.
|
||||
Note: &id should be the pointer offset addressable via SS (SS:BP == &id)
|
||||
*/
|
||||
if (muxGo(NLSFUNC_INSTALL_CHECK, 0, NLS_FREEDOS_NLSFUNC_VERSION,
|
||||
0, NLS_FREEDOS_NLSFUNC_ID, 0, (UWORD *)&id) != 0x14ff)
|
||||
if (muxGo(0, 0, NLS_FREEDOS_NLSFUNC_VERSION, 0, NLS_FREEDOS_NLSFUNC_ID, 0,
|
||||
(UWORD *)&id) != 0x14ff)
|
||||
return DE_FILENOTFND; /* No NLSFUNC --> no load */
|
||||
if (id != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */
|
||||
return DE_INVLDACC; /* This magic number */
|
||||
@ -137,7 +137,7 @@ COUNT muxLoadPkg(UWORD cp, UWORD cntry)
|
||||
/* OK, the correct NLSFUNC is available --> load pkg */
|
||||
/* If cp == -1 on entry, NLSFUNC updates cp to the codepage loaded
|
||||
into memory. The system must then change to this one later */
|
||||
return muxGo(NLSFUNC_LOAD_PKG, 0, cp, cntry, 0, 0, 0);
|
||||
return muxGo(subfct, 0, cp, cntry, 0, 0, 0);
|
||||
}
|
||||
|
||||
STATIC int muxBufGo(int subfct, int bp, UWORD cp, UWORD cntry,
|
||||
@ -372,16 +372,31 @@ STATIC COUNT nlsSetPackage(struct nlsPackage FAR * nls)
|
||||
return SUCCESS;
|
||||
}
|
||||
STATIC COUNT DosSetPackage(UWORD cp, UWORD cntry)
|
||||
{
|
||||
/* Right now, we do not have codepage change support in kernel, so push
|
||||
it through the mux in any case. */
|
||||
|
||||
return muxLoadPkg(NLSFUNC_LOAD_PKG2, cp, cntry);
|
||||
}
|
||||
|
||||
STATIC COUNT nlsLoadPackage(struct nlsPackage FAR * nls)
|
||||
{
|
||||
|
||||
nlsInfo.actPkg = nls;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
STATIC COUNT DosLoadPackage(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);
|
||||
return nlsLoadPackage(nls);
|
||||
|
||||
/* not loaded --> invoke NLSFUNC to load it */
|
||||
return muxLoadPkg(cp, cntry);
|
||||
return muxLoadPkg(NLSFUNC_LOAD_PKG, cp, cntry);
|
||||
}
|
||||
|
||||
STATIC void nlsUpMem(struct nlsPackage FAR * nls, VOID FAR * str, int len)
|
||||
@ -564,7 +579,7 @@ COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf)
|
||||
#ifndef DosSetCountry
|
||||
COUNT DosSetCountry(UWORD cntry)
|
||||
{
|
||||
return DosSetPackage(NLS_DEFAULT, cntry);
|
||||
return DosLoadPackage(NLS_DEFAULT, cntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -636,6 +651,7 @@ UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS)
|
||||
/* Does not pass buffer length */
|
||||
return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
|
||||
case NLSFUNC_LOAD_PKG:
|
||||
return nlsLoadPackage(nls);
|
||||
case NLSFUNC_LOAD_PKG2:
|
||||
return nlsSetPackage(nls);
|
||||
case NLSFUNC_YESNO:
|
||||
|
@ -77,11 +77,12 @@ long cooked_write(struct dhdr FAR **pdev, size_t n, char FAR *bp);
|
||||
sft FAR *get_sft(UCOUNT);
|
||||
|
||||
/* dosfns.c */
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
#define SEEK_SET 0u
|
||||
#define SEEK_CUR 1u
|
||||
#define SEEK_END 2u
|
||||
|
||||
const char FAR *get_root(const char FAR *);
|
||||
BOOL check_break(void);
|
||||
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp,
|
||||
COUNT * err, BOOL force_binary);
|
||||
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode);
|
||||
@ -91,7 +92,7 @@ void BinarySftIO(int sft_idx, void *bp, int mode);
|
||||
long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode);
|
||||
#define DosRead(hndl, n, bp) DosRWSft(get_sft_idx(hndl), n, bp, XFR_READ)
|
||||
#define DosWrite(hndl, n, bp) DosRWSft(get_sft_idx(hndl), n, bp, XFR_WRITE)
|
||||
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode);
|
||||
int _SftSeek(sft FAR*, LONG new_pos, unsigned mode);
|
||||
long DosOpen(char FAR * fname, unsigned flags, unsigned attrib);
|
||||
COUNT CloneHandle(unsigned hndl);
|
||||
long DosDup(unsigned Handle);
|
||||
@ -100,8 +101,7 @@ long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib);
|
||||
COUNT DosClose(COUNT hndl);
|
||||
COUNT DosCloseSft(int sft_idx, BOOL commitonly);
|
||||
#define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE)
|
||||
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
UWORD * bps, UWORD * nc);
|
||||
UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc);
|
||||
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
|
||||
COUNT DosChangeDir(BYTE FAR * s);
|
||||
COUNT DosFindFirst(UCOUNT attr, const char FAR * name);
|
||||
@ -122,7 +122,8 @@ COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
|
||||
int idx_to_sft_(int SftIndex);
|
||||
sft FAR *idx_to_sft(int SftIndex);
|
||||
int get_sft_idx(UCOUNT hndl);
|
||||
struct cds FAR *get_cds(unsigned dsk);
|
||||
struct cds FAR *get_cds1(unsigned drv);
|
||||
struct cds FAR *get_cds(unsigned drv);
|
||||
COUNT DosTruename(const char FAR * src, char FAR * dest);
|
||||
|
||||
/*dosidle.asm */
|
||||
@ -212,9 +213,8 @@ int DosCharInput(VOID);
|
||||
VOID DosDirectConsoleIO(iregs FAR * r);
|
||||
VOID DosCharOutput(COUNT c);
|
||||
VOID DosDisplayOutput(COUNT c);
|
||||
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps,
|
||||
UWORD * nc);
|
||||
UWORD FcbParseFname(int *wTestMode, const BYTE FAR *lpFileName, fcb FAR * lpFcb);
|
||||
UBYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * spc, UWORD * bps, UWORD * nc);
|
||||
ofs_t FcbParseFname(UBYTE *wTestMode, const char FAR * lpFileName, fcb FAR * lpFcb);
|
||||
const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName);
|
||||
BOOL TestCmnSeps(BYTE FAR * lpFileName);
|
||||
BOOL TestFieldSeps(BYTE FAR * lpFileName);
|
||||
|
@ -214,13 +214,6 @@ void child_psp(seg_t para, seg_t cur_psp, seg_t beyond)
|
||||
}
|
||||
}
|
||||
|
||||
struct cds FAR *get_cds1(unsigned drv)
|
||||
{
|
||||
if (drv-- == 0) /* 0 = A:, 1 = B:, ... */
|
||||
drv = default_drive;
|
||||
return get_cds(drv);
|
||||
}
|
||||
|
||||
STATIC void makePSP(seg_t pspseg, seg_t envseg, size_t asize, const char FAR * path)
|
||||
{
|
||||
psp _seg *p = MK_SEG_PTR(psp, pspseg);
|
||||
|
@ -455,7 +455,7 @@ int abswrite(int DosDrive, int nsects, int foo, void *diskReadPacket);
|
||||
modify [si di] \
|
||||
value [ax];
|
||||
|
||||
fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno);
|
||||
int fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno);
|
||||
#pragma aux fat32readwrite = \
|
||||
"mov ax, 0x7305" \
|
||||
"mov cx, 0xffff" \
|
||||
@ -516,7 +516,7 @@ int2526readwrite(DosDrive, diskReadPacket, 0x26)
|
||||
|
||||
#endif
|
||||
|
||||
fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno)
|
||||
int fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno)
|
||||
{
|
||||
union REGS regs;
|
||||
|
||||
|
112
utils/exeflat.c
112
utils/exeflat.c
@ -191,43 +191,46 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fseek(src, header.exRelocTable, SEEK_SET);
|
||||
reloc = malloc(header.exRelocItems * sizeof(farptr));
|
||||
if (reloc == NULL)
|
||||
if (header.exRelocTable && header.exRelocItems)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
return 1;
|
||||
}
|
||||
if (fread(reloc, sizeof(farptr), header.exRelocItems, src) !=
|
||||
header.exRelocItems)
|
||||
{
|
||||
printf("Source file read error\n");
|
||||
return 1;
|
||||
}
|
||||
fclose(src);
|
||||
qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
ULONG spot = ((ULONG) reloc[i].seg << 4) + reloc[i].off;
|
||||
UBYTE *spot0 = &buffers[(size_t)(spot / BUFSIZE)][(size_t)(spot % BUFSIZE)];
|
||||
UBYTE *spot1 = &buffers[(size_t)((spot + 1) / BUFSIZE)][(size_t)((spot + 1) % BUFSIZE)];
|
||||
UWORD segment = ((UWORD) * spot1 << 8) + *spot0;
|
||||
fseek(src, header.exRelocTable, SEEK_SET);
|
||||
reloc = malloc(header.exRelocItems * sizeof(farptr));
|
||||
if (reloc == NULL)
|
||||
{
|
||||
printf("Allocation error\n");
|
||||
return 1;
|
||||
}
|
||||
if (fread(reloc, sizeof(farptr), header.exRelocItems, src) !=
|
||||
header.exRelocItems)
|
||||
{
|
||||
printf("Source file read error\n");
|
||||
return 1;
|
||||
}
|
||||
fclose(src);
|
||||
qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
ULONG spot = ((ULONG) reloc[i].seg << 4) + reloc[i].off;
|
||||
UBYTE *spot0 = &buffers[(size_t)(spot / BUFSIZE)][(size_t)(spot % BUFSIZE)];
|
||||
UBYTE *spot1 = &buffers[(size_t)((spot + 1) / BUFSIZE)][(size_t)((spot + 1) % BUFSIZE)];
|
||||
UWORD segment = ((UWORD) * spot1 << 8) + *spot0;
|
||||
|
||||
for (j = 0; j < silentcount; j++)
|
||||
if (segment == silentSegments[j])
|
||||
{
|
||||
silentdone++;
|
||||
goto dontPrint;
|
||||
}
|
||||
|
||||
printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg,
|
||||
reloc[i].off, segment);
|
||||
|
||||
dontPrint:
|
||||
|
||||
segment += start_seg;
|
||||
*spot0 = segment & 0xff;
|
||||
*spot1 = segment >> 8;
|
||||
for (j = 0; j < silentcount; j++)
|
||||
if (segment == silentSegments[j])
|
||||
{
|
||||
silentdone++;
|
||||
goto dontPrint;
|
||||
}
|
||||
|
||||
printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg,
|
||||
reloc[i].off, segment);
|
||||
|
||||
dontPrint:
|
||||
|
||||
segment += start_seg;
|
||||
*spot0 = segment & 0xff;
|
||||
*spot1 = segment >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (UPX)
|
||||
@ -292,25 +295,28 @@ int main(int argc, char **argv)
|
||||
static char trailer[] = {
|
||||
0x0E, /* 0 push cs */
|
||||
0x1F, /* 1 pop ds ; =0x60 */
|
||||
0xBF,0x5E,0x00, /* 2 mov di,start_seg-2 */
|
||||
0x8E,0xC7, /* 5 mov es,di */
|
||||
0xFC, /* 7 cld */
|
||||
0x33,0xFF, /* 8 xor di,di */
|
||||
0x93, /* 10 xchg ax,bx ; mov al,bl */
|
||||
0xAA, /* 11 stosb ; mov [es:0],al */
|
||||
0x8B,0xF7, /* 12 mov si,di */
|
||||
0xB9,0x00,0x00, /* 14 mov cx,offset trailer */
|
||||
0xF3,0xA4, /* 17 rep movsb */
|
||||
0xBF,0x00,0x00, /* 19 mov di,... */
|
||||
0x8E,0xD7, /* 22 mov ss,di */
|
||||
0xBC,0x00,0x00, /* 24 mov sp,... */
|
||||
0x33,0xFF, /* 27 xor di,di */
|
||||
0xFF,0xE7, /* 29 jmp di ; jmp 0 */
|
||||
0x8C,0xDF, /* 2 mov di,ds */
|
||||
0x4F, /* 4 dec di */
|
||||
0x4F, /* 5 dec di */
|
||||
0x8E,0xC7, /* 6 mov es,di */
|
||||
0xFC, /* 8 cld */
|
||||
0x33,0xFF, /* 9 xor di,di */
|
||||
0x93, /* 11 xchg ax,bx ; mov al,bl */
|
||||
0xAA, /* 12 stosb ; mov [es:0],al */
|
||||
0x8B,0xF7, /* 13 mov si,di */
|
||||
0xB9,0x00,0x00, /* 15 mov cx,offset trailer */
|
||||
0xF3,0xA4, /* 18 rep movsb */
|
||||
0x1E, /* 20 push ds */
|
||||
0x58, /* 21 pop ax */
|
||||
0x05,0x00,0x00, /* 22 add ax,... */
|
||||
0x8E,0xD0, /* 25 mov ss,ax */
|
||||
0xBC,0x00,0x00, /* 27 mov sp,... */
|
||||
0x31,0xC0, /* 30 xor ax,ax */
|
||||
0xFF,0xE0, /* 32 jmp ax ; jmp 0 */
|
||||
};
|
||||
*(short *)&trailer[3] = start_seg - 2;
|
||||
*(short *)&trailer[15] = (short)size + 0x20;
|
||||
*(short *)&trailer[20] = start_seg + header.exInitSS;
|
||||
*(short *)&trailer[25] = header.exInitSP;
|
||||
*(short *)&trailer[16] = (short)size + 0x20;
|
||||
*(short *)&trailer[23] = header.exInitSS;
|
||||
*(short *)&trailer[28] = header.exInitSP;
|
||||
fwrite(trailer, 1, sizeof trailer, dest);
|
||||
}
|
||||
fclose(dest);
|
||||
|
@ -1,6 +1,7 @@
|
||||
!include "../mkfiles/generic.mak"
|
||||
|
||||
DEPENDS=$(DEPENDS) *.cfg
|
||||
CFLAGSC=$(CFLAGSC) -DEXEFLAT
|
||||
|
||||
########################################################################
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user