The CRTC InterfaceProblem backgroundHardware registersThe relevant CRTC registers8x16 character boxCURSOR START/ENDOrganization of VRAMChanging the visual pageMoving the CRT’s cursorScrolling the screenLinux uses hardware scrollingThe ROM-BIOS variablesStandard addressesReal-mode INT-0x10 servicesCursor-movement demoPolling the status-registerDisadvantage of pollingAnother noteworthy featureIn-Class exerciseThe CRTC InterfaceEssential aspects of display page and cursor control for standard 80-column by 25-row textProblem background•For proper display of text that applications wish to write to the STDOUT device-file, our ‘os630’ program will need to reposition the CRT cursor •This will involve directly programming certain registers in the CRT Controller (i.e., hardware)•For cooperation with messages that our ‘trackldr’ boot-loader displays (it uses int-0x10), we also need to set some variable-values located in the ROM-BIOS DATA AREA (i.e., software)•This lesson will explore these two issuesHardware registers•The CRT Controller is a peripheral chip •It implements 25 standard CRTC registers•Access to these registers is accomplished via a multiplexing scheme that uses just two I/O port-addresses:address-port: 0x03D4data-port: 0x03D5The relevant CRTC registers•We are only concerned with 6 (of the 25) standard CRTC registers:•0x0A: CURSOR_START•0x0B: CURSOR_END•0x0C: START_ADDRESS_HI•0x0D: START_ADDRESS_LO•0x0E: CURSOR_LOCATION_HI•0x0F: CURSOR_LOCATION_LO8x16 character boxscanline 0scanline 1 scanline 2scanline 3scanline 4scanline 5scanline 6scanline 7scanline 8scanline 9scanline 10scanline 11scanline 12scanline 13scanline 14scanline 15Cursor_start = 12Cursor_end = 13CURSOR START/ENDdis-ablestarting_scanlineskew ending_scanline7 6 5 4 3 2 1 07 6 5 4 3 2 1 0Index 0x0A:Index 0x0B:CURSOR_START REGISTERCURSOR_END REGISTEROrganization of VRAMPage 0Page 1Page 2Page 3Page 4Page 5Page 6Page 7Base_Address = 0xB80004KB4KB4KB4KB4KB4KB4KB4KBChanging the visual page7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0START_ADDRESS_HI START_ADDRESS_LOregister-index 0x0Cregister-index 0x0DProgramming example: // switches display to vram page 5// the offset to visual page 5 (in words) is 0x2800 (= 5 * 2048)mov dx, #0x03D4 // port-address in register DXmov ax, #0x280C // value=0x28, register=0x0Cout dx, ax // write value to CRTC registermov ax, #0x000D // value=0x00, register=0x0Dout dx, ax // write value to CRTC registerMoving the CRT’s cursor7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0CURSOR_LOCATION_HI CURSOR_LOCATION_LOregister-index 0x0E register-index 0x0FProgramming example: // moves cursor to row 4, column 9, on page 0mov dx, #0x03D4 // port-address in register DXmov bx, #4 // row-numberimul bx, #80 // times cells-per-rowadd bx, #9 // plus column-numbermov ah, bh // offset’s MSBmov al, #0x0E // CURSOR_HI indexout dx, ax // write value to CRTC registermov ah, bl // offset’s LSBmov al, #0x0F // CURSOR_LO indexout dx, ax // write value to CRTC registerScrolling the screen•Here’s a code-fragment that will scroll the contents of vram page 0 up by one line: mov ax, 0xB800 // address vram page 0 mov ds, ax // with DS register mov es, ax // also ES register mov di, #0 // destination is top line mov si, #160 // source is one line lower cld // do forward copying mov cx, #1920 // 24 times 80 rep movsw mov ax, #0x0720 // blank character/color mov cx, #80 // characters on bottom line rep stoswLinux uses hardware scrolling•The value of the CRT START_ADDRESS is reprogrammed, to change the region of visible vram by one line (i.e., add #80)•So instead of subdividing vram into eight 4KB pages, the entire 32KB vram is one continuous page, but only partially visible•To scroll up by one line, Linux adds #80 to the value of the CRT_START_ADDRESSThe ROM-BIOS variables•Several variables in the ROM-BIOS DATA AREA are used by the VIDEO ROM-BIOS routins (i.e., int-0x10) to keep track of the current visisible page and of the positions of the cursors on each of the eight pages•The locations of these variables are part of the IBM-PC BIOS standard, and as such are widely documentedStandard addresses0x449 (byte) video mode-number0x44A (word) number of columns on screen0x44C (word) current page-size (in bytes)0x44E (word) current page-address0x450 (byte array) cursor-positions (col,row)0x460 (cursor type) (END, START)0x462 (byte) current page-number0x463 (word) CRTC i/o port-addressReal-mode INT-0x10 services•0x00: set_display_mode•0x01: set_cursor_type•0x02: set_cursor_position•0x03: get_cursor_position_and_type•0x05: select_new_video_page •0x06: scroll_current_page_up•0x07: scroll_current_page_down•0x08: read_char_and_attrib_from_screen•0x09: write_char_and_attrib_to_screen•0x0A: write char_only_to_screen•0x0E: write_teletype_to_active_page•0x0F: return_video_status•0x13: write_stringNOTE: These ROM-BIOS services are not available in protected-modeCursor-movement demo•To illustrate reprogramming of the six CRT controller registers, we wrote ‘arrows.s’ •It lets the user control the cursor position and visible page by using arrow-keys•It also changes the height of the cursor •An unusual feature (not recommended) is its use of “polled mode” keyboard device-programming (instead of “interrupt-driven”)Polling the status-register•The keyboard interrupts are masked•The keyboard controller’s status-register is read and reread in a tight loop until bit #0 is set, indicating that a key was pressed and thus the output-buffer is now “full”•Then the output-buffer register is read by the CPU to get the key’s “scancode”•For arrow-keys, the cursor is moved•Other keys are ignored (except ESCAPE)Disadvantage of polling•Almost all of the CPU’s time is consumed by continually reading the status-register•So this would not be a good design to use in writing a multitasking operating system•On the other hand, for single-tasking it has the advantage of not requiring a interrupt service routine to be written, so the demo code can be shorter and simplerAnother noteworthy feature•The ‘arrows.s’ demo uses a ‘jump-table’ to efficiently dispatch control to appropriate subroutines, based on a variable’s value •This is a similar programming situation to using a ‘switch’ statement in C/C++•The jump-table avoids the long chain of ‘compare-and-branch’ statements for all the various possible cases that can occurIn-Class
View Full Document