;
;	framw65a.s
;
;	P/ECE W65C02 Emulator
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2005 Naoyuki Sawa
;
;	* Sun Apr 10 06:09:00 JST 2005 Naoyuki Sawa
;	- 作成開始。
;
#include "clipw65a.h"

/* W65C02_TRACEシンボルを定義すると、トレース出力を行います。 */
//#define W65C02_TRACE

;****************************************************************************
;	
;****************************************************************************

; 高速化のため、W65C02構造体を高速RAMに配置します。
; 高速RAMへ配置するために、.codeセクションとします。
	.code
	.align	2
	.global	w65c02
w65c02:
	.space	SIZEOF_W65C02

;****************************************************************************
;	
;****************************************************************************

	.code
	.align 1

;****************************************************************************
;	
;****************************************************************************

; 実行コンテキストへ入ります。
; [in]
;	ありません。
; [out]
;	規定のレジスタを設定します。
; [use]
;	規定のレジスタを設定すること以外は、全レジスタを保存します。
; [note]
;	* 実行コンテキスト外からのみ呼び出し可能です。
;	  このルーチンを呼び出すと、実行コンテキストへ入ります。
;
	.global	w65c02_enter
w65c02_enter:
	xld.w	%CPU  , w65c02
	xld.ub	%A    , [%CPU+_A_    ]
	xld.ub	%Y    , [%CPU+_Y_    ]
	xld.ub	%X    , [%CPU+_X_    ]
	xld.uh	%NZ   , [%CPU+_NZ_   ]
	xld.uh	%PC   , [%CPU+_PC_   ]
	xld.ub	%S    , [%CPU+_S_    ]
	xld.w	%CYCLE, [%CPU+_CYCLE_]
	ret

; 実行コンテキストを抜けます。
; [in]
;	規定のレジスタが設定されていること。
; [out]
;	ありません。
; [use]
;	全レジスタを保存します。
; [note]
;	* 実行コンテキスト内からのみ呼び出し可能です。
;	  このルーチンを呼び出すと、実行コンテキストを抜けます。
;
	.global	w65c02_leave
w65c02_leave:
	xld.b	[%CPU+_A_    ], %A
	xld.b	[%CPU+_Y_    ], %Y
	xld.b	[%CPU+_X_    ], %X
	xld.h	[%CPU+_NZ_   ], %NZ
	xld.h	[%CPU+_PC_   ], %PC
	xld.b	[%CPU+_S_    ], %S
	xld.w	[%CPU+_CYCLE_], %CYCLE
	ret

;****************************************************************************
;	実行コンテキスト外から利用する関数
;****************************************************************************

	.global	w65c02_run
w65c02_run:
	pushn	%r3
	;
	xld.w	[w65c02+_CYCLE_], %r12		; 必要!!
	xcall	w65c02_enter			; 実行コンテキストへ入ります。
	;
	xbtst	[%CPU+WI], WAI_BIT		; 既にWAI中ならば、残り実行サイクル数を0にして、すぐにループを抜けます。
	jreq	2				; (w65c02.cycle=0で関数を抜けること。必須!!)
	ld.w	%CYCLE, 0			; (skip?)
	;
	xjp	w65c02_run_LOOP			; 実行サイクル数≦0が指定された場合のために、まず条件判定から。
w65c02_run_DO:
;----------------------------------------------------------------------------
#ifdef W65C02_TRACE
	; トレースデバッグを行う場合は、このブロックを有効にしてください。
	; その際、w65c02_trace()は、アプリケーションにて定義してください。
	; w65c02_trace()は、ライブラリ内では定義していません。
	xcall  w65c02_leave
	xcall  w65c02_trace
	xcall  w65c02_enter
#endif /*W65C02_TRACE*/
;----------------------------------------------------------------------------
	xcall.d	w65c02_read			; %data = OpCode = [PC]
	ld.w	%addr, %PC			; *delay*
	add	%PC, 1				; PC++
	xsll	%data, 4			; %pseq = &w65c02seq[OpCode].cycle
	ext	w65c02seq+3@ah
	ext	w65c02seq+3@al
	add	%pseq, %data
	ld.ub	%t0, [%pseq]+			; %t0   = 消費サイクル数
	ld.w	%t1, [%pseq]+			; %t1   = Action or Operation
	call.d	%t1
	sub	%CYCLE, %t0			; 残り実行サイクル数 -= 消費サイクル数 *delay*
w65c02_run_LOOP:
	xcmp	%CYCLE, 0			; 残り実行サイクル数が0以下になるまで繰り返します。
	xjrgt	w65c02_run_DO
	;
	xcall	w65c02_leave			; 実行コンテキストを抜けます。
	;
	popn	%r3
	ret

;****************************************************************************
;	実行コンテキスト内から利用する関数
;****************************************************************************

	.global	w65c02_push
w65c02_push:
	pushn	%addr				; 必要!!
	xoor	%addr, %S, 0x100		; %addr = $100|S
	xcall.d	w65c02_write			; [%addr] = %data
	sub	%S, 1				; S-- ($ffffffff,$00..$fe) *delay*
	popn	%addr				; 必要!!
	ret.d
	ld.ub	%S, %S				;     (      $ff,$00..$fe) *delay*

	.global	w65c02_pull
w65c02_pull:
	pushn	%addr				; 必要!!
	xadd	%S, %S, 1			; S++ ($01..$ff,$100)
	xoor	%addr, %S, 0x100		; %addr = $100|S
	xcall	w65c02_read			; %data = [%addr]
	popn	%addr				; 必要!!
	ret.d
	ld.ub	%S, %S				;     ($01..$ff, $00) *delay*

;****************************************************************************
;	Action
;****************************************************************************

	.global	w65c02_acc
w65c02_acc:
	ld.w	%t0, [%pseq]			; %t0   = Operation
	call.d	%t0				; %data = Operation(data)
	ld.w	%data, %A			; %data = A			*delay*
	ret.d
	ld.w	%A, %data			; %A    = data			*delay*

	.global	w65c02_imm
w65c02_imm:
	xcall.d	w65c02_read			; %data = imm = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	ld.w	%t0, [%pseq]			; %t0   = Operation
	jp	%t0				;         Operation(data)

	.global	w65c02_r
w65c02_r:
	ld.w	%t0, [%pseq]+			; %t0   = AddressMode
	call	%t0				; %addr = AddressMode()
	xcall	w65c02_read			; %data = [addr]
	ld.w	%t0, [%pseq]			; %t0   = Operation
	jp	%t0				;         Operation(data)

	.global	w65c02_w
w65c02_w:
	ld.w	%t0, [%pseq]+			; %t0    = AddressMode
	call	%t0				; %addr  = AddressMode()
	ld.w	%t0, [%pseq]			; %t0    = Operation
	call	%t0				; %data  = Operation()
	xjp	w65c02_write			; [addr] = data

	.global	w65c02_rw
w65c02_rw:
	ld.w	%t0, [%pseq]+			; %t0    = AddressMode
	call	%t0				; %addr  = AddressMode()
	xcall	w65c02_read			; %data  = [addr]
	ld.w	%t0, [%pseq]			; %t0    = Operation
	call	%t0				; %data  = Operation(data)
	xjp	w65c02_write			; [addr] = data

	.global	w65c02_bbr
	.global	w65c02_beq
w65c02_bbr:
	xcall	w65c02_zp			; %addr   =  zp
	xcall	w65c02_read			; %data   = [zp]
w65c02_beq:
	xld.w	%t0, [%pseq]			; %t0     = Operation
	call	%t0				; %psr(Z) = Operation()
	xjreq	w65c02_bcond			; if Z then branch taken
	ret.d
	add	%PC, 1				; Skip rel			*delay*

	.global	w65c02_bbs
	.global	w65c02_bne
w65c02_bbs:
	xcall	w65c02_zp			; %addr   =  zp
	xcall	w65c02_read			; %data   = [zp]
w65c02_bne:
	xld.w	%t0, [%pseq]			; %t0     = Operation
	call	%t0				; %psr(Z) = Operation()
	xjrne	w65c02_bcond			; if !Z then branch taken
	ret.d
	add	%PC, 1				; Skip rel			*delay*

	.global	w65c02_bcond
	.global	w65c02_bra
w65c02_bcond:
	sub	%CYCLE, 1			; More 1 cycle
w65c02_bra:
	xcall.d	w65c02_read			; %data = rel = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	ld.b	%data, %data			; %data =   ±rel
	add	%PC, %data			; %PC   = PC±rel
	ret.d
	ld.uh	%PC, %PC			; ($0000..$FFFF)		*delay*

	.global	w65c02_jmp
w65c02_jmp:
	ld.w	%t0, [%pseq]			; %t0   = AddressMode
	call	%t0				; %addr = AddressMode()
	ret.d
	ld.w	%PC, %addr			; %PC   = addr			*delay*

	.global	w65c02_jsr
w65c02_jsr:
	ld.w	%t0, [%pseq]			; %t0   = AddressMode
	call	%t0				; %addr = AddressMode()
	sub	%PC, 1				; PC-- (仕様)
	ld.w	%data, %PC
	xcall.d	w65c02_push			; Push HI(PC)
	srl	%data, 8			;				*delay*
	xcall.d	w65c02_push			; Push LO(PC)
	ld.ub	%data, %PC			;				*delay*
	ret.d
	ld.w	%PC, %addr			; %PC   = addr			*delay*

;****************************************************************************
;	AddressMode
;****************************************************************************

	.global	w65c02_zp
w65c02_zp:
	xcall.d	w65c02_read			; %data = zp = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	ret.d
	ld.w	%addr, %data			; %addr = zp			*delay*

	.global	w65c02_zp_x
w65c02_zp_x:
	xcall.d	w65c02_read			; %data = zp = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	add	%data, %X			; %data = zp+X
	ret.d
	ld.ub	%addr, %data			; %addr = zp+X ($00..$FF)	*delay*

	.global	w65c02_zp_y
w65c02_zp_y:
	xcall.d	w65c02_read			; %data = zp = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	add	%data, %Y			; %data = zp+Y
	ret.d
	ld.ub	%addr, %data			; %addr = zp+Y ($00..$FF)	*delay*

	.global	w65c02_a
w65c02_a:
	xcall.d	w65c02_read			; %data = [PC+0]
	ld.w	%addr, %PC			; %addr =  PC+0			*delay*
	ld.w	%s0, %data			; %s0   = [PC+0]
	xcall.d	w65c02_read			; %data =        [PC+1]
	add	%addr, 1			; %addr =         PC+1		*delay*
	xsll	%data, 8			; %data =        [PC+1]<<8
	or	%s0, %data			; %s0   = [PC+0]|[PC+1]<<8
	add	%PC, 2				; PC+=2
	ret.d
	ld.w	%addr, %s0			; %addr = a			*delay*

	.global	w65c02_a_x
w65c02_a_x:
	xcall.d	w65c02_read			; %data = [PC+0]
	ld.w	%addr, %PC			; %addr =  PC+0			*delay*
	ld.w	%s0, %data			; %s0   = [PC+0]
	xcall.d	w65c02_read			; %data =        [PC+1]
	add	%addr, 1			; %addr =         PC+1		*delay*
	xsll	%data, 8			; %data =        [PC+1]<<8
	or	%s0, %data			; %s0   = [PC+0]|[PC+1]<<8
	add	%PC, 2				; PC+=2
	add	%s0, %X				; %s0   = a+X
	ret.d
	ld.uh	%addr, %s0			; %addr = a+X ($0000..$FFFF)	*delay*

	.global	w65c02_a_y
w65c02_a_y:
	xcall.d	w65c02_read			; %data = [PC+0]
	ld.w	%addr, %PC			; %addr =  PC+0			*delay*
	ld.w	%s0, %data			; %s0   = [PC+0]
	xcall.d	w65c02_read			; %data =        [PC+1]
	add	%addr, 1			; %addr =         PC+1		*delay*
	xsll	%data, 8			; %data =        [PC+1]<<8
	or	%s0, %data			; %s0   = [PC+0]|[PC+1]<<8
	add	%PC, 2				; PC+=2
	add	%s0, %Y				; %s0   = a+Y
	ret.d
	ld.uh	%addr, %s0			; %addr = a+Y ($0000..$FFFF)	*delay*

	.global	w65c02_IzpI
w65c02_IzpI:
	xcall.d	w65c02_read			; %data =  zp = [PC]
	ld.w	%addr, %PC			; *delay*
	add	%PC, 1				; PC++
	xcall.d	w65c02_read			; %data = [zp+0]
	ld.w	%addr, %data			; %addr =  zp+0			*delay*
	ld.w	%s0, %data			; %s0   = [zp+0]
	xcall.d	w65c02_read			; %data =        [zp+1]
	add	%addr, 1			; %addr =         zp+1		*delay*
	xsll	%data, 8			; %data =        [zp+1]<<8
	or	%s0, %data			; %s0   = [zp+0]|[zp+1]<<8
	ret.d
	ld.w	%addr, %s0			; %addr = (zp)			*delay*

	.global	w65c02_Izp_xI
