diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index d5b1b18eb922..aa5141711f42 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.34 1997/04/11 07:41:22 kato Exp $ + * $Id: syscons.c,v 1.35 1997/04/21 12:31:31 kato Exp $ */ #include "sc.h" @@ -94,7 +94,10 @@ #define WARM 1 /* this may break on older VGA's but is useful on real 32 bit systems */ -#define bcopyw bcopy +/* XXX use sc_bcopy where video memory is concerned */ +#define bcopyw bcopy +#define sc_bcopy generic_bcopy +extern void generic_bcopy(const void *, void *, size_t); static default_attr user_default = { (FG_LIGHTGREY | BG_BLACK) << 8, @@ -154,6 +157,7 @@ static long scrn_time_stamp; char font_14[256*14]; char font_16[256*16]; char palette[256*3]; +static char vgaregs[64]; static char *cut_buffer; static u_short mouse_and_mask[16] = { 0xc000, 0xe000, 0xf000, 0xf800, @@ -239,6 +243,9 @@ 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 read_vgaregs(char *buf); +static int comp_vgaregs(u_char *buf1, u_char *buf2); +static void dump_vgaregs(u_char *buf); static void set_font_mode(void); static void set_normal_mode(void); static void set_destructive_cursor(scr_stat *scp); @@ -612,6 +619,21 @@ scattach(struct isa_device *dev) update_leds(scp->status); +#ifndef PC98 + if (bootverbose) { + printf("sc%d: BIOS video mode:%d\n", + dev->id_unit, *(u_char *)pa_to_va(0x449)); + printf("sc%d: VGA registers upon power-up\n", dev->id_unit); + dump_vgaregs(vgaregs); + printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode); + if (video_mode_ptr != NULL) { + printf("sc%d: VGA registers for mode:%d\n", + dev->id_unit, scp->mode); + dump_vgaregs(video_mode_ptr + (64*scp->mode)); + } + } +#endif + printf("sc%d: ", dev->id_unit); #ifdef PC98 printf(" "); @@ -1705,10 +1727,10 @@ sccnputc(dev_t dev, int c) s = splclock(); if (scp == cur_console && !(scp->status & UNKNOWN_MODE)) { if (/* timer not running && */ (scp->start <= scp->end)) { - bcopyw(scp->scr_buf + scp->start, Crtat + scp->start, + sc_bcopy(scp->scr_buf + scp->start, Crtat + scp->start, (1 + scp->end - scp->start) * sizeof(u_short)); #ifdef PC98 - bcopyw(scp->atr_buf + scp->start, Atrat + scp->start, + sc_bcopy(scp->atr_buf + scp->start, Atrat + scp->start, (1 + scp->end - scp->start) * sizeof(u_short)); #endif scp->start = scp->xsize * scp->ysize; @@ -1801,10 +1823,10 @@ scrn_timer(void *arg) if (!scrn_blanked) { /* update screen image */ if (scp->start <= scp->end) { - bcopyw(scp->scr_buf + scp->start, Crtat + scp->start, + sc_bcopy(scp->scr_buf + scp->start, Crtat + scp->start, (1 + scp->end - scp->start) * sizeof(u_short)); #ifdef PC98 - bcopyw(scp->atr_buf + scp->start, Atrat + scp->start, + sc_bcopy(scp->atr_buf + scp->start, Atrat + scp->start, (1 + scp->end - scp->start) * sizeof(u_short)); #endif } @@ -3214,6 +3236,7 @@ scinit(void) u_long segoff; crtc_vga = TRUE; + read_vgaregs(vgaregs); /* Get the BIOS video mode pointer */ segoff = *(u_long *)pa_to_va(0x4a8); @@ -3232,8 +3255,15 @@ scinit(void) init_scp(console[0]); cur_console = console[0]; +#ifndef PC98 + /* discard the video mode table if we are not familiar with it... */ + if (video_mode_ptr) { + if (comp_vgaregs(vgaregs, video_mode_ptr + 64*console[0]->mode)) + video_mode_ptr = NULL; + } +#endif /* copy screen to temporary buffer */ - bcopyw(Crtat, sc_buffer, + sc_bcopy(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); console[0]->scr_buf = console[0]->mouse_pos = sc_buffer; @@ -4289,6 +4319,80 @@ set_vgaregs(char *modetable) splx(s); } +static void +read_vgaregs(char *buf) +{ + int i, j; + int s; + + bzero(buf, 64); + + s = splhigh(); + + outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ + outb(TSIDX, 0x07); outb(TSREG, 0x00); /* unlock registers */ + for (i=0, j=5; i<4; i++) { + outb(TSIDX, i+1); + buf[j++] = inb(TSREG); + } + buf[9] = inb(MISC + 10); /* dot-clock */ + outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ + + for (i=0, j=10; i<25; i++) { /* crtc */ + outb(crtc_addr, i); + buf[j++] = inb(crtc_addr+1); + } + for (i=0, j=35; i<20; i++) { /* attribute ctrl */ + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, i); + buf[j++] = inb(ATC + 1); + } + for (i=0, j=55; i<9; i++) { /* graph data ctrl */ + outb(GDCIDX, i); + buf[j++] = inb(GDCREG); + } + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable palette */ + + buf[0] = *(char *)pa_to_va(0x44a); /* COLS */ + buf[1] = *(char *)pa_to_va(0x484); /* ROWS */ + buf[2] = *(char *)pa_to_va(0x485); /* POINTS */ + buf[3] = *(char *)pa_to_va(0x44c); + buf[4] = *(char *)pa_to_va(0x44d); + + splx(s); +} + +static int +comp_vgaregs(u_char *buf1, u_char *buf2) +{ + int i; + + for(i = 0; i < 24; ++i) { + if (*buf1++ != *buf2++) + return 1; + } + buf1 += 2; /* skip the cursor position register value */ + buf2 += 2; + for(i = 26; i < 64; ++i) { + if (*buf1++ != *buf2++) + return 1; + } + return 0; +} + +static void +dump_vgaregs(u_char *buf) +{ + int i; + + for(i = 0; i < 64;) { + printf("%02x ", buf[i]); + if ((++i % 16) == 0) + printf("\n"); + } +} + static void set_font_mode() { @@ -4361,6 +4465,9 @@ set_normal_mode() modetable = video_mode_ptr + (64*M_VGA_C80x25); } + if (video_mode_ptr == NULL) + modetable = vgaregs; + /* setup vga for normal operation mode again */ inb(crtc_addr+6); /* reset flip-flop */ outb(ATC, 0x10); outb(ATC, modetable[0x10+35]); @@ -4481,7 +4588,7 @@ set_destructive_cursor(scr_stat *scp) while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ; #endif set_font_mode(); - bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32); + sc_bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32); set_normal_mode(); #endif } @@ -4651,7 +4758,7 @@ draw_mouse_image(scr_stat *scp) while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ; #endif set_font_mode(); - bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + 0xd0 * 32, 128); + sc_bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + 0xd0 * 32, 128); set_normal_mode(); *(crt_pos) = (*(scp->mouse_pos)&0xff00)|0xd0; *(crt_pos+scp->xsize) = (*(scp->mouse_pos+scp->xsize)&0xff00)|0xd2; @@ -4828,8 +4935,14 @@ toggle_splash_screen(scr_stat *scp) { static int toggle = 0; static u_char save_mode; - int s = splhigh(); + int s; +#ifndef PC98 + if (video_mode_ptr == NULL) + return; +#endif + + s = splhigh(); if (toggle) { scp->mode = save_mode; scp->status &= ~UNKNOWN_MODE;