All of the Video handling code is in the "video" subdirectory.
There is one file for each video card or chipset and the master file. To Add a new card, it needs a set of save & restore routines putting in a file here.
These are the functions defined in env/video/video.c.
Set pointer to correct structure of functions to initialize, close, etc... video routines.
Here the sleeping lion will be awoken and eat much of CPU time !!!
The result of setting VM86_SCREEN_BITMAP (at state of Linux 1.1.56): Each vm86 call will set 32 pages of video mem RD-only (there may be 1000000 per second) Write access to RD-only page results in page-fault (mm/memory.c), which will set a bit in current->screen_bitmap and calls do_wp_page() which does __get_free_page(GFP_KERNEL) but frees it immediatly, because copy-on-write is not neccessary and sets RD/WR for the page. (this could happen 32000000 per second, if the CPU were fast enough) It would be better to get the DIRTY-bit directly from the page table, isn't it? A special syscall in emumodule could do this.
-----
reserve_video_memory()
This procedure is trying to eke out all the UMB blocks possible to maximize your memory under DOSEMU. If you know about dual monitor setups, you can contribute by putting in the correct graphics page address values.
These are the functions defined in env/video/X.c.
Initialize everything X-related.
Destroy the window, unload font, pixmap and colormap.
Check availability of the MIT-SHM shared memory extension.
Turn off usage of the MIT-SHM shared memory extension.
called by mouse.c to hide/display the mouse and set it's position. This is currently the only callback from mouse.c to X.
Handle pending X events (called from SIGALRM handler).
Allocate a colormap for graphics modes and initialize it. Do mostly nothing on true color displays. Otherwise, do: - if colormaps have less than 256 entries (notably 16 or 2 colors), don't use a private colormap - if a shared map is requested and there are less than 36 colors (3/4/3) available, use a private colormap
Note: Text modes always use the screen's default colormap.
This is the interface function called by the video subsystem to set a video mode.
NOTE: The actual mode is taken from the global variable "video_mode".
Set the video mode. If init_vga is zero, this will only reinitialize the current mode. The other arguments are ignored in this case.
Update the part of the screen which has changed, in text mode and in graphics mode. Usually called from the SIGALRM handler.
X_update_screen returns 0 if nothing was updated, 1 if the whole screen was updated, and 2 for a partial update.
It is called in arch/linux/async/signal.c::SIGALRM_call() as part of a struct video_system (see top of X.c) every 50 ms or every 10 ms if 2 was returned, depending somewhat on various config options as e.g. config.X_updatefreq and VIDEO_CHECK_DIRTY. At least it is supposed to do that.
Place the mouse on the right position.
DO NOT REMOVE THIS TEST!!! It is magic, without it EMS fails on my machine under X. Perhaps someday when we don't use a buggy /proc/self/mem.. -- EB 18 May 1998 A slightly further look says it's not the test so much as suppressing noop resize events... -- EB 1 June 1998
These are the functions defined in env/video/vgaemu.c.
Emulates writes to VGA ports. This is a hardware emulation function.
Arguments are:
port - The port being written to.
value - The value written,
Emulates reads from VGA ports. This is a hardware emulation function.
Arguments are:
port - The port being read from.
vga_emu_fault() is used to catch video access, and handle it. This function is called from arch/linux/async/sigsegv.c::dosemu_fault1(). The sigcontext_struct is defined in include/cpu.h. Now it catches only changes in a 4K page, but maybe it is useful to catch each video access. The problem when you do that is, you have to simulate each instruction which could write to the video memory. It is easy to get the place where the exception happens (scp->cr2), but what are those changes? An other problem is, it could eat a lot of time, but it does now also.
MODIFICATION: VGA mode 12h under X is supported in exactly the way that was suggested above. Not every instruction needs to be simulated in order to make this feature useful, just the ones used to access video RAM by key applications (Borland BGI, Protel, etc.).
MODIFICATION: all VGA modes now work and almost all instructions are simulated.
Arguments are:
scp - A pointer to a struct sigcontext_struct holding some relevant data.
vga_emu_init() must be called before using the VGAEmu functions. It is only called from env/video/X.c::X_init() at the moment. This function basically initializes the global variable `vga' and allocates the VGA memory.
It does in particular *not* map any memory into the range 0xa0000 - 0xc0000, this is done as part of a VGA mode switch.
There should be an accompanying vga_emu_done().
Arguments are:
vedt - Pointer to struct describing the type of display we are actually
attached to.
vga_emu_update() scans the VGA memory for dirty (= written to since last update) pages and returns the changed area in *veut. See the definition of vga_emu_update_type in env/video/vgaemu_inside.h for details.
You will need to call this function repeatedly until it returns 0 to grab all changes. You can specify an upper limit for the size of the area that will be returned using `veut->max_max_len' and `veut->max_len'. See the example in env/video/X.c how this works.
If the return value of vga_emu_update() is >= 0, it is the number of changed pages, -1 means there are still changed pages but the maximum update chunk size (`veut->max_max_len') was exceeded.
This function does in its current form not work for Hercules modes; it does, however work for text modes, although this feature is currently not used.
Arguments are:
veut - A pointer to a vga_emu_update_type object holding all relevant info.
vgaemu_switch_plane() maps the specified plane.
This function returns True on success and False on error, usually indicating an invalid bank number.
Arguments are:
plane (0..3) - The plane to map.
vga_emu_switch_bank() is used to emulate video-bankswitching.
This function returns True on success and False on error, usually indicating an invalid bank number.
Arguments are:
bank - The bank to switch to.
Searches a video mode with the requested mode number.
The search starts with the mode *after* the mode `vmi' points to. If `vmi' == NULL, starts at the beginning of the internal mode table. `mode' may be a standard VGA mode number (0 ... 0x7f) or a VESA mode number (>= 0x100). The mode number may have its don't-clear-bit (bit 7 or bit 15) or its use-lfb-bit (bit 14) set. The special mode number -1 will match any mode and may be used to scan through the whole table.
Returns NULL if no mode was found and a pointer into the mode table otherwise. The returned pointer is a suitable argument for subsequent calls to this function.
You should (and can) access the mode table only through this function.
Arguments are:
mode - video mode.
vmi - pointer into internal mode list
Set a video mode.
Switches to `mode' with text sizes `width' and `height' or (if no such mode was found) at least `width' and `height'.
Arguments are:
mode - The new video mode.
width - Number of text columns.
height - Number of text rows.
Sets the text mode resolution. Typically called after a font change.
Arguments are:
width - Number of text columns.
height - Number of text rows.
Marks the whole VGA memory as modified.
Set visible text page.
`vga.display_start' is set to `page' * `page_size'. This function works only in text modes.
Arguments are:
page - Number of the text page.
page_size - Size of one text page.
Marks all colors as changed.
Checks DAC and Attribute Controller to find all colors with changed RGB-values. Returns number of changed colors. Note: the list _must_ be large enough, that is, have at least min(256, (1 << vga.pixel_size)) entries!
Arguments are:
de - list of DAC entries to store changed colors in
Adjust VGAEmu according to VGA register changes.
These are the functions defined in env/video/vesa.c.
Initializes the VGA/VBE BIOS and the VBE support.
Arguments are:
vedt - Pointer to struct describing the type of display we are actually
attached to.
This is the VESA interrupt handler.
It is called from base/bios/int10.c::int10(). The VESA interrupt is called with 0x4f in AH and the function number (0x00 ... 0x10) in AL.
These are the functions defined in env/video/attremu.c.
Initializes the attribute controller. This is an interface function.
Directly reads the Attribute Controller's registers. This is an interface function.
Directly sets the Attribute Controller's registers. This is an interface function.
Emulates reads from the attribute controller. This is a hardware emulation function.
Emulates writes to attribute controller combined index and data register. Read VGADOC for details. This is a hardware emulation function.
Returns the current index of the attribute controller. This is a hardware emulation function, though in fact this function is undefined in a real attribute controller. Well, it is exactly what my VGA board (S3) does. -- sw This is a hardware emulation function.
These are the functions defined in env/video/dacemu.c.
Initializes the DAC. It depends on a correct value in vga.pixel_size. This function should be called during VGA mode initialization. This is an interface function.
Sets the DAC width. Typical values are 6 or 8 bits. In theory, we support other values as well (untested). This is an interface function.
Returns a complete DAC entry (r, g, b). Don't forget to set DAC_entry.index first! This is an interface function.
Sets a complete DAC entry (r,g,b). This is an interface function.
Converts a DAC register's RGB values to gray scale. This is an interface function.
Specifies which palette entry is read. This is a hardware emulation function.
Specifies which palette entry is written. This is a hardware emulation function.
Read a value from the DAC. Each read will cycle through the registers for red, green and blue. After a ``blue read'' the read index will be incremented. Read VGADOC4 if you want to know more about the DAC. This is a hardware emulation function.
Write a value to the DAC. Each write will cycle through the registers for red, green and blue. After a ``blue write'' the write index will be incremented. This is a hardware emulation function.
Returns the current PEL mask. Note that changed_vga_colors() already applies the PEL mask; so applications should not worry too much about it. This is a hardware emulation function.
Sets the PEL mask and marks all DAC entries as dirty. This is a hardware emulation function.
Returns the current state of the DAC. This is a hardware emulation function.
These are the functions defined in env/video/crtcemu.c.
Initializes the CRT Controller. This is an interface function.
These are the functions defined in env/video/dualmon.c.
Initializes the monochrome card. First detects which monochrome card is used, because the Hercules RamFont and the Hercules InColor need one more register to be initialized. If there is no monochrome card at all, we just think there is one and poke an peek in the void. After the detection the card is initialized.
returns: nothing
Arguments are:
none
After MDA_init() the VGA is configured, something in video.c or console.c "reprograms" the monochrome card again in such a way that I always have to run hgc.com before I can use any program that uses the monochrome card. I've spent a day trying to find it, but I can't figure out. Something is writing to one of the following ports: 0x3b4, 0x3b5, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bf. The problem occurs at (at least) the following 2 systems:
- AMD 386DX40, Trident 9000/512Kb ISA, Hercules Graphics Card Plus - Intel 486DX2/66, Cirrus Logic 5426/1Mb VLB, Hercules clone
The problem doesn't occur when I start dosemu from a telnet connection or from a VT100 terminal. (Erik Mouw, jakmouw@et.tudelft.nl)
These are the functions defined in env/video/vgaemu.c.
Emulates writes to VGA ports. This is a hardware emulation function.
Arguments are:
port - The port being written to.
value - The value written,
Emulates reads from VGA ports. This is a hardware emulation function.
Arguments are:
port - The port being read from.
vga_emu_fault() is used to catch video access, and handle it. This function is called from arch/linux/async/sigsegv.c::dosemu_fault1(). The sigcontext_struct is defined in include/cpu.h. Now it catches only changes in a 4K page, but maybe it is useful to catch each video access. The problem when you do that is, you have to simulate each instruction which could write to the video memory. It is easy to get the place where the exception happens (scp->cr2), but what are those changes? An other problem is, it could eat a lot of time, but it does now also.
MODIFICATION: VGA mode 12h under X is supported in exactly the way that was suggested above. Not every instruction needs to be simulated in order to make this feature useful, just the ones used to access video RAM by key applications (Borland BGI, Protel, etc.).
MODIFICATION: all VGA modes now work and almost all instructions are simulated.
Arguments are:
scp - A pointer to a struct sigcontext_struct holding some relevant data.
vga_emu_init() must be called before using the VGAEmu functions. It is only called from env/video/X.c::X_init() at the moment. This function basically initializes the global variable `vga' and allocates the VGA memory.
It does in particular *not* map any memory into the range 0xa0000 - 0xc0000, this is done as part of a VGA mode switch.
There should be an accompanying vga_emu_done().
Arguments are:
vedt - Pointer to struct describing the type of display we are actually
attached to.
vga_emu_update() scans the VGA memory for dirty (= written to since last update) pages and returns the changed area in *veut. See the definition of vga_emu_update_type in env/video/vgaemu_inside.h for details.
You will need to call this function repeatedly until it returns 0 to grab all changes. You can specify an upper limit for the size of the area that will be returned using `veut->max_max_len' and `veut->max_len'. See the example in env/video/X.c how this works.
If the return value of vga_emu_update() is >= 0, it is the number of changed pages, -1 means there are still changed pages but the maximum update chunk size (`veut->max_max_len') was exceeded.
This function does in its current form not work for Hercules modes; it does, however work for text modes, although this feature is currently not used.
Arguments are:
veut - A pointer to a vga_emu_update_type object holding all relevant info.
vgaemu_switch_plane() maps the specified plane.
This function returns True on success and False on error, usually indicating an invalid bank number.
Arguments are:
plane (0..3) - The plane to map.
vga_emu_switch_bank() is used to emulate video-bankswitching.
This function returns True on success and False on error, usually indicating an invalid bank number.
Arguments are:
bank - The bank to switch to.
Searches a video mode with the requested mode number.
The search starts with the mode *after* the mode `vmi' points to. If `vmi' == NULL, starts at the beginning of the internal mode table. `mode' may be a standard VGA mode number (0 ... 0x7f) or a VESA mode number (>= 0x100). The mode number may have its don't-clear-bit (bit 7 or bit 15) or its use-lfb-bit (bit 14) set. The special mode number -1 will match any mode and may be used to scan through the whole table.
Returns NULL if no mode was found and a pointer into the mode table otherwise. The returned pointer is a suitable argument for subsequent calls to this function.
You should (and can) access the mode table only through this function.
Arguments are:
mode - video mode.
vmi - pointer into internal mode list
Set a video mode.
Switches to `mode' with text sizes `width' and `height' or (if no such mode was found) at least `width' and `height'.
Arguments are:
mode - The new video mode.
width - Number of text columns.
height - Number of text rows.
Sets the text mode resolution. Typically called after a font change.
Arguments are:
width - Number of text columns.
height - Number of text rows.
Marks the whole VGA memory as modified.
Set visible text page.
`vga.display_start' is set to `page' * `page_size'. This function works only in text modes.
Arguments are:
page - Number of the text page.
page_size - Size of one text page.
Marks all colors as changed.
Checks DAC and Attribute Controller to find all colors with changed RGB-values. Returns number of changed colors. Note: the list _must_ be large enough, that is, have at least min(256, (1 << vga.pixel_size)) entries!
Arguments are:
de - list of DAC entries to store changed colors in
Adjust VGAEmu according to VGA register changes.
These are the functions defined in env/video/instremu.c.
Returns the length of an instruction; 0 if it could not be determined.
instr_sim is used to simulate instructions that access the VGA video memory in planar modes when using X as the video output device.
It is necessary to do this in order to simulate the effects of the hardware VGA controller in X mode.
If the return value is 0, it means the instruction was not one that for which a simulation is provided. The return value is 1 for success, but the function exits because we need to go back to the DOSEMU's main loop or count runs out.
Arguments are:
x86: the structure holding everything about the cpu-state we need.
instr_emu is the main interface to instr_sim. It puts the processor state in the x86 structure.
Arguments are:
scp - A pointer to a struct sigcontext_struct holding some relevant data.
cp - A pointer to the instruction to be simulated