MMX
[eradicate] / src / intro_s.asm
1 ; vi:ft=nasm:
2         section .text
3         bits 32
4
5         global fade_image
6 fade_image:
7         push ebp
8         mov ebp, esp
9         push ebx
10
11         mov eax, [ebp + 8]
12         mov edx, [ebp + 12]
13         mov ebx, [ebp + 16]
14         call fade_image_
15
16         pop ebx
17         pop ebp
18         ret
19
20         ; void fade_image(uint16_t *dest, uint32_t *src, uint16_t fade)
21         ;  - dest points to a 16bit 565 framebuffer
22         ;  - src points to a 32bit RGBX image
23         ;  - fade is 24.8 fixed point [0, 1]
24         ; watcom register calling convention arguments: eax, edx, ebx
25         global fade_image_
26 fade_image_:
27         push ecx
28         push edi
29
30         mov ecx, 640 * 480
31         mov edi, eax
32
33         ; take fade and duplicate it across all words of mm1
34         movd mm1, ebx           ; mm1 [00|00|00|VV]
35         punpckldq mm1, mm1      ; mm1 [00|VV|00|VV]
36         packssdw mm1, mm1       ; mm1 [VV|VV|VV|VV]
37 .loop:
38         ; grab RGB32 pixel and unpack it to zero-extended words in mm0
39         movd mm0, [edx]         ; mm0 [??|??|?R|GB]
40         add edx, 4
41         pxor mm7, mm7
42         punpcklbw mm0, mm7      ; mm0 [0?|0R|0G|0B]
43         ; multiply by fade and divide by 256 to drop the decimal part
44         pmullw mm0, mm1
45         psrlw mm0, 10   ; 8 for the div + 2 to make them 666, easier 565 packing
46         ; pack result into 565 in ax
47         packuswb mm0, mm0
48         movd eax, mm0
49         mov ebx, eax
50         shr al, 1       ; blue in position [........|00RRRRRR|00GGGGGG|000BBBBB]
51         xor bl, bl
52         shr bx, 3
53         xor ah, ah
54         or ax, bx       ; green in position ...|00RRRRRR|00000GGG|GGGBBBBB]
55         shr ebx, 6
56         and ebx, 0f800h
57         or eax, ebx     ; done [RRRRRGGG|GGGBBBBB]
58         mov [edi], ax
59         add edi, 2
60
61         dec ecx
62         jnz .loop
63
64         emms            ; clear fpu state
65
66         pop edi
67         pop ecx
68         ret