w65c02_Izp_xI:
	xcall.d	w65c02_read			; %data =  zp = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	add	%data, %X			; %data =  zp+X
	xcall.d	w65c02_read			; %data = [zp+X+0]
	ld.ub	%addr, %data			; %addr =  zp+X ($00..$FF)	*delay*
	ld.w	%s0, %data			; %s0   = [zp+X+0]
	xcall.d	w65c02_read			; %data =          [zp+X+1]
	add	%addr, 1			; %addr =           zp+X+1	*delay*
	xsll	%data, 8			; %data =          [zp+X+1]<<8
	or	%s0, %data			; %s0   = [zp+X+0]|[zp+X+1]<<8
	ret.d
	ld.w	%addr, %s0			; %addr = (zp+X)		*delay*

	.global	w65c02_IzpI_y
w65c02_IzpI_y:
	xcall.d	w65c02_read			; %data =  zp = [PC]
	ld.w	%addr, %PC			;				*delay*
	add	%PC, 1				; PC++
	xcall.d	w65c02_read			; %data = [zp+0]
	ld.w	%addr, %data			; %addr =  zp+0			*delay*
	ld.w	%s0, %data			; %s0   = [zp+0]
	xcall.d	w65c02_read			; %data =        [zp+1]
	add	%addr, 1			; %addr =         zp+1		*delay*
	xsll	%data, 8			; %data =        [zp+1]<<8
	or	%s0, %data			; %s0   = [zp+0]|[zp+1]<<8
	add	%s0, %Y				; %s0   = (zp)+Y
	ret.d
	ld.uh	%addr, %s0			; %addr = (zp)+Y ($0000..$FFFF)	*delay*

;****************************************************************************
;	Operation
;****************************************************************************

	.global	w65c02_LDA
w65c02_LDA:
	ld.w	%A, %data
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_LDX
w65c02_LDX:
	ld.w	%X, %data
	ret.d
	ld.w	%NZ, %X				; *delay*

	.global	w65c02_LDY
w65c02_LDY:
	ld.w	%Y, %data
	ret.d
	ld.w	%NZ, %Y				; *delay*

;----------------------------------------------------------------------------

	.global	w65c02_STA
w65c02_STA:
	ret.d
	ld.w	%data, %A			; *delay*

	.global	w65c02_STX
w65c02_STX:
	ret.d
	ld.w	%data, %X			; *delay*

	.global	w65c02_STY
w65c02_STY:
	ret.d
	ld.w	%data, %Y			; *delay*

	.global	w65c02_STZ
w65c02_STZ:
	ret.d
	ld.w	%data, 0			; *delay*

;----------------------------------------------------------------------------

	.global	w65c02_TXA
w65c02_TXA:
	ld.w	%A, %X
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_TAX
w65c02_TAX:
	ld.w	%X, %A
	ret.d
	ld.w	%NZ, %X				; *delay*

	.global	w65c02_TYA
w65c02_TYA:
	ld.w	%A, %Y
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_TAY
w65c02_TAY:
	ld.w	%Y, %A
	ret.d
	ld.w	%NZ, %Y				; *delay*

	.global	w65c02_TSX
w65c02_TSX:
	ld.w	%X, %S
	ret.d
	ld.w	%NZ, %X				; *delay*

	.global	w65c02_TXS
w65c02_TXS:
	ret.d
	ld.w	%S, %X				; *delay*
	; no P affected

;----------------------------------------------------------------------------

	.global	w65c02_PHA
w65c02_PHA:
	xjp.d	w65c02_push			; Push A
	ld.w	%data, %A			; *delay*

	.global	w65c02_PHX
w65c02_PHX:
	xjp.d	w65c02_push			; Push X
	ld.w	%data, %X			; *delay*

	.global	w65c02_PHY
w65c02_PHY:
	xjp.d	w65c02_push			; Push Y
	ld.w	%data, %Y			; *delay*

	.global	w65c02_PHP
w65c02_PHP:
	xcall	w65c02_get_p			; Push P (NV11DIZC)
	xjp	w65c02_push

	.global	w65c02_PLA
w65c02_PLA:
	xcall	w65c02_pull			; Pull A
	ld.w	%A, %data
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_PLX
w65c02_PLX:
	xcall	w65c02_pull			; Pull X
	ld.w	%X, %data
	ret.d
	ld.w	%NZ, %X				; *delay*

	.global	w65c02_PLY
w65c02_PLY:
	xcall	w65c02_pull			; Pull Y
	ld.w	%Y, %data
	ret.d
	ld.w	%NZ, %Y				; *delay*

	.global	w65c02_PLP
w65c02_PLP:
	xcall	w65c02_pull			; Pull P (NV??DIZC)
	xcall	w65c02_set_p
	xjp	w65c02_check_pending		; 保留されているIRQ要求を調べます。

;----------------------------------------------------------------------------

	.global	w65c02_ADC
w65c02_ADC:
	xbtst	[%CPU+DI], 3			; if D then ADCD
	xjrne	w65c02_ADCD
	;
	ld.w	%t0, %A				; %t0 = A+data+C
	xbtst	[%CPU+C], 0
	jreq.d	3
	add	%t0, %data			; *delay*
	add	%t0, 1				; (skip?)
	;
	xld.h	[%CPU+CA], %t0			; C = (A+data+C)[8]
	;
	xor	%data, %A			; %data =  (A^data)
	not	%data, %data			; %data = ~(A^data)
	xor	%A, %t0				; %A    =           (A^(A+data+C))
	and	%data, %A			; %data = ~(A^data)&(A^(A+data+C))
	xld.b	[%CPU+V], %data			; V     = ~(A^data)&(A^(A+data+C))[7]
	;
	ld.ub	%A, %t0				; %A = A+data+C ($00..$FF)
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_SBC
w65c02_SBC:
	xbtst	[%CPU+DI], 3			; if D then SBCD
	xjrne	w65c02_SBCD
	;
	ld.w	%t0, %A				; %t0 = A-data-~C
	xbtst	[%CPU+C], 0
	jrne.d	3
	sub	%t0, %data			; *delay*
	sub	%t0, 1				; (skip?)
	;
	not	%t1, %t0			; C = ~(A-data-~C)[8]
	xld.h	[%CPU+CA], %t1
	;
	xor	%data, %A			; %data = (A^data)
	xor	%A, %t0				; %A    =          (A^(A-data-~C))
	and	%data, %A			; %data = (A^data)&(A^(A-data-~C))
	xld.b	[%CPU+V], %data			; V     = (A^data)&(A^(A-data-~C))[7]
	;
	ld.ub	%A, %t0				; %A = A-data-~C ($00..$FF)
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_CMP
w65c02_CMP:
	ld.w	%NZ, %A				; %NZ = A-data
	sub	%NZ, %data
	not	%t0, %NZ			; C = ~(A-data)[8]
	xld.h	[%CPU+CA], %t0
	ret.d
	ld.ub	%NZ, %NZ			; 必要!! *delay*

	.global	w65c02_CPX
w65c02_CPX:
	ld.w	%NZ, %X				; %NZ = X-data
	sub	%NZ, %data
	not	%t0, %NZ			; C = ~(X-data)[8]
	xld.h	[%CPU+CA], %t0
	ret.d
	ld.ub	%NZ, %NZ			; 必要!! *delay*

	.global	w65c02_CPY
w65c02_CPY:
	ld.w	%NZ, %Y				; %NZ = Y-data
	sub	%NZ, %data
	not	%t0, %NZ			; C = ~(Y-data)[8]
	xld.h	[%CPU+CA], %t0
	ret.d
	ld.ub	%NZ, %NZ			; 必要!! *delay*

;----------------------------------------------------------------------------

	.global	w65c02_INC
w65c02_INC:
	xadd	%data, %data, 1
	ld.ub	%data, %data			; 必要!!
	ret.d
	ld.w	%NZ, %data			; *delay*

	.global	w65c02_INX
w65c02_INX:
	xadd	%X, %X, 1
	ld.ub	%X, %X				; 必要!!
	ret.d
	ld.w	%NZ, %X				; *delay*

	.global	w65c02_INY
w65c02_INY:
	xadd	%Y, %Y, 1
	ld.ub	%Y, %Y				; 必要!!
	ret.d
	ld.w	%NZ, %Y				; *delay*

	.global	w65c02_DEC
