61 lines
1.4 KiB
Text
61 lines
1.4 KiB
Text
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.$'
|