fcbxmem.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 273 行

C
273
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdio.h>
#include <stddef.h>
#include "vi.h"

#ifndef NOXTD

#include "dosx.h"
#include "xmem.h"
#include "fcbmem.h"

extern void interrupt XMemIntHandler( volatile union INTPACK r );

static descriptor GDT[] = {
{ 0, 0, 0 },    /* dummy segment */
{ 0, 0, 0 },    /* data segment */
{ 0, 0, 0 },    /* source segment */
{ 0, 0, 0 },    /* target segment */
{ 0, 0, 0 },    /* BIOS code segment */
{ 0, 0, 0 }     /* stack segment */
};

xtd_struct XMemCtrl;

static void xmemWrite( long , void *, unsigned );
static void xmemRead( long , void *, unsigned );
static bool checkVDISK( flat_address * );

/*
 * SwapToExtendedMemory - move an fcb to extended memory from memory
 */
int SwapToExtendedMemory( fcb *fb )
{
    long        addr;
    int         len;

    if( !XMemCtrl.inuse ) {
        return( ERR_NO_EXTENDED_MEMORY );
    }

    /*
     * dump the fcb
     */
    if( !GetNewBlock( &addr, XMemBlocks, XMemBlockArraySize )) {
        return( ERR_NO_EXTENDED_MEMORY );
    }
    XMemCtrl.allocated++;
    addr += XMemCtrl.offset;
    len = MakeWriteBlock( fb );
    xmemWrite( addr, WriteBuffer, len );

    /*
     * finish up
     */
    fb->xmemaddr = addr;
    fb->in_extended_memory = TRUE;
    return( ERR_NO_ERR );

} /* SwapToExtendedMemory */

/*
 * SwapToMemoryFromExtendedMemory - bring data back from extended memory
 */
int SwapToMemoryFromExtendedMemory( fcb *fb )
{
    int len;

    len = FcbSize( fb );
    xmemRead( fb->xmemaddr, ReadBuffer, len );
    GiveBackXMemBlock( fb->xmemaddr );

    return( RestoreToNormalMemory( fb, len ) );

} /* SwapToMemoryFromExtendedMemory */

/*
 * XMemInit - initialize extended memory
 */
void XMemInit( void )
{
    long        blocks,rc;
    int         j,i,extra;
    U_INT       amount;

    /*
     * init
     */
    XMemCtrl.inuse = FALSE;
    if( !EditFlags.ExtendedMemory ) {
        return;
    }

    /*
     * get amount of extended memory out there
     */
    checkVDISK( &XMemCtrl.offset );
    rc = _XtdGetSize();
    if( rc < 0 ) {
        return;
    }

    amount = rc;
    if( amount <= 16 ) return;      /* to allow for ibm cache bug */
    amount -= 16;

    XMemCtrl.amount_left = (((unsigned long)amount)*1024 +
                    XMEM_MEMORY_START ) - XMemCtrl.offset;
    if( XMemCtrl.amount_left <= 0 ) {
        return;
    }

    XMemCtrl.xtd_vector = DosGetVect( XMEM_INTERRUPT );
    DosSetVect( XMEM_INTERRUPT, XMemIntHandler );
    XMemCtrl.inuse = TRUE;

    /*
     * build allocation blocks
     */
    blocks = XMemCtrl.amount_left / (long) MAX_IO_BUFFER;
    XMemBlockArraySize = (int) (blocks >> 3);
    extra = (int) (blocks - ((long) (XMemBlockArraySize) << 3));
    if( extra > 0 ) {
        XMemBlockArraySize++;
    }
    XMemBlocks = MemAlloc( XMemBlockArraySize+1 );
    for( i=0;i< XMemBlockArraySize;i++ ) {
        XMemBlocks[i] = 0xff;
    }

    /*
     * if we have extra blocks, add them to the last entry
     */
    if( extra > 0 ) {
        j = 0x80;
        i = j;
        while( --extra > 0 ) {
            j >>= 1;
            i |= j;
        }
        XMemBlocks[ XMemBlockArraySize-1] = (char) i;
    }

    XMemCtrl.allocated = 0;

} /* XMemInit */

/*
 * XMemFini - finish up with extended memory
 */
void XMemFini( void )
{
    void        *verify;

    if( !XMemCtrl.inuse ) {
        return;
    }
    verify = DosGetVect( XMEM_INTERRUPT );
    if( verify != XMemIntHandler ) {
        if( verify == XMemCtrl.xtd_vector ) {
            return;
        }
    }
    DosSetVect( XMEM_INTERRUPT, XMemCtrl.xtd_vector );
    XMemCtrl.inuse = FALSE;

} /* XMemFini */

/*
 * xmemRead - read from extended memory
 */
static void xmemRead( long addr, void *buff, unsigned size )
{
    flat_address        source,target;

    size = (size+1) & ~1;
    source = addr;
    GDT[ GDT_SOURCE ].address = GDT_RW_DATA | source;
    GDT[ GDT_SOURCE ].length = size;
    target = MAKE_LINEAR( buff );
    GDT[ GDT_TARGET ].address = GDT_RW_DATA | target;
    GDT[ GDT_TARGET ].length = size;

    _XtdMoveMemory( &GDT, size >> 1 );

} /* xmemRead */

/*
 * xmemWrite - write to extended memory
 */
static void xmemWrite( long addr, void *buff, unsigned size )
{
    flat_address        source,target;

    size = (size+1) & ~1;
    target = addr;
    GDT[ GDT_TARGET ].address = GDT_RW_DATA | target;
    GDT[ GDT_TARGET ].length = size;
    source = MAKE_LINEAR( buff );
    GDT[ GDT_SOURCE ].address = GDT_RW_DATA | source;
    GDT[ GDT_SOURCE ].length = size;

    _XtdMoveMemory( &GDT, size >> 1 );

} /* xmemWrite */

/*
 * checkVDISK - test for resident vdisk
 */
static bool checkVDISK( flat_address *start )
{
    int                 i;
    void                *value;
    char                *name;
    flat_address        *avail;
    static char _vdisk[] = "VDISK  V";

    *start = XMEM_MEMORY_START;
    value = DosGetVect( VDISK_INTERRUPT );
    name = MK_FP( FP_SEG( value ), VDISK_NAME_OFFSET );
    for( i=0;i<=7;i++ ) {
        if( name[i] != _vdisk[i] ) {
            return( FALSE );
        }
    }
    avail = MK_FP( FP_SEG( value ), VDISK_AVAIL_OFFSET );
    *start = *avail & GDT_ADDR;
    return( TRUE );

} /* checkVDISK */

/*
 * GiveBackXMemBlock - return some extended memory
 */
void GiveBackXMemBlock( long addr )
{

    GiveBackBlock( addr - XMemCtrl.offset, XMemBlocks );
    XMemCtrl.allocated--;

} /* GiveBackXMemBlock */
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?