aboutsummaryrefslogtreecommitdiff
path: root/cio.c
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2026-09-29 23:40:31 +0200
committerJavier <dev.git@javispedro.com>2026-09-29 23:40:31 +0200
commit0a656a4a84f920194958d339d61ed567eba9c03c (patch)
tree0feecbddf0150e02fe7a2fa619dc232c50ced4c8 /cio.c
downloadchu-0a656a4a84f920194958d339d61ed567eba9c03c.tar.gz
chu-0a656a4a84f920194958d339d61ed567eba9c03c.zip
initial import
Diffstat (limited to 'cio.c')
-rw-r--r--cio.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/cio.c b/cio.c
new file mode 100644
index 0000000..43a2a27
--- /dev/null
+++ b/cio.c
@@ -0,0 +1,147 @@
+/*
+ * CHU - driver for CH375 in disk mode
+ * Copyright (C) 2024 Javier S. Pedro
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/* Simple printf function for console, a bit wasteful for what it is used.
+ * But it is part of the init code, so it will be thrown away.
+ * dlog.h is more powerful but only in debug builds. */
+
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <i86.h>
+
+#include "inc/dosapi.h"
+
+#include "cio.h"
+
+static inline void c_llputc(char c)
+{
+ dos_print_char(c);
+}
+
+void c_utoa(unsigned num, unsigned base)
+{
+ char buf[6];
+ int i = 0;
+
+ do {
+ unsigned digit = num % base;
+
+ if (digit < 10) {
+ buf[i] = '0' + digit;
+ } else {
+ buf[i] = 'a' + (digit - 10);
+ }
+
+ i++;
+ num /= base;
+ } while (num > 0 && i < sizeof(buf));
+
+ while (i--) {
+ c_llputc(buf[i]);
+ }
+}
+
+void c_itoa(int num, unsigned base)
+{
+ unsigned unum;
+
+ if (num < 0) {
+ c_llputc('-');
+ unum = -num;
+ } else {
+ unum = num;
+ }
+
+ c_utoa(unum, base);
+}
+
+unsigned c_strtou(const char * *str)
+{
+ unsigned i = 0;
+ const char *s = *str;
+ char c = *s;
+ while (c >= '0' && c <= '9') {
+ i = (i * 10) + (c - '0');
+ c = *(++s);
+ }
+ *str = s;
+ return i;
+}
+
+static void c_printstr(const char *s)
+{
+ while (*s) { c_llputc(*s++); }
+}
+
+void c_printf(const char *fmt, ...)
+{
+ va_list va;
+ char c;
+
+ va_start(va, fmt);
+
+ while ((c = *(fmt++))) {
+ if (c == '%') {
+ switch ((c = *(fmt++))) {
+ case 'd':
+ c_itoa(va_arg(va, int), 10);
+ break;
+ case 'u':
+ c_utoa(va_arg(va, unsigned), 10);
+ break;
+ case 'x':
+ case 'p':
+ c_utoa(va_arg(va, unsigned), 16);
+ break;
+ case 's':
+ c_printstr(va_arg(va, const char *));
+ break;
+ case 'c':
+ c_putc(va_arg(va, char));
+ break;
+ case '%':
+ c_llputc('%');
+ break;
+ }
+ } else {
+ c_putc(c);
+ }
+ }
+
+ va_end(va);
+}
+
+void c_putc(char c)
+{
+ if (c == '\n') {
+ c_llputc('\r');
+ }
+ c_llputc(c);
+}
+
+
+void c_puts(const char *s)
+{
+ char c;
+ while ((c = *(s++))) {
+ c_putc(c);
+ }
+ c_putc('\n');
+}