From 609a5a0d28facca35f04b3185d38ba81a4efac62 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Wed, 5 Jun 2019 22:11:45 +0200 Subject: [PATCH] iocall --- ka/dos.k | 3 +- ka/err/errno.k | 8 +++ ka/fmt/{fmt.k => format.k} | 0 ka/fmt/itoa.k | 99 +++++++++++++++++++++++++++++++++++++- ka/main.k | 28 ++++++++++- vm/dv/cpu.c | 11 +++-- vm/dv/dev.h | 2 +- vm/dv/devctl.c | 7 ++- vm/in/INSTRS | 26 ++++++++-- vm/in/arith.c | 22 ++++++++- vm/in/instrs.c | 21 ++++++++ 11 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 ka/err/errno.k rename ka/fmt/{fmt.k => format.k} (100%) diff --git a/ka/dos.k b/ka/dos.k index 1a135d3..372b477 100644 --- a/ka/dos.k +++ b/ka/dos.k @@ -18,7 +18,8 @@ _start: ; ; Include librairies ; -include "fmt/fmt.k" +include "err/errno.k" +include "fmt/format.k" include "prn/print.k" include "str/string.k" diff --git a/ka/err/errno.k b/ka/err/errno.k new file mode 100644 index 0000000..49d68cd --- /dev/null +++ b/ka/err/errno.k @@ -0,0 +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. + +EOK := 0 +EINVAL := 1 + +errno = 0 + diff --git a/ka/fmt/fmt.k b/ka/fmt/format.k similarity index 100% rename from ka/fmt/fmt.k rename to ka/fmt/format.k diff --git a/ka/fmt/itoa.k b/ka/fmt/itoa.k index 64d7d8d..18e366e 100644 --- a/ka/fmt/itoa.k +++ b/ka/fmt/itoa.k @@ -2,5 +2,102 @@ ; See the LICENSE file in the project root for more information. ; -; char *itoa(char *buf, int num, int base) +; char *_itoa(char *buf, int num, int base, int unsi) ; +; Acts as itoa if unsi == 0, as utoa otherwise +; + +_itoa: + mov rax, ax0 + xor rdx, rdx + + ; make sure base is in [2, 32] + + cmp ax2, 2 + cjmpb .bad + + cmp ax2, 36 + cjmpa .bad + + ; deal with zero + test ax1, ax1 + cjmpz .zero + + ; deal with base 10 signedness + + test ax3, ax3 ; unsigned mode + cjmpnz .conv + + cmp ax2, 10 ; base 10 + cjmpnz .conv + + cmp ax2, -9223372036854775808 ; LONG_MIN + cjmpz .min + + sgn rdx, ax1 ; extract ax1 sign + + cmp rdx, -1 ; negative? + cnotz ax1 ; -x = ~x+1 + cincz ax1 ; need "neg" inst... + + ; main loop +.conv: + test ax1, ax1 + cjmpz .fini + + mov rsx, ax1 + mod rsx, ax2 ; ax1 % base + + cmp rsx, 9 ; rsx > 9 ? + caddz rsx, 48 ; '0' + cjmpz .next + + add rsx, 87 ; 'a' - 10 + mov ax1, rsx + +.next: + mov b[ax0], rsx + inc ax0 + + div ax1, ax2 + break + jmp .conv + + ; null-terminate and reverse +.fini: + mov b[ax0], 0 + ret + +; +; exceptional cases +; + +.bad: + mov q[errno], EINVAL + mov b[rax], 0 + ret + +.zero: + mov b[ax0], 48 ; '0' + mov b[ax0+1], 0 + ret + +.min: + mov ax1, .min10 + call strcpy + ret + +.min10 = "-9223372036854775808" + +; +; wrappers +; + +itoa: + mov ax3, 0 + jmp _itoa + +utoa: + mov ax3, 1 + jmp _itoa + diff --git a/ka/main.k b/ka/main.k index b246447..dfdfc64 100644 --- a/ka/main.k +++ b/ka/main.k @@ -7,6 +7,32 @@ main: enter + mov ax0, .buf + mov ax1, 65 + mov ax2, 10 + call itoa + + mov ax0, rax + call print + + ; prn 10 + + mov ax0, .buf + mov ax1, 0xffffffffffffffff + mov ax2, 16 + call itoa + + mov ax0, rax + call print + + leave + ret + +.buf = [32] + +test: + enter + mov ax0, .buf devctl 0, 1 @@ -20,7 +46,7 @@ main: .buf = [32] -test: +test1: enter mov ax0, .msg diff --git a/vm/dv/cpu.c b/vm/dv/cpu.c index c903ace..1b0c5d1 100644 --- a/vm/dv/cpu.c +++ b/vm/dv/cpu.c @@ -3,28 +3,31 @@ #include -void cpudev_testfn(ctx_t *ctx, dev_t *dev) +long cpudev_testfn(ctx_t *ctx, dev_t *dev) { assert(dev == &cpudev); rax = 4; rdx = 3; + + return 0; } -void cpudev_poweron(ctx_t *ctx, dev_t *dev) +long cpudev_poweron(ctx_t *ctx, dev_t *dev) { assert(dev == &cpudev); dev->fslots[0] = cpudev_testfn; - dev->state = DEVGOOD; + + return 0; } dev_t cpudev = { .type = "cpu", .name = "K-CPU", - .modl = "K-CPU", + .modl = "Prisma 1", .vend = "The OS/K Team", .major = 0, diff --git a/vm/dv/dev.h b/vm/dv/dev.h index db6e76f..46823e0 100644 --- a/vm/dv/dev.h +++ b/vm/dv/dev.h @@ -6,7 +6,7 @@ #define DEVLEN 32 #define DEVSLOTS 256 -typedef void (*devfn_t)(ctx_t *, dev_t *); +typedef long (*devfn_t)(ctx_t *, dev_t *); enum { diff --git a/vm/dv/devctl.c b/vm/dv/devctl.c index dd25ca0..735bbce 100644 --- a/vm/dv/devctl.c +++ b/vm/dv/devctl.c @@ -86,6 +86,7 @@ IMPL_START_2(iocall) { CHK_SUPERV(); + long rc; dev_t *dev = devctl_common(ctx, v1, v2); if (dev == NULL) @@ -97,8 +98,10 @@ IMPL_START_2(iocall) else if (dev->fslots[v2] == NULL) rax = -6; - else - dev->fslots[v2](ctx, dev); + else { + rc = dev->fslots[v2](ctx, dev); + if (rc < 0) rax = rc; + } } IMPL_END; diff --git a/vm/in/INSTRS b/vm/in/INSTRS index 3754c53..38df33e 100644 --- a/vm/in/INSTRS +++ b/vm/in/INSTRS @@ -42,12 +42,19 @@ cshrnz rm rim # rax = rax / $0 sgn rm rim -add rm rim -sub rm rim -mul rim -div rim + inc rm dec rm +add rm rim +sub rm rim + +mul rm rim +mul2 rim + +div rm rim +div2 rim + +mod rm rim csgnz rm rim caddz rm rim @@ -184,7 +191,16 @@ iocall rim rim # Misc. instructions # -# Prints a character on the screen +# Clear rax...rsi +clr + +# Clear ax0...ax7 +cla + +# Clear nx0...nx7 +cln + +# Print a character on the screen prn rim # diff --git a/vm/in/arith.c b/vm/in/arith.c index 2d5bd6b..6f18d91 100644 --- a/vm/in/arith.c +++ b/vm/in/arith.c @@ -27,7 +27,13 @@ IMPL_START_2(sub) } IMPL_OUT; -IMPL_START_1(mul) +IMPL_START_2(mul) +{ + v1 *= v2; +} +IMPL_OUT; + +IMPL_START_1(mul2) { // Adapted from www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring ulong v2 = v1; @@ -53,7 +59,19 @@ IMPL_START_1(mul) } IMPL_END; -IMPL_START_1(div) +IMPL_START_2(div) +{ + v1 /= v2; +} +IMPL_OUT; + +IMPL_START_2(mod) +{ + v1 %= v2; +} +IMPL_OUT; + +IMPL_START_1(div2) { rdx = rax % v1; rax = rax / v1; diff --git a/vm/in/instrs.c b/vm/in/instrs.c index 6eeb2a0..aaa7c4b 100644 --- a/vm/in/instrs.c +++ b/vm/in/instrs.c @@ -32,3 +32,24 @@ IMPL_START_1(prn) } IMPL_END; +IMPL_START_0(clr) +{ + rax = rbx = rcx = rdx = 0; + rsx = rbi = rdi = rsi = 0; +} +IMPL_END; + +IMPL_START_0(cla) +{ + ax0 = ax1 = ax2 = ax3 = 0; + ax4 = ax5 = ax6 = ax7 = 0; +} +IMPL_END; + +IMPL_START_0(cln) +{ + nx0 = nx1 = nx2 = nx3 = 0; + nx4 = nx5 = nx6 = nx7 = 0; +} +IMPL_END; +