mirror of
https://github.com/emptyynes/LIVM.git
synced 2025-01-06 16:42:25 +03:00
Add files via upload
This commit is contained in:
parent
2c17fb4918
commit
bbcd65b937
4 changed files with 398 additions and 0 deletions
163
LIVM.c
Normal file
163
LIVM.c
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
uint64_t pc, cc;
|
||||||
|
void* ram;
|
||||||
|
|
||||||
|
uint8_t* ramu8;
|
||||||
|
uint16_t* ramu16;
|
||||||
|
uint32_t* ramu32;
|
||||||
|
uint64_t* ramu64;
|
||||||
|
int8_t* ram8;
|
||||||
|
int16_t* ram16;
|
||||||
|
int32_t* ram32;
|
||||||
|
int64_t* ram64;
|
||||||
|
float* ramf;
|
||||||
|
double* ramd;
|
||||||
|
|
||||||
|
|
||||||
|
#include "device.c"
|
||||||
|
|
||||||
|
|
||||||
|
void allocLIVM(uint64_t size) {
|
||||||
|
ram = malloc(size);
|
||||||
|
ramu8 = (uint8_t*)ram, ramu16 = (uint16_t*)ram,
|
||||||
|
ramu32 = (uint32_t*)ram, ramu64 = (uint64_t*)ram;
|
||||||
|
ram8 = (int8_t*)ram, ram16 = (int16_t*)ram,
|
||||||
|
ram32 = (int32_t*)ram, ram64 = (int64_t*)ram;
|
||||||
|
ramf = (float*)ram, ramd = (double*)ram;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum opcode {
|
||||||
|
NOP, END, // 2
|
||||||
|
LDA, LDB, LDC, // 3
|
||||||
|
ULA, ULB, ULC, // 3
|
||||||
|
CST, SSM, // 2
|
||||||
|
JMP, IVE, SLE, SIP, // 4
|
||||||
|
SUB, SUM, MUL, DIV, MOD, POW, // 6
|
||||||
|
INC, DEC, // 2
|
||||||
|
AND, BOR, XOR, NOT, // 4
|
||||||
|
EQU, LTH, GTH, // 3
|
||||||
|
OFR, WAI, OUT, GET, // 4
|
||||||
|
ALC, RLC, FRE, CPY, ADD, CAT, // 6
|
||||||
|
PRC // 1
|
||||||
|
/*
|
||||||
|
TODO: PRC
|
||||||
|
PRC - process
|
||||||
|
PRC 0 - create a new process with id = a
|
||||||
|
PRC 1 - kill process with id = a
|
||||||
|
PRC 2 - set offset = b for process with id = a
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
void print_ullram() {
|
||||||
|
for (int i = 0; i < 100; i++) printf("%llu ", ramu64[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
register uint_least64_t ip = 0;
|
||||||
|
register uint_least64_t a = 0, b = 0, c = 0, s = 0, op, arg;
|
||||||
|
register uint8_t running = 1, mode_int = 1, size_mode = 1;
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
switch (size_mode) {
|
||||||
|
case 0:
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype uint8_t
|
||||||
|
#define xram ramu8
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype int8_t
|
||||||
|
#define xram ram8
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype uint16_t
|
||||||
|
#define xram ramu16
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype int16_t
|
||||||
|
#define xram ram16
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype uint32_t
|
||||||
|
#define xram ramu32
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype int32_t
|
||||||
|
#define xram ram32
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype uint64_t
|
||||||
|
#define xram ramu64
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype int64_t
|
||||||
|
#define xram ram64
|
||||||
|
#include "xcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype float
|
||||||
|
#define xram ramf
|
||||||
|
#include "xfcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
while (mode_int) {
|
||||||
|
#define xtype double
|
||||||
|
#define xram ramd
|
||||||
|
#include "xfcase.c"
|
||||||
|
#undef xtype
|
||||||
|
#undef xram
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mode_int = 1;
|
||||||
|
}
|
||||||
|
free(ram);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadBIOS(uint64_t length, uint64_t* data) {
|
||||||
|
for (register uint64_t i = 0; i < length; ++i) ramu64[i] = data[i];
|
||||||
|
}
|
111
device.c
Normal file
111
device.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#define opargs uint64_t a, uint64_t b, uint64_t c
|
||||||
|
typedef void opfunc(opargs);
|
||||||
|
typedef uint64_t rdfunc(opargs);
|
||||||
|
|
||||||
|
struct Device {
|
||||||
|
uint64_t* buffer;
|
||||||
|
uint64_t* data;
|
||||||
|
uint64_t* rdata;
|
||||||
|
opfunc* offer;
|
||||||
|
opfunc* wait;
|
||||||
|
opfunc* out;
|
||||||
|
rdfunc* read;
|
||||||
|
};
|
||||||
|
|
||||||
|
void d_null_writef(opargs) {}
|
||||||
|
uint64_t d_null_readf(opargs) {}
|
||||||
|
|
||||||
|
struct Device d_null = {
|
||||||
|
.buffer = NULL,
|
||||||
|
.data = NULL,
|
||||||
|
.rdata = NULL,
|
||||||
|
.offer = d_null_writef,
|
||||||
|
.wait = d_null_writef,
|
||||||
|
.out = d_null_writef,
|
||||||
|
.read = d_null_readf
|
||||||
|
};
|
||||||
|
|
||||||
|
void d_clock_offer(opargs) {}
|
||||||
|
void d_clock_out(opargs) {}
|
||||||
|
void d_clock_wait(opargs) {
|
||||||
|
usleep(a * 1000);
|
||||||
|
}
|
||||||
|
uint64_t d_clock_read(opargs) {
|
||||||
|
return (uint64_t)clock();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Device d_clock = {
|
||||||
|
.buffer = NULL,
|
||||||
|
.data = NULL,
|
||||||
|
.rdata = NULL,
|
||||||
|
.offer = d_clock_offer,
|
||||||
|
.wait = d_clock_wait,
|
||||||
|
.out = d_clock_out,
|
||||||
|
.read = d_clock_read
|
||||||
|
};
|
||||||
|
|
||||||
|
# ifdef CONSOLE_D
|
||||||
|
void d_console_offer(opargs);
|
||||||
|
void d_console_out(opargs);
|
||||||
|
void d_console_wait(opargs);
|
||||||
|
uint64_t d_console_read(opargs);
|
||||||
|
|
||||||
|
struct Device d_console = {
|
||||||
|
.buffer = (uint64_t[1024]){ [0 ... 1023] = 0 },
|
||||||
|
.data = (uint64_t[800]){ [0 ... 799] = 0 },
|
||||||
|
.rdata = (uint64_t[1]){ 0 },
|
||||||
|
.offer = d_console_offer,
|
||||||
|
.wait = d_console_wait,
|
||||||
|
.out = d_console_out,
|
||||||
|
.read = d_console_read
|
||||||
|
};
|
||||||
|
|
||||||
|
void d_console_offer(opargs) {
|
||||||
|
if (a == 0) return;
|
||||||
|
uint64_t* cursor = d_console.buffer;
|
||||||
|
uint8_t* data = (uint8_t*)(d_console.buffer + 1);
|
||||||
|
if (c == 1) {
|
||||||
|
(*cursor) = a;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (*cursor >= 3200) return;
|
||||||
|
if (a == 1)
|
||||||
|
data[*cursor++] = b;
|
||||||
|
else {
|
||||||
|
if ((*cursor + a) >= 3200) return;
|
||||||
|
for (uint64_t i = 0; i < a; i++)
|
||||||
|
data[(*cursor)++] = ramu8[b + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void d_console_out(opargs) {
|
||||||
|
uint8_t* _data = (uint8_t*)(d_console.buffer + 1);
|
||||||
|
uint64_t* _data64 = (uint64_t*)_data;
|
||||||
|
for (uint64_t i = 0; i < 400; i++)
|
||||||
|
d_console.data[i] = _data64[i];
|
||||||
|
d_console.buffer[0] = 0;
|
||||||
|
printf("\e[H");
|
||||||
|
for (uint64_t i = 0; i < 40; i++) {
|
||||||
|
for (uint64_t j = 0; j < 80; j++) {
|
||||||
|
if (((uint8_t*)d_console.data)[j + i * 80])
|
||||||
|
putchar(((uint8_t*)d_console.data)[j + i * 80]);
|
||||||
|
else putchar(' ');
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void d_console_wait(opargs) {
|
||||||
|
d_console.rdata[0] = getchar();
|
||||||
|
}
|
||||||
|
uint64_t d_console_read(opargs) {
|
||||||
|
return d_console.rdata[0];
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# define d_console d_null
|
||||||
|
# endif
|
||||||
|
|
||||||
|
struct Device* vm_dev[2] = { &d_clock, &d_console };
|
||||||
|
|
||||||
|
# ifdef d_console
|
||||||
|
# undef d_console
|
||||||
|
# endif
|
||||||
|
#undef opargs
|
66
xcase.c
Normal file
66
xcase.c
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// what is a template/generic?
|
||||||
|
op = ramu64[ip], arg = ramu64[ip + 1];
|
||||||
|
//printf("%d | %d %d: a[%d] b[%d] c[%d]\n", ip / 2 + 1, op, arg, a, b, c);
|
||||||
|
//uint8_t dx = getchar();
|
||||||
|
switch (op) {
|
||||||
|
case NOP: break;
|
||||||
|
case END: break;
|
||||||
|
case LDA: a = xram[arg]; break;
|
||||||
|
case LDB: b = xram[arg]; break;
|
||||||
|
case LDC: c = xram[arg]; break;
|
||||||
|
case ULA: xram[arg] = (xtype) a; break;
|
||||||
|
case ULB: xram[arg] = (xtype) b; break;
|
||||||
|
case ULC: xram[arg] = (xtype) c; break;
|
||||||
|
case CST:
|
||||||
|
switch (arg) {
|
||||||
|
case 0: break;
|
||||||
|
case 1: a = (uint8_t) a; break;
|
||||||
|
case 2: a = (int8_t) a; break;
|
||||||
|
case 3: a = (uint16_t) a; break;
|
||||||
|
case 4: a = (int16_t) a; break;
|
||||||
|
case 5: a = (uint32_t) a; break;
|
||||||
|
case 6: a = (int32_t) a; break;
|
||||||
|
case 7: a = (uint64_t) a; break;
|
||||||
|
case 8: a = (int64_t) a; break;
|
||||||
|
case 9: a = (float) a; break;
|
||||||
|
case 10: a = (double) a; break;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case SSM: size_mode = arg; mode_int = 0; break;
|
||||||
|
case JMP: ip = a; break;
|
||||||
|
case IVE: if (c) ip = a; break;
|
||||||
|
case SLE: if (!c) ip = a; break;
|
||||||
|
case SIP: a = ip; break;
|
||||||
|
case SUB: a -= b; break;
|
||||||
|
case SUM: a += b; break;
|
||||||
|
case MUL: a *= b; break;
|
||||||
|
case DIV: a /= b; break;
|
||||||
|
case MOD: a %= b; break;
|
||||||
|
case POW: a = pow(a, b); break;
|
||||||
|
case INC: a++; break;
|
||||||
|
case DEC: a--; break;
|
||||||
|
case AND: a &= b; break;
|
||||||
|
case BOR: a |= b; break;
|
||||||
|
case XOR: a ^= b; break;
|
||||||
|
case NOT: a = !a; break;
|
||||||
|
case EQU: a = a == b; break;
|
||||||
|
case LTH: a = a < b; break;
|
||||||
|
case GTH: a = a > b; break;
|
||||||
|
case OFR: vm_dev[arg]->offer(a, b, c); break;
|
||||||
|
case WAI: vm_dev[arg]->wait(a, b, c); break;
|
||||||
|
case OUT: vm_dev[arg]->out(a, b, c); break;
|
||||||
|
case REA: a = vm_dev[arg]->read(a, b, c); break;
|
||||||
|
case ALC: break;
|
||||||
|
case RLC: break;
|
||||||
|
case FRE: break;
|
||||||
|
case CPY: break;
|
||||||
|
case ADD: break;
|
||||||
|
case CAT: break;
|
||||||
|
case PRC: break;
|
||||||
|
}
|
||||||
|
ip += 2;
|
||||||
|
/*if (dx == '?') {
|
||||||
|
getchar();
|
||||||
|
for(uint64_t i = 0; i < 50; i++) printf("%u ", ((uint8_t*)d_console.buffer)[i]);
|
||||||
|
puts("");
|
||||||
|
}*/
|
58
xfcase.c
Normal file
58
xfcase.c
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// what is a template/generic?
|
||||||
|
switch (op) {
|
||||||
|
case NOP: break;
|
||||||
|
case END: break;
|
||||||
|
case LDA: a = xram[arg]; break;
|
||||||
|
case LDB: b = xram[arg]; break;
|
||||||
|
case LDC: c = xram[arg]; break;
|
||||||
|
case ULA: xram[arg] = (xtype) a; break;
|
||||||
|
case ULB: xram[arg] = (xtype) b; break;
|
||||||
|
case ULC: xram[arg] = (xtype) c; break;
|
||||||
|
case CST:
|
||||||
|
switch (arg) {
|
||||||
|
case 0: break;
|
||||||
|
case 1: a = (uint8_t) a; break;
|
||||||
|
case 2: a = (int8_t) a; break;
|
||||||
|
case 3: a = (uint16_t) a; break;
|
||||||
|
case 4: a = (int16_t) a; break;
|
||||||
|
case 5: a = (uint32_t) a; break;
|
||||||
|
case 6: a = (int32_t) a; break;
|
||||||
|
case 7: a = (uint64_t) a; break;
|
||||||
|
case 8: a = (int64_t) a; break;
|
||||||
|
case 9: a = (float) a; break;
|
||||||
|
case 10: a = (double) a; break;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case SSM: size_mode = arg; mode_int = 0; break;
|
||||||
|
case JMP: ip = a; break;
|
||||||
|
case IVE: if (c) ip = arg; break;
|
||||||
|
case SLE: if (!c) ip = arg; break;
|
||||||
|
case SIP: a = ip; break;
|
||||||
|
case SUB: a -= b; break;
|
||||||
|
case SUM: a += b; break;
|
||||||
|
case MUL: a *= b; break;
|
||||||
|
case DIV: a /= b; break;
|
||||||
|
case MOD: a %= b; break;
|
||||||
|
case POW: a = pow(a, b); break;
|
||||||
|
case INC: c++; break;
|
||||||
|
case DEC: c--; break;
|
||||||
|
case AND: a &= b; break;
|
||||||
|
case BOR: a |= b; break;
|
||||||
|
case XOR: a ^= b; break;
|
||||||
|
case NOT: a = !a; break;
|
||||||
|
case EQU: a = a == b; break;
|
||||||
|
case LTH: a = a < b; break;
|
||||||
|
case GTH: a = a > b; break;
|
||||||
|
case OFR: vm_dev[arg]->offer(a, b, c); break;
|
||||||
|
case WAI: vm_dev[arg]->wait(a, b, c); break;
|
||||||
|
case OUT: vm_dev[arg]->out(a, b, c); break;
|
||||||
|
case REA: a = vm_dev[arg]->read(a, b, c); break;
|
||||||
|
case ALC: break;
|
||||||
|
case RLC: break;
|
||||||
|
case FRE: break;
|
||||||
|
case CPY: break;
|
||||||
|
case ADD: break;
|
||||||
|
case CAT: break;
|
||||||
|
case PRC: break;
|
||||||
|
}
|
||||||
|
ip += 2;
|
Loading…
Reference in a new issue