The sequence is generated by following this pseudo-code:

A:  The first term is zero.
    Repeatedly apply:
        If the last term is *new* to the sequence so far then:
B:          The next term is zero.
        Otherwise:
C:          The next term is how far back this last term occured previously.



Example

Using A:

0
Using B:

0 0
Using C:

0 0 1
Using B:

0 0 1 0
Using C: (zero last occurred two steps back - before the one)

0 0 1 0 2
Using B:

0 0 1 0 2 0
Using C: (two last occurred two steps back - before the zero)

0 0 1 0 2 0 2 2
Using C: (two last occurred one step back)

0 0 1 0 2 0 2 2 1
Using C: (one last appeared six steps back)

0 0 1 0 2 0 2 2 1 6
...



Task

 Create a function/procedure/method/subroutine/... to generate the Van Eck sequence of numbers.
 Use it to display here, on this page:
 The first ten terms of the sequence.
 Terms 991 - to - 1000 of the sequence.


References

 Don't Know (the Van Eck Sequence) - Numberphile video.
 Wikipedia Article: Van Eck's Sequence.
  OEIS sequence: A181391.


	org	100h
	lxi	h,ecks	; Zero out 2000 bytes
	lxi	b,0
	lxi	d,2000
zero:	mov	m,b
	inx	h
	dcx	d
	mov	a,d
	ora	e
	jnz 	zero
	lxi	b,-1	; BC = Outer loop variable
outer:	inx	b
	mvi	a,3	; Are we there yet? 1000 = 03E8h
	cmp	b	; Compare high byte
	jnz	go
	mvi	a,0E8h	; Compare low byte
	cmp	c
	jz	done
go:	mov	d,b	; DE = Inner loop variable
	mov	e,c
inner:	dcx	d
	mov	a,d	; <= 0?
	ral
	jc	outer
	push	b	; Keep both pointers
	push	d
	mov	h,b	; Load BC = eck[BC]
	mov	l,c
	call	eck
	mov	c,m
	inx	h
	mov	b,m
	xchg		; Load HL = -eck[DE]
	call	eck
	xchg
	ldax 	d
	cma
	mov	l,a
	inx	d
	ldax 	d
	cma
	mov	h,a
	inx	h 	; Two's complement
	dad	b	; -eck[DE] + eck[BC]
	mov	a,h	; Unfortunately this does not set flags
	ora	l	; Check zero
	pop	d	; Meanwhile, restore the pointers
	pop	b
	jnz	inner	; If no match, continue with inner loop
	mov	h,b	; If we _did_, then get &eck[BC + 1]
	mov	l,c 
	inx	h
	call 	eck
	mov	a,c	; Store BC - DE at that address
	sub	e
	mov	m,a
	inx	h
	mov	a,b
	sbb	d
	mov	m,a
	jmp 	outer	; And continue the outer loop
done:	lxi	h,0	; Print first 10 terms
	call	p10
	lxi	h,990	; Print last 10 terms
p10:	mvi 	b,10	; Print 10 terms starting at term HL
	call	eck
ploop:	mov	e,m	; Load term into DE
	inx	h
	mov	d,m 
	inx	h
	push 	b	; Keep counter 
	push 	h	; Keep pointer
	xchg		; Term in HL
	call	printn	; Print term
	pop 	h	; Restore pointer and counter
	pop 	b
	dcr	b
	jnz	ploop
	lxi	d,nl	; Print a newline afterwards
	jmp	prints
eck:	push	b	; Set HL = &eck[HL]
	lxi	b,ecks	; Base address
	dad	h	; Multiply by two 
	dad	b	; Add base 
	pop	b
	ret
printn:	lxi	d,buf	; Print the number in HL
	push	d	; Buffer pointer on stack
	lxi	b,-10	; Divisor
pdigit:	lxi	d,-1	; Quotient
pdiv:	inx 	d
	dad	b
	jc 	pdiv
	mvi	a,'0'+10
	add	l	; Make ASCII digit
	pop	h
	dcx	h	; Store digit
	mov	m,a
	push 	h
	xchg
	mov	a,h	; Quotient nonzero?
	ora	l
	jnz	pdigit	; Then there are more digits
	pop	d 	; Otherwise, print string using CP/M
prints:	mvi	c,9
	jmp	5
nl:	db	13,10,'$'
	db	'.....'
buf:	db	' $'
ecks:	equ	$