;	WinSTon

;	ABCD Dy,Dx
;	ABCD -(Ay),-(Ax)

;	XNZVC
;	*U*U*

PUBLIC _abcd_dn_dn
PUBLIC _abcd_an_an

;Convert 'ebx' as BCD to decimal number = ((var&0xf0)>>4)*10 + (var&0x0f)
BCDtoDEC PROC NEAR
	push	eax
	push	ecx

	and		ebx,0ffh		;Clear
	mov		eax,ebx
	shr		eax,4
	and		eax,0fh			;(var>>4)&0x0f
	mov		cl,10
	mul		cl				;ax = al*cl

	and		ebx,0fh			;(var&0x0f)
	add		ebx,eax			;+((var>>4)&0x0f)

	pop		ecx
	pop		eax
	ret
BCDtoDEC ENDP

;Convert 'ebx' as decimal into BCD number ((var/10)<<4) + (var%10)
DECtoBCD PROC NEAR
	push	eax
	push	ecx

	and		ebx,0ffh		;Clear
	mov		eax,ebx
	mov		cl,10
	div		cl				;al-quo, ah-rem

	xor		ebx,ebx
	mov		bl,al
	shl		ebx,4			;((var/10)<<4)
	add		bl,ah			;+(var%10)

	pop		ecx
	pop		eax
	ret
DECtoBCD ENDP

;-----------------------------------------------------------------------
;ABCD Dy,Dx
_abcd_dn_dn PROC NEAR
	mov		edx,DECODE_2[ecx]						;Rx('opcode' bits 9-11)
	mov		bl,BYTE PTR [edx]
	call	BCDtoDEC								;dl = RegY as decimal
	mov		edx,ebx

	mov		ecx,DECODE_1[ecx]						;Ry('opcode' bits 0-2)
	mov		bl,BYTE PTR [ecx]
	call	BCDtoDEC								;bl = RegX as decimal

	test	eax,EMU_X
	je		no_carry
	add		ebx,edx
	inc		ebx										;RegX+RegY+1
	jmp		result
no_carry:
	add		ebx,edx									;RegX+RegY
result:

	and		eax,NOT (EMU_X+EMU_C)
	cmp		ebx,100
	jl		no_overflow
	sub		ebx,100
	or		eax,EMU_C+EMU_X
no_overflow:
	cmp		ebx,0
	je		not_zero
	and		eax,EMU_CLEAR_Z
not_zero:

	call	DECtoBCD								;bl = Reg as binary coded decimal
	mov		BYTE PTR [ecx],bl

	FRET
_abcd_dn_dn ENDP

;-----------------------------------------------------------------------
;ABCD -(Ay),-(Ax)
_abcd_an_an PROC NEAR
	mov		edx,DECODE_2[ecx]						;RegY
	cmp		edx,OFFSET _Regs+(15*4)
	jl		no_ay_a7								;Is (a7) or (a8)?
	sub		DWORD PTR [edx],SIZE_BYTE				;Yes, add SIZE_WORD
no_ay_a7:
	sub		DWORD PTR [edx],SIZE_BYTE
	mov		ebp,[edx]								;Look up contents
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		bl,BYTE PTR _STRam[ebp]
	call	BCDtoDEC								;dl = RegY as decimal
	mov		edx,ebx

	mov		ebp,DECODE_1[ecx]						;RegX
	cmp		ebp,OFFSET _Regs+(15*4)
	jl		no_ax_a7								;Is (a7) or (a8)?
	sub		DWORD PTR [ebp],SIZE_BYTE				;Yes, add SIZE_WORD
no_ax_a7:
	sub		DWORD PTR [ebp],SIZE_BYTE
	mov		ebp,[ebp]								;Look up contents
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		bl,BYTE PTR _STRam[ebp]
	call	BCDtoDEC								;bl = RegX as decimal

	test	eax,EMU_X
	je		no_carry
	add		ebx,edx
	inc		ebx										;RegX+RegY+1
	jmp		result
no_carry:
	add		ebx,edx									;RegX+RegY
result:

	and		eax,NOT (EMU_X+EMU_C)
	cmp		ebx,100
	jl		no_overflow
	sub		ebx,100
	or		eax,EMU_C+EMU_X
no_overflow:
	cmp		ebx,0
	je		not_zero
	and		eax,EMU_CLEAR_Z
not_zero:

	call	DECtoBCD								;bl = Reg as binary coded decimal
	mov		BYTE PTR _STRam[ebp],bl
	FRET
_abcd_an_an ENDP
