/*
 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
 *
 * (c) Copyright 1996, 1997, 1998 Gary Henderson (gary@daniver.demon.co.uk) and
 *                                Jerremy Koot (jkoot@euronet.nl)
 *
 * Super FX C emulator code 
 * (c) Copyright 1997, 1998 Lestat (lstat@hotmail.com) and
 *                          Gary Henderson.
 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
 *
 * DSP1 emulator code (c) Copyright 1998 Lestat and Gary Henderson.
 * DOS port code contains the works of other authors. See headers in
 * individual files.
 *
 * 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 APUS9xPackStatus K
    movb ApuP, %dl
    andb $~(Zero | Negative | Carry | Overflow), %dl
    orb APU_Carry, %dl
    movb APU_Zero, %al
    andb $0x80, %al
    orb %al, %dl
    movb APU_Overflow, %al
    salb $6, %al
    orb %al, %dl
    movb APU_Zero, %al
    orb %al, %al
    setz %al
    salb $1, %al
    orb %al, %dl
    movb %dl, ApuP
.endm

.macro APUS9xUnpackStatus K
.endm

.macro Absolute K
	movw (APUPC), %dx
	addl $2, APUPC
	andl $0xffff, %edx
.endm

.macro Direct K
	movb (APUPC), %dl
	incl APUPC
	andl $0xff, %edx
.endm

.macro Immediate8 K
	movb (APUPC), %al
	incl APUPC
.endm

.macro IndirectX K
	movb ApuX, %dl
	andl $0xff, %edx
.endm

.macro IndexedXIndirect K
	xorl %eax, %eax
	xorl %edx, %edx
	movb ApuX, %al
	movl APUDirectPage, %ecx
	addb (APUPC), %al
	movw (%ecx, %eax), %dx
	incl APUPC
.endm

.macro DirectX K
        movb (APUPC), %dl
	addb ApuX, %dl
	andl $0xff, %edx
	incl APUPC
.endm

.macro AbsoluteX K
	movb ApuX, %dl
	andl $0xff, %edx
	addw (APUPC), %dx
	addl $2, APUPC
.endm	

.macro AbsoluteY K
	movb ApuY, %dl
	andl $0xff, %edx
	addw (APUPC), %dx
	addl $2, APUPC
.endm

.macro IndirectIndexedY K
	xorl %edx, %edx
	xorl %eax, %eax
	movl APUDirectPage, %ecx
	movb ApuY, %dl
	movb (APUPC), %al
	addw (%ecx, %eax), %dx
	incl APUPC
.endm

.macro MemBit K
	xorl %ecx, %ecx
	movw (APUPC), %dx
	movb 1(APUPC), %cl
	shrb $5, %cl
	andl $0x1fff, %edx
	addl $2, APUPC
.endm

.macro ApuPushWord
	movb ApuS, %cl
	movl APURAM, %edx
	andl $0xff, %ecx
	movw %ax,0xff(%edx, %ecx)
	subl $2, %ecx
	movb %cl, ApuS
.endm

.macro ApuPushByte
	movb ApuS, %cl
	movl APURAM, %edx
	andl $0xff, %ecx
	movb %al,0x100(%edx, %ecx)
	decb %cl
	movb %cl, ApuS
.endm

.macro Tcall N
	movl APUPC, %eax
	subl APURAM, %eax
	ApuPushWord
	movw APUExtraRAM + ((15 - \N) << 1), %cx
	movl APURAM, APUPC
	andl $0xffff, %ecx
	addl %ecx, APUPC
	ret
.endm	

.macro Set K
	Direct SET\K
	pushl %edx
	call S9xAPUGetByteZ
	orb $(1 << \K), %al
	popl %edx
	call S9xAPUSetByteZ
	ret
.endm

.macro Clr K
	Direct CLR\K
	pushl %edx
	call S9xAPUGetByteZ
	andb $~(1 << \K), %al
	popl %edx
	call S9xAPUSetByteZ
	ret
.endm

.macro BBS K
	movb (APUPC), %dl
	andl $0xff, %edx
	call S9xAPUGetByteZ
	andb $(1 << \K), %al
	jz .BBS\K
	movsbl 1(APUPC), %eax
	addl $2, APUPC
	addl %eax, APUPC
	ret
.BBS\K:
	addl $2, APUPC
	ret
.endm	

.macro BBC K
	movb (APUPC), %dl
	andl $0xff, %edx
	call S9xAPUGetByteZ
	andb $(1 << \K), %al
	jnz .BBC\K
	movsbl 1(APUPC), %eax
	addl $2, APUPC
	addl %eax, APUPC
	ret
.BBC\K:
	addl $2, APUPC
	ret
.endm	

.macro ORA K
	orb ApuA, %al
	movb %al, ApuA
	movb %al, APU_Zero
	movb %al, APU_Negative
	ret
.endm
