Mercurial > vba-clojure
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]) // compressed94 {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 data102 {103 control &= 0x7f;104 control += 2;105 memset(dest, *data++, control);106 len += control;107 dest += control;108 }109 else // raw data110 {111 control++;112 memcpy(dest, data, control);113 dest += control;114 data += control;115 len += control;116 }117 }118 }119 else120 {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 packet134 gbPrinterDataCount = 0;135 gbPrinterStatus = 0;136 break;137 case 0x02:138 // print packet139 gbPrinterShowData();140 break;141 case 0x04:142 // data packet143 gbPrinterReceiveData();144 break;145 case 0x0f:146 // NUL packet147 break;148 }149 }151 u8 gbPrinterSend(u8 byte)152 {153 switch (gbPrinterState)154 {155 case 0:156 gbPrinterCount = 0;157 // receiving preamble158 if (byte == 0x88)159 {160 gbPrinterPacket[gbPrinterCount++] = byte;161 gbPrinterState++;162 }163 else164 {165 // todo: handle failure166 gbPrinterReset();167 }168 break;169 case 1:170 // receiving preamble171 if (byte == 0x33)172 {173 gbPrinterPacket[gbPrinterCount++] = byte;174 gbPrinterState++;175 }176 else177 {178 // todo: handle failure179 gbPrinterReset();180 }181 break;182 case 2:183 // receiving header184 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 data193 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 receive204 case 4:205 // receiving CRC206 gbPrinterPacket[gbPrinterCount++] = byte;207 gbPrinterState++;208 break;209 case 5:210 // receiving CRC-2211 gbPrinterPacket[gbPrinterCount++] = byte;212 if (gbPrinterCheckCRC())213 {214 gbPrinterCommand();215 }216 gbPrinterState++;217 break;218 case 6:219 // receiving dummy 1220 gbPrinterPacket[gbPrinterCount++] = byte;221 gbPrinterResult = 0x81;222 gbPrinterState++;223 break;224 case 7:225 // receiving dummy 2226 gbPrinterPacket[gbPrinterCount++] = byte;227 gbPrinterResult = gbPrinterStatus;228 gbPrinterState = 0;229 gbPrinterCount = 0;230 break;231 }232 return gbPrinterResult;233 }