trplddsx.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 622 行 · 第 1/2 页
C
622 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Trap file loading for DOS extended debugger.
*
****************************************************************************/
#include <i86.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "dpmi.h"
#include "exedos.h"
#include "dbgdefn.h"
#include "dbgio.h"
#include "dsxutil.h"
#include "trpcore.h"
#include "tinyio.h"
#include "tcerr.h"
#ifdef __OSI__
#include "extender.h"
#endif
#include <conio.h>
#include <stdio.h>
extern trap_version TrapVer;
extern unsigned (TRAPENTRY *ReqFunc)( unsigned, mx_entry *,
unsigned, mx_entry * );
#define DOS4G_COMM_VECTOR 0x15
#define NUM_BUFF_RELOCS 16
#define DEFAULT_TRP_NAME "STD"
#define DEFAULT_TRP_EXT "TRP"
#define PARM_SEPARATOR ';'
#define TRAP_VECTOR 0x1a
#define PSP_ENVSEG_OFF 0x2c
#define TRAP_SIGNATURE 0xdeaf
typedef _Packed struct {
unsigned_16 sig;
addr32_off init;
addr32_off req;
addr32_off fini;
} trap_file_header;
typedef _Packed struct {
memptr ptr;
unsigned_16 len;
} mx_entry16;
static dos_memory TrapMem;
static void __far *RawPMtoRMSwitchAddr;
extern int EnvLkup( char *, char *, int max );
extern handle PathOpen( char *, uint, char * );
extern sys_handle GetSystemHandle( handle );
unsigned_8 DPMICheck = 0;
//#define FULL_SAVE
#ifdef FULL_SAVE
#define INT_VECT_COUNT 256
#define EXCEPT_COUNT 32
#else
#define INT_VECT_COUNT
#define EXCEPT_COUNT
#endif
static unsigned_8 PMVectSaveList[INT_VECT_COUNT] = {
0x00, 0x10, 0x21, 0x2f, 0x31, 0x33
};
#define NUM_PM_SAVE_VECTS (sizeof(PMVectSaveList)/sizeof(PMVectSaveList[0]))
static void __far *OrigPMVects[NUM_PM_SAVE_VECTS];
static void __far *SavePMVects[NUM_PM_SAVE_VECTS];
static unsigned_8 PMExceptSaveList[EXCEPT_COUNT] = {
0x01, 0x03, 0x05
};
#define NUM_PM_SAVE_EXCEPTS (sizeof(PMExceptSaveList)/sizeof(PMExceptSaveList[0]))
static void __far *OrigPMExcepts[NUM_PM_SAVE_VECTS];
static void __far *SavePMExcepts[NUM_PM_SAVE_VECTS];
static enum {
IS_NONE,
IS_DPMI,
IS_RATIONAL
} IntrState = IS_NONE;
extern void DoRawSwitchToRM( unsigned, unsigned, unsigned );
#pragma aux DoRawSwitchToRM = \
"push ebp" \
"mov edx,eax" \
"mov ecx,eax" \
"mov esi,eax" \
"lea ebp,-8[esp]" \
"call pword ptr [RawPMtoRMSwitchAddr]" \
"pop ebp" \
parm caller [eax] [ebx] [edi] \
modify exact [ eax ebx ecx edx esi edi gs ];
extern void BackFromRealMode( void );
/*
We zero out the registers here so that there isn't any garbage
in the high word of them in 16-bit code. It turns out that the
Pentium sometimes uses the full 32-bit registers even
when the instruction specifies the 16-bit version (e.g string
instructions.
*/
extern void DoIntSwitchToRM( void );
#pragma aux DoIntSwitchToRM = \
"pushad", \
"xor ebp,ebp" \
"xor ebx,ebx" \
"xor esi,esi" \
"xor edi,edi" \
"xor ecx,ecx" \
"xor edx,edx" \
"xor eax,eax" \
"mov ah,6" \
"mov cx,0xffff" \
"int 1ah", \
"popad" \
modify exact [];
typedef unsigned long P1616;
typedef P1616 extension_routine( unsigned, void *, void * );
static char sig_str[] = "RATIONAL DOS/4G";
static char pkg_name[] = "D32_KERNEL";
static char pkg_entry[] = "D32NullPtrCheck";
#pragma aux extension_routine parm [eax] [edx] [ebx] value [eax];
static extension_routine __far *RSI_extensions;
/* These are static because I'm not conversant with your inline asm
facility, and this accomplished the desired result...
*/
//static void *parmp;
static P1616 _D32NullPtrCheck;
#if 0
void lookup_prep (void);
#pragma aux lookup_prep = \
"sub eax, eax" \
"mov ebx, OFFSET pkg_name" \
"mov edx, OFFSET pkg_entry"
void call_prep (void);
#pragma aux call_prep = \
"mov eax, 2" \
"mov ebx, parmp" \
"mov edx, _D32NullPtrCheck"
#endif
P1616 __cdecl find_entry( void )
{
P1616 retval = 0;
RSI_extensions = DPMIGetVenderSpecificAPI( sig_str );
if (RSI_extensions != NULL )
{
retval = RSI_extensions( 0, pkg_entry, pkg_name );
}
return (retval);
}
/* Returns 16:16 pointer to MONITOR array, describing state of hardware
breakpoints. You shouldn't care about the return value during your init.
*/
int __cdecl D32NullPtrCheck( unsigned short on )
{
static int old_state;
int old;
char buff[128];
if( _D32NullPtrCheck == NULL ) {
_D32NullPtrCheck = find_entry();
if( _D32NullPtrCheck == NULL ) return( 0 );
EnvLkup( "DOS4G", buff, sizeof( buff ) );
if( strstr( strupr( buff ), "NULLP" ) ) {
old_state = 1;
}
}
old = old_state;
if( old_state != on ) {
RSI_extensions( 2, (void *)_D32NullPtrCheck, &on );
old_state = on;
}
return (old);
}
void SaveOrigVectors( void )
{
rm_data *p;
unsigned i;
unsigned old;
#ifdef FULL_SAVE
for( i = 0; i < INT_VECT_COUNT; ++i ) PMVectSaveList[i]=i;
for( i = 0; i < EXCEPT_COUNT; ++i ) PMExceptSaveList[i]=i;
#endif
old = D32NullPtrCheck( 0 );
/* haven't moved things yet, so PMData isn't set up */
p = (rm_data *)RMDataStart;
for( i = 0; i < NUM_VECTS; ++i ) {
p->orig_vects[i].a = MyGetRMVector( i );
}
D32NullPtrCheck( old );
for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
OrigPMVects[i] = DPMIGetPMInterruptVector( PMVectSaveList[i] );
}
for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
OrigPMExcepts[i] = DPMIGetPMExceptionVector( PMExceptSaveList[i] );
}
memcpy( p->vecttable1, p->orig_vects, sizeof( p->vecttable1 ) );
memcpy( p->vecttable2, p->orig_vects, sizeof( p->vecttable2 ) );
memcpy( SavePMVects, OrigPMVects, sizeof( SavePMVects ) );
memcpy( SavePMExcepts, OrigPMExcepts, sizeof( SavePMExcepts ) );
}
void RestoreOrigVectors(void)
{
unsigned i;
unsigned old;
for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
DPMISetPMExceptionVector( PMExceptSaveList[i], OrigPMExcepts[i] );
}
for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
DPMISetPMInterruptVector( PMVectSaveList[i], OrigPMVects[i] );
}
old = D32NullPtrCheck( 0 );
for( i = 0; i < NUM_VECTS; ++i ) {
MySetRMVector( i,
PMData->orig_vects[i].s.segment,
PMData->orig_vects[i].s.offset );
}
D32NullPtrCheck( old );
}
static void GoToRealMode( void *rm_func )
{
unsigned i;
PMData->rm_func = RM_OFF( rm_func );
if( IntrState == IS_DPMI ) {
for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
DPMISetPMInterruptVector( PMVectSaveList[i], SavePMVects[i] );
}
for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
DPMISetPMExceptionVector( PMExceptSaveList[i], SavePMExcepts[i] );
}
DoRawSwitchToRM( RMData.s.rm,
offsetof( rm_data, stack )+STACK_SIZE,
RM_OFF( RawSwitchHandler ) );
for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
SavePMExcepts[i] = DPMIGetPMExceptionVector(PMExceptSaveList[i]);
DPMISetPMExceptionVector( PMExceptSaveList[i], OrigPMExcepts[i] );
}
for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
SavePMVects[i] = DPMIGetPMInterruptVector( PMVectSaveList[i] );
DPMISetPMInterruptVector( PMVectSaveList[i], OrigPMVects[i] );
}
} else {
DoIntSwitchToRM();
}
}
static uint_16 EnvAreaSize( char __far *envarea )
{
char __far *envptr;
envptr = envarea;
while( *envptr ) {
envptr += _fstrlen( envptr ) + 1;
}
return( envptr - envarea + 1 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?