org 100h			
	
	jmp start

p1win:	db 'Player 1 wins!'
p2win:	db 'Player 2 wins!'
anykey:	db 'Press any key to exit.'

start:	
	mov si, sp
	sub si, 2
	
	push 0
%define ball_x ss:si
	push 0
%define ball_y ss:si-2
	push 1
%define ball_dx ss:si-4
	push 1
%define ball_dy ss:si-6

	push 100
%define p1_y ss:si-8
	push 100
%define p2_y ss:si-10
	push 0
%define p1_dy ss:si-12
	push 0
%define p2_dy ss:si-14
	
	push 0
%define winner ss:si-16
	
	;; set graphics mode 13
	mov ax, 0x13
	int 10h
  	mov ax, 0xa000
  	mov es, ax

loop1:	

	;; sync to vertical refresh
	mov dx, 0x03da
waitin:	
	in al, dx
	test al, 8
	jnz waitin
waitout:
	in al, dx
	test al, 8
	jz waitout
	
	
	;; erase ball
	mov bx, [ball_x]
	mov ax, [ball_y]

	mov dx, 320
	mul dx	
	add bx, ax
	mov byte [es:bx], 0x00
	
	
	;; move ball
	mov bx, [ball_x]
	mov ax, [ball_y]

	add bx, [ball_dx]
	add ax, [ball_dy]
	mov [ball_x], bx
	mov [ball_y], ax
	
	;; bounce ball
	cmp bx, 319
	jl dont_hit_p2

	cmp ax, [p2_y]
	jl p2_lose
	mov dx, [p2_y]
	add dx, 20
	cmp ax, dx
	jg p2_lose
	;; survive
	neg word [ball_dx]
	jmp flip_x_done
p2_lose:
	mov word [winner], 1
	jmp done
dont_hit_p2:	
	
	cmp bx, 0
	jg dont_hit_p1

	cmp ax, [p1_y]
	jl p1_lose
	mov dx, [p1_y]
	add dx, 20
	cmp ax, dx
	jg p1_lose
	;; survive
	neg word [ball_dx]
	jmp flip_x_done
p1_lose:
	mov word [winner], 2
	jmp done
dont_hit_p1:	
flip_x_done:	

	cmp ax, 199
	jge flip_y
	cmp ax, 0
	jle flip_y
	jmp skip_flip_y
flip_y:	
	neg word [ball_dy]
skip_flip_y:

	;; draw ball
	mov dx, 320
	mul dx	
	add bx, ax
	mov byte [es:bx], 0x0F
	
	;; erase player 1 paddle
	mov cx, [p1_y]
	add cx, 20
	
lx1_erase:	
	mov bx, 0
	mov ax, cx
	mov dx, 320
	mul dx	
	add bx, ax
	mov byte [es:bx], 0x00
	
	dec cx
	cmp cx, [p1_y]
	jne lx1_erase
	
	;; move player 1 paddle
	mov ax, [p1_y]
	add ax, [p1_dy]
	cmp ax, 0
	jge ok11
	mov ax, 0
	mov word [p1_dy], 0
ok11:	cmp ax, 179
	jle ok12
	mov ax, 179
	mov word [p1_dy], 0
ok12:	mov [p1_y], ax
	
	;; draw player 1 paddle
	mov cx, [p1_y]
	add cx, 20
	
lx1:	
	mov bx, 0
	mov ax, cx
	mov dx, 320
	mul dx	
	add bx, ax
	mov byte [es:bx], 0x0F
	
	dec cx
	cmp cx, [p1_y]
	jne lx1
	
	;; erase player 2 paddle
	mov cx, [p2_y]
	add cx, 20
p	
lx2_erase:	
	mov bx, 319
	mov ax, cx
	mov dx, 320
	mul dx	
	add bx, ax
	mov byte [es:bx], 0x00
	
	dec cx
	cmp cx, [p2_y]
	jne lx2_erase
	
	;; move player 2 paddle
	mov ax, [p2_y]
	add ax, [p2_dy]
	cmp ax, 0
	jge ok21
	mov ax, 0
	mov word [p2_dy], 0
ok21:	cmp ax, 179
	jle ok22
	mov ax, 179
	mov word [p2_dy], 0
ok22:	mov [p2_y], ax
	
	;; draw player 2 paddle
	mov cx, [p2_y]
	add cx, 20
	
lx2:	
	mov bx, 319
	mov ax, cx
	mov dx, 320
	mul dx	
	add bx, ax
	mov byte [es:bx], 0x0F
	
	dec cx
	cmp cx, [p2_y]
	jne lx2
	
	
	;; check keyboard status
	in al, 0x60
	;; escape quits
	cmp al, 1
	je done
	
	;; a to move p1 up
	cmp al, 0x1e
	jne key1
	mov word [p1_dy], -1
	jmp key_done
key1:
	cmp al, 0x9e
	jne key2
	mov word [p1_dy], 0
	jmp key_done
key2:	
	;; z to move p1 down
	cmp al, 0x2c
	jne key3
	mov word [p1_dy], 1
	jmp key_done
key3:
	cmp al, 0xac
	jne key4
	mov word [p1_dy], 0
	jmp key_done
key4:
	;; ' to move p2 up
	cmp al, 0x28
	jne key5
	mov word [p2_dy], -1
	jmp key_done
key5:
	cmp al, 0xa8
	jne key6
	mov word [p2_dy], 0
	jmp key_done
key6:
	;; / to move p2 down
	cmp al, 0x35
	jne key7
	mov word [p2_dy], 1
	jmp key_done
key7:
	cmp al, 0xb5
	jne key8
	mov word [p2_dy], 0
	jmp key_done
key8:	

key_done:	
	

	;; clear key buffer
clear_key:	
	mov ah, 1
	int 16h
	jz clear_key_done
	mov ah, 0
	int 16h
	jmp clear_key
clear_key_done:	
	
next:	
	jmp loop1

done:	
  	;; set text mode
  	mov ax, 3h
  	int 10h
	mov ax, 0xB800
	mov es, ax

	cmp word [winner], 1
	jne foo
	mov dx, p1win
	jmp bar
foo:	mov dx, p2win
bar:

	mov cx, 14
	mov si, dx
	mov bx, 0
print_loop:
	mov al, [ds:si]
	mov [es:bx], al
	add bx, 2
	inc si
	loop print_loop

	mov cx, 22
	mov si, anykey
	mov bx, 160
print_loop2:	
	mov al, [ds:si]
	mov [es:bx], al
	add bx, 2
	inc si
	loop print_loop2

	;; move cursor
	mov ah, 2
	mov bh, 0
	mov dh, 2
	mov dl, 0
	int 10h

  	;; wait for keypress
  	mov ah, 0
  	int 16h
	
  	;; set text mode again
  	mov ax, 3h
  	int 10h
	
	int 20h

