Annotation of qemu/roms/vgabios/vbe.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.