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
|
; cprintul.s - print an unsigned long, int, or char
; Modified from cc65's libsrc/common/ltoa.s
; Originally by Ullrich von Bassewitz, 11.06.1998
; modified version by B. Watson
; - print the characters with cputs instead of storing in a buffer
; - rename ultoa => cprintul, change its prototype
; - add cprintuchar and cprintuint wrappers
; - got rid of ltoa (don't need it)
; - hardcode radix to 10
; - don't need __hextab since we don't do hex (saves 16 bytes)
; - get rid of dopop subroutine, since the return type is now
; void, and we don't take a buffer argument that needs returning.
; void __fastcall__ cprintul(unsigned long value);
.export _cprintulong, _cprintuchar, _cprintuint
.import popax, _cputc
.importzp sreg, ptr2
radix = 10
.ifdef CART_TARGET
.segment "HIGHCODE"
.else
.code
.endif
; char and int wrappers for cprintulong(). basically these are
; the 'casting' code cc65 would emit any time cprintulong() is
; called with a char or int argument. it happens often enough in
; taipan.c that it's worth doing this way:
; cprintulong(1) compiles to 11 bytes:
; ldx #$00
; stx sreg
; stx sreg+1
; lda #$01
; jsr _cprintulong
; whereas cprintuchar(1) is 5 bytes (saves 6):
; lda #$01
; jsr _cprintuchar
; cprintuint(1) is 7 bytes (saves 4, add 'ldx #$00' to the above).
; the wrappers are 10 bytes together. so long as we remember to *use*
; them, we only have to use cprintuchar() 2 times and/or cprintuint()
; 3 times to start saving bytes.
_cprintuchar:
ldx #0
_cprintuint:
pha
lda #0
sta sreg
sta sreg+1
pla
; main routine
_cprintulong:
; high word passed to us in sreg
; low word in ptr2
sta ptr2
stx ptr2+1
; Convert to string by dividing and push the result onto the stack
lda #$00
pha ; sentinel
; Divide val/radix -> val, remainder in a
L5: ldy #32 ; 32 bit
lda #0 ; remainder
L6: asl ptr2
rol ptr2+1
rol sreg
rol sreg+1
rol a
cmp #radix
bcc L7
sbc #radix
inc ptr2
L7: dey
bne L6
ora #'0' ; get ascii character
pha ; save char value on stack
lda ptr2
ora ptr2+1
ora sreg
ora sreg+1
bne L5
; Get the characters from the stack, print them.
@print: pla
beq @done ; exit if sentinel
pha
jsr _cputc
pla
bne @print ; branch always
@done:
rts
|