# gcc -nostdlib -nostdinc -Wl,--oformat,binary,-Ttext,0x7c00 bootet.s

	.code16
	bss=0x8000
	seed=0x8000
	score=0x8010
	curbr=0x8014
	curxy=curbr+2
	nextbr=0x8018
	timer=0x8020
	.text
_start:	.global	_start
	xor	%ax, %ax
	mov	%ax, %ss
	mov	$0xfffe, %sp
	mov	%ax, %ds
	mov	%ax, %es
	mov	$bss, %di
	mov	%di, %cx
	cld
	rep	stosb
	inc	%ax
	int	$0x10
	mov	$0xb800, %ax
	mov	%ax, %es
	cld
	xor	%di, %di
	mov	$80*25, %cx
	rep	stosb
	call	getnext
	call	getnext
main2:	mov	score+1, %ax
	mov	%ax, timer
main:	call	wrblkc
	jc	gameover
	call	wrblks
wait:	sti
	hlt
	cli
	xor	%ax, %ax
	incw	seed
	mov	%ax, 0x1c*4+2
	movw	$int0x1c, 0x1c*4+0
	cmpw	$0xa0, timer
	ja	2f
1:	mov	$1, %ah
	int	$0x16
	jz	wait
	mov	$0, %ah
	int	$0x16
2:	call	wrblks
	mov	$curxy+1, %bx
	test	%ax, %ax
	je	movedown
	cmp	$' ', %al
	je	drop
	inc	%ax
	dec	%bx
	cmp	$75, %ah
	je	move
	neg	%al
	cmp	$77, %ah
	je	move
	dec	%bx
	cmp	$72, %ah
	jne	main
move:	subb	%al, (%bx)
	call	wrblkc
	jnc	main
	addb	%al, (%bx)
	jmp	main
gameover:
	hlt
	jmp	gameover
drop:	decb	(%bx)
	addw	$1, score-(curxy+1)(%bx)
	adcw	%cx, score+2-(curxy+1)(%bx)
	call	wrblkc
	jnc	drop
putit:	incb	(%bx)
	call	wrblks
	call	clearlines
1:	jmp	main2
movedown:
	decb	(%bx)
	call	wrblkc
	jc	putit
	jmp	1b
wrblks:
	stc
	.byte	0xb1	# mov $imm, %cl
wrblkc:
	clc
wrblk:
	push	%ax
	push	%bx
	mov	curbr, %ax
	sbb	%dx, %dx
	and	%ax, %dx
	mov	$4, %cl
	shl	%cl, %dl
	mov	$blkdata-9, %bx
	test	%ax, %ax
	je	wrblk_
	xlatb
	xchg	%ax, %bx
	mov	$4, %al
	shr	%bl
	sbb	%ah, %ah
	shr	%bl
	jp	1f
	dec	%ax
	push	%ax
1:	adc	$0, %al
	mov	$3, %cx
2:	sub	$2, %al
	shr	%bl
	jnc	1f
	push	%ax
1:	loop	2b
	add	$2, %ah
2:	shr	%bl
	jnc	1f
	push	%ax
1:	add	$2, %al
	jno	2b
	mov	$4, %cl
2:	pop	%ax
	test	$1, %bh
	je	1f
	xchg	%ah, %al
	neg	%al
1:	test	$2, %bh
	je	1f
	neg	%al
	neg	%ah
1:	add	$1, %al
	sar	%al
	sar	%ah
	add	curxy+0, %al
	add	curxy+1, %ah
	test	%dl, %dl
	jne	1f
	cmp	$10, %al
	jae	3f
	cmp	$25, %ah
	jae	3f
1:	mov	$25*80+1, %di
1:	sub	$80, %di
	dec	%ah
	jns	1b
	cbw
	add	%ax, %di
	add	%ax, %di
	xor	%dl, %es:(%di)
	je	1f
3:	inc	%dh
1:	loop	2b
wrblk_:	neg	%dh
	pop	%bx
	pop	%ax
	ret
clearlines:
	cld
	mov	$100, %si
	mov	$25*80, %di
	push	%di
2:	sub	$80, %di
	jb	3f
	mov	$10, %cl
	xor	%ax, %ax
	push	%di
1:	inc	%di
	scasb
	loopne	1b
	pop	%di
	je	2b
	add	%si, score
	adc	%cx, score+2
	shl	%si
	push	%di
	mov	$0x80, %ah
	mov	$10, %cl
	rep	stosw
	pop	%di
	jmp	2b
3:	pop	%di
3:	sub	$80, %di
	jb	getnext
2:	push	%di
	mov	$0x80, %al
	inc	%di
	scasb
	pop	%di
	jne	3b
	movb	$-0x40, timer
	sti
1:	hlt
	cmp	%cl, timer
	js	1b
	cli
	push	%di
	lea	-80(%di), %si
1:	mov	$10, %cl
	rep
	es
	movsw
	sub	$80+20, %di
	sub	$80+20, %si
	jnb	1b
	xor	%ax, %ax
	mov	$10, %cl
	rep	stosw
	pop	%di
	jmp	2b
getnext:
	pushw	nextbr
	# rand
	mov	$0, %ah
	int	$0x1a
	add	%dx, seed
	mov	seed, %ax
	xor	%dx, %dx
	mov	$0x7, %cl
	div	%cx
	mov	%al, %dh
	add	$9, %dl
	push	%dx
	# print score
	mov	score, %si
	mov	score+2, %ax
	mov	$8*80+38, %di
	std
	mov	$10, %cl
	mov	%cx, %bx
1:	xor	%dx, %dx
	div	%bx
	xchg	%ax, %si
	div	%bx
	xchg	%ax, %si
	xchg	%ax, %dx
	add	$0x0730, %ax
	stosw
	xchg	%ax, %dx
	loop	1b
	mov	$curbr, %bx
	movw	$0x150e, curxy-curbr(%bx)
	pop	%ax
	mov	%ax, (%bx)
	mov	%ax, nextbr-curbr(%bx)
	call	wrblks
	popw	(%bx)
	call	wrblks
	movb	$0x04, curxy-curbr(%bx)
	ret
int0x1c:
	addw	$0x10, %cs:timer
	iret

blkdata:
	.byte	0x7b, 0xd9, 0x9c, 0x1c, 0x6d, 0x3c, 0x5c

	.org	510
	.byte	0x55, 0xaa
