Progrès
This commit is contained in:
parent
db7d68b317
commit
3c16d5d7bd
5 changed files with 68 additions and 76 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.out
|
BIN
interpr/a.out
BIN
interpr/a.out
Binary file not shown.
|
@ -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
BIN
interpr/test.bin
Normal file
Binary file not shown.
22
spec.txt
22
spec.txt
|
@ -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:
|
||||||
|
|
Loading…
Add table
Reference in a new issue