commit 6ac543f312ae222ca445b90db32a1d0f8c88f8ad
parent 521be808a0ae99083414f9baf4b192f90c42b8be
Author: neauoire <aliceffekt@gmail.com>
Date: Thu, 4 Feb 2021 12:22:08 -0800
Starting 16bits mode
Diffstat:
5 files changed, 154 insertions(+), 133 deletions(-)
diff --git a/README.md b/README.md
@@ -10,13 +10,27 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
## Assembly Syntax
-- `;variable`, a named address(zero-page)
-- `:label`, a named address
-- `.pointer`, a pointer to a label
-- `@0010`, a position in the program
+### Write
+
+- `;variable`, set a name to address on the zero-page
+- `:label`, set a name to an address
+
+### Read
+
+- `,literal`, get a literal pointer
+- `.pointer`, get a raw pointer
+
+### Special
+
+- `@0010`, move to position in the program
+- `( comment )`
```
-< conditionals >
+( comment )
+
+;variable1
+;variable2
+;variable3
.there ( 0a 05 GTH ) JMC
diff --git a/examples/core.usm b/examples/core.usm
@@ -1,13 +1,3 @@
-< conditionals >
+( comment )
-.there ( 0a 05 GTH ) JMC
-
-:here
- < when not equal >
- ee
- BRK
-
-:there
- < when is equal >
- ff
- BRK
+,abcd ,ef STR
+\ No newline at end of file
diff --git a/examples/vectors.usm b/examples/vectors.usm
@@ -0,0 +1,11 @@
+< vectors >
+
+:RESET BRK
+:FRAME BRK
+:ERROR BRK
+
+@FFFA < vectors >
+
+.RESET
+.FRAME
+.ERROR
+\ No newline at end of file
diff --git a/uxn.c b/uxn.c
@@ -74,6 +74,13 @@ echo(Stack *s, Uint8 len, char *name)
void wspush(Uint8 v) { cpu.wst.dat[cpu.wst.ptr++] = v; }
Uint8 wspop(void) { return cpu.wst.dat[--cpu.wst.ptr]; }
+Uint16 wspop16(void) {
+
+ Uint8 a = cpu.wst.dat[--cpu.wst.ptr];
+ Uint8 b = cpu.wst.dat[--cpu.wst.ptr];
+ return a + (b << 8);
+
+}
Uint8 wspeek(void) { return cpu.wst.dat[cpu.wst.ptr - 1]; }
void rspush(Uint8 v) { cpu.rst.dat[cpu.rst.ptr++] = v; }
Uint8 rspop(void) { return cpu.rst.dat[--cpu.rst.ptr]; }
@@ -102,17 +109,27 @@ void op_add() { wspush(wspop() + wspop()); }
void op_sub() { wspush(wspop() - wspop()); }
void op_mul() { wspush(wspop() * wspop()); }
void op_div() { wspush(wspop() / wspop()); }
+void op_ldr() { }
+void op_str() {
+
+ Uint8 b = wspop();
+ Uint16 addr = wspop16();
+ printf("store: %02x @ %04x\n", b, addr);
+}
void (*ops[])(void) = {
op_brk, op_rts, op_lit, op_drp, op_dup, op_swp, op_ovr, op_rot,
op_jmu, op_jsu, op_jmc, op_jsc, op_equ, op_neq, op_gth, op_lth,
- op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div};
+ op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div,
+ op_ldr, op_str, op_brk, op_brk, op_brk, op_brk, op_brk, op_brk
+};
Uint8 opr[][2] = {
{0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {1,1}, {0,1}, {3,3},
{2,0}, {2,0}, {2,0}, {2,0}, {2,1}, {2,1}, {2,1}, {2,1},
{1,0}, {1,0}, {1,0}, {1,0}, {2,1}, {0,0}, {0,0}, {0,0},
- {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}
+ {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1},
+ {3,1}, {3,1}
};
/* clang-format on */
@@ -155,7 +172,7 @@ eval()
cpu.literal--;
return 1;
}
- if(instr < 24) {
+ if(instr < 32) {
if(cpu.wst.ptr < opr[instr][0])
return error("Stack underflow");
/* TODO stack overflow */
diff --git a/uxnasm.c b/uxnasm.c
@@ -11,19 +11,17 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
-#define PRGLEN 256
-#define LABELIDLEN 32
-
typedef unsigned char Uint8;
+typedef unsigned short Uint16;
typedef struct {
int ptr;
- Uint8 data[PRGLEN];
+ Uint8 data[65536];
} Program;
typedef struct {
- Uint8 addr;
- char name[LABELIDLEN];
+ Uint16 addr;
+ char name[64];
} Label;
int labelslen;
@@ -34,7 +32,9 @@ Label labels[256];
char opcodes[][4] = {
"BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT",
"JMU", "JSU", "JMC", "JSC", "EQU", "NEQ", "GTH", "LTH",
- "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"};
+ "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV",
+ "LDR", "STR", "---", "---", "---", "---", "---", "---"
+};
/* clang-format on */
@@ -82,7 +82,7 @@ suca(char *s) /* string to uppercase */
}
int
-sihx(char *s)
+sihx(char *s) /* string is hexadecimal */
{
int i = 0;
char c;
@@ -107,57 +107,66 @@ shex(char *s) /* string to num */
return n;
}
-#pragma mark - Parser
+int
+ismarker(char *w)
+{
+ return w[0] == '[' || w[0] == ']' || w[0] == '{' || w[0] == '}';
+}
-void
-pushprg(Uint8 hex)
+int
+iscomment(char *w, int *skip)
{
- p.data[p.ptr++] = hex;
+ if(w[0] == ')') {
+ *skip = 0;
+ return 1;
+ }
+ if(w[0] == '(') *skip = 1;
+ if(*skip) return 1;
+ return 0;
}
+#pragma mark - I/O
+
void
-pushlabel(Label *l)
+pushbyte(Uint8 b, int lit)
{
- pushprg(0x02);
- pushprg(0x01);
- pushprg(l->addr);
+ if(lit) {
+ pushbyte(0x02, 0);
+ pushbyte(0x01, 0);
+ }
+ p.data[p.ptr++] = b;
}
void
-pushliteral(char *w)
+pushshort(Uint16 s, int lit)
{
- int len = slen(w) / 2, value = shex(w);
- pushprg(0x02);
- pushprg(len);
- switch(len) {
- case 1:
- pushprg(value);
- break;
- case 2:
- pushprg(value >> 8);
- pushprg(value);
- break;
- case 3:
- pushprg(value >> 16);
- pushprg(value >> 8);
- pushprg(value);
- break;
+ if(lit) {
+ pushbyte(0x02, 0);
+ pushbyte(0x02, 0);
}
+ pushbyte((s >> 8) & 0xff, 0);
+ pushbyte(s & 0xff, 0);
}
-void
-addlabel(char *id, Uint8 addr)
+#pragma mark - Parser
+
+Uint8
+findop(char *s)
{
- Label *l = &labels[labelslen++];
- scpy(suca(id), l->name, LABELIDLEN);
- l->addr = addr;
- printf("New label: %s[0x%02x]\n", l->name, l->addr);
+ int i;
+ for(i = 0; i < 32; ++i)
+ if(scmp(opcodes[i], s))
+ return i;
+ return 0;
}
void
-addconst(char *id, Uint8 value)
+makelabel(char *id, Uint8 addr)
{
- printf("New const: %s[%02x]\n", id, value);
+ Label *l = &labels[labelslen++];
+ scpy(suca(id), l->name, 64);
+ l->addr = addr;
+ printf("New label: %s[0x%02x]\n", l->name, l->addr);
}
Label *
@@ -170,94 +179,72 @@ findlabel(char *s)
return NULL;
}
-Uint8
-findop(char *s)
-{
- int i;
- for(i = 0; i < 24; ++i)
- if(scmp(opcodes[i], s))
- return i;
- return 0;
-}
-
-int
-ismarker(char *w)
-{
- return w[0] == '(' || w[0] == ')' || w[0] == '{' || w[0] == '}';
-}
+#pragma mark - Parser
int
-iscomment(char *w, int *skip)
+error(char *name, char *id)
{
- if(w[0] == '>') {
- *skip = 0;
- return 1;
- }
- if(w[0] == '<') *skip = 1;
- if(*skip) return 1;
+ printf("Error: %s - %s\n", name, id);
return 0;
}
int
-getlength(char *w)
-{
- if(findop(w) || scmp(w, "BRK")) return 1;
- if(w[0] == '.') return 3;
- if(w[0] == ':') return 0;
- if(w[0] == ';') return 0;
- if(w[0] == '@') return 0;
- if(sihx(w)) { return slen(w) / 2 + 2; }
- if(ismarker(w)) return 0;
- printf("Unknown length %s\n", w);
- return 0;
-}
-
-void
pass1(FILE *f)
{
- int skip = 0;
- int addr = 0;
- int vars = 0;
- char word[64];
- while(fscanf(f, "%s", word) == 1) {
- if(iscomment(word, &skip)) continue;
- if(word[0] == ':') addlabel(word + 1, addr);
- if(word[0] == ';') addlabel(word + 1, vars++);
- addr += getlength(word);
+ int skip = 0, addr = 0, vars = 0;
+ char w[64];
+ while(fscanf(f, "%s", w) == 1) {
+ if(iscomment(w, &skip)) continue;
+ if(w[0] == ':') makelabel(w + 1, addr);
+ if(w[0] == ';') makelabel(w + 1, vars++);
+ /* move addr ptr */
+ if(findop(w) || scmp(w, "BRK"))
+ addr += 1;
+ else if(w[0] == '@')
+ addr += 0;
+ else if(w[0] == ':')
+ addr += 0;
+ else if(w[0] == ';')
+ addr += 0;
+ else if(w[0] == '.')
+ addr += 2;
+ else if(w[0] == ',')
+ addr += 4;
+ else if(ismarker(w))
+ addr += 0;
+ else
+ return error("Unknown label(pass1)", w);
}
rewind(f);
+ return 1;
}
-void
+int
pass2(FILE *f)
{
int skip = 0;
- char word[64];
- while(fscanf(f, "%s", word) == 1) {
+ char w[64];
+ while(fscanf(f, "%s", w) == 1) {
Uint8 op = 0;
Label *l;
- if(word[0] == ':') continue;
- if(word[0] == ';') continue;
- suca(word);
- if(iscomment(word, &skip) || ismarker(word)) continue;
- if(word[0] == '@')
- p.ptr = shex(word + 1);
- else if((op = findop(word)) || scmp(word, "BRK"))
- pushprg(op);
- else if((l = findlabel(word + 1)))
- pushlabel(l);
- else if(sihx(word))
- pushliteral(word);
+ if(w[0] == ':') continue;
+ if(w[0] == ';') continue;
+ suca(w);
+ if(iscomment(w, &skip) || ismarker(w)) continue;
+ if(w[0] == '@')
+ p.ptr = shex(w + 1);
+ else if((op = findop(w)) || scmp(w, "BRK"))
+ pushbyte(op, 0);
+ else if((l = findlabel(w + 1)))
+ pushshort(l->addr, w[0] == ',');
+ else if(sihx(w + 1) && slen(w + 1) == 2)
+ pushbyte(shex(w + 1), w[0] == ',');
+ else if(sihx(w + 1) && slen(w + 1) == 4)
+ pushshort(shex(w + 1), w[0] == ',');
else
- printf("Unknown label: %s\n", word);
+ return error("Unknown label(pass2)", w);
}
-}
-
-int
-error(char *name)
-{
- printf("Error: %s\n", name);
- return 0;
+ return 1;
}
int
@@ -265,11 +252,11 @@ main(int argc, char *argv[])
{
FILE *f;
if(argc < 3)
- return error("No input.");
+ return error("Input", "Missing");
if(!(f = fopen(argv[1], "r")))
- return error("Missing input.");
- pass1(f);
- pass2(f);
+ return error("Open", "Failed");
+ if(!pass1(f) || !pass2(f))
+ return error("Assembly", "Failed");
fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
fclose(f);
return 0;