diff options
Diffstat (limited to 'qemu/roms/qemu-palcode/console.c')
-rw-r--r-- | qemu/roms/qemu-palcode/console.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/qemu/roms/qemu-palcode/console.c b/qemu/roms/qemu-palcode/console.c new file mode 100644 index 000000000..382cf54d4 --- /dev/null +++ b/qemu/roms/qemu-palcode/console.c @@ -0,0 +1,145 @@ +/* The SRM console prompt. + + Copyright (C) 2011 Richard Henderson + + This file is part of QEMU PALcode. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the text + of the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not see + <http://www.gnu.org/licenses/>. */ + +#include "protos.h" +#include "console.h" +#include "vgatables.h" + + +static void +output_crnl(void) +{ + crb_puts(0, "\r\n", 2); +} + +static void +output_bell(void) +{ + crb_puts(0, "\a", 1); +} + +static void +backspace_and_erase(void) +{ + crb_puts(0, "\b \b", 3); +} + +static unsigned long +getline(char *buf, unsigned long bufsize) +{ + unsigned long len = 0; + long c; + + while (1) + { + c = crb_getc(0); + if (c < 0) + continue; + switch ((int)c) + { + case '\r': + case '\n': + output_crnl(); + buf[len] = 0; + return len; + + case '\b': + case 0x7f: /* Delete */ + if (len > 0) + { + backspace_and_erase(); + len--; + } + else + output_bell(); + break; + + default: + if (len + 1 < bufsize) + { + buf[len] = c; + crb_puts(0, buf+len, 1); + len++; + } + else + output_bell(); + break; + } + } +} + +static inline void set_console_alarm(void) +{ + /* Just set a new timeout for 10ms = 10M ns. */ + set_alarm_rel(10 * 1000 * 1000); +} + +void +do_entInt(unsigned long type, unsigned long vector) +{ + switch (type) + { + case 0: + /* ??? SMP interrupt. We're going to need this for starting up + secondary cpus. */ + break; + case 1: + /* Timer interrupt. */ + set_console_alarm(); + break; + case 2: + /* ??? Device interrupt. We're going to need this for virtio disk + operations at minimum. */ + break; + } +} + +void +do_console(void) +{ + char line[256]; + unsigned long len; + + wrkgp(); + wrent(entInt, 0); + set_console_alarm(); + swpipl(0); + + if (have_vga) + { + unsigned short *vga, attr; + vga = pci_mem_base + SEG_CTEXT *16; + attr = 0x2000; + vga[0] = 'H' + attr; + vga[1] = 'e' + attr; + vga[2] = 'l' + attr; + vga[3] = 'l' + attr; + vga[4] = 'o' + attr; + } + + while (1) + { + crb_puts(0, ">>> ", 4); + len = getline(line, sizeof(line)); + crb_puts(0, "got: ", 5); + crb_puts(0, line, len); + output_crnl(); + } +} |