Page 1 of 1

8086 Video Memory?

Posted: Tue Jul 30, 2013 3:43 am
by computertrick
Hi I am making a x86 emulator I need to clarify certain things for video memory.


First of all from my knowledge I believe video memory is handled by changing memory values not by using IO ports with in, out instructions is this correct?

Second of all does anybody know of any references, datasheets that explain how you decode this memory. I assume the memory will also be different depending on what video mode your in maybe

Thanks

Re: 8086 Video Memory?

Posted: Tue Jul 30, 2013 5:12 am
by iansjack
An 8086 has no video capabilities; different computers using the processor may handle output in different ways. There is a wealth of information about video output for PC compatibles (if this is what you wish to implement rather than a more generic 8086 emulator) both in this Wiki and on the web (also in books).

Seek and ye shall find. Google is a good starting point.

Edit: I realize, in retrospect, that my answer might seem a little harsh, but there are very good reasons fo it. There is an old saying "Give a man a fish and you feed him for a day, teach him to fish and you feed him for life". You have asked a number of elementary questions on this site that could easily be answered by a little reading, a little learning, and a little research. You are attempting to do quite difficult things and you will run into far deeper questions than these - are you to come running here with each difficulty or will you make an effort to learn for yourself?

Learn how to research topics. You know it makes sense.

Re: 8086 Video Memory?

Posted: Tue Jul 30, 2013 6:22 am
by computertrick
iansjack wrote:An 8086 has no video capabilities; different computers using the processor may handle output in different ways. There is a wealth of information about video output for PC compatibles (if this is what you wish to implement rather than a more generic 8086 emulator) both in this Wiki and on the web (also in books).

Seek and ye shall find. Google is a good starting point.

Edit: I realize, in retrospect, that my answer might seem a little harsh, but there are very good reasons fo it. There is an old saying "Give a man a fish and you feed him for a day, teach him to fish and you feed him for life". You have asked a number of elementary questions on this site that could easily be answered by a little reading, a little learning, and a little research. You are attempting to do quite difficult things and you will run into far deeper questions than these - are you to come running here with each difficulty or will you make an effort to learn for yourself?

Learn how to research topics. You know it makes sense.
Thanks for your reply. I don't believe I am chucking all the questions here or I would be asking about opcodes ect ect. I wrote this post so I could get an answer from someone who knows for sure how the video memory is handled because if I miss something my emulator could have false results. But sorry if you feel that way I currently have this document open
ftp://sierra.iem.pw.edu.pl/pnp/1%20lec/ ... cycles.pdf
If I couldn't do self research I wouldn't be looking at that document.

I posted this topic just to get more of an insight on how video memory is processed for future reference when my emulator is ready for graphics.

Re: 8086 Video Memory?

Posted: Tue Jul 30, 2013 7:02 am
by iansjack
How do you suppose that a list of 8086 opcodes is going to help when researching how a particular computer implementation handles graphical output? I'm afraid that your answer reinforces my suggestion that you need to do a lot more reading, and need to learn how to research a topic, before you will be ready to do the things that you are attempting.

I'm sorry that you are unwilling to take constructive criticism in the spirit that it was intended - the usual retort to the sort of questions you are asking is "RTFM", but I tried to explain a little more fully than that. I feel that just answering your questions would be doing you no favours at all as it will reinforce your tendency to rush into things without knowing how to read the documentation and solve problems and with no apparent willingness to make the effort to learn. Therefore I won't be replying further to any of your posts.

Re: 8086 Video Memory?

Posted: Tue Jul 30, 2013 12:41 pm
by ~
computertrick wrote:Hi I am making a x86 emulator I need to clarify certain things for video memory.


First of all from my knowledge I believe video memory is handled by changing memory values not by using IO ports with in, out instructions is this correct?

Second of all does anybody know of any references, datasheets that explain how you decode this memory. I assume the memory will also be different depending on what video mode your in maybe

Thanks
I am also writing a PC emulator and I have learned a lot. I have implemented basic 80x25 text mode (3h), 320x200 256-color mode (13h) and, 320x200x4 color mode (4h) 640x480x16 color mode (12h), so I think I can post what I have learned here (and will probably open other topics from myself to explain the different things that the emulator is, well, emulating).

Now about the question. For x86 PCs and for standard VGAs, you mainly change memory values to change pixels. For different modes the way you use this memory is what changes. And to change palette colors, you use I/O ports.

As we know, the standard video region goes from 0xA0000 to 0xBFFFF. Those are 128 Kilobytes, but nowadays we can consider that all standard VGA cards have up to and exactly 256 Kilobytes, which is the maximum possible given that internally the VGA uses 18-bit addresses. More information about how it works is more complex, and needs more careful explanations, but once understood, it will be easy to explain.

