mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
strtol!
This commit is contained in:
parent
97e52b65bb
commit
bdb36e2864
9
ka/crt/chr/ctype.k
Normal file
9
ka/crt/chr/ctype.k
Normal file
@ -0,0 +1,9 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; bool isdigit(int c)
|
||||
;
|
||||
isdigit:
|
||||
ret
|
||||
|
@ -1,7 +1,8 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
include "crt/fmt/itoa.k"
|
||||
include "crt/fmt/ltostr.k"
|
||||
include "crt/fmt/strtol.k"
|
||||
include "crt/fmt/doprnt.k"
|
||||
include "crt/fmt/printf.k"
|
||||
|
||||
|
@ -5,14 +5,25 @@
|
||||
; void itoa(char *buf, int num, int base)
|
||||
;
|
||||
itoa:
|
||||
mov ax3, 1
|
||||
jmp ltostr
|
||||
|
||||
;
|
||||
; void utoa(char *buf, int num, int base)
|
||||
;
|
||||
sub ax3, ax3
|
||||
jmp ltostr
|
||||
|
||||
;
|
||||
; void ltostr(char *buf, int num, int base, bool signed)
|
||||
;
|
||||
ltostr:
|
||||
mov rax, ax0
|
||||
xor lx0, lx0
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
|
||||
cmp ax2, 2
|
||||
j.b .bad
|
||||
|
||||
cmp ax2, 36
|
||||
j.a .bad
|
||||
|
||||
@ -22,7 +33,8 @@ itoa:
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
cmp ax2, 10 ; base 10
|
||||
test ax3, ax3
|
||||
cmp.nz ax2, 10 ; base 10
|
||||
j.nz .conv
|
||||
|
||||
sgn lx0, ax1 ; extract ax1 sign
|
||||
@ -70,7 +82,6 @@ itoa:
|
||||
;
|
||||
; exceptional cases
|
||||
;
|
||||
|
||||
.bad:
|
||||
mov q[errno], EINVAL
|
||||
mov b[ax0], 0
|
170
ka/crt/fmt/strtol.k
Normal file
170
ka/crt/fmt/strtol.k
Normal file
@ -0,0 +1,170 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; int strtol(const char *str, int base)
|
||||
;
|
||||
; rax = integer extracted from str
|
||||
; rdx = pointer to first invalid byte
|
||||
;
|
||||
strtol:
|
||||
mov ax2, 1
|
||||
jmp strtoq
|
||||
|
||||
;
|
||||
; int strtoul(const char *str, int base)
|
||||
;
|
||||
; rax = integer extracted from str
|
||||
; rdx = pointer to first invalid byte
|
||||
;
|
||||
strtoul:
|
||||
sub ax2, ax2
|
||||
jmp strtoq
|
||||
|
||||
;
|
||||
; int strtoq(const char *str, int base, bool signed)
|
||||
;
|
||||
; guesses base when 'base'=0
|
||||
;
|
||||
strtoq:
|
||||
xor rax, rax
|
||||
mov rdx, ax0
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
cmp ax1, 1
|
||||
j.z .bad
|
||||
cmp ax1, 36
|
||||
j.a .bad
|
||||
|
||||
; empty string?
|
||||
cmp b[rdx], 0
|
||||
jmp.z .done
|
||||
|
||||
.skip_spc:
|
||||
cmp b[rdx], ' '
|
||||
inc.z rdx
|
||||
jmp.z .skip_spc
|
||||
|
||||
; skip +
|
||||
cmp b[rdx], '+'
|
||||
inc.z rdx
|
||||
|
||||
; signed?
|
||||
test ax2, ax2
|
||||
sub.z lx1, lx1
|
||||
jmp.z .unsigned
|
||||
|
||||
; parse '-'
|
||||
cmp b[rdx], '-'
|
||||
inc.z rdx
|
||||
mov.z lx1, 1
|
||||
sub.nz lx1, lx1
|
||||
|
||||
.unsigned:
|
||||
; base 0
|
||||
test ax1, ax1
|
||||
jmp.z .base_0
|
||||
|
||||
; base prefix?
|
||||
cmp b[rdx], '0'
|
||||
jmp.nz .main_loop
|
||||
|
||||
inc rdx
|
||||
|
||||
; string is "0"
|
||||
cmp b[rdx], 0
|
||||
jmp.z .done
|
||||
|
||||
; "0x" prefix
|
||||
cmp b[rdx], 'x'
|
||||
jmp.z .parsed_0x
|
||||
|
||||
; "0b" prefix
|
||||
cmp b[rdx], 'b'
|
||||
jmp.z .parsed_0b
|
||||
|
||||
; may be octal, but we don't care
|
||||
; we accept "0110101010" (binary) for instance
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0x:
|
||||
; are we in base 16?
|
||||
; if not, leave rax = 0 and *rdx = 'x'
|
||||
cmp ax1, 16
|
||||
jmp.nz .done
|
||||
; else
|
||||
inc rdx
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0b:
|
||||
; are we in base 2?
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
cmp ax1, 2
|
||||
jmp.nz .done
|
||||
; else
|
||||
inc rdx
|
||||
jmp .main_loop
|
||||
|
||||
.base_0:
|
||||
; guess base
|
||||
|
||||
cmp b[rdx], '0'
|
||||
mov.nz ax1, 10
|
||||
jmp.nz .main_loop
|
||||
inc rdx
|
||||
|
||||
cmp b[rdx], 'x'
|
||||
inc.z rdx
|
||||
mov.z ax1, 16
|
||||
jmp.z .main_loop
|
||||
|
||||
cmp b[rdx], 'b'
|
||||
inc.z rdx
|
||||
mov.z ax1, 2
|
||||
jmp.z .main_loop
|
||||
|
||||
mov ax1, 8
|
||||
|
||||
.main_loop:
|
||||
mov lx0, b[rdx]
|
||||
inc rdx
|
||||
|
||||
cmp lx0, '0'
|
||||
jmp.b .done
|
||||
cmp.ae lx0, '9'
|
||||
sub.be lx0, '0'
|
||||
jmp.be .next
|
||||
|
||||
cmp lx0, 'A'
|
||||
cmp.ae lx0, 'Z'
|
||||
sub.be lx0, 55 ; 'A' - 10
|
||||
jmp.be .next
|
||||
|
||||
cmp lx0, 'a'
|
||||
jmp.b .next
|
||||
cmp.ae lx0, 'z'
|
||||
sub.be lx0, 87 ; 'a' - 10
|
||||
jmp.be .next
|
||||
|
||||
.next:
|
||||
; too large for base?
|
||||
cmp lx0, ax1
|
||||
jmp.ae .done
|
||||
|
||||
mul rax, ax1
|
||||
add rax, lx0
|
||||
jmp .main_loop
|
||||
|
||||
.done:
|
||||
; negative?
|
||||
test lx1, lx1
|
||||
ret.z
|
||||
|
||||
; yes
|
||||
neg rax
|
||||
ret
|
||||
|
||||
.bad:
|
||||
mov q[errno], EINVAL
|
||||
ret
|
||||
|
4
ka/dos.k
4
ka/dos.k
@ -10,6 +10,10 @@ start:
|
||||
|
||||
call main
|
||||
|
||||
call strtol_test
|
||||
|
||||
stop
|
||||
|
||||
; Wait for and print input indefinitely
|
||||
.1:
|
||||
scan rax
|
||||
|
@ -13,6 +13,5 @@ PrintBootMsg:
|
||||
;
|
||||
main:
|
||||
call PrintBootMsg
|
||||
|
||||
ret
|
||||
|
||||
|
@ -1,6 +1,34 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
strtol_test:
|
||||
mov ax0, .s1
|
||||
mov ax1, 10
|
||||
call strtol
|
||||
mov nx0, rax
|
||||
|
||||
mov ax0, .s2
|
||||
mov ax1, 16
|
||||
call strtol
|
||||
mov nx1, rax
|
||||
|
||||
mov ax0, .s3
|
||||
mov ax1, 0
|
||||
call strtol
|
||||
mov nx2, rax
|
||||
|
||||
mov ax0, .s4
|
||||
mov ax1, 10
|
||||
call strtol
|
||||
mov nx3, rax
|
||||
|
||||
ret
|
||||
|
||||
.s1 = "+065536"
|
||||
.s2 = "0xABCD"
|
||||
.s3 = "0b100000"
|
||||
.s4 = "-1"
|
||||
|
||||
speed_test:
|
||||
utime lx0
|
||||
|
||||
@ -12,7 +40,7 @@ speed_test:
|
||||
mov rax, lx1
|
||||
sub rax, lx0
|
||||
|
||||
stop
|
||||
ret
|
||||
|
||||
putc_scroll_test:
|
||||
mov rdx, 25
|
||||
|
@ -58,8 +58,14 @@ xor rm rim
|
||||
xorf rm rim
|
||||
|
||||
# To document
|
||||
|
||||
shl rm rim
|
||||
shr rm rim
|
||||
shlf rm rim
|
||||
shrf rm rim
|
||||
|
||||
sal rm rim
|
||||
sar rm rim
|
||||
salf rm rim
|
||||
sarf rm rim
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include <in/instrs.h>
|
||||
#include <pc/console.h>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(prn)
|
||||
{
|
||||
if (p1->mlen > 1) {
|
||||
@ -13,9 +11,7 @@ IMPL_START_1(prn)
|
||||
}
|
||||
console_putc(ctx, (char)v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
IMPL_END
|
||||
|
||||
IMPL_START_1(scan)
|
||||
{
|
||||
@ -23,5 +19,3 @@ IMPL_START_1(scan)
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -91,3 +91,49 @@ IMPL_OUT_ZSF;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(sal)
|
||||
{
|
||||
long w1 = v1;
|
||||
long w2 = v2;
|
||||
|
||||
w1 <<= w2;
|
||||
|
||||
v1 = (ulong) w1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(salf)
|
||||
{
|
||||
long w1 = v1;
|
||||
long w2 = v2;
|
||||
|
||||
w1 <<= w2;
|
||||
|
||||
v1 = (ulong) w1;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(sar)
|
||||
{
|
||||
long w1 = v1;
|
||||
long w2 = v2;
|
||||
|
||||
w1 >>= w2;
|
||||
|
||||
v1 = (ulong) w1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(sarf)
|
||||
{
|
||||
long w1 = v1;
|
||||
long w2 = v2;
|
||||
|
||||
w1 >>= w2;
|
||||
|
||||
v1 = (ulong) w1;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
@ -101,11 +101,6 @@ static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
addr += cr2; \
|
||||
ulong real = addr2real(addr)
|
||||
|
||||
#define SIGN_EXTEND(val, mask) \
|
||||
(val & ((mask + 1) >> 1) \
|
||||
? (val | ~mask) \
|
||||
: val)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
ulong readmem(ctx_t *ctx, ulong addr, uint len)
|
||||
|
@ -21,3 +21,9 @@ void writemem(ctx_t *, ulong val, ulong addr, uint len);
|
||||
|
||||
ulong readmemzx(ctx_t *c, ulong addr, uint len);
|
||||
void writememzx(ctx_t *, ulong val, ulong addr, uint len);
|
||||
|
||||
#define SIGN_EXTEND(val, mask) \
|
||||
(val & ((mask + 1) >> 1) \
|
||||
? (val | ~mask) \
|
||||
: val)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user