mirror of https://github.com/snes9xgit/snes9x.git
377 lines
8.2 KiB
NASM
377 lines
8.2 KiB
NASM
; Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
;
|
|
; Super FX assembler emulator code
|
|
; (c) Copyright 1998, 1999 zsKnight and _Demo_.
|
|
;
|
|
; Permission to use, copy, modify and distribute Snes9x in both binary and
|
|
; source form, for non-commercial purposes, is hereby granted without fee,
|
|
; providing that this license information and copyright notice appear with
|
|
; all copies and any derived work.
|
|
;
|
|
; This software is provided 'as-is', without any express or implied
|
|
; warranty. In no event shall the authors be held liable for any damages
|
|
; arising from the use of this software.
|
|
;
|
|
; Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
; seek permission of the copyright holders first. Commercial use includes
|
|
; charging money for Snes9x or software derived from Snes9x.
|
|
;
|
|
; The copyright holders request that bug fixes and improvements to the code
|
|
; should be forwarded to them so everyone can benefit from the modifications
|
|
; in future versions.
|
|
;
|
|
; Super NES and Super Nintendo Entertainment System are trademarks of
|
|
; Nintendo Co., Limited and its subsidiary companies.
|
|
;
|
|
; ZSNES SuperFX emulation code and wrappers
|
|
; (C) Copyright 1997-8 zsKnight and _Demo_
|
|
|
|
; Used with the kind permission of the copyright holders.
|
|
;
|
|
|
|
%include "macros.mac"
|
|
|
|
EXTSYM SfxR1,SfxR2,InitFxTables,SfxSFR,SfxSCMR,initsfxregsw,initsfxregsr
|
|
EXTSYM SfxPBR,NumberOfOpcodes,SfxCLSR,MainLoop,SfxCROM
|
|
EXTSYM SfxRomBuffer,SfxRAMMem,SfxLastRamAdr,SfxR0
|
|
EXTSYM PHnum2writesfxreg, SfxCPB, SfxROMBR, SfxRAMBR, SfxnRamBanks
|
|
EXTSYM SfxSignZero
|
|
|
|
[BITS 32]
|
|
SECTION .data
|
|
|
|
NEWSYM flagnz, dd 0
|
|
NEWSYM romdata, dd 0 ; rom data (4MB = 4194304)
|
|
|
|
NEWSYM regptr, dd 0 ; pointer to registers
|
|
NEWSYM regptw, dd 0 ; pointer to registers
|
|
NEWSYM regptra, times 49152 db 0
|
|
NEWSYM regptwa, times 49152 db 0
|
|
|
|
NEWSYM debstop, db 0
|
|
NEWSYM sfxramdata, dd 0 ; SuperFX Ram Data
|
|
NEWSYM sfxplottable, dd 0
|
|
NEWSYM FxTable, times 256 dd 0
|
|
NEWSYM FxTableA1, times 256 dd 0
|
|
NEWSYM FxTableA2, times 256 dd 0
|
|
NEWSYM FxTableA3, times 256 dd 0
|
|
NEWSYM FxTableb, times 256 dd 0
|
|
NEWSYM FxTablebA1, times 256 dd 0
|
|
NEWSYM FxTablebA2, times 256 dd 0
|
|
NEWSYM FxTablebA3, times 256 dd 0
|
|
NEWSYM FxTablec, times 256 dd 0
|
|
NEWSYM FxTablecA1, times 256 dd 0
|
|
NEWSYM FxTablecA2, times 256 dd 0
|
|
NEWSYM FxTablecA3, times 256 dd 0
|
|
NEWSYM FxTabled, times 256 dd 0
|
|
NEWSYM FxTabledA1, times 256 dd 0
|
|
NEWSYM FxTabledA2, times 256 dd 0
|
|
NEWSYM FxTabledA3, times 256 dd 0
|
|
NEWSYM SfxMemTable, times 256 dd 0
|
|
NEWSYM fxxand, times 256 dd 0
|
|
NEWSYM fxbit01, times 256 dd 0
|
|
NEWSYM fxbit23, times 256 dd 0
|
|
NEWSYM fxbit45, times 256 dd 0
|
|
NEWSYM fxbit67, times 256 dd 0
|
|
NEWSYM PLOTJmpa, times 64 dd 0
|
|
NEWSYM PLOTJmpb, times 64 dd 0
|
|
|
|
NEWSYM NumberOfOpcodes2, dd 350
|
|
NEWSYM SFXCounter, dd 0
|
|
NEWSYM SfxAC, dd 0
|
|
|
|
;%INCLUDE "fxtable.asm"
|
|
;%INCLUDE "sfxproc.asm"
|
|
;%INCLUDE "fxemu2.asm"
|
|
;%INCLUDE "fxemu2b.asm"
|
|
;%INCLUDE "fxemu2c.asm"
|
|
|
|
;
|
|
; Snes9x wrapper functions for the zsnes SuperFX code
|
|
; (C) Copyright 1998 Gary Henderson
|
|
|
|
SECTION .data
|
|
|
|
EXTSYM SRAM,ROM,RegRAM,SFXPlotTable
|
|
|
|
SECTION .text
|
|
|
|
NEWSYM StartSFX
|
|
NEWSYM StartSFXret
|
|
jmp S9xSuperFXExec
|
|
|
|
NEWSYM S9xResetSuperFX
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
|
|
mov dword[SfxR1],0
|
|
mov dword[SfxR2],0
|
|
mov dword[SfxSignZero],1 ; clear z flag
|
|
|
|
mov eax,dword[SRAM]
|
|
mov dword[sfxramdata],eax
|
|
mov eax,dword[ROM]
|
|
mov dword[romdata],eax
|
|
mov eax,dword[SFXPlotTable]
|
|
mov dword[sfxplottable],eax
|
|
|
|
call InitFxTables
|
|
|
|
mov dword[SfxSFR],0
|
|
mov byte[SfxSCMR],0
|
|
mov dword[regptr],regptra
|
|
sub dword[regptr],8000h ; Since register address starts @ 2000h
|
|
mov dword[regptw],regptwa
|
|
sub dword[regptw],8000h ; Since register address starts @ 2000h
|
|
call initsfxregsw
|
|
call initsfxregsr
|
|
|
|
NEWSYM preparesfx
|
|
mov byte[SFXCounter],0
|
|
mov esi,[romdata]
|
|
add esi,07FC0h
|
|
cmp dword[esi],'FX S'
|
|
je .yessfxcounter
|
|
cmp dword[esi],'Stun'
|
|
jne .nosfxcounter
|
|
.yessfxcounter
|
|
mov byte[SFXCounter],1
|
|
.nosfxcounter
|
|
|
|
; make table
|
|
mov byte[SfxAC],0
|
|
mov eax,[romdata]
|
|
cmp dword[eax+02B80h],0AB6CAB6Ch
|
|
jne .noac
|
|
mov byte[SfxAC],1
|
|
.noac
|
|
call UpdateSFX
|
|
|
|
pop ebp
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
|
|
NEWSYM S9xSuperFXWriteReg
|
|
mov eax,dword[esp+4]
|
|
mov ecx,dword[esp+8]
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
test dword[regptwa+ecx*4-8000h], ~0
|
|
jz .skipwrite
|
|
call dword[regptwa+ecx*4-8000h]
|
|
.skipwrite:
|
|
pop ebp
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
|
|
NEWSYM S9xSuperFXReadReg
|
|
mov ecx,dword[esp+4]
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
test dword[regptra+ecx*4-8000h], ~0
|
|
jz .skipread
|
|
call dword[regptra+ecx*4-8000h]
|
|
.skipread:
|
|
pop ebp
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
and eax, 255
|
|
endfx:
|
|
ret
|
|
|
|
EXTSYM SCBRrel,SfxSCBR,SfxCOLR,SfxPOR
|
|
EXTSYM sfx128lineloc,sfx160lineloc,sfx192lineloc,sfxobjlineloc,sfxclineloc
|
|
EXTSYM fxbit01pcal,fxbit23pcal,fxbit45pcal,fxbit67pcal
|
|
|
|
NEWSYM S9xSuperFXExec
|
|
test byte[SfxSFR],20h
|
|
jz endfx
|
|
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
|
|
xor ebx,ebx
|
|
mov bl,[SfxPBR]
|
|
mov al,[SfxSCMR]
|
|
and bl,7Fh
|
|
cmp bl,70h
|
|
jae .ram
|
|
test al,10h
|
|
jz .noaccess
|
|
jmp .noram
|
|
.ram
|
|
test al,08h
|
|
jz .noaccess
|
|
.noram
|
|
mov eax,[NumberOfOpcodes2]
|
|
mov [NumberOfOpcodes],eax
|
|
call MainLoop
|
|
.noaccess
|
|
pop ebp
|
|
pop edi
|
|
pop esi
|
|
pop edx
|
|
ret
|
|
|
|
NEWSYM S9xSuperFXPreSaveState
|
|
mov ecx,dword[SfxCROM]
|
|
sub dword[SfxRomBuffer],ecx
|
|
mov ecx,dword[SfxRAMMem]
|
|
sub dword[SfxLastRamAdr],ecx
|
|
; Copy num2writesfxreg bytes from SfxR0 to a free area in RegRAM.
|
|
push ebx
|
|
mov ecx,SfxR0
|
|
mov edx,dword[RegRAM]
|
|
add edx,7000h
|
|
mov ebx,[PHnum2writesfxreg]
|
|
.loop
|
|
mov al,[ecx]
|
|
mov [edx],al
|
|
inc ecx
|
|
inc edx
|
|
dec ebx
|
|
jnz .loop
|
|
pop ebx
|
|
mov ecx,dword[SfxCROM]
|
|
add dword[SfxRomBuffer],ecx
|
|
mov ecx,dword[SfxRAMMem]
|
|
add dword[SfxLastRamAdr],ecx
|
|
ret
|
|
|
|
NEWSYM S9xSuperFXPostSaveState
|
|
ret
|
|
|
|
NEWSYM S9xSuperFXPostLoadState
|
|
; Copy num2writesfxreg bytes from a free area in RegRAM to SfxR0
|
|
push ebx
|
|
mov ecx,SfxR0
|
|
mov edx,dword[RegRAM]
|
|
add edx,7000h
|
|
mov ebx,[PHnum2writesfxreg]
|
|
.loop
|
|
mov al,[edx]
|
|
mov [ecx],al
|
|
inc ecx
|
|
inc edx
|
|
dec ebx
|
|
jnz .loop
|
|
pop ebx
|
|
xor ecx,ecx
|
|
mov cl,byte[SfxPBR]
|
|
mov ecx,dword[SfxMemTable+ecx*4]
|
|
mov dword[SfxCPB],ecx
|
|
|
|
xor ecx,ecx
|
|
mov cl,byte[SfxROMBR]
|
|
mov ecx,dword[SfxMemTable+ecx*4]
|
|
mov dword[SfxCROM],ecx
|
|
|
|
xor ecx,ecx
|
|
mov cl,byte[SfxRAMBR]
|
|
shl ecx,16
|
|
add ecx,dword[sfxramdata]
|
|
mov dword [SfxRAMMem],ecx
|
|
|
|
mov ecx,dword[SfxCROM]
|
|
add dword[SfxRomBuffer],ecx
|
|
mov ecx,dword[SfxRAMMem]
|
|
add dword[SfxLastRamAdr],ecx
|
|
; Fix for mystery zeroing of SfxnRamBanks, allowing junk RAMBR values to be
|
|
; set in turn causing a crash when the code tries to access the junk RAM bank.
|
|
mov dword [SfxnRamBanks], 4
|
|
call UpdateSFX
|
|
ret
|
|
|
|
NEWSYM UpdatePORSCMR
|
|
push ebx
|
|
push eax
|
|
test byte[SfxPOR],10h
|
|
jnz .objmode
|
|
mov al,[SfxSCMR]
|
|
and al,00100100b ; 4 + 32
|
|
cmp al,4
|
|
je .lines160
|
|
cmp al,32
|
|
je .lines192
|
|
cmp al,36
|
|
je .objmode
|
|
mov eax,[sfx128lineloc]
|
|
jmp .donelines
|
|
.lines160
|
|
mov eax,[sfx160lineloc]
|
|
jmp .donelines
|
|
.lines192
|
|
mov eax,[sfx192lineloc]
|
|
jmp .donelines
|
|
.objmode
|
|
mov eax,[sfxobjlineloc]
|
|
.donelines
|
|
mov [sfxclineloc],eax
|
|
|
|
mov al,[SfxSCMR]
|
|
and eax,00000011b
|
|
mov bl,[SfxPOR]
|
|
and bl,0Fh
|
|
shl bl,2
|
|
or al,bl
|
|
mov ebx,[PLOTJmpb+eax*4]
|
|
mov eax,[PLOTJmpa+eax*4]
|
|
mov dword [FxTable+4Ch*4],eax
|
|
mov dword [FxTableb+4Ch*4],eax
|
|
mov dword [FxTablec+4Ch*4],eax
|
|
mov dword [FxTabled+4Ch*4],ebx
|
|
pop eax
|
|
pop ebx
|
|
ret
|
|
|
|
NEWSYM UpdateSCBRCOLR
|
|
push eax
|
|
push ebx
|
|
mov ebx,[SfxSCBR]
|
|
shl ebx,10
|
|
add ebx,[sfxramdata]
|
|
mov [SCBRrel],ebx
|
|
mov eax,[SfxCOLR]
|
|
mov ebx,[fxbit01+eax*4]
|
|
mov [fxbit01pcal],ebx
|
|
mov ebx,[fxbit23+eax*4]
|
|
mov [fxbit23pcal],ebx
|
|
mov ebx,[fxbit45+eax*4]
|
|
mov [fxbit45pcal],ebx
|
|
mov ebx,[fxbit67+eax*4]
|
|
mov [fxbit67pcal],ebx
|
|
pop ebx
|
|
pop eax
|
|
ret
|
|
|
|
NEWSYM UpdateCLSR
|
|
mov dword [NumberOfOpcodes2],350 ; 0FFFFFFFh;350
|
|
test byte[SfxCLSR],01h
|
|
jz .nohighsfx
|
|
mov dword [NumberOfOpcodes2],700 ;700
|
|
.nohighsfx
|
|
cmp byte[SFXCounter],1
|
|
je .noyi
|
|
mov dword [NumberOfOpcodes2],0FFFFFFFh
|
|
.noyi
|
|
ret
|
|
|
|
NEWSYM UpdateSFX
|
|
call UpdatePORSCMR
|
|
call UpdatePORSCMR
|
|
call UpdateCLSR
|
|
ret
|