⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 copyvid.inc

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 INC
📖 第 1 页 / 共 5 页
字号:
;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 + -