w65c02_DEC:
	xsub	%data, %data, 1
	ld.ub	%data, %data			; 必要!!
	ret.d
	ld.w	%NZ, %data			; *delay*

	.global	w65c02_DEX
w65c02_DEX:
	xsub	%X, %X, 1
	ld.ub	%X, %X				; 必要!!
	ret.d
	ld.w	%NZ, %X				; *delay*

	.global	w65c02_DEY
w65c02_DEY:
	xsub	%Y, %Y, 1
	ld.ub	%Y, %Y				; 必要!!
	ret.d
	ld.w	%NZ, %Y				; *delay*

;----------------------------------------------------------------------------

	.global	w65c02_AND
w65c02_AND:
	and	%A, %data
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_ORA
w65c02_ORA:
	or	%A, %data
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_EOR
w65c02_EOR:
	xor	%A, %data
	ret.d
	ld.w	%NZ, %A				; *delay*

	.global	w65c02_ASL
w65c02_ASL:
	xsll	%data, 1			; %data = -------7 6543210-
	xld.h	[%CPU+CA], %data		;                +------------> C
	ld.ub	%data, %data			; %data = -------- 6543210-
	ret.d
	ld.w	%NZ, %data			; *delay*

	.global	w65c02_LSR
w65c02_LSR:
	xld.b	[%CPU+C], %data			; %data = -------- 76543210 +-> C
	xsrl	%data, 1			; %data = -------- -7654321
	ret.d
	ld.w	%NZ, %data			; *delay *

	.global	w65c02_ROL
w65c02_ROL:
	xld.ub	%t0, [%CPU+C]			; %t0   = -------- -------C
	xand	%t0, %t0, 1
	xsll	%data, 1			; %data = -------7 6543210-
	xld.h	[%CPU+CA], %data		;                +------------> C
	ld.ub	%data, %data			; %data = -------- 6543210-
	or	%data, %t0			; %data = -------- 6543210C
	ret.d
	ld.w	%NZ, %data			; *delay*

	.global	w65c02_ROR
w65c02_ROR:
	xld.ub	%t0, [%CPU+C]			; %t0   = -------- -------C
	xand	%t0, %t0, 1
	xsll	%t0, 7				; %t0   = -------- C-------
	xld.b	[%CPU+C], %data			; %data = -------- 76543210 +-> C
	xsrl	%data, 1			; %data = -------- -7654321
	or	%data, %t0			; %data = -------- C7654321
	ret.d
	ld.w	%NZ, %data			; *delay*

	.global	w65c02_BIT
w65c02_BIT:
	ld.w	%NZ, %data			; V   =          V-------
	xsll	%NZ, 1				;                +-------- (  data)[6]
	xld.b	[%CPU+V], %NZ			; %NZ = N------- NZZZZZZZ
	xsll	%NZ, 7				;       |        ++++++++- (A&data)
	and	%data, %A			;       |        +-------- (A&data)[7]
	ret.d					;       +----------------- (  data)[7]
	or	%NZ, %data			; *delay*

;----------------------------------------------------------------------------

	.global	w65c02_CLC
w65c02_CLC:
	xbclr	[%CPU+C], 0
	ret

	.global	w65c02_SEC
w65c02_SEC:
	xbset	[%CPU+C], 0
	ret

;----------------------------------------------------------------------------

	.global	w65c02_BCC
w65c02_BCC:
	.global	w65c02_BCS
w65c02_BCS:
	xbtst	[%CPU+C], 0
	ret

	.global	w65c02_BEQ
w65c02_BEQ:
	.global	w65c02_BNE
w65c02_BNE:
	xand	%r9, %NZ, 0xff
	ret

	.global	w65c02_BPL
w65c02_BPL:
	.global	w65c02_BMI
w65c02_BMI:
	xand	%r9, %NZ, 0x8080
	ret

	.global	w65c02_BVC
w65c02_BVC:
	.global	w65c02_BVS
w65c02_BVS:
	xbtst	[%CPU+V], 7
	ret

;----------------------------------------------------------------------------

	.global	w65c02_RTS
w65c02_RTS:
	xcall	w65c02_pull			; Pull LO(PC)
	xcall.d	w65c02_pull			; Pull HI(PC)
	ld.w	%PC, %data			; *delay*
	xsll	%data, 8			; %PC = PC
	or	%PC, %data
	ret.d
	add	%PC, 1				; PC++ (仕様) *delay*

;****************************************************************************
;	
;****************************************************************************
