Skip to content

Commit 16cf578

Browse files
committed
implemented atoi, atol, and atoll in assembly
1 parent a494909 commit 16cf578

File tree

6 files changed

+428
-26
lines changed

6 files changed

+428
-26
lines changed

src/libc/atoi.src

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
xor a, '-' - 14
24+
push af
25+
jr z, .minus_sign
26+
xor a, ('+' - 14) xor ('-' - 14)
27+
jr z, .plus_sign
28+
dec hl
29+
.plus_sign:
30+
.minus_sign:
31+
; carry is cleared
32+
ex de, hl
33+
sbc hl, hl
34+
; DE = start of the digits
35+
; HL = 0
36+
jr .start
37+
.loop:
38+
; 21F + 4R + 3W + 1 per digit
39+
push hl
40+
pop bc
41+
add hl, hl ; *= 2
42+
add hl, hl ; *= 4
43+
add hl, bc ; *= 5
44+
add hl, hl ; *= 10
45+
ld bc, 0
46+
ld c, a
47+
add hl, bc
48+
inc de ; next digit
49+
.start:
50+
ld a, (de)
51+
sub a, 48
52+
cp a, 10
53+
jr c, .loop
54+
.finish:
55+
pop af
56+
; carry is cleared
57+
ret nz ; A != '-' positive
58+
; A == '-' negative
59+
jp __ineg
60+
61+
extern __ineg

src/libc/atol.src

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,77 @@
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+
xor a, '-' - 14
24+
push af
25+
jr z, .minus_sign
26+
xor a, ('+' - 14) xor ('-' - 14)
27+
jr z, .plus_sign
28+
dec hl
29+
.plus_sign:
30+
.minus_sign:
31+
; carry is cleared
1432
push hl
15-
call _strtol
16-
pop af
17-
pop af
33+
pop iy
34+
sbc hl, hl
35+
ld e, l
36+
; IY = start of the digits
37+
; E:UHL = 0
38+
jr .start
39+
.loop:
40+
; 32F + 4R + 3W + 1 per digit
41+
ld d, a
42+
ld a, e
43+
push hl
44+
pop bc
45+
; *= 2
46+
add hl, hl
47+
rla
48+
; *= 4
49+
add hl, hl
50+
rla
51+
; *= 5
52+
add hl, bc
53+
adc a, e
54+
; *= 10
55+
add hl, hl
56+
rla
57+
; += digit
58+
ld bc, 0
59+
ld c, d
60+
add hl, bc
61+
adc a, b
62+
ld e, a
63+
; next digit
64+
inc iy
65+
.start:
66+
ld a, (iy)
67+
sub a, 48
68+
cp a, 10
69+
jr c, .loop
70+
.finish:
1871
pop af
19-
ret
72+
; carry is cleared
73+
ret nz ; A != '-' positive
74+
; A == '-' negative
75+
jp __lneg
2076

21-
extern _strtol
77+
extern __lneg

src/libc/atoll.src

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,73 @@
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+
xor a, '-' - 14
25+
push af
26+
jr z, .minus_sign
27+
xor a, ('+' - 14) xor ('-' - 14)
28+
jr z, .plus_sign
29+
dec hl
30+
.plus_sign:
31+
.minus_sign:
32+
; carry is cleared
1333
push hl
14-
call _strtoll
15-
pop af
16-
pop af
34+
pop iy
35+
sbc hl, hl
36+
ex de, hl
37+
sbc hl, hl
38+
ld b, l
39+
ld c, l
40+
push hl
41+
push hl
42+
push hl
43+
; IY = start of the digits
44+
; BC:UDE:UHL = 0
45+
; (ix - 9) = [0, 10]
46+
jr .start
47+
.loop:
48+
; loop : 27F + 1R + 8W + 1
49+
; lladd : ?
50+
; llmulu: ?
51+
; total : a lot per digit
52+
ld (ix - 9), 10
53+
call __llmulu ; BC:UDE:UHL *= 10
54+
ld (ix - 9), a
55+
call __lladd
56+
inc iy ; next digit
57+
.start:
58+
ld a, (iy)
59+
sub a, 48
60+
cp a, 10
61+
jr c, .loop
62+
.finish:
63+
ld sp, ix
1764
pop af
18-
ret
65+
; carry is cleared
66+
pop ix
67+
ret nz ; A != '-' positive
68+
; A == '-' negative
69+
jp __llneg
1970

20-
extern _strtoll
71+
extern __llneg
72+
extern __lladd
73+
extern __llmulu
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/strtol/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)