minor corrections by M.Taguchi
[reactos.git] / reactos / apps / utils / pice / module / serial.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7 serial.c
8
9 Abstract:
10
11 serial debugger connection
12
13 Environment:
14
15 LINUX 2.2.X
16 Kernel mode only
17
18 Author:
19
20 Klaus P. Gerlicher
21
22 Revision History:
23
24 19-Aug-2000: created
25 15-Nov-2000: general cleanup of source files
26
27 Copyright notice:
28
29 This file may be distributed under the terms of the GNU Public License.
30
31 --*/
32 #include "remods.h"
33 #include "precomp.h"
34 #include "serial_port.h"
35
36 BOOLEAN SerialReadByte(PUCHAR px);
37
38
39 // used for SERIAL window creation
40 // NB: at the moment the terminal is 60 lines high.
41 WINDOW wWindowSerial[4]=
42 {
43 {1,3,1,0,FALSE},
44 {5,8,1,0,FALSE},
45 {14,26,1,0,FALSE},
46 {41,18,1,0,FALSE}
47 };
48
49 PUCHAR pScreenBufferSerial;
50
51 USHORT usSerialPortBase;
52
53 UCHAR packet[_PAGE_SIZE];
54 UCHAR assemble_packet[_PAGE_SIZE];
55
56 UCHAR flush_buffer[_PAGE_SIZE],g_x,g_y;
57 ULONG ulFlushBufferPos = 0;
58
59 UCHAR ucLastKeyRead;
60 ECOLORS eForegroundColor=WHITE,eBackgroundColor=BLACK;
61
62 ///************************************************************************
63 // SerialSetSpeed()
64 //
65 ///************************************************************************
66 void SerialSetSpeed(ULONG baudrate)
67 {
68 UCHAR c;
69 ULONG divisor;
70
71 divisor = (ULONG) (115200L/baudrate);
72
73 c = inportb((USHORT)(usSerialPortBase + LCR));
74 outportb((USHORT)(usSerialPortBase + LCR), (UCHAR)(c | 0x80)); // Set DLAB
75 outportb((USHORT)(usSerialPortBase + DLL), (UCHAR)(divisor & 0x00FF));
76 outportb((USHORT)(usSerialPortBase + DLH), (UCHAR)((divisor >> 8) & 0x00FF));
77 outportb((USHORT)(usSerialPortBase + LCR), c); // Reset DLAB
78
79 }
80
81 ///************************************************************************
82 // SerialSetOthers()
83 //
84 // Set other communications parameters
85 //************************************************************************
86 void SerialSetOthers(ULONG Parity, ULONG Bits, ULONG StopBit)
87 {
88 ULONG setting;
89 UCHAR c;
90
91 if (usSerialPortBase == 0) return ;
92 if (Bits < 5 || Bits > 8) return ;
93 if (StopBit != 1 && StopBit != 2) return ;
94 if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
95 return;
96
97 setting = Bits-5;
98 setting |= ((StopBit == 1) ? 0x00 : 0x04);
99 setting |= Parity;
100
101 c = inportb((USHORT)(usSerialPortBase + LCR));
102 outportb((USHORT)(usSerialPortBase + LCR), (UCHAR)(c & ~0x80)); // Reset DLAB
103
104 // no ints
105 outportb((USHORT)(usSerialPortBase + IER), (UCHAR)0);
106
107 // clear FIFO and disable them
108 outportb((USHORT)(usSerialPortBase + FCR), (UCHAR)0);
109
110 outportb((USHORT)(usSerialPortBase + LCR), (UCHAR)setting);
111
112 outportb((USHORT)(usSerialPortBase + MCR), DTR | RTS);
113
114
115 return ;
116 }
117
118 ///************************************************************************
119 // FlushSerialBuffer()
120 //
121 ///************************************************************************
122 void FlushSerialBuffer(void)
123 {
124 UCHAR c;
125
126 while(SerialReadByte(&c));
127 }
128
129 ///************************************************************************
130 // SetupSerial()
131 //
132 ///************************************************************************
133 void SetupSerial(ULONG port,ULONG baudrate)
134 {
135 USHORT ports[]={COM1BASE,COM2BASE,COM3BASE,COM4BASE};
136
137 usSerialPortBase = ports[port-1];
138 SerialSetOthers(NO_PARITY,8,1);
139 SerialSetSpeed(baudrate);
140
141 // clear out received bytes
142 // else we would think there's a terminal connected
143 FlushSerialBuffer();
144 }
145
146
147 ///************************************************************************
148 // SerialReadByte()
149 //
150 // Output a character to the serial port
151 //************************************************************************
152 BOOLEAN SerialReadByte(PUCHAR px)
153 {
154 ULONG timeout;
155
156 timeout = 0x00FFFFL;
157
158 // Wait for transmitter to clear
159 while ((inportb((USHORT)(usSerialPortBase + LSR)) & RCVRDY) == 0)
160 if (!(--timeout))
161 {
162 return FALSE;
163 }
164
165 *px = inportb((USHORT)(usSerialPortBase + RXR));
166
167 return TRUE;
168 }
169
170 ///************************************************************************
171 // SerialSendByte()
172 //
173 // Output a character to the serial port
174 //************************************************************************
175 BOOLEAN SerialSendByte(UCHAR x)
176 {
177 ULONG timeout;
178
179 timeout = 0x00FFFFL;
180
181 // Wait for transmitter to clear
182 while ((inportb((USHORT)(usSerialPortBase + LSR)) & XMTRDY) == 0)
183 if (!(--timeout))
184 {
185 return FALSE;
186 }
187
188 outportb((USHORT)(usSerialPortBase + TXR), x);
189
190 return TRUE;
191 }
192
193 //************************************************************************
194 // CheckSum()
195 //
196 //************************************************************************
197 UCHAR CheckSum(LPSTR p,ULONG Len)
198 {
199 UCHAR ucCheckSum = 0;
200 ULONG i;
201 for(i=0;i<Len;i++)
202 {
203 ucCheckSum ^= *p++;
204 ucCheckSum += 1;
205 }
206
207 return ucCheckSum;
208 }
209
210
211 ///************************************************************************
212 // ReadPacket()
213 //
214 ///************************************************************************
215 BOOLEAN ReadPacket(PSERIAL_PACKET p)
216 {
217 return TRUE;
218 }
219
220
221 ///************************************************************************
222 // SendPacket()
223 //
224 ///************************************************************************
225 BOOLEAN SendPacket(PSERIAL_PACKET p)
226 {
227 PUCHAR pHeader = (PUCHAR)&p->header;
228 ULONG i;
229 UCHAR c;
230 ULONG timeout;
231
232 do
233 {
234 timeout = 10;
235 pHeader = (PUCHAR)&p->header;
236 for(i=0;i<(sizeof(SERIAL_PACKET_HEADER)+p->header.packet_size);i++)
237 {
238 if(!SerialSendByte(*pHeader++))
239 {
240 return FALSE;
241 }
242 }
243
244 do
245 {
246 c = 0;
247 SerialReadByte(&c);
248 if(c != ACK)
249 ucLastKeyRead = c;
250 }while(c != ACK && timeout--);
251
252 }while(c != ACK);
253
254 return TRUE;
255 }
256
257 ///************************************************************************
258 // SendPacketTimeout()
259 //
260 ///************************************************************************
261 BOOLEAN SendPacketTimeout(PSERIAL_PACKET p)
262 {
263 PUCHAR pHeader = (PUCHAR)&p->header;
264 ULONG i;
265 UCHAR c;
266 ULONG timeout = 20;
267 BOOLEAN bResult = TRUE;
268
269 pHeader = (PUCHAR)&p->header;
270 for(i=0;i<(sizeof(SERIAL_PACKET_HEADER)+p->header.packet_size);i++)
271 {
272 if(!SerialSendByte(*pHeader++))
273 {
274 return FALSE;
275 }
276 }
277
278 do
279 {
280 c = 0xFF;
281 SerialReadByte(&c);
282 }while(c != ACK && timeout--);
283
284 if(c != ACK)
285 bResult = FALSE;
286
287 return bResult;
288 }
289
290
291 //************************************************************************
292 // AssemblePacket()
293 //
294 //************************************************************************
295 PSERIAL_PACKET AssemblePacket(PUCHAR pData,ULONG ulSize)
296 {
297 PSERIAL_PACKET p;
298 ULONG ulCheckSum;
299
300 p = (PSERIAL_PACKET)assemble_packet;
301
302 // fill in header
303 p->header.packet_chksum = CheckSum(pData,ulSize);
304 p->header.packet_size = ulSize;
305 p->header.packet_header_chksum = 0;
306 ulCheckSum = (ULONG)CheckSum((PUCHAR)p,sizeof(SERIAL_PACKET_HEADER));
307 p->header.packet_header_chksum = ulCheckSum;
308 // attach data to packet
309 PICE_memcpy(p->data,pData,ulSize);
310
311 return p;
312 }
313
314
315 // OUTPUT handlers
316
317 //*************************************************************************
318 // SetForegroundColorVga()
319 //
320 //*************************************************************************
321 void SetForegroundColorSerial(ECOLORS col)
322 {
323 eForegroundColor = col;
324 }
325
326 //*************************************************************************
327 // SetBackgroundColorVga()
328 //
329 //*************************************************************************
330 void SetBackgroundColorSerial(ECOLORS col)
331 {
332 eBackgroundColor = col;
333 }
334
335
336 //*************************************************************************
337 // PrintGrafSerial()
338 //
339 //*************************************************************************
340 void PrintGrafSerial(ULONG x,ULONG y,UCHAR c)
341 {
342 // put this into memory
343 pScreenBufferSerial[y*GLOBAL_SCREEN_WIDTH + x] = c;
344
345 // put this into cache
346 if(ulFlushBufferPos == 0)
347 {
348 g_x = x;
349 g_y = y;
350 }
351
352 flush_buffer[ulFlushBufferPos++] = c;
353 }
354
355 //*************************************************************************
356 // FlushSerial()
357 //
358 //*************************************************************************
359 void FlushSerial(void)
360 {
361 PSERIAL_DATA_PACKET_PRINT pPrint;
362 PSERIAL_PACKET p;
363
364 pPrint = (PSERIAL_DATA_PACKET_PRINT)packet;
365 pPrint->type = PACKET_TYPE_PRINT;
366 pPrint->x = g_x;
367 pPrint->y = g_y;
368 pPrint->fgcol = eForegroundColor;
369 pPrint->bkcol = eBackgroundColor;
370 flush_buffer[ulFlushBufferPos++] = 0;
371 PICE_strcpy(pPrint->string,flush_buffer);
372 ulFlushBufferPos = 0;
373
374 p = AssemblePacket((PUCHAR)pPrint,sizeof(SERIAL_DATA_PACKET_PRINT)+PICE_strlen(flush_buffer));
375 SendPacket(p);
376 }
377
378 //*************************************************************************
379 // ShowCursorSerial()
380 //
381 // show hardware cursor
382 //*************************************************************************
383 void ShowCursorSerial(void)
384 {
385 PSERIAL_DATA_PACKET_CURSOR pCursor;
386 PSERIAL_PACKET p;
387
388 ENTER_FUNC();
389
390 bCursorEnabled = TRUE;
391
392 pCursor = (PSERIAL_DATA_PACKET_CURSOR)packet;
393 pCursor->type = PACKET_TYPE_CURSOR;
394 pCursor->state = (UCHAR)TRUE;
395 pCursor->x = (UCHAR)wWindow[OUTPUT_WINDOW].usCurX;
396 pCursor->y = (UCHAR)wWindow[OUTPUT_WINDOW].usCurY;
397
398 p = AssemblePacket((PUCHAR)pCursor,sizeof(SERIAL_DATA_PACKET_CURSOR));
399 SendPacket(p);
400
401 LEAVE_FUNC();
402 }
403
404 //*************************************************************************
405 // HideCursorSerial()
406 //
407 // hide hardware cursor
408 //*************************************************************************
409 void HideCursorSerial(void)
410 {
411 PSERIAL_DATA_PACKET_CURSOR pCursor;
412 PSERIAL_PACKET p;
413
414 ENTER_FUNC();
415
416 bCursorEnabled = FALSE;
417
418 pCursor = (PSERIAL_DATA_PACKET_CURSOR)packet;
419 pCursor->type = PACKET_TYPE_CURSOR;
420 pCursor->state = (UCHAR)TRUE;
421
422 p = AssemblePacket((PUCHAR)pCursor,sizeof(SERIAL_DATA_PACKET_CURSOR));
423 SendPacket(p);
424
425 LEAVE_FUNC();
426 }
427
428 //*************************************************************************
429 // CopyLineToSerial()
430 //
431 // copy a line from src to dest
432 //*************************************************************************
433 void CopyLineToSerial(USHORT dest,USHORT src)
434 {
435 NOT_IMPLEMENTED();
436 }
437
438 //*************************************************************************
439 // InvertLineSerial()
440 //
441 // invert a line on the screen
442 //*************************************************************************
443 void InvertLineSerial(ULONG line)
444 {
445 PSERIAL_DATA_PACKET_INVERTLINE pInvertLine;
446 PSERIAL_PACKET p;
447
448 pInvertLine = (PSERIAL_DATA_PACKET_INVERTLINE)packet;
449 pInvertLine->type = PACKET_TYPE_INVERTLINE;
450 pInvertLine->line = line;
451
452 p = AssemblePacket((PUCHAR)pInvertLine,sizeof(SERIAL_DATA_PACKET_INVERTLINE));
453 SendPacket(p);
454 }
455
456 //*************************************************************************
457 // HatchLineSerial()
458 //
459 // hatches a line on the screen
460 //*************************************************************************
461 void HatchLineSerial(ULONG line)
462 {
463 NOT_IMPLEMENTED();
464 }
465
466 //*************************************************************************
467 // ClrLineSerial()
468 //
469 // clear a line on the screen
470 //*************************************************************************
471 void ClrLineSerial(ULONG line)
472 {
473 PSERIAL_DATA_PACKET_CLRLINE pClrLine;
474 PSERIAL_PACKET p;
475
476 pClrLine = (PSERIAL_DATA_PACKET_CLRLINE)packet;
477 pClrLine->type = PACKET_TYPE_CLRLINE;
478 pClrLine->fgcol = eForegroundColor;
479 pClrLine->bkcol = eBackgroundColor;
480 pClrLine->line = line;
481
482 p = AssemblePacket((PUCHAR)pClrLine,sizeof(SERIAL_DATA_PACKET_CLRLINE));
483 SendPacket(p);
484 }
485
486 //*************************************************************************
487 // PrintLogoSerial()
488 //
489 //*************************************************************************
490 void PrintLogoSerial(BOOLEAN bShow)
491 {
492 NOT_IMPLEMENTED();
493 }
494
495 //*************************************************************************
496 // PrintCursorSerial()
497 //
498 // emulate a blinking cursor block
499 //*************************************************************************
500 void PrintCursorSerial(BOOLEAN bForce)
501 {
502 NOT_IMPLEMENTED();
503 }
504
505 //*************************************************************************
506 // SaveGraphicsStateSerial()
507 //
508 //*************************************************************************
509 void SaveGraphicsStateSerial(void)
510 {
511 // not implemented
512 }
513
514 //*************************************************************************
515 // RestoreGraphicsStateSerial()
516 //
517 //*************************************************************************
518 void RestoreGraphicsStateSerial(void)
519 {
520 // not implemented
521 }
522
523 // INPUT handlers
524 //*************************************************************************
525 // GetKeyPolledSerial()
526 //
527 //*************************************************************************
528 UCHAR GetKeyPolledSerial(void)
529 {
530 UCHAR ucResult;
531 PSERIAL_DATA_PACKET_POLL pPoll;
532 PSERIAL_PACKET p;
533
534 pPoll = (PSERIAL_DATA_PACKET_POLL)packet;
535 pPoll->type = PACKET_TYPE_POLL;
536 pPoll->major_version = PICE_MAJOR_VERSION;
537 pPoll->minor_version = PICE_MINOR_VERSION;
538 pPoll->build_number = PICE_BUILD;
539
540 p = AssemblePacket((PUCHAR)pPoll,sizeof(SERIAL_DATA_PACKET_POLL));
541 SendPacket(p);
542
543 ucResult = ucLastKeyRead;
544
545 ucLastKeyRead = 0;
546
547 return ucResult;
548 }
549
550 //*************************************************************************
551 // FlushKeyboardQueueSerial()
552 //
553 //*************************************************************************
554 void FlushKeyboardQueueSerial(void)
555 {
556 // not implemented
557 }
558
559 //*************************************************************************
560 // Connect()
561 //
562 //*************************************************************************
563 BOOLEAN Connect(USHORT xSize,USHORT ySize)
564 {
565 PSERIAL_DATA_PACKET_CONNECT pConnect;
566 PSERIAL_PACKET p;
567
568 pConnect = (PSERIAL_DATA_PACKET_CONNECT)packet;
569 pConnect->type = PACKET_TYPE_CONNECT;
570 pConnect->xsize = xSize;
571 pConnect->ysize = ySize;
572
573 p = AssemblePacket((PUCHAR)pConnect,sizeof(SERIAL_DATA_PACKET_CONNECT));
574 return SendPacketTimeout(p);
575 }
576
577 //*************************************************************************
578 // ConsoleInitSerial()
579 //
580 // init terminal screen
581 //*************************************************************************
582 BOOLEAN ConsoleInitSerial(void)
583 {
584 BOOLEAN bResult = FALSE;
585
586 ENTER_FUNC();
587
588 ohandlers.CopyLineTo = CopyLineToSerial;
589 ohandlers.PrintGraf = PrintGrafSerial;
590 ohandlers.Flush = FlushSerial;
591 ohandlers.ClrLine = ClrLineSerial;
592 ohandlers.InvertLine = InvertLineSerial;
593 ohandlers.HatchLine = HatchLineSerial;
594 ohandlers.PrintLogo = PrintLogoSerial;
595 ohandlers.PrintCursor = PrintCursorSerial;
596 ohandlers.SaveGraphicsState = SaveGraphicsStateSerial;
597 ohandlers.RestoreGraphicsState = RestoreGraphicsStateSerial;
598 ohandlers.ShowCursor = ShowCursorSerial;
599 ohandlers.HideCursor = HideCursorSerial;
600 ohandlers.SetForegroundColor = SetForegroundColorSerial;
601 ohandlers.SetBackgroundColor = SetBackgroundColorSerial;
602
603 ihandlers.GetKeyPolled = GetKeyPolledSerial;
604 ihandlers.FlushKeyboardQueue = FlushKeyboardQueueSerial;
605
606 SetWindowGeometry(wWindowSerial);
607
608 GLOBAL_SCREEN_WIDTH = 80;
609 GLOBAL_SCREEN_HEIGHT = 60;
610
611 pScreenBufferSerial = PICE_malloc(FRAMEBUFFER_SIZE, NONPAGEDPOOL);
612
613 if(pScreenBufferSerial)
614 {
615 bResult = TRUE;
616
617 EmptyRingBuffer();
618
619 SetupSerial(1,115200);
620
621 // connect to terminal, if none's there, we give up
622 bResult = Connect(GLOBAL_SCREEN_WIDTH,GLOBAL_SCREEN_HEIGHT);
623
624 if(bResult)
625 {
626 GetKeyPolledSerial();
627 }
628 }
629
630 LEAVE_FUNC();
631
632 return bResult;
633 }
634
635
636 //*************************************************************************
637 // ConsoleShutdownSerial()
638 //
639 // exit terminal screen
640 //*************************************************************************
641 void ConsoleShutdownSerial(void)
642 {
643 ENTER_FUNC();
644
645 Connect(80,25);
646
647 FlushSerialBuffer();
648
649 if(pScreenBufferSerial)
650 PICE_free(pScreenBufferSerial);
651
652 LEAVE_FUNC();
653 }
654
655
656