⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vga_support.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
// 0x70
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
};

static int KBIndexTab[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };

//-----------------------------------------------------------------------------

static __inline__ cyg_uint8
inb(cyg_uint32 port)
{
    cyg_uint8 val;
    val = localbus_readl(port<<2);
    return val;
}

static __inline__ void
outb(cyg_uint32 port, cyg_uint8 val)
{
    localbus_writel(val, port<<2);
}

static cyg_bool
KeyboardInit(void)
{
    unsigned char c, s;

    /* flush input queue */
    while ((inb(KBSTATPORT) & KBINRDY)) {
        (void)inb(KBDATAPORT);
    }

    /* Send self-test - controller local */
    while (inb(KBSTATPORT) & KBOUTRDY) c = inb(KBDATAPORT);
    outb(KBCMDPORT,0xAA);
    while ((inb(KBSTATPORT) & KBINRDY) == 0) ; /* wait input ready */
    if ((c = inb(KBDATAPORT)) != 0x55) {
#ifdef DEBUG_KBD_INIT
        diag_printf("Keyboard self test failed - result: %x\n", c);
#endif
        return false;
    }

    /* Enable interrupts and keyboard controller */
    while (inb(KBSTATPORT) & KBOUTRDY) ;
    outb(KBCMDPORT,0x60);     
    while (inb(KBSTATPORT) & KBOUTRDY) ;
    outb(KBCMDPORT,0x45);
    CYGACC_CALL_IF_DELAY_US(10000);  // 10ms
        
    while (inb(KBSTATPORT) & KBOUTRDY) ;
    outb(KBCMDPORT,0xAE);  // Enable keyboard

    /* See if a keyboard is connected */
    while (inb(KBSTATPORT) & KBOUTRDY) ;
    outb(KBDATAPORT,0xFF);     
    while (((s = inb(KBSTATPORT)) & (KBINRDY|KBTXTO)) == 0) ; /* wait input ready */
    if ((s & KBTXTO) || ((c = inb(KBDATAPORT)) != 0xFA)) {
#ifdef DEBUG_KBD_INIT
        diag_printf("Keyboard reset failed - no ACK: %x, stat: %x\n", c, s);
#endif
        return false;
    }
    while (((s = inb(KBSTATPORT)) & KBINRDY) == 0) ; /* wait input ready */
    if ((s & KBTXTO) || ((c = inb(KBDATAPORT)) != 0xAA)) {
#ifdef DEBUG_KBD_INIT
        diag_printf("Keyboard reset failed - bad code: %x, stat: %x\n", c, s);
#endif
        return false;
    }

    // Set scan mode
    while (inb(KBSTATPORT) & KBOUTRDY) ;
    outb(KBCMDPORT,0x20);
    while ((inb(KBSTATPORT) & KBINRDY) == 0) ; /* wait input ready */
    if (! (inb(KBDATAPORT) & 0x40)) {
        /*
         * Quote from PS/2 System Reference Manual:
         *
         * "Address hex 0060 and address hex 0064 should be
         * written only when the input-buffer-full bit and
         * output-buffer-full bit in the Controller Status
         * register are set 0." (KBINRDY and KBOUTRDY)
         */
                
        while (inb(KBSTATPORT) & (KBINRDY | KBOUTRDY)) ;
        outb(KBDATAPORT,0xF0);
        while (inb(KBSTATPORT) & (KBINRDY | KBOUTRDY)) ;
        outb(KBDATAPORT,0x01);
    }
        
    KBFlags = 0;
    return true;
} /* KeyboardInit */

//-----------------------------------------------------------------------------

