move includes to sourcefiles
- fix initialise_ram() function - add function-doc comments
This commit is contained in:
parent
669072be49
commit
b6a88963e5
4
makefile
4
makefile
@ -7,7 +7,7 @@ DEBUG = -DNDEBUG
|
|||||||
|
|
||||||
VPATH = src src/debug
|
VPATH = src src/debug
|
||||||
#--------------Linker-Part-----------------
|
#--------------Linker-Part-----------------
|
||||||
toy_cpu : main.o toy.o debug.o
|
toy_cpu : main.o toy.o helper.o
|
||||||
echo $@ is now linked
|
echo $@ is now linked
|
||||||
$(CC) $(LDFLAGS) -o $@ $^
|
$(CC) $(LDFLAGS) -o $@ $^
|
||||||
#--------------Compiler-Part---------------
|
#--------------Compiler-Part---------------
|
||||||
@ -17,7 +17,7 @@ main.o : main.c
|
|||||||
toy.o : toy.c toy.h
|
toy.o : toy.c toy.h
|
||||||
$(CC) $(DEBUG) $(CFLAGS) -o $@ -c $<
|
$(CC) $(DEBUG) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
debug.o : debug.c debug.h
|
helper.o : helper.c helper.h
|
||||||
$(CC) $(DEBUG) $(CFLAGS) -o $@ -c $<
|
$(CC) $(DEBUG) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "debug.h"
|
#include <stdio.h>
|
||||||
#include "../toy.h"
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "toy.h"
|
||||||
|
|
||||||
//assumes little endian
|
//assumes little endian
|
||||||
//stackoverflow.com/questions/111928
|
//stackoverflow.com/questions/111928
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef DEBUG_H
|
#ifndef DEBUG_H
|
||||||
#define DEBUG_H
|
#define DEBUG_H
|
||||||
|
|
||||||
#include "../toy.h"
|
|
||||||
|
|
||||||
void fprintBits(size_t const size, void const * const ptr, FILE *file_pointer);
|
void fprintBits(size_t const size, void const * const ptr, FILE *file_pointer);
|
||||||
void makeHexDump(bool base_2, uint16_t ram[]);
|
void makeHexDump(bool base_2, uint16_t ram[]);
|
||||||
|
|
33
src/main.c
33
src/main.c
@ -1,5 +1,8 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "toy.h"
|
#include "toy.h"
|
||||||
#include "./debug/debug.h"
|
#include "helper.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@ -28,9 +31,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
while(run)
|
while(run)
|
||||||
{
|
{
|
||||||
ir = ram[pc]; //get instruction from RAM
|
ir = ram[pc]; //get instruction from RAM
|
||||||
op_code = get_opcode(ir); //determine the instruction form
|
op_code = get_opcode(ir); //determine the instruction form
|
||||||
data_addr=find_data(ir); //locate the 2nd operand (ignord from OP_Code 8 to 15)
|
data_addr=get_data(ir); //locate the 2nd operand (ignord from OP_Code 8 to 15)
|
||||||
|
|
||||||
//Handele user output
|
//Handele user output
|
||||||
printf("\ninstruction: ");
|
printf("\ninstruction: ");
|
||||||
@ -41,26 +44,24 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
//CPU control flow
|
//CPU control flow
|
||||||
if(execute(op_code,data_addr,ram)) //EXECUTE instruction, jump if ALU says
|
if(execute(op_code,data_addr,ram)) //EXECUTE instruction, jump if ALU says
|
||||||
pc=find_data(ir);
|
pc=get_data(ir);
|
||||||
else pc++;
|
else pc++;
|
||||||
|
|
||||||
if(pc>=RAM_SIZE) pc %= RAM_SIZE; //TOY_CPU can only address 12 Bit
|
if(pc>=RAM_SIZE) pc %= RAM_SIZE; //TOY_CPU can only address 12 Bit
|
||||||
|
|
||||||
//Handele user output
|
//Handele user output
|
||||||
printf("PROGRAM COUNTER: %" PRIu16 "\n",pc);
|
printf("PROGRAM COUNTER: %" PRIu16 "\n",pc);
|
||||||
printf("\x1b[32m \n(n)ext step or (q)uit or (c)oredump ?\n \x1b[0m");
|
printf("\x1b[32m \n(n)ext step or (q)uit or (c)oredump ?\n \x1b[0m");
|
||||||
|
|
||||||
//handel program flow
|
//handle program flow
|
||||||
while((quit = getchar()) != '\n' && quit != EOF)
|
while((quit = getchar()) != '\n')
|
||||||
{
|
{
|
||||||
if(quit == 'c') makeHexDump(true,ram);
|
switch(quit)
|
||||||
|
{
|
||||||
else if(quit == 'q')
|
case EOF: break;
|
||||||
{
|
case 'c': makeHexDump(true,ram); break;
|
||||||
run = false;
|
case 'q': run = false;
|
||||||
printf("\nThis is an interpreter for the "CPU_TYPE" by\n"
|
}
|
||||||
"\tmichael.krause@uni-leipzig.de\n\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
66
src/toy.c
66
src/toy.c
@ -1,3 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "toy.h"
|
#include "toy.h"
|
||||||
|
|
||||||
void print_instructionSet(void)
|
void print_instructionSet(void)
|
||||||
@ -35,16 +41,15 @@ void print_instructionSet(void)
|
|||||||
"\tmichael.krause@uni-leipzig.de\n");
|
"\tmichael.krause@uni-leipzig.de\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//gibt Anzahl der erfolgreich gelesenen Maschinenworte zurück(-1 im Fehlerfall).
|
|
||||||
int initialise_ram(uint16_t *ram, int argc, char **argv )
|
int initialise_ram(uint16_t *ram, int argc, char **argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
//open Input Stream
|
//open and check the input stream
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int j=0;
|
int j=0,int_cache=0;
|
||||||
char tempS[CPU_WORD_SIZE+1]; //+1 for "\0"
|
char tempS[CPU_WORD_SIZE+1]; //+1 for "\0"
|
||||||
|
|
||||||
for(int i=0;i<RAM_SIZE;i++) ram[i]=0;
|
for(int i=0;i<RAM_SIZE;i++) ram[i]=0; //initialize the toy-RAM with NULL
|
||||||
|
|
||||||
if(argc<2)
|
if(argc<2)
|
||||||
{
|
{
|
||||||
@ -70,28 +75,37 @@ int initialise_ram(uint16_t *ram, int argc, char **argv )
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialise Toy-RAM
|
// Fill the toy-RAM with data and break in case of error
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
for(int i = 0;i <= CPU_WORD_SIZE;i++)
|
||||||
|
{
|
||||||
|
int_cache = fgetc(fp);
|
||||||
|
|
||||||
do
|
if((int_cache =='\n' && i<CPU_WORD_SIZE) || (feof(fp) && i!=0))
|
||||||
{
|
{
|
||||||
for(int i=0;i<=CPU_WORD_SIZE;i++)
|
fprintf(stderr,"%s","input file has incorrect machine-word size !\n");
|
||||||
{
|
fclose(fp);
|
||||||
tempS[i]=fgetc(fp);
|
return -1;
|
||||||
if(tempS[0]==EOF) break;
|
}
|
||||||
if(tempS[i]!='1' && tempS[i]!='0' && i<CPU_WORD_SIZE)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s","input file corrupted\n");
|
|
||||||
fclose(fp);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempS[CPU_WORD_SIZE]='\0';
|
|
||||||
ram[j]=strtoul(tempS,NULL,2);
|
|
||||||
j++;
|
|
||||||
}while(tempS[0]!=EOF);
|
|
||||||
|
|
||||||
|
if(feof(fp)) break;
|
||||||
|
|
||||||
|
if((int_cache != '1' && int_cache != '0' && int_cache != '\n') || j >= RAM_SIZE )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"%s","input file corrupted\n");
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tempS[i] = int_cache;
|
||||||
|
}
|
||||||
|
if(feof(fp)) break;
|
||||||
|
tempS[CPU_WORD_SIZE] = '\0'; //replace \n by \0
|
||||||
|
ram[j] = strtoul(tempS,NULL,2);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return j-1;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t get_opcode(uint16_t instruction)
|
uint8_t get_opcode(uint16_t instruction)
|
||||||
@ -101,7 +115,7 @@ uint8_t get_opcode(uint16_t instruction)
|
|||||||
return opcode;
|
return opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t find_data(uint16_t instruction)
|
uint16_t get_data(uint16_t instruction)
|
||||||
{
|
{
|
||||||
uint16_t operand;
|
uint16_t operand;
|
||||||
operand = instruction & 4095;
|
operand = instruction & 4095;
|
||||||
@ -110,7 +124,7 @@ uint16_t find_data(uint16_t instruction)
|
|||||||
|
|
||||||
int get2compl(uint16_t value)
|
int get2compl(uint16_t value)
|
||||||
{
|
{
|
||||||
int sign_value = value;
|
int32_t sign_value = value;
|
||||||
if(value>32767)
|
if(value>32767)
|
||||||
{
|
{
|
||||||
value=(~value)+1;
|
value=(~value)+1;
|
||||||
@ -129,7 +143,7 @@ bool execute(uint8_t op_code, int data_addr, uint16_t *ram) // jump if true
|
|||||||
{
|
{
|
||||||
case 0: ram[data_addr] = accu; break; //STORE
|
case 0: ram[data_addr] = accu; break; //STORE
|
||||||
case 1: accu = ram[data_addr]; break; //LOAD
|
case 1: accu = ram[data_addr]; break; //LOAD
|
||||||
case 2: jump = ((accu==0) ? true : false); break; //JMPZ
|
case 2: jump = (accu == 0); break; //JMP
|
||||||
case 3: accu = accu + ram[data_addr]; break; //ADD
|
case 3: accu = accu + ram[data_addr]; break; //ADD
|
||||||
case 4: accu = accu - ram[data_addr]; break; //SUB
|
case 4: accu = accu - ram[data_addr]; break; //SUB
|
||||||
case 5: accu = accu | ram[data_addr]; break; //OR
|
case 5: accu = accu | ram[data_addr]; break; //OR
|
||||||
|
49
src/toy.h
49
src/toy.h
@ -1,22 +1,57 @@
|
|||||||
#ifndef TOY_H
|
#ifndef TOY_H
|
||||||
#define TOY_H
|
#define TOY_H
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define CPU_TYPE "Koopman_TOY_CPU"
|
#define CPU_TYPE "Koopman_TOY_CPU"
|
||||||
#define RAM_SIZE 4096
|
#define RAM_SIZE 4096
|
||||||
#define CPU_WORD_SIZE 16
|
#define CPU_WORD_SIZE 16
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print_instructionSet(): print the cpu instruction set
|
||||||
|
* This is a user help function, can be activated via
|
||||||
|
* the -h paramter.
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
|
||||||
void print_instructionSet(void);
|
void print_instructionSet(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialise_ram(): read inputstream into the toy-ram
|
||||||
|
* Return:
|
||||||
|
* the number of successfully read machine words,
|
||||||
|
* -1 in case of error
|
||||||
|
*/
|
||||||
|
|
||||||
int initialise_ram(uint16_t *ram, int argc, char **argv );
|
int initialise_ram(uint16_t *ram, int argc, char **argv );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_opcode(): segments the mashine code in the OP-Code
|
||||||
|
* Return: 4 bit OP-Code
|
||||||
|
*/
|
||||||
|
|
||||||
uint8_t get_opcode(uint16_t instruction);
|
uint8_t get_opcode(uint16_t instruction);
|
||||||
uint16_t find_data(uint16_t instruction);
|
|
||||||
|
/**
|
||||||
|
* get_data(): get the addressed data from the RAM
|
||||||
|
* Return: the 12 bit data address
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t get_data(uint16_t instruction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get2compl(): interpret the transfer value as tow's complement
|
||||||
|
* Return: tow's complement value between -255 and 254
|
||||||
|
*/
|
||||||
|
|
||||||
int get2compl(uint16_t value); //not good place for something!
|
int get2compl(uint16_t value); //not good place for something!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* execute(): execute the toy-CPU instruction
|
||||||
|
* This function implements the CPU instruction set,
|
||||||
|
* use print_instructionSet() for an overview.
|
||||||
|
* Return: true if there is a jump
|
||||||
|
*/
|
||||||
|
|
||||||
bool execute(uint8_t op_code, int data_addr,uint16_t *ram);
|
bool execute(uint8_t op_code, int data_addr,uint16_t *ram);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user