; Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
;
; Super FX assembler emulator code
; (c) Copyright 1998 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.
;

%macro AssembleSFXFlags 0
    and word[SfxSFR],8F60h
    test byte[SfxCarry],1
    jz .nosfxcarry
    or word[SfxSFR],04h
.nosfxcarry
    cmp word[SfxSignZero],0
    jne .nozero
    or word[SfxSFR],02h
.nozero
    test word[SfxSignZero],8000h
    jz .noneg
    or word[SfxSFR],08h
.noneg
    cmp byte[SfxOverflow],0
    je .noof
    or word[SfxSFR],10h
.noof
    cmp byte[SfxB],0
    je .bzero
    or word[SfxSFR],1000h
.bzero
%endmacro


initsfxregsr:
    setreg 3000h*4,reg3000r
    setreg 3001h*4,reg3001r
    setreg 3002h*4,reg3002r
    setreg 3003h*4,reg3003r
    setreg 3004h*4,reg3004r
    setreg 3005h*4,reg3005r
    setreg 3006h*4,reg3006r
    setreg 3007h*4,reg3007r
    setreg 3008h*4,reg3008r
    setreg 3009h*4,reg3009r
    setreg 300Ah*4,reg300Ar
    setreg 300Bh*4,reg300Br
    setreg 300Ch*4,reg300Cr
    setreg 300Dh*4,reg300Dr
    setreg 300Eh*4,reg300Er
    setreg 300Fh*4,reg300Fr
    setreg 3010h*4,reg3010r
    setreg 3011h*4,reg3011r
    setreg 3012h*4,reg3012r
    setreg 3013h*4,reg3013r
    setreg 3014h*4,reg3014r
    setreg 3015h*4,reg3015r
    setreg 3016h*4,reg3016r
    setreg 3017h*4,reg3017r
    setreg 3018h*4,reg3018r
    setreg 3019h*4,reg3019r
    setreg 301Ah*4,reg301Ar
    setreg 301Bh*4,reg301Br
    setreg 301Ch*4,reg301Cr
    setreg 301Dh*4,reg301Dr
    setreg 301Eh*4,reg301Er
    setreg 301Fh*4,reg301Fr
    setreg 3030h*4,reg3030r
    setreg 3031h*4,reg3031r
    setreg 3032h*4,reg3032r
    setreg 3033h*4,reg3033r
    setreg 3034h*4,reg3034r
    setreg 3035h*4,reg3035r
    setreg 3036h*4,reg3036r
    setreg 3037h*4,reg3037r
    setreg 3038h*4,reg3038r
    setreg 3039h*4,reg3039r
    setreg 303Ah*4,reg303Ar
    setreg 303Bh*4,reg303Br
    setreg 303Ch*4,reg303Cr
    setreg 303Dh*4,reg303Dr
    setreg 303Eh*4,reg303Er
    setreg 303Fh*4,reg303Fr
    ; set 3100-31FF to cacheregr
    mov edi,3100h*4
    add edi,[regptr]
    mov eax,cacheregr
    mov ecx,200h
.loop
    mov [edi],eax
    add edi,4
    dec ecx
    jnz .loop
    ret

initsfxregsw:
    setregw 3000h*4,reg3000w
    setregw 3001h*4,reg3001w
    setregw 3002h*4,reg3002w
    setregw 3003h*4,reg3003w
    setregw 3004h*4,reg3004w
    setregw 3005h*4,reg3005w
    setregw 3006h*4,reg3006w
    setregw 3007h*4,reg3007w
    setregw 3008h*4,reg3008w
    setregw 3009h*4,reg3009w
    setregw 300Ah*4,reg300Aw
    setregw 300Bh*4,reg300Bw
    setregw 300Ch*4,reg300Cw
    setregw 300Dh*4,reg300Dw
    setregw 300Eh*4,reg300Ew
    setregw 300Fh*4,reg300Fw
    setregw 3010h*4,reg3010w
    setregw 3011h*4,reg3011w
    setregw 3012h*4,reg3012w
    setregw 3013h*4,reg3013w
    setregw 3014h*4,reg3014w
    setregw 3015h*4,reg3015w
    setregw 3016h*4,reg3016w
    setregw 3017h*4,reg3017w
    setregw 3018h*4,reg3018w
    setregw 3019h*4,reg3019w
    setregw 301Ah*4,reg301Aw
    setregw 301Bh*4,reg301Bw
    setregw 301Ch*4,reg301Cw
    setregw 301Dh*4,reg301Dw
    setregw 301Eh*4,reg301Ew
    setregw 301Fh*4,reg301Fw
    setregw 3030h*4,reg3030w
    setregw 3031h*4,reg3031w
    setregw 3032h*4,reg3032w
    setregw 3033h*4,reg3033w
    setregw 3034h*4,reg3034w
    setregw 3035h*4,reg3035w
    setregw 3036h*4,reg3036w
    setregw 3037h*4,reg3037w
    setregw 3038h*4,reg3038w
    setregw 3039h*4,reg3039w
    setregw 303Ah*4,reg303Aw
    setregw 303Bh*4,reg303Bw
    setregw 303Ch*4,reg303Cw
    setregw 303Dh*4,reg303Dw
    setregw 303Eh*4,reg303Ew
    setregw 303Fh*4,reg303Fw
    ; set 3100-31FF to cacheregw
    mov edi,3100h*4
    add edi,[regptw]
    mov eax,cacheregw
    mov ecx,200h
.loop
    mov [edi],eax
    add edi,4
    dec ecx
    jnz .loop
    ret

cacheregr:
    or byte[cachewarning],1
    ret

cacheregw:
    or byte[cachewarning],2
    ret

cachewarning db 0

; SFX Registers

reg3000r:
    mov al,[SfxR0]
    ret
reg3001r:
    mov al,[SfxR0+1]
    ret
reg3002r:
    mov al,[SfxR1]
    ret
reg3003r:
    mov al,[SfxR1+1]
    ret
reg3004r:
    mov al,[SfxR2]
    ret
reg3005r:
    mov al,[SfxR2+1]
    ret
reg3006r:
    mov al,[SfxR3]
    ret
reg3007r:
    mov al,[SfxR3+1]
    ret
reg3008r:
    mov al,[SfxR4]
    ret
reg3009r:
    mov al,[SfxR4+1]
    ret
reg300Ar:
    mov al,[SfxR5]
    ret
reg300Br:
    mov al,[SfxR5+1]
    ret
reg300Cr:
    mov al,[SfxR6]
    ret
reg300Dr:
    mov al,[SfxR6+1]
    ret
reg300Er:
    mov al,[SfxR7]
    ret
reg300Fr:
    mov al,[SfxR7+1]
    ret
reg3010r:
    mov al,[SfxR8]
    ret
reg3011r:
    mov al,[SfxR8+1]
    ret
reg3012r:
    mov al,[SfxR9]
    ret
reg3013r:
    mov al,[SfxR9+1]
    ret
reg3014r:
    mov al,[SfxR10]
    ret
reg3015r:
    mov al,[SfxR10+1]
    ret
reg3016r:
    mov al,[SfxR11]
    ret
reg3017r:
    mov al,[SfxR11+1]
    ret
reg3018r:
    mov al,[SfxR12]
    ret
reg3019r:
    mov al,[SfxR12+1]
    ret
reg301Ar:
    mov al,[SfxR13]
    ret
reg301Br:
    mov al,[SfxR13+1]
    ret
reg301Cr:
    mov al,[SfxR14]
    ret
reg301Dr:
    mov al,[SfxR14+1]
    ret
reg301Er:
    mov al,[SfxR15]
    ret
reg301Fr:
    mov al,[SfxR15+1]
    ret

; Other SFX stuff

reg3030r:
    AssembleSFXFlags
    mov al,[SfxSFR]
    ret
reg3031r:
    mov al,[SfxSFR+1]
    and byte[SfxSFR+1],07Fh        ; clear IRQ flag
    ret
reg3032r:       ; Unused
    xor al,al
    ret
reg3033r:       ; BRAMR Backup Ram Read only on/off (bits 1-15 unused)
    mov al,[SfxBRAMR]
    ret
reg3034r:       ; PBR (Program Bank)
    mov al,[SfxPBR]
    ret
reg3035r:       ; Unused
    xor al,al
    ret
reg3036r:       ; ROMBR (Gamepak Rom Bank Register)
    mov al,[SfxROMBR]
    ret
reg3037r:       ; CFGR (Control Flags Register)
    mov al,[SfxCFGR]
    ret
reg3038r:       ; SCBR (Screen Bank Register)
    mov al,[SfxSCBR]
    ret
reg3039r:       ; CLSR (Clock Speed Register)
    mov al,[SfxCLSR]
    ret
reg303Ar:       ; SCMR (Screen Mode Register)
    mov al,[SfxSCMR]
    ret
reg303Br:       ; VCR (Version Code Register)
    mov al,20h
    ret
reg303Cr:       ; RAMBR (Ram bank register)
    mov al,[SfxRAMBR]
    ret
reg303Dr:       ; Unused
    xor al,al
    ret
reg303Er:       ; CBR (Cache Base Register), lower byte
    mov al,[SfxCBR]
    ret
reg303Fr:       ; CBR (Cache Base Register), upper byte
    mov al,[SfxCBR+1]
    ret

; SFX Write Registers

reg3000w:
    mov [SfxR0],al
    ret
reg3001w:
    mov [SfxR0+1],al
    ret
reg3002w:
    mov [SfxR1],al
    ret
reg3003w:
    mov [SfxR1+1],al
    ret
reg3004w:
    mov [SfxR2],al
    ret
reg3005w:
    mov [SfxR2+1],al
    ret
reg3006w:
    mov [SfxR3],al
    ret
reg3007w:
    mov [SfxR3+1],al
    ret
reg3008w:
    mov [SfxR4],al
    ret
reg3009w:
    mov [SfxR4+1],al
    ret
reg300Aw:
    mov [SfxR5],al
    ret
reg300Bw:
    mov [SfxR5+1],al
    ret
reg300Cw:
    mov [SfxR6],al
    ret
reg300Dw:
    mov [SfxR6+1],al
    ret
reg300Ew:
    mov [SfxR7],al
    ret
reg300Fw:
    mov [SfxR7+1],al
    ret
reg3010w:
    mov [SfxR8],al
    ret
reg3011w:
    mov [SfxR8+1],al
    ret       
reg3012w:
    mov [SfxR9],al
    ret
reg3013w:
    mov [SfxR9+1],al
    ret
reg3014w:
    mov [SfxR10],al
    ret
reg3015w:
    mov [SfxR10+1],al
    ret
reg3016w:
    mov [SfxR11],al
    ret
reg3017w:
    mov [SfxR11+1],al
    ret
reg3018w:
    mov [SfxR12],al
    ret
reg3019w:
    mov [SfxR12+1],al
    ret
reg301Aw:
    mov [SfxR13],al
    ret
reg301Bw:
    mov [SfxR13+1],al
    ret
reg301Cw:
    mov [SfxR14],al
    ret
reg301Dw:
    mov [SfxR14+1],al
    ret
reg301Ew:
    mov [SfxR15],al
    ret
reg301Fw:
    mov [SfxR15+1],al
    mov byte[debstop],1
    ; start execution
    push edx
    mov edx,[SfxPBR]
    mov edx,[SfxMemTable+edx*4]
    add edx,[SfxR15]
    mov dl,[edx]
    mov [SfxPIPE],dl
    pop edx
    inc word[SfxR15]
    or byte[SfxSFR],20h
;    call StartSFXret
    ret

; Other SFX stuff

reg3030w:
    mov [SfxSFR],al
    ; Disassemble Flags
    ret
reg3031w:
    mov [SfxSFR+1],al
    ret
reg3032w:       ; Unused
    ret
reg3033w:       ; BRAMR Backup Ram Read only on/off (bits 1-15 unused)
    and al,0FEh
    mov [SfxBRAMR],al
    ret
reg3034w:       ; PBR (Program Bank)
    mov [SfxPBR],al
    xor ebx,ebx
    mov bl,al
    mov ebx,[SfxMemTable+ebx*4]
    mov [SfxCPB],ebx
    ret
reg3035w:       ; Unused
    ret
reg3036w:       ; ROMBR (Gamepak Rom Bank Register)
    mov [SfxROMBR],al
    xor ebx,ebx
    mov bl,al
    mov ebx,[SfxMemTable+ebx*4]
    mov [SfxCROM],ebx
    ret
reg3037w:       ; CFGR (Control Flags Register)
    mov [SfxCFGR],al
    ret
reg3038w:       ; SCBR (Screen Bank Register)
    mov [SfxSCBR],al
    ret
reg3039w:       ; CLSR (Clock Speed Register)
    and al,0FEh
    mov [SfxCLSR],al
    ret
reg303Aw:       ; SCMR (Screen Mode Register)
    mov [SfxSCMR],al
    ret
reg303Bw:       ; VCR (Version Code Register)
    ret
reg303Cw:       ; RAMBR (Ram bank register)
    mov bl,[SfxnRamBanks]
    dec bl
    and al,bl
    mov ebx,[SfxnRamBanks]
    dec ebx
    and eax,ebx
    mov [SfxRAMBR],eax
    xor ebx,ebx
    mov bl,al
    shl ebx,16
    add ebx,[sfxramdata]
    mov dword [SfxRAMMem],ebx
    ret
reg303Dw:       ; Unused
    ret
reg303Ew:       ; CBR (Cache Base Register), lower byte
    mov [SfxCBR],al
    ret
reg303Fw:       ; CBR (Cache Base Register), upper byte
    mov [SfxCBR+1],al
    ret

sfxaccessbankr8:
    mov ebx,[sfxramdata]
    mov al,[ebx+ecx]
    xor ebx,ebx
    ret

sfxaccessbankw8:
    mov ebx,[sfxramdata]
    mov [ebx+ecx],al
    xor ebx,ebx
    ret

sfxaccessbankr16:
    mov ebx,[sfxramdata]
    mov ax,[ebx+ecx]
    xor ebx,ebx
    ret

sfxaccessbankw16:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx],ax
    xor ebx,ebx
    ret

sfxaccessbankr8b:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov al,[ebx+ecx+65536]
    xor ebx,ebx
    ret

sfxaccessbankw8b:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx+65536],al
    xor ebx,ebx
    ret

sfxaccessbankr16b:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov ax,[ebx+ecx+65536]
    xor ebx,ebx
    ret

sfxaccessbankw16b:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx+65536],ax
    xor ebx,ebx
    ret

sfxaccessbankr8c:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov al,[ebx+ecx+65536*2]
    xor ebx,ebx
    ret

sfxaccessbankw8c:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx+65536*2],al
    xor ebx,ebx
    ret

sfxaccessbankr16c:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov ax,[ebx+ecx+65536*2]
    xor ebx,ebx
    ret

sfxaccessbankw16c:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx+65536*2],ax
    xor ebx,ebx
    ret

sfxaccessbankr8d:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov al,[ebx+ecx+65536*3]
    xor ebx,ebx
    ret

sfxaccessbankw8d:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx+65536*3],al
    xor ebx,ebx
    ret

sfxaccessbankr16d:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov ax,[ebx+ecx+65536*3]
    xor ebx,ebx
    ret

sfxaccessbankw16d:
    mov byte[debstop],1
    mov ebx,[sfxramdata]
    mov [ebx+ecx+65536*3],ax
    xor ebx,ebx
    ret

