.EQU PRECISION, 0x30

.EQU cout, 0x7D
.EQU cin, 0x7F

.ORG 0x8000
	MOV SP, #0x40
	MOV A, #10
intro_loop:
	MOV R0, A
	MOVC A, @A + PC
	LCALL cout ;3B
	MOV A, R0 ;1B
	INC A ;1B
	CJNE A, #10 + 15, intro_loop ;3B
	SJMP init ;2B

.DB "RPN Calc v1.0\n\r"

init:
	MOV PRECISION, #4
	MOV DPL, #0
	MOV DPH, #0xFF

start:
	MOV A, #'\r'
	LCALL cout
	MOV A, #'\n'
	LCALL cout
	MOV A, #'>'
	LCALL cout
in_loop:
	LCALL cin

	CJNE A, #'+', *+6
	LJMP op_add

	CJNE A, #'.', *+6
	LJMP op_disp

	CJNE A, #'*', *+6
	LJMP op_mult

	CJNE A, #'/', *+6
	LJMP op_div

	CJNE A, #'s', *+6
	LJMP op_show_stack

	CJNE A, #'x', *+6
	LJMP op_xchg

	CJNE A, #'?', *+6
	LJMP op_help
	
	CJNE A, #'p', *+6
	LJMP op_chng_prec

	CJNE A, #'-', *+6
	LJMP in_neg_loop 

	SUBB A, #'0'
	JZ in_zero_digit
	JC in_loop
	
	CJNE A, #10, *+3
	JNC in_loop
in_zero_digit:
	mov R4, A
	mov A, #'+'
	LCALL cout
	CLR 0
in_digit:
	SETB 1
	MOV R0, #0xFF
	mov R5, #0
	mov R6, #0
	mov R7, #0

	mov A, R4
	ADD A, #'0'
	LCALL cout

in_digit_loop:
	LCALL cin

	CJNE A, #0x7F, *+6; BACKSPACE
	LJMP in_digit_abort
	CJNE A, #0x1B, *+6; ESC
	LJMP in_digit_abort

	CJNE A, #',', *+6
	LJMP in_digit_shift	

	CJNE A, #'\n', *+6
	LJMP in_digit_end
	SUBB A, #'0'
	JC in_digit_loop
	CJNE A, #10, *+3
	JNC in_digit_loop

	MOV B, A
	ADD A, #'0'
	LCALL  cout 
	LCALL left_dshift_32
	JZ *+5
	LJMP in_digit_err

	CLR C
	MOV A, R4
	ADDC A, B
	MOV R4, A
	MOV A, R5
	ADDC A, #0
	MOV R5, A
	MOV A, R6
	ADDC A, #0
	MOV R6, A
	MOV A, R7
	ADDC A, #0
	MOV R7, A
	ANL A, #0x80

	JZ *+5
	LJMP in_digit_err
	
	DJNZ R0, *+5
	LJMP in_digit_end

	LJMP in_digit_loop

in_digit_shift:
	MOV A, #','
	LCALL cout
	JNB 1, in_digit_loop
	CLR 1
	MOV R0, PRECISION
	MOV A, R0
	JNZ in_digit_loop
	
in_digit_end:
	JNB 1, in_digit_shift_loop
	MOV R0, PRECISION
in_digit_shift_loop:
	MOV A, R0
	JZ in_digit_out
	DEC R0
	LCALL left_dshift_32
	JNZ in_digit_err
	SJMP in_digit_shift_loop

in_digit_out:
	JNB 0, in_digit_to_start
	MOV A, R7
	ORL A, #0x80
	MOV R7, A
in_digit_to_start:
	LCALL store_num
	LJMP start
in_digit_err:
	MOV A, #'E'
	LCALL cout
	MOV A, #'R'
	LCALL cout
	MOV A, #'R'
	LCALL cout
	LJMP start

in_digit_abort:
	MOV A, #'A'
	LCALL cout
	MOV A, #'B'
	LCALL cout
	MOV A, #'O'
	LCALL cout
	MOV A, #'R'
	LCALL cout
	MOV A, #'T'
	LCALL cout
	LJMP start

in_neg_loop:
	LCALL cout
	LCALL cin
	CJNE A, #'\n', *+6
	LJMP op_sub
	SUBB A, #'0'
	JZ in_neg_zero_digit
	JC in_neg_loop

	CJNE A, #10, *+3
	JNC in_neg_loop
