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 <stdint.h>
#include <string.h>
#include <stdbool.h>
#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];
union {
uint16_t sreg[2];
uint8_t sreg_b[4];
};
uint8_t interr[16];
uint8_t intern;
uint8_t interen;
bool interen;
uint8_t tbit;
@ -47,16 +37,9 @@ int init_proc(ProcDat *procdat){
return 1;
}
for(int i=0; i<BOOTCODE_S; i++){
procdat->mem[i] = bootcode[i-1];
}
for(int i=BOOTCODE_S; i<MEM_ALLOC; i++){
procdat->mem[i] = 1;
}
memset(procdat->mem, 0x1, MEM_ALLOC);
procdat->sreg[1] = procdat->mem[0]<<8 + procdat->mem[1];
printf("%x\n", procdat->mem[1]);
procdat->interen = 1;
procdat->interen = true;
procdat->interr[0] = 0b01;
procdat->intern = 1;
procdat->cycles = 0;
@ -68,36 +51,62 @@ void free_proc(ProcDat *procdat){
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){
if(!procdat->interen)return;
if(!(procdat->interr[interrupt] & 0x2) && call_type) return;
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];
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];
procdat->sreg[1] = (procdat->mem[3]<<8) + procdat->mem[4];
}
int exec_instr(uint16_t instr, ProcDat *procdat){
int8_t in0 = instr & 0xFF;
int exec_instr(ProcDat *procdat){
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 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 *greg = procdat->greg;
uint16_t *sreg = procdat->sreg;
uint8_t *sreg_b = procdat->sreg_b;
uint8_t *mem = procdat->mem;
uint16_t st = mem[0x2]<<8 + mem[0x3];
int32_t cycles = 0;
printf("Executing %x : %x \n", sreg[1], instr);
switch(in4){
case 0x0 : {
cycles++;
break;
}
case 0x2 : {
greg[in2] = greg[in1];
cycles++;
@ -106,6 +115,7 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
case 0x3 : {
switch(in3){
case 0x0 : {
printf("br to : %x\n", sreg[1]+in0*2);
sreg[1] += in0*2;
cycles++;
break;
@ -130,6 +140,7 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
break;
}
case 0x4 : {
printf("jmp to : %x\n", sreg[0]);
sreg[1] = sreg[0];
cycles+=2;
break;
@ -335,7 +346,7 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
switch(in3){
case 0x0 : {
if(in2 < 2){
sreg[1] = (sreg[1] & (0x00FF00>>(8*in2))) + greg[in1]<<(8*in2);
sreg_b[in2] = greg[in1];
}
cycles++;
break;
@ -367,11 +378,10 @@ int exec_instr(uint16_t instr, ProcDat *procdat){
if(mem[sreg[1]] == 1){
return 0;
}
if(mem[sreg[1]])
return 1;
}
int main(){
int main(int argc, char *argv[]){
ProcDat procdat;
@ -381,40 +391,13 @@ int main(){
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<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)){}
}
}
if(argc < 2 || load_bin(&procdat, argv[1])){
printf("No file provided or failed to load file !\n");
return 1;
}
exit:
while(exec_instr(&procdat)){}
free_proc(&procdat);
return 0;

BIN
interpr/test.bin Normal file

Binary file not shown.

View file

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