move includes to sourcefiles

- fix initialise_ram() function
- add function-doc comments
This commit is contained in:
Michael 2017-09-20 15:59:31 +02:00 committed by lux
parent 669072be49
commit b6a88963e5
6 changed files with 106 additions and 56 deletions

View File

@ -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 :

View File

@ -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

View File

@ -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[]);

View File

@ -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>
@ -30,7 +33,7 @@ int main(int argc, char *argv[])
{ {
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,7 +44,7 @@ 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
@ -50,16 +53,14 @@ int main(int argc, char *argv[])
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')
{ {
run = false; case EOF: break;
printf("\nThis is an interpreter for the "CPU_TYPE" by\n" case 'c': makeHexDump(true,ram); break;
"\tmichael.krause@uni-leipzig.de\n\n"); case 'q': run = false;
} }
} }
} }

View File

@ -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)
if(feof(fp)) break;
if((int_cache != '1' && int_cache != '0' && int_cache != '\n') || j >= RAM_SIZE )
{ {
fprintf(stderr,"%s","input file corrupted\n"); fprintf(stderr,"%s","input file corrupted\n");
fclose(fp); fclose(fp);
return -1; return -1;
} }
tempS[i] = int_cache;
} }
tempS[CPU_WORD_SIZE]='\0'; if(feof(fp)) break;
ram[j]=strtoul(tempS,NULL,2); tempS[CPU_WORD_SIZE] = '\0'; //replace \n by \0
ram[j] = strtoul(tempS,NULL,2);
j++; j++;
}while(tempS[0]!=EOF); }
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

View File

@ -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