zxdiv,tty: optimize interrupt path
authorAlan Cox <alan@linux.intel.com>
Mon, 26 Nov 2018 12:13:22 +0000 (12:13 +0000)
committerAlan Cox <alan@linux.intel.com>
Mon, 26 Nov 2018 12:13:22 +0000 (12:13 +0000)
This saves us a lot of clocks of pointless processing if no keyboard line
changed state.

Kernel/platform-zxdiv/devtty.c

index f1f2dbf..77b2b01 100644 (file)
@@ -113,24 +113,34 @@ void tty_data_consumed(uint8_t minor)
 {
 }
 
-void update_keyboard(void)
+static uint8_t update_keyboard(void) __naked
 {
-       /* We need this assembler code because it is much faster, of course  */
-       /* TODO: make it naked? */
+       /*
+        *      This is run 50 time a second so we do it in asm and also return
+        *      0 if nothing changed. That allows us to avoid the main tty
+        *      processing on most interrupt events which saves us a lot of
+        *      clocks.
+        */
        __asm
                ld hl,#_keybuf
                ld c, #0xFE
                ld b, #0x7f
-               ld e, #8        ; 8 keyboard ports, 7FFE, BFFE, DFFE and so on
+               ld de, #8        ; 8 keyboard ports, 7FFE, BFFE, DFFE and so on
+                                ; D to 0 for no change found
        read_halfrow:
                in a, (c)
-;              and #0
                cpl
-               ld(hl), a
+               cp (hl)
+               jr z,nochange
+               inc d           ; there 8 ports so we cannot overflow
+               ld (hl), a
+       nochange:
                rrc b
                inc hl
                dec e
                jr nz, read_halfrow
+               ld l,d
+               ret
        __endasm;
 }
 
@@ -138,10 +148,12 @@ void tty_pollirq(void)
 {
        int i;
 
-       update_keyboard();
-
        newkey = 0;
 
+       /* Nothing changed - no processing required */
+       if (!update_keyboard())
+               return;
+
        for (i = 0; i < 8; i++) {
                int n;
                uint8_t key = keybuf[i] ^ keymap[i];