|
|
1.1 ! root 1: // ============================================================================================ ! 2: /* ! 3: * vgabios.c ! 4: */ ! 5: // ============================================================================================ ! 6: // ! 7: // Copyright (C) 2001-2008 the LGPL VGABios developers Team ! 8: // ! 9: // This library is free software; you can redistribute it and/or ! 10: // modify it under the terms of the GNU Lesser General Public ! 11: // License as published by the Free Software Foundation; either ! 12: // version 2 of the License, or (at your option) any later version. ! 13: // ! 14: // This library is distributed in the hope that it will be useful, ! 15: // but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 17: // Lesser General Public License for more details. ! 18: // ! 19: // You should have received a copy of the GNU Lesser General Public ! 20: // License along with this library; if not, write to the Free Software ! 21: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! 22: // ! 23: // ============================================================================================ ! 24: // ! 25: // This VGA Bios is specific to the plex86/bochs Emulated VGA card. ! 26: // You can NOT drive any physical vga card with it. ! 27: // ! 28: // ============================================================================================ ! 29: // ! 30: // This file contains code ripped from : ! 31: // - rombios.c of plex86 ! 32: // ! 33: // This VGA Bios contains fonts from : ! 34: // - fntcol16.zip (c) by Joseph Gil avalable at : ! 35: // ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip ! 36: // These fonts are public domain ! 37: // ! 38: // This VGA Bios is based on information taken from : ! 39: // - Kevin Lawton's vga card emulation for bochs/plex86 ! 40: // - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html ! 41: // - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ ! 42: // - Michael Abrash's Graphics Programming Black Book ! 43: // - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex ! 44: // - DOSEMU 1.0.1 source code for several tables values and formulas ! 45: // ! 46: // Thanks for patches, comments and ideas to : ! 47: // - [email protected] ! 48: // ! 49: // ============================================================================================ ! 50: ! 51: #include "vgabios.h" ! 52: ! 53: #ifdef VBE ! 54: #include "vbe.h" ! 55: #endif ! 56: ! 57: #define USE_BX_INFO ! 58: ! 59: /* Declares */ ! 60: static Bit8u read_byte(); ! 61: static Bit16u read_word(); ! 62: static void write_byte(); ! 63: static void write_word(); ! 64: static Bit8u inb(); ! 65: static Bit16u inw(); ! 66: static void outb(); ! 67: static void outw(); ! 68: ! 69: static Bit16u get_SS(); ! 70: ! 71: // Output ! 72: static void printf(); ! 73: static void unimplemented(); ! 74: static void unknown(); ! 75: ! 76: static Bit8u find_vga_entry(); ! 77: ! 78: static void memsetb(); ! 79: static void memsetw(); ! 80: static void memcpyb(); ! 81: static void memcpyw(); ! 82: ! 83: static void biosfn_set_video_mode(); ! 84: static void biosfn_set_cursor_shape(); ! 85: static void biosfn_set_cursor_pos(); ! 86: static void biosfn_get_cursor_pos(); ! 87: static void biosfn_set_active_page(); ! 88: static void biosfn_scroll(); ! 89: static void biosfn_read_char_attr(); ! 90: static void biosfn_write_char_attr(); ! 91: static void biosfn_write_char_only(); ! 92: static void biosfn_write_pixel(); ! 93: static void biosfn_read_pixel(); ! 94: static void biosfn_write_teletype(); ! 95: static void biosfn_perform_gray_scale_summing(); ! 96: static void biosfn_load_text_user_pat(); ! 97: static void biosfn_load_text_8_14_pat(); ! 98: static void biosfn_load_text_8_8_pat(); ! 99: static void biosfn_load_text_8_16_pat(); ! 100: static void biosfn_load_gfx_8_8_chars(); ! 101: static void biosfn_load_gfx_user_chars(); ! 102: static void biosfn_load_gfx_8_14_chars(); ! 103: static void biosfn_load_gfx_8_8_dd_chars(); ! 104: static void biosfn_load_gfx_8_16_chars(); ! 105: static void biosfn_get_font_info(); ! 106: static void biosfn_alternate_prtsc(); ! 107: static void biosfn_switch_video_interface(); ! 108: static void biosfn_enable_video_refresh_control(); ! 109: static void biosfn_write_string(); ! 110: static void biosfn_read_state_info(); ! 111: static void biosfn_read_video_state_size(); ! 112: static Bit16u biosfn_save_video_state(); ! 113: static Bit16u biosfn_restore_video_state(); ! 114: extern Bit8u video_save_pointer_table[]; ! 115: ! 116: // This is for compiling with gcc2 and gcc3 ! 117: #define ASM_START #asm ! 118: #define ASM_END #endasm ! 119: ! 120: ASM_START ! 121: ! 122: MACRO SET_INT_VECTOR ! 123: push ds ! 124: xor ax, ax ! 125: mov ds, ax ! 126: mov ax, ?3 ! 127: mov ?1*4, ax ! 128: mov ax, ?2 ! 129: mov ?1*4+2, ax ! 130: pop ds ! 131: MEND ! 132: ! 133: ASM_END ! 134: ! 135: ASM_START ! 136: .text ! 137: .rom ! 138: .org 0 ! 139: ! 140: use16 386 ! 141: ! 142: vgabios_start: ! 143: .byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */ ! 144: ! 145: .byte 0x40 /* BIOS extension length in units of 512 bytes */ ! 146: ! 147: ! 148: vgabios_entry_point: ! 149: ! 150: jmp vgabios_init_func ! 151: ! 152: #ifdef PCIBIOS ! 153: .org 0x18 ! 154: .word vgabios_pci_data ! 155: #endif ! 156: ! 157: // Info from Bart Oldeman ! 158: .org 0x1e ! 159: .ascii "IBM" ! 160: .byte 0x00 ! 161: ! 162: vgabios_name: ! 163: .ascii "Plex86/Bochs VGABios" ! 164: #ifdef PCIBIOS ! 165: .ascii " (PCI)" ! 166: #endif ! 167: .ascii " " ! 168: .byte 0x00 ! 169: ! 170: vgabios_version: ! 171: #ifndef VGABIOS_VERS ! 172: .ascii "current-cvs" ! 173: #else ! 174: .ascii VGABIOS_VERS ! 175: #endif ! 176: .ascii " " ! 177: ! 178: vgabios_date: ! 179: .ascii VGABIOS_DATE ! 180: .byte 0x0a,0x0d ! 181: .byte 0x00 ! 182: ! 183: vgabios_copyright: ! 184: .ascii "(C) 2008 the LGPL VGABios developers Team" ! 185: .byte 0x0a,0x0d ! 186: .byte 0x00 ! 187: ! 188: vgabios_license: ! 189: .ascii "This VGA/VBE Bios is released under the GNU LGPL" ! 190: .byte 0x0a,0x0d ! 191: .byte 0x0a,0x0d ! 192: .byte 0x00 ! 193: ! 194: vgabios_website: ! 195: .ascii "Please visit :" ! 196: .byte 0x0a,0x0d ! 197: ;;.ascii " . http://www.plex86.org" ! 198: ;;.byte 0x0a,0x0d ! 199: .ascii " . http://bochs.sourceforge.net" ! 200: .byte 0x0a,0x0d ! 201: .ascii " . http://www.nongnu.org/vgabios" ! 202: .byte 0x0a,0x0d ! 203: .byte 0x0a,0x0d ! 204: .byte 0x00 ! 205: ! 206: #ifdef PCIBIOS ! 207: vgabios_pci_data: ! 208: .ascii "PCIR" ! 209: #ifdef CIRRUS ! 210: .word 0x1013 ! 211: .word 0x00b8 // CLGD5446 ! 212: #else ! 213: #error "Unknown PCI vendor and device id" ! 214: #endif ! 215: .word 0 // reserved ! 216: .word 0x18 // dlen ! 217: .byte 0 // revision ! 218: .byte 0x0 // class,hi: vga display ! 219: .word 0x300 // class,lo: vga display ! 220: .word 0x40 // bios size ! 221: .word 1 // revision ! 222: .byte 0 // intel x86 data ! 223: .byte 0x80 // last image ! 224: .word 0 // reserved ! 225: #endif ! 226: ! 227: ! 228: ;; ============================================================================================ ! 229: ;; ! 230: ;; Init Entry point ! 231: ;; ! 232: ;; ============================================================================================ ! 233: vgabios_init_func: ! 234: ! 235: ;; init vga card ! 236: call init_vga_card ! 237: ! 238: ;; init basic bios vars ! 239: call init_bios_area ! 240: ! 241: #ifdef VBE ! 242: ;; init vbe functions ! 243: call vbe_init ! 244: #endif ! 245: ! 246: ;; set int10 vect ! 247: SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler) ! 248: ! 249: #ifdef CIRRUS ! 250: call cirrus_init ! 251: #endif ! 252: ! 253: ;; display splash screen ! 254: call _display_splash_screen ! 255: ! 256: ;; init video mode and clear the screen ! 257: mov ax,#0x0003 ! 258: int #0x10 ! 259: ! 260: ;; show info ! 261: call _display_info ! 262: ! 263: #ifdef VBE ! 264: ;; show vbe info ! 265: call vbe_display_info ! 266: #endif ! 267: ! 268: #ifdef CIRRUS ! 269: ;; show cirrus info ! 270: call cirrus_display_info ! 271: #endif ! 272: ! 273: retf ! 274: ASM_END ! 275: ! 276: /* ! 277: * int10 handled here ! 278: */ ! 279: ASM_START ! 280: vgabios_int10_handler: ! 281: pushf ! 282: #ifdef DEBUG ! 283: push es ! 284: push ds ! 285: pusha ! 286: mov bx, #0xc000 ! 287: mov ds, bx ! 288: call _int10_debugmsg ! 289: popa ! 290: pop ds ! 291: pop es ! 292: #endif ! 293: cmp ah, #0x0f ! 294: jne int10_test_1A ! 295: call biosfn_get_video_mode ! 296: jmp int10_end ! 297: int10_test_1A: ! 298: cmp ah, #0x1a ! 299: jne int10_test_0B ! 300: call biosfn_group_1A ! 301: jmp int10_end ! 302: int10_test_0B: ! 303: cmp ah, #0x0b ! 304: jne int10_test_1103 ! 305: call biosfn_group_0B ! 306: jmp int10_end ! 307: int10_test_1103: ! 308: cmp ax, #0x1103 ! 309: jne int10_test_12 ! 310: call biosfn_set_text_block_specifier ! 311: jmp int10_end ! 312: int10_test_12: ! 313: cmp ah, #0x12 ! 314: jne int10_test_101B ! 315: cmp bl, #0x10 ! 316: jne int10_test_BL30 ! 317: call biosfn_get_ega_info ! 318: jmp int10_end ! 319: int10_test_BL30: ! 320: cmp bl, #0x30 ! 321: jne int10_test_BL31 ! 322: call biosfn_select_vert_res ! 323: jmp int10_end ! 324: int10_test_BL31: ! 325: cmp bl, #0x31 ! 326: jne int10_test_BL32 ! 327: call biosfn_enable_default_palette_loading ! 328: jmp int10_end ! 329: int10_test_BL32: ! 330: cmp bl, #0x32 ! 331: jne int10_test_BL33 ! 332: call biosfn_enable_video_addressing ! 333: jmp int10_end ! 334: int10_test_BL33: ! 335: cmp bl, #0x33 ! 336: jne int10_test_BL34 ! 337: call biosfn_enable_grayscale_summing ! 338: jmp int10_end ! 339: int10_test_BL34: ! 340: cmp bl, #0x34 ! 341: jne int10_normal ! 342: call biosfn_enable_cursor_emulation ! 343: jmp int10_end ! 344: int10_test_101B: ! 345: cmp ax, #0x101b ! 346: je int10_normal ! 347: cmp ah, #0x10 ! 348: #ifndef VBE ! 349: jne int10_normal ! 350: #else ! 351: jne int10_test_4F ! 352: #endif ! 353: call biosfn_group_10 ! 354: jmp int10_end ! 355: #ifdef VBE ! 356: int10_test_4F: ! 357: cmp ah, #0x4f ! 358: jne int10_normal ! 359: cmp al, #0x03 ! 360: jne int10_test_vbe_05 ! 361: call vbe_biosfn_return_current_mode ! 362: jmp int10_end ! 363: int10_test_vbe_05: ! 364: cmp al, #0x05 ! 365: jne int10_test_vbe_06 ! 366: call vbe_biosfn_display_window_control ! 367: jmp int10_end ! 368: int10_test_vbe_06: ! 369: cmp al, #0x06 ! 370: jne int10_test_vbe_07 ! 371: call vbe_biosfn_set_get_logical_scan_line_length ! 372: jmp int10_end ! 373: int10_test_vbe_07: ! 374: cmp al, #0x07 ! 375: jne int10_test_vbe_08 ! 376: call vbe_biosfn_set_get_display_start ! 377: jmp int10_end ! 378: int10_test_vbe_08: ! 379: cmp al, #0x08 ! 380: jne int10_test_vbe_0A ! 381: call vbe_biosfn_set_get_dac_palette_format ! 382: jmp int10_end ! 383: int10_test_vbe_0A: ! 384: cmp al, #0x0A ! 385: jne int10_normal ! 386: call vbe_biosfn_return_protected_mode_interface ! 387: jmp int10_end ! 388: #endif ! 389: ! 390: int10_normal: ! 391: push es ! 392: push ds ! 393: pusha ! 394: ! 395: ;; We have to set ds to access the right data segment ! 396: mov bx, #0xc000 ! 397: mov ds, bx ! 398: call _int10_func ! 399: ! 400: popa ! 401: pop ds ! 402: pop es ! 403: int10_end: ! 404: popf ! 405: iret ! 406: ASM_END ! 407: ! 408: #include "vgatables.h" ! 409: #include "vgafonts.h" ! 410: ! 411: /* ! 412: * Boot time harware inits ! 413: */ ! 414: ASM_START ! 415: init_vga_card: ! 416: ;; switch to color mode and enable CPU access 480 lines ! 417: mov dx, #0x3C2 ! 418: mov al, #0xC3 ! 419: outb dx,al ! 420: ! 421: ;; more than 64k 3C4/04 ! 422: mov dx, #0x3C4 ! 423: mov al, #0x04 ! 424: outb dx,al ! 425: mov dx, #0x3C5 ! 426: mov al, #0x02 ! 427: outb dx,al ! 428: ! 429: #if defined(USE_BX_INFO) || defined(DEBUG) ! 430: mov bx, #msg_vga_init ! 431: push bx ! 432: call _printf ! 433: #endif ! 434: inc sp ! 435: inc sp ! 436: ret ! 437: ! 438: #if defined(USE_BX_INFO) || defined(DEBUG) ! 439: msg_vga_init: ! 440: .ascii "VGABios $Id$" ! 441: .byte 0x0d,0x0a,0x00 ! 442: #endif ! 443: ASM_END ! 444: ! 445: // -------------------------------------------------------------------------------------------- ! 446: /* ! 447: * Boot time bios area inits ! 448: */ ! 449: ASM_START ! 450: init_bios_area: ! 451: push ds ! 452: mov ax, # BIOSMEM_SEG ! 453: mov ds, ax ! 454: ! 455: ;; init detected hardware BIOS Area ! 456: mov bx, # BIOSMEM_INITIAL_MODE ! 457: mov ax, [bx] ! 458: and ax, #0xffcf ! 459: ;; set 80x25 color (not clear from RBIL but usual) ! 460: or ax, #0x0020 ! 461: mov [bx], ax ! 462: ! 463: ;; Just for the first int10 find its children ! 464: ! 465: ;; the default char height ! 466: mov bx, # BIOSMEM_CHAR_HEIGHT ! 467: mov al, #0x10 ! 468: mov [bx], al ! 469: ! 470: ;; Clear the screen ! 471: mov bx, # BIOSMEM_VIDEO_CTL ! 472: mov al, #0x60 ! 473: mov [bx], al ! 474: ! 475: ;; Set the basic screen we have ! 476: mov bx, # BIOSMEM_SWITCHES ! 477: mov al, #0xf9 ! 478: mov [bx], al ! 479: ! 480: ;; Set the basic modeset options ! 481: mov bx, # BIOSMEM_MODESET_CTL ! 482: mov al, #0x51 ! 483: mov [bx], al ! 484: ! 485: ;; Set the default MSR ! 486: mov bx, # BIOSMEM_CURRENT_MSR ! 487: mov al, #0x09 ! 488: mov [bx], al ! 489: ! 490: pop ds ! 491: ret ! 492: ! 493: _video_save_pointer_table: ! 494: .word _video_param_table ! 495: .word 0xc000 ! 496: ! 497: .word 0 /* XXX: fill it */ ! 498: .word 0 ! 499: ! 500: .word 0 /* XXX: fill it */ ! 501: .word 0 ! 502: ! 503: .word 0 /* XXX: fill it */ ! 504: .word 0 ! 505: ! 506: .word 0 /* XXX: fill it */ ! 507: .word 0 ! 508: ! 509: .word 0 /* XXX: fill it */ ! 510: .word 0 ! 511: ! 512: .word 0 /* XXX: fill it */ ! 513: .word 0 ! 514: ! 515: ASM_END ! 516: ! 517: // -------------------------------------------------------------------------------------------- ! 518: /* ! 519: * Boot time Splash screen ! 520: */ ! 521: static void display_splash_screen() ! 522: { ! 523: } ! 524: ! 525: // -------------------------------------------------------------------------------------------- ! 526: /* ! 527: * Tell who we are ! 528: */ ! 529: ! 530: static void display_info() ! 531: { ! 532: ASM_START ! 533: mov ax,#0xc000 ! 534: mov ds,ax ! 535: mov si,#vgabios_name ! 536: call _display_string ! 537: mov si,#vgabios_version ! 538: call _display_string ! 539: ! 540: ;;mov si,#vgabios_copyright ! 541: ;;call _display_string ! 542: ;;mov si,#crlf ! 543: ;;call _display_string ! 544: ! 545: mov si,#vgabios_license ! 546: call _display_string ! 547: mov si,#vgabios_website ! 548: call _display_string ! 549: ASM_END ! 550: } ! 551: ! 552: static void display_string() ! 553: { ! 554: // Get length of string ! 555: ASM_START ! 556: mov ax,ds ! 557: mov es,ax ! 558: mov di,si ! 559: xor cx,cx ! 560: not cx ! 561: xor al,al ! 562: cld ! 563: repne ! 564: scasb ! 565: not cx ! 566: dec cx ! 567: push cx ! 568: ! 569: mov ax,#0x0300 ! 570: mov bx,#0x0000 ! 571: int #0x10 ! 572: ! 573: pop cx ! 574: mov ax,#0x1301 ! 575: mov bx,#0x000b ! 576: mov bp,si ! 577: int #0x10 ! 578: ASM_END ! 579: } ! 580: ! 581: // -------------------------------------------------------------------------------------------- ! 582: #ifdef DEBUG ! 583: static void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) ! 584: Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; ! 585: { ! 586: // 0E is write char... ! 587: if(GET_AH()!=0x0E) ! 588: printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); ! 589: } ! 590: #endif ! 591: ! 592: // -------------------------------------------------------------------------------------------- ! 593: /* ! 594: * int10 main dispatcher ! 595: */ ! 596: static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) ! 597: Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; ! 598: { ! 599: ! 600: // BIOS functions ! 601: switch(GET_AH()) ! 602: { ! 603: case 0x00: ! 604: biosfn_set_video_mode(GET_AL()); ! 605: switch(GET_AL()&0x7F) ! 606: {case 6: ! 607: SET_AL(0x3F); ! 608: break; ! 609: case 0: ! 610: case 1: ! 611: case 2: ! 612: case 3: ! 613: case 4: ! 614: case 5: ! 615: case 7: ! 616: SET_AL(0x30); ! 617: break; ! 618: default: ! 619: SET_AL(0x20); ! 620: } ! 621: break; ! 622: case 0x01: ! 623: biosfn_set_cursor_shape(GET_CH(),GET_CL()); ! 624: break; ! 625: case 0x02: ! 626: biosfn_set_cursor_pos(GET_BH(),DX); ! 627: break; ! 628: case 0x03: ! 629: biosfn_get_cursor_pos(GET_BH(),&CX,&DX); ! 630: break; ! 631: case 0x04: ! 632: // Read light pen pos (unimplemented) ! 633: #ifdef DEBUG ! 634: unimplemented(); ! 635: #endif ! 636: AX=0x00; ! 637: BX=0x00; ! 638: CX=0x00; ! 639: DX=0x00; ! 640: break; ! 641: case 0x05: ! 642: biosfn_set_active_page(GET_AL()); ! 643: break; ! 644: case 0x06: ! 645: biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP); ! 646: break; ! 647: case 0x07: ! 648: biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN); ! 649: break; ! 650: case 0x08: ! 651: biosfn_read_char_attr(GET_BH(),&AX); ! 652: break; ! 653: case 0x09: ! 654: biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX); ! 655: break; ! 656: case 0x0A: ! 657: biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX); ! 658: break; ! 659: case 0x0C: ! 660: biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX); ! 661: break; ! 662: case 0x0D: ! 663: biosfn_read_pixel(GET_BH(),CX,DX,&AX); ! 664: break; ! 665: case 0x0E: ! 666: // Ralf Brown Interrupt list is WRONG on bh(page) ! 667: // We do output only on the current page ! ! 668: biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR); ! 669: break; ! 670: case 0x10: ! 671: // All other functions of group AH=0x10 rewritten in assembler ! 672: biosfn_perform_gray_scale_summing(BX,CX); ! 673: break; ! 674: case 0x11: ! 675: switch(GET_AL()) ! 676: { ! 677: case 0x00: ! 678: case 0x10: ! 679: biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH()); ! 680: break; ! 681: case 0x01: ! 682: case 0x11: ! 683: biosfn_load_text_8_14_pat(GET_AL(),GET_BL()); ! 684: break; ! 685: case 0x02: ! 686: case 0x12: ! 687: biosfn_load_text_8_8_pat(GET_AL(),GET_BL()); ! 688: break; ! 689: case 0x04: ! 690: case 0x14: ! 691: biosfn_load_text_8_16_pat(GET_AL(),GET_BL()); ! 692: break; ! 693: case 0x20: ! 694: biosfn_load_gfx_8_8_chars(ES,BP); ! 695: break; ! 696: case 0x21: ! 697: biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL()); ! 698: break; ! 699: case 0x22: ! 700: biosfn_load_gfx_8_14_chars(GET_BL()); ! 701: break; ! 702: case 0x23: ! 703: biosfn_load_gfx_8_8_dd_chars(GET_BL()); ! 704: break; ! 705: case 0x24: ! 706: biosfn_load_gfx_8_16_chars(GET_BL()); ! 707: break; ! 708: case 0x30: ! 709: biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX); ! 710: break; ! 711: #ifdef DEBUG ! 712: default: ! 713: unknown(); ! 714: #endif ! 715: } ! 716: ! 717: break; ! 718: case 0x12: ! 719: switch(GET_BL()) ! 720: { ! 721: case 0x20: ! 722: biosfn_alternate_prtsc(); ! 723: break; ! 724: case 0x35: ! 725: biosfn_switch_video_interface(GET_AL(),ES,DX); ! 726: SET_AL(0x12); ! 727: break; ! 728: case 0x36: ! 729: biosfn_enable_video_refresh_control(GET_AL()); ! 730: SET_AL(0x12); ! 731: break; ! 732: #ifdef DEBUG ! 733: default: ! 734: unknown(); ! 735: #endif ! 736: } ! 737: break; ! 738: case 0x13: ! 739: biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP); ! 740: break; ! 741: case 0x1B: ! 742: biosfn_read_state_info(BX,ES,DI); ! 743: SET_AL(0x1B); ! 744: break; ! 745: case 0x1C: ! 746: switch(GET_AL()) ! 747: { ! 748: case 0x00: ! 749: biosfn_read_video_state_size(CX,&BX); ! 750: break; ! 751: case 0x01: ! 752: biosfn_save_video_state(CX,ES,BX); ! 753: break; ! 754: case 0x02: ! 755: biosfn_restore_video_state(CX,ES,BX); ! 756: break; ! 757: #ifdef DEBUG ! 758: default: ! 759: unknown(); ! 760: #endif ! 761: } ! 762: SET_AL(0x1C); ! 763: break; ! 764: ! 765: #ifdef VBE ! 766: case 0x4f: ! 767: if (vbe_has_vbe_display()) { ! 768: switch(GET_AL()) ! 769: { ! 770: case 0x00: ! 771: vbe_biosfn_return_controller_information(&AX,ES,DI); ! 772: break; ! 773: case 0x01: ! 774: vbe_biosfn_return_mode_information(&AX,CX,ES,DI); ! 775: break; ! 776: case 0x02: ! 777: vbe_biosfn_set_mode(&AX,BX,ES,DI); ! 778: break; ! 779: case 0x04: ! 780: vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX); ! 781: break; ! 782: case 0x09: ! 783: //FIXME ! 784: #ifdef DEBUG ! 785: unimplemented(); ! 786: #endif ! 787: // function failed ! 788: AX=0x100; ! 789: break; ! 790: case 0x0A: ! 791: //FIXME ! 792: #ifdef DEBUG ! 793: unimplemented(); ! 794: #endif ! 795: // function failed ! 796: AX=0x100; ! 797: break; ! 798: default: ! 799: #ifdef DEBUG ! 800: unknown(); ! 801: #endif ! 802: // function failed ! 803: AX=0x100; ! 804: } ! 805: } ! 806: else { ! 807: // No VBE display ! 808: AX=0x0100; ! 809: } ! 810: break; ! 811: #endif ! 812: ! 813: #ifdef DEBUG ! 814: default: ! 815: unknown(); ! 816: #endif ! 817: } ! 818: } ! 819: ! 820: // ============================================================================================ ! 821: // ! 822: // BIOS functions ! 823: // ! 824: // ============================================================================================ ! 825: ! 826: static void biosfn_set_video_mode(mode) Bit8u mode; ! 827: {// mode: Bit 7 is 1 if no clear screen ! 828: ! 829: // Should we clear the screen ? ! 830: Bit8u noclearmem=mode&0x80; ! 831: Bit8u line,mmask,*palette,vpti; ! 832: Bit16u i,twidth,theightm1,cheight; ! 833: Bit8u modeset_ctl,video_ctl,vga_switches; ! 834: Bit16u crtc_addr; ! 835: ! 836: #ifdef VBE ! 837: if (vbe_has_vbe_display()) { ! 838: dispi_set_enable(VBE_DISPI_DISABLED); ! 839: } ! 840: #endif // def VBE ! 841: ! 842: // The real mode ! 843: mode=mode&0x7f; ! 844: ! 845: // find the entry in the video modes ! 846: line=find_vga_entry(mode); ! 847: ! 848: #ifdef DEBUG ! 849: printf("mode search %02x found line %02x\n",mode,line); ! 850: #endif ! 851: ! 852: if(line==0xFF) ! 853: return; ! 854: ! 855: vpti=line_to_vpti[line]; ! 856: twidth=video_param_table[vpti].twidth; ! 857: theightm1=video_param_table[vpti].theightm1; ! 858: cheight=video_param_table[vpti].cheight; ! 859: ! 860: // Read the bios vga control ! 861: video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); ! 862: ! 863: // Read the bios vga switches ! 864: vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES); ! 865: ! 866: // Read the bios mode set control ! 867: modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); ! 868: ! 869: // Then we know the number of lines ! 870: // FIXME ! 871: ! 872: // if palette loading (bit 3 of modeset ctl = 0) ! 873: if((modeset_ctl&0x08)==0) ! 874: {// Set the PEL mask ! 875: outb(VGAREG_PEL_MASK,vga_modes[line].pelmask); ! 876: ! 877: // Set the whole dac always, from 0 ! 878: outb(VGAREG_DAC_WRITE_ADDRESS,0x00); ! 879: ! 880: // From which palette ! 881: switch(vga_modes[line].dacmodel) ! 882: {case 0: ! 883: palette=&palette0; ! 884: break; ! 885: case 1: ! 886: palette=&palette1; ! 887: break; ! 888: case 2: ! 889: palette=&palette2; ! 890: break; ! 891: case 3: ! 892: palette=&palette3; ! 893: break; ! 894: } ! 895: // Always 256*3 values ! 896: for(i=0;i<0x0100;i++) ! 897: {if(i<=dac_regs[vga_modes[line].dacmodel]) ! 898: {outb(VGAREG_DAC_DATA,palette[(i*3)+0]); ! 899: outb(VGAREG_DAC_DATA,palette[(i*3)+1]); ! 900: outb(VGAREG_DAC_DATA,palette[(i*3)+2]); ! 901: } ! 902: else ! 903: {outb(VGAREG_DAC_DATA,0); ! 904: outb(VGAREG_DAC_DATA,0); ! 905: outb(VGAREG_DAC_DATA,0); ! 906: } ! 907: } ! 908: if((modeset_ctl&0x02)==0x02) ! 909: { ! 910: biosfn_perform_gray_scale_summing(0x00, 0x100); ! 911: } ! 912: } ! 913: ! 914: // Reset Attribute Ctl flip-flop ! 915: inb(VGAREG_ACTL_RESET); ! 916: ! 917: // Set Attribute Ctl ! 918: for(i=0;i<=0x13;i++) ! 919: {outb(VGAREG_ACTL_ADDRESS,i); ! 920: outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]); ! 921: } ! 922: outb(VGAREG_ACTL_ADDRESS,0x14); ! 923: outb(VGAREG_ACTL_WRITE_DATA,0x00); ! 924: ! 925: // Set Sequencer Ctl ! 926: outb(VGAREG_SEQU_ADDRESS,0); ! 927: outb(VGAREG_SEQU_DATA,0x03); ! 928: for(i=1;i<=4;i++) ! 929: {outb(VGAREG_SEQU_ADDRESS,i); ! 930: outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]); ! 931: } ! 932: ! 933: // Set Grafx Ctl ! 934: for(i=0;i<=8;i++) ! 935: {outb(VGAREG_GRDC_ADDRESS,i); ! 936: outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]); ! 937: } ! 938: ! 939: // Set CRTC address VGA or MDA ! 940: crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; ! 941: ! 942: // Disable CRTC write protection ! 943: outw(crtc_addr,0x0011); ! 944: // Set CRTC regs ! 945: for(i=0;i<=0x18;i++) ! 946: {outb(crtc_addr,i); ! 947: outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]); ! 948: } ! 949: ! 950: // Set the misc register ! 951: outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg); ! 952: ! 953: // Enable video ! 954: outb(VGAREG_ACTL_ADDRESS,0x20); ! 955: inb(VGAREG_ACTL_RESET); ! 956: ! 957: if(noclearmem==0x00) ! 958: { ! 959: if(vga_modes[line].class==TEXT) ! 960: { ! 961: memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k ! 962: } ! 963: else ! 964: { ! 965: if(mode<0x0d) ! 966: { ! 967: memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k ! 968: } ! 969: else ! 970: { ! 971: outb( VGAREG_SEQU_ADDRESS, 0x02 ); ! 972: mmask = inb( VGAREG_SEQU_DATA ); ! 973: outb( VGAREG_SEQU_DATA, 0x0f ); // all planes ! 974: memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k ! 975: outb( VGAREG_SEQU_DATA, mmask ); ! 976: } ! 977: } ! 978: } ! 979: ! 980: // Set the BIOS mem ! 981: write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); ! 982: write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); ! 983: write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l); ! 984: write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); ! 985: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1); ! 986: write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); ! 987: write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem)); ! 988: write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); ! 989: write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); ! 990: ! 991: // FIXME We nearly have the good tables. to be reworked ! 992: write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now ! 993: write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table); ! 994: write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000); ! 995: ! 996: // FIXME ! 997: write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... ! 998: write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... ! 999: ! 1000: // Set cursor shape ! 1001: if(vga_modes[line].class==TEXT) ! 1002: { ! 1003: biosfn_set_cursor_shape(0x06,0x07); ! 1004: } ! 1005: ! 1006: // Set cursor pos for page 0..7 ! 1007: for(i=0;i<8;i++) ! 1008: biosfn_set_cursor_pos(i,0x0000); ! 1009: ! 1010: // Set active page 0 ! 1011: biosfn_set_active_page(0x00); ! 1012: ! 1013: // Write the fonts in memory ! 1014: if(vga_modes[line].class==TEXT) ! 1015: { ! 1016: ASM_START ! 1017: ;; copy and activate 8x16 font ! 1018: mov ax, #0x1104 ! 1019: mov bl, #0x00 ! 1020: int #0x10 ! 1021: mov ax, #0x1103 ! 1022: mov bl, #0x00 ! 1023: int #0x10 ! 1024: ASM_END ! 1025: } ! 1026: ! 1027: // Set the ints 0x1F and 0x43 ! 1028: ASM_START ! 1029: SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8) ! 1030: ASM_END ! 1031: ! 1032: switch(cheight) ! 1033: {case 8: ! 1034: ASM_START ! 1035: SET_INT_VECTOR(0x43, #0xC000, #_vgafont8) ! 1036: ASM_END ! 1037: break; ! 1038: case 14: ! 1039: ASM_START ! 1040: SET_INT_VECTOR(0x43, #0xC000, #_vgafont14) ! 1041: ASM_END ! 1042: break; ! 1043: case 16: ! 1044: ASM_START ! 1045: SET_INT_VECTOR(0x43, #0xC000, #_vgafont16) ! 1046: ASM_END ! 1047: break; ! 1048: } ! 1049: } ! 1050: ! 1051: // -------------------------------------------------------------------------------------------- ! 1052: static void biosfn_set_cursor_shape (CH,CL) ! 1053: Bit8u CH;Bit8u CL; ! 1054: {Bit16u cheight,curs,crtc_addr; ! 1055: Bit8u modeset_ctl; ! 1056: ! 1057: CH&=0x3f; ! 1058: CL&=0x1f; ! 1059: ! 1060: curs=(CH<<8)+CL; ! 1061: write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs); ! 1062: ! 1063: modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); ! 1064: cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); ! 1065: if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20)) ! 1066: { ! 1067: if(CL!=(CH+1)) ! 1068: { ! 1069: CH = ((CH+1) * cheight / 8) -1; ! 1070: } ! 1071: else ! 1072: { ! 1073: CH = ((CL+1) * cheight / 8) - 2; ! 1074: } ! 1075: CL = ((CL+1) * cheight / 8) - 1; ! 1076: } ! 1077: ! 1078: // CTRC regs 0x0a and 0x0b ! 1079: crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); ! 1080: outb(crtc_addr,0x0a); ! 1081: outb(crtc_addr+1,CH); ! 1082: outb(crtc_addr,0x0b); ! 1083: outb(crtc_addr+1,CL); ! 1084: } ! 1085: ! 1086: // -------------------------------------------------------------------------------------------- ! 1087: static void biosfn_set_cursor_pos (page, cursor) ! 1088: Bit8u page;Bit16u cursor; ! 1089: { ! 1090: Bit8u xcurs,ycurs,current; ! 1091: Bit16u nbcols,nbrows,address,crtc_addr; ! 1092: ! 1093: // Should not happen... ! 1094: if(page>7)return; ! 1095: ! 1096: // Bios cursor pos ! 1097: write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor); ! 1098: ! 1099: // Set the hardware cursor ! 1100: current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); ! 1101: if(page==current) ! 1102: { ! 1103: // Get the dimensions ! 1104: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1105: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1106: ! 1107: xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; ! 1108: ! 1109: // Calculate the address knowing nbcols nbrows and page num ! 1110: address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols; ! 1111: ! 1112: // CRTC regs 0x0e and 0x0f ! 1113: crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); ! 1114: outb(crtc_addr,0x0e); ! 1115: outb(crtc_addr+1,(address&0xff00)>>8); ! 1116: outb(crtc_addr,0x0f); ! 1117: outb(crtc_addr+1,address&0x00ff); ! 1118: } ! 1119: } ! 1120: ! 1121: // -------------------------------------------------------------------------------------------- ! 1122: static void biosfn_get_cursor_pos (page,shape, pos) ! 1123: Bit8u page;Bit16u *shape;Bit16u *pos; ! 1124: { ! 1125: Bit16u ss=get_SS(); ! 1126: ! 1127: // Default ! 1128: write_word(ss, shape, 0); ! 1129: write_word(ss, pos, 0); ! 1130: ! 1131: if(page>7)return; ! 1132: // FIXME should handle VGA 14/16 lines ! 1133: write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); ! 1134: write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2)); ! 1135: } ! 1136: ! 1137: // -------------------------------------------------------------------------------------------- ! 1138: static void biosfn_set_active_page (page) ! 1139: Bit8u page; ! 1140: { ! 1141: Bit16u cursor,dummy,crtc_addr; ! 1142: Bit16u nbcols,nbrows,address; ! 1143: Bit8u mode,line; ! 1144: ! 1145: if(page>7)return; ! 1146: ! 1147: // Get the mode ! 1148: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1149: line=find_vga_entry(mode); ! 1150: if(line==0xFF)return; ! 1151: ! 1152: // Get pos curs pos for the right page ! 1153: biosfn_get_cursor_pos(page,&dummy,&cursor); ! 1154: ! 1155: if(vga_modes[line].class==TEXT) ! 1156: { ! 1157: // Get the dimensions ! 1158: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1159: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1160: ! 1161: // Calculate the address knowing nbcols nbrows and page num ! 1162: address=SCREEN_MEM_START(nbcols,nbrows,page); ! 1163: write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address); ! 1164: ! 1165: // Start address ! 1166: address=SCREEN_IO_START(nbcols,nbrows,page); ! 1167: } ! 1168: else ! 1169: { ! 1170: address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l); ! 1171: } ! 1172: ! 1173: // CRTC regs 0x0c and 0x0d ! 1174: crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); ! 1175: outb(crtc_addr,0x0c); ! 1176: outb(crtc_addr+1,(address&0xff00)>>8); ! 1177: outb(crtc_addr,0x0d); ! 1178: outb(crtc_addr+1,address&0x00ff); ! 1179: ! 1180: // And change the BIOS page ! 1181: write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); ! 1182: ! 1183: #ifdef DEBUG ! 1184: printf("Set active page %02x address %04x\n",page,address); ! 1185: #endif ! 1186: ! 1187: // Display the cursor, now the page is active ! 1188: biosfn_set_cursor_pos(page,cursor); ! 1189: } ! 1190: ! 1191: // -------------------------------------------------------------------------------------------- ! 1192: static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight) ! 1193: Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight; ! 1194: { ! 1195: Bit16u src,dest; ! 1196: Bit8u i; ! 1197: ! 1198: src=ysrc*cheight*nbcols+xstart; ! 1199: dest=ydest*cheight*nbcols+xstart; ! 1200: outw(VGAREG_GRDC_ADDRESS, 0x0105); ! 1201: for(i=0;i<cheight;i++) ! 1202: { ! 1203: memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols); ! 1204: } ! 1205: outw(VGAREG_GRDC_ADDRESS, 0x0005); ! 1206: } ! 1207: ! 1208: // -------------------------------------------------------------------------------------------- ! 1209: static void vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr) ! 1210: Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr; ! 1211: { ! 1212: Bit16u dest; ! 1213: Bit8u i; ! 1214: ! 1215: dest=ystart*cheight*nbcols+xstart; ! 1216: outw(VGAREG_GRDC_ADDRESS, 0x0205); ! 1217: for(i=0;i<cheight;i++) ! 1218: { ! 1219: memsetb(0xa000,dest+i*nbcols,attr,cols); ! 1220: } ! 1221: outw(VGAREG_GRDC_ADDRESS, 0x0005); ! 1222: } ! 1223: ! 1224: // -------------------------------------------------------------------------------------------- ! 1225: static void vgamem_copy_cga(xstart,ysrc,ydest,cols,nbcols,cheight) ! 1226: Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight; ! 1227: { ! 1228: Bit16u src,dest; ! 1229: Bit8u i; ! 1230: ! 1231: src=((ysrc*cheight*nbcols)>>1)+xstart; ! 1232: dest=((ydest*cheight*nbcols)>>1)+xstart; ! 1233: for(i=0;i<cheight;i++) ! 1234: { ! 1235: if (i & 1) ! 1236: memcpyb(0xb800,0x2000+dest+(i>>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols); ! 1237: else ! 1238: memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols); ! 1239: } ! 1240: } ! 1241: ! 1242: // -------------------------------------------------------------------------------------------- ! 1243: static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr) ! 1244: Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr; ! 1245: { ! 1246: Bit16u dest; ! 1247: Bit8u i; ! 1248: ! 1249: dest=((ystart*cheight*nbcols)>>1)+xstart; ! 1250: for(i=0;i<cheight;i++) ! 1251: { ! 1252: if (i & 1) ! 1253: memsetb(0xb800,0x2000+dest+(i>>1)*nbcols,attr,cols); ! 1254: else ! 1255: memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols); ! 1256: } ! 1257: } ! 1258: ! 1259: // -------------------------------------------------------------------------------------------- ! 1260: static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir) ! 1261: Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir; ! 1262: { ! 1263: // page == 0xFF if current ! 1264: ! 1265: Bit8u mode,line,cheight,bpp,cols; ! 1266: Bit16u nbcols,nbrows,i; ! 1267: Bit16u address; ! 1268: ! 1269: if(rul>rlr)return; ! 1270: if(cul>clr)return; ! 1271: ! 1272: // Get the mode ! 1273: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1274: line=find_vga_entry(mode); ! 1275: if(line==0xFF)return; ! 1276: ! 1277: // Get the dimensions ! 1278: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1279: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1280: ! 1281: // Get the current page ! 1282: if(page==0xFF) ! 1283: page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); ! 1284: ! 1285: if(rlr>=nbrows)rlr=nbrows-1; ! 1286: if(clr>=nbcols)clr=nbcols-1; ! 1287: if(nblines>nbrows)nblines=0; ! 1288: cols=clr-cul+1; ! 1289: ! 1290: if(vga_modes[line].class==TEXT) ! 1291: { ! 1292: // Compute the address ! 1293: address=SCREEN_MEM_START(nbcols,nbrows,page); ! 1294: #ifdef DEBUG ! 1295: printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page); ! 1296: #endif ! 1297: ! 1298: if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) ! 1299: { ! 1300: memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols); ! 1301: } ! 1302: else ! 1303: {// if Scroll up ! 1304: if(dir==SCROLL_UP) ! 1305: {for(i=rul;i<=rlr;i++) ! 1306: { ! 1307: if((i+nblines>rlr)||(nblines==0)) ! 1308: memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols); ! 1309: else ! 1310: memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols); ! 1311: } ! 1312: } ! 1313: else ! 1314: {for(i=rlr;i>=rul;i--) ! 1315: { ! 1316: if((i<rul+nblines)||(nblines==0)) ! 1317: memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols); ! 1318: else ! 1319: memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols); ! 1320: if (i>rlr) break; ! 1321: } ! 1322: } ! 1323: } ! 1324: } ! 1325: else ! 1326: { ! 1327: // FIXME gfx mode not complete ! 1328: cheight=video_param_table[line_to_vpti[line]].cheight; ! 1329: switch(vga_modes[line].memmodel) ! 1330: { ! 1331: case PLANAR4: ! 1332: case PLANAR1: ! 1333: if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) ! 1334: { ! 1335: outw(VGAREG_GRDC_ADDRESS, 0x0205); ! 1336: memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight); ! 1337: outw(VGAREG_GRDC_ADDRESS, 0x0005); ! 1338: } ! 1339: else ! 1340: {// if Scroll up ! 1341: if(dir==SCROLL_UP) ! 1342: {for(i=rul;i<=rlr;i++) ! 1343: { ! 1344: if((i+nblines>rlr)||(nblines==0)) ! 1345: vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); ! 1346: else ! 1347: vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight); ! 1348: } ! 1349: } ! 1350: else ! 1351: {for(i=rlr;i>=rul;i--) ! 1352: { ! 1353: if((i<rul+nblines)||(nblines==0)) ! 1354: vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); ! 1355: else ! 1356: vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight); ! 1357: if (i>rlr) break; ! 1358: } ! 1359: } ! 1360: } ! 1361: break; ! 1362: case CGA: ! 1363: bpp=vga_modes[line].pixbits; ! 1364: if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) ! 1365: { ! 1366: memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp); ! 1367: } ! 1368: else ! 1369: { ! 1370: if(bpp==2) ! 1371: { ! 1372: cul<<=1; ! 1373: cols<<=1; ! 1374: nbcols<<=1; ! 1375: } ! 1376: // if Scroll up ! 1377: if(dir==SCROLL_UP) ! 1378: {for(i=rul;i<=rlr;i++) ! 1379: { ! 1380: if((i+nblines>rlr)||(nblines==0)) ! 1381: vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); ! 1382: else ! 1383: vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight); ! 1384: } ! 1385: } ! 1386: else ! 1387: {for(i=rlr;i>=rul;i--) ! 1388: { ! 1389: if((i<rul+nblines)||(nblines==0)) ! 1390: vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); ! 1391: else ! 1392: vgamem_copy_cga(cul,i,i-nblines,cols,nbcols,cheight); ! 1393: if (i>rlr) break; ! 1394: } ! 1395: } ! 1396: } ! 1397: break; ! 1398: #ifdef DEBUG ! 1399: default: ! 1400: printf("Scroll in graphics mode "); ! 1401: unimplemented(); ! 1402: #endif ! 1403: } ! 1404: } ! 1405: } ! 1406: ! 1407: // -------------------------------------------------------------------------------------------- ! 1408: static void biosfn_read_char_attr (page,car) ! 1409: Bit8u page;Bit16u *car; ! 1410: {Bit16u ss=get_SS(); ! 1411: Bit8u xcurs,ycurs,mode,line; ! 1412: Bit16u nbcols,nbrows,address; ! 1413: Bit16u cursor,dummy; ! 1414: ! 1415: // Get the mode ! 1416: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1417: line=find_vga_entry(mode); ! 1418: if(line==0xFF)return; ! 1419: ! 1420: // Get the cursor pos for the page ! 1421: biosfn_get_cursor_pos(page,&dummy,&cursor); ! 1422: xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; ! 1423: ! 1424: // Get the dimensions ! 1425: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1426: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1427: ! 1428: if(vga_modes[line].class==TEXT) ! 1429: { ! 1430: // Compute the address ! 1431: address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; ! 1432: ! 1433: write_word(ss,car,read_word(vga_modes[line].sstart,address)); ! 1434: } ! 1435: else ! 1436: { ! 1437: // FIXME gfx mode ! 1438: #ifdef DEBUG ! 1439: unimplemented(); ! 1440: #endif ! 1441: } ! 1442: } ! 1443: ! 1444: // -------------------------------------------------------------------------------------------- ! 1445: static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight) ! 1446: Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight; ! 1447: { ! 1448: Bit8u i,j,mask; ! 1449: Bit8u *fdata; ! 1450: Bit16u addr,dest,src; ! 1451: ! 1452: switch(cheight) ! 1453: {case 14: ! 1454: fdata = &vgafont14; ! 1455: break; ! 1456: case 16: ! 1457: fdata = &vgafont16; ! 1458: break; ! 1459: default: ! 1460: fdata = &vgafont8; ! 1461: } ! 1462: addr=xcurs+ycurs*cheight*nbcols; ! 1463: src = car * cheight; ! 1464: outw(VGAREG_SEQU_ADDRESS, 0x0f02); ! 1465: outw(VGAREG_GRDC_ADDRESS, 0x0205); ! 1466: if(attr&0x80) ! 1467: { ! 1468: outw(VGAREG_GRDC_ADDRESS, 0x1803); ! 1469: } ! 1470: else ! 1471: { ! 1472: outw(VGAREG_GRDC_ADDRESS, 0x0003); ! 1473: } ! 1474: for(i=0;i<cheight;i++) ! 1475: { ! 1476: dest=addr+i*nbcols; ! 1477: for(j=0;j<8;j++) ! 1478: { ! 1479: mask=0x80>>j; ! 1480: outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); ! 1481: read_byte(0xa000,dest); ! 1482: if(fdata[src+i]&mask) ! 1483: { ! 1484: write_byte(0xa000,dest,attr&0x0f); ! 1485: } ! 1486: else ! 1487: { ! 1488: write_byte(0xa000,dest,0x00); ! 1489: } ! 1490: } ! 1491: } ! 1492: ASM_START ! 1493: mov dx, # VGAREG_GRDC_ADDRESS ! 1494: mov ax, #0xff08 ! 1495: out dx, ax ! 1496: mov ax, #0x0005 ! 1497: out dx, ax ! 1498: mov ax, #0x0003 ! 1499: out dx, ax ! 1500: ASM_END ! 1501: } ! 1502: ! 1503: // -------------------------------------------------------------------------------------------- ! 1504: static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp) ! 1505: Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp; ! 1506: { ! 1507: Bit8u i,j,mask,data; ! 1508: Bit8u *fdata; ! 1509: Bit16u addr,dest,src; ! 1510: ! 1511: fdata = &vgafont8; ! 1512: addr=(xcurs*bpp)+ycurs*320; ! 1513: src = car * 8; ! 1514: for(i=0;i<8;i++) ! 1515: { ! 1516: dest=addr+(i>>1)*80; ! 1517: if (i & 1) dest += 0x2000; ! 1518: mask = 0x80; ! 1519: if (bpp == 1) ! 1520: { ! 1521: if (attr & 0x80) ! 1522: { ! 1523: data = read_byte(0xb800,dest); ! 1524: } ! 1525: else ! 1526: { ! 1527: data = 0x00; ! 1528: } ! 1529: for(j=0;j<8;j++) ! 1530: { ! 1531: if (fdata[src+i] & mask) ! 1532: { ! 1533: if (attr & 0x80) ! 1534: { ! 1535: data ^= (attr & 0x01) << (7-j); ! 1536: } ! 1537: else ! 1538: { ! 1539: data |= (attr & 0x01) << (7-j); ! 1540: } ! 1541: } ! 1542: mask >>= 1; ! 1543: } ! 1544: write_byte(0xb800,dest,data); ! 1545: } ! 1546: else ! 1547: { ! 1548: while (mask > 0) ! 1549: { ! 1550: if (attr & 0x80) ! 1551: { ! 1552: data = read_byte(0xb800,dest); ! 1553: } ! 1554: else ! 1555: { ! 1556: data = 0x00; ! 1557: } ! 1558: for(j=0;j<4;j++) ! 1559: { ! 1560: if (fdata[src+i] & mask) ! 1561: { ! 1562: if (attr & 0x80) ! 1563: { ! 1564: data ^= (attr & 0x03) << ((3-j)*2); ! 1565: } ! 1566: else ! 1567: { ! 1568: data |= (attr & 0x03) << ((3-j)*2); ! 1569: } ! 1570: } ! 1571: mask >>= 1; ! 1572: } ! 1573: write_byte(0xb800,dest,data); ! 1574: dest += 1; ! 1575: } ! 1576: } ! 1577: } ! 1578: } ! 1579: ! 1580: // -------------------------------------------------------------------------------------------- ! 1581: static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols) ! 1582: Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols; ! 1583: { ! 1584: Bit8u i,j,mask,data; ! 1585: Bit8u *fdata; ! 1586: Bit16u addr,dest,src; ! 1587: ! 1588: fdata = &vgafont8; ! 1589: addr=xcurs*8+ycurs*nbcols*64; ! 1590: src = car * 8; ! 1591: for(i=0;i<8;i++) ! 1592: { ! 1593: dest=addr+i*nbcols*8; ! 1594: mask = 0x80; ! 1595: for(j=0;j<8;j++) ! 1596: { ! 1597: data = 0x00; ! 1598: if (fdata[src+i] & mask) ! 1599: { ! 1600: data = attr; ! 1601: } ! 1602: write_byte(0xa000,dest+j,data); ! 1603: mask >>= 1; ! 1604: } ! 1605: } ! 1606: } ! 1607: ! 1608: // -------------------------------------------------------------------------------------------- ! 1609: static void biosfn_write_char_attr (car,page,attr,count) ! 1610: Bit8u car;Bit8u page;Bit8u attr;Bit16u count; ! 1611: { ! 1612: Bit8u cheight,xcurs,ycurs,mode,line,bpp; ! 1613: Bit16u nbcols,nbrows,address; ! 1614: Bit16u cursor,dummy; ! 1615: ! 1616: // Get the mode ! 1617: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1618: line=find_vga_entry(mode); ! 1619: if(line==0xFF)return; ! 1620: ! 1621: // Get the cursor pos for the page ! 1622: biosfn_get_cursor_pos(page,&dummy,&cursor); ! 1623: xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; ! 1624: ! 1625: // Get the dimensions ! 1626: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1627: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1628: ! 1629: if(vga_modes[line].class==TEXT) ! 1630: { ! 1631: // Compute the address ! 1632: address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; ! 1633: ! 1634: dummy=((Bit16u)attr<<8)+car; ! 1635: memsetw(vga_modes[line].sstart,address,dummy,count); ! 1636: } ! 1637: else ! 1638: { ! 1639: // FIXME gfx mode not complete ! 1640: cheight=video_param_table[line_to_vpti[line]].cheight; ! 1641: bpp=vga_modes[line].pixbits; ! 1642: while((count-->0) && (xcurs<nbcols)) ! 1643: { ! 1644: switch(vga_modes[line].memmodel) ! 1645: { ! 1646: case PLANAR4: ! 1647: case PLANAR1: ! 1648: write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); ! 1649: break; ! 1650: case CGA: ! 1651: write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); ! 1652: break; ! 1653: case LINEAR8: ! 1654: write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); ! 1655: break; ! 1656: #ifdef DEBUG ! 1657: default: ! 1658: unimplemented(); ! 1659: #endif ! 1660: } ! 1661: xcurs++; ! 1662: } ! 1663: } ! 1664: } ! 1665: ! 1666: // -------------------------------------------------------------------------------------------- ! 1667: static void biosfn_write_char_only (car,page,attr,count) ! 1668: Bit8u car;Bit8u page;Bit8u attr;Bit16u count; ! 1669: { ! 1670: Bit8u cheight,xcurs,ycurs,mode,line,bpp; ! 1671: Bit16u nbcols,nbrows,address; ! 1672: Bit16u cursor,dummy; ! 1673: ! 1674: // Get the mode ! 1675: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1676: line=find_vga_entry(mode); ! 1677: if(line==0xFF)return; ! 1678: ! 1679: // Get the cursor pos for the page ! 1680: biosfn_get_cursor_pos(page,&dummy,&cursor); ! 1681: xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; ! 1682: ! 1683: // Get the dimensions ! 1684: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1685: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1686: ! 1687: if(vga_modes[line].class==TEXT) ! 1688: { ! 1689: // Compute the address ! 1690: address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; ! 1691: ! 1692: while(count-->0) ! 1693: {write_byte(vga_modes[line].sstart,address,car); ! 1694: address+=2; ! 1695: } ! 1696: } ! 1697: else ! 1698: { ! 1699: // FIXME gfx mode not complete ! 1700: cheight=video_param_table[line_to_vpti[line]].cheight; ! 1701: bpp=vga_modes[line].pixbits; ! 1702: while((count-->0) && (xcurs<nbcols)) ! 1703: { ! 1704: switch(vga_modes[line].memmodel) ! 1705: { ! 1706: case PLANAR4: ! 1707: case PLANAR1: ! 1708: write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); ! 1709: break; ! 1710: case CGA: ! 1711: write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); ! 1712: break; ! 1713: case LINEAR8: ! 1714: write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); ! 1715: break; ! 1716: #ifdef DEBUG ! 1717: default: ! 1718: unimplemented(); ! 1719: #endif ! 1720: } ! 1721: xcurs++; ! 1722: } ! 1723: } ! 1724: } ! 1725: ! 1726: // -------------------------------------------------------------------------------------------- ! 1727: ASM_START ! 1728: biosfn_group_0B: ! 1729: cmp bh, #0x00 ! 1730: je biosfn_set_border_color ! 1731: cmp bh, #0x01 ! 1732: je biosfn_set_palette ! 1733: #ifdef DEBUG ! 1734: call _unknown ! 1735: #endif ! 1736: ret ! 1737: biosfn_set_border_color: ! 1738: push ax ! 1739: push bx ! 1740: push cx ! 1741: push dx ! 1742: mov dx, # VGAREG_ACTL_RESET ! 1743: in al, dx ! 1744: mov dx, # VGAREG_ACTL_ADDRESS ! 1745: mov al, #0x00 ! 1746: out dx, al ! 1747: mov al, bl ! 1748: and al, #0x0f ! 1749: test al, #0x08 ! 1750: jz set_low_border ! 1751: add al, #0x08 ! 1752: set_low_border: ! 1753: out dx, al ! 1754: mov cl, #0x01 ! 1755: and bl, #0x10 ! 1756: set_intensity_loop: ! 1757: mov dx, # VGAREG_ACTL_ADDRESS ! 1758: mov al, cl ! 1759: out dx, al ! 1760: mov dx, # VGAREG_ACTL_READ_DATA ! 1761: in al, dx ! 1762: and al, #0xef ! 1763: or al, bl ! 1764: mov dx, # VGAREG_ACTL_ADDRESS ! 1765: out dx, al ! 1766: inc cl ! 1767: cmp cl, #0x04 ! 1768: jne set_intensity_loop ! 1769: mov al, #0x20 ! 1770: out dx, al ! 1771: pop dx ! 1772: pop cx ! 1773: pop bx ! 1774: pop ax ! 1775: ret ! 1776: biosfn_set_palette: ! 1777: push ax ! 1778: push bx ! 1779: push cx ! 1780: push dx ! 1781: mov dx, # VGAREG_ACTL_RESET ! 1782: in al, dx ! 1783: mov cl, #0x01 ! 1784: and bl, #0x01 ! 1785: set_cga_palette_loop: ! 1786: mov dx, # VGAREG_ACTL_ADDRESS ! 1787: mov al, cl ! 1788: out dx, al ! 1789: mov dx, # VGAREG_ACTL_READ_DATA ! 1790: in al, dx ! 1791: and al, #0xfe ! 1792: or al, bl ! 1793: mov dx, # VGAREG_ACTL_ADDRESS ! 1794: out dx, al ! 1795: inc cl ! 1796: cmp cl, #0x04 ! 1797: jne set_cga_palette_loop ! 1798: mov al, #0x20 ! 1799: out dx, al ! 1800: pop dx ! 1801: pop cx ! 1802: pop bx ! 1803: pop ax ! 1804: ret ! 1805: ASM_END ! 1806: ! 1807: // -------------------------------------------------------------------------------------------- ! 1808: static void biosfn_write_pixel (BH,AL,CX,DX) Bit8u BH;Bit8u AL;Bit16u CX;Bit16u DX; ! 1809: { ! 1810: Bit8u mode,line,mask,attr,data; ! 1811: Bit16u addr; ! 1812: ! 1813: // Get the mode ! 1814: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1815: line=find_vga_entry(mode); ! 1816: if(line==0xFF)return; ! 1817: if(vga_modes[line].class==TEXT)return; ! 1818: ! 1819: switch(vga_modes[line].memmodel) ! 1820: { ! 1821: case PLANAR4: ! 1822: case PLANAR1: ! 1823: addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1824: mask = 0x80 >> (CX & 0x07); ! 1825: outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); ! 1826: outw(VGAREG_GRDC_ADDRESS, 0x0205); ! 1827: data = read_byte(0xa000,addr); ! 1828: if (AL & 0x80) ! 1829: { ! 1830: outw(VGAREG_GRDC_ADDRESS, 0x1803); ! 1831: } ! 1832: write_byte(0xa000,addr,AL); ! 1833: ASM_START ! 1834: mov dx, # VGAREG_GRDC_ADDRESS ! 1835: mov ax, #0xff08 ! 1836: out dx, ax ! 1837: mov ax, #0x0005 ! 1838: out dx, ax ! 1839: mov ax, #0x0003 ! 1840: out dx, ax ! 1841: ASM_END ! 1842: break; ! 1843: case CGA: ! 1844: if(vga_modes[line].pixbits==2) ! 1845: { ! 1846: addr=(CX>>2)+(DX>>1)*80; ! 1847: } ! 1848: else ! 1849: { ! 1850: addr=(CX>>3)+(DX>>1)*80; ! 1851: } ! 1852: if (DX & 1) addr += 0x2000; ! 1853: data = read_byte(0xb800,addr); ! 1854: if(vga_modes[line].pixbits==2) ! 1855: { ! 1856: attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); ! 1857: mask = 0x03 << ((3 - (CX & 0x03)) * 2); ! 1858: } ! 1859: else ! 1860: { ! 1861: attr = (AL & 0x01) << (7 - (CX & 0x07)); ! 1862: mask = 0x01 << (7 - (CX & 0x07)); ! 1863: } ! 1864: if (AL & 0x80) ! 1865: { ! 1866: data ^= attr; ! 1867: } ! 1868: else ! 1869: { ! 1870: data &= ~mask; ! 1871: data |= attr; ! 1872: } ! 1873: write_byte(0xb800,addr,data); ! 1874: break; ! 1875: case LINEAR8: ! 1876: addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); ! 1877: write_byte(0xa000,addr,AL); ! 1878: break; ! 1879: #ifdef DEBUG ! 1880: default: ! 1881: unimplemented(); ! 1882: #endif ! 1883: } ! 1884: } ! 1885: ! 1886: // -------------------------------------------------------------------------------------------- ! 1887: static void biosfn_read_pixel (BH,CX,DX,AX) Bit8u BH;Bit16u CX;Bit16u DX;Bit16u *AX; ! 1888: { ! 1889: Bit8u mode,line,mask,attr,data,i; ! 1890: Bit16u addr; ! 1891: Bit16u ss=get_SS(); ! 1892: ! 1893: // Get the mode ! 1894: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1895: line=find_vga_entry(mode); ! 1896: if(line==0xFF)return; ! 1897: if(vga_modes[line].class==TEXT)return; ! 1898: ! 1899: switch(vga_modes[line].memmodel) ! 1900: { ! 1901: case PLANAR4: ! 1902: case PLANAR1: ! 1903: addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1904: mask = 0x80 >> (CX & 0x07); ! 1905: attr = 0x00; ! 1906: for(i=0;i<4;i++) ! 1907: { ! 1908: outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04); ! 1909: data = read_byte(0xa000,addr) & mask; ! 1910: if (data > 0) attr |= (0x01 << i); ! 1911: } ! 1912: break; ! 1913: case CGA: ! 1914: addr=(CX>>2)+(DX>>1)*80; ! 1915: if (DX & 1) addr += 0x2000; ! 1916: data = read_byte(0xb800,addr); ! 1917: if(vga_modes[line].pixbits==2) ! 1918: { ! 1919: attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03; ! 1920: } ! 1921: else ! 1922: { ! 1923: attr = (data >> (7 - (CX & 0x07))) & 0x01; ! 1924: } ! 1925: break; ! 1926: case LINEAR8: ! 1927: addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); ! 1928: attr=read_byte(0xa000,addr); ! 1929: break; ! 1930: default: ! 1931: #ifdef DEBUG ! 1932: unimplemented(); ! 1933: #endif ! 1934: attr = 0; ! 1935: } ! 1936: write_word(ss,AX,(read_word(ss,AX) & 0xff00) | attr); ! 1937: } ! 1938: ! 1939: // -------------------------------------------------------------------------------------------- ! 1940: static void biosfn_write_teletype (car, page, attr, flag) ! 1941: Bit8u car;Bit8u page;Bit8u attr;Bit8u flag; ! 1942: {// flag = WITH_ATTR / NO_ATTR ! 1943: ! 1944: Bit8u cheight,xcurs,ycurs,mode,line,bpp; ! 1945: Bit16u nbcols,nbrows,address; ! 1946: Bit16u cursor,dummy; ! 1947: ! 1948: // special case if page is 0xff, use current page ! 1949: if(page==0xff) ! 1950: page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); ! 1951: ! 1952: // Get the mode ! 1953: mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); ! 1954: line=find_vga_entry(mode); ! 1955: if(line==0xFF)return; ! 1956: ! 1957: // Get the cursor pos for the page ! 1958: biosfn_get_cursor_pos(page,&dummy,&cursor); ! 1959: xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; ! 1960: ! 1961: // Get the dimensions ! 1962: nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; ! 1963: nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 1964: ! 1965: switch(car) ! 1966: { ! 1967: case 7: ! 1968: //FIXME should beep ! 1969: break; ! 1970: ! 1971: case 8: ! 1972: if(xcurs>0)xcurs--; ! 1973: break; ! 1974: ! 1975: case '\r': ! 1976: xcurs=0; ! 1977: break; ! 1978: ! 1979: case '\n': ! 1980: ycurs++; ! 1981: break; ! 1982: ! 1983: case '\t': ! 1984: do ! 1985: { ! 1986: biosfn_write_teletype(' ',page,attr,flag); ! 1987: biosfn_get_cursor_pos(page,&dummy,&cursor); ! 1988: xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; ! 1989: }while(xcurs%8==0); ! 1990: break; ! 1991: ! 1992: default: ! 1993: ! 1994: if(vga_modes[line].class==TEXT) ! 1995: { ! 1996: // Compute the address ! 1997: address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; ! 1998: ! 1999: // Write the char ! 2000: write_byte(vga_modes[line].sstart,address,car); ! 2001: ! 2002: if(flag==WITH_ATTR) ! 2003: write_byte(vga_modes[line].sstart,address+1,attr); ! 2004: } ! 2005: else ! 2006: { ! 2007: // FIXME gfx mode not complete ! 2008: cheight=video_param_table[line_to_vpti[line]].cheight; ! 2009: bpp=vga_modes[line].pixbits; ! 2010: switch(vga_modes[line].memmodel) ! 2011: { ! 2012: case PLANAR4: ! 2013: case PLANAR1: ! 2014: write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); ! 2015: break; ! 2016: case CGA: ! 2017: write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); ! 2018: break; ! 2019: case LINEAR8: ! 2020: write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); ! 2021: break; ! 2022: #ifdef DEBUG ! 2023: default: ! 2024: unimplemented(); ! 2025: #endif ! 2026: } ! 2027: } ! 2028: xcurs++; ! 2029: } ! 2030: ! 2031: // Do we need to wrap ? ! 2032: if(xcurs==nbcols) ! 2033: {xcurs=0; ! 2034: ycurs++; ! 2035: } ! 2036: ! 2037: // Do we need to scroll ? ! 2038: if(ycurs==nbrows) ! 2039: { ! 2040: if(vga_modes[line].class==TEXT) ! 2041: { ! 2042: biosfn_scroll(0x01,0x07,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); ! 2043: } ! 2044: else ! 2045: { ! 2046: biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); ! 2047: } ! 2048: ycurs-=1; ! 2049: } ! 2050: ! 2051: // Set the cursor for the page ! 2052: cursor=ycurs; cursor<<=8; cursor+=xcurs; ! 2053: biosfn_set_cursor_pos(page,cursor); ! 2054: } ! 2055: ! 2056: // -------------------------------------------------------------------------------------------- ! 2057: ASM_START ! 2058: biosfn_get_video_mode: ! 2059: push ds ! 2060: mov ax, # BIOSMEM_SEG ! 2061: mov ds, ax ! 2062: push bx ! 2063: mov bx, # BIOSMEM_CURRENT_PAGE ! 2064: mov al, [bx] ! 2065: pop bx ! 2066: mov bh, al ! 2067: push bx ! 2068: mov bx, # BIOSMEM_VIDEO_CTL ! 2069: mov ah, [bx] ! 2070: and ah, #0x80 ! 2071: mov bx, # BIOSMEM_CURRENT_MODE ! 2072: mov al, [bx] ! 2073: or al, ah ! 2074: mov bx, # BIOSMEM_NB_COLS ! 2075: mov ah, [bx] ! 2076: pop bx ! 2077: pop ds ! 2078: ret ! 2079: ASM_END ! 2080: ! 2081: // -------------------------------------------------------------------------------------------- ! 2082: ASM_START ! 2083: biosfn_group_10: ! 2084: cmp al, #0x00 ! 2085: jne int10_test_1001 ! 2086: jmp biosfn_set_single_palette_reg ! 2087: int10_test_1001: ! 2088: cmp al, #0x01 ! 2089: jne int10_test_1002 ! 2090: jmp biosfn_set_overscan_border_color ! 2091: int10_test_1002: ! 2092: cmp al, #0x02 ! 2093: jne int10_test_1003 ! 2094: jmp biosfn_set_all_palette_reg ! 2095: int10_test_1003: ! 2096: cmp al, #0x03 ! 2097: jne int10_test_1007 ! 2098: jmp biosfn_toggle_intensity ! 2099: int10_test_1007: ! 2100: cmp al, #0x07 ! 2101: jne int10_test_1008 ! 2102: jmp biosfn_get_single_palette_reg ! 2103: int10_test_1008: ! 2104: cmp al, #0x08 ! 2105: jne int10_test_1009 ! 2106: jmp biosfn_read_overscan_border_color ! 2107: int10_test_1009: ! 2108: cmp al, #0x09 ! 2109: jne int10_test_1010 ! 2110: jmp biosfn_get_all_palette_reg ! 2111: int10_test_1010: ! 2112: cmp al, #0x10 ! 2113: jne int10_test_1012 ! 2114: jmp biosfn_set_single_dac_reg ! 2115: int10_test_1012: ! 2116: cmp al, #0x12 ! 2117: jne int10_test_1013 ! 2118: jmp biosfn_set_all_dac_reg ! 2119: int10_test_1013: ! 2120: cmp al, #0x13 ! 2121: jne int10_test_1015 ! 2122: jmp biosfn_select_video_dac_color_page ! 2123: int10_test_1015: ! 2124: cmp al, #0x15 ! 2125: jne int10_test_1017 ! 2126: jmp biosfn_read_single_dac_reg ! 2127: int10_test_1017: ! 2128: cmp al, #0x17 ! 2129: jne int10_test_1018 ! 2130: jmp biosfn_read_all_dac_reg ! 2131: int10_test_1018: ! 2132: cmp al, #0x18 ! 2133: jne int10_test_1019 ! 2134: jmp biosfn_set_pel_mask ! 2135: int10_test_1019: ! 2136: cmp al, #0x19 ! 2137: jne int10_test_101A ! 2138: jmp biosfn_read_pel_mask ! 2139: int10_test_101A: ! 2140: cmp al, #0x1a ! 2141: jne int10_group_10_unknown ! 2142: jmp biosfn_read_video_dac_state ! 2143: int10_group_10_unknown: ! 2144: #ifdef DEBUG ! 2145: call _unknown ! 2146: #endif ! 2147: ret ! 2148: ! 2149: biosfn_set_single_palette_reg: ! 2150: cmp bl, #0x14 ! 2151: ja no_actl_reg1 ! 2152: push ax ! 2153: push dx ! 2154: mov dx, # VGAREG_ACTL_RESET ! 2155: in al, dx ! 2156: mov dx, # VGAREG_ACTL_ADDRESS ! 2157: mov al, bl ! 2158: out dx, al ! 2159: mov al, bh ! 2160: out dx, al ! 2161: mov al, #0x20 ! 2162: out dx, al ! 2163: pop dx ! 2164: pop ax ! 2165: no_actl_reg1: ! 2166: ret ! 2167: ASM_END ! 2168: ! 2169: // -------------------------------------------------------------------------------------------- ! 2170: ASM_START ! 2171: biosfn_set_overscan_border_color: ! 2172: push bx ! 2173: mov bl, #0x11 ! 2174: call biosfn_set_single_palette_reg ! 2175: pop bx ! 2176: ret ! 2177: ASM_END ! 2178: ! 2179: // -------------------------------------------------------------------------------------------- ! 2180: ASM_START ! 2181: biosfn_set_all_palette_reg: ! 2182: push ax ! 2183: push bx ! 2184: push cx ! 2185: push dx ! 2186: mov bx, dx ! 2187: mov dx, # VGAREG_ACTL_RESET ! 2188: in al, dx ! 2189: mov cl, #0x00 ! 2190: mov dx, # VGAREG_ACTL_ADDRESS ! 2191: set_palette_loop: ! 2192: mov al, cl ! 2193: out dx, al ! 2194: seg es ! 2195: mov al, [bx] ! 2196: out dx, al ! 2197: inc bx ! 2198: inc cl ! 2199: cmp cl, #0x10 ! 2200: jne set_palette_loop ! 2201: mov al, #0x11 ! 2202: out dx, al ! 2203: seg es ! 2204: mov al, [bx] ! 2205: out dx, al ! 2206: mov al, #0x20 ! 2207: out dx, al ! 2208: pop dx ! 2209: pop cx ! 2210: pop bx ! 2211: pop ax ! 2212: ret ! 2213: ASM_END ! 2214: ! 2215: // -------------------------------------------------------------------------------------------- ! 2216: ASM_START ! 2217: biosfn_toggle_intensity: ! 2218: push ax ! 2219: push bx ! 2220: push dx ! 2221: mov dx, # VGAREG_ACTL_RESET ! 2222: in al, dx ! 2223: mov dx, # VGAREG_ACTL_ADDRESS ! 2224: mov al, #0x10 ! 2225: out dx, al ! 2226: mov dx, # VGAREG_ACTL_READ_DATA ! 2227: in al, dx ! 2228: and al, #0xf7 ! 2229: and bl, #0x01 ! 2230: shl bl, 3 ! 2231: or al, bl ! 2232: mov dx, # VGAREG_ACTL_ADDRESS ! 2233: out dx, al ! 2234: mov al, #0x20 ! 2235: out dx, al ! 2236: pop dx ! 2237: pop bx ! 2238: pop ax ! 2239: ret ! 2240: ASM_END ! 2241: ! 2242: // -------------------------------------------------------------------------------------------- ! 2243: ASM_START ! 2244: biosfn_get_single_palette_reg: ! 2245: cmp bl, #0x14 ! 2246: ja no_actl_reg2 ! 2247: push ax ! 2248: push dx ! 2249: mov dx, # VGAREG_ACTL_RESET ! 2250: in al, dx ! 2251: mov dx, # VGAREG_ACTL_ADDRESS ! 2252: mov al, bl ! 2253: out dx, al ! 2254: mov dx, # VGAREG_ACTL_READ_DATA ! 2255: in al, dx ! 2256: mov bh, al ! 2257: mov dx, # VGAREG_ACTL_RESET ! 2258: in al, dx ! 2259: mov dx, # VGAREG_ACTL_ADDRESS ! 2260: mov al, #0x20 ! 2261: out dx, al ! 2262: pop dx ! 2263: pop ax ! 2264: no_actl_reg2: ! 2265: ret ! 2266: ASM_END ! 2267: ! 2268: // -------------------------------------------------------------------------------------------- ! 2269: ASM_START ! 2270: biosfn_read_overscan_border_color: ! 2271: push ax ! 2272: push bx ! 2273: mov bl, #0x11 ! 2274: call biosfn_get_single_palette_reg ! 2275: mov al, bh ! 2276: pop bx ! 2277: mov bh, al ! 2278: pop ax ! 2279: ret ! 2280: ASM_END ! 2281: ! 2282: // -------------------------------------------------------------------------------------------- ! 2283: ASM_START ! 2284: biosfn_get_all_palette_reg: ! 2285: push ax ! 2286: push bx ! 2287: push cx ! 2288: push dx ! 2289: mov bx, dx ! 2290: mov cl, #0x00 ! 2291: get_palette_loop: ! 2292: mov dx, # VGAREG_ACTL_RESET ! 2293: in al, dx ! 2294: mov dx, # VGAREG_ACTL_ADDRESS ! 2295: mov al, cl ! 2296: out dx, al ! 2297: mov dx, # VGAREG_ACTL_READ_DATA ! 2298: in al, dx ! 2299: seg es ! 2300: mov [bx], al ! 2301: inc bx ! 2302: inc cl ! 2303: cmp cl, #0x10 ! 2304: jne get_palette_loop ! 2305: mov dx, # VGAREG_ACTL_RESET ! 2306: in al, dx ! 2307: mov dx, # VGAREG_ACTL_ADDRESS ! 2308: mov al, #0x11 ! 2309: out dx, al ! 2310: mov dx, # VGAREG_ACTL_READ_DATA ! 2311: in al, dx ! 2312: seg es ! 2313: mov [bx], al ! 2314: mov dx, # VGAREG_ACTL_RESET ! 2315: in al, dx ! 2316: mov dx, # VGAREG_ACTL_ADDRESS ! 2317: mov al, #0x20 ! 2318: out dx, al ! 2319: pop dx ! 2320: pop cx ! 2321: pop bx ! 2322: pop ax ! 2323: ret ! 2324: ASM_END ! 2325: ! 2326: // -------------------------------------------------------------------------------------------- ! 2327: ASM_START ! 2328: biosfn_set_single_dac_reg: ! 2329: push ax ! 2330: push dx ! 2331: mov dx, # VGAREG_DAC_WRITE_ADDRESS ! 2332: mov al, bl ! 2333: out dx, al ! 2334: mov dx, # VGAREG_DAC_DATA ! 2335: pop ax ! 2336: push ax ! 2337: mov al, ah ! 2338: out dx, al ! 2339: mov al, ch ! 2340: out dx, al ! 2341: mov al, cl ! 2342: out dx, al ! 2343: pop dx ! 2344: pop ax ! 2345: ret ! 2346: ASM_END ! 2347: ! 2348: // -------------------------------------------------------------------------------------------- ! 2349: ASM_START ! 2350: biosfn_set_all_dac_reg: ! 2351: push ax ! 2352: push bx ! 2353: push cx ! 2354: push dx ! 2355: mov dx, # VGAREG_DAC_WRITE_ADDRESS ! 2356: mov al, bl ! 2357: out dx, al ! 2358: pop dx ! 2359: push dx ! 2360: mov bx, dx ! 2361: mov dx, # VGAREG_DAC_DATA ! 2362: set_dac_loop: ! 2363: seg es ! 2364: mov al, [bx] ! 2365: out dx, al ! 2366: inc bx ! 2367: seg es ! 2368: mov al, [bx] ! 2369: out dx, al ! 2370: inc bx ! 2371: seg es ! 2372: mov al, [bx] ! 2373: out dx, al ! 2374: inc bx ! 2375: dec cx ! 2376: jnz set_dac_loop ! 2377: pop dx ! 2378: pop cx ! 2379: pop bx ! 2380: pop ax ! 2381: ret ! 2382: ASM_END ! 2383: ! 2384: // -------------------------------------------------------------------------------------------- ! 2385: ASM_START ! 2386: biosfn_select_video_dac_color_page: ! 2387: push ax ! 2388: push bx ! 2389: push dx ! 2390: mov dx, # VGAREG_ACTL_RESET ! 2391: in al, dx ! 2392: mov dx, # VGAREG_ACTL_ADDRESS ! 2393: mov al, #0x10 ! 2394: out dx, al ! 2395: mov dx, # VGAREG_ACTL_READ_DATA ! 2396: in al, dx ! 2397: and bl, #0x01 ! 2398: jnz set_dac_page ! 2399: and al, #0x7f ! 2400: shl bh, 7 ! 2401: or al, bh ! 2402: mov dx, # VGAREG_ACTL_ADDRESS ! 2403: out dx, al ! 2404: jmp set_actl_normal ! 2405: set_dac_page: ! 2406: push ax ! 2407: mov dx, # VGAREG_ACTL_RESET ! 2408: in al, dx ! 2409: mov dx, # VGAREG_ACTL_ADDRESS ! 2410: mov al, #0x14 ! 2411: out dx, al ! 2412: pop ax ! 2413: and al, #0x80 ! 2414: jnz set_dac_16_page ! 2415: shl bh, 2 ! 2416: set_dac_16_page: ! 2417: and bh, #0x0f ! 2418: mov al, bh ! 2419: out dx, al ! 2420: set_actl_normal: ! 2421: mov al, #0x20 ! 2422: out dx, al ! 2423: pop dx ! 2424: pop bx ! 2425: pop ax ! 2426: ret ! 2427: ASM_END ! 2428: ! 2429: // -------------------------------------------------------------------------------------------- ! 2430: ASM_START ! 2431: biosfn_read_single_dac_reg: ! 2432: push ax ! 2433: push dx ! 2434: mov dx, # VGAREG_DAC_READ_ADDRESS ! 2435: mov al, bl ! 2436: out dx, al ! 2437: pop ax ! 2438: mov ah, al ! 2439: mov dx, # VGAREG_DAC_DATA ! 2440: in al, dx ! 2441: xchg al, ah ! 2442: push ax ! 2443: in al, dx ! 2444: mov ch, al ! 2445: in al, dx ! 2446: mov cl, al ! 2447: pop dx ! 2448: pop ax ! 2449: ret ! 2450: ASM_END ! 2451: ! 2452: // -------------------------------------------------------------------------------------------- ! 2453: ASM_START ! 2454: biosfn_read_all_dac_reg: ! 2455: push ax ! 2456: push bx ! 2457: push cx ! 2458: push dx ! 2459: mov dx, # VGAREG_DAC_READ_ADDRESS ! 2460: mov al, bl ! 2461: out dx, al ! 2462: pop dx ! 2463: push dx ! 2464: mov bx, dx ! 2465: mov dx, # VGAREG_DAC_DATA ! 2466: read_dac_loop: ! 2467: in al, dx ! 2468: seg es ! 2469: mov [bx], al ! 2470: inc bx ! 2471: in al, dx ! 2472: seg es ! 2473: mov [bx], al ! 2474: inc bx ! 2475: in al, dx ! 2476: seg es ! 2477: mov [bx], al ! 2478: inc bx ! 2479: dec cx ! 2480: jnz read_dac_loop ! 2481: pop dx ! 2482: pop cx ! 2483: pop bx ! 2484: pop ax ! 2485: ret ! 2486: ASM_END ! 2487: ! 2488: // -------------------------------------------------------------------------------------------- ! 2489: ASM_START ! 2490: biosfn_set_pel_mask: ! 2491: push ax ! 2492: push dx ! 2493: mov dx, # VGAREG_PEL_MASK ! 2494: mov al, bl ! 2495: out dx, al ! 2496: pop dx ! 2497: pop ax ! 2498: ret ! 2499: ASM_END ! 2500: ! 2501: // -------------------------------------------------------------------------------------------- ! 2502: ASM_START ! 2503: biosfn_read_pel_mask: ! 2504: push ax ! 2505: push dx ! 2506: mov dx, # VGAREG_PEL_MASK ! 2507: in al, dx ! 2508: mov bl, al ! 2509: pop dx ! 2510: pop ax ! 2511: ret ! 2512: ASM_END ! 2513: ! 2514: // -------------------------------------------------------------------------------------------- ! 2515: ASM_START ! 2516: biosfn_read_video_dac_state: ! 2517: push ax ! 2518: push dx ! 2519: mov dx, # VGAREG_ACTL_RESET ! 2520: in al, dx ! 2521: mov dx, # VGAREG_ACTL_ADDRESS ! 2522: mov al, #0x10 ! 2523: out dx, al ! 2524: mov dx, # VGAREG_ACTL_READ_DATA ! 2525: in al, dx ! 2526: mov bl, al ! 2527: shr bl, 7 ! 2528: mov dx, # VGAREG_ACTL_RESET ! 2529: in al, dx ! 2530: mov dx, # VGAREG_ACTL_ADDRESS ! 2531: mov al, #0x14 ! 2532: out dx, al ! 2533: mov dx, # VGAREG_ACTL_READ_DATA ! 2534: in al, dx ! 2535: mov bh, al ! 2536: and bh, #0x0f ! 2537: test bl, #0x01 ! 2538: jnz get_dac_16_page ! 2539: shr bh, 2 ! 2540: get_dac_16_page: ! 2541: mov dx, # VGAREG_ACTL_RESET ! 2542: in al, dx ! 2543: mov dx, # VGAREG_ACTL_ADDRESS ! 2544: mov al, #0x20 ! 2545: out dx, al ! 2546: pop dx ! 2547: pop ax ! 2548: ret ! 2549: ASM_END ! 2550: ! 2551: // -------------------------------------------------------------------------------------------- ! 2552: static void biosfn_perform_gray_scale_summing (start,count) ! 2553: Bit16u start;Bit16u count; ! 2554: {Bit8u r,g,b; ! 2555: Bit16u i; ! 2556: Bit16u index; ! 2557: ! 2558: inb(VGAREG_ACTL_RESET); ! 2559: outb(VGAREG_ACTL_ADDRESS,0x00); ! 2560: ! 2561: for( index = 0; index < count; index++ ) ! 2562: { ! 2563: // set read address and switch to read mode ! 2564: outb(VGAREG_DAC_READ_ADDRESS,start); ! 2565: // get 6-bit wide RGB data values ! 2566: r=inb( VGAREG_DAC_DATA ); ! 2567: g=inb( VGAREG_DAC_DATA ); ! 2568: b=inb( VGAREG_DAC_DATA ); ! 2569: ! 2570: // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue ) ! 2571: i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8; ! 2572: ! 2573: if(i>0x3f)i=0x3f; ! 2574: ! 2575: // set write address and switch to write mode ! 2576: outb(VGAREG_DAC_WRITE_ADDRESS,start); ! 2577: // write new intensity value ! 2578: outb( VGAREG_DAC_DATA, i&0xff ); ! 2579: outb( VGAREG_DAC_DATA, i&0xff ); ! 2580: outb( VGAREG_DAC_DATA, i&0xff ); ! 2581: start++; ! 2582: } ! 2583: inb(VGAREG_ACTL_RESET); ! 2584: outb(VGAREG_ACTL_ADDRESS,0x20); ! 2585: } ! 2586: ! 2587: // -------------------------------------------------------------------------------------------- ! 2588: static void get_font_access() ! 2589: { ! 2590: ASM_START ! 2591: mov dx, # VGAREG_SEQU_ADDRESS ! 2592: mov ax, #0x0100 ! 2593: out dx, ax ! 2594: mov ax, #0x0402 ! 2595: out dx, ax ! 2596: mov ax, #0x0704 ! 2597: out dx, ax ! 2598: mov ax, #0x0300 ! 2599: out dx, ax ! 2600: mov dx, # VGAREG_GRDC_ADDRESS ! 2601: mov ax, #0x0204 ! 2602: out dx, ax ! 2603: mov ax, #0x0005 ! 2604: out dx, ax ! 2605: mov ax, #0x0406 ! 2606: out dx, ax ! 2607: ASM_END ! 2608: } ! 2609: ! 2610: static void release_font_access() ! 2611: { ! 2612: ASM_START ! 2613: mov dx, # VGAREG_SEQU_ADDRESS ! 2614: mov ax, #0x0100 ! 2615: out dx, ax ! 2616: mov ax, #0x0302 ! 2617: out dx, ax ! 2618: mov ax, #0x0304 ! 2619: out dx, ax ! 2620: mov ax, #0x0300 ! 2621: out dx, ax ! 2622: mov dx, # VGAREG_READ_MISC_OUTPUT ! 2623: in al, dx ! 2624: and al, #0x01 ! 2625: shl al, 2 ! 2626: or al, #0x0a ! 2627: mov ah, al ! 2628: mov al, #0x06 ! 2629: mov dx, # VGAREG_GRDC_ADDRESS ! 2630: out dx, ax ! 2631: mov ax, #0x0004 ! 2632: out dx, ax ! 2633: mov ax, #0x1005 ! 2634: out dx, ax ! 2635: ASM_END ! 2636: } ! 2637: ! 2638: ASM_START ! 2639: idiv_u: ! 2640: xor dx,dx ! 2641: div bx ! 2642: ret ! 2643: ASM_END ! 2644: ! 2645: static void set_scan_lines(lines) Bit8u lines; ! 2646: { ! 2647: Bit16u crtc_addr,cols,page,vde; ! 2648: Bit8u crtc_r9,ovl,rows; ! 2649: ! 2650: crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); ! 2651: outb(crtc_addr, 0x09); ! 2652: crtc_r9 = inb(crtc_addr+1); ! 2653: crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); ! 2654: outb(crtc_addr+1, crtc_r9); ! 2655: if(lines==8) ! 2656: { ! 2657: biosfn_set_cursor_shape(0x06,0x07); ! 2658: } ! 2659: else ! 2660: { ! 2661: biosfn_set_cursor_shape(lines-4,lines-3); ! 2662: } ! 2663: write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines); ! 2664: outb(crtc_addr, 0x12); ! 2665: vde = inb(crtc_addr+1); ! 2666: outb(crtc_addr, 0x07); ! 2667: ovl = inb(crtc_addr+1); ! 2668: vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); ! 2669: rows = vde / lines; ! 2670: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1); ! 2671: cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); ! 2672: write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2); ! 2673: } ! 2674: ! 2675: static void biosfn_load_text_user_pat (AL,ES,BP,CX,DX,BL,BH) Bit8u AL;Bit16u ES;Bit16u BP;Bit16u CX;Bit16u DX;Bit8u BL;Bit8u BH; ! 2676: { ! 2677: Bit16u blockaddr,dest,i,src; ! 2678: ! 2679: get_font_access(); ! 2680: blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); ! 2681: for(i=0;i<CX;i++) ! 2682: { ! 2683: src = BP + i * BH; ! 2684: dest = blockaddr + (DX + i) * 32; ! 2685: memcpyb(0xA000, dest, ES, src, BH); ! 2686: } ! 2687: release_font_access(); ! 2688: if(AL>=0x10) ! 2689: { ! 2690: set_scan_lines(BH); ! 2691: } ! 2692: } ! 2693: ! 2694: static void biosfn_load_text_8_14_pat (AL,BL) Bit8u AL;Bit8u BL; ! 2695: { ! 2696: Bit16u blockaddr,dest,i,src; ! 2697: ! 2698: get_font_access(); ! 2699: blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); ! 2700: for(i=0;i<0x100;i++) ! 2701: { ! 2702: src = i * 14; ! 2703: dest = blockaddr + i * 32; ! 2704: memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14); ! 2705: } ! 2706: release_font_access(); ! 2707: if(AL>=0x10) ! 2708: { ! 2709: set_scan_lines(14); ! 2710: } ! 2711: } ! 2712: ! 2713: static void biosfn_load_text_8_8_pat (AL,BL) Bit8u AL;Bit8u BL; ! 2714: { ! 2715: Bit16u blockaddr,dest,i,src; ! 2716: ! 2717: get_font_access(); ! 2718: blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); ! 2719: for(i=0;i<0x100;i++) ! 2720: { ! 2721: src = i * 8; ! 2722: dest = blockaddr + i * 32; ! 2723: memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8); ! 2724: } ! 2725: release_font_access(); ! 2726: if(AL>=0x10) ! 2727: { ! 2728: set_scan_lines(8); ! 2729: } ! 2730: } ! 2731: ! 2732: // -------------------------------------------------------------------------------------------- ! 2733: ASM_START ! 2734: biosfn_set_text_block_specifier: ! 2735: push ax ! 2736: push dx ! 2737: mov dx, # VGAREG_SEQU_ADDRESS ! 2738: mov ah, bl ! 2739: mov al, #0x03 ! 2740: out dx, ax ! 2741: pop dx ! 2742: pop ax ! 2743: ret ! 2744: ASM_END ! 2745: ! 2746: // -------------------------------------------------------------------------------------------- ! 2747: static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL; ! 2748: { ! 2749: Bit16u blockaddr,dest,i,src; ! 2750: ! 2751: get_font_access(); ! 2752: blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); ! 2753: for(i=0;i<0x100;i++) ! 2754: { ! 2755: src = i * 16; ! 2756: dest = blockaddr + i * 32; ! 2757: memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16); ! 2758: } ! 2759: release_font_access(); ! 2760: if(AL>=0x10) ! 2761: { ! 2762: set_scan_lines(16); ! 2763: } ! 2764: } ! 2765: ! 2766: static void biosfn_load_gfx_8_8_chars (ES,BP) Bit16u ES;Bit16u BP; ! 2767: { ! 2768: #ifdef DEBUG ! 2769: unimplemented(); ! 2770: #endif ! 2771: } ! 2772: static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL; ! 2773: { ! 2774: #ifdef DEBUG ! 2775: unimplemented(); ! 2776: #endif ! 2777: } ! 2778: static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL; ! 2779: { ! 2780: #ifdef DEBUG ! 2781: unimplemented(); ! 2782: #endif ! 2783: } ! 2784: static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL; ! 2785: { ! 2786: #ifdef DEBUG ! 2787: unimplemented(); ! 2788: #endif ! 2789: } ! 2790: static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL; ! 2791: { ! 2792: #ifdef DEBUG ! 2793: unimplemented(); ! 2794: #endif ! 2795: } ! 2796: // -------------------------------------------------------------------------------------------- ! 2797: static void biosfn_get_font_info (BH,ES,BP,CX,DX) ! 2798: Bit8u BH;Bit16u *ES;Bit16u *BP;Bit16u *CX;Bit16u *DX; ! 2799: {Bit16u ss=get_SS(); ! 2800: ! 2801: switch(BH) ! 2802: {case 0x00: ! 2803: write_word(ss,ES,read_word(0x00,0x1f*4)); ! 2804: write_word(ss,BP,read_word(0x00,(0x1f*4)+2)); ! 2805: break; ! 2806: case 0x01: ! 2807: write_word(ss,ES,read_word(0x00,0x43*4)); ! 2808: write_word(ss,BP,read_word(0x00,(0x43*4)+2)); ! 2809: break; ! 2810: case 0x02: ! 2811: write_word(ss,ES,0xC000); ! 2812: write_word(ss,BP,vgafont14); ! 2813: break; ! 2814: case 0x03: ! 2815: write_word(ss,ES,0xC000); ! 2816: write_word(ss,BP,vgafont8); ! 2817: break; ! 2818: case 0x04: ! 2819: write_word(ss,ES,0xC000); ! 2820: write_word(ss,BP,vgafont8+128*8); ! 2821: break; ! 2822: case 0x05: ! 2823: write_word(ss,ES,0xC000); ! 2824: write_word(ss,BP,vgafont14alt); ! 2825: break; ! 2826: case 0x06: ! 2827: write_word(ss,ES,0xC000); ! 2828: write_word(ss,BP,vgafont16); ! 2829: break; ! 2830: case 0x07: ! 2831: write_word(ss,ES,0xC000); ! 2832: write_word(ss,BP,vgafont16alt); ! 2833: break; ! 2834: default: ! 2835: #ifdef DEBUG ! 2836: printf("Get font info BH(%02x) was discarded\n",BH); ! 2837: #endif ! 2838: return; ! 2839: } ! 2840: // Set byte/char of on screen font ! 2841: write_word(ss,CX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); ! 2842: ! 2843: // Set Highest char row ! 2844: write_word(ss,DX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); ! 2845: } ! 2846: ! 2847: // -------------------------------------------------------------------------------------------- ! 2848: ASM_START ! 2849: biosfn_get_ega_info: ! 2850: push ds ! 2851: push ax ! 2852: mov ax, # BIOSMEM_SEG ! 2853: mov ds, ax ! 2854: xor ch, ch ! 2855: mov bx, # BIOSMEM_SWITCHES ! 2856: mov cl, [bx] ! 2857: and cl, #0x0f ! 2858: mov bx, # BIOSMEM_CRTC_ADDRESS ! 2859: mov ax, [bx] ! 2860: mov bx, #0x0003 ! 2861: cmp ax, # VGAREG_MDA_CRTC_ADDRESS ! 2862: jne mode_ega_color ! 2863: mov bh, #0x01 ! 2864: mode_ega_color: ! 2865: pop ax ! 2866: pop ds ! 2867: ret ! 2868: ASM_END ! 2869: ! 2870: // -------------------------------------------------------------------------------------------- ! 2871: static void biosfn_alternate_prtsc() ! 2872: { ! 2873: #ifdef DEBUG ! 2874: unimplemented(); ! 2875: #endif ! 2876: } ! 2877: ! 2878: // -------------------------------------------------------------------------------------------- ! 2879: ASM_START ! 2880: biosfn_select_vert_res: ! 2881: ! 2882: ; res : 00 200 lines, 01 350 lines, 02 400 lines ! 2883: ! 2884: push ds ! 2885: push bx ! 2886: push dx ! 2887: mov dl, al ! 2888: mov ax, # BIOSMEM_SEG ! 2889: mov ds, ax ! 2890: mov bx, # BIOSMEM_MODESET_CTL ! 2891: mov al, [bx] ! 2892: mov bx, # BIOSMEM_SWITCHES ! 2893: mov ah, [bx] ! 2894: cmp dl, #0x01 ! 2895: je vert_res_350 ! 2896: jb vert_res_200 ! 2897: cmp dl, #0x02 ! 2898: je vert_res_400 ! 2899: #ifdef DEBUG ! 2900: mov al, dl ! 2901: xor ah, ah ! 2902: push ax ! 2903: mov bx, #msg_vert_res ! 2904: push bx ! 2905: call _printf ! 2906: add sp, #4 ! 2907: #endif ! 2908: jmp set_retcode ! 2909: vert_res_400: ! 2910: ! 2911: ; reset modeset ctl bit 7 and set bit 4 ! 2912: ; set switches bit 3-0 to 0x09 ! 2913: ! 2914: and al, #0x7f ! 2915: or al, #0x10 ! 2916: and ah, #0xf0 ! 2917: or ah, #0x09 ! 2918: jnz set_vert_res ! 2919: vert_res_350: ! 2920: ! 2921: ; reset modeset ctl bit 7 and bit 4 ! 2922: ; set switches bit 3-0 to 0x09 ! 2923: ! 2924: and al, #0x6f ! 2925: and ah, #0xf0 ! 2926: or ah, #0x09 ! 2927: jnz set_vert_res ! 2928: vert_res_200: ! 2929: ! 2930: ; set modeset ctl bit 7 and reset bit 4 ! 2931: ; set switches bit 3-0 to 0x08 ! 2932: ! 2933: and al, #0xef ! 2934: or al, #0x80 ! 2935: and ah, #0xf0 ! 2936: or ah, #0x08 ! 2937: set_vert_res: ! 2938: mov bx, # BIOSMEM_MODESET_CTL ! 2939: mov [bx], al ! 2940: mov bx, # BIOSMEM_SWITCHES ! 2941: mov [bx], ah ! 2942: set_retcode: ! 2943: mov ax, #0x1212 ! 2944: pop dx ! 2945: pop bx ! 2946: pop ds ! 2947: ret ! 2948: ! 2949: #ifdef DEBUG ! 2950: msg_vert_res: ! 2951: .ascii "Select vert res (%02x) was discarded" ! 2952: .byte 0x0d,0x0a,0x00 ! 2953: #endif ! 2954: ! 2955: ! 2956: biosfn_enable_default_palette_loading: ! 2957: push ds ! 2958: push bx ! 2959: push dx ! 2960: mov dl, al ! 2961: and dl, #0x01 ! 2962: shl dl, 3 ! 2963: mov ax, # BIOSMEM_SEG ! 2964: mov ds, ax ! 2965: mov bx, # BIOSMEM_MODESET_CTL ! 2966: mov al, [bx] ! 2967: and al, #0xf7 ! 2968: or al, dl ! 2969: mov [bx], al ! 2970: mov ax, #0x1212 ! 2971: pop dx ! 2972: pop bx ! 2973: pop ds ! 2974: ret ! 2975: ! 2976: ! 2977: biosfn_enable_video_addressing: ! 2978: push bx ! 2979: push dx ! 2980: mov bl, al ! 2981: and bl, #0x01 ! 2982: xor bl, #0x01 ! 2983: shl bl, 1 ! 2984: mov dx, # VGAREG_READ_MISC_OUTPUT ! 2985: in al, dx ! 2986: and al, #0xfd ! 2987: or al, bl ! 2988: mov dx, # VGAREG_WRITE_MISC_OUTPUT ! 2989: out dx, al ! 2990: mov ax, #0x1212 ! 2991: pop dx ! 2992: pop bx ! 2993: ret ! 2994: ! 2995: ! 2996: biosfn_enable_grayscale_summing: ! 2997: push ds ! 2998: push bx ! 2999: push dx ! 3000: mov dl, al ! 3001: and dl, #0x01 ! 3002: xor dl, #0x01 ! 3003: shl dl, 1 ! 3004: mov ax, # BIOSMEM_SEG ! 3005: mov ds, ax ! 3006: mov bx, # BIOSMEM_MODESET_CTL ! 3007: mov al, [bx] ! 3008: and al, #0xfd ! 3009: or al, dl ! 3010: mov [bx], al ! 3011: mov ax, #0x1212 ! 3012: pop dx ! 3013: pop bx ! 3014: pop ds ! 3015: ret ! 3016: ! 3017: ! 3018: biosfn_enable_cursor_emulation: ! 3019: push ds ! 3020: push bx ! 3021: push dx ! 3022: mov dl, al ! 3023: and dl, #0x01 ! 3024: xor dl, #0x01 ! 3025: mov ax, # BIOSMEM_SEG ! 3026: mov ds, ax ! 3027: mov bx, # BIOSMEM_MODESET_CTL ! 3028: mov al, [bx] ! 3029: and al, #0xfe ! 3030: or al, dl ! 3031: mov [bx], al ! 3032: mov ax, #0x1212 ! 3033: pop dx ! 3034: pop bx ! 3035: pop ds ! 3036: ret ! 3037: ASM_END ! 3038: ! 3039: // -------------------------------------------------------------------------------------------- ! 3040: static void biosfn_switch_video_interface (AL,ES,DX) Bit8u AL;Bit16u ES;Bit16u DX; ! 3041: { ! 3042: #ifdef DEBUG ! 3043: unimplemented(); ! 3044: #endif ! 3045: } ! 3046: static void biosfn_enable_video_refresh_control (AL) Bit8u AL; ! 3047: { ! 3048: #ifdef DEBUG ! 3049: unimplemented(); ! 3050: #endif ! 3051: } ! 3052: ! 3053: // -------------------------------------------------------------------------------------------- ! 3054: static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset) ! 3055: Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset; ! 3056: { ! 3057: Bit16u newcurs,oldcurs,dummy; ! 3058: Bit8u car,carattr; ! 3059: ! 3060: // Read curs info for the page ! 3061: biosfn_get_cursor_pos(page,&dummy,&oldcurs); ! 3062: ! 3063: // if row=0xff special case : use current cursor position ! 3064: if(row==0xff) ! 3065: {col=oldcurs&0x00ff; ! 3066: row=(oldcurs&0xff00)>>8; ! 3067: } ! 3068: ! 3069: newcurs=row; newcurs<<=8; newcurs+=col; ! 3070: biosfn_set_cursor_pos(page,newcurs); ! 3071: ! 3072: while(count--!=0) ! 3073: { ! 3074: car=read_byte(seg,offset++); ! 3075: if((flag&0x02)!=0) ! 3076: attr=read_byte(seg,offset++); ! 3077: ! 3078: biosfn_write_teletype(car,page,attr,WITH_ATTR); ! 3079: } ! 3080: ! 3081: // Set back curs pos ! 3082: if((flag&0x01)==0) ! 3083: biosfn_set_cursor_pos(page,oldcurs); ! 3084: } ! 3085: ! 3086: // -------------------------------------------------------------------------------------------- ! 3087: ASM_START ! 3088: biosfn_group_1A: ! 3089: cmp al, #0x00 ! 3090: je biosfn_read_display_code ! 3091: cmp al, #0x01 ! 3092: je biosfn_set_display_code ! 3093: #ifdef DEBUG ! 3094: call _unknown ! 3095: #endif ! 3096: ret ! 3097: biosfn_read_display_code: ! 3098: push ds ! 3099: push ax ! 3100: mov ax, # BIOSMEM_SEG ! 3101: mov ds, ax ! 3102: mov bx, # BIOSMEM_DCC_INDEX ! 3103: mov al, [bx] ! 3104: mov bl, al ! 3105: xor bh, bh ! 3106: pop ax ! 3107: mov al, ah ! 3108: pop ds ! 3109: ret ! 3110: biosfn_set_display_code: ! 3111: push ds ! 3112: push ax ! 3113: push bx ! 3114: mov ax, # BIOSMEM_SEG ! 3115: mov ds, ax ! 3116: mov ax, bx ! 3117: mov bx, # BIOSMEM_DCC_INDEX ! 3118: mov [bx], al ! 3119: #ifdef DEBUG ! 3120: mov al, ah ! 3121: xor ah, ah ! 3122: push ax ! 3123: mov bx, #msg_alt_dcc ! 3124: push bx ! 3125: call _printf ! 3126: add sp, #4 ! 3127: #endif ! 3128: pop bx ! 3129: pop ax ! 3130: mov al, ah ! 3131: pop ds ! 3132: ret ! 3133: ! 3134: #ifdef DEBUG ! 3135: msg_alt_dcc: ! 3136: .ascii "Alternate Display code (%02x) was discarded" ! 3137: .byte 0x0d,0x0a,0x00 ! 3138: #endif ! 3139: ASM_END ! 3140: ! 3141: // -------------------------------------------------------------------------------------------- ! 3142: static void biosfn_read_state_info (BX,ES,DI) ! 3143: Bit16u BX;Bit16u ES;Bit16u DI; ! 3144: { ! 3145: // Address of static functionality table ! 3146: write_word(ES,DI+0x00,&static_functionality); ! 3147: write_word(ES,DI+0x02,0xC000); ! 3148: ! 3149: // Hard coded copy from BIOS area. Should it be cleaner ? ! 3150: memcpyb(ES,DI+0x04,BIOSMEM_SEG,0x49,30); ! 3151: memcpyb(ES,DI+0x22,BIOSMEM_SEG,0x84,3); ! 3152: ! 3153: write_byte(ES,DI+0x25,read_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); ! 3154: write_byte(ES,DI+0x26,0); ! 3155: write_byte(ES,DI+0x27,16); ! 3156: write_byte(ES,DI+0x28,0); ! 3157: write_byte(ES,DI+0x29,8); ! 3158: write_byte(ES,DI+0x2a,2); ! 3159: write_byte(ES,DI+0x2b,0); ! 3160: write_byte(ES,DI+0x2c,0); ! 3161: write_byte(ES,DI+0x31,3); ! 3162: write_byte(ES,DI+0x32,0); ! 3163: ! 3164: memsetb(ES,DI+0x33,0,13); ! 3165: } ! 3166: ! 3167: // -------------------------------------------------------------------------------------------- ! 3168: // -------------------------------------------------------------------------------------------- ! 3169: static Bit16u biosfn_read_video_state_size2 (CX) ! 3170: Bit16u CX; ! 3171: { ! 3172: Bit16u size; ! 3173: size = 0; ! 3174: if (CX & 1) { ! 3175: size += 0x46; ! 3176: } ! 3177: if (CX & 2) { ! 3178: size += (5 + 8 + 5) * 2 + 6; ! 3179: } ! 3180: if (CX & 4) { ! 3181: size += 3 + 256 * 3 + 1; ! 3182: } ! 3183: return size; ! 3184: } ! 3185: ! 3186: static void biosfn_read_video_state_size (CX, BX) ! 3187: Bit16u CX; Bit16u *BX; ! 3188: { ! 3189: Bit16u ss=get_SS(); ! 3190: write_word(ss, BX, biosfn_read_video_state_size2(CX)); ! 3191: } ! 3192: ! 3193: static Bit16u biosfn_save_video_state (CX,ES,BX) ! 3194: Bit16u CX;Bit16u ES;Bit16u BX; ! 3195: { ! 3196: Bit16u i, v, crtc_addr, ar_index; ! 3197: ! 3198: crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS); ! 3199: if (CX & 1) { ! 3200: write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++; ! 3201: write_byte(ES, BX, inb(crtc_addr)); BX++; ! 3202: write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++; ! 3203: inb(VGAREG_ACTL_RESET); ! 3204: ar_index = inb(VGAREG_ACTL_ADDRESS); ! 3205: write_byte(ES, BX, ar_index); BX++; ! 3206: write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++; ! 3207: ! 3208: for(i=1;i<=4;i++){ ! 3209: outb(VGAREG_SEQU_ADDRESS, i); ! 3210: write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; ! 3211: } ! 3212: outb(VGAREG_SEQU_ADDRESS, 0); ! 3213: write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; ! 3214: ! 3215: for(i=0;i<=0x18;i++) { ! 3216: outb(crtc_addr,i); ! 3217: write_byte(ES, BX, inb(crtc_addr+1)); BX++; ! 3218: } ! 3219: ! 3220: for(i=0;i<=0x13;i++) { ! 3221: inb(VGAREG_ACTL_RESET); ! 3222: outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); ! 3223: write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++; ! 3224: } ! 3225: inb(VGAREG_ACTL_RESET); ! 3226: ! 3227: for(i=0;i<=8;i++) { ! 3228: outb(VGAREG_GRDC_ADDRESS,i); ! 3229: write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++; ! 3230: } ! 3231: ! 3232: write_word(ES, BX, crtc_addr); BX+= 2; ! 3233: ! 3234: /* XXX: read plane latches */ ! 3235: write_byte(ES, BX, 0); BX++; ! 3236: write_byte(ES, BX, 0); BX++; ! 3237: write_byte(ES, BX, 0); BX++; ! 3238: write_byte(ES, BX, 0); BX++; ! 3239: } ! 3240: if (CX & 2) { ! 3241: write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++; ! 3242: write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2; ! 3243: write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2; ! 3244: write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2; ! 3245: write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++; ! 3246: write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2; ! 3247: write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++; ! 3248: write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++; ! 3249: write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++; ! 3250: write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2; ! 3251: for(i=0;i<8;i++) { ! 3252: write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i)); ! 3253: BX += 2; ! 3254: } ! 3255: write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2; ! 3256: write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++; ! 3257: /* current font */ ! 3258: write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2; ! 3259: write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2; ! 3260: write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2; ! 3261: write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2; ! 3262: } ! 3263: if (CX & 4) { ! 3264: /* XXX: check this */ ! 3265: write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */ ! 3266: write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */ ! 3267: write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++; ! 3268: // Set the whole dac always, from 0 ! 3269: outb(VGAREG_DAC_WRITE_ADDRESS,0x00); ! 3270: for(i=0;i<256*3;i++) { ! 3271: write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++; ! 3272: } ! 3273: write_byte(ES, BX, 0); BX++; /* color select register */ ! 3274: } ! 3275: return BX; ! 3276: } ! 3277: ! 3278: static Bit16u biosfn_restore_video_state (CX,ES,BX) ! 3279: Bit16u CX;Bit16u ES;Bit16u BX; ! 3280: { ! 3281: Bit16u i, crtc_addr, v, addr1, ar_index; ! 3282: ! 3283: if (CX & 1) { ! 3284: // Reset Attribute Ctl flip-flop ! 3285: inb(VGAREG_ACTL_RESET); ! 3286: ! 3287: crtc_addr = read_word(ES, BX + 0x40); ! 3288: addr1 = BX; ! 3289: BX += 5; ! 3290: ! 3291: for(i=1;i<=4;i++){ ! 3292: outb(VGAREG_SEQU_ADDRESS, i); ! 3293: outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; ! 3294: } ! 3295: outb(VGAREG_SEQU_ADDRESS, 0); ! 3296: outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; ! 3297: ! 3298: // Disable CRTC write protection ! 3299: outw(crtc_addr,0x0011); ! 3300: // Set CRTC regs ! 3301: for(i=0;i<=0x18;i++) { ! 3302: if (i != 0x11) { ! 3303: outb(crtc_addr,i); ! 3304: outb(crtc_addr+1, read_byte(ES, BX)); ! 3305: } ! 3306: BX++; ! 3307: } ! 3308: // select crtc base address ! 3309: v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; ! 3310: if (crtc_addr = 0x3d4) ! 3311: v |= 0x01; ! 3312: outb(VGAREG_WRITE_MISC_OUTPUT, v); ! 3313: ! 3314: // enable write protection if needed ! 3315: outb(crtc_addr, 0x11); ! 3316: outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11)); ! 3317: ! 3318: // Set Attribute Ctl ! 3319: ar_index = read_byte(ES, addr1 + 0x03); ! 3320: inb(VGAREG_ACTL_RESET); ! 3321: for(i=0;i<=0x13;i++) { ! 3322: outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); ! 3323: outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++; ! 3324: } ! 3325: outb(VGAREG_ACTL_ADDRESS, ar_index); ! 3326: inb(VGAREG_ACTL_RESET); ! 3327: ! 3328: for(i=0;i<=8;i++) { ! 3329: outb(VGAREG_GRDC_ADDRESS,i); ! 3330: outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++; ! 3331: } ! 3332: BX += 2; /* crtc_addr */ ! 3333: BX += 4; /* plane latches */ ! 3334: ! 3335: outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++; ! 3336: outb(crtc_addr, read_byte(ES, addr1)); addr1++; ! 3337: outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++; ! 3338: addr1++; ! 3339: outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++; ! 3340: } ! 3341: if (CX & 2) { ! 3342: write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++; ! 3343: write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2; ! 3344: write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2; ! 3345: write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2; ! 3346: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++; ! 3347: write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2; ! 3348: write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++; ! 3349: write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++; ! 3350: write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++; ! 3351: write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2; ! 3352: for(i=0;i<8;i++) { ! 3353: write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX)); ! 3354: BX += 2; ! 3355: } ! 3356: write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2; ! 3357: write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++; ! 3358: /* current font */ ! 3359: write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2; ! 3360: write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2; ! 3361: write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2; ! 3362: write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2; ! 3363: } ! 3364: if (CX & 4) { ! 3365: BX++; ! 3366: v = read_byte(ES, BX); BX++; ! 3367: outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++; ! 3368: // Set the whole dac always, from 0 ! 3369: outb(VGAREG_DAC_WRITE_ADDRESS,0x00); ! 3370: for(i=0;i<256*3;i++) { ! 3371: outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++; ! 3372: } ! 3373: BX++; ! 3374: outb(VGAREG_DAC_WRITE_ADDRESS, v); ! 3375: } ! 3376: return BX; ! 3377: } ! 3378: ! 3379: // ============================================================================================ ! 3380: // ! 3381: // Video Utils ! 3382: // ! 3383: // ============================================================================================ ! 3384: ! 3385: // -------------------------------------------------------------------------------------------- ! 3386: static Bit8u find_vga_entry(mode) ! 3387: Bit8u mode; ! 3388: { ! 3389: Bit8u i,line=0xFF; ! 3390: for(i=0;i<=MODE_MAX;i++) ! 3391: if(vga_modes[i].svgamode==mode) ! 3392: {line=i; ! 3393: break; ! 3394: } ! 3395: return line; ! 3396: } ! 3397: ! 3398: /* =========================================================== */ ! 3399: /* ! 3400: * Misc Utils ! 3401: */ ! 3402: /* =========================================================== */ ! 3403: ! 3404: // -------------------------------------------------------------------------------------------- ! 3405: static void memsetb(seg,offset,value,count) ! 3406: Bit16u seg; ! 3407: Bit16u offset; ! 3408: Bit16u value; ! 3409: Bit16u count; ! 3410: { ! 3411: ASM_START ! 3412: push bp ! 3413: mov bp, sp ! 3414: ! 3415: push ax ! 3416: push cx ! 3417: push es ! 3418: push di ! 3419: ! 3420: mov cx, 10[bp] ; count ! 3421: cmp cx, #0x00 ! 3422: je memsetb_end ! 3423: mov ax, 4[bp] ; segment ! 3424: mov es, ax ! 3425: mov ax, 6[bp] ; offset ! 3426: mov di, ax ! 3427: mov al, 8[bp] ; value ! 3428: cld ! 3429: rep ! 3430: stosb ! 3431: ! 3432: memsetb_end: ! 3433: pop di ! 3434: pop es ! 3435: pop cx ! 3436: pop ax ! 3437: ! 3438: pop bp ! 3439: ASM_END ! 3440: } ! 3441: ! 3442: // -------------------------------------------------------------------------------------------- ! 3443: static void memsetw(seg,offset,value,count) ! 3444: Bit16u seg; ! 3445: Bit16u offset; ! 3446: Bit16u value; ! 3447: Bit16u count; ! 3448: { ! 3449: ASM_START ! 3450: push bp ! 3451: mov bp, sp ! 3452: ! 3453: push ax ! 3454: push cx ! 3455: push es ! 3456: push di ! 3457: ! 3458: mov cx, 10[bp] ; count ! 3459: cmp cx, #0x00 ! 3460: je memsetw_end ! 3461: mov ax, 4[bp] ; segment ! 3462: mov es, ax ! 3463: mov ax, 6[bp] ; offset ! 3464: mov di, ax ! 3465: mov ax, 8[bp] ; value ! 3466: cld ! 3467: rep ! 3468: stosw ! 3469: ! 3470: memsetw_end: ! 3471: pop di ! 3472: pop es ! 3473: pop cx ! 3474: pop ax ! 3475: ! 3476: pop bp ! 3477: ASM_END ! 3478: } ! 3479: ! 3480: // -------------------------------------------------------------------------------------------- ! 3481: static void memcpyb(dseg,doffset,sseg,soffset,count) ! 3482: Bit16u dseg; ! 3483: Bit16u doffset; ! 3484: Bit16u sseg; ! 3485: Bit16u soffset; ! 3486: Bit16u count; ! 3487: { ! 3488: ASM_START ! 3489: push bp ! 3490: mov bp, sp ! 3491: ! 3492: push ax ! 3493: push cx ! 3494: push es ! 3495: push di ! 3496: push ds ! 3497: push si ! 3498: ! 3499: mov cx, 12[bp] ; count ! 3500: cmp cx, #0x0000 ! 3501: je memcpyb_end ! 3502: mov ax, 4[bp] ; dsegment ! 3503: mov es, ax ! 3504: mov ax, 6[bp] ; doffset ! 3505: mov di, ax ! 3506: mov ax, 8[bp] ; ssegment ! 3507: mov ds, ax ! 3508: mov ax, 10[bp] ; soffset ! 3509: mov si, ax ! 3510: cld ! 3511: rep ! 3512: movsb ! 3513: ! 3514: memcpyb_end: ! 3515: pop si ! 3516: pop ds ! 3517: pop di ! 3518: pop es ! 3519: pop cx ! 3520: pop ax ! 3521: ! 3522: pop bp ! 3523: ASM_END ! 3524: } ! 3525: ! 3526: // -------------------------------------------------------------------------------------------- ! 3527: static void memcpyw(dseg,doffset,sseg,soffset,count) ! 3528: Bit16u dseg; ! 3529: Bit16u doffset; ! 3530: Bit16u sseg; ! 3531: Bit16u soffset; ! 3532: Bit16u count; ! 3533: { ! 3534: ASM_START ! 3535: push bp ! 3536: mov bp, sp ! 3537: ! 3538: push ax ! 3539: push cx ! 3540: push es ! 3541: push di ! 3542: push ds ! 3543: push si ! 3544: ! 3545: mov cx, 12[bp] ; count ! 3546: cmp cx, #0x0000 ! 3547: je memcpyw_end ! 3548: mov ax, 4[bp] ; dsegment ! 3549: mov es, ax ! 3550: mov ax, 6[bp] ; doffset ! 3551: mov di, ax ! 3552: mov ax, 8[bp] ; ssegment ! 3553: mov ds, ax ! 3554: mov ax, 10[bp] ; soffset ! 3555: mov si, ax ! 3556: cld ! 3557: rep ! 3558: movsw ! 3559: ! 3560: memcpyw_end: ! 3561: pop si ! 3562: pop ds ! 3563: pop di ! 3564: pop es ! 3565: pop cx ! 3566: pop ax ! 3567: ! 3568: pop bp ! 3569: ASM_END ! 3570: } ! 3571: ! 3572: /* =========================================================== */ ! 3573: /* ! 3574: * These functions where ripped from Kevin's rombios.c ! 3575: */ ! 3576: /* =========================================================== */ ! 3577: ! 3578: // -------------------------------------------------------------------------------------------- ! 3579: static Bit8u ! 3580: read_byte(seg, offset) ! 3581: Bit16u seg; ! 3582: Bit16u offset; ! 3583: { ! 3584: ASM_START ! 3585: push bp ! 3586: mov bp, sp ! 3587: ! 3588: push bx ! 3589: push ds ! 3590: mov ax, 4[bp] ; segment ! 3591: mov ds, ax ! 3592: mov bx, 6[bp] ; offset ! 3593: mov al, [bx] ! 3594: ;; al = return value (byte) ! 3595: pop ds ! 3596: pop bx ! 3597: ! 3598: pop bp ! 3599: ASM_END ! 3600: } ! 3601: ! 3602: // -------------------------------------------------------------------------------------------- ! 3603: static Bit16u ! 3604: read_word(seg, offset) ! 3605: Bit16u seg; ! 3606: Bit16u offset; ! 3607: { ! 3608: ASM_START ! 3609: push bp ! 3610: mov bp, sp ! 3611: ! 3612: push bx ! 3613: push ds ! 3614: mov ax, 4[bp] ; segment ! 3615: mov ds, ax ! 3616: mov bx, 6[bp] ; offset ! 3617: mov ax, [bx] ! 3618: ;; ax = return value (word) ! 3619: pop ds ! 3620: pop bx ! 3621: ! 3622: pop bp ! 3623: ASM_END ! 3624: } ! 3625: ! 3626: // -------------------------------------------------------------------------------------------- ! 3627: static void ! 3628: write_byte(seg, offset, data) ! 3629: Bit16u seg; ! 3630: Bit16u offset; ! 3631: Bit8u data; ! 3632: { ! 3633: ASM_START ! 3634: push bp ! 3635: mov bp, sp ! 3636: ! 3637: push ax ! 3638: push bx ! 3639: push ds ! 3640: mov ax, 4[bp] ; segment ! 3641: mov ds, ax ! 3642: mov bx, 6[bp] ; offset ! 3643: mov al, 8[bp] ; data byte ! 3644: mov [bx], al ; write data byte ! 3645: pop ds ! 3646: pop bx ! 3647: pop ax ! 3648: ! 3649: pop bp ! 3650: ASM_END ! 3651: } ! 3652: ! 3653: // -------------------------------------------------------------------------------------------- ! 3654: static void ! 3655: write_word(seg, offset, data) ! 3656: Bit16u seg; ! 3657: Bit16u offset; ! 3658: Bit16u data; ! 3659: { ! 3660: ASM_START ! 3661: push bp ! 3662: mov bp, sp ! 3663: ! 3664: push ax ! 3665: push bx ! 3666: push ds ! 3667: mov ax, 4[bp] ; segment ! 3668: mov ds, ax ! 3669: mov bx, 6[bp] ; offset ! 3670: mov ax, 8[bp] ; data word ! 3671: mov [bx], ax ; write data word ! 3672: pop ds ! 3673: pop bx ! 3674: pop ax ! 3675: ! 3676: pop bp ! 3677: ASM_END ! 3678: } ! 3679: ! 3680: // -------------------------------------------------------------------------------------------- ! 3681: Bit8u ! 3682: inb(port) ! 3683: Bit16u port; ! 3684: { ! 3685: ASM_START ! 3686: push bp ! 3687: mov bp, sp ! 3688: ! 3689: push dx ! 3690: mov dx, 4[bp] ! 3691: in al, dx ! 3692: pop dx ! 3693: ! 3694: pop bp ! 3695: ASM_END ! 3696: } ! 3697: ! 3698: Bit16u ! 3699: inw(port) ! 3700: Bit16u port; ! 3701: { ! 3702: ASM_START ! 3703: push bp ! 3704: mov bp, sp ! 3705: ! 3706: push dx ! 3707: mov dx, 4[bp] ! 3708: in ax, dx ! 3709: pop dx ! 3710: ! 3711: pop bp ! 3712: ASM_END ! 3713: } ! 3714: ! 3715: // -------------------------------------------------------------------------------------------- ! 3716: void ! 3717: outb(port, val) ! 3718: Bit16u port; ! 3719: Bit8u val; ! 3720: { ! 3721: ASM_START ! 3722: push bp ! 3723: mov bp, sp ! 3724: ! 3725: push ax ! 3726: push dx ! 3727: mov dx, 4[bp] ! 3728: mov al, 6[bp] ! 3729: out dx, al ! 3730: pop dx ! 3731: pop ax ! 3732: ! 3733: pop bp ! 3734: ASM_END ! 3735: } ! 3736: ! 3737: // -------------------------------------------------------------------------------------------- ! 3738: void ! 3739: outw(port, val) ! 3740: Bit16u port; ! 3741: Bit16u val; ! 3742: { ! 3743: ASM_START ! 3744: push bp ! 3745: mov bp, sp ! 3746: ! 3747: push ax ! 3748: push dx ! 3749: mov dx, 4[bp] ! 3750: mov ax, 6[bp] ! 3751: out dx, ax ! 3752: pop dx ! 3753: pop ax ! 3754: ! 3755: pop bp ! 3756: ASM_END ! 3757: } ! 3758: ! 3759: Bit16u get_SS() ! 3760: { ! 3761: ASM_START ! 3762: mov ax, ss ! 3763: ASM_END ! 3764: } ! 3765: ! 3766: #ifdef DEBUG ! 3767: void unimplemented() ! 3768: { ! 3769: printf("--> Unimplemented\n"); ! 3770: } ! 3771: ! 3772: void unknown() ! 3773: { ! 3774: printf("--> Unknown int10\n"); ! 3775: } ! 3776: #endif ! 3777: ! 3778: // -------------------------------------------------------------------------------------------- ! 3779: #if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG) ! 3780: void printf(s) ! 3781: Bit8u *s; ! 3782: { ! 3783: Bit8u c, format_char; ! 3784: Boolean in_format; ! 3785: unsigned format_width, i; ! 3786: Bit16u *arg_ptr; ! 3787: Bit16u arg_seg, arg, digit, nibble, shift_count; ! 3788: ! 3789: arg_ptr = &s; ! 3790: arg_seg = get_SS(); ! 3791: ! 3792: in_format = 0; ! 3793: format_width = 0; ! 3794: ! 3795: while (c = read_byte(0xc000, s)) { ! 3796: if ( c == '%' ) { ! 3797: in_format = 1; ! 3798: format_width = 0; ! 3799: } ! 3800: else if (in_format) { ! 3801: if ( (c>='0') && (c<='9') ) { ! 3802: format_width = (format_width * 10) + (c - '0'); ! 3803: } ! 3804: else if (c == 'x') { ! 3805: arg_ptr++; // increment to next arg ! 3806: arg = read_word(arg_seg, arg_ptr); ! 3807: if (format_width == 0) ! 3808: format_width = 4; ! 3809: i = 0; ! 3810: digit = format_width - 1; ! 3811: for (i=0; i<format_width; i++) { ! 3812: nibble = (arg >> (4 * digit)) & 0x000f; ! 3813: if (nibble <= 9) ! 3814: outb(0x0500, nibble + '0'); ! 3815: else ! 3816: outb(0x0500, (nibble - 10) + 'A'); ! 3817: digit--; ! 3818: } ! 3819: in_format = 0; ! 3820: } ! 3821: //else if (c == 'd') { ! 3822: // in_format = 0; ! 3823: // } ! 3824: } ! 3825: else { ! 3826: outb(0x0500, c); ! 3827: } ! 3828: s ++; ! 3829: } ! 3830: } ! 3831: #endif ! 3832: ! 3833: #ifdef VBE ! 3834: #include "vbe.c" ! 3835: #endif ! 3836: ! 3837: #ifdef CIRRUS ! 3838: #include "clext.c" ! 3839: #endif ! 3840: ! 3841: // -------------------------------------------------------------------------------------------- ! 3842: ! 3843: ASM_START ! 3844: ;; DATA_SEG_DEFS_HERE ! 3845: ASM_END ! 3846: ! 3847: ASM_START ! 3848: .ascii "vgabios ends here" ! 3849: .byte 0x00 ! 3850: vgabios_end: ! 3851: .byte 0xCB ! 3852: ;; BLOCK_STRINGS_BEGIN ! 3853: ASM_END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.