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 memcpy(c
.d
.asBytes
, str
, c
.arg
[0]);
81 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
82 // TODO fix USB so stupid things like this aren't req'd
87 void DbpIntegers(int x1
, int x2
, int x3
)
89 /* this holds up stuff unless we're connected to usb */
94 c
.cmd
= CMD_DEBUG_PRINT_INTEGERS
;
99 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
105 void Dbprintf(const char *fmt
, ...) {
106 // should probably limit size here; oh well, let's just use a big buffer
107 char output_string
[128];
111 kvsprintf(fmt
, output_string
, 10, ap
);
114 DbpString(output_string
);
117 //-----------------------------------------------------------------------------
118 // Read an ADC channel and block till it completes, then return the result
119 // in ADC units (0 to 1023). Also a routine to average 32 samples and
121 //-----------------------------------------------------------------------------
122 static int ReadAdc(int ch
)
126 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_SWRST
;
127 AT91C_BASE_ADC
->ADC_MR
=
128 ADC_MODE_PRESCALE(32) |
129 ADC_MODE_STARTUP_TIME(16) |
130 ADC_MODE_SAMPLE_HOLD_TIME(8);
131 AT91C_BASE_ADC
->ADC_CHER
= ADC_CHANNEL(ch
);
133 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_START
;
134 while(!(AT91C_BASE_ADC
->ADC_SR
& ADC_END_OF_CONVERSION(ch
)))
136 d
= AT91C_BASE_ADC
->ADC_CDR
[ch
];
141 static int AvgAdc(int ch
)
146 for(i
= 0; i
< 32; i
++) {
150 return (a
+ 15) >> 5;
153 void MeasureAntennaTuning(void)
155 BYTE
*dest
= (BYTE
*)BigBuf
;
156 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
157 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
161 DbpString("Measuring antenna characteristics, please wait.");
162 memset(BigBuf
,0,sizeof(BigBuf
));
165 * Sweeps the useful LF range of the proxmark from
166 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
167 * read the voltage in the antenna, the result left
168 * in the buffer is a graph which should clearly show
169 * the resonating frequency of your LF antenna
170 * ( hopefully around 95 if it is tuned to 125kHz!)
172 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
173 for (i
=255; i
>19; i
--) {
174 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
176 // Vref = 3.3V, and a 10000:240 voltage divider on the input
177 // can measure voltages up to 137500 mV
178 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
179 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
180 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
182 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
191 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
192 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
194 // Vref = 3300mV, and an 10:1 voltage divider on the input
195 // can measure voltages up to 33000 mV
196 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
198 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
199 c
.arg
[0] = (vLf125
<< 0) | (vLf134
<< 16);
201 c
.arg
[2] = peakf
| (peakv
<< 16);
202 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
205 void MeasureAntennaTuningHf(void)
207 int vHf
= 0; // in mV
209 DbpString("Measuring HF antenna, press button to exit");
212 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
213 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
215 // Vref = 3300mV, and an 10:1 voltage divider on the input
216 // can measure voltages up to 33000 mV
217 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
219 Dbprintf("%d mV",vHf
);
220 if (BUTTON_PRESS()) break;
222 DbpString("cancelled");
226 void SimulateTagHfListen(void)
228 BYTE
*dest
= (BYTE
*)BigBuf
;
229 int n
= sizeof(BigBuf
);
234 // We're using this mode just so that I can test it out; the simulated
235 // tag mode would work just as well and be simpler.
236 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
238 // We need to listen to the high-frequency, peak-detected path.
239 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
245 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
246 AT91C_BASE_SSC
->SSC_THR
= 0xff;
248 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
249 BYTE r
= (BYTE
)AT91C_BASE_SSC
->SSC_RHR
;
269 DbpString("simulate tag (now type bitsamples)");
272 void ReadMem(int addr
)
274 const BYTE
*data
= ((BYTE
*)addr
);
276 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
277 addr
, data
[0], data
[1], data
[2], data
[3], data
[4], data
[5], data
[6], data
[7]);
280 /* osimage version information is linked in */
281 extern struct version_information version_information
;
282 /* bootrom version information is pointed to from _bootphase1_version_pointer */
283 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
;
284 void SendVersion(void)
286 char temp
[48]; /* Limited data payload in USB packets */
287 DbpString("Prox/RFID mark3 RFID instrument");
289 /* Try to find the bootrom version information. Expect to find a pointer at
290 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
291 * pointer, then use it.
293 char *bootrom_version
= *(char**)&_bootphase1_version_pointer
;
294 if( bootrom_version
< &_flash_start
|| bootrom_version
>= &_flash_end
) {
295 DbpString("bootrom version information appears invalid");
297 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
301 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
304 FpgaGatherVersion(temp
, sizeof(temp
));
309 // samy's sniff and repeat routine
312 DbpString("Stand-alone mode! No PC necessary.");
314 // 3 possible options? no just 2 for now
317 int high
[OPTS
], low
[OPTS
];
319 // Oooh pretty -- notify user we're in elite samy mode now
321 LED(LED_ORANGE
, 200);
323 LED(LED_ORANGE
, 200);
325 LED(LED_ORANGE
, 200);
327 LED(LED_ORANGE
, 200);
333 // Turn on selected LED
334 LED(selected
+ 1, 0);
341 // Was our button held down or pressed?
342 int button_pressed
= BUTTON_HELD(1000);
345 // Button was held for a second, begin recording
346 if (button_pressed
> 0)
349 LED(selected
+ 1, 0);
353 DbpString("Starting recording");
355 // wait for button to be released
356 while(BUTTON_PRESS())
359 /* need this delay to prevent catching some weird data */
362 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
363 Dbprintf("Recorded %x %x %x", selected
, high
[selected
], low
[selected
]);
366 LED(selected
+ 1, 0);
367 // Finished recording
369 // If we were previously playing, set playing off
370 // so next button push begins playing what we recorded
374 // Change where to record (or begin playing)
375 else if (button_pressed
)
377 // Next option if we were previously playing
379 selected
= (selected
+ 1) % OPTS
;
383 LED(selected
+ 1, 0);
385 // Begin transmitting
389 DbpString("Playing");
390 // wait for button to be released
391 while(BUTTON_PRESS())
393 Dbprintf("%x %x %x", selected
, high
[selected
], low
[selected
]);
394 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
395 DbpString("Done playing");
396 if (BUTTON_HELD(1000) > 0)
398 DbpString("Exiting");
403 /* We pressed a button so ignore it here with a delay */
406 // when done, we're done playing, move to next option
407 selected
= (selected
+ 1) % OPTS
;
410 LED(selected
+ 1, 0);
413 while(BUTTON_PRESS())
422 Listen and detect an external reader. Determine the best location
426 Inside the ListenReaderField() function, there is two mode.
427 By default, when you call the function, you will enter mode 1.
428 If you press the PM3 button one time, you will enter mode 2.
429 If you press the PM3 button a second time, you will exit the function.
431 DESCRIPTION OF MODE 1:
432 This mode just listens for an external reader field and lights up green
433 for HF and/or red for LF. This is the original mode of the detectreader
436 DESCRIPTION OF MODE 2:
437 This mode will visually represent, using the LEDs, the actual strength of the
438 current compared to the maximum current detected. Basically, once you know
439 what kind of external reader is present, it will help you spot the best location to place
440 your antenna. You will probably not get some good results if there is a LF and a HF reader
441 at the same place! :-)
445 static const char LIGHT_SCHEME
[] = {
446 0x0, /* ---- | No field detected */
447 0x1, /* X--- | 14% of maximum current detected */
448 0x2, /* -X-- | 29% of maximum current detected */
449 0x4, /* --X- | 43% of maximum current detected */
450 0x8, /* ---X | 57% of maximum current detected */
451 0xC, /* --XX | 71% of maximum current detected */
452 0xE, /* -XXX | 86% of maximum current detected */
453 0xF, /* XXXX | 100% of maximum current detected */
455 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
457 void ListenReaderField(int limit
)
459 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
460 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
461 int mode
=1, display_val
, display_max
, i
;
468 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
470 if(limit
!= HF_ONLY
) {
471 Dbprintf("LF 125/134 Baseline: %d", lf_av
);
475 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
477 if (limit
!= LF_ONLY
) {
478 Dbprintf("HF 13.56 Baseline: %d", hf_av
);
483 if (BUTTON_PRESS()) {
488 DbpString("Signal Strength Mode");
492 DbpString("Stopped");
500 if (limit
!= HF_ONLY
) {
502 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
507 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
508 // see if there's a significant change
509 if(abs(lf_av
- lf_av_new
) > 10) {
510 Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av
, lf_av_new
, lf_count
);
518 if (limit
!= LF_ONLY
) {
520 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
525 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
526 // see if there's a significant change
527 if(abs(hf_av
- hf_av_new
) > 10) {
528 Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av
, hf_av_new
, hf_count
);
537 if (limit
== LF_ONLY
) {
539 display_max
= lf_max
;
540 } else if (limit
== HF_ONLY
) {
542 display_max
= hf_max
;
543 } else { /* Pick one at random */
544 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
546 display_max
= hf_max
;
549 display_max
= lf_max
;
552 for (i
=0; i
<LIGHT_LEN
; i
++) {
553 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
554 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
555 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
556 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
557 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
565 void UsbPacketReceived(BYTE
*packet
, int len
)
567 UsbCommand
*c
= (UsbCommand
*)packet
;
571 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
572 AcquireRawAdcSamples125k(c
->arg
[0]);
577 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
578 ModThenAcquireRawAdcSamples125k(c
->arg
[0],c
->arg
[1],c
->arg
[2],c
->d
.asBytes
);
583 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
584 AcquireRawAdcSamplesIso15693();
593 case CMD_READER_ISO_15693
:
594 ReaderIso15693(c
->arg
[0]);
598 case CMD_READER_LEGIC_RF
:
603 case CMD_SIMTAG_ISO_15693
:
604 SimTagIso15693(c
->arg
[0]);
608 #ifdef WITH_ISO14443b
609 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
610 AcquireRawAdcSamplesIso14443(c
->arg
[0]);
614 #ifdef WITH_ISO14443b
615 case CMD_READ_SRI512_TAG
:
616 ReadSRI512Iso14443(c
->arg
[0]);
618 case CMD_READ_SRIX4K_TAG
:
619 ReadSRIX4KIso14443(c
->arg
[0]);
623 #ifdef WITH_ISO14443a
624 case CMD_READER_ISO_14443a
:
625 ReaderIso14443a(c
->arg
[0]);
629 #ifdef WITH_ISO14443a
630 case CMD_READER_MIFARE
:
631 ReaderMifare(c
->arg
[0]);
635 #ifdef WITH_ISO14443b
636 case CMD_SNOOP_ISO_14443
:
641 #ifdef WITH_ISO14443a
642 case CMD_SNOOP_ISO_14443a
:
647 case CMD_SIMULATE_TAG_HF_LISTEN
:
648 SimulateTagHfListen();
651 #ifdef WITH_ISO14443b
652 case CMD_SIMULATE_TAG_ISO_14443
:
653 SimulateIso14443Tag();
657 #ifdef WITH_ISO14443a
658 case CMD_SIMULATE_TAG_ISO_14443a
:
659 SimulateIso14443aTag(c
->arg
[0], c
->arg
[1]); // ## Simulate iso14443a tag - pass tag type & UID
663 case CMD_MEASURE_ANTENNA_TUNING
:
664 MeasureAntennaTuning();
667 case CMD_MEASURE_ANTENNA_TUNING_HF
:
668 MeasureAntennaTuningHf();
671 case CMD_LISTEN_READER_FIELD
:
672 ListenReaderField(c
->arg
[0]);
676 case CMD_HID_DEMOD_FSK
:
677 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
682 case CMD_HID_SIM_TAG
:
683 CmdHIDsimTAG(c
->arg
[0], c
->arg
[1], 1); // Simulate HID tag by ID
687 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
688 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
690 LED_D_OFF(); // LED D indicates field ON or OFF
694 case CMD_READ_TI_TYPE
:
700 case CMD_WRITE_TI_TYPE
:
701 WriteTItag(c
->arg
[0],c
->arg
[1],c
->arg
[2]);
705 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
707 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
708 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
710 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
712 n
.arg
[0] = c
->arg
[0];
713 memcpy(n
.d
.asDwords
, BigBuf
+c
->arg
[0], 12*sizeof(DWORD
));
714 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
718 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
720 BYTE
*b
= (BYTE
*)BigBuf
;
721 memcpy(b
+c
->arg
[0], c
->d
.asBytes
, 48);
722 //Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
724 UsbSendPacket((BYTE
*)&ack
, sizeof(ack
));
729 case CMD_SIMULATE_TAG_125K
:
731 SimulateTagLowFrequency(c
->arg
[0], c
->arg
[1], 1);
740 case CMD_SET_LF_DIVISOR
:
741 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->arg
[0]);
744 case CMD_SET_ADC_MUX
:
746 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break;
747 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break;
748 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break;
749 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break;
758 case CMD_LF_SIMULATE_BIDIR
:
759 SimulateTagLowFrequencyBidir(c
->arg
[0], c
->arg
[1]);
771 case CMD_SETUP_WRITE
:
772 case CMD_FINISH_WRITE
:
773 case CMD_HARDWARE_RESET
:
774 USB_D_PLUS_PULLUP_OFF();
777 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
779 // We're going to reset, and the bootrom will take control.
783 case CMD_START_FLASH
:
784 if(common_area
.flags
.bootrom_present
) {
785 common_area
.command
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
;
787 USB_D_PLUS_PULLUP_OFF();
788 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
792 case CMD_DEVICE_INFO
: {
794 c
.cmd
= CMD_DEVICE_INFO
;
795 c
.arg
[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
;
796 if(common_area
.flags
.bootrom_present
) c
.arg
[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT
;
797 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
801 Dbprintf("%s: 0x%04x","unknown command:",c
->cmd
);
806 void __attribute__((noreturn
)) AppMain(void)
810 if(common_area
.magic
!= COMMON_AREA_MAGIC
|| common_area
.version
!= 1) {
811 /* Initialize common area */
812 memset(&common_area
, 0, sizeof(common_area
));
813 common_area
.magic
= COMMON_AREA_MAGIC
;
814 common_area
.version
= 1;
816 common_area
.flags
.osimage_present
= 1;
825 // The FPGA gets its clock from us from PCK0 output, so set that up.
826 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_PCK0
;
827 AT91C_BASE_PIOA
->PIO_PDR
= GPIO_PCK0
;
828 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_PCK0
;
829 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
830 AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK
|
831 AT91C_PMC_PRES_CLK_4
;
832 AT91C_BASE_PIOA
->PIO_OER
= GPIO_PCK0
;
835 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
837 AT91C_BASE_SSC
->SSC_CR
= AT91C_SSC_SWRST
;
839 // Load the FPGA image, which we have stored in our flash.
846 // test text on different colored backgrounds
847 LCDString(" The quick brown fox ", (char *)&FONT6x8
,1,1+8*0,WHITE
,BLACK
);
848 LCDString(" jumped over the ", (char *)&FONT6x8
,1,1+8*1,BLACK
,WHITE
);
849 LCDString(" lazy dog. ", (char *)&FONT6x8
,1,1+8*2,YELLOW
,RED
);
850 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8
,1,1+8*3,RED
,GREEN
);
851 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
852 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
853 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8
,1,1+8*6,BLACK
,CYAN
);
854 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
857 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
858 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
859 LCDFill(0, 1+8*10, 132, 8, RED
);
860 LCDFill(0, 1+8*11, 132, 8, GREEN
);
861 LCDFill(0, 1+8*12, 132, 8, BLUE
);
862 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
863 LCDFill(0, 1+8*14, 132, 8, CYAN
);
864 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
873 if (BUTTON_HELD(1000) > 0)