;
;	clipc16a.s
;
;	P/ECE CP1610 Emulator
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2005 Naoyuki Sawa
;
;	* Sun May 15 21:34:00 JST 2005 Naoyuki Sawa
;	- 作成開始。
;
#include "clipc16a.h"

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

	.code
	.align 1

;****************************************************************************
;	Operation (使用頻度が低いもの)
;****************************************************************************

	.global	cp1610_ERR
cp1610_ERR:
	xcall	cp1610_leave			; 実行コンテキストを抜けます。
	xjp	cp1610_err			; C言語版のエラールーチンへ。

	.global	cp1610_HLT
cp1610_HLT:
	xbset	[%CPU+FLAGS], HLT_BIT		; HLT = 1
	ret.d
	ld.w	%CYCLE, 0			; cycle = 0	*delay*

	.global	cp1610_SDBD
cp1610_SDBD:
	xbset	[%CPU+FLAGS], DBD_BIT		; DBD = 1
	ret

	.global	cp1610_EIS
cp1610_EIS:
	xbset	[%CPU+FLAGS], IFF_BIT		; IFF = 1
	ret

	.global	cp1610_DIS
cp1610_DIS:
	xbclr	[%CPU+FLAGS], IFF_BIT		; IFF = 0
	ret

	.global	cp1610_TCI
cp1610_TCI:
	xbclr	[%CPU+FLAGS], IRQ_BIT		; IRQ = 0
	ret

	.global	cp1610_CLRC
cp1610_CLRC:
	xbclr	[%CPU+C+2], 0			; C = 0
	ret

	.global	cp1610_SETC
cp1610_SETC:
	xbset	[%CPU+C+2], 0			; C = 1
	ret

	.global	cp1610_GSWD
cp1610_GSWD:
	xcall	cp1610_get_status		; %r10 = 00000000 SZVC0000
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.b	[%dst]+, %r10			; RD   = -------- SZVC0000
	ld.b	[%dst] , %r10			; RD   = SZVC0000 SZVC0000
	ret

	.global	cp1610_NOP
cp1610_NOP:
	/** no job **/
	ret

	.global	cp1610_SIN
cp1610_SIN:
	xjp	cp1610_ERR

	.global	cp1610_RSWD
cp1610_RSWD:
	xld.ub	%src, [%op+SRC]			; %src =  RS
	add	%src, %CPU			; %src = &RS
	ld.uh	%r12, [%src]			; %r12 = 00000000 SZVC0000
	xjp	cp1610_set_status

	.global	cp1610_SWAP
cp1610_SWAP:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   =  RD (00 00 Hi Lo)
	swap	%r9, %SZ			; %r9  =  RD (Lo Hi 00 00)
	xsrl	%r9, 16				; %r9  =  RD (00 00 Lo Hi)
	ld.h	[%dst], %r9			; RD   =  RD (00 00 Lo Hi)
	ret					; (SZ  =  SWAP『前』の値を反映!!)

	.global	cp1610_SWAP2
cp1610_SWAP2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	xld.ub	%SZ, [%dst+0]			; SZ   =  RD (00 00 00 Lo)
	xld.b	[%dst+1], %SZ			; RD   =  RD (00 00 Lo Lo)
	ld.uh	%SZ, [%dst]			; SZ   =  RD (00 00 Lo Lo)
	ret					; (SZ  =  SWAP2『後』の値を反映!!)

	.global	cp1610_SLL
cp1610_SLL:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xsll	%SZ, 1				; SZ   = -f edcba987 6543210-
	ld.h	[%dst], %SZ			; RD   =    edcba987 6543210-
	ret.d
	ld.uh	%SZ, %SZ			; SZ   = (half)SZ			*delay*

	.global	cp1610_SLL2
cp1610_SLL2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xsll	%SZ, 2				; SZ   = fe dcba9876 543210--
	ld.h	[%dst], %SZ			; RD   =    dcba9876 543210--
	ret.d
	ld.uh	%SZ, %SZ			; SZ   = (half)SZ			*delay*

	.global	cp1610_RLC
cp1610_RLC:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xld.ub	%r10, [%CPU+C+2]		; %r10 = -- -------- ???????C
	xand	%r10, %r10, 1			; %r10 = -- -------- -------C
	xsll	%SZ, 1				; SZ   = -f edcba987 6543210-
	xld.w	[%CPU+C], %SZ			;         +->STATUS(C)
	or	%SZ, %r10			; SZ   = -f edcba987 6543210C
	ld.h	[%dst], %SZ			; RD   =    edcba987 6543210C
	ret.d
	ld.uh	%SZ, %SZ			; SZ   = (half)SZ			*delay*

	.global	cp1610_RLC2
cp1610_RLC2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xld.ub	%r10, [%CPU+C+2]		; %r10 = -- -------- ???????C
	xand	%r10, %r10, 1			; %r10 = -- -------- -------C
	xld.ub	%r11, [%CPU+OV+1]		; %r11 = -- -------- V???????
	xsrl	%r11, 7				; %r11 = -- -------- -------V
	xsll	%SZ, 1				; SZ   = -f edcba987 6543210-
	xld.h	[%CPU+OV], %SZ			;         | +->STATUS(OV)
	xld.w	[%CPU+C], %SZ			;         +--->STATUS(C)
	or	%SZ, %r10			; SZ   = -f edcba987 6543210C
	xsll	%SZ, 1				; SZ   = fe dcba9876 543210C-
	or	%SZ, %r11			; SZ   = fe dcba9876 543210CV
	ld.h	[%dst], %SZ			; RD   =    dcba9876 543210CV
	ret.d
	ld.uh	%SZ, %SZ			; SZ   = (half)SZ			*delay*

	.global	cp1610_SLLC
cp1610_SLLC:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xsll	%SZ, 1				; SZ   =  f edcba987 6543210-
	xld.w	[%CPU+C], %SZ			;         +->STATUS(C)
	ld.h	[%dst], %SZ			; RD   =    edcba987 6543210-
	ret.d
	ld.uh	%SZ, %SZ			; SZ   = (half)SZ			*delay*

	.global	cp1610_SLLC2
cp1610_SLLC2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xsll	%SZ, 1				; SZ   = -f edcba987 6543210-
	xld.h	[%CPU+OV], %SZ			;         | +->STATUS(OV)
	xld.w	[%CPU+C], %SZ			;         +--->STATUS(C)
	xsll	%SZ, 1				; SZ   = fe dcba9876 543210--
	ld.h	[%dst], %SZ			; RD   =    dcba9876 543210--
	ret.d
	ld.uh	%SZ, %SZ			; SZ   = (half)SZ			*delay*

	.global	cp1610_SLR
cp1610_SLR:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xsrl	%SZ, 1				; SZ   = -- -fedcba9 87654321
	ld.h	[%dst], %SZ			; RD   =    -fedcba9 87654321
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_SLR2
cp1610_SLR2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210
	xsrl	%SZ, 2				; SZ   = -- --fedcba 98765432
	ld.h	[%dst], %SZ			; RD   =    --fedcba 98765432
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_SAR
cp1610_SAR:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.h	%SZ, [%dst]			; SZ   = ff fedcba98 76543210
	xsrl	%SZ, 1				; SZ   = ff ffedcba9 87654321
	ld.h	[%dst], %SZ			; RD   =    ffedcba9 87654321
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_SAR2
cp1610_SAR2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.h	%SZ, [%dst]			; SZ   = ff fedcba98 76543210
	xsrl	%SZ, 2				; SZ   = ff fffedcba 98765432
	ld.h	[%dst], %SZ			; RD   =    fffedcba 98765432
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_RRC
cp1610_RRC:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210-+
	xld.w	%r10, [%CPU+C]			; %r10 = ?C ???????? ???????? |
	xand	%r10, %r10, (1<<16)		; %r10 = -C -------- -------- |
	xld.b	[%CPU+C+2], %SZ			;                STATUS(C)<---+
	or	%SZ, %r10			; SZ   = -C fedcba98 76543210
	xsrl	%SZ, 1				; SZ   = -- Cfedcba9 87654321
	ld.h	[%dst], %SZ			; RD   =    Cfedcba9 87654321
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_RRC2
cp1610_RRC2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.uh	%SZ, [%dst]			; SZ   = -- fedcba98 76543210-+
	xld.w	%r10, [%CPU+C]			; %r10 = ?C ???????? ???????? |
	xand	%r10, %r10, (1<<16)		; %r10 = -C -------- -------- |
	xld.uh	%r11, [%CPU+OV]			; %r11 = -- V??????? ???????? |
	xand	%r11, %r11, (1<<15)		; %r11 = -- V------- -------- |
	xld.b	[%CPU+C+2], %SZ			;                STATUS(C)<---+
	or	%SZ, %r10			; SZ   = -C fedcba98 76543210
	xsrl	%SZ, 1				; SZ   = -- Cfedcba9 87654321
	mirror	%r9, %SZ			;                           |
	xld.b	[%CPU+OV+1], %r9		;               STATUS(OV)<-+
	xsrl	%SZ, 1				; SZ   = -- -Cfedcba 98765432
	or	%SZ, %r11			; SZ   = -- VCfedcba 98765432
	ld.h	[%dst], %SZ			; RD   =    VCfedcba 98765432
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_SARC
cp1610_SARC:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.h	%SZ, [%dst]			; SZ   = ff fedcba98 76543210
	xld.b	[%CPU+C+2], %SZ			;               STATUS(C)<-+
	xsrl	%SZ, 1				; SZ   = ff ffedcba9 87654321
	ld.h	[%dst], %SZ			; RD   =    ffedcba9 87654321
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_SARC2
cp1610_SARC2:
	xld.ub	%dst, [%op+DST]			; %dst =  RD
	add	%dst, %CPU			; %dst = &RD
	ld.h	%SZ, [%dst]			; SZ   = ff fedcba98 76543210
	xld.b	[%CPU+C+2], %SZ			;                STATUS(C)<-+
	xsrl	%SZ, 1				; SZ   = ff ffedcba9 87654321
	mirror	%r9, %SZ			;                           |
	xld.b	[%CPU+OV+1], %r9		;               STATUS(OV)<-+
	xsrl	%SZ, 1				; SZ   = ff fffedcba 98765432
	ld.h	[%dst], %SZ			; RD   =    fffedcba 98765432
	xsll	%SZ, 16				; SZ   =  RD (Hi Lo 00 00)
	ret.d
	swap	%SZ, %SZ			; SZ   =  RD (00 00 Lo Hi)		*delay*

	.global	cp1610_BEXT
cp1610_BEXT:
	xld.ub	%r10, [%CPU+EBC]		; %r10    = EBC
	xld.ub	%src, [%op+SRC]			; %src    = cond (0..15)
	xjp.d	cp1610_bcond
	cmp	%r10, %src			; %psr(Z) = 1:分岐有り or 0:分岐無し	*delay*

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