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