Design progress
This commit is contained in:
parent
69d255bfff
commit
521be808a0
25
README.md
25
README.md
|
@ -10,17 +10,15 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
|
||||||
|
|
||||||
## Assembly Syntax
|
## Assembly Syntax
|
||||||
|
|
||||||
|
- `;variable`, a named address(zero-page)
|
||||||
- `:label`, a named address
|
- `:label`, a named address
|
||||||
- `+literal`, a numeric value
|
- `.pointer`, a pointer to a label
|
||||||
- `.pointer`, pointer to a label
|
- `@0010`, a position in the program
|
||||||
|
|
||||||
```
|
```
|
||||||
< conditionals >
|
< conditionals >
|
||||||
|
|
||||||
0302 ADD
|
.there ( 0a 05 GTH ) JMC
|
||||||
05 EQU
|
|
||||||
|
|
||||||
.there JMZ
|
|
||||||
|
|
||||||
:here
|
:here
|
||||||
< when not equal >
|
< when not equal >
|
||||||
|
@ -35,10 +33,15 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
|
||||||
|
|
||||||
## Mission
|
## Mission
|
||||||
|
|
||||||
|
### Assembler
|
||||||
|
|
||||||
|
- Crash on missing label
|
||||||
- Catch overflow/underflow
|
- Catch overflow/underflow
|
||||||
|
- Constants
|
||||||
- Jumps should be relative
|
- Jumps should be relative
|
||||||
- constants
|
|
||||||
- variables
|
### CPU
|
||||||
|
|
||||||
- Pointers/Literals
|
- Pointers/Literals
|
||||||
- A Three-Way Decision Routine(http://www.6502.org/tutorials/compare_instructions.html)
|
- A Three-Way Decision Routine(http://www.6502.org/tutorials/compare_instructions.html)
|
||||||
- Carry flag?
|
- Carry flag?
|
||||||
|
@ -47,7 +50,7 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
|
||||||
- Detect mouse click
|
- Detect mouse click
|
||||||
- SDL Layer Emulator
|
- SDL Layer Emulator
|
||||||
- Build PPU
|
- Build PPU
|
||||||
- Interrupts
|
- Interrupts, vectors
|
||||||
|
|
||||||
### 16 Bit Missions
|
### 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 addressing
|
||||||
- Implement 16 bits operations
|
- Implement 16 bits operations
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- Forth logic operators pop 2 items and add a bool to the stack, is that viable in uxn?
|
|
||||||
|
|
||||||
## 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
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
< arithmetic >
|
< arithmetic >
|
||||||
|
|
||||||
0203 LTH .true JMZ
|
0203 LTH .true JMC
|
||||||
|
|
||||||
:false ee BRK
|
:false ee BRK
|
||||||
:true ff BRK
|
:true ff BRK
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
< conditionals >
|
< conditionals >
|
||||||
|
|
||||||
0302 ADD
|
.there ( 0a 05 GTH ) JMC
|
||||||
05 EQU
|
|
||||||
|
|
||||||
.there JMZ
|
|
||||||
|
|
||||||
:here
|
:here
|
||||||
< when not equal >
|
< when not equal >
|
|
@ -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
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
:loop
|
:loop
|
||||||
01 ADD
|
01 ADD
|
||||||
0f NEQ .loop JMZ
|
0f NEQ .loop JMC
|
||||||
RTS
|
RTS
|
||||||
|
|
20
uxn.c
20
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_swp() { Uint8 b = wspop(), a = wspop(); wspush(b); wspush(a); }
|
||||||
void op_ovr() { wspush(cpu.wst.dat[cpu.wst.ptr - 2]); }
|
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_rot() { Uint8 c = wspop(),b = wspop(),a = wspop(); wspush(b); wspush(c); wspush(a); }
|
||||||
void op_jmi() { cpu.rom.ptr = wspop(); }
|
void op_jmu() { cpu.rom.ptr = wspop(); }
|
||||||
void op_jsi() { rspush(cpu.rom.ptr); cpu.rom.ptr = wspop(); }
|
void op_jsu() { 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_jmc() { if(wspop()) op_jmu(); }
|
||||||
void op_jsz() { Uint8 a = wspop(); if(getflag(FLAG_ZERO)){ rspush(cpu.rom.ptr); cpu.rom.ptr = a; } setflag(FLAG_ZERO,0); }
|
void op_jsc() { if(wspop()) op_jsu(); }
|
||||||
void op_equ() { setflag(FLAG_ZERO, wspop() == wspeek()); }
|
void op_equ() { wspush(wspop() == wspop()); }
|
||||||
void op_neq() { setflag(FLAG_ZERO, wspop() != wspeek()); }
|
void op_neq() { wspush(wspop() != wspop()); }
|
||||||
void op_gth() { setflag(FLAG_ZERO, wspop() < wspeek()); }
|
void op_gth() { wspush(wspop() < wspop()); }
|
||||||
void op_lth() { setflag(FLAG_ZERO, wspop() > wspeek()); }
|
void op_lth() { wspush(wspop() > wspop()); }
|
||||||
void op_and() { wspush(wspop() & wspop()); }
|
void op_and() { wspush(wspop() & wspop()); }
|
||||||
void op_ora() { wspush(wspop() | wspop()); }
|
void op_ora() { wspush(wspop() | wspop()); }
|
||||||
void op_rol() { wspush(wspop() << 1); }
|
void op_rol() { wspush(wspop() << 1); }
|
||||||
|
@ -105,12 +105,12 @@ void op_div() { wspush(wspop() / wspop()); }
|
||||||
|
|
||||||
void (*ops[])(void) = {
|
void (*ops[])(void) = {
|
||||||
op_brk, op_rts, op_lit, op_drp, op_dup, op_swp, op_ovr, op_rot,
|
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};
|
op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div};
|
||||||
|
|
||||||
Uint8 opr[][2] = {
|
Uint8 opr[][2] = {
|
||||||
{0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {1,1}, {0,1}, {3,3},
|
{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},
|
{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}
|
||||||
};
|
};
|
||||||
|
|
46
uxnasm.c
46
uxnasm.c
|
@ -17,7 +17,7 @@ WITH REGARD TO THIS SOFTWARE.
|
||||||
typedef unsigned char Uint8;
|
typedef unsigned char Uint8;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int len;
|
int ptr;
|
||||||
Uint8 data[PRGLEN];
|
Uint8 data[PRGLEN];
|
||||||
} Program;
|
} Program;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ Label labels[256];
|
||||||
|
|
||||||
char opcodes[][4] = {
|
char opcodes[][4] = {
|
||||||
"BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT",
|
"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"};
|
"AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"};
|
||||||
|
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
@ -112,7 +112,7 @@ shex(char *s) /* string to num */
|
||||||
void
|
void
|
||||||
pushprg(Uint8 hex)
|
pushprg(Uint8 hex)
|
||||||
{
|
{
|
||||||
p.data[p.len++] = hex;
|
p.data[p.ptr++] = hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -151,13 +151,13 @@ addlabel(char *id, Uint8 addr)
|
||||||
Label *l = &labels[labelslen++];
|
Label *l = &labels[labelslen++];
|
||||||
scpy(suca(id), l->name, LABELIDLEN);
|
scpy(suca(id), l->name, LABELIDLEN);
|
||||||
l->addr = addr;
|
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
|
void
|
||||||
addconst(char *id, Uint8 value)
|
addconst(char *id, Uint8 value)
|
||||||
{
|
{
|
||||||
printf("new const: %s=%02x\n", id, value);
|
printf("New const: %s[%02x]\n", id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Label *
|
Label *
|
||||||
|
@ -181,18 +181,13 @@ findop(char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
getlength(char *w)
|
ismarker(char *w)
|
||||||
{
|
{
|
||||||
if(findop(w) || scmp(w, "BRK")) return 1;
|
return w[0] == '(' || w[0] == ')' || w[0] == '{' || w[0] == '}';
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
comment(char *w, int *skip)
|
iscomment(char *w, int *skip)
|
||||||
{
|
{
|
||||||
if(w[0] == '>') {
|
if(w[0] == '>') {
|
||||||
*skip = 0;
|
*skip = 0;
|
||||||
|
@ -203,15 +198,31 @@ comment(char *w, int *skip)
|
||||||
return 0;
|
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
|
void
|
||||||
pass1(FILE *f)
|
pass1(FILE *f)
|
||||||
{
|
{
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
int addr = 0;
|
int addr = 0;
|
||||||
|
int vars = 0;
|
||||||
char word[64];
|
char word[64];
|
||||||
while(fscanf(f, "%s", word) == 1) {
|
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, addr);
|
||||||
|
if(word[0] == ';') addlabel(word + 1, vars++);
|
||||||
addr += getlength(word);
|
addr += getlength(word);
|
||||||
}
|
}
|
||||||
rewind(f);
|
rewind(f);
|
||||||
|
@ -226,9 +237,12 @@ pass2(FILE *f)
|
||||||
Uint8 op = 0;
|
Uint8 op = 0;
|
||||||
Label *l;
|
Label *l;
|
||||||
if(word[0] == ':') continue;
|
if(word[0] == ':') continue;
|
||||||
|
if(word[0] == ';') continue;
|
||||||
suca(word);
|
suca(word);
|
||||||
if(comment(word, &skip)) continue;
|
if(iscomment(word, &skip) || ismarker(word)) continue;
|
||||||
if((op = findop(word)) || scmp(word, "BRK"))
|
if(word[0] == '@')
|
||||||
|
p.ptr = shex(word + 1);
|
||||||
|
else if((op = findop(word)) || scmp(word, "BRK"))
|
||||||
pushprg(op);
|
pushprg(op);
|
||||||
else if((l = findlabel(word + 1)))
|
else if((l = findlabel(word + 1)))
|
||||||
pushlabel(l);
|
pushlabel(l);
|
||||||
|
|
Loading…
Reference in New Issue