mirror of
https://github.com/emptyynes/LIVM.git
synced 2025-01-04 23:52: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