map table), make it map in video memory.
sadly, this breaks tty in non-paged mode.
happily, this simplifies the code by throwing out the messing
around with segments, and throws out vidcopy.s.
LDFLAGS = -i
LIBS = -lsys -ltimers
-OBJ = tty.o console.o vidcopy.o keyboard.o pty.o rs232.o
+OBJ = tty.o console.o keyboard.o pty.o rs232.o
# build local binary
all build: $(DRIVER)
#include <sys/ioctl.h>
#include <sys/vm.h>
#include <sys/video.h>
+#include <sys/mman.h>
#include <minix/tty.h>
#include <minix/callnr.h>
#include <minix/com.h>
#define TIMER_FREQ 1193182L /* clock frequency for timer in PC and AT */
/* Global variables used by the console driver and assembly support. */
-PUBLIC int vid_index; /* index of video segment in remote mem map */
-PUBLIC u16_t vid_seg;
-PUBLIC vir_bytes vid_off; /* video ram is found at vid_seg:vid_off */
PUBLIC phys_bytes vid_size; /* 0x2000 for color or 0x0800 for mono */
PUBLIC phys_bytes vid_base;
PUBLIC unsigned vid_mask; /* 0x1FFF for color or 0x07FF for mono */
PRIVATE unsigned scr_size; /* # characters on the screen */
PUBLIC unsigned info_location; /* location in video memory of struct */
+/* tells mem_vid_copy() to blank the screen */
+#define BLANK_MEM ((vir_bytes) 0)
+
PRIVATE int disabled_vc = -1; /* Virtual console that was active when
* disable_console was called.
*/
* console
*/
+char *console_memory = NULL;
+
/* boot_tty_info we use to communicate with the boot code. */
struct boot_tty_info boot_tty_info;
#define UPDATEBOOTINFO(ccons, infofield, value) { \
if(ccons->c_line == 0) { \
boot_tty_info.infofield = value; \
- mem_vid_copy((u16_t *) &boot_tty_info, \
+ mem_vid_copy((vir_bytes) &boot_tty_info, \
info_location/2, sizeof(boot_tty_info)/2); \
} \
}
FORWARD _PROTOTYPE( void reenable_console, (void) );
FORWARD _PROTOTYPE( int ga_program, (struct sequence *seq) );
FORWARD _PROTOTYPE( int cons_ioctl, (tty_t *tp, int) );
+FORWARD _PROTOTYPE( void mem_vid_copy, (vir_bytes src, int dst, int count) );
+FORWARD _PROTOTYPE( void vid_vid_copy, (int src, int dst, int count) );
#if 0
FORWARD _PROTOTYPE( void get_6845, (int reg, unsigned *val) );
/* Have the characters in 'ramqueue' transferred to the screen. */
if (cons->c_rwords > 0) {
- mem_vid_copy(cons->c_ramqueue, cons->c_cur, cons->c_rwords);
+ mem_vid_copy((vir_bytes) cons->c_ramqueue, cons->c_cur, cons->c_rwords);
cons->c_rwords = 0;
/* TTY likes to know the current column and if echoing messed up. */
wrap = ! machine.vdu_ega;
info_location = vid_size - sizeof(struct boot_tty_info);
- s = sys_segctl(&vid_index, &vid_seg, &vid_off, vid_base, vid_size);
+ console_memory = vm_map_phys(SELF, (void *) vid_base, vid_size);
+
+ if(console_memory == MAP_FAILED)
+ panic("TTY","Console couldn't map video memory", NO_NUM);
vid_size >>= 1; /* word count */
vid_mask = vid_size - 1;
return 0;
}
+#define LIMITINDEX(mask, start, size, ct) { \
+ int countlimit = size - start; \
+ start &= mask; \
+ if(ct > countlimit) ct = countlimit; \
+}
+
+/*===========================================================================*
+ * mem_vid_copy *
+ *===========================================================================*/
+PRIVATE void mem_vid_copy(vir_bytes src, int dst_index, int count)
+{
+ u16_t *src_mem = (u16_t *) src;
+ while(count > 0) {
+ int i, subcount = count;
+ u16_t *dst_mem;
+ LIMITINDEX(vid_mask, dst_index, vid_size, subcount);
+ dst_mem = (u16_t *) console_memory + dst_index;
+ if(!src)
+ for(i = 0; i < subcount; i++)
+ *dst_mem++ = blank_color;
+ else
+ for(i = 0; i < subcount; i++)
+ *dst_mem++ = *src_mem++;
+ count -= subcount;
+ dst_index += subcount;
+ }
+}
+
+/*===========================================================================*
+ * vid_vid_copy *
+ *===========================================================================*/
+PRIVATE void vid_vid_copy(int src_index, int dst_index, int count)
+{
+ int backwards = 0;
+ if(src_index < dst_index)
+ backwards = 1;
+ while(count > 0) {
+ int i, subcount = count;
+ u16_t *dst_mem, *src_mem;
+ LIMITINDEX(vid_mask, src_index, vid_size, subcount);
+ LIMITINDEX(vid_mask, dst_index, vid_size, subcount);
+ src_mem = (u16_t *) console_memory + src_index;
+ dst_mem = (u16_t *) console_memory + dst_index;
+ if(backwards) {
+ src_mem += subcount - 1;
+ dst_mem += subcount - 1;
+ for(i = 0; i < subcount; i++)
+ *dst_mem-- = *src_mem--;
+ } else {
+ for(i = 0; i < subcount; i++)
+ *dst_mem++ = *src_mem++;
+ }
+ count -= subcount;
+ dst_index += subcount;
+ src_index += subcount;
+ }
+}
_PROTOTYPE( void select_retry_pty, (struct tty *tp) );
_PROTOTYPE( int pty_status, (message *m_ptr) );
-/* vidcopy.s */
-_PROTOTYPE( void vid_vid_copy, (unsigned src, unsigned dst, unsigned count));
-_PROTOTYPE( void mem_vid_copy, (u16_t *src, unsigned dst, unsigned count));
-
#endif /* (CHIP == INTEL) */
+++ /dev/null
-#
-! This file contains two specialized assembly code routines to update the
-! video memory. The routines can copy from user to video memory, or from
-! video to video memory.
-
-! sections
-
-.sect .text; .sect .rom; .sect .data; .sect .bss
-
-! exported functions
-
-.define _mem_vid_copy ! copy data to video ram
-.define _vid_vid_copy ! move data in video ram
-
-! The routines only guarantee to preserve the registers the C compiler
-! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and
-! direction bit in the flags).
-
-.sect .text
-!*===========================================================================*
-!* mem_vid_copy *
-!*===========================================================================*
-! PUBLIC void mem_vid_copy(u16 *src, unsigned dst, unsigned count);
-!
-! Copy count characters from kernel memory to video memory. Src is an ordinary
-! pointer to a word, but dst and count are character (word) based video offset
-! and count. If src is null then screen memory is blanked by filling it with
-! blank_color.
-
-_mem_vid_copy:
- push ebp
- mov ebp, esp
- push esi
- push edi
- push es
- mov esi, 8(ebp) ! source
- mov edi, 12(ebp) ! destination
- mov edx, 16(ebp) ! count
- mov es, (_vid_seg) ! segment containing video memory
- cld ! make sure direction is up
-mvc_loop:
- and edi, (_vid_mask) ! wrap address
- mov ecx, edx ! one chunk to copy
- mov eax, (_vid_size)
- sub eax, edi
- cmp ecx, eax
- jbe 0f
- mov ecx, eax ! ecx = min(ecx, vid_size - edi)
-0: sub edx, ecx ! count -= ecx
- shl edi, 1 ! byte address
- add edi, (_vid_off) ! in video memory
- test esi, esi ! source == 0 means blank the screen
- jz mvc_blank
-mvc_copy:
- rep ! copy words to video memory
- o16 movs
- jmp mvc_test
-mvc_blank:
- mov eax, (_blank_color) ! ax = blanking character
- rep
- o16 stos ! copy blanks to video memory
- !jmp mvc_test
-mvc_test:
- sub edi, (_vid_off)
- shr edi, 1 ! back to a word address
- test edx, edx
- jnz mvc_loop
-mvc_done:
- pop es
- pop edi
- pop esi
- pop ebp
- ret
-
-
-!*===========================================================================*
-!* vid_vid_copy *
-!*===========================================================================*
-! PUBLIC void vid_vid_copy(unsigned src, unsigned dst, unsigned count);
-!
-! Copy count characters from video memory to video memory. Handle overlap.
-! Used for scrolling, line or character insertion and deletion. Src, dst
-! and count are character (word) based video offsets and count.
-
-_vid_vid_copy:
- push ebp
- mov ebp, esp
- push esi
- push edi
- push es
- mov esi, 8(ebp) ! source
- mov edi, 12(ebp) ! destination
- mov edx, 16(ebp) ! count
- mov es, (_vid_seg) ! segment containing video memory
- cmp esi, edi ! copy up or down?
- jb vvc_down
-vvc_up:
- cld ! direction is up
-vvc_uploop:
- and esi, (_vid_mask) ! wrap addresses
- and edi, (_vid_mask)
- mov ecx, edx ! one chunk to copy
- mov eax, (_vid_size)
- sub eax, esi
- cmp ecx, eax
- jbe 0f
- mov ecx, eax ! ecx = min(ecx, vid_size - esi)
-0: mov eax, (_vid_size)
- sub eax, edi
- cmp ecx, eax
- jbe 0f
- mov ecx, eax ! ecx = min(ecx, vid_size - edi)
-0: sub edx, ecx ! count -= ecx
- call vvc_copy ! copy video words
- test edx, edx
- jnz vvc_uploop ! again?
- jmp vvc_done
-vvc_down:
- std ! direction is down
- lea esi, -1(esi)(edx*1) ! start copying at the top
- lea edi, -1(edi)(edx*1)
-vvc_downloop:
- and esi, (_vid_mask) ! wrap addresses
- and edi, (_vid_mask)
- mov ecx, edx ! one chunk to copy
- lea eax, 1(esi)
- cmp ecx, eax
- jbe 0f
- mov ecx, eax ! ecx = min(ecx, esi + 1)
-0: lea eax, 1(edi)
- cmp ecx, eax
- jbe 0f
- mov ecx, eax ! ecx = min(ecx, edi + 1)
-0: sub edx, ecx ! count -= ecx
- call vvc_copy
- test edx, edx
- jnz vvc_downloop ! again?
- cld ! C compiler expects up
- !jmp vvc_done
-vvc_done:
- pop es
- pop edi
- pop esi
- pop ebp
- ret
-
-! Copy video words. (Inner code of both the up and downcopying loop.)
-vvc_copy:
- shl esi, 1
- shl edi, 1 ! byte addresses
- add esi, (_vid_off)
- add edi, (_vid_off) ! in video memory
- rep
-eseg o16 movs ! copy video words
- sub esi, (_vid_off)
- sub edi, (_vid_off)
- shr esi, 1
- shr edi, 1 ! back to word addresses
- ret
-
#define BLANK_COLOR 0x0700 /* determines cursor color on blank screen */
#define SCROLL_UP 0 /* scroll forward */
#define SCROLL_DOWN 1 /* scroll backward */
-#define BLANK_MEM ((u16_t *) 0) /* tells mem_vid_copy() to blank the screen */
#define CONS_RAM_WORDS 80 /* video ram buffer size */
#define MAX_ESC_PARMS 4 /* number of escape sequence params allowed */