Added extra codes from miniterm_mpy.py and finalised setconsolemode shenanigans.
diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py
index 83d8dbd..a113db3 100644
--- a/serial/tools/miniterm.py
+++ b/serial/tools/miniterm.py
@@ -88,7 +88,6 @@
 if os.name == 'nt':  # noqa
     import msvcrt
     import ctypes
-    import ctypes.wintypes as wintypes
     import platform
 
     class Out(object):
@@ -104,28 +103,51 @@
             os.write(self.fd, s)
 
     class Console(ConsoleBase):
-        nav = {
+        fncodes = {
+            ';': '\1bOP',  # F1
+            '<': '\1bOQ',  # F2
+            '=': '\1bOR',  # F3
+            '>': '\1bOS',  # F4
+            '?': '\1b[15~',  # F5
+            '@': '\1b[17~',  # F6
+            'A': '\1b[18~',  # F7
+            'B': '\1b[19~',  # F8
+            'C': '\1b[20~',  # F9
+            'D': '\1b[21~',  # F10
+        }
+        navcodes = {
             'H': '\x1b[A',  # UP
             'P': '\x1b[B',  # DOWN
             'K': '\x1b[D',  # LEFT
             'M': '\x1b[C',  # RIGHT
             'G': '\x1b[H',  # HOME
             'O': '\x1b[F',  # END
+            'R': '\x1b[2~',  # INSERT
+            'S': '\x1b[3~',  # DELETE
+            'I': '\x1b[5~',  # PGUP
+            'Q': '\x1b[6~',  # PGDN        
         }
         
         def __init__(self):
             super(Console, self).__init__()
-            if not hasattr(wintypes, 'LPDWORD'): # PY2
-                wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
-            self._saved_cm = mode = wintypes.DWORD()
-            ctypes.windll.kernel32.GetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), ctypes.byref(self._saved_cm))
             self._saved_ocp = ctypes.windll.kernel32.GetConsoleOutputCP()
             self._saved_icp = ctypes.windll.kernel32.GetConsoleCP()
             ctypes.windll.kernel32.SetConsoleOutputCP(65001)
             ctypes.windll.kernel32.SetConsoleCP(65001)
-            # ANSI handling available through SetConsoleMode since v1511
+            # ANSI handling available through SetConsoleMode since v1511 https://en.wikipedia.org/wiki/ANSI_escape_code#cite_note-win10th2-1
             if platform.release() == '10' and int(platform.version().split('.')[2]) > 10586:
-                ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), 0x7)
+                ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
+                import ctypes.wintypes as wintypes
+                if not hasattr(wintypes, 'LPDWORD'): # PY2
+                    wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
+                SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode
+                GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode
+                GetStdHandle = ctypes.windll.kernel32.GetStdHandle
+                mode = wintypes.DWORD()
+                GetConsoleMode(GetStdHandle(-11), ctypes.byref(mode))
+                if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0:
+                    SetConsoleMode(GetStdHandle(-11), mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+                    self._saved_cm = mode
             self.output = codecs.getwriter('UTF-8')(Out(sys.stdout.fileno()), 'replace')
             # the change of the code page is not propagated to Python, manually fix it
             sys.stderr = codecs.getwriter('UTF-8')(Out(sys.stderr.fileno()), 'replace')
@@ -135,19 +157,23 @@
         def __del__(self):
             ctypes.windll.kernel32.SetConsoleOutputCP(self._saved_ocp)
             ctypes.windll.kernel32.SetConsoleCP(self._saved_icp)
-            ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), self._saved_cm)
+            try:
+                ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), self._saved_cm)
+            except AttributeError: # in case no _saved_cm
+                pass
 
         def getkey(self):
             while True:
                 z = msvcrt.getwch()
                 if z == unichr(13):
                     return unichr(10)
-                elif z in unichr(0):    # functions keys, ignore
-                    msvcrt.getwch()
-                elif z in unichr(0xe0):    # map special keys
-                    code = msvcrt.getwch()
+                elif z is unichr(0) or z is unichr(0xe0):
                     try:
-                        return self.nav[code]
+                        code = msvcrt.getwch()
+                        if z is unichr(0):
+                            return self.fncodes[code]
+                        else:
+                            return self.navcodes[code]
                     except KeyError:
                         pass
                 else: