📄 dma.asm
字号:
;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.%include "macros.mac"EXTSYM memtabler8,regptw,snesmap2,snesmmap,memtablew8,regptr,memtabler16EXTSYM dmadata,hdmatype,nexthdma,resolutn,curhdma,curypos,hdmadataEXTSYM hdmadelay,hdmarestart,nohdmaframe,INTEnab,HIRQLoc;*******************************************************; Transfer DMA Inits & Transfers DMA;*******************************************************; DMA transfer registersection .bssNEWSYM AddrNoIncr, resb 1section .text%macro ExecSPCCycles 0 movzx ebx,word[esi+5] inc bx inc ebx shr ebx,2 mov [soundcycleft],ebx or ebx,ebx jz .nocycles xor ebx,ebx xor ecx,ecx call pexecs2.nocycles%endmacroNEWSYM transdma push eax cmp word[esi+5],480h jne .no; mov byte[debstop3],1.no; ExecSPCCycles mov al,[esi] test al,80h jnz near transdmappu2cpu ; set address increment value mov dword[.addrincr],0 test al,00001000b jnz .skipaddrincr test al,00010000b jnz .autodec mov dword[.addrincr],1 jmp .skipaddrincr.autodec mov dword[.addrincr],0FFFFFFFFh.skipaddrincr mov byte[AddrNoIncr],0 cmp dword[.addrincr],0 jne .notzero mov byte[AddrNoIncr],1.notzero ; get address order to be written xor ebx,ebx and al,00000111b cmp al,5 jne .notmode5dma sub al,4.notmode5dma mov bl,al shl bl,3 add ebx,.addrwrite mov edi,ebx ; get pointer #1 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi] shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [.regptra],eax ; get pointer #2 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+2] shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [.regptrb],eax ; get pointer #3 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+4] shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [.regptrc],eax ; get pointer #4 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+6] shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [.regptrd],eax mov dx,[esi+5] ; Number of bytes to transfer movzx ebx,byte[esi+4] ; Bank # mov ecx,[esi+2] ; address offset # and ecx,0FFFFh mov [.curbank],bl mov word[esi+5],0 mov ebx,[.curbank] mov eax,snesmap2 test ecx,8000h jz .nomap1 mov eax,snesmmap.nomap1 and edx,0FFFFh mov ebx,[eax+ebx*4] push esi mov esi,ebx movzx ebx,byte[.curbank] ; do loop cmp edx,0 jne .no0 mov edx,65536.no0 mov ebx,[memtabler8+ebx*4] mov [.readaddr],ebx movzx ebx,byte[.curbank] mov [.cebx],ebx.againloop cmp edx,4 jbe .deccheckloop mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptra] mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptrb] mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptrc] mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptrd] sub edx,4 jmp .againloop.deccheckloop mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptra] dec edx jz .findma mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptrb] dec edx jz .findma mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptrc] dec edx jz .findma mov ebx,[.cebx] call dword near [.readaddr] add cx,[.addrincr] call dword near [.regptrd].findma pop esi mov [esi+2],cx pop eax mov byte[AddrNoIncr],0 retsection .dataALIGN32.curbank dd 0.addrincr dd 0.addrwrite dw 0,0,0,0, 0,1,0,1, 0,0,0,0, 0,0,1,1, 0,1,2,3, 0,1,2,3, 0,1,2,3 dw 0,1,2,3; pointer address of registers.regptra dd 0.regptrb dd 0.regptrc dd 0.regptrd dd 0.readaddr dd 0.cebx dd 0section .textNEWSYM transdmappu2cpu ; set address increment value mov dword[.addrincr],0 test al,00001000b jnz .skipaddrincr test al,00010000b jnz .autodec mov dword[.addrincr],1 jmp .skipaddrincr.autodec mov dword[.addrincr],0FFFFFFFFh.skipaddrincr ; get address order to be written and al,00000111b movzx ebx,al shl bl,3 add ebx,.addrwrite mov edi,ebx ; get pointer #1 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi] shl ebx,2 add ebx,[regptr] mov eax,[ebx] mov [.regptra],eax ; get pointer #2 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+2] shl ebx,2 add ebx,[regptr] mov eax,[ebx] mov [.regptrb],eax ; get pointer #3 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+4] shl ebx,2 add ebx,[regptr] mov eax,[ebx] mov [.regptrc],eax ; get pointer #4 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+6] shl ebx,2 add ebx,[regptr] mov eax,[ebx] mov [.regptrd],eax mov dx,[esi+5] ; Number of bytes to transfer movzx ebx,byte[esi+4] ; Bank # mov ecx,[esi+2] ; address offset # and ecx,0FFFFh mov [.curbank],bl mov word[esi+5],0 mov ebx,[.curbank] mov eax,snesmap2 test ecx,8000h jz .nomap1 mov eax,snesmmap.nomap1 and edx,0FFFFh mov ebx,[eax+ebx*4] push esi mov esi,ebx movzx ebx,byte[.curbank] ; do loop cmp edx,0 jne .no0 mov edx,65536.no0 mov ebx,[memtablew8+ebx*4] mov [.writeaddr],ebx movzx ebx,byte[.curbank] mov [.cebx],ebx.againloop cmp edx,4 jbe .deccheckloop call dword near [.regptra] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] call dword near [.regptrb] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] call dword near [.regptrc] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] call dword near [.regptrd] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] sub edx,4 jmp .againloop.deccheckloop call dword near [.regptra] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] dec edx jz .findma call dword near [.regptrb] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] dec edx jz .findma call dword near [.regptrc] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr] dec edx jz .findma call dword near [.regptrd] mov ebx,[.cebx] call dword near [.writeaddr] add cx,[.addrincr].findma pop esi mov [esi+2],cx pop eax retsection .dataALIGN32.curbank dd 0.addrincr dd 0.addrwrite dw 0,0,0,0, 0,1,0,1, 0,0,0,0, 0,0,1,1, 0,1,2,3, 0,1,2,3, 0,1,2,3 dw 0,1,2,3; pointer address of registers.regptra dd 0.regptrb dd 0.regptrc dd 0.regptrd dd 0.writeaddr dd 0.cebx dd 0section .text%macro TestDMA 0%endmacro; DMA enable register; use dmadata for input on dmaNEWSYM reg420Bw push eax push esi push edi push ecx push edx mov esi,dmadata test al,01h jz .notransa TestDMA call transdma.notransa add esi,16 test al,02h jz .notransb TestDMA call transdma.notransb add esi,16 test al,04h jz .notransc TestDMA call transdma.notransc add esi,16 test al,08h jz .notransd TestDMA call transdma.notransd add esi,16 test al,10h jz .notranse TestDMA call transdma.notranse add esi,16 test al,20h jz .notransf TestDMA call transdma.notransf add esi,16 test al,40h jz .notransg TestDMA call transdma.notransg add esi,16 test al,80h jz .notransh TestDMA call transdma.notransh pop edx pop ecx pop edi pop esi pop eax ret;*******************************************************; HDMA Settings;*******************************************************NEWSYM setuphdma push eax ; transfer old address to new address mov ax,[esi+2] mov [esi+8],ax mov [edx+17],ax ; get address order to be written xor ebx,ebx xor ecx,ecx movzx eax,byte[esi] and al,00000111b cmp al,5 jb .notmode567dma sub al,4.notmode567dma mov ah,[.addrnumt+eax] mov [edx+16],ah mov bl,al shl bl,3 add ebx,.addrwrite mov edi,ebx ; get pointer #1 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi] cmp bx,2118h je .notnormalhdma1 cmp bx,2119h je .notnormalhdma1 jmp .normalhdma1.notnormalhdma1 mov bx,2200h ; bad hack _Demo_.normalhdma1 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx],eax ; get pointer #2 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+2] cmp bx,2118h je .notnormalhdma2 cmp bx,2119h je .notnormalhdma2 jmp .normalhdma2.notnormalhdma2 mov bx,2200h ; bad hack _Demo_.normalhdma2 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx+4],eax ; get pointer #3 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+4] cmp bx,2118h je .notnormalhdma3 cmp bx,2119h je .notnormalhdma3 jmp .normalhdma3.notnormalhdma3 mov bx,2200h ; bad hack _Demo_.normalhdma3 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx+8],eax ; get pointer #4 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+6] cmp bx,2118h je .notnormalhdma4 cmp bx,2119h je .notnormalhdma4 jmp .normalhdma4.notnormalhdma4 mov bx,2200h ; bad hack _Demo_.normalhdma4 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx+12],eax xor ebx,ebx mov byte[esi+10],0 pop eax or [hdmatype],ah retsection .data.addrwrite dw 0,0,0,0, 0,1,0,1, 0,0,0,0, 0,0,1,1, 0,1,2,3, 0,1,2,3, 0,1,2,3 dw 0,1,2,3.addrnumt db 1,2,2,4,4,4,4,4section .textNEWSYM setuphdmars push eax ; get address order to be written xor ebx,ebx xor ecx,ecx movzx eax,byte[esi] and al,00000111b cmp al,5 jb .notmode567dma sub al,4.notmode567dma mov ah,[.addrnumt+eax] mov [edx+16],ah mov bl,al shl bl,3 add ebx,.addrwrite mov edi,ebx ; get pointer #1 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi] cmp bx,2118h je .notnormalhdma1 cmp bx,2119h je .notnormalhdma1 jmp .normalhdma1.notnormalhdma1 mov bx,2200h ; bad hack _Demo_.normalhdma1 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx],eax ; get pointer #2 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+2] cmp bx,2118h je .notnormalhdma2 cmp bx,2119h je .notnormalhdma2 jmp .normalhdma2.notnormalhdma2 mov bx,2200h ; bad hack _Demo_.normalhdma2 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx+4],eax ; get pointer #3 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+4] cmp bx,2118h je .notnormalhdma3 cmp bx,2119h je .notnormalhdma3 jmp .normalhdma3.notnormalhdma3 mov bx,2200h ; bad hack _Demo_.normalhdma3 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx+8],eax ; get pointer #4 movzx ebx,byte[esi+1] ; PPU memory - 21xx mov bh,21h add bx,[edi+6] cmp bx,2118h je .notnormalhdma4 cmp bx,2119h je .notnormalhdma4 jmp .normalhdma4.notnormalhdma4 mov bx,2200h ; bad hack _Demo_.normalhdma4 shl ebx,2 add ebx,[regptw] mov eax,[ebx] mov [edx+12],eax xor ebx,ebx pop eax retsection .data.addrwrite dw 0,0,0,0, 0,1,0,1, 0,0,0,0, 0,0,1,1, 0,1,2,3, 0,1,2,3, 0,1,2,3 dw 0,1,2,3.addrnumt db 1,2,2,4,4,4,4,4section .textNEWSYM setuphdma2 push eax cmp byte[esi+10],0 je near .nohdma ; transfer old address to new address mov ax,[esi+8] mov [edx+17],ax ; get address order to be written xor ebx,ebx xor ecx,ecx movzx eax,byte[esi] and al,00000111b cmp al,5 jb .notmode567dma sub al,4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -