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:
Luchezar Georgiev 2004-09-03 09:26:53 +00:00
parent 31a4275854
commit a6b468389b
27 changed files with 958 additions and 473 deletions

View File

@ -1,3 +1 @@
@echo off @echo Welcome to FreeDOS (http://www.freedos.org)!
echo Welcome to FreeDOS (http://www.freedos.org)!
path=a:\

View File

@ -1,5 +1 @@
rem dos=high ;
rem device=fdxms.sys (or himem.sys)
files=20
buffers=20
rem screen=0x12

View File

@ -30,6 +30,13 @@
; |BOOT SEC| ; |BOOT SEC|
; |RELOCATE| ; |RELOCATE|
; |--------| 1FE0:7C00 ; |--------| 1FE0:7C00
; |LBA PKT |
; |--------| 1FE0:7BC0
; |--------| 1FE0:7BA0
; |BS STACK|
; |--------|
; |4KBRDBUF| used to avoid crossing 64KB DMA boundary
; |--------| 1FE0:63A0
; | | ; | |
; |--------| 1FE0:3000 ; |--------| 1FE0:3000
; | CLUSTER| ; | CLUSTER|
@ -95,24 +102,24 @@ Entry: jmp short real_start
times 0x3E-$+$$ db 0 times 0x3E-$+$$ db 0
%define loadsegoff_60 bp+loadseg_off-Entry ; using bp-Entry+loadseg_xxx generates smaller code than using just
%define loadseg_60 bp+loadseg_seg-Entry ; 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_PACKET bp-0x40
%define LBA_SIZE word [LBA_PACKET] %define LBA_SIZE word [LBA_PACKET] ; size of packet, should be 10h
%define LBA_SECNUM word [LBA_PACKET+2] %define LBA_SECNUM word [LBA_PACKET+2] ; number of sectors to read
%define LBA_OFF LBA_PACKET+4 %define LBA_OFF LBA_PACKET+4 ; buffer to read/write to
%define LBA_SEG LBA_PACKET+6 %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_16 word [LBA_PACKET+10]
%define LBA_SECTOR_32 word [LBA_PACKET+12] %define LBA_SECTOR_32 word [LBA_PACKET+12]
%define LBA_SECTOR_48 word [LBA_PACKET+14] %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 PARAMS LBA_PACKET+0x10
%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses %define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
@ -133,7 +140,7 @@ real_start:
cld cld
xor ax, ax xor ax, ax
mov ds, ax mov ds, ax
mov bp, 0x7c00 mov bp, BASE
; a reset should not be needed here ; 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_SIZE, 10h
mov LBA_SECNUM,1 ; initialise LBA packet constants 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. ; 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] mov di, word [RootDirSecs]
les bx, [loadsegoff_60] ; es:bx = 60:0 les bx, [loadsegoff_60] ; es:bx = 60:0
call readDisk 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. ; Search for KERNEL.SYS file name, and find start cluster.
@ -356,7 +365,8 @@ show: pop si
ret ret
boot_error: call show boot_error: call show
db "Error! Hit a key to reboot." ; db "Error! Hit a key to reboot."
db "Err."
xor ah,ah xor ah,ah
int 0x13 ; reset floppy int 0x13 ; reset floppy
@ -377,8 +387,8 @@ readDisk: push si
mov LBA_SECTOR_0,ax mov LBA_SECTOR_0,ax
mov LBA_SECTOR_16,dx mov LBA_SECTOR_16,dx
mov word [LBA_SEG],es mov word [READADDR_SEG], es
mov word [LBA_OFF],bx mov word [READADDR_OFF], bx
call show call show
db "." db "."
@ -409,7 +419,7 @@ read_next:
lea si,[LBA_PACKET] lea si,[LBA_PACKET]
; setup LBA disk block ; 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 LBA_SECTOR_48,bx
mov ah,042h mov ah,042h
@ -459,22 +469,33 @@ read_normal_BIOS:
or cl, ah ; merge sector into cylinder or cl, ah ; merge sector into cylinder
inc cx ; make sector 1-based (1-63) inc cx ; make sector 1-based (1-63)
les bx,[LBA_OFF] les bx,[LBA_OFF]
mov ax, 0x0201 mov ax, 0x0201
do_int13_read: do_int13_read:
mov dl, [drive] mov dl, [drive]
int 0x13 int 0x13
jc boot_error ; exit on error jc boot_error ; exit on error
mov ax, word [bsBytesPerSec]
div byte[LBA_PACKET] ; luckily 16 !! mov ax, word [bsBytesPerSec]
add word [LBA_SEG], ax
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 add LBA_SECTOR_0, byte 1
adc LBA_SECTOR_16, byte 0 ; DX:AX = next sector to read adc LBA_SECTOR_16, byte 0 ; DX:AX = next sector to read
dec di ; if there is anything left to read, dec di ; if there is anything left to read,
jnz read_next ; continue jnz read_next ; continue
mov es,word [LBA_SEG] les bx, [READADDR_OFF]
; clear carry: unnecessary since adc clears it ; clear carry: unnecessary since adc clears it
pop si pop si
ret ret
@ -484,3 +505,32 @@ do_int13_read:
filename db "KERNEL SYS",0,0 filename db "KERNEL SYS",0,0
sign dw 0xAA55 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

View File

@ -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: Thanks to all the following for contributing to the FreeDOS kernel:
Aitor Santamaria (aitor.sm@wanadoo.es)
Arkady Belousov (ark@mos.ru) Arkady Belousov (ark@mos.ru)
Bart Oldeman (bart@dosemu.org) Bart Oldeman (bart@dosemu.org)
Bernd Blaauw (bblaauw@home.nl)
Brian Reifsnyder (reifsnyderb@mindspring.com) Brian Reifsnyder (reifsnyderb@mindspring.com)
Charles Dye (raster@highfiber.com) Charles Dye (raster@highfiber.com)
Eduardo Casino (eduardo@terra.es)
Eric Auer (eric@coli.uni-sb.de) Eric Auer (eric@coli.uni-sb.de)
Eric Biederman (ebiederm+eric@ccr.net) Eric Biederman (ebiederm+eric@ccr.net)
Eric Luttmann (ecl@users.sourceforge.net) Eric Luttmann (ecl@users.sourceforge.net)

View File

@ -277,6 +277,7 @@
* inthndlr.c * inthndlr.c
- fix: INT21/3301 now returns in DL low bit of input value (as in MS-DOS). - fix: INT21/3301 now returns in DL low bit of input value (as in MS-DOS).
- callerARG1 declared as xreg instead UWORD. - callerARG1 declared as xreg instead UWORD.
* fcbfns.c: FatGetDrvData() and FcbParseFname() optimised
+ Changes Bernd, Aitor, & Arkady + Changes Bernd, Aitor, & Arkady
* config.c * config.c
- source: (Bernd) the codepage table rewritten into a smaller layout. - source: (Bernd) the codepage table rewritten into a smaller layout.
@ -285,6 +286,8 @@
* exeflat.c * exeflat.c
- fix: eliminated warning by explicit cast. - fix: eliminated warning by explicit cast.
- reduced trailer, added to UPXed kernel. - reduced trailer, added to UPXed kernel.
- allow processing of files with 0 relocations
- UPX trailer no longer depends on load segment
* segs.inc * segs.inc
- fix: for MSVC CONST segment should be class CONST, not DATA. - fix: for MSVC CONST segment should be class CONST, not DATA.
* dsk.c * dsk.c
@ -293,15 +296,46 @@
- optimize and make more user friendly instead of retrying endlessly - optimize and make more user friendly instead of retrying endlessly
* sys.c * sys.c
- change OEM Name field to FRDOS4.1 per Eric Auer for better compatibility. - 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 * ludivmul.inc
- 32-bit division code for 386-enabled Watcom kernel. - 32-bit division code for 386-enabled Watcom kernel.
* inthndlr.c * inthndlr.c
- fix: for INT21/5F07 and 5F08, before changing bit CDSPHYSDRV, - fix: for INT21/5F07 and 5F08, before changing bit CDSPHYSDRV,
MS-DOS checks if physical device associated with drive letter. Without MS-DOS checks if physical device associated with drive letter. Without
this check MS-FORMAT under FreeDOS was destroys RAMDISK. 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 + Changes Jeremy
* config.txt * config.txt
- update to include all CONFIG.SYS options (except ANYDOS) - update to include all CONFIG.SYS options (except ANYDOS)
* exeflat.c
- show usage also when number of arguments incorrect
*** Sync - Stable Build 2035 *** *** Sync - Stable Build 2035 ***
2004 May 30 - Build 2035 2004 May 30 - Build 2035

View File

@ -77,6 +77,7 @@
*/*/kernel/config.c */*/kernel/config.c
*/*/kernel/config.h */*/kernel/config.h
*/*/kernel/console.asm */*/kernel/console.asm
*/*/kernel/country.asm
*/*/kernel/dosfns.c */*/kernel/dosfns.c
*/*/kernel/dosidle.asm */*/kernel/dosidle.asm
*/*/kernel/dosnames.c */*/kernel/dosnames.c

View File

@ -374,7 +374,8 @@ typedef struct {
struct { struct {
UBYTE _r_cat; /* Category code */ UBYTE _r_cat; /* Category code */
UBYTE _r_fun; /* Function 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 union
{ {
struct gblkio FAR *_r_io; struct gblkio FAR *_r_io;
@ -424,6 +425,8 @@ typedef struct {
/* generic IOCTL and IOCTL query macros */ /* generic IOCTL and IOCTL query macros */
#define r_cat _r_x._r_gen._r_cat #define r_cat _r_x._r_gen._r_cat
#define r_fun _r_x._r_gen._r_fun #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_rw _r_x._r_gen._r_par._r_rw
#define r_io _r_x._r_gen._r_par._r_io #define r_io _r_x._r_gen._r_par._r_io
#define r_fv _r_x._r_gen._r_par._r_fv #define r_fv _r_x._r_gen._r_par._r_fv

View File

@ -123,6 +123,10 @@ unsigned short getSS(void);
#pragma aux getSS = "mov dx,ss" value [dx] modify exact[dx]; #pragma aux getSS = "mov dx,ss" value [dx] modify exact[dx];
/* enable Possible loss of precision warning for compatibility with Borland */ /* enable Possible loss of precision warning for compatibility with Borland */
#pragma enable_message(130) #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) #if _M_IX86 >= 300 || defined(M_I386)
#define I386 #define I386

View File

@ -1152,38 +1152,103 @@ STATIC void Fcbs(PCStr p)
* matching the specified code page and country code, and loads * matching the specified code page and country code, and loads
* the corresponding information into memory. If code page is 0, * the corresponding information into memory. If code page is 0,
* the default code page for the country will be used. * 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) 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); struct { /* file header */
UNREFERENCED_PARAMETER(ccode); char name[8]; /* "\377COUNTRY.SYS" */
UNREFERENCED_PARAMETER(filename); 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]] */ /* Format: COUNTRY [=] countryCode [, [codePage] [, filename]] */
STATIC void Country(PCStr p) STATIC void Country(PCStr p)
{ {
int ccode; int ccode;
/*PCStr filename = "";*/ PCStr filename = "\\COUNTRY.SYS";
p = GetNumArg(p); p = GetNumArg(p);
if (p == NULL) if (p == NULL)
return; return;
ccode = numarg; ccode = numarg;
/* currently 'implemented' COUNTRY=nnn only */ numarg = 0;
#if 0
numarg = NLS_DEFAULT;
p = skipwh(p); p = skipwh(p);
if (*p == ',') if (*p == ',')
{ {
@ -1204,9 +1269,8 @@ STATIC void Country(PCStr p)
CfgFailure(p); CfgFailure(p);
return; return;
} }
#endif
LoadCountryInfoHardCoded(/*filename*/"", ccode, /*numarg*/NLS_DEFAULT); LoadCountryInfo(filename, ccode, numarg);
} }
/* Format: STACKS [=] stacks [, stackSize] */ /* 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 ** implementation of INSTALL=NANSI.COM /P /X /BLA
*/ */

402
kernel/country.asm Normal file
View 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

View File

@ -96,6 +96,13 @@ STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
/* get current directory structure for drive /* get current directory structure for drive
return NULL if the CDS is not valid or the return NULL if the CDS is not valid or the
drive is not within range */ 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 *get_cds(unsigned drive)
{ {
struct cds FAR *cdsp; struct cds FAR *cdsp;
@ -106,9 +113,9 @@ struct cds FAR *get_cds(unsigned drive)
cdsp = &CDSp[drive]; cdsp = &CDSp[drive];
flags = cdsp->cdsFlags; flags = cdsp->cdsFlags;
/* Entry is disabled or JOINed drives are accessable by the path only */ /* Entry is disabled or JOINed drives are accessable by the path only */
if (!(flags & CDSVALID) || (flags & CDSJOINED) != 0) if ((flags & CDSVALID) == 0 ||
return NULL; (flags & CDSJOINED) != 0 ||
if (!(flags & CDSNETWDRV) && cdsp->cdsDpb == NULL) (flags & CDSNETWDRV) == 0 && cdsp->cdsDpb == NULL)
return NULL; return NULL;
return cdsp; 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) if (FP_OFF(s) == (size_t) -1)
return DE_INVLDHNDL; return DE_INVLDHNDL;
@ -322,7 +333,6 @@ COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
if (s->sft_flags & SFT_FSHARED) if (s->sft_flags & SFT_FSHARED)
{ {
/* SEEK_SET handled below (s->sft_posit=new_pos) */
if (mode == SEEK_CUR) if (mode == SEEK_CUR)
{ {
new_pos += s->sft_posit; new_pos += s->sft_posit;
@ -361,20 +371,6 @@ COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
return SUCCESS; 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) STATIC long get_free_hndl(void)
{ {
psp FAR *p = MK_FP(cu_psp, 0); psp FAR *p = MK_FP(cu_psp, 0);
@ -764,28 +760,22 @@ COUNT DosClose(COUNT hndl)
return ret; return ret;
} }
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc, UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)
UWORD * bps, UWORD * nc)
{ {
/* navc==NULL means: called from FatGetDrvData, fcbfns.c */ /* navc==NULL means: called from FatGetDrvData, fcbfns.c */
struct dpb FAR *dpbp; struct dpb FAR *dpbp;
struct cds FAR *cdsp; struct cds FAR *cdsp;
COUNT rg[4]; UWORD spc;
/* next - "log" in the drive */ /* first check for valid drive */
drive = (drive == 0 ? default_drive : drive - 1); if ((cdsp = get_cds1(drive)) == NULL)
return -1;
/* first check for valid drive */
*spc = -1;
cdsp = get_cds(drive);
if (cdsp == NULL)
return FALSE;
if (cdsp->cdsFlags & CDSNETWDRV) if (cdsp->cdsFlags & CDSNETWDRV)
{ {
COUNT rg[4];
if (remote_getfree(cdsp, rg) != SUCCESS) if (remote_getfree(cdsp, rg) != SUCCESS)
return FALSE; return -1;
/* for int21/ah=1c: /* for int21/ah=1c:
Undoc DOS says, its not supported for 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 the redirector can provide all info
- Bart, 2002 Apr 1 */ - Bart, 2002 Apr 1 */
if (navc != NULL) *bps = rg[2];
{ *nc = rg[1];
*navc = (COUNT) rg[3]; if (navc)
*spc &= 0xff; /* zero out media ID byte */ *navc = rg[3];
} return rg[0];
*spc = (COUNT) rg[0];
*nc = (COUNT) rg[1];
*bps = (COUNT) rg[2];
return TRUE;
} }
dpbp = cdsp->cdsDpb; if ((dpbp = cdsp->cdsDpb) == NULL)
if (dpbp == NULL) return -1;
return FALSE;
if (navc == NULL) if (navc == NULL)
{ {
@ -816,56 +800,60 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
flush_buffers(dpbp->dpb_unit); flush_buffers(dpbp->dpb_unit);
dpbp->dpb_flags = M_CHANGED; dpbp->dpb_flags = M_CHANGED;
} }
if (media_check(dpbp) < 0) if (media_check(dpbp) < 0)
return FALSE; return -1;
/* get the data available from dpb */
*spc = (dpbp->dpb_clsmask + 1); /* get the data available from dpb */
spc = dpbp->dpb_clsmask + 1;
*bps = dpbp->dpb_secsize; *bps = dpbp->dpb_secsize;
/* now tell fs to give us free cluster */
/* count */
#ifdef WITHFAT32 #ifdef WITHFAT32
if (ISFAT32(dpbp)) if (ISFAT32(dpbp))
{ {
ULONG cluster_size, ntotal, nfree; 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; cluster_size = (ULONG) dpbp->dpb_secsize << dpbp->dpb_shftcnt;
ntotal = dpbp->dpb_xsize - 1; ntotal = dpbp->dpb_xsize - 1;
if (navc != NULL) /* now tell fs to give us free cluster count */
if (navc)
nfree = dos_free(dpbp); nfree = dos_free(dpbp);
/* we shift ntotal until it is equal to or below 0xfff6 */
while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000) while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000)
{ {
cluster_size <<= 1; cluster_size <<= 1;
*spc <<= 1; spc <<= 1;
ntotal >>= 1; ntotal >>= 1;
nfree >>= 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 */ *nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UWORD) ntotal;
/* count */ if (navc)
if (navc != NULL) *navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UWORD) nfree;
*navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) nfree; return spc;
return TRUE;
} }
#endif #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; *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 /* fake for 64k clusters do confuse some DOS programs, but let
others work without overflowing */ others work without overflowing */
*spc >>= 1; spc >>= 1;
*navc = ((unsigned)*navc < FAT_MAGIC16 / 2) ? ((unsigned)*navc << 1) : FAT_MAGIC16; if (*nc > FAT_MAGIC16 / 2)
*nc = ((unsigned)*nc < FAT_MAGIC16 / 2) ? ((unsigned)*nc << 1) : FAT_MAGIC16; *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 #ifdef WITHFAT32

View File

@ -82,11 +82,13 @@ void far *DynAlloc(char *what, unsigned num, unsigned size)
return now; return now;
} }
/*
void DynFree(void *ptr) void DynFree(void *ptr)
{ {
struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn)); struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn));
Dynp->Allocated = (char *)ptr - (char *)Dynp->Buffer; Dynp->Allocated = (char *)ptr - (char *)Dynp->Buffer;
} }
*/
void FAR * DynLast() void FAR * DynLast()
{ {

View File

@ -44,13 +44,6 @@ static BYTE *RcsId =
cluster number rather than overwriting it */ cluster number rather than overwriting it */
#define READ_CLUSTER 1 #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 *getFATblock(struct dpb FAR * dpbp, CLUSTER clussec)
{ {
struct buffer FAR *bp = getblock(clussec, dpbp->dpb_unit); 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; struct buffer FAR *bp;
unsigned idx; unsigned idx;
unsigned secdiv; unsigned secdiv;
unsigned char wasfree; unsigned char wasfree = 0;
CLUSTER clussec = Cluster1; CLUSTER clussec = Cluster1;
CLUSTER max_cluster = dpbp->dpb_size; CLUSTER max_cluster = dpbp->dpb_size;
@ -207,7 +200,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
if (bp1 == 0) if (bp1 == 0)
return 1; /* the only error code possible here */ return 1; /* the only error code possible here */
if (Cluster2 != READ_CLUSTER) if ((unsigned)Cluster2 != READ_CLUSTER)
bp1->b_flag |= BFR_DIRTY | BFR_VALID; bp1->b_flag |= BFR_DIRTY | BFR_VALID;
fbp1 = &bp1->b_buffer[0]; fbp1 = &bp1->b_buffer[0];
@ -232,11 +225,8 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
return LONG_BAD; return LONG_BAD;
return cluster; return cluster;
} }
wasfree = 0;
if (cluster == FREE) if (cluster == FREE)
wasfree = 1; wasfree++;
cluster = res; cluster = res;
} }
@ -245,7 +235,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
cluster2 = (unsigned)Cluster2 & 0x0fff; cluster2 = (unsigned)Cluster2 & 0x0fff;
/* Now pack the value in */ /* Now pack the value in */
if ((unsigned)Cluster1 & 0x01) if (Cluster1 & 0x01)
{ {
cluster &= 0x000f; cluster &= 0x000f;
cluster2 <<= 4; 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 */ /* Finally, put the word into the buffer and mark the */
/* buffer as dirty. */ /* buffer as dirty. */
fputword(&bp->b_buffer[idx * 2], (UWORD)Cluster2); fputword(&bp->b_buffer[idx * 2], (UWORD)Cluster2);
wasfree = 0;
if (res == FREE) if (res == FREE)
wasfree = 1; wasfree++;
} }
#ifdef WITHFAT32 #ifdef WITHFAT32
else if (ISFAT32(dpbp)) 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 */ /* Finally, put the word into the buffer and mark the */
/* buffer as dirty. */ /* buffer as dirty. */
fputlong(&bp->b_buffer[idx * 4], Cluster2); fputlong(&bp->b_buffer[idx * 4], Cluster2);
wasfree = 0;
if (res == FREE) if (res == FREE)
wasfree = 1; wasfree++;
} }
#endif #endif
else else
@ -310,9 +298,9 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
{ {
int adjust = 0; int adjust = 0;
if (!wasfree) if (!wasfree)
adjust = 1; adjust++;
else if (Cluster2 != FREE) else if (Cluster2 != FREE)
adjust = -1; adjust--;
#ifdef WITHFAT32 #ifdef WITHFAT32
if (ISFAT32(dpbp) && dpbp->dpb_xnfreeclst != XUNKNCLSTFREE) if (ISFAT32(dpbp) && dpbp->dpb_xnfreeclst != XUNKNCLSTFREE)
{ {

View File

@ -50,29 +50,27 @@ STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL) #define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL) #define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
static dmatch Dmatch; UBYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, 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 (drive-- == 0) /* 0 = A:, 1 = B:, ... */
if (DosGetFree(drive, spc, NULL, bps, nc)) drive = default_drive;
/* Point to the media desctriptor for this drive */
{ {
struct dpb FAR *dpbp = get_dpb(drive == 0 ? default_drive : drive - 1); struct dpb FAR *dpbp;
/* Point to the media desctriptor for this drive */ if ((dpbp = get_dpb(drive)) != NULL)
if (dpbp == NULL) return &dpbp->dpb_mdb;
{ }
mdb = *spc >> 8;
*spc &= 0xff; {
return &mdb; static UBYTE mdb = 0;
} return &mdb;
else
{
return (BYTE FAR *) & (dpbp->dpb_mdb);
}
} }
return NULL;
} }
#define PARSE_SEP_STOP 0x01 #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 #define PARSE_RET_BADDRIVE 0xff
#ifndef IPL #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; 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, GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
FEXT_SIZE, (BOOL *) & wRetCodeExt); 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); return FP_OFF(lpFileName);
} }
@ -539,13 +539,14 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
else do else do
{ {
/* 'A:' + '.' + '\0' */ /* 'A:' + '.' + '\0' */
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1]; char loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1];
fcb LocalFcb; fcb LocalFcb;
BYTE *pToName; BYTE *pToName;
const BYTE FAR *pFromPattern = Dmatch.dm_name; 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 '?' */ /* Overlay the pattern, skipping '?' */
/* I'm cheating because this assumes that the */ /* I'm cheating because this assumes that the */
/* struct alignments are on byte boundaries */ /* struct alignments are on byte boundaries */
@ -630,6 +631,10 @@ VOID FcbCloseAll()
DosCloseSft(idx, FALSE); 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) UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
{ {
void FAR *orig_dta = dta; void FAR *orig_dta = dta;
@ -691,4 +696,3 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
return FCB_SUCCESS; return FCB_SUCCESS;
} }
#endif #endif

View File

@ -217,7 +217,7 @@ GLOBAL const BYTE ASM os_release[]
= "DOS-C version %d.%d Beta %d [FreeDOS Release] (Build %d).\n" = "DOS-C version %d.%d Beta %d [FreeDOS Release] (Build %d).\n"
#endif #endif
= "FreeDOS kernel version " KERNEL_VERSION_STRING = "FreeDOS kernel version " KERNEL_VERSION_STRING
" (Build " KERNEL_BUILD_STRING ") [" __DATE__ " " __TIME__ "]\n" " (Build " KERNEL_BUILD_STRING ", " __DATE__ ")\n"
#if 0 #if 0
"For technical information and description of the DOS-C operating system\n\ "For technical information and description of the DOS-C operating system\n\
consult \"FreeDOS Kernel\" by Pat Villani, published by Miller\n\ consult \"FreeDOS Kernel\" by Pat Villani, published by Miller\n\

View File

@ -158,6 +158,7 @@ unsigned ASMPASCAL read(int fd, void *buf, unsigned count);
int ASMPASCAL open(const char *pathname, int flags); int ASMPASCAL open(const char *pathname, int flags);
int ASMPASCAL close(int fd); int ASMPASCAL close(int fd);
int ASMPASCAL dup2(int oldfd, int newfd); int ASMPASCAL dup2(int oldfd, int newfd);
ULONG ASMPASCAL lseek(int fd, long position);
seg ASMPASCAL allocmem(UWORD size); seg ASMPASCAL allocmem(UWORD size);
void ASMPASCAL init_PSPSet(seg psp_seg); void ASMPASCAL init_PSPSet(seg psp_seg);
int ASMPASCAL init_DosExec(int mode, exec_blk *, CStr); int ASMPASCAL init_DosExec(int mode, exec_blk *, CStr);
@ -246,7 +247,7 @@ enum { ASK_ASK = 0x01, /* ?device= device?= */
extern UBYTE askCommand; 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 */ extern struct dhdr DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */

View File

@ -411,13 +411,6 @@ dispatch:
} }
/* Clear carry by default for these functions */ /* 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 */ /* Check for Ctrl-Break */
if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b)) if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b))
@ -616,14 +609,12 @@ dispatch:
/* Get Drive Data */ /* Get Drive Data */
case 0x1c: case 0x1c:
{ {
BYTE FAR *p; UBYTE FAR *p = FatGetDrvData(lr.DL, &lr.AL, &lr.CX, &lr.DX);
lr.DS = FP_SEG(p);
p = FatGetDrvData(lr.DL, &lr.AX, &lr.CX, &lr.DX); lr.BX = FP_OFF(p);
lr.DS = FP_SEG(p);
lr.BX = FP_OFF(p);
}
break; break;
}
/* Get default DPB */ /* Get default DPB */
/* case 0x1f: see case 0x32 */ /* case 0x1f: see case 0x32 */
@ -669,9 +660,7 @@ dispatch:
/* Parse File Name */ /* Parse File Name */
case 0x29: case 0x29:
rc = 0; lr.SI = FcbParseFname(&lr.AL, MK_FP(lr.DS, lr.SI), FP_ES_DI);
lr.SI = FcbParseFname(&rc, MK_FP(lr.DS, lr.SI), FP_ES_DI);
lr.AL = rc;
break; break;
/* Get Date */ /* Get Date */
@ -709,10 +698,8 @@ dispatch:
case 0x30: case 0x30:
lr.AL = os_setver_major; lr.AL = os_setver_major;
lr.AH = os_setver_minor; lr.AH = os_setver_minor;
lr.BH = OEM_ID; lr.BX = (OEM_ID << 8) | REVISION_SEQ;
lr.CH = REVISION_MAJOR; /* JPP */ lr.CX = 0; /* serial number must be 0 or buggy 32RTM thrashes stack! */
lr.CL = REVISION_MINOR;
lr.BL = REVISION_SEQ;
if (ReturnAnyDosVersionExpected) if (ReturnAnyDosVersionExpected)
{ {
@ -801,7 +788,7 @@ dispatch:
/* Dos Get Disk Free Space */ /* Dos Get Disk Free Space */
case 0x36: 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; break;
/* Undocumented Get/Set Switchar */ /* Undocumented Get/Set Switchar */
@ -900,19 +887,15 @@ dispatch:
/* Dos Seek */ /* Dos Seek */
case 0x42: case 0x42:
if (lr.AL > 2) {
goto error_invalid; sft FAR *s = get_sft(lr.BX);
lrc = DosSeek(lr.BX, (LONG)((((ULONG) (lr.CX)) << 16) | lr.DX), lr.AL); if ((rc = _SftSeek(s, MK_ULONG(lr.CX, lr.DX), lr.AL)) >= SUCCESS)
if (lrc == -1)
{ {
lrc = DE_INVLDHNDL; lr.DX = hiword (s->sft_posit);
lr.AX = loword (s->sft_posit);
} }
else goto short_check;
{ }
lr.DX = (UWORD)(lrc >> 16);
lrc = (UWORD) lrc;
}
goto long_check;
/* Get/Set File Attributes */ /* Get/Set File Attributes */
case 0x43: case 0x43:
@ -1003,6 +986,7 @@ dispatch:
panic("after 4a: MCB chain corrupted"); panic("after 4a: MCB chain corrupted");
goto error_exit; goto error_exit;
} }
lr.AX = lr.ES; /* Undocumented MS-DOS behaviour expected by BRUN45! */
break; break;
/* Load and Execute Program */ /* Load and Execute Program */
@ -1242,7 +1226,7 @@ dispatch:
break; break;
case 0x5f: case 0x5f:
if (lr.AL == 7 || lr.AL == 8) if (inrange(UBYTE, lr.AL, 7, 8))
{ {
if (lr.DL < lastdrive) if (lr.DL < lastdrive)
{ {
@ -1660,6 +1644,9 @@ struct int2f12regs {
*/ */
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r) VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
{ {
COUNT rc;
long lrc;
if (r.AH == 0x4a) if (r.AH == 0x4a)
{ {
size_t size = 0, offs = 0xffff; size_t size = 0, offs = 0xffff;
@ -1760,11 +1747,14 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
break; break;
case 0x13: /* uppercase character */ case 0x13: /* uppercase character */
{
/* for now, ASCII only because nls.c cannot handle DS!=SS */ /* for now, ASCII only because nls.c cannot handle DS!=SS */
r.AL = r.callerARG1.b.l; UBYTE ch = r.callerARG1.b.l;
if (_islower(r.AL)) if (_islower(ch))
r.AL -= (UBYTE)('a' - 'A'); ch -= (UBYTE)('a' - 'A');
r.AL = ch;
break; break;
}
case 0x16: case 0x16:
/* get address of system file table entry - used by NET.EXE /* 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; r.CX = fstrlen(MK_FP(r.DS, r.SI)) + 1;
break; 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. */ case 0x2a: /* Set FastOpen but does nothing. */
r.FLAGS &= ~FLG_CARRY; r.FLAGS &= ~FLG_CARRY;
break; 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 case 0x2c: /* added by James Tabor For Zip Drives
Return Null Device Pointer */ Return Null Device Pointer */
/* by UDOS+RBIL: get header of SECOND device driver in device chain, /* 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!! */ doesn't work!! */
break; 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: default:
if (r.AL <= 0x31) if (r.AL <= 0x31)
{ {
@ -1906,6 +1938,25 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
r.FLAGS |= FLG_CARRY; 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;
} }
/* /*

View File

@ -245,6 +245,24 @@ DUP2:
push ax ; ret address push ax ; ret address
mov ah, 46h mov ah, 46h
jmp short common_int21 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); ; void ASMPASCAL init_PSPSet(seg psp_seg);

View File

@ -92,8 +92,9 @@ COUNT DosDevIOctl(lregs * r)
sft FAR *s; sft FAR *s;
struct dhdr FAR *dev; struct dhdr FAR *dev;
struct dpb FAR *dpbp;
unsigned attr, flags; unsigned attr, flags;
UBYTE cmd; UBYTE cmd, unit;
switch (r->AL) switch (r->AL)
{ {
@ -141,8 +142,6 @@ COUNT DosDevIOctl(lregs * r)
case 0x0e: case 0x0e:
case 0x0f: case 0x0f:
case 0x11: case 0x11:
{
struct dpb FAR *dpbp;
/* /*
Line below previously returned the deviceheader at r->bl. But, 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 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 #define NDN_HACK
#ifdef NDN_HACK #ifdef NDN_HACK
/* NDN feeds the actual ASCII drive letter to this function */ /* NDN feeds the actual ASCII drive letter to this function */
UBYTE unit = (r->BL & 0x1f) - 1; unit = (r->BL & 0x1f) - 1;
#else #else
UBYTE unit = r->BL - 1; unit = r->BL - 1;
#endif #endif
if (unit == 0xff) if (unit == 0xff)
unit = default_drive; unit = default_drive;
CharReqHdr.r_unit = unit;
if ((dpbp = get_dpb(unit)) == NULL) if ((dpbp = get_dpb(unit)) == NULL)
{ {
if (r->AL != 0x09) if (r->AL != 0x09)
return DE_INVLDDRV; return DE_INVLDDRV;
attr = ATTR_REMOTE; attr = ATTR_REMOTE;
} }
else else
{ {
dev = dpbp->dpb_device; dev = dpbp->dpb_device;
attr = dev->dh_attr; attr = dev->dh_attr;
}
} }
} /* switch */ } /* switch */
@ -186,6 +183,8 @@ COUNT DosDevIOctl(lregs * r)
{ {
CharReqHdr.r_cat = r->CH; /* category (major) code */ CharReqHdr.r_cat = r->CH; /* category (major) code */
CharReqHdr.r_fun = r->CL; /* function (minor) 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 */ CharReqHdr.r_io = MK_FP(r->DS, r->DX); /* parameter block */
} }
else else
@ -194,6 +193,7 @@ COUNT DosDevIOctl(lregs * r)
CharReqHdr.r_trans = MK_FP(r->DS, r->DX); CharReqHdr.r_trans = MK_FP(r->DS, r->DX);
} }
CharReqHdr.r_length = sizeof(request); CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_unit = dpbp->dpb_subunit;
CharReqHdr.r_status = 0; CharReqHdr.r_status = 0;
switch (r->AL) switch (r->AL)
@ -256,7 +256,7 @@ COUNT DosDevIOctl(lregs * r)
case 0x09: case 0x09:
{ {
const struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit); const struct cds FAR *cdsp = get_cds(unit);
if (cdsp == NULL) if (cdsp == NULL)
return DE_INVLDDRV; return DE_INVLDDRV;
if (cdsp->cdsFlags & CDSSUBST) if (cdsp->cdsFlags & CDSSUBST)

View File

@ -36,12 +36,12 @@ static BYTE *mainRcsId =
"$Id$"; "$Id$";
#endif #endif
/* The Holy Copyright Message. Do NOT remove it or you'll be cursed forever! */
static char copyright[] = static char copyright[] =
"(C) Copyright 1995-2004 Pasquale J. Villani and The FreeDOS Project.\n" "Copyright 1995-2004 Pasquale J. Villani and The FreeDOS Project.\n"
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n" "This free software has ABSOLUTELY NO WARRANTY and is licensed under\n"
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n" "the GNU General Public License (http://www.gnu.org/licenses/gpl.html)\n\n";
"GNU General Public License as published by the Free Software Foundation;\n"
"either version 2, or (at your option) any later version.\n";
struct _KernelConfig InitKernelConfig BSS_INIT({0}); struct _KernelConfig InitKernelConfig BSS_INIT({0});
@ -67,7 +67,7 @@ __segment DosTextSeg = 0;
#endif #endif
struct lol FAR *LoL = &DATASTART; struct lol FAR * const LoL = &DATASTART;
void ASMCFUNC FreeDOSmain(void) void ASMCFUNC FreeDOSmain(void)
{ {
@ -132,26 +132,6 @@ void ASMCFUNC FreeDOSmain(void)
init_call_p_0(&Config); /* execute process 0 (the shell) */ 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) STATIC void PSPInit(void)
{ {
psp _seg *p = MK_SEG_PTR(psp, DOS_PSP); 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_major = LoL->os_major = MAJOR_RELEASE;
LoL->os_setver_minor = LoL->os_minor = MINOR_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 */ /* move kernel to high conventional RAM, just below the init code */
#ifdef __WATCOMC__ #ifdef __WATCOMC__
@ -320,8 +301,6 @@ STATIC void init_kernel(void)
configDone(); configDone();
InitializeAllBPBs();
DoInstall(); DoInstall();
} }
@ -652,34 +631,12 @@ static int EmulatedDriveStatus(int drive,char statusOnly)
STATIC void CheckContinueBootFromHarddisk(void) STATIC void CheckContinueBootFromHarddisk(void)
{ {
char *bootedFrom = "Floppy/CD"; if (InitKernelConfig.BootHarddiskSeconds <= 0 /* feature disabled */
|| LoL->BootDrive >= 3 && EmulatedDriveStatus(0x80,1)) /* booted from HD */
if (InitKernelConfig.BootHarddiskSeconds <= 0)
return; return;
if (LoL->BootDrive >= 3) 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",
#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,
InitKernelConfig.BootHarddiskSeconds); InitKernelConfig.BootHarddiskSeconds);
if (GetBiosKey(InitKernelConfig.BootHarddiskSeconds)) if (GetBiosKey(InitKernelConfig.BootHarddiskSeconds))

View File

@ -14,24 +14,20 @@ HDR=../hdr/
# files (only 9 directly accessible parameters). # files (only 9 directly accessible parameters).
# Order of linking is important: first kernel.asm, last INIT code. # Order of linking is important: first kernel.asm, last INIT code.
OBJS1=kernel.obj entry.obj intr.obj irqstack.obj apisupt.obj io.obj console.obj
OBJS1=kernel.obj entry.obj io.obj console.obj serial.obj printer.obj dsk.obj \ OBJS2=printer.obj serial.obj dosidle.obj execrh.obj asmsupt.obj int2f.obj \
sysclk.obj nlssupt.obj
OBJS2=asmsupt.obj execrh.obj nlssupt.obj procsupt.obj dosidle.obj int2f.obj \ OBJS3=nls_hc.obj procsupt.obj dsk.obj error.obj blockio.obj chario.obj break.obj
nls_hc.obj OBJS4=fatfs.obj fatdir.obj fattab.obj dosfns.obj fcbfns.obj inthndlr.obj
OBJS3=apisupt.obj intr.obj irqstack.obj blockio.obj chario.obj systime.obj \ OBJS5=ioctl.obj memmgr.obj task.obj newstuff.obj dosnames.obj nls.obj
error.obj OBJS6=prf.obj network.obj sysclk.obj lfnapi.obj systime.obj initclk.obj
OBJS4=break.obj dosfns.obj fatdir.obj fatfs.obj fattab.obj fcbfns.obj \ OBJS7=initdisk.obj inithma.obj main.obj config.obj iprf.obj dyninit.obj \
inthndlr.obj iasmsupt.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
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7) OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7)
# Explicit Rules ####################################################### # Explicit Rules #######################################################
all: ..\bin\$(TARGET).sys all: ..\bin\$(TARGET).sys ..\bin\country.sys
..\bin\$(TARGET).sys: $(TARGET).lnk $(OBJS) $(LIBS) ..\utils\exeflat.exe ..\bin\$(TARGET).sys: $(TARGET).lnk $(OBJS) $(LIBS) ..\utils\exeflat.exe
$(LINK) @$(TARGET).lnk; $(LINK) @$(TARGET).lnk;
@ -39,6 +35,9 @@ all: ..\bin\$(TARGET).sys
..\utils\exeflat kernel.exe $*.sys $(LOADSEG) -S0x10 -S0x8B $(UPXOPT) ..\utils\exeflat kernel.exe $*.sys $(LOADSEG) -S0x10 -S0x8B $(UPXOPT)
copy $*.sys ..\bin\kernel.sys 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 # 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 # inability of Turbo `make' 2.0 to perform command line redirection. --ror4

View File

@ -109,7 +109,7 @@ STATIC COUNT muxGo(int subfct, UWORD bp, UWORD cp, UWORD cntry, UWORD bufsize,
/* /*
* Call NLSFUNC to load the NLS package * 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 UWORD id; /* on stack, call_nls in int2f.asm takes care of this
* if DS != SS */ * 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. 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) Note: &id should be the pointer offset addressable via SS (SS:BP == &id)
*/ */
if (muxGo(NLSFUNC_INSTALL_CHECK, 0, NLS_FREEDOS_NLSFUNC_VERSION, if (muxGo(0, 0, NLS_FREEDOS_NLSFUNC_VERSION, 0, NLS_FREEDOS_NLSFUNC_ID, 0,
0, NLS_FREEDOS_NLSFUNC_ID, 0, (UWORD *)&id) != 0x14ff) (UWORD *)&id) != 0x14ff)
return DE_FILENOTFND; /* No NLSFUNC --> no load */ return DE_FILENOTFND; /* No NLSFUNC --> no load */
if (id != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */ if (id != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */
return DE_INVLDACC; /* This magic number */ return DE_INVLDACC; /* This magic number */
@ -137,7 +137,7 @@ COUNT muxLoadPkg(UWORD cp, UWORD cntry)
/* OK, the correct NLSFUNC is available --> load pkg */ /* OK, the correct NLSFUNC is available --> load pkg */
/* If cp == -1 on entry, NLSFUNC updates cp to the codepage loaded /* If cp == -1 on entry, NLSFUNC updates cp to the codepage loaded
into memory. The system must then change to this one later */ 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, STATIC int muxBufGo(int subfct, int bp, UWORD cp, UWORD cntry,
@ -372,16 +372,31 @@ STATIC COUNT nlsSetPackage(struct nlsPackage FAR * nls)
return SUCCESS; return SUCCESS;
} }
STATIC COUNT DosSetPackage(UWORD cp, UWORD cntry) 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 */ struct nlsPackage FAR *nls; /* NLS package to use to return the info from */
/* nls := NLS package of cntry/codepage */ /* nls := NLS package of cntry/codepage */
if ((nls = searchPackage(cp, cntry)) != NULL) if ((nls = searchPackage(cp, cntry)) != NULL)
/* OK the NLS pkg is loaded --> activate it */ /* OK the NLS pkg is loaded --> activate it */
return nlsSetPackage(nls); return nlsLoadPackage(nls);
/* not loaded --> invoke NLSFUNC to load it */ /* 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) 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 #ifndef DosSetCountry
COUNT DosSetCountry(UWORD cntry) COUNT DosSetCountry(UWORD cntry)
{ {
return DosSetPackage(NLS_DEFAULT, cntry); return DosLoadPackage(NLS_DEFAULT, cntry);
} }
#endif #endif
@ -636,6 +651,7 @@ UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS)
/* Does not pass buffer length */ /* Does not pass buffer length */
return nlsGetData(nls, CL, MK_FP(ES, DI), 512); return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
case NLSFUNC_LOAD_PKG: case NLSFUNC_LOAD_PKG:
return nlsLoadPackage(nls);
case NLSFUNC_LOAD_PKG2: case NLSFUNC_LOAD_PKG2:
return nlsSetPackage(nls); return nlsSetPackage(nls);
case NLSFUNC_YESNO: case NLSFUNC_YESNO:

View File

@ -77,11 +77,12 @@ long cooked_write(struct dhdr FAR **pdev, size_t n, char FAR *bp);
sft FAR *get_sft(UCOUNT); sft FAR *get_sft(UCOUNT);
/* dosfns.c */ /* dosfns.c */
#define SEEK_SET 0
#define SEEK_CUR 1 #define SEEK_SET 0u
#define SEEK_END 2 #define SEEK_CUR 1u
#define SEEK_END 2u
const char FAR *get_root(const char FAR *); const char FAR *get_root(const char FAR *);
BOOL check_break(void);
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp, UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp,
COUNT * err, BOOL force_binary); COUNT * err, BOOL force_binary);
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode); 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); 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 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) #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); long DosOpen(char FAR * fname, unsigned flags, unsigned attrib);
COUNT CloneHandle(unsigned hndl); COUNT CloneHandle(unsigned hndl);
long DosDup(unsigned Handle); long DosDup(unsigned Handle);
@ -100,8 +101,7 @@ long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib);
COUNT DosClose(COUNT hndl); COUNT DosClose(COUNT hndl);
COUNT DosCloseSft(int sft_idx, BOOL commitonly); COUNT DosCloseSft(int sft_idx, BOOL commitonly);
#define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE) #define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE)
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc, UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc);
UWORD * bps, UWORD * nc);
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s); COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
COUNT DosChangeDir(BYTE FAR * s); COUNT DosChangeDir(BYTE FAR * s);
COUNT DosFindFirst(UCOUNT attr, const char FAR * name); 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); int idx_to_sft_(int SftIndex);
sft FAR *idx_to_sft(int SftIndex); sft FAR *idx_to_sft(int SftIndex);
int get_sft_idx(UCOUNT hndl); 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); COUNT DosTruename(const char FAR * src, char FAR * dest);
/*dosidle.asm */ /*dosidle.asm */
@ -212,9 +213,8 @@ int DosCharInput(VOID);
VOID DosDirectConsoleIO(iregs FAR * r); VOID DosDirectConsoleIO(iregs FAR * r);
VOID DosCharOutput(COUNT c); VOID DosCharOutput(COUNT c);
VOID DosDisplayOutput(COUNT c); VOID DosDisplayOutput(COUNT c);
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UBYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * spc, UWORD * bps, UWORD * nc);
UWORD * nc); ofs_t FcbParseFname(UBYTE *wTestMode, const char FAR * lpFileName, fcb FAR * lpFcb);
UWORD FcbParseFname(int *wTestMode, const BYTE FAR *lpFileName, fcb FAR * lpFcb);
const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName); const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName);
BOOL TestCmnSeps(BYTE FAR * lpFileName); BOOL TestCmnSeps(BYTE FAR * lpFileName);
BOOL TestFieldSeps(BYTE FAR * lpFileName); BOOL TestFieldSeps(BYTE FAR * lpFileName);