static CYG_BYTE 
KeyboardAscii(CYG_BYTE scancode)
{
    CYG_BYTE ascii = 0xFF;

    // Start by handling all shift/ctl keys:

    switch( scancode ) {
    case 0xe0:
        KBFlags |= KBExtend;
        return 0xFF;

    case 0xfa:
        KBFlags |= KBAck;
        return 0xFF;

    case 0xfe:
        KBFlags |= KBResend;
        return 0xFF;

    case LSHIFT:
        KBFlags |= KBShiftL;
        return 0xFF;

    case LSHIFT | BREAK:
        KBFlags &= ~KBShiftL;
        return 0xFF;

    case RSHIFT:
        KBFlags |= KBShiftR;
        return 0xFF;

    case RSHIFT | BREAK:
        KBFlags &= ~KBShiftR;
        return 0xFF;

    case CTRL:
        if( KBFlags & KBExtend )
        {
            KBFlags |= KBCtrlR;
            KBFlags &= ~KBExtend;
        }
        else  KBFlags |= KBCtrlL;
        return 0xFF;

    case CTRL | BREAK:
        if( KBFlags & KBExtend )
        {
            KBFlags &= ~KBCtrlR;
            KBFlags &= ~KBExtend;
        }
        else  KBFlags &= ~KBCtrlL;
        return 0xFF;


    case ALT:
        if( KBFlags & KBExtend )
        {
            KBFlags |= KBAltR;
            KBFlags &= ~KBExtend;
        }
        else  KBFlags |= KBAltL;
        return 0xFF;

    case ALT | BREAK:
        if( KBFlags & KBExtend )
        {
            KBFlags &= ~KBAltR;
            KBFlags &= ~KBExtend;
        }
        else  KBFlags &= ~KBAltL;
        return 0xFF;

    case CAPS:
        KBFlags ^= KBCapsLock;
    case CAPS | BREAK:
        return 0xFF;

    case NUMS:
        KBFlags ^= KBNumLock;
    case NUMS | BREAK:
        return 0xFF;

    case KBArrowUp:
    case KBArrowDown:
        screen_pan = 0;
        vga_refresh();
        break;
    case KBArrowLeft:
        screen_pan -= SCREEN_PAN;
        if (screen_pan < 0) screen_pan = 0;
        vga_refresh();
        break;
    case KBArrowRight:
        screen_pan += SCREEN_PAN;
        if (screen_pan > (SCREEN_WIDTH-SCREEN_PAN)) 
            screen_pan = SCREEN_WIDTH-SCREEN_PAN;
        vga_refresh();
        break;

    }

    // Clear Extend flag if set
    KBFlags &= ~KBExtend;

    // Ignore all other BREAK codes
    if( scancode & 0x80 ) return 0xFF;

    // Here the scancode is for something we can turn
    // into an ASCII value

    ascii = KBScanTable[scancode & 0x7F][KBIndexTab[KBFlags & KBIndex]];

    return ascii;

} /* KeyboardAscii */

//-----------------------------------------------------------------------------

static int 
KeyboardTest(void)
{
    // If there is a pending character, return True
    if( KBPending != 0xFF ) return true;

    // If there is something waiting at the port, get it
    for(;;) {
        CYG_BYTE stat, code;
        CYG_BYTE c;
        
        stat = inb(KBSTATPORT);

        if( (stat & KBINRDY) == 0 )
            break;

        code = inb(KBDATAPORT);

        // Translate to ASCII
        c = KeyboardAscii(code);
    
        // if it is a real ASCII char, save it and
        // return True.
        if( c != 0xFF ) {
            KBPending = c;
            return true;
        }
    }

    // Otherwise return False
    return false;
  
} /* KeyboardTest */

char 
KeyboardChar(void)
{
    char c = KBPending;
    KBPending = 0xFF;
    return c;
}

static int  _timeout = 500;

static cyg_bool
vga_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch)
{
    if( !KeyboardTest() )
        return false;
    *ch = KBPending;
    KBPending = 0xFF;
    return true;
}

static cyg_uint8
vga_comm_getc(void* __ch_data)
{
    cyg_uint8 ch;

    while (!vga_comm_getc_nonblock(__ch_data, &ch)) ;
    return ch;
}

static void
vga_comm_putc(void* __ch_data, cyg_uint8 c)
{
    vga_putc(c);
}

static void
vga_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
{
#if 0
    CYGARC_HAL_SAVE_GP();

    while(__len-- > 0)
        vga_comm_putc(__ch_data, *__buf++);

    CYGARC_HAL_RESTORE_GP();
#endif
}

static void
vga_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
{
#if 0
    CYGARC_HAL_SAVE_GP();

    while(__len-- > 0)
        *__buf++ = vga_comm_getc(__ch_data);

    CYGARC_HAL_RESTORE_GP();
#endif
}

static cyg_bool
vga_comm_getc_timeout(void* __ch_data, cyg_uint8* ch)
{
    int delay_count;
    cyg_bool res;

    delay_count = _timeout * 2; // delay in .5 ms steps
    for(;;) {
        res = vga_comm_getc_nonblock(__ch_data, ch);
        if (res || 0 == delay_count--)
            break;
        CYGACC_CALL_IF_DELAY_US(500);
    }
    return res;
}

static int
vga_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...)
{
    static int vector = 0;
    int ret = -1;
    static int irq_state = 0;

    CYGARC_HAL_SAVE_GP();

    switch (__func) {
    case __COMMCTL_IRQ_ENABLE:
        ret = irq_state;
        irq_state = 1;
        break;
    case __COMMCTL_IRQ_DISABLE:
        ret = irq_state;
        irq_state = 0;
        break;
    case __COMMCTL_DBG_ISR_VECTOR:
        ret = vector;
        break;
    case __COMMCTL_SET_TIMEOUT:
    {
        va_list ap;

        va_start(ap, __func);

        ret = _timeout;
        _timeout = va_arg(ap, cyg_uint32);

        va_end(ap);
        break;
    }
    case __COMMCTL_FLUSH_OUTPUT:
        ret = 0;
        break;
    default:
        break;
    }
    CYGARC_HAL_RESTORE_GP();
    return ret;
}

static int
vga_comm_isr(void *__ch_data, int* __ctrlc, 
           CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
{
#if 0
    char ch;

    cyg_drv_interrupt_acknowledge(__vector);
    *__ctrlc = 0;
    if (vga_comm_getc_nonblock(__ch_data, &ch)) {
        if (ch == 0x03) {
            *__ctrlc = 1;
        }
    }
    return CYG_ISR_HANDLED;
#else
    return 0;
#endif
}

void
vga_comm_init(cyg_uint32 *addr)
{
    static int init = 0;

    if (!init) {
        hal_virtual_comm_table_t* comm;
        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);

        init = 1;
        if (!KeyboardInit()) {
            // No keyboard - no VGA/CRT display
            return;
        }

        // Initialize screen
        cursor_enable = true;
        vga_init(addr);
        vga_on(true);
        vga_screen_clear();

        // Setup procs in the vector table
        CYGACC_CALL_IF_SET_CONSOLE_COMM(1);  // FIXME - should be controlled by CDL
        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
        //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
        CYGACC_COMM_IF_WRITE_SET(*comm, vga_comm_write);
        CYGACC_COMM_IF_READ_SET(*comm, vga_comm_read);
        CYGACC_COMM_IF_PUTC_SET(*comm, vga_comm_putc);
        CYGACC_COMM_IF_GETC_SET(*comm, vga_comm_getc);
        CYGACC_COMM_IF_CONTROL_SET(*comm, vga_comm_control);
        CYGACC_COMM_IF_DBG_ISR_SET(*comm, vga_comm_isr);
        CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, vga_comm_getc_timeout);

        // Restore original console
        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
    }
}

#ifdef CYGPKG_REDBOOT
#include <redboot.h>

// Get here when RedBoot is idle.  If it's been long enough, then
// dim the VGA.  The problem is - how to determine other activities
// so at this doesn't get in the way.  In the default case, this will
// be called from RedBoot every 10ms (CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT)

#define MAX_IDLE_TIME (30*100)

static void
idle(bool is_idle)
{
    static int idle_time = 0;
    static bool was_idled = false;

    if (is_idle) {
        if (!was_idled) {
            if (++idle_time == MAX_IDLE_TIME) {
                was_idled = true;
                vga_on(false);
            }
        }
    } else {        
        idle_time = 0;
        if (was_idled) {
            was_idled = false;
                vga_on(true);
        }
    }
}

RedBoot_idle(idle, RedBoot_AFTER_NETIO);
#endif
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -