rename all cpp into c, as they're 99.9% C
[rofl0r-VisualBoyAdvance.git] / src / gb / gbPrinter.c
blobcf676c9b2aacbb800c7b0deb1e3fccafb4af4676
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #include <stdio.h>
20 #include <memory.h>
21 #include "../GBA.h"
23 u8 gbPrinterStatus = 0;
24 int gbPrinterState = 0;
25 u8 gbPrinterData[0x280*9];
26 u8 gbPrinterPacket[0x400];
27 int gbPrinterCount = 0;
28 int gbPrinterDataCount = 0;
29 int gbPrinterDataSize = 0;
30 int gbPrinterResult = 0;
32 bool gbPrinterCheckCRC()
34 u16 crc = 0;
36 for(int i = 2; i < (6+gbPrinterDataSize); i++) {
37 crc += gbPrinterPacket[i];
40 int msgCrc = gbPrinterPacket[6+gbPrinterDataSize] +
41 (gbPrinterPacket[7+gbPrinterDataSize]<<8);
43 return msgCrc == crc;
46 void gbPrinterReset()
48 gbPrinterState = 0;
49 gbPrinterDataSize = 0;
50 gbPrinterDataCount = 0;
51 gbPrinterCount = 0;
52 gbPrinterStatus = 0;
53 gbPrinterResult = 0;
56 void gbPrinterShowData()
58 systemGbPrint(gbPrinterData,
59 gbPrinterPacket[6],
60 gbPrinterPacket[7],
61 gbPrinterPacket[8],
62 gbPrinterPacket[9]);
64 allegro_init();
65 install_keyboard();
66 set_gfx_mode(GFX_AUTODETECT, 160, 144, 0, 0);
67 PALETTE pal;
68 pal[0].r = 255;
69 pal[0].g = 255;
70 pal[0].b = 255;
71 pal[1].r = 168;
72 pal[1].g = 168;
73 pal[1].b = 168;
74 pal[2].r = 96;
75 pal[2].g = 96;
76 pal[2].b = 96;
77 pal[3].r = 0;
78 pal[3].g = 0;
79 pal[3].b = 0;
80 set_palette(pal);
81 acquire_screen();
82 u8 *data = gbPrinterData;
83 for(int y = 0; y < 0x12; y++) {
84 for(int x = 0; x < 0x14; x++) {
85 for(int k = 0; k < 8; k++) {
86 int a = *data++;
87 int b = *data++;
88 for(int j = 0; j < 8; j++) {
89 int mask = 1 << (7-j);
90 int c = 0;
91 if(a & mask)
92 c++;
93 if(b & mask)
94 c+=2;
95 putpixel(screen, x*8+j, y*8+k, c);
100 release_screen();
101 while(!keypressed()) {
106 void gbPrinterReceiveData()
108 if(gbPrinterPacket[3]) { // compressed
109 u8 *data = &gbPrinterPacket[6];
110 u8 *dest = &gbPrinterData[gbPrinterDataCount];
111 int len = 0;
112 while(len < gbPrinterDataSize) {
113 u8 control = *data++;
114 if(control & 0x80) { // repeated data
115 control &= 0x7f;
116 control += 2;
117 memset(dest, *data++, control);
118 len += control;
119 dest += control;
120 } else { // raw data
121 control++;
122 memcpy(dest, data, control);
123 dest += control;
124 data += control;
125 len += control;
128 } else {
129 memcpy(&gbPrinterData[gbPrinterDataCount],
130 &gbPrinterPacket[6],
131 gbPrinterDataSize);
132 gbPrinterDataCount += gbPrinterDataSize;
136 void gbPrinterCommand()
138 switch(gbPrinterPacket[2]) {
139 case 0x01:
140 // reset/initialize packet
141 gbPrinterDataCount = 0;
142 gbPrinterStatus = 0;
143 break;
144 case 0x02:
145 // print packet
146 gbPrinterShowData();
147 break;
148 case 0x04:
149 // data packet
150 gbPrinterReceiveData();
151 break;
152 case 0x0f:
153 // NUL packet
154 break;
158 u8 gbPrinterSend(u8 b)
160 switch(gbPrinterState) {
161 case 0:
162 gbPrinterCount = 0;
163 // receiving preamble
164 if(b == 0x88) {
165 gbPrinterPacket[gbPrinterCount++] = b;
166 gbPrinterState++;
167 } else {
168 // todo: handle failure
169 gbPrinterReset();
171 break;
172 case 1:
173 // receiving preamble
174 if(b == 0x33) {
175 gbPrinterPacket[gbPrinterCount++] = b;
176 gbPrinterState++;
177 } else {
178 // todo: handle failure
179 gbPrinterReset();
181 break;
182 case 2:
183 // receiving header
184 gbPrinterPacket[gbPrinterCount++] = b;
185 if(gbPrinterCount == 6) {
186 gbPrinterState++;
187 gbPrinterDataSize = gbPrinterPacket[4] + (gbPrinterPacket[5]<<8);
189 break;
190 case 3:
191 // receiving data
192 if(gbPrinterDataSize) {
193 gbPrinterPacket[gbPrinterCount++] = b;
194 if(gbPrinterCount == (6+gbPrinterDataSize)) {
195 gbPrinterState++;
197 break;
199 gbPrinterState++;
200 // intentionally move to next if no data to receive
201 case 4:
202 // receiving CRC
203 gbPrinterPacket[gbPrinterCount++] = b;
204 gbPrinterState++;
205 break;
206 case 5:
207 // receiving CRC-2
208 gbPrinterPacket[gbPrinterCount++] = b;
209 if(gbPrinterCheckCRC()) {
210 gbPrinterCommand();
212 gbPrinterState++;
213 break;
214 case 6:
215 // receiving dummy 1
216 gbPrinterPacket[gbPrinterCount++] = b;
217 gbPrinterResult = 0x81;
218 gbPrinterState++;
219 break;
220 case 7:
221 // receiving dummy 2
222 gbPrinterPacket[gbPrinterCount++] = b;
223 gbPrinterResult = gbPrinterStatus;
224 gbPrinterState = 0;
225 gbPrinterCount = 0;
226 break;
228 return gbPrinterResult;