summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/syscons/syscons.c124
1 files changed, 116 insertions, 8 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 35110c6..e80e6df 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/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.209 1997/04/10 12:26:50 yokota Exp $
+ * $Id: syscons.c,v 1.210 1997/04/20 16:05:33 bde Exp $
*/
#include "sc.h"
@@ -79,7 +79,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,
@@ -126,6 +129,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,
@@ -200,6 +204,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);
@@ -489,6 +496,19 @@ scattach(struct isa_device *dev)
update_leds(scp->status);
+ 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));
+ }
+ }
+
printf("sc%d: ", dev->id_unit);
if (crtc_vga)
if (crtc_addr == MONO_BASE)
@@ -1470,7 +1490,7 @@ 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));
scp->start = scp->xsize * scp->ysize;
scp->end = 0;
@@ -1562,7 +1582,7 @@ 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));
}
@@ -2429,6 +2449,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);
@@ -2445,8 +2466,14 @@ scinit(void)
init_scp(console[0]);
cur_console = console[0];
+ /* 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;
+ }
+
/* 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;
@@ -3321,6 +3348,80 @@ set_vgaregs(char *modetable)
}
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()
{
int s = splhigh();
@@ -3392,6 +3493,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]);
@@ -3508,7 +3612,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();
}
@@ -3668,7 +3772,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;
@@ -3805,8 +3909,12 @@ toggle_splash_screen(scr_stat *scp)
{
static int toggle = 0;
static u_char save_mode;
- int s = splhigh();
+ int s;
+
+ if (video_mode_ptr == NULL)
+ return;
+ s = splhigh();
if (toggle) {
scp->mode = save_mode;
scp->status &= ~UNKNOWN_MODE;
OpenPOWER on IntegriCloud