This commit is contained in:
attilavs2 2025-01-26 12:08:44 +01:00
parent db7d68b317
commit 3c16d5d7bd
5 changed files with 68 additions and 76 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.out

Binary file not shown.

View file

@ -2,37 +2,27 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define MEM_ALLOC 0xFFFF //64KiB #define MEM_ALLOC 0xFFFF //64KiB
#define TOTAL_ALLOC (MEM_ALLOC) #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{ typedef struct{
uint8_t *mem; uint8_t *mem;
uint8_t greg[16]; uint8_t greg[16];
union {
uint16_t sreg[2]; uint16_t sreg[2];
uint8_t sreg_b[4];
};
uint8_t interr[16]; uint8_t interr[16];
uint8_t intern; uint8_t intern;
uint8_t interen; bool interen;
uint8_t tbit; uint8_t tbit;
@ -47,16 +37,9 @@ int init_proc(ProcDat *procdat){
return 1; return 1;
} }
for(int i=0; i<BOOTCODE_S; i++){ memset(procdat->mem, 0x1, MEM_ALLOC);
procdat->mem[i] = bootcode[i-1];
}
for(int i=BOOTCODE_S; i<MEM_ALLOC; i++){
procdat->mem[i] = 1;
}
procdat->sreg[1] = procdat->mem[0]<<8 + procdat->mem[1]; procdat->interen = true;
printf("%x\n", procdat->mem[1]);
procdat->interen = 1;
procdat->interr[0] = 0b01; procdat->interr[0] = 0b01;
procdat->intern = 1; procdat->intern = 1;
procdat->cycles = 0; procdat->cycles = 0;
@ -68,36 +51,62 @@ void free_proc(ProcDat *procdat){
free(procdat->mem); free(procdat->mem);
} }
int load_bin(ProcDat *procdat, char *filename){
FILE *file = fopen(filename, "r");
if(!fgets(procdat->mem, MEM_ALLOC, file)){
fclose(file);
return 1;
}
procdat->sreg[1] = 0x28;
fclose(file);
return 0;
}
void itp(uint8_t interrupt, uint8_t call_type, ProcDat *procdat){ void itp(uint8_t interrupt, uint8_t call_type, ProcDat *procdat){
if(!procdat->interen)return; if(!procdat->interen)
if(!(procdat->interr[interrupt] & 0x2) && call_type) return; return;
if(!(procdat->interr[interrupt] & 0x2) && call_type)
return;
printf("Interrupt %x, PC : %x\n", interrupt, procdat->sreg[1]); printf("Interrupt %x, PC : %x\n", interrupt, procdat->sreg[1]);
uint16_t st = procdat->mem[0x2]<<8 + procdat->mem[0x3]; uint16_t st = (procdat->mem[0x2]<<8) + procdat->mem[0x3];
procdat->mem[st+procdat->greg[12]] = procdat->sreg[1] >> 8; procdat->mem[st+procdat->greg[12]] = procdat->sreg[1] >> 8;
procdat->greg[12]++; procdat->greg[12]++;
procdat->mem[st+procdat->greg[12]] = procdat->sreg[1] & 0xFF; procdat->mem[st+procdat->greg[12]] = procdat->sreg[1] & 0xFF;
procdat->greg[12]++; procdat->greg[12]++;
procdat->sreg[1] = procdat->mem[3]<<8 + procdat->mem[4]; procdat->sreg[1] = (procdat->mem[3]<<8) + procdat->mem[4];
} }
int exec_instr(uint16_t instr, ProcDat *procdat){ int exec_instr(ProcDat *procdat){
int8_t in0 = instr & 0xFF; uint16_t addr = procdat->sreg[1];
uint16_t instr = procdat->mem[addr]<<8 | procdat->mem[addr+1];
int16_t in0 = (int8_t)(instr & 0xFF);
uint8_t in1 = instr & 0xF; uint8_t in1 = instr & 0xF;
uint8_t in2 = (instr>>4) & 0xF; uint8_t in2 = (instr>>4) & 0xF;
uint8_t in3 = (instr>>8) & 0xF; uint8_t in3 = (instr>>8) & 0xF;
uint8_t in4 = instr>>12; uint8_t in4 = instr>>12;
uint8_t *greg = &procdat->greg; uint8_t *greg = procdat->greg;
uint16_t *sreg = &procdat->sreg; uint16_t *sreg = procdat->sreg;
uint8_t *sreg_b = procdat->sreg_b;
uint8_t *mem = procdat->mem; uint8_t *mem = procdat->mem;
uint16_t st = mem[0x2]<<8 + mem[0x3]; uint16_t st = mem[0x2]<<8 + mem[0x3];
int32_t cycles = 0; int32_t cycles = 0;
printf("Executing %x : %x \n", sreg[1], instr);
switch(in4){ switch(in4){
case 0x0 : {
cycles++;
break;
}
case 0x2 : { case 0x2 : {
greg[in2] = greg[in1]; greg[in2] = greg[in1];
cycles++; cycles++;
@ -106,6 +115,7 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
case 0x3 : { case 0x3 : {
switch(in3){ switch(in3){
case 0x0 : { case 0x0 : {
printf("br to : %x\n", sreg[1]+in0*2);
sreg[1] += in0*2; sreg[1] += in0*2;
cycles++; cycles++;
break; break;
@ -130,6 +140,7 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
break; break;
} }
case 0x4 : { case 0x4 : {
printf("jmp to : %x\n", sreg[0]);
sreg[1] = sreg[0]; sreg[1] = sreg[0];
cycles+=2; cycles+=2;
break; break;
@ -335,7 +346,7 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
switch(in3){ switch(in3){
case 0x0 : { case 0x0 : {
if(in2 < 2){ if(in2 < 2){
sreg[1] = (sreg[1] & (0x00FF00>>(8*in2))) + greg[in1]<<(8*in2); sreg_b[in2] = greg[in1];
} }
cycles++; cycles++;
break; break;
@ -367,11 +378,10 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
if(mem[sreg[1]] == 1){ if(mem[sreg[1]] == 1){
return 0; return 0;
} }
if(mem[sreg[1]])
return 1; return 1;
} }
int main(){ int main(int argc, char *argv[]){
ProcDat procdat; ProcDat procdat;
@ -381,39 +391,12 @@ int main(){
return 1; return 1;
} }
char *buf = malloc(100); if(argc < 2 || load_bin(&procdat, argv[1])){
printf("No file provided or failed to load file !\n");
return 1;
}
while(1){ while(exec_instr(&procdat)){}
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<MEM_ALLOC;){
printf("%x : ", i);
i++;
printf("%x ",procdat.mem[i]);
i++;
printf("%x\n",procdat.mem[i]);
}
}
if(!memcmp(buf, "-q", 2)){
break;
}
}
else{
if(exec_instr(inp & 0xFFFF, &procdat)){
while(exec_instr(procdat.mem[procdat.sreg[1]], &procdat)){}
}
}
}
exit:
free_proc(&procdat); free_proc(&procdat);

BIN
interpr/test.bin Normal file

Binary file not shown.

View file

@ -24,7 +24,7 @@ registers:
interrupt register, interrupt register,
contains the type of contains the type of
interrupt interrupt
4bits - bits 0-3 will always be 0 3bits - bits 0-4 will always be 0
t bit: t bit:
is set by comp ops is set by comp ops
1bit 1bit
@ -39,10 +39,13 @@ calling conventions:
Interrupts: Interrupts:
Hardware interrupts: Hardware interrupts:
0x0 : Invalid instruction 0x0 : Invalid instruction
The 15 other interrupts are free to The 7 other interrupts are free to
define by the user define by the user
On interrupt (either called through On interrupt, the CPU will jump to the
the bus or itp) handler base + interrupt number * 256
When an interrupt is raised, the cpu will push the resume adress to stack (in
order pc0 then pc1)
startup: startup:
the cpu will look the cpu will look
at adress 0x0,and at adress 0x0,and
@ -62,9 +65,14 @@ startup:
adress will be adress will be
read here read here
everytime everytime
When an interrupt is raised, the cpu will allow acces
to r12-15 and push the resume adress to stack (in soc :
order pc0 then pc1) The emulator implements a couple of features to be interseting.
- Keyboard handler
- "Serial" (stdout) output
keyboard:
instructions : instructions :
format: format: