From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bJ2qy-0006Tm-Fd for qemu-devel@nongnu.org; Fri, 01 Jul 2016 14:07:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bJ2qu-0006gw-Od for qemu-devel@nongnu.org; Fri, 01 Jul 2016 14:07:47 -0400 Received: from mail-qk0-x243.google.com ([2607:f8b0:400d:c09::243]:35927) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bJ2qu-0006gs-JO for qemu-devel@nongnu.org; Fri, 01 Jul 2016 14:07:44 -0400 Received: by mail-qk0-x243.google.com with SMTP id r68so22474928qka.3 for ; Fri, 01 Jul 2016 11:07:44 -0700 (PDT) Date: Fri, 1 Jul 2016 14:07:41 -0400 From: Kevin O'Connor Message-ID: <20160701180741.GA24801@morn.lan> References: <1467370471-20554-1-git-send-email-kraxel@redhat.com> <1467370471-20554-3-git-send-email-kraxel@redhat.com> <20160701170739.GB11200@morn.lan> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160701170739.GB11200@morn.lan> Subject: Re: [Qemu-devel] [SeaBIOS] [RFC PATCH 2/2] serial console, input List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann Cc: seabios@seabios.org, qemu-devel@nongnu.org On Fri, Jul 01, 2016 at 01:07:39PM -0400, Kevin O'Connor wrote: > If I understand correctly, most keys are sent on the serial port as > single bytes, but there are a few keys that are sent as multi-byte > sequences. There's a lot of complexity to implement buffering for > that unusual case. I wonder if the buffer could be avoided - I played > with it a little and came up with the below (totally untested). I'm > not sure if it's an improvement. The version below might be slightly easier to understand (still totally untested). -Kevin u8 multibyte_read_count VARLOW; u8 multibyte_read_pos VARLOW; void sercon_check_event(void) { u16 addr = GET_LOW(sercon_port); ... // read and process data int readdata = 0; while (inb(addr + SEROFF_LSR) & 0x01) { u8 byte = inb(addr + SEROFF_DATA); readdata = 1; int ret = sercon_check_multibyte(byte); if (ret) // byte part of multi-byte sequence continue; if (byte == 0x1b) { // Start multi-byte sequence check SET_LOW(multibyte_read_count, 1); continue; } // Send normal key sercon_sendkey(GET_LOW(termchr[chr].scancode), GET_LOW(termchr[chr].flags)); } if (!readdata && GET_LOW(multibyte_read_count)) // Too long to read multi-byte sequence - must flush dump_multibyte_sequence(); } static int sercon_check_multibyte(u8 byte) { int mb_count = GET_LOW(multibyte_read_count); if (!mb_count) // Not in a multi-byte sequence return 0; int mb_pos = GET_LOW(multibyte_read_pos); while (GET_GLOBAL(termseq[mb_pos].seq[mb_count-1]) != byte) { // Byte didn't match this sequence - find a sequence that does mb_pos++; if (mb_pos >= ARRAY_SIZE(termseq) || memcmp_far(GLOBAL_SEG, termseq[mb_pos-1].seq , GLOBAL_SEG, termseq[mb_pos].seq, mb_count-1) != 0) // No match - must flush previusly queued keys dump_multibyte_sequence(); return 0; } } mb_count++; if (!GET_GLOBAL(termseq[mb_pos].seq[mb_count-1])) { // sequence complete - send key sercon_sendkey(GET_GLOBAL(termseq[seq].scancode), 0); mb_count = mb_pos = 0; } SET_LOW(multibyte_read_count, mb_count); SET_LOW(multibyte_read_pos, mb_pos); return 1; } static void dump_multibyte_sequence(void) { sercon_sendkey(GET_LOW(termchr[0x1b].scancode), GET_LOW(termchr[0x1b].flags)); int i, mb_count = GET_LOW(multibyte_read_count); for (i=0; i