commit 099d1f08455ceffce3512e6a7655c0d3df70ffe4
parent 72d9c98f358c54d3d082ef61761ba768ba8a68c3
Author: neauoire <aliceffekt@gmail.com>
Date: Fri, 29 Jan 2021 21:56:19 -0800
*
Diffstat:
6 files changed, 125 insertions(+), 57 deletions(-)
diff --git a/.clang-format b/.clang-format
@@ -1,7 +1,9 @@
AlignAfterOpenBracket: DontAlign
AlignEscapedNewlines: DontAlign
+AlignOperands: DontAlign
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: true
+AllowShortEnumsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
diff --git a/build.sh b/build.sh
@@ -7,10 +7,11 @@ clang-format -i uxn.c
# remove old
rm -f ./uxnasm
rm -f ./uxn
+rm -f ./boot.rom
# debug(slow)
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxnasm.c -o uxnasm
-# cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c -o uxn
+cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c -o uxn
# build(fast)
# cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
@@ -19,5 +20,5 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr
# echo "Size: $(du -sk ./uxn)"
# run
-./uxnasm program.usm program.rom
-# ./uxn program.rom
+./uxnasm example.usm boot.rom
+./uxn boot.rom
diff --git a/example.usm b/example.usm
@@ -0,0 +1 @@
+{ 25 26 27 28 } SWP POP DUP BRK
+\ No newline at end of file
diff --git a/program.usm b/program.usm
@@ -1 +0,0 @@
-LIT 25 26 LIT DUP ADD BRK
-\ No newline at end of file
diff --git a/uxn.c b/uxn.c
@@ -11,20 +11,38 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
+#define FLAG_HALT 0x01
+#define FLAG_ZERO 0x02
+#define FLAG_CARRY 0x04
+#define FLAG_TRAPS 0x08
+
#define STACK_DEPTH 256
-#define ECHO 1
typedef unsigned char Uint8;
-typedef unsigned char Uint16;
typedef struct {
-
+ Uint8 literal;
+ Uint8 status, counter;
+ Uint8 memory[STACK_DEPTH];
+ Uint8 mptr, sptr;
+ Uint8 stack[STACK_DEPTH];
+ Uint8 address[STACK_DEPTH];
} Computer;
-Uint8 sptr;
-Uint8 stack[STACK_DEPTH];
-Uint8 address[STACK_DEPTH];
-Uint16 memory[STACK_DEPTH];
+void
+setflag(Computer *cpu, char flag, int b)
+{
+ if(b)
+ cpu->status |= flag;
+ else
+ cpu->status &= (~flag);
+}
+
+int
+getflag(Computer *cpu, char flag)
+{
+ return cpu->status & flag;
+}
void
echo(Uint8 *s, Uint8 len, char *name)
@@ -34,51 +52,79 @@ echo(Uint8 *s, Uint8 len, char *name)
for(i = 0; i < len; ++i) {
if(i % 16 == 0)
printf("\n");
- if(sptr == i)
- printf("[%02x]", s[i]);
- else
- printf(" %02x ", s[i]);
+ printf("%02x ", s[i]);
}
- printf("\n");
+ printf("\n\n");
}
void
-op_push(Uint8 *s, Uint8 v)
+op_push(Uint8 *s, Uint8 *ptr, Uint8 v)
{
- s[sptr++] = v;
+ s[*ptr] = v;
+ (*ptr) += 1;
}
void
-op_pop(Uint8 *s)
+op_pop(Uint8 *s, Uint8 *ptr)
{
- s[sptr--] = 0x00;
+ s[*ptr--] = 0x00;
}
void
reset(Computer *cpu)
{
+ int i;
+ cpu->status = 0x00;
+ cpu->counter = 0x00;
+ cpu->mptr = 0x00;
+ cpu->sptr = 0x00;
+ cpu->literal = 0x00;
+ for(i = 0; i < 256; i++)
+ cpu->stack[i] = 0x00;
}
int
-disk(Computer *cpu, FILE *f)
+error(char *name)
{
- int i;
- unsigned short buffer[256];
- reset(cpu);
- if(!fread(buffer, sizeof(buffer), 1, f))
- return 0;
-
- for(i = 0; i < 128; i++) {
- cpu->memory[i * 2] |= (buffer[i] >> 8) & 0xFF;
- cpu->memory[i * 2 + 1] |= buffer[i] & 0xFF;
- }
+ printf("Error: %s\n", name);
+ return 0;
+}
+
+void
+load(Computer *cpu, FILE *f)
+{
+ fread(cpu->memory, sizeof(cpu->memory), 1, f);
+}
- return 1;
+void
+eval(Computer *cpu)
+{
+ Uint8 instr = cpu->memory[cpu->mptr++];
+
+ if(cpu->literal > 0) {
+ printf("push: %02x[%d](%d)\n", instr, cpu->literal, cpu->sptr);
+ op_push(cpu->stack, &cpu->sptr, instr);
+ cpu->literal--;
+ return;
+ }
+ switch(instr) {
+ case 0x0: setflag(cpu, FLAG_HALT, 1); break;
+ case 0x1: cpu->literal += 4; break;
+ default: printf("Unknown instruction: #%02x\n", instr);
+ }
}
void
-run(Computer *cpu, int debug)
+run(Computer *cpu)
{
+ int i;
+ while((cpu->status & FLAG_HALT) == 0)
+ eval(cpu);
+ /* debug */
+ printf("ended @ %d | ", cpu->counter);
+ for(i = 0; i < 4; i++)
+ printf("%d-", (cpu->status & (1 << i)) != 0);
+ printf("\n\n");
}
int
@@ -90,11 +136,11 @@ main(int argc, char *argv[])
return error("No input.");
if(!(f = fopen(argv[1], "rb")))
return error("Missing input.");
- if(!disk(&cpu, f))
- return error("Unreadable input.");
- run(&cpu, ECHO);
+ reset(&cpu);
+ load(&cpu, f);
+ run(&cpu);
/* print result */
- echo(stack, 0x40, "stack");
- echo(memory, 0x40, "memory");
+ echo(cpu.stack, 0x40, "stack");
+ echo(cpu.memory, 0x40, "memory");
return 0;
}
diff --git a/uxnasm.c b/uxnasm.c
@@ -20,7 +20,39 @@ typedef struct {
Uint8 data[PRGLEN];
} Program;
-char opcodes[][4] = {"BRK", "LIT", "DUP", "DRP", "SWP", "SLP", "PSH", "POP", "JMP", "JSR", "RST", "BEQ", "EQU", "NEQ", "LTH", "GTH"};
+char opcodes[][4] = {
+ "BRK",
+ "LIT",
+ "DUP",
+ "DRP",
+ "SWP",
+ "SLP",
+ "PSH",
+ "POP", /* --- */
+ "JMP",
+ "JSR",
+ "RST",
+ "BEQ",
+ "EQU",
+ "NEQ",
+ "LTH",
+ "GTH", /* --- */
+ "---",
+ "---",
+ "---",
+ "---",
+ "---",
+ "---",
+ "---",
+ "---", /* --- */
+ "---",
+ "---",
+ "---",
+ "---",
+ "---",
+ "---",
+ "---",
+ "---"};
Program p;
@@ -65,6 +97,8 @@ Uint8
getopcode(char *s)
{
int i;
+ if(s[0] == '{') /* TODO catch closing */
+ return 0x01;
for(i = 0; i < 16; ++i)
if(scmp(opcodes[i], suca(s)))
return i;
@@ -72,27 +106,13 @@ getopcode(char *s)
}
void
-echo(Uint8 *s, Uint8 len, Uint8 ptr, char *name)
-{
- int i;
- printf("%s\n", name);
- for(i = 0; i < len; ++i) {
- if(i % 16 == 0)
- printf("\n");
- if(ptr == i)
- printf("[%02x]", s[i]);
- else
- printf(" %02x ", s[i]);
- }
- printf("\n");
-}
-
-void
pass1(FILE *f)
{
char word[64];
while(fscanf(f, "%s", word) == 1) {
int op = getopcode(word);
+ if(word[0] == '}')
+ continue;
if(op == 0xff)
op = shex(word);
p.data[p.ptr++] = op;
@@ -117,6 +137,5 @@ main(int argc, char *argv[])
pass1(f);
fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
fclose(f);
- echo(p.data, 0x40, 0, "program");
return 0;
}