in_neg_zero_digit:
	mov R4, A
	SETB 0
	LJMP in_digit

help_end:
	LJMP start
op_help:
	MOV R0, #6
help_loop:
	INC R0
	MOV A, R0
	MOVC A, @A+PC
	JZ help_end ;2B
	LCALL cout ;3B
	SJMP help_loop ;2B
	.DB "\r\nRPN Calc v1.0 Help:\r\n+ - add\r\n- - subtract\r\n* - multiply\r\n/ - divide\r\np - change Precision\r\nx - eXchange numbers\r\ns - show Stack\r\n. - pop from stack\r\n", 0

op_xchg:
	MOV A, #'x'
	LCALL cout
	LCALL retr_num
	MOV 8, R4
	MOV 9, R5
	MOV 10, R6
	MOV 11, R7
	LCALL retr_num
	MOV 12, R4
	MOV 13, R5
	MOV 14, R6
	MOV 15, R7
	MOV R4, 8
	MOV R5, 9
	MOV R6, 10
	MOV R7, 11
	LCALL store_num
	MOV R4, 12
	MOV R5, 13
	MOV R6, 14
	MOV R7, 15
	LCALL store_num
	LJMP start

op_chng_prec:
	MOV A, #'p'
	LCALL cout
	
	LCALL cin
	SUBB A, #'0'
	JC op_chng_prec_err
	CJNE A, #10, *+3
	JNC op_chng_prec_err
	
	MOV PRECISION, A
	ADD A, #'0'
	LCALL cout
	LJMP start

op_chng_prec_err:
	LJMP start


op_show_stack:
	MOV A, #'s'
	LCALL cout

	MOV A, DPL
	MOV B, A

show_stack_loop:
	MOV A, DPL
	JZ show_stack_end
	DEC DPL

	MOV A, #'\r'
	LCALL cout
	MOV A, #'\n'
	LCALL cout
	
	MOVX A, @DPTR
	MOV R7, A
	DEC DPL
	
	MOVX A, @DPTR
	MOV R6, A
	DEC DPL
	
	MOVX A, @DPTR
	MOV R5, A
	DEC DPL
	
	MOVX A, @DPTR
	MOV R4, A
	
	LCALL display_num
	SJMP show_stack_loop

show_stack_end:
	MOV A, B
	MOV DPL, A
	LJMP start

op_add:
	MOV A, #'+'
	LCALL cout
	MOV A, #'\r'
	LCALL cout
	MOV A, #'\n'
	LCALL cout

	LCALL retr_num
	MOV 8, R4
	MOV 9, R5
	MOV 10, R6
	MOV 11, R7
	LCALL retr_num
	
	MOV A, R7
	XRL A, 11
	ANL A, #0x80
	JZ add_num
	LJMP sub_num

add_num:	
	MOV A, 11
	ANL A, #0x7F
	MOV 11, A

	MOV A, R7
	ANL A, #0x80
	JZ *+6
	SETB 0
	SJMP *+4
	CLR 0
	MOV A, R7
	ANL A, #0x7F
	MOV R7, A

	CLR C
	MOV A, R4
	ADDC A, 8
	MOV R4, A
	MOV A, R5
	ADDC A, 9
	MOV R5, A
	MOV A, R6
	ADDC A, 10
	MOV R6, A
	MOV A, R7
	ADDC A, 11
	MOV R7, A
	
	ANL A, #0x80
	JZ *+4
	SJMP add_overflow
	
	JNB 0, *+7
	MOV A, R7
	ORL A, #0x80
	MOV R7, A

	LCALL display_num
	LCALL store_num

	LJMP start

add_overflow:
	MOV A, #'E'
	LCALL cout
	MOV A, #'R'
	LCALL cout
	MOV A, #'R'
	LCALL cout
	LJMP start

op_sub:	; OP1 - OP2
	MOV A, #'-'
	LCALL cout
	MOV A, #'\r'
	LCALL cout
	MOV A, #'\n'
	LCALL cout

	LCALL retr_num ;OP2 -> (8,9,10,11)
	MOV 8, R4
	MOV 9, R5
	MOV 10, R6
	MOV 11, R7
	LCALL retr_num ;OP1 -> (R4, R5, R6, R7)
	
	MOV A, R7 ; CHECK SIGN != -> ADD : (+) - (-) -> (+) + (+) / (-) - (+) -> (-) + (-)
	XRL A, 11
	ANL A, #0x80
	JNZ add_num

