From 5a5bed307d628ac02224ce67d39ee393d8dfbdce Mon Sep 17 00:00:00 2001 From: attilavs2 Date: Sat, 27 Jul 2024 21:49:56 +0200 Subject: [PATCH] Initial commit --- assembl/Makefile | 2 + assembl/a.out | Bin 0 -> 17792 bytes assembl/src/main.c | 254 +++++++++++++++++++++++++++ interpr/Makefile | 5 + interpr/a.out | Bin 0 -> 16336 bytes interpr/src/main.c | 421 +++++++++++++++++++++++++++++++++++++++++++++ spec.txt | 332 +++++++++++++++++++++++++++++++++++ 7 files changed, 1014 insertions(+) create mode 100644 assembl/Makefile create mode 100755 assembl/a.out create mode 100644 assembl/src/main.c create mode 100644 interpr/Makefile create mode 100755 interpr/a.out create mode 100644 interpr/src/main.c create mode 100644 spec.txt diff --git a/assembl/Makefile b/assembl/Makefile new file mode 100644 index 0000000..4976b37 --- /dev/null +++ b/assembl/Makefile @@ -0,0 +1,2 @@ +[all]: + gcc src/main.c -lm diff --git a/assembl/a.out b/assembl/a.out new file mode 100755 index 0000000000000000000000000000000000000000..19ede811df3ef3829b4a5d0e1c62024329116b43 GIT binary patch literal 17792 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 Kn5Q{tqWCZD<;tZ1 literal 0 HcmV?d00001 diff --git a/assembl/src/main.c b/assembl/src/main.c new file mode 100644 index 0000000..4d47ad3 --- /dev/null +++ b/assembl/src/main.c @@ -0,0 +1,254 @@ +#include +#include +#include +#include + +typedef struct{ + + int id; + + int ntyps; + + //Bitfields representing possible arg combinations: + //(Using left to right big endian naming) + // upper 4 bits : left arg / arg1 + // lower 4 bits : right arg / arg2 + //0 : rm/rn + //1 : r0 + //2 : *rm/*rn + //3 : #imm + //4 : *#imm + //5 : sr + //6 : *sr + //7 : sr0-1 + //F : none + uint8_t argtyps[7]; + + //Opcodes for the different types, a 0xF + //nibble indicates replaceable + uint16_t opcodes[7]; + +} InstrDef; + +#define INSTR_DICT_S 29 + +InstrDef instr_dict[INSTR_DICT_S] = { + {0 ,1, {0xFF,0,0,0,0,0,0},{0,0,0,0,0,0,0}},//nop + {1 ,7, {0x00,0x03,0x02,0x04,0x20,0x40,0x22},{0x20FF,0x8FFF,0xB0FF,0x9FFF,0xB1FF,0xAFFF,0xB2FF}},//mov + {2 ,2, {0x06,0x60,0,0,0,0,0},{0xB3FF,0xB4FF,0,0,0,0,0}},//mmv + {3 ,1, {0x0F,0,0,0,0,0,0},{0xB5F0,0,0,0,0,0,0}},//psh + {4 ,1, {0x0F,0,0,0,0,0,0},{0xB6F0,0,0,0,0,0,0}},//pop + {5 ,1, {0x70,0,0,0,0,0,0},{0xE0FF,0,0,0,0,0,0}},//lds + {6 ,1, {0x07,0,0,0,0,0,0},{0xE1FF,0,0,0,0,0,0}},//sts + {7 ,2, {0x00,0x13,0,0,0,0,0},{0x40FF,0x48FF,0,0,0,0,0}},//add + {8 ,1, {0x70,0,0,0,0,0,0},{0xE2FF,0,0,0,0,0,0}},//sad + {9 ,1, {0x00,0,0,0,0,0,0},{0x41FF,0,0,0,0,0,0}},//sub + {10,1, {0x0F,0,0,0,0,0,0},{0x42F0,0,0,0,0,0,0}},//shl + {11,1, {0x0F,0,0,0,0,0,0},{0x43F0,0,0,0,0,0,0}},//shr + {12,1, {0x00,0,0,0,0,0,0},{0x44FF,0,0,0,0,0,0}},//and + {13,1, {0x00,0,0,0,0,0,0},{0x45FF,0,0,0,0,0,0}},//or + {14,1, {0x00,0,0,0,0,0,0},{0x46FF,0,0,0,0,0,0}},//xor + {15,1, {0x0F,0,0,0,0,0,0},{0x47FF,0,0,0,0,0,0}},//not + {16,1, {0xFF,0,0,0,0,0,0},{0x6000,0,0,0,0,0,0}},//rtb + {17,1, {0x00,0,0,0,0,0,0},{0x61FF,0,0,0,0,0,0}},//gth + {18,1, {0x00,0,0,0,0,0,0},{0x64FF,0,0,0,0,0,0}},//gts + {19,1, {0x00,0,0,0,0,0,0},{0x62FF,0,0,0,0,0,0}},//eql + {20,1, {0x0F,0,0,0,0,0,0},{0x63F0,0,0,0,0,0,0}},//stb + {21,2, {0x2F,0x4F,0,0,0,0,0},{0x32F0,0x30FF,0,0,0,0,0}},//br + {22,2, {0x2F,0x4F,0,0,0,0,0},{0x35F0,0x31FF,0,0,0,0,0}},//bt + {23,1, {0x2F,0,0,0,0,0,0},{0x33F0,0,0,0,0,0,0}},//bf + {24,1, {0x6F,0,0,0,0,0,0},{0x34F0,0,0,0,0,0,0}},//jmp + {25,1, {0x0F,0,0,0,0,0,0},{0x71F0,0,0,0,0,0,0}},//itp + {26,1, {0xFF,0,0,0,0,0,0},{0x7200,0,0,0,0,0,0}},//dsi + {27,1, {0xFF,0,0,0,0,0,0},{0x7300,0,0,0,0,0,0}},//eni + {28,1, {0x0F,0,0,0,0,0,0},{0x70F0,0,0,0,0,0,0}}//rgi +}; + +char *instr_tok_dict[INSTR_DICT_S] = { + "nop", + "mov", + "mmv", + "psh", + "pop", + "lds", + "sts", + "add", + "sad", + "sub", + "shl", + "shr", + "and", + "or", + "xor", + "not", + "rtb", + "gth", + "gts", + "eql", + "stb", + "br", + "bt", + "bf", + "jmp", + "itp", + "dsi", + "eni", + "rgi" +}; + +int find_token(char *token, int dicts, char *dict[]){ + int toklen = strlen(token); + + if(toklen < 2) return -1; + + for(int i=0; i < dicts; i++){ + if(token[1] == dict[i][1]){ + if(!strcmp(token, dict[i])){ + return i; + } + } + } + + return -1; +} + +int uint8_t_cmpfunc(const void *a, const void *b){ + return *(uint8_t*)a - *(uint8_t*)b; +} + +int find_corres_def(uint8_t argtyps, InstrDef *indef){ + uint8_t *match = bsearch(&argtyps, &indef->argtyps, 7, 1, &uint8_t_cmpfunc); + + if(!match) return -1; + + return (int64_t)match - (int64_t)&indef->argtyps; +} + +int32_t pars_line(char *line){ + char *tok; + + tok = strtok(line, " "); + + int tokid = find_token(tok, INSTR_DICT_S, instr_tok_dict); + + if(tokid < 0) return -1; + + InstrDef *indef = &instr_dict[tokid]; + + tok = strtok(NULL, " "); + char *ntok = strtok(NULL, " "); + + tok = strtok(tok, ","); + + int8_t argtyps = 0xFF; + int8_t argt[2] = {0xF,0xF}; + int8_t fargs[2]; + int8_t rn, imm; + + for(int i = 0; i < 2; i++){ + if(!strncmp(tok,"ac",2) + (!strncmp(tok,"pc",2))*2 && strlen(tok)>2){ + if((tok[2]-48) > -1 && (tok[2]-48) < 10){ + argt[i] = 0x7; + fargs[i] = !strncmp(tok,"ac",2) + (!strncmp(tok,"pc",2))*2 + tok[2]-48; + } + } + + if(!strncmp(tok,"*ac",2) + (!strncmp(tok,"*pc",2))*2){ + argt[i] = 0x6; + fargs[i] = !strncmp(tok,"*ac",2) + (!strncmp(tok,"*pc",2))*2; + } + + if(strlen(tok)>1 && !strncmp(tok,"r",1)){ + if(!sscanf(&tok[1], "%d", &rn)){ + return -2; + } + else if(rn > -1 && rn < 16){ + argt[i] = 0x0; + fargs[i] = rn; + } + else { + return -2; + } + } + + if(strlen(tok)>1 && !strncmp(tok,"*r",1)){ + if(!sscanf(&tok[2], "%d", &rn)){ + return -2; + } + if(rn > -1 && rn < 16){ + argt[i] = 0x2; + fargs[i] = rn; + } + else return -2; + } + + if(strlen(tok)>1 && !strncmp(tok, "#",1)){ + if(!sscanf(&tok[1], "%d", &imm)){ + return -2; + } + if(imm < -128 || imm > 127){ + return -3; + } + argt[i] = 0x3; + fargs[i] = imm; + } + + if(strlen(tok) > 1 && !strncmp(tok,"*#",2)){ + if(!sscanf(&tok[2], "%d", &imm)){ + return -2; + } + if(imm < -128 || imm > 127){ + return -3; + } + argt[i] = 0x4; + fargs[i] = imm; + } + + tok = ntok; + + argtyps = (argtyps & (0xF0F>>(i*4))); + argtyps += (argt[i] << (4-i*4)); + } + + int instt = find_corres_def(argtyps, indef); + + if(instt < 0) return -4; + + uint16_t op = indef->opcodes[instt]; + + uint8_t *opb = &op; + + if((argtyps & 0xF0) < 5 && (argtyps & 0xF0) > 2){ + opb[1] = (opb[1] & 0x0F) + fargs[1]; + opb[0] = fargs[0]; + return op; + } + if((argtyps & 0x0F) < 5 && (argtyps & 0x0F) > 2){ + opb[1] = (opb[1] & 0xF0) + fargs[0]; + opb[0] = fargs[1]; + return op; + } + if((argtyps & 0xF0) < 3 || (argtyps & 0xF0 > 4 && argtyps & 0xF0 < 8)){ + opb[1] = opb[1] & 0x0F + fargs[0]; + } + if(argtyps & 0x0F < 3 || (argtyps & 0x0F > 4 && argtyps & 0x0F < 8)){ + opb[1] = opb[1] & 0xF0 + fargs[1]; + } + + return op; +} + +int main(int argc, int *argv[]){ + + if(argc < 2) return -1; + + char *line_ = argv[1]; + + char *line = malloc(strlen(line_)); + + memcpy(line, line_, 11); + + printf("%x\n", pars_line(line)); + + return 0; +} diff --git a/interpr/Makefile b/interpr/Makefile new file mode 100644 index 0000000..3f82c30 --- /dev/null +++ b/interpr/Makefile @@ -0,0 +1,5 @@ +CFLAGS = -O2 -lm +CC = gcc + +[all]: + ${CC} src/main.c ${CFLAGS} diff --git a/interpr/a.out b/interpr/a.out new file mode 100755 index 0000000000000000000000000000000000000000..fb0e5df22c661149fbd6ba2bd0d407bf56e550ac GIT binary patch literal 16336 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 literal 0 HcmV?d00001 diff --git a/interpr/src/main.c b/interpr/src/main.c new file mode 100644 index 0000000..161e81c --- /dev/null +++ b/interpr/src/main.c @@ -0,0 +1,421 @@ +#include +#include +#include +#include + +#define MEM_ALLOC 0xFFFF //64KiB + +#define TOTAL_ALLOC (MEM_ALLOC) + +#define BOOTCODE_S 18 + +uint8_t bootcode[] = { + 0x00,0xFF, + 0xFF,0x00, + 0x00,0x06, + 0x72,0x00, + 0xB6,0xE0, + 0xE0,0x0E, + 0xB6,0xE0, + 0xE0,0x1E, + 0x34,0x00 +}; + +typedef struct{ + + uint8_t *mem; + + uint8_t greg[16]; + + uint16_t sreg[2]; + + uint8_t interr[16]; + uint8_t intern; + + uint8_t interen; + + uint8_t tbit; + + int32_t cycles; + +} ProcDat; + +int init_proc(ProcDat *procdat){ + procdat->mem = malloc(MEM_ALLOC); + + if(!procdat->mem){ + return 1; + } + + for(int i=0; imem[i] = bootcode[i-1]; + } + for(int i=BOOTCODE_S; imem[i] = 1; + } + + procdat->sreg[1] = procdat->mem[0]<<8 + procdat->mem[1]; + printf("%x\n", procdat->mem[1]); + procdat->interen = 1; + procdat->interr[0] = 0b01; + procdat->intern = 1; + procdat->cycles = 0; + + return 0; +} + +void free_proc(ProcDat *procdat){ + free(procdat->mem); +} + +void itp(uint8_t interrupt, uint8_t call_type, ProcDat *procdat){ + if(!procdat->interen)return; + if(!(procdat->interr[interrupt] & 0x2) && call_type) return; + + printf("Interrupt %x, PC : %x\n", interrupt, procdat->sreg[1]); + + uint16_t st = procdat->mem[0x2]<<8 + procdat->mem[0x3]; + + procdat->mem[st+procdat->greg[12]] = procdat->sreg[1] >> 8; + procdat->greg[12]++; + procdat->mem[st+procdat->greg[12]] = procdat->sreg[1] & 0xFF; + procdat->greg[12]++; + + procdat->sreg[1] = procdat->mem[3]<<8 + procdat->mem[4]; +} + +int exec_instr(uint16_t instr, ProcDat *procdat){ + int8_t in0 = instr & 0xFF; + uint8_t in1 = instr & 0xF; + uint8_t in2 = (instr>>4) & 0xF; + uint8_t in3 = (instr>>8) & 0xF; + uint8_t in4 = instr>>12; + + uint8_t *greg = &procdat->greg; + uint16_t *sreg = &procdat->sreg; + uint8_t *mem = procdat->mem; + uint16_t st = mem[0x2]<<8 + mem[0x3]; + int32_t cycles = 0; + + switch(in4){ + case 0x2 : { + greg[in2] = greg[in1]; + cycles++; + break; + } + case 0x3 : { + switch(in3){ + case 0x0 : { + sreg[1] += in0*2; + cycles++; + break; + } + case 0x1 : { + if(procdat->tbit){ + sreg[1] += in0*2; + } + cycles++; + break; + } + case 0x2 : { + sreg[1] += ((int8_t)in2)*2; + cycles++; + break; + } + case 0x3 : { + if(!procdat->tbit){ + sreg[1] += ((int8_t)in2)*2; + } + cycles++; + break; + } + case 0x4 : { + sreg[1] = sreg[0]; + cycles+=2; + break; + } + case 0x5 : { + if(procdat->tbit){ + sreg[1] += ((int8_t)in2)*2; + } + cycles++; + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + } + case 0x4 : { + switch(in3){ + case 0x0 : { + greg[in2] += greg[in1]; + cycles++; + break; + } + case 0x1 : { + greg[in2] -= greg[in1]; + cycles++; + break; + } + case 0x2 : { + greg[in2] <<= 1; + cycles++; + break; + } + case 0x3 : { + greg[in2] >>= 2; + cycles++; + break; + } + case 0x4 : { + greg[in2] &= greg[in1]; + cycles++; + break; + } + case 0x5 : { + greg[in2] |= greg[in1]; + cycles++; + break; + } + case 0x6 : { + greg[in2] ^= greg[in1]; + cycles++; + break; + } + case 0x7 : { + greg[in2] = ~greg[in2]; + cycles++; + break; + } + case 0x8 : { + greg[0] += in0; + cycles++; + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + break; + } + case 0x6 : { + switch(in3){ + case 0x0 : { + procdat->tbit = 0; + cycles++; + break; + } + case 0x1 : { + procdat->tbit = greg[in2] > greg[in1]; + cycles++; + break; + } + case 0x2 : { + procdat->tbit = greg[in2] == greg[in1]; + cycles++; + break; + } + case 0x3 : { + greg[in2] = procdat->tbit; + cycles++; + break; + } + case 0x4 : { + procdat->tbit = (int8_t)greg[in2] > (int8_t)greg[in1]; + cycles++; + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + break; + } + case 0x7 : { + switch(in3){ + case 0x0 : { + if(procdat->intern > 15){ + greg[in2] = 0xFF; + break; + } + procdat->interr[procdat->intern] = greg[in2]; + procdat->intern++; + cycles+=2; + break; + } + case 0x1 : { + itp(in2, 1, procdat); + cycles+=6; + break; + } + case 0x2 : { + procdat->interen = 0; + printf("PC : %x - disabled interrupts\n", sreg[1]); + cycles++; + break; + } + case 0x3 : { + procdat->interen = 1; + printf("PC : %x - enabled interrupts\n", sreg[1]); + cycles++; + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + } + case 0x8 : { + greg[in3] = in0; + cycles++; + break; + } + case 0x9 : { + greg[in3] = mem[(sreg[1]+in0)&0xFFFF]; + cycles++; + break; + } + case 0xA : { + mem[(sreg[1]+in0)&0xFFFF] = greg[in3]; + cycles++; + break; + } + case 0xB : { + switch(in3){ + case 0x0 : { + greg[in2] = mem[(sreg[1]+(int8_t)greg[in1])&0xFFFF]; + cycles++; + break; + } + case 0x1 : { + mem[(sreg[1]+(int8_t)greg[in2])&0xFFFF] = greg[in1]; + cycles++; + break; + } + case 0x2 : { + mem[(sreg[1]+(int8_t)greg[in2])&0xFFFF] = mem[(sreg[1]+(int8_t)greg[in1])&0xFFFF]; + cycles++; + break; + } + case 0x3 : { + greg[in2] = mem[sreg[0]]; + cycles++; + break; + } + case 0x4 : { + mem[sreg[0]] = greg[in1]; + cycles++; + break; + } + case 0x5 : { + mem[st+greg[12]] = greg[in2]; + greg[12]++; + cycles+=2; + break; + } + case 0x6 : { + greg[12]--; + greg[in2] = mem[st+greg[12]]; + cycles+=2; + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + break; + } + case 0xE : { + switch(in3){ + case 0x0 : { + if(in2 < 2){ + sreg[1] = (sreg[1] & (0x00FF00>>(8*in2))) + greg[in1]<<(8*in2); + } + cycles++; + break; + } + case 0x1 : { + greg[in2] = sreg[in1/2] >> (in1%2 ? 8:0); + cycles++; + break; + } + case 0x2 : { + sreg[in2] += greg[in1]; + cycles++; + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + break; + } + default : { + itp(0, 0, procdat); + break; + } + } + sreg[1]+=2; + procdat->cycles += cycles; + if(mem[sreg[1]] == 1){ + return 0; + } + if(mem[sreg[1]]) + return 1; +} + +int main(){ + + ProcDat procdat; + + if(init_proc(&procdat)){ + printf("Error during initialization !\n(Likely couldn't allocate %d KiB)\n", TOTAL_ALLOC/1024); + free_proc(&procdat); + return 1; + } + + char *buf = malloc(100); + + while(1){ + int inp = 0; + int i; + + scanf("%X", &inp); + if(inp == 0x1){ + scanf("%99s", buf); + if(!memcmp(buf, "-d", 2)){ + printf("PC : %x AC : %x\n", procdat.sreg[1], procdat.sreg[0]); + for(i=0; i<16; i++){ + printf("r%d : %x\n", i, procdat.greg[i]); + } + for(i=0; i>1 + pure shift, no keep sign + 1 clock + and rm,rn: + 0b01000100mmmmnnnn + 0x44mn + binary AND : + rm <- rm&rn + 1 clock + or rm,rn: + 0b01000101mmmmnnnn + 0x45mn + binary OR : + rm <- rm|rn + 1 clock + xor rm,rn: + 0b01000110mmmmnnnn + 0x46mn + binary eXclusive OR: + rm <- rm^rn + 1 clock + not rm: + 0b01000111mmmmnnnn + 0x47mn + binary NOT : + rm <- !rm + binary not + 1 clock + rtb : + 0b0110000000000000 + 0x6000 + Reset T Bit : + t <- 0 + 1 clock + gth rm,rn: + 0b01100001mmmmnnnn + 0x61mn + Greater THan : + t <- rm > rn ? 1:0 + 1 clock + gts rm,rn: + 0b01100100mmmmnnn + 0x64mn + Greater Than (Signed): + t <- rm > rn ? 1:0 + (signed) (signed) + 1 clock + eql rm,rn: + 0b01100010mmmmnnnn + 0x62mn + EQuaL : + t <- rm == rn ? 1:0 + 1 clock + stb rm: + 0b01100011mmmm0000 + 0x63m0 + Store T Bit: + rm <- t + 1 clock + br *rm: + 0b10110010mmmm0000 + 0x32m0 + BRanch : + pc <- pc + rm *2 + (signed) + 1 clock + br *#imm: + 0b10110000mmmmmmmm + 0x30mm + pc <- pc + #imm*2 + 1 clock + bt *rm: + 0b10110101mmmm0000 + 0x35m0 + Branch if True: + If t == 1, + pc <- pc + rm *2 + (signed) + else is nop + 1 clock + bt *#imm: + 0b10110001mmmmmmmm + 0x31mm + If t == 1, + pc <- pc + #imm*2 + else is nop + 1 clock + bf *rm: + 0b10110011mmmm0000 + 0x33m0 + Branch if False: + If t == 0, + pc <- pc + rm *2 + (signed) + else is nop + 1 clock + jmp *sr: + 0b10110100ssss0000 + 0x34s0 + JuMP : + pc <- sr + nop on pc + 2 clocks + itp rm: + 0b01110001mmmm0000 + 0x71m0 + InTerruPt : + Raises interrupt of id + rm + 6 clocks + dsi : + 0b0111001000000000 + 0x7200 + DiSable Interrupts: + Disables interrupts + 1 clock + eni : + 0b0111001100000000 + 0x7300 + ENable Interrupts: + Enables interrupts + 1 clock + rgi rm: + 0b01110000mmmm0000 + 0x70m0 + ReGister Interrupt : + rm should be as follows: + bit 0 : raisable by itp + bit 1 : raisable by bus + Sets rm to id on succes, + and 0xFF on failure + 2 clocks