#include #include #define PIEZO_BIT 0x04 #define BTN_BIT 0x40 #define POUT P2OUT #define DC_BIT 0x01 #define DIN_BIT 0x02 #define CLK_BIT 0x04 #define RST_BIT 0x08 #define MODE_CMD 0 #define MODE_DATA 1 #define WIDTH 84 #define HEIGHT 48 void delay_ms(uint16_t ms) { while (ms--) __delay_cycles(1000 * 16); } inline void lcd_delay() { __delay_cycles(12); } void lcd_mode(char cmd) { if (cmd) POUT |= DC_BIT; else POUT &= ~DC_BIT; } void lcd_write(char data) { for (int i = 0; i < 8; i++) { if (data & 0x80) POUT |= DIN_BIT; else POUT &= ~DIN_BIT; POUT |= CLK_BIT; lcd_delay(); POUT &= ~CLK_BIT; lcd_delay(); data <<= 1; } POUT &= ~DIN_BIT; } void lcd_locate(char x, char y) { lcd_mode(MODE_CMD); lcd_delay(); lcd_write(0x80 | x); lcd_write(0x40 | y); lcd_mode(MODE_DATA); lcd_delay(); } void lcd_reset() { POUT &= ~RST_BIT; lcd_delay(); POUT |= RST_BIT; lcd_delay(); lcd_mode(MODE_CMD); lcd_delay(); lcd_write(0x20); lcd_write(0x0c); lcd_mode(MODE_DATA); lcd_delay(); lcd_locate(0, 0); for (int i = 0; i < WIDTH * HEIGHT/8; i++) lcd_write(0x00); } void sound_out(int count) { if (count == 0) { TACTL = TACLR; TACCTL1 = OUTMOD_0; } else { TACTL = TASSEL_2 | MC_1; TACCR0 = count; TACCR1 = count >> 1; TACCTL1 = OUTMOD_7; } } // 587Hz, 698Hz // 1703 #include "gen.c" void skull_trumpet() { char btn_prev = 1; int count = 0; int prev_frame = -1, frame = 0; while (1) { if (frame != prev_frame) { prev_frame = frame; lcd_locate(0, 0); const char *p = frames[frame]; for (int i = 0; i < WIDTH*HEIGHT/8; i++) lcd_write(*p++); } char btn = !(P1IN & BTN_BIT); if (btn && !btn_prev) { sound_out(0); count = 142; } btn_prev = btn; if (count) { count--; if (count == 140) { sound_out(1703 * 16); frame = 3; } else if (count == 130) { sound_out(1432 * 16); frame = 6; } else if (count == 105) { sound_out(0); frame = 5; } else if (count == 90) { frame = 6; } else if (count == 75) { frame = 5; } else if (count == 60) { frame = 4; } else if (count == 45) { frame = 3; } else if (count == 30) { frame = 2; } else if (count == 15) { frame = 1; } else if (count == 0) { frame = 0; } } delay_ms(10); } } typedef short fixed; const fixed sin_table[] = {0,1,3,4,6,7,9,10,12,14,15,17,18,20,21,23,25,26,28,29,31,32,34,36,37,39,40,42,43,45,46,48,49,51,53,54,56,57,59,60,62,63,65,66,68,69,71,72,74,75,77,78,80,81,83,84,86,87,89,90,92,93,95,96,97,99,100,102,103,105,106,108,109,110,112,113,115,116,117,119,120,122,123,124,126,127,128,130,131,132,134,135,136,138,139,140,142,143,144,146,147,148,149,151,152,153,155,156,157,158,159,161,162,163,164,166,167,168,169,170,171,173,174,175,176,177,178,179,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,211,212,213,214,215,216,217,217,218,219,220,221,221,222,223,224,225,225,226,227,227,228,229,230,230,231,232,232,233,234,234,235,235,236,237,237,238,238,239,239,240,241,241,242,242,243,243,244,244,244,245,245,246,246,247,247,247,248,248,249,249,249,250,250,250,251,251,251,251,252,252,252,252,253,253,253,253,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,256,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,254,254,254,254,254,253,253,253,253,252,252,252,252,251,251,251,251,250,250,250,249,249,249,248,248,247,247,247,246,246,245,245,244,244,244,243,243,242,242,241,241,240,239,239,238,238,237,237,236,235,235,234,234,233,232,232,231,230,230,229,228,227,227,226,225,225,224,223,222,221,221,220,219,218,217,217,216,215,214,213,212,211,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,179,178,177,176,175,174,173,171,170,169,168,167,166,164,163,162,161,159,158,157,156,155,153,152,151,149,148,147,146,144,143,142,140,139,138,136,135,134,132,131,130,128,127,126,124,123,122,120,119,117,116,115,113,112,110,109,108,106,105,103,102,100,99,97,96,95,93,92,90,89,87,86,84,83,81,80,78,77,75,74,72,71,69,68,66,65,63,62,60,59,57,56,54,53,51,49,48,46,45,43,42,40,39,37,36,34,32,31,29,28,26,25,23,21,20,18,17,15,14,12,10,9,7,6,4,3,1,0,-1,-3,-4,-6,-7,-9,-10,-12,-14,-15,-17,-18,-20,-21,-23,-25,-26,-28,-29,-31,-32,-34,-36,-37,-39,-40,-42,-43,-45,-46,-48,-49,-51,-53,-54,-56,-57,-59,-60,-62,-63,-65,-66,-68,-69,-71,-72,-74,-75,-77,-78,-80,-81,-83,-84,-86,-87,-89,-90,-92,-93,-95,-96,-97,-99,-100,-102,-103,-105,-106,-108,-109,-110,-112,-113,-115,-116,-117,-119,-120,-122,-123,-124,-126,-127,-128,-130,-131,-132,-134,-135,-136,-138,-139,-140,-142,-143,-144,-146,-147,-148,-149,-151,-152,-153,-155,-156,-157,-158,-159,-161,-162,-163,-164,-166,-167,-168,-169,-170,-171,-173,-174,-175,-176,-177,-178,-179,-181,-182,-183,-184,-185,-186,-187,-188,-189,-190,-191,-192,-193,-194,-195,-196,-197,-198,-199,-200,-201,-202,-203,-204,-205,-206,-207,-208,-209,-210,-211,-211,-212,-213,-214,-215,-216,-217,-217,-218,-219,-220,-221,-221,-222,-223,-224,-225,-225,-226,-227,-227,-228,-229,-230,-230,-231,-232,-232,-233,-234,-234,-235,-235,-236,-237,-237,-238,-238,-239,-239,-240,-241,-241,-242,-242,-243,-243,-244,-244,-244,-245,-245,-246,-246,-247,-247,-247,-248,-248,-249,-249,-249,-250,-250,-250,-251,-251,-251,-251,-252,-252,-252,-252,-253,-253,-253,-253,-254,-254,-254,-254,-254,-254,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-256,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-254,-254,-254,-254,-254,-254,-253,-253,-253,-253,-252,-252,-252,-252,-251,-251,-251,-251,-250,-250,-250,-249,-249,-249,-248,-248,-247,-247,-247,-246,-246,-245,-245,-244,-244,-244,-243,-243,-242,-242,-241,-241,-240,-239,-239,-238,-238,-237,-237,-236,-235,-235,-234,-234,-233,-232,-232,-231,-230,-230,-229,-228,-227,-227,-226,-225,-225,-224,-223,-222,-221,-221,-220,-219,-218,-217,-217,-216,-215,-214,-213,-212,-211,-211,-210,-209,-208,-207,-206,-205,-204,-203,-202,-201,-200,-199,-198,-197,-196,-195,-194,-193,-192,-191,-190,-189,-188,-187,-186,-185,-184,-183,-182,-181,-179,-178,-177,-176,-175,-174,-173,-171,-170,-169,-168,-167,-166,-164,-163,-162,-161,-159,-158,-157,-156,-155,-153,-152,-151,-149,-148,-147,-146,-144,-143,-142,-140,-139,-138,-136,-135,-134,-132,-131,-130,-128,-127,-126,-124,-123,-122,-120,-119,-117,-116,-115,-113,-112,-110,-109,-108,-106,-105,-103,-102,-100,-99,-97,-96,-95,-93,-92,-90,-89,-87,-86,-84,-83,-81,-80,-78,-77,-75,-74,-72,-71,-69,-68,-66,-65,-63,-62,-60,-59,-57,-56,-54,-53,-51,-49,-48,-46,-45,-43,-42,-40,-39,-37,-36,-34,-32,-31,-29,-28,-26,-25,-23,-21,-20,-18,-17,-15,-14,-12,-10,-9,-7,-6,-4,-3,-1}; inline fixed intf(int i) { return (((fixed)i) << 8); } inline int fint(fixed f) { return (int)(f >> 8); } inline fixed fmul(fixed a, fixed b) { return ((long)a * (long)b) >> 8; } inline fixed fsin(int angle) { return sin_table[angle & 0x3ff]; } inline fixed fcos(int angle) { return fsin(angle + 256); } char buf[WIDTH]; void rotozoom() { int angle = 0, angle2 = 0, angle3 = 0; while (1) { lcd_locate(0, 0); fixed s = fsin(angle), c = fcos(angle); fixed scale = 100 + (fsin(angle2) >> 2); fixed right_x = fmul(scale, c - s), right_y = fmul(scale, c + s); fixed down_x = right_y, down_y = -right_x; fixed rowstartx = 0, rowstarty = 0; for (int y = 0; y < HEIGHT; y += 8) { fixed tilestartx = rowstartx, tilestarty = rowstarty; for (int x = 0; x < WIDTH; x++) { fixed sy = tilestarty, sx = tilestartx; char byte = 0; for (char bit = 0x01; bit; bit <<= 1) { if ((fint(sx) ^ fint(sy)) & 0x08) byte |= bit; sx += down_x; sy += down_y; } lcd_write(byte); tilestartx += right_x; tilestarty += right_y; } rowstartx += down_x << 3; rowstarty += down_y << 3; } delay_ms(62); angle += 11; angle2 += 31; angle3 += 3; } } int main() { // Disable watchdog WDTCTL = WDTPW | WDTHOLD; // 1MHz internal timer BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // Button input, piezo output P1DIR = PIEZO_BIT; P1REN = BTN_BIT; P1OUT = BTN_BIT; P1SEL |= PIEZO_BIT; sound_out(0); // LCD output P2DIR = CLK_BIT | DIN_BIT | DC_BIT | RST_BIT; P2OUT = 0x00; lcd_reset(); lcd_locate(0, 0); if (P1IN & BTN_BIT) rotozoom(); else skull_trumpet(); }