1
2; ===============================================================
3; Jan 2014
4; ===============================================================
5;
6; int _strtoi(const char *nptr, char **endptr, int base)
7;
8; Read number encoded in given radix from string; if base == 0,
9; radix is auto-detected as decimal, octal or hex.
10;
11; 16-bit version of strtol.
12;
13; ===============================================================
14
15SECTION code_clib
16SECTION code_stdlib
17
18PUBLIC asm__strtoi
19
20EXTERN __strtou__, error_erange_mc, error_erange_zc, error_einval_zc
21
22asm__strtoi:
23
24   ; enter : bc = int base
25   ;         de = char **endp
26   ;         hl = char *nptr
27   ;
28   ; exit  : *endp = de as detailed below
29   ;
30   ;         no error:
31   ;
32   ;           carry reset
33   ;             hl = int result
34   ;             de = char *nptr (& next unconsumed char)
35   ;
36   ;         invalid input string or base:
37   ;
38   ;           carry set
39   ;             de = initial char *nptr
40   ;             hl = 0
41   ;           errno set to EINVAL
42   ;
43   ;         overflow:
44   ;
45   ;           carry set
46   ;             de = char *nptr (& next unconsumed char following oversized number)
47   ;             hl = $7fff (INT_MAX) or $8000 (INT_MIN)
48   ;           errno set to ERANGE
49   ;
50   ; uses  : af, bc, de, hl
51
52   call __strtou__
53   jr c, check_errors
54
55   ; unsigned conversion was successful but signed
56   ; number range is narrower so must check again
57
58   dec a
59   ret z                       ; negative result is in range
60
61   bit 7,h                     ; if most significant bit of positive number
62   ret z                       ;   is set we are out of range
63
64positive_overflow:
65
66   call error_erange_mc
67   ld h,$7f                    ; hl = $7fff = INT_MAX
68   ret
69
70check_errors:
71
72   ; what kind of error was it
73
74   dec a
75   jp m, error_einval_zc       ; on invalid base or invalid string
76
77   ; overflow occurred
78
79   dec a
80   jr z, positive_overflow
81
82   call error_erange_zc
83   ld h,$80                    ; hl = $8000 = INT_MIN
84   ret
85