more win3 support, some comments, upx option to build.bat, misc debug print changes

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1147 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Kenneth J Davis 2005-11-06 19:50:35 +00:00
parent a82122eec8
commit 24f47a5ecc
11 changed files with 280 additions and 34 deletions

View File

@ -6,7 +6,7 @@
if NOT "%1" == "/?" goto start
echo ":-----------------------------------------------------------------------"
echo ":- Syntax: BUILD [-r] [fat32|fat16] [msc|wc|tc|tcpp|bc] [86|186|386] "
echo ":- [debug] [lfnapi] [/L #] [/D value] [list] "
echo ":- [debug] [lfnapi] [/L #] [/D value] [list] [upx] "
echo ":- option case is significant !! "
echo ":- Note: Open Watcom (wc) is the preferred compiler "
echo ":-----------------------------------------------------------------------"
@ -47,6 +47,8 @@ if "%1" == "186" set XCPU=186
if "%1" == "386" set XCPU=386
if "%1" == "x86" goto setCPU
if "%1" == "upx" set XUPX=upx --8086 --best
if "%1" == "debug" set ALLCFLAGS=%ALLCFLAGS% -DDEBUG
if "%1" == "lfnapi" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI

View File

@ -87,10 +87,15 @@ set WATCOM=c:\watcom
::set MAKE=nmaker /nologo
:-----------------------------------------------------------------------
:- This section can still be used if you need special consideration
:- for UPX, such as it is not in your PATH or you do not want
:- 8086 compatible settings, otherwise the recommended use is now
:- to add 'upx' option to the build.bat command line
:- where is UPX and which options to use
:- (comment this out if you don't want to use it)
set XUPX=upx --8086 --best
::set XUPX=upx --8086 --best
:-----------------------------------------------------------------------
:- select default target: CPU type (default is 86) and
@ -107,6 +112,7 @@ set XUPX=upx --8086 --best
:- Give extra compiler DEFINE flags here
:- such as -DDEBUG : extra DEBUG output
:- -DDOSEMU : printf output goes to dosemu log
:- -DWIN31SUPPORT : extra Win3.x API support
::set ALLCFLAGS=-DDEBUG
:-----------------------------------------------------------------------

View File

@ -395,12 +395,24 @@
time failure finding/loading CONFIG.SYS)
* config.txt
- update to include all CONFIG.SYS options (except ANYDOS)
* debug.h
- add additional debug style printfs to enable selective debug output
* entry.asm
- add [conditional compiled] support for OEM handler (int 21h ah>0xf8)
- work towards critical section entry/exit calls for Win3 support
* exeflat.c
- show usage also when number of arguments incorrect
* fatdir.c
- be more restrictive in what considered a volume search
* initdisk.c
- set hidden & huge fields in floppy bpb (bugfix 1789)
* inthndlr.c
- add [conditional compiled] support for Win3 API calls (entry/exit/...)
* int2f.asm
- switch to local stack when Win3 support compiled in, ?unneeded/to be removed?
* kernel.asm
- comment some additional variables
- use some unused spaces for OEMHandler variable and Win3 instancing information
* main.c
- treat block devices returning 0 units as load failure
* oemboot.asm - add [optional] PC/MS DOS compatible boot sector

View File

@ -36,8 +36,14 @@
NOTE: this file included by INIT time code and normal
resident code, so use care for all memory references
*/
/* allow output even in non-debug builds */
#if 0
#ifndef DEBUG_NEED_PRINTF
#define DEBUG_NEED_PRINTF
#endif
#endif
/* use to limit output to debug builds */
#ifdef DEBUG
#define DebugPrintf(x) printf x
@ -92,9 +98,12 @@
#define FDirDbgPrintf(x)
#endif
/* extra debug output marking sections */
/* extra debug output when transferring I/O chunks of data */
/* #define DISPLAY_GETBLOCK */
/* extra output during read/write operations */
/* #define DSK_DEBUG */
/* display info on various FAT handling functions (fatfs.c) */
/* #define DEBUGFATFS */
#ifdef DEBUGFATFS
@ -103,6 +112,14 @@
#define FatFSDbgPrintf(x)
#endif
/* debug truename */
/* #define DEBUG_TRUENAME */
#ifdef DEBUG_TRUENAME
#define tn_printf(x) printf x
#else
#define tn_printf(x)
#endif
/* just to be sure printf is declared */
#if defined(DEBUG) || defined(DEBUGIRQ) || defined(DEBUGCFG) || \
@ -110,8 +127,11 @@
defined(DEBUGFATDIR) || defined(DEBUGFATFS)
#ifndef DEBUG_NEED_PRINTF
#define DEBUG_NEED_PRINTF
VOID VA_CDECL printf(const char * fmt, ...);
#endif
#endif
#ifdef DEBUG_NEED_PRINTF
VOID VA_CDECL printf(const char * fmt, ...);
#endif
#endif /* __DEBUG_H */

View File

