hubble@cae780.UUCP (04/13/87)
The EGA problem, as I mentioned in my earlier posting, was with the way the EGA treats the video origin. I have changed the way MINIX does it's screen scrolling to cure the problem. Two routines were added to klib88.s: 1) _scr_up Scroll page zero up one line 2) _scr_dn Scroll page zero down one line These are brute force assembly routines that simply move all characters in the video ram page zero up or down one line as required. One would expect this to be slower than just changing the video origin register; however, I was able to notice no performance degradation. There must be enough overhead elsewhere that this gets lost in the noise. Then, the terminal driver, tty.c, was modified to call these new assembly routines. I have included the complete new routine to replace the existing routine: 1) scroll_screen Modified to call scr_up and scr_dn for scrolling I have tagged the source for all three routines on the end of this message. The changes work on my clone EGA and I believe they should also work on all CGA's and Mono graphic adapters. However, I do not have the hardware to test that belief. A couple of other points: 1) Since the EGA does not suffer from "snow", the wait for vertical retrace in the _vid_copy routine of klib88.s can be deleted. This improves performance but would break on normal CGA's. 2) As far as I could tell, the variable tty_struct[n].tty_org was never initialized. This seemed to have no effect, but I initialized it in tty_init for good measure. Source of the three routines follow: ---------------------------------------------------------------------------- Add the following routines (_scr_up and _scr_dn) to kernel/MINIX/klib88.s. Don't forget to add their names to one of the ".globl" statements near the beginning of the file. ---------------------------------------------------------------------------- |*===========================================================================* |* scr_up * |*===========================================================================* | This routine scrolls the screen up one line on an EGA display | | The call is: | scr_up(org) | where | 'org' is the video segment origin of the desired page _scr_up: push bp | we need bp to access the parameters mov bp,sp | set bp to sp for indexing push si | save the registers push di | save di push cx | save cx push es | save es push ds | save ds mov si,#160 | si = pointer to data to be copied mov di,#0 | di = offset within video ram mov cx,#1920 | cx = word count for copy loop pushf | copying may now start; save flags cli | interrupts just get in the way: disable them mov ax,4(bp) mov es,ax | load es now: int routines may ruin it mov ds,ax rep | this is the copy loop movw | ditto popf | restore flags pop ds | restore ds pop es | restore es pop cx | restore cx pop di | restore di pop si | restore si pop bp | restore bp ret | return to caller |*===========================================================================* |* scr_dn * |*===========================================================================* | This routine scrolls the screen down one line on an EGA display | | The call is: | scr_dn(org) | where | 'org' is the video segment origin of the desired page _scr_dn: push bp | we need bp to access the parameters mov bp,sp | set bp to sp for indexing push si | save the registers push di | save di push cx | save cx push es | save es push ds | save ds mov si,#3838 | si = pointer to data to be copied mov di,#3998 | di = offset within video ram mov cx,#1920 | cx = word count for copy loop pushf | copying may now start; save flags cli | interrupts just get in the way: disable them mov ax,4(bp) mov es,ax | load es now: int routines may ruin it mov ds,ax std rep | this is the copy loop movw | ditto popf | restore flags pop ds | restore ds pop es | restore es pop cx | restore cx pop di | restore di pop si | restore si pop bp | restore bp ret | return to caller ---------------------------------------------------------------------------- Replace the existing scroll_screen routine (in kernel/tty.c) with the following one: ---------------------------------------------------------------------------- /*===========================================================================* * scroll_screen * *===========================================================================*/ PRIVATE scroll_screen(tp, dir) register struct tty_struct *tp; /* pointer to tty struct */ int dir; /* GO_FORWARD or GO_BACKWARD */ { if (dir == GO_FORWARD) { scr_up(vid_base); vid_copy(NIL_PTR, vid_base, tp->tty_org + 2*(SCR_LINES-1)*LINE_WIDTH, LINE_WIDTH); } else { scr_dn(vid_base); vid_copy(NIL_PTR, vid_base, tp->tty_org, LINE_WIDTH); } } ---------------------------------------------------------------------------- I hope this helps solve other's EGA problems. Good Luck! Larry R. Hubble {hplabs, tektronix}!hubble@cae780