mirror of
https://git.checksum.fail/alec/templenes.git
synced 2026-05-26 20:12:22 +00:00
379 lines
7.4 KiB
HolyC
Executable File
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;
|