@ -96,10 +96,12 @@ 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 */
drive is not within range, on input drv is
0 for default or 1=A,2=B,...
*/
struct cds FAR *get_cds1(unsigned drv)
{
if (drv-- == 0) /* 0 = A:, 1 = B:, ... */
if (drv-- == 0) /* get default drive or convert to 0 = A:, 1 = B:, ... */
drv = default_drive;
return get_cds(drv);
}
@ -781,6 +783,16 @@ COUNT DosClose(COUNT hndl)
return ret;
}
/* get disk free space (in terms of free clusters and cluster size)
input: drive specifies which disk to obtain information about,
where 0=default, 1=A,2=B,...
navc, bps, and nc are pointers to uninitialized variables
used to hold the result, where
navc is count of available [free] clusters
bps is bytes per sector
nc is total number of clusters
returns the number of sectors per cluster or on error -1
*/
UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)
{
/* navc==NULL means: called from FatGetDrvData, fcbfns.c */

View File

@ -206,6 +206,35 @@ reloc_call_int20_handler:
; int21_handler(iregs UserRegs)
;
reloc_call_int21_handler:
;%define OEMHANDLER ; enable OEM hook, mostly OEM DOS 2.x, maybe through OEM 6.x
%ifdef OEMHANDLER
extern _OemHook21
; When defined and set (!= ffff:ffffh) invoke installed
; int 21h handler for ah=f9h through ffh
; with all registers preserved, callee must perform the iret
cmp ah, 0f9h ; if a normal int21 call, proceed
jb skip_oemhndlr ; as quickly as possible
; we need all registers preserved but also
; access to the hook address, so we copy locally
; 1st (while performing check for valid address)
; then do the jmp
push ds
push dx
mov dx,[cs:_DGROUP_]
mov ds,dx
cmp word [_OemHook21], -1
je no_oemhndlr
cmp word [_OemHook21+2], -1
je no_oemhndlr
pop dx
pop ds
jmp far [ds:_OemHook21] ; invoke OEM handler (no return)
;local_hookaddr dd 0
no_oemhndlr:
pop dx
pop ds
skip_oemhndlr:
%endif ;OEMHANDLER
;
; Create the stack frame for C call. This is done to
; preserve machine state and provide a C structure for
@ -246,7 +275,9 @@ int21_reentry:
jne int21_1
int21_user:
%IFNDEF WIN31SUPPORT ; begin critical section
call dos_crit_sect
%ENDIF ; NOT WIN31SUPPORT
push ss
push bp
@ -309,15 +340,30 @@ int21_onerrorstack:
jmp short int21_exit_nodec
int21_2: inc byte [_InDOS]
int21_2:
%IFDEF WIN31SUPPORT ; begin critical section
; should be called as needed, but we just
; mark the whole int21 api as critical
push ax
mov ax, 8001h ; Enter Critical Section
int 2ah
pop ax
%ENDIF ; WIN31SUPPORT
inc byte [_InDOS]
mov cx,_char_api_tos
or ah,ah
jz int21_3
%IFDEF WIN31SUPPORT ; testing, this function call crashes
cmp ah,06h
je int21_3
%ENDIF ; WIN31SUPPORT
cmp ah,0ch
jbe int21_normalentry
int21_3:
%IFNDEF WIN31SUPPORT ; begin critical section
call dos_crit_sect
%ENDIF ; NOT WIN31SUPPORT
mov cx,_disk_api_tos
int21_normalentry:
@ -337,6 +383,17 @@ int21_normalentry:
call _int21_service
int21_exit: dec byte [_InDOS]
%IFDEF WIN31SUPPORT ; end critical section
call dos_crit_sect ; release all critical sections
%if 0
; should be called as needed, but we just
; mark the whole int21 api as critical
push ax
mov ax, 8101h ; Leave Critical Section
int 2ah
pop ax
%endif
%ENDIF ; WIN31SUPPORT
;
; Recover registers from system call. Registers and flags

View File

@ -1833,11 +1833,11 @@ int dos_cd(char * PathName)
f_node_ptr get_near_f_node(void)
{
f_node_ptr fnp = fnode;
DebugPrintf(("get_near_f_node: fnp is %p\n", fnp));
DDebugPrintf(("get_near_f_node: fnp is %p\n", fnp));
if (fnp->f_count && (++fnp)->f_count)
panic("more than two near fnodes requested at the same time!\n");
fnp->f_count++;
DebugPrintf(("got near fnode, fnp->f_count=%i\n", fnp->f_count));
DDebugPrintf(("got near fnode, fnp->f_count=%i\n", fnp->f_count));
return fnp;
}

View File

@ -69,6 +69,9 @@ Int2f3:
cmp ax,4a33h ; Check DOS version 7
jne Check4Share
xor ax,ax ; no undocumented shell strings
xor bx,bx ; RBIL undoc BX = ?? (0h)
; " DS:DX ASCIIZ shell exe name
; " DS:SI SHELL= line
iret
Check4Share:
%endif
@ -134,6 +137,28 @@ IntDosCal:
cld
%IFDEF WIN31SUPPORT ; switch to local stack, no reentrancy support
extern mux2F_stk_top:wrt DGROUP
cli
; setup, initialize copy
mov si, sp ; ds:si = ss:sp (user stack)
mov ax, ss
mov ds, ax
mov di, mux2F_stk_top-30 ; es:di = local stack-copied chunk
mov es, [cs:_DGROUP_] ; [-X == -(2*cx below+4) ]
mov cx, 13 ; how many words to copy over
; setup, store original stack pointer
mov [es:di+28], si ; store ss:sp
mov [es:di+26], ds
; actually switch to local stack
mov ax, es
mov ss, ax
mov sp, di
; copy over stack data to local stack
rep movsw
sti
%ENDIF ; WIN31SUPPORT
%if XCPU >= 386
%ifdef WATCOM
mov si,fs
@ -156,6 +181,24 @@ IntDosCal:
%endif
%endif
%IFDEF WIN31SUPPORT ; switch back to user stack
cli
; setup, initialize copy
mov si, sp ; ds:si = ss:sp (local stack)
mov ax, ss
mov ds, ax
mov di, [ds:si+28] ; restore original ss:sp
mov es, [ds:si+26]
mov cx, 13 ; how many words to copy over
; actually switch to user stack
mov ax, es
mov ss, ax
mov sp, di
; copy over stack data to user stack
rep movsw
sti
%ENDIF ; WIN31SUPPORT
pop es
pop ds
pop di

View File

@ -31,6 +31,8 @@
#include "portab.h"
#include "globals.h"
#include "nls.h"
#include "debug.h"
#ifdef VERSION_STRINGS
BYTE *RcsId =
@ -413,7 +415,7 @@ dispatch:
if (bDumpRegs)
{
fmemcpy(&error_regs, user_r, sizeof(iregs));
printf("System call (21h): %02x\n", user_r->AX);
printf("System call (21h): %04x\n", user_r->AX);
dump_regs = TRUE;
dump();
}
@ -762,6 +764,7 @@ dispatch:
case 0x31:
DosMemChange(cu_psp, lr.DX < 6 ? 6 : lr.DX, 0);
return_code = lr.AL | 0x300;
DDebugPrintf(("ErrorLevel kernel returns is %x(==%x|0x300)\n", (unsigned)return_code, (unsigned)lr.AL));
tsr = TRUE;
return_user();
break;
@ -1034,6 +1037,7 @@ dispatch:
rc = 0x100;
}
return_code = lr.AL | rc;
DDebugPrintf(("ErrorLevel kernel returns is %x\n", (unsigned)return_code));
if (DosMemCheck() != SUCCESS)
panic("MCB chain corrupted");
#ifdef TSC
@ -1045,6 +1049,7 @@ dispatch:
/* Get Child-program Return Value */
case 0x4d:
lr.AX = return_code;
DDebugPrintf(("Child ErrorLevel kernel returns is %x(==%x)\n", (unsigned)return_code, (unsigned)lr.AX));
/* needs to be cleared (RBIL) */
return_code = 0;
break;
@ -1734,7 +1739,12 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
switch (r.AL)
{
/* default: unhandled requests pass through unchanged */
#if 0
case 0x0: /* is Windows active */
case 0x0A: /* identify Windows version */
{
/* return AX unchanged if Windows not active */
break;
} /* 0x0, 0x0A */
case 0x03: /* Windows Get Instance Data */
{
/* This should only be called if AX=1607h/BX=15h is not supported. */
@ -1742,12 +1752,12 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
can also be in INSTANCE.386 [which in theory means Windows could
be updated to support FD kernel without responding to these?].
*/
DebugPrintf(("get instance data\n"));
break;
} /* 0x03 */
#endif
case 0x05: /* Windows Startup Broadcast */
{
/* After receiving this call we activiate compatibility changes
/* After receiving this call we activate compatibility changes
as DOS 5 does, though can wait until 0x07 subfunc 0x01
*/
/* on entry:
@ -1763,6 +1773,7 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
r.BX = FP_OFF(&winStartupInfo);
winStartupInfo.winver = r.di; /* match what caller says it is */
winInstanced = 1; /* internal flag marking Windows is active */
DebugPrintf(("Win startup\n"));
break;
} /* 0x05 */
case 0x06: /* Windows Exit Broadcast */
@ -1772,10 +1783,12 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
Note: If Windows fatally exits then may not be called.
*/
winInstanced = 0; /* internal flag marking Windows is NOT active */
DebugPrintf(("Win exit\n"));
break;
} /* 0x06 */
case 0x07: /* DOSMGR Virtual Device API */
{
DebugPrintf(("Vxd:DOSMGR:%x:%x:%x:%x\n",r.AX,r.BX,r.CX,r.DX));
if (r.BX == 0x15) /* VxD id of "DOSMGR" */
{
switch (r.CX)
@ -1791,7 +1804,7 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
}
case 0x01: /* enable Win support, ie patch DOS */
{
/* DOS 5+ return with flags unchanged, Windows critical section
/* DOS 5+ return with bitflags unchanged, Windows critical section
needs are handled without need to patch. If this
function does not return successfully windows will
attempt to do the patching itself (very bad idea).
@ -1810,12 +1823,19 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
0010h: notify Windows of logical drive map change ("Insert disk X:")
*/
r.BX = r.DX; /* sure we support everything asked for, ;-) */
r.DX = 0xA2AB; /* on succes DS:AX set to A2AB:B97Ch */
r.DX = 0xA2AB; /* on succes DX:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
/* FIXME: do we need to do anything special for FD kernel? */
break;
}
/* case 0x02 is below so we can reuse it for 0x05 */
case 0x02: /* disable Win support, ie remove patches */
{
/* Note: if we do anything special in 'patch DOS', undo it here.
This is only called when Windows exits, can be ignored.
*/
r.CX = 0; /* for compatibility with MS-DOS 5/6 */
break;
}
case 0x03: /* get internal structure sizes */
{
if (r.CX & 0x01) /* size of Current Directory Structure in bytes */
@ -1839,29 +1859,89 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
*/
r.DX = 0xA2AB; /* on succes DS:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
r.BX = 0x0008; /* our whole data seg is instanced, so
anything within it we assume instanced. */
r.BX = 0; /* a zero here tells Windows to instance everything */
break;
}
case 0x05: /* get device driver size */
{
/* On entry ES:DI points to possible device driver
if is not one return with AX=BX=CX=DX=0
else return BX:CX size in bytes allocated to driver
and DX:AX set to A2AB:B97Ch */
mcb FAR *smcb = MK_PTR(mcb, (r.ES-1), 0); /* para before is possibly submcb segment */
/* drivers always start a seg:0 (DI==0), so if not then either
not device driver or duplicate (ie device driver file loaded
is of multi-driver variety; multiple device drivers in same file,
whose memory was allocated as a single chunk)
Drivers don't really have a MCB, instead the DOS MCB is broken
up into submcbs, which will have a type of 'D' (or 'E')
So we check that this is primary segment, a device driver, and owner.
*/
if (!r.DI && (smcb->m_type == 'D') && (smcb->m_psp == r.ES))
{
ULONG size = smcb->m_size * 16ul;
r.BX = hiword(size);
r.CX = loword(size);
r.DX = 0xA2AB; /* on succes DX:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
break;
}
r.DX = 0; /* we aren't one so return unsupported */
r.AX = 0;
r.BX = 0;
/* fall through to set CX=0 and exit */
}
case 0x02: /* disable Win support, ie remove patches */
{
/* Note: if we do anything special in 'patch DOS', undo it here.
This is only called when Windows exits, can be ignored.
*/
r.CX = 0; /* for compatibility with MS-DOS 5/6 */
r.CX = 0;
break;
}
}
}
DebugPrintf(("Vxd:DOSMGR:%x:%x:%x:%x\n",r.AX,r.BX,r.CX,r.DX));
break;
} /* 0x07 */
case 0x08: /* Windows Init Complete Broadcast */
{
DebugPrintf(("Init complete\n"));
break;
} /* 0x08 */
case 0x09: /* Windows Begin Exit Broadcast */
{
DebugPrintf(("Exit initiated\n"));
break;
} /* 0x09 */
case 0x0B: /* Win TSR Identify */
{
DebugPrintf(("TSR identify request.\n"));
break;
} /* 0x0B */
case 0x80: /* Win Release Time-slice */
{
/* This function is generally only called in idle loops */
enable; /* enable interrupts */
// __emit__(0xf4); /* halt */
asm hlt;
r.AX = 0;
/* DebugPrintf(("Release Time Slice\n")); */
break;
} /* 0x80 */
case 0x81: /* Win3 Begin Critical Section */
{
DebugPrintf(("Begin CritSect\n"));
break;
} /* 0x81 */
case 0x82: /* Win3 End Critical Section */
{
DebugPrintf(("End CritSect\n"));
break;
} /* 0x82 */
case 0x8F: /* Win4 Close Awareness */
{
if (r.DH != 0x01) /* query close */
r.AX = 0x0;
/* else r.AX = 0x168F; don't close -- continue execution */
break;
} /* 0x8F */
default:
DebugPrintf(("Win call (int 2Fh/16h): %04x %04x %04x %04x\n", r.AX, r.BX, r.CX, r.DX));
break;
}
#endif
return;
@ -1874,7 +1954,7 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
/* To prevent corruption when dos=umb where Windows 3.0 standard
writes a sentinel at 9FFEh, DOS 5 will save the MCB marking
end of conventional memory (ie MCB following caller's PSP memory
block [which I assume occupies all of convential memory] into
block [which I assume occupies all of conventional memory] into
the DOS data segment.
Note: presumably Win3.1 uses the WinPatchTable.OffLastMCBSeg
when DOS ver > 5 to do this itself.

View File

@ -256,11 +256,14 @@ dos_data db 0
global _NetBios
_NetBios dw 0 ; NetBios Number
times (26h - 0ch - ($ - DATASTART)) db 0
times (26h - 12h - ($ - DATASTART)) db 0
; Globally referenced variables - WARNING: DO NOT CHANGE ORDER
; BECAUSE THEY ARE DOCUMENTED AS UNDOCUMENTED (?) AND HAVE
; MANY MULTIPLEX PROGRAMS AND TSR'S ACCESSING THEM
global _OemHook21
_OemHook21 dd -1 ;-0012 OEM fn handler (int21/f8h)
dw 0 ;-000e offset from DOS CS of int21 ret
global _NetRetry
_NetRetry dw 3 ;-000c network retry count
global _NetDelay
@ -284,7 +287,8 @@ _clock dd 0 ; 0008 CLOCK$ device
_syscon dw _con_dev,seg _con_dev ; 000c console device
global _maxbksize
_maxbksize dw 512 ; 0010 maximum bytes/sector of any block device
dd 0 ; 0012 pointer to buffers info structure
global _inforecptr
_inforecptr dd 0 ; 0012 pointer to buffers info structure
global _CDSp
_CDSp dd 0 ; 0016 Current Directory Structure
global _FCBp
@ -338,7 +342,7 @@ _bufloc db 0 ; 0053 00=conv 01=HMA
_deblock_buf dd 0 ; 0054 deblock buffer
times 3 db 0 ; 0058 unknown
dw 0 ; 005B unknown
db 0, 0FFh, 0 ; 005D unknown
db 0, 0FFh, 0 ; 005D int24fail,memstrat,a20count
global _VgaSet
_VgaSet db 0 ; 0060 unknown
dw 0 ; 0061 unknown
@ -385,7 +389,8 @@ _winStartupInfo:
dw instance_table,seg instance_table ; array of instance data
instance_table: ; should include stacks, Win may auto determine SDA region
; we simply include whole DOS data segment
dw 0, seg _DATASTART ; [?linear?] address of region's base
dw seg _DATASTART, 0 ; [?linear?] address of region's base
; dw 0, 0;seg _DATASTART ; [?linear?] address of region's base
dw markEndInstanceData wrt seg _DATASTART ; size in bytes
dd 0 ; 0 marks end of table
patch_bytes: ; mark end of array of offsets of critical section bytes to patch
@ -414,6 +419,8 @@ _winPatchTable: ; returns offsets to various internal variables
_firstsftt:
dd -1 ; link to next
dw 5 ; count
times 5*59 db 0 ; reserve space for the 5 sft entries
db 0 ; pad byte so next value on even boundary
; Some references seem to indicate that this data should start at 01fbh in
; order to maintain 100% MS-DOS compatibility.
@ -717,6 +724,13 @@ blk_stk_top:
times 64 dw 0
clk_stk_top:
%IFDEF WIN31SUPPORT
; mux2F private stack
global mux2F_stk_top
times 128 dw 0
mux2F_stk_top:
%ENDIF ; WIN31SUPPORT
; Dynamic data:
; member of the DOS DATA GROUP
; and marks definitive end of all used data in kernel data segment

View File

@ -48,7 +48,7 @@ DEPENDS=makefile ..\*.bat ..\mkfiles\*.*
# Implicit Rules #######################################################
.asm.obj:
$(NASM) $(NASMFLAGS) $<
$(NASM) $(NASMFLAGS) -l$*.lst $<
.c.obj:
$(CC) $(CFLAGS) $<