CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

MMX.ASM (11660B)


      1 ;
      2 ; Copyright 2020 Electronic Arts Inc.
      3 ;
      4 ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 ; software: you can redistribute it and/or modify it under the terms of 
      6 ; the GNU General Public License as published by the Free Software Foundation, 
      7 ; either version 3 of the License, or (at your option) any later version.
      8 
      9 ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 ; in the hope that it will be useful, but with permitted additional restrictions 
     11 ; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 ; distributed with this program. You should have received a copy of the 
     13 ; GNU General Public License along with permitted additional restrictions 
     14 ; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.
     15 
     16 
     17 ;***************************************************************************
     18 ;**   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  **
     19 ;***************************************************************************
     20 ;*                                                                         *
     21 ;*                 Project Name : Command & Conquer                        *
     22 ;*                                                                         *
     23 ;*                    File Name : MMX.ASM                                  *
     24 ;*                                                                         *
     25 ;*                   Programmer : Steve Tall                               *
     26 ;*                                                                         *
     27 ;*                   Start Date : May 19th, 1996                           *
     28 ;*                                                                         *
     29 ;*                  Last Update : May 19th 1996 [ST]                       *
     30 ;*                                                                         *
     31 ;*-------------------------------------------------------------------------*
     32 ;* Functions:                                                              *
     33 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
     34 
     35 
     36  ;		include	<mmx.inc>
     37 
     38 
     39 		.model	flat
     40 		;.686
     41 
     42 
     43 		externdef	C Detect_MMX_Availability:near
     44 		externdef	C Single_Line_Trans_Entry:near
     45 		externdef	C Next_Line:near
     46 		externdef	C Init_MMX:near
     47 		externdef	C MMX_Done:near
     48 
     49 		externdef	EndNewShapeJumpTable:byte
     50 		externdef	NewShapeJumpTable:dword
     51 		externdef	C Single_Line_Trans:near
     52 		externdef	MMX_Single_Line_Trans:near
     53 
     54 
     55 		.code
     56 
     57 externdef	C CPUType:byte
     58 
     59 
     60 
     61 ;*********************************************************************************************
     62 ;* Detect_MMX_Availability -- Detect the presence of MMX technology.                         *
     63 ;*                                                                                           *
     64 ;*                                                                                           *
     65 ;* INPUT:	Nothing                                                                      *
     66 ;*                                                                                           *
     67 ;* OUTPUT:      True if MMX technology is available.                                         *
     68 ;*                                                                                           *
     69 ;* Warnings:                                                                                 *
     70 ;*                                                                                           *
     71 ;* Note: Based in part on CPUID32.ASM by Intel                                               *
     72 ;*                                                                                           *
     73 ;* HISTORY:                                                                                  *
     74 ;*   05/19/96 ST : Created.                                                                  *
     75 ;*===========================================================================================*
     76 
     77 Detect_MMX_Availability proc C
     78 
     79 		local	idflag:byte
     80 		local	local_cputype:byte
     81 
     82 		; MMX always available now. ST - 1/3/2019 1:31PM
     83 		mov	[CPUType], 5
     84 		mov	eax, 1
     85 		ret
     86 
     87 
     88 ;assume processor is at least 386
     89 ;
     90 ;check whether AC bit in eflags can be toggled.
     91 ;If not then processor is 386
     92 
     93 		mov	[idflag],0
     94 
     95 		pushfd			;get Eflags in EAX
     96 		pop	eax
     97 		mov	ecx,eax		;save eflags
     98 		xor	eax,40000h	;toggle AC bit in eflags
     99 		push	eax		;new eflags on stack
    100 		popfd			;move new value into eflags
    101 		pushfd			;get new eflags back into eax
    102 		pop	eax
    103 		xor	eax,ecx		;if AC bit not toggled then CPU=386
    104 		mov	[local_cputype],3
    105 		jz	@@end_get_cpu	;cpu is 386
    106 
    107 		push	ecx
    108 		popfd			;restore AC bit in eflags
    109 
    110 
    111 ;processor is at least 486
    112 ;
    113 ;Check for ability to set/clear ID flag in EFLAGS
    114 ;ID flag indicates ability of processor to execute the CPUID instruction.
    115 ;486 not guaranteed to have CPUID inst?
    116 ;
    117 		mov	[local_cputype],4
    118 		mov	eax,ecx		;original EFLAGS
    119 		xor	eax,200000h	;toggle ID bit
    120 		push	eax
    121 		popfd
    122 		pushfd
    123 		pop	eax
    124 		xor	eax,ecx		;check if still toggled
    125 		jz	@@end_get_cpu
    126 
    127 
    128 ;       Execute CPUID instruction to determine vendor, family,
    129 ;       model and stepping.
    130 ;
    131 
    132 		mov	[idflag],1	;flag ID is available
    133 
    134 		xor	eax,eax
    135 		cpuid
    136 
    137 		mov	dword ptr [VendorID],ebx
    138 		mov	dword ptr [VendorID+4],edx
    139 		mov	dword ptr [VendorID+8],ecx
    140 		mov	dword ptr [VendorID+12]," "
    141 
    142 		cmp	eax,1		;check if 1 is valid
    143 		jl	@@end_get_cpu	;inp for cpuid inst.
    144 
    145 		xor	eax,eax
    146 		inc	eax
    147 
    148 		cpuid		;get stepping, model and family
    149 
    150 		and     ax,0f00H
    151 		shr     ax,08H
    152 
    153 		mov	[local_cputype],al
    154 
    155 @@end_get_cpu:	mov	al,[local_cputype]
    156 		mov	[CPUType],al
    157 
    158 
    159 ;
    160 ; We have the CPU type in al now.
    161 ; If we arent on at least a pentium then we can assume there is no MMX
    162 ;
    163 		cmp	al,5
    164 		jl	@@no_mmx
    165 
    166 		mov	eax,1
    167 		cpuid
    168 		test	edx,00800000h
    169 		jz	@@no_mmx
    170 
    171 ;
    172 ; MMX detected - return true
    173 ;
    174 		mov	eax,1
    175 		ret
    176 
    177 
    178 @@no_mmx:	xor	eax,eax
    179 		ret
    180 
    181 
    182 Detect_MMX_Availability endp
    183 
    184 
    185 
    186 ;*********************************************************************************************
    187 ;* Init_MMX -- Do any special inits required for MMX support                                 *
    188 ;*                                                                                           *
    189 ;*                                                                                           *
    190 ;* INPUT:	Nothing                                                                      *
    191 ;*                                                                                           *
    192 ;* OUTPUT:      None                                                                         *
    193 ;*                                                                                           *
    194 ;* Warnings:                                                                                 *
    195 ;*                                                                                           *
    196 ;* HISTORY:                                                                                  *
    197 ;*   05/19/96 ST : Created.                                                                  *
    198 ;*===========================================================================================*
    199 
    200 Init_MMX	proc C
    201 
    202 		mov	edi,offset NewShapeJumpTable
    203 		mov	ecx,offset EndNewShapeJumpTable
    204 		sub	ecx,edi
    205 		shr	ecx,2
    206 		mov	eax,offset Single_Line_Trans
    207 		mov	ebx,offset MMX_Single_Line_Trans
    208 		cld
    209 
    210 
    211 @@patch_loop:   repnz	scasd
    212 		jnz	@@done
    213 		mov	[edi-4],ebx
    214 		test	ecx,ecx
    215 		jnz	@@patch_loop
    216 
    217 @@done:		ret
    218 
    219 Init_MMX	endp
    220 
    221 
    222 
    223 
    224 
    225 
    226 ;*********************************************************************************************
    227 ;* MMX_Done -- Restores floating point capability after MMX usage                            *
    228 ;*                                                                                           *
    229 ;*                                                                                           *
    230 ;* INPUT:	Nothing                                                                      *
    231 ;*                                                                                           *
    232 ;* OUTPUT:      None                                                                         *
    233 ;*                                                                                           *
    234 ;* Warnings:                                                                                 *
    235 ;*                                                                                           *
    236 ;* HISTORY:                                                                                  *
    237 ;*   05/19/96 ST : Created.                                                                  *
    238 ;*===========================================================================================*
    239 
    240 MMX_Done	proc C
    241 
    242 		emms
    243 		ret
    244 
    245 MMX_Done	endp
    246 
    247 
    248 
    249 
    250 
    251 
    252 
    253 		code segment page public use32 'code'	; Need stricter segment alignment
    254 							; for pentium optimisations
    255 
    256 
    257 ;*********************************************************************************************
    258 ;* MMX_Single_Line_Trans -- draw a single line of transparent pixels using MMX technology    *
    259 ;*                                                                                           *
    260 ;*                                                                                           *
    261 ;* INPUT:	Esi - ptr to source data                                                     *
    262 ;*              Edi - ptr to destination data                                                *
    263 ;*              Ecx - width to draw in bytes                                                 *
    264 ;*                                                                                           *
    265 ;* OUTPUT:      None                                                                         *
    266 ;*                                                                                           *
    267 ;* Warnings:                                                                                 *
    268 ;*                                                                                           *
    269 ;* HISTORY:                                                                                  *
    270 ;*   05/19/96 ST : Created.                                                                  *
    271 ;*===========================================================================================*
    272 
    273 		align	16
    274 
    275 MMX_Single_Line_Trans proc near
    276 
    277 ;
    278 ; If we are doing less than 8 bytes then dont use MMX
    279 ;
    280 		cmp	ecx,8
    281 		jge	@@mmx_loop
    282 		push	offset Single_Line_Trans_Entry
    283 		ret
    284 
    285 ;
    286 ; Use MMX instructions to mask 8 bytes at once
    287 ;
    288 ; Creates a bitmask based on the source bytes equality with zero and then uses this to mask
    289 ; out the source bytes in the destination data. The advatage that MMX gives us is that there is
    290 ; no 'test for zero then jump' required to mask.
    291 ;
    292 		align	64		;MMX instructions like 64 byte alignment!
    293 
    294 @@mmx_loop:
    295 		movq	mm0,[esi]	; move 8 bytes of source into mm0
    296 		pxor	mm1,mm1		; zero out mm1
    297 		pcmpeqb mm1,mm0		; compare mm0 with 0. Bits get set in mm1
    298 		lea	esi,[esi+8]     ; adjust the source data pointer
    299 		pand	mm1,[edi]	; and in the destination data to throw away the bytes which arent zero in the source
    300 		sub	ecx,8		; adjust the byte counter
    301 		por	mm1,mm0         ; or in the source with the destination data
    302 		movq	[edi],mm1       ; write back the destination data
    303 		lea	edi,[edi+8]	; adjust the destination pointer
    304 
    305 		cmp	ecx,8
    306 		jg	@@mmx_loop
    307 
    308 ;
    309 ; Jump to the approprite code for drawing the end of this line or going to the next one
    310 ;
    311 		push	offset Next_Line
    312 		jcxz   	@@next_line
    313 		push	offset Single_Line_Trans_Entry
    314 @@next_line:	ret
    315 
    316 
    317 MMX_Single_Line_Trans endp
    318 
    319 
    320 code ends
    321 
    322 		.data
    323 
    324 CPUType		db	0
    325 VendorID	db	"Not available",0,0,0,0,0,0
    326 
    327 
    328 end