]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/i386/pcmb/v2_0/src/pcmb_screen.c
Initial revision
[karo-tx-redboot.git] / packages / hal / i386 / pcmb / v2_0 / src / pcmb_screen.c
1 //=============================================================================
2 //
3 //      pcmb_screen.c
4 //
5 //      HAL diagnostic output code
6 //
7 //=============================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //=============================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   proven
44 // Contributors:proven
45 // Date:        1998-10-05
46 // Purpose:     HAL diagnostic output
47 // Description: Implementations of HAL diagnostic output support.
48 //
49 //####DESCRIPTIONEND####
50 //
51 //=============================================================================
52
53 #include <pkgconf/hal.h>
54 #include <pkgconf/hal_i386_pcmb.h>
55
56 #if CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT
57
58 #include <cyg/infra/cyg_type.h>         // base types
59
60 #include <cyg/hal/hal_arch.h>           // basic machine info
61 #include <cyg/hal/hal_intr.h>           // interrupt macros
62 #include <cyg/hal/hal_io.h>             // IO macros
63 #include <cyg/hal/drv_api.h>
64 #include <cyg/hal/hal_if.h>             // interface API
65 #include <cyg/hal/hal_misc.h>
66
67 #include <cyg/hal/pcmb_serial.h>
68
69 // Index into pc_ser_channels[] for screen entry.
70 #define PCMB_PORT_INDEX (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS - 1)
71
72 //-----------------------------------------------------------------------------
73 // Screen output definitions...
74
75 static short            *DisplayBuffer = (short *)0xB8000;
76 static short            DisplayAttr = 0x0700;
77
78 static  short           DisplayPort = 0x03d4;
79
80 static  int             XPos;
81 static  int             YPos;
82
83 static  int             ScreenWidth = 80;
84 static  int             ScreenLength = 25;
85
86 //-----------------------------------------------------------------------------
87
88 static void MoveLine
89 (
90         short   *dest,
91         short   *src,
92         int     count           
93 )
94 {
95
96         while( count-- ) *dest++ = *src++;
97         
98 } /* MoveLine */
99
100 //-----------------------------------------------------------------------------
101
102 static void FillLine
103 (
104         short  *dest,
105         short  val,
106         int    count
107 )
108 {
109         while( count-- ) *dest++ = val;
110         
111 } /* FillLine */
112
113 //-----------------------------------------------------------------------------
114
115 void ClearScreen(void)
116 {
117     FillLine(DisplayBuffer, ' ' | DisplayAttr, ScreenWidth*ScreenLength);
118         
119 } /* ClearScreen */
120
121 void MoveCursor
122 (
123         void
124 )
125 {
126         int pos = XPos + YPos * ScreenWidth;
127
128         HAL_WRITE_UINT8(DisplayPort, 0x0e );
129         HAL_WRITE_UINT8(DisplayPort+1, pos >> 8 );
130
131         HAL_WRITE_UINT8(DisplayPort, 0x0f );
132         HAL_WRITE_UINT8(DisplayPort+1, pos & 0xFF );
133         
134 } /* MoveCursor */
135
136 //-----------------------------------------------------------------------------
137
138 void ScrollUp
139 (
140         int     lines
141 )
142 {
143 //      Report_Function(ScrollUp)
144
145         int rest = ScreenLength - lines;
146         
147         MoveLine
148         (
149                 DisplayBuffer,
150                 DisplayBuffer+(lines*ScreenWidth),
151                 rest*ScreenWidth
152         );
153
154         FillLine
155         (
156                 DisplayBuffer+(rest*ScreenWidth),
157                 ' ' | DisplayAttr,
158                 lines*ScreenWidth
159         );
160         
161 } /* ScrollUp */
162
163 //-----------------------------------------------------------------------------
164
165 void ScrollDown
166 (
167         int     lines
168 )
169 {
170 //      Report_Function(ScrollDown)
171
172         int rest = ScreenLength - lines;
173         short *db = DisplayBuffer+(ScreenWidth*(ScreenLength-1));
174         
175         while( rest )
176         {
177                 MoveLine
178                 (
179                         db,
180                         db-ScreenWidth,
181                         ScreenWidth
182                 );
183
184                 rest--;
185                 db -= ScreenWidth;
186         }
187
188         FillLine
189         (
190                 DisplayBuffer,
191                 ' ' | DisplayAttr,
192                 lines*ScreenWidth
193         );
194         
195 } /* ScrollDown */
196
197 //-----------------------------------------------------------------------------
198
199 void NewLine
200 (
201         void
202 )
203 {
204
205         XPos = 0;
206         YPos++;
207         
208         if( YPos >= ScreenLength )
209         {
210                 YPos = ScreenLength-1;
211                 ScrollUp(1);
212         }
213
214         MoveCursor();
215         
216 } /* NewLine */
217
218 //-----------------------------------------------------------------------------
219
220 void DisplayChar
221 (
222         char    ch
223 )
224 {
225
226         DisplayBuffer[XPos + YPos*ScreenWidth] = ch | DisplayAttr;
227
228         XPos++;
229
230         if( XPos >= ScreenWidth )
231         {
232                 XPos = 0;
233                 YPos++;
234                 if( YPos >= ScreenLength )
235                 {
236                         YPos = ScreenLength-1;
237                         ScrollUp(1);
238                 }
239         }
240
241         MoveCursor();
242         
243 } /* DisplayChar */
244
245 //-----------------------------------------------------------------------------
246 // Keyboard definitions
247
248 #define KBDATAPORT      0x0060          // data I/O port
249 #define KBCMDPORT       0x0064          // command port (write)
250 #define KBSTATPORT      0x0064          // status port  (read)
251
252 // Scan codes
253
254 #define LSHIFT          0x2a
255 #define RSHIFT          0x36
256 #define CTRL            0x1d
257 #define ALT                 0x38
258 #define CAPS            0x3a
259 #define NUMS            0x45
260
261 #define BREAK           0x80
262
263 // Bits for KBFlags
264
265 #define KBNormal        0x0000
266 #define KBShift         0x0001
267 #define KBCtrl          0x0002
268 #define KBAlt           0x0004
269 #define KBIndex         0x0007  // mask for the above
270
271 #define KBExtend        0x0010
272 #define KBAck           0x0020
273 #define KBResend        0x0040
274 #define KBShiftL        (0x0080 | KBShift)
275 #define KBShiftR        (0x0100 | KBShift)
276 #define KBCtrlL         (0x0200 | KBCtrl)
277 #define KBCtrlR         (0x0400 | KBCtrl)
278 #define KBAltL          (0x0800 | KBAlt)
279 #define KBAltR          (0x1000 | KBAlt)
280 #define KBCapsLock      0x2000
281 #define KBNumLock       0x4000
282
283 //-----------------------------------------------------------------------------
284 // Keyboard Variables
285
286 static  int     KBFlags = 0;
287
288 static  CYG_BYTE        KBPending = 0xFF;
289
290 static  CYG_BYTE        KBScanTable[128][4] =
291 {
292 //      Normal          Shift           Control         Alt
293 // 0x00
294 {       0xFF,           0xFF,           0xFF,           0xFF,   },
295 {       0x1b,           0x1b,           0x1b,           0xFF,   },
296 {       '1',            '!',            0xFF,           0xFF,   },
297 {       '2',            '"',            0xFF,           0xFF,   },
298 {       '3',            '#',            0xFF,           0xFF,   },
299 {       '4',            '$',            0xFF,           0xFF,   },
300 {       '5',            '%',            0xFF,           0xFF,   },
301 {       '6',            '^',            0xFF,           0xFF,   },
302 {       '7',            '&',            0xFF,           0xFF,   },
303 {       '8',            '*',            0xFF,           0xFF,   },
304 {       '9',            '(',            0xFF,           0xFF,   },
305 {       '0',            ')',            0xFF,           0xFF,   },
306 {       '-',            '_',            0xFF,           0xFF,   },
307 {       '=',            '+',            0xFF,           0xFF,   },
308 {       '\b',           '\b',           0xFF,           0xFF,   },
309 {       '\t',           '\t',           0xFF,           0xFF,   },
310 // 0x10
311 {       'q',            'Q',            0x11,           0xFF,   },
312 {       'w',            'W',            0x17,           0xFF,   },
313 {       'e',            'E',            0x05,           0xFF,   },
314 {       'r',            'R',            0x12,           0xFF,   },
315 {       't',            'T',            0x14,           0xFF,   },
316 {       'y',            'Y',            0x19,           0xFF,   },
317 {       'u',            'U',            0x15,           0xFF,   },
318 {       'i',            'I',            0x09,           0xFF,   },
319 {       'o',            'O',            0x0F,           0xFF,   },
320 {       'p',            'P',            0x10,           0xFF,   },
321 {       '[',            '{',            0x1b,           0xFF,   },
322 {       ']',            '}',            0x1d,           0xFF,   },
323 {       '\r',           '\r',           '\n',           0xFF,   },
324 {       0xFF,           0xFF,           0xFF,           0xFF,   },
325 {       'a',            'A',            0x01,           0xFF,   },
326 {       's',            'S',            0x13,           0xFF,   },
327 // 0x20
328 {       'd',            'D',            0x04,           0xFF,   },
329 {       'f',            'F',            0x06,           0xFF,   },
330 {       'g',            'G',            0x07,           0xFF,   },
331 {       'h',            'H',            0x08,           0xFF,   },
332 {       'j',            'J',            0x0a,           0xFF,   },
333 {       'k',            'K',            0x0b,           0xFF,   },
334 {       'l',            'L',            0x0c,           0xFF,   },
335 {       ';',            ':',            0xFF,           0xFF,   },
336 {       0x27,           '@',            0xFF,           0xFF,   },
337 {       '#',            '~',            0xFF,           0xFF,   },
338 {       '`',            '~',            0xFF,           0xFF,   },
339 {       '\\',           '|',            0x1C,           0xFF,   },
340 {       'z',            'Z',            0x1A,           0xFF,   },
341 {       'x',            'X',            0x18,           0xFF,   },
342 {       'c',            'C',            0x03,           0xFF,   },
343 {       'v',            'V',            0x16,           0xFF,   },
344 // 0x30
345 {       'b',            'B',            0x02,           0xFF,   },
346 {       'n',            'N',            0x0E,           0xFF,   },
347 {       'm',            'M',            0x0D,           0xFF,   },
348 {       ',',            '<',            0xFF,           0xFF,   },
349 {       '.',            '>',            0xFF,           0xFF,   },
350 {       '/',            '?',            0xFF,           0xFF,   },
351 {       0xFF,           0xFF,           0xFF,           0xFF,   },
352 {       '*',            0xFF,           0xFF,           0xFF,   },
353 {       0xFF,           0xFF,           0xFF,           0xFF,   },
354 {       ' ',            ' ',            ' ',            ' ',    },
355 {       0xFF,           0xFF,           0xFF,           0xFF,   },
356 {       0xF1,           0xE1,           0xFF,           0xFF,   },
357 {       0xF2,           0xE2,           0xFF,           0xFF,   },
358 {       0xF3,           0xE3,           0xFF,           0xFF,   },
359 {       0xF4,           0xE4,           0xFF,           0xFF,   },
360 {       0xF5,           0xE5,           0xFF,           0xFF,   },
361 // 0x40
362 {       0xFF,           0xFF,           0xFF,           0xFF,   },
363 {       0xFF,           0xFF,           0xFF,           0xFF,   },
364 {       0xFF,           0xFF,           0xFF,           0xFF,   },
365 {       0xFF,           0xFF,           0xFF,           0xFF,   },
366 {       0xFF,           0xFF,           0xFF,           0xFF,   },
367 {       0xFF,           0xFF,           0xFF,           0xFF,   },
368 {       0xFF,           0xFF,           0xFF,           0xFF,   },
369 {       '7',            0xFF,           0xFF,           0xFF,   },
370
371 {       '8',            0x15,           0x15,           0x15,   },
372 {       '9',            0x10,           0x10,           0x10,   },
373 {       '-',            0xFF,           0xFF,           0xFF,   },
374 {       '4',            0xFF,           0xFF,           0xFF,   },
375 {       '5',            0xFF,           0xFF,           0xFF,   },
376 {       '6',            0xFF,           0xFF,           0xFF,   },
377 {       '+',            0xFF,           0xFF,           0xFF,   },
378 {       '1',            0xFF,           0xFF,           0xFF,   },
379 // 0x50
380 {       '2',            0x04,           0x04,           0x04,   },
381 {       '3',            0x0e,           0x0e,           0x0e,   },
382 {       '0',            0xFF,           0xFF,           0xFF,   },
383 {       '.',            0xFF,           0xFF,           0xFF,   },
384 {       0xFF,           0xFF,           0xFF,           0xFF,   },
385 {       0xFF,           0xFF,           0xFF,           0xFF,   },
386 {       0xFF,           0xFF,           0xFF,           0xFF,   },
387 {       0xFF,           0xFF,           0xFF,           0xFF,   },
388 {       0xFF,           0xFF,           0xFF,           0xFF,   },
389 {       0xFF,           0xFF,           0xFF,           0xFF,   },
390 {       0xFF,           0xFF,           0xFF,           0xFF,   },
391 {       0xFF,           0xFF,           0xFF,           0xFF,   },
392 {       0xFF,           0xFF,           0xFF,           0xFF,   },
393 {       0xFF,           0xFF,           0xFF,           0xFF,   },
394 {       0xFF,           0xFF,           0xFF,           0xFF,   },
395 {       0xFF,           0xFF,           0xFF,           0xFF,   },
396 // 0x60
397 {       0xFF,           0xFF,           0xFF,           0xFF,   },
398 {       0xFF,           0xFF,           0xFF,           0xFF,   },
399 {       0xFF,           0xFF,           0xFF,           0xFF,   },
400 {       0xFF,           0xFF,           0xFF,           0xFF,   },
401 {       0xFF,           0xFF,           0xFF,           0xFF,   },
402 {       0xFF,           0xFF,           0xFF,           0xFF,   },
403 {       0xFF,           0xFF,           0xFF,           0xFF,   },
404 {       0xFF,           0xFF,           0xFF,           0xFF,   },
405 {       0xFF,           0xFF,           0xFF,           0xFF,   },
406 {       0xFF,           0xFF,           0xFF,           0xFF,   },
407 {       0xFF,           0xFF,           0xFF,           0xFF,   },
408 {       0xFF,           0xFF,           0xFF,           0xFF,   },
409 {       0xFF,           0xFF,           0xFF,           0xFF,   },
410 {       0xFF,           0xFF,           0xFF,           0xFF,   },
411 {       0xFF,           0xFF,           0xFF,           0xFF,   },
412 {       0xFF,           0xFF,           0xFF,           0xFF,   },
413 // 0x70
414 {       0xFF,           0xFF,           0xFF,           0xFF,   },
415 {       0xFF,           0xFF,           0xFF,           0xFF,   },
416 {       0xFF,           0xFF,           0xFF,           0xFF,   },
417 {       0xFF,           0xFF,           0xFF,           0xFF,   },
418 {       0xFF,           0xFF,           0xFF,           0xFF,   },
419 {       0xFF,           0xFF,           0xFF,           0xFF,   },
420 {       0xFF,           0xFF,           0xFF,           0xFF,   },
421 {       0xFF,           0xFF,           0xFF,           0xFF,   },
422 {       0xFF,           0xFF,           0xFF,           0xFF,   },
423 {       0xFF,           0xFF,           0xFF,           0xFF,   },
424 {       0xFF,           0xFF,           0xFF,           0xFF,   },
425 {       0xFF,           0xFF,           0xFF,           0xFF,   },
426 {       0xFF,           0xFF,           0xFF,           0xFF,   },
427 {       0xFF,           0xFF,           0xFF,           0xFF,   },
428 {       0xFF,           0xFF,           0xFF,           0xFF,   },
429 {       0xFF,           0xFF,           0xFF,           0xFF,   },
430         
431 };
432
433 static int KBIndexTab[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
434
435 //-----------------------------------------------------------------------------
436
437 static void KeyboardInit
438 (
439         void
440 )
441 {
442     KBFlags = 0;
443         
444 } /* KeyboardInit */
445
446 //-----------------------------------------------------------------------------
447
448 static CYG_BYTE KeyboardAscii
449 (
450         CYG_BYTE        scancode
451 )
452 {
453     CYG_BYTE ascii = 0xFF;
454
455     // Start by handling all shift/ctl keys:
456
457     switch( scancode )
458     {
459     case 0x53:  // delete
460         if (KBFlags & KBCtrl && KBFlags & KBAlt)
461         {
462             CYGACC_CALL_IF_RESET();
463         }
464         break;
465
466     case 0xe0:
467         KBFlags |= KBExtend;
468         return 0xFF;
469
470     case 0xfa:
471         KBFlags |= KBAck;
472         return 0xFF;
473
474     case 0xfe:
475         KBFlags |= KBResend;
476         return 0xFF;
477
478     case LSHIFT:
479         KBFlags |= KBShiftL;
480         return 0xFF;
481
482     case LSHIFT | BREAK:
483         KBFlags &= ~KBShiftL;
484         return 0xFF;
485
486     case RSHIFT:
487         KBFlags |= KBShiftR;
488         return 0xFF;
489
490     case RSHIFT | BREAK:
491         KBFlags &= ~KBShiftR;
492         return 0xFF;
493
494     case CTRL:
495         if( KBFlags & KBExtend )
496         {
497             KBFlags |= KBCtrlR;
498             KBFlags &= ~KBExtend;
499         }
500         else    KBFlags |= KBCtrlL;
501         return 0xFF;
502
503     case CTRL | BREAK:
504         if( KBFlags & KBExtend )
505         {
506             KBFlags &= ~KBCtrlR;
507             KBFlags &= ~KBExtend;
508         }
509         else    KBFlags &= ~KBCtrlL;
510         return 0xFF;
511
512
513     case ALT:
514         if( KBFlags & KBExtend )
515         {
516             KBFlags |= KBAltR;
517             KBFlags &= ~KBExtend;
518         }
519         else    KBFlags |= KBAltL;
520         return 0xFF;
521
522     case ALT | BREAK:
523         if( KBFlags & KBExtend )
524         {
525             KBFlags &= ~KBAltR;
526             KBFlags &= ~KBExtend;
527         }
528         else    KBFlags &= ~KBAltL;
529         return 0xFF;
530
531     case CAPS:
532         KBFlags ^= KBCapsLock;
533     case CAPS | BREAK:
534         return 0xFF;
535
536     case NUMS:
537         KBFlags ^= KBNumLock;
538     case NUMS | BREAK:
539         return 0xFF;
540     }
541
542     // Clear Extend flag if set
543     KBFlags &= ~KBExtend;
544
545     // Ignore all other BREAK codes
546     if( scancode & 0x80 ) return 0xFF;
547
548     // Here the scancode is for something we can turn
549     // into an ASCII value
550
551     ascii = KBScanTable[scancode & 0x7F][KBIndexTab[KBFlags & KBIndex]];
552
553     return ascii;
554
555 } /* KeyboardAscii */
556
557 //-----------------------------------------------------------------------------
558
559 static int KeyboardTest
560 (
561         void
562 )
563 {
564     // If there is a pending character, return True
565     if( KBPending != 0xFF ) return true;
566
567
568     // If there is something waiting at the port, get it
569     for(;;) 
570     {
571         CYG_BYTE stat, code;
572         CYG_BYTE c;
573         
574         HAL_READ_UINT8( KBSTATPORT, stat );
575
576         if( (stat & 0x01) == 0 )
577             break;
578
579         HAL_READ_UINT8( KBDATAPORT, code );
580
581         // Translate to ASCII
582         c = KeyboardAscii(code);
583                 
584         // if it is a real ASCII char, save it and
585         // return True.
586         if( c != 0xFF )
587         {
588             KBPending = c;
589             return true;
590         }
591
592     }
593
594     // Otherwise return False
595     return false;
596         
597 } /* KeyboardTest */
598
599 //=============================================================================
600 // Basic IO functions
601
602 static void
603 cyg_hal_plf_screen_init_channel(void* __ch_data)
604 {
605     KeyboardInit();
606     
607     XPos        = 0;
608     YPos        = 0;
609
610     ClearScreen();
611     MoveCursor();
612 }
613
614
615 void
616 cyg_hal_plf_screen_putc(void *__ch_data, char ch)
617 {
618     CYGARC_HAL_SAVE_GP();
619
620         switch( ch )
621         {
622         case '\n':
623                 NewLine();
624                 return;
625
626         case '\r':
627                 XPos = 0;
628                 MoveCursor();
629                 return;
630
631         case '\b':
632                 if( XPos == 0 ) return;
633                 XPos--;
634                 MoveCursor();
635                 return;
636
637         case '\t':
638                 do
639                 {
640                         DisplayChar(' ');
641                 } while( (XPos % 8) != 0 );
642                 return;
643
644         case 0x0c:
645                 ClearScreen();
646                 XPos = YPos = 0;
647                 MoveCursor();
648                 return;         
649
650         case 1:
651                 ScrollUp(1);
652                 XPos = 0;
653                 YPos = ScreenLength-1;
654                 return;
655
656         case 2:
657                 ScrollDown(1);
658                 XPos = 0;
659                 YPos = 0;
660                 return;
661         
662                 
663         default:
664                 DisplayChar(ch);
665                 return;
666         }
667
668     CYGARC_HAL_RESTORE_GP();
669 }
670
671 static cyg_bool
672 cyg_hal_plf_screen_getc_nonblock(void* __ch_data, cyg_uint8* ch)
673 {
674     if( !KeyboardTest() )
675         return false;
676
677     *ch = KBPending;
678     KBPending = 0xFF;
679
680     return true;
681 }
682
683 cyg_uint8
684 cyg_hal_plf_screen_getc(void* __ch_data)
685 {
686     cyg_uint8 ch;
687     CYGARC_HAL_SAVE_GP();
688
689     while(!cyg_hal_plf_screen_getc_nonblock(__ch_data, &ch));
690
691     CYGARC_HAL_RESTORE_GP();
692
693     return ch;
694 }
695
696
697
698 //=============================================================================
699 // Call IF support
700
701 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
702     || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
703
704 static void
705 cyg_hal_plf_screen_write(void* __ch_data, const cyg_uint8* __buf, 
706                          cyg_uint32 __len)
707 {
708     CYGARC_HAL_SAVE_GP();
709
710     while(__len-- > 0)
711         cyg_hal_plf_screen_putc(__ch_data, *__buf++);
712
713     CYGARC_HAL_RESTORE_GP();
714 }
715
716 static void
717 cyg_hal_plf_screen_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
718 {
719     CYGARC_HAL_SAVE_GP();
720
721     while(__len-- > 0)
722         *__buf++ = cyg_hal_plf_screen_getc(__ch_data);
723
724     CYGARC_HAL_RESTORE_GP();
725 }
726
727 cyg_bool
728 cyg_hal_plf_screen_getc_timeout(void* __ch_data, cyg_uint8* ch)
729 {
730     int delay_count;
731     channel_data_t* chan = (channel_data_t*)__ch_data;
732     cyg_bool res;
733     CYGARC_HAL_SAVE_GP();
734
735     delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
736
737     for(;;) {
738         res = cyg_hal_plf_screen_getc_nonblock(__ch_data, ch);
739         if (res || 0 == delay_count--)
740             break;
741         
742         CYGACC_CALL_IF_DELAY_US(100);
743     }
744
745     CYGARC_HAL_RESTORE_GP();
746     return res;
747 }
748
749 static int
750 cyg_hal_plf_screen_control(void *__ch_data, __comm_control_cmd_t __func, ...)
751 {
752     static int irq_state = 0;
753     channel_data_t* chan = (channel_data_t*)__ch_data;
754     int ret = 0;
755     CYGARC_HAL_SAVE_GP();
756
757     switch (__func) {
758     case __COMMCTL_IRQ_ENABLE:
759         irq_state = 1;
760
761         HAL_INTERRUPT_UNMASK(chan->isr_vector);
762         break;
763     case __COMMCTL_IRQ_DISABLE:
764         ret = irq_state;
765         irq_state = 0;
766
767         HAL_INTERRUPT_MASK(chan->isr_vector);
768         break;
769     case __COMMCTL_DBG_ISR_VECTOR:
770         ret = chan->isr_vector;
771         break;
772     case __COMMCTL_SET_TIMEOUT:
773     {
774         va_list ap;
775
776         va_start(ap, __func);
777
778         ret = chan->msec_timeout;
779         chan->msec_timeout = va_arg(ap, cyg_uint32);
780
781         va_end(ap);
782     }        
783     default:
784         break;
785     }
786     CYGARC_HAL_RESTORE_GP();
787     return ret;
788 }
789
790 static int
791 cyg_hal_plf_screen_isr(void *__ch_data, int* __ctrlc, 
792                        CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
793 {
794     int res = 0;
795     channel_data_t* chan = (channel_data_t*)__ch_data;
796     char c;
797
798     CYGARC_HAL_SAVE_GP();
799
800     cyg_drv_interrupt_acknowledge(chan->isr_vector);
801
802     *__ctrlc = 0;
803
804     if ( KeyboardTest() ) {
805
806         c = KBPending;
807         KBPending = 0xFF;
808         if( cyg_hal_is_break( &c , 1 ) )
809             *__ctrlc = 1;
810
811         res = CYG_ISR_HANDLED;
812     }
813
814     CYGARC_HAL_RESTORE_GP();
815     return res;
816 }
817
818 void cyg_hal_plf_screen_init(void)
819 {
820     hal_virtual_comm_table_t* comm;
821     int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
822
823     // Disable interrupts.
824     HAL_INTERRUPT_MASK(pc_ser_channels[PCMB_PORT_INDEX].isr_vector);
825
826     // Init channels
827     cyg_hal_plf_screen_init_channel(&pc_ser_channels[PCMB_PORT_INDEX]);
828
829     // Setup procs in the vector table
830
831     // Set channel 2
832     CYGACC_CALL_IF_SET_CONSOLE_COMM(PCMB_PORT_INDEX);
833     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
834     CYGACC_COMM_IF_CH_DATA_SET(*comm, &pc_ser_channels[PCMB_PORT_INDEX]);
835     CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_screen_write);
836     CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_screen_read);
837     CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_screen_putc);
838     CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_screen_getc);
839     CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_screen_control);
840     CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_screen_isr);
841     CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_screen_getc_timeout);
842
843     // Restore original console
844     CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
845 }
846
847 #endif //  defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
848        // || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
849
850
851 // Return the position of the cursor. 
852 void cyg_hal_plf_screen_position(int *x, int *y)
853 {
854     *x = XPos;
855     *y = YPos;
856 }
857
858 //-----------------------------------------------------------------------------
859
860 #endif // CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT
861
862 //-----------------------------------------------------------------------------
863 // End of pcmb_screen.c