📄 copyvid.inc
字号:
;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.
SECTION .text
%macro FlipCheck 0
cmp byte[FlipWait],0
je %%noflip
mov dx,3DAh ;VGA status port
in al,dx
test al,8
jz %%noflip
mov ax,4F07h
mov bh,00h
mov bl,00h
xor cx,cx
mov dx,[NextLineStart]
mov [LastLineStart],dx
int 10h
mov byte[FlipWait],0
%%noflip
%endmacro
NEWSYM ResetTripleBuf
mov byte[FlipWait],0
mov dword[VidStartDraw],0
mov byte[CVidStartAd],0
ret
%ifdef __MSDOS__
GUITripleBuffer:
cmp byte[TriplebufTech],0
je near .tech2
cmp byte[ApplyStart],0
je .notstartedb
mov byte[ApplyStart],0
cmp word[LastLineStart],0
je .notstartedb
mov ax,4F07h
mov bh,00h
mov bl,00h
xor ecx,ecx
xor edx,edx
int 10h
.notstartedb
mov byte[FlipWait],0
mov dword[VidStartDraw],0
mov byte[CVidStartAd],0
mov dword[LastLineStart],0
ret
.tech2
xor ecx,ecx
mov cl,[cvidmode]
cmp byte[VidModeComp+ecx],0
je .notbuf
cmp byte[Triplebufen],0
je .notbuf
jmp .yestbuf
.notbuf
ret
.yestbuf
cmp byte[ApplyStart],0
je .notstarted
mov ax,4F07h
mov bh,00h
mov bl,02h
xor ecx,ecx
xor edx,edx
int 10h
cmp byte[ApplyStart],4
jne .nocheck
cmp al,4Fh
jne .failed
cmp ah,0
ja .failed
.nocheck
mov dword[VidStartDraw],0
mov byte[CVidStartAd],0
mov byte[ApplyStart],0
.notstarted
ret
.failed
mov byte[TriplebufTech],1
ret
PostTripleBuffer:
xor ecx,ecx
mov cl,[cvidmode]
cmp byte[VidModeComp+ecx],0
je .notbuf
cmp byte[Triplebufen],0
je .notbuf
jmp .yestbuf
.notbuf
ret
.yestbuf
xor ecx,ecx
cmp byte[CVidStartAd],2
je .nooffset0
mov cl,[cvidmode]
mov ecx,[VidModeSize+ecx*4]
cmp byte[CVidStartAd],0
je .nooffset0
add ecx,ecx
.nooffset0
mov [VidStartDraw],ecx
inc byte[CVidStartAd]
cmp byte[CVidStartAd],3
jne .notof
mov byte[CVidStartAd],0
.notof
ret
PreTripleBuffer2:
cmp byte[TriplebufTech],0
je near PreTripleBuffer
xor ecx,ecx
mov cl,[cvidmode]
cmp byte[VidModeComp+ecx],0
je .notbuf
cmp byte[Triplebufen],0
jne .yestbuf
.notbuf
ret
.yestbuf
cmp byte[FlipWait],0
je .noflip
mov dx,3DAh ;VGA status port
.loop
in al,dx
test al,8
jz .loop
mov ax,4F07h
mov bh,00h
mov bl,00h
xor cx,cx
mov dx,[NextLineStart]
mov [LastLineStart],dx
int 10h
mov byte[FlipWait],0
.noflip
xor ecx,ecx
cmp byte[CVidStartAd],2
je .nooffset0
mov cl,[cvidmode]
mov ecx,[VidModeLine+ecx*4]
cmp byte[CVidStartAd],0
je .nooffset0
add ecx,ecx
.nooffset0
mov [NextLineStart],ecx
mov byte[ApplyStart],1
mov byte[FlipWait],1
ret
PreTripleBuffer:
xor ecx,ecx
mov cl,[cvidmode]
cmp byte[VidModeComp+ecx],0
je .notbuf
cmp byte[Triplebufen],0
jne .yestbuf
.notbuf
ret
.yestbuf
cmp byte[ApplyStart],2
jne .noflip
.notflipped
; *** I have no idea why this code doesn't work (freezes on NVidia cards)
; mov ax,4F07h
; mov bx,04h
; int 10h
; or ah,ah
; jnz .noflip
; or cx,cx
; jz .notflipped
.noflip
mov ax,4F07h
mov bh,00h
mov bl,02h
xor ecx,ecx
cmp byte[CVidStartAd],0
je .nooffset0
mov cl,[cvidmode]
mov ecx,[VidModeSize+ecx*4]
cmp byte[CVidStartAd],1
je .nooffset0
add ecx,ecx
.nooffset0
xor edx,edx
int 10h
cmp byte[ApplyStart],4
jne .nocheck
cmp al,4Fh
jne .failed
cmp ah,0
ja .failed
mov byte[ApplyStart],0
.nocheck
cmp byte[ApplyStart],2
je .skipcheckb
inc byte[ApplyStart]
.skipcheckb
ret
.failed
mov byte[Triplebufen],0
ret
%endif
VidModeSize dd 0,0,320*240,320*240*2,640*480,640*480*2,512*384,512*384*2
dd 0,320*480,320*480*2
VidModeLine dd 0,0,240,240,480,480,384,384
dd 0,480,480
NEWSYM VidStartDraw, dd 0
VidModeComp db 0,0,1,1,1,1,1,1,0,1,1
CVidStartAd db 0
ApplyStart db 4
NEWSYM NextLineStart, dd 0
NEWSYM LastLineStart, dd 0
NEWSYM FlipWait, db 0
NEWSYM TriplebufTech, db 0
%ifdef __MSDOS__
NEWSYM DosDrawScreen
cmp byte[curblank],40h
je .nocopy
call PreTripleBuffer2
call PostTripleBuffer
.nocopy
call ScreenShow
FlipCheck
ret
NEWSYM DosDrawScreenB
cmp byte[curblank],40h
je .nocopy
call GUITripleBuffer
.nocopy
call ScreenShow
ret
ScreenShow:
cmp byte[debugdisble],0
je .debug
cmp byte[cvidmode],1
je near copymodeq
.debug
cmp byte[cvidmode],2
je near copyvesa2320x240x8b
cmp byte[cvidmode],3
je near copyvesa2320x240x16b
cmp byte[cvidmode],4
je near copyvesa2640x480x8b
cmp byte[cvidmode],5
je near copyvesa2640x480x16b
cmp byte[cvidmode],6
je near copyvesa2512x384x8b
cmp byte[cvidmode],7
je near copyvesa2512x384x16b
cmp byte[cvidmode],8
je near copyvesa12640x480x16b
cmp byte[cvidmode],9
je near copyvesa2320x480x8b
cmp byte[cvidmode],10
je near copyvesa2320x480x16b
cmp byte[cvidmode],0
je near copymodex
cmp byte[curblank],40h
je .startcopy
inc byte[curfps2]
; call sounddisplay
call hextestoutput
.startcopy
jmp copymodeq
NEWSYM dosvidpastecopyscr
cmp byte[curblank],40h
je .nocopy
call GUITripleBuffer
.nocopy
call ScreenShowGUI
ret
ScreenShowGUI:
cmp byte[cvidmode],1
je near copymodeq
cmp byte[cvidmode],2
je near copyvesa2320x240x8b
cmp byte[cvidmode],3
je near copyvesa2320x240x16bgui
cmp byte[cvidmode],4
je near copyvesa2640x480x8bgui
cmp byte[cvidmode],5
je near copyvesa2640x480x16bgui
cmp byte[cvidmode],6
je near copyvesa2512x384x8b
cmp byte[cvidmode],7
je near copyvesa2512x384x16bgui
cmp byte[cvidmode],8
je near copyvesa12640x480x16bgui
cmp byte[cvidmode],9
je near copyvesa2320x480x8bgui
cmp byte[cvidmode],10
je near copyvesa2320x480x16bgui
cmp byte[cvidmode],0
je near copymodex
jmp copymodeq
%endif
;*******************************************************
; CopyModeX Copies buffer into unchained 320x240
;*******************************************************
%ifdef __MSDOS__
NEWSYM copymodex
cmp byte[curblank],40h
jne .startcopy
ret
.startcopy
; select plane 1
mov dx,03C4h
mov ax,0102h ; set as plane 1
out dx,ax
push es
mov ax,[selcA000]
mov es,ax
mov esi,[vidbuffer]
mov edi,8 ; Draw @ Y from 9 to 247
cmp word[resolutn],224
jne .res239
mov edi,8*80+8
.res239
add esi,16+256+32
cmp byte[whichpage],0
jne .pageb
add edi,19200
.pageb
mov [.startesi],esi
mov [.startedi],edi
mov dl,[resolutn]
dec dl
dec dl
.loopa
mov ecx,16
.loopb
mov ah,[esi+12]
mov al,[esi+8]
shl eax,16
mov ah,[esi+4]
mov al,[esi+0]
mov [es:edi],eax
add esi,16
add edi,4
dec ecx
jnz .loopb
add esi,32
add edi,16
dec dl
jnz .loopa
mov dx,03C4h
mov ax,0202h ; set as plane 2
out dx,ax
mov esi,[.startesi]
inc esi
mov edi,[.startedi]
mov dl,[resolutn]
dec dl
dec dl
.loopa2
mov ecx,16
.loopb2
mov ah,[esi+12]
mov al,[esi+8]
shl eax,16
mov ah,[esi+4]
mov al,[esi+0]
mov [es:edi],eax
add esi,16
add edi,4
dec ecx
jnz .loopb2
add esi,32
add edi,16
dec dl
jnz .loopa2
mov dx,03C4h
mov ax,0402h ; set as plane 3
out dx,ax
mov esi,[.startesi]
add esi,2
mov edi,[.startedi]
mov dl,[resolutn]
dec dl
dec dl
.loopa3
mov ecx,16
.loopb3
mov ah,[esi+12]
mov al,[esi+8]
shl eax,16
mov ah,[esi+4]
mov al,[esi+0]
mov [es:edi],eax
add esi,16
add edi,4
dec ecx
jnz .loopb3
add esi,32
add edi,16
dec dl
jnz .loopa3
mov dx,03C4h
mov ax,0802h ; set as plane 4
out dx,ax
mov esi,[.startesi]
add esi,3
mov edi,[.startedi]
mov dl,[resolutn]
dec dl
dec dl
.loopa4
mov ecx,16
.loopb4
mov ah,[esi+12]
mov al,[esi+8]
shl eax,16
mov ah,[esi+4]
mov al,[esi+0]
mov [es:edi],eax
add esi,16
add edi,4
dec ecx
jnz .loopb4
add esi,32
add edi,16
dec dl
jnz .loopa4
pop es
cmp byte[whichpage],0
jne .setpageb
mov dx,03D4h
mov al,0Ch
out dx,al
inc dx
mov al,75
out dx,al
dec dx
mov al,0Dh
out dx,al
inc dx
xor al,al
out dx,al
mov byte[whichpage],1
ret
.setpageb
mov dx,03D4h
mov al,0Ch
out dx,al
inc dx
xor al,al
out dx,al
dec dx
mov al,0Dh
out dx,al
inc dx
xor al,al
out dx,al
mov byte[whichpage],0
ret
.startesi dd 0
.startedi dd 0
NEWSYM whichpage, db 0 ; active page and visual page locations
;*******************************************************
; CopyModeQ Copies buffer into chained 256x256
;*******************************************************
NEWSYM copymodeq
cmp byte[curblank],40h
jne .startcopy
ret
.startcopy
push es
mov ax,[selcA000]
mov es,ax
mov esi,[vidbuffer]
mov ebp,[vidbufferm]
mov edi,9*256 ; Draw @ Y from 9 to 247
cmp word[resolutn],224
jne .res239
mov edi,17*256
.res239
add esi,16+256+32
add ebp,16+256+32
xor eax,eax
mov dl,[resolutn]
dec dl
dec dl
cmp byte[FPUCopy],2
je near .loopc
.loopa
mov ecx,64
rep movsd
add esi,32
dec dl
jnz .loopa
pop es
ret
.loopc
mov ecx,16
MMXStuff
add esi,32
dec dl
jnz .loopc
emms
pop es
ret
;*******************************************************
; Copy VESA2 320x240x8b Copies buffer to 320x240x8bVBE2
;*******************************************************
; Input: AX = 4F07h VBE Set/Get Display Start Control
; BH = 00h Reserved and must be 00h
; BL = 00h Set Display Start
; = 01h Get Display Start
; = 80h Set Display Start during Vertical
; Retrace
; CX = First Displayed Pixel In Scan Line
; (Set Display Start only)
; DX = First Displayed Scan Line (Set Display Start
; only)
NEWSYM copyvesa2320x240x8b
cmp byte[curblank],40h
jne .startcopy
ret
.startcopy
cmp byte[ScreenScale],1
je near .scalescreen
push es
mov ax,[vesa2selec]
mov es,ax
mov esi,[vidbuffer]
mov edi,32 ; Draw @ Y from 9 to 247
cmp word[resolutn],224
jne .res239
mov edi,8*320+32
.res239
add edi,[VidStartDraw]
add esi,16+256+32
xor eax,eax
mov dl,[resolutn]
dec dl
dec dl
cmp byte[FPUCopy],1
je .loopb
cmp byte[FPUCopy],2
je near .loopc
.loopa
mov ecx,64
rep movsd
add esi,32
add edi,64
dec dl
jnz .loopa
pop es
ret
.loopb
CopyFPU
add esi,32
add edi,64
dec dl
jnz near .loopa
pop es
ret
.loopc
mov ecx,16
MMXStuff
add esi,32
add edi,64
dec dl
jnz .loopc
emms
pop es
ret
.scalescreen
push es
mov ax,[vesa2selec]
mov es,ax
mov esi,[vidbuffer]
xor edi,edi
cmp word[resolutn],224
jne .res239b
mov edi,8*320
.res239b
add edi,[VidStartDraw]
add esi,16+256+32
xor eax,eax
mov dl,[resolutn]
dec dl
dec dl
.loopab
mov ecx,64
.loopbbb
mov eax,[esi]
mov [es:edi],al
mov [es:edi+1],eax
add esi,4
add edi,5
dec ecx
jnz .loopbbb
add esi,32
dec dl
jnz .loopab
pop es
ret
;*******************************************************
; Copy VESA2 320x480x8b Copies buffer to 320x480x8bVBE2
;*******************************************************
NEWSYM copyvesa2320x480x8bgui
mov byte[CurrentGUIOn],1
jmp copyvesa2320x480x8b.nogui
NEWSYM copyvesa2320x480x8b
mov byte[CurrentGUIOn],0
.nogui
cmp byte[curblank],40h
jne .startcopy
ret
.startcopy
push es
mov ax,[vesa2selec]
mov es,ax
mov esi,[vidbuffer]
mov edi,32 ; Draw @ Y from 9 to 247
cmp word[resolutn],224
jne .res239
mov edi,8*320+32
.res239
add edi,[VidStartDraw]
add esi,16+256+32
xor eax,eax
mov dl,[resolutn]
dec dl
dec dl
cmp byte[scanlines],1
je near copyvesa2320x480x8bs
cmp byte[CurrentGUIOn],1
je .loopa
cmp byte[f3menuen],1
je .loopa
cmp byte[ForceNewGfxOff],0
jne .loopa
cmp byte[newengen],0
jne near copyvesa2320x480x8ng
.loopa
mov ecx,64
.a
mov eax,[esi]
mov [es:edi],eax
add esi,4
add edi,4
dec ecx
jnz .a
mov ecx,64
add edi,64
sub esi,256
.a2r
mov eax,[esi]
mov [es:edi],eax
add esi,4
add edi,4
dec ecx
jnz .a2r
.returnloop
add esi,32
add edi,64
dec dl
jnz .loopa
pop es
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -