OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [software/] [FMTK/] [source/] [kernel/] [keybd.c] - Rev 23

Compare with Previous | Blame | View Log

// The keyboard semaphore is locked only for short durations, so the interrupt
// routine doesn't need to make many attempts to lock the semaphore.
 
#include "config.h"
#include "const.h"
#include "types.h"
#include "glo.h"
#include "proto.h"
 
#define SC_F12      0x07
#define SC_C        0x21
#define SC_T        0x2C
#define SC_Z        0x1A
#define SC_KEYUP	0xF0
#define SC_EXTEND   0xE0
#define SC_CTRL		0x14
#define SC_RSHIFT	0x59
#define SC_NUMLOCK	0x77
#define SC_SCROLLLOCK	0x7E
#define SC_CAPSLOCK	0x58
#define SC_ALT		0x11
/*
#define SC_LSHIFT	EQU		$12
SC_DEL		EQU		$71		; extend
SC_LCTRL	EQU		$58
*/
#define SC_TAB      0x0D
 
extern byte keybdExtendedCodes[];
extern byte keybdControlCodes[];
extern byte shiftedScanCodes[];
extern byte unshiftedScanCodes[];
extern signed byte KeybdGetStatus();
extern byte KeybdGetScancode();
extern void KeybdClearRcv();
int kbd_sema = 0;
 
//
// KeyState2_
// 76543210
// |||||||+ = shift
// ||||||+- = alt
// |||||+-- = control
// ||||+--- = numlock
// |||+---- = capslock
// ||+----- = scrolllock
// |+------ =
// +------- = extended
//
 
unsigned int keybd_irq_stack[256];
static hMBX hKeybdMbx = -1;
 
