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
2082 changed files with 797727 additions and 0 deletions

594
LAUNCH/LAUNCH.ASM Normal file
View File

@@ -0,0 +1,594 @@
;
; 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 : Command & Conquer -- launcher program *
;* *
;* File Name : launch.asm *
;* *
;* Programmer : Steve Tall *
;* *
;* Start Date : August 19, 1995 *
;* *
;* Last Update : Modified for RA, October 14th, 1996 [ST] *
;* *
;* Build : Compile and link with MASM 6 *
;* Note that masm will complain there is no stack because *
;* we are not using a simplified segment model *
;* *
;*---------------------------------------------------------------------------------------------*
;* Functions: *
;* Start -- Program entry point *
;* Mem_Error -- report an out of memory error (not a function) *
;* Disc_Error -- report an out of disk space error (not a function) *
;* Delete_Swaps -- Deletes old swap files from the game directory *
;* Setup_Environment -- Adds environment strings required for DOS4G professional *
;* *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
TITLE "Red Alert launcher"
.386
;----------------------------------------------------------------------------------------------
; Defines for DOS system functions.
;
DOS_LOAD_AND_EXEC =4B00H
DOS_ALLOC =48H
DOS_FREE =49h
DOS_GET_FREE_DISC_SPACE =36H
DOS_SET_DIRECTORY =3BH
DOS =21H
DOS_SET_DTA =1AH
DOS_FIND_FIRST =4EH
DOS_FIND_NEXT =4FH
DOS_DELETE_FILE =41H
DOS_SET_ATTRIBUTES =43H
DOS_SET_DRIVE =0EH
DOS_RESIZE_ALLOCATION =4Ah
DOS_EXIT =4ch
DOS_PRINT_STRING =9
;----------------------------------------------------------------------------------------------
; Defines for keyboard BIOS functions
;
KEYBOARD_BIOS =16h
BIOS_CHECK_KEYBOARD =11h
BIOS_GET_KEYSTROKE =10h
;----------------------------------------------------------------------------------------------
; Defines for video bios functions
;
VIDEO_BIOS =10h
BIOS_SET_VIDEO_MODE_3 =0003h
;----------------------------------------------------------------------------------------------
; Misc defines
;
MEM_REQUIRED =1024 * 400 ;Check for 400k low memory
INIT_FREE_DISK_SPACE =15*1024*1024 ;C&C requirement for disc space
MY_ALLOCATION =1536/16 ;only allow myself 1.5k to run in incl. psp and stack
;you can find out how much space the program needs
;by running WDISASM LAUNCH.OBJ
;dont forget to add 256 bytes on for the psp
include <pcmacro.16>
;----------------------------------------------------------------------------------------------
; Simplified segment models are for wimmin
;
; We want 32 bit instructions in a 16 bit segment
;
_code segment para public use16 'code'
assume ds:_data
assume es:_data
assume ss:_data
assume cs:_code
;*************************************************************************************************
;* Start -- Program entry point *
;* *
;* *
;* INPUT: nothing *
;* *
;* OUTPUT: DOS return code from spawning the game *
;* *
;* HISTORY: *
;* 08/19/95 ST: Created. *
;*===============================================================================================*
Start: ;
; Set up the segments and the stack pointer
;
cli
mov ax,_data
mov ds,ax
mov [Psp],es
mov ss,ax
mov sp,offset MyStack
sti
;
; Modify the starting memory allocation to free enough for the game proper
;
save ax
mov bx,MY_ALLOCATION
mov ah,DOS_RESIZE_ALLOCATION
int DOS
restore ax
bcs Mem_Error
;
; See if we have enough free memory to launch
;
mov ah,DOS_ALLOC
mov bx,-1 ;I want it all! hahaha
int DOS
jnc Mem_Error ;shouldnt ever succeed but...
cmp ax,8
jnz Mem_Error
cmp bx,(MEM_REQUIRED/16)-MY_ALLOCATION
bls Mem_Error ;oh dear
;
; See if there is enough free disc space to launch
;
xor dl,dl
mov ah,DOS_GET_FREE_DISC_SPACE
int DOS
; dos get free disc space returns with the following
; ax - sectors per cluster
; bx - number of available clusters
; cx - bytes per sector
; dx - cluster on the drive
mul bx ;clusters avail*sectors per cluster
shl edx,16
mov dx,ax
mov eax,edx
and ecx,65535
mul ecx ;*bytes per sector
cmp eax,INIT_FREE_DISK_SPACE
blo Disc_Error
;
; Get the directory we were run from and cd to it
;
mov es,[Psp]
mov bx,2ch
mov es,es:[bx] ;es points to env
xor di,di
xor al,al
mov cx,-1
;
; Search for 0,0 as that aways terminates the environment block
;
@@again: repnz scasb
cmp_b es:[di],al
jnz @@again
lea si,[di+3] ;skip length word and second zero
;
; Copy the directory name to temporary workspace
;
mov di,si
mov cx,-1
repnz scasb
neg cx
mov bx,cx
mov cx,-1
std
mov al,'\'
repnz scasb
neg cx
sub bx,cx
mov cx,bx
inc cx
cld
mov di,offset Dta
push ds
mov ax,es
mov bx,ds
mov es,bx
mov ds,ax
rep movsb
xor al,al
stosb
pop ds
;
; Actually set the drive and path
;
mov dl,[Dta]
sub dl,'A'
mov ah,DOS_SET_DRIVE
int DOS
mov dx,offset Dta
mov ah,DOS_SET_DIRECTORY
int DOS
;
; Delete all the old swap files
;
mov dx,offset Dta
mov ah,DOS_SET_DTA
int DOS
call Delete_Swaps
;
; Add in the environment strings required for DOS4G professional
;
call Setup_Environment
;
; Set up the parameters to launch c&c
;
mov es,[Psp]
mov dx,offset GameName
mov bx,offset GameParameterBlock
mov ax,[EnvironmentSegment] ;Initialised by Setup_Environment
mov_w [bx],ax ;ptr to environment
;
; just pass the command tail we got straight through
;
mov ax,80h
mov [bx+2],ax ;offset of command tail
mov ax,[Psp]
mov [bx+4],ax ;segment of command tail
mov es,ax
mov ax,es:[2ch]
mov [bx+8],ax ;segment of first fcb
mov [bx+12],ax ;segment of second fcb
mov ax,_data
mov es,ax
;
; Run the main game program
;
mov ax,DOS_LOAD_AND_EXEC ;load and execute program
int DOS
;
; Restore teh environment memory
;
mov ax,[EnvironmentSegment]
test ax,ax
jz @@no_free
mov es,ax
mov ah,DOS_FREE
int DOS
@@no_free: ;
; Quit to DOS
;
mov ah,DOS_EXIT
int DOS
;*************************************************************************************************
;* Mem_Error -- Print a memory error message and quit *
;* *
;* *
;* INPUT: nothing *
;* *
;* OUTPUT: undefined *
;* *
;* HISTORY: *
;* 08/19/95 ST: Created. *
;*===============================================================================================*
Mem_Error: mov ax,BIOS_SET_VIDEO_MODE_3
int VIDEO_BIOS
mov dx,offset MemErrorTxt
mov ah,DOS_PRINT_STRING
int DOS
mov dx,offset MoreInfoTxt
Error_In: mov ah,DOS_PRINT_STRING
int DOS
;
; wait for keypress
;
nochar: mov ah,BIOS_CHECK_KEYBOARD
int KEYBOARD_BIOS
beq nochar
;
; get the ket out of the buffer
;
mov ah,BIOS_GET_KEYSTROKE
int KEYBOARD_BIOS
;
; Quit to DOS
;
mov ah,DOS_EXIT
int DOS
;*************************************************************************************************
;* Disc_Error -- Prints a disk error message and exits *
;* *
;* *
;* INPUT: nothing *
;* *
;* OUTPUT: DOS return code from spawning the game *
;* *
;* HISTORY: *
;* 08/19/95 ST: Created. *
;*===============================================================================================*
Disc_Error: mov ax,BIOS_SET_VIDEO_MODE_3
int VIDEO_BIOS
mov dx,offset DiscErrorTxt
jmp Error_In
;*************************************************************************************************
;* Setup_Environment -- Create a new environment block with the set DOS4GVM= stuff *
;* *
;* *
;* INPUT: nothing *
;* *
;* OUTPUT: nothing *
;* *
;* Note: Modifies the global variable 'EnvironmentStrings' to point to the start of our new *
;* environment block. This memory will need to be freed later. *
;* *
;* HISTORY: *
;* 10/14/96 ST: Created. *
;*===============================================================================================*
Setup_Environment proc near
;
; Point to default environment.
;
mov [EnvironmentSegment],0
;
; Get the address of our environment block into es
;
mov es,[Psp]
mov bx,2ch
mov es,es:[bx] ;es points to env
;
; Search for the end of the block to get its length
;
xor di,di
xor al,al
mov cx,-1
@@search: repnz scasb
cmp_b es:[di],al
jnz @@search
;
; di is length of environment block
;
lea bx,[di+256] ; a little extra to be sure.
;
; Allocate memory for a copy of the environment.
;
push di
mov ah,DOS_ALLOC
shr bx,4 ;needs to be number of paragraphs
int DOS
jnc @@ok
;
; Oops. Not enough memory. We are screwed so just exit.
;
pop di
jmp @@out
@@ok: ;
; Save the pointer to our new environment
; We can also use this to free the memory later
;
mov [EnvironmentSegment],ax
;
; Copy the original environment to the newly alloced memory
;
mov es,ax
pop cx ; size to copy
push ds
mov ds,[Psp]
mov bx,2ch
mov ds,ds:[bx] ;ds points to original environment
xor si,si
xor di,di
rep movsb
pop ds
mov si,offset Dos4gEnvironment
@@copy_loop: lodsb
stosb
test al,al
jnz @@copy_loop
;
; Copy the final zero. The environment must be terminated by 2 zeros.
;
movsb
@@out: ret
Setup_Environment endp
;*************************************************************************************************
;* Delete_Swaps -- Delete any swap files left over from a previous game *
;* *
;* *
;* INPUT: nothing *
;* *
;* OUTPUT: nothing *
;* *
;* HISTORY: *
;* 08/19/95 ST: Created. *
;*===============================================================================================*
Delete_Swaps proc near
;
; Use 'Find first/next' to find the swap files
;
mov dx,offset SwapName
mov cx,7 ;attributes
mov ah,DOS_FIND_FIRST
int DOS
bcs @@out ;no matching files
;
; Make sure it isn't read only
;
@@loop: mov dx,offset Dta+1eh
mov ah,DOS_SET_ATTRIBUTES
mov al,1
xor cx,cx ;attributes
int DOS
;
; Delete the file
;
mov dx,offset Dta+1eh
mov ah,DOS_DELETE_FILE
int DOS
;
; Find the next one
;
mov ah,DOS_FIND_NEXT
int DOS
bcc @@loop
@@out: ret
Delete_Swaps endp
_code ends ;end of code segment
;----------------------------------------------------------------------------------------------
;
; Complex data segment
;
;
_data segment dword public use16 'data'
EnvironmentSegment dw 0 ;ptr to environment to pass to child process
Psp dw 0 ;segment addr of program segment prefix
GameParameterBlock db 16h dup (0) ;required parameters for DOS launch
GameName db "GAME.DAT",0 ;this is the name of the app to be spawned
SwapName db "*.SWP",0 ;swap files always have a .SWP extension
;
; Environment to be set for DOS4G professional
;
Dos4gEnvironment db "DOS4GVM=SwapMin:12M,SwapInc:0",0,0
;
; Error and warning messages
;
MemErrorTxt db "Warning - There is very little free conventional DOS memory in the system.",13,10,"$"
DiscErrorTxt db "Error - insufficient disk space to run Red Alert."
db 13,10,"Red Alert requires 15,728,640 bytes of free disk space.",13,10 ;this string will
;run into the next because
;there is no '$'
MoreInfoTxt db "Please read the Red Alert manual for more information.",13,10,13,10
db "Press a key to continue.",13,10,"$"
Dta db 128 dup (0) ;enough for complete path
;*************************************************************
;
; The stack
;
StackSpace db 256 dup (0) ;256 byte stack!
MyStack label byte ;The stack starts here and grows down.
EndCode label byte ;The end of the data segment
_data ends
end Start

