summaryrefslogblamecommitdiffstats
path: root/src/emu/risci.c
blob: 704ece8350f8888ca0bc31873074c2de4b995a52 (plain) (tree)
1
2
3
4
5
6
7
8


                   
                     


                    
                   






                              
                


                      

                                   








                                                           
                         
 


                                                                   








                                            

                                                                         




                                                  



                                             
 








                                                                 




                               
                     
                                  






                                
                                                        





                                            

                                                    









                                            

                                             
 



                                    

                                                        
               


                                    
                                   
                                            



                                                                             
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <signal.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <readline/readline.h>

#include "asm.h"
#include "cpu.h"
#include "log.h"
#include "mem.h"
#include "opc.h"

bool is_debug = false;
size_t mem_size = 64 * 1024 * 1024;
size_t reg_size = 0;

static
void usage(int rc)
{
	fprintf(stderr, "Usage: risci [-dhi] <program>\n");
	exit(rc);
}

static
void dump_registers(void)
{
	fprintf(stderr, "REGISTER DUMP:\n");
	for (size_t i = 0; i < reg_size; i++)
		fprintf(stderr, "\tr%zu = %"PRIu32"\n", i, GPR[i]);
}

static
void read_program(const char *program)
{
	struct stat sb;
	if (lstat(program, &sb) == -1)
		pdie("cannot stat program");

	if (sb.st_size % 4)
		die("program does not align to op-code size of 4 bytes");

	int pfd;
	if ((pfd = open(program, O_RDONLY)) == -1)
		pdie("could not open program");

	/* initialize register file */
	assert(read(pfd, &reg_size, 4) == 4);
	reg_size += 4;
	GPR = calloc(reg_size, 4);

	/* initialize pseudo registers */
	BP = reg_size - 3;
	SP = reg_size - 2;
	RV = reg_size - 1;
	GPR[BP] = GPR[SP] = mem_size;
	GPR[RV] = 0;

	assert(read(pfd, MEM, sb.st_size - 4) == sb.st_size - 4);
	memset(MEM + sb.st_size + 4, 0xFF, 4);
}

static
uint32_t next_instruction(void)
{
	uint32_t tmp;
	memcpy(&tmp, &MEM[IP], 4);
	return tmp;
}

int main(int argc, char *argv[])
{
	int ch;

	while ((ch = getopt(argc, argv, "dhm")) != -1) {
		switch (ch) {
		case 'd':
			is_debug = true;
			break;
		case 'h':
			usage(EXIT_SUCCESS);
		case 'm':
			mem_size = atoi(optarg) * 4;
			break;
		case '?':
		default:
			usage(EXIT_FAILURE);
		}
	}

	argc -= optind;
	argv += optind;

	/* reserve memory */
	MEM = calloc(mem_size, sizeof(char));

	/* load program from file */
	if (argc < 1)
		usage(EXIT_FAILURE);
	read_program(argv[0]);

	/* reset program counter to first instruction */
	IP = 0;

	/* start instruction loop */
	while (1) {
		//dump_registers();
		execute(next_instruction());
	}

	/* not reached, program is terminated by signal traps from the cpu */
}