snes9x/i386/zsnes.asm

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