# gcc -nostdlib -nostdinc -Wl,--oformat,binary,-Ttext,0x7c00 bootet.s
# [up]    rotate
# [left]  move left
# [right] move right
# [space] drop
# [enter] restart after gameover

	.code16
	bss=0x8000
	seed=0x8000
	score=0x8010
	curbr=0x8014
	curxy=curbr+2
	nextbr=0x8018
	timer=0x8020
	.text
_start:	.global	_start
	jmp	1f
gameover:
	mov	$25*80-2, %di
	mov	$0x07b1, %ax
	std
3:	scasw
	jnb	2f
	inc	%di
	inc	%di
	stosw
2:	test	%di, %di
	jns	3b
	sti
2:	mov	$0, %ah
	int	$0x16
	cmp	$13, %al
	jne	2b
1:	xor	%ax, %ax
	mov	%ax, %ss
	mov	%ax, %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
	mov	$24*80+22, %cx
	rep	stosb
	not	%ax
	mov	$10, %cl
	rep	stosw
1:	stosw
	mov	%ax, %es:-24(%di)
	sub	$82, %di
	jnb	1b
main3:	call	clearlines
	movb	$0x04, curxy-curbr(%si)
main2:	mov	%es:8*80+64-8, %al
	aaa
	mov	%al, timer
main:	call	wrblkc
	jne	gameover
	call	wrblks
wait:	incw	seed
	mov	$1, %ah
	int	$0x16
	mov	%sp, %ax
	jnz	1f
	cmpb	$0x9, timer
	ja	2f
	sti
	hlt
	cli
	mov	%ax, 0x1c*4+2
	movw	$int0x1c, 0x1c*4+0
	jmp	wait
1:	int	$0x16
2:	call	wrblks
	mov	$curxy+1, %si
	test	%ax, %ax
	je	movedown
	cmp	$' ', %al
	jne	1f
drop:	decb	(%si)
	addw	$1, score-(curxy+1)(%si)
	adcw	%cx, score+2-(curxy+1)(%si)
	call	wrblkc
	je	drop
putit:	incb	(%si)
	call	wrblks
	jmp	main3
movedown:
	decb	(%si)
	call	wrblkc
	je	main2
	jmp	putit
1:	inc	%ax
	dec	%si
	cmp	$77, %ah
	ja	main
	je	move
	neg	%al
	cmp	$72, %ah
	jb	main
	ja	move
	dec	%si
move:	addb	%al, (%si)
	call	wrblkc
	je	main
	subb	%al, (%si)
	jmp	main
clearlines:
	cld
	mov	$100, %bx
	mov	$23*80+22, %di
	mov	$0x800, %ax
	push	%di
2:	mov	$10, %cl
	push	%di
1:	inc	%di
	scasb
	loopne	1b
	pop	%di
	je	1f
	add	%bx, score-(curxy+1)(%si)
	adc	%cx, score+2-(curxy+1)(%si)
	shl	%bx
	push	%di
	mov	$10, %cl
	mov	$0xdb, %al
	rep	stosw
	mov	$0, %al
	pop	%di
1:	sub	$80, %di
	jnb	2b
	pop	%di
2:	cmp	%ah, %es:1(%di)
	jne	3f
	mov	%al, timer
	sti
1:	hlt
	cmpb	$4, timer
	jb	1b
	cli
	push	%di
	lea	-80(%di), %si
1:	push	%si
	mov	$10, %cl
	rep
	es
	movsw
	pop	%di
	sub	$80+20, %si
	jnb	1b
	pop	%di
	jmp	2b
3:	sub	$80, %di
	jnb	2b
getnext:
	# 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+64, %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
	test	%ax, %ax
	jne	2f
	test	%si, %si
2:	loopne	1b
	mov	$curbr, %si
	movw	$0x1610, curxy-curbr(%si)
	pop	%ax
	mov	%ax, (%si)
	xchg	%ax, nextbr-curbr(%si)
	call	wrblks
	mov	%ax, (%si)
	test	%ax, %ax
	je	getnext
wrblks:
	stc
	.byte	0xb1	# mov $imm, %cl
wrblkc:
	clc
wrblk:
	push	%ax
	mov	curbr, %ax
	sbb	%dx, %dx
	and	$0xdb, %dh
	and	%al, %dl
	mov	$blkdata-9, %bx
	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
	jne	1f
	xchg	%ah, %al
	neg	%al
1:	test	$2, %bh
	jne	1f
	neg	%al
	neg	%ah
1:	add	$16+1, %al
	sar	%al
	sar	%ah
	add	curxy, %ax
1:	mov	$25*80+23-16, %di
1:	sub	$80, %di
	dec	%ah
	jne	1b
	add	%ax, %di
	add	%ax, %di
	orb	%dh, %es:-1(%di)
1:	xor	%dl, %es:(%di)
	je	1f
	inc	%bx
1:	loop	2b
	cmp	%cl, %bl
	pop	%ax
	ret
int0x1c:
	incb	%cs:timer
	iret

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

	.org	510
	.byte	0x55, 0xaa
