PAL.ASM 12 KB

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