Date: Sun, 1 Nov 1998 12:36:10 -0500 From: Christopher Masto <chris@netmonger.net> To: Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> Cc: hackers@FreeBSD.ORG Subject: Re: Some curiosity about syscons Message-ID: <19981101123610.A7850@netmonger.net> In-Reply-To: <199811011131.UAA15844@zodiac.mech.utsunomiya-u.ac.jp>; from Kazutaka YOKOTA on Sun, Nov 01, 1998 at 08:31:24PM %2B0900 References: <19981026230208.A8159@netmonger.net> <199811011131.UAA15844@zodiac.mech.utsunomiya-u.ac.jp>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Nov 01, 1998 at 08:31:24PM +0900, Kazutaka YOKOTA wrote: > You have to poll a CRTC status port for vertical retrace period. > > As Mike has already suggested, it is probably best to do this sort of > things as a screen saver LKM. The screen saver can do whatever > it wants (just like DOS programs... :-) > > The tricky thing is that syscons will instantly deactivate the > screen saver LKM as soon as a key is pressed (or mouse is moved). Doesn't the screen saver only get run periodically? Hmm.. Anyway, I have something which works a lot more reliably than my original call-scrn_update()-excessively hack. Of course, this is about four hacks in one. Because I stubbornly didn't want to get involved in graphics mode, but I found out that unfortunately, the lines I need to draw are slightly closer together than one 16-pixel character (so I couldn't just use the "IBM line drawing" character 196), I am making a special font that has two lines per cell, in various spacings, so I can put the right one down to simulate graphics. I'm using syscons to load the font, and mmap to get access to the video memory directly to update the screen. I then found out about the bizzaro design of text modes where there are 8 pixels across per character, but put into a 9-pixel cell. The VGA hardware leaves a one-pixel gap between characters, _except_ for the magic range of the standard IBM line drawing characters, where it duplicates the 8th column into the 9th. So I futz with the VGA registers (thank you, /dev/io) behind syscons' back.. after using syscons to request 80x30, because I need a 60Hz screen. Finally, busy-waiting for the vertical retrace completes the evil picture, and it all comes together. Then it's just a matter of putting the pieces back together so the console is again usable. Here are the preliminary functions.. I know that this is not entirely kosher, but it's a stupid little program that runs for ten seconds while the user holds their watch up to the screen. I'm not yet dealing with issues like mono vs. color screens, but other than that, I don't think I'll get yelled at for too much. There is the slight matter of not disabling interrupts while programming one of the VGA registers, but this is a user level program.. I take my chances. :-) [...] #define WAIT_RETRACE { while (inb(0x3DA) & 0x08); \ while (!(inb(0x3DA) & 0x08)); } u_short *vmem; unsigned char font[16*256], oldfont[16*256]; [...] void txt_init(void) { int p1, p2, l, i=0; unsigned char b; struct rtprio rtp; // Set realtime priority rtp.type = RTP_PRIO_REALTIME; rtp.prio = 0; if (rtprio(RTP_SET, 0, &rtp)) { perror("Couldn't set realtime priority; rtprio()"); exit(-1); } // Get I/O privileges fd = open("/dev/io", O_RDONLY, 0777); if (fd == -1) { perror("Couldn't open /dev/io"); exit(-1); } // Map video memory vmem = (u_short *)mmap(0, 0x8000, PROT_READ|PROT_WRITE, 0, 0, 0x18000); if (vmem == MAP_FAILED) { perror("mmap()"); exit(-1); } // Save the current font if (ioctl(0, GIO_FONT8x16, oldfont) < 0) { perror("Saving font failed; ioctl()"); exit(-1); } // Change syscons mode to 80x30 (60hz) if (ioctl(0, SW_VGA_C80x30) < 0) { perror("Can't change to 80x30; ioctl()"); exit(-1); } // 640 pixel mode b=inb(0x3CC); outb(0x3C2, b & 0xf3); // 8 dot clocks outb(0x3C4, 0x01); b=inb(0x3C5); outb(0x3C5, b | 0x01); sleep(2); // Let monitor resync // Generate font for (p1 = 0; p1 < 16; p1++) for (p2 = 0; p2 < 16; p2++) for (l = 0; l < 16; l++) font[i++] = (l == p1 || l == p2) ? 0xff : 0x00; for (l = 16; l < 32; l++) font[l] = 0x00; // Install font if (ioctl(0, PIO_FONT8x16, font) < 0) { perror("ioctl()"); exit(-1); } WAIT_RETRACE; clear_screen(); } [...] void draw_2line(int y, int l1, int l2) { int start, stop; u_short b; start = y * 80; stop = start + 80; b = (0x0f << 8) | ((l1 << 4) + l2); while (start < stop) vmem[start++] = b; } -- Christopher Masto Director of Operations S NetMonger Communications chris@netmonger.net info@netmonger.net SSS http://www.netmonger.net \_/ Microsoft, I think, is fundamentally an evil company. - JAMES H. CLARK To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19981101123610.A7850>