Initial commit of Command & Conquer Red Alert source code.

This commit is contained in:
LFeenanEA 2025-02-27 16:15:05 +00:00
parent b685cea758
commit 5e733d5dcc
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
2082 changed files with 797727 additions and 0 deletions

590
WWFLAT32/SRCDEBUG/ALLOC.CPP Normal file
View file

@ -0,0 +1,590 @@
/*
** Command & Conquer Red Alert(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***************************************************************************
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : ALLOC.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : February 1, 1992 *
* *
* Last Update : March 9, 1995 [JLB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Alloc -- Allocates system RAM. *
* Ram_Free -- Determines the largest free chunk of RAM. *
* Free -- Free an Alloc'ed block of RAM. *
* Resize_Alloc -- Change the size of an allocated block. *
* Heap_Size -- Size of the heap we have. *
* Total_Ram_Free -- Total amount of free RAM. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#ifndef WWMEM_H
#include "wwmem.h"
#endif
extern "C" unsigned long Largest_Mem_Block ( void ) ;
//
// use double-word alignment for allocs
//
#define LONG_ALIGNMENT 1
/*
** Define the equates necessary to call a DPMI interrupt.
*/
#define DPMI_INT 0x0031
#define DPMI_LOCK_MEM 0x0600
#define DPMI_UNLOCK_MEM 0x0601
#define LOGGING FALSE
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
unsigned long MinRam=0L; // Record of least memory at worst case.
unsigned long MaxRam=0L; // Record of total allocated at worst case.
static unsigned long TotalRam = 0L;
static unsigned long Memory_Calls = 0L;
static unsigned long RequestedSystemRam = 16*1024*1024;
static unsigned long LargestRamBlock = 0L;
void (*Memory_Error)(void) = NULL;
void (*Memory_Error_Exit)(char *string) = NULL;
/***************************************************************************
* DPMI_LOCK -- handles locking a block of DPMI memory *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/23/1995 PWG : Created. *
*=========================================================================*/
#include"mono.h"
void DPMI_Lock(VOID const *ptr, long const size)
{
union REGS regs;
struct SREGS sregs;
/*
** Lock memory
** AX = 0x600
** BX:CX = starting linear address of memory to lock
** SI:DI = size of region to lock (in bytes)
** - If Failure, carry flag is set.
*/
memset (&regs, 0 ,sizeof(regs));
segread (&sregs);
regs.x.eax = DPMI_LOCK_MEM;
regs.x.ebx = ((long)ptr & 0xffff0000) >> 16;
regs.x.ecx = ((long)ptr & 0x0000ffff);
regs.x.esi = ((long)size & 0xffff0000) >> 16;
regs.x.edi = ((long)size & 0x0000ffff);
int386x (DPMI_INT, &regs, &regs, &sregs); // call DPMI
// if (regs.x.cflag) {
// }
#if(0)
char *temp = (char *)ptr;
char hold;
for (int lp = 0; lp < size; lp += 2048) {
hold = *temp;
temp += 2048;
}
#endif
}
/***************************************************************************
* DPMI_UNLOCK -- Handles unlocking a locked block of DPMI *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/23/1995 PWG : Created. *
*=========================================================================*/
void DPMI_Unlock(void const *ptr, long const size)
{
union REGS regs;
struct SREGS sregs;
/*
** Unlock the memory
*/
memset (&regs, 0 ,sizeof(regs));
segread (&sregs);
regs.x.eax = DPMI_UNLOCK_MEM; // DPMI function to call
regs.x.ebx = ((long)ptr & 0xffff0000) >> 16;
regs.x.ecx = ((long)ptr & 0x0000ffff);
regs.x.esi = ((long)size & 0xffff0000) >> 16;
regs.x.edi = ((long)size & 0x0000ffff);
int386x (DPMI_INT, &regs, &regs, &sregs); // call DPMI
// if (regs.x.cflag) {
// }
}
/***************************************************************************
* Alloc -- Allocates system RAM. *
* *
* This is the basic RAM allocation function. It is used for all *
* memory allocations needed by the system or the main program. *
* *
* INPUT: bytes_to_alloc -- LONG value of the number of bytes to alloc. *
* *
* flags -- Memory allocation control flags. *
* MEM_NORMAL: No special flags. *
* MEM_CLEAR: Zero out memory block. *
* MEM_NEW: Called by a new. *
* *
* OUTPUT: Returns with pointer to allocated block. If NULL was returned *
* it indicates a failure to allocate. Note: NULL will never be *
* returned if the standard library allocation error routine is *
* used. *
* *
* WARNINGS: If you replace the standard memory allocation error routine *
* and make it so that Alloc CAN return with a NULL, be sure *
* and check for this in your code. *
* *
* HISTORY: *
* 09/03/1991 JLB : Documented. *
* 08/09/1993 JLB : Updated with EMS memory support. *
* 04/28/1994 JAW : Updated to 32bit Protected mode. *
* 03/09/1995 JLB : Fixed *
*=========================================================================*/
void *Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags)
{
union REGS regs ;
struct SREGS sregs ;
unsigned char *retval=NULL; // Pointer to allocated block.
unsigned long original_size; // Original allocation size.
unsigned long bytesfree; // Number of free bytes.
long *longptr=NULL; // Pointer used to store selector
static unsigned char _allocinit=0;
//
// Init memory system by finding largest block to alloc
// then allocate it to get one large heap and free it.
// There may be more memory available from DPMI but we only are
// for now allocating and freeing the first largest block.
//
if ( !_allocinit ) {
unsigned long largestblock = Largest_Mem_Block();
largestblock -= 1024; // subtract for heap header and misc
largestblock &= 0xffff0000; // forcing to 64K boundary
if ( largestblock ) {
LargestRamBlock = MIN( largestblock, RequestedSystemRam );
unsigned char *lptr = (unsigned char *)malloc( LargestRamBlock );
if ( lptr ) {
free( (void *)lptr );
}
}
/*
** Initialize the total ram available value.
*/
TotalRam = Total_Ram_Free(MEM_NORMAL);
_allocinit = 1;
}
/*
** Save the original allocated space size so that we can clear the
** exact amount of RAM if they specified MEM_CLEAR.
*/
original_size = bytes_to_alloc;
/*
** Reserve one byte for the header of the memory we allocated.
** We will store the flags variable there for later use.
*/
#if (LONG_ALIGNMENT)
bytes_to_alloc += (flags & MEM_LOCK) ? 8 : 4;
#else
bytes_to_alloc += (flags & MEM_LOCK) ? 5 : 1;
#endif
// Try to allocate the memory out of the protected mode memory
// chain if we did not require a real mode allocation. If this
// fails we will have to try to allocate it out of real mode memory.
// Real mode memory is a last resort because some types of applications
// require real mode memory.
if (!(flags & MEM_REAL)) {
retval = (unsigned char*)malloc(bytes_to_alloc);
}
// Try to allocate the memory out of the real mode memory using DPMI
// service 0x100. Note that retval will be null if we are requesting
// real mode memory so that we do not have to explicitly check for the
// real mode flag. Remember we need to reserve room for the dos
// selector value at the beginning of our allocated block so rather than
// adding fifteen and rounding, we need to add 19 and round.
if (!retval) {
flags = (MemoryFlagType)(flags | MEM_REAL);
regs.x.eax = 0x100;
regs.x.ebx = (bytes_to_alloc + 19) >> 4;
if (regs.x.ebx & 0xFFFF0000) {
retval = NULL;
} else {
segread ( & sregs ) ;
int386x ( 0x31 , & regs, & regs , & sregs ) ;
if (regs.x.cflag)
retval = NULL;
else {
#if (LONG_ALIGNMENT)
longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 4);
#else
longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 1);
#endif
*longptr++ = regs.x.edx & 0xFFFF;
retval = (unsigned char *)longptr;
}
}
}
// If the alloc failed then we need to signify a memory error.
if (retval == NULL) {
if (Memory_Error != NULL)
Memory_Error();
return NULL;
}
// If the memory needs to be DPMI locked then we should store the
// original size in the header before we store the flags.
if (flags & MEM_LOCK) {
longptr = (long *)retval;
*longptr++ = original_size;
retval = (unsigned char *)longptr;
}
// Now that we know the alloc was sucessful (and for an extra byte
// more than the user wanted) we need to stick in the memory flags.
#if (LONG_ALIGNMENT)
if ( !(flags & (MEM_LOCK|MEM_REAL)) ) {
//
// WARNING!!!!!!!!!!
// USE this only with the WATCOM malloc ALLOCATION!!!!!!!!!
// it reads the actual block size before the ptr returned.
// then eors and uses the upper word for a validation later on free.
//
longptr = (long *)retval;
*longptr = ((*(longptr - 1)) ^ 0xffffffff) & 0xffff0000;
*retval++ = flags;
*retval++ = (unsigned char)(flags ^ 0xff);
retval += 2;
}
else {
*retval++ = flags;
*retval++ = (unsigned char)(flags ^ 0xff);
*retval++ = 0;
*retval++ = 0;
}
#else
*retval++ = (unsigned char)(flags | (((flags ^ 0x07) & 0x07) << 5));
#endif
// If the memory needed to be DPMI locked then set it up so it
// is locked.
if (flags & MEM_LOCK) {
DPMI_Lock(retval, original_size);
}
/* Clear the space if they wanted it clear */
if (flags & MEM_CLEAR) {
unsigned char *ptr; // Working memory block pointer.
ptr = retval;
memset(ptr, '\0', original_size);
}
bytesfree = Total_Ram_Free(MEM_NORMAL);
if (bytesfree < MinRam) {
MinRam = bytesfree;
}
if (TotalRam-bytesfree > MaxRam) {
MaxRam = TotalRam-bytesfree;
}
Memory_Calls++;
#if(LOGGING)
int val = _heapchk();
FILE *file = fopen("mem.txt","at");
fprintf(file, "%P Alloc size = %d, Actual Size = %d, flags = %d, heap = %d\n",
retval,
original_size,
bytes_to_alloc,
flags,
val);
fclose(file);
#endif
return(retval);
}
/***************************************************************************
* Free -- Free an Alloc'ed block of RAM. *
* *
* FUNCTION: *
* *
* INPUT: A pointer to a block of RAM from Alloc. *
* *
* OUTPUT: None. *
* *
* WARNINGS: Don't use this for an Alloc_Block'ed RAM block. *
* *
* HISTORY: *
* 05/25/1990 : Created. *
***************************************************************************/
void Free(void const *pointer)
{
union REGS regs ;
struct SREGS sregs ;
void const *original = pointer;
char string[80];
if (pointer) {
/*
** Get a pointer to the flags that we stored off.
*/
#if (LONG_ALIGNMENT)
unsigned char *byteptr = ((unsigned char *)pointer) - 4;
//
// validate the flags with and eor of the flags
//
if ( *byteptr != ((*(byteptr + 1)) ^ 0xff) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
else {
if ( !(*byteptr & (MEM_LOCK|MEM_REAL)) ) {
unsigned short *wordptr = (unsigned short *)(byteptr - 2);
//
// WARNING!!!!!!!!!!
// USE this only with the WATCOM malloc ALLOCATION!!!!!!!!!
// it reads the actual block size before the ptr to be freed.
// then compares with the EOR to the value stored during allocation.
//
if ( *wordptr != ((*(wordptr + 2)) ^ 0xffff) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
}
else if ( *(byteptr + 2) || *(byteptr + 3) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
}
// if ( *byteptr != (*(byteptr + 1) ^ 0xff) ||
// *(byteptr + 2) || *(byteptr + 3) ) {
// if (Memory_Error_Exit != NULL) {
// sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
// Memory_Error_Exit( string );
// }
// }
#else
unsigned char *byteptr = ((unsigned char *)pointer) - 1;
if ( (*byteptr & 0xe0) != (((*byteptr ^ 0x07) & 0x07) << 5) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
#endif
/*
** Check to see if this was locked me and if it was unlock it.
*/
if (*byteptr & MEM_LOCK) {
long *longptr = ((long *)byteptr) - 1;
DPMI_Unlock(pointer, *longptr);
pointer = (void *)longptr;
} else
pointer = (void *)byteptr;
#if(LOGGING)
int val = _heapchk();
FILE *file = fopen("mem.txt","at");
fprintf(file, "%P Free flags = %d, Heap = %d\n",
original,
*byteptr,
val);
fclose(file);
#endif
// If the pointer is a real mode pointer than it will point to the
// first megabyte of system memory. If it does than we need to
// use DPMI to free it.
if (*byteptr & MEM_REAL) {
regs.x.eax = 0x101;
regs.x.edx = *(((long *)pointer) - 1);
segread ( & sregs ) ;
int386x(0x31, &regs, &regs, &sregs);
} else {
free((void *)pointer);
}
Memory_Calls--;
}
}
/***************************************************************************
* Resize_Alloc -- Change the size of an allocated block. *
* *
* This routine will take a previously allocated block and change its *
* size without unnecessarily altering its contents. *
* *
* INPUT: pointer -- Pointer to the original memory allocation. *
* *
* new_size -- Size in bytes that it will be converted to. *
* *
* OUTPUT: Returns with a pointer to the new allocation. *
* *
* WARNINGS: ??? *
* *
* HISTORY: *
* 02/01/1992 JLB : Commented. *
*=========================================================================*/
void *Resize_Alloc(void *original_ptr, unsigned long new_size_in_bytes)
{
unsigned long *temp;
// unsigned long diff, flags;
temp = (unsigned long*)original_ptr;
/* ReAlloc the space */
temp = (unsigned long *)realloc(temp, new_size_in_bytes);
if (temp == NULL) {
if (Memory_Error != NULL)
Memory_Error();
return NULL;
}
return(temp);
}
/***************************************************************************
* Ram_Free -- Determines the largest free chunk of RAM. *
* *
* Use this routine to determine the largest free chunk of available *
* RAM for allocation. It also performs a check of the memory chain. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the size of the largest free chunk of RAM. *
* *
* WARNINGS: This does not return the TOTAL memory free, only the *
* largest free chunk. *
* *
* HISTORY: *
* 09/03/1991 JLB : Commented. *
*=========================================================================*/
long Ram_Free(MemoryFlagType)
{
return(_memmax());
// return Largest_Mem_Block();
}
/***************************************************************************
* Heap_Size -- Size of the heap we have. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
*=========================================================================*/
long Heap_Size(MemoryFlagType )
{
if (!TotalRam) {
TotalRam = Total_Ram_Free(MEM_NORMAL);
}
return(TotalRam);
}
/***************************************************************************
* Total_Ram_Free -- Total amount of free RAM. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
* 03/09/1995 JLB : Uses prerecorded heap size maximum. *
*=========================================================================*/
long Total_Ram_Free(MemoryFlagType )
{
return(_memavl());
// return Largest_Mem_Block () ;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1091
WWFLAT32/SRCDEBUG/MEM.CPP Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,184 @@
;
; Command & Conquer Red Alert(tm)
; Copyright 2025 Electronic Arts Inc.
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;***************************************************************************
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
;***************************************************************************
;* *
;* Project Name : LIBRARY *
;* *
;* File Name : MEM_COPY.ASM *
;* *
;* Programmer : Scott Bowen *
;* *
;* Last Update : September 8, 1994 [IML] *
;* Ported to watcom c32 : 01/03/96 [JRJ] *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Mem_Copy -- Copies from one pointer to another. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
LOCALS ??
;******************************************************************************
; Much testing was done to determine that only when there are 14 or more bytes
; being copied does it speed the time it takes to do copies in this algorithm.
; For this reason and because 1 and 2 byte copies crash, is the special case
; used. SKB 4/21/94. Tested on 486 66mhz.
OPTIMAL_BYTE_COPY equ 14
;******************************************************************************
; External declares so these functions can be called
;
GLOBAL Mem_Copy : NEAR
GLOBAL Largest_Mem_Block : near
CODESEG
;***************************************************************************
;* MEM_COPY -- Copies from one pointer to another. *
;* This routine copies bytes from source to dest. It takes care of *
;* overlapped memory, and unsigned long copies. *
;* *
;* *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 04/18/1994 SKB : Created. *
;*=========================================================================*
; void Mem_Copy(void *source, void *dest, unsigned long bytes_to_copy);
PROC Mem_Copy C near
USES ecx , esi , edi , ebx
ARG source:DWORD
ARG dest:DWORD
ARG bytes:DWORD
;********************************* Setup ******************************************
cld
mov esi,[source]
mov edi,[dest]
mov ecx,[bytes] ; get number of bytes to copy.
; check pointers for singularities
cmp esi,edi ; Compare source with dest.
je ??done ; No sence in copying the same pointer.
or esi,0
jz ??done
or edi,0
jz ??done
cmp ecx,OPTIMAL_BYTE_COPY ; see notes above about equate.
jge ??normal ; If >= MAX(2,OPTIMAL_BYTE_COPY), do normal dword copy.
;******************************** Special case <= 2 *******************************
;
; This section must be called for bytes <= 2 since the other case will crash. It
; optionally uses OPTIMAL_BYTE_COPY for the cut off point. This is because after
; extensive testing, it was proved that only at that point (14 or more bytes) does
; it become quicker to use the dword copy method.
cmp esi,edi ; Compare source with dest.
jge ??do_move ; if source greater do forward copy.
lea esi,[esi+ecx-1]
std ; Opps, wrong, force the pointers to decrement.
lea edi,[edi+ecx-1]
??do_move:
rep movsb ; move the one or two bytes.
cld
??done:
ret
;************************** back or forth, that is the question *******************
??normal:
mov ebx,ecx
cmp esi,edi ; Compare source with dest.
jge ??forward ; if source greater do forward copy.
;********************************* Backward ***************************************
??backward:
lea ecx,[edi+ebx]
std
lea edi,[edi+ebx-1]
and ecx,3 ; Get non aligned bytes.
lea esi,[esi+ebx-1]
sub ebx,ecx ; remove that from the total size to be copied later.
rep movsb ; do the copy.
sub esi,3
mov ecx,ebx ; Get number of bytes left.
sub edi,3
shr ecx,2 ; Do 4 bytes at a time.
rep movsd ; do the dword copy.
mov ecx,ebx
add esi,3
add edi,3
and ecx,03h
rep movsb ; finnish the remaining bytes.
cld
ret
;********************************* Forward ***************************************
??forward:
cld
mov ecx,edi ; get destination pointer.
neg ecx
and ecx,3 ; Get non aligned bytes.
sub ebx,ecx ; remove that from the total size to be copied later.
rep movsb ; do the copy.
mov ecx,ebx ; Get number of bytes left.
shr ecx,2 ; Do 4 bytes at a time.
rep movsd ; do the dword copy.
mov ecx, ebx
and ecx,03h
rep movsb ; finnish the remaining bytes.
ret
ENDP Mem_Copy
PROC Largest_Mem_Block C near
uses esi , edi , ebx , ecx , edx
local mem_struct : dword : 16
mov eax , 0500h
lea edi , [ mem_struct ]
int 31h
mov eax , [ mem_struct ]
ret
ENDP Largest_Mem_Block
END


2226
WWFLAT32/SRCDEBUG/MOUSE.ASM Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,166 @@
/*
** Command & Conquer Red Alert(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***************************************************************************
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
***************************************************************************
* *
* Project Name : Memory system. *
* *
* File Name : NEWDEL.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : June 21, 1994 *
* *
* Last Update : July 17, 1995 [PWG] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* operator NEW -- Overides the global new function. *
* operator delete -- Overides the global delete function. *
* operator NEW[] -- Overides the array version of new. *
* operator delete[] -- Overides the array version of delete[] *
* -- *
* OPERATOR NEW -- New opperator which takes a MEM_FLAG *
* OPERATOR NEW[] -- Global NEW[] which takes MEM_FLAG *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "wwmem.h"
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/***************************************************************************
* OPERATOR NEW -- Overides the global new function. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
*=========================================================================*/
void * operator new(size_t size)
{
return (Alloc((unsigned long) size, MEM_NEW));
}
/***************************************************************************
* OPERATOR NEW[] -- Overides the array version of new. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
*=========================================================================*/
void * operator new[](size_t size)
{
return (Alloc((unsigned long) size, MEM_NEW));
}
/***************************************************************************
* OPERATOR NEW -- New opperator which takes a MEM_FLAG *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/17/1995 PWG : Created. *
*=========================================================================*/
void * operator new(size_t size, MemoryFlagType flag)
{
return(Alloc(size, (MemoryFlagType)(flag|MEM_NEW)));
}
/***************************************************************************
* OPERATOR NEW[] -- Global NEW[] which takes MEM_FLAG *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/17/1995 PWG : Created. *
*=========================================================================*/
void * operator new[] (size_t size, MemoryFlagType flag)
{
return(Alloc(size, (MemoryFlagType)(flag|MEM_NEW)));
}
/***************************************************************************
* OPERATOR DELETE -- Overides the global delete function. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
*=========================================================================*/
void operator delete(void *ptr)
{
Free(ptr);
}
/***************************************************************************
* OPERATOR DELETE[] -- Overides the array version of delete[] *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/20/1994 SKB : Created. *
*=========================================================================*/
void operator delete[](void *ptr)
{
Free(ptr);
}

View file

@ -0,0 +1,153 @@
;
; Command & Conquer Red Alert(tm)
; Copyright 2025 Electronic Arts Inc.
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;***************************************************************************
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
;***************************************************************************
;* *
;* Project Name : Library *
;* *
;* File Name : PAGFAULT.ASM *
;* *
;* Programmer : Julio R Jerez *
;* *
;* Date : April 25,1995 *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;
; Here are prototypes for the routines defined within this module:
; VOID Install_Page_Fault_Handle (void) ;
;
; ----------------------------------------------------------------
IDEAL ; the product runs in ideal mode
P386 ; use 386 real mode instructions
MODEL USE32 FLAT
LOCALS ?? ; ?? is the symbol for a local
WARN ; generate all warnings we can
JUMPS ; optimize jumps if possible
;---------------------------------------------------------------------------
; Make some general equates for easy compatability
;---------------------------------------------------------------------------
DPMI_INTR EQU 31h
PAGE_FAULT equ 0eh
RESET_VIDEO_MODE equ -1
GLOBAL Install_Page_Fault_Handle : NEAR
GLOBAL Set_Video_Mode : NEAR
GLOBAL Remove_Mouse : NEAR
GLOBAL Remove_Keyboard_Interrupt : NEAR
GLOBAL Remove_Timer_Interrupt : NEAR
DATASEG
Old_Page_Fault_handle DF ?
Page_Fault_SS DD ?
Page_Fault_ESP DD ?
CODESEG
;***************************************************************************
;* INSTALL_PAGE_FAULT_HANDLE -- Installs new page fault handle *
;* This function will install a new page fault handle *
;* so in the event that we have a program crash thi handle will *
;* remove all interrupts and then will chain to the default Page *
;* Fault handle *
;* *
;* INPUT: none *
;* *
;* *
;* OUTPUT: none *
;* *
;* PROTO: VOID Install_Page_Fault_Handle( void); *
;* *
;* HISTORY: 04/25/96 Created *
;*=========================================================================*
PROC Install_Page_Fault_Handle C NEAR
USES eax,ebx,ecx,edx,esi,edi
mov eax,0202h ; get address of exception handle
mov bl,PAGE_FAULT
int DPMI_INTR
jc ??exit ; not action is taken
; save addrees of default handle
mov [dword ptr Old_Page_Fault_handle],edx
mov [word ptr Old_Page_Fault_handle+4],cx
; redirect default handle to a new Page Fault Handle
mov eax,0203h
mov bl,PAGE_FAULT
mov cx,cs
lea edx,[Page_Fault_Handle]
int DPMI_INTR
??exit:
ret
ENDP Install_Page_Fault_Handle
;***************************************************************************
;* PAGE_FAULT_HANDLE -- This *
;* *
;* *
;* *
;* HISTORY: 04/25/96 Created *
;*=========================================================================*
PROC Page_Fault_Handle far
; preserve used registers
push eax
push ebx
; save Page Fault satck frame
mov ax,ss
mov [Page_Fault_SS],eax
mov [Page_Fault_ESP],esp
; retrieve application original stack frame
mov eax , [ esp + ( 6 + 2 ) * 4 ]
mov ebx , [ esp + ( 7 + 2 ) * 4 ]
mov ss , bx
mov esp , eax
; set video mode to standard text mode
push RESET_VIDEO_MODE
call Set_Video_Mode
pop eax
call Remove_Mouse
call Remove_Keyboard_Interrupt
call Remove_Timer_Interrupt
; restore Page Fault stack frame
mov eax,[Page_Fault_SS]
mov ss , ax
mov esp, [Page_Fault_ESP]
; restore used registers and chain to default Page Fault Handle
pop ebx
pop eax
jmp [fword Old_Page_Fault_handle]
ENDP Page_Fault_Handle
;***************************************************************************
;* End of File. *
;***************************************************************************
END