;
; Ullrich von Bassewitz, 31.05.1998
;
; char* itoa (int value, char* s, int radix);
; char* utoa (unsigned value, char* s, int radix);
;

      	.export		_itoa, _utoa
	.import	     	addysp1
	.import	     	__hextab
	.importzp    	sp, sreg, ptr2, ptr3, tmp1

.rodata
specval:
       	.byte  	'-', '3', '2', '7', '6', '8', 0
.code

;
; Common subroutine to pop the parameters and put them into core
;

dopop: 	sta	tmp1 		; will loose high byte
	ldy	#0
	lda	(sp),y
	sta	ptr2
	sta	ptr3
	iny
	lda	(sp),y
	sta	ptr2+1
	sta	ptr3+1
	iny
	lda	(sp),y
	sta	sreg
	iny
	lda	(sp),y
	sta	sreg+1
	jmp	addysp1		; Bump stack pointer

;
; itoa
;

_itoa:	jsr	dopop		; pop the arguments

; We must handle $8000 in a special way, since it is the only negative
; number that has no positive 16-bit counterpart

	ldy	tmp1  		; get radix
	cpy	#10
	bne	utoa
	cmp	#$00
	bne	L2
	cpx	#$80
	bne	L2

	ldy	#6
L1:	lda	specval,y   	; copy -32768
   	sta	(ptr2),y
    	dey
    	bpl	L1
    	jmp	L10

; Check if the value is negative. If so, write a - sign and negate the
; number.

L2:    	lda    	sreg+1		; get high byte
   	bpl	utoa
	lda	#'-'
	ldy	#0
	sta	(ptr2),y	; store sign
	inc	ptr2
	bne	L3
       	inc	ptr2+1

L3:	lda	sreg
   	eor	#$FF
   	clc
   	adc	#$01
   	sta	sreg
   	lda	sreg+1
   	eor	#$FF
   	adc	#$00
   	sta	sreg+1
	jmp	utoa

;
; utoa
;

_utoa:	jsr	dopop		; pop the arguments

; Convert to string by dividing and push the result onto the stack

utoa:	lda	#$00
   	pha	     		; sentinel

; Divide sreg/tmp1 -> sreg, remainder in a

L5:	ldy	#16 		; 16 bit
  	lda	#0  		; remainder
L6:	asl	sreg
  	rol	sreg+1
  	rol	a
  	cmp	tmp1
  	bcc	L7
  	sbc	tmp1
  	inc	sreg
L7:	dey
  	bne	L6

	tay			; get remainder into y
	lda	__hextab,y	; get hex character
	pha	     		; save char value on stack

   	lda	sreg
   	ora	sreg+1
   	bne	L5

; Get the characters from the stack into the string

	ldy	#0
L9:	pla
  	sta	(ptr2),y
	beq	L10    		; jump if sentinel
	iny
   	bne     L9		; jump always

; Done! Return the target string

L10:	lda	ptr3
       	ldx	ptr3+1
	rts