init:
	LDIU $A, 0
	LDIL $A, 0
	STDR $A					# Initialize $DR to 0
	
	STDSI 0					# Everything is on Page 0
	SETII INT0, getInput	# Set INT0
	SETII INT1, performTask	# Set INT1
	EI
	
loopForever:				# Everything is INT driven
	JP loopForever
	

getInput:				# Interrupt #0
	DI					# Disable interrupts
	LDDS $D				# Preserve DS

#	LDIU $A, 0			# Create bitmask
#	LDIL $A, 15			# 00..001111
	
	STDSI 255			# Switch to I/O page
	LD $B, (0)			# Get data
#	AND $B, $A			# Mask it off
	
#	LDDR $A				# Get current $DR

#	SLLI $A, 4			# Shift left 4 bits
#	ANDI $A, 240			# Bitmask ..11110000
#	OR $A, $B			# Concat input

#	STDR $A				# Update $DR
	STDR $B
	
	STDS $D				# Restore DS
	EI					# Enable interrupts
	RET					# Return


performTask:			# Interrupt #1
	DI					# Disable interrupts
	LDDS $D				# Preserve DS

	LDIU $B, 0
	LDIL $B, 2			# Initialize divisor

	LDDR $A				# Retrieve value to work on
	
	STDSI 0				# Return DS to this page
	
	CPI $A, 0			# If zero, do nothing
	JP NEQ, mainLoop
	
	STDS $D				# Restore DS
	EI					# Enable interrupts
	RET					# Return
	
mainLoop:
	PUSH $A				# Preserve
	PUSH $B
	
	CALL GCD			# $A = GCD($A, $B)
	
	CPI $A, 1			# If $A = 1, we're done
	JP EQ, mainDone
	
	POP $B				# Retrieve
	POP $A
	
	ADDI $B, 1			# Advance divisor
	
	JP mainLoop			# Loop forever
	
mainDone:
	POP $B				# Retrive Divisor
	POP $A				# Cleanup Stack

	STDSI 255			# Store result onto the
	ST (0), $B			# the I/O page
	STDR $B				# and $DR

	STDS $D				# Restore DS
	EI					# Enable interrupts
	RET					# We're done, return


# $A = GCD($A, $B)
GCD:
	CPI $B,0			# If divisor is zero, we're done
	JP GT, GCDCont
	RET
	
GCDCont:	
	CP $B, $A			# If B > A, swap the order
	JP GT, GCDSwap

GCDnoSwap:
	SUB $A, $B			# $A = $A - $B
	JP GCD				# Repeat
	
GCDSwap:
	LDR $C, $A			# SWAP $A, $B
	LDR $A, $B
	LDR $B, $C
	JP GCD				# Repeat
