Skip to content

Commit 698ee2d

Browse files
committed
implemented atoi, atol, and atoll in assembly
1 parent 61f79f9 commit 698ee2d

File tree

6 files changed

+431
-26
lines changed

6 files changed

+431
-26
lines changed

src/libc/atoi.src

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public _atoi
6+
7+
_atoi:
8+
pop de
9+
ex (sp), hl
10+
push de
11+
; inlined isspace
12+
.whitespace_loop:
13+
ld a, (hl)
14+
inc hl
15+
cp a, 32
16+
jr z, .whitespace_loop
17+
sub a, 9
18+
add a, -5
19+
jr nc, .whitespace_loop
20+
21+
; A = (HL - 1) - 9 + -5
22+
; A = (HL - 1) - 14
23+
sub a, '-' - 14
24+
push af
25+
jr z, .minus_sign
26+
; A = (HL - 1) - 14 - ('-' - 14)
27+
; A = (HL - 1) - '-'
28+
xor a, '+' - '-'
29+
jr z, .plus_sign
30+
dec hl
31+
.plus_sign:
32+
.minus_sign:
33+
; carry is clear
34+
ex de, hl
35+
sbc hl, hl
36+
; DE = start of the digits
37+
; HL = 0
38+
jr .start
39+
.loop:
40+
; 21F + 4R + 3W + 1 per digit
41+
push hl
42+
pop bc
43+
add hl, hl ; *= 2
44+
add hl, hl ; *= 4
45+
add hl, bc ; *= 5
46+
add hl, hl ; *= 10
47+
ld bc, 0
48+
ld c, a
49+
add hl, bc
50+
inc de ; next digit
51+
.start:
52+
ld a, (de)
53+
sub a, 48
54+
cp a, 10
55+
jr c, .loop
56+
.finish:
57+
pop af
58+
ret nz ; A != '-' positive
59+
; A == '-' negative
60+
jp __ineg
61+
62+
extern __ineg

src/libc/atol.src

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,78 @@
11
assume adl=1
22

33
section .text
4-
public _atoi, _atol
5-
_atoi:
4+
5+
public _atol
6+
67
_atol:
7-
pop bc
8-
ex (sp),hl
9-
push bc
10-
ld bc,10
11-
push bc
12-
ld c,b
13-
push bc
8+
pop de
9+
ex (sp), hl
10+
push de
11+
; inlined isspace
12+
.whitespace_loop:
13+
ld a, (hl)
14+
inc hl
15+
cp a, 32
16+
jr z, .whitespace_loop
17+
sub a, 9
18+
add a, -5
19+
jr nc, .whitespace_loop
20+
21+
; A = (HL - 1) - 9 + -5
22+
; A = (HL - 1) - 14
23+
sub a, '-' - 14
24+
push af
25+
jr z, .minus_sign
26+
; A = (HL - 1) - 14 - ('-' - 14)
27+
; A = (HL - 1) - '-'
28+
xor a, '+' - '-'
29+
jr z, .plus_sign
30+
dec hl
31+
.plus_sign:
32+
.minus_sign:
33+
; carry is clear
1434
push hl
15-
call _strtol
16-
pop af
17-
pop af
35+
pop iy
36+
sbc hl, hl
37+
ld e, l
38+
; IY = start of the digits
39+
; E:UHL = 0
40+
jr .start
41+
.loop:
42+
; 32F + 4R + 3W + 1 per digit
43+
ld d, a
44+
ld a, e
45+
push hl
46+
pop bc
47+
; *= 2
48+
add hl, hl
49+
rla
50+
; *= 4
51+
add hl, hl
52+
rla
53+
; *= 5
54+
add hl, bc
55+
adc a, e
56+
; *= 10
57+
add hl, hl
58+
rla
59+
; += digit
60+
ld bc, 0
61+
ld c, d
62+
add hl, bc
63+
adc a, b
64+
ld e, a
65+
; next digit
66+
inc iy
67+
.start:
68+
ld a, (iy)
69+
sub a, 48
70+
cp a, 10
71+
jr c, .loop
72+
.finish:
1873
pop af
19-
ret
74+
ret nz ; A != '-' positive
75+
; A == '-' negative
76+
jp __lneg
2077

21-
extern _strtol
78+
extern __lneg

src/libc/atoll.src

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,74 @@
11
assume adl=1
22

33
section .text
4+
45
public _atoll
6+
57
_atoll:
6-
pop bc
7-
ex (sp),hl
8-
push bc
9-
ld bc,10
10-
push bc
11-
ld c,b
12-
push bc
8+
push ix
9+
ld ix, -3
10+
add ix, sp
11+
ld hl, (ix + 9)
12+
; inlined isspace
13+
.whitespace_loop:
14+
ld a, (hl)
15+
inc hl
16+
cp a, 32
17+
jr z, .whitespace_loop
18+
sub a, 9
19+
add a, -5
20+
jr nc, .whitespace_loop
21+
22+
; A = (HL - 1) - 9 + -5
23+
; A = (HL - 1) - 14
24+
sub a, '-' - 14
25+
push af
26+
jr z, .minus_sign
27+
; A = (HL - 1) - 14 - ('-' - 14)
28+
; A = (HL - 1) - '-'
29+
xor a, '+' - '-'
30+
jr z, .plus_sign
31+
dec hl
32+
.plus_sign:
33+
.minus_sign:
34+
; carry is clear
1335
push hl
14-
call _strtoll
15-
pop af
16-
pop af
36+
pop iy
37+
sbc hl, hl
38+
ex de, hl
39+
sbc hl, hl
40+
ld b, l
41+
ld c, l
42+
push hl
43+
push hl
44+
push hl
45+
; IY = start of the digits
46+
; BC:UDE:UHL = 0
47+
; (ix - 9) = [0, 10]
48+
jr .start
49+
.loop:
50+
; loop : 27F + 1R + 8W + 1
51+
; lladd : ?
52+
; llmulu: ?
53+
; total : a lot per digit
54+
ld (ix - 9), 10
55+
call __llmulu ; BC:UDE:UHL *= 10
56+
ld (ix - 9), a
57+
call __lladd
58+
inc iy ; next digit
59+
.start:
60+
ld a, (iy)
61+
sub a, 48
62+
cp a, 10
63+
jr c, .loop
64+
.finish:
65+
ld sp, ix
1766
pop af
18-
ret
67+
pop ix
68+
ret nz ; A != '-' positive
69+
; A == '-' negative
70+
jp __llneg
1971

20-
extern _strtoll
72+
extern __llneg
73+
extern __lladd
74+
extern __llmulu

test/standalone/atol/autotest.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"transfer_files": [
3+
"bin/DEMO.8xp"
4+
],
5+
"target": {
6+
"name": "DEMO",
7+
"isASM": true
8+
},
9+
"sequence": [
10+
"action|launch",
11+
"delay|1000",
12+
"hashWait|1",
13+
"key|enter",
14+
"delay|300",
15+
"hashWait|2"
16+
],
17+
"hashes": {
18+
"1": {
19+
"description": "All tests passed",
20+
"timeout": 5000,
21+
"start": "vram_start",
22+
"size": "vram_16_size",
23+
"expected_CRCs": [
24+
"38E2AD5A"
25+
]
26+
},
27+
"2": {
28+
"description": "Exit",
29+
"start": "vram_start",
30+
"size": "vram_16_size",
31+
"expected_CRCs": [
32+
"FFAF89BA",
33+
"101734A5",
34+
"9DA19F44",
35+
"A32840C8",
36+
"349F4775"
37+
]
38+
}
39+
}
40+
}

test/standalone/atol/makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
ARCHIVED = NO
10+
11+
CFLAGS = -ffreestanding -Wall -Wextra -Wshadow -Wconversion -Wformat=2 -Wno-sign-conversion -Oz
12+
CXXFLAGS = -ffreestanding -Wall -Wextra -Wshadow -Wconversion -Wformat=2 -Wno-sign-conversion -Oz
13+
14+
PREFER_OS_LIBC = NO
15+
PREFER_OS_CRT = NO
16+
17+
# ----------------------------
18+
19+
include $(shell cedev-config --makefile)

0 commit comments

Comments
 (0)