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

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

unix.superglobalmegacorp.com

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