rosgb/main.c
2024-05-17 22:13:30 -05:00

130 lines
2.6 KiB
C

#include<assert.h>
#include<inttypes.h>
#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include"cpu.h"
#include"ppu.h"
#include"gb.h"
#define _min(x,y) (((x)<(y))?(x):(y))
#define _max(x,y) (((x)>(y))?(x):(y))
int main(int argc,char **argv)
{
FILE *romfile;
Gb gb;
bool hexdumponly=false;
char*fname=NULL;
// Allocate Gb state
gb=gb_new();
if(!gb.cpu||!gb.ppu||!gb.ram)goto quit;
gb.log=true;
// Parse arguments
for(size_t i=1;i<(size_t)argc;++i)
{
if(strcmp(argv[i],"-d")==0)
hexdumponly=true;
// Default action: treat as ROM file name
else
fname=argv[i];
}
// Try to open ROM file
if(fname)
{
romfile=fopen(argv[1],"rb");
if(!romfile)
{
fprintf(stderr,"error: failed to open file '%s'\n",argv[1]);
goto quit;
}
}
else
{
fprintf(stderr,"error: no ROM files specified\n");
goto quit;
}
// Allocate memory for entire ROM file
fseek(romfile,0,SEEK_END);
gb.romsize=ftell(romfile);
gb.romsize=_max(gb.romsize,0x8000);
gb.rom=malloc(gb.romsize);
if(!gb.rom)return 2;
// Map ROM file into memory
rewind(romfile);
fread(gb.rom,1,gb.romsize,romfile);
printf("Loaded ROM \'%s\' (%u B)\n",argv[1],gb.romsize);
printf("ROM Size: %ukB\n",32<<gb.rom[0x148]);
printf("RAM Size: %ukB\n",16<<gb.rom[0x149]*2);
fclose(romfile);
// Hex dump only
if(hexdumponly)
{
cpu_romhexdump(gb.rom);
goto quit;
}
// Load program into RAM
for(int i=0;i<0x8000;i++)
{
gb.ram[i]=gb.rom[i];
assert(gb.ram[i]==gb.rom[i]);
}
printf("Loaded 8000h (32768) bytes into RAM\n");
// Open window
if(gb.video)
ppu_openwindow(gb.ppu,gb.rom+0x134);
// VRAM bank
gb.ram[0xff4f]=0;
// Main CPU loop
for(;;)
{
if(gb.video)
if(ppu_updatewindow(&gb,gb.ram))break;
if(gb.paused)continue;
// Manage Control Registers
gb.ram[0xff44]+=1; // CURLINE (VBLANK INT AT:144-153)
//gb.ram[0xff05]+=1; // TIMA (TIMER INT AT OVERFLOW)
//if(!gb.ram[0xff05])gb.ram[0xff05]=gb.ram[0xff06];
gb.ram[0xff41]=(gb.ram[0xff41]+1)%4; // V-BLANK
// Handle Interrupts
//if(gb.ram[0xff44]==144 && gb.ram[0xffff] && gb.cpu->ime) // V-BLANK INT
//{
//gb.cpu->sp-=2; // Push pc, jump to 0040h interrupt
//cpu_write_ram(gb.cpu,gb.ppu,gb.cpu->sp,gb.cpu->pc&0x00ff,gb.ram);
//cpu_write_ram(gb.cpu,gb.ppu,gb.cpu->sp+1,gb.cpu->pc>>8,gb.ram);
//gb.cpu->pc=0x0040;
//}
/* if(gb.log) */
/* printf("\n[%#10.8x]%#5.2x: ",gb.cpu->pc,gb.rom[gb.cpu->pc]); */
// Fetch, decode, execute instruction
cpu_fetch8(gb.cpu,gb.rom,&gb.op);
cpu_decexec(gb.cpu,gb.ppu,gb.rom,&gb.op,gb.ram,!gb.log);
}
// Clean up, exit
quit:
gb_print_cpu_state(&gb);
if(gb.video)
ppu_closewindow(gb.ppu);
gb_free(&gb);
}