Given that you will know the video base address at all times (be it 0xA0000, 0xB0000 or 0xB8000), the part of the emulator that emulates the VGA must subtract that value to the RAM address it receives so that you can be left with the raw 18-bit the VGA would use internally, and from there you figure out how to handle the different planes, according to the global configuration of the VGA registers.

Since main RAM has only 128 Kilobytes of space and the VGA memory has 256 Kilobytes as a minimum, it will maybe be better to define a separate buffer for video RAM, at least to start with something minimally useable. Then the emulator would read from/write to that mapped buffer instead of main RAM.

For VGA mode 12h 640x480x16 colors, for instance, the 256 Kilobytes is divided into 4 64-Kilobyte areas (since the VGA has 4 memory planes). To set colors, you need to enable or disable writes to those planes (by using I/O ports, so technically you will need both memory writes and I/O writes for a lot of vital tasks), or use other tricks, like the Set/Reset register.

To implement it, in this mode the buffer would have:

0+(65536*0) == plane 0
0+(65536*1) == plane 1
0+(65536*2) == plane 2
0+(65536*3) == plane 3


The colors are of course set in the palette. But there are actually 2 palettes. The main one is the 256-color palette, which has 6 bits per component. The other palette is the 16-color palette, at the Attribute Controller registers 0 to 15. This 16-color palette is what we use in text mode and in standard VGA mode 12h 640x480x16 colors. Each color in this palette is an index that chooses from the first 64 colors of the 256-color palette.

Then, when you use the 16-color palette, in mode 12h for instance, 1 byte controls 8 contiguous pixels. The highest bit position controls the leftmost pixel, and the lowest bit controls the rightmost pixel. We need to combine each bit from each plane so that we will have 8 4-bit indexes for 8 16-color, 4-bit pixels.

Bit 0 -- plane 0
Bit 1 -- plane 1
Bit 2 -- plane 2
Bit 3 -- plane 3

And you do that for each pixel of the byte. If all planes are enabled then the same byte is written to the 4 areas, unless you activate other functional registers of the VGA intended specifically to modify or replace the data written by the CPU.

For text mode 3h 80x25x16 colors, I might be wrong (please somebody clarify), but at least in my emulator I have plane 0 mapped to 0xB8000, then plane 1 (where the colors are), at 0x8000 bytes above that address, and plane 2 (where fonts are), at 0x8000*2 bytes above that address. Plane 3 seems not to be used in text mode 3h. Since this mode starts its memory access at 0xB8000, and because of other configuration registers (for which the VGA already has certain built-in behaviors), the planes are forced to be smaller than those of mode 12h for instance, or for most color-rich graphics modes.

For mode 3h, plane 0 (where ASCII characters are) only gets even bytes written, and plane 1 (were background/foreground/blink color and properties are) only gets odd bytes written. Probably it would have been better to implement this mode such that 2 bytes were written only to plane 0 and then interpreted accordingly. It is a little wasteful, but it seems to be how it has been implemented.

This is how I have implemented text mode 3h, but since the documentation says that it has 4 "pages" that we can scroll with an address starting register, it would be better to put each plane at least 32768 bytes apart (since each page uses 8000 bytes in planes 0 and 1).

Or maybe I will determine that I can implement it later always in 65536 planes for all video modes, but as can be seen, it isn't initially a crucial problem for an emulator, and it is reasonably easy to fix.


______________________________
For mode 13h, 320x200x256 colors, the memory, like in mode 12h, is accessed by the CPU at memory address 0xA0000 (A000:0000). But for 256-color mode, as far as the programmer is initially concerned, the memory is just a flat array of 1-byte pixels. The values of those pixels are simple indexes into the 256-color palette (0-255). Then the colors are displayed accordingly.

If you were to emulate this palette color, which has 6 bits per R, G and B component, and if you use a standard 24-bit display color format for the RGB, then you must shift 2 bits left each component to scale the smaller 18-bit color space of the standard VGA into the bigger 24-bit color space of your real hardware. Otherwise the colors will look much darker:

R8 = R6<<2;
G8 = G6<<2;
B8 = B6<<2;


Graphics video mode 4h (320x200x4 colors) starts at 0xB8000, so planes are required to be smaller (8192 bytes each, since there are 32768 bytes from 0xB8000 and 0xBFFFF), although it looks like only 1 plane was effectively used (plane 0). Here, 1 byte controls 4 pixels. Since we use 4 colors, 1 pixel requires 2 bits for its color to be defined. The 2 highest bits control the leftmost pixel, and the 2 lowest bits control the rightmost pixel.


And if you are wondering about how to implement (non-accelerated to begin with) Super VGA modes, since we are emulating the hardware, all we have to do is increase the video buffer from 256 Kilobytes to, say, some 4 Megabytes.

Then it becomes easy to implement modes like 640x480x256 colors, 640x480x16 million colors and 800x600x16 million colors.

