📄 vesa2.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 printnum
EXTSYM DosExit,ZSNESBase,Change_Dir,PrintStr,newengen
EXTSYM HalfTransB,HalfTransC
EXTSYM InitDrive,gotoroot,InitDir,fulladdtab
; EXTSYM printhex
; EXTSYM printhex
EXTSYM UnusedBit,HalfTrans,UnusedBitXor,ngrposng,nggposng,ngbposng
; EXTSYM printhex
EXTSYM Init_2xSaIMMX
NEWSYM Vesa2AsmStart
; add 0214h video mode
anticrash times 10 db 0
ALIGN32
NEWSYM vesa2_usbit, dd 0 ; Unused bit in proper bit location
NEWSYM vesa2_clbit, dd 0 ; clear all bit 0's if AND is used
NEWSYM vesa2_clbitng, dd 0 ; clear all bit 0's if AND is used
NEWSYM vesa2_clbitng2, dd 0,0 ; clear all bit 0's if AND is used
NEWSYM vesa2_clbitng3, dd 0 ; clear all bit 0's if AND is used
NEWSYM vesa2_x, dd 320 ; Desired screen width
NEWSYM vesa2_y, dd 240 ; Height
NEWSYM vesa2selec, dd 0 ; VESA2 Selector Location
NEWSYM vesa2_bits, dd 8 ; Bits per pixel
NEWSYM vesa2_rpos, dd 0 ; Red bit position
NEWSYM vesa2_gpos, dd 0 ; Green bit position
NEWSYM vesa2_bpos, dd 0 ; Blue bit position
NEWSYM vesa2_rposng, dd 0 ; Red bit position
NEWSYM vesa2_gposng, dd 0 ; Green bit position
NEWSYM vesa2_bposng, dd 0 ; Blue bit position
NEWSYM vesa2_rtrcl, dd 0 ; red transparency clear (bit+4)
NEWSYM vesa2_rtrcla, dd 0 ; red transparency (AND) clear (not(bit+4))
NEWSYM vesa2_rfull, dd 0 ; red max (or bit*1Fh)
NEWSYM vesa2_gtrcl, dd 0 ; red transparency clear (bit+4)
NEWSYM vesa2_gtrcla, dd 0 ; red transparency (AND) clear (not(bit+4))
NEWSYM vesa2_gfull, dd 0 ; red max (or bit*1Fh)
NEWSYM vesa2_btrcl, dd 0 ; red transparency clear (bit+4)
NEWSYM vesa2_btrcla, dd 0 ; red transparency (AND) clear (not(bit+4))
NEWSYM vesa2_bfull, dd 0 ; red max (or bit*1Fh)
NEWSYM vesa2red10, dd 0 ; red position at bit 10
NEWSYM videotroub, dd 0 ; red position at bit 10
NEWSYM vesa3en, dd 0
NEWSYM VESAAddr, dd 0
NEWSYM ExitFromGUI, db 0
NEWSYM ErrorPointer, dd 0
NEWSYM TripBufAvail, db 0
NEWSYM dcolortab, times 256 dd 0
NEWSYM genfulladdtab
; Write to buffer
cmp byte[newengen],1
jne .notneweng
cmp byte[vesa2red10],0
jne near genfulladdtabred
.notneweng
xor ecx,ecx
.loopers
mov ax,cx
test [vesa2_rtrcl],cx
jz .nor
and ax,[vesa2_rtrcla]
or ax,[vesa2_rfull]
.nor
test [vesa2_gtrcl],cx
jz .nog
and ax,[vesa2_gtrcla]
or ax,[vesa2_gfull]
.nog
test [vesa2_btrcl],cx
jz .nob
and ax,[vesa2_btrcla]
or ax,[vesa2_bfull]
.nob
shl ax,1
mov [fulladdtab+ecx*2],ax
dec cx
jnz .loopers
ret
NEWSYM genfulladdtabred
NEWSYM genfulladdtabng
; Write to buffer
xor ecx,ecx
.loopers
mov ax,cx
test cx,0100000000000000b
jz .nor
and ax,1011111111111111b
or ax, 0011110000000000b
.nor
test cx,0000001000000000b
jz .nog
and ax,1111110111111111b
or ax, 0000000111100000b
.nog
test cx,0000000000010000b
jz .nob
and ax,1111111111101111b
or ax, 0000000000001111b
.nob
shl ax,1
mov [fulladdtab+ecx*2],ax
dec cx
jnz .loopers
ret
NEWSYM VESA2EXITTODOS
mov byte[videotroub],1
cmp byte[ExitFromGUI],0
je .nogui
mov [ErrorPointer],edx
ret
.nogui
mov ax,0003h
int 10h
push edx
mov edx,.exitfromvesa2
call PrintStr
pop edx
call PrintStr
mov edx,.return
call PrintStr
mov dl,[InitDrive]
mov ebx,InitDir
call Change_Dir
jmp DosExit
.exitfromvesa2 db 'Unable to Initialize VESA2 : ',0
.return db 10,13,0
;*******************************************************
; Set up Vesa 2
;*******************************************************
NEWSYM InitVesa2
;-------------------------------------------------;
; 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 VESA2EXITTODOS
.nomemmessage
db 'Unable to locate DOS memory.',0
.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],'VBE2' ; 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 VESA2EXITTODOS
.noint1message
db 'Simulated real mode interrupt failed.',0
.int1ok ; Real mode int successful!!!
mov eax,[RMREGS.eax]
cmp al,4fh ; Check vbe interrupt went OK
jz .vbedetected
mov edx,.novbemessage
jmp VESA2EXITTODOS
.novbemessage
db 'VBE not detected!!',0
.vbedetected
cmp dword[fs:0000],'VESA'
jz .vesadetected ; Check for presence of vesa
mov edx,.novesamessage
jmp VESA2EXITTODOS
.novesamessage
db 'VESA not detected!',0
.vesadetected
cmp word[fs:0004],200h
jae .vesa2detected ; Check we've got VESA 2.0 or greater
mov edx,.novesa2message
jmp VESA2EXITTODOS
.novesa2message
db 'VESA 2.0 or greater required!',0
;-----------------------------------------------------;
; OK - vesa 2.0 or greater has been detected. Copy ;
; mode information into VESAmodelist ;
;-----------------------------------------------------;
.vesa2detected
mov dword[vesa3en],0
cmp word[fs:004],300h
jb .notvbe3
mov dword[vesa3en],1
.notvbe3
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 VESA2EXITTODOS
.oopsnoselector
db 'Failed to allocate vesa display selector!',0
.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 VESA2EXITTODOS
.outofmodelistspacemessage
db 'Out of VESA2 mode list space!',0
;----------------------------------------------;
; 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 VESA2EXITTODOS
.endoflist db 'This VESA2 mode does not work on your video card / driver.',0
.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 VESA2EXITTODOS
.modecheckfail
db 'Real mode interrupt failure while checking vesa mode',0
.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 ax,3
; int 10h
; xor eax,eax
; mov ax,[fs:0h]
; call printnum
; jmp DosExit
mov byte[TripBufAvail],1
test word[fs:0000h],400h
jz .notbuf
mov byte[TripBufAvail],1
.notbuf
; jz .notvesa3
; xor eax,eax
; mov ax,[fs:0000h]
; call printhex
; jmp DosExit
.notvesa3
; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -