summaryrefslogblamecommitdiffstats
path: root/src/emu/risci.c
blob: adae285b6061cf75a78629471703a1d23f826aba (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;
uint64_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 % sizeof(inst_t))
		die("program does not align to instruction size of %zu bytes", sizeof(inst_t));

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

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

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

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

static
inst_t next_instruction(void)
{
	inst_t tmp;
	memcpy(&tmp, &MEM[IP], sizeof(inst_t));
	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) * sizeof(uint32_t);
			break;
		case '?':
		default:
			usage(EXIT_FAILURE);
		}
	}

	argc -= optind;
	argv += optind;

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

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

	/* push arguments onto stack */
	while (--argc) {
		//dump_registers();
		push(atoi(argv[argc]));
	}

	/* 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 */
}