VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

Does anyone know what happens when a EGA and VGA render mode Fh?

https://cs.lmu.edu/~ray/notes/pcvideomodes/

Some documentation apparently say it's 4 colors (black and white and perhaps an extra bit for brightness/intensity)?

If so, how does the monochrome monitor and VGA render this special case?
And how does the blinking work if enabled during this mode (if it actually works on a real card at all)? Does it even work in graphics mode?

What about the attribute planes that are filtered? Aren't they set to plane 0 only (thus no extra intensity or blink bit)?

Is this determined by the attribute register 10h (mode control)'s MONO bit? What about graphics modes?

The attribute controller color registers also say something odd (EGA documentation)?
Bit 3 Secondary Blue / Mono video
Bit 4 Secondary Green / Intensity

Does the latter (Mono video / Intensity) have something to do with monochrome monitors only? What about colors monitors in this case (with the MONO bit in the attribute mode control set)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just implemented the EGA's monitor 'DAC' (which converts the palette output to colors before applying grayscale) to use bit 3 and 4 and ignore all other bits (so shifting and masking with 3, thus getting "0,55,aa,ff" for it being "0,1,2,3" after shifting).

Edit: Looking at the EGA documentation's registers programmed for all the modes, the intensity (blink) seems to be:

mode 7:
0=0
1-7=8 (bit 3 set)
8=10h (bit 4 set)
9-14=18h (both bits set)
15=17h(only high bits set, some other unused bits set as well???)

mode Fh:
0=0
1=8 (bit 3 set)
4=18 (both set)
5=18 (both set)
9=8 (lower bit set)
D=18 (both set)
all others=0

Anyone knows how this combines with the blink effect?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 2 of 54, by mkarcher

User metadata
Rank l33t
Rank
l33t

As far as I understand mode F, it's a standard 16-color EGA mode. 32 bits from video-memory get transformed into 8 pixels of 4 bits each (sent to the AC) when then drives 6 pins in the monitor socket, which would enable EGA monitors to display 64 different colors (but EGA monitors can not synchronize to the frequency of mode 0Fh). A monochrome monitor uses the same pins for synchronziation as a CGA or EGA monitor, but it uses the pin used for "secondary green" on an EGA monitor as "intensity" pin, and the pin used for "secondary blue" on EGA monitor is used as the primary video pin. So out of the 6 bits output by the attribute controller, only 2 bits are interpreted by the monitor. All monochrome monitors interpret

  • video = 0, intensity = 0 as black
  • video = 1, intensity = 0 as normal-intensity video
  • video = 1, intensity = 1 as high-intensity video

The interpretation of video=0, intensity=1 is not standardized. It will be either black or a dim intensity.

So you get three or four intensities on your monitor. The bits 3 and 4 in the attribute controller entries select which intensity is displayed on the monitor. Bits 0-2 and 5 are ignored. The assignment from color numbers in video memory to video signals is programmed just like in mode 10h. As you don't have colors, resorting to blinking makes sense. In graphics mode, EGA enables blinking on colors 8-15 (top bit set). If I remember correctly, "blinking" in graphics modes means toggling between the color value with the top bit set, and the color with the top bit clear, so color 12 will toggle between color 4 and 12. You can set up the attribute controller entries for colors 4 and 12 as you desire to have blinking between any of the three/four intensity levels.

Reply 3 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2024-02-03, 15:35:
As far as I understand mode F, it's a standard 16-color EGA mode. 32 bits from video-memory get transformed into 8 pixels of 4 b […]
Show full quote

As far as I understand mode F, it's a standard 16-color EGA mode. 32 bits from video-memory get transformed into 8 pixels of 4 bits each (sent to the AC) when then drives 6 pins in the monitor socket, which would enable EGA monitors to display 64 different colors (but EGA monitors can not synchronize to the frequency of mode 0Fh). A monochrome monitor uses the same pins for synchronziation as a CGA or EGA monitor, but it uses the pin used for "secondary green" on an EGA monitor as "intensity" pin, and the pin used for "secondary blue" on EGA monitor is used as the primary video pin. So out of the 6 bits output by the attribute controller, only 2 bits are interpreted by the monitor. All monochrome monitors interpret

  • video = 0, intensity = 0 as black
  • video = 1, intensity = 0 as normal-intensity video
  • video = 1, intensity = 1 as high-intensity video

The interpretation of video=0, intensity=1 is not standardized. It will be either black or a dim intensity.

So you get three or four intensities on your monitor. The bits 3 and 4 in the attribute controller entries select which intensity is displayed on the monitor. Bits 0-2 and 5 are ignored. The assignment from color numbers in video memory to video signals is programmed just like in mode 10h. As you don't have colors, resorting to blinking makes sense. In graphics mode, EGA enables blinking on colors 8-15 (top bit set). If I remember correctly, "blinking" in graphics modes means toggling between the color value with the top bit set, and the color with the top bit clear, so color 12 will toggle between color 4 and 12. You can set up the attribute controller entries for colors 4 and 12 as you desire to have blinking between any of the three/four intensity levels.

Is that blinking applied to the data gotten from the sequencer (4 planes) or to the attribute controller output (what's in the registers)? Rn it's the former in UniPCemu's emulation.
But does that apply with the register sets I mentioned in the first post (planes 0 and 2 being enabled only for input (color enable register being set to 05h))? Only with more than 64K memory on EGA planes 1 and 3 are used as well? How does that combine with blinking(blink enabled by plane 3 only)?
For mode 7 and F respectively?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-03, 21:48:

Is that blinking applied to the data gotten from the sequencer (4 planes) or to the attribute controller output (what's in the registers)? Rn it's the former in UniPCemu's emulation.
But does that apply with the register sets I mentioned in the first post (planes 0 and 2 being enabled only for input (color enable register being set to 05h))? Only with more than 64K memory on EGA planes 1 and 3 are used as well? How does that combine with blinking(blink enabled by plane 3 only)?
For mode 7 and F respectively?

I've been studying the EGA diagram over the past while and I would be willing to bet that the attribute controller handles blinking. Nothing is really intercepting the attribute data lines from M1D (plane 1)
if you look at sheet 6, you can follow the M1D data lines right to page 8 where they feed into the attribute controller.

The attribute controller also gets the CURSOR and VSYNC signals, which allows it to implement a counter that is some factor of frame rate.

Splitting hairs here, but the sequencer doesn't really get or give data - it just provides the RAS and CAS timings for the DRAM (and some other miscellaneous timing outputs) It can hold and implement the mask map register because if it withholds those strobes, then it can essentially disable banks/planes of VRAM. On the EGA, the address generation is discrete logic and the attribute controller can read from plane 1 and 2 directly.

I know you're asking about VGA, but maybe some of that still applies logically when everything is condensed onto a single chip.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 5 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-04, 00:56:
I've been studying the EGA diagram over the past while and I would be willing to bet that the attribute controller handles blink […]
Show full quote
superfury wrote on 2024-02-03, 21:48:

Is that blinking applied to the data gotten from the sequencer (4 planes) or to the attribute controller output (what's in the registers)? Rn it's the former in UniPCemu's emulation.
But does that apply with the register sets I mentioned in the first post (planes 0 and 2 being enabled only for input (color enable register being set to 05h))? Only with more than 64K memory on EGA planes 1 and 3 are used as well? How does that combine with blinking(blink enabled by plane 3 only)?
For mode 7 and F respectively?

I've been studying the EGA diagram over the past while and I would be willing to bet that the attribute controller handles blinking. Nothing is really intercepting the attribute data lines from M1D (plane 1)
if you look at sheet 6, you can follow the M1D data lines right to page 8 where they feed into the attribute controller.

The attribute controller also gets the CURSOR and VSYNC signals, which allows it to implement a counter that is some factor of frame rate.

Splitting hairs here, but the sequencer doesn't really get or give data - it just provides the RAS and CAS timings for the DRAM (and some other miscellaneous timing outputs) It can hold and implement the mask map register because if it withholds those strobes, then it can essentially disable banks/planes of VRAM. On the EGA, the address generation is discrete logic and the attribute controller can read from plane 1 and 2 directly.

I know you're asking about VGA, but maybe some of that still applies logically when everything is condensed onto a single chip.

The odd thing about this case is you mention bit 3 to indicate blinking. But bitplane 3 is masked off always with 64K VRAM on the EGA? Also the documentation mentions 'blinking' to be bit 'C0' cleared and bit 'C2' set in mode F? How does the attribute controller know that's the case? The color enable register can be 5h(64K RAM) or Fh(>64K RAM) in the EGA mode listing. Besides the palette changes mentioned.

Btw what schematic are you looking at? The IBM manuals never mention the exact attribute pin-ins afaik?
Edit: Ah, found them on the EGA specs... page 98 on the manual.

I see attribute 0-3 coming from a chip that has inputs C0/MID0, C1/MID1 from sheet 6(graphics controller), but C2/C3 from sheet 7 and MID2/MID3 from sheet 6(which is the graphics controller)?

sheet 6 says (graphics controller) C0/C1 outputs to C2,C3(sheet 8 )???
Perhaps the chain logic?

But unlike those lower 4 bits, the upper are always driven by the MID inputs? What are those MID inputs?
A chip probably selects between MID inputs and C0/C1/C2/C3 inputs depending on graphics mode (driven by sheet 5 _GRAPHICS from sheet 6 GRAPHICS, from the graphics controller GP0 (driving C0/C1 as well)?
What is the output of GP0?

MID3 is also connected to the sequencer 'CG' pin?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 6 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-04, 10:24:

The odd thing about this case is you mention bit 3 to indicate blinking. But bitplane 3 is masked off always with 64K VRAM on the EGA?

I am not sure where you came to this conclusion. Two points:

  • All bitplanes are available on the 64KB EGA, just each has 16K
  • Bits in the text attribute are not stored in different planes. In text mode, the card is put into Odd/Even addressing mode, where writes to even memory addresses are directed toward planes 0 and 2, and writes to odd memory addresses are sent to planes 1 and 3 (Via the sequencer O/E bit disabling the other planes on write... the Sequencer normally knows nothing about addresses with one exception - it receives the A0 pin so that it can implement the odd/even mode) Since attributes are at odd addresses, and the BIOS sets the map mask to 0011 in text mode, your attributes end up only on plane 1 - the entire byte.
superfury wrote on 2024-02-04, 10:24:

Also the documentation mentions 'blinking' to be bit 'C0' cleared and bit 'C2' set in mode F? How does the attribute controller know that's the case? The color enable register can be 5h(64K RAM) or Fh(>64K RAM) in the EGA mode listing. Besides the palette changes mentioned.

The first four bits of the attribute input are multiplexed with the four color lines C0-C3 , see U23 on page 8. Which one the Attribute Controller expects to receive is controlled by the S/L (shift load) pin, which tells the Attribute Controller to expect serial data (C0-C3 color data per pixel) or parallel data (glyph font byte + attribute byte)

Also, you may be wondering about line drawing characters C0h-DF, since in monochrome modes they are extended for a 9th column. These are detected with discrete logic (the NAND gate U5 on sheet 5) which produces a 'LG' or 'Line Graphics' signal to the Attribute controller - this is required because the attribute controller never actually receives the actual character data, just the 8-pixel span of character font glyph and the 8-bit attribute.

Last edited by GloriousCow on 2024-02-04, 13:45. Edited 1 time in total.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 7 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-04, 10:24:

I see attribute 0-3 coming from a chip that has inputs C0/MID0, C1/MID1 from sheet 6(graphics controller), but C2/C3 from sheet 7 and MID2/MID3 from sheet 6(which is the graphics controller)?
sheet 6 says (graphics controller) C0/C1 outputs to C2,C3(sheet 8 )???
Perhaps the chain logic?

Don't get confused. there are TWO graphics controllers, each one handles two planes, and thus emits 2 bits of each color. If you're flipping pages, make sure you're looking at the right graphics controller. The functional unit of a graphics controller and its attached bit planes are referred to as 'banks' and referenced as banks A and B, so address lines for planes 0 and 1 will be AA0-AA7, and for planes 2 and 3 will be BA0-BA7.

superfury wrote on 2024-02-04, 10:24:

But unlike those lower 4 bits, the upper are always driven by the MID inputs? What are those MID inputs?

M1D is data from Memory 1, or Plane #1, so attribute bytes for text mode.

superfury wrote on 2024-02-04, 10:24:

A chip probably selects between MID inputs and C0/C1/C2/C3 inputs depending on graphics mode (driven by sheet 5 _GRAPHICS from sheet 6 GRAPHICS, from the graphics controller GP0 (driving C0/C1 as well)?

Yes, this is U23 on page 8.

superfury wrote on 2024-02-04, 10:24:

What is the output of GP0?

Sorry, where are you seeing GP0 pin?

superfury wrote on 2024-02-04, 10:24:

MID3 is also connected to the sequencer 'CG' pin?

This is the character generator select bit, if enabled. Bit 3 is interpreted to select the active font, if different character generators are configured in the Character Map Select register.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 8 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-04, 13:42:
Don't get confused. there are TWO graphics controllers, each one handles two planes, and thus emits 2 bits of each color. If you […]
Show full quote
superfury wrote on 2024-02-04, 10:24:

I see attribute 0-3 coming from a chip that has inputs C0/MID0, C1/MID1 from sheet 6(graphics controller), but C2/C3 from sheet 7 and MID2/MID3 from sheet 6(which is the graphics controller)?
sheet 6 says (graphics controller) C0/C1 outputs to C2,C3(sheet 8 )???
Perhaps the chain logic?

Don't get confused. there are TWO graphics controllers, each one handles two planes, and thus emits 2 bits of each color. If you're flipping pages, make sure you're looking at the right graphics controller. The functional unit of a graphics controller and its attached bit planes are referred to as 'banks' and referenced as banks A and B, so address lines for planes 0 and 1 will be AA0-AA7, and for planes 2 and 3 will be BA0-BA7.

superfury wrote on 2024-02-04, 10:24:

But unlike those lower 4 bits, the upper are always driven by the MID inputs? What are those MID inputs?

M1D is data from Memory 1, or Plane #1, so attribute bytes for text mode.

superfury wrote on 2024-02-04, 10:24:

A chip probably selects between MID inputs and C0/C1/C2/C3 inputs depending on graphics mode (driven by sheet 5 _GRAPHICS from sheet 6 GRAPHICS, from the graphics controller GP0 (driving C0/C1 as well)?

Yes, this is U23 on page 8.

superfury wrote on 2024-02-04, 10:24:

What is the output of GP0?

Sorry, where are you seeing GP0 pin?

superfury wrote on 2024-02-04, 10:24:

MID3 is also connected to the sequencer 'CG' pin?

This is the character generator select bit, if enabled. Bit 3 is interpreted to select the active font, if different character generators are configured in the Character Map Select register.

OK. So those MID lines are the attribute number selected (from the text mode attribute generator. Bit 3 is used afaik to select character set A or B? Is that what those attribute inputs are for?)?
What do those lower 4 bits of the character index have to do with attribute inputs and text mode/graphics mode for attribute inputs? Doesn't the attribute controller just receive attribute inputs? Why multiplex the character number depending on text mode? What does U23 do with the character number (MID0-3)? And MID4-7 is always connected for something (blink on MID7? What's it's purpose)? Is MID the attribute byte and C0-C3 on it's inputs the attribute for graphics modes?

Last edited by superfury on 2024-02-04, 15:12. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-04, 13:42:
Don't get confused. there are TWO graphics controllers, each one handles two planes, and thus emits 2 bits of each color. If you […]
Show full quote
superfury wrote on 2024-02-04, 10:24:

I see attribute 0-3 coming from a chip that has inputs C0/MID0, C1/MID1 from sheet 6(graphics controller), but C2/C3 from sheet 7 and MID2/MID3 from sheet 6(which is the graphics controller)?
sheet 6 says (graphics controller) C0/C1 outputs to C2,C3(sheet 8 )???
Perhaps the chain logic?

Don't get confused. there are TWO graphics controllers, each one handles two planes, and thus emits 2 bits of each color. If you're flipping pages, make sure you're looking at the right graphics controller. The functional unit of a graphics controller and its attached bit planes are referred to as 'banks' and referenced as banks A and B, so address lines for planes 0 and 1 will be AA0-AA7, and for planes 2 and 3 will be BA0-BA7.

superfury wrote on 2024-02-04, 10:24:

But unlike those lower 4 bits, the upper are always driven by the MID inputs? What are those MID inputs?

M1D is data from Memory 1, or Plane #1, so attribute bytes for text mode.

superfury wrote on 2024-02-04, 10:24:

A chip probably selects between MID inputs and C0/C1/C2/C3 inputs depending on graphics mode (driven by sheet 5 _GRAPHICS from sheet 6 GRAPHICS, from the graphics controller GP0 (driving C0/C1 as well)?

Yes, this is U23 on page 8.

superfury wrote on 2024-02-04, 10:24:

What is the output of GP0?

Sorry, where are you seeing GP0 pin?

Chip U31 pin 12, marked GP0 ("GRAPHICS" output) going to U23's _GRAPHICS input. On page 5 it's inverted before being sent to U23?

The same pin is connected to CDSEL0(PROM pin A7 on U48?) on the other graphics chip.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 10 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-04, 14:53:

But unlike those lower 4 bits, the upper are always driven by the MID inputs? What are those MID inputs?

M1D is the attribute byte. It's an entire byte - 3-4 bits for foreground color and 3-4 bits for background color, but as we have seen the 3rd and 7th bit gets borrowed for other purposes, depending.

superfury wrote on 2024-02-04, 14:53:

OK. So those MID lines are the attribute number selected (from the text mode attribute generator. Bit 3 is used afaik to select character set A or B? Is that what those attribute inputs are for?)?

whats an attribute generator? The Attribute Controller receives the raw attribute byte. It needs the attribute byte to know what colors to emit for foreground and background of the font glyph span it receives.

superfury wrote on 2024-02-04, 14:53:

What do those lower 4 bits of the character index have to do with attribute inputs and text mode/graphics mode for attribute inputs? Doesn't the attribute controller just receive attribute inputs? Why multiplex the character number depending on text mode? What does U23 do with the character number (MID0-3)? And MID4-7 is always connected for something (blink on MID7? What's it's purpose)? Is MID the attribute byte and C0-C3 on it's inputs the attribute for graphics modes?

The lower four bits are multiplexed as they receive serial color information in graphics mode - one 4bpp pixel index per clock. In graphics mode, ATR4-7, and CC0-CC7 aren't used.
The Attribute controller basically has two operational modes - serial and parallel, again controlled by the S/L input. (Shift Load).

In text mode, the Attribute Controller receives the attribute byte on ATR0-ATR7, this comes from Plane 1, and the 8-pixel row 'slice' of glyph font data on CC0-CC7. You can see these come from M2D , or Plane #2, where we know fonts are stored. Thus in text mode, the Attribute Controller operates in parallel mode, since it receives the entire 8-bit glyph row span at once instead of being fed pixel data clock by clock.

Note that the Attribute controller has no connection to Plane 0. It has no idea what character it is drawing, other than whether the character is a line drawing character or not (indicated by the LG input)
When a character is read from plane 0 there is discrete logic that calculates the address of the corresponding font glyph by combining the character index with the CRTC's character row counter. This is accomplished by chips U12 and U3 on Sheet 5. You can see U12 takes RS0-RS4, which is the 5-bit row counter from the CRTC, latched by U20 on page 3. It looks like it's turning addresses into row counters, which might be a bit confusing. What's going on is that the CRTC is also multiplexing its own pins between address and row count. The 'REF' pin signals which one is being output, allowing U20 to latch the row counter at the appropriate time.

superfury wrote on 2024-02-04, 15:11:

Chip U31 pin 12, marked GP0 ("GRAPHICS" output) going to U23's _GRAPHICS input. On page 5 it's inverted before being sent to U23?
The same pin is connected to CDSEL0(PROM pin A7 on U48?) on the other graphics chip.

Ah. Well, I would imagine GP0 tied to GRAPHICS is controlled by the G/A bit in the Graphics Controller's Miscellaneous Register. The sequencer also has to be told we are in text mode via it's own A/G bit in the Memory Mode register, because it is responsible for switching the Attribute controller into parallel mode via the S/L bit. A lot of these redundant registers make sense when you realize that each chip has a specific role to perform. It would be interesting to properly emulate what happens if they are not set correctly to match each other...

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 11 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-04, 15:45:
M1D is the attribute byte. It's an entire byte - 3-4 bits for foreground color and 3-4 bits for background color, but as we hav […]
Show full quote
superfury wrote on 2024-02-04, 14:53:

But unlike those lower 4 bits, the upper are always driven by the MID inputs? What are those MID inputs?

M1D is the attribute byte. It's an entire byte - 3-4 bits for foreground color and 3-4 bits for background color, but as we have seen the 3rd and 7th bit gets borrowed for other purposes, depending.

superfury wrote on 2024-02-04, 14:53:

OK. So those MID lines are the attribute number selected (from the text mode attribute generator. Bit 3 is used afaik to select character set A or B? Is that what those attribute inputs are for?)?

whats an attribute generator? The Attribute Controller receives the raw attribute byte. It needs the attribute byte to know what colors to emit for foreground and background of the font glyph span it receives.

superfury wrote on 2024-02-04, 14:53:

What do those lower 4 bits of the character index have to do with attribute inputs and text mode/graphics mode for attribute inputs? Doesn't the attribute controller just receive attribute inputs? Why multiplex the character number depending on text mode? What does U23 do with the character number (MID0-3)? And MID4-7 is always connected for something (blink on MID7? What's it's purpose)? Is MID the attribute byte and C0-C3 on it's inputs the attribute for graphics modes?

The lower four bits are multiplexed as they receive serial color information in graphics mode - one 4bpp pixel index per clock. In graphics mode, ATR4-7, and CC0-CC7 aren't used.
The Attribute controller basically has two operational modes - serial and parallel, again controlled by the S/L input. (Shift Load).

In text mode, the Attribute Controller receives the attribute byte on ATR0-ATR7, this comes from Plane 1, and the 8-pixel row 'slice' of glyph font data on CC0-CC7. You can see these come from M2D , or Plane #2, where we know fonts are stored. Thus in text mode, the Attribute Controller operates in parallel mode, since it receives the entire glyph at once instead of being fed pixel data.

Note that the Attribute controller has no connection to Plane 0. It has no idea what character it is drawing, other than whether the character is a line drawing character or not (indicated by the LG input)
When a character is read from plane 0 there is discrete logic that calculates the address of the corresponding font glyph by combining the character index with the CRTC's character row counter. This is accomplished by chips U12 and U3 on Sheet 5. You can see U12 takes RS0-RS4, which is the 5-bit row counter from the CRTC, latched by U20 on page 3. It looks like it's turning addresses into row counters, which might be a bit confusing. What's going on is that the CRTC is also multiplexing its own pins between address and row count. The 'REF' pin signals which one is being output, allowing U20 to latch the row counter at the appropriate time.

OK. So the attribute controller gets the 8 pixel on/off states if text mode in parallel and shifts it out itself during each pixel clock?
Then it's badically OR'ed with the underline output for the font/background status. And perhaps AND'ed with the text mode (mode control bit 0 inversed) as well (forcing 'background' in graphics modes to apply later)?

So in graphics modes it receives C0-C4 to use. The upper ATR4-7 is ignored. So is the D0-5. The cursor is probably still used for blinking toggle (both cursor and blinking?)

Also, the P0-5 outputs are only 6 bits. The VGA (unlike EGA) probably also adds P6 and P7 for it's 8-bit and extra color select outputs.

Then the next question: what effect does the MONO bit really have on the inputs? And what about which blink bit is used?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 12 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member

Some of the memory address generation may be confusing. You'll only see 8 address bus lines at any time - how do we address 64k per plane with 8 bits?

The key is that the DRAM chips use row/column addressing. They have have 8 row address bits and 6 column address bits.
I find it easier to flip rows/columns when visualizing. Each chip holds 16k nibbles, but we can sort of ignore that since they can be thought of as contributing each half a byte, logically.

Therefore say, plane #2 holding fonts, can be represented across its pair of VRAM chips as a 2048x64 array:

Filename
font_in_ram.png
File size
2.44 KiB
Downloads
No downloads
File comment
font layout in EGA VRAM plane #2
File license
Public domain

So we have 8 glyphs per memory 'row' , and each row of each glyph can be addressed successively - which is why the row counter outputs can be used directly as low order address bits. There are gaps as fonts are 32 rows tall (why, i dunno) and 16k apart (although only one is loaded here)

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 13 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-04, 16:10:

OK. So the attribute controller gets the 8 pixel on/off states if text mode in parallel and shifts it out itself during each pixel clock?

Each dot clock, specifically. The dot clock input is provided by the sequencer, and we can set the dot clock to divide the pixel clock by 2 - this is how we get 40 column mode.

superfury wrote on 2024-02-04, 16:10:

Then it's badically OR'ed with the underline output for the font/background status. And perhaps AND'ed with the text mode (mode control bit 0 inversed) as well (forcing 'background' in graphics modes to apply later)?

This is an interesting detail - the underline is really just a nonblinking cursor. Now that I think about it, that implies that the cursor blink is done by the CRTC. Otherwise how would the Attribute controller know the difference between an underline and a cursor to blink one and not the other?

superfury wrote on 2024-02-04, 16:10:

So in graphics modes it receives C0-C4 to use. The upper ATR4-7 is ignored. So is the D0-5. The cursor is probably still used for blinking toggle (both cursor and blinking?)

The attribute controller has to at least handle text blink, since the CRTC can't do it - it doesn't know about attributes.

superfury wrote on 2024-02-04, 16:10:

Also, the P0-5 outputs are only 6 bits. The VGA (unlike EGA) probably also adds P6 and P7 for it's 8-bit and extra color select outputs.

Without a diagram I couldn't say. Internally the 6 bits in each attribute palette entry is now an index into the 256 color registers. Whether the color registers are in the attribute controller or they left it mostly alone, I don't know.

superfury wrote on 2024-02-04, 16:10:

Then the next question: what effect does the MONO bit really have on the inputs? And what about which blink bit is used?

The attribute controller doesn't have to do much special for MDA mode. When entering MDA emulation mode the BIOS can set up attribute palette to map the appropriate MDA attributes to the compatible output pins. We would expect to see only two bits set in the palette entries, set to toggle the MDA's two video inputs, +VIDEO and +I, and sure enough, if i put the EGA in MDA emulation mode in MartyPC and look at the attribute palette:

ega_mda_palette.PNG
Filename
ega_mda_palette.PNG
File size
7.61 KiB
Views
776 views
File comment
attribute palette in MDA emulation mode
File license
Public domain

This sort of implies that you could start sending voltage down the wrong pins to your MDA monitor if you screw with the palette, doesn't it?

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 14 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member

Anticipating a followup question - what tells the attribute controller to draw 9 columns?

It looks like the S/L is edge-triggered. So that's the attribute controller's signal to start serializing its character and attribute input lines. I assume if doesn't receive another S/L transition that on the 9th clock it will emit the 8th glyph bit again as foreground if LG is active-low, otherwise as background.

Here's a probe of the S/L line taken off the feature connector:

shift_load_01.png
Filename
shift_load_01.png
File size
18.25 KiB
Views
754 views
File comment
probe of S/L line on EGA card
File license
Public domain

A pixel clock of 16.257 Mhz gives us a character time of ~492 ns, and we measured the period of S/L as 490ns. Seems like a character clock, to me!

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 15 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-04, 17:41:
Anticipating a followup question - what tells the attribute controller to draw 9 columns? […]
Show full quote

Anticipating a followup question - what tells the attribute controller to draw 9 columns?

It looks like the S/L is edge-triggered. So that's the attribute controller's signal to start serializing its character and attribute input lines. I assume if doesn't receive another S/L transition that on the 9th clock it will emit the 8th glyph bit again as foreground if LG is active-low, otherwise as background.

Here's a probe of the S/L line taken off the feature connector:

shift_load_01.png

A pixel clock of 16.257 Mhz gives us a character time of ~492 ns, and we measured the period of S/L as 490ns. Seems like a character clock, to me!

OK. So the attribute controller handles all blinking.
Now what does it do to the C0-C3 inputs in graphics modes for generating a lookup index into it's LUT?

C0-C3 are of course first masked by Color plane enable before any other processing into an index into the LUT.

The documentation mentions it uses C2 and C0 and their combination effects when MONO (mode control bit 1) is set. Enabling C1 and C3 is not mentioned? What happens when this is done?

Now what happens to the index (into the LUT):
- What bit is the blink 'enable' bit?
- What bit(s) is/are toggled during blink in graphics modes? Bit 3? Bit 2?
- How does MONO affect the 4 plane inputs combined with graphics modes?

All I can find is:
- Blink enable in text modes (ONLY!) is at bit 7 and masked effectively for the background color. It switches foreground font bits to background depending on half cursor rate.
- Blink enable in monochrome graphics modes is C2=1 with C0=0. Otherwise, nothing is documented? What becomes the blink on and off indexes into the LUT? What if you enable the C1 and/or C3 planes?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 16 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-04, 18:42:

C0-C3 are of course first masked by Color plane enable before any other processing into an index into the LUT.

Right. The color plane enable basically masks the address bits to the attribute palette registers.

superfury wrote on 2024-02-04, 18:42:

The documentation mentions it uses C2 and C0 and their combination effects when MONO (mode control bit 1) is set. Enabling C1 and C3 is not mentioned? What happens when this is done?

Good question, someone would have to try it.

superfury wrote on 2024-02-04, 18:42:

Now what happens to the index (into the LUT):
- What bit is the blink 'enable' bit?

Blink enable is the B/I bit, Bit #3, in the Attribute Controller's Mode Control Register.

superfury wrote on 2024-02-04, 18:42:

- What bit(s) is/are toggled during blink in graphics modes? Bit 3? Bit 2?

Ferraro has this to say:

In monochrome (text) modes, blinking causes the character to switch between on and off. In color modes, the most significant bit feeding the color palette is toggled. This causes the character color to switch between the lower and upper halves of the color palette. For example, a character with foreground color 3 and background color E hex would alternately change to foreground color D hex and background color 6 during the blinking cycle. In the graphics modes, the most significant bit addressing the color palette is switched, similarly altering the color codes.

I haven't messed around with the blink enable bit in graphics modes before, but it sounds like in theory, if you forced it on with a screen full of 16 color graphics, you'd get some funky palette effects

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 17 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-04, 20:14:
Right. The color plane enable basically masks the address bits to the attribute palette registers. […]
Show full quote
superfury wrote on 2024-02-04, 18:42:

C0-C3 are of course first masked by Color plane enable before any other processing into an index into the LUT.

Right. The color plane enable basically masks the address bits to the attribute palette registers.

superfury wrote on 2024-02-04, 18:42:

The documentation mentions it uses C2 and C0 and their combination effects when MONO (mode control bit 1) is set. Enabling C1 and C3 is not mentioned? What happens when this is done?

Good question, someone would have to try it.

superfury wrote on 2024-02-04, 18:42:

Now what happens to the index (into the LUT):
- What bit is the blink 'enable' bit?

Blink enable is the B/I bit, Bit #3, in the Attribute Controller's Mode Control Register.

What I mean is the blink enable bit that's used from the C0-C3 masked inputs, the bit that enables character blinking (defined for monochrome modes to be 'officially' C2 combined with C0 being 1 (C2) and 0(C0) respectively). Is it C3 for color modes?

GloriousCow wrote on 2024-02-04, 20:14:
Ferraro has this to say: […]
Show full quote
superfury wrote on 2024-02-04, 18:42:

- What bit(s) is/are toggled during blink in graphics modes? Bit 3? Bit 2?

Ferraro has this to say:

In monochrome (text) modes, blinking causes the character to switch between on and off. In color modes, the most significant bit feeding the color palette is toggled. This causes the character color to switch between the lower and upper halves of the color palette. For example, a character with foreground color 3 and background color E hex would alternately change to foreground color D hex and background color 6 during the blinking cycle. In the graphics modes, the most significant bit addressing the color palette is switched, similarly altering the color codes.

I haven't messed around with the blink enable bit in graphics modes before, but it sounds like in theory, if you forced it on with a screen full of 16 color graphics, you'd get some funky palette effects

The logical bit would be the C3 input (the highest bit of the 4 planes inputted). But then the question: is that also the bit that's toggling on and off for the color inputs for 'on' and 'off' blinking states?
That one should be easily verifyable by setting up any planar 16 color mode, putting pixels on the screen and then enabling the blink bit.

Also, since 8-bit color graphics mode (4-bits high followed by 4-bits low for the first pixel in UniPCemu) also doesn't have foreground/background, would the same apply, but to C3 of the first byte instead? Once again funky results ofc 🤣 But verifyable on real hardware as well. Perhaps fill with one color and scroll through the DAC colors (by setting up a single DAC entry coloured to find results by eye and all other DAC entries black)? Perhaps a bit of split-screen raster effect to visualize the current position (bottom half of the screen normal output and non-blinking)?

Edit: Thinking about it, perhaps it's way more simple in graphics modes:
1. Graphics modes use bit 3 instead of bit 7 (4 bits less). (UniPCemu already does this)
2. MONO takes a lower bit (bit 2 instead of bit 3).
3. Simply add a NAND with bit 2, with said bit 2 being ANDed with MONO bit to disable it on the C3=1,C0=1 MONO combination and ignore on non-MONO operation.
4. Toggle the highest enable bit (1=case 1/2) for blink if enabled.

Last edited by superfury on 2024-02-04, 21:22. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 18 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

It would be easy to test 16-color blink on a EGA or VGA device. Simply show a 16-color test pattern (squares filled with 1 color like checkit diagnostics does) and enable blink bit?

Edit: Perhaps confirmed C3 being toggled on and off at least.

EGA/VGA: a programmer’s reference guide [2nd ed.] 007035099X, 9780070350991

Attribute Mode Control register (page 204) mentions:

Notes: Bit 3 can be used to enable blinking on color graphics systems in graphics modes. The blink produced is an alteration between two palette colors rather than an on/off blink. For example, color 15 alternates between colors 15 and 8.

That sounds odd? So input C3 causes C2-C0 to be masked (AND) or XOR'ed with the blink status(which is itself toggling (flipping) between 0 and 1 every 2 cursor flips/toggles)?

Page 148 's Video Status MUX (bits 4-5 of Input Status 1) is interesting too. UniPCemu simply places the DAC input (output of the attribute controller) here for the last rendered pixel (selected by Attribute Color Plane Enable Register, 3cf index 12 bits 4/5). Or is this simply read with the palette index's register 0-F bits that's (last) selected (or not written by leaving it at data write state)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 19 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

UniPCemu also fails on EGA in monochrome mode? When setting the SW1=SW2=SW4=off and SW3=on, it indeed boots up in monochrome mode. But text is never written to VRAM using the Generic Super PC/Turbo XT BIOS?

Edit: OK. Blindly waited for HDD boot. It displayed one line of the MS-DOS boot menu somehow?

Used F5 for safe boot.

Then ran 'mode mono' without the screen. (wrong MS-DOS version apparently).

Now, looking at the misc graphics register (index 06h). It's set to 05h? That's weird?
It seems to be in graphics mode somehow?

The only reason it displays at all is because the BIOS seems to properly render the MS-DOS text in graphics mode?

Microsoft Flight simulator 3 also seems to run in mode 0Fh, but doesn't seem to use more than 2 colors as well?

Last edited by superfury on 2024-02-11, 02:01. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io