commit 5a5bed307d628ac02224ce67d39ee393d8dfbdce Author: attilavs2 Date: Sat Jul 27 21:49:56 2024 +0200 Initial commit 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 0000000..19ede81 Binary files /dev/null and b/assembl/a.out differ 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 0000000..fb0e5df Binary files /dev/null and b/interpr/a.out differ 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