Starting 16bits mode

This commit is contained in:
neauoire 2021-02-04 12:22:08 -08:00
parent 521be808a0
commit 6ac543f312
5 changed files with 162 additions and 143 deletions

View File

@ -10,13 +10,27 @@ 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) ### Write
- `:label`, a named address
- `.pointer`, a pointer to a label - `;variable`, set a name to address on the zero-page
- `@0010`, a position in the program - `:label`, set a name to an address
### Read
- `,literal`, get a literal pointer
- `.pointer`, get a raw pointer
### Special
- `@0010`, move to position in the program
- `( comment )`
``` ```
< conditionals > ( comment )
;variable1
;variable2
;variable3
.there ( 0a 05 GTH ) JMC .there ( 0a 05 GTH ) JMC

View File

@ -1,13 +1,3 @@
< conditionals > ( comment )
.there ( 0a 05 GTH ) JMC ,abcd ,ef STR
:here
< when not equal >
ee
BRK
:there
< when is equal >
ff
BRK

11
examples/vectors.usm Normal file
View File

@ -0,0 +1,11 @@
< vectors >
:RESET BRK
:FRAME BRK
:ERROR BRK
@FFFA < vectors >
.RESET
.FRAME
.ERROR

23
uxn.c
View File

@ -74,6 +74,13 @@ echo(Stack *s, Uint8 len, char *name)
void wspush(Uint8 v) { cpu.wst.dat[cpu.wst.ptr++] = v; } void wspush(Uint8 v) { cpu.wst.dat[cpu.wst.ptr++] = v; }
Uint8 wspop(void) { return cpu.wst.dat[--cpu.wst.ptr]; } Uint8 wspop(void) { return cpu.wst.dat[--cpu.wst.ptr]; }
Uint16 wspop16(void) {
Uint8 a = cpu.wst.dat[--cpu.wst.ptr];
Uint8 b = cpu.wst.dat[--cpu.wst.ptr];
return a + (b << 8);
}
Uint8 wspeek(void) { return cpu.wst.dat[cpu.wst.ptr - 1]; } Uint8 wspeek(void) { return cpu.wst.dat[cpu.wst.ptr - 1]; }
void rspush(Uint8 v) { cpu.rst.dat[cpu.rst.ptr++] = v; } void rspush(Uint8 v) { cpu.rst.dat[cpu.rst.ptr++] = v; }
Uint8 rspop(void) { return cpu.rst.dat[--cpu.rst.ptr]; } Uint8 rspop(void) { return cpu.rst.dat[--cpu.rst.ptr]; }
@ -102,17 +109,27 @@ void op_add() { wspush(wspop() + wspop()); }
void op_sub() { wspush(wspop() - wspop()); } void op_sub() { wspush(wspop() - wspop()); }
void op_mul() { wspush(wspop() * wspop()); } void op_mul() { wspush(wspop() * wspop()); }
void op_div() { wspush(wspop() / wspop()); } void op_div() { wspush(wspop() / wspop()); }
void op_ldr() { }
void op_str() {
Uint8 b = wspop();
Uint16 addr = wspop16();
printf("store: %02x @ %04x\n", b, addr);
}
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_jmu, op_jsu, op_jmc, op_jsc, 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,
op_ldr, op_str, op_brk, op_brk, op_brk, op_brk, op_brk, op_brk
};
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},
{2,0}, {2,0}, {2,0}, {2,0}, {2,1}, {2,1}, {2,1}, {2,1}, {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},
{3,1}, {3,1}
}; };
/* clang-format on */ /* clang-format on */
@ -155,7 +172,7 @@ eval()
cpu.literal--; cpu.literal--;
return 1; return 1;
} }
if(instr < 24) { if(instr < 32) {
if(cpu.wst.ptr < opr[instr][0]) if(cpu.wst.ptr < opr[instr][0])
return error("Stack underflow"); return error("Stack underflow");
/* TODO stack overflow */ /* TODO stack overflow */

233
uxnasm.c
View File

@ -11,19 +11,17 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define PRGLEN 256
#define LABELIDLEN 32
typedef unsigned char Uint8; typedef unsigned char Uint8;
typedef unsigned short Uint16;
typedef struct { typedef struct {
int ptr; int ptr;
Uint8 data[PRGLEN]; Uint8 data[65536];
} Program; } Program;
typedef struct { typedef struct {
Uint8 addr; Uint16 addr;
char name[LABELIDLEN]; char name[64];
} Label; } Label;
int labelslen; int labelslen;
@ -34,7 +32,9 @@ 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",
"JMU", "JSU", "JMC", "JSC", "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",
"LDR", "STR", "---", "---", "---", "---", "---", "---"
};
/* clang-format on */ /* clang-format on */
@ -82,7 +82,7 @@ suca(char *s) /* string to uppercase */
} }
int int
sihx(char *s) sihx(char *s) /* string is hexadecimal */
{ {
int i = 0; int i = 0;
char c; char c;
@ -107,59 +107,68 @@ shex(char *s) /* string to num */
return n; return n;
} }
int
ismarker(char *w)
{
return w[0] == '[' || w[0] == ']' || w[0] == '{' || w[0] == '}';
}
int
iscomment(char *w, int *skip)
{
if(w[0] == ')') {
*skip = 0;
return 1;
}
if(w[0] == '(') *skip = 1;
if(*skip) return 1;
return 0;
}
#pragma mark - I/O
void
pushbyte(Uint8 b, int lit)
{
if(lit) {
pushbyte(0x02, 0);
pushbyte(0x01, 0);
}
p.data[p.ptr++] = b;
}
void
pushshort(Uint16 s, int lit)
{
if(lit) {
pushbyte(0x02, 0);
pushbyte(0x02, 0);
}
pushbyte((s >> 8) & 0xff, 0);
pushbyte(s & 0xff, 0);
}
#pragma mark - Parser #pragma mark - Parser
void Uint8
pushprg(Uint8 hex) findop(char *s)
{ {
p.data[p.ptr++] = hex; int i;
for(i = 0; i < 32; ++i)
if(scmp(opcodes[i], s))
return i;
return 0;
} }
void void
pushlabel(Label *l) makelabel(char *id, Uint8 addr)
{
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++]; Label *l = &labels[labelslen++];
scpy(suca(id), l->name, LABELIDLEN); scpy(suca(id), l->name, 64);
l->addr = addr; l->addr = addr;
printf("New label: %s[0x%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);
}
Label * Label *
findlabel(char *s) findlabel(char *s)
{ {
@ -170,94 +179,72 @@ findlabel(char *s)
return NULL; return NULL;
} }
Uint8 #pragma mark - Parser
findop(char *s)
int
error(char *name, char *id)
{ {
int i; printf("Error: %s - %s\n", name, id);
for(i = 0; i < 24; ++i)
if(scmp(opcodes[i], s))
return i;
return 0; return 0;
} }
int int
ismarker(char *w)
{
return w[0] == '(' || w[0] == ')' || w[0] == '{' || w[0] == '}';
}
int
iscomment(char *w, int *skip)
{
if(w[0] == '>') {
*skip = 0;
return 1;
}
if(w[0] == '<') *skip = 1;
if(*skip) return 1;
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) pass1(FILE *f)
{ {
int skip = 0; int skip = 0, addr = 0, vars = 0;
int addr = 0; char w[64];
int vars = 0; while(fscanf(f, "%s", w) == 1) {
char word[64]; if(iscomment(w, &skip)) continue;
while(fscanf(f, "%s", word) == 1) { if(w[0] == ':') makelabel(w + 1, addr);
if(iscomment(word, &skip)) continue; if(w[0] == ';') makelabel(w + 1, vars++);
if(word[0] == ':') addlabel(word + 1, addr); /* move addr ptr */
if(word[0] == ';') addlabel(word + 1, vars++); if(findop(w) || scmp(w, "BRK"))
addr += getlength(word); addr += 1;
else if(w[0] == '@')
addr += 0;
else if(w[0] == ':')
addr += 0;
else if(w[0] == ';')
addr += 0;
else if(w[0] == '.')
addr += 2;
else if(w[0] == ',')
addr += 4;
else if(ismarker(w))
addr += 0;
else
return error("Unknown label(pass1)", w);
} }
rewind(f); rewind(f);
return 1;
} }
void int
pass2(FILE *f) pass2(FILE *f)
{ {
int skip = 0; int skip = 0;
char word[64]; char w[64];
while(fscanf(f, "%s", word) == 1) { while(fscanf(f, "%s", w) == 1) {
Uint8 op = 0; Uint8 op = 0;
Label *l; Label *l;
if(word[0] == ':') continue; if(w[0] == ':') continue;
if(word[0] == ';') continue; if(w[0] == ';') continue;
suca(word); suca(w);
if(iscomment(word, &skip) || ismarker(word)) continue; if(iscomment(w, &skip) || ismarker(w)) continue;
if(word[0] == '@') if(w[0] == '@')
p.ptr = shex(word + 1); p.ptr = shex(w + 1);
else if((op = findop(word)) || scmp(word, "BRK")) else if((op = findop(w)) || scmp(w, "BRK"))
pushprg(op); pushbyte(op, 0);
else if((l = findlabel(word + 1))) else if((l = findlabel(w + 1)))
pushlabel(l); pushshort(l->addr, w[0] == ',');
else if(sihx(word)) else if(sihx(w + 1) && slen(w + 1) == 2)
pushliteral(word); pushbyte(shex(w + 1), w[0] == ',');
else if(sihx(w + 1) && slen(w + 1) == 4)
pushshort(shex(w + 1), w[0] == ',');
else else
printf("Unknown label: %s\n", word); return error("Unknown label(pass2)", w);
} }
} return 1;
int
error(char *name)
{
printf("Error: %s\n", name);
return 0;
} }
int int
@ -265,11 +252,11 @@ main(int argc, char *argv[])
{ {
FILE *f; FILE *f;
if(argc < 3) if(argc < 3)
return error("No input."); return error("Input", "Missing");
if(!(f = fopen(argv[1], "r"))) if(!(f = fopen(argv[1], "r")))
return error("Missing input."); return error("Open", "Failed");
pass1(f); if(!pass1(f) || !pass2(f))
pass2(f); return error("Assembly", "Failed");
fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb")); fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
fclose(f); fclose(f);
return 0; return 0;