void KeybdIRQ()
{
    __int8 sc;
    __int8 kh, kt;
    hTCB ht;
    TCB *t;
    JCB *jcb;
    int nn;
 
	prolog asm {
		sync
		sw		r1,TCB_ir1[tr]
		sw		r2,TCB_ir2[tr]
		sw		r3,TCB_ir3[tr]
		sw		r4,TCB_ir4[tr]
		sw		r5,TCB_ir5[tr]
		sw		r6,TCB_ir6[tr]
		sw		r7,TCB_ir7[tr]
		sw		r8,TCB_ir8[tr]
		sw		r9,TCB_ir9[tr]
		sw		r10,TCB_ir10[tr]
		sw		r11,TCB_ir11[tr]
		sw		r12,TCB_ir12[tr]
		sw		r13,TCB_ir13[tr]
		sw		r14,TCB_ir14[tr]
		sw		r15,TCB_ir15[tr]
		sw		r16,TCB_ir16[tr]
		sw		r17,TCB_ir17[tr]
		sw		r18,TCB_ir18[tr]
		sw		r19,TCB_ir19[tr]
		sw		r20,TCB_ir20[tr]
		sw		r21,TCB_ir21[tr]
		sw		r22,TCB_ir22[tr]
		sw		r23,TCB_ir23[tr]
		sw		r24,TCB_ir24[tr]
		sw		r25,TCB_ir25[tr]
		sw		r26,TCB_ir26[tr]
		sw		r27,TCB_ir27[tr]
		sws		ds,TCB_ids[tr]
		sws		es,TCB_ies[tr]
		sws		fs,TCB_ifs[tr]
		sws		gs,TCB_igs[tr]
		sws		hs,TCB_ihs[tr]
		sws		ss,TCB_iss[tr]
		sws		cs,TCB_ics[tr]
		sws		ds.lmt,TCB_idslmt[tr]
		sws		es.lmt,TCB_ieslmt[tr]
		sws		fs.lmt,TCB_ifslmt[tr]
		sws		gs.lmt,TCB_igslmt[tr]
		sws		hs.lmt,TCB_ihslmt[tr]
		sws		ss.lmt,TCB_isslmt[tr]
		sws		cs.lmt,TCB_icslmt[tr]
		sws		c1,TCB_ic1[tr]
		sws		c2,TCB_ic2[tr]
		sws		c3,TCB_ic3[tr]
		sws		c4,TCB_ic4[tr]
		sws		c5,TCB_ic5[tr]
		sws		c6,TCB_ic6[tr]
		sws		c7,TCB_ic7[tr]
		sws		c8,TCB_ic8[tr]
		sws		c9,TCB_ic9[tr]
		sws		c10,TCB_ic10[tr]
		sws		c11,TCB_ic11[tr]
		sws		c13,TCB_ic13[tr]
		sws		c14,TCB_ic14[tr]
		sws		pregs,TCB_ipregs[tr]
 
		ldi		sp,#irq_stack_+511*8	; setup system stack and data segments
		mtspr	ss,r0
		ldis	ss.lmt,#-1
		mtspr	ds,r0
		ldis	ds.lmt,#-1
		ldi		hs,#$FFD00000
		ldi		hs.lmt,#$100000
	}
     while (KeybdGetStatus() < 0) {    // Is there actually a scancode available ?
         sc = KeybdGetScancode();
         jcb = IOFocusNdx;             // Are there any jobs with focus ?     
         if (jcb) {
          	 if (LockSemaphore(&kbd_sema,200)) {
                 KeybdClearRcv();              // clear recieve register
                 kh = jcb->KeybdHead;
                 kt = jcb->KeybdTail;
                 kh++;
				 if (kh > jcb->KeybdBufSz)
					 kh = 0;
                 if (kh <> kt) {
                     jcb->KeybdHead = kh;   
                     jcb->KeybdBuf[kh] = sc;
                 }
                 UnlockSemaphore(&kbd_sema);
             }
             // Trigger debugger if F12 pressed. Set a breakpoint at the RTI
             // return address.
             if (sc==SC_F12 && !jcb->KeyState1) {
                 asm {
                     mfspr  r1,ipc
                     mtspr  dbad0,r1      ; Set breakpoint 0 address
                     mfspr  r1,dbctrl
                     or     r1,r1,#1      ; enable breakpoint #0
                     and    r1,r1,#~0x30000
                     mtspr  dbctrl,r1
                 }
             }
             // If CTRL-C is pressed, cause the tasks to return to the 
             // catch handler.
             if (jcb->KeyState2 & 4) {
                 if(sc == SC_C) {      // control-c ?
                     for (nn = 0; nn < 8; nn++) {
                         if (jcb->tasks[nn]==-1)
                             break;
                         t = &tcbs[jcb->tasks[nn]];
                         t->exception = 512+3;     // CTRL-C type exception
                     }
                 }
                 else if (sc==SC_T || sc==SC_Z) {
                      t = &tcbs[2];
                      t->exception = (512 + ((sc==SC_T) ? 20 : 26)) | (GetRunningTCB() << 32);
                 }
             }
             if ((jcb->KeyState2 & 2) && sc == SC_TAB)    // ALT + TAB ?
                 if (hFocusSwitchMbx >= 0)
                     FMTK_PostMsg(hFocusSwitchMbx,-1,-1,-1);
//                 iof_switch++;
         }
         if (hKeybdMbx >= 0)
            FMTK_PostMsg(hKeybdMbx,-1,-1,-1);
     }
     // Restore the processor registers and return using an RTI.
	epilog asm {
		lw		r1,TCB_ir1[tr]
		lw		r2,TCB_ir2[tr]
		lw		r3,TCB_ir3[tr]
		lw		r4,TCB_ir4[tr]
		lw		r5,TCB_ir5[tr]
		lw		r6,TCB_ir6[tr]
		lw		r7,TCB_ir7[tr]
		lw		r8,TCB_ir8[tr]
		lw		r9,TCB_ir9[tr]
		lw		r10,TCB_ir10[tr]
		lw		r11,TCB_ir11[tr]
		lw		r12,TCB_ir12[tr]
		lw		r13,TCB_ir13[tr]
		lw		r14,TCB_ir14[tr]
		lw		r15,TCB_ir15[tr]
		lw		r16,TCB_ir16[tr]
		lw		r17,TCB_ir17[tr]
		lw		r18,TCB_ir18[tr]
		lw		r19,TCB_ir19[tr]
		lw		r20,TCB_ir20[tr]
		lw		r21,TCB_ir21[tr]
		lw		r22,TCB_ir22[tr]
		lw		r23,TCB_ir23[tr]
		lw		r24,TCB_ir24[tr]
		lw		r25,TCB_ir25[tr]
		lw		r26,TCB_ir26[tr]
		lw		r27,TCB_ir27[tr]
		lws		ds,TCB_ids[tr]
		lws		es,TCB_ies[tr]
		lws		fs,TCB_ifs[tr]
		lws		gs,TCB_igs[tr]
		lws		hs,TCB_ihs[tr]
		lws		ss,TCB_iss[tr]
		lws		cs,TCB_ics[tr]
		lws		ds.lmt,TCB_idslmt[tr]
		lws		es.lmt,TCB_ieslmt[tr]
		lws		fs.lmt,TCB_ifslmt[tr]
		lws		gs.lmt,TCB_igslmt[tr]
		lws		hs.lmt,TCB_ihslmt[tr]
		lws		ss.lmt,TCB_isslmt[tr]
		lws		cs.lmt,TCB_icslmt[tr]
		lws		c1,TCB_ic1[tr]
		lws		c2,TCB_ic2[tr]
		lws		c3,TCB_ic3[tr]
		lws		c4,TCB_ic4[tr]
		lws		c5,TCB_ic5[tr]
		lws		c6,TCB_ic6[tr]
		lws		c7,TCB_ic7[tr]
		lws		c8,TCB_ic8[tr]
		lws		c9,TCB_ic9[tr]
		lws		c10,TCB_ic10[tr]
		lws		c11,TCB_ic11[tr]
		lws		c13,TCB_ic13[tr]
		lws		c14,TCB_ic14[tr]
		lws		pregs,TCB_ipregs[tr]
		sync
		rti
	}
}
 
 
// Return -1 if there is a scancode available in the buffer.
 
