98 lines
2.0 KiB
C
98 lines
2.0 KiB
C
/*
|
|
* Source file for entry point and initialization.
|
|
*
|
|
* CAR (Cool ARM Ripoff) copyright (c) 2026 David J Goeke. All rights reserved.
|
|
* Unauthorized (re)distribution is prohibited.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "include/defs.h"
|
|
|
|
static long get_file_size(FILE *fp)
|
|
{
|
|
long current = ftell(fp);
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
long size = ftell(fp);
|
|
|
|
fseek(fp, current, SEEK_SET);
|
|
|
|
return size;
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
printf("CAR (Cool ARM Ripoff) copyright (c) 2026 David J Goeke. All rights reserved.\n\n");
|
|
|
|
pstate_t* state = malloc(sizeof(pstate_t));
|
|
|
|
if (!state)
|
|
{
|
|
printf("Error: malloc failed.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (argc < 1)
|
|
{
|
|
printf("Error: no input file specified.\n");
|
|
return -1;
|
|
}
|
|
|
|
FILE* f = fopen(argv[1], "rb");
|
|
|
|
if (!f)
|
|
{
|
|
printf("Error: failed to open file %s.\n", argv[1]);
|
|
return -1;
|
|
}
|
|
|
|
uint8_t* data = malloc(get_file_size(f));
|
|
|
|
if (!data)
|
|
{
|
|
printf("Error: malloc failed.\n");
|
|
free(state);
|
|
return -1;
|
|
}
|
|
|
|
size_t read = fread(data, 1, get_file_size(f), f);
|
|
|
|
size_t words = read / sizeof(uint32_t);
|
|
|
|
if (read % sizeof(uint32_t) != 0)
|
|
{
|
|
fprintf(stderr, "Error: file size (%zu bytes) is not a multiple of 4.\n", read);
|
|
free(data);
|
|
free(state);
|
|
fclose(f);
|
|
return -1;
|
|
}
|
|
|
|
|
|
state->memory_size = words; // Just to be safe, use the number of bytes read instead of what get_file_size told us
|
|
state->memory = (uint32_t*) data;
|
|
|
|
state->flags = 0;
|
|
state->pc = 0; // TODO: we should load ELF files or some other format so we can start somewhere other than address 0 (and so we can have bss)
|
|
// We could set sp, but let's let software do that
|
|
|
|
for (int k = 0; k < words; k++)
|
|
{
|
|
state->memory[k] = __builtin_bswap32(state->memory[k]);
|
|
}
|
|
|
|
int j = processor_start(state);
|
|
|
|
if (j != 0)
|
|
{
|
|
// An error occured, though a message already has been printed, so for now do nothing.
|
|
}
|
|
|
|
free(data); // or would could do free(state->memory), shouldn't matter
|
|
free(state);
|
|
|
|
return 0;
|
|
}
|