WINASM.ASM 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  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 I N C **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Command & Conquer *
  23. ;* *
  24. ;* File Name : WINSAM.ASM *
  25. ;* *
  26. ;* Programmer : Steve Tall *
  27. ;* *
  28. ;* Start Date : October 26th, 1995 *
  29. ;* *
  30. ;* Last Update : October 26th, 1995 [ST] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  35. IDEAL
  36. P386
  37. MODEL USE32 FLAT
  38. global C _AbortModemFunctionPtr:dword
  39. global C Memory_Error_Exit :dword
  40. global C MouseQX :dword
  41. global C MouseQY :dword
  42. global FastGetPortHardware_ :near
  43. global FastSetPortHardware_ :near
  44. global PortOpenGreenleafFast_ :near
  45. global HMWaitForOK_ :near
  46. global HMSetDialingMethod_ :near
  47. global HMDial_ :near
  48. global HMInputLine_ :near
  49. global HMAnswer_ :near
  50. global PortKillTime_ :near
  51. global HMSendStringNoWait_ :near
  52. global HMSetUpEchoRoutine_ :near
  53. global HMSetUpAbortKey_ :near
  54. global SetAbortModemFunctionPtr_:near
  55. global Change8259Priority_ :near
  56. global HMSendString_ :near
  57. global C Stop_Execution :near
  58. global _IPX_Initialise:near
  59. global _ASM_IPX_Initialise:near
  60. codeseg
  61. ;proc _ASM_IPX_Initialise near
  62. ;
  63. ; int 3
  64. ; jmp _IPX_Initialise
  65. ;
  66. ;endp
  67. global _Int3:near
  68. proc _Int3 near
  69. ;int 3
  70. ret
  71. endp
  72. proc Stop_Execution C near
  73. nop
  74. ret
  75. endp
  76. ;
  77. ; Stuff needed from the shape library
  78. ;
  79. ;
  80. ;
  81. INCLUDE "shape.inc"
  82. ;***************************************************************************
  83. ;* ModeX_Blit -- Copy a 320x200 graphic view port to a modex screen *
  84. ;* *
  85. ;* *
  86. ;* INPUT: eax - graphic view port *
  87. ;* *
  88. ;* OUTPUT: none *
  89. ;* *
  90. ;* PROTO: extern "C" void ModeX_Blit (GraphicBufferClass *source); *
  91. ;* *
  92. ;* HISTORY: *
  93. ;* 10/26/1994 PWG : Created. *
  94. ;*=========================================================================*
  95. SEQUENCER =3c4h ; sequencer port
  96. MAP_MASK =2 ; map mask register
  97. INCLUDE "gbuffer.inc"
  98. global ModeX_Blit_:near
  99. proc ModeX_Blit_ NEAR
  100. pushad
  101. mov ebx,eax
  102. mov esi,[(GraphicViewPort ebx).GVPOffset]
  103. mov eax,[(GraphicViewPort ebx).GVPXAdd]
  104. add eax,[(GraphicViewPort ebx).GVPPitch]
  105. mov edi,0a0000h
  106. mov ebx,eax
  107. mov al,MAP_MASK
  108. mov ebp,200
  109. ??each_line_lp: mov ah,1 ;1st plane
  110. push ebx
  111. push esi
  112. ??each_plane_lp:mov edx,SEQUENCER
  113. out dx,ax
  114. push esi
  115. push edi
  116. push eax
  117. rept 10
  118. mov al,[esi]
  119. mov bl,[esi+8]
  120. mov cl,[esi+16]
  121. mov dl,[esi+24]
  122. mov ah,[esi+4]
  123. mov bh,[esi+12]
  124. mov ch,[esi+20]
  125. mov dh,[esi+28]
  126. shl ebx,16
  127. shl edx,16
  128. or ebx,eax
  129. or edx,ecx
  130. mov [edi],ebx
  131. mov [edi+4],edx
  132. add esi,32
  133. add edi,8
  134. endm
  135. pop eax
  136. pop edi
  137. pop esi
  138. inc esi
  139. shl ah,1
  140. cmp ah,16
  141. jl ??each_plane_lp
  142. pop esi
  143. pop ebx
  144. lea esi,[esi+ebx+320]
  145. add edi,80
  146. dec ebp
  147. jnz ??each_line_lp
  148. popad
  149. ret
  150. endp ModeX_Blit_
  151. ifdef cuts
  152. pushad
  153. mov ebx,eax
  154. mov esi,[(GraphicViewPort ebx).GVPOffset]
  155. mov eax,[(GraphicViewPort ebx).GVPXAdd]
  156. add eax,[(GraphicViewPort ebx).GVPPitch]
  157. mov edi,0a0000h
  158. mov ebx,eax
  159. mov al,MAP_MASK
  160. mov ah,1 ;1st plane
  161. ??each_plane_lp:mov edx,SEQUENCER
  162. out dx,ax
  163. mov ebp,200 ;do 200 lines
  164. push esi
  165. push edi
  166. ??each_line_lp: mov ecx,320/4
  167. ??each_pixel_lp:mov dl,[esi]
  168. mov [edi],dl
  169. add esi,4
  170. inc edi
  171. dec ecx
  172. jnz ??each_pixel_lp
  173. add esi,ebx
  174. dec ebp
  175. jnz ??each_line_lp
  176. pop edi
  177. pop esi
  178. inc esi
  179. shl ah,1
  180. cmp ah,16
  181. jl ??each_plane_lp
  182. endif
  183. proc FastGetPortHardware_ NEAR
  184. endp
  185. proc FastSetPortHardware_ NEAR
  186. endp
  187. proc PortOpenGreenleafFast_ NEAR
  188. endp
  189. proc HMWaitForOK_ NEAR
  190. endp
  191. proc HMSetDialingMethod_ NEAR
  192. endp
  193. proc HMDial_ NEAR
  194. endp
  195. proc HMInputLine_ NEAR
  196. endp
  197. proc HMAnswer_ NEAR
  198. endp
  199. proc PortKillTime_ NEAR
  200. endp
  201. proc HMSendStringNoWait_ NEAR
  202. endp
  203. proc HMSetUpEchoRoutine_ NEAR
  204. endp
  205. proc HMSetUpAbortKey_ NEAR
  206. endp
  207. proc SetAbortModemFunctionPtr_ NEAR
  208. endp
  209. proc Change8259Priority_ NEAR
  210. endp
  211. proc HMSendString_ NEAR
  212. endp
  213. ret
  214. masm
  215. ;
  216. ; Change a DAC colour register directly
  217. ;
  218. ; register number in al
  219. ;
  220. ; bh=red bl=green cl=blue
  221. ;
  222. set_dac_col proc near
  223. pushad
  224. cli
  225. push eax
  226. mov dx,03dah
  227. in al,dx
  228. jmp @@1
  229. @@1: mov dx,03c8h
  230. pop eax
  231. out dx,al
  232. jmp @@2
  233. @@2: inc dl
  234. mov al,bh
  235. out dx,al
  236. jmp @@3
  237. @@3: mov al,bl
  238. out dx,al
  239. jmp @@4
  240. @@4: mov al,cl
  241. out dx,al
  242. jmp @@5
  243. @@5: sti
  244. popad
  245. ret
  246. set_dac_col endp
  247. ideal
  248. global Set_Palette_Register_:near
  249. proc Set_Palette_Register_ near
  250. pushad
  251. and cl,63
  252. mov bh,dl
  253. and bh,63
  254. and bl,63
  255. call set_dac_col
  256. popad
  257. ret
  258. endp Set_Palette_Register_
  259. locals ??
  260. ends
  261. dataseg
  262. LineBuffer dd 640 dup (?)
  263. ends
  264. segment mycode page public use32 'code' ; Need stricter segment alignment
  265. global C Asm_Interpolate:near
  266. global C Asm_Interpolate_Line_Double:near
  267. global C Asm_Interpolate_Line_Interpolate:near
  268. global C PaletteInterpolationTable:byte
  269. ;*********************************************************************************************
  270. ;* Asm_Interpolate -- interpolate a 320x200 buffer to a 640x400 screen *
  271. ;* *
  272. ;* INPUT: ptr to source buffer (320x200 image) *
  273. ;* ptr to dest buffer (640x400) *
  274. ;* height of source buffer *
  275. ;* width of source buffer *
  276. ;* width of dest buffer *
  277. ;* *
  278. ;* *
  279. ;* OUTPUT: none *
  280. ;* *
  281. ;* Warnings: *
  282. ;* *
  283. ;* HISTORY: *
  284. ;* 12/15/95 ST : Created. *
  285. ;*===========================================================================================*
  286. PROC Asm_Interpolate C near
  287. ARG src_ptr:dword
  288. ARG dest_ptr:dword
  289. ARG source_height:dword
  290. ARG source_width:dword
  291. ARG dest_width:dword
  292. LOCAL old_dest:dword
  293. pushad
  294. mov eax,[dest_ptr]
  295. mov [old_dest],eax
  296. mov esi,[src_ptr]
  297. ??each_line_loop:
  298. mov ecx,[source_width]
  299. sub ecx,2
  300. shr ecx,1
  301. mov edi,[old_dest]
  302. jmp ??interpolate_loop
  303. align 32
  304. ;
  305. ; convert 2 pixels of source into 4 pixels of destination
  306. ; so we can write to video memory with dwords
  307. ;
  308. ??interpolate_loop:
  309. mov eax,[esi]
  310. lea esi,[esi+2]
  311. mov edx,eax
  312. mov ebx,eax
  313. and edx,65535
  314. ror ebx,8
  315. mov bl,[edx+PaletteInterpolationTable]
  316. mov bh,ah
  317. and eax,000ffff00h
  318. ror ebx,8
  319. ;1st 3 pixels now in ebx
  320. shr eax,8
  321. mov bh,[eax+PaletteInterpolationTable]
  322. ror ebx,16
  323. mov [edi],ebx
  324. add edi,4
  325. dec ecx
  326. jnz ??interpolate_loop
  327. ; do the last three pixels and a blank on the end of a row
  328. xor eax,eax
  329. mov ax,[esi]
  330. mov [edi],al
  331. inc edi
  332. lea esi,[esi+2]
  333. mov al,[eax+PaletteInterpolationTable]
  334. mov [edi],al
  335. inc edi
  336. mov [edi],ah
  337. inc edi
  338. mov [byte edi],0
  339. mov edi,[dest_width]
  340. add [old_dest],edi
  341. dec [source_height]
  342. jnz ??each_line_loop
  343. popad
  344. ret
  345. endp Asm_Interpolate
  346. PROC Asm_Interpolate_Line_Double C near
  347. ARG src_ptr:dword
  348. ARG dest_ptr:dword
  349. ARG source_height:dword
  350. ARG source_width:dword
  351. ARG dest_width:dword
  352. LOCAL old_dest:dword
  353. LOCAL width_counter:dword
  354. LOCAL pixel_count:dword
  355. pushad
  356. mov eax,[dest_ptr]
  357. mov [old_dest],eax
  358. mov esi,[src_ptr]
  359. mov edi,[dest_ptr]
  360. ??each_line_loop:
  361. mov [width_counter],0
  362. mov ecx,[source_width]
  363. sub ecx,2
  364. shr ecx,1
  365. mov [pixel_count],ecx
  366. mov ecx,offset LineBuffer
  367. mov edi,[old_dest]
  368. jmp ??interpolate_loop
  369. align 16
  370. ; convert 2 pixels of source into 4 pixels of destination
  371. ??interpolate_loop:
  372. mov eax,[esi]
  373. lea esi,[esi+2]
  374. mov edx,eax
  375. mov ebx,eax
  376. and edx,65535
  377. ror ebx,8
  378. mov bl,[edx+PaletteInterpolationTable]
  379. mov bh,ah
  380. and eax,000ffff00h
  381. ror ebx,8
  382. ;1st 3 pixels now in ebx
  383. shr eax,8
  384. mov bh,[eax+PaletteInterpolationTable]
  385. ror ebx,16
  386. mov [edi],ebx
  387. mov [ecx],ebx
  388. add edi,4
  389. add ecx,4
  390. dec [pixel_count]
  391. jnz ??interpolate_loop
  392. ; do the last three pixels and a blank
  393. xor eax,eax
  394. mov ax,[esi]
  395. mov [edi],al
  396. mov [ecx],al
  397. inc edi
  398. inc ecx
  399. lea esi,[esi+2]
  400. mov al,[eax+PaletteInterpolationTable]
  401. mov [edi],al
  402. mov [ecx],al
  403. inc edi
  404. inc ecx
  405. mov [edi],ah
  406. mov [ecx],ah
  407. inc edi
  408. inc ecx
  409. mov [byte edi],0
  410. mov [byte ecx],0
  411. mov edi,[dest_width]
  412. shr edi,1
  413. add [old_dest],edi
  414. push esi
  415. push edi
  416. mov esi,offset LineBuffer
  417. mov edi,[old_dest]
  418. mov ecx,[source_width]
  419. shr ecx,1
  420. rep movsd
  421. pop edi
  422. pop esi
  423. add [old_dest],edi
  424. mov edi,[old_dest]
  425. dec [source_height]
  426. jnz ??each_line_loop
  427. popad
  428. ret
  429. endp Asm_Interpolate_Line_Double
  430. ends
  431. dataseg
  432. TopLine dd 640 dup (?)
  433. BottomLine dd 640 dup (?)
  434. segment mycode page public use32 'code' ; Need stricter segment alignment
  435. proc Interpolate_Single_Line C near
  436. ARG source_ptr:dword
  437. ARG dest_ptr:dword
  438. ARG source_width:dword
  439. pushad
  440. mov ecx,[source_width]
  441. sub ecx,2
  442. shr ecx,1
  443. mov esi,[source_ptr]
  444. mov edi,[dest_ptr]
  445. ??interpolate_loop:
  446. mov eax,[esi]
  447. lea esi,[esi+2]
  448. mov edx,eax
  449. mov ebx,eax
  450. and edx,65535
  451. ror ebx,8
  452. mov bl,[edx+PaletteInterpolationTable]
  453. mov bh,ah
  454. and eax,000ffff00h
  455. ror ebx,8
  456. ;1st 3 pixels now in ebx
  457. shr eax,8
  458. mov bh,[eax+PaletteInterpolationTable]
  459. ror ebx,16
  460. mov [edi],ebx
  461. add edi,4
  462. dec ecx
  463. jnz ??interpolate_loop
  464. ; do the last three pixels and a blank
  465. xor eax,eax
  466. mov ax,[esi]
  467. mov [edi],al
  468. inc edi
  469. mov al,[eax+PaletteInterpolationTable]
  470. mov [edi],al
  471. inc edi
  472. mov [edi],ah
  473. inc edi
  474. mov [byte edi],0
  475. popad
  476. ret
  477. endp Interpolate_Single_Line
  478. proc Interpolate_Between_Lines C near
  479. ARG source1:dword
  480. ARG source2:dword
  481. ARG destination:dword
  482. ARG source_width:dword
  483. pushad
  484. mov esi,[source1]
  485. mov edi,[destination]
  486. mov ebx,[source2]
  487. xor eax,eax
  488. mov ecx,[source_width]
  489. add ecx,ecx
  490. ??interpolate_each_pixel_loop:
  491. mov al,[esi]
  492. mov ah,[ebx]
  493. inc esi
  494. inc ebx
  495. mov dl,[eax+PaletteInterpolationTable]
  496. mov [edi],dl
  497. inc edi
  498. dec ecx
  499. jnz ??interpolate_each_pixel_loop
  500. popad
  501. ret
  502. endp Interpolate_Between_Lines
  503. macro Lineswp
  504. push [next_line]
  505. push [last_line]
  506. pop [next_line]
  507. pop [last_line]
  508. endm
  509. PROC Asm_Interpolate_Line_Interpolate C near
  510. ARG src_ptr:dword
  511. ARG dest_ptr:dword
  512. ARG source_lines:dword
  513. ARG source_width:dword
  514. ARG dest_width:dword
  515. LOCAL old_dest:dword
  516. LOCAL pixel_count:dword
  517. LOCAL next_line:dword
  518. LOCAL last_line:dword
  519. pushad
  520. mov eax,[dest_ptr]
  521. mov [old_dest],eax
  522. mov [next_line],offset TopLine
  523. mov [last_line],offset BottomLine
  524. mov ecx,[source_width]
  525. shr ecx,1
  526. mov [pixel_count],ecx
  527. shr [dest_width],1
  528. call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width]
  529. mov esi,[source_width]
  530. Lineswp
  531. add [src_ptr],esi
  532. dec [source_lines]
  533. ??each_line_pair_loop:
  534. call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width]
  535. call Interpolate_Between_Lines C,[last_line],[next_line],offset LineBuffer,[source_width]
  536. mov esi,[last_line]
  537. mov edi,[old_dest]
  538. mov ecx,[pixel_count]
  539. rep movsd
  540. mov edi,[old_dest]
  541. mov esi,offset LineBuffer
  542. add edi,[dest_width]
  543. mov ecx,[pixel_count]
  544. mov [old_dest],edi
  545. rep movsd
  546. mov edi,[old_dest]
  547. mov esi,[source_width]
  548. add edi,[dest_width]
  549. add [src_ptr],esi
  550. mov [old_dest],edi
  551. Lineswp
  552. dec [source_lines]
  553. jnz ??each_line_pair_loop
  554. call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width]
  555. mov esi,[next_line]
  556. mov edi,[old_dest]
  557. mov ecx,[pixel_count]
  558. rep movsd
  559. popad
  560. ret
  561. endp Asm_Interpolate_Line_Interpolate
  562. ends mycode
  563. global C Asm_Create_Palette_Interpolation_Table:near
  564. global C InterpolationPalette:dword
  565. codeseg
  566. proc Asm_Create_Palette_Interpolation_Table C near
  567. LOCAL palette_counter:dword
  568. LOCAL first_palette:dword
  569. LOCAL second_palette:dword
  570. LOCAL dest_ptr:dword
  571. LOCAL count:dword
  572. LOCAL closest_colour:dword
  573. LOCAL distance_of_closest:dword
  574. pushad
  575. mov [dest_ptr],0
  576. mov [palette_counter],256
  577. mov esi,[InterpolationPalette]
  578. ??palette_outer_loop:
  579. mov edi,[InterpolationPalette]
  580. mov ecx,256
  581. ??palette_inner_loop:
  582. mov bl,[esi]
  583. add bl,[edi]
  584. shr bl,1
  585. mov bh,[esi+1]
  586. add bh,[edi+1]
  587. shr bh,1
  588. mov dl,[esi+2]
  589. add dl,[edi+2]
  590. shr dl,1
  591. mov [closest_colour],0
  592. mov [distance_of_closest],-1
  593. push edi
  594. push ecx
  595. mov edi,[InterpolationPalette]
  596. mov [count],0
  597. ??cmp_pal_lp: xor eax,eax
  598. xor ecx,ecx
  599. mov al,[edi]
  600. sub al,bl
  601. imul al
  602. mov ecx,eax
  603. mov al,[edi+1]
  604. sub al,bh
  605. imul al
  606. add ecx,eax
  607. mov al,[edi+2]
  608. sub al,dl
  609. imul al
  610. add ecx,eax
  611. cmp ecx,[distance_of_closest]
  612. ja ??end_cmp_lp
  613. mov [distance_of_closest],ecx
  614. mov eax,[count]
  615. mov [closest_colour],eax
  616. test ecx,ecx
  617. jz ??got_perfect
  618. ??end_cmp_lp: lea edi,[edi+3]
  619. inc [count]
  620. cmp [count],256
  621. jb ??cmp_pal_lp
  622. ??got_perfect: mov edi,[dest_ptr]
  623. mov eax,[closest_colour]
  624. mov [edi+PaletteInterpolationTable],al
  625. inc [dest_ptr]
  626. pop ecx
  627. pop edi
  628. lea edi,[edi+3]
  629. dec ecx
  630. jnz ??palette_inner_loop
  631. lea esi,[esi+3]
  632. dec [palette_counter]
  633. jnz ??palette_outer_loop
  634. popad
  635. ret
  636. endp Asm_Create_Palette_Interpolation_Table
  637. DATASEG
  638. _AbortModemFunctionPtr dd 0
  639. Memory_Error_Exit dd 0
  640. MouseQX dd 0
  641. MouseQY dd 0
  642. end