0
0
Fork 0
mirror of https://git.sr.ht/~rabbits/uxn synced 2024-11-25 07:15:12 +00:00
This commit is contained in:
neauoire 2021-01-29 21:56:19 -08:00
parent 72d9c98f35
commit 099d1f0845
6 changed files with 125 additions and 57 deletions

View file

@ -1,7 +1,9 @@
AlignAfterOpenBracket: DontAlign
AlignEscapedNewlines: DontAlign
AlignOperands: DontAlign
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel

View file

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

1
example.usm Normal file
View file

@ -0,0 +1 @@
{ 25 26 27 28 } SWP POP DUP BRK

View file

@ -1 +0,0 @@
LIT 25 26 LIT DUP ADD BRK

116
uxn.c
View file

@ -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;
}
return 1;
printf("Error: %s\n", name);
return 0;
}
void
run(Computer *cpu, int debug)
load(Computer *cpu, FILE *f)
{
fread(cpu->memory, sizeof(cpu->memory), 1, f);
}
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 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;
}

View file

@ -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,34 +97,22 @@ 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;
return 0xff;
}
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;
}