1 //-----------------------------------------------------------------------------
2 // The main application code. This is the first thing called after start.c
4 // Jonathan Westhues, Mar 2006
5 // Edits by Gerhard de Koning Gans, Sep 2007 (##)
6 //-----------------------------------------------------------------------------
17 #define va_list __builtin_va_list
18 #define va_start __builtin_va_start
19 #define va_arg __builtin_va_arg
20 #define va_end __builtin_va_end
21 int kvsprintf(char const *fmt
, void *arg
, int radix
, va_list ap
);
23 //=============================================================================
24 // A buffer where we can queue things up to be sent through the FPGA, for
25 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
26 // is the order in which they go out on the wire.
27 //=============================================================================
32 struct common_area common_area
__attribute__((section(".commonarea")));
34 void BufferClear(void)
36 memset(BigBuf
,0,sizeof(BigBuf
));
37 Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf
));
40 void ToSendReset(void)
46 void ToSendStuffBit(int b
)
50 ToSend
[ToSendMax
] = 0;
55 ToSend
[ToSendMax
] |= (1 << (7 - ToSendBit
));
60 if(ToSendBit
>= sizeof(ToSend
)) {
62 DbpString("ToSendStuffBit overflowed!");
66 //=============================================================================
67 // Debug print functions, to go out over USB, to the usual PC-side client.
68 //=============================================================================
70 void DbpString(char *str
)
72 /* this holds up stuff unless we're connected to usb */
77 c
.cmd
= CMD_DEBUG_PRINT_STRING
;
78 c
.arg
[0] = strlen(str
);
79 if(c
.arg
[0] > sizeof(c
.d
.asBytes
)) {
80 c
.arg
[0] = sizeof(c
.d
.asBytes
);
82 memcpy(c
.d
.asBytes
, str
, c
.arg
[0]);
84 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
85 // TODO fix USB so stupid things like this aren't req'd
90 void DbpIntegers(int x1
, int x2
, int x3
)
92 /* this holds up stuff unless we're connected to usb */
97 c
.cmd
= CMD_DEBUG_PRINT_INTEGERS
;
102 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
108 void Dbprintf(const char *fmt
, ...) {
109 // should probably limit size here; oh well, let's just use a big buffer
110 char output_string
[128];
114 kvsprintf(fmt
, output_string
, 10, ap
);
117 DbpString(output_string
);
120 //-----------------------------------------------------------------------------
121 // Read an ADC channel and block till it completes, then return the result
122 // in ADC units (0 to 1023). Also a routine to average 32 samples and
124 //-----------------------------------------------------------------------------
125 static int ReadAdc(int ch
)
129 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_SWRST
;
130 AT91C_BASE_ADC
->ADC_MR
=
131 ADC_MODE_PRESCALE(32) |
132 ADC_MODE_STARTUP_TIME(16) |
133 ADC_MODE_SAMPLE_HOLD_TIME(8);
134 AT91C_BASE_ADC
->ADC_CHER
= ADC_CHANNEL(ch
);
136 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_START
;
137 while(!(AT91C_BASE_ADC
->ADC_SR
& ADC_END_OF_CONVERSION(ch
)))
139 d
= AT91C_BASE_ADC
->ADC_CDR
[ch
];
144 static int AvgAdc(int ch
)
149 for(i
= 0; i
< 32; i
++) {
153 return (a
+ 15) >> 5;
156 void MeasureAntennaTuning(void)
158 BYTE
*dest
= (BYTE
*)BigBuf
;
159 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
160 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
164 DbpString("Measuring antenna characteristics, please wait.");
165 memset(BigBuf
,0,sizeof(BigBuf
));
168 * Sweeps the useful LF range of the proxmark from
169 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
170 * read the voltage in the antenna, the result left
171 * in the buffer is a graph which should clearly show
172 * the resonating frequency of your LF antenna
173 * ( hopefully around 95 if it is tuned to 125kHz!)
175 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
176 for (i
=255; i
>19; i
--) {
177 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
179 // Vref = 3.3V, and a 10000:240 voltage divider on the input
180 // can measure voltages up to 137500 mV
181 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
182 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
183 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
185 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
194 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
195 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
197 // Vref = 3300mV, and an 10:1 voltage divider on the input
198 // can measure voltages up to 33000 mV
199 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
201 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
202 c
.arg
[0] = (vLf125
<< 0) | (vLf134
<< 16);
204 c
.arg
[2] = peakf
| (peakv
<< 16);
205 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
208 void MeasureAntennaTuningHf(void)
210 int vHf
= 0; // in mV
212 DbpString("Measuring HF antenna, press button to exit");
215 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
216 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
218 // Vref = 3300mV, and an 10:1 voltage divider on the input
219 // can measure voltages up to 33000 mV
220 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
222 Dbprintf("%d mV",vHf
);
223 if (BUTTON_PRESS()) break;
225 DbpString("cancelled");
229 void SimulateTagHfListen(void)
231 BYTE
*dest
= (BYTE
*)BigBuf
;
232 int n
= sizeof(BigBuf
);
237 // We're using this mode just so that I can test it out; the simulated
238 // tag mode would work just as well and be simpler.
239 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
241 // We need to listen to the high-frequency, peak-detected path.
242 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
248 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
249 AT91C_BASE_SSC
->SSC_THR
= 0xff;
251 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
252 BYTE r
= (BYTE
)AT91C_BASE_SSC
->SSC_RHR
;
272 DbpString("simulate tag (now type bitsamples)");
275 void ReadMem(int addr
)
277 const BYTE
*data
= ((BYTE
*)addr
);
279 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
280 addr
, data
[0], data
[1], data
[2], data
[3], data
[4], data
[5], data
[6], data
[7]);
283 /* osimage version information is linked in */
284 extern struct version_information version_information
;
285 /* bootrom version information is pointed to from _bootphase1_version_pointer */
286 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
;
287 void SendVersion(void)
289 char temp
[48]; /* Limited data payload in USB packets */
290 DbpString("Prox/RFID mark3 RFID instrument");
292 /* Try to find the bootrom version information. Expect to find a pointer at
293 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
294 * pointer, then use it.
296 char *bootrom_version
= *(char**)&_bootphase1_version_pointer
;
297 if( bootrom_version
< &_flash_start
|| bootrom_version
>= &_flash_end
) {
298 DbpString("bootrom version information appears invalid");
300 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
304 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
307 FpgaGatherVersion(temp
, sizeof(temp
));
312 // samy's sniff and repeat routine
315 DbpString("Stand-alone mode! No PC necessary.");
317 // 3 possible options? no just 2 for now
320 int high
[OPTS
], low
[OPTS
];
322 // Oooh pretty -- notify user we're in elite samy mode now
324 LED(LED_ORANGE
, 200);
326 LED(LED_ORANGE
, 200);
328 LED(LED_ORANGE
, 200);
330 LED(LED_ORANGE
, 200);
336 // Turn on selected LED
337 LED(selected
+ 1, 0);
344 // Was our button held down or pressed?
345 int button_pressed
= BUTTON_HELD(1000);
348 // Button was held for a second, begin recording
349 if (button_pressed
> 0)
352 LED(selected
+ 1, 0);
356 DbpString("Starting recording");
358 // wait for button to be released
359 while(BUTTON_PRESS())
362 /* need this delay to prevent catching some weird data */
365 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
366 Dbprintf("Recorded %x %x %x", selected
, high
[selected
], low
[selected
]);
369 LED(selected
+ 1, 0);
370 // Finished recording
372 // If we were previously playing, set playing off
373 // so next button push begins playing what we recorded
377 // Change where to record (or begin playing)
378 else if (button_pressed
)
380 // Next option if we were previously playing
382 selected
= (selected
+ 1) % OPTS
;
386 LED(selected
+ 1, 0);
388 // Begin transmitting
392 DbpString("Playing");
393 // wait for button to be released
394 while(BUTTON_PRESS())
396 Dbprintf("%x %x %x", selected
, high
[selected
], low
[selected
]);
397 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
398 DbpString("Done playing");
399 if (BUTTON_HELD(1000) > 0)
401 DbpString("Exiting");
406 /* We pressed a button so ignore it here with a delay */
409 // when done, we're done playing, move to next option
410 selected
= (selected
+ 1) % OPTS
;
413 LED(selected
+ 1, 0);
416 while(BUTTON_PRESS())
425 Listen and detect an external reader. Determine the best location
429 Inside the ListenReaderField() function, there is two mode.
430 By default, when you call the function, you will enter mode 1.
431 If you press the PM3 button one time, you will enter mode 2.
432 If you press the PM3 button a second time, you will exit the function.
434 DESCRIPTION OF MODE 1:
435 This mode just listens for an external reader field and lights up green
436 for HF and/or red for LF. This is the original mode of the detectreader
439 DESCRIPTION OF MODE 2:
440 This mode will visually represent, using the LEDs, the actual strength of the
441 current compared to the maximum current detected. Basically, once you know
442 what kind of external reader is present, it will help you spot the best location to place
443 your antenna. You will probably not get some good results if there is a LF and a HF reader
444 at the same place! :-)
448 static const char LIGHT_SCHEME
[] = {
449 0x0, /* ---- | No field detected */
450 0x1, /* X--- | 14% of maximum current detected */
451 0x2, /* -X-- | 29% of maximum current detected */
452 0x4, /* --X- | 43% of maximum current detected */
453 0x8, /* ---X | 57% of maximum current detected */
454 0xC, /* --XX | 71% of maximum current detected */
455 0xE, /* -XXX | 86% of maximum current detected */
456 0xF, /* XXXX | 100% of maximum current detected */
458 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
460 void ListenReaderField(int limit
)
462 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
463 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
464 int mode
=1, display_val
, display_max
, i
;
471 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
473 if(limit
!= HF_ONLY
) {
474 Dbprintf("LF 125/134 Baseline: %d", lf_av
);
478 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
480 if (limit
!= LF_ONLY
) {
481 Dbprintf("HF 13.56 Baseline: %d", hf_av
);
486 if (BUTTON_PRESS()) {
491 DbpString("Signal Strength Mode");
495 DbpString("Stopped");
503 if (limit
!= HF_ONLY
) {
505 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
510 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
511 // see if there's a significant change
512 if(abs(lf_av
- lf_av_new
) > 10) {
513 Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av
, lf_av_new
, lf_count
);
521 if (limit
!= LF_ONLY
) {
523 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
528 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
529 // see if there's a significant change
530 if(abs(hf_av
- hf_av_new
) > 10) {
531 Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av
, hf_av_new
, hf_count
);
540 if (limit
== LF_ONLY
) {
542 display_max
= lf_max
;
543 } else if (limit
== HF_ONLY
) {
545 display_max
= hf_max
;
546 } else { /* Pick one at random */
547 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
549 display_max
= hf_max
;
552 display_max
= lf_max
;
555 for (i
=0; i
<LIGHT_LEN
; i
++) {
556 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
557 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
558 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
559 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
560 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
568 void UsbPacketReceived(BYTE
*packet
, int len
)
570 UsbCommand
*c
= (UsbCommand
*)packet
;
574 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
575 AcquireRawAdcSamples125k(c
->arg
[0]);
580 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
581 ModThenAcquireRawAdcSamples125k(c
->arg
[0],c
->arg
[1],c
->arg
[2],c
->d
.asBytes
);
586 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
587 AcquireRawAdcSamplesIso15693();
596 case CMD_READER_ISO_15693
:
597 ReaderIso15693(c
->arg
[0]);
601 case CMD_READER_LEGIC_RF
:
606 case CMD_SIMTAG_ISO_15693
:
607 SimTagIso15693(c
->arg
[0]);
611 #ifdef WITH_ISO14443b
612 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
613 AcquireRawAdcSamplesIso14443(c
->arg
[0]);
617 #ifdef WITH_ISO14443b
618 case CMD_READ_SRI512_TAG
:
619 ReadSRI512Iso14443(c
->arg
[0]);
621 case CMD_READ_SRIX4K_TAG
:
622 ReadSRIX4KIso14443(c
->arg
[0]);
626 #ifdef WITH_ISO14443a
627 case CMD_READER_ISO_14443a
:
628 ReaderIso14443a(c
->arg
[0]);
632 #ifdef WITH_ISO14443a
633 case CMD_READER_MIFARE
:
634 ReaderMifare(c
->arg
[0]);
638 #ifdef WITH_ISO14443b
639 case CMD_SNOOP_ISO_14443
:
644 #ifdef WITH_ISO14443a
645 case CMD_SNOOP_ISO_14443a
:
650 case CMD_SIMULATE_TAG_HF_LISTEN
:
651 SimulateTagHfListen();
654 #ifdef WITH_ISO14443b
655 case CMD_SIMULATE_TAG_ISO_14443
:
656 SimulateIso14443Tag();
660 #ifdef WITH_ISO14443a
661 case CMD_SIMULATE_TAG_ISO_14443a
:
662 SimulateIso14443aTag(c
->arg
[0], c
->arg
[1]); // ## Simulate iso14443a tag - pass tag type & UID
666 case CMD_MEASURE_ANTENNA_TUNING
:
667 MeasureAntennaTuning();
670 case CMD_MEASURE_ANTENNA_TUNING_HF
:
671 MeasureAntennaTuningHf();
674 case CMD_LISTEN_READER_FIELD
:
675 ListenReaderField(c
->arg
[0]);
679 case CMD_HID_DEMOD_FSK
:
680 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
685 case CMD_HID_SIM_TAG
:
686 CmdHIDsimTAG(c
->arg
[0], c
->arg
[1], 1); // Simulate HID tag by ID
690 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
691 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
693 LED_D_OFF(); // LED D indicates field ON or OFF
697 case CMD_READ_TI_TYPE
:
703 case CMD_WRITE_TI_TYPE
:
704 WriteTItag(c
->arg
[0],c
->arg
[1],c
->arg
[2]);
708 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
710 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
711 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
713 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
715 n
.arg
[0] = c
->arg
[0];
716 memcpy(n
.d
.asDwords
, BigBuf
+c
->arg
[0], 12*sizeof(DWORD
));
717 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
721 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
723 BYTE
*b
= (BYTE
*)BigBuf
;
724 memcpy(b
+c
->arg
[0], c
->d
.asBytes
, 48);
725 //Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
727 UsbSendPacket((BYTE
*)&ack
, sizeof(ack
));
732 case CMD_SIMULATE_TAG_125K
:
734 SimulateTagLowFrequency(c
->arg
[0], c
->arg
[1], 1);
743 case CMD_SET_LF_DIVISOR
:
744 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->arg
[0]);
747 case CMD_SET_ADC_MUX
:
749 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break;
750 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break;
751 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break;
752 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break;
761 case CMD_LF_SIMULATE_BIDIR
:
762 SimulateTagLowFrequencyBidir(c
->arg
[0], c
->arg
[1]);
774 case CMD_SETUP_WRITE
:
775 case CMD_FINISH_WRITE
:
776 case CMD_HARDWARE_RESET
:
777 USB_D_PLUS_PULLUP_OFF();
780 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
782 // We're going to reset, and the bootrom will take control.
786 case CMD_START_FLASH
:
787 if(common_area
.flags
.bootrom_present
) {
788 common_area
.command
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
;
790 USB_D_PLUS_PULLUP_OFF();
791 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
795 case CMD_DEVICE_INFO
: {
797 c
.cmd
= CMD_DEVICE_INFO
;
798 c
.arg
[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
;
799 if(common_area
.flags
.bootrom_present
) c
.arg
[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT
;
800 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
804 Dbprintf("%s: 0x%04x","unknown command:",c
->cmd
);
809 void __attribute__((noreturn
)) AppMain(void)
813 if(common_area
.magic
!= COMMON_AREA_MAGIC
|| common_area
.version
!= 1) {
814 /* Initialize common area */
815 memset(&common_area
, 0, sizeof(common_area
));
816 common_area
.magic
= COMMON_AREA_MAGIC
;
817 common_area
.version
= 1;
819 common_area
.flags
.osimage_present
= 1;
828 // The FPGA gets its clock from us from PCK0 output, so set that up.
829 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_PCK0
;
830 AT91C_BASE_PIOA
->PIO_PDR
= GPIO_PCK0
;
831 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_PCK0
;
832 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
833 AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK
|
834 AT91C_PMC_PRES_CLK_4
;
835 AT91C_BASE_PIOA
->PIO_OER
= GPIO_PCK0
;
838 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
840 AT91C_BASE_SSC
->SSC_CR
= AT91C_SSC_SWRST
;
842 // Load the FPGA image, which we have stored in our flash.
849 // test text on different colored backgrounds
850 LCDString(" The quick brown fox ", (char *)&FONT6x8
,1,1+8*0,WHITE
,BLACK
);
851 LCDString(" jumped over the ", (char *)&FONT6x8
,1,1+8*1,BLACK
,WHITE
);
852 LCDString(" lazy dog. ", (char *)&FONT6x8
,1,1+8*2,YELLOW
,RED
);
853 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8
,1,1+8*3,RED
,GREEN
);
854 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
855 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
856 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8
,1,1+8*6,BLACK
,CYAN
);
857 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
860 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
861 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
862 LCDFill(0, 1+8*10, 132, 8, RED
);
863 LCDFill(0, 1+8*11, 132, 8, GREEN
);
864 LCDFill(0, 1+8*12, 132, 8, BLUE
);
865 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
866 LCDFill(0, 1+8*14, 132, 8, CYAN
);
867 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
876 if (BUTTON_HELD(1000) > 0)