1 //-----------------------------------------------------------------------------
2 // Jonathan Westhues, Mar 2006
3 // Edits by Gerhard de Koning Gans, Sep 2007 (##)
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // The main application code. This is the first thing called after start.c
11 //-----------------------------------------------------------------------------
13 #include "proxmark3.h"
28 #define abs(x) ( ((x)<0) ? -(x) : (x) )
30 //=============================================================================
31 // A buffer where we can queue things up to be sent through the FPGA, for
32 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
33 // is the order in which they go out on the wire.
34 //=============================================================================
39 struct common_area common_area
__attribute__((section(".commonarea")));
41 void BufferClear(void)
43 memset(BigBuf
,0,sizeof(BigBuf
));
44 Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf
));
47 void ToSendReset(void)
53 void ToSendStuffBit(int b
)
57 ToSend
[ToSendMax
] = 0;
62 ToSend
[ToSendMax
] |= (1 << (7 - ToSendBit
));
67 if(ToSendBit
>= sizeof(ToSend
)) {
69 DbpString("ToSendStuffBit overflowed!");
73 //=============================================================================
74 // Debug print functions, to go out over USB, to the usual PC-side client.
75 //=============================================================================
77 void DbpString(char *str
)
79 /* this holds up stuff unless we're connected to usb */
84 c
.cmd
= CMD_DEBUG_PRINT_STRING
;
85 c
.arg
[0] = strlen(str
);
86 if(c
.arg
[0] > sizeof(c
.d
.asBytes
)) {
87 c
.arg
[0] = sizeof(c
.d
.asBytes
);
89 memcpy(c
.d
.asBytes
, str
, c
.arg
[0]);
91 UsbSendPacket((uint8_t *)&c
, sizeof(c
));
92 // TODO fix USB so stupid things like this aren't req'd
97 void DbpIntegers(int x1
, int x2
, int x3
)
99 /* this holds up stuff unless we're connected to usb */
104 c
.cmd
= CMD_DEBUG_PRINT_INTEGERS
;
109 UsbSendPacket((uint8_t *)&c
, sizeof(c
));
115 void Dbprintf(const char *fmt
, ...) {
116 // should probably limit size here; oh well, let's just use a big buffer
117 char output_string
[128];
121 kvsprintf(fmt
, output_string
, 10, ap
);
124 DbpString(output_string
);
127 //-----------------------------------------------------------------------------
128 // Read an ADC channel and block till it completes, then return the result
129 // in ADC units (0 to 1023). Also a routine to average 32 samples and
131 //-----------------------------------------------------------------------------
132 static int ReadAdc(int ch
)
136 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_SWRST
;
137 AT91C_BASE_ADC
->ADC_MR
=
138 ADC_MODE_PRESCALE(32) |
139 ADC_MODE_STARTUP_TIME(16) |
140 ADC_MODE_SAMPLE_HOLD_TIME(8);
141 AT91C_BASE_ADC
->ADC_CHER
= ADC_CHANNEL(ch
);
143 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_START
;
144 while(!(AT91C_BASE_ADC
->ADC_SR
& ADC_END_OF_CONVERSION(ch
)))
146 d
= AT91C_BASE_ADC
->ADC_CDR
[ch
];
151 static int AvgAdc(int ch
)
156 for(i
= 0; i
< 32; i
++) {
160 return (a
+ 15) >> 5;
163 void MeasureAntennaTuning(void)
165 uint8_t *dest
= (uint8_t *)BigBuf
;
166 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
167 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
171 DbpString("Measuring antenna characteristics, please wait.");
172 memset(BigBuf
,0,sizeof(BigBuf
));
175 * Sweeps the useful LF range of the proxmark from
176 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
177 * read the voltage in the antenna, the result left
178 * in the buffer is a graph which should clearly show
179 * the resonating frequency of your LF antenna
180 * ( hopefully around 95 if it is tuned to 125kHz!)
182 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
183 for (i
=255; i
>19; i
--) {
184 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
186 // Vref = 3.3V, and a 10000:240 voltage divider on the input
187 // can measure voltages up to 137500 mV
188 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
189 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
190 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
192 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
201 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
202 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
204 // Vref = 3300mV, and an 10:1 voltage divider on the input
205 // can measure voltages up to 33000 mV
206 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
208 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
209 c
.arg
[0] = (vLf125
<< 0) | (vLf134
<< 16);
211 c
.arg
[2] = peakf
| (peakv
<< 16);
212 UsbSendPacket((uint8_t *)&c
, sizeof(c
));
215 void MeasureAntennaTuningHf(void)
217 int vHf
= 0; // in mV
219 DbpString("Measuring HF antenna, press button to exit");
222 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
223 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
225 // Vref = 3300mV, and an 10:1 voltage divider on the input
226 // can measure voltages up to 33000 mV
227 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
229 Dbprintf("%d mV",vHf
);
230 if (BUTTON_PRESS()) break;
232 DbpString("cancelled");
236 void SimulateTagHfListen(void)
238 uint8_t *dest
= (uint8_t *)BigBuf
;
239 int n
= sizeof(BigBuf
);
244 // We're using this mode just so that I can test it out; the simulated
245 // tag mode would work just as well and be simpler.
246 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
248 // We need to listen to the high-frequency, peak-detected path.
249 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
255 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
256 AT91C_BASE_SSC
->SSC_THR
= 0xff;
258 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
259 uint8_t r
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
;
279 DbpString("simulate tag (now type bitsamples)");
282 void ReadMem(int addr
)
284 const uint8_t *data
= ((uint8_t *)addr
);
286 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
287 addr
, data
[0], data
[1], data
[2], data
[3], data
[4], data
[5], data
[6], data
[7]);
290 /* osimage version information is linked in */
291 extern struct version_information version_information
;
292 /* bootrom version information is pointed to from _bootphase1_version_pointer */
293 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
;
294 void SendVersion(void)
296 char temp
[48]; /* Limited data payload in USB packets */
297 DbpString("Prox/RFID mark3 RFID instrument");
299 /* Try to find the bootrom version information. Expect to find a pointer at
300 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
301 * pointer, then use it.
303 char *bootrom_version
= *(char**)&_bootphase1_version_pointer
;
304 if( bootrom_version
< &_flash_start
|| bootrom_version
>= &_flash_end
) {
305 DbpString("bootrom version information appears invalid");
307 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
311 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
314 FpgaGatherVersion(temp
, sizeof(temp
));
319 // samy's sniff and repeat routine
322 DbpString("Stand-alone mode! No PC necessary.");
324 // 3 possible options? no just 2 for now
327 int high
[OPTS
], low
[OPTS
];
329 // Oooh pretty -- notify user we're in elite samy mode now
331 LED(LED_ORANGE
, 200);
333 LED(LED_ORANGE
, 200);
335 LED(LED_ORANGE
, 200);
337 LED(LED_ORANGE
, 200);
343 // Turn on selected LED
344 LED(selected
+ 1, 0);
351 // Was our button held down or pressed?
352 int button_pressed
= BUTTON_HELD(1000);
355 // Button was held for a second, begin recording
356 if (button_pressed
> 0)
359 LED(selected
+ 1, 0);
363 DbpString("Starting recording");
365 // wait for button to be released
366 while(BUTTON_PRESS())
369 /* need this delay to prevent catching some weird data */
372 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
373 Dbprintf("Recorded %x %x %x", selected
, high
[selected
], low
[selected
]);
376 LED(selected
+ 1, 0);
377 // Finished recording
379 // If we were previously playing, set playing off
380 // so next button push begins playing what we recorded
384 // Change where to record (or begin playing)
385 else if (button_pressed
)
387 // Next option if we were previously playing
389 selected
= (selected
+ 1) % OPTS
;
393 LED(selected
+ 1, 0);
395 // Begin transmitting
399 DbpString("Playing");
400 // wait for button to be released
401 while(BUTTON_PRESS())
403 Dbprintf("%x %x %x", selected
, high
[selected
], low
[selected
]);
404 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
405 DbpString("Done playing");
406 if (BUTTON_HELD(1000) > 0)
408 DbpString("Exiting");
413 /* We pressed a button so ignore it here with a delay */
416 // when done, we're done playing, move to next option
417 selected
= (selected
+ 1) % OPTS
;
420 LED(selected
+ 1, 0);
423 while(BUTTON_PRESS())
432 Listen and detect an external reader. Determine the best location
436 Inside the ListenReaderField() function, there is two mode.
437 By default, when you call the function, you will enter mode 1.
438 If you press the PM3 button one time, you will enter mode 2.
439 If you press the PM3 button a second time, you will exit the function.
441 DESCRIPTION OF MODE 1:
442 This mode just listens for an external reader field and lights up green
443 for HF and/or red for LF. This is the original mode of the detectreader
446 DESCRIPTION OF MODE 2:
447 This mode will visually represent, using the LEDs, the actual strength of the
448 current compared to the maximum current detected. Basically, once you know
449 what kind of external reader is present, it will help you spot the best location to place
450 your antenna. You will probably not get some good results if there is a LF and a HF reader
451 at the same place! :-)
455 static const char LIGHT_SCHEME
[] = {
456 0x0, /* ---- | No field detected */
457 0x1, /* X--- | 14% of maximum current detected */
458 0x2, /* -X-- | 29% of maximum current detected */
459 0x4, /* --X- | 43% of maximum current detected */
460 0x8, /* ---X | 57% of maximum current detected */
461 0xC, /* --XX | 71% of maximum current detected */
462 0xE, /* -XXX | 86% of maximum current detected */
463 0xF, /* XXXX | 100% of maximum current detected */
465 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
467 void ListenReaderField(int limit
)
469 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
470 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
471 int mode
=1, display_val
, display_max
, i
;
478 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
480 if(limit
!= HF_ONLY
) {
481 Dbprintf("LF 125/134 Baseline: %d", lf_av
);
485 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
487 if (limit
!= LF_ONLY
) {
488 Dbprintf("HF 13.56 Baseline: %d", hf_av
);
493 if (BUTTON_PRESS()) {
498 DbpString("Signal Strength Mode");
502 DbpString("Stopped");
510 if (limit
!= HF_ONLY
) {
512 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
517 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
518 // see if there's a significant change
519 if(abs(lf_av
- lf_av_new
) > 10) {
520 Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av
, lf_av_new
, lf_count
);
528 if (limit
!= LF_ONLY
) {
530 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
535 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
536 // see if there's a significant change
537 if(abs(hf_av
- hf_av_new
) > 10) {
538 Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av
, hf_av_new
, hf_count
);
547 if (limit
== LF_ONLY
) {
549 display_max
= lf_max
;
550 } else if (limit
== HF_ONLY
) {
552 display_max
= hf_max
;
553 } else { /* Pick one at random */
554 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
556 display_max
= hf_max
;
559 display_max
= lf_max
;
562 for (i
=0; i
<LIGHT_LEN
; i
++) {
563 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
564 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
565 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
566 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
567 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
575 void UsbPacketReceived(uint8_t *packet
, int len
)
577 UsbCommand
*c
= (UsbCommand
*)packet
;
583 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
584 AcquireRawAdcSamples125k(c
->arg
[0]);
585 UsbSendPacket((uint8_t*)&ack
, sizeof(ack
));
590 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
591 ModThenAcquireRawAdcSamples125k(c
->arg
[0],c
->arg
[1],c
->arg
[2],c
->d
.asBytes
);
596 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
597 AcquireRawAdcSamplesIso15693();
606 case CMD_READER_ISO_15693
:
607 ReaderIso15693(c
->arg
[0]);
611 case CMD_SIMULATE_TAG_LEGIC_RF
:
612 LegicRfSimulate(c
->arg
[0], c
->arg
[1], c
->arg
[2]);
615 case CMD_WRITER_LEGIC_RF
:
616 LegicRfWriter(c
->arg
[1], c
->arg
[0]);
619 case CMD_READER_LEGIC_RF
:
620 LegicRfReader(c
->arg
[0], c
->arg
[1]);
624 case CMD_SIMTAG_ISO_15693
:
625 SimTagIso15693(c
->arg
[0]);
629 #ifdef WITH_ISO14443b
630 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
631 AcquireRawAdcSamplesIso14443(c
->arg
[0]);
635 #ifdef WITH_ISO14443b
636 case CMD_READ_SRI512_TAG
:
637 ReadSRI512Iso14443(c
->arg
[0]);
639 case CMD_READ_SRIX4K_TAG
:
640 ReadSRIX4KIso14443(c
->arg
[0]);
644 #ifdef WITH_ISO14443a
645 case CMD_READER_ISO_14443a
:
646 ReaderIso14443a(c
->arg
[0]);
650 #ifdef WITH_ISO14443a
651 case CMD_READER_MIFARE
:
652 ReaderMifare(c
->arg
[0]);
656 #ifdef WITH_ISO14443b
657 case CMD_SNOOP_ISO_14443
:
662 #ifdef WITH_ISO14443a
663 case CMD_SNOOP_ISO_14443a
:
668 case CMD_SIMULATE_TAG_HF_LISTEN
:
669 SimulateTagHfListen();
672 #ifdef WITH_ISO14443b
673 case CMD_SIMULATE_TAG_ISO_14443
:
674 SimulateIso14443Tag();
678 #ifdef WITH_ISO14443a
679 case CMD_SIMULATE_TAG_ISO_14443a
:
680 SimulateIso14443aTag(c
->arg
[0], c
->arg
[1]); // ## Simulate iso14443a tag - pass tag type & UID
684 case CMD_MEASURE_ANTENNA_TUNING
:
685 MeasureAntennaTuning();
688 case CMD_MEASURE_ANTENNA_TUNING_HF
:
689 MeasureAntennaTuningHf();
692 case CMD_LISTEN_READER_FIELD
:
693 ListenReaderField(c
->arg
[0]);
697 case CMD_HID_DEMOD_FSK
:
698 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
703 case CMD_HID_SIM_TAG
:
704 CmdHIDsimTAG(c
->arg
[0], c
->arg
[1], 1); // Simulate HID tag by ID
708 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
709 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
711 LED_D_OFF(); // LED D indicates field ON or OFF
715 case CMD_READ_TI_TYPE
:
721 case CMD_WRITE_TI_TYPE
:
722 WriteTItag(c
->arg
[0],c
->arg
[1],c
->arg
[2]);
726 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
728 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
729 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
731 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
733 n
.arg
[0] = c
->arg
[0];
734 memcpy(n
.d
.asDwords
, BigBuf
+c
->arg
[0], 12*sizeof(uint32_t));
735 UsbSendPacket((uint8_t *)&n
, sizeof(n
));
739 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
740 uint8_t *b
= (uint8_t *)BigBuf
;
741 memcpy(b
+c
->arg
[0], c
->d
.asBytes
, 48);
742 //Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
743 UsbSendPacket((uint8_t*)&ack
, sizeof(ack
));
748 case CMD_SIMULATE_TAG_125K
:
750 SimulateTagLowFrequency(c
->arg
[0], c
->arg
[1], 1);
759 case CMD_SET_LF_DIVISOR
:
760 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->arg
[0]);
763 case CMD_SET_ADC_MUX
:
765 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break;
766 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break;
767 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break;
768 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break;
777 case CMD_LF_SIMULATE_BIDIR
:
778 SimulateTagLowFrequencyBidir(c
->arg
[0], c
->arg
[1]);
790 case CMD_SETUP_WRITE
:
791 case CMD_FINISH_WRITE
:
792 case CMD_HARDWARE_RESET
:
793 USB_D_PLUS_PULLUP_OFF();
796 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
798 // We're going to reset, and the bootrom will take control.
802 case CMD_START_FLASH
:
803 if(common_area
.flags
.bootrom_present
) {
804 common_area
.command
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
;
806 USB_D_PLUS_PULLUP_OFF();
807 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
811 case CMD_DEVICE_INFO
: {
813 c
.cmd
= CMD_DEVICE_INFO
;
814 c
.arg
[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
;
815 if(common_area
.flags
.bootrom_present
) c
.arg
[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT
;
816 UsbSendPacket((uint8_t*)&c
, sizeof(c
));
820 Dbprintf("%s: 0x%04x","unknown command:",c
->cmd
);
825 void __attribute__((noreturn
)) AppMain(void)
829 if(common_area
.magic
!= COMMON_AREA_MAGIC
|| common_area
.version
!= 1) {
830 /* Initialize common area */
831 memset(&common_area
, 0, sizeof(common_area
));
832 common_area
.magic
= COMMON_AREA_MAGIC
;
833 common_area
.version
= 1;
835 common_area
.flags
.osimage_present
= 1;
844 // The FPGA gets its clock from us from PCK0 output, so set that up.
845 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_PCK0
;
846 AT91C_BASE_PIOA
->PIO_PDR
= GPIO_PCK0
;
847 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_PCK0
;
848 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
849 AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK
|
850 AT91C_PMC_PRES_CLK_4
;
851 AT91C_BASE_PIOA
->PIO_OER
= GPIO_PCK0
;
854 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
856 AT91C_BASE_SSC
->SSC_CR
= AT91C_SSC_SWRST
;
858 // Load the FPGA image, which we have stored in our flash.
865 // test text on different colored backgrounds
866 LCDString(" The quick brown fox ", (char *)&FONT6x8
,1,1+8*0,WHITE
,BLACK
);
867 LCDString(" jumped over the ", (char *)&FONT6x8
,1,1+8*1,BLACK
,WHITE
);
868 LCDString(" lazy dog. ", (char *)&FONT6x8
,1,1+8*2,YELLOW
,RED
);
869 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8
,1,1+8*3,RED
,GREEN
);
870 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
871 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
872 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8
,1,1+8*6,BLACK
,CYAN
);
873 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
876 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
877 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
878 LCDFill(0, 1+8*10, 132, 8, RED
);
879 LCDFill(0, 1+8*11, 132, 8, GREEN
);
880 LCDFill(0, 1+8*12, 132, 8, BLUE
);
881 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
882 LCDFill(0, 1+8*14, 132, 8, CYAN
);
883 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
892 if (BUTTON_HELD(1000) > 0)