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