Annotation of qemu/roms/vgabios/vbe.c, revision 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.