📄 infones.cpp
字号:
/*===================================================================*/
/* */
/* InfoNES.cpp : NES Emulator for Win32, Linux(x86), Linux(PS2) */
/* */
/* 2000/05/18 InfoNES Project ( based on pNesX ) */
/* */
/*===================================================================*/
/*-------------------------------------------------------------------
* File List :
*
* [NES Hardware]
* InfoNES.cpp
* InfoNES.h
* K6502_rw.h
*
* [Mapper function]
* InfoNES_Mapper.cpp
* InfoNES_Mapper.h
*
* [The function which depends on a system]
* InfoNES_System_ooo.cpp (ooo is a system name. win, ...)
* InfoNES_System.h
*
* [CPU]
* K6502.cpp
* K6502.h
*
* [Others]
* InfoNES_Types.h
*
--------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Include files */
/*-------------------------------------------------------------------*/
#include "InfoNES.h"
#include "InfoNES_System.h"
#include "InfoNES_Mapper.h"
#include "InfoNES_pAPU.h"
#include "K6502.h"
/*-------------------------------------------------------------------*/
/* NES resources */
/*-------------------------------------------------------------------*/
/* RAM */
BYTE RAM[ RAM_SIZE ];
/* SRAM */
BYTE SRAM[ SRAM_SIZE ];
/* ROM */
BYTE *ROM;
/* SRAM BANK ( 8Kb ) */
BYTE *SRAMBANK;
/* ROM BANK ( 8Kb * 4 ) */
BYTE *ROMBANK0;
BYTE *ROMBANK1;
BYTE *ROMBANK2;
BYTE *ROMBANK3;
/*-------------------------------------------------------------------*/
/* PPU resources */
/*-------------------------------------------------------------------*/
/* PPU RAM */
BYTE PPURAM[ PPURAM_SIZE ];
/* VROM */
BYTE *VROM;
/* PPU BANK ( 1Kb * 16 ) */
BYTE *PPUBANK[ 16 ];
/* Sprite RAM */
BYTE SPRRAM[ SPRRAM_SIZE ];
/* PPU Register */
BYTE PPU_R0;
BYTE PPU_R1;
BYTE PPU_R2;
BYTE PPU_R3;
BYTE PPU_R7;
/* Vertical scroll value */
BYTE PPU_Scr_V;
BYTE PPU_Scr_V_Next;
BYTE PPU_Scr_V_Byte;
BYTE PPU_Scr_V_Byte_Next;
BYTE PPU_Scr_V_Bit;
BYTE PPU_Scr_V_Bit_Next;
/* Horizontal scroll value */
BYTE PPU_Scr_H;
BYTE PPU_Scr_H_Next;
BYTE PPU_Scr_H_Byte;
BYTE PPU_Scr_H_Byte_Next;
BYTE PPU_Scr_H_Bit;
BYTE PPU_Scr_H_Bit_Next;
/* PPU Address */
WORD PPU_Addr;
/* PPU Address */
WORD PPU_Temp;
/* The increase value of the PPU Address */
WORD PPU_Increment;
/* Current Scanline */
WORD PPU_Scanline;
/* Scanline Table */
BYTE PPU_ScanTable[ 263 ];
/* Name Table Bank */
BYTE PPU_NameTableBank;
/* BG Base Address */
BYTE *PPU_BG_Base;
/* Sprite Base Address */
BYTE *PPU_SP_Base;
/* Sprite Height */
WORD PPU_SP_Height;
/* Sprite #0 Scanline Hit Position */
int SpriteJustHit;
/* VRAM Write Enable ( 0: Disable, 1: Enable ) */
BYTE byVramWriteEnable;
/* PPU Address and Scroll Latch Flag*/
BYTE PPU_Latch_Flag;
/* Up and Down Clipping Flag ( 0: non-clip, 1: clip ) */
BYTE PPU_UpDown_Clip;
/* Frame IRQ ( 0: Disabled, 1: Enabled )*/
BYTE FrameIRQ_Enable;
WORD FrameStep;
/*-------------------------------------------------------------------*/
/* Display and Others resouces */
/*-------------------------------------------------------------------*/
/* Frame Skip */
WORD FrameSkip;
WORD FrameCnt;
/* Display Buffer */
WORD DoubleFrame[ 2 ][ NES_DISP_WIDTH * NES_DISP_HEIGHT ];
WORD *WorkFrame;
WORD WorkFrameIdx;
/* Character Buffer */
BYTE ChrBuf[ 256 * 2 * 8 * 8 ];
/* Update flag for ChrBuf */
BYTE ChrBufUpdate;
/* Palette Table */
WORD PalTable[ 32 ];
/* Table for Mirroring */
BYTE PPU_MirrorTable[][ 4 ] =
{
#if 1
{ NAME_TABLE0, NAME_TABLE0, NAME_TABLE1, NAME_TABLE1 },
{ NAME_TABLE0, NAME_TABLE1, NAME_TABLE0, NAME_TABLE1 },
{ NAME_TABLE1, NAME_TABLE1, NAME_TABLE1, NAME_TABLE1 },
{ NAME_TABLE0, NAME_TABLE0, NAME_TABLE0, NAME_TABLE0 }
#else
{ NAME_TABLE0, NAME_TABLE0, NAME_TABLE1, NAME_TABLE1 },
{ NAME_TABLE0, NAME_TABLE1, NAME_TABLE0, NAME_TABLE1 },
{ NAME_TABLE0, NAME_TABLE1, NAME_TABLE2, NAME_TABLE3 },
{ NAME_TABLE0, NAME_TABLE0, NAME_TABLE0, NAME_TABLE0 }
#endif
};
/*-------------------------------------------------------------------*/
/* APU and Pad resources */
/*-------------------------------------------------------------------*/
/* APU Register */
BYTE APU_Reg[ 0x18 ];
/* APU Mute ( 0:OFF, 1:ON ) */
int APU_Mute = 0;
/* Pad data */
DWORD PAD1_Latch;
DWORD PAD2_Latch;
DWORD PAD_System;
DWORD PAD1_Bit;
DWORD PAD2_Bit;
/*-------------------------------------------------------------------*/
/* Mapper Function */
/*-------------------------------------------------------------------*/
/* Initialize Mapper */
void (*MapperInit)();
/* Write to Mapper */
void (*MapperWrite)( WORD wAddr, BYTE byData );
/* Write to SRAM */
void (*MapperSram)( WORD wAddr, BYTE byData );
/* Write to Apu */
void (*MapperApu)( WORD wAddr, BYTE byData );
/* Read from Apu */
BYTE (*MapperReadApu)( WORD wAddr );
/* Callback at VSync */
void (*MapperVSync)();
/* Callback at HSync */
void (*MapperHSync)();
/* Callback at PPU read/write */
void (*MapperPPU)( WORD wAddr );
/* Callback at Rendering Screen 1:BG, 0:Sprite */
void (*MapperRenderScreen)( BYTE byMode );
/*-------------------------------------------------------------------*/
/* ROM information */
/*-------------------------------------------------------------------*/
/* .nes File Header */
struct NesHeader_tag NesHeader;
/* Mapper Number */
BYTE MapperNo;
/* Mirroring 0:Horizontal 1:Vertical */
BYTE ROM_Mirroring;
/* It has SRAM */
BYTE ROM_SRAM;
/* It has Trainer */
BYTE ROM_Trainer;
/* Four screen VRAM */
BYTE ROM_FourScr;
/*===================================================================*/
/* */
/* InfoNES_Init() : Initialize InfoNES */
/* */
/*===================================================================*/
void InfoNES_Init()
{
/*
* Initialize InfoNES
*
* Remarks
* Initialize K6502 and Scanline Table.
*/
int nIdx;
// Initialize 6502
K6502_Init();
// Initialize Scanline Table
for ( nIdx = 0; nIdx < 263; ++nIdx )
{
if ( nIdx < SCAN_ON_SCREEN_START )
PPU_ScanTable[ nIdx ] = SCAN_ON_SCREEN;
else
if ( nIdx < SCAN_BOTTOM_OFF_SCREEN_START )
PPU_ScanTable[ nIdx ] = SCAN_ON_SCREEN;
else
if ( nIdx < SCAN_UNKNOWN_START )
PPU_ScanTable[ nIdx ] = SCAN_ON_SCREEN;
else
if ( nIdx < SCAN_VBLANK_START )
PPU_ScanTable[ nIdx ] = SCAN_UNKNOWN;
else
PPU_ScanTable[ nIdx ] = SCAN_VBLANK;
}
}
/*===================================================================*/
/* */
/* InfoNES_Fin() : Completion treatment */
/* */
/*===================================================================*/
void InfoNES_Fin()
{
/*
* Completion treatment
*
* Remarks
* Release resources
*/
// Finalize pAPU
InfoNES_pAPUDone();
// Release a memory for ROM
InfoNES_ReleaseRom();
}
/*===================================================================*/
/* */
/* InfoNES_Load() : Load a cassette */
/* */
/*===================================================================*/
int InfoNES_Load( const char *pszFileName )
{
/*
* Load a cassette
*
* Parameters
* const char *pszFileName (Read)
* File name of ROM image
*
* Return values
* 0 : It was finished normally.
* -1 : An error occurred.
*
* Remarks
* Read a ROM image in the memory.
* Reset InfoNES.
*/
// Release a memory for ROM
InfoNES_ReleaseRom();
// Read a ROM image in the memory
if ( InfoNES_ReadRom( pszFileName ) < 0 )
return -1;
// Reset InfoNES
if ( InfoNES_Reset() < 0 )
return -1;
// Successful
return 0;
}
/*===================================================================*/
/* */
/* InfoNES_Reset() : Reset InfoNES */
/* */
/*===================================================================*/
int InfoNES_Reset()
{
/*
* Reset InfoNES
*
* Return values
* 0 : Normally
* -1 : Non support mapper
*
* Remarks
* Initialize Resources, PPU and Mapper.
* Reset CPU.
*/
int nIdx;
/*-------------------------------------------------------------------*/
/* Get information on the cassette */
/*-------------------------------------------------------------------*/
// Get Mapper Number
MapperNo = NesHeader.byInfo1 >> 4;
// Check bit counts of Mapper No.
for ( nIdx = 4; nIdx < 8 && NesHeader.byReserve[ nIdx ] == 0; ++nIdx )
;
if ( nIdx == 8 )
{
// Mapper Number is 8bits
MapperNo |= ( NesHeader.byInfo2 & 0xf0 );
}
// Get information on the ROM
ROM_Mirroring = NesHeader.byInfo1 & 1;
ROM_SRAM = NesHeader.byInfo1 & 2;
ROM_Trainer = NesHeader.byInfo1 & 4;
ROM_FourScr = NesHeader.byInfo1 & 8;
/*-------------------------------------------------------------------*/
/* Initialize resources */
/*-------------------------------------------------------------------*/
// Clear RAM
InfoNES_MemorySet( RAM, 0, sizeof RAM );
// Reset frame skip and frame count
FrameSkip = 0;
FrameCnt = 0;
// Reset work frame
WorkFrame = DoubleFrame[ 0 ];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -