	PAGE	,132
	TITLE	Powers of Ten
IF1
INCLUDE 87MAC.LIB
ENDIF
STACK	SEGMENT STACK
	DW	64 DUP(?)
STACK	ENDS
CODE	SEGMENT
	ASSUME	CS:CODE
POWER_OF_TEN	DD	?		; Data area for 10**x, short real
OUTPUT_POWER	DB	2 DUP(' ')      ; Buffer for power value
		DB	'H    '
OUTPUT_STRING	DB	8 DUP(' ')      ; Hexadecimal string output
		DB	'H',13,10,'$'   ; String ending
POWER		DB	0		; Current power of ten
THOUSAND	DW	1000		; Constant
CONTROL_87	DW	03BFH
CALCULATE_POWER PROC	FAR
	PUSH	DS			;Set return address
	MOV	AX,0
	PUSH	AX
	PUSH	CS
	POP	DS
	ASSUME	DS:CODE 		; Addressing to data area
	FLDCW	CONTROL_87
	FILD	THOUSAND		; Load 10**3
	FLD1				; Load starting value
POWER_LOOP:
	FMUL	ST1			; Multiply st0 * st1
	FST	POWER_OF_TEN		; Store into ram
	ADD	POWER,3 		; Update power of ten
	MOV	AL,POWER		; Get power
	MOV	BX,OFFSET OUTPUT_POWER
	CALL	TRANSLATE
	MOV	CX,4
	MOV	BX,OFFSET OUTPUT_STRING
	MOV	SI,OFFSET POWER_OF_TEN+3
	STD				; Backwards
VALUE_OUTPUT:
	LODSB				; Get byte of power
	CALL	TRANSLATE		; Write to output string
	LOOP	VALUE_OUTPUT		; Do it for all bytes of string

	MOV	DX,OFFSET OUTPUT_POWER
	MOV	AH,9
	INT	21H
	CMP	POWER,38
	JB	POWER_LOOP
	FSTP	POWER_OF_TEN
	FSTP	POWER_OF_TEN
	RET
CALCULATE_POWER ENDP

TRANSLATE	PROC	NEAR
	PUSH	AX
	PUSH	CX
	MOV	CL,4
	SHR	AL,CL
	POP	CX
	CALL	XLAT_OUTPUT
	POP	AX
	CALL	XLAT_OUTPUT
	RET
TRANSLATE	ENDP

ASCII_TABLE	DB	'0123456789ABCDEF'
XLAT_OUTPUT	PROC	NEAR
	AND	AL,0FH
	PUSH	BX
	MOV	BX,OFFSET ASCII_TABLE
	XLAT	ASCII_TABLE
	POP	BX
	MOV	[BX],AL
	INC	BX
	RET
XLAT_OUTPUT	ENDP
CODE	ENDS
	END	CALCULATE_POWER
