diff options
-rw-r--r-- | sys/conf/files.pc98 | 1 | ||||
-rw-r--r-- | sys/conf/options.pc98 | 9 | ||||
-rw-r--r-- | sys/pc98/conf/files.pc98 | 1 | ||||
-rw-r--r-- | sys/pc98/conf/options.pc98 | 9 | ||||
-rw-r--r-- | sys/pc98/pc98/if_fe.c | 150 | ||||
-rw-r--r-- | sys/pc98/pc98/syscons.c | 232 | ||||
-rw-r--r-- | sys/pc98/pc98/syscons.h | 2 |
7 files changed, 306 insertions, 98 deletions
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index b82024f..57c71c9 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -125,6 +125,7 @@ pc98/isa/istallion.c optional stli device-driver pc98/isa/joy.c optional joy device-driver i386/isa/kbdio.c optional psm device-driver i386/isa/kbdio.c optional sc device-driver +i386/isa/kbdio.c optional vt device-driver pc98/pc98/labpc.c optional labpc device-driver pc98/pc98/lpt.c optional lpt device-driver pc98/pc98/mcd.c optional mcd device-driver diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98 index 0b6aaab..6421e58 100644 --- a/sys/conf/options.pc98 +++ b/sys/conf/options.pc98 @@ -46,6 +46,15 @@ SC_SPLASH_SCREEN opt_syscons.h MAXCONS opt_syscons.h SLOW_VGA opt_syscons.h +PSM_ACCEL opt_psm.h +PSM_EMULATION opt_psm.h +PSM_CHECKSYNC opt_psm.h +PSM_DEBUG opt_psm.h + +KBD_RESETDELAY opt_kbdio.h +KBD_MAXWAIT opt_kbdio.h +KBDIO_DEBUG opt_kbdio.h + ATAPI opt_atapi.h ATAPI_STATIC opt_atapi.h diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98 index b82024f..57c71c9 100644 --- a/sys/pc98/conf/files.pc98 +++ b/sys/pc98/conf/files.pc98 @@ -125,6 +125,7 @@ pc98/isa/istallion.c optional stli device-driver pc98/isa/joy.c optional joy device-driver i386/isa/kbdio.c optional psm device-driver i386/isa/kbdio.c optional sc device-driver +i386/isa/kbdio.c optional vt device-driver pc98/pc98/labpc.c optional labpc device-driver pc98/pc98/lpt.c optional lpt device-driver pc98/pc98/mcd.c optional mcd device-driver diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98 index 0b6aaab..6421e58 100644 --- a/sys/pc98/conf/options.pc98 +++ b/sys/pc98/conf/options.pc98 @@ -46,6 +46,15 @@ SC_SPLASH_SCREEN opt_syscons.h MAXCONS opt_syscons.h SLOW_VGA opt_syscons.h +PSM_ACCEL opt_psm.h +PSM_EMULATION opt_psm.h +PSM_CHECKSYNC opt_psm.h +PSM_DEBUG opt_psm.h + +KBD_RESETDELAY opt_kbdio.h +KBD_MAXWAIT opt_kbdio.h +KBDIO_DEBUG opt_kbdio.h + ATAPI opt_atapi.h ATAPI_STATIC opt_atapi.h diff --git a/sys/pc98/pc98/if_fe.c b/sys/pc98/pc98/if_fe.c index 9981c91..85d1808 100644 --- a/sys/pc98/pc98/if_fe.c +++ b/sys/pc98/pc98/if_fe.c @@ -394,9 +394,24 @@ feinit(struct pccard_dev *dp, int first) #if FE_DEBUG >= 2 printf("Start Probe\n"); #endif + /* Initialize "minimum" parts of our softc. */ sc = &fe_softc[dp->isahd.id_unit]; - memcpy( sc->sc_enaddr, dp->misc, ETHER_ADDR_LEN ); - if (fe_probe(&dp->isahd) == 0) + sc->sc_unit = dp->isahd.id_unit; + sc->iobase = dp->isahd.id_iobase; + + /* Use Ethernet address got from CIS, if one is available. */ + if ((dp->misc[0] & 0x03) == 0x00 + && (dp->misc[0] | dp->misc[1] | dp->misc[2]) != 0) { + /* Yes, it looks like a valid Ether address. */ + bcopy(dp->misc, sc->sc_enaddr, ETHER_ADDR_LEN); + } else { + /* Indicate we have no Ether address in CIS. */ + bzero(sc->sc_enaddr, ETHER_ADDR_LEN); + } + + /* Probe supported PC card models. */ + if (fe_probe_tdk(&dp->isahd, sc) == 0 + && fe_probe_mbh(&dp->isahd, sc) == 0) return (ENXIO); #if FE_DEBUG >= 2 printf("Start attach\n"); @@ -477,11 +492,8 @@ static struct fe_probe_list const fe_probe_list [] = #else { fe_probe_fmv, fe_fmv_addr }, { fe_probe_ati, fe_ati_addr }, -#if NCRD > 0 - { fe_probe_mbh, NULL }, /* PCMCIAs cannot be auto-detected. */ - { fe_probe_tdk, NULL }, -#endif #endif + { fe_probe_gwy, NULL }, /* GWYs cannot be auto detected. */ { NULL, NULL } }; @@ -1435,7 +1447,7 @@ fe_probe_gwy ( DEVICE * dev, struct fe_softc * sc ) { FE_DLCR2, 0x70, 0x00 }, { FE_DLCR4, 0x08, 0x00 }, { FE_DLCR7, 0xC0, 0x00 }, - /* + /* * Test *vendor* part of the address for Gateway. * This test is essential to identify Gateway's cards. * We shuld define some symbolic names for the @@ -1505,7 +1517,7 @@ fe_probe_gwy ( DEVICE * dev, struct fe_softc * sc ) } #if NCRD > 0 - /* +/* * Probe and initialization for Fujitsu MBH10302 PCMCIA Ethernet interface. * Note that this is for 10302 only; MBH10304 is handled by fe_probe_tdk(). */ @@ -1647,8 +1659,8 @@ fe_init_mbh ( struct fe_softc * sc ) * (Contec uses TDK Ethenet chip -- hosokawa) * * This version of fe_probe_tdk has been rewrote to handle - * *generic* PC card implementation of Fujitsu MB8696x family. The - * name _tdk is just for a historical reason. :-) + * *generic* PC card implementation of Fujitsu MB8696x and compatibles. + * The name _tdk is just for a historical reason. <seki> :-) */ static int fe_probe_tdk ( DEVICE * dev, struct fe_softc * sc ) @@ -1662,13 +1674,25 @@ fe_probe_tdk ( DEVICE * dev, struct fe_softc * sc ) { 0 } }; + /* We need an IRQ. */ if ( dev->id_irq == NO_IRQ ) { return ( 0 ); } - /* Setup an I/O address mapping table. */ - for ( i = 0; i < MAXREGISTERS; i++ ) { - sc->ioaddr[ i ] = sc->iobase + i; + /* Generic driver needs Ethernet address taken from CIS. */ + if (sc->arpcom.ac_enaddr[0] == 0 + && sc->arpcom.ac_enaddr[1] == 0 + && sc->arpcom.ac_enaddr[2] == 0) { + return 0; + } + + /* Setup an I/O address mapping table; we need only 16 ports. */ + for (i = 0; i < 16; i++) { + sc->ioaddr[i] = sc->iobase + i; + } + /* Fill unused slots with a safe address. */ + for (i = 16; i < MAXREGISTERS; i++) { + sc->ioaddr[i] = sc->iobase; } /* @@ -1717,8 +1741,17 @@ fe_probe_tdk ( DEVICE * dev, struct fe_softc * sc ) /* * That's all. C-NET(PC)C occupies 16 I/O addresses. - * XXX: Are there any card with 32 I/O addresses? FIXME. - */ + * + * Some PC cards (e.g., TDK and Contec) have 16 I/O addresses, + * while some others (e.g., Fujitsu) have 32. Fortunately, + * this generic driver never accesses latter 16 ports in 32 + * ports cards. So, we can assume the *generic* PC cards + * always have 16 ports. + * + * Moreover, PC card probe is isolated from ISA probe, and PC + * card probe routine doesn't use "# of ports" returned by this + * function. 16 v.s. 32 is not important now. + */ return 16; } #endif @@ -2348,7 +2381,7 @@ fe_emptybuffer ( struct fe_softc * sc ) int i; u_char saved_dlcr5; -#if FE_DEBUG >= 1 +#if FE_DEBUG >= 2 log( LOG_WARNING, "fe%d: emptying receive buffer", sc->sc_unit ); #endif /* @@ -2356,12 +2389,14 @@ fe_emptybuffer ( struct fe_softc * sc ) */ saved_dlcr5 = inb( sc->ioaddr[ FE_DLCR5 ] ); outb( sc->ioaddr[ FE_DLCR5 ], sc->proto_dlcr5 ); + DELAY(1300); /* * When we come here, the receive buffer management should * have been broken. So, we cannot use skip operation. + * Just discard everything in the buffer. */ - for ( i = 0; i < sc->txb_size; i += 2 ) { + for (i = 0; i < 32768; i++) { if ( inb( sc->ioaddr[ FE_DLCR5 ] ) & FE_D5_BUFEMP ) break; ( void )inw( sc->ioaddr[ FE_BMPR8 ] ); } @@ -2529,7 +2564,7 @@ fe_rint ( struct fe_softc * sc, u_char rstat ) */ if ( rstat & ( FE_D1_OVRFLO | FE_D1_CRCERR | FE_D1_ALGERR | FE_D1_SRTPKT ) ) { -#if FE_DEBUG >= 3 +#if FE_DEBUG >= 2 log( LOG_WARNING, "fe%d: receive error: %s%s%s%s(%02x)\n", sc->sc_unit, @@ -2548,11 +2583,9 @@ fe_rint ( struct fe_softc * sc, u_char rstat ) * packets. * * We limit the number of iterations to avoid infinite-loop. - * It can be caused by a very slow CPU (some broken - * peripheral may insert incredible number of wait cycles) - * or, worse, by a broken MB86960 chip. + * The upper bound is set to unrealistic high value. */ - for ( i = 0; i < FE_MAX_RECV_COUNT; i++ ) { + for (i = 0; i < FE_MAX_RECV_COUNT * 2; i++) { /* Stop the iteration if 86960 indicates no packets. */ if ( inb( sc->ioaddr[ FE_DLCR5 ] ) & FE_D5_BUFEMP ) break; @@ -2576,19 +2609,25 @@ fe_rint ( struct fe_softc * sc, u_char rstat ) */ len = inw( sc->ioaddr[ FE_BMPR8 ] ); +#if FE_DEBUG >= 1 /* - * If there was an error, update statistics and drop - * the packet, unless the interface is in promiscuous - * mode. + * If there was an error with the received packet, it + * must be an indication of out-of-sync on receive + * buffer, because we have programmed the 8696x to + * to discard errored packets, even when the interface + * is in promiscuous mode. We have to re-synchronize. */ - if ( ( status & 0xF0 ) != 0x20 ) { - if ( !( sc->sc_if.if_flags & IFF_PROMISC ) ) { - sc->sc_if.if_ierrors++; - fe_droppacket( sc, len ); - continue; - } + if (!(status & FE_RPH_GOOD)) { + log(LOG_ERR, + "fe%d: corrupted receive status byte (%02x)\n", + sc->arpcom.ac_if.if_unit, status); + sc->arpcom.ac_if.if_ierrors++; + fe_emptybuffer( sc ); + break; } +#endif +#if FE_DEBUG >= 1 /* * MB86960 checks the packet length and drop big packet * before passing it to us. There are no chance we can @@ -2602,38 +2641,40 @@ fe_rint ( struct fe_softc * sc, u_char rstat ) */ if ( len > ETHER_MAX_LEN - ETHER_CRC_LEN || len < ETHER_MIN_LEN - ETHER_CRC_LEN ) { -#if FE_DEBUG >= 1 log( LOG_WARNING, "fe%d: received a %s packet? (%u bytes)\n", sc->sc_unit, len < ETHER_MIN_LEN - ETHER_CRC_LEN ? "partial" : "big", len ); -#endif sc->sc_if.if_ierrors++; fe_emptybuffer( sc ); - continue; + break; } +#endif /* * Go get a packet. */ if ( fe_get_packet( sc, len ) < 0 ) { - /* Skip a packet, updating statistics. */ + #if FE_DEBUG >= 2 log( LOG_WARNING, "%s%d: out of mbuf;" " dropping a packet (%u bytes)\n", sc->sc_unit, len ); #endif + + /* Skip a packet, updating statistics. */ sc->sc_if.if_ierrors++; fe_droppacket( sc, len ); /* - * We stop receiving packets, even if there are - * more in the buffer. We hope we can get more - * mbuf next time. + * Try extracting other packets, although they will + * cause out-of-mbuf error again. This is required + * to keep receiver interrupt comming. + * (Earlier versions had a bug on this point.) */ - return; + continue; } /* Successfully received a packet. Update stat. */ @@ -2664,6 +2705,26 @@ feintr ( int unit ) */ tstat = inb( sc->ioaddr[ FE_DLCR0 ] ) & FE_TMASK; rstat = inb( sc->ioaddr[ FE_DLCR1 ] ) & FE_RMASK; + +#if FE_DEBUG >= 1 + /* Test for a "dead-lock" condition. */ + if ((rstat & FE_D1_PKTRDY) == 0 + && (inb(sc->ioaddr[FE_DLCR5]) & FE_D5_BUFEMP) == 0 + && (inb(sc->ioaddr[FE_DLCR1]) & FE_D1_PKTRDY) == 0) { + /* + * PKTRDY is off, while receive buffer is not empty. + * We did a double check to avoid a race condition... + * So, we should have missed an interrupt. + */ + log(LOG_WARNING, + "fe%d: missed a receiver interrupt?\n", + sc->arpcom.ac_if.if_unit); + /* Simulate the missed interrupt condition. */ + rstat |= FE_D1_PKTRDY; + } +#endif + + /* Stop processing if there are no interrupts to handle. */ if ( tstat == 0 && rstat == 0 ) break; /* @@ -3079,20 +3140,23 @@ fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m ) static u_char padding [ ETHER_MIN_LEN - ETHER_CRC_LEN - ETHER_HDR_LEN ]; -#if FE_DEBUG >= 2 +#if FE_DEBUG >= 1 /* First, count up the total number of bytes to copy */ length = 0; for ( mp = m; mp != NULL; mp = mp->m_next ) { length += mp->m_len; } +#else + /* Just use the length value in the packet header. */ + length = m->m_pkthdr.len; +#endif + +#if FE_DEBUG >= 2 /* Check if this matches the one in the packet header. */ if ( length != m->m_pkthdr.len ) { log( LOG_WARNING, "fe%d: packet length mismatch? (%d/%d)\n", sc->sc_unit, length, m->m_pkthdr.len ); } -#else - /* Just use the length value in the packet header. */ - length = m->m_pkthdr.len; #endif #if FE_DEBUG >= 1 diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index 6d171bc..f81d6e4 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -124,6 +124,7 @@ static term_stat kernel_console; static default_attr *current_default; static int flags = 0; static int sc_port = IO_KBD; +static KBDC sc_kbdc = NULL; static char init_done = COLD; static u_short sc_buffer[ROW*COL]; static char switch_in_progress = FALSE; @@ -140,9 +141,6 @@ static u_char nlkcnt = 0, slkcnt = 0, alkcnt = 0; #else static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0; #endif - char *font_8 = NULL, *font_14 = NULL, *font_16 = NULL; - int fonts_loaded = 0; - char *palette; static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ @@ -151,6 +149,11 @@ static long scrn_time_stamp; u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; + int fonts_loaded = 0; + char font_8[256*8]; + char font_14[256*14]; + char font_16[256*16]; + char palette[256*3]; static char *cut_buffer; static u_short mouse_and_mask[16] = { 0xc000, 0xe000, 0xf000, 0xf800, @@ -232,6 +235,7 @@ static void history_to_screen(scr_stat *scp); static int history_up_line(scr_stat *scp); static int history_down_line(scr_stat *scp); static int mask2attr(struct term_stat *term); +static void set_keyboard(int command, int data); static void update_leds(int which); static void set_vgaregs(char *modetable); static void set_font_mode(void); @@ -393,30 +397,37 @@ scprobe(struct isa_device *dev) { #ifdef PC98 sc_port = dev->id_iobase; + sc_kbdc = kbdc_open(sc_port); return(16); #else - int c; + int codeset; + int c = -1; + int m; sc_port = dev->id_iobase; + sc_kbdc = kbdc_open(sc_port); + + if (!kbdc_lock(sc_kbdc, TRUE)) { + /* driver error? */ + printf("sc%d: unable to lock the controller.\n", dev->id_unit); + return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE); + } /* discard anything left after UserConfig */ - empty_both_buffers(sc_port, 10); + empty_both_buffers(sc_kbdc, 10); /* save the current keyboard controller command byte */ - c = -1; - if (!write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE)) { - /* CONTROLLER ERROR */ - printf("sc%d: unable to get the current command byte value.\n", - dev->id_unit); - goto fail; - } - c = read_controller_data(sc_port); + m = kbdc_get_device_mask(sc_kbdc) & ~KBD_KBD_CONTROL_BITS; + c = get_controller_command_byte(sc_kbdc); if (c == -1) { /* CONTROLLER ERROR */ printf("sc%d: unable to get the current command byte value.\n", dev->id_unit); goto fail; } + if (bootverbose) + printf("sc%d: the current keyboard controller command byte %04x\n", + dev->id_unit, c); #if 0 /* override the keyboard lock switch */ c |= KBD_OVERRIDE_KBD_LOCK; @@ -426,19 +437,40 @@ scprobe(struct isa_device *dev) * enable the keyboard port, but disable the keyboard intr. * the aux port (mouse port) is disabled too. */ - if (!set_controller_command_byte(sc_port, - c & ~(KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS), + if (!set_controller_command_byte(sc_kbdc, + KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS, KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT - | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { + | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { /* CONTROLLER ERROR * there is very little we can do... */ printf("sc%d: unable to set the command byte.\n", dev->id_unit); goto fail; } + + /* + * Check if we have an XT keyboard before we attempt to reset it. + * The procedure assumes that the keyboard and the controller have + * been set up properly by BIOS and have not been messed up + * during the boot process. + */ + codeset = -1; + if (dev->id_flags & XT_KEYBD) + /* the user says there is a XT keyboard */ + codeset = 1; +#ifdef DETECT_XT_KEYBOARD + else if ((c & KBD_TRANSLATION) == 0) { + /* SET_SCANCODE_SET is not always supported; ignore error */ + if (send_kbd_command_and_data(sc_kbdc, KBDC_SET_SCANCODE_SET, 0) + == KBD_ACK) + codeset = read_kbd_data(sc_kbdc); + } + if (bootverbose) + printf("sc%d: keyboard scancode set %d\n", dev->id_unit, codeset); +#endif /* DETECT_XT_KEYBOARD */ /* reset keyboard hardware */ - if (!reset_kbd(sc_port)) { + if (!reset_kbd(sc_kbdc)) { /* KEYBOARD ERROR * Keyboard reset may fail either because the keyboard doen't exist, * or because the keyboard doesn't pass the self-test, or the keyboard @@ -448,14 +480,14 @@ scprobe(struct isa_device *dev) * test_controller() and test_kbd_port() appear to bring the keyboard * controller back (I don't know why and how, though.) */ - empty_both_buffers(sc_port, 10); - test_controller(sc_port); - test_kbd_port(sc_port); + empty_both_buffers(sc_kbdc, 10); + test_controller(sc_kbdc); + test_kbd_port(sc_kbdc); /* We could disable the keyboard port and interrupt... but, * the keyboard may still exist (see above). */ - if (bootverbose) - printf("sc%d: failed to reset the keyboard.\n", dev->id_unit); + if (bootverbose) + printf("sc%d: failed to reset the keyboard.\n", dev->id_unit); goto fail; } @@ -464,9 +496,9 @@ scprobe(struct isa_device *dev) * such as those on the IBM ThinkPad laptop computers can be used * with the standard console driver. */ - if (dev->id_flags & XT_KEYBD) { + if (codeset == 1) { if (send_kbd_command_and_data( - sc_port, KBDC_SET_SCAN_CODESET, 1) == KBD_ACK) { + sc_kbdc, KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) { /* XT kbd doesn't need scan code translation */ c &= ~KBD_TRANSLATION; } else { @@ -479,8 +511,10 @@ scprobe(struct isa_device *dev) } } /* enable the keyboard port and intr. */ - if (!set_controller_command_byte(sc_port, c & ~KBD_KBD_CONTROL_BITS, - KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) { + if (!set_controller_command_byte(sc_kbdc, + KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS | KBD_OVERRIDE_KBD_LOCK, + (c & (KBD_AUX_CONTROL_BITS | KBD_OVERRIDE_KBD_LOCK)) + | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) { /* CONTROLLER ERROR * This is serious; we are left with the disabled keyboard intr. */ @@ -490,12 +524,17 @@ scprobe(struct isa_device *dev) } succeed: + kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS), + kbdc_lock(sc_kbdc, FALSE); return (IO_KBDSIZE); fail: if (c != -1) - /* try to restore the command byte as before, if possible */ - set_controller_command_byte(sc_port, c, 0); + /* try to restore the command byte as before, if possible */ + set_controller_command_byte(sc_kbdc, 0xff, c); + kbdc_set_device_mask(sc_kbdc, + (dev->id_flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS); + kbdc_lock(sc_kbdc, FALSE); return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE); #endif } @@ -526,14 +565,6 @@ scattach(struct isa_device *dev) #ifndef PC98 if (crtc_vga) { cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT); - font_8 = (char *)malloc(8*256, M_DEVBUF, M_NOWAIT); - font_14 = (char *)malloc(14*256, M_DEVBUF, M_NOWAIT); - font_16 = (char *)malloc(16*256, M_DEVBUF, M_NOWAIT); - copy_font(SAVE, FONT_16, font_16); - fonts_loaded = FONT_16; - scp->font_size = FONT_16; - palette = (char *)malloc(3*256, M_DEVBUF, M_NOWAIT); - save_palette(); } #endif @@ -1307,7 +1338,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) copy_font(LOAD, FONT_16, font_16); if (flags & CHAR_CURSOR) set_destructive_cursor(scp); - load_palette(); + load_palette(palette); } /* FALL THROUGH */ #endif @@ -1364,9 +1395,8 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) #ifndef PC98 if (*data & 0x80) return EINVAL; - i = spltty(); - send_kbd_command_and_data(sc_port, KBDC_SET_TYPEMATIC, *data); - splx(i); + if (sc_kbdc != NULL) + set_keyboard(KBDC_SET_TYPEMATIC, *data); #endif return 0; @@ -1638,6 +1668,8 @@ sccnprobe(struct consdev *cp) /* initialize required fields */ cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE); cp->cn_pri = CN_INTERNAL; + + sc_kbdc = kbdc_open(sc_port); } void @@ -1736,8 +1768,21 @@ scrn_timer() * This ugly hack calls scintr if input is ready for the keyboard * and conveniently hides the problem. XXX */ - if ((inb(sc_port+KBD_STATUS_PORT)&KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) - scintr(0); + /* Try removing anything stuck in the keyboard controller; whether + * it's a keyboard scan code or mouse data. `scintr()' doesn't + * read the mouse data directly, but `kbdio' routines will, as a + * side effect. + */ + if (kbdc_lock(sc_kbdc, TRUE)) { + /* + * We have seen the lock flag is not set. Let's reset the flag early; + * otherwise `update_led()' failes which may want the lock + * during `scintr()'. + */ + kbdc_lock(sc_kbdc, FALSE); + if (kbdc_data_ready(sc_kbdc)) + scintr(0); + } /* should we just return ? */ if ((scp->status&UNKNOWN_MODE) || blink_in_progress || switch_in_progress) { @@ -1912,7 +1957,7 @@ exchange_scr(void) if ((old_scp->status & UNKNOWN_MODE) && crtc_vga) { if (flags & CHAR_CURSOR) set_destructive_cursor(new_scp); - load_palette(); + load_palette(palette); } #endif if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) @@ -3130,9 +3175,8 @@ scinit(void) u_long segoff; crtc_vga = TRUE; - /* - * Get the BIOS video mode pointer. - */ + + /* Get the BIOS video mode pointer */ segoff = *(u_long *)pa_to_va(0x4a8); pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff)); if (ISMAPPED(pa, sizeof(u_long))) { @@ -3152,6 +3196,13 @@ scinit(void) bcopyw(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); + /* Save font and palette if VGA */ + if (crtc_vga) { + copy_font(SAVE, FONT_16, font_16); + fonts_loaded = FONT_16; + save_palette(); + } + console[0]->scr_buf = console[0]->mouse_pos = sc_buffer; console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor; #ifdef PC98 @@ -3169,6 +3220,7 @@ scinit(void) kernel_console.cur_color = kernel_console.std_color = kernel_default.std_color; kernel_console.rev_color = kernel_default.rev_color; + /* initialize mapscrn arrays to a one to one map */ for (i=0; i<sizeof(scr_map); i++) { scr_map[i] = scr_rmap[i] = i; @@ -3224,7 +3276,7 @@ init_scp(scr_stat *scp) if (crtc_addr == MONO_BASE) scp->mode = M_VGA_M80x25; else - scp->mode = M_VGA_C80x25; + scp->mode = M_VGA_C80x25; else if (crtc_addr == MONO_BASE) scp->mode = M_B80x25; @@ -3366,12 +3418,12 @@ scgetc(u_int flags) next_code: /* first see if there is something in the keyboard port */ if (flags & SCGETC_NONBLOCK) { - c = read_kbd_data_no_wait(sc_port); + c = read_kbd_data_no_wait(sc_kbdc); if (c == -1) return(NOKEY); } else { do { - c = read_kbd_data(sc_port); + c = read_kbd_data(sc_kbdc); } while(c == -1); } scancode = (u_char)c; @@ -3934,6 +3986,54 @@ mask2attr(struct term_stat *term) } static void +set_keyboard(int command, int data) +{ +#ifndef PC98 + int s; + int c; + + if (sc_kbdc == NULL) + return; + + /* prevent the timeout routine from polling the keyboard */ + if (!kbdc_lock(sc_kbdc, TRUE)) + return; + + /* disable the keyboard and mouse interrupt */ + s = spltty(); + c = get_controller_command_byte(sc_kbdc); + if ((c == -1) + || !set_controller_command_byte(sc_kbdc, + kbdc_get_device_mask(sc_kbdc), + KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT + | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { + /* CONTROLLER ERROR */ + kbdc_lock(sc_kbdc, FALSE); + splx(s); + return; + } + /* + * Now that the keyboard controller is told not to generate + * the keyboard and mouse interrupts, call `splx()' to allow + * the other tty interrupts. The clock interrupt may also occur, + * but the timeout routine (`scrn_timer()') will be blocked + * by the lock flag set via `kbdc_lock()' + */ + splx(s); + + send_kbd_command_and_data(sc_kbdc, command, data); + + /* restore the interrupts */ + if (!set_controller_command_byte(sc_kbdc, + kbdc_get_device_mask(sc_kbdc), + c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) { + /* CONTROLLER ERROR */ + } + kbdc_lock(sc_kbdc, FALSE); +#endif +} + +static void update_leds(int which) { #ifndef PC98 @@ -3948,10 +4048,7 @@ update_leds(int which) which &= ~CLKED; } - s = spltty(); - send_kbd_command_and_data(sc_port, KBDC_SET_LEDS, - xlate_leds[which & LED_MASK]); - splx(s); + set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]); #endif } @@ -4582,7 +4679,7 @@ save_palette(void) } void -load_palette(void) +load_palette(char *palette) { #ifndef PC98 int i; @@ -4657,6 +4754,33 @@ blink_screen(scr_stat *scp) } } +#ifdef SC_SPLASH_SCREEN +static void +toggle_splash_screen(scr_stat *scp) +{ + static int toggle = 0; + static u_char save_mode; + int s = splhigh(); + + if (toggle) { + scp->mode = save_mode; + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + load_palette(palette); + toggle = 0; + } + else { + save_mode = scp->mode; + scp->mode = M_VGA_CG320; + scp->status |= UNKNOWN_MODE; + set_mode(scp); + /* load image */ + toggle = 1; + } + splx(s); +} +#endif + #if defined(PC98) && defined(LINE30) /* 30line */ static void master_gdc_cmd(unsigned int cmd) diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h index 29f6cf1..1d6ec83 100644 --- a/sys/pc98/pc98/syscons.h +++ b/sys/pc98/pc98/syscons.h @@ -229,7 +229,7 @@ typedef struct default_attr { void set_border(u_char color); void set_mode(scr_stat *scp); void copy_font(int operation, int font_type, char* font_image); -void load_palette(void); +void load_palette(char *palette); #ifdef PC98 unsigned int at2pc98(unsigned int attr); |