Started implementing errors
This commit is contained in:
parent
5147884639
commit
2cf40a4293
29
README.md
29
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
< core >
|
||||
|
||||
+12 +34 ADD
|
||||
01 ADD
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
< conditionals >
|
||||
< jump >
|
||||
|
||||
.end JMP
|
||||
.end JMP BRK
|
||||
|
||||
:end
|
||||
+ff
|
||||
BRK
|
||||
:end
|
||||
ff
|
||||
BRK
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
53
uxn.c
53
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
|
||||
|
|
102
uxnasm.c
102
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,11 +110,41 @@ 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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue