Task

Determine whether a given year is a leap year in the Gregorian calendar.



See also

 Leap year (wiki)


		org	100h
		jmp	test
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;; Check if a year is a leap year.
		;; Input: HL = year.
		;; Output: Carry flag set if HL is a leap year.
		;; Registers used: all.
leap:		mvi	a,3		; Divisible by 4?
		ana	l		; If not, not a leap year,
		rnz			; Return w/carry cleared
		mvi	b,2		; Divide by 4 (shift right 2)
leapdiv4:	mov	a,h
		rar
		mov	h,a
		mov 	a,l
		rar
		mov	l,a
		dcr 	b
		jnz	leapdiv4
		lxi	b,-1		; Divide by 25 using subtraction
		lxi	d,-25
leapdiv25:	inx	b		; Keep quotient in BC
		dad	d
		jc	leapdiv25
		mov	a,e		; If so, L==E afterwards.
		xra	l 		; (High byte is always FF.)
		stc			; Set carry, and
		rnz			; return if not divisible.
		mvi	a,3		; Is this divisble by 4?
		ana	c
		sui	1		; Set carry if so.
		ret
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;; Test code: get year from CP/M command line and see
		;; if it is a leap year.
test:		lxi	b,5Dh		; First char of "file name"
		lxi	h,0		; Accumulator
digit:		ldax	b		; Get character
		sui	'0'		; ASCII digit
		jc	getleap		; Not valid digit = done
		cpi	10
		jnc	getleap		; Not valid digit = done
		dad	h		; HL *= 10
		mov	d,h
		mov	e,l
		dad	h
		dad	h
		dad	d
		mvi	d,0		; Plus digit
		mov	e,a
		dad	d
		inx	b		; Next character
		jmp	digit
getleap:	call	leap		; Is HL a leap year?
		lxi	d,no		; No, 
		jnc	out		; unless carry is set,
		lxi	d,yes		; then it is a leap year.
out:		mvi	c,9
		jmp	5 
no:		db	'NOT '
yes:		db	'LEAP YEAR.$'