view src/gb/gbPrinter.cpp @ 378:5c4a30521d09

created efficient frame-metronome program
author Robert McIntyre <rlm@mit.edu>
date Wed, 11 Apr 2012 11:43:51 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include <cstdio>
2 #include <cstring>
4 #include "../common/System.h"
5 #include "gbPrinter.h"
7 u8 gbPrinterStatus = 0;
8 int gbPrinterState = 0;
9 u8 gbPrinterData[0x280*9];
10 u8 gbPrinterPacket[0x400];
11 int gbPrinterCount = 0;
12 int gbPrinterDataCount = 0;
13 int gbPrinterDataSize = 0;
14 int gbPrinterResult = 0;
16 bool gbPrinterCheckCRC()
17 {
18 u16 crc = 0;
20 for (int i = 2; i < (6+gbPrinterDataSize); i++)
21 {
22 crc += gbPrinterPacket[i];
23 }
25 int msgCrc = gbPrinterPacket[6+gbPrinterDataSize] +
26 (gbPrinterPacket[7+gbPrinterDataSize]<<8);
28 return msgCrc == crc;
29 }
31 void gbPrinterReset()
32 {
33 gbPrinterState = 0;
34 gbPrinterDataSize = 0;
35 gbPrinterDataCount = 0;
36 gbPrinterCount = 0;
37 gbPrinterStatus = 0;
38 gbPrinterResult = 0;
39 }
41 void gbPrinterShowData()
42 {
43 systemGbPrint(gbPrinterData,
44 gbPrinterPacket[6],
45 gbPrinterPacket[7],
46 gbPrinterPacket[8],
47 gbPrinterPacket[9]);
48 /*
49 allegro_init();
50 install_keyboard();
51 set_gfx_mode(GFX_AUTODETECT, 160, 144, 0, 0);
52 PALETTE pal;
53 pal[0].r = 255;
54 pal[0].g = 255;
55 pal[0].b = 255;
56 pal[1].r = 168;
57 pal[1].g = 168;
58 pal[1].b = 168;
59 pal[2].r = 96;
60 pal[2].g = 96;
61 pal[2].b = 96;
62 pal[3].r = 0;
63 pal[3].g = 0;
64 pal[3].b = 0;
65 set_palette(pal);
66 acquire_screen();
67 u8 *data = gbPrinterData;
68 for(int y = 0; y < 0x12; y++) {
69 for(int x = 0; x < 0x14; x++) {
70 for(int k = 0; k < 8; k++) {
71 int a = *data++;
72 int b = *data++;
73 for(int j = 0; j < 8; j++) {
74 int mask = 1 << (7-j);
75 int c = 0;
76 if(a & mask)
77 c++;
78 if(b & mask)
79 c+=2;
80 putpixel(screen, x*8+j, y*8+k, c);
81 }
82 }
83 }
84 }
85 release_screen();
86 while(!keypressed()) {
87 }
88 */
89 }
91 void gbPrinterReceiveData()
92 {
93 if (gbPrinterPacket[3]) // compressed
94 {
95 u8 *data = &gbPrinterPacket[6];
96 u8 *dest = &gbPrinterData[gbPrinterDataCount];
97 int len = 0;
98 while (len < gbPrinterDataSize)
99 {
100 u8 control = *data++;
101 if (control & 0x80) // repeated data
102 {
103 control &= 0x7f;
104 control += 2;
105 memset(dest, *data++, control);
106 len += control;
107 dest += control;
108 }
109 else // raw data
110 {
111 control++;
112 memcpy(dest, data, control);
113 dest += control;
114 data += control;
115 len += control;
116 }
117 }
118 }
119 else
120 {
121 memcpy(&gbPrinterData[gbPrinterDataCount],
122 &gbPrinterPacket[6],
123 gbPrinterDataSize);
124 gbPrinterDataCount += gbPrinterDataSize;
125 }
126 }
128 void gbPrinterCommand()
129 {
130 switch (gbPrinterPacket[2])
131 {
132 case 0x01:
133 // reset/initialize packet
134 gbPrinterDataCount = 0;
135 gbPrinterStatus = 0;
136 break;
137 case 0x02:
138 // print packet
139 gbPrinterShowData();
140 break;
141 case 0x04:
142 // data packet
143 gbPrinterReceiveData();
144 break;
145 case 0x0f:
146 // NUL packet
147 break;
148 }
149 }
151 u8 gbPrinterSend(u8 byte)
152 {
153 switch (gbPrinterState)
154 {
155 case 0:
156 gbPrinterCount = 0;
157 // receiving preamble
158 if (byte == 0x88)
159 {
160 gbPrinterPacket[gbPrinterCount++] = byte;
161 gbPrinterState++;
162 }
163 else
164 {
165 // todo: handle failure
166 gbPrinterReset();
167 }
168 break;
169 case 1:
170 // receiving preamble
171 if (byte == 0x33)
172 {
173 gbPrinterPacket[gbPrinterCount++] = byte;
174 gbPrinterState++;
175 }
176 else
177 {
178 // todo: handle failure
179 gbPrinterReset();
180 }
181 break;
182 case 2:
183 // receiving header
184 gbPrinterPacket[gbPrinterCount++] = byte;
185 if (gbPrinterCount == 6)
186 {
187 gbPrinterState++;
188 gbPrinterDataSize = gbPrinterPacket[4] + (gbPrinterPacket[5]<<8);
189 }
190 break;
191 case 3:
192 // receiving data
193 if (gbPrinterDataSize)
194 {
195 gbPrinterPacket[gbPrinterCount++] = byte;
196 if (gbPrinterCount == (6+gbPrinterDataSize))
197 {
198 gbPrinterState++;
199 }
200 break;
201 }
202 gbPrinterState++;
203 // intentionally move to next if no data to receive
204 case 4:
205 // receiving CRC
206 gbPrinterPacket[gbPrinterCount++] = byte;
207 gbPrinterState++;
208 break;
209 case 5:
210 // receiving CRC-2
211 gbPrinterPacket[gbPrinterCount++] = byte;
212 if (gbPrinterCheckCRC())
213 {
214 gbPrinterCommand();
215 }
216 gbPrinterState++;
217 break;
218 case 6:
219 // receiving dummy 1
220 gbPrinterPacket[gbPrinterCount++] = byte;
221 gbPrinterResult = 0x81;
222 gbPrinterState++;
223 break;
224 case 7:
225 // receiving dummy 2
226 gbPrinterPacket[gbPrinterCount++] = byte;
227 gbPrinterResult = gbPrinterStatus;
228 gbPrinterState = 0;
229 gbPrinterCount = 0;
230 break;
231 }
232 return gbPrinterResult;
233 }