###########################################################################################
#
#		IME-84 Calculator: Division Subroutine Emulation
#
#
# The main loop of the Divide routine emulates the actions during a number cycle.
# State information at the end of each number cycle is printed.
#
# This file is a python module, not a program.
# Routines can be exercised from the the python interpreter or
# for quick use e.g.:
#
# 	shell! python3 -c 'import IME84; IME84.exdv()'
#
#	2025 Nov: Initial creation / bh
#	
#############################################################################################
### Quick Use Examples

def exdv():
	print( "  divide = {:d}".format(	Divide( 1_000_000,	25	)))

def exdv1():
	print( "  divide = {:d}".format(	Divide( 156545,		133	)))

def exdvpi():
	print( "  divide = {:d}".format(	Divide( 35500000000,	113	)))


#############################################################################################
#############################################################################################
### Utilities

MOD15 = 1000_0000_0000_0000
MOD16 = MOD15 * 10


def EDGE0( n, p ):
	return n==0 and p==1


def SHIFT_UP( r ):
	return (r%MOD15)*10 + r//MOD15


def SHIFT_DN( r ):
	return r//10 + (r%10)*MOD15


def printHeading():
	print( " WK DV1 DV2 PLC PQC D1C KZ: {:>17s} {:>17s} {:>17s} RBX".format("RK","RA","RB") )



#############################################################################################
### Divide

def Divide( dividend, divisor ):
	RA = dividend
	RK = divisor
	RB = 0

	printHeading()

	FPSYNC	= 1
	FPWORK	= 0
	FPDV1	= 0
	FPDV2	= 0
	PLC	= 0
	D1C	= 0
	PQC	= 0
	FDK15Z	= 1

	RBX	= 0
	exit	= 0

	while 1:	# each iteration emulates a number cycle
		##### prep next state

		nFPSYNC = FPSYNC
		nFPWORK = FPWORK
		nFPDV1	= FPDV1
		nFPDV2	= FPDV2
		nPLC	= PLC
		nD1C	= D1C
		nPQC	= PQC

		###### actions

		if FPDV1:
			if FPWORK:
				if FDK15Z: RK = SHIFT_UP( RK )
				FDK15Z = (RK//MOD15)==0
				if not FDK15Z: nFPWORK = 0
			else:
				nPLC += 1

		if FPDV2 and PQC==0:
			RA -= RK
			if RA >= 0:	RBX += 1
			else:		nPQC = 1

		if PQC==1:
			RA += RK
		elif PQC==2:
			if FPDV2: RK = SHIFT_DN( RK )
		elif PQC==3:
			RB  = SHIFT_UP( RB )
			RB += RBX
			RBX = 0

		##### EON ##### phiN 0-edge

		if PQC>0:
			nPQC = (PQC+1)%4

		if PQC==1:
			nPLC = (PLC+1)%16

		if PLC==15 and nPLC==0:
			nFPDV2 = 0

		if PQC==3 and not FPDV2:
			nFPWORK = 0
			exit = 1

		if FPDV1:
			nD1C = (D1C+1)%16
			if nD1C==0:
				nFPDV1 = 0
				nFPDV2 = 1
				nFPWORK = 1

		if FPSYNC:
			nFPSYNC = 0
			nFPWORK = 1
			if FDK15Z:
				nFPDV1 = 1
				nD1C = 1

		##### display state

		print( " {:2d} {:3d} {:3d} {:3d} {:3d} {:3d} {:2d}: {:>17d} {:>17d} {:>17d} {:3d}".format
			(FPWORK,FPDV1,FPDV2,PLC,PQC,D1C,FDK15Z,RK,RA,RB,RBX) )

		##### next state

		FPSYNC	= nFPSYNC
		FPWORK	= nFPWORK
		FPDV1	= nFPDV1
		FPDV2	= nFPDV2
		PLC	= nPLC
		D1C	= nD1C
		PQC	= nPQC

		if exit>0:
			exit += 1
			if exit == 3:
				break

	return RB

### EOF
#############################################################################################
