duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 919e09bf652c319197b536d09e84c6dc0999f1df
parent 93c0cca799e5e1a35fcd15d08b12d5a92177aed0
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed, 14 Dec 2022 16:36:32 -0500

comp/c: add uchar ushort uint typedefs

Also, move slen0 from emul/uxn/varvara to lib/str, add a C interface to it and
use it in asm/uxntal.

Diffstat:
Mfs/asm/uxntal.c | 62+++++++++++++++++++++++++++++---------------------------------
Mfs/comp/c/cc.fs | 4++++
Mfs/comp/c/lib.fs | 1+
Mfs/doc/cc/usage.txt | 4++++
Mfs/emul/uxn/varvara.fs | 8+++-----
Mfs/emul/uxn/vm.c | 112++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mfs/lib/str.fs | 4++++
7 files changed, 101 insertions(+), 94 deletions(-)

diff --git a/fs/asm/uxntal.c b/fs/asm/uxntal.c @@ -1,4 +1,5 @@ /* Source: https://git.sr.ht/~rabbits/uxn + * Filename: src/uxnasm.c * License: /license/dll-uxn.txt */ @@ -6,10 +7,6 @@ #define LENGTH $10000 #define LINESZ $40 -typedef unsigned char Uint8; -typedef char Sint8; -typedef unsigned short Uint16; - static int _arena = NULL; struct MacroLine { @@ -26,17 +23,17 @@ struct Macro { struct Label { Label *next; char name[LINESZ]; - Uint16 addr, refs; + ushort addr, refs; }; struct Reference { Reference *next; char name[LINESZ], rune; - Uint16 addr; + ushort addr; }; struct Program { - Uint8 data[LENGTH]; + uchar data[LENGTH]; unsigned int ptr, length; Label *labels; Macro *macros; @@ -56,10 +53,9 @@ static char* ops[$20] = { static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i]) if(!a[i] || ++i >= len) return 1; return 0; } /* string compare */ static int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f')) return 0; return i > 1; } /* string is hexadecimal */ static int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */ -static int slen(char *s) { int i = 0; while(s[i]) i++; return i; } /* string length */ -static int spos(char *s, char c) { Uint8 i = 0, j; while((j = s[i++])) if(j == c) return i; return -1; } /* character position */ +static int spos(char *s, char c) { uchar i = 0, j; while((j = s[i++])) if(j == c) return i; return -1; } /* character position */ static char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = 0; return dst; } /* string copy */ -static char *scat(char *dst, char *src) { char *ptr = dst + slen(dst); while(*src) *ptr++ = *src++; *ptr = 0; return dst; } /* string cat */ +static char *scat(char *dst, char *src) { char *ptr = dst + zstrlen(dst); while(*src) *ptr++ = *src++; *ptr = 0; return dst; } /* string cat */ static int parse(char *w, int hdl); @@ -100,7 +96,7 @@ findlabel(char *name) return NULL; } -static Uint8 +static uchar findopcode(char *s) { int i, m; @@ -150,9 +146,9 @@ makemacro(char *name, int hdl) char word[LINESZ]; if(findmacro(name)) return error("Macro duplicate", name); - if(sihx(name) && slen(name) % 2 == 0) + if(sihx(name) && zstrlen(name) % 2 == 0) return error("Macro name is hex number", name); - if(findopcode(name) || scmp(name, "BRK"0, 4) || !slen(name)) + if(findopcode(name) || scmp(name, "BRK"0, 4) || !zstrlen(name)) return error("Macro name is invalid", name); m = alloc_allot(sizeof(Macro), _arena); m->next = NULL; @@ -178,9 +174,9 @@ makelabel(char *name) Label *l; if(findlabel(name)) return error("Label duplicate", name); - if(sihx(name) && (slen(name) == 2 || slen(name) == 4)) + if(sihx(name) && (zstrlen(name) == 2 || zstrlen(name) == 4)) return error("Label name is hex number", name); - if(findopcode(name) || scmp(name, "BRK"0, 4) || !slen(name)) + if(findopcode(name) || scmp(name, "BRK"0, 4) || !zstrlen(name)) return error("Label name is invalid", name); l = alloc_allot(sizeof(Label), _arena); l->next = NULL; @@ -192,7 +188,7 @@ makelabel(char *name) } static int -makereference(char *scope, char *label, Uint16 addr) +makereference(char *scope, char *label, ushort addr) { char subw[LINESZ], parent[LINESZ]; int pos; @@ -217,7 +213,7 @@ makereference(char *scope, char *label, Uint16 addr) } static int -writebyte(Uint8 b) +writebyte(uchar b) { if(p.ptr < TRIM) return error("Writing in zero-page", ""0); @@ -233,13 +229,13 @@ writebyte(Uint8 b) static int writeopcode(char *w) { - Uint8 res; + uchar res; res = writebyte(findopcode(w)); return res; } static int -writeshort(Uint16 s, int lit) +writeshort(ushort s, int lit) { if(lit) if(!writebyte(findopcode("LIT2"0))) return 0; @@ -247,7 +243,7 @@ writeshort(Uint16 s, int lit) } static int -writelitbyte(Uint8 b) +writelitbyte(uchar b) { if(!writebyte(findopcode("LIT"0))) return 0; if(!writebyte(b)) return 0; @@ -275,14 +271,14 @@ parse(char *w, int hdl) char word[LINESZ], subw[LINESZ], c; Macro *m; MacroLine *ml; - if(slen(w) >= 63) + if(zstrlen(w) >= 63) return error("Invalid token", w); switch(w[0]) { case '(': /* comment */ - if(slen(w) != 1) fprintf(w, "-- Malformed comment: %s\n", ConsoleOut()); + if(zstrlen(w) != 1) fprintf(w, "-- Malformed comment: %s\n", ConsoleOut()); i = 1; /* track nested comment depth */ while(freadword(word, hdl) == 1) { - if(slen(word) != 1) + if(zstrlen(word) != 1) continue; else if(word[0] == '(') i++; @@ -318,11 +314,11 @@ parse(char *w, int hdl) return error("Invalid sublabel", w); break; case '#': /* literals hex */ - if(!sihx(w + 1) || (slen(w) != 3 && slen(w) != 5)) + if(!sihx(w + 1) || (zstrlen(w) != 3 && zstrlen(w) != 5)) return error("Invalid hex literal", w); - if(slen(w) == 3) { + if(zstrlen(w) == 3) { if(!writelitbyte(shex(w + 1))) return 0; - } else if(slen(w) == 5) { + } else if(zstrlen(w) == 5) { if(!writeshort(shex(w + 1), 1)) return 0; } break; @@ -358,18 +354,18 @@ parse(char *w, int hdl) break; case '[': case ']': - if(slen(w) == 1) break; /* else fallthrough */ + if(zstrlen(w) == 1) break; /* else fallthrough */ default: /* opcode */ if(findopcode(w) || scmp(w, "BRK"0, 4)) { if(!writeopcode(w)) return 0; } /* raw byte */ - else if(sihx(w) && slen(w) == 2) { + else if(sihx(w) && zstrlen(w) == 2) { if(!writebyte(shex(w))) return 0; } /* raw short */ - else if(sihx(w) && slen(w) == 4) { + else if(sihx(w) && zstrlen(w) == 4) { if(!writeshort(shex(w), 0)) return 0; } /* macro */ @@ -397,16 +393,16 @@ resolve() case '_': if(!(l = findlabel(r->name))) return error("Unknown relative reference", r->name); - p.data[r->addr] = (Sint8)(l->addr - r->addr - 2); - if(p.data[r->addr] != (Sint8)(l->addr - r->addr - 2)) + p.data[r->addr] = (char)(l->addr - r->addr - 2); + if(p.data[r->addr] != (char)(l->addr - r->addr - 2)) return error("Relative reference is too far", r->name); l->refs++; break; case ',': if(!(l = findlabel(r->name))) return error("Unknown relative reference", r->name); - p.data[r->addr + 1] = (Sint8)(l->addr - r->addr - 3); - if(p.data[r->addr + 1] != (Sint8)(l->addr - r->addr - 3)) + p.data[r->addr + 1] = (char)(l->addr - r->addr - 3); + if(p.data[r->addr + 1] != (char)(l->addr - r->addr - 3)) return error("Relative reference is too far", r->name); l->refs++; break; diff --git a/fs/comp/c/cc.fs b/fs/comp/c/cc.fs @@ -14,3 +14,7 @@ : :c cctok$ nextt cparse ; : cc<< ( -- ) ['] cc1, word with-stdin-file ; + +:c typedef unsigned char uchar ; +:c typedef unsigned short ushort ; +:c typedef unsigned int uint ; diff --git a/fs/comp/c/lib.fs b/fs/comp/c/lib.fs @@ -14,6 +14,7 @@ :c void dump(int addr); :c void emit(char c); :c void stype(char *str); +:c int zstrlen(char *zstr); :c int StdIn(); :c int StdOut(); :c int ConsoleIn(); diff --git a/fs/doc/cc/usage.txt b/fs/doc/cc/usage.txt @@ -28,6 +28,10 @@ are a few differences: * no long, redundant with int * no double, float is always 32b * char is always 8b, short is always 16b, int is always 32b +* Extra builtin typedefs: + * uchar -- unsigned char + * ushort -- unsigned short + * uint -- unsigned int * tightened parsing requirements for simplification purposes * "unsigned" always goes first * no "signed" (always default), no "auto" diff --git a/fs/emul/uxn/varvara.fs b/fs/emul/uxn/varvara.fs @@ -1,9 +1,7 @@ +\ Varvara implementation +?f<< /lib/str.fs ?f<< /emul/uxn/vm.fs -: slen0 ( a -- len ) - 0 swap $100 [c]? ( idx ) - dup 0< if abort" string too long" then ; - : short@ ( a -- n ) c@+ 8 lshift swap c@ or ; : short! ( n a -- ) over 8 rshift swap c!+ c! ; : devshort@ ( idx dev -- n ) Device dat + short@ ; @@ -24,7 +22,7 @@ create _fpos 8 allot0 \ current file position : _findfn ( dev -- path-or-0 ) 8 swap devshort@ uxn_ram + ( a ) - dup slen0 dup _fnbuf c! _fnbuf 1+ swap move ( dev ) + dup zstrlen dup _fnbuf c! _fnbuf 1+ swap move ( dev ) \ _fnbuf now holds stringified filename _fnbuf curpath :find ( path ) ; diff --git a/fs/emul/uxn/vm.c b/fs/emul/uxn/vm.c @@ -7,71 +7,71 @@ */ struct Stack { - unsigned char ptr, dat[$ff]; + uchar ptr, dat[$ff]; }; struct Device { - unsigned char port, dat[$10]; - unsigned char (*dei)(Device*, unsigned char); - void (*deo)(Device*, unsigned char); + uchar port, dat[$10]; + uchar (*dei)(Device*, uchar); + void (*deo)(Device*, uchar); }; typedef void (*VMOP) (); -static unsigned char ram[$10000]; +static uchar ram[$10000]; static Stack wst, rst, *src, *dst; static Device dev[$10]; -static unsigned short pc; // Program Counter +static ushort pc; // Program Counter static int bs; // byte/short 0=byte 1=short -static unsigned char *sp; // pointer to current stack top -static unsigned char kptr; // holding value for keep mode +static uchar *sp; // pointer to current stack top +static uchar kptr; // holding value for keep mode static void error(int code) { printf(code, "Error %d encountered\n"); abort(); } -static unsigned short gw(unsigned char *a) { return *a<<8|*(a+1); } -static void sw(unsigned char *a, unsigned short val) { +static ushort gw(uchar *a) { return *a<<8|*(a+1); } +static void sw(uchar *a, ushort val) { *a = val>>8; *(a+1) = val; } -static unsigned short signext(unsigned short val) { +static ushort signext(ushort val) { // TODO: allow sign-extending through typecasting if (val >= $80) return val - $100; else return val; } -static void push8(Stack *s, unsigned char val) { +static void push8(Stack *s, uchar val) { if (s->ptr == $ff) { error(2); } else { s->dat[s->ptr++] = val; } } -static void push16(Stack *s, unsigned short val) { +static void push16(Stack *s, ushort val) { if (s->ptr >= $fe) { error(2); } else { sw(&s->dat[s->ptr], val); s->ptr += 2 ; } } -static void pushs(Stack *s, unsigned short val) { +static void pushs(Stack *s, ushort val) { if (bs) push16(s, val); else push8(s, val); } -static void push(unsigned short val) { pushs(src, val); } +static void push(ushort val) { pushs(src, val); } -static unsigned char pop8() { +static uchar pop8() { if (!*sp) { error(0); } else { return src->dat[--*sp]; } } -static unsigned short pop16() { - unsigned short val; +static ushort pop16() { + ushort val; if (*sp <= 1) { error(0); } else { *sp -= 2; return gw(&src->dat[*sp]); } } -static unsigned short pop() { if (bs) return pop16(); else return pop8(); } +static ushort pop() { if (bs) return pop16(); else return pop8(); } -static void poke(unsigned short addr, unsigned short val) { +static void poke(ushort addr, ushort val) { if (bs) sw(&ram[addr], val); else ram[addr] = val; } -static unsigned short peek(unsigned short addr) { +static ushort peek(ushort addr) { if (bs) return gw(&ram[addr]); else return ram[addr]; } -static void warp(unsigned short addr) { +static void warp(ushort addr) { if (bs) { pc = addr; } else { @@ -79,53 +79,53 @@ static void warp(unsigned short addr) { } } -static unsigned char nulldei(Device *d, unsigned char port) { return d->dat[port]; } -static void nulldeo(Device *d, unsigned char port) { } +static uchar nulldei(Device *d, uchar port) { return d->dat[port]; } +static void nulldeo(Device *d, uchar port) { } /* Operations */ static void LIT() { push(peek(pc++)); pc += bs; } static void INC() { push(pop()+1); } static void POP() { pop(); } -static void NIP() { unsigned short x = pop(); pop(); push(x); } +static void NIP() { ushort x = pop(); pop(); push(x); } static void SWP() { - unsigned short x = pop(); - unsigned short y = pop(); + ushort x = pop(); + ushort y = pop(); push(x); push(y); } static void ROT() { - unsigned short x = pop(); - unsigned short y = pop(); - unsigned short z = pop(); + ushort x = pop(); + ushort y = pop(); + ushort z = pop(); push(y); push(x); push(z); } -static void DUP() { unsigned short x = pop(); push(x); push(x); } +static void DUP() { ushort x = pop(); push(x); push(x); } static void OVR() { - unsigned short x = pop(); - unsigned short y = pop(); + ushort x = pop(); + ushort y = pop(); push(y); push(x); push(y); } static void EQU() { push8(src, pop() == pop()); } static void NEQ() { push8(src, pop() != pop()); } static void GTH() { - unsigned short a = pop(); - unsigned short b = pop(); + ushort a = pop(); + ushort b = pop(); push8(src, b > a); } static void LTH() { - unsigned short a = pop(); - unsigned short b = pop(); + ushort a = pop(); + ushort b = pop(); push8(src, b < a); } static void JMP() { warp(pop()); } -static void JCN() { unsigned short a = pop(); if (pop8()) { warp(a); } } +static void JCN() { ushort a = pop(); if (pop8()) { warp(a); } } static void JSR() { - unsigned short a = pop(); + ushort a = pop(); push16(dst, pc); warp(a); } static void STH() { pushs( dst, pop()); } static void LDZ() { push(peek(pop8())); } -static void STZ() { unsigned short a = pop8(); poke(a, pop()); } +static void STZ() { ushort a = pop8(); poke(a, pop()); } static void LDR() { push(peek(pc+signext(pop8()))); } -static void STR() { unsigned short r = signext(pop8()); poke(pc+r, pop()); } +static void STR() { ushort r = signext(pop8()); poke(pc+r, pop()); } static void LDA() { push(peek(pop16())); } -static void STA() { unsigned short a = pop16(); poke(a, pop()); } +static void STA() { ushort a = pop16(); poke(a, pop()); } static void DEI() { - unsigned char port = pop8(); - unsigned short val; + uchar port = pop8(); + ushort val; Device *d = &dev[port>>4]; port &= $f; if (bs) { @@ -138,8 +138,8 @@ static void DEI() { push(val); } static void DEO() { - unsigned char port = pop8(); - unsigned short val = pop(); + uchar port = pop8(); + ushort val = pop(); Device *d = &dev[port>>4]; port &= $f; if (bs) { @@ -152,20 +152,20 @@ static void DEO() { } static void ADD() { push(pop() + pop()); } static void SUB() { - unsigned short a = pop(); - unsigned short b = pop(); + ushort a = pop(); + ushort b = pop(); push(b - a); } static void MUL() { push(pop() * pop()); } static void DIV() { - unsigned short a = pop(); - unsigned short b = pop(); + ushort a = pop(); + ushort b = pop(); push(b / a); } static void AND() { push(pop() & pop()); } static void ORA() { push(pop() | pop()); } static void EOR() { push(pop() ^ pop()); } static void SFT() { - unsigned char shift = pop8(); - unsigned short n = pop(); + uchar shift = pop8(); + ushort n = pop(); n >>= (shift & $0f); n <<= (shift >> 4); push(n); @@ -178,7 +178,7 @@ static VMOP ops[$20] = { ADD, SUB, MUL, DIV, AND, ORA, EOR, SFT}; void uxn_exec() { - unsigned char op; + uchar op; while (op = ram[pc++]) { bs = (op >> 5) & 1; if(op & $40) { @@ -217,11 +217,11 @@ void uxn_init() { } } -unsigned int* uxn_ram() { return ram; } +uint* uxn_ram() { return ram; } void uxn_set_dev( int port, - unsigned char (*dei)(Device*, unsigned char), - void (*deo)(Device*, unsigned char)) { + uchar (*dei)(Device*, uchar), + void (*deo)(Device*, uchar)) { dev[port].dei = dei; dev[port].deo = deo; } diff --git a/fs/lib/str.fs b/fs/lib/str.fs @@ -14,6 +14,10 @@ create NULLSTR 0 c, : s[]= ( str a len -- f ) rot dup c@ rot = if ( a str ) c@+ []= else 2drop 0 then ; +\ null-terminated strings (zstr) routines +: zstrlen ( zstr -- len ) + 0 swap $100 [c]? ( idx ) dup 0< if abort" string too long" then ; + \\ append character to end of string : sappend ( c str -- ) tuck s) c! dup c@ 1+ swap c! ;