sub_num:
	MOV A, R7 ; SIGN OF OP1 -> b0
	ANL A, #0x80
	JZ *+6
	SETB 0
	SJMP *+4
	CLR 0
	
	MOV A, R7 ; STRIP SIGN OFF OP
	ANL A, #0x7F
	MOV R7, A
	MOV A, 11
	ANL A, #0x7F
	MOV 11, A

sub_num_sub:
	CLR C
	MOV A, R4
	SUBB A, 8
	MOV R0, A
	MOV A, R5
	SUBB A, 9
	MOV R1, A
	MOV A, R6
	SUBB A, 10
	MOV R2, A
	MOV A, R7
	SUBB A, 11
	MOV R3, A
	
	JNC sub_num_end
	MOV A, R4
	MOV R4, 8
	MOV 8, A
	MOV A, R5
	MOV R5, 9
	MOV 9, A
	MOV A, R6
	MOV R6, 10
	MOV 10, A
	MOV A, R7
	MOV R7, 11
	MOV 11, A

	JB 0, *+6
	SETB 0
	SJMP sub_num_sub
	CLR 0
	SJMP sub_num_sub	

sub_num_end:
	MOV A, R0
	MOV R4, A
	MOV A, R1
	MOV R5, A
	MOV A, R2
	MOV R6, A
	MOV A, R3
	MOV R7, A
	JNB 0, *+7
	MOV A, R7
	ORL A, #0x80
	MOV R7, A

	LCALL display_num
	LCALL store_num

	LJMP start


op_mult:
	MOV A, #'*'
	LCALL cout
	MOV A, #'\r'
	LCALL cout
	MOV A, #'\n'
	LCALL cout

	LCALL retr_num
	MOV 8, R4
	MOV 9, R5
	MOV 10, R6
	MOV 11, R7
	MOV 12, #0
	MOV 13, #0
	MOV 14, #0
	MOV 15, #0
	MOV 16, #0
	MOV 17, #0
	MOV 18, #0
	MOV 19, #0
	MOV 20, #0
	MOV 21, #0
	MOV 22, #0
	MOV 23, #0
	LCALL retr_num
	
	MOV A, R7
	XRL A, 11
	ANL A, #0x80
	JNZ *+6
	CLR 0
	SJMP *+4
	SETB 0
	
	MOV A, R7
	ANL A, #0x7F
	MOV R7, A
	MOV A, 11
	ANL A, #0x7F
	MOV 11, A

	MOV R0, #32
	
mult_loop:
	CLR C
	MOV A, R7
	RRC A
	MOV R7, A
	
	MOV A, R6
	RRC A
	MOV R6, A
	
	MOV A, R5
	RRC A
	MOV R5, A
	
	MOV A, R4
	RRC A
	MOV R4, A

	JNC mult_loop_skip

	CLR C

	MOV A, 16
	ADDC A, 8
	MOV 16, A

	MOV A, 17
	ADDC A, 9
	MOV 17, A

	MOV A, 18
	ADDC A, 10
	MOV 18, A

	MOV A, 19
	ADDC A, 11
	MOV 19, A

	MOV A, 20
	ADDC A, 12
	MOV 20, A

	MOV A, 21
	ADDC A, 13
	MOV 21, A

	MOV A, 22
	ADDC A, 14
	MOV 22, A

	MOV A, 23
	ADDC A, 15
	MOV 23, A

mult_loop_skip:
	CLR C
	
	MOV A, 8
	RLC A
	MOV 8, A

	MOV A, 9
	RLC A
	MOV 9, A

	MOV A, 10
	RLC A
	MOV 10, A
	
	MOV A, 11
	RLC A
	MOV 11, A
	
	MOV A, 12
	RLC A
	MOV 12, A
	
	MOV A, 13
	RLC A
	MOV 13, A
	
	MOV A, 14
	RLC A
	MOV 14, A
	
	MOV A, 15
	RLC A
	MOV 15, A

	DJNZ R0, mult_loop

	LCALL bin_2_bcd_u64

	JB 0, *+7
	MOV A, #'+'
	SJMP *+4
	MOV A, #'-'
	LCALL cout

	MOV R0, #6
	MOV A, #20
	SUBB A, PRECISION
	SUBB A, PRECISION
	MOV R1, A
mul_disp_loop:
	MOV A, @R0
	ANL A, #0xF0
	SWAP A
	ADD A, #'0'
	LCALL cout
	DEC R1
	MOV A, R1
	JNZ *+7
	MOV A, #','
	LCALL cout

	MOV A, @R0
	ANL A, #0x0F
	ADD A, #'0'
	LCALL cout
	DEC R1
	MOV A, R1
	JNZ *+7
	MOV A, #','
	LCALL cout

	INC R0
	CJNE R0, #16, mul_disp_loop

	MOV A, PRECISION 
mul_full_step:
	SUBB A, #2
	JC mul_half_step
	MOV 15, 14
	MOV 14, 13
	MOV 13, 12
	MOV 12, 11
	MOV 11, 10
	MOV 10, 9
	MOV 9, 8
	MOV 8, 7
	MOV 7, 6
	MOV 6, #0
	SJMP mul_full_step

mul_half_step:
	ADD A, #1
	JNZ mul_end
	
	MOV A, 15
	ANL A, #0xF0
	SWAP A
	MOV 15, A

	MOV R1, #14
mul_half_loop:
	MOV A, @R1
	SWAP A
	ANL A, #0xF0
	MOV R0, A
	INC R1
	MOV A, @R1
	ADD A, R0
	MOV @R1, A
	DEC R1
	MOV A, @R1
	SWAP A
	ANL A, #0x0F
	MOV @R1, A
	DEC R1
	CJNE R1, #6, mul_half_loop

	MOV A, 6
	SWAP A
	ANL A, #0x0F
	MOV 6, A

mul_end:
	MOV R0, #10
mul_check_over:
	MOV A, @R0
	JNZ mul_overflow
	DEC R0
	CJNE R0, #5, mul_check_over 
	SJMP mul_save

mul_overflow:
	MOV A, #'O'
	LCALL cout
	MOV A, #'V'
	LCALL cout
	MOV A, #'E'
	LCALL cout
	MOV A, #'R'
	LCALL cout
mul_save:
	LCALL bcd_2_bin_u32

	JNB 0, *+7 ;3B
	MOV A, R7 ;1B
	ORL A, #0x80 ;2B
	MOV R7, A ;1B

	LCALL store_num

	LJMP start

op_div:
	MOV A, #'/'
	LCALL cout

	LCALL retr_num
	MOV 23, #0
	MOV 22, #0
	MOV 21, #0
	MOV 20, #0
	MOV 19, R4
	MOV 18, R5
	MOV 17, R6
	MOV 16, R7
	LCALL retr_num
	MOV 15, R4
	MOV 14, R5
	MOV 13, R6
	MOV 12, R7
	MOV 11, #0
	MOV 10, #0
	MOV 9, #0
	MOV 8, #0

	MOV R4, #0
	MOV R5, #0
	MOV R5, #0
	MOV R6, #0

	MOV A, 12
	XRL A, 16
	ANL A, #0x80
	JNZ *+6
	CLR 0
	SJMP *+4
	SETB 0

	MOV A, 16
	ANL A, #0x7F
	MOV 16, A
	MOV A, 12
	ANL A, #0x7F
	MOV 12, A

	MOV R0, PRECISION
	MOV A, R0
	JZ div_start
div_start_mult:
	LCALL left_dshift_64
	DJNZ R0, div_start_mult

div_start:

	MOV R1, #32
div_loop:
	MOV A, 8
	CJNE A, 16, div_ne
	MOV A, 9
	CJNE A, 17, div_ne
	MOV A, 10
	CJNE A, 18, div_ne
	MOV A, 11
	CJNE A, 19, div_ne
	MOV A, 12
	CJNE A, 20, div_ne
	MOV A, 13
	CJNE A, 21, div_ne
	MOV A, 14
	CJNE A, 22, div_ne
	MOV A, 15
	CJNE A, 23, div_ne

div_ne:
	JC div_shift
	INC R7
	
	CLR C	
	MOV 15, A
	SUBB A, 23
	MOV A, 15
	MOV A, 14
	SUBB A, 22
	MOV 14, A
	MOV A, 13
	SUBB A, 21
	MOV 13, A
	MOV A, 12
	SUBB A, 20
	MOV 12, A
	MOV A, 11
	SUBB A, 19
	MOV 11, A
	MOV A, 10
	SUBB A, 18
	MOV 10, A
	MOV A, 9
	SUBB A, 17
	MOV 9, A
	MOV A, 8
	SUBB A, 16
	MOV 8, A

