ovlboth.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 275 行
C
275 行
/****************************************************************************
*
* 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: overlay routines used by both overlaying schemes.
*
****************************************************************************/
#include <dos.h>
#include <stddef.h>
#include <string.h>
#include "ovlstd.h"
extern void near __OvlMsg__( unsigned int msg )
//=============================================
// Write message.
{
char far * ptr;
ptr = __OVLMSGS__[ msg ];
TinyWrite( TIO_STDERR_FILENO, ptr + sizeof( char ), *ptr );
}
extern void near __OvlExit__( unsigned int msg )
//==============================================
// Terminate execution.
{
__OvlMsg__( msg );
TinyTerminateProcess( -1 );
}
void near __OvlCodeLoad__( ovltab_entry far *ovl, tiny_handle_t fp )
//==================================================================
// Load code portion of section.
{
unsigned int block_size; // number of paragraphs
unsigned int code_size; // number of paragraphs
tiny_ret_t status;
unsigned int load_seg;
load_seg = ovl->code_handle;
code_size = ovl->num_paras;
for(;;) {
if( code_size == 0 ) break;
block_size = 0x0fff;
if( code_size < 0x0fff ) {
block_size = code_size;
}
status = __OvlRead__( fp, MK_FP( load_seg, 0 ), block_size << 4 );
if( TINY_ERROR( status ) ) __OvlExit__( OVL_IO_ERR );
load_seg += block_size;
code_size -= block_size;
}
}
#define RELOC_CAPACITY 32
int near __OvlRelocLoad__( ovltab_entry far *ovl, tiny_handle_t fp )
//==================================================================
// Relocate section code; returns 1 if section is self-referential.
{
unsigned int buffered_relocs;
unsigned int num_relocs;
int self_ref = 0;
dos_addr far * relocs;
dos_addr reloc_buffer[ RELOC_CAPACITY ];
unsigned int far * fixup;
tiny_ret_t status;
num_relocs = ovl->relocs;
for(;;) {
if( num_relocs == 0 ) break;
buffered_relocs = RELOC_CAPACITY;
if( num_relocs < RELOC_CAPACITY ) {
buffered_relocs = num_relocs;
}
relocs = reloc_buffer;
status = __OvlRead__( fp, relocs, buffered_relocs * sizeof(dos_addr) );
if( TINY_ERROR( status ) ) __OvlExit__( OVL_IO_ERR );
num_relocs -= buffered_relocs;
while( buffered_relocs != 0 ) {
fixup = MK_FP( ovl->code_handle + relocs->seg, relocs->off );
if( (unsigned)(*fixup - ovl->start_para) < ovl->num_paras ) {
self_ref = 1;
*fixup += (ovl->code_handle - ovl->start_para);
} else {
*fixup += __OVLTAB__.prolog.delta;
}
relocs++;
buffered_relocs--;
}
}
return self_ref;
}
// Maximum size of a filename allowed here.
#define FNMAX 80
#ifdef OVL_DEBUG
extern void near __OvlNum__( unsigned int ovl_num )
//=================================================
// Write overlay number.
{
char buff[ 4 ]; // assume overlay number < 9999
int len;
int power;
len = 0;
power = 1000;
while( power > 0 ) {
buff[ len ] = '0' + ovl_num / power;
len++;
ovl_num = ovl_num - ( ovl_num / power ) * power;
power /= 10;
}
TinyWrite( TIO_STDERR_FILENO, &buff, len );
}
#endif
static char far * getpathenv( void )
/**********************************/
/* get the PATH environment variable */
{
char far * ptr;
ptr = MK_FP( *(unsigned int far *)MK_FP( __OVLPSP__, 0x2c ), 0 );
for( ;; ) {
if( ptr[0] == 'P'
&& ptr[1] == 'A'
&& ptr[2] == 'T'
&& ptr[3] == 'H'
&& ptr[4] == '=' ) return( ptr + 5 );
for( ; *ptr != 0; ++ptr )
{}
if( *++ptr == 0 ) return( __OVLNULLSTR__ );
}
}
extern void far __CloseOvl__( void )
//==================================
{
if( __OVLFILEPREV__ != 0xFFFF ) {
__OvlClose__( TINY_INFO( __OVLHDLPREV__ ) );
__OVLFILEPREV__ = 0xFFFF;
}
}
extern tiny_ret_t near __OpenOvl__( unsigned int offset )
//=======================================================
// Open section file.
{
char far * fname;
char far * cmd;
char chr;
char far * lastslash;
char far * fnstart;
char far * path;
char buf[ FNMAX ];
tiny_ret_t status;
unsigned isexe;
if( offset == __OVLFILEPREV__ ) {
status = __OVLHDLPREV__;
} else {
__CloseOvl__();
__OVLFILEPREV__ = offset;
isexe = offset & OVE_EXE_FILENAME;
offset &= ~OVE_EXE_FILENAME;
fname = (( char * )(&__OVLTAB__)) + offset;
// strip drive/directory from fname
for( fnstart = fname; *fnstart != 0; ++fnstart ) {
switch( *fnstart ) {
case '\\':
case '/':
case ':':
fname = fnstart + 1;
break;
}
}
if( __OVLFLAGS__ & OVL_DOS3 ) {
cmd = MK_FP( *( unsigned int far * )MK_FP(__OVLPSP__, 0x002c), 0x0000 );
for(;;) { // go through environment to find path of .EXE file.
for(;;) {
chr = *cmd;
cmd++;
if( chr == 0x00 ) break;
}
chr = *cmd;
cmd++;
if( chr == 0x00 ) break;
}
cmd += 2;
// now replace executable name with fname.
fnstart = buf;
lastslash = 0;
while( *cmd != '\0' ) {
chr = *cmd++;
*fnstart++ = chr;
if( chr == '\\'
|| chr == '/'
|| chr == ':' ) {
lastslash = cmd; // NOTE: this points to the char after.
} else if( chr == '\0' ) {
break;
}
}
if( isexe ) {
*fnstart = '\0';
fnstart = buf; // use the specified filename
} else if( lastslash == 0 ) { //no path
fnstart = fname;
} else {
fnstart -= cmd - lastslash;
cmd = fname;
while( *cmd != '\0' ) {
*fnstart++ = *cmd++;
}
*fnstart = '\0';
fnstart = buf;
}
} else {
fnstart = fname;
}
path = getpathenv();
for( ;; ) {
status = __OvlOpen__( fnstart );
if( TINY_OK( status ) ) break;
if( *path == 0 ) break;
cmd = buf;
for( ; *path != ';' && *path != 0; ) {
*cmd++ = *path++;
}
if( *path == ';' ) ++path;
if( cmd > buf && cmd[-1] != ':' && cmd[-1] != '\\'
&& cmd[-1] != '/' ) *cmd++ = '\\';
fnstart = fname;
for( ;; ) {
*cmd = *fnstart;
if( *cmd == 0 ) break;
++cmd;
++fnstart;
}
fnstart = buf;
}
__OVLHDLPREV__ = status;
}
return( status );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?