commit 2cf40a429379c90c3bde06bf2ce0f4044b560045
parent 514788463919af30d9539d7acf5cbbcca6a3485f
Author: neauoire <aliceffekt@gmail.com>
Date: Mon, 1 Feb 2021 20:21:27 -0800
Started implementing errors
Diffstat:
8 files changed, 124 insertions(+), 119 deletions(-)
diff --git a/README.md b/README.md
@@ -17,20 +17,20 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
```
< conditionals >
-+03 +02 ADD
-+05 EQU
+0302 ADD
+05 EQU
-.there JMQ
+.there JMQ
:here
- < when not equal >
- +ee
- BRK
+ < when not equal >
+ ee
+ BRK
:there
- < when is equal >
- +ff
- BRK
+ < when is equal >
+ ff
+ BRK
```
## Mission
@@ -44,10 +44,6 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
- Print word to stdout
- Draw pixel to screen
- Detect mouse click
-- 16 bits addressing
-- jumping to subroutine should be relative
-- Implement addressing
-- Implement 16 bits operations
- Jumps should be relative
- Catch overflow/underflow
- Audo-detect literals length.
@@ -55,6 +51,13 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
- Build PPU
- Interrupts
+### 16 Bit Missions
+
+- 16 bits addressing
+- jumping to subroutine should be relative
+- Implement addressing
+- Implement 16 bits operations
+
## Refs
https://code.9front.org/hg/plan9front/file/a7f9946e238f/sys/src/games/nes/cpu.c
diff --git a/examples/cond.usm b/examples/cond.usm
@@ -1,16 +1,16 @@
< conditionals >
-+03 +02 ADD
-+05 EQU
+0302 ADD
+05 EQU
-.there JMQ
+.there JMQ
:here
- < when not equal >
- +ee
- BRK
+ < when not equal >
+ ee
+ BRK
:there
- < when is equal >
- +ff
- BRK
+ < when is equal >
+ ff
+ BRK
diff --git a/examples/core.usm b/examples/core.usm
@@ -1,4 +1,4 @@
< core >
-+12 +34 ADD
+01 ADD
diff --git a/examples/jump.usm b/examples/jump.usm
@@ -1,7 +1,7 @@
-< conditionals >
+< jump >
-.end JMP
+.end JMP BRK
-:end
- +ff
- BRK
+:end
+ ff
+ BRK
diff --git a/examples/rstack.usm b/examples/rstack.usm
@@ -1,18 +0,0 @@
-< comment >
-
-.deep JSR [4 6 7 8 9 ] BRK
-
-:deep
- [2 1 2 ]
- .deeper JSR
- RTS
-
-:deeper
- [3 3 4 5 ]
- .deeperyet JSR
- RTS
-
-:deeperyet
- [2 aa bb ]
- RTS
-
-\ No newline at end of file
diff --git a/examples/subroutines.usm b/examples/subroutines.usm
@@ -2,17 +2,17 @@
:begin
.addall JSR ADD ADD
- +06 EQU .isequal JSR
+ 06 EQU .isequal JSR
BRK
:add1
- +01 RTS
+ 01 RTS
:add2
- +02 RTS
+ 02 RTS
:add3
- +03 RTS
+ 03 RTS
:addall
.add1 JSR
@@ -21,5 +21,5 @@
RTS
:isequal
- .addall JSR +ff
+ .addall JSR ff
RTS
diff --git a/uxn.c b/uxn.c
@@ -19,15 +19,15 @@ WITH REGARD TO THIS SOFTWARE.
#define STACK_DEPTH 256
typedef unsigned char Uint8;
+typedef unsigned short Uint16;
typedef struct {
- Uint8 literal;
- Uint8 status, counter;
- Uint8 memory[STACK_DEPTH];
+ Uint8 literal, status;
Uint8 mptr, sptr, rsptr;
+ Uint8 memory[STACK_DEPTH];
Uint8 stack[STACK_DEPTH];
Uint8 rstack[STACK_DEPTH];
- Uint8 address[STACK_DEPTH];
+ Uint16 counter;
} Computer;
Computer cpu;
@@ -92,7 +92,7 @@ rspop(void)
void op_brk() { setflag(FLAG_HALT, 1); }
void op_rts() { cpu.mptr = rspop(); }
-void op_lit() { cpu.literal += 1; }
+void op_lit() { cpu.literal += cpu.memory[cpu.mptr++]; }
void op_drp() { spop(); }
void op_dup() { spush(cpu.stack[cpu.sptr - 1]); }
void op_swp() { Uint8 b = spop(), a = spop(); spush(b); spush(a); }
@@ -100,8 +100,8 @@ void op_ovr() { spush(cpu.stack[cpu.sptr - 2]); }
void op_rot() { Uint8 c = spop(),b = spop(),a = spop(); spush(b); spush(c); spush(a); }
void op_jmp() { cpu.mptr = spop(); }
void op_jsr() { rspush(cpu.mptr); cpu.mptr = spop(); }
-void op_jmq() { if(getflag(FLAG_ZERO)){ op_jmp(); } setflag(FLAG_ZERO,0); }
-void op_jsq() { if(getflag(FLAG_ZERO)){ op_jsr(); } setflag(FLAG_ZERO,0); }
+void op_jmq() { Uint8 a = spop(); if(getflag(FLAG_ZERO)){ cpu.mptr = a; } setflag(FLAG_ZERO,0); }
+void op_jsq() { Uint8 a = spop(); if(getflag(FLAG_ZERO)){ rspush(cpu.mptr); cpu.mptr = a; } setflag(FLAG_ZERO,0); }
void op_equ() { setflag(FLAG_ZERO, spop() == spop()); }
void op_neq() { setflag(FLAG_ZERO, spop() != spop()); }
void op_lth() { setflag(FLAG_ZERO, spop() < spop()); }
@@ -120,6 +120,13 @@ void (*ops[])(void) = {
op_jmp, op_jsr, op_jmq, op_jsq, 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}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+ {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {0,0}, {0,0}, {0,0},
+ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+};
+
/* clang-format on */
void
@@ -148,38 +155,40 @@ load(FILE *f)
fread(cpu.memory, sizeof(cpu.memory), 1, f);
}
-void
+int
eval()
{
Uint8 instr = cpu.memory[cpu.mptr++];
if(cpu.literal > 0) {
spush(instr);
cpu.literal--;
- return;
+ return 1;
}
- if(instr < 24)
+ if(instr < 24) {
+ if(cpu.sptr < opr[instr][0])
+ return error("Stack underflow");
+ /* TODO stack overflow */
(*ops[instr])();
+ }
if(instr > 0x10)
setflag(FLAG_ZERO, 0);
+ cpu.counter++;
+ return 1;
}
void
run(void)
{
- int i;
- while((cpu.status & FLAG_HALT) == 0)
- eval(cpu);
+ while(!(cpu.status & FLAG_HALT) && eval(cpu))
+ ;
/* debug */
- printf("ended @ %d | ", cpu.counter);
+ printf("ended @ %d steps | ", cpu.counter);
printf("hf: %x zf: %x cf: %x tf: %x\n",
- getflag(FLAG_HALT),
- getflag(FLAG_ZERO),
- getflag(FLAG_CARRY),
- getflag(FLAG_TRAPS));
- printf("\n\n");
- for(i = 0; i < 4; i++)
- printf("%d-", (cpu.status & (1 << i)) != 0);
- printf("\n\n");
+ getflag(FLAG_HALT) != 0,
+ getflag(FLAG_ZERO) != 0,
+ getflag(FLAG_CARRY) != 0,
+ getflag(FLAG_TRAPS) != 0);
+ printf("\n");
}
int
diff --git a/uxnasm.c b/uxnasm.c
@@ -29,33 +29,14 @@ typedef struct {
int labelslen;
Label labels[256];
+/* clang-format off */
+
char opcodes[][4] = {
- "BRK",
- "RTS",
- "LIT",
- "POP",
- "DUP",
- "SWP",
- "OVR",
- "ROT",
- /* */
- "JMP",
- "JSR",
- "JMQ",
- "JSQ",
- "EQU",
- "NEQ",
- "LTH",
- "GTH",
- "---",
- "---",
- "---",
- "---",
- "ADD",
- "SUB",
- "MUL",
- "DIV"
- /* */};
+ "BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT",
+ "JMP", "JSR", "JMQ", "JSQ", "EQU", "NEQ", "LTH", "GTH",
+ "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"};
+
+/* clang-format on */
Program p;
@@ -81,6 +62,15 @@ scpy(char *src, char *dst, int len) /* string copy */
return dst;
}
+int
+slen(char *s) /* string length */
+{
+ int i = 0;
+ while(s[i] && s[++i])
+ ;
+ return i;
+}
+
char *
suca(char *s) /* string to uppercase */
{
@@ -120,12 +110,42 @@ shex(char *s) /* string to num */
#pragma mark - Parser
void
-addprg(Uint8 hex)
+pushprg(Uint8 hex)
{
p.data[p.len++] = hex;
}
void
+pushlabel(Label *l)
+{
+ pushprg(0x02);
+ pushprg(0x01);
+ pushprg(l->addr);
+}
+
+void
+pushliteral(char *w)
+{
+ 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;
+ }
+}
+
+void
addlabel(char *id, Uint8 addr)
{
Label *l = &labels[labelslen++];
@@ -164,10 +184,9 @@ int
getlength(char *w)
{
if(findop(w) || scmp(w, "BRK")) return 1;
- if(w[0] == '.') return 2;
+ if(w[0] == '.') return 3;
if(w[0] == ':') return 0;
- if(w[0] == '+') return 2;
- if(w[0] == '-') return 2;
+ if(sihx(w)) { return slen(w) / 2 + 2; }
printf("Unknown length %s\n", w);
return 0;
}
@@ -209,21 +228,14 @@ pass2(FILE *f)
if(word[0] == ':') continue;
suca(word);
if(comment(word, &skip)) continue;
- /* literals */
- if(word[0] == '+' || word[0] == '-')
- addprg(0x02);
- if(word[0] == '+')
- addprg(shex(word + 1));
- else if(word[0] == '-')
- addprg((Uint8)(-1 * shex(word + 1)));
- /* opcodes */
- else if((op = findop(word)) || scmp(word, "BRK"))
- addprg(op);
- else if((l = findlabel(word + 1))) {
- addprg(0x02);
- addprg(l->addr);
- } else
- printf("unknown: %s\n", word);
+ if((op = findop(word)) || scmp(word, "BRK"))
+ pushprg(op);
+ else if((l = findlabel(word + 1)))
+ pushlabel(l);
+ else if(sihx(word))
+ pushliteral(word);
+ else
+ printf("Unknown label: %s\n", word);
}
}