duskos

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

commit 2d89b3ab4865005d79c19ff7af9f927c0f0dd195
parent c66d99ade72a01298f5dc7103ad2a14b4e9e7261
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Mon, 21 Nov 2022 11:31:01 -0500

app/uxn: hex formatting

Diffstat:
Mfs/app/uxn/vm.c | 224++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Afs/tests/app/uxn/hexfmt.bin | 0
Afs/tests/app/uxn/hexfmt.tal | 9+++++++++
Mfs/tests/app/uxn/vm.fs | 4++++
4 files changed, 138 insertions(+), 99 deletions(-)

diff --git a/fs/app/uxn/vm.c b/fs/app/uxn/vm.c @@ -7,15 +7,15 @@ */ struct Stack { - // TODO: allow single line decl - unsigned char ptr; - unsigned char dat[$ff]; + // TODO: allow single line decl + unsigned char ptr; + unsigned char dat[$ff]; }; struct Device { - unsigned char dat[$10]; - unsigned char (*dei)(Device*, unsigned char); - void (*deo)(Device*, unsigned char); + unsigned char dat[$10]; + unsigned char (*dei)(Device*, unsigned char); + void (*deo)(Device*, unsigned char); }; typedef void (*VMOP) (); @@ -33,152 +33,178 @@ static unsigned char *sp; // pointer to current stack top static unsigned char kptr; // holding value for keep mode static void error(int code) { - printf(code, "Error %d encountered\n"); - abort(); + printf(code, "Error %d encountered\n"); + abort(); } +// TODO: have pointer arithmetics strong enough to use something like this: +// static unsigned short gw(unsigned short *a) { return *a<<8|*(a+1); } +// static void sw(unsigned short *a, unsigned short val) { +// *a = val>>8; *(a+1) = val; } static void push8(unsigned char val) { - if (src->ptr == $ff) { error(2); } else { src->dat[src->ptr++] = val; } + if (src->ptr == $ff) { error(2); } else { src->dat[src->ptr++] = val; } } -static void push16(unsigned short val) { - if (src->ptr >= $fe) { error(2); } else { - src->dat[src->ptr] = val >> 8; - src->dat[src->ptr+1] = val; - src->ptr += 2 ; - } +static void push16(Stack *s, unsigned short val) { + if (s->ptr >= $fe) { error(2); } else { + s->dat[s->ptr] = val >> 8; + s->dat[s->ptr+1] = val; + s->ptr += 2 ; + } } -static void push(unsigned short val) { if (bs) push16(val); else push8(val); } +static void push(unsigned short val) { if (bs) push16(src, val); else push8(val); } static unsigned char pop8() { - if (!*sp) { error(0); } else { return src->dat[--*sp]; } + if (!*sp) { error(0); } else { return src->dat[--*sp]; } } static unsigned short pop16() { - unsigned short val; - if (*sp <= 1) { error(0); } else { - *sp -= 2; - val = src->dat[*sp] << 8; - val |= src->dat[*sp+1]; - return val; - } + unsigned short val; + if (*sp <= 1) { error(0); } else { + *sp -= 2; + val = src->dat[*sp] << 8; + val |= src->dat[*sp+1]; + return val; + } } static unsigned short pop() { if (bs) return pop16(); else return pop8(); } static void poke(unsigned short addr, unsigned short val) { - if (bs) { - ram[addr] = val >> 8; - ram[addr+1] = val; - } else { - ram[addr] = val; - } + if (bs) { + ram[addr] = val >> 8; + ram[addr+1] = val; + } else { + ram[addr] = val; + } } static unsigned short peek(unsigned short addr) { - if (bs) { - return (ram[addr] << 8) | ram[addr+1]; - } else { - return ram[addr]; - } + if (bs) { + return (ram[addr] << 8) | ram[addr+1]; + } else { + return ram[addr]; + } } static void warp(unsigned short addr) { - if (bs) { - pc = addr; - } else { - // TODO: allow sign-extending through typecasting - if (addr >= $80) addr -= $100; - pc += addr; - } + if (bs) { + pc = addr; + } else { + // TODO: allow sign-extending through typecasting + if (addr >= $80) addr -= $100; + pc += addr; + } } static unsigned char nulldei(Device *d, unsigned char port) { return d->dat[port]; } static void nulldeo(Device *d, unsigned char port) { } /* Operations */ -static void _err() { error(42); } 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 SWP() { - unsigned short x = pop(); - unsigned short y = pop(); - push(x); push(y); } + unsigned short x = pop(); + unsigned short y = pop(); + push(x); push(y); } static void ROT() { - unsigned short x = pop(); - unsigned short y = pop(); - unsigned short z = pop(); - push(y); push(x); push(z); } + unsigned short x = pop(); + unsigned short y = pop(); + unsigned short z = pop(); + push(y); push(x); push(z); } static void DUP() { unsigned short x = pop(); push(x); push(x); } static void OVR() { - unsigned short x = pop(); - unsigned short y = pop(); - push(y); push(x); push(y); } + unsigned short x = pop(); + unsigned short y = pop(); + push(y); push(x); push(y); } static void EQU() { push8(pop() == pop()); } static void NEQ() { push8(pop() != pop()); } static void GTH() { - unsigned short a = pop(); - unsigned short b = pop(); - push8(b > a); } + unsigned short a = pop(); + unsigned short b = pop(); + push8(b > a); } static void LTH() { - unsigned short a = pop(); - unsigned short b = pop(); - push8(b < a); } + unsigned short a = pop(); + unsigned short b = pop(); + push8(b < a); } static void JMP() { warp(pop()); } static void JCN() { unsigned short a = pop(); if (pop8()) { warp(a); } } +static void JSR() { + unsigned short a = pop(); + push16(dst, pc); warp(a); } static void LDA() { push(peek(pop16())); } static void DEO() { - unsigned char port = pop8(); - unsigned short val = pop(); - Device *d = &dev[port>>4]; - port &= $f; - if (bs) { - d->dat[port] = val >> 8; d->deo(d, port++); - port &= $f; - d->dat[port] = val; d->deo(d, port); - } else { - d->dat[port] = val; d->deo(d, port); - } + unsigned char port = pop8(); + unsigned short val = pop(); + Device *d = &dev[port>>4]; + port &= $f; + if (bs) { + d->dat[port] = val >> 8; d->deo(d, port++); + port &= $f; + d->dat[port] = val; d->deo(d, port); + } else { + d->dat[port] = val; d->deo(d, port); + } } static void ADD() { push(pop() + pop()); } +static void MUL() { push(pop() * pop()); } +static void AND() { push(pop() & pop()); } +static void SFT() { + unsigned char shift = pop8(); + unsigned short n = pop(); + n >>= (shift & $0f); + n <<= (shift >> 4); + push(n); +} + static VMOP ops[$20] = { - LIT, INC, POP, NIP, SWP, ROT, DUP, OVR, - EQU, NEQ, GTH, LTH, JMP, JCN, _err, _err, - _err, _err, _err, _err, LDA, _err, _err, DEO, - ADD, _err, _err, _err, _err, _err, _err, _err}; + LIT, INC, POP, NIP, SWP, ROT, DUP, OVR, + EQU, NEQ, GTH, LTH, JMP, JCN, JSR, NULL, + NULL, NULL, NULL, NULL, LDA, NULL, NULL, DEO, + ADD, NULL, MUL, NULL, AND, NULL, NULL, SFT}; void uxn_exec() { - unsigned char op; - while (op = ram[pc++]) { - bs = (op >> 5) & 1; - if (op & $80) { - kptr = src->ptr; - sp = &kptr; - } else { - sp = &src->ptr; - } - op &= $1f; - ops[op](); - } + unsigned char op; + while (op = ram[pc++]) { + bs = (op >> 5) & 1; + if(op & $40) { + src = &rst; dst = &wst; + } else { + src = &wst; dst = &rst; + } + if (op & $80) { + kptr = src->ptr; + sp = &kptr; + } else { + sp = &src->ptr; + } + op &= $1f; + if (ops[op]) { + ops[op](); + } else { + printf(op, "unimplemented %b\n"); + return; + } + } } /* Console */ void console_deo(Device *d, unsigned char port) { - if (port == 8) stdout(d->dat[port]); + if (port == 8) stdout(d->dat[port]); } void uxn_init() { - int i; - pc = $100; - wst.ptr = 0; - rst.ptr = 0; - src = &wst; - dst = &rst; - for (i=0; i<$10; i++) { - dev[i].dei = nulldei; - dev[i].deo = nulldeo; - memset(dev[i].dat, 0, $10); - } - dev[1].deo = console_deo; + int i; + pc = $100; + wst.ptr = 0; + rst.ptr = 0; + src = &wst; + dst = &rst; + for (i=0; i<$10; i++) { + dev[i].dei = nulldei; + dev[i].deo = nulldeo; + memset(dev[i].dat, 0, $10); + } + dev[1].deo = console_deo; } unsigned int* uxn_ram() { return ram; } diff --git a/fs/tests/app/uxn/hexfmt.bin b/fs/tests/app/uxn/hexfmt.bin Binary files differ. diff --git a/fs/tests/app/uxn/hexfmt.tal b/fs/tests/app/uxn/hexfmt.tal @@ -0,0 +1,9 @@ +|0100 #1234 ,print-hex JSR #abcd ,print-hex JSR BRK + +@print-hex ( short* -- ) + + SWP ,&byte JSR + &byte ( byte -- ) DUP #04 SFT ,&char JSR + &char ( char -- ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO + +JMP2r diff --git a/fs/tests/app/uxn/vm.fs b/fs/tests/app/uxn/vm.fs @@ -17,4 +17,8 @@ create expected 47 nc, $00 $59 $00 $90 $00 $e9 $01 $79 $02 $62 $03 $db $06 $3d $0a $18 $10 $55 $1a $6d $2a $c2 $45 $2f $6f $f1 $b5 $20 capture uxn_exec expected 47 []= # + +S" /tests/app/uxn/hexfmt.bin" _load +uxn_init +capture uxn_exec S" 1234abcd" #s= testend