I have seen for instance in the Raspberry PI that setting video modes doesn't involve setting as many registers as in the standard VGA, but basically request a video mode resolution.

So why not do the same by implementing a graphics controller register that, when set to a certain value, gets the Super VGA video requested from yet another register(s) from the graphics controller, which would contain the Super VGA mode number (e.g., 101h for 640x480x256 colors, and 115h for 800x600x16 million colors)?

Then most of the standard VGA registers would no longer have any effect in the Super VGA modes, except for the 256-color palette, which we would reuse and maybe make more efficient, and things like the vertical retrace so that we have a standard way to synchronize easily even under our Super VGA modes. And also keep standard registers or implement similar ones that normally are capable of turning on or off (some) monitors, to implement that easily as well.

However, a Super VGA mode requires a 32-bit addressing space and 32-bit registers and instructions (at least under Real Mode or Unreal Mode), so that we can map those 4 Megabytes or more in a higher convenient memory area (using emulated PCI configuration?) and so that we can actually be able to modify the huge on-screen bitmap without having to complicate things even more by having to bank/segment the video memory in smaller but more confusing chunks.

The particularity of this mode is that pixels in even rows start at 0xB8000, and pixels in odd rows start 8192 bytes above (0xB8000+8192). This way of using memory seems to be as wasteful as that of text mode, since we would only be using 4096 bytes from the two 8192-byte chunks instead of using 1 full 8192-byte chunk at 0xB8000, but it seems that this is how it has always been.

Also, there are 8000 bytes visible at a time

_____________________________________________
So that you see, this is what I have been doing and what I plan to discuss and write/explain about:
Image Source code (public domain): Z86Emu__2013-07-03-jansflame.zip
x86 PC Emulator Test for MCGA Mode 13h (2013-07-03) for running in the latest versions of Firefox/Chrome/maybe OperaImage


The most recent of what I have done is this (adding basic plane support for mode 12h):
Image Source code (public domain): Z86Emu_v2013-07-26-10-21.zip
Test for Z86Emu_v2013-07-26-10-21for running in the latest versions of Firefox/Chrome/maybe Opera
Image

(See the BIOS/booting/debug/Blob_Image.bin file and subdirectories with assembly sources to see what is being run).

Now please let me know what else you would like to know about what is being done or about your original or further questions.

Re: 8086 Video Memory?

Posted: Wed Jul 31, 2013 1:58 am
by Combuster
To correct the most glaring errors, even though they don't help the OP which is way below this kind of matter. It does show some guidelines how to implement VGA emulation accurately (and not end up looking like QEMU and its clones which is crap at this):

The VGA "planes" are actually four 64 kilobyte 8-bit wide RAM chips. Together they make a 32-bit data bus and a 16-bit addressing bus. Reads always access all 32 bits, writes can be toggled on a per-chip basis. You can thus perform 32-bit writes with any byte masked from the VGA chip. Everything to and from the CPU always gets cut into 8-bit accesses first - 16-bit IO writes turn into separate index and value writes, 16-bit memory writes become two write cycles on the video RAM (potentially modifying 64 bits total). The routing inside the VGA chip is otherwise well documented, but can be confusing. In essence, setting a "video mode" the typical way configures the routing to a known default so that the 64k of memory space looks like it has a certain storage "format". While only mode 12h (and Mode X) actually demonstrates the default routing. Mode 3h and Mode 13h don't actually use consecutive bytes in their respective planes, but leave holes of 1 or 3 bytes, which actually means space is "wasted" as a compromise for each of use.

SuperVGA doesn't need any 32-bit code. It has "windows" so that 16-bit applications can directly access parts of a flat framebuffer at 0xA0000. A bios interrupt or an IO port on the svga controller selects which area to access. Most such devices have different physical memory layouts and corresponding logic to simulate the VGA routing and masked writing as appropriate. When reading the LFB, you can typically see the VGA bytes laid out according to planes 012301230123 (or 0123xxxx0123xxxx)

Re: 8086 Video Memory?

Posted: Wed Jul 31, 2013 6:07 am
by egos
Combuster wrote:The VGA "planes" are actually four 64 kilobyte 8-bit wide RAM chips. Together they make a 32-bit data bus and a 16-bit addressing bus.
Yes. I use full 128-kb buffer for text modes (even bytes belong to plane 0, odd bytes belong to plane 1). VGA allows this if it has 256 kb of RAM installed.

Re: 8086 Video Memory?

Posted: Wed Jul 31, 2013 10:51 am
by computertrick
Thanks for all your reply's even though they are slightly confusing but I suppose that's expected since I have never implemented VGA before. I will look back at these posts as a reference as I learn more about VGA. Do any of you know of any datasheets for VGA as I have looked for them but had little reference maybe I am searching for the wrong thing.