Line 66... |
Line 66... |
static unsigned long kbd_buf_tail = 0;
|
static unsigned long kbd_buf_tail = 0;
|
|
|
/* Input stream */
|
/* Input stream */
|
static FILE *kbd_rxfs = NULL;
|
static FILE *kbd_rxfs = NULL;
|
|
|
|
/* Controller Command (write into 0x64) */
|
|
static int kbd_ccmd;
|
|
|
|
/* Keyboard Command (write into 0x60) */
|
|
static unsigned char kbd_kcmd;
|
|
|
|
/* Controller Command Byte */
|
|
static unsigned char kbd_ccmdbyte;
|
|
|
|
/* Keyboard response pending */
|
|
static unsigned long kbd_kresp;
|
|
|
static void kbd_put (unsigned char c)
|
static void kbd_put (unsigned char c)
|
{
|
{
|
if (kbd_buf_count >= KBD_MAX_BUF) {
|
if (kbd_buf_count >= KBD_MAX_BUF) {
|
fprintf (stderr, "WARNING: Keyboard buffer overflow.\n");
|
fprintf (stderr, "WARNING: Keyboard buffer overflow.\n");
|
} else {
|
} else {
|
Line 99... |
Line 111... |
/* Write a register */
|
/* Write a register */
|
void kbd_write8 (unsigned long addr, unsigned long value)
|
void kbd_write8 (unsigned long addr, unsigned long value)
|
{
|
{
|
int a = (addr - config.kbd.baseaddr);
|
int a = (addr - config.kbd.baseaddr);
|
switch (a) {
|
switch (a) {
|
case KBD_CTRL: break;
|
case KBD_CTRL:
|
case KBD_DATA: break;
|
kbd_ccmd = value & 0xff;
|
|
if (kbd_ccmd == KBD_CCMD_RCB)
|
|
kbd_kresp = 0x1;
|
|
if (kbd_ccmd == KBD_CCMD_ST1)
|
|
kbd_kresp = 0x1;
|
|
if (kbd_ccmd == KBD_CCMD_ST2)
|
|
kbd_kresp = 0x1;
|
|
if (kbd_ccmd == KBD_CCMD_DKI)
|
|
kbd_ccmdbyte |= KBD_CCMDBYTE_EN;
|
|
if (kbd_ccmd == KBD_CCMD_EKI)
|
|
kbd_ccmdbyte &= ~KBD_CCMDBYTE_EN;
|
|
if (config.sim.verbose)
|
|
printf("kbd_write8(%x) %x\n", addr, value);
|
|
break;
|
|
case KBD_DATA:
|
|
if (kbd_ccmd == KBD_CCMD_WCB) {
|
|
kbd_ccmdbyte = value & 0xff;
|
|
kbd_ccmd = 0x00;
|
|
} else
|
|
kbd_kcmd = value & 0xff;
|
|
if (kbd_kcmd == KBD_KCMD_DK)
|
|
kbd_ccmdbyte |= KBD_CCMDBYTE_EN;
|
|
if (kbd_kcmd == KBD_KCMD_EK)
|
|
kbd_ccmdbyte &= ~KBD_CCMDBYTE_EN;
|
|
kbd_kresp = 0x1;
|
|
kbd_ccmd = 0x00;
|
|
if (config.sim.verbose)
|
|
printf("kbd_write8(%x) %x\n", addr, value);
|
|
break;
|
default:
|
default:
|
fprintf (stderr, "Write out of keyboard space (0x%08x)!\n", addr);
|
fprintf (stderr, "Write out of keyboard space (0x%08x)!\n", addr);
|
cont_run = 0;
|
cont_run = 0;
|
break;
|
break;
|
}
|
}
|
Line 113... |
Line 153... |
/* Read a register */
|
/* Read a register */
|
unsigned long kbd_read8 (unsigned long addr)
|
unsigned long kbd_read8 (unsigned long addr)
|
{
|
{
|
int a = (addr - config.kbd.baseaddr);
|
int a = (addr - config.kbd.baseaddr);
|
switch (a) {
|
switch (a) {
|
case KBD_CTRL: return 0; break;
|
case KBD_CTRL: {
|
|
unsigned long c = 0x0;
|
|
if (kbd_kresp || kbd_buf_count)
|
|
c |= KBD_STATUS_OBF;
|
|
c |= kbd_ccmdbyte & KBD_CCMDBYTE_SYS;
|
|
c |= KBD_STATUS_INH;
|
|
if (config.sim.verbose)
|
|
printf("kbd_read8(%x) %x\n", addr, c);
|
|
return c;
|
|
}
|
case KBD_DATA:
|
case KBD_DATA:
|
if (kbd_buf_count) {
|
if (kbd_ccmd) {
|
|
unsigned long rc;
|
|
if (kbd_ccmd == KBD_CCMD_RCB)
|
|
rc = kbd_ccmdbyte;
|
|
if (kbd_ccmd == KBD_CCMD_ST1)
|
|
rc = 0x55;
|
|
if (kbd_ccmd == KBD_CCMD_ST2)
|
|
rc = 0x00;
|
|
kbd_ccmd = 0x00;
|
|
kbd_kresp = 0x0;
|
|
if (config.sim.verbose)
|
|
printf("kbd_read8(%x) %x\n", addr, rc);
|
|
return rc;
|
|
}
|
|
else if (kbd_kresp) {
|
|
unsigned long rc;
|
|
if (kbd_kresp == 0x2) {
|
|
kbd_kresp = 0x0;
|
|
rc = KBD_KRESP_RSTOK;
|
|
} else if (kbd_kcmd == KBD_KCMD_RST) {
|
|
kbd_kresp = 0x2;
|
|
rc = KBD_KRESP_ACK;
|
|
} else if (kbd_kcmd == KBD_KCMD_ECHO) {
|
|
kbd_kresp = 0x0;
|
|
rc = KBD_KRESP_ECHO;
|
|
} else {
|
|
kbd_kresp = 0x0;
|
|
rc = KBD_KRESP_ACK;
|
|
}
|
|
kbd_kcmd = 0x00;
|
|
if (config.sim.verbose)
|
|
printf("kbd_read8(%x) %x\n", addr, rc);
|
|
return rc;
|
|
} else if (kbd_buf_count) {
|
unsigned long c = kbd_buf[kbd_buf_tail];
|
unsigned long c = kbd_buf[kbd_buf_tail];
|
kbd_buf_tail = (kbd_buf_tail + 1) % KBD_MAX_BUF;
|
kbd_buf_tail = (kbd_buf_tail + 1) % KBD_MAX_BUF;
|
kbd_buf_count--;
|
kbd_buf_count--;
|
|
kbd_kresp = 0x0;
|
|
if (config.sim.verbose)
|
|
printf("kbd_read8(%x) %x\n", addr, c);
|
return c;
|
return c;
|
}
|
}
|
|
kbd_kresp = 0x0;
|
|
if (config.sim.verbose)
|
|
printf("kbd_read8(%x) fifo empty\n", addr);
|
return 0;
|
return 0;
|
default:
|
default:
|
fprintf (stderr, "Read out of keyboard space (0x%08x)!\n", addr);
|
fprintf (stderr, "Read out of keyboard space (0x%08x)!\n", addr);
|
cont_run = 0;
|
cont_run = 0;
|
return 0;
|
return 0;
|
Line 136... |
Line 224... |
{
|
{
|
if (config.kbd.enabled) {
|
if (config.kbd.enabled) {
|
kbd_buf_count = 0;
|
kbd_buf_count = 0;
|
kbd_buf_head = 0;
|
kbd_buf_head = 0;
|
kbd_buf_tail = 0;
|
kbd_buf_tail = 0;
|
|
kbd_kresp = 0x0;
|
|
kbd_ccmdbyte = 0x65; /* We reset into default normal operation. */
|
register_memoryarea(config.kbd.baseaddr, KBD_SPACE, 1, kbd_read8, kbd_write8);
|
register_memoryarea(config.kbd.baseaddr, KBD_SPACE, 1, kbd_read8, kbd_write8);
|
|
|
if (!(kbd_rxfs = fopen(config.kbd.rxfile, "r"))
|
if (!(kbd_rxfs = fopen(config.kbd.rxfile, "r"))
|
&& !(kbd_rxfs = fopen(config.kbd.rxfile, "r+"))) {
|
&& !(kbd_rxfs = fopen(config.kbd.rxfile, "r+"))) {
|
fprintf (stderr, "WARNING: Keyboard has problems with RX file stream.\n");
|
fprintf (stderr, "WARNING: Keyboard has problems with RX file stream.\n");
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
|
void kbd_info()
|
|
{
|
|
printf("kbd_kcmd: %x\n", kbd_kcmd);
|
|
printf("kbd_ccmd: %x\n", kbd_ccmd);
|
|
printf("kbd_ccmdbyte: %x\n", kbd_ccmdbyte);
|
|
printf("kbd_kresp: %x\n", kbd_kresp);
|
|
printf("kbd_buf_count: %x\n", kbd_buf_count);
|
|
}
|
|
|
/* Simulation hook. Must be called every clock cycle to simulate incomming data. */
|
/* Simulation hook. Must be called every clock cycle to simulate incomming data. */
|
void kbd_clock()
|
void kbd_clock()
|
{
|
{
|
int c;
|
int c;
|
|
int kbd_int = 0;
|
/* Check if there is something waiting, and decode it into kdb_buf */
|
/* Check if there is something waiting, and decode it into kdb_buf */
|
if((c = fgetc(kbd_rxfs)) != EOF) {
|
if((c = fgetc(kbd_rxfs)) != EOF) {
|
scan_decode (c);
|
scan_decode (c);
|
}
|
}
|
if (kbd_buf_count) report_interrupt(config.kbd.irq);
|
kbd_int = kbd_kresp || kbd_buf_count;
|
|
kbd_int = kbd_kresp || kbd_buf_count ? kbd_ccmdbyte & KBD_CCMDBYTE_INT : 0;
|
|
if (config.sim.verbose && kbd_int)
|
|
printf("Keyboard Interrupt.... kbd_kresp %x kbd_buf_count %x \n", kbd_kresp, kbd_buf_count);
|
|
if (kbd_int) report_interrupt(config.kbd.irq);
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|