www.pudn.com > zsnes117b-src.zip > vesa12.asm


;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) 
; 
;This program is free software; you can redistribute it and/or 
;modify it under the terms of the GNU General Public License 
;as published by the Free Software Foundation; either 
;version 2 of the License, or (at your option) any later 
;version. 
; 
;This program is distributed in the hope that it will be useful, 
;but WITHOUT ANY WARRANTY; without even the implied warranty of 
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
;GNU General Public License for more details. 
; 
;You should have received a copy of the GNU General Public License 
;along with this program; if not, write to the Free Software 
;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 
%include "macros.mac" 
 
EXTSYM vesa2_usbit,vesa2_clbit,vesa2_clbitng,vesa2_clbitng2,vesa2_clbitng3 
EXTSYM vesa2_x,vesa2_y,vesa2selec,vesa2_bits,vesa2_rpos,vesa2_gpos,vesa2_bpos 
EXTSYM vesa2_rposng,vesa2_gposng,vesa2_bposng,vesa2_rtrcl,vesa2_rtrcla,vesa2_rfull 
EXTSYM vesa2_gtrcl,vesa2_gtrcla,vesa2_gfull,vesa2_btrcl,vesa2_btrcla,vesa2_bfull 
EXTSYM vesa2red10,dcolortab,videotroub,Change_Dir 
EXTSYM genfulladdtab,genfulladdtabng,DosExit 
EXTSYM InitDrive,gotoroot,InitDir,fulladdtab 
;        EXTSYM printnum,DosExit 
EXTSYM LFBpointer,noblocks,bytesperscanline,vesamode,VESAmodelist 
 
 
 
 
 
 
; add 0214h video mode 
 
NEWSYM granularity, dw 0 
NEWSYM granadd, dd 0 
 
NEWSYM VESA12EXITTODOS 
        mov ax,0003h 
        int 10h 
        push edx 
        mov edx,.exitfromvesa12 
        mov ah,9 
        int 21h 
        pop edx 
        mov ah,9 
        int 21h 
        mov edx,.return 
        mov ah,9 
        int 21h 
 
        mov dl,[InitDrive] 
        mov ebx,InitDir 
        call Change_Dir 
 
        mov byte[videotroub],1 
        jmp DosExit 
 
.exitfromvesa12 db 'Unable to Initialize VESA1.2 $' 
.return db 10,13,'$' 
 
;******************************************************* 
;	Set up Vesa 2 
;******************************************************* 
 
NEWSYM InitVesa12 
	   ;-------------------------------------------------; 
	    ; First - allocate some bytes in DOS memory for ; 
	    ; communication with VBE			    ; 
	   ;-------------------------------------------------; 
 
	mov eax,0100h 
	mov ebx,512/16			; 512 bytes 
	int 31h				; Function 31h,100h - Allocate 
					; DOS memory (512 bytes) 
	jnc .gotmem 
	    mov edx,.nomemmessage 
            jmp VESA12EXITTODOS 
	    .nomemmessage 
            db ': Unable to locate DOS memory.$' 
 
	.gotmem 
	mov fs,dx			; FS now points to the DOS 
					; buffer 
 
 
	   ;--------------------------------------------------; 
	    ; Now, get information about the video card into ; 
	    ; a data structure				     ; 
	   ;--------------------------------------------------; 
 
	mov edi,RMREGS 
        mov dword[fs:0],'VBE1'          ; Request VBE 2.0 info 
	mov dword[RMREGS.eax],4f00h 
	mov word[RMREGS.es],ax		; Real mode segment of DOS  
					; buffer 
	mov dword[RMREGS.edi],0 
 
	push es 
        push ds 
	pop es 
	mov eax,300h 
	mov ebx,10h 
	xor ecx,ecx 
	int 31h				; Simulate real mode interrupt 
	pop es 
 
	jnc .int1ok 
	    mov edx,.noint1message 
            jmp VESA12EXITTODOS 
	    .noint1message 
            db ': Simulated real mode interrupt failed.$' 
 
	.int1ok			; Real mode int successful!!! 
	mov eax,[RMREGS.eax] 
	cmp al,4fh		; Check vbe interrupt went OK 
	jz .vbedetected 
	    mov edx,.novbemessage 
            jmp VESA12EXITTODOS 
	    .novbemessage 
            db ': VBE not detected!!$' 
 
	.vbedetected 
	cmp dword[fs:0000],'VESA' 
	jz .vesadetected	; Check for presence of vesa 
	    mov edx,.novesamessage 
            jmp VESA12EXITTODOS 
	    .novesamessage 
            db ': VESA not detected!$' 
 
	.vesadetected 
        cmp word[fs:0004],102h 
        jae .vesa12detected      ; Check we've got VESA 1.2 or greater 
	    mov edx,.novesa2message 
            jmp VESA12EXITTODOS 
	    .novesa2message 
            db ': VESA 1.2 or greater required!$' 
 
 
		;-----------------------------------------------------; 
		 ; OK - vesa 2.0 or greater has been detected. Copy  ; 
		 ; mode information into VESAmodelist		     ; 
		;-----------------------------------------------------; 
 
        .vesa12detected 
	mov ax,[fs:12h]			; Get no. of 64k blocks 
	mov [noblocks],ax 
	mov ax, 2 
	mov bx,[fs:10h] 
	int 31h 
 
	jnc .wegottheselector 
	    mov edx, .oopsnoselector 
            jmp VESA12EXITTODOS 
	    .oopsnoselector 
                db ': Failed to allocate vesa display selector!$' 
 
	.wegottheselector 
 
	mov gs,ax 
	xor eax,eax 
	mov ebp,VESAmodelist 
	mov ecx,512 
	mov ax,[fs:0eh] 
 
	.loopcopymodes 
	    mov bx,[gs:eax] 
	    mov [ebp],bx 
	    cmp bx,0ffffh 
	    jz .copiedmodes 
	    add ebp,2 
	    add eax,2 
	    dec ecx 
	    jz .outofmodelistspace 
	    jmp .loopcopymodes 
 
		.outofmodelistspace 
		mov edx,.outofmodelistspacemessage 
                jmp VESA12EXITTODOS 
		.outofmodelistspacemessage 
                db ': Out of VESA mode list space!$' 
 
		   ;----------------------------------------------; 
		    ; OK - Scan the mode list to find a matching ; 
		    ; mode for vesa2_x, vesa2_y and vesa2_depth	 ; 
		   ;----------------------------------------------; 
 
    .copiedmodes 
 
	mov ebp,VESAmodelist 
	xor ecx,ecx 
 
    .loopcheckmodes 
	mov cx, [ebp] 
	cmp cx, 0ffffh 
	jnz .notendoflist 
 
	    mov edx,.endoflist 
            jmp VESA12EXITTODOS 
 
            .endoflist db ': VESA 1.2 mode does not work on your video card/driver.$' 
            .whichwin db 0 
 
    .notendoflist 
 
        mov edi, RMREGS 
        mov dword[RMREGS.eax],4f01h 
        mov dword[RMREGS.ebx],0 
        mov dword[RMREGS.ecx],ecx 
        mov dword[RMREGS.edi],0 
 
	push es 
        push ds 
	pop es 
	mov eax,300h 
	mov ebx,10h 
	xor ecx,ecx 
	int 31h				; Simulate real mode interrupt 
	pop es 
	jnc .modecheckok 
	    mov edx,.modecheckfail 
            jmp VESA12EXITTODOS 
	    .modecheckfail 
            db ': Real mode interrupt failure while checking vesa mode$' 
 
	.modecheckok 
	add ebp,2 
 
        test word[fs:0000h],1b 
            jz near .loopcheckmodes     ; If mode is not available 
 
; 
;        xor eax,eax 
;        mov ax,[fs:12h] 
;        call printnum 
;        mov ah,02h 
;        mov dl,'x' 
;        int 21h 
;        mov ax,[fs:14h] 
;        call printnum 
;        mov ah,02h 
;        mov dl,'x' 
;        int 21h 
;        xor ah,ah 
;        mov al,[fs:19h] 
;        call printnum 
;        mov ah,02h 
;        mov dl,13 
;        int 21h 
;        mov dl,10 
;        int 21h 
 
        mov eax,[vesa2_x] 
	cmp [fs:12h],ax			; Check that the height matches 
	    jnz near .loopcheckmodes 
        mov eax,[vesa2_y] 
	cmp [fs:14h],ax			; Check that the width matches 
	    jnz near .loopcheckmodes 
	mov al,[vesa2_bits] 
	cmp [fs:19h],al			; Check bits/pixel for match 
	    jnz near .loopcheckmodes 
 
;        mov ah,07h 
;        int 21h 
 
;        D0 = Window supported 
;                0 = Window is not supported 
;                1 = Window is supported 
;        D1 = Window readable 
;                0 = Window is not readable 
;                1 = Window is readable 
;        D2 = Window writeable 
;                0 = Window is not writeable 
;                1 = Window is writeable 
;        D3-D7 = Reserved 
 
        mov byte[.whichwin],0 
	mov al,[fs:2]			; Get window A attributes 
        and al,0100b 
        cmp al,0100b 
        je .foundwin    ; Mode supported 
        mov al,[fs:3]                   ; Get window B attributes 
        and al,0100b 
        cmp al,0100b 
        jne .foundwin    ; Mode not supported 
        mov byte[.whichwin],1 
.foundwin 
 
		; Success - a match has been found!! 
 
	sub ebp,2 
	mov ax,[ebp] 
        mov [vesamode],ax               ; Store vesa 1.2 mode number 
;        and eax,0FFFFh 
;        push eax 
;        mov ax,0003h 
;        int 10h 
;        pop eax 
;        call printnum 
;        jmp DosExit 
 
        mov ax,[fs:10h] 
        mov byte[vesa2red10],0 
        mov byte[vesa2_rposng],11 
        mov byte[vesa2_gposng],6 
        mov byte[vesa2_bposng],0 
        mov dword[vesa2_clbitng],1111011111011110b 
        mov dword[vesa2_clbitng2],11110111110111101111011111011110b 
        mov dword[vesa2_clbitng2+4],11110111110111101111011111011110b 
        mov dword[vesa2_clbitng3],0111101111101111b 
	mov [bytesperscanline],ax	; Store bytes per scan line 
        cmp byte[fs:20h],10 
        jne .nored10 
        mov byte[fs:20h],11 
        mov byte[vesa2red10],1 
        mov byte[vesa2_rposng],10 
        mov byte[vesa2_gposng],5 
        mov dword[vesa2_clbitng],0111101111011110b 
        mov dword[vesa2_clbitng2],01111011110111100111101111011110b 
        mov dword[vesa2_clbitng2+4],01111011110111100111101111011110b 
        mov dword[vesa2_clbitng3],0011110111101111b 
.nored10 
        ; fix up bit lengths 
        mov al,16 
        sub al,[fs:20h] 
        mov ah,[fs:22h] 
        sub ah,[fs:20h] 
        mov bl,[fs:24h] 
        sub bl,[fs:20h] 
        mov bh,al 
        cmp bh,ah 
        jb .scheck1 
        mov bh,ah 
      .scheck1 
        cmp bh,bl 
        jb .scheck2 
        mov bh,bl 
      .scheck2 
        mov byte[fs:19h],5 
 
        mov al,16 
        sub al,[fs:22h] 
        mov ah,[fs:20h] 
        sub ah,[fs:22h] 
        mov bl,[fs:24h] 
        sub bl,[fs:22h] 
        mov bh,al 
        cmp bh,ah 
        jb .scheck1b 
        mov bh,ah 
      .scheck1b 
        cmp bh,bl 
        jb .scheck2b 
        mov bh,bl 
      .scheck2b 
        mov [fs:21h],bh 
 
        mov al,16 
        sub al,[fs:24h] 
        mov ah,[fs:20h] 
        sub ah,[fs:24h] 
        mov bl,[fs:22h] 
        sub bl,[fs:24h] 
        mov bh,al 
        cmp bh,ah 
        jb .scheck1c 
        mov bh,ah 
      .scheck1c 
        cmp bh,bl 
        jb .scheck2c 
        mov bh,bl 
      .scheck2c 
        mov [fs:23h],bh 
 
        mov word[vesa2_clbit],0 
 
        cmp byte[fs:20h],10 
        jne .nottopbit 
        mov word[vesa2_usbit],8000h 
.nottopbit 
 
        ; Process Red Stuff 
        mov al,[fs:20h]         ; bit sizes = [fs:19h,21h,23h] 
        mov cl,al 
        mov bx,1 
        shl bx,cl 
        cmp byte[fs:19h],6 
        jne .no6bit 
        mov [vesa2_usbit],bx 
        inc al 
.no6bit 
        or [vesa2_clbit],bx 
        mov [vesa2_rpos],al 
        dec al 
        mov cl,al 
        mov bx,001Fh 
        cmp cl,0FFh 
        je .shrr 
        shl bx,cl 
        jmp .shlr 
.shrr 
        shr bx,1 
.shlr 
        mov word[vesa2_rfull],bx 
        add al,5 
        mov bx,1 
        mov cl,al 
        shl bx,cl 
        mov word[vesa2_rtrcl],bx 
        xor bx,0FFFFh 
        mov word[vesa2_rtrcla],bx 
 
        ; Process Green Stuff 
        mov al,[fs:22h] 
        mov cl,al 
        mov bx,1 
        shl bx,cl 
        cmp byte[fs:21h],6 
        jne .no6bitb 
        mov [vesa2_usbit],bx 
        inc al 
.no6bitb 
        or [vesa2_clbit],bx 
        mov [vesa2_gpos],al 
        dec al 
        mov cl,al 
        mov bx,001Fh 
        cmp cl,0FFh 
        je .shrg 
        shl bx,cl 
        jmp .shlg 
.shrg 
        shr bx,1 
.shlg 
        mov word[vesa2_gfull],bx 
        add al,5 
        mov bx,1 
        mov cl,al 
        shl bx,cl 
        mov word[vesa2_gtrcl],bx 
        xor bx,0FFFFh 
        mov word[vesa2_gtrcla],bx 
 
        ; Process Blue Stuff 
        mov al,[fs:24h] 
        mov cl,al 
        mov bx,1 
        shl bx,cl 
        cmp byte[fs:23h],6 
        jne .no6bitc 
        mov [vesa2_usbit],bx 
        inc al 
.no6bitc 
        or [vesa2_clbit],bx 
        mov [vesa2_bpos],al 
        dec al 
        mov cl,al 
        mov bx,001Fh 
        cmp cl,0FFh 
        je .shrb 
        shl bx,cl 
        jmp .shlb 
.shrb 
        shr bx,1 
.shlb 
        mov word[vesa2_bfull],bx 
        add al,5 
        mov bx,1 
        mov cl,al 
        shl bx,cl 
        mov word[vesa2_btrcl],bx 
        xor bx,0FFFFh 
        mov word[vesa2_btrcla],bx 
 
        xor word[vesa2_clbit],0FFFFh 
 
        mov ax,[fs:4] 
        mov [granularity],ax 
        xor edx,edx 
        mov ax,64 
        mov bx,[granularity] 
        div bx 
        mov [granadd],ax 
 
 
;vesa2_rtrcl     dw 0            ; red transparency clear     (bit+4) 
;vesa2_rtrcla    dw 0            ; red transparency (AND) clear (not(bit+4)) 
;vesa2_rfull     dw 0            ; red max (or (bit-1)*1Fh) 
 
        call genfulladdtab 
 
	xor eax,eax 
	xor ebx,ebx 
	xor ecx,ecx 
	xor edx,edx 
	mov ax,4f02h 
	mov bx,[vesamode] 
	int 10h				; Set the vesa mode 
	cmp ax,004fh 
	jz .modesetok 
            mov edx,.unableset 
            jmp VESA12EXITTODOS               ; Failure!!! 
        .unableset db 'Unable to initialize video mode.$' 
 
	.modesetok 
;******************************* EXTRA BIT **************************** 
 
        ret 
 
        ; Check logical scanline length 
        mov eax,4f06h 
        mov ebx,1 
        int 10h 
        cmp cx,[vesa2_x] 
        je .correctwidth 
 
	mov eax,4f06h			; VBE Set/Get logical scan line 
					; length 
	mov ebx,0			; Set scan line length in 
					; pixels 
        mov ecx, [vesa2_x]                ; Desired screen width 
	int 10h 
	cmp ax,04fh 
	jz .correctwidth 
            mov edx, .unablescan 
            jmp VESA12EXITTODOS          ; Failure!!! 
        .unablescan db 'Unable to set scan line length.$' 
 
	.correctwidth 
 
        ret 
 
 
RMREGS 
.edi	dd 0 
.esi	dd 0 
.ebp	dd 0 
.esp	dd 0 
.ebx	dd 0 
.edx	dd 0 
.ecx	dd 0 
.eax	dd 0 
.flags	dw 0 
.es	dw 0 
.ds	dw 0  
.fs	dw 0 
.gs	dw 0 
.ip	dw 0 
.cs	dw 0 
.sp	dw 0 
.ss	dw 0 
.spare	times 20 dd 0