PAL.ASM 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  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 A S S O C I A T E S **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Westwood Library *
  23. ;* *
  24. ;* File Name : PAL.ASM *
  25. ;* *
  26. ;* Programmer : Joe L. Bostic *
  27. ;* *
  28. ;* Start Date : May 30, 1992 *
  29. ;* *
  30. ;* Last Update : April 27, 1994 [BR] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* Set_Palette_Range -- Sets changed values in the palette. *
  35. ;* Bump_Color -- adjusts specified color in specified palette *
  36. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  37. ;********************** Model & Processor Directives ************************
  38. IDEAL
  39. P386
  40. MODEL USE32 FLAT
  41. ;include "keyboard.inc"
  42. FALSE = 0
  43. TRUE = 1
  44. ;****************************** Declarations ********************************
  45. GLOBAL C Set_Palette_Range:NEAR
  46. GLOBAL C Bump_Color:NEAR
  47. GLOBAL C CurrentPalette:BYTE:768
  48. GLOBAL C PaletteTable:byte:1024
  49. ;********************************** Data ************************************
  50. LOCALS ??
  51. DATASEG
  52. CurrentPalette DB 768 DUP(255) ; copy of current values of DAC regs
  53. PaletteTable DB 1024 DUP(0)
  54. IFNDEF LIB_EXTERNS_RESOLVED
  55. VertBlank DW 0 ; !!!! this should go away
  56. ENDIF
  57. ;********************************** Code ************************************
  58. CODESEG
  59. IF 1
  60. ;***************************************************************************
  61. ;* SET_PALETTE_RANGE -- Sets a palette range to the new pal *
  62. ;* *
  63. ;* INPUT: *
  64. ;* *
  65. ;* OUTPUT: *
  66. ;* *
  67. ;* PROTO: *
  68. ;* *
  69. ;* WARNINGS: This routine is optimized for changing a small number of *
  70. ;* colors in the palette.
  71. ;* *
  72. ;* HISTORY: *
  73. ;* 03/07/1995 PWG : Created. *
  74. ;*=========================================================================*
  75. PROC Set_Palette_Range C NEAR
  76. ARG palette:DWORD
  77. GLOBAL Set_DD_Palette_:near
  78. GLOBAL Wait_Vert_Blank_:near
  79. pushad
  80. mov esi,[palette]
  81. mov ecx,768/4
  82. mov edi,offset CurrentPalette
  83. cld
  84. rep movsd
  85. ;call Wait_Vert_Blank_
  86. mov eax,[palette]
  87. call Set_DD_Palette_
  88. popad
  89. ret
  90. ifdef NOT_FOR_WIN95
  91. USES eax,ebx,ecx,edx,edi,esi
  92. cld
  93. ;*=================================================================*/
  94. ;* Set up pointers to begin making palette comparison */
  95. ;*=================================================================*/
  96. mov esi, [palette]
  97. mov edi, OFFSET CurrentPalette
  98. mov ebx, OFFSET PaletteTable
  99. mov ecx, 0
  100. ??loop_top:
  101. mov eax,[esi] ; read a dword from palette source
  102. mov edx,[edi] ; read a dword from compare palette
  103. and eax,00FFFFFFh ; palette entrys are only 3 bytes
  104. and edx,00FFFFFFh ; long so and of extra
  105. cmp eax,edx ; if they are not the same then
  106. jne ??set_table ; add them into the table
  107. add esi,3
  108. add edi,3
  109. inc cl ; adjust to next palette entry
  110. jnz ??loop_top ; if we dont wrap to zero we have more
  111. jmp ??set_pal ; so now go set the palette
  112. ??set_table:
  113. shl eax,8 ; shift bgr value up register
  114. mov al,cl ; store which palette entry num
  115. mov [ebx],eax
  116. add ebx,4
  117. movsw ; copy the three gun values into
  118. movsb ; the shadow palette. Use movsb
  119. inc cl ; adjust to next palette entry
  120. jnz ??loop_top ; if we dont wrap to zero we have more
  121. ??set_pal:
  122. mov esi,ebx
  123. mov ebx,OFFSET PaletteTable
  124. sub esi,ebx ; if ebx didn't change there
  125. jz ??exit ; is nothing to set
  126. shr esi,2 ; find how many entrys
  127. mov eax,[ebx]
  128. movzx ecx,al ; we are currently on entry 0
  129. add ebx,4
  130. ; Tell DAC of the color gun to start setting.
  131. mov edx,03C8h
  132. out dx,al ; First color set.
  133. ; Set the colors only during a VSync.
  134. mov edx,03DAh ; CRTC register.
  135. push ebx
  136. mov bx,[VertBlank]
  137. and bl,001h
  138. shl bl,3
  139. ??in_vbi:
  140. in al,dx ; read CRTC status
  141. and al,008h ; only vertical sync bit
  142. xor al,bl
  143. je ??in_vbi ; in vertical sync
  144. ??out_vbi:
  145. in al,dx ; read CRTC status
  146. and al,008h ; only vertical sync bit
  147. xor al,bl
  148. jne ??out_vbi ; not in vertical sync
  149. pop ebx
  150. ; Update the DAC data register.
  151. mov dx,03C9h
  152. ;**************** Time Critical Section Start ******************
  153. cli
  154. ??loop:
  155. shr eax,8 ; shift down the red gun value
  156. out dx,al ; write it to the video card
  157. jmp $ + 2 ; force cache to flush, to create a time
  158. shr eax,8 ; shift down the blue gun value
  159. out dx,al ; write it to the video card
  160. jmp $ + 2 ; force cache to flush, to create a time
  161. shr eax,8 ; shift down the blue gun value
  162. out dx,al ; write the green value to video card
  163. jmp $ + 2 ; force cache to flush, to create a time
  164. inc ecx ; move edx to next palette entry
  165. mov eax,[ebx] ; get next value to set
  166. add ebx,4 ; and post increment the palette value
  167. cmp al,cl ; check if DAC position already correct
  168. je ??correct_pos
  169. mov edx,03C8h ; Tell DAC of the color gun to start setting.
  170. out dx,al ; First color set.
  171. mov dx,03C9h
  172. ??correct_pos:
  173. dec esi
  174. jnz ??loop
  175. sti
  176. ;***************** Time Critical Section End *******************
  177. ??exit:
  178. ret
  179. endif ;NOT_FOR_WIN95
  180. ENDP Set_Palette_Range
  181. ELSE
  182. ;***************************************************************************
  183. ;* Set_Palette_Range -- Sets changed values in the palette. *
  184. ;* *
  185. ;* INPUT: *
  186. ;* VOID *palette - pointer to the new palette. *
  187. ;* *
  188. ;* OUTPUT: *
  189. ;* none *
  190. ;* *
  191. ;* WARNINGS: *
  192. ;* *
  193. ;* HISTORY: *
  194. ;* 04/25/1994 SKB : Created. *
  195. ;* 04/27/1994 BR : Converted to 32-bit *
  196. ;*=========================================================================*
  197. ; VOID cdecl Set_Palette_Range(VOID *palette);
  198. PROC Set_Palette_Range C NEAR
  199. USES eax,ebx,ecx,edx,edi,esi
  200. ARG palette:DWORD
  201. LOCAL remain:DWORD ; 32-bit: converted to LONG
  202. cld
  203. mov bx,[VertBlank]
  204. and bl,001h
  205. shl bl,3
  206. ; Make a copy of the palette passed in.
  207. mov edi,OFFSET CurrentPalette
  208. mov esi,[palette]
  209. mov [remain],768
  210. ; Search for differences between the current palette and the
  211. ; new palette. When a difference is found, output a block
  212. ; of color registers and keep scanning.
  213. ??bodyloop:
  214. mov ecx,[remain]
  215. repe cmpsb ; Search for differences.
  216. je short ??exit
  217. dec esi
  218. dec edi
  219. inc ecx
  220. mov edx,0 ; clear EDX
  221. mov eax,ecx
  222. mov ecx,3
  223. div ecx ; EAX = # of colors to set, EDX = Fraction.
  224. or edx,edx
  225. jz short ??nofrac
  226. neg edx
  227. add edx,3 ; Back offset skip needed.
  228. inc eax ; Fractional color rounds up to whole color to set.
  229. ??nofrac:
  230. ; Set CX to be the number of color guns to set.
  231. mov ecx,eax ; Colors * 3 bytes per color.
  232. add ecx,eax
  233. add ecx,eax
  234. ; Chop this DAC dump short if necessary in order to reduce
  235. ; sparkling.
  236. mov [remain],0
  237. cmp ecx,86*3 ; Number of color guns to set per vert retrace
  238. jbe short ??ok
  239. sub ecx,86*3
  240. mov [remain],ecx
  241. mov ecx,86*3
  242. ??ok:
  243. ; Adjust the palette offsets back to point to the RED color gun.
  244. sub esi,edx
  245. sub edi,edx
  246. ; Determine the color number to start setting.
  247. neg eax
  248. add eax,256 ; AX = Color to start setting (0..255).
  249. ; Tell DAC of the color gun to start setting.
  250. mov edx,03C8h
  251. out dx,al ; First color set.
  252. ; Set the colors only during a VSync.
  253. mov edx,03DAh ; CRTC register.
  254. ??in_vbi:
  255. in al,dx ; read CRTC status
  256. and al,008h ; only vertical sync bit
  257. xor al,bl
  258. je ??in_vbi ; in vertical sync
  259. ??out_vbi:
  260. in al,dx ; read CRTC status
  261. and al,008h ; only vertical sync bit
  262. xor al,bl
  263. jne ??out_vbi ; not in vertical sync
  264. ;??wait:
  265. ; in al,dx
  266. ; test al,01000b
  267. ; jnz ??wait
  268. ;??retrace:
  269. ; in al,dx
  270. ; test al,01000b
  271. ; jz ??retrace
  272. ; Update the DAC data register.
  273. mov dx,03C9h
  274. ;**************** Time Critical Section Start ******************
  275. pushf
  276. cli
  277. ??loop:
  278. lodsb
  279. stosb
  280. out dx,al
  281. jmp $ + 2 ; force cache to flush, to create a time
  282. ; delay to give DAC time to get value
  283. loop ??loop
  284. popf
  285. ;***************** Time Critical Section End *******************
  286. cmp [remain],0
  287. jnz ??bodyloop
  288. ??exit:
  289. ret
  290. ENDP Set_Palette_Range
  291. ENDIF
  292. ;***************************************************************************
  293. ;* Bump_Color -- adjusts specified color in specified palette *
  294. ;* *
  295. ;* INPUT: *
  296. ;* VOID *palette - palette to modify *
  297. ;* WORD changable - color # to change *
  298. ;* WORD target - color to bend toward *
  299. ;* *
  300. ;* OUTPUT: *
  301. ;* *
  302. ;* WARNINGS: *
  303. ;* *
  304. ;* HISTORY: *
  305. ;* 04/27/1994 BR : Converted to 32-bit. *
  306. ;*=========================================================================*
  307. ; BOOL cdecl Bump_Color(VOID *palette, WORD changable, WORD target);
  308. PROC Bump_Color C NEAR
  309. USES ebx,ecx,edi,esi
  310. ARG pal:DWORD, color:WORD, desired:WORD
  311. LOCAL changed:WORD ; Has palette changed?
  312. mov edi,[pal] ; Original palette pointer.
  313. mov esi,edi
  314. mov eax,0
  315. mov ax,[color]
  316. add edi,eax
  317. add edi,eax
  318. add edi,eax ; Offset to changable color.
  319. mov ax,[desired]
  320. add esi,eax
  321. add esi,eax
  322. add esi,eax ; Offset to target color.
  323. mov [changed],FALSE ; Presume no change.
  324. mov ecx,3 ; Three color guns.
  325. ; Check the color gun.
  326. ??colorloop:
  327. mov al,[BYTE PTR esi]
  328. sub al,[BYTE PTR edi] ; Carry flag is set if subtraction needed.
  329. jz short ??gotit
  330. mov [changed],TRUE
  331. inc [BYTE PTR edi] ; Presume addition.
  332. jnc short ??gotit ; oops, subtraction needed so dec twice.
  333. dec [BYTE PTR edi]
  334. dec [BYTE PTR edi]
  335. ??gotit:
  336. inc edi
  337. inc esi
  338. loop ??colorloop
  339. mov ax,[changed]
  340. ret
  341. ENDP Bump_Color
  342. END
  343. ;*************************** End of pal.asm ********************************
  344.