Files

379 lines
7.4 KiB
HolyC
Executable File

#include "HDAudio";
// vim: set ft=c:
#ifndef SND_BUF_LEN
#define SND_BUF_LEN 0
U64 snd_obuf_num;
U64 fp_snd_fill_buf;
#endif
#ifndef SND_OUT_CONTAINER
#define SND_OUT_CONTAINER U32
#endif
U8 *rom_filename=NULL;
Bool rom_select=FALSE;
CDoc *doc_tmp=DocNew;
CDoc *doc_prev=Fs->put_doc;
CTask *draw_task=NULL;
CTask *emu_task=NULL;
CTask *sys_task=NULL;
CSprite *vid;
CDC *gameCanvas=DCNew(320,240);
CDC *Canvas16=DCNew(320,240);
DCFill(gameCanvas,0);
DCFill(Canvas16);
CDC *scr_pillar = DCNew(32,200);
DCFill(scr_pillar,0);
Bool fit_screen = FALSE;
I64 RoundUp(I64 numToRound, I64 multiple)
{
if (multiple == 0)
{
return numToRound;
}
I64 remainder = numToRound % multiple;
if (remainder == 0)
{
return numToRound;
}
return numToRound + multiple - remainder;
}
Bool reset = FALSE;
Bool quit = FALSE;
Bool paused = FALSE;
U8 cycles=0;
U8 loop=0;
U8 frame_finished=0;
U8 tmp_str[256];
#include "TOSGame";
#include "Font";
#include "GUI";
//Hide 64-bit reg var compiler warnings.
//Fs->put_doc=doc_tmp;
U8 *cartridgebuffer=NULL;
I64 numPRGROM;
I64 numCHRROM;
I64 controlByte1;
I64 controlByte2;
I64 numRAM;
I64 trainer;
I64 mapper;
I64 mirroringType;
Bool papu_request_irq = FALSE;
Bool mapper_request_irq = FALSE;
#define MIRR_HORZ 0
#define MIRR_VERT 1
#define MIRR_SINGLE 2
#include "Gamepad";
#include "Joypad";
#include "Mappers";
#include "PAPU";
#include "MMU";
#include "CPU";
#include "PPU";
#include "Audio";
initMMU();
U8 *system_state=MAlloc(0x200FD);
/*
U0 SaveInitSystemState()
{
MemCpy(system_state, MMU.RAM, 0xFFFF);
MemCpy(system_state+0xFFFF, MMU.VRAM, 0xFFFF);
MemCpy(system_state+(0xFFFF*2), MMU.OAM, 0xFF);
FileWrite("E:/Home/Src/templenes/State.BIN.Z",system_state,0x200FD);
}
*/
U0 LoadInitSystemState()
{
if (system_state)
{
//Free(system_state);
}
system_state=FileRead("E:/Home/Src/templenes/State.BIN.Z");
MemCpy(MMU.RAM, system_state, 0xFFFF);
MemCpy(MMU.VRAM, system_state+0xFFFF, 0xFFFF);
MemCpy(MMU.OAM, system_state+(0xFFFF*2), 0xFF);
MemCpy(system_state+0xFFFF, MMU.VRAM, 0xFFFF);
MemCpy(system_state+(0xFFFF*2), MMU.OAM, 0xFF);
//Free(system_state);
system_state=NULL;
}
U0 resetSystem()
{
reset6502;
//initalize the PPU
initPPU2C02(&PPU_state);
//initalize the Joypad
initJoypad(&NES_Joypad);
//initialize the pAPU
if (SND_BUF_LEN>0)
{
PAPU_reset(&PAPU);
}
}
U0 handleCmdButtons()
{
if (TG_KeyDown(SC_ESC))
{
quit=TRUE;
}
if (TG_KeyDown(Char2ScanCode('r')))
{
resetSystem;
}
if (TG_KeyDown(Char2ScanCode('d')))
{
paused = TRUE;
fp_snd_fill_buf=fp_old_fill_buf;
Sleep(100);//Give time to switch audio callback
TG_Exit;
Dbg;
fp_snd_fill_buf=&AudioFillBuf;
paused = FALSE;
}
}
U0 doScreenUpdate()
{
if (MMU.RAM[0x2000] & (1 << 5) != 0)
{
GrBlot(gameCanvas, 0, -8, Canvas16);
DCFill(Canvas16);
}
if (fit_screen)
{
vid=DC2Sprite(gameCanvas);
Sprite3XB(TG_Canvas, 0, 0, 0, vid, .58);
Free(vid);
}
else
{
GrBlot(TG_Canvas, 0, 0, gameCanvas);
GrBlot(TG_Canvas,0,0,scr_pillar);
GrBlot(TG_Canvas,288,0,scr_pillar);
}
UpdateGUI;
TG_Flip;
}
U0 drawScreen()
{
while (1)
{
WinMsUpdate;
KbdMsHndlr(FALSE, FALSE);
if( frame_finished ) {
updateGamepad;
frame_count += 1;
doScreenUpdate;
}
if ( paused )
{
doScreenUpdate;
}
}
}
U0 initCart(U8 *rom_filename)
{
cartridgebuffer = FileRead(rom_filename);
//if the file is not an iNES-file, abort
if(cartridgebuffer[0] != 'N' || cartridgebuffer[1] != 'E' || cartridgebuffer[2] != 'S' || cartridgebuffer[3] != 0x1a) {
PrintErr("File is not an iNES-file.\n");
return 1;
}
mirroringType = MIRR_HORZ;
numPRGROM = cartridgebuffer[4];
numCHRROM = cartridgebuffer[5];
controlByte1 = cartridgebuffer[6];
controlByte2 = cartridgebuffer[7];
numRAM = cartridgebuffer[8];
trainer = (controlByte1 & (1 << 2));
if (controlByte1 & 1)
{
mirroringType = MIRR_VERT;
}
mapper = ( (controlByte2 & 0xF0) | ((controlByte1 & 0xF0) >> 4));
//LoadInitSystemState;
switch (mapper)
{
case 0:
//Copy the ROM into the CPU's memory
MemCpy(MMU.RAM+0x8000, cartridgebuffer+0x10, numPRGROM*0x4000);
if(numPRGROM == 1) {
MemCpy(MMU.RAM+0xC000, cartridgebuffer+0x10, numPRGROM*0x4000);
}
//Copy the ROM into the PPU's memory
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000*numCHRROM);
break;
case 1:// MMC1
case 2:// UNROM
//Load first PRG ROM bank
MemCpy(MMU.RAM+0x8000, cartridgebuffer+0x10, 0x4000);
//and last PRG ROM bank
MemCpy(MMU.RAM+0xC000, cartridgebuffer+0x10+0x4000*(numPRGROM-1), 0x4000);
//Copy the ROM into the PPU's memory
if (numCHRROM)
{
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000*numCHRROM);
}
break;
case 3:// CNROM
//Copy the ROM into the CPU's memory
MemCpy(MMU.RAM+0x8000, cartridgebuffer+0x10, numPRGROM*0x4000);
if(numPRGROM == 1) {
MemCpy(MMU.RAM+0xC000, cartridgebuffer+0x10, numPRGROM*0x4000);
}
//Copy the ROM into the PPU's memory
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000);
break;
case 4:// MMC3
MMC1_load8kRomBank((numPRGROM - 1) * 2, 0xc000);
MMC1_load8kRomBank((numPRGROM - 1) * 2 + 1, 0xe000);
MMC1_load8kRomBank(0, 0x8000);
MMC1_load8kRomBank(1, 0xa000);
//Copy the ROM into the PPU's memory
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000);
break;
case 11:// Color Dreams
//Load first PRG ROM bank
MemCpy(MMU.RAM+0x8000, cartridgebuffer+0x10, 0x8000);
//Copy the ROM into the PPU's memory
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000);
break;
case 17:// FFE Copier
//Load first PRG ROM bank
MemCpy(MMU.RAM+0x8000, cartridgebuffer+0x10, 0x8000);
//Copy the ROM into the PPU's memory
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000);
break;
case 18:// Jaleco SS88006
//Load first/last PRG ROM bank
MemCpy(MMU.RAM+0x8000, cartridgebuffer+0x10, 0x4000);
MemCpy(MMU.RAM+0xC000, cartridgebuffer+0x10+(0x4000*(numPRGROM-1)), 0x4000);
//Copy the ROM into the PPU's memory
MemCpy(MMU.VRAM, cartridgebuffer+0x10+0x4000*numPRGROM, 0x2000);
break;
default:
PrintErr("iNES mapper not supported.\n");
//Free(cartridgebuffer);
return 1;
break;
}
}
I64 TempleNES(U8 *rom_file)
{
initCart(rom_file);
//initalize the CPU
reset6502;
//initalize the PPU
initPPU2C02(&PPU_state);
//initalize the Joypad
initJoypad(&NES_Joypad);
//initialize the pAPU
if (SND_BUF_LEN>0)
{
initPAPU(&PAPU);
}
//Initalize TOSGame
TG_Start;
//Initialize palette
PPU_InitPalette;
draw_task = Spawn(&drawScreen,,,1);
start_buf_num=snd_obuf_num;
fp_old_fill_buf=fp_snd_fill_buf;
fp_snd_fill_buf=&AudioFillBuf;
while(!quit && !TG_KeyDown(SC_ESC)) {
//emulate CPU and PPU
frame_finished = 0;
if( paused == 0) {
if (mapper_request_irq)
{
irq6502;
mapper_request_irq = FALSE;
}
if (papu_request_irq)
{
irq6502;
papu_request_irq = FALSE;
}
exec6502(1);
cycles = ticktable[opcode];
if (SND_BUF_LEN>0)
{
PAPU_clockFrameCounter(&PAPU, cycles);
}
loop = cycles*3;
while( loop != 0 )
{
frame_finished |= PPUcycle(&PPU_state);
loop -= 1;
}
I64 ii;
for (ii=0;ii<1024;ii++){} // Delay loop
}
if (reset)
{
resetSystem;
reset = FALSE;
}
handleCmdButtons;
handleInput(&NES_Joypad);
}
quit = FALSE;
fp_snd_fill_buf=fp_old_fill_buf;
Kill(draw_task);
DocClear;
//Free(cartridgebuffer);
TG_Exit;
return 0;
}
Fs->put_doc=doc_prev;
start_buf_num=snd_obuf_num;
fp_old_fill_buf=fp_snd_fill_buf;