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

📄 spc700.asm

📁 linux下的任天堂模拟器代码。供大家参考。
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;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 DSPMem,spcWptr,disablespcclr,SPCSkipXtraROM,cycpbl,spcRptrEXTSYM spc700read,dspWptr,curexecstate,tableadc%include "cpu/regsw.mac"%include "cpu/spcdef.inc"%include "cpu/spcaddr.inc"; SPC 700 Emulation by _Demo_; Version 2.0; Little info on functions :; Write byte : write al at [ebx]; Read byte : read al from [ebx]; update timer : update the timers, called every scanlineSECTION .dataALIGN32;spcBuffer times 65536*4 db 0    ; The buffer of brr blocks... 4 bits -> 16 bits;spcPrevbf times 65536   db 0    ; SPC PrevX compare bufferNEWSYM SPCRAM,   times 65472 db 0FFh  ; Pointer to the SPC's RAM; copy #1; THE SPC ROM :)   db 0CDh,0EFh,0BDh,0E8h,000h,0C6h,01Dh,0D0h,0FCh,08Fh,0AAh,0F4h,08Fh,0BBh,0F5h,078h   db 0CCh,0F4h,0D0h,0FBh,02Fh,019h,0EBh,0F4h,0D0h,0FCh,07Eh,0F4h,0D0h,00Bh,0E4h,0F5h   db 0CBh,0F4h,0D7h,000h,0FCh,0D0h,0F3h,0ABh,001h,010h,0EFh,07Eh,0F4h,010h,0EBh,0BAh   db 0F6h,0DAh,000h,0BAh,0F4h,0C4h,0F4h,0DDh,05Dh,0D0h,0DBh,01Fh,000h,000h,0C0h,0FFh   db 0AAh,0BBh,0CCh,0DDh,0EEh,0FFh,000h,011h,022h,033h,044h,055h,066h,077h,088h,099hNEWSYM spcPCRam,       dd 0     ; Program Counter (with SPCRAM added)NEWSYM spcA,       db 0     ; The A register (general purpose)       db 0       db 0       db 0NEWSYM spcX,       db 0     ; The X register (general purpose)       db 0       db 0       db 0NEWSYM spcY,       db 0     ; The Y register (general purpose)       db 0       db 0       db 0NEWSYM spcP,       db 0     ; The processor status byte (Removed for each flags)       db 0     ; NZ are not always processed...       db 0       db 0NEWSYM spcNZ,       db 0     ; The processor NZ flag (little speed up hack :) )       db 0       db 0       db 0;spcNF    db 0     ; The Negative Flag  128 or 127;spcOF    db 0     ; The Overflow Flag   64 or 191;spcDPF   db 0     ; Direct Page Flag    32 or 223;spcUF    db 0     ; The Unused Flag ?   16 or 239;spcHCF   db 0     ; The Half Carry Flag  8 or 247;spcIF    db 0     ; The interrupt flag   4 or 251;spcZF    db 0     ; The Zero Flag      2 or 253;spcCF    db 0     ; The Carry Flag     1 or 254NEWSYM spcS,     dd 1FFh  ; The stack pointer (always from 100 to 1FF) (added Ram)NEWSYM spcRamDP, dd 0     ; The direct page pointerNEWSYM spcCycle, dd 0     ; The Cycle CounterNEWSYM reg1read, db 0     ; read from 65816NEWSYM reg2read, db 0     ; read from 65816NEWSYM reg3read, db 0     ; read from 65816NEWSYM reg4read, db 0     ; read from 65816NEWSYM timeron,  db 0     ; timer0 onNEWSYM timincr0, db 0     ; # of ticks before incrementingNEWSYM timincr1, db 0     ; # of ticks before incrementingNEWSYM timincr2, db 0     ; # of ticks before incrementingNEWSYM timinl0,  db 0     ; ticks left before incrementingNEWSYM timinl1,  db 0     ; ticks left before incrementingNEWSYM timinl2,  db 0     ; ticks left before incrementingNEWSYM timrcall, db 0     ; alternating bit 0 to correctly timer timer1 & 2 to 8000hzNEWSYM spcextraram, times 64 db 0 ; extra ram, used for tcallNEWSYM FutureExpandS,  times 256-64 db 0spcsave equ $-SPCRAM; pharos equ hack *sigh*NEWSYM PHspcsave, dd spcsave; copy #2NEWSYM SPCROM   db 0CDh,0EFh,0BDh,0E8h,000h,0C6h,01Dh,0D0h,0FCh,08Fh,0AAh,0F4h,08Fh,0BBh,0F5h,078h   db 0CCh,0F4h,0D0h,0FBh,02Fh,019h,0EBh,0F4h,0D0h,0FCh,07Eh,0F4h,0D0h,00Bh,0E4h,0F5h   db 0CBh,0F4h,0D7h,000h,0FCh,0D0h,0F3h,0ABh,001h,010h,0EFh,07Eh,0F4h,010h,0EBh,0BAh   db 0F6h,0DAh,000h,0BAh,0F4h,0C4h,0F4h,0DDh,05Dh,0D0h,0DBh,01Fh,000h,000h,0C0h,0FFhSECTION .text%macro WriteByte 0  cmp ebx,0ffh+SPCRAM  ja %%extramem  cmp ebx,0f0h+SPCRAM  jb %%normalmem  sub ebx,SPCRAM  call dword near [spcWptr+ebx*4-0f0h*4]  jmp %%finished%%extramem  cmp ebx,0ffc0h+SPCRAM  jb %%normalmem  mov [spcextraram+ebx-0FFC0h-SPCRAM],al  test byte[SPCRAM+0F1h],80h  jnz %%finished;  push ecx;  mov cl,[DSPMem+06Ch];  test cl,20h;  pop ecx;  jz .finished%%normalmem  mov [ebx],al%%finished%endmacro%macro ReadByte 0  cmp ebx,0f0h+SPCRAM  jb %%normalmem2  cmp ebx,0ffh+SPCRAM  ja %%normalmem  sub ebx,SPCRAM  call dword near [spcRptr+ebx*4-0f0h*4]  jmp %%finished%%normalmem;  cmp ebx,0ffc0h+SPCRAM;  jb .rnormalmem2;  test byte[DSPMem+6Ch],10h;  jz .rnormalmem2;  mov al,[spcextraram+ebx-0FFC0h-SPCRAM];  jmp .rfinished%%normalmem2   mov al,[ebx]%%finished%endmacro%macro ReadByte2 0  cmp ebx,0f0h+SPCRAM  jb %%normalmem2  cmp ebx,0ffh+SPCRAM  ja %%normalmem  sub ebx,SPCRAM  call dword near [spcRptr+ebx*4-0f0h*4]  add ebx,SPCRAM  jmp %%finished%%normalmem;  cmp ebx,0ffc0h+SPCRAM;  jb .rnormalmem2;  test byte[DSPMem+6Ch],10h;  jz .rnormalmem2;  mov al,[spcextraram+ebx-0FFC0h-SPCRAM];  jmp .rfinished%%normalmem2   mov al,[ebx]%%finished%endmacroSECTION .dataNEWSYM timer2upd, dd 0SECTION .text; This function is called every scanline (262*60 times/sec); Make it call 0.9825 times (393/400) (skip when divisible by 64); 2 8khz, 1 64khzNEWSYM updatetimer;    inc dword[timer2upd];    cmp dword[timer2upd],400;    jne .nowrap;    mov dword[timer2upd],0;.nowrap;.again;    mov eax,dword[timer2upd];    shr eax,6;    shl eax,6;    cmp eax,dword[timer2upd];    je near .noin2d.another    xor byte[timrcall],01h    test byte[timrcall],01h    jz near .notimer    test byte[timeron],1    jz .noin0    dec byte[timinl0]    jnz .noin0    inc byte[SPCRAM+0FDh]    mov al,[timincr0]    mov [timinl0],al    cmp byte[SPCRAM+0FDh],1    jne .noin0    reenablespc    mov dword[cycpbl],0.noin0    test byte[timeron],2    jz .noin1    dec byte[timinl1]    jnz .noin1    inc byte[SPCRAM+0FEh]    mov al,[timincr1]    mov [timinl1],al    cmp byte[SPCRAM+0FEh],1    jne .noin1    reenablespc    mov dword[cycpbl],0.noin1.notimer    test byte[timeron],4    jz near .noin2d2    dec byte[timinl2]    jnz .noin2    inc byte[SPCRAM+0FFh]    mov al,[timincr2]    mov [timinl2],al    cmp byte[SPCRAM+0FFh],1    jne .noin2    reenablespc    mov dword[cycpbl],0.noin2    dec byte[timinl2]    jnz .noin2b    inc byte[SPCRAM+0FFh]    mov al,[timincr2]    mov [timinl2],al    cmp byte[SPCRAM+0FFh],1    jne .noin2b    reenablespc    mov dword[cycpbl],0.noin2b    dec byte[timinl2]    jnz .noin2c    inc byte[SPCRAM+0FFh]    mov al,[timincr2]    mov [timinl2],al    cmp byte[SPCRAM+0FFh],1    jne .noin2c    reenablespc    mov dword[cycpbl],0.noin2c    dec byte[timinl2]    jnz .noin2d    inc byte[SPCRAM+0FFh]    mov al,[timincr2]    mov [timinl2],al    cmp byte[SPCRAM+0FFh],1    jne .noin2d    reenablespc    mov dword[cycpbl],0.noin2d.noin2d2;    inc dword[timer2upd];    cmp dword[timer2upd],31;    jne .nowrap;    mov dword[timer2upd],0;    jmp .again;.nowrap    inc dword[timer2upd]    cmp dword[timer2upd],60    jne .noanother    mov dword[timer2upd],0    jmp .another.noanother    ret; SPC Write Registers; DO NOT MODIFY DX OR ECX!NEWSYM SPCRegF0    mov [SPCRAM+0F0h],al    retNEWSYM SPCRegF1    cmp byte[disablespcclr],1    je .No23Clear    test al,10h    jz .No01Clear    mov byte[SPCRAM+0F4h],0    mov byte[SPCRAM+0F5h],0.No01Clear    test al,20h    jz .No23Clear    mov byte[SPCRAM+0F6h],0    mov byte[SPCRAM+0F7h],0.No23Clear    cmp byte[SPCSkipXtraROM],1    je near .AfterNoROM    test al,80h    jz .NoROM    push eax    push ebx    xor eax,eax.loopa    mov bl,[SPCROM+eax]    mov [SPCRAM+0FFC0h+eax],bl    inc eax    cmp eax,040h    jne .loopa    pop ebx    pop eax    jmp .AfterNoROM.NoROM    push eax    push ebx    xor eax,eax.loopb    mov bl,[spcextraram+eax]    mov [SPCRAM+0FFC0h+eax],bl    inc eax    cmp eax,040h    jne .loopb    pop ebx    pop eax.AfterNoROM    mov [SPCRAM+0F1h],al    and al,0Fh    mov [timeron],al    retNEWSYM SPCRegF2    mov [SPCRAM+0F2h],al    push eax    push ebx    xor eax,eax    mov al,[SPCRAM+0F2h]    mov bl,[DSPMem+eax]    mov [SPCRAM+0F3h],bl    pop ebx    pop eax    retNEWSYM SPCRegF3    push ebx    xor ebx,ebx    mov bl,[SPCRAM+0F2h]    and bl,07fh    call dword near [dspWptr+ebx*4]    pop ebx    mov [SPCRAM+ebx],al    retNEWSYM SPCRegF4    mov [reg1read],al    inc dword[spc700read]    retNEWSYM SPCRegF5    mov [reg2read],al    inc dword[spc700read]    retNEWSYM SPCRegF6    mov [reg3read],al    inc dword[spc700read]    retNEWSYM SPCRegF7    mov [reg4read],al    inc dword[spc700read]    retNEWSYM SPCRegF8    mov [SPCRAM+ebx],al    retNEWSYM SPCRegF9    mov [SPCRAM+ebx],al    retNEWSYM SPCRegFA    mov [timincr0],al    test byte[timinl0],0FFh    jne .nowrite    mov [timinl0],al.nowrite    mov [SPCRAM+ebx],al    retNEWSYM SPCRegFB    mov [timincr1],al    test byte[timinl1],0FFh    jne .nowrite    mov [timinl1],al.nowrite    mov [SPCRAM+ebx],al    retNEWSYM SPCRegFC    mov [timincr2],al    test byte[timinl2],0FFh    jne .nowrite    mov [timinl2],al.nowrite    mov [SPCRAM+ebx],al    retNEWSYM SPCRegFD    retNEWSYM SPCRegFE    retNEWSYM SPCRegFF    ret; SPC Read Registers; DO NOT MODIFY ANY REG!; return data true alNEWSYM RSPCRegF0    mov al,[SPCRAM+0f0h]    retNEWSYM RSPCRegF1    mov al,[SPCRAM+0f1h]    retNEWSYM RSPCRegF2    mov al,[SPCRAM+0f2h]    retNEWSYM RSPCRegF3    mov al,[SPCRAM+0f3h]    retNEWSYM RSPCRegF4    mov al,[SPCRAM+0f4h]    retNEWSYM RSPCRegF5    mov al,[SPCRAM+0f5h]    retNEWSYM RSPCRegF6    mov al,[SPCRAM+0f6h]    retNEWSYM RSPCRegF7    mov al,[SPCRAM+0f7h]    retNEWSYM RSPCRegF8    mov al,0 ;[SPCRAM+0f8h]    retNEWSYM RSPCRegF9    mov al,0 ;[SPCRAM+0f9h]    retNEWSYM RSPCRegFA    mov al,[SPCRAM+0fah]    retNEWSYM RSPCRegFB    mov al,[SPCRAM+0fbh]    retNEWSYM RSPCRegFC    mov al,[SPCRAM+0fch]    retNEWSYM RSPCRegFD    mov al,[SPCRAM+0fdh]    and al,0Fh    mov byte[SPCRAM+0fdh],0    mov byte[spcnumread],0    retNEWSYM RSPCRegFE    mov al,[SPCRAM+0feh]    and al,0Fh    mov byte[SPCRAM+0feh],0    mov byte[spcnumread],0    retNEWSYM RSPCRegFF    mov al,[SPCRAM+0ffh]    and al,0Fh    mov byte[SPCRAM+0ffh],0    mov byte[spcnumread],0    retSECTION .dataNEWSYM spcnumread, db 0SECTION .text%macro SPCSetFlagnzc 0  js .setsignflag  jz .setzeroflag  mov byte[spcNZ],1  jc .setcarryflag  and byte[spcP],0FEh  ret.setsignflag  mov byte[spcNZ],80h  jc .setcarryflag  and byte[spcP],0FEh  ret.setzeroflag  mov byte[spcNZ],0  jc .setcarryflag  and byte[spcP],0FEh  ret.setcarryflag  or byte[spcP],1  ret%endmacro%macro SPCSetFlagnzcnoret 0  js .setsignflag  jz .setzeroflag  mov byte[spcNZ],1  jc .setcarryflag  and byte[spcP],0FEh  jmp .skipflags.setsignflag  mov byte[spcNZ],80h  jc .setcarryflag  and byte[spcP],0FEh  jmp .skipflags.setzeroflag  mov byte[spcNZ],0  jc .setcarryflag  and byte[spcP],0FEh  jmp .skipflags.setcarryflag  or byte[spcP],1.skipflags%endmacro%macro SPCSetFlagnvhzc 0  lahf  js .setsignflag  jz .setzeroflag  mov byte[spcNZ],1  jo .setoverflowflag  and byte[spcP],0BFh  jmp .skipflags.setsignflag  mov byte[spcNZ],80h  jo .setoverflowflag  and byte[spcP],0BFh  jmp .skipflags.setzeroflag  mov byte[spcNZ],0  jo .setoverflowflag  and byte[spcP],0BFh  jmp .skipflags.setoverflowflag  or byte[spcP],40h.skipflags  and byte[spcP],0F6h  test ah,01h  jz .noCarry  or byte[spcP],1.noCarry  test ah,10h  jz .nohf  or byte[spcP],8.nohf  ret%endmacro%macro SPCSetFlagnvhzcnoret 0  lahf  js .setsignflag  jz .setzeroflag  mov byte[spcNZ],1  jo .setoverflowflag  and byte[spcP],0BFh  jmp .skipflags.setsignflag  mov byte[spcNZ],80h  jo .setoverflowflag  and byte[spcP],0BFh  jmp .skipflags.setzeroflag  mov byte[spcNZ],0  jo .setoverflowflag  and byte[spcP],0BFh  jmp .skipflags.setoverflowflag  or byte[spcP],40h.skipflags  and byte[spcP],0F6h  test ah,01h  jz .noCarry  or byte[spcP],1.noCarry  test ah,10h  jz .nohf  or byte[spcP],8.nohf%endmacro;************************************************; Misc Opcodes;************************************************NEWSYM Op00     ; NOP    retNEWSYM OpEF     ; SLEEP      standby SLEEP mode    .........    dec ebp    retNEWSYM OpFF     ; STOP       standby STOP mode     .........    inc dword[spc700read]    dec ebp    retNEWSYM Op9F     ; XCN A     A(7-4) <-> A(3-0)     N......Z.    ror byte[spcA],4    mov al,[spcA]    mov [spcNZ],al    ret;************************************************; Branch Stuff;************************************************NEWSYM Op10     ; BPL Branch on N=0    test byte[spcNZ],128    jz .branch    spcbrancherNEWSYM Op30     ; BMI Branch on N=1    test byte[spcNZ],128    jnz .branch    spcbrancherNEWSYM Op50     ; BVC Branch on V=0    test byte[spcP],64    jz .branch    spcbrancherNEWSYM Op70     ; BVS Branch on V=1    test byte[spcP],64    jnz .branch    spcbrancherNEWSYM Op90     ; BCC Branc on c=0    test byte[spcP],1    jz .branch    spcbrancherNEWSYM OpB0     ; BCS Branch on C=1    test byte[spcP],1    jnz .branch    spcbrancherNEWSYM OpD0     ; BNE branch on Z=0    test byte[spcNZ],255    jnz .branch    spcbrancherNEWSYM OpF0     ; BEQ Branch on Z=1    test byte[spcNZ],0FFh    jz .branch    spcbrancherNEWSYM Op2F     ; BRA rel    branch always            ...    movsx ebx,byte[ebp]    inc ebp    add ebp,ebx    ret;************************************************; Clear/Set Flag bits

⌨️ 快捷键说明

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