📄 copyvid.inc
字号:
;Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach );;http://www.zsnes.com;http://sourceforge.net/projects/zsnes;https://zsnes.bountysource.com;;This program is free software; you can redistribute it and/or;modify it under the terms of the GNU General Public License;version 2 as published by the Free Software Foundation.;;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.%macro MMXStuff 0%%1 movq mm0,[esi] movq [es:edi],mm0 movq mm1,[esi+8] movq [es:edi+8],mm1 add esi,16 add edi,16 dec ecx jnz %%1%endmacro%macro FilterTest 1 cmp byte[GUIOn],1 jne %%nogui cmp byte[FilteredGUI],1 jne %%nofilter%%nogui cmp byte[antienab],1 je near %1%%nofilter%endmacro; Blends two 16-bit pixels at 50%.; ax = first pixel, bx = second pixel; ax (after) = resulting pixel%macro SSHalfBlend 0 shr eax,byte 1 shr ebx,byte 1 and eax,7befh and ebx,7befh add eax,ebx%endmacro; Horizontal recursive anti-aliasing,; blurs edges without increasing size.; ax = current pixel, bx = working pixel; ecx = number of pixels (passed)%macro SSInterpLineH 0 mov ax,[esi] mov [es:edi],ax add esi,byte 2 add edi,byte 2 mov ecx,254%%loop mov ax,[esi] mov bx,[esi-2] cmp ax,bx jne %%loop2 mov [es:edi],ax mov [es:edi-2],bx jmp %%loop3%%loop2 SSHalfBlend mov [es:edi],ax mov [es:edi-2],ax%%loop3 add esi,byte 2 add edi,byte 2 dec ecx jnz %%loop mov ax,[esi] mov [es:edi],ax add esi,byte 2 add edi,byte 2%endmacro; Used for 640x400 16bit...; Kills the vertical stretch effect.; ax = current pixel, bx = working pixel; ecx = number of pixels (passed)%macro SSInterpLineV 0%%loop mov ax,[esi] mov bx,[esi-(288*2)] cmp ax,bx je %%loop2 SSHalfBlend%%loop2 mov [es:edi],ax mov [es:edi+2],ax add esi,byte 2 add edi,byte 4 dec ecx jnz %%loop%endmacro; True high-resolution interpolation.; Don't forget to skip every other line; (on the screen, not in vidbuffer).; ax = current pixel, bx = working pixel; ecx = number of pixels (passed)%macro SSInterpFull 1%%loop mov ax,[esi] mov [es:edi],ax mov bx,[esi+2] SSHalfBlend mov [es:edi+2],ax mov ax,[esi] mov bx,[esi+(288*2)] SSHalfBlend mov [es:edi+(%1*2)],ax mov ax,[esi] mov bx,[esi+(288*2)+2] SSHalfBlend mov [es:edi+(%1*2)+2],ax add esi,byte 2 add edi,byte 4 dec ecx jnz %%loop%endmacro%macro FlipCheck 0 cmp byte[FlipWait],0 je %%noflip mov edx,3DAh ;VGA status port in al,dx test al,8 jz %%noflip mov eax,4F07h mov bh,00h mov bl,00h xor ecx,ecx mov dx,[NextLineStart] mov [LastLineStart],dx int 10h mov byte[FlipWait],0%%noflip%endmacroSECTION .textNEWSYM 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 eax,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 eax,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 retPostTripleBuffer: 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 retPreTripleBuffer2: 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 edx,3DAh ;VGA status port.loop in al,dx test al,8 jz .loop mov eax,4F07h mov bh,00h mov bl,00h xor ecx,ecx 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 retPreTripleBuffer: 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 eax,4F07h; mov bx,04h; int 10h; or ah,ah; jnz .noflip; or cx,cx; jz .notflipped.noflip mov eax,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%endifSECTION .data; Please don't break this again. :)VidModeSize dd 0,0,0,0,0,0,0,320*240,320*240*2,320*480,320*480*2,512*384 dd 512*384*2,640*400,640*400*2,640*480,640*480*2,800*600,800*600*2VidModeLine dd 0,0,0,0,0,0,0,240,240,480,480,384,384,400,400,480,480,600,600NEWSYM VidStartDraw, dd 0VidModeComp db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1CVidStartAd db 0ApplyStart db 4SECTION .bssNEWSYM NextLineStart, resd 1NEWSYM LastLineStart, resd 1NEWSYM FlipWait, resb 1NEWSYM TriplebufTech, resb 1SECTION .text%ifdef __MSDOS__NEWSYM DosDrawScreen cmp byte[curblank],40h je .nocopy call PreTripleBuffer2 call PostTripleBuffer.nocopy call ScreenShow FlipCheck retNEWSYM DosDrawScreenB cmp byte[curblank],40h je .nocopy call GUITripleBuffer.nocopy call ScreenShow retScreenShow: cmp byte[debugdisble],0 je .debug cmp byte[cvidmode],2 je near copymodeq256.debug cmp byte[cvidmode],0 je near copymodeq224 cmp byte[cvidmode],1 je near copymodeq240 cmp byte[cvidmode],3 je near copymodex224 cmp byte[cvidmode],4 je near copymodex240 cmp byte[cvidmode],5 je near copymodex256 cmp byte[cvidmode],6 je near copyvesa12640x480x16b cmp byte[cvidmode],7 je near copyvesa2320x240x8b cmp byte[cvidmode],8 je near copyvesa2320x240x16b cmp byte[cvidmode],9 je near copyvesa2320x480x8b cmp byte[cvidmode],10 je near copyvesa2320x480x16b cmp byte[cvidmode],11 je near copyvesa2512x384x8b cmp byte[cvidmode],12 je near copyvesa2512x384x16b cmp byte[cvidmode],13 je near copyvesa2640x400x8b cmp byte[cvidmode],14 je near copyvesa2640x400x16b cmp byte[cvidmode],15 je near copyvesa2640x480x8b cmp byte[cvidmode],16 je near copyvesa2640x480x16b cmp byte[cvidmode],17 je near copyvesa2800x600x8b cmp byte[cvidmode],18 je near copyvesa2800x600x16b cmp byte[curblank],40h jne .startcopy inc byte[curfps2]; call sounddisplay call hextestoutput.startcopy jmp copymodeq256;NEWSYM dosvidpastecopyscr; cmp byte[curblank],40h; je .nocopy; call GUITripleBuffer;.nocopy; call ScreenShowGUI; ret;ScreenShowGUI:; cmp byte[cvidmode],0; je near copymodeq224; cmp byte[cvidmode],1; je near copymodeq240; cmp byte[cvidmode],2; je near copymodeq256; cmp byte[cvidmode],3; je near copymodex224; cmp byte[cvidmode],4; je near copymodex240; cmp byte[cvidmode],5; je near copymodex256; cmp byte[cvidmode],6; je near copyvesa12640x480x16bgui; cmp byte[cvidmode],7; je near copyvesa2320x240x8b; cmp byte[cvidmode],8; je near copyvesa2320x240x16bgui; cmp byte[cvidmode],9; je near copyvesa2320x480x8bgui; cmp byte[cvidmode],10; je near copyvesa2320x480x16bgui; cmp byte[cvidmode],11; je near copyvesa2512x384x8b; cmp byte[cvidmode],12; je near copyvesa2512x384x16bgui; cmp byte[cvidmode],13; je near copyvesa2640x400x8b; cmp byte[cvidmode],14; je near copyvesa2640x400x16b; cmp byte[cvidmode],15; je near copyvesa2640x480x8bgui; cmp byte[cvidmode],16; je near copyvesa2640x480x16bgui; cmp byte[cvidmode],17; je near copyvesa2800x600x8b; cmp byte[cvidmode],18; je near copyvesa2800x600x16b; jmp copymodeq256%endif%ifdef __MSDOS__;*******************************************************; CopyModeX 224 Copies buffer into unchained 320x224;*******************************************************NEWSYM copymodex224 cmp byte[curblank],40h jne .startcopy ret.startcopy ; video memory selector push es mov ax,[selcA000] mov es,ax mov esi,[vidbuffer] ; center on output screen mov edi,(320-256)/2/4 ; address of first source line to copy add esi,(16+256+16)+16 ; 2nd page address mov eax,(320*225)/4 mov bl,224-2 jmp copymodexloop;*******************************************************; CopyModeX 240 Copies buffer into unchained 320x240;*******************************************************NEWSYM copymodex240 cmp byte[curblank],40h jne .startcopy ret.startcopy ; video memory selector push es mov ax,[selcA000] mov es,ax mov esi,[vidbuffer] ; center on output screen mov edi,(320-256)/2/4 cmp word[resolutn],224 jne .res239 mov edi,(8*320+32)/4.res239 ; address of first source line to copy add esi,(16+256+16)+16 ; 2nd page address mov eax,(320*240)/4 mov bl,[resolutn] sub bl,2 jmp copymodexloop;*******************************************************; CopyModeX 256 Copies buffer into unchained 320x256;*******************************************************NEWSYM copymodex256 cmp byte[curblank],40h jne .startcopy ret.startcopy ; video memory selector push es mov ax,[selcA000] mov es,ax mov esi,[vidbuffer] ; center on output screen mov edi,(8*320+(320-256)/2)/4 cmp word[resolutn],224 jne .res239 mov edi,(16*320+(320-256)/2)/4.res239 ; address of first source line to copy add esi,(16+256+16)+16 ; 2nd page address mov eax,(320*256)/4 mov bl,[resolutn] sub bl,2;eax = VGA address of 2nd page;edi = offset in current page of first line;esi = address of first line to be copied;bl = number of lines to copycopymodexloop: ; select output video page mov bh,[whichpage] test bh,bh mov bh,1 jz .pagea xor eax,eax mov bh,0.pagea mov [whichpage],bh add edi,eax mov [.pageaddress],eax; register allocation; bl = line counter (0-total lines); bh = other line counter (descriptive, eh?) (0-8); ebp = plane counter; ch = plane enable bit; cl = 4-pixel copy counter; edx = pixel processing & I/O address; eax = pixel processing & I/O data mov edx,03C4h.loopa mov ebp,4 mov ch,1 cmp bl,8 mov bh,bl jb .loopb mov bh,8.loopb ; set write plane mov ah,ch add ch,ch mov al,02h out dx,ax push ebx push edi push esi.loopc ; loop count mov cl,16.loopd mov al,[esi+8] mov ah,[esi+12] shl eax,16 mov al,[esi+0] mov ah,[esi+4] add esi,byte 16 mov [es:edi],eax add edi,byte 4 dec cl jnz .loopd add esi,byte 16+16 add edi,byte (320-256)/4 dec bh jnz .loopc pop esi pop edi pop ebx inc esi dec ebp jnz .loopb ; next line add esi,(16+256+16)*8-4 add edi,320*8/4 sub bl,bh jnz .loopa pop es ; flip pages by setting new offset mov edx,03D4h mov al,0Ch mov ah,[.pageaddress+1] out dx,ax mov al,0Dh mov ah,[.pageaddress] out dx,ax retSECTION .bss.startesi resd 1.startedi resd 1.pageaddress resd 1.linecount resd 1NEWSYM whichpage, resb 1 ; active page and visual page locationsSECTION .text;*******************************************************; CopyModeQ 224 Copies buffer into chained 256x224;*******************************************************NEWSYM copymodeq224 cmp byte[curblank],40h jne .startcopy ret.startcopy ; video memory selector push es mov ax,[selcA000] mov es,ax mov esi,[vidbuffer] ; center on output screen mov edi,256 ; address of first source line to copy add esi,(16+256+16)+16 mov bl,224-2 jmp copymodeqloop;*******************************************************; CopyModeQ 240 Copies buffer into chained 256x240;*******************************************************NEWSYM copymodeq240 cmp byte[curblank],40h jne .startcopy ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -