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 <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
BIN
interpr/test.bin
Normal file
Binary file not shown.
24
spec.txt
24
spec.txt
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue