commit 521be808a0ae99083414f9baf4b192f90c42b8be
parent 69d255bfff808ef63c270abe1ed56413b129b65b
Author: neauoire <aliceffekt@gmail.com>
Date: Wed, 3 Feb 2021 21:53:56 -0800
Design progress
Diffstat:
8 files changed, 77 insertions(+), 60 deletions(-)
diff --git a/README.md b/README.md
@@ -10,17 +10,15 @@ 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
-- `+literal`, a numeric value
-- `.pointer`, pointer to a label
+- `.pointer`, a pointer to a label
+- `@0010`, a position in the program
```
< conditionals >
-0302 ADD
-05 EQU
-
-.there JMZ
+.there ( 0a 05 GTH ) JMC
:here
< when not equal >
@@ -35,10 +33,15 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
## Mission
+### Assembler
+
+- Crash on missing label
- Catch overflow/underflow
+- Constants
- Jumps should be relative
-- constants
-- variables
+
+### CPU
+
- Pointers/Literals
- A Three-Way Decision Routine(http://www.6502.org/tutorials/compare_instructions.html)
- Carry flag?
@@ -47,7 +50,7 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
- Detect mouse click
- SDL Layer Emulator
- Build PPU
-- Interrupts
+- Interrupts, vectors
### 16 Bit Missions
@@ -56,10 +59,6 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
- Implement addressing
- Implement 16 bits operations
-## Notes
-
-- Forth logic operators pop 2 items and add a bool to the stack, is that viable in uxn?
-
## Refs
https://code.9front.org/hg/plan9front/file/a7f9946e238f/sys/src/games/nes/cpu.c
diff --git a/examples/arithmetic.usm b/examples/arithmetic.usm
@@ -1,6 +1,6 @@
< arithmetic >
-0203 LTH .true JMZ
+0203 LTH .true JMC
:false ee BRK
:true ff BRK
diff --git a/examples/cond.usm b/examples/cond.usm
@@ -1,16 +0,0 @@
-< conditionals >
-
-0302 ADD
-05 EQU
-
-.there JMZ
-
-:here
- < when not equal >
- ee
- BRK
-
-:there
- < when is equal >
- ff
- BRK
diff --git a/examples/conditionals.usm b/examples/conditionals.usm
@@ -0,0 +1,13 @@
+< conditionals >
+
+.there ( 0a 05 GTH ) JMC
+
+:here
+ < when not equal >
+ ee
+ BRK
+
+:there
+ < when is equal >
+ ff
+ BRK
diff --git a/examples/core.usm b/examples/core.usm
@@ -1,6 +1,13 @@
-< core >
+< conditionals >
-34 34 EQU .label JSZ ff BRK
+.there ( 0a 05 GTH ) JMC
-:label ee RTS
+:here
+ < when not equal >
+ ee
+ BRK
+:there
+ < when is equal >
+ ff
+ BRK
diff --git a/examples/loop.usm b/examples/loop.usm
@@ -4,5 +4,5 @@
:loop
01 ADD
- 0f NEQ .loop JMZ
+ 0f NEQ .loop JMC
RTS
diff --git a/uxn.c b/uxn.c
@@ -86,14 +86,14 @@ void op_dup() { wspush(wspeek()); }
void op_swp() { Uint8 b = wspop(), a = wspop(); wspush(b); wspush(a); }
void op_ovr() { wspush(cpu.wst.dat[cpu.wst.ptr - 2]); }
void op_rot() { Uint8 c = wspop(),b = wspop(),a = wspop(); wspush(b); wspush(c); wspush(a); }
-void op_jmi() { cpu.rom.ptr = wspop(); }
-void op_jsi() { rspush(cpu.rom.ptr); cpu.rom.ptr = wspop(); }
-void op_jmz() { Uint8 a = wspop(); if(getflag(FLAG_ZERO)){ cpu.rom.ptr = a; } setflag(FLAG_ZERO,0); }
-void op_jsz() { Uint8 a = wspop(); if(getflag(FLAG_ZERO)){ rspush(cpu.rom.ptr); cpu.rom.ptr = a; } setflag(FLAG_ZERO,0); }
-void op_equ() { setflag(FLAG_ZERO, wspop() == wspeek()); }
-void op_neq() { setflag(FLAG_ZERO, wspop() != wspeek()); }
-void op_gth() { setflag(FLAG_ZERO, wspop() < wspeek()); }
-void op_lth() { setflag(FLAG_ZERO, wspop() > wspeek()); }
+void op_jmu() { cpu.rom.ptr = wspop(); }
+void op_jsu() { rspush(cpu.rom.ptr); cpu.rom.ptr = wspop(); }
+void op_jmc() { if(wspop()) op_jmu(); }
+void op_jsc() { if(wspop()) op_jsu(); }
+void op_equ() { wspush(wspop() == wspop()); }
+void op_neq() { wspush(wspop() != wspop()); }
+void op_gth() { wspush(wspop() < wspop()); }
+void op_lth() { wspush(wspop() > wspop()); }
void op_and() { wspush(wspop() & wspop()); }
void op_ora() { wspush(wspop() | wspop()); }
void op_rol() { wspush(wspop() << 1); }
@@ -105,12 +105,12 @@ void op_div() { wspush(wspop() / wspop()); }
void (*ops[])(void) = {
op_brk, op_rts, op_lit, op_drp, op_dup, op_swp, op_ovr, op_rot,
- op_jmi, op_jsi, op_jmz, op_jsz, op_equ, op_neq, op_gth, op_lth,
+ 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};
Uint8 opr[][2] = {
{0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {1,1}, {0,1}, {3,3},
- {1,0}, {1,0}, {1,0}, {1,0}, {1,0}, {1,0}, {1,0}, {1,0},
+ {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}
};
diff --git a/uxnasm.c b/uxnasm.c
@@ -17,7 +17,7 @@ WITH REGARD TO THIS SOFTWARE.
typedef unsigned char Uint8;
typedef struct {
- int len;
+ int ptr;
Uint8 data[PRGLEN];
} Program;
@@ -33,7 +33,7 @@ Label labels[256];
char opcodes[][4] = {
"BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT",
- "JMI", "JSI", "JMZ", "JSZ", "EQU", "NEQ", "GTH", "LTH",
+ "JMU", "JSU", "JMC", "JSC", "EQU", "NEQ", "GTH", "LTH",
"AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"};
/* clang-format on */
@@ -112,7 +112,7 @@ shex(char *s) /* string to num */
void
pushprg(Uint8 hex)
{
- p.data[p.len++] = hex;
+ p.data[p.ptr++] = hex;
}
void
@@ -151,13 +151,13 @@ addlabel(char *id, Uint8 addr)
Label *l = &labels[labelslen++];
scpy(suca(id), l->name, LABELIDLEN);
l->addr = addr;
- printf("new label: %s=%02x\n", l->name, l->addr);
+ printf("New label: %s[0x%02x]\n", l->name, l->addr);
}
void
addconst(char *id, Uint8 value)
{
- printf("new const: %s=%02x\n", id, value);
+ printf("New const: %s[%02x]\n", id, value);
}
Label *
@@ -181,18 +181,13 @@ findop(char *s)
}
int
-getlength(char *w)
+ismarker(char *w)
{
- if(findop(w) || scmp(w, "BRK")) return 1;
- if(w[0] == '.') return 3;
- if(w[0] == ':') return 0;
- if(sihx(w)) { return slen(w) / 2 + 2; }
- printf("Unknown length %s\n", w);
- return 0;
+ return w[0] == '(' || w[0] == ')' || w[0] == '{' || w[0] == '}';
}
int
-comment(char *w, int *skip)
+iscomment(char *w, int *skip)
{
if(w[0] == '>') {
*skip = 0;
@@ -203,15 +198,31 @@ comment(char *w, int *skip)
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(comment(word, &skip)) continue;
+ if(iscomment(word, &skip)) continue;
if(word[0] == ':') addlabel(word + 1, addr);
+ if(word[0] == ';') addlabel(word + 1, vars++);
addr += getlength(word);
}
rewind(f);
@@ -226,9 +237,12 @@ pass2(FILE *f)
Uint8 op = 0;
Label *l;
if(word[0] == ':') continue;
+ if(word[0] == ';') continue;
suca(word);
- if(comment(word, &skip)) continue;
- if((op = findop(word)) || scmp(word, "BRK"))
+ 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);