File: itoa.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (146 lines) | stat: -rw-r--r-- 2,881 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
;
; 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