LAUNCH.ASM 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;***********************************************************************************************
  19. ;*** 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 ***
  20. ;***********************************************************************************************
  21. ;* *
  22. ;* Project Name : Command & Conquer -- launcher program *
  23. ;* *
  24. ;* File Name : launch.asm *
  25. ;* *
  26. ;* Programmer : Steve Tall *
  27. ;* *
  28. ;* Start Date : August 19, 1995 *
  29. ;* *
  30. ;* Last Update : Modified for RA, October 14th, 1996 [ST] *
  31. ;* *
  32. ;* Build : Compile and link with MASM 6 *
  33. ;* Note that masm will complain there is no stack because *
  34. ;* we are not using a simplified segment model *
  35. ;* *
  36. ;*---------------------------------------------------------------------------------------------*
  37. ;* Functions: *
  38. ;* Start -- Program entry point *
  39. ;* Mem_Error -- report an out of memory error (not a function) *
  40. ;* Disc_Error -- report an out of disk space error (not a function) *
  41. ;* Delete_Swaps -- Deletes old swap files from the game directory *
  42. ;* Setup_Environment -- Adds environment strings required for DOS4G professional *
  43. ;* *
  44. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  45. TITLE "Red Alert launcher"
  46. .386
  47. ;----------------------------------------------------------------------------------------------
  48. ; Defines for DOS system functions.
  49. ;
  50. DOS_LOAD_AND_EXEC =4B00H
  51. DOS_ALLOC =48H
  52. DOS_FREE =49h
  53. DOS_GET_FREE_DISC_SPACE =36H
  54. DOS_SET_DIRECTORY =3BH
  55. DOS =21H
  56. DOS_SET_DTA =1AH
  57. DOS_FIND_FIRST =4EH
  58. DOS_FIND_NEXT =4FH
  59. DOS_DELETE_FILE =41H
  60. DOS_SET_ATTRIBUTES =43H
  61. DOS_SET_DRIVE =0EH
  62. DOS_RESIZE_ALLOCATION =4Ah
  63. DOS_EXIT =4ch
  64. DOS_PRINT_STRING =9
  65. ;----------------------------------------------------------------------------------------------
  66. ; Defines for keyboard BIOS functions
  67. ;
  68. KEYBOARD_BIOS =16h
  69. BIOS_CHECK_KEYBOARD =11h
  70. BIOS_GET_KEYSTROKE =10h
  71. ;----------------------------------------------------------------------------------------------
  72. ; Defines for video bios functions
  73. ;
  74. VIDEO_BIOS =10h
  75. BIOS_SET_VIDEO_MODE_3 =0003h
  76. ;----------------------------------------------------------------------------------------------
  77. ; Misc defines
  78. ;
  79. MEM_REQUIRED =1024 * 400 ;Check for 400k low memory
  80. INIT_FREE_DISK_SPACE =15*1024*1024 ;C&C requirement for disc space
  81. MY_ALLOCATION =1536/16 ;only allow myself 1.5k to run in incl. psp and stack
  82. ;you can find out how much space the program needs
  83. ;by running WDISASM LAUNCH.OBJ
  84. ;dont forget to add 256 bytes on for the psp
  85. include <pcmacro.16>
  86. ;----------------------------------------------------------------------------------------------
  87. ; Simplified segment models are for wimmin
  88. ;
  89. ; We want 32 bit instructions in a 16 bit segment
  90. ;
  91. _code segment para public use16 'code'
  92. assume ds:_data
  93. assume es:_data
  94. assume ss:_data
  95. assume cs:_code
  96. ;*************************************************************************************************
  97. ;* Start -- Program entry point *
  98. ;* *
  99. ;* *
  100. ;* INPUT: nothing *
  101. ;* *
  102. ;* OUTPUT: DOS return code from spawning the game *
  103. ;* *
  104. ;* HISTORY: *
  105. ;* 08/19/95 ST: Created. *
  106. ;*===============================================================================================*
  107. Start: ;
  108. ; Set up the segments and the stack pointer
  109. ;
  110. cli
  111. mov ax,_data
  112. mov ds,ax
  113. mov [Psp],es
  114. mov ss,ax
  115. mov sp,offset MyStack
  116. sti
  117. ;
  118. ; Modify the starting memory allocation to free enough for the game proper
  119. ;
  120. save ax
  121. mov bx,MY_ALLOCATION
  122. mov ah,DOS_RESIZE_ALLOCATION
  123. int DOS
  124. restore ax
  125. bcs Mem_Error
  126. ;
  127. ; See if we have enough free memory to launch
  128. ;
  129. mov ah,DOS_ALLOC
  130. mov bx,-1 ;I want it all! hahaha
  131. int DOS
  132. jnc Mem_Error ;shouldnt ever succeed but...
  133. cmp ax,8
  134. jnz Mem_Error
  135. cmp bx,(MEM_REQUIRED/16)-MY_ALLOCATION
  136. bls Mem_Error ;oh dear
  137. ;
  138. ; See if there is enough free disc space to launch
  139. ;
  140. xor dl,dl
  141. mov ah,DOS_GET_FREE_DISC_SPACE
  142. int DOS
  143. ; dos get free disc space returns with the following
  144. ; ax - sectors per cluster
  145. ; bx - number of available clusters
  146. ; cx - bytes per sector
  147. ; dx - cluster on the drive
  148. mul bx ;clusters avail*sectors per cluster
  149. shl edx,16
  150. mov dx,ax
  151. mov eax,edx
  152. and ecx,65535
  153. mul ecx ;*bytes per sector
  154. cmp eax,INIT_FREE_DISK_SPACE
  155. blo Disc_Error
  156. ;
  157. ; Get the directory we were run from and cd to it
  158. ;
  159. mov es,[Psp]
  160. mov bx,2ch
  161. mov es,es:[bx] ;es points to env
  162. xor di,di
  163. xor al,al
  164. mov cx,-1
  165. ;
  166. ; Search for 0,0 as that aways terminates the environment block
  167. ;
  168. @@again: repnz scasb
  169. cmp_b es:[di],al
  170. jnz @@again
  171. lea si,[di+3] ;skip length word and second zero
  172. ;
  173. ; Copy the directory name to temporary workspace
  174. ;
  175. mov di,si
  176. mov cx,-1
  177. repnz scasb
  178. neg cx
  179. mov bx,cx
  180. mov cx,-1
  181. std
  182. mov al,'\'
  183. repnz scasb
  184. neg cx
  185. sub bx,cx
  186. mov cx,bx
  187. inc cx
  188. cld
  189. mov di,offset Dta
  190. push ds
  191. mov ax,es
  192. mov bx,ds
  193. mov es,bx
  194. mov ds,ax
  195. rep movsb
  196. xor al,al
  197. stosb
  198. pop ds
  199. ;
  200. ; Actually set the drive and path
  201. ;
  202. mov dl,[Dta]
  203. sub dl,'A'
  204. mov ah,DOS_SET_DRIVE
  205. int DOS
  206. mov dx,offset Dta
  207. mov ah,DOS_SET_DIRECTORY
  208. int DOS
  209. ;
  210. ; Delete all the old swap files
  211. ;
  212. mov dx,offset Dta
  213. mov ah,DOS_SET_DTA
  214. int DOS
  215. call Delete_Swaps
  216. ;
  217. ; Add in the environment strings required for DOS4G professional
  218. ;
  219. call Setup_Environment
  220. ;
  221. ; Set up the parameters to launch c&c
  222. ;
  223. mov es,[Psp]
  224. mov dx,offset GameName
  225. mov bx,offset GameParameterBlock
  226. mov ax,[EnvironmentSegment] ;Initialised by Setup_Environment
  227. mov_w [bx],ax ;ptr to environment
  228. ;
  229. ; just pass the command tail we got straight through
  230. ;
  231. mov ax,80h
  232. mov [bx+2],ax ;offset of command tail
  233. mov ax,[Psp]
  234. mov [bx+4],ax ;segment of command tail
  235. mov es,ax
  236. mov ax,es:[2ch]
  237. mov [bx+8],ax ;segment of first fcb
  238. mov [bx+12],ax ;segment of second fcb
  239. mov ax,_data
  240. mov es,ax
  241. ;
  242. ; Run the main game program
  243. ;
  244. mov ax,DOS_LOAD_AND_EXEC ;load and execute program
  245. int DOS
  246. ;
  247. ; Restore teh environment memory
  248. ;
  249. mov ax,[EnvironmentSegment]
  250. test ax,ax
  251. jz @@no_free
  252. mov es,ax
  253. mov ah,DOS_FREE
  254. int DOS
  255. @@no_free: ;
  256. ; Quit to DOS
  257. ;
  258. mov ah,DOS_EXIT
  259. int DOS
  260. ;*************************************************************************************************
  261. ;* Mem_Error -- Print a memory error message and quit *
  262. ;* *
  263. ;* *
  264. ;* INPUT: nothing *
  265. ;* *
  266. ;* OUTPUT: undefined *
  267. ;* *
  268. ;* HISTORY: *
  269. ;* 08/19/95 ST: Created. *
  270. ;*===============================================================================================*
  271. Mem_Error: mov ax,BIOS_SET_VIDEO_MODE_3
  272. int VIDEO_BIOS
  273. mov dx,offset MemErrorTxt
  274. mov ah,DOS_PRINT_STRING
  275. int DOS
  276. mov dx,offset MoreInfoTxt
  277. Error_In: mov ah,DOS_PRINT_STRING
  278. int DOS
  279. ;
  280. ; wait for keypress
  281. ;
  282. nochar: mov ah,BIOS_CHECK_KEYBOARD
  283. int KEYBOARD_BIOS
  284. beq nochar
  285. ;
  286. ; get the ket out of the buffer
  287. ;
  288. mov ah,BIOS_GET_KEYSTROKE
  289. int KEYBOARD_BIOS
  290. ;
  291. ; Quit to DOS
  292. ;
  293. mov ah,DOS_EXIT
  294. int DOS
  295. ;*************************************************************************************************
  296. ;* Disc_Error -- Prints a disk error message and exits *
  297. ;* *
  298. ;* *
  299. ;* INPUT: nothing *
  300. ;* *
  301. ;* OUTPUT: DOS return code from spawning the game *
  302. ;* *
  303. ;* HISTORY: *
  304. ;* 08/19/95 ST: Created. *
  305. ;*===============================================================================================*
  306. Disc_Error: mov ax,BIOS_SET_VIDEO_MODE_3
  307. int VIDEO_BIOS
  308. mov dx,offset DiscErrorTxt
  309. jmp Error_In
  310. ;*************************************************************************************************
  311. ;* Setup_Environment -- Create a new environment block with the set DOS4GVM= stuff *
  312. ;* *
  313. ;* *
  314. ;* INPUT: nothing *
  315. ;* *
  316. ;* OUTPUT: nothing *
  317. ;* *
  318. ;* Note: Modifies the global variable 'EnvironmentStrings' to point to the start of our new *
  319. ;* environment block. This memory will need to be freed later. *
  320. ;* *
  321. ;* HISTORY: *
  322. ;* 10/14/96 ST: Created. *
  323. ;*===============================================================================================*
  324. Setup_Environment proc near
  325. ;
  326. ; Point to default environment.
  327. ;
  328. mov [EnvironmentSegment],0
  329. ;
  330. ; Get the address of our environment block into es
  331. ;
  332. mov es,[Psp]
  333. mov bx,2ch
  334. mov es,es:[bx] ;es points to env
  335. ;
  336. ; Search for the end of the block to get its length
  337. ;
  338. xor di,di
  339. xor al,al
  340. mov cx,-1
  341. @@search: repnz scasb
  342. cmp_b es:[di],al
  343. jnz @@search
  344. ;
  345. ; di is length of environment block
  346. ;
  347. lea bx,[di+256] ; a little extra to be sure.
  348. ;
  349. ; Allocate memory for a copy of the environment.
  350. ;
  351. push di
  352. mov ah,DOS_ALLOC
  353. shr bx,4 ;needs to be number of paragraphs
  354. int DOS
  355. jnc @@ok
  356. ;
  357. ; Oops. Not enough memory. We are screwed so just exit.
  358. ;
  359. pop di
  360. jmp @@out
  361. @@ok: ;
  362. ; Save the pointer to our new environment
  363. ; We can also use this to free the memory later
  364. ;
  365. mov [EnvironmentSegment],ax
  366. ;
  367. ; Copy the original environment to the newly alloced memory
  368. ;
  369. mov es,ax
  370. pop cx ; size to copy
  371. push ds
  372. mov ds,[Psp]
  373. mov bx,2ch
  374. mov ds,ds:[bx] ;ds points to original environment
  375. xor si,si
  376. xor di,di
  377. rep movsb
  378. pop ds
  379. mov si,offset Dos4gEnvironment
  380. @@copy_loop: lodsb
  381. stosb
  382. test al,al
  383. jnz @@copy_loop
  384. ;
  385. ; Copy the final zero. The environment must be terminated by 2 zeros.
  386. ;
  387. movsb
  388. @@out: ret
  389. Setup_Environment endp
  390. ;*************************************************************************************************
  391. ;* Delete_Swaps -- Delete any swap files left over from a previous game *
  392. ;* *
  393. ;* *
  394. ;* INPUT: nothing *
  395. ;* *
  396. ;* OUTPUT: nothing *
  397. ;* *
  398. ;* HISTORY: *
  399. ;* 08/19/95 ST: Created. *
  400. ;*===============================================================================================*
  401. Delete_Swaps proc near
  402. ;
  403. ; Use 'Find first/next' to find the swap files
  404. ;
  405. mov dx,offset SwapName
  406. mov cx,7 ;attributes
  407. mov ah,DOS_FIND_FIRST
  408. int DOS
  409. bcs @@out ;no matching files
  410. ;
  411. ; Make sure it isn't read only
  412. ;
  413. @@loop: mov dx,offset Dta+1eh
  414. mov ah,DOS_SET_ATTRIBUTES
  415. mov al,1
  416. xor cx,cx ;attributes
  417. int DOS
  418. ;
  419. ; Delete the file
  420. ;
  421. mov dx,offset Dta+1eh
  422. mov ah,DOS_DELETE_FILE
  423. int DOS
  424. ;
  425. ; Find the next one
  426. ;
  427. mov ah,DOS_FIND_NEXT
  428. int DOS
  429. bcc @@loop
  430. @@out: ret
  431. Delete_Swaps endp
  432. _code ends ;end of code segment
  433. ;----------------------------------------------------------------------------------------------
  434. ;
  435. ; Complex data segment
  436. ;
  437. ;
  438. _data segment dword public use16 'data'
  439. EnvironmentSegment dw 0 ;ptr to environment to pass to child process
  440. Psp dw 0 ;segment addr of program segment prefix
  441. GameParameterBlock db 16h dup (0) ;required parameters for DOS launch
  442. GameName db "GAME.DAT",0 ;this is the name of the app to be spawned
  443. SwapName db "*.SWP",0 ;swap files always have a .SWP extension
  444. ;
  445. ; Environment to be set for DOS4G professional
  446. ;
  447. Dos4gEnvironment db "DOS4GVM=SwapMin:12M,SwapInc:0",0,0
  448. ;
  449. ; Error and warning messages
  450. ;
  451. MemErrorTxt db "Warning - There is very little free conventional DOS memory in the system.",13,10,"$"
  452. DiscErrorTxt db "Error - insufficient disk space to run Red Alert."
  453. db 13,10,"Red Alert requires 15,728,640 bytes of free disk space.",13,10 ;this string will
  454. ;run into the next because
  455. ;there is no '$'
  456. MoreInfoTxt db "Please read the Red Alert manual for more information.",13,10,13,10
  457. db "Press a key to continue.",13,10,"$"
  458. Dta db 128 dup (0) ;enough for complete path
  459. ;*************************************************************
  460. ;
  461. ; The stack
  462. ;
  463. StackSpace db 256 dup (0) ;256 byte stack!
  464. MyStack label byte ;The stack starts here and grows down.
  465. EndCode label byte ;The end of the data segment
  466. _data ends
  467. end Start