div_shift:
	CLR C
	MOV A, 7
	RLC A
	MOV 7, A
	MOV A, 6
	RLC A
	MOV 6, A
	MOV A, 5
	RLC A
	MOV 5, A
	MOV A, 4
	RLC A
	MOV 4, A

	CLR C
	MOV A, 16
	RRC A
	MOV 16, A
	MOV A, 17
	RRC A
	MOV 17, A
	MOV A, 18
	RRC A
	MOV 18, A
	MOV A, 19
	RRC A
	MOV 19, A
	MOV A, 20
	RRC A
	MOV 20, A
	MOV A, 21
	RRC A
	MOV 21, A
	MOV A, 22
	RRC A
	MOV 22, A
	MOV A, 23
	RRC A
	MOV 23, A

	DJNZ R1, div_long_loop

	MOV A, R4
	XCH A, R7
	MOV R4, A
	MOV A, R5
	XCH A, R6
	MOV R5, A

	JNB 0, *+7
	MOV A, R7
	ORL A, #0x80
	MOV R7, A

	LCALL display_num
	LCALL store_num
	
	LJMP start
div_long_loop:
	LJMP div_loop

left_dshift_64: ;(8-15)*10
	CLR C
	MOV A, 15
	RLC A
	MOV 15, A
	MOV A, 14
	RLC A
	MOV 14, A
	MOV A, 13
	RLC A
	MOV 13, A
	MOV A, 12
	RLC A
	MOV 12, A
	MOV A, 11
	RLC A
	MOV 11, A
	MOV A, 10
	RLC A
	MOV 10, A
	MOV A, 9
	RLC A
	MOV 9, A
	MOV A, 8
	RLC A
	MOV 8, A

	CLR C
	MOV A, 15
	RLC A
	MOV 31, A
	MOV A, 14
	RLC A
	MOV 30, A
	MOV A, 13
	RLC A
	MOV 29, A
	MOV A, 12
	RLC A
	MOV 28, A
	MOV A, 11
	RLC A
	MOV 27, A
	MOV A, 10
	RLC A
	MOV 26, A
	MOV A, 9
	RLC A
	MOV 25, A
	MOV A, 8
	RLC A
	MOV 24, A

	CLR C
	MOV A, 31
	RLC A
	MOV 31, A
	MOV A, 30
	RLC A
	MOV 30, A
	MOV A, 29
	RLC A
	MOV 29, A
	MOV A, 28
	RLC A
	MOV 28, A
	MOV A, 27
	RLC A
	MOV 27, A
	MOV A, 26
	RLC A
	MOV 26, A
	MOV A, 25
	RLC A
	MOV 25, A
	MOV A, 24
	RLC A
	MOV 24, A

	CLR C
	MOV A, 15
	ADDC A, 31
	MOV 15, A 
	MOV A, 14
	ADDC A, 30
	MOV 14, A
	MOV A, 13
	ADDC A, 29
	MOV 13, A
	MOV A, 12
	ADDC A, 28
	MOV 12, A
	MOV A, 11
	ADDC A, 27
	MOV 11, A
	MOV A, 10
	ADDC A, 26
	MOV 10, A
	MOV A, 9
	ADDC A, 25
	MOV 9, A
	MOV A, 8
	ADDC A, 24
	MOV 8, A
	RET

bcd_2_bin_u32: ;(11-15) -> (R4, R5, R6, R7)
	MOV 16, #0
	MOV 17, #0
	MOV 18, #0
	MOV 19, #0
	
	MOV R1, #32
bi2bc32_loop:
	CLR C
	MOV A, 11
	RRC A
	MOV 11, A
	MOV A, 12
	RRC A
	MOV 12, A
	MOV A, 13
	RRC A
	MOV 13, A
	MOV A, 14
	RRC A
	MOV 14, A
	MOV A, 15
	RRC A
	MOV 15, A
	MOV A, 16
	RRC A
	MOV 16, A
	MOV A, 17
	RRC A
	MOV 17, A
	MOV A, 18
	RRC A
	MOV 18, A
	MOV A, 19
	RRC A
	MOV 19, A

	MOV R0, #11
