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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [peripheral/] [ps2kbd.c] - Blame information for rev 664

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 664 markom
/* ps2kbd.c -- Very simple (and limited) PS/2 keyboard simulation
2
   Copyright (C) 2002 Marko Mlinar, markom@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include "ps2kbd.h"
24
#include "sim-config.h"
25
#include "abstract.h"
26
 
27
/* ASCII to scan code conversion table */
28
const static struct {
29
  /* Whether shift must be pressed */
30
  unsigned char shift;
31
  /* Scan code to be generated */
32
  unsigned char code;
33
} scan_table [128] = {
34
/* 0 - 15 */
35
{0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00},
36
{0, 0x0E}, {0, 0x0F}, {0, 0x1C}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00},
37
/* 16 - 31 */
38
{0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00},
39
{0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x01}, {0, 0x00}, {0, 0x00}, {0, 0x00}, {0, 0x00},
40
/* 32 - 47 */
41
{0, 0x39}, {1, 0x02}, {1, 0x28}, {1, 0x04}, {1, 0x05}, {1, 0x06}, {1, 0x08}, {0, 0x28},
42
{1, 0x0A}, {1, 0x0B}, {1, 0x09}, {1, 0x0D}, {0, 0x33}, {0, 0x0C}, {0, 0x34}, {0, 0x35},
43
/* 48 - 63 */
44
{0, 0x0B}, {0, 0x02}, {0, 0x03}, {0, 0x04}, {0, 0x05}, {0, 0x06}, {0, 0x07}, {0, 0x08},
45
{0, 0x09}, {0, 0x0A}, {1, 0x27}, {0, 0x27}, {1, 0x33}, {0, 0x0D}, {1, 0x34}, {1, 0x35},
46
/* 64 - 79 */
47
{1, 0x03}, {1, 0x1E}, {1, 0x30}, {1, 0x2E}, {1, 0x20}, {1, 0x12}, {1, 0x21}, {1, 0x22},
48
{1, 0x23}, {1, 0x17}, {1, 0x24}, {1, 0x25}, {1, 0x26}, {1, 0x32}, {1, 0x31}, {1, 0x18},
49
/* 80 - 95 */
50
{1, 0x19}, {1, 0x10}, {1, 0x13}, {1, 0x1F}, {1, 0x14}, {1, 0x16}, {1, 0x2F}, {1, 0x11},
51
{1, 0x2D}, {1, 0x15}, {1, 0x2C}, {0, 0x1A}, {0, 0x2B}, {0, 0x1B}, {1, 0x07}, {1, 0x0C},
52
/* 96 - 111 */
53
{0, 0x29}, {0, 0x1E}, {0, 0x30}, {0, 0x2E}, {0, 0x20}, {0, 0x12}, {0, 0x21}, {0, 0x22},
54
{0, 0x23}, {0, 0x17}, {0, 0x24}, {0, 0x25}, {0, 0x26}, {0, 0x32}, {0, 0x31}, {0, 0x18},
55
/* 112 - 127 */
56
{0, 0x19}, {0, 0x10}, {0, 0x13}, {0, 0x1F}, {0, 0x14}, {0, 0x16}, {0, 0x2F}, {0, 0x11},
57
{0, 0x2D}, {0, 0x15}, {0, 0x2C}, {1, 0x1A}, {1, 0x2B}, {1, 0x1B}, {1, 0x29}, {0, 0x00}
58
};
59
 
60
/* Temporary buffer to store incoming scan codes */
61
static unsigned char kbd_buf[KBD_MAX_BUF] = {0};
62
 
63
/* Number of scan codes in buffer */
64
static unsigned long kbd_buf_count = 0;
65
static unsigned long kbd_buf_head = 0;
66
static unsigned long kbd_buf_tail = 0;
67
 
68
/* Input stream */
69
static FILE *kbd_rxfs = NULL;
70
 
71
static void kbd_put (unsigned char c)
72
{
73
  if (kbd_buf_count >= KBD_MAX_BUF) {
74
    fprintf (stderr, "WARNING: Keyboard buffer overflow.\n");
75
  } else {
76
    kbd_buf[kbd_buf_head] = c;
77
    kbd_buf_head = (kbd_buf_head + 1) % KBD_MAX_BUF;
78
    kbd_buf_count++;
79
  }
80
}
81
 
82
/* Decodes ascii code c into multiple scan codes, placed into buf, length is returned */
83
static void scan_decode (unsigned char c)
84
{
85
  /* Do not handle special characters and extended ascii */
86
  if (c >= 128 || !scan_table[c].code)
87
    return;
88
 
89
  /* Make shift? */
90
  if (scan_table[c].shift) kbd_put (0x2a);
91
  /* Make char */
92
  kbd_put (scan_table[c].code);
93
  /* Break char */
94
  kbd_put (scan_table[c].code | 0x80);
95
  /* Break shift? */
96
  if (scan_table[c].shift) kbd_put (0xaa);
97
}
98
 
99
/* Write a register */
100
void kbd_write8 (unsigned long addr, unsigned long value)
101
{
102
  int a = (addr - config.kbd.baseaddr);
103
  switch (a) {
104
    case KBD_CTRL:    break;
105
    case KBD_DATA:    break;
106
    default:
107
      fprintf (stderr, "Write out of keyboard space (0x%08x)!\n", addr);
108
      cont_run = 0;
109
      break;
110
  }
111
}
112
 
113
/* Read a register */
114
unsigned long kbd_read8 (unsigned long addr)
115
{
116
  int a = (addr - config.kbd.baseaddr);
117
  switch (a) {
118
    case KBD_CTRL:    return 0; break;
119
    case KBD_DATA:
120
      if (kbd_buf_count) {
121
        unsigned long c = kbd_buf[kbd_buf_tail];
122
        kbd_buf_tail = (kbd_buf_tail + 1) % KBD_MAX_BUF;
123
        kbd_buf_count--;
124
        return c;
125
      }
126
      return 0;
127
    default:
128
      fprintf (stderr, "Read out of keyboard space (0x%08x)!\n", addr);
129
      cont_run = 0;
130
      return 0;
131
  }
132
}
133
 
134
/* Reset all VGAs */
135
void kbd_reset ()
136
{
137
  if (config.kbd.enabled) {
138
    kbd_buf_count = 0;
139
    kbd_buf_head = 0;
140
    kbd_buf_tail = 0;
141
    register_memoryarea(config.kbd.baseaddr, KBD_SPACE, 1, kbd_read8, kbd_write8);
142
 
143
    if (!(kbd_rxfs = fopen(config.kbd.rxfile, "r"))
144
     && !(kbd_rxfs = fopen(config.kbd.rxfile, "r+"))) {
145
      fprintf (stderr, "WARNING: Keyboard has problems with RX file stream.\n");
146
    }
147
  }
148
}
149
 
150
/* Simulation hook. Must be called every clock cycle to simulate incomming data. */
151
void kbd_clock()
152
{
153
  int c;
154
  /* Check if there is something waiting, and decode it into kdb_buf */
155
  if((c = fgetc(kbd_rxfs)) != EOF) {
156
    scan_decode (c);
157
  }
158
  if (kbd_buf_count) report_interrupt(config.kbd.irq);
159
}

powered by: WebSVN 2.1.0

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