;	WinSTon

;	ASR Dx,Dy
;	ASR #<data>,Dy
;	ASR <ea>

;	XNZVC
;	***0*

PUBLIC _asr_dn_dn_byte
PUBLIC _asr_dn_dn_word
PUBLIC _asr_dn_dn_long
PUBLIC _asr_imm_dn_byte
PUBLIC _asr_imm_dn_word
PUBLIC _asr_imm_dn_long
PUBLIC _asr_ea_word

;-----------------------------------------------------------------------
;ASR.B Dx,Dy
_asr_dn_dn_byte PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Dx
	mov		edx,DECODE_2[ecx]						;Dy(can corrupt 'ecx')
	mov		cl,BYTE PTR [ebx]
	and		ecx,63									;Modulus 64
	je		zero_shift_byte							;Check shift count 0
	ADD_SHIFT_CYCLES_BYTEWORD	ecx					;NOTE corrupts 'ebx'
		
	xor		eax,eax									;Clear XNZVC
	mov		[Overflow],al

	mov		bl,BYTE PTR [edx]						;And shift
shift_loop:
	sar		bl,1
	jno		no_overflow
	mov		[Overflow],EMU_V
no_overflow:
	loop	shift_loop

	mov		BYTE PTR [edx],bl
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		al,[Overflow]
	or		bl,bl									;Test NZ value
	SET_NZ
_asr_dn_dn_byte ENDP

;ASR.W Dx,Dy
_asr_dn_dn_word PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Dx
	mov		edx,DECODE_2[ecx]						;Dy(can corrupt 'ecx')
	mov		cl,BYTE PTR [ebx]
	and		ecx,63									;Modulus 64
	je		zero_shift_word							;Check shift count 0
	ADD_SHIFT_CYCLES_BYTEWORD	ecx					;NOTE corrupts 'ebx'

	xor		eax,eax									;Clear XNZVC
	mov		[Overflow],al

	mov		bx,WORD PTR [edx]						;And shift
shift_loop:
	sar		bx,1
	jno		no_overflow
	mov		[Overflow],EMU_V
no_overflow:
	loop	shift_loop

	mov		WORD PTR [edx],bx
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		al,[Overflow]
	or		bx,bx									;Test NZ value
	SET_NZ
_asr_dn_dn_word ENDP

;ASR.L Dx,Dy
_asr_dn_dn_long PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Dx
	mov		edx,DECODE_2[ecx]						;Dy(can corrupt 'ecx')
	mov		cl,BYTE PTR [ebx]
	and		ecx,63									;Modulus 64
	je		zero_shift_long							;Check shift count 0
	ADD_SHIFT_CYCLES_LONG	ecx						;NOTE corrupts 'ebx'

	xor		eax,eax									;Clear XNZVC
	mov		[Overflow],al

	mov		ebx,DWORD PTR [edx]						;And shift
shift_loop:
	sar		ebx,1
	jno		no_overflow
	mov		[Overflow],EMU_V
no_overflow:
	loop	shift_loop

	mov		DWORD PTR [edx],ebx
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		al,[Overflow]
	or		ebx,ebx									;Test NZ value
	SET_NZ
_asr_dn_dn_long ENDP

;-----------------------------------------------------------------------
;ASR.B #<data>,Dy
_asr_imm_dn_byte PROC NEAR
	mov		edx,DECODE_1[ecx]						;DReg
	mov		ecx,DECODE_2[ecx]						;Count		
	ADD_SHIFT_CYCLES_BYTEWORD	ecx					;NOTE corrupts 'ebx'

	xor		eax,eax									;Clear XNZVC
	mov		[Overflow],al

	mov		bl,BYTE PTR [edx]						;And shift
shift_loop:
	sar		bl,1
	jno		no_overflow
	mov		[Overflow],EMU_V
no_overflow:
	loop	shift_loop

	mov		BYTE PTR [edx],bl
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		al,[Overflow]
	or		bl,bl									;Test NZ value
	SET_NZ
_asr_imm_dn_byte ENDP

;ASR.W #<data>,Dy
_asr_imm_dn_word PROC NEAR
	mov		edx,DECODE_1[ecx]						;DReg
	mov		ecx,DECODE_2[ecx]						;Count		
	ADD_SHIFT_CYCLES_BYTEWORD	ecx					;NOTE corrupts 'ebx'

	xor		eax,eax									;Clear XNZVC
	mov		[Overflow],al

	mov		bx,WORD PTR [edx]						;And shift
shift_loop:
	sar		bx,1
	jno		no_overflow
	mov		[Overflow],EMU_V
no_overflow:
	loop	shift_loop

	mov		WORD PTR [edx],bx
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		al,[Overflow]
	or		bx,bx									;Test NZ value
	SET_NZ
_asr_imm_dn_word ENDP

;ASR.L #<data>,Dy
_asr_imm_dn_long PROC NEAR
	mov		edx,DECODE_1[ecx]						;DReg
	mov		ecx,DECODE_2[ecx]						;Count		
	ADD_SHIFT_CYCLES_LONG	ecx						;NOTE corrupts 'ebx'

	xor		eax,eax									;Clear XNZVC
	mov		[Overflow],al

	mov		ebx,DWORD PTR [edx]						;And shift
shift_loop:
	sar		ebx,1
	jno		no_overflow
	mov		[Overflow],EMU_V
no_overflow:
	loop	shift_loop

	mov		DWORD PTR [edx],ebx
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		al,[Overflow]
	or		ebx,ebx									;Test NZ value
	SET_NZ
_asr_imm_dn_long ENDP

;-----------------------------------------------------------------------
;ASR.W <ea>
_asr_ea_word PROC NEAR
	EFFADDR_READ									;Read <ea>

	xor		eax,eax									;Clear XNZVC		
	sar		bx,1									;And shift

	jno		no_overflow
	or		al,EMU_V
no_overflow:
	jnc		no_carry
	or		ax,EMU_C+EMU_X
no_carry:
	or		bx,bx									;Test NZ value
	WRITE_WORD_NZ
_asr_ea_word ENDP
