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

📄 dma.asm

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;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 memtabler8,regptw,snesmap2,snesmmap,debstop3
;EXTSYM soundcycleft,pexecs2
EXTSYM memtablew8,regptr
EXTSYM dmadata
EXTSYM hdmatype
EXTSYM nexthdma
EXTSYM curhdma,curypos,disablehdma,hdmadata,hdmadelay,hdmaearlstart
EXTSYM resolutn
EXTSYM memtabler16

NEWSYM DmaAsmStart




;*******************************************************
; Transfer DMA                     Inits & Transfers DMA
;*******************************************************
; DMA transfer register

NEWSYM AddrNoIncr, db 0

%macro ExecSPCCycles 0
    xor ebx,ebx
    mov bx,[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
%endmacro

NEWSYM 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
    mov al,1
.notmode5dma
    mov bl,al
    shl bl,3
    add ebx,.addrwrite
    mov edi,ebx

    ; get pointer #1
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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]

;snesmmap times 256 dd 0         ; addresses 8000-FFFF
;snesmap2 times 256 dd 0         ; addresses 0000-7FFF

    push esi
    mov esi,ebx
    xor ebx,ebx
    mov bl,[.curbank]
    ; do loop
    cmp edx,0
    jne .no0
    mov edx,65536
.no0
    mov ebx,[memtabler8+ebx*4]
    mov [.readaddr],ebx
    xor ebx,ebx
    mov bl,[.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
    ret

ALIGN32

.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 0

NEWSYM 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
    xor ebx,ebx
    and al,00000111b
    mov bl,al
    shl bl,3
    add ebx,.addrwrite
    mov edi,ebx

    ; get pointer #1
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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]

;snesmmap times 256 dd 0         ; addresses 8000-FFFF
;snesmap2 times 256 dd 0         ; addresses 0000-7FFF

    push esi
    mov esi,ebx
    xor ebx,ebx
    mov bl,[.curbank]
    ; do loop
    cmp edx,0
    jne .no0
    mov edx,65536
.no0
    mov ebx,[memtablew8+ebx*4]
    mov [.writeaddr],ebx
    xor ebx,ebx
    mov bl,[.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
    ret

ALIGN32

.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 0

%macro TestDMA 0
%endmacro

; DMA enable register
; use dmadata for input on dma
NEWSYM 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 eax,eax
    xor ecx,ecx
    mov al,[esi]
    and al,00000111b
    mov ah,[.addrnumt+eax]
    mov [edx+16],ah
    mov bl,al
    shl bl,3
    add ebx,.addrwrite
    mov edi,ebx

    ; get pointer #1
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    ret

.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,4

NEWSYM setuphdmars
    push eax

    ; get address order to be written
    xor ebx,ebx
    xor eax,eax
    xor ecx,ecx
    mov al,[esi]
    and al,00000111b
    mov ah,[.addrnumt+eax]
    mov [edx+16],ah
    mov bl,al
    shl bl,3
    add ebx,.addrwrite
    mov edi,ebx

    ; get pointer #1
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    ret

.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,4

NEWSYM 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 eax,eax
    xor ecx,ecx
    mov al,[esi]
    and al,00000111b
    mov ah,[.addrnumt+eax]
    mov [edx+16],ah
    mov bl,al
    shl bl,3
    add ebx,.addrwrite
    mov edi,ebx

    ; get pointer #1
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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
    xor ebx,ebx
    mov bl,[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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -