0
0
Fork 0
mirror of https://git.sr.ht/~rabbits/uxn synced 2024-11-25 15:25:12 +00:00
This commit is contained in:
neauoire 2021-01-29 17:49:10 -08:00
parent 588a0f8b92
commit 72d9c98f35
4 changed files with 67 additions and 50 deletions

View file

@ -8,34 +8,29 @@ A stack-based VM, written in ANSI C.
cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
``` ```
## OP Codes ## Assembly Syntax
``` ```
VALUE OPCODE EXPLANATION : starting a definition
0x00000000 NOP do nothing & obtaining pointers
0x00000001 ADD pop a, pop b, push a + b ( stack comments
0x00000002 SUB pop a, pop b, push a - b ` inlining bytecodes
0x00000003 AND pop a, pop b, push a & b ' strings
0x00000004 OR pop a, pop b, push a | b # numbers
0x00000005 XOR pop a, pop b, push a ^ b $ characters
0x00000006 NOT pop a, push !a ~ vector
0x00000007 IN read one byte from stdin, push as word on stack [ 12 34 ] real values
0x00000008 OUT pop one word and write to stream as one byte < 12 34 > relative values
0x00000009 LOAD pop a, push word read from address a ( 12 34 ) deadzone
0x0000000A STOR pop a, pop b, write b to address a ```
0x0000000B JMP pop a, goto a
0x0000000C JZ pop a, pop b, if a == 0 goto b ```
0x0000000D PUSH push next word ;add-two JSR
0x0000000E DUP duplicate word on stack
0x0000000F SWAP swap top two words on stack BRK
0x00000010 ROL3 rotate top three words on stack once left, (a b c) -> (b c a)
0x00000011 OUTNUM pop one word and write to stream as number :add-two
0x00000012 JNZ pop a, pop b, if a != 0 goto b [ 2 ] ADD RTS
0x00000013 DROP remove top of stack
0x00000014 PUSHIP push a in IP stack
0x00000015 POPIP pop IP stack to current IP, effectively performing a jump
0x00000016 DROPIP pop IP, but do not jump
0x00000017 COMPL pop a, push the complement of a
``` ```
## Design ## Design
@ -50,12 +45,11 @@ VALUE OPCODE EXPLANATION
### Assembly ### Assembly
- `%25`, decimal #### Addressing
- `#25`, hex
``` - `label`, a named offset[TODO]
2 2 + $ef - `literal`, a numeric value
``` - `pointer`, pointer to an address[TODO]
### Assembler ### Assembler

View file

@ -10,14 +10,14 @@ rm -f ./uxn
# debug(slow) # debug(slow)
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxnasm.c -o uxnasm cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxnasm.c -o uxnasm
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c -o uxn # cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c -o uxn
# build(fast) # build(fast)
# cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn # cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
# Size # Size
echo "Size: $(du -sk ./uxn)" # echo "Size: $(du -sk ./uxn)"
# run # run
./uxnasm program.usm program.rom ./uxnasm program.usm program.rom
./uxn program.rom # ./uxn program.rom

View file

@ -1 +1 @@
#12 #34 add LIT 25 26 LIT DUP ADD BRK

View file

@ -14,13 +14,14 @@ WITH REGARD TO THIS SOFTWARE.
#define PRGLEN 256 #define PRGLEN 256
typedef unsigned char Uint8; typedef unsigned char Uint8;
typedef unsigned short Uint16;
typedef struct { typedef struct {
int ptr; int ptr;
Uint16 data[PRGLEN]; Uint8 data[PRGLEN];
} Program; } Program;
char opcodes[][4] = {"BRK", "LIT", "DUP", "DRP", "SWP", "SLP", "PSH", "POP", "JMP", "JSR", "RST", "BEQ", "EQU", "NEQ", "LTH", "GTH"};
Program p; Program p;
#pragma mark - Helpers #pragma mark - Helpers
@ -35,6 +36,16 @@ scmp(char *a, char *b) /* string compare */
return 0; return 0;
} }
char *
suca(char *s) /* string to uppercase */
{
int i = 0;
char c;
while((c = s[i]))
s[i++] = c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c;
return s;
}
int int
shex(char *s) /* string to num */ shex(char *s) /* string to num */
{ {
@ -53,10 +64,27 @@ shex(char *s) /* string to num */
Uint8 Uint8
getopcode(char *s) getopcode(char *s)
{ {
if(scmp(s, "add")) { int i;
return 0x01; for(i = 0; i < 16; ++i)
if(scmp(opcodes[i], suca(s)))
return i;
return 0xff;
}
void
echo(Uint8 *s, Uint8 len, Uint8 ptr, char *name)
{
int i;
printf("%s\n", name);
for(i = 0; i < len; ++i) {
if(i % 16 == 0)
printf("\n");
if(ptr == i)
printf("[%02x]", s[i]);
else
printf(" %02x ", s[i]);
} }
return 0; printf("\n");
} }
void void
@ -64,16 +92,10 @@ pass1(FILE *f)
{ {
char word[64]; char word[64];
while(fscanf(f, "%s", word) == 1) { while(fscanf(f, "%s", word) == 1) {
int lit = 0, val = 0; int op = getopcode(word);
if(word[0] == '#') { if(op == 0xff)
lit = 0; op = shex(word);
val = shex(word + 1); p.data[p.ptr++] = op;
} else {
lit = 1;
val = getopcode(word);
}
printf("#%d -> %s[%02x %02x]\n", p.ptr, word, lit, val);
p.data[p.ptr++] = (val << 8) + (lit & 0xff);
} }
} }
@ -95,5 +117,6 @@ main(int argc, char *argv[])
pass1(f); pass1(f);
fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb")); fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
fclose(f); fclose(f);
echo(p.data, 0x40, 0, "program");
return 0; return 0;
} }