source: tools/FAD/ddd_for_fad/Functions.cpp@ 248

Last change on this file since 248 was 248, checked in by dneise, 14 years ago
initial check in of FAD tools simple daq - simple command line interface to FAD will produce binary socket_x.dat files ddd_for_fad - simple GUI able to plot FAD raw data.
File size: 17.9 KB
Line 
1
2#include "GUI.h"
3#include "SocketClient.h"
4#include "ViewEvent.h"
5#include "math.h"
6// Quit application when clicking close button on window
7void fad::closeEvent(QCloseEvent *) {
8 qApp->quit();
9}
10
11// +++ Connecting or disconnecting from client +++
12void fad::MakeConnection() {
13
14 if(Socket[0]->state() == QAbstractSocket::ConnectedState) {
15 ManualDisconnect = true;
16 for (int i=0; i<NUM_SOCKETS; i++) Socket[i]->disconnectFromHost();
17 return;
18 }
19
20 for (int i=0; i<NUM_SOCKETS; i++) {
21 Connect->setEnabled(false);
22 Socket[i]->connectToHost(IPAddress->text(),Port->value() + i);
23 Socket[i]->waitForConnected(SOCKET_TIMEOUT);
24 Connect->setEnabled(true);
25
26 if (Socket[i]->state() != QAbstractSocket::ConnectedState) {
27 QMessageBox::warning(this, "fad Message","Could not connect to host.",QMessageBox::Ok);
28 return;
29 }
30 }
31
32 Connect->setText("Disconnect");
33 ConnectAction->setText("Disconnect");
34 Port->setEnabled(false);
35 IPAddress->setEnabled(false);
36 Command->setEnabled(true);
37 ManualDisconnect = false;
38}
39
40// +++ Send command to socket +++
41void fad::SendToSocket() {
42
43 char *Buffer = Command->text().toAscii().data();
44
45 int i;
46 unsigned short CMD_Buffer[512];
47 unsigned char CMD_Str[16];
48 unsigned short CMD_Num = 1;
49 int val, num;
50
51 if (strncmp (Buffer, "r", 2) == 0)
52 {
53 CMD_Buffer[0] = htons (CMD_Start);
54 printf ("# Start Run ->\n");
55 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
56 }
57
58 else if (strncmp (Buffer, "s", 2) == 0)
59 {
60 CMD_Buffer[0] = htons (CMD_Stop);
61 printf ("# Stop Run ->\n");
62 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
63 }
64
65 else if (strncmp (Buffer, "sz", 3) == 0)
66 {
67 CMD_Buffer[0] = 0x0000;
68 printf ("# Send 0x0000 ->\n");
69 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
70 }
71 else if (strncmp (Buffer, "de\n", 2) == 0)
72 {
73 CMD_Buffer[0] = htons (CMD_DENABLE);
74 printf ("# domino wave enabled ->\n");
75 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
76 }
77
78 else if (strncmp (Buffer, "dd\n", 2) == 0)
79 {
80 CMD_Buffer[0] = htons (CMD_DDISABLE);
81 printf ("# domino wave disabled ->\n");
82 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
83 }
84
85 else if (strncmp (Buffer, "dr\n", 2) == 0)
86 {
87 CMD_Buffer[0] = htons (CMD_DWRITE_RUN);
88 printf ("# DWRITE HIGH->\n");
89 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
90 }
91
92 else if (strncmp (Buffer, "ds\n", 2) == 0)
93 {
94 CMD_Buffer[0] = htons (CMD_DWRITE_STOP);
95 printf ("# DWRITE LOW ->\n");
96 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
97 }
98
99 else if (strncmp (Buffer, "t", 2) == 0)
100 {
101 CMD_Buffer[0] = htons (CMD_Trigger);
102 printf ("# Trigger ->\n");
103 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
104 }
105
106 else if (strncmp (Buffer, "tc", 3) == 0)
107 {
108 CMD_Buffer[0] = htons (CMD_Trigger_C);
109 printf ("# Continuous Trigger ->\n");
110 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
111 }
112
113 else if (strncmp (Buffer, "ts", 3) == 0)
114 {
115 CMD_Buffer[0] = htons (CMD_Trigger_S);
116 printf ("# Stop Trigger ->\n");
117 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
118 }
119
120 // Set ROI value
121 else if (strncmp (Buffer, "sr ", 3) == 0)
122 {
123 CMD_Num = 0;
124 if (sscanf (Buffer, "%3s %i %i", CMD_Str, &num, &val) == 3)
125 {
126 if ((num >= 0) & (num <= MAX_ROINUM) & (val >= 0) & (val <= MAX_ROIVAL))
127 {
128 printf ("# Set ROI %d to %d ->\n", num, val);
129 CMD_Buffer[0] = htons (CMD_Write | (BADDR_ROI + num));
130 CMD_Buffer[1] = htons (val);
131 printf ("# 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[0]), ntohs (CMD_Buffer[1]));
132 CMD_Num = 2;
133 }
134 else
135 {
136 printf ("Out of range\n");
137 printf ("Usage: sr NUM VAL: Set ROI NUM (0-%d) to VAL (0-%d)\n", MAX_ROINUM, MAX_ROIVAL);
138 }
139 }
140 else
141 {
142 printf ("Usage: sr NUM VAL: Set ROI NUM (0-%d) to VAL (0-%d)\n", MAX_ROINUM, MAX_ROIVAL);
143 }
144 }
145
146 // Set all ROIs
147 else if (strncmp (Buffer, "sra ", 4) == 0)
148 {
149 CMD_Num = 0;
150 if (sscanf (Buffer, "%4s %i", CMD_Str, &val) == 2)
151 {
152 if ((val >= 0) & (val <= MAX_ROIVAL))
153 {
154 printf ("# Set all ROIs to %d ->\n", val);
155 for (i = 0; i < (MAX_ROINUM + 1); i++)
156 {
157 CMD_Buffer[i * 2] = htons (CMD_Write | (BADDR_ROI + i));
158 CMD_Buffer[(i * 2) + 1] = htons (val);
159 CMD_Num += 2;
160 }
161 for (i = 0; i < ((MAX_ROINUM + 1) * 2); i += 8)
162 {
163 printf ("# 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X\n",
164 ntohs (CMD_Buffer[i]), ntohs (CMD_Buffer[i + 1]),
165 ntohs (CMD_Buffer[i + 2]), ntohs (CMD_Buffer[i + 3]),
166 ntohs (CMD_Buffer[i + 4]), ntohs (CMD_Buffer[i + 5]),
167 ntohs (CMD_Buffer[i + 6]), ntohs (CMD_Buffer[i + 7]));
168 }
169 }
170 else
171 {
172 printf ("Out of range\n");
173 printf ("Usage: sra VAL: Set all ROIs to VAL (0-%d)\n", MAX_ROIVAL);
174 }
175 }
176 else
177 {
178 printf ("Usage: sra VAL: Set all ROIs to VAL (0-%d)\n", MAX_ROIVAL);
179 }
180 }
181
182 // Set DAC value
183 else if (strncmp (Buffer, "sd ", 3) == 0)
184 {
185 CMD_Num = 0;
186 if (sscanf (Buffer, "%3s %i %i", CMD_Str, &num, &val) == 3)
187 {
188 if ((num >= 0) & (num <= MAX_DACNUM) & (val >= 0) & (val <= MAX_DACVAL))
189 {
190 printf ("# Set DAC %d to %d ->\n", num, val);
191 CMD_Buffer[0] = htons (CMD_Write | (BADDR_DAC + num));
192 CMD_Buffer[1] = htons (val);
193 printf ("# 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[0]), ntohs (CMD_Buffer[1]));
194 CMD_Num = 2;
195 }
196 else
197 {
198 printf ("Out of range\n");
199 printf ("Usage: sd NUM VAL: Set DAC NUM (0-%d) to VAL (0-%d)\n", MAX_DACNUM, MAX_DACVAL);
200 }
201 }
202 else
203 {
204 printf ("Usage: sd NUM VAL: Set DAC NUM (0-%d) to VAL (0-%d)\n", MAX_DACNUM, MAX_DACVAL);
205 }
206 }
207
208 // Set address to value
209 else if (strncmp (Buffer, "sa ", 3) == 0)
210 {
211 CMD_Num = 0;
212 if (sscanf (Buffer, "%4s %i %i", CMD_Str, &num, &val) == 3)
213 {
214 if ((num >= 0) & (num <= MAX_ADDR) & (val >= 0) & (val <= MAX_VAL))
215 {
216 printf ("# Set ADDR %d to %d ->\n", num, val);
217 CMD_Buffer[0] = htons (CMD_Write | num);
218 CMD_Buffer[1] = htons (val);
219 printf ("# 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[0]), ntohs (CMD_Buffer[1]));
220 CMD_Num = 2;
221 }
222 else
223 {
224 printf ("Out of range\n");
225 printf ("Usage: sa NUM VAL: Set addr NUM (0-%d) to VAL (0-%d)\n", MAX_ADDR, MAX_VAL);
226 }
227 }
228 else
229 {
230 printf ("Usage: raw NUM VAL: Set addr NUM (0-%d) to VAL (0-%d)\n", MAX_ADDR, MAX_VAL);
231 }
232 }
233
234 // Send value
235 else if (strncmp (Buffer, "sv ", 3) == 0)
236 {
237 CMD_Num = 0;
238 if (sscanf (Buffer, "%4s %i", CMD_Str, &val) == 2)
239 {
240 if ((val >= 0) & (val <= MAX_VAL))
241 {
242 printf ("# Send %d ->\n", val);
243 CMD_Buffer[0] = htons (val);
244 printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0]));
245 CMD_Num = 1;
246 }
247 else
248 {
249 printf ("Out of range\n");
250 printf ("Usage: sv VAL: Send VAL (0-%d)\n", MAX_VAL);
251 }
252 }
253 else
254 {
255 printf ("Usage: sv VAL: Send VAL (0-%d)\n", MAX_VAL);
256 }
257 }
258
259 // Anything else... , print help
260 else
261 {
262 printf ("Commands:\n");
263 printf (" r: Start Run -- TODO\n");
264 printf (" s: Stop Run -- TODO\n");
265 printf (" t: Single Trigger\n\n");
266 printf (" de: DENABLE HIGH\n");
267 printf (" dd: DENABLE LOW\n");
268 printf (" dr: DWRITE HIGH\n");
269 printf (" ds: DWRITE LOW\n\n");
270 printf (" tc: Continuous Trigger\n");
271 printf (" ts: Stop Trigger\n");
272 printf (" sr NUM VAL: Set ROI NUM (0-35) to VAL (0-1024)\n");
273 printf (" sra VAL: Set all ROIs to VAL (0-1024)\n");
274 printf (" sd NUM VAL: Set DAC NUM (0-7) to VAL (0-65535)\n");
275 printf (" q: Quit\n");
276 printf ("\n");
277 printf (" Only for debugging:\n");
278 printf (" sa NUM VAL: Set addr NUM (0-255) to VAL (0-65535)\n");
279 printf (" sv VAL: Send VAL\n");
280 printf (" sz: Send 0x0000\n");
281 printf ("\n");
282
283 CMD_Num = 0;
284 }
285
286
287 // Clear output
288 SocketOutput->clear();
289 for (int i=0; i<NUM_SOCKETS; i++) Data[i].clear();
290
291 // Send commands
292 QByteArray Data((char *) CMD_Buffer, CMD_Num * sizeof (short));
293 printf("Wrote %d bytes\n", (int) Socket[0]->write(Data));
294 Command->clear();
295}
296
297// +++ Read data from socket and display +++
298//
299// Structure interpreation taken from 'ViewEvent.cc' by Kai Warda.
300//
301void fad::ReadFromSocket() {
302
303 QByteArray SocketData;
304
305 // Add data to text display (hex) and to data array
306 for (int Sckt=0; Sckt<NUM_SOCKETS; Sckt++) {
307
308 // Read from socket and accumulate in Data[] arrays
309 SocketData = Socket[Sckt]->readAll();
310 if (SocketData.isEmpty()) continue;
311 Data[Sckt].append(SocketData);
312
313 // Print result
314 printf("Got %d bytes from socket %d\n", (int) SocketData.size(), Sckt);
315 SocketOutput->insertPlainText(SocketData.toHex());
316
317 // Check package length (measured in units of 2 bytes)
318 EVNT_HEADER *Header = (EVNT_HEADER *) Data[Sckt].data();
319 if (Data[Sckt].size() != 2 * ntohs (Header->package_length)) continue;
320
321 // read and print package header
322 printf ("Start Package Flag: 0x%.4X\n", ntohs (Header->start_package_flag));
323 printf ("Package Length: 0x%.4X\n", ntohs (Header->package_length));
324 printf ("Version Number: 0x%.4X\n", ntohs (Header->version_no));
325 printf ("Trigger-ID: 0x%.8X\n", ntohl (Header->trigger_id));
326 printf ("Trigger Type: 0x%.2X\n", Header->trigger_type);
327 printf ("Trigger CRC: 0x%.2X\n", Header->trigger_crc);
328 printf ("Local Trigger-ID: 0x%.8X\n", ntohl (Header->local_trigger_id));
329 printf ("Local Trigger Type: 0x%.2X\n", Header->local_trigger_type);
330 printf ("Local Trigger CRC: 0x%.2X\n", Header->local_trigger_crc);
331 printf ("Board-ID: 0x%.4X\n", ntohs (Header->board_id));
332
333 for (int i = 0; i < 4; i++) {
334 if ((ntohs (Header->drs_temperature[i]) & 0x8000) == 0x8000) {
335 printf ("Temperature %d: %d\n", i, 0xE000 | (ntohs (Header->drs_temperature[i])) >> 3);
336 }
337 else printf ("Temperature %d: %d\n", i, ntohs (Header->drs_temperature[i]) >> 3);
338 }
339
340 // DAC Values, only if version > 0x0101
341 if (ntohs (Header->version_no) > 0x0101) {
342 for (int i = 0; i < 8; i++) printf ("DAC %d: %d\n", i, ntohs (Header->dac[i]));
343 }
344
345 // read channels, no error checking...
346 double *x, *y;
347 CHANNEL *Channel = (CHANNEL *) (Data[Sckt].data() + sizeof(EVNT_HEADER));
348
349 unsigned int drs_index, channel_index;
350
351 for (int i=0; i<NUM_CHANNELS; i++) {
352
353 drs_index = i%4;
354 channel_index = i/4;
355
356 x = new double [ntohs (Channel->channel_roi)];
357 y = new double [ntohs (Channel->channel_roi)];
358 int dummy;
359 printf("ROI: %d\n", ntohs (Channel->channel_roi));
360
361 // print channel header
362 printf ("\nChannel-ID: 0x%.4X\n", ntohs (Channel->channel_id));
363 printf ("Channel Start-Cell: 0x%.4X\n", ntohs (Channel->channel_start_cell));
364 printf ("Channel ROI: 0x%.4X\n", ntohs (Channel->channel_roi));
365
366 // print channel data
367 printf ("Channel Data:\n");
368 unsigned short *ChannelData = (unsigned short *) &Channel->channel_adc_data;
369 for (int j=0; j<ntohs (Channel->channel_roi); j++) {
370 x[j] = j* 50;
371 dummy = ad9238ToInt( (short) ntohs (ChannelData[j]) );
372 y[j] = (double) dummy /2048.0 ;
373 //printf ("%4d: 0x%.4x , 0x%.4x , %.4f \n", j, (short) ntohs (ChannelData[j]), dummy, y[j]);
374
375 }
376
377 printf ("channel %d: DRS[%d] is %d : ChannelCheckBox[%d] is %d\n" , i, drs_index, DRS[drs_index]->isChecked() , channel_index, ChannelCheckBox[channel_index]->isChecked() );
378 if (DRS[drs_index]->isChecked() && ChannelCheckBox[channel_index]->isChecked())
379 {
380 // Plot data
381 Signal[i]->setData(x, y, ntohs(Channel->channel_roi));
382 Signal[i]->show();
383 printf ("plotting\n" );
384 }
385 else
386 {
387 Signal[i]->hide();
388 }
389 delete[] x;
390 delete[] y;
391
392 // Move pointer to next channel
393
394 Channel = (CHANNEL *) ((char *) Channel + (3 + ntohs (Channel->channel_roi)) * sizeof(unsigned short));
395 }
396
397 // Recast to access last entries of event structure
398 unsigned int *Pointer = (unsigned int *) Channel;
399
400 // CRC, only if version > 0x0100
401 if (ntohs (Header->version_no) > 0x0100) {
402 printf ("\nPackage CRC: 0x%.4X\n", ntohs (*(Pointer++)));
403 }
404 // end package flag
405 printf ("\nEnd Package Flag: 0x%.4X\n\n", ntohs (*Pointer));
406
407 // Clear accumulated data array
408 Data[Sckt].clear();
409
410 } // Loop over sockets
411}
412
413// +++ Reset graph axes to autoscale when fully unzoomed +++
414void fad::HandleZoom(const QwtDoubleRect &) {
415 if(Zoomer->zoomRectIndex() == 0) {
416 Graph->setAxisAutoScale(QwtPlot::xBottom);
417 Graph->setAxisAutoScale(QwtPlot::yLeft);
418 }
419}
420
421// +++ Disconnect from socket +++
422void fad::GotDisconnected() {
423 Connect->setText("Connect");
424 ConnectAction->setText("Connect");
425 Port->setEnabled(true);
426 IPAddress->setEnabled(true);
427 Command->setEnabled(false);
428
429 SocketOutput->clear();
430 if(!ManualDisconnect) QMessageBox::warning(this, "fad Message","Socket disconnected, maybe host gone.",QMessageBox::Ok);
431}
432
433
434//------------------------------------------------------------------
435//**************************** All menus ***************************
436//------------------------------------------------------------------
437
438void fad::MenuSave() {
439 QString Filename = QFileDialog::getSaveFileName(this,
440 "Filename of image", ".", "Image files (*.bmp *.jpg *.png *.ppm *.tiff *.xbm *.xpm);;All files (*)");
441 if (Filename.length()>0) {
442 QPixmap Pixmap = QPixmap::grabWidget(Graph);
443 if(!Pixmap.save(Filename)) {
444 QMessageBox::warning(this, "fad Message","Could not write image file.",QMessageBox::Ok);
445 remove(Filename.toAscii().data());
446 }
447 }
448}
449
450void fad::MenuPrint() {
451 QPrinter *Printer = new QPrinter;
452 QPrintDialog *PrintDialog = new QPrintDialog(Printer, this);
453 if (PrintDialog->exec() == QDialog::Accepted) {
454 QPainter Painter(Printer);
455 QPixmap Pixmap = QPixmap::grabWidget(Graph);
456 Painter.drawPixmap(0, 0, Pixmap);
457 }
458 delete Printer; delete PrintDialog;
459}
460
461void fad::MenuSaveASCII() {
462 QString Filename = QFileDialog::getSaveFileName(this,
463 "Filename", ".", "Text files (*.txt *.ascii *.asc);;All files (*)");
464 if (Filename.length()>0) {
465 QFile File(Filename);
466 if (File.open(QFile::WriteOnly | QIODevice::Text | QFile::Truncate)) {
467 QTextStream Stream(&File);
468 for (int Count=0; Count<NUM_CHANNELS; Count++) {
469 for (int i=0; i<Signal[i]->dataSize(); i++) Stream << Signal[i]->y(i) << endl;
470 Stream << endl;
471 }
472 }
473 else {
474 QMessageBox::warning(this, "fad Message","Could not write data to file.",QMessageBox::Ok);
475 }
476 }
477}
478
479/*
480ad9238ToDouble
481input:
482unsigned short code: 13bit ADC code in an 16bit data type
483 unsigned short was chosen, because it is least subject to interpretation
484
485AD9238 is an 12bit ADC which in addition outputs an overflow bit.
486The overflow bit (OVFL) as well as the data bits 11 until 0 (D11..D0) are assembled in
487the unsigned short as follows:
488|bit15|bit14|bit13|bit12|bit11|bit10|bit9 |bit8 |
489| 0 | 0 | 0 |OVFL | D11 | D10 | D9 | D8 |
490
491|bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
492| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
493
494D11..D0 are formatted as twos complement so:
495
4960x000 = 0
497...
4980x7FF = 2047
4990x800 = -2048
500...
5010xFFF = -1
502
503Note:
504taking the overflow bit into account as well as the
505twos complement format.
506This is how overflows are coded:
5070x7FF ist the largest positive 12bit number.
508therefore:
5090x17FF = 0001.0111.1111.1111 = 6143 is the code for a positive overflow
510and
5110x800 is the most negative 12bit number.
512now 0x1800 = 0001.1000.0000.0000 = 6144 is the code for an underflow.
513*/
514
515
516double fad::ad9238ToDouble(unsigned short code){
517 unsigned short upper_three_bit_mask = 0xE000;
518
519 if ((code & upper_three_bit_mask) != 0x0000)
520 // one of the upper three bits was set --> Error
521 {
522 fprintf (stderr, "error in ad9238ToDouble. 1 of 3 upper bits was set. code = 0x%4X" ,code);
523 return nan("");
524 }
525
526 // check for over- and underflow
527 if (code == 0x17FF) // overflow
528 return 2048; // this is the highest signed short + 1, indicating an overflow.
529 if (code == 0x1800) // underflow
530 return -2049; // this is the lowest signed short - 1, indicating an underflow.
531
532 // note: bit shifting operator >> is smart.
533 // when shifting a signed integer type to the right, the
534 // sign bit is expanded:
535 // 0x1800 << 4 = 0x8000 and then
536 // 0x8000 >> 4 = 0xF800, when the type is a signed one.
537 return double( (((short) code) << 4) >> 4);
538}
539
540
541double fad::ad9238ToDouble(short code){
542
543 unsigned short upper_three_bit_mask = 0xE000;
544
545
546 if ((code & upper_three_bit_mask) != 0x0000)
547 // one of the upper three bits was set --> Error
548 {
549 fprintf (stderr, "error in ad9238ToDouble. 1 of 3 upper bits was set. code = 0x%4X" ,code);
550 return nan("");
551 }
552
553 // check for over- and underflow
554 if (code == 0x17FF) // overflow
555 return 2048; // this is the highest signed short + 1, indicating an overflow.
556 if (code == 0x1800) // underflow
557 return -2049; // this is the lowest signed short - 1, indicating an underflow.
558
559 // note: bit shifting operator >> is smart.
560 // when shifting a signed integer type to the right, the
561 // sign bit is expanded:
562 // 0x1800 << 4 = 0x8000 and then
563 // 0x8000 >> 4 = 0xF800, when the type is a signed one.
564 return double( (( code) << 4) >> 4);
565}
566
567int fad::ad9238ToInt(short code){
568
569 unsigned short upper_three_bit_mask = 0xE000;
570
571
572 if ((code & upper_three_bit_mask) != 0x0000)
573 // one of the upper three bits was set --> Error
574 {
575 fprintf (stderr, "error in ad9238ToDouble. 1 of 3 upper bits was set. code = 0x%4X" ,code);
576 return -10000;
577 }
578
579 // check for over- and underflow
580 if (code == 0x17FF) // overflow
581 return 2048; // this is the highest signed short + 1, indicating an overflow.
582 if (code == 0x1800) // underflow
583 return -2049; // this is the lowest signed short - 1, indicating an underflow.
584
585 // note: bit shifting operator >> is smart.
586 // when shifting a signed integer type to the right, the
587 // sign bit is expanded:
588 // 0x1800 << 4 = 0x8000 and then
589 // 0x8000 >> 4 = 0xF800, when the type is a signed one.
590 //return (( code) << 4) >> 4;
591 // this doenst seem to work.
592
593 // check if sign-bit (bit 11) is set
594 if ( (code & 0x800) != 0) { // sign-bit is set -> number is negative
595 code = code | 0xF000; // bits 12..15 are set
596 } else {
597
598 }
599 return code;
600
601}
Note: See TracBrowser for help on using the repository browser.