778
LAUNCH/PCMACRO.16 Normal file
View File

@@ -0,0 +1,778 @@
;
; 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/>.
;
;$e:\ifil\pcmacro.inc
;- 16-5-1991 at 10:55:13 by mike
;- 16-5-1991 at 08:30:30 by mike
;- 3-5-1991 at 15:39:52 by mike
SUBTTL PCMACRO.INC
.xlist
saveall macro
save ax,bx,cx,dx,bp,si,di,es,ds
endm
restall macro
restore ax,bx,cx,dx,bp,si,di,es,ds
endm
save macro r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14
IFNB <r0>
push r0
save r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14
ENDIF
endm
restore macro r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14
IFNB <r14>
pop r14
ENDIF
IFNB <r13>
pop r13
ENDIF
IFNB <r12>
pop r12
ENDIF
IFNB <r11>
pop r11
ENDIF
IFNB <r10>
pop r10
ENDIF
IFNB <r9>
pop r9
ENDIF
IFNB <r8>
pop r8
ENDIF
IFNB <r7>
pop r7
ENDIF
IFNB <r6>
pop r6
ENDIF
IFNB <r5>
pop r5
ENDIF
IFNB <r4>
pop r4
ENDIF
IFNB <r3>
pop r3
ENDIF
IFNB <r2>
pop r2
ENDIF
IFNB <r1>
pop r1
ENDIF
IFNB <r0>
pop r0
ENDIF
endm
bhi macro lab
ja lab
endm
bls macro lab
jbe lab
endm
bcc macro lab
jnc lab
endm
bcs macro lab
jc lab
endm
bhs macro lab
jnc lab
endm
blo macro lab
jc lab
endm
bne macro lab
jne lab
endm
beq macro lab
je lab
endm
bpl macro lab
jns lab
endm
bmi macro lab
js lab
endm
bge macro lab
jge lab
endm
blt macro lab
jl lab
endm
bgt macro lab
jg lab
endm
ble macro lab
jle lab
endm
bra macro lab
jmp lab
endm
bhis macro lab
ja lab
endm
blss macro lab
jbe lab
endm
bccs macro lab
jnc lab
endm
bcss macro lab
jc lab
endm
bnes macro lab
jne lab
endm
beqs macro lab
je lab
endm
bpls macro lab
jns lab
endm
bmis macro lab
js lab
endm
bges macro lab
jge lab
endm
blts macro lab
jl lab
endm
bgts macro lab
jg lab
endm
bles macro lab
jle lab
endm
bras macro lab
jmp lab
endm
tstb macro e1
IFIDN <e1>,<al>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bp>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<ah>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bl>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bh>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<cl>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<ch>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<dl>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<dh>
or e1,e1
EXITM
ENDIF
cmp BYTE PTR e1,0
endm
tstw macro e1
IFIDN <e1>,<ax>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bx>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<cx>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<dx>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bp>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<si>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<di>
or e1,e1
EXITM
ENDIF
cmp WORD PTR e1,0
endm
tst macro e1
IFIDN <e1>,<ax>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bx>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<cx>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<dx>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bp>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<si>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<di>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<al>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bl>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<cl>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<dl>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<ah>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<bh>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<ch>
or e1,e1
EXITM
ENDIF
IFIDN <e1>,<dh>
or e1,e1
EXITM
ENDIF
cmp e1,0
endm
clear macro first
xor first,first
endm
rts macro
ret
endm
bclrb macro e1,e2
btstb e1,e2
pushf
bclrb_sub e1,e2
popf
endm
bclrb_sub macro e1,e2
IFIDN <e1>,<al>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<bp>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<ah>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<bl>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<bh>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<cl>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<ch>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<dl>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
IFIDN <e1>,<dh>
and e1,NOT ( 1 SHL e2 )
EXITM
ENDIF
and BYTE PTR e1,NOT ( 1 SHL e2 )
endm
bsetb macro e1,e2
btstb e1,e2
pushf
or BYTE PTR e1,1 SHL e2
popf
endm
bchgb macro e1,e2
btstb e1,e2
pushf
xor BYTE PTR e1,1 SHL e2
popf
endm
mov_b macro label,label2
mov byte ptr label,byte ptr label2
endm
mov_w macro label,label2
mov word ptr label,word ptr label2
endm
mov_d macro label,label2
mov dword ptr label,dword ptr label2
endm
cmp_b macro label,label2
cmp byte ptr label,byte ptr label2
endm
cmp_w macro label,label2
cmp word ptr label,word ptr label2
endm
cmp_d macro label,label2
cmp dword ptr label,dword ptr label2
endm
add_b macro label,label2
add byte ptr label,byte ptr label2
endm
add_w macro label,label2
add word ptr label,word ptr label2
endm
add_d macro label,label2
add dword ptr label,dword ptr label2
endm
sub_b macro label,label2
sub byte ptr label,byte ptr label2
endm
sub_w macro label,label2
sub word ptr label,word ptr label2
endm
sub_d macro label,label2
sub dword ptr label,dword ptr label2
endm
or_b macro label,label2
or byte ptr label,byte ptr label2
endm
or_w macro label,label2
or word ptr label,word ptr label2
endm
or_d macro label,label2
or dword ptr label,dword ptr label2
endm
xor_b macro label,label2
xor byte ptr label,byte ptr label2
endm
xor_w macro label,label2
xor word ptr label,word ptr label2
endm
xor_d macro label,label2
xor dword ptr label,dword ptr label2
endm
eor_b macro label,label2
xor byte ptr label,byte ptr label2
endm
eor_w macro label,label2
xor word ptr label,word ptr label2
endm
eor_d macro label,label2
xor dword ptr label,dword ptr label2
endm
and_b macro label,label2
and byte ptr label,byte ptr label2
endm
and_w macro label,label2
and word ptr label,word ptr label2
endm
and_d macro label,label2
and dword ptr label,dword ptr label2
endm
test_b macro label,label2
test byte ptr label,byte ptr label2
endm
test_w macro label,label2
test word ptr label,word ptr label2
endm
test_d macro label,label2
test dword ptr label,dword ptr label2
endm
shr_b macro label,label2
shr byte ptr label,label2
endm
shr_w macro label,label2
shr word ptr label,label2
endm
shr_d macro label,label2
shr dword ptr label,label2
endm
shl_b macro label,label2
shl byte ptr label,label2
endm
shl_w macro label,label2
shl word ptr label,label2
endm
shl_d macro label,label2
shl dword ptr label,label2
endm
sar_b macro label,label2
sar byte ptr label,label2
endm
sar_w macro label,label2
sar word ptr label,label2
endm
sar_d macro label,label2
sar dword ptr label,label2
endm
sal_b macro label,label2
sal byte ptr label,label2
endm
sal_w macro label,label2
sal word ptr label,label2
endm
sal_d macro label,label2
sal dword ptr label,label2
endm
inc_b macro label
inc byte ptr label
endm
inc_w macro label
inc word ptr label
endm
inc_d macro label
inc dword ptr label
endm
dec_b macro label
dec byte ptr label
endm
dec_w macro label
dec word ptr label
endm
dec_d macro label
dec dword ptr label
endm
movzx_b macro label,label2
movzx label,byte ptr label2
endm
movzx_w macro label,label2
movzx label,word ptr label2
endm
movsx_b macro label,label2
movsx label,byte ptr label2
endm
movsx_w macro label,label2
movsx label,word ptr label2
endm
mul_b macro label
mul byte ptr label
endm
mul_w macro label
mul word ptr label
endm
div_b macro label
div byte ptr label
endm
div_w macro label
div word ptr label
endm
idiv_b macro label
idiv byte ptr label
endm
idiv_w macro label
idiv word ptr label
endm
tst_b macro label
cmp byte ptr label,0
endm
tst_w macro label
cmp word ptr label,0
endm
tst_d macro label
cmp dword ptr label,0
endm
not_b macro label
not byte ptr label
endm
not_w macro label
not word ptr label
endm
not_d macro label
not dword ptr label
endm
neg_b macro label
neg byte ptr label
endm
neg_w macro label
neg word ptr label
endm
neg_d macro label
neg dword ptr label
endm
.list