;WinSTon

;-----------------------------------------------------------------------
;Set condition codes for each instruction
SET_NUZV_CX_SAME MACRO
	call	FUNC_SET_NUZV_CX_SAME_CALL
	FRET
	ENDM
WRITE_BYTE_NUZV_CX_SAME MACRO
	jmp		FUNC_WRITE_BYTE_NUZV_CX_SAME
	ENDM
WRITE_WORD_NUZV_CX_SAME MACRO
	jmp		FUNC_WRITE_WORD_NUZV_CX_SAME
	ENDM
WRITE_LONG_NUZV_CX_SAME MACRO
	jmp		FUNC_WRITE_LONG_NUZV_CX_SAME
	ENDM
SET_NZVC MACRO
	jmp		FUNC_SET_NZVC
	ENDM
SET_NZ_CX_SAME_CLEAR_V MACRO
	call	FUNC_SET_NZ_CX_SAME_CLEAR_V_CALL
	FRET
	ENDM
WRITE_WORD_NZ_CX_SAME_CLEAR_V MACRO
	jmp		FUNC_WRITE_WORD_NZ_CX_SAME_CLEAR_V
	ENDM
SET_NZV_CX_SAME MACRO
	call	FUNC_SET_NZV_CX_SAME_CALL
	FRET
	ENDM
WRITE_BYTE_NZV_CX_SAME MACRO
	jmp		FUNC_WRITE_BYTE_NZV_CX_SAME
	ENDM
WRITE_WORD_NZV_CX_SAME MACRO
	jmp		FUNC_WRITE_WORD_NZV_CX_SAME
	ENDM
WRITE_LONG_NZV_CX_SAME MACRO
	jmp		FUNC_WRITE_LONG_NZV_CX_SAME
	ENDM
SET_NZ MACRO
	jmp		FUNC_SET_NZ
	ENDM
WRITE_BYTE_NZ MACRO
	jmp		FUNC_WRITE_BYTE_NZ
	ENDM
WRITE_WORD_NZ MACRO
	jmp		FUNC_WRITE_WORD_NZ
	ENDM
WRITE_LONG_NZ MACRO
	jmp		FUNC_WRITE_LONG_NZ
	ENDM

;-----------------------------------------------------------------------
;Combine 'SR' with current condition codes, NOTE 'ecx' is corrupted
COMBINE_SR_TO_AX MACRO
	shr		eax,4									;Emulation codes in correct bits
	and		eax,SR_CCODE_MASK
	mov		ah,BYTE PTR 1[_SR]						;Upper 8 bits of SR
	ENDM





;-----------------------------------------------------------------------
;Handle cases of shift count of '0', simply set NZVC(ignore X)
;'edx' is register
zero_shift_byte PROC NEAR
	xor		al,al									;Clear NZVC(ignore X)
	or		BYTE PTR [edx],0						;Set flags, for zero shift case
	SET_NZ
zero_shift_byte ENDP

zero_shift_word PROC NEAR
	xor		al,al									;Clear NZVC(ignore X)
	or		WORD PTR [edx],0						;Set flags, for zero shift case
	SET_NZ
zero_shift_word ENDP

zero_shift_long PROC NEAR
	xor		al,al									;Clear NZVC(ignore X)
	or		DWORD PTR [edx],0						;Set flags, for zero shift case
	SET_NZ
zero_shift_long ENDP

;-----------------------------------------------------------------------
;Handle cases of rotate X count of '0', simply set NZVC(ignore X)
;'edx' is register
zero_rox_byte PROC NEAR
	and		eax,EMU_X								;Clear NZVC(ignore X)
	je		no_carry
	or		eax,EMU_C								;Copy X bit into C
no_carry:
	or		BYTE PTR [edx],0						;Set flags, for zero shift case
	SET_NZ
zero_rox_byte ENDP

zero_rox_word PROC NEAR
	and		eax,EMU_X								;Clear NZVC(ignore X)
	je		no_carry
	or		eax,EMU_C								;Copy X bit into C
no_carry:
	or		WORD PTR [edx],0						;Set flags, for zero shift case
	SET_NZ
zero_rox_word ENDP

zero_rox_long PROC NEAR
	and		eax,EMU_X								;Clear NZVC(ignore X)
	je		no_carry
	or		eax,EMU_C								;Copy X bit into C
no_carry:
	or		DWORD PTR [edx],0						;Set flags, for zero shift case
	SET_NZ
zero_rox_long ENDP


;-----------------------------------------------------------------------
;Set emulation XNZVC flags ,CX same and Z clear in non-zero. according to PC condition codes

;Z is only changed if non-zero, else leave alone
FUNC_SET_NUZV_CX_SAME_CALL PROC NEAR
	pushf
	pop		dx
	and		edx,000000fffh
	test	edx,PC_ZERO								;Is zero? If so,leave Z unchanged
	jne		zero

non_zero:
	mov		al,_PCCodeTable_NZV_CX_SAME[edx]
	shl		eax,4									;In EMU order
	ret

zero:
	and		eax,NOT (EMU_X+EMU_N+EMU_V+EMU_C)		;Clear XNVC, leave 'Z' alone
	and		edx,NOT PC_ZERO							;Clear zero, to leave unchanged
	mov		dl,_PCCodeTable_NZV_CX_SAME[edx]		;Ccodes
	shl		edx,4									;In EMU order
	or		eax,edx									;Store condition codes
	ret
FUNC_SET_NUZV_CX_SAME_CALL ENDP

;And write back into <ea>
FUNC_WRITE_BYTE_NUZV_CX_SAME PROC NEAR
	call	FUNC_SET_NUZV_CX_SAME_CALL
	INTERCEPT_CHECK_ADDR_WRITEBYTE					;Write 'bl' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_BYTE_NUZV_CX_SAME ENDP

FUNC_WRITE_WORD_NUZV_CX_SAME PROC NEAR
	call	FUNC_SET_NUZV_CX_SAME_CALL
	INTERCEPT_CHECK_ADDR_WRITEWORD					;Write 'bx' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_WORD_NUZV_CX_SAME ENDP

FUNC_WRITE_LONG_NUZV_CX_SAME PROC NEAR
	call	FUNC_SET_NUZV_CX_SAME_CALL
	INTERCEPT_CHECK_ADDR_WRITELONG					;Write 'ebx' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_LONG_NUZV_CX_SAME ENDP

;-----------------------------------------------------------------------
;Set emulation XNZC flags, X same as C, clear V according to PC condition codes
FUNC_SET_NZ_CX_SAME_CLEAR_V_CALL PROC NEAR
	pushf
	pop		ax
	and		eax,PC_CARRY+PC_ZERO+PC_NEG
	mov		al,_PCCodeTable_NZV_CX_SAME[eax]
	shl		eax,4									;In EMU order
	ret
FUNC_SET_NZ_CX_SAME_CLEAR_V_CALL ENDP

FUNC_WRITE_WORD_NZ_CX_SAME_CLEAR_V PROC NEAR
	call	FUNC_SET_NZ_CX_SAME_CLEAR_V_CALL
	INTERCEPT_CHECK_ADDR_WRITEWORD					;Write 'bx' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_WORD_NZ_CX_SAME_CLEAR_V ENDP

;-----------------------------------------------------------------------
;Set emulation XNZVC flags, X same as C, according to PC condition codes
FUNC_SET_NZV_CX_SAME_CALL PROC NEAR
	pushf
	pop		ax
	and		eax,000000fffh
	mov		al,_PCCodeTable_NZV_CX_SAME[eax]
	shl		eax,4									;In EMU order
	ret
FUNC_SET_NZV_CX_SAME_CALL ENDP

;And write back into <ea>
FUNC_WRITE_BYTE_NZV_CX_SAME PROC NEAR
	call	FUNC_SET_NZV_CX_SAME_CALL
	INTERCEPT_CHECK_ADDR_WRITEBYTE					;Write 'bl' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_BYTE_NZV_CX_SAME ENDP

FUNC_WRITE_WORD_NZV_CX_SAME PROC NEAR
	call	FUNC_SET_NZV_CX_SAME_CALL
	INTERCEPT_CHECK_ADDR_WRITEWORD					;Write 'bx' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_WORD_NZV_CX_SAME ENDP

FUNC_WRITE_LONG_NZV_CX_SAME PROC NEAR
	call	FUNC_SET_NZV_CX_SAME_CALL
	INTERCEPT_CHECK_ADDR_WRITELONG					;Write 'ebx' to 'ebp', corrupts 'ecx'
	FRET
FUNC_WRITE_LONG_NZV_CX_SAME ENDP

;-----------------------------------------------------------------------
;Set emulation NZVC flags, according to PC condition codes
FUNC_SET_NZVC PROC NEAR
	pushf
	pop		bx
	and		ebx,000000fffh
	mov		al,_PCCodeTable_NZVC[ebx]				;Already in EMU order
	FRET
FUNC_SET_NZVC ENDP

;-----------------------------------------------------------------------
;Set emulation NZ flags according to PC condition codes

;Set emulation NZ flags according to value in 'ebx'
;And write back into <ea>
FUNC_WRITE_BYTE_NZ PROC NEAR
	jl		negative								;Check flags
	jz		zero
ok:
	INTERCEPT_CHECK_ADDR_WRITEBYTE					;Write 'bl' to 'ebp', corrupts 'ecx'
	FRET
zero:
	or		al,EMU_Z
	jmp		ok
negative:
	or		al,EMU_N
	jmp		ok
FUNC_WRITE_BYTE_NZ ENDP

FUNC_WRITE_WORD_NZ PROC NEAR
	jl		negative								;Check flags
	jz		zero
ok:
	INTERCEPT_CHECK_ADDR_WRITEWORD					;Write 'bx' to 'ebp', corrupts 'ecx'
	FRET
zero:
	or		al,EMU_Z
	jmp		ok
negative:
	or		al,EMU_N
	jmp		ok
FUNC_WRITE_WORD_NZ ENDP

FUNC_WRITE_LONG_NZ PROC NEAR
	jl		negative								;Check flags
	jz		zero
ok:
	INTERCEPT_CHECK_ADDR_WRITELONG					;Write 'ebx' to 'ebp', corrupts 'ecx'
	FRET
zero:
	or		al,EMU_Z
	jmp		ok
negative:
	or		al,EMU_N
	jmp		ok
FUNC_WRITE_LONG_NZ ENDP

FUNC_SET_NZ_SET PROC NEAR
	;MUST be <=0, if get here!
	jz		zero									;Set flags, N is bit 7

	or		al,EMU_N								;Negative
	FRET
zero:
	or		al,EMU_Z								;Zero
	FRET
FUNC_SET_NZ_SET ENDP

;Set emulation NZ flags according to PC condition codes
FUNC_SET_NZ PROC NEAR
	jle		FUNC_SET_NZ_SET							;Needs to set, else +ve number
	;NOTE Good optimisation here, as 99% time is +ve number, so run through into decode loop!
FUNC_SET_NZ ENDP
;
;BIG WARNING!!!!!!!
;RUN-THROUGH (oo-er), INTO InstructionLoop()
;
