1 //=============================================================================
5 // HAL diagnostic output code
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.
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.
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
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.
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.
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.
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####
44 // Contributors:proven
46 // Purpose: HAL diagnostic output
47 // Description: Implementations of HAL diagnostic output support.
49 //####DESCRIPTIONEND####
51 //=============================================================================
53 #include <pkgconf/hal.h>
54 #include <pkgconf/hal_i386_pcmb.h>
56 #if CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT
58 #include <cyg/infra/cyg_type.h> // base types
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>
67 #include <cyg/hal/pcmb_serial.h>
69 // Index into pc_ser_channels[] for screen entry.
70 #define PCMB_PORT_INDEX (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS - 1)
72 //-----------------------------------------------------------------------------
73 // Screen output definitions...
75 static short *DisplayBuffer = (short *)0xB8000;
76 static short DisplayAttr = 0x0700;
78 static short DisplayPort = 0x03d4;
83 static int ScreenWidth = 80;
84 static int ScreenLength = 25;
86 //-----------------------------------------------------------------------------
96 while( count-- ) *dest++ = *src++;
100 //-----------------------------------------------------------------------------
109 while( count-- ) *dest++ = val;
113 //-----------------------------------------------------------------------------
115 void ClearScreen(void)
117 FillLine(DisplayBuffer, ' ' | DisplayAttr, ScreenWidth*ScreenLength);
126 int pos = XPos + YPos * ScreenWidth;
128 HAL_WRITE_UINT8(DisplayPort, 0x0e );
129 HAL_WRITE_UINT8(DisplayPort+1, pos >> 8 );
131 HAL_WRITE_UINT8(DisplayPort, 0x0f );
132 HAL_WRITE_UINT8(DisplayPort+1, pos & 0xFF );
136 //-----------------------------------------------------------------------------
143 // Report_Function(ScrollUp)
145 int rest = ScreenLength - lines;
150 DisplayBuffer+(lines*ScreenWidth),
156 DisplayBuffer+(rest*ScreenWidth),
163 //-----------------------------------------------------------------------------
170 // Report_Function(ScrollDown)
172 int rest = ScreenLength - lines;
173 short *db = DisplayBuffer+(ScreenWidth*(ScreenLength-1));
197 //-----------------------------------------------------------------------------
208 if( YPos >= ScreenLength )
210 YPos = ScreenLength-1;
218 //-----------------------------------------------------------------------------
226 DisplayBuffer[XPos + YPos*ScreenWidth] = ch | DisplayAttr;
230 if( XPos >= ScreenWidth )
234 if( YPos >= ScreenLength )
236 YPos = ScreenLength-1;
245 //-----------------------------------------------------------------------------
246 // Keyboard definitions
248 #define KBDATAPORT 0x0060 // data I/O port
249 #define KBCMDPORT 0x0064 // command port (write)
250 #define KBSTATPORT 0x0064 // status port (read)
265 #define KBNormal 0x0000
266 #define KBShift 0x0001
267 #define KBCtrl 0x0002
269 #define KBIndex 0x0007 // mask for the above
271 #define KBExtend 0x0010
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
283 //-----------------------------------------------------------------------------
284 // Keyboard Variables
286 static int KBFlags = 0;
288 static CYG_BYTE KBPending = 0xFF;
290 static CYG_BYTE KBScanTable[128][4] =
292 // Normal Shift Control Alt
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, },
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, },
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, },
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, },
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, },
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, },
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, },
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, },
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, },
433 static int KBIndexTab[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
435 //-----------------------------------------------------------------------------
437 static void KeyboardInit
446 //-----------------------------------------------------------------------------
448 static CYG_BYTE KeyboardAscii
453 CYG_BYTE ascii = 0xFF;
455 // Start by handling all shift/ctl keys:
460 if (KBFlags & KBCtrl && KBFlags & KBAlt)
462 CYGACC_CALL_IF_RESET();
483 KBFlags &= ~KBShiftL;
491 KBFlags &= ~KBShiftR;
495 if( KBFlags & KBExtend )
498 KBFlags &= ~KBExtend;
500 else KBFlags |= KBCtrlL;
504 if( KBFlags & KBExtend )
507 KBFlags &= ~KBExtend;
509 else KBFlags &= ~KBCtrlL;
514 if( KBFlags & KBExtend )
517 KBFlags &= ~KBExtend;
519 else KBFlags |= KBAltL;
523 if( KBFlags & KBExtend )
526 KBFlags &= ~KBExtend;
528 else KBFlags &= ~KBAltL;
532 KBFlags ^= KBCapsLock;
537 KBFlags ^= KBNumLock;
542 // Clear Extend flag if set
543 KBFlags &= ~KBExtend;
545 // Ignore all other BREAK codes
546 if( scancode & 0x80 ) return 0xFF;
548 // Here the scancode is for something we can turn
549 // into an ASCII value
551 ascii = KBScanTable[scancode & 0x7F][KBIndexTab[KBFlags & KBIndex]];
555 } /* KeyboardAscii */
557 //-----------------------------------------------------------------------------
559 static int KeyboardTest
564 // If there is a pending character, return True
565 if( KBPending != 0xFF ) return true;
568 // If there is something waiting at the port, get it
574 HAL_READ_UINT8( KBSTATPORT, stat );
576 if( (stat & 0x01) == 0 )
579 HAL_READ_UINT8( KBDATAPORT, code );
581 // Translate to ASCII
582 c = KeyboardAscii(code);
584 // if it is a real ASCII char, save it and
594 // Otherwise return False
599 //=============================================================================
600 // Basic IO functions
603 cyg_hal_plf_screen_init_channel(void* __ch_data)
616 cyg_hal_plf_screen_putc(void *__ch_data, char ch)
618 CYGARC_HAL_SAVE_GP();
632 if( XPos == 0 ) return;
641 } while( (XPos % 8) != 0 );
653 YPos = ScreenLength-1;
668 CYGARC_HAL_RESTORE_GP();
672 cyg_hal_plf_screen_getc_nonblock(void* __ch_data, cyg_uint8* ch)
674 if( !KeyboardTest() )
684 cyg_hal_plf_screen_getc(void* __ch_data)
687 CYGARC_HAL_SAVE_GP();
689 while(!cyg_hal_plf_screen_getc_nonblock(__ch_data, &ch));
691 CYGARC_HAL_RESTORE_GP();
698 //=============================================================================
701 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
702 || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
705 cyg_hal_plf_screen_write(void* __ch_data, const cyg_uint8* __buf,
708 CYGARC_HAL_SAVE_GP();
711 cyg_hal_plf_screen_putc(__ch_data, *__buf++);
713 CYGARC_HAL_RESTORE_GP();
717 cyg_hal_plf_screen_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
719 CYGARC_HAL_SAVE_GP();
722 *__buf++ = cyg_hal_plf_screen_getc(__ch_data);
724 CYGARC_HAL_RESTORE_GP();
728 cyg_hal_plf_screen_getc_timeout(void* __ch_data, cyg_uint8* ch)
731 channel_data_t* chan = (channel_data_t*)__ch_data;
733 CYGARC_HAL_SAVE_GP();
735 delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
738 res = cyg_hal_plf_screen_getc_nonblock(__ch_data, ch);
739 if (res || 0 == delay_count--)
742 CYGACC_CALL_IF_DELAY_US(100);
745 CYGARC_HAL_RESTORE_GP();
750 cyg_hal_plf_screen_control(void *__ch_data, __comm_control_cmd_t __func, ...)
752 static int irq_state = 0;
753 channel_data_t* chan = (channel_data_t*)__ch_data;
755 CYGARC_HAL_SAVE_GP();
758 case __COMMCTL_IRQ_ENABLE:
761 HAL_INTERRUPT_UNMASK(chan->isr_vector);
763 case __COMMCTL_IRQ_DISABLE:
767 HAL_INTERRUPT_MASK(chan->isr_vector);
769 case __COMMCTL_DBG_ISR_VECTOR:
770 ret = chan->isr_vector;
772 case __COMMCTL_SET_TIMEOUT:
776 va_start(ap, __func);
778 ret = chan->msec_timeout;
779 chan->msec_timeout = va_arg(ap, cyg_uint32);
786 CYGARC_HAL_RESTORE_GP();
791 cyg_hal_plf_screen_isr(void *__ch_data, int* __ctrlc,
792 CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
795 channel_data_t* chan = (channel_data_t*)__ch_data;
798 CYGARC_HAL_SAVE_GP();
800 cyg_drv_interrupt_acknowledge(chan->isr_vector);
804 if ( KeyboardTest() ) {
808 if( cyg_hal_is_break( &c , 1 ) )
811 res = CYG_ISR_HANDLED;
814 CYGARC_HAL_RESTORE_GP();
818 void cyg_hal_plf_screen_init(void)
820 hal_virtual_comm_table_t* comm;
821 int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
823 // Disable interrupts.
824 HAL_INTERRUPT_MASK(pc_ser_channels[PCMB_PORT_INDEX].isr_vector);
827 cyg_hal_plf_screen_init_channel(&pc_ser_channels[PCMB_PORT_INDEX]);
829 // Setup procs in the vector table
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);
843 // Restore original console
844 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
847 #endif // defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
848 // || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
851 // Return the position of the cursor.
852 void cyg_hal_plf_screen_position(int *x, int *y)
858 //-----------------------------------------------------------------------------
860 #endif // CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT
862 //-----------------------------------------------------------------------------
863 // End of pcmb_screen.c