1 /*
2  * blit_c.c
3  *
4  * C version of blitters.S
5  */
6 
7 /* $Id: blit_c.c,v 1.2 2001/03/16 21:54:48 nyef Exp $ */
8 
9 #include "blitters.h"
10 
11 /*
12  * Basic merges
13  */
14 
15 #define MERGE(reg1, reg2, shift, mask) \
16   temp = reg2;    \
17   temp >>= shift; \
18   temp ^= reg1;   \
19   temp &= mask;   \
20   reg1 ^= temp;   \
21   temp <<= shift; \
22   reg2 ^= temp
23 
24 #define MERGE4(reg1, reg2) MERGE(reg1, reg2, 4, 0x0f)
25 #define MERGE2(reg1, reg2) MERGE(reg1, reg2, 2, 0x33)
26 #define MERGE1(reg1, reg2) MERGE(reg1, reg2, 1, 0x55)
27 
28 
29 /*
30  * Special merges
31  */
32 
33 #define SPECIAL_MERGE(reg1, reg2, shift, mask) \
34   reg1 = reg2;  \
35   reg1 &= mask; \
36   reg2 >>= shift
37 
38 #define MERGE_2_8(reg1, reg2) SPECIAL_MERGE(reg1, reg2, 2, 0x03)
39 #define MERGE_4_8(reg1, reg2) SPECIAL_MERGE(reg1, reg2, 4, 0x0f)
40 
41 
42 /*
43  * common code fragments
44  */
45 
46 #define ARGS_2 unsigned char pattern0, unsigned char pattern1, \
47 	       unsigned char count, unsigned char skip,        \
48 	       const unsigned char *colors, unsigned char *vbp
49 
50 #define ARGS_4 unsigned char pattern0, unsigned char pattern1, \
51 	       unsigned char pattern2, unsigned char pattern3, \
52 	       unsigned char count, unsigned char skip,        \
53 	       const unsigned char *colors, unsigned char *vbp
54 
55 #define VARIABLES_2    unsigned char pattern2, pattern3, pattern4, \
56                                      pattern5, pattern6, pattern7, temp
57 
58 #define VARIABLES_4    unsigned char pattern4, pattern5, \
59                                      pattern6, pattern7, temp
60 
61 #define SKIP_2         pattern0 <<= skip; pattern1 <<= skip
62 #define SKIP_4 SKIP_2; pattern2 <<= skip; pattern3 <<= skip
63 
64 #define SKIP_2_REV             pattern0 >>= skip; pattern1 >>= skip
65 #define SKIP_4_REV SKIP_2_REV; pattern2 >>= skip; pattern3 >>= skip
66 
67 #define COMBINE_2		   \
68     MERGE1(pattern0, pattern1);    \
69     MERGE_2_8(pattern6, pattern0); \
70     MERGE_2_8(pattern7, pattern1); \
71     MERGE_2_8(pattern4, pattern0); \
72     MERGE_2_8(pattern5, pattern1); \
73     MERGE_2_8(pattern2, pattern0); \
74     MERGE_2_8(pattern3, pattern1)
75 
76 #define COMBINE_4		   \
77     MERGE1(pattern0, pattern1);    \
78     MERGE1(pattern2, pattern3);    \
79     MERGE2(pattern0, pattern2);    \
80     MERGE2(pattern1, pattern3);    \
81     MERGE_4_8(pattern4, pattern0); \
82     MERGE_4_8(pattern5, pattern1); \
83     MERGE_4_8(pattern6, pattern2); \
84     MERGE_4_8(pattern7, pattern3)
85 
86 /*
87  * NOTE: These next might need the "do { ... } while (0)" trick when not
88  * using gcc to compile.
89  */
90 #define OUTPUT	                         \
91     switch (count) {                     \
92       case 8: vbp[7] = colors[pattern7]; \
93       case 7: vbp[6] = colors[pattern6]; \
94       case 6: vbp[5] = colors[pattern5]; \
95       case 5: vbp[4] = colors[pattern4]; \
96       case 4: vbp[3] = colors[pattern3]; \
97       case 3: vbp[2] = colors[pattern2]; \
98       case 2: vbp[1] = colors[pattern1]; \
99       case 1: vbp[0] = colors[pattern0]; \
100       default: break;                    \
101     }
102 
103 #define OUTPUT_REV			 \
104     switch (count) {			 \
105       case 8: vbp[7] = colors[pattern0]; \
106       case 7: vbp[6] = colors[pattern1]; \
107       case 6: vbp[5] = colors[pattern2]; \
108       case 5: vbp[4] = colors[pattern3]; \
109       case 4: vbp[3] = colors[pattern4]; \
110       case 3: vbp[2] = colors[pattern5]; \
111       case 2: vbp[1] = colors[pattern6]; \
112       case 1: vbp[0] = colors[pattern7]; \
113       default: break;                    \
114     }
115 
116 #define OUTPUT_CZT				       \
117     switch (count) {			 	       \
118       case 8: if (pattern7) vbp[7] = colors[pattern7]; \
119       case 7: if (pattern6) vbp[6] = colors[pattern6]; \
120       case 6: if (pattern5) vbp[5] = colors[pattern5]; \
121       case 5: if (pattern4) vbp[4] = colors[pattern4]; \
122       case 4: if (pattern3) vbp[3] = colors[pattern3]; \
123       case 3: if (pattern2) vbp[2] = colors[pattern2]; \
124       case 2: if (pattern1) vbp[1] = colors[pattern1]; \
125       case 1: if (pattern0) vbp[0] = colors[pattern0]; \
126       default: break; 			               \
127     }
128 
129 #define OUTPUT_CZT_REV				       \
130     switch (count) {			 	       \
131       case 8: if (pattern0) vbp[7] = colors[pattern0]; \
132       case 7: if (pattern1) vbp[6] = colors[pattern1]; \
133       case 6: if (pattern2) vbp[5] = colors[pattern2]; \
134       case 5: if (pattern3) vbp[4] = colors[pattern3]; \
135       case 4: if (pattern4) vbp[3] = colors[pattern4]; \
136       case 3: if (pattern5) vbp[2] = colors[pattern5]; \
137       case 2: if (pattern6) vbp[1] = colors[pattern6]; \
138       case 1: if (pattern7) vbp[0] = colors[pattern7]; \
139       default: break; 			               \
140     }
141 
142 
143 /*
144  * The blitter functions themselves.
145  */
146 
147 #if 0 /* not actually used anywhere */
148 /*
149  * NOTE: the 2-plane blitters are CZT without being declared so in their
150  * names, which might want to be changed at some point (they were originally
151  * used for NES rendering, which required CZT, and was before support for the
152  * SMS and PCE was added, which required both CZT and non-CZT 4-plane blits).
153  */
154 void blit_2_8(ARGS_2)
155 { VARIABLES_2; SKIP_2;     COMBINE_2; OUTPUT_CZT; }
156 
157 void blit_2_8_rev(ARGS_2)
158 { VARIABLES_2; SKIP_2_REV; COMBINE_2; OUTPUT_CZT_REV; }
159 #endif
160 
blit_4_8(ARGS_4)161 void blit_4_8(ARGS_4)
162 { VARIABLES_4; SKIP_4;     COMBINE_4; OUTPUT; }
163 
blit_4_8_rev(ARGS_4)164 void blit_4_8_rev(ARGS_4)
165 { VARIABLES_4; SKIP_4_REV; COMBINE_4; OUTPUT_REV; }
166 
blit_4_8_czt(ARGS_4)167 void blit_4_8_czt(ARGS_4)
168 { VARIABLES_4; SKIP_4;     COMBINE_4; OUTPUT_CZT; }
169 
blit_4_8_czt_rev(ARGS_4)170 void blit_4_8_czt_rev(ARGS_4)
171 { VARIABLES_4; SKIP_4_REV; COMBINE_4; OUTPUT_CZT_REV; }
172 
173 /*
174  * $Log: blit_c.c,v $
175  * Revision 1.2  2001/03/16 21:54:48  nyef
176  * completely rebuilt based on code from AmiDog and some preprocessor abuse
177  *
178  * Revision 1.1  1999/08/15 02:17:19  nyef
179  * Initial revision
180  *
181  */
182