The CRT Controller How to modify CRTC registers to achieve a non-standard horizontal and vertical screen resolution Video bandwidth • PC systems display pixels at a rate that is determined by an internal hardware timer • An oscillator generates this rate-frequency (it is known as the ‘dot clock’) • Modern SVGA systems can select among several different dot clocks • Faster dot clock rates are used with higher screen-resolutions Example: VESA mode 0x101 • Radeon BIOS programs CRTC hardware for 640-by-480 screen-resolution (8bpp) • Screen refresh-rate is 60 Hz (frames/sec) • This mode uses a 25.2 MHz Dot Clock • One pixel is drawn per dot-clock oscillation • But extra time is needed for the horizontal and vertical retrace operations Horizontal timing parameters • • • • • • Horizontal Display-Enable End Horizontal Blanking Start Horizontal Retrace Start Horizontal Retrace End Horizontal Blanking End Horizontal Total Vertical timing parameters • • • • • • Vertical Display-Enable End Vertical Blanking Start Vertical Retrace Start Vertical Retrace End Vertical Blanking End Vertical Total Dot-clock operation • Two internal counters are used: – The character-counter (horizontal) – The scanline-counter (vertical) • Both counters start from zero • After eight dot-clocks, the character-counter is incremented (since character-width is 8 pixels) • When character-counter reaches the horizontal total, the scanline-counter is incremented (and the character-counter is reset to zero) Dot-clock operation (2) • When scanline-counter reaches vertical total, both counters are reset to zero (and a new frame begins to be displayed) • As the counters reach programmed values for the horizontal and vertical parameters, the CRT enters a different ‘state’ (such as screen blanked, or a retrace operation) The ‘border color’ • After the ‘display-enabled’ state ends, and before the ‘display-blanked’ state begins, a traditional CRT displays a ‘overscan color’ • The overscan-color is programmable (and normally is set to ‘black’ by default) • On our classroom’s LCD monitors, we do see this border color • Border width & height are programmable Example: mode 0x101 • • • • • • Horiz Display-Enable End = 80 chars Horiz Blanking Start = 81 chars Horiz Retrace Start = 84 chars Horiz Retrace End = 96 chars Horiz Blanking End = 99 chars Horiz Total = 100 chars Horizontal timings visualized Horizontal display enabled Horizontal Retrace is active Horizontal Blanking is active Overscan Color is visible Example: mode 0x101 (cont) • • • • • • Vertical Display-Enable End = 480 Vertical Blanking Start = 487 Vertical Retrace Start = 489 Vertical Retrace End = 498 Vertical Blanking End = 516 Vertical Total = 525 Vertical timings visualized Vertical display enabled Vertical Retrace is active Vertical Blanking is active Overscan color is visible Arithmetic Formulae • frameRate = dot-clock / (Htotal * Vtotal) • 60 Hz = 25,200,000 / (800 * 525) • Horizontal freq = 31.25 KHz (= 25.2 / 800) • Vertical freq = 60 Hz Reprogramming the CRTC • We show how to reprogram the CRTC for a (nonstandard) 256-color display-mode • We start with standard VESA mode 0x101 • Then we ‘tweak’ this mode my changing the values in five of the CRTC registers • Recall that CRTC registers are addressed using a pair of i/o ports: 0x3D4 and 0x3D5 Order for our modifications Our ‘mymode.cpp’ demo does these steps: 1) Lower Horizontal Display End by 8 chars 2) Lower Vertical Disply End by 48 lines 3) Reduce Horiz Retrace Start by 5 chars 4) Reduce Vertl Retrace Start by 15 lines 5) Adjust Offset for narrower screen pitch Register details • Unlock CRTC timing registers, by clearing bit 7 in Vert Retrace End reg (index 0x11) • Perform ‘image clipping’ (horiz & vertl): – Horizontal Display-Enable End (index 1) outw( 0x4701, 0x3D4 ); // 0x4F0x47 – Vertical Display-Enable End (index 0x12) outw( 0xAF12, 0x3D4 ); // 0xDF0xAF More register details • Perform image-centering (horiz & vertl): – Horizontal Retrace Start (index 0x04) outw( 0x5004, 0x3D4 ); // 0x550x50 – Vertical Retrace Start (index 0x10) outw( 0xDA10, 0x3D4 ); // 0xE90xDA • Adjust CRT Offset register (reduced pitch) – Offset Register (index 0x13) outw( 0x4813, 0x3D4 ); // 0x500x48 Motivation for mode-tweak • Consider mode 0x101 memory-required 640x480 = 307,200 pixels • 256-colors: requires one byte-per-pixel • Total memory exceeds 4*64K (= 262,144) • Consider tweaked memory-requirements 576x432 = 248,832 pixels • Total memory does NOT exceed 4*64K Legacy VGA addressing • VGA can be programmed to access vram using 128K window: 0xA0000 – 0xBFFFF • Hardware can be programmed to access vram in ‘planar’ mode (4 bytes in parallel) • Thus two ‘pages’ of planar vram could be available for graphics animations, using ‘square’ pixels and 8086 real-mode 16-bit memory-addressing (cf Abrash ‘ModeX’) In-class exercise • Compile and run our ‘mymode.cpp’ demo • Observe final image ‘isn’t centered right’ • Can you alter the CRTC register changes that we used to produce a ‘better centered’ screen image? (horizontally & vertically)