1 // 2 // QEMU Cirrus CLGD 54xx VGABIOS Extension. 3 // 4 // Copyright (c) 2004 Makoto Suzuki (suzu) 5 // 6 // This library is free software; you can redistribute it and/or 7 // modify it under the terms of the GNU Lesser General Public 8 // License as published by the Free Software Foundation; either 9 // version 2 of the License, or (at your option) any later version. 10 // 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // Lesser General Public License for more details. 15 // 16 // You should have received a copy of the GNU Lesser General Public 17 // License along with this library; If not, see <http://www.gnu.org/licenses/>. 18 // 19 20 //#define CIRRUS_VESA3_PMINFO 21 #ifdef VBE 22 #undef CIRRUS_VESA3_PMINFO 23 #endif 24 25 #define PM_BIOSMEM_CURRENT_MODE 0x449 26 #define PM_BIOSMEM_CRTC_ADDRESS 0x463 27 #define PM_BIOSMEM_VBE_MODE 0x4BA 28 #define PM_BIOSMEM_VBE_POWER 0x4BC 29 30 typedef struct 31 { 32 /* + 0 */ 33 unsigned short mode; 34 unsigned short width; 35 unsigned short height; 36 unsigned short depth; 37 /* + 8 */ 38 unsigned short hidden_dac; /* 0x3c6 */ 39 unsigned short *seq; /* 0x3c4 */ 40 unsigned short *graph; /* 0x3ce */ 41 unsigned short *crtc; /* 0x3d4 */ 42 /* +16 */ 43 unsigned char bitsperpixel; 44 unsigned char vesacolortype; 45 unsigned char vesaredmask; 46 unsigned char vesaredpos; 47 unsigned char vesagreenmask; 48 unsigned char vesagreenpos; 49 unsigned char vesabluemask; 50 unsigned char vesabluepos; 51 /* +24 */ 52 unsigned char vesareservedmask; 53 unsigned char vesareservedpos; 54 } cirrus_mode_t; 55 #define CIRRUS_MODE_SIZE 26 56 57 58 /* For VESA BIOS 3.0 */ 59 #define CIRRUS_PM16INFO_SIZE 20 60 61 /* VGA */ 62 unsigned short cseq_vga[] = {0x0007,0xffff}; 63 unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff}; 64 unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff}; 65 66 /* extensions */ 67 unsigned short cgraph_svgacolor[] = { 68 0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08, 69 0x0009,0x000a,0x000b, 70 0xffff 71 }; 72 /* 640x480x8 */ 73 unsigned short cseq_640x480x8[] = { 74 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 75 0x580b,0x580c,0x580d,0x580e, 76 0x0412,0x0013,0x2017, 77 0x331b,0x331c,0x331d,0x331e, 78 0xffff 79 }; 80 unsigned short ccrtc_640x480x8[] = { 81 0x2c11, 82 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 83 0x4009,0x000c,0x000d, 84 0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18, 85 0x001a,0x221b,0x001d, 86 0xffff 87 }; 88 /* 640x480x16 */ 89 unsigned short cseq_640x480x16[] = { 90 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 91 0x580b,0x580c,0x580d,0x580e, 92 0x0412,0x0013,0x2017, 93 0x331b,0x331c,0x331d,0x331e, 94 0xffff 95 }; 96 unsigned short ccrtc_640x480x16[] = { 97 0x2c11, 98 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 99 0x4009,0x000c,0x000d, 100 0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18, 101 0x001a,0x221b,0x001d, 102 0xffff 103 }; 104 /* 640x480x24 */ 105 unsigned short cseq_640x480x24[] = { 106 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, 107 0x580b,0x580c,0x580d,0x580e, 108 0x0412,0x0013,0x2017, 109 0x331b,0x331c,0x331d,0x331e, 110 0xffff 111 }; 112 unsigned short ccrtc_640x480x24[] = { 113 0x2c11, 114 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 115 0x4009,0x000c,0x000d, 116 0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18, 117 0x001a,0x321b,0x001d, 118 0xffff 119 }; 120 /* 800x600x8 */ 121 unsigned short cseq_800x600x8[] = { 122 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 123 0x230b,0x230c,0x230d,0x230e, 124 0x0412,0x0013,0x2017, 125 0x141b,0x141c,0x141d,0x141e, 126 0xffff 127 }; 128 unsigned short ccrtc_800x600x8[] = { 129 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, 130 0x6009,0x000c,0x000d, 131 0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18, 132 0x001a,0x221b,0x001d, 133 0xffff 134 }; 135 /* 800x600x16 */ 136 unsigned short cseq_800x600x16[] = { 137 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 138 0x230b,0x230c,0x230d,0x230e, 139 0x0412,0x0013,0x2017, 140 0x141b,0x141c,0x141d,0x141e, 141 0xffff 142 }; 143 unsigned short ccrtc_800x600x16[] = { 144 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, 145 0x6009,0x000c,0x000d, 146 0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18, 147 0x001a,0x221b,0x001d, 148 0xffff 149 }; 150 /* 800x600x24 */ 151 unsigned short cseq_800x600x24[] = { 152 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, 153 0x230b,0x230c,0x230d,0x230e, 154 0x0412,0x0013,0x2017, 155 0x141b,0x141c,0x141d,0x141e, 156 0xffff 157 }; 158 unsigned short ccrtc_800x600x24[] = { 159 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, 160 0x6009,0x000c,0x000d, 161 0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18, 162 0x001a,0x321b,0x001d, 163 0xffff 164 }; 165 /* 1024x768x8 */ 166 unsigned short cseq_1024x768x8[] = { 167 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 168 0x760b,0x760c,0x760d,0x760e, 169 0x0412,0x0013,0x2017, 170 0x341b,0x341c,0x341d,0x341e, 171 0xffff 172 }; 173 unsigned short ccrtc_1024x768x8[] = { 174 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, 175 0x6009,0x000c,0x000d, 176 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, 177 0x001a,0x221b,0x001d, 178 0xffff 179 }; 180 /* 1024x768x16 */ 181 unsigned short cseq_1024x768x16[] = { 182 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 183 0x760b,0x760c,0x760d,0x760e, 184 0x0412,0x0013,0x2017, 185 0x341b,0x341c,0x341d,0x341e, 186 0xffff 187 }; 188 unsigned short ccrtc_1024x768x16[] = { 189 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, 190 0x6009,0x000c,0x000d, 191 0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18, 192 0x001a,0x321b,0x001d, 193 0xffff 194 }; 195 /* 1024x768x24 */ 196 unsigned short cseq_1024x768x24[] = { 197 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, 198 0x760b,0x760c,0x760d,0x760e, 199 0x0412,0x0013,0x2017, 200 0x341b,0x341c,0x341d,0x341e, 201 0xffff 202 }; 203 unsigned short ccrtc_1024x768x24[] = { 204 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, 205 0x6009,0x000c,0x000d, 206 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, 207 0x001a,0x321b,0x001d, 208 0xffff 209 }; 210 /* 1280x1024x8 */ 211 unsigned short cseq_1280x1024x8[] = { 212 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 213 0x760b,0x760c,0x760d,0x760e, 214 0x0412,0x0013,0x2017, 215 0x341b,0x341c,0x341d,0x341e, 216 0xffff 217 }; 218 unsigned short ccrtc_1280x1024x8[] = { 219 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 220 0x6009,0x000c,0x000d, 221 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, 222 0x001a,0x221b,0x001d, 223 0xffff 224 }; 225 /* 1280x1024x16 */ 226 unsigned short cseq_1280x1024x16[] = { 227 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 228 0x760b,0x760c,0x760d,0x760e, 229 0x0412,0x0013,0x2017, 230 0x341b,0x341c,0x341d,0x341e, 231 0xffff 232 }; 233 unsigned short ccrtc_1280x1024x16[] = { 234 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 235 0x6009,0x000c,0x000d, 236 0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18, 237 0x001a,0x321b,0x001d, 238 0xffff 239 }; 240 241 /* 1600x1200x8 */ 242 unsigned short cseq_1600x1200x8[] = { 243 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 244 0x760b,0x760c,0x760d,0x760e, 245 0x0412,0x0013,0x2017, 246 0x341b,0x341c,0x341d,0x341e, 247 0xffff 248 }; 249 unsigned short ccrtc_1600x1200x8[] = { 250 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 251 0x6009,0x000c,0x000d, 252 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, 253 0x001a,0x221b,0x001d, 254 0xffff 255 }; 256 257 cirrus_mode_t cirrus_modes[] = 258 { 259 {0x5f,640,480,8,0x00, 260 cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, 261 4,0,0,0,0,0,0,0,0}, 262 {0x64,640,480,16,0xe1, 263 cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 264 6,5,11,6,5,5,0,0,0}, 265 {0x66,640,480,15,0xf0, 266 cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 267 6,5,10,5,5,5,0,1,15}, 268 {0x71,640,480,24,0xe5, 269 cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, 270 6,8,16,8,8,8,0,0,0}, 271 272 {0x5c,800,600,8,0x00, 273 cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, 274 4,0,0,0,0,0,0,0,0}, 275 {0x65,800,600,16,0xe1, 276 cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 277 6,5,11,6,5,5,0,0,0}, 278 {0x67,800,600,15,0xf0, 279 cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 280 6,5,10,5,5,5,0,1,15}, 281 282 {0x60,1024,768,8,0x00, 283 cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, 284 4,0,0,0,0,0,0,0,0}, 285 {0x74,1024,768,16,0xe1, 286 cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 287 6,5,11,6,5,5,0,0,0}, 288 {0x68,1024,768,15,0xf0, 289 cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 290 6,5,10,5,5,5,0,1,15}, 291 292 {0x78,800,600,24,0xe5, 293 cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, 294 6,8,16,8,8,8,0,0,0}, 295 {0x79,1024,768,24,0xe5, 296 cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, 297 6,8,16,8,8,8,0,0,0}, 298 299 {0x6d,1280,1024,8,0x00, 300 cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, 301 4,0,0,0,0,0,0,0,0}, 302 {0x69,1280,1024,15,0xf0, 303 cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 304 6,5,10,5,5,5,0,1,15}, 305 {0x75,1280,1024,16,0xe1, 306 cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 307 6,5,11,6,5,5,0,0,0}, 308 309 {0x7b,1600,1200,8,0x00, 310 cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, 311 4,0,0,0,0,0,0,0,0}, 312 313 {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, 314 0xff,0,0,0,0,0,0,0,0}, 315 {0xff,0,0,0,0,0,0,0,0, 316 0xff,0,0,0,0,0,0,0,0}, 317 }; 318 319 unsigned char cirrus_id_table[] = { 320 // 5430 321 0xA0, 0x32, 322 // 5446 323 0xB8, 0x39, 324 325 0xff, 0xff 326 }; 327 328 329 unsigned short cirrus_vesa_modelist[] = { 330 // 640x480x8 331 0x101, 0x5f, 332 // 640x480x15 333 0x110, 0x66, 334 // 640x480x16 335 0x111, 0x64, 336 // 640x480x24 337 0x112, 0x71, 338 // 800x600x8 339 0x103, 0x5c, 340 // 800x600x15 341 0x113, 0x67, 342 // 800x600x16 343 0x114, 0x65, 344 // 800x600x24 345 0x115, 0x78, 346 // 1024x768x8 347 0x105, 0x60, 348 // 1024x768x15 349 0x116, 0x68, 350 // 1024x768x16 351 0x117, 0x74, 352 // 1024x768x24 353 0x118, 0x79, 354 // 1280x1024x8 355 0x107, 0x6d, 356 // 1280x1024x15 357 0x119, 0x69, 358 // 1280x1024x16 359 0x11a, 0x75, 360 // invalid 361 0xffff,0xffff 362 }; 363 364 365 ASM_START 366 367 cirrus_installed: 368 .ascii "cirrus-compatible VGA is detected" 369 .byte 0x0d,0x0a 370 .byte 0x0d,0x0a,0x00 371 372 cirrus_not_installed: 373 .ascii "cirrus-compatible VGA is not detected" 374 .byte 0x0d,0x0a 375 .byte 0x0d,0x0a,0x00 376 377 cirrus_vesa_vendorname: 378 cirrus_vesa_productname: 379 cirrus_vesa_oemname: 380 .ascii "VGABIOS Cirrus extension" 381 .byte 0 382 cirrus_vesa_productrevision: 383 .ascii "1.0" 384 .byte 0 385 386 cirrus_init: 387 call cirrus_check 388 jnz no_cirrus 389 SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler) 390 mov al, #0x0f ; memory setup 391 mov dx, #0x3C4 392 out dx, al 393 inc dx 394 in al, dx 395 and al, #0x18 396 mov ah, al 397 mov al, #0x0a 398 dec dx 399 out dx, ax 400 mov ax, #0x0007 ; set vga mode 401 out dx, ax 402 mov ax, #0x0431 ; reset bitblt 403 mov dx, #0x3CE 404 out dx, ax 405 mov ax, #0x0031 406 out dx, ax 407 no_cirrus: 408 ret 409 410 cirrus_display_info: 411 push ds 412 push si 413 push cs 414 pop ds 415 call cirrus_check 416 mov si, #cirrus_not_installed 417 jnz cirrus_msgnotinstalled 418 mov si, #cirrus_installed 419 420 cirrus_msgnotinstalled: 421 call _display_string 422 pop si 423 pop ds 424 ret 425 426 cirrus_check: 427 push ax 428 push dx 429 mov ax, #0x9206 430 mov dx, #0x3C4 431 out dx, ax 432 inc dx 433 in al, dx 434 cmp al, #0x12 435 pop dx 436 pop ax 437 ret 438 439 440 cirrus_int10_handler: 441 pushf 442 push bp 443 cmp ah, #0x00 ;; set video mode 444 jz cirrus_set_video_mode 445 cmp ah, #0x12 ;; cirrus extension 446 jz cirrus_extbios 447 cmp ah, #0x4F ;; VESA extension 448 jz cirrus_vesa 449 450 cirrus_unhandled: 451 pop bp 452 popf 453 jmp vgabios_int10_handler 454 455 cirrus_return: 456 #ifdef CIRRUS_DEBUG 457 call cirrus_debug_dump 458 #endif 459 pop bp 460 popf 461 iret 462 463 cirrus_set_video_mode: 464 #ifdef CIRRUS_DEBUG 465 call cirrus_debug_dump 466 #endif 467 push si 468 push ax 469 push bx 470 push ds 471 #ifdef CIRRUS_VESA3_PMINFO 472 db 0x2e ;; cs: 473 mov si, [cirrus_vesa_sel0000_data] 474 #else 475 xor si, si 476 #endif 477 mov ds, si 478 xor bx, bx 479 mov [PM_BIOSMEM_VBE_MODE], bx 480 pop ds 481 pop bx 482 call cirrus_get_modeentry 483 jnc cirrus_set_video_mode_extended 484 mov al, #0xfe 485 call cirrus_get_modeentry_nomask 486 call cirrus_switch_mode 487 pop ax 488 pop si 489 jmp cirrus_unhandled 490 491 cirrus_extbios: 492 #ifdef CIRRUS_DEBUG 493 call cirrus_debug_dump 494 #endif 495 cmp bl, #0x80 496 jb cirrus_unhandled 497 cmp bl, #0xAF 498 ja cirrus_unhandled 499 push bx 500 and bx, #0x7F 501 shl bx, 1 502 db 0x2e ;; cs: 503 mov bp, cirrus_extbios_handlers[bx] 504 pop bx 505 push #cirrus_return 506 push bp 507 ret 508 509 cirrus_vesa: 510 #ifdef CIRRUS_DEBUG 511 call cirrus_debug_dump 512 #endif 513 cmp al, #0x10 514 ja cirrus_vesa_not_handled 515 push bx 516 xor bx, bx 517 mov bl, al 518 shl bx, 1 519 db 0x2e ;; cs: 520 mov bp, cirrus_vesa_handlers[bx] 521 pop bx 522 push #cirrus_return 523 push bp 524 ret 525 526 cirrus_vesa_not_handled: 527 mov ax, #0x014F ;; not implemented 528 jmp cirrus_return 529 530 #ifdef CIRRUS_DEBUG 531 cirrus_debug_dump: 532 push es 533 push ds 534 pusha 535 push cs 536 pop ds 537 call _cirrus_debugmsg 538 popa 539 pop ds 540 pop es 541 ret 542 #endif 543 544 cirrus_set_video_mode_extended: 545 call cirrus_switch_mode 546 pop ax ;; mode 547 test al, #0x80 548 jnz cirrus_set_video_mode_extended_1 549 push ax 550 mov ax, #0xffff ; set to 0xff to keep win 2K happy 551 call cirrus_clear_vram 552 pop ax 553 cirrus_set_video_mode_extended_1: 554 and al, #0x7f 555 556 push ds 557 #ifdef CIRRUS_VESA3_PMINFO 558 db 0x2e ;; cs: 559 mov si, [cirrus_vesa_sel0000_data] 560 #else 561 xor si, si 562 #endif 563 mov ds, si 564 mov [PM_BIOSMEM_CURRENT_MODE], al 565 pop ds 566 567 mov al, #0x20 568 569 pop si 570 jmp cirrus_return 571 572 cirrus_vesa_pmbios_init: 573 retf 574 cirrus_vesa_pmbios_entry: 575 pushf 576 push bp 577 cmp ah, #0x4F 578 jnz cirrus_vesa_pmbios_unimplemented 579 cmp al, #0x0F 580 ja cirrus_vesa_pmbios_unimplemented 581 push bx 582 xor bx, bx 583 mov bl, al 584 shl bx, 1 585 db 0x2e ;; cs: 586 mov bp, cirrus_vesa_handlers[bx] 587 pop bx 588 push #cirrus_vesa_pmbios_return 589 push bp 590 ret 591 cirrus_vesa_pmbios_unimplemented: 592 mov ax, #0x014F 593 cirrus_vesa_pmbios_return: 594 pop bp 595 popf 596 retf 597 598 ; in si:mode table 599 cirrus_switch_mode: 600 push ds 601 push bx 602 push dx 603 push cs 604 pop ds 605 606 mov bx, [si+10] ;; seq 607 mov dx, #0x3c4 608 mov ax, #0x1206 609 out dx, ax ;; Unlock cirrus special 610 call cirrus_switch_mode_setregs 611 612 mov bx, [si+12] ;; graph 613 mov dx, #0x3ce 614 call cirrus_switch_mode_setregs 615 616 mov bx, [si+14] ;; crtc 617 call cirrus_get_crtc 618 call cirrus_switch_mode_setregs 619 620 mov dx, #0x3c6 621 mov al, #0x00 622 out dx, al 623 in al, dx 624 in al, dx 625 in al, dx 626 in al, dx 627 mov al, [si+8] ;; hidden dac 628 out dx, al 629 mov al, #0xff 630 out dx, al 631 632 mov al, #0x00 633 mov bl, [si+17] ;; memory model 634 or bl, bl 635 jz is_text_mode 636 mov al, #0x01 637 cmp bl, #0x03 638 jnz is_text_mode 639 or al, #0x40 640 is_text_mode: 641 mov bl, #0x10 642 call biosfn_get_single_palette_reg 643 and bh, #0xfe 644 or bh, al 645 call biosfn_set_single_palette_reg 646 647 pop dx 648 pop bx 649 pop ds 650 ret 651 652 cirrus_enable_16k_granularity: 653 push ax 654 push dx 655 mov dx, #0x3ce 656 mov al, #0x0b 657 out dx, al 658 inc dx 659 in al, dx 660 or al, #0x20 ;; enable 16k 661 out dx, al 662 pop dx 663 pop ax 664 ret 665 666 cirrus_switch_mode_setregs: 667 csms_1: 668 mov ax, [bx] 669 cmp ax, #0xffff 670 jz csms_2 671 out dx, ax 672 add bx, #0x2 673 jmp csms_1 674 csms_2: 675 ret 676 677 cirrus_extbios_80h: 678 push dx 679 call cirrus_get_crtc 680 mov al, #0x27 681 out dx, al 682 inc dx 683 in al, dx 684 mov bx, #_cirrus_id_table 685 c80h_1: 686 db 0x2e ;; cs: 687 mov ah, [bx] 688 cmp ah, al 689 jz c80h_2 690 cmp ah, #0xff 691 jz c80h_2 692 inc bx 693 inc bx 694 jmp c80h_1 695 c80h_2: 696 db 0x2e ;; cs: 697 mov al, 0x1[bx] 698 pop dx 699 mov ah, #0x00 700 xor bx, bx 701 ret 702 703 cirrus_extbios_81h: 704 mov ax, #0x103 ;; XXX 705 ret 706 cirrus_extbios_82h: 707 push dx 708 call cirrus_get_crtc 709 xor ax, ax 710 mov al, #0x27 711 out dx, al 712 inc dx 713 in al, dx 714 and al, #0x03 715 mov ah, #0xAF 716 pop dx 717 ret 718 719 cirrus_extbios_85h: 720 push cx 721 push dx 722 mov dx, #0x3C4 723 mov al, #0x0f ;; get DRAM band width 724 out dx, al 725 inc dx 726 in al, dx 727 ;; al = 4 << bandwidth 728 mov cl, al 729 shr cl, #0x03 730 and cl, #0x03 731 cmp cl, #0x03 732 je c85h2 733 mov al, #0x04 734 shl al, cl 735 jmp c85h3 736 c85h2: 737 ;; 4MB or 2MB 738 and al, #0x80 739 mov al, #0x20 ;; 2 MB 740 je c85h3 741 mov al, #0x40 ;; 4 MB 742 c85h3: 743 pop dx 744 pop cx 745 ret 746 747 cirrus_extbios_9Ah: 748 mov ax, #0x4060 749 mov cx, #0x1132 750 ret 751 752 cirrus_extbios_A0h: 753 call cirrus_get_modeentry 754 mov ah, #0x01 755 sbb ah, #0x00 756 mov bx, cirrus_extbios_A0h_callback 757 mov si, #0xffff 758 mov di, bx 759 mov ds, bx 760 mov es, bx 761 ret 762 763 cirrus_extbios_A0h_callback: 764 ;; fatal: not implemented yet 765 cli 766 hlt 767 retf 768 769 cirrus_extbios_A1h: 770 mov bx, #0x0E00 ;; IBM 8512/8513, color 771 ret 772 773 cirrus_extbios_A2h: 774 mov al, #0x07 ;; HSync 31.5 - 64.0 kHz 775 ret 776 777 cirrus_extbios_AEh: 778 mov al, #0x01 ;; High Refresh 75Hz 779 ret 780 781 cirrus_extbios_unimplemented: 782 ret 783 784 cirrus_vesa_00h: 785 push ds 786 push si 787 mov bp, di 788 push es 789 pop ds 790 cld 791 mov ax, [di] 792 cmp ax, #0x4256 ;; VB 793 jnz cv00_1 794 mov ax, [di+2] 795 cmp ax, #0x3245 ;; E2 796 jnz cv00_1 797 ;; VBE2 798 lea di, 0x14[bp] 799 mov ax, #0x0100 ;; soft ver. 800 stosw 801 mov ax, # cirrus_vesa_vendorname 802 stosw 803 mov ax, cs 804 stosw 805 mov ax, # cirrus_vesa_productname 806 stosw 807 mov ax, cs 808 stosw 809 mov ax, # cirrus_vesa_productrevision 810 stosw 811 mov ax, cs 812 stosw 813 cv00_1: 814 mov di, bp 815 mov ax, #0x4556 ;; VE 816 stosw 817 mov ax, #0x4153 ;; SA 818 stosw 819 mov ax, #0x0200 ;; v2.00 820 stosw 821 mov ax, # cirrus_vesa_oemname 822 stosw 823 mov ax, cs 824 stosw 825 xor ax, ax ;; caps 826 stosw 827 stosw 828 lea ax, 0x40[bp] 829 stosw 830 mov ax, es 831 stosw 832 call cirrus_extbios_85h ;; vram in 64k 833 mov ah, #0x00 834 stosw 835 836 push cs 837 pop ds 838 lea di, 0x40[bp] 839 mov si, #_cirrus_vesa_modelist 840 cv00_2: 841 lodsw 842 stosw 843 add si, #2 844 cmp ax, #0xffff 845 jnz cv00_2 846 847 mov ax, #0x004F 848 mov di, bp 849 pop si 850 pop ds 851 ret 852 853 cirrus_vesa_01h: 854 mov ax, cx 855 and ax, #0x3fff 856 call cirrus_vesamode_to_mode 857 cmp ax, #0xffff 858 jnz cirrus_vesa_01h_1 859 jmp cirrus_vesa_unimplemented 860 cirrus_vesa_01h_1: 861 push ds 862 push si 863 push cx 864 push dx 865 push bx 866 mov bp, di 867 cld 868 push cs 869 pop ds 870 call cirrus_get_modeentry_nomask 871 872 push di 873 xor ax, ax 874 mov cx, #0x80 875 rep 876 stosw ;; clear buffer 877 pop di 878 879 mov ax, #0x003b ;; mode 880 stosw 881 mov ax, #0x0007 ;; attr 882 stosw 883 mov ax, #0x0010 ;; granularity =16K 884 stosw 885 mov ax, #0x0040 ;; size =64K 886 stosw 887 mov ax, #0xA000 ;; segment A 888 stosw 889 xor ax, ax ;; no segment B 890 stosw 891 mov ax, #cirrus_vesa_05h_farentry 892 stosw 893 mov ax, cs 894 stosw 895 call cirrus_get_line_offset_entry 896 stosw ;; bytes per scan line 897 mov ax, [si+2] ;; width 898 stosw 899 mov ax, [si+4] ;; height 900 stosw 901 mov ax, #0x08 902 stosb 903 mov ax, #0x10 904 stosb 905 mov al, #1 ;; count of planes 906 stosb 907 mov al, [si+6] ;; bpp 908 stosb 909 mov al, #0x1 ;; XXX number of banks 910 stosb 911 mov al, [si+17] 912 stosb ;; memory model 913 mov al, #0x0 ;; XXX size of bank in K 914 stosb 915 call cirrus_get_line_offset_entry 916 mov bx, [si+4] 917 mul bx ;; dx:ax=vramdisp 918 or ax, ax 919 jz cirrus_vesa_01h_3 920 inc dx 921 cirrus_vesa_01h_3: 922 call cirrus_extbios_85h ;; al=vram in 64k 923 mov ah, #0x00 924 mov cx, dx 925 xor dx, dx 926 div cx 927 dec ax 928 stosb ;; number of image pages = vramtotal/vramdisp-1 929 mov al, #0x00 930 stosb 931 932 ;; v1.2+ stuffs 933 push si 934 add si, #18 935 movsw 936 movsw 937 movsw 938 movsw 939 pop si 940 941 mov ah, [si+16] 942 mov al, #0x0 943 sub ah, #9 944 rcl al, #1 ; bit 0=palette flag 945 stosb ;; direct screen mode info 946 947 ;; v2.0+ stuffs 948 ;; 32-bit LFB address 949 xor ax, ax 950 stosw 951 call cirrus_get_lfb_addr 952 stosw 953 or ax, ax 954 jz cirrus_vesa_01h_4 955 push di 956 mov di, bp 957 db 0x26 ;; es: 958 mov ax, [di] 959 or ax, #0x0080 ;; mode bit 7:LFB 960 stosw 961 pop di 962 cirrus_vesa_01h_4: 963 964 xor ax, ax 965 stosw ; reserved 966 stosw ; reserved 967 stosw ; reserved 968 969 mov ax, #0x004F 970 mov di, bp 971 pop bx 972 pop dx 973 pop cx 974 pop si 975 pop ds 976 977 test cx, #0x4000 ;; LFB flag 978 jz cirrus_vesa_01h_5 979 push cx 980 db 0x26 ;; es: 981 mov cx, [di] 982 cmp cx, #0x0080 ;; is LFB supported? 983 jnz cirrus_vesa_01h_6 984 mov ax, #0x014F ;; error - no LFB 985 cirrus_vesa_01h_6: 986 pop cx 987 cirrus_vesa_01h_5: 988 ret 989 990 cirrus_vesa_02h: 991 ;; XXX support CRTC registers 992 test bx, #0x3e00 993 jnz cirrus_vesa_02h_2 ;; unknown flags 994 mov ax, bx 995 and ax, #0x1ff ;; bit 8-0 mode 996 cmp ax, #0x100 ;; legacy VGA mode 997 jb cirrus_vesa_02h_legacy 998 call cirrus_vesamode_to_mode 999 cmp ax, #0xffff 1000 jnz cirrus_vesa_02h_1 1001 cirrus_vesa_02h_2: 1002 jmp cirrus_vesa_unimplemented 1003 cirrus_vesa_02h_legacy: 1004 #ifdef CIRRUS_VESA3_PMINFO 1005 db 0x2e ;; cs: 1006 cmp byte ptr [cirrus_vesa_is_protected_mode], #0 1007 jnz cirrus_vesa_02h_2 1008 #endif // CIRRUS_VESA3_PMINFO 1009 int #0x10 1010 mov ax, #0x004F 1011 ret 1012 cirrus_vesa_02h_1: 1013 push si 1014 push ax 1015 call cirrus_get_modeentry_nomask 1016 call cirrus_switch_mode 1017 test bx, #0x4000 ;; LFB 1018 jnz cirrus_vesa_02h_3 1019 call cirrus_enable_16k_granularity 1020 cirrus_vesa_02h_3: 1021 test bx, #0x8000 ;; no clear 1022 jnz cirrus_vesa_02h_4 1023 push ax 1024 xor ax,ax 1025 call cirrus_clear_vram 1026 pop ax 1027 cirrus_vesa_02h_4: 1028 pop ax 1029 push ds 1030 #ifdef CIRRUS_VESA3_PMINFO 1031 db 0x2e ;; cs: 1032 mov si, [cirrus_vesa_sel0000_data] 1033 #else 1034 xor si, si 1035 #endif 1036 mov ds, si 1037 mov [PM_BIOSMEM_CURRENT_MODE], al 1038 mov [PM_BIOSMEM_VBE_MODE], bx 1039 pop ds 1040 pop si 1041 mov ax, #0x004F 1042 ret 1043 1044 cirrus_vesa_03h: 1045 push ds 1046 #ifdef CIRRUS_VESA3_PMINFO 1047 db 0x2e ;; cs: 1048 mov ax, [cirrus_vesa_sel0000_data] 1049 #else 1050 xor ax, ax 1051 #endif 1052 mov ds, ax 1053 mov bx, # PM_BIOSMEM_VBE_MODE 1054 mov ax, [bx] 1055 mov bx, ax 1056 test bx, bx 1057 jnz cirrus_vesa_03h_1 1058 mov bx, # PM_BIOSMEM_CURRENT_MODE 1059 mov al, [bx] 1060 mov bl, al 1061 xor bh, bh 1062 cirrus_vesa_03h_1: 1063 mov ax, #0x004f 1064 pop ds 1065 ret 1066 1067 cirrus_vesa_05h_farentry: 1068 call cirrus_vesa_05h 1069 retf 1070 1071 cirrus_vesa_05h: 1072 cmp bl, #0x01 1073 ja cirrus_vesa_05h_1 1074 cmp bh, #0x00 1075 jz cirrus_vesa_05h_setmempage 1076 cmp bh, #0x01 1077 jz cirrus_vesa_05h_getmempage 1078 cirrus_vesa_05h_1: 1079 jmp cirrus_vesa_unimplemented 1080 cirrus_vesa_05h_setmempage: 1081 or dh, dh ; address must be < 0x100 1082 jnz cirrus_vesa_05h_1 1083 push dx 1084 mov al, bl ;; bl=bank number 1085 add al, #0x09 1086 mov ah, dl ;; dx=window address in granularity 1087 mov dx, #0x3ce 1088 out dx, ax 1089 pop dx 1090 mov ax, #0x004F 1091 ret 1092 cirrus_vesa_05h_getmempage: 1093 mov al, bl ;; bl=bank number 1094 add al, #0x09 1095 mov dx, #0x3ce 1096 out dx, al 1097 inc dx 1098 in al, dx 1099 xor dx, dx 1100 mov dl, al ;; dx=window address in granularity 1101 mov ax, #0x004F 1102 ret 1103 1104 cirrus_vesa_06h: 1105 mov ax, cx 1106 cmp bl, #0x01 1107 je cirrus_vesa_06h_3 1108 cmp bl, #0x02 1109 je cirrus_vesa_06h_2 1110 jb cirrus_vesa_06h_1 1111 mov ax, #0x0100 1112 ret 1113 cirrus_vesa_06h_1: 1114 call cirrus_get_bpp_bytes 1115 mov bl, al 1116 xor bh, bh 1117 mov ax, cx 1118 mul bx 1119 cirrus_vesa_06h_2: 1120 call cirrus_set_line_offset 1121 cirrus_vesa_06h_3: 1122 call cirrus_get_bpp_bytes 1123 mov bl, al 1124 xor bh, bh 1125 xor dx, dx 1126 call cirrus_get_line_offset 1127 push ax 1128 div bx 1129 mov cx, ax 1130 pop bx 1131 call cirrus_extbios_85h ;; al=vram in 64k 1132 xor dx, dx 1133 mov dl, al 1134 xor ax, ax 1135 div bx 1136 mov dx, ax 1137 mov ax, #0x004f 1138 ret 1139 1140 cirrus_vesa_07h: 1141 cmp bl, #0x80 1142 je cirrus_vesa_07h_1 1143 cmp bl, #0x01 1144 je cirrus_vesa_07h_2 1145 jb cirrus_vesa_07h_1 1146 mov ax, #0x0100 1147 ret 1148 cirrus_vesa_07h_1: 1149 push dx 1150 call cirrus_get_bpp_bytes 1151 mov bl, al 1152 xor bh, bh 1153 mov ax, cx 1154 mul bx 1155 pop bx 1156 push ax 1157 call cirrus_get_line_offset 1158 mul bx 1159 pop bx 1160 add ax, bx 1161 jnc cirrus_vesa_07h_3 1162 inc dx 1163 cirrus_vesa_07h_3: 1164 push dx 1165 and dx, #0x0003 1166 mov bx, #0x04 1167 div bx 1168 pop dx 1169 shr dx, #2 1170 call cirrus_set_start_addr 1171 mov ax, #0x004f 1172 ret 1173 cirrus_vesa_07h_2: 1174 call cirrus_get_start_addr 1175 shl dx, #2 1176 push dx 1177 mov bx, #0x04 1178 mul bx 1179 pop bx 1180 or dx, bx 1181 push ax 1182 call cirrus_get_line_offset 1183 mov bx, ax 1184 pop ax 1185 div bx 1186 push ax 1187 push dx 1188 call cirrus_get_bpp_bytes 1189 mov bl, al 1190 xor bh, bh 1191 pop ax 1192 xor dx, dx 1193 div bx 1194 mov cx, ax 1195 pop dx 1196 mov ax, #0x004f 1197 ret 1198 1199 cirrus_vesa_10h: ;; Power management functions 1200 ;; Set up DS to read stored power info from RAM 1201 push ds 1202 #ifdef CIRRUS_VESA3_PMINFO 1203 db 0x2e ;; cs: 1204 mov ax, [cirrus_vesa_sel0000_data] 1205 #else 1206 xor ax, ax 1207 #endif 1208 mov ds, ax 1209 ;; Now choose the right function 1210 cmp bl, #0x00 1211 ja cirrus_vesa_10h_01 1212 ;; 1213 ;; Function 00h: Get capabilities 1214 ;; 1215 mov bx, #0x0720 ;; 07: standby/suspend/off, 20: VBE/PM 2.0 1216 mov ax, #0x004f 1217 jmp cirrus_vesa_10h_done 1218 cirrus_vesa_10h_01: 1219 cmp bl, #0x01 1220 ja cirrus_vesa_10h_02 1221 ;; 1222 ;; Function 01h: Set power state 1223 ;; 1224 mov ax, bx 1225 mov bx, # PM_BIOSMEM_VBE_POWER 1226 mov [bx], ah 1227 mov ax, #0x004f 1228 jmp cirrus_vesa_10h_done 1229 cirrus_vesa_10h_02: 1230 cmp bl, #0x02 1231 ja cirrus_vesa_10h_unimplemented 1232 ;; 1233 ;; Function 02h: Get power state 1234 ;; 1235 mov bx, # PM_BIOSMEM_VBE_POWER 1236 mov bh, [bx] 1237 mov ax, #0x004f 1238 jmp cirrus_vesa_10h_done 1239 cirrus_vesa_10h_unimplemented: 1240 mov ax, #0x014F ;; not implemented 1241 cirrus_vesa_10h_done: 1242 pop ds 1243 ret 1244 1245 cirrus_vesa_unimplemented: 1246 mov ax, #0x014F ;; not implemented 1247 ret 1248 1249 1250 ;; in ax:vesamode, out ax:cirrusmode 1251 cirrus_vesamode_to_mode: 1252 push ds 1253 push cx 1254 push si 1255 push cs 1256 pop ds 1257 mov cx, #0xffff 1258 mov si, #_cirrus_vesa_modelist 1259 cvtm_1: 1260 cmp [si],ax 1261 jz cvtm_2 1262 cmp [si],cx 1263 jz cvtm_2 1264 add si, #4 1265 jmp cvtm_1 1266 cvtm_2: 1267 mov ax,[si+2] 1268 pop si 1269 pop cx 1270 pop ds 1271 ret 1272 1273 ; cirrus_get_crtc 1274 ;; NOTE - may be called in protected mode 1275 cirrus_get_crtc: 1276 push ds 1277 push ax 1278 mov dx, #0x3cc 1279 in al, dx 1280 and al, #0x01 1281 shl al, #5 1282 mov dx, #0x3b4 1283 add dl, al 1284 pop ax 1285 pop ds 1286 ret 1287 1288 ;; in - al:mode, out - cflag:result, si:table, ax:destroyed 1289 cirrus_get_modeentry: 1290 and al, #0x7f 1291 cirrus_get_modeentry_nomask: 1292 mov si, #_cirrus_modes 1293 cgm_1: 1294 db 0x2e ;; cs: 1295 mov ah, [si] 1296 cmp al, ah 1297 jz cgm_2 1298 cmp ah, #0xff 1299 jz cgm_4 1300 add si, # CIRRUS_MODE_SIZE 1301 jmp cgm_1 1302 cgm_4: 1303 xor si, si 1304 stc ;; video mode is not supported 1305 jmp cgm_3 1306 cgm_2: 1307 clc ;; video mode is supported 1308 cgm_3: 1309 ret 1310 1311 ; get LFB address 1312 ; out - ax:LFB address (high 16 bit) 1313 ;; NOTE - may be called in protected mode 1314 cirrus_get_lfb_addr: 1315 push cx 1316 push dx 1317 push eax 1318 xor cx, cx 1319 mov dl, #0x00 1320 call cirrus_pci_read 1321 cmp ax, #0xffff 1322 jz cirrus_get_lfb_addr_5 1323 cirrus_get_lfb_addr_3: 1324 mov dl, #0x00 1325 call cirrus_pci_read 1326 cmp ax, #0x1013 ;; cirrus 1327 jz cirrus_get_lfb_addr_4 1328 add cx, #0x8 1329 cmp cx, #0x200 ;; search bus #0 and #1 1330 jb cirrus_get_lfb_addr_3 1331 cirrus_get_lfb_addr_5: 1332 xor dx, dx ;; no LFB 1333 jmp cirrus_get_lfb_addr_6 1334 cirrus_get_lfb_addr_4: 1335 mov dl, #0x10 ;; I/O space #0 1336 call cirrus_pci_read 1337 test ax, #0xfff1 1338 jnz cirrus_get_lfb_addr_5 1339 shr eax, #16 1340 mov dx, ax ;; LFB address 1341 cirrus_get_lfb_addr_6: 1342 pop eax 1343 mov ax, dx 1344 pop dx 1345 pop cx 1346 ret 1347 1348 cirrus_pci_read: 1349 mov eax, #0x00800000 1350 mov ax, cx 1351 shl eax, #8 1352 mov al, dl 1353 mov dx, #0xcf8 1354 out dx, eax 1355 add dl, #4 1356 in eax, dx 1357 ret 1358 1359 ;; out - al:bytes per pixel 1360 cirrus_get_bpp_bytes: 1361 push dx 1362 mov dx, #0x03c4 1363 mov al, #0x07 1364 out dx, al 1365 inc dx 1366 in al, dx 1367 and al, #0x0e 1368 cmp al, #0x06 1369 jne cirrus_get_bpp_bytes_1 1370 and al, #0x02 1371 cirrus_get_bpp_bytes_1: 1372 shr al, #1 1373 cmp al, #0x04 1374 je cirrus_get_bpp_bytes_2 1375 inc al 1376 cirrus_get_bpp_bytes_2: 1377 pop dx 1378 ret 1379 1380 ;; in - ax: new line offset 1381 cirrus_set_line_offset: 1382 shr ax, #3 1383 push ax 1384 call cirrus_get_crtc 1385 mov al, #0x13 1386 out dx, al 1387 inc dx 1388 pop ax 1389 out dx, al 1390 dec dx 1391 mov al, #0x1b 1392 out dx, al 1393 inc dx 1394 shl ah, #4 1395 in al, dx 1396 and al, #ef 1397 or al, ah 1398 out dx, al 1399 ret 1400 1401 ;; out - ax: active line offset 1402 cirrus_get_line_offset: 1403 push dx 1404 push bx 1405 call cirrus_get_crtc 1406 mov al, #0x13 1407 out dx, al 1408 inc dx 1409 in al, dx 1410 mov bl, al 1411 dec dx 1412 mov al, #0x1b 1413 out dx, al 1414 inc dx 1415 in al, dx 1416 mov ah, al 1417 shr ah, #4 1418 and ah, #0x01 1419 mov al, bl 1420 shl ax, #3 1421 pop bx 1422 pop dx 1423 ret 1424 1425 ;; in - si: table 1426 ;; out - ax: line offset for mode 1427 cirrus_get_line_offset_entry: 1428 push bx 1429 mov bx, [si+14] ;; crtc table 1430 push bx 1431 offset_loop1: 1432 mov ax, [bx] 1433 cmp al, #0x13 1434 je offset_found1 1435 inc bx 1436 inc bx 1437 jnz offset_loop1 1438 offset_found1: 1439 xor al, al 1440 shr ax, #5 1441 pop bx 1442 push ax 1443 offset_loop2: 1444 mov ax, [bx] 1445 cmp al, #0x1b 1446 je offset_found2 1447 inc bx 1448 inc bx 1449 jnz offset_loop2 1450 offset_found2: 1451 pop bx 1452 and ax, #0x1000 1453 shr ax, #1 1454 or ax, bx 1455 pop bx 1456 ret 1457 1458 ;; in - new address in DX:AX 1459 cirrus_set_start_addr: 1460 push bx 1461 push dx 1462 push ax 1463 call cirrus_get_crtc 1464 mov al, #0x0d 1465 out dx, al 1466 inc dx 1467 pop ax 1468 out dx, al 1469 dec dx 1470 mov al, #0x0c 1471 out dx, al 1472 inc dx 1473 mov al, ah 1474 out dx, al 1475 dec dx 1476 mov al, #0x1d 1477 out dx, al 1478 inc dx 1479 in al, dx 1480 and al, #0x7f 1481 pop bx 1482 mov ah, bl 1483 shl bl, #4 1484 and bl, #0x80 1485 or al, bl 1486 out dx, al 1487 dec dx 1488 mov bl, ah 1489 and ah, #0x01 1490 shl bl, #1 1491 and bl, #0x0c 1492 or ah, bl 1493 mov al, #0x1b 1494 out dx, al 1495 inc dx 1496 in al, dx 1497 and al, #0xf2 1498 or al, ah 1499 out dx, al 1500 pop bx 1501 ret 1502 1503 ;; out - current address in DX:AX 1504 cirrus_get_start_addr: 1505 push bx 1506 call cirrus_get_crtc 1507 mov al, #0x0c 1508 out dx, al 1509 inc dx 1510 in al, dx 1511 mov ah, al 1512 dec dx 1513 mov al, #0x0d 1514 out dx, al 1515 inc dx 1516 in al, dx 1517 push ax 1518 dec dx 1519 mov al, #0x1b 1520 out dx, al 1521 inc dx 1522 in al, dx 1523 dec dx 1524 mov bl, al 1525 and al, #0x01 1526 and bl, #0x0c 1527 shr bl, #1 1528 or bl, al 1529 mov al, #0x1d 1530 out dx, al 1531 inc dx 1532 in al, dx 1533 and al, #0x80 1534 shr al, #4 1535 or bl, al 1536 mov dl, bl 1537 xor dh, dh 1538 pop ax 1539 pop bx 1540 ret 1541 1542 cirrus_clear_vram: 1543 pusha 1544 push es 1545 mov si, ax 1546 1547 call cirrus_enable_16k_granularity 1548 call cirrus_extbios_85h 1549 shl al, #2 1550 mov bl, al 1551 xor ah,ah 1552 cirrus_clear_vram_1: 1553 mov al, #0x09 1554 mov dx, #0x3ce 1555 out dx, ax 1556 push ax 1557 1558 ;; Windows Vista appears to be emulating this sequence as part of changing 1559 ;; screen resolution, but it generates 4096 writes per iteration. 1560 ;; Instead, use a magic register sequence to write the whole bank. 1561 ;;mov cx, #0xa000 1562 ;;mov es, cx 1563 ;;xor di, di 1564 ;;mov ax, si 1565 ;;mov cx, #8192 1566 ;;cld 1567 ;;rep 1568 ;; stosw 1569 mov ax, si 1570 shl ax, #8 1571 mov al, #0xfe 1572 out dx, ax ;; Low byte of value to be written to the bank 1573 mov ax, si 1574 mov al, #0xff 1575 out dx, ax ;; High byte and trigger the write 1576 1577 pop ax 1578 inc ah 1579 cmp ah, bl 1580 jne cirrus_clear_vram_1 1581 1582 xor ah,ah 1583 mov dx, #0x3ce 1584 out dx, ax 1585 1586 pop es 1587 popa 1588 ret 1589 1590 cirrus_extbios_handlers: 1591 ;; 80h 1592 dw cirrus_extbios_80h 1593 dw cirrus_extbios_81h 1594 dw cirrus_extbios_82h 1595 dw cirrus_extbios_unimplemented 1596 ;; 84h 1597 dw cirrus_extbios_unimplemented 1598 dw cirrus_extbios_85h 1599 dw cirrus_extbios_unimplemented 1600 dw cirrus_extbios_unimplemented 1601 ;; 88h 1602 dw cirrus_extbios_unimplemented 1603 dw cirrus_extbios_unimplemented 1604 dw cirrus_extbios_unimplemented 1605 dw cirrus_extbios_unimplemented 1606 ;; 8Ch 1607 dw cirrus_extbios_unimplemented 1608 dw cirrus_extbios_unimplemented 1609 dw cirrus_extbios_unimplemented 1610 dw cirrus_extbios_unimplemented 1611 ;; 90h 1612 dw cirrus_extbios_unimplemented 1613 dw cirrus_extbios_unimplemented 1614 dw cirrus_extbios_unimplemented 1615 dw cirrus_extbios_unimplemented 1616 ;; 94h 1617 dw cirrus_extbios_unimplemented 1618 dw cirrus_extbios_unimplemented 1619 dw cirrus_extbios_unimplemented 1620 dw cirrus_extbios_unimplemented 1621 ;; 98h 1622 dw cirrus_extbios_unimplemented 1623 dw cirrus_extbios_unimplemented 1624 dw cirrus_extbios_9Ah 1625 dw cirrus_extbios_unimplemented 1626 ;; 9Ch 1627 dw cirrus_extbios_unimplemented 1628 dw cirrus_extbios_unimplemented 1629 dw cirrus_extbios_unimplemented 1630 dw cirrus_extbios_unimplemented 1631 ;; A0h 1632 dw cirrus_extbios_A0h 1633 dw cirrus_extbios_A1h 1634 dw cirrus_extbios_A2h 1635 dw cirrus_extbios_unimplemented 1636 ;; A4h 1637 dw cirrus_extbios_unimplemented 1638 dw cirrus_extbios_unimplemented 1639 dw cirrus_extbios_unimplemented 1640 dw cirrus_extbios_unimplemented 1641 ;; A8h 1642 dw cirrus_extbios_unimplemented 1643 dw cirrus_extbios_unimplemented 1644 dw cirrus_extbios_unimplemented 1645 dw cirrus_extbios_unimplemented 1646 ;; ACh 1647 dw cirrus_extbios_unimplemented 1648 dw cirrus_extbios_unimplemented 1649 dw cirrus_extbios_AEh 1650 dw cirrus_extbios_unimplemented 1651 1652 cirrus_vesa_handlers: 1653 ;; 00h 1654 dw cirrus_vesa_00h 1655 dw cirrus_vesa_01h 1656 dw cirrus_vesa_02h 1657 dw cirrus_vesa_03h 1658 ;; 04h 1659 dw cirrus_vesa_unimplemented 1660 dw cirrus_vesa_05h 1661 dw cirrus_vesa_06h 1662 dw cirrus_vesa_07h 1663 ;; 08h 1664 dw cirrus_vesa_unimplemented 1665 dw cirrus_vesa_unimplemented 1666 dw cirrus_vesa_unimplemented 1667 dw cirrus_vesa_unimplemented 1668 ;; 0Ch 1669 dw cirrus_vesa_unimplemented 1670 dw cirrus_vesa_unimplemented 1671 dw cirrus_vesa_unimplemented 1672 dw cirrus_vesa_unimplemented 1673 ;; 10h 1674 dw cirrus_vesa_10h 1675 1676 1677 1678 ASM_END 1679 1680 #ifdef CIRRUS_VESA3_PMINFO 1681 ASM_START 1682 cirrus_vesa_pminfo: 1683 /* + 0 */ 1684 .byte 0x50,0x4d,0x49,0x44 ;; signature[4] 1685 /* + 4 */ 1686 dw cirrus_vesa_pmbios_entry ;; entry_bios 1687 dw cirrus_vesa_pmbios_init ;; entry_init 1688 /* + 8 */ 1689 cirrus_vesa_sel0000_data: 1690 dw 0x0000 ;; sel_00000 1691 cirrus_vesa_selA000_data: 1692 dw 0xA000 ;; sel_A0000 1693 /* +12 */ 1694 cirrus_vesa_selB000_data: 1695 dw 0xB000 ;; sel_B0000 1696 cirrus_vesa_selB800_data: 1697 dw 0xB800 ;; sel_B8000 1698 /* +16 */ 1699 cirrus_vesa_selC000_data: 1700 dw 0xC000 ;; sel_C0000 1701 cirrus_vesa_is_protected_mode: 1702 ;; protected mode flag and checksum 1703 dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \ 1704 + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01 1705 ASM_END 1706 #endif // CIRRUS_VESA3_PMINFO 1707 1708 1709 #ifdef CIRRUS_DEBUG 1710 static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) 1711 Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; 1712 { 1713 if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05)) 1714 printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); 1715 } 1716 #endif 1717