View File

@ -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) STATIC void makePSP(seg_t pspseg, seg_t envseg, size_t asize, const char FAR * path)
{ {
psp _seg *p = MK_SEG_PTR(psp, pspseg); psp _seg *p = MK_SEG_PTR(psp, pspseg);

View File

@ -455,7 +455,7 @@ int abswrite(int DosDrive, int nsects, int foo, void *diskReadPacket);
modify [si di] \ modify [si di] \
value [ax]; value [ax];
fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno); int fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno);
#pragma aux fat32readwrite = \ #pragma aux fat32readwrite = \
"mov ax, 0x7305" \ "mov ax, 0x7305" \
"mov cx, 0xffff" \ "mov cx, 0xffff" \
@ -516,7 +516,7 @@ int2526readwrite(DosDrive, diskReadPacket, 0x26)
#endif #endif
fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno) int fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno)
{ {
union REGS regs; union REGS regs;

View File

@ -191,43 +191,46 @@ int main(int argc, char **argv)
return 1; return 1;
} }
} }
fseek(src, header.exRelocTable, SEEK_SET); if (header.exRelocTable && header.exRelocItems)
reloc = malloc(header.exRelocItems * sizeof(farptr));
if (reloc == NULL)
{ {
printf("Allocation error\n"); fseek(src, header.exRelocTable, SEEK_SET);
return 1; reloc = malloc(header.exRelocItems * sizeof(farptr));
} if (reloc == NULL)
if (fread(reloc, sizeof(farptr), header.exRelocItems, src) != {
header.exRelocItems) printf("Allocation error\n");
{ return 1;
printf("Source file read error\n"); }
return 1; if (fread(reloc, sizeof(farptr), header.exRelocItems, src) !=
} header.exRelocItems)
fclose(src); {
qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc); printf("Source file read error\n");
for (i = 0; i < header.exRelocItems; i++) return 1;
{ }
ULONG spot = ((ULONG) reloc[i].seg << 4) + reloc[i].off; fclose(src);
UBYTE *spot0 = &buffers[(size_t)(spot / BUFSIZE)][(size_t)(spot % BUFSIZE)]; qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc);
UBYTE *spot1 = &buffers[(size_t)((spot + 1) / BUFSIZE)][(size_t)((spot + 1) % BUFSIZE)]; for (i = 0; i < header.exRelocItems; i++)
UWORD segment = ((UWORD) * spot1 << 8) + *spot0; {
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++) for (j = 0; j < silentcount; j++)
if (segment == silentSegments[j]) if (segment == silentSegments[j])
{ {
silentdone++; silentdone++;
goto dontPrint; goto dontPrint;
} }
printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg, printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg,
reloc[i].off, segment); reloc[i].off, segment);
dontPrint: dontPrint:
segment += start_seg; segment += start_seg;
*spot0 = segment & 0xff; *spot0 = segment & 0xff;
*spot1 = segment >> 8; *spot1 = segment >> 8;
}
} }
if (UPX) if (UPX)
@ -292,25 +295,28 @@ int main(int argc, char **argv)
static char trailer[] = { static char trailer[] = {
0x0E, /* 0 push cs */ 0x0E, /* 0 push cs */
0x1F, /* 1 pop ds ; =0x60 */ 0x1F, /* 1 pop ds ; =0x60 */
0xBF,0x5E,0x00, /* 2 mov di,start_seg-2 */ 0x8C,0xDF, /* 2 mov di,ds */
0x8E,0xC7, /* 5 mov es,di */ 0x4F, /* 4 dec di */
0xFC, /* 7 cld */ 0x4F, /* 5 dec di */
0x33,0xFF, /* 8 xor di,di */ 0x8E,0xC7, /* 6 mov es,di */
0x93, /* 10 xchg ax,bx ; mov al,bl */ 0xFC, /* 8 cld */
0xAA, /* 11 stosb ; mov [es:0],al */ 0x33,0xFF, /* 9 xor di,di */
0x8B,0xF7, /* 12 mov si,di */ 0x93, /* 11 xchg ax,bx ; mov al,bl */
0xB9,0x00,0x00, /* 14 mov cx,offset trailer */ 0xAA, /* 12 stosb ; mov [es:0],al */
0xF3,0xA4, /* 17 rep movsb */ 0x8B,0xF7, /* 13 mov si,di */
0xBF,0x00,0x00, /* 19 mov di,... */ 0xB9,0x00,0x00, /* 15 mov cx,offset trailer */
0x8E,0xD7, /* 22 mov ss,di */ 0xF3,0xA4, /* 18 rep movsb */
0xBC,0x00,0x00, /* 24 mov sp,... */ 0x1E, /* 20 push ds */
0x33,0xFF, /* 27 xor di,di */ 0x58, /* 21 pop ax */
0xFF,0xE7, /* 29 jmp di ; jmp 0 */ 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[16] = (short)size + 0x20;
*(short *)&trailer[15] = (short)size + 0x20; *(short *)&trailer[23] = header.exInitSS;
*(short *)&trailer[20] = start_seg + header.exInitSS; *(short *)&trailer[28] = header.exInitSP;
*(short *)&trailer[25] = header.exInitSP;
fwrite(trailer, 1, sizeof trailer, dest); fwrite(trailer, 1, sizeof trailer, dest);
} }
fclose(dest); fclose(dest);

View File

@ -1,6 +1,7 @@
!include "../mkfiles/generic.mak" !include "../mkfiles/generic.mak"
DEPENDS=$(DEPENDS) *.cfg DEPENDS=$(DEPENDS) *.cfg
CFLAGSC=$(CFLAGSC) -DEXEFLAT
######################################################################## ########################################################################