diff --git a/bin/autoexec.bat b/bin/autoexec.bat index 54f3e64..ec624b1 100644 --- a/bin/autoexec.bat +++ b/bin/autoexec.bat @@ -1,3 +1 @@ -@echo off -echo Welcome to FreeDOS (http://www.freedos.org)! -path=a:\ +@echo Welcome to FreeDOS (http://www.freedos.org)! diff --git a/bin/config.sys b/bin/config.sys index 1810c89..092bc2b 100644 --- a/bin/config.sys +++ b/bin/config.sys @@ -1,5 +1 @@ -rem dos=high -rem device=fdxms.sys (or himem.sys) -files=20 -buffers=20 -rem screen=0x12 +; diff --git a/boot/boot.asm b/boot/boot.asm index fac35f1..ee6ff75 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -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 diff --git a/docs/contrib.txt b/docs/contrib.txt index 15a2570..6f446a5 100644 --- a/docs/contrib.txt +++ b/docs/contrib.txt @@ -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) diff --git a/docs/history.txt b/docs/history.txt index ea88b53..c7c5d7b 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -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 diff --git a/filelist b/filelist index b6c5735..7aa7764 100644 --- a/filelist +++ b/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 diff --git a/hdr/device.h b/hdr/device.h index 2708a60..b873bad 100644 --- a/hdr/device.h +++ b/hdr/device.h @@ -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 diff --git a/hdr/portab.h b/hdr/portab.h index e551d6c..19d91d4 100644 --- a/hdr/portab.h +++ b/hdr/portab.h @@ -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 diff --git a/kernel/config.c b/kernel/config.c index 6974e8f..1e036f6 100644 --- a/kernel/config.c +++ b/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 */ diff --git a/kernel/country.asm b/kernel/country.asm new file mode 100644 index 0000000..204498c --- /dev/null +++ b/kernel/country.asm @@ -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 diff --git a/kernel/dosfns.c b/kernel/dosfns.c index 5135d4d..7ef142c 100644 --- a/kernel/dosfns.c +++ b/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 diff --git a/kernel/dyninit.c b/kernel/dyninit.c index 46acb1a..575998e 100644 --- a/kernel/dyninit.c +++ b/kernel/dyninit.c @@ -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() { diff --git a/kernel/fattab.c b/kernel/fattab.c index 6083a65..f6aafe2 100644 --- a/kernel/fattab.c +++ b/kernel/fattab.c @@ -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) { diff --git a/kernel/fcbfns.c b/kernel/fcbfns.c index a74795e..576aec7 100644 --- a/kernel/fcbfns.c +++ b/kernel/fcbfns.c @@ -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 - diff --git a/kernel/globals.h b/kernel/globals.h index dc16b57..c8f912a 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -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\ diff --git a/kernel/init-mod.h b/kernel/init-mod.h index c7b3459..2102674 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -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 */ diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 752c4f0..f2d9f16 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -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; } /* diff --git a/kernel/intr.asm b/kernel/intr.asm index 7318522..1b966da 100644 --- a/kernel/intr.asm +++ b/kernel/intr.asm @@ -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); diff --git a/kernel/ioctl.c b/kernel/ioctl.c index 63b5674..c5bcb1f 100644 --- a/kernel/ioctl.c +++ b/kernel/ioctl.c @@ -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) diff --git a/kernel/main.c b/kernel/main.c index 4262859..bd54324 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -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)) diff --git a/kernel/makefile b/kernel/makefile index 39806a9..db79239 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -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 diff --git a/kernel/nls.c b/kernel/nls.c index 8e6f0c1..768a525 100644 --- a/kernel/nls.c +++ b/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: diff --git a/kernel/proto.h b/kernel/proto.h index 8ed745a..a2aebea 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -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); diff --git a/kernel/task.c b/kernel/task.c index 4e578d1..454328c 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -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); diff --git a/sys/sys.c b/sys/sys.c index 5d30140..8f4e9e9 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -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; diff --git a/utils/exeflat.c b/utils/exeflat.c index b24404a..a24b23e 100644 --- a/utils/exeflat.c +++ b/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); diff --git a/utils/makefile b/utils/makefile index 5a26e97..f29c6aa 100644 --- a/utils/makefile +++ b/utils/makefile @@ -1,6 +1,7 @@ !include "../mkfiles/generic.mak" DEPENDS=$(DEPENDS) *.cfg +CFLAGSC=$(CFLAGSC) -DEXEFLAT ########################################################################