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


FxOpb05:     ; BRA    branch always      ; Verified.
   movsx eax,byte[ebp]
   mov cl,[ebp+1]
   inc ebp
   add ebp,eax
   call [FxTableb+ecx*4]
   ret

FxOpb06:     ; BGE    branch on greater or equals        ; Verified.
   movsx eax,byte[ebp]
   mov ebx,[SfxSignZero]
   shr ebx,15
   inc ebp
   xor bl,[SfxOverflow]
   mov cl,[ebp]
   test bl,01h
   jnz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb07:     ; BLT    branch on lesss than       ; Verified.
   movsx eax,byte[ebp]
   mov ebx,[SfxSignZero]
   shr ebx,15
   inc ebp
   xor bl,[SfxOverflow]
   mov cl,[ebp]
   test bl,01h
   jz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb08:     ; BNE    branch on not equal        ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],0FFFFh
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb09:     ; BEQ    branch on equal (z=1)      ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],0FFFFh
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb0A:     ; BPL    branch on plus     ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],088000h
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb0B:     ; BMI    branch on minus    ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],088000h
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb0C:     ; BCC    branch on carry clear      ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxCarry],01h
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb0D:     ; BCS    branch on carry set        ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxCarry],01h
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb0E:     ; BVC    branch on overflow clear   ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxOverflow],01h
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

FxOpb0F:     ; BVS    branch on overflow set     ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxOverflow],01h
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTableb+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTableb+ecx*4]
   ret

%macro TORNb 1   ; V
   FETCHPIPE
   test dword [SfxB],1
   jnz .VersionB
   mov edi, SfxR0+%1*4
   inc ebp                ; Increase program counter
   mov eax,ebp
   sub eax,[SfxCPB]
   mov dword[withr15sk],1
   mov [SfxR15],eax
   call [FxTableb+ecx*4]
   mov edi,SfxR0
   ret
.VersionB
   mov eax,[esi]            ; Read Source
   mov dword[withr15sk],1
   inc ebp                ; Increase program counter
   mov [SfxR0+%1*4],eax             ; Write
   CLRFLAGS
   ret
%endmacro

FxOpb10:     ; TO RN  set register n as destination register
   TORNb 0
FxOpb11:     ; TO RN  set register n as destination register
   TORNb 1   
FxOpb12:     ; TO RN  set register n as destination register
   TORNb 2   
FxOpb13:     ; TO RN  set register n as destination register
   TORNb 3   
FxOpb14:     ; TO RN  set register n as destination register
   TORNb 4   
FxOpb15:     ; TO RN  set register n as destination register
   TORNb 5   
FxOpb16:     ; TO RN  set register n as destination register
   TORNb 6   
FxOpb17:     ; TO RN  set register n as destination register
   TORNb 7   
FxOpb18:     ; TO RN  set register n as destination register
   TORNb 8   
FxOpb19:     ; TO RN  set register n as destination register
   TORNb 9   
FxOpb1A:     ; TO RN  set register n as destination register
   TORNb 10   
FxOpb1B:     ; TO RN  set register n as destination register
   TORNb 11   
FxOpb1C:     ; TO RN  set register n as destination register
   TORNb 12   
FxOpb1D:     ; TO RN  set register n as destination register
   TORNb 13
FxOpb1E:     ; TO RN  set register n as destination register
   FETCHPIPE
   test dword [SfxB],1
   jnz .VersionB
   mov edi,SfxR0+14*4
   inc ebp
   mov eax,ebp
   sub eax,[SfxCPB]
   mov dword[withr15sk],1
   mov [SfxR15],eax
   call [FxTableb+ecx*4]
   mov edi,SfxR0
   UpdateR14
   ret
.VersionB
   mov eax,[esi]            ; Read Source
   mov dword[withr15sk],1
   mov [SfxR0+14*4],eax             ; Write
   CLRFLAGS
   UpdateR14
   inc ebp                ; Increase program counter
   ret
FxOpb1F:     ; TO RN  set register n as destination register
   FETCHPIPE
   test dword [SfxB],1
   jnz .VersionB
   mov edi,SfxR0+15*4
   inc ebp
   mov eax,ebp
   sub eax,[SfxCPB]
   mov [SfxR15],eax
   call [FxTableb+ecx*4]
   mov ebp,[SfxCPB]
   mov dword[withr15sk],1
   add ebp,[SfxR15]
   mov edi,SfxR0
   ret
.VersionB
   mov eax,[esi]            ; Read Source
   mov ebp,[SfxCPB]
   mov dword[withr15sk],1
   add ebp,eax
   CLRFLAGS
   ret

FxOpb3D:     ; ALT1   set alt1 mode      ; Verified.
   FETCHPIPE
   mov dword [SfxB],0
   or ch,01h
   inc ebp
   mov eax,ebp
   sub eax,[SfxCPB]
   mov [SfxR15],eax
   call [FxTableb+ecx*4]
   xor ch,ch
   ret

FxOpb3E:     ; ALT2   set alt1 mode      ; Verified.
   FETCHPIPE
   mov dword [SfxB],0
   or ch,02h
   inc ebp
   mov eax,ebp
   sub eax,[SfxCPB]
   mov [SfxR15],eax
   call [FxTable+ecx*4]
   xor ch,ch
   ret

FxOpb3F:     ; ALT3   set alt3 mode      ; Verified.
   FETCHPIPE
   mov dword [SfxB],0
   or ch,03h
   inc ebp
   mov eax,ebp
   sub eax,[SfxCPB]
   mov [SfxR15],eax
   call [FxTable+ecx*4]
   xor ch,ch
   ret

%macro FROMRNb 1 ; V
   FETCHPIPE
   test dword [SfxB],1
   jnz .VersionB
   mov esi,SfxR0+%1*4
   inc ebp                ; Increase program counter
   call [FxTable+ecx*4]
   mov esi,SfxR0
   ret
.VersionB
   mov eax,[SfxR0+%1*4]             ; Read
   inc ebp
   mov [edi],eax        ; Write Destination
   mov [SfxSignZero],eax
   shr al,7
   mov byte[SfxOverflow],al
   CLRFLAGS
   ret
%endmacro

FxOpbB0:     ; FROM rn   set source register
   FROMRNb 0
FxOpbB1:     ; FROM rn   set source register
   FROMRNb 1
FxOpbB2:     ; FROM rn   set source register
   FROMRNb 2
FxOpbB3:     ; FROM rn   set source register
   FROMRNb 3
FxOpbB4:     ; FROM rn   set source register
   FROMRNb 4
FxOpbB5:     ; FROM rn   set source register
   FROMRNb 5
FxOpbB6:     ; FROM rn   set source register
   FROMRNb 6
FxOpbB7:     ; FROM rn   set source register
   FROMRNb 7
FxOpbB8:     ; FROM rn   set source register
   FROMRNb 8
FxOpbB9:     ; FROM rn   set source register
   FROMRNb 9
FxOpbBA:     ; FROM rn   set source register
   FROMRNb 10
FxOpbBB:     ; FROM rn   set source register
   FROMRNb 11
FxOpbBC:     ; FROM rn   set source register
   FROMRNb 12
FxOpbBD:     ; FROM rn   set source register
   FROMRNb 13
FxOpbBE:     ; FROM rn   set source register
   FROMRNb 14
FxOpbBF:     ; FROM rn   set source register
   test dword [SfxB],1
   jnz .VersionB
   mov esi,SfxR0+15*4
   inc ebp                ; Increase program counter
   mov eax,ebp
   sub eax,[SfxCPB]
   mov [SfxR15],eax
   call [FxTableb+ecx*4]
   mov esi,SfxR0
   ret
.VersionB
   FETCHPIPE
   mov eax,ebp
   sub eax,[SfxCPB]
   inc ebp
   mov [edi],eax        ; Write Destination
   mov [SfxSignZero],eax
   shr al,7
   mov byte[SfxOverflow],al
   CLRFLAGS
   ret

FxOpc05:     ; BRA    branch always      ; Verified.
   movsx eax,byte[ebp]
   mov cl,[ebp+1]
   inc ebp
   add ebp,eax
   call [FxTablec+ecx*4]
   ret

FxOpc06:     ; BGE    branch on greater or equals        ; Verified.
   movsx eax,byte[ebp]
   mov ebx,[SfxSignZero]
   shr ebx,15
   inc ebp
   xor bl,[SfxOverflow]
   mov cl,[ebp]
   test bl,01h
   jnz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc07:     ; BLT    branch on lesss than       ; Verified.
   movsx eax,byte[ebp]
   mov ebx,[SfxSignZero]
   shr ebx,15
   inc ebp
   xor bl,[SfxOverflow]
   mov cl,[ebp]
   test bl,01h
   jz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc08:     ; BNE    branch on not equal        ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],0FFFFh
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc09:     ; BEQ    branch on equal (z=1)      ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],0FFFFh
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc0A:     ; BPL    branch on plus     ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],088000h
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc0B:     ; BMI    branch on minus    ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test dword[SfxSignZero],088000h
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc0C:     ; BCC    branch on carry clear      ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxCarry],01h
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc0D:     ; BCS    branch on carry set        ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxCarry],01h
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc0E:     ; BVC    branch on overflow clear   ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxOverflow],01h
   mov cl,[ebp]
   jnz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

FxOpc0F:     ; BVS    branch on overflow set     ; Verified.
   movsx eax,byte[ebp]
   inc ebp
   test byte[SfxOverflow],01h
   mov cl,[ebp]
   jz .nojump
   add ebp,eax
   call [FxTablec+ecx*4]
   ret
.nojump
   inc ebp
   call [FxTablec+ecx*4]
   ret

%macro TORNc 1   ; V
   FETCHPIPE
   mov eax,[esi]            ; Read Source
   inc ebp                ; Increase program counter
   mov [SfxR0+%1*4],eax             ; Write
   CLRFLAGS
   ret
%endmacro

FxOpc10:     ; TO RN  set register n as destination register
   TORNc 0
FxOpc11:     ; TO RN  set register n as destination register
   TORNc 1   
FxOpc12:     ; TO RN  set register n as destination register
   TORNc 2   
FxOpc13:     ; TO RN  set register n as destination register
   TORNc 3   
FxOpc14:     ; TO RN  set register n as destination register
   TORNc 4   
FxOpc15:     ; TO RN  set register n as destination register
   TORNc 5   
FxOpc16:     ; TO RN  set register n as destination register
   TORNc 6   
FxOpc17:     ; TO RN  set register n as destination register
   TORNc 7   
FxOpc18:     ; TO RN  set register n as destination register
   TORNc 8   
FxOpc19:     ; TO RN  set register n as destination register
   TORNc 9   
FxOpc1A:     ; TO RN  set register n as destination register
   TORNc 10   
FxOpc1B:     ; TO RN  set register n as destination register
   TORNc 11   
FxOpc1C:     ; TO RN  set register n as destination register
   TORNc 12   
FxOpc1D:     ; TO RN  set register n as destination register
   TORNc 13
FxOpc1E:     ; TO RN  set register n as destination register
   FETCHPIPE
   mov eax,[esi]            ; Read Source
   mov [SfxR0+14*4],eax             ; Write
   CLRFLAGS
   UpdateR14
   inc ebp                ; Increase program counter
   ret
FxOpc1F:     ; TO RN  set register n as destination register
   FETCHPIPE
   mov eax,[esi]            ; Read Source
   mov ebp,[SfxCPB]
   mov [SfxR15],eax
   add ebp,eax
   CLRFLAGS
   ret

FxOpc3D:     ; ALT1   set alt1 mode      ; Verified.
   FETCHPIPE
   mov dword [SfxB],0
   or ch,01h
   inc ebp
   call [FxTablec+ecx*4]
   xor ch,ch
   ret

FxOpc3E:     ; ALT2   set alt1 mode      ; Verified.
   FETCHPIPE
   mov dword [SfxB],0
   or ch,02h
   inc ebp
   call [FxTablec+ecx*4]
   xor ch,ch
   ret

FxOpc3F:     ; ALT3   set alt3 mode      ; Verified.
   FETCHPIPE
   mov dword [SfxB],0
   or ch,03h
   inc ebp
   call [FxTablec+ecx*4]
   xor ch,ch
   ret

%macro FROMRNc 1 ; V
   FETCHPIPE
   mov eax,[SfxR0+%1*4]             ; Read
   inc ebp
   mov [edi],eax        ; Write Destination
   mov [SfxSignZero],eax
   shr al,7
   mov byte[SfxOverflow],al
   CLRFLAGS
   ret
%endmacro

FxOpcB0:     ; FROM rn   set source register
   FROMRNc 0
FxOpcB1:     ; FROM rn   set source register
   FROMRNc 1
FxOpcB2:     ; FROM rn   set source register
   FROMRNc 2
FxOpcB3:     ; FROM rn   set source register
   FROMRNc 3
FxOpcB4:     ; FROM rn   set source register
   FROMRNc 4
FxOpcB5:     ; FROM rn   set source register
   FROMRNc 5
FxOpcB6:     ; FROM rn   set source register
   FROMRNc 6
FxOpcB7:     ; FROM rn   set source register
   FROMRNc 7
FxOpcB8:     ; FROM rn   set source register
   FROMRNc 8
FxOpcB9:     ; FROM rn   set source register
   FROMRNc 9
FxOpcBA:     ; FROM rn   set source register
   FROMRNc 10
FxOpcBB:     ; FROM rn   set source register
   FROMRNc 11
FxOpcBC:     ; FROM rn   set source register
   FROMRNc 12
FxOpcBD:     ; FROM rn   set source register
   FROMRNc 13
FxOpcBE:     ; FROM rn   set source register
   FROMRNc 14
FxOpcBF:     ; FROM rn   set source register
   FETCHPIPE
   mov eax,ebp
   sub eax,[SfxCPB]
   inc ebp
   mov [edi],eax        ; Write Destination
   mov [SfxSignZero],eax
   shr al,7
   mov byte[SfxOverflow],al
   CLRFLAGS
   ret