bi2bc32_sub_loop:
	MOV A, @R0
	ANL A, #0x0F
	CLR C
	SUBB A, #8
	JC *+6
	MOV A, @R0
	SUBB A, #3
	MOV @R0, A

	MOV A, @R0
	ANL A, #0xF0
	SWAP A
	CLR C
	SUBB A, #5
	JC *+6
	MOV A, @R0
	SUBB A, #0x30
	MOV @R0, A
	
	INC R0
	CJNE R0, #16, bi2bc32_sub_loop

	DJNZ R1, bi2bc32_loop

	MOV R4, 19
	MOV R5, 18
	MOV R6, 17
	MOV R7, 16
	RET

bin_2_bcd_u64: ;(16-23) -> (6-15)
	MOV 6, #0
	MOV 7, #0
	
	MOV 8, #0
	MOV 9, #0
	MOV 10, #0
	MOV 11, #0
	MOV 12, #0
	MOV 13, #0
	MOV 14, #0
	MOV 15, #0

	MOV A, 23	
	XCH A, 16
	MOV 23, A

	MOV A, 22	
	XCH A, 17
	MOV 22, A

	MOV A, 21	
	XCH A, 18
	MOV 21, A

	MOV A, 20	
	XCH A, 19
	MOV 20, A

	MOV R1, #64
b2bu64_loop:
	MOV R0, #15
b2bu64_add_loop:
	MOV A, @R0
	ANL A, #0x0F
	CLR C
	SUBB A, #5
	JC *+6 ;2B
	MOV A, @R0 ;1B
	ADD A, #3 ;2B
	MOV @R0, A ;1B

	MOV A, @R0
	ANL A, #0xF0
	SWAP A
	CLR C
	SUBB A, #5
	JC *+6
	MOV A, @R0
	ADD A, #0x30
	MOV @R0, A

	DEC R0
	CJNE R0, #5, b2bu64_add_loop
	
	CLR C
	MOV A, 23
	RLC A
	MOV 23, A 
	MOV A, 22
	RLC A
	MOV 22, A 
	MOV A, 21
	RLC A
	MOV 21, A 
	MOV A, 20
	RLC A
	MOV 20, A 
	MOV A, 19
	RLC A
	MOV 19, A 
	MOV A, 18
	RLC A
	MOV 18, A 
	MOV A, 17
	RLC A
	MOV 17, A 
	MOV A, 16
	RLC A
	MOV 16, A 
	MOV A, 15
	RLC A
	MOV 15, A 
	MOV A, 14
	RLC A
	MOV 14, A 
	MOV A, 13
	RLC A
	MOV 13, A 
	MOV A, 12
	RLC A
	MOV 12, A 
	MOV A, 11
	RLC A
	MOV 11, A 
	MOV A, 10
	RLC A
	MOV 10, A 
	MOV A, 9
	RLC A
	MOV 9, A 
	MOV A, 8
	RLC A
	MOV 8, A 
	MOV A, 7
	RLC A
	MOV 7, A 
	MOV A, 6
	RLC A
	MOV 6, A 

	DJNZ R1, b2bu64_loop
	RET

op_disp:
	mov A, #'.'
	LCALL cout
	LCALL retr_num
	LCALL display_num
	LJMP start

store_num:
	MOV A, DPL
	CJNE A, #0xFC, *+5
	SJMP store_num_err
	MOV A, R4
	MOVX @DPTR, A
	INC DPTR
	
	MOV A, R5
	MOVX @DPTR, A
	INC DPTR

	MOV A, R6
	MOVX @DPTR, A
	INC DPTR

	MOV A, R7
	MOVX @DPTR, A
	INC DPTR

	RET

store_num_err:
	MOV A, #9
store_err_loop:
	MOV R0, A
	MOVC A, @A + PC
	LCALL cout ;3B
	MOV A, R0 ;1B
	INC A ;1B
	CJNE A, #9 + 17, store_err_loop ;3B	
	RET ;1B
	.DB "Stack overflow!\r\n"
	

retr_num:
	MOV A, DPL
	JZ retr_err
	DEC DPL
	
	MOVX A, @DPTR
	MOV R7, A
	DEC DPL
	
	MOVX A, @DPTR
	MOV R6, A
	DEC DPL
	
	MOVX A, @DPTR
	MOV R5, A
	DEC DPL
	
	MOVX A, @DPTR
	MOV R4, A

	RET

retr_err:
	MOV R4, #0
	MOV R5, #0
	MOV R6, #0
	MOV R7, #0
	MOV A, #9
retr_err_loop:
	MOV R0, A
	MOVC A, @A + PC
	LCALL cout ;3B
	MOV A, R0 ;1B
	INC A ;1B
	CJNE A, #9 + 18, retr_err_loop ;3B	
	RET ;1B
	.DB "Stack underflow!\r\n"

.EQU R0_B1, 8
.EQU R1_B1, 9
.EQU R2_B1, 10
.EQU R3_B1, 11
.EQU R4_B1, 12

display_num: ;(R4, R5, R6, R7)
	MOV A, R7
	ANL A, #0x80
	JZ *+6 ;2B
	MOV A, #'-' ;2B
	SJMP *+4 ;2B
	MOV A, #'+'
	LCALL cout
	MOV 16, R4
	MOV 17, R5
	MOV 18, R6
	MOV 19, R7
	MOV A, R7
	ANL A, #0x7F
	MOV R7, A
	MOV R0, #12
	MOV R1, #32
dn_clr:	
	MOV @R0, #0
	DEC R0
	CJNE R0, #0x07, dn_clr  
dn_shift:
	MOV A, R4
	CLR C
	RLC A
	MOV R4, A
	MOV A, R5
	RLC A
	MOV R5, A
	MOV A, R6
	RLC A
	MOV R6, A
	MOV A, R7
	RLC A
	MOV R7, A
	
	MOV A, R0_B1
	RLC A
	MOV R0_B1, A
	MOV A, R1_B1
	RLC A
	MOV R1_B1, A
	MOV A, R2_B1
	RLC A
	MOV R2_B1, A
	MOV A, R3_B1
	RLC A
	MOV R3_B1, A
	MOV A, R4_B1
	RLC A
	MOV R4_B1, A
;SCAN
	DJNZ R1, *+4
	sjmp dn_end
	MOV R0, #12
scan:
	MOV A, @R0
	ANL A, #0x0F
	CLR C
	SUBB A, #5
	JC scan_lower_ok
	MOV A, @R0
	ADD A, #3
	MOV @R0, A
scan_lower_ok:
	MOV A, @R0
	SWAP A
	ANL A, #0x0F
	CLR C
	SUBB A, #5
	JC scan_upper_ok
	MOV A, @R0
	ADD A , #0x30
	MOV @R0, A
scan_upper_ok:
	DEC R0
	CJNE R0, #7, scan
	
	sjmp dn_shift
dn_end:
	MOV A, #10
	SUBB A, PRECISION
	MOV R1, A
	MOV R0, #0x0C
dn_show:
	MOV A, @R0
	SWAP A
	ANL A, #0x0F
	ADD A, #0x30
	LCALL cout
	DEC R1
	MOV A, R1
	JNZ *+7
	MOV A, #','
	LCALL cout
	
	MOV A, @R0
	ANL A, #0x0F
	ADD A, #0x30
	LCALL cout
	DEC R0
	DEC R1
	MOV A, R1
	JNZ *+7
	MOV A, #','
	LCALL cout
	CJNE R0, #0x07, dn_show

	MOV R4, 16
	MOV R5, 17
	MOV R6, 18
	MOV R7, 19

	RET

left_dshift_32: ;(R4, R5, R6, R7)*10 : A -> 0 SUCCESS, ELSE OVERFLOW
	CLR C
	MOV A, R4
	RLC A
	MOV R4, A
	MOV A, R5
	RLC A
	MOV R5, A
	MOV A, R6
	RLC A
	MOV R6, A
	MOV A, R7
	RLC A
	MOV R7, A
	ANL A, #0x80
	JZ *+3
	RET

	CLR C
	MOV A, R4
	RLC A
	MOV 8, A
	MOV A, R5
	RLC A
	MOV 9, A
	MOV A, R6
	RLC A
	MOV 10, A
	MOV A, R7
	RLC A
	MOV 11, A
	ANL A, #0x80
	JZ *+3
	RET
	
	CLR C
	MOV A, 8
	RLC A
	MOV 8, A
	MOV A, 9
	RLC A
	MOV 9, A
	MOV A, 10
	RLC A
	MOV 10, A
	MOV A, 11
	RLC A
	MOV 11, A
	ANL A, #0x80
	JZ *+3
	RET
		
	CLR C
	MOV A, R4
	ADDC A, 8
	MOV R4, A
	MOV A, R5
	ADDC A, 9
	MOV R5, A
	MOV A, R6
	ADDC A, 10
	MOV R6, A
	MOV A, R7
	ADDC A, 11
	MOV R7, A
	ANL A, #0x80
	RET