int KeybdGetBufferStatus()
{
    JCB *j;
    __int8 kh, kt;
 
    kh = kt = 0;
    j = GetJCBPtr();
    if (LockSemaphore(&kbd_sema,200)) {
        kh = j->KeybdHead;
        kt = j->KeybdTail;
        UnlockSemaphore(&kbd_sema);
    }
    if (kh<>kt)
        return -1;
    return 0;
 
}
 
// Get a scancode from the keyboard buffer.
 
__int8 KeybdGetBufferedScancode()
{
    JCB *j;
    __int8 kh, kt;
    __int8 sc;
 
    j = GetJCBPtr();
    sc = 0;
    if (LockSemaphore(&kbd_sema,200)) {
        kh = j->KeybdHead;
        kt = j->KeybdTail;
        if (kh <> kt) {
            sc = j->KeybdBuf[kt];
            kt++;
			if (kt > j->KeybdBufSz)
				kt = 0;
            j->KeybdTail = kt;
        }
        UnlockSemaphore(&kbd_sema);
    }
    return sc;
}
 
private char KeybdGetBufferedChar()
{
    JCB *j;
    unsigned __int8 sc;
    char ch;
    int d1, d2, d3;
	static int fc = 0;
 
    if (!fc) {
        FMTK_AllocMbx(&hKeybdMbx);
		fc = 1;
    }
    j = GetJCBPtr();
    forever {
        while (KeybdGetBufferStatus() >= 0) {
            if (j->KeybdWaitFlag==0)
                return -1;
            FMTK_WaitMsg(hKeybdMbx, &d1, &d2, &d3, 0x7FFFFFFFFFFFFFFFL);
        }
        // The following typecast is needed to avoid a compiler bug in the
        // optimizer which removes the conversion from byte to word by zero
        // extension.
        sc = (unsigned __int8)KeybdGetBufferedScancode();
        switch(sc) {
        case SC_KEYUP:
            j->KeyState1 = -1;
            break;
        case SC_EXTEND:
            j->KeyState2 |= 0x80;
            break;
        case SC_CTRL:
            if (j->KeyState1 >= 0)
                j->KeyState2 |= 4;
            else
                j->KeyState2 &= ~4;
            j->KeyState1 = 0;
            break;
        case SC_RSHIFT:
            if (j->KeyState1 >= 0)
                j->KeyState2 |= 1;
            else
                j->KeyState2 &= ~1;
            j->KeyState1 = 0;
            break;
        case SC_NUMLOCK:
            j->KeyState2 ^= 16;
            //KeybdSetLEDStatus();
            break;
        case SC_CAPSLOCK:
            j->KeyState2 ^= 32;
            //KeybdSetLEDStatus();
            break;
        case SC_SCROLLLOCK:
            j->KeyState2 ^= 64;
            //KeybdSetLEDStatus();
            break;
        case SC_ALT:
            if (j->KeyState1 >= 0)
                j->KeyState2 |= 2;
            else
                j->KeyState2 &= ~2;
            j->KeyState1 = 0;
            break;
        default:
            if (sc == SC_TAB && (j->KeyState2 & 2) && j->KeyState1==0) {
                iof_switch++;
            }
            else {
                 if (j->KeyState1) {
                     j->KeyState1 = 0;
                 }
                 else {
                      if (j->KeyState2 & 0x80) { // Extended code ?
                          j->KeyState2 &= ~0x80;
                          ch = keybdExtendedCodes[sc];
                          return ch;
                      }
                      else if (j->KeyState2 & 0x04) { // control ?
                          ch = keybdControlCodes[sc];
                          return ch;
                      }
                      else if (j->KeyState2 & 0x01) { // shifted ?
                          ch = shiftedScanCodes[sc];
                          return ch;
                      }
                      else {
                          ch = unshiftedScanCodes[sc];
                          return ch;
                      }
                 }
            }
        }
    }
}
 
char KeybdGetBufferedCharWait() {
    JCB *j;
    j = GetJCBPtr();
    j->KeybdWaitFlag = 1;
    return KeybdGetBufferedChar();     
}
 
char KeybdGetBufferedCharNoWait() {
    JCB *j;
    j = GetJCBPtr();
    j->KeybdWaitFlag = 0;
    return KeybdGetBufferedChar();     
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.