|
|
1.1 ! root 1: // ============================================================================================ ! 2: // ! 3: // Copyright (C) 2002 Jeroen Janssen ! 4: // ! 5: // This library is free software; you can redistribute it and/or ! 6: // modify it under the terms of the GNU Lesser General Public ! 7: // License as published by the Free Software Foundation; either ! 8: // version 2 of the License, or (at your option) any later version. ! 9: // ! 10: // This library is distributed in the hope that it will be useful, ! 11: // but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 13: // Lesser General Public License for more details. ! 14: // ! 15: // You should have received a copy of the GNU Lesser General Public ! 16: // License along with this library; if not, write to the Free Software ! 17: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! 18: // ! 19: // ============================================================================================ ! 20: // ! 21: // This VBE is part of the VGA Bios specific to the plex86/bochs Emulated VGA card. ! 22: // You can NOT drive any physical vga card with it. ! 23: // ! 24: // ============================================================================================ ! 25: // ! 26: // This VBE Bios is based on information taken from : ! 27: // - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org ! 28: // ! 29: // ============================================================================================ ! 30: ! 31: ! 32: // defines available ! 33: ! 34: // disable VESA/VBE2 check in vbe info ! 35: //#define VBE2_NO_VESA_CHECK ! 36: ! 37: ! 38: #include "vbe.h" ! 39: #include "vbetables.h" ! 40: ! 41: #define VBE_TOTAL_VIDEO_MEMORY_DIV_64K (VBE_DISPI_TOTAL_VIDEO_MEMORY_MB*1024/64) ! 42: ! 43: // The current OEM Software Revision of this VBE Bios ! 44: #define VBE_OEM_SOFTWARE_REV 0x0002; ! 45: ! 46: extern char vbebios_copyright; ! 47: extern char vbebios_vendor_name; ! 48: extern char vbebios_product_name; ! 49: extern char vbebios_product_revision; ! 50: ! 51: ASM_START ! 52: // FIXME: 'merge' these (c) etc strings with the vgabios.c strings? ! 53: _vbebios_copyright: ! 54: .ascii "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/" ! 55: .byte 0x00 ! 56: ! 57: _vbebios_vendor_name: ! 58: .ascii "Bochs/Plex86 Developers" ! 59: .byte 0x00 ! 60: ! 61: _vbebios_product_name: ! 62: .ascii "Bochs/Plex86 VBE Adapter" ! 63: .byte 0x00 ! 64: ! 65: _vbebios_product_revision: ! 66: .ascii "$Id$" ! 67: .byte 0x00 ! 68: ! 69: _vbebios_info_string: ! 70: .ascii "Bochs VBE Display Adapter enabled" ! 71: .byte 0x0a,0x0d ! 72: .byte 0x0a,0x0d ! 73: .byte 0x00 ! 74: ! 75: _no_vbebios_info_string: ! 76: .ascii "NO Bochs VBE Support available!" ! 77: .byte 0x0a,0x0d ! 78: .byte 0x0a,0x0d ! 79: .byte 0x00 ! 80: ! 81: #if defined(USE_BX_INFO) || defined(DEBUG) ! 82: msg_vbe_init: ! 83: .ascii "VBE Bios $Id$" ! 84: .byte 0x0a,0x0d, 0x00 ! 85: #endif ! 86: ! 87: .align 2 ! 88: vesa_pm_start: ! 89: dw vesa_pm_set_window - vesa_pm_start ! 90: dw vesa_pm_set_display_start - vesa_pm_start ! 91: dw vesa_pm_unimplemented - vesa_pm_start ! 92: dw vesa_pm_io_ports_table - vesa_pm_start ! 93: vesa_pm_io_ports_table: ! 94: dw VBE_DISPI_IOPORT_INDEX ! 95: dw VBE_DISPI_IOPORT_INDEX + 1 ! 96: dw VBE_DISPI_IOPORT_DATA ! 97: dw VBE_DISPI_IOPORT_DATA + 1 ! 98: dw 0xffff ! 99: dw 0xffff ! 100: ! 101: USE32 ! 102: vesa_pm_set_window: ! 103: cmp bx, #0x00 ! 104: je vesa_pm_set_display_window1 ! 105: mov ax, #0x0100 ! 106: ret ! 107: vesa_pm_set_display_window1: ! 108: mov ax, dx ! 109: push dx ! 110: push ax ! 111: mov dx, # VBE_DISPI_IOPORT_INDEX ! 112: mov ax, # VBE_DISPI_INDEX_BANK ! 113: out dx, ax ! 114: pop ax ! 115: mov dx, # VBE_DISPI_IOPORT_DATA ! 116: out dx, ax ! 117: in ax, dx ! 118: pop dx ! 119: cmp dx, ax ! 120: jne illegal_window ! 121: mov ax, #0x004f ! 122: ret ! 123: illegal_window: ! 124: mov ax, #0x014f ! 125: ret ! 126: ! 127: vesa_pm_set_display_start: ! 128: cmp bl, #0x80 ! 129: je vesa_pm_set_display_start1 ! 130: cmp bl, #0x00 ! 131: je vesa_pm_set_display_start1 ! 132: mov ax, #0x0100 ! 133: ret ! 134: vesa_pm_set_display_start1: ! 135: ; convert offset to (X, Y) coordinate ! 136: ; (would be simpler to change Bochs VBE API...) ! 137: push eax ! 138: push ecx ! 139: push edx ! 140: push esi ! 141: push edi ! 142: shl edx, #16 ! 143: and ecx, #0xffff ! 144: or ecx, edx ! 145: shl ecx, #2 ! 146: mov eax, ecx ! 147: ! 148: push eax ! 149: mov dx, # VBE_DISPI_IOPORT_INDEX ! 150: mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH ! 151: out dx, ax ! 152: mov dx, # VBE_DISPI_IOPORT_DATA ! 153: in ax, dx ! 154: movzx ecx, ax ! 155: ! 156: mov dx, # VBE_DISPI_IOPORT_INDEX ! 157: mov ax, # VBE_DISPI_INDEX_BPP ! 158: out dx, ax ! 159: mov dx, # VBE_DISPI_IOPORT_DATA ! 160: in ax, dx ! 161: movzx esi, ax ! 162: pop eax ! 163: ! 164: cmp esi, #4 ! 165: jz bpp4_mode ! 166: add esi, #7 ! 167: shr esi, #3 ! 168: imul ecx, esi ! 169: xor edx, edx ! 170: div ecx ! 171: mov edi, eax ! 172: mov eax, edx ! 173: xor edx, edx ! 174: div esi ! 175: jmp set_xy_regs ! 176: ! 177: bpp4_mode: ! 178: shr ecx, #1 ! 179: xor edx, edx ! 180: div ecx ! 181: mov edi, eax ! 182: mov eax, edx ! 183: shl eax, #1 ! 184: ! 185: set_xy_regs: ! 186: push dx ! 187: push ax ! 188: mov dx, # VBE_DISPI_IOPORT_INDEX ! 189: mov ax, # VBE_DISPI_INDEX_X_OFFSET ! 190: out dx, ax ! 191: pop ax ! 192: mov dx, # VBE_DISPI_IOPORT_DATA ! 193: out dx, ax ! 194: pop dx ! 195: ! 196: mov ax, di ! 197: push dx ! 198: push ax ! 199: mov dx, # VBE_DISPI_IOPORT_INDEX ! 200: mov ax, # VBE_DISPI_INDEX_Y_OFFSET ! 201: out dx, ax ! 202: pop ax ! 203: mov dx, # VBE_DISPI_IOPORT_DATA ! 204: out dx, ax ! 205: pop dx ! 206: ! 207: pop edi ! 208: pop esi ! 209: pop edx ! 210: pop ecx ! 211: pop eax ! 212: mov ax, #0x004f ! 213: ret ! 214: ! 215: vesa_pm_unimplemented: ! 216: mov ax, #0x014f ! 217: ret ! 218: USE16 ! 219: vesa_pm_end: ! 220: ! 221: ; DISPI ioport functions ! 222: ! 223: dispi_get_id: ! 224: push dx ! 225: mov dx, # VBE_DISPI_IOPORT_INDEX ! 226: mov ax, # VBE_DISPI_INDEX_ID ! 227: out dx, ax ! 228: mov dx, # VBE_DISPI_IOPORT_DATA ! 229: in ax, dx ! 230: pop dx ! 231: ret ! 232: ! 233: dispi_set_id: ! 234: push dx ! 235: push ax ! 236: mov dx, # VBE_DISPI_IOPORT_INDEX ! 237: mov ax, # VBE_DISPI_INDEX_ID ! 238: out dx, ax ! 239: pop ax ! 240: mov dx, # VBE_DISPI_IOPORT_DATA ! 241: out dx, ax ! 242: pop dx ! 243: ret ! 244: ASM_END ! 245: ! 246: static void dispi_set_xres(xres) ! 247: Bit16u xres; ! 248: { ! 249: ASM_START ! 250: push bp ! 251: mov bp, sp ! 252: push ax ! 253: push dx ! 254: ! 255: mov dx, # VBE_DISPI_IOPORT_INDEX ! 256: mov ax, # VBE_DISPI_INDEX_XRES ! 257: out dx, ax ! 258: mov dx, # VBE_DISPI_IOPORT_DATA ! 259: mov ax, 4[bp] ; xres ! 260: out dx, ax ! 261: ! 262: pop dx ! 263: pop ax ! 264: pop bp ! 265: ASM_END ! 266: } ! 267: ! 268: static void dispi_set_yres(yres) ! 269: Bit16u yres; ! 270: { ! 271: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES); ! 272: outw(VBE_DISPI_IOPORT_DATA,yres); ! 273: } ! 274: ! 275: static void dispi_set_bpp(bpp) ! 276: Bit16u bpp; ! 277: { ! 278: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP); ! 279: outw(VBE_DISPI_IOPORT_DATA,bpp); ! 280: } ! 281: ! 282: ASM_START ! 283: ; AL = bits per pixel / AH = bytes per pixel ! 284: dispi_get_bpp: ! 285: push dx ! 286: mov dx, # VBE_DISPI_IOPORT_INDEX ! 287: mov ax, # VBE_DISPI_INDEX_BPP ! 288: out dx, ax ! 289: mov dx, # VBE_DISPI_IOPORT_DATA ! 290: in ax, dx ! 291: mov ah, al ! 292: shr ah, 3 ! 293: test al, #0x07 ! 294: jz get_bpp_noinc ! 295: inc ah ! 296: get_bpp_noinc: ! 297: pop dx ! 298: ret ! 299: ! 300: ; get display capabilities ! 301: ! 302: _dispi_get_max_xres: ! 303: push dx ! 304: push bx ! 305: call dispi_get_enable ! 306: mov bx, ax ! 307: or ax, # VBE_DISPI_GETCAPS ! 308: call _dispi_set_enable ! 309: mov dx, # VBE_DISPI_IOPORT_INDEX ! 310: mov ax, # VBE_DISPI_INDEX_XRES ! 311: out dx, ax ! 312: mov dx, # VBE_DISPI_IOPORT_DATA ! 313: in ax, dx ! 314: push ax ! 315: mov ax, bx ! 316: call _dispi_set_enable ! 317: pop ax ! 318: pop bx ! 319: pop dx ! 320: ret ! 321: ! 322: _dispi_get_max_bpp: ! 323: push dx ! 324: push bx ! 325: call dispi_get_enable ! 326: mov bx, ax ! 327: or ax, # VBE_DISPI_GETCAPS ! 328: call _dispi_set_enable ! 329: mov dx, # VBE_DISPI_IOPORT_INDEX ! 330: mov ax, # VBE_DISPI_INDEX_BPP ! 331: out dx, ax ! 332: mov dx, # VBE_DISPI_IOPORT_DATA ! 333: in ax, dx ! 334: push ax ! 335: mov ax, bx ! 336: call _dispi_set_enable ! 337: pop ax ! 338: pop bx ! 339: pop dx ! 340: ret ! 341: ! 342: _dispi_set_enable: ! 343: push dx ! 344: push ax ! 345: mov dx, # VBE_DISPI_IOPORT_INDEX ! 346: mov ax, # VBE_DISPI_INDEX_ENABLE ! 347: out dx, ax ! 348: pop ax ! 349: mov dx, # VBE_DISPI_IOPORT_DATA ! 350: out dx, ax ! 351: pop dx ! 352: ret ! 353: ! 354: dispi_get_enable: ! 355: push dx ! 356: mov dx, # VBE_DISPI_IOPORT_INDEX ! 357: mov ax, # VBE_DISPI_INDEX_ENABLE ! 358: out dx, ax ! 359: mov dx, # VBE_DISPI_IOPORT_DATA ! 360: in ax, dx ! 361: pop dx ! 362: ret ! 363: ! 364: _dispi_set_bank: ! 365: push dx ! 366: push ax ! 367: mov dx, # VBE_DISPI_IOPORT_INDEX ! 368: mov ax, # VBE_DISPI_INDEX_BANK ! 369: out dx, ax ! 370: pop ax ! 371: mov dx, # VBE_DISPI_IOPORT_DATA ! 372: out dx, ax ! 373: pop dx ! 374: ret ! 375: ! 376: dispi_get_bank: ! 377: push dx ! 378: mov dx, # VBE_DISPI_IOPORT_INDEX ! 379: mov ax, # VBE_DISPI_INDEX_BANK ! 380: out dx, ax ! 381: mov dx, # VBE_DISPI_IOPORT_DATA ! 382: in ax, dx ! 383: pop dx ! 384: ret ! 385: ASM_END ! 386: ! 387: static void dispi_set_bank_farcall() ! 388: { ! 389: ASM_START ! 390: cmp bx,#0x0100 ! 391: je dispi_set_bank_farcall_get ! 392: or bx,bx ! 393: jnz dispi_set_bank_farcall_error ! 394: mov ax,dx ! 395: push dx ! 396: push ax ! 397: mov ax,# VBE_DISPI_INDEX_BANK ! 398: mov dx,# VBE_DISPI_IOPORT_INDEX ! 399: out dx,ax ! 400: pop ax ! 401: mov dx,# VBE_DISPI_IOPORT_DATA ! 402: out dx,ax ! 403: in ax,dx ! 404: pop dx ! 405: cmp dx,ax ! 406: jne dispi_set_bank_farcall_error ! 407: mov ax, #0x004f ! 408: retf ! 409: dispi_set_bank_farcall_get: ! 410: mov ax,# VBE_DISPI_INDEX_BANK ! 411: mov dx,# VBE_DISPI_IOPORT_INDEX ! 412: out dx,ax ! 413: mov dx,# VBE_DISPI_IOPORT_DATA ! 414: in ax,dx ! 415: mov dx,ax ! 416: retf ! 417: dispi_set_bank_farcall_error: ! 418: mov ax,#0x014F ! 419: retf ! 420: ASM_END ! 421: } ! 422: ! 423: ASM_START ! 424: dispi_set_x_offset: ! 425: push dx ! 426: push ax ! 427: mov dx, # VBE_DISPI_IOPORT_INDEX ! 428: mov ax, # VBE_DISPI_INDEX_X_OFFSET ! 429: out dx, ax ! 430: pop ax ! 431: mov dx, # VBE_DISPI_IOPORT_DATA ! 432: out dx, ax ! 433: pop dx ! 434: ret ! 435: ! 436: dispi_get_x_offset: ! 437: push dx ! 438: mov dx, # VBE_DISPI_IOPORT_INDEX ! 439: mov ax, # VBE_DISPI_INDEX_X_OFFSET ! 440: out dx, ax ! 441: mov dx, # VBE_DISPI_IOPORT_DATA ! 442: in ax, dx ! 443: pop dx ! 444: ret ! 445: ! 446: dispi_set_y_offset: ! 447: push dx ! 448: push ax ! 449: mov dx, # VBE_DISPI_IOPORT_INDEX ! 450: mov ax, # VBE_DISPI_INDEX_Y_OFFSET ! 451: out dx, ax ! 452: pop ax ! 453: mov dx, # VBE_DISPI_IOPORT_DATA ! 454: out dx, ax ! 455: pop dx ! 456: ret ! 457: ! 458: dispi_get_y_offset: ! 459: push dx ! 460: mov dx, # VBE_DISPI_IOPORT_INDEX ! 461: mov ax, # VBE_DISPI_INDEX_Y_OFFSET ! 462: out dx, ax ! 463: mov dx, # VBE_DISPI_IOPORT_DATA ! 464: in ax, dx ! 465: pop dx ! 466: ret ! 467: ! 468: vga_set_virt_width: ! 469: push ax ! 470: push bx ! 471: push dx ! 472: mov bx, ax ! 473: call dispi_get_bpp ! 474: cmp al, #0x04 ! 475: ja set_width_svga ! 476: shr bx, #1 ! 477: set_width_svga: ! 478: shr bx, #3 ! 479: mov dx, # VGAREG_VGA_CRTC_ADDRESS ! 480: mov ah, bl ! 481: mov al, #0x13 ! 482: out dx, ax ! 483: pop dx ! 484: pop bx ! 485: pop ax ! 486: ret ! 487: ! 488: dispi_set_virt_width: ! 489: call vga_set_virt_width ! 490: push dx ! 491: push ax ! 492: mov dx, # VBE_DISPI_IOPORT_INDEX ! 493: mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH ! 494: out dx, ax ! 495: pop ax ! 496: mov dx, # VBE_DISPI_IOPORT_DATA ! 497: out dx, ax ! 498: pop dx ! 499: ret ! 500: ! 501: dispi_get_virt_width: ! 502: push dx ! 503: mov dx, # VBE_DISPI_IOPORT_INDEX ! 504: mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH ! 505: out dx, ax ! 506: mov dx, # VBE_DISPI_IOPORT_DATA ! 507: in ax, dx ! 508: pop dx ! 509: ret ! 510: ! 511: dispi_get_virt_height: ! 512: push dx ! 513: mov dx, # VBE_DISPI_IOPORT_INDEX ! 514: mov ax, # VBE_DISPI_INDEX_VIRT_HEIGHT ! 515: out dx, ax ! 516: mov dx, # VBE_DISPI_IOPORT_DATA ! 517: in ax, dx ! 518: pop dx ! 519: ret ! 520: ! 521: _vga_compat_setup: ! 522: push ax ! 523: push dx ! 524: ! 525: ; set CRT X resolution ! 526: mov dx, # VBE_DISPI_IOPORT_INDEX ! 527: mov ax, # VBE_DISPI_INDEX_XRES ! 528: out dx, ax ! 529: mov dx, # VBE_DISPI_IOPORT_DATA ! 530: in ax, dx ! 531: push ax ! 532: mov dx, # VGAREG_VGA_CRTC_ADDRESS ! 533: mov ax, #0x0011 ! 534: out dx, ax ! 535: pop ax ! 536: push ax ! 537: shr ax, #3 ! 538: dec ax ! 539: mov ah, al ! 540: mov al, #0x01 ! 541: out dx, ax ! 542: pop ax ! 543: call vga_set_virt_width ! 544: ! 545: ; set CRT Y resolution ! 546: mov dx, # VBE_DISPI_IOPORT_INDEX ! 547: mov ax, # VBE_DISPI_INDEX_YRES ! 548: out dx, ax ! 549: mov dx, # VBE_DISPI_IOPORT_DATA ! 550: in ax, dx ! 551: dec ax ! 552: push ax ! 553: mov dx, # VGAREG_VGA_CRTC_ADDRESS ! 554: mov ah, al ! 555: mov al, #0x12 ! 556: out dx, ax ! 557: pop ax ! 558: mov al, #0x07 ! 559: out dx, al ! 560: inc dx ! 561: in al, dx ! 562: and al, #0xbd ! 563: test ah, #0x01 ! 564: jz bit8_clear ! 565: or al, #0x02 ! 566: bit8_clear: ! 567: test ah, #0x02 ! 568: jz bit9_clear ! 569: or al, #0x40 ! 570: bit9_clear: ! 571: out dx, al ! 572: ! 573: ; other settings ! 574: mov dx, # VGAREG_VGA_CRTC_ADDRESS ! 575: mov ax, #0x0009 ! 576: out dx, ax ! 577: mov al, #0x17 ! 578: out dx, al ! 579: mov dx, # VGAREG_VGA_CRTC_DATA ! 580: in al, dx ! 581: or al, #0x03 ! 582: out dx, al ! 583: mov dx, # VGAREG_ACTL_RESET ! 584: in al, dx ! 585: mov dx, # VGAREG_ACTL_ADDRESS ! 586: mov al, #0x10 ! 587: out dx, al ! 588: mov dx, # VGAREG_ACTL_READ_DATA ! 589: in al, dx ! 590: or al, #0x01 ! 591: mov dx, # VGAREG_ACTL_ADDRESS ! 592: out dx, al ! 593: mov al, #0x20 ! 594: out dx, al ! 595: mov dx, # VGAREG_GRDC_ADDRESS ! 596: mov ax, #0x0506 ! 597: out dx, ax ! 598: mov dx, # VGAREG_SEQU_ADDRESS ! 599: mov ax, #0x0f02 ! 600: out dx, ax ! 601: ! 602: ; settings for >= 8bpp ! 603: mov dx, # VBE_DISPI_IOPORT_INDEX ! 604: mov ax, # VBE_DISPI_INDEX_BPP ! 605: out dx, ax ! 606: mov dx, # VBE_DISPI_IOPORT_DATA ! 607: in ax, dx ! 608: cmp al, #0x08 ! 609: jb vga_compat_end ! 610: mov dx, # VGAREG_VGA_CRTC_ADDRESS ! 611: mov al, #0x14 ! 612: out dx, al ! 613: mov dx, # VGAREG_VGA_CRTC_DATA ! 614: in al, dx ! 615: or al, #0x40 ! 616: out dx, al ! 617: mov dx, # VGAREG_ACTL_RESET ! 618: in al, dx ! 619: mov dx, # VGAREG_ACTL_ADDRESS ! 620: mov al, #0x10 ! 621: out dx, al ! 622: mov dx, # VGAREG_ACTL_READ_DATA ! 623: in al, dx ! 624: or al, #0x40 ! 625: mov dx, # VGAREG_ACTL_ADDRESS ! 626: out dx, al ! 627: mov al, #0x20 ! 628: out dx, al ! 629: mov dx, # VGAREG_SEQU_ADDRESS ! 630: mov al, #0x04 ! 631: out dx, al ! 632: mov dx, # VGAREG_SEQU_DATA ! 633: in al, dx ! 634: or al, #0x08 ! 635: out dx, al ! 636: mov dx, # VGAREG_GRDC_ADDRESS ! 637: mov al, #0x05 ! 638: out dx, al ! 639: mov dx, # VGAREG_GRDC_DATA ! 640: in al, dx ! 641: and al, #0x9f ! 642: or al, #0x40 ! 643: out dx, al ! 644: ! 645: vga_compat_end: ! 646: pop dx ! 647: pop ax ! 648: ASM_END ! 649: ! 650: ! 651: // ModeInfo helper function ! 652: static ModeInfoListItem* mode_info_find_mode(mode, using_lfb) ! 653: Bit16u mode; Boolean using_lfb; ! 654: { ! 655: ModeInfoListItem *cur_info=&mode_info_list; ! 656: ! 657: while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST) ! 658: { ! 659: if (cur_info->mode == mode) ! 660: { ! 661: if (!using_lfb) ! 662: { ! 663: return cur_info; ! 664: } ! 665: else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE) ! 666: { ! 667: return cur_info; ! 668: } ! 669: else ! 670: { ! 671: cur_info++; ! 672: } ! 673: } ! 674: else ! 675: { ! 676: cur_info++; ! 677: } ! 678: } ! 679: ! 680: return 0; ! 681: } ! 682: ! 683: ASM_START ! 684: ! 685: ; Has VBE display - Returns true if VBE display detected ! 686: ! 687: _vbe_has_vbe_display: ! 688: push ds ! 689: push bx ! 690: mov ax, # BIOSMEM_SEG ! 691: mov ds, ax ! 692: mov bx, # BIOSMEM_VBE_FLAG ! 693: mov al, [bx] ! 694: and al, #0x01 ! 695: xor ah, ah ! 696: pop bx ! 697: pop ds ! 698: ret ! 699: ! 700: ; VBE Init - Initialise the Vesa Bios Extension Code ! 701: ; This function does a sanity check on the host side display code interface. ! 702: ! 703: vbe_init: ! 704: mov ax, # VBE_DISPI_ID0 ! 705: call dispi_set_id ! 706: call dispi_get_id ! 707: cmp ax, # VBE_DISPI_ID0 ! 708: jne no_vbe_interface ! 709: push ds ! 710: push bx ! 711: mov ax, # BIOSMEM_SEG ! 712: mov ds, ax ! 713: mov bx, # BIOSMEM_VBE_FLAG ! 714: mov al, #0x01 ! 715: mov [bx], al ! 716: pop bx ! 717: pop ds ! 718: mov ax, # VBE_DISPI_ID4 ! 719: call dispi_set_id ! 720: no_vbe_interface: ! 721: #if defined(USE_BX_INFO) || defined(DEBUG) ! 722: mov bx, #msg_vbe_init ! 723: push bx ! 724: call _printf ! 725: inc sp ! 726: inc sp ! 727: #endif ! 728: ret ! 729: ! 730: ; VBE Display Info - Display information on screen about the VBE ! 731: ! 732: vbe_display_info: ! 733: call _vbe_has_vbe_display ! 734: test ax, ax ! 735: jz no_vbe_flag ! 736: mov ax, #0xc000 ! 737: mov ds, ax ! 738: mov si, #_vbebios_info_string ! 739: jmp _display_string ! 740: no_vbe_flag: ! 741: mov ax, #0xc000 ! 742: mov ds, ax ! 743: mov si, #_no_vbebios_info_string ! 744: jmp _display_string ! 745: ASM_END ! 746: ! 747: /** Function 00h - Return VBE Controller Information ! 748: * ! 749: * Input: ! 750: * AX = 4F00h ! 751: * ES:DI = Pointer to buffer in which to place VbeInfoBlock structure ! 752: * (VbeSignature should be VBE2 when VBE 2.0 information is desired and ! 753: * the info block is 512 bytes in size) ! 754: * Output: ! 755: * AX = VBE Return Status ! 756: * ! 757: */ ! 758: void vbe_biosfn_return_controller_information(AX, ES, DI) ! 759: Bit16u *AX;Bit16u ES;Bit16u DI; ! 760: { ! 761: Bit16u ss=get_SS(); ! 762: VbeInfoBlock vbe_info_block; ! 763: Bit16u status; ! 764: Bit16u result; ! 765: Bit16u vbe2_info; ! 766: Bit16u cur_mode=0; ! 767: Bit16u cur_ptr=34; ! 768: ModeInfoListItem *cur_info=&mode_info_list; ! 769: ! 770: status = read_word(ss, AX); ! 771: ! 772: #ifdef DEBUG ! 773: printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status); ! 774: #endif ! 775: ! 776: vbe2_info = 0; ! 777: #ifdef VBE2_NO_VESA_CHECK ! 778: #else ! 779: // get vbe_info_block into local variable ! 780: memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block)); ! 781: ! 782: // check for VBE2 signature ! 783: if (((vbe_info_block.VbeSignature[0] == 'V') && ! 784: (vbe_info_block.VbeSignature[1] == 'B') && ! 785: (vbe_info_block.VbeSignature[2] == 'E') && ! 786: (vbe_info_block.VbeSignature[3] == '2')) || ! 787: ! 788: ((vbe_info_block.VbeSignature[0] == 'V') && ! 789: (vbe_info_block.VbeSignature[1] == 'E') && ! 790: (vbe_info_block.VbeSignature[2] == 'S') && ! 791: (vbe_info_block.VbeSignature[3] == 'A')) ) ! 792: { ! 793: vbe2_info = 1; ! 794: #ifdef DEBUG ! 795: printf("VBE correct VESA/VBE2 signature found\n"); ! 796: #endif ! 797: } ! 798: #endif ! 799: ! 800: // VBE Signature ! 801: vbe_info_block.VbeSignature[0] = 'V'; ! 802: vbe_info_block.VbeSignature[1] = 'E'; ! 803: vbe_info_block.VbeSignature[2] = 'S'; ! 804: vbe_info_block.VbeSignature[3] = 'A'; ! 805: ! 806: // VBE Version supported ! 807: vbe_info_block.VbeVersion = 0x0200; ! 808: ! 809: // OEM String ! 810: vbe_info_block.OemStringPtr_Seg = 0xc000; ! 811: vbe_info_block.OemStringPtr_Off = &vbebios_copyright; ! 812: ! 813: // Capabilities ! 814: vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC; ! 815: vbe_info_block.Capabilities[1] = 0; ! 816: vbe_info_block.Capabilities[2] = 0; ! 817: vbe_info_block.Capabilities[3] = 0; ! 818: ! 819: // VBE Video Mode Pointer (dynamicly generated from the mode_info_list) ! 820: vbe_info_block.VideoModePtr_Seg= ES ; ! 821: vbe_info_block.VideoModePtr_Off= DI + 34; ! 822: ! 823: // VBE Total Memory (in 64b blocks) ! 824: vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K; ! 825: ! 826: if (vbe2_info) ! 827: { ! 828: // OEM Stuff ! 829: vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV; ! 830: vbe_info_block.OemVendorNamePtr_Seg = 0xc000; ! 831: vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name; ! 832: vbe_info_block.OemProductNamePtr_Seg = 0xc000; ! 833: vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name; ! 834: vbe_info_block.OemProductRevPtr_Seg = 0xc000; ! 835: vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision; ! 836: ! 837: // copy updates in vbe_info_block back ! 838: memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block)); ! 839: } ! 840: else ! 841: { ! 842: // copy updates in vbe_info_block back (VBE 1.x compatibility) ! 843: memcpyb(ES, DI, ss, &vbe_info_block, 256); ! 844: } ! 845: ! 846: do ! 847: { ! 848: if ((cur_info->info.XResolution <= dispi_get_max_xres()) && ! 849: (cur_info->info.BitsPerPixel <= dispi_get_max_bpp())) { ! 850: #ifdef DEBUG ! 851: printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); ! 852: #endif ! 853: write_word(ES, DI + cur_ptr, cur_info->mode); ! 854: cur_mode++; ! 855: cur_ptr+=2; ! 856: } else { ! 857: #ifdef DEBUG ! 858: printf("VBE mode %x (xres=%x / bpp=%02x) not supported by display\n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel); ! 859: #endif ! 860: } ! 861: cur_info++; ! 862: } while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST); ! 863: ! 864: // Add vesa mode list terminator ! 865: write_word(ES, DI + cur_ptr, cur_info->mode); ! 866: ! 867: result = 0x4f; ! 868: ! 869: write_word(ss, AX, result); ! 870: } ! 871: ! 872: ! 873: /** Function 01h - Return VBE Mode Information ! 874: * ! 875: * Input: ! 876: * AX = 4F01h ! 877: * CX = Mode Number ! 878: * ES:DI = Pointer to buffer in which to place ModeInfoBlock structure ! 879: * Output: ! 880: * AX = VBE Return Status ! 881: * ! 882: */ ! 883: void vbe_biosfn_return_mode_information(AX, CX, ES, DI) ! 884: Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; ! 885: { ! 886: Bit16u result=0x0100; ! 887: Bit16u ss=get_SS(); ! 888: ModeInfoBlock info; ! 889: ModeInfoListItem *cur_info; ! 890: Boolean using_lfb; ! 891: ! 892: #ifdef DEBUG ! 893: printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX); ! 894: #endif ! 895: ! 896: using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); ! 897: ! 898: CX = (CX & 0x1ff); ! 899: ! 900: cur_info = mode_info_find_mode(CX, using_lfb, &cur_info); ! 901: ! 902: if (cur_info != 0) ! 903: { ! 904: #ifdef DEBUG ! 905: printf("VBE found mode %x\n",CX); ! 906: #endif ! 907: memsetb(ss, &info, 0, sizeof(ModeInfoBlock)); ! 908: memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); ! 909: if (using_lfb) { ! 910: info.NumberOfBanks = 1; ! 911: } ! 912: if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) { ! 913: info.WinFuncPtr = 0xC0000000UL; ! 914: *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall); ! 915: } ! 916: ! 917: result = 0x4f; ! 918: } ! 919: else ! 920: { ! 921: #ifdef DEBUG ! 922: printf("VBE *NOT* found mode %x\n",CX); ! 923: #endif ! 924: result = 0x100; ! 925: } ! 926: ! 927: if (result == 0x4f) ! 928: { ! 929: // copy updates in mode_info_block back ! 930: memcpyb(ES, DI, ss, &info, sizeof(info)); ! 931: } ! 932: ! 933: write_word(ss, AX, result); ! 934: } ! 935: ! 936: /** Function 02h - Set VBE Mode ! 937: * ! 938: * Input: ! 939: * AX = 4F02h ! 940: * BX = Desired Mode to set ! 941: * ES:DI = Pointer to CRTCInfoBlock structure ! 942: * Output: ! 943: * AX = VBE Return Status ! 944: * ! 945: */ ! 946: void vbe_biosfn_set_mode(AX, BX, ES, DI) ! 947: Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI; ! 948: { ! 949: Bit16u ss = get_SS(); ! 950: Bit16u result; ! 951: ModeInfoListItem *cur_info; ! 952: Boolean using_lfb; ! 953: Bit8u no_clear; ! 954: Bit8u lfb_flag; ! 955: ! 956: using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); ! 957: lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0; ! 958: no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0; ! 959: ! 960: BX = (BX & 0x1ff); ! 961: ! 962: //result=read_word(ss,AX); ! 963: ! 964: // check for non vesa mode ! 965: if (BX<VBE_MODE_VESA_DEFINED) ! 966: { ! 967: Bit8u mode; ! 968: ! 969: dispi_set_enable(VBE_DISPI_DISABLED); ! 970: // call the vgabios in order to set the video mode ! 971: // this allows for going back to textmode with a VBE call (some applications expect that to work) ! 972: ! 973: mode=(BX & 0xff); ! 974: biosfn_set_video_mode(mode); ! 975: result = 0x4f; ! 976: } ! 977: ! 978: cur_info = mode_info_find_mode(BX, using_lfb, &cur_info); ! 979: ! 980: if (cur_info != 0) ! 981: { ! 982: #ifdef DEBUG ! 983: printf("VBE found mode %x, setting:\n", BX); ! 984: printf("\txres%x yres%x bpp%x\n", ! 985: cur_info->info.XResolution, ! 986: cur_info->info.YResolution, ! 987: cur_info->info.BitsPerPixel); ! 988: #endif ! 989: ! 990: // first disable current mode (when switching between vesa modi) ! 991: dispi_set_enable(VBE_DISPI_DISABLED); ! 992: ! 993: if (cur_info->info.BitsPerPixel == 4) ! 994: { ! 995: biosfn_set_video_mode(0x6a); ! 996: } ! 997: ! 998: dispi_set_bpp(cur_info->info.BitsPerPixel); ! 999: dispi_set_xres(cur_info->info.XResolution); ! 1000: dispi_set_yres(cur_info->info.YResolution); ! 1001: dispi_set_bank(0); ! 1002: dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag); ! 1003: vga_compat_setup(); ! 1004: ! 1005: write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX); ! 1006: write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear)); ! 1007: ! 1008: result = 0x4f; ! 1009: } ! 1010: else ! 1011: { ! 1012: #ifdef DEBUG ! 1013: printf("VBE *NOT* found mode %x\n" , BX); ! 1014: #endif ! 1015: result = 0x100; ! 1016: ! 1017: // FIXME: redirect non VBE modi to normal VGA bios operation ! 1018: // (switch back to VGA mode ! 1019: if (BX == 3) ! 1020: result = 0x4f; ! 1021: } ! 1022: ! 1023: write_word(ss, AX, result); ! 1024: } ! 1025: ! 1026: /** Function 03h - Return Current VBE Mode ! 1027: * ! 1028: * Input: ! 1029: * AX = 4F03h ! 1030: * Output: ! 1031: * AX = VBE Return Status ! 1032: * BX = Current VBE Mode ! 1033: * ! 1034: */ ! 1035: ASM_START ! 1036: vbe_biosfn_return_current_mode: ! 1037: push ds ! 1038: mov ax, # BIOSMEM_SEG ! 1039: mov ds, ax ! 1040: call dispi_get_enable ! 1041: and ax, # VBE_DISPI_ENABLED ! 1042: jz no_vbe_mode ! 1043: mov bx, # BIOSMEM_VBE_MODE ! 1044: mov ax, [bx] ! 1045: mov bx, ax ! 1046: jnz vbe_03_ok ! 1047: no_vbe_mode: ! 1048: mov bx, # BIOSMEM_CURRENT_MODE ! 1049: mov al, [bx] ! 1050: mov bl, al ! 1051: xor bh, bh ! 1052: vbe_03_ok: ! 1053: mov ax, #0x004f ! 1054: pop ds ! 1055: ret ! 1056: ASM_END ! 1057: ! 1058: ! 1059: Bit16u vbe_biosfn_read_video_state_size() ! 1060: { ! 1061: return 9 * 2; ! 1062: } ! 1063: ! 1064: void vbe_biosfn_save_video_state(ES, BX) ! 1065: Bit16u ES; Bit16u BX; ! 1066: { ! 1067: Bit16u enable, i; ! 1068: ! 1069: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); ! 1070: enable = inw(VBE_DISPI_IOPORT_DATA); ! 1071: write_word(ES, BX, enable); ! 1072: BX += 2; ! 1073: if (!(enable & VBE_DISPI_ENABLED)) ! 1074: return; ! 1075: for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { ! 1076: if (i != VBE_DISPI_INDEX_ENABLE) { ! 1077: outw(VBE_DISPI_IOPORT_INDEX, i); ! 1078: write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA)); ! 1079: BX += 2; ! 1080: } ! 1081: } ! 1082: } ! 1083: ! 1084: ! 1085: void vbe_biosfn_restore_video_state(ES, BX) ! 1086: Bit16u ES; Bit16u BX; ! 1087: { ! 1088: Bit16u enable, i; ! 1089: ! 1090: enable = read_word(ES, BX); ! 1091: BX += 2; ! 1092: ! 1093: if (!(enable & VBE_DISPI_ENABLED)) { ! 1094: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); ! 1095: outw(VBE_DISPI_IOPORT_DATA, enable); ! 1096: } else { ! 1097: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES); ! 1098: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ! 1099: BX += 2; ! 1100: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES); ! 1101: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ! 1102: BX += 2; ! 1103: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP); ! 1104: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ! 1105: BX += 2; ! 1106: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); ! 1107: outw(VBE_DISPI_IOPORT_DATA, enable); ! 1108: ! 1109: for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { ! 1110: outw(VBE_DISPI_IOPORT_INDEX, i); ! 1111: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ! 1112: BX += 2; ! 1113: } ! 1114: } ! 1115: } ! 1116: ! 1117: /** Function 04h - Save/Restore State ! 1118: * ! 1119: * Input: ! 1120: * AX = 4F04h ! 1121: * DL = 00h Return Save/Restore State buffer size ! 1122: * 01h Save State ! 1123: * 02h Restore State ! 1124: * CX = Requested states ! 1125: * ES:BX = Pointer to buffer (if DL <> 00h) ! 1126: * Output: ! 1127: * AX = VBE Return Status ! 1128: * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h) ! 1129: * ! 1130: */ ! 1131: void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX) ! 1132: Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX; ! 1133: { ! 1134: Bit16u ss=get_SS(); ! 1135: Bit16u result, val; ! 1136: ! 1137: result = 0x4f; ! 1138: switch(GET_DL()) { ! 1139: case 0x00: ! 1140: val = biosfn_read_video_state_size2(CX); ! 1141: #ifdef DEBUG ! 1142: printf("VGA state size=%x\n", val); ! 1143: #endif ! 1144: if (CX & 8) ! 1145: val += vbe_biosfn_read_video_state_size(); ! 1146: write_word(ss, BX, val); ! 1147: break; ! 1148: case 0x01: ! 1149: val = read_word(ss, BX); ! 1150: val = biosfn_save_video_state(CX, ES, val); ! 1151: #ifdef DEBUG ! 1152: printf("VGA save_state offset=%x\n", val); ! 1153: #endif ! 1154: if (CX & 8) ! 1155: vbe_biosfn_save_video_state(ES, val); ! 1156: break; ! 1157: case 0x02: ! 1158: val = read_word(ss, BX); ! 1159: val = biosfn_restore_video_state(CX, ES, val); ! 1160: #ifdef DEBUG ! 1161: printf("VGA restore_state offset=%x\n", val); ! 1162: #endif ! 1163: if (CX & 8) ! 1164: vbe_biosfn_restore_video_state(ES, val); ! 1165: break; ! 1166: default: ! 1167: // function failed ! 1168: result = 0x100; ! 1169: break; ! 1170: } ! 1171: write_word(ss, AX, result); ! 1172: } ! 1173: ! 1174: /** Function 05h - Display Window Control ! 1175: * ! 1176: * Input: ! 1177: * AX = 4F05h ! 1178: * (16-bit) BH = 00h Set memory window ! 1179: * = 01h Get memory window ! 1180: * BL = Window number ! 1181: * = 00h Window A ! 1182: * = 01h Window B ! 1183: * DX = Window number in video memory in window ! 1184: * granularity units (Set Memory Window only) ! 1185: * Note: ! 1186: * If this function is called while in a linear frame buffer mode, ! 1187: * this function must fail with completion code AH=03h ! 1188: * ! 1189: * Output: ! 1190: * AX = VBE Return Status ! 1191: * DX = Window number in window granularity units ! 1192: * (Get Memory Window only) ! 1193: */ ! 1194: ASM_START ! 1195: vbe_biosfn_display_window_control: ! 1196: cmp bl, #0x00 ! 1197: jne vbe_05_failed ! 1198: cmp bh, #0x01 ! 1199: je get_display_window ! 1200: jb set_display_window ! 1201: mov ax, #0x0100 ! 1202: ret ! 1203: set_display_window: ! 1204: mov ax, dx ! 1205: call _dispi_set_bank ! 1206: call dispi_get_bank ! 1207: cmp ax, dx ! 1208: jne vbe_05_failed ! 1209: mov ax, #0x004f ! 1210: ret ! 1211: get_display_window: ! 1212: call dispi_get_bank ! 1213: mov dx, ax ! 1214: mov ax, #0x004f ! 1215: ret ! 1216: vbe_05_failed: ! 1217: mov ax, #0x014f ! 1218: ret ! 1219: ASM_END ! 1220: ! 1221: ! 1222: /** Function 06h - Set/Get Logical Scan Line Length ! 1223: * ! 1224: * Input: ! 1225: * AX = 4F06h ! 1226: * BL = 00h Set Scan Line Length in Pixels ! 1227: * = 01h Get Scan Line Length ! 1228: * = 02h Set Scan Line Length in Bytes ! 1229: * = 03h Get Maximum Scan Line Length ! 1230: * CX = If BL=00h Desired Width in Pixels ! 1231: * If BL=02h Desired Width in Bytes ! 1232: * (Ignored for Get Functions) ! 1233: * ! 1234: * Output: ! 1235: * AX = VBE Return Status ! 1236: * BX = Bytes Per Scan Line ! 1237: * CX = Actual Pixels Per Scan Line ! 1238: * (truncated to nearest complete pixel) ! 1239: * DX = Maximum Number of Scan Lines ! 1240: */ ! 1241: ASM_START ! 1242: vbe_biosfn_set_get_logical_scan_line_length: ! 1243: mov ax, cx ! 1244: cmp bl, #0x01 ! 1245: je get_logical_scan_line_length ! 1246: cmp bl, #0x02 ! 1247: je set_logical_scan_line_bytes ! 1248: jb set_logical_scan_line_pixels ! 1249: mov ax, #0x0100 ! 1250: ret ! 1251: set_logical_scan_line_bytes: ! 1252: push ax ! 1253: call dispi_get_bpp ! 1254: xor bh, bh ! 1255: mov bl, ah ! 1256: or bl, bl ! 1257: jnz no_4bpp_1 ! 1258: shl ax, #3 ! 1259: mov bl, #1 ! 1260: no_4bpp_1: ! 1261: xor dx, dx ! 1262: pop ax ! 1263: div bx ! 1264: set_logical_scan_line_pixels: ! 1265: call dispi_set_virt_width ! 1266: get_logical_scan_line_length: ! 1267: call dispi_get_bpp ! 1268: xor bh, bh ! 1269: mov bl, ah ! 1270: call dispi_get_virt_width ! 1271: mov cx, ax ! 1272: or bl, bl ! 1273: jnz no_4bpp_2 ! 1274: shr ax, #3 ! 1275: mov bl, #1 ! 1276: no_4bpp_2: ! 1277: mul bx ! 1278: mov bx, ax ! 1279: call dispi_get_virt_height ! 1280: mov dx, ax ! 1281: mov ax, #0x004f ! 1282: ret ! 1283: ASM_END ! 1284: ! 1285: ! 1286: /** Function 07h - Set/Get Display Start ! 1287: * ! 1288: * Input(16-bit): ! 1289: * AX = 4F07h ! 1290: * BH = 00h Reserved and must be 00h ! 1291: * BL = 00h Set Display Start ! 1292: * = 01h Get Display Start ! 1293: * = 02h Schedule Display Start (Alternate) ! 1294: * = 03h Schedule Stereoscopic Display Start ! 1295: * = 04h Get Scheduled Display Start Status ! 1296: * = 05h Enable Stereoscopic Mode ! 1297: * = 06h Disable Stereoscopic Mode ! 1298: * = 80h Set Display Start during Vertical Retrace ! 1299: * = 82h Set Display Start during Vertical Retrace (Alternate) ! 1300: * = 83h Set Stereoscopic Display Start during Vertical Retrace ! 1301: * ECX = If BL=02h/82h Display Start Address in bytes ! 1302: * If BL=03h/83h Left Image Start Address in bytes ! 1303: * EDX = If BL=03h/83h Right Image Start Address in bytes ! 1304: * CX = If BL=00h/80h First Displayed Pixel In Scan Line ! 1305: * DX = If BL=00h/80h First Displayed Scan Line ! 1306: * ! 1307: * Output: ! 1308: * AX = VBE Return Status ! 1309: * BH = If BL=01h Reserved and will be 0 ! 1310: * CX = If BL=01h First Displayed Pixel In Scan Line ! 1311: * If BL=04h 0 if flip has not occurred, not 0 if it has ! 1312: * DX = If BL=01h First Displayed Scan Line ! 1313: * ! 1314: * Input(32-bit): ! 1315: * BH = 00h Reserved and must be 00h ! 1316: * BL = 00h Set Display Start ! 1317: * = 80h Set Display Start during Vertical Retrace ! 1318: * CX = Bits 0-15 of display start address ! 1319: * DX = Bits 16-31 of display start address ! 1320: * ES = Selector for memory mapped registers ! 1321: */ ! 1322: ASM_START ! 1323: vbe_biosfn_set_get_display_start: ! 1324: cmp bl, #0x80 ! 1325: je set_display_start ! 1326: cmp bl, #0x01 ! 1327: je get_display_start ! 1328: jb set_display_start ! 1329: mov ax, #0x0100 ! 1330: ret ! 1331: set_display_start: ! 1332: mov ax, cx ! 1333: call dispi_set_x_offset ! 1334: mov ax, dx ! 1335: call dispi_set_y_offset ! 1336: mov ax, #0x004f ! 1337: ret ! 1338: get_display_start: ! 1339: call dispi_get_x_offset ! 1340: mov cx, ax ! 1341: call dispi_get_y_offset ! 1342: mov dx, ax ! 1343: xor bh, bh ! 1344: mov ax, #0x004f ! 1345: ret ! 1346: ASM_END ! 1347: ! 1348: ! 1349: /** Function 08h - Set/Get Dac Palette Format ! 1350: * ! 1351: * Input: ! 1352: * AX = 4F08h ! 1353: * BL = 00h set DAC palette width ! 1354: * = 01h get DAC palette width ! 1355: * BH = If BL=00h: desired number of bits per primary color ! 1356: * Output: ! 1357: * AX = VBE Return Status ! 1358: * BH = current number of bits per primary color (06h = standard VGA) ! 1359: */ ! 1360: ASM_START ! 1361: vbe_biosfn_set_get_dac_palette_format: ! 1362: cmp bl, #0x01 ! 1363: je get_dac_palette_format ! 1364: jb set_dac_palette_format ! 1365: mov ax, #0x0100 ! 1366: ret ! 1367: set_dac_palette_format: ! 1368: call dispi_get_enable ! 1369: cmp bh, #0x06 ! 1370: je set_normal_dac ! 1371: cmp bh, #0x08 ! 1372: jne vbe_08_unsupported ! 1373: or ax, # VBE_DISPI_8BIT_DAC ! 1374: jnz set_dac_mode ! 1375: set_normal_dac: ! 1376: and ax, #~ VBE_DISPI_8BIT_DAC ! 1377: set_dac_mode: ! 1378: call _dispi_set_enable ! 1379: get_dac_palette_format: ! 1380: mov bh, #0x06 ! 1381: call dispi_get_enable ! 1382: and ax, # VBE_DISPI_8BIT_DAC ! 1383: jz vbe_08_ok ! 1384: mov bh, #0x08 ! 1385: vbe_08_ok: ! 1386: mov ax, #0x004f ! 1387: ret ! 1388: vbe_08_unsupported: ! 1389: mov ax, #0x014f ! 1390: ret ! 1391: ASM_END ! 1392: ! 1393: ! 1394: /** Function 09h - Set/Get Palette Data ! 1395: * ! 1396: * Input: ! 1397: * AX = 4F09h ! 1398: * Output: ! 1399: * AX = VBE Return Status ! 1400: * ! 1401: * FIXME: incomplete API description, Input & Output ! 1402: */ ! 1403: void vbe_biosfn_set_get_palette_data(AX) ! 1404: { ! 1405: } ! 1406: ! 1407: /** Function 0Ah - Return VBE Protected Mode Interface ! 1408: * Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface ! 1409: * BL = 00h Return protected mode table ! 1410: * ! 1411: * ! 1412: * Output: AX = Status ! 1413: * ES = Real Mode Segment of Table ! 1414: * DI = Offset of Table ! 1415: * CX = Length of Table including protected mode code ! 1416: * (for copying purposes) ! 1417: */ ! 1418: ASM_START ! 1419: vbe_biosfn_return_protected_mode_interface: ! 1420: test bl, bl ! 1421: jnz _fail ! 1422: mov di, #0xc000 ! 1423: mov es, di ! 1424: mov di, # vesa_pm_start ! 1425: mov cx, # vesa_pm_end ! 1426: sub cx, di ! 1427: mov ax, #0x004f ! 1428: ret ! 1429: _fail: ! 1430: mov ax, #0x014f ! 1431: ret ! 1432: ASM_END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.