/*	c80rtl.h, c80 run-time library. */
/*	These are threads used by the compiler */
#asm
;	T i n y  C  l i b r a r y
;
;Fetch a single byte from the address in HL and
; sign extend into HL
ccgchar: LD	A,(HL)
ccsxt:	LD	L,A
	RLCA
	SBC	A,A
	LD	H,A
	RET
;Fetch a full 16-bit integer from the address in HL
ccgint:	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A
	RET
;Store a single byte from HL at the address in DE
ccpchar: LD	A,L
	ld	(DE), A
	RET
;Store a 16-bit integer in HL at the address in DE
ccpint:	LD	A,L
	ld	(DE), A
	INC	DE
	LD	A,H
	LD	(DE), A
	RET
;Inclusive "or" HL and DE into HL
ccor:	LD	A,L
	OR	E
	LD	L,A
	LD	A,H
	OR	D
	LD	H,A
	RET
;Exclusive "or" HL and DE into HL
ccxor:	LD	A,L
	XOR	E
	LD	L,A
	LD	A,H
	XOR	D
	LD	H,A
	RET
;"And" HL and DE into HL
ccand:	LD	A,L
	AND	E
	LD	L,A
	LD	A,H
	AND	D
	LD	H,A
	RET
;Test if HL = DE and set HL = 1 if true else 0
cceq:	CALL	cccmp
	RET Z
	DEC	HL
	RET
;Test if DE != HL
ccne:	CALL	cccmp
	RET	NZ
	DEC	HL
	RET
;Test if DE > HL (signed)
ccgt:	EX DE, HL
	CALL	cccmp
	RET C
	DEC	HL
	RET
;Test if DE <= HL (signed)
ccle:	CALL	cccmp
	RET Z
	RET C
	DEC	HL
	RET
;Test if DE >= HL (signed)
ccge:	CALL	cccmp
	RET NC
	DEC	HL
	RET
;Test if DE < HL (signed)
cclt:	CALL	cccmp
	RET C
	DEC	HL
	RET
;Common routine to perform a signed compare
; of DE and HL
;This routine performs DE - HL and sets the conditions:
;	Carry reflects sign of difference (set means DE < HL)
;	Zero/non-zero set according to equality.
cccmp:	LD	A,E
	SUB	L
	LD	E,A
	LD	A,D
	SBC	A, H
	LD	HL,1	;preset true condition
	JP M,	cccmp1
	OR	E	;"OR" resets carry
	RET
cccmp1:	OR	E
	SCF		;set carry to signal minus
	RET
;
;Test if DE >= HL (unsigned)
ccuge:	CALL	ccucmp
	RET NC
	DEC	HL
	RET	
;
;Test if DE < HL (unsigned)
ccult:	CALL	ccucmp
	RET C
	DEC	HL
	RET
;
;Test if DE > HL (unsigned)
ccugt:	EX DE, HL
	CALL	ccucmp
	RET C
	DEC	HL
	RET
;
;Test if DE <= HL (unsigned)
ccule:	CALL	ccucmp
	RET Z
	RET C
	DEC	HL
	RET
;
;Common routine to perform unsigned compare
;carry set if DE < HL
;zero/nonzero set accordingly
ccucmp:	LD	A,D
	CP	H
	JP NZ,	.+5
	LD	A,E
	CP	L
	LD	HL,1
	RET
;
;Shift DE arithmetically right by HL and return in HL
ccasr:	EX DE, HL
	LD	A,H
	RLA
	LD	A,H
	RRA
	LD	H,A
	LD	A,L
	RRA
	LD	L,A
	DEC	E
	JP NZ,	ccasr+1
	RET
;Shift DE arithmetically left by HL and return in HL
ccasl:	EX DE, HL
	ADD	HL,HL
	DEC	E
	JP NZ,	ccasl+1
	RET
;Subtract HL from DE and return in HL
ccsub:	LD	A,E
	SUB	L
	LD	L,A
	LD	A,D
	SBC	A,H
	LD	H,A
	RET
;Form the two's complement of HL
ccneg:	CALL	cccom
	INC	HL
	RET
;Form the one's complement of HL
cccom:	LD	A,H
	CPL
	LD	H,A
	LD	A,L
	CPL
	LD	L,A
	RET
;Multiply DE by HL and return in HL
ccmult:	LD	B,H
	LD	C,L
	LD	HL,0
ccmul1: LD	A,C
	RRCA
	JP NC,	.+4
	ADD	HL,DE
	XOR	A
	LD	A,B
	RRA
	LD	B,A
	LD	A,C
	RRA
	LD	C,A
	OR	B
	RET Z
	XOR	A
	LD	A,E
	RLA
	LD	E,A
	LD	A,D
	RLA
	LD	D,A
	OR	E
	RET Z
	JP	ccmul1
;Divide DE by HL and return quotient in HL, remainder in DE
ccdiv:	LD	B,H
	LD	C,L
	LD	A,D
	XOR	B
	PUSH	AF
	LD	A,D
	OR	A
	CALL M,	ccdeneg
	LD	A,B
	OR	A
	CALL M,	ccbcneg
	LD	A,16
	PUSH	AF
	EX	DE, HL
	LD	DE,0
ccdiv1:	ADD	HL,HL
	CALL	ccrdel
	JP Z,	ccdiv2
	CALL	cccmpbcde
	JP M,	ccdiv2
	LD	A,L
	OR	1
	LD	L,A
	LD	A,E
	SUB	C
	LD	E,A
	LD	A,D
	SBC	A,B
	LD	D,A
ccdiv2:	POP	AF
	DEC	A
	JP Z,	ccdiv3
	PUSH	AF
	JP	ccdiv1
ccdiv3:	POP	AF
	RET P
	CALL	ccdeneg
	EX DE, HL
	CALL	ccdeneg
	EX DE, HL
	RET
ccdeneg: LD	A,D
	CPL
	LD	D,A
	LD	A,E
	CPL
	LD	E,A
	INC	DE
	RET
ccbcneg: LD	A,B
	CPL
	LD	B,A
	LD	A,C
	CPL
	LD	C,A
	INC	BC
	RET
ccrdel:	LD	A,E
	RLA
	LD	E,A
	LD	A,D
	RLA
	LD	D,A
	OR	E
	RET
cccmpbcde: LD	A,E
	SUB	C
	LD	A,D
	SBC	A,B
	RET
#endasm
