Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
201 lines (190 sloc) 11.7 KB
/* Arduboy Self destruct message
*
* A useless entry for the 4th Arduboy game Jam
*
* 15th November 2019 by Mr.Blinky
*
* MIT Licence
*
* This Program will self erase after viewing the message after 5 seconds
*
* Do not immediately power off Arduboy after the screen turns black.
* Turn power off after about 3 seconds.
*
* When turning Arduboy on again. Arduboy will enter and remain in bootloader mode
*/
#include <Arduboy2.h>
const uint8_t PROGMEM message[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0E, 0x1C, 0xF8, 0xE0, 0xFF, 0xF8, 0xE0, 0xFF, 0xF8, 0xE0, 0xFF, 0x8F, 0xC0, 0xC0, 0x40, 0xC0, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xC0, 0xF8, 0x3E, 0xC7, 0xF0, 0x7C, 0x00, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0x0F, 0x0F, 0x03, 0x01, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0x07, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x0E, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x7F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x1F, 0x1F, 0x1F, 0x07, 0x0F, 0x0F, 0x0F, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xF8, 0xFF, 0xDF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3F, 0x3F, 0x18, 0x1C, 0x0E, 0x0E, 0x07, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1C, 0x1C, 0x38, 0x30, 0x70, 0x60, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xA0, 0x70, 0x70, 0x70, 0xF0, 0xF8, 0xF8, 0xF0, 0xE0, 0x18, 0x1C, 0x0E, 0x07, 0x03, 0x01, 0x01, 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0x70, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x03, 0x1F, 0x3F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFC, 0xFC, 0x7C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0x1C, 0x1C, 0x1C, 0xF8, 0xF0, 0xC0, 0x00, 0xF0, 0xF8, 0x1C, 0x1C, 0x1C, 0x3C, 0xF8, 0xE0, 0x00, 0xFC, 0xFC, 0xF8, 0xE0, 0x80, 0x00, 0xFC, 0xFC, 0x00, 0x6C, 0x3C, 0x08, 0x00, 0x08, 0x1C, 0xFC, 0xFC, 0x1C, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0x1C, 0x1C, 0xFC, 0xF8, 0xE0, 0x00, 0xC0, 0xF8, 0x3C, 0xFC, 0xE0, 0x00, 0x00, 0xF8, 0xFC, 0xF8, 0xE0, 0x80, 0x00, 0xFC, 0xFC, 0x00, 0x00, 0xFC, 0xF8, 0x00, 0xE0, 0xF8, 0x3C, 0x1C, 0x1C, 0x1C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x70, 0x70, 0x70, 0x3E, 0x3F, 0x07, 0x00, 0x1F, 0x3F, 0x70, 0x60, 0x70, 0x78, 0x3F, 0x0F, 0x00, 0x7F, 0x7F, 0x00, 0x03, 0x07, 0x1E, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x07, 0x07, 0x07, 0x03, 0x00, 0x7C, 0x7F, 0x1F, 0x1C, 0x1D, 0x3F, 0x7E, 0x00, 0x3F, 0x7F, 0x3F, 0x01, 0x07, 0x1E, 0x7F, 0x7F, 0x00, 0x00, 0x7F, 0x3F, 0x00, 0x0F, 0x3F, 0x78, 0x70, 0x70, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
Arduboy2 arduboy;
uint16_t eraseEntryPointAddress; //var to store erase program code address
uint8_t state, seconds;
void GetEraseEntryPointAddress(void) //find the address of erase program code in bootloader
{
uint16_t addr;
asm volatile(
" ldi r30, lo8(0x7000) \n" //search from beginning of bootloader
" ldi r31, hi8(0x7000) \n" //for erase program code signature
"1: \n"
" lpm r18, z+ \n"
" cpi r18, 0x85 \n"//test for cpi r18,'e' AVR-109 (erase command)
" brne 2f \n"
" lpm r18, z+ \n"
" cpi r18, 0x36 \n"
" brne 2f \n"
" lpm r18, z+ \n"//test for 'brne k'
" andi r18, 0x07 \n"
" cpi r18, 0x01 \n"
" brne 2f \n"
" lpm r18, z+ \n"
" andi r18, 0xfc \n"
" cpi r18, 0xf4 \n"
" brne 2f \n"
" movw %A[addr], r30 \n" //return entry address
" lpm r18, z+ \n" //test for 'ldi r30, k'
" andi r18, 0xf0 \n"
" cpi r18, 0xe0 \n"
" brne 2f \n"
" lpm r18, z+ \n"
" andi r18, 0xf0 \n"
" cpi r18, 0xe0 \n"
" brne 2f \n"
" lpm r18, z+ \n" //test for 'ldi r31, k'
" andi r18, 0xf0 \n"
" cpi r18, 0xf0 \n"
" brne 2f \n"
" lpm r18, z+ \n"
" andi r18, 0xf0 \n"
" cpi r18, 0xe0 \n"
" breq 3f \n" //found erase code entry point
"2: \n"
" sbrc r30, 0 \n" //ensure even address for next test
" adiw r30, 1 \n"
" sbrs r31, 7 \n"
" rjmp 1b \n" //loop until end of flash memory
" movw %A[addr], r30 \n" //return 0x8000 for not found
"3: \n"
: [addr] "=r" (addr)
:
: "r18", "r30", "r31"
);
eraseEntryPointAddress = addr;
}
void eraseProgram(void)
{
uint16_t addr = eraseEntryPointAddress;
asm volatile(
" cli \n" //disable interrupts
" ldi r30, lo8(%[ramstart]) \n" //cler all ram
" ldi r31, hi8(%[ramstart]) \n"
"1: \n"
" st z+, r1 \n"
" cpi r31, hi8(%[ramend]) \n"
" brne 1b \n"
" movw r30, %[addr] \n"//get erase program code address
" lsr r31 \n"//convert to program word address
" ror r30 \n"
" ijmp \n"//execute
:
: [addr] "r" (addr),
[ramstart] "" (RAMSTART),
[ramend] "" (RAMEND + 1)
: "r30", "r31"
);
}
void setup() {
arduboy.begin();
GetEraseEntryPointAddress();
if (eraseEntryPointAddress != 0x8000) state++;
arduboy.frameCount = 0;
}
void loop() {
if (!arduboy.nextFrame()) return;
switch(state)
{
case 0:
{
arduboy.setCursor(34,10);
arduboy.print(F("SORRY THIS"));
arduboy.setCursor(28,20);
arduboy.print(F("ARDUBOY UNIT"));
arduboy.setCursor(16,30);
arduboy.print(F("DOES NOT SUPPORT"));
arduboy.setCursor(25,40);
arduboy.print(F("SELF DESTRUCT"));
arduboy.setCursor(40,50);
arduboy.print(F("MESSAGES"));
break;
}
case 1:
{
arduboy.setCursor(13,20);
arduboy.print(F("THIS MESSAGE WILL"));
arduboy.setCursor(25,30);
arduboy.print(F("SELF DESTRUCT"));
arduboy.setCursor(19,40);
arduboy.print(F("AFTER 5 SECONDS"));
if (arduboy.frameCount > 3 * 60) state++;
break;
}
case 2:
{
arduboy.setCursor(13,10);
arduboy.print(F("DO NOT TURN POWER"));
arduboy.setCursor(19,20);
arduboy.print(F("OFF IMMEDIATELY"));
arduboy.setCursor(19,30);
arduboy.print(F("WHEN THE SCREEN"));
arduboy.setCursor(34,40);
arduboy.print(F("GOES BLACK."));
arduboy.setCursor(10,50);
arduboy.print(F("WAIT FOR 3 SECONDS"));
if (arduboy.frameCount > 7 * 60) state++;
break;
}
case 3:
{
arduboy.setCursor(16,20);
arduboy.print(F("PRESS ANY BUTTON"));
arduboy.setCursor(31,30);
arduboy.print(F("TO VIEW THE"));
arduboy.setCursor(22,40);
arduboy.print(F("SECRET MESSAGE"));
if (arduboy.buttonsState())
{
arduboy.frameCount = 0;
seconds = 5;
state++;
}
break;
}
case 4:
{
arduboy.drawBitmap(0, 0, message, 128, 64, WHITE);
if (arduboy.frameCount >= 60)
{
arduboy.setCursor(120,0);
arduboy.print(seconds);
if (arduboy.frameCount % 60 == 59) seconds--;
if (seconds == 0) state++;
}
break;
}
case 5:
{
arduboy.displayOff();
eraseProgram();
break;
}
}
arduboy.display(CLEAR_BUFFER);
}
You can’t perform that action at this time.