0
0
Fork 0
mirror of https://git.sr.ht/~rabbits/uxn synced 2024-11-29 09:13:01 +00:00

Started implementing errors

This commit is contained in:
neauoire 2021-02-01 20:21:27 -08:00
parent 5147884639
commit 2cf40a4293
8 changed files with 124 additions and 118 deletions

View file

@ -17,20 +17,20 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
``` ```
< conditionals > < conditionals >
+03 +02 ADD 0302 ADD
+05 EQU 05 EQU
.there JMQ .there JMQ
:here :here
< when not equal > < when not equal >
+ee ee
BRK BRK
:there :there
< when is equal > < when is equal >
+ff ff
BRK BRK
``` ```
## Mission ## Mission
@ -44,10 +44,6 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
- Print word to stdout - Print word to stdout
- Draw pixel to screen - Draw pixel to screen
- Detect mouse click - Detect mouse click
- 16 bits addressing
- jumping to subroutine should be relative
- Implement addressing
- Implement 16 bits operations
- Jumps should be relative - Jumps should be relative
- Catch overflow/underflow - Catch overflow/underflow
- Audo-detect literals length. - 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 - Build PPU
- Interrupts - Interrupts
### 16 Bit Missions
- 16 bits addressing
- jumping to subroutine should be relative
- Implement addressing
- Implement 16 bits operations
## Refs ## Refs
https://code.9front.org/hg/plan9front/file/a7f9946e238f/sys/src/games/nes/cpu.c https://code.9front.org/hg/plan9front/file/a7f9946e238f/sys/src/games/nes/cpu.c

View file

@ -1,16 +1,16 @@
< conditionals > < conditionals >
+03 +02 ADD 0302 ADD
+05 EQU 05 EQU
.there JMQ .there JMQ
:here :here
< when not equal > < when not equal >
+ee ee
BRK BRK
:there :there
< when is equal > < when is equal >
+ff ff
BRK BRK

View file

@ -1,4 +1,4 @@
< core > < core >
+12 +34 ADD 01 ADD

View file

@ -1,7 +1,7 @@
< conditionals > < jump >
.end JMP .end JMP BRK
:end :end
+ff ff
BRK BRK

View file

@ -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

View file

@ -2,17 +2,17 @@
:begin :begin
.addall JSR ADD ADD .addall JSR ADD ADD
+06 EQU .isequal JSR 06 EQU .isequal JSR
BRK BRK
:add1 :add1
+01 RTS 01 RTS
:add2 :add2
+02 RTS 02 RTS
:add3 :add3
+03 RTS 03 RTS
:addall :addall
.add1 JSR .add1 JSR
@ -21,5 +21,5 @@
RTS RTS
:isequal :isequal
.addall JSR +ff .addall JSR ff
RTS RTS

53
uxn.c
View file

@ -19,15 +19,15 @@ WITH REGARD TO THIS SOFTWARE.
#define STACK_DEPTH 256 #define STACK_DEPTH 256
typedef unsigned char Uint8; typedef unsigned char Uint8;
typedef unsigned short Uint16;
typedef struct { typedef struct {
Uint8 literal; Uint8 literal, status;
Uint8 status, counter;
Uint8 memory[STACK_DEPTH];
Uint8 mptr, sptr, rsptr; Uint8 mptr, sptr, rsptr;
Uint8 memory[STACK_DEPTH];
Uint8 stack[STACK_DEPTH]; Uint8 stack[STACK_DEPTH];
Uint8 rstack[STACK_DEPTH]; Uint8 rstack[STACK_DEPTH];
Uint8 address[STACK_DEPTH]; Uint16 counter;
} Computer; } Computer;
Computer cpu; Computer cpu;
@ -92,7 +92,7 @@ rspop(void)
void op_brk() { setflag(FLAG_HALT, 1); } void op_brk() { setflag(FLAG_HALT, 1); }
void op_rts() { cpu.mptr = rspop(); } 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_drp() { spop(); }
void op_dup() { spush(cpu.stack[cpu.sptr - 1]); } void op_dup() { spush(cpu.stack[cpu.sptr - 1]); }
void op_swp() { Uint8 b = spop(), a = spop(); spush(b); spush(a); } 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_rot() { Uint8 c = spop(),b = spop(),a = spop(); spush(b); spush(c); spush(a); }
void op_jmp() { cpu.mptr = spop(); } void op_jmp() { cpu.mptr = spop(); }
void op_jsr() { rspush(cpu.mptr); 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_jmq() { Uint8 a = spop(); if(getflag(FLAG_ZERO)){ cpu.mptr = a; } setflag(FLAG_ZERO,0); }
void op_jsq() { if(getflag(FLAG_ZERO)){ op_jsr(); } 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_equ() { setflag(FLAG_ZERO, spop() == spop()); }
void op_neq() { setflag(FLAG_ZERO, spop() != spop()); } void op_neq() { setflag(FLAG_ZERO, spop() != spop()); }
void op_lth() { 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_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}; 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 */ /* clang-format on */
void void
@ -148,38 +155,40 @@ load(FILE *f)
fread(cpu.memory, sizeof(cpu.memory), 1, f); fread(cpu.memory, sizeof(cpu.memory), 1, f);
} }
void int
eval() eval()
{ {
Uint8 instr = cpu.memory[cpu.mptr++]; Uint8 instr = cpu.memory[cpu.mptr++];
if(cpu.literal > 0) { if(cpu.literal > 0) {
spush(instr); spush(instr);
cpu.literal--; 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])(); (*ops[instr])();
}
if(instr > 0x10) if(instr > 0x10)
setflag(FLAG_ZERO, 0); setflag(FLAG_ZERO, 0);
cpu.counter++;
return 1;
} }
void void
run(void) run(void)
{ {
int i; while(!(cpu.status & FLAG_HALT) && eval(cpu))
while((cpu.status & FLAG_HALT) == 0) ;
eval(cpu);
/* debug */ /* debug */
printf("ended @ %d | ", cpu.counter); printf("ended @ %d steps | ", cpu.counter);
printf("hf: %x zf: %x cf: %x tf: %x\n", printf("hf: %x zf: %x cf: %x tf: %x\n",
getflag(FLAG_HALT), getflag(FLAG_HALT) != 0,
getflag(FLAG_ZERO), getflag(FLAG_ZERO) != 0,
getflag(FLAG_CARRY), getflag(FLAG_CARRY) != 0,
getflag(FLAG_TRAPS)); getflag(FLAG_TRAPS) != 0);
printf("\n\n"); printf("\n");
for(i = 0; i < 4; i++)
printf("%d-", (cpu.status & (1 << i)) != 0);
printf("\n\n");
} }
int int

102
uxnasm.c
View file

@ -29,33 +29,14 @@ typedef struct {
int labelslen; int labelslen;
Label labels[256]; Label labels[256];
/* clang-format off */
char opcodes[][4] = { char opcodes[][4] = {
"BRK", "BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT",
"RTS", "JMP", "JSR", "JMQ", "JSQ", "EQU", "NEQ", "LTH", "GTH",
"LIT", "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"};
"POP",
"DUP", /* clang-format on */
"SWP",
"OVR",
"ROT",
/* */
"JMP",
"JSR",
"JMQ",
"JSQ",
"EQU",
"NEQ",
"LTH",
"GTH",
"---",
"---",
"---",
"---",
"ADD",
"SUB",
"MUL",
"DIV"
/* */};
Program p; Program p;
@ -81,6 +62,15 @@ scpy(char *src, char *dst, int len) /* string copy */
return dst; return dst;
} }
int
slen(char *s) /* string length */
{
int i = 0;
while(s[i] && s[++i])
;
return i;
}
char * char *
suca(char *s) /* string to uppercase */ suca(char *s) /* string to uppercase */
{ {
@ -120,11 +110,41 @@ shex(char *s) /* string to num */
#pragma mark - Parser #pragma mark - Parser
void void
addprg(Uint8 hex) pushprg(Uint8 hex)
{ {
p.data[p.len++] = 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 void
addlabel(char *id, Uint8 addr) addlabel(char *id, Uint8 addr)
{ {
@ -164,10 +184,9 @@ int
getlength(char *w) getlength(char *w)
{ {
if(findop(w) || scmp(w, "BRK")) return 1; 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 0;
if(w[0] == '+') return 2; if(sihx(w)) { return slen(w) / 2 + 2; }
if(w[0] == '-') return 2;
printf("Unknown length %s\n", w); printf("Unknown length %s\n", w);
return 0; return 0;
} }
@ -209,21 +228,14 @@ pass2(FILE *f)
if(word[0] == ':') continue; if(word[0] == ':') continue;
suca(word); suca(word);
if(comment(word, &skip)) continue; if(comment(word, &skip)) continue;
/* literals */ if((op = findop(word)) || scmp(word, "BRK"))
if(word[0] == '+' || word[0] == '-') pushprg(op);
addprg(0x02); else if((l = findlabel(word + 1)))
if(word[0] == '+') pushlabel(l);
addprg(shex(word + 1)); else if(sihx(word))
else if(word[0] == '-') pushliteral(word);
addprg((Uint8)(-1 * shex(word + 1))); else
/* opcodes */ printf("Unknown label: %s\n", word);
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);
} }
} }