diff --git a/README.md b/README.md index df7f3fb0..db3a7be0 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,9 @@ Mapper支持越多,通俗讲就是支持更多卡带。 我们的项目也必须支持上! 咱们也同步要进行一个补充 -追加了特殊的失传Mapper 162,163,175,176,178,192,195,199,216 (from https://github.com/yamanyandakure/VirtuaNES097) +追加了特殊的失传Mapper 35,111,162,163,175,176,178,192,195,199,216 (from https://github.com/yamanyandakure/VirtuaNES097) + +后续补充二次,修正 Mapper199 参照叶枫VirtuaNESex_src(20191105) diff --git a/References/VirtuaNESex_src_191105/7z/7z.h b/References/VirtuaNESex_src_191105/7z/7z.h new file mode 100644 index 00000000..01c4cac6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7z.h @@ -0,0 +1,203 @@ +/* 7z.h -- 7z interface +2010-03-11 : Igor Pavlov : Public domain */ + +#ifndef __7Z_H +#define __7Z_H + +#include "7zBuf.h" + +EXTERN_C_BEGIN + +#define k7zStartHeaderSize 0x20 +#define k7zSignatureSize 6 +extern Byte k7zSignature[k7zSignatureSize]; +#define k7zMajorVersion 0 + +enum EIdEnum +{ + k7zIdEnd, + k7zIdHeader, + k7zIdArchiveProperties, + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + k7zIdPackInfo, + k7zIdUnpackInfo, + k7zIdSubStreamsInfo, + k7zIdSize, + k7zIdCRC, + k7zIdFolder, + k7zIdCodersUnpackSize, + k7zIdNumUnpackStream, + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + k7zIdName, + k7zIdCTime, + k7zIdATime, + k7zIdMTime, + k7zIdWinAttributes, + k7zIdComment, + k7zIdEncodedHeader, + k7zIdStartPos, + k7zIdDummy +}; + +typedef struct +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; + UInt64 MethodID; + CBuf Props; +} CSzCoderInfo; + +void SzCoderInfo_Init(CSzCoderInfo *p); +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); + +typedef struct +{ + UInt32 InIndex; + UInt32 OutIndex; +} CSzBindPair; + +typedef struct +{ + CSzCoderInfo *Coders; + CSzBindPair *BindPairs; + UInt32 *PackStreams; + UInt64 *UnpackSizes; + UInt32 NumCoders; + UInt32 NumBindPairs; + UInt32 NumPackStreams; + int UnpackCRCDefined; + UInt32 UnpackCRC; + + UInt32 NumUnpackStreams; +} CSzFolder; + +void SzFolder_Init(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); + +SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, + ILookInStream *stream, UInt64 startPos, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); + +typedef struct +{ + UInt32 Low; + UInt32 High; +} CNtfsFileTime; + +typedef struct +{ + CNtfsFileTime MTime; + UInt64 Size; + UInt32 Crc; + UInt32 Attrib; + Byte HasStream; + Byte IsDir; + Byte IsAnti; + Byte CrcDefined; + Byte MTimeDefined; + Byte AttribDefined; +} CSzFileItem; + +void SzFile_Init(CSzFileItem *p); + +typedef struct +{ + UInt64 *PackSizes; + Byte *PackCRCsDefined; + UInt32 *PackCRCs; + CSzFolder *Folders; + CSzFileItem *Files; + UInt32 NumPackStreams; + UInt32 NumFolders; + UInt32 NumFiles; +} CSzAr; + +void SzAr_Init(CSzAr *p); +void SzAr_Free(CSzAr *p, ISzAlloc *alloc); + + +/* + SzExtract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +typedef struct +{ + CSzAr db; + + UInt64 startPosAfterHeader; + UInt64 dataPos; + + UInt32 *FolderStartPackStreamIndex; + UInt64 *PackStreamStartPositions; + UInt32 *FolderStartFileIndex; + UInt32 *FileIndexToFolderIndexMap; + + size_t *FileNameOffsets; /* in 2-byte steps */ + CBuf FileNames; /* UTF-16-LE */ +} CSzArEx; + +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); + +/* +if dest == NULL, the return value specifies the required size of the buffer, + in 16-bit characters, including the null-terminating character. +if dest != NULL, the return value specifies the number of 16-bit characters that + are written to the dest, including the null-terminating character. */ + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); + +SRes SzArEx_Extract( + const CSzArEx *db, + ILookInStream *inStream, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + + +/* +SzArEx_Open Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/7zAlloc.c b/References/VirtuaNESex_src_191105/7z/7zAlloc.c new file mode 100644 index 00000000..964b28db --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zAlloc.c @@ -0,0 +1,76 @@ +/* 7zAlloc.c -- Allocation functions +2010-10-29 : Igor Pavlov : Public domain */ + +#include "7zAlloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef _SZ_ALLOC_DEBUG + +#ifdef _WIN32 +#include +#endif + +#include +int g_allocCount = 0; +int g_allocCountTemp = 0; + +#endif + +void *SzAlloc(void *p, size_t size) +{ + p = p; + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); + g_allocCount++; + #endif + return malloc(size); +} + +void SzFree(void *p, void *address) +{ + p = p; + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCount--; + fprintf(stderr, "\nFree; count = %10d", g_allocCount); + } + #endif + free(address); +} + +void *SzAllocTemp(void *p, size_t size) +{ + p = p; + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); + g_allocCountTemp++; + #ifdef _WIN32 + return HeapAlloc(GetProcessHeap(), 0, size); + #endif + #endif + return malloc(size); +} + +void SzFreeTemp(void *p, void *address) +{ + p = p; + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCountTemp--; + fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); + } + #ifdef _WIN32 + HeapFree(GetProcessHeap(), 0, address); + return; + #endif + #endif + free(address); +} diff --git a/References/VirtuaNESex_src_191105/7z/7zAlloc.h b/References/VirtuaNESex_src_191105/7z/7zAlloc.h new file mode 100644 index 00000000..3344e937 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zAlloc.h @@ -0,0 +1,15 @@ +/* 7zAlloc.h -- Allocation functions +2010-10-29 : Igor Pavlov : Public domain */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include + +void *SzAlloc(void *p, size_t size); +void SzFree(void *p, void *address); + +void *SzAllocTemp(void *p, size_t size); +void SzFreeTemp(void *p, void *address); + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/7zBuf.c b/References/VirtuaNESex_src_191105/7z/7zBuf.c new file mode 100644 index 00000000..14e7f4e2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zBuf.c @@ -0,0 +1,36 @@ +/* 7zBuf.c -- Byte Buffer +2008-03-28 +Igor Pavlov +Public domain */ + +#include "7zBuf.h" + +void Buf_Init(CBuf *p) +{ + p->data = 0; + p->size = 0; +} + +int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) +{ + p->size = 0; + if (size == 0) + { + p->data = 0; + return 1; + } + p->data = (Byte *)alloc->Alloc(alloc, size); + if (p->data != 0) + { + p->size = size; + return 1; + } + return 0; +} + +void Buf_Free(CBuf *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->data); + p->data = 0; + p->size = 0; +} diff --git a/References/VirtuaNESex_src_191105/7z/7zBuf.h b/References/VirtuaNESex_src_191105/7z/7zBuf.h new file mode 100644 index 00000000..e9f2f316 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zBuf.h @@ -0,0 +1,39 @@ +/* 7zBuf.h -- Byte Buffer +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __7Z_BUF_H +#define __7Z_BUF_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + Byte *data; + size_t size; +} CBuf; + +void Buf_Init(CBuf *p); +int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); +void Buf_Free(CBuf *p, ISzAlloc *alloc); + +typedef struct +{ + Byte *data; + size_t size; + size_t pos; +} CDynBuf; + +void DynBuf_Construct(CDynBuf *p); +void DynBuf_SeekToBeg(CDynBuf *p); +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); +void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/7zCrc.c b/References/VirtuaNESex_src_191105/7z/7zCrc.c new file mode 100644 index 00000000..a9208496 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zCrc.c @@ -0,0 +1,74 @@ +/* 7zCrc.c -- CRC32 calculation +2009-11-23 : Igor Pavlov : Public domain */ + +#include "7zCrc.h" +#include "CpuArch.h" + +#define kCrcPoly 0xEDB88320 + +#ifdef MY_CPU_LE +#define CRC_NUM_TABLES 8 +#else +#define CRC_NUM_TABLES 1 +#endif + +typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); + +static CRC_FUNC g_CrcUpdate; +UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; + +#if CRC_NUM_TABLES == 1 + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#else + +UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); + +#endif + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) +{ + return g_CrcUpdate(v, data, size, g_CrcTable); +} + +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) +{ + return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; +} + +void MY_FAST_CALL CrcGenerateTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + g_CrcTable[i] = r; + } + #if CRC_NUM_TABLES == 1 + g_CrcUpdate = CrcUpdateT1; + #else + for (; i < 256 * CRC_NUM_TABLES; i++) + { + UInt32 r = g_CrcTable[i - 256]; + g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); + } + g_CrcUpdate = CrcUpdateT4; + #ifdef MY_CPU_X86_OR_AMD64 + if (!CPU_Is_InOrder()) + g_CrcUpdate = CrcUpdateT8; + #endif + #endif +} diff --git a/References/VirtuaNESex_src_191105/7z/7zCrc.h b/References/VirtuaNESex_src_191105/7z/7zCrc.h new file mode 100644 index 00000000..38e3e5fb --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zCrc.h @@ -0,0 +1,25 @@ +/* 7zCrc.h -- CRC32 calculation +2009-11-21 : Igor Pavlov : Public domain */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include "Types.h" + +EXTERN_C_BEGIN + +extern UInt32 g_CrcTable[]; + +/* Call CrcGenerateTable one time before other CRC functions */ +void MY_FAST_CALL CrcGenerateTable(void); + +#define CRC_INIT_VAL 0xFFFFFFFF +#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) +#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/7zCrcOpt.c b/References/VirtuaNESex_src_191105/7z/7zCrcOpt.c new file mode 100644 index 00000000..6c766a20 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zCrcOpt.c @@ -0,0 +1,34 @@ +/* 7zCrcOpt.c -- CRC32 calculation : optimized version +2009-11-23 : Igor Pavlov : Public domain */ + +#include "CpuArch.h" + +#ifdef MY_CPU_LE + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const UInt32 *)p; + v = + table[0x300 + (v & 0xFF)] ^ + table[0x200 + ((v >> 8) & 0xFF)] ^ + table[0x100 + ((v >> 16) & 0xFF)] ^ + table[0x000 + ((v >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + return CrcUpdateT4(v, data, size, table); +} + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/7zDec.c b/References/VirtuaNESex_src_191105/7z/7zDec.c new file mode 100644 index 00000000..b6d80995 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zDec.c @@ -0,0 +1,470 @@ +/* 7zDec.c -- Decoding from 7z folder +2010-11-02 : Igor Pavlov : Public domain */ + +#include + +/* #define _7ZIP_PPMD_SUPPPORT */ + +#include "7z.h" + +#include "Bcj2.h" +#include "Bra.h" +#include "CpuArch.h" +#include "LzmaDec.h" +#include "Lzma2Dec.h" +#ifdef _7ZIP_PPMD_SUPPPORT +#include "Ppmd7.h" +#endif + +#define k_Copy 0 +#define k_LZMA2 0x21 +#define k_LZMA 0x30101 +#define k_BCJ 0x03030103 +#define k_PPC 0x03030205 +#define k_ARM 0x03030501 +#define k_ARMT 0x03030701 +#define k_SPARC 0x03030805 +#define k_BCJ2 0x0303011B + +#ifdef _7ZIP_PPMD_SUPPPORT + +#define k_PPMD 0x30401 + +typedef struct +{ + IByteIn p; + const Byte *cur; + const Byte *end; + const Byte *begin; + UInt64 processed; + Bool extra; + SRes res; + ILookInStream *inStream; +} CByteInToLook; + +static Byte ReadByte(void *pp) +{ + CByteInToLook *p = (CByteInToLook *)pp; + if (p->cur != p->end) + return *p->cur++; + if (p->res == SZ_OK) + { + size_t size = p->cur - p->begin; + p->processed += size; + p->res = p->inStream->Skip(p->inStream, size); + size = (1 << 25); + p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); + p->cur = p->begin; + p->end = p->begin + size; + if (size != 0) + return *p->cur++;; + } + p->extra = True; + return 0; +} + +static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CPpmd7 ppmd; + CByteInToLook s; + SRes res = SZ_OK; + + s.p.Read = ReadByte; + s.inStream = inStream; + s.begin = s.end = s.cur = NULL; + s.extra = False; + s.res = SZ_OK; + s.processed = 0; + + if (coder->Props.size != 5) + return SZ_ERROR_UNSUPPORTED; + + { + unsigned order = coder->Props.data[0]; + UInt32 memSize = GetUi32(coder->Props.data + 1); + if (order < PPMD7_MIN_ORDER || + order > PPMD7_MAX_ORDER || + memSize < PPMD7_MIN_MEM_SIZE || + memSize > PPMD7_MAX_MEM_SIZE) + return SZ_ERROR_UNSUPPORTED; + Ppmd7_Construct(&ppmd); + if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) + return SZ_ERROR_MEM; + Ppmd7_Init(&ppmd, order); + } + { + CPpmd7z_RangeDec rc; + Ppmd7z_RangeDec_CreateVTable(&rc); + rc.Stream = &s.p; + if (!Ppmd7z_RangeDec_Init(&rc)) + res = SZ_ERROR_DATA; + else if (s.extra) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else + { + SizeT i; + for (i = 0; i < outSize; i++) + { + int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); + if (s.extra || sym < 0) + break; + outBuffer[i] = (Byte)sym; + } + if (i != outSize) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) + res = SZ_ERROR_DATA; + } + } + Ppmd7_Free(&ppmd, allocMain); + return res; +} + +#endif + + +static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CLzmaDec state; + SRes res = SZ_OK; + + LzmaDec_Construct(&state); + RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); + + for (;;) + { + Byte *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) + { + if (state.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + LzmaDec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CLzma2Dec state; + SRes res = SZ_OK; + + Lzma2Dec_Construct(&state); + if (coder->Props.size != 1) + return SZ_ERROR_DATA; + RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); + state.decoder.dic = outBuffer; + state.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&state); + + for (;;) + { + Byte *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; + ELzmaStatus status; + res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) + { + if (state.decoder.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + Lzma2Dec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) +{ + while (inSize > 0) + { + void *inBuf; + size_t curSize = (1 << 18); + if (curSize > inSize) + curSize = (size_t)inSize; + RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuf, curSize); + outBuffer += curSize; + inSize -= curSize; + RINOK(inStream->Skip((void *)inStream, curSize)); + } + return SZ_OK; +} + +static Bool IS_MAIN_METHOD(UInt32 m) +{ + switch(m) + { + case k_Copy: + case k_LZMA: + case k_LZMA2: + #ifdef _7ZIP_PPMD_SUPPPORT + case k_PPMD: + #endif + return True; + } + return False; +} + +static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) +{ + return + c->NumInStreams == 1 && + c->NumOutStreams == 1 && + c->MethodID <= (UInt32)0xFFFFFFFF && + IS_MAIN_METHOD((UInt32)c->MethodID); +} + +#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) + +static SRes CheckSupportedFolder(const CSzFolder *f) +{ + if (f->NumCoders < 1 || f->NumCoders > 4) + return SZ_ERROR_UNSUPPORTED; + if (!IS_SUPPORTED_CODER(&f->Coders[0])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumCoders == 1) + { + if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + if (f->NumCoders == 2) + { + CSzCoderInfo *c = &f->Coders[1]; + if (c->MethodID > (UInt32)0xFFFFFFFF || + c->NumInStreams != 1 || + c->NumOutStreams != 1 || + f->NumPackStreams != 1 || + f->PackStreams[0] != 0 || + f->NumBindPairs != 1 || + f->BindPairs[0].InIndex != 1 || + f->BindPairs[0].OutIndex != 0) + return SZ_ERROR_UNSUPPORTED; + switch ((UInt32)c->MethodID) + { + case k_BCJ: + case k_ARM: + break; + default: + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; + } + if (f->NumCoders == 4) + { + if (!IS_SUPPORTED_CODER(&f->Coders[1]) || + !IS_SUPPORTED_CODER(&f->Coders[2]) || + !IS_BCJ2(&f->Coders[3])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumPackStreams != 4 || + f->PackStreams[0] != 2 || + f->PackStreams[1] != 6 || + f->PackStreams[2] != 1 || + f->PackStreams[3] != 0 || + f->NumBindPairs != 3 || + f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || + f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || + f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + return SZ_ERROR_UNSUPPORTED; +} + +static UInt64 GetSum(const UInt64 *values, UInt32 index) +{ + UInt64 sum = 0; + UInt32 i; + for (i = 0; i < index; i++) + sum += values[i]; + return sum; +} + +#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; + +static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, + Byte *tempBuf[]) +{ + UInt32 ci; + SizeT tempSizes[3] = { 0, 0, 0}; + SizeT tempSize3 = 0; + Byte *tempBuf3 = 0; + + RINOK(CheckSupportedFolder(folder)); + + for (ci = 0; ci < folder->NumCoders; ci++) + { + CSzCoderInfo *coder = &folder->Coders[ci]; + + if (IS_MAIN_METHOD((UInt32)coder->MethodID)) + { + UInt32 si = 0; + UInt64 offset; + UInt64 inSize; + Byte *outBufCur = outBuffer; + SizeT outSizeCur = outSize; + if (folder->NumCoders == 4) + { + UInt32 indices[] = { 3, 2, 0 }; + UInt64 unpackSize = folder->UnpackSizes[ci]; + si = indices[ci]; + if (ci < 2) + { + Byte *temp; + outSizeCur = (SizeT)unpackSize; + if (outSizeCur != unpackSize) + return SZ_ERROR_MEM; + temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); + if (temp == 0 && outSizeCur != 0) + return SZ_ERROR_MEM; + outBufCur = tempBuf[1 - ci] = temp; + tempSizes[1 - ci] = outSizeCur; + } + else if (ci == 2) + { + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; + tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); + tempSize3 = outSizeCur = (SizeT)unpackSize; + } + else + return SZ_ERROR_UNSUPPORTED; + } + offset = GetSum(packSizes, si); + inSize = packSizes[si]; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) /* check it */ + return SZ_ERROR_DATA; + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + } + else if (coder->MethodID == k_LZMA) + { + RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + else if (coder->MethodID == k_LZMA2) + { + RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + else + { + #ifdef _7ZIP_PPMD_SUPPPORT + RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + #else + return SZ_ERROR_UNSUPPORTED; + #endif + } + } + else if (coder->MethodID == k_BCJ2) + { + UInt64 offset = GetSum(packSizes, 1); + UInt64 s3Size = packSizes[1]; + SRes res; + if (ci != 3) + return SZ_ERROR_UNSUPPORTED; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + tempSizes[2] = (SizeT)s3Size; + if (tempSizes[2] != s3Size) + return SZ_ERROR_MEM; + tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); + if (tempBuf[2] == 0 && tempSizes[2] != 0) + return SZ_ERROR_MEM; + res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); + RINOK(res) + + res = Bcj2_Decode( + tempBuf3, tempSize3, + tempBuf[0], tempSizes[0], + tempBuf[1], tempSizes[1], + tempBuf[2], tempSizes[2], + outBuffer, outSize); + RINOK(res) + } + else + { + if (ci != 1) + return SZ_ERROR_UNSUPPORTED; + switch(coder->MethodID) + { + case k_BCJ: + { + UInt32 state; + x86_Convert_Init(state); + x86_Convert(outBuffer, outSize, 0, &state, 0); + break; + } + CASE_BRA_CONV(ARM) + default: + return SZ_ERROR_UNSUPPORTED; + } + } + } + return SZ_OK; +} + +SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) +{ + Byte *tempBuf[3] = { 0, 0, 0}; + int i; + SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, + outBuffer, (SizeT)outSize, allocMain, tempBuf); + for (i = 0; i < 3; i++) + IAlloc_Free(allocMain, tempBuf[i]); + return res; +} diff --git a/References/VirtuaNESex_src_191105/7z/7zFile.c b/References/VirtuaNESex_src_191105/7z/7zFile.c new file mode 100644 index 00000000..a66c9e9d --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zFile.c @@ -0,0 +1,284 @@ +/* 7zFile.c -- File IO +2009-11-24 : Igor Pavlov : Public domain */ + +#include "7zFile.h" + +#ifndef USE_WINDOWS_FILE + +#ifndef UNDER_CE +#include +#endif + +#else + +/* + ReadFile and WriteFile functions in Windows have BUG: + If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) + from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES + (Insufficient system resources exist to complete the requested service). + Probably in some version of Windows there are problems with other sizes: + for 32 MB (maybe also for 16 MB). + And message can be "Network connection was lost" +*/ + +#define kChunkSizeMax (1 << 22) + +#endif + +void File_Construct(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + p->handle = INVALID_HANDLE_VALUE; + #else + p->file = NULL; + #endif +} + +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +static WRes File_Open(CSzFile *p, const char *name, int writeMode) +{ + #ifdef USE_WINDOWS_FILE + p->handle = CreateFileA(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); + #else + p->file = fopen(name, writeMode ? "wb+" : "rb"); + return (p->file != 0) ? 0 : + #ifdef UNDER_CE + 2; /* ENOENT */ + #else + errno; + #endif + #endif +} + +WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } +WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } +#endif + +#ifdef USE_WINDOWS_FILE +static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) +{ + p->handle = CreateFileW(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); +} +WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } +#endif + +WRes File_Close(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + if (p->handle != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(p->handle)) + return GetLastError(); + p->handle = INVALID_HANDLE_VALUE; + } + #else + if (p->file != NULL) + { + int res = fclose(p->file); + if (res != 0) + return res; + p->file = NULL; + } + #endif + return 0; +} + +WRes File_Read(CSzFile *p, void *data, size_t *size) +{ + size_t originalSize = *size; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + *size = 0; + do + { + DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + return 0; + + #else + + *size = fread(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + + #endif +} + +WRes File_Write(CSzFile *p, const void *data, size_t *size) +{ + size_t originalSize = *size; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + *size = 0; + do + { + DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + return 0; + + #else + + *size = fwrite(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + + #endif +} + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) +{ + #ifdef USE_WINDOWS_FILE + + LARGE_INTEGER value; + DWORD moveMethod; + value.LowPart = (DWORD)*pos; + value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ + switch (origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return ERROR_INVALID_PARAMETER; + } + value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + { + WRes res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *pos = ((Int64)value.HighPart << 32) | value.LowPart; + return 0; + + #else + + int moveMethod; + int res; + switch (origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return 1; + } + res = fseek(p->file, (long)*pos, moveMethod); + *pos = ftell(p->file); + return res; + + #endif +} + +WRes File_GetLength(CSzFile *p, UInt64 *length) +{ + #ifdef USE_WINDOWS_FILE + + DWORD sizeHigh; + DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + { + DWORD res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *length = (((UInt64)sizeHigh) << 32) + sizeLow; + return 0; + + #else + + long pos = ftell(p->file); + int res = fseek(p->file, 0, SEEK_END); + *length = ftell(p->file); + fseek(p->file, pos, SEEK_SET); + return res; + + #endif +} + + +/* ---------- FileSeqInStream ---------- */ + +static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) +{ + CFileSeqInStream *p = (CFileSeqInStream *)pp; + return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; +} + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p) +{ + p->s.Read = FileSeqInStream_Read; +} + + +/* ---------- FileInStream ---------- */ + +static SRes FileInStream_Read(void *pp, void *buf, size_t *size) +{ + CFileInStream *p = (CFileInStream *)pp; + return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) +{ + CFileInStream *p = (CFileInStream *)pp; + return File_Seek(&p->file, pos, origin); +} + +void FileInStream_CreateVTable(CFileInStream *p) +{ + p->s.Read = FileInStream_Read; + p->s.Seek = FileInStream_Seek; +} + + +/* ---------- FileOutStream ---------- */ + +static size_t FileOutStream_Write(void *pp, const void *data, size_t size) +{ + CFileOutStream *p = (CFileOutStream *)pp; + File_Write(&p->file, data, &size); + return size; +} + +void FileOutStream_CreateVTable(CFileOutStream *p) +{ + p->s.Write = FileOutStream_Write; +} diff --git a/References/VirtuaNESex_src_191105/7z/7zFile.h b/References/VirtuaNESex_src_191105/7z/7zFile.h new file mode 100644 index 00000000..84538c03 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zFile.h @@ -0,0 +1,83 @@ +/* 7zFile.h -- File IO +2009-11-24 : Igor Pavlov : Public domain */ + +#ifndef __7Z_FILE_H +#define __7Z_FILE_H + +#ifdef _WIN32 +#define USE_WINDOWS_FILE +#endif + +#ifdef USE_WINDOWS_FILE +#include +#else +#include +#endif + +#include "Types.h" + +EXTERN_C_BEGIN + +/* ---------- File ---------- */ + +typedef struct +{ + #ifdef USE_WINDOWS_FILE + HANDLE handle; + #else + FILE *file; + #endif +} CSzFile; + +void File_Construct(CSzFile *p); +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +WRes InFile_Open(CSzFile *p, const char *name); +WRes OutFile_Open(CSzFile *p, const char *name); +#endif +#ifdef USE_WINDOWS_FILE +WRes InFile_OpenW(CSzFile *p, const WCHAR *name); +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); +#endif +WRes File_Close(CSzFile *p); + +/* reads max(*size, remain file's size) bytes */ +WRes File_Read(CSzFile *p, void *data, size_t *size); + +/* writes *size bytes */ +WRes File_Write(CSzFile *p, const void *data, size_t *size); + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); +WRes File_GetLength(CSzFile *p, UInt64 *length); + + +/* ---------- FileInStream ---------- */ + +typedef struct +{ + ISeqInStream s; + CSzFile file; +} CFileSeqInStream; + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p); + + +typedef struct +{ + ISeekInStream s; + CSzFile file; +} CFileInStream; + +void FileInStream_CreateVTable(CFileInStream *p); + + +typedef struct +{ + ISeqOutStream s; + CSzFile file; +} CFileOutStream; + +void FileOutStream_CreateVTable(CFileOutStream *p); + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/7zIn.c b/References/VirtuaNESex_src_191105/7z/7zIn.c new file mode 100644 index 00000000..ec93a43f --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zIn.c @@ -0,0 +1,1402 @@ +/* 7zIn.c -- 7z Input functions +2010-10-29 : Igor Pavlov : Public domain */ + +#include + +#include "7z.h" +#include "7zCrc.h" +#include "CpuArch.h" + +Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + +#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } + +#define NUM_FOLDER_CODERS_MAX 32 +#define NUM_CODER_STREAMS_MAX 32 + +void SzCoderInfo_Init(CSzCoderInfo *p) +{ + Buf_Init(&p->Props); +} + +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) +{ + Buf_Free(&p->Props, alloc); + SzCoderInfo_Init(p); +} + +void SzFolder_Init(CSzFolder *p) +{ + p->Coders = 0; + p->BindPairs = 0; + p->PackStreams = 0; + p->UnpackSizes = 0; + p->NumCoders = 0; + p->NumBindPairs = 0; + p->NumPackStreams = 0; + p->UnpackCRCDefined = 0; + p->UnpackCRC = 0; + p->NumUnpackStreams = 0; +} + +void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) +{ + UInt32 i; + if (p->Coders) + for (i = 0; i < p->NumCoders; i++) + SzCoderInfo_Free(&p->Coders[i], alloc); + IAlloc_Free(alloc, p->Coders); + IAlloc_Free(alloc, p->BindPairs); + IAlloc_Free(alloc, p->PackStreams); + IAlloc_Free(alloc, p->UnpackSizes); + SzFolder_Init(p); +} + +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) +{ + UInt32 result = 0; + UInt32 i; + for (i = 0; i < p->NumCoders; i++) + result += p->Coders[i].NumOutStreams; + return result; +} + +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) +{ + UInt32 i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; +} + + +int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) +{ + UInt32 i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; +} + +UInt64 SzFolder_GetUnpackSize(CSzFolder *p) +{ + int i = (int)SzFolder_GetNumOutStreams(p); + if (i == 0) + return 0; + for (i--; i >= 0; i--) + if (SzFolder_FindBindPairForOutStream(p, i) < 0) + return p->UnpackSizes[i]; + /* throw 1; */ + return 0; +} + +void SzFile_Init(CSzFileItem *p) +{ + p->HasStream = 1; + p->IsDir = 0; + p->IsAnti = 0; + p->CrcDefined = 0; + p->MTimeDefined = 0; +} + +void SzAr_Init(CSzAr *p) +{ + p->PackSizes = 0; + p->PackCRCsDefined = 0; + p->PackCRCs = 0; + p->Folders = 0; + p->Files = 0; + p->NumPackStreams = 0; + p->NumFolders = 0; + p->NumFiles = 0; +} + +void SzAr_Free(CSzAr *p, ISzAlloc *alloc) +{ + UInt32 i; + if (p->Folders) + for (i = 0; i < p->NumFolders; i++) + SzFolder_Free(&p->Folders[i], alloc); + + IAlloc_Free(alloc, p->PackSizes); + IAlloc_Free(alloc, p->PackCRCsDefined); + IAlloc_Free(alloc, p->PackCRCs); + IAlloc_Free(alloc, p->Folders); + IAlloc_Free(alloc, p->Files); + SzAr_Init(p); +} + + +void SzArEx_Init(CSzArEx *p) +{ + SzAr_Init(&p->db); + p->FolderStartPackStreamIndex = 0; + p->PackStreamStartPositions = 0; + p->FolderStartFileIndex = 0; + p->FileIndexToFolderIndexMap = 0; + p->FileNameOffsets = 0; + Buf_Init(&p->FileNames); +} + +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) +{ + IAlloc_Free(alloc, p->FolderStartPackStreamIndex); + IAlloc_Free(alloc, p->PackStreamStartPositions); + IAlloc_Free(alloc, p->FolderStartFileIndex); + IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); + + IAlloc_Free(alloc, p->FileNameOffsets); + Buf_Free(&p->FileNames, alloc); + + SzAr_Free(&p->db, alloc); + SzArEx_Init(p); +} + +/* +UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const +{ + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; +} + +UInt64 GetFilePackSize(int fileIndex) const +{ + int folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + const CSzFolder &folderInfo = Folders[folderIndex]; + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; +} +*/ + +#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ + if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } + +static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) +{ + UInt32 startPos = 0; + UInt64 startPosSize = 0; + UInt32 i; + UInt32 folderIndex = 0; + UInt32 indexInFolder = 0; + MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); + for (i = 0; i < p->db.NumFolders; i++) + { + p->FolderStartPackStreamIndex[i] = startPos; + startPos += p->db.Folders[i].NumPackStreams; + } + + MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); + + for (i = 0; i < p->db.NumPackStreams; i++) + { + p->PackStreamStartPositions[i] = startPosSize; + startPosSize += p->db.PackSizes[i]; + } + + MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); + MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); + + for (i = 0; i < p->db.NumFiles; i++) + { + CSzFileItem *file = p->db.Files + i; + int emptyStream = !file->HasStream; + if (emptyStream && indexInFolder == 0) + { + p->FileIndexToFolderIndexMap[i] = (UInt32)-1; + continue; + } + if (indexInFolder == 0) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: Loop for skipping empty folders + */ + for (;;) + { + if (folderIndex >= p->db.NumFolders) + return SZ_ERROR_ARCHIVE; + p->FolderStartFileIndex[folderIndex] = i; + if (p->db.Folders[folderIndex].NumUnpackStreams != 0) + break; + folderIndex++; + } + } + p->FileIndexToFolderIndexMap[i] = folderIndex; + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) + { + folderIndex++; + indexInFolder = 0; + } + } + return SZ_OK; +} + + +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) +{ + return p->dataPos + + p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; +} + +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) +{ + UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; + CSzFolder *folder = p->db.Folders + folderIndex; + UInt64 size = 0; + UInt32 i; + for (i = 0; i < folder->NumPackStreams; i++) + { + UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; + if (t < size) /* check it */ + return SZ_ERROR_FAIL; + size = t; + } + *resSize = size; + return SZ_OK; +} + + +/* +SRes SzReadTime(const CObjectVector &dataVector, + CObjectVector &files, UInt64 type) +{ + CBoolVector boolVector; + RINOK(ReadBoolVector2(files.Size(), boolVector)) + + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + + for (int i = 0; i < files.Size(); i++) + { + CSzFileItem &file = files[i]; + CArchiveFileTime fileTime; + bool defined = boolVector[i]; + if (defined) + { + UInt32 low, high; + RINOK(SzReadUInt32(low)); + RINOK(SzReadUInt32(high)); + fileTime.dwLowDateTime = low; + fileTime.dwHighDateTime = high; + } + switch(type) + { + case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; + case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; + case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; + } + } + return SZ_OK; +} +*/ + +static int TestSignatureCandidate(Byte *testBytes) +{ + size_t i; + for (i = 0; i < k7zSignatureSize; i++) + if (testBytes[i] != k7zSignature[i]) + return 0; + return 1; +} + +typedef struct _CSzState +{ + Byte *Data; + size_t Size; +}CSzData; + +static SRes SzReadByte(CSzData *sd, Byte *b) +{ + if (sd->Size == 0) + return SZ_ERROR_ARCHIVE; + sd->Size--; + *b = *sd->Data++; + return SZ_OK; +} + +static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) + { + RINOK(SzReadByte(sd, data + i)); + } + return SZ_OK; +} + +static SRes SzReadUInt32(CSzData *sd, UInt32 *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt32)(b) << (8 * i)); + } + return SZ_OK; +} + +static SRes SzReadNumber(CSzData *sd, UInt64 *value) +{ + Byte firstByte; + Byte mask = 0x80; + int i; + RINOK(SzReadByte(sd, &firstByte)); + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + if ((firstByte & mask) == 0) + { + UInt64 highPart = firstByte & (mask - 1); + *value += (highPart << (8 * i)); + return SZ_OK; + } + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt64)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + +static SRes SzReadNumber32(CSzData *sd, UInt32 *value) +{ + UInt64 value64; + RINOK(SzReadNumber(sd, &value64)); + if (value64 >= 0x80000000) + return SZ_ERROR_UNSUPPORTED; + if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) + return SZ_ERROR_UNSUPPORTED; + *value = (UInt32)value64; + return SZ_OK; +} + +static SRes SzReadID(CSzData *sd, UInt64 *value) +{ + return SzReadNumber(sd, value); +} + +static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) +{ + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + sd->Size -= (size_t)size; + sd->Data += (size_t)size; + return SZ_OK; +} + +static SRes SzSkeepData(CSzData *sd) +{ + UInt64 size; + RINOK(SzReadNumber(sd, &size)); + return SzSkeepDataSize(sd, size); +} + +static SRes SzReadArchiveProperties(CSzData *sd) +{ + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + SzSkeepData(sd); + } + return SZ_OK; +} + +static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) +{ + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == attribute) + return SZ_OK; + if (type == k7zIdEnd) + return SZ_ERROR_ARCHIVE; + RINOK(SzSkeepData(sd)); + } +} + +static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) +{ + Byte b = 0; + Byte mask = 0; + size_t i; + MY_ALLOC(Byte, *v, numItems, alloc); + for (i = 0; i < numItems; i++) + { + if (mask == 0) + { + RINOK(SzReadByte(sd, &b)); + mask = 0x80; + } + (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); + mask >>= 1; + } + return SZ_OK; +} + +static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) +{ + Byte allAreDefined; + size_t i; + RINOK(SzReadByte(sd, &allAreDefined)); + if (allAreDefined == 0) + return SzReadBoolVector(sd, numItems, v, alloc); + MY_ALLOC(Byte, *v, numItems, alloc); + for (i = 0; i < numItems; i++) + (*v)[i] = 1; + return SZ_OK; +} + +static SRes SzReadHashDigests( + CSzData *sd, + size_t numItems, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *alloc) +{ + size_t i; + RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); + MY_ALLOC(UInt32, *digests, numItems, alloc); + for (i = 0; i < numItems; i++) + if ((*digestsDefined)[i]) + { + RINOK(SzReadUInt32(sd, (*digests) + i)); + } + return SZ_OK; +} + +static SRes SzReadPackInfo( + CSzData *sd, + UInt64 *dataOffset, + UInt32 *numPackStreams, + UInt64 **packSizes, + Byte **packCRCsDefined, + UInt32 **packCRCs, + ISzAlloc *alloc) +{ + UInt32 i; + RINOK(SzReadNumber(sd, dataOffset)); + RINOK(SzReadNumber32(sd, numPackStreams)); + + RINOK(SzWaitAttribute(sd, k7zIdSize)); + + MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); + + for (i = 0; i < *numPackStreams; i++) + { + RINOK(SzReadNumber(sd, (*packSizes) + i)); + } + + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + if (type == k7zIdCRC) + { + RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); + continue; + } + RINOK(SzSkeepData(sd)); + } + if (*packCRCsDefined == 0) + { + MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); + MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); + for (i = 0; i < *numPackStreams; i++) + { + (*packCRCsDefined)[i] = 0; + (*packCRCs)[i] = 0; + } + } + return SZ_OK; +} + +static SRes SzReadSwitch(CSzData *sd) +{ + Byte external; + RINOK(SzReadByte(sd, &external)); + return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; +} + +static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) +{ + UInt32 numCoders, numBindPairs, numPackStreams, i; + UInt32 numInStreams = 0, numOutStreams = 0; + + RINOK(SzReadNumber32(sd, &numCoders)); + if (numCoders > NUM_FOLDER_CODERS_MAX) + return SZ_ERROR_UNSUPPORTED; + folder->NumCoders = numCoders; + + MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); + + for (i = 0; i < numCoders; i++) + SzCoderInfo_Init(folder->Coders + i); + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CSzCoderInfo *coder = folder->Coders + i; + { + unsigned idSize, j; + Byte longID[15]; + RINOK(SzReadByte(sd, &mainByte)); + idSize = (unsigned)(mainByte & 0xF); + RINOK(SzReadBytes(sd, longID, idSize)); + if (idSize > sizeof(coder->MethodID)) + return SZ_ERROR_UNSUPPORTED; + coder->MethodID = 0; + for (j = 0; j < idSize; j++) + coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); + + if ((mainByte & 0x10) != 0) + { + RINOK(SzReadNumber32(sd, &coder->NumInStreams)); + RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); + if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || + coder->NumOutStreams > NUM_CODER_STREAMS_MAX) + return SZ_ERROR_UNSUPPORTED; + } + else + { + coder->NumInStreams = 1; + coder->NumOutStreams = 1; + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) + return SZ_ERROR_MEM; + RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); + } + } + while ((mainByte & 0x80) != 0) + { + RINOK(SzReadByte(sd, &mainByte)); + RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); + if ((mainByte & 0x10) != 0) + { + UInt32 n; + RINOK(SzReadNumber32(sd, &n)); + RINOK(SzReadNumber32(sd, &n)); + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + RINOK(SzSkeepDataSize(sd, propertiesSize)); + } + } + numInStreams += coder->NumInStreams; + numOutStreams += coder->NumOutStreams; + } + + if (numOutStreams == 0) + return SZ_ERROR_UNSUPPORTED; + + folder->NumBindPairs = numBindPairs = numOutStreams - 1; + MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); + + for (i = 0; i < numBindPairs; i++) + { + CSzBindPair *bp = folder->BindPairs + i; + RINOK(SzReadNumber32(sd, &bp->InIndex)); + RINOK(SzReadNumber32(sd, &bp->OutIndex)); + } + + if (numInStreams < numBindPairs) + return SZ_ERROR_UNSUPPORTED; + + folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; + MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); + + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams ; i++) + if (SzFolder_FindBindPairForInStream(folder, i) < 0) + break; + if (i == numInStreams) + return SZ_ERROR_UNSUPPORTED; + folder->PackStreams[0] = i; + } + else + for (i = 0; i < numPackStreams; i++) + { + RINOK(SzReadNumber32(sd, folder->PackStreams + i)); + } + return SZ_OK; +} + +static SRes SzReadUnpackInfo( + CSzData *sd, + UInt32 *numFolders, + CSzFolder **folders, /* for alloc */ + ISzAlloc *alloc, + ISzAlloc *allocTemp) +{ + UInt32 i; + RINOK(SzWaitAttribute(sd, k7zIdFolder)); + RINOK(SzReadNumber32(sd, numFolders)); + { + RINOK(SzReadSwitch(sd)); + + MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); + + for (i = 0; i < *numFolders; i++) + SzFolder_Init((*folders) + i); + + for (i = 0; i < *numFolders; i++) + { + RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); + } + } + + RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); + + for (i = 0; i < *numFolders; i++) + { + UInt32 j; + CSzFolder *folder = (*folders) + i; + UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); + + MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); + + for (j = 0; j < numOutStreams; j++) + { + RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); + } + } + + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + SRes res; + Byte *crcsDefined = 0; + UInt32 *crcs = 0; + res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); + if (res == SZ_OK) + { + for (i = 0; i < *numFolders; i++) + { + CSzFolder *folder = (*folders) + i; + folder->UnpackCRCDefined = crcsDefined[i]; + folder->UnpackCRC = crcs[i]; + } + } + IAlloc_Free(allocTemp, crcs); + IAlloc_Free(allocTemp, crcsDefined); + RINOK(res); + continue; + } + RINOK(SzSkeepData(sd)); + } +} + +static SRes SzReadSubStreamsInfo( + CSzData *sd, + UInt32 numFolders, + CSzFolder *folders, + UInt32 *numUnpackStreams, + UInt64 **unpackSizes, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *allocTemp) +{ + UInt64 type = 0; + UInt32 i; + UInt32 si = 0; + UInt32 numDigests = 0; + + for (i = 0; i < numFolders; i++) + folders[i].NumUnpackStreams = 1; + *numUnpackStreams = numFolders; + + for (;;) + { + RINOK(SzReadID(sd, &type)); + if (type == k7zIdNumUnpackStream) + { + *numUnpackStreams = 0; + for (i = 0; i < numFolders; i++) + { + UInt32 numStreams; + RINOK(SzReadNumber32(sd, &numStreams)); + folders[i].NumUnpackStreams = numStreams; + *numUnpackStreams += numStreams; + } + continue; + } + if (type == k7zIdCRC || type == k7zIdSize) + break; + if (type == k7zIdEnd) + break; + RINOK(SzSkeepData(sd)); + } + + if (*numUnpackStreams == 0) + { + *unpackSizes = 0; + *digestsDefined = 0; + *digests = 0; + } + else + { + *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); + RINOM(*unpackSizes); + *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); + RINOM(*digestsDefined); + *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); + RINOM(*digests); + } + + for (i = 0; i < numFolders; i++) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: we check that folder is empty + */ + UInt64 sum = 0; + UInt32 j; + UInt32 numSubstreams = folders[i].NumUnpackStreams; + if (numSubstreams == 0) + continue; + if (type == k7zIdSize) + for (j = 1; j < numSubstreams; j++) + { + UInt64 size; + RINOK(SzReadNumber(sd, &size)); + (*unpackSizes)[si++] = size; + sum += size; + } + (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; + } + if (type == k7zIdSize) + { + RINOK(SzReadID(sd, &type)); + } + + for (i = 0; i < *numUnpackStreams; i++) + { + (*digestsDefined)[i] = 0; + (*digests)[i] = 0; + } + + + for (i = 0; i < numFolders; i++) + { + UInt32 numSubstreams = folders[i].NumUnpackStreams; + if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) + numDigests += numSubstreams; + } + + + si = 0; + for (;;) + { + if (type == k7zIdCRC) + { + int digestIndex = 0; + Byte *digestsDefined2 = 0; + UInt32 *digests2 = 0; + SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); + if (res == SZ_OK) + { + for (i = 0; i < numFolders; i++) + { + CSzFolder *folder = folders + i; + UInt32 numSubstreams = folder->NumUnpackStreams; + if (numSubstreams == 1 && folder->UnpackCRCDefined) + { + (*digestsDefined)[si] = 1; + (*digests)[si] = folder->UnpackCRC; + si++; + } + else + { + UInt32 j; + for (j = 0; j < numSubstreams; j++, digestIndex++) + { + (*digestsDefined)[si] = digestsDefined2[digestIndex]; + (*digests)[si] = digests2[digestIndex]; + si++; + } + } + } + } + IAlloc_Free(allocTemp, digestsDefined2); + IAlloc_Free(allocTemp, digests2); + RINOK(res); + } + else if (type == k7zIdEnd) + return SZ_OK; + else + { + RINOK(SzSkeepData(sd)); + } + RINOK(SzReadID(sd, &type)); + } +} + + +static SRes SzReadStreamsInfo( + CSzData *sd, + UInt64 *dataOffset, + CSzAr *p, + UInt32 *numUnpackStreams, + UInt64 **unpackSizes, /* allocTemp */ + Byte **digestsDefined, /* allocTemp */ + UInt32 **digests, /* allocTemp */ + ISzAlloc *alloc, + ISzAlloc *allocTemp) +{ + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if ((UInt64)(int)type != type) + return SZ_ERROR_UNSUPPORTED; + switch((int)type) + { + case k7zIdEnd: + return SZ_OK; + case k7zIdPackInfo: + { + RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, + &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); + break; + } + case k7zIdUnpackInfo: + { + RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); + break; + } + case k7zIdSubStreamsInfo: + { + RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, + numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); + break; + } + default: + return SZ_ERROR_UNSUPPORTED; + } + } +} + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) +{ + size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + if (dest != 0) + { + size_t i; + const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); + for (i = 0; i < len; i++) + dest[i] = GetUi16(src + i * 2); + } + return len; +} + +static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes) +{ + UInt32 i; + size_t pos = 0; + for (i = 0; i < numFiles; i++) + { + sizes[i] = pos; + for (;;) + { + if (pos >= size) + return SZ_ERROR_ARCHIVE; + if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) + break; + pos++; + } + pos++; + } + sizes[i] = pos; + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; +} + +static SRes SzReadHeader2( + CSzArEx *p, /* allocMain */ + CSzData *sd, + UInt64 **unpackSizes, /* allocTemp */ + Byte **digestsDefined, /* allocTemp */ + UInt32 **digests, /* allocTemp */ + Byte **emptyStreamVector, /* allocTemp */ + Byte **emptyFileVector, /* allocTemp */ + Byte **lwtVector, /* allocTemp */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt64 type; + UInt32 numUnpackStreams = 0; + UInt32 numFiles = 0; + CSzFileItem *files = 0; + UInt32 numEmptyStreams = 0; + UInt32 i; + + RINOK(SzReadID(sd, &type)); + + if (type == k7zIdArchiveProperties) + { + RINOK(SzReadArchiveProperties(sd)); + RINOK(SzReadID(sd, &type)); + } + + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(sd, + &p->dataPos, + &p->db, + &numUnpackStreams, + unpackSizes, + digestsDefined, + digests, allocMain, allocTemp)); + p->dataPos += p->startPosAfterHeader; + RINOK(SzReadID(sd, &type)); + } + + if (type == k7zIdEnd) + return SZ_OK; + if (type != k7zIdFilesInfo) + return SZ_ERROR_ARCHIVE; + + RINOK(SzReadNumber32(sd, &numFiles)); + p->db.NumFiles = numFiles; + + MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); + + p->db.Files = files; + for (i = 0; i < numFiles; i++) + SzFile_Init(files + i); + + for (;;) + { + UInt64 type; + UInt64 size; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(SzReadNumber(sd, &size)); + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + if ((UInt64)(int)type != type) + { + RINOK(SzSkeepDataSize(sd, size)); + } + else + switch((int)type) + { + case k7zIdName: + { + size_t namesSize; + RINOK(SzReadSwitch(sd)); + namesSize = (size_t)size - 1; + if ((namesSize & 1) != 0) + return SZ_ERROR_ARCHIVE; + if (!Buf_Create(&p->FileNames, namesSize, allocMain)) + return SZ_ERROR_MEM; + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); + memcpy(p->FileNames.data, sd->Data, namesSize); + RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) + RINOK(SzSkeepDataSize(sd, namesSize)); + break; + } + case k7zIdEmptyStream: + { + RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); + numEmptyStreams = 0; + for (i = 0; i < numFiles; i++) + if ((*emptyStreamVector)[i]) + numEmptyStreams++; + break; + } + case k7zIdEmptyFile: + { + RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); + break; + } + case k7zIdWinAttributes: + { + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); + RINOK(SzReadSwitch(sd)); + for (i = 0; i < numFiles; i++) + { + CSzFileItem *f = &files[i]; + Byte defined = (*lwtVector)[i]; + f->AttribDefined = defined; + f->Attrib = 0; + if (defined) + { + RINOK(SzReadUInt32(sd, &f->Attrib)); + } + } + IAlloc_Free(allocTemp, *lwtVector); + *lwtVector = NULL; + break; + } + case k7zIdMTime: + { + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); + RINOK(SzReadSwitch(sd)); + for (i = 0; i < numFiles; i++) + { + CSzFileItem *f = &files[i]; + Byte defined = (*lwtVector)[i]; + f->MTimeDefined = defined; + f->MTime.Low = f->MTime.High = 0; + if (defined) + { + RINOK(SzReadUInt32(sd, &f->MTime.Low)); + RINOK(SzReadUInt32(sd, &f->MTime.High)); + } + } + IAlloc_Free(allocTemp, *lwtVector); + *lwtVector = NULL; + break; + } + default: + { + RINOK(SzSkeepDataSize(sd, size)); + } + } + } + + { + UInt32 emptyFileIndex = 0; + UInt32 sizeIndex = 0; + for (i = 0; i < numFiles; i++) + { + CSzFileItem *file = files + i; + file->IsAnti = 0; + if (*emptyStreamVector == 0) + file->HasStream = 1; + else + file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); + if (file->HasStream) + { + file->IsDir = 0; + file->Size = (*unpackSizes)[sizeIndex]; + file->Crc = (*digests)[sizeIndex]; + file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex]; + sizeIndex++; + } + else + { + if (*emptyFileVector == 0) + file->IsDir = 1; + else + file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); + emptyFileIndex++; + file->Size = 0; + file->Crc = 0; + file->CrcDefined = 0; + } + } + } + return SzArEx_Fill(p, allocMain); +} + +static SRes SzReadHeader( + CSzArEx *p, + CSzData *sd, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt64 *unpackSizes = 0; + Byte *digestsDefined = 0; + UInt32 *digests = 0; + Byte *emptyStreamVector = 0; + Byte *emptyFileVector = 0; + Byte *lwtVector = 0; + SRes res = SzReadHeader2(p, sd, + &unpackSizes, &digestsDefined, &digests, + &emptyStreamVector, &emptyFileVector, &lwtVector, + allocMain, allocTemp); + IAlloc_Free(allocTemp, unpackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + IAlloc_Free(allocTemp, emptyStreamVector); + IAlloc_Free(allocTemp, emptyFileVector); + IAlloc_Free(allocTemp, lwtVector); + return res; +} + +static SRes SzReadAndDecodePackedStreams2( + ILookInStream *inStream, + CSzData *sd, + CBuf *outBuffer, + UInt64 baseOffset, + CSzAr *p, + UInt64 **unpackSizes, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *allocTemp) +{ + + UInt32 numUnpackStreams = 0; + UInt64 dataStartPos; + CSzFolder *folder; + UInt64 unpackSize; + SRes res; + + RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, + &numUnpackStreams, unpackSizes, digestsDefined, digests, + allocTemp, allocTemp)); + + dataStartPos += baseOffset; + if (p->NumFolders != 1) + return SZ_ERROR_ARCHIVE; + + folder = p->Folders; + unpackSize = SzFolder_GetUnpackSize(folder); + + RINOK(LookInStream_SeekTo(inStream, dataStartPos)); + + if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) + return SZ_ERROR_MEM; + + res = SzFolder_Decode(folder, p->PackSizes, + inStream, dataStartPos, + outBuffer->data, (size_t)unpackSize, allocTemp); + RINOK(res); + if (folder->UnpackCRCDefined) + if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) + return SZ_ERROR_CRC; + return SZ_OK; +} + +static SRes SzReadAndDecodePackedStreams( + ILookInStream *inStream, + CSzData *sd, + CBuf *outBuffer, + UInt64 baseOffset, + ISzAlloc *allocTemp) +{ + CSzAr p; + UInt64 *unpackSizes = 0; + Byte *digestsDefined = 0; + UInt32 *digests = 0; + SRes res; + SzAr_Init(&p); + res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, + &p, &unpackSizes, &digestsDefined, &digests, + allocTemp); + SzAr_Free(&p, allocTemp); + IAlloc_Free(allocTemp, unpackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + return res; +} + +static SRes SzArEx_Open2( + CSzArEx *p, + ILookInStream *inStream, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + Byte header[k7zStartHeaderSize]; + Int64 startArcPos; + UInt64 nextHeaderOffset, nextHeaderSize; + size_t nextHeaderSizeT; + UInt32 nextHeaderCRC; + CBuf buffer; + SRes res; + + startArcPos = 0; + RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); + + if (!TestSignatureCandidate(header)) + return SZ_ERROR_NO_ARCHIVE; + if (header[6] != k7zMajorVersion) + return SZ_ERROR_UNSUPPORTED; + + nextHeaderOffset = GetUi64(header + 12); + nextHeaderSize = GetUi64(header + 20); + nextHeaderCRC = GetUi32(header + 28); + + p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; + + if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) + return SZ_ERROR_CRC; + + nextHeaderSizeT = (size_t)nextHeaderSize; + if (nextHeaderSizeT != nextHeaderSize) + return SZ_ERROR_MEM; + if (nextHeaderSizeT == 0) + return SZ_OK; + if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || + nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) + return SZ_ERROR_NO_ARCHIVE; + + { + Int64 pos = 0; + RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); + if ((UInt64)pos < startArcPos + nextHeaderOffset || + (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || + (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + return SZ_ERROR_INPUT_EOF; + } + + RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); + + if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) + return SZ_ERROR_MEM; + + res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); + if (res == SZ_OK) + { + res = SZ_ERROR_ARCHIVE; + if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) + { + CSzData sd; + UInt64 type; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + if (res == SZ_OK) + { + if (type == k7zIdEncodedHeader) + { + CBuf outBuffer; + Buf_Init(&outBuffer); + res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); + if (res != SZ_OK) + Buf_Free(&outBuffer, allocTemp); + else + { + Buf_Free(&buffer, allocTemp); + buffer.data = outBuffer.data; + buffer.size = outBuffer.size; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + } + } + } + if (res == SZ_OK) + { + if (type == k7zIdHeader) + res = SzReadHeader(p, &sd, allocMain, allocTemp); + else + res = SZ_ERROR_UNSUPPORTED; + } + } + } + Buf_Free(&buffer, allocTemp); + return res; +} + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) +{ + SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + if (res != SZ_OK) + SzArEx_Free(p, allocMain); + return res; +} + +SRes SzArEx_Extract( + const CSzArEx *p, + ILookInStream *inStream, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; + SRes res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (UInt32)-1) + { + IAlloc_Free(allocMain, *outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CSzFolder *folder = p->db.Folders + folderIndex; + UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); + size_t unpackSize = (size_t)unpackSizeSpec; + UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); + + if (unpackSize != unpackSizeSpec) + return SZ_ERROR_MEM; + *blockIndex = folderIndex; + IAlloc_Free(allocMain, *outBuffer); + *outBuffer = 0; + + RINOK(LookInStream_SeekTo(inStream, startOffset)); + + if (res == SZ_OK) + { + *outBufferSize = unpackSize; + if (unpackSize != 0) + { + *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); + if (*outBuffer == 0) + res = SZ_ERROR_MEM; + } + if (res == SZ_OK) + { + res = SzFolder_Decode(folder, + p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], + inStream, startOffset, + *outBuffer, unpackSize, allocTemp); + if (res == SZ_OK) + { + if (folder->UnpackCRCDefined) + { + if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) + res = SZ_ERROR_CRC; + } + } + } + } + } + if (res == SZ_OK) + { + UInt32 i; + CSzFileItem *fileItem = p->db.Files + fileIndex; + *offset = 0; + for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)p->db.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZ_ERROR_FAIL; + if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) + res = SZ_ERROR_CRC; + } + return res; +} diff --git a/References/VirtuaNESex_src_191105/7z/7zMain.c b/References/VirtuaNESex_src_191105/7z/7zMain.c new file mode 100644 index 00000000..784ae030 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zMain.c @@ -0,0 +1,438 @@ +/* 7zMain.c - Test application for 7z Decoder +2010-10-28 : Igor Pavlov : Public domain */ + +#include +#include + +#include "7z/7z.h" +#include "7z/7zAlloc.h" +#include "7z/7zCrc.h" +#include "7z/7zFile.h" +#include "7z/7zVersion.h" + +/* +#ifndef UNICODE +#define UNICODE +#endif +*/ +#ifndef USE_WINDOWS_FILE +/* for mkdir */ +#ifdef _WIN32 +#include +#else +#include +#include +#endif +#endif + +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static int Buf_EnsureSize(CBuf *dest, size_t size) +{ + if (dest->size >= size) + return 1; + Buf_Free(dest, &g_Alloc); + return Buf_Create(dest, size, &g_Alloc); +} + +#ifndef _WIN32 + +static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen) +{ + size_t destPos = 0, srcPos = 0; + for (;;) + { + unsigned numAdds; + UInt32 value; + if (srcPos == srcLen) + { + *destLen = destPos; + return True; + } + value = src[srcPos++]; + if (value < 0x80) + { + if (dest) + dest[destPos] = (char)value; + destPos++; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00 || srcPos == srcLen) + break; + c2 = src[srcPos++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + break; + value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + if (dest) + dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + destPos++; + do + { + numAdds--; + if (dest) + dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + destPos++; + } + while (numAdds != 0); + } + *destLen = destPos; + return False; +} + +static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen) +{ + size_t destLen = 0; + Bool res; + Utf16_To_Utf8(NULL, &destLen, src, srcLen); + destLen += 1; + if (!Buf_EnsureSize(dest, destLen)) + return SZ_ERROR_MEM; + res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen); + dest->data[destLen] = 0; + return res ? SZ_OK : SZ_ERROR_FAIL; +} +#endif + +static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode) +{ + int len = 0; + for (len = 0; s[len] != '\0'; len++); + + #ifdef _WIN32 + { + int size = len * 3 + 100; + if (!Buf_EnsureSize(buf, size)) + return SZ_ERROR_MEM; + { + char defaultChar = '_'; + BOOL defUsed; + int numChars = WideCharToMultiByte(fileMode ? + ( + #ifdef UNDER_CE + CP_ACP + #else + AreFileApisANSI() ? CP_ACP : CP_OEMCP + #endif + ) : CP_OEMCP, + 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed); + if (numChars == 0 || numChars >= size) + return SZ_ERROR_FAIL; + buf->data[numChars] = 0; + return SZ_OK; + } + } + #else + fileMode = fileMode; + return Utf16_To_Utf8Buf(buf, s, len); + #endif +} + +static WRes MyCreateDir(const UInt16 *name) +{ + #ifdef USE_WINDOWS_FILE + + return CreateDirectoryW(name, NULL) ? 0 : GetLastError(); + + #else + + CBuf buf; + WRes res; + Buf_Init(&buf); + RINOK(Utf16_To_Char(&buf, name, 1)); + + res = + #ifdef _WIN32 + _mkdir((const char *)buf.data) + #else + mkdir((const char *)buf.data, 0777) + #endif + == 0 ? 0 : errno; + Buf_Free(&buf, &g_Alloc); + return res; + + #endif +} + +static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name) +{ + #ifdef USE_WINDOWS_FILE + return OutFile_OpenW(p, name); + #else + CBuf buf; + WRes res; + Buf_Init(&buf); + RINOK(Utf16_To_Char(&buf, name, 1)); + res = OutFile_Open(p, (const char *)buf.data); + Buf_Free(&buf, &g_Alloc); + return res; + #endif +} + +static SRes PrintString(const UInt16 *s) +{ + CBuf buf; + SRes res; + Buf_Init(&buf); + res = Utf16_To_Char(&buf, s, 0); + if (res == SZ_OK) + fputs((const char *)buf.data, stdout); + Buf_Free(&buf, &g_Alloc); + return res; +} + +static void UInt64ToStr(UInt64 value, char *s) +{ + char temp[32]; + int pos = 0; + do + { + temp[pos++] = (char)('0' + (unsigned)(value % 10)); + value /= 10; + } + while (value != 0); + do + *s++ = temp[--pos]; + while (pos); + *s = '\0'; +} + +static char *UIntToStr(char *s, unsigned value, int numDigits) +{ + char temp[16]; + int pos = 0; + do + temp[pos++] = (char)('0' + (value % 10)); + while (value /= 10); + for (numDigits -= pos; numDigits > 0; numDigits--) + *s++ = '0'; + do + *s++ = temp[--pos]; + while (pos); + *s = '\0'; + return s; +} + +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) + +static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s) +{ + unsigned year, mon, day, hour, min, sec; + UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000; + Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + unsigned t; + UInt32 v; + sec = (unsigned)(v64 % 60); v64 /= 60; + min = (unsigned)(v64 % 60); v64 /= 60; + hour = (unsigned)(v64 % 24); v64 /= 24; + + v = (UInt32)v64; + + year = (unsigned)(1601 + v / PERIOD_400 * 400); + v %= PERIOD_400; + + t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100; + t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4; + t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + for (mon = 1; mon <= 12; mon++) + { + unsigned s = ms[mon - 1]; + if (v < s) + break; + v -= s; + } + day = (unsigned)v + 1; + s = UIntToStr(s, year, 4); *s++ = '-'; + s = UIntToStr(s, mon, 2); *s++ = '-'; + s = UIntToStr(s, day, 2); *s++ = ' '; + s = UIntToStr(s, hour, 2); *s++ = ':'; + s = UIntToStr(s, min, 2); *s++ = ':'; + s = UIntToStr(s, sec, 2); +} + +void PrintError(char *sz) +{ + printf("\nERROR: %s\n", sz); +} + +#ifdef USE_WINDOWS_FILE +#define kEmptyAttribChar '.' +static void GetAttribString(UInt32 wa, Bool isDir, char *s) +{ + s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar); + s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar); + s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar); + s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar); + s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar); + s[5] = '\0'; +} +#else +static void GetAttribString(UInt32, Bool, char *s) +{ + s[0] = '\0'; +} +#endif + +int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize) +{ + CFileInStream archiveStream; + CLookToRead lookStream; + CSzArEx db; + SRes res; + ISzAlloc allocImp; + ISzAlloc allocTempImp; + UInt16 *temp = NULL; + size_t tempSize = 0; + + int bHasRomFile = 0; + int bExtractRomOK = 0; + //öļҵNESUNFļҲֱӷ + allocImp.Alloc = SzAlloc; + allocImp.Free = SzFree; + + allocTempImp.Alloc = SzAllocTemp; + allocTempImp.Free = SzFreeTemp; + + if (InFile_Open(&archiveStream.file, fname)) + { + return FALSE; + } + + FileInStream_CreateVTable(&archiveStream); + LookToRead_CreateVTable(&lookStream, False); + + lookStream.realStream = &archiveStream.s; + LookToRead_Init(&lookStream); + + CrcGenerateTable(); + + SzArEx_Init(&db); + res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); + if (res == SZ_OK) + { + UInt32 i; + + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ + Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ + + for (i = 0; i < db.db.NumFiles; i++) + { + size_t offset = 0; + size_t outSizeProcessed = 0; + const CSzFileItem *f = db.db.Files + i; + size_t len; + + len = SzArEx_GetFileNameUtf16(&db, i, NULL); + + if (len > tempSize) + { + SzFree(NULL, temp); + tempSize = len; + temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); + if (temp == 0) + { + res = SZ_ERROR_MEM; + break; + } + } + + SzArEx_GetFileNameUtf16(&db, i, temp); + //ȡļϢ + { + char attr[8]; + GetAttribString(f->AttribDefined ? f->Attrib : 0, f->IsDir, attr);// f->IsDir ļǷĿ¼ + + //UInt64ToStr(f->Size, s);//f->Size ļС + if(f->IsDir!=1) + { + //չ + if(len>5) + { + //"*.nes", + //"*.unf", + //"*.fds", + //"*.nsf", + if(wcsicmp(L".nes",&temp[len-5])==0) + { + bHasRomFile =1; + } + else if(wcsicmp(L".unf",&temp[len-5])==0) + { + bHasRomFile =1; + } + else if(wcsicmp(L".fds",&temp[len-5])==0) + { + bHasRomFile =1; + } + else if(wcsicmp(L".nsf",&temp[len-5])==0) + { + bHasRomFile =1; + } + } + //if( (f->Size>16000)&&(f->Size<10000000) ) + //bHasRomFile =1; + } + + if(bHasRomFile==0) + continue; + } + + if (bHasRomFile) + { + res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex, ppBuf, lpdwSize,&offset, &outSizeProcessed,&allocImp, &allocTempImp); + if (res != SZ_OK) + continue; + else + { + bExtractRomOK = 1; + if(offset!=0) + {// + void *pRom = malloc(f->Size); + memcpy(pRom,*ppBuf+offset,f->Size); + *lpdwSize = f->Size; + free(*ppBuf); + *ppBuf = pRom; + } + } + } + if(bExtractRomOK) + break; + }//ļöѭ + IAlloc_Free(&allocImp, outBuffer); + } + SzArEx_Free(&db, &allocImp); + SzFree(NULL, temp); + + File_Close(&archiveStream.file); + /*if (res == SZ_OK) + { + printf("\nEverything is Ok\n"); + return 0; + }*/ + return bExtractRomOK; +} + +/* + +int MY_CDECL main(int c, char *v[]) +{ + unsigned char *pBuf = 0; + size_t fileLen; + int i = SevenZipUnCompress(v[1],&pBuf,&fileLen); + free(pBuf); pBuf = 0; + printf("%d",i); +} +*/ \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/7z/7zStream.c b/References/VirtuaNESex_src_191105/7z/7zStream.c new file mode 100644 index 00000000..0ebb7b5f --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zStream.c @@ -0,0 +1,169 @@ +/* 7zStream.c -- 7z Stream functions +2010-03-11 : Igor Pavlov : Public domain */ + +#include + +#include "Types.h" + +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(stream->Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) +{ + return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) +{ + size_t processed = 1; + RINOK(stream->Read(stream, buf, &processed)); + return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; +} + +SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) +{ + Int64 t = offset; + return stream->Seek(stream, &t, SZ_SEEK_SET); +} + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) +{ + const void *lookBuf; + if (*size == 0) + return SZ_OK; + RINOK(stream->Look(stream, &lookBuf, size)); + memcpy(buf, lookBuf, *size); + return stream->Skip(stream, *size); +} + +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(stream->Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) +{ + return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + CLookToRead *p = (CLookToRead *)pp; + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size > 0) + { + p->pos = 0; + size2 = LookToRead_BUF_SIZE; + res = p->realStream->Read(p->realStream, p->buf, &size2); + p->size = size2; + } + if (size2 < *size) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + CLookToRead *p = (CLookToRead *)pp; + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size > 0) + { + p->pos = 0; + if (*size > LookToRead_BUF_SIZE) + *size = LookToRead_BUF_SIZE; + res = p->realStream->Read(p->realStream, p->buf, size); + size2 = p->size = *size; + } + if (size2 < *size) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead_Skip(void *pp, size_t offset) +{ + CLookToRead *p = (CLookToRead *)pp; + p->pos += offset; + return SZ_OK; +} + +static SRes LookToRead_Read(void *pp, void *buf, size_t *size) +{ + CLookToRead *p = (CLookToRead *)pp; + size_t rem = p->size - p->pos; + if (rem == 0) + return p->realStream->Read(p->realStream, buf, size); + if (rem > *size) + rem = *size; + memcpy(buf, p->buf + p->pos, rem); + p->pos += rem; + *size = rem; + return SZ_OK; +} + +static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) +{ + CLookToRead *p = (CLookToRead *)pp; + p->pos = p->size = 0; + return p->realStream->Seek(p->realStream, pos, origin); +} + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead) +{ + p->s.Look = lookahead ? + LookToRead_Look_Lookahead : + LookToRead_Look_Exact; + p->s.Skip = LookToRead_Skip; + p->s.Read = LookToRead_Read; + p->s.Seek = LookToRead_Seek; +} + +void LookToRead_Init(CLookToRead *p) +{ + p->pos = p->size = 0; +} + +static SRes SecToLook_Read(void *pp, void *buf, size_t *size) +{ + CSecToLook *p = (CSecToLook *)pp; + return LookInStream_LookRead(p->realStream, buf, size); +} + +void SecToLook_CreateVTable(CSecToLook *p) +{ + p->s.Read = SecToLook_Read; +} + +static SRes SecToRead_Read(void *pp, void *buf, size_t *size) +{ + CSecToRead *p = (CSecToRead *)pp; + return p->realStream->Read(p->realStream, buf, size); +} + +void SecToRead_CreateVTable(CSecToRead *p) +{ + p->s.Read = SecToRead_Read; +} diff --git a/References/VirtuaNESex_src_191105/7z/7zVersion.h b/References/VirtuaNESex_src_191105/7z/7zVersion.h new file mode 100644 index 00000000..9d99c5df --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/7zVersion.h @@ -0,0 +1,7 @@ +#define MY_VER_MAJOR 9 +#define MY_VER_MINOR 20 +#define MY_VER_BUILD 0 +#define MY_VERSION "9.20" +#define MY_DATE "2010-11-18" +#define MY_COPYRIGHT ": Igor Pavlov : Public domain" +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE diff --git a/References/VirtuaNESex_src_191105/7z/Bcj2.c b/References/VirtuaNESex_src_191105/7z/Bcj2.c new file mode 100644 index 00000000..20199ce5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Bcj2.c @@ -0,0 +1,132 @@ +/* Bcj2.c -- Converter for x86 code (BCJ2) +2008-10-04 : Igor Pavlov : Public domain */ + +#include "Bcj2.h" + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) +#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*buffer++) +#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } +#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ + { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} + +#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } + +#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; + +int Bcj2_Decode( + const Byte *buf0, SizeT size0, + const Byte *buf1, SizeT size1, + const Byte *buf2, SizeT size2, + const Byte *buf3, SizeT size3, + Byte *outBuf, SizeT outSize) +{ + CProb p[256 + 2]; + SizeT inPos = 0, outPos = 0; + + const Byte *buffer, *bufferLim; + UInt32 range, code; + Byte prevByte = 0; + + unsigned int i; + for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) + p[i] = kBitModelTotal >> 1; + + buffer = buf3; + bufferLim = buffer + size3; + RC_INIT2 + + if (outSize == 0) + return SZ_OK; + + for (;;) + { + Byte b; + CProb *prob; + UInt32 bound; + UInt32 ttt; + + SizeT limit = size0 - inPos; + if (outSize - outPos < limit) + limit = outSize - outPos; + while (limit != 0) + { + Byte b = buf0[inPos]; + outBuf[outPos++] = b; + if (IsJ(prevByte, b)) + break; + inPos++; + prevByte = b; + limit--; + } + + if (limit == 0 || outPos == outSize) + break; + + b = buf0[inPos++]; + + if (b == 0xE8) + prob = p + prevByte; + else if (b == 0xE9) + prob = p + 256; + else + prob = p + 257; + + IF_BIT_0(prob) + { + UPDATE_0(prob) + prevByte = b; + } + else + { + UInt32 dest; + const Byte *v; + UPDATE_1(prob) + if (b == 0xE8) + { + v = buf1; + if (size1 < 4) + return SZ_ERROR_DATA; + buf1 += 4; + size1 -= 4; + } + else + { + v = buf2; + if (size2 < 4) + return SZ_ERROR_DATA; + buf2 += 4; + size2 -= 4; + } + dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | + ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); + outBuf[outPos++] = (Byte)dest; + if (outPos == outSize) + break; + outBuf[outPos++] = (Byte)(dest >> 8); + if (outPos == outSize) + break; + outBuf[outPos++] = (Byte)(dest >> 16); + if (outPos == outSize) + break; + outBuf[outPos++] = prevByte = (Byte)(dest >> 24); + } + } + return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; +} diff --git a/References/VirtuaNESex_src_191105/7z/Bcj2.h b/References/VirtuaNESex_src_191105/7z/Bcj2.h new file mode 100644 index 00000000..dbc05414 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Bcj2.h @@ -0,0 +1,38 @@ +/* Bcj2.h -- Converter for x86 code (BCJ2) +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __BCJ2_H +#define __BCJ2_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Conditions: + outSize <= FullOutputSize, + where FullOutputSize is full size of output stream of x86_2 filter. + +If buf0 overlaps outBuf, there are two required conditions: + 1) (buf0 >= outBuf) + 2) (buf0 + size0 >= outBuf + FullOutputSize). + +Returns: + SZ_OK + SZ_ERROR_DATA - Data error +*/ + +int Bcj2_Decode( + const Byte *buf0, SizeT size0, + const Byte *buf1, SizeT size1, + const Byte *buf2, SizeT size2, + const Byte *buf3, SizeT size3, + Byte *outBuf, SizeT outSize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/Bra.c b/References/VirtuaNESex_src_191105/7z/Bra.c new file mode 100644 index 00000000..2e47b141 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Bra.c @@ -0,0 +1,133 @@ +/* Bra.c -- Converters for RISC code +2010-04-16 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 8; + for (i = 0; i <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + UInt32 dest; + UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 2; + data[i + 2] = (Byte)(dest >> 16); + data[i + 1] = (Byte)(dest >> 8); + data[i + 0] = (Byte)dest; + } + } + return i; +} + +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 4; + for (i = 0; i <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + UInt32 dest; + UInt32 src = + (((UInt32)data[i + 1] & 0x7) << 19) | + ((UInt32)data[i + 0] << 11) | + (((UInt32)data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 1; + + data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); + data[i + 0] = (Byte)(dest >> 11); + data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); + data[i + 2] = (Byte)dest; + i += 2; + } + } + return i; +} + +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) + { + UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3] & (~3)); + + UInt32 dest; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} + +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + UInt32 i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || + (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) + { + UInt32 src = + ((UInt32)data[i + 0] << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3]); + UInt32 dest; + + src <<= 2; + if (encoding) + dest = ip + i + src; + else + dest = src - (ip + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (Byte)(dest >> 24); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] = (Byte)dest; + } + } + return i; +} diff --git a/References/VirtuaNESex_src_191105/7z/Bra.h b/References/VirtuaNESex_src_191105/7z/Bra.h new file mode 100644 index 00000000..5748c1c0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Bra.h @@ -0,0 +1,68 @@ +/* Bra.h -- Branch converters for executables +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __BRA_H +#define __BRA_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +These functions convert relative addresses to absolute addresses +in CALL instructions to increase the compression ratio. + + In: + data - data buffer + size - size of data + ip - current virtual Instruction Pinter (IP) value + state - state variable for x86 converter + encoding - 0 (for decoding), 1 (for encoding) + + Out: + state - state variable for x86 converter + + Returns: + The number of processed bytes. If you call these functions with multiple calls, + you must start next call with first byte after block of processed bytes. + + Type Endian Alignment LookAhead + + x86 little 1 4 + ARMT little 2 2 + ARM little 4 0 + PPC big 4 0 + SPARC big 4 0 + IA64 little 16 0 + + size must be >= Alignment + LookAhead, if it's not last block. + If (size < Alignment + LookAhead), converter returns 0. + + Example: + + UInt32 ip = 0; + for () + { + ; size must be >= Alignment + LookAhead, if it's not last block + SizeT processed = Convert(data, size, ip, 1); + data += processed; + size -= processed; + ip += processed; + } +*/ + +#define x86_Convert_Init(state) { state = 0; } +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/Bra86.c b/References/VirtuaNESex_src_191105/7z/Bra86.c new file mode 100644 index 00000000..1ee0e709 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Bra86.c @@ -0,0 +1,85 @@ +/* Bra86.c -- Converter for x86 code (BCJ) +2008-10-04 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) + +const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +{ + SizeT bufferPos = 0, prevPosT; + UInt32 prevMask = *state & 0x7; + if (size < 5) + return 0; + ip += 5; + prevPosT = (SizeT)0 - 1; + + for (;;) + { + Byte *p = data + bufferPos; + Byte *limit = data + size - 4; + for (; p < limit; p++) + if ((*p & 0xFE) == 0xE8) + break; + bufferPos = (SizeT)(p - data); + if (p >= limit) + break; + prevPosT = bufferPos - prevPosT; + if (prevPosT > 3) + prevMask = 0; + else + { + prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; + if (prevMask != 0) + { + Byte b = p[4 - kMaskToBitNumber[prevMask]]; + if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) + { + prevPosT = bufferPos; + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + continue; + } + } + } + prevPosT = bufferPos; + + if (Test86MSByte(p[4])) + { + UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); + UInt32 dest; + for (;;) + { + Byte b; + int index; + if (encoding) + dest = (ip + (UInt32)bufferPos) + src; + else + dest = src - (ip + (UInt32)bufferPos); + if (prevMask == 0) + break; + index = kMaskToBitNumber[prevMask] * 8; + b = (Byte)(dest >> (24 - index)); + if (!Test86MSByte(b)) + break; + src = dest ^ ((1 << (32 - index)) - 1); + } + p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); + p[3] = (Byte)(dest >> 16); + p[2] = (Byte)(dest >> 8); + p[1] = (Byte)dest; + bufferPos += 5; + } + else + { + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + } + } + prevPosT = bufferPos - prevPosT; + *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); + return bufferPos; +} diff --git a/References/VirtuaNESex_src_191105/7z/CpuArch.c b/References/VirtuaNESex_src_191105/7z/CpuArch.c new file mode 100644 index 00000000..260cc1f4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/CpuArch.c @@ -0,0 +1,168 @@ +/* CpuArch.c -- CPU specific code +2010-10-26: Igor Pavlov : Public domain */ + +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + +#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) +#define USE_ASM +#endif + +#if defined(USE_ASM) && !defined(MY_CPU_AMD64) +static UInt32 CheckFlag(UInt32 flag) +{ + #ifdef _MSC_VER + __asm pushfd; + __asm pop EAX; + __asm mov EDX, EAX; + __asm xor EAX, flag; + __asm push EAX; + __asm popfd; + __asm pushfd; + __asm pop EAX; + __asm xor EAX, EDX; + __asm push EDX; + __asm popfd; + __asm and flag, EAX; + #else + __asm__ __volatile__ ( + "pushf\n\t" + "pop %%EAX\n\t" + "movl %%EAX,%%EDX\n\t" + "xorl %0,%%EAX\n\t" + "push %%EAX\n\t" + "popf\n\t" + "pushf\n\t" + "pop %%EAX\n\t" + "xorl %%EDX,%%EAX\n\t" + "push %%EDX\n\t" + "popf\n\t" + "andl %%EAX, %0\n\t": + "=c" (flag) : "c" (flag)); + #endif + return flag; +} +#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; +#else +#define CHECK_CPUID_IS_SUPPORTED +#endif + +static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) +{ + #ifdef USE_ASM + + #ifdef _MSC_VER + + UInt32 a2, b2, c2, d2; + __asm xor EBX, EBX; + __asm xor ECX, ECX; + __asm xor EDX, EDX; + __asm mov EAX, function; + __asm cpuid; + __asm mov a2, EAX; + __asm mov b2, EBX; + __asm mov c2, ECX; + __asm mov d2, EDX; + + *a = a2; + *b = b2; + *c = c2; + *d = d2; + + #else + + __asm__ __volatile__ ( + "cpuid" + : "=a" (*a) , + "=b" (*b) , + "=c" (*c) , + "=d" (*d) + : "0" (function)) ; + + #endif + + #else + + int CPUInfo[4]; + __cpuid(CPUInfo, function); + *a = CPUInfo[0]; + *b = CPUInfo[1]; + *c = CPUInfo[2]; + *d = CPUInfo[3]; + + #endif +} + +Bool x86cpuid_CheckAndRead(Cx86cpuid *p) +{ + CHECK_CPUID_IS_SUPPORTED + MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); + MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); + return True; +} + +static UInt32 kVendors[][3] = +{ + { 0x756E6547, 0x49656E69, 0x6C65746E}, + { 0x68747541, 0x69746E65, 0x444D4163}, + { 0x746E6543, 0x48727561, 0x736C7561} +}; + +int x86cpuid_GetFirm(const Cx86cpuid *p) +{ + unsigned i; + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) + { + const UInt32 *v = kVendors[i]; + if (v[0] == p->vendor[0] && + v[1] == p->vendor[1] && + v[2] == p->vendor[2]) + return (int)i; + } + return -1; +} + +Bool CPU_Is_InOrder() +{ + Cx86cpuid p; + int firm; + UInt32 family, model; + if (!x86cpuid_CheckAndRead(&p)) + return True; + family = x86cpuid_GetFamily(&p); + model = x86cpuid_GetModel(&p); + firm = x86cpuid_GetFirm(&p); + switch (firm) + { + case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C)); + case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); + case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); + } + return True; +} + +#if !defined(MY_CPU_AMD64) && defined(_WIN32) +static Bool CPU_Sys_Is_SSE_Supported() +{ + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionEx(&vi)) + return False; + return (vi.dwMajorVersion >= 5); +} +#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; +#else +#define CHECK_SYS_SSE_SUPPORT +#endif + +Bool CPU_Is_Aes_Supported() +{ + Cx86cpuid p; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_CheckAndRead(&p)) + return False; + return (p.c >> 25) & 1; +} + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/CpuArch.h b/References/VirtuaNESex_src_191105/7z/CpuArch.h new file mode 100644 index 00000000..01930c7e --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/CpuArch.h @@ -0,0 +1,155 @@ +/* CpuArch.h -- CPU specific code +2010-10-26: Igor Pavlov : Public domain */ + +#ifndef __CPU_ARCH_H +#define __CPU_ARCH_H + +#include "Types.h" + +EXTERN_C_BEGIN + +/* +MY_CPU_LE means that CPU is LITTLE ENDIAN. +If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). + +MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. +If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. +*/ + +#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) +#define MY_CPU_AMD64 +#endif + +#if defined(MY_CPU_AMD64) || defined(_M_IA64) +#define MY_CPU_64BIT +#endif + +#if defined(_M_IX86) || defined(__i386__) +#define MY_CPU_X86 +#endif + +#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) +#define MY_CPU_X86_OR_AMD64 +#endif + +#if defined(MY_CPU_X86) || defined(_M_ARM) +#define MY_CPU_32BIT +#endif + +#if defined(_WIN32) && defined(_M_ARM) +#define MY_CPU_ARM_LE +#endif + +#if defined(_WIN32) && defined(_M_IA64) +#define MY_CPU_IA64_LE +#endif + +#if defined(MY_CPU_X86_OR_AMD64) +#define MY_CPU_LE_UNALIGN +#endif + +#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) +#define MY_CPU_LE +#endif + +#if defined(__BIG_ENDIAN__) +#define MY_CPU_BE +#endif + +#if defined(MY_CPU_LE) && defined(MY_CPU_BE) +Stop_Compiling_Bad_Endian +#endif + +#ifdef MY_CPU_LE_UNALIGN + +#define GetUi16(p) (*(const UInt16 *)(p)) +#define GetUi32(p) (*(const UInt32 *)(p)) +#define GetUi64(p) (*(const UInt64 *)(p)) +#define SetUi16(p, d) *(UInt16 *)(p) = (d); +#define SetUi32(p, d) *(UInt32 *)(p) = (d); +#define SetUi64(p, d) *(UInt64 *)(p) = (d); + +#else + +#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) + +#define GetUi32(p) ( \ + ((const Byte *)(p))[0] | \ + ((UInt32)((const Byte *)(p))[1] << 8) | \ + ((UInt32)((const Byte *)(p))[2] << 16) | \ + ((UInt32)((const Byte *)(p))[3] << 24)) + +#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) + +#define SetUi16(p, d) { UInt32 _x_ = (d); \ + ((Byte *)(p))[0] = (Byte)_x_; \ + ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } + +#define SetUi32(p, d) { UInt32 _x_ = (d); \ + ((Byte *)(p))[0] = (Byte)_x_; \ + ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ + ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ + ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } + +#define SetUi64(p, d) { UInt64 _x64_ = (d); \ + SetUi32(p, (UInt32)_x64_); \ + SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } + +#endif + +#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) + +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) +#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) +#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) + +#else + +#define GetBe32(p) ( \ + ((UInt32)((const Byte *)(p))[0] << 24) | \ + ((UInt32)((const Byte *)(p))[1] << 16) | \ + ((UInt32)((const Byte *)(p))[2] << 8) | \ + ((const Byte *)(p))[3] ) + +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) + +#endif + +#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) + + +#ifdef MY_CPU_X86_OR_AMD64 + +typedef struct +{ + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA +}; + +Bool x86cpuid_CheckAndRead(Cx86cpuid *p); +int x86cpuid_GetFirm(const Cx86cpuid *p); + +#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) +#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) +#define x86cpuid_GetStepping(p) ((p)->ver & 0xF) + +Bool CPU_Is_InOrder(); +Bool CPU_Is_Aes_Supported(); + +#endif + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/Lzma2Dec.c b/References/VirtuaNESex_src_191105/7z/Lzma2Dec.c new file mode 100644 index 00000000..7ea1cc95 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Lzma2Dec.c @@ -0,0 +1,356 @@ +/* Lzma2Dec.c -- LZMA2 Decoder +2009-05-03 : Igor Pavlov : Public domain */ + +/* #define SHOW_DEBUG_INFO */ + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include + +#include "Lzma2Dec.h" + +/* +00000000 - EOS +00000001 U U - Uncompressed Reset Dic +00000010 U U - Uncompressed No Reset +100uuuuu U U P P - LZMA no reset +101uuuuu U U P P - LZMA reset state +110uuuuu U U P P S - LZMA reset state + new prop +111uuuuu U U P P S - LZMA reset state + new prop + reset dic + + u, U - Unpack Size + P - Pack Size + S - Props +*/ + +#define LZMA2_CONTROL_LZMA (1 << 7) +#define LZMA2_CONTROL_COPY_NO_RESET 2 +#define LZMA2_CONTROL_COPY_RESET_DIC 1 +#define LZMA2_CONTROL_EOF 0 + +#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) + +#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) +#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) + +#define LZMA2_LCLP_MAX 4 +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +typedef enum +{ + LZMA2_STATE_CONTROL, + LZMA2_STATE_UNPACK0, + LZMA2_STATE_UNPACK1, + LZMA2_STATE_PACK0, + LZMA2_STATE_PACK1, + LZMA2_STATE_PROP, + LZMA2_STATE_DATA, + LZMA2_STATE_DATA_CONT, + LZMA2_STATE_FINISHED, + LZMA2_STATE_ERROR +} ELzma2State; + +static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) +{ + UInt32 dicSize; + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); + props[0] = (Byte)LZMA2_LCLP_MAX; + props[1] = (Byte)(dicSize); + props[2] = (Byte)(dicSize >> 8); + props[3] = (Byte)(dicSize >> 16); + props[4] = (Byte)(dicSize >> 24); + return SZ_OK; +} + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +void Lzma2Dec_Init(CLzma2Dec *p) +{ + p->state = LZMA2_STATE_CONTROL; + p->needInitDic = True; + p->needInitState = True; + p->needInitProp = True; + LzmaDec_Init(&p->decoder); +} + +static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) +{ + switch(p->state) + { + case LZMA2_STATE_CONTROL: + p->control = b; + PRF(printf("\n %4X ", p->decoder.dicPos)); + PRF(printf(" %2X", b)); + if (p->control == 0) + return LZMA2_STATE_FINISHED; + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if ((p->control & 0x7F) > 2) + return LZMA2_STATE_ERROR; + p->unpackSize = 0; + } + else + p->unpackSize = (UInt32)(p->control & 0x1F) << 16; + return LZMA2_STATE_UNPACK0; + + case LZMA2_STATE_UNPACK0: + p->unpackSize |= (UInt32)b << 8; + return LZMA2_STATE_UNPACK1; + + case LZMA2_STATE_UNPACK1: + p->unpackSize |= (UInt32)b; + p->unpackSize++; + PRF(printf(" %8d", p->unpackSize)); + return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; + + case LZMA2_STATE_PACK0: + p->packSize = (UInt32)b << 8; + return LZMA2_STATE_PACK1; + + case LZMA2_STATE_PACK1: + p->packSize |= (UInt32)b; + p->packSize++; + PRF(printf(" %8d", p->packSize)); + return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: + (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); + + case LZMA2_STATE_PROP: + { + int lc, lp; + if (b >= (9 * 5 * 5)) + return LZMA2_STATE_ERROR; + lc = b % 9; + b /= 9; + p->decoder.prop.pb = b / 5; + lp = b % 5; + if (lc + lp > LZMA2_LCLP_MAX) + return LZMA2_STATE_ERROR; + p->decoder.prop.lc = lc; + p->decoder.prop.lp = lp; + p->needInitProp = False; + return LZMA2_STATE_DATA; + } + } + return LZMA2_STATE_ERROR; +} + +static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) +{ + memcpy(p->dic + p->dicPos, src, size); + p->dicPos += size; + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) + p->checkDicSize = p->prop.dicSize; + p->processedPos += (UInt32)size; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->state != LZMA2_STATE_FINISHED) + { + SizeT dicPos = p->decoder.dicPos; + if (p->state == LZMA2_STATE_ERROR) + return SZ_ERROR_DATA; + if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->state = Lzma2Dec_UpdateState(p, *src++); + continue; + } + { + SizeT destSizeCur = dicLimit - dicPos; + SizeT srcSizeCur = inSize - *srcLen; + ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; + + if (p->unpackSize <= destSizeCur) + { + destSizeCur = (SizeT)p->unpackSize; + curFinishMode = LZMA_FINISH_END; + } + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (p->state == LZMA2_STATE_DATA) + { + Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); + if (initDic) + p->needInitProp = p->needInitState = True; + else if (p->needInitDic) + return SZ_ERROR_DATA; + p->needInitDic = False; + LzmaDec_InitDicAndState(&p->decoder, initDic, False); + } + + if (srcSizeCur > destSizeCur) + srcSizeCur = destSizeCur; + + if (srcSizeCur == 0) + return SZ_ERROR_DATA; + + LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); + + src += srcSizeCur; + *srcLen += srcSizeCur; + p->unpackSize -= (UInt32)srcSizeCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + SizeT outSizeProcessed; + SRes res; + + if (p->state == LZMA2_STATE_DATA) + { + int mode = LZMA2_GET_LZMA_MODE(p); + Bool initDic = (mode == 3); + Bool initState = (mode > 0); + if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) + return SZ_ERROR_DATA; + + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); + p->needInitDic = False; + p->needInitState = False; + p->state = LZMA2_STATE_DATA_CONT; + } + if (srcSizeCur > p->packSize) + srcSizeCur = (SizeT)p->packSize; + + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); + + src += srcSizeCur; + *srcLen += srcSizeCur; + p->packSize -= (UInt32)srcSizeCur; + + outSizeProcessed = p->decoder.dicPos - dicPos; + p->unpackSize -= (UInt32)outSizeProcessed; + + RINOK(res); + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) + return res; + + if (srcSizeCur == 0 && outSizeProcessed == 0) + { + if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || + p->unpackSize != 0 || p->packSize != 0) + return SZ_ERROR_DATA; + p->state = LZMA2_STATE_CONTROL; + } + if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + *status = LZMA_STATUS_NOT_FINISHED; + } + } + } + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; +} + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen, inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT srcSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->decoder.dicPos == p->decoder.dicBufSize) + p->decoder.dicPos = 0; + dicPos = p->decoder.dicPos; + if (outSize > p->decoder.dicBufSize - dicPos) + { + outSizeCur = p->decoder.dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); + src += srcSizeCur; + inSize -= srcSizeCur; + *srcLen += srcSizeCur; + outSizeCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzma2Dec decoder; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + Byte props[LZMA_PROPS_SIZE]; + + Lzma2Dec_Construct(&decoder); + + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + decoder.decoder.dic = dest; + decoder.decoder.dicBufSize = outSize; + + RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); + + *srcLen = inSize; + res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); + *destLen = decoder.decoder.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + LzmaDec_FreeProbs(&decoder.decoder, alloc); + return res; +} diff --git a/References/VirtuaNESex_src_191105/7z/Lzma2Dec.h b/References/VirtuaNESex_src_191105/7z/Lzma2Dec.h new file mode 100644 index 00000000..6bc07bbc --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Lzma2Dec.h @@ -0,0 +1,84 @@ +/* Lzma2Dec.h -- LZMA2 Decoder +2009-05-03 : Igor Pavlov : Public domain */ + +#ifndef __LZMA2_DEC_H +#define __LZMA2_DEC_H + +#include "LzmaDec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------- State Interface ---------- */ + +typedef struct +{ + CLzmaDec decoder; + UInt32 packSize; + UInt32 unpackSize; + int state; + Byte control; + Bool needInitDic; + Bool needInitState; + Bool needInitProp; +} CLzma2Dec; + +#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); +void Lzma2Dec_Init(CLzma2Dec *p); + + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen or dicLimit). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + SZ_ERROR_DATA - Data error +*/ + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/LzmaDec.c b/References/VirtuaNESex_src_191105/7z/LzmaDec.c new file mode 100644 index 00000000..2036761b --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/LzmaDec.c @@ -0,0 +1,999 @@ +/* LzmaDec.c -- LZMA Decoder +2009-09-20 : Igor Pavlov : Public domain */ + +#include "LzmaDec.h" + +#include + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p); i = (i + i); A0; } else \ + { UPDATE_1(p); i = (i + i) + 1; A1; } +#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + +#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK; i = (i + i); A0; } else \ + { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#define LZMA_DIC_MIN (1 << 12) + +/* First LZMA-symbol is always decoded. +And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization +Out: + Result: + SZ_OK - OK + SZ_ERROR_DATA - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : Flush marker + = kMatchSpecLenStart + 2 : State Init Marker +*/ + +static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = p->probs; + + unsigned state = p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; + unsigned lc = p->prop.lc; + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = processedPos & pbMask; + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (checkDicSize != 0 || processedPos != 0) + prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + + (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); + + if (state < kNumLitStates) + { + state -= (state < 4) ? state : 3; + symbol = 1; + do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + dic[dicPos++] = (Byte)symbol; + processedPos++; + continue; + } + else + { + UPDATE_1(prob); + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob); + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + UPDATE_0(prob); + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob); + } + else + { + UInt32 distance; + UPDATE_1(prob); + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + UPDATE_1(prob); + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = (1 << kLenNumMidBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, limit, len); + len += offset; + } + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + int numDirectBits = (int)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos + distance - posSlot - 1; + { + UInt32 mask = 1; + unsigned i = 1; + do + { + GET_BIT2(prob + i, i, ; , distance |= mask); + mask <<= 1; + } + while (--numDirectBits != 0); + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits != 0); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + GET_BIT2(prob + i, i, ; , distance |= 1); + GET_BIT2(prob + i, i, ; , distance |= 2); + GET_BIT2(prob + i, i, ; , distance |= 4); + GET_BIT2(prob + i, i, ; , distance |= 8); + } + if (distance == (UInt32)0xFFFFFFFF) + { + len += kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (checkDicSize == 0) + { + if (distance >= processedPos) + return SZ_ERROR_DATA; + } + else if (distance >= checkDicSize) + return SZ_ERROR_DATA; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + } + + len += kMatchMinLen; + + if (limit == dicPos) + return SZ_ERROR_DATA; + { + SizeT rem = limit - dicPos; + unsigned curLen = ((rem < len) ? (unsigned)rem : len); + SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); + + processedPos += curLen; + + len -= curLen; + if (pos + curLen <= dicBufSize) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + NORMALIZE; + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = state; + + return SZ_OK; +} + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + Byte *dic = p->dic; + SizeT dicPos = p->dicPos; + SizeT dicBufSize = p->dicBufSize; + unsigned len = p->remainLen; + UInt32 rep0 = p->reps[0]; + if (limit - dicPos < len) + len = (unsigned)(limit - dicPos); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += len; + p->remainLen -= len; + while (len-- != 0) + { + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + do + { + SizeT limit2 = limit; + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + } + RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); + if (p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + if (p->remainLen > kMatchSpecLenStart) + { + p->remainLen = kMatchSpecLenStart; + } + return 0; +} + +typedef enum +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = buf + inSize; + CLzmaProb *probs = p->probs; + unsigned state = p->state; + ELzmaDummy res; + + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += (LZMA_LIT_SIZE * + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumMidBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits != 0); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + do + { + GET_BIT_CHECK(prob + i, i); + } + while (--numDirectBits != 0); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +{ + p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); + p->range = 0xFFFFFFFF; + p->needFlush = 0; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->needInitState = 1; + } + if (initState) + p->needInitState = 1; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + +static void LzmaDec_InitStateReal(CLzmaDec *p) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); + UInt32 i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + p->needInitState = 0; +} + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + LzmaDec_WriteRem(p, dicLimit); + + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow; + + if (p->needFlush != 0) + { + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + + LzmaDec_InitRc(p, p->tempBuf); + p->tempBufSize = 0; + } + + checkEndMarkNow = 0; + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->needInitState) + LzmaDec_InitStateReal(p); + + if (p->tempBufSize == 0) + { + SizeT processed; + const Byte *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = (SizeT)(p->buf - src); + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); + (*srcLen) += lookAhead; + src += lookAhead; + inSize -= lookAhead; + p->tempBufSize = 0; + } + } + if (p->code == 0) + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->probs); + p->probs = 0; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->dic); + p->dic = 0; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = d % 9; + d /= 9; + p->pb = d / 5; + p->lp = d % 5; + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (p->probs == 0 || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->numProbs = numProbs; + if (p->probs == 0) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + dicBufSize = propNew.dicSize; + if (p->dic == 0 || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); + if (p->dic == 0) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzmaDec p; + SRes res; + SizeT inSize = *srcLen; + SizeT outSize = *destLen; + *srcLen = *destLen = 0; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + + LzmaDec_Construct(&p); + res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); + if (res != 0) + return res; + p.dic = dest; + p.dicBufSize = outSize; + + LzmaDec_Init(&p); + + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + (*destLen) = p.dicPos; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/References/VirtuaNESex_src_191105/7z/LzmaDec.h b/References/VirtuaNESex_src_191105/7z/LzmaDec.h new file mode 100644 index 00000000..bf7f084b --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/LzmaDec.h @@ -0,0 +1,231 @@ +/* LzmaDec.h -- LZMA Decoder +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_DEC_H +#define __LZMA_DEC_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* #define _LZMA_PROB32 */ +/* _LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaProps +{ + unsigned lc, lp, pb; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct +{ + CLzmaProps prop; + CLzmaProb *probs; + Byte *dic; + const Byte *buf; + UInt32 range, code; + SizeT dicPos; + SizeT dicBufSize; + UInt32 processedPos; + UInt32 checkDicSize; + unsigned state; + UInt32 reps[4]; + unsigned remainLen; + int needFlush; + int needInitState; + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. + 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); + +SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Constr() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/Ppmd.h b/References/VirtuaNESex_src_191105/7z/Ppmd.h new file mode 100644 index 00000000..72a1cc52 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Ppmd.h @@ -0,0 +1,81 @@ +/* Ppmd.h -- PPMD codec common code +2010-03-12 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#ifndef __PPMD_H +#define __PPMD_H + +#include "Types.h" +#include "CpuArch.h" + +EXTERN_C_BEGIN + +#ifdef MY_CPU_32BIT + #define PPMD_32BIT +#endif + +#define PPMD_INT_BITS 7 +#define PPMD_PERIOD_BITS 7 +#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) + +#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) +#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) +#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) +#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) + +#define PPMD_N1 4 +#define PPMD_N2 4 +#define PPMD_N3 4 +#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) +#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) + +/* SEE-contexts for PPM-contexts with masked symbols */ +typedef struct +{ + UInt16 Summ; /* Freq */ + Byte Shift; /* Speed of Freq change; low Shift is for fast change */ + Byte Count; /* Count to next change of Shift */ +} CPpmd_See; + +#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ + { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } + +typedef struct +{ + Byte Symbol; + Byte Freq; + UInt16 SuccessorLow; + UInt16 SuccessorHigh; +} CPpmd_State; + +typedef + #ifdef PPMD_32BIT + CPpmd_State * + #else + UInt32 + #endif + CPpmd_State_Ref; + +typedef + #ifdef PPMD_32BIT + void * + #else + UInt32 + #endif + CPpmd_Void_Ref; + +typedef + #ifdef PPMD_32BIT + Byte * + #else + UInt32 + #endif + CPpmd_Byte_Ref; + +#define PPMD_SetAllBitsIn256Bytes(p) \ + { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ + p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/Ppmd7.c b/References/VirtuaNESex_src_191105/7z/Ppmd7.c new file mode 100644 index 00000000..060d86d2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Ppmd7.c @@ -0,0 +1,708 @@ +/* Ppmd7.c -- PPMdH codec +2010-03-12 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#include + +#include "Ppmd7.h" + +const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; + +#define MAX_FREQ 124 +#define UNIT_SIZE 12 + +#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) +#define U2I(nu) (p->Units2Indx[(nu) - 1]) +#define I2U(indx) (p->Indx2Units[indx]) + +#ifdef PPMD_32BIT + #define REF(ptr) (ptr) +#else + #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) +#endif + +#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +#define STATS(ctx) Ppmd7_GetStats(p, ctx) +#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) +#define SUFFIX(ctx) CTX((ctx)->Suffix) + +typedef CPpmd7_Context * CTX_PTR; + +struct CPpmd7_Node_; + +typedef + #ifdef PPMD_32BIT + struct CPpmd7_Node_ * + #else + UInt32 + #endif + CPpmd7_Node_Ref; + +typedef struct CPpmd7_Node_ +{ + UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ + UInt16 NU; + CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ + CPpmd7_Node_Ref Prev; +} CPpmd7_Node; + +#ifdef PPMD_32BIT + #define NODE(ptr) (ptr) +#else + #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) +#endif + +void Ppmd7_Construct(CPpmd7 *p) +{ + unsigned i, k, m; + + p->Base = 0; + + for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) + { + unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); + do { p->Units2Indx[k++] = (Byte)i; } while(--step); + p->Indx2Units[i] = (Byte)k; + } + + p->NS2BSIndx[0] = (0 << 1); + p->NS2BSIndx[1] = (1 << 1); + memset(p->NS2BSIndx + 2, (2 << 1), 9); + memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); + + for (i = 0; i < 3; i++) + p->NS2Indx[i] = (Byte)i; + for (m = i, k = 1; i < 256; i++) + { + p->NS2Indx[i] = (Byte)m; + if (--k == 0) + k = (++m) - 2; + } + + memset(p->HB2Flag, 0, 0x40); + memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); +} + +void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->Base); + p->Size = 0; + p->Base = 0; +} + +Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) +{ + if (p->Base == 0 || p->Size != size) + { + Ppmd7_Free(p, alloc); + p->AlignOffset = + #ifdef PPMD_32BIT + (4 - size) & 3; + #else + 4 - (size & 3); + #endif + if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size + #ifndef PPMD_32BIT + + UNIT_SIZE + #endif + )) == 0) + return False; + p->Size = size; + } + return True; +} + +static void InsertNode(CPpmd7 *p, void *node, unsigned indx) +{ + *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; + p->FreeList[indx] = REF(node); +} + +static void *RemoveNode(CPpmd7 *p, unsigned indx) +{ + CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); + p->FreeList[indx] = *node; + return node; +} + +static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +{ + unsigned i, nu = I2U(oldIndx) - I2U(newIndx); + ptr = (Byte *)ptr + U2B(I2U(newIndx)); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + } + InsertNode(p, ptr, i); +} + +static void GlueFreeBlocks(CPpmd7 *p) +{ + #ifdef PPMD_32BIT + CPpmd7_Node headItem; + CPpmd7_Node_Ref head = &headItem; + #else + CPpmd7_Node_Ref head = p->AlignOffset + p->Size; + #endif + + CPpmd7_Node_Ref n = head; + unsigned i; + + p->GlueCount = 255; + + /* create doubly-linked list of free blocks */ + for (i = 0; i < PPMD_NUM_INDEXES; i++) + { + UInt16 nu = I2U(i); + CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; + p->FreeList[i] = 0; + while (next != 0) + { + CPpmd7_Node *node = NODE(next); + node->Next = n; + n = NODE(n)->Prev = next; + next = *(const CPpmd7_Node_Ref *)node; + node->Stamp = 0; + node->NU = (UInt16)nu; + } + } + NODE(head)->Stamp = 1; + NODE(head)->Next = n; + NODE(n)->Prev = head; + if (p->LoUnit != p->HiUnit) + ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; + + /* Glue free blocks */ + while (n != head) + { + CPpmd7_Node *node = NODE(n); + UInt32 nu = (UInt32)node->NU; + for (;;) + { + CPpmd7_Node *node2 = NODE(n) + nu; + nu += node2->NU; + if (node2->Stamp != 0 || nu >= 0x10000) + break; + NODE(node2->Prev)->Next = node2->Next; + NODE(node2->Next)->Prev = node2->Prev; + node->NU = (UInt16)nu; + } + n = node->Next; + } + + /* Fill lists of free blocks */ + for (n = NODE(head)->Next; n != head;) + { + CPpmd7_Node *node = NODE(n); + unsigned nu; + CPpmd7_Node_Ref next = node->Next; + for (nu = node->NU; nu > 128; nu -= 128, node += 128) + InsertNode(p, node, PPMD_NUM_INDEXES - 1); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + InsertNode(p, node + k, nu - k - 1); + } + InsertNode(p, node, i); + n = next; + } +} + +static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) +{ + unsigned i; + void *retVal; + if (p->GlueCount == 0) + { + GlueFreeBlocks(p); + if (p->FreeList[indx] != 0) + return RemoveNode(p, indx); + } + i = indx; + do + { + if (++i == PPMD_NUM_INDEXES) + { + UInt32 numBytes = U2B(I2U(indx)); + p->GlueCount--; + return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); + } + } + while (p->FreeList[i] == 0); + retVal = RemoveNode(p, i); + SplitBlock(p, retVal, i, indx); + return retVal; +} + +static void *AllocUnits(CPpmd7 *p, unsigned indx) +{ + UInt32 numBytes; + if (p->FreeList[indx] != 0) + return RemoveNode(p, indx); + numBytes = U2B(I2U(indx)); + if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) + { + void *retVal = p->LoUnit; + p->LoUnit += numBytes; + return retVal; + } + return AllocUnitsRare(p, indx); +} + +#define MyMem12Cpy(dest, src, num) \ + { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ + do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } + +static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) +{ + unsigned i0 = U2I(oldNU); + unsigned i1 = U2I(newNU); + if (i0 == i1) + return oldPtr; + if (p->FreeList[i1] != 0) + { + void *ptr = RemoveNode(p, i1); + MyMem12Cpy(ptr, oldPtr, newNU); + InsertNode(p, oldPtr, i0); + return ptr; + } + SplitBlock(p, oldPtr, i0, i1); + return oldPtr; +} + +#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) + +static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) +{ + (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); + (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); +} + +static void RestartModel(CPpmd7 *p) +{ + unsigned i, k, m; + + memset(p->FreeList, 0, sizeof(p->FreeList)); + p->Text = p->Base + p->AlignOffset; + p->HiUnit = p->Text + p->Size; + p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; + p->GlueCount = 0; + + p->OrderFall = p->MaxOrder; + p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; + p->PrevSuccess = 0; + + p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + p->MinContext->Suffix = 0; + p->MinContext->NumStats = 256; + p->MinContext->SummFreq = 256 + 1; + p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + p->LoUnit += U2B(256 / 2); + p->MinContext->Stats = REF(p->FoundState); + for (i = 0; i < 256; i++) + { + CPpmd_State *s = &p->FoundState[i]; + s->Symbol = (Byte)i; + s->Freq = 1; + SetSuccessor(s, 0); + } + + for (i = 0; i < 128; i++) + for (k = 0; k < 8; k++) + { + UInt16 *dest = p->BinSumm[i] + k; + UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); + for (m = 0; m < 64; m += 8) + dest[m] = val; + } + + for (i = 0; i < 25; i++) + for (k = 0; k < 16; k++) + { + CPpmd_See *s = &p->See[i][k]; + s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); + s->Count = 4; + } +} + +void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) +{ + p->MaxOrder = maxOrder; + RestartModel(p); + p->DummySee.Shift = PPMD_PERIOD_BITS; + p->DummySee.Summ = 0; /* unused */ + p->DummySee.Count = 64; /* unused */ +} + +static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) +{ + CPpmd_State upState; + CTX_PTR c = p->MinContext; + CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); + CPpmd_State *ps[PPMD7_MAX_ORDER]; + unsigned numPs = 0; + + if (!skip) + ps[numPs++] = p->FoundState; + + while (c->Suffix) + { + CPpmd_Void_Ref successor; + CPpmd_State *s; + c = SUFFIX(c); + if (c->NumStats != 1) + { + for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); + } + else + s = ONE_STATE(c); + successor = SUCCESSOR(s); + if (successor != upBranch) + { + c = CTX(successor); + if (numPs == 0) + return c; + break; + } + ps[numPs++] = s; + } + + upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); + SetSuccessor(&upState, upBranch + 1); + + if (c->NumStats == 1) + upState.Freq = ONE_STATE(c)->Freq; + else + { + UInt32 cf, s0; + CPpmd_State *s; + for (s = STATS(c); s->Symbol != upState.Symbol; s++); + cf = s->Freq - 1; + s0 = c->SummFreq - c->NumStats - cf; + upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); + } + + do + { + /* Create Child */ + CTX_PTR c1; /* = AllocContext(p); */ + if (p->HiUnit != p->LoUnit) + c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); + else if (p->FreeList[0] != 0) + c1 = (CTX_PTR)RemoveNode(p, 0); + else + { + c1 = (CTX_PTR)AllocUnitsRare(p, 0); + if (!c1) + return NULL; + } + c1->NumStats = 1; + *ONE_STATE(c1) = upState; + c1->Suffix = REF(c); + SetSuccessor(ps[--numPs], REF(c1)); + c = c1; + } + while (numPs != 0); + + return c; +} + +static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) +{ + CPpmd_State tmp = *t1; + *t1 = *t2; + *t2 = tmp; +} + +static void UpdateModel(CPpmd7 *p) +{ + CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); + CTX_PTR c; + unsigned s0, ns; + + if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) + { + c = SUFFIX(p->MinContext); + + if (c->NumStats == 1) + { + CPpmd_State *s = ONE_STATE(c); + if (s->Freq < 32) + s->Freq++; + } + else + { + CPpmd_State *s = STATS(c); + if (s->Symbol != p->FoundState->Symbol) + { + do { s++; } while (s->Symbol != p->FoundState->Symbol); + if (s[0].Freq >= s[-1].Freq) + { + SwapStates(&s[0], &s[-1]); + s--; + } + } + if (s->Freq < MAX_FREQ - 9) + { + s->Freq += 2; + c->SummFreq += 2; + } + } + } + + if (p->OrderFall == 0) + { + p->MinContext = p->MaxContext = CreateSuccessors(p, True); + if (p->MinContext == 0) + { + RestartModel(p); + return; + } + SetSuccessor(p->FoundState, REF(p->MinContext)); + return; + } + + *p->Text++ = p->FoundState->Symbol; + successor = REF(p->Text); + if (p->Text >= p->UnitsStart) + { + RestartModel(p); + return; + } + + if (fSuccessor) + { + if (fSuccessor <= successor) + { + CTX_PTR cs = CreateSuccessors(p, False); + if (cs == NULL) + { + RestartModel(p); + return; + } + fSuccessor = REF(cs); + } + if (--p->OrderFall == 0) + { + successor = fSuccessor; + p->Text -= (p->MaxContext != p->MinContext); + } + } + else + { + SetSuccessor(p->FoundState, successor); + fSuccessor = REF(p->MinContext); + } + + s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); + + for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) + { + unsigned ns1; + UInt32 cf, sf; + if ((ns1 = c->NumStats) != 1) + { + if ((ns1 & 1) == 0) + { + /* Expand for one UNIT */ + unsigned oldNU = ns1 >> 1; + unsigned i = U2I(oldNU); + if (i != U2I(oldNU + 1)) + { + void *ptr = AllocUnits(p, i + 1); + void *oldPtr; + if (!ptr) + { + RestartModel(p); + return; + } + oldPtr = STATS(c); + MyMem12Cpy(ptr, oldPtr, oldNU); + InsertNode(p, oldPtr, i); + c->Stats = STATS_REF(ptr); + } + } + c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); + } + else + { + CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); + if (!s) + { + RestartModel(p); + return; + } + *s = *ONE_STATE(c); + c->Stats = REF(s); + if (s->Freq < MAX_FREQ / 4 - 1) + s->Freq <<= 1; + else + s->Freq = MAX_FREQ - 4; + c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); + } + cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); + sf = (UInt32)s0 + c->SummFreq; + if (cf < 6 * sf) + { + cf = 1 + (cf > sf) + (cf >= 4 * sf); + c->SummFreq += 3; + } + else + { + cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); + c->SummFreq = (UInt16)(c->SummFreq + cf); + } + { + CPpmd_State *s = STATS(c) + ns1; + SetSuccessor(s, successor); + s->Symbol = p->FoundState->Symbol; + s->Freq = (Byte)cf; + c->NumStats = (UInt16)(ns1 + 1); + } + } + p->MaxContext = p->MinContext = CTX(fSuccessor); +} + +static void Rescale(CPpmd7 *p) +{ + unsigned i, adder, sumFreq, escFreq; + CPpmd_State *stats = STATS(p->MinContext); + CPpmd_State *s = p->FoundState; + { + CPpmd_State tmp = *s; + for (; s != stats; s--) + s[0] = s[-1]; + *s = tmp; + } + escFreq = p->MinContext->SummFreq - s->Freq; + s->Freq += 4; + adder = (p->OrderFall != 0); + s->Freq = (Byte)((s->Freq + adder) >> 1); + sumFreq = s->Freq; + + i = p->MinContext->NumStats - 1; + do + { + escFreq -= (++s)->Freq; + s->Freq = (Byte)((s->Freq + adder) >> 1); + sumFreq += s->Freq; + if (s[0].Freq > s[-1].Freq) + { + CPpmd_State *s1 = s; + CPpmd_State tmp = *s1; + do + s1[0] = s1[-1]; + while (--s1 != stats && tmp.Freq > s1[-1].Freq); + *s1 = tmp; + } + } + while (--i); + + if (s->Freq == 0) + { + unsigned numStats = p->MinContext->NumStats; + unsigned n0, n1; + do { i++; } while ((--s)->Freq == 0); + escFreq += i; + p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); + if (p->MinContext->NumStats == 1) + { + CPpmd_State tmp = *stats; + do + { + tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); + escFreq >>= 1; + } + while (escFreq > 1); + InsertNode(p, stats, U2I(((numStats + 1) >> 1))); + *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; + return; + } + n0 = (numStats + 1) >> 1; + n1 = (p->MinContext->NumStats + 1) >> 1; + if (n0 != n1) + p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); + } + p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); + p->FoundState = STATS(p->MinContext); +} + +CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) +{ + CPpmd_See *see; + unsigned nonMasked = p->MinContext->NumStats - numMasked; + if (p->MinContext->NumStats != 256) + { + see = p->See[p->NS2Indx[nonMasked - 1]] + + (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + + 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + + 4 * (numMasked > nonMasked) + + p->HiBitsFlag; + { + unsigned r = (see->Summ >> see->Shift); + see->Summ = (UInt16)(see->Summ - r); + *escFreq = r + (r == 0); + } + } + else + { + see = &p->DummySee; + *escFreq = 1; + } + return see; +} + +static void NextContext(CPpmd7 *p) +{ + CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + if (p->OrderFall == 0 && (Byte *)c > p->Text) + p->MinContext = p->MaxContext = c; + else + UpdateModel(p); +} + +void Ppmd7_Update1(CPpmd7 *p) +{ + CPpmd_State *s = p->FoundState; + s->Freq += 4; + p->MinContext->SummFreq += 4; + if (s[0].Freq > s[-1].Freq) + { + SwapStates(&s[0], &s[-1]); + p->FoundState = --s; + if (s->Freq > MAX_FREQ) + Rescale(p); + } + NextContext(p); +} + +void Ppmd7_Update1_0(CPpmd7 *p) +{ + p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); + p->RunLength += p->PrevSuccess; + p->MinContext->SummFreq += 4; + if ((p->FoundState->Freq += 4) > MAX_FREQ) + Rescale(p); + NextContext(p); +} + +void Ppmd7_UpdateBin(CPpmd7 *p) +{ + p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); + p->PrevSuccess = 1; + p->RunLength++; + NextContext(p); +} + +void Ppmd7_Update2(CPpmd7 *p) +{ + p->MinContext->SummFreq += 4; + if ((p->FoundState->Freq += 4) > MAX_FREQ) + Rescale(p); + p->RunLength = p->InitRL; + UpdateModel(p); +} diff --git a/References/VirtuaNESex_src_191105/7z/Ppmd7.h b/References/VirtuaNESex_src_191105/7z/Ppmd7.h new file mode 100644 index 00000000..96521c31 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Ppmd7.h @@ -0,0 +1,140 @@ +/* Ppmd7.h -- PPMdH compression codec +2010-03-12 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +/* This code supports virtual RangeDecoder and includes the implementation +of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. +If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ + +#ifndef __PPMD7_H +#define __PPMD7_H + +#include "Ppmd.h" + +EXTERN_C_BEGIN + +#define PPMD7_MIN_ORDER 2 +#define PPMD7_MAX_ORDER 64 + +#define PPMD7_MIN_MEM_SIZE (1 << 11) +#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) + +struct CPpmd7_Context_; + +typedef + #ifdef PPMD_32BIT + struct CPpmd7_Context_ * + #else + UInt32 + #endif + CPpmd7_Context_Ref; + +typedef struct CPpmd7_Context_ +{ + UInt16 NumStats; + UInt16 SummFreq; + CPpmd_State_Ref Stats; + CPpmd7_Context_Ref Suffix; +} CPpmd7_Context; + +#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) + +typedef struct +{ + CPpmd7_Context *MinContext, *MaxContext; + CPpmd_State *FoundState; + unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; + Int32 RunLength, InitRL; /* must be 32-bit at least */ + + UInt32 Size; + UInt32 GlueCount; + Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; + UInt32 AlignOffset; + + Byte Indx2Units[PPMD_NUM_INDEXES]; + Byte Units2Indx[128]; + CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; + Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; + CPpmd_See DummySee, See[25][16]; + UInt16 BinSumm[128][64]; +} CPpmd7; + +void Ppmd7_Construct(CPpmd7 *p); +Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); +void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); +void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); +#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) + + +/* ---------- Internal Functions ---------- */ + +extern const Byte PPMD7_kExpEscape[16]; + +#ifdef PPMD_32BIT + #define Ppmd7_GetPtr(p, ptr) (ptr) + #define Ppmd7_GetContext(p, ptr) (ptr) + #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) +#else + #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) + #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) + #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) +#endif + +void Ppmd7_Update1(CPpmd7 *p); +void Ppmd7_Update1_0(CPpmd7 *p); +void Ppmd7_Update2(CPpmd7 *p); +void Ppmd7_UpdateBin(CPpmd7 *p); + +#define Ppmd7_GetBinSumm(p) \ + &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ + p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ + (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ + 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ + ((p->RunLength >> 26) & 0x20)] + +CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); + + +/* ---------- Decode ---------- */ + +typedef struct +{ + UInt32 (*GetThreshold)(void *p, UInt32 total); + void (*Decode)(void *p, UInt32 start, UInt32 size); + UInt32 (*DecodeBit)(void *p, UInt32 size0); +} IPpmd7_RangeDec; + +typedef struct +{ + IPpmd7_RangeDec p; + UInt32 Range; + UInt32 Code; + IByteIn *Stream; +} CPpmd7z_RangeDec; + +void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); +Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); +#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) + +int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); + + +/* ---------- Encode ---------- */ + +typedef struct +{ + UInt64 Low; + UInt32 Range; + Byte Cache; + UInt64 CacheSize; + IByteOut *Stream; +} CPpmd7z_RangeEnc; + +void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); +void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); + +void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/7z/Ppmd7Dec.c b/References/VirtuaNESex_src_191105/7z/Ppmd7Dec.c new file mode 100644 index 00000000..68438d5c --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Ppmd7Dec.c @@ -0,0 +1,187 @@ +/* Ppmd7Dec.c -- PPMdH Decoder +2010-03-12 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#include "Ppmd7.h" + +#define kTopValue (1 << 24) + +Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) +{ + unsigned i; + p->Code = 0; + p->Range = 0xFFFFFFFF; + if (p->Stream->Read((void *)p->Stream) != 0) + return False; + for (i = 0; i < 4; i++) + p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); + return (p->Code < 0xFFFFFFFF); +} + +static UInt32 Range_GetThreshold(void *pp, UInt32 total) +{ + CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; + return (p->Code) / (p->Range /= total); +} + +static void Range_Normalize(CPpmd7z_RangeDec *p) +{ + if (p->Range < kTopValue) + { + p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); + p->Range <<= 8; + if (p->Range < kTopValue) + { + p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); + p->Range <<= 8; + } + } +} + +static void Range_Decode(void *pp, UInt32 start, UInt32 size) +{ + CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; + p->Code -= start * p->Range; + p->Range *= size; + Range_Normalize(p); +} + +static UInt32 Range_DecodeBit(void *pp, UInt32 size0) +{ + CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; + UInt32 newBound = (p->Range >> 14) * size0; + UInt32 symbol; + if (p->Code < newBound) + { + symbol = 0; + p->Range = newBound; + } + else + { + symbol = 1; + p->Code -= newBound; + p->Range -= newBound; + } + Range_Normalize(p); + return symbol; +} + +void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) +{ + p->p.GetThreshold = Range_GetThreshold; + p->p.Decode = Range_Decode; + p->p.DecodeBit = Range_DecodeBit; +} + + +#define MASK(sym) ((signed char *)charMask)[sym] + +int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) +{ + size_t charMask[256 / sizeof(size_t)]; + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + unsigned i; + UInt32 count, hiCnt; + if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) + { + Byte symbol; + rc->Decode(rc, 0, s->Freq); + p->FoundState = s; + symbol = s->Symbol; + Ppmd7_Update1_0(p); + return symbol; + } + p->PrevSuccess = 0; + i = p->MinContext->NumStats - 1; + do + { + if ((hiCnt += (++s)->Freq) > count) + { + Byte symbol; + rc->Decode(rc, hiCnt - s->Freq, s->Freq); + p->FoundState = s; + symbol = s->Symbol; + Ppmd7_Update1(p); + return symbol; + } + } + while (--i); + if (count >= p->MinContext->SummFreq) + return -2; + p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; + rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); + PPMD_SetAllBitsIn256Bytes(charMask); + MASK(s->Symbol) = 0; + i = p->MinContext->NumStats - 1; + do { MASK((--s)->Symbol) = 0; } while (--i); + } + else + { + UInt16 *prob = Ppmd7_GetBinSumm(p); + if (rc->DecodeBit(rc, *prob) == 0) + { + Byte symbol; + *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); + symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; + Ppmd7_UpdateBin(p); + return symbol; + } + *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); + p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; + PPMD_SetAllBitsIn256Bytes(charMask); + MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; + p->PrevSuccess = 0; + } + for (;;) + { + CPpmd_State *ps[256], *s; + UInt32 freqSum, count, hiCnt; + CPpmd_See *see; + unsigned i, num, numMasked = p->MinContext->NumStats; + do + { + p->OrderFall++; + if (!p->MinContext->Suffix) + return -1; + p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); + } + while (p->MinContext->NumStats == numMasked); + hiCnt = 0; + s = Ppmd7_GetStats(p, p->MinContext); + i = 0; + num = p->MinContext->NumStats - numMasked; + do + { + int k = (int)(MASK(s->Symbol)); + hiCnt += (s->Freq & k); + ps[i] = s++; + i -= k; + } + while (i != num); + + see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); + freqSum += hiCnt; + count = rc->GetThreshold(rc, freqSum); + + if (count < hiCnt) + { + Byte symbol; + CPpmd_State **pps = ps; + for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); + s = *pps; + rc->Decode(rc, hiCnt - s->Freq, s->Freq); + Ppmd_See_Update(see); + p->FoundState = s; + symbol = s->Symbol; + Ppmd7_Update2(p); + return symbol; + } + if (count >= freqSum) + return -2; + rc->Decode(rc, hiCnt, freqSum - hiCnt); + see->Summ = (UInt16)(see->Summ + freqSum); + do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); + } +} diff --git a/References/VirtuaNESex_src_191105/7z/Types.h b/References/VirtuaNESex_src_191105/7z/Types.h new file mode 100644 index 00000000..7732c240 --- /dev/null +++ b/References/VirtuaNESex_src_191105/7z/Types.h @@ -0,0 +1,254 @@ +/* Types.h -- Basic types +2010-10-09 : Igor Pavlov : Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#include + +#ifdef _WIN32 +#include +#endif + +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + +#ifdef _WIN32 +typedef DWORD WRes; +#else +typedef int WRes; +#endif + +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef _LZMA_UINT32_IS_ULONG +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + +#ifdef _SZ_NO_INT_64 + +/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. + NOTES: Some code will work incorrectly in that case! */ + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#define UINT64_CONST(n) n +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +#define UINT64_CONST(n) n ## ULL +#endif + +#endif + +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +typedef size_t SizeT; +#endif + +typedef int Bool; +#define True 1 +#define False 0 + + +#ifdef _WIN32 +#define MY_STD_CALL __stdcall +#else +#define MY_STD_CALL +#endif + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) +#else +#define MY_NO_INLINE +#endif + +#define MY_CDECL __cdecl +#define MY_FAST_CALL __fastcall + +#else + +#define MY_CDECL +#define MY_FAST_CALL + +#endif + + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct +{ + Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ +} IByteIn; + +typedef struct +{ + void (*Write)(void *p, Byte b); +} IByteOut; + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +} ISeqInStream; + +/* it can return SZ_ERROR_INPUT_EOF */ +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); + +typedef struct +{ + size_t (*Write)(void *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +} ISeqOutStream; + +typedef enum +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ISeekInStream; + +typedef struct +{ + SRes (*Look)(void *p, const void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(void *p, size_t offset); + /* offset must be <= output(*size) of Look */ + + SRes (*Read)(void *p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ILookInStream; + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); + +#define LookToRead_BUF_SIZE (1 << 14) + +typedef struct +{ + ILookInStream s; + ISeekInStream *realStream; + size_t pos; + size_t size; + Byte buf[LookToRead_BUF_SIZE]; +} CLookToRead; + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead); +void LookToRead_Init(CLookToRead *p); + +typedef struct +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + +typedef struct +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + +typedef struct +{ + SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +} ICompressProgress; + +typedef struct +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ +} ISzAlloc; + +#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +#define IAlloc_Free(p, a) (p)->Free((p), a) + +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#endif + +EXTERN_C_END + +#endif diff --git a/References/VirtuaNESex_src_191105/AboutDlg.cpp b/References/VirtuaNESex_src_191105/AboutDlg.cpp new file mode 100644 index 00000000..6456cf05 --- /dev/null +++ b/References/VirtuaNESex_src_191105/AboutDlg.cpp @@ -0,0 +1,106 @@ +// +// o[W_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "AboutDlg.h" + +DLG_MESSAGE_BEGIN(CAboutDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDC_VER_WEBSITE, OnWebsite ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CAboutDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_VERSION), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CAboutDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CAboutDlg::OnInitDialog\n" ); + + ::SendDlgItemMessage( m_hWnd, IDC_VER_ICON, STM_SETICON, + (WPARAM)CApp::LoadIcon( IDI_ICON ), 0 ); + + TCHAR str[256]; + + ::wsprintf( str, "VirtuaNESex version %01d.%01d%01d%s", + (VIRTUANES_VERSION&0xF00)>>8, + (VIRTUANES_VERSION&0x0F0)>>4, + (VIRTUANES_VERSION&0x00F), + VIRTUANES_FIXVERSION ); + + ::SetDlgItemText( m_hWnd, IDC_VER_VERSION, str ); + + ::wsprintf( str, +"ʱ䣺\r\n\ + %s %s\r\n\r\n\ +빱ߣ\r\n\ + tpu \r\n\ + temryu \r\n\ + byemu \r\n\ + Ҷ \r\n\ + Ăl֪", +__DATE__,__TIME__); + ::SetDlgItemText( m_hWnd, IDC_VER_CONTRIBUTOR, str ); + +// ::SetDlgItemText( m_hWnd, IDC_VER_WEBSITE, VIRTUANES_WEBSITE ); + + m_Website.Attach( ::GetDlgItem( m_hWnd, IDC_VER_WEBSITE ), VIRTUANES_WEBSITE ); + + string email, mailto; + email = VIRTUANES_EMAILNAME; + email += "@"; + email += VIRTUANES_EMAILDOMAIN; + mailto = "mailto:" + email; + + m_Email.Attach( ::GetDlgItem( m_hWnd, IDC_VER_EMAIL ), email.c_str(), mailto.c_str() ); + + return TRUE; +} + +DLGCMD CAboutDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CAboutDlg::OnOK\n" ); + +// m_Website.Detach(); +// m_Email.Detach(); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CAboutDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CAboutDlg::OnCancel\n" ); + +// m_Website.Detach(); +// m_Email.Detach(); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CAboutDlg::OnWebsite( DLGCMDPARAM ) +{ +// DEBUGOUT( "CAboutDlg::OnCancel\n" ); + + ::ShellExecute( HWND_DESKTOP, "open", VIRTUANES_WEBSITE, NULL, NULL, SW_SHOWNORMAL ); +// ::ShellExecute( m_hWnd, "open", VIRTUANES_WEBSITE, NULL, NULL, SW_SHOWNORMAL ); +} + diff --git a/References/VirtuaNESex_src_191105/AboutDlg.h b/References/VirtuaNESex_src_191105/AboutDlg.h new file mode 100644 index 00000000..88f8b560 --- /dev/null +++ b/References/VirtuaNESex_src_191105/AboutDlg.h @@ -0,0 +1,36 @@ +// +// o[W_CAONX +// +#ifndef __CABOUTDLG_INCLUDED__ +#define __CABOUTDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "CHyperLink.h" + +class CAboutDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnWebsite( DLGCMDPARAM ); + // + + CHyperLink m_Website; + CHyperLink m_Email; +private: +}; + +#endif // !__CABOUTDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/App.cpp b/References/VirtuaNESex_src_191105/App.cpp new file mode 100644 index 00000000..2a3cb2d9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/App.cpp @@ -0,0 +1,81 @@ +// +// AvP[VT|[gNX +// +#include "VirtuaNESres.h" +#include "App.h" + +// _tWinMain̈̂܂ +HINSTANCE CApp::m_hInstance = NULL; +HINSTANCE CApp::m_hPrevInstance = NULL; +LPTSTR CApp::m_lpCmdLine = NULL; +INT CApp::m_nCmdShow = 0; + +// ꃊ\[XvOC̃CX^Xnh +HINSTANCE CApp::m_hPlugin = NULL; +// CEChẼEChEnh +HWND CApp::m_hWnd = NULL; +// CEChẼj[nh +HMENU CApp::m_hMenu = NULL; + +// vÕpX(ÑpX) +CHAR CApp::m_szModulePath[_MAX_PATH]; + +// G[XgO(e|) +CHAR szErrorString[256]; + +// G[p +INT CApp::m_ErrorStringTableID[] = { + IDS_ERROR, + IDS_ERROR_STARTUP, + IDS_ERROR_UNKNOWN, + IDS_ERROR_OPEN, + IDS_ERROR_READ, + IDS_ERROR_WRITE, + IDS_ERROR_OUTOFMEMORY, + + IDS_ERROR_ILLEGALOPCODE, + IDS_ERROR_UNSUPPORTFORMAT, + IDS_ERROR_INVALIDNESHEADER, + IDS_ERROR_SMALLFILE, + IDS_ERROR_UNSUPPORTMAPPER, + IDS_ERROR_NODISKBIOS, + IDS_ERROR_UNSUPPORTDISK, + IDS_ERROR_ILLEGALDISKSIZE, + + IDS_ERROR_ILLEGALMAPPERNO, + IDS_ERROR_ILLEGALHEADER, + + IDS_ERROR_ILLEGALSTATECRC, + IDS_ERROR_ILLEGALMOVIEOLD, + IDS_ERROR_ILLEGALMOVIEVER, + IDS_ERROR_ILLEGALMOVIECRC, + IDS_ERROR_ILLEGALMOVIEOLD_A, + IDS_ERROR_ILLEGALMOVIEVER_A, + IDS_ERROR_ILLEGALMOVIECRC_A, + + IDS_ERROR_NETWORKDISCONNECT, + IDS_ERROR_NETWORKERROR, + 0, +}; + +CHAR CApp::m_ErrorString[ERRORSTRING_MAX][256]; + +void CApp::LoadErrorString() +{ + if( !m_hPlugin ) + return; + + for( INT i = 0; m_ErrorStringTableID[i]; i++ ) { + LoadString( m_ErrorStringTableID[i], m_ErrorString[i], sizeof(m_ErrorString[i]) ); + } +} + +CHAR* CApp::GetErrorString( INT nID ) +{ + for( INT i = 0; m_ErrorStringTableID[i]; i++ ) { + if( m_ErrorStringTableID[i] == nID ) + return m_ErrorString[i]; + } + return ""; // NULL XgOƂēn +} + diff --git a/References/VirtuaNESex_src_191105/App.h b/References/VirtuaNESex_src_191105/App.h new file mode 100644 index 00000000..f28ebac9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/App.h @@ -0,0 +1,76 @@ +// +// AvP[VT|[gNX +// + +#ifndef __CAPP_INCLUDED__ +#define __CAPP_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#define ERRORSTRING_MAX 32 + +class CApp { +public: + // Nɐݒ肷 + static void SetInstance( HINSTANCE hInstance ) { m_hInstance = hInstance; } + static void SetPrevInstance( HINSTANCE hInstance ) { m_hPrevInstance = hInstance; } + static void SetCmdLine( LPSTR lpCmdLine ) { m_lpCmdLine = lpCmdLine; } + static void SetCmdShow( INT nCmdShow ) { m_nCmdShow = nCmdShow; } + + static void SetHWnd( HWND hWnd ) { m_hWnd = hWnd; } + static void SetMenu( HMENU hMenu ) { m_hMenu = hMenu; } + static void SetPlugin( HINSTANCE hPlugin ) { m_hPlugin = hPlugin; LoadErrorString(); } + + static void SetModulePath( LPCSTR lpModulePath ) { ::strcpy( m_szModulePath, lpModulePath ); } + + // AvŎgp + static HINSTANCE GetInstance() { return m_hInstance; } + static HINSTANCE GetPrevInstance() { return m_hPrevInstance; } + static LPTSTR GetCmdLine() { return m_lpCmdLine; } + static INT GetCmdShow() { return m_nCmdShow; } + + static HWND GetHWnd() { return m_hWnd; } + static HMENU GetMenu() { return m_hMenu; } + static HINSTANCE GetPlugin() { return m_hPlugin; } + + static LPCSTR GetModulePath() { return m_szModulePath; } + + static HMENU LoadMenu( UINT uID ) { return ::LoadMenu( m_hPlugin, MAKEINTRESOURCE(uID) ); } + static HICON LoadIcon( UINT uID ) { return ::LoadIcon( m_hInstance, MAKEINTRESOURCE(uID) ); } + static INT LoadString( UINT uID, LPTSTR lpBuffer, INT nBufferMax ) { + return ::LoadString( m_hPlugin, uID, lpBuffer, nBufferMax ); } + + // G[p + static void LoadErrorString(); + static CHAR* GetErrorString( INT nID ); + +protected: + // WinMain ̈̂܂ + static HINSTANCE m_hInstance; + static HINSTANCE m_hPrevInstance; + static LPSTR m_lpCmdLine; + static INT m_nCmdShow; + + // ꃊ\[XvOC̃CX^Xnh + static HINSTANCE m_hPlugin; + // CEChẼEChEnh + static HWND m_hWnd; + // CEChẼj[nh + static HMENU m_hMenu; + + // vÕpX(ÑpX) + static CHAR m_szModulePath[_MAX_PATH]; + + // G[p + static INT m_ErrorStringTableID[ERRORSTRING_MAX]; + static CHAR m_ErrorString[ERRORSTRING_MAX][256]; +private: +}; + +// G[bZ[Wpe| +extern CHAR szErrorString[256]; + +#endif // !__CAPP_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/Archive.cpp b/References/VirtuaNESex_src_191105/Archive.cpp new file mode 100644 index 00000000..c9147d81 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Archive.cpp @@ -0,0 +1,332 @@ +// +// A[JCut@C +// +// Original:NesterJ arc.cpp arc.h by Mikami Kana +// Original:NNNesterJ ulunzip.cpp +// +// Zlib use! +// Reprogrammed by Norix +// +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +#include +#include +#include +#include + +#include "typedef.h" +#include "macro.h" +#include "DebugOut.h" + +#include "App.h" +#include "Pathlib.h" + +#include "VirtuaNESres.h" + +#define UNZ_BUFSIZE (65536) + +#include "unzip.h" + +#ifdef __cplusplus +extern "C" { +#endif +int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize); +#ifdef __cplusplus +} +#endif + + +#pragma pack(1) +#define FNAME_MAX32 512 + +typedef struct { + DWORD dwOriginalSize; + DWORD dwCompressedSize; + DWORD dwCRC; + UINT uFlag; + UINT uOSType; + WORD wRatio; + WORD wDate; + WORD wTime; + char szFileName[FNAME_MAX32 + 1]; + char dummy1[3]; + char szAttribute[8]; + char szMode[8]; +} INDIVIDUALINFO, *LPINDIVIDUALINFO; +#pragma pack() + +// Un??? use function +typedef int(WINAPI *EXECUTECOMMAND)(HWND,LPCSTR,LPSTR,const DWORD); +typedef BOOL(WINAPI *CHECKARCHIVE)(LPCSTR,const int); +typedef int(WINAPI *EXTRACTMEM)(HWND,LPCSTR,LPBYTE,const DWORD,time_t,LPWORD,LPDWORD); +typedef HGLOBAL(WINAPI *OPENARCHIVE)(HWND,LPCSTR,const DWORD); +typedef int(WINAPI *CLOSEARCHIVE)(HGLOBAL); +typedef int(WINAPI *FINDFIRST)(HGLOBAL,LPCSTR,INDIVIDUALINFO*); + +static LPCSTR pszArchiver[] = { + "UNLHA32", + "UNZIP32", + "UNRAR32", + "CAB32", + NULL +}; + +static LPCSTR pszFuncPrefix[] = { + "Unlha", + "UnZip", + "Unrar", + "Cab", +}; + +static LPCSTR pszCommand[] = { + NULL, + NULL, + "-e -u \"%s\" \"%s\" \"%s\"", + "-x -j \"%s\" \"%s\" \"%s\"", +}; + +static LPCSTR pszExtension[] = { + "*.nes", + "*.fds", + "*.nsf", + NULL +}; + +static BOOL bFileMatching[] = { + FALSE, + TRUE, + FALSE, + FALSE, +}; + +#define FREEDLL(h) if( h ) { FreeLibrary(h);h=NULL; } + +#define M_ERROR_MESSAGE_OFF 0x00800000L + +// zlibgpZIP𓀃[` +BOOL ZlibUnZip( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize ) +{ + unzFile unzipFile = NULL; + unz_global_info unzipGlobalInfo; + unz_file_info unzipFileInfo; + char fname_buf[256]; + + *ppBuf = NULL; + *lpdwSize = 0; + + if( !(unzipFile = unzOpen( (const char*)fname )) ) + return FALSE; + + if( unzGetGlobalInfo( unzipFile, &unzipGlobalInfo ) != UNZ_OK ) { + unzClose( unzipFile ); + return FALSE; + } + + for( uLong i = 0; i < unzipGlobalInfo.number_entry; i++ ) { + if( unzGetCurrentFileInfo( unzipFile, &unzipFileInfo, fname_buf, sizeof(fname_buf), NULL, 0, NULL, 0 ) != UNZ_OK ) + break; + + char* pExt = ::PathFindExtension( fname_buf ); + if( _stricmp( pExt, ".nes" ) == 0 || _stricmp( pExt, ".fds" ) == 0 || _stricmp( pExt, ".nsf" ) == 0 ) { + if( unzipFileInfo.uncompressed_size ) { + if( unzOpenCurrentFile( unzipFile ) != UNZ_OK ) + break; + + if( unzipFileInfo.uncompressed_size > 0 ) { + if( !(*ppBuf = (LPBYTE)::malloc( unzipFileInfo.uncompressed_size )) ) + break; + + uInt size = unzReadCurrentFile( unzipFile, *ppBuf, unzipFileInfo.uncompressed_size ); + if( size != unzipFileInfo.uncompressed_size ) + break; + } + *lpdwSize = unzipFileInfo.uncompressed_size; + + if( unzCloseCurrentFile( unzipFile ) != UNZ_OK ) + break; + unzClose( unzipFile ); + return TRUE; + } + } + + // Next file + if( (i+1) < unzipGlobalInfo.number_entry ) { + if( unzGoToNextFile( unzipFile ) != UNZ_OK ) { + break; + } + } + } + + FREE( *ppBuf ); + + if( unzipFile ) { + unzCloseCurrentFile( unzipFile ); + unzClose( unzipFile ); + } + return FALSE; +} + +BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize ) +{ + HMODULE hDLL; + INDIVIDUALINFO idvinfo; + + char* pExt = ::PathFindExtension( fname ); + if( _stricmp( pExt, ".zip" ) == 0 ) { + // ZIPȂ܂zlibCủ𓀂gĂ݂ + if( ZlibUnZip( fname, ppBuf, lpdwSize ) ) { +// DEBUGOUT( "zlib unzip ok! [%s]\n", fname ); + return TRUE; + } + } else if( _stricmp( pExt, ".7z" ) == 0 ) { + return SevenZipUnCompress((char*)fname, ppBuf, (size_t*)lpdwSize); + } + + + hDLL = NULL; + for( INT i = 0; pszArchiver[i]; i++ ) { + // DLLA[h + FREEDLL( hDLL ); + + // DLL[h + if( !(hDLL = LoadLibrary( pszArchiver[i] )) ) + continue; + + CHAR szTemp[256]; + sprintf( szTemp, "%sCheckArchive", pszFuncPrefix[i] ); + CHECKARCHIVE CheckArchive; + if( !(CheckArchive = (CHECKARCHIVE)GetProcAddress( hDLL, szTemp )) ) + continue; + // ΉA[JCu`FbN + if( !CheckArchive( fname, 1 ) ) + continue; + + // A[JCuɑΉt@C邩̃`FbN + OPENARCHIVE OpenArchive; + CLOSEARCHIVE CloseArchive; + FINDFIRST FindFirst; + + sprintf( szTemp, "%sOpenArchive", pszFuncPrefix[i] ); + OpenArchive = (OPENARCHIVE)GetProcAddress( hDLL, szTemp ); + sprintf( szTemp, "%sFindFirst", pszFuncPrefix[i] ); + FindFirst = (FINDFIRST)GetProcAddress( hDLL, szTemp ); + sprintf( szTemp, "%sCloseArchive", pszFuncPrefix[i] ); + CloseArchive = (CLOSEARCHIVE)GetProcAddress( hDLL, szTemp ); + + HGLOBAL hARC; + BOOL bFound = FALSE; + for( INT j = 0; pszExtension[j]; j++ ) { + if( !(hARC = OpenArchive( NULL, fname, M_ERROR_MESSAGE_OFF ) ) ) { + CloseArchive( hARC ); + break; + } + INT ret = FindFirst( hARC, pszExtension[j], &idvinfo ); + CloseArchive( hARC ); + if( ret == 0 ) { // Found!! + bFound = TRUE; + break; + } else if( ret == -1 ) { // Not found. + } else { // ُI + break; + } + } + if( !bFound ) + continue; + + if( !pszCommand[i] ) { + // 𓀂(UNLHA32,UNZIP32) + *lpdwSize = idvinfo.dwOriginalSize; + *ppBuf = (LPBYTE)malloc( *lpdwSize ); + + CHAR szCmd [256]; + CHAR szFunc[256]; + + if( !bFileMatching[i] ) { + sprintf( szCmd, "\"%s\" \"%s\"", fname, idvinfo.szFileName ); + } else { + // UNZIP32 only + BYTE szFile[FNAME_MAX32+1]; + LPBYTE lpF0, lpF1; + + // K\؂IvV~.... + lpF0 = (LPBYTE)idvinfo.szFileName; + lpF1 = szFile; + while( *lpF0 ) { + if( *lpF0 == '[' || *lpF0 == ']' ) { + *lpF1++ = '\\'; + } + _mbsncpy( lpF1, lpF0, 1 ); + lpF0 = _mbsinc( lpF0 ); + lpF1 = _mbsinc( lpF1 ); + } + *lpF1 = '\0'; + + sprintf( szCmd, "\"%s\" \"%s\"", fname, szFile ); + } + sprintf( szFunc, "%sExtractMem", pszFuncPrefix[i] ); + + EXTRACTMEM ExtractMem; + ExtractMem = (EXTRACTMEM)GetProcAddress( hDLL, szFunc ); + INT ret = ExtractMem( NULL, szCmd, (LPBYTE)(*ppBuf), *lpdwSize, NULL, NULL, NULL ); + FREEDLL( hDLL ); + if( ret == 0 ) + return TRUE; + } else { + // 𓀂ꍇ + CHAR szCmd [256]; + CHAR szTempPath[_MAX_PATH]; + EXECUTECOMMAND ExecuteCommand; + + GetTempPath( _MAX_PATH, szTempPath ); +//DEBUGOUT( "TempPath:%s\n", szTempPath ); + + sprintf( szCmd, pszCommand[i], fname, szTempPath, idvinfo.szFileName ); + ExecuteCommand = (EXECUTECOMMAND)GetProcAddress( hDLL, pszFuncPrefix[i] ); + ExecuteCommand( NULL, szCmd, NULL, 0 ); + FREEDLL( hDLL ); + + string FileName = CPathlib::MakePath( szTempPath, idvinfo.szFileName ); + + FILE *fp = NULL; + if( (fp = fopen( FileName.c_str(), "rb" )) ) { + // t@CTCY擾 + fseek( fp, 0, SEEK_END ); + *lpdwSize = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + if( *lpdwSize < 17 ) { + // t@CTCY܂ + throw CApp::GetErrorString( IDS_ERROR_SMALLFILE ); + } + + // e|m + if( !(*ppBuf = (LPBYTE)malloc( *lpdwSize )) ) { + FCLOSE( fp ); + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + // TCYǂݍ + if( fread( *ppBuf, *lpdwSize, 1, fp ) != 1 ) { + FCLOSE( fp ); + FREE( *ppBuf ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + FCLOSE( fp ); + DeleteFile( FileName.c_str() ); + } else { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + return TRUE; + } + } + FREEDLL( hDLL ); + + return FALSE; +} +// Archive diff --git a/References/VirtuaNESex_src_191105/Archive.h b/References/VirtuaNESex_src_191105/Archive.h new file mode 100644 index 00000000..fc35e1e7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Archive.h @@ -0,0 +1,12 @@ +// +// A[JCut@C +// +#ifndef __CARCHIVEFILE_INCLUDED__ +#define __CARCHIVEFILE_INCLUDED__ + +#include "typedef.h" + +extern BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize ); + +#endif // !__CARCHIVEFILE_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/CHyperLink.h b/References/VirtuaNESex_src_191105/CHyperLink.h new file mode 100644 index 00000000..ad33bdde --- /dev/null +++ b/References/VirtuaNESex_src_191105/CHyperLink.h @@ -0,0 +1,250 @@ +#ifndef __CHYPERLINK_INCLUDED__ +#define __CHYPERLINK_INCLUDED__ + +// +// X^eBbNRg[SubclassănCp[NT|[g +// +// Usage: CHyperLink hyperlink; +// hyperlink.Attach( GetDlgItem( hWnd, IDC_URL ) ); +// +class CHyperLink +{ +public: + CHyperLink() : m_hWnd(NULL), m_lpLabel(NULL), + m_hCursor(NULL), m_hFont(NULL), + m_lpHyperLink(NULL), m_lpfnOldWndProc(NULL) + { + } + ~CHyperLink() + { + Detach(); + } + + // Rg[ɃA^b` + BOOL Attach( HWND hWnd, LPCSTR lpLabel = NULL, LPCSTR lpHyperLink = NULL ) + { + if( m_hWnd ) + return FALSE; // Attachς + + m_hWnd = hWnd; + + // Rs[ + if( lpLabel ) { + m_lpLabel = new CHAR[::lstrlen(lpLabel)+1]; + ::lstrcpy( m_lpLabel, lpLabel ); + ::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel ); + } + // \ƃnCp[Nꍇ̓nCp[N̓xƓ + if( lpLabel && !lpHyperLink ) { + m_lpHyperLink = new CHAR[::lstrlen(lpLabel)+1]; + ::lstrcpy( m_lpHyperLink, lpLabel ); + } + // nCp[Nʂ̏ꍇ + if( lpHyperLink ) { + m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1]; + ::lstrcpy( m_lpHyperLink, lpHyperLink ); + } + + // |CgJ[\(΃ftHg) + m_hCursor = ::LoadCursor( NULL, MAKEINTRESOURCE(32649) ); + + // A_[CtHg̍쐬 + HFONT m_hOldFont = (HFONT)::SendMessage( hWnd, WM_GETFONT, 0, 0 ); + LOGFONT lFont; + ::GetObject( m_hOldFont, sizeof(LOGFONT), &lFont ); + lFont.lfUnderline = TRUE; + m_hFont = ::CreateFontIndirect( &lFont ); + + // x̕\̈vZ + CalcLabelRectangle(); + + // X^C̕ύX(ʒmCl[uɂ) + DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE ); + dwStyle |= SS_NOTIFY; + ::SetWindowLong( hWnd, GWL_STYLE, (LONG)dwStyle ); + + // Rg[̃TuNX + m_lpfnOldWndProc = (WNDPROC)::SetWindowLong( hWnd, GWL_WNDPROC, (LONG)HyperLinkProc ); + + // This𖄂ߍ + ::SetWindowLong( hWnd, GWL_USERDATA, (LONG)this ); + + return TRUE; + } + + BOOL Detach() + { + if( m_hWnd ) { + // TuNX + if( m_lpfnOldWndProc ) { + ::SetWindowLong( m_hWnd, GWL_WNDPROC, (LONG)m_lpfnOldWndProc ); + m_lpfnOldWndProc = NULL; + } + + // tHg폜 + if( m_hFont ) { + ::DeleteObject( (HGDIOBJ)m_hFont ); + m_hFont = NULL; + } + + // 폜 + if( m_lpLabel ) { + delete[] m_lpLabel; + m_lpLabel = NULL; + } + if( m_lpHyperLink ) { + delete[] m_lpHyperLink; + m_lpHyperLink = NULL; + } + } + + m_hWnd = NULL; + + return TRUE; + } + + BOOL SetLabel( LPCSTR lpLabel ) + { + if( m_lpLabel ) { + delete[] m_lpLabel; + } + + m_lpLabel = new CHAR[::lstrlen(lpLabel)+1]; + ::lstrcpy( m_lpLabel, lpLabel ); + + // Rg[ɕݒ + ::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel ); + + // x̕\̈vZ + CalcLabelRectangle(); + } + + BOOL SetHyperLink( LPCSTR lpHyperLink ) + { + if( m_lpHyperLink ) { + delete[] m_lpHyperLink; + } + + m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1]; + ::lstrcpy( m_lpHyperLink, lpHyperLink ); + } + +protected: + BOOL CalcLabelRectangle() + { + if( !::IsWindow(m_hWnd) ) + return FALSE; + + if( !m_lpLabel ) + return FALSE; + + RECT rcClient; + ::GetClientRect( m_hWnd, &rcClient ); + m_rcLabel = rcClient; + + HDC hDC = ::GetDC( m_hWnd ); + HFONT hOldFont = (HFONT)::SelectObject( hDC, m_hFont ); + + // X^C + DWORD dwStyle = ::GetWindowLong( m_hWnd, GWL_STYLE ); + INT nDrawStyle = DT_LEFT; + if( dwStyle && SS_CENTER ) { + nDrawStyle = DT_CENTER; + } else if( dwStyle && SS_RIGHT ) { + nDrawStyle = DT_RIGHT; + } + + // \ƕ`̈̌vZ + ::DrawText( hDC, m_lpLabel, -1, &m_rcLabel, nDrawStyle | DT_WORDBREAK | DT_CALCRECT ); + + ::SelectObject( hDC, hOldFont ); + + // X^CɂăItZbgvZ + if( dwStyle & SS_CENTER ) { + ::OffsetRect( &m_rcLabel, (rcClient.right - m_rcLabel.right) / 2, 0 ); + } else if (dwStyle & SS_RIGHT) { + ::OffsetRect( &m_rcLabel, rcClient.right - m_rcLabel.right, 0 ); + } + + return true; + } + + static LRESULT CALLBACK HyperLinkProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + CHyperLink* pHyperLink = reinterpret_cast(::GetWindowLong( hWnd, GWL_USERDATA)); + + switch( msg ) { + case WM_DESTROY: + { + // 2003/10/11 [Xfix... + WNDPROC pWndProcOld = pHyperLink->m_lpfnOldWndProc; + pHyperLink->Detach(); + return CallWindowProc( pWndProcOld, hWnd, msg, wParam, lParam ); + } + break; + case WM_LBUTTONDOWN: { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) { + if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) { + ::ShellExecute( hWnd, NULL, pHyperLink->m_lpHyperLink, NULL, NULL, SW_SHOWNORMAL ); + return TRUE; + } + } + } + break; + case WM_MOUSEMOVE: { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) { + if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) { + ::SetCursor( pHyperLink->m_hCursor ); + return TRUE; + } + } + } + break; + case WM_PAINT: { + PAINTSTRUCT ps; + HDC hDC = ::BeginPaint( hWnd, &ps ); + DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE ); + INT nDrawStyle = DT_LEFT; + if( dwStyle && SS_CENTER ) { + nDrawStyle = DT_CENTER; + } else if( dwStyle && SS_RIGHT ) { + nDrawStyle = DT_RIGHT; + } + + // Agr[g + ::SetBkMode( hDC, TRANSPARENT ); + ::SetTextColor( hDC, 0x00FF0000 ); + + // \ + if( pHyperLink->m_lpLabel ) { + HFONT hOldFont = (HFONT)::SelectObject( hDC, pHyperLink->m_hFont ); + ::DrawText( hDC, pHyperLink->m_lpLabel, -1, &pHyperLink->m_rcLabel, nDrawStyle | DT_WORDBREAK ); + ::SelectObject( hDC, hOldFont ); + } + + ::EndPaint( hWnd, &ps ); + } + return TRUE; + default: + break; + } + + return CallWindowProc( pHyperLink->m_lpfnOldWndProc, hWnd, msg, wParam, lParam ); + } + + HWND m_hWnd; + HFONT m_hFont; + HFONT m_hOldFont; + HCURSOR m_hCursor; + WNDPROC m_lpfnOldWndProc; + + RECT m_rcLabel; + + LPSTR m_lpLabel; + LPSTR m_lpHyperLink; +private: +}; + +#endif // !__CHYPERLINK_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/ChatDlg.cpp b/References/VirtuaNESex_src_191105/ChatDlg.cpp new file mode 100644 index 00000000..3b4a2775 --- /dev/null +++ b/References/VirtuaNESex_src_191105/ChatDlg.cpp @@ -0,0 +1,277 @@ +// +// `bg_CAONX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Config.h" + +#include "NetPlay.h" + +#include "Wnd.h" +#include "ChatDlg.h" + +// bZ[W +DLG_MESSAGE_BEGIN(CChatDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_DESTROY, OnDestroy ) +DLG_ON_MESSAGE( WM_CLOSE, OnClose ) +DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +DLG_ON_MESSAGE( WM_SETCURSOR, OnSetCursor ) +DLG_ON_MESSAGE( WM_SIZE, OnSize ) +DLG_ON_MESSAGE( WM_CTLCOLORSTATIC, OnControlColorStatic ) +DLG_ON_MESSAGE( WM_COPYDATA, OnCopyData ) + +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND_NOTIFY( IDC_NCT_MESSAGE, EN_SETFOCUS, OnMessageFocus ) +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDC_NCT_SEND, OnSend ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +BOOL CChatDlg::Create( HWND hWndParent ) +{ + // e̓fXNgbvɂ + m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_NETPLAY_CHAT), + NULL, g_DlgProc, (LPARAM)this ); + if( !m_hWnd ) + return FALSE; + + // [hX_CAOXgɉ + CWndList::Add( this ); + + return TRUE; +} + +void CChatDlg::Destroy() +{ + if( m_hWnd ) { + // [hX_CAOXg폜 + CWndList::Del( this ); + + ::GetWindowRect( m_hWnd, &Config.netplay.rcChatPos ); + + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +void CChatDlg::SetEditText() +{ + CHAR szText[256+1]; + + ::GetWindowText( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), szText, sizeof(szText)-1 ); + ::SetWindowText( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), "" ); + + if( ::strlen(szText) ) { + // clear message window + if( ::StrCmpI( szText, "/clear" ) == 0 ) { + ::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_SETSEL, 0, -1 ); + ::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, FALSE, (WPARAM)"" ); + return; + } + + string str; + + if( NetPlay.IsConnect() ) { + str = "("; + str = str + Config.netplay.szNick; + str = str + ") "; + } + + str = str + szText; + str = str + "\r\n"; + + // ɑM + if( NetPlay.IsConnect() ) { + NetPlay.ChatSend( (LPSTR)str.c_str() ); + } + + // g̃bZ[W\ + INT n = GetWindowTextLength( GetDlgItem( m_hWnd, IDC_NCT_MESSAGE ) ); + ::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_SETSEL, (WPARAM)n, (LPARAM)n ); + ::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)str.c_str() ); + } +} + +DLGMSG CChatDlg::OnCopyData( DLGMSGPARAM ) +{ + COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam; + CHAR* lpStr = (CHAR*)pcds->lpData; + + INT n = GetWindowTextLength( GetDlgItem( hWnd, IDC_NCT_MESSAGE ) ); + ::SendDlgItemMessage( hWnd, IDC_NCT_MESSAGE, EM_SETSEL, (WPARAM)n, (LPARAM)n ); + ::SendDlgItemMessage( hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)lpStr ); + + if( ::GetFocus() != m_hWnd && ::strlen( lpStr ) > 0 ) { + ::MessageBeep( MB_OK ); +// ::PlaySound( "MailBeep", NULL, SND_ALIAS|SND_ASYNC ); + } + + // bZ[W|bvAbv邽 + ::SendMessage( CApp::GetHWnd(), WM_VNS_CHATPOPUP, 0, 0 ); + + return TRUE; +} + +DLGMSG CChatDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CChatDlg::OnInitDialog\n" ); + + NetPlay.SetChatWnd( m_hWnd ); + + // ʒuۑ + ::GetClientRect( m_hWnd, &m_rcClient ); + ::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_MESSAGE), &m_rcMessage ); + ::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), &m_rcEdit ); + ::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_SEND), &m_rcButton ); + + // NCAgWւ̕ϊ + ::ScreenToClient( m_hWnd, (POINT*)&m_rcMessage.left ); + ::ScreenToClient( m_hWnd, (POINT*)&m_rcMessage.right ); + ::ScreenToClient( m_hWnd, (POINT*)&m_rcEdit.left ); + ::ScreenToClient( m_hWnd, (POINT*)&m_rcEdit.right ); + ::ScreenToClient( m_hWnd, (POINT*)&m_rcButton.left ); + ::ScreenToClient( m_hWnd, (POINT*)&m_rcButton.right ); + + // EChEʒu/TCY̐ݒ +// RECT rc = Config.launcher.rcWindowPos; +// if( (rc.right-rc.left) && (rc.bottom-rc.top) ) { +// ::SetWindowPos( m_hWnd, NULL, rc.left, rc.top, RCWIDTH(rc), RCHEIGHT(rc), SWP_NOZORDER ); +// } + + // EChEʒu/TCY̐ݒ + RECT rc = Config.netplay.rcChatPos; + if( (rc.right-rc.left) && (rc.bottom-rc.top) ) { + ::SetWindowPos( m_hWnd, NULL, rc.left, rc.top, RCWIDTH(rc), RCHEIGHT(rc), SWP_NOZORDER ); + } + + // \ + ::ShowWindow( m_hWnd, SW_SHOW ); + + return TRUE; +} + +DLGMSG CChatDlg::OnDestroy( DLGMSGPARAM ) +{ + return TRUE; +} + +DLGMSG CChatDlg::OnClose( DLGMSGPARAM ) +{ + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 + return TRUE; +} + +DLGMSG CChatDlg::OnActivate( DLGMSGPARAM ) +{ + if( LOWORD(wParam) == WA_INACTIVE ) { +// DEBUGOUT( "CChatDlg::OnActivate:Inactive\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 ); + + Config.InputKeyboardDisable( FALSE ); + } else { +// DEBUGOUT( "CChatDlg::OnActivate:Active\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 ); + + Config.InputKeyboardDisable( TRUE ); + } + return TRUE; +} + +DLGMSG CChatDlg::OnSetCursor( DLGMSGPARAM ) +{ +// DEBUGOUT( "CChatDlg::OnSetCursor\n" ); + return FALSE; +} + +DLGMSG CChatDlg::OnSize( DLGMSGPARAM ) +{ +// DEBUGOUT( "CChatDlg::OnSize\n" ); + HWND hWndCtrl; + RECT rcC, rcT; + ::GetClientRect( m_hWnd, &rcC ); + + // bZ[Wg + if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_MESSAGE )) ) { + rcT.left = rcC.left; + rcT.right = rcC.right; + rcT.top = rcC.top; + rcT.bottom = rcC.bottom - (m_rcClient.bottom-m_rcMessage.bottom); + ::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE ); + } + if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_EDIT )) ) { + rcT.left = rcC.left; + rcT.right = rcC.right - (m_rcClient.right-m_rcEdit.right); + rcT.top = rcC.bottom - (m_rcClient.bottom-m_rcEdit.top); + rcT.bottom = rcC.bottom - (m_rcClient.bottom-m_rcEdit.bottom); + ::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE ); + } + if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_SEND )) ) { + rcT.left = rcC.right - (m_rcClient.right-m_rcButton.left); + rcT.right = rcT.left + RCWIDTH(m_rcButton); + rcT.top = rcC.bottom - (m_rcClient.bottom-m_rcButton.top); + rcT.bottom = rcT.top + RCHEIGHT(m_rcButton); + ::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE ); + } + return FALSE; +} + +DLGMSG CChatDlg::OnControlColorStatic( DLGMSGPARAM ) +{ + if( (HWND)lParam == ::GetDlgItem( m_hWnd, IDC_NCT_MESSAGE ) ) { + SetBkColor( (HDC)wParam, (COLORREF)0x00FFFFFF ); + bResult = (LRESULT)GetStockObject( WHITE_BRUSH ); + return TRUE; + } + return FALSE; +} + +DLGCMD CChatDlg::OnMessageFocus( DLGCMDPARAM ) +{ + DEBUGOUT( "CChatDlg::OnMessageFocus\n" ); + +// ::SetFocus( ::GetDlgItem( m_hWnd, IDC_NCT_EDIT ) ); + ::SetFocus( m_hWnd ); +} + +DLGCMD CChatDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CChatDlg::OnOK\n" ); + SetEditText(); +} + +DLGCMD CChatDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CChatDlg::OnCancel\n" ); + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 +} + +DLGCMD CChatDlg::OnSend( DLGCMDPARAM ) +{ +// DEBUGOUT( "CChatDlg::OnSend\n" ); + SetEditText(); + + ::SetFocus( ::GetDlgItem( m_hWnd, IDC_NCT_EDIT ) ); +} + diff --git a/References/VirtuaNESex_src_191105/ChatDlg.h b/References/VirtuaNESex_src_191105/ChatDlg.h new file mode 100644 index 00000000..59e5346d --- /dev/null +++ b/References/VirtuaNESex_src_191105/ChatDlg.h @@ -0,0 +1,55 @@ +// +// `bg_CAONX +// +#ifndef __CCHATDLG_INCLUDED__ +#define __CCHATDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +using namespace std; + +#include "Wnd.h" + +class CChatDlg : public CWnd +{ +public: + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + + // Set Message + void SetEditText(); +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnDestroy( DLGMSGPARAM ); + DLGMSG OnClose( DLGMSGPARAM ); + DLGMSG OnActivate( DLGMSGPARAM ); + DLGMSG OnSetCursor( DLGMSGPARAM ); + DLGMSG OnSize( DLGMSGPARAM ); + + DLGMSG OnControlColorStatic( DLGMSGPARAM ); + + DLGMSG OnCopyData( DLGMSGPARAM ); + + DLGCMD OnMessageFocus( DLGCMDPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnSend( DLGCMDPARAM ); + // + + // ʒu + RECT m_rcClient; // NCAgGA + RECT m_rcMessage; // bZ[Wg + RECT m_rcEdit; // GfBbgg + RECT m_rcButton; // M{^ + +private: +}; + +#endif // !__CCHATDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/CheatDlg.cpp b/References/VirtuaNESex_src_191105/CheatDlg.cpp new file mode 100644 index 00000000..4b808e7e --- /dev/null +++ b/References/VirtuaNESex_src_191105/CheatDlg.cpp @@ -0,0 +1,1561 @@ +// +// `[g_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Config.h" + +#include "Wnd.h" +#include "CheatDlg.h" + +#include "EmuThread.h" + +// +// T[`_CAO +// +DLG_MESSAGE_BEGIN(CSearchDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +DLG_ON_MESSAGE( WM_CLOSE, OnClose ) +DLG_ON_MESSAGE( WM_CONTEXTMENU, OnContextMenu ) + +DLG_COMMAND_BEGIN() +//DLG_ON_COMMAND( IDOK, OnOK ) +//DLG_ON_COMMAND( IDCANCEL, OnCancel ) + +DLG_ON_COMMAND( IDC_SCH_START, OnStart ) +DLG_ON_COMMAND( IDC_SCH_UPDATE, OnUpdate ) +DLG_ON_COMMAND( IDC_SCH_UNDO, OnUndo ) + +DLG_ON_COMMAND_RANGE( IDC_SCH_RADIX_DEC, IDC_SCH_RADIX_HEX, OnRadixCommand ) +DLG_ON_COMMAND_RANGE( IDC_SCH_LENGTH_1BYTE, IDC_SCH_LENGTH_4BYTE, OnLengthCommand ) +DLG_ON_COMMAND_RANGE( IDC_SCH_EQUAL, IDC_SCH_GRATEREQUAL, OnSearchCommand ) + +DLG_ON_COMMAND( IDC_SCH_SEARCH, OnSearchData ) +DLG_ON_COMMAND( IDC_SCH_WRITE, OnWriteData ) + +DLG_ON_COMMAND( ID_SCH_APPEND, OnCodeAppend ) + +//DLG_ON_COMMAND( IDC_VER_WEBSITE, OnWebsite ) +DLG_COMMAND_END() + +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_ON_NOTIFY( IDC_SCH_RESULT_LIST, NM_DBLCLK, OnDoubleClickListView ) +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +BOOL CSearchDlg::Create( HWND hWndParent ) +{ + m_hMenu = NULL; + m_bShortCutDisable = FALSE; + + m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_SEARCH), + hWndParent, g_DlgProc, (LPARAM)this ); + if( !m_hWnd ) + return FALSE; + + // [hX_CAOXgɉ + CWndList::Add( this ); + + return TRUE; +} + +void CSearchDlg::Destroy() +{ + if( m_hWnd ) { + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcSearchDlgPos ); + + // j[폜 + if( m_hMenu ) + ::DestroyMenu( m_hMenu ); + m_hMenu = NULL; + + // [hX_CAOXg폜 + CWndList::Del( this ); + + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +void CSearchDlg::OnListUpdate() +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_SCH_RESULT_LIST ); + ListView_DeleteAllItems( hWndCtrl ); + + INT i; + DWORD data; + CHAR szStr[256], szTemp[256]; + INT index; + + LVITEM lvitem; + lvitem.mask = LVIF_TEXT|LVIF_PARAM; + lvitem.iSubItem = 0; + + index = 0; + + if( m_nRadix == 10 ) { + ::wsprintf( szTemp, "%%lu" ); + } else { + ::wsprintf( szTemp, "%%0%dX", (m_nLength+1)*2 ); + } + + if( IsBTNCHECK( IDC_SCH_AREA_RAM ) ) { + for( i = 0; i < 0x0800-m_nLength; i++ ) { + if( m_Result.RAM_F[i] ) { + // Address + ::wsprintf( szStr, "%04X", i ); + lvitem.pszText = szStr; + lvitem.iItem = index; + lvitem.lParam = (LPARAM)i; + ListView_InsertItem( hWndCtrl, &lvitem ); + + // OLD + data = GetSearchMemoryOld( m_nLength, i ); + ::wsprintf( szStr, szTemp, data ); + ListView_SetItemText( hWndCtrl, index, 1, (LPSTR)szStr ); + + // NEW + data = GetSearchMemory( m_nLength, i ); + ::wsprintf( szStr, szTemp, data ); + ListView_SetItemText( hWndCtrl, index, 2, (LPSTR)szStr ); + + index++; + } + } + } + + if( IsBTNCHECK( IDC_SCH_AREA_SRAM ) ) { + for( i = 0; i < 0x2000-m_nLength; i++ ) { + if( m_Result.SRAM_F[i] ) { + // Address + ::wsprintf( szStr, "%04X", i+0x6000 ); + lvitem.pszText = szStr; + lvitem.iItem = index; + lvitem.lParam = (LPARAM)(i+0x6000); + ListView_InsertItem( hWndCtrl, &lvitem ); + + // OLD + data = GetSearchMemoryOld( m_nLength, i+0x6000 ); + ::wsprintf( szStr, szTemp, data ); + ListView_SetItemText( hWndCtrl, index, 1, (LPSTR)szStr ); + + // NEW + data = GetSearchMemory( m_nLength, i+0x6000 ); + ::wsprintf( szStr, szTemp, data ); + ListView_SetItemText( hWndCtrl, index, 2, (LPSTR)szStr ); + + index++; + } + } + } + +} + +DWORD CSearchDlg::GetNesMemory( INT length, DWORD addr ) +{ + DWORD data = 0; + for( INT i = 0; i <= length; i++ ) { + data |= (DWORD)Emu.GetNES()->Read( (WORD)addr+i )*(1<<(i*8)); + } + + return data; +} + +DWORD CSearchDlg::GetSearchMemory( INT length, DWORD addr ) +{ + BYTE* lpRAM; + if( addr < 0x0800 ) { + lpRAM = m_Result.RAM_N; + } else if( addr < 0x8000 ) { + lpRAM = m_Result.SRAM_N - 0x6000; + } + + DWORD data = 0; + for( INT i = 0; i <= length; i++ ) { + data |= (DWORD)lpRAM[ (WORD)addr+i ]*(1<<(i*8)); + } + + return data; +} + +DWORD CSearchDlg::GetSearchMemoryOld( INT length, DWORD addr ) +{ + BYTE* lpRAM; + if( addr < 0x0800 ) { + lpRAM = m_Result.RAM_O; + } else if( addr < 0x8000 ) { + lpRAM = m_Result.SRAM_O - 0x6000; + } + + DWORD data = 0; + for( INT i = 0; i <= length; i++ ) { + data |= (DWORD)lpRAM[ (WORD)addr+i ]*(1<<(i*8)); + } + + return data; +} + +BOOL CSearchDlg::CompareData( INT type, DWORD dataA, DWORD dataB ) +{ + switch( type ) { + case 0: // EQUAL + if( dataA == dataB ) + return TRUE; + break; + case 1: // NOTEQUAL + if( dataA != dataB ) + return TRUE; + break; + + case 2: // LESS + if( dataA < dataB ) + return TRUE; + break; + case 3: // GRATER + if( dataA > dataB ) + return TRUE; + break; + + case 4: // LESSEQUAL + if( dataA <= dataB ) + return TRUE; + break; + case 5: // GRATEREQUAL + if( dataA >= dataB ) + return TRUE; + break; + } + + return FALSE; +} + +BOOL CSearchDlg::CompareRange( INT length, DWORD dataA, DWORD dataB, DWORD range ) +{ + DWORD dmin, dmax; + + switch( length ) { + case 0: // 1byte + dataA &= 0x000000FF; + dataB &= 0x000000FF; + range &= 0x000000FF; + + dmin = dataB-range; + dmax = dataB+range; + + if( dataB < dmin ) + dmin = 0; + if( dataB > dmax ) + dmax = 0xFF; + break; + + case 1: // 2byte + dataA &= 0x0000FFFF; + dataB &= 0x0000FFFF; + range &= 0x0000FFFF; + + dmin = dataB-range; + dmax = dataB+range; + + if( dataB < dmin ) + dmin = 0; + if( dataB > dmax ) + dmax = 0xFFFF; + break; + + case 2: // 3byte + dataA &= 0x00FFFFFF; + dataB &= 0x00FFFFFF; + range &= 0x00FFFFFF; + + dmin = dataB-range; + dmax = dataB+range; + + if( dataB < dmin ) + dmin = 0; + if( dataB > dmax ) + dmax = 0xFFFFFF; + break; + + case 3: // 4byte +// dataA &= 0xFFFFFFFF; +// dataB &= 0xFFFFFFFF; +// range &= 0xFFFFFFFF; + + dmin = dataB-range; + dmax = dataB+range; + + if( dataB < dmin ) + dmin = 0; + if( dataB > dmax ) + dmax = 0xFFFFFFFF; + break; + } + + if( dataA >= dmin && dataA <= dmax ) + return TRUE; + + return FALSE; +} + +DLGMSG CSearchDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnInitDialog\n" ); + + m_nRadix = 10; + m_nLength = 0; + + HWND hWndCtrl; + INT i, j; + CHAR szStr[256]; + + // ʒuC + if( Config.general.rcSearchDlgPos.right-Config.general.rcSearchDlgPos.left != 0 + && Config.general.rcSearchDlgPos.bottom-Config.general.rcSearchDlgPos.top != 0 ) { + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, Config.general.rcSearchDlgPos.left, Config.general.rcSearchDlgPos.top, + 0, 0, SWP_NOSIZE | SWP_NOZORDER ); + } + + // T[`ʏ + ::memset( &m_Result, 0, sizeof(m_Result) ); + ::memset( &m_ResultOld, 0, sizeof(m_ResultOld) ); + + // WI{^ + BTNCHECK( IDC_SCH_RADIX_DEC, TRUE ); +// BTNCHECK( IDC_SCH_RADIX_HEX, FALSE ); + + // f[^WI{^ + BTNCHECK( IDC_SCH_LENGTH_1BYTE, TRUE ); +// BTNCHECK( IDC_SCH_LENGTH_2BYTE, FALSE ); +// BTNCHECK( IDC_SCH_LENGTH_3BYTE, FALSE ); +// BTNCHECK( IDC_SCH_LENGTH_4BYTE, FALSE ); + + // ͈̓`FbN{bNX + BTNCHECK( IDC_SCH_AREA_RAM, TRUE ); + BTNCHECK( IDC_SCH_AREA_SRAM, FALSE ); + BTNCHECK( IDC_SCH_AREA_EXRAM, FALSE ); + + // Xgr[ + hWndCtrl = ::GetDlgItem( m_hWnd, IDC_SCH_RESULT_LIST ); + ListView_SetExtendedListViewStyle( hWndCtrl, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES ); + + ListView_DeleteAllItems( hWndCtrl ); + ListView_SetItemCount( hWndCtrl, 16384 ); + + // wb_Rg[̐ݒ + LVCOLUMN lvColumn; + lvColumn.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH; + lvColumn.fmt = LVCFMT_RIGHT; + lvColumn.pszText = szStr; + + RECT rc; + ::GetClientRect( hWndCtrl, &rc ); + INT nWidth = RCWIDTH(rc) - ::GetSystemMetrics( SM_CXVSCROLL ); + + CApp::LoadString( IDS_CHT_ADDRESS, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 0; + lvColumn.cx = nWidth*2/8; + ListView_InsertColumn( hWndCtrl, 0, &lvColumn ); + + CApp::LoadString( IDS_CHT_DATA_OLD, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 1; + lvColumn.cx = nWidth*3/8; + ListView_InsertColumn( hWndCtrl, 1, &lvColumn ); + + CApp::LoadString( IDS_CHT_DATA_NOW, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 2; + lvColumn.cx = nWidth*3/8; + ListView_InsertColumn( hWndCtrl, 2, &lvColumn ); + + // f[^ݒ + ::SetDlgItemText( m_hWnd, IDC_SCH_DATA_EDIT, "0" ); + + ::SetDlgItemText( m_hWnd, IDC_SCH_WADDR_EDIT, "0000" ); + ::SetDlgItemText( m_hWnd, IDC_SCH_WDATA_EDIT, "0" ); + + // Undo{^fBZ[u + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), FALSE ); + + // f[^ݒ + for( i = 0; i < 0x0800; i++ ) { + m_Result.RAM_N[i] = m_Result.RAM_O[i] = Emu.GetNES()->Read( (WORD)i ); + m_Result.RAM_F[i] = 1; + } + + j = 0; + BYTE da = Emu.GetNES()->Read( 0x6000 ); + for( i = 0; i < 0x2000; i++ ) { + m_Result.SRAM_N[i] = m_Result.SRAM_O[i] = Emu.GetNES()->Read( (WORD)i+0x6000 ); + m_Result.SRAM_F[i] = 1; + + if( m_Result.SRAM_N[i] != da ) + j = 1; + } + + // SRAMgpĂ玩ON + if( j ) { + BTNCHECK( IDC_SCH_AREA_SRAM, TRUE ); + } + + // j[ + m_hMenu = CApp::LoadMenu( IDR_SCH_MENU ); + m_hSubMenu = ::GetSubMenu( m_hMenu, 0 ); + + OnListUpdate(); + + return TRUE; +} + +DLGMSG CSearchDlg::OnActivate( DLGMSGPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnActivate\n" ); + + if( LOWORD(wParam) == WA_INACTIVE ) { + DEBUGOUT( "CSearchDlg::OnActivate:Inactive\n" ); + if( !m_bShortCutDisable ) + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 ); + + if( Emu.IsRunning() ) + Emu.Resume(); + } else { + DEBUGOUT( "CSearchDlg::OnActivate:Active\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 ); + + if( Emu.IsRunning() ) + Emu.Pause(); + } + + return FALSE; +} + +DLGMSG CSearchDlg::OnClose( DLGMSGPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnClose\n" ); + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 + return TRUE; +} + +DLGMSG CSearchDlg::OnContextMenu( DLGMSGPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnContextMenu\n" ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_SCH_RESULT_LIST ); + + POINT pt; + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + + LVHITTESTINFO lvhti; + + lvhti.pt = pt; + ::ScreenToClient( hWndCtrl, &lvhti.pt ); + + INT nItem = ListView_HitTest( hWndCtrl, &lvhti ); + +//DEBUGOUT( "OnContextMenu nItem=%d\n", nItem ); + if( nItem >= 0 ) { + CHAR szStr[256]; + ListView_GetItemText( hWndCtrl, nItem, 0, szStr, sizeof(szStr) ); + m_Address = (WORD)::strtoul( szStr, NULL, 16 ); + + ::TrackPopupMenu( m_hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN, pt.x, pt.y, 0, m_hWnd, NULL ); + } + + return TRUE; +} + +DLGCMD CSearchDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnOK\n" ); +// ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CSearchDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnCancel\n" ); + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 +} + +DLGCMD CSearchDlg::OnRadixCommand( DLGCMDPARAM ) +{ + if( uID == IDC_SCH_RADIX_DEC ) + m_nRadix = 10; + if( uID == IDC_SCH_RADIX_HEX ) + m_nRadix = 16; + + OnListUpdate(); +} + +DLGCMD CSearchDlg::OnLengthCommand( DLGCMDPARAM ) +{ + m_nLength = (INT)uID - IDC_SCH_LENGTH_1BYTE; + + OnListUpdate(); +} + +DLGCMD CSearchDlg::OnStart( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnStart\n" ); + + INT i; + + // Undoobt@ɃZ[u + m_ResultOld = m_Result; + + // f[^̏ + ::memset( &m_Result, 0, sizeof(m_Result) ); + + // f[^̐ݒ + if( IsBTNCHECK( IDC_SCH_AREA_RAM ) ) { + for( i = 0; i < 0x0800; i++ ) { + m_Result.RAM_N[i] = m_Result.RAM_O[i] = Emu.GetNES()->Read( (WORD)i ); + m_Result.RAM_F[i] = 1; + } + } + + if( IsBTNCHECK( IDC_SCH_AREA_SRAM ) ) { + for( i = 0; i < 0x2000; i++ ) { + m_Result.SRAM_N[i] = m_Result.SRAM_O[i] = Emu.GetNES()->Read( (WORD)i+0x6000 ); + m_Result.SRAM_F[i] = 1; + } + } + + OnListUpdate(); + + // Undo{^Cl[u + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), TRUE ); +} + +DLGCMD CSearchDlg::OnUpdate( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnUpdate\n" ); + + INT i; + + // Undoobt@ɃZ[u + m_ResultOld = m_Result; + + // f[^̍XV + if( IsBTNCHECK( IDC_SCH_AREA_RAM ) ) { + for( i = 0; i < 0x0800; i++ ) { + m_Result.RAM_O[i] = m_Result.RAM_N[i]; + m_Result.RAM_N[i] = Emu.GetNES()->Read( (WORD)i ); + } + } + + if( IsBTNCHECK( IDC_SCH_AREA_SRAM ) ) { + for( i = 0; i < 0x2000; i++ ) { + m_Result.SRAM_N[i] = m_Result.SRAM_O[i]; + m_Result.SRAM_N[i] = Emu.GetNES()->Read( (WORD)i+0x6000 ); + } + } + + OnListUpdate(); + + // Undo{^Cl[u + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), TRUE ); +} + +DLGCMD CSearchDlg::OnUndo( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnUndo\n" ); + +// // Undo + m_Result = m_ResultOld; + + OnListUpdate(); + + // Undo{^fBZ[u + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), FALSE ); +} + +DLGCMD CSearchDlg::OnSearchCommand( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnSearchCommand\n" ); + + INT i; + INT type = (INT)uID - IDC_SCH_EQUAL; + + // Undoobt@ɃZ[u + m_ResultOld = m_Result; + + // e| + struct RESULT ResultTemp; + ::memset( &ResultTemp, 0, sizeof(ResultTemp) ); + + // ̒Ō + if( IsBTNCHECK( IDC_SCH_AREA_RAM ) ) { + for( i = 0; i < 0x0800-m_nLength; i++ ) { + if( m_Result.RAM_F[i] ) { + if( CompareData( type, GetNesMemory( m_nLength, i ), GetSearchMemory( m_nLength, i ) ) ) { + ResultTemp.RAM_F[i] = 1; + } + } + } + // RAM̏ԂRs[ + for( i = 0; i < 0x0800; i++ ) { + ResultTemp.RAM_O[i] = m_Result.RAM_N[i]; + ResultTemp.RAM_N[i] = Emu.GetNES()->Read( (WORD)i ); + } + } + if( IsBTNCHECK( IDC_SCH_AREA_SRAM ) ) { + for( i = 0; i < 0x2000-m_nLength; i++ ) { + if( m_Result.SRAM_F[i] ) { + if( CompareData( type, GetNesMemory( m_nLength, i+0x6000 ), GetSearchMemory( m_nLength, i+0x6000 ) ) ) { + ResultTemp.SRAM_F[i] = 1; + } + } + } + // RAM̏ԂRs[ + for( i = 0; i < 0x2000; i++ ) { + ResultTemp.SRAM_O[i] = m_Result.SRAM_N[i]; + ResultTemp.SRAM_N[i] = Emu.GetNES()->Read( (WORD)i+0x6000 ); + } + } + + // e|f[^Rs[ + m_Result = ResultTemp; + + OnListUpdate(); + + // Undo{^Cl[u + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), TRUE ); +} + +DLGCMD CSearchDlg::OnSearchData( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnSearchData\n" ); + + INT i; + DWORD data; + CHAR szStr[256]; + + // Undoobt@ɃZ[u + m_ResultOld = m_Result; + + // f[^/W̎擾 + ::GetDlgItemText( m_hWnd, IDC_SCH_DATA_EDIT, szStr, sizeof(szStr) ); + if( m_nRadix == 10 ) { + ::GetDlgItemText( m_hWnd, IDC_SCH_DATA_EDIT, szStr, sizeof(szStr) ); + data = (DWORD)::strtoul( szStr, NULL, 10 ); + } else { + ::GetDlgItemText( m_hWnd, IDC_SCH_DATA_EDIT, szStr, sizeof(szStr) ); + data = (DWORD)::strtoul( szStr, NULL, 16 ); + } + + // e| + struct RESULT ResultTemp; + ::memset( &ResultTemp, 0, sizeof(ResultTemp) ); + + // ̒f[^Ɣ͈͂Ō + if( IsBTNCHECK( IDC_SCH_AREA_RAM ) ) { + for( i = 0; i < 0x0800-m_nLength; i++ ) { + if( m_Result.RAM_F[i] ) { + if( CompareData( 0, GetNesMemory( m_nLength, i ), data ) ) { + ResultTemp.RAM_F[i] = 1; + } + } + } + // RAM̏ԂRs[ + for( i = 0; i < 0x0800; i++ ) { + ResultTemp.RAM_O[i] = m_Result.RAM_O[i]; + ResultTemp.RAM_N[i] = Emu.GetNES()->Read( (WORD)i ); + } + } + if( IsBTNCHECK( IDC_SCH_AREA_SRAM ) ) { + for( i = 0; i < 0x2000-m_nLength; i++ ) { + if( m_Result.SRAM_F[i] ) { + if( CompareData( 0, GetNesMemory( m_nLength, i+0x6000 ), data ) ) { + ResultTemp.SRAM_F[i] = 1; + } + } + } + // RAM̏ԂRs[ + for( i = 0; i < 0x2000; i++ ) { + ResultTemp.SRAM_O[i] = m_Result.SRAM_O[i]; + ResultTemp.SRAM_N[i] = Emu.GetNES()->Read( (WORD)i+0x6000 ); + } + } + + // e|f[^Rs[ + m_Result = ResultTemp; + + OnListUpdate(); + + // Undo{^Cl[u + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), TRUE ); +} + +DLGCMD CSearchDlg::OnWriteData( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnWriteData\n" ); + + DWORD addr, data; + CHAR szStr[256]; + + // AhX/f[^̎擾 + ::GetDlgItemText( m_hWnd, IDC_SCH_WADDR_EDIT, szStr, sizeof(szStr) ); + addr = (DWORD)::strtoul( szStr, NULL, 16 ); + + if( m_nRadix == 10 ) { + ::GetDlgItemText( m_hWnd, IDC_SCH_WDATA_EDIT, szStr, sizeof(szStr) ); + data = (DWORD)::strtoul( szStr, NULL, 10 ); + } else { + ::GetDlgItemText( m_hWnd, IDC_SCH_WDATA_EDIT, szStr, sizeof(szStr) ); + data = (DWORD)::strtoul( szStr, NULL, 16 ); + } + + for( INT i = 0; i <= m_nLength; i++ ) { + Emu.GetNES()->Write( (WORD)(addr+i), data&0xFF ); + data >>= 8; + } +} + +DLGCMD CSearchDlg::OnCodeAppend( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSearchDlg::OnCodeAppend\n" ); + + if( Emu.IsRunning() ) + Emu.Pause(); + + CCheatCodeEditDlg dlg; + dlg.m_Code.enable = 1; + dlg.m_Code.address = m_Address; + dlg.m_Code.data = 0; + dlg.m_Code.length = m_nLength; + dlg.m_Code.type = CHEAT_TYPE_ALWAYS; + + dlg.m_nRadix = m_nRadix; + + m_bShortCutDisable = TRUE; + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + Emu.GetNES()->AddCheatCode( dlg.m_Code ); + } + + m_bShortCutDisable = FALSE; + + if( Emu.IsRunning() ) + Emu.Resume(); +} + +DLGNOTIFY CSearchDlg::OnDoubleClickListView( DLGNOTIFYPARAM ) +{ + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; +//DEBUGOUT( "Column click!! I:%d S:%d\n", pNMListView->iItem, pNMListView->iSubItem ); + + CHAR szStr[256]; + ListView_GetItemText( pNMHDR->hwndFrom, pNMListView->iItem, 0, szStr, sizeof(szStr) ); + + ::SetDlgItemText( m_hWnd, IDC_SCH_WADDR_EDIT, szStr ); +} + +// +// `[gR[hҏW_CAO +// +DLG_MESSAGE_BEGIN(CCheatCodeEditDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CCheatCodeEditDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CODEEDIT), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CCheatCodeEditDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CCheatCodeEditDlg::OnInitDialog\n" ); + + CHAR szStr[256], szTemp[256]; + + // AhX + ::wsprintf( szStr, "%04X", m_Code.address ); + ::SetDlgItemText( m_hWnd, IDC_CED_ADDR, szStr ); + + // f[^ + if( m_nRadix == 10 ) { + ::wsprintf( szStr, "%d", m_Code.data ); + } else { + ::wsprintf( szTemp, "%%0%dX", (m_Code.length+1)*2 ); + ::wsprintf( szStr, szTemp, m_Code.data ); + } + ::SetDlgItemText( m_hWnd, IDC_CED_DATA, szStr ); + + // Rg + ::SetDlgItemText( m_hWnd, IDC_CED_COMMENT, m_Code.comment.c_str() ); + + // WI{^ + BTNCHECK( (m_nRadix==10)?IDC_CED_RADIX_DEC:IDC_CED_RADIX_HEX, TRUE ); + BTNCHECK( (IDC_CED_LENGTH_1BYTE+m_Code.length), TRUE ); + + if( m_Code.type == CHEAT_TYPE_ALWAYS ) { + BTNCHECK( IDC_CED_TYPE_ALWAYS, TRUE ); + } else + if( m_Code.type == CHEAT_TYPE_ONCE ) { + BTNCHECK( IDC_CED_TYPE_ONCE, TRUE ); + } else + if( m_Code.type == CHEAT_TYPE_GREATER ) { + BTNCHECK( IDC_CED_TYPE_GREATER, TRUE ); + } else + if( m_Code.type == CHEAT_TYPE_LESS ) { + BTNCHECK( IDC_CED_TYPE_LESS, TRUE ); + } + + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 ); + + return TRUE; +} + +DLGCMD CCheatCodeEditDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeEditDlg::OnOK\n" ); + CHAR szStr[256]; + DWORD data; + + ::GetDlgItemText( m_hWnd, IDC_CED_DATA, szStr, sizeof(szStr) ); + if( IsBTNCHECK( IDC_CED_RADIX_DEC ) ) { + data = (DWORD)::strtoul( szStr, NULL, 10 ); + } else { + data = (DWORD)::strtoul( szStr, NULL, 16 ); + } + + if( IsBTNCHECK( IDC_CED_LENGTH_1BYTE ) ) { + data &= 0x000000FF; + m_Code.length = CHEAT_LENGTH_1BYTE; + } else + if( IsBTNCHECK( IDC_CED_LENGTH_2BYTE ) ) { + data &= 0x0000FFFF; + m_Code.length = CHEAT_LENGTH_2BYTE; + } else + if( IsBTNCHECK( IDC_CED_LENGTH_3BYTE ) ) { + data &= 0x00FFFFFF; + m_Code.length = CHEAT_LENGTH_3BYTE; + } else + if( IsBTNCHECK( IDC_CED_LENGTH_4BYTE ) ) { + m_Code.length = CHEAT_LENGTH_4BYTE; + } + + m_Code.data = data; + + if( IsBTNCHECK( IDC_CED_TYPE_ALWAYS ) ) { + m_Code.type = CHEAT_TYPE_ALWAYS; + } else + if( IsBTNCHECK( IDC_CED_TYPE_ONCE ) ) { + m_Code.type = CHEAT_TYPE_ONCE; + } else + if( IsBTNCHECK( IDC_CED_TYPE_GREATER ) ) { + m_Code.type = CHEAT_TYPE_GREATER; + } else + if( IsBTNCHECK( IDC_CED_TYPE_LESS ) ) { + m_Code.type = CHEAT_TYPE_LESS; + } + + ::GetDlgItemText( m_hWnd, IDC_CED_COMMENT, szStr, sizeof(szStr) ); + m_Code.comment = szStr; + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CCheatCodeEditDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeEditDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +// +// `[gR[h̓_CAO +// +DLG_MESSAGE_BEGIN(CCheatCodeInputDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CCheatCodeInputDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CODEINPUT), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CCheatCodeInputDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CCheatCodeInputDlg::OnInitDialog\n" ); + + ::SetDlgItemText( m_hWnd, IDC_CHC_CODE, m_Codes.c_str() ); + ::SetDlgItemText( m_hWnd, IDC_CHC_COMMENT, m_Comment.c_str() ); + + return TRUE; +} + +DLGCMD CCheatCodeInputDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeInputDlg::OnOK\n" ); + + CHAR szStr[256]; + + ::GetDlgItemText( m_hWnd, IDC_CHC_CODE, szStr, sizeof(szStr) ); + m_Codes = szStr; + + ::GetDlgItemText( m_hWnd, IDC_CHC_COMMENT, szStr, sizeof(szStr) ); + m_Comment = szStr; + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CCheatCodeInputDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeInputDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +// +// `[gR[h_CAO +// + +// bZ[W +DLG_MESSAGE_BEGIN(CCheatCodeDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_DESTROY, OnDestroy ) +DLG_ON_MESSAGE( WM_TIMER, OnTimer ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDC_CHT_ENABLE, OnEnable ) +DLG_ON_COMMAND( IDC_CHT_DISABLE, OnDisable ) +DLG_ON_COMMAND( IDC_CHT_CLEAR, OnClear ) +DLG_ON_COMMAND( IDC_CHT_REMOVE, OnRemove ) +DLG_ON_COMMAND( IDC_CHT_INPUT, OnInput ) +DLG_ON_COMMAND( IDC_CHT_EDIT, OnEdit ) +DLG_ON_COMMAND( IDC_CHT_LOAD, OnLoad ) +DLG_ON_COMMAND( IDC_CHT_SAVE, OnSave ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_ON_NOTIFY( IDC_CHT_CODE_LIST, LVN_KEYDOWN, OnKeyDownListView ) +DLG_ON_NOTIFY( IDC_CHT_CODE_LIST, NM_CLICK, OnClickListView ) +DLG_ON_NOTIFY( IDC_CHT_CODE_LIST, NM_DBLCLK, OnDblClkListView ) +DLG_NOTIFY_END() + +DLG_MESSAGE_END() + +INT CCheatCodeDlg::DoModal( HWND hWndParent ) +{ + m_hImageList = NULL; + + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CHEAT), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CCheatCodeDlg::OnListUpdate() +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CHT_CODE_LIST ); + ListView_DeleteAllItems( hWndCtrl ); + + INT i; + CHAR szStr[256], szTemp[256]; + + LVITEM lvitem; + lvitem.mask = LVIF_TEXT; + lvitem.iSubItem = 0; + + INT codenum = Emu.GetNES()->GetCheatCodeNum(); + + for( i = 0; i < codenum; i++ ) { + CHEATCODE code; + Emu.GetNES()->GetCheatCode( i, code ); + + // Code + ::wsprintf( szTemp, "%%04X-%%01d%%01d-%%0%dX", (code.length+1)*2 ); + ::wsprintf( szStr, szTemp, code.address, code.type, code.length+1, code.data ); + lvitem.pszText = szStr; + lvitem.iItem = i; + + ListView_InsertItem( hWndCtrl, &lvitem ); + + // Comment + ListView_SetItemText( hWndCtrl, i, 1, (LPSTR)code.comment.c_str() ); + + // State + ListView_SetItemState( hWndCtrl, i, INDEXTOSTATEIMAGEMASK(code.enable+1), LVIS_STATEIMAGEMASK ); + } +} + +DLGMSG CCheatCodeDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnInitDialog\n" ); + + HWND hWndCtrl; + CHAR szStr[256]; + + // Xgr[ + hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CHT_CODE_LIST ); +// ListView_SetExtendedListViewStyle( hWndCtrl, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES ); + ListView_SetExtendedListViewStyle( hWndCtrl, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES ); + ListView_DeleteAllItems( hWndCtrl ); + + // C[WXg̍쐬 + m_hImageList = ImageList_LoadBitmap( + CApp::GetInstance(), MAKEINTRESOURCE(IDB_CHEATIMAGELIST), + 16, 4, RGB(255,0,255) ); + + // C[WXgXgr[Ɋ蓖 + ListView_SetImageList( hWndCtrl, m_hImageList, LVSIL_STATE ); + + // wb_Rg[̐ݒ + LVCOLUMN lvColumn; + lvColumn.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH; + lvColumn.fmt = LVCFMT_LEFT; + lvColumn.pszText = szStr; + + RECT rc; + ::GetClientRect( hWndCtrl, &rc ); + INT nWidth = RCWIDTH(rc) - ::GetSystemMetrics( SM_CXVSCROLL ); + + CApp::LoadString( IDS_CHT_CHEATCODE, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 0; + lvColumn.cx = nWidth*2/5; + ListView_InsertColumn( hWndCtrl, 0, &lvColumn ); + + CApp::LoadString( IDS_CHT_COMMENT, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 1; + lvColumn.cx = nWidth*3/5; + ListView_InsertColumn( hWndCtrl, 1, &lvColumn ); + + // `[gR[hobNAbv(Cancelp) + INT codenum = Emu.GetNES()->GetCheatCodeNum(); + if( codenum > 0 ) { + CHEATCODE code; + + for( INT i = 0; i < codenum; i++ ) { + if( Emu.GetNES()->GetCheatCode( i, code ) ) { + m_CheatCode.push_back( code ); + } + } + } else { + m_CheatCode.clear(); + } + + OnListUpdate(); + + m_uTimerID = ::SetTimer( m_hWnd, 0x0001, 1000, NULL ); // 1sec + + return TRUE; +} + +DLGMSG CCheatCodeDlg::OnDestroy( DLGMSGPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnDestroy\n" ); + + ::KillTimer( m_hWnd, m_uTimerID ); + m_uTimerID = 0; + + if( m_hImageList ) { + ImageList_Destroy( m_hImageList ); + m_hImageList = NULL; + } + + return TRUE; +} + +DLGMSG CCheatCodeDlg::OnTimer( DLGMSGPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnTimer\n" ); + + if( Emu.GetNES()->IsCheatCodeAdd() ) { + OnListUpdate(); + } + + return TRUE; +} + +DLGNOTIFY CCheatCodeDlg::OnKeyDownListView( DLGNOTIFYPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnKeyDownListView\n" ); + + NMLVKEYDOWN* pNMKeyDown = (NMLVKEYDOWN*)pNMHDR; + + if( pNMKeyDown->wVKey != VK_SPACE ) + return; + + INT codenum = Emu.GetNES()->GetCheatCodeNum(); + + for( INT i = 0; i < codenum; i++ ) { + if( ListView_GetItemState( pNMKeyDown->hdr.hwndFrom, i, LVIS_SELECTED ) ) { + UINT state = ListView_GetItemState( pNMKeyDown->hdr.hwndFrom, i, LVIS_STATEIMAGEMASK ); + if( (state+=0x1000) > 0x4000 ) + state = 0x1000; + ListView_SetItemState( pNMKeyDown->hdr.hwndFrom, i, state, LVIS_STATEIMAGEMASK ); + + // R[hXV + CHEATCODE code; + if( Emu.GetNES()->GetCheatCode( i, code ) ) { + code.enable = (state>>12)-1; + Emu.GetNES()->ReplaceCheatCode( i, code ); + } + break; + } + } +} + +DLGNOTIFY CCheatCodeDlg::OnClickListView( DLGNOTIFYPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnClickListView\n" ); + + NMLISTVIEW* pNMListView = (NMLISTVIEW*)pNMHDR; + + LVHITTESTINFO lvht; + + lvht.pt = pNMListView->ptAction; + ListView_HitTest( pNMListView->hdr.hwndFrom, &lvht ); + + // Xe[gC[WȊO͋A + if( (lvht.flags&LVHT_NOWHERE) || (lvht.flags&LVHT_ONITEMLABEL) || lvht.iItem < 0 ) + return; + + // Xe[gACRȂ΍XV + if( lvht.flags & LVHT_ONITEMSTATEICON ) { + UINT state = ListView_GetItemState( pNMListView->hdr.hwndFrom, lvht.iItem, LVIS_STATEIMAGEMASK ); + if( (state+=0x1000) > 0x4000 ) + state = 0x1000; + ListView_SetItemState( pNMListView->hdr.hwndFrom, lvht.iItem, state, LVIS_STATEIMAGEMASK ); + + // R[hXV + CHEATCODE code; + if( Emu.GetNES()->GetCheatCode( lvht.iItem, code ) ) { + code.enable = (state>>12)-1; + Emu.GetNES()->ReplaceCheatCode( lvht.iItem, code ); + } + } +} + +DLGNOTIFY CCheatCodeDlg::OnDblClkListView( DLGNOTIFYPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnClickListView\n" ); + + NMLISTVIEW* pNMListView = (NMLISTVIEW*)pNMHDR; + + LVHITTESTINFO lvht; + + lvht.pt = pNMListView->ptAction; + ListView_HitTest( pNMListView->hdr.hwndFrom, &lvht ); + + // xȊO͋A + if( (lvht.flags&LVHT_NOWHERE) || !(lvht.flags&LVHT_ONITEMLABEL) || lvht.iItem < 0 ) + return; + + // GfBbgĂˁcƁB + ::PostMessage( m_hWnd, WM_COMMAND, (WPARAM)IDC_CHT_EDIT, (LPARAM)0 ); +} + +DLGCMD CCheatCodeDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnOK\n" ); + + // Ô + m_CheatCode.clear(); + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CCheatCodeDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnCancel\n" ); + + // obNAbvĂ`[gR[h߂ + Emu.GetNES()->CheatInitial(); + for( INT i = 0; i < m_CheatCode.size(); i++ ) { + Emu.GetNES()->AddCheatCode( m_CheatCode[i] ); + } + + // Ô + m_CheatCode.clear(); + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CCheatCodeDlg::OnEnable( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnEnable\n" ); + + Emu.GetNES()->SetCheatCodeAllFlag( TRUE, FALSE ); + OnListUpdate(); +} + +DLGCMD CCheatCodeDlg::OnDisable( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnDisable\n" ); + + Emu.GetNES()->SetCheatCodeAllFlag( FALSE, FALSE ); + OnListUpdate(); +} + +DLGCMD CCheatCodeDlg::OnClear( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnClear\n" ); + + Emu.GetNES()->CheatInitial(); + OnListUpdate(); +} + +DLGCMD CCheatCodeDlg::OnRemove( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnRemove\n" ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CHT_CODE_LIST ); + INT nCount = ListView_GetItemCount( hWndCtrl ); + + for( INT i = 0; i < nCount; i++ ) { + if( ListView_GetItemState( hWndCtrl, i, LVIS_SELECTED ) ) { + ListView_DeleteItem( hWndCtrl, i ); + // + Emu.GetNES()->DelCheatCode( i ); + break; + } + } +} + +DLGCMD CCheatCodeDlg::OnInput( DLGCMDPARAM ) +{ + DEBUGOUT( "CCheatCodeDlg::OnInput\n" ); + + CCheatCodeInputDlg dlg; + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + CHEATCODE code; + + if( ::strlen( dlg.m_Codes.c_str() ) < 10 ) + return; + + const UCHAR seps[] = " -\t\n\0"; // Zp[^ + CHAR szStr[256]; + + ::wsprintf( szStr, "%s", dlg.m_Codes.c_str() ); + + CHAR* pToken; + + // ԂŃCl[uɂ + code.enable = CHEAT_ENABLE; + + // Initial state + if( szStr[0] == '#' ) { + if( (pToken = (CHAR*)_mbstok( (UCHAR*)szStr, seps )) ) { + if( ::strlen(pToken) == 2 ) { + if( pToken[1] >= '0' && pToken[1] <= '3' ) { + code.enable = pToken[1] - '0'; + } + } + } + } + + // Address + if( szStr[0] != '#' ) { + if( !(pToken = (CHAR*)_mbstok( (UCHAR*)szStr, seps )) ) + return; + } else { + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + return; + } + + code.address = ::strtoul( pToken, NULL, 16 ); + // Type & Length + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + return; + code.type = pToken[0]-'0'; + code.length = pToken[1]-'1'; + if( code.type < CHEAT_TYPE_ALWAYS ) + code.type = CHEAT_TYPE_ALWAYS; + if( code.type > CHEAT_TYPE_LESS ) + code.type = CHEAT_TYPE_ALWAYS; + + if( code.length < CHEAT_LENGTH_1BYTE ) + code.length = CHEAT_LENGTH_1BYTE; + if( code.length > CHEAT_LENGTH_4BYTE ) + code.length = CHEAT_LENGTH_1BYTE; + + // Data + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + return; + code.data = ::strtoul( pToken, NULL, 16 ); + + // Comment + code.comment = dlg.m_Comment; + + // lj + Emu.GetNES()->AddCheatCode( code ); + // ^C}[ŌmȂ悤ɃtO + (void)Emu.GetNES()->IsCheatCodeAdd(); + + // XgXV + OnListUpdate(); + } +} + +DLGCMD CCheatCodeDlg::OnEdit( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnEdit\n" ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CHT_CODE_LIST ); + INT nCount = ListView_GetItemCount( hWndCtrl ); + INT i; + + for( i = 0; i < nCount; i++ ) { + if( ListView_GetItemState( hWndCtrl, i, LVIS_SELECTED ) ) { + CCheatCodeEditDlg dlg; + + if( Emu.GetNES()->GetCheatCode( i, dlg.m_Code ) ) { + dlg.m_nRadix = 16; + if( dlg.DoModal( m_hWnd ) == IDOK ) { + Emu.GetNES()->ReplaceCheatCode( i, dlg.m_Code ); + OnListUpdate(); + } + } + break; + } + } +} + +DLGCMD CCheatCodeDlg::OnLoad( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnLoad\n" ); + + string pathstr, tempstr; + if( Config.path.bCheatPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szCheatPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Emu.GetNES()->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Emu.GetNES()->rom->GetRomName(), "vct" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ::strcpy( szFile, tempstr.c_str() ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "Cheat Files(*.vct)\0*.vct\0All Files(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = pathstr.c_str(); + + CHAR szTitle[256], szTemp[256]; + + CApp::LoadString( IDS_UI_LOADCHEATCODE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetOpenFileName( &ofn ) ) { + FILE* fp = NULL; + + if( (fp = ::fopen( szFile, "r" )) ) { + // U + Emu.GetNES()->CheatInitial(); + + while( ::fgets( szTemp, sizeof(szTemp), fp ) ) { + if( szTemp[0] == ';' ) + continue; + + CHEATCODE code; + + if( ::strlen( szTemp ) < 10 ) + continue; + + const UCHAR seps[] = " -\t\n\0"; // Zp[^ + const UCHAR seps2[] = "\t\n\0"; // Zp[^ + const UCHAR seps3[] = "-\t\n\0"; // Zp[^ + + CHAR* pToken; + + code.enable = CHEAT_ENABLE; + + // Initial state + if( szTemp[0] == '#' ) { + if( !(pToken = (CHAR*)_mbstok( (UCHAR*)szTemp, seps )) ) + continue; + + if( ::strlen(pToken) == 2 ) { + if( pToken[1] >= '0' && pToken[1] <= '3' ) { + code.enable = pToken[1] - '0'; + } + } + } + + // Address + if( szTemp[0] != '#' ) { + if( !(pToken = (CHAR*)_mbstok( (UCHAR*)szTemp, seps )) ) + continue; + } else { + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + } + + if( ::strlen( pToken ) == 4 ) { + // VirtuaNES code + code.address = ::strtoul( pToken, NULL, 16 ); + // Type & Length + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + + if( ::strlen( pToken ) == 2 ) { + // VirtuaNES code + code.type = pToken[0]-'0'; + code.length = pToken[1]-'1'; + } else { + // NNNesterJ code? + code.type = CHEAT_TYPE_ALWAYS; + code.length = pToken[0]-'1'; + } + if( code.type < CHEAT_TYPE_ALWAYS ) + code.type = CHEAT_TYPE_ALWAYS; + if( code.type > CHEAT_TYPE_LESS ) + code.type = CHEAT_TYPE_ALWAYS; + + if( code.length < CHEAT_LENGTH_1BYTE ) + code.length = CHEAT_LENGTH_1BYTE; + if( code.length > CHEAT_LENGTH_4BYTE ) + code.length = CHEAT_LENGTH_1BYTE; + + // Data + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + code.data = ::strtoul( pToken, NULL, 16 ); + + // Comment + if( (pToken = (CHAR*)_mbstok( NULL, seps2 )) ) { + code.comment = pToken; + } else { + code.comment = ""; + } + } else if( ::strlen( pToken ) == 5 ) { + // NNNesterJ code? + if( pToken[0] == '0' ) { + code.address = ::strtoul( pToken+1, NULL, 16 ); + } else if( pToken[0] == '1' ) { + code.address = ::strtoul( pToken+1, NULL, 16 ); + code.address += 0x6000; + } + // Length + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + code.type = CHEAT_TYPE_ALWAYS; + code.length = pToken[1]-'1'; + if( code.length < CHEAT_LENGTH_1BYTE ) + code.length = CHEAT_LENGTH_1BYTE; + if( code.length > CHEAT_LENGTH_4BYTE ) + code.length = CHEAT_LENGTH_1BYTE; + + // Data + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + code.data = ::strtoul( pToken, NULL, 16 ); + + // Comment + if( (pToken = (CHAR*)_mbstok( NULL, seps3 )) ) { + code.comment = pToken; + } else { + code.comment = ""; + } + } + + // lj + Emu.GetNES()->AddCheatCode( code ); + // ^C}[ŌmȂ悤ɃtO + (void)Emu.GetNES()->IsCheatCodeAdd(); + } + // XgXV + OnListUpdate(); + } + FCLOSE( fp ); + } +} + +DLGCMD CCheatCodeDlg::OnSave( DLGCMDPARAM ) +{ +// DEBUGOUT( "CCheatCodeDlg::OnSave\n" ); + + INT codenum = Emu.GetNES()->GetCheatCodeNum(); + + if( !codenum ) + return; + + string pathstr, tempstr; + if( Config.path.bCheatPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szCheatPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Emu.GetNES()->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Emu.GetNES()->rom->GetRomName(), "vct" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ::strcpy( szFile, tempstr.c_str() ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "Cheat Files(*.vct)\0*.vct\0All Files(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = pathstr.c_str(); + + CHAR szTitle[256], szTemp[256], szTemp2[256]; + + ofn.Flags |= OFN_OVERWRITEPROMPT; + CApp::LoadString( IDS_UI_SAVECHEATCODE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetSaveFileName( &ofn ) ) { + FILE* fp = NULL; + + if( (fp = ::fopen( szFile, "w" )) ) { + ::fprintf( fp, "; %s\n", Emu.GetNES()->rom->GetRomName() ); + + // R[ht@Cɕۑ + CHEATCODE code; + for( INT i = 0; i < codenum; i++ ) { + Emu.GetNES()->GetCheatCode( i, code ); + // Code + ::wsprintf( szTemp, "#%01d %%04X-%%01d%%01d-%%0%dX", code.enable, (code.length+1)*2 ); + ::wsprintf( szTemp2, szTemp, code.address, code.type, code.length+1, code.data ); + ::fputs( szTemp2, fp ); + if( ::strlen(szTemp2) >= 16 ) + ::fprintf( fp, "\t%s\n", code.comment.c_str() ); + else + ::fprintf( fp, "\t\t%s\n", code.comment.c_str() ); + } + } + FCLOSE( fp ); + } +} + diff --git a/References/VirtuaNESex_src_191105/CheatDlg.h b/References/VirtuaNESex_src_191105/CheatDlg.h new file mode 100644 index 00000000..c4ddf7d3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/CheatDlg.h @@ -0,0 +1,175 @@ +// +// `[g_CAONX +// +#ifndef __CCHEATDLG_INCLUDED__ +#define __CCHEATDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +using namespace std; + +#include "Wnd.h" +#include "cheat.h" + +// T[`_CAO +class CSearchDlg : public CWnd +{ +public: + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + void OnListUpdate(); + + // Utils + DWORD GetNesMemory( INT length, DWORD addr ); + DWORD GetSearchMemory( INT length, DWORD addr ); + DWORD GetSearchMemoryOld( INT length, DWORD addr ); + + BOOL CompareData( INT type, DWORD dataA, DWORD dataB ); + BOOL CompareRange( INT length, DWORD dataA, DWORD dataB, DWORD range ); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnActivate( DLGMSGPARAM ); + DLGMSG OnClose( DLGMSGPARAM ); + + DLGMSG OnContextMenu( DLGMSGPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + + DLGCMD OnRadixCommand( DLGCMDPARAM ); + DLGCMD OnLengthCommand( DLGCMDPARAM ); + + DLGCMD OnStart( DLGCMDPARAM ); + DLGCMD OnUpdate( DLGCMDPARAM ); + DLGCMD OnUndo( DLGCMDPARAM ); + + DLGCMD OnSearchCommand( DLGCMDPARAM ); + DLGCMD OnSearchData( DLGCMDPARAM ); + DLGCMD OnWriteData( DLGCMDPARAM ); + + DLGCMD OnCodeAppend( DLGCMDPARAM ); + // + DLGNOTIFY OnDoubleClickListView( DLGNOTIFYPARAM ); + +private: + HMENU m_hMenu; + HMENU m_hSubMenu; + + BOOL m_bShortCutDisable; + + WORD m_Address; + + INT m_nRadix; + INT m_nLength; + + struct RESULT { + BYTE RAM_N[0x0800]; // RAM New value + BYTE RAM_O[0x0800]; // RAM Old value + BYTE RAM_F[0x0800]; // RAM Flag + + BYTE SRAM_N[0x2000]; // RAM New value + BYTE SRAM_O[0x2000]; // RAM Old value + BYTE SRAM_F[0x2000]; // RAM Flag + }; + + struct RESULT m_Result; // f[^ + struct RESULT m_ResultOld; // PO +}; + +// `[gR[hҏW_CAO +class CCheatCodeEditDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + + // + CHEATCODE m_Code; + INT m_nRadix; + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // +private: +}; + +// `[gR[h̓_CAO +class CCheatCodeInputDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + + string m_Codes; + string m_Comment; + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // +private: +}; + +// `[gR[h_CAO +class CCheatCodeDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + void OnListUpdate(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnDestroy( DLGMSGPARAM ); + DLGMSG OnTimer( DLGMSGPARAM ); + + DLGNOTIFY OnKeyDownListView( DLGNOTIFYPARAM ); + DLGNOTIFY OnClickListView( DLGNOTIFYPARAM ); + DLGNOTIFY OnDblClkListView( DLGNOTIFYPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + + DLGCMD OnEnable( DLGCMDPARAM ); + DLGCMD OnDisable( DLGCMDPARAM ); + DLGCMD OnClear( DLGCMDPARAM ); + DLGCMD OnRemove( DLGCMDPARAM ); + + DLGCMD OnInput( DLGCMDPARAM ); + DLGCMD OnEdit( DLGCMDPARAM ); + + DLGCMD OnLoad( DLGCMDPARAM ); + DLGCMD OnSave( DLGCMDPARAM ); + + // Image List + HIMAGELIST m_hImageList; + + // Timer + UINT m_uTimerID; + + // Temp buffer + vector m_CheatCode; + +private: +}; + +#endif // !__CCHEATDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Com.cpp b/References/VirtuaNESex_src_191105/Com.cpp new file mode 100644 index 00000000..321bba50 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Com.cpp @@ -0,0 +1,35 @@ +// +// COMpT|[gNX +// +#include +#include "DebugOut.h" +#include "Com.h" + +INT COM::m_nRefCount = 0; + +LRESULT COM::AddRef() +{ + if( !m_nRefCount ) { + HRESULT hr; + if( (hr = ::CoInitialize( NULL )) != S_OK ) { + DEBUGOUT( "COM::AddRef() CoInitialize failed.\n" ); + return hr; + } + DEBUGOUT( "COM::AddRef() CoInitialize.\n" ); + } + m_nRefCount++; + return 0L; +} + +void COM::Release() +{ + if( !m_nRefCount ) { + DEBUGOUT( "COM::Release() too many released.\n" ); + return; + } + if( !(--m_nRefCount) ) { + ::CoUninitialize(); + DEBUGOUT( "COM::AddRef() CoUninitialize.\n" ); + } +} + diff --git a/References/VirtuaNESex_src_191105/Com.h b/References/VirtuaNESex_src_191105/Com.h new file mode 100644 index 00000000..d34d1ded --- /dev/null +++ b/References/VirtuaNESex_src_191105/Com.h @@ -0,0 +1,21 @@ +// +// COMpT|[gNX +// +#ifndef __CCOM_INCLUDED__ +#define __CCOM_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +class COM +{ +public: + static LRESULT AddRef(); + static void Release(); + +protected: + static INT m_nRefCount; +}; + +#endif // !__CCOM_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Config.cpp b/References/VirtuaNESex_src_191105/Config.cpp new file mode 100644 index 00000000..1515611b --- /dev/null +++ b/References/VirtuaNESex_src_191105/Config.cpp @@ -0,0 +1,817 @@ +// +// ݒۑNX +// +#include "VirtuaNESres.h" +#include "DebugOut.h" + +#include "Config.h" +#include "Registry.h" + +#include "DirectInput.h" +#include "extsoundfile.h" + +// Global instance +CConfig Config; + +// Sampling rate table +INT CConfig::SamplingRateTable[] = { + 11025, 8, 11025, 16, 22050, 8, 22050, 16, + 44100, 8, 44100, 16, 48000, 8, 48000, 16, +}; + +// Shortcut key IDs table +INT CConfig::ShortcutKeyID[] = { + // Main controls + ID_OPEN, IDS_CUT_OPEN, 0, + ID_CLOSE, IDS_CUT_CLOSE, 1, + ID_LAUNCHER, IDS_CUT_LAUNCHER, 2, + + ID_NETPLAY_CONNECT, IDS_CUT_NETPLAY_CONNECT, 3, + ID_NETPLAY_DISCONNECT, IDS_CUT_NETPLAY_DISCONNECT, 4, + ID_NETPLAY_CHAT, IDS_CUT_NETPLAY_CHAT, 5, + + ID_ROMINFO, IDS_CUT_ROMINFO, 8, + ID_WAVERECORD, IDS_CUT_WAVERECORD, 9, + ID_EXIT, IDS_CUT_EXIT, 15, + + // Emulation controls + ID_HWRESET, IDS_CUT_HWRESET, 16, + ID_SWRESET, IDS_CUT_SWRESET, 17, + ID_PAUSE, IDS_CUT_PAUSE, 18, + ID_ONEFRAME, IDS_CUT_ONEFRAME, 23, + ID_THROTTLE, IDS_CUT_THROTTLE, 19, + ID_KEYTHROTTLE, IDS_CUT_KEYTHROTTLE, 24, + + ID_FRAMESKIP_AUTO, IDS_CUT_FRAMESKIP_AUTO, 20, + ID_FRAMESKIP_UP, IDS_CUT_FRAMESKIP_UP, 21, + ID_FRAMESKIP_DOWN, IDS_CUT_FRAMESKIP_DOWN, 22, + + // State controls + ID_STATE_LOAD, IDS_CUT_STATE_LOAD, 32, + ID_STATE_SAVE, IDS_CUT_STATE_SAVE, 33, + ID_STATE_UP, IDS_CUT_STATE_UP, 34, + ID_STATE_DOWN, IDS_CUT_STATE_DOWN, 35, + ID_STATE_SLOT0, IDS_CUT_STATE_SLOT0, 36, + ID_STATE_SLOT1, IDS_CUT_STATE_SLOT1, 37, + ID_STATE_SLOT2, IDS_CUT_STATE_SLOT2, 38, + ID_STATE_SLOT3, IDS_CUT_STATE_SLOT3, 39, + ID_STATE_SLOT4, IDS_CUT_STATE_SLOT4, 40, + ID_STATE_SLOT5, IDS_CUT_STATE_SLOT5, 41, + ID_STATE_SLOT6, IDS_CUT_STATE_SLOT6, 42, + ID_STATE_SLOT7, IDS_CUT_STATE_SLOT7, 43, + ID_STATE_SLOT8, IDS_CUT_STATE_SLOT8, 44, + ID_STATE_SLOT9, IDS_CUT_STATE_SLOT9, 45, + + // QuickLoad + ID_QUICKLOAD_SLOT0, IDS_CUT_QUICKLOAD_SLOT0, 256, + ID_QUICKLOAD_SLOT1, IDS_CUT_QUICKLOAD_SLOT1, 257, + ID_QUICKLOAD_SLOT2, IDS_CUT_QUICKLOAD_SLOT2, 258, + ID_QUICKLOAD_SLOT3, IDS_CUT_QUICKLOAD_SLOT3, 259, + ID_QUICKLOAD_SLOT4, IDS_CUT_QUICKLOAD_SLOT4, 260, + ID_QUICKLOAD_SLOT5, IDS_CUT_QUICKLOAD_SLOT5, 261, + ID_QUICKLOAD_SLOT6, IDS_CUT_QUICKLOAD_SLOT6, 262, + ID_QUICKLOAD_SLOT7, IDS_CUT_QUICKLOAD_SLOT7, 263, + ID_QUICKLOAD_SLOT8, IDS_CUT_QUICKLOAD_SLOT8, 264, + ID_QUICKLOAD_SLOT9, IDS_CUT_QUICKLOAD_SLOT9, 265, + // QuickSave + ID_QUICKSAVE_SLOT0, IDS_CUT_QUICKSAVE_SLOT0, 266, + ID_QUICKSAVE_SLOT1, IDS_CUT_QUICKSAVE_SLOT1, 267, + ID_QUICKSAVE_SLOT2, IDS_CUT_QUICKSAVE_SLOT2, 268, + ID_QUICKSAVE_SLOT3, IDS_CUT_QUICKSAVE_SLOT3, 269, + ID_QUICKSAVE_SLOT4, IDS_CUT_QUICKSAVE_SLOT4, 270, + ID_QUICKSAVE_SLOT5, IDS_CUT_QUICKSAVE_SLOT5, 271, + ID_QUICKSAVE_SLOT6, IDS_CUT_QUICKSAVE_SLOT6, 272, + ID_QUICKSAVE_SLOT7, IDS_CUT_QUICKSAVE_SLOT7, 273, + ID_QUICKSAVE_SLOT8, IDS_CUT_QUICKSAVE_SLOT8, 274, + ID_QUICKSAVE_SLOT9, IDS_CUT_QUICKSAVE_SLOT9, 275, + + // Disk controls + ID_DISK_EJECT, IDS_CUT_DISK_EJECT, 48, + ID_DISK_0A, IDS_CUT_DISK_0A, 49, + ID_DISK_0B, IDS_CUT_DISK_0B, 50, + ID_DISK_1A, IDS_CUT_DISK_1A, 51, + ID_DISK_1B, IDS_CUT_DISK_1B, 52, + + // Movie controls + ID_MOVIE_PLAY, IDS_CUT_MOVIE_PLAY, 56, + ID_MOVIE_REC, IDS_CUT_MOVIE_REC, 57, + ID_MOVIE_REC_APPEND, IDS_CUT_MOVIE_REC_APPEND, 58, + ID_MOVIE_STOP, IDS_CUT_MOVIE_STOP, 59, + ID_MOVIE_INFO, IDS_CUT_MOVIE_INFO, 60, + + // Screen controls + ID_ZOOMx1, IDS_CUT_ZOOMx1, 64, + ID_ZOOMx2, IDS_CUT_ZOOMx2, 65, + ID_ZOOMx3, IDS_CUT_ZOOMx3, 66, + ID_ZOOMx4, IDS_CUT_ZOOMx4, 67, + ID_FULLSCREEN, IDS_CUT_FULLSCREEN, 68, + + // Sound controls + ID_MUTE_0, IDS_CUT_MUTE_MASTER, 72, + ID_MUTE_1, IDS_CUT_MUTE_RECTANGLE1, 73, + ID_MUTE_2, IDS_CUT_MUTE_RECTANGLE2, 74, + ID_MUTE_3, IDS_CUT_MUTE_TRIANGLE, 75, + ID_MUTE_4, IDS_CUT_MUTE_NOISE, 76, + ID_MUTE_5, IDS_CUT_MUTE_DPCM, 77, + ID_MUTE_6, IDS_CUT_MUTE_EXTERNAL1, 78, + ID_MUTE_7, IDS_CUT_MUTE_EXTERNAL2, 79, + ID_MUTE_8, IDS_CUT_MUTE_EXTERNAL3, 80, + ID_MUTE_9, IDS_CUT_MUTE_EXTERNAL4, 81, + ID_MUTE_A, IDS_CUT_MUTE_EXTERNAL5, 82, + ID_MUTE_B, IDS_CUT_MUTE_EXTERNAL6, 83, + ID_MUTE_C, IDS_CUT_MUTE_EXTERNAL7, 84, + ID_MUTE_D, IDS_CUT_MUTE_EXTERNAL8, 85, + + // Tape controls + ID_TAPE_PLAY, IDS_CUT_TAPE_PLAY, 90, + ID_TAPE_REC, IDS_CUT_TAPE_REC, 91, + ID_TAPE_STOP, IDS_CUT_TAPE_STOP, 92, + + // Other controls + ID_SNAPSHOT, IDS_CUT_SNAPSHOT, 96, + ID_FPSDISP, IDS_CUT_FPSDISP, 97, + ID_TVASPECT, IDS_CUT_TVASPECT, 98, + ID_TVFRAME, IDS_CUT_TVFRAME, 99, + ID_SCANLINE, IDS_CUT_SCANLINE, 100, + ID_ALLLINE, IDS_CUT_ALLLINE, 101, + ID_ALLSPRITE, IDS_CUT_ALLSPRITE, 102, + ID_LEFTCLIP, IDS_CUT_LEFTCLIP, 105, + ID_SYNCDRAW, IDS_CUT_SYNCDRAW, 103, + ID_FITSCREEN, IDS_CUT_FITSCREEN, 104, + + // Tool controls + ID_SEARCH, IDS_CUT_SEARCH, 110, + ID_CHEAT, IDS_CUT_CHEAT, 111, + ID_CHEAT_ENABLE, IDS_CUT_CHEAT_ENABLE, 112, + ID_CHEAT_DISABLE, IDS_CUT_CHEAT_DISABLE, 113, + ID_GENIE, IDS_CUT_GENIE, 114, + + ID_VIEW_PATTERN, IDS_CUT_VIEW_PATTERN, 116, + ID_VIEW_NAMETABLE, IDS_CUT_VIEW_NAMETABLE, 117, + ID_VIEW_PALETTE, IDS_CUT_VIEW_PALETTE, 118, + + ID_VIEW_MEMORY, IDS_CUT_VIEW_MEMORY, 119, + + 0, 0, 0 +}; + +void CConfig::Load() +{ +INT i, j; +string ret; +string section; +CHAR keys[64]; +CHAR szTemp[MAX_PATH]; +WORD szKeyTemp[64]; + +// General + section = "General"; + + general.bDoubleExecute = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DoubleExecute", general.bDoubleExecute ); + general.bStartupLauncher = (BOOL)CRegistry::GetProfileInt( section.c_str(), "StartupLauncher", general.bStartupLauncher ); + +// general.bWindowSave = CRegistry::GetProfileInt( section.c_str(), "WindowPosSave", general.bWindowSave ); + general.bWindowZoom = CRegistry::GetProfileInt( section.c_str(), "WindowZoom", general.bWindowZoom ); + + RECT rc; + if( CRegistry::GetProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcWindowPos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "SearchDialogPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcSearchDlgPos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "PatternViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcPatternViewPos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "NameTableViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcNameTableViewPos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "PaletteViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcPaletteViewPos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "MemoryViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcMemoryViewPos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "BarcodePos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcBarcodePos = rc; + } + if( CRegistry::GetProfileBinary( section.c_str(), "PaletteEditPos", (LPBYTE)&rc, sizeof(RECT) ) ) { + general.rcPaletteEditPos = rc; + } + + general.nScreenZoom = CRegistry::GetProfileInt( section.c_str(), "ScreenZoom", general.nScreenZoom ); + + general.bNoJoystickID = (BOOL)CRegistry::GetProfileInt( section.c_str(), "NoJoystickID", general.bNoJoystickID ); + + general.nJoyAxisDisable = CRegistry::GetProfileInt( section.c_str(), "JoyAxisDisable", general.nJoyAxisDisable ); + + if( general.nJoyAxisDisable ) { + // ȑO̐ݒp + WORD bits = 0; + switch( general.nJoyAxisDisable ) { + case 1: + bits = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5); + break; + case 2: + bits = (1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5); + break; + case 3: + bits = (1<<2)|(1<<3)|(1<<4)|(1<<5); + break; + case 4: + bits = (1<<3)|(1<<4)|(1<<5); + break; + case 5: + bits = (1<<4)|(1<<5); + break; + case 6: + bits = (1<<5); + break; + } + for( i = 0; i < 16; i++ ) { + general.JoyAxisSetting[i] = bits; + } + + general.nJoyAxisDisable = 0; + } else { + if( CRegistry::GetProfileBinary( section.c_str(), "JoyAxisSetting", szKeyTemp, 16*sizeof(WORD) ) ) { + ::memcpy( general.JoyAxisSetting, szKeyTemp, 16*sizeof(WORD) ); + } + } +// Paths + section = "Path"; + + path.bRomAutoRunPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "RomAutoRunPathUse", path.bRomAutoRunPath ); + path.bRomPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "RomPathUse", path.bRomPath ); + path.bSavePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SavePathUse", path.bSavePath ); + path.bStatePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "StatePathUse", path.bStatePath ); + path.bSnapshotPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SnapshotPathUse", path.bSnapshotPath ); + path.bMoviePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "MoviePathUse", path.bMoviePath ); + path.bWavePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "WavePathUse", path.bWavePath ); + path.bCheatPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "CheatPathUse", path.bCheatPath ); + + if( CRegistry::GetProfileString(section.c_str(), "RomAutoRunPath", szTemp, sizeof(szTemp))) { + ::strcpy(path.szRomAutoRunPath, szTemp); + DEBUGOUT("RomAutoRunPath = %s\n", szTemp); + } else { + DEBUGOUT("RomAutoRunPath get failed! write default path\n"); + CRegistry::WriteProfileString( section.c_str(), "RomAutoRunPath", path.szRomAutoRunPath ); + } + + if( CRegistry::GetProfileString( section.c_str(), "RomPath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szRomPath, szTemp ); + if( CRegistry::GetProfileString( section.c_str(), "SavePath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szSavePath, szTemp ); + if( CRegistry::GetProfileString( section.c_str(), "StatePath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szStatePath, szTemp ); + if( CRegistry::GetProfileString( section.c_str(), "SnapshotPath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szSnapshotPath, szTemp ); + if( CRegistry::GetProfileString( section.c_str(), "MoviePath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szMoviePath, szTemp ); + if( CRegistry::GetProfileString( section.c_str(), "WavePath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szWavePath, szTemp ); + if( CRegistry::GetProfileString( section.c_str(), "CheatPath", szTemp, sizeof(szTemp) ) ) + ::strcpy( path.szCheatPath, szTemp ); + +// Emulator + section = "Emulation"; + + emulator.bIllegalOp = (BOOL)CRegistry::GetProfileInt( section.c_str(), "IllegalOp", emulator.bIllegalOp ); + emulator.bAutoFrameSkip = (BOOL)CRegistry::GetProfileInt( section.c_str(), "AutoFrameSkip", emulator.bAutoFrameSkip ); + emulator.bThrottle = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Throttle", emulator.bThrottle ); + emulator.nThrottleFPS = CRegistry::GetProfileInt( section.c_str(), "ThrottleFPS", emulator.nThrottleFPS ); + emulator.bBackground = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Background", emulator.bBackground ); + emulator.nPriority = CRegistry::GetProfileInt( section.c_str(), "Priority", emulator.nPriority ); + emulator.bFourPlayer = (BOOL)CRegistry::GetProfileInt( section.c_str(), "FourPlayer", emulator.bFourPlayer ); + emulator.bCrcCheck = (BOOL)CRegistry::GetProfileInt( section.c_str(), "CrcCheck", emulator.bCrcCheck ); + emulator.bDiskThrottle = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DiskThrottle", emulator.bDiskThrottle ); + emulator.bLoadFullscreen= (BOOL)CRegistry::GetProfileInt( section.c_str(), "LoadFullscreen",emulator.bLoadFullscreen ); + emulator.bPNGsnapshot = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PNGsnapshot", emulator.bPNGsnapshot ); + +// Graphic + section = "Graphics"; + + graphics.bAspect = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Aspect", graphics.bAspect ); + graphics.bAllSprite = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SpriteMax", graphics.bAllSprite ); + graphics.bAllLine = (BOOL)CRegistry::GetProfileInt( section.c_str(), "AllLine", graphics.bAllLine ); + graphics.bFPSDisp = (BOOL)CRegistry::GetProfileInt( section.c_str(), "FPSDisp", graphics.bFPSDisp ); + graphics.bTVFrame = (BOOL)CRegistry::GetProfileInt( section.c_str(), "TVFrameMode", graphics.bTVFrame ); + graphics.bScanline = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ScanlineMode", graphics.bScanline ); + graphics.nScanlineColor = CRegistry::GetProfileInt( section.c_str(), "ScanlineColor", graphics.nScanlineColor ); + graphics.bSyncDraw = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SyncDraw", graphics.bSyncDraw ); + graphics.bFitZoom = (BOOL)CRegistry::GetProfileInt( section.c_str(), "MaxZoom", graphics.bFitZoom ); + + graphics.bLeftClip = (BOOL)CRegistry::GetProfileInt( section.c_str(), "LeftClip", graphics.bLeftClip ); + + graphics.bWindowVSync = (BOOL)CRegistry::GetProfileInt( section.c_str(), "WindowVSync", graphics.bWindowVSync ); + graphics.bSyncNoSleep = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SyncNoSleep", graphics.bSyncNoSleep ); + + graphics.bDiskAccessLamp= (BOOL)CRegistry::GetProfileInt( section.c_str(), "DiskAccessLamp",graphics.bDiskAccessLamp ); + + graphics.bDoubleSize = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DoubleSize", graphics.bDoubleSize ); + graphics.bSystemMemory = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SystemMemory", graphics.bSystemMemory ); + graphics.bUseHEL = (BOOL)CRegistry::GetProfileInt( section.c_str(), "UseHEL", graphics.bUseHEL ); + + graphics.bNoSquareList = (BOOL)CRegistry::GetProfileInt( section.c_str(), "NoSquareList", graphics.bNoSquareList ); + + graphics.nGraphicsFilter= CRegistry::GetProfileInt( section.c_str(), "GraphicsFilter",graphics.nGraphicsFilter ); + + graphics.dwDisplayWidth = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayWidth", graphics.dwDisplayWidth ); + graphics.dwDisplayHeight = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayHeight", graphics.dwDisplayHeight ); + graphics.dwDisplayDepth = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayDepth", graphics.dwDisplayDepth ); + graphics.dwDisplayRate = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayRate", graphics.dwDisplayRate ); + + graphics.bPaletteFile = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PaletteUse", graphics.bPaletteFile ); + + if( CRegistry::GetProfileString( section.c_str(), "PaletteFile", szTemp, sizeof(szTemp) ) ) + ::strcpy( graphics.szPaletteFile, szTemp ); + +// Sound + section = "Sound"; + + sound.bEnable = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Enable", sound.bEnable ); + sound.nRate = CRegistry::GetProfileInt( section.c_str(), "SamplingRate", sound.nRate ); + sound.nBits = CRegistry::GetProfileInt( section.c_str(), "SamplingBits", sound.nBits ); + sound.nBufferSize = CRegistry::GetProfileInt( section.c_str(), "BufferSize", sound.nBufferSize ); + sound.nFilterType = CRegistry::GetProfileInt( section.c_str(), "FilterType", sound.nFilterType ); + + sound.bChangeTone = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ChangeTone", sound.bChangeTone ); + + sound.bDisableVolumeEffect = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DisableVolumeEffect", sound.bDisableVolumeEffect ); + sound.bExtraSoundEnable = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ExtraSoundEnable", sound.bExtraSoundEnable ); + + if( CRegistry::GetProfileBinary( section.c_str(), "Volume", szTemp, sizeof(sound.nVolume) ) ) + ::memcpy( sound.nVolume, szTemp, sizeof(sound.nVolume) ); + +// ShortCuts + section = "ShortCut"; + for( i = 0; i < sizeof(shortcut.nShortCut)/(16*sizeof(WORD)); i++ ) { + ::wsprintf( keys, "Tbl%02d", i ); + if( CRegistry::GetProfileBinary( section.c_str(), keys, szTemp, 16*sizeof(WORD) ) ) + ::memcpy( &shortcut.nShortCut[i*16], szTemp, 16*sizeof(WORD) ); + } + +// Controllers + for( i = 0; i < 4; i++ ) { + ::wsprintf( keys, "Controller %d", i+1 ); + if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 64*sizeof(WORD) ) ) { + ::memcpy( controller.nButton[i], szKeyTemp, 64*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 32*sizeof(WORD) ) ) { + // Âݒpׂ̑[u + ::memcpy( &controller.nButton[i][ 0], &szKeyTemp[ 0], 16*sizeof(WORD) ); + ::memcpy( &controller.nButton[i][32], &szKeyTemp[16], 16*sizeof(WORD) ); + ::memcpy( controller.nButton[i], szKeyTemp, 32*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 20*sizeof(WORD) ) ) { + // Âݒpׂ̑[u + ::memcpy( &controller.nButton[i][ 0], &szKeyTemp[ 0], 10*sizeof(WORD) ); + ::memcpy( &controller.nButton[i][32], &szKeyTemp[10], 10*sizeof(WORD) ); + // Mic̕ύX + if( i == 1 ) { + controller.nButton[i][10] = szKeyTemp[ 8]; + controller.nButton[i][ 8] = 0; + controller.nButton[i][42] = szKeyTemp[18]; + controller.nButton[i][40] = 0; + } + } else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 10*sizeof(WORD) ) ) { + // Âݒpׂ̑[u + ::memcpy( controller.nButton[i], szKeyTemp, 10*sizeof(WORD) ); + // Mic̕ύX + if( i == 1 ) { + controller.nButton[i][10] = szKeyTemp[ 8]; + controller.nButton[i][ 8] = 0; + } + } + if( CRegistry::GetProfileBinary( keys, "Rapid", szTemp, 2*sizeof(WORD) ) ) + ::memcpy( controller.nRapid[i], szTemp, 2*sizeof(WORD) ); + } + +// ExControllers + for( i = 0; i < 4; i++ ) { + if( i == 0 ) section = "Crazy Climber"; + if( i == 1 ) section = "Family Trainer"; + if( i == 2 ) section = "Exciting Boxing"; + if( i == 3 ) section = "Mahjang"; + + if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) { + ::memcpy( controller.nExButton[i], szKeyTemp, 64*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 32*sizeof(WORD) ) ) { + ::memcpy( &controller.nExButton[i][ 0], &szKeyTemp[ 0], 16*sizeof(WORD) ); + ::memcpy( &controller.nExButton[i][32], &szKeyTemp[16], 16*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 20*sizeof(WORD) ) ) { + // Âݒpׂ̑[u + ::memcpy( &controller.nExButton[i][ 0], &szKeyTemp[ 0], 10*sizeof(WORD) ); + ::memcpy( &controller.nExButton[i][32], &szKeyTemp[10], 10*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 10*sizeof(WORD) ) ) { + // Âݒpׂ̑[u + ::memcpy( controller.nExButton[i], szKeyTemp, 10*sizeof(WORD) ); + } + } + +// NSF Contoller + section = "NSF controller"; + if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) { + ::memcpy( controller.nNsfButton, szKeyTemp, 64*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 32*sizeof(WORD) ) ) { + ::memcpy( &controller.nNsfButton[ 0], &szKeyTemp[ 0], 16*sizeof(WORD) ); + ::memcpy( &controller.nNsfButton[32], &szKeyTemp[16], 16*sizeof(WORD) ); + } else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 20*sizeof(WORD) ) ) { + // Âݒpׂ̑[u + ::memcpy( &controller.nNsfButton[ 0], &szKeyTemp[ 0], 10*sizeof(WORD) ); + ::memcpy( &controller.nNsfButton[32], &szKeyTemp[10], 10*sizeof(WORD) ); + } + +// VS-Unisystem + section = "VS-Unisystem"; + if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) { + ::memcpy( controller.nVSUnisystem, szKeyTemp, 64*sizeof(WORD) ); + } + +// Movie + section = "Movie"; + if( CRegistry::GetProfileBinary( section.c_str(), "UsePlayer", szTemp, sizeof(movie.bUsePlayer) ) ) + ::memcpy( movie.bUsePlayer, szTemp, sizeof(movie.bUsePlayer) ); + movie.bResetRec = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ResetRec", movie.bResetRec ); + movie.bRerecord = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Rerecord", movie.bRerecord ); + movie.bLoopPlay = (BOOL)CRegistry::GetProfileInt( section.c_str(), "LoopPlay", movie.bLoopPlay ); + movie.bPadDisplay = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PadDisplay", movie.bPadDisplay ); + +// Launcher + section = "Launcher"; + + if( CRegistry::GetProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&rc, sizeof(RECT) ) ) + launcher.rcWindowPos = rc; + if( CRegistry::GetProfileBinary( section.c_str(), "ColumnView", szTemp, sizeof(launcher.bHeaderView) ) ) + ::memcpy( launcher.bHeaderView, szTemp, sizeof(launcher.bHeaderView) ); + if( CRegistry::GetProfileBinary( section.c_str(), "ColumnOrder", szTemp, sizeof(launcher.nHeaderOrder) ) ) + ::memcpy( launcher.nHeaderOrder, szTemp, sizeof(launcher.nHeaderOrder) ); + if( CRegistry::GetProfileBinary( section.c_str(), "ColumnWidth", szTemp, sizeof(launcher.nHeaderWidth) ) ) + ::memcpy( launcher.nHeaderWidth, szTemp, sizeof(launcher.nHeaderWidth) ); + + launcher.nListSelect = CRegistry::GetProfileInt( section.c_str(), "ListSelect", launcher.nListSelect ); + + launcher.bSortDir = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SortDir", launcher.bSortDir ); + launcher.nSortType = CRegistry::GetProfileInt( section.c_str(), "SortType", launcher.nSortType ); + + if( CRegistry::GetProfileBinary( section.c_str(), "ColumnSort", szTemp, sizeof(launcher.nHeaderWidth) ) ) + ::memcpy( launcher.nHeaderWidth, szTemp, sizeof(launcher.nHeaderWidth) ); + + if( CRegistry::GetProfileBinary( section.c_str(), "FolderUse", szTemp, sizeof(launcher.bFolderUse) ) ) + ::memcpy( launcher.bFolderUse, szTemp, sizeof(launcher.bFolderUse) ); + + for( i = 0; i < 16; i++ ) { + ::wsprintf( keys, "Folder%02d", i ); + if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) ) + ::strcpy( launcher.szFolder[i], szTemp ); + } + + if( CRegistry::GetProfileString( section.c_str(), "LastSelect", szTemp, sizeof(szTemp) ) ) + ::strcpy( launcher.szLastSelect, szTemp ); + + launcher.bActivePause = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ActivePause", launcher.bActivePause ); + +// ExtraSound + section = "ExtraSound"; + + for( i = ESF_MOEPRO_STRIKE; i <= ESF_MOEPRO_WA; i++ ) { + ::wsprintf( keys, "Moepro%02d", i ); + if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) ) + ::strcpy( extsound.szExtSoundFile[i], szTemp ); + } + + for( i = ESF_DISKSYSTEM_BOOT, j = 0; i <= ESF_DISKSYSTEM_SEEKEND; i++, j++ ) { + ::wsprintf( keys, "DiskSound%02d", j ); + if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) ) + ::strcpy( extsound.szExtSoundFile[i], szTemp ); + } + +// NetPlay + section = "Netplay"; + + if( CRegistry::GetProfileBinary( section.c_str(), "ChatPos", (LPBYTE)&rc, sizeof(RECT) ) ) + netplay.rcChatPos = rc; + + if( CRegistry::GetProfileString( section.c_str(), "NickName", szTemp, sizeof(szTemp) ) ) + ::strcpy( netplay.szNick, szTemp ); + + netplay.nRecentPort = CRegistry::GetProfileInt( section.c_str(), "RecnetPortNum", netplay.nRecentPort ); + for( i = 0; i < netplay.nRecentPort; i++ ) { + ::wsprintf( keys, "RecentPort%02d", i ); + if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) ) + ::strcpy( netplay.szRecentPort[i], szTemp ); + } + + netplay.nRecentHost = CRegistry::GetProfileInt( section.c_str(), "RecnetHostNum", netplay.nRecentHost ); + for( i = 0; i < netplay.nRecentHost; i++ ) { + ::wsprintf( keys, "RecentHost%02d", i ); + if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) ) + ::strcpy( netplay.szRecentHost[i], szTemp ); + } +} + +void CConfig::Save() +{ +INT i; +string section; +CHAR keys[64]; + +// General + section = "General"; + + CRegistry::WriteProfileInt ( section.c_str(), "DoubleExecute", general.bDoubleExecute ); + CRegistry::WriteProfileInt ( section.c_str(), "StartupLauncher", general.bStartupLauncher ); + +// CRegistry::WriteProfileInt( section.c_str(), "WindowPosSave", general.bWindowSave ); + CRegistry::WriteProfileInt ( section.c_str(), "WindowZoom", general.bWindowZoom ); + CRegistry::WriteProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&general.rcWindowPos, sizeof(RECT) ); + CRegistry::WriteProfileInt ( section.c_str(), "ScreenZoom", general.nScreenZoom ); + + CRegistry::WriteProfileBinary( section.c_str(), "SearchDialogPos", (LPBYTE)&general.rcSearchDlgPos, sizeof(RECT) ); + + CRegistry::WriteProfileBinary( section.c_str(), "PatternViewPos", (LPBYTE)&general.rcPatternViewPos, sizeof(RECT) ); + CRegistry::WriteProfileBinary( section.c_str(), "NameTableViewPos", (LPBYTE)&general.rcNameTableViewPos, sizeof(RECT) ); + CRegistry::WriteProfileBinary( section.c_str(), "PaletteViewPos", (LPBYTE)&general.rcPaletteViewPos, sizeof(RECT) ); + CRegistry::WriteProfileBinary( section.c_str(), "MemoryViewPos", (LPBYTE)&general.rcMemoryViewPos, sizeof(RECT) ); + + CRegistry::WriteProfileBinary( section.c_str(), "BarcodePos", (LPBYTE)&general.rcBarcodePos, sizeof(RECT) ); + + CRegistry::WriteProfileBinary( section.c_str(), "PaletteEditPos", (LPBYTE)&general.rcPaletteEditPos, sizeof(RECT) ); + + CRegistry::WriteProfileInt ( section.c_str(), "JoyAxisDisable", general.nJoyAxisDisable ); + CRegistry::WriteProfileBinary( section.c_str(), "JoyAxisSetting", (LPBYTE)general.JoyAxisSetting, 16*sizeof(WORD) ); + +// Paths + section = "Path"; + + CRegistry::WriteProfileInt( section.c_str(), "RomPathUse", path.bRomPath ); + CRegistry::WriteProfileInt( section.c_str(), "SavePathUse", path.bSavePath ); + CRegistry::WriteProfileInt( section.c_str(), "StatePathUse", path.bStatePath ); + CRegistry::WriteProfileInt( section.c_str(), "SnapshotPathUse", path.bSnapshotPath ); + CRegistry::WriteProfileInt( section.c_str(), "MoviePathUse", path.bMoviePath ); + CRegistry::WriteProfileInt( section.c_str(), "WavePathUse", path.bWavePath ); + CRegistry::WriteProfileInt( section.c_str(), "CheatPathUse", path.bCheatPath ); + + CRegistry::WriteProfileString( section.c_str(), "RomAutoRunPath", path.szRomAutoRunPath ); + CRegistry::WriteProfileString( section.c_str(), "RomPath", path.szRomPath ); + CRegistry::WriteProfileString( section.c_str(), "SavePath", path.szSavePath ); + CRegistry::WriteProfileString( section.c_str(), "StatePath", path.szStatePath ); + CRegistry::WriteProfileString( section.c_str(), "SnapshotPath", path.szSnapshotPath ); + CRegistry::WriteProfileString( section.c_str(), "MoviePath", path.szMoviePath ); + CRegistry::WriteProfileString( section.c_str(), "WavePath", path.szWavePath ); + CRegistry::WriteProfileString( section.c_str(), "CheatPath", path.szCheatPath ); + +// Emulation + section = "Emulation"; + + CRegistry::WriteProfileInt( section.c_str(), "IllegalOp", emulator.bIllegalOp ); + CRegistry::WriteProfileInt( section.c_str(), "AutoFrameSkip", emulator.bAutoFrameSkip ); + CRegistry::WriteProfileInt( section.c_str(), "Throttle", emulator.bThrottle ); + CRegistry::WriteProfileInt( section.c_str(), "ThrottleFPS", emulator.nThrottleFPS ); + CRegistry::WriteProfileInt( section.c_str(), "Background", emulator.bBackground ); + CRegistry::WriteProfileInt( section.c_str(), "Priority", emulator.nPriority ); + CRegistry::WriteProfileInt( section.c_str(), "FourPlayer", emulator.bFourPlayer ); + CRegistry::WriteProfileInt( section.c_str(), "CrcCheck", emulator.bCrcCheck ); + CRegistry::WriteProfileInt( section.c_str(), "DiskThrottle", emulator.bDiskThrottle ); + CRegistry::WriteProfileInt( section.c_str(), "LoadFullscreen",emulator.bLoadFullscreen ); + CRegistry::WriteProfileInt( section.c_str(), "PNGsnapshot", emulator.bPNGsnapshot ); + +// Graphic + section = "Graphics"; + + CRegistry::WriteProfileInt( section.c_str(), "Aspect", graphics.bAspect ); + CRegistry::WriteProfileInt( section.c_str(), "SpriteMax", graphics.bAllSprite ); + CRegistry::WriteProfileInt( section.c_str(), "AllLine", graphics.bAllLine ); + CRegistry::WriteProfileInt( section.c_str(), "FPSDisp", graphics.bFPSDisp ); + CRegistry::WriteProfileInt( section.c_str(), "TVFrameMode", graphics.bTVFrame ); + CRegistry::WriteProfileInt( section.c_str(), "ScanlineMode", graphics.bScanline ); + CRegistry::WriteProfileInt( section.c_str(), "ScanlineColor", graphics.nScanlineColor ); + CRegistry::WriteProfileInt( section.c_str(), "SyncDraw", graphics.bSyncDraw ); + CRegistry::WriteProfileInt( section.c_str(), "MaxZoom", graphics.bFitZoom ); + + CRegistry::WriteProfileInt( section.c_str(), "LeftClip", graphics.bLeftClip ); + + CRegistry::WriteProfileInt( section.c_str(), "WindowVSync", graphics.bWindowVSync ); + + CRegistry::WriteProfileInt( section.c_str(), "DiskAccessLamp",graphics.bDiskAccessLamp ); + + CRegistry::WriteProfileInt( section.c_str(), "DoubleSize", graphics.bDoubleSize ); + CRegistry::WriteProfileInt( section.c_str(), "SystemMemory", graphics.bSystemMemory ); + CRegistry::WriteProfileInt( section.c_str(), "UseHEL", graphics.bUseHEL ); + + CRegistry::WriteProfileInt( section.c_str(), "NoSquareList", graphics.bNoSquareList ); + + CRegistry::WriteProfileInt( section.c_str(), "GraphicsFilter",graphics.nGraphicsFilter ); + + CRegistry::WriteProfileInt( section.c_str(), "DisplayWidth", graphics.dwDisplayWidth ); + CRegistry::WriteProfileInt( section.c_str(), "DisplayHeight", graphics.dwDisplayHeight ); + CRegistry::WriteProfileInt( section.c_str(), "DisplayDepth", graphics.dwDisplayDepth ); + CRegistry::WriteProfileInt( section.c_str(), "DisplayRate", graphics.dwDisplayRate ); + + CRegistry::WriteProfileInt( section.c_str(), "PaletteUse", graphics.bPaletteFile ); + CRegistry::WriteProfileString( section.c_str(), "PaletteFile", graphics.szPaletteFile ); + +// Sound + section = "Sound"; + + CRegistry::WriteProfileInt( section.c_str(), "Enable", sound.bEnable ); + + CRegistry::WriteProfileInt( section.c_str(), "DisableVolumeEffect", sound.bDisableVolumeEffect ); + CRegistry::WriteProfileInt( section.c_str(), "ExtraSoundEnable", sound.bExtraSoundEnable ); + + CRegistry::WriteProfileInt( section.c_str(), "SamplingRate", sound.nRate ); + CRegistry::WriteProfileInt( section.c_str(), "SamplingBits", sound.nBits ); + CRegistry::WriteProfileInt( section.c_str(), "BufferSize", sound.nBufferSize ); + CRegistry::WriteProfileInt( section.c_str(), "FilterType", sound.nFilterType ); + + CRegistry::WriteProfileBinary( section.c_str(), "Volume", (LPBYTE)sound.nVolume, sizeof(sound.nVolume) ); + +// ShortCut + section = "ShortCut"; + for( i = 0; i < sizeof(shortcut.nShortCut)/(16*sizeof(WORD)); i++ ) { + ::wsprintf( keys, "TBL%02d", i ); + CRegistry::WriteProfileBinary( section.c_str(), keys, (LPBYTE)&shortcut.nShortCut[i*16], 16*sizeof(WORD) ); + } + +// Controllers + for( i = 0; i < 4; i++ ) { + ::wsprintf( keys, "Controller %01d", i+1 ); + CRegistry::WriteProfileBinary( keys, "Keys", (LPBYTE)controller.nButton[i], 64*sizeof(WORD) ); + CRegistry::WriteProfileBinary( keys, "Rapid", (LPBYTE)controller.nRapid[i], 2*sizeof(WORD) ); + } + +// ExControllers + section = "Crazy Climber"; + CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[0], 64*sizeof(WORD) ); + section = "Family Trainer"; + CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[1], 64*sizeof(WORD) ); + section = "Exciting Boxing"; + CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[2], 64*sizeof(WORD) ); + section = "Mahjang"; + CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[3], 64*sizeof(WORD) ); + +// NSF Contoller + section = "NSF controller"; + CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nNsfButton, 64*sizeof(WORD) ); + +// VS-Unisystem + section = "VS-Unisystem"; + CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nVSUnisystem, 64*sizeof(WORD) ); + +// Movie + section = "Movie"; + CRegistry::WriteProfileBinary( section.c_str(), "UsePlayer", (LPBYTE)movie.bUsePlayer, sizeof(movie.bUsePlayer) ); + CRegistry::WriteProfileInt( section.c_str(), "ResetRec", movie.bResetRec ); + CRegistry::WriteProfileInt( section.c_str(), "Rerecord", movie.bRerecord ); + CRegistry::WriteProfileInt( section.c_str(), "LoopPlay", movie.bLoopPlay ); + CRegistry::WriteProfileInt( section.c_str(), "PadDisplay", movie.bPadDisplay ); + +// Launcher + section = "Launcher"; + + CRegistry::WriteProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&launcher.rcWindowPos, sizeof(RECT) ); + + CRegistry::WriteProfileBinary( section.c_str(), "ColumnView", (LPBYTE)launcher.bHeaderView, sizeof(launcher.bHeaderView) ); + CRegistry::WriteProfileBinary( section.c_str(), "ColumnOrder", (LPBYTE)launcher.nHeaderOrder, sizeof(launcher.nHeaderOrder) ); + CRegistry::WriteProfileBinary( section.c_str(), "ColumnWidth", (LPBYTE)launcher.nHeaderWidth, sizeof(launcher.nHeaderWidth) ); + + CRegistry::WriteProfileInt( section.c_str(), "ListSelect", launcher.nListSelect ); + + CRegistry::WriteProfileInt( section.c_str(), "SortDir", launcher.bSortDir ); + CRegistry::WriteProfileInt( section.c_str(), "SortType", launcher.nSortType ); + + CRegistry::WriteProfileBinary( section.c_str(), "FolderUse", (LPBYTE)launcher.bFolderUse, sizeof(launcher.bFolderUse) ); + + for( i = 0; i < 16; i++ ) { + ::wsprintf( keys, "Folder%02d", i ); + CRegistry::WriteProfileString( section.c_str(), keys, launcher.szFolder[i] ); + } + + CRegistry::WriteProfileString( section.c_str(), "LastSelect", launcher.szLastSelect ); + + CRegistry::WriteProfileInt( section.c_str(), "ActivePause", launcher.bActivePause ); + +// NetPlay + section = "Netplay"; + + CRegistry::WriteProfileBinary( section.c_str(), "ChatPos", (LPBYTE)&netplay.rcChatPos, sizeof(RECT) ); + + CRegistry::WriteProfileString( section.c_str(), "NickName", netplay.szNick ); + + CRegistry::WriteProfileInt( section.c_str(), "RecnetPortNum", netplay.nRecentPort ); + for( i = 0; i < 16; i++ ) { + ::wsprintf( keys, "RecentPort%02d", i ); + CRegistry::WriteProfileString( section.c_str(), keys, netplay.szRecentPort[i] ); + } + CRegistry::WriteProfileInt( section.c_str(), "RecnetHostNum", netplay.nRecentHost ); + for( i = 0; i < 16; i++ ) { + ::wsprintf( keys, "RecentHost%02d", i ); + CRegistry::WriteProfileString( section.c_str(), keys, netplay.szRecentHost[i] ); + } +} + +BOOL CConfig::ButtonCheck( INT nNo, INT nID ) +{ + if( m_bKeyboardDisable ) { + if( (Config.controller.nButton[nNo][nID+ 0] >= 256) && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+ 0]] + || (Config.controller.nButton[nNo][nID+32] >= 256) && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+32]] ) + return TRUE; + } else { + if( Config.controller.nButton[nNo][nID+ 0] && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+ 0]] + || Config.controller.nButton[nNo][nID+32] && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+32]] ) + return TRUE; + } + return FALSE; +} + +BOOL CConfig::ExButtonCheck( INT nNo, INT nID ) +{ + if( Config.controller.nExButton[nNo][nID+ 0] && DirectInput.m_Sw[Config.controller.nExButton[nNo][nID+ 0]] + || Config.controller.nExButton[nNo][nID+32] && DirectInput.m_Sw[Config.controller.nExButton[nNo][nID+32]] ) + return TRUE; + return FALSE; +} + +BOOL CConfig::NsfButtonCheck( INT nID ) +{ + if( Config.controller.nNsfButton[nID+ 0] && DirectInput.m_Sw[Config.controller.nNsfButton[nID+ 0]] + || Config.controller.nNsfButton[nID+32] && DirectInput.m_Sw[Config.controller.nNsfButton[nID+32]] ) + return TRUE; + return FALSE; +} + +BOOL CConfig::ButtonCheck( INT nID, WORD* pKey ) +{ + if( pKey[nID+ 0] && DirectInput.m_Sw[pKey[nID+ 0]] + || pKey[nID+32] && DirectInput.m_Sw[pKey[nID+32]] ) + return TRUE; + return FALSE; +} + +string CConfig::ShortcutToKeyName( INT nShortcutKey ) +{ + string str; + if( nShortcutKey == 0 ) { + str = "----"; + } else { + if( nShortcutKey & CCfgShortCut::K_ALT ) + str = str + "Alt+"; + if( nShortcutKey & CCfgShortCut::K_CTRL ) + str = str + "Ctrl+"; + if( nShortcutKey & CCfgShortCut::K_SHIFT ) + str = str + "Shift+"; + + str = str + DirectInput.SearchKeyName( nShortcutKey & 0x0FFF ); + } + return str; +} + +///////////////////////////////// +CGameOption GameOption; + +void CGameOption::Load( DWORD crc ) +{ + CRegistry::SetRegistryKey( "GameOption.ini" ); + + CHAR szSection[256]; + ::wsprintf( szSection, "%08X", crc ); + nRenderMethod = CRegistry::GetProfileInt( szSection, "RenderMethod", defRenderMethod ); + nIRQtype = CRegistry::GetProfileInt( szSection, "IRQtype", defIRQtype ); + bFrameIRQ = (BOOL)CRegistry::GetProfileInt( szSection, "FrameIRQ", defFrameIRQ ); + bVideoMode = (BOOL)CRegistry::GetProfileInt( szSection, "VideoMode", defVideoMode ); +} + +void CGameOption::Save( LPCSTR name, DWORD crc ) +{ + CRegistry::SetRegistryKey( "GameOption.ini" ); + + CHAR szSection[256]; + ::wsprintf( szSection, "%08X", crc ); + CRegistry::WriteProfileString( szSection, "Title", name ); + CRegistry::WriteProfileInt( szSection, "RenderMethod", nRenderMethod ); + CRegistry::WriteProfileInt( szSection, "IRQtype", nIRQtype ); + CRegistry::WriteProfileInt( szSection, "FrameIRQ", (INT)bFrameIRQ ); + CRegistry::WriteProfileInt( szSection, "VideoMode", (INT)bVideoMode ); +} + +void CGameOption::Load( DWORD gid, DWORD mid ) +{ + CRegistry::SetRegistryKey( "GameOption.ini" ); + + CHAR szSection[256]; + ::wsprintf( szSection, "%08X%08X", gid, mid ); + nRenderMethod = CRegistry::GetProfileInt( szSection, "RenderMethod", defRenderMethod ); + nIRQtype = CRegistry::GetProfileInt( szSection, "IRQtype", defIRQtype ); + bFrameIRQ = (BOOL)CRegistry::GetProfileInt( szSection, "FrameIRQ", defFrameIRQ ); +} + +void CGameOption::Save( LPCSTR name, DWORD gid, DWORD mid ) +{ + CRegistry::SetRegistryKey( "GameOption.ini" ); + + CHAR szSection[256]; + ::wsprintf( szSection, "%08X%08X", gid, mid ); + CRegistry::WriteProfileString( szSection, "Title", name ); + CRegistry::WriteProfileInt( szSection, "RenderMethod", nRenderMethod ); + CRegistry::WriteProfileInt( szSection, "IRQtype", nIRQtype ); + CRegistry::WriteProfileInt( szSection, "FrameIRQ", (INT)bFrameIRQ ); +} + diff --git a/References/VirtuaNESex_src_191105/Config.h b/References/VirtuaNESex_src_191105/Config.h new file mode 100644 index 00000000..a737233a --- /dev/null +++ b/References/VirtuaNESex_src_191105/Config.h @@ -0,0 +1,783 @@ +// +// ݒۑNX +// +#ifndef __CCONFIG_INCLUDED__ +#define __CCONFIG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#define DIRECTINPUT_VERSION 0x0700 +#include + +#include +using namespace std; + +#include "extsoundfile.h" + +#include "typedef.h" +#include "macro.h" + +class CCfgGeneral +{ +public: + BOOL bDoubleExecute; + BOOL bStartupLauncher; + + BOOL bWindowSave; + BOOL bWindowZoom; + RECT rcWindowPos; + + BOOL bScreenMode; + BOOL nScreenZoom; + + RECT rcSearchDlgPos; + + RECT rcPatternViewPos; + RECT rcNameTableViewPos; + RECT rcPaletteViewPos; + RECT rcMemoryViewPos; + + RECT rcBarcodePos; + RECT rcPaletteEditPos; + + BOOL bNoJoystickID; + + WORD JoyAxisSetting[16]; + + // WCpbh̖̎ + // 0 : All enable + // 1 : Xȍ~S + // 2 : Yȍ~S + // 3 : Zȍ~S + // 4 : RXȍ~S + // 5 : RYȍ~S + // 6 : RZȍ~S + INT nJoyAxisDisable; + + void Default() { + bWindowSave = FALSE; + bWindowZoom = FALSE; + rcWindowPos.left = rcWindowPos.right = + rcWindowPos.top = rcWindowPos.bottom = 0; + + bDoubleExecute = TRUE; + bStartupLauncher = FALSE; + + bScreenMode = FALSE; + nScreenZoom = 0; + + rcSearchDlgPos.left = rcSearchDlgPos.right = + rcSearchDlgPos.top = rcSearchDlgPos.bottom = 0; + + rcPatternViewPos.left = rcPatternViewPos.right = + rcPatternViewPos.top = rcPatternViewPos.bottom = 0; + rcNameTableViewPos.left = rcNameTableViewPos.right = + rcNameTableViewPos.top = rcNameTableViewPos.bottom = 0; + rcPaletteViewPos.left = rcPaletteViewPos.right = + rcPaletteViewPos.top = rcPaletteViewPos.bottom = 0; + rcMemoryViewPos.left = rcMemoryViewPos.right = + rcMemoryViewPos.top = rcMemoryViewPos.bottom = 0; + + rcBarcodePos.left = rcBarcodePos.right = + rcBarcodePos.top = rcBarcodePos.bottom = 0; + + rcPaletteEditPos.left = rcPaletteEditPos.right = + rcPaletteEditPos.top = rcPaletteEditPos.bottom = 0; + + bNoJoystickID = FALSE; + nJoyAxisDisable = 0; + + for( INT i = 0; i < 16; i++ ) { + JoyAxisSetting[i] = 0; + } + } +}; + +class CCfgPath +{ +public: + BOOL bRomAutoRunPath;//Ăl֪100ҶӵĹ ģʱԶָļ + BOOL bRomPath; + BOOL bRamPath; + BOOL bSavePath; + BOOL bStatePath; + BOOL bSnapshotPath; + BOOL bMoviePath; + BOOL bWavePath; + BOOL bCheatPath; + + CHAR szRomAutoRunPath [_MAX_PATH]; + CHAR szRomPath [_MAX_PATH]; + CHAR szRamPath [_MAX_PATH]; + CHAR szSavePath [_MAX_PATH]; + CHAR szStatePath [_MAX_PATH]; + CHAR szSnapshotPath[_MAX_PATH]; + CHAR szMoviePath [_MAX_PATH]; + CHAR szWavePath [_MAX_PATH]; + CHAR szCheatPath [_MAX_PATH]; + + void Default() { +#if 0 + bRomPath = bRamPath = bSavePath = + bStatePath = bSnapshotPath = + bMoviePath = bWavePath = + bCheatPath = FALSE; + szRomPath[0] = szRamPath[0] = szSavePath[0] = + szStatePath[0] = szSnapshotPath[0] = + szMoviePath[0] = szWavePath[0] = + szCheatPath[0] = 0; +#endif + bRomPath = bRomPath = bSavePath = + bStatePath = bSnapshotPath = + bMoviePath = bWavePath = + bCheatPath = TRUE; + + bRomAutoRunPath = FALSE; + + ::lstrcpy( szRomAutoRunPath, ".\\" ); + ::lstrcpy( szRomPath, ".\\roms\\" ); + ::lstrcpy( szRamPath, ".\\ram\\" ); + ::lstrcpy( szSavePath, ".\\save\\" ); + ::lstrcpy( szStatePath, ".\\state\\" ); + ::lstrcpy( szSnapshotPath, ".\\snapshot\\" ); + ::lstrcpy( szMoviePath, ".\\movie\\" ); + ::lstrcpy( szWavePath, ".\\wave\\" ); + ::lstrcpy( szCheatPath, ".\\cheatcode\\" ); + } +}; + +class CCfgEmulator +{ +public: + BOOL bIllegalOp; + BOOL bAutoFrameSkip; + BOOL bThrottle; + INT nThrottleFPS; + BOOL bBackground; + INT nPriority; + BOOL bFourPlayer; + BOOL bCrcCheck; + BOOL bDiskThrottle; + BOOL bLoadFullscreen; + BOOL bPNGsnapshot; + + void Default() { + bIllegalOp = FALSE; + bAutoFrameSkip = TRUE; + bThrottle = TRUE; + nThrottleFPS = 120; // 120FPS + bBackground = FALSE; + nPriority = 3; // Normal + bFourPlayer = TRUE; // TRUE:NES FALSE:Famicom + bCrcCheck = TRUE; + bDiskThrottle = TRUE; + bLoadFullscreen = FALSE; + bPNGsnapshot = FALSE; + } +}; + +class CCfgGraphics +{ +public: + BOOL bAspect; + BOOL bAllSprite; + BOOL bAllLine; + BOOL bFPSDisp; + BOOL bTVFrame; + BOOL bScanline; + INT nScanlineColor; + BOOL bSyncDraw; + BOOL bFitZoom; + + BOOL bLeftClip; + + BOOL bWindowVSync; + + BOOL bSyncNoSleep; + + BOOL bDiskAccessLamp; + + BOOL bDoubleSize; + BOOL bSystemMemory; + BOOL bUseHEL; + + BOOL bNoSquareList; + + INT nGraphicsFilter; + + DWORD dwDisplayWidth; + DWORD dwDisplayHeight; + DWORD dwDisplayDepth; + DWORD dwDisplayRate; + + BOOL bPaletteFile; + CHAR szPaletteFile[_MAX_PATH]; + + void Default() { + bAspect = FALSE; + bAllSprite = TRUE; + bAllLine = FALSE; + bFPSDisp = FALSE; + bTVFrame = FALSE; + bScanline = FALSE; + nScanlineColor = 75; + bSyncDraw = FALSE; + bFitZoom = FALSE; + + bLeftClip = TRUE; + + bWindowVSync = FALSE; + bSyncNoSleep = FALSE; + + bDiskAccessLamp = FALSE; + + bDoubleSize = FALSE; + bSystemMemory = FALSE; + bUseHEL = FALSE; + + bNoSquareList = FALSE; + + nGraphicsFilter = 0; + + dwDisplayWidth = 640; + dwDisplayHeight = 480; + dwDisplayDepth = 16; + dwDisplayRate = 0; + + bPaletteFile = FALSE; + szPaletteFile[0] = 0; + } +}; + +class CCfgSound +{ +public: + BOOL bEnable; + INT nRate; + INT nBits; + INT nBufferSize; + + INT nFilterType; + + BOOL bChangeTone; + + BOOL bDisableVolumeEffect; + BOOL bExtraSoundEnable; + + // 0:Master + // 1:Rectangle 1 + // 2:Rectangle 2 + // 3:Triangle + // 4:Noise + // 5:DPCM + // 6:VRC6 + // 7:VRC7 + // 8:FDS + // 9:MMC5 + // 10:N106 + // 11:FME7 + SHORT nVolume[16]; + + void Default() { + bEnable = TRUE; + nRate = 22050; + nBits = 8; + nBufferSize = 4; + + nFilterType = 0; + + bChangeTone = FALSE; + + bDisableVolumeEffect = FALSE; + bExtraSoundEnable = TRUE; + + for( INT i = 0; i < 16; i++ ) { + nVolume[i] = 100; + } + } +}; + +class CCfgShortCut +{ +public: + WORD nShortCut[512]; + + enum { + K_ALT = 0x8000, + K_CTRL = 0x4000, + K_SHIFT = 0x2000, + }; + + void Default() { + for( INT i = 0; i < (sizeof(nShortCut)/sizeof(WORD)); i++ ) { + nShortCut[i] = 0; + } + + // Main controls + nShortCut[ 0] = DIK_O+K_CTRL; // ID_OPEN + nShortCut[ 1] = DIK_C+K_CTRL; // ID_CLOSE + nShortCut[ 2] = DIK_L+K_CTRL; // ID_LAUNCHER + nShortCut[ 3] = DIK_N+K_CTRL; // ID_NETPLAY_CONNECT + nShortCut[ 4] = DIK_D+K_CTRL; // ID_NETPLAY_DISCONNECT + nShortCut[ 5] = DIK_A+K_CTRL; // ID_NETPLAY_CHAT + nShortCut[ 8] = DIK_I+K_CTRL; // ID_ROMINFO + nShortCut[ 9] = DIK_W+K_CTRL; // ID_WAVERECORD + nShortCut[ 15] = DIK_X+K_CTRL; // ID_EXIT + + // Emulation controls + nShortCut[ 16] = DIK_F1; // Hardware reset + nShortCut[ 17] = DIK_F2; // Software reset + nShortCut[ 18] = DIK_P; // Hardware pause + nShortCut[ 19] = DIK_TAB; // Throttle(toggled) + nShortCut[ 20] = DIK_NUMPADENTER; // Frame skip Auto + nShortCut[ 21] = DIK_ADD; // Frame skip + + nShortCut[ 22] = DIK_SUBTRACT; // Frame skip - + + nShortCut[ 23] = DIK_SPACE; // One Frame step + nShortCut[ 24] = DIK_BACKSPACE; // Throttle(Not toggle) + + // State controls + nShortCut[ 32] = DIK_L; // State Load + nShortCut[ 33] = DIK_S; // State Save + nShortCut[ 34] = DIK_F3; // State Slot + + nShortCut[ 35] = DIK_F4; // State Slot - + + // Disk controls + nShortCut[ 48] = DIK_5; // Disk Eject + nShortCut[ 49] = DIK_1; // Disk 0 Side A + nShortCut[ 50] = DIK_2; // Disk 0 Side B + nShortCut[ 51] = DIK_3; // Disk 1 Side A + nShortCut[ 52] = DIK_4; // Disk 1 Side B + + // Movie controls + nShortCut[ 56] = DIK_P+K_ALT; // Movie Play + nShortCut[ 57] = DIK_R+K_ALT; // Movie Rec + nShortCut[ 58] = DIK_A+K_ALT; // Movie Rec Append + nShortCut[ 59] = DIK_S+K_ALT; // Movie Stop + nShortCut[ 60] = DIK_M+K_ALT; // Movie Info + + // Screen controls + nShortCut[ 64] = DIK_F5; // Zoom x1 + nShortCut[ 65] = DIK_F6; // Zoom x2 + nShortCut[ 66] = DIK_F7; // Zoom x3 + nShortCut[ 67] = DIK_F8; // Zoom x4 + nShortCut[ 68] = DIK_RETURN+K_ALT; // Fullscreen + + // Sound controls + nShortCut[ 72] = DIK_BACK+K_CTRL; // Mute Master + nShortCut[ 73] = DIK_1+K_CTRL; // Mute Rectangle #1 + nShortCut[ 74] = DIK_2+K_CTRL; // Mute Rectangle #2 + nShortCut[ 75] = DIK_3+K_CTRL; // Mute Triangle + nShortCut[ 76] = DIK_4+K_CTRL; // Mute Noise + nShortCut[ 77] = DIK_5+K_CTRL; // Mute Dpcm + nShortCut[ 78] = DIK_6+K_CTRL; // Mute External #1 + nShortCut[ 79] = DIK_7+K_CTRL; // Mute External #2 + nShortCut[ 80] = DIK_8+K_CTRL; // Mute External #3 + nShortCut[ 81] = DIK_9+K_CTRL; // Mute External #4 + nShortCut[ 82] = DIK_0+K_CTRL; // Mute External #5 + nShortCut[ 83] = DIK_MINUS+K_CTRL; // Mute External #6 + nShortCut[ 84] = DIK_CIRCUMFLEX+K_CTRL; // Mute External #7 + nShortCut[ 85] = DIK_YEN+K_CTRL; // Mute External #8 + + // Tape controls + nShortCut[ 90] = 0; // Tape Play + nShortCut[ 91] = 0; // Tape Rec + nShortCut[ 92] = 0; // Tape Stop + + // Other controls + nShortCut[ 96] = DIK_P+K_CTRL; // Snapshot + nShortCut[ 97] = DIK_F11; // FPSDISP + nShortCut[ 98] = DIK_F12+K_CTRL; // TV Aspect + nShortCut[ 99] = DIK_F11+K_CTRL; // TV frame + nShortCut[100] = DIK_F12; // Scanline + nShortCut[101] = DIK_F9+K_CTRL; // Show 240 lines + nShortCut[102] = DIK_F9; // All sprites + nShortCut[103] = DIK_F10; // Sync draw + nShortCut[104] = DIK_F10+K_CTRL; // Fit screen + nShortCut[105] = 0; // Left clip + + // Cheat + nShortCut[110] = DIK_HOME+K_CTRL; // Search + nShortCut[111] = DIK_END+K_CTRL; // Cheat + nShortCut[112] = DIK_INSERT; // Cheat enable + nShortCut[113] = DIK_DELETE; // Cheat disable + nShortCut[114] = 0; // GameGenie + + // Tools + nShortCut[116] = 0; // Pattern Viewer + nShortCut[117] = 0; // NameTable Viewer + nShortCut[118] = 0; // Palette Viewer + + nShortCut[119] = 0; // Memory Viewer + + // Quick Load/Save + nShortCut[256] = DIK_NUMPAD0+K_CTRL; // QuickLoad Slot0 + nShortCut[257] = DIK_NUMPAD1+K_CTRL; // QuickLoad Slot1 + nShortCut[258] = DIK_NUMPAD2+K_CTRL; // QuickLoad Slot2 + nShortCut[259] = DIK_NUMPAD3+K_CTRL; // QuickLoad Slot3 + nShortCut[260] = DIK_NUMPAD4+K_CTRL; // QuickLoad Slot4 + nShortCut[261] = DIK_NUMPAD5+K_CTRL; // QuickLoad Slot5 + nShortCut[262] = DIK_NUMPAD6+K_CTRL; // QuickLoad Slot6 + nShortCut[263] = DIK_NUMPAD7+K_CTRL; // QuickLoad Slot7 + nShortCut[264] = DIK_NUMPAD8+K_CTRL; // QuickLoad Slot8 + nShortCut[265] = DIK_NUMPAD9+K_CTRL; // QuickLoad Slot9 + + nShortCut[266] = DIK_NUMPAD0+K_ALT; // QuickSave Slot0 + nShortCut[267] = DIK_NUMPAD1+K_ALT; // QuickSave Slot1 + nShortCut[268] = DIK_NUMPAD2+K_ALT; // QuickSave Slot2 + nShortCut[269] = DIK_NUMPAD3+K_ALT; // QuickSave Slot3 + nShortCut[270] = DIK_NUMPAD4+K_ALT; // QuickSave Slot4 + nShortCut[271] = DIK_NUMPAD5+K_ALT; // QuickSave Slot5 + nShortCut[272] = DIK_NUMPAD6+K_ALT; // QuickSave Slot6 + nShortCut[273] = DIK_NUMPAD7+K_ALT; // QuickSave Slot7 + nShortCut[274] = DIK_NUMPAD8+K_ALT; // QuickSave Slot8 + nShortCut[275] = DIK_NUMPAD9+K_ALT; // QuickSave Slot9 + } +}; + +class CCfgLanguage +{ +public: + LCID lcID; + CHAR szLanguage[256]; + + void Default() { + lcID = NULL; + szLanguage[0] = 0; + } +}; + +class CCfgController +{ +public: + WORD nButton[4][64]; + WORD nRapid [4][ 2]; + // 0:Crazy Climber + // 1:Famly Trainer + // 2:Exciting Boxing + // 3:Mahjang + WORD nExButton[4][64]; + WORD nNsfButton[64]; + WORD nVSUnisystem[64]; + + void Default() { + DefaultController1(); + DefaultController2(); + DefaultController3(); + DefaultController4(); + DefaultExController0(); + DefaultExController1(); + DefaultExController2(); + DefaultExController3(); + DefaultNsfController(); + DefaultVSUnisystem(); + } + + void DefaultController1() { + for( INT i = 0; i < 64; i++ ) + nButton[0][i] = 0; + + nButton[0][ 0] = DIK_UP; + nButton[0][ 1] = DIK_DOWN; + nButton[0][ 2] = DIK_LEFT; + nButton[0][ 3] = DIK_RIGHT; + nButton[0][ 4] = DIK_X; // A + nButton[0][ 5] = DIK_Z; // B + nButton[0][ 6] = 0; // A Rapid + nButton[0][ 7] = 0; // B Rapid + nButton[0][ 8] = DIK_RSHIFT; // SELECT + nButton[0][ 9] = DIK_RETURN; // START + + nRapid[0][0] = 0; // A Rapid speed + nRapid[0][1] = 0; // B Rapid speed + } + + void DefaultController2() { + for( INT i = 0; i < 64; i++ ) + nButton[1][i] = 0; + + nButton[1][ 0] = DIK_NUMPAD8; + nButton[1][ 1] = DIK_NUMPAD2; + nButton[1][ 2] = DIK_NUMPAD4; + nButton[1][ 3] = DIK_NUMPAD6; + nButton[1][ 4] = DIK_N; // A + nButton[1][ 5] = DIK_B; // B + nButton[1][ 6] = 0; // A Rapid + nButton[1][ 7] = 0; // B Rapid + nButton[1][ 8] = 0; // SELECT + nButton[1][ 9] = 0; // START + nButton[1][10] = DIK_M; // Mic + + nRapid[1][0] = 0; // A Rapid speed + nRapid[1][1] = 0; // B Rapid speed + } + + void DefaultController3() { + for( INT i = 0; i < 64; i++ ) + nButton[2][i] = 0; + + nRapid[2][0] = 0; // A Rapid speed + nRapid[2][1] = 0; // B Rapid speed + } + + void DefaultController4() { + for( INT i = 0; i < 64; i++ ) + nButton[3][i] = 0; + + nRapid[3][0] = 0; // A Rapid speed + nRapid[3][1] = 0; // B Rapid speed + } + + void DefaultExController0() { + // Crazy Climber۰(ۂɂ݂͑Ȃ) + for( INT i = 0; i < 64; i++ ) + nExButton[0][i] = 0; +// nExButton[0][ 0] = 0; // L up +// nExButton[0][ 1] = 0; // L down +// nExButton[0][ 2] = 0; // L left +// nExButton[0][ 3] = 0; // L right +// nExButton[0][ 4] = 0; // R up +// nExButton[0][ 5] = 0; // R down +// nExButton[0][ 6] = 0; // R left +// nExButton[0][ 7] = 0; // R right + } + + void DefaultExController1() { + // Famly Trainer۰ + for( INT i = 0; i < 64; i++ ) + nExButton[1][i] = 0; + } + + void DefaultExController2() { + // Exciting Boxing۰ + for( INT i = 0; i < 64; i++ ) + nExButton[2][i] = 0; + } + + void DefaultExController3() { + // Mahjang۰ + for( INT i = 0; i < 64; i++ ) + nExButton[3][i] = 0; + } + + void DefaultNsfController() { + for( INT i = 0; i < 64; i++ ) + nNsfButton[i] = 0; + + nNsfButton[ 0] = DIK_UP; // Play + nNsfButton[ 1] = DIK_DOWN; // Stop + nNsfButton[ 2] = DIK_LEFT; // Number -1 + nNsfButton[ 3] = DIK_RIGHT; // Number +1 + nNsfButton[ 4] = DIK_PRIOR; // Number +16 + nNsfButton[ 5] = DIK_NEXT; // Number -16 + } + + void DefaultVSUnisystem() { + for( INT i = 0; i < 64; i++ ) + nVSUnisystem[i] = 0; + + nVSUnisystem[0] = DIK_C; // Coin + } +}; + +class CCfgMovie +{ +public: + BYTE bUsePlayer[4]; + BOOL bRerecord; + BOOL bLoopPlay; + BOOL bResetRec; + BOOL bPadDisplay; + + void Default() { + bUsePlayer[0] = 0xFF; + bUsePlayer[1] = 0x00; + bUsePlayer[2] = 0x00; + bUsePlayer[3] = 0x00; + bRerecord = TRUE; + bLoopPlay = FALSE; + bResetRec = FALSE; + bPadDisplay = FALSE; + } +}; + +class CCfgLauncher +{ +public: + RECT rcWindowPos; + + BYTE bHeaderView [16]; + BYTE nHeaderOrder[16]; + SHORT nHeaderWidth[16]; + + BOOL bActivePause; + + INT nListSelect; + + BOOL bSortDir; + INT nSortType; + + BYTE bFolderUse[16]; + CHAR szFolder[16][_MAX_PATH]; + + CHAR szLastSelect[_MAX_PATH]; + + void Default() { + rcWindowPos.left = rcWindowPos.right = + rcWindowPos.top = rcWindowPos.bottom = 0; + + bActivePause = FALSE; + + nListSelect = 0; + + bSortDir = FALSE; + nSortType = 0; + + INT i; + for( i = 0; i < 16; i++ ) { + bHeaderView [i] = TRUE; + nHeaderOrder[i] = i; + nHeaderWidth[i] = (i==0)?160:48; + } + + for( i = 0; i < 16; i++ ) { + bFolderUse[i] = FALSE; + szFolder[i][0] = '\0'; + } + + szLastSelect[0] = '\0'; + } +}; + +class CCfgExtraSound +{ +public: + CHAR szExtSoundFile[ ESF_FILE_MAX ][ MAX_PATH ]; + + void Default() { + for( INT i = 0; i < ESF_FILE_MAX; i++ ) { + szExtSoundFile[i][0] = '\0'; + } + } +}; + +class CCfgNetPlay +{ +public: + RECT rcChatPos; + + INT nRecentPort, nRecentHost; + CHAR szRecentPort[16][_MAX_PATH+1]; + CHAR szRecentHost[16][_MAX_PATH+1]; + CHAR szNick[_MAX_PATH+1]; + + void Default() { + rcChatPos.left = rcChatPos.right = + rcChatPos.top = rcChatPos.bottom = 0; + + ::lstrcpy( szNick, "NoName" ); + + for( INT i = 0; i < 16; i++ ) { + szRecentPort[i][0] = '\0'; + szRecentHost[i][0] = '\0'; + } + ::lstrcpy( szRecentPort[0], "10000" ); + ::lstrcpy( szRecentHost[0], "localhost:10000" ); + + nRecentPort = 1; + nRecentHost = 1; + } +}; + +class CConfig +{ +public: + CConfig() { + m_bKeyboardDisable = FALSE; + Default(); + } + + CCfgGeneral general; + CCfgPath path; + CCfgEmulator emulator; + CCfgGraphics graphics; + CCfgSound sound; + CCfgShortCut shortcut; + CCfgLanguage language; + CCfgController controller; + CCfgMovie movie; + CCfgLauncher launcher; + CCfgExtraSound extsound; + CCfgNetPlay netplay; + + void Default() { + general.Default(); + path.Default(); + emulator.Default(); + graphics.Default(); + sound.Default(); + shortcut.Default(); + language.Default(); + controller.Default(); + movie.Default(); + launcher.Default(); + extsound.Default(); + netplay.Default(); + } + + void Load(); + void Save(); + +// Checker + void InputKeyboardDisable( BOOL bEnable ) { + m_bKeyboardDisable = bEnable; + } + + BOOL ButtonCheck( INT nNo, INT nID ); + BOOL ExButtonCheck( INT nNo, INT nID ); + BOOL NsfButtonCheck( INT nID ); + BOOL ButtonCheck( INT nID, WORD* pKey ); + +// Converter + string ShortcutToKeyName( INT nShortcut ); + +// Table + static INT SamplingRateTable[]; + static INT ShortcutKeyID[]; +protected: + + BOOL m_bKeyboardDisable; +private: +}; + +// •ʃQ[IvV +class CGameOption +{ +public: + // for Cartridge + void Load( DWORD crc ); + void Save( LPCSTR name, DWORD crc ); + // for FDS + void Load( DWORD gid, DWORD mid ); + void Save( LPCSTR name, DWORD gid, DWORD mid ); + + // Defaultۑ + INT defRenderMethod; + INT defIRQtype; + BOOL defFrameIRQ; + BOOL defVideoMode; + + // f[^ + INT nRenderMethod; + INT nIRQtype; + BOOL bFrameIRQ; + BOOL bVideoMode; +protected: +private: +}; + +extern CConfig Config; +extern CGameOption GameOption; + +#endif // !__CCONFIG_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/ControllerDlg.cpp b/References/VirtuaNESex_src_191105/ControllerDlg.cpp new file mode 100644 index 00000000..d0ce2e43 --- /dev/null +++ b/References/VirtuaNESex_src_191105/ControllerDlg.cpp @@ -0,0 +1,516 @@ +// +// Rg[_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "ControllerDlg.h" + +#include "DirectInput.h" + +/////////////////////////////////////////////////////////////////////////////// + +DLG_MESSAGE_BEGIN(CControllerPageDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// NOTIFYbZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND_NOTIFY_RANGE( IDC_CTR_UP, IDC_CTR_END, STN_CLICKED, OnClicked ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CControllerPageDlg::Create( UINT nID, HWND hWndParent ) +{ + m_nPageID = nID; + + m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(nID), + hWndParent, g_DlgProc, (LPARAM)this ); + return (m_hWnd)?TRUE:FALSE; +} + +void CControllerPageDlg::Destroy() +{ + ::DestroyWindow( m_hWnd ); +} + +DLGCMD CControllerPageDlg::OnClicked( DLGCMDPARAM ) +{ +// DEBUGOUT( "CControllerPageDlg::OnClicked uID=%d\n", uID ); + + // ẽ^uRg[pXăbZ[Wʒm:p + HWND hWndParent, hWndOwner; + hWndParent = ::GetParent( m_hWnd ); + hWndOwner = ::GetParent( hWndParent ); + ::SendMessage( hWndOwner, WM_COMMAND, MAKELPARAM(uID,STN_CLICKED), (LPARAM)::GetDlgItem(m_hWnd,uID) ); +} + +DLGMSG CControllerPageDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CControllerPageDlg::OnInitDialog\n" ); + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// + +UINT CControllerDlg::ControllerPageID[] = { + IDD_CTR_PLAYER1, + IDD_CTR_PLAYER2, + IDD_CTR_PLAYER3, + IDD_CTR_PLAYER4, + IDD_CTR_CRAZYCLIMBER, + IDD_CTR_FAMLYTRAINER, + IDD_CTR_EXCITINGBOXING, + IDD_CTR_MAHJANG, + IDD_CTR_NSFPLAYER, + IDD_CTR_VSUNISYSTEM, + 0 +}; + +DLG_MESSAGE_BEGIN(CControllerDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_DESTROY, OnDestroy ) +DLG_ON_MESSAGE( WM_TIMER, OnTimer ) +// NOTIFYbZ[W +DLG_NOTIFY_BEGIN() +DLG_ON_NOTIFY( IDC_CTR_TAB, TCN_SELCHANGE, OnSelectChange ) +DLG_NOTIFY_END() +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_ON_COMMAND_NOTIFY_RANGE( IDC_CTR_UP, IDC_CTR_END, STN_CLICKED, OnClicked ) +DLG_ON_COMMAND_NOTIFY( IDC_CTR_SELECT_COMBO, CBN_SELCHANGE, OnSettingSelectChange ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CControllerDlg::DoModal( HWND hWndParent ) +{ + m_bCancelMode = FALSE; + m_TimerID = 0; + + m_SettingSel = 0; + + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_CONTROLLER), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +BOOL CControllerDlg::PreTranslateMessage( MSG* pMsg ) +{ + if( pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST ) { +// DEBUGOUT( "CControllerDlg::PreTranslateMessage WM_KEY????\n" ); + return m_bCancelMode; + } + return FALSE; +} + +void CControllerDlg::OnInitialMember() +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CTR_TAB ); + RECT rcT, rcP, rcW; + INT page; + +// for( INT page = 0; ControllerPageID[page]; page++ ) { + for( page = 0; ControllerPageID[page]; page++ ) { + m_Page[page].Create( ControllerPageID[page], hWndCtrl ); + + // O̎擾 + CHAR szTitle[256]; + ::GetWindowText( m_Page[page].m_hWnd, szTitle, sizeof(szTitle) ); + + // O擾LvV + LONG style; + style = ::GetWindowLong( m_Page[page].m_hWnd, GWL_STYLE ); + style &= ~(WS_CAPTION|WS_BORDER|WS_OVERLAPPED); + ::SetWindowLong( m_Page[page].m_hWnd, GWL_STYLE, style ); + + // TCYύX + ::GetWindowRect( m_Page[page].m_hWnd, &rcW ); + rcW.right -= ::GetSystemMetrics( SM_CXSIZEFRAME ); + rcW.bottom -= ::GetSystemMetrics( SM_CYCAPTION )+::GetSystemMetrics( SM_CYSIZEFRAME )*2; + ::SetWindowPos( m_Page[page].m_hWnd, NULL, 0, 0, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOMOVE|SWP_NOZORDER ); + + // ^uɖOݒ肷 + TCITEM tcitem; + tcitem.mask = TCIF_TEXT; + tcitem.pszText = szTitle; + TabCtrl_InsertItem( hWndCtrl, page, &tcitem ); + +// // y[Wʒu̕␳ +// ::GetClientRect( hWndCtrl, &rcT ); +// TabCtrl_AdjustRect( hWndCtrl, FALSE, &rcT ); +// ::GetWindowRect( m_Page[page].m_hWnd, &rcP ); + + // vZ +// rcW.left = rcT.left + (RCWIDTH(rcT)-RCWIDTH(rcP))/2; +// rcW.top = rcT.top + (RCHEIGHT(rcT)-RCHEIGHT(rcP))/2; +// rcW.right = rcW.left + RCWIDTH(rcP); +// rcW.bottom = rcW.top + RCHEIGHT(rcP); +// ::SetWindowPos( m_Page[page].m_hWnd, NULL, rcW.left, rcW.top, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOZORDER|SWP_NOACTIVATE ); + + // ey[W̃Xg{bNX̐ݒ + if( page < 4 ) { + HWND hWndList; + hWndList = ::GetDlgItem( m_Page[page].m_hWnd, IDC_CTR_A_RAPID_LIST ); + ::SendMessage( hWndList, LB_INSERTSTRING, 0, (LPARAM)" 10FPS" ); + ::SendMessage( hWndList, LB_INSERTSTRING, 1, (LPARAM)" 15FPS" ); + ::SendMessage( hWndList, LB_INSERTSTRING, 2, (LPARAM)" 20FPS" ); + ::SendMessage( hWndList, LB_INSERTSTRING, 3, (LPARAM)" 30FPS" ); + hWndList = ::GetDlgItem( m_Page[page].m_hWnd, IDC_CTR_B_RAPID_LIST ); + ::SendMessage( hWndList, LB_INSERTSTRING, 0, (LPARAM)" 10FPS" ); + ::SendMessage( hWndList, LB_INSERTSTRING, 1, (LPARAM)" 15FPS" ); + ::SendMessage( hWndList, LB_INSERTSTRING, 2, (LPARAM)" 20FPS" ); + ::SendMessage( hWndList, LB_INSERTSTRING, 3, (LPARAM)" 30FPS" ); + } + + // {^̐ݒ + OnPageSetup( page ); + + ::ShowWindow( m_Page[page].m_hWnd, (page==0)?SW_SHOW:SW_HIDE ); + } + + // y[WʒuĒ + for( page = 0; ControllerPageID[page]; page++ ) { + // y[Wʒu̕␳ + ::GetClientRect( hWndCtrl, &rcT ); + TabCtrl_AdjustRect( hWndCtrl, FALSE, &rcT ); + ::GetWindowRect( m_Page[page].m_hWnd, &rcP ); + + // vZ + rcW.left = rcT.left + (RCWIDTH(rcT)-RCWIDTH(rcP))/2; + rcW.top = rcT.top + (RCHEIGHT(rcT)-RCHEIGHT(rcP))/2; + rcW.right = rcW.left + RCWIDTH(rcP); + rcW.bottom = rcW.top + RCHEIGHT(rcP); + ::SetWindowPos( m_Page[page].m_hWnd, NULL, rcW.left, rcW.top, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOZORDER|SWP_NOACTIVATE ); + } + + TabCtrl_SetCurSel( hWndCtrl, 0 ); + m_PageSel = 0; + + m_PageNum = page; + + // ݒR{{bNX + ::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_RESETCONTENT, 0, 0 ); + CHAR szStr[64]; + for( INT i = IDS_CTR_SELECT1; i <= IDS_CTR_SELECT2; i++ ) { + CApp::LoadString( i, szStr, sizeof(szStr) ); + ::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_INSERTSTRING, (WPARAM)i-IDS_CTR_SELECT1, (LPARAM)szStr ); + } + ::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_SETCURSEL, 0, 0 ); +} + +void CControllerDlg::OnPageSetup( UINT nPage ) +{ + HWND hWnd = m_Page[nPage].m_hWnd; + HWND hWndCtrl; + INT nKey; + LPCSTR lpStr; + INT nOffset = m_SettingSel?32:0; + + for( INT nID = IDC_CTR_UP; nID <= IDC_CTR_END; nID++ ) { + if( (hWndCtrl = ::GetDlgItem( hWnd, nID )) ) { + if( nPage < 4 ) { + nKey = Config.controller.nButton[nPage][nID-IDC_CTR_UP+nOffset]; + } else if( ControllerPageID[nPage] == IDD_CTR_CRAZYCLIMBER ) { + nKey = Config.controller.nExButton[0][nID-IDC_CTR_UP+nOffset]; + } else if( ControllerPageID[nPage] == IDD_CTR_FAMLYTRAINER ) { + nKey = Config.controller.nExButton[1][nID-IDC_CTR_UP+nOffset]; + } else if( ControllerPageID[nPage] == IDD_CTR_EXCITINGBOXING ) { + nKey = Config.controller.nExButton[2][nID-IDC_CTR_UP+nOffset]; + } else if( ControllerPageID[nPage] == IDD_CTR_MAHJANG ) { + nKey = Config.controller.nExButton[3][nID-IDC_CTR_UP+nOffset]; + } else if( ControllerPageID[nPage] == IDD_CTR_NSFPLAYER ) { + nKey = Config.controller.nNsfButton[nID-IDC_CTR_UP+nOffset]; + } else if( ControllerPageID[nPage] == IDD_CTR_VSUNISYSTEM ) { + nKey = Config.controller.nVSUnisystem[nID-IDC_CTR_UP+nOffset]; + } + if( (lpStr = DirectInput.SearchKeyName(nKey)) ) { + ::SetWindowText( hWndCtrl, lpStr ); + } else { + ::SetWindowText( hWndCtrl, "----" ); + } + ::InvalidateRect( hWndCtrl, NULL, TRUE ); + } + } + + if( nPage < 4 ) { + ::SendDlgItemMessage( hWnd, IDC_CTR_A_RAPID_LIST, LB_SETCURSEL, + (WPARAM)Config.controller.nRapid[nPage][0], 0 ); + ::SendDlgItemMessage( hWnd, IDC_CTR_B_RAPID_LIST, LB_SETCURSEL, + (WPARAM)Config.controller.nRapid[nPage][1], 0 ); + } +} + +DLGMSG CControllerDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnInitDialog\n" ); + m_ConfigSave = Config.controller; + + OnInitialMember(); + + return TRUE; +} + +DLGMSG CControllerDlg::OnDestroy( DLGMSGPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnDestroy\n" ); + + // `ChEChEj + for( INT i = 0; i < m_PageNum; i++ ) { + ::DestroyWindow( m_Page[i].m_hWnd ); + } + return FALSE; +} + +DLGNOTIFY CControllerDlg::OnSelectChange( DLGNOTIFYPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnSelectChange\n" ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CTR_TAB ); + m_PageSel = TabCtrl_GetCurSel( hWndCtrl ); + + OnPageSetup( m_PageSel ); + + for( INT i = 0; i < m_PageNum; i++ ) { + if( i == m_PageSel ) { + ::ShowWindow( m_Page[i].m_hWnd, SW_SHOW ); + } else { + ::ShowWindow( m_Page[i].m_hWnd, SW_HIDE ); + } + } + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; +// ::InvalidateRect( hWndCtrl, NULL, TRUE ); + } + m_bCancelMode = FALSE; +} + +DLGNOTIFY CControllerDlg::OnSettingSelectChange( DLGCMDPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnSettingSelectChange\n" ); + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; +// ::InvalidateRect( ::GetDlgItem( m_hWnd, IDC_CTR_TAB ), NULL, TRUE ); + } + m_bCancelMode = FALSE; + + m_SettingSel = ::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_GETCURSEL, 0, 0 ); + + OnPageSetup( m_PageSel ); +} + +DLGCMD CControllerDlg::OnClicked( DLGCMDPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnClicked uID=%d\n", uID ); + if( !m_TimerID ) { + m_ControlID = uID; + m_TimerCount = 0; + m_TimerID = ::SetTimer( m_hWnd, 1, 50, NULL ); + m_bCancelMode = TRUE; + } +} + +DLGMSG CControllerDlg::OnTimer( DLGMSGPARAM ) +{ + HWND hWndCtrl = ::GetDlgItem( m_Page[m_PageSel].m_hWnd, m_ControlID ); + INT nID = m_ControlID - IDC_CTR_UP; + INT nOffset = m_SettingSel?32:0; + + if( wParam == (WPARAM)m_TimerID ) { + if( m_TimerCount == 0 ) + m_TimerStart = ::timeGetTime(); + m_TimerCount++; + + DirectInput.Poll(); + + if( m_TimerCount > 60 ) { + // TimeOut + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; + ::InvalidateRect( hWndCtrl, NULL, TRUE ); + } + m_bCancelMode = FALSE; + } else { + // Button push? + BOOL bSet = FALSE; + INT i; + LPCSTR str; + // Set cancel + if( DirectInput.m_Sw[DIK_ESCAPE] ) { + if( m_PageSel < 4 ) { + Config.controller.nButton[m_PageSel][nID+nOffset] = 0; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_CRAZYCLIMBER ) { + Config.controller.nExButton[0][nID+nOffset] = 0; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_FAMLYTRAINER ) { + Config.controller.nExButton[1][nID+nOffset] = 0; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_EXCITINGBOXING ) { + Config.controller.nExButton[2][nID+nOffset] = 0; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_MAHJANG ) { + Config.controller.nExButton[3][nID+nOffset] = 0; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_NSFPLAYER ) { + Config.controller.nNsfButton[nID+nOffset] = 0; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_VSUNISYSTEM ) { + Config.controller.nVSUnisystem[nID+nOffset] = 0; + } + ::SetWindowText( hWndCtrl, "----" ); + bSet = TRUE; + } else { + for( i = 0; i < 512; i++ ) { + if( DirectInput.m_Sw[i] ) { + if( (str=DirectInput.SearchKeyName( i )) ) { + if( m_PageSel < 4 ) { + Config.controller.nButton[m_PageSel][nID+nOffset] = i; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_CRAZYCLIMBER ) { + Config.controller.nExButton[0][nID+nOffset] = i; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_FAMLYTRAINER ) { + Config.controller.nExButton[1][nID+nOffset] = i; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_EXCITINGBOXING ) { + Config.controller.nExButton[2][nID+nOffset] = i; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_MAHJANG ) { + Config.controller.nExButton[3][nID+nOffset] = i; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_NSFPLAYER ) { + Config.controller.nNsfButton[nID+nOffset] = i; + } else if( ControllerPageID[m_PageSel] == IDD_CTR_VSUNISYSTEM ) { + Config.controller.nVSUnisystem[nID+nOffset] = i; + } + ::SetWindowText( hWndCtrl, str ); + bSet = TRUE; + } + } + } + } + + if( bSet ) { + // Button Pressed + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; + ::InvalidateRect( hWndCtrl, NULL, TRUE ); + } + m_bCancelMode = FALSE; + } else { + // Flashing + HDC hDC = ::GetDC( hWndCtrl ); + RECT rc; + ::GetClientRect( hWndCtrl, &rc ); + DWORD c = ((::timeGetTime()-m_TimerStart)/3)&0xFF; + if( c > 0x7F ) + c = 0x80 - (c - 0x7F); + c *= 2; + ::SetBkColor( hDC, RGB(c,c,c) ); + ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + ::ReleaseDC( hWndCtrl, hDC ); + } + } + } + return FALSE; +} + +DLGCMD CControllerDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnOK\n" ); + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; + } + m_bCancelMode = FALSE; + + for( INT page = 0; page < 4; page++ ) { + Config.controller.nRapid[page][0] = ::SendDlgItemMessage( m_Page[page].m_hWnd, IDC_CTR_A_RAPID_LIST, LB_GETCURSEL, 0, 0 ); + Config.controller.nRapid[page][1] = ::SendDlgItemMessage( m_Page[page].m_hWnd, IDC_CTR_B_RAPID_LIST, LB_GETCURSEL, 0, 0 ); + } + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CControllerDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnCancel\n" ); +// if( m_bCancelMode ) +// return; + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; + } + m_bCancelMode = FALSE; + + Config.controller = m_ConfigSave; + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CControllerDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CControllerDlg::OnDefault\n" ); + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_ControlID = 0; + } + m_bCancelMode = FALSE; + + switch( ControllerPageID[m_PageSel] ) { + case IDD_CTR_PLAYER1: + Config.controller.DefaultController1(); + break; + case IDD_CTR_PLAYER2: + Config.controller.DefaultController2(); + break; + case IDD_CTR_PLAYER3: + Config.controller.DefaultController3(); + break; + case IDD_CTR_PLAYER4: + Config.controller.DefaultController4(); + break; + case IDD_CTR_CRAZYCLIMBER: + Config.controller.DefaultExController0(); + break; + case IDD_CTR_FAMLYTRAINER: + Config.controller.DefaultExController1(); + break; + case IDD_CTR_EXCITINGBOXING: + Config.controller.DefaultExController2(); + break; + case IDD_CTR_MAHJANG: + Config.controller.DefaultExController3(); + break; + case IDD_CTR_NSFPLAYER: + Config.controller.DefaultNsfController(); + break; + case IDD_CTR_VSUNISYSTEM: + Config.controller.DefaultVSUnisystem(); + break; + default: + break; + } + OnPageSetup( m_PageSel ); +} + diff --git a/References/VirtuaNESex_src_191105/ControllerDlg.h b/References/VirtuaNESex_src_191105/ControllerDlg.h new file mode 100644 index 00000000..e873458e --- /dev/null +++ b/References/VirtuaNESex_src_191105/ControllerDlg.h @@ -0,0 +1,81 @@ +// +// Rg[_CAONX +// +#ifndef __CCONTROLLERDLG_INCLUDED__ +#define __CCONTROLLERDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CControllerPageDlg : public CWnd +{ +public: + BOOL Create( UINT nID, HWND hWndParent ); + // Override from CWnd + void Destroy(); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnClicked( DLGCMDPARAM ); + // + + UINT m_nPageID; +private: +}; + +class CControllerDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + + // Override from CWnd + BOOL PreTranslateMessage( MSG* pMsg ); +protected: + void OnInitialMember(); + void OnPageSetup( UINT nPage ); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnDestroy( DLGMSGPARAM ); + DLGMSG OnTimer( DLGMSGPARAM ); + DLGNOTIFY OnSelectChange( DLGNOTIFYPARAM ); + DLGNOTIFY OnSettingSelectChange( DLGCMDPARAM ); + DLGCMD OnClicked( DLGCMDPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + // + + enum { PAGE_MAX=12 }; + + BOOL m_bCancelMode; + + INT m_ControlID; + INT m_TimerID; + INT m_TimerStart; + INT m_TimerCount; + + INT m_SettingSel; + + INT m_PageSel; + INT m_PageNum; + CControllerPageDlg m_Page[PAGE_MAX]; + + CCfgController m_ConfigSave; + + static UINT ControllerPageID[]; + +private: +}; + +#endif // !__CCONTROLLERDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Crclib.cpp b/References/VirtuaNESex_src_191105/Crclib.cpp new file mode 100644 index 00000000..9e4e760a --- /dev/null +++ b/References/VirtuaNESex_src_191105/Crclib.cpp @@ -0,0 +1,71 @@ +// +// CRC`FbNpCuNX +// +#include "Crclib.h" + +BOOL CRC::m_Init = FALSE; +BOOL CRC::m_InitRev = FALSE; +DWORD CRC::m_CrcTable[ UCHAR_MAX+1 ]; +DWORD CRC::m_CrcTableRev[ UCHAR_MAX+1 ]; + +#define CRCPOLY1 0x04C11DB7UL +#define CRCPOLY2 0xEDB88320UL + +DWORD CRC::Crc( INT size, LPBYTE c ) +{ + if( !m_Init ) { + MakeTable(); + m_Init = TRUE; + } + + DWORD r = 0xFFFFFFFFUL; + while( --size >= 0 ) { + r = (r << CHAR_BIT) ^ m_CrcTable[(BYTE)(r >> (32 - CHAR_BIT)) ^ *c++]; + } + return ~r & 0xFFFFFFFFUL; +} + +DWORD CRC::CrcRev( INT size, LPBYTE c ) +{ + if( !m_InitRev ) { + MakeTableRev(); + m_InitRev = TRUE; + } + + DWORD r = 0xFFFFFFFFUL; + while( --size >= 0 ) { + r = (r >> CHAR_BIT) ^ m_CrcTableRev[(BYTE)r ^ *c++]; + } + return r ^ 0xFFFFFFFFUL; +} + +void CRC::MakeTable() +{ +INT i, j; +DWORD r; + + for( i = 0; i <= UCHAR_MAX; i++ ) { + r = (DWORD)i << (32 - CHAR_BIT); + for( j = 0; j < CHAR_BIT; j++ ) { + if( r & 0x80000000UL ) r = (r << 1) ^ CRCPOLY1; + else r <<= 1; + } + m_CrcTable[i] = r & 0xFFFFFFFFUL; + } +} + +void CRC::MakeTableRev() +{ +INT i, j; +DWORD r; + + for( i = 0; i <= UCHAR_MAX; i++ ) { + r = i; + for( j = 0; j < CHAR_BIT; j++ ) { + if( r & 1 ) r = (r >> 1) ^ CRCPOLY2; + else r >>= 1; + } + m_CrcTableRev[i] = r; + } +} + diff --git a/References/VirtuaNESex_src_191105/Crclib.h b/References/VirtuaNESex_src_191105/Crclib.h new file mode 100644 index 00000000..97a19027 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Crclib.h @@ -0,0 +1,24 @@ +// +// CRC`FbNpCuNX +// +#define WIN32_LEAN_AND_MEAN +#include +#include + +class CRC +{ +public: + static DWORD Crc( INT size, LPBYTE c ); + static DWORD CrcRev( INT size, LPBYTE c ); // t + +protected: + static void MakeTable(); + static void MakeTableRev(); // t + + static BOOL m_Init; + static BOOL m_InitRev; + static DWORD m_CrcTable[ UCHAR_MAX+1 ]; + static DWORD m_CrcTableRev[ UCHAR_MAX+1 ]; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/DatachBarcodeDlg.cpp b/References/VirtuaNESex_src_191105/DatachBarcodeDlg.cpp new file mode 100644 index 00000000..2c2f4cf5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/DatachBarcodeDlg.cpp @@ -0,0 +1,173 @@ +// +// DATACHo[R[hog[_CAONX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +#include +#include +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Config.h" + +#include "Wnd.h" +#include "DatachBarcodeDlg.h" + +#include "EmuThread.h" +#include "nes.h" +#include "mapper.h" + +// bZ[W +DLG_MESSAGE_BEGIN(CDatachBarcodeDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +DLG_ON_MESSAGE( WM_DESTROY, OnDestroy ) +DLG_ON_MESSAGE( WM_CLOSE, OnClose ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +//DLG_ON_COMMAND( IDC_EBB_CODE, OnCodeinput ) +DLG_ON_COMMAND( IDC_EBB_TRANSFER, OnCodeTransfer ) +DLG_ON_COMMAND( IDC_EBB_RANDOM, OnCodeCreate ) + +DLG_ON_COMMAND_NOTIFY( IDC_EBB_CODE, EN_CHANGE, OnCodeinput ) + +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +//DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_KEYDOWN, OnKeyDownListView ) +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +BOOL CDatachBarcodeDlg::Create( HWND hWndParent ) +{ + // e̓fXNgbvɂ + m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_EXT_BARCODEBATTLER), + NULL, g_DlgProc, (LPARAM)this ); + if( !m_hWnd ) + return FALSE; + + // [hX_CAOXgɉ + CWndList::Add( this ); + + return TRUE; +} + +void CDatachBarcodeDlg::Destroy() +{ + if( m_hWnd ) { + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcBarcodePos ); + + // [hX_CAOXg폜 + CWndList::Del( this ); + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +DLGMSG CDatachBarcodeDlg::OnInitDialog( DLGMSGPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnInitDialog\n" ); + + // ʒuC + if( Config.general.rcBarcodePos.right-Config.general.rcBarcodePos.left != 0 + && Config.general.rcBarcodePos.bottom-Config.general.rcBarcodePos.top != 0 ) { + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, Config.general.rcBarcodePos.left, Config.general.rcBarcodePos.top, + 0, 0, SWP_NOSIZE | SWP_NOZORDER ); + } + + ::SendDlgItemMessage( m_hWnd, IDC_EBB_CODE, EM_SETLIMITTEXT, 13, 0 ); + CTRLENABLE( IDC_EBB_TRANSFER, FALSE ); + + ::srand( (unsigned)::time( NULL ) ); + + return TRUE; +} + +DLGMSG CDatachBarcodeDlg::OnActivate( DLGMSGPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnActivate\n" ); + + if( LOWORD(wParam) == WA_INACTIVE ) { + DEBUGOUT( "CDatachBarcodeDlg::OnActivate:Inactive\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 ); + } else { + DEBUGOUT( "CDatachBarcodeDlg::OnActivate:Active\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 ); + } + + return FALSE; +} + +DLGMSG CDatachBarcodeDlg::OnDestroy( DLGMSGPARAM ) +{ + return TRUE; +} + +DLGMSG CDatachBarcodeDlg::OnClose( DLGMSGPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnClose\n" ); + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 + return TRUE; +} + +DLGCMD CDatachBarcodeDlg::OnCancel( DLGCMDPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnCancel\n" ); + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 +} + +DLGCMD CDatachBarcodeDlg::OnCodeinput( DLGCMDPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnCodeinput\n" ); + + INT len = ::SendDlgItemMessage( m_hWnd, IDC_EBB_CODE, WM_GETTEXTLENGTH, 0, 0 ); + CTRLENABLE( IDC_EBB_TRANSFER, ((len==8)||(len==13))?TRUE:FALSE ); +} + +DLGCMD CDatachBarcodeDlg::OnCodeTransfer( DLGCMDPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnCodeTransfer\n" ); + + if( !Emu.IsRunning() ) + return; + + BYTE code[14], *p; + p = code; + INT len = ::GetDlgItemText( m_hWnd, IDC_EBB_CODE, (LPTSTR)code, 14 ); + + Emu.EventParam2( CEmuThread::EV_BARCODE, (LONG)code, (LONG)len ); +} + +DLGCMD CDatachBarcodeDlg::OnCodeCreate( DLGCMDPARAM ) +{ + DEBUGOUT( "CDatachBarcodeDlg::OnCodeCreate\n" ); + + BYTE code[14]; + INT digit, sum; + + sum = 0; + for( INT i = 0; i < 12; i++ ) { + digit = ::rand()%10; + code[i] = '0'+digit; + sum += digit*((i&1)?3:1); + } + code[12] = '0'+((10-(sum%10))%10); + code[13] = '\0'; + + ::SetDlgItemText( m_hWnd, IDC_EBB_CODE, (LPCTSTR)code ); +} + diff --git a/References/VirtuaNESex_src_191105/DatachBarcodeDlg.h b/References/VirtuaNESex_src_191105/DatachBarcodeDlg.h new file mode 100644 index 00000000..af27f560 --- /dev/null +++ b/References/VirtuaNESex_src_191105/DatachBarcodeDlg.h @@ -0,0 +1,40 @@ +// +// DATACHo[R[hog[_CAONX +// +#ifndef __CDATACHBARCODEDLG_INCLUDED__ +#define __CDATACHBARCODEDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +#include +#include +using namespace std; + +#include "Wnd.h" + +class CDatachBarcodeDlg : public CWnd +{ +public: + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnActivate( DLGMSGPARAM ); + DLGMSG OnDestroy( DLGMSGPARAM ); + DLGMSG OnClose( DLGMSGPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnCodeinput( DLGCMDPARAM ); + DLGCMD OnCodeTransfer( DLGCMDPARAM ); + DLGCMD OnCodeCreate( DLGCMDPARAM ); + // +private: +}; + +#endif // !__CDATACHBARCODEDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Debug/Chinese.vlp b/References/VirtuaNESex_src_191105/Debug/Chinese.vlp new file mode 100644 index 00000000..34d05cdc Binary files /dev/null and b/References/VirtuaNESex_src_191105/Debug/Chinese.vlp differ diff --git a/References/VirtuaNESex_src_191105/Debug/VirtuaNESex.ini b/References/VirtuaNESex_src_191105/Debug/VirtuaNESex.ini new file mode 100644 index 00000000..b1b9c15d --- /dev/null +++ b/References/VirtuaNESex_src_191105/Debug/VirtuaNESex.ini @@ -0,0 +1,211 @@ +[Path] +RomAutoRunPath=.\ +RomPathUse=1 +SavePathUse=1 +StatePathUse=1 +SnapshotPathUse=1 +MoviePathUse=1 +WavePathUse=1 +CheatPathUse=1 +RomPath=.\roms\ +SavePath=.\save\ +StatePath=.\state\ +SnapshotPath=.\snapshot\ +MoviePath=.\movie\ +WavePath=.\wave\ +CheatPath=.\cheatcode\ +[General] +DoubleExecute=1 +StartupLauncher=0 +WindowZoom=0 +WindowPos=5B020000C10000006F040000E002000073 +ScreenZoom=1 +SearchDialogPos=0000000000000000000000000000000000 +PatternViewPos=0000000000000000000000000000000000 +NameTableViewPos=0000000000000000000000000000000000 +PaletteViewPos=0000000000000000000000000000000000 +MemoryViewPos=A50000009E00000078020000BC0200007B +BarcodePos=0000000000000000000000000000000000 +PaletteEditPos=0000000000000000000000000000000000 +JoyAxisDisable=0 +JoyAxisSetting=000000000000000000000000000000000000000000000000000000000000000000 +[Emulation] +IllegalOp=0 +AutoFrameSkip=1 +Throttle=1 +ThrottleFPS=120 +Background=0 +Priority=3 +FourPlayer=1 +CrcCheck=1 +DiskThrottle=1 +LoadFullscreen=0 +PNGsnapshot=0 +[Graphics] +Aspect=0 +SpriteMax=1 +AllLine=1 +FPSDisp=0 +TVFrameMode=0 +ScanlineMode=0 +ScanlineColor=75 +SyncDraw=0 +MaxZoom=0 +LeftClip=1 +WindowVSync=0 +DiskAccessLamp=0 +DoubleSize=0 +SystemMemory=0 +UseHEL=0 +NoSquareList=0 +GraphicsFilter=0 +DisplayWidth=640 +DisplayHeight=480 +DisplayDepth=32 +DisplayRate=56 +PaletteUse=0 +PaletteFile= +[Sound] +Enable=1 +DisableVolumeEffect=0 +ExtraSoundEnable=1 +SamplingRate=22050 +SamplingBits=8 +BufferSize=4 +FilterType=0 +Volume=640064006400640064006400640064006400640064006400640064006400640040 +[ShortCut] +TBL00=18402E402640314020401E400000000017401140000000000000000000002D4070 +TBL01=3B003C0019000F009C004E004A0039000E0000000000000000000000000000001A +TBL02=0C000D003D003E0000000000000000000000000000000000000000000000000094 +TBL03=06000200030004000500000000000000198013801E801F8032800000000000002F +TBL04=3F004000410042001C800000000000000E400240034004400540064007400840CF +TBL05=09400A400B400C4090407D400000000000000000000000000000000000000000B7 +TBL06=19405700584057405800434043004400444000000000000000000000C740CF40DB +TBL07=D200D30000000000000000000000000000000000000000000000000000000000A5 +TBL08=000000000000000000000000000000000000000000000000000000000000000000 +TBL09=000000000000000000000000000000000000000000000000000000000000000000 +TBL10=000000000000000000000000000000000000000000000000000000000000000000 +TBL11=000000000000000000000000000000000000000000000000000000000000000000 +TBL12=000000000000000000000000000000000000000000000000000000000000000000 +TBL13=000000000000000000000000000000000000000000000000000000000000000000 +TBL14=000000000000000000000000000000000000000000000000000000000000000000 +TBL15=000000000000000000000000000000000000000000000000000000000000000000 +TBL16=52404F40504051404B404C404D4047404840494052804F80508051804B804C8057 +TBL17=4D8047804880498000000000000000000000000000000000000000000000000025 +TBL18=000000000000000000000000000000000000000000000000000000000000000000 +TBL19=000000000000000000000000000000000000000000000000000000000000000000 +TBL20=000000000000000000000000000000000000000000000000000000000000000000 +TBL21=000000000000000000000000000000000000000000000000000000000000000000 +TBL22=000000000000000000000000000000000000000000000000000000000000000000 +TBL23=000000000000000000000000000000000000000000000000000000000000000000 +TBL24=000000000000000000000000000000000000000000000000000000000000000000 +TBL25=000000000000000000000000000000000000000000000000000000000000000000 +TBL26=000000000000000000000000000000000000000000000000000000000000000000 +TBL27=000000000000000000000000000000000000000000000000000000000000000000 +TBL28=000000000000000000000000000000000000000000000000000000000000000000 +TBL29=000000000000000000000000000000000000000000000000000000000000000000 +TBL30=000000000000000000000000000000000000000000000000000000000000000000 +TBL31=000000000000000000000000000000000000000000000000000000000000000000 +[Controller 1] +Keys=120020001F0021002500240017001600220023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D +Rapid=0000000000 +[Controller 2] +Keys=480050004B004D00310030000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3 +Rapid=0000000000 +[Controller 3] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Rapid=0000000000 +[Controller 4] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Rapid=0000000000 +[Crazy Climber] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[Family Trainer] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[Exciting Boxing] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[Mahjang] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[NSF controller] +Keys=C800D000CB00CD00C900D1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA +[VS-Unisystem] +Keys=2E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E +[Movie] +UsePlayer=FF000000FF +ResetRec=0 +Rerecord=1 +LoopPlay=0 +PadDisplay=0 +[Launcher] +WindowPos=0000000000000000000000000000000000 +ColumnView=0101010101010101010101010101010110 +ColumnOrder=000102030405060708090A0B0C0D0E0F78 +ColumnWidth=A00030003000300030003000300030003000300030003000300030003000300070 +ListSelect=0 +SortDir=0 +SortType=0 +FolderUse=0000000000000000000000000000000000 +Folder00= +Folder01= +Folder02= +Folder03= +Folder04= +Folder05= +Folder06= +Folder07= +Folder08= +Folder09= +Folder10= +Folder11= +Folder12= +Folder13= +Folder14= +Folder15= +LastSelect= +ActivePause=0 +[Netplay] +ChatPos=0000000000000000000000000000000000 +NickName=NoName +RecnetPortNum=1 +RecentPort00=10000 +RecentPort01= +RecentPort02= +RecentPort03= +RecentPort04= +RecentPort05= +RecentPort06= +RecentPort07= +RecentPort08= +RecentPort09= +RecentPort10= +RecentPort11= +RecentPort12= +RecentPort13= +RecentPort14= +RecentPort15= +RecnetHostNum=1 +RecentHost00=localhost:10000 +RecentHost01= +RecentHost02= +RecentHost03= +RecentHost04= +RecentHost05= +RecentHost06= +RecentHost07= +RecentHost08= +RecentHost09= +RecentHost10= +RecentHost11= +RecentHost12= +RecentHost13= +RecentHost14= +RecentHost15= +[Recent Path List] +Path1=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\ +Path2=E:\Game\NES\NSF\ +Path3=E:\Game\NES\Rom\ +[Recent File List] +File1=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\[Subor]Karaoke(C).nsf +File2=E:\Game\NES\NSF\Contra.nsf +File3=E:\Game\NES\Rom\Contra(U).nes diff --git a/References/VirtuaNESex_src_191105/DebugOut.cpp b/References/VirtuaNESex_src_191105/DebugOut.cpp new file mode 100644 index 00000000..8fc76c56 --- /dev/null +++ b/References/VirtuaNESex_src_191105/DebugOut.cpp @@ -0,0 +1,62 @@ +// +// Debug output +// +#include "DebugOut.h" + +CDebugOut Dbg; + +static const CHAR szClassName[] = "DebugWindow_wndclass"; + +CDebugOut::CDebugOut() +{ +#if defined(_DEBUG) || defined(_DEBUGOUT) + hWndDebugOutput = ::FindWindow( szClassName, NULL ); + if( !hWndDebugOutput ) { + ::OutputDebugString( "DebugWindow ܂\n" ); + } +#endif +} + +void CDebugOut::Clear() +{ +#if defined(_DEBUG) || defined(_DEBUGOUT) + if( hWndDebugOutput ) { + if( ::IsWindow( hWndDebugOutput ) ) { + ::SendMessage( hWndDebugOutput, WM_APP+1, (WPARAM)NULL, (LPARAM)NULL ); + } + } +#endif +} + +void __cdecl CDebugOut::Out( LPSTR fmt, ... ) +{ +#if defined(_DEBUG) || defined(_DEBUGOUT) + CHAR buf[1000]; + va_list va; + va_start( va, fmt ); + ::vsprintf( buf, fmt, va ); + + if( hWndDebugOutput ) { + if( ::IsWindow( hWndDebugOutput ) ) { + COPYDATASTRUCT cds; + cds.dwData = 0; + cds.lpData = (void*)buf; + cds.cbData = ::strlen(buf)+1; // I[NULL + // 񑗐M + ::SendMessage( hWndDebugOutput, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds ); + } else { + ::OutputDebugString( buf ); + } + } else { + ::OutputDebugString( buf ); + } +#endif +} + +void CDebugOut::Out( const string& str ) +{ +#if defined(_DEBUG) || defined(_DEBUGOUT) + Out( (LPSTR)str.c_str() ); +#endif +} + diff --git a/References/VirtuaNESex_src_191105/DebugOut.h b/References/VirtuaNESex_src_191105/DebugOut.h new file mode 100644 index 00000000..0d5e596a --- /dev/null +++ b/References/VirtuaNESex_src_191105/DebugOut.h @@ -0,0 +1,45 @@ +// +// Debug output +// +#ifndef __DEBUGOUT_INCLUDED__ +#define __DEBUGOUT_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +using namespace std; + +typedef void (__cdecl *DEBUGWINDOWOUTPUT)(LPCTSTR); + +class CDebugOut { +public: + CDebugOut(); + + void Clear(); + + void __cdecl Out( LPSTR fmt, ... ); + void Out( const string& str ); + +protected: + HWND hWndDebugOutput; + +private: +}; + +extern CDebugOut Dbg; + +#if defined(_DEBUG) || defined(_DEBUGOUT) +#define DEBUGOUT Dbg.Out +#else +#define DEBUGOUT +#endif // !_DEBUG + +#if defined(_DEBUG) || defined(_DEBUGOUT) +#define DEBUGCLR Dbg.Clear +#else +#define DEBUGCLR +#endif // !_DEBUG + +#endif // !__DEBUGOUT_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/DipSwitchDlg.cpp b/References/VirtuaNESex_src_191105/DipSwitchDlg.cpp new file mode 100644 index 00000000..54a678ca --- /dev/null +++ b/References/VirtuaNESex_src_191105/DipSwitchDlg.cpp @@ -0,0 +1,130 @@ +// +// `bg_CAONX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "EmuThread.h" +#include "VsUnisystem.h" + +#include "Wnd.h" +#include "DipSwitchDlg.h" + +// bZ[W +DLG_MESSAGE_BEGIN(CDipSwitchDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +INT CDipSwitchDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_EXT_VSUNISYSTEM), + hWndParent, g_DlgProc, (LPARAM)this ); +} + + +DLGMSG CDipSwitchDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CDipSwitchDlg::OnInitDialog\n" ); + + for( INT i = IDC_EVS_DIPCOMBO0; i <= IDC_EVS_DIPCOMBO7; i++ ) { + ::SendDlgItemMessage( m_hWnd, i, CB_RESETCONTENT, 0, 0 ); + } + + BYTE val = Emu.GetNES()->GetVSDipSwitch(); + VSDIPSWITCH* dip = Emu.GetNES()->GetVSDipSwitchTable(); + +DEBUGOUT( "GET DIPSWITCH:%02X\n", val ); + + BYTE mask; + + INT nStatic = IDC_EVS_DIPNAME0; + INT nCombo = IDC_EVS_DIPCOMBO0; + BOOL bFlag; + INT nCount, nSelect; + + bFlag = FALSE; + nCount = nSelect = 0; + for(;;) { + if( dip->name == NULL && dip->value == 0x0000 ) { + break; + } else if( dip->value == 0x00FF ) { + bFlag = FALSE; + ::SendDlgItemMessage( m_hWnd, nCombo, CB_SETCURSEL, (WPARAM)nSelect, 0 ); + nCombo++; + } else if( !bFlag ) { + bFlag = TRUE; + ::SetDlgItemText( m_hWnd, nStatic, (LPCTSTR)dip->name ); + mask = dip->value>>8; + nCount = 0; + nStatic++; + } else { + if( dip->value == (val & mask) ) + nSelect = nCount; + ::SendDlgItemMessage( m_hWnd, nCombo, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dip->name ); + ::SendDlgItemMessage( m_hWnd, nCombo, CB_SETITEMDATA, (WPARAM)nCount, (LPARAM)(dip->value&0xFF) ); + nCount++; + } + dip++; + } + m_nDispCount = nStatic-IDC_EVS_DIPNAME0; + + // gȂz͔\ɂ + for( ; nStatic <= IDC_EVS_DIPNAME7; nStatic++, nCombo++ ) { + ::ShowWindow( ::GetDlgItem( m_hWnd, nStatic ), SW_HIDE ); + ::ShowWindow( ::GetDlgItem( m_hWnd, nCombo ), SW_HIDE ); + } + + return TRUE; +} + +DLGCMD CDipSwitchDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CDipSwitchDlg::OnOK\n" ); + + // IĂzItemData擾DipSwitchf[^蒼(OnInitDialogItemDataݒς) + BYTE dipval = 0; + for( INT i = IDC_EVS_DIPCOMBO0; i < IDC_EVS_DIPCOMBO0+m_nDispCount; i++ ) { + INT sel = ::SendDlgItemMessage( m_hWnd, i, CB_GETCURSEL, 0, 0 ); + DWORD val = (DWORD)::SendDlgItemMessage( m_hWnd, i, CB_GETITEMDATA, (WPARAM)sel, 0 ); + + dipval |= val & 0xFF; + } + + Emu.GetNES()->SetVSDipSwitch( dipval ); + +DEBUGOUT( "SET DIPSWITCH:%02X\n", dipval ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CDipSwitchDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CDipSwitchDlg::OnCancel\n" ); + ::EndDialog( m_hWnd, IDCANCEL ); +} + diff --git a/References/VirtuaNESex_src_191105/DipSwitchDlg.h b/References/VirtuaNESex_src_191105/DipSwitchDlg.h new file mode 100644 index 00000000..01f5975b --- /dev/null +++ b/References/VirtuaNESex_src_191105/DipSwitchDlg.h @@ -0,0 +1,36 @@ +// +// `bg_CAONX +// +#ifndef __CDIPSWITCHDLG_INCLUDED__ +#define __CDIPSWITCHDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +using namespace std; + +#include "Wnd.h" + +class CDipSwitchDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // + + INT m_nDispCount; + +private: +}; + +#endif // !__CDIPSWITCHDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/DirectDraw.cpp b/References/VirtuaNESex_src_191105/DirectDraw.cpp new file mode 100644 index 00000000..65c8bfad --- /dev/null +++ b/References/VirtuaNESex_src_191105/DirectDraw.cpp @@ -0,0 +1,2285 @@ +// +// DirectDraw class +// +#include "DebugOut.h" +#include "DirectDraw.h" +#include "COM.h" + +#include "MMU.h" + +extern BOOL g_bSan2; +extern unsigned char pFont[256*1024]; + +#define MIN_GROUP 0x6 +#define MIN_INDEX 0x40 +#define MAX_GROUP 0xF +#define MAX_INDEX 0x76 +int txt[MAX_GROUP][MAX_INDEX] = +{ +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x130,0x131,0x126,0x000,0x000,0x151,0x000,0x000,0x39F,0x132,0x0C8,0x133,0x134,0x135,0x3A0,0x3A1,0x3A2,0x152, +0x000,0x000,0x000,0x000,0x000,0x000,0x0FF,0x34D,0x138,0x0C5,0x25B,0x1C2,0x3A3,0x3A4,0x017,0x3A5,0x364,0x029,0x120,0x000,0x000,0x3A6,0x311,0x39F,0x39F,0x39F,0x39F,0x39F,0x39F,0x39F,0x39F,0x39F, +0x39F,0x39F,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x001,0x002,0x003,0x004,0x005,0x006,0x007,0x008,0x009,0x00A,0x00B,0x00C, +0x00D,0x00E,0x00F,0x010,0x011,0x012,0x013,0x014,0x015,0x016,0x017,0x018,0x019,0x01A,0x01B,0x01C,0x01D,0x01E,0x01F,0x020,0x021,0x022,0x023,0x024,0x025,0x026,0x027,0x028,0x029,0x02A,0x02B,0x02C, +0x02D,0x02E,0x02F,0x030,0x1B9,0x1BA,0x1BB,0x1BC,0x1BD,0x1BE,0x1BF,0x1C0,0x1C1,0x1C2,0x1C3,0x1C4,0x1C5,0x1C6,0x1C7,0x1C8,0x1C9,0x1CA,0x1CB,0x1CC,0x1CD,0x1CE,0x1CF,0x1D0,0x1D1,0x1D2,0x1D3,0x1D4, +0x1D5,0x1D6,0x1D7,0x1D8,0x1D9,0x1DA,0x1DB,0x1DC,0x1DD,0x1DE,0x1DF,0x1E0,0x1E1,0x1E2,0x1E3,0x1E4,0x1E5,0x1E6,0x1E7,0x1E8,0x1E9,0x1EA,0x1EB,0x1EC,0x1ED,0x1EE,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039,0x03A,0x03B,0x03C,0x03D,0x03E,0x03F,0x040,0x041,0x042,0x043,0x044,0x045,0x046,0x047, +0x048,0x049,0x04A,0x04B,0x04C,0x04D,0x04E,0x04F,0x050,0x051,0x052,0x053,0x054,0x055,0x056,0x057,0x058,0x059,0x05A,0x05B,0x05C,0x05D,0x05E,0x05F,0x060,0x061,0x1EF,0x1F0,0x1F1,0x1F2,0x1F3,0x1F4, +0x1F5,0x1F6,0x1F7,0x1F8,0x1F9,0x1FA,0x1FB,0x1FC,0x1FD,0x1FE,0x1FF,0x200,0x201,0x202,0x203,0x204,0x205,0x206,0x207,0x208,0x209,0x20A,0x20B,0x20C,0x20D,0x20E,0x20F,0x210,0x211,0x212,0x213,0x214, +0x215,0x216,0x217,0x218,0x219,0x21A,0x21B,0x21C,0x21D,0x21E,0x21F,0x220,0x221,0x222,0x223,0x224,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x062, +0x063,0x064,0x065,0x066,0x067,0x068,0x069,0x06A,0x06B,0x06C,0x06D,0x06E,0x06F,0x070,0x071,0x072,0x073,0x074,0x075,0x076,0x077,0x078,0x079,0x07A,0x07B,0x07C,0x07D,0x07E,0x07F,0x080,0x081,0x082, +0x083,0x084,0x085,0x086,0x087,0x088,0x089,0x08A,0x08B,0x08C,0x08D,0x08E,0x08F,0x090,0x091,0x092,0x225,0x226,0x227,0x228,0x229,0x22A,0x22B,0x22C,0x22D,0x22E,0x22F,0x230,0x231,0x232,0x233,0x234, +0x235,0x236,0x237,0x238,0x239,0x23A,0x23B,0x23C,0x23D,0x23E,0x23F,0x240,0x241,0x242,0x243,0x244,0x245,0x246,0x247,0x248,0x249,0x24A,0x24B,0x24C,0x24D,0x24E,0x24F,0x250,0x251,0x252,0x253,0x254, +0x255,0x256,0x257,0x258,0x259,0x25A,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x093,0x094,0x095,0x096,0x097,0x098,0x099,0x09A,0x09B,0x09C,0x09D, +0x09E,0x09F,0x0A0,0x0A1,0x0A2,0x0A3,0x0A4,0x0A5,0x0A6,0x0A7,0x0A8,0x0A9,0x0AA,0x0AB,0x0AC,0x0AD,0x0AE,0x0AF,0x0B0,0x0B1,0x0B2,0x0B3,0x0B4,0x0B5,0x0B6,0x0B7,0x0B8,0x0B9,0x0BA,0x0BB,0x0BC,0x0BD, +0x0BE,0x0BF,0x0C0,0x0C1,0x0C2,0x0C3,0x25B,0x25C,0x25D,0x25E,0x25F,0x260,0x261,0x262,0x263,0x264,0x265,0x266,0x267,0x268,0x269,0x26A,0x26B,0x26C,0x26D,0x26E,0x26F,0x270,0x271,0x272,0x273,0x274, +0x275,0x276,0x277,0x278,0x279,0x27A,0x27B,0x27C,0x27D,0x27E,0x27F,0x280,0x281,0x282,0x283,0x284,0x285,0x286,0x287,0x288,0x289,0x28A,0x28B,0x28C,0x28D,0x28E,0x28F,0x290,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x0C4,0x0C5,0x0C6,0x0C7,0x0C8,0x0C9,0x0CA,0x0CB,0x0CC,0x0CD,0x0CE,0x0CF,0x0D0,0x0D1,0x0D2,0x0D3,0x0D4,0x0D5,0x0D6,0x0D7,0x0D8, +0x0D9,0x0DA,0x0DB,0x0DC,0x0DD,0x0DE,0x0DF,0x0E0,0x0E1,0x0E2,0x0E3,0x0E4,0x0E5,0x0E6,0x0E7,0x0E8,0x0E9,0x0EA,0x0EB,0x0EC,0x0ED,0x0EE,0x0EF,0x0F0,0x0F1,0x0F2,0x0F3,0x0F4,0x291,0x292,0x293,0x294, +0x295,0x296,0x297,0x298,0x299,0x29A,0x29B,0x29C,0x29D,0x29E,0x29F,0x2A0,0x2A1,0x2A2,0x2A3,0x2A4,0x2A5,0x2A6,0x2A7,0x2A8,0x2A9,0x2AA,0x2AB,0x2AC,0x2AD,0x2AE,0x2AF,0x2B0,0x2B1,0x2B2,0x2B3,0x2B4, +0x2B5,0x2B6,0x2B7,0x2B8,0x2B9,0x2BA,0x2BB,0x2BC,0x2BD,0x2BE,0x2BF,0x2C0,0x2C1,0x2C2,0x2C3,0x2C4,0x2C5,0x2C6,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x0F5,0x0F6,0x0F7,0x0F8,0x0F9,0x0FA,0x0FB,0x0FC,0x0FD,0x0FE,0x0FF,0x100,0x101,0x102,0x103,0x104,0x105,0x106,0x107,0x108,0x109,0x10A,0x10B,0x10C,0x10D,0x10E,0x10F,0x110,0x111,0x112,0x113, +0x114,0x115,0x116,0x117,0x118,0x119,0x11A,0x11B,0x11C,0x11D,0x11E,0x11F,0x120,0x121,0x122,0x123,0x124,0x125,0x2C7,0x2C8,0x2C9,0x2CA,0x2CB,0x2CC,0x2CD,0x2CE,0x2CF,0x2D0,0x2D1,0x2D2,0x2D3,0x2D4, +0x2D5,0x2D6,0x2D7,0x2D8,0x2D9,0x2DA,0x2DB,0x2DC,0x2DD,0x2DE,0x2DF,0x2E0,0x2E1,0x2E2,0x2E3,0x2E4,0x2E5,0x2E6,0x2E7,0x2E8,0x2E9,0x2EA,0x2EB,0x2EC,0x2ED,0x2EE,0x2EF,0x2F0,0x2F1,0x2F2,0x2F3,0x2F4, +0x2F5,0x2F6,0x2F7,0x2F8,0x2F9,0x2FA,0x2FB,0x2FC,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x126,0x127,0x128,0x129,0x12A,0x12B,0x12C,0x12D,0x12E, +0x12F,0x130,0x131,0x132,0x133,0x134,0x135,0x136,0x137,0x138,0x139,0x13A,0x13B,0x13C,0x13D,0x13E,0x13F,0x140,0x141,0x142,0x143,0x144,0x145,0x146,0x147,0x148,0x149,0x14A,0x14B,0x14C,0x14D,0x14E, +0x14F,0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x2FD,0x2FE,0x2FF,0x300,0x301,0x302,0x303,0x304,0x305,0x306,0x307,0x308,0x309,0x30A,0x30B,0x30C,0x30D,0x30E,0x30F,0x310,0x311,0x312,0x313,0x314, +0x315,0x316,0x317,0x318,0x319,0x31A,0x31B,0x31C,0x31D,0x31E,0x31F,0x320,0x321,0x322,0x323,0x324,0x325,0x326,0x327,0x328,0x329,0x32A,0x32B,0x32C,0x32D,0x32E,0x32F,0x330,0x331,0x332,0x000,0x000, +0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x157,0x158,0x159,0x15A,0x15B,0x15C,0x15D,0x15E,0x15F,0x160,0x161,0x162,0x163,0x164,0x165,0x166,0x167,0x168,0x169, +0x16A,0x16B,0x16C,0x16D,0x16E,0x16F,0x170,0x171,0x172,0x173,0x174,0x175,0x176,0x177,0x178,0x179,0x17A,0x17B,0x17C,0x17D,0x17E,0x17F,0x180,0x181,0x182,0x183,0x184,0x185,0x186,0x187,0x333,0x334, +0x335,0x336,0x337,0x338,0x339,0x33A,0x33B,0x33C,0x33D,0x33E,0x33F,0x340,0x341,0x342,0x343,0x344,0x345,0x346,0x347,0x348,0x349,0x34A,0x34B,0x34C,0x34D,0x34E,0x34F,0x350,0x351,0x352,0x353,0x354, +0x355,0x356,0x357,0x358,0x359,0x35A,0x35B,0x35C,0x35D,0x35E,0x35F,0x360,0x361,0x362,0x363,0x364,0x365,0x366,0x367,0x368,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, +0x000,0x000,0x000,0x188,0x189,0x18A,0x18B,0x18C,0x18D,0x18E,0x18F,0x190,0x191,0x192,0x193,0x194,0x195,0x196,0x197,0x198,0x199,0x19A,0x19B,0x19C,0x19D,0x19E,0x19F,0x1A0,0x1A1,0x1A2,0x1A3,0x1A4, +0x1A5,0x1A6,0x1A7,0x1A8,0x1A9,0x1AA,0x1AB,0x1AC,0x1AD,0x1AE,0x1AF,0x1B0,0x1B1,0x1B2,0x1B3,0x1B4,0x1B5,0x1B6,0x1B7,0x1B8,0x369,0x36A,0x36B,0x36C,0x36D,0x36E,0x36F,0x370,0x371,0x372,0x373,0x374, +0x375,0x376,0x377,0x378,0x379,0x37A,0x37B,0x37C,0x37D,0x37E,0x37F,0x380,0x381,0x382,0x383,0x384,0x385,0x386,0x387,0x388,0x389,0x38A,0x38B,0x38C,0x38D,0x38E,0x38F,0x390,0x391,0x392,0x393,0x394, +0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,}; + +CDirectDraw DirectDraw; + +#define COMUSE TRUE +#define DYNDLL FALSE + +CDirectDraw::BLTFUNC CDirectDraw::NormalBltTable[] = { + &CDirectDraw::Render8bpp_Normal, + &CDirectDraw::Render16bpp_Normal, + &CDirectDraw::Render24bpp_Normal, + &CDirectDraw::Render32bpp_Normal, +}; +CDirectDraw::BLTFUNC CDirectDraw::ScanlineBltTable[] = { + &CDirectDraw::Render8bpp_Scanline, + &CDirectDraw::Render16bpp_Scanline, + &CDirectDraw::Render24bpp_Scanline, + &CDirectDraw::Render32bpp_Scanline, +}; +CDirectDraw::BLTFUNC CDirectDraw::DoubleBltTable[] = { + &CDirectDraw::Render8bpp_Double, + &CDirectDraw::Render16bpp_Double, + &CDirectDraw::Render24bpp_Double, + &CDirectDraw::Render32bpp_Double, +}; +CDirectDraw::BLTFUNC CDirectDraw::DoubleScanlineBltTable[] = { + &CDirectDraw::Render8bpp_DoubleScanline, + &CDirectDraw::Render16bpp_DoubleScanline, + &CDirectDraw::Render24bpp_DoubleScanline, + &CDirectDraw::Render32bpp_DoubleScanline, +}; +CDirectDraw::BLTFUNC CDirectDraw::nx2xSaIBltTable[] = { + &CDirectDraw::Render8bpp_Double, + &CDirectDraw::nx_2xSaI_16bpp, + &CDirectDraw::Render24bpp_Double, + &CDirectDraw::nx_2xSaI_32bpp, +}; +CDirectDraw::BLTFUNC CDirectDraw::nxSuper2xSaIBltTable[] = { + &CDirectDraw::Render8bpp_Double, + &CDirectDraw::nx_Super2xSaI_16bpp, + &CDirectDraw::Render24bpp_Double, + &CDirectDraw::nx_Super2xSaI_32bpp, +}; +CDirectDraw::BLTFUNC CDirectDraw::nxSuperEagleBltTable[] = { + &CDirectDraw::Render8bpp_Double, + &CDirectDraw::nx_SuperEagle_16bpp, + &CDirectDraw::Render24bpp_Double, + &CDirectDraw::nx_SuperEagle_32bpp, +}; +CDirectDraw::BLTFUNC CDirectDraw::nxScale2xBltTable[] = { + &CDirectDraw::Render8bpp_Double, + &CDirectDraw::nx_Scale2x_16bpp, + &CDirectDraw::Render24bpp_Double, + &CDirectDraw::nx_Scale2x_32bpp, +}; + +////////////////////////////////////////////////////////////////////// +// ftHgpbg +////////////////////////////////////////////////////////////////////// +CDirectDraw::PALBUF CDirectDraw::m_PalDefault[] = { +/* + 0x7F, 0x7F, 0x7F, 0x20, 0x00, 0xB0, 0x28, 0x00, 0xB8, 0x60, 0x10, 0xA0, 0x98, 0x20, 0x78, 0xB0, + 0x10, 0x30, 0xA0, 0x30, 0x00, 0x78, 0x40, 0x00, 0x48, 0x58, 0x00, 0x38, 0x68, 0x00, 0x38, 0x6C, + 0x00, 0x30, 0x60, 0x40, 0x30, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xBC, 0xBC, 0xBC, 0x40, 0x60, 0xF8, 0x40, 0x40, 0xFF, 0x90, 0x40, 0xF0, 0xD8, 0x40, 0xC0, 0xD8, + 0x40, 0x60, 0xE0, 0x50, 0x00, 0xC0, 0x70, 0x00, 0x88, 0x88, 0x00, 0x50, 0xA0, 0x00, 0x48, 0xA8, + 0x10, 0x48, 0xA0, 0x68, 0x40, 0x90, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFF, 0xFF, 0x60, 0xA0, 0xFF, 0x50, 0x80, 0xFF, 0xA0, 0x70, 0xFF, 0xF0, 0x60, 0xFF, 0xFF, + 0x60, 0xB0, 0xFF, 0x78, 0x30, 0xFF, 0xA0, 0x00, 0xE8, 0xD0, 0x20, 0x98, 0xE8, 0x00, 0x70, 0xF0, + 0x40, 0x70, 0xE0, 0x90, 0x60, 0xD0, 0xE0, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFF, 0xFF, 0x90, 0xD0, 0xFF, 0xA0, 0xB8, 0xFF, 0xC0, 0xB0, 0xFF, 0xE0, 0xB0, 0xFF, 0xFF, + 0xB8, 0xE8, 0xFF, 0xC8, 0xB8, 0xFF, 0xD8, 0xA0, 0xFF, 0xF0, 0x90, 0xC8, 0xF0, 0x80, 0xA0, 0xF0, + 0xA0, 0xA0, 0xFF, 0xC8, 0xA0, 0xFF, 0xF0, 0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, */ + +//Mesenɫ + 0x66, 0x66, 0x66, 0x00, 0x2A, 0x88, 0x14, 0x12, 0xA7, 0x3B, 0x00, 0xA4, 0x5C, 0x00, 0x7E, 0x6E, + 0x00, 0x40, 0x6C, 0x06, 0x00, 0x56, 0x1D, 0x00, 0x33, 0x35, 0x00, 0x0B, 0x48, 0x00, 0x00, 0x52, + 0x00, 0x00, 0x4F, 0x08, 0x00, 0x40, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xAD, 0xAD, 0xAD, 0x15, 0x5F, 0xD9, 0x42, 0x40, 0xFF, 0x75, 0x27, 0xFE, 0xA0, 0x1A, 0xCC, 0xB7, + 0x1E, 0x7B, 0xB5, 0x31, 0x20, 0x99, 0x4E, 0x00, 0x6B, 0x6D, 0x00, 0x38, 0x87, 0x00, 0x0C, 0x93, + 0x00, 0x00, 0x8F, 0x32, 0x00, 0x7C, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFE, 0xFF, 0x64, 0xB0, 0xFF, 0x92, 0x90, 0xFF, 0xC6, 0x76, 0xFF, 0xF3, 0x6A, 0xFF, 0xFE, + 0x6E, 0xCC, 0xFE, 0x81, 0x70, 0xEA, 0x9E, 0x22, 0xBC, 0xBE, 0x00, 0x88, 0xD8, 0x00, 0x5C, 0xE4, + 0x30, 0x45, 0xE0, 0x82, 0x48, 0xCD, 0xDE, 0x4F, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFE, 0xFF, 0xC0, 0xDF, 0xFF, 0xD3, 0xD2, 0xFF, 0xE8, 0xC8, 0xFF, 0xFB, 0xC2, 0xFF, 0xFE, + 0xC4, 0xEA, 0xFE, 0xCC, 0xC5, 0xF7, 0xD8, 0xA5, 0xE4, 0xE5, 0x94, 0xCF, 0xEF, 0x96, 0xBD, 0xF4, + 0xAB, 0xB3, 0xF3, 0xCC, 0xB5, 0xEB, 0xF2, 0xB8, 0xB8, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +////////////////////////////////////////////////////////////////////// +// LN^ +////////////////////////////////////////////////////////////////////// +static BYTE lzSight[] = { +#include "lzSight.h" +}; +static BYTE lzAscii[] = { +#include "lzAscii.h" +}; +static BYTE lzTVlayer[] = { +#include "lzTVlayer.h" +}; + +// PoCgĂ +static __inline INT mgetc( LPBYTE& inbuf, INT& bufsize ) +{ + if( bufsize <= 0 ) + return -1; + bufsize--; + return (INT)*inbuf++; +} + +// +// LZSS𓀃[` +// +#define N 4096 +#define F 18 + +static void LZdecode( BYTE *inbuf, BYTE *outbuf, INT length ) +{ +INT i, j, k, r, c; +WORD flags; +BYTE text[N+F-1]; +INT outsize = 0; + + for( i = 0; i < N - F; i++ ) + text[i] = 0; + r = N - F; + flags = 0; + + for(;;) { + if( ((flags >>= 1) & 256) == 0 ) { + if( (c = mgetc( inbuf, length )) < 0 ) + break; + flags = c | 0xff00; + } + if( flags & 1 ) { + if( (c = mgetc( inbuf, length )) < 0 ) + break; + *outbuf++ = c; + text[r++] = c; + r &= (N-1); + + outsize++; + } else { + if( (i = mgetc( inbuf, length )) < 0 ) + break; + if( (j = mgetc( inbuf, length )) < 0 ) + break; + i |= ((j & 0xf0)<<4); + j = (j & 0x0f)+2; + for( k = 0; k <= j; k++ ) { + c = text[(i+k) & (N-1)]; + *outbuf++ = c; + text[r++] = c; + r &= (N-1); + + outsize++; + } + } + } +} + +////////////////////////////////////////////////////////////////////// +// \z/ +////////////////////////////////////////////////////////////////////// + +CDirectDraw::CDirectDraw() +{ + font = pFont; + // General + m_hWnd = NULL; + + m_bUseHEL = FALSE; + m_bSystemMemory = FALSE; + + m_bScreenMode = FALSE; + m_bGDI = FALSE; + m_bAspect = FALSE; + m_bAllLine = FALSE; + m_bMaxZoom = FALSE; + m_bDoubleSize = FALSE; + m_bTVFrameMode = FALSE; + m_bScanlineMode = FALSE; + m_nScanlineColor = 75; + m_bZapper = FALSE; + m_bZapperDraw = FALSE; + + m_ZapperPosX = m_ZapperPosY = -1; + + m_bWindowVSync = FALSE; + + m_bChangeMode = FALSE; + m_bDraw = FALSE; + + m_bNoRestore = FALSE; + + // DirectDraw + m_hDDraw = NULL; + + m_lpDD = NULL; + m_lpDDPrimary = NULL; + m_lpDDBack = NULL; + m_lpDDRender = NULL; + m_lpDDAscii = NULL; + m_lpDDZapper = NULL; + m_lpDDTV = NULL; + m_lpDDClipper = NULL; + m_lpDDClipper2 = NULL; + m_lpDDPalette = NULL; + + m_lpRender = NULL; + m_lpRenderDelta = NULL; + m_bDeltaUpdate = FALSE; + + m_hPalette = NULL; + + m_DisplayModeNum = 0; + + m_bForceWrite = FALSE; + // Filter + m_nBltFilter = 0; + + // ftHg𑜓x + m_dwDisplayWidth = 640; + m_dwDisplayHeight = 480; + m_dwDisplayDepth = 16; + m_dwDisplayRate = 0; // tbV[gw薳 + + // LineColormode + ::memset( m_LineColormode, 0, sizeof(m_LineColormode) ); + + // pbg + m_nPaletteMode = 0; + m_bMonoMode = FALSE; + + ::memcpy( m_PaletteBuf, m_PalDefault, sizeof(m_PaletteBuf) ); + + ZEROMEMORY( m_cpPalette, sizeof(m_cpPalette) ); + ZEROMEMORY( m_mpPalette, sizeof(m_mpPalette) ); + ZEROMEMORY( m_cnPalette, sizeof(m_cnPalette) ); + ZEROMEMORY( m_csPalette, sizeof(m_csPalette) ); + ZEROMEMORY( m_mnPalette, sizeof(m_mnPalette) ); + ZEROMEMORY( m_msPalette, sizeof(m_msPalette) ); + + // ̑ + m_bDiskAccessLamp = FALSE; + + ZEROMEMORY( m_szInfo, sizeof(m_szInfo) ); + ZEROMEMORY( m_szMess, sizeof(m_szMess) ); + + // MMX detect + { + m_bMMX = FALSE; + + DWORD flag1, flag2; + __asm { + pushfd + pop eax + mov flag1, eax + xor eax, 0x00200000 + push eax + popfd + pushfd + pop eax + mov flag2, eax + } + + if( flag1 != flag2 ) { + DWORD flag; + __asm { + mov eax, 1 + cpuid + mov flag, edx + } + if( flag & 0x00800000 ) { + m_bMMX = TRUE; + } + } + } + + // TEST +// m_nBltFilter = BLTFILTER_2XSAI; +// m_nBltFilter = BLTFILTER_SUPER2XSAI; +// m_nBltFilter = BLTFILTER_SUPEREAGLE; +// m_nBltFilter = BLTFILTER_SCALE2X; + +#if COMUSE + COM::AddRef(); +#endif +} + +CDirectDraw::~CDirectDraw() +{ + ReleaseDDraw(); + +#if COMUSE + COM::Release(); +#endif +} + +////////////////////////////////////////////////////////////////////// +// o֐ +////////////////////////////////////////////////////////////////////// + +// R[obN֐ +HRESULT WINAPI CDirectDraw::EnumModesCallback( LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext ) +{ + // This|C^󂯎 + CDirectDraw* pDD = (CDirectDraw*)lpContext; + + // 256x240ȉ̉𑜓x͏O(ex. 320x200) + if( lpDDSurfaceDesc->dwWidth < 256 || lpDDSurfaceDesc->dwHeight < 240 ) + return DDENUMRET_OK; + + // 8,16,24,32bitȊO͏O(4bit^^;) + if( !(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 8 + || lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 16 + || lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 24 + || lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 32) ) + return DDENUMRET_OK; + + // XNGATCỶ𑜓xȊO͏O(ex. 640x400) (1280x1024͑I”\) +// if( lpDDSurfaceDesc->dwWidth*3 != lpDDSurfaceDesc->dwHeight*4 && !(lpDDSurfaceDesc->dwWidth == 1280 && lpDDSurfaceDesc->dwHeight == 1024) ) +// return DDENUMRET_OK; + + // TCY^rbg[x^tbV[g^sNZtH[}bg̃Rs[ + DISPLAYMODE mode; + mode.dwWidth = lpDDSurfaceDesc->dwWidth; + mode.dwHeight = lpDDSurfaceDesc->dwHeight; + mode.dwDepth = lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount; + mode.dwRate = lpDDSurfaceDesc->dwRefreshRate; + pDD->m_DisplayModes.push_back( mode ); + + // 񋓐ꍇ̓LZ + if( ++pDD->m_DisplayModeNum > CDirectDraw::DD_DISPLAYMODEMAX-1 ) { +// DEBUGOUT( "CDirectDraw:Maximum display modes over.\n" ); + return DDENUMRET_CANCEL; + } + return DDENUMRET_OK; +} + +// DirectDraw̏ +BOOL CDirectDraw::InitialDDraw( HWND hWnd ) +{ + try { + // DirectDrawIuWFNg̍쐬 + +#if !DYNDLL +#if !COMUSE + if( !m_bUseHEL ) { + if( DirectDrawCreateEx(NULL, (LPVOID*)&m_lpDD, IID_IDirectDraw7, NULL) != DD_OK ) { + m_lpDD = NULL; + throw "CDirectDraw:DirectDrawCreateEx failed."; + } + } else { + if( DirectDrawCreateEx((LPGUID)DDCREATE_EMULATIONONLY, (LPVOID*)&m_lpDD, IID_IDirectDraw7, NULL) != DD_OK ) { + m_lpDD = NULL; + throw "CDirectDraw:DirectDrawCreateEx failed."; + } + } +#else + // COMIp(CuN邾ŋNxȂ̂...) +// COM::AddRef(); + + // CLSID_DirectDrawł͖CLSID_DirectDraw7gȂƑʖ + if( ::CoCreateInstance( CLSID_DirectDraw7, NULL, CLSCTX_ALL, IID_IDirectDraw7, (LPVOID*)&m_lpDD ) != S_OK ) { + m_lpDD = NULL; + throw "CDirectDraw:DirectX 7.0 or greater is required."; +// throw "CDirectDraw:CoCreateInstance failed."; + } + if( !m_bUseHEL ) { + if( m_lpDD->Initialize( NULL ) != DD_OK ) + throw "CDirectDraw:IDirectDraw7->Initialize failed."; + } else { + if( m_lpDD->Initialize( (LPGUID)DDCREATE_EMULATIONONLY ) != DD_OK ) // HEL + throw "CDirectDraw:IDirectDraw7->Initialize failed."; + } +#endif +#else + // DLL𓮓I[hėp + if( !(m_hDDraw = ::LoadLibrary( "DDRAW.DLL" )) ) { + throw "CDirectDraw:DirectX 7.0 or greater is required."; + } + +typedef HRESULT(WINAPI * DIRECTDRAWCREATEEX)( GUID*, VOID**, REFIID, IUnknown* ); + + DIRECTDRAWCREATEEX DirectDrawCreateEx = (DIRECTDRAWCREATEEX)GetProcAddress( m_hDDraw, "DirectDrawCreateEx" ); + if( !DirectDrawCreateEx ) { + ::FreeLibrary( m_hDDraw ); + m_hDDraw = NULL; + throw "CDirectDraw:DirectX 7.0 or greater is required."; + } + + if( !m_bUseHEL ) { + if( DirectDrawCreateEx(NULL, (LPVOID*)&m_lpDD, IID_IDirectDraw7, NULL) != DD_OK ) { + m_lpDD = NULL; + throw "CDirectDraw:DirectX 7.0 or greater is required."; + } + } else { + if( DirectDrawCreateEx((LPGUID)DDCREATE_EMULATIONONLY, (LPVOID*)&m_lpDD, IID_IDirectDraw7, NULL) != DD_OK ) { + m_lpDD = NULL; + throw "CDirectDraw:DirectX 7.0 or greater is required."; + } + } +#endif + // j^𑜓x̒ + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + if( m_lpDD->GetDisplayMode( &ddsd ) != DD_OK ) + throw "CDirectDraw:GetDisplayMode failed."; + + if( ddsd.ddpfPixelFormat.dwRGBBitCount < 8 ) + throw "CDirectDraw:Unsupported display mode."; + + // p”\ȃfBXvC[h̎擾 + m_DisplayModeNum = 0; + if( m_lpDD->EnumDisplayModes(DDEDM_REFRESHRATES, NULL, (LPVOID)this, (LPDDENUMMODESCALLBACK2)EnumModesCallback) != DD_OK ) + throw "CDirectDraw:EnumDisplayModes failed."; + if( !m_DisplayModeNum ) + throw "CDirectDraw:No display modes available."; + + m_hWnd = hWnd; + + // ftHgpbgݒ + memcpy( m_PaletteBuf, m_PalDefault, sizeof(m_PalDefault) ); + + // Render screen + if( !m_lpRender ) { + if( !(m_lpRender = (LPBYTE)malloc( RENDER_WIDTH*RENDER_HEIGHT )) ) + throw "CDirectDraw::Out of memory."; + + } + ::memset( m_lpRender, 0x3F, RENDER_WIDTH*RENDER_HEIGHT ); + + // Render delta screen + if( !m_lpRenderDelta ) { + if( !(m_lpRenderDelta = (LPBYTE)malloc( DELTA_WIDTH*DELTA_HEIGHT*sizeof(DWORD) )) ) + throw "CDirectDraw::Out of memory."; + } + ::memset( m_lpRenderDelta, 0xFF, DELTA_WIDTH*DELTA_HEIGHT*sizeof(DWORD) ); + m_bDeltaUpdate = FALSE; + + // LineColormode + ::memset( m_LineColormode, 0, sizeof(m_LineColormode) ); + } catch( char *str ) { + m_DisplayModeNum = 0; + RELEASE( m_lpDD ); + ::MessageBox( hWnd, str, "ERROR", MB_ICONERROR|MB_OK ); + + return FALSE; + } + + return TRUE; +} + +// DirectDraẘJ +void CDirectDraw::ReleaseDDraw() +{ + ReleaseSurface(); + + if( m_lpDD ) { + RELEASE( m_lpDD ); + } +#if COMUSE +// COM::Release(); +#endif + +#if DYNDLL + if( m_hDDraw ) { + m_hDDraw = NULL; + ::FreeLibrary( m_hDDraw ); + } +#endif + + FREE( m_lpRenderDelta ); + FREE( m_lpRender ); +// m_hWnd = NULL; +} + +// T[tFX̏ +BOOL CDirectDraw::InitialSurface( BOOL bScreenMode ) +{ +INT i; +DDSURFACEDESC2 ddsd; +DDSCAPS2 ddscaps; +DDBLTFX ddbltfx; + + try { + if( !m_lpDD ) + throw "CDirectDraw:DirectDraw object uninitialized."; + + m_bGDI = FALSE; + m_bScreenMode = bScreenMode; + m_bMessage = FALSE; + + if( !m_bScreenMode ) { + // EChE + // [h + if( m_lpDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL ) != DD_OK ) + throw "CDirectDraw:SetCooperativeLevel failed."; + + // vC}T[tFX + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if( m_lpDD->CreateSurface( &ddsd, &m_lpDDPrimary, NULL ) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + + // Nbp[̍쐬 + if( m_lpDD->CreateClipper( 0, &m_lpDDClipper, NULL ) != DD_OK ) + throw "CDirectDraw:CreateClipper failed."; + + m_lpDDClipper->SetHWnd( 0, m_hWnd ); + m_lpDDPrimary->SetClipper( m_lpDDClipper ); + RELEASE( m_lpDDClipper ); + } else { + // tXN[ + // r[h + if( m_lpDD->SetCooperativeLevel( m_hWnd, DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN ) != DD_OK ) + throw "CDirectDraw:SetCooperativeLevel error"; + + // ʉ𑜓x̐ݒ + if( m_lpDD->SetDisplayMode( m_dwDisplayWidth, m_dwDisplayHeight, + m_dwDisplayDepth, m_dwDisplayRate, + DDSDM_STANDARDVGAMODE ) != DD_OK ) { + // s烊tbV[gw𖳂ĂxĂ݂ + if( m_lpDD->SetDisplayMode( m_dwDisplayWidth, m_dwDisplayHeight, + m_dwDisplayDepth, 0, + DDSDM_STANDARDVGAMODE ) != DD_OK ) { + throw "CDirectDraw:SetDisplayMode failed."; + } else { + m_dwDisplayRate = 0; + } + } + + // vC}T[tFXƃobNT[tFX̍쐬 + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd.dwBackBufferCount = 1; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDPrimary, NULL) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + + ZEROMEMORY( &ddscaps, sizeof(DDSCAPS2) ); + ddscaps.dwCaps = DDSCAPS_BACKBUFFER; + if( m_lpDDPrimary->GetAttachedSurface(&ddscaps, &m_lpDDBack) != DD_OK ) + throw "CDirectDraw:GetAttachedSurface failed."; + } + + // offscreen surface + m_bForceWrite = FALSE; + + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + if( !m_bSystemMemory ) { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + } else { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + m_bForceWrite = TRUE; // i_OȂ + } + ddsd.dwWidth = SCREEN_WIDTH*2; + ddsd.dwHeight = SCREEN_HEIGHT*2; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDRender, NULL) != DD_OK ) { + // VXeɂȂĂ.... + if( ddsd.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) + throw "CDirectDraw:CreateSurface failed."; + + // rfIɎȂC傤Ȃ̂ŃVXeɎ + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDRender, NULL) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + + m_bForceWrite = TRUE; // i_OȂ + } + if( !m_bSystemMemory ) { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + } else { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + } + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDRender2, NULL) != DD_OK ) { + // VXeɂȂĂ.... + if( ddsd.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) + throw "CDirectDraw:CreateSurface failed."; + + // rfIɎȂC傤Ȃ̂ŃVXeɎ + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDRender2, NULL) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + } + + typedef struct tagDDRGNDATA { + RGNDATAHEADER rdh; + RECT rect[8]; + } DDRGNDATA; + + DDRGNDATA rgn; + rgn.rdh.dwSize = sizeof(RGNDATAHEADER); + rgn.rdh.iType = RDH_RECTANGLES; + rgn.rdh.nCount = 1; + rgn.rdh.nRgnSize = sizeof(RECT); + rgn.rdh.rcBound.left = 0; + rgn.rdh.rcBound.top = 0; + rgn.rdh.rcBound.right = ddsd.dwWidth; + rgn.rdh.rcBound.bottom = ddsd.dwHeight; + rgn.rect[0].left = 0; + rgn.rect[0].top = 0; + rgn.rect[0].right = ddsd.dwWidth; + rgn.rect[0].bottom = ddsd.dwHeight; + + // Rendering surface clipper + if( m_lpDD->CreateClipper( 0, &m_lpDDClipper2, NULL ) != DD_OK ) + throw "CDirectDraw:CreateClipper failed."; + + m_lpDDClipper2->SetClipList( (LPRGNDATA)&rgn, 0 ); + m_lpDDRender->SetClipper( m_lpDDClipper2 ); + + // Ascii surface(6x6x64character) + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; +// ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwWidth = 6*8; + ddsd.dwHeight = 6*8; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDAscii, NULL) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + // Color key + DDCOLORKEY ddck; + ZEROMEMORY( &ddck, sizeof(DDCOLORKEY) ); + ddck.dwColorSpaceLowValue = 0; + ddck.dwColorSpaceHighValue = 0; + m_lpDDAscii->SetColorKey( DDCKEY_SRCBLT, &ddck ); + + // Zapper surface + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; +// ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDZapper, NULL) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + // Color key + ZEROMEMORY( &ddck, sizeof(DDCOLORKEY) ); + ddck.dwColorSpaceLowValue = 0; + ddck.dwColorSpaceHighValue = 0; + m_lpDDZapper->SetColorKey( DDCKEY_SRCBLT, &ddck ); + + // TV + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + if( !m_bSystemMemory ) { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + } else { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + } + ddsd.dwWidth = 512; + ddsd.dwHeight = 480; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDTV, NULL) != DD_OK ) { + // VXeɂȂĂ.... + if( ddsd.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) + throw "CDirectDraw:CreateSurface failed."; + + // rfIɎȂC傤Ȃ̂ŃVXeɎ + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if( m_lpDD->CreateSurface(&ddsd, &m_lpDDTV, NULL) != DD_OK ) + throw "CDirectDraw:CreateSurface failed."; + } + + // Color key + ZEROMEMORY( &ddck, sizeof(DDCOLORKEY) ); + ddck.dwColorSpaceLowValue = 0; + ddck.dwColorSpaceHighValue = 0; + m_lpDDTV->SetColorKey( DDCKEY_SRCBLT, &ddck ); + + // DirectDraw/GDI Palette + ZEROMEMORY( &m_logPalette, sizeof(m_logPalette) ); + m_logPalette.palVersion = 0x0300; + m_logPalette.palNumEntries = 256; + + HDC hdc = ::GetDC( NULL ); + GetSystemPaletteEntries( hdc, 0, 256, m_logPalette.pe ); + ReleaseDC( NULL, hdc ); + + for( i = 0; i < 10; i++ ) { + m_logPalette.pe[i ].peFlags = PC_EXPLICIT; + m_logPalette.pe[i+246].peFlags = PC_EXPLICIT; + } + for( i = 10; i < 246; i++ ) { + m_logPalette.pe[i].peRed = 0; + m_logPalette.pe[i].peGreen = 0; + m_logPalette.pe[i].peBlue = 0; + if( i >= 0x10 && i < 0x20 ) { + m_logPalette.pe[i].peRed = (i-0x10)*0x10; + m_logPalette.pe[i].peGreen = (i-0x10)*0x10; + m_logPalette.pe[i].peBlue = (i-0x10)*0x10; + m_logPalette.pe[i].peFlags = PC_RESERVED; + } else if( i >= 0x40 && i < 0xC0 ) { + m_logPalette.pe[i].peFlags = PC_RESERVED; + } else { + m_logPalette.pe[i].peFlags = PC_NOCOLLAPSE; + } + } + + // Surface clear + ddbltfx.dwSize = sizeof(DDBLTFX); + ddbltfx.dwFillColor = 0; + if( m_lpDDBack ) { + m_lpDDBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx); + } + m_lpDDRender->Blt(NULL, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx); + m_lpDDRender2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx); + + // Palette object + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + m_lpDDPrimary->GetSurfaceDesc(&ddsd); + + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) { + if( !m_bScreenMode ) { + if( (m_hPalette = CreatePalette( (LOGPALETTE *)&m_logPalette )) == NULL ) + throw "CDirectDraw:CreatePalette failed."; + } else { + if( m_lpDD->CreatePalette( DDPCAPS_8BIT, m_logPalette.pe, &m_lpDDPalette, NULL ) != DD_OK ) + throw "CDirectDraw:CreatePalette error"; + if( m_lpDDPrimary->SetPalette( m_lpDDPalette ) != DD_OK ) + throw "CDirectDraw:SetPalette failed."; + } + } + + // Palette calculate + CalcPaletteTable(); + // Palette Realize + RealizePalette(); + m_bPaletteUpdate = TRUE; + + // Character setup + SetLZSSChar( lzAscii, m_lpDDAscii ); + SetLZSSChar( lzSight, m_lpDDZapper ); + SetLZSSChar( lzTVlayer, m_lpDDTV ); + + // ĕ`̈ + m_bDeltaUpdate = TRUE; + } catch( char *str ) { + ReleaseSurface(); + +// DEBUGOUT( "%s\n", str ); + ::MessageBox( m_hWnd, str, "ERROR", MB_ICONERROR|MB_OK ); + + return FALSE; + } +// DEBUGOUT( "CDirectDraw:InitialSurface complete.\n" ); + + return TRUE; +} + +// T[tFX̊J +BOOL CDirectDraw::ReleaseSurface( void ) +{ + if( !m_lpDD ) + return FALSE; + + GDIDELETE( m_hPalette ); + RELEASE( m_lpDDPalette ); + + RELEASE( m_lpDDClipper2 ); + RELEASE( m_lpDDClipper ); + + RELEASE( m_lpDDTV ); + RELEASE( m_lpDDZapper ); + RELEASE( m_lpDDAscii ); + RELEASE( m_lpDDRender2 ); + RELEASE( m_lpDDRender ); + RELEASE( m_lpDDBack ); + RELEASE( m_lpDDPrimary ); + + return TRUE; +} + +// T[tFX̃XgATu +BOOL CDirectDraw::RestoreSurfaceSub( LPDIRECTDRAWSURFACE7 lpSurface ) +{ + if( lpSurface ) { + if( lpSurface->IsLost() == DDERR_SURFACELOST ) { + // XgĂ烊XgA +// DEBUGOUT( "CDirectDraw:Restore surface...." ); + if( lpSurface->Restore() == DD_OK ) { +// DEBUGOUT( "Ok.\n" ); + } else { +// DEBUGOUT( "Failed.\n" ); + } + return FALSE; + } + } + return TRUE; +} + +// T[tFX̃XgA +BOOL CDirectDraw::RestoreSurface() +{ + if( !m_lpDD ) return FALSE; + + if( m_bNoRestore ) + return FALSE; + + BOOL bRet = TRUE; + + // XgĂe͎Ă̂ŕ`LZĂ + if( !RestoreSurfaceSub( m_lpDDRender ) ) { + bRet = FALSE; + } + if( !RestoreSurfaceSub( m_lpDDRender2 ) ) { + bRet = FALSE; + } + if( !RestoreSurfaceSub( m_lpDDBack ) ) { + bRet = FALSE; + } + if( !RestoreSurfaceSub( m_lpDDPrimary ) ) { + bRet = FALSE; + } + if( !RestoreSurfaceSub( m_lpDDAscii ) ) { + SetLZSSChar( lzAscii, m_lpDDAscii ); + bRet = FALSE; + } + if( !RestoreSurfaceSub( m_lpDDZapper ) ) { + SetLZSSChar( lzSight, m_lpDDZapper ); + bRet = FALSE; + } + if( !RestoreSurfaceSub( m_lpDDTV ) ) { + SetLZSSChar( lzTVlayer, m_lpDDTV ); + bRet = FALSE; + } + + if( !bRet ) { + // ĕ`̈ + m_bDeltaUpdate = TRUE; + } + + return bRet; +} + +// +// fBXvC[hύXJn +// +BOOL CDirectDraw::BeginDisplayChange() +{ + if( !m_lpDD ) + return FALSE; + + // ɕύXȂ + if( m_bChangeMode ) + return FALSE; + + // ύX + m_bChangeMode = TRUE; + + if( m_bScreenMode ) { + m_lpDD->RestoreDisplayMode(); + } + + // T[tFX̊J + ReleaseSurface(); + + // [h + m_lpDD->SetCooperativeLevel( NULL, DDSCL_NORMAL ); + + return TRUE; +} + +// +// fBXvC[hύXIƃT[tFX̍č\z +// +BOOL CDirectDraw::EndDisplayChange() +{ + if( !m_lpDD || !m_bChangeMode ) + return FALSE; + + // Rebuild surface + if( !InitialSurface( m_bScreenMode ) ) { + m_bChangeMode = FALSE; + return FALSE; + } + + // Wait + ::Sleep( 250 ); + + // Change mode complete + m_bChangeMode = FALSE; + + return TRUE; +} + +// +// WM_DISPLAYCHANGEnhĂ΂ +// +BOOL CDirectDraw::OnChangeDisplayMode() +{ + // gŕύXĂ鎞̓LZ + if( m_bChangeMode ) + return TRUE; + + // DirectDrawIuWFNgΈӖ + if( !m_lpDD ) + return FALSE; + +// DEBUGOUT( "CDirectDraw:OnChangeDisplayMode\n" ); + + // [h̃`FbN + HRESULT hr = m_lpDD->TestCooperativeLevel(); + + if( !m_bScreenMode ) { + // EChE + if( hr == DDERR_EXCLUSIVEMODEALREADYSET ) { + // ɔr[hŶł܂ +// DEBUGOUT( "CDirectDraw:DDERR_EXCLUSIVEMODEALREADYSET\n" ); + // XgAႢ + m_bNoRestore = TRUE; + return TRUE; + } else if( hr == DDERR_WRONGMODE || hr == DD_OK ) { + // ʂ̃fBXvC[h̕ύX(̂WindowbZ[WDD_OKȎ) +// DEBUGOUT( "CDirectDraw:DDERR_WRONGMODE\n" ); + // XgAĂ + m_bNoRestore = FALSE; + + // T[tFX̊J + ReleaseSurface(); + + // T[tFX̏ + BOOL bRet = InitialSurface( m_bScreenMode ); + + if( bRet ) { +// DEBUGOUT( "CDirectDraw:InitialSurface ok.\n" ); + } else { +// DEBUGOUT( "CDirectDraw:InitialSurface failed.\n" ); + } + + return bRet; + } else if( hr == DDERR_INVALIDOBJECT ) { +// DEBUGOUT( "CDirectDraw:DDERR_INVALIDOBJECT\n" ); + return FALSE; + } else if( hr == DDERR_NOEXCLUSIVEMODE ) { +// DEBUGOUT( "CDirectDraw:DDERR_NOEXCLUSIVEMODE\n" ); + } else { +// DEBUGOUT( "CDirectDraw:Unknown error. hr=%08X\n", hr ); + } + // ǂ̂łƂ肠T[tFXXgA + m_bNoRestore = FALSE; + RestoreSurface(); + + return TRUE; + } else { + // tXN[ + if( hr == DDERR_NOEXCLUSIVEMODE ) { + // tXN[[h甲 +// DEBUGOUT( "CDirectDraw:DDERR_NOEXCLUSIVEMODE\n" ); + return TRUE; + } + + if( hr == DD_OK ) { + // XgAĎ... + // T[tFXXgA + RestoreSurface(); + + return TRUE; + } + + // sȌ + return FALSE; + } + + return TRUE; +} + +void CDirectDraw::SetDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate ) +{ + m_dwDisplayWidth = dwWidth; + m_dwDisplayHeight = dwHeight; + m_dwDisplayDepth = dwDepth; + m_dwDisplayRate = dwRate; +} + +void CDirectDraw::GetDisplayMode( DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate ) +{ + dwWidth = m_dwDisplayWidth; + dwHeight = m_dwDisplayHeight; + dwDepth = m_dwDisplayDepth; + dwRate = m_dwDisplayRate; +} + +BOOL CDirectDraw::GetDisplayMode( INT no, DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate ) +{ + if( m_DisplayModes.size() < no ) + return FALSE; + + dwWidth = m_DisplayModes[no].dwWidth; + dwHeight = m_DisplayModes[no].dwHeight; + dwDepth = m_DisplayModes[no].dwDepth; + dwRate = m_DisplayModes[no].dwRate; + + return TRUE; +} + +INT CDirectDraw::GetMatchDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate ) +{ + for( int i = 0; i < m_DisplayModes.size(); i++ ) { + if( m_DisplayModes[i].dwWidth == dwWidth + || m_DisplayModes[i].dwHeight == dwHeight + || m_DisplayModes[i].dwDepth == dwDepth + || m_DisplayModes[i].dwRate == dwRate ) + return i; + } + + return -1; +} + +BOOL CDirectDraw::IsNowDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate ) +{ + if( m_dwDisplayWidth == dwWidth && m_dwDisplayHeight == dwHeight + && m_dwDisplayDepth == dwDepth && m_dwDisplayRate == dwRate ) + return TRUE; + return FALSE; +} + +// rbgʒu̎擾 +void CDirectDraw::GetBitMask( DWORD val, int& shift, int& bits ) +{ + shift = 0; + while( !(val & (1<0) ) { + bits--; + } + bits = bits - shift; +} + +static float PalConvTbl[][3] = { + 1.00f, 1.00f, 1.00f, + 1.00f, 0.80f, 0.73f, + 0.73f, 1.00f, 0.70f, + 0.76f, 0.78f, 0.58f, + 0.86f, 0.80f, 1.00f, + 0.83f, 0.68f, 0.85f, + 0.67f, 0.77f, 0.83f, + 0.68f, 0.68f, 0.68f, +// 1.00f, 1.00f, 1.00f, +}; + +// pbge[ǔvZ +BOOL CDirectDraw::CalcPaletteTable() +{ +INT i, j; + + if( !m_lpDD || !m_lpDDPrimary ) + return FALSE; + + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_PIXELFORMAT; + if( m_lpDDPrimary->GetSurfaceDesc(&ddsd) != DD_OK ) + throw "CDirectDraw:GetSurfaceDesc error"; + + INT Rbit, Gbit, Bbit; + INT Rsft, Gsft, Bsft; + + if( ddsd.ddpfPixelFormat.dwRGBBitCount != 8 ) { + GetBitMask( ddsd.ddpfPixelFormat.dwRBitMask, Rsft, Rbit ); + GetBitMask( ddsd.ddpfPixelFormat.dwGBitMask, Gsft, Gbit ); + GetBitMask( ddsd.ddpfPixelFormat.dwBBitMask, Bsft, Bbit ); + } + + for( j = 0; j < 8; j++ ) { + for( i = 0; i < 64; i++ ) { + DWORD Rn, Gn, Bn; + DWORD Rs, Gs, Bs; + + // Normal + Rn = (DWORD)(PalConvTbl[j][0]*m_PaletteBuf[i].r); + Gn = (DWORD)(PalConvTbl[j][1]*m_PaletteBuf[i].g); + Bn = (DWORD)(PalConvTbl[j][2]*m_PaletteBuf[i].b); + // Scanline + Rs = (DWORD)(PalConvTbl[j][0]*m_PaletteBuf[i].r*m_nScanlineColor/100.0f); + Gs = (DWORD)(PalConvTbl[j][1]*m_PaletteBuf[i].g*m_nScanlineColor/100.0f); + Bs = (DWORD)(PalConvTbl[j][2]*m_PaletteBuf[i].b*m_nScanlineColor/100.0f); + + m_cpPalette[j][i+0x00].rgbRed = (BYTE)Rn; + m_cpPalette[j][i+0x00].rgbGreen = (BYTE)Gn; + m_cpPalette[j][i+0x00].rgbBlue = (BYTE)Bn; + m_cpPalette[j][i+0x40].rgbRed = (BYTE)Rs; + m_cpPalette[j][i+0x40].rgbGreen = (BYTE)Gs; + m_cpPalette[j][i+0x40].rgbBlue = (BYTE)Bs; + + m_cnPalette[j][i] = ((Rn>>(8-Rbit))<>(8-Gbit))<>(8-Bbit))<>(8-Rbit))<>(8-Gbit))<>(8-Bbit))< Bsft ) { + // RGB555->RGB888̎ + m_cfPalette[j][i] = ((Rn>>(8-5))<<10)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<0); + } else { + // BGR555->BGR888̎ + m_cfPalette[j][i] = ((Rn>>(8-5))<<0)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<10); + } + + // Monochrome + Rn = (DWORD)(m_PaletteBuf[i&0x30].r); + Gn = (DWORD)(m_PaletteBuf[i&0x30].g); + Bn = (DWORD)(m_PaletteBuf[i&0x30].b); + Rn = + Gn = + Bn = (DWORD)(0.299f * Rn + 0.587f * Gn + 0.114f * Bn); + Rn = (DWORD)(PalConvTbl[j][0]*Rn); + Gn = (DWORD)(PalConvTbl[j][1]*Gn); + Bn = (DWORD)(PalConvTbl[j][2]*Bn); + if( Rn > 0xFF ) Rs = 0xFF; + if( Gn > 0xFF ) Gs = 0xFF; + if( Bn > 0xFF ) Bs = 0xFF; + // Scanline + Rs = (DWORD)(m_PaletteBuf[i&0x30].r*m_nScanlineColor/100.0f); + Gs = (DWORD)(m_PaletteBuf[i&0x30].g*m_nScanlineColor/100.0f); + Bs = (DWORD)(m_PaletteBuf[i&0x30].b*m_nScanlineColor/100.0f); + Rs = + Gs = + Bs = (DWORD)(0.299f * Rs + 0.587f * Gs + 0.114f * Bs); + Rs = (DWORD)(PalConvTbl[j][0]*Rs); + Gs = (DWORD)(PalConvTbl[j][1]*Gs); + Bs = (DWORD)(PalConvTbl[j][2]*Bs); + if( Rs > 0xFF ) Rs = 0xFF; + if( Gs > 0xFF ) Gs = 0xFF; + if( Bs > 0xFF ) Bs = 0xFF; + + m_mpPalette[j][i+0x00].rgbRed = (BYTE)Rn; + m_mpPalette[j][i+0x00].rgbGreen = (BYTE)Gn; + m_mpPalette[j][i+0x00].rgbBlue = (BYTE)Bn; + m_mpPalette[j][i+0x40].rgbRed = (BYTE)Rs; + m_mpPalette[j][i+0x40].rgbGreen = (BYTE)Gs; + m_mpPalette[j][i+0x40].rgbBlue = (BYTE)Bs; + + m_mnPalette[j][i] = ((Rn>>(8-Rbit))<>(8-Gbit))<>(8-Bbit))<>(8-Rbit))<>(8-Gbit))<>(8-Bbit))< Bsft ) { + // RGB555->RGB888̎ + m_mfPalette[j][i] = ((Rn>>(8-5))<<10)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<0); + } else { + // BGR555->BGR888̎ + m_mfPalette[j][i] = ((Rn>>(8-5))<<0)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<10); + } + } + } + + // ĕ`̈ + m_bDeltaUpdate = TRUE; + + return TRUE; +} + +// pbge[u̐ݒ +void CDirectDraw::SetPaletteTable( LPBYTE pal ) +{ + if( pal ) + memcpy( m_PaletteBuf, pal, sizeof(m_PaletteBuf) ); + else + memcpy( m_PaletteBuf, m_PalDefault, sizeof(m_PaletteBuf) ); + + CalcPaletteTable(); + + m_bPaletteUpdate = TRUE; +} + +// pbge[u̐ݒ +void CDirectDraw::SetPaletteTable( RGBQUAD* rgb ) +{ + for( INT i = 0; i < 64; i++ ) { + m_PaletteBuf[i].r = rgb[i].rgbRed; + m_PaletteBuf[i].g = rgb[i].rgbGreen; + m_PaletteBuf[i].b = rgb[i].rgbBlue; + } + + CalcPaletteTable(); + + m_bPaletteUpdate = TRUE; +} + +// pbge[u̎擾 +void CDirectDraw::GetPaletteTable( RGBQUAD* rgb ) +{ + for( INT i = 0; i < 64; i++ ) { + rgb[i].rgbRed = m_PaletteBuf[i].r; + rgb[i].rgbGreen = m_PaletteBuf[i].g; + rgb[i].rgbBlue = m_PaletteBuf[i].b; + rgb[i].rgbReserved = 0; + } +} + +// pbgt@C̍XV +void CDirectDraw::SetPaletteFile( LPCTSTR fname ) +{ + // pbgt@C̍XV + if( strlen( fname ) > 0 ) { + FILE *fp; + if( (fp = ::fopen( fname, "rb" )) ) { + BYTE palbuf[192]; + // TCYǂݍ + if( ::fread( palbuf, 192, 1, fp ) == 1 ) { + // pbg̕ύXƌvZ + SetPaletteTable( palbuf ); + } else { + // ǂ݂Ȃ̓ftHg + SetPaletteTable( (LPBYTE)NULL ); + } + FCLOSE(fp); + } else { + // JȂ̓ftHg + SetPaletteTable( (LPBYTE)NULL ); + } + } else { + // O̓ftHg + SetPaletteTable( (LPBYTE)NULL ); + } +} + +// tXN[[hłGDIEChE\ݒ +BOOL CDirectDraw::SetFullScreenGDI( BOOL bMode ) +{ + // Ö׃`FbN + if( !m_lpDD || !m_lpDDPrimary ) + return FALSE; + + if( m_bScreenMode ) { + if( !m_bGDI ) { + if( bMode ) { + RELEASE( m_lpDDClipper ); // ꉞ + if( m_lpDD->CreateClipper(0, &m_lpDDClipper, NULL) == DD_OK ) { + m_lpDDClipper->SetHWnd( 0, m_hWnd ); + m_lpDDPrimary->SetClipper( m_lpDDClipper ); + if( m_lpDD->FlipToGDISurface() == DD_OK ) { + m_bGDI = TRUE; + } else { + RELEASE( m_lpDDClipper ); + return FALSE; + } + } + } + } else { + if( !bMode ) { + RELEASE( m_lpDDClipper ); + m_bGDI = FALSE; + } + } + } + return TRUE; +} + +void CDirectDraw::RealizePalette() +{ + if( !m_lpDD || !m_lpDDPrimary ) + return; + + if( !m_bScreenMode ) { + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + m_lpDDPrimary->GetSurfaceDesc(&ddsd); + + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) { + HDC hdc; + hdc = ::GetDC( m_hWnd ); + ::SelectPalette( hdc, m_hPalette, FALSE ); + ::RealizePalette( hdc ); + ::ReleaseDC( m_hWnd, hdc ); + + m_bPaletteUpdate = TRUE; + } + } +} + +// `(WindowsbZ[Wp) +void CDirectDraw::OnScreenDraw() +{ + if( !m_bScreenMode ) { + // Window mode + Blt(); + Flip(); + } else { + // Fullscreen mode + if( m_bGDI ) { + Blt(); + Flip(); + } + } +} + +void CDirectDraw::SetPaletteMode( INT nMode, BOOL bMono ) +{ + if( (m_nPaletteMode != nMode) || (m_bMonoMode != bMono) ) { + m_bPaletteUpdate = TRUE; + } + m_nPaletteMode = nMode; + m_bMonoMode = bMono; +} + +// \̃pbge[u̎擾 +void CDirectDraw::GetPaletteData( RGBQUAD* rgb ) +{ +INT i; + if( !m_bMonoMode ) { + for( i = 0; i < 64; i++ ) { + rgb[i ] = m_cpPalette[m_nPaletteMode][i]; + rgb[i+0x40] = m_mpPalette[m_nPaletteMode][i]; + } + } else { + for( i = 0; i < 64; i++ ) { + rgb[i ] = m_mpPalette[m_nPaletteMode][i]; + rgb[i+0x40] = m_mpPalette[m_nPaletteMode][i]; + } + } +} + +void CDirectDraw::Blt() +{ +INT i; +DDSURFACEDESC2 ddsd; + + if( !m_lpDD || !m_lpDDPrimary ) + return; + // ScreenMode changing? + if( m_bChangeMode ) + return; + // Surface lost check & restore + if( !RestoreSurface() ) + return; + + //ڴ֮ǰm_lpRenderѾдݣIJֻǽϣ + LPBYTE lpRdr = m_lpRender+8; + + if(g_bSan2) ViewChars(lpRdr); //½ + + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + if( m_lpDDPrimary->GetSurfaceDesc(&ddsd) != DD_OK ) + return; + + // Palette copy + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) { + if( !(m_LineColormode[1]&0x80) ) { + for( i = 0; i < 128; i++ ) { + m_logPalette.pe[i+0x40].peRed = m_cpPalette[m_nPaletteMode][i].rgbRed; + m_logPalette.pe[i+0x40].peGreen = m_cpPalette[m_nPaletteMode][i].rgbGreen; + m_logPalette.pe[i+0x40].peBlue = m_cpPalette[m_nPaletteMode][i].rgbBlue; + } + } else { + for( i = 0; i < 128; i++ ) { + m_logPalette.pe[i+0x40].peRed = m_mpPalette[m_nPaletteMode][i].rgbRed; + m_logPalette.pe[i+0x40].peGreen = m_mpPalette[m_nPaletteMode][i].rgbGreen; + m_logPalette.pe[i+0x40].peBlue = m_mpPalette[m_nPaletteMode][i].rgbBlue; + } + } + if( !m_bScreenMode ) { + ::AnimatePalette( m_hPalette, 0, 256, m_logPalette.pe ); + } + } + + // Size calculate + BOOL bDoubleWidth = FALSE; + BOOL bDoubleHeight = FALSE; + + RECT rcW; + rcW.left = 0; + rcW.top = 0; + rcW.right = SCREEN_WIDTH; + rcW.bottom = SCREEN_HEIGHT; + if( m_bDoubleSize || (m_nBltFilter && IsMMX()) ) { + rcW.right *= 2; + rcW.bottom *= 2; + bDoubleWidth = TRUE; + bDoubleHeight = TRUE; + } else if( m_bScanlineMode ) { + rcW.bottom *= 2; + bDoubleHeight = TRUE; + } + + // Render function + BLTFUNC* bltfunc; + if( !m_nBltFilter || !IsMMX() ) { + if( !m_bDoubleSize ) { + if( !m_bScanlineMode ) { + bltfunc = NormalBltTable; + } else { + bltfunc = ScanlineBltTable; + } + } else { + if( !m_bScanlineMode ) { + bltfunc = DoubleBltTable; + } else { + bltfunc = DoubleScanlineBltTable; + } + } + } else { + switch( m_nBltFilter ) { + case BLTFILTER_2XSAI: + bltfunc = nx2xSaIBltTable; + break; + case BLTFILTER_SUPER2XSAI: + bltfunc = nxSuper2xSaIBltTable; + break; + case BLTFILTER_SUPEREAGLE: + bltfunc = nxSuperEagleBltTable; + break; + case BLTFILTER_SCALE2X: + bltfunc = nxScale2xBltTable; + break; + default: + break; + } + } + + BOOL bFilter = FALSE; +// LPBYTE lpRdr = m_lpRender+8; + + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + + if( m_bForceWrite ) { + // i_O + if( m_lpDDRender->Lock( NULL, &ddsd, 0, NULL ) == DD_OK ) { + switch( ddsd.ddpfPixelFormat.dwRGBBitCount ) { + case 8: + (this->*bltfunc[0])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE ); + break; + case 16: + (this->*bltfunc[1])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE ); + break; + case 24: + (this->*bltfunc[2])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE ); + break; + case 32: + (this->*bltfunc[3])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE ); + break; + default: + break; + } + + m_lpDDRender->Unlock( NULL ); + m_bDeltaUpdate = FALSE; + } + } else { + if( m_lpDDRender2->Lock( NULL, &ddsd, 0, NULL ) == DD_OK ) { + switch( ddsd.ddpfPixelFormat.dwRGBBitCount ) { + case 8: + (this->*bltfunc[0])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate ); + break; + case 16: + (this->*bltfunc[1])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate ); + break; + case 24: + (this->*bltfunc[2])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate ); + break; + case 32: + (this->*bltfunc[3])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate ); + break; + default: + break; + } + + m_lpDDRender2->Unlock( NULL ); + m_bDeltaUpdate = FALSE; + + m_lpDDRender->Blt( &rcW, m_lpDDRender2, &rcW, 0, NULL ); + } + } + + // TVg + if( m_bTVFrameMode ) { + m_lpDDRender->Blt( &rcW, m_lpDDTV, NULL, DDBLT_KEYSRC, NULL ); + } + + // Infomation string + if( strlen(m_szInfo) > 0 ) { + INT x, y, o; + + x = bDoubleWidth ? 16 : 8; + o = m_bAllLine ? 0 : 8; + y = bDoubleHeight ? 8+o*2 : 4+o; + + RenderString( x, y, m_szInfo ); + } + // Message string + if( m_bMessage ) { + if( timeGetTime()-m_dwMessageTime > 1500 ) { + m_bMessage = FALSE; + } + if( strlen(m_szMess) > 0 ) { + INT x, y, o; + + x = bDoubleWidth ? 16 : 8; + o = m_bAllLine ? 8 : 0; + y = bDoubleHeight ? (SCREEN_HEIGHT*2-36+o*2) : (SCREEN_HEIGHT-18+o); + + RenderString( x, y, m_szMess ); + } + } + // DiskAccessLamp + if( m_bDiskAccessLamp ) { + INT x, y, o; + + x = bDoubleWidth ? SCREEN_WIDTH*2-20 : SCREEN_WIDTH-10; + o = m_bAllLine ? 0 : 8; + y = bDoubleHeight ? 8+o*2 : 4+o; + + RenderString( x, y, "\\" ); + } + + if( m_bZapper && m_bZapperDraw ) { + if( m_ZapperPosX >= 0 && m_ZapperPosX < SCREEN_WIDTH && m_ZapperPosY >= 0 && m_ZapperPosY < SCREEN_HEIGHT ) { + RECT rcS, rcZ; + + SetRect( &rcZ, 0, 0, 16, 16 ); + if( !bDoubleWidth ) { + rcS.left = m_ZapperPosX-(rcZ.right-rcZ.left)/2; + rcS.right = m_ZapperPosX+(rcZ.right-rcZ.left)/2; + } else { + rcS.left = m_ZapperPosX*2-(rcZ.right-rcZ.left); + rcS.right = m_ZapperPosX*2+(rcZ.right-rcZ.left); + } + if( !bDoubleHeight ) { + rcS.top = m_ZapperPosY-(rcZ.bottom-rcZ.top)/2; + rcS.bottom = m_ZapperPosY+(rcZ.bottom-rcZ.top)/2; + } else { + rcS.top = m_ZapperPosY*2-(rcZ.bottom-rcZ.top); + rcS.bottom = m_ZapperPosY*2+(rcZ.bottom-rcZ.top); + } + + m_lpDDRender->Blt( &rcS, m_lpDDZapper, &rcZ, DDBLT_KEYSRC, NULL ); + } + } +} + +void CDirectDraw::Flip() +{ + if( !m_lpDD || !m_lpDDPrimary ) + return; + // ScreenMode changing? + if( m_bChangeMode ) + return; + // Surface lost check & restore + if( !RestoreSurface() ) + return; + + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + m_lpDDPrimary->GetSurfaceDesc(&ddsd); + + // Size calculate + BOOL bDoubleWidth = FALSE; + BOOL bDoubleHeight = FALSE; + if( m_bDoubleSize || (m_nBltFilter && IsMMX()) ) { + bDoubleWidth = TRUE; + bDoubleHeight = TRUE; + } else if( m_bScanlineMode ) { + bDoubleHeight = TRUE; + } + + RECT rcS, rcC; + if( !bDoubleWidth ) { + rcS.left = 0; + rcS.right = SCREEN_WIDTH; + } else { + rcS.left = 0; + rcS.right = SCREEN_WIDTH*2; + } + if( !m_bAllLine ) { + rcS.top = 8; + rcS.bottom = SCREEN_HEIGHT-8; + } else { + rcS.top = 0; + rcS.bottom = SCREEN_HEIGHT; + } + if( bDoubleHeight ) { + rcS.top *= 2; + rcS.bottom *= 2; + } + + if( !m_bScreenMode ) { + // Window mode + ::GetClientRect( m_hWnd, &rcC ); + ::ClientToScreen( m_hWnd, (POINT*)&rcC.left ); + ::ClientToScreen( m_hWnd, (POINT*)&rcC.right ); + + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) { + HDC hdc; + if( m_lpDDPrimary->GetDC( &hdc ) == DD_OK ) { + ::SelectPalette( hdc, m_hPalette, FALSE ); + ::RealizePalette( hdc ); + m_lpDDPrimary->ReleaseDC( hdc ); + } + } + } else { + // Fullscreen mode + if( !m_bMaxZoom ) { + DDBLTFX ddbltfx; + ddbltfx.dwSize = sizeof(DDBLTFX); + ddbltfx.dwFillColor = 0; + m_lpDDBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx); + + // Position offset caluclate + LONG swidth, sheight; + LONG dwidth, dheight; + LONG hmul, vmul; + + if( !m_bAspect ) swidth = SCREEN_WIDTH; + else swidth = 320; + if( !m_bAllLine ) sheight = SCREEN_HEIGHT-16; + else sheight = SCREEN_HEIGHT; + + dwidth = (LONG)ddsd.dwWidth; + dheight = (LONG)ddsd.dwHeight; + hmul = dwidth / swidth; + vmul = dheight / sheight; + + if( vmul < hmul ) hmul = vmul; + else vmul = hmul; + + rcC.left = (dwidth -swidth *hmul)/2; + rcC.top = (dheight-sheight*vmul)/2; + rcC.right = rcC.left+swidth *hmul; + rcC.bottom = rcC.top +sheight*vmul; + } else { + // Maximum zoom + rcC.left = 0; + rcC.top = 0; + rcC.right = (LONG)ddsd.dwWidth; + rcC.bottom = (LONG)ddsd.dwHeight; + } + } + + if( !m_bScreenMode ) { + // Window mode + if( m_bWindowVSync ) { + HRESULT hr; + while( TRUE ) { + hr = m_lpDD->WaitForVerticalBlank( DDWAITVB_BLOCKBEGIN, NULL ); + if( hr == DD_OK ) + break; + if( hr == DDERR_SURFACELOST ) { + break; + } + if( hr != DDERR_WASSTILLDRAWING ) { + break; + } + } +// m_lpDDPrimary->Blt( NULL, m_lpDDBack, NULL, DDBLT_WAIT, NULL ); + } + + m_lpDDPrimary->Blt( &rcC, m_lpDDRender, &rcS, DDBLT_WAIT, NULL ); + + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) { + if( m_bPaletteUpdate ) { + m_bPaletteUpdate = FALSE; + ::AnimatePalette( m_hPalette, 0, 256, m_logPalette.pe ); + } + } + } else { + // Fullscreen mode + m_lpDDBack->Blt( &rcC, m_lpDDRender, &rcS, DDBLT_WAIT, NULL ); + + if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) { + if( m_bPaletteUpdate ) { + m_bPaletteUpdate = FALSE; + m_lpDDPalette->SetEntries( 0, 0, 256, m_logPalette.pe ); + } + } + + if( m_bFlip ) { + if( !m_bGDI ) { + HRESULT hr; + while( TRUE ) { + hr = m_lpDDPrimary->Flip( NULL, DDFLIP_WAIT ); + if( hr == DD_OK ) + break; + if( hr == DDERR_SURFACELOST ) { + break; + } + if( hr != DDERR_WASSTILLDRAWING ) { + break; + } + } + } else { + HRESULT hr; + while( TRUE ) { + hr = m_lpDD->WaitForVerticalBlank( DDWAITVB_BLOCKBEGIN, NULL ); + if( hr == DD_OK ) + break; + if( hr == DDERR_SURFACELOST ) { + break; + } + if( hr != DDERR_WASSTILLDRAWING ) { + break; + } + } + m_lpDDPrimary->Blt( NULL, m_lpDDBack, NULL, DDBLT_WAIT, NULL ); + } + } else { + m_lpDDPrimary->Blt( NULL, m_lpDDBack, NULL, DDBLT_WAIT, NULL ); + } + } +} + +BYTE CDirectDraw::GetZapperHit() +{ + if( m_bZapper ) { + if( m_ZapperPosX >= 0 && m_ZapperPosX < SCREEN_WIDTH && m_ZapperPosY >= 0 && m_ZapperPosY < SCREEN_HEIGHT ) { + BYTE c = m_lpRender[8+m_ZapperPosX+RENDER_WIDTH*m_ZapperPosY]; + DWORD Yn = (DWORD)(0.299f * m_cpPalette[0][c].rgbRed + 0.587f * m_cpPalette[0][c].rgbGreen + 0.114f * m_cpPalette[0][c].rgbBlue); + if( Yn > 0xFF ) + Yn = 0xFF; + return (BYTE)Yn; + } + } + return 0x00; +} + +void CDirectDraw::GetZapperPos( LONG& x, LONG& y ) +{ + x = y = -1; + + if( !m_lpDD || !m_lpDDPrimary ) + return; + // ScreenMode changing? + if( m_bChangeMode ) + return; + + if( !m_bZapper ) + return; + + RECT rcS, rcC; + + // Size calculate + rcS.left = 0; + rcS.right = SCREEN_WIDTH; + if( !m_bAllLine ) { + rcS.top = 8; + rcS.bottom = SCREEN_HEIGHT-8; + } else { + rcS.top = 0; + rcS.bottom = SCREEN_HEIGHT; + } + if( m_bScanlineMode ) { + rcS.top *= 2; + rcS.bottom *= 2; + } + + if( !m_bScreenMode ) { + // Window mode + ::GetClientRect( m_hWnd, &rcC ); + ::ClientToScreen( m_hWnd, (POINT*)&rcC.left ); + ::ClientToScreen( m_hWnd, (POINT*)&rcC.right ); + } else { + // Fullscreen mode + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + if( m_lpDDPrimary->GetSurfaceDesc(&ddsd) != DD_OK ) + return; + + if( !m_bMaxZoom ) { + // Position offset caluclate + LONG swidth, sheight; + LONG dwidth, dheight; + LONG hmul, vmul; + + if( !m_bAspect ) swidth = SCREEN_WIDTH; + else swidth = 320; + if( !m_bAllLine ) sheight = SCREEN_HEIGHT-16; + else sheight = SCREEN_HEIGHT; + + dwidth = (LONG)ddsd.dwWidth; + dheight = (LONG)ddsd.dwHeight; + hmul = dwidth / swidth; + vmul = dheight / sheight; + + if( vmul < hmul ) hmul = vmul; + else vmul = hmul; + + rcC.left = (dwidth -swidth *hmul)/2; + rcC.top = (dheight-sheight*vmul)/2; + rcC.right = rcC.left+swidth *hmul; + rcC.bottom = rcC.top +sheight*vmul; + } else { + // Maximum zoom + rcC.left = 0; + rcC.top = 0; + rcC.right = (LONG)ddsd.dwWidth; + rcC.bottom = (LONG)ddsd.dwHeight; + } + + } + + POINT mp; + FLOAT hz, vz; + + ::GetCursorPos( &mp ); + + if( mp.x >= rcC.left && mp.x < rcC.right + && mp.y >= rcC.top && mp.y < rcC.bottom ) { + hz = (FLOAT)(rcS.right-rcS.left)/(rcC.right-rcC.left); + vz = (FLOAT)(rcS.bottom-rcS.top)/(rcC.bottom-rcC.top); + x = (LONG)((mp.x-rcC.left)*hz)+rcS.left; + if( !m_bScanlineMode ) { + y = (LONG)((mp.y-rcC.top) *vz)+rcS.top; + } else { + y = (LONG)(((mp.y-rcC.top) *vz)+rcS.top)/2; + } + + if( x > SCREEN_WIDTH-1 ) + x = SCREEN_WIDTH-1; + if( y > SCREEN_HEIGHT-1 ) + y = SCREEN_HEIGHT-1; + } else { + x = y = -1; + } + + m_ZapperPosX = x; + m_ZapperPosY = y; +} + +void CDirectDraw::SetZapperPos( LONG x, LONG y ) +{ + m_ZapperPosX = x; + m_ZapperPosY = y; +} + +// Infomation string +void CDirectDraw::SetInfoString( LPCSTR str ) +{ + if( str ) { + if( strlen(str) > INFOSTR_SIZE ) { + memcpy( m_szInfo, str, INFOSTR_SIZE ); + m_szInfo[INFOSTR_SIZE] = '\0'; + } else { + strcpy( m_szInfo, str ); + } + } else { + m_szInfo[0] = '\0'; + } +} + +// Message string +void CDirectDraw::SetMessageString( LPCSTR str ) +{ + if( str ) { + if( strlen(str) > INFOSTR_SIZE ) { + memcpy( m_szMess, str, INFOSTR_SIZE ); + m_szMess[INFOSTR_SIZE] = '\0'; + } else { + strcpy( m_szMess, str ); + } + m_bMessage = TRUE; + m_dwMessageTime = ::timeGetTime(); + } else { + m_bMessage = FALSE; + m_szMess[0] = '\0'; + } +} + +void CDirectDraw::RenderString( INT x, INT y, LPCSTR str ) +{ + if( !m_lpDD || !m_lpDDPrimary ) + return; + // ScreenMode changing? + if( m_bChangeMode ) + return; + + if( !str ) + return; + + // Size calculate + BOOL bDoubleWidth = FALSE; + BOOL bDoubleHeight = FALSE; + if( m_bDoubleSize || (m_nBltFilter && IsMMX()) ) { + bDoubleWidth = TRUE; + bDoubleHeight = TRUE; + } else if( m_bScanlineMode ) { + bDoubleHeight = TRUE; + } + + RECT rcS, rcW; + INT ch; + INT xadd; + + rcW.left = x; + rcW.top = y; + if( !bDoubleWidth ) { + rcW.right = x+6; + xadd = 6; + } else { + rcW.right = x+12; + xadd = 12; + } + if( !bDoubleHeight ) { + rcW.bottom = y+6; + } else { + rcW.bottom = y+12; + } + + while( *str ) { + ch = toupper(*str)-0x20; + rcS.left = (ch%8)*6; + rcS.right = rcS.left+6; + rcS.top = (ch/8)*6; + rcS.bottom = rcS.top+6; + + m_lpDDRender->Blt( &rcW, m_lpDDAscii, &rcS, DDBLT_KEYSRC, NULL ); + + rcW.left += xadd; + rcW.right += xadd; + str++; + } +} + +// LZSS BMPT[tFXւ̃Rs[ +void CDirectDraw::SetLZSSChar( LPBYTE lpLZ, LPDIRECTDRAWSURFACE7 lpDDSurface ) +{ +LPBYTE lpBuf = NULL; +LPBITMAPINFOHEADER pbi; +LPBYTE lpPix; +HDC hDC; + + if( !(lpBuf = (LPBYTE)malloc( *((LONG*)lpLZ) )) ) + throw "Out of memory."; + + LZdecode( &lpLZ[8], lpBuf, *((LONG*)&lpLZ[4]) ); + + pbi = (LPBITMAPINFOHEADER)lpBuf; + if( pbi->biBitCount < 16 ) + lpPix = ((LPBYTE)pbi)+pbi->biSize+(1<biBitCount)*sizeof(RGBQUAD); + else + lpPix = (LPBYTE)pbi+pbi->biSize; + + DDSURFACEDESC2 ddsd; + ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) ); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + lpDDSurface->GetSurfaceDesc(&ddsd); + + // BMP͍}CiXȎ̂.... + LONG height = pbi->biHeight; + if( height < 0 ) + height = -height; + + if( lpDDSurface->GetDC( &hDC ) == DD_OK ) { + StretchDIBits( hDC, 0, 0, ddsd.dwWidth, ddsd.dwHeight, + 0, 0, pbi->biWidth, height, lpPix, (LPBITMAPINFO)lpBuf, DIB_RGB_COLORS, SRCCOPY ); + lpDDSurface->ReleaseDC( hDC ); + } + FREE( lpBuf ); +} + +#include "Render.h" + +void CDirectDraw::ViewChars( unsigned char * lpRdr ) //дı +{ + unsigned char tileid=0, bktileid=1,count=0,offset=0; + unsigned int i, j = 0,pos=0; + unsigned int gridy=0, scrolly = 0, scrollyy = 0; + unsigned int BASE_VRAM = 0x2000, MAX_INDEX_R = MAX_INDEX, F_SPECIAL = 0; + unsigned int Line_Start = 30, Line_End = 30; + + #define LINESKIP(n) ((0x7FFF - ((RAM[0x69+(n<<1)]&0x7F)<<8) - RAM[0x68+(n<<1)])*3)/2728 + + switch(RAM[0x60]) + { + case 0x1 : //佫 + if(RAM[0xBA] == 0x08) + { + if(RAM[0x6A] == 0x70) + { + Line_Start = 21;//5 + LINESKIP(0) + LINESKIP(1)+ LINESKIP(2) + LINESKIP(3) + LINESKIP(4); + { + scrollyy = (RAM[0x98]&0x07) + 2; + } + gridy = (RAM[0x9B]*0x100+RAM[0x9A]+RAM[0x97]*0x400-0x2000)/0x20 - Line_Start; + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + else + { + Line_Start = 21; + if(RAM[0x98]<=RAM[0x99]) + { + scrollyy = (RAM[0x98]+2)&0x07; + } + else + { + scrollyy = ((RAM[0x98]+6)&0x07)+4; + } + gridy = (RAM[0x9B]*0x100+RAM[0x9A]-0x2000)/0x20 - Line_Start; + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + } + break; + case 0x3 : //ȫͼ + if(RAM[0xBA] == 0x08) + { + Line_Start = 0x280/0x20; + gridy = (RAM[0x9B]*0x100+RAM[0x9A]-0x2000)/0x20 - Line_Start; + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + break; + case 0x5 : //սսܽ + if(RAM[0xBA] == 0x08) + { + if(RAM[0xAF] == 0x08) + { + Line_Start = 0; + } + else + { + Line_Start = 20; //ɨ߿ʼ + gridy = 32 - Line_Start; //ɨߵƫ + } + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + break; + case 0x6 : + BASE_VRAM = 0x2400; + if(RAM[0xBA] == 0x08) + { + Line_Start =0; + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + break; + case 0x7 : //ü + if(RAM[0xBA] == 0x08) + { + Line_Start = 1 + LINESKIP(0) + LINESKIP(1) + LINESKIP(2) + LINESKIP(3); + gridy = (RAM[0x9B]*0x100+RAM[0x9A]+RAM[0x97]*0x400-0x2000)/0x20 - Line_Start; + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + break; + case 0x8 : + if(RAM[0xBD] == 0xB3) + { + Line_Start =14; + F_SPECIAL = 1; + } + break; + case 0xA : + case 0xB : + if(RAM[0xBA] == 0x08) + { + Line_Start = 20; + gridy = (RAM[0x9B]*0x100+RAM[0x9A]+RAM[0x97]*0x400-0x2000)/0x20 - Line_Start; + if(RAM[0xBB] != 0x09) + { + MAX_INDEX_R = MIN_INDEX; + } + } + break; + } + + RGBQUAD m_Palette[256]; + DirectDraw.GetPaletteData( m_Palette ); + + for(j = Line_Start + gridy; j < Line_End + gridy; j ++) //scan memory + { + if(j == 20 && RAM[0x60] == 0x05 && RAM[0xCB] == 0x09) + { + gridy += 12; + j += 12; + } + count=0; + offset=0; + bktileid = 1; + for(i = 0; i < 32; i ++) + { + pos = (i & 0x1F) + (j << 5); + + if(pos > 0x800) + { + pos -= 0x400; + scrolly = scrollyy + 16; + } + else + { + scrolly = scrollyy; + } + tileid = VRAM[pos + BASE_VRAM - 0x2000]; + + //ʾ + if(tileid < MAX_GROUP) + { + bktileid = tileid; + if(bktileid < 5) + { + offset = 0; + count = 0; + } + else + { + offset += 8; + } + } + else if(((tileid < MAX_INDEX_R) && (F_SPECIAL == 0)) || ((F_SPECIAL == 1) && (tileid > 0xC7))) + { + //Աɫ + int ataddr; + ataddr = 0x03C0 + ((j-(j&3))<<1) + (i>>2); + unsigned char atbyte = VRAM[ataddr]; + unsigned char color; + + switch((i&3)+((j&3)<<2)) + { + case 0: + case 1: + case 4: + case 5: + //bit 0,1 + color = (((atbyte&0x03)<<2)|0); + break; + case 2: + case 3: + case 6: + case 7: + //bit 2,3 + color = ((atbyte&0x0C)|0); + break; + case 8: + case 9: + case 12: + case 13: + //bit 4,5 + color = (((atbyte&0x30)>>2)|0); + break; + case 10: + case 11: + case 14: + case 15: + //bit 6,7 + color = (((atbyte&0xC0)>>4)|0); + break; + } + if(F_SPECIAL == 1) + { + tileid -= 0x90; + color = 7; + } + + int x = (i<<3) +(count*6) - offset; + int y = ((j - gridy)<<3) - scrolly - 2; + unsigned int index = txt[bktileid][tileid]; + long maxpos = (RENDER_WIDTH * RENDER_HEIGHT - 8); + + for(int i = 0; i < 16; i ++) + { + for(int j = 0; j < 16; j ++) + { + long pos = (y + i) * RENDER_WIDTH + j + x; + + if(pos < maxpos) + { + if(j < 8 && (font[index * 32 + i * 2]&(0x80>>j))) + lpRdr[pos] = BGPAL[color]; + if(j >= 8 && (font[index * 32 + i * 2 + 1]&(0x80>>(j - 8)))) + lpRdr[pos] = BGPAL[color]; + } + } + } + count++; + } + else + { + count = 0; + offset =0; + } + } + } +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/DirectDraw.h b/References/VirtuaNESex_src_191105/DirectDraw.h new file mode 100644 index 00000000..a65b8e54 --- /dev/null +++ b/References/VirtuaNESex_src_191105/DirectDraw.h @@ -0,0 +1,372 @@ +// +// DirectDraw class +// +#ifndef __DIRECTDRAW_INCLUDED__ +#define __DIRECTDRAW_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include +using namespace std; + +#define DIRECTDRAW_VERSION 0x0700 +#include +#include +#include + +#include "typedef.h" +#include "macro.h" + +class CDirectDraw +{ +public: + // pubNoϐ + typedef struct tagDISPLAYMODE { + DWORD dwWidth; + DWORD dwHeight; + DWORD dwDepth; + DWORD dwRate; + } DISPLAYMODE, *LPDISPLAYMODE; + + typedef struct tagPALBUF { + BYTE r; + BYTE g; + BYTE b; + } PALBUF, *LPPALBUF; + + // p”\ȃfBXvC[h + enum { DD_DISPLAYMODEMAX = 256 }; + + INT m_DisplayModeNum; // fBXvC[h + DISPLAYMODE m_DisplayModeBuf[DD_DISPLAYMODEMAX]; + + // Screen size + enum { SCREEN_WIDTH = 256, SCREEN_HEIGHT = 240 }; + + // Render screen size + enum { RENDER_WIDTH = SCREEN_WIDTH+16, RENDER_HEIGHT = SCREEN_HEIGHT }; + + // Delta screen size + enum { DELTA_WIDTH = SCREEN_WIDTH, DELTA_HEIGHT = SCREEN_HEIGHT+6 }; + + // Filter + enum { BLTFILTER_NONE = 0, + BLTFILTER_2XSAI, + BLTFILTER_SUPER2XSAI, + BLTFILTER_SUPEREAGLE, + BLTFILTER_SCALE2X, + }; + + // pubNo֐ + CDirectDraw(); + virtual ~CDirectDraw(); + + BOOL InitialDDraw( HWND hWnd ); + void ReleaseDDraw(); + + BOOL InitialSurface( BOOL bScreenMode ); + BOOL ReleaseSurface(); + BOOL RestoreSurface(); + + BOOL BeginDisplayChange(); + BOOL EndDisplayChange(); + BOOL OnChangeDisplayMode(); + + // Display[h + INT GetDisplayModeNum() { return m_DisplayModes.size(); } + void SetDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate ); + void GetDisplayMode( DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate ); + BOOL GetDisplayMode( INT no, DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate ); + INT GetMatchDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate ); + BOOL IsNowDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate ); + + BOOL CalcPaletteTable(); + void SetPaletteTable( LPBYTE pal ); + void SetPaletteTable( RGBQUAD* pal ); + void GetPaletteTable( RGBQUAD* pal ); + void SetPaletteFile( LPCTSTR fname ); + + BOOL SetFullScreenGDI( BOOL bMode ); + + void SetUseHEL( BOOL bUseHEL ) { + m_bUseHEL = bUseHEL; + m_bDeltaUpdate = TRUE; + } + void SetSystemMemory( BOOL bSystemMemory ) { + m_bSystemMemory = bSystemMemory; + m_bDeltaUpdate = TRUE; + } + void SetScreenMode( BOOL bScreenMode ) { + m_bScreenMode = bScreenMode; + m_bDeltaUpdate = TRUE; + } + void SetFlipMode( BOOL bFlip ) { + m_bFlip = bFlip; + } + void SetAspectMode( BOOL bAspect ) { + m_bAspect = bAspect; + } + void SetAllLineMode( BOOL bAllLine ) { + m_bAllLine = bAllLine; + } + void SetMaxZoom( BOOL bZoom ) { + m_bMaxZoom = bZoom; + } + void SetDoubleSize( BOOL bDoubleSize ) { + m_bDoubleSize = bDoubleSize; + m_bDeltaUpdate = TRUE; + } + void SetTVFrameMode( BOOL bTVFrame ) { + m_bTVFrameMode = bTVFrame; + } + void SetScanlineMode( BOOL bScanline ) { + m_bScanlineMode = bScanline; + m_bDeltaUpdate = TRUE; + } + void SetScanlineColor( INT nScanlineColor ) { + m_nScanlineColor = nScanlineColor; + } + + void SetZapperMode( BOOL bZapper ) { + m_bZapper = bZapper; + } + void SetZapperDrawMode( BOOL bDraw ) { + m_bZapperDraw = bDraw; + } + + void SetWindowVSyncMode( BOOL bVSync ) { + m_bWindowVSync = bVSync; + } + + void SetGraphicsFilter( INT nFilter ) { + m_nBltFilter = nFilter; + m_bDeltaUpdate = TRUE; + } + + BOOL GetUseHEL() { return m_bUseHEL; } + BOOL GetSystemMemory() { return m_bSystemMemory; } + BOOL GetScreenMode() { return m_bScreenMode; } + BOOL GetFlipMode() { return m_bFlip; } + BOOL GetAspectMode() { return m_bAspect; } + BOOL GetAllLineMode() { return m_bAllLine; } + BOOL GetMaxZoom() { return m_bMaxZoom; } + BOOL GetDoubleSize() { return m_bDoubleSize; } + BOOL GetTVFrameMode() { return m_bTVFrameMode; } + BOOL GetScanlineMode() { return m_bScanlineMode; } + INT GetScanlineColor() { return m_nScanlineColor; } + BOOL GetZapperMode() { return m_bZapper; } + BOOL GetZapperDrawMode() { return m_bZapperDraw; } + + BOOL GetWindowVSyncMode() { return m_bWindowVSync; } + + INT GetGraphicsFilter() { return m_nBltFilter; } + + LPBYTE GetRenderScreen() { return m_lpRender; } + LPBYTE GetLineColormode() { return m_LineColormode; } + + // For Zapper + BYTE GetZapperHit(); + void GetZapperPos( LONG& x, LONG& y ); + void SetZapperPos( LONG x, LONG y ); + + void SetInfoString( LPCSTR str ); + void SetMessageString( LPCSTR str ); + + void RealizePalette(); + + void OnScreenDraw(); + void SetPaletteMode( INT nMode, BOOL bMono ); + void GetPaletteData( RGBQUAD* rgb ); + + void SetDiskAccessLamp( BOOL bAccess ) { + m_bDiskAccessLamp = bAccess; + } + + void Blt(); + void Flip(); + + // MMX + BOOL IsMMX() { return m_bMMX; } + + unsigned char * font; + void ViewChars( unsigned char * lpRdr ); //дı + +protected: + // veNgoϐ + + // General + HWND m_hWnd; // Window handle + BOOL m_bChangeMode; // Screen Mode changing flag + BOOL m_bDraw; // Drawing flag + BOOL m_bNoRestore; + + BOOL m_bMessage; // Message display? + DWORD m_dwMessageTime; // Message display times + + BOOL m_bMMX; // Existence of MMX technology. + + // Options + BOOL m_bUseHEL; // HALg킸HELgp + BOOL m_bSystemMemory; // T[tFXɃVXegp + + BOOL m_bScreenMode; // FALSE:Window TRUE:Fullscreen + BOOL m_bFlip; // tbvgp + BOOL m_bGDI; // GDI + BOOL m_bAspect; // TVAXyNg␳ + BOOL m_bAllLine; // SC\ + BOOL m_bMaxZoom; // ʑŜ܂Ŋg + BOOL m_bDoubleSize; // Q{TCY_O + BOOL m_bTVFrameMode; // TVg\ + BOOL m_bScanlineMode; // XLC[h + INT m_nScanlineColor; // XLCJ[ + BOOL m_bZapper; // Zapper + BOOL m_bZapperDraw; // Zapper Sight drawing + + BOOL m_bWindowVSync; // Wait for VSync(Window mode) + + BOOL m_bForceWrite; // ɏ㏑` + INT m_nBltFilter; // Blit Filter + + // p”\ȃfBXvC[h + std::vector m_DisplayModes; + + // tXN[fBXvC[h + DWORD m_dwDisplayWidth; + DWORD m_dwDisplayHeight; + DWORD m_dwDisplayDepth; + DWORD m_dwDisplayRate; + + // DLL dynamic load + HINSTANCE m_hDDraw; // DLL Instance handle + + // DirectDraw object + LPDIRECTDRAW7 m_lpDD; // DirectDraw Object + LPDIRECTDRAWSURFACE7 m_lpDDPrimary; // PrimarySurface + LPDIRECTDRAWSURFACE7 m_lpDDBack; // BackSurface + LPDIRECTDRAWSURFACE7 m_lpDDRender; // RenderSurface + LPDIRECTDRAWSURFACE7 m_lpDDRender2; // RenderSurface2 + LPDIRECTDRAWSURFACE7 m_lpDDAscii; // AsciiSurface + LPDIRECTDRAWSURFACE7 m_lpDDZapper; // ZapperSurface + LPDIRECTDRAWSURFACE7 m_lpDDTV; // TVg(^^; + LPDIRECTDRAWCLIPPER m_lpDDClipper; // Clipper + LPDIRECTDRAWCLIPPER m_lpDDClipper2; // Render window Clipper + LPDIRECTDRAWPALETTE m_lpDDPalette; // DirectDraw Palette + + LPBYTE m_lpRender; + LPBYTE m_lpRenderDelta; + BYTE m_LineColormode[RENDER_HEIGHT]; + + BOOL m_bDeltaUpdate; + + // pbg + INT m_nPaletteMode; + BOOL m_bMonoMode; + BOOL m_bPaletteUpdate; // Palette Update? + + static PALBUF m_PalDefault[64]; // ftHgpbg + PALBUF m_PaletteBuf[64]; // pbgobt@ + + typedef struct tagLOGPAL { + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY pe[256]; + } LOGPAL, *LPLOGPAL; + + HPALETTE m_hPalette; // Windows GDI Palette handle + LOGPAL m_logPalette; // Windows GDI Palette + + // 256F[hp + RGBQUAD m_cpPalette[8][64*2]; // Color + RGBQUAD m_mpPalette[8][64*2]; // Monochrome + + // sNZtH[}bgɕϊpbg + DWORD m_cnPalette[8][256]; // Color + DWORD m_csPalette[8][256]; // Color/Scanline + DWORD m_mnPalette[8][256]; // Monochrome + DWORD m_msPalette[8][256]; // Monochrome/Scanline + + // 2xSaI mmxpRGB555pbg + DWORD m_cfPalette[8][256]; // Color + DWORD m_mfPalette[8][256]; // Monochrome + + // For Zapper + LONG m_ZapperPosX, m_ZapperPosY; + + // For Infomation&Message + enum { INFOSTR_SIZE = 64 }; + + CHAR m_szInfo[INFOSTR_SIZE+1]; + CHAR m_szMess[INFOSTR_SIZE+1]; + + // For DiskAccessLamp + BOOL m_bDiskAccessLamp; + + // veNgo֐ + static HRESULT WINAPI EnumModesCallback( LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext ); + + void RenderString( INT x, INT y, LPCSTR str ); + + BOOL RestoreSurfaceSub( LPDIRECTDRAWSURFACE7 lpSurface ); + void GetBitMask( DWORD val, int& shift, int& bits ); + + void SetLZSSChar( LPBYTE lpLZ, LPDIRECTDRAWSURFACE7 lpDDSurface ); + + // Blitters + typedef void (CDirectDraw::*BLTFUNC)(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + + static BLTFUNC NormalBltTable[]; + static BLTFUNC ScanlineBltTable[]; + static BLTFUNC DoubleBltTable[]; + static BLTFUNC DoubleScanlineBltTable[]; + static BLTFUNC nx2xSaIBltTable[]; + static BLTFUNC nxSuper2xSaIBltTable[]; + static BLTFUNC nxSuperEagleBltTable[]; + static BLTFUNC nxScale2xBltTable[]; + + // ʁc + void Render8bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render16bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render24bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render32bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + + void Render8bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render16bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render24bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render32bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + + void Render8bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render16bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render24bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render32bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + + void Render8bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render16bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render24bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void Render32bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + + // v_p + void Render16bpp( LPBYTE lpSrc, LPBYTE lpDst ); + void Render16bppPrefilter( LPBYTE lpSrc, LPBYTE lpDst ); + void Render32bpp( LPBYTE lpSrc, LPBYTE lpDst ); + + // Effects + void nx_2xSaI_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_2xSaI_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_Super2xSaI_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_Super2xSaI_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_SuperEagle_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_SuperEagle_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_Scale2x_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + void nx_Scale2x_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL); + +private: + // vCx[goϐ + // vCx[go֐ +}; + +extern CDirectDraw DirectDraw; + +#endif // !__DIRECTDRAW_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/DirectInput.cpp b/References/VirtuaNESex_src_191105/DirectInput.cpp new file mode 100644 index 00000000..22605a8f --- /dev/null +++ b/References/VirtuaNESex_src_191105/DirectInput.cpp @@ -0,0 +1,477 @@ +// +// DirectInput class +// +#include "DebugOut.h" +#include "DirectInput.h" +#include "COM.h" +#include "Config.h" + +CDirectInput DirectInput; + +#define COMUSE TRUE + +// +// Table +// +CDirectInput::DIKEYTBL CDirectInput::DIKeyTable[] = { + DIK_ESCAPE, "ESC", DIK_1, "1", + DIK_2, "2", DIK_3, "3", + DIK_4, "4", DIK_5, "5", + DIK_6, "6", DIK_7, "7", + DIK_8, "8", DIK_9, "9", + DIK_0, "0", DIK_MINUS, "-", + DIK_EQUALS, "=", DIK_BACK, "BackSpace", + DIK_TAB, "TAB", DIK_Q, "Q", + DIK_W, "W", DIK_E, "E", + DIK_R, "R", DIK_T, "T", + DIK_Y, "Y", DIK_U, "U", + DIK_I, "I", DIK_O, "O", + DIK_P, "P", DIK_LBRACKET, "[", + DIK_RBRACKET, "]", DIK_RETURN, "Enter", + DIK_LCONTROL, "L Ctrl", DIK_A, "A", + DIK_S, "S", DIK_D, "D", + DIK_F, "F", DIK_G, "G", + DIK_H, "H", DIK_J, "J", + DIK_K, "K", DIK_L, "L", + DIK_SEMICOLON, ";", DIK_APOSTROPHE, "'", + DIK_GRAVE, "`", DIK_LSHIFT, "L Shift", + DIK_BACKSLASH, "\\", DIK_Z, "Z", + DIK_X, "X", DIK_C, "C", + DIK_V, "V", DIK_B, "B", + DIK_N, "N", DIK_M, "M", + DIK_COMMA, ",", DIK_PERIOD, ".", + DIK_SLASH, "/", DIK_RSHIFT, "R Shift", + DIK_MULTIPLY, "*", DIK_LMENU, "L Alt", + DIK_SPACE, "Space", + DIK_F1, "F1", DIK_F2, "F2", + DIK_F3, "F3", DIK_F4, "F4", + DIK_F5, "F5", DIK_F6, "F6", + DIK_F7, "F7", DIK_F8, "F8", + DIK_F9, "F9", DIK_F10, "F10", + + DIK_NUMPAD7, "Num 7", DIK_NUMPAD8, "Num 8", + DIK_NUMPAD9, "Num 9", DIK_SUBTRACT, "Num -", + DIK_NUMPAD4, "Num 4", DIK_NUMPAD5, "Num 5", + DIK_NUMPAD6, "Num 6", DIK_ADD, "Num +", + DIK_NUMPAD1, "Num 1", DIK_NUMPAD2, "Num 2", + DIK_NUMPAD3, "Num 3", DIK_NUMPAD0, "Num 0", + DIK_DECIMAL, "Num .", DIK_F11, "F11", + DIK_F12, "F12", DIK_F13, "F13", + DIK_F14, "F14", DIK_F15, "F15", + DIK_CONVERT, "ϊ", + DIK_NOCONVERT, "ϊ", DIK_YEN, "\\", + DIK_NUMPADEQUALS,"Num =", DIK_CIRCUMFLEX, "^", + DIK_AT, "@", DIK_COLON, ":", + DIK_UNDERLINE, "_", + DIK_STOP, "Stop", DIK_NUMPADENTER,"Num Enter", + DIK_RCONTROL, "R Ctrl", DIK_NUMPADCOMMA,"Num ,", + DIK_DIVIDE, "Num /", DIK_SYSRQ, "SysRq", + DIK_RMENU, "R Alt", DIK_PAUSE, "Pause", + DIK_HOME, "Home", DIK_UP, "Up", + DIK_PRIOR, "Page Up", DIK_LEFT, "Left", + DIK_RIGHT, "Right", DIK_END, "End", + DIK_DOWN, "Down", DIK_NEXT, "Page Down", + DIK_INSERT, "Insert", DIK_DELETE, "Delete", + DIK_LWIN, "L Windows", DIK_LWIN, "R Windows", + DIK_APPS, "AppMenu", + +#if 0 +// gOnL[Ȃ̂ŎgȂ + DIK_CAPITAL, "Caps Lock", + DIK_NUMLOCK, "NumLock", + DIK_SCROLL, "ScrollLock", + DIK_KANA, "Ji", + DIK_KANJI, "", +#endif + 0x00, NULL +}; + +LPSTR CDirectInput::DIKeyDirTable[] = { + "X+", "X-", "Y+", "Y-", "Z+", "Z-", + "RX+", "RX-", "RY+", "RY-", "RZ+", "RZ-", + "S0+", "S0-", "S1+", "S1-", +}; + +LPSTR CDirectInput::DIKeyDirTable2[] = { + "P0 Up", "P0 Down", "P0 Left", "P0 Right", + "P1 Up", "P1 Down", "P1 Left", "P1 Right", + "P2 Up", "P2 Down", "P2 Left", "P2 Right", + "P3 Up", "P3 Down", "P3 Left", "P3 Right", +}; + +////////////////////////////////////////////////////////////////////// +// \z/ +////////////////////////////////////////////////////////////////////// + +CDirectInput::CDirectInput() +{ + m_lpDI = NULL; + m_lpKeyboard = NULL; + + m_nJoystickNum = 0; + + ZEROMEMORY( m_lpJoystick, sizeof(m_lpJoystick) ); + ZEROMEMORY( m_Sw, sizeof(m_Sw) ); + + ZEROMEMORY( m_JoyAxisMode, sizeof(m_JoyAxisMode) ); + +#if COMUSE + COM::AddRef(); +#endif +} + +CDirectInput::~CDirectInput() +{ + ReleaseDInput(); + +#if COMUSE + COM::AddRef(); +#endif +} + +////////////////////////////////////////////////////////////////////// +// o֐ +////////////////////////////////////////////////////////////////////// +// foCXIuWFNg񋓃R[obN +BOOL CALLBACK CDirectInput::DIEnumDevicesCallback( LPDIDEVICEINSTANCE lpddi, LPVOID pvRef ) +{ + CDirectInput* pCDi = (CDirectInput*)pvRef; + +// DEBUGOUT( "dwDevType=%08X IName:%s PName:%s\n", lpddi->dwDevType, lpddi->tszInstanceName, lpddi->tszProductName ); + + if( pCDi->AddJoystickDevice( lpddi->guidInstance ) ) + return DIENUM_CONTINUE; + + return DIENUM_STOP; +} + +// WCXeBbNfoCXIuWFNg̍쐬 +BOOL CDirectInput::AddJoystickDevice( GUID deviceguid ) +{ + LPDIRECTINPUTDEVICE7 lpDIDev; + + if( m_lpDI->CreateDeviceEx( deviceguid, IID_IDirectInputDevice7, + (LPVOID*)&lpDIDev, NULL ) != DI_OK ) { + return FALSE; + } + + if( lpDIDev->SetDataFormat( &c_dfDIJoystick ) != DI_OK ) { + DEBUGOUT( "CDirectInput:SetDataFormat failed.\n" ); + RELEASE( lpDIDev ); + return FALSE; + } + + INT nID = m_nJoystickNum; + + if( !Config.general.bNoJoystickID ) { + // DX7ł͉Bvf̃WCXeBbNID̎擾(DX8̓}jAɋLڂĂ) + DIPROPDWORD diprp_dw; + ZEROMEMORY( &diprp_dw, sizeof(diprp_dw) ); + diprp_dw.diph.dwSize = sizeof(DIPROPDWORD); + diprp_dw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprp_dw.diph.dwHow = DIPH_DEVICE; + diprp_dw.diph.dwObj = 0; + + if( lpDIDev->GetProperty( DIPROP_JOYSTICKID, &diprp_dw.diph ) != DI_OK ) { + DEBUGOUT( "CDirectInput:GetProperty failed.\n" ); + RELEASE( lpDIDev ); + return FALSE; + } +DEBUGOUT( "ID:%d\n", diprp_dw.dwData ); + + nID = diprp_dw.dwData; + } + + if( nID < DIJOYSTICK_MAX ) { + m_lpJoystick[ nID ] = lpDIDev; + + // ẽWݒ + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.diph.dwObj = DIJOFS_X; + diprg.lMin = -10000; + diprg.lMax = +10000; + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + diprg.diph.dwObj = DIJOFS_Y; + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + diprg.diph.dwObj = DIJOFS_Z; + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + diprg.diph.dwObj = DIJOFS_RX; + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + diprg.diph.dwObj = DIJOFS_RY; + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + diprg.diph.dwObj = DIJOFS_RZ; + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + + diprg.diph.dwObj = DIJOFS_SLIDER(0); + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + diprg.diph.dwObj = DIJOFS_SLIDER(1); + lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph ); + + // ̂̎擾 + DIDEVICEINSTANCE didins; + ZEROMEMORY( &didins, sizeof(didins) ); + didins.dwSize = sizeof( didins ); + lpDIDev->GetDeviceInfo( &didins ); + + m_JoyName[ nID ] = didins.tszInstanceName; +DEBUGOUT( "Instance Name:%s\n", didins.tszInstanceName ); +//DEBUGOUT( "Product Name:%s\n", didins.tszProductName ); + } else { + m_lpJoystick[ nID ] = NULL; + RELEASE( lpDIDev ); + } + + m_nJoystickNum++; + + return TRUE; +} + +// DirectInputIuWFNg^foCXIuWFNg̍\z +BOOL CDirectInput::InitialDInput(HWND hWnd, HINSTANCE hInst) +{ + try { + // CDirectInputIuWFNg̍쐬 +#if !COMUSE + if( DirectInputCreateEx( hInst, DIRECTINPUT_VERSION, IID_IDirectInput7, (LPVOID*)&m_lpDI, NULL ) != DI_OK ) { + m_lpDI = NULL; + throw "CDirectInput:DirectInputCreateEx failed."; + } +#else + // COMIp +// COM::AddRef(); + if( FAILED(CoCreateInstance( CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, IID_IDirectInput7, (VOID**)&m_lpDI )) ) { + m_lpDI = NULL; + throw "CDirectInput:CoCreateInstance failed."; + } + if( m_lpDI->Initialize( hInst, DIRECTINPUT_VERSION ) != DI_OK ) + throw "CDirectInput:IDirectInput7->Initialize failed."; +#endif + + if( m_lpDI->CreateDevice( GUID_SysKeyboard, &m_lpKeyboard, NULL ) != DI_OK ) + throw "CDirectInput:CreateDevice failed."; + + if( m_lpKeyboard ) { + if( m_lpKeyboard->SetDataFormat( &c_dfDIKeyboard ) != DI_OK ) + throw "CDirectInput:SetDataFormat failed."; + if( m_lpKeyboard->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND) != DI_OK ) + throw "CDirectInput:SetCooperativeLevel failed."; + if( m_lpKeyboard->Acquire() != DI_OK ) { +// DEBUGOUT( "CDirectInput:Acquire failed.\n" ); + } + } + + m_nJoystickNum = 0; + if( m_lpDI->EnumDevices( DIDEVTYPE_JOYSTICK, (LPDIENUMDEVICESCALLBACK)DIEnumDevicesCallback, + (LPVOID)this, DIEDFL_ATTACHEDONLY ) != DI_OK ) { + DEBUGOUT( "CDirectInput:EnumDevices failed.\n" ); + } + + if( !m_nJoystickNum ) { + DEBUGOUT( "CDirectInput:No Joystick device available.\n" ); + } else { + for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) { + if( m_lpJoystick[i] ) { + if( m_lpJoystick[i]->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND) != DI_OK ) { + DEBUGOUT( "CDirectInput:SetCooperativeLevel failed.\n" ); + throw "CDirectInput:SetCooperativeLevel failed."; + } + } + } + + DEBUGOUT( "CDirectInput:Can use %d Joystick(s)\n", m_nJoystickNum ); + } + } catch( char *str ) { + ReleaseDInput(); + + MessageBox( hWnd, str, "ERROR", MB_ICONERROR|MB_OK ); + + return FALSE; + } + + return TRUE; +} + +void CDirectInput::ReleaseDInput() +{ + for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) { + RELEASE( m_lpJoystick[i] ); + } + + if( m_lpKeyboard ) { +// m_lpKeyboard->Unacquire(); + RELEASE( m_lpKeyboard ); + } + + if( m_lpDI ) { + RELEASE( m_lpDI ); +#if COMUSE +// COM::Release(); +#endif + } +} + +// ̓tH[JX擾 +void CDirectInput::Acquire() +{ + if( !m_lpDI ) + return; + if( m_lpKeyboard ) + m_lpKeyboard->Acquire(); + for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) { + if( m_lpJoystick[i] ) { + m_lpJoystick[i]->Acquire(); + } + } +} + +// ̓tH[JXJ +void CDirectInput::Unacquire() +{ + if( !m_lpDI ) + return; + if( m_lpKeyboard ) + m_lpKeyboard->Unacquire(); + for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) { + if( m_lpJoystick[i] ) { + m_lpJoystick[i]->Unacquire(); + } + } +} + +// f[^|[O +void CDirectInput::Poll() +{ +DIJOYSTATE js; + + ZEROMEMORY( m_Sw, sizeof(m_Sw) ); + + if( !m_lpDI ) { + return; + } + + if( m_lpKeyboard ) { + if( m_lpKeyboard->GetDeviceState( 256, &m_Sw ) == DIERR_INPUTLOST ) { + m_lpKeyboard->Acquire(); + m_lpKeyboard->GetDeviceState( 256, &m_Sw ); + } + } + + INT idx; + for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) { + if( !m_lpJoystick[i] ) + continue; + + idx = 256+i*64; + + if( m_lpJoystick[i]->Poll() == DIERR_INPUTLOST ) { + m_lpJoystick[i]->Acquire(); + m_lpJoystick[i]->Poll(); + } + if( m_lpJoystick[i]->GetDeviceState( sizeof(DIJOYSTATE), &js ) != DI_OK ) { + ZEROMEMORY( &js, sizeof(DIJOYSTATE) ); + } + + m_JoyAxis[i][0] = js.lX; + m_JoyAxis[i][1] = js.lY; + m_JoyAxis[i][2] = js.lZ; + m_JoyAxis[i][3] = js.lRx; + m_JoyAxis[i][4] = js.lRy; + m_JoyAxis[i][5] = js.lRz; + + if( !(m_JoyAxisMode[i] & (1<<0)) ) { + if( js.lX > 8000 ) m_Sw[idx + DI_XAXIS+0] = 0x80; + if( js.lX < -8000 ) m_Sw[idx + DI_XAXIS+1] = 0x80; + } + if( !(m_JoyAxisMode[i] & (1<<1)) ) { + if( js.lY > 8000 ) m_Sw[idx + DI_YAXIS+0] = 0x80; + if( js.lY < -8000 ) m_Sw[idx + DI_YAXIS+1] = 0x80; + } + if( !(m_JoyAxisMode[i] & (1<<2)) ) { + if( js.lZ > 8000 ) m_Sw[idx + DI_ZAXIS+0] = 0x80; + if( js.lZ < -8000 ) m_Sw[idx + DI_ZAXIS+1] = 0x80; + } + if( !(m_JoyAxisMode[i] & (1<<3)) ) { + if( js.lRx > 8000 ) m_Sw[idx + DI_RXAXIS+0] = 0x80; + if( js.lRx < -8000 ) m_Sw[idx + DI_RXAXIS+1] = 0x80; + } + if( !(m_JoyAxisMode[i] & (1<<4)) ) { + if( js.lRy > 8000 ) m_Sw[idx + DI_RYAXIS+0] = 0x80; + if( js.lRy < -8000 ) m_Sw[idx + DI_RYAXIS+1] = 0x80; + } + if( !(m_JoyAxisMode[i] & (1<<5)) ) { + if( js.lRz > 8000 ) m_Sw[idx + DI_RZAXIS+0] = 0x80; + if( js.lRz < -8000 ) m_Sw[idx + DI_RZAXIS+1] = 0x80; + } + +#if 0 +// 2003/11/3 Ƃ肠 + if( js.rglSlider[0] > 8000 ) m_Sw[idx + DI_SLIDER0+0] = 0x80; + if( js.rglSlider[0] < -8000 ) m_Sw[idx + DI_SLIDER0+1] = 0x80; + if( js.rglSlider[1] > 8000 ) m_Sw[idx + DI_SLIDER1+0] = 0x80; + if( js.rglSlider[1] < -8000 ) m_Sw[idx + DI_SLIDER1+1] = 0x80; +#endif + + for( INT j = 0; j < 32; j++ ) { + m_Sw[idx + DI_BUTTON + j] = js.rgbButtons[j]; + } + + // POV + for( INT pov = 0; pov < 4; pov++ ) { + DWORD dwPOV = js.rgdwPOV[pov]; + BOOL bPOVcenter = (LOWORD(dwPOV) == 0xFFFF); + + BYTE data = 0; + if( !bPOVcenter ) { + static const BYTE dirtbl[] = { + (1<<0), (1<<0)|(1<<3), (1<<3), (1<<1)|(1<<3), + (1<<1), (1<<1)|(1<<2), (1<<2), (1<<0)|(1<<2), + }; + + data = dirtbl[ ((dwPOV+(DWORD)(22.5*DI_DEGREES)) % (360*DI_DEGREES))/(45*DI_DEGREES) ]; + } + + // Up/Down + if( data & (1<<0) ) m_Sw[idx + DI_POV0_UD+i*4+0] = 0x80; + if( data & (1<<1) ) m_Sw[idx + DI_POV0_UD+i*4+1] = 0x80; + // Left/Right + if( data & (1<<2) ) m_Sw[idx + DI_POV0_LR+i*4+0] = 0x80; + if( data & (1<<3) ) m_Sw[idx + DI_POV0_LR+i*4+1] = 0x80; + } + } +} + +LPCSTR CDirectInput::SearchKeyName( INT key ) +{ +LPDIKEYTBL kt = DIKeyTable; +static CHAR KeyStr[256]; + + if( key == 0x00 ) + return NULL; + + if( key < 0x100 ) { + while( kt->name != NULL ) { + if( kt->key == key ) + return kt->name; + kt++; + } + } else { + INT no = (key-256)>>6; + INT idx = key & 0x3F; + if( idx < DI_MAXAXIS ) { + ::wsprintf( KeyStr, "J:%d %s", no, DIKeyDirTable[idx] ); + return KeyStr; + } else if( idx >= DI_BUTTON && idx < DI_BUTTON_END ) { + ::wsprintf( KeyStr, "J:%d B:%02d", no, idx-DI_BUTTON ); + return KeyStr; + } else if( idx >= DI_EXT && idx < DI_EXT_END ) { + ::wsprintf( KeyStr, "J:%d %s", no, DIKeyDirTable2[idx-DI_EXT] ); + return KeyStr; + } + } + + return NULL; +} + diff --git a/References/VirtuaNESex_src_191105/DirectInput.h b/References/VirtuaNESex_src_191105/DirectInput.h new file mode 100644 index 00000000..99e53935 --- /dev/null +++ b/References/VirtuaNESex_src_191105/DirectInput.h @@ -0,0 +1,87 @@ +// +// DirectInput class +// +#ifndef __DIRECTINPUT_INCLUDED__ +#define __DIRECTINPUT_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define DIRECTINPUT_VERSION 0x0700 +#include + +#include "typedef.h" +#include "macro.h" + +#include +using namespace std; + +class CDirectInput +{ +public: + // pubNoϐ + typedef struct tagDIKEYTBL { + WORD key; + LPCSTR name; + } DIKEYTBL, *LPDIKEYTBL; + + static DIKEYTBL DIKeyTable[]; + + INT m_nJoystickNum; + enum { DIJOYSTICK_MAX = 16 }; + enum { + DI_XAXIS = 0, DI_YAXIS = 2, DI_ZAXIS = 4, + DI_RXAXIS = 6, DI_RYAXIS = 8, DI_RZAXIS = 10, + DI_SLIDER0 = 12, DI_SLIDER1 = 14, + DI_MAXAXIS = 16, + DI_BUTTON = 16, DI_BUTTON_END = 48, + DI_EXT = 48, + DI_POV0_UD = 48, DI_POV0_LR = 50, + DI_POV1_UD = 52, DI_POV1_LR = 54, + DI_POV2_UD = 56, DI_POV2_LR = 58, + DI_POV3_UD = 60, DI_POV3_LR = 62, + DI_EXT_END = 64, + }; + + BYTE m_Sw[256+64*DIJOYSTICK_MAX]; + LONG m_JoyAxis[DIJOYSTICK_MAX][8]; + string m_JoyName[DIJOYSTICK_MAX]; + + static LPSTR DIKeyDirTable[]; + static LPSTR DIKeyDirTable2[]; + + // pubNo֐ + CDirectInput(); + virtual ~CDirectInput(); + + BOOL InitialDInput( HWND hWnd, HINSTANCE hInst ); + void ReleaseDInput( void ); + + void Acquire(); + void Unacquire(); + void Poll(); + + BOOL AddJoystickDevice( GUID deviceguid ); + + void SetJoyAxisMode( LPWORD pMode ) { + for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) + m_JoyAxisMode[i] = pMode[i]; + }; + + LPCSTR SearchKeyName( INT key ); +protected: + // veNgoϐ + LPDIRECTINPUT7 m_lpDI; + LPDIRECTINPUTDEVICE m_lpKeyboard; + LPDIRECTINPUTDEVICE7 m_lpJoystick[DIJOYSTICK_MAX]; + + WORD m_JoyAxisMode[DIJOYSTICK_MAX]; + + // veNgo֐ + static BOOL CALLBACK DIEnumDevicesCallback( LPDIDEVICEINSTANCE lpddi, LPVOID pvRef ); +}; + +extern CDirectInput DirectInput; + +#endif // !__DIRECTINPUT_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/DirectSound.cpp b/References/VirtuaNESex_src_191105/DirectSound.cpp new file mode 100644 index 00000000..144a322f --- /dev/null +++ b/References/VirtuaNESex_src_191105/DirectSound.cpp @@ -0,0 +1,607 @@ +// +// DirectSound class +// +#include "DebugOut.h" +#include "DirectSound.h" +#include "COM.h" + +CDirectSound DirectSound; + +#define COMUSE TRUE + +// +// WaveFilẽ[hƃւ̕ێ +// +CWaveData::CWaveData() +{ + m_pBuffer = NULL; + m_pwfex = NULL; + m_dwSize = 0; + m_pData = NULL; +} + +CWaveData::~CWaveData() +{ + Free(); +} + +BOOL CWaveData::Load( LPCSTR szFileName ) +{ + Free(); + + FILE* fp = NULL; + if( !(fp = ::fopen( szFileName, "rb" )) ) { + return FALSE; + } + + LONG size; + ::fseek( fp, 0, SEEK_END ); + size = ::ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + + if( size < 0 ) { + return FALSE; + } + + if( !(m_pBuffer = ::malloc( size )) ) { + return FALSE; + } + + if( ::fread( m_pBuffer, size, 1, fp ) != 1 ) { + Free(); + return FALSE; + } + FCLOSE( fp ); + + LPWAVEFORMATEX pWaveHeader; + BYTE *pbWaveData; + DWORD cbWaveSize; + DWORD *pdw, *pdwEnd; + DWORD dwRiff, dwLength, dwType; + + // WAVEf[^̉ + pWaveHeader = NULL; + pbWaveData = NULL; + cbWaveSize = 0; + + pdw = (DWORD *)m_pBuffer; + dwRiff = *pdw++; + dwLength = *pdw++; + dwType = *pdw++; + if( dwRiff != mmioFOURCC( 'R','I','F','F' ) ) { + Free(); + return FALSE; + } + if( dwType != mmioFOURCC( 'W','A','V','E' ) ) { + Free(); + return FALSE; + } + pdwEnd = (DWORD*)((BYTE*)pdw+dwLength-sizeof(DWORD)); + + while( pdw < pdwEnd ) { + dwType = *pdw++; + dwLength = *pdw++; + + switch( dwType ) { + case mmioFOURCC( 'f','m','t',' ' ): + if( pWaveHeader == NULL ) { + if( dwLength < sizeof(WAVEFORMAT) ) { + Free(); + return FALSE; + } + pWaveHeader = (WAVEFORMATEX *)pdw; + } + break; + case mmioFOURCC( 'd','a','t','a' ): + if( (pbWaveData == NULL)||(!cbWaveSize) ) { + pbWaveData = (BYTE *)pdw; + cbWaveSize = dwLength; + } + } + if( pWaveHeader && (pbWaveData != NULL) && cbWaveSize) + break; + pdw = (DWORD *)((BYTE*)pdw + ((dwLength+1)&~1)); + } + if( pdwEnd <= pdw ) { + Free(); + return FALSE; + } + if( pWaveHeader->wFormatTag != WAVE_FORMAT_PCM ) { + Free(); + return FALSE; + } + + m_pwfex = pWaveHeader; + m_dwSize = dwLength; + m_pData = pbWaveData; + + return TRUE; +} + +void CWaveData::Free() +{ + FREE( m_pBuffer ); +} + +DWORD CWaveData::GetSize() +{ + if( !m_pBuffer ) + return 0; + return m_dwSize; +} + +WAVEFORMATEX* CWaveData::GetFormat() +{ + if( !m_pBuffer ) + return 0; + return m_pwfex; +} + +LPVOID CWaveData::GetData() +{ + if( !m_pBuffer ) + return 0; + return m_pData; +} + +////////////////////////////////////////////////////////////////////// +// \z/ +////////////////////////////////////////////////////////////////////// +CDirectSound::SAMPLERATE CDirectSound::m_SampleRateTable[] = { + 11025, 8, + 22050, 8, + 44100, 8, + 48000, 8, + 11025, 16, + 22050, 16, + 44100, 16, + 48000, 16, + 0, 0 +}; + +INT CDirectSound::m_BufferSizeTable[] = { + 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 +}; + +CDirectSound::CDirectSound() +{ + m_lpDS = NULL; + m_lpDSPrimary = NULL; + m_lpDSStream = NULL; + +#if 1 + m_SampleRate.Rate = 22050; +#else + m_SampleRate.Rate = 44100; +#endif + +// m_SampleRate.Bits = 8; + m_SampleRate.Bits = 16; + m_BufferSize = 1; +// m_BufferSize = 2; + + m_bStreamPlay = FALSE; + m_bStreamPause = FALSE; + + for( INT i = 0; i < ESF_FILE_MAX; i++ ) { + m_pEsfDSBuffer[ i ] = NULL; + } + +#if COMUSE + COM::AddRef(); +#endif +} + +CDirectSound::~CDirectSound() +{ + ReleaseDSound(); + +#if COMUSE + COM::Release(); +#endif +} + +// DirectSound̏ +BOOL CDirectSound::InitialDSound( HWND hWnd ) +{ +DSBUFFERDESC dsbdesc; + + m_hWnd = hWnd; + + try { + // DirectSoundIuWFNg̍쐬 +#if !COMUSE + if( DirectSoundCreate( NULL, &m_lpDS, NULL ) != DS_OK ) { + m_lpDS = NULL; + throw "CDirectSound:DirectSoundCreate failed."; + } +#else + // COMIp +// COM::AddRef(); + if( ::CoCreateInstance( CLSID_DirectSound, NULL, CLSCTX_ALL, IID_IDirectSound, (LPVOID*)&m_lpDS) != S_OK ) { + m_lpDS = NULL; + throw "CDirectSound:CoCreateInstance failed."; + } + if( m_lpDS->Initialize( NULL ) != DS_OK ) + throw "CDirectSound:IDirectSound->Initialize failed."; +#endif + + // D拦[h̐ݒ + if( m_lpDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ) != DS_OK ) + throw "CDirectSound:SetCooperativeLevel failed."; + + // Xs[J̐ݒ +// m_lpDS->SetSpeakerConfig( DSSPEAKER_COMBINED( DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE ) ); + + // vC}obt@̍쐬 + ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); + dsbdesc.dwSize = sizeof(DSBUFFERDESC); +// dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME +// | DSBCAPS_PRIMARYBUFFER; + dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; + dsbdesc.dwBufferBytes = 0; + dsbdesc.lpwfxFormat = NULL; + if( m_lpDS->CreateSoundBuffer( &dsbdesc, &m_lpDSPrimary, NULL ) != DS_OK ) + throw "CDirectSound:CreateSoundBuffer failed."; + } catch( char *str ) { + ReleaseDSound(); + ::MessageBox( hWnd, str, "ERROR", MB_ICONERROR|MB_OK ); + + return FALSE; + } + + return TRUE; +} + +// DirectSound̊J +void CDirectSound::ReleaseDSound() +{ + ReleaseEsfBuffer(); + ReleaseBuffer(); + // DirectSoundIuWFNg̊J + RELEASE( m_lpDSPrimary ); + if( m_lpDS ) { + RELEASE( m_lpDS ); +#if COMUSE +// COM::Release(); +#endif + } + + m_hWnd = NULL; +} + +// DirectSoundobt@̍쐬 +BOOL CDirectSound::InitialBuffer() +{ +DSBUFFERDESC dsbdesc; +WAVEFORMATEX pcmwf; + + try { + if( !m_lpDSPrimary ) + throw "CDirectSound:DirectSound object uninitialized."; + + // vC}obt@WavetH[}bgݒ(Ƀm) + ZEROMEMORY( &pcmwf, sizeof(WAVEFORMATEX) ); + pcmwf.wFormatTag = WAVE_FORMAT_PCM; + pcmwf.nChannels = 1; + pcmwf.nSamplesPerSec = (WORD)m_SampleRate.Rate; + pcmwf.nBlockAlign = (WORD)m_SampleRate.Bits/8; + pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign; + pcmwf.wBitsPerSample = (WORD)m_SampleRate.Bits; + + if( m_lpDSPrimary->SetFormat( &pcmwf ) != DS_OK ) + throw "CDirectSound:SetFormat failed."; + + // Xg[ZJ_obt@쐬 + if( m_BufferSize < 2 ) + m_BufferSize = 2; + + // obt@TCY̌vZ + m_dwDSBlockNum = m_BufferSize * 10; + m_dwDSBlockSize = pcmwf.nAvgBytesPerSec * m_BufferSize / 60; + m_dwDSBlockSize-= m_dwDSBlockSize % pcmwf.nBlockAlign; + m_dwDSBufferSize = m_dwDSBlockSize * m_dwDSBlockNum; + m_dwDSLastBlock = 0; + + ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE + | DSBCAPS_GETCURRENTPOSITION2 + | DSBCAPS_GLOBALFOCUS; + dsbdesc.dwBufferBytes = m_dwDSBufferSize; + dsbdesc.lpwfxFormat = &pcmwf; + + if( m_lpDS->CreateSoundBuffer( &dsbdesc, &m_lpDSStream, NULL ) != DS_OK ) + throw "CDirectSound:CreateSoundBuffer failed."; + + LPBYTE lpPtr; + DWORD dwBytes; + if( m_lpDSStream->Lock( 0, m_dwDSBufferSize, (LPVOID*)&lpPtr, &dwBytes, NULL, NULL, 0 ) != DS_OK ) { + throw "CDirectSound:Lock failed."; + } else { + FillMemory( lpPtr, dwBytes, (BYTE)(m_SampleRate.Bits==8?128:0) ); + m_lpDSStream->Unlock( lpPtr, dwBytes, NULL, NULL ); + } + } catch( char *str ) { + ReleaseBuffer(); + + ::MessageBox( m_hWnd, str, "ERROR", MB_ICONERROR|MB_OK ); + + return FALSE; + } + + return TRUE; +} + +// DirectSoundobt@̊J +void CDirectSound::ReleaseBuffer() +{ + StreamStop(); + RELEASE( m_lpDSStream ); +} + +// TvO[g̐ݒ +BOOL CDirectSound::SetSamplingRate( DWORD rate, DWORD bits ) +{ +INT i; + + i = 0; + while( m_SampleRateTable[i].Rate != 0 ) { + if( m_SampleRateTable[i].Rate == rate + && m_SampleRateTable[i].Bits == bits ) { + m_SampleRate.Rate = rate; + m_SampleRate.Bits = bits; + return TRUE; + } + i++; + } + return FALSE; +} + +// TvO[g̎擾 +void CDirectSound::GetSamplingRate( DWORD& rate, DWORD& bits ) +{ + rate = m_SampleRate.Rate; + bits = m_SampleRate.Bits; +} + +// Xg[~OĐ +void CDirectSound::StreamPlay() +{ + if( !m_lpDS || !m_lpDSStream ) + return; + + if( !m_bStreamPlay ) { + // Buffer clear + LPBYTE lpPtr; + DWORD dwBytes; + if( m_lpDSStream->Lock( 0, m_dwDSBufferSize, (LPVOID*)&lpPtr, &dwBytes, NULL, NULL, 0 ) != DS_OK ) { + throw "CDirectSound:Lock failed."; + } else { + FillMemory( lpPtr, dwBytes, (BYTE)(m_SampleRate.Bits==8?128:0) ); + m_lpDSStream->Unlock( lpPtr, dwBytes, NULL, NULL ); + } + + m_dwDSLastBlock = 0xFFFFFFFF; + m_bStreamPlay = TRUE; + m_bStreamPause = FALSE; + m_lpDSStream->SetCurrentPosition( 0 ); + m_lpDSStream->Play( 0, 0, DSBPLAY_LOOPING ); + } +} + +// Xg[~O~ +void CDirectSound::StreamStop() +{ + if( !m_lpDS || !m_lpDSStream ) + return; + + if( m_bStreamPlay ) { + m_bStreamPlay = FALSE; + m_bStreamPause = FALSE; + m_lpDSStream->Stop(); + + // S~܂ő҂ + DWORD dwStatus; + do { + m_lpDSStream->GetStatus( &dwStatus ); + } while( dwStatus & DSBSTATUS_PLAYING ); + + m_lpDSStream->SetCurrentPosition( 0 ); + } +} + +// Xg[~O|[Y +void CDirectSound::StreamPause() +{ +// DEBUGOUT( "CDirectSound::StreamPause\n" ); + + if( !m_lpDS || !m_lpDSStream ) + return; + + if( m_bStreamPlay ) { + if( !m_bStreamPause ) { + m_bStreamPause = TRUE; + m_lpDSStream->Stop(); + } + } +} + +// Xg[~OW[ +void CDirectSound::StreamResume() +{ +// DEBUGOUT( "CDirectSound::StreamResume\n" ); + + if( !m_lpDS || !m_lpDSStream ) + return; + + if( m_bStreamPlay ) { + if( m_bStreamPause ) { + m_bStreamPause = FALSE; + m_lpDSStream->Play( 0, 0, DSBPLAY_LOOPING ); + } + } +} + +// Xg[~O +BOOL CDirectSound::GetStreamLockPosition( LPDWORD lpdwStart, LPDWORD lpdwSize ) +{ +static BOOL bLockHalf = FALSE; +DWORD dwPlayPos, dwWritePos; + + if( m_lpDSStream->GetCurrentPosition( &dwPlayPos, &dwWritePos ) == DS_OK ) { + if( (dwWritePos / m_dwDSBlockSize) != m_dwDSLastBlock ) { + m_dwDSLastBlock = dwWritePos / m_dwDSBlockSize; + dwWritePos = (((dwWritePos/m_dwDSBlockSize)+1)%m_dwDSBlockNum) * m_dwDSBlockSize; + // bNׂꏊ + *lpdwStart = dwWritePos; + *lpdwSize = m_dwDSBlockSize; + return TRUE; + } + } + + return FALSE; +} + +BOOL CDirectSound::StreamLock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID* lplpvPtr1, LPDWORD lpdwBytes1, LPVOID* lplpvPtr2, LPDWORD lpdwBytes2, DWORD dwFlags ) +{ + if( m_lpDSStream->Lock( dwWriteCursor, dwWriteBytes, lplpvPtr1, lpdwBytes1, lplpvPtr2, lpdwBytes2, dwFlags ) == DS_OK ) + return TRUE; + return FALSE; +} + +BOOL CDirectSound::StreamUnlock( LPVOID lpvPtr1, DWORD dwBytes1, LPVOID lpvPtr2, DWORD dwBytes2 ) +{ + if( m_lpDSStream->Unlock( lpvPtr1, dwBytes1, lpvPtr2, dwBytes2 ) == DS_OK ) + return TRUE; + return FALSE; +} + +BOOL CDirectSound::LoadEsf( LPCSTR szFileName, INT no ) +{ + if( no < 0 || no > ESF_FILE_MAX-1 ) + return FALSE; + + if( m_EsfWaveFile[no].Load( szFileName ) ) { + return CreateESFBuffer( no, m_EsfWaveFile[no].GetFormat(), m_EsfWaveFile[no].GetData(), m_EsfWaveFile[no].GetSize() ); + } else { +DEBUGOUT( "CDirectSound::LoadEsf error. [%s]\n", szFileName ); + } + + return FALSE; +} + +BOOL CDirectSound::EsfPlay( INT no ) +{ + if( !m_lpDS ) + return FALSE; + + if( !m_pEsfDSBuffer[no] ) + return FALSE; + + m_pEsfDSBuffer[no]->SetCurrentPosition( 0 ); + if( m_pEsfDSBuffer[no]->Play( 0, 0, 0 ) == DSERR_BUFFERLOST ) { + if( m_pEsfDSBuffer[no]->Restore() == DS_OK ) { + CreateESFBuffer( no, m_EsfWaveFile[no].GetFormat(), m_EsfWaveFile[no].GetData(), m_EsfWaveFile[no].GetSize() ); + m_pEsfDSBuffer[no]->Play( 0, 0, 0 ); + } + } + + return TRUE; +} + +BOOL CDirectSound::EsfPlayLoop( INT no ) +{ + if( !m_lpDS ) + return FALSE; + + if( !m_pEsfDSBuffer[no] ) + return FALSE; + + // ɍĐH + DWORD dwStatus; + if( m_pEsfDSBuffer[no]->GetStatus( &dwStatus ) == DS_OK ) { + if( dwStatus == DSBSTATUS_PLAYING ) { + return TRUE; + } + } + + m_pEsfDSBuffer[no]->SetCurrentPosition( 0 ); + if( m_pEsfDSBuffer[no]->Play( 0, 0, DSBPLAY_LOOPING ) == DSERR_BUFFERLOST ) { + if( m_pEsfDSBuffer[no]->Restore() == DS_OK ) { + CreateESFBuffer( no, m_EsfWaveFile[no].GetFormat(), m_EsfWaveFile[no].GetData(), m_EsfWaveFile[no].GetSize() ); + m_pEsfDSBuffer[no]->Play( 0, 0, DSBPLAY_LOOPING ); + } + } + + return TRUE; +} + +BOOL CDirectSound::EsfStop( INT no ) +{ + if( !m_lpDS ) + return FALSE; + + if( !m_pEsfDSBuffer[no] ) + return FALSE; + + m_pEsfDSBuffer[no]->Stop(); + m_pEsfDSBuffer[no]->SetCurrentPosition( 0 ); + + return TRUE; +} + +void CDirectSound::EsfAllStop() +{ + if( !m_lpDS ) + return; + + for( INT i = 0; i < ESF_FILE_MAX; i++ ) { + EsfStop( i ); + } +} + +BOOL CDirectSound::CreateESFBuffer( INT no, WAVEFORMATEX* pwfex, LPVOID pData, DWORD dwSize ) +{ +DSBUFFERDESC dsbdesc; +LPVOID lpPtr0, lpPtr1; +DWORD dwBytes0, dwBytes1; + + // ɎgĂJĂ + if( m_pEsfDSBuffer[no] ) { + RELEASE( m_pEsfDSBuffer[no] ); + } + + // DirectSound ZJ_obt@쐬 + ZEROMEMORY( &dsbdesc, sizeof(DSBUFFERDESC) ); + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE; + dsbdesc.dwBufferBytes = dwSize; + dsbdesc.lpwfxFormat = pwfex; + + if( m_lpDS->CreateSoundBuffer( &dsbdesc, &m_pEsfDSBuffer[no], NULL ) != DS_OK ) { + m_pEsfDSBuffer[no] = NULL; + return FALSE; + } + + // 쐬ZJ_obt@ɃEF[uf[^Rs[ + m_pEsfDSBuffer[no]->Lock( 0L, dwSize, &lpPtr0, &dwBytes0, &lpPtr1, &dwBytes1, 0 ); + ::CopyMemory( lpPtr0, pData, dwBytes0 ); + if( dwBytes1 ) { + ::CopyMemory( lpPtr1, (LPBYTE)pData + dwBytes1, dwBytes1 ); + } + m_pEsfDSBuffer[no]->Unlock( &lpPtr0, dwBytes0, &lpPtr1, dwBytes1 ); + + return TRUE; +} + +void CDirectSound::ReleaseEsfBuffer() +{ + EsfAllStop(); + + for( INT i = 0; i < ESF_FILE_MAX; i++ ) { + RELEASE( m_pEsfDSBuffer[i] ); + m_EsfWaveFile[i].Free(); + } +} + diff --git a/References/VirtuaNESex_src_191105/DirectSound.h b/References/VirtuaNESex_src_191105/DirectSound.h new file mode 100644 index 00000000..f66d8d2c --- /dev/null +++ b/References/VirtuaNESex_src_191105/DirectSound.h @@ -0,0 +1,123 @@ +// +// DirectSound class +// +#ifndef __DIRECTSOUND_INCLUDED__ +#define __DIRECTSOUND_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define DIRECTSOUND_VERSION 0x0700 +#include + +#include "extsoundfile.h" + +#include "typedef.h" +#include "macro.h" + +class CWaveData +{ +public: + CWaveData(); + virtual ~CWaveData(); + + BOOL Load( LPCSTR szFileName ); + void Free(); + + DWORD GetSize(); + WAVEFORMATEX* GetFormat(); + LPVOID GetData(); +protected: + LPVOID m_pBuffer; + + WAVEFORMATEX* m_pwfex; + DWORD m_dwSize; + + LPVOID m_pData; + +private: +}; + +class CDirectSound +{ +public: + // pubNoϐ + typedef struct tagSAMPLERATE { + DWORD Rate; + DWORD Bits; + } SAMPLERATE, *LPSAMPLERATE; + + SAMPLERATE m_SampleRate; // ݃TvO[g + INT m_BufferSize; // obt@TCY(t[) + static SAMPLERATE m_SampleRateTable[]; // TvO[ge[u + static INT m_BufferSizeTable[]; // obt@TCYe[u + + // pubNo֐ + CDirectSound(); + virtual ~CDirectSound(); + + BOOL InitialDSound( HWND hWnd ); + void ReleaseDSound(); + + BOOL InitialBuffer(); + void ReleaseBuffer(); + + BOOL SetSamplingRate( DWORD rate, DWORD bits ); + void GetSamplingRate( DWORD& rate, DWORD& bits ); + + void SetBufferSize( INT nSize ) { m_BufferSize = nSize; } + INT GetBufferSize() { return m_BufferSize; } + + BOOL IsStreamPlaying() { return (m_bStreamPlay&&!m_bStreamPause); } + void StreamPlay(); + void StreamStop(); + void StreamPause(); + void StreamResume(); + + BOOL GetStreamLockPosition( LPDWORD lpdwStart, LPDWORD lpdwSize ); + BOOL StreamLock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID* lplpvPtr1, LPDWORD lpdwBytes1, LPVOID* lplpvPtr2, LPDWORD lpdwBytes2, DWORD dwFlags ); + BOOL StreamUnlock( LPVOID lpvPtr1, DWORD dwBytes1, LPVOID lpvPtr2, DWORD dwBytes2 ); + + BOOL IsStreamPlay() { return m_bStreamPlay; } + BOOL IsStreamPause() { return m_bStreamPause; } + + // Ot@CΉ + BOOL LoadEsf( LPCSTR szFileName, INT no ); + BOOL EsfPlay( INT no ); + BOOL EsfPlayLoop( INT no ); + BOOL EsfStop( INT no ); + void EsfAllStop(); + BOOL CreateESFBuffer( INT no, WAVEFORMATEX* pwfex, LPVOID pData, DWORD dwSize ); + void ReleaseEsfBuffer(); + +protected: + // veNgoϐ + HWND m_hWnd; // Window handle + + LPDIRECTSOUND m_lpDS; // DirectSoundIuWFNg + LPDIRECTSOUNDBUFFER m_lpDSPrimary; // vC}IuWFNg + + LPDIRECTSOUNDBUFFER m_lpDSStream; // Xg[~OIuWFNg + + DWORD m_dwDSBufferSize; + DWORD m_dwDSBlockSize; // 1ubÑTCY + DWORD m_dwDSBlockNum; // ubN̐ + DWORD m_dwDSLastBlock; // Ōɏ񂾃ubNʒu + + volatile BOOL m_bStreamPlay; // Xg[ĐtO + volatile BOOL m_bStreamPause; // Xg[|[YtO + + // Ot@CΉ + CWaveData m_EsfWaveFile[ ESF_FILE_MAX ]; + LPDIRECTSOUNDBUFFER m_pEsfDSBuffer[ ESF_FILE_MAX ]; + + // veNgo֐ +private: + // vCx[goϐ + // vCx[go֐ +}; + +extern CDirectSound DirectSound; + +#endif // !__DIRECTSOUND_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/Disksys.rom b/References/VirtuaNESex_src_191105/Disksys.rom new file mode 100644 index 00000000..93a8d933 Binary files /dev/null and b/References/VirtuaNESex_src_191105/Disksys.rom differ diff --git a/References/VirtuaNESex_src_191105/Doc/Chinese.vlp b/References/VirtuaNESex_src_191105/Doc/Chinese.vlp new file mode 100644 index 00000000..34d05cdc Binary files /dev/null and b/References/VirtuaNESex_src_191105/Doc/Chinese.vlp differ diff --git a/References/VirtuaNESex_src_191105/Doc/Chinese.vlp.bak b/References/VirtuaNESex_src_191105/Doc/Chinese.vlp.bak new file mode 100644 index 00000000..d2e1547c Binary files /dev/null and b/References/VirtuaNESex_src_191105/Doc/Chinese.vlp.bak differ diff --git a/References/VirtuaNESex_src_191105/Doc/Copying.txt b/References/VirtuaNESex_src_191105/Doc/Copying.txt new file mode 100644 index 00000000..fb06a424 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Doc/Copying.txt @@ -0,0 +1,281 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/References/VirtuaNESex_src_191105/Doc/Readme.txt b/References/VirtuaNESex_src_191105/Doc/Readme.txt new file mode 100644 index 00000000..da4f2a81 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Doc/Readme.txt @@ -0,0 +1,33 @@ +2019-11-05 Ҷ: + οbyemugoogle codeйܵVirtuaNES plusĿIntroROMʹ7zѹ7z֧֡ + + 1ģĬϵɫΪMesenɫ壻 + 2 Mapper192Mapper195֧֣ + 3 Mapper194 + 4֧7zѹļ + 5ڶԻļʱ估빱ߣ + + +2019-10-30 Ҷ: + 1ֳ֧(1MB)nsfļţ: [Subor]Karaoke(C).nsf + +2019-10-26 ҶĂl֪: + 1ļеļ׺ʾӢĸΪġ + 2ļепļӺ׺ʾ + 3ļ.unf׺ + 4˵Ĵ->ʹù·ĴҲ3㡣 + 5ּ̨֧.unfļ + 6еİ汾0.85Ϊ0.86 + 7ļʱҲ·ʱʾ"޷a"Ϊ"޷" + 8ģʱԶļ,ļ·VirtuaNESex.iniRomAutoRunPathá + 9޷NSFļ(Ͽ,¹ر) + +2015-09-03 : +֧·ĸߴ + +2014-01-30 : +ܾûд־ˣǾӵĶˣҪ˵˵ɡ +1ϾƼġ21ûmapperֱӸmapper198棻 +2mapper168СһRomлTPUϴİæCRC HackķʽСġOKRomҲӵ棬Ϊͼʽһmapperˣ +3mapper169ԣѧϰRomƵģӣĿǰ֧֪ԣV8.0V8.2V8.3V9.0V9.2汾ѧϰRomRomļԵַء(http://hi.baidu.com/yxleimeng/item/bdfb2f9fe08118d81a49df47)뽫Rommapper޸ij169 +4ӽ̼İ̡̺ϼ̡ʹЩ̵Romδģڴ. \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/Doc/ReadmeSrc.txt b/References/VirtuaNESex_src_191105/Doc/ReadmeSrc.txt new file mode 100644 index 00000000..816f0b57 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Doc/ReadmeSrc.txt @@ -0,0 +1,5 @@ + +<\[XXgɕt> + +GNU Public License Version 2ɏ]ĉB(Copying.txtQƁBpł) + diff --git a/References/VirtuaNESex_src_191105/Doc/VirtuaNESex.txt b/References/VirtuaNESex_src_191105/Doc/VirtuaNESex.txt new file mode 100644 index 00000000..554ad744 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Doc/VirtuaNESex.txt @@ -0,0 +1,40 @@ +VirtuaNES 0.86a mapper extension +================================ + +Support mappers: +================ +mapper 27: + WorldHero +mapper 163:NanJing's game + Paladin(C) + Harvest_Moon(C) +mapper 164:Union-bond's game + Digital_dragon(C) + sanguo2(C) + Final Fantasy V(C) + Pocket Monster Gold(C) + ... +mapper 165: + Fire Emblem (Chinese version) +mapper 167:Subor Computer serias(PAL mode) + Subor Computer V1.0 (Russian) + Subor Computer V2.0 (Chinese) + Subor Computer V4.0 (Chinese) + Subor English (Chinese) + +Support Controller: +=================== +Subor Computer Keyboard: +Use by Subor Computer and EDU(C) + +Fixed: +====== +PAL timing: + Total scanlines : 313 + Vblank start lines: 291 + +Others: +======= +This extension is made by tpu(tpunix [AT] 126.com). +You can find the new roms at (http://www.romchina.com). +Enjoy it! \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/EmuThread.cpp b/References/VirtuaNESex_src_191105/EmuThread.cpp new file mode 100644 index 00000000..b944a4b7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/EmuThread.cpp @@ -0,0 +1,1129 @@ +// +// G~[^XbhNX +// +#include "DebugOut.h" + +#include "VirtuaNESres.h" +#include "EmuThread.h" +#include "MainFrame.h" +#include "Pathlib.h" + +#include "NetPlay.h" + +#include "DirectDraw.h" +#include "DirectSound.h" +#include "DirectInput.h" + +// g +CEmuThread Emu; + +// This|C^ +CEmuThread* CEmuThread::g_pThis = NULL; +// EChEnh +HWND CEmuThread::g_hWnd = NULL; +// G~[^IuWFNg|C^ +NES* CEmuThread::g_nes = NULL; +// WAVER[_ +CWaveRec CEmuThread::g_WaveRec; + +// NetEvent Queue +deque CEmuThread::NetEventQueue; +string CEmuThread::strNetStateName; + +// Xe[^X +INT CEmuThread::g_Status = CEmuThread::STATUS_NONE; +// XbhCxgƃCxgnh +INT CEmuThread::g_Event = CEmuThread::EV_NONE; +LONG CEmuThread::g_EventParam = 0; +LONG CEmuThread::g_EventParam2 = 0; +HANDLE CEmuThread::g_hEvent = NULL; +HANDLE CEmuThread::g_hEventAccept = NULL; + +// G[bZ[W +CHAR CEmuThread::g_szErrorMessage[512]; + +// XgOe[u +LPCSTR CEmuThread::g_lpSoundMuteStringTable[] = { + "Master ", + "Rectangle 1", + "Rectangle 2", + "Triangle ", + "Noise ", + "DPCM ", + "Ex CH1 ", + "Ex CH2 ", + "Ex CH3 ", + "Ex CH4 ", + "Ex CH5 ", + "Ex CH6 ", + "Ex CH7 ", + "Ex CH8 ", + NULL, + NULL, +}; + +// XbhvCIeBe[u +INT CEmuThread::g_PriorityTable[] = { + THREAD_PRIORITY_IDLE, + THREAD_PRIORITY_LOWEST, + THREAD_PRIORITY_BELOW_NORMAL, + THREAD_PRIORITY_NORMAL, + THREAD_PRIORITY_ABOVE_NORMAL, + THREAD_PRIORITY_HIGHEST, + THREAD_PRIORITY_TIME_CRITICAL +}; + +CEmuThread::CEmuThread() +{ + g_pThis = this; + + m_hThread = NULL; + g_Status = STATUS_NONE; + m_nPriority = 3; // Normal + g_nes = NULL; + m_nPauseCount = 0; +} + +CEmuThread::~CEmuThread() +{ + Stop(); +} + +void CEmuThread::SetPriority( INT nPriority ) +{ + m_nPriority = nPriority; + if( IsRunning() ) { + ::SetThreadPriority( m_hThread, g_PriorityTable[m_nPriority] ); + } +} + +BOOL CEmuThread::Start( HWND hWnd, NES* nes ) +{ + Stop(); + + if( !g_hEvent ) { + if( !(g_hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL )) ) { + DEBUGOUT( "CreateEvent failed.\n" ); + goto _Start_Failed; + } + } + if( !g_hEventAccept ) { + if( !(g_hEventAccept = ::CreateEvent( NULL, FALSE, FALSE, NULL )) ) { + DEBUGOUT( "CreateEvent failed.\n" ); + goto _Start_Failed; + } + } + + ::ResetEvent( g_hEvent ); + ::ResetEvent( g_hEventAccept ); + + g_hWnd = hWnd; + g_nes = nes; + g_Event = EV_INITIAL; + g_Status = STATUS_NONE; + ::SetEvent( g_hEvent ); + m_nPauseCount = 0; + + if( !(m_hThread = ::CreateThread( NULL, 0, ThreadProc, 0, 0, &m_dwThreadID )) ) { + DEBUGOUT( "CreateThread failed.\n" ); + goto _Start_Failed; + } + + // XbhvCIeB̐ݒ + ::SetThreadPriority( m_hThread, g_PriorityTable[m_nPriority] ); + + // ƋNłmF̈׃Cxg҂ + ::WaitForSingleObject( g_hEventAccept, INFINITE ); + g_Status = STATUS_RUN; + +// DEBUGOUT( "CEmuThread:Start() Thread started.\n" ); + return TRUE; + +_Start_Failed: + CLOSEHANDLE( g_hEvent ); + CLOSEHANDLE( g_hEventAccept ); + + DEBUGOUT( "CEmuThread:Start() Thread startup failed!!." ); + return FALSE; +} + +void CEmuThread::Stop() +{ + if( IsRunning() ) { + ::ResetEvent( g_hEventAccept ); + + g_Event = EV_EXIT; + ::SetEvent( g_hEvent ); + + ::WaitForSingleObject( m_hThread, INFINITE ); + CLOSEHANDLE( m_hThread ); + m_hThread = NULL; + g_Status = STATUS_NONE; + + CLOSEHANDLE( g_hEvent ); + CLOSEHANDLE( g_hEventAccept ); + + // lbgvC̐ؒf + NetPlay.Disconnect(); + +// DEBUGOUT( "CEmuThread::Stop() Thread stoped.\n" ); + } +} + +void CEmuThread::Pause() +{ + if( IsRunning() ) { + if( !IsPausing() ) { + ::ResetEvent( g_hEventAccept ); + g_Event = EV_PAUSE; + ::SetEvent( g_hEvent ); + ::WaitForSingleObject( g_hEventAccept, INFINITE ); + g_Status = STATUS_PAUSE; + m_nPauseCount++; + } else { + m_nPauseCount++; + } +// DEBUGOUT( "CEmuThread::Pause() Thread paused. Count=%d\n", m_nPauseCount ); + } +} + +void CEmuThread::Resume() +{ + if( IsRunning() ) { + if( IsPausing() ) { + if( --m_nPauseCount <= 0 ) { + m_nPauseCount = 0; + ::ResetEvent( g_hEventAccept ); + g_Event = EV_RESUME; + ::SetEvent( g_hEvent ); + ::WaitForSingleObject( g_hEventAccept, INFINITE ); + g_Status = STATUS_RUN; + } + } +// DEBUGOUT( "CEmuThread::Resume() Thread resumed. Count=%d\n", m_nPauseCount ); + } +} + +void CEmuThread::Event( EMUEVENT ev ) +{ + if( IsRunning() ) { + ::ResetEvent( g_hEventAccept ); + g_Event = ev; + g_EventParam = 0; + g_EventParam2 = -1; + ::SetEvent( g_hEvent ); + ::WaitForSingleObject( g_hEventAccept, INFINITE ); + } +} + +void CEmuThread::EventParam( EMUEVENT ev, LONG param ) +{ + if( IsRunning() ) { + ::ResetEvent( g_hEventAccept ); + g_Event = ev; + g_EventParam = param; + g_EventParam2 = -1; + ::SetEvent( g_hEvent ); + ::WaitForSingleObject( g_hEventAccept, INFINITE ); + } +} + +void CEmuThread::EventParam2( EMUEVENT ev, LONG param, LONG param2 ) +{ + if( IsRunning() ) { + ::ResetEvent( g_hEventAccept ); + g_Event = ev; + g_EventParam = param; + g_EventParam2 = param2; + ::SetEvent( g_hEvent ); + ::WaitForSingleObject( g_hEventAccept, INFINITE ); + } +} + +void CEmuThread::DiskCommand( BYTE cmd ) +{ + switch( cmd ) { + case 0: // Eject + if( g_nes->rom->GetDiskNo() > 0 ) { + g_nes->Command( NES::NESCMD_DISK_EJECT ); + DirectDraw.SetMessageString( "Disk Eject." ); + } + break; + case 1: // Disk0 SideA + if( g_nes->rom->GetDiskNo() > 0 ) { + g_nes->Command( NES::NESCMD_DISK_0A ); + DirectDraw.SetMessageString( "Change Disk1 SideA." ); + } + break; + case 2: // Disk0 SideB + if( g_nes->rom->GetDiskNo() > 1 ) { + g_nes->Command( NES::NESCMD_DISK_0B ); + DirectDraw.SetMessageString( "Change Disk1 SideB." ); + } + break; + case 3: // Disk1 SideA + if( g_nes->rom->GetDiskNo() > 2 ) { + g_nes->Command( NES::NESCMD_DISK_1A ); + DirectDraw.SetMessageString( "Change Disk2 SideA." ); + } + break; + case 4: // Disk1 SideB + if( g_nes->rom->GetDiskNo() > 3 ) { + g_nes->Command( NES::NESCMD_DISK_1B ); + DirectDraw.SetMessageString( "Change Disk2 SideB." ); + } + break; + } +} + +BOOL CEmuThread::FrameInput() +{ +static CHAR szMes[256]; + + DirectInput.Poll(); + if( DirectDraw.GetZapperMode() ) { + LONG x, y; + DirectDraw.GetZapperPos( x, y ); + if( g_nes ) { + g_nes->SetZapperPos( x, y ); + } + } + g_nes->pad->Sync(); + + if( !NetPlay.IsConnect() ) { + g_nes->Movie(); + } else { + DWORD paddata = g_nes->pad->GetSyncData(); + BYTE player1[CNetPlay::SOCKET_BLOCK_SIZE], player2[CNetPlay::SOCKET_BLOCK_SIZE]; + + player1[0] = player1[1] = player1[2] = player1[3] = 0; + if( !NetEventQueue.empty() ) { + NETEV& ev = NetEventQueue.front(); + + switch( ev.Event ) { + case EV_HWRESET: + player1[0] = 0x80; + break; + case EV_SWRESET: + player1[0] = 0x81; + break; + case EV_DISK_COMMAND: + player1[0] = 0x88; + player1[1] = (BYTE)ev.Param; + break; + case EV_STATE_LOAD: + player1[0] = 0xF0; + break; + case EV_STATE_SAVE: + player1[0] = 0xF1; + break; + default: + break; + } + } + + player1[4] = (BYTE) paddata; + player1[5] = (BYTE)(paddata>>8); + player1[6] = (BYTE)(paddata>>16); + player1[7] = (BYTE)(paddata>>24); + + INT ret = NetPlay.ModifyPlayer( player1, player2 ); + + if( ret < 0 ) { + // Network Error + NetPlay.Disconnect(); + return FALSE; + } else if( ret == 0 ) { + // Queue͑̕M̂FIFO菜 + if( !NetEventQueue.empty() ) { + NetEventQueue.pop_front(); + } + + // Command check(P1D) + BYTE event = 0; + BYTE param = 0; + if( player1[0] ) { + event = player1[0]; + param = player1[1]; + } else if( player2[0] ) { + event = player2[0]; + param = player2[1]; + } + switch( event ) { + case 0x80: + g_nes->Command( NES::NESCMD_HWRESET ); + DirectDraw.SetMessageString( "Hardware reset." ); + break; + case 0x81: + g_nes->Command( NES::NESCMD_SWRESET ); + DirectDraw.SetMessageString( "Software reset." ); + break; + case 0x88: + DiskCommand( param ); + break; + case 0xF0: + if( g_nes->LoadState( strNetStateName.c_str() ) ) { + ::wsprintf( szMes, "Net State Load." ); + DirectDraw.SetMessageString( szMes ); + } + break; + case 0xF1: + if( g_nes->SaveState( strNetStateName.c_str() ) ) { + ::wsprintf( szMes, "Net State Save." ); + DirectDraw.SetMessageString( szMes ); + } + break; + default: + break; + } + } + + LPBYTE p1, p2; + if( NetPlay.IsServer() ) { + p1 = player1; + p2 = player2; + } else { + p1 = player2; + p2 = player1; + } +//DEBUGOUT( "P1:%02X P2:%02X P3:%02X P4:%02X\n", player1[4], player2[4], player1[5], player2[5] ); + g_nes->pad->SetSyncData( ((DWORD)p1[4])|((DWORD)p2[4]<<8)|((DWORD)p1[5]<<16)|((DWORD)p2[5]<<24) ); + } + + return TRUE; +} + +DWORD WINAPI CEmuThread::ThreadProc( LPVOID lpParam ) +{ +INT i; +INT Ev; +LONG Param, Param2; +BOOL bLoop = TRUE; +BOOL bPause = FALSE; // Thread pause +BOOL bEmuPause = FALSE; // Emulation pause +BOOL bThrottle = FALSE; // Emulation throttle +INT nFrameSkip = 0; // Emulation frameskip +BOOL bOneStep = FALSE; // Emulation one step +BOOL bSleep = FALSE; // Sleep use + +INT frameskipno; +double frame_time = 0.0f; +double frame_period; +DWORD start_time, current_time, now_time; +LONG sleep_time; + +// FPS +INT nFrameCount = 0; +DWORD dwFrameTime[32]; +DWORD FPS = 0; + +// Str +CHAR szStr[256]; + +// Netplay +NETEV netev; +INT nNetTimeoutCount = 0; + + while( bLoop ) { + try { + bOneStep = FALSE; + + Ev = EV_NONE; + if( WAIT_OBJECT_0 == ::WaitForSingleObject(g_hEvent,0) ) { + Ev = g_Event; + Param = g_EventParam; + Param2 = g_EventParam2; + } + + switch( Ev ) { + case EV_NONE: + break; + case EV_INITIAL: + DirectDraw.SetMessageString( "Emulation start." ); + DirectSound.StreamPlay(); + frame_time = 0.0f; + start_time = ::timeGetTime(); + if( g_nes ) { + g_nes->ppu->SetScreenPtr( DirectDraw.GetRenderScreen(), DirectDraw.GetLineColormode() ); + } + ::SetEvent( g_hEventAccept ); + break; + case EV_EXIT: + DirectSound.StreamStop(); + g_WaveRec.Stop(); + bLoop = FALSE; + return 0; + case EV_PAUSE: + DirectSound.StreamPause(); + bPause = TRUE; + ::SetEvent( g_hEventAccept ); + break; + case EV_RESUME: + if( !bEmuPause ) + DirectSound.StreamResume(); + frame_time = 0.0f; + start_time = ::timeGetTime(); + bPause = FALSE; + ::SetEvent( g_hEventAccept ); + break; + case EV_FULLSCREEN_GDI: + DirectDraw.SetFullScreenGDI( (BOOL)Param ); + ::SetEvent( g_hEventAccept ); + break; + + case EV_HWRESET: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( !g_nes->IsMoviePlay() ) { + g_nes->Command( NES::NESCMD_HWRESET ); + DirectDraw.SetMessageString( "Hardware reset." ); + } + } else { + netev.Event = EV_HWRESET; + netev.Param = 0; + NetEventQueue.push_back( netev ); + } + } + ::SetEvent( g_hEventAccept ); + break; + case EV_SWRESET: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( !g_nes->IsMoviePlay() ) { + g_nes->Command( NES::NESCMD_SWRESET ); + DirectDraw.SetMessageString( "Software reset." ); + } + } else { + netev.Event = EV_SWRESET; + netev.Param = 0; + NetEventQueue.push_back( netev ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_NETPLAY_START: + if( g_nes ) { + // ꉞ + g_nes->MovieStop(); + + string pathstr; + if( Config.path.bStatePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szStatePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + DEBUGOUT( "Path: %s\n", pathstr.c_str() ); + } else { + pathstr = g_nes->rom->GetRomPath(); + } + strNetStateName = CPathlib::MakePathExt( pathstr.c_str(), g_nes->rom->GetRomName(), "stn" ); + DEBUGOUT( "NetState Path: %s\n", strNetStateName.c_str() ); + + g_nes->Command( NES::NESCMD_HWRESET ); + DirectDraw.SetMessageString( "Netplay start!" ); + } + bThrottle = FALSE; + + // QueueNA + NetEventQueue.clear(); + // ŏSync + NetPlay.Sync(); + + ::SetEvent( g_hEventAccept ); + break; + + case EV_EMUPAUSE: + if( !NetPlay.IsConnect() ) { + bEmuPause = !bEmuPause; + if( bEmuPause ) { + DirectSound.StreamPause(); + } else if( !bPause ) { + DirectSound.StreamResume(); + } + DirectDraw.SetMessageString( "Pause." ); + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_ONEFRAME: + if( !NetPlay.IsConnect() ) { + bEmuPause = TRUE; + DirectSound.StreamPause(); + bOneStep = TRUE; + DirectDraw.SetMessageString( "One Frame." ); + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_THROTTLE: + if( !NetPlay.IsConnect() ) { + bThrottle = !bThrottle; + if( bThrottle ) { + DirectDraw.SetMessageString( "Throttle ON." ); + } else { + DirectDraw.SetMessageString( "Throttle OFF." ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_FRAMESKIP_AUTO: + if( !NetPlay.IsConnect() ) { + DirectDraw.SetMessageString( "FrameSkip Auto." ); + nFrameSkip = 0; + } + ::SetEvent( g_hEventAccept ); + break; + case EV_FRAMESKIP_UP: + if( !NetPlay.IsConnect() ) { + if( nFrameSkip < 20 ) + nFrameSkip++; + ::wsprintf( szStr, "FrameSkip %d", nFrameSkip ); + DirectDraw.SetMessageString( szStr ); + } + ::SetEvent( g_hEventAccept ); + break; + case EV_FRAMESKIP_DOWN: + if( !NetPlay.IsConnect() ) { + if( nFrameSkip ) + nFrameSkip--; + if( nFrameSkip ) { + ::wsprintf( szStr, "FrameSkip %d", nFrameSkip ); + DirectDraw.SetMessageString( szStr ); + } else { + DirectDraw.SetMessageString( "FrameSkip Auto." ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_STATE_LOAD: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->LoadState( (const char*)Param ) ) { + if( Param2 < 0 ) + ::wsprintf( szStr, "State Load." ); + else + ::wsprintf( szStr, "State Load #%d", Param2 ); + DirectDraw.SetMessageString( szStr ); + } + } else { + netev.Event = EV_STATE_LOAD; + netev.Param = 0; + NetEventQueue.push_back( netev ); + } + } + ::SetEvent( g_hEventAccept ); + break; + case EV_STATE_SAVE: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->SaveState( (const char*)Param ) ) { + if( Param2 < 0 ) + ::wsprintf( szStr, "State Save." ); + else + ::wsprintf( szStr, "State Save #%d", Param2 ); + DirectDraw.SetMessageString( szStr ); + } + } else { + netev.Event = EV_STATE_SAVE; + netev.Param = 0; + NetEventQueue.push_back( netev ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_DISK_COMMAND: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + DiskCommand( Param ); + } else { + netev.Event = EV_DISK_COMMAND; + netev.Param = Param; + NetEventQueue.push_back( netev ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_EXCONTROLLER: + if( g_nes ) + g_nes->CommandParam( NES::NESCMD_EXCONTROLLER, Param ); + ::SetEvent( g_hEventAccept ); + break; + + case EV_SOUND_MUTE: + { + if( g_nes ) + if( g_nes->CommandParam( NES::NESCMD_SOUND_MUTE, Param ) ) { + ::wsprintf( szStr, "%s Enable.", g_lpSoundMuteStringTable[Param] ); + } else { + ::wsprintf( szStr, "%s Mute.", g_lpSoundMuteStringTable[Param] ); + } + DirectDraw.SetMessageString( szStr ); + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_MOVIE_PLAY: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->MoviePlay( (const char*)Param ) ) { + DirectDraw.SetMessageString( "Movie replay." ); + } + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_MOVIE_REC: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->MovieRec( (const char*)Param ) ) { + DirectDraw.SetMessageString( "Movie record." ); + } + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_MOVIE_RECAPPEND: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->MovieRecAppend( (const char*)Param ) ) { + DirectDraw.SetMessageString( "Movie append record." ); + } + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_MOVIE_STOP: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + g_nes->MovieStop(); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_SNAPSHOT: + if( g_nes ) { + if( g_nes->Snapshot() ) { + DirectDraw.SetMessageString( "Snap shot." ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_WAVEREC_START: + if( g_nes ) { + DWORD nRate, nBits; + DirectSound.GetSamplingRate( nRate, nBits ); + g_WaveRec.Start( (LPSTR)Param, nRate, nBits, FALSE ); + } + DirectDraw.SetMessageString( "Wave recording start." ); + ::SetEvent( g_hEventAccept ); + break; + + case EV_WAVEREC_STOP: + if( g_nes ) { + g_WaveRec.Stop(); + DirectDraw.SetMessageString( "Wave recording stop." ); + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_TAPE_PLAY: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->TapePlay( (const char*)Param ) ) { + DirectDraw.SetMessageString( "Tape play." ); + } + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_TAPE_REC: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + if( g_nes->TapeRec( (const char*)Param ) ) { + DirectDraw.SetMessageString( "Tape record." ); + } + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_TAPE_STOP: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + g_nes->TapeStop(); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_BARCODE: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + g_nes->SetBarcodeData( (LPBYTE)Param, (INT)Param2 ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_TURBOFILE: + if( g_nes ) { + if( !NetPlay.IsConnect() ) { + g_nes->SetTurboFileBank( (INT)Param ); + } + } + ::SetEvent( g_hEventAccept ); + break; + + case EV_MESSAGE_OUT: + DirectDraw.SetMessageString( (LPSTR)Param ); + ::SetEvent( g_hEventAccept ); + break; + + default: + DEBUGOUT( "ThreadProc:Unknown event.\n" ); + ::SetEvent( g_hEventAccept ); + break; + } + } catch( CHAR* str ) { + bPause = TRUE; + ::strcpy( g_szErrorMessage, str ); + ::PostMessage( g_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)g_szErrorMessage ); + ::SetEvent( g_hEventAccept ); +#ifndef _DEBUG + } catch(...) { + bPause = TRUE; + ::PostMessage( g_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)CApp::GetErrorString( IDS_ERROR_UNKNOWN ) ); + ::SetEvent( g_hEventAccept ); +#endif + } + + if( bPause ) { + // Cxg̈ + DirectInput.Poll(); + + // c + CMainFrame::OnKeyControl(); + + // Ă΂ȂWindowsdȂ̂(NTnȊO͓) + ::Sleep( 20 ); + } else { + try { + INT nNetBuffer = 0; + BOOL bNoFrame = FALSE; + BOOL bAddFrame = FALSE; + + bSleep = TRUE; + + if( !NetPlay.IsConnect() ) { + // ʏ + BOOL bKeyThrottle = FALSE; + // L[`FbN + { + BYTE* pKey = (BYTE*)DirectInput.m_Sw; + WORD* pShortCutKey = Config.shortcut.nShortCut; + INT* pShortCutKeyID = Config.ShortcutKeyID; + for( INT i = 0; pShortCutKeyID[i*3+0]; i++ ) { + if( pShortCutKeyID[i*3+0] == ID_KEYTHROTTLE ) { + if( (pKey[pShortCutKey[pShortCutKeyID[i*3+2] ]] & 0x80) && pShortCutKey[pShortCutKeyID[i*3+2] ] + || (pKey[pShortCutKey[pShortCutKeyID[i*3+2]+128]] & 0x80) && pShortCutKey[pShortCutKeyID[i*3+2]+128] ) { + bKeyThrottle = TRUE; + } + break; + } + } + } + + if( Config.general.bScreenMode ) { + // FullScreen +// if( Config.graphics.bSyncDraw ) { + if( Config.graphics.bSyncDraw && Config.graphics.bSyncNoSleep ) { + bSleep = FALSE; + } else if( Config.emulator.bAutoFrameSkip ) { + bSleep = TRUE; + } else { + bSleep = FALSE; + } + } else { + // Window +// if( Config.graphics.bWindowVSync ) { + if( Config.graphics.bWindowVSync && Config.graphics.bSyncNoSleep ) { + bSleep = FALSE; + } else if( Config.emulator.bAutoFrameSkip ) { + bSleep = TRUE; + } else { + bSleep = FALSE; + } + } + + frame_period = 1000.0/g_nes->nescfg->FrameRate; + + // t[XLbv̌vZ + current_time = ::timeGetTime(); + now_time = current_time - start_time; + + if( Config.emulator.bAutoFrameSkip && bSleep ) { + if( g_nes->IsDiskThrottle() ) { + frame_period = g_nes->nescfg->FramePeriod/10.0f; + } else if( !nFrameSkip ) { + // Auto + double fps = 0.0; + if( (bThrottle||bKeyThrottle) ) { + fps = (double)Config.emulator.nThrottleFPS; + } else { + fps = g_nes->nescfg->FrameRate; + } + if( fps < 0.0 ) fps = 60.0; + if( fps > 600.0 ) fps = 600.0; + frame_period = 1000.0/fps; + } else { + frame_period = (1000.0/g_nes->nescfg->FrameRate)/(nFrameSkip+1); + } + + if( !nFrameSkip && !g_nes->IsDiskThrottle() ) { + frameskipno = (INT)(((double)now_time-frame_time) / frame_period); + if( frameskipno < 0 || frameskipno > 20 ) { + frameskipno = 1; + frame_time = 0.0; + start_time = ::timeGetTime(); + } + } else if( g_nes->IsDiskThrottle() ) { + frameskipno = 10; + frame_time = 0.0; + start_time = ::timeGetTime(); + } else { + if( nFrameSkip < 0 ) + frameskipno = 1; + else + frameskipno = nFrameSkip+1; + } + } else { + if( g_nes->IsDiskThrottle() ) { + frameskipno = 10; + } + if( bThrottle||bKeyThrottle ) { + frameskipno = (INT)(((double)Config.emulator.nThrottleFPS+30)/60.0); + } else { + // I[gOVSYNC̎ɂt[XLbvׂ̑[u + if( nFrameSkip < 0 ) { + frameskipno = 1; + } else { + frameskipno = nFrameSkip+1; + } + } + } + } else { + bSleep = TRUE; + + // lbgvC̓t[XLbvs + frame_period = 1000.0/g_nes->nescfg->FrameRate; + + // t[XLbv̌vZ + current_time = ::timeGetTime(); + now_time = current_time - start_time; + + frameskipno = (INT)(((double)now_time-frame_time) / frame_period); + if( frameskipno > 20-1 ) { + frameskipno = 20; + frame_time = 0.0f; + start_time = ::timeGetTime(); + } + + if( !NetPlay.RecvBuffer() ) { + bPause = TRUE; + goto _emulate_error; + } + + // obt@sŏx点ׂǂ̃`FbN + INT ret = NetPlay.BufferCheck(); + if( ret > 0 ) { + bAddFrame = TRUE; + if( frameskipno > 1 ) { + frameskipno++; + } else { + frameskipno = 2; + } + } + if( ret < 0 ) { + bNoFrame = TRUE; + } + + // Timeout check + if( bNoFrame ) { + nNetTimeoutCount++; + if( nNetTimeoutCount > 10*60 ) { + NetPlay.Disconnect(); + bPause = TRUE; + goto _emulate_error; + } + } else { + nNetTimeoutCount = 0; + } + + nNetBuffer = NetPlay.GetRecvBufferSize(); + } + + // Emulation + if( (!bEmuPause || bOneStep) && g_nes ) { + g_nes->ppu->SetScreenPtr( DirectDraw.GetRenderScreen(), DirectDraw.GetLineColormode() ); + + if( !bOneStep ) { + for( i = 0; i < frameskipno-1; i++ ) { + if( !bNoFrame ) { + // Skip frames + if( !FrameInput() ) { + bPause = TRUE; + goto _emulate_error; + } + g_nes->EmulateFrame( FALSE ); + } + if( !bAddFrame ) { + frame_time += frame_period; + } + bAddFrame = FALSE; + + // Sound streaming + StreamProcess( bEmuPause ); + } + } + if( !bNoFrame ) { + if( !FrameInput() ) { + bPause = TRUE; + goto _emulate_error; + } + g_nes->EmulateFrame( TRUE ); + } + frame_time += frame_period; + } else { + // Cxg̈ + DirectInput.Poll(); + + for( i = 0; i < frameskipno-1; i++ ) { + frame_time += frame_period; + } + frame_time += frame_period; + } + + // c + CMainFrame::OnKeyControl(); + +// // ` +// if( g_nes->ppu->GetExtMonoMode() ) { +// DirectDraw.SetPaletteMode( (PPUREG[1]&PPU_BGCOLOR_BIT)>>5, 0 ); +// } else { +// DirectDraw.SetPaletteMode( (PPUREG[1]&PPU_BGCOLOR_BIT)>>5, PPUREG[1]&PPU_COLORMODE_BIT ); +// } + // fBXNANZXv + DirectDraw.SetDiskAccessLamp( (Config.graphics.bDiskAccessLamp && g_nes->mapper->ExCmdRead( Mapper::EXCMDRD_DISKACCESS ))?TRUE:FALSE ); + // blit + DirectDraw.Blt(); + + // Sound streaming + StreamProcess( bEmuPause ); + + // ɂȎԑ҂ + sleep_time = (frame_time+frame_period) - (LONG)(::timeGetTime() - start_time); + if( bSleep && (sleep_time > 0) ) { + ::Sleep( sleep_time-1 ); + } else { + ::Sleep( 0 ); + } + + DirectDraw.Flip(); + +#if _DEBUGOUT +{ +static BOOL bPalettePut = FALSE; + + if( ::GetAsyncKeyState( VK_ESCAPE ) & 0x8000 ) { + if( !bPalettePut ) { + int i; + DEBUGOUT( "BG\t" ); + for( i = 0; i < 16; i++ ) { + DEBUGOUT( "%02X ", BGPAL[i] ); + } + DEBUGOUT( "\n" ); + DEBUGOUT( "SP\t" ); + for( i = 0; i < 16; i++ ) { + DEBUGOUT( "%02X ", SPPAL[i] ); + } + DEBUGOUT( "\n" ); + } + bPalettePut = TRUE; + } else { + bPalettePut = FALSE; + } +} +#endif + + // FPS\ + dwFrameTime[nFrameCount] = ::timeGetTime(); + if( ++nFrameCount > 32-1 ) { + nFrameCount = 0; + if( Config.graphics.bFPSDisp ) { + if( dwFrameTime[32-1]-dwFrameTime[0] > 0 ) { + FPS = 1000*10*(32-1)/(dwFrameTime[32-1]-dwFrameTime[0]); + } else { + FPS = 0; + } + } else { + FPS = 0; + } + } + if( Config.graphics.bFPSDisp ) { +#if !(defined(_DEBUG)||defined(_DEBUGOUT)) + sprintf( szStr, "FPS:%d.%01d", FPS/10, FPS%10 ); +#else + if( !NetPlay.IsConnect() ) { + sprintf( szStr, "FPS:%d.%01d", FPS/10, FPS%10 ); + } else { + sprintf( szStr, "FPS:%d.%01d NET:%3d NOFRM:%d TOUT:%3d", FPS/10, FPS%10, nNetBuffer, bNoFrame, nNetTimeoutCount ); + } +#endif + DirectDraw.SetInfoString( szStr ); + } else { + DirectDraw.SetInfoString( NULL ); + } +_emulate_error:; + } catch( CHAR* str ) { + bPause = TRUE; + ::strcpy( g_szErrorMessage, str ); + ::PostMessage( g_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)g_szErrorMessage ); +#ifndef _DEBUG + } catch(...) { + bPause = TRUE; + ::PostMessage( g_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)CApp::GetErrorString( IDS_ERROR_UNKNOWN ) ); +#endif + } + } + } + + g_WaveRec.Stop(); + + return 0; +} + +void CEmuThread::StreamProcess( BOOL bPause ) +{ + if( g_pThis && g_nes && !bPause && !DirectSound.IsStreamPause() ) { + DWORD dwWrite, dwSize; + LPVOID lpLockPtr; + DWORD dwLockSize; + if( DirectSound.GetStreamLockPosition( &dwWrite, &dwSize ) ) { + if( DirectSound.StreamLock( dwWrite, dwSize, &lpLockPtr, &dwLockSize, NULL, NULL, 0 ) ) { + g_nes->apu->Process( (LPBYTE)lpLockPtr, dwLockSize ); + g_WaveRec.Out( lpLockPtr, dwLockSize ); + DirectSound.StreamUnlock( lpLockPtr, dwLockSize, NULL, NULL ); + } + } + } +} + diff --git a/References/VirtuaNESex_src_191105/EmuThread.h b/References/VirtuaNESex_src_191105/EmuThread.h new file mode 100644 index 00000000..765377f9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/EmuThread.h @@ -0,0 +1,197 @@ +// +// G~[^XbhNX +// +#ifndef __CEMUTHREAD_INCLUDED__ +#define __CEMUTHREAD_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +#include +#include +using namespace std; + +#include "App.h" +#include "MMTimer.h" +#include "Config.h" +#include "WaveRec.h" + +#include "typedef.h" +#include "macro.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "pad.h" +#include "rom.h" +#include "mapper.h" + +// Prototypes +// NetPlay Event +class NETEV { +public: + INT Event; + DWORD Param; +}; +//class NES; + +class CEmuThread +{ +public: + CEmuThread(); + ~CEmuThread(); + + // Cxg + enum EMUEVENT { + EV_EXIT = -1, + EV_NONE = 0, + EV_INITIAL, + EV_PAUSE, + EV_RESUME, + // ȉEventŎgp + EV_MESSAGE_OUT, // bZ[Wo͂Ɏgp + + EV_FULLSCREEN_GDI, // EventParam + + EV_EMUPAUSE, + EV_ONEFRAME, + EV_THROTTLE, + EV_FRAMESKIP_AUTO, + EV_FRAMESKIP_UP, + EV_FRAMESKIP_DOWN, + + EV_HWRESET, + EV_SWRESET, + + EV_NETPLAY_START, + + EV_STATE_LOAD, // EventParam2 + EV_STATE_SAVE, // EventParam2 + + // For Disk system + EV_DISK_COMMAND, // EventParam + // For ExController + EV_EXCONTROLLER, // EventParam + // For Sound + EV_SOUND_MUTE, // EventParam + + // For Snapshot + EV_SNAPSHOT, + // For Movie + EV_MOVIE_PLAY, // EventParam + EV_MOVIE_REC, // EventParam + EV_MOVIE_RECAPPEND, // EventParam + EV_MOVIE_STOP, // EventParam + + // For Wave recording + EV_WAVEREC_START, // EventParam + EV_WAVEREC_STOP, + + // For Tape recording + EV_TAPE_PLAY, // EventParam + EV_TAPE_REC, // EventParam + EV_TAPE_STOP, + + // For Barcode + EV_BARCODE, // EventParam2 + + // For TurboFile + EV_TURBOFILE, // EventParam + + // For Debugger + EV_DEBUG_RUN, + EV_DEBUG_BRAKE, + EV_DEBUG_STEP, + EV_DEBUG_COMMAND, // EventParam + }; + + // 샂[h + enum { + STATUS_NONE = 0, + STATUS_RUN, + STATUS_PAUSE, + }; + + // fobKR}h + + // + void SetPriority( INT nPriority ); + + BOOL Start( HWND hWnd, NES* nes ); + void Stop(); + void Pause(); + void Resume(); + + void Event( EMUEVENT ev ); + void EventParam( EMUEVENT ev, LONG Param ); + void EventParam2( EMUEVENT ev, LONG Param, LONG Param2 ); + + BOOL IsRunning() { return (g_Status!=STATUS_NONE); } + BOOL IsPausing() { return (g_Status==STATUS_PAUSE); } + + BOOL IsWaveRecord() { return g_WaveRec.IsWaveRecord(); } + + INT GetDiskNo() { if( g_nes ) return g_nes->rom->GetDiskNo(); else return 0; } + INT GetExController() { if( g_nes ) return g_nes->pad->GetExController(); else return 0; } + + // + NES* GetNES() { return g_nes; } + +protected: + static void DiskCommand( BYTE cmd ); + static BOOL FrameInput(); + + static DWORD WINAPI ThreadProc( LPVOID lpVoid ); + // TEhXg[~Op + static void StreamProcess( BOOL bPause ); + + // XbhnhID + HANDLE m_hThread; + DWORD m_dwThreadID; + + // This|C^ + static CEmuThread* g_pThis; + // EChEnh + static HWND g_hWnd; + // G~[^IuWFNg|C^ + static NES* g_nes; + + // WaveR[_ + static CWaveRec g_WaveRec; + + // |[YJEg + INT m_nPauseCount; + // Xe[^X + static INT g_Status; + + // XbhCxgƃCxgnh + static INT g_Event; + static LONG g_EventParam; + static LONG g_EventParam2; + static HANDLE g_hEvent; + static HANDLE g_hEventAccept; + + // XbhvCIeB + INT m_nPriority; + static INT g_PriorityTable[]; + + // G[bZ[W + static CHAR g_szErrorMessage[512]; + + // XgOe[u + static LPCSTR g_lpSoundMuteStringTable[]; + + // NetPlay Event + static deque NetEventQueue; + static string strNetStateName; + +private: +}; + +extern CEmuThread Emu; + +#endif // !__CEMUTHREAD_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/EmulatorDlg.cpp b/References/VirtuaNESex_src_191105/EmulatorDlg.cpp new file mode 100644 index 00000000..ee66bc0d --- /dev/null +++ b/References/VirtuaNESex_src_191105/EmulatorDlg.cpp @@ -0,0 +1,136 @@ +// +// G~[^_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "EmulatorDlg.h" + +DLG_MESSAGE_BEGIN(CEmulatorDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_HSCROLL, OnHScroll ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CEmulatorDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_EMULATOR), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CEmulatorDlg::OnInitialMember() +{ + BTNCHECK( IDC_EMU_ILLEGALOP, Config.emulator.bIllegalOp ); + BTNCHECK( IDC_EMU_FOURPLAYER, Config.emulator.bFourPlayer ); + BTNCHECK( IDC_EMU_AUTOFRAMESKIP, Config.emulator.bAutoFrameSkip ); + BTNCHECK( IDC_EMU_THROTTLE, Config.emulator.bThrottle ); + BTNCHECK( IDC_EMU_BACKGROUND, Config.emulator.bBackground ); + + BTNCHECK( IDC_EMU_CRCCHECK, Config.emulator.bCrcCheck ); + BTNCHECK( IDC_EMU_DISKTHROTTLE, Config.emulator.bDiskThrottle ); + BTNCHECK( IDC_EMU_LOADFULLSCREEN, Config.emulator.bLoadFullscreen ); + + BTNCHECK( IDC_EMU_DOUBLEEXECUTE, Config.general.bDoubleExecute ); + BTNCHECK( IDC_EMU_STARTUPLAUNCHER,Config.general.bStartupLauncher ); + + BTNCHECK( IDC_EMU_PNGSNAPSHOT, Config.emulator.bPNGsnapshot ); + + // XC_ + ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETRANGE, TRUE, MAKELONG(1,60) ); + ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETPOS, TRUE, (WPARAM)Config.emulator.nThrottleFPS/10 ); + ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETTICFREQ, 2, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETLINESIZE, 0, 1 ); + ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETPAGESIZE, 0, 1 ); + + // FPSl + CHAR str[64]; + ::wsprintf( str, "%d", Config.emulator.nThrottleFPS ); + ::SetDlgItemText( m_hWnd, IDC_EMU_FPS, str ); + + // vCIeBR{{bNX + ::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_RESETCONTENT, 0, 0 ); + INT i, j; + for( i = IDS_EMU_PRIORITY_IDLE, j = 0; i <= IDS_EMU_PRIORITY_REALTIME; i++, j++ ) { + CApp::LoadString( i, str, sizeof(str) ); + ::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)str ); + } + + ::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_SETCURSEL, (WPARAM)Config.emulator.nPriority, 0 ); +} + +DLGMSG CEmulatorDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CEmulatorDlg::OnInitDialog\n" ); + + m_ConfigSave = Config.emulator; + OnInitialMember(); + + return TRUE; +} + +DLGMSG CEmulatorDlg::OnHScroll( DLGMSGPARAM ) +{ +// DEBUGOUT( "CEmulatorDlg::OnHScroll\n" ); + + INT pos = ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_GETPOS, 0, 0 ); + CHAR str[16]; + ::wsprintf( str, "%d", pos*10 ); + ::SetDlgItemText( m_hWnd, IDC_EMU_FPS, str ); + + return FALSE; +} + +DLGCMD CEmulatorDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CEmulatorDlg::OnOK\n" ); + + Config.emulator.bIllegalOp = IsBTNCHECK( IDC_EMU_ILLEGALOP ); + Config.emulator.bFourPlayer = IsBTNCHECK( IDC_EMU_FOURPLAYER ); + Config.emulator.bAutoFrameSkip = IsBTNCHECK( IDC_EMU_AUTOFRAMESKIP ); + Config.emulator.bThrottle = IsBTNCHECK( IDC_EMU_THROTTLE ); + Config.emulator.bBackground = IsBTNCHECK( IDC_EMU_BACKGROUND ); + + Config.emulator.bCrcCheck = IsBTNCHECK( IDC_EMU_CRCCHECK ); + Config.emulator.bDiskThrottle = IsBTNCHECK( IDC_EMU_DISKTHROTTLE ); + Config.emulator.bLoadFullscreen = IsBTNCHECK( IDC_EMU_LOADFULLSCREEN ); + + Config.general.bDoubleExecute = IsBTNCHECK( IDC_EMU_DOUBLEEXECUTE ); + Config.general.bStartupLauncher = IsBTNCHECK( IDC_EMU_STARTUPLAUNCHER ); + + Config.emulator.bPNGsnapshot = IsBTNCHECK( IDC_EMU_PNGSNAPSHOT ); + + Config.emulator.nThrottleFPS = 10 * ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_GETPOS, 0, 0 ); + Config.emulator.nPriority = ::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_GETCURSEL, 0, 0 ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CEmulatorDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CEmulatorDlg::OnCancel\n" ); + Config.emulator = m_ConfigSave; + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CEmulatorDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CEmulatorDlg::OnDefault\n" ); + Config.emulator.Default(); + OnInitialMember(); +} + diff --git a/References/VirtuaNESex_src_191105/EmulatorDlg.h b/References/VirtuaNESex_src_191105/EmulatorDlg.h new file mode 100644 index 00000000..de20399e --- /dev/null +++ b/References/VirtuaNESex_src_191105/EmulatorDlg.h @@ -0,0 +1,38 @@ +// +// G~[^_CAONX +// +#ifndef __CEMULATORDLG_INCLUDED__ +#define __CEMULATORDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CEmulatorDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); +protected: + void OnInitialMember(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnHScroll( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + // + + CCfgEmulator m_ConfigSave; + +private: +}; + +#endif // !__CEMULATORDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/ExtSoundFile.h b/References/VirtuaNESex_src_191105/ExtSoundFile.h new file mode 100644 index 00000000..f423e5b4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/ExtSoundFile.h @@ -0,0 +1,30 @@ +#ifndef __EXTSOUNDFILE_INCLUDED__ +#define __EXTSOUNDFILE_INCLUDED__ + +enum EXTSOUNDFILE +{ + ESF_MOEPRO_STRIKE = 0, // XgCNbI + ESF_MOEPRO_BALL, // {[ + ESF_MOEPRO_TIME, // ^[C + ESF_MOEPRO_OUT, // AEbI + ESF_MOEPRO_SAFE, // Z[t + ESF_MOEPRO_FAIRBALL, // t@[ + ESF_MOEPRO_FOULBALL, // tFAbI + ESF_MOEPRO_BATTEROUT, // ob^[AEbI + ESF_MOEPRO_PLAYBALL, // vC{[ + ESF_MOEPRO_FOURBALL, // tHA{[ + ESF_MOEPRO_HOMERUN, // z[}bI + ESF_MOEPRO_PITCHER, // s` + ESF_MOEPRO_OUCH, // Ceb + ESF_MOEPRO_AHO, // `ق + ESF_MOEPRO_KNOCK, // Ō + ESF_MOEPRO_WA, // [bIiI[CbH + + ESF_DISKSYSTEM_BOOT, // J + ESF_DISKSYSTEM_MOTOR, // [^[([v) + ESF_DISKSYSTEM_SEEKEND, // ~ + + ESF_FILE_MAX +}; + +#endif // !__EXTSOUNDFILE_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/FolderDlg.cpp b/References/VirtuaNESex_src_191105/FolderDlg.cpp new file mode 100644 index 00000000..e16b6aaa --- /dev/null +++ b/References/VirtuaNESex_src_191105/FolderDlg.cpp @@ -0,0 +1,279 @@ +// +// tH__CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "FolderDlg.h" + +DLG_MESSAGE_BEGIN(CFolderDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_ON_COMMAND( IDC_FLD_ROM_BROWSE, OnRomBrowse ) +DLG_ON_COMMAND( IDC_FLD_SAVE_BROWSE, OnSaveBrowse ) +DLG_ON_COMMAND( IDC_FLD_STATE_BROWSE, OnStateBrowse ) +DLG_ON_COMMAND( IDC_FLD_SNAPSHOT_BROWSE, OnSnapshotBrowse ) +DLG_ON_COMMAND( IDC_FLD_MOVIE_BROWSE, OnMovieBrowse ) +DLG_ON_COMMAND( IDC_FLD_WAVE_BROWSE, OnWaveBrowse ) +DLG_ON_COMMAND( IDC_FLD_CHEAT_BROWSE, OnCheatBrowse ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +CFolderDlg::CFolderDlg() +{ + m_hFont = NULL; +} + +CFolderDlg::~CFolderDlg() +{ + GDIDELETE( m_hFont ); +} + +INT CFolderDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_FOLDER), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CFolderDlg::OnInitialMember() +{ + BTNCHECK( IDC_FLD_ROM_USE, Config.path.bRomPath ); + BTNCHECK( IDC_FLD_SAVE_USE, Config.path.bSavePath ); + BTNCHECK( IDC_FLD_STATE_USE, Config.path.bStatePath ); + BTNCHECK( IDC_FLD_SNAPSHOT_USE, Config.path.bSnapshotPath ); + BTNCHECK( IDC_FLD_MOVIE_USE, Config.path.bMoviePath ); + BTNCHECK( IDC_FLD_WAVE_USE, Config.path.bWavePath ); + BTNCHECK( IDC_FLD_CHEAT_USE, Config.path.bCheatPath ); + + ::SetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, Config.path.szRomPath ); + ::SetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, Config.path.szSavePath ); + ::SetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, Config.path.szStatePath ); + ::SetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, Config.path.szSnapshotPath ); + ::SetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, Config.path.szMoviePath ); + ::SetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, Config.path.szWavePath ); + ::SetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, Config.path.szCheatPath ); +} + +void CFolderDlg::PathCheck( LPSTR lpszPath ) +{ + INT len = ::strlen( lpszPath ); + + if( len > 3 ) { + if( isleadbyte( (UINT)lpszPath[len-2] ) ) { + // MBCSŁꍇ + ::strcat( lpszPath, "\\" ); + } else { + if( lpszPath[ len-1 ] != '\\' ) { + ::strcat( lpszPath, "\\" ); + } + } + } +} + +DLGMSG CFolderDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnInitDialog\n" ); + m_ConfigSave = Config.path; + OnInitialMember(); + + return TRUE; +} + +DLGCMD CFolderDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnOK\n" ); + Config.path.bRomPath = IsBTNCHECK( IDC_FLD_ROM_USE ); + Config.path.bSavePath = IsBTNCHECK( IDC_FLD_SAVE_USE ); + Config.path.bStatePath = IsBTNCHECK( IDC_FLD_STATE_USE ); + Config.path.bSnapshotPath = IsBTNCHECK( IDC_FLD_SNAPSHOT_USE ); + Config.path.bMoviePath = IsBTNCHECK( IDC_FLD_MOVIE_USE ); + Config.path.bWavePath = IsBTNCHECK( IDC_FLD_WAVE_USE ); + Config.path.bCheatPath = IsBTNCHECK( IDC_FLD_CHEAT_USE ); + + ::GetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, Config.path.szRomPath, _MAX_PATH ); + ::GetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, Config.path.szSavePath, _MAX_PATH ); + ::GetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, Config.path.szStatePath, _MAX_PATH ); + ::GetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, Config.path.szSnapshotPath, _MAX_PATH ); + ::GetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, Config.path.szMoviePath, _MAX_PATH ); + ::GetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, Config.path.szWavePath, _MAX_PATH ); + ::GetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, Config.path.szCheatPath, _MAX_PATH ); + + PathCheck( Config.path.szRomPath ); + PathCheck( Config.path.szSavePath ); + PathCheck( Config.path.szStatePath ); + PathCheck( Config.path.szSnapshotPath ); + PathCheck( Config.path.szMoviePath ); + PathCheck( Config.path.szWavePath ); + PathCheck( Config.path.szCheatPath ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CFolderDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnCancel\n" ); + Config.path = m_ConfigSave; + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CFolderDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnDefault\n" ); + Config.path.Default(); + OnInitialMember(); +} + +DLGCMD CFolderDlg::OnRomBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnRomBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, szFolder ); + BTNCHECK( IDC_FLD_ROM_USE, TRUE ); + } +} + +DLGCMD CFolderDlg::OnSaveBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnSaveBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, szFolder ); + BTNCHECK( IDC_FLD_SAVE_USE, TRUE ); + } +} + +DLGCMD CFolderDlg::OnStateBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnStateBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, szFolder ); + BTNCHECK( IDC_FLD_STATE_USE, TRUE ); + } +} + +DLGCMD CFolderDlg::OnSnapshotBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnSnapshotBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, szFolder ); + BTNCHECK( IDC_FLD_SNAPSHOT_USE, TRUE ); + } +} + +DLGCMD CFolderDlg::OnMovieBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnMovieBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, szFolder ); + BTNCHECK( IDC_FLD_MOVIE_USE, TRUE ); + } +} + +DLGCMD CFolderDlg::OnWaveBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnWaveBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, szFolder ); + BTNCHECK( IDC_FLD_WAVE_USE, TRUE ); + } +} + +DLGCMD CFolderDlg::OnCheatBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CFolderDlg::OnCheatBrowse\n" ); + CHAR szTemp[_MAX_PATH]; + ::GetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, szTemp, _MAX_PATH ); + + CHAR szFolder[_MAX_PATH]; + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp ); + ::lstrcpy( szFolder, pathstr.c_str() ); +DEBUGOUT( "Path:%s\n", szFolder ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + ::SetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, szFolder ); + BTNCHECK( IDC_FLD_CHEAT_USE, TRUE ); + } +} + diff --git a/References/VirtuaNESex_src_191105/FolderDlg.h b/References/VirtuaNESex_src_191105/FolderDlg.h new file mode 100644 index 00000000..fdbd33fb --- /dev/null +++ b/References/VirtuaNESex_src_191105/FolderDlg.h @@ -0,0 +1,48 @@ +// +// tH__CAONX +// +#ifndef __CFOLDERDLG_INCLUDED__ +#define __CFOLDERDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CFolderDlg : public CWnd +{ +public: + CFolderDlg(); + ~CFolderDlg(); + + // Override from CWnd + INT DoModal( HWND hWndParent ); +protected: + void OnInitialMember(); + void PathCheck( LPSTR szPath ); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + DLGCMD OnRomBrowse( DLGCMDPARAM ); + DLGCMD OnSaveBrowse( DLGCMDPARAM ); + DLGCMD OnStateBrowse( DLGCMDPARAM ); + DLGCMD OnSnapshotBrowse( DLGCMDPARAM ); + DLGCMD OnMovieBrowse( DLGCMDPARAM ); + DLGCMD OnWaveBrowse( DLGCMDPARAM ); + DLGCMD OnCheatBrowse( DLGCMDPARAM ); + // + + CCfgPath m_ConfigSave; +private: + HFONT m_hFont; +}; + +#endif // !__CFOLDERDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/GameOptionDlg.cpp b/References/VirtuaNESex_src_191105/GameOptionDlg.cpp new file mode 100644 index 00000000..1f8d321b --- /dev/null +++ b/References/VirtuaNESex_src_191105/GameOptionDlg.cpp @@ -0,0 +1,136 @@ +// +// Q[IvV_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "EmuThread.h" + +#include "Wnd.h" +#include "GameOptionDlg.h" + +DLG_MESSAGE_BEGIN(CGameOptionDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_ON_COMMAND( IDC_OPT_NOTSAVE, OnNotSave ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CGameOptionDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_GAMEOPTION), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CGameOptionDlg::OnInitialMember() +{ + ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_RESETCONTENT, 0, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_RESETCONTENT, 0, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_RESETCONTENT, 0, 0 ); + + INT i, j; + CHAR szStr[256]; + for( i = IDS_OPT_RENDER_POST_ALL, j = 0; i <= IDS_OPT_RENDER_TILE; i++, j++ ) { + CApp::LoadString( i, szStr, sizeof(szStr) ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)szStr ); + } + for( i = IDS_OPT_IRQ_HSYNC, j = 0; i <= IDS_OPT_IRQ_CLOCK; i++, j++ ) { + CApp::LoadString( i, szStr, sizeof(szStr) ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)szStr ); + } + for( i = IDS_OPT_VIDEOMODE_NTSC, j = 0; i <= IDS_OPT_VIDEOMODE_PALCHINA; i++, j++ ) { + CApp::LoadString( i, szStr, sizeof(szStr) ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)szStr ); + } + + ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_SETCURSEL, (WPARAM)GameOption.nRenderMethod, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_SETCURSEL, (WPARAM)GameOption.nIRQtype, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_SETCURSEL, (WPARAM)(GameOption.bVideoMode?1:0), 0 ); + + BTNCHECK( IDC_OPT_FRAMEIRQ, !GameOption.bFrameIRQ ); +} + +DLGMSG CGameOptionDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CGameOptionDlg::OnInitDialog\n" ); + OnInitialMember(); + + return TRUE; +} + +DLGCMD CGameOptionDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGameOptionDlg::OnOK\n" ); + + GameOption.nRenderMethod = ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_GETCURSEL, 0, 0 ); + GameOption.nIRQtype = ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_GETCURSEL, 0, 0 ); + GameOption.bVideoMode = ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_GETCURSEL, 0, 0 ); + GameOption.bFrameIRQ = !IsBTNCHECK( IDC_OPT_FRAMEIRQ ); + + // ݒ肵 + Emu.GetNES()->SetRenderMethod( (NES::RENDERMETHOD)GameOption.nRenderMethod ); + Emu.GetNES()->SetIrqType ( GameOption.nIRQtype ); + Emu.GetNES()->SetFrameIRQmode( GameOption.bFrameIRQ ); + Emu.GetNES()->SetVideoMode ( GameOption.bVideoMode ); + + // Z[u + if( Emu.GetNES()->rom->GetMapperNo() == 20 ) { + GameOption.Save( Emu.GetNES()->rom->GetRomName(), Emu.GetNES()->rom->GetGameID(), Emu.GetNES()->rom->GetMakerID() ); + } else if( Emu.GetNES()->rom->GetMapperNo() < 256 ) { + GameOption.Save( Emu.GetNES()->rom->GetRomName(), Emu.GetNES()->rom->GetPROM_CRC() ); + } + // + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CGameOptionDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGameOptionDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CGameOptionDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGameOptionDlg::OnCancel\n" ); + + GameOption.nRenderMethod = GameOption.defRenderMethod; + GameOption.nIRQtype = GameOption.defIRQtype; + GameOption.bFrameIRQ = GameOption.defFrameIRQ; + GameOption.bVideoMode = GameOption.defVideoMode; + + OnInitialMember(); +} + +DLGCMD CGameOptionDlg::OnNotSave( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGameOptionDlg::OnNotSave\n" ); + + GameOption.nRenderMethod = ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_GETCURSEL, 0, 0 ); + GameOption.nIRQtype = ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_GETCURSEL, 0, 0 ); + GameOption.bVideoMode = ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_GETCURSEL, 0, 0 ); + GameOption.bFrameIRQ = !IsBTNCHECK( IDC_OPT_FRAMEIRQ ); + + // ݒ肵 + Emu.GetNES()->SetRenderMethod( (NES::RENDERMETHOD)GameOption.nRenderMethod ); + Emu.GetNES()->SetIrqType ( GameOption.nIRQtype ); + Emu.GetNES()->SetFrameIRQmode( GameOption.bFrameIRQ ); + Emu.GetNES()->SetVideoMode ( GameOption.bVideoMode ); + + ::EndDialog( m_hWnd, IDOK ); +} + diff --git a/References/VirtuaNESex_src_191105/GameOptionDlg.h b/References/VirtuaNESex_src_191105/GameOptionDlg.h new file mode 100644 index 00000000..33c3eb0d --- /dev/null +++ b/References/VirtuaNESex_src_191105/GameOptionDlg.h @@ -0,0 +1,36 @@ +// +// Q[IvV_CAONX +// +#ifndef __CGAMEOPTIONDLG_INCLUDED__ +#define __CGAMEOPTIONDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CGameOptionDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + void OnInitialMember(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + DLGCMD OnNotSave( DLGCMDPARAM ); + // +private: +}; + +#endif // !__CGAMEOPTIONDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/GraphicsDlg.cpp b/References/VirtuaNESex_src_191105/GraphicsDlg.cpp new file mode 100644 index 00000000..013fc02b --- /dev/null +++ b/References/VirtuaNESex_src_191105/GraphicsDlg.cpp @@ -0,0 +1,261 @@ +// +// OtBbNX_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "GraphicsDlg.h" + +#include "DirectDraw.h" + +DLG_MESSAGE_BEGIN(CGraphicsDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_HSCROLL, OnHScroll ) +// NOTIFYbZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_ON_COMMAND( IDC_GRA_PALETTE_BROWSE, OnPaletteBrowse ) +DLG_ON_COMMAND_NOTIFY( IDC_GRA_PALETTE_USE, BN_CLICKED, OnPaletteUseClick ) +DLG_ON_COMMAND_NOTIFY( IDC_GRA_NOSQUARELIST, BN_CLICKED, OnNoSquareListClick ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CGraphicsDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_GRAPHICS), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CGraphicsDlg::OnInitialMember() +{ + BTNCHECK( IDC_GRA_ASPECT, Config.graphics.bAspect ); + BTNCHECK( IDC_GRA_ALLSPRITE, Config.graphics.bAllSprite ); + BTNCHECK( IDC_GRA_ALLLINE, Config.graphics.bAllLine ); + BTNCHECK( IDC_GRA_FPS, Config.graphics.bFPSDisp ); + BTNCHECK( IDC_GRA_TVFRAME, Config.graphics.bTVFrame ); + BTNCHECK( IDC_GRA_SCANLINE, Config.graphics.bScanline ); + BTNCHECK( IDC_GRA_SYNCDRAW, Config.graphics.bSyncDraw ); + BTNCHECK( IDC_GRA_FITZOOM, Config.graphics.bFitZoom ); + BTNCHECK( IDC_GRA_LEFTCLIP, Config.graphics.bLeftClip ); + BTNCHECK( IDC_GRA_DOUBLESIZE, Config.graphics.bDoubleSize ); + BTNCHECK( IDC_GRA_SYSTEMMEMORY, Config.graphics.bSystemMemory ); + BTNCHECK( IDC_GRA_USEHEL, Config.graphics.bUseHEL ); + BTNCHECK( IDC_GRA_WAITVSYNC, Config.graphics.bWindowVSync ); + BTNCHECK( IDC_GRA_DISKACCESSLAMP, Config.graphics.bDiskAccessLamp ); + BTNCHECK( IDC_GRA_NOSQUARELIST, Config.graphics.bNoSquareList ); + BTNCHECK( IDC_GRA_SYNCNOSLEEP, !Config.graphics.bSyncNoSleep ); + + // XC_ + ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETRANGE, TRUE, MAKELONG(0,100) ); + ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETPOS, TRUE, (WPARAM)Config.graphics.nScanlineColor ); + ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETLINESIZE, 0, 1 ); + ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETPAGESIZE, 0, 10 ); + + // XLCJ[l + CHAR str[64]; + ::wsprintf( str, "%d%%", Config.graphics.nScanlineColor ); + ::SetDlgItemText( m_hWnd, IDC_GRA_SCANLINE_COLOR, str ); + + // pbg + BTNCHECK( IDC_GRA_PALETTE_USE, Config.graphics.bPaletteFile ); + ::SetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, Config.graphics.szPaletteFile ); + + // 𑜓xR{{bNX + OnUpdateComboBox(); +} + +void CGraphicsDlg::OnUpdateComboBox() +{ + // 𑜓xR{{bNX + ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_RESETCONTENT, 0, 0 ); + INT i, listno, select = 0; + CHAR szMode[64]; + for( i = 0, listno = 0; i < DirectDraw.GetDisplayModeNum(); i++ ) { + DWORD dwWidth, dwHeight, dwDepth, dwRate; + DirectDraw.GetDisplayMode( i, dwWidth, dwHeight, dwDepth, dwRate ); + + if( !Config.graphics.bNoSquareList && dwWidth*3 != dwHeight*4 ) + continue; + + if( Config.graphics.dwDisplayWidth == dwWidth + && Config.graphics.dwDisplayHeight == dwHeight + && Config.graphics.dwDisplayDepth == dwDepth + && Config.graphics.dwDisplayRate == dwRate ) { + select = listno; + } + + ::wsprintf( szMode, "%4dx%4d %dbit %dHz", dwWidth, dwHeight, dwDepth, dwRate ); + ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_INSERTSTRING, (WPARAM)listno, (LPARAM)szMode ); + ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_SETITEMDATA, (WPARAM)listno, (LPARAM)i ); + + listno++; + } + ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_SETCURSEL, (WPARAM)select, 0 ); +} + +DLGMSG CGraphicsDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CGraphicsDlg::OnInitDialog\n" ); + m_ConfigSave = Config.graphics; + + OnInitialMember(); + + return TRUE; +} + +DLGMSG CGraphicsDlg::OnHScroll( DLGMSGPARAM ) +{ +// DEBUGOUT( "CGraphicsDlg::OnHScroll\n" ); + + INT pos; + CHAR str[16]; + ::wsprintf( str, "%d%%", pos = ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_GETPOS, 0, 0 ) ); + ::SetDlgItemText( m_hWnd, IDC_GRA_SCANLINE_COLOR, str ); + + // XLCJ[̕ύX + DirectDraw.SetScanlineColor( pos ); + // pbge[ǔvZ + DirectDraw.CalcPaletteTable(); + + // Fς̂ŃyCgĂ + ::PostMessage( CApp::GetHWnd(), WM_PAINT, 0, 0 ); + + return FALSE; +} + +DLGCMD CGraphicsDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGraphicsDlg::OnOK\n" ); + + Config.graphics.bAspect = IsBTNCHECK( IDC_GRA_ASPECT ); + Config.graphics.bAllSprite = IsBTNCHECK( IDC_GRA_ALLSPRITE ); + Config.graphics.bAllLine = IsBTNCHECK( IDC_GRA_ALLLINE ); + Config.graphics.bFPSDisp = IsBTNCHECK( IDC_GRA_FPS ); + Config.graphics.bTVFrame = IsBTNCHECK( IDC_GRA_TVFRAME ); + Config.graphics.bScanline = IsBTNCHECK( IDC_GRA_SCANLINE ); + Config.graphics.bSyncDraw = IsBTNCHECK( IDC_GRA_SYNCDRAW ); + Config.graphics.bFitZoom = IsBTNCHECK( IDC_GRA_FITZOOM ); + Config.graphics.bLeftClip = IsBTNCHECK( IDC_GRA_LEFTCLIP ); + Config.graphics.bDoubleSize = IsBTNCHECK( IDC_GRA_DOUBLESIZE ); + Config.graphics.bSystemMemory = IsBTNCHECK( IDC_GRA_SYSTEMMEMORY ); + Config.graphics.bUseHEL = IsBTNCHECK( IDC_GRA_USEHEL ); + Config.graphics.bWindowVSync = IsBTNCHECK( IDC_GRA_WAITVSYNC ); + Config.graphics.bDiskAccessLamp = IsBTNCHECK( IDC_GRA_DISKACCESSLAMP ); + Config.graphics.bNoSquareList = IsBTNCHECK( IDC_GRA_NOSQUARELIST ); + Config.graphics.bSyncNoSleep = !IsBTNCHECK( IDC_GRA_SYNCNOSLEEP ); + + Config.graphics.nScanlineColor = ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_GETPOS, 0, 0 ); + + INT sel = ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_GETCURSEL, 0, 0 ); + INT no = ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_GETITEMDATA, (WPARAM)sel, 0 ); + + DirectDraw.GetDisplayMode( no, Config.graphics.dwDisplayWidth, + Config.graphics.dwDisplayHeight, + Config.graphics.dwDisplayDepth, + Config.graphics.dwDisplayRate ); + + Config.graphics.bPaletteFile = IsBTNCHECK( IDC_GRA_PALETTE_USE ); + ::GetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, Config.graphics.szPaletteFile, _MAX_PATH ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CGraphicsDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGraphicsDlg::OnCancel\n" ); + Config.graphics = m_ConfigSave; + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CGraphicsDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGraphicsDlg::OnDefault\n" ); + Config.graphics.Default(); + OnInitialMember(); +} + +DLGCMD CGraphicsDlg::OnPaletteBrowse( DLGCMDPARAM ) +{ +// DEBUGOUT( "CGraphicsDlg::OnPaletteBrowse\n" ); + + CHAR szTemp[ _MAX_PATH ]; + ::GetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, szTemp, _MAX_PATH ); + + CHAR szPath[ _MAX_PATH ]; + CHAR szFile[ _MAX_PATH ]; + string temp; + temp = CPathlib::SplitPath( szTemp ); + ::strcpy( szPath, temp.c_str() ); + temp = CPathlib::SplitFnameExt( szTemp ); + ::strcpy( szFile, temp.c_str() ); + + OPENFILENAME ofn; + ZeroMemory( &ofn, sizeof(ofn) ); + + if( strlen( szPath ) > 0 ) { + // ݒς݂Ȃ΃pX^t@Cl[̐ݒ + ofn.lpstrInitialDir = szPath; + } else { + // ݒȂΎst@CƓpX̐ݒ + ofn.lpstrInitialDir = CApp::GetModulePath(); + szFile[0] = '\0'; + } + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_OPENPALETTE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + + ofn.lpstrFilter = "Palette File(*.PAL)\0*.PAL\0All File(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST; + + if( ::GetOpenFileName( &ofn ) ) { + BTNCHECK( IDC_GRA_PALETTE_USE, TRUE ); + ::SetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, szFile ); + + DirectDraw.SetPaletteFile( szFile ); + } +} + +DLGCMD CGraphicsDlg::OnPaletteUseClick( DLGCMDPARAM ) +{ + if( IsBTNCHECK(IDC_GRA_PALETTE_USE) ) { + CHAR szTemp[ _MAX_PATH ]; + ::GetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, szTemp, _MAX_PATH ); + DirectDraw.SetPaletteFile( szTemp ); + } else { + DirectDraw.SetPaletteTable( (LPBYTE)NULL ); + } + + ::PostMessage( CApp::GetHWnd(), WM_PAINT, 0, 0 ); +} + +DLGCMD CGraphicsDlg::OnNoSquareListClick( DLGCMDPARAM ) +{ + Config.graphics.bNoSquareList = IsBTNCHECK( IDC_GRA_NOSQUARELIST ); + + // 𑜓xR{{bNX̍XV + OnUpdateComboBox(); +} + diff --git a/References/VirtuaNESex_src_191105/GraphicsDlg.h b/References/VirtuaNESex_src_191105/GraphicsDlg.h new file mode 100644 index 00000000..f3a7dcfe --- /dev/null +++ b/References/VirtuaNESex_src_191105/GraphicsDlg.h @@ -0,0 +1,42 @@ +// +// OtBbNX_CAONX +// +#ifndef __CGRAPHICSDLG_INCLUDED__ +#define __CGRAPHICSDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CGraphicsDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); +protected: + void OnInitialMember(); + void OnUpdateComboBox(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnHScroll( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + DLGCMD OnPaletteBrowse( DLGCMDPARAM ); + DLGCMD OnPaletteUseClick( DLGCMDPARAM ); + DLGCMD OnNoSquareListClick( DLGCMDPARAM ); + // + + CCfgGraphics m_ConfigSave; + +private: +}; + +#endif // !__CGRAPHICSDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/JoyAxisDlg.cpp b/References/VirtuaNESex_src_191105/JoyAxisDlg.cpp new file mode 100644 index 00000000..3251f52f --- /dev/null +++ b/References/VirtuaNESex_src_191105/JoyAxisDlg.cpp @@ -0,0 +1,141 @@ +// +// WCXeBbNݒ_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "JoyAxisDlg.h" + +#include "DirectInput.h" + +DLG_MESSAGE_BEGIN(CJoyAxisDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_TIMER, OnTimer ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_ON_COMMAND_NOTIFY( IDC_AST_ID_COMBO, CBN_SELCHANGE, OnSelectChange ) +DLG_ON_COMMAND_NOTIFY_RANGE( IDC_AST_XAXIS, IDC_AST_RZAXIS, BN_CLICKED, OnCheckChange ) + +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CJoyAxisDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_AXISSETTING), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CJoyAxisDlg::OnJoySettingSetup( INT nID ) +{ + BTNCHECK( IDC_AST_XAXIS, m_JoyAxisSetting[nID]&(1<<0) ); + BTNCHECK( IDC_AST_YAXIS, m_JoyAxisSetting[nID]&(1<<1) ); + BTNCHECK( IDC_AST_ZAXIS, m_JoyAxisSetting[nID]&(1<<2) ); + BTNCHECK( IDC_AST_RXAXIS, m_JoyAxisSetting[nID]&(1<<3) ); + BTNCHECK( IDC_AST_RYAXIS, m_JoyAxisSetting[nID]&(1<<4) ); + BTNCHECK( IDC_AST_RZAXIS, m_JoyAxisSetting[nID]&(1<<5) ); +} + +DLGMSG CJoyAxisDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CJoyAxisDlg::OnInitDialog\n" ); + + m_JoySel = 0; + ::memcpy( m_JoyAxisSetting, Config.general.JoyAxisSetting, 16*sizeof(WORD) ); + + OnJoySettingSetup( m_JoySel ); + + for( INT i = IDC_AST_XAXIS_PROGRESS; i <= IDC_AST_RZAXIS_PROGRESS; i++ ) { + ::SendDlgItemMessage( m_hWnd, i, PBM_SETRANGE32, (WPARAM)-10000, (LPARAM)10000 ); + ::SendDlgItemMessage( m_hWnd, i, PBM_SETSTEP, (WPARAM)1, 0 ); + } + + // IDR{{bNX + ::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_RESETCONTENT, 0, 0 ); + CHAR szStr[MAX_PATH+16]; + for( i = 0; i < DirectInput.m_nJoystickNum; i++ ) { + ::wsprintf( szStr, " %d : %s", i, DirectInput.m_JoyName[i].c_str() ); + ::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szStr ); + } + ::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_SETCURSEL, 0, 0 ); + + m_TimerID = ::SetTimer( m_hWnd, 1, 50, NULL ); + + return TRUE; +} + +DLGMSG CJoyAxisDlg::OnTimer( DLGMSGPARAM ) +{ +// DEBUGOUT( "CJoyAxisDlg::OnTimer\n" ); + + DirectInput.Poll(); + + INT i, j; + for( i = IDC_AST_XAXIS_PROGRESS, j = 0; i <= IDC_AST_RZAXIS_PROGRESS; i++, j++ ) { + ::SendDlgItemMessage( m_hWnd, i, PBM_SETPOS, (WPARAM)DirectInput.m_JoyAxis[ m_JoySel ][ j ], 0 ); + } + + return TRUE; +} + +DLGCMD CJoyAxisDlg::OnCheckChange( DLGCMDPARAM ) +{ +// DEBUGOUT( "CJoyAxisDlg::OnCheckChange\n" ); + + WORD bits = 0; + + bits |= IsBTNCHECK( IDC_AST_XAXIS )?(1<<0):0; + bits |= IsBTNCHECK( IDC_AST_YAXIS )?(1<<1):0; + bits |= IsBTNCHECK( IDC_AST_ZAXIS )?(1<<2):0; + bits |= IsBTNCHECK( IDC_AST_RXAXIS )?(1<<3):0; + bits |= IsBTNCHECK( IDC_AST_RYAXIS )?(1<<4):0; + bits |= IsBTNCHECK( IDC_AST_RZAXIS )?(1<<5):0; + + m_JoyAxisSetting[ m_JoySel ] = bits; +} + +DLGNOTIFY CJoyAxisDlg::OnSelectChange( DLGCMDPARAM ) +{ + m_JoySel = ::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_GETCURSEL, 0, 0 ); + OnJoySettingSetup( m_JoySel ); +} + +DLGCMD CJoyAxisDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CJoyAxisDlg::OnOK\n" ); + + ::memcpy( Config.general.JoyAxisSetting, m_JoyAxisSetting, 16*sizeof(WORD) ); + ::KillTimer( m_hWnd, m_TimerID ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CJoyAxisDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CJoyAxisDlg::OnCancel\n" ); + + ::KillTimer( m_hWnd, m_TimerID ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CJoyAxisDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CJoyAxisDlg::OnDefault\n" ); + + ::memset( m_JoyAxisSetting, 0, 16*sizeof(WORD) ); + OnJoySettingSetup( m_JoySel ); +} + diff --git a/References/VirtuaNESex_src_191105/JoyAxisDlg.h b/References/VirtuaNESex_src_191105/JoyAxisDlg.h new file mode 100644 index 00000000..83e947d9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/JoyAxisDlg.h @@ -0,0 +1,44 @@ +// +// WCXeBbNݒ_CAONX +// +#ifndef __CJOYAXISDLG_INCLUDED__ +#define __CJOYAXISDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CJoyAxisDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + void OnJoySettingSetup( INT nID ); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + + DLGMSG OnTimer( DLGMSGPARAM ); + DLGNOTIFY OnCheckChange( DLGCMDPARAM ); + DLGNOTIFY OnSelectChange( DLGCMDPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + // + + INT m_JoySel; + INT m_TimerID; + WORD m_JoyAxisSetting[16]; +private: +}; + +#endif // !__CJOYAXISDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/LanguageDlg.cpp b/References/VirtuaNESex_src_191105/LanguageDlg.cpp new file mode 100644 index 00000000..fe2c3693 --- /dev/null +++ b/References/VirtuaNESex_src_191105/LanguageDlg.cpp @@ -0,0 +1,77 @@ +// +// Q[W_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Plugin.h" + +#include "Wnd.h" +#include "LanguageDlg.h" + +DLG_MESSAGE_BEGIN(CLanguageDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CLanguageDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_LANGUAGE), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CLanguageDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CLanguageDlg::OnInitDialog\n" ); + + m_nPluginID = CPlugin::GetPluginID(); + + for( INT i = 0; i < CPlugin::GetPluginNum(); i++ ) { + ::SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_INSERTSTRING, (WPARAM)i, (LPARAM)CPlugin::GetPluginLanguage(i) ); + } + // ftHgI + ::SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_SETCURSEL, (WPARAM)m_nPluginID, 0 ); + + return TRUE; +} + +DLGCMD CLanguageDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLanguageDlg::OnOK\n" ); + INT nID = ::SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_GETCURSEL, 0, 0 ); + if( m_nPluginID != nID ) { + CPlugin::SetPluginID( nID ); + ::EndDialog( m_hWnd, IDOK ); + } else { + ::EndDialog( m_hWnd, IDCANCEL ); + } +} + +DLGCMD CLanguageDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLanguageDlg::OnCancel\n" ); + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CLanguageDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLanguageDlg::OnDefault\n" ); + + // ftHgI + SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_SETCURSEL, (WPARAM)CPlugin::GetPluginID(), 0 ); +} + diff --git a/References/VirtuaNESex_src_191105/LanguageDlg.h b/References/VirtuaNESex_src_191105/LanguageDlg.h new file mode 100644 index 00000000..d19ee035 --- /dev/null +++ b/References/VirtuaNESex_src_191105/LanguageDlg.h @@ -0,0 +1,33 @@ +// +// Q[W_CAONX +// +#ifndef __CLANGUAGEDLG_INCLUDED__ +#define __CLANGUAGEDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CLanguageDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + // + + INT m_nPluginID; +private: +}; + +#endif // !__CLANGUAGEDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/LauncherDlg.cpp b/References/VirtuaNESex_src_191105/LauncherDlg.cpp new file mode 100644 index 00000000..7be9521e --- /dev/null +++ b/References/VirtuaNESex_src_191105/LauncherDlg.cpp @@ -0,0 +1,1974 @@ +// +// `[_CAONX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#include +#include +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Crclib.h" +#include "Config.h" +#include "Archive.h" + +#include "Wnd.h" +#include "LauncherDlg.h" + +#include "rom.h" +#include "romdb.h" + +#include "EmuThread.h" + +// bZ[W +DLG_MESSAGE_BEGIN(CLauncherDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_DESTROY, OnDestroy ) +DLG_ON_MESSAGE( WM_CLOSE, OnClose ) +DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +DLG_ON_MESSAGE( WM_SETCURSOR, OnSetCursor ) +DLG_ON_MESSAGE( WM_SIZE, OnSize ) +DLG_ON_MESSAGE( WM_TIMER, OnTimer ) +DLG_ON_MESSAGE( WM_INITMENUPOPUP, OnInitMenuPopup ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( ID_LCH_REFRESH, OnRefresh ) +DLG_ON_COMMAND( ID_LCH_DISPEDIT, OnDispEdit ) +DLG_ON_COMMAND( ID_LCH_HEADEREDIT, OnHeaderEdit ) +DLG_ON_COMMAND( ID_LCH_FOLDER, OnFolder ) +DLG_ON_COMMAND_RANGE( ID_LCH_LIST0, ID_LCH_LIST9, OnListSelect ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_KEYDOWN, OnKeyDownListView ) +DLG_ON_NOTIFY( IDC_LCH_LIST, NM_RETURN, OnReturnListView ) +DLG_ON_NOTIFY( IDC_LCH_LIST, NM_DBLCLK, OnDoubleClickListView ) +DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_COLUMNCLICK, OnColumnClickListView ) +DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_ITEMCHANGED, OnItemChangedListView ) +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +// X^eBbNo +BOOL CLauncherDlg::m_bSortDir = FALSE; + +INT CLauncherDlg::m_FileListNum = 0; +vector CLauncherDlg::m_FileList; +CHAR CLauncherDlg::m_LaunchPath[_MAX_PATH]; + +#define LAUNCHHEADER_MAX 15 + +INT CLauncherDlg::m_HeaderID[] = { + IDS_LCH_FILENAME, + IDS_LCH_PATH, + IDS_LCH_MAPPER, + IDS_LCH_PRG, + IDS_LCH_CHR, + IDS_LCH_ALLCRC, + IDS_LCH_PRGCRC, + IDS_LCH_INFO, + IDS_LCH_DATABASE, + IDS_LCH_TITLE, + IDS_LCH_COUNTRY, + IDS_LCH_MANUFACTURER, + IDS_LCH_SALEDATE, + IDS_LCH_PRICE, + IDS_LCH_GENRE, +}; + +BOOL CLauncherDlg::Create( HWND hWndParent ) +{ + m_hImageList = NULL; + m_hImageListHdr = NULL; + + // e̓fXNgbvɂ + m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_LAUNCHER), + NULL, g_DlgProc, (LPARAM)this ); + if( !m_hWnd ) + return FALSE; + + // [hX_CAOXgɉ + CWndList::Add( this ); + + return TRUE; +} + +void CLauncherDlg::Destroy() +{ + if( m_hWnd ) { + // [hX_CAOXg폜 + CWndList::Del( this ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + INT i; + INT Order[16]; + INT nCount = Header_GetItemCount( ListView_GetHeader( hWndCtrl ) ); + + ListView_GetColumnOrderArray( hWndCtrl, nCount, Order ); + + INT OrderTemp[16]; + for( i = 0; i < LAUNCHHEADER_MAX; i++ ) { + OrderTemp[i] = Config.launcher.nHeaderOrder[i]; + } + for( i = 0; i < nCount; i++ ) { + Config.launcher.nHeaderOrder[i] = OrderTemp[Order[i]]; + Config.launcher.nHeaderWidth[Config.launcher.nHeaderOrder[i]] = ListView_GetColumnWidth( hWndCtrl, Order[i] ); + } + OnUpdateStop(); + + ::GetWindowRect( m_hWnd, &Config.launcher.rcWindowPos ); + + if( !m_FileListNum ) { + Config.launcher.szLastSelect[0] = '\0'; + } else { + FILELIST& fl = m_FileList[m_SelectPos]; + string Path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() ); + ::strcpy( Config.launcher.szLastSelect, Path.c_str() ); + } + + if( !m_bFileLoaded ) { + SaveFileList(); + } + + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +INT CALLBACK CLauncherDlg::ListViewCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) +{ +//DEBUGOUT( "L1:%08X L2:%08X PA:%d\n", lParam1, lParam2, lParamSort ); + + FILELIST& fl1 = m_FileList[lParam1]; + FILELIST& fl2 = m_FileList[lParam2]; + + CHAR szTemp[_MAX_PATH]; + string s1, s2; + INT n1, n2; + + INT ret = 0; + switch( lParamSort ) { + case COLUMN_FILENAME: +#if 1 + ::strcpy( szTemp, fl1.fname.c_str() ); + s1 = (CHAR*)::_mbsupr( (UCHAR*)szTemp ); + ::strcpy( szTemp, fl2.fname.c_str() ); + s2 = (CHAR*)::_mbsupr( (UCHAR*)szTemp ); + if( !Config.launcher.bSortDir ) { + ret = s1.compare( s2.c_str() ); + } else { + ret = s2.compare( s1.c_str() ); + } +#else + { + INT cmpresult = ::CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH, + fl1.fname.c_str(), fl1.fname.size(), fl2.fname.c_str(), fl1.fname.size() ); + if( cmpresult == CSTR_LESS_THAN ) + ret = -1; + if( cmpresult == CSTR_EQUAL ) + ret = 0; + if( cmpresult == CSTR_GREATER_THAN ) + ret = 1; + } +#endif + if( ret == 0 ) { + return ListViewCompare( lParam1, lParam2, COLUMN_PATH ); + } + return ret; + case COLUMN_PATH: + ::strcpy( szTemp, fl1.path.c_str() ); + s1 = (CHAR*)::_mbsupr( (UCHAR*)szTemp ); + ::strcpy( szTemp, fl2.path.c_str() ); + s2 = (CHAR*)::_mbsupr( (UCHAR*)szTemp ); + if( !Config.launcher.bSortDir ) { + ret = s1.compare( s2.c_str() ); + } else { + ret = s2.compare( s1.c_str() ); + } + return ret; + case COLUMN_MAPPER: + n1 = fl1.mapper & 0x0FFF; + n2 = fl2.mapper & 0x0FFF; + goto _Compare_Num; + case COLUMN_PRG: + n1 = fl1.prg_size; + n2 = fl2.prg_size; + goto _Compare_Num; + case COLUMN_CHR: + n1 = fl1.chr_size; + n2 = fl2.chr_size; + goto _Compare_Num; + case COLUMN_ALLCRC: + n1 = fl1.crcall; + n2 = fl2.crcall; + goto _Compare_Num; + case COLUMN_PRGCRC: + n1 = fl1.crc; + n2 = fl2.crc; + goto _Compare_Num; + case COLUMN_INFO: + s1 = fl1.info; + s2 = fl2.info; + goto _Compare_Str; + case COLUMN_DB: + s1 = fl1.db; + s2 = fl2.db; + goto _Compare_Str; + case COLUMN_TITLE: + s1 = fl1.title; + s2 = fl2.title; + goto _Compare_Str; + case COLUMN_COUNTRY: + s1 = fl1.country; + s2 = fl2.country; + goto _Compare_Str; + case COLUMN_MANUFACTURER: + s1 = fl1.manufacturer; + s2 = fl2.manufacturer; + goto _Compare_Str; + case COLUMN_SALEDATE: + s1 = fl1.saledate; + s2 = fl2.saledate; + goto _Compare_Str; + case COLUMN_PRICE: + s1 = fl1.price; + s2 = fl2.price; + goto _Compare_Str; + case COLUMN_GENRE: + s1 = fl1.genre; + s2 = fl2.genre; + goto _Compare_Str; +_Compare_Num: + if( n1 == n2 ) { + return ListViewCompare( lParam1, lParam2, COLUMN_FILENAME ); + } + if( !Config.launcher.bSortDir ) { + if( n1 < n2 ) ret = -1; + else ret = 1; + } else { + if( n1 < n2 ) ret = 1; + else ret = -1; + } + return ret; + +_Compare_Str: +#if 1 + ::strcpy( szTemp, s1.c_str() ); + s1 = (CHAR*)::_mbsupr( (UCHAR*)szTemp ); + ::strcpy( szTemp, s2.c_str() ); + s2 = (CHAR*)::_mbsupr( (UCHAR*)szTemp ); + if( !Config.launcher.bSortDir ) { + ret = s1.compare( s2.c_str() ); + } else { + ret = s2.compare( s1.c_str() ); + } +#else + { + INT cmpresult = ::CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH, + s1.c_str(), s1.size(), s2.c_str(), s2.size() ); + if( cmpresult == CSTR_LESS_THAN ) + ret = -1; + if( cmpresult == CSTR_EQUAL ) + ret = 0; + if( cmpresult == CSTR_GREATER_THAN ) + ret = 1; + } +#endif + if( ret == 0 ) { + return ListViewCompare( lParam1, lParam2, COLUMN_FILENAME ); + } + return ret; + default: + break; + } + return 0; +} + +void CLauncherDlg::ResetListViewHeader() +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + + INT i; + for( i = 0; i < LAUNCHHEADER_MAX; i++ ) { + ListView_DeleteColumn( hWndCtrl, 0 ); + } + + LV_COLUMN lvColumn; + lvColumn.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH; + + INT no = 0; + for( i = 0; i < LAUNCHHEADER_MAX; i++ ) { + if( Config.launcher.bHeaderView[Config.launcher.nHeaderOrder[i]] ) { +// if( Config.launcher.nHeaderOrder[i] >= 2 && Config.launcher.nHeaderOrder[i] <= 6 ) { +// lvColumn.fmt = LVCFMT_RIGHT; +// } else { +// lvColumn.fmt = LVCFMT_LEFT; +// } + lvColumn.fmt = LVCFMT_LEFT; + + CHAR szStr[64]; + CApp::LoadString( m_HeaderID[Config.launcher.nHeaderOrder[i]], szStr, sizeof(szStr) ); + lvColumn.iSubItem = no; + lvColumn.pszText = szStr; + lvColumn.cx = Config.launcher.nHeaderWidth[Config.launcher.nHeaderOrder[i]]; + ListView_InsertColumn( hWndCtrl, no, &lvColumn ); + no++; + } + } +} + +void CLauncherDlg::ResetListView() +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + + ListView_DeleteAllItems( hWndCtrl ); + + FILELIST fl; + LVITEM lvitem; + lvitem.mask = LVIF_TEXT|LVIF_PARAM; + lvitem.iSubItem = 0; + lvitem.pszText = ""; + + ::SendMessage( hWndCtrl, WM_SETREDRAW, (WPARAM)FALSE, 0 ); + + for( INT index = 0; index < m_FileListNum; index++ ) { + lvitem.iItem = index; + lvitem.lParam = (LPARAM)index; + ListView_InsertItem( hWndCtrl, &lvitem ); + fl = m_FileList[index]; + + // Xgr[ւ̃t@C̐ݒ + SetListView( index, fl ); + } + + ::SendMessage( hWndCtrl, WM_SETREDRAW, (WPARAM)TRUE, 0 ); + ::InvalidateRect( hWndCtrl, NULL, TRUE ); +} + +void CLauncherDlg::SetListView( INT index, FILELIST& fl ) +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + + CHAR szStr[256]; + INT RealOrder[16]; + INT i; + for( i = 0; i < LAUNCHHEADER_MAX; i++ ) { + RealOrder[Config.launcher.nHeaderOrder[i]] = i; + } + + szStr[0] = '\0'; + + // File name + if( Config.launcher.bHeaderView[0] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[0], (LPSTR)fl.fname.c_str() ); + } + // Path + if( Config.launcher.bHeaderView[1] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[1], (LPSTR)fl.path.c_str() ); + } + // Mapper + if( Config.launcher.bHeaderView[2] ) { + INT Mapper = fl.mapper & 0x0FFF; + INT image = 0; + + if( Mapper == 20 ) { + ::strcpy( szStr, "FDS" ); + if( fl.mapper&0xF000 ) + image = 4; + else + image = 3; + } else if( Mapper == 0x100 ) { + ::strcpy( szStr, "NSF" ); + image = 5; + } else if( Mapper > 0x100 ) { + ::strcpy( szStr, "Unknown" ); + image = 0; + } else { + ::wsprintf( szStr, "%d", fl.mapper&0xFF ); + if( fl.mapper&0xF000 ) + image = 2; + else + image = 1; + } + ListView_SetItemText( hWndCtrl, index, RealOrder[2], szStr ); + + // Image(State) + ListView_SetItemState( hWndCtrl, index, INDEXTOSTATEIMAGEMASK(image+1), LVIS_STATEIMAGEMASK ); + + } + // PRG size + if( Config.launcher.bHeaderView[3] ) { + if( (fl.mapper&0x0FFF) == 20 ) { + // FDS + ::wsprintf( szStr, "%d", fl.prg_size ); + } else if( (fl.mapper&0x0FFF) == 0x100 ) { + // NSF + ::wsprintf( szStr, "%d", fl.prg_size ); + } else if( (fl.mapper&0x0FFF) < 0x100 ) { + // NES + ::wsprintf( szStr, "%d", 16*fl.prg_size ); + } else { + // Bad file + ::strcpy( szStr, "0" ); + } + ListView_SetItemText( hWndCtrl, index, RealOrder[3], szStr ); + } + // CHR size + if( Config.launcher.bHeaderView[4] ) { + if( (fl.mapper&0x0FFF) == 0x100 ) { + // NSF + ::wsprintf( szStr, "%d", fl.chr_size ); + } else if( (fl.mapper&0x0FFF) < 0x100 ) { + // NES + ::wsprintf( szStr, "%d", 8*fl.chr_size ); + } +// ::wsprintf( szStr, "%d", 8*fl.chr_size ); + ListView_SetItemText( hWndCtrl, index, RealOrder[4], szStr ); + } + // CRC ALL + if( Config.launcher.bHeaderView[5] ) { + ::wsprintf( szStr, "%08X", fl.crcall ); + ListView_SetItemText( hWndCtrl, index, RealOrder[5], szStr ); + } + // CRC + if( Config.launcher.bHeaderView[6] ) { + ::wsprintf( szStr, "%08X", fl.crc ); + ListView_SetItemText( hWndCtrl, index, RealOrder[6], szStr ); + } + // Info + if( Config.launcher.bHeaderView[7] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[7], (LPSTR)fl.info.c_str() ); + } + // DB + if( Config.launcher.bHeaderView[8] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[8], (LPSTR)fl.db.c_str() ); + } + // TITLE + if( Config.launcher.bHeaderView[9] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[9], (LPSTR)fl.title.c_str() ); + } + // Country + if( Config.launcher.bHeaderView[10] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[10], (LPSTR)fl.country.c_str() ); + } + // Manufacturer + if( Config.launcher.bHeaderView[11] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[11], (LPSTR)fl.manufacturer.c_str() ); + } + // Sale date + if( Config.launcher.bHeaderView[12] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[12], (LPSTR)fl.saledate.c_str() ); + } + // Price + if( Config.launcher.bHeaderView[13] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[13], (LPSTR)fl.price.c_str() ); + } + // Genre + if( Config.launcher.bHeaderView[14] ) { + ListView_SetItemText( hWndCtrl, index, RealOrder[14], (LPSTR)fl.genre.c_str() ); + } +} + +void CLauncherDlg::SortListView() +{ + INT i; + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + + if( ListView_GetItemCount( hWndCtrl ) <= 0 ) + return; + + // wb_ + HWND hWndHdr = ListView_GetHeader( hWndCtrl ); + HD_ITEM hdi; + hdi.mask = HDI_FORMAT; + hdi.fmt = HDF_STRING; + for( i = 0; i < Header_GetItemCount(hWndHdr); i++ ) { + Header_SetItem( hWndHdr, i, &hdi ); + } + hdi.mask = HDI_FORMAT|HDI_IMAGE; + hdi.fmt = HDF_STRING | HDF_IMAGE | HDF_BITMAP_ON_RIGHT; + hdi.iImage = Config.launcher.bSortDir?1:0; + + INT RealOrder[16]; + for( i = 0; i < LAUNCHHEADER_MAX; i++ ) { + RealOrder[Config.launcher.nHeaderOrder[i]] = i; + } + + Header_SetItem( hWndHdr, RealOrder[Config.launcher.nSortType], &hdi ); + + // \[g{ + ListView_SortItems( hWndCtrl, (PFNLVCOMPARE)ListViewCompare, Config.launcher.nSortType ); + + if( m_SelectPos >= 0 ) { + LV_FINDINFO fi; + fi.flags = LVFI_PARAM; + fi.lParam = (LPARAM)m_SelectPos; + INT index = ListView_FindItem( hWndCtrl, -1, &fi ); + if( index >= 0 ) { + ListView_EnsureVisible( hWndCtrl, index, FALSE ); + ListView_SetItemState( hWndCtrl, index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); + } + } else { + LVITEM lvitem; + lvitem.mask = LVIF_PARAM; + lvitem.iItem = 0; + ListView_GetItem( hWndCtrl, &lvitem ); + m_SelectPos = lvitem.lParam; + ListView_SetItemState( hWndCtrl, 0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); + } +} + +void CLauncherDlg::SetLastSelect() +{ + if( !m_FileListNum ) + return; + + FILELIST fl; + BOOL bSel = FALSE; + string path; + + for( INT index = 0; index < m_FileListNum; index++ ) { + fl = m_FileList[index]; + path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() ); + if( ::strcmp( Config.launcher.szLastSelect, path.c_str() ) == 0 ) { + m_SelectPos = index; + bSel = TRUE; + break; + } + } + + if( bSel ) { + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + LV_FINDINFO fi; + fi.flags = LVFI_PARAM; + fi.lParam = (LPARAM)m_SelectPos; + INT index = ListView_FindItem( hWndCtrl, -1, &fi ); + if( index >= 0 ) { + ListView_EnsureVisible( hWndCtrl, index, FALSE ); + ListView_SetItemState( hWndCtrl, index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); + } + } +} + +void CLauncherDlg::OnUpdateStart() +{ + if( !m_FileListNum ) + return; + + if( m_bUpdate ) { + m_UpdatePos = 0; + m_nUpdateIndex = 0; + } else { + m_UpdatePos = 0; + m_nUpdateIndex = 0; + m_nTimerID = ::SetTimer( m_hWnd, 1, 100, NULL ); + m_bUpdate = TRUE; + } +} + +void CLauncherDlg::OnUpdateStop() +{ + if( m_bUpdate ) { + ::KillTimer( m_hWnd, m_nTimerID ); + m_bUpdate = FALSE; + + ::SendMessage( ::GetDlgItem( m_hWnd, IDC_LCH_STATUS ), SB_SETTEXT, SBT_NOBORDERS, (LPARAM)"" ); + } +} + +DLGMSG CLauncherDlg::OnTimer( DLGMSGPARAM ) +{ + if( m_bUpdate && !m_bUpdating ) { + UpdateListView(); + } + return FALSE; +} + +void CLauncherDlg::UpdateListView() +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + INT nListCount = ListView_GetItemCount( hWndCtrl ); + if( nListCount <= 0 ) + return; + + m_bUpdating = TRUE; + +// for( INT i = 0; i < 5; i++ ) { + for( INT i = 0; i < 20; i++ ) { + FILELIST& fl = m_FileList[m_UpdatePos]; + CheckFile( fl ); + + LV_FINDINFO fi; + fi.flags = LVFI_PARAM; + fi.lParam = (LPARAM)m_UpdatePos; + INT index = ListView_FindItem( hWndCtrl, -1, &fi ); + if( index >= 0 ) { + SetListView( index, fl ); + } + + m_UpdatePos++; + m_nUpdateIndex++; + + if( m_nUpdateIndex >= nListCount ) { + OnUpdateStop(); + break; + } + } + + if( m_nUpdateIndex < nListCount ) { + // Xe[^Xo[ւ̕\ + CHAR szTemp[256], szText[256]; + CApp::LoadString( IDS_LCH_LISTUPDATE, szTemp, sizeof(szTemp) ); + ::wsprintf( szText, szTemp, m_nUpdateIndex, nListCount ); + ::SendMessage( ::GetDlgItem( m_hWnd, IDC_LCH_STATUS ), SB_SETTEXT, SBT_NOBORDERS, (LPARAM)szText ); + } + + m_bUpdating = FALSE; +} + +#define MKID(a) ((unsigned long) \ + (((a) >> 24) & 0x000000FF) | \ + (((a) >> 8) & 0x0000FF00) | \ + (((a) << 8) & 0x00FF0000) | \ + (((a) << 24) & 0xFF000000)) + +void CLauncherDlg::CheckFile( FILELIST& fl ) +{ +FILE* fp = NULL; +LPBYTE temp = NULL; +LPBYTE pUnif = NULL; +LONG FileSize; +LONG filesize; +string path; + + path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() ); + + if( (fp = ::fopen( path.c_str(), "rb" )) ) { + NESHEADER header; + + // t@CTCY擾 + ::fseek( fp, 0, SEEK_END ); + FileSize = ::ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + // t@CTCY`FbN(NESwb_+1oCgȏォH) + if( FileSize < 17 ) + goto _error_return; + + // e|m + if( !(temp = (LPBYTE)::malloc( FileSize )) ) + goto _error_return; + + pUnif = (LPBYTE)::malloc( FileSize ); + filesize = FileSize; + + // TCYǂݍ + if( ::fread( temp, FileSize, 1, fp ) != 1 ) + goto _error_return; + + memcpy(pUnif,temp,FileSize); + + FCLOSE( fp ); + + // wb_Rs[ + memcpy( &header, temp, sizeof(NESHEADER) ); + + if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + // wb_Rs[ +// memcpy( &header, temp, sizeof(NESHEADER) ); + } else if( header.ID[0] == 'F' && header.ID[1] == 'D' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + // wb_Rs[ +// memcpy( &header, temp, sizeof(NESHEADER) ); + } else if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 'M') { + // wb_Rs[ +// memcpy( &header, temp, sizeof(NESHEADER) ); + } else if( header.ID[0] == 'U' && header.ID[1] == 'N' + && header.ID[2] == 'I' && header.ID[3] == 'F' ) { + // + } else { + FREE( temp ); + temp = NULL; + if( !UnCompress( path.c_str(), &temp, (LPDWORD)&FileSize ) ) + goto _error_return; + memcpy( &header, temp, sizeof(NESHEADER) ); + } + + if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + fl.mapper = ((header.control1&0xF0)>>4)|(header.control2&0xF0); + fl.prg_size = header.PRG_PAGE_SIZE; + fl.chr_size = header.CHR_PAGE_SIZE; + CHAR szTemp[64]; + ::wsprintf( szTemp, "%s%s%s%s %s", + (header.control1&0x01)?"V":"H", + (header.control1&0x02)?"S":"_", + (header.control1&0x04)?"T":"_", + (header.control1&0x08)?"4":"_", + (header.control2&0x01)?"(VS)":"" ); + fl.info = szTemp; + + BOOL bBad = FALSE; + if( header.control1&0x04 ) { + if( FileSize < (512+16384*fl.prg_size+8192*fl.chr_size+sizeof(NESHEADER)) ) { + fl.crcall = CRC::CrcRev( FileSize-sizeof(NESHEADER), temp+sizeof(NESHEADER) ); + fl.crc = 0; + fl.prg_size = 0; + fl.chr_size = 0; + fl.info = "Bad NES header"; + bBad = TRUE; + } else { + fl.crcall = CRC::CrcRev( 512+16384*fl.prg_size+8192*fl.chr_size, temp+sizeof(NESHEADER) ); + fl.crc = CRC::CrcRev( 512+16384*fl.prg_size, temp+sizeof(NESHEADER) ); + } + } else { + if( FileSize < (16384*fl.prg_size+8192*fl.chr_size+sizeof(NESHEADER)) ) { + fl.crcall = CRC::CrcRev( FileSize-sizeof(NESHEADER), temp+sizeof(NESHEADER) ); + fl.crc = 0; + fl.prg_size = 0; + fl.chr_size = 0; + fl.info = "Bad NES header"; + bBad = TRUE; + } else { + fl.crcall = CRC::CrcRev( 16384*fl.prg_size+8192*fl.chr_size, temp+sizeof(NESHEADER) ); + fl.crc = CRC::CrcRev( 16384*fl.prg_size, temp+sizeof(NESHEADER) ); + } + } + + if( !bBad ) { + ROMDB db; + INT ret = romdatabase.HeaderCheck( header, fl.crcall, fl.crc, db ); + if( ret == 0 ) { + fl.db = "OK"; + } else if( ret == 1 ) { + fl.db = "NG"; + fl.mapper |= 0x1000; + } else { + fl.db = "??"; + } + if( ret >= 0 ) { + fl.title = db.title; + fl.country = db.country; + fl.manufacturer = db.manufacturer; + fl.saledate = db.saledate; + fl.price = db.price; + fl.genre = db.genre; + } + } else { + fl.mapper |= 0x1000; + } + }else if( header.ID[0] == 'U' && header.ID[1] == 'N'&& header.ID[2] == 'I' && header.ID[3] == 'F' ) { + + DWORD Signature, BlockLen; + DWORD ipos =0x20;//UNIFͷ + BYTE id,i; + BYTE *tPRG[0x10], *tCHR[0x10]; + DWORD sizePRG[0x10],sizeCHR[0x10]; + char info[100]; + char name[100]; + + + for (i = 0; i < 0x10; i++) + { + tPRG[i] = tCHR[i] = 0; + } + + //filesize + while(ipos>14; + free(tPRG[i]); + } + if (tCHR[i]) + { + //memcpy(&g_ROM.VROM_banks[LenCHR], tCHR[i], sizeCHR[i]); + LenCHR += sizeCHR[i]; + fl.chr_size = (fl.chr_size)+(sizeCHR[i]>>13); + free(tCHR[i]); + } + } + FREE( pUnif ); + + }else if( header.ID[0] == 'F' && header.ID[1] == 'D' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + fl.mapper = 20; + fl.info = "Disk"; + // Disk number + fl.prg_size = header.PRG_PAGE_SIZE; + + if( FileSize < (16+65500*(LONG)header.PRG_PAGE_SIZE) ) { + // fBXNTCYُł + fl.mapper |= 0x1000; + fl.info = "Bad FDS size"; + } + } else if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 'M') { + fl.mapper = 0x100; + if( FileSize < 0x80 ) { + fl.info = "Bad NSF size"; + } else { + // Total songs + fl.prg_size = (INT)temp[0x06]; + fl.chr_size = (INT)temp[0x7a]; // NTSC/PAL + if( temp[0x7b] ) { + static LPCSTR szChipName[] = { "VRC VI", "VRC VII", "FDS", "MMC5", + "N106", "FME-07", NULL, NULL }; + BOOL bFind = FALSE; + for( INT i = 0; szChipName[i]; i++ ) { + if( temp[0x7b] & (1<wVKey == VK_ESCAPE ) { + ::PostMessage( m_hWnd, WM_COMMAND, IDCANCEL, 0 ); + } +} + +DLGNOTIFY CLauncherDlg::OnReturnListView( DLGNOTIFYPARAM ) +{ + ::PostMessage( m_hWnd, WM_COMMAND, IDOK, 0 ); +} + +DLGNOTIFY CLauncherDlg::OnDoubleClickListView( DLGNOTIFYPARAM ) +{ + if( m_FileListNum ) { +//DEBUGOUT( "Item double click!! SEL=%08X\n", m_SelectPos ); + FILELIST& fl = m_FileList[m_SelectPos]; + string path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() ); + ::strcpy( m_LaunchPath, path.c_str() ); + + // CEChEɃ|Xg + ::PostMessage( CApp::GetHWnd(), WM_VNS_LAUNCHERCMD, 0, (LPARAM)m_LaunchPath ); + } +} + +DLGNOTIFY CLauncherDlg::OnColumnClickListView( DLGNOTIFYPARAM ) +{ + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; +//DEBUGOUT( "Column click!! I:%d S:%d\n", pNMListView->iItem, pNMListView->iSubItem ); +//DEBUGOUT( "Order:%d\n", Config.launcher.nHeaderOrder[pNMListView->iSubItem] ); + + if( Config.launcher.nSortType == Config.launcher.nHeaderOrder[pNMListView->iSubItem] ) { + Config.launcher.bSortDir = !Config.launcher.bSortDir; + } else { + Config.launcher.bSortDir = FALSE; + Config.launcher.nSortType = Config.launcher.nHeaderOrder[pNMListView->iSubItem]; + } + SortListView(); +} + +DLGNOTIFY CLauncherDlg::OnItemChangedListView( DLGNOTIFYPARAM ) +{ + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; + + if( !(pNMListView->uOldState & LVIS_SELECTED) && (pNMListView->uNewState & LVIS_SELECTED) ) { +//DEBUGOUT( "Item Select. SEL=%d\n", pNMListView->iItem ); + m_SelectPos = (INT)pNMListView->lParam; + } +} + +DLGCMD CLauncherDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLauncherDlg::OnOK\n" ); + if( m_FileListNum ) { +//DebugOut( "Item double click!! SEL=%08X\n", m_SelectPos ); + FILELIST& fl = m_FileList[m_SelectPos]; + string path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() ); + ::strcpy( m_LaunchPath, path.c_str() ); + + // CEChEɃ|Xg + ::PostMessage( CApp::GetHWnd(), WM_VNS_LAUNCHERCMD, 0, (LPARAM)m_LaunchPath ); + } +} + +DLGCMD CLauncherDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLauncherDlg::OnCancel\n" ); + ::ShowWindow( m_hWnd, SW_HIDE ); // \ɂ邾 +} + +DLGCMD CLauncherDlg::OnListSelect( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLauncherDlg::OnListSelect uID:%d\n", uID ); + INT nSel = uID-ID_LCH_LIST0; + + // ႤXgɂH + if( m_nListSelect != nSel ) { + // ł +// DEBUGOUT( "LISTSEL=%d\n", nSel ); + + // Ô̂Z[u + m_bFileLoaded = FALSE; + SaveFileList(); + + Config.launcher.nListSelect = m_nListSelect = nSel; + LoadFileList(); + if( m_FileListNum ) { + ResetListView(); + SortListView(); + SetLastSelect(); + m_bFileLoaded = TRUE; + } else { + ResetListView(); + } + } +} + +DLGCMD CLauncherDlg::OnRefresh( DLGCMDPARAM ) +{ + OnUpdateStop(); + ResetFileList(); + ResetListView(); + SortListView(); + OnUpdateStart(); +} + +DLGCMD CLauncherDlg::OnDispEdit( DLGCMDPARAM ) +{ + CLchDispEditDlg dlg; + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + ResetListViewHeader(); + ResetListView(); + SortListView(); + } +} + +DLGCMD CLauncherDlg::OnFolder( DLGCMDPARAM ) +{ + CLchFolderConfigDlg dlg; + + if( dlg.DoModal( m_hWnd ) == IDOK ) { +// ::PostMessage( m_hWnd, WM_COMMAND, ID_LCH_REFRESH, 0 ); + } +} + +DLGCMD CLauncherDlg::OnHeaderEdit( DLGCMDPARAM ) +{ +DEBUGOUT( "CLauncherDlg::OnHeaderEdit SEL=%d\n", m_SelectPos ); + + if( m_SelectPos >= 0 && m_FileListNum ) { + FILE* fp = NULL; + NESHEADER header; + + FILELIST& fl = m_FileList[ m_SelectPos ]; + + string Path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() ); +DEBUGOUT( "Path:%s\n", Path.c_str() ); + + // A[JCut@C̓GfBbgs + char* pExt = ::PathFindExtension( Path.c_str() ); + if( _stricmp( pExt, ".lzh" ) == 0 || _stricmp( pExt, ".zip" ) == 0 || _stricmp( pExt, ".cab" ) == 0 || _stricmp( pExt, ".rar" ) == 0 ) { + return; + } + + if( (fp = ::fopen( Path.c_str(), "rb" )) ) { + if( ::fread( &header, sizeof(header), 1, fp ) != 1 ) { + FCLOSE( fp ); + return; + } + FCLOSE( fp ); + } else { + return; + } + + // NESȊO̓GfBbgs + if( header.ID[0] != 'N' || header.ID[1] != 'E' + || header.ID[2] != 'S' || header.ID[3] != 0x1A) { + return; + } + + CLchHeaderEditDlg dlg; + + dlg.m_nMapperNo = (INT)((header.control1&0xF0)>>4)|(header.control2&0xF0); + dlg.m_bMirror = (header.control1&0x01)?TRUE:FALSE; + dlg.m_bSram = (header.control1&0x02)?TRUE:FALSE; + dlg.m_bTrainer = (header.control1&0x04)?TRUE:FALSE; + dlg.m_bFourScreen = (header.control1&0x08)?TRUE:FALSE; + dlg.m_bVSUnisystem = (header.control2&0x01)?TRUE:FALSE; + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + BYTE control1 = 0; + BYTE control2 = 0; + INT no = dlg.m_nMapperNo; + + control1 = (no&0x0F)<<4; + control2 = no&0xF0; + + if( dlg.m_bMirror ) control1 |= 0x01; + if( dlg.m_bSram ) control1 |= 0x02; + if( dlg.m_bTrainer ) control1 |= 0x04; + if( dlg.m_bFourScreen ) control1 |= 0x08; + if( dlg.m_bVSUnisystem ) control2 |= 0x01; + + if( header.control1 != control1 || header.control2 != control2 ) { + CHAR szStr[256]; + CApp::LoadString( IDS_LCH_HEADERREWRITE, szStr, sizeof(szStr) ); + + if( ::MessageBox( m_hWnd, szStr, "", MB_YESNO ) == IDYES ) { + header.control1 = control1; + header.control2 = control2; + + for( INT i = 0; i < 8; i++ ) + header.reserved[i] = 0; + + LPBYTE temp = NULL; + LONG size; + + try { + if( (fp = ::fopen( Path.c_str(), "r+b" )) ) { + // t@CTCY擾 + ::fseek( fp, 0, SEEK_END ); + size = ::ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + + // e|m + if( !(temp = (LPBYTE)::malloc( size )) ) + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + + // TCYǂݍ + if( ::fread( temp, size, 1, fp ) != 1 ) + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + + ::memcpy( temp, &header, sizeof(header) ); + + ::fseek( fp, 0, SEEK_SET ); + + if( ::fwrite( temp, size, 1, fp ) != 1 ) + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + + FCLOSE( fp ); + FREE( temp ); + } + + CheckFile( fl ); + m_bFileLoaded = FALSE; // Z[uׂɃtO + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST ); + + LV_FINDINFO fi; + fi.flags = LVFI_PARAM; + fi.lParam = (LPARAM)m_SelectPos; + INT index = ListView_FindItem( hWndCtrl, -1, &fi ); + if( index >= 0 ) { + SetListView( index, fl ); + } + } catch( CHAR* str ) { + ::MessageBox( m_hWnd, str, "ERROR", MB_ICONERROR|MB_OK ); +#ifndef _DEBUG + } catch(...) { + ::MessageBox( m_hWnd, CApp::GetErrorString( IDS_ERROR_UNKNOWN ), "ERROR", MB_ICONERROR|MB_OK ); +#endif + } + } + } + } + } +} + +BOOL CLauncherDlg::LoadFileList() +{ +FILE* fp = NULL; +CHAR buf[1024+1]; +const UCHAR seps[] = ";\n\0"; // Zp[^ +FILELIST fl; + +// string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "launcher", "lst" ); + string Path = CPathlib::MakePath( CApp::GetModulePath(), "launcher" ); + if( m_nListSelect ) { + Path = Path + (char)('0'+m_nListSelect) + ".lst"; + } else { + Path = Path + ".lst"; + } + + m_FileList.clear(); + m_FileListNum = 0; + + if( (fp = ::fopen( Path.c_str(), "r" )) ) { +DEBUGOUT( "Load Launcher File:%s\n", Path.c_str() ); + while( ::fgets( buf, 1024, fp ) ) { + if( buf[0] == ';' ) { + continue; + } + + CHAR* pToken; + + // File Name + if( !(pToken = (CHAR*)::_mbstok( (UCHAR*)buf, seps )) ) + continue; + fl.fname = pToken; + + // Path + if( !(pToken = (CHAR*)::_mbstok( NULL, seps )) ) + continue; + fl.path = pToken; + + // Mapper + if( !(pToken = (CHAR*)::_mbstok( NULL, seps )) ) + continue; + fl.mapper = ::atoi( pToken ); + + // PRG SIZE + if( !(pToken = (CHAR*)::_mbstok( NULL, seps )) ) + continue; + fl.prg_size = ::atoi( pToken ); + + // CHR SIZE + if( !(pToken = (CHAR*)::_mbstok( NULL, seps )) ) + continue; + fl.chr_size = ::atoi( pToken ); + + // ALL CRC + if( !(pToken = (CHAR*)::_mbstok( NULL, seps )) ) + continue; + fl.crcall = ::strtoul( pToken, NULL, 16 ); + + // CRC + if( !(pToken = (CHAR*)::_mbstok( NULL, seps )) ) + continue; + fl.crc = ::strtoul( pToken, NULL, 16 ); + + // Info + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.info = pToken; + } else { + fl.info = ""; + } + + // DB + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.db = pToken; + } else { + fl.db = ""; + } + + // TITLE + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.title = pToken; + } else { + fl.title = ""; + } + + // Country + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.country = pToken; + } else { + fl.country = ""; + } + + // Manufacturer + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.manufacturer = pToken; + } else { + fl.manufacturer = ""; + } + + // Sale date + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.saledate = pToken; + } else { + fl.saledate = ""; + } + + // Price + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.price = pToken; + } else { + fl.price = ""; + } + + // Genre + if( (pToken = (CHAR*)::_mbstok( NULL, seps )) ) { + fl.genre = pToken; + } else { + fl.genre = ""; + } + + m_FileList.push_back( fl ); + m_FileListNum++; + } + + FCLOSE( fp ); + return TRUE; + } + + return FALSE; +} + +void CLauncherDlg::SaveFileList() +{ +FILE* fp = NULL; + +// string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "launcher", "lst" ); + string Path = CPathlib::MakePath( CApp::GetModulePath(), "launcher" ); + if( m_nListSelect ) { + Path = Path + (char)('0'+m_nListSelect) + ".lst"; + } else { + Path = Path + ".lst"; + } + + if( !m_FileListNum ) { +DEBUGOUT( "Delete Launcher File:%s\n", Path.c_str() ); + ::DeleteFile( Path.c_str() ); + return; + } + +DEBUGOUT( "Save Launcher File:%s\n", Path.c_str() ); + + if( (fp = ::fopen( Path.c_str(), "w" )) ) { + for( INT index = 0; index < m_FileListNum; index++ ) { + FILELIST& fl = m_FileList[index]; +//DEBUGOUT( "%08X:%s\n", index, fl.fname.c_str() ); + ::fprintf( fp, "%s;%s;%d;%d;%d;%08X;%08X;%s;%s;%s;%s;%s;%s;%s;%s\n", + fl.fname.c_str(), + fl.path.c_str(), + fl.mapper, + fl.prg_size, + fl.chr_size, + fl.crcall, + fl.crc, + fl.info.c_str(), + fl.db.c_str(), + fl.title.c_str(), + fl.country.c_str(), + fl.manufacturer.c_str(), + fl.saledate.c_str(), + fl.price.c_str(), + fl.genre.c_str() ); + } + FCLOSE( fp ); + } + + m_FileList.clear(); + m_FileListNum = 0; +} + +///////////////////////////////////////////////////////////////////////////// + +// bZ[W +DLG_MESSAGE_BEGIN(CLchDispEditDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDC_DED_ADD, OnAdd ) +DLG_ON_COMMAND( IDC_DED_DEL, OnDel ) +DLG_ON_COMMAND( IDC_DED_UP, OnUp ) +DLG_ON_COMMAND( IDC_DED_DOWN, OnDown ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +INT CLchDispEditDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_LCH_DISPEDIT), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CLchDispEditDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CLchDispEditDlg::OnInitDialog\n" ); + + INT i; + CHAR szStr[64]; + m_nViewNum = m_nHideNum = 0; + for( i = 0; i < LAUNCHHEADER_MAX; i++ ) { + CApp::LoadString( CLauncherDlg::m_HeaderID[Config.launcher.nHeaderOrder[i]], szStr, sizeof(szStr) ); + if( Config.launcher.bHeaderView[Config.launcher.nHeaderOrder[i]] ) { + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_ADDSTRING, 0, (LPARAM)szStr ); + m_nViewOrder[m_nViewNum] = Config.launcher.nHeaderOrder[i]; + m_nViewNum++; + } else { + ::SendDlgItemMessage( m_hWnd, IDC_DED_HIDELIST, LB_ADDSTRING, 0, (LPARAM)szStr ); + m_nHideOrder[m_nHideNum] = Config.launcher.nHeaderOrder[i]; + m_nHideNum++; + } + } + if( m_nViewNum <= 1 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_DED_DEL ), FALSE ); + } + if( m_nHideNum == 0 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_DED_ADD ), FALSE ); + } + + return TRUE; +} + +DLGCMD CLchDispEditDlg::OnAdd( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchDispEditDlg::OnAdd\n" ); + + INT nSel = ::SendDlgItemMessage( m_hWnd, IDC_DED_HIDELIST, LB_GETCURSEL, 0, 0 ); + + if( nSel != LB_ERR ) { + CHAR szStr[64]; + ::SendDlgItemMessage( m_hWnd, IDC_DED_HIDELIST, LB_GETTEXT, (WPARAM)nSel, (LPARAM)szStr ); + + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_ADDSTRING, 0, (LPARAM)szStr ); + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_SETCURSEL, (WPARAM)m_nViewNum, 0 ); + + m_nViewOrder[m_nViewNum] = m_nHideOrder[nSel]; + m_nViewNum++; + + ::SendDlgItemMessage( m_hWnd, IDC_DED_HIDELIST, LB_DELETESTRING, (WPARAM)nSel, 0 ); + + for( INT i = nSel; i < m_nHideNum-1; i++ ) { + m_nHideOrder[i] = m_nHideOrder[i+1]; + } + m_nHideNum--; + } + + if( m_nViewNum >= 1 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_DED_DEL ), TRUE ); + } + if( m_nHideNum == 0 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_DED_ADD ), FALSE ); + } +} + +DLGCMD CLchDispEditDlg::OnDel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchDispEditDlg::OnDel\n" ); + + INT nSel = ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_GETCURSEL, 0, 0 ); + + if( nSel != LB_ERR ) { + CHAR szStr[64]; + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_GETTEXT, (WPARAM)nSel, (LPARAM)szStr ); + + ::SendDlgItemMessage( m_hWnd, IDC_DED_HIDELIST, LB_ADDSTRING, 0, (LPARAM)szStr ); + ::SendDlgItemMessage( m_hWnd, IDC_DED_HIDELIST, LB_SETCURSEL, (WPARAM)m_nHideNum, 0 ); + + m_nHideOrder[m_nHideNum] = m_nViewOrder[nSel]; + m_nHideNum++; + + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_DELETESTRING, (WPARAM)nSel, 0 ); + + for( INT i = nSel; i < m_nViewNum-1; i++ ) { + m_nViewOrder[i] = m_nViewOrder[i+1]; + } + m_nViewNum--; + } + + if( m_nViewNum <= 1 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_DED_DEL ), FALSE ); + } + if( m_nHideNum != 0 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_DED_ADD ), TRUE ); + } +} + +DLGCMD CLchDispEditDlg::OnUp( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchDispEditDlg::OnUp\n" ); + + INT nSel = ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_GETCURSEL, 0, 0 ); + + if( nSel != LB_ERR && nSel > 0 ) { + CHAR szStr[64]; + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_GETTEXT, (WPARAM)nSel, (LPARAM)szStr ); + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_DELETESTRING, (WPARAM)nSel, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_INSERTSTRING, (WPARAM)nSel-1, (LPARAM)szStr ); + + INT temp = m_nViewOrder[nSel]; + m_nViewOrder[nSel] = m_nViewOrder[nSel-1]; + m_nViewOrder[nSel-1] = temp; + + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_SETCURSEL, (WPARAM)nSel-1, 0 ); + } +} + +DLGCMD CLchDispEditDlg::OnDown( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchDispEditDlg::OnDown\n" ); + + INT nSel = ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_GETCURSEL, 0, 0 ); + + if( nSel != LB_ERR && nSel < m_nViewNum-1 ) { + CHAR szStr[64]; + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_GETTEXT, (WPARAM)nSel, (LPARAM)szStr ); + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_DELETESTRING, (WPARAM)nSel, 0 ); + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_INSERTSTRING, (WPARAM)nSel+1, (LPARAM)szStr ); + + INT temp = m_nViewOrder[nSel]; + m_nViewOrder[nSel] = m_nViewOrder[nSel+1]; + m_nViewOrder[nSel+1] = temp; + + ::SendDlgItemMessage( m_hWnd, IDC_DED_VIEWLIST, LB_SETCURSEL, (WPARAM)nSel+1, 0 ); + } +} + +DLGCMD CLchDispEditDlg::OnOK( DLGCMDPARAM ) +{ + for( INT i = 0; i < LAUNCHHEADER_MAX; i++ ) { + if( i < m_nViewNum ) { + Config.launcher.nHeaderOrder[i] = m_nViewOrder[i]; + Config.launcher.bHeaderView[m_nViewOrder[i]] = TRUE; + } else { + Config.launcher.nHeaderOrder[i] = m_nHideOrder[i-m_nViewNum]; + Config.launcher.bHeaderView[m_nHideOrder[i-m_nViewNum]] = FALSE; + } +//DEBUGOUT( "%2d:%2d %2d\n", i, Config.launcher.nHeaderOrder[i], Config.launcher.bHeaderView[i] ); + } + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CLchDispEditDlg::OnCancel( DLGCMDPARAM ) +{ + ::EndDialog( m_hWnd, IDCANCEL ); +} + +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ListView_SetCheckState + #define ListView_SetCheckState(hwndLV, i, fCheck) \ + ListView_SetItemState(hwndLV, i, \ + INDEXTOSTATEIMAGEMASK((fCheck)+1), LVIS_STATEIMAGEMASK) +#endif + +// bZ[W +DLG_MESSAGE_BEGIN(CLchFolderConfigDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDC_LFL_ADD, OnAdd ) +DLG_ON_COMMAND( IDC_LFL_DEL, OnDel ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +INT CLchFolderConfigDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_LCH_FOLDER), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CLchFolderConfigDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CLchFolderConfigDlg::OnInitDialog\n" ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LFL_LIST ); + ListView_SetExtendedListViewStyle( hWndCtrl, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES ); + + // |[g[hł̓wb_[Ăݒ肵Ȃƕ\Ȃ + LV_COLUMN lvcol; + lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvcol.fmt = LVCFMT_LEFT; + lvcol.cx = 1024; + lvcol.iSubItem = 0; + lvcol.pszText = ""; + ListView_InsertColumn( hWndCtrl, 0, &lvcol ); + + LV_ITEM lvitem; + lvitem.mask = LVIF_TEXT; + lvitem.iSubItem = 0; + for( INT i = 0; i < 16; i++ ) { + lvitem.iItem = i; + if( ::strlen( Config.launcher.szFolder[i] ) ) { + lvitem.pszText = Config.launcher.szFolder[i]; + ListView_InsertItem( hWndCtrl, &lvitem ); + ListView_SetCheckState( hWndCtrl, i, Config.launcher.bFolderUse[i] ); + } else { + break; + } + } + + return TRUE; +} + +DLGCMD CLchFolderConfigDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchFolderConfigDlg::OnOK\n" ); + + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LFL_LIST ); + INT nCount = ListView_GetItemCount( hWndCtrl ); + + INT i; + for( i = 0; i < nCount; i++ ) { + ListView_GetItemText( hWndCtrl, i, 0, Config.launcher.szFolder[i], sizeof(Config.launcher.szFolder[i]) ); + Config.launcher.bFolderUse[i] = ListView_GetCheckState( hWndCtrl, i ); + } + for( ; i < 16; i++ ) { + Config.launcher.bFolderUse[i] = FALSE; + Config.launcher.szFolder[i][0] = '\0'; + } + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CLchFolderConfigDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchFolderConfigDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CLchFolderConfigDlg::OnAdd( DLGCMDPARAM ) +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LFL_LIST ); + + CHAR szFolder[_MAX_PATH]; + szFolder[0] = '\0'; + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) ); + + if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) { + LV_ITEM lvitem; + lvitem.mask = LVIF_TEXT; + lvitem.iItem = ListView_GetItemCount( hWndCtrl ); + lvitem.iSubItem = 0; + lvitem.pszText = szFolder; + + ListView_InsertItem( hWndCtrl, &lvitem ); + ListView_SetCheckState( hWndCtrl, lvitem.iItem, TRUE ); + + if( lvitem.iItem+1 >= 16 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_LFL_ADD ), FALSE ); + } + } +} + +DLGCMD CLchFolderConfigDlg::OnDel( DLGCMDPARAM ) +{ + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LFL_LIST ); + INT nCount = ListView_GetItemCount( hWndCtrl ); + + for( INT i = 0; i < nCount; i++ ) { + if( ListView_GetItemState( hWndCtrl, i, LVIS_SELECTED ) ) { + ListView_DeleteItem( hWndCtrl, i ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_LFL_ADD ), TRUE ); + break; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// bZ[W +DLG_MESSAGE_BEGIN(CLchHeaderEditDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +INT CLchHeaderEditDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_LCH_HEADEREDIT), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CLchHeaderEditDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CLchHeaderEditDlg::OnInitDialog\n" ); + + ::SetDlgItemInt( m_hWnd, IDC_HED_EDIT, (UINT)m_nMapperNo, FALSE ); + + BTNCHECK( IDC_HED_VMIRROR, m_bMirror ); + BTNCHECK( IDC_HED_SRAM, m_bSram ); + BTNCHECK( IDC_HED_4SCREEN, m_bFourScreen ); + BTNCHECK( IDC_HED_TRAINER, m_bTrainer ); + BTNCHECK( IDC_HED_VSUNISYSTEM, m_bVSUnisystem ); + + return TRUE; +} + +DLGCMD CLchHeaderEditDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchHeaderEditDlg::OnOK\n" ); + + m_nMapperNo = (INT)::GetDlgItemInt( m_hWnd, IDC_HED_EDIT, NULL, FALSE ); + if( m_nMapperNo < 0 || m_nMapperNo > 255 ) { + CHAR szStr[256]; + CApp::LoadString( IDS_ERROR_ILLEGALMAPPERNO, szStr, sizeof(szStr) ); + ::MessageBox( m_hWnd, szStr, "ERROR", MB_ICONERROR|MB_OK ); + return; + } + + m_bMirror = IsBTNCHECK( IDC_HED_VMIRROR ); + m_bSram = IsBTNCHECK( IDC_HED_SRAM ); + m_bFourScreen = IsBTNCHECK( IDC_HED_4SCREEN ); + m_bTrainer = IsBTNCHECK( IDC_HED_TRAINER ); + m_bVSUnisystem = IsBTNCHECK( IDC_HED_VSUNISYSTEM ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CLchHeaderEditDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CLchHeaderEditDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + diff --git a/References/VirtuaNESex_src_191105/LauncherDlg.h b/References/VirtuaNESex_src_191105/LauncherDlg.h new file mode 100644 index 00000000..22109b2a --- /dev/null +++ b/References/VirtuaNESex_src_191105/LauncherDlg.h @@ -0,0 +1,214 @@ +// +// `[_CAONX +// +#ifndef __CLAUNCHERDLG_INCLUDED__ +#define __CLAUNCHERDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +#include +#include +using namespace std; + +#include "Wnd.h" + +class FILELIST +{ +public: + string fname; + string path; + INT mapper; + INT prg_size; + INT chr_size; + DWORD crcall; + DWORD crc; + string info; + string db; + string title; + string country; + string manufacturer; + string saledate; + string price; + string genre; +}; + +class CLauncherDlg : public CWnd +{ +public: + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + + // Table + static INT m_HeaderID[]; +protected: + enum { + COLUMN_FILENAME = 0, + COLUMN_PATH, + COLUMN_MAPPER, + COLUMN_PRG, + COLUMN_CHR, + COLUMN_ALLCRC, + COLUMN_PRGCRC, + COLUMN_INFO, + COLUMN_DB, + COLUMN_TITLE, + COLUMN_COUNTRY, + COLUMN_MANUFACTURER, + COLUMN_SALEDATE, + COLUMN_PRICE, + COLUMN_GENRE, + }; + + static INT CALLBACK ListViewCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ); + + void ResetListViewHeader(); + void ResetFileList(); + void ResetListView(); + void SetListView( INT index, FILELIST& fl ); + void SortListView(); + + void SetLastSelect(); + + void OnUpdateStart(); + void OnUpdateStop(); + void UpdateListView(); + + void CheckFile( FILELIST& fl ); + + void OnUpdateMenu( HMENU hMenu, UINT uID ); + + BOOL LoadFileList(); + void SaveFileList(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnDestroy( DLGMSGPARAM ); + DLGMSG OnClose( DLGMSGPARAM ); + DLGMSG OnActivate( DLGMSGPARAM ); + DLGMSG OnSetCursor( DLGMSGPARAM ); + DLGMSG OnSize( DLGMSGPARAM ); + DLGMSG OnTimer( DLGMSGPARAM ); + DLGMSG OnInitMenuPopup( DLGMSGPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + + DLGCMD OnListSelect( DLGCMDPARAM ); + + DLGCMD OnRefresh( DLGCMDPARAM ); + + DLGCMD OnDispEdit( DLGCMDPARAM ); + DLGCMD OnFolder( DLGCMDPARAM ); + DLGCMD OnHeaderEdit( DLGCMDPARAM ); + + DLGNOTIFY OnKeyDownListView( DLGNOTIFYPARAM ); + DLGNOTIFY OnReturnListView( DLGNOTIFYPARAM ); + DLGNOTIFY OnDoubleClickListView( DLGNOTIFYPARAM ); + DLGNOTIFY OnColumnClickListView( DLGNOTIFYPARAM ); + DLGNOTIFY OnItemChangedListView( DLGNOTIFYPARAM ); + // + + // Image List + HIMAGELIST m_hImageList; + HIMAGELIST m_hImageListHdr; // sort + + // + BOOL m_bFileLoaded; + + // `[Xgԍ + INT m_nListSelect; + + INT m_nSortType; + INT m_SelectPos; + + INT m_UpdatePos; + BOOL m_bUpdate; + volatile BOOL m_bUpdating; + INT m_nTimerID; + INT m_nUpdateIndex; + + // Sort type + static BOOL m_bSortDir; + + // File list + static INT m_FileListNum; + static vector m_FileList; + + // Path + static CHAR m_LaunchPath[_MAX_PATH]; +private: +}; + +class CLchDispEditDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnAdd( DLGCMDPARAM ); + DLGCMD OnDel( DLGCMDPARAM ); + DLGCMD OnUp( DLGCMDPARAM ); + DLGCMD OnDown( DLGCMDPARAM ); + // + + // Temp + INT m_nViewOrder[16]; + INT m_nViewNum; + INT m_nHideOrder[16]; + INT m_nHideNum; +private: +}; + +class CLchFolderConfigDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnAdd( DLGCMDPARAM ); + DLGCMD OnDel( DLGCMDPARAM ); + // +private: +}; + +class CLchHeaderEditDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + + INT m_nMapperNo; + BOOL m_bMirror; + BOOL m_bSram; + BOOL m_bTrainer; + BOOL m_bFourScreen; + BOOL m_bVSUnisystem; + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // +private: +}; + +#endif // !__CLAUNCHERDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/MMTimer.cpp b/References/VirtuaNESex_src_191105/MMTimer.cpp new file mode 100644 index 00000000..ee0a756e --- /dev/null +++ b/References/VirtuaNESex_src_191105/MMTimer.cpp @@ -0,0 +1,58 @@ +// +// Multimedia timer support +// +#include "DebugOut.h" +#include "MMTimer.h" + +// RXgN^/fXgN^ׂ̈̃CX^X +static CMMTimer MMTimer; + +BOOL CMMTimer::m_bInitialize = FALSE; + +BOOL CMMTimer::m_bHigh = FALSE; +SQWORD CMMTimer::m_hpFrequency = 0; + +CMMTimer::CMMTimer() +{ + // 1msPʂۏ؂ׂɌĂԁcȂ񂿂イdl + if( !m_bInitialize ) { + if( ::timeBeginPeriod( 1 ) == TIMERR_NOERROR ) + m_bInitialize = TRUE; + } + + // nCptH[}XJE^ł̎Ԍvp + if( ::QueryPerformanceFrequency( (LARGE_INTEGER*)&m_hpFrequency ) ) { + DEBUGOUT( "CMMTimer:Use high performance counter.(QueryPerformanceCounter)\n" ); + m_bHigh = TRUE; + } +} + +CMMTimer::~CMMTimer() +{ + if( m_bInitialize ) { + ::timeEndPeriod( 1 ); + m_bInitialize = FALSE; + } +} + +SQWORD CMMTimer::GetMMTimer() +{ + if( m_bHigh ) { + SQWORD freq; + ::QueryPerformanceCounter( (LARGE_INTEGER*)&freq ); + + return freq; + } + + return (SQWORD)::timeGetTime(); +} + +FLOAT CMMTimer::CalcTimeDifference( SQWORD t0, SQWORD t1 ) +{ + if( m_bHigh ) { + return (FLOAT)(1000.0*(double)(t1-t0)/(double)m_hpFrequency); + } + + return (FLOAT)(t1-t0)*1000.0f; +} + diff --git a/References/VirtuaNESex_src_191105/MMTimer.h b/References/VirtuaNESex_src_191105/MMTimer.h new file mode 100644 index 00000000..0cf125e3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MMTimer.h @@ -0,0 +1,32 @@ +// +// Multimedia timer support +// +#ifndef __CMMTIMER_INCLUDED__ +#define __CMMTIMER_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include "typedef.h" + +class CMMTimer +{ +public: + CMMTimer(); + ~CMMTimer(); + + static SQWORD GetMMTimer(); + static FLOAT CalcTimeDifference( SQWORD t0, SQWORD t1 ); + +protected: +private: + static BOOL m_bInitialize; + + // \JE^𗘗po邩ǂ̃tO + static BOOL m_bHigh; + // \JE^g + static SQWORD m_hpFrequency; +}; + +#endif // !__CMMTIMER_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Macro.h b/References/VirtuaNESex_src_191105/Macro.h new file mode 100644 index 00000000..94a593dd --- /dev/null +++ b/References/VirtuaNESex_src_191105/Macro.h @@ -0,0 +1,23 @@ +// +// ֗mȂ}N +// +#ifndef __MACRO_INCLUDED__ +#define __MACRO_INCLUDED__ + +// dĂяoΉ}N +#define DELETEPTR(x) if(x) { delete x; x = NULL; } +#define DELETEARR(x) if(x) { delete[] x; x = NULL; } +#define RELEASE(x) if(x) { x->Release(); x=NULL; } +#define FREE(x) if(x) { free(x); x=NULL; } +#define FCLOSE(x) if(x) { fclose(x); x=NULL; } +#define GDIDELETE(x) if(x) { ::DeleteObject(x); x=NULL; } +#define CLOSEHANDLE(x) if(x) { ::CloseHandle(x); x = NULL; } + +// ̑ +#define ZEROMEMORY(p,s) ::memset( (p), 0, (s) ) + +// RECT\̗p +#define RCWIDTH(rc) ((rc).right-(rc).left) +#define RCHEIGHT(rc) ((rc).bottom-(rc).top) + +#endif // !__MACRO_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/MainFrame.cpp b/References/VirtuaNESex_src_191105/MainFrame.cpp new file mode 100644 index 00000000..a09ef976 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MainFrame.cpp @@ -0,0 +1,3169 @@ +// +// CEChENX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Plugin.h" + +#include "Wnd.h" +#include "WndHook.h" +#include "MainFrame.h" +#include "Recent.h" +#include "Config.h" + +#include "NetPlay.h" + +#include "AboutDlg.h" +#include "EmulatorDlg.h" +#include "GraphicsDlg.h" +#include "SoundDlg.h" +#include "ControllerDlg.h" +#include "ShortcutDlg.h" +#include "FolderDlg.h" +#include "LanguageDlg.h" +#include "MovieDlg.h" +#include "GameOptionDlg.h" +#include "JoyAxisDlg.h" +#include "RomInfoDlg.h" +#include "NetPlayDlg.h" +#include "MovieInfoDlg.h" + +#include "DirectDraw.h" +#include "DirectSound.h" +#include "DirectInput.h" + +#include "nes.h" +#include "rom.h" +#include "romdb.h" +#include "pad.h" + +BOOL CMainFrame::m_bKeyEnable = FALSE; +volatile BOOL CMainFrame::m_bKeyThreadExit = FALSE; + +DWORD CMainFrame::m_dwKeyTime = 0; +BYTE CMainFrame::m_KeyBuf[256+64*8]; +BYTE CMainFrame::m_KeyOld[256+64*8]; +BYTE CMainFrame::m_KeyCnt[256*64*8]; + +// bZ[W}bv +WND_MESSAGE_BEGIN(CMainFrame) +// bZ[W +WND_ON_MESSAGE( WM_CREATE, OnCreate ) +WND_ON_MESSAGE( WM_CLOSE, OnClose ) +WND_ON_MESSAGE( WM_DESTROY, OnDestroy ) +WND_ON_MESSAGE( WM_GETMINMAXINFO, OnGetMinMaxInfo ) +WND_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +WND_ON_MESSAGE( WM_ACTIVATEAPP, OnActivateApp ) +WND_ON_MESSAGE( WM_VNS_SHORTCUTENABLE, OnShortCutEnable ) +WND_ON_MESSAGE( WM_ENABLE, OnEnable ) +WND_ON_MESSAGE( WM_ENTERMENULOOP, OnEnterMenuLoop ) +WND_ON_MESSAGE( WM_EXITMENULOOP, OnExitMenuLoop ) +WND_ON_MESSAGE( WM_SETFOCUS, OnSetFocus ) +WND_ON_MESSAGE( WM_KILLFOCUS, OnKillFocus ) +WND_ON_MESSAGE( WM_INITMENU, OnInitMenu ) +WND_ON_MESSAGE( WM_INITMENUPOPUP, OnInitMenuPopup ) +WND_ON_MESSAGE( WM_PAINT, OnPaint ) +WND_ON_MESSAGE( WM_DISPLAYCHANGE, OnDisplayChange ) +WND_ON_MESSAGE( WM_PALETTECHANGED, OnPaletteChanged ) +WND_ON_MESSAGE( WM_QUERYNEWPALETTE, OnQueryNewPalette ) +WND_ON_MESSAGE( WM_MENUCHAR, OnMenuChar ) +WND_ON_MESSAGE( WM_KEYDOWN, OnKeyDown ) +WND_ON_MESSAGE( WM_SIZE, OnSize ) +WND_ON_MESSAGE( WM_SYSCOMMAND, OnSysCommand ) +WND_ON_MESSAGE( WM_EXITSIZEMOVE, OnExitSizeMove ) + +WND_ON_MESSAGE( WM_SETCURSOR, OnSetCursor ) +WND_ON_MESSAGE( WM_TIMER, OnTimer ) + +WND_ON_MESSAGE( WM_COPYDATA, OnCopyData ) + +WND_ON_MESSAGE( WM_VNS_ERRORMSG, OnErrorMessage ) + +WND_ON_MESSAGE( WM_DROPFILES, OnDropFiles ) +WND_ON_MESSAGE( WM_VNS_COMMANDLINE, OnCommandLine ) +WND_ON_MESSAGE( WM_VNS_LAUNCHERCMD, OnLauncherCommand ) + +WND_ON_MESSAGE( WM_NETPLAY, OnNetPlay ) +WND_ON_MESSAGE( WM_NETPLAY_CLOSE, OnNetPlayClose ) +WND_ON_MESSAGE( WM_NETPLAY_ERROR, OnNetPlayError ) +WND_ON_MESSAGE( WM_VNS_CHATPOPUP, OnNetPlayChatPopup ) + +// R}h +WND_COMMAND_BEGIN() +WND_ON_COMMAND( ID_EXIT, OnExit ) +WND_ON_COMMAND( ID_HTMLHELP, OnHelp ) +WND_ON_COMMAND( ID_ABOUT, OnAbout ) +WND_ON_COMMAND( ID_OPEN, OnFileOpen ) +WND_ON_COMMAND( ID_CLOSE, OnFileClose ) +WND_ON_COMMAND( ID_ROMINFO, OnRomInfo ) +WND_ON_COMMAND( ID_WAVERECORD, OnWaveRecord ) +WND_ON_COMMAND( ID_LAUNCHER, OnLauncher ) +WND_ON_COMMAND_RANGE( ID_MRU_PATH0, ID_MRU_PATH9, OnRecentOpenPath ) +WND_ON_COMMAND_RANGE( ID_MRU_FILE0, ID_MRU_FILE9, OnRecentOpen ) + +WND_ON_COMMAND( ID_NETPLAY_CONNECT, OnNetPlayConnect ) +WND_ON_COMMAND( ID_NETPLAY_DISCONNECT, OnNetPlayDisconnect ) +WND_ON_COMMAND( ID_NETPLAY_CHAT, OnNetPlayChat ) + +WND_ON_COMMAND( ID_CFG_EMULATOR, OnEmulatorCfg ) +WND_ON_COMMAND( ID_CFG_GRAPHICS, OnGraphicsCfg ) +WND_ON_COMMAND( ID_CFG_SOUND, OnSoundCfg ) +WND_ON_COMMAND( ID_CFG_CONTROLLER, OnControllerCfg ) +WND_ON_COMMAND( ID_CFG_SHORTCUT, OnShortcutCfg ) +WND_ON_COMMAND( ID_CFG_FOLDER, OnFolderCfg ) +WND_ON_COMMAND( ID_CFG_LANGUAGE, OnLanguageCfg ) +WND_ON_COMMAND( ID_CFG_MOVIE, OnMovieCfg ) +WND_ON_COMMAND( ID_CFG_GAMEOPTION, OnGameOptionCfg ) +WND_ON_COMMAND( ID_CFG_JOYAXIS, OnJoyAxisCfg ) +WND_ON_COMMAND( ID_CFG_PALETTE, OnPaletteEditCfg ) + +WND_ON_COMMAND( ID_SEARCH, OnSearch ) +WND_ON_COMMAND( ID_CHEAT, OnCheat ) +WND_ON_COMMAND_RANGE( ID_CHEAT_ENABLE, ID_CHEAT_DISABLE, OnCheatCommand ) +WND_ON_COMMAND( ID_GENIE, OnGenie ) + +WND_ON_COMMAND( ID_BARCODEBATTLER, OnDatachBacode ) +WND_ON_COMMAND( ID_VSUNISYSTEM_DIPSWITCH, OnDipSwitch ) + +WND_ON_COMMAND( ID_FULLSCREEN, OnFullScreen ) +WND_ON_COMMAND_RANGE( ID_ZOOMx1, ID_ZOOMx4, OnZoom ) +WND_ON_COMMAND( ID_HWRESET, OnEmuCommand ) +WND_ON_COMMAND( ID_SWRESET, OnEmuCommand ) +WND_ON_COMMAND( ID_PAUSE, OnEmuCommand ) +WND_ON_COMMAND( ID_THROTTLE, OnEmuCommand ) +WND_ON_COMMAND( ID_STATE_UP, OnEmuCommand ) +WND_ON_COMMAND( ID_STATE_DOWN, OnEmuCommand ) +WND_ON_COMMAND( ID_FPSDISP, OnEmuCommand ) +WND_ON_COMMAND( ID_TVASPECT, OnEmuCommand ) +WND_ON_COMMAND( ID_TVFRAME, OnEmuCommand ) +WND_ON_COMMAND( ID_SCANLINE, OnEmuCommand ) +WND_ON_COMMAND( ID_ALLLINE, OnEmuCommand ) +WND_ON_COMMAND( ID_ALLSPRITE, OnEmuCommand ) +WND_ON_COMMAND( ID_SYNCDRAW, OnEmuCommand ) +WND_ON_COMMAND( ID_FITSCREEN, OnEmuCommand ) +WND_ON_COMMAND( ID_SNAPSHOT, OnEmuCommand ) + +WND_ON_COMMAND( ID_LEFTCLIP, OnEmuCommand ) +WND_ON_COMMAND( ID_ONEFRAME, OnEmuCommand ) + +WND_ON_COMMAND( ID_STATE_LOAD, OnStateCommand ) +WND_ON_COMMAND( ID_STATE_SAVE, OnStateCommand ) + +WND_ON_COMMAND( ID_MOVIE_PLAY, OnMovieCommand ) +WND_ON_COMMAND( ID_MOVIE_REC, OnMovieCommand ) +WND_ON_COMMAND( ID_MOVIE_REC_APPEND, OnMovieCommand ) +WND_ON_COMMAND( ID_MOVIE_STOP, OnMovieCommand ) +WND_ON_COMMAND( ID_MOVIE_INFO, OnMovieInfo ) + +WND_ON_COMMAND( ID_TAPE_PLAY, OnTapeCommand ) +WND_ON_COMMAND( ID_TAPE_REC, OnTapeCommand ) +WND_ON_COMMAND( ID_TAPE_STOP, OnTapeCommand ) + +WND_ON_COMMAND( ID_FRAMESKIP_AUTO, OnEmuCommand ) +WND_ON_COMMAND( ID_FRAMESKIP_UP, OnEmuCommand ) +WND_ON_COMMAND( ID_FRAMESKIP_DOWN, OnEmuCommand ) + +// Viewers +WND_ON_COMMAND( ID_VIEW_PATTERN, OnViewCommand ) +WND_ON_COMMAND( ID_VIEW_NAMETABLE, OnViewCommand ) +WND_ON_COMMAND( ID_VIEW_PALETTE, OnViewCommand ) +WND_ON_COMMAND( ID_VIEW_MEMORY, OnViewCommand ) + +// +WND_ON_COMMAND_RANGE( ID_FILTER_NONE, ID_FILTER_END, OnEmuCommand ) + +WND_ON_COMMAND_RANGE( ID_STATE_SLOT0, ID_STATE_SLOT9, OnEmuCommand ) +WND_ON_COMMAND_RANGE( ID_DISK_EJECT, ID_DISK_1B, OnEmuCommand ) +//WND_ON_COMMAND_RANGE( ID_EXCTR_NONE, ID_EXCTR_END, OnEmuCommand ) +WND_ON_COMMAND_RANGE( ID_EXCTR_SUBOR_KEYBOARD, ID_EXCTR_END, OnEmuCommand ) +WND_ON_COMMAND_RANGE( ID_MUTE_0, ID_MUTE_F, OnEmuCommand ) +WND_ON_COMMAND_RANGE( ID_TURBOFILE_BANK0, ID_TURBOFILE_BANK3, OnEmuCommand ) + +WND_ON_COMMAND_RANGE( ID_QUICKLOAD_SLOT0, ID_QUICKLOAD_SLOT9, OnStateCommand2 ) +WND_ON_COMMAND_RANGE( ID_QUICKSAVE_SLOT0, ID_QUICKSAVE_SLOT9, OnStateCommand2 ) + +WND_COMMAND_END() +WND_MESSAGE_END() + +BOOL CMainFrame::Create( HWND hWndParent ) +{ + // NESIuWFNg + Nes = NULL; + + // oϐ + m_hMenu = NULL; + + WNDCLASSEX wcl; + ZEROMEMORY( &wcl, sizeof(wcl) ); + wcl.cbSize = sizeof(wcl); + wcl.lpszClassName = "VirtuaNESwndclass"; + wcl.lpfnWndProc = g_WndProc; +// wcl.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wcl.style = CS_DBLCLKS; + wcl.cbClsExtra = wcl.cbWndExtra = 0; + wcl.hInstance = CApp::GetInstance(); + wcl.lpszMenuName = NULL; + wcl.hIcon = + wcl.hIconSm = ::LoadIcon( CApp::GetInstance(), MAKEINTRESOURCE(IDI_ICON) ); + wcl.hCursor = ::LoadCursor( NULL, IDC_ARROW ); + wcl.hbrBackground = 0; + + if( !RegisterClassEx( &wcl ) ) { +// DEBUGOUT( "RegisterClassEx faild.\n" ); + return FALSE; + } + + HWND hWnd = CreateWindowEx( + WS_EX_CLIENTEDGE, + VIRTUANES_WNDCLASS, + VIRTUANES_CAPTION, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + hWndParent, + NULL, + CApp::GetInstance(), + (LPVOID)this // This 𖄂ߍވ + ); + if( !hWnd ) { +// DEBUGOUT( "CreateWindow faild.\n" ); + return FALSE; + } + + // CEChEƂēo^ + CApp::SetHWnd( hWnd ); + + // Xe[gXbg + m_nStateSlot = 0; + + return TRUE; +} + +void CMainFrame::Destroy() +{ + if( m_hWnd && IsWindow(m_hWnd) ) { + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +BOOL CMainFrame::PreTranslateMessage( MSG* pMsg ) +{ + if( pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST ) { +// return TRUE; + } + return FALSE; +} + +WNDMSG CMainFrame::OnCreate( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnCreate\n" ); + + DirectDraw.SetSystemMemory( Config.graphics.bSystemMemory ); + DirectDraw.SetUseHEL ( Config.graphics.bUseHEL ); + + if( !DirectDraw.InitialDDraw( m_hWnd ) ) { + hResult = -1L; + return TRUE; + } + if( !DirectSound.InitialDSound( m_hWnd ) ) { + hResult = -1L; + return TRUE; + } + if( !DirectInput.InitialDInput( m_hWnd, CApp::GetInstance() ) ) { + hResult = -1L; + return TRUE; + } + // DirectDraw߼݂̐ݒ + DirectDraw.SetFlipMode ( Config.graphics.bSyncDraw ); + DirectDraw.SetAspectMode ( Config.graphics.bAspect ); + DirectDraw.SetAllLineMode ( Config.graphics.bAllLine ); + DirectDraw.SetMaxZoom ( Config.graphics.bFitZoom ); + DirectDraw.SetTVFrameMode ( Config.graphics.bTVFrame ); + DirectDraw.SetScanlineMode ( Config.graphics.bScanline ); + DirectDraw.SetScanlineColor( Config.graphics.nScanlineColor ); + + DirectDraw.SetWindowVSyncMode( Config.graphics.bWindowVSync ); + + DirectDraw.SetDoubleSize( Config.graphics.bDoubleSize ); + DirectDraw.SetGraphicsFilter( Config.graphics.nGraphicsFilter ); + + // DirectDrawT[tFX̍\z + if( !DirectDraw.InitialSurface( FALSE ) ) { + hResult = -1L; + return TRUE; + } + + // pbgt@C̃[h + if( Config.graphics.bPaletteFile ) { + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.graphics.szPaletteFile ); + DirectDraw.SetPaletteFile( pathstr.c_str() ); + } + + // DirectSound߼݂̐ݒ + DirectSound.SetSamplingRate( Config.sound.nRate, Config.sound.nBits ); + DirectSound.SetBufferSize( Config.sound.nBufferSize ); + + // ExtraSoundFilẽ[h + for( INT i = 0; i < ESF_FILE_MAX; i++ ) { + string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.extsound.szExtSoundFile[i] ); + DirectSound.LoadEsf( pathstr.c_str(), i ); + } + + // DirectInput߼݂̐ݒ + DirectInput.SetJoyAxisMode( Config.general.JoyAxisSetting ); + + // DirectSoundobt@̍\z + if( !DirectSound.InitialBuffer() ) { + hResult = -1L; + return TRUE; + } + + // pbge[ǔvZ + DirectDraw.CalcPaletteTable(); + + // lbgvC + NetPlay.Initialize( m_hWnd ); + + // j[̃[h + m_hMenu = CApp::LoadMenu( IDR_MENU ); + CApp::SetMenu( m_hMenu ); + ::SetMenu( m_hWnd, m_hMenu ); + m_bMenu = TRUE; // j[\tO + + // j[ɃANZ[^L[̒lj + OnRebuildMenu(); + + // EChEʒu̐ݒ + RECT rc = Config.general.rcWindowPos; + if( !((rc.right-rc.left) <= 0 || (rc.bottom-rc.top) <= 0) ) { + if( (m_bZoomed = Config.general.bWindowZoom) ) { + CApp::SetCmdShow( SW_SHOWMAXIMIZED ); + } + // ۑĂEChETCYɂ + m_WindowRect = rc; + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, rc.left, rc.top, + rc.right-rc.left, rc.bottom-rc.top, 0 ); + } else { + m_bZoomed = FALSE; + // ftHgTCY𒲐 + OnSetWindowSize(); + } + + // EChEX^C̕ۑ + m_StyleBackup = ::GetWindowLong( m_hWnd, GWL_STYLE ); + m_ExStyleBackup = ::GetWindowLong( m_hWnd, GWL_EXSTYLE ); + + // IMEgp֎~:D + ::ImmAssociateContext( m_hWnd, NULL ); + + // Drag&Drop̋ + ::DragAcceptFiles( m_hWnd, TRUE ); + + // tO + m_bActivate = TRUE; + m_bActivateApp = TRUE; + m_bForcus = TRUE; + m_bCursor = TRUE; + m_bEnable = TRUE; + m_bKeyEnable = TRUE; + m_bKeyChecking = FALSE; + m_LastMovedTime = 0; + + m_uTimerID = ::SetTimer( m_hWnd, 0x0001, 1000, NULL ); +// m_uKeyTimerID = ::SetTimer( m_hWnd, 0x0100, 30, NULL ); // 30ms + + m_dwKeyTime = 0; + + // Key Thread + ::memset( m_KeyBuf, 0x00, sizeof(m_KeyBuf) ); + ::memset( m_KeyOld, 0x00, sizeof(m_KeyBuf) ); + ::memset( m_KeyCnt, 0x00, sizeof(m_KeyCnt) ); + + ::_beginthread( KeyThreadProc, 0, NULL ); + + ZEROMEMORY( m_KeyBuf, sizeof(m_KeyBuf) ); + ZEROMEMORY( m_KeyCnt, sizeof(m_KeyCnt) ); + +#if 0 + // For Command Lines + if( ::strlen( CApp::GetCmdLine() ) > 0 ) { + LPSTR pCmd = CApp::GetCmdLine(); + if( pCmd[0] == '"' ) { // Shell execute!! + ZEROMEMORY( m_szCommandLine, sizeof(m_szCommandLine) ); + ::memcpy( m_szCommandLine, pCmd+1, ::strlen(pCmd)-2 ); + m_szCommandLine[::strlen(m_szCommandLine)] = '\0'; + } else { + ::strcpy( m_szCommandLine, pCmd ); + } + ::PostMessage( m_hWnd, WM_VNS_COMMANDLINE, 0, 0L ); + } +#endif + return FALSE; +} + +WNDMSG CMainFrame::OnClose( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnClose\n" ); + + // lbgvC + NetPlay.Release(); + + // G~[VI + Emu.Stop(); + DELETEPTR( Nes ); + + // L[XbhI + m_bKeyThreadExit = TRUE; + + // ^C}[̏I + ::KillTimer( m_hWnd, m_uTimerID ); +// ::KillTimer( m_hWnd, m_uKeyTimerID ); + m_uTimerID = 0; + m_uKeyTimerID = 0; + + // EChEj + ::DestroyWindow( m_hWnd ); + + // T[`_CAOI + m_SearchDlg.Destroy(); + + // `[I + m_LauncherDlg.Destroy(); + + // `bgI + m_ChatDlg.Destroy(); + + // p^[rAI + m_PatternView.Destroy(); + m_NameTableView.Destroy(); + m_PaletteView.Destroy(); + m_MemoryView.Destroy(); + + // o[R[h̓_CAOI + m_DatachBarcodeDlg.Destroy(); + + // pbgҏW̏I + m_PaletteEdit.Destroy(); + + // EChEʒu̕ۑ + Config.general.bWindowZoom = m_bZoomed; + Config.general.rcWindowPos = m_WindowRect; + + ::DragAcceptFiles( m_hWnd, FALSE ); + + return FALSE; +} + +WNDMSG CMainFrame::OnDestroy( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnDestroy\n" ); + + ::PostQuitMessage( 0 ); + return FALSE; +} + +WNDMSG CMainFrame::OnGetMinMaxInfo( WNDMSGPARAM ) +{ + MINMAXINFO* lpMMI = (MINMAXINFO*)lParam; + + // ŏTCY + lpMMI->ptMinTrackSize.x = 128; + lpMMI->ptMinTrackSize.y = 128; +// lpMMI->ptMaxTrackSize.x = 65535; +// lpMMI->ptMaxTrackSize.y = 65535; + + return TRUE; +} + +WNDMSG CMainFrame::OnActivate( WNDMSGPARAM ) +{ +//DEBUGOUT( "WA_ACTIVATE: Minimized:%s Prev:%08X This:%08X\n", HIWORD(wParam)?"TRUE":"FALSE", lParam, m_hWnd ); + +#if 1 + if( HIWORD(wParam) || (LOWORD(wParam) == WA_INACTIVE && !lParam) ) { + if( m_bActivate ) { +// DEBUGOUT( "Inactivate.\n" ); + m_bActivate = FALSE; + // obNOEhONlbgvC̓|[YȂ + if( !(Config.emulator.bBackground || NetPlay.IsConnect()) ) { + Emu.Pause(); + } + } + // DirectInput + DirectInput.Unacquire(); + } else if( !lParam ) { +// DEBUGOUT( "Activate.\n" ); + m_bActivate = TRUE; + // obNOEhONlbgvC̓W[Ȃ + if( !(Config.emulator.bBackground || NetPlay.IsConnect()) ) { + Emu.Resume(); + } + // DirectInputL + DirectInput.Acquire(); + } +#else + if( LOWORD(wParam) == WA_INACTIVE ) { +// DEBUGOUT( "WM_ACTIVATE: WA_INACTIVE\n" ); +//// DEBUGOUT( "CMainFrame::OnActivate:Inactive\n" ); + m_bActivate = FALSE; +//// m_bActivate = TRUE; + } else if( LOWORD(wParam) == WA_ACTIVE ) { +// DEBUGOUT( "WM_ACTIVATE: WA_ACTIVE\n" ); +//// DEBUGOUT( "CMainFrame::OnActivate:Active\n" ); + m_bActivate = TRUE; + } else if( LOWORD(wParam) == WA_CLICKACTIVE ) { +// DEBUGOUT( "WM_ACTIVATE: WA_CLICKACTIVE\n" ); +//// DEBUGOUT( "CMainFrame::OnActivate:ClickActive\n" ); + m_bActivate = TRUE; + } +#endif + return FALSE; +} + +WNDMSG CMainFrame::OnActivateApp( WNDMSGPARAM ) +{ +//DEBUGOUT( "wParam:%08X lParam:%08X\n", wParam, lParam ); + +#if 0 + if( (BOOL)wParam ) { +// DEBUGOUT( "CMainFrame::OnActivateApp:Active\n" ); + m_bActivateApp = TRUE; + // obNOEhONlbgvC̓W[Ȃ + if( !(Config.emulator.bBackground || NetPlay.IsConnect()) ) { + Emu.Resume(); + } + DirectInput.Acquire(); + } else { +// DEBUGOUT( "CMainFrame::OnActivateApp:Inactive\n" ); + if( m_bActivateApp ) { + m_bActivateApp = FALSE; + // obNOEhONlbgvC̓|[YȂ + if( !(Config.emulator.bBackground || NetPlay.IsConnect()) ) { + Emu.Pause(); + } + } + DirectInput.Unacquire(); + } +#else + if( (BOOL)wParam ) { +// DEBUGOUT( "CMainFrame::OnActivateApp:Active\n" ); + m_bActivateApp = TRUE; + if( !m_bActivate ) { + m_bActivate = TRUE; + // obNOEhONlbgvC̓W[Ȃ + if( !(Config.emulator.bBackground || NetPlay.IsConnect()) ) { + Emu.Resume(); + } + } + DirectInput.Acquire(); + } else { +// DEBUGOUT( "CMainFrame::OnActivateApp:Inactive\n" ); + m_bActivateApp = FALSE; + if( m_bActivate ) { + m_bActivate = FALSE; + // obNOEhONlbgvC̓|[YȂ + if( !(Config.emulator.bBackground || NetPlay.IsConnect()) ) { + Emu.Pause(); + } + } + DirectInput.Unacquire(); + } +#endif + return FALSE; +} + +WNDMSG CMainFrame::OnShortCutEnable( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnShortCutmode Req=%s\n", (BOOL)wParam?"TRUE":"FALSE" ); + + if( (BOOL)wParam ) { + if( m_bEnable ) { + m_bKeyEnable = TRUE; +//DEBUGOUT( "CMainFrame::OnShortCutmode TRUE\n" ); + } + } else { + m_bKeyEnable = FALSE; +//DEBUGOUT( "CMainFrame::OnShortCutmode FALSE\n" ); + } +// m_bKeyEnable = (BOOL)wParam; + +#if 0 + if( (BOOL)wParam ) { + if( --m_nKeyDisableCount < 0 ) { + m_bKeyEnable = TRUE; + } + } else { + m_nKeyDisableCount++; + m_bKeyEnable = FALSE; + } +#endif + return FALSE; +} + +WNDMSG CMainFrame::OnEnable( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnEnable = %s\n", (BOOL)wParam?"TRUE":"FALSE" ); + + if( (BOOL)wParam ) + Emu.Resume(); + else + Emu.Pause(); + + m_bEnable = (BOOL)wParam; + m_bKeyEnable = (BOOL)wParam; + + return FALSE; +} + +WNDMSG CMainFrame::OnEnterMenuLoop( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnEnterMenuLoop\n" ); + m_bKeyEnable = FALSE; + Emu.Pause(); + return FALSE; +} + +WNDMSG CMainFrame::OnExitMenuLoop( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnExitMenuLoop\n" ); + m_bKeyEnable = TRUE; + Emu.Resume(); + return FALSE; +} + +WNDMSG CMainFrame::OnSetFocus( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnSetFocus\n" ); + m_bForcus = TRUE; + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + if( !m_bMenu ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, FALSE ); + } + } + } + return FALSE; +} + +WNDMSG CMainFrame::OnKillFocus( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnKillFocus\n" ); + m_bForcus = FALSE; + return FALSE; +} + +WNDMSG CMainFrame::OnInitMenu( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnInitMenu\n" ); + CRecent::UpdateMenu( CApp::GetMenu() ); + DrawMenuBar( m_hWnd ); + return FALSE; +} + +WNDMSG CMainFrame::OnInitMenuPopup( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnInitMenuPopup\n" ); + // System menu + if( (BOOL)HIWORD(lParam) ) + return FALSE; + +// DEBUGOUT( "SubMenu=%08X uPos=%d bSys=%d\n", wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam) ); + + HMENU hMenu = (HMENU)wParam; + + INT MenuCount = ::GetMenuItemCount( hMenu ); + for( INT i = 0; i < MenuCount; i++ ) { + OnUpdateMenu( hMenu, ::GetMenuItemID( hMenu, i ) ); + } + + return FALSE; +} + +WNDMSG CMainFrame::OnPaint( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnPaint\n" ); + HDC hDC; + PAINTSTRUCT ps; + hDC = ::BeginPaint( m_hWnd, &ps ); + if( !Emu.IsRunning() ) { + RECT rc; + ::GetClientRect( m_hWnd, &rc ); + ::SetBkColor( hDC, 0x00000000 ); + ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + } else if( Emu.IsPausing() ) { + DirectDraw.OnScreenDraw(); + } + ::EndPaint( m_hWnd, &ps ); + + return TRUE; +} + +WNDMSG CMainFrame::OnDisplayChange( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnDisplayChange\n" ); + + // tXN[ȂΎŃ`FWALT+TAB؂ւ + if( !Config.general.bScreenMode ) { + // 댯Ȃ̂ŃXbh|[Y + Emu.Pause(); + DirectDraw.OnChangeDisplayMode(); + + // ĕ` + ::InvalidateRect( m_hWnd, NULL, TRUE ); + + // XbhW[ + Emu.Resume(); + } + + return FALSE; +} + +WNDMSG CMainFrame::OnPaletteChanged( WNDMSGPARAM ) +{ + if( (HWND)wParam == m_hWnd ) + return FALSE; + + DirectDraw.RealizePalette(); + return FALSE; +} + +WNDMSG CMainFrame::OnQueryNewPalette( WNDMSGPARAM ) +{ + DirectDraw.RealizePalette(); + return TRUE; +} + +WNDMSG CMainFrame::OnMenuChar( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnMenuChar\n" ); + // LL邳‚cƉR‚ + hResult = MAKELONG(0,MNC_CLOSE); + return TRUE; +} + +WNDMSG CMainFrame::OnKeyDown( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnKeyDown\n" ); + + if( Config.general.bScreenMode ) { + if( wParam == VK_ESCAPE && (lParam & (1<<30)) == 0 ) { + OnChangeMenu( !m_bMenu ); + return TRUE; + } + } + + return FALSE; +} + +WNDMSG CMainFrame::OnSize( WNDMSGPARAM ) +{ + // ő剻\ + // WM_SYSCOMMANDłǂ̂CLvV_uNbNƂɗȂ̂... + switch( wParam ) { + case SIZE_MAXIMIZED: + m_bZoomed = TRUE; + { + WINDOWPLACEMENT wpl; + ::GetWindowPlacement( m_hWnd, &wpl ); + m_WindowRect = wpl.rcNormalPosition; // ̈ʒuRs[ + } + break; + case SIZE_RESTORED: + m_bZoomed = FALSE; + break; + default: + break; + } + + return FALSE; +} + +WNDMSG CMainFrame::OnSysCommand( WNDMSGPARAM ) +{ + // G~[V̂ + if( Emu.IsRunning() ) { + // XN[Z[o[̋N̗}~ + if( wParam == SC_SCREENSAVE ) { +// DEBUGOUT( "CMainFrame::OnSysCommand SC_SCREENSAVE\n" ); + hResult = 1L; + return TRUE; + } + // fBXvCdIt̗}~ + if( wParam == SC_MONITORPOWER ) { +// DEBUGOUT( "CMainFrame::OnSysCommand SC_MONITORPOWER\n" ); + hResult = 1L; + return TRUE; + } + } + + return FALSE; +} + +WNDMSG CMainFrame::OnExitSizeMove( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnExitSizeMove\n" ); + + if( !Config.general.bScreenMode ) { + ::GetWindowRect( m_hWnd, &m_WindowRect ); + } + + return FALSE; +} + +WNDMSG CMainFrame::OnSetCursor( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnSetCursor\n" ); + if( LOWORD(lParam) == HTCLIENT ) { + if( Emu.IsRunning() ) { +// if( !Emu.IsPausing() && !Emu.IsEmuPausing() ) { + if( !Emu.IsPausing() ) { + if( DirectDraw.GetZapperMode() ) { + m_bCursor = TRUE; + ::SetCursor( NULL ); + hResult = 1L; + return TRUE; + } else { + m_bCursor = FALSE; + m_LastMovedTime = ::timeGetTime(); + } + } else { + m_bCursor = TRUE; + } + } else { + m_bCursor = TRUE; + } + } else { + m_bCursor = TRUE; + } + + return FALSE; +} + +WNDMSG CMainFrame::OnTimer( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnTimer\n" ); +// DEBUGOUT( "CMainFrame::OnTimer bCursor=%s bForcus=%s\n", m_bCursor?"TRUE":"FALSE", m_bForcus?"TRUE":"FALSE" ); + + if( wParam == 0x0001 ) { + // }EXJ[\p^C}[ + RECT rc; + POINT pt; + ::GetWindowRect( m_hWnd, &rc ); + ::GetCursorPos( &pt ); + + if( !m_bCursor && m_bForcus && pt.x >= rc.left && pt.x <= rc.right && pt.y >= rc.top && pt.y <= rc.bottom ) { + if( Emu.IsRunning() && !Emu.IsPausing() ) { + if( (::timeGetTime()-m_LastMovedTime) > 1500 ) { + ::SetCursor( NULL ); + } + } + } + } else if( wParam == 0x0100 ) { + // L[`FbNp^C}[ + // ANeBuEChEłȂ_CAOoĂ鎞̓LZ +//// if( m_bActivate && m_bKeyEnable ) +//// if( m_bKeyEnable ) +// OnKeyControl(); + } + + return FALSE; +} + +WNDMSG CMainFrame::OnCopyData( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnCopyData\n" ); + + COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam; + + OnEmulationStart( (LPSTR)pcds->lpData, FALSE ); + + return TRUE; +} + +WNDMSG CMainFrame::OnErrorMessage( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnErrorMessage\n" ); + + // `bgI + m_ChatDlg.Destroy(); + + // T[`_CAOI + m_SearchDlg.Destroy(); + + // p^[rAI + m_PatternView.Destroy(); + m_NameTableView.Destroy(); + m_PaletteView.Destroy(); + m_MemoryView.Destroy(); + + // o[R[h̓_CAOI + m_DatachBarcodeDlg.Destroy(); + + // NetPlayؒf + NetPlay.Disconnect(); + + // G~[VI + Emu.Stop(); + DELETEPTR( Nes ); + + // LvVς + ::SetWindowText( m_hWnd, VIRTUANES_CAPTION ); + + if( Config.general.bScreenMode ) { + OnFullScreenGDI( TRUE ); + } + + ::MessageBox( m_hWnd, (LPCTSTR)lParam, "ERROR", MB_ICONERROR|MB_OK ); + ::InvalidateRect( m_hWnd, NULL, TRUE ); + + if( Config.general.bScreenMode ) { + OnChangeMenu( TRUE ); + } + + return TRUE; +} + +WNDCMD CMainFrame::OnExit( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnExit\n" ); + + ::PostMessage( m_hWnd, WM_CLOSE, 0, 0 ); +} + +WNDCMD CMainFrame::OnHelp( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnHelp\n" ); + + string sHelp = CPathlib::MakePath( CApp::GetModulePath(), "virtuanes.chm" ); + + // ʓ|ȂShellExecuteőp + ::ShellExecute( HWND_DESKTOP, "open", sHelp.c_str(), NULL, NULL, SW_SHOWNORMAL ); +// ::HtmlHelp( m_hWnd, "virtuanes.chm", HH_DISPLAY_TOPIC, NULL ); +} + +WNDCMD CMainFrame::OnAbout( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnAbout\n" ); + CAboutDlg dlg; + dlg.DoModal( m_hWnd ); +} + +WNDCMD CMainFrame::OnFileOpen( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnFileOpen\n" ); + + if( Emu.IsRunning() ) { + Emu.Pause(); + } + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + OnFullScreenGDI( TRUE ); + } + } + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ZEROMEMORY( szFile, sizeof(szFile) ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + string pathstr; + if( Config.path.bRomPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRomPath ); + } else { + pathstr = CApp::GetModulePath(); + } + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_OPENROM, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "пļ (*.nes,*.unf,*.fds,*.nsf,*.lzh,*.zip,*.7z,*.cab)\0*.nes;*.unf;*.fds;*.nsf;*.lzh;*.zip;*.7z;*.cab\0" + "NES ROM (*.nes,*.unf)\0*.nes*.unf\0" + "FDS ŵ (*.fds)\0*.fds\0" + "NES ļ (*.nsf)\0*.nsf\0" + "ѹļ (*.lzh,*.zip,*.7z,*.cab)\0*.lzh;*.zip;*.7z;*.cab\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = pathstr.c_str(); + + if( ::GetOpenFileName( &ofn ) ) { + OnEmulationStart( szFile, FALSE ); + if( Config.general.bScreenMode && Emu.IsRunning() ) { + OnChangeMenu( FALSE ); + } + } else { + if( Emu.IsRunning() ) { + OnFullScreenGDI( FALSE ); + } + } + while( Emu.IsPausing() ) { + Emu.Resume(); + } +} + +WNDCMD CMainFrame::OnFileClose( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnFileClose\n" ); + + // `bgI + m_ChatDlg.Destroy(); + + // T[`_CAOI + m_SearchDlg.Destroy(); + + // p^[rAI + m_PatternView.Destroy(); + m_NameTableView.Destroy(); + m_PaletteView.Destroy(); + m_MemoryView.Destroy(); + + // o[R[h̓_CAOI + m_DatachBarcodeDlg.Destroy(); + + if( Emu.IsRunning() ) { + Emu.Stop(); + DELETEPTR( Nes ); + + // LvVς + ::SetWindowText( m_hWnd, VIRTUANES_CAPTION ); + + // ĕ` + ::InvalidateRect( m_hWnd, NULL, TRUE ); + } + + if( Config.general.bScreenMode ) { + OnChangeMenu( TRUE ); + } +} + +WNDMSG CMainFrame::OnCommandLine( WNDMSGPARAM ) +{ + OnEmulationStart( (LPSTR)lParam, FALSE ); + + return TRUE; +} + +WNDMSG CMainFrame::OnLauncherCommand( WNDMSGPARAM ) +{ + if( Config.general.bScreenMode ) { + if( m_LauncherDlg.m_hWnd ) { + ::SetWindowPos( m_LauncherDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } + } + ::SetForegroundWindow( m_hWnd ); + + OnEmulationStart( (LPSTR)lParam, FALSE ); + + return TRUE; +} + +WNDMSG CMainFrame::OnNetPlay( WNDMSGPARAM ) +{ + DEBUGOUT( "CMainFrame::OnNetPlay\n" ); + hResult = NetPlay.WndProc( hWnd, wParam, lParam ); + return TRUE; +} + +WNDMSG CMainFrame::OnNetPlayClose( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnNetPlayClose\n" ); + NetPlay.SetMsgWnd( NULL ); + NetPlay.Disconnect(); + + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_NETWORKDISCONNECT ); + ::PostMessage( m_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)szErrStr ); + return TRUE; +} + +WNDMSG CMainFrame::OnNetPlayError( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnNetPlayError\n" ); + NetPlay.SetMsgWnd( NULL ); + NetPlay.Disconnect(); + + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_NETWORKERROR ); + ::PostMessage( m_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)szErrStr ); + return TRUE; +} + +WNDMSG CMainFrame::OnNetPlayChatPopup( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnNetPlayChatPopup\n" ); + DEBUGOUT( "CMainFrame::OnNetPlayChatPopup\n" ); + if( !NetPlay.IsConnect() ) + return TRUE; + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + } else { + DirectDraw.SetFullScreenGDI( TRUE ); + } + // _CAOʊOȂΒɈړ:) + RECT rcParent, rc; + ::GetWindowRect( m_hWnd, &rcParent ); + ::GetWindowRect( m_ChatDlg.m_hWnd, &rc ); + + if( (rc.right < rcParent.left) || (rc.left > rcParent.right) + || (rc.bottom < rcParent.top) || (rc.top > rcParent.bottom) ) { + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; + ::SetWindowPos( m_ChatDlg.m_hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + } else { + ::SetWindowPos( m_ChatDlg.m_hWnd, NULL, 0, 0, -1, -1, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + } + ::SetWindowPos( m_ChatDlg.m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE ); + } else { + ::SetWindowPos( m_ChatDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE ); + } + + return TRUE; +} + +WNDCMD CMainFrame::OnRecentOpen( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnRecentOpen ID=%d\n", uID-ID_MRU_FILE0 ); +// DEBUGOUT( "Fname: \"%s\"\n", CRecent::GetName( (INT)uID-ID_MRU_FILE0 ) ); + + OnEmulationStart( CRecent::GetName( (INT)uID-ID_MRU_FILE0 ), FALSE ); +} + +WNDCMD CMainFrame::OnRecentOpenPath( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnRecentOpenPath ID=%d\n", uID-ID_MRU_FILE0 ); +// DEBUGOUT( "Fname: \"%s\"\n", CRecent::GetPath( (INT)uID-ID_MRU_FILE0 ) ); + + if( Emu.IsRunning() ) { + Emu.Pause(); + } + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + OnFullScreenGDI( TRUE ); + } + } + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ZEROMEMORY( szFile, sizeof(szFile) ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_OPENROM, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "пļ (*.nes,*.unf,*.fds,*.nsf,*.lzh,*.zip,*.7z,*.cab)\0*.nes;*.unf;*.fds;*.nsf;*.lzh;*.zip;*.7z;*.cab\0" + "NES ROM (*.nes,*.unf)\0*.nes*.unf\0" + "FDS ŵ (*.fds)\0*.fds\0" + "NES ļ (*.nsf)\0*.nsf\0" + "ѹļ (*.lzh,*.zip,*.7z,*.cab)\0*.lzh;*.zip;*.7z;*.cab\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = CRecent::GetPath( (INT)uID-ID_MRU_PATH0 ); + + + if( ::GetOpenFileName( &ofn ) ) { + OnEmulationStart( szFile, FALSE ); + } else { + if( Emu.IsRunning() ) { + OnFullScreenGDI( FALSE ); + } + } + while( Emu.IsPausing() ) { + Emu.Resume(); + } +} + +WNDMSG CMainFrame::OnDropFiles( WNDMSGPARAM ) +{ + DEBUGOUT( "CMainFrame::OnDropFiles\n" ); + ::SetForegroundWindow( m_hWnd ); + + CHAR szFile[_MAX_PATH]; + ::DragQueryFile( (HDROP)wParam, 0, szFile, _MAX_PATH ); + ::DragFinish( (HDROP)wParam ); + + INT ret; + if( (ret = ROM::IsRomFile( szFile )) >= 0 ) { +DEBUGOUT( "ROMt@C CHK=%d\n", ret ); + if( ret == IDS_ERROR_ILLEGALHEADER ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return TRUE; + + OnEmulationStart( szFile, TRUE ); + return TRUE; + } else if( ret == 0 ) { + OnEmulationStart( szFile, TRUE ); + return TRUE; + } + } + + if( Emu.IsRunning() && !NetPlay.IsConnect() ) { + if( (ret = NES::IsStateFile( szFile, Nes->rom )) >= 0 ) { +DEBUGOUT( "Xe[gt@C CHK=%d\n", ret ); + if( ret == IDS_ERROR_ILLEGALSTATECRC ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return TRUE; + } + } + Emu.EventParam2( CEmuThread::EV_STATE_LOAD, (INT)szFile, -1 ); + } else + if( (ret = NES::IsMovieFile( szFile, Nes->rom )) >= 0 ) { +DEBUGOUT( "[r[t@C CHK=%d\n", ret ); + if( ret == IDS_ERROR_ILLEGALMOVIEOLD ) { + ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONHAND|MB_OK ); + return TRUE; + } else + if( ret == IDS_ERROR_ILLEGALMOVIEVER ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return TRUE; + } + } else + if( ret == IDS_ERROR_ILLEGALMOVIECRC ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return TRUE; + } + } + Emu.EventParam( CEmuThread::EV_MOVIE_PLAY, (INT)szFile ); + } + } + + return TRUE; +} + +void CMainFrame::OnEmulationStart( LPCSTR szFile, BOOL bChecked ) +{ + // T[`_CAOI + m_SearchDlg.Destroy(); + + // o[R[h̓_CAOI + m_DatachBarcodeDlg.Destroy(); + + // p^[rAI +// m_PatternView.Destroy(); +// m_NameTableView.Destroy(); +// m_PaletteView.Destroy(); +// m_MemoryView.Destroy(); + + // G~[VI +// Emu.Stop(); +// DELETEPTR( Nes ); + + try { + if( !bChecked ) { + INT ret; + if( (ret = ROM::IsRomFile( szFile )) != 0 ) { + // vIȃG[ + if( ret == IDS_ERROR_OPEN ) { + if( ::strlen(Config.path.szRomAutoRunPath ) > 0 ) { + ::wsprintf(Config.path.szRomAutoRunPath, ".\\"); + } + + // xxx t@CJ܂ + ::wsprintf( szErrorString, CApp::GetErrorString(ret), szFile ); + throw szErrorString; + } + if( ret == IDS_ERROR_READ ) { + throw CApp::GetErrorString(ret); + } + if( ret == IDS_ERROR_UNSUPPORTFORMAT ) { + throw CApp::GetErrorString(ret); + } + + // YES/NO`FbN + if( ret == IDS_ERROR_ILLEGALHEADER ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return; + } +// } else { +// throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + } + + // G~[VI + Emu.Stop(); + DELETEPTR( Nes ); + + if( (Nes = new NES(szFile)) ) { + CRecent::Add( szFile ); + + if( Config.general.bScreenMode ) { + DirectDraw.SetFullScreenGDI( FALSE ); + OnChangeMenu( FALSE ); + } else { + if( Config.emulator.bLoadFullscreen ) { + ::PostMessage( m_hWnd, WM_COMMAND, (WPARAM)ID_FULLSCREEN, (LPARAM)0 ); + } + } + + // LvVς + { + string str = VIRTUANES_CAPTION; + str = str + " - " + Nes->rom->GetRomName(); + ::SetWindowText( m_hWnd, str.c_str() ); + } + + // G~[VXbhX^[g + Emu.Start( m_hWnd, Nes ); + } else { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, szFile ); + throw szErrorString; + } + } catch( CHAR* str ) { + ::strcpy( szErrorString, str ); + PostMessage( m_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)szErrorString ); +#ifndef _DEBUG + } catch(...) { + // sȃG[܂ + ::strcpy( szErrorString, CApp::GetErrorString( IDS_ERROR_UNKNOWN ) ); + PostMessage( m_hWnd, WM_VNS_ERRORMSG, 0, (LPARAM)szErrorString ); +#endif + } +} + +WNDCMD CMainFrame::OnRomInfo( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnRomInfo\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + + CRomInfoDlg dlg; + + // o̐ݒ + if(Nes->rom->IsUnifMapper()) + ::strcpy( dlg.m_szName, Nes->rom->GetBoardName() ); + else + ::strcpy( dlg.m_szName, Nes->rom->GetRomName() ); + + dlg.m_nMapper = Nes->rom->GetMapperNo(); + dlg.m_nPRG = Nes->rom->GetPROM_SIZE(); + + //for Game Star - Smart Genius (Unl) + if(Nes->rom->GetPROM_SIZE()==0xff) + dlg.m_nPRG = Nes->rom->GetPROM_SIZE()+1; + + dlg.m_nCHR = Nes->rom->GetVROM_SIZE(); + dlg.m_bMirror = Nes->rom->IsVMIRROR(); + dlg.m_bSram = Nes->rom->IsSAVERAM(); + dlg.m_b4Screen = Nes->rom->Is4SCREEN(); + dlg.m_bTrainer = Nes->rom->IsTRAINER(); + dlg.m_bVSUnisystem = Nes->rom->IsVSUNISYSTEM(); + + if( Nes->rom->GetMapperNo() < 256 && Nes->rom->GetMapperNo() != 20 ) { + dlg.m_dwCRC = Nes->rom->GetPROM_CRC(); + dlg.m_dwCRCALL = Nes->rom->GetROM_CRC(); + dlg.m_dwCRCCHR = Nes->rom->GetVROM_CRC(); + } + if(Nes->rom->IsUnifMapper()){ + dlg.m_dwCRC = Nes->rom->GetPROM_CRC(); + dlg.m_dwCRCCHR = Nes->rom->GetVROM_CRC(); + } + + if( !m_bMenu ) + OnFullScreenGDI( TRUE ); + dlg.DoModal( m_hWnd ); + if( !m_bMenu ) + OnFullScreenGDI( FALSE ); +} + +WNDCMD CMainFrame::OnWaveRecord( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnWaveRecord\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + + if( Emu.IsWaveRecord() ) { + // ^~߂ + Emu.Event( CEmuThread::EV_WAVEREC_STOP ); + } else { + // ߂ĂȂ + string pathstr, tempstr; + if( Config.path.bWavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szWavePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), "wav" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ::strcpy( szFile, tempstr.c_str() ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_WAVERECORD, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.lpstrDefExt = "wav"; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "Wave Files(*.wav)\0*.wav\0All Files(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT; + ofn.lpstrInitialDir = pathstr.c_str(); + + if( !m_bMenu ) + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + + if( ::GetSaveFileName( &ofn ) ) { + Emu.EventParam( CEmuThread::EV_WAVEREC_START, (INT)szFile ); + } + + if( !m_bMenu ) + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, FALSE ); + } +} + +WNDCMD CMainFrame::OnLauncher( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnLauncher\n" ); + + if( !m_LauncherDlg.m_hWnd ) { + m_LauncherDlg.Create( NULL ); + } + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + } else { + DirectDraw.SetFullScreenGDI( TRUE ); + } + // _CAO𒆉Ɉړ:) + RECT rcParent, rc; + ::GetWindowRect( m_hWnd, &rcParent ); + ::GetWindowRect( m_LauncherDlg.m_hWnd, &rc ); + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; + ::SetWindowPos( m_LauncherDlg.m_hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + + ::SetWindowPos( m_LauncherDlg.m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } else { + ::SetWindowPos( m_LauncherDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } + + ::ShowWindow( m_LauncherDlg.m_hWnd, SW_SHOW ); +} + +WNDCMD CMainFrame::OnNetPlayConnect( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() || !Nes ) + return; + if( Nes->IsMoviePlay() || Nes->IsMovieRec() ) + return; + if( NetPlay.IsConnect() ) + return; + + Emu.Pause(); + + if( !m_bMenu ) + OnFullScreenGDI( TRUE ); + + CNetPlayDlg dlg; + if( dlg.DoModal( m_hWnd ) == IDOK ) { + if( !m_ChatDlg.m_hWnd ) { + m_ChatDlg.Create( NULL ); + } + ::ShowWindow( m_ChatDlg.m_hWnd, SW_SHOW ); + + Emu.Event( CEmuThread::EV_NETPLAY_START ); + + // test + if( !Config.emulator.bBackground ) { + Emu.Resume(); + } + } + + if( !m_bMenu ) + OnFullScreenGDI( FALSE ); + + Emu.Resume(); +} + +WNDCMD CMainFrame::OnNetPlayDisconnect( WNDCMDPARAM ) +{ + if( !NetPlay.IsConnect() ) + return; + + Emu.Pause(); + NetPlay.Disconnect(); + Emu.Resume(); +} + +WNDCMD CMainFrame::OnNetPlayChat( WNDCMDPARAM ) +{ + DEBUGOUT( "CMainFrame::OnNetPlayChat\n" ); + if( !NetPlay.IsConnect() ) + return; + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + } else { + DirectDraw.SetFullScreenGDI( TRUE ); + } + // _CAOʊOȂΒɈړ:) + RECT rcParent, rc; + ::GetWindowRect( m_hWnd, &rcParent ); + ::GetWindowRect( m_ChatDlg.m_hWnd, &rc ); + + if( (rc.right < rcParent.left) || (rc.left > rcParent.right) + || (rc.bottom < rcParent.top) || (rc.top > rcParent.bottom) ) { + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; + ::SetWindowPos( m_ChatDlg.m_hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + } else { + ::SetWindowPos( m_ChatDlg.m_hWnd, NULL, 0, 0, -1, -1, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + } + ::SetWindowPos( m_ChatDlg.m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE ); + } else { + ::SetWindowPos( m_ChatDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW ); + } +// ::ShowWindow( m_ChatDlg.m_hWnd, SW_SHOW ); +} + +WNDCMD CMainFrame::OnSearch( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnSearch\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + + if( !m_SearchDlg.m_hWnd ) { + m_SearchDlg.Create( NULL ); + } + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + } else { + DirectDraw.SetFullScreenGDI( TRUE ); + } + // _CAO𒆉Ɉړ:) + RECT rcParent, rc; + ::GetWindowRect( m_hWnd, &rcParent ); + ::GetWindowRect( m_SearchDlg.m_hWnd, &rc ); + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; + ::SetWindowPos( m_SearchDlg.m_hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + + ::SetWindowPos( m_SearchDlg.m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } else { + ::SetWindowPos( m_SearchDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } + + ::ShowWindow( m_SearchDlg.m_hWnd, SW_SHOW ); +} + +WNDCMD CMainFrame::OnCheat( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnCheat\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + +// if( m_SearchDlg.m_hWnd ) { +// if( ::IsWindowVisible( m_SearchDlg.m_hWnd ) ) +// return; +// } + + if( !m_bMenu ) + OnFullScreenGDI( TRUE ); + + CCheatCodeDlg dlg; + + dlg.DoModal( m_hWnd ); + + if( !m_bMenu ) + OnFullScreenGDI( FALSE ); +} + +WNDCMD CMainFrame::OnGenie( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnGenie\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + + Emu.Pause(); + + string pathstr, tempstr; + if( Config.path.bCheatPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szCheatPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), "gen" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ::strcpy( szFile, tempstr.c_str() ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "GameGeine Files(*.gen)\0*.gen\0All Files(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = pathstr.c_str(); + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_LOADGENIECODE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetOpenFileName( &ofn ) ) { + Nes->GenieLoad( szFile ); + } + + Emu.Resume(); +} + +WNDCMD CMainFrame::OnCheatCommand( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnCheatCommand\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + + if( uID == ID_CHEAT_ENABLE ) { + Nes->SetCheatCodeAllFlag( TRUE, TRUE ); + } else + if( uID == ID_CHEAT_DISABLE ) { + Nes->SetCheatCodeAllFlag( FALSE, TRUE ); + } +} + +WNDCMD CMainFrame::OnDatachBacode( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnDatachBacode\n" ); + + if( !Emu.IsRunning() || !Nes ) + return; + + if( !m_DatachBarcodeDlg.m_hWnd ) { + m_DatachBarcodeDlg.Create( NULL ); + } + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + } else { + DirectDraw.SetFullScreenGDI( TRUE ); + } + // _CAO𒆉Ɉړ:) + RECT rcParent, rc; + ::GetWindowRect( m_hWnd, &rcParent ); + ::GetWindowRect( m_DatachBarcodeDlg.m_hWnd, &rc ); + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; + ::SetWindowPos( m_DatachBarcodeDlg.m_hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + + ::SetWindowPos( m_DatachBarcodeDlg.m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } else { + ::SetWindowPos( m_DatachBarcodeDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } + + ::ShowWindow( m_DatachBarcodeDlg.m_hWnd, SW_SHOW ); +} + + +WNDCMD CMainFrame::OnDipSwitch( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnDipSwitch\n" ); + CDipSwitchDlg dlg; + if( dlg.DoModal( m_hWnd ) == IDOK ) { + } +} + +WNDCMD CMainFrame::OnEmulatorCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnEmulatorCfg\n" ); + CEmulatorDlg dlg; + if( dlg.DoModal( m_hWnd ) == IDOK ) { + Emu.SetPriority( Config.emulator.nPriority ); + } +} + +WNDCMD CMainFrame::OnGraphicsCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnGraphicsCfg\n" ); + CGraphicsDlg dlg; + if( dlg.DoModal( m_hWnd ) == IDOK ) { + Emu.Pause(); + + // T[tFXrhKv邩̃`FbN + BOOL bRebuildDirectDraw = FALSE; + BOOL bRebuildSurface = FALSE; + BOOL bMenuOFF = FALSE; + + if( DirectDraw.GetUseHEL() != Config.graphics.bUseHEL ) + bRebuildDirectDraw = TRUE; + if( DirectDraw.GetSystemMemory() != Config.graphics.bSystemMemory ) + bRebuildSurface = TRUE; + + // DirectDraw߼݂̐ݒ + DirectDraw.SetFlipMode ( Config.graphics.bSyncDraw ); + DirectDraw.SetAspectMode ( Config.graphics.bAspect ); + DirectDraw.SetAllLineMode ( Config.graphics.bAllLine ); + DirectDraw.SetMaxZoom ( Config.graphics.bFitZoom ); + DirectDraw.SetTVFrameMode ( Config.graphics.bTVFrame ); + DirectDraw.SetScanlineMode ( Config.graphics.bScanline ); + DirectDraw.SetScanlineColor( Config.graphics.nScanlineColor ); + + DirectDraw.SetUseHEL ( Config.graphics.bUseHEL ); + DirectDraw.SetDoubleSize ( Config.graphics.bDoubleSize ); + DirectDraw.SetSystemMemory( Config.graphics.bSystemMemory ); + + DirectDraw.SetWindowVSyncMode( Config.graphics.bWindowVSync ); + + if( Config.general.bScreenMode ) { + // XN[[h̕ύXꍇ + if( !DirectDraw.IsNowDisplayMode( Config.graphics.dwDisplayWidth, + Config.graphics.dwDisplayHeight, + Config.graphics.dwDisplayDepth, + Config.graphics.dwDisplayRate ) ) { + if( !bRebuildDirectDraw ) + DirectDraw.BeginDisplayChange(); + + // XN[[h̐ݒ + DirectDraw.SetDisplayMode( Config.graphics.dwDisplayWidth, + Config.graphics.dwDisplayHeight, + Config.graphics.dwDisplayDepth, + Config.graphics.dwDisplayRate ); + + DirectDraw.SetScreenMode( Config.general.bScreenMode ); + if( !bRebuildDirectDraw ) + DirectDraw.EndDisplayChange(); + + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, 0, 0, ::GetSystemMetrics(SM_CXSCREEN), + ::GetSystemMetrics(SM_CYSCREEN), SWP_SHOWWINDOW ); + + // pbg + ::PostMessage( m_hWnd, WM_QUERYNEWPALETTE, 0, 0 ); + + // T[tFX͍č\zꂽ̂œx͍sȂ + bRebuildSurface = FALSE; + + bMenuOFF = TRUE; + } + } else { + OnSetWindowSize(); + } + if( bRebuildDirectDraw ) { + DirectDraw.ReleaseDDraw(); + DirectDraw.InitialDDraw( m_hWnd ); + DirectDraw.InitialSurface( Config.general.bScreenMode ); + bMenuOFF = TRUE; + } else + if( bRebuildSurface ) { + DirectDraw.ReleaseSurface(); + DirectDraw.InitialSurface( Config.general.bScreenMode ); + bMenuOFF = TRUE; + } + + if( Config.general.bScreenMode && bMenuOFF ) { + if( Emu.IsRunning() ) { + OnChangeMenu( FALSE ); + } + } + + Emu.Resume(); + } +} + +WNDCMD CMainFrame::OnSoundCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnSoundCfg\n" ); + CSoundDlg dlg; + + DWORD rate, bits; + DirectSound.GetSamplingRate( rate, bits ); + BOOL bSoundOn = DirectSound.IsStreamPlay(); + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + if( Config.sound.nRate != (INT)rate + || Config.sound.nBits != (INT)bits + || Config.sound.nBufferSize != DirectSound.GetBufferSize() ) { + Emu.Pause(); + if( bSoundOn ) { + DirectSound.StreamStop(); + } + + DirectSound.ReleaseBuffer(); + + DirectSound.SetSamplingRate( Config.sound.nRate, Config.sound.nBits ); + DirectSound.SetBufferSize( Config.sound.nBufferSize ); + + if( DirectSound.InitialBuffer() ) { + if( Nes ) { + Nes->SoundSetup(); + } + if( bSoundOn ) { + DirectSound.StreamPlay(); + DirectSound.StreamPause(); + } + } + Emu.Resume(); + } + } +} + +WNDCMD CMainFrame::OnControllerCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnControllerCfg\n" ); + CControllerDlg dlg; + + CWndHook::SetFiltering( TRUE ); + dlg.DoModal( m_hWnd ); + CWndHook::SetFiltering( FALSE ); +} + +WNDCMD CMainFrame::OnShortcutCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnShortcutCfg\n" ); + CShortcutDlg dlg; + + CWndHook::SetFiltering( TRUE ); + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + ::SetMenu( m_hWnd, NULL ); + ::DestroyMenu( m_hMenu ); + // j[̍ă[h + m_hMenu = CApp::LoadMenu( IDR_MENU ); + CApp::SetMenu( m_hMenu ); + ::SetMenu( m_hWnd, m_hMenu ); + OnRebuildMenu(); + } + + CWndHook::SetFiltering( FALSE ); +} + +WNDCMD CMainFrame::OnFolderCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnFolderCfg\n" ); + CFolderDlg dlg; + dlg.DoModal( m_hWnd ); +} + +WNDCMD CMainFrame::OnLanguageCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnLanguageCfg\n" ); + CLanguageDlg dlg; + + if( dlg.DoModal( m_hWnd ) == IDOK ) { + // `[NȂΕ‚ + BOOL bLauncher = FALSE; + BOOL bLauncherVisible = FALSE; + if( m_LauncherDlg.m_hWnd && ::IsWindow(m_LauncherDlg.m_hWnd) ) { + bLauncherVisible = ::IsWindowVisible( m_LauncherDlg.m_hWnd ); + bLauncher = TRUE; + m_LauncherDlg.Destroy(); + } + + // `bg_CAO͕‚ + BOOL bChat = FALSE; + BOOL bChatVisible = FALSE; + if( m_ChatDlg.m_hWnd && ::IsWindow(m_ChatDlg.m_hWnd) ) { + bChatVisible = ::IsWindowVisible( m_ChatDlg.m_hWnd ); + bChat = TRUE; + m_ChatDlg.Destroy(); + } + + // T[`_CAO͕‚ + if( m_SearchDlg.m_hWnd && ::IsWindow(m_SearchDlg.m_hWnd) ) { + m_SearchDlg.Destroy(); + } + + // o[R[h̓_CAO͕‚ + if( m_DatachBarcodeDlg.m_hWnd && ::IsWindow(m_DatachBarcodeDlg.m_hWnd) ) { + m_DatachBarcodeDlg.Destroy(); + } + + // j[̔j + ::SetMenu( m_hWnd, NULL ); + ::DestroyMenu( m_hMenu ); + + // ̃vOC̊J + ::FreeLibrary( CApp::GetPlugin() ); + // VvOC̃[h + HINSTANCE hPlugin; + if( !(hPlugin = ::LoadLibrary( CPlugin::GetPluginPath() )) ) { + ::MessageBox( m_hWnd, "Language plug-in load failed.", "VirtuaNES", MB_ICONERROR|MB_OK ); + ::PostMessage( m_hWnd, WM_CLOSE, 0, 0 ); + return; + } + CApp::SetPlugin( hPlugin ); + // j[̍ă[h + m_hMenu = CApp::LoadMenu( IDR_MENU ); + CApp::SetMenu( m_hMenu ); + ::SetMenu( m_hWnd, m_hMenu ); + + OnRebuildMenu(); + + // `[ċN + if( bLauncher ) { + m_LauncherDlg.Create( NULL ); + if( bLauncherVisible ) { + ::ShowWindow( m_LauncherDlg.m_hWnd, SW_SHOW ); + } + } + + // `bgċN + if( bChat ) { + m_ChatDlg.Create( NULL ); + if( bChatVisible ) { + ::ShowWindow( m_ChatDlg.m_hWnd, SW_SHOW ); + } + } + + ::SetForegroundWindow( m_hWnd ); + } +} + +WNDCMD CMainFrame::OnMovieCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnMovieCfg\n" ); + CMovieDlg dlg; + dlg.DoModal( m_hWnd ); +} + +WNDCMD CMainFrame::OnGameOptionCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnGameOptionCfg\n" ); + CGameOptionDlg dlg; + dlg.DoModal( m_hWnd ); +} + +WNDCMD CMainFrame::OnJoyAxisCfg( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnJoyAxisCfg\n" ); + CJoyAxisDlg dlg; + dlg.DoModal( m_hWnd ); + + DirectInput.SetJoyAxisMode( Config.general.JoyAxisSetting ); +} + +WNDCMD CMainFrame::OnPaletteEditCfg( WNDCMDPARAM ) +{ + DEBUGOUT( "CMainFrame::OnPaletteEditCfg\n" ); + + if( !m_PaletteEdit.m_hWnd ) { + m_PaletteEdit.Create( NULL ); + } + + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, TRUE ); + } else { + DirectDraw.SetFullScreenGDI( TRUE ); + } + // _CAO𒆉Ɉړ:) + RECT rcParent, rc; + ::GetWindowRect( m_hWnd, &rcParent ); + ::GetWindowRect( m_PaletteEdit.m_hWnd, &rc ); + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; + ::SetWindowPos( m_PaletteEdit.m_hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + + ::SetWindowPos( m_PaletteEdit.m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } else { + ::SetWindowPos( m_PaletteEdit.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + } + + ::ShowWindow( m_PaletteEdit.m_hWnd, SW_SHOW ); +} + +WNDCMD CMainFrame::OnFullScreen( WNDCMDPARAM ) +{ + DEBUGOUT( "CMainFrame::OnFullScreen\n" ); + + m_bKeyEnable = FALSE; + + // 댯Ȃ̂... + Emu.Pause(); + + Config.general.bScreenMode = !Config.general.bScreenMode; +// OnChangeMenu( FALSE ); + + if( !Config.general.bScreenMode ) { + // FullScreen to Window mode + DirectDraw.BeginDisplayChange(); + // ʒu̕A + ::SetWindowLong( m_hWnd, GWL_STYLE, m_StyleBackup ); + ::SetWindowLong( m_hWnd, GWL_EXSTYLE, m_ExStyleBackup ); + ::SetWindowPlacement( m_hWnd, &m_WindowPlacement ); + } else { + // Window to FullScreen mode + // ʒu̕ۑ +// m_bZoomed = ::IsZoomed( m_hWnd ); + m_WindowPlacement.length = sizeof(m_WindowPlacement); + ::GetWindowPlacement( m_hWnd, &m_WindowPlacement ); + + m_StyleBackup = ::GetWindowLong( m_hWnd, GWL_STYLE ); + m_ExStyleBackup = ::GetWindowLong( m_hWnd, GWL_EXSTYLE ); + ::SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP ); + ::SetWindowLong( m_hWnd, GWL_EXSTYLE, 0 ); + + // XN[[h̐ݒ + DirectDraw.SetDisplayMode( Config.graphics.dwDisplayWidth, + Config.graphics.dwDisplayHeight, + Config.graphics.dwDisplayDepth, + Config.graphics.dwDisplayRate ); + + DirectDraw.BeginDisplayChange(); + } + +// OnChangeMenu( FALSE ); + + DirectDraw.SetScreenMode( Config.general.bScreenMode ); + DirectDraw.EndDisplayChange(); + + if( !Config.general.bScreenMode ) { + if( m_LauncherDlg.m_hWnd && ::IsWindow(m_LauncherDlg.m_hWnd) ) { + ::SetWindowPos( m_LauncherDlg.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE ); + } + + OnChangeMenu( TRUE ); + ::SetForegroundWindow( m_hWnd ); + + ::RedrawWindow( m_hWnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE ); + } else { + if( Emu.IsRunning() ) { + OnChangeMenu( FALSE ); + } else { + OnChangeMenu( TRUE ); + } + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, 0, 0, ::GetSystemMetrics(SM_CXSCREEN), + ::GetSystemMetrics(SM_CYSCREEN), SWP_SHOWWINDOW ); + } + + // 댯Ȃ̂... + Emu.Resume(); + + m_bKeyEnable = TRUE; +} + +WNDCMD CMainFrame::OnZoom( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnZoom %d\n", uID-ID_ZOOMx1 ); + + // tXN[͖ + if( Config.general.bScreenMode ) + return; + + Config.general.nScreenZoom = (INT)(uID-ID_ZOOMx1); + OnSetWindowSize(); + + CHAR szStr[64]; + ::wsprintf( szStr, "Screen Zoom *%d", uID-ID_ZOOMx1+1 ); + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)szStr ); +} + +WNDCMD CMainFrame::OnViewCommand( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() || !Nes ) + return; + + switch( uID ) { + case ID_VIEW_PATTERN: + if( !m_PatternView.m_hWnd ) { + m_PatternView.Create( HWND_DESKTOP ); + } + ::SetWindowPos( m_PatternView.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + break; + case ID_VIEW_NAMETABLE: + if( !m_NameTableView.m_hWnd ) { + m_NameTableView.Create( HWND_DESKTOP ); + } + ::SetWindowPos( m_NameTableView.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + break; + case ID_VIEW_PALETTE: + if( !m_PaletteView.m_hWnd ) { + m_PaletteView.Create( HWND_DESKTOP ); + } + ::SetWindowPos( m_PaletteView.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + break; + + case ID_VIEW_MEMORY: + if( !m_MemoryView.m_hWnd ) { + m_MemoryView.Create( HWND_DESKTOP ); + } + ::SetWindowPos( m_MemoryView.m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + break; + default: + break; + } +} + +WNDCMD CMainFrame::OnEmuCommand( WNDCMDPARAM ) +{ +// DEBUGOUT( "CMainFrame::OnEmuCommand %d\n", uID ); + + switch( uID ) { + case ID_HWRESET: + Emu.Event( CEmuThread::EV_HWRESET ); + break; + case ID_SWRESET: + Emu.Event( CEmuThread::EV_SWRESET ); + break; + case ID_PAUSE: + Emu.Event( CEmuThread::EV_EMUPAUSE ); + break; + + case ID_ONEFRAME: + Emu.Event( CEmuThread::EV_ONEFRAME ); + break; + + case ID_THROTTLE: + Emu.Event( CEmuThread::EV_THROTTLE ); + break; + case ID_FRAMESKIP_UP: + Emu.Event( CEmuThread::EV_FRAMESKIP_UP ); + break; + case ID_FRAMESKIP_DOWN: + Emu.Event( CEmuThread::EV_FRAMESKIP_DOWN ); + break; + case ID_FRAMESKIP_AUTO: + Emu.Event( CEmuThread::EV_FRAMESKIP_AUTO ); + break; + + case ID_STATE_UP: + { + CHAR szStr[64]; + if( ++m_nStateSlot > 10-1 ) { + m_nStateSlot = 0; + } + ::wsprintf( szStr, "State Slot #%d", m_nStateSlot ); + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)szStr ); + } + break; + case ID_STATE_DOWN: + { + CHAR szStr[64]; + if( --m_nStateSlot < 0 ) { + m_nStateSlot = 10-1; + } + ::wsprintf( szStr, "State Slot #%d", m_nStateSlot ); + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)szStr ); + } + break; + + case ID_STATE_SLOT0: case ID_STATE_SLOT1: + case ID_STATE_SLOT2: case ID_STATE_SLOT3: + case ID_STATE_SLOT4: case ID_STATE_SLOT5: + case ID_STATE_SLOT6: case ID_STATE_SLOT7: + case ID_STATE_SLOT8: case ID_STATE_SLOT9: + m_nStateSlot = (INT)(uID-ID_STATE_SLOT0); + { + CHAR szStr[64]; + ::wsprintf( szStr, "State Slot #%d", m_nStateSlot ); + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)szStr ); + } + break; + + case ID_DISK_EJECT: + case ID_DISK_0A: case ID_DISK_0B: + case ID_DISK_1A: case ID_DISK_1B: + Emu.EventParam( CEmuThread::EV_DISK_COMMAND, (LONG)(uID-ID_DISK_EJECT) ); + break; + + case ID_MUTE_0: case ID_MUTE_1: case ID_MUTE_2: case ID_MUTE_3: + case ID_MUTE_4: case ID_MUTE_5: case ID_MUTE_6: case ID_MUTE_7: + case ID_MUTE_8: case ID_MUTE_9: case ID_MUTE_A: case ID_MUTE_B: + case ID_MUTE_C: case ID_MUTE_D: case ID_MUTE_E: case ID_MUTE_F: + Emu.EventParam( CEmuThread::EV_SOUND_MUTE, (LONG)(uID-ID_MUTE_0) ); + break; + + case ID_EXCTR_NONE: + case ID_EXCTR_PADDLE: + case ID_EXCTR_HYPERSHOT: + case ID_EXCTR_ZAPPER: + case ID_EXCTR_KEYBOARD: + case ID_EXCTR_SUBOR_KEYBOARD: + case ID_EXCTR_CRAZYCLIMBER: + case ID_EXCTR_SPACESHADOWGUN: + case ID_EXCTR_FAMILYTRAINER_A: + case ID_EXCTR_FAMILYTRAINER_B: + case ID_EXCTR_MAHJANG: + case ID_EXCTR_EXCITINGBOXING: + case ID_EXCTR_OEKAKIDS_TABLET: + case ID_EXCTR_TURBOFILE: + case ID_EXCTR_CHINA_EDUCATIONAL_MOUSE: + case ID_EXCTR_VSUNISYSTEM: + case ID_EXCTR_VSUNISYSTEM_ZAPPER: + if(uID>=ID_EXCTR_CRAZYCLIMBER){ + uID++; + }else if(uID==ID_EXCTR_SUBOR_KEYBOARD){ + uID=ID_EXCTR_CRAZYCLIMBER; + } + Emu.EventParam( CEmuThread::EV_EXCONTROLLER, uID-ID_EXCTR_NONE ); + break; + + case ID_TURBOFILE_BANK0: + case ID_TURBOFILE_BANK1: + case ID_TURBOFILE_BANK2: + case ID_TURBOFILE_BANK3: + Emu.EventParam( CEmuThread::EV_TURBOFILE, uID-ID_TURBOFILE_BANK0 ); + break; + + case ID_SNAPSHOT: + Emu.Event( CEmuThread::EV_SNAPSHOT ); + break; + + case ID_TVASPECT: + Config.graphics.bAspect = !Config.graphics.bAspect; + Emu.Pause(); + DirectDraw.SetAspectMode( Config.graphics.bAspect ); + if( !Config.general.bScreenMode ) + OnSetWindowSize(); + Emu.Resume(); + break; + case ID_SCANLINE: + Config.graphics.bScanline = !Config.graphics.bScanline; + Emu.Pause(); + DirectDraw.SetScanlineMode( Config.graphics.bScanline ); + Emu.Resume(); + break; + case ID_ALLLINE: + Config.graphics.bAllLine = !Config.graphics.bAllLine; + Emu.Pause(); + DirectDraw.SetAllLineMode( Config.graphics.bAllLine ); + if( !Config.general.bScreenMode ) + OnSetWindowSize(); + Emu.Resume(); + break; + case ID_ALLSPRITE: + Config.graphics.bAllSprite = !Config.graphics.bAllSprite; + break; + case ID_SYNCDRAW: + Config.graphics.bSyncDraw = !Config.graphics.bSyncDraw; + Emu.Pause(); + DirectDraw.SetFlipMode( Config.graphics.bSyncDraw ); + Emu.Resume(); + break; + case ID_FITSCREEN: + Config.graphics.bFitZoom = !Config.graphics.bFitZoom; + Emu.Pause(); + DirectDraw.SetMaxZoom( Config.graphics.bFitZoom ); + Emu.Resume(); + break; + + case ID_TVFRAME: + Config.graphics.bTVFrame = !Config.graphics.bTVFrame; + Emu.Pause(); + DirectDraw.SetTVFrameMode( Config.graphics.bTVFrame ); + Emu.Resume(); + break; + case ID_FPSDISP: + Config.graphics.bFPSDisp = !Config.graphics.bFPSDisp; + break; + + case ID_LEFTCLIP: + Config.graphics.bLeftClip = !Config.graphics.bLeftClip; + break; + + case ID_FILTER_NONE: + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)"Filter: None" ); + goto _gohell; + case ID_FILTER_2XSAI: + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)"Filter: 2xSaI" ); + goto _gohell; + case ID_FILTER_SUPER2XSAI: + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)"Filter: Super2xSaI" ); + goto _gohell; + case ID_FILTER_SUPEREAGLE: + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)"Filter: SuperEagle" ); + goto _gohell; + case ID_FILTER_SCALE2X: + Emu.EventParam( CEmuThread::EV_MESSAGE_OUT, (LONG)"Filter: Scale2x" ); +// goto _gohell; +_gohell: + Config.graphics.nGraphicsFilter = (INT)(uID-ID_FILTER_NONE); + Emu.Pause(); + DirectDraw.SetGraphicsFilter( Config.graphics.nGraphicsFilter ); + Emu.Resume(); + break; + + default: + break; + } +} + +WNDCMD CMainFrame::OnStateCommand( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() ) + return; + + CHAR st[16]; + ::wsprintf( st, "st%1X", m_nStateSlot ); + + string pathstr, tempstr; + if( Config.path.bStatePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szStatePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + DEBUGOUT( "Path: %s\n", pathstr.c_str() ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), st ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + if( uID == ID_STATE_LOAD ) { + INT ret; + if( (ret = NES::IsStateFile( tempstr.c_str(), Nes->rom )) >= 0 ) { + if( ret == IDS_ERROR_ILLEGALSTATECRC ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return; + } + } + } + Emu.EventParam2( CEmuThread::EV_STATE_LOAD, (INT)tempstr.c_str(), m_nStateSlot ); + } + if( uID == ID_STATE_SAVE ) { + Emu.EventParam2( CEmuThread::EV_STATE_SAVE, (INT)tempstr.c_str(), m_nStateSlot ); + } +} + +WNDCMD CMainFrame::OnStateCommand2( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() ) + return; + + BOOL bLoad = FALSE; + INT slot = 0; + if( uID >= ID_QUICKLOAD_SLOT0 && uID <= ID_QUICKLOAD_SLOT9 ) { + bLoad = TRUE; + slot = uID - ID_QUICKLOAD_SLOT0; + } else { + bLoad = FALSE; + slot = uID - ID_QUICKSAVE_SLOT0; + } + + CHAR st[16]; + ::wsprintf( st, "st%1X", slot ); + + string pathstr, tempstr; + if( Config.path.bStatePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szStatePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + DEBUGOUT( "Path: %s\n", pathstr.c_str() ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), st ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + if( bLoad ) { + INT ret; + if( (ret = NES::IsStateFile( tempstr.c_str(), Nes->rom )) >= 0 ) { + if( ret == IDS_ERROR_ILLEGALSTATECRC ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + return; + } + } + } + Emu.EventParam2( CEmuThread::EV_STATE_LOAD, (INT)tempstr.c_str(), slot ); + } + if( !bLoad ) { + Emu.EventParam2( CEmuThread::EV_STATE_SAVE, (INT)tempstr.c_str(), slot ); + } +} + +WNDCMD CMainFrame::OnMovieCommand( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() ) + return; + + if( uID == ID_MOVIE_STOP ) { + Emu.Event( CEmuThread::EV_MOVIE_STOP ); + return; + } + + Emu.Pause(); + + if( Config.general.bScreenMode && !m_bMenu ) { + OnFullScreenGDI( TRUE ); + } + + string pathstr, tempstr; + if( Config.path.bMoviePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szMoviePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), "vmv" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ::strcpy( szFile, tempstr.c_str() ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.lpstrDefExt = "vmv"; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "Movie Files(*.vmv)\0*.vmv\0All Files(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = pathstr.c_str(); + + CHAR szTitle[256]; + + if( uID == ID_MOVIE_PLAY ) { + CApp::LoadString( IDS_UI_PLAYMOVIE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetOpenFileName( &ofn ) ) { + INT ret; + if( (ret = NES::IsMovieFile( szFile, Nes->rom )) >= 0 ) { + if( ret == IDS_ERROR_ILLEGALMOVIEOLD ) { + ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONHAND|MB_OK ); + goto _Movie_Play_Failed; + } else + if( ret == IDS_ERROR_ILLEGALMOVIEVER ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + goto _Movie_Play_Failed; + } + } else + if( ret == IDS_ERROR_ILLEGALMOVIECRC ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(ret), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + goto _Movie_Play_Failed; + } + } + + Emu.EventParam( CEmuThread::EV_MOVIE_PLAY, (INT)szFile ); + } +_Movie_Play_Failed:; + } + } + if( uID == ID_MOVIE_REC ) { + ofn.Flags |= OFN_OVERWRITEPROMPT; + CApp::LoadString( IDS_UI_RECMOVIE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetSaveFileName( &ofn ) ) { + Emu.EventParam( CEmuThread::EV_MOVIE_REC, (INT)szFile ); + } + } + if( uID == ID_MOVIE_REC_APPEND ) { + CApp::LoadString( IDS_UI_APPENDMOVIE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetOpenFileName( &ofn ) ) { + INT ret; + if( (ret = NES::IsMovieFile( szFile, Nes->rom )) >= 0 ) { + if( ret == IDS_ERROR_ILLEGALMOVIEOLD ) { + ::MessageBox( m_hWnd, CApp::GetErrorString(IDS_ERROR_ILLEGALMOVIEOLD_A), "VirtuaNES", MB_ICONHAND|MB_OK ); + goto _Movie_Append_Failed; + } else + if( ret == IDS_ERROR_ILLEGALMOVIEVER ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(IDS_ERROR_ILLEGALMOVIEVER_A), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + goto _Movie_Append_Failed; + } + } else + if( ret == IDS_ERROR_ILLEGALMOVIECRC ) { + if( Config.emulator.bCrcCheck ) { + if( ::MessageBox( m_hWnd, CApp::GetErrorString(IDS_ERROR_ILLEGALMOVIECRC_A), "VirtuaNES", MB_ICONWARNING|MB_YESNO ) != IDYES ) + goto _Movie_Append_Failed; + } + } + + Emu.EventParam( CEmuThread::EV_MOVIE_RECAPPEND, (INT)szFile ); + } else { + // VK쐬Ɠ + Emu.EventParam( CEmuThread::EV_MOVIE_REC, (INT)szFile ); + } + } +_Movie_Append_Failed:; + } + + if( Config.general.bScreenMode && !m_bMenu ) { + OnFullScreenGDI( FALSE ); + } + + Emu.Resume(); +} + +void CMainFrame::OnMovieInfo( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() || !Nes ) + return; + + if( !(Nes->IsMoviePlay() || Nes->IsMovieRec()) ) + return; + + CMovieInfoDlg dlg; + + // o̐ݒ + Nes->GetMovieInfo( dlg.m_wRecVersion, dlg.m_wVersion, dlg.m_dwFrames, dlg.m_dwRerecordTimes ); + + if( !m_bMenu ) + OnFullScreenGDI( TRUE ); + dlg.DoModal( m_hWnd ); + if( !m_bMenu ) + OnFullScreenGDI( FALSE ); +} + +WNDCMD CMainFrame::OnTapeCommand( WNDCMDPARAM ) +{ + if( !Emu.IsRunning() ) + return; + + if( uID == ID_TAPE_STOP ) { + Emu.Event( CEmuThread::EV_TAPE_STOP ); + return; + } + + Emu.Pause(); + + if( Config.general.bScreenMode && !m_bMenu ) { + OnFullScreenGDI( TRUE ); + } + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), "vtp" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + OPENFILENAME ofn; + CHAR szFile[_MAX_PATH]; + + ::strcpy( szFile, tempstr.c_str() ); + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.lpstrDefExt = "vtp"; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "Tape Files(*.vtp)\0*.vtp\0All Files(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = pathstr.c_str(); + + CHAR szTitle[256]; + + if( uID == ID_TAPE_PLAY ) { + CApp::LoadString( IDS_UI_PLAYTAPE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetOpenFileName( &ofn ) ) { + Emu.EventParam( CEmuThread::EV_TAPE_PLAY, (INT)szFile ); + } + } + if( uID == ID_TAPE_REC ) { + ofn.Flags |= OFN_OVERWRITEPROMPT; + CApp::LoadString( IDS_UI_RECTAPE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + if( ::GetSaveFileName( &ofn ) ) { + Emu.EventParam( CEmuThread::EV_TAPE_REC, (INT)szFile ); + } + } + + if( Config.general.bScreenMode && !m_bMenu ) { + OnFullScreenGDI( FALSE ); + } + + Emu.Resume(); +} + +void CMainFrame::OnFullScreenGDI( BOOL bFlag ) +{ + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, (INT)bFlag ); + } + } +} + +void CMainFrame::OnShowCursor( BOOL bFlag ) +{ + if( !bFlag ) { + if( m_bCursor ) { + while( ::ShowCursor( FALSE ) >= 0 ); + m_bCursor = FALSE; + } + } else { + if( !m_bCursor ) { + while( ::ShowCursor( TRUE ) < 0 ); + m_bCursor = TRUE; + } + } +} + +void CMainFrame::OnChangeMenu( BOOL bFlag ) +{ + if( Config.general.bScreenMode ) { + if( Emu.IsRunning() ) { + Emu.EventParam( CEmuThread::EV_FULLSCREEN_GDI, (INT)bFlag ); + } else { + DirectDraw.SetFullScreenGDI( bFlag ); + } + } + + if( m_bMenu ) { + if( !bFlag ) { + ::SetMenu( m_hWnd, NULL ); + m_bMenu = FALSE; + } + } else { + if( bFlag ) { + ::SetMenu( m_hWnd, m_hMenu ); + m_bMenu = TRUE; + ::DrawMenuBar( m_hWnd ); + } + } + +// OnShowCursor( m_bMenu ); +} + +void CMainFrame::OnSetWindowSize() +{ + // EChE[h̎ + if( Config.general.bScreenMode ) + return; + + LONG width, height; + + if( !Config.graphics.bAspect ) width = CDirectDraw::SCREEN_WIDTH; + else width = (LONG)((CDirectDraw::SCREEN_WIDTH)*1.25); + if( !Config.graphics.bAllLine ) height = CDirectDraw::SCREEN_HEIGHT-16; + else height = CDirectDraw::SCREEN_HEIGHT; + + width *= Config.general.nScreenZoom+1; + height *= Config.general.nScreenZoom+1; + + RECT rcW, rcC; + ::GetWindowRect( m_hWnd, &rcW ); + ::GetClientRect( m_hWnd, &rcC ); + + rcW.right += width -(rcC.right-rcC.left); + rcW.bottom += height-(rcC.bottom-rcC.top); + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, rcW.left, rcW.top, + rcW.right-rcW.left, rcW.bottom-rcW.top, SWP_NOZORDER ); + + // j[܂ԂƏcȂ鎖̂ōďC + ::GetClientRect( m_hWnd, &rcC ); + if( (rcC.bottom-rcC.top) != height ) { + ::GetWindowRect( m_hWnd, &rcW ); + ::GetClientRect( m_hWnd, &rcC ); + + rcW.right += width -(rcC.right-rcC.left); + rcW.bottom += height-(rcC.bottom-rcC.top); + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, rcW.left, rcW.top, + rcW.right-rcW.left, rcW.bottom-rcW.top, SWP_NOZORDER ); + } + + + // ő\ɃTCYύXꍇ̍ő\̉yу{^̍ĕ` + LONG style = ::GetWindowLong( m_hWnd, GWL_STYLE ); + style &= ~WS_MAXIMIZE; + ::SetWindowLong( m_hWnd, GWL_STYLE, style ); + ::RedrawWindow( m_hWnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE ); + + // ʒuۑȂ + m_bZoomed = FALSE; + ::GetWindowRect( m_hWnd, &m_WindowRect ); +} + +void CMainFrame::OnRebuildMenu() +{ + CHAR szMenuString[256]; + string str; + for( INT i = 0; CConfig::ShortcutKeyID[i*3+0]; i++ ) { + ::GetMenuString( m_hMenu, CConfig::ShortcutKeyID[i*3+0], szMenuString, 256, MF_BYCOMMAND ); + + INT id, code; + id = CConfig::ShortcutKeyID[i*3+2]; + code = Config.shortcut.nShortCut[id]; + if( code != 0 ) { + string temp = szMenuString; + temp = temp + "\t"; + temp = temp + Config.ShortcutToKeyName( code ); + + ::ModifyMenu( m_hMenu, CConfig::ShortcutKeyID[i*3+0], MF_BYCOMMAND|MF_STRING, + CConfig::ShortcutKeyID[i*3+0], temp.c_str() ); + } + } +} + +void CMainFrame::OnUpdateMenu( HMENU hMenu, UINT uID ) +{ + BOOL bEnable = FALSE; + BOOL bCheck = FALSE; + BOOL bEmu = Emu.IsRunning(); + BOOL bScn = Config.general.bScreenMode; + + switch( uID ) { + case ID_CLOSE: + case ID_ROMINFO: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_NETPLAY_CONNECT: + if( bEmu ) + bEnable = !(Nes->IsMoviePlay() || Nes->IsMovieRec() || Nes->rom->IsNSF()); + else + bEnable = FALSE; + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|((bEnable&&bEmu&&NetPlay.IsNetPlay()&&!NetPlay.IsConnect())?MF_ENABLED:MF_GRAYED) ); + break; + case ID_NETPLAY_DISCONNECT: + case ID_NETPLAY_CHAT: + if( bEmu ) + bEnable = !(Nes->IsMoviePlay() || Nes->IsMovieRec() || Nes->rom->IsNSF()); + else + bEnable = FALSE; + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|((bEnable&&bEmu&&NetPlay.IsNetPlay()&&NetPlay.IsConnect())?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_WAVERECORD: + bCheck = bEmu && Emu.IsWaveRecord(); + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(bCheck?MF_CHECKED:MF_UNCHECKED) ); + break; + + case ID_HWRESET: + case ID_SWRESET: + case ID_PAUSE: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + case ID_STATE_LOAD: + case ID_STATE_SAVE: + if( Nes ) { + bEnable = bEmu && !Nes->rom->IsNSF(); + } else { + bEnable = bEmu; + } + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEnable?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_STATE_SLOT0: case ID_STATE_SLOT1: + case ID_STATE_SLOT2: case ID_STATE_SLOT3: + case ID_STATE_SLOT4: case ID_STATE_SLOT5: + case ID_STATE_SLOT6: case ID_STATE_SLOT7: + case ID_STATE_SLOT8: case ID_STATE_SLOT9: + case ID_QUICKLOAD_SLOT0: case ID_QUICKLOAD_SLOT1: + case ID_QUICKLOAD_SLOT2: case ID_QUICKLOAD_SLOT3: + case ID_QUICKLOAD_SLOT4: case ID_QUICKLOAD_SLOT5: + case ID_QUICKLOAD_SLOT6: case ID_QUICKLOAD_SLOT7: + case ID_QUICKLOAD_SLOT8: case ID_QUICKLOAD_SLOT9: + case ID_QUICKSAVE_SLOT0: case ID_QUICKSAVE_SLOT1: + case ID_QUICKSAVE_SLOT2: case ID_QUICKSAVE_SLOT3: + case ID_QUICKSAVE_SLOT4: case ID_QUICKSAVE_SLOT5: + case ID_QUICKSAVE_SLOT6: case ID_QUICKSAVE_SLOT7: + case ID_QUICKSAVE_SLOT8: case ID_QUICKSAVE_SLOT9: + // \(\ʓ|) + { + CHAR szMenuString[256]; + CHAR* pToken; + const UCHAR seps[] = " \t\0"; // Zp[^ + + // IDԍCfbNXT + for( INT i = 0; CConfig::ShortcutKeyID[i*3+0] != uID; i++ ); + + ::GetMenuString( m_hMenu, CConfig::ShortcutKeyID[i*3+0], szMenuString, 256, MF_BYCOMMAND ); + + if( (pToken = (CHAR*)_mbstok( (UCHAR*)szMenuString, seps )) ) { + string str = pToken; + + if( Emu.IsRunning() && Nes ) { + CHAR temp[256]; + if( uID >= ID_STATE_SLOT0 && uID <= ID_STATE_SLOT9 ) + ::wsprintf( temp, "st%1X", CConfig::ShortcutKeyID[i*3+0]-ID_STATE_SLOT0 ); + else if( uID >= ID_QUICKLOAD_SLOT0 && uID <= ID_QUICKLOAD_SLOT9 ) + ::wsprintf( temp, "st%1X", CConfig::ShortcutKeyID[i*3+0]-ID_QUICKLOAD_SLOT0 ); + else + ::wsprintf( temp, "st%1X", CConfig::ShortcutKeyID[i*3+0]-ID_QUICKSAVE_SLOT0 ); + + string pathstr, tempstr; + if( Config.path.bStatePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szStatePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = Nes->rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), Nes->rom->GetRomName(), temp ); + + HANDLE hFile = ::CreateFile( tempstr.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + if( hFile != INVALID_HANDLE_VALUE ) { + BY_HANDLE_FILE_INFORMATION fi; + FILETIME filetime; + SYSTEMTIME systime; + ::GetFileInformationByHandle( hFile, &fi ); + ::FileTimeToLocalFileTime( &fi.ftLastWriteTime, &filetime ); + ::FileTimeToSystemTime( &filetime, &systime ); + ::wsprintf( temp,"%04d/%02d/%02d %02d:%02d:%02d", systime.wYear, systime.wMonth, systime.wDay, systime.wHour, systime.wMinute, systime.wSecond ); + ::CloseHandle( hFile ); + + str = str + " "; + str = str + temp; + } else { + str = str + " not exist"; + } + } + + INT code = Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2]]; + if( code ) { + str = str + "\t"; + str = str + Config.ShortcutToKeyName( code ); + } + + ::ModifyMenu( m_hMenu, CConfig::ShortcutKeyID[i*3+0], MF_BYCOMMAND|MF_STRING, + CConfig::ShortcutKeyID[i*3+0], str.c_str() ); + } + + if( !(uID >= ID_STATE_SLOT0 && uID <= ID_STATE_SLOT9) ) { + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + } + + if( uID >= ID_STATE_SLOT0 && uID <= ID_STATE_SLOT9 ) { + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(m_nStateSlot==(INT)(uID-ID_STATE_SLOT0)?MF_CHECKED:MF_UNCHECKED) ); + } + } + break; + + case ID_ZOOMx1: case ID_ZOOMx2: + case ID_ZOOMx3: case ID_ZOOMx4: + if( bScn ) ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|MF_GRAYED ); + else ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|MF_ENABLED ); + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(Config.general.nScreenZoom==(uID-ID_ZOOMx1)?MF_CHECKED:MF_UNCHECKED) ); + break; + + case ID_FILTER_NONE: + case ID_FILTER_2XSAI: + case ID_FILTER_SUPER2XSAI: + case ID_FILTER_SUPEREAGLE: + case ID_FILTER_SCALE2X: + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(Config.graphics.nGraphicsFilter==(uID-ID_FILTER_NONE)?MF_CHECKED:MF_UNCHECKED) ); + break; + + case ID_DISK_EJECT: + case ID_DISK_0A: case ID_DISK_0B: + case ID_DISK_1A: case ID_DISK_1B: + if( Nes ) { + INT no = Nes->GetDiskNo(); + bEnable = bEmu && !(Nes->rom->GetMapperNo() != 20 || Nes->rom->IsNSF() || (!no || (uID-ID_DISK_EJECT)>no)); + } else { + bEnable = bEmu; + } + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEnable?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_MOVIE_PLAY: + case ID_MOVIE_REC: + case ID_MOVIE_REC_APPEND: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|((bEmu&&!NetPlay.IsConnect())?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_MOVIE_STOP: + case ID_MOVIE_INFO: + if( Nes ) { + bEnable = Nes->IsMoviePlay() || Nes->IsMovieRec(); + } else { + bEnable = bEmu; + } + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEnable?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_TAPE_PLAY: + case ID_TAPE_REC: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|((bEmu&&!NetPlay.IsConnect())?MF_ENABLED:MF_GRAYED) ); + break; + case ID_TAPE_STOP: + if( Nes ) { + bEnable = Nes->IsTapePlay() || Nes->IsTapeRec(); + } else { + bEnable = bEmu; + } + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEnable?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_BARCODEBATTLER: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|((bEmu&&!NetPlay.IsConnect())?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_VSUNISYSTEM_DIPSWITCH: + bEnable = bEmu && + ( (Nes->pad->GetExController() == PAD::EXCONTROLLER_VSUNISYSTEM) + ||(Nes->pad->GetExController() == PAD::EXCONTROLLER_VSZAPPER) ); + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|((bEmu&&!NetPlay.IsConnect())?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_SNAPSHOT: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_EXCTR_NONE: + case ID_EXCTR_PADDLE: + case ID_EXCTR_HYPERSHOT: + case ID_EXCTR_ZAPPER: + case ID_EXCTR_KEYBOARD: + case ID_EXCTR_SUBOR_KEYBOARD: + case ID_EXCTR_CRAZYCLIMBER: + case ID_EXCTR_TOPRIDER: + case ID_EXCTR_SPACESHADOWGUN: + case ID_EXCTR_FAMILYTRAINER_A: + case ID_EXCTR_FAMILYTRAINER_B: + case ID_EXCTR_EXCITINGBOXING: + case ID_EXCTR_MAHJANG: + case ID_EXCTR_OEKAKIDS_TABLET: + case ID_EXCTR_TURBOFILE: + case ID_EXCTR_CHINA_EDUCATIONAL_MOUSE: + case ID_EXCTR_VSUNISYSTEM: + case ID_EXCTR_VSUNISYSTEM_ZAPPER: + { + UINT tuID = uID; + if(uID>=ID_EXCTR_CRAZYCLIMBER){ + uID++; + }else if(uID==ID_EXCTR_SUBOR_KEYBOARD){ + uID=ID_EXCTR_CRAZYCLIMBER; + } + if( Nes ) { + if( Nes->pad->GetExController() == (uID-ID_EXCTR_NONE) ) + bCheck = TRUE; + else + bCheck = FALSE; + } else { + if( uID == ID_EXCTR_NONE ) + bCheck = TRUE; + else + bCheck = FALSE; + } + ::EnableMenuItem( hMenu, tuID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + ::CheckMenuItem( hMenu, tuID, MF_BYCOMMAND|(bCheck?MF_CHECKED:MF_UNCHECKED) ); + break; + + } + case ID_TURBOFILE_BANK0: + case ID_TURBOFILE_BANK1: + case ID_TURBOFILE_BANK2: + case ID_TURBOFILE_BANK3: + if( Nes ) { + bEnable = bEmu && (Nes->pad->GetExController() == PAD::EXCONTROLLER_TURBOFILE); + if( bEnable ) { + if( Nes->GetTurboFileBank() == (uID-ID_TURBOFILE_BANK0) ) + bCheck = TRUE; + else + bCheck = FALSE; + } + } + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEnable?MF_ENABLED:MF_GRAYED) ); + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(bCheck?MF_CHECKED:MF_UNCHECKED) ); + break; + + case ID_FULLSCREEN: + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(bScn?MF_CHECKED:MF_UNCHECKED) ); + break; + case ID_FPSDISP: + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(Config.graphics.bFPSDisp?MF_CHECKED:MF_UNCHECKED) ); + break; + case ID_TVFRAME: + ::CheckMenuItem( hMenu, uID, MF_BYCOMMAND|(Config.graphics.bTVFrame?MF_CHECKED:MF_UNCHECKED) ); + break; + + case ID_CFG_GAMEOPTION: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_SEARCH: + case ID_CHEAT: + case ID_CHEAT_ENABLE: + case ID_CHEAT_DISABLE: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; +#if 0 + case ID_CHEAT: + if( m_SearchDlg.m_hWnd ) + bEnable = bEmu && !::IsWindowVisible( m_SearchDlg.m_hWnd ); + else + bEnable = bEmu; + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEnable?MF_ENABLED:MF_GRAYED) ); + break; +#endif + case ID_GENIE: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_VIEW_PATTERN: + case ID_VIEW_NAMETABLE: + case ID_VIEW_PALETTE: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_VIEW_MEMORY: + case ID_VIEW_WATCH: + ::EnableMenuItem( hMenu, uID, MF_BYCOMMAND|(bEmu?MF_ENABLED:MF_GRAYED) ); + break; + + default: + break; + } +} + +void CMainFrame::OnKeyControl() +{ +BYTE KeyInp[256+64*8]; + + // 20msł͎󂯕tȂ悤ɂ + if( (::timeGetTime()-m_dwKeyTime) < 20 ) + return; + m_dwKeyTime = ::timeGetTime(); + + ::memset( KeyInp, 0x00, sizeof(KeyInp) ); + + if( !m_bKeyEnable ) { + // gK𔭐Ȃ悤ɂ + ::memset( m_KeyBuf, 0x80, sizeof(m_KeyBuf) ); +//DEBUGOUT( "Key Disable\n" ); + return; + } + + // gKs[g + BYTE* pSw = (BYTE*)DirectInput.m_Sw; + BYTE* pOld = (BYTE*)m_KeyBuf; + BYTE* pCnt = (BYTE*)m_KeyCnt; + BYTE* pKey = (BYTE*)KeyInp; + + for( INT i = 0; i < 256+64*8; i++ ) { + pKey[i] = (pSw[i]&0x80) & ~(pOld[i]&0x80); + if( pKey[i] ) { + pCnt[i] = 14; + } else if( pCnt[i] != 0 && (pSw[i]&0x80) ) { + if( --pCnt[i] == 0 ) { + pKey[i] = pSw[i]&0x80; + pCnt[i] = 5; + } else { + pKey[i] = 0; + } + } + } + ::memcpy( m_KeyBuf, DirectInput.m_Sw, sizeof(DirectInput.m_Sw) ); + +//DEBUGOUT( "LMENU:%02X RMENU:%02X ENTER:%02X\n", m_KeyBuf[DIK_LMENU], m_KeyBuf[DIK_RMENU], KeyInp[DIK_RETURN] ); + + // CxgM + BOOL bAltOnly = FALSE; + if( Emu.IsRunning() ) { + // t@~[x[VbNL[{[h̎ + if( Emu.GetExController() == PAD::EXCONTROLLER_KEYBOARD || + Emu.GetExController() == PAD::EXCONTROLLER_Subor_KEYBOARD || + Emu.GetExController() == PAD::EXCONTROLLER_PEC_KEYBOARD || + Emu.GetExController() == PAD::EXCONTROLLER_Kingwon_KEYBOARD || + Emu.GetExController() == PAD::EXCONTROLLER_ZeCheng_KEYBOARD || + Emu.GetExController() == PAD::EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE || + Emu.GetNES()->rom->GetMapperNo() == 169 ) //YuXing + bAltOnly = TRUE; + if( Emu.IsPausing() ) + bAltOnly = FALSE; + } + + WORD keyex = 0; + if( m_KeyBuf[DIK_LMENU] || m_KeyBuf[DIK_RMENU] ) + keyex = CCfgShortCut::K_ALT; + if( m_KeyBuf[DIK_LCONTROL] || m_KeyBuf[DIK_RCONTROL] ) + keyex = CCfgShortCut::K_CTRL; + if( m_KeyBuf[DIK_LSHIFT] || m_KeyBuf[DIK_RSHIFT] ) + keyex = CCfgShortCut::K_SHIFT; + + WORD* pShortCutKey = Config.shortcut.nShortCut; + INT* pShortCutKeyID = Config.ShortcutKeyID; + + if( bAltOnly ) { + INT no; + WORD key, key2; + for( INT i = 0; pShortCutKeyID[i*3+0]; i++ ) { + no = pShortCutKeyID[i*3+2]; + key = pShortCutKey[no]; + key2 = pShortCutKey[no+128]; + + if( (key & 0xF000) == CCfgShortCut::K_ALT && keyex == CCfgShortCut::K_ALT && KeyInp[key&0x0FFF] && (key&0x0FFF) ) { + ::PostMessage( CApp::GetHWnd(), WM_COMMAND, (WPARAM)pShortCutKeyID[i*3+0], (LPARAM)0 ); + } + if( (key2 & 0xF000) == CCfgShortCut::K_ALT && keyex == CCfgShortCut::K_ALT && KeyInp[key2&0x0FFF] && (key2&0x0FFF) ) { + ::PostMessage( CApp::GetHWnd(), WM_COMMAND, (WPARAM)pShortCutKeyID[i*3+0], (LPARAM)0 ); + } + } + } else { + INT no; + WORD key, key2; + for( INT i = 0; pShortCutKeyID[i*3+0]; i++ ) { + no = pShortCutKeyID[i*3+2]; + key = pShortCutKey[no]; + key2 = pShortCutKey[no+128]; + if( (key & 0xF000) == keyex && KeyInp[key&0x0FFF] && (key&0x0FFF) ) { + ::PostMessage( CApp::GetHWnd(), WM_COMMAND, (WPARAM)pShortCutKeyID[i*3+0], (LPARAM)0 ); + } + if( (key2 & 0xF000) == keyex && KeyInp[key2&0x0FFF] && (key2&0x0FFF) ) { + ::PostMessage( CApp::GetHWnd(), WM_COMMAND, (WPARAM)pShortCutKeyID[i*3+0], (LPARAM)0 ); + } + } + } +} + +void _cdecl CMainFrame::KeyThreadProc( LPVOID lpParam ) +{ + while( !m_bKeyThreadExit ) { + ::Sleep( 20 ); + + // G~[VȊOłȂ + if( Emu.IsRunning() ) { + continue; + } else { + DirectInput.Poll(); + OnKeyControl(); + } + } + _endthread(); +} + diff --git a/References/VirtuaNESex_src_191105/MainFrame.h b/References/VirtuaNESex_src_191105/MainFrame.h new file mode 100644 index 00000000..60121d52 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MainFrame.h @@ -0,0 +1,208 @@ +// +// CEChENX +// +#ifndef __CMAINFRAME_INCLUDED__ +#define __CMAINFRAME_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +using namespace std; + +#include "Wnd.h" +#include "EmuThread.h" +#include "LauncherDlg.h" +#include "CheatDlg.h" +#include "PatternView.h" +#include "NameTableView.h" +#include "PaletteView.h" +#include "MemoryView.h" +#include "DatachBarcodeDlg.h" +#include "ChatDlg.h" +#include "PaletteEdit.h" +#include "DipSwitchDlg.h" + +class CMainFrame : public CWnd +{ +public: + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + + // Override from CWnd + BOOL PreTranslateMessage( MSG* pMsg ); + + static void OnKeyControl(); +protected: + void OnEmulationStart( LPCSTR szFile, BOOL bChecked ); + + void OnFullScreenGDI( BOOL bFlag ); + void OnShowCursor( BOOL bFlag ); + void OnChangeMenu( BOOL bFlag ); + void OnSetWindowSize(); + void OnRebuildMenu(); + void OnUpdateMenu( HMENU hMenu, UINT uID ); + + static void _cdecl KeyThreadProc( LPVOID lpParam ); + + // Message map + WND_MESSAGE_MAP() + WNDMSG OnCreate( WNDMSGPARAM ); + WNDMSG OnClose( WNDMSGPARAM ); + WNDMSG OnDestroy( WNDMSGPARAM ); + WNDMSG OnActivate( WNDMSGPARAM ); + WNDMSG OnActivateApp( WNDMSGPARAM ); + WNDMSG OnShortCutEnable( WNDMSGPARAM ); // Private message + WNDMSG OnEnable( WNDMSGPARAM ); + WNDMSG OnEnterMenuLoop( WNDMSGPARAM ); + WNDMSG OnExitMenuLoop( WNDMSGPARAM ); + WNDMSG OnSetFocus( WNDMSGPARAM ); + WNDMSG OnKillFocus( WNDMSGPARAM ); + WNDMSG OnInitMenu( WNDMSGPARAM ); + WNDMSG OnInitMenuPopup( WNDMSGPARAM ); + WNDMSG OnGetMinMaxInfo( WNDMSGPARAM ); + WNDMSG OnPaint( WNDMSGPARAM ); + WNDMSG OnDisplayChange( WNDMSGPARAM ); + WNDMSG OnPaletteChanged( WNDMSGPARAM ); + WNDMSG OnQueryNewPalette( WNDMSGPARAM ); + WNDMSG OnMenuChar( WNDMSGPARAM ); + WNDMSG OnKeyDown( WNDMSGPARAM ); + WNDMSG OnSize( WNDMSGPARAM ); + WNDMSG OnSysCommand( WNDMSGPARAM ); + WNDMSG OnExitSizeMove( WNDMSGPARAM ); + + WNDMSG OnSetCursor( WNDMSGPARAM ); + WNDMSG OnTimer( WNDMSGPARAM ); + + WNDMSG OnCopyData( WNDMSGPARAM ); + + WNDMSG OnErrorMessage( WNDMSGPARAM ); // Private message + + WNDMSG OnDropFiles( WNDMSGPARAM ); + WNDMSG OnCommandLine( WNDMSGPARAM ); // Private message + WNDMSG OnLauncherCommand( WNDMSGPARAM ); // Private message + + WNDMSG OnNetPlay( WNDMSGPARAM ); + WNDMSG OnNetPlayClose( WNDMSGPARAM ); + WNDMSG OnNetPlayError( WNDMSGPARAM ); + WNDMSG OnNetPlayChatPopup( WNDMSGPARAM ); + + WNDCMD OnExit( WNDCMDPARAM ); + WNDCMD OnHelp( WNDCMDPARAM ); + WNDCMD OnAbout( WNDCMDPARAM ); + WNDCMD OnFileOpen( WNDCMDPARAM ); + WNDCMD OnFileClose( WNDCMDPARAM ); + WNDCMD OnRecentOpen( WNDCMDPARAM ); + WNDCMD OnRecentOpenPath( WNDCMDPARAM ); + WNDCMD OnRomInfo( WNDCMDPARAM ); + WNDCMD OnWaveRecord( WNDCMDPARAM ); + WNDCMD OnLauncher( WNDCMDPARAM ); + + WNDCMD OnSearch( WNDCMDPARAM ); + WNDCMD OnCheat( WNDCMDPARAM ); + WNDCMD OnGenie( WNDCMDPARAM ); + WNDCMD OnCheatCommand( WNDCMDPARAM ); + + WNDCMD OnDatachBacode( WNDCMDPARAM ); + WNDCMD OnDipSwitch( WNDCMDPARAM ); + + WNDCMD OnNetPlayConnect( WNDCMDPARAM ); + WNDCMD OnNetPlayDisconnect( WNDCMDPARAM ); + WNDCMD OnNetPlayChat( WNDCMDPARAM ); + + WNDCMD OnEmulatorCfg( WNDCMDPARAM ); + WNDCMD OnGraphicsCfg( WNDCMDPARAM ); + WNDCMD OnSoundCfg( WNDCMDPARAM ); + WNDCMD OnControllerCfg( WNDCMDPARAM ); + WNDCMD OnShortcutCfg( WNDCMDPARAM ); + WNDCMD OnFolderCfg( WNDCMDPARAM ); + WNDCMD OnLanguageCfg( WNDCMDPARAM ); + WNDCMD OnMovieCfg( WNDCMDPARAM ); + WNDCMD OnGameOptionCfg( WNDCMDPARAM ); + WNDCMD OnJoyAxisCfg( WNDCMDPARAM ); + WNDCMD OnPaletteEditCfg( WNDCMDPARAM ); + WNDCMD OnFullScreen( WNDCMDPARAM ); + WNDCMD OnZoom( WNDCMDPARAM ); + + WNDCMD OnViewCommand( WNDCMDPARAM ); + + WNDCMD OnEmuCommand( WNDCMDPARAM ); + + WNDCMD OnStateCommand( WNDCMDPARAM ); + WNDCMD OnStateCommand2( WNDCMDPARAM ); // For QuickLoad/Save + WNDCMD OnMovieCommand( WNDCMDPARAM ); + WNDCMD OnMovieInfo( WNDCMDPARAM ); + WNDCMD OnTapeCommand( WNDCMDPARAM ); + + // Command line + CHAR m_szCommandLine[_MAX_PATH]; + + // Window activate flags + BOOL m_bActivate; + BOOL m_bActivateApp; + BOOL m_bForcus; + + BOOL m_bEnable; + static BOOL m_bKeyEnable; + + // Cursor + BOOL m_bCursor; + UINT m_uTimerID; + DWORD m_LastMovedTime; + + // Menu flags + BOOL m_bMenu; + + // Window Position + BOOL m_bZoomed; + RECT m_WindowRect; + WINDOWPLACEMENT m_WindowPlacement; + + // Window Style + LONG m_ExStyleBackup; + LONG m_StyleBackup; + + // Short Cut + UINT m_uKeyTimerID; + volatile BOOL m_bKeyChecking; + + static DWORD m_dwKeyTime; + static BYTE m_KeyBuf[256+64*8]; + static BYTE m_KeyOld[256+64*8]; + static BYTE m_KeyCnt[256*64*8]; + static volatile BOOL m_bKeyThreadExit; + + // Emulator + NES* Nes; +// CEmuThread Emu; + + // State slot + INT m_nStateSlot; + + // Launcher + CLauncherDlg m_LauncherDlg; + + // Cheat + CSearchDlg m_SearchDlg; + + // Viewer + CPatternView m_PatternView; + CNameTableView m_NameTableView; + CPaletteView m_PaletteView; + + CMemoryView m_MemoryView; + + // Palette Editor + CPaletteEdit m_PaletteEdit; + + // Cheat + CDatachBarcodeDlg m_DatachBarcodeDlg; + + // Chat + CChatDlg m_ChatDlg; +private: +}; + +#endif // !__CMAINFRAME_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/MemoryView.cpp b/References/VirtuaNESex_src_191105/MemoryView.cpp new file mode 100644 index 00000000..f9d054a0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MemoryView.cpp @@ -0,0 +1,589 @@ +// +// r[NX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "MemoryView.h" +#include "EmuThread.h" + +#include "MMU.h" + +#include "DirectDraw.h" + +#define OFFSETH 4 +#define OFFSETV 4 + +#define FONTWIDTH 6 +#define FONTHEIGHT 12 + +LOGFONT CMemoryView::m_logFont={ FONTHEIGHT, FONTWIDTH, 0, 0, 0, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, NULL }; + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x020A +#endif + +WND_MESSAGE_BEGIN(CMemoryView) +WND_ON_MESSAGE( WM_CREATE, OnCreate ) +WND_ON_MESSAGE( WM_CLOSE, OnClose ) +WND_ON_MESSAGE( WM_DESTROY, OnDestroy ) +WND_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +WND_ON_MESSAGE( WM_SIZE, OnSize ) +WND_ON_MESSAGE( WM_LBUTTONDOWN, OnLButtonDown ) +WND_ON_MESSAGE( WM_MOUSEWHEEL, OnMouseWheel ) +WND_ON_MESSAGE( WM_CHAR, OnChar ) +WND_ON_MESSAGE( WM_KEYDOWN, OnKeyDown ) +WND_ON_MESSAGE( WM_VSCROLL, OnVScroll ) +WND_ON_MESSAGE( WM_PAINT, OnPaint ) +WND_ON_MESSAGE( WM_TIMER, OnTimer ) + +WND_COMMAND_BEGIN() +WND_COMMAND_END() +WND_MESSAGE_END() + +CMemoryView::CMemoryView() +{ + m_hFont = NULL; + m_StartAddress = 0; + + m_CursorX = m_CursorY = 0; + m_DispLines = 16; +} + +CMemoryView::~CMemoryView() +{ +} + +BOOL CMemoryView::Create( HWND hWndParent ) +{ + m_logFont.lfCharSet = SHIFTJIS_CHARSET; + if( !(m_hFont = ::CreateFontIndirect( &m_logFont )) ) { + m_logFont.lfCharSet = ANSI_CHARSET; + if( !(m_hFont = ::CreateFontIndirect( &m_logFont )) ) { + return FALSE; + } + } + + HWND hWnd = ::CreateWindowEx( + WS_EX_TOOLWINDOW, + VIRTUANES_WNDCLASS, + "MemoryView", + WS_OVERLAPPEDWINDOW|WS_VSCROLL, // Windowgk”\ + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + hWndParent, + NULL, + CApp::GetInstance(), + (LPVOID)this // This 𖄂ߍވ + ); + if( !hWnd ) { + DEBUGOUT( "CreateWindow faild.\n" ); + return FALSE; + } + + m_hWnd = hWnd; + + return TRUE; +} + +void CMemoryView::Destroy() +{ + if( m_hWnd && IsWindow(m_hWnd) ) { + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcMemoryViewPos ); + + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } + + if( m_hFont ) { + ::DeleteObject( m_hFont ); + m_hFont = NULL; + } +} + +WNDMSG CMemoryView::OnCreate( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnCreate\n" ); + + // EChETCY̐ݒ + if( RCWIDTH(Config.general.rcMemoryViewPos) > 0 && RCHEIGHT(Config.general.rcMemoryViewPos) > 0 ) { + ::MoveWindow( m_hWnd, Config.general.rcMemoryViewPos.left, Config.general.rcMemoryViewPos.top, + RCWIDTH(Config.general.rcMemoryViewPos), RCHEIGHT(Config.general.rcMemoryViewPos), FALSE ); + } else { + RECT rw, rc; + ::GetWindowRect( m_hWnd, &rw ); + ::GetClientRect( m_hWnd, &rc ); + INT x = rw.right - rw.left - rc.right + OFFSETH*2+FONTWIDTH*71; + INT y = rw.bottom - rw.top - rc.bottom + OFFSETV*2+FONTHEIGHT*18; + ::MoveWindow( m_hWnd, 0, 0, x, y, FALSE ); + } + + RECT rc; + ::GetClientRect( m_hWnd, &rc ); + + // XN[W̐ݒ + m_DispLines = (RCHEIGHT(rc)-(OFFSETV*2+FONTHEIGHT*2))/FONTHEIGHT; + if( m_DispLines < 0 ) + m_DispLines = 0; + + DEBUGOUT( "Display Lines:%d\n", m_DispLines ); + DEBUGOUT( "Scroll Max :%d\n", (0xFFF-m_DispLines)<0?0:(0xFFF-m_DispLines) ); + + SCROLLINFO sif; + ::ZeroMemory( &sif, sizeof(sif) ); + sif.cbSize = sizeof(sif); + sif.fMask = SIF_ALL; + sif.nMin = 0; + sif.nMax = (0x1000-m_DispLines); + sif.nPos = 0; + sif.nPage = 1; + sif.nTrackPos = 1; + ::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE ); + m_StartAddress = 0; + + m_CursorX = m_CursorY = 0; + + // \ + ::ShowWindow( m_hWnd, SW_SHOW ); + + // ^C}[N + ::SetTimer( m_hWnd, 1, 50, NULL ); + return TRUE; +} + +WNDMSG CMemoryView::OnClose( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnClose\n" ); + ::KillTimer( m_hWnd, 1 ); + ::DestroyWindow( m_hWnd ); + return TRUE; +} + +WNDMSG CMemoryView::OnDestroy( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnDestroy\n" ); + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcMemoryViewPos ); + + m_hWnd = NULL; + return TRUE; +} + +WNDMSG CMemoryView::OnActivate( WNDMSGPARAM ) +{ + if( LOWORD(wParam) == WA_INACTIVE ) { +// DEBUGOUT( "CMemoryView::OnActivate:Inactive\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 ); + } else { +// DEBUGOUT( "CMemoryView::OnActivate:Active\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 ); + } + return TRUE; +} + +WNDMSG CMemoryView::OnSize( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnSize\n" ); + + m_DispLines = (HIWORD(lParam)-(OFFSETV*2+FONTHEIGHT*2))/FONTHEIGHT; + if( m_DispLines < 0 ) + m_DispLines = 0; + +// DEBUGOUT( "Display Lines:%d\n", m_DispLines ); + + SCROLLINFO sif; + ::ZeroMemory( &sif, sizeof(sif) ); + sif.cbSize = sizeof(sif); + sif.fMask = SIF_POS; + ::GetScrollInfo( m_hWnd, SB_VERT, &sif ); + + sif.fMask = SIF_POS|SIF_RANGE; + sif.nMin = 0; + sif.nMax = (0x1000-m_DispLines)<0?0:(0x1000-m_DispLines); + if( sif.nMin > sif.nPos ) + sif.nPos = sif.nMin; + if( sif.nMax < sif.nPos ) + sif.nPos = sif.nMax; + ::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE ); + + m_StartAddress = sif.nPos * 0x10; + + if( m_CursorY > m_DispLines-1 ) + m_CursorY = m_DispLines-1; + if( m_CursorY < 0 ) + m_CursorY = 0; + + return TRUE; +} + +WNDMSG CMemoryView::OnLButtonDown( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnLButtonDown\n" ); + + INT x = LOWORD(lParam); + INT y = HIWORD(lParam); + + x -= OFFSETH+FONTWIDTH*6; + y -= OFFSETV+FONTHEIGHT*2; + + if( x >= 0 && x < FONTWIDTH*(3*16) + && y >= 0 && y < FONTHEIGHT*m_DispLines ) { + if( (x%(FONTWIDTH*3)) < FONTWIDTH*2 ) { + m_CursorX = (x / (FONTWIDTH*3))*2; + m_CursorY = y / FONTHEIGHT; + } + } + + return TRUE; +} + +WNDMSG CMemoryView::OnMouseWheel( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnMouseWheel\n" ); + short zDelta = (short)HIWORD(wParam); + if( zDelta > 0 ) { + while( zDelta > 0 ) { + if( LOWORD(wParam) == MK_CONTROL ) + ::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0L ); + else + ::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0L ); + + zDelta -= 30; + } + return TRUE; + } else { + while( zDelta < 0 ) { + if( LOWORD(wParam) == MK_CONTROL ) + ::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0L ); + else + ::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0L ); + zDelta += 30; + } + } + return TRUE; +} + +WNDMSG CMemoryView::OnChar( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnChar\n" ); + + WORD wScrollNotify = 0xFFFF; + + CHAR Keys = ::toupper((CHAR)wParam); + + switch( Keys ) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if( m_DispLines ) { + INT addr = m_StartAddress+(m_CursorX/2)+m_CursorY*16; + BYTE data = CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + if( !(m_CursorX&1) ) { + data &= 0x0F; + data |= (Keys-'0')<<4; + } else { + data &= 0xF0; + data |= (Keys-'0'); + } + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + + if( ++m_CursorX > 32-1 ) { + if( ++m_CursorY > m_DispLines-1 ) { + wScrollNotify = SB_LINEDOWN; + m_CursorY = m_DispLines-1; + } + if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) { + m_CursorX = 32-1; + } else { + m_CursorX = 0; + } + } + } + break; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + if( m_DispLines ) { + INT addr = m_StartAddress+(m_CursorX/2)+m_CursorY*16; + BYTE data = CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + if( !(m_CursorX&1) ) { + data &= 0x0F; + data |= (Keys-'A'+10)<<4; + } else { + data &= 0xF0; + data |= (Keys-'A'+10); + } + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + if( ++m_CursorX > 32-1 ) { + if( ++m_CursorY > m_DispLines-1 ) { + wScrollNotify = SB_LINEDOWN; + m_CursorY = m_DispLines-1; + } + if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) { + m_CursorX = 32-1; + } else { + m_CursorX = 0; + } + } + } + break; + default: + break; + } + if( wScrollNotify != 0xFFFF ) + ::SendMessage( hWnd, WM_VSCROLL, MAKELONG(wScrollNotify, 0), 0L ); + + return TRUE; +} + +WNDMSG CMemoryView::OnKeyDown( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnKeyDown\n" ); + + WORD wScrollNotify = 0xFFFF; + + switch( wParam ) { + case VK_UP: + m_CursorX &= ~1; + if( --m_CursorY < 0 ) { + wScrollNotify = SB_LINEUP; + m_CursorY = 0; + } + break; + case VK_DOWN: + m_CursorX &= ~1; + if( ++m_CursorY > m_DispLines-1 ) { + wScrollNotify = SB_LINEDOWN; + m_CursorY = m_DispLines-1; + } + break; + case VK_LEFT: + if( m_CursorX & 1 ) { + m_CursorX &= ~1; + } else + if( (m_CursorX-=2) < 0 ) { + if( --m_CursorY < 0 ) { + wScrollNotify = SB_LINEUP; + m_CursorX = 0; + m_CursorY = 0; + } else { + m_CursorX = 32-1; + } + } + break; + case VK_RIGHT: + m_CursorX &= ~1; + if( (m_CursorX+=2) > 32-1 ) { + if( ++m_CursorY > m_DispLines-1 ) { + wScrollNotify = SB_LINEDOWN; + m_CursorY = m_DispLines-1; + } + if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) { + m_CursorX = 32-1; + } else { + m_CursorX = 0; + } + } + break; + + case VK_PRIOR: + m_CursorX &= ~1; + if( (m_CursorY-16) < 0 ) { + wScrollNotify = SB_PAGEUP; + if( m_StartAddress <= 0 ) { + m_CursorY = 0; + } + } else { + m_CursorY-= 16; + } + break; + case VK_NEXT: + m_CursorX &= ~1; + if( (m_CursorY+16) > m_DispLines-1 ) { + wScrollNotify = SB_PAGEDOWN; + if( m_StartAddress+m_DispLines*16 >= 0xFFFF ) { + m_CursorY = m_DispLines-1; + } + } else { + m_CursorY += 16; + } + break; + case VK_HOME: + wScrollNotify = SB_TOP; + m_CursorY = 0; + break; + case VK_END: + wScrollNotify = SB_BOTTOM; + m_CursorY = m_DispLines-1; + break; + default: + break; + } + if( wScrollNotify != 0xFFFF ) + ::SendMessage( hWnd, WM_VSCROLL, MAKELONG(wScrollNotify, 0), 0L ); + + return TRUE; +} + +WNDMSG CMemoryView::OnVScroll( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnVScroll\n" ); + + SCROLLINFO sif; + ::ZeroMemory( &sif, sizeof(sif) ); + sif.cbSize = sizeof(sif); + sif.fMask = SIF_POS|SIF_RANGE; + ::GetScrollInfo( m_hWnd, SB_VERT, &sif ); + + switch( LOWORD(wParam) ) { + case SB_TOP: + sif.nPos = 0; + break; + case SB_BOTTOM: + sif.nPos = sif.nMax; + break; + case SB_PAGEUP: + sif.nPos -= 16; + break; + case SB_PAGEDOWN: + sif.nPos += 16; + break; + case SB_LINEUP: + sif.nPos--; + break; + case SB_LINEDOWN: + sif.nPos++; + break; + case SB_THUMBTRACK: + sif.nPos = HIWORD(wParam); + break; + default: + break; + } + if( sif.nMin > sif.nPos ) + sif.nPos = sif.nMin; + if( sif.nMax < sif.nPos ) + sif.nPos = sif.nMax; + sif.fMask = SIF_POS; + ::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE ); + + m_StartAddress = sif.nPos * 0x10; + + return TRUE; +} + +WNDMSG CMemoryView::OnPaint( WNDMSGPARAM ) +{ +// DEBUGOUT( "CMemoryView::OnPaint\n" ); + + PAINTSTRUCT ps; + HDC hDC = ::BeginPaint( hWnd, &ps ); + RECT rc; + ::GetClientRect( m_hWnd, &rc ); + ::FillRect( hDC, &rc, (HBRUSH)::GetStockObject(WHITE_BRUSH) ); + OnDraw( hDC ); + ::EndPaint( hWnd, &ps ); + + return TRUE; +} + +WNDMSG CMemoryView::OnTimer( WNDMSGPARAM ) +{ + if( !Emu.IsRunning() ) + return TRUE; + + HDC hDC = ::GetDC( m_hWnd ); + OnDraw( hDC ); + ::ReleaseDC( m_hWnd, hDC ); + + return TRUE; +} + +void CMemoryView::OnDraw( HDC hDC ) +{ + RECT rc; + ::GetClientRect( m_hWnd, &rc ); + + HFONT hFontOld = (HFONT)::SelectObject( hDC, m_hFont ); + + ::SetBkMode( hDC, OPAQUE ); + ::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT* 0, "ADDR +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF", 71 ); + ::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT* 1, "-----------------------------------------------------------------------", 71 ); + + CHAR szBuf[256]; + INT address = m_StartAddress; + for( INT i = 0; i < m_DispLines; i++ ) { + ::wsprintf( szBuf, "%04X ", address&0xFFFF ); + + for( INT d = 0; d < 16; d++ ) { + CHAR szTemp[16]; + INT addr = address+d; + ::wsprintf( szTemp, "%02X ", CPU_MEM_BANK[addr>>13][addr&0x1FFF] ); + ::strcat( szBuf, szTemp ); + } + ::strcat( szBuf, " " ); + for( INT a = 0; a < 16; a++ ) { + CHAR szTemp[16]; + INT addr = address+a; + + if( m_logFont.lfCharSet == SHIFTJIS_CHARSET ) { + ::wsprintf( szTemp, "%1c", ::_ismbcprint(CPU_MEM_BANK[addr>>13][addr&0x1FFF])?CPU_MEM_BANK[addr>>13][addr&0x1FFF]:'.' ); + } else { + ::wsprintf( szTemp, "%1c", ::isprint(CPU_MEM_BANK[addr>>13][addr&0x1FFF])?CPU_MEM_BANK[addr>>13][addr&0x1FFF]:'.' ); + } + ::strcat( szBuf, szTemp ); + } + + ::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT*(2+i), szBuf, ::strlen(szBuf) ); + + address += 16; + address &= 0xFFFF; + } + + ::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT*(2+i), " ", 71 ); + + // Cursor + if( m_DispLines ) { + RECT rcInv; + rcInv.left = OFFSETH+FONTWIDTH*6+FONTWIDTH*3*(m_CursorX>>1)+FONTWIDTH*(m_CursorX&1)-1; + rcInv.top = OFFSETV+FONTHEIGHT*2+FONTHEIGHT*m_CursorY; + rcInv.right = rcInv.left+FONTWIDTH; + rcInv.bottom = rcInv.top+FONTHEIGHT; + ::InvertRect( hDC, &rcInv ); + + rcInv.left = OFFSETH+FONTWIDTH*55+FONTWIDTH*(m_CursorX>>1)-1; + rcInv.top = OFFSETV+FONTHEIGHT*2+FONTHEIGHT*m_CursorY; + rcInv.right = rcInv.left+FONTWIDTH; + rcInv.bottom = rcInv.top+FONTHEIGHT; + ::InvertRect( hDC, &rcInv ); + } + + // ɖ߂ďH + ::SelectObject( hDC, hFontOld ); +} + diff --git a/References/VirtuaNESex_src_191105/MemoryView.h b/References/VirtuaNESex_src_191105/MemoryView.h new file mode 100644 index 00000000..01e85eb8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MemoryView.h @@ -0,0 +1,55 @@ +// +// r[NX +// +#ifndef __CMEMORYVIEW_INCLUDED__ +#define __CMEMORYVIEW_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CMemoryView : public CWnd +{ +public: + // Constructor/Destructor + CMemoryView(); + ~CMemoryView(); + + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + // Message map + WND_MESSAGE_MAP() + WNDMSG OnCreate( WNDMSGPARAM ); + WNDMSG OnClose( WNDMSGPARAM ); + WNDMSG OnDestroy( WNDMSGPARAM ); + WNDMSG OnActivate( WNDMSGPARAM ); + WNDMSG OnSize( WNDMSGPARAM ); + WNDMSG OnLButtonDown( WNDMSGPARAM ); + WNDMSG OnMouseWheel( WNDMSGPARAM ); + WNDMSG OnChar( WNDMSGPARAM ); + WNDMSG OnKeyDown( WNDMSGPARAM ); + WNDMSG OnVScroll( WNDMSGPARAM ); + WNDMSG OnPaint( WNDMSGPARAM ); + WNDMSG OnTimer( WNDMSGPARAM ); + // + + void OnDraw( HDC hDC ); + + static LOGFONT m_logFont; + HFONT m_hFont; + + INT m_StartAddress; + INT m_DispLines; + + INT m_CursorX, m_CursorY; +private: +}; + +#endif // !__CMEMORYVIEW_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/MovieDlg.cpp b/References/VirtuaNESex_src_191105/MovieDlg.cpp new file mode 100644 index 00000000..6f89df74 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MovieDlg.cpp @@ -0,0 +1,77 @@ +// +// o[W_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" + +#include "Wnd.h" +#include "MovieDlg.h" + +DLG_MESSAGE_BEGIN(CMovieDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CMovieDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_MOVIE), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CMovieDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CAboutDlg::OnInitDialog\n" ); + + m_ConfigSave = Config.movie; + BTNCHECK( IDC_MVI_1P_USE, Config.movie.bUsePlayer[0]?TRUE:FALSE ); + BTNCHECK( IDC_MVI_2P_USE, Config.movie.bUsePlayer[1]?TRUE:FALSE ); + BTNCHECK( IDC_MVI_3P_USE, Config.movie.bUsePlayer[2]?TRUE:FALSE ); + BTNCHECK( IDC_MVI_4P_USE, Config.movie.bUsePlayer[3]?TRUE:FALSE ); + BTNCHECK( IDC_MVI_RESETRECORD, Config.movie.bResetRec ); + BTNCHECK( IDC_MVI_RERECORD_DISABLE, !Config.movie.bRerecord ); + BTNCHECK( IDC_MVI_LOOPPLAY, Config.movie.bLoopPlay ); + BTNCHECK( IDC_MVI_PADDISPLAY, Config.movie.bPadDisplay ); + + return TRUE; +} + +DLGCMD CMovieDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CMovieDlg::OnOK\n" ); + + Config.movie.bUsePlayer[0] = IsBTNCHECK(IDC_MVI_1P_USE)?0xFF:0x00; + Config.movie.bUsePlayer[1] = IsBTNCHECK(IDC_MVI_2P_USE)?0xFF:0x00; + Config.movie.bUsePlayer[2] = IsBTNCHECK(IDC_MVI_3P_USE)?0xFF:0x00; + Config.movie.bUsePlayer[3] = IsBTNCHECK(IDC_MVI_4P_USE)?0xFF:0x00; + Config.movie.bResetRec = IsBTNCHECK( IDC_MVI_RESETRECORD ); + Config.movie.bRerecord = !IsBTNCHECK( IDC_MVI_RERECORD_DISABLE ); + Config.movie.bLoopPlay = IsBTNCHECK( IDC_MVI_LOOPPLAY ); + Config.movie.bPadDisplay = IsBTNCHECK( IDC_MVI_PADDISPLAY ); + + // SOFF̏ꍇ1PL^”\ɂĂ + if( !Config.movie.bUsePlayer[0] && !Config.movie.bUsePlayer[1] + && !Config.movie.bUsePlayer[2] && !Config.movie.bUsePlayer[3] ) { + Config.movie.bUsePlayer[0] = 0xFF; + } + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CMovieDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CMovieDlg::OnCancel\n" ); + Config.movie = m_ConfigSave; + ::EndDialog( m_hWnd, IDCANCEL ); +} + diff --git a/References/VirtuaNESex_src_191105/MovieDlg.h b/References/VirtuaNESex_src_191105/MovieDlg.h new file mode 100644 index 00000000..cdf10863 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MovieDlg.h @@ -0,0 +1,34 @@ +// +// [r[_CAONX +// +#ifndef __CMOVIEDLG_INCLUDED__ +#define __CMOVIEDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CMovieDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // + + CCfgMovie m_ConfigSave; +private: +}; + +#endif // !__CMOVIEDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/MovieInfoDlg.cpp b/References/VirtuaNESex_src_191105/MovieInfoDlg.cpp new file mode 100644 index 00000000..e7cac520 --- /dev/null +++ b/References/VirtuaNESex_src_191105/MovieInfoDlg.cpp @@ -0,0 +1,89 @@ +// +// [r[_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "MovieInfoDlg.h" + +DLG_MESSAGE_BEGIN(CMovieInfoDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CMovieInfoDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_MOVIEINFO), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CMovieInfoDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CMovieInfoDlg::OnInitDialog\n" ); + + CHAR szTemp[256]; + + ::wsprintf( szTemp, "%01d.%01d%01d", + (m_wRecVersion&0xF00)>>8, + (m_wRecVersion&0x0F0)>>4, + (m_wRecVersion&0x00F) ); + ::SetDlgItemText( m_hWnd, IDC_MIF_RERECORDVERSION, szTemp ); + + ::wsprintf( szTemp, "%04X", m_wVersion ); + ::SetDlgItemText( m_hWnd, IDC_MIF_VERSION, szTemp ); + + // t[ + ::wsprintf( szTemp, "%d frames", m_dwFrames ); + ::SetDlgItemText( m_hWnd, IDC_MIF_FRAMES, szTemp ); + + // + INT t, h, m, s; + t = (INT)m_dwFrames; + h = t / (60*60*60); + t -= h * (60*60*60); + m = t / (60*60); + t -= m * (60*60); + s = t / 60; + + ::wsprintf( szTemp, "%02d:%02d:%02d", h, m, s ); + ::SetDlgItemText( m_hWnd, IDC_MIF_TIMES, szTemp ); + + // B蒼 + if( m_dwRerecordTimes == 0xFFFFFFFF ) { + ::SetDlgItemText( m_hWnd, IDC_MIF_RERECORDTIMES, "----" ); + } else { + ::wsprintf( szTemp, "%d times", m_dwRerecordTimes ); + ::SetDlgItemText( m_hWnd, IDC_MIF_RERECORDTIMES, szTemp ); + } + + return TRUE; +} + +DLGCMD CMovieInfoDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CMovieInfoDlg::OnOK\n" ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CMovieInfoDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CMovieInfoDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + diff --git a/References/VirtuaNESex_src_191105/MovieInfoDlg.h b/References/VirtuaNESex_src_191105/MovieInfoDlg.h new file mode 100644 index 00000000..b01aefea --- /dev/null +++ b/References/VirtuaNESex_src_191105/MovieInfoDlg.h @@ -0,0 +1,36 @@ +// +// [r[_CAONX +// +#ifndef __CMOVIEINFODLG_INCLUDED__ +#define __CMOVIEINFODLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CMovieInfoDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + + WORD m_wRecVersion; + WORD m_wVersion; + DWORD m_dwFrames; + DWORD m_dwRerecordTimes; + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // +private: +}; + +#endif // !__CMOVIEINFODLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/APU.cpp b/References/VirtuaNESex_src_191105/NES/APU.cpp new file mode 100644 index 00000000..05611672 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/APU.cpp @@ -0,0 +1,635 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES APU core // +// Norix // +// written 2002/06/27 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#include "DebugOut.h" +#include "App.h" +#include "Config.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "rom.h" +#include "apu.h" + +// Volume adjust +// Internal sounds +#define RECTANGLE_VOL (0x0F0) +#define TRIANGLE_VOL (0x130) +#define NOISE_VOL (0x0C0) +#define DPCM_VOL (0x0F0) +// Extra sounds +#define VRC6_VOL (0x0F0) +#define VRC7_VOL (0x130) +#define FDS_VOL (0x0F0) +#define MMC5_VOL (0x0F0) +#define N106_VOL (0x088) +#define FME7_VOL (0x130) + +APU::APU( NES* parent ) +{ + exsound_select = 0; + + nes = parent; + internal.SetParent( parent ); + + last_data = last_diff = 0; + + ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) ); + + ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) ); + ZEROMEMORY( &queue, sizeof(queue) ); + ZEROMEMORY( &exqueue, sizeof(exqueue) ); + + for( INT i = 0; i < 16; i++ ) { + m_bMute[i] = TRUE; + } +} + +APU::~APU() +{ +} + +void APU::SetQueue( INT writetime, WORD addr, BYTE data ) +{ + queue.data[queue.wrptr].time = writetime; + queue.data[queue.wrptr].addr = addr; + queue.data[queue.wrptr].data = data; + queue.wrptr++; + queue.wrptr&=QUEUE_LENGTH-1; + if( queue.wrptr == queue.rdptr ) { + DEBUGOUT( "queue overflow.\n" ); + } +} + +BOOL APU::GetQueue( INT writetime, QUEUEDATA& ret ) +{ + if( queue.wrptr == queue.rdptr ) { + return FALSE; + } + if( queue.data[queue.rdptr].time <= writetime ) { + ret = queue.data[queue.rdptr]; + queue.rdptr++; + queue.rdptr&=QUEUE_LENGTH-1; + return TRUE; + } + return FALSE; +} + +void APU::SetExQueue( INT writetime, WORD addr, BYTE data ) +{ + exqueue.data[exqueue.wrptr].time = writetime; + exqueue.data[exqueue.wrptr].addr = addr; + exqueue.data[exqueue.wrptr].data = data; + exqueue.wrptr++; + exqueue.wrptr&=QUEUE_LENGTH-1; + if( exqueue.wrptr == exqueue.rdptr ) { + DEBUGOUT( "exqueue overflow.\n" ); + } +} + +BOOL APU::GetExQueue( INT writetime, QUEUEDATA& ret ) +{ + if( exqueue.wrptr == exqueue.rdptr ) { + return FALSE; + } + if( exqueue.data[exqueue.rdptr].time <= writetime ) { + ret = exqueue.data[exqueue.rdptr]; + exqueue.rdptr++; + exqueue.rdptr&=QUEUE_LENGTH-1; + return TRUE; + } + return FALSE; +} + +void APU::QueueClear() +{ + ZEROMEMORY( &queue, sizeof(queue) ); + ZEROMEMORY( &exqueue, sizeof(exqueue) ); +} + +void APU::QueueFlush() +{ + while( queue.wrptr != queue.rdptr ) { + WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data ); + queue.rdptr++; + queue.rdptr&=QUEUE_LENGTH-1; + } + + while( exqueue.wrptr != exqueue.rdptr ) { + WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data ); + exqueue.rdptr++; + exqueue.rdptr&=QUEUE_LENGTH-1; + } +} + +void APU::SoundSetup() +{ + FLOAT fClock = nes->nescfg->CpuClock; + INT nRate = (INT)Config.sound.nRate; + internal.Setup( fClock, nRate ); + vrc6.Setup( fClock, nRate ); + vrc7.Setup( fClock, nRate ); + mmc5.Setup( fClock, nRate ); + fds.Setup ( fClock, nRate ); + n106.Setup( fClock, nRate ); + fme7.Setup( fClock, nRate ); +} + +void APU::Reset() +{ + ZEROMEMORY( &queue, sizeof(queue) ); + ZEROMEMORY( &exqueue, sizeof(exqueue) ); + + elapsed_time = 0; + + FLOAT fClock = nes->nescfg->CpuClock; + INT nRate = (INT)Config.sound.nRate; + internal.Reset( fClock, nRate ); + vrc6.Reset( fClock, nRate ); + vrc7.Reset( fClock, nRate ); + mmc5.Reset( fClock, nRate ); + fds.Reset ( fClock, nRate ); + n106.Reset( fClock, nRate ); + fme7.Reset( fClock, nRate ); + + SoundSetup(); +} + +void APU::SelectExSound( BYTE data ) +{ + exsound_select = data; +} + +BYTE APU::Read( WORD addr ) +{ + return internal.SyncRead( addr ); +} + +void APU::Write( WORD addr, BYTE data ) +{ + // $4018VirtuaNESŗL|[g + if( addr >= 0x4000 && addr <= 0x401F ) { + internal.SyncWrite( addr, data ); + SetQueue( nes->cpu->GetTotalCycles(), addr, data ); + } +} + +BYTE APU::ExRead( WORD addr ) +{ +BYTE data = 0; + + if( exsound_select & 0x10 ) { + if( addr == 0x4800 ) { + SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 ); + } + } + if( exsound_select & 0x04 ) { + if( addr >= 0x4040 && addr < 0x4100 ) { + data = fds.SyncRead( addr ); + } + } + if( exsound_select & 0x08 ) { + if( addr >= 0x5000 && addr <= 0x5015 ) { + data = mmc5.SyncRead( addr ); + } + } + + return data; +} + +void APU::ExWrite( WORD addr, BYTE data ) +{ + SetExQueue( nes->cpu->GetTotalCycles(), addr, data ); + + if( exsound_select & 0x04 ) { + if( addr >= 0x4040 && addr < 0x4100 ) { + fds.SyncWrite( addr, data ); + } + } + + if( exsound_select & 0x08 ) { + if( addr >= 0x5000 && addr <= 0x5015 ) { + mmc5.SyncWrite( addr, data ); + } + } +} + +void APU::Sync() +{ +} + +void APU::SyncDPCM( INT cycles ) +{ + internal.Sync( cycles ); + + if( exsound_select & 0x04 ) { + fds.Sync( cycles ); + } + if( exsound_select & 0x08 ) { + mmc5.Sync( cycles ); + } +} + +void APU::WriteProcess( WORD addr, BYTE data ) +{ + // $4018VirtuaNESŗL|[g + if( addr >= 0x4000 && addr <= 0x401F ) { + internal.Write( addr, data ); + } +} + +void APU::WriteExProcess( WORD addr, BYTE data ) +{ + if( exsound_select & 0x01 ) { + vrc6.Write( addr, data ); + } + if( exsound_select & 0x02 ) { + vrc7.Write( addr, data ); + } + if( exsound_select & 0x04 ) { + fds.Write( addr, data ); + } + if( exsound_select & 0x08 ) { + mmc5.Write( addr, data ); + } + if( exsound_select & 0x10 ) { + if( addr == 0x0000 ) { + BYTE dummy = n106.Read( addr ); + } else { + n106.Write( addr, data ); + } + } + if( exsound_select & 0x20 ) { + fme7.Write( addr, data ); + } +} + +void APU::Process( LPBYTE lpBuffer, DWORD dwSize ) +{ +INT nBits = Config.sound.nBits; +DWORD dwLength = dwSize / (nBits/8); +INT output; +QUEUEDATA q; +DWORD writetime; + +LPSHORT pSoundBuf = m_SoundBuffer; +INT nCcount = 0; + +INT nFilterType = Config.sound.nFilterType; + + if( !Config.sound.bEnable ) { + ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) ); + return; + } + + // Volume setup + // 0:Master + // 1:Rectangle 1 + // 2:Rectangle 2 + // 3:Triangle + // 4:Noise + // 5:DPCM + // 6:VRC6 + // 7:VRC7 + // 8:FDS + // 9:MMC5 + // 10:N106 + // 11:FME7 + INT vol[24]; + BOOL* bMute = m_bMute; + SHORT* nVolume = Config.sound.nVolume; + + INT nMasterVolume = bMute[0]?nVolume[0]:0; + + // Internal + vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0; + vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0; + vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0; + vol[ 3] = bMute[4]?(NOISE_VOL *nVolume[4]*nMasterVolume)/(100*100):0; + vol[ 4] = bMute[5]?(DPCM_VOL *nVolume[5]*nMasterVolume)/(100*100):0; + + // VRC6 + vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0; + vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0; + vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0; + + // VRC7 + vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0; + + // FDS + vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0; + + // MMC5 + vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0; + vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0; + vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0; + + // N106 + vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0; + + // FME7 + vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0; + vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0; + vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0; + +// double cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate; + double cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate; + + // CPUTCN[vĂ܂̑΍􏈗 + if( elapsed_time > nes->cpu->GetTotalCycles() ) { + QueueFlush(); + } + + while( dwLength-- ) { + writetime = (DWORD)elapsed_time; + + while( GetQueue( writetime, q ) ) { + WriteProcess( q.addr, q.data ); + } + + while( GetExQueue( writetime, q ) ) { + WriteExProcess( q.addr, q.data ); + } + + // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7 + output = 0; + output += internal.Process( 0 )*vol[0]; + output += internal.Process( 1 )*vol[1]; + output += internal.Process( 2 )*vol[2]; + output += internal.Process( 3 )*vol[3]; + output += internal.Process( 4 )*vol[4]; + + if( exsound_select & 0x01 ) { + output += vrc6.Process( 0 )*vol[5]; + output += vrc6.Process( 1 )*vol[6]; + output += vrc6.Process( 2 )*vol[7]; + } + if( exsound_select & 0x02 ) { + output += vrc7.Process( 0 )*vol[8]; + } + if( exsound_select & 0x04 ) { + output += fds.Process( 0 )*vol[9]; + } + if( exsound_select & 0x08 ) { + output += mmc5.Process( 0 )*vol[10]; + output += mmc5.Process( 1 )*vol[11]; + output += mmc5.Process( 2 )*vol[12]; + } + if( exsound_select & 0x10 ) { + output += n106.Process( 0 )*vol[13]; + output += n106.Process( 1 )*vol[14]; + output += n106.Process( 2 )*vol[15]; + output += n106.Process( 3 )*vol[16]; + output += n106.Process( 4 )*vol[17]; + output += n106.Process( 5 )*vol[18]; + output += n106.Process( 6 )*vol[19]; + output += n106.Process( 7 )*vol[20]; + } + if( exsound_select & 0x20 ) { + fme7.Process( 3 ); // Envelope & Noise + output += fme7.Process( 0 )*vol[21]; + output += fme7.Process( 1 )*vol[22]; + output += fme7.Process( 2 )*vol[23]; + } + + output >>= 8; + + if( nFilterType == 1 ) { + //[pXtB^[TYPE 1(Simple) + output = (lowpass_filter[0]+output)/2; + lowpass_filter[0] = output; + } else if( nFilterType == 2 ) { + //[pXtB^[TYPE 2(Weighted type 1) + output = (lowpass_filter[1]+lowpass_filter[0]+output)/3; + lowpass_filter[1] = lowpass_filter[0]; + lowpass_filter[0] = output; + } else if( nFilterType == 3 ) { + //[pXtB^[TYPE 3(Weighted type 2) + output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4; + lowpass_filter[2] = lowpass_filter[1]; + lowpass_filter[1] = lowpass_filter[0]; + lowpass_filter[0] = output; + } else if( nFilterType == 4 ) { + //[pXtB^[TYPE 4(Weighted type 3) + output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4; + lowpass_filter[1] = lowpass_filter[0]; + lowpass_filter[0] = output; + } + +#if 0 + // DC̃Jbg + { + static double ave = 0.0, max=0.0, min=0.0; + double delta; + delta = (max-min)/32768.0; + max -= delta; + min += delta; + if( output > max ) max = output; + if( output < min ) min = output; + ave -= ave/1024.0; + ave += (max+min)/2048.0; + output -= (INT)ave; + } +#endif +#if 1 + // DC̃Jbg(HPF TEST) + { +// static double cutoff = (2.0*3.141592653579*40.0/44100.0); + static double cutofftemp = (2.0*3.141592653579*40.0); + double cutoff = cutofftemp/(double)Config.sound.nRate; + static double tmp = 0.0; + double in, out; + + in = (double)output; + out = (in - tmp); + tmp = tmp + cutoff * out; + + output = (INT)out; + } +#endif +#if 0 + // XpCNmCY̏(AGC TEST) + { + INT diff = abs(output-last_data); + if( diff > 0x4000 ) { + output /= 4; + } else + if( diff > 0x3000 ) { + output /= 3; + } else + if( diff > 0x2000 ) { + output /= 2; + } + last_data = output; + } +#endif + // Limit + if( output > 0x7FFF ) { + output = 0x7FFF; + } else if( output < -0x8000 ) { + output = -0x8000; + } + + if( nBits != 8 ) { + *(SHORT*)lpBuffer = (SHORT)output; + lpBuffer += sizeof(SHORT); + } else { + *lpBuffer++ = (output>>8)^0x80; + } + + if( nCcount < 0x0100 ) + pSoundBuf[nCcount++] = (SHORT)output; + +// elapsedtime += cycle_rate; + elapsed_time += cycle_rate; + } + +#if 1 + if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) { + elapsed_time = nes->cpu->GetTotalCycles(); + } + if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) { + elapsed_time = nes->cpu->GetTotalCycles(); + } +#else + elapsed_time = nes->cpu->GetTotalCycles(); +#endif +} + +// `l̎g擾Tu[`(NSFp) +INT APU::GetChannelFrequency( INT no ) +{ + if( !m_bMute[0] ) + return 0; + + // Internal + if( no < 5 ) { + return m_bMute[no+1]?internal.GetFreq( no ):0; + } + // VRC6 + if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) { + return m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0; + } + // FDS + if( (exsound_select & 0x04) && no == 0x300 ) { + return m_bMute[6]?fds.GetFreq( 0 ):0; + } + // MMC5 + if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) { + return m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0; + } + // N106 + if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) { + return m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0; + } + // FME7 + if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) { + return m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0; + } + // VRC7 + if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) { + return m_bMute[6]?vrc7.GetFreq(no&0x0F):0; + } + return 0; +} + +// State Save/Load +void APU::SaveState( LPBYTE p ) +{ +#ifdef _DEBUG +LPBYTE pold = p; +#endif + + // Ԏ𓯊Flush + QueueFlush(); + + internal.SaveState( p ); + p += (internal.GetStateSize()+15)&(~0x0F); // Padding + + // VRC6 + if( exsound_select & 0x01 ) { + vrc6.SaveState( p ); + p += (vrc6.GetStateSize()+15)&(~0x0F); // Padding + } + // VRC7 (not support) + if( exsound_select & 0x02 ) { + vrc7.SaveState( p ); + p += (vrc7.GetStateSize()+15)&(~0x0F); // Padding + } + // FDS + if( exsound_select & 0x04 ) { + fds.SaveState( p ); + p += (fds.GetStateSize()+15)&(~0x0F); // Padding + } + // MMC5 + if( exsound_select & 0x08 ) { + mmc5.SaveState( p ); + p += (mmc5.GetStateSize()+15)&(~0x0F); // Padding + } + // N106 + if( exsound_select & 0x10 ) { + n106.SaveState( p ); + p += (n106.GetStateSize()+15)&(~0x0F); // Padding + } + // FME7 + if( exsound_select & 0x20 ) { + fme7.SaveState( p ); + p += (fme7.GetStateSize()+15)&(~0x0F); // Padding + } + +#ifdef _DEBUG +DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold ); +#endif +} + +void APU::LoadState( LPBYTE p ) +{ + // Ԏ𓯊ׂɏ + QueueClear(); + + internal.LoadState( p ); + p += (internal.GetStateSize()+15)&(~0x0F); // Padding + + // VRC6 + if( exsound_select & 0x01 ) { + vrc6.LoadState( p ); + p += (vrc6.GetStateSize()+15)&(~0x0F); // Padding + } + // VRC7 (not support) + if( exsound_select & 0x02 ) { + vrc7.LoadState( p ); + p += (vrc7.GetStateSize()+15)&(~0x0F); // Padding + } + // FDS + if( exsound_select & 0x04 ) { + fds.LoadState( p ); + p += (fds.GetStateSize()+15)&(~0x0F); // Padding + } + // MMC5 + if( exsound_select & 0x08 ) { + mmc5.LoadState( p ); + p += (mmc5.GetStateSize()+15)&(~0x0F); // Padding + } + // N106 + if( exsound_select & 0x10 ) { + n106.LoadState( p ); + p += (n106.GetStateSize()+15)&(~0x0F); // Padding + } + // FME7 + if( exsound_select & 0x20 ) { + fme7.LoadState( p ); + p += (fme7.GetStateSize()+15)&(~0x0F); // Padding + } +} diff --git a/References/VirtuaNESex_src_191105/NES/APU.h b/References/VirtuaNESex_src_191105/NES/APU.h new file mode 100644 index 00000000..90ba0f1e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/APU.h @@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES APU core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __APU_INCLUDED__ +#define __APU_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "typedef.h" +#include "macro.h" + +#include "APU_INTERNAL.h" +#include "APU_VRC6.h" +#include "APU_VRC7.h" +#include "APU_MMC5.h" +#include "APU_FDS.h" +#include "APU_N106.h" +#include "APU_FME7.h" + +#define QUEUE_LENGTH 4096 + +// class prototype +class NES; + +class APU +{ +public: + APU( NES* parent ); + virtual ~APU(); + + void SoundSetup(); + void SelectExSound( BYTE data ); + + BOOL SetChannelMute( INT nCH ) { m_bMute[nCH] = !m_bMute[nCH]; return m_bMute[nCH]; } + + void QueueClear(); + + void Reset(); + BYTE Read( WORD addr ); + void Write( WORD addr, BYTE data ); + BYTE ExRead( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + + void Sync(); + void SyncDPCM( INT cycles ); + + void Process( LPBYTE lpBuffer, DWORD dwSize ); + + // For NSF player + INT GetChannelFrequency( INT ch ); + LPSHORT GetSoundBuffer() { return m_SoundBuffer; } + + // For State + void GetFrameIRQ( INT& Cycle, BYTE& Count, BYTE& Type, BYTE& IRQ, BYTE& Occur ) { + internal.GetFrameIRQ( Cycle, Count, Type, IRQ, Occur ); + } + + void SetFrameIRQ( INT Cycle, BYTE Count, BYTE Type, BYTE IRQ, BYTE Occur ) { + internal.SetFrameIRQ( Cycle, Count, Type, IRQ, Occur ); + } + + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); +protected: + typedef struct { + INT time; + WORD addr; + BYTE data; + BYTE reserved; + } QUEUEDATA, *LPQUEUEDATA; + + typedef struct { + INT rdptr; + INT wrptr; + QUEUEDATA data[QUEUE_LENGTH]; + } QUEUE, *LPQUEUE; + + void SetQueue( INT writetime, WORD addr, BYTE data ); + BOOL GetQueue( INT writetime, QUEUEDATA& ret ); + + void SetExQueue( INT writetime, WORD addr, BYTE data ); + BOOL GetExQueue( INT writetime, QUEUEDATA& ret ); + + void QueueFlush(); + + void WriteProcess( WORD addr, BYTE data ); + void WriteExProcess( WORD addr, BYTE data ); + + NES* nes; + + QUEUE queue; + QUEUE exqueue; + + BYTE exsound_select; + + double elapsed_time; +// INT elapsed_time; + + // Filter + INT last_data, last_diff; + INT lowpass_filter[4]; + + // Sound core + APU_INTERNAL internal; + APU_VRC6 vrc6; + APU_VRC7 vrc7; + APU_MMC5 mmc5; + APU_FDS fds; + APU_N106 n106; + APU_FME7 fme7; + + // Channel mute + BOOL m_bMute[16]; + + // ܂ + SHORT m_SoundBuffer[0x100]; +private: +}; + +#endif // !__APU_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FDS.cpp b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FDS.cpp new file mode 100644 index 00000000..fdb9287e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FDS.cpp @@ -0,0 +1,379 @@ +////////////////////////////////////////////////////////////////////////// +// // +// FDS sound // +// Norix // +// written 2002/06/30 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#include "DebugOut.h" + +#include "APU_FDS.h" +#include "state.h" + +APU_FDS::APU_FDS() +{ + ZEROMEMORY( &fds, sizeof(fds) ); + ZEROMEMORY( &fds_sync, sizeof(fds) ); + + ZEROMEMORY( output_buf, sizeof(output_buf) ); + + sampling_rate = 22050; +} + +APU_FDS::~APU_FDS() +{ +} + +void APU_FDS::Reset( FLOAT fClock, INT nRate ) +{ + ZEROMEMORY( &fds, sizeof(fds) ); + ZEROMEMORY( &fds_sync, sizeof(fds) ); + + sampling_rate = nRate; +} + +void APU_FDS::Setup( FLOAT fClock, INT nRate ) +{ + sampling_rate = nRate; +} + +void APU_FDS::WriteSub( WORD addr, BYTE data, FDSSOUND& ch, double rate ) +{ + if( addr < 0x4040 || addr > 0x40BF ) + return; + + ch.reg[addr-0x4040] = data; + if( addr >= 0x4040 && addr <= 0x407F ) { + if( ch.wave_setup ) { + ch.main_wavetable[addr-0x4040] = 0x20-((INT)data&0x3F); + } + } else { + switch( addr ) { + case 0x4080: // Volume Envelope + ch.volenv_mode = data>>6; + if( data&0x80 ) { + ch.volenv_gain = data&0x3F; + + // f + if( !ch.main_addr ) { + ch.now_volume = (ch.volenv_gain<0x21)?ch.volenv_gain:0x20; + } + } + // Gx[v1iK̉Z + ch.volenv_decay = data&0x3F; + ch.volenv_phaseacc = (double)ch.envelope_speed * (double)(ch.volenv_decay+1) * rate / (232.0*960.0); + break; + + case 0x4082: // Main Frequency(Low) + ch.main_frequency = (ch.main_frequency&~0x00FF)|(INT)data; + break; + case 0x4083: // Main Frequency(High) + ch.main_enable = (~data)&(1<<7); + ch.envelope_enable = (~data)&(1<<6); + if( !ch.main_enable ) { + ch.main_addr = 0; + ch.now_volume = (ch.volenv_gain<0x21)?ch.volenv_gain:0x20; + } + ch.main_frequency = (ch.main_frequency&0x00FF)|(((INT)data&0x0F)<<8); + break; + + case 0x4084: // Sweep Envelope + ch.swpenv_mode = data>>6; + if( data&0x80 ) { + ch.swpenv_gain = data&0x3F; + } + // Gx[v1iK̉Z + ch.swpenv_decay = data&0x3F; + ch.swpenv_phaseacc = (double)ch.envelope_speed * (double)(ch.swpenv_decay+1) * rate / (232.0*960.0); + break; + + case 0x4085: // Sweep Bias + if( data&0x40 ) ch.sweep_bias = (data&0x3f)-0x40; + else ch.sweep_bias = data&0x3f; + ch.lfo_addr = 0; + break; + + case 0x4086: // Effector(LFO) Frequency(Low) + ch.lfo_frequency = (ch.lfo_frequency&(~0x00FF))|(INT)data; + break; + case 0x4087: // Effector(LFO) Frequency(High) + ch.lfo_enable = (~data&0x80); + ch.lfo_frequency = (ch.lfo_frequency&0x00FF)|(((INT)data&0x0F)<<8); + break; + + case 0x4088: // Effector(LFO) wavetable + if( !ch.lfo_enable ) { + // FIFO? + for( INT i = 0; i < 31; i++ ) { + ch.lfo_wavetable[i*2+0] = ch.lfo_wavetable[(i+1)*2+0]; + ch.lfo_wavetable[i*2+1] = ch.lfo_wavetable[(i+1)*2+1]; + } + ch.lfo_wavetable[31*2+0] = data&0x07; + ch.lfo_wavetable[31*2+1] = data&0x07; + } + break; + + case 0x4089: // Sound control + { + INT tbl[] = {30, 20, 15, 12}; + ch.master_volume = tbl[data&3]; + ch.wave_setup = data&0x80; + } + break; + + case 0x408A: // Sound control 2 + ch.envelope_speed = data; + break; + + default: + break; + } + } +} + +// APU_Ă΂ +void APU_FDS::Write( WORD addr, BYTE data ) +{ + // TvO[g + WriteSub( addr, data, fds, (double)sampling_rate ); +} + +BYTE APU_FDS::Read ( WORD addr ) +{ +BYTE data = addr>>8; + + if( addr >= 0x4040 && addr <= 0x407F ) { + data = fds.main_wavetable[addr&0x3F] | 0x40; + } else + if( addr == 0x4090 ) { + data = (fds.volenv_gain&0x3F)|0x40; + } else + if( addr == 0x4092 ) { + data = (fds.swpenv_gain&0x3F)|0x40; + } + + return data; +} + +INT APU_FDS::Process( INT channel ) +{ + // Envelope unit + if( fds.envelope_enable && fds.envelope_speed ) { + // Volume envelope + if( fds.volenv_mode < 2 ) { + double decay = ((double)fds.envelope_speed * (double)(fds.volenv_decay+1) * (double)sampling_rate) / (232.0*960.0); + fds.volenv_phaseacc -= 1.0; + while( fds.volenv_phaseacc < 0.0 ) { + fds.volenv_phaseacc += decay; + + if( fds.volenv_mode == 0 ) { + // [h + if( fds.volenv_gain ) + fds.volenv_gain--; + } else + if( fds.volenv_mode == 1 ) { + if( fds.volenv_gain < 0x20 ) + fds.volenv_gain++; + } + } + } + + // Sweep envelope + if( fds.swpenv_mode < 2 ) { + double decay = ((double)fds.envelope_speed * (double)(fds.swpenv_decay+1) * (double)sampling_rate) / (232.0*960.0); + fds.swpenv_phaseacc -= 1.0; + while( fds.swpenv_phaseacc < 0.0 ) { + fds.swpenv_phaseacc += decay; + + if( fds.swpenv_mode == 0 ) { + // [h + if( fds.swpenv_gain ) + fds.swpenv_gain--; + } else + if( fds.swpenv_mode == 1 ) { + if( fds.swpenv_gain < 0x20 ) + fds.swpenv_gain++; + } + } + } + } + + // Effector(LFO) unit + INT sub_freq = 0; + if( fds.lfo_enable && fds.envelope_speed && fds.lfo_frequency ) { + static int tbl[8] = { 0, 1, 2, 4, 0, -4, -2, -1}; + + fds.lfo_phaseacc -= (1789772.5*(double)fds.lfo_frequency)/65536.0; + while( fds.lfo_phaseacc < 0.0 ) { + fds.lfo_phaseacc += (double)sampling_rate; + + if( fds.lfo_wavetable[fds.lfo_addr] == 4 ) + fds.sweep_bias = 0; + else + fds.sweep_bias += tbl[fds.lfo_wavetable[fds.lfo_addr]]; + + fds.lfo_addr = (fds.lfo_addr+1)&63; + } + + if( fds.sweep_bias > 63 ) + fds.sweep_bias -= 128; + else if( fds.sweep_bias < -64 ) + fds.sweep_bias += 128; + + INT sub_multi = fds.sweep_bias * fds.swpenv_gain; + + if( sub_multi & 0x0F ) { + // 16Ŋ؂Ȃꍇ + sub_multi = (sub_multi / 16); + if( fds.sweep_bias >= 0 ) + sub_multi += 2; // ̏ꍇ + else + sub_multi -= 1; // ̏ꍇ + } else { + // 16Ŋ؂ꍇ + sub_multi = (sub_multi / 16); + } + // 193𒴂-258(-64փbv) + if( sub_multi > 193 ) + sub_multi -= 258; + // -64+256(192փbv) + if( sub_multi < -64 ) + sub_multi += 256; + + sub_freq = (fds.main_frequency) * sub_multi / 64; + } + + // Main unit + INT output = 0; + if( fds.main_enable && fds.main_frequency && !fds.wave_setup ) { + INT freq; + INT main_addr_old = fds.main_addr; + + freq = (fds.main_frequency+sub_freq)*1789772.5/65536.0; + + fds.main_addr = (fds.main_addr+freq+64*sampling_rate)%(64*sampling_rate); + + // 1𒴂{[XV + if( main_addr_old > fds.main_addr ) + fds.now_volume = (fds.volenv_gain<0x21)?fds.volenv_gain:0x20; + + output = fds.main_wavetable[(fds.main_addr / sampling_rate)&0x3f] * 8 * fds.now_volume * fds.master_volume / 30; + + if( fds.now_volume ) + fds.now_freq = freq * 4; + else + fds.now_freq = 0; + } else { + fds.now_freq = 0; + output = 0; + } + + // LPF +#if 1 + output = (output_buf[0] * 2 + output) / 3; + output_buf[0] = output; +#else + output = (output_buf[0] + output_buf[1] + output) / 3; + output_buf[0] = output_buf[1]; + output_buf[1] = output; +#endif + + fds.output = output; + return fds.output; +} + +// CPUĂ΂ +void APU_FDS::SyncWrite( WORD addr, BYTE data ) +{ + // NbN + WriteSub( addr, data, fds_sync, 1789772.5 ); +} + +BYTE APU_FDS::SyncRead( WORD addr ) +{ +BYTE data = addr>>8; + + if( addr >= 0x4040 && addr <= 0x407F ) { + data = fds_sync.main_wavetable[addr&0x3F] | 0x40; + } else + if( addr == 0x4090 ) { + data = (fds_sync.volenv_gain&0x3F)|0x40; + } else + if( addr == 0x4092 ) { + data = (fds_sync.swpenv_gain&0x3F)|0x40; + } + + return data; +} + +BOOL APU_FDS::Sync( INT cycles ) +{ + // Envelope unit + if( fds_sync.envelope_enable && fds_sync.envelope_speed ) { + // Volume envelope + double decay; + if( fds_sync.volenv_mode < 2 ) { + decay = ((double)fds_sync.envelope_speed * (double)(fds_sync.volenv_decay+1) * 1789772.5) / (232.0*960.0); + fds_sync.volenv_phaseacc -= (double)cycles; + while( fds_sync.volenv_phaseacc < 0.0 ) { + fds_sync.volenv_phaseacc += decay; + + if( fds_sync.volenv_mode == 0 ) { + // [h + if( fds_sync.volenv_gain ) + fds_sync.volenv_gain--; + } else + if( fds_sync.volenv_mode == 1 ) { + // [h + if( fds_sync.volenv_gain < 0x20 ) + fds_sync.volenv_gain++; + } + } + } + + // Sweep envelope + if( fds_sync.swpenv_mode < 2 ) { + decay = ((double)fds_sync.envelope_speed * (double)(fds_sync.swpenv_decay+1) * 1789772.5) / (232.0*960.0); + fds_sync.swpenv_phaseacc -= (double)cycles; + while( fds_sync.swpenv_phaseacc < 0.0 ) { + fds_sync.swpenv_phaseacc += decay; + + if( fds_sync.swpenv_mode == 0 ) { + // [h + if( fds_sync.swpenv_gain ) + fds_sync.swpenv_gain--; + } else + if( fds_sync.swpenv_mode == 1 ) { + // [h + if( fds_sync.swpenv_gain < 0x20 ) + fds_sync.swpenv_gain++; + } + } + } + } + + return FALSE; +} + +INT APU_FDS::GetFreq( INT channel ) +{ + return fds.now_freq; +} + +INT APU_FDS::GetStateSize() +{ + return sizeof(fds) + sizeof(fds_sync); +} + +void APU_FDS::SaveState( LPBYTE p ) +{ + SETBLOCK( p, &fds, sizeof(fds) ); + SETBLOCK( p, &fds_sync, sizeof(fds_sync) ); +} + +void APU_FDS::LoadState( LPBYTE p ) +{ + GETBLOCK( p, &fds, sizeof(fds) ); + GETBLOCK( p, &fds_sync, sizeof(fds_sync) ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FDS.h b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FDS.h new file mode 100644 index 00000000..ea69d2b7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FDS.h @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////// +// // +// FDS plugin // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __FDSPLUGIN_INCLUDED__ +#define __FDSPLUGIN_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +#include "typedef.h" +#include "macro.h" + +#include "APU_INTERFACE.h" + +class APU_FDS : public APU_INTERFACE +{ +public: + APU_FDS(); + ~APU_FDS(); + + void Reset( FLOAT fClock, INT nRate ); + void Setup( FLOAT fClock, INT nRate ); + void Write( WORD addr, BYTE data ); + BYTE Read ( WORD addr ); + INT Process( INT channel ); + + void SyncWrite( WORD addr, BYTE data ); + BYTE SyncRead ( WORD addr ); + BOOL Sync( INT cycles ); + + INT GetFreq( INT channel ); + + INT GetStateSize(); + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); +protected: + typedef struct tagFDSSOUND { + BYTE reg[0x80]; + + BYTE volenv_mode; // Volume Envelope + BYTE volenv_gain; + BYTE volenv_decay; + double volenv_phaseacc; + + BYTE swpenv_mode; // Sweep Envelope + BYTE swpenv_gain; + BYTE swpenv_decay; + double swpenv_phaseacc; + + // For envelope unit + BYTE envelope_enable; // $4083 bit6 + BYTE envelope_speed; // $408A + + // For $4089 + BYTE wave_setup; // bit7 + INT master_volume; // bit1-0 + + // For Main unit + INT main_wavetable[64]; + BYTE main_enable; + INT main_frequency; + INT main_addr; + + // For Effector(LFO) unit + BYTE lfo_wavetable[64]; + BYTE lfo_enable; // 0:Enable 1:Wavetable setup + INT lfo_frequency; + INT lfo_addr; + double lfo_phaseacc; + + // For Sweep unit + INT sweep_bias; + + // Misc + INT now_volume; + INT now_freq; + INT output; + + } FDSSOUND, *LPFDSSOUND; + + FDSSOUND fds; + FDSSOUND fds_sync; + + INT sampling_rate; + INT output_buf[8]; + + // Write Sub + void WriteSub( WORD addr, BYTE data, FDSSOUND& ch, double rate ); +private: +}; + +#endif // !__FDSPLUGIN_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FME7.cpp b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FME7.cpp new file mode 100644 index 00000000..8a51adbe --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FME7.cpp @@ -0,0 +1,328 @@ +////////////////////////////////////////////////////////////////////////// +// // +// SunSoft FME7 // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#include "APU_FME7.h" + +#define CHANNEL_VOL_SHIFT 8 + +// Envelope tables +BYTE APU_FME7::envelope_pulse0[] = { + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 +}; +BYTE APU_FME7::envelope_pulse1[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x00 +}; +BYTE APU_FME7::envelope_pulse2[] = { + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x1F +}; +BYTE APU_FME7::envelope_pulse3[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x1F +}; +SBYTE APU_FME7::envstep_pulse[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0 +}; + +BYTE APU_FME7::envelope_sawtooth0[] = { + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 +}; +BYTE APU_FME7::envelope_sawtooth1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F +}; +SBYTE APU_FME7::envstep_sawtooth[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, -15 +}; + +BYTE APU_FME7::envelope_triangle0[] = { + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F +}; +BYTE APU_FME7::envelope_triangle1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 +}; +SBYTE APU_FME7::envstep_triangle[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, -31 +}; + +LPBYTE APU_FME7::envelope_table[16] = { + envelope_pulse0, envelope_pulse0, envelope_pulse0, envelope_pulse0, + envelope_pulse1, envelope_pulse1, envelope_pulse1, envelope_pulse1, + envelope_sawtooth0, envelope_pulse0, envelope_triangle0, envelope_pulse2, + envelope_sawtooth1, envelope_pulse3, envelope_triangle1, envelope_pulse1 +}; +LPSBYTE APU_FME7::envstep_table[16] = { + envstep_pulse, envstep_pulse, envstep_pulse, envstep_pulse, + envstep_pulse, envstep_pulse, envstep_pulse, envstep_pulse, + envstep_sawtooth, envstep_pulse, envstep_triangle, envstep_pulse, + envstep_sawtooth, envstep_pulse, envstep_triangle, envstep_pulse +}; + +APU_FME7::APU_FME7() +{ + // ݒ + Reset( APU_CLOCK, 22050 ); +} + +APU_FME7::~APU_FME7() +{ +} + +void APU_FME7::Reset( FLOAT fClock, INT nRate ) +{ + INT i; + + ::ZeroMemory( &envelope, sizeof(envelope) ); + ::ZeroMemory( &noise, sizeof(noise) ); + + for( i = 0; i < 3; i++ ) { + ::ZeroMemory( &op[i], sizeof(op[i]) ); + } + + envelope.envtbl = envelope_table[0]; + envelope.envstep = envstep_table[0]; + + noise.noiserange = 1; + noise.noiseout = 0xFF; + + address = 0; + + // Volume to voltage + double out = 0x1FFF; + for( i = 31; i > 0; i-- ) { + vol_table[i] = (INT)(out+0.5); + out /= 1.188502227; /* = 10 ^ (1.5/20) = 1.5dB */ + } + vol_table[0] = 0; + + Setup( fClock, nRate ); +} + +void APU_FME7::Setup( FLOAT fClock, INT nRate ) +{ + cpu_clock = fClock; + cycle_rate = (INT)((fClock/16.0f)*(1<<16)/nRate); +} + +void APU_FME7::Write( WORD addr, BYTE data ) +{ + if( addr == 0xC000 ) { + address = data; + } else if( addr == 0xE000 ) { + BYTE chaddr = address; + switch( chaddr ) { + case 0x00: case 0x01: + case 0x02: case 0x03: + case 0x04: case 0x05: + { + CHANNEL& ch = op[chaddr>>1]; + ch.reg[chaddr&0x01] = data; + ch.freq = INT2FIX(((INT)(ch.reg[1]&0x0F)<<8)+ch.reg[0]+1); + } + break; + case 0x06: + noise.freq = INT2FIX((INT)(data&0x1F)+1); + break; + case 0x07: + { + for( INT i = 0; i < 3; i++ ) { + op[i].enable = data&(1<enable || !ch->freq ) + return 0; + if( ch->env_on ) { + if( !envelope.volume ) + return 0; + } else { + if( !ch->volume ) + return 0; + } + + return (INT)(256.0f*cpu_clock/((FLOAT)FIX2INT(ch->freq)*16.0f)); + } + + return 0; +} + +void APU_FME7::EnvelopeRender() +{ + if( !envelope.freq ) + return; + envelope.phaseacc -= cycle_rate; + if( envelope.phaseacc >= 0 ) + return; + while( envelope.phaseacc < 0 ) { + envelope.phaseacc += envelope.freq; + envelope.envadr += envelope.envstep[envelope.envadr]; + } + envelope.volume = envelope.envtbl[envelope.envadr]; +} + +void APU_FME7::NoiseRender() +{ + if( !noise.freq ) + return; + noise.phaseacc -= cycle_rate; + if( noise.phaseacc >= 0 ) + return; + while( noise.phaseacc < 0 ) { + noise.phaseacc += noise.freq; + if( (noise.noiserange+1) & 0x02 ) + noise.noiseout = ~noise.noiseout; + if( noise.noiserange & 0x01 ) + noise.noiserange ^= 0x28000; + noise.noiserange >>= 1; + } +} + +INT APU_FME7::ChannelRender( CHANNEL& ch ) +{ +INT output, volume; + + if( ch.enable ) + return 0; + if( !ch.freq ) + return 0; + + ch.phaseacc -= cycle_rate; + while( ch.phaseacc < 0 ) { + ch.phaseacc += ch.freq; + ch.adder++; + } + + output = volume = 0; + volume = ch.env_on?vol_table[envelope.volume]:vol_table[ch.volume+1]; + + if( ch.adder & 0x01 ) { + output += volume; + } else { + output -= volume; + } + if( !ch.noise_on ) { + if( noise.noiseout ) + output += volume; + else + output -= volume; + } + + ch.output_vol = output; + + return ch.output_vol; +} + +INT APU_FME7::GetStateSize() +{ + return sizeof(BYTE) + sizeof(envelope) + sizeof(noise) + 3*sizeof(op); +} + +void APU_FME7::SaveState( LPBYTE p ) +{ + SETBYTE( p, address ); + + SETBLOCK( p, &envelope, sizeof(envelope) ); + SETBLOCK( p, &noise, sizeof(noise) ); + SETBLOCK( p, op, 3*sizeof(op) ); +} + +void APU_FME7::LoadState( LPBYTE p ) +{ + GETBYTE( p, address ); + + GETBLOCK( p, &envelope, sizeof(envelope) ); + GETBLOCK( p, &noise, sizeof(noise) ); + GETBLOCK( p, op, 3*sizeof(op) ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FME7.h b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FME7.h new file mode 100644 index 00000000..068a7d92 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_FME7.h @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////////// +// // +// SunSoft FME7 // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __APU_FME7_INCLUDED__ +#define __APU_FME7_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +#include "typedef.h" +#include "macro.h" + +#include "APU_INTERFACE.h" +#include "nes.h" + +class APU_FME7 : public APU_INTERFACE +{ +public: + APU_FME7(); + ~APU_FME7(); + + void Reset( FLOAT fClock, INT nRate ); + void Setup( FLOAT fClock, INT nRate ); + void Write( WORD addr, BYTE data ); + INT Process( INT channel ); + + INT GetFreq( INT channel ); + + INT GetStateSize(); + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); +protected: + typedef struct { + BYTE reg[3]; + BYTE volume; + + INT freq; + INT phaseacc; + INT envadr; + + LPBYTE envtbl; + LPSBYTE envstep; + } ENVELOPE, *LPENVELOPE; + + typedef struct { + INT freq; + INT phaseacc; + INT noiserange; + BYTE noiseout; + } NOISE, *LPNOISE; + + typedef struct { + BYTE reg[3]; + BYTE enable; + BYTE env_on; + BYTE noise_on; + BYTE adder; + BYTE volume; + + INT freq; + INT phaseacc; + + INT output_vol; + } CHANNEL, *LPCHANNEL; + + void EnvelopeRender(); + void NoiseRender(); + + INT ChannelRender( CHANNEL& ch ); + + ENVELOPE envelope; + NOISE noise; + CHANNEL op[3]; + + BYTE address; + + INT vol_table[0x20]; + INT cycle_rate; + + FLOAT cpu_clock; + + // Tables + static BYTE envelope_pulse0[]; + static BYTE envelope_pulse1[]; + static BYTE envelope_pulse2[]; + static BYTE envelope_pulse3[]; + static SBYTE envstep_pulse[]; + + static BYTE envelope_sawtooth0[]; + static BYTE envelope_sawtooth1[]; + static SBYTE envstep_sawtooth[]; + + static BYTE envelope_triangle0[]; + static BYTE envelope_triangle1[]; + + static SBYTE envstep_triangle[]; + + static LPBYTE envelope_table[16]; + static LPSBYTE envstep_table[16]; +private: +}; + +#endif // !__APU_FME7_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERFACE.h b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERFACE.h new file mode 100644 index 00000000..b5feb6e1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERFACE.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// // +// APU Interface class // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __APU_INTERFACE_INCLUDED__ +#define __APU_INTERFACE_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +#include "typedef.h" +#include "macro.h" + +#define APU_CLOCK 1789772.5f + +// Fixed point decimal macro +#define INT2FIX(x) ((x)<<16) +#define FIX2INT(x) ((x)>>16) + +// APUC^[tF[XۃNX +class APU_INTERFACE +{ +public: + // Ɏv + virtual void Reset( FLOAT fClock, INT nRate ) = 0; + virtual void Setup( FLOAT fClock, INT nRate ) = 0; + virtual void Write( WORD addr, BYTE data ) = 0; + virtual INT Process( INT channel ) = 0; + + // IvVŎ + virtual BYTE Read ( WORD addr ) { return (BYTE)(addr>>8); } + + virtual void WriteSync( WORD addr, BYTE data ) {} + virtual BYTE ReadSync ( WORD addr ) { return 0; } + virtual void VSync() {} + virtual BOOL Sync( INT cycles ) { return FALSE; } // IRQ𔭐鎞TRUEԂ + + virtual INT GetFreq( INT channel ) { return 0; } + + // For State save + virtual INT GetStateSize() { return 0; } + virtual void SaveState( LPBYTE p ) {} + virtual void LoadState( LPBYTE p ) {} +protected: +private: +}; + +#endif // !__APU_INTERFACE_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERNAL.cpp b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERNAL.cpp new file mode 100644 index 00000000..e2f5524a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERNAL.cpp @@ -0,0 +1,1348 @@ +////////////////////////////////////////////////////////////////////////// +// // +// APU Internal // +// Norix // +// written 2002/06/27 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#include "DebugOut.h" +#include "Pathlib.h" +#include "Config.h" + +#include "APU_INTERNAL.h" + +#include "state.h" +#include "rom.h" + +// Dummy +#define APU_CLOCK 1789772.5f + +// Volume shift +#define RECTANGLE_VOL_SHIFT 8 +#define TRIANGLE_VOL_SHIFT 9 +#define NOISE_VOL_SHIFT 8 +#define DPCM_VOL_SHIFT 8 + +INT APU_INTERNAL::vbl_length[32] = { + 5, 127, 10, 1, 19, 2, 40, 3, + 80, 4, 30, 5, 7, 6, 13, 7, + 6, 8, 12, 9, 24, 10, 48, 11, + 96, 12, 36, 13, 8, 14, 16, 15 +}; + +INT APU_INTERNAL::freq_limit[8] = { + 0x03FF, 0x0555, 0x0666, 0x071C, 0x0787, 0x07C1, 0x07E0, 0x07F0 +}; +INT APU_INTERNAL::duty_lut[4] = { + 2, 4, 8, 12 +}; + +INT APU_INTERNAL::noise_freq[16] = { + 4, 8, 16, 32, 64, 96, 128, 160, + 202, 254, 380, 508, 762, 1016, 2034, 4068 +}; + +// DMC ]NbNe[u +INT APU_INTERNAL::dpcm_cycles[16] = { + 428, 380, 340, 320, 286, 254, 226, 214, + 190, 160, 142, 128, 106, 85, 72, 54 +}; + +//INT APU_INTERNAL::vol_effect[16] = { +// 100, 94, 88, 83, 78, 74, 71, 67, +// 64, 61, 59, 56, 54, 52, 50, 48 +//}; + +APU_INTERNAL::APU_INTERNAL() +{ + nes = NULL; + + ZEROMEMORY( &ch0, sizeof(ch0) ); + ZEROMEMORY( &ch1, sizeof(ch1) ); + ZEROMEMORY( &ch2, sizeof(ch2) ); + ZEROMEMORY( &ch3, sizeof(ch3) ); + ZEROMEMORY( &ch4, sizeof(ch4) ); + + FrameIRQ = 0xC0; + FrameCycle = 0; + FrameIRQoccur = 0; + FrameCount = 0; + FrameType = 0; + + reg4015 = sync_reg4015 = 0; + + cpu_clock = APU_CLOCK; + sampling_rate = 22050; + + // ݒ + cycle_rate = (INT)(cpu_clock*65536.0f/22050.0f); + +} + +APU_INTERNAL::~APU_INTERNAL() +{ +} + +void APU_INTERNAL::Reset( FLOAT fClock, INT nRate ) +{ + ZEROMEMORY( &ch0, sizeof(ch0) ); + ZEROMEMORY( &ch1, sizeof(ch1) ); + ZEROMEMORY( &ch2, sizeof(ch2) ); + ZEROMEMORY( &ch3, sizeof(ch3) ); +// ZEROMEMORY( &ch4, sizeof(ch4) ); + + ZEROMEMORY( bToneTableEnable, sizeof(bToneTableEnable) ); + ZEROMEMORY( ToneTable, sizeof(ToneTable) ); + ZEROMEMORY( ChannelTone, sizeof(ChannelTone) ); + + reg4015 = sync_reg4015 = 0; + + // Sweep complement + ch0.complement = 0x00; + ch1.complement = 0xFF; + + // Noise shift register + ch3.shift_reg = 0x4000; + + Setup( fClock, nRate ); + + // $4011͏Ȃ + WORD addr; + for( addr = 0x4000; addr <= 0x4010; addr++ ) { + Write( addr, 0x00 ); + SyncWrite( addr, 0x00 ); + } +// Write( 0x4001, 0x08 ); // Resetinc[hɂȂ? +// Write( 0x4005, 0x08 ); // Resetinc[hɂȂ? + Write( 0x4012, 0x00 ); + Write( 0x4013, 0x00 ); + Write( 0x4015, 0x00 ); + SyncWrite( 0x4012, 0x00 ); + SyncWrite( 0x4013, 0x00 ); + SyncWrite( 0x4015, 0x00 ); + + // $4017͏݂ŏȂ([h0ł̂҂\tg) + FrameIRQ = 0xC0; + FrameCycle = 0; + FrameIRQoccur = 0; + FrameCount = 0; + FrameType = 0; + + // ToneLoad + ToneTableLoad(); +} + +void APU_INTERNAL::Setup( FLOAT fClock, INT nRate ) +{ + cpu_clock = fClock; + sampling_rate = nRate; + + cycle_rate = (INT)(fClock*65536.0f/(float)nRate); +} + +// +// Wavetable loader +// +void APU_INTERNAL::ToneTableLoad() +{ +FILE* fp = NULL; +CHAR buf[512]; + + string tempstr; + tempstr = CPathlib::MakePathExt( nes->rom->GetRomPath(), nes->rom->GetRomName(), "vtd" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + if( !(fp = ::fopen( tempstr.c_str(), "r" )) ) { + // ftHgt@CœǂŌ + tempstr = CPathlib::MakePathExt( nes->rom->GetRomPath(), "Default", "vtd" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + if( !(fp = ::fopen( tempstr.c_str(), "r" )) ) { + DEBUGOUT( "File not found.\n" ); + return; + } + } + + DEBUGOUT( "Find.\n" ); + + // `t@Cǂݍ + while( ::fgets( buf, 512, fp ) != NULL ) { + if( buf[0] == ';' || ::strlen(buf) <= 0 ) + continue; + + CHAR c = ::toupper( buf[0] ); + + if( c == '@' ) { + // Fǂݍ + CHAR* pbuf = &buf[1]; + CHAR* p; + INT no, val; + + // Fio[擾 + no = ::strtol( pbuf, &p, 10 ); + if( pbuf == p ) + continue; + if( no < 0 || no > TONEDATA_MAX-1 ) + continue; + + // '='‚ + p = ::strchr( pbuf, '=' ); + if( p == NULL ) + continue; + pbuf = p+1; // + + // Ff[^擾 + for( INT i = 0; i < TONEDATA_LEN; i++ ) { + val = ::strtol( pbuf, &p, 10 ); + if( pbuf == p ) // 擾sH + break; + if( *p == ',' ) // J}΂c + pbuf = p+1; + else + pbuf = p; + + ToneTable[no][i] = val; + } + if( i >= TONEDATA_MAX ) + bToneTableEnable[no] = TRUE; + } else + if( c == 'A' || c == 'B' ) { + // e`lF` + CHAR* pbuf = &buf[1]; + CHAR* p; + INT no, val; + + // Fio[擾 + no = ::strtol( pbuf, &p, 10 ); + if( pbuf == p ) + continue; + pbuf = p; + if( no < 0 || no > TONE_MAX-1 ) + continue; + + // '='‚ + p = ::strchr( pbuf, '=' ); + if( p == NULL ) + continue; + pbuf = p+1; // + + // Fio[擾 + val = ::strtol( pbuf, &p, 10 ); + if( pbuf == p ) + continue; + pbuf = p; + + if( val > TONEDATA_MAX-1 ) + continue; + + if( val >= 0 && bToneTableEnable[val] ) { + if( c == 'A' ) { + ChannelTone[0][no] = val+1; + } else { + ChannelTone[1][no] = val+1; + } + } else { + if( c == 'A' ) { + ChannelTone[0][no] = 0; + } else { + ChannelTone[1][no] = 0; + } + } + } else + if( c == 'C' ) { + // e`lF` + CHAR* pbuf = &buf[1]; + CHAR* p; + INT val; + + // '='‚ + p = ::strchr( pbuf, '=' ); + if( p == NULL ) + continue; + pbuf = p+1; // + + // Fio[擾 + val = ::strtol( pbuf, &p, 10 ); + if( pbuf == p ) + continue; + pbuf = p; + + if( val > TONEDATA_MAX-1 ) + continue; + + if( val >= 0 && bToneTableEnable[val] ) { + ChannelTone[2][0] = val+1; + } else { + ChannelTone[2][0] = 0; + } + } + } + + FCLOSE( fp ); +} + +INT APU_INTERNAL::Process( INT channel ) +{ + switch( channel ) { + case 0: + return RenderRectangle( ch0 ); + case 1: + return RenderRectangle( ch1 ); + case 2: + return RenderTriangle(); + case 3: + return RenderNoise(); + case 4: + return RenderDPCM(); + default: + return 0; + } + + return 0; +} + +void APU_INTERNAL::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + // CH0,1 rectangle + case 0x4000: case 0x4001: + case 0x4002: case 0x4003: + case 0x4004: case 0x4005: + case 0x4006: case 0x4007: + WriteRectangle( (addr<0x4004)?0:1, addr, data ); + break; + + // CH2 triangle + case 0x4008: case 0x4009: + case 0x400A: case 0x400B: + WriteTriangle( addr, data ); + break; + + // CH3 noise + case 0x400C: case 0x400D: + case 0x400E: case 0x400F: + WriteNoise( addr, data ); + break; + + // CH4 DPCM + case 0x4010: case 0x4011: + case 0x4012: case 0x4013: + WriteDPCM( addr, data ); + break; + + case 0x4015: + reg4015 = data; + + if( !(data&(1<<0)) ) { + ch0.enable = 0; + ch0.len_count = 0; + } + if( !(data&(1<<1)) ) { + ch1.enable = 0; + ch1.len_count = 0; + } + if( !(data&(1<<2)) ) { + ch2.enable = 0; + ch2.len_count = 0; + ch2.lin_count = 0; + } + if( !(data&(1<<3)) ) { + ch3.enable = 0; + ch3.len_count = 0; + } + if( !(data&(1<<4)) ) { + ch4.enable = 0; + ch4.dmalength = 0; + } else { + ch4.enable = 0xFF; + if( !ch4.dmalength ) { + ch4.address = ch4.cache_addr; + ch4.dmalength = ch4.cache_dmalength; + } + } + break; + + case 0x4017: + break; + + // VirtuaNESŗL|[g + case 0x4018: + UpdateRectangle( ch0, (INT)data ); + UpdateRectangle( ch1, (INT)data ); + UpdateTriangle ( (INT)data ); + UpdateNoise ( (INT)data ); + break; + + default: + break; + } +} + +BYTE APU_INTERNAL::Read( WORD addr ) +{ +BYTE data = addr>>8; + + if( addr == 0x4015 ) { + data = 0; + if( ch0.enable && ch0.len_count > 0 ) data |= (1<<0); + if( ch1.enable && ch1.len_count > 0 ) data |= (1<<1); + if( ch2.enable ) { + if( !ch2.holdnote ) { + if( ch2.len_count > 0 ) data |= (1<<2); + } else { + if( ch2.lin_count > 0 ) data |= (1<<2); + } + } + if( ch3.enable && ch3.len_count > 0 ) data |= (1<<3); + } + return data; +} + +void APU_INTERNAL::SyncWrite( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X=$%02X\n", addr, data ); + + switch( addr ) { + // CH0,1 rectangle + case 0x4000: case 0x4001: + case 0x4002: case 0x4003: + case 0x4004: case 0x4005: + case 0x4006: case 0x4007: + SyncWriteRectangle( (addr<0x4004)?0:1, addr, data ); + break; + + // CH2 triangle + case 0x4008: case 0x4009: + case 0x400A: case 0x400B: + SyncWriteTriangle( addr, data ); + break; + + // CH3 noise + case 0x400C: case 0x400D: + case 0x400E: case 0x400F: + SyncWriteNoise( addr, data ); + break; + + // CH4 DPCM + case 0x4010: case 0x4011: + case 0x4012: case 0x4013: + SyncWriteDPCM( addr, data ); + break; + + case 0x4015: + sync_reg4015 = data; + + if( !(data&(1<<0)) ) { + ch0.sync_enable = 0; + ch0.sync_len_count = 0; + } + if( !(data&(1<<1)) ) { + ch1.sync_enable = 0; + ch1.sync_len_count = 0; + } + if( !(data&(1<<2)) ) { + ch2.sync_enable = 0; + ch2.sync_len_count = 0; + ch2.sync_lin_count = 0; + } + if( !(data&(1<<3)) ) { + ch3.sync_enable = 0; + ch3.sync_len_count = 0; + } + if( !(data&(1<<4)) ) { + ch4.sync_enable = 0; + ch4.sync_dmalength = 0; + ch4.sync_irq_enable = 0; + + nes->cpu->ClrIRQ( IRQ_DPCM ); + } else { + ch4.sync_enable = 0xFF; + if( !ch4.sync_dmalength ) { + ch4.sync_cycles = ch4.sync_cache_cycles; + ch4.sync_dmalength = ch4.sync_cache_dmalength; + } + } + break; + + case 0x4017: + SyncWrite4017( data ); + break; + + // VirtuaNESŗL|[g + case 0x4018: + SyncUpdateRectangle( ch0, (INT)data ); + SyncUpdateRectangle( ch1, (INT)data ); + SyncUpdateTriangle ( (INT)data ); + SyncUpdateNoise ( (INT)data ); + break; + + default: + break; + } +} + +// $4017 Write +void APU_INTERNAL::SyncWrite4017( BYTE data ) +{ + FrameCycle = 0; + FrameIRQ = data; + FrameIRQoccur = 0; + + nes->cpu->ClrIRQ( IRQ_FRAMEIRQ ); + + if( !(data&0x80) ) { + FrameType = 0; + FrameCount = 0; + } else { + FrameCount = 0; + FrameType = 1; + + // Counters Update + nes->Write( 0x4018, 0 ); + } +} + +BYTE APU_INTERNAL::SyncRead( WORD addr ) +{ +BYTE data = addr>>8; + + if( addr == 0x4015 ) { + data = 0; + if( ch0.sync_enable && ch0.sync_len_count > 0 ) data |= (1<<0); + if( ch1.sync_enable && ch1.sync_len_count > 0 ) data |= (1<<1); + if( ch2.sync_enable ) { + if( !ch2.sync_holdnote ) { + if( ch2.sync_len_count > 0 ) data |= (1<<2); + } else { + if( ch2.sync_lin_count > 0 ) data |= (1<<2); + } + } + if( ch3.sync_enable && ch3.sync_len_count > 0 ) data |= (1<<3); + if( ch4.sync_enable && ch4.sync_dmalength ) data |= (1<<4); + if( FrameIRQoccur ) data |= (1<<6); + if( ch4.sync_irq_enable ) data |= (1<<7); + FrameIRQoccur = 0; + + nes->cpu->ClrIRQ( IRQ_FRAMEIRQ ); + } + if( addr == 0x4017 ) { + if( FrameIRQoccur ) { + data = 0; + } else { + data |= (1<<6); + } + } + return data; +} + +BOOL APU_INTERNAL::Sync( INT cycles ) +{ + FrameCycle += cycles; + if( FrameCycle >= 7457 ) { + FrameCycle -= 7457; + + if( FrameType == 0 ) { + // 0,1,2,3 + if( FrameCount < 4 ) { + // Counters Update + nes->Write( 0x4018, (BYTE)FrameCount&3 ); + } + if( ++FrameCount > 3 ) { + FrameCount = 0; + + if( !(FrameIRQ&0xC0) && nes->GetFrameIRQmode() ) { + FrameIRQoccur = 0xFF; + + nes->cpu->SetIRQ( IRQ_FRAMEIRQ ); + } + } + } else { + // 0,1,2 + if( FrameCount < 3 ) { + // Counters Update + nes->Write( 0x4018, (BYTE)(FrameCount+1)&3 ); + } + if( ++FrameCount > 4 ) { + FrameCount = 0; + // Counters Update + nes->Write( 0x4018, 0 ); + } + } + } + + return FrameIRQoccur | SyncUpdateDPCM( cycles ); +} + +INT APU_INTERNAL::GetFreq( INT channel ) +{ +INT freq = 0; + + // Rectangle + if( channel == 0 || channel == 1 ) { + RECTANGLE* ch; + if( channel == 0 ) ch = &ch0; + else ch = &ch1; + if( !ch->enable || ch->len_count <= 0 ) + return 0; + if( (ch->freq < 8) || (!ch->swp_inc && ch->freq > ch->freqlimit) ) + return 0; + + if( !ch->volume ) + return 0; + +// freq = (((INT)ch->reg[3]&0x07)<<8)+(INT)ch->reg[2]+1; + freq = (INT)(16.0f*cpu_clock/(FLOAT)(ch->freq+1)); + return freq; + } + + // Triangle + if( channel == 2 ) { + if( !ch2.enable || ch2.len_count <= 0 ) + return 0; + if( ch2.lin_count <= 0 || ch2.freq < INT2FIX(8) ) + return 0; + freq = (((INT)ch2.reg[3]&0x07)<<8)+(INT)ch2.reg[2]+1; + freq = (INT)(8.0f*cpu_clock/(FLOAT)freq); + return freq; + } + + // Noise + if( channel == 3 ) { + if( !ch3.enable || ch3.len_count <= 0 ) + return 0; + if( ch3.env_fixed ) { + if( !ch3.volume ) + return 0; + } else { + if( !ch3.env_vol ) + return 0; + } + return 1; + } + + // DPCM + if( channel == 4 ) { + if( ch4.enable && ch4.dmalength ) + return 1; + } + + return 0; +} + +// Write Rectangle +void APU_INTERNAL::WriteRectangle( INT no, WORD addr, BYTE data ) +{ + RECTANGLE& ch = (no==0)?ch0:ch1; + + ch.reg[addr&3] = data; + switch( addr&3 ) { + case 0: + ch.holdnote = data&0x20; + ch.volume = data&0x0F; + ch.env_fixed = data&0x10; + ch.env_decay = (data&0x0F)+1; + ch.duty = duty_lut[data>>6]; + break; + case 1: + ch.swp_on = data&0x80; + ch.swp_inc = data&0x08; + ch.swp_shift = data&0x07; + ch.swp_decay = ((data>>4)&0x07)+1; + ch.freqlimit = freq_limit[data&0x07]; + break; + case 2: + ch.freq = (ch.freq&(~0xFF))+data; + break; + case 3: // Master + ch.freq = ((data&0x07)<<8)+(ch.freq&0xFF); + ch.len_count = vbl_length[data>>3]*2; + ch.env_vol = 0x0F; + ch.env_count = ch.env_decay+1; + ch.adder = 0; + + if( reg4015&(1<> ch.swp_shift); // CH 0 + else + ch.freq -= (ch.freq >> ch.swp_shift); // CH 1 + } else { + // Sweep decrement(to lower frequency) + ch.freq += (ch.freq >> ch.swp_shift); + } + } + } + } + + // Update Envelope + if( ch.env_count ) { + ch.env_count--; + } + if( ch.env_count == 0 ) { + ch.env_count = ch.env_decay; + + // Holdnote + if( ch.holdnote ) { + ch.env_vol = (ch.env_vol-1)&0x0F; + } else if( ch.env_vol ) { + ch.env_vol--; + } + } + + if( !ch.env_fixed ) { + ch.nowvolume = ch.env_vol<>3]*2; + if( sync_reg4015&(1< ch.freqlimit) ) { + return 0; + } + + if( ch.env_fixed ) { + ch.nowvolume = ch.volume<>6]) ) { + // ԏ + double total; + double sample_weight = ch.phaseacc; + if( sample_weight > cycle_rate ) { + sample_weight = cycle_rate; + } + total = (ch.adder < ch.duty)?sample_weight:-sample_weight; + + INT freq = INT2FIX( ch.freq+1 ); + ch.phaseacc -= cycle_rate; + while( ch.phaseacc < 0 ) { + ch.phaseacc += freq; + ch.adder = (ch.adder+1)&0x0F; + + sample_weight = freq; + if( ch.phaseacc > 0 ) { + sample_weight -= ch.phaseacc; + } + total += (ch.adder < ch.duty)?sample_weight:-sample_weight; + } + return (INT)floor( volume*total/cycle_rate + 0.5 ); + } else { + INT* pTone = ToneTable[ChannelTone[(!ch.complement)?0:1][ch.reg[0]>>6]-1]; + + // XV + ch.phaseacc -= cycle_rate*2; + if( ch.phaseacc >= 0 ) { + return pTone[ch.adder&0x1F]*volume/((1< cycle_rate*2 ) { + ch.phaseacc += freq; + ch.adder = (ch.adder+1)&0x1F; + return pTone[ch.adder&0x1F]*volume/((1<>3]*2; + ch2.lin_count = ch2.reg[0]&0x7F; + ch2.holdnote = ch2.reg[0]&0x80; + ch2.counter_start = 0x80; + + if( reg4015&(1<<2) ) + ch2.enable = 0xFF; + break; + } +} + +// Update Triangle +void APU_INTERNAL::UpdateTriangle( INT type ) +{ + if( !ch2.enable ) + return; + + // Update Length/Linear + if( !ch2.holdnote ) { + if( (type&1) && ch2.len_count ) { + ch2.len_count--; + } + ch2.counter_start = 0; + + if( ch2.lin_count ) { + ch2.lin_count--; + } + if( (ch2.len_count <= 0) || (ch2.lin_count <= 0) ) { + ch2.lin_count = 0; + } + } +} + +// Sync Write Triangle +void APU_INTERNAL::SyncWriteTriangle( WORD addr, BYTE data ) +{ + ch2.sync_reg[addr&3] = data; + switch( addr&3 ) { + case 0: + if( ch2.sync_counter_start & 0x80 ) { + ch2.sync_lin_count = data&0x7F; + ch2.sync_holdnote = data&0x80; + } + if( !(data&0x7F) ) { + ch2.sync_lin_count = 0; + } + ch2.sync_counter_start = data&0x80; + break; + case 1: + break; + case 2: + break; + case 3: // Master + ch2.sync_len_count = vbl_length[ch2.sync_reg[3]>>3]*2; + ch2.sync_lin_count = ch2.sync_reg[0]&0x7F; + ch2.sync_holdnote = ch2.sync_reg[0]&0x80; + ch2.sync_counter_start = 0x80; + + if( sync_reg4015&(1<<2) ) + ch2.sync_enable = 0xFF; + break; + } +} + +// Sync Update Triangle +void APU_INTERNAL::SyncUpdateTriangle( INT type ) +{ + if( !ch2.sync_enable ) + return; + + // Update Length/Linear + if( !ch2.sync_holdnote ) { + if( (type&1) && ch2.sync_len_count ) { + ch2.sync_len_count--; + } + ch2.sync_counter_start = 0; + + if( ch2.sync_lin_count ) { + ch2.sync_lin_count--; + } + } +} + +// Render Triangle +INT APU_INTERNAL::RenderTriangle() +{ + INT vol; + if( Config.sound.bDisableVolumeEffect ) { + vol = 256; + } else { + vol = 256-(INT)((ch4.reg[1]&0x01)+ch4.dpcm_value*2); + } + + if( !ch2.enable || (ch2.len_count <= 0) || (ch2.lin_count <= 0) ) { + return ch2.nowvolume*vol/256; + } + + if( ch2.freq < INT2FIX(8) ) { + return ch2.nowvolume*vol/256; + } + +// if( !ch2.holdnote ) { +// ch2.counter_start = 0xFF; +// } + + if( !(Config.sound.bChangeTone && ChannelTone[2][0]) ) { + ch2.phaseacc -= cycle_rate; + if( ch2.phaseacc >= 0 ) { + return ch2.nowvolume*vol/256; + } + + if( ch2.freq > cycle_rate ) { + ch2.phaseacc += ch2.freq; + ch2.adder = (ch2.adder+1)&0x1F; + + if( ch2.adder < 0x10 ) { + ch2.nowvolume = (ch2.adder&0x0F)<= 0 ) { + return ch2.nowvolume*vol/256; + } + + if( ch2.freq > cycle_rate ) { + ch2.phaseacc += ch2.freq; + ch2.adder = (ch2.adder+1)&0x1F; + ch2.nowvolume = pTone[ch2.adder&0x1F]*0x0F; + return ch2.nowvolume*vol/256; + } + + // d + INT num_times, total; + num_times = total = 0; + while( ch2.phaseacc < 0 ) { + ch2.phaseacc += ch2.freq; + ch2.adder = (ch2.adder+1)&0x1F; + total += pTone[ch2.adder&0x1F]*0x0F; + num_times++; + } + + return (total/num_times)*vol/256; + } +} + +////////////// + +// Write Noise +void APU_INTERNAL::WriteNoise( WORD addr, BYTE data ) +{ + ch3.reg[addr&3] = data; + switch( addr&3 ) { + case 0: + ch3.holdnote = data&0x20; + ch3.volume = data&0x0F; + ch3.env_fixed = data&0x10; + ch3.env_decay = (data&0x0F)+1; + break; + case 1: // Unused + break; + case 2: + ch3.freq = INT2FIX(noise_freq[data&0x0F]); + ch3.xor_tap = (data&0x80)?0x40:0x02; + break; + case 3: // Master + ch3.len_count = vbl_length[data>>3]*2; + ch3.env_vol = 0x0F; + ch3.env_count = ch3.env_decay+1; + + if( reg4015&(1<<3) ) + ch3.enable = 0xFF; + break; + } +} + +// Update Noise +void APU_INTERNAL::UpdateNoise( INT type ) +{ + if( !ch3.enable || ch3.len_count <= 0 ) + return; + + // Update Length + if( !ch3.holdnote ) { + // Holdnote + if( (type&1) && ch3.len_count ) { + ch3.len_count--; + } + } + + // Update Envelope + if( ch3.env_count ) { + ch3.env_count--; + } + if( ch3.env_count == 0 ) { + ch3.env_count = ch3.env_decay; + + // Holdnote + if( ch3.holdnote ) { + ch3.env_vol = (ch3.env_vol-1)&0x0F; + } else if( ch3.env_vol ) { + ch3.env_vol--; + } + } + + if( !ch3.env_fixed ) { + ch3.nowvolume = ch3.env_vol<>3]*2; + if( sync_reg4015&(1<<3) ) + ch3.sync_enable = 0xFF; + break; + } +} + +// Sync Update Noise +void APU_INTERNAL::SyncUpdateNoise( INT type ) +{ + if( !ch3.sync_enable || ch3.sync_len_count <= 0 ) + return; + + // Update Length + if( ch3.sync_len_count && !ch3.sync_holdnote ) { + if( (type&1) && ch3.sync_len_count ) { + ch3.sync_len_count--; + } + } +} + +// Noise ShiftRegister +BYTE APU_INTERNAL::NoiseShiftreg( BYTE xor_tap ) +{ +int bit0, bit14; + + bit0 = ch3.shift_reg & 1; + if( ch3.shift_reg & xor_tap ) bit14 = bit0^1; + else bit14 = bit0^0; + ch3.shift_reg >>= 1; + ch3.shift_reg |= (bit14<<14); + return (bit0^1); +} + +// Render Noise +INT APU_INTERNAL::RenderNoise() +{ + if( !ch3.enable || ch3.len_count <= 0 ) + return 0; + + if( ch3.env_fixed ) { + ch3.nowvolume = ch3.volume<= 0 ) + return ch3.output*vol/256; + + if( ch3.freq > cycle_rate ) { + ch3.phaseacc += ch3.freq; + if( NoiseShiftreg(ch3.xor_tap) ) + ch3.output = ch3.nowvolume; + else + ch3.output = -ch3.nowvolume; + + return ch3.output*vol/256; + } + + INT num_times, total; + num_times = total = 0; + while( ch3.phaseacc < 0 ) { + ch3.phaseacc += ch3.freq; + if( NoiseShiftreg(ch3.xor_tap) ) + ch3.output = ch3.nowvolume; + else + ch3.output = -ch3.nowvolume; + + total += ch3.output; + num_times++; + } + + return (total/num_times)*vol/256; +} + +////////// + +void APU_INTERNAL::WriteDPCM( WORD addr, BYTE data ) +{ + ch4.reg[addr&3] = data; + switch( addr&3 ) { + case 0: + ch4.freq = INT2FIX( dpcm_cycles[data&0x0F] ); + ch4.looping = data&0x40; + break; + case 1: + ch4.dpcm_value = (data&0x7F)>>1; + break; + case 2: + ch4.cache_addr = 0xC000+(WORD)(data<<6); + break; + case 3: + ch4.cache_dmalength = ((data<<4)+1)<<3; + break; + } +} + +INT APU_INTERNAL::RenderDPCM() +{ + if( ch4.dmalength ) { + ch4.phaseacc -= cycle_rate; + + while( ch4.phaseacc < 0 ) { + ch4.phaseacc += ch4.freq; + if( !(ch4.dmalength&7) ) { + ch4.cur_byte = nes->Read( ch4.address ); + if( 0xFFFF == ch4.address ) + ch4.address = 0x8000; + else + ch4.address++; + } + + if( !(--ch4.dmalength) ) { + if( ch4.looping ) { + ch4.address = ch4.cache_addr; + ch4.dmalength = ch4.cache_dmalength; + } else { + ch4.enable = 0; + break; + } + } + // positive delta + if( ch4.cur_byte&(1<<((ch4.dmalength&7)^7)) ) { + if( ch4.dpcm_value < 0x3F ) + ch4.dpcm_value += 1; + } else { + // negative delta + if( ch4.dpcm_value > 1 ) + ch4.dpcm_value -= 1; + } + } + } + +#if 1 + // C`LLv`mCYJbg(TEST) + ch4.dpcm_output_real = (INT)((ch4.reg[1]&0x01)+ch4.dpcm_value*2)-0x40; + if( abs(ch4.dpcm_output_real-ch4.dpcm_output_fake) <= 8 ) { + ch4.dpcm_output_fake = ch4.dpcm_output_real; + ch4.output = (INT)ch4.dpcm_output_real< ch4.dpcm_output_fake ) + ch4.dpcm_output_fake += 8; + else + ch4.dpcm_output_fake -= 8; + ch4.output = (INT)ch4.dpcm_output_fake<cpu->ClrIRQ( IRQ_DPCM ); + } + break; + case 1: + break; + case 2: + break; + case 3: + ch4.sync_cache_dmalength = ((data<<4)+1)<<3; + break; + } +} + +BOOL APU_INTERNAL::SyncUpdateDPCM( INT cycles ) +{ +BOOL bIRQ = FALSE; + + if( ch4.sync_enable ) { + ch4.sync_cycles -= cycles; + while( ch4.sync_cycles < 0 ) { + ch4.sync_cycles += ch4.sync_cache_cycles; + if( ch4.sync_dmalength ) { + if( !(--ch4.sync_dmalength) ) { + if( ch4.sync_looping ) { + ch4.sync_dmalength = ch4.sync_cache_dmalength; + } else if( ch4.sync_irq_gen ) { + ch4.sync_irq_enable = 0xFF; + nes->cpu->SetIRQ( IRQ_DPCM ); + } + } + } + } + } + if( ch4.sync_irq_enable ) { + bIRQ = TRUE; + } + + return bIRQ; +} + +INT APU_INTERNAL::GetStateSize() +{ + return 4*sizeof(BYTE) + 3*sizeof(INT) + + sizeof(ch0) + sizeof(ch1) + + sizeof(ch2) + sizeof(ch3) + + sizeof(ch4); +} + +void APU_INTERNAL::SaveState( LPBYTE p ) +{ + SETBYTE( p, reg4015 ); + SETBYTE( p, sync_reg4015 ); + + SETINT( p, FrameCycle ); + SETINT( p, FrameCount ); + SETINT( p, FrameType ); + SETBYTE( p, FrameIRQ ); + SETBYTE( p, FrameIRQoccur ); + + SETBLOCK( p, &ch0, sizeof(ch0) ); + SETBLOCK( p, &ch1, sizeof(ch1) ); + SETBLOCK( p, &ch2, sizeof(ch2) ); + SETBLOCK( p, &ch3, sizeof(ch3) ); + SETBLOCK( p, &ch4, sizeof(ch4) ); +} + +void APU_INTERNAL::LoadState( LPBYTE p ) +{ + GETBYTE( p, reg4015 ); + GETBYTE( p, sync_reg4015 ); + + GETINT( p, FrameCycle ); + GETINT( p, FrameCount ); + GETINT( p, FrameType ); + GETBYTE( p, FrameIRQ ); + GETBYTE( p, FrameIRQoccur ); + + GETBLOCK( p, &ch0, sizeof(ch0) ); + GETBLOCK( p, &ch1, sizeof(ch1) ); + GETBLOCK( p, &ch2, sizeof(ch2) ); + GETBLOCK( p, &ch3, sizeof(ch3) ); +// p += sizeof(ch3); + GETBLOCK( p, &ch4, sizeof(ch4) ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERNAL.h b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERNAL.h new file mode 100644 index 00000000..19c8db3d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_INTERNAL.h @@ -0,0 +1,272 @@ +////////////////////////////////////////////////////////////////////////// +// // +// APU Internal // +// Norix // +// written 2002/06/27 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __APU_INTERNAL_INCLUDED__ +#define __APU_INTERNAL_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" +#include "math.h" + +#include "typedef.h" +#include "macro.h" + +#include "APU_INTERFACE.h" +#include "nes.h" +#include "cpu.h" + +class APU_INTERNAL : public APU_INTERFACE +{ +public: + APU_INTERNAL(); + ~APU_INTERNAL(); + + void SetParent( NES* parent ) { nes = parent; } + + void Reset( FLOAT fClock, INT nRate ); + void Setup( FLOAT fClock, INT nRate ); + + void ToneTableLoad(); + + INT Process( INT channel ); + + void Write( WORD addr, BYTE data ); + BYTE Read ( WORD addr ); + + void SyncWrite( WORD addr, BYTE data ); + BYTE SyncRead ( WORD addr ); + BOOL Sync( INT cycles ); + + INT GetFreq( INT channel ); + + void GetFrameIRQ( INT& Cycle, BYTE& Count, BYTE& Type, BYTE& IRQ, BYTE& Occur ) { + Cycle = FrameCycle; + Count = (BYTE)FrameCount; + Type = (BYTE)FrameType; + IRQ = FrameIRQ; + Occur = FrameIRQoccur; + } + + void SetFrameIRQ( INT Cycle, BYTE Count, BYTE Type, BYTE IRQ, BYTE Occur ) { + FrameCycle = Cycle; + FrameCount = (INT)Count; + FrameType = (INT)Type; + FrameIRQ = IRQ; + FrameIRQoccur = Occur; + } + + INT GetStateSize(); + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + typedef struct { + BYTE reg[4]; // register + + BYTE enable; // enable + BYTE holdnote; // holdnote + BYTE volume; // volume + BYTE complement; + + // For Render + INT phaseacc; + INT freq; + INT freqlimit; + INT adder; + INT duty; + INT len_count; + + INT nowvolume; + + // For Envelope + BYTE env_fixed; + BYTE env_decay; + BYTE env_count; + BYTE dummy0; + INT env_vol; + + // For Sweep + BYTE swp_on; + BYTE swp_inc; + BYTE swp_shift; + BYTE swp_decay; + BYTE swp_count; + BYTE dummy1[3]; + + // For sync; + BYTE sync_reg[4]; + BYTE sync_output_enable; + BYTE sync_enable; + BYTE sync_holdnote; + BYTE dummy2; + INT sync_len_count; + } RECTANGLE, *LPRECTANGLE; + + typedef struct { + BYTE reg[4]; + + BYTE enable; + BYTE holdnote; + BYTE counter_start; + BYTE dummy0; + + INT phaseacc; + INT freq; + INT len_count; + INT lin_count; + INT adder; + + INT nowvolume; + + // For sync; + BYTE sync_reg[4]; + BYTE sync_enable; + BYTE sync_holdnote; + BYTE sync_counter_start; +// BYTE dummy1; + INT sync_len_count; + INT sync_lin_count; + } TRIANGLE, *LPTRIANGLE; + + typedef struct { + BYTE reg[4]; // register + + BYTE enable; // enable + BYTE holdnote; // holdnote + BYTE volume; // volume + BYTE xor_tap; + INT shift_reg; + + // For Render + INT phaseacc; + INT freq; + INT len_count; + + INT nowvolume; + INT output; + + // For Envelope + BYTE env_fixed; + BYTE env_decay; + BYTE env_count; + BYTE dummy0; + INT env_vol; + + // For sync; + BYTE sync_reg[4]; + BYTE sync_output_enable; + BYTE sync_enable; + BYTE sync_holdnote; + BYTE dummy1; + INT sync_len_count; + } NOISE, *LPNOISE; + + typedef struct { + BYTE reg[4]; + BYTE enable; + BYTE looping; + BYTE cur_byte; + BYTE dpcm_value; + + INT freq; + INT phaseacc; + INT output; + + WORD address, cache_addr; + INT dmalength, cache_dmalength; + INT dpcm_output_real, dpcm_output_fake, dpcm_output_old, dpcm_output_offset; + + // For sync + BYTE sync_reg[4]; + BYTE sync_enable; + BYTE sync_looping; + BYTE sync_irq_gen; + BYTE sync_irq_enable; + INT sync_cycles, sync_cache_cycles; + INT sync_dmalength, sync_cache_dmalength; + } DPCM, *LPDPCM; + + void SyncWrite4017( BYTE data ); + + // Rectangle + void WriteRectangle ( INT no, WORD addr, BYTE data ); + void UpdateRectangle( RECTANGLE& ch, INT type ); + INT RenderRectangle( RECTANGLE& ch ); + // For Sync + void SyncWriteRectangle ( INT no, WORD addr, BYTE data ); + void SyncUpdateRectangle( RECTANGLE& ch, INT type ); + + // Triangle + void WriteTriangle ( WORD addr, BYTE data ); + void UpdateTriangle( INT type ); + INT RenderTriangle(); + // For Sync + void SyncWriteTriangle ( WORD addr, BYTE data ); + void SyncUpdateTriangle( INT type ); + + // Noise + void WriteNoise ( WORD addr, BYTE data ); + void UpdateNoise( INT type ); + BYTE NoiseShiftreg( BYTE xor_tap ); + INT RenderNoise(); + // For Sync + void SyncWriteNoise ( WORD addr, BYTE data ); + void SyncUpdateNoise( INT type ); + + // DPCM + void WriteDPCM ( WORD addr, BYTE data ); +// void UpdateDPCM(); + INT RenderDPCM(); + // For Sync + void SyncWriteDPCM ( WORD addr, BYTE data ); + BOOL SyncUpdateDPCM( INT cycles ); + + // Frame Counter + INT FrameCycle; + INT FrameCount; + INT FrameType; + BYTE FrameIRQ; + BYTE FrameIRQoccur; + + // Channels + RECTANGLE ch0; + RECTANGLE ch1; + TRIANGLE ch2; + NOISE ch3; + DPCM ch4; + + // $4015 Reg + BYTE reg4015, sync_reg4015; + + // NES object(ref) + NES* nes; + + // Sound + FLOAT cpu_clock; + INT sampling_rate; + INT cycle_rate; + + // Tables + static INT vbl_length[32]; + static INT freq_limit[8]; + static INT duty_lut[4]; + static INT noise_freq[16]; + static INT dpcm_cycles[16]; +// static INT vol_effect[16]; + + // WaveTables + enum { TONEDATA_MAX = 16, TONEDATA_LEN = 32 }; + enum { CHANNEL_MAX = 3, TONE_MAX = 4 }; + + BOOL bToneTableEnable[TONEDATA_MAX]; + INT ToneTable[TONEDATA_MAX][TONEDATA_LEN]; + INT ChannelTone[CHANNEL_MAX][TONE_MAX]; + +private: +}; + +#endif // !__APU_INTERNAL_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_MMC5.cpp b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_MMC5.cpp new file mode 100644 index 00000000..675feb96 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_MMC5.cpp @@ -0,0 +1,380 @@ +////////////////////////////////////////////////////////////////////////// +// // +// Nintendo MMC5 // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#include "DebugOut.h" + +#include "APU_MMC5.h" +#include "state.h" + +#define RECTANGLE_VOL_SHIFT 8 +#define DAOUT_VOL_SHIFT 6 + +INT APU_MMC5::vbl_length[32] = { + 5, 127, 10, 1, 19, 2, 40, 3, + 80, 4, 30, 5, 7, 6, 13, 7, + 6, 8, 12, 9, 24, 10, 48, 11, + 96, 12, 36, 13, 8, 14, 16, 15 +}; + +INT APU_MMC5::duty_lut[4] = { + 2, 4, 8, 12 +}; + +INT APU_MMC5::decay_lut[16]; +INT APU_MMC5::vbl_lut[32]; + +APU_MMC5::APU_MMC5() +{ + // ݒ + Reset( APU_CLOCK, 22050 ); +} + +APU_MMC5::~APU_MMC5() +{ +} + +void APU_MMC5::Reset( FLOAT fClock, INT nRate ) +{ + ZeroMemory( &ch0, sizeof(ch0) ); + ZeroMemory( &ch1, sizeof(ch1) ); + + reg5010 = reg5011 = reg5015 = 0; + + sync_reg5015 = 0; + FrameCycle = 0; + + Setup( fClock, nRate ); + + for( WORD addr = 0x5000; addr <= 0x5015; addr++ ) { + Write( addr, 0 ); + } +} + +void APU_MMC5::Setup( FLOAT fClock, INT nRate ) +{ + cpu_clock = fClock; + cycle_rate = (INT)(fClock*65536.0f/(float)nRate); + + // Create Tables + INT i; + INT samples = (INT)((float)nRate/60.0f); + for( i = 0; i < 16; i++ ) + decay_lut[i] = (i+1)*samples*5; + for( i = 0; i < 32; i++ ) + vbl_lut[i] = vbl_length[i]*samples*5; +} + +void APU_MMC5::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X:%02X\n", addr, data ); + switch( addr ) { + // MMC5 CH0 rectangle + case 0x5000: + ch0.reg[0] = data; + ch0.volume = data&0x0F; + ch0.holdnote = data&0x20; + ch0.fixed_envelope = data&0x10; + ch0.env_decay = decay_lut[data&0x0F]; + ch0.duty_flip = duty_lut[data>>6]; + break; + case 0x5001: + ch0.reg[1] = data; + break; + case 0x5002: + ch0.reg[2] = data; + ch0.freq = INT2FIX( ((ch0.reg[3]&0x07)<<8)+data+1 ); + break; + case 0x5003: + ch0.reg[3] = data; + ch0.vbl_length = vbl_lut[data>>3]; + ch0.env_vol = 0; + ch0.freq = INT2FIX( ((data&0x07)<<8)+ch0.reg[2]+1 ); + if( reg5015 & 0x01 ) + ch0.enable = 0xFF; + break; + // MMC5 CH1 rectangle + case 0x5004: + ch1.reg[0] = data; + ch1.volume = data&0x0F; + ch1.holdnote = data&0x20; + ch1.fixed_envelope = data&0x10; + ch1.env_decay = decay_lut[data&0x0F]; + ch1.duty_flip = duty_lut[data>>6]; + break; + case 0x5005: + ch1.reg[1] = data; + break; + case 0x5006: + ch1.reg[2] = data; + ch1.freq = INT2FIX( ((ch1.reg[3]&0x07)<<8)+data+1 ); + break; + case 0x5007: + ch1.reg[3] = data; + ch1.vbl_length = vbl_lut[data>>3]; + ch1.env_vol = 0; + ch1.freq = INT2FIX( ((data&0x07)<<8)+ch1.reg[2]+1 ); + if( reg5015 & 0x02 ) + ch1.enable = 0xFF; + break; + case 0x5010: + reg5010 = data; + break; + case 0x5011: + reg5011 = data; + break; + case 0x5012: + case 0x5013: + case 0x5014: + break; + case 0x5015: + reg5015 = data; + if( reg5015 & 0x01 ) { + ch0.enable = 0xFF; + } else { + ch0.enable = 0; + ch0.vbl_length = 0; + } + if( reg5015 & 0x02 ) { + ch1.enable = 0xFF; + } else { + ch1.enable = 0; + ch1.vbl_length = 0; + } + break; + } +} + +void APU_MMC5::SyncWrite( WORD addr, BYTE data ) +{ + switch( addr ) { + // MMC5 CH0 rectangle + case 0x5000: + sch0.reg[0] = data; + sch0.holdnote = data&0x20; + break; + case 0x5001: + case 0x5002: + sch0.reg[addr&3] = data; + break; + case 0x5003: + sch0.reg[3] = data; + sch0.vbl_length = vbl_length[data>>3]; + if( sync_reg5015 & 0x01 ) + sch0.enable = 0xFF; + break; + // MMC5 CH1 rectangle + case 0x5004: + sch1.reg[0] = data; + sch1.holdnote = data&0x20; + break; + case 0x5005: + case 0x5006: + sch1.reg[addr&3] = data; + break; + case 0x5007: + sch1.reg[3] = data; + sch1.vbl_length = vbl_length[data>>3]; + if( sync_reg5015 & 0x02 ) + sch1.enable = 0xFF; + break; + case 0x5010: + case 0x5011: + case 0x5012: + case 0x5013: + case 0x5014: + break; + case 0x5015: + sync_reg5015 = data; + if( sync_reg5015 & 0x01 ) { + sch0.enable = 0xFF; + } else { + sch0.enable = 0; + sch0.vbl_length = 0; + } + if( sync_reg5015 & 0x02 ) { + sch1.enable = 0xFF; + } else { + sch1.enable = 0; + sch1.vbl_length = 0; + } + break; + } +} + +BYTE APU_MMC5::SyncRead( WORD addr ) +{ +BYTE data = 0; + + if( addr == 0x5015 ) { + if( sch0.enable && sch0.vbl_length > 0 ) data |= (1<<0); + if( sch1.enable && sch1.vbl_length > 0 ) data |= (1<<1); + } + + return data; +} + +BOOL APU_MMC5::Sync( INT cycles ) +{ + FrameCycle += cycles; + if( FrameCycle >= 7457*5/2 ) { + FrameCycle -= 7457*5/2; + + if( sch0.enable && !sch0.holdnote ) { + if( sch0.vbl_length ) { + sch0.vbl_length--; + } + } + if( sch1.enable && !sch1.holdnote ) { + if( sch1.vbl_length ) { + sch1.vbl_length--; + } + } + } + + return FALSE; +} + +INT APU_MMC5::Process( INT channel ) +{ + switch( channel ) { + case 0: + return RectangleRender( ch0 ); + break; + case 1: + return RectangleRender( ch1 ); + break; + case 2: + return (INT)reg5011 << DAOUT_VOL_SHIFT; + break; + } + + return 0; +} + +INT APU_MMC5::GetFreq( INT channel ) +{ + if( channel == 0 || channel == 1 ) { + RECTANGLE* ch; + if( channel == 0 ) ch = &ch0; + else ch = &ch1; + + if( !ch->enable || ch->vbl_length <= 0 ) + return 0; + if( ch->freq < INT2FIX( 8 ) ) + return 0; + if( ch->fixed_envelope ) { + if( !ch->volume ) + return 0; + } else { + if( !(0x0F-ch->env_vol) ) + return 0; + } + + return (INT)(256.0f*cpu_clock/((FLOAT)FIX2INT(ch->freq)*16.0f)); + } + + return 0; +} + +INT APU_MMC5::RectangleRender( RECTANGLE& ch ) +{ + if( !ch.enable || ch.vbl_length <= 0 ) + return 0; + + // vbl length counter + if( !ch.holdnote ) + ch.vbl_length -= 5; + + // envelope unit + ch.env_phase -= 5*4; + while( ch.env_phase < 0 ) { + ch.env_phase += ch.env_decay; + if( ch.holdnote ) + ch.env_vol = (ch.env_vol+1)&0x0F; + else if( ch.env_vol < 0x0F ) + ch.env_vol++; + } + + if( ch.freq < INT2FIX( 8 ) ) + return 0; + + INT volume; + if( ch.fixed_envelope ) + volume = (INT)ch.volume; + else + volume = (INT)(0x0F-ch.env_vol); + + INT output = volume<= 0 ) { + if( ch.adder < ch.duty_flip ) + ch.output_vol = output; + else + ch.output_vol = -output; + return ch.output_vol; + } + + if( ch.freq > cycle_rate ) { + ch.phaseacc += ch.freq; + ch.adder = (ch.adder+1)&0x0F; + if( ch.adder < ch.duty_flip ) + ch.output_vol = output; + else + ch.output_vol = -output; + } else { + // d + INT num_times, total; + num_times = total = 0; + while( ch.phaseacc < 0 ) { + ch.phaseacc += ch.freq; + ch.adder = (ch.adder+1)&0x0F; + if( ch.adder < ch.duty_flip ) + total += output; + else + total -= output; + num_times++; + } + ch.output_vol = total/num_times; + } + + return ch.output_vol; +} + +INT APU_MMC5::GetStateSize() +{ + return 3*sizeof(BYTE) + sizeof(ch0) + sizeof(ch1) + sizeof(sch0) + sizeof(sch1); +} + +void APU_MMC5::SaveState( LPBYTE p ) +{ + SETBYTE( p, reg5010 ); + SETBYTE( p, reg5011 ); + SETBYTE( p, reg5015 ); + + SETBLOCK( p, &ch0, sizeof(ch0) ); + SETBLOCK( p, &ch1, sizeof(ch1) ); + + SETBYTE( p, sync_reg5015 ); + SETBLOCK( p, &sch0, sizeof(sch0) ); + SETBLOCK( p, &sch1, sizeof(sch1) ); +} + +void APU_MMC5::LoadState( LPBYTE p ) +{ + GETBYTE( p, reg5010 ); + GETBYTE( p, reg5011 ); + GETBYTE( p, reg5015 ); + + GETBLOCK( p, &ch0, sizeof(ch0) ); + GETBLOCK( p, &ch1, sizeof(ch1) ); + + GETBYTE( p, sync_reg5015 ); + GETBLOCK( p, &sch0, sizeof(sch0) ); + GETBLOCK( p, &sch1, sizeof(sch1) ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_MMC5.h b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_MMC5.h new file mode 100644 index 00000000..970b3d21 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_MMC5.h @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// // +// Nintendo MMC5 // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __APU_MMC5_INCLUDED__ +#define __APU_MMC5_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +#include "typedef.h" +#include "macro.h" + +#include "APU_INTERFACE.h" + +class APU_MMC5 : public APU_INTERFACE +{ +public: + APU_MMC5(); + ~APU_MMC5(); + + void Reset( FLOAT fClock, INT nRate ); + void Setup( FLOAT fClock, INT nRate ); + void Write( WORD addr, BYTE data ); + INT Process( INT channel ); + + void SyncWrite( WORD addr, BYTE data ); + BYTE SyncRead ( WORD addr ); + BOOL Sync( INT cycles ); + + INT GetFreq( INT channel ); + + INT GetStateSize(); + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); +protected: + typedef struct { + BYTE reg[4]; + BYTE enable; + + INT vbl_length; + + INT phaseacc; + INT freq; + + INT output_vol; + BYTE fixed_envelope; + BYTE holdnote; + BYTE volume; + + BYTE env_vol; + INT env_phase; + INT env_decay; + + INT adder; + INT duty_flip; + } RECTANGLE, *LPRECTANGLE; + + typedef struct { + // For sync + BYTE reg[4]; + BYTE enable; + BYTE holdnote; + BYTE dummy[2]; + INT vbl_length; + } SYNCRECTANGLE, *LPSYNCRECTANGLE; + + INT RectangleRender( RECTANGLE& ch ); + + RECTANGLE ch0, ch1; + SYNCRECTANGLE sch0, sch1; + + BYTE reg5010; + BYTE reg5011; + BYTE reg5015; + INT cycle_rate; + + INT FrameCycle; + BYTE sync_reg5015; + + FLOAT cpu_clock; + + // Tables + static INT vbl_length[32]; + static INT duty_lut[4]; + + static INT decay_lut[16]; + static INT vbl_lut[32]; +private: +}; + +#endif // !__APU_MMC5_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_N106.cpp b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_N106.cpp new file mode 100644 index 00000000..a5bb0a7a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_N106.cpp @@ -0,0 +1,191 @@ +////////////////////////////////////////////////////////////////////////// +// // +// Namcot N106 // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#include "APU_N106.h" +#include "state.h" + +#include "DebugOut.h" + +#define CHANNEL_VOL_SHIFT 6 + +APU_N106::APU_N106() +{ + // ŏTONȄs + ::ZeroMemory( tone, sizeof(tone) ); + + // ݒ + cpu_clock = APU_CLOCK; + cycle_rate = (DWORD)(cpu_clock*12.0f*(1<<20)/(45.0f*22050.0f)); +} + +APU_N106::~APU_N106() +{ +} + +void APU_N106::Reset( FLOAT fClock, INT nRate ) +{ + for( INT i = 0; i < 8; i++ ) { + ::ZeroMemory( &op[i], sizeof(op[i]) ); + op[i].tonelen = 0x10<<18; + } + + address = 0; + addrinc = 1; + channel_use = 8; + + Setup( fClock, nRate ); + + // TONȄ͂Ȃ... +} + +void APU_N106::Setup( FLOAT fClock, INT nRate ) +{ + cpu_clock = fClock; + cycle_rate = (DWORD)(cpu_clock*12.0f*(1<<20)/(45.0f*nRate)); +} + +void APU_N106::Write( WORD addr, BYTE data ) +{ + if( addr == 0x4800 ) { +// tone[address*2+0] = (INT)(data&0x0F); +// tone[address*2+1] = (INT)(data >>4); + tone[address*2+0] = data&0x0F; + tone[address*2+1] = data>>4; + + if( address >= 0x40 ) { + INT no = (address-0x40)>>3; + DWORD tonelen; + CHANNEL& ch = op[no]; + + switch( address & 7 ) { + case 0x00: + ch.freq = (ch.freq&~0x000000FF)|(DWORD)data; + break; + case 0x02: + ch.freq = (ch.freq&~0x0000FF00)|((DWORD)data<<8); + break; + case 0x04: + ch.freq = (ch.freq&~0x00030000)|(((DWORD)data&0x03)<<16); + tonelen = (0x20-(data&0x1c))<<18; + ch.databuf = (data&0x1c)>>2; + if( ch.tonelen != tonelen ) { + ch.tonelen = tonelen; + ch.phase = 0; + } + break; + case 0x06: + ch.toneadr = data; + break; + case 0x07: + ch.vol = data&0x0f; + ch.volupdate = 0xFF; + if( no == 7 ) + channel_use = ((data>>4)&0x07)+1; + break; + } + } + + if( addrinc ) { + address = (address+1)&0x7f; + } + } else if( addr == 0xF800 ) { + address = data&0x7F; + addrinc = data&0x80; + } +} + +BYTE APU_N106::Read( WORD addr ) +{ + // $4800 dummy read!! + if( addr == 0x0000 ) { + if( addrinc ) { + address = (address+1)&0x7F; + } + } + + return (BYTE)(addr>>8); +} + +INT APU_N106::Process( INT channel ) +{ + if( channel >= (8-channel_use) && channel < 8 ) { + return ChannelRender( op[channel] ); + } + + return 0; +} + +INT APU_N106::GetFreq( INT channel ) +{ + if( channel < 8 ) { + channel &= 7; + if( channel < (8-channel_use) ) + return 0; + + CHANNEL* ch = &op[channel&0x07]; + if( !ch->freq || !ch->vol ) + return 0; + INT temp = channel_use*(8-ch->databuf)*4*45; + if( !temp ) + return 0; + return (INT)(256.0*(double)cpu_clock*12.0*ch->freq/((double)0x40000*temp)); + } + + return 0; +} + +INT APU_N106::ChannelRender( CHANNEL& ch ) +{ +DWORD phasespd = channel_use<<20; + + ch.phaseacc -= cycle_rate; + if( ch.phaseacc >= 0 ) { + if( ch.volupdate ) { + ch.output = ((INT)tone[((ch.phase>>18)+ch.toneadr)&0xFF]*ch.vol)<= ch.tonelen)) { + ch.phase -= ch.tonelen; + } + + ch.output = ((INT)tone[((ch.phase>>18)+ch.toneadr)&0xFF]*ch.vol)<>4)&0x07; + break; + case 0x9001: + ch0.reg[1] = data; + ch0.freq = INT2FIX( (((ch0.reg[2]&0x0F)<<8)|data)+1 ); + break; + case 0x9002: + ch0.reg[2] = data; + ch0.enable = data&0x80; + ch0.freq = INT2FIX( (((data&0x0F)<<8)|ch0.reg[1])+1 ); + break; + // VRC6 CH1 rectangle + case 0xA000: + ch1.reg[0] = data; + ch1.gate = data&0x80; + ch1.volume = data&0x0F; + ch1.duty_pos = (data>>4)&0x07; + break; + case 0xA001: + ch1.reg[1] = data; + ch1.freq = INT2FIX( (((ch1.reg[2]&0x0F)<<8)|data)+1 ); + break; + case 0xA002: + ch1.reg[2] = data; + ch1.enable = data&0x80; + ch1.freq = INT2FIX( (((data&0x0F)<<8)|ch1.reg[1])+1 ); + break; + // VRC6 CH2 sawtooth + case 0xB000: + ch2.reg[1] = data; + ch2.phaseaccum = data&0x3F; + break; + case 0xB001: + ch2.reg[1] = data; + ch2.freq = INT2FIX( (((ch2.reg[2]&0x0F)<<8)|data)+1 ); + break; + case 0xB002: + ch2.reg[2] = data; + ch2.enable = data&0x80; + ch2.freq = INT2FIX( (((data&0x0F)<<8)|ch2.reg[1])+1 ); +// ch2.adder = 0; // NAƃmCY̌ɂȂ +// ch2.accum = 0; // NAƃmCY̌ɂȂ + break; + } +} + +INT APU_VRC6::Process( INT channel ) +{ + switch( channel ) { + case 0: + return RectangleRender( ch0 ); + break; + case 1: + return RectangleRender( ch1 ); + break; + case 2: + return SawtoothRender( ch2 ); + break; + } + + return 0; +} + +INT APU_VRC6::GetFreq( INT channel ) +{ + if( channel == 0 || channel == 1 ) { + RECTANGLE* ch; + if( channel == 0 ) ch = &ch0; + else ch = &ch1; + if( !ch->enable || ch->gate || !ch->volume ) + return 0; + if( ch->freq < INT2FIX( 8 ) ) + return 0; + return (INT)(256.0f*cpu_clock/((FLOAT)FIX2INT(ch->freq)*16.0f)); + } + if( channel == 2 ) { + SAWTOOTH* ch = &ch2; + if( !ch->enable || !ch->phaseaccum ) + return 0; + if( ch->freq < INT2FIX( 8 ) ) + return 0; + return (INT)(256.0f*cpu_clock/((FLOAT)FIX2INT(ch->freq)*14.0f)); + } + + return 0; +} + +INT APU_VRC6::RectangleRender( RECTANGLE& ch ) +{ + // Enable? + if( !ch.enable ) { + ch.output_vol = 0; + ch.adder = 0; + return ch.output_vol; + } + + // Digitized output + if( ch.gate ) { + ch.output_vol = ch.volume<= 0 ) + return ch.output_vol; + + INT output = ch.volume< cycle_rate ) { + // add 1 step + ch.phaseacc += ch.freq; + ch.adder = (ch.adder+1)&0x0F; + if( ch.adder <= ch.duty_pos ) + ch.output_vol = output; + else + ch.output_vol = -output; + } else { + // average calculate + INT num_times, total; + num_times = total = 0; + while( ch.phaseacc < 0 ) { + ch.phaseacc += ch.freq; + ch.adder = (ch.adder+1)&0x0F; + if( ch.adder <= ch.duty_pos ) + total += output; + else + total += -output; + num_times++; + } + ch.output_vol = total/num_times; + } + + return ch.output_vol; +} + +INT APU_VRC6::SawtoothRender( SAWTOOTH& ch ) +{ + // Digitized output + if( !ch.enable ) { + ch.output_vol = 0; + return ch.output_vol; + } + + // ȏ̎g͏Ȃ() + if( ch.freq < INT2FIX( 9 ) ) { + return ch.output_vol; + } + + ch.phaseacc -= cycle_rate/2; + if( ch.phaseacc >= 0 ) + return ch.output_vol; + + if( ch.freq > cycle_rate/2 ) { + // add 1 step + ch.phaseacc += ch.freq; + if( ++ch.adder >= 7 ) { + ch.adder = 0; + ch.accum = 0; + } + ch.accum += ch.phaseaccum; + ch.output_vol = ch.accum<= 7 ) { + ch.adder = 0; + ch.accum = 0; + } + ch.accum += ch.phaseaccum; + total += ch.accum<masterVolume = 128; + } + + // ݒ + Reset( APU_CLOCK, 22050 ); +} + +APU_VRC7::~APU_VRC7() +{ + if( VRC7_OPLL ) { + OPLL_delete( VRC7_OPLL ); + VRC7_OPLL = NULL; +// OPLL_close(); // Ăǂ(g) + } +} + +void APU_VRC7::Reset( FLOAT fClock, INT nRate ) +{ + if( VRC7_OPLL ) { + OPLL_reset( VRC7_OPLL ); + OPLL_reset_patch( VRC7_OPLL, OPLL_VRC7_TONE ); + VRC7_OPLL->masterVolume = 128; + } + + address = 0; + + Setup( fClock, nRate ); +} + +void APU_VRC7::Setup( FLOAT fClock, INT nRate ) +{ + OPLL_setClock( (uint32)(fClock*2.0f), (uint32)nRate ); +} + +void APU_VRC7::Write( WORD addr, BYTE data ) +{ + if( VRC7_OPLL ) { + if( addr == 0x9010 ) { + address = data; + } else if( addr == 0x9030 ) { + OPLL_writeReg( VRC7_OPLL, address, data ); + } + } +} + +INT APU_VRC7::Process( INT channel ) +{ + if( VRC7_OPLL ) + return OPLL_calc( VRC7_OPLL ); + + return 0; +} + +INT APU_VRC7::GetFreq( INT channel ) +{ + if( VRC7_OPLL && channel < 8 ) { + INT fno = (((INT)VRC7_OPLL->reg[0x20+channel]&0x01)<<8) + + (INT)VRC7_OPLL->reg[0x10+channel]; + INT blk = (VRC7_OPLL->reg[0x20+channel]>>1) & 0x07; + float blkmul[] = { 0.5f, 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f }; + + if( VRC7_OPLL->reg[0x20+channel] & 0x10 ) { + return (INT)((256.0*(double)fno*blkmul[blk]) / ((double)(1<<18)/(3579545.0/72.0))); + } + } + + return 0; +} diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/APU_VRC7.h b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_VRC7.h new file mode 100644 index 00000000..dfa3ad5b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/APU_VRC7.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// // +// Konami VRC7 // +// Norix // +// written 2001/09/18 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __APU_VRC7_INCLUDED__ +#define __APU_VRC7_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +#include "typedef.h" +#include "macro.h" + +#include "APU_INTERFACE.h" + +#include "emu2413.h" + +class APU_VRC7 : public APU_INTERFACE +{ +public: + APU_VRC7(); + ~APU_VRC7(); + + void Reset( FLOAT fClock, INT nRate ); + void Setup( FLOAT fClock, INT nRate ); + void Write( WORD addr, BYTE data ); + INT Process( INT channel ); + + INT GetFreq( INT channel ); +protected: + OPLL* VRC7_OPLL; + + BYTE address; +private: +}; + +#endif // !__APU_VRC7_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/2413tone.h b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/2413tone.h new file mode 100644 index 00000000..45cc21f8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/2413tone.h @@ -0,0 +1,20 @@ +/* YM2413 VOICE */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0x61, 0x1e, 0x17, 0xf0, 0x7f, 0x07, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x13, 0x41, 0x0f, 0x0d, 0xce, 0xd2, 0x43, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x01, 0x99, 0x04, 0xff, 0xc3, 0x03, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x21, 0x61, 0x1b, 0x07, 0xaf, 0x63, 0x40, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x22, 0x21, 0x1e, 0x06, 0xf0, 0x76, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x10, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0x21, 0x1b, 0x06, 0x64, 0x65, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0x61, 0x0c, 0x18, 0x85, 0xa0, 0x79, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x23, 0x21, 0x87, 0x11, 0xf0, 0xa4, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x97, 0xe1, 0x28, 0x07, 0xff, 0xf3, 0x02, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0x10, 0x0c, 0x05, 0xf2, 0xc4, 0x40, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x56, 0x03, 0xb4, 0xb2, 0x23, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x21, 0x28, 0x00, 0xdf, 0xf8, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x23, 0x22, 0x00, 0x00, 0xd8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x25, 0x18, 0x00, 0x00, 0xf8, 0xda, 0xf8, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.c b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/emu2413.c similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.c rename to References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/emu2413.c diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/emu2413.h b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/emu2413.h new file mode 100644 index 00000000..795c0a7f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/emu2413.h @@ -0,0 +1,172 @@ +#ifndef _EMU2413_H_ +#define _EMU2413_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef EMU2413_DLL_EXPORTS + #define EMU2413_API __declspec(dllexport) +#elif EMU2413_DLL_IMPORTS + #define EMU2413_API __declspec(dllimport) +#else + #define EMU2413_API +#endif + +#define PI 3.14159265358979 + +#ifndef __VMTYPES_INCLUDED__ +typedef unsigned int uint32 ; +typedef int int32 ; +typedef signed short int16 ; +typedef unsigned short uint16 ; +//typedef signed char int8 ; +typedef char int8 ; +typedef unsigned char uint8 ; +#endif + +enum {OPLL_2413_TONE=0, OPLL_VRC7_TONE=1} ; + +/* voice data */ +typedef struct { + unsigned int TL,FB,EG,ML,AR,DR,SL,RR,KR,KL,AM,PM,WF ; +} OPLL_PATCH ; + +/* slot */ +typedef struct { + + OPLL_PATCH *patch; + + int type ; /* 0 : modulator 1 : carrier */ + + /* OUTPUT */ + int32 feedback ; + int32 output[5] ; /* Output value of slot */ + + /* for Phase Generator (PG) */ + uint32 *sintbl ; /* Wavetable */ + uint32 phase ; /* Phase */ + uint32 dphase ; /* Phase increment amount */ + uint32 pgout ; /* output */ + + /* for Envelope Generator (EG) */ + int fnum ; /* F-Number */ + int block ; /* Block */ + int volume ; /* Current volume */ + int sustine ; /* Sustine 1 = ON, 0 = OFF */ + uint32 tll ; /* Total Level + Key scale level*/ + uint32 rks ; /* Key scale offset (Rks) */ + int eg_mode ; /* Current state */ + uint32 eg_phase ; /* Phase */ + uint32 eg_dphase ; /* Phase increment amount */ + uint32 egout ; /* output */ + + + /* refer to opll-> */ + int32 *plfo_pm ; + int32 *plfo_am ; + + +} OPLL_SLOT ; + +/* Channel */ +typedef struct { + + int patch_number ; + int key_status ; + OPLL_SLOT *mod, *car ; + +} OPLL_CH ; + +/* Mask */ +#define OPLL_MASK_CH(x) (1<<(x)) +#define OPLL_MASK_HH (1<<(9)) +#define OPLL_MASK_CYM (1<<(10)) +#define OPLL_MASK_TOM (1<<(11)) +#define OPLL_MASK_SD (1<<(12)) +#define OPLL_MASK_BD (1<<(13)) +#define OPLL_MASK_RYTHM ( OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD ) + +/* opll */ +typedef struct { + + uint32 adr ; + + int32 output[2] ; + + /* Register */ + unsigned char reg[0x40] ; + int slot_on_flag[18] ; + + /* Rythm Mode : 0 = OFF, 1 = ON */ + int rythm_mode ; + + /* Pitch Modulator */ + uint32 pm_phase ; + int32 lfo_pm ; + + /* Amp Modulator */ + int32 am_phase ; + int32 lfo_am ; + + + /* Noise Generator */ + uint32 noise_seed ; + uint32 whitenoise ; + uint32 noiseA ; + uint32 noiseB ; + uint32 noiseA_phase ; + uint32 noiseB_phase ; + uint32 noiseA_idx ; + uint32 noiseB_idx ; + uint32 noiseA_dphase ; + uint32 noiseB_dphase ; + + /* Channel & Slot */ + OPLL_CH *ch[9] ; + OPLL_SLOT *slot[18] ; + + /* Voice Data */ + OPLL_PATCH *patch[19*2] ; + int patch_update[2] ; /* flag for check patch update */ + + uint32 mask ; + + int masterVolume ; /* 0min -- 64 -- 127 max (Liner) */ + +} OPLL ; + +/* Initialize */ +EMU2413_API void OPLL_init(uint32 clk, uint32 rate) ; +EMU2413_API void OPLL_close(void) ; + +/* Create Object */ +EMU2413_API OPLL *OPLL_new(void) ; +EMU2413_API void OPLL_delete(OPLL *) ; + +/* Setup */ +EMU2413_API void OPLL_reset(OPLL *) ; +EMU2413_API void OPLL_reset_patch(OPLL *, int) ; +EMU2413_API void OPLL_setClock(uint32 c, uint32 r) ; + +/* Port/Register access */ +EMU2413_API void OPLL_writeIO(OPLL *, uint32 reg, uint32 val) ; +EMU2413_API void OPLL_writeReg(OPLL *, uint32 reg, uint32 val) ; + +/* Synthsize */ +EMU2413_API int16 OPLL_calc(OPLL *) ; + +/* Misc */ +EMU2413_API void OPLL_copyPatch(OPLL *, int, OPLL_PATCH *) ; +EMU2413_API void OPLL_forceRefresh(OPLL *) ; +EMU2413_API void dump2patch(unsigned char *, OPLL_PATCH *) ; + +/* Channel Mask */ +EMU2413_API uint32 OPLL_setMask(OPLL *, uint32 mask) ; +EMU2413_API uint32 OPLL_toggleMask(OPLL *, uint32 mask) ; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/vrc7tone.h b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/vrc7tone.h new file mode 100644 index 00000000..bd2abf06 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ApuEX/emu2413/vrc7tone.h @@ -0,0 +1,20 @@ +/* VRC7 VOICE */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x33, 0x01, 0x09, 0x0e, 0x94, 0x90, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x13, 0x41, 0x0f, 0x0d, 0xce, 0xd3, 0x43, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x12, 0x1b, 0x06, 0xff, 0xd2, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x61, 0x61, 0x1b, 0x07, 0xaf, 0x63, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x22, 0x21, 0x1e, 0x06, 0xf0, 0x76, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x21, 0x15, 0x00, 0x93, 0x94, 0x20, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x21, 0x61, 0x1c, 0x07, 0x82, 0x81, 0x10, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x23, 0x21, 0x20, 0x1f, 0xc0, 0x71, 0x07, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x25, 0x31, 0x26, 0x05, 0x64, 0x41, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x17, 0x21, 0x28, 0x07, 0xff, 0x83, 0x02, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x97, 0x81, 0x25, 0x07, 0xcf, 0xc8, 0x02, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x21, 0x21, 0x54, 0x0f, 0x80, 0x7f, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x56, 0x03, 0xd3, 0xb2, 0x43, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x31, 0x21, 0x0c, 0x03, 0x82, 0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x21, 0x01, 0x0c, 0x03, 0xd4, 0xd3, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x21, 0x28, 0x00, 0xdf, 0xf8, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x23, 0x22, 0x00, 0x00, 0xa8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x25, 0x18, 0x00, 0x00, 0xf8, 0xa9, 0xf8, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/References/VirtuaNESex_src_191105/NES/CPU.h b/References/VirtuaNESex_src_191105/NES/CPU.h new file mode 100644 index 00000000..8db4e42b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/CPU.h @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////////////////// +// // +// 6502 CPU core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __CPU_INCLUDED__ +#define __CPU_INCLUDED__ + +#include "typedef.h" +#include "macro.h" + +class NES; +class APU; +class Mapper; + +// 6502 status flags +#define C_FLAG 0x01 // 1: Carry +#define Z_FLAG 0x02 // 1: Zero +#define I_FLAG 0x04 // 1: Irq disabled +#define D_FLAG 0x08 // 1: Decimal mode flag (NES unused) +#define B_FLAG 0x10 // 1: Break +#define R_FLAG 0x20 // 1: Reserved (Always 1) +#define V_FLAG 0x40 // 1: Overflow +#define N_FLAG 0x80 // 1: Negative + +// Interrupt +#define NMI_FLAG 0x01 +#define IRQ_FLAG 0x02 + +#define IRQ_FRAMEIRQ 0x04 +#define IRQ_DPCM 0x08 +#define IRQ_MAPPER 0x10 +#define IRQ_MAPPER2 0x20 +#define IRQ_TRIGGER 0x40 // one shot(IRQ()) +#define IRQ_TRIGGER2 0x80 // one shot(IRQ_NotPending()) + +#define IRQ_MASK (~(NMI_FLAG|IRQ_FLAG)) + +// Vector +#define NMI_VECTOR 0xFFFA +#define RES_VECTOR 0xFFFC +#define IRQ_VECTOR 0xFFFE + +// 6502 context +typedef struct { + WORD PC; /* Program counter */ + BYTE A; /* CPU registers */ + BYTE P; + BYTE X; + BYTE Y; + BYTE S; + + BYTE INT_pending; // 荞݃yfBOtO +} R6502; + + +class CPU +{ +public: + CPU( NES* parent ); + virtual ~CPU(); + + BYTE RD6502( WORD addr ); + void WR6502( WORD addr, BYTE data ); + WORD RD6502W( WORD addr ); + + void Reset(); + + void NMI(); + void SetIRQ( BYTE mask ); + void ClrIRQ( BYTE mask ); + + void DMA( INT cycles ); + + INT EXEC( INT request_cycles ); + + INT GetDmaCycles(); + void SetDmaCycles( INT cycles ); + + INT GetTotalCycles(); + void SetTotalCycles( INT cycles ); + + void SetContext( R6502 r ) { R = r; } + void GetContext( R6502& r ) { r = R; } + + void SetClockProcess( BOOL bEnable ) { m_bClockProcess = bEnable; } + + // + unsigned char DebugMemCPU (unsigned short Addr); + int DecodeInstruction (unsigned short Addr, char *str1); + + +protected: + NES* nes; + APU* apu; + Mapper* mapper; + + R6502 R; + + INT TOTAL_cycles; // CPUg[^TCN + INT DMA_cycles; // DMATCN + + // PTR + LPBYTE STACK; + + // Zero & Negative table + BYTE ZN_Table[256]; + + // Clock process + BOOL m_bClockProcess; +private: +}; + +#endif // !__CPU_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/CPU097.h b/References/VirtuaNESex_src_191105/NES/CPU097.h new file mode 100644 index 00000000..2e6afdcd --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/CPU097.h @@ -0,0 +1,110 @@ +////////////////////////////////////////////////////////////////////////// +// // +// 6502 CPU core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __CPU_INCLUDED__ +#define __CPU_INCLUDED__ + +#include "typedef.h" +#include "macro.h" + +class NES; +class APU; +class Mapper; + +// 6502 status flags +#define C_FLAG 0x01 // 1: Carry +#define Z_FLAG 0x02 // 1: Zero +#define I_FLAG 0x04 // 1: Irq disabled +#define D_FLAG 0x08 // 1: Decimal mode flag (NES unused) +#define B_FLAG 0x10 // 1: Break +#define R_FLAG 0x20 // 1: Reserved (Always 1) +#define V_FLAG 0x40 // 1: Overflow +#define N_FLAG 0x80 // 1: Negative + +// Interrupt +#define NMI_FLAG 0x01 +#define IRQ_FLAG 0x02 + +#define IRQ_FRAMEIRQ 0x04 +#define IRQ_DPCM 0x08 +#define IRQ_MAPPER 0x10 +#define IRQ_MAPPER2 0x20 +#define IRQ_TRIGGER 0x40 // one shot(IRQ()) +#define IRQ_TRIGGER2 0x80 // one shot(IRQ_NotPending()) + +#define IRQ_MASK (~(NMI_FLAG|IRQ_FLAG)) + +// Vector +#define NMI_VECTOR 0xFFFA +#define RES_VECTOR 0xFFFC +#define IRQ_VECTOR 0xFFFE + +// 6502 context +typedef struct { + WORD PC; /* Program counter */ + BYTE A; /* CPU registers */ + BYTE P; + BYTE X; + BYTE Y; + BYTE S; + + BYTE INT_pending; // 荞݃yfBOtO +} R6502; + + +class CPU +{ +public: + CPU( NES* parent ); + virtual ~CPU(); + + BYTE RD6502( WORD addr ); + void WR6502( WORD addr, BYTE data ); + WORD RD6502W( WORD addr ); + + void Reset(); + + void NMI(); + void SetIRQ( BYTE mask ); + void ClrIRQ( BYTE mask ); + + void DMA( INT cycles ); + + INT EXEC( INT request_cycles ); + + INT GetDmaCycles(); + void SetDmaCycles( INT cycles ); + + INT GetTotalCycles(); + void SetTotalCycles( INT cycles ); + + void SetContext( R6502 r ) { R = r; } + void GetContext( R6502& r ) { r = R; } + + void SetClockProcess( BOOL bEnable ) { m_bClockProcess = bEnable; } +protected: + NES* nes; + APU* apu; + Mapper* mapper; + + R6502 R; + + INT TOTAL_cycles; // CPUg[^TCN + INT DMA_cycles; // DMATCN + + // PTR + LPBYTE STACK; + + // Zero & Negative table + BYTE ZN_Table[256]; + + // Clock process + BOOL m_bClockProcess; +private: +}; + +#endif // !__CPU_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/Cheat.h b/References/VirtuaNESex_src_191105/NES/Cheat.h new file mode 100644 index 00000000..3c3ef20f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Cheat.h @@ -0,0 +1,44 @@ +#ifndef __CEHAT_INCLUDED__ +#define __CEHAT_INCLUDED__ + +#include "typedef.h" + +#include +using namespace std; + +// ȉ̂Q‚OR}XN +#define CHEAT_ENABLE (1<<0) +#define CHEAT_KEYDISABLE (1<<1) + +// ݎ +#define CHEAT_TYPE_ALWAYS 0 // ɏ +#define CHEAT_TYPE_ONCE 1 // P񂾂 +#define CHEAT_TYPE_GREATER 2 // f[^傫 +#define CHEAT_TYPE_LESS 3 // f[^菬 + +// f[^ +#define CHEAT_LENGTH_1BYTE 0 +#define CHEAT_LENGTH_2BYTE 1 +#define CHEAT_LENGTH_3BYTE 2 +#define CHEAT_LENGTH_4BYTE 3 + +class CHEATCODE { +public: + BYTE enable; + BYTE type; + BYTE length; + WORD address; + DWORD data; + + string comment; +}; + +class GENIECODE { +public: + WORD address; + BYTE data; + BYTE cmp; +}; + +#endif // !__CEHAT_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/Cpu.cpp b/References/VirtuaNESex_src_191105/NES/Cpu.cpp new file mode 100644 index 00000000..9ce9bdcf --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Cpu.cpp @@ -0,0 +1,2056 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* 6502 CPU Core v0.00 */ +/* Norix */ +/* written 2000/12/23 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +/*--------------[ INCLUDE ]-------------------------------*/ +#define WIN32_LEAN_AND_MEAN +#include + +#include "VirtuaNESres.h" + +#include "typedef.h" +#include "macro.h" + +#include "DebugOut.h" +#include "App.h" +#include "Config.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "rom.h" +#include "mapper.h" + +/*--------------[ DEFINE ]-------------------------------*/ +#define DPCM_SYNCCLOCK FALSE +/*--------------[ EXTERNAL PROGRAM ]-------------------------------*/ +/*--------------[ EXTERNAL WORK ]-------------------------------*/ +/*--------------[ WORK ]-------------------------------*/ +/*--------------[ CONST ]-------------------------------*/ +/*--------------[ PROTOTYPE ]-------------------------------*/ +/*--------------[ PROGRAM ]-------------------------------*/ +// IyR[h +//#define OP6502(A) RD6502((A)) +//#define OP6502W(A) RD6502W((A)) + +// [y[W[h +#define ZPRD(A) (RAM[(BYTE)(A)]) +//#define ZPRDW(A) (*((LPWORD)&RAM[(BYTE)(A)])) +#define ZPRDW(A) ((WORD)RAM[(BYTE)(A)]+((WORD)RAM[(BYTE)((A)+1)]<<8)) + +#define ZPWR(A,V) { RAM[(BYTE)(A)]=(V); } +#define ZPWRW(A,V) { *((LPWORD)&RAM[(BYTE)(A)])=(WORD)(V); } + +// TCNJE^ +#define ADD_CYCLE(V) { exec_cycles += (V); } +//#define ADD_CYCLE(V) {} + +// EFFECTIVE ADDRESSy[WE`FbN +#define CHECK_EA() { if( (ET&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); } +//#define CHECK_EA() { if( (R.PC&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); } +//#define CHECK_EA() {} + +// tO +// [^lKeButÕ`FbNƐݒ +#define SET_ZN_FLAG(A) { R.P &= ~(Z_FLAG|N_FLAG); R.P |= ZN_Table[(BYTE)(A)]; } + +// tOZbg +#define SET_FLAG(V) { R.P |= (V); } +// tONA +#define CLR_FLAG(V) { R.P &= ~(V); } +// tOeXgZbg^NA +#define TST_FLAG(F,V) { R.P &= ~(V); if((F)) R.P |= (V); } +// tO`FbN +#define CHK_FLAG(V) (R.P&(V)) + +// WT .... WORD TEMP +// EA .... EFFECTIVE ADDRESS +// ET .... EFFECTIVE ADDRESS TEMP +// DT .... DATA + +#define MR_IM() { \ + DT = OP6502( R.PC++ ); \ +} +#define MR_ZP() { \ + EA = OP6502( R.PC++ ); \ + DT = ZPRD( EA ); \ +} +#define MR_ZX() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.X); \ + DT = ZPRD( EA ); \ +} +#define MR_ZY() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.Y); \ + DT = ZPRD( EA ); \ +} +#define MR_AB() { \ + EA = OP6502W( R.PC ); \ + R.PC += 2; \ + DT = RD6502( EA ); \ +} +#define MR_AX() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.X; \ + DT = RD6502( EA ); \ +} +#define MR_AY() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.Y; \ + DT = RD6502( EA ); \ +} +#define MR_IX() { \ + DT = OP6502( R.PC++ ); \ + EA = ZPRDW( DT + R.X ); \ + DT = RD6502( EA ); \ +} +#define MR_IY() { \ + DT = OP6502( R.PC++ ); \ + ET = ZPRDW( DT ); \ + EA = ET + R.Y; \ + DT = RD6502( EA ); \ +} + +// EFFECTIVE ADDRESS +#define EA_ZP() { \ + EA = OP6502( R.PC++ ); \ +} +#define EA_ZX() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.X); \ +} +#define EA_ZY() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.Y); \ +} +#define EA_AB() { \ + EA = OP6502W( R.PC ); \ + R.PC += 2; \ +} +#define EA_AX() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.X; \ +} +#define EA_AY() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.Y; \ +} +#define EA_IX() { \ + DT = OP6502( R.PC++ ); \ + EA = ZPRDW( DT + R.X ); \ +} +#define EA_IY() { \ + DT = OP6502( R.PC++ ); \ + ET = ZPRDW( DT ); \ + EA = ET + (WORD)R.Y; \ +} + +// Cg +#define MW_ZP() ZPWR(EA,DT) +#define MW_EA() WR6502(EA,DT) + +// STACK +#define PUSH(V) { STACK[(R.S--)&0xFF]=(V); } +#define POP() STACK[(++R.S)&0xFF] + +// ZpZn +/* ADC (NV----ZC) */ +#define ADC() { \ + WT = R.A+DT+(R.P&C_FLAG); \ + TST_FLAG( WT > 0xFF, C_FLAG ); \ + TST_FLAG( ((~(R.A^DT))&(R.A^WT)&0x80), V_FLAG ); \ + R.A = (BYTE)WT; \ + SET_ZN_FLAG(R.A); \ +} + +/* SBC (NV----ZC) */ +#define SBC() { \ + WT = R.A-DT-(~R.P&C_FLAG); \ + TST_FLAG( ((R.A^DT) & (R.A^WT)&0x80), V_FLAG ); \ + TST_FLAG( WT < 0x100, C_FLAG ); \ + R.A = (BYTE)WT; \ + SET_ZN_FLAG(R.A); \ +} + +/* INC (N-----Z-) */ +#define INC() { \ + DT++; \ + SET_ZN_FLAG(DT); \ +} +/* INX (N-----Z-) */ +#define INX() { \ + R.X++; \ + SET_ZN_FLAG(R.X); \ +} +/* INY (N-----Z-) */ +#define INY() { \ + R.Y++; \ + SET_ZN_FLAG(R.Y); \ +} + +/* DEC (N-----Z-) */ +#define DEC() { \ + DT--; \ + SET_ZN_FLAG(DT); \ +} +/* DEX (N-----Z-) */ +#define DEX() { \ + R.X--; \ + SET_ZN_FLAG(R.X); \ +} +/* DEY (N-----Z-) */ +#define DEY() { \ + R.Y--; \ + SET_ZN_FLAG(R.Y); \ +} + +// _Zn +/* AND (N-----Z-) */ +#define AND() { \ + R.A &= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* ORA (N-----Z-) */ +#define ORA() { \ + R.A |= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* EOR (N-----Z-) */ +#define EOR() { \ + R.A ^= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* ASL_A (N-----ZC) */ +#define ASL_A() { \ + TST_FLAG( R.A&0x80, C_FLAG ); \ + R.A <<= 1; \ + SET_ZN_FLAG(R.A); \ +} + +/* ASL (N-----ZC) */ +#define ASL() { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + SET_ZN_FLAG(DT); \ +} + +/* LSR_A (N-----ZC) */ +#define LSR_A() { \ + TST_FLAG( R.A&0x01, C_FLAG ); \ + R.A >>= 1; \ + SET_ZN_FLAG(R.A); \ +} +/* LSR (N-----ZC) */ +#define LSR() { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + SET_ZN_FLAG(DT); \ +} + +/* ROL_A (N-----ZC) */ +#define ROL_A() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(R.A&0x80,C_FLAG); \ + R.A = (R.A<<1)|0x01; \ + } else { \ + TST_FLAG(R.A&0x80,C_FLAG); \ + R.A <<= 1; \ + } \ + SET_ZN_FLAG(R.A); \ +} +/* ROL (N-----ZC) */ +#define ROL() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(DT&0x80,C_FLAG); \ + DT = (DT<<1)|0x01; \ + } else { \ + TST_FLAG(DT&0x80,C_FLAG); \ + DT <<= 1; \ + } \ + SET_ZN_FLAG(DT); \ +} + +/* ROR_A (N-----ZC) */ +#define ROR_A() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(R.A&0x01,C_FLAG); \ + R.A = (R.A>>1)|0x80; \ + } else { \ + TST_FLAG(R.A&0x01,C_FLAG); \ + R.A >>= 1; \ + } \ + SET_ZN_FLAG(R.A); \ +} +/* ROR (N-----ZC) */ +#define ROR() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(DT&0x01,C_FLAG); \ + DT = (DT>>1)|0x80; \ + } else { \ + TST_FLAG(DT&0x01,C_FLAG); \ + DT >>= 1; \ + } \ + SET_ZN_FLAG(DT); \ +} + +/* BIT (NV----Z-) */ +#define BIT() { \ + TST_FLAG( (DT&R.A)==0, Z_FLAG ); \ + TST_FLAG( DT&0x80, N_FLAG ); \ + TST_FLAG( DT&0x40, V_FLAG ); \ +} + +// [h^XgAn +/* LDA (N-----Z-) */ +#define LDA() { R.A = DT; SET_ZN_FLAG(R.A); } +/* LDX (N-----Z-) */ +#define LDX() { R.X = DT; SET_ZN_FLAG(R.X); } +/* LDY (N-----Z-) */ +#define LDY() { R.Y = DT; SET_ZN_FLAG(R.Y); } + +/* STA (--------) */ +#define STA() { DT = R.A; } +/* STX (--------) */ +#define STX() { DT = R.X; } +/* STY (--------) */ +#define STY() { DT = R.Y; } + +/* TAX (N-----Z-) */ +#define TAX() { R.X = R.A; SET_ZN_FLAG(R.X); } +/* TXA (N-----Z-) */ +#define TXA() { R.A = R.X; SET_ZN_FLAG(R.A); } +/* TAY (N-----Z-) */ +#define TAY() { R.Y = R.A; SET_ZN_FLAG(R.Y); } +/* TYA (N-----Z-) */ +#define TYA() { R.A = R.Y; SET_ZN_FLAG(R.A); } +/* TSX (N-----Z-) */ +#define TSX() { R.X = R.S; SET_ZN_FLAG(R.X); } +/* TXS (--------) */ +#define TXS() { R.S = R.X; } + +// rn +/* CMP (N-----ZC) */ +#define CMP_() { \ + WT = (WORD)R.A - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} +/* CPX (N-----ZC) */ +#define CPX() { \ + WT = (WORD)R.X - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} +/* CPY (N-----ZC) */ +#define CPY() { \ + WT = (WORD)R.Y - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} + +// Wv^^[n +#if 1 +#define JMP_ID() { \ + WT = OP6502W(R.PC); \ + EA = RD6502(WT); \ + WT = (WT&0xFF00)|((WT+1)&0x00FF); \ + R.PC = EA+RD6502(WT)*0x100; \ +} +#else +#define JMP_ID() { \ + ET = OP6502W(R.PC); \ + EA = RD6502W(ET); \ + R.PC = EA; \ +} +#endif +#define JMP() { \ + R.PC = OP6502W( R.PC ); \ +} +#define JSR() { \ + EA = OP6502W( R.PC ); \ + R.PC++; \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + R.PC = EA; \ +} +#define RTS() { \ + R.PC = POP(); \ + R.PC |= POP()*0x0100; \ + R.PC++; \ +} +#define RTI() { \ + R.P = POP() | R_FLAG; \ + R.PC = POP(); \ + R.PC |= POP()*0x0100; \ +} +// DEBUGOUT("_NMI-str!!!!!!!!!!\n"); +// DEBUGOUT("_NMI-end!!!!!!!!!!\n"); +#define _NMI() { \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + CLR_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(NMI_VECTOR); \ + exec_cycles += 7; \ +} +// DEBUGOUT("_IRQ-str!!!!!!!!!!\n"); +// DEBUGOUT("_IRQ-end!!!!!!!!!!\n"); +#define _IRQ() { \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + CLR_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(IRQ_VECTOR); \ + exec_cycles += 7; \ +} +// DEBUGOUT("_BRK-str!!!!!!!!!!\n"); +// DEBUGOUT("_BRK-end!!!!!!!!!!\n"); +#define BRK() { \ + R.PC++; \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + SET_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(IRQ_VECTOR); \ +} + +#if 1 +#define REL_JUMP() { \ + ET = R.PC; \ + EA = R.PC + (SBYTE)DT; \ + R.PC = EA; \ + ADD_CYCLE(1); \ + CHECK_EA(); \ +} +#else +#define REL_JUMP() { \ + R.PC = R.PC + (SBYTE)DT; \ + ADD_CYCLE(1); \ +} +#endif + +#define BCC() { if( !(R.P & C_FLAG) ) REL_JUMP(); } +#define BCS() { if( (R.P & C_FLAG) ) REL_JUMP(); } +#define BNE() { if( !(R.P & Z_FLAG) ) REL_JUMP(); } +#define BEQ() { if( (R.P & Z_FLAG) ) REL_JUMP(); } +#define BPL() { if( !(R.P & N_FLAG) ) REL_JUMP(); } +#define BMI() { if( (R.P & N_FLAG) ) REL_JUMP(); } +#define BVC() { if( !(R.P & V_FLAG) ) REL_JUMP(); } +#define BVS() { if( (R.P & V_FLAG) ) REL_JUMP(); } + +// tOn +#define CLC() { R.P &= ~C_FLAG; } +#define CLD() { R.P &= ~D_FLAG; } +#define CLI() { R.P &= ~I_FLAG; } +#define CLV() { R.P &= ~V_FLAG; } +#define SEC() { R.P |= C_FLAG; } +#define SED() { R.P |= D_FLAG; } +#define SEI() { R.P |= I_FLAG; } + +// Unofficial +#define ANC() { \ + R.A &= DT; \ + SET_ZN_FLAG( R.A ); \ + TST_FLAG( R.P&N_FLAG, C_FLAG ); \ +} + +#define ANE() { \ + R.A = (R.A|0xEE)&R.X&DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define ARR() { \ + DT &= R.A; \ + R.A = (DT>>1)|((R.P&C_FLAG)<<7); \ + SET_ZN_FLAG( R.A ); \ + TST_FLAG( R.A&0x40, C_FLAG ); \ + TST_FLAG( (R.A>>6)^(R.A>>5), V_FLAG ); \ +} + +#define ASR() { \ + DT &= R.A; \ + TST_FLAG( DT&0x01, C_FLAG ); \ + R.A = DT>>1; \ + SET_ZN_FLAG( R.A ); \ +} + +#define DCP() { \ + DT--; \ + CMP_(); \ +} + +#define DOP() { \ + R.PC++; \ +} + +#define ISB() { \ + DT++; \ + SBC(); \ +} + +#define LAS() { \ + R.A = R.X = R.S = (R.S & DT); \ + SET_ZN_FLAG( R.A ); \ +} + +#define LAX() { \ + R.A = DT; \ + R.X = R.A; \ + SET_ZN_FLAG( R.A ); \ +} + +#define LXA() { \ + R.A = R.X = ((R.A|0xEE)&DT); \ + SET_ZN_FLAG( R.A ); \ +} + +#define RLA() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT = (DT<<1)|1; \ + } else { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + } \ + R.A &= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define RRA() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT = (DT>>1)|0x80; \ + } else { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + } \ + ADC(); \ +} + +#define SAX() { \ + DT = R.A & R.X; \ +} + +#define SBX() { \ + WT = (R.A&R.X)-DT; \ + TST_FLAG( WT < 0x100, C_FLAG ); \ + R.X = WT&0xFF; \ + SET_ZN_FLAG( R.X ); \ +} + +#define SHA() { \ + DT = R.A & R.X & (BYTE)((EA>>8)+1); \ +} + +#define SHS() { \ + R.S = R.A & R.X; \ + DT = R.S & (BYTE)((EA>>8)+1); \ +} + +#define SHX() { \ + DT = R.X & (BYTE)((EA>>8)+1); \ +} + +#define SHY() { \ + DT = R.Y & (BYTE)((EA>>8)+1); \ +} + +#define SLO() { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + R.A |= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define SRE() { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + R.A ^= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define TOP() { \ + R.PC += 2; \ +} + +// +// RXgN^/fXgN^ +// +//CPU::CPU( NES* parent ) +CPU::CPU( NES* parent ) : nes(parent) +{ +// nes = parent; + m_bClockProcess = FALSE; +} + +CPU::~CPU() +{ +} + +// ANZX +//#define OP6502(A) (CPU_MEM_BANK[(A)>>13][(A)&0x1FFF]) +//#define OP6502W(A) (*((WORD*)&CPU_MEM_BANK[(A)>>13][(A)&0x1FFF])) + +Mapper* g_mapper=NULL; + +//#if 0 +#define OP6502(A) RD6502((A)) +#define OP6502W(A) RD6502W((A)) +//#else +//inline BYTE OP6502( WORD addr ) +//{ + //#ifdef EMU_DUMP + //return g_mapper->Read( addr ); + //#else + //return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + //#endif +//} + +//inline WORD OP6502W( WORD addr ) +//{ +//#if 0 +// WORD ret; +// ret = (WORD)CPU_MEM_BANK[(addr+0)>>13][(addr+0)&0x1FFF]; +// ret |= (WORD)CPU_MEM_BANK[(addr+1)>>13][(addr+1)&0x1FFF]<<8; +// return ret; +//#else +// +// #ifdef EMU_DUMP +// WORD w1 = g_mapper->Read( addr ); +// WORD w2 = g_mapper->Read( addr+1 ); +// return w1|(w2<<8); +// #else +// return *((WORD*)&CPU_MEM_BANK[addr>>13][addr&0x1FFF]); +// #endif +//#endif +//} +//#endif + +inline BYTE CPU::RD6502( WORD addr ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + return RAM[addr&0x07FF]; + } else if( addr < 0x8000 ) { + // Others + return nes->Read( addr ); + } else { + BYTE data; + if (mapper->ReadHigh(addr, &data)) + return data; + return mapper->Read( addr ); + } +} + +inline WORD CPU::RD6502W( WORD addr ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + return *((WORD*)&RAM[addr&0x07FF]); + } else //if( addr < 0x8000 ) + { + // Others + return (WORD)nes->Read(addr)+(WORD)nes->Read(addr+1)*0x100; + } + //return (WORD)nes->Read(addr)+(WORD)nes->Read(addr+1)*0x100; + + // Quick bank read +//#if 0 +// WORD ret; +// ret = (WORD)CPU_MEM_BANK[(addr+0)>>13][(addr+0)&0x1FFF]; +// ret |= (WORD)CPU_MEM_BANK[(addr+1)>>13][(addr+1)&0x1FFF]<<8; +// return ret; +//#else +// return *((WORD*)&CPU_MEM_BANK[addr>>13][addr&0x1FFF]); +//#endif +} + +// Cg +inline void CPU::WR6502( WORD addr, BYTE data ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + RAM[addr&0x07FF] = data; + } else { + // Others + nes->Write( addr, data ); + } +} + +// +// Zbg +// +void CPU::Reset() +{ + apu = nes->apu; + mapper = nes->mapper; + g_mapper = mapper; + + + R.A = 0x00; + R.X = 0x00; + R.Y = 0x00; + R.S = 0xFF; + R.P = Z_FLAG|R_FLAG; + R.PC = RD6502W(RES_VECTOR); + + R.INT_pending = 0; + + TOTAL_cycles = 0; + DMA_cycles = 0; + + // STACK quick access + STACK = &RAM[0x0100]; + + // Zero/Negative FLAG + ZN_Table[0] = Z_FLAG; + for( INT i = 1; i < 256; i++ ) + ZN_Table[i] = (i & 0x80)?N_FLAG:0; +} + +INT CPU::GetDmaCycles() +{ + return DMA_cycles; +} + +void CPU::SetDmaCycles( INT cycles ) +{ + DMA_cycles = cycles; +} + +INT CPU::GetTotalCycles() +{ + return TOTAL_cycles; +} + +void CPU::SetTotalCycles( INT cycles ) +{ + TOTAL_cycles = cycles; +} + +// +// DMAyfBOTCNݒ +// +void CPU::DMA( INT cycles ) +{ + DMA_cycles += cycles; +} + +static int nmicount; + +// +// 荞 +// +void CPU::NMI() +{ + R.INT_pending |= NMI_FLAG; + nmicount = 0; +} + +void CPU::SetIRQ( BYTE mask ) +{ + R.INT_pending |= mask; +} + +void CPU::ClrIRQ( BYTE mask ) +{ + R.INT_pending &= ~mask; +} + +enum ADDRMODE { IMP, ACC, IMM, ADR, ABS, IND, REL, ABX, ABY, ZPG, ZPX, ZPY, INX, INY, ERR, NUM_ADDR_MODES }; + +enum ADDRMODE TraceAddrMode[256] = +{ + IMM, INX, ERR, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, ACC, IMM, ABS, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPX, ZPX, IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + ADR, INX, ERR, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, ACC, IMM, ABS, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPX, ZPX, IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMP, INX, ERR, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, ACC, IMM, ADR, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPX, ZPX, IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMP, INX, ERR, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, ACC, IMM, IND, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPX, ZPX, IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMM, INX, IMM, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPY, ZPY, IMP, ABY, IMP, ABY, ABX, ABX, ABY, ABY, + IMM, INX, IMM, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPY, ZPY, IMP, ABY, IMP, ABY, ABX, ABX, ABY, ABY, + IMM, INX, IMM, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPX, ZPX, IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMM, INX, IMM, INX, ZPG, ZPG, ZPG, ZPG, IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, REL, INY, ERR, INY, ZPX, ZPX, ZPX, ZPX, IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX +}; + +char TraceArr[256][5] = +{ + " BRK", " ORA", "*HLT", "*SLO", "*NOP", " ORA", " ASL", "*SLO", " PHP", " ORA", " ASL", "*AAC", "*NOP", " ORA", " ASL", "*SLO", + " BPL", " ORA", "*HLT", "*SLO", "*NOP", " ORA", " ASL", "*SLO", " CLC", " ORA", "*NOP", "*SLO", "*NOP", " ORA", " ASL", "*SLO", + " JSR", " AND", "*HLT", "*RLA", " BIT", " AND", " ROL", "*RLA", " PLP", " AND", " ROL", "*AAC", " BIT", " AND", " ROL", "*RLA", + " BMI", " AND", "*HLT", "*RLA", "*NOP", " AND", " ROL", "*RLA", " SEC", " AND", "*NOP", "*RLA", "*NOP", " AND", " ROL", "*RLA", + " RTI", " EOR", "*HLT", "*SRE", "*NOP", " EOR", " LSR", "*SRE", " PHA", " EOR", " LSR", "*ASR", " JMP", " EOR", " LSR", "*SRE", + " BVC", " EOR", "*HLT", "*SRE", "*NOP", " EOR", " LSR", "*SRE", " CLI", " EOR", "*NOP", "*SRE", "*NOP", " EOR", " LSR", "*SRE", + " RTS", " ADC", "*HLT", "*RRA", "*NOP", " ADC", " ROR", "*RRA", " PLA", " ADC", " ROR", "*ARR", " JMP", " ADC", " ROR", "*RRA", + " BVS", " ADC", "*HLT", "*RRA", "*NOP", " ADC", " ROR", "*RRA", " SEI", " ADC", "*NOP", "*RRA", "*NOP", " ADC", " ROR", "*RRA", + "*NOP", " STA", "*NOP", "*SAX", " STY", " STA", " STX", "*SAX", " DEY", "*NOP", " TXA", " ???", " STY", " STA", " STX", "*SAX", + " BCC", " STA", "*HLT", " ???", " STY", " STA", " STX", "*SAX", " TYA", " STA", " TXS", " ???", " ???", " STA", " ???", " ???", + " LDY", " LDA", " LDX", "*LAX", " LDY", " LDA", " LDX", "*LAX", " TAY", " LDA", " TAX", "*ATX", " LDY", " LDA", " LDX", "*LAX", + " BCS", " LDA", "*HLT", "*LAX", " LDY", " LDA", " LDX", "*LAX", " CLV", " LDA", " TSX", " ???", " LDY", " LDA", " LDX", "*LAX", + " CPY", " CMP", "*NOP", "*DCP", " CPY", " CMP", " DEC", "*DCP", " INY", " CMP", " DEX", "*AXS", " CPY", " CMP", " DEC", "*DCP", + " BNE", " CMP", "*HLT", "*DCP", "*NOP", " CMP", " DEC", "*DCP", " CLD", " CMP", "*NOP", "*DCP", "*NOP", " CMP", " DEC", "*DCP", + " CPX", " SBC", "*NOP", "*ISB", " CPX", " SBC", " INC", "*ISB", " INX", " SBC", " NOP", "*SBC", " CPX", " SBC", " INC", "*ISB", + " BEQ", " SBC", "*HLT", "*ISB", "*NOP", " SBC", " INC", "*ISB", " SED", " SBC", "*NOP", "*ISB", "*NOP", " SBC", " INC", "*ISB" +}; + +unsigned char CPU::DebugMemCPU (unsigned short Addr) +{ + return OP6502( Addr ); +} + +int CPU::DecodeInstruction (unsigned short Addr, char *str1) +{ + unsigned char OpData[3] = {0, 0, 0}; + unsigned short Operand = 0, MidAddr = 0; + int EffectiveAddr = -1; + //int EffectiveAddr = 0xffff; + int iInstructionLen = 1; + + OpData[0] = DebugMemCPU(Addr); + switch (TraceAddrMode[OpData[0]]) + { + case IND: + OpData[1] = DebugMemCPU(Addr+1); + OpData[2] = DebugMemCPU(Addr+2); + Operand = OpData[1] | (OpData[2] << 8); + EffectiveAddr = DebugMemCPU(Operand) | (DebugMemCPU(Operand+1) << 8); + iInstructionLen = 3; + break; + case ADR: + OpData[1] = DebugMemCPU(Addr+1); + OpData[2] = DebugMemCPU(Addr+2);Operand = OpData[1] | (OpData[2] << 8); + iInstructionLen = 3; + break; + case ABS: + OpData[1] = DebugMemCPU(Addr+1); + OpData[2] = DebugMemCPU(Addr+2);Operand = OpData[1] | (OpData[2] << 8); + iInstructionLen = 3; + EffectiveAddr = Operand; + break; + case ABX: + OpData[1] = DebugMemCPU(Addr+1); + OpData[2] = DebugMemCPU(Addr+2);Operand = OpData[1] | (OpData[2] << 8); + iInstructionLen = 3; + EffectiveAddr = Operand + R.X; + break; + case ABY: + OpData[1] = DebugMemCPU(Addr+1); + OpData[2] = DebugMemCPU(Addr+2);Operand = OpData[1] | (OpData[2] << 8); + iInstructionLen = 3; + EffectiveAddr = Operand + R.Y; + break; + case IMM: + OpData[1] = DebugMemCPU(Addr+1); + Operand = OpData[1]; + iInstructionLen = 2; + break; + case ZPG: + OpData[1] = DebugMemCPU(Addr+1); + Operand = OpData[1]; + EffectiveAddr = Operand; + iInstructionLen = 2; + break; + case ZPX: + OpData[1] = DebugMemCPU(Addr+1); + Operand = OpData[1]; + EffectiveAddr = (Operand + R.X) & 0xFF; + iInstructionLen = 2; + break; + case ZPY: + OpData[1] = DebugMemCPU(Addr+1); + Operand = OpData[1]; + EffectiveAddr = (Operand + R.Y) & 0xFF; + iInstructionLen = 2; + break; + case INX: + OpData[1] = DebugMemCPU(Addr+1); + Operand = OpData[1]; + MidAddr = (Operand + R.X) & 0xFF; + EffectiveAddr = DebugMemCPU(MidAddr) | (DebugMemCPU((MidAddr+1) & 0xFF) << 8); + iInstructionLen = 2; + break; + case INY: + OpData[1] = DebugMemCPU(Addr+1); + Operand = OpData[1]; + MidAddr = DebugMemCPU(Operand) | (DebugMemCPU((Operand+1) & 0xFF) << 8); + EffectiveAddr = MidAddr + R.Y; + iInstructionLen = 2; + break; + case IMP: + break; + case ACC: + break; + case ERR: + break; + case REL: + OpData[1] = DebugMemCPU(Addr+1); + Operand = Addr+2+(signed char)OpData[1]; + iInstructionLen = 2; + break; + } + // Use this for outputting to debug logfile + if (str1) + { + switch (TraceAddrMode[DebugMemCPU(Addr)]) + { + case IMP: + case ERR: sprintf(str1, "%04X %02X %s ", Addr, OpData[0], TraceArr[OpData[0]]); break; + case ACC: sprintf(str1, "%04X %02X %s A ", Addr, OpData[0], TraceArr[OpData[0]]); break; + case IMM: sprintf(str1, "%04X %02X %02X %s #$%02X ", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand); break; + case REL: sprintf(str1, "%04X %02X %02X %s $%04X ", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand); break; + case ZPG: sprintf(str1, "%04X %02X %02X %s $%02X = %02X ", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand, DebugMemCPU(Operand)); break; + case ZPX: sprintf(str1, "%04X %02X %02X %s $%02X,X @ %02X = %02X ", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand, EffectiveAddr, DebugMemCPU(EffectiveAddr)); break; + case ZPY: sprintf(str1, "%04X %02X %02X %s $%02X,Y @ %02X = %02X ", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand, EffectiveAddr, DebugMemCPU(EffectiveAddr)); break; + case INX: sprintf(str1, "%04X %02X %02X %s ($%02X,X) @ %02X = %04X = %02X", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand, MidAddr, EffectiveAddr, DebugMemCPU(EffectiveAddr)); break; + case INY: sprintf(str1, "%04X %02X %02X %s ($%02X),Y = %04X @ %04X = %02X", Addr, OpData[0], OpData[1], TraceArr[OpData[0]], Operand, MidAddr, EffectiveAddr, DebugMemCPU(EffectiveAddr)); break; + case ADR: sprintf(str1, "%04X %02X %02X %02X %s $%04X ", Addr, OpData[0], OpData[1], OpData[2], TraceArr[OpData[0]], Operand); break; + case ABS: sprintf(str1, "%04X %02X %02X %02X %s $%04X = %02X ", Addr, OpData[0], OpData[1], OpData[2], TraceArr[OpData[0]], Operand, DebugMemCPU(Operand)); break; + case IND: sprintf(str1, "%04X %02X %02X %02X %s ($%04X) = %04X ", Addr, OpData[0], OpData[1], OpData[2], TraceArr[OpData[0]], Operand, EffectiveAddr); break; + case ABX: sprintf(str1, "%04X %02X %02X %02X %s $%04X,X @ %04X = %02X ", Addr, OpData[0], OpData[1], OpData[2], TraceArr[OpData[0]], Operand, EffectiveAddr, DebugMemCPU(EffectiveAddr)); break; + case ABY: sprintf(str1, "%04X %02X %02X %02X %s $%04X,Y @ %04X = %02X ", Addr, OpData[0], OpData[1], OpData[2], TraceArr[OpData[0]], Operand, EffectiveAddr, DebugMemCPU(EffectiveAddr)); break; + default: strcpy(str1, " "); break; + } + } + + return iInstructionLen; +} + +// +// ߎs +// +INT CPU::EXEC( INT request_cycles ) +{ +BYTE opcode; // IyR[h +INT OLD_cycles = TOTAL_cycles; +INT exec_cycles; +BYTE nmi_request, irq_request; +BOOL bClockProcess = m_bClockProcess; + +// TEMP +register WORD EA; +register WORD ET; +register WORD WT; +register BYTE DT; + + while( request_cycles > 0 ) { + exec_cycles = 0; + + if( DMA_cycles ) { + if( request_cycles <= DMA_cycles ) { + DMA_cycles -= request_cycles; + TOTAL_cycles += request_cycles; + + // NbN + mapper->Clock( request_cycles ); +#if DPCM_SYNCCLOCK + apu->SyncDPCM( request_cycles ); +#endif + if( bClockProcess ) { + nes->Clock( request_cycles ); + } +// nes->Clock( request_cycles ); + goto _execute_exit; + } else { + exec_cycles += DMA_cycles; +// request_cycles -= DMA_cycles; + DMA_cycles = 0; + } + } + + nmi_request = irq_request = 0; + opcode = OP6502( R.PC++ ); + + if( R.INT_pending ) { + if( R.INT_pending & NMI_FLAG ) { + nmi_request = 0xFF; + R.INT_pending &= ~NMI_FLAG; + } else + if( R.INT_pending & IRQ_MASK ) { + R.INT_pending &= ~IRQ_TRIGGER2; + if( !(R.P & I_FLAG) && opcode != 0x40 ) { + irq_request = 0xFF; + R.INT_pending &= ~IRQ_TRIGGER; + } + } + } +/* + //ָԤԹ + + //opcode + BYTE iInstructionLen =1; + switch (TraceAddrMode[opcode]) + { + case IND: + case ADR: + case ABS: + case ABX: + case ABY: + iInstructionLen = 3; + break; + case IMM: + case ZPG: + case ZPX: + case ZPY: + case INX: + case INY: + iInstructionLen = 2; + break; + case IMP:case ACC:case ERR: break; + case REL:iInstructionLen = 2;break; + } + + if( ((TraceArr[opcode][0]=='*') || + (TraceArr[opcode][1]=='?'))&& + (!Config.emulator.bIllegalOp) ) + { + //ŻϢ + #ifdef _DEBUG + char str[111]; + DecodeInstruction (R.PC-1, str); + DEBUGOUT( "Bad Instruction:%s\n",str); + #endif + R.PC=(R.PC-1)+iInstructionLen; + ADD_CYCLE(iInstructionLen*2); + goto end_is; + } + // +*/ + switch( opcode ) { + case 0x69: // ADC #$?? + MR_IM(); ADC(); + ADD_CYCLE(2); + break; + case 0x65: // ADC $?? + MR_ZP(); ADC(); + ADD_CYCLE(3); + break; + case 0x75: // ADC $??,X + MR_ZX(); ADC(); + ADD_CYCLE(4); + break; + case 0x6D: // ADC $???? + MR_AB(); ADC(); + ADD_CYCLE(4); + break; + case 0x7D: // ADC $????,X + MR_AX(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x79: // ADC $????,Y + MR_AY(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x61: // ADC ($??,X) + MR_IX(); ADC(); + ADD_CYCLE(6); + break; + case 0x71: // ADC ($??),Y + MR_IY(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0xE9: // SBC #$?? + MR_IM(); SBC(); + ADD_CYCLE(2); + break; + case 0xE5: // SBC $?? + MR_ZP(); SBC(); + ADD_CYCLE(3); + break; + case 0xF5: // SBC $??,X + MR_ZX(); SBC(); + ADD_CYCLE(4); + break; + case 0xED: // SBC $???? + MR_AB(); SBC(); + ADD_CYCLE(4); + break; + case 0xFD: // SBC $????,X + MR_AX(); SBC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xF9: // SBC $????,Y + MR_AY(); SBC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xE1: // SBC ($??,X) + MR_IX(); SBC(); + ADD_CYCLE(6); + break; + case 0xF1: // SBC ($??),Y + MR_IY(); SBC(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xC6: // DEC $?? + MR_ZP(); DEC(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xD6: // DEC $??,X + MR_ZX(); DEC(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xCE: // DEC $???? + MR_AB(); DEC(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xDE: // DEC $????,X + MR_AX(); DEC(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xCA: // DEX + DEX(); + ADD_CYCLE(2); + break; + case 0x88: // DEY + DEY(); + ADD_CYCLE(2); + break; + + case 0xE6: // INC $?? + MR_ZP(); INC(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xF6: // INC $??,X + MR_ZX(); INC(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xEE: // INC $???? + MR_AB(); INC(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xFE: // INC $????,X + MR_AX(); INC(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xE8: // INX + INX(); + ADD_CYCLE(2); + break; + case 0xC8: // INY + INY(); + ADD_CYCLE(2); + break; + + case 0x29: // AND #$?? + MR_IM(); AND(); + ADD_CYCLE(2); + break; + case 0x25: // AND $?? + MR_ZP(); AND(); + ADD_CYCLE(3); + break; + case 0x35: // AND $??,X + MR_ZX(); AND(); + ADD_CYCLE(4); + break; + case 0x2D: // AND $???? + MR_AB(); AND(); + ADD_CYCLE(4); + break; + case 0x3D: // AND $????,X + MR_AX(); AND(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x39: // AND $????,Y + MR_AY(); AND(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x21: // AND ($??,X) + MR_IX(); AND(); + ADD_CYCLE(6); + break; + case 0x31: // AND ($??),Y + MR_IY(); AND(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x0A: // ASL A + ASL_A(); + ADD_CYCLE(2); + break; + case 0x06: // ASL $?? + MR_ZP(); ASL(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x16: // ASL $??,X + MR_ZX(); ASL(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x0E: // ASL $???? + MR_AB(); ASL(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x1E: // ASL $????,X + MR_AX(); ASL(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x24: // BIT $?? + MR_ZP(); BIT(); + ADD_CYCLE(3); + break; + case 0x2C: // BIT $???? + MR_AB(); BIT(); + ADD_CYCLE(4); + break; + + case 0x49: // EOR #$?? + MR_IM(); EOR(); + ADD_CYCLE(2); + break; + case 0x45: // EOR $?? + MR_ZP(); EOR(); + ADD_CYCLE(3); + break; + case 0x55: // EOR $??,X + MR_ZX(); EOR(); + ADD_CYCLE(4); + break; + case 0x4D: // EOR $???? + MR_AB(); EOR(); + ADD_CYCLE(4); + break; + case 0x5D: // EOR $????,X + MR_AX(); EOR(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x59: // EOR $????,Y + MR_AY(); EOR(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x41: // EOR ($??,X) + MR_IX(); EOR(); + ADD_CYCLE(6); + break; + case 0x51: // EOR ($??),Y + MR_IY(); EOR(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x4A: // LSR A + LSR_A(); + ADD_CYCLE(2); + break; + case 0x46: // LSR $?? + MR_ZP(); LSR(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x56: // LSR $??,X + MR_ZX(); LSR(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x4E: // LSR $???? + MR_AB(); LSR(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x5E: // LSR $????,X + MR_AX(); LSR(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x09: // ORA #$?? + MR_IM(); ORA(); + ADD_CYCLE(2); + break; + case 0x05: // ORA $?? + MR_ZP(); ORA(); + ADD_CYCLE(3); + break; + case 0x15: // ORA $??,X + MR_ZX(); ORA(); + ADD_CYCLE(4); + break; + case 0x0D: // ORA $???? + MR_AB(); ORA(); + ADD_CYCLE(4); + break; + case 0x1D: // ORA $????,X + MR_AX(); ORA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x19: // ORA $????,Y + MR_AY(); ORA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x01: // ORA ($??,X) + MR_IX(); ORA(); + ADD_CYCLE(6); + break; + case 0x11: // ORA ($??),Y + MR_IY(); ORA(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x2A: // ROL A + ROL_A(); + ADD_CYCLE(2); + break; + case 0x26: // ROL $?? + MR_ZP(); ROL(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x36: // ROL $??,X + MR_ZX(); ROL(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x2E: // ROL $???? + MR_AB(); ROL(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x3E: // ROL $????,X + MR_AX(); ROL(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x6A: // ROR A + ROR_A(); + ADD_CYCLE(2); + break; + case 0x66: // ROR $?? + MR_ZP(); ROR(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x76: // ROR $??,X + MR_ZX(); ROR(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x6E: // ROR $???? + MR_AB(); ROR(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x7E: // ROR $????,X + MR_AX(); ROR(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xA9: // LDA #$?? + MR_IM(); LDA(); + ADD_CYCLE(2); + break; + case 0xA5: // LDA $?? + MR_ZP(); LDA(); + ADD_CYCLE(3); + break; + case 0xB5: // LDA $??,X + MR_ZX(); LDA(); + ADD_CYCLE(4); + break; + case 0xAD: // LDA $???? + MR_AB(); LDA(); + ADD_CYCLE(4); + break; + case 0xBD: // LDA $????,X + MR_AX(); LDA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xB9: // LDA $????,Y + MR_AY(); LDA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xA1: // LDA ($??,X) + MR_IX(); LDA(); + ADD_CYCLE(6); + break; + case 0xB1: // LDA ($??),Y + MR_IY(); LDA(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xA2: // LDX #$?? + MR_IM(); LDX(); + ADD_CYCLE(2); + break; + case 0xA6: // LDX $?? + MR_ZP(); LDX(); + ADD_CYCLE(3); + break; + case 0xB6: // LDX $??,Y + MR_ZY(); LDX(); + ADD_CYCLE(4); + break; + case 0xAE: // LDX $???? + MR_AB(); LDX(); + ADD_CYCLE(4); + break; + case 0xBE: // LDX $????,Y + MR_AY(); LDX(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0xA0: // LDY #$?? + MR_IM(); LDY(); + ADD_CYCLE(2); + break; + case 0xA4: // LDY $?? + MR_ZP(); LDY(); + ADD_CYCLE(3); + break; + case 0xB4: // LDY $??,X + MR_ZX(); LDY(); + ADD_CYCLE(4); + break; + case 0xAC: // LDY $???? + MR_AB(); LDY(); + ADD_CYCLE(4); + break; + case 0xBC: // LDY $????,X + MR_AX(); LDY(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0x85: // STA $?? + EA_ZP(); STA(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x95: // STA $??,X + EA_ZX(); STA(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8D: // STA $???? + EA_AB(); STA(); MW_EA(); + ADD_CYCLE(4); + break; + case 0x9D: // STA $????,X + EA_AX(); STA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x99: // STA $????,Y + EA_AY(); STA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x81: // STA ($??,X) + EA_IX(); STA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x91: // STA ($??),Y + EA_IY(); STA(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0x86: // STX $?? + EA_ZP(); STX(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x96: // STX $??,Y + EA_ZY(); STX(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8E: // STX $???? + EA_AB(); STX(); MW_EA(); + ADD_CYCLE(4); + break; + + case 0x84: // STY $?? + EA_ZP(); STY(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x94: // STY $??,X + EA_ZX(); STY(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8C: // STY $???? + EA_AB(); STY(); MW_EA(); + ADD_CYCLE(4); + break; + + case 0xAA: // TAX + TAX(); + ADD_CYCLE(2); + break; + case 0x8A: // TXA + TXA(); + ADD_CYCLE(2); + break; + case 0xA8: // TAY + TAY(); + ADD_CYCLE(2); + break; + case 0x98: // TYA + TYA(); + ADD_CYCLE(2); + break; + case 0xBA: // TSX + TSX(); + ADD_CYCLE(2); + break; + case 0x9A: // TXS + TXS(); + ADD_CYCLE(2); + break; + + case 0xC9: // CMP #$?? + MR_IM(); CMP_(); + ADD_CYCLE(2); + break; + case 0xC5: // CMP $?? + MR_ZP(); CMP_(); + ADD_CYCLE(3); + break; + case 0xD5: // CMP $??,X + MR_ZX(); CMP_(); + ADD_CYCLE(4); + break; + case 0xCD: // CMP $???? + MR_AB(); CMP_(); + ADD_CYCLE(4); + break; + case 0xDD: // CMP $????,X + MR_AX(); CMP_(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xD9: // CMP $????,Y + MR_AY(); CMP_(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xC1: // CMP ($??,X) + MR_IX(); CMP_(); + ADD_CYCLE(6); + break; + case 0xD1: // CMP ($??),Y + MR_IY(); CMP_(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xE0: // CPX #$?? + MR_IM(); CPX(); + ADD_CYCLE(2); + break; + case 0xE4: // CPX $?? + MR_ZP(); CPX(); + ADD_CYCLE(3); + break; + case 0xEC: // CPX $???? + MR_AB(); CPX(); + ADD_CYCLE(4); + break; + + case 0xC0: // CPY #$?? + MR_IM(); CPY(); + ADD_CYCLE(2); + break; + case 0xC4: // CPY $?? + MR_ZP(); CPY(); + ADD_CYCLE(3); + break; + case 0xCC: // CPY $???? + MR_AB(); CPY(); + ADD_CYCLE(4); + break; + + case 0x90: // BCC + MR_IM(); BCC(); + ADD_CYCLE(2); + break; + case 0xB0: // BCS + MR_IM(); BCS(); + ADD_CYCLE(2); + break; + case 0xF0: // BEQ + MR_IM(); BEQ(); + ADD_CYCLE(2); + break; + case 0x30: // BMI + MR_IM(); BMI(); + ADD_CYCLE(2); + break; + case 0xD0: // BNE + MR_IM(); BNE(); + ADD_CYCLE(2); + break; + case 0x10: // BPL + MR_IM(); BPL(); + ADD_CYCLE(2); + break; + case 0x50: // BVC + MR_IM(); BVC(); + ADD_CYCLE(2); + break; + case 0x70: // BVS + MR_IM(); BVS(); + ADD_CYCLE(2); + break; + + case 0x4C: // JMP $???? + JMP(); + ADD_CYCLE(3); + break; + case 0x6C: // JMP ($????) + JMP_ID(); + ADD_CYCLE(5); + break; + + case 0x20: // JSR + JSR(); + ADD_CYCLE(6); + break; + + case 0x40: // RTI + RTI(); + ADD_CYCLE(6); + break; + case 0x60: // RTS + RTS(); + ADD_CYCLE(6); + break; + + // tOn + case 0x18: // CLC + CLC(); + ADD_CYCLE(2); + break; + case 0xD8: // CLD + CLD(); + ADD_CYCLE(2); + break; + case 0x58: // CLI + CLI(); + ADD_CYCLE(2); + break; + case 0xB8: // CLV + CLV(); + ADD_CYCLE(2); + break; + + case 0x38: // SEC + SEC(); + ADD_CYCLE(2); + break; + case 0xF8: // SED + SED(); + ADD_CYCLE(2); + break; + case 0x78: // SEI + SEI(); + ADD_CYCLE(2); + break; + + // X^bNn + case 0x48: // PHA + PUSH( R.A ); + ADD_CYCLE(3); + break; + case 0x08: // PHP + PUSH( R.P | B_FLAG ); + ADD_CYCLE(3); + break; + case 0x68: // PLA (N-----Z-) + R.A = POP(); + SET_ZN_FLAG(R.A); + ADD_CYCLE(4); + break; + case 0x28: // PLP + R.P = POP() | R_FLAG; + ADD_CYCLE(4); + break; + + // ̑ + case 0x00: // BRK + BRK(); + ADD_CYCLE(7); + break; + + case 0xEA: // NOP + ADD_CYCLE(2); + break; + + // JߌQ + case 0x0B: // ANC #$?? + case 0x2B: // ANC #$?? + MR_IM(); ANC(); + ADD_CYCLE(2); + break; + + case 0x8B: // ANE #$?? + MR_IM(); ANE(); + ADD_CYCLE(2); + break; + + case 0x6B: // ARR #$?? + MR_IM(); ARR(); + ADD_CYCLE(2); + break; + + case 0x4B: // ASR #$?? + MR_IM(); ASR(); + ADD_CYCLE(2); + break; + + case 0xC7: // DCP $?? + MR_ZP(); DCP(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xD7: // DCP $??,X + MR_ZX(); DCP(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xCF: // DCP $???? + MR_AB(); DCP(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xDF: // DCP $????,X + MR_AX(); DCP(); MW_EA(); + ADD_CYCLE(7); + break; + case 0xDB: // DCP $????,Y + MR_AY(); DCP(); MW_EA(); + ADD_CYCLE(7); + break; + case 0xC3: // DCP ($??,X) + MR_IX(); DCP(); MW_EA(); + ADD_CYCLE(8); + break; + case 0xD3: // DCP ($??),Y + MR_IY(); DCP(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0xE7: // ISB $?? + MR_ZP(); ISB(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xF7: // ISB $??,X + MR_ZX(); ISB(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xEF: // ISB $???? + MR_AB(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xFF: // ISB $????,X + MR_AX(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xFB: // ISB $????,Y + MR_AY(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xE3: // ISB ($??,X) + MR_IX(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xF3: // ISB ($??),Y + MR_IY(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0xBB: // LAS $????,Y + MR_AY(); LAS(); CHECK_EA(); + ADD_CYCLE(4); + break; + + + case 0xA7: // LAX $?? + MR_ZP(); LAX(); + ADD_CYCLE(3); + break; + case 0xB7: // LAX $??,Y + MR_ZY(); LAX(); + ADD_CYCLE(4); + break; + case 0xAF: // LAX $???? + MR_AB(); LAX(); + ADD_CYCLE(4); + break; + case 0xBF: // LAX $????,Y + MR_AY(); LAX(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xA3: // LAX ($??,X) + MR_IX(); LAX(); + ADD_CYCLE(6); + break; + case 0xB3: // LAX ($??),Y + MR_IY(); LAX(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xAB: // LXA #$?? + MR_IM(); LXA(); + ADD_CYCLE(2); + break; + + case 0x27: // RLA $?? + MR_ZP(); RLA(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x37: // RLA $??,X + MR_ZX(); RLA(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x2F: // RLA $???? + MR_AB(); RLA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x3F: // RLA $????,X + MR_AX(); RLA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x3B: // RLA $????,Y + MR_AY(); RLA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x23: // RLA ($??,X) + MR_IX(); RLA(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x33: // RLA ($??),Y + MR_IY(); RLA(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x67: // RRA $?? + MR_ZP(); RRA(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x77: // RRA $??,X + MR_ZX(); RRA(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x6F: // RRA $???? + MR_AB(); RRA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x7F: // RRA $????,X + MR_AX(); RRA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x7B: // RRA $????,Y + MR_AY(); RRA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x63: // RRA ($??,X) + MR_IX(); RRA(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x73: // RRA ($??),Y + MR_IY(); RRA(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x87: // SAX $?? + MR_ZP(); SAX(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x97: // SAX $??,Y + MR_ZY(); SAX(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8F: // SAX $???? + MR_AB(); SAX(); MW_EA(); + ADD_CYCLE(4); + break; + case 0x83: // SAX ($??,X) + MR_IX(); SAX(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0xCB: // SBX #$?? + MR_IM(); SBX(); + ADD_CYCLE(2); + break; + + case 0x9F: // SHA $????,Y + MR_AY(); SHA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x93: // SHA ($??),Y + MR_IY(); SHA(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0x9B: // SHS $????,Y + MR_AY(); SHS(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x9E: // SHX $????,Y + MR_AY(); SHX(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x9C: // SHY $????,X + MR_AX(); SHY(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x07: // SLO $?? + MR_ZP(); SLO(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x17: // SLO $??,X + MR_ZX(); SLO(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x0F: // SLO $???? + MR_AB(); SLO(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x1F: // SLO $????,X + MR_AX(); SLO(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x1B: // SLO $????,Y + MR_AY(); SLO(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x03: // SLO ($??,X) + MR_IX(); SLO(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x13: // SLO ($??),Y + MR_IY(); SLO(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x47: // SRE $?? + MR_ZP(); SRE(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x57: // SRE $??,X + MR_ZX(); SRE(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x4F: // SRE $???? + MR_AB(); SRE(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x5F: // SRE $????,X + MR_AX(); SRE(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x5B: // SRE $????,Y + MR_AY(); SRE(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x43: // SRE ($??,X) + MR_IX(); SRE(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x53: // SRE ($??),Y + MR_IY(); SRE(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0xEB: // SBC #$?? (Unofficial) + MR_IM(); SBC(); + ADD_CYCLE(2); + break; + + case 0x1A: // NOP (Unofficial) + case 0x3A: // NOP (Unofficial) + case 0x5A: // NOP (Unofficial) + case 0x7A: // NOP (Unofficial) + case 0xDA: // NOP (Unofficial) + case 0xFA: // NOP (Unofficial) + ADD_CYCLE(2); + break; + case 0x80: // DOP (CYCLES 2) + case 0x82: // DOP (CYCLES 2) + case 0x89: // DOP (CYCLES 2) + case 0xC2: // DOP (CYCLES 2) + case 0xE2: // DOP (CYCLES 2) + R.PC++; + ADD_CYCLE(2); + break; + case 0x04: // DOP (CYCLES 3) + case 0x44: // DOP (CYCLES 3) + case 0x64: // DOP (CYCLES 3) + R.PC++; + ADD_CYCLE(3); + break; + case 0x14: // DOP (CYCLES 4) + case 0x34: // DOP (CYCLES 4) + case 0x54: // DOP (CYCLES 4) + case 0x74: // DOP (CYCLES 4) + case 0xD4: // DOP (CYCLES 4) + case 0xF4: // DOP (CYCLES 4) + R.PC++; + ADD_CYCLE(4); + break; + case 0x0C: // TOP + case 0x1C: // TOP + case 0x3C: // TOP + case 0x5C: // TOP + case 0x7C: // TOP + case 0xDC: // TOP + case 0xFC: // TOP + R.PC+=2; + ADD_CYCLE(4); + break; + + case 0x02: /* JAM */ + case 0x12: /* JAM */ + case 0x22: /* JAM */ + case 0x32: /* JAM */ + case 0x42: /* JAM */ + case 0x52: /* JAM */ + case 0x62: /* JAM */ + case 0x72: /* JAM */ + case 0x92: /* JAM */ + case 0xB2: /* JAM */ + case 0xD2: /* JAM */ + case 0xF2: /* JAM */ + default: + if( !Config.emulator.bIllegalOp ) + { + throw CApp::GetErrorString( IDS_ERROR_ILLEGALOPCODE ); + goto _execute_exit; + } + else + { + R.PC--; + ADD_CYCLE(4); + } + break; +// default: +// __assume(0); + } + +// end_is: __asm nop; + + if( nmi_request ) { + _NMI(); + } else + if( irq_request ) { + _IRQ(); + } + + request_cycles -= exec_cycles; + TOTAL_cycles += exec_cycles; + + // NbN + mapper->Clock( exec_cycles ); +#if DPCM_SYNCCLOCK + apu->SyncDPCM( exec_cycles ); +#endif + if( bClockProcess ) { + nes->Clock( exec_cycles ); + } +// nes->Clock( exec_cycles ); + } +_execute_exit: + +#if !DPCM_SYNCCLOCK + apu->SyncDPCM( TOTAL_cycles - OLD_cycles ); +#endif + + return TOTAL_cycles - OLD_cycles; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Cpu097.cpp b/References/VirtuaNESex_src_191105/NES/Cpu097.cpp new file mode 100644 index 00000000..f9ce564b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Cpu097.cpp @@ -0,0 +1,1828 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* 6502 CPU Core v0.00 */ +/* Norix */ +/* written 2000/12/23 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +/*--------------[ INCLUDE ]-------------------------------*/ +#define WIN32_LEAN_AND_MEAN +#include + +#include "VirtuaNESres.h" + +#include "typedef.h" +#include "macro.h" + +#include "DebugOut.h" +#include "App.h" +#include "Config.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "rom.h" +#include "mapper.h" + +/*--------------[ DEFINE ]-------------------------------*/ +#define DPCM_SYNCCLOCK FALSE +/*--------------[ EXTERNAL PROGRAM ]-------------------------------*/ +/*--------------[ EXTERNAL WORK ]-------------------------------*/ +/*--------------[ WORK ]-------------------------------*/ +/*--------------[ CONST ]-------------------------------*/ +/*--------------[ PROTOTYPE ]-------------------------------*/ +/*--------------[ PROGRAM ]-------------------------------*/ +// IyR[h +//#define OP6502(A) RD6502((A)) +//#define OP6502W(A) RD6502W((A)) + +// [y[W[h +#define ZPRD(A) (RAM[(BYTE)(A)]) +//#define ZPRDW(A) (*((LPWORD)&RAM[(BYTE)(A)])) +#define ZPRDW(A) ((WORD)RAM[(BYTE)(A)]+((WORD)RAM[(BYTE)((A)+1)]<<8)) + +#define ZPWR(A,V) { RAM[(BYTE)(A)]=(V); } +#define ZPWRW(A,V) { *((LPWORD)&RAM[(BYTE)(A)])=(WORD)(V); } + +// TCNJE^ +#define ADD_CYCLE(V) { exec_cycles += (V); } +//#define ADD_CYCLE(V) {} + +// EFFECTIVE ADDRESSy[WE`FbN +#define CHECK_EA() { if( (ET&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); } +//#define CHECK_EA() { if( (R.PC&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); } +//#define CHECK_EA() {} + +// tO +// [^lKeButÕ`FbNƐݒ +#define SET_ZN_FLAG(A) { R.P &= ~(Z_FLAG|N_FLAG); R.P |= ZN_Table[(BYTE)(A)]; } + +// tOZbg +#define SET_FLAG(V) { R.P |= (V); } +// tONA +#define CLR_FLAG(V) { R.P &= ~(V); } +// tOeXgZbg^NA +#define TST_FLAG(F,V) { R.P &= ~(V); if((F)) R.P |= (V); } +// tO`FbN +#define CHK_FLAG(V) (R.P&(V)) + +// WT .... WORD TEMP +// EA .... EFFECTIVE ADDRESS +// ET .... EFFECTIVE ADDRESS TEMP +// DT .... DATA + +#define MR_IM() { \ + DT = OP6502( R.PC++ ); \ +} +#define MR_ZP() { \ + EA = OP6502( R.PC++ ); \ + DT = ZPRD( EA ); \ +} +#define MR_ZX() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.X); \ + DT = ZPRD( EA ); \ +} +#define MR_ZY() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.Y); \ + DT = ZPRD( EA ); \ +} +#define MR_AB() { \ + EA = OP6502W( R.PC ); \ + R.PC += 2; \ + DT = RD6502( EA ); \ +} +#define MR_AX() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.X; \ + DT = RD6502( EA ); \ +} +#define MR_AY() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.Y; \ + DT = RD6502( EA ); \ +} +#define MR_IX() { \ + DT = OP6502( R.PC++ ); \ + EA = ZPRDW( DT + R.X ); \ + DT = RD6502( EA ); \ +} +#define MR_IY() { \ + DT = OP6502( R.PC++ ); \ + ET = ZPRDW( DT ); \ + EA = ET + R.Y; \ + DT = RD6502( EA ); \ +} + +// EFFECTIVE ADDRESS +#define EA_ZP() { \ + EA = OP6502( R.PC++ ); \ +} +#define EA_ZX() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.X); \ +} +#define EA_ZY() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.Y); \ +} +#define EA_AB() { \ + EA = OP6502W( R.PC ); \ + R.PC += 2; \ +} +#define EA_AX() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.X; \ +} +#define EA_AY() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.Y; \ +} +#define EA_IX() { \ + DT = OP6502( R.PC++ ); \ + EA = ZPRDW( DT + R.X ); \ +} +#define EA_IY() { \ + DT = OP6502( R.PC++ ); \ + ET = ZPRDW( DT ); \ + EA = ET + (WORD)R.Y; \ +} + +// Cg +#define MW_ZP() ZPWR(EA,DT) +#define MW_EA() WR6502(EA,DT) + +// STACK +#define PUSH(V) { STACK[(R.S--)&0xFF]=(V); } +#define POP() STACK[(++R.S)&0xFF] + +// ZpZn +/* ADC (NV----ZC) */ +#define ADC() { \ + WT = R.A+DT+(R.P&C_FLAG); \ + TST_FLAG( WT > 0xFF, C_FLAG ); \ + TST_FLAG( ((~(R.A^DT))&(R.A^WT)&0x80), V_FLAG ); \ + R.A = (BYTE)WT; \ + SET_ZN_FLAG(R.A); \ +} + +/* SBC (NV----ZC) */ +#define SBC() { \ + WT = R.A-DT-(~R.P&C_FLAG); \ + TST_FLAG( ((R.A^DT) & (R.A^WT)&0x80), V_FLAG ); \ + TST_FLAG( WT < 0x100, C_FLAG ); \ + R.A = (BYTE)WT; \ + SET_ZN_FLAG(R.A); \ +} + +/* INC (N-----Z-) */ +#define INC() { \ + DT++; \ + SET_ZN_FLAG(DT); \ +} +/* INX (N-----Z-) */ +#define INX() { \ + R.X++; \ + SET_ZN_FLAG(R.X); \ +} +/* INY (N-----Z-) */ +#define INY() { \ + R.Y++; \ + SET_ZN_FLAG(R.Y); \ +} + +/* DEC (N-----Z-) */ +#define DEC() { \ + DT--; \ + SET_ZN_FLAG(DT); \ +} +/* DEX (N-----Z-) */ +#define DEX() { \ + R.X--; \ + SET_ZN_FLAG(R.X); \ +} +/* DEY (N-----Z-) */ +#define DEY() { \ + R.Y--; \ + SET_ZN_FLAG(R.Y); \ +} + +// _Zn +/* AND (N-----Z-) */ +#define AND() { \ + R.A &= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* ORA (N-----Z-) */ +#define ORA() { \ + R.A |= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* EOR (N-----Z-) */ +#define EOR() { \ + R.A ^= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* ASL_A (N-----ZC) */ +#define ASL_A() { \ + TST_FLAG( R.A&0x80, C_FLAG ); \ + R.A <<= 1; \ + SET_ZN_FLAG(R.A); \ +} + +/* ASL (N-----ZC) */ +#define ASL() { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + SET_ZN_FLAG(DT); \ +} + +/* LSR_A (N-----ZC) */ +#define LSR_A() { \ + TST_FLAG( R.A&0x01, C_FLAG ); \ + R.A >>= 1; \ + SET_ZN_FLAG(R.A); \ +} +/* LSR (N-----ZC) */ +#define LSR() { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + SET_ZN_FLAG(DT); \ +} + +/* ROL_A (N-----ZC) */ +#define ROL_A() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(R.A&0x80,C_FLAG); \ + R.A = (R.A<<1)|0x01; \ + } else { \ + TST_FLAG(R.A&0x80,C_FLAG); \ + R.A <<= 1; \ + } \ + SET_ZN_FLAG(R.A); \ +} +/* ROL (N-----ZC) */ +#define ROL() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(DT&0x80,C_FLAG); \ + DT = (DT<<1)|0x01; \ + } else { \ + TST_FLAG(DT&0x80,C_FLAG); \ + DT <<= 1; \ + } \ + SET_ZN_FLAG(DT); \ +} + +/* ROR_A (N-----ZC) */ +#define ROR_A() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(R.A&0x01,C_FLAG); \ + R.A = (R.A>>1)|0x80; \ + } else { \ + TST_FLAG(R.A&0x01,C_FLAG); \ + R.A >>= 1; \ + } \ + SET_ZN_FLAG(R.A); \ +} +/* ROR (N-----ZC) */ +#define ROR() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(DT&0x01,C_FLAG); \ + DT = (DT>>1)|0x80; \ + } else { \ + TST_FLAG(DT&0x01,C_FLAG); \ + DT >>= 1; \ + } \ + SET_ZN_FLAG(DT); \ +} + +/* BIT (NV----Z-) */ +#define BIT() { \ + TST_FLAG( (DT&R.A)==0, Z_FLAG ); \ + TST_FLAG( DT&0x80, N_FLAG ); \ + TST_FLAG( DT&0x40, V_FLAG ); \ +} + +// [h^XgAn +/* LDA (N-----Z-) */ +#define LDA() { R.A = DT; SET_ZN_FLAG(R.A); } +/* LDX (N-----Z-) */ +#define LDX() { R.X = DT; SET_ZN_FLAG(R.X); } +/* LDY (N-----Z-) */ +#define LDY() { R.Y = DT; SET_ZN_FLAG(R.Y); } + +/* STA (--------) */ +#define STA() { DT = R.A; } +/* STX (--------) */ +#define STX() { DT = R.X; } +/* STY (--------) */ +#define STY() { DT = R.Y; } + +/* TAX (N-----Z-) */ +#define TAX() { R.X = R.A; SET_ZN_FLAG(R.X); } +/* TXA (N-----Z-) */ +#define TXA() { R.A = R.X; SET_ZN_FLAG(R.A); } +/* TAY (N-----Z-) */ +#define TAY() { R.Y = R.A; SET_ZN_FLAG(R.Y); } +/* TYA (N-----Z-) */ +#define TYA() { R.A = R.Y; SET_ZN_FLAG(R.A); } +/* TSX (N-----Z-) */ +#define TSX() { R.X = R.S; SET_ZN_FLAG(R.X); } +/* TXS (--------) */ +#define TXS() { R.S = R.X; } + +// rn +/* CMP (N-----ZC) */ +#define CMP_() { \ + WT = (WORD)R.A - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} +/* CPX (N-----ZC) */ +#define CPX() { \ + WT = (WORD)R.X - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} +/* CPY (N-----ZC) */ +#define CPY() { \ + WT = (WORD)R.Y - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} + +// Wv^^[n +#if 1 +#define JMP_ID() { \ + WT = OP6502W(R.PC); \ + EA = RD6502(WT); \ + WT = (WT&0xFF00)|((WT+1)&0x00FF); \ + R.PC = EA+RD6502(WT)*0x100; \ +} +#else +#define JMP_ID() { \ + ET = OP6502W(R.PC); \ + EA = RD6502W(ET); \ + R.PC = EA; \ +} +#endif +#define JMP() { \ + R.PC = OP6502W( R.PC ); \ +} +#define JSR() { \ + EA = OP6502W( R.PC ); \ + R.PC++; \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + R.PC = EA; \ +} +#define RTS() { \ + R.PC = POP(); \ + R.PC |= POP()*0x0100; \ + R.PC++; \ +} +#define RTI() { \ + R.P = POP() | R_FLAG; \ + R.PC = POP(); \ + R.PC |= POP()*0x0100; \ +} +#define _NMI() { \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + CLR_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(NMI_VECTOR); \ + exec_cycles += 7; \ +} +#define _IRQ() { \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + CLR_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(IRQ_VECTOR); \ + exec_cycles += 7; \ +} +#define BRK() { \ + R.PC++; \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + SET_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(IRQ_VECTOR); \ +} + +#if 1 +#define REL_JUMP() { \ + ET = R.PC; \ + EA = R.PC + (SBYTE)DT; \ + R.PC = EA; \ + ADD_CYCLE(1); \ + CHECK_EA(); \ +} +#else +#define REL_JUMP() { \ + R.PC = R.PC + (SBYTE)DT; \ + ADD_CYCLE(1); \ +} +#endif + +#define BCC() { if( !(R.P & C_FLAG) ) REL_JUMP(); } +#define BCS() { if( (R.P & C_FLAG) ) REL_JUMP(); } +#define BNE() { if( !(R.P & Z_FLAG) ) REL_JUMP(); } +#define BEQ() { if( (R.P & Z_FLAG) ) REL_JUMP(); } +#define BPL() { if( !(R.P & N_FLAG) ) REL_JUMP(); } +#define BMI() { if( (R.P & N_FLAG) ) REL_JUMP(); } +#define BVC() { if( !(R.P & V_FLAG) ) REL_JUMP(); } +#define BVS() { if( (R.P & V_FLAG) ) REL_JUMP(); } + +// tOn +#define CLC() { R.P &= ~C_FLAG; } +#define CLD() { R.P &= ~D_FLAG; } +#define CLI() { R.P &= ~I_FLAG; } +#define CLV() { R.P &= ~V_FLAG; } +#define SEC() { R.P |= C_FLAG; } +#define SED() { R.P |= D_FLAG; } +#define SEI() { R.P |= I_FLAG; } + +// Unofficial +#define ANC() { \ + R.A &= DT; \ + SET_ZN_FLAG( R.A ); \ + TST_FLAG( R.P&N_FLAG, C_FLAG ); \ +} + +#define ANE() { \ + R.A = (R.A|0xEE)&R.X&DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define ARR() { \ + DT &= R.A; \ + R.A = (DT>>1)|((R.P&C_FLAG)<<7); \ + SET_ZN_FLAG( R.A ); \ + TST_FLAG( R.A&0x40, C_FLAG ); \ + TST_FLAG( (R.A>>6)^(R.A>>5), V_FLAG ); \ +} + +#define ASR() { \ + DT &= R.A; \ + TST_FLAG( DT&0x01, C_FLAG ); \ + R.A = DT>>1; \ + SET_ZN_FLAG( R.A ); \ +} + +#define DCP() { \ + DT--; \ + CMP_(); \ +} + +#define DOP() { \ + R.PC++; \ +} + +#define ISB() { \ + DT++; \ + SBC(); \ +} + +#define LAS() { \ + R.A = R.X = R.S = (R.S & DT); \ + SET_ZN_FLAG( R.A ); \ +} + +#define LAX() { \ + R.A = DT; \ + R.X = R.A; \ + SET_ZN_FLAG( R.A ); \ +} + +#define LXA() { \ + R.A = R.X = ((R.A|0xEE)&DT); \ + SET_ZN_FLAG( R.A ); \ +} + +#define RLA() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT = (DT<<1)|1; \ + } else { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + } \ + R.A &= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define RRA() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT = (DT>>1)|0x80; \ + } else { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + } \ + ADC(); \ +} + +#define SAX() { \ + DT = R.A & R.X; \ +} + +#define SBX() { \ + WT = (R.A&R.X)-DT; \ + TST_FLAG( WT < 0x100, C_FLAG ); \ + R.X = WT&0xFF; \ + SET_ZN_FLAG( R.X ); \ +} + +#define SHA() { \ + DT = R.A & R.X & (BYTE)((EA>>8)+1); \ +} + +#define SHS() { \ + R.S = R.A & R.X; \ + DT = R.S & (BYTE)((EA>>8)+1); \ +} + +#define SHX() { \ + DT = R.X & (BYTE)((EA>>8)+1); \ +} + +#define SHY() { \ + DT = R.Y & (BYTE)((EA>>8)+1); \ +} + +#define SLO() { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + R.A |= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define SRE() { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + R.A ^= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define TOP() { \ + R.PC += 2; \ +} + +// +// RXgN^/fXgN^ +// +//CPU::CPU( NES* parent ) +CPU::CPU( NES* parent ) : nes(parent) +{ +// nes = parent; + m_bClockProcess = FALSE; +} + +CPU::~CPU() +{ +} + +// ANZX +//#define OP6502(A) (CPU_MEM_BANK[(A)>>13][(A)&0x1FFF]) +//#define OP6502W(A) (*((WORD*)&CPU_MEM_BANK[(A)>>13][(A)&0x1FFF])) + +#if 0 +#define OP6502(A) RD6502((A)) +#define OP6502W(A) RD6502W((A)) +#else +inline BYTE OP6502( WORD addr ) +{ + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +inline WORD OP6502W( WORD addr ) +{ +#if 0 + WORD ret; + ret = (WORD)CPU_MEM_BANK[(addr+0)>>13][(addr+0)&0x1FFF]; + ret |= (WORD)CPU_MEM_BANK[(addr+1)>>13][(addr+1)&0x1FFF]<<8; + return ret; +#else + return *((WORD*)&CPU_MEM_BANK[addr>>13][addr&0x1FFF]); +#endif +} +#endif + +inline BYTE CPU::RD6502( WORD addr ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + return RAM[addr&0x07FF]; + } else if( addr < 0x8000 ) { + // Others + return nes->Read( addr ); + } else { + return mapper->Read( addr ); + } +} + +inline WORD CPU::RD6502W( WORD addr ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + return *((WORD*)&RAM[addr&0x07FF]); + } else if( addr < 0x8000 ) { + // Others + return (WORD)nes->Read(addr)+(WORD)nes->Read(addr+1)*0x100; + } + + // Quick bank read +#if 0 + WORD ret; + ret = (WORD)CPU_MEM_BANK[(addr+0)>>13][(addr+0)&0x1FFF]; + ret |= (WORD)CPU_MEM_BANK[(addr+1)>>13][(addr+1)&0x1FFF]<<8; + return ret; +#else + return *((WORD*)&CPU_MEM_BANK[addr>>13][addr&0x1FFF]); +#endif +} + +// Cg +inline void CPU::WR6502( WORD addr, BYTE data ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + RAM[addr&0x07FF] = data; + } else { + // Others + nes->Write( addr, data ); + } +} + +// +// Zbg +// +void CPU::Reset() +{ + apu = nes->apu; + mapper = nes->mapper; + + R.A = 0x00; + R.X = 0x00; + R.Y = 0x00; + R.S = 0xFF; + R.P = Z_FLAG|R_FLAG; + R.PC = RD6502W(RES_VECTOR); + + R.INT_pending = 0; + + TOTAL_cycles = 0; + DMA_cycles = 0; + + // STACK quick access + STACK = &RAM[0x0100]; + + // Zero/Negative FLAG + ZN_Table[0] = Z_FLAG; + for( INT i = 1; i < 256; i++ ) + ZN_Table[i] = (i & 0x80)?N_FLAG:0; +} + +INT CPU::GetDmaCycles() +{ + return DMA_cycles; +} + +void CPU::SetDmaCycles( INT cycles ) +{ + DMA_cycles = cycles; +} + +INT CPU::GetTotalCycles() +{ + return TOTAL_cycles; +} + +void CPU::SetTotalCycles( INT cycles ) +{ + TOTAL_cycles = cycles; +} + +// +// DMAyfBOTCNݒ +// +void CPU::DMA( INT cycles ) +{ + DMA_cycles += cycles; +} + +static int nmicount; + +// +// 荞 +// +void CPU::NMI() +{ + R.INT_pending |= NMI_FLAG; + nmicount = 0; +} + +void CPU::SetIRQ( BYTE mask ) +{ + R.INT_pending |= mask; +} + +void CPU::ClrIRQ( BYTE mask ) +{ + R.INT_pending &= ~mask; +} + +// +// ߎs +// +INT CPU::EXEC( INT request_cycles ) +{ +BYTE opcode; // IyR[h +INT OLD_cycles = TOTAL_cycles; +INT exec_cycles; +BYTE nmi_request, irq_request; +BOOL bClockProcess = m_bClockProcess; + +// TEMP +register WORD EA; +register WORD ET; +register WORD WT; +register BYTE DT; + + while( request_cycles > 0 ) { + exec_cycles = 0; + + if( DMA_cycles ) { + if( request_cycles <= DMA_cycles ) { + DMA_cycles -= request_cycles; + TOTAL_cycles += request_cycles; + + // NbN + mapper->Clock( request_cycles ); +#if DPCM_SYNCCLOCK + apu->SyncDPCM( request_cycles ); +#endif + if( bClockProcess ) { + nes->Clock( request_cycles ); + } +// nes->Clock( request_cycles ); + goto _execute_exit; + } else { + exec_cycles += DMA_cycles; +// request_cycles -= DMA_cycles; + DMA_cycles = 0; + } + } + + nmi_request = irq_request = 0; + opcode = OP6502( R.PC++ ); + + if( R.INT_pending ) { + if( R.INT_pending & NMI_FLAG ) { + nmi_request = 0xFF; + R.INT_pending &= ~NMI_FLAG; + } else + if( R.INT_pending & IRQ_MASK ) { + R.INT_pending &= ~IRQ_TRIGGER2; + if( !(R.P & I_FLAG) && opcode != 0x40 ) { + irq_request = 0xFF; + R.INT_pending &= ~IRQ_TRIGGER; + } + } + } + + switch( opcode ) { + case 0x69: // ADC #$?? + MR_IM(); ADC(); + ADD_CYCLE(2); + break; + case 0x65: // ADC $?? + MR_ZP(); ADC(); + ADD_CYCLE(3); + break; + case 0x75: // ADC $??,X + MR_ZX(); ADC(); + ADD_CYCLE(4); + break; + case 0x6D: // ADC $???? + MR_AB(); ADC(); + ADD_CYCLE(4); + break; + case 0x7D: // ADC $????,X + MR_AX(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x79: // ADC $????,Y + MR_AY(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x61: // ADC ($??,X) + MR_IX(); ADC(); + ADD_CYCLE(6); + break; + case 0x71: // ADC ($??),Y + MR_IY(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0xE9: // SBC #$?? + MR_IM(); SBC(); + ADD_CYCLE(2); + break; + case 0xE5: // SBC $?? + MR_ZP(); SBC(); + ADD_CYCLE(3); + break; + case 0xF5: // SBC $??,X + MR_ZX(); SBC(); + ADD_CYCLE(4); + break; + case 0xED: // SBC $???? + MR_AB(); SBC(); + ADD_CYCLE(4); + break; + case 0xFD: // SBC $????,X + MR_AX(); SBC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xF9: // SBC $????,Y + MR_AY(); SBC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xE1: // SBC ($??,X) + MR_IX(); SBC(); + ADD_CYCLE(6); + break; + case 0xF1: // SBC ($??),Y + MR_IY(); SBC(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xC6: // DEC $?? + MR_ZP(); DEC(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xD6: // DEC $??,X + MR_ZX(); DEC(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xCE: // DEC $???? + MR_AB(); DEC(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xDE: // DEC $????,X + MR_AX(); DEC(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xCA: // DEX + DEX(); + ADD_CYCLE(2); + break; + case 0x88: // DEY + DEY(); + ADD_CYCLE(2); + break; + + case 0xE6: // INC $?? + MR_ZP(); INC(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xF6: // INC $??,X + MR_ZX(); INC(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xEE: // INC $???? + MR_AB(); INC(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xFE: // INC $????,X + MR_AX(); INC(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xE8: // INX + INX(); + ADD_CYCLE(2); + break; + case 0xC8: // INY + INY(); + ADD_CYCLE(2); + break; + + case 0x29: // AND #$?? + MR_IM(); AND(); + ADD_CYCLE(2); + break; + case 0x25: // AND $?? + MR_ZP(); AND(); + ADD_CYCLE(3); + break; + case 0x35: // AND $??,X + MR_ZX(); AND(); + ADD_CYCLE(4); + break; + case 0x2D: // AND $???? + MR_AB(); AND(); + ADD_CYCLE(4); + break; + case 0x3D: // AND $????,X + MR_AX(); AND(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x39: // AND $????,Y + MR_AY(); AND(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x21: // AND ($??,X) + MR_IX(); AND(); + ADD_CYCLE(6); + break; + case 0x31: // AND ($??),Y + MR_IY(); AND(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x0A: // ASL A + ASL_A(); + ADD_CYCLE(2); + break; + case 0x06: // ASL $?? + MR_ZP(); ASL(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x16: // ASL $??,X + MR_ZX(); ASL(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x0E: // ASL $???? + MR_AB(); ASL(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x1E: // ASL $????,X + MR_AX(); ASL(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x24: // BIT $?? + MR_ZP(); BIT(); + ADD_CYCLE(3); + break; + case 0x2C: // BIT $???? + MR_AB(); BIT(); + ADD_CYCLE(4); + break; + + case 0x49: // EOR #$?? + MR_IM(); EOR(); + ADD_CYCLE(2); + break; + case 0x45: // EOR $?? + MR_ZP(); EOR(); + ADD_CYCLE(3); + break; + case 0x55: // EOR $??,X + MR_ZX(); EOR(); + ADD_CYCLE(4); + break; + case 0x4D: // EOR $???? + MR_AB(); EOR(); + ADD_CYCLE(4); + break; + case 0x5D: // EOR $????,X + MR_AX(); EOR(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x59: // EOR $????,Y + MR_AY(); EOR(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x41: // EOR ($??,X) + MR_IX(); EOR(); + ADD_CYCLE(6); + break; + case 0x51: // EOR ($??),Y + MR_IY(); EOR(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x4A: // LSR A + LSR_A(); + ADD_CYCLE(2); + break; + case 0x46: // LSR $?? + MR_ZP(); LSR(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x56: // LSR $??,X + MR_ZX(); LSR(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x4E: // LSR $???? + MR_AB(); LSR(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x5E: // LSR $????,X + MR_AX(); LSR(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x09: // ORA #$?? + MR_IM(); ORA(); + ADD_CYCLE(2); + break; + case 0x05: // ORA $?? + MR_ZP(); ORA(); + ADD_CYCLE(3); + break; + case 0x15: // ORA $??,X + MR_ZX(); ORA(); + ADD_CYCLE(4); + break; + case 0x0D: // ORA $???? + MR_AB(); ORA(); + ADD_CYCLE(4); + break; + case 0x1D: // ORA $????,X + MR_AX(); ORA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x19: // ORA $????,Y + MR_AY(); ORA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x01: // ORA ($??,X) + MR_IX(); ORA(); + ADD_CYCLE(6); + break; + case 0x11: // ORA ($??),Y + MR_IY(); ORA(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x2A: // ROL A + ROL_A(); + ADD_CYCLE(2); + break; + case 0x26: // ROL $?? + MR_ZP(); ROL(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x36: // ROL $??,X + MR_ZX(); ROL(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x2E: // ROL $???? + MR_AB(); ROL(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x3E: // ROL $????,X + MR_AX(); ROL(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x6A: // ROR A + ROR_A(); + ADD_CYCLE(2); + break; + case 0x66: // ROR $?? + MR_ZP(); ROR(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x76: // ROR $??,X + MR_ZX(); ROR(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x6E: // ROR $???? + MR_AB(); ROR(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x7E: // ROR $????,X + MR_AX(); ROR(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xA9: // LDA #$?? + MR_IM(); LDA(); + ADD_CYCLE(2); + break; + case 0xA5: // LDA $?? + MR_ZP(); LDA(); + ADD_CYCLE(3); + break; + case 0xB5: // LDA $??,X + MR_ZX(); LDA(); + ADD_CYCLE(4); + break; + case 0xAD: // LDA $???? + MR_AB(); LDA(); + ADD_CYCLE(4); + break; + case 0xBD: // LDA $????,X + MR_AX(); LDA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xB9: // LDA $????,Y + MR_AY(); LDA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xA1: // LDA ($??,X) + MR_IX(); LDA(); + ADD_CYCLE(6); + break; + case 0xB1: // LDA ($??),Y + MR_IY(); LDA(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xA2: // LDX #$?? + MR_IM(); LDX(); + ADD_CYCLE(2); + break; + case 0xA6: // LDX $?? + MR_ZP(); LDX(); + ADD_CYCLE(3); + break; + case 0xB6: // LDX $??,Y + MR_ZY(); LDX(); + ADD_CYCLE(4); + break; + case 0xAE: // LDX $???? + MR_AB(); LDX(); + ADD_CYCLE(4); + break; + case 0xBE: // LDX $????,Y + MR_AY(); LDX(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0xA0: // LDY #$?? + MR_IM(); LDY(); + ADD_CYCLE(2); + break; + case 0xA4: // LDY $?? + MR_ZP(); LDY(); + ADD_CYCLE(3); + break; + case 0xB4: // LDY $??,X + MR_ZX(); LDY(); + ADD_CYCLE(4); + break; + case 0xAC: // LDY $???? + MR_AB(); LDY(); + ADD_CYCLE(4); + break; + case 0xBC: // LDY $????,X + MR_AX(); LDY(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0x85: // STA $?? + EA_ZP(); STA(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x95: // STA $??,X + EA_ZX(); STA(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8D: // STA $???? + EA_AB(); STA(); MW_EA(); + ADD_CYCLE(4); + break; + case 0x9D: // STA $????,X + EA_AX(); STA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x99: // STA $????,Y + EA_AY(); STA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x81: // STA ($??,X) + EA_IX(); STA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x91: // STA ($??),Y + EA_IY(); STA(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0x86: // STX $?? + EA_ZP(); STX(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x96: // STX $??,Y + EA_ZY(); STX(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8E: // STX $???? + EA_AB(); STX(); MW_EA(); + ADD_CYCLE(4); + break; + + case 0x84: // STY $?? + EA_ZP(); STY(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x94: // STY $??,X + EA_ZX(); STY(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8C: // STY $???? + EA_AB(); STY(); MW_EA(); + ADD_CYCLE(4); + break; + + case 0xAA: // TAX + TAX(); + ADD_CYCLE(2); + break; + case 0x8A: // TXA + TXA(); + ADD_CYCLE(2); + break; + case 0xA8: // TAY + TAY(); + ADD_CYCLE(2); + break; + case 0x98: // TYA + TYA(); + ADD_CYCLE(2); + break; + case 0xBA: // TSX + TSX(); + ADD_CYCLE(2); + break; + case 0x9A: // TXS + TXS(); + ADD_CYCLE(2); + break; + + case 0xC9: // CMP #$?? + MR_IM(); CMP_(); + ADD_CYCLE(2); + break; + case 0xC5: // CMP $?? + MR_ZP(); CMP_(); + ADD_CYCLE(3); + break; + case 0xD5: // CMP $??,X + MR_ZX(); CMP_(); + ADD_CYCLE(4); + break; + case 0xCD: // CMP $???? + MR_AB(); CMP_(); + ADD_CYCLE(4); + break; + case 0xDD: // CMP $????,X + MR_AX(); CMP_(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xD9: // CMP $????,Y + MR_AY(); CMP_(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xC1: // CMP ($??,X) + MR_IX(); CMP_(); + ADD_CYCLE(6); + break; + case 0xD1: // CMP ($??),Y + MR_IY(); CMP_(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xE0: // CPX #$?? + MR_IM(); CPX(); + ADD_CYCLE(2); + break; + case 0xE4: // CPX $?? + MR_ZP(); CPX(); + ADD_CYCLE(3); + break; + case 0xEC: // CPX $???? + MR_AB(); CPX(); + ADD_CYCLE(4); + break; + + case 0xC0: // CPY #$?? + MR_IM(); CPY(); + ADD_CYCLE(2); + break; + case 0xC4: // CPY $?? + MR_ZP(); CPY(); + ADD_CYCLE(3); + break; + case 0xCC: // CPY $???? + MR_AB(); CPY(); + ADD_CYCLE(4); + break; + + case 0x90: // BCC + MR_IM(); BCC(); + ADD_CYCLE(2); + break; + case 0xB0: // BCS + MR_IM(); BCS(); + ADD_CYCLE(2); + break; + case 0xF0: // BEQ + MR_IM(); BEQ(); + ADD_CYCLE(2); + break; + case 0x30: // BMI + MR_IM(); BMI(); + ADD_CYCLE(2); + break; + case 0xD0: // BNE + MR_IM(); BNE(); + ADD_CYCLE(2); + break; + case 0x10: // BPL + MR_IM(); BPL(); + ADD_CYCLE(2); + break; + case 0x50: // BVC + MR_IM(); BVC(); + ADD_CYCLE(2); + break; + case 0x70: // BVS + MR_IM(); BVS(); + ADD_CYCLE(2); + break; + + case 0x4C: // JMP $???? + JMP(); + ADD_CYCLE(3); + break; + case 0x6C: // JMP ($????) + JMP_ID(); + ADD_CYCLE(5); + break; + + case 0x20: // JSR + JSR(); + ADD_CYCLE(6); + break; + + case 0x40: // RTI + RTI(); + ADD_CYCLE(6); + break; + case 0x60: // RTS + RTS(); + ADD_CYCLE(6); + break; + + // tOn + case 0x18: // CLC + CLC(); + ADD_CYCLE(2); + break; + case 0xD8: // CLD + CLD(); + ADD_CYCLE(2); + break; + case 0x58: // CLI + CLI(); + ADD_CYCLE(2); + break; + case 0xB8: // CLV + CLV(); + ADD_CYCLE(2); + break; + + case 0x38: // SEC + SEC(); + ADD_CYCLE(2); + break; + case 0xF8: // SED + SED(); + ADD_CYCLE(2); + break; + case 0x78: // SEI + SEI(); + ADD_CYCLE(2); + break; + + // X^bNn + case 0x48: // PHA + PUSH( R.A ); + ADD_CYCLE(3); + break; + case 0x08: // PHP + PUSH( R.P | B_FLAG ); + ADD_CYCLE(3); + break; + case 0x68: // PLA (N-----Z-) + R.A = POP(); + SET_ZN_FLAG(R.A); + ADD_CYCLE(4); + break; + case 0x28: // PLP + R.P = POP() | R_FLAG; + ADD_CYCLE(4); + break; + + // ̑ + case 0x00: // BRK + BRK(); + ADD_CYCLE(7); + break; + + case 0xEA: // NOP + ADD_CYCLE(2); + break; + + // JߌQ + case 0x0B: // ANC #$?? + case 0x2B: // ANC #$?? + MR_IM(); ANC(); + ADD_CYCLE(2); + break; + + case 0x8B: // ANE #$?? + MR_IM(); ANE(); + ADD_CYCLE(2); + break; + + case 0x6B: // ARR #$?? + MR_IM(); ARR(); + ADD_CYCLE(2); + break; + + case 0x4B: // ASR #$?? + MR_IM(); ASR(); + ADD_CYCLE(2); + break; + + case 0xC7: // DCP $?? + MR_ZP(); DCP(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xD7: // DCP $??,X + MR_ZX(); DCP(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xCF: // DCP $???? + MR_AB(); DCP(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xDF: // DCP $????,X + MR_AX(); DCP(); MW_EA(); + ADD_CYCLE(7); + break; + case 0xDB: // DCP $????,Y + MR_AY(); DCP(); MW_EA(); + ADD_CYCLE(7); + break; + case 0xC3: // DCP ($??,X) + MR_IX(); DCP(); MW_EA(); + ADD_CYCLE(8); + break; + case 0xD3: // DCP ($??),Y + MR_IY(); DCP(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0xE7: // ISB $?? + MR_ZP(); ISB(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xF7: // ISB $??,X + MR_ZX(); ISB(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xEF: // ISB $???? + MR_AB(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xFF: // ISB $????,X + MR_AX(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xFB: // ISB $????,Y + MR_AY(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xE3: // ISB ($??,X) + MR_IX(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xF3: // ISB ($??),Y + MR_IY(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0xBB: // LAS $????,Y + MR_AY(); LAS(); CHECK_EA(); + ADD_CYCLE(4); + break; + + + case 0xA7: // LAX $?? + MR_ZP(); LAX(); + ADD_CYCLE(3); + break; + case 0xB7: // LAX $??,Y + MR_ZY(); LAX(); + ADD_CYCLE(4); + break; + case 0xAF: // LAX $???? + MR_AB(); LAX(); + ADD_CYCLE(4); + break; + case 0xBF: // LAX $????,Y + MR_AY(); LAX(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xA3: // LAX ($??,X) + MR_IX(); LAX(); + ADD_CYCLE(6); + break; + case 0xB3: // LAX ($??),Y + MR_IY(); LAX(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xAB: // LXA #$?? + MR_IM(); LXA(); + ADD_CYCLE(2); + break; + + case 0x27: // RLA $?? + MR_ZP(); RLA(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x37: // RLA $??,X + MR_ZX(); RLA(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x2F: // RLA $???? + MR_AB(); RLA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x3F: // RLA $????,X + MR_AX(); RLA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x3B: // RLA $????,Y + MR_AY(); RLA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x23: // RLA ($??,X) + MR_IX(); RLA(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x33: // RLA ($??),Y + MR_IY(); RLA(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x67: // RRA $?? + MR_ZP(); RRA(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x77: // RRA $??,X + MR_ZX(); RRA(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x6F: // RRA $???? + MR_AB(); RRA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x7F: // RRA $????,X + MR_AX(); RRA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x7B: // RRA $????,Y + MR_AY(); RRA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x63: // RRA ($??,X) + MR_IX(); RRA(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x73: // RRA ($??),Y + MR_IY(); RRA(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x87: // SAX $?? + MR_ZP(); SAX(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x97: // SAX $??,Y + MR_ZY(); SAX(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8F: // SAX $???? + MR_AB(); SAX(); MW_EA(); + ADD_CYCLE(4); + break; + case 0x83: // SAX ($??,X) + MR_IX(); SAX(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0xCB: // SBX #$?? + MR_IM(); SBX(); + ADD_CYCLE(2); + break; + + case 0x9F: // SHA $????,Y + MR_AY(); SHA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x93: // SHA ($??),Y + MR_IY(); SHA(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0x9B: // SHS $????,Y + MR_AY(); SHS(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x9E: // SHX $????,Y + MR_AY(); SHX(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x9C: // SHY $????,X + MR_AX(); SHY(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x07: // SLO $?? + MR_ZP(); SLO(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x17: // SLO $??,X + MR_ZX(); SLO(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x0F: // SLO $???? + MR_AB(); SLO(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x1F: // SLO $????,X + MR_AX(); SLO(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x1B: // SLO $????,Y + MR_AY(); SLO(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x03: // SLO ($??,X) + MR_IX(); SLO(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x13: // SLO ($??),Y + MR_IY(); SLO(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x47: // SRE $?? + MR_ZP(); SRE(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x57: // SRE $??,X + MR_ZX(); SRE(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x4F: // SRE $???? + MR_AB(); SRE(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x5F: // SRE $????,X + MR_AX(); SRE(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x5B: // SRE $????,Y + MR_AY(); SRE(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x43: // SRE ($??,X) + MR_IX(); SRE(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x53: // SRE ($??),Y + MR_IY(); SRE(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0xEB: // SBC #$?? (Unofficial) + MR_IM(); SBC(); + ADD_CYCLE(2); + break; + + case 0x1A: // NOP (Unofficial) + case 0x3A: // NOP (Unofficial) + case 0x5A: // NOP (Unofficial) + case 0x7A: // NOP (Unofficial) + case 0xDA: // NOP (Unofficial) + case 0xFA: // NOP (Unofficial) + ADD_CYCLE(2); + break; + case 0x80: // DOP (CYCLES 2) + case 0x82: // DOP (CYCLES 2) + case 0x89: // DOP (CYCLES 2) + case 0xC2: // DOP (CYCLES 2) + case 0xE2: // DOP (CYCLES 2) + R.PC++; + ADD_CYCLE(2); + break; + case 0x04: // DOP (CYCLES 3) + case 0x44: // DOP (CYCLES 3) + case 0x64: // DOP (CYCLES 3) + R.PC++; + ADD_CYCLE(3); + break; + case 0x14: // DOP (CYCLES 4) + case 0x34: // DOP (CYCLES 4) + case 0x54: // DOP (CYCLES 4) + case 0x74: // DOP (CYCLES 4) + case 0xD4: // DOP (CYCLES 4) + case 0xF4: // DOP (CYCLES 4) + R.PC++; + ADD_CYCLE(4); + break; + case 0x0C: // TOP + case 0x1C: // TOP + case 0x3C: // TOP + case 0x5C: // TOP + case 0x7C: // TOP + case 0xDC: // TOP + case 0xFC: // TOP + R.PC+=2; + ADD_CYCLE(4); + break; + + case 0x02: /* JAM */ + case 0x12: /* JAM */ + case 0x22: /* JAM */ + case 0x32: /* JAM */ + case 0x42: /* JAM */ + case 0x52: /* JAM */ + case 0x62: /* JAM */ + case 0x72: /* JAM */ + case 0x92: /* JAM */ + case 0xB2: /* JAM */ + case 0xD2: /* JAM */ + case 0xF2: /* JAM */ + default: + if( !Config.emulator.bIllegalOp ) { + throw CApp::GetErrorString( IDS_ERROR_ILLEGALOPCODE ); + goto _execute_exit; + } else { + R.PC--; + ADD_CYCLE(4); + } + break; +// default: +// __assume(0); + } + + if( nmi_request ) { + _NMI(); + } else + if( irq_request ) { + _IRQ(); + } + + request_cycles -= exec_cycles; + TOTAL_cycles += exec_cycles; + + // NbN + mapper->Clock( exec_cycles ); +#if DPCM_SYNCCLOCK + apu->SyncDPCM( exec_cycles ); +#endif + if( bClockProcess ) { + nes->Clock( exec_cycles ); + } +// nes->Clock( exec_cycles ); + } +_execute_exit: + +#if !DPCM_SYNCCLOCK + apu->SyncDPCM( TOTAL_cycles - OLD_cycles ); +#endif + + return TOTAL_cycles - OLD_cycles; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Cpu_old.cpp b/References/VirtuaNESex_src_191105/NES/Cpu_old.cpp new file mode 100644 index 00000000..f6d0bbea --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Cpu_old.cpp @@ -0,0 +1,2018 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* 6502 CPU Core v0.00 */ +/* Norix */ +/* written 2000/12/23 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +/*--------------[ INCLUDE ]-------------------------------*/ +#define WIN32_LEAN_AND_MEAN +#include + +#include "VirtuaNESres.h" + +#include "typedef.h" +#include "macro.h" + +#include "DebugOut.h" +#include "App.h" +#include "Config.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "rom.h" +#include "mapper.h" + +WORD PC_N; + +/*--------------[ DEFINE ]-------------------------------*/ +#define DPCM_SYNCCLOCK FALSE +/*--------------[ EXTERNAL PROGRAM ]-------------------------------*/ +/*--------------[ EXTERNAL WORK ]-------------------------------*/ +/*--------------[ WORK ]-------------------------------*/ +/*--------------[ CONST ]-------------------------------*/ +/*--------------[ PROTOTYPE ]-------------------------------*/ +/*--------------[ PROGRAM ]-------------------------------*/ +// IyR[h +//#define OP6502(A) RD6502((A)) +//#define OP6502W(A) RD6502W((A)) + +// [y[W[h +#define ZPRD(A) (RAM[(BYTE)(A)]) +//#define ZPRDW(A) (*((LPWORD)&RAM[(BYTE)(A)])) +#define ZPRDW(A) ((WORD)RAM[(BYTE)(A)]+((WORD)RAM[(BYTE)((A)+1)]<<8)) + +#define ZPWR(A,V) { RAM[(BYTE)(A)]=(V); } +#define ZPWRW(A,V) { *((LPWORD)&RAM[(BYTE)(A)])=(WORD)(V); } + +// TCNJE^ +#define ADD_CYCLE(V) { exec_cycles += (V); } +//#define ADD_CYCLE(V) {} + +// EFFECTIVE ADDRESSy[WE`FbN +#define CHECK_EA() { if( (ET&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); } +//#define CHECK_EA() { if( (R.PC&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); } +//#define CHECK_EA() {} + +// tO +// [^lKeButÕ`FbNƐݒ +#define SET_ZN_FLAG(A) { R.P &= ~(Z_FLAG|N_FLAG); R.P |= ZN_Table[(BYTE)(A)]; } + +// tOZbg +#define SET_FLAG(V) { R.P |= (V); } +// tONA +#define CLR_FLAG(V) { R.P &= ~(V); } +// tOeXgZbg^NA +#define TST_FLAG(F,V) { R.P &= ~(V); if((F)) R.P |= (V); } +// tO`FbN +#define CHK_FLAG(V) (R.P&(V)) + +// WT .... WORD TEMP +// EA .... EFFECTIVE ADDRESS +// ET .... EFFECTIVE ADDRESS TEMP +// DT .... DATA + +#define MR_IM() { \ + DT = OP6502( R.PC++ ); \ +} +#define MR_ZP() { \ + EA = OP6502( R.PC++ ); \ + DT = ZPRD( EA ); \ +} +#define MR_ZX() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.X); \ + DT = ZPRD( EA ); \ +} +#define MR_ZY() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.Y); \ + DT = ZPRD( EA ); \ +} +#define MR_AB() { \ + EA = OP6502W( R.PC ); \ + R.PC += 2; \ + DT = RD6502( EA ); \ +} +#define MR_AX() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + (WORD)R.X; \ + DT = RD6502( EA ); \ +} +#define MR_AY() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + (WORD)R.Y; \ + DT = RD6502( EA ); \ +} +#define MR_IX() { \ + DT = OP6502( R.PC++ ); \ + EA = ZPRDW( DT + R.X ); \ + DT = RD6502( EA ); \ +} +#define MR_IY() { \ + DT = OP6502( R.PC++ ); \ + ET = ZPRDW( DT ); \ + EA = ET + (WORD)R.Y; \ + DT = RD6502( EA ); \ +} + +// EFFECTIVE ADDRESS +#define EA_ZP() { \ + EA = OP6502( R.PC++ ); \ +} +#define EA_ZX() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.X); \ +} +#define EA_ZY() { \ + DT = OP6502( R.PC++ ); \ + EA = (BYTE)(DT + R.Y); \ +} +#define EA_AB() { \ + EA = OP6502W( R.PC ); \ + R.PC += 2; \ +} +#define EA_AX() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.X; \ +} +#define EA_AY() { \ + ET = OP6502W( R.PC ); \ + R.PC += 2; \ + EA = ET + R.Y; \ +} +#define EA_IX() { \ + DT = OP6502( R.PC++ ); \ + EA = ZPRDW( DT + R.X ); \ +} +#define EA_IY() { \ + DT = OP6502( R.PC++ ); \ + ET = ZPRDW( DT ); \ + EA = ET + (WORD)R.Y; \ +} + +// Cg +#define MW_ZP() ZPWR(EA,DT) +#define MW_EA() WR6502(EA,DT) + +// STACK +#define PUSH(V) { STACK[(R.S--)&0xFF]=(V); } +#define POP() STACK[(++R.S)&0xFF] + +// ZpZn +/* ADC (NV----ZC) */ +#define ADC() { \ + WT = R.A+DT+(R.P&C_FLAG); \ + TST_FLAG( WT > 0xFF, C_FLAG ); \ + TST_FLAG( ((~(R.A^DT))&(R.A^WT)&0x80), V_FLAG ); \ + R.A = (BYTE)WT; \ + SET_ZN_FLAG(R.A); \ +} + +/* SBC (NV----ZC) */ +#define SBC() { \ + WT = R.A-DT-(~R.P&C_FLAG); \ + TST_FLAG( ((R.A^DT) & (R.A^WT)&0x80), V_FLAG ); \ + TST_FLAG( WT < 0x100, C_FLAG ); \ + R.A = (BYTE)WT; \ + SET_ZN_FLAG(R.A); \ +} + +/* INC (N-----Z-) */ +#define INC() { \ + DT++; \ + SET_ZN_FLAG(DT); \ +} +/* INX (N-----Z-) */ +#define INX() { \ + R.X++; \ + SET_ZN_FLAG(R.X); \ +} +/* INY (N-----Z-) */ +#define INY() { \ + R.Y++; \ + SET_ZN_FLAG(R.Y); \ +} + +/* DEC (N-----Z-) */ +#define DEC() { \ + DT--; \ + SET_ZN_FLAG(DT); \ +} +/* DEX (N-----Z-) */ +#define DEX() { \ + R.X--; \ + SET_ZN_FLAG(R.X); \ +} +/* DEY (N-----Z-) */ +#define DEY() { \ + R.Y--; \ + SET_ZN_FLAG(R.Y); \ +} + +// _Zn +/* AND (N-----Z-) */ +#define AND() { \ + R.A &= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* ORA (N-----Z-) */ +#define ORA() { \ + R.A |= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* EOR (N-----Z-) */ +#define EOR() { \ + R.A ^= DT; \ + SET_ZN_FLAG(R.A); \ +} + +/* ASL_A (N-----ZC) */ +#define ASL_A() { \ + TST_FLAG( R.A&0x80, C_FLAG ); \ + R.A <<= 1; \ + SET_ZN_FLAG(R.A); \ +} + +/* ASL (N-----ZC) */ +#define ASL() { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + SET_ZN_FLAG(DT); \ +} + +/* LSR_A (N-----ZC) */ +#define LSR_A() { \ + TST_FLAG( R.A&0x01, C_FLAG ); \ + R.A >>= 1; \ + SET_ZN_FLAG(R.A); \ +} +/* LSR (N-----ZC) */ +#define LSR() { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + SET_ZN_FLAG(DT); \ +} + +/* ROL_A (N-----ZC) */ +#define ROL_A() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(R.A&0x80,C_FLAG); \ + R.A = (R.A<<1)|0x01; \ + } else { \ + TST_FLAG(R.A&0x80,C_FLAG); \ + R.A <<= 1; \ + } \ + SET_ZN_FLAG(R.A); \ +} +/* ROL (N-----ZC) */ +#define ROL() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(DT&0x80,C_FLAG); \ + DT = (DT<<1)|0x01; \ + } else { \ + TST_FLAG(DT&0x80,C_FLAG); \ + DT <<= 1; \ + } \ + SET_ZN_FLAG(DT); \ +} + +/* ROR_A (N-----ZC) */ +#define ROR_A() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(R.A&0x01,C_FLAG); \ + R.A = (R.A>>1)|0x80; \ + } else { \ + TST_FLAG(R.A&0x01,C_FLAG); \ + R.A >>= 1; \ + } \ + SET_ZN_FLAG(R.A); \ +} +/* ROR (N-----ZC) */ +#define ROR() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG(DT&0x01,C_FLAG); \ + DT = (DT>>1)|0x80; \ + } else { \ + TST_FLAG(DT&0x01,C_FLAG); \ + DT >>= 1; \ + } \ + SET_ZN_FLAG(DT); \ +} + +/* BIT (NV----Z-) */ +#define BIT() { \ + TST_FLAG( (DT&R.A)==0, Z_FLAG ); \ + TST_FLAG( DT&0x80, N_FLAG ); \ + TST_FLAG( DT&0x40, V_FLAG ); \ +} + +// [h^XgAn +/* LDA (N-----Z-) */ +#define LDA() { R.A = DT; SET_ZN_FLAG(R.A); } +/* LDX (N-----Z-) */ +#define LDX() { R.X = DT; SET_ZN_FLAG(R.X); } +/* LDY (N-----Z-) */ +#define LDY() { R.Y = DT; SET_ZN_FLAG(R.Y); } + +/* STA (--------) */ +#define STA() { DT = R.A; } +/* STX (--------) */ +#define STX() { DT = R.X; } +/* STY (--------) */ +#define STY() { DT = R.Y; } + +/* TAX (N-----Z-) */ +#define TAX() { R.X = R.A; SET_ZN_FLAG(R.X); } +/* TXA (N-----Z-) */ +#define TXA() { R.A = R.X; SET_ZN_FLAG(R.A); } +/* TAY (N-----Z-) */ +#define TAY() { R.Y = R.A; SET_ZN_FLAG(R.Y); } +/* TYA (N-----Z-) */ +#define TYA() { R.A = R.Y; SET_ZN_FLAG(R.A); } +/* TSX (N-----Z-) */ +#define TSX() { R.X = R.S; SET_ZN_FLAG(R.X); } +/* TXS (--------) */ +#define TXS() { R.S = R.X; } + +// rn +/* CMP (N-----ZC) */ +#define CMP_() { \ + WT = (WORD)R.A - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} +/* CPX (N-----ZC) */ +#define CPX() { \ + WT = (WORD)R.X - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} +/* CPY (N-----ZC) */ +#define CPY() { \ + WT = (WORD)R.Y - (WORD)DT; \ + TST_FLAG( (WT&0x8000)==0, C_FLAG ); \ + SET_ZN_FLAG( (BYTE)WT ); \ +} + +// Wv^^[n +#if 1 +#define JMP_ID() { \ + WT = OP6502W(R.PC); \ + EA = RD6502(WT); \ + WT = (WT&0xFF00)|((WT+1)&0x00FF); \ + R.PC = EA+RD6502(WT)*0x100; \ +} +#else +#define JMP_ID() { \ + ET = OP6502W(R.PC); \ + EA = RD6502W(ET); \ + R.PC = EA; \ +} +#endif +#define JMP() { \ + R.PC = OP6502W( R.PC ); \ +} +#define JSR() { \ + EA = OP6502W( R.PC ); \ + R.PC++; \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + R.PC = EA; \ +} +#define RTS() { \ + R.PC = POP(); \ + R.PC |= POP()*0x0100; \ + R.PC++; \ +} +#define RTI() { \ + R.P = POP() | R_FLAG; \ + R.PC = POP(); \ + R.PC |= POP()*0x0100; \ +} +#define _NMI() { \ + DEBUGOUT("_NMI-str!!!!!!!!!!\n");\ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + CLR_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(NMI_VECTOR); \ + exec_cycles += 7; \ + DEBUGOUT("_NMI-end!!!!!!!!!!\n");\ +} +#define _IRQ() { \ + DEBUGOUT("_IRQ-str!!!!!!!!!!\n");\ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + CLR_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(IRQ_VECTOR); \ + exec_cycles += 7; \ + DEBUGOUT("_IRQ-end!!!!!!!!!!\n");\ +} +#define BRK() { \ + DEBUGOUT("_BRK-str!!!!!!!!!!\n");\ + R.PC++; \ + PUSH( R.PC>>8 ); \ + PUSH( R.PC&0xFF ); \ + SET_FLAG( B_FLAG ); \ + PUSH( R.P ); \ + SET_FLAG( I_FLAG ); \ + R.PC = RD6502W(IRQ_VECTOR); \ + DEBUGOUT("_BRK-end!!!!!!!!!!\n");\ +} + +#if 1 +#define REL_JUMP() { \ + ET = R.PC; \ + EA = R.PC + (SBYTE)DT; \ + R.PC = EA; \ + ADD_CYCLE(1); \ + CHECK_EA(); \ +} +#else +#define REL_JUMP() { \ + R.PC = R.PC + (SBYTE)DT; \ + ADD_CYCLE(1); \ +} +#endif + +#define BCC() { if( !(R.P & C_FLAG) ) REL_JUMP(); } +#define BCS() { if( (R.P & C_FLAG) ) REL_JUMP(); } +#define BNE() { if( !(R.P & Z_FLAG) ) REL_JUMP(); } +#define BEQ() { if( (R.P & Z_FLAG) ) REL_JUMP(); } +#define BPL() { if( !(R.P & N_FLAG) ) REL_JUMP(); } +#define BMI() { if( (R.P & N_FLAG) ) REL_JUMP(); } +#define BVC() { if( !(R.P & V_FLAG) ) REL_JUMP(); } +#define BVS() { if( (R.P & V_FLAG) ) REL_JUMP(); } + +// tOn +#define CLC() { R.P &= ~C_FLAG; } +#define CLD() { R.P &= ~D_FLAG; } +#define CLI() { R.P &= ~I_FLAG; } +#define CLV() { R.P &= ~V_FLAG; } +#define SEC() { R.P |= C_FLAG; } +#define SED() { R.P |= D_FLAG; } +#define SEI() { R.P |= I_FLAG; } + +// Unofficial +#define ANC() { \ + R.A &= DT; \ + SET_ZN_FLAG( R.A ); \ + TST_FLAG( R.P&N_FLAG, C_FLAG ); \ +} + +#define ANE() { \ + R.A = (R.A|0xEE)&R.X&DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define ARR() { \ + DT &= R.A; \ + R.A = (DT>>1)|((R.P&C_FLAG)<<7); \ + SET_ZN_FLAG( R.A ); \ + TST_FLAG( R.A&0x40, C_FLAG ); \ + TST_FLAG( (R.A>>6)^(R.A>>5), V_FLAG ); \ +} + +#define ASR() { \ + DT &= R.A; \ + TST_FLAG( DT&0x01, C_FLAG ); \ + R.A = DT>>1; \ + SET_ZN_FLAG( R.A ); \ +} + +#define DCP() { \ + DT--; \ + CMP_(); \ +} + +#define DOP() { \ + R.PC++; \ +} + +#define ISB() { \ + DT++; \ + SBC(); \ +} + +#define LAS() { \ + R.A = R.X = R.S = (R.S & DT); \ + SET_ZN_FLAG( R.A ); \ +} + +#define LAX() { \ + R.A = DT; \ + R.X = R.A; \ + SET_ZN_FLAG( R.A ); \ +} + +#define LXA() { \ + R.A = R.X = ((R.A|0xEE)&DT); \ + SET_ZN_FLAG( R.A ); \ +} + +#define RLA() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT = (DT<<1)|1; \ + } else { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + } \ + R.A &= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define RRA() { \ + if( R.P & C_FLAG ) { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT = (DT>>1)|0x80; \ + } else { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + } \ + ADC(); \ +} + +#define SAX() { \ + DT = R.A & R.X; \ +} + +#define SBX() { \ + WT = (R.A&R.X)-DT; \ + TST_FLAG( WT < 0x100, C_FLAG ); \ + R.X = WT&0xFF; \ + SET_ZN_FLAG( R.X ); \ +} + +#define SHA() { \ + DT = R.A & R.X & (BYTE)((EA>>8)+1); \ +} + +#define SHS() { \ + R.S = R.A & R.X; \ + DT = R.S & (BYTE)((EA>>8)+1); \ +} + +#define SHX() { \ + DT = R.X & (BYTE)((EA>>8)+1); \ +} + +#define SHY() { \ + DT = R.Y & (BYTE)((EA>>8)+1); \ +} + +#define SLO() { \ + TST_FLAG( DT&0x80, C_FLAG ); \ + DT <<= 1; \ + R.A |= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define SRE() { \ + TST_FLAG( DT&0x01, C_FLAG ); \ + DT >>= 1; \ + R.A ^= DT; \ + SET_ZN_FLAG( R.A ); \ +} + +#define TOP() { \ + R.PC += 2; \ +} + +// +// RXgN^/fXgN^ +// +//CPU::CPU( NES* parent ) +CPU::CPU( NES* parent ) : nes(parent) +{ +// nes = parent; + m_bClockProcess = FALSE; +} + +CPU::~CPU() +{ +} + +// ANZX +//#define OP6502(A) (CPU_MEM_BANK[(A)>>13][(A)&0x1FFF]) +//#define OP6502W(A) (*((WORD*)&CPU_MEM_BANK[(A)>>13][(A)&0x1FFF])) + +#if 0 +#define OP6502(A) RD6502((A)) +#define OP6502W(A) RD6502W((A)) +#else +inline BYTE OP6502( WORD addr ) +{ + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +inline WORD OP6502W( WORD addr ) +{ +#if 0 + WORD ret; + ret = (WORD)CPU_MEM_BANK[(addr+0)>>13][(addr+0)&0x1FFF]; + ret |= (WORD)CPU_MEM_BANK[(addr+1)>>13][(addr+1)&0x1FFF]<<8; + return ret; +#else + return *((WORD*)&CPU_MEM_BANK[addr>>13][addr&0x1FFF]); +#endif +} +#endif + +inline BYTE CPU::RD6502( WORD addr ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + return RAM[addr&0x07FF]; + } else if( addr < 0x8000 ) { + // Others + return nes->Read( addr ); + } else { + + BYTE data; + if (mapper->ReadHigh(addr, &data)) + return data; + + // Dummy access + mapper->Read( addr, CPU_MEM_BANK[addr>>13][addr&0x1FFF] ); + } + + // Quick bank read + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +inline WORD CPU::RD6502W( WORD addr ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + return *((WORD*)&RAM[addr&0x07FF]); + } else if( addr < 0x8000 ) { + // Others + return (WORD)nes->Read(addr)+(WORD)nes->Read(addr+1)*0x100; + } + + // Quick bank read +#if 0 + WORD ret; + ret = (WORD)CPU_MEM_BANK[(addr+0)>>13][(addr+0)&0x1FFF]; + ret |= (WORD)CPU_MEM_BANK[(addr+1)>>13][(addr+1)&0x1FFF]<<8; + return ret; +#else + return *((WORD*)&CPU_MEM_BANK[addr>>13][addr&0x1FFF]); +#endif +} + +// Cg +inline void CPU::WR6502( WORD addr, BYTE data ) +{ + if( addr < 0x2000 ) { + // RAM (Mirror $0800, $1000, $1800) + RAM[addr&0x07FF] = data; + } else { + // Others + nes->Write( addr, data ); + } +} + +// +// Zbg +// +void CPU::Reset() +{ + apu = nes->apu; + mapper = nes->mapper; + + R.A = 0x00; + R.X = 0x00; + R.Y = 0x00; + R.S = 0xFF; + R.P = Z_FLAG|R_FLAG; + R.PC = RD6502W(RES_VECTOR); + + R.INT_pending = 0; + + TOTAL_cycles = 0; + DMA_cycles = 0; + + // STACK quick access + STACK = &RAM[0x0100]; + + // Zero/Negative FLAG + ZN_Table[0] = Z_FLAG; + for( INT i = 1; i < 256; i++ ) + ZN_Table[i] = (i & 0x80)?N_FLAG:0; +} + +INT CPU::GetDmaCycles() +{ + return DMA_cycles; +} + +void CPU::SetDmaCycles( INT cycles ) +{ + DMA_cycles = cycles; +} + +INT CPU::GetTotalCycles() +{ + return TOTAL_cycles; +} + +void CPU::SetTotalCycles( INT cycles ) +{ + TOTAL_cycles = cycles; +} + +// +// DMAyfBOTCNݒ +// +void CPU::DMA( INT cycles ) +{ + DMA_cycles += cycles; +} + +// +// 荞 +// +void CPU::NMI() +{ + R.INT_pending |= NMI_FLAG; +} + +void CPU::SetIRQ( BYTE mask ) +{ + R.INT_pending |= mask; +} + +void CPU::ClrIRQ( BYTE mask ) +{ + R.INT_pending &= ~mask; +} + + +//dasm +int CPU::dasm6502(int *dasmpc, int *bcc_pc, char *obuf) +{ + + static char *opnmt[57] = { + "ADC","AND","ASL","BCC","BCS","BEQ","BIT","BMI","BNE","BPL","BRK","BVC","BVS","CLC","???", + "CLD","CLI","CLV","CMP","CPX","CPY","DEC","DEX","DEY","EOR","INC","INX","INY","JMP", + "JSR","LDA","LDX","LDY","LSR","NOP","ORA","PHA","PHP","PLA","PLP","ROL","ROR","RTI", + "RTS","SBC","SEC","SED","SEI","STA","STX","STY","TAX","TAY","TSX","TXA","TXS","TYA" + }; + static int opct[256] = { + 0x0a87,0x2366,0x0e82,0x0e82,0x0e82,0x2313,0x0215,0x0e82,0x2583,0x2302,0x02a2,0x0e82,0x0e82,0x2334,0x0236,0x0e82, + 0x0992,0x237d,0x0e82,0x0e82,0x0e82,0x2324,0x0226,0x0e82,0x0d82,0x235c,0x0e82,0x0e82,0x0e82,0x234c,0x0247,0x0e82, + 0x1d36,0x0166,0x0e82,0x0e82,0x0613,0x0113,0x2815,0x0e82,0x2784,0x0102,0x28a2,0x0e82,0x0634,0x0134,0x2836,0x0e82, + 0x0792,0x017d,0x0e82,0x0e82,0x0e82,0x0124,0x2826,0x0e82,0x2d82,0x015c,0x0e82,0x0e82,0x0e82,0x014c,0x2847,0x0e82, + 0x2a86,0x1866,0x0e82,0x0e82,0x0e82,0x1813,0x2115,0x0e82,0x2483,0x1802,0x21a2,0x0e82,0x1c33,0x1834,0x2136,0x0e82, + 0x0b92,0x187d,0x0e82,0x0e82,0x0e82,0x1824,0x2126,0x0e82,0x1082,0x185c,0x0e82,0x0e82,0x0e82,0x184c,0x2147,0x0e82, + 0x2b86,0x0066,0x0e82,0x0e82,0x0e82,0x0013,0x2915,0x0e82,0x2684,0x0002,0x29a2,0x0e82,0x1cb5,0x0034,0x2936,0x0e82, + 0x0c92,0x007d,0x0e82,0x0e82,0x0e82,0x0024,0x2926,0x0e82,0x2f82,0x005c,0x0e82,0x0e82,0x0e82,0x004c,0x2947,0x0e82, + 0x0e82,0x3066,0x0e82,0x0e82,0x3213,0x3013,0x3113,0x0e82,0x1782,0x0e82,0x3682,0x0e82,0x3234,0x3034,0x3134,0x0e82, + 0x0392,0x307d,0x0e82,0x0e82,0x3224,0x3024,0x31c4,0x0e82,0x3882,0x305c,0x3782,0x0e82,0x0e82,0x304c,0x0e82,0x0e82, + 0x2002,0x1e66,0x1f02,0x0e82,0x2013,0x1e13,0x1f13,0x0e82,0x3482,0x1e02,0x3382,0x0e82,0x2034,0x1e34,0x1f34,0x0e82, + 0x0492,0x1e7d,0x0e82,0x0e82,0x2024,0x1e24,0x1fc4,0x0e82,0x1182,0x1e5c,0x3582,0x0e82,0x204c,0x1e4c,0x1f5c,0x0e82, + 0x1402,0x1266,0x0e82,0x0e82,0x1413,0x1213,0x1515,0x0e82,0x1b82,0x1202,0x1682,0x0e82,0x1434,0x1234,0x1536,0x0e82, + 0x0892,0x127d,0x0e82,0x0e82,0x0e82,0x1224,0x1526,0x0e82,0x0f82,0x125c,0x0e82,0x0e82,0x0e82,0x124c,0x1547,0x0e82, + 0x1302,0x2c66,0x0e82,0x0e82,0x1313,0x2c13,0x1915,0x0e82,0x1a82,0x2c02,0x2282,0x0e82,0x1334,0x2c34,0x1936,0x0e82, + 0x0592,0x2c7d,0x0e82,0x0e82,0x0e82,0x2c24,0x1926,0x0e82,0x2e82,0x2c5c,0x0e82,0x0e82,0x0e82,0x2c4c,0x1947,0x0e82 + }; + static int opsz[16]={2,2,2,3,3,3,2,2,0,2,0,3,2}; + static char *oppre[16]={"#$","$","$","$","$","$","($","($","","$","A","($","$"}; + static char *opsuf[16]={"","",",X","",",X",",Y",",X)","),Y","","","",")",",Y"}; + + unsigned int opcode,opdata,rpc; + unsigned int opname,opsize,opaddr; + int retv; + char *regbuf; + + + memset(obuf, 32, 40); + retv = 0; + regbuf = obuf+36; + sprintf(obuf,"%04X: ",(*dasmpc)); + obuf+=6; + opcode=OP6502(*dasmpc); + (*dasmpc)++; + + if(opcode == 0x4c || opcode == 0x40 || opcode == 0x6c){ + retv = 1; + } + + opname=opct[opcode]; + opaddr=(opname>>4)&0x0f; + opsize=opsz[opaddr]; + opname>>=8; + sprintf(obuf,"%02X ",opcode); + obuf+=3; + + if(opsize==2){ + opdata=OP6502(*dasmpc); + (*dasmpc)++; + sprintf(obuf,"%02X ",opdata); + obuf+=6; + }else if(opsize==3){ + opdata=OP6502(*dasmpc); + (*dasmpc)++; + sprintf(obuf,"%02X ",opdata); + obuf+=3; + opdata<<=8; + opdata|=OP6502(*dasmpc); + (*dasmpc)++; + sprintf(obuf,"%02X ",opdata&0xff); + obuf+=3; + }else{ + sprintf(obuf," "); + obuf+=6; + } + + sprintf(obuf," %s ",opnmt[opname]); + obuf+=6; + sprintf(obuf,"%s",oppre[opaddr]); + obuf+=strlen(oppre[opaddr]); + + if(opsize==2){ + if(opaddr==9){ + retv = 2; + if(opdata>=0x80) + rpc=(*dasmpc)+(opdata|~0xff); + else + rpc=(*dasmpc)+opdata; + sprintf(obuf,"%04X",rpc); + (*bcc_pc) = rpc; + obuf+=4; + }else{ + sprintf(obuf,"%02X",opdata); + obuf+=2; + } + }else if(opsize==3){ + sprintf(obuf,"%02X",opdata&0xff); + obuf+=2; + sprintf(obuf,"%02X",opdata>>8); + obuf+=2; + if(opcode == 0x4c) + (*bcc_pc) = ((opdata<<8)&0xff00) | ((opdata>>8)&0xff); + } + + sprintf(obuf,"%s",opsuf[opaddr]); + obuf += strlen(opsuf[opaddr]); + *obuf = 32; + + sprintf(regbuf, "A=%02X X=%02X Y=%02X SL=%02x", R.A, R.X, R.Y, nes->ppu->GetScanlineNo()); + + regbuf+=32; +/* + sprintf(regbuf, " ["); + regbuf += 3; + rpc = R.S; + rpc++; + for(i=0; i<16; i++){ + sprintf(regbuf, "%02x ", STACK[rpc+i]); + regbuf += 3; + } + sprintf(regbuf, "]"); +*/ + return retv; +} + +FILE *dfp = NULL; + +void MDEBUGOUT(char *str) +{ + if(dfp==NULL){ + dfp = fopen("log.txt", "w"); + } + + fprintf(dfp, "%s", str); +} + + +// +// ߎs +// +INT CPU::EXEC( INT request_cycles ) +{ +BYTE opcode; // IyR[h +INT OLD_cycles = TOTAL_cycles; +INT exec_cycles; +BYTE nmi_request, irq_request; +BOOL bClockProcess = m_bClockProcess; + +// TEMP +register WORD EA; +register WORD ET; +register WORD WT; +register BYTE DT; + + PC_N = R.PC; + if(nnn==8) DEBUGOUT( "PC_N = %04X\n", PC_N ); + + while( request_cycles > 0 ) { + exec_cycles = 0; + + if( DMA_cycles ) { + if( request_cycles <= DMA_cycles ) { + DMA_cycles -= request_cycles; + TOTAL_cycles += request_cycles; + + // NbN + mapper->Clock( request_cycles ); +#if DPCM_SYNCCLOCK + apu->SyncDPCM( request_cycles ); +#endif + if( bClockProcess ) { + nes->Clock( request_cycles ); + } +// nes->Clock( request_cycles ); + goto _execute_exit; + } else { + exec_cycles += DMA_cycles; + request_cycles -= DMA_cycles; + DMA_cycles = 0; + } + } + +#if 0 +{ +static int retv, dpc, bpc, jpc=0, skip=0; +char dbuf[512]; +static int disasm = 0; + +if( ::GetAsyncKeyState( VK_ESCAPE ) & 0x8000 ) { + disasm ^= 1; +} +if(disasm==1){ + dpc = R.PC; + + if(dpc>jpc || dpc0){ + jpc = R.PC; + skip = 1; + MDEBUGOUT(" -- Maybe a loop? --\n"); + } + } + MDEBUGOUT(dbuf); + MDEBUGOUT("\n"); + } +} +} +#endif + + nmi_request = irq_request = 0; + opcode = OP6502(R.PC); + if( R.INT_pending ) { + if( R.INT_pending & NMI_FLAG ) { + nmi_request = 0xFF; + R.INT_pending &= ~NMI_FLAG; + } else + if( R.INT_pending & IRQ_MASK ) { + R.INT_pending &= ~IRQ_TRIGGER2; + if( !(R.P & I_FLAG) && opcode != 0x40 ) { + irq_request = 0xFF; + R.INT_pending &= ~IRQ_TRIGGER; + } + } + } + + + if( irq_request ){ + _IRQ(); + } + + opcode = OP6502( R.PC++ ); + switch( opcode ) { + case 0x69: // ADC #$?? + MR_IM(); ADC(); + ADD_CYCLE(2); + break; + case 0x65: // ADC $?? + MR_ZP(); ADC(); + ADD_CYCLE(3); + break; + case 0x75: // ADC $??,X + MR_ZX(); ADC(); + ADD_CYCLE(4); + break; + case 0x6D: // ADC $???? + MR_AB(); ADC(); + ADD_CYCLE(4); + break; + case 0x7D: // ADC $????,X + MR_AX(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x79: // ADC $????,Y + MR_AY(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x61: // ADC ($??,X) + MR_IX(); ADC(); + ADD_CYCLE(6); + break; + case 0x71: // ADC ($??),Y + MR_IY(); ADC(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0xE9: // SBC #$?? + MR_IM(); SBC(); + ADD_CYCLE(2); + break; + case 0xE5: // SBC $?? + MR_ZP(); SBC(); + ADD_CYCLE(3); + break; + case 0xF5: // SBC $??,X + MR_ZX(); SBC(); + ADD_CYCLE(4); + break; + case 0xED: // SBC $???? + MR_AB(); SBC(); + ADD_CYCLE(4); + break; + case 0xFD: // SBC $????,X + MR_AX(); SBC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xF9: // SBC $????,Y + MR_AY(); SBC(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xE1: // SBC ($??,X) + MR_IX(); SBC(); + ADD_CYCLE(6); + break; + case 0xF1: // SBC ($??),Y + MR_IY(); SBC(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xC6: // DEC $?? + MR_ZP(); DEC(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xD6: // DEC $??,X + MR_ZX(); DEC(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xCE: // DEC $???? + MR_AB(); DEC(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xDE: // DEC $????,X + MR_AX(); DEC(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xCA: // DEX + DEX(); + ADD_CYCLE(2); + break; + case 0x88: // DEY + DEY(); + ADD_CYCLE(2); + break; + + case 0xE6: // INC $?? + MR_ZP(); INC(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xF6: // INC $??,X + MR_ZX(); INC(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xEE: // INC $???? + MR_AB(); INC(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xFE: // INC $????,X + MR_AX(); INC(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xE8: // INX + INX(); + ADD_CYCLE(2); + break; + case 0xC8: // INY + INY(); + ADD_CYCLE(2); + break; + + case 0x29: // AND #$?? + MR_IM(); AND(); + ADD_CYCLE(2); + break; + case 0x25: // AND $?? + MR_ZP(); AND(); + ADD_CYCLE(3); + break; + case 0x35: // AND $??,X + MR_ZX(); AND(); + ADD_CYCLE(4); + break; + case 0x2D: // AND $???? + MR_AB(); AND(); + ADD_CYCLE(4); + break; + case 0x3D: // AND $????,X + MR_AX(); AND(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x39: // AND $????,Y + MR_AY(); AND(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x21: // AND ($??,X) + MR_IX(); AND(); + ADD_CYCLE(6); + break; + case 0x31: // AND ($??),Y + MR_IY(); AND(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x0A: // ASL A + ASL_A(); + ADD_CYCLE(2); + break; + case 0x06: // ASL $?? + MR_ZP(); ASL(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x16: // ASL $??,X + MR_ZX(); ASL(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x0E: // ASL $???? + MR_AB(); ASL(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x1E: // ASL $????,X + MR_AX(); ASL(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x24: // BIT $?? + MR_ZP(); BIT(); + ADD_CYCLE(3); + break; + case 0x2C: // BIT $???? + MR_AB(); BIT(); + ADD_CYCLE(4); + break; + + case 0x49: // EOR #$?? + MR_IM(); EOR(); + ADD_CYCLE(2); + break; + case 0x45: // EOR $?? + MR_ZP(); EOR(); + ADD_CYCLE(3); + break; + case 0x55: // EOR $??,X + MR_ZX(); EOR(); + ADD_CYCLE(4); + break; + case 0x4D: // EOR $???? + MR_AB(); EOR(); + ADD_CYCLE(4); + break; + case 0x5D: // EOR $????,X + MR_AX(); EOR(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x59: // EOR $????,Y + MR_AY(); EOR(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x41: // EOR ($??,X) + MR_IX(); EOR(); + ADD_CYCLE(6); + break; + case 0x51: // EOR ($??),Y + MR_IY(); EOR(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x4A: // LSR A + LSR_A(); + ADD_CYCLE(2); + break; + case 0x46: // LSR $?? + MR_ZP(); LSR(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x56: // LSR $??,X + MR_ZX(); LSR(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x4E: // LSR $???? + MR_AB(); LSR(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x5E: // LSR $????,X + MR_AX(); LSR(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x09: // ORA #$?? + MR_IM(); ORA(); + ADD_CYCLE(2); + break; + case 0x05: // ORA $?? + MR_ZP(); ORA(); + ADD_CYCLE(3); + break; + case 0x15: // ORA $??,X + MR_ZX(); ORA(); + ADD_CYCLE(4); + break; + case 0x0D: // ORA $???? + MR_AB(); ORA(); + ADD_CYCLE(4); + break; + case 0x1D: // ORA $????,X + MR_AX(); ORA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x19: // ORA $????,Y + MR_AY(); ORA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0x01: // ORA ($??,X) + MR_IX(); ORA(); + ADD_CYCLE(6); + break; + case 0x11: // ORA ($??),Y + MR_IY(); ORA(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0x2A: // ROL A + ROL_A(); + ADD_CYCLE(2); + break; + case 0x26: // ROL $?? + MR_ZP(); ROL(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x36: // ROL $??,X + MR_ZX(); ROL(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x2E: // ROL $???? + MR_AB(); ROL(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x3E: // ROL $????,X + MR_AX(); ROL(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0x6A: // ROR A + ROR_A(); + ADD_CYCLE(2); + break; + case 0x66: // ROR $?? + MR_ZP(); ROR(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x76: // ROR $??,X + MR_ZX(); ROR(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x6E: // ROR $???? + MR_AB(); ROR(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x7E: // ROR $????,X + MR_AX(); ROR(); MW_EA(); + ADD_CYCLE(7); + break; + + case 0xA9: // LDA #$?? + MR_IM(); LDA(); + ADD_CYCLE(2); + break; + case 0xA5: // LDA $?? + MR_ZP(); LDA(); + ADD_CYCLE(3); + break; + case 0xB5: // LDA $??,X + MR_ZX(); LDA(); + ADD_CYCLE(4); + break; + case 0xAD: // LDA $???? + MR_AB(); LDA(); + ADD_CYCLE(4); + break; + case 0xBD: // LDA $????,X + MR_AX(); LDA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xB9: // LDA $????,Y + MR_AY(); LDA(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xA1: // LDA ($??,X) + MR_IX(); LDA(); + ADD_CYCLE(6); + break; + case 0xB1: // LDA ($??),Y + MR_IY(); LDA(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xA2: // LDX #$?? + MR_IM(); LDX(); + ADD_CYCLE(2); + break; + case 0xA6: // LDX $?? + MR_ZP(); LDX(); + ADD_CYCLE(3); + break; + case 0xB6: // LDX $??,Y + MR_ZY(); LDX(); + ADD_CYCLE(4); + break; + case 0xAE: // LDX $???? + MR_AB(); LDX(); + ADD_CYCLE(4); + break; + case 0xBE: // LDX $????,Y + MR_AY(); LDX(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0xA0: // LDY #$?? + MR_IM(); LDY(); + ADD_CYCLE(2); + break; + case 0xA4: // LDY $?? + MR_ZP(); LDY(); + ADD_CYCLE(3); + break; + case 0xB4: // LDY $??,X + MR_ZX(); LDY(); + ADD_CYCLE(4); + break; + case 0xAC: // LDY $???? + MR_AB(); LDY(); + ADD_CYCLE(4); + break; + case 0xBC: // LDY $????,X + MR_AX(); LDY(); CHECK_EA(); + ADD_CYCLE(4); + break; + + case 0x85: // STA $?? + EA_ZP(); STA(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x95: // STA $??,X + EA_ZX(); STA(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8D: // STA $???? + EA_AB(); STA(); MW_EA(); + ADD_CYCLE(4); + break; + case 0x9D: // STA $????,X + EA_AX(); STA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x99: // STA $????,Y + EA_AY(); STA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x81: // STA ($??,X) + EA_IX(); STA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x91: // STA ($??),Y + EA_IY(); STA(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0x86: // STX $?? + EA_ZP(); STX(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x96: // STX $??,Y + EA_ZY(); STX(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8E: // STX $???? + EA_AB(); STX(); MW_EA(); + ADD_CYCLE(4); + break; + + case 0x84: // STY $?? + EA_ZP(); STY(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x94: // STY $??,X + EA_ZX(); STY(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8C: // STY $???? + EA_AB(); STY(); MW_EA(); + ADD_CYCLE(4); + break; + + case 0xAA: // TAX + TAX(); + ADD_CYCLE(2); + break; + case 0x8A: // TXA + TXA(); + ADD_CYCLE(2); + break; + case 0xA8: // TAY + TAY(); + ADD_CYCLE(2); + break; + case 0x98: // TYA + TYA(); + ADD_CYCLE(2); + break; + case 0xBA: // TSX + TSX(); + ADD_CYCLE(2); + break; + case 0x9A: // TXS + TXS(); + ADD_CYCLE(2); + break; + + case 0xC9: // CMP #$?? + MR_IM(); CMP_(); + ADD_CYCLE(2); + break; + case 0xC5: // CMP $?? + MR_ZP(); CMP_(); + ADD_CYCLE(3); + break; + case 0xD5: // CMP $??,X + MR_ZX(); CMP_(); + ADD_CYCLE(4); + break; + case 0xCD: // CMP $???? + MR_AB(); CMP_(); + ADD_CYCLE(4); + break; + case 0xDD: // CMP $????,X + MR_AX(); CMP_(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xD9: // CMP $????,Y + MR_AY(); CMP_(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xC1: // CMP ($??,X) + MR_IX(); CMP_(); + ADD_CYCLE(6); + break; + case 0xD1: // CMP ($??),Y + MR_IY(); CMP_(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xE0: // CPX #$?? + MR_IM(); CPX(); + ADD_CYCLE(2); + break; + case 0xE4: // CPX $?? + MR_ZP(); CPX(); + ADD_CYCLE(3); + break; + case 0xEC: // CPX $???? + MR_AB(); CPX(); + ADD_CYCLE(4); + break; + + case 0xC0: // CPY #$?? + MR_IM(); CPY(); + ADD_CYCLE(2); + break; + case 0xC4: // CPY $?? + MR_ZP(); CPY(); + ADD_CYCLE(3); + break; + case 0xCC: // CPY $???? + MR_AB(); CPY(); + ADD_CYCLE(4); + break; + + case 0x90: // BCC + MR_IM(); BCC(); + ADD_CYCLE(2); + break; + case 0xB0: // BCS + MR_IM(); BCS(); + ADD_CYCLE(2); + break; + case 0xF0: // BEQ + MR_IM(); BEQ(); + ADD_CYCLE(2); + break; + case 0x30: // BMI + MR_IM(); BMI(); + ADD_CYCLE(2); + break; + case 0xD0: // BNE + MR_IM(); BNE(); + ADD_CYCLE(2); + break; + case 0x10: // BPL + MR_IM(); BPL(); + ADD_CYCLE(2); + break; + case 0x50: // BVC + MR_IM(); BVC(); + ADD_CYCLE(2); + break; + case 0x70: // BVS + MR_IM(); BVS(); + ADD_CYCLE(2); + break; + + case 0x4C: // JMP $???? + JMP(); + ADD_CYCLE(3); + break; + case 0x6C: // JMP ($????) + JMP_ID(); + ADD_CYCLE(5); + break; + + case 0x20: // JSR + JSR(); + ADD_CYCLE(6); + break; + + case 0x40: // RTI + RTI(); + ADD_CYCLE(6); + break; + case 0x60: // RTS + RTS(); + ADD_CYCLE(6); + break; + + // tOn + case 0x18: // CLC + CLC(); + ADD_CYCLE(2); + break; + case 0xD8: // CLD + CLD(); + ADD_CYCLE(2); + break; + case 0x58: // CLI + CLI(); + ADD_CYCLE(2); + break; + case 0xB8: // CLV + CLV(); + ADD_CYCLE(2); + break; + + case 0x38: // SEC + SEC(); + ADD_CYCLE(2); + break; + case 0xF8: // SED + SED(); + ADD_CYCLE(2); + break; + case 0x78: // SEI + SEI(); + ADD_CYCLE(2); + break; + + // X^bNn + case 0x48: // PHA + PUSH( R.A ); + ADD_CYCLE(3); + break; + case 0x08: // PHP + PUSH( R.P | B_FLAG ); + ADD_CYCLE(3); + break; + case 0x68: // PLA (N-----Z-) + R.A = POP(); + SET_ZN_FLAG(R.A); + ADD_CYCLE(4); + break; + case 0x28: // PLP + R.P = POP() | R_FLAG; + ADD_CYCLE(4); + break; + + // ̑ + case 0x00: // BRK + BRK(); + ADD_CYCLE(7); + break; + + case 0xEA: // NOP + ADD_CYCLE(2); + break; + + // JߌQ + case 0x0B: // ANC #$?? + case 0x2B: // ANC #$?? + MR_IM(); ANC(); + ADD_CYCLE(2); + break; + + case 0x8B: // ANE #$?? + MR_IM(); ANE(); + ADD_CYCLE(2); + break; + + case 0x6B: // ARR #$?? + MR_IM(); ARR(); + ADD_CYCLE(2); + break; + + case 0x4B: // ASR #$?? + MR_IM(); ASR(); + ADD_CYCLE(2); + break; + + case 0xC7: // DCP $?? + MR_ZP(); DCP(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xD7: // DCP $??,X + MR_ZX(); DCP(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0xCF: // DCP $???? + MR_AB(); DCP(); MW_EA(); + ADD_CYCLE(6); + break; + case 0xDF: // DCP $????,X + MR_AX(); DCP(); MW_EA(); + ADD_CYCLE(7); + break; + case 0xDB: // DCP $????,Y + MR_AY(); DCP(); MW_EA(); + ADD_CYCLE(7); + break; + case 0xC3: // DCP ($??,X) + MR_IX(); DCP(); MW_EA(); + ADD_CYCLE(8); + break; + case 0xD3: // DCP ($??),Y + MR_IY(); DCP(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0xE7: // ISB $?? + MR_ZP(); ISB(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xF7: // ISB $??,X + MR_ZX(); ISB(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0xEF: // ISB $???? + MR_AB(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xFF: // ISB $????,X + MR_AX(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xFB: // ISB $????,Y + MR_AY(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xE3: // ISB ($??,X) + MR_IX(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + case 0xF3: // ISB ($??),Y + MR_IY(); ISB(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0xBB: // LAS $????,Y + MR_AY(); LAS(); CHECK_EA(); + ADD_CYCLE(4); + break; + + + case 0xA7: // LAX $?? + MR_ZP(); LAX(); + ADD_CYCLE(3); + break; + case 0xB7: // LAX $??,Y + MR_ZY(); LAX(); + ADD_CYCLE(4); + break; + case 0xAF: // LAX $???? + MR_AB(); LAX(); + ADD_CYCLE(4); + break; + case 0xBF: // LAX $????,Y + MR_AY(); LAX(); CHECK_EA(); + ADD_CYCLE(4); + break; + case 0xA3: // LAX ($??,X) + MR_IX(); LAX(); + ADD_CYCLE(6); + break; + case 0xB3: // LAX ($??),Y + MR_IY(); LAX(); CHECK_EA(); + ADD_CYCLE(5); + break; + + case 0xAB: // LXA #$?? + MR_IM(); LXA(); + ADD_CYCLE(2); + break; + + case 0x27: // RLA $?? + MR_ZP(); RLA(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x37: // RLA $??,X + MR_ZX(); RLA(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x2F: // RLA $???? + MR_AB(); RLA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x3F: // RLA $????,X + MR_AX(); RLA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x3B: // RLA $????,Y + MR_AY(); RLA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x23: // RLA ($??,X) + MR_IX(); RLA(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x33: // RLA ($??),Y + MR_IY(); RLA(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x67: // RRA $?? + MR_ZP(); RRA(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x77: // RRA $??,X + MR_ZX(); RRA(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x6F: // RRA $???? + MR_AB(); RRA(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x7F: // RRA $????,X + MR_AX(); RRA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x7B: // RRA $????,Y + MR_AY(); RRA(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x63: // RRA ($??,X) + MR_IX(); RRA(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x73: // RRA ($??),Y + MR_IY(); RRA(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x87: // SAX $?? + MR_ZP(); SAX(); MW_ZP(); + ADD_CYCLE(3); + break; + case 0x97: // SAX $??,Y + MR_ZY(); SAX(); MW_ZP(); + ADD_CYCLE(4); + break; + case 0x8F: // SAX $???? + MR_AB(); SAX(); MW_EA(); + ADD_CYCLE(4); + break; + case 0x83: // SAX ($??,X) + MR_IX(); SAX(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0xCB: // SBX #$?? + MR_IM(); SBX(); + ADD_CYCLE(2); + break; + + case 0x9F: // SHA $????,Y + MR_AY(); SHA(); MW_EA(); + ADD_CYCLE(5); + break; + case 0x93: // SHA ($??),Y + MR_IY(); SHA(); MW_EA(); + ADD_CYCLE(6); + break; + + case 0x9B: // SHS $????,Y + MR_AY(); SHS(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x9E: // SHX $????,Y + MR_AY(); SHX(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x9C: // SHY $????,X + MR_AX(); SHY(); MW_EA(); + ADD_CYCLE(5); + break; + + case 0x07: // SLO $?? + MR_ZP(); SLO(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x17: // SLO $??,X + MR_ZX(); SLO(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x0F: // SLO $???? + MR_AB(); SLO(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x1F: // SLO $????,X + MR_AX(); SLO(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x1B: // SLO $????,Y + MR_AY(); SLO(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x03: // SLO ($??,X) + MR_IX(); SLO(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x13: // SLO ($??),Y + MR_IY(); SLO(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0x47: // SRE $?? + MR_ZP(); SRE(); MW_ZP(); + ADD_CYCLE(5); + break; + case 0x57: // SRE $??,X + MR_ZX(); SRE(); MW_ZP(); + ADD_CYCLE(6); + break; + case 0x4F: // SRE $???? + MR_AB(); SRE(); MW_EA(); + ADD_CYCLE(6); + break; + case 0x5F: // SRE $????,X + MR_AX(); SRE(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x5B: // SRE $????,Y + MR_AY(); SRE(); MW_EA(); + ADD_CYCLE(7); + break; + case 0x43: // SRE ($??,X) + MR_IX(); SRE(); MW_EA(); + ADD_CYCLE(8); + break; + case 0x53: // SRE ($??),Y + MR_IY(); SRE(); MW_EA(); + ADD_CYCLE(8); + break; + + case 0xEB: // SBC #$?? (Unofficial) + MR_IM(); SBC(); + ADD_CYCLE(2); + break; + + case 0x1A: // NOP (Unofficial) + case 0x3A: // NOP (Unofficial) + case 0x5A: // NOP (Unofficial) + case 0x7A: // NOP (Unofficial) + case 0xDA: // NOP (Unofficial) + case 0xFA: // NOP (Unofficial) + ADD_CYCLE(2); + break; + case 0x80: // DOP (CYCLES 2) + case 0x82: // DOP (CYCLES 2) + case 0x89: // DOP (CYCLES 2) + case 0xC2: // DOP (CYCLES 2) + case 0xE2: // DOP (CYCLES 2) + R.PC++; + ADD_CYCLE(2); + break; + case 0x04: // DOP (CYCLES 3) + case 0x44: // DOP (CYCLES 3) + case 0x64: // DOP (CYCLES 3) + R.PC++; + ADD_CYCLE(3); + break; + case 0x14: // DOP (CYCLES 4) + case 0x34: // DOP (CYCLES 4) + case 0x54: // DOP (CYCLES 4) + case 0x74: // DOP (CYCLES 4) + case 0xD4: // DOP (CYCLES 4) + case 0xF4: // DOP (CYCLES 4) + R.PC++; + ADD_CYCLE(4); + break; + case 0x0C: // TOP + case 0x1C: // TOP + case 0x3C: // TOP + case 0x5C: // TOP + case 0x7C: // TOP + case 0xDC: // TOP + case 0xFC: // TOP + R.PC+=2; + ADD_CYCLE(4); + break; + + case 0x02: /* JAM */ + case 0x12: /* JAM */ + case 0x22: /* JAM */ + case 0x32: /* JAM */ + case 0x42: /* JAM */ + case 0x52: /* JAM */ + case 0x62: /* JAM */ + case 0x72: /* JAM */ + case 0x92: /* JAM */ + case 0xB2: /* JAM */ + case 0xD2: /* JAM */ + case 0xF2: /* JAM */ + default: + if( !Config.emulator.bIllegalOp ) { + throw CApp::GetErrorString( IDS_ERROR_ILLEGALOPCODE ); + goto _execute_exit; + } else { + R.PC--; + ADD_CYCLE(4); + } + break; +// default: +// __assume(0); + } + + + if( nmi_request ) { + _NMI(); + } + + request_cycles -= exec_cycles; + TOTAL_cycles += exec_cycles; + + // NbN + mapper->Clock( exec_cycles ); +#if DPCM_SYNCCLOCK + apu->SyncDPCM( exec_cycles ); +#endif + if( bClockProcess ) { + nes->Clock( exec_cycles ); + } +// nes->Clock( exec_cycles ); + } +_execute_exit: + +#if !DPCM_SYNCCLOCK + apu->SyncDPCM( TOTAL_cycles - OLD_cycles ); +#endif + + return TOTAL_cycles - OLD_cycles; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Cpu_old.h b/References/VirtuaNESex_src_191105/NES/Cpu_old.h new file mode 100644 index 00000000..8de10c77 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Cpu_old.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// // +// 6502 CPU core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __CPU_INCLUDED__ +#define __CPU_INCLUDED__ + +#include "typedef.h" +#include "macro.h" + +extern WORD PC_N; + +class NES; +class APU; +class Mapper; + +// 6502 status flags +#define C_FLAG 0x01 // 1: Carry +#define Z_FLAG 0x02 // 1: Zero +#define I_FLAG 0x04 // 1: Irq disabled +#define D_FLAG 0x08 // 1: Decimal mode flag (NES unused) +#define B_FLAG 0x10 // 1: Break +#define R_FLAG 0x20 // 1: Reserved (Always 1) +#define V_FLAG 0x40 // 1: Overflow +#define N_FLAG 0x80 // 1: Negative + +// Interrupt +#define NMI_FLAG 0x01 +#define IRQ_FLAG 0x02 + +#define IRQ_FRAMEIRQ 0x04 +#define IRQ_DPCM 0x08 +#define IRQ_MAPPER 0x10 +#define IRQ_MAPPER2 0x20 +#define IRQ_TRIGGER 0x40 // one shot(IRQ()) +#define IRQ_TRIGGER2 0x80 // one shot(IRQ_NotPending()) + +#define IRQ_MASK (~(NMI_FLAG|IRQ_FLAG)) + +// Vector +#define NMI_VECTOR 0xFFFA +#define RES_VECTOR 0xFFFC +#define IRQ_VECTOR 0xFFFE + +// 6502 context +typedef struct { + WORD PC; /* Program counter */ + BYTE A; /* CPU registers */ + BYTE P; + BYTE X; + BYTE Y; + BYTE S; + + BYTE INT_pending; // 荞݃yfBOtO +} R6502; + + +class CPU +{ +public: + CPU( NES* parent ); + virtual ~CPU(); + + BYTE RD6502( WORD addr ); + void WR6502( WORD addr, BYTE data ); + WORD RD6502W( WORD addr ); + + void Reset(); + + void NMI(); + void SetIRQ( BYTE mask ); + void ClrIRQ( BYTE mask ); + + void DMA( INT cycles ); + + INT EXEC( INT request_cycles ); + + INT GetDmaCycles(); + void SetDmaCycles( INT cycles ); + + INT GetTotalCycles(); + void SetTotalCycles( INT cycles ); + + void SetContext( R6502 r ) { R = r; } + void GetContext( R6502& r ) { r = R; } + + void SetClockProcess( BOOL bEnable ) { m_bClockProcess = bEnable; } + int dasm6502(int *dasmpc, int *bcc_pc, char *obuf); +protected: + NES* nes; + APU* apu; + Mapper* mapper; + + R6502 R; + + INT TOTAL_cycles; // CPUg[^TCN + INT DMA_cycles; // DMATCN + + // PTR + LPBYTE STACK; + + // Zero & Negative table + BYTE ZN_Table[256]; + + // Clock process + BOOL m_bClockProcess; +private: +}; + +#endif // !__CPU_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/MMU.cpp b/References/VirtuaNESex_src_191105/NES/MMU.cpp new file mode 100644 index 00000000..dcc7ec96 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/MMU.cpp @@ -0,0 +1,467 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES Memory Management Unit // +// Norix // +// written 2001/02/21 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#define WIN32_LEAN_AND_MEAN +#include +#include "typedef.h" +#include "macro.h" +#include "DebugOut.h" + +#include "mmu.h" + +BYTE nnn; + +// CPU oN +LPBYTE CPU_MEM_BANK[8]; // 8KP +BYTE CPU_MEM_TYPE[8]; +INT CPU_MEM_PAGE[8]; // Xe[gZ[up + +// PPU oN +LPBYTE PPU_MEM_BANK[12]; // 1KP +BYTE PPU_MEM_TYPE[12]; +INT PPU_MEM_PAGE[12]; // Xe[gZ[up +BYTE CRAM_USED[16]; // Xe[gZ[up +PBYTE VROM_WRITED; // for mapper 74 + +// NES +BYTE RAM [ 8*1024]; // NESRAM +BYTE WRAM[128*1024]; // [N/obNAbvRAM +BYTE DRAM[ 40*1024]; // fBXNVXeRAM +BYTE XRAM[ 8*1024]; // _~[oN +BYTE ERAM[ 32*1024]; // g@pRAM + +BYTE VRAM[ 4*1024]; // l[e[u/Agr[gRAM +BYTE CRAM[ 32*1024]; // LN^p^[RAM + +BYTE YWRAM[1024*1024]; // for YuXing 98/F 1024K PRam +BYTE YSRAM[ 32*1024]; // for YuXing 98/F 32K SRam +BYTE YCRAM[ 128*1024]; // for YuXing 98/F 128K CRam + +BYTE BDRAM[ 512*1024]; // for BBK 512K PRam +BYTE BSRAM[ 32*1024]; // for BBK 32K SRam +BYTE BCRAM[ 512*1024]; // for BBK 512K CRam + +BYTE JDRAM[ 512*1024]; // for DrPCJr 512K PRam +BYTE JSRAM[ 8*1024]; // for DrPCJr 8K SRam +BYTE JCRAM[ 512*1024]; // for DrPCJr 512K CRam + +BYTE tempRAM[ 4*1024]; + +BYTE WAVRAM[256]; + +BYTE SPRAM[0x100]; // XvCgRAM +BYTE BGPAL[0x10]; // BGpbg +BYTE SPPAL[0x10]; // SPpbg + +// WX^ +BYTE CPUREG[0x18]; // Nes $4000-$4017 +BYTE PPUREG[0x04]; // Nes $2000-$2003 + +// Frame-IRQWX^($4017) +BYTE FrameIRQ; + +// PPUWX^ +BYTE PPU56Toggle; // $2005-$2006 Toggle +BYTE PPU7_Temp; // $2007 read buffer +WORD loopy_t; // same as $2005/$2006 +WORD loopy_v; // same as $2005/$2006 +WORD loopy_x; // tile x offset + +// ROMf[^|C^ +LPBYTE PROM; // PROM ptr +LPBYTE VROM; // VROM ptr + +// For dis... +LPBYTE PROM_ACCESS = NULL; + +// ROM oNTCY +INT PROM_8K_SIZE, PROM_16K_SIZE, PROM_32K_SIZE; +INT VROM_1K_SIZE, VROM_2K_SIZE, VROM_4K_SIZE, VROM_8K_SIZE; + +// +// S/WX^̏ +// +void NesSub_MemoryInitial() +{ +INT i; + + // NA + ZEROMEMORY( RAM, sizeof(RAM) ); + ZEROMEMORY( WRAM, sizeof(WRAM) ); + ZEROMEMORY( DRAM, sizeof(DRAM) ); + ZEROMEMORY( ERAM, sizeof(ERAM) ); + ZEROMEMORY( XRAM, sizeof(XRAM) ); + ZEROMEMORY( CRAM, sizeof(CRAM) ); + ZEROMEMORY( VRAM, sizeof(VRAM) ); + + ZEROMEMORY( YWRAM, sizeof(YWRAM) ); + ZEROMEMORY( YSRAM, sizeof(YSRAM) ); + ZEROMEMORY( YCRAM, sizeof(YCRAM) ); + + ZEROMEMORY( BDRAM, sizeof(BDRAM) ); + ZEROMEMORY( BSRAM, sizeof(BSRAM) ); + ZEROMEMORY( BCRAM, sizeof(BCRAM) ); + + ZEROMEMORY( JDRAM, sizeof(JDRAM) ); + ZEROMEMORY( JSRAM, sizeof(JSRAM) ); + ZEROMEMORY( JCRAM, sizeof(JCRAM) ); + + ZEROMEMORY( SPRAM, sizeof(SPRAM) ); + ZEROMEMORY( BGPAL, sizeof(BGPAL) ); + ZEROMEMORY( SPPAL, sizeof(SPPAL) ); + + ZEROMEMORY( CPUREG, sizeof(CPUREG) ); + ZEROMEMORY( PPUREG, sizeof(PPUREG) ); + + FrameIRQ = 0xC0; + + PROM = VROM = NULL; + + // 0 Zh~΍ + PROM_8K_SIZE = PROM_16K_SIZE = PROM_32K_SIZE = 1; + VROM_1K_SIZE = VROM_2K_SIZE = VROM_4K_SIZE = VROM_8K_SIZE = 1; + + // ftHgoNݒ + for( i = 0; i < 8; i++ ) { + CPU_MEM_BANK[i] = NULL; + CPU_MEM_TYPE[i] = BANKTYPE_ROM; + CPU_MEM_PAGE[i] = 0; + } + + // RAM/WRAM + SetPROM_Bank( 0, RAM, BANKTYPE_RAM ); + SetPROM_Bank( 3, WRAM, BANKTYPE_RAM ); + + // _~[ + SetPROM_Bank( 1, XRAM, BANKTYPE_ROM ); + SetPROM_Bank( 2, XRAM, BANKTYPE_ROM ); + + for( i = 0; i < 8; i++ ) { + CRAM_USED[i] = 0; + } + VROM_WRITED = CRAM+28*1024; + + // PPU VROMoNݒ +// SetVRAM_Mirror( VRAM_MIRROR4 ); +} + +// CPU ROM bank +void SetPROM_Bank( BYTE page, LPBYTE ptr, BYTE type ) +{ + CPU_MEM_BANK[page] = ptr; + CPU_MEM_TYPE[page] = type; + CPU_MEM_PAGE[page] = 0; +} + +void SetPROM_8K_Bank( BYTE page, INT bank ) +{ + bank %= PROM_8K_SIZE; + CPU_MEM_BANK[page] = PROM+0x2000*bank; + CPU_MEM_TYPE[page] = BANKTYPE_ROM; + CPU_MEM_PAGE[page] = bank; +} + +void SetPROM_16K_Bank( BYTE page, INT bank ) +{ + SetPROM_8K_Bank( page+0, bank*2+0 ); + SetPROM_8K_Bank( page+1, bank*2+1 ); +} + +void SetPROM_32K_Bank( INT bank ) +{ + SetPROM_8K_Bank( 4, bank*4+0 ); + SetPROM_8K_Bank( 5, bank*4+1 ); + SetPROM_8K_Bank( 6, bank*4+2 ); + SetPROM_8K_Bank( 7, bank*4+3 ); +} + +void SetPROM_32K_Bank( INT bank0, INT bank1, INT bank2, INT bank3 ) +{ + SetPROM_8K_Bank( 4, bank0 ); + SetPROM_8K_Bank( 5, bank1 ); + SetPROM_8K_Bank( 6, bank2 ); + SetPROM_8K_Bank( 7, bank3 ); +} + +// PPU VROM bank +void SetVROM_Bank( BYTE page, LPBYTE ptr, BYTE type ) +{ + PPU_MEM_BANK[page] = ptr; + PPU_MEM_TYPE[page] = type; + PPU_MEM_PAGE[page] = 0; +} + +void SetVROM_1K_Bank( BYTE page, INT bank ) +{ + bank %= VROM_1K_SIZE; + PPU_MEM_BANK[page] = VROM+0x0400*bank; + PPU_MEM_TYPE[page] = BANKTYPE_VROM; + PPU_MEM_PAGE[page] = bank; +} + +void SetVROM_2K_Bank( BYTE page, INT bank ) +{ + SetVROM_1K_Bank( page+0, bank*2+0 ); + SetVROM_1K_Bank( page+1, bank*2+1 ); +} + +void SetVROM_4K_Bank( BYTE page, INT bank ) +{ + SetVROM_1K_Bank( page+0, bank*4+0 ); + SetVROM_1K_Bank( page+1, bank*4+1 ); + SetVROM_1K_Bank( page+2, bank*4+2 ); + SetVROM_1K_Bank( page+3, bank*4+3 ); +} + +void SetVROM_8K_Bank( INT bank ) +{ + for( INT i = 0; i < 8; i++ ) { + SetVROM_1K_Bank( i, bank*8+i ); + } +} + +void SetVROM_8K_Bank( INT bank0, INT bank1, INT bank2, INT bank3, + INT bank4, INT bank5, INT bank6, INT bank7 ) +{ + SetVROM_1K_Bank( 0, bank0 ); + SetVROM_1K_Bank( 1, bank1 ); + SetVROM_1K_Bank( 2, bank2 ); + SetVROM_1K_Bank( 3, bank3 ); + SetVROM_1K_Bank( 4, bank4 ); + SetVROM_1K_Bank( 5, bank5 ); + SetVROM_1K_Bank( 6, bank6 ); + SetVROM_1K_Bank( 7, bank7 ); +} + +void SetCRAM_1K_Bank( BYTE page, INT bank ) +{ + bank &= 0x1F; + PPU_MEM_BANK[page] = CRAM+0x0400*bank; + PPU_MEM_TYPE[page] = BANKTYPE_CRAM; + PPU_MEM_PAGE[page] = bank; + + CRAM_USED[bank>>2] = 0xFF; // CRAMgptO +} + +void SetCRAM_2K_Bank( BYTE page, INT bank ) +{ + SetCRAM_1K_Bank( page+0, bank*2+0 ); + SetCRAM_1K_Bank( page+1, bank*2+1 ); +} + +void SetCRAM_4K_Bank( BYTE page, INT bank ) +{ + SetCRAM_1K_Bank( page+0, bank*4+0 ); + SetCRAM_1K_Bank( page+1, bank*4+1 ); + SetCRAM_1K_Bank( page+2, bank*4+2 ); + SetCRAM_1K_Bank( page+3, bank*4+3 ); +} + +void SetCRAM_8K_Bank( INT bank ) +{ + for( INT i = 0; i < 8; i++ ) { + SetCRAM_1K_Bank( i, bank*8+i ); // fix + } +} + +void SetVRAM_1K_Bank( BYTE page, INT bank ) +{ + bank &= 3; + PPU_MEM_BANK[page] = VRAM+0x0400*bank; + PPU_MEM_TYPE[page] = BANKTYPE_VRAM; + PPU_MEM_PAGE[page] = bank; +} + +void SetVRAM_Bank( INT bank0, INT bank1, INT bank2, INT bank3 ) +{ + SetVRAM_1K_Bank( 8, bank0 ); + SetVRAM_1K_Bank( 9, bank1 ); + SetVRAM_1K_Bank( 10, bank2 ); + SetVRAM_1K_Bank( 11, bank3 ); +} + +void SetVRAM_Mirror( INT type ) +{ + switch( type ) { + case VRAM_HMIRROR: + SetVRAM_Bank( 0, 0, 1, 1 ); + break; + case VRAM_VMIRROR: + SetVRAM_Bank( 0, 1, 0, 1 ); + break; + case VRAM_MIRROR4L: + SetVRAM_Bank( 0, 0, 0, 0 ); + break; + case VRAM_MIRROR3H: + SetVRAM_Bank( 0, 1, 1, 1 ); + break; + case VRAM_MIRROR4H: + SetVRAM_Bank( 1, 1, 1, 1 ); + break; + case VRAM_MIRROR4: + SetVRAM_Bank( 0, 1, 2, 3 ); + break; + } +} + +void SetVRAM_Mirror( INT bank0, INT bank1, INT bank2, INT bank3 ) +{ + SetVRAM_1K_Bank( 8, bank0 ); + SetVRAM_1K_Bank( 9, bank1 ); + SetVRAM_1K_Bank( 10, bank2 ); + SetVRAM_1K_Bank( 11, bank3 ); +} + +// for YuXing 98/F 1024K PRam +void SetYWRAM_8K_Bank( BYTE page, INT bank ) +{ + bank %= 0x80; + CPU_MEM_BANK[page] = YWRAM+0x2000*bank; + CPU_MEM_TYPE[page] = BANKTYPE_RAM; + CPU_MEM_PAGE[page] = bank; +} +void SetYWRAM_16K_Bank( BYTE page, INT bank ) +{ + SetYWRAM_8K_Bank( page+0, bank*2+0 ); + SetYWRAM_8K_Bank( page+1, bank*2+1 ); +} +void SetYWRAM_32K_Bank( INT bank ) +{ + SetYWRAM_8K_Bank( 4, bank*4+0 ); + SetYWRAM_8K_Bank( 5, bank*4+1 ); + SetYWRAM_8K_Bank( 6, bank*4+2 ); + SetYWRAM_8K_Bank( 7, bank*4+3 ); +} +void SetYWRAM_32K_Bank( INT bank0, INT bank1, INT bank2, INT bank3 ) +{ + SetYWRAM_8K_Bank( 4, bank0 ); + SetYWRAM_8K_Bank( 5, bank1 ); + SetYWRAM_8K_Bank( 6, bank2 ); + SetYWRAM_8K_Bank( 7, bank3 ); +} + +// for YuXing 98/F 128K CRam +// Up for CoolBoy 256K +void SetYCRAM_1K_Bank( BYTE page, INT bank ) +{ +// bank &= 0x7F; + bank &= 0xFF; + PPU_MEM_BANK[page] = YCRAM+0x0400*bank; + PPU_MEM_TYPE[page] = BANKTYPE_YCRAM; + PPU_MEM_PAGE[page] = bank; +} +void SetYCRAM_2K_Bank( BYTE page, INT bank ) +{ + SetYCRAM_1K_Bank( page+0, bank*2+0 ); + SetYCRAM_1K_Bank( page+1, bank*2+1 ); +} +void SetYCRAM_4K_Bank( BYTE page, INT bank ) +{ + SetYCRAM_1K_Bank( page+0, bank*4+0 ); + SetYCRAM_1K_Bank( page+1, bank*4+1 ); + SetYCRAM_1K_Bank( page+2, bank*4+2 ); + SetYCRAM_1K_Bank( page+3, bank*4+3 ); +} +void SetYCRAM_8K_Bank( INT bank ) +{ + for( INT i = 0; i < 8; i++ ) { + SetYCRAM_1K_Bank( i, bank*8+i ); + } +} + +// +void SetBDRAM_8K_Bank( BYTE page, INT bank ) +{ + bank %= 0x40; + CPU_MEM_BANK[page] = BDRAM+0x2000*bank; + CPU_MEM_TYPE[page] = BANKTYPE_RAM; + CPU_MEM_PAGE[page] = bank; +} +void SetBDRAM_16K_Bank( BYTE page, INT bank ) +{ + SetBDRAM_8K_Bank( page+0, bank*2+0 ); + SetBDRAM_8K_Bank( page+1, bank*2+1 ); +} +void SetBDRAM_32K_Bank( INT bank ) +{ + SetBDRAM_8K_Bank( 4, bank*4+0 ); + SetBDRAM_8K_Bank( 5, bank*4+1 ); + SetBDRAM_8K_Bank( 6, bank*4+2 ); + SetBDRAM_8K_Bank( 7, bank*4+3 ); +} + +//------------------------------------------------------------ + +void SetJDRAM_8K_Bank( BYTE page, INT bank ) +{ + bank %= 0x40; + CPU_MEM_BANK[page] = JDRAM+0x2000*bank; + CPU_MEM_TYPE[page] = BANKTYPE_RAM; + CPU_MEM_PAGE[page] = bank; +} +void SetJDRAM_32K_Bank( INT bank ) +{ + SetJDRAM_8K_Bank( 3, bank*4+0 ); + SetJDRAM_8K_Bank( 4, bank*4+1 ); + SetJDRAM_8K_Bank( 5, bank*4+2 ); + SetJDRAM_8K_Bank( 6, bank*4+3 ); +} + +void SetJCRAM_1K_Bank( BYTE page, INT bank ) +{ + bank %= 0x200; + PPU_MEM_BANK[page] = JCRAM+0x0400*bank; + PPU_MEM_TYPE[page] = BANKTYPE_JCRAM; + PPU_MEM_PAGE[page] = bank; +} +void SetJCRAM_2K_Bank( BYTE page, INT bank ) +{ + SetJCRAM_1K_Bank( page+0, bank*2+0 ); + SetJCRAM_1K_Bank( page+1, bank*2+1 ); +} +void SetJCRAM_4K_Bank( BYTE page, INT bank ) +{ + SetJCRAM_1K_Bank( page+0, bank*4+0 ); + SetJCRAM_1K_Bank( page+1, bank*4+1 ); + SetJCRAM_1K_Bank( page+2, bank*4+2 ); + SetJCRAM_1K_Bank( page+3, bank*4+3 ); +} +void SetJCRAM_8K_Bank( INT bank ) +{ + for( INT i = 0; i < 8; i++ ) { + SetJCRAM_1K_Bank( i, bank*8+i ); + } +} +void SetJCRAM_8K_Bank( INT bank0, INT bank1, INT bank2, INT bank3, + INT bank4, INT bank5, INT bank6, INT bank7 ) +{ + SetJCRAM_1K_Bank( 0, bank0 ); + SetJCRAM_1K_Bank( 1, bank1 ); + SetJCRAM_1K_Bank( 2, bank2 ); + SetJCRAM_1K_Bank( 3, bank3 ); + SetJCRAM_1K_Bank( 4, bank4 ); + SetJCRAM_1K_Bank( 5, bank5 ); + SetJCRAM_1K_Bank( 6, bank6 ); + SetJCRAM_1K_Bank( 7, bank7 ); +} + +void SetOBCRAM_1K_Bank( BYTE page, INT bank ) +{ + bank %= (PROM_8K_SIZE*8); + PPU_MEM_BANK[page] = PROM+0x0400*bank; + PPU_MEM_TYPE[page] = BANKTYPE_ROM; + PPU_MEM_PAGE[page] = bank; +} + +void SetPROM_4K_Bank( WORD addr, INT bank ) +{ + bank %= (PROM_8K_SIZE*2); + memcpy( &CPU_MEM_BANK[addr>>13][addr&0x1FFF], PROM+0x1000*bank, 0x1000); +// memcpy( &CPU_MEM_BANK[addr>>13][addr&0x1FFF], YSRAM+0x1000*bank, 0x1000); + CPU_MEM_TYPE[addr>>13] = BANKTYPE_ROM; + CPU_MEM_PAGE[addr>>13] = 0; +} diff --git a/References/VirtuaNESex_src_191105/NES/MMU.h b/References/VirtuaNESex_src_191105/NES/MMU.h new file mode 100644 index 00000000..ab334de6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/MMU.h @@ -0,0 +1,165 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES Memory Management Unit // +// Norix // +// written 2001/02/21 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// + +#ifndef __MMU_INCLUDED__ +#define __MMU_INCLUDED__ + +#include "typedef.h" +#include "macro.h" + +extern BYTE nnn; + +// CPU oN +extern LPBYTE CPU_MEM_BANK[8]; // 8KP +extern BYTE CPU_MEM_TYPE[8]; +extern INT CPU_MEM_PAGE[8]; // Xe[gZ[up + +// PPU oN +extern LPBYTE PPU_MEM_BANK[12]; // 1KP +extern BYTE PPU_MEM_TYPE[12]; +extern INT PPU_MEM_PAGE[12]; // Xe[gZ[up +extern BYTE CRAM_USED[16]; // Xe[gZ[up +extern PBYTE VROM_WRITED; // for mapper 74 + +// NES +extern BYTE RAM [ 8*1024]; // NESRAM +extern BYTE WRAM[128*1024]; // [N/obNAbvRAM +extern BYTE DRAM[ 40*1024]; // fBXNVXeRAM +extern BYTE XRAM[ 8*1024]; // _~[oN +extern BYTE ERAM[ 32*1024]; // g@pRAM + +extern BYTE VRAM[ 4*1024]; // l[e[u/Agr[gRAM +extern BYTE CRAM[ 32*1024]; // LN^p^[RAM + +extern BYTE YWRAM[1024*1024]; // for YuXing 98/F 1024K PRam +extern BYTE YSRAM[ 32*1024]; // for YuXing 98/F 32K SRam +extern BYTE YCRAM[ 128*1024]; // for YuXing 98/F 128K CRam + +extern BYTE BDRAM[ 512*1024]; // for BBK 512K PRam +extern BYTE BSRAM[ 32*1024]; // for BBK 32K SRam +extern BYTE BCRAM[ 512*1024]; // for BBK 512K CRam + +extern BYTE JDRAM[ 512*1024]; // for DrPCJr 512K PRam +extern BYTE JSRAM[ 8*1024]; // for DrPCJr 8K SRam +extern BYTE JCRAM[ 512*1024]; // for DrPCJr 512K CRam + +extern BYTE tempRAM[ 4*1024]; + +extern BYTE WAVRAM[256]; + +extern BYTE SPRAM[0x100]; // XvCgRAM +extern BYTE BGPAL[0x10]; // BGpbg +extern BYTE SPPAL[0x10]; // SPpbg + +// WX^ +extern BYTE CPUREG[0x18]; // Nes $4000-$4017 +extern BYTE PPUREG[0x04]; // Nes $2000-$2003 + +// Frame-IRQWX^($4017) +extern BYTE FrameIRQ; + +// PPUWX^ +extern BYTE PPU56Toggle; // $2005-$2006 Toggle +extern BYTE PPU7_Temp; // $2007 read buffer +extern WORD loopy_t; // same as $2005/$2006 +extern WORD loopy_v; // same as $2005/$2006 +extern WORD loopy_x; // tile x offset + +// ROMf[^|C^ +extern LPBYTE PROM; // PROM ptr +extern LPBYTE VROM; // VROM ptr + +#ifdef _DATATRACE +// For dis... +extern LPBYTE PROM_ACCESS; +#endif + +// ROM oNTCY +extern INT PROM_8K_SIZE, PROM_16K_SIZE, PROM_32K_SIZE; +extern INT VROM_1K_SIZE, VROM_2K_SIZE, VROM_4K_SIZE, VROM_8K_SIZE; + + +// ֐ +extern void NesSub_MemoryInitial(); + +extern void SetPROM_Bank( BYTE page, LPBYTE ptr, BYTE type ); +extern void SetPROM_8K_Bank ( BYTE page, INT bank ); +extern void SetPROM_16K_Bank( BYTE page, INT bank ); +extern void SetPROM_32K_Bank( INT bank ); +extern void SetPROM_32K_Bank( INT bank0, INT bank1, INT bank2, INT bank3 ); + +extern void SetVROM_Bank( BYTE page, LPBYTE ptr, BYTE type ); +extern void SetVROM_1K_Bank( BYTE page, INT bank ); +extern void SetVROM_2K_Bank( BYTE page, INT bank ); +extern void SetVROM_4K_Bank( BYTE page, INT bank ); +extern void SetVROM_8K_Bank( INT bank ); +extern void SetVROM_8K_Bank( INT bank0, INT bank1, INT bank2, INT bank3, + INT bank4, INT bank5, INT bank6, INT bank7 ); + +extern void SetCRAM_1K_Bank( BYTE page, INT bank ); +extern void SetCRAM_2K_Bank( BYTE page, INT bank ); +extern void SetCRAM_4K_Bank( BYTE page, INT bank ); +extern void SetCRAM_8K_Bank( INT bank ); + +extern void SetVRAM_1K_Bank( BYTE page, INT bank ); +extern void SetVRAM_Bank( INT bank0, INT bank1, INT bank2, INT bank3 ); +extern void SetVRAM_Mirror( INT type ); +extern void SetVRAM_Mirror( INT bank0, INT bank1, INT bank2, INT bank3 ); + +// for YuXing 98/F 1024K PRam +extern void SetYWRAM_8K_Bank ( BYTE page, INT bank ); +extern void SetYWRAM_16K_Bank( BYTE page, INT bank ); +extern void SetYWRAM_32K_Bank( INT bank ); +extern void SetYWRAM_32K_Bank( INT bank0, INT bank1, INT bank2, INT bank3 ); +// for YuXing 98/F 128K CRam +extern void SetYCRAM_1K_Bank( BYTE page, INT bank ); +extern void SetYCRAM_2K_Bank( BYTE page, INT bank ); +extern void SetYCRAM_4K_Bank( BYTE page, INT bank ); +extern void SetYCRAM_8K_Bank( INT bank ); + +extern void SetBDRAM_8K_Bank( BYTE page, INT bank ); +extern void SetBDRAM_16K_Bank( BYTE page, INT bank ); +extern void SetBDRAM_32K_Bank( INT bank ); + +extern void SetPROM_4K_Bank( WORD addr, INT bank ); + +extern void SetJCRAM_1K_Bank( BYTE page, INT bank ); +extern void SetJCRAM_2K_Bank( BYTE page, INT bank ); +extern void SetJCRAM_4K_Bank( BYTE page, INT bank ); +extern void SetJCRAM_8K_Bank( INT bank ); +extern void SetJCRAM_8K_Bank( INT bank0, INT bank1, INT bank2, INT bank3, + INT bank4, INT bank5, INT bank6, INT bank7 ); +extern void SetJDRAM_8K_Bank ( BYTE page, INT bank ); +extern void SetJDRAM_32K_Bank( INT bank ); + +extern void SetOBCRAM_1K_Bank( BYTE page, INT bank ); + + +// ^Cv +// For PROM (CPU) +#define BANKTYPE_ROM 0x00 +#define BANKTYPE_RAM 0xFF +#define BANKTYPE_DRAM 0x01 +#define BANKTYPE_MAPPER 0x80 +// For VROM/VRAM/CRAM (PPU) +#define BANKTYPE_VROM 0x00 +#define BANKTYPE_CRAM 0x01 +#define BANKTYPE_YCRAM 0x02 +#define BANKTYPE_JCRAM 0x03 +#define BANKTYPE_VRAM 0x80 + +// ~[^Cv +#define VRAM_HMIRROR 0x00 // Horizontal +#define VRAM_VMIRROR 0x01 // Virtical +#define VRAM_MIRROR4 0x02 // All screen +#define VRAM_MIRROR4L 0x03 // PA10 LŒ $2000-$23FF̃~[ +#define VRAM_MIRROR4H 0x04 // PA10 HŒ $2400-$27FF̃~[ +#define VRAM_MIRROR3H 0x05 + +#endif // !__MMU_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardBS5.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardBS5.cpp new file mode 100644 index 00000000..89aa2a5e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardBS5.cpp @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// BoardBS5 ĺһ // +////////////////////////////////////////////////////////////////////////// +void BoardBS5::Reset() +{ + dip_s++; + if(dip_s==4) dip_s=0; + reg_prg[0] = reg_prg[1] = reg_prg[2] = reg_prg[3] = 0x0f; + reg_chr[0] = reg_chr[1] = reg_chr[2] = reg_chr[3] = 0x00; + SetVRAM_Mirror( VRAM_VMIRROR ); + SetBank(); +} + +void BoardBS5::Write( WORD addr, BYTE data ) +{ + int bank = (addr & 0xC00) >> 10; + switch (addr & 0xF000) { + case 0x8000: + reg_chr[bank] = addr & 0x1F; + break; + case 0xA000: + if (addr & (1 << ((dip_s&3)|4))) + reg_prg[bank] = addr & 0x0F; + break; + } + SetBank(); +} + +void BoardBS5::SetBank() +{ + SetPROM_8K_Bank(4, reg_prg[0]); + SetPROM_8K_Bank(5, reg_prg[1]); + SetPROM_8K_Bank(6, reg_prg[2]); + SetPROM_8K_Bank(7, reg_prg[3]); + SetVROM_2K_Bank(0, reg_chr[0]); + SetVROM_2K_Bank(2, reg_chr[1]); + SetVROM_2K_Bank(4, reg_chr[2]); + SetVROM_2K_Bank(6, reg_chr[3]); +} + +void BoardBS5::SaveState( LPBYTE p ) +{ + // +} + +void BoardBS5::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardBS5.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardBS5.h new file mode 100644 index 00000000..8c0d9909 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardBS5.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// BoardBS5 // +////////////////////////////////////////////////////////////////////////// +class BoardBS5 : public Mapper +{ +public: + BoardBS5( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg_prg[4], reg_chr[4]; + BYTE dip_s; +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardCityFighter.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCityFighter.cpp new file mode 100644 index 00000000..23e66949 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCityFighter.cpp @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// BoardCityFighter // +////////////////////////////////////////////////////////////////////////// +void BoardCityFighter::Reset() +{ + for(int n=0;n<8;n++) chr_reg[n] = 0x00; + prg_reg = 0; + prg_mode = 0; + mirr = 0; + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + SetBank(); +} + +void BoardCityFighter::Write( WORD addr, BYTE data ) +{ + switch (addr & 0xF00C) { + case 0x9000: prg_reg = data & 0xC; mirr = data & 3; break; + case 0x9004: + case 0x9008: + case 0x900C: + if (addr & 0x800) + nes->apu->Write(0x4011,(data&0xf)<<3); + else + prg_reg = data & 0xC; + break; + case 0xC000: + case 0xC004: + case 0xC008: + case 0xC00C: prg_mode = data & 1; break; + case 0xD000: chr_reg[0] = (chr_reg[0] & 0xF0) | (data & 0x0F); break; + case 0xD004: chr_reg[0] = (chr_reg[0] & 0x0F) | (data << 4); break; + case 0xD008: chr_reg[1] = (chr_reg[1] & 0xF0) | (data & 0x0F); break; + case 0xD00C: chr_reg[1] = (chr_reg[1] & 0x0F) | (data << 4); break; + case 0xA000: chr_reg[2] = (chr_reg[2] & 0xF0) | (data & 0x0F); break; + case 0xA004: chr_reg[2] = (chr_reg[2] & 0x0F) | (data << 4); break; + case 0xA008: chr_reg[3] = (chr_reg[3] & 0xF0) | (data & 0x0F); break; + case 0xA00C: chr_reg[3] = (chr_reg[3] & 0x0F) | (data << 4); break; + case 0xB000: chr_reg[4] = (chr_reg[4] & 0xF0) | (data & 0x0F); break; + case 0xB004: chr_reg[4] = (chr_reg[4] & 0x0F) | (data << 4); break; + case 0xB008: chr_reg[5] = (chr_reg[5] & 0xF0) | (data & 0x0F); break; + case 0xB00C: chr_reg[5] = (chr_reg[5] & 0x0F) | (data << 4); break; + case 0xE000: chr_reg[6] = (chr_reg[6] & 0xF0) | (data & 0x0F); break; + case 0xE004: chr_reg[6] = (chr_reg[6] & 0x0F) | (data << 4); break; + case 0xE008: chr_reg[7] = (chr_reg[7] & 0xF0) | (data & 0x0F); break; + case 0xE00C: chr_reg[7] = (chr_reg[7] & 0x0F) | (data << 4); break; + case 0xF000: irq_latch = (irq_latch & 0xF0) | (data & 0x0F); break; + case 0xF004: irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); break; + case 0xF008: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + default: + break; + } + SetBank(); +} + +void BoardCityFighter::SetBank() +{ + SetPROM_32K_Bank( prg_reg >> 2 ); + if (!prg_mode) SetPROM_8K_Bank(6, prg_reg); + for (int i = 0; i < 8; i++) SetVROM_1K_Bank(i, chr_reg[i]); + switch (mirr) { + case 0: SetVRAM_Mirror( VRAM_VMIRROR ); break; + case 1: SetVRAM_Mirror( VRAM_HMIRROR ); break; + case 2: SetVRAM_Mirror( VRAM_MIRROR4L ); break; + case 3: SetVRAM_Mirror( VRAM_MIRROR4H ); break; + } +} + +void BoardCityFighter::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock+=cycles) >= 0x72 ) { + irq_clock -= 0x72; + if( irq_counter == 0xFF ) { + irq_counter = irq_latch; + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } + } +} + +void BoardCityFighter::SaveState( LPBYTE p ) +{ + // +} + +void BoardCityFighter::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardCityFighter.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCityFighter.h new file mode 100644 index 00000000..cdf82bf3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCityFighter.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// BoardCityFighter // +////////////////////////////////////////////////////////////////////////// +class BoardCityFighter : public Mapper +{ +public: + BoardCityFighter( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE prg_reg, prg_mode, mirr; + BYTE chr_reg[8]; + BYTE irq_enable, irq_counter, irq_latch; + INT irq_clock; +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardCoolBoy.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCoolBoy.cpp new file mode 100644 index 00000000..5f027178 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCoolBoy.cpp @@ -0,0 +1,217 @@ +////////////////////////////////////////////////////////////////////////// +// BoardCoolBoy // +////////////////////////////////////////////////////////////////////////// + +//code by CaH4e3 from fceumm + +void BoardCoolBoy::Reset() +{ + if(!(VROM_8K_SIZE)) SetYCRAM_8K_Bank(0); + + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + IRQReload = IRQCount = IRQLatch = IRQa = 0; + MMC3cmd = A000B = A001B = 0; + + DRegBuf[0] = 0; + DRegBuf[1] = 2; + DRegBuf[2] = 4; + DRegBuf[3] = 5; + DRegBuf[4] = 6; + DRegBuf[5] = 7; + DRegBuf[6] = 0; + DRegBuf[7] = 1; + + FixCBMMC3PRG(MMC3cmd); + FixCBMMC3CHR(MMC3cmd); +} + +void BoardCoolBoy::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) XRAM[addr-0x4000] = data; + if(addr>=0x6000) + { + if(A001B&0x80) CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + if ((EXPREGS[3] & 0x90) != 0x80) { + EXPREGS[addr & 3] = data; + FixCBMMC3PRG(MMC3cmd); + FixCBMMC3CHR(MMC3cmd); + } + } +} + +void BoardCoolBoy::Write( WORD addr, BYTE data ) +{ + switch (addr & 0xE001) { + case 0x8000: + if ((data & 0x40) != (MMC3cmd & 0x40)) + FixCBMMC3PRG(data); + if ((data & 0x80) != (MMC3cmd & 0x80)) + FixCBMMC3CHR(data); + MMC3cmd = data; + break; + case 0x8001: + { + int cbase = (MMC3cmd & 0x80) << 5; + DRegBuf[MMC3cmd & 0x7] = data; + switch (MMC3cmd & 0x07) { + case 0: + PPUSW((cbase ^ 0x000), data & (~1)); + PPUSW((cbase ^ 0x400), data | 1); + break; + case 1: + PPUSW((cbase ^ 0x800), data & (~1)); + PPUSW((cbase ^ 0xC00), data | 1); + break; + case 2: + PPUSW(cbase ^ 0x1000, data); + break; + case 3: + PPUSW(cbase ^ 0x1400, data); + break; + case 4: + PPUSW(cbase ^ 0x1800, data); + break; + case 5: + PPUSW(cbase ^ 0x1C00, data); + break; + case 6: + if (MMC3cmd&0x40) CPUSW(0xC000, data); + else CPUSW(0x8000, data); + break; + case 7: + CPUSW(0xA000, data); + break; + } + break; + } + case 0xA000: + A000B = data; + if (!nes->rom->Is4SCREEN()) { + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + } + break; + case 0xA001: + A001B = data; + break; + case 0xC000: IRQReload = 0;IRQCount = data; break; + case 0xC001: IRQReload = 0;IRQLatch = data; break; + case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xE001: IRQReload = 0;IRQa = 1; break; + } + +} + +void BoardCoolBoy::PPUSW(WORD A, BYTE V) +{ + uint32 mask = 0xFF ^ (EXPREGS[0] & 0x80); + if (EXPREGS[3] & 0x10) { + if (EXPREGS[3] & 0x40) { + int cbase = (MMC3cmd & 0x80) << 5; + switch (cbase ^ A) { + case 0x0400: + case 0x0C00: V &= 0x7F; break; + } + } + SetYCRAM_1K_Bank(A>>10, + (V & 0x80 & mask) | ((((EXPREGS[0] & 0x08) << 4) & ~mask)) + | ((EXPREGS[2] & 0x0F) << 3) + | ((A >> 10) & 7) + ); + } else { + if (EXPREGS[3] & 0x40) { + int cbase = (MMC3cmd & 0x80) << 5; + switch (cbase ^ A) { + case 0x0000: V = DRegBuf[0]; break; + case 0x0800: V = DRegBuf[1]; break; + case 0x0400: + case 0x0C00: V = 0; break; + } + } + SetYCRAM_1K_Bank(A>>10, (V & mask) | (((EXPREGS[0] & 0x08) << 4) & ~mask)); + } +} + +void BoardCoolBoy::CPUSW(WORD A, BYTE V) +{ + uint32 mask = ((0x3F | (EXPREGS[1] & 0x40) | ((EXPREGS[1] & 0x20) << 2)) ^ ((EXPREGS[0] & 0x40) >> 2)) ^ ((EXPREGS[1] & 0x80) >> 2); + uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2); + + if ((EXPREGS[3] & 0x40) && (V >= 0xFE) && !((MMC3cmd & 0x40) != 0)) { + switch (A & 0xE000) { + case 0xA000: + if ((MMC3cmd & 0x40)) V = 0; + break; + case 0xC000: + if (!(MMC3cmd & 0x40)) V = 0; + break; + case 0xE000: + V = 0; + break; + } + } + + if (!(EXPREGS[3] & 0x10)) + SetPROM_8K_Bank(A>>13, (((base << 4) & ~mask)) | (V & mask)); + else { + mask &= 0xF0; + uint8 emask; + if ((((EXPREGS[1] & 2) != 0))) + emask = (EXPREGS[3] & 0x0C) | ((A & 0x4000) >> 13); + else + emask = EXPREGS[3] & 0x0E; + SetPROM_8K_Bank(A>>13, ((base << 4) & ~mask) + | (V & mask) + | emask + | ((A & 0x2000) >> 13)); + } +} + +void BoardCoolBoy::FixCBMMC3PRG(BYTE data) +{ + if (data & 0x40) { + CPUSW(0xC000, DRegBuf[6]); + CPUSW(0x8000, ~1); + } else { + CPUSW(0x8000, DRegBuf[6]); + CPUSW(0xC000, ~1); + } + CPUSW(0xA000, DRegBuf[7]); + CPUSW(0xE000, ~0); +} + +void BoardCoolBoy::FixCBMMC3CHR(BYTE data) +{ + int cbase = (data & 0x80) << 5; + PPUSW((cbase ^ 0x000), DRegBuf[0] & (~1)); + PPUSW((cbase ^ 0x400), DRegBuf[0] | 1); + PPUSW((cbase ^ 0x800), DRegBuf[1] & (~1)); + PPUSW((cbase ^ 0xC00), DRegBuf[1] | 1); + PPUSW(cbase ^ 0x1000, DRegBuf[2]); + PPUSW(cbase ^ 0x1400, DRegBuf[3]); + PPUSW(cbase ^ 0x1800, DRegBuf[4]); + PPUSW(cbase ^ 0x1c00, DRegBuf[5]); +} + +void BoardCoolBoy::HSync(INT scanline) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (IRQa && !IRQReload) { + if (scanline == 0) { + if (IRQCount) { + IRQCount -= 1; + } + } + if (!(IRQCount)){ + IRQReload = 0xFF; + IRQCount = IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + IRQCount--; + } + } + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardCoolBoy.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCoolBoy.h new file mode 100644 index 00000000..b6edc0c0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardCoolBoy.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// BoardCoolBoy // +////////////////////////////////////////////////////////////////////////// +class BoardCoolBoy : public Mapper +{ +public: + BoardCoolBoy( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync(INT scanline); + +protected: + BYTE EXPREGS[8]; + BYTE MMC3cmd; + BYTE DRegBuf[8]; + BYTE A000B, A001B; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; +private: + void PPUSW(WORD A, BYTE V); + void CPUSW(WORD A, BYTE V); + void FixCBMMC3PRG(BYTE data); + void FixCBMMC3CHR(BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardDragonFighter.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardDragonFighter.cpp new file mode 100644 index 00000000..f3dacf39 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardDragonFighter.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// BoardDragonFighter // +////////////////////////////////////////////////////////////////////////// + +void BoardDragonFighter::Reset() +{ + chr0 = chr1 = 0; + reg[0] = reg[1] = 0; + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_request = 0; + SetPROM_32K_Bank( 0, PROM_8K_SIZE-1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); +} + +BYTE BoardDragonFighter::ReadLow( WORD addr ) +{ + switch( addr ) { + case 0x6000: + SetVROM_4K_Bank( 4, RAM[0xFF]&0x3F ); + break; + case 0x6002: + SetVROM_4K_Bank( 4, RAM[0xFF]&0x3F ); + if(chr0){ + if(RAM[0x4F]==RAM[0x6A]) + SetVROM_2K_Bank( 0, ((reg[1]>>1)^RAM[0x4F]) ); + else + SetVROM_2K_Bank( 0, ((reg[1]>>1)^RAM[0x4F]) + 0x80 ); + } + chr0 = 0; + break; + case 0x6004: + if(chr1) + SetVROM_2K_Bank( 2, (reg[1]>>1) + (RAM[0xFF]&0x40)*2 ); + chr1 = 0; + break; + } + + if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void BoardDragonFighter::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x07 ) { + case 0x00: + chr0 = 1; + if((addr&0xF000)==0x9000){ + SetVROM_2K_Bank( 0, reg[1]>>1 ); + chr0 = 0; + } + break; + case 0x01: + chr1 = 1; + break; + case 0x06: + SetPROM_8K_Bank( 4, reg[1] ); + break; + case 0x07: + SetPROM_8K_Bank( 5, reg[1] ); + break; + } + break; + case 0xA000: + if(data&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0xC000: + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + irq_enable = 1; + irq_request = 0; + break; + } +} + +void BoardDragonFighter::HSync(int scanline) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter -= 1; + } + } + if(!(irq_counter)){ + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + irq_counter--; + } + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardDragonFighter.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardDragonFighter.h new file mode 100644 index 00000000..1d3edc82 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardDragonFighter.h @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// BoardDragonFighter // +////////////////////////////////////////////////////////////////////////// +class BoardDragonFighter : public Mapper +{ +public: + BoardDragonFighter( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow(WORD addr); + void Write(WORD addr, BYTE data); + void HSync(INT scanline); + +protected: + BYTE chr0, chr1, reg[2]; + BYTE irq_enable, irq_counter, irq_latch, irq_request; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardFK23C.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardFK23C.cpp new file mode 100644 index 00000000..09b25b7e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardFK23C.cpp @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////////// +// BoardFK23C // +////////////////////////////////////////////////////////////////////////// + +//code by CaH4e3 from fceumm + +void BoardFK23C::Reset() +{ + INT BoardNo = NES_ROM_get_unifBoardID(nes->rom->GetBoardName()); + if((BoardNo==379)||(nes->rom->GetMapperNo()==176)){ //BMC-FK23C + EXPREGS[0] = 4; + EXPREGS[1] = 0xFF; + EXPREGS[2] = EXPREGS[3] = 0; + }else if(BoardNo==635){ //BMC-FK23CA + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + } + dipswitch = unromchr = 0; + EXPREGS[4] = EXPREGS[5] = EXPREGS[6] = EXPREGS[7] = 0xFF; + + IRQReload = IRQCount = IRQLatch = IRQa = 0; + MMC3cmd = A000B = A001B = 0; + + DRegBuf[0] = 0; + DRegBuf[1] = 2; + DRegBuf[2] = 4; + DRegBuf[3] = 5; + DRegBuf[4] = 6; + DRegBuf[5] = 7; + DRegBuf[6] = 0; + DRegBuf[7] = 1; + + FixFK23MMC3PRG(MMC3cmd); + FixFK23MMC3CHR(MMC3cmd); +} + +void BoardFK23C::WriteLow( WORD addr, BYTE data ) +{ + if((addr>=0x5000)&&(addr<=0x5FFF)) + { + if (dipswitch) { + if (addr & (1 << (dipswitch + 3))) { + EXPREGS[addr & 3] = data; + FixFK23MMC3PRG(MMC3cmd); + FixFK23MMC3CHR(MMC3cmd); + } + } else { + EXPREGS[addr & 3] = data; + FixFK23MMC3PRG(MMC3cmd); + FixFK23MMC3CHR(MMC3cmd); + } + if (EXPREGS[3] & 2) EXPREGS[0] &= ~7; + } +} + +void BoardFK23C::Write( WORD addr, BYTE data ) +{ + if (EXPREGS[0] & 0x40) { + if (EXPREGS[0] & 0x30) + unromchr = 0; + else { + unromchr = data & 3; + FixFK23MMC3CHR(MMC3cmd); + } + } else { + if ((addr == 0x8001) && (EXPREGS[3] & 2) && (MMC3cmd & 8)) { + EXPREGS[4 | (MMC3cmd & 3)] = data; + FixFK23MMC3PRG(MMC3cmd); + FixFK23MMC3CHR(MMC3cmd); + } else + if (addr < 0xC000) { + if (!(VROM_1K_SIZE)) { + if ((addr == 0x8000) && (data == 0x46)) + data = 0x47; + else if ((addr == 0x8000) && (data == 0x47)) + data = 0x46; + } + MMC3CMDWrite(addr, data); + FixFK23MMC3PRG(MMC3cmd); + } else + MMC3IRQWrite(addr, data); + } +} + +void BoardFK23C::MMC3CMDWrite( WORD addr, BYTE data ) +{ + switch (addr & 0xE001) { + case 0x8000: + if ((data & 0x40) != (MMC3cmd & 0x40)) + FixFK23MMC3PRG(data); + if ((data & 0x80) != (MMC3cmd & 0x80)) + FixFK23MMC3CHR(data); + MMC3cmd = data; + break; + case 0x8001: + { + int cbase = (MMC3cmd & 0x80) << 5; + DRegBuf[MMC3cmd & 0x7] = data; + switch (MMC3cmd & 0x07) { + case 0: + PPUSW((cbase ^ 0x000), data & (~1)); + PPUSW((cbase ^ 0x400), data | 1); + break; + case 1: + PPUSW((cbase ^ 0x800), data & (~1)); + PPUSW((cbase ^ 0xC00), data | 1); + break; + case 2: + PPUSW(cbase ^ 0x1000, data); + break; + case 3: + PPUSW(cbase ^ 0x1400, data); + break; + case 4: + PPUSW(cbase ^ 0x1800, data); + break; + case 5: + PPUSW(cbase ^ 0x1C00, data); + break; + case 6: + if (MMC3cmd&0x40) CPUSW(0xC000, data); + else CPUSW(0x8000, data); + break; + case 7: + CPUSW(0xA000, data); + break; + } + break; + } + case 0xA000: + A000B = data; + if (!nes->rom->Is4SCREEN()) { + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + } + break; + case 0xA001: + A001B = data; + break; + } +} + +void BoardFK23C::MMC3IRQWrite( WORD addr, BYTE data ) +{ + switch (addr & 0xE001) { + case 0xC000: IRQReload = 0;IRQCount = data; break; + case 0xC001: IRQReload = 0;IRQLatch = data; break; + case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xE001: IRQReload = 0;IRQa = 1; break; + } +} + +void BoardFK23C::PPUSW(WORD A, BYTE V) +{ + if (VROM_1K_SIZE){ + if (EXPREGS[0] & 0x40) + SetVROM_8K_Bank(EXPREGS[2] | unromchr); + else if (EXPREGS[0] & 0x20) { + SetVROM_1K_Bank(A>>10, V); + } else { + uint16 base = (EXPREGS[2] & 0x7F) << 3; + if (EXPREGS[3] & 2) { + int cbase = (MMC3cmd & 0x80) << 5; + SetVROM_1K_Bank(A>>10, V | base); + SetVROM_1K_Bank((0x0000 ^ cbase)>>10, DRegBuf[0] | base); + SetVROM_1K_Bank((0x0400 ^ cbase)>>10, EXPREGS[6] | base); + SetVROM_1K_Bank((0x0800 ^ cbase)>>10, DRegBuf[1] | base); + SetVROM_1K_Bank((0x0c00 ^ cbase)>>10, EXPREGS[7] | base); + } else + SetVROM_1K_Bank(A>>10, V | base); + } + }else{ + if (EXPREGS[0] & 0x40) + SetYCRAM_8K_Bank(EXPREGS[2] | unromchr); + else if (EXPREGS[0] & 0x20) { + SetYCRAM_1K_Bank(A>>10, V); + } else { + uint16 base = (EXPREGS[2] & 0x7F) << 3; + if (EXPREGS[3] & 2) { + int cbase = (MMC3cmd & 0x80) << 5; + SetYCRAM_1K_Bank(A>>10, V | base); + SetYCRAM_1K_Bank((0x0000 ^ cbase)>>10, DRegBuf[0] | base); + SetYCRAM_1K_Bank((0x0400 ^ cbase)>>10, EXPREGS[6] | base); + SetYCRAM_1K_Bank((0x0800 ^ cbase)>>10, DRegBuf[1] | base); + SetYCRAM_1K_Bank((0x0c00 ^ cbase)>>10, EXPREGS[7] | base); + } else + SetYCRAM_1K_Bank(A>>10, V | base); + } + } +} + +void BoardFK23C::CPUSW(WORD A, BYTE V) +{ + uint32 bank = (EXPREGS[1] & 0x1F); + uint32 hiblock = ((EXPREGS[0] & 8) << 4) | ((EXPREGS[0] & 0x80) << 1) | ((!(VROM_1K_SIZE)) ? ((EXPREGS[2] & 0x40) << 3) : 0); + uint32 block = (EXPREGS[1] & 0x60) | hiblock; + uint32 extra = (EXPREGS[3] & 2); + switch (EXPREGS[0] & 7) { + case 0: + SetPROM_8K_Bank(A>>13, (block << 1) | (V & 0x3F)); + if (extra) { + SetPROM_8K_Bank(6, EXPREGS[4]); + SetPROM_8K_Bank(7, EXPREGS[5]); + } + break; + case 1: + SetPROM_8K_Bank(A>>13, ((hiblock | (EXPREGS[1] & 0x70)) << 1) | (V & 0x1F)); + if (extra) { + SetPROM_8K_Bank(6, EXPREGS[4]); + SetPROM_8K_Bank(7, EXPREGS[5]); + } + break; + case 2: + SetPROM_8K_Bank(A>>13, ((hiblock | (EXPREGS[1] & 0x78)) << 1) | (V & 0x0F)); + if (extra) { + SetPROM_8K_Bank(6, EXPREGS[4]); + SetPROM_8K_Bank(7, EXPREGS[5]); + } + break; + case 3: + SetPROM_16K_Bank(4, (bank | block)); + SetPROM_16K_Bank(6, (bank | block)); + break; + case 4: + SetPROM_32K_Bank((bank | block) >> 1); + break; + } + SetPROM_Bank( 3, &WRAM[0x2000*(A001B&3)], BANKTYPE_RAM ); +} + +void BoardFK23C::FixFK23MMC3PRG(BYTE data) +{ + if (data & 0x40) { + CPUSW(0xC000, DRegBuf[6]); + CPUSW(0x8000, ~1); + } else { + CPUSW(0x8000, DRegBuf[6]); + CPUSW(0xC000, ~1); + } + CPUSW(0xA000, DRegBuf[7]); + CPUSW(0xE000, ~0); +} + +void BoardFK23C::FixFK23MMC3CHR(BYTE data) +{ + int cbase = (data & 0x80) << 5; + PPUSW((cbase ^ 0x000), DRegBuf[0] & (~1)); + PPUSW((cbase ^ 0x400), DRegBuf[0] | 1); + PPUSW((cbase ^ 0x800), DRegBuf[1] & (~1)); + PPUSW((cbase ^ 0xC00), DRegBuf[1] | 1); + PPUSW(cbase ^ 0x1000, DRegBuf[2]); + PPUSW(cbase ^ 0x1400, DRegBuf[3]); + PPUSW(cbase ^ 0x1800, DRegBuf[4]); + PPUSW(cbase ^ 0x1c00, DRegBuf[5]); +} + +void BoardFK23C::HSync(INT scanline) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (IRQa && !IRQReload) { + if (scanline == 0) { + if (IRQCount) { + IRQCount -= 1; + } + } + if (!(IRQCount)){ + IRQReload = 0xFF; + IRQCount = IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + IRQCount--; + } + } + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardFK23C.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardFK23C.h new file mode 100644 index 00000000..edd197e3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardFK23C.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// BoardFK23C // +////////////////////////////////////////////////////////////////////////// +class BoardFK23C : public Mapper +{ +public: + BoardFK23C( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync(INT scanline); + +protected: + BYTE unromchr; + INT dipswitch; + BYTE EXPREGS[8]; + BYTE MMC3cmd; + BYTE DRegBuf[8]; + BYTE A000B, A001B; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; +private: + void MMC3CMDWrite(WORD addr, BYTE data); + void MMC3IRQWrite(WORD addr, BYTE data); + void PPUSW(WORD A, BYTE V); + void CPUSW(WORD A, BYTE V); + void FixFK23MMC3PRG(BYTE data); + void FixFK23MMC3CHR(BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7010.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7010.cpp new file mode 100644 index 00000000..65add739 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7010.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// BoardKS7010 EMC // +////////////////////////////////////////////////////////////////////////// + +void BoardKS7010::Reset() +{ + SetPROM_8K_Bank( 3, 0x0C ); + SetPROM_32K_Bank( 0x0A, 0x0B, 0x06, 0x07 ); + SetVROM_8K_Bank( 0x0C ); +} + +BYTE BoardKS7010::ReadLow( WORD addr ) +{ + if(addr==0x692C) + if((CPU_MEM_BANK[3][0x92C]==0xFE)&&(CPU_MEM_BANK[3][0x92D]==0xFA)) + SetVROM_8K_Bank( 0x06 ); + return Mapper::ReadLow( addr ); +} + +void BoardKS7010::ExWrite( WORD addr, BYTE data ) +{ + if(addr==0x4025) + if((RAM[0x602]>0)&&(RAM[0x602]<10)){ + BYTE bank = (RAM[0x602]-4)&0x0F; + SetPROM_8K_Bank( 3, bank ); + SetVROM_8K_Bank( bank ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7010.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7010.h new file mode 100644 index 00000000..ee632f65 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7010.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// BoardKS7010 EMC // +////////////////////////////////////////////////////////////////////////// + +class BoardKS7010 : public Mapper +{ +public: + BoardKS7010( NES* parent ) : Mapper(parent) {} + + void Reset(); + void ExWrite( WORD addr, BYTE data ); + BYTE ReadLow ( WORD addr ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7030.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7030.cpp new file mode 100644 index 00000000..5c257b94 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7030.cpp @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////// +// BoardKS7030 // +////////////////////////////////////////////////////////////////////////// + +//code by CaH4e3 from fceumm + +void BoardKS7030::Reset() +{ + reg0 = reg1 = 0x1F; + SetBank(); +} + +void BoardKS7030::ExWrite( WORD addr, BYTE data ) +{ + if(addr==0x4025) + if(data&0x08) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); +} + +BYTE BoardKS7030::ReadLow( WORD addr ) +{ + if((addr>=0x6000)&&(addr<=0x7FFF)) + { + if ((addr >= 0x6000) && (addr <= 0x6BFF)) { + return DRAM[addr - 0x6000]; + } else if ((addr >= 0x6C00) && (addr <= 0x6FFF)) { + return CPU_MEM_BANK[(0xC800+(addr-0x6C00))>>13][(0xC800+(addr-0x6C00))&0x1FFF]; + } else if ((addr >= 0x7000) && (addr <= 0x7FFF)) { + return CPU_MEM_BANK[(0xB800+(addr-0x7000))>>13][(0xB800+(addr-0x7000))&0x1FFF]; + } + } + return Mapper::ReadLow( addr ); +} + +void BoardKS7030::WriteLow( WORD addr, BYTE data ) +{ + if((addr>=0x6000)&&(addr<=0x7FFF)) + { + if ((addr >= 0x6000) && (addr <= 0x6BFF)) { + DRAM[addr - 0x6000] = data; + } else if ((addr >= 0x6C00) && (addr <= 0x6FFF)) { + CPU_MEM_BANK[(0xC800+(addr-0x6C00))>>13][(0xC800+(addr-0x6C00))&0x1FFF] = data; + } else if ((addr >= 0x7000) && (addr <= 0x7FFF)) { + CPU_MEM_BANK[(0xB800+(addr-0x7000))>>13][(0xB800+(addr-0x7000))&0x1FFF] = data; + } + } +} + +BYTE BoardKS7030::Read( WORD addr) +{ + if((addr>=0xB800)&&(addr<=0xD7FF)) + { + if ((addr >= 0xB800) && addr <= 0xBFFF) { + return DRAM[0x0C00 + (addr - 0xB800)]; + } else if ((addr >= 0xC000) && addr <= 0xCBFF) { + return CPU_MEM_BANK[(0xCC00+(addr-0xC000))>>13][(0xCC00+(addr-0xC000))&0x1FFF]; + } else if ((addr >= 0xCC00) && addr <= 0xD7FF) { + return DRAM[0x1400 + (addr - 0xCC00)]; + } + } + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +void BoardKS7030::Write( WORD addr, BYTE data ) +{ + if((addr>=0x8000)&&(addr<=0x8FFF)) + { + reg0 = addr & 0x07; + SetBank(); + } + else if((addr>=0x9000)&&(addr<=0x9FFF)) + { + reg1 = addr & 0x0F; + SetBank(); + } + else if((addr>=0xB800)&&(addr<=0xD7FF)) + { + if ((addr >= 0xB800) && (addr <= 0xBFFF)) { + DRAM[0x0C00 + (addr - 0xB800)] = data; + } else if ((addr >= 0xC000) && (addr <= 0xCBFF)) { + CPU_MEM_BANK[(0xCC00+(addr-0xC000))>>13][(0xCC00+(addr-0xC000))&0x1FFF] = data; + } else if ((addr >= 0xCC00) && (addr <= 0xD7FF)) { + DRAM[0x1400 + (addr - 0xCC00)] = data; + } + } +} + +void BoardKS7030::SetBank() +{ + SetPROM_32K_Bank(3); + SetCRAM_8K_Bank(0); + memcpy( &CPU_MEM_BANK[5][0x1800], PROM+(0x1000*(reg0%0x20))+0x0000, 0x0800); + memcpy( &CPU_MEM_BANK[6][0x0000], PROM+(0x1000*(reg0%0x20))+0x0800, 0x0800); + memcpy( &CPU_MEM_BANK[6][0x0800], PROM+(0x1000*((reg1+8)%0x20)), 0x1000); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7030.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7030.h new file mode 100644 index 00000000..8157ae8b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardKS7030.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// BoardKS7030 // +////////////////////////////////////////////////////////////////////////// + +class BoardKS7030 : public Mapper +{ +public: + BoardKS7030( NES* parent ) : Mapper(parent) {} + + void Reset(); + void ExWrite( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + BYTE Read( WORD addr ); + void Write( WORD addr, BYTE data ); + +protected: + BYTE reg0, reg1; +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardLB12IN1.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardLB12IN1.cpp new file mode 100644 index 00000000..d8470e6b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardLB12IN1.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// BoardLB12IN1 // +////////////////////////////////////////////////////////////////////////// + +void BoardLB12IN1::Reset() +{ + SetPROM_8K_Bank( 3, 0x0C ); + SetPROM_32K_Bank( 0x0A, 0x0B, 0x06, 0x07 ); + SetVROM_8K_Bank( 0x0C ); +} + +BYTE BoardLB12IN1::ReadLow( WORD addr ) +{ + if(addr==0x692C) + if((CPU_MEM_BANK[3][0x92C]==0xFE)&&(CPU_MEM_BANK[3][0x92D]==0xFA)) + SetVROM_8K_Bank( 0x06 ); + return Mapper::ReadLow( addr ); +} + +void BoardLB12IN1::ExWrite( WORD addr, BYTE data ) +{ + if(addr==0x4025) + if((RAM[0x602]>0)&&(RAM[0x602]<10)){ + BYTE bank = (RAM[0x602]-4)&0x0F; + SetPROM_8K_Bank( 3, bank ); + SetVROM_8K_Bank( bank ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardLB12IN1.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardLB12IN1.h new file mode 100644 index 00000000..f25502ed --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardLB12IN1.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// BoardLB12IN1 // +////////////////////////////////////////////////////////////////////////// + +class BoardLB12IN1 : public Mapper +{ +public: + BoardLB12IN1( NES* parent ) : Mapper(parent) {} + + void Reset(); + void ExWrite( WORD addr, BYTE data ); + BYTE ReadLow ( WORD addr ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardMGC002.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMGC002.cpp new file mode 100644 index 00000000..6076112f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMGC002.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// BoardMGC002 // +////////////////////////////////////////////////////////////////////////// + +void BoardMGC002::Reset() +{ + SetPROM_32K_Bank( 0, 1, 6, 7 ); + from_mode = 0; + game_set = 0; + reg[0] = 0x0C; + reg[1] = reg[2] = reg[3] = 0; + shift = regbuf = 0; +} + +void BoardMGC002::WriteLow( WORD addr, BYTE data ) +{ + if(addr==0x4120){ + if((data==0x21)&&(from_mode)){ + game_set = 1; //Operation Wolf + SetPROM_32K_Bank( 0x1c, 0x1d, 0x1e, 0x1f ); + } + if((data==0x62)&&(from_mode)){ + game_set = 2; //Space Shadow + SetPROM_32K_Bank( 0x0c, 0x0d, 0x0e, 0x0f ); + SetVROM_8K_Bank( 0 ); + } + } + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF]=data; +} + +void BoardMGC002::Write( WORD addr, BYTE data ) +{ + if((addr==0x8387)&&(data==0x20)){ + from_mode = 1; + SetPROM_32K_Bank( 4, 5, 6, 7 ); + } + if(game_set==1){ //Operation Wolf [MMC1] + if((addr&0x6000)!=(last_addr&0x6000)) shift=regbuf=0; + last_addr=addr; + if(data&0x80){ + shift=regbuf=0; + reg[0]|=0x0C; + return; + } + if(data&0x01) regbuf|=1<>13; + reg[addr]=regbuf; + shift=regbuf=0; + switch( addr ) { + case 0: + if(reg[0]&0x02){ + if(reg[0]&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + }else{ + if(reg[0]&0x01) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + break; + case 1: + case 2: + if(reg[0]&0x10){ + SetVROM_4K_Bank(0,reg[1]+0x20); + SetVROM_4K_Bank(4,reg[2]+0x20); + } else { + SetVROM_8K_Bank((reg[1]>>1)+0x10); + } + break; + case 3: + if(!(reg[0]&0x08)){ + SetPROM_32K_Bank((reg[3]>>1)+0x4); + } else { + if(reg[0]&0x04){ + SetPROM_16K_Bank(4,reg[3]+0x8); + SetPROM_16K_Bank(6,0x1f); + } else { + SetPROM_16K_Bank(6,reg[3]+0x8); + SetPROM_16K_Bank(4,+0x8); + } + } + break; + } + } + if(game_set==2){ //Space Shadow [mapper070] + SetPROM_16K_Bank(4,(data&0x70)>>4); + SetVROM_8K_Bank(data&0x0F); + if(data&0x80) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + } +} + +void BoardMGC002::SaveState( LPBYTE p ) +{ + // +} + +void BoardMGC002::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardMGC002.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMGC002.h new file mode 100644 index 00000000..c9a213b1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMGC002.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// BoardMGC002 // +////////////////////////////////////////////////////////////////////////// +class BoardMGC002 : public Mapper +{ +public: + BoardMGC002( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE from_mode, game_set; + BYTE reg[4], shift, regbuf; + WORD last_addr; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardMMC3.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMMC3.cpp new file mode 100644 index 00000000..dcb71f1a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMMC3.cpp @@ -0,0 +1,184 @@ +#include +#include +#include + +#include "DebugOut.h" +#include "typedef.h" +#include "macro.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "pad.h" +#include "rom.h" + +#include "mapper.h" + +#include "Config.h" + +#include "BoardMMC3.h" + +BYTE MMC3_cmd; +BYTE MMC3_DRegBuf[8]; +BYTE MMC3_A000B, MMC3_A001B; +BYTE MMC3_IRQCount, MMC3_IRQLatch, MMC3_IRQa, MMC3_IRQReload; + +// ------------------------- Generic MM3 Code --------------------------- + +void MMC3_RegReset() +{ + MMC3_IRQReload = MMC3_IRQCount = MMC3_IRQLatch = MMC3_IRQa = 0; + MMC3_cmd = MMC3_A000B = MMC3_A001B = 0; + + MMC3_DRegBuf[0] = 0; + MMC3_DRegBuf[1] = 2; + MMC3_DRegBuf[2] = 4; + MMC3_DRegBuf[3] = 5; + MMC3_DRegBuf[4] = 6; + MMC3_DRegBuf[5] = 7; + MMC3_DRegBuf[6] = 0; + MMC3_DRegBuf[7] = 1; + + FixMMC3PRG(0); + FixMMC3CHR(0); +} + +void pwrap(WORD A, BYTE V) +{ + SetPROM_8K_Bank(A>>13, V&0x7F); +} + +void cwrap(WORD A, BYTE V) +{ + if (VROM_1K_SIZE) SetVROM_1K_Bank(A>>10, V); + else SetCRAM_1K_Bank(A>>10, V); +} + +void mwrap(BYTE V) +{ +// if (!nes->rom->Is4SCREEN()) { + if ( V == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if ( V == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if ( V == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); +// } +} + +void FixMMC3PRG(BYTE V) +{ + if (V & 0x40) { + pwrap(0xC000, MMC3_DRegBuf[6]); + pwrap(0x8000, ~1); + } else { + pwrap(0x8000, MMC3_DRegBuf[6]); + pwrap(0xC000, ~1); + } + pwrap(0xA000, MMC3_DRegBuf[7]); + pwrap(0xE000, ~0); +} + +void FixMMC3CHR(BYTE V) +{ + int cbase = (V & 0x80) << 5; + cwrap((cbase ^ 0x000), MMC3_DRegBuf[0] & (~1)); + cwrap((cbase ^ 0x400), MMC3_DRegBuf[0] | 1); + cwrap((cbase ^ 0x800), MMC3_DRegBuf[1] & (~1)); + cwrap((cbase ^ 0xC00), MMC3_DRegBuf[1] | 1); + cwrap(cbase ^ 0x1000, MMC3_DRegBuf[2]); + cwrap(cbase ^ 0x1400, MMC3_DRegBuf[3]); + cwrap(cbase ^ 0x1800, MMC3_DRegBuf[4]); + cwrap(cbase ^ 0x1c00, MMC3_DRegBuf[5]); + + mwrap(MMC3_A000B); +} + +void MMC3_CMDWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0x8000: + if ((V & 0x40) != (MMC3_cmd & 0x40)) + FixMMC3PRG(V); + if ((V & 0x80) != (MMC3_cmd & 0x80)) + FixMMC3CHR(V); + MMC3_cmd = V; + break; + case 0x8001: + { + int cbase = (MMC3_cmd & 0x80) << 5; + MMC3_DRegBuf[MMC3_cmd & 0x7] = V; + switch (MMC3_cmd & 0x07) { + case 0: + cwrap((cbase ^ 0x000), V & (~1)); + cwrap((cbase ^ 0x400), V | 1); + break; + case 1: + cwrap((cbase ^ 0x800), V & (~1)); + cwrap((cbase ^ 0xC00), V | 1); + break; + case 2: + cwrap(cbase ^ 0x1000, V); + break; + case 3: + cwrap(cbase ^ 0x1400, V); + break; + case 4: + cwrap(cbase ^ 0x1800, V); + break; + case 5: + cwrap(cbase ^ 0x1C00, V); + break; + case 6: + if (MMC3_cmd&0x40) pwrap(0xC000, V); + else pwrap(0x8000, V); + break; + case 7: + pwrap(0xA000, V); + break; + } + break; + } + case 0xA000: + MMC3_A000B = V; + mwrap(MMC3_A000B); + break; + case 0xA001: + MMC3_A001B = V; + break; + } +} + +void MMC3_IRQWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0xC000: MMC3_IRQReload = 0;MMC3_IRQCount = V; break; + case 0xC001: MMC3_IRQReload = 0;MMC3_IRQLatch = V; break; + case 0xE000: MMC3_IRQReload = 0;MMC3_IRQa = 0; break;//nes->cpu->ClrIRQ(IRQ_MAPPER); + case 0xE001: MMC3_IRQReload = 0;MMC3_IRQa = 1; break; + } +} + +void MMC3_HSync(INT scanline) +{ + if ((scanline >= 0 && scanline <= 239)) { +// if (nes->ppu->IsDispON()) +// { + if (MMC3_IRQa && !MMC3_IRQReload) { + if (scanline == 0) { + if (MMC3_IRQCount) { + MMC3_IRQCount -= 1; + } + } + if (!(MMC3_IRQCount)){ + MMC3_IRQReload = 0xFF; + MMC3_IRQCount = MMC3_IRQLatch; +// nes->cpu->SetIRQ(IRQ_MAPPER); + } + MMC3_IRQCount--; + } +// } + } +} + +// ---------------------------------------------------------------------- diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardMMC3.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMMC3.h new file mode 100644 index 00000000..33e4d8c7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardMMC3.h @@ -0,0 +1,34 @@ +#include +#include +#include + +#include "DebugOut.h" +#include "typedef.h" +#include "macro.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "pad.h" +#include "rom.h" + +#include "mapper.h" + +#include "Config.h" + +extern BYTE MMC3_cmd; +extern BYTE MMC3_DRegBuf[8]; +extern BYTE MMC3_A000B, MMC3_A001B; +extern BYTE MMC3_IRQCount, MMC3_IRQLatch, MMC3_IRQa, MMC3_IRQReload; + +extern void MMC3_RegReset(); +extern void pwrap(WORD A, BYTE V); +extern void cwrap(WORD A, BYTE V); +extern void mwrap(BYTE V); +extern void FixMMC3PRG(BYTE V); +extern void FixMMC3CHR(BYTE V); +extern void MMC3_CMDWrite(WORD A, BYTE V); +extern void MMC3_IRQWrite(WORD A, BYTE V); +extern void MMC3_HSync(INT scanline); diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardOneBus.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardOneBus.cpp new file mode 100644 index 00000000..520ae3ab --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardOneBus.cpp @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// BoardOneBus // +////////////////////////////////////////////////////////////////////////// + +//code by CaH4e3 from fceumm + +void BoardOneBus::Reset() +{ + inv_hack = 0; + pcm_enable = pcm_irq = 0; + pcm_clock = 0xE1; + IRQReload = IRQCount = IRQa = 0; + memset(cpu410x, 0x00, sizeof(cpu410x)); + memset(ppu201x, 0x00, sizeof(ppu201x)); + memset(apu40xx, 0x00, sizeof(apu40xx)); + SetBank(); + + count = 0; +} + +void BoardOneBus::WriteExPPU( WORD addr, BYTE data ) //Write $2010-$201F +{ + ppu201x[addr&0x0F] = data; + SetBank(); +} + +BYTE BoardOneBus::ReadExAPU ( WORD addr ) //Read $4000-$403F +{ + uint8 result = nes->apu->Read(addr); + switch (addr & 0x3f) { + case 0x15: + if (apu40xx[0x30] & 0x10) { + result = (result & 0x7f) | pcm_irq; + } + break; + } + return result; +} + +void BoardOneBus::WriteExAPU( WORD addr, BYTE data ) //Write $4000-$403F +{ + apu40xx[addr & 0x3f] = data; + switch (addr & 0x3f) { + case 0x12: + if (apu40xx[0x30] & 0x10) { + pcm_addr = data << 6; + } + break; + case 0x13: + if (apu40xx[0x30] & 0x10) { + pcm_size = (data << 4) + 1; + } + break; + case 0x15: + if (apu40xx[0x30] & 0x10) { + pcm_enable = data & 0x10; + if (pcm_irq) { + nes->cpu->ClrIRQ(IRQ_MAPPER); + pcm_irq = 0; + } + if (pcm_enable) + pcm_latch = pcm_clock; + data &= 0xef; + } + break; + } + nes->apu->Write(addr,data); +} + +void BoardOneBus::WriteLow( WORD addr, BYTE data ) +{ + if((addr>=0x4100)&&(addr<=0x410F)) //Write $4100-$410F + { + switch (addr & 0xf) { + case 0x1: IRQLatch = data & 0xfe; break; + case 0x2: IRQReload = 1; break; + case 0x3: nes->cpu->ClrIRQ(IRQ_MAPPER); IRQa = 0; break; + case 0x4: IRQa = 1; break; + default: + cpu410x[addr & 0xf] = data; + SetBank(); + } + } +} + +void BoardOneBus::Write( WORD addr, BYTE data ) +{ + switch (addr & 0xe001) { + case 0x8000: mmc3cmd = (mmc3cmd & 0x38) | (data & 0xc7); SetBank(); break; + case 0x8001: + { + switch (mmc3cmd & 7) { + case 0: ppu201x[0x6] = data; SetBankPPU(); break; + case 1: ppu201x[0x7] = data; SetBankPPU(); break; + case 2: ppu201x[0x2] = data; SetBankPPU(); break; + case 3: ppu201x[0x3] = data; SetBankPPU(); break; + case 4: ppu201x[0x4] = data; SetBankPPU(); break; + case 5: ppu201x[0x5] = data; SetBankPPU(); break; + case 6: cpu410x[0x7] = data; SetBankCPU(); break; + case 7: cpu410x[0x8] = data; SetBankCPU(); break; + } + break; + } + case 0xa000: mirror = data; SetBankPPU(); break; + case 0xc000: IRQLatch = data & 0xfe; break; + case 0xc001: IRQReload = 1; break; + case 0xe000: nes->cpu->ClrIRQ(IRQ_MAPPER); IRQa = 0; break; + case 0xe001: IRQa = 1; break; + } +} + +void BoardOneBus::SetBank() +{ + SetBankCPU(); + SetBankPPU(); +} + +void BoardOneBus::SetBankCPU() +{ + uint8 bankmode = cpu410x[0xb] & 7; + uint8 mask = (bankmode == 0x7) ? (0xff) : (0x3f >> bankmode); + uint32 block = ((cpu410x[0x0] & 0xf0) << 4) + (cpu410x[0xa] & (~mask)); + uint32 pswap = (mmc3cmd & 0x40) << 8; + + uint8 bank0 = cpu410x[0x7 ^ inv_hack]; + uint8 bank1 = cpu410x[0x8 ^ inv_hack]; + uint8 bank2 = (cpu410x[0xb] & 0x40) ? (cpu410x[0x9]) : (~1); + uint8 bank3 = ~0; + + SetPROM_8K_Bank((0x8000^pswap)>>13, block | (bank0 & mask)); + SetPROM_8K_Bank(5, block | (bank1 & mask)); + SetPROM_8K_Bank((0xc000^pswap)>>13, block | (bank2 & mask)); + SetPROM_8K_Bank(7, block | (bank3 & mask)); +} + +void BoardOneBus::SetBankPPU() +{ + static const uint8 midx[8] = { 0, 1, 2, 0, 3, 4, 5, 0 }; + uint8 mask = 0xff >> midx[ppu201x[0xa] & 7]; + uint32 block = ((cpu410x[0x0] & 0x0f) << 11) + ((ppu201x[0x8] & 0x70) << 4) + (ppu201x[0xa] & (~mask)); + uint32 cswap = (mmc3cmd & 0x80) << 5; + + uint8 bank0 = ppu201x[0x6] & (~1); + uint8 bank1 = ppu201x[0x6] | 1; + uint8 bank2 = ppu201x[0x7] & (~1); + uint8 bank3 = ppu201x[0x7] | 1; + uint8 bank4 = ppu201x[0x2]; + uint8 bank5 = ppu201x[0x3]; + uint8 bank6 = ppu201x[0x4]; + uint8 bank7 = ppu201x[0x5]; + + SetOBCRAM_1K_Bank((0x0000^cswap)>>10, block | (bank0 & mask)); + SetOBCRAM_1K_Bank((0x0400^cswap)>>10, block | (bank1 & mask)); + SetOBCRAM_1K_Bank((0x0800^cswap)>>10, block | (bank2 & mask)); + SetOBCRAM_1K_Bank((0x0c00^cswap)>>10, block | (bank3 & mask)); + SetOBCRAM_1K_Bank((0x1000^cswap)>>10, block | (bank4 & mask)); + SetOBCRAM_1K_Bank((0x1400^cswap)>>10, block | (bank5 & mask)); + SetOBCRAM_1K_Bank((0x1800^cswap)>>10, block | (bank6 & mask)); + SetOBCRAM_1K_Bank((0x1c00^cswap)>>10, block | (bank7 & mask)); + + if(mirror&0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + +} + +void BoardOneBus::HSync( INT scanline ) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + uint32 count = IRQCount; + if (!count || IRQReload) { + IRQCount = IRQLatch; + IRQReload = 0; + } else + IRQCount--; + if (count && !IRQCount) { + if (IRQa) + nes->cpu->SetIRQ(IRQ_MAPPER); + } + } + } +} + +void BoardOneBus::Clock( INT cycles ) +{ + if (pcm_enable) { + pcm_latch -= cycles; + if (pcm_latch <= 0) { + pcm_latch += pcm_clock; + pcm_size--; + if (pcm_size < 0) { + pcm_irq = 0x80; + pcm_enable = 0; + nes->cpu->SetIRQ(IRQ_MAPPER); + } else { + uint16 addr = pcm_addr | ((apu40xx[0x30]^3) << 14); + uint8 raw_pcm = CPU_MEM_BANK[addr>>13][addr&0x1FFF] >> 1; + +// YWRAM[count] = CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +// count++; + + nes->apu->Write(0x4011, raw_pcm); + pcm_addr++; + pcm_addr &= 0x7FFF; + } + } + } +} + +void BoardOneBus::PPU_Latch( WORD addr ) +{ + if(DirectInput.m_Sw[DIK_PAUSE]){ +// nes->Dump_YWRAM(); + } +} + +void BoardOneBus::SaveState( LPBYTE p ) +{ + // +} + +void BoardOneBus::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardOneBus.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardOneBus.h new file mode 100644 index 00000000..c070552d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardOneBus.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// BoardOneBus // +////////////////////////////////////////////////////////////////////////// +class BoardOneBus : public Mapper +{ +public: + BoardOneBus( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + void Clock( INT cycles ); + + void WriteExPPU( WORD addr, BYTE data ); + BYTE ReadExAPU ( WORD addr ); + void WriteExAPU( WORD addr, BYTE data ); + void PPU_Latch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE cpu410x[16], ppu201x[16], apu40xx[64]; + BYTE IRQCount, IRQa, IRQReload, IRQLatch; + BYTE inv_hack, mmc3cmd, mirror; + BYTE pcm_enable, pcm_irq; + INT pcm_addr, pcm_size, pcm_latch, pcm_clock; + + DWORD count; +private: + void SetBank(); + void SetBankCPU(); + void SetBankPPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardSA9602B.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardSA9602B.cpp new file mode 100644 index 00000000..95aa9355 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardSA9602B.cpp @@ -0,0 +1,168 @@ +//////////////////////////////////////////////////////////////////////////// +// BoardSA9602B Mei Shao Nv Meng Gong Chang (Princess Maker)(Sachen)(Unl)[!] // +//////////////////////////////////////////////////////////////////////////// + +void BoardSA9602B::Reset() +{ + CRAM_sav = 3 ; + memcpy(&CRAM[CRAM_sav*0x2000], &WRAM[0], 0x2000); + reg[0] = 0; + reg[1] = 0; + IRQCount = IRQLatch = IRQa = MMC3cmd = 0; + DRegBuf[0] = 0; + DRegBuf[1] = 2; + DRegBuf[2] = 4; + DRegBuf[3] = 5; + DRegBuf[4] = 6; + DRegBuf[5] = 7; + DRegBuf[6] = 0; + DRegBuf[7] = 1; + A000B = 0; + UpdatePrg(0); + UpdateChr(0); +} + +void BoardSA9602B::Write( WORD addr, BYTE data ) +{ + switch (addr & 0xE001) { + case 0x8000: + reg[0] = data; + if ((data & 0x40) != (MMC3cmd & 0x40)) + UpdatePrg(data); + if ((data & 0x80) != (MMC3cmd & 0x80)) + UpdateChr(data); + MMC3cmd = data; + break; + case 0x8001: + { + if ((reg[0] & 7) < 6) { + reg[1] = data >> 6; + UpdatePrg(MMC3cmd); + } + int cbase = (MMC3cmd & 0x80) << 5; + DRegBuf[MMC3cmd & 0x7] = data; + switch (MMC3cmd & 0x07) { + case 0: + UpdateChr((cbase ^ 0x000), data & (~1)); + UpdateChr((cbase ^ 0x400), data | 1); + break; + case 1: + UpdateChr((cbase ^ 0x800), data & (~1)); + UpdateChr((cbase ^ 0xC00), data | 1); + break; + case 2: + UpdateChr(cbase ^ 0x1000, data); + break; + case 3: + UpdateChr(cbase ^ 0x1400, data); + break; + case 4: + UpdateChr(cbase ^ 0x1800, data); + break; + case 5: + UpdateChr(cbase ^ 0x1C00, data); + break; + case 6: + if (MMC3cmd & 0x40) + UpdatePrg(0xC000, data); + else + UpdatePrg(0x8000, data); + break; + case 7: + UpdatePrg(0xA000, data); + break; + } + break; + } + case 0xA000: + A000B = data; + if (!nes->rom->Is4SCREEN()) { + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + } + break; + case 0xC000: IRQReload = 0;IRQCount = data; break; + case 0xC001: IRQReload = 0;IRQLatch = data; break; + case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xE001: IRQReload = 0;IRQa = 1; break; + } +} + +void BoardSA9602B::UpdatePrg(WORD addr, BYTE data) +{ + SetPROM_8K_Bank(addr>>13, (data&0x3F)|(reg[1]<<6)); + if (MMC3cmd & 0x40) + SetPROM_8K_Bank(4, 0x3E); + else + SetPROM_8K_Bank(6, 0x3E); + SetPROM_8K_Bank(7, 0x3F); +} + +void BoardSA9602B::UpdateChr(WORD addr, BYTE data) +{ + SetCRAM_1K_Bank(addr >> 10, data); +} + +void BoardSA9602B::UpdatePrg(BYTE data) +{ + if (data & 0x40) { + UpdatePrg(0xC000, DRegBuf[6]); + UpdatePrg(0x8000, ~1); + } + else { + UpdatePrg(0x8000, DRegBuf[6]); + UpdatePrg(0xC000, ~1); + } + UpdatePrg(0xA000, DRegBuf[7]); + UpdatePrg(0xE000, ~0); +} + +void BoardSA9602B::UpdateChr(BYTE data) +{ + BYTE cbase = (data & 0x80) << 5; + UpdateChr((cbase ^ 0x000), DRegBuf[0] & (~1)); + UpdateChr((cbase ^ 0x400), DRegBuf[0] | 1); + UpdateChr((cbase ^ 0x800), DRegBuf[1] & (~1)); + UpdateChr((cbase ^ 0xC00), DRegBuf[1] | 1); + UpdateChr(cbase ^ 0x1000, DRegBuf[2]); + UpdateChr(cbase ^ 0x1400, DRegBuf[3]); + UpdateChr(cbase ^ 0x1800, DRegBuf[4]); + UpdateChr(cbase ^ 0x1c00, DRegBuf[5]); + if (!nes->rom->Is4SCREEN()) { + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + } +} + +void BoardSA9602B::HSync(INT scanline) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (IRQa && !IRQReload) { + if (scanline == 0) { + if (IRQCount) { + IRQCount -= 1; + } + } + if (!(IRQCount)){ + IRQReload = 0xFF; + IRQCount = IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + IRQCount--; + } + } + } + memcpy(&WRAM[0], &CRAM[CRAM_sav*0x2000], 0x2000); +} + +void BoardSA9602B::SaveState( LPBYTE p ) +{ + // +} + +void BoardSA9602B::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardSA9602B.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardSA9602B.h new file mode 100644 index 00000000..e19acc1e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardSA9602B.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// BoardSA9602B // +////////////////////////////////////////////////////////////////////////// +class BoardSA9602B : public Mapper +{ +public: + BoardSA9602B( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void UpdatePrg(BYTE data); + void UpdateChr(BYTE data); + void UpdatePrg(WORD addr,BYTE data); + void UpdateChr(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + + void HSync(INT scanline); + +protected: + BYTE DRegBuf[8], reg[2]; + BYTE A000B, MMC3cmd, CRAM_sav; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardTH21311.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardTH21311.cpp new file mode 100644 index 00000000..df46ac58 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardTH21311.cpp @@ -0,0 +1,151 @@ +////////////////////////////////////////////////////////////////////////// +// BoardTH21311 // +////////////////////////////////////////////////////////////////////////// + +void BoardTH21311::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0; + } + + irq_enable = 0; + irq_counter = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + +} + +void BoardTH21311::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + case 0x9000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB001: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB002: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB003: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC001: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC002: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC003: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD001: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD002: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD003: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE001: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE002: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE003: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF001: + irq_enable = 1; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF002: + irq_counter = (irq_counter & 0xFF00) | data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF003: + irq_counter = (irq_counter & 0x00FF) | (data << 8); + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} +/* +void BoardTH21311::Clock( INT cycles ) +{ + if( irq_enable ) { + irq_counter -= cycles; + if( irq_counter <= 0 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + irq_enable = 0; + irq_counter = 0xFFFF; + } + } +} +*/ +void BoardTH21311::HSync( INT scanline ) +{ + if( irq_enable ) { + irq_counter -= 123; + if( irq_counter <= 0 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + irq_enable = 0; + irq_counter = 0xFFFF; + } + } +} + +void BoardTH21311::SaveState( LPBYTE p ) +{ + // +} + +void BoardTH21311::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardTH21311.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardTH21311.h new file mode 100644 index 00000000..87226903 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardTH21311.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// BoardTH21311 // +////////////////////////////////////////////////////////////////////////// + +class BoardTH21311 : public Mapper +{ +public: + BoardTH21311( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +// void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE irq_enable; + INT irq_counter; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL158B.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL158B.cpp new file mode 100644 index 00000000..8ed6e61a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL158B.cpp @@ -0,0 +1,197 @@ +////////////////////////////////////////////////////////////////////////// +// BoardUNL158B Blood Of Jurassic (GD-98) // +////////////////////////////////////////////////////////////////////////// + +static uint8 lut[8] = { 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0F, 0x00 }; + +void BoardUNL158B::Reset() +{ + IRQReload = IRQCount = IRQLatch = IRQa = 0; + MMC3cmd = A000B = A001B = 0; + + DRegBuf[0] = 0; + DRegBuf[1] = 2; + DRegBuf[2] = 4; + DRegBuf[3] = 5; + DRegBuf[4] = 6; + DRegBuf[5] = 7; + DRegBuf[6] = 0; + DRegBuf[7] = 1; + + Fix158BMMC3PRG(MMC3cmd); + Fix158BMMC3CHR(MMC3cmd); + + nes->pad->SetExController( 3 ); +} + +BYTE BoardUNL158B::ReadLow( WORD addr ) +{ + if((addr>=0x5000)&&(addr<=0x5007)) return lut[addr&7]; + return Mapper::ReadLow( addr ); +} + +void BoardUNL158B::WriteLow( WORD addr, BYTE data ) +{ + if((addr>=0x5000)&&(addr<=0x5007)){ + EXPREGS[addr & 7] = data; + switch(addr & 7) { + case 0: + Fix158BMMC3PRG(MMC3cmd); + break; + case 7: + // + break; + } + } +} +void BoardUNL158B::Write( WORD addr, BYTE data ) +{ + MMC3CMDWrite(addr, data); + MMC3IRQWrite(addr, data); +} + +void BoardUNL158B::MMC3CMDWrite( WORD addr, BYTE data ) +{ + switch (addr & 0xE001) { + case 0x8000: + if ((data & 0x40) != (MMC3cmd & 0x40)) + Fix158BMMC3PRG(data); + if ((data & 0x80) != (MMC3cmd & 0x80)) + Fix158BMMC3CHR(data); + MMC3cmd = data; + break; + case 0x8001: + { + int cbase = (MMC3cmd & 0x80) << 5; + DRegBuf[MMC3cmd & 0x7] = data; + switch (MMC3cmd & 0x07) { + case 0: + PPUSW((cbase ^ 0x000), data & (~1)); + PPUSW((cbase ^ 0x400), data | 1); + break; + case 1: + PPUSW((cbase ^ 0x800), data & (~1)); + PPUSW((cbase ^ 0xC00), data | 1); + break; + case 2: + PPUSW(cbase ^ 0x1000, data); + break; + case 3: + PPUSW(cbase ^ 0x1400, data); + break; + case 4: + PPUSW(cbase ^ 0x1800, data); + break; + case 5: + PPUSW(cbase ^ 0x1C00, data); + break; + case 6: + if (MMC3cmd&0x40) CPUSW(0xC000, data); + else CPUSW(0x8000, data); + break; + case 7: + CPUSW(0xA000, data); + break; + } + break; + } + case 0xA000: + A000B = data; + if (!nes->rom->Is4SCREEN()) { + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + } + break; + case 0xA001: + A001B = data; + break; + } +} + +void BoardUNL158B::MMC3IRQWrite( WORD addr, BYTE data ) +{ + switch (addr & 0xE001) { + case 0xC000: IRQReload = 0;IRQCount = data; break; + case 0xC001: IRQReload = 0;IRQLatch = data; break; + case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xE001: IRQReload = 0;IRQa = 1; break; + } +} + +void BoardUNL158B::PPUSW(WORD A, BYTE V) +{ + SetVROM_1K_Bank(A>>10, V); +} + +void BoardUNL158B::CPUSW(WORD A, BYTE V) +{ + if (EXPREGS[0] & 0x80) { + uint32 bank = EXPREGS[0] & 7; + if(EXPREGS[0] & 0x20) { // 32Kb mode + SetPROM_32K_Bank(bank >> 1); + } else { // 16Kb mode + SetPROM_16K_Bank(4, bank); + SetPROM_16K_Bank(6, bank); + } + } else { + SetPROM_8K_Bank(A>>13, V & 0xF); + } +} + +void BoardUNL158B::Fix158BMMC3PRG(BYTE data) +{ + if (data & 0x40) { + CPUSW(0xC000, DRegBuf[6]); + CPUSW(0x8000, ~1); + } else { + CPUSW(0x8000, DRegBuf[6]); + CPUSW(0xC000, ~1); + } + CPUSW(0xA000, DRegBuf[7]); + CPUSW(0xE000, ~0); +} + +void BoardUNL158B::Fix158BMMC3CHR(BYTE data) +{ + int cbase = (data & 0x80) << 5; + PPUSW((cbase ^ 0x000), DRegBuf[0] & (~1)); + PPUSW((cbase ^ 0x400), DRegBuf[0] | 1); + PPUSW((cbase ^ 0x800), DRegBuf[1] & (~1)); + PPUSW((cbase ^ 0xC00), DRegBuf[1] | 1); + PPUSW(cbase ^ 0x1000, DRegBuf[2]); + PPUSW(cbase ^ 0x1400, DRegBuf[3]); + PPUSW(cbase ^ 0x1800, DRegBuf[4]); + PPUSW(cbase ^ 0x1c00, DRegBuf[5]); +} + +void BoardUNL158B::HSync(INT scanline) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (IRQa && !IRQReload) { + if (scanline == 0) { + if (IRQCount) { + IRQCount -= 1; + } + } + if (!(IRQCount)){ + IRQReload = 0xFF; + IRQCount = IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + IRQCount--; + } + } + } +} + +void BoardUNL158B::SaveState( LPBYTE p ) +{ + // +} + +void BoardUNL158B::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL158B.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL158B.h new file mode 100644 index 00000000..14bb488a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL158B.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// BoardUNL158B // +////////////////////////////////////////////////////////////////////////// +class BoardUNL158B : public Mapper +{ +public: + BoardUNL158B( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE EXPREGS[8]; + BYTE MMC3cmd; + BYTE DRegBuf[8]; + BYTE A000B, A001B; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; +private: + void MMC3CMDWrite(WORD addr, BYTE data); + void MMC3IRQWrite(WORD addr, BYTE data); + void PPUSW(WORD A, BYTE V); + void CPUSW(WORD A, BYTE V); + void Fix158BMMC3PRG(BYTE data); + void Fix158BMMC3CHR(BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL831128C.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL831128C.cpp new file mode 100644 index 00000000..36aedc68 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL831128C.cpp @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// Board831128C // +////////////////////////////////////////////////////////////////////////// +void Board831128C::Reset() +{ + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + bn = 1; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + +} + +void Board831128C::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + + BYTE bank = (data&((0x10*bn)|0x0F))+(0x10*bn); + switch( addr & 0x0F ) { + case 0x00: case 0x01: + case 0x02: case 0x03: + case 0x04: case 0x05: + case 0x06: case 0x07: + SetVROM_1K_Bank( addr&0x07, data+(0x100*bn) ); + break; + + case 0x08: + if(!bn && !(data&0x40)) SetPROM_8K_Bank( 3, bank ); + break; + case 0x09: + SetPROM_8K_Bank( 4, bank ); + break; + case 0x0A: + SetPROM_8K_Bank( 5, bank ); + break; + case 0x0B: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); +// SetPROM_8K_Bank( 6, bank ); + break; + + case 0x0C: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x0D: + irq_enable = data; + +// irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x0E: + bn = (addr >> 14) & 1; + SetPROM_32K_Bank( 0, 1, 0x0E|(0x20*bn), 0x0F|(0x20*bn) ); + break; + case 0x0F: + irq_counter = (irq_counter & 0xFF00) | RAM[0x0E]; + BYTE VVV = (((data-0xF1)&0xFF)^0xFF)>>1; + irq_counter = (irq_counter & 0x00FF) | (VVV << 8); + +// irq_enable = data & 0x03; +// irq_latch = data; +// irq_counter = data; +// irq_clock = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } + +} + +void Board831128C::HSync( INT scanline ) +{ + if( irq_enable ) { + irq_counter -= 114; + if( irq_counter <= 0 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + irq_enable = 0; + irq_counter = 0xFFFF; + } + } +} + +void Board831128C::Clock( INT cycles ) +{ +/* if( irq_enable ) { + irq_clock += cycles*4; + while( irq_clock >= 455 ) { + irq_clock -= 455; + irq_counter++; + if( irq_counter == 0 ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + }*/ +} + +void Board831128C::SaveState( LPBYTE p ) +{ + // +} + +void Board831128C::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL831128C.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL831128C.h new file mode 100644 index 00000000..fb030911 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardUNL831128C.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Board831128C SunSoft FME-7 // +////////////////////////////////////////////////////////////////////////// +class Board831128C : public Mapper +{ +public: + Board831128C( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void HSync( INT scanline ); + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE bn; + BYTE irq_enable; + INT irq_counter; +// BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardYoko.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/BoardYoko.cpp new file mode 100644 index 00000000..57f97a87 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardYoko.cpp @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////////// +// BoardYoko // +////////////////////////////////////////////////////////////////////////// + +//code by CaH4e3 from fceumm + +void BoardYoko::Reset() +{ + dip = 2; + dip = (dip + 1) & 3; + mode = bank = 0; + + IRQCount = IRQa = 0; + + SetBank(); + + INT BoardNo = NES_ROM_get_unifBoardID(nes->rom->GetBoardName()); + if(BoardNo==642) SPROM = 0; //Master Fighter VI' (YOKO-Y1) [U][!] + if(BoardNo==644) SPROM = 1; //Master Fighter VI' (Unl,EJ-4003) + +} + +BYTE BoardYoko::ReadLow( WORD addr ) +{ + if((addr>=0x5000)&&(addr<=0x53FF)) return (((BYTE)(addr>>8)) & 0xFC) | dip; + + if((addr>=0x5400)&&(addr<=0x5FFF)) return low[addr & 3]; + + if( addr >= 0x6000 ) return Mapper::ReadLow( addr ); + + return (BYTE)(addr>>8); +} + +void BoardYoko::WriteLow( WORD addr, BYTE data ) +{ + if((addr>=0x5400)&&(addr<=0x5FFF)) low[addr & 3] = data; +} + +void BoardYoko::Write( WORD addr, BYTE data ) +{ + if(SPROM==0){ + switch (addr & 0x8C17) { + case 0x8000: bank = data; SetBank(); break; + case 0x8400: mode = data; SetBank(); break; + case 0x8800: IRQCount &= 0xFF00; IRQCount |= data; nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0x8801: IRQa = mode & 0x80; IRQCount &= 0xFF; IRQCount |= data << 8; break; + case 0x8c00: reg[0] = data; SetBank(); break; + case 0x8c01: reg[1] = data; SetBank(); break; + case 0x8c02: reg[2] = data; SetBank(); break; + case 0x8c10: reg[3] = data; SetBank(); break; + case 0x8c11: reg[4] = data; SetBank(); break; + case 0x8c16: reg[5] = data; SetBank(); break; + case 0x8c17: reg[6] = data; SetBank(); break; + } + }else if(SPROM==1){ + switch (addr){ + case 0x9001: bank = data; SetBank(); break; + case 0x9000: mode = (data&0xFE)+(~(data&1)); SetBank(); break; + case 0xC000: IRQCount &= 0xFF00; IRQCount |= data; nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xC001: IRQa = mode & 0x80; IRQCount &= 0xFF; IRQCount |= data << 8; break; + case 0x8000: + case 0x8C00: reg[0] = data; SetBank(); break; + case 0x8C01: reg[1] = data; SetBank(); break; + case 0x8C02: reg[2] = data; SetBank(); break; + case 0xC002: + case 0xA000: reg[3] = data; SetBank(); break; + case 0xA001: reg[4] = data; SetBank(); break; + case 0xB002: reg[5] = data; SetBank(); break; + case 0xB003: reg[6] = data; SetBank(); break; + } + } +} + +void BoardYoko::SetBank() { + if(mode&1) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + SetVROM_2K_Bank(0, reg[3]); + SetVROM_2K_Bank(2, reg[4]); + SetVROM_2K_Bank(4, reg[5]); + SetVROM_2K_Bank(6, reg[6]); + if (mode & 0x10) { + uint32 base = (bank & 8) << 1; + SetPROM_8K_Bank(4, (reg[0] & 0x0f) | base); + SetPROM_8K_Bank(5, (reg[1] & 0x0f) | base); + SetPROM_8K_Bank(6, (reg[2] & 0x0f) | base); + SetPROM_8K_Bank(7, 0x0f | base); + } else { + if (mode & 8) + SetPROM_32K_Bank(bank >> 1); + else { + SetPROM_16K_Bank(4, bank); + SetPROM_16K_Bank(6, 7); + } + } +} + +void BoardYoko::HSync( INT scanline ) +{ + if( IRQa ) { + if( IRQCount <= 113 ) { + IRQa = 0; + nes->cpu->SetIRQ( IRQ_TRIGGER ); + } else { + IRQCount -= 113; + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/BoardYoko.h b/References/VirtuaNESex_src_191105/NES/Mapper/BoardYoko.h new file mode 100644 index 00000000..2dcd038f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/BoardYoko.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// BoardYoko // +////////////////////////////////////////////////////////////////////////// +class BoardYoko : public Mapper +{ +public: + BoardYoko( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow(WORD addr); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync( INT scanline ); +// void Clock( INT cycles ); + +protected: + BYTE reg[8], low[4]; + BYTE mode, bank, dip; + BYTE IRQa; + WORD IRQCount; + BYTE SPROM; +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/EEPROM.h b/References/VirtuaNESex_src_191105/NES/Mapper/EEPROM.h new file mode 100644 index 00000000..fe0436ce --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/EEPROM.h @@ -0,0 +1,411 @@ +class X24C01 +{ +public: + X24C01() { + now_state = X24C01_IDLE; + next_state = X24C01_IDLE; + addr = 0; + data = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = NULL; + } + + void Reset( LPBYTE ptr ) { + now_state = X24C01_IDLE; + next_state = X24C01_IDLE; + addr = 0; + data = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = ptr; + } + + void Write( BYTE scl_in, BYTE sda_in ) { + // Clock line + BYTE scl_rise = ~scl_old & scl_in; + BYTE scl_fall = scl_old & ~scl_in; + // Data line + BYTE sda_rise = ~sda_old & sda_in; + BYTE sda_fall = sda_old & ~sda_in; + + BYTE scl_old_temp = scl_old; + BYTE sda_old_temp = sda_old; + + scl_old = scl_in; + sda_old = sda_in; + + // Start condition? + if( scl_old_temp && sda_fall ) { + now_state = X24C01_ADDRESS; + bitcnt = 0; + addr = 0; + sda = 0xFF; + return; + } + + // Stop condition? + if( scl_old_temp && sda_rise ) { + now_state = X24C01_IDLE; + sda = 0xFF; + return; + } + + // SCL ____---- RISE + if( scl_rise ) { + switch( now_state ) { + case X24C01_ADDRESS: + if( bitcnt < 7 ) { + // {MSB->LSB + addr &= ~(1<LSB + sda = (data&(1<LSB + data &= ~(1<= 8 ) { + now_state = X24C01_ACK; + sda = 0xFF; + } + break; + case X24C01_ACK: + now_state = next_state; + bitcnt = 0; + sda = 0xFF; + break; + case X24C01_READ: + if( bitcnt >= 8 ) { + now_state = X24C01_ACK_WAIT; + addr = (addr+1)&0x7F; + } + break; + case X24C01_WRITE: + if( bitcnt >= 8 ) { + now_state = X24C01_ACK; + next_state = X24C01_IDLE; + pEEPDATA[addr&0x7F] = data; + addr = (addr+1)&0x7F; + } + break; + } + } + } + + BYTE Read() { + return sda; + } + + // For State save + void Load( LPBYTE p ) + { + now_state = *((INT*)&p[0]); + next_state = *((INT*)&p[4]); + bitcnt = *((INT*)&p[8]); + addr = p[12]; + data = p[13]; + sda = p[14]; + scl_old = p[15]; + sda_old = p[16]; + } + + void Save( LPBYTE p ) + { + *((INT*)&p[0]) = now_state; + *((INT*)&p[4]) = next_state; + *((INT*)&p[8]) = bitcnt; + p[12] = addr; + p[13] = data; + p[14] = sda; + p[15] = scl_old; + p[16] = sda_old; + } + +protected: + enum { + X24C01_IDLE = 0, // Idle + X24C01_ADDRESS, // Address set + X24C01_READ, // Read + X24C01_WRITE, // Write + X24C01_ACK, // Acknowledge + X24C01_ACK_WAIT, // Acknowledge wait + }; + + INT now_state, next_state; + INT bitcnt; + BYTE addr, data; + BYTE sda; + BYTE scl_old, sda_old; + + LPBYTE pEEPDATA; +private: +}; + +class X24C02 +{ +public: + X24C02() { + now_state = X24C02_IDLE; + next_state = X24C02_IDLE; + addr = 0; + data = 0; + rw = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = NULL; + } + + void Reset( LPBYTE ptr ) { + now_state = X24C02_IDLE; + next_state = X24C02_IDLE; + addr = 0; + data = 0; + rw = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = ptr; + } + + void Write( BYTE scl_in, BYTE sda_in ) { + // Clock line + BYTE scl_rise = ~scl_old & scl_in; + BYTE scl_fall = scl_old & ~scl_in; + // Data line + BYTE sda_rise = ~sda_old & sda_in; + BYTE sda_fall = sda_old & ~sda_in; + + BYTE scl_old_temp = scl_old; + BYTE sda_old_temp = sda_old; + + scl_old = scl_in; + sda_old = sda_in; + + // Start condition? + if( scl_old_temp && sda_fall ) { + now_state = X24C02_DEVADDR; + bitcnt = 0; + sda = 0xFF; + return; + } + + // Stop condition? + if( scl_old_temp && sda_rise ) { + now_state = X24C02_IDLE; + sda = 0xFF; + return; + } + + // SCL ____---- RISE + if( scl_rise ) { + switch( now_state ) { + case X24C02_DEVADDR: + if( bitcnt < 8 ) { + data &= ~(1<<(7-bitcnt)); + data |= (sda_in?1:0)<<(7-bitcnt); + } + bitcnt++; + break; + case X24C02_ADDRESS: + if( bitcnt < 8 ) { + addr &= ~(1<<(7-bitcnt)); + addr |= (sda_in?1:0)<<(7-bitcnt); + } + bitcnt++; + break; + case X24C02_READ: + if( bitcnt < 8 ) { + sda = (data&(1<<(7-bitcnt)))?1:0; + } + bitcnt++; + break; + case X24C02_WRITE: + if( bitcnt < 8 ) { + data &= ~(1<<(7-bitcnt)); + data |= (sda_in?1:0)<<(7-bitcnt); + } + bitcnt++; + break; + case X24C02_NAK: + sda = 0xFF; // NAK + break; + case X24C02_ACK: + sda = 0; // ACK + break; + case X24C02_ACK_WAIT: + if( !sda_in ) { + next_state = X24C02_READ; + data = pEEPDATA[addr]; + } + break; + } + } + + // SCL ----____ FALL + if( scl_fall ) { + switch( now_state ) { + case X24C02_DEVADDR: + if( bitcnt >= 8 ) { + if( (data & 0xA0) == 0xA0 ) { + now_state = X24C02_ACK; + rw = data & 0x01; + sda = 0xFF; + if( rw ) { + // Now address read + next_state = X24C02_READ; + data = pEEPDATA[addr]; + } else { + next_state = X24C02_ADDRESS; + } + bitcnt = 0; + } else { + now_state = X24C02_NAK; + next_state = X24C02_IDLE; + sda = 0xFF; + } + } + break; + case X24C02_ADDRESS: + if( bitcnt >= 8 ) { + now_state = X24C02_ACK; + sda = 0xFF; + if( rw ) { + // Readł͐ΗȂÖ + next_state = X24C02_IDLE; + } else { + // to Data Write + next_state = X24C02_WRITE; + } + bitcnt = 0; + } + break; + case X24C02_READ: + if( bitcnt >= 8 ) { + now_state = X24C02_ACK_WAIT; + addr = (addr+1)&0xFF; + } + break; + case X24C02_WRITE: + if( bitcnt >= 8 ) { + pEEPDATA[addr] = data; + now_state = X24C02_ACK; + next_state = X24C02_WRITE; + addr = (addr+1)&0xFF; + bitcnt = 0; + } + break; + case X24C02_NAK: + now_state = X24C02_IDLE; + bitcnt = 0; + sda = 0xFF; + break; + case X24C02_ACK: + now_state = next_state; + bitcnt = 0; + sda = 0xFF; + break; + case X24C02_ACK_WAIT: + now_state = next_state; + bitcnt = 0; + sda = 0xFF; + break; + } + } + } + + BYTE Read() { + return sda; + } + + // For State save + void Load( LPBYTE p ) + { + now_state = *((INT*)&p[0]); + next_state = *((INT*)&p[4]); + bitcnt = *((INT*)&p[8]); + addr = p[12]; + data = p[13]; + rw = p[14]; + sda = p[15]; + scl_old = p[16]; + sda_old = p[17]; + } + + void Save( LPBYTE p ) + { + *((INT*)&p[0]) = now_state; + *((INT*)&p[4]) = next_state; + *((INT*)&p[8]) = bitcnt; + p[12] = addr; + p[13] = data; + p[14] = rw; + p[15] = sda; + p[16] = scl_old; + p[17] = sda_old; + } + +protected: + enum { + X24C02_IDLE = 0, // Idle + X24C02_DEVADDR, // Device address set + X24C02_ADDRESS, // Address set + X24C02_READ, // Read + X24C02_WRITE, // Write + X24C02_ACK, // Acknowledge + X24C02_NAK, // Not Acknowledge + X24C02_ACK_WAIT, // Acknowledge wait + }; + + INT now_state, next_state; + INT bitcnt; + BYTE addr, data, rw; + BYTE sda; + BYTE scl_old, sda_old; + + LPBYTE pEEPDATA; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper.cpp new file mode 100644 index 00000000..82f251ce --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper.cpp @@ -0,0 +1,454 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* NES Mapeers */ +/* Norix */ +/* written 2000/02/05 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +/*--------------[ INCLUDE ]-------------------------------*/ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "DebugOut.h" +#include "typedef.h" +#include "macro.h" + +#include "nes.h" +#include "mmu.h" + +#include "mapper.h" + +#include +const BOARDINFO BoardInfo[]= +{ + { "ACCLAIM-AOROM", STD_AOROM }, + { "ACCLAIM-MC-ACC", STD_TLROM }, + { "ACCLAIM-TLROM", STD_TLROM }, + { "AGCI-47516", DISCRETE_74_377 }, + { "AGCI-50282", AGCI_50282 }, + { "AVE-74*161", UNL_CXROM }, + { "AVE-MB-91", AVE_MB_91 }, + { "AVE-NINA-01", AVE_NINA001 }, + { "AVE-NINA-02", AVE_NINA002 }, + { "AVE-NINA-03", AVE_NINA03 }, + { "AVE-NINA-06", AVE_NINA06 }, + { "AVE-NINA-07", AVE_NINA07 }, + { "BANDAI-74*161/161/32", DISCRETE_74_161_161_32_A }, + { "BANDAI-CNROM", STD_CNROM }, + { "BANDAI-FCG-1", BANDAI_FCG1 }, + { "BANDAI-FCG-2", BANDAI_FCG2 }, + { "BANDAI-GNROM", STD_GNROM }, + { "BANDAI-JUMP2", BANDAI_BAJUMP2 }, + { "BANDAI-LZ93D50+24C01", BANDAI_LZ93D50_24C01 }, + { "BANDAI-LZ93D50+24C02", BANDAI_LZ93D50_24C02 }, + { "BANDAI-NROM-128", STD_NROM }, + { "BANDAI-NROM-256", STD_NROM }, + { "BANDAI-PT-554", BANDAI_AEROBICSSTUDIO }, + { "BMC-190IN1", BMC_GOLDEN_190IN1 }, + { "BMC-42IN1RESETSWITCH", BMC_SUPER_22GAMES }, + { "BMC-64IN1NOREPEAT", BMC_Y2K_64IN1 }, + { "BMC-70IN1", BMC_GAME_800IN1 }, + { "BMC-70IN1B", BMC_GAME_800IN1 }, + { "BMC-8157", BMC_8157 }, + { "BMC-A65AS", BMC_A65AS }, + { "BMC-BS-5", BENSHENG_BS5 }, + { "BMC-D1038", BMC_VT5201 }, + { "BMC-FK23C", BMC_FK23C }, + { "BMC-GHOSTBUSTERS63IN1", BMC_CTC65 }, + { "BMC-GS-2004", RCM_GS2004 }, + { "BMC-GS-2013", RCM_GS2013 }, + { "BMC-N625092", UNL_N625092 }, + { "BMC-NOVELDIAMOND9999999IN1", BMC_NOVELDIAMOND }, + { "BMC-SUPER24IN1SC03", BMC_SUPER_24IN1 }, + { "BMC-SUPERHIK8IN1", BMC_HERO }, + { "BMC-SUPERVISION16IN1", BMC_SUPERVISION_16IN1 }, + { "BMC-T-262", BMC_T262 }, + { "BMC-WS", BMC_SUPER_40IN1 }, + { "BTL-MARIO1-MALEE2", BTL_GENIUSMERIOBROS }, + { "CAMERICA-ALGN", CAMERICA_ALGNV11 }, + { "CAMERICA-ALGQ", CAMERICA_ALGQV11 }, + { "CAMERICA-BF9093", CAMERICA_BF9093 }, + { "CAMERICA-BF9096", CAMERICA_BF9096 }, + { "CAMERICA-BF9097", CAMERICA_BF9097 }, + { "CAMERICA-GAMEGENIE", STD_NROM }, + { "COLORDREAMS-74*377", DISCRETE_74_377 }, + { "DREAMTECH01", DREAMTECH_01 }, + { "HVC-AMROM", STD_AMROM }, + { "HVC-AN1ROM", STD_AN1ROM }, + { "HVC-ANROM", STD_ANROM }, + { "HVC-AOROM", STD_AOROM }, + { "HVC-BNROM", STD_BNROM }, + { "HVC-CNROM", STD_CNROM }, + { "HVC-CPROM", STD_CPROM }, + { "HVC-DE1ROM", STD_DE1ROM }, + { "HVC-DEROM", STD_DEROM }, + { "HVC-DRROM", STD_DRROM }, + { "HVC-EKROM", STD_EKROM }, + { "HVC-ELROM", STD_ELROM }, + { "HVC-ETROM", STD_ETROM }, + { "HVC-EWROM", STD_EWROM }, + { "HVC-FAMILYBASIC", CUSTOM_FB02 }, + { "HVC-FJROM", STD_FJROM }, + { "HVC-FKROM", STD_FKROM }, + { "HVC-GNROM", STD_GNROM }, + { "HVC-HKROM", STD_HKROM }, + { "HVC-HROM", STD_NROM }, + { "HVC-JLROM", STD_JLROM }, + { "HVC-JSROM", STD_JSROM }, + { "HVC-MHROM", STD_MHROM }, + { "HVC-NROM", STD_NROM }, + { "HVC-NROM-128", STD_NROM }, + { "HVC-NROM-256", STD_NROM }, + { "HVC-NTBROM", STD_NTBROM }, + { "HVC-PEEOROM", STD_PEEOROM }, + { "HVC-PNROM", STD_PNROM }, + { "HVC-RROM", STD_NROM }, + { "HVC-RROM-128", STD_NROM }, + { "HVC-SAROM", STD_SAROM }, + { "HVC-SBROM", STD_SBROM }, + { "HVC-SC1ROM", STD_SCROM }, + { "HVC-SCROM", STD_SCROM }, + { "HVC-SEROM", STD_SEROM }, + { "HVC-SF1ROM", STD_SFROM }, + { "HVC-SFROM", STD_SFROM }, + { "HVC-SGROM", STD_SGROM }, + { "HVC-SH1ROM", STD_SHROM }, + { "HVC-SHROM", STD_SHROM }, + { "HVC-SJROM", STD_SJROM }, + { "HVC-SKROM", STD_SKROM }, + { "HVC-SL1ROM", STD_SLROM }, + { "HVC-SL2ROM", STD_SLROM }, + { "HVC-SL3ROM", STD_SLROM }, + { "HVC-SLROM", STD_SLROM }, + { "HVC-SLRROM", STD_SLROM }, + { "HVC-SNROM", STD_SNROM }, + { "HVC-SOROM", STD_SOROM }, + { "HVC-SROM", STD_NROM }, + { "HVC-STROM", STD_NROM }, + { "HVC-SUROM", STD_SUROM }, + { "HVC-SXROM", STD_SXROM }, + { "HVC-TBROM", STD_TBROM }, + { "HVC-TEROM", STD_TEROM }, + { "HVC-TFROM", STD_TFROM }, + { "HVC-TGROM", STD_TGROM }, + { "HVC-TKROM", STD_TKROM }, + { "HVC-TKSROM", STD_TKSROM }, + { "HVC-TL1ROM", STD_TLROM }, + { "HVC-TL2ROM", STD_TLROM }, + { "HVC-TLROM", STD_TLROM }, + { "HVC-TLSROM", STD_TLSROM }, + { "HVC-TNROM", STD_TNROM }, + { "HVC-TQROM", STD_TQROM }, + { "HVC-TR1ROM", STD_TR1ROM }, + { "HVC-TSROM", STD_TSROM }, + { "HVC-TVROM", STD_TVROM }, + { "HVC-UN1ROM", STD_UN1ROM }, + { "HVC-UNROM", STD_UNROM }, + { "HVC-UOROM", STD_UOROM }, + { "IREM-74*161/161/21/138", IREM_LROG017 }, + { "IREM-BNROM", STD_BNROM }, + { "IREM-G101", IREM_G101A_0 }, + { "IREM-G101-A", IREM_G101A_0 }, + { "IREM-G101-B", IREM_G101B_0 }, + { "IREM-HOLYDIVER", IREM_HOLYDIVER }, + { "IREM-NROM-128", STD_NROM }, + { "IREM-NROM-256", STD_NROM }, + { "IREM-UNROM", STD_UNROM }, + { "JALECO-JF-01", JALECO_JF01 }, + { "JALECO-JF-02", JALECO_JF02 }, + { "JALECO-JF-03", JALECO_JF03 }, + { "JALECO-JF-04", JALECO_JF04 }, + { "JALECO-JF-05", JALECO_JF05 }, + { "JALECO-JF-06", JALECO_JF06 }, + { "JALECO-JF-07", JALECO_JF07 }, + { "JALECO-JF-08", JALECO_JF08 }, + { "JALECO-JF-09", JALECO_JF09 }, + { "JALECO-JF-10", JALECO_JF10 }, + { "JALECO-JF-11", JALECO_JF11 }, + { "JALECO-JF-12", JALECO_JF12 }, + { "JALECO-JF-13", JALECO_JF13 }, + { "JALECO-JF-14", JALECO_JF14 }, + { "JALECO-JF-15", JALECO_JF15 }, + { "JALECO-JF-16", JALECO_JF16 }, + { "JALECO-JF-17", JALECO_JF17 }, + { "JALECO-JF-18", JALECO_JF18 }, + { "JALECO-JF-19", JALECO_JF19 }, + { "JALECO-JF-20", JALECO_JF20 }, + { "JALECO-JF-21", JALECO_JF21 }, + { "JALECO-JF-22", JALECO_JF22 }, + { "JALECO-JF-23", JALECO_JF23 }, + { "JALECO-JF-24", JALECO_JF24 }, + { "JALECO-JF-25", JALECO_JF25 }, + { "JALECO-JF-26", JALECO_JF26 }, + { "JALECO-JF-27", JALECO_JF27 }, + { "JALECO-JF-28", JALECO_JF28 }, + { "JALECO-JF-29", JALECO_JF29 }, + { "JALECO-JF-30", JALECO_JF30 }, + { "JALECO-JF-31", JALECO_JF31 }, + { "JALECO-JF-32", JALECO_JF32 }, + { "JALECO-JF-33", JALECO_JF33 }, + { "JALECO-JF-34", JALECO_JF34 }, + { "JALECO-JF-35", JALECO_JF35 }, + { "JALECO-JF-36", JALECO_JF36 }, + { "JALECO-JF-37", JALECO_JF37 }, + { "JALECO-JF-38", JALECO_JF38 }, + { "JALECO-JF-39", JALECO_JF39 }, + { "JALECO-JF-40", JALECO_JF40 }, + { "JALECO-JF-41", JALECO_JF41 }, + { "KONAMI-74*139/74", DISCRETE_74_139_74 }, + { "KONAMI-CNROM", STD_CNROM }, + { "KONAMI-NROM-128", STD_NROM }, + { "KONAMI-SLROM", STD_SLROM }, + { "KONAMI-TLROM", STD_TLROM }, + { "KONAMI-UNROM", STD_UNROM }, + { "KONAMI-VRC-1", KONAMI_VRC1 }, + { "KONAMI-VRC-2", KONAMI_VRC2 }, + { "KONAMI-VRC-3", KONAMI_VRC3 }, + { "KONAMI-VRC-4", KONAMI_VRC4_0 }, + { "KONAMI-VRC-6", KONAMI_VRC6_0 }, + { "KONAMI-VRC-7", KONAMI_VRC7_0 }, + { "MLT-ACTION52", AE_STD }, + { "MLT-CALTRON6IN1", CALTRON_6IN1 }, + { "MLT-MAXI15", AVE_D1012 }, + { "NAMCOT-163", NAMCOT_163_0 }, + { "NAMCOT-3301", STD_NROM }, + { "NAMCOT-3302", STD_NROM }, + { "NAMCOT-3303", STD_NROM }, + { "NAMCOT-3305", STD_NROM }, + { "NAMCOT-3311", STD_NROM }, + { "NAMCOT-3401", STD_DE1ROM }, + { "NAMCOT-3405", STD_DE1ROM }, + { "NAMCOT-3406", STD_DE1ROM }, + { "NAMCOT-3407", STD_DE1ROM }, + { "NAMCOT-3411", STD_NROM }, + { "NAMCOT-3413", STD_DE1ROM }, + { "NAMCOT-3414", STD_DE1ROM }, + { "NAMCOT-3415", STD_DE1ROM }, + { "NAMCOT-3416", STD_DE1ROM }, + { "NAMCOT-3417", STD_DE1ROM }, + { "NAMCOT-3425", NAMCOT_3425 }, + { "NAMCOT-3433", NAMCOT_3433 }, + { "NAMCOT-3443", NAMCOT_3443 }, + { "NAMCOT-3446", NAMCOT_3446 }, + { "NAMCOT-3451", STD_DE1ROM }, + { "NES-AMROM", STD_AMROM }, + { "NES-AN1ROM", STD_AN1ROM }, + { "NES-ANROM", STD_ANROM }, + { "NES-AOROM", STD_AOROM }, + { "NES-B4", STD_TLROM }, + { "NES-BNROM", STD_BNROM }, + { "NES-BTR", CUSTOM_BTR }, + { "NES-CNROM", STD_CNROM }, + { "NES-CPROM", STD_CPROM }, + { "NES-DE1ROM", STD_DE1ROM }, + { "NES-DEROM", STD_DEROM }, + { "NES-DRROM", STD_DRROM }, + { "NES-EKROM", STD_EKROM }, + { "NES-ELROM", STD_ELROM }, + { "NES-ETROM", STD_ETROM }, + { "NES-EVENT", CUSTOM_EVENT }, + { "NES-EWROM", STD_EWROM }, + { "NES-FJROM", STD_FJROM }, + { "NES-FKROM", STD_FKROM }, + { "NES-GNROM", STD_GNROM }, + { "NES-HKROM", STD_HKROM }, + { "NES-HROM", STD_NROM }, + { "NES-JLROM", STD_JLROM }, + { "NES-JSROM", STD_JSROM }, + { "NES-MHROM", STD_MHROM }, + { "NES-NROM", STD_NROM }, + { "NES-NROM-128", STD_NROM }, + { "NES-NROM-256", STD_NROM }, + { "NES-NTBROM", STD_NTBROM }, + { "NES-PEEOROM", STD_PEEOROM }, + { "NES-PNROM", STD_PNROM }, + { "NES-QJ", CUSTOM_QJ }, + { "NES-RROM", STD_NROM }, + { "NES-RROM-128", STD_NROM }, + { "NES-SAROM", STD_SAROM }, + { "NES-SBROM", STD_SBROM }, + { "NES-SC1ROM", STD_SCROM }, + { "NES-SCROM", STD_SCROM }, + { "NES-SEROM", STD_SEROM }, + { "NES-SF1ROM", STD_SFROM }, + { "NES-SFROM", STD_SFROM }, + { "NES-SGROM", STD_SGROM }, + { "NES-SH1ROM", STD_SHROM }, + { "NES-SHROM", STD_SHROM }, + { "NES-SJROM", STD_SJROM }, + { "NES-SKROM", STD_SKROM }, + { "NES-SL1ROM", STD_SLROM }, + { "NES-SL2ROM", STD_SLROM }, + { "NES-SL3ROM", STD_SLROM }, + { "NES-SLROM", STD_SLROM }, + { "NES-SLRROM", STD_SLROM }, + { "NES-SNROM", STD_SNROM }, + { "NES-SOROM", STD_SOROM }, + { "NES-SROM", STD_NROM }, + { "NES-STROM", STD_NROM }, + { "NES-SUROM", STD_SUROM }, + { "NES-SXROM", STD_SXROM }, + { "NES-TBROM", STD_TBROM }, + { "NES-TEROM", STD_TEROM }, + { "NES-TFROM", STD_TFROM }, + { "NES-TGROM", STD_TGROM }, + { "NES-TKROM", STD_TKROM }, + { "NES-TKSROM", STD_TKSROM }, + { "NES-TL1ROM", STD_TLROM }, + { "NES-TL2ROM", STD_TLROM }, + { "NES-TLROM", STD_TLROM }, + { "NES-TLSROM", STD_TLSROM }, + { "NES-TNROM", STD_TNROM }, + { "NES-TQROM", STD_TQROM }, + { "NES-TR1ROM", STD_TR1ROM }, + { "NES-TSROM", STD_TSROM }, + { "NES-TVROM", STD_TVROM }, + { "NES-UN1ROM", STD_UN1ROM }, + { "NES-UNROM", STD_UNROM }, + { "NES-UOROM", STD_UOROM }, + { "NES-WH", CUSTOM_WH }, + { "NTDEC-N715062", NTDEC_N715062 }, + { "PAL-MH", STD_MHROM }, + { "PAL-ZZ", CUSTOM_ZZ }, + { "SACHEN-8259A", SACHEN_8259A }, + { "SACHEN-8259B", SACHEN_8259B }, + { "SACHEN-8259C", SACHEN_8259C }, + { "SACHEN-8259D", SACHEN_8259D }, + { "SACHEN-CNROM", STD_CXROM }, + { "SETA-NROM-128", STD_NROM }, + { "SUNSOFT-1", SUNSOFT_1 }, + { "SUNSOFT-2", SUNSOFT_2B }, + { "SUNSOFT-3", SUNSOFT_3 }, + { "SUNSOFT-4", SUNSOFT_4_0 }, + { "SUNSOFT-5B", SUNSOFT_5B_0 }, + { "SUNSOFT-FME-7", SUNSOFT_FME7_0 }, + { "SUNSOFT-NROM-256", STD_NROM }, + { "TAITO-74*139/74", DISCRETE_74_139_74 }, + { "TAITO-74*161/161/32", DISCRETE_74_161_161_32_A }, + { "TAITO-CNROM", STD_CNROM }, + { "TAITO-NROM-128", STD_NROM }, + { "TAITO-NROM-256", STD_NROM }, + { "TAITO-TC0190FMC", TAITO_TC0190FMC }, + { "TAITO-TC0190FMC+PAL16R4", TAITO_TC0190FMC_PAL16R4 }, + { "TAITO-UNROM", STD_UNROM }, + { "TAITO-X1-005", TAITO_X1005 }, + { "TAITO-X1-017", TAITO_X1017 }, + { "TENGEN-800002", TENGEN_800002 }, + { "TENGEN-800003", STD_NROM }, + { "TENGEN-800004", TENGEN_800004 }, + { "TENGEN-800008", TENGEN_800008 }, + { "TENGEN-800030", TENGEN_800030 }, + { "TENGEN-800032", TENGEN_800032 }, + { "TENGEN-800037", TENGEN_800037 }, + { "TENGEN-800042", TENGEN_800042 }, + { "UNL-22211", TXC_22211A }, + { "UNL-603-5052", BTL_6035052 }, + { "UNL-8237", SUPERGAME_POCAHONTAS2 }, + { "UNL-A9746", UNL_A9746 }, + { "UNL-AX5705", BTL_AX5705 }, + { "UNL-CC-21", UNL_CC21 }, + { "UNL-EDU2000", UNL_EDU2000 }, + { "UNL-H2288", KAY_H2288 }, + { "UNL-KOF97", UNL_KINGOFFIGHTERS97 }, + { "UNL-KS7032", KAISER_KS7032 }, + { "UNL-N625092", UNL_N625092 }, + { "UNL-SA-0036", SACHEN_SA0036 }, + { "UNL-SA-0037", SACHEN_SA0037 }, + { "UNL-SA-016-1M", SACHEN_SA0161M }, + { "UNL-SA-72007", SACHEN_SA72007 }, + { "UNL-SA-72008", SACHEN_SA72008 }, + { "UNL-SA-NROM", SACHEN_TCA01 }, + { "UNL-SACHEN-74LS374N", SACHEN_74_374B }, + { "UNL-SACHEN-8259A", SACHEN_8259A }, + { "UNL-SACHEN-8259B", SACHEN_8259B }, + { "UNL-SACHEN-8259C", SACHEN_8259C }, + { "UNL-SACHEN-8259D", SACHEN_8259D }, + { "UNL-SHERO", SACHEN_STREETHEROES }, + { "UNL-SL1632", REXSOFT_SL1632 }, + { "UNL-SMB2J", BTL_SMB2_C }, + { "UNL-T-230", BTL_T230 }, + { "UNL-TC-U01-1.5M", SACHEN_TCU01 }, + { "UNL-TEK90", JYCOMPANY_TYPE_A }, + { "UNL-TF1201", UNL_TF1201 }, + { "VIRGIN-SNROM", STD_SNROM }, + { "NES-NROM-256-CN", NROM_256_CN }, + { "SUBOR_999", SUBOR_999 }, + { "SMART_GENIUS", SMART_GENIUS }, + { "FK23CA", FK23CA }, + { "BMC-FK23CA", BMC_FK23CA }, + { "FK23C", FK23C }, + { "BMC-Super24in1SC03", BMC_SUPER_24IN1 }, + { "CHINA_ER_SAN2", CHINA_ER_SAN2 }, + { "UNL-SA-9602B", UNL_SA_9602B }, + { "UNL-CITYFIGHT", City_Fighter_IV }, + { "COOLBOY", COOLBOY }, + { "UNL-DRAGONFIGHTER", Dragon_Fighter }, + { "UNL-YOKO", UNL_YOKO }, + { "UNL-OneBus", OneBus }, + { "UNL-82112C", UNL_82112C }, + { "UNL-01-22110-000", MGC_002 }, + { "FF3_CN", FF3_CN }, + { "UNL-KS7010", UNL_KS7010 }, + { "UNL-158B", UNL_158B }, + { "UNL-KS7030", UNL_KS7030 }, + { "UNL-TH2131-1", UNL_TH2131_1 }, + { "UNL-831128C", UNL_831128C }, + { "BMC-LB12IN1", BMC_LB12IN1 }, +}; + +/*--------------[ DEFINE ]-------------------------------*/ +/*--------------[ EXTERNAL PROGRAM ]-------------------------------*/ +/*--------------[ EXTERNAL WORK ]-------------------------------*/ +/*--------------[ WORK ]-------------------------------*/ +/*--------------[ PROTOTYPE ]-------------------------------*/ +/*--------------[ CONST ]-------------------------------*/ +/*--------------[ PROGRAM ]-------------------------------*/ + +////////////////////////////////////////////////////////////////////////// +// Based class implement +////////////////////////////////////////////////////////////////////////// +Mapper::Mapper( NES* parent ) : nes(parent) +{ +} + +Mapper::~Mapper() +{ +} + +// $4100-$7FFF Lower Memory read +BYTE Mapper::ReadLow( WORD addr ) +{ + // $6000-$7FFF WRAM + if( addr >= 0x6000 && addr <= 0x7FFF ) { + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } + + return (BYTE)(addr>>8); +} + +// $4100-$7FFF Lower Memory write +void Mapper::WriteLow( WORD addr, BYTE data ) +{ + // $6000-$7FFF WRAM + if( addr >= 0x6000 && addr <= 0x7FFF ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + +int NES_ROM_get_unifBoardID(char *unif_board) +{//Ż㷨 + int iCount=0; + while(1) + { + if( iCount>=BOARD_MAX ) break; + if(strcmp(BoardInfo[iCount].boardName,unif_board)==0) + { + return BoardInfo[iCount].boardID; + } + iCount++; + } + + return 0; +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper.h new file mode 100644 index 00000000..0447a5ea --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper.h @@ -0,0 +1,588 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* NES Mapper */ +/* Norix */ +/* written 2001/02/05 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +#ifndef __MAPPER_INCLUDED__ +#define __MAPPER_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "DirectSound.h" + +#include "typedef.h" +#include "macro.h" + +// class prototype +class NES; + +// Mapper base class +class Mapper +{ +public: + Mapper( NES* parent ); + virtual ~Mapper(); + + // For Mapper + // Reset + virtual void Reset() = 0; + + // $8000-$FFFF Memory write + virtual void Write( WORD addr, BYTE data ) {} + + // $8000-$FFFF Memory read + virtual BYTE Read( WORD addr) {return CPU_MEM_BANK[addr>>13][addr&0x1FFF];} + + virtual BOOL ReadHigh( WORD addr, LPBYTE pdata ) { return FALSE; } + + // $4100-$7FFF Lower Memory read/write + virtual BYTE ReadLow ( WORD addr ); + virtual void WriteLow( WORD addr, BYTE data ); + + // $4018-$40FF Extention register read/write + virtual BYTE ExRead ( WORD addr ) { return 0x00; } + virtual void ExWrite( WORD addr, BYTE data ) {} + + // Extension commands + // For ExCmdRead command + enum EXCMDRD { + EXCMDRD_NONE = 0, + EXCMDRD_DISKACCESS, + }; + // For ExCmdWrite command + enum EXCMDWR { + EXCMDWR_NONE = 0, + EXCMDWR_DISKINSERT, + EXCMDWR_DISKEJECT, + }; + + virtual void WriteExPPU( WORD addr, BYTE data ) {} + + virtual BYTE ReadExAPU ( WORD addr ) { return 0x00; } + virtual void WriteExAPU( WORD addr, BYTE data ) {} + + virtual BYTE ExCmdRead ( EXCMDRD cmd ) { return 0x00; } + virtual void ExCmdWrite( EXCMDWR cmd, BYTE data ) {} + + // H sync/V sync/Clock sync + virtual void HSync( INT scanline ) {} + virtual void VSync() {} + virtual void Clock( INT cycles ) {} + + // PPU address bus latch + virtual void PPU_Latch( WORD addr ) {} + + // PPU Character latch + virtual void PPU_ChrLatch( WORD addr ) {} + + // PPU Extension character/palette + virtual void PPU_ExtLatchX( INT x ) {} + virtual void PPU_ExtLatch( WORD addr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) {} + + //YuXing + virtual BYTE PPU_ExtLatchSP() { return 0; } + + // For State save + virtual BOOL IsStateSave() { return FALSE; } + virtual void SaveState( LPBYTE p ) {} + virtual void LoadState( LPBYTE p ) {} + +protected: + NES* nes; + +private: +}; + +// Create class instance +extern Mapper* CreateMapper( NES* parent, INT no,BOOL bUnif); + +#endif + +#ifndef _UNIF_H_ +#define _UNIF_H_ + +struct BDINFO { +char boardName[30]; +int boardID; +} ; + +typedef struct BDINFO BOARDINFO; + +extern const BOARDINFO BoardInfo[]; + + +enum BoardID +{ + // NROM + STD_NROM =256 , + // AxROM + STD_AMROM , + STD_ANROM , + STD_AN1ROM , + STD_AOROM , + // BxROM + STD_BNROM , + // CxROM + STD_CNROM , + STD_CXROM , + STD_CPROM , + // DxROM + STD_DEROM , + STD_DE1ROM , + STD_DRROM , + // ExROM + STD_ELROM , + STD_EKROM , + STD_ETROM , + STD_EWROM , + STD_EXROM_0 , + STD_EXROM_1 , + STD_EXROM_2 , + STD_EXROM_3 , + STD_EXROM_4 , + STD_EXROM_5 , + // FxROM + STD_FJROM , + STD_FKROM , + // GxROM + STD_GNROM , + // MxROM + STD_MHROM , + // HxROM + STD_HKROM , + // JxROM + STD_JLROM , + STD_JSROM , + // NxROM + STD_NTBROM , + // PxROM + STD_PNROM , + STD_PNROM_PC10 , + STD_PEEOROM , + // SxROM + STD_SAROM , + STD_SBROM , + STD_SCROM , + STD_SEROM , + STD_SFROM , + STD_SGROM , + STD_SHROM , + STD_SJROM , + STD_SKROM , + STD_SLROM , + STD_SNROM , + STD_SOROM , + STD_SUROM , + STD_SXROM , + // TxROM + STD_TEROM , + STD_TBROM , + STD_TFROM , + STD_TGROM , + STD_TKROM , + STD_TKSROM , + STD_TLROM , + STD_TLSROM , + STD_TNROM , + STD_TQROM , + STD_TR1ROM , + STD_TSROM , + STD_TVROM , + // UxROM + STD_UNROM , + STD_UN1ROM , + STD_UOROM , + STD_UXROM , + // Discrete Logic + DISCRETE_74_377 , + DISCRETE_74_139_74 , + DISCRETE_74_161_138 , + DISCRETE_74_161_161_32_A , + DISCRETE_74_161_161_32_B , + // Other + CUSTOM_B4 , + CUSTOM_BTR , + CUSTOM_EVENT , + CUSTOM_FFE3 , + CUSTOM_FFE4 , + CUSTOM_FFE8 , + CUSTOM_FB02 , + CUSTOM_FB04 , + CUSTOM_RUMBLESTATION , + CUSTOM_QJ , + CUSTOM_VSSYSTEM_0 , + CUSTOM_VSSYSTEM_1 , + CUSTOM_WH , + CUSTOM_X79B , + CUSTOM_ZZ , + // Active Enterprises + AE_STD , + // AGCI + AGCI_50282 , + // AVE + AVE_NINA001 , + AVE_NINA002 , + AVE_NINA03 , + AVE_NINA06 , + AVE_NINA07 , + AVE_MB_91 , + AVE_D1012 , + // Bandai + BANDAI_FCG1 , + BANDAI_FCG2 , + BANDAI_BAJUMP2 , + BANDAI_LZ93D50_24C01 , + BANDAI_LZ93D50_24C02 , + BANDAI_DATACH , + BANDAI_KARAOKESTUDIO , + BANDAI_AEROBICSSTUDIO , + BANDAI_OEKAKIDS , + // Bensheng + BENSHENG_BS5 , + // Bootleg multicarts + BMC_110IN1 , + BMC_150IN1 , + BMC_15IN1 , + BMC_1200IN1 , + BMC_20IN1 , + BMC_21IN1 , + BMC_22GAMES , + BMC_31IN1 , + BMC_35IN1 , + BMC_36IN1 , + BMC_64IN1 , + BMC_72IN1 , + BMC_76IN1 , + BMC_8157 , + BMC_9999999IN1 , + BMC_A65AS , + BMC_BALLGAMES_11IN1 , + BMC_CTC65 , + BMC_DRAGONBOLLPARTY , + BMC_FAMILY_4646B , + BMC_FK23C , + BMC_GAME_800IN1 , + BMC_GOLDEN_190IN1 , + BMC_GOLDENGAME_150IN1 , + BMC_GOLDENGAME_260IN1 , + BMC_GKA , + BMC_GKB , + BMC_GOLDENCARD_6IN1 , + BMC_HERO , + BMC_MARIOPARTY_7IN1 , + BMC_NOVELDIAMOND , + BMC_CH001 , + BMC_POWERJOY_84IN1 , + BMC_RESETBASED_4IN1 , + BMC_SUPER_24IN1 , + BMC_SUPER_22GAMES , + BMC_SUPER_40IN1 , + BMC_SUPER_42IN1 , + BMC_SUPER_700IN1 , + BMC_SUPERBIG_7IN1 , + BMC_SUPERGUN_20IN1 , + BMC_SUPERHIK_4IN1 , + BMC_SUPERHIK_300IN1 , + BMC_SUPERVISION_16IN1 , + BMC_T262 , + BMC_VRC4 , + BMC_VT5201 , + BMC_Y2K_64IN1 , + // Bootlegs + BTL_2708 , + BTL_6035052 , + BTL_AISENSHINICOL , + BTL_AX5705 , + BTL_DRAGONNINJA , + BTL_GENIUSMERIOBROS , + BTL_MARIOBABY , + BTL_PIKACHUY2K , + BTL_SHUIGUANPIPE , + BTL_SMB2_A , + BTL_SMB2_B , + BTL_SMB2_C , + BTL_SMB3 , + BTL_SUPERBROS11 , + BTL_T230 , + BTL_TOBIDASEDAISAKUSEN , + // Camerica + CAMERICA_BF9093 , + CAMERICA_BF9096 , + CAMERICA_BF9097 , + CAMERICA_BF909X , + CAMERICA_ALGNV11 , + CAMERICA_ALGQV11 , + CAMERICA_GOLDENFIVE , + // Caltron + CALTRON_6IN1 , + // C&E + CNE_SHLZ , + CNE_DECATHLON , + CNE_PSB , + // Cony + CONY_STD , + // Dreamtech + DREAMTECH_01 , + // Fujiya + FUJIYA_STD , + // Fukutake + FUKUTAKE_SBX , + // Future Media + FUTUREMEDIA_STD , + // Gouder + GOUDER_37017 , + // Henggedianzi + HENGEDIANZI_STD , + HENGEDIANZI_XJZB , + // HES + HES_STD , + // Hosenkan + HOSENKAN_STD , + // Irem + IREM_G101A_0 , + IREM_G101A_1 , + IREM_G101B_0 , + IREM_G101B_1 , + IREM_H3001 , + IREM_LROG017 , + IREM_HOLYDIVER , + IREM_KAIKETSU , + // Jaleco + JALECO_JF01 , + JALECO_JF02 , + JALECO_JF03 , + JALECO_JF04 , + JALECO_JF05 , + JALECO_JF06 , + JALECO_JF07 , + JALECO_JF08 , + JALECO_JF09 , + JALECO_JF10 , + JALECO_JF11 , + JALECO_JF12 , + JALECO_JF13 , + JALECO_JF14 , + JALECO_JF15 , + JALECO_JF16 , + JALECO_JF17 , + JALECO_JF18 , + JALECO_JF19 , + JALECO_JF20 , + JALECO_JF21 , + JALECO_JF22 , + JALECO_JF23 , + JALECO_JF24 , + JALECO_JF25 , + JALECO_JF26 , + JALECO_JF27 , + JALECO_JF28 , + JALECO_JF29 , + JALECO_JF30 , + JALECO_JF31 , + JALECO_JF32 , + JALECO_JF33 , + JALECO_JF34 , + JALECO_JF35 , + JALECO_JF36 , + JALECO_JF37 , + JALECO_JF38 , + JALECO_JF39 , + JALECO_JF40 , + JALECO_JF41 , + JALECO_SS88006 , + // J.Y.Company + JYCOMPANY_TYPE_A , + JYCOMPANY_TYPE_B , + JYCOMPANY_TYPE_C , + // Kaiser + KAISER_KS202 , + KAISER_KS7022 , + KAISER_KS7032 , + KAISER_KS7058 , + // Kasing + KASING_STD , + // K + KAY_H2288 , + KAY_PANDAPRINCE , + // Konami + KONAMI_VRC1 , + KONAMI_VRC2 , + KONAMI_VRC3 , + KONAMI_VRC4_0 , + KONAMI_VRC4_1 , + KONAMI_VRC4_2 , + KONAMI_VRC6_0 , + KONAMI_VRC6_1 , + KONAMI_VRC7_0 , + KONAMI_VRC7_1 , + KONAMI_VSSYSTEM , + // Magic Series + MAGICSERIES_MAGICDRAGON , + // Namcot + NAMCOT_3433 , + NAMCOT_3443 , + NAMCOT_3446 , + NAMCOT_3425 , + NAMCOT_34XX , + NAMCOT_163_0 , + NAMCOT_163_1 , + NAMCOT_163_S_0 , + NAMCOT_163_S_1 , + // Nitra + NITRA_TDA , + // NTDEC + NTDEC_N715062 , + NTDEC_ASDER_0 , + NTDEC_ASDER_1 , + NTDEC_FIGHTINGHERO , + // Nanjing + NANJING_STD , + // Nihon Bussan + NIHON_UNROM_M5 , + // Open Corp + OPENCORP_DAOU306 , + // RCM + RCM_GS2004 , + RCM_GS2013 , + RCM_GS2015 , + RCM_TETRISFAMILY , + // Rex Soft + REXSOFT_DBZ5 , + REXSOFT_SL1632 , + // Sachen + SACHEN_8259A , + SACHEN_8259B , + SACHEN_8259C , + SACHEN_8259D , + SACHEN_TCA01 , + SACHEN_TCU01 , + SACHEN_TCU02 , + SACHEN_SA0036 , + SACHEN_SA0037 , + SACHEN_SA0161M , + SACHEN_SA72007 , + SACHEN_SA72008 , + SACHEN_74_374A , + SACHEN_74_374B , + SACHEN_STREETHEROES , + // Someri Team + SOMERITEAM_SL12 , + // Subor + SUBOR_TYPE0 , + SUBOR_TYPE1 , + SUBOR_STUDYNGAME , + // Sunsoft + SUNSOFT_1 , + SUNSOFT_2A , + SUNSOFT_2B , + SUNSOFT_3 , + SUNSOFT_4_0 , + SUNSOFT_4_1 , + SUNSOFT_5B_0 , + SUNSOFT_5B_1 , + SUNSOFT_DCS , + SUNSOFT_FME7_0 , + SUNSOFT_FME7_1 , + // Super Game + SUPERGAME_LIONKING , + SUPERGAME_BOOGERMAN , + SUPERGAME_MK3E , + SUPERGAME_POCAHONTAS2 , + // Taito + TAITO_TC0190FMC , + TAITO_TC0190FMC_PAL16R4 , + TAITO_X1005 , + TAITO_X1017 , + // Tengen + TENGEN_800002 , + TENGEN_800004 , + TENGEN_800008 , + TENGEN_800030 , + TENGEN_800032 , + TENGEN_800037 , + TENGEN_800042 , + // TXC + TXC_22211A , + TXC_22211B , + TXC_22211C , + TXC_MXMDHTWO , + TXC_POLICEMAN , + TXC_TW , + // Unlicensed + UNL_A9746 , + UNL_CC21 , + UNL_EDU2000 , + UNL_KINGOFFIGHTERS96 , + UNL_KINGOFFIGHTERS97 , + UNL_MORTALKOMBAT2 , + UNL_N625092 , + UNL_SUPERFIGHTER3 , + UNL_TF1201 , + UNL_WORLDHERO , + UNL_AXROM , + UNL_BXROM , + UNL_CXROM , + UNL_GXROM , + UNL_NROM , + UNL_UXROM , + UNL_TRXROM , + UNL_XZY , + // Waixing + WAIXING_PS2_0 , + WAIXING_PS2_1 , + WAIXING_TYPE_A , + WAIXING_TYPE_B , + WAIXING_TYPE_C , + WAIXING_TYPE_D , + WAIXING_TYPE_E , + WAIXING_TYPE_F , + WAIXING_TYPE_G , + WAIXING_TYPE_H , + WAIXING_TYPE_I , + WAIXING_TYPE_J , + WAIXING_FFV_0 , + WAIXING_FFV_1 , + WAIXING_SH2_0 , + WAIXING_SH2_1 , + WAIXING_SGZLZ , + WAIXING_ZS , + WAIXING_DQVII , + WAIXING_SGZ , + WAIXING_SECURITY_0 , + WAIXING_SECURITY_1 , + // Whirlwind + WHIRLWIND_2706 , + // Unknown + NROM_256_CN , + // ¼ + SUBOR_999, + SMART_GENIUS, + FK23CA, + BMC_FK23CA, + FK23C, + CHINA_ER_SAN2, + UNL_SA_9602B, + City_Fighter_IV, + COOLBOY, + Dragon_Fighter, + UNL_YOKO, + OneBus, + UNL_82112C, + MGC_002, + FF3_CN, + UNL_KS7010, + UNL_158B, + UNL_KS7030, + UNL_TH2131_1, + UNL_831128C, + BMC_LB12IN1, + BOARD_MAX +}; + + +int NES_ROM_get_unifBoardID(char *unif_board); + +#endif diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper000.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper000.cpp new file mode 100644 index 00000000..228cd083 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper000.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper000 // +////////////////////////////////////////////////////////////////////////// + +#include "nnd.cpp" + +void Mapper000::Reset() +{ + switch( PROM_16K_SIZE ) { + case 1: // 16K only + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 0 ); + break; + case 2: // 32K + SetPROM_32K_Bank( 0 ); + break; + } + +//------------------------------ +// main(); +//------------------------------ + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x4e7db5af ) { // Circus Charlie(J) + nes->SetRenderMethod( NES::POST_RENDER ); + } + if( crc == 0x57970078 ) { // F-1 Race(J) + nes->SetRenderMethod( NES::POST_RENDER ); + } + if( crc == 0xaf2bbcbc // Mach Rider(JU) + || crc == 0x3acd4bf1 ) { // Mach Rider(Alt)(JU) + nes->SetRenderMethod( NES::POST_RENDER ); + } + +} +/* +BYTE Mapper000::ReadLow( WORD addr ) +{ + // $4100-$7FFF Lower Memory read +// int data; +// if( addr >= 0x4100 && addr <= 0x5FFF ){ +// data = ppread(addr); +// main(); +// return data; +// } + return Mapper::ReadLow( addr ); +} + +void Mapper000::WriteLow( WORD addr, BYTE data ) +{ + // $4100-$7FFF Lower Memory write +// if( addr >= 0x4100 && addr <= 0x5FFF ){ +// ppwrite(addr, data); +// main(); +// } +} +*/ +void Mapper000::Write( WORD addr, BYTE data ) +{ + // $8000-$FFFF Memory write +// ppwrite(addr, data); +// main(); + + if(nes->rom->GetPROM_CRC()==0x15612dc8){ // Ի공[ά] + SetVROM_4K_Bank( 0, addr&1 ); + SetVROM_4K_Bank( 4, addr&1 ); + if(addr&1) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + + if(nes->rom->GetPROM_CRC()==0x366C20D7){ + SetCRAM_8K_Bank( data ); + if(data&1) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper000.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper000.h new file mode 100644 index 00000000..1ac0abc7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper000.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper000 // +////////////////////////////////////////////////////////////////////////// +class Mapper000 : public Mapper +{ +public: + Mapper000( NES* parent ) : Mapper(parent) {} + + void Reset(); +// BYTE ReadLow ( WORD addr ); +// void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper001.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper001.cpp new file mode 100644 index 00000000..0c41c0f9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper001.cpp @@ -0,0 +1,297 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper001 Nintendo MMC1 // +////////////////////////////////////////////////////////////////////////// +void Mapper001::Reset() +{ + reg[0] = 0x0C; // D3=1,D2=1 + reg[1] = reg[2] = reg[3] = 0; + shift = regbuf = 0; + + patch = 0; + wram_patch = 0; + + if( PROM_16K_SIZE < 32 ) { + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } else { + // For 512K/1M byte Cartridge + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 16-1 ); + + patch = 1; + } + + if( VROM_8K_SIZE ) { +// SetVROM_8K_Bank( 0 ); + } + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0xb8e16bd0 ) { // Snow Bros.(J) + patch = 2; + } +// if( crc == 0x9b565541 ) { // Triathron, The(J) +// nes->SetFrameIRQmode( FALSE ); +// } + if( crc == 0xc96c6f04 ) { // Venus Senki(J) + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } +// if( crc == 0x5e3f7004 ) { // Softball Tengoku(J) +// } + + if( crc == 0x4d2edf70 ) { // Night Rider(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xcd2a73f0 ) { // Pirates!(U) + nes->SetRenderMethod( NES::TILE_RENDER ); + patch = 2; + } + +// if( crc == 0x09efe54b ) { // Majaventure - Mahjong Senki(J) +// nes->SetFrameIRQmode( FALSE ); +// } + + if( crc == 0x11469ce3 ) { // Viva! Las Vegas(J) + } + if( crc == 0xd878ebf5 ) { // Ninja Ryukenden(J) + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } + +// if( crc == 0x7bd7b849 ) { // Nekketsu Koukou - Dodgeball Bu(J) +// } + + if( crc == 0x466efdc2 ) { // Final Fantasy(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + nes->ppu->SetExtMonoMode( TRUE ); + } + if( crc == 0xc9556b36 ) { // Final Fantasy I&II(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + nes->ppu->SetExtMonoMode( TRUE ); + nes->SetSAVERAM_SIZE( 16*1024 ); + wram_patch = 2; + } + + if( crc == 0x717e1169 ) { // Cosmic Wars(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + + if( crc == 0xb8747abf // Best Play - Pro Yakyuu Special(J) + || crc == 0x29449ba9 // Nobunaga no Yabou - Zenkoku Ban(J) + || crc == 0x2b11e0b0 // Nobunaga no Yabou - Zenkoku Ban(J)(alt) + || crc == 0x4642dda6 // Nobunaga's Ambition(U) + || crc == 0xfb69743a // Aoki Ookami to Shiroki Mejika - Genghis Khan(J) + || crc == 0x2225c20f // Genghis Khan(U) + || crc == 0xabbf7217 // Sangokushi(J) + ) { + + nes->SetSAVERAM_SIZE( 16*1024 ); + wram_patch = 1; + wram_bank = 0; + wram_count = 0; + } +} + +void Mapper001::Write( WORD addr, BYTE data ) +{ + + if( wram_patch == 1 && addr == 0xBFFF ) { + DEBUGOUT( "MMC1 %04X=%02X\n", addr&0xFFFF,data&0xFF ); + wram_count++; + wram_bank += data&0x01; + if( wram_count == 5 ) { + if( wram_bank ) { + SetPROM_Bank( 3, &WRAM[0x2000], BANKTYPE_RAM ); + } else { + SetPROM_Bank( 3, &WRAM[0x0000], BANKTYPE_RAM ); + } + wram_bank = wram_count = 0; + } + } + + if( patch != 1 ) { + if((addr & 0x6000) != (last_addr & 0x6000)) { + shift = regbuf = 0; + } + last_addr = addr; + } + + if( data & 0x80 ) { + shift = regbuf = 0; +// reg[0] = 0x0C; // D3=1,D2=1 + reg[0] |= 0x0C; // D3=1,D2=1 c̓ZbgȂ + return; + } + + if( data&0x01 ) regbuf |= 1<>13; + reg[addr] = regbuf; + +// DEBUGOUT( "MMC1 %d=%02X\n", addr&0xFFFF,regbuf&0xFF ); + + regbuf = 0; + shift = 0; + + if( patch != 1 ) { + // For Normal Cartridge + switch( addr ) { + case 0: + if( reg[0] & 0x02 ) { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + break; + case 1: + // Register #1 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank lower($0000-$0FFF) + SetVROM_4K_Bank( 0, reg[1] ); + // CHR 4K bank higher($1000-$1FFF) + SetVROM_4K_Bank( 4, reg[2] ); + } else { + // CHR 8K bank($0000-$1FFF) + SetVROM_8K_Bank( reg[1]>>1 ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 0, reg[1] ); + } + } + break; + case 2: + // Register #2 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank lower($0000-$0FFF) + SetVROM_4K_Bank( 0, reg[1] ); + // CHR 4K bank higher($1000-$1FFF) + SetVROM_4K_Bank( 4, reg[2] ); + } else { + // CHR 8K bank($0000-$1FFF) + SetVROM_8K_Bank( reg[1]>>1 ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 4, reg[2] ); + } + } + break; + case 3: + if( !(reg[0] & 0x08) ) { + // PRG 32K bank ($8000-$FFFF) + SetPROM_32K_Bank( reg[3]>>1 ); + } else { + if( reg[0] & 0x04 ) { + // PRG 16K bank ($8000-$BFFF) + SetPROM_16K_Bank( 4, reg[3] ); + SetPROM_16K_Bank( 6, PROM_16K_SIZE-1 ); + } else { + // PRG 16K bank ($C000-$FFFF) + SetPROM_16K_Bank( 6, reg[3] ); + SetPROM_16K_Bank( 4, 0 ); + } + } + break; + } + } else { + // For 512K/1M byte Cartridge + INT PROM_BASE = 0; + if( PROM_16K_SIZE >= 32 ) { + PROM_BASE = reg[1] & 0x10; + } + + // For FinalFantasy I&II + if( wram_patch == 2 ) { + if( !(reg[1] & 0x18) ) { + SetPROM_Bank( 3, &WRAM[0x0000], BANKTYPE_RAM ); + } else { + SetPROM_Bank( 3, &WRAM[0x2000], BANKTYPE_RAM ); + } + } + + // Register #0 + if( addr == 0 ) { + if( reg[0] & 0x02 ) { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + } + // Register #1 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank lower($0000-$0FFF) + SetVROM_4K_Bank( 0, reg[1] ); + } else { + // CHR 8K bank($0000-$1FFF) + SetVROM_8K_Bank( reg[1]>>1 ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 0, reg[1] ); + } + } + // Register #2 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank higher($1000-$1FFF) + SetVROM_4K_Bank( 4, reg[2] ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 4, reg[2] ); + } + } + // Register #3 + if( !(reg[0] & 0x08) ) { + // PRG 32K bank ($8000-$FFFF) + SetPROM_32K_Bank( (reg[3]&(0xF+PROM_BASE))>>1 ); + } else { + if( reg[0] & 0x04 ) { + // PRG 16K bank ($8000-$BFFF) + SetPROM_16K_Bank( 4, PROM_BASE+(reg[3]&0x0F) ); + if( PROM_16K_SIZE >= 32 ) SetPROM_16K_Bank( 6, PROM_BASE+16-1 ); + } else { + // PRG 16K bank ($C000-$FFFF) + SetPROM_16K_Bank( 6, PROM_BASE+(reg[3]&0x0F) ); + if( PROM_16K_SIZE >= 32 ) SetPROM_16K_Bank( 4, PROM_BASE ); + } + } + } +} + +void Mapper001::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = reg[3]; + p[4] = shift; + p[5] = regbuf; + + p[6] = wram_bank; + p[7] = wram_count; +} + +void Mapper001::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + reg[3] = p[3]; + shift = p[4]; + regbuf = p[5]; + + wram_bank = p[6]; + wram_count = p[7]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper001.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper001.h new file mode 100644 index 00000000..d0e068f0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper001.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper001 Nintendo MMC1 // +////////////////////////////////////////////////////////////////////////// +class Mapper001 : public Mapper +{ +public: + Mapper001( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + WORD last_addr; + + BYTE patch; + BYTE wram_patch; + BYTE wram_bank; + BYTE wram_count; + + BYTE reg[4]; + BYTE shift, regbuf; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper002.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper002.cpp new file mode 100644 index 00000000..2681de16 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper002.cpp @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper002 UNROM // +////////////////////////////////////////////////////////////////////////// +void Mapper002::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); +// if( crc == 0x322c9b09 ) { // Metal Gear (Alt)(J) +//// nes->SetFrameIRQmode( FALSE ); +// } +// if( crc == 0xe7a3867b ) { // Dragon Quest 2(Alt)(J) +// nes->SetFrameIRQmode( FALSE ); +// } +//// if( crc == 0x9622fbd9 ) { // Ballblazer(J) +//// patch = 0; +//// } + if( crc == 0x8c3d54e8 // Ikari(J) + || crc == 0x655efeed // Ikari Warriors(U) + || crc == 0x538218b2 ) { // Ikari Warriors(E) + patch = 1; + } +} + +void Mapper002::WriteLow( WORD addr, BYTE data ) +{ + if( !nes->rom->IsSAVERAM() ) { + if( addr >= 0x5000 && patch ) + SetPROM_16K_Bank( 4, data ); + } else { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper002::Write( WORD addr, BYTE data ) +{ + SetPROM_16K_Bank( 4, data ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper002.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper002.h new file mode 100644 index 00000000..60114aec --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper002.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper002 UNROM // +////////////////////////////////////////////////////////////////////////// +class Mapper002 : public Mapper +{ +public: + Mapper002( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: + BYTE patch; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper003.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper003.cpp new file mode 100644 index 00000000..5990c87c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper003.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper003 CNROM // +////////////////////////////////////////////////////////////////////////// +void Mapper003::Reset() +{ + switch( PROM_16K_SIZE ) { + case 1: // 16K only + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 0 ); + break; + case 2: // 32K + SetPROM_32K_Bank( 0 ); + break; + } +// nes->SetRenderMethod( NES::TILE_RENDER ); + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x2b72fe7e ) { // Ganso Saiyuuki - Super Monkey Dai Bouken(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + nes->ppu->SetExtNameTableMode( TRUE ); + } + +// if( crc == 0xE44D95B5 ) { // Ђ݂‚ +// } +} + +#if 0 +void Mapper003::WriteLow( WORD addr, BYTE data ) +{ + if( patch ) { + Mapper::WriteLow( addr, data ); + } else { + if( nes->rom->IsSAVERAM() ) { + Mapper::WriteLow( addr, data ); + } else { + if( addr >= 0x4800 ) { + SetVROM_8K_Bank( data & 0x03 ); + } + } + } +} +#endif + +void Mapper003::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MAP3 WR $%04X=$%02X L=%d\n", addr, data, nes->GetScanline() ); + SetVROM_8K_Bank( data ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper003.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper003.h new file mode 100644 index 00000000..7da337fc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper003.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper003 CNROM // +////////////////////////////////////////////////////////////////////////// +class Mapper003 : public Mapper +{ +public: + Mapper003( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper004.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper004.cpp new file mode 100644 index 00000000..8c8e0196 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper004.cpp @@ -0,0 +1,567 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper004 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +#define MMC3_IRQ_KLAX 1 +#define MMC3_IRQ_SHOUGIMEIKAN 2 +#define MMC3_IRQ_DAI2JISUPER 3 +#define MMC3_IRQ_DBZ2 4 +#define MMC3_IRQ_ROCKMAN3 5 + +void Mapper004::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0xFF; + irq_request = 0; + irq_preset = 0; + irq_preset_vbl = 0; + + rom_type = 0; + security = 0; + + KT_bank = 0; //for KT CN games + + temp1 = 0xE001; + + // IRQ^Cvݒ + nes->SetIrqType( NES::IRQ_CLOCK ); + irq_type = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x488AB51A + || crc == 0xf7b93e43) { + temp1 = 0xE002; + } + if( crc == 0x8bc9ec42){ // "Contra Fighter (Unl) [U]" + rom_type = 1; + } + if( crc == 0xA9B36A7D // Feng Yun (C) + || crc == 0x370808c3) { //WXN- + rom_type = 2; + } + if( crc == 0x5c707ac4 ) { // Mother(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xcb106f49 ) { // F-1 Sensation(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x1170392a ) { // Karakuri Kengou Den - Musashi Road - Karakuri Nin Hashiru!(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x14a01c70 ) { // Gun-Dec(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xeffeea40 ) { // For Klax(J) + irq_type = MMC3_IRQ_KLAX; + nes->SetIrqType( NES::IRQ_HSYNC ); + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xc17ae2dc ) { // God Slayer - Haruka Tenkuu no Sonata(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x126ea4a0 ) { // Summer Carnival '92 - Recca(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x1f2f4861 ) { // J League Fighting Soccer - The King of Ace Strikers(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x5a6860f1 ) { // Shougi Meikan '92(J) + irq_type = MMC3_IRQ_SHOUGIMEIKAN; + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0xae280e20 ) { // Shougi Meikan '93(J) + irq_type = MMC3_IRQ_SHOUGIMEIKAN; + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0xe19a2473 ) { // Sugoro Quest - Dice no Senshi Tachi(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x702d9b33 ) { // Star Wars - The Empire Strikes Back(Victor)(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0xa9a0d729 ) { // Dai Kaijuu - Deburas(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xc5fea9f2 ) { // Dai 2 Ji - Super Robot Taisen(J) + irq_type = MMC3_IRQ_DAI2JISUPER; + } + if( crc == 0xd852c2f7 ) { // Time Zone(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xecfd3c69 ) { // Taito Chase H.Q.(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x7a748058 ) { // Tom & Jerry (and Tuffy)(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0xaafe699c ) { // Ninja Ryukenden 3 - Yomi no Hakobune(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x6cc62c06 ) { // Hoshi no Kirby - Yume no Izumi no Monogatari(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x877dba77 ) { // My Life My Love - Boku no Yume - Watashi no Negai(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x6f96ed15 ) { // Max Warrior - Wakusei Kaigenrei(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x8685f366 ) { // Matendouji(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x8635fed1 ) { // Mickey Mouse 3 - Yume Fuusen(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x26ff3ea2 ) { // Yume Penguin Monogatari(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x7671bc51 ) { // Red Ariimaa 2(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0xade11141 ) { // Wanpaku Kokkun no Gourmet World(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0x7c7ab58e ) { // Walkuere no Bouken - Toki no Kagi Densetsu(J) + nes->SetRenderMethod( NES::POST_RENDER ); + } + if( crc == 0x26ff3ea2 ) { // Yume Penguin Monogatari(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x126ea4a0 ) { // Summer Carnival '92 Recca(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + + if( crc == 0x1d2e5018 // Rockman 3(J) + || crc == 0x6b999aaf ) { // Megaman 3(U) + irq_type = MMC3_IRQ_ROCKMAN3; + } + + if( crc == 0xd88d48d7 ) { // Kick Master(U) + irq_type = MMC3_IRQ_ROCKMAN3; + } + + if( crc == 0xe763891b ) { // DBZ2 + irq_type = MMC3_IRQ_DBZ2; + } + + // VS-Unisystem + vs_patch = 0; + vs_index = 0; + + if( crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x98cfe016 ) { // VS TKO Boxing (Alt) + vs_patch = 1; + } + if( crc == 0x135adf7c ) { // VS Atari RBI Baseball + vs_patch = 2; + } + if( crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious (b1) + || crc == 0x66bb838f ) { // VS Super Xevious (b2) + vs_patch = 3; + } +} +//static uint8 lut[8] = { 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0F, 0x00 }; +BYTE Mapper004::ReadLow( WORD addr ) +{ + if( !vs_patch ) { +// if((addr>=5000)&&(addr<=5007)) return lut[addr&7]; + if(rom_type == 1){ + if( addr >= 0x4020 && addr <= 0x7FFF ) { + return security; + } + } else if( addr >= 0x5000 && addr <= 0x5FFF ) { + return XRAM[addr-0x4000]; + } + } else if( vs_patch == 1 ) { + // VS TKO Boxing Security + if( addr == 0x5E00 ) { + vs_index = 0; + return 0x00; + } else if( addr == 0x5E01 ) { + BYTE VS_TKO_Security[32] = { + 0xff, 0xbf, 0xb7, 0x97, 0x97, 0x17, 0x57, 0x4f, + 0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90, 0x94, 0x14, + 0x56, 0x4e, 0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90, + 0xd4, 0x5c, 0x3e, 0x26, 0x87, 0x83, 0x13, 0x00 }; + return VS_TKO_Security[(vs_index++) & 0x1F]; + } + } else if( vs_patch == 2 ) { + // VS Atari RBI Baseball Security + if( addr == 0x5E00 ) { + vs_index = 0; + return 0x00; + } else if( addr == 0x5E01 ) { + if( vs_index++ == 9 ) + return 0x6F; + else + return 0xB4; + } + } else if( vs_patch == 3 ) { + // VS Super Xevious + switch( addr ) { + case 0x54FF: + return 0x05; + case 0x5678: + if( vs_index ) + return 0x00; + else + return 0x01; + break; + case 0x578f: + if( vs_index ) + return 0xD1; + else + return 0x89; + break; + case 0x5567: + if( vs_index ) { + vs_index = 0; + return 0x3E; + } else { + vs_index = 1; + return 0x37; + } + break; + default: + break; + } + } + + return Mapper::ReadLow( addr ); +} + +void Mapper004::WriteLow( WORD addr, BYTE data ) +{ + + DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + if(addr==0x5000) KT_bank = data * 0x10; //for KT CN games + + if(rom_type == 1){ + if( addr >= 0x4020 && addr <= 0x7FFF ) { + security = data & 3; + if (security == 1){ + security = 2; + } + } + } else if( addr >= 0x5000 && addr <= 0x5FFF ) { + XRAM[addr-0x4000] = data; + } else { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper004::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + switch( addr & temp1 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + case 0x8002: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data + KT_bank; + SetBank_CPU(); + break; + case 0x07: + prg1 = data + KT_bank; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + if( irq_type == MMC3_IRQ_KLAX || irq_type == MMC3_IRQ_ROCKMAN3 ) { + irq_counter = data; + } else { + irq_latch = data; + } + if( irq_type == MMC3_IRQ_DBZ2 ) { + irq_latch = 0x07; + } + break; + case 0xC001: + reg[5] = data; + if( irq_type == MMC3_IRQ_KLAX || irq_type == MMC3_IRQ_ROCKMAN3 ) { + irq_latch = data; + } else { + if( (nes->GetScanline() < 240) || (irq_type == MMC3_IRQ_SHOUGIMEIKAN) ) { + irq_counter |= 0x80; + irq_preset = 0xFF; + } else { + irq_counter |= 0x80; + irq_preset_vbl = 0xFF; + irq_preset = 0; + } + } + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper004::Clock( INT cycles ) +{ +// if( irq_request && (nes->GetIrqType() == NES::IRQ_CLOCK) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper004::HSync( INT scanline ) +{ + if( irq_type == MMC3_IRQ_KLAX ) { + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( irq_counter == 0 ) { + irq_counter = irq_latch; + irq_request = 0xFF; + } + if( irq_counter > 0 ) { + irq_counter--; + } + } + } + if( irq_request ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } else if( irq_type == MMC3_IRQ_ROCKMAN3 ) { + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_request = 0xFF; + irq_counter = irq_latch; + } + } + } + if( irq_request ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } else { + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( irq_preset_vbl ) { + irq_counter = irq_latch; + irq_preset_vbl = 0; + } + if( irq_preset ) { + irq_counter = irq_latch; + irq_preset = 0; + if( irq_type == MMC3_IRQ_DAI2JISUPER && scanline == 0 ) { + irq_counter--; + } + } else if( irq_counter > 0 ) { + irq_counter--; + } + + if( irq_counter == 0 ) { + if( irq_enable ) { + irq_request = 0xFF; + + nes->cpu->SetIRQ( IRQ_MAPPER ); +#if 0 +{ +LPBYTE lpScn = nes->ppu->GetScreenPtr(); + + lpScn = lpScn+(256+16)*nes->GetScanline(); + + for( INT i = 0; i < 16; i++ ) { + lpScn[i] = 22; + } +} +#endif + } + irq_preset = 0xFF; + } + } + } +// if( irq_request && (nes->GetIrqType() == NES::IRQ_HSYNC) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper004::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper004::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + if(rom_type == 2){ + SetBank_PPUSUB( 4, chr01+0 ); + SetBank_PPUSUB( 5, chr01+1 ); + SetBank_PPUSUB( 6, chr23+0 ); + SetBank_PPUSUB( 7, chr23+1 ); + SetBank_PPUSUB( 0, chr4 ); + SetBank_PPUSUB( 1, chr5 ); + SetBank_PPUSUB( 2, chr6 ); + SetBank_PPUSUB( 3, chr7 ); + } else { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } + } else { + if(rom_type == 2){ + SetBank_PPUSUB( 0, chr01+0 ); + SetBank_PPUSUB( 1, chr01+1 ); + SetBank_PPUSUB( 2, chr23+0 ); + SetBank_PPUSUB( 3, chr23+1 ); + SetBank_PPUSUB( 4, chr4 ); + SetBank_PPUSUB( 5, chr5 ); + SetBank_PPUSUB( 6, chr6 ); + SetBank_PPUSUB( 7, chr7 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } +} + +void Mapper004::SetBank_PPUSUB( int bank, int page ) +{ + if( page < 8 ) { + SetCRAM_1K_Bank( bank, page ); + } else { + SetVROM_1K_Bank( bank, page ); + } +} + +void Mapper004::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = (BYTE)irq_counter; + p[18] = irq_latch; + p[19] = irq_request; + p[20] = irq_preset; + p[21] = irq_preset_vbl; +} + +void Mapper004::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = (INT)p[17]; + irq_latch = p[18]; + irq_request = p[19]; + irq_preset = p[20]; + irq_preset_vbl = p[21]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper004.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper004.h new file mode 100644 index 00000000..2f2f0b7a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper004.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper004 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper004 : public Mapper +{ +public: + Mapper004( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE rom_type; //for "Contra Fighter (Unl) [U]" + BYTE security; + + BYTE KT_bank; //for KT CN games + + WORD temp1; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + BYTE irq_preset; + BYTE irq_preset_vbl; + + BYTE vs_patch; + BYTE vs_index; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_PPUSUB( int bank, int page ); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper005.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper005.cpp new file mode 100644 index 00000000..d4ae680e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper005.cpp @@ -0,0 +1,672 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper005 Nintendo MMC5 // +////////////////////////////////////////////////////////////////////////// +#define MMC5_IRQ_METAL (1<<0) + +void Mapper005::Reset() +{ +INT i; + + prg_size = 3; + chr_size = 3; + + sram_we_a = 0x00; + sram_we_b = 0x00; + + graphic_mode = 0; + nametable_mode = 0; + + for( i = 0; i < 4; i++ ) { + nametable_type[i] = 0; + } + + fill_chr = fill_pal = 0; + split_control = split_scroll = split_page = 0; + + irq_enable = 0; + irq_status = 0; + irq_scanline = 0; + irq_line = 0; + irq_clear = 0; + + irq_type = 0; + + mult_a = mult_b = 0; + + chr_type = 0; + chr_mode = 0; + for( i = 0; i < 8; i++ ) { + chr_page[0][i] = i; + chr_page[1][i] = 4+(i&0x03); + } + + SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + for( i = 0; i < 8; i++ ) { + BG_MEM_BANK[i] = VROM+0x0400*i; + BG_MEM_PAGE[i] = i; + } + + // SRAMݒ + SetBank_SRAM( 3, 0 ); + + sram_size = 0; + nes->SetSAVERAM_SIZE( 16*1024 ); + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x2b548d75 // Bandit Kings of Ancient China(U) + || crc == 0xf4cd4998 // Dai Koukai Jidai(J) + || crc == 0x8fa95456 // Ishin no Arashi(J) + || crc == 0x98c8e090 // Nobunaga no Yabou - Sengoku Gunyuu Den(J) + || crc == 0x8e9a5e2f // L'Empereur(Alt)(U) + || crc == 0x57e3218b // L'Empereur(U) + || crc == 0x2f50bd38 // L'Empereur(J) + || crc == 0xb56958d1 // Nobunaga's Ambition 2(U) + || crc == 0xe6c28c5f // Suikoden - Tenmei no Chikai(J) + || crc == 0xcd35e2e9 ) { // Uncharted Waters(U) + sram_size = 1; + nes->SetSAVERAM_SIZE( 32*1024 ); + } else + if( crc == 0xf4120e58 // Aoki Ookami to Shiroki Mejika - Genchou Hishi(J) + || crc == 0x286613d8 // Nobunaga no Yabou - Bushou Fuuun Roku(J) + || crc == 0x11eaad26 // Romance of the Three Kingdoms 2(U) + || crc == 0x95ba5733 ) { // Sangokushi 2(J) + sram_size = 2; + nes->SetSAVERAM_SIZE( 64*1024 ); + } + + if( crc == 0x95ca9ec7 ) { // Castlevania 3 - Dracula's Curse(U) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + + if( crc == 0xcd9acf43 ) { // Metal Slader Glory(J) + irq_type = MMC5_IRQ_METAL; + } + + if( crc == 0xe91548d8 ) { // Shin 4 Nin Uchi Mahjong - Yakuman Tengoku(J) + chr_type = 1; + } + + nes->ppu->SetExtLatchMode( TRUE ); + nes->apu->SelectExSound( 8 ); +} + +BYTE Mapper005::ReadLow( WORD addr ) +{ +BYTE data = (BYTE)(addr>>8); + + switch( addr ) { + case 0x5015: + data = nes->apu->ExRead( addr ); + break; + + case 0x5204: + data = irq_status; +// irq_status = 0; + irq_status &= ~0x80; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x5205: + data = mult_a*mult_b; + break; + case 0x5206: + data = (BYTE)(((WORD)mult_a*(WORD)mult_b)>>8); + break; + } + + if( addr >= 0x5C00 && addr <= 0x5FFF ) { + if( graphic_mode >= 2 ) { // ExRAM mode + data = VRAM[0x0800+(addr&0x3FF)]; + } + } else if( addr >= 0x6000 && addr <= 0x7FFF ) { + data = Mapper::ReadLow( addr ); + } + + return data; +} + +void Mapper005::WriteLow( WORD addr, BYTE data ) +{ +INT i; + +#if 0 +if( addr >= 0x5000 && addr <=0x5100 ) { +DEBUGOUT( "$%04X=%02X C:%10d\n", addr, data, nes->cpu->GetTotalCycles() ); +} +#endif + + switch( addr ) { + case 0x5100: + prg_size = data & 0x03; + break; + case 0x5101: + chr_size = data & 0x03; + break; + + case 0x5102: + sram_we_a = data & 0x03; + break; + case 0x5103: + sram_we_b = data & 0x03; + break; + + case 0x5104: + graphic_mode = data & 0x03; + break; + case 0x5105: + nametable_mode = data; + for( i = 0; i < 4; i++ ) { + nametable_type[i] = data&0x03; + SetVRAM_1K_Bank( 8+i, nametable_type[i] ); + data >>= 2; + } + break; + + case 0x5106: + fill_chr = data; + break; + case 0x5107: + fill_pal = data & 0x03; + break; + + case 0x5113: + SetBank_SRAM( 3, data&0x07 ); + break; + + case 0x5114: + case 0x5115: + case 0x5116: + case 0x5117: + SetBank_CPU( addr, data ); + break; + + case 0x5120: + case 0x5121: + case 0x5122: + case 0x5123: + case 0x5124: + case 0x5125: + case 0x5126: + case 0x5127: + chr_mode = 0; + chr_page[0][addr&0x07] = data; + SetBank_PPU(); + break; + + case 0x5128: + case 0x5129: + case 0x512A: + case 0x512B: + chr_mode = 1; + chr_page[1][(addr&0x03)+0] = data; + chr_page[1][(addr&0x03)+4] = data; + SetBank_PPU(); + break; + + case 0x5200: + split_control = data; + break; + case 0x5201: + split_scroll = data; + break; + case 0x5202: + split_page = data&0x3F; + break; + + case 0x5203: + irq_line = data; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x5204: + irq_enable = data; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0x5205: + mult_a = data; + break; + case 0x5206: + mult_b = data; + break; + + default: + if( addr >= 0x5000 && addr <= 0x5015 ) { + nes->apu->ExWrite( addr, data ); + } else if( addr >= 0x5C00 && addr <= 0x5FFF ) { + if( graphic_mode == 2 ) { // ExRAM + VRAM[0x0800+(addr&0x3FF)] = data; + } else if( graphic_mode != 3 ) { // Split,ExGraphic + if( irq_status&0x40 ) { + VRAM[0x0800+(addr&0x3FF)] = data; + } else { + VRAM[0x0800+(addr&0x3FF)] = 0; + } + } + } else if( addr >= 0x6000 && addr <= 0x7FFF ) { + if( sram_we_a == 0x02 && sram_we_b == 0x01 ) { + if( CPU_MEM_TYPE[3] == BANKTYPE_RAM ) { + CPU_MEM_BANK[3][addr&0x1FFF] = data; + } + } + } + break; + } +} + +void Mapper005::Write( WORD addr, BYTE data ) +{ + if( sram_we_a == 0x02 && sram_we_b == 0x01 ) { + if( addr >= 0x8000 && addr < 0xE000 ) { + if( CPU_MEM_TYPE[addr>>13] == BANKTYPE_RAM ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } + } + } +} + +void Mapper005::SetBank_CPU( WORD addr, BYTE data ) +{ + if( data & 0x80 ) { + // PROM Bank + switch( addr & 7 ) { + case 4: + if( prg_size == 3 ) { + SetPROM_8K_Bank( 4, data&0x7F ); + } + break; + case 5: + if( prg_size == 1 || prg_size == 2 ) { + SetPROM_16K_Bank( 4, (data&0x7F)>>1 ); + } else if( prg_size == 3 ) { + SetPROM_8K_Bank( 5, (data&0x7F) ); + } + break; + case 6: + if( prg_size == 2 || prg_size == 3 ) { + SetPROM_8K_Bank( 6, (data&0x7F) ); + } + break; + case 7: + if( prg_size == 0 ) { + SetPROM_32K_Bank( (data&0x7F)>>2 ); + } else if( prg_size == 1 ) { + SetPROM_16K_Bank( 6, (data&0x7F)>>1 ); + } else if( prg_size == 2 || prg_size == 3 ) { + SetPROM_8K_Bank( 7, (data&0x7F) ); + } + break; + } + } else { + // WRAM Bank + switch( addr & 7 ) { + case 4: + if( prg_size == 3 ) { + SetBank_SRAM( 4, data&0x07 ); + } + break; + case 5: + if( prg_size == 1 || prg_size == 2 ) { + SetBank_SRAM( 4, (data&0x06)+0 ); + SetBank_SRAM( 5, (data&0x06)+1 ); + } else if( prg_size == 3 ) { + SetBank_SRAM( 5, data&0x07 ); + } + break; + case 6: + if( prg_size == 2 || prg_size == 3 ) { + SetBank_SRAM( 6, data&0x07 ); + } + break; + } + } +} + +void Mapper005::SetBank_SRAM( BYTE page, BYTE data ) +{ + if( sram_size == 0 ) data = (data > 3) ? 8 : 0; + if( sram_size == 1 ) data = (data > 3) ? 1 : 0; + if( sram_size == 2 ) data = (data > 3) ? 8 : data; + if( sram_size == 3 ) data = (data > 3) ? 4 : data; + + if( data != 8 ) { + SetPROM_Bank( page, &WRAM[0x2000*data], BANKTYPE_RAM ); + CPU_MEM_PAGE[page] = data; + } else { + CPU_MEM_TYPE[page] = BANKTYPE_ROM; + } +} + +void Mapper005::SetBank_PPU() +{ +INT i; + + if( chr_mode == 0 ) { + // PPU SP Bank + switch( chr_size ) { + case 0: + SetVROM_8K_Bank( chr_page[0][7] ); + break; + case 1: + SetVROM_4K_Bank( 0, chr_page[0][3] ); + SetVROM_4K_Bank( 4, chr_page[0][7] ); + break; + case 2: + SetVROM_2K_Bank( 0, chr_page[0][1] ); + SetVROM_2K_Bank( 2, chr_page[0][3] ); + SetVROM_2K_Bank( 4, chr_page[0][5] ); + SetVROM_2K_Bank( 6, chr_page[0][7] ); + break; + case 3: + SetVROM_8K_Bank( chr_page[0][0], + chr_page[0][1], + chr_page[0][2], + chr_page[0][3], + chr_page[0][4], + chr_page[0][5], + chr_page[0][6], + chr_page[0][7] ); + break; + } + } else if( chr_mode == 1 ) { + // PPU BG Bank + switch( chr_size ) { + case 0: + for( i = 0; i < 8; i++ ) { + BG_MEM_BANK[i] = VROM+0x2000*(chr_page[1][7]%VROM_8K_SIZE)+0x0400*i; + BG_MEM_PAGE[i] = (chr_page[1][7]%VROM_8K_SIZE)*8+i; + } + break; + case 1: + for( i = 0; i < 4; i++ ) { + BG_MEM_BANK[i+0] = VROM+0x1000*(chr_page[1][3]%VROM_4K_SIZE)+0x0400*i; + BG_MEM_BANK[i+4] = VROM+0x1000*(chr_page[1][7]%VROM_4K_SIZE)+0x0400*i; + BG_MEM_PAGE[i+0] = (chr_page[1][3]%VROM_4K_SIZE)*4+i; + BG_MEM_PAGE[i+4] = (chr_page[1][7]%VROM_4K_SIZE)*4+i; + } + break; + case 2: + for( i = 0; i < 2; i++ ) { + BG_MEM_BANK[i+0] = VROM+0x0800*(chr_page[1][1]%VROM_2K_SIZE)+0x0400*i; + BG_MEM_BANK[i+2] = VROM+0x0800*(chr_page[1][3]%VROM_2K_SIZE)+0x0400*i; + BG_MEM_BANK[i+4] = VROM+0x0800*(chr_page[1][5]%VROM_2K_SIZE)+0x0400*i; + BG_MEM_BANK[i+6] = VROM+0x0800*(chr_page[1][7]%VROM_2K_SIZE)+0x0400*i; + BG_MEM_PAGE[i+0] = (chr_page[1][1]%VROM_2K_SIZE)*2+i; + BG_MEM_PAGE[i+2] = (chr_page[1][3]%VROM_2K_SIZE)*2+i; + BG_MEM_PAGE[i+4] = (chr_page[1][5]%VROM_2K_SIZE)*2+i; + BG_MEM_PAGE[i+6] = (chr_page[1][7]%VROM_2K_SIZE)*2+i; + } + break; + case 3: + for( i = 0; i < 8; i++ ) { + BG_MEM_BANK[i] = VROM+0x0400*(chr_page[1][i]%VROM_1K_SIZE); + BG_MEM_PAGE[i] = (chr_page[1][i]%VROM_1K_SIZE)+i; + } + break; + } + } +} + +void Mapper005::HSync( INT scanline ) +{ + if( irq_type & MMC5_IRQ_METAL ) { + if( irq_scanline == irq_line ) { + irq_status |= 0x80; + } + } + +// if( nes->ppu->IsDispON() && scanline < 239 ) { + if( nes->ppu->IsDispON() && scanline < 240 ) { + irq_scanline++; + irq_status |= 0x40; + irq_clear = 0; + } else if( irq_type & MMC5_IRQ_METAL ) { + irq_scanline = 0; + irq_status &= ~0x80; + irq_status &= ~0x40; + } + + if( !(irq_type & MMC5_IRQ_METAL) ) { + if( irq_scanline == irq_line ) { + irq_status |= 0x80; + } + + if( ++irq_clear > 2 ) { + irq_scanline = 0; + irq_status &= ~0x80; + irq_status &= ~0x40; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + } + + if( (irq_enable & 0x80) && (irq_status & 0x80) && (irq_status & 0x40) ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); +/// nes->cpu->IRQ_NotPending(); +#if 0 +{ +LPBYTE lpScn = nes->ppu->GetScreenPtr(); + + lpScn = lpScn+(256+16)*scanline; + + for( INT i = 0; i < 256+16; i++ ) { + lpScn[i] = 22; + } +} +#endif + } + + // For Split mode! + if( scanline == 0 ) { + split_yofs = split_scroll&0x07; + split_addr = ((split_scroll&0xF8)<<2); + } else if( nes->ppu->IsDispON() ) { + if( split_yofs == 7 ) { + split_yofs = 0; + if( (split_addr & 0x03E0) == 0x03A0 ) { + split_addr &= 0x001F; + } else { + if( (split_addr & 0x03E0) == 0x03E0 ) { + split_addr &= 0x001F; + } else { + split_addr += 0x0020; + } + } + } else { + split_yofs++; + } + } +} + +void Mapper005::PPU_ExtLatchX( INT x ) +{ + split_x = x; +} + +void Mapper005::PPU_ExtLatch( WORD addr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ +WORD ntbladr, attradr, tileadr, tileofs; +WORD tile_yofs; +DWORD tilebank; +BOOL bSplit; + + tile_yofs = nes->ppu->GetTILEY(); + + bSplit = FALSE; + if( split_control & 0x80 ) { + if( !(split_control&0x40) ) { + // Left side + if( (split_control&0x1F) > split_x ) { + bSplit = TRUE; + } + } else { + // Right side + if( (split_control&0x1F) <= split_x ) { + bSplit = TRUE; + } + } + } + + if( !bSplit ) { + if( nametable_type[(addr&0x0C00)>>10] == 3 ) { + // Fill mode + if( graphic_mode == 1 ) { + // ExGraphic mode + ntbladr = 0x2000+(addr&0x0FFF); + // Get Nametable + tileadr = fill_chr*0x10+tile_yofs; + // Get TileBank + tilebank = 0x1000*((VRAM[0x0800+(ntbladr&0x03FF)]&0x3F)%VROM_4K_SIZE); + // Attribute + attr = (fill_pal<<2)&0x0C; + // Get Pattern + chr_l = VROM[tilebank+tileadr ]; + chr_h = VROM[tilebank+tileadr+8]; + } else { + // Normal + tileofs = (PPUREG[0]&PPU_BGTBL_BIT)?0x1000:0x0000; + tileadr = tileofs+fill_chr*0x10+tile_yofs; + attr = (fill_pal<<2)&0x0C; + // Get Pattern + if( chr_type ) { + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } else { + chr_l = BG_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = BG_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } + } + } else if( graphic_mode == 1 ) { + // ExGraphic mode + ntbladr = 0x2000+(addr&0x0FFF); + // Get Nametable + tileadr = (WORD)PPU_MEM_BANK[ntbladr>>10][ntbladr&0x03FF]*0x10+tile_yofs; + // Get TileBank + tilebank = 0x1000*((VRAM[0x0800+(ntbladr&0x03FF)]&0x3F)%VROM_4K_SIZE); + // Get Attribute + attr = (VRAM[0x0800+(ntbladr&0x03FF)]&0xC0)>>4; + // Get Pattern + chr_l = VROM[tilebank+tileadr ]; + chr_h = VROM[tilebank+tileadr+8]; + } else { + // Normal or ExVRAM + tileofs = (PPUREG[0]&PPU_BGTBL_BIT)?0x1000:0x0000; + ntbladr = 0x2000+(addr&0x0FFF); + attradr = 0x23C0+(addr&0x0C00)+((addr&0x0380)>>4)+((addr&0x001C)>>2); + // Get Nametable + tileadr = tileofs+PPU_MEM_BANK[ntbladr>>10][ntbladr&0x03FF]*0x10+tile_yofs; + // Get Attribute + attr = PPU_MEM_BANK[attradr>>10][attradr&0x03FF]; + if( ntbladr & 0x0002 ) attr >>= 2; + if( ntbladr & 0x0040 ) attr >>= 4; + attr = (attr&0x03)<<2; + // Get Pattern + if( chr_type ) { + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } else { + chr_l = BG_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = BG_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } + } + } else { + ntbladr = ((split_addr&0x03E0)|(split_x&0x1F))&0x03FF; + // Get Split TileBank + tilebank = 0x1000*((INT)split_page%VROM_4K_SIZE); + tileadr = (WORD)VRAM[0x0800+ntbladr]*0x10+split_yofs; + // Get Attribute + attradr = 0x03C0+((ntbladr&0x0380)>>4)+((ntbladr&0x001C)>>2); + attr = VRAM[0x0800+attradr]; + if( ntbladr & 0x0002 ) attr >>= 2; + if( ntbladr & 0x0040 ) attr >>= 4; + attr = (attr&0x03)<<2; + // Get Pattern + chr_l = VROM[tilebank+tileadr ]; + chr_h = VROM[tilebank+tileadr+8]; + } +} + +void Mapper005::SaveState( LPBYTE p ) +{ + p[ 0] = prg_size; + p[ 1] = chr_size; + p[ 2] = sram_we_a; + p[ 3] = sram_we_b; + p[ 4] = graphic_mode; + p[ 5] = nametable_mode; + p[ 6] = nametable_type[0]; + p[ 7] = nametable_type[1]; + p[ 8] = nametable_type[2]; + p[ 9] = nametable_type[3]; + p[10] = sram_page; + p[11] = fill_chr; + p[12] = fill_pal; + p[13] = split_control; + p[14] = split_scroll; + p[15] = split_page; + p[16] = chr_mode; + p[17] = irq_status; + p[18] = irq_enable; + p[19] = irq_line; + p[20] = irq_scanline; + p[21] = irq_clear; + p[22] = mult_a; + p[23] = mult_b; + + INT i, j; + for( j = 0; j < 2; j++ ) { + for( i = 0; i < 8; i++ ) { + p[24+j*8+i] = chr_page[j][i]; + } + } + for( i = 0; i < 8; i++ ) { + p[40+i] = BG_MEM_PAGE[i]; + } +} + +void Mapper005::LoadState( LPBYTE p ) +{ + prg_size = p[ 0]; + chr_size = p[ 1]; + sram_we_a = p[ 2]; + sram_we_b = p[ 3]; + graphic_mode = p[ 4]; + nametable_mode = p[ 5]; + nametable_type[0] = p[ 6]; + nametable_type[1] = p[ 7]; + nametable_type[2] = p[ 8]; + nametable_type[3] = p[ 9]; + sram_page = p[10]; + fill_chr = p[11]; + fill_pal = p[12]; + split_control = p[13]; + split_scroll = p[14]; + split_page = p[15]; + chr_mode = p[16]; + irq_status = p[17]; + irq_enable = p[18]; + irq_line = p[19]; + irq_scanline = p[20]; + irq_clear = p[21]; + mult_a = p[22]; + mult_b = p[23]; + + INT i, j; + + for( j = 0; j < 2; j++ ) { + for( i = 0; i < 8; i++ ) { + chr_page[j][i] = p[24+j*8+i]; + } + } + // BGoN̍Đݒ菈 + for( i = 0; i < 8; i++ ) { + BG_MEM_PAGE[i] = p[40+i]%VROM_1K_SIZE; + } + for( i = 0; i < 8; i++ ) { + BG_MEM_BANK[i] = VROM+0x0400*BG_MEM_PAGE[i]; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper005.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper005.h new file mode 100644 index 00000000..5298ce3d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper005.h @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper005 Nintendo MMC5 // +////////////////////////////////////////////////////////////////////////// +class Mapper005 : public Mapper +{ +public: + Mapper005( NES* parent ) : Mapper(parent) {} + + void Reset(); + + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + void PPU_ExtLatchX( INT x ); + void PPU_ExtLatch( WORD addr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE sram_size; + + BYTE prg_size; // $5100 + BYTE chr_size; // $5101 + BYTE sram_we_a, sram_we_b; // $5102-$5103 + BYTE graphic_mode; // $5104 + BYTE nametable_mode; // $5105 + BYTE nametable_type[4]; // $5105 use + + BYTE sram_page; // $5113 + + BYTE fill_chr, fill_pal; // $5106-$5107 + BYTE split_control; // $5200 + BYTE split_scroll; // $5201 + BYTE split_page; // $5202 + + BYTE split_x; + WORD split_addr; + WORD split_yofs; + + BYTE chr_type; + BYTE chr_mode; // $5120-$512B use + BYTE chr_page[2][8]; // $5120-$512B + LPBYTE BG_MEM_BANK[8]; // BGp^[poN + BYTE BG_MEM_PAGE[8]; + + BYTE irq_status; // $5204(R) + BYTE irq_enable; // $5204(W) + BYTE irq_line; // $5203 + BYTE irq_scanline; + BYTE irq_clear; // HSyncŎgp + BYTE irq_type; + + BYTE mult_a, mult_b; // $5205-$5206 + +private: + void SetBank_CPU( WORD addr, BYTE data ); + void SetBank_SRAM( BYTE page, BYTE data ); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper006.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper006.cpp new file mode 100644 index 00000000..0c7d9e0d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper006.cpp @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper006 FFE F4xxx // +////////////////////////////////////////////////////////////////////////// +void Mapper006::Reset() +{ + SetPROM_32K_Bank( 0, 1, 14, 15 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } else { + SetCRAM_8K_Bank( 0 ); + } + + irq_enable = 0; + irq_counter = 0; +} + +void Mapper006::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x42FE: + if( data&0x10 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + case 0x42FF: + if( data&0x10 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0x4501: + irq_enable = 0; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x4502: + irq_counter = (irq_counter&0xFF00)|data; + break; + case 0x4503: + irq_counter = (irq_counter&0x00FF)|((INT)data<<8); + irq_enable = 0xFF; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + default: + Mapper::WriteLow( addr, data ); + break; + } +} + +void Mapper006::Write( WORD addr, BYTE data ) +{ + SetPROM_16K_Bank( 4, (data&0x3C)>>2 ); + SetCRAM_8K_Bank( data&0x03 ); +} + +void Mapper006::HSync( INT scanline ) +{ + if( irq_enable ) { + irq_counter+=133; + if( irq_counter >= 0xFFFF ) { +// nes->cpu->IRQ(); + irq_counter = 0; + + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper006::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_counter; +} + +void Mapper006::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = *(INT*)&p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper006.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper006.h new file mode 100644 index 00000000..28e8b8f0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper006.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper006 FFE F4xxx // +////////////////////////////////////////////////////////////////////////// +class Mapper006 : public Mapper +{ +public: + Mapper006( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + INT irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper007.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper007.cpp new file mode 100644 index 00000000..cc67c16b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper007.cpp @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper007 AOROM/AMROM // +////////////////////////////////////////////////////////////////////////// +void Mapper007::Reset() +{ + patch = 0; + + SetPROM_32K_Bank( 0 ); + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x3c9fe649 ) { // WWF Wrestlemania Challenge(U) + SetVRAM_Mirror( VRAM_VMIRROR ); + patch = 1; + } + if( crc == 0x09874777 ) { // Marble Madness(U) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xfad97471 ) { // Ժ(unif - [CC-21]) + patch = 2; + } +} + +void Mapper007::Write( WORD addr, BYTE data ) +{ + if( patch == 2 ) + { + SetVROM_8K_Bank( addr & 0x1 ); + if( addr & 0x2 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + }else{ + SetPROM_32K_Bank( (data & 0x07) ); + if( !patch ) { + if( data & 0x10 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper007.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper007.h new file mode 100644 index 00000000..5cf45e63 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper007.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper007 AOROM/AMROM // +////////////////////////////////////////////////////////////////////////// +class Mapper007 : public Mapper +{ +public: + Mapper007( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: + BYTE patch; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper008.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper008.cpp new file mode 100644 index 00000000..4abbd64a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper008.cpp @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper008 FFE F3xxx // +////////////////////////////////////////////////////////////////////////// +void Mapper008::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper008::Write( WORD addr, BYTE data ) +{ + SetPROM_16K_Bank( 4, (data&0xF8)>>3 ); + SetVROM_8K_Bank( data&0x07 ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper008.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper008.h new file mode 100644 index 00000000..5f9ec157 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper008.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper008 FFE F3xxx // +////////////////////////////////////////////////////////////////////////// +class Mapper008 : public Mapper +{ +public: + Mapper008( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper009.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper009.cpp new file mode 100644 index 00000000..3250b29a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper009.cpp @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper009 Nintendo MMC2 // +////////////////////////////////////////////////////////////////////////// +void Mapper009::Reset() +{ + SetPROM_32K_Bank( 0, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + reg[0] = 0; reg[1] = 4; + reg[2] = 0; reg[3] = 0; + + latch_a = 0xFE; + latch_b = 0xFE; + SetVROM_4K_Bank( 0, 4 ); + SetVROM_4K_Bank( 4, 0 ); + + nes->ppu->SetChrLatchMode( TRUE ); +} + +void Mapper009::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF000 ) { + case 0xA000: + SetPROM_8K_Bank( 4, data ); + break; + case 0xB000: + reg[0] = data; + if( latch_a == 0xFD ) { + SetVROM_4K_Bank( 0, reg[0] ); + } + break; + case 0xC000: + reg[1] = data; + if( latch_a == 0xFE ) { + SetVROM_4K_Bank( 0, reg[1] ); + } + break; + case 0xD000: + reg[2] = data; + if( latch_b == 0xFD ) { + SetVROM_4K_Bank( 4, reg[2] ); + } + break; + case 0xE000: + reg[3] = data; + if( latch_b == 0xFE ) { + SetVROM_4K_Bank( 4, reg[3] ); + } + break; + case 0xF000: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } +} + +void Mapper009::PPU_ChrLatch( WORD addr ) +{ + if( (addr&0x1FF0) == 0x0FD0 && latch_a != 0xFD ) { + latch_a = 0xFD; + SetVROM_4K_Bank( 0, reg[0] ); + } else if( (addr&0x1FF0) == 0x0FE0 && latch_a != 0xFE ) { + latch_a = 0xFE; + SetVROM_4K_Bank( 0, reg[1] ); + } else if( (addr&0x1FF0) == 0x1FD0 && latch_b != 0xFD ) { + latch_b = 0xFD; + SetVROM_4K_Bank( 4, reg[2] ); + } else if( (addr&0x1FF0) == 0x1FE0 && latch_b != 0xFE ) { + latch_b = 0xFE; + SetVROM_4K_Bank( 4, reg[3] ); + } +} + +void Mapper009::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = reg[3]; + p[4] = latch_a; + p[5] = latch_b; +} + +void Mapper009::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + reg[3] = p[3]; + latch_a = p[4]; + latch_b = p[5]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper009.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper009.h new file mode 100644 index 00000000..3fa13aa6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper009.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper009 Nintendo MMC2 // +////////////////////////////////////////////////////////////////////////// +class Mapper009 : public Mapper +{ +public: + Mapper009( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void PPU_ChrLatch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[4]; + BYTE latch_a, latch_b; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper010.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper010.cpp new file mode 100644 index 00000000..10b94c12 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper010.cpp @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper010 Nintendo MMC4 // +////////////////////////////////////////////////////////////////////////// +void Mapper010::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + reg[0] = 0; reg[1] = 4; + reg[2] = 0; reg[3] = 0; + + latch_a = 0xFE; + latch_b = 0xFE; + SetVROM_4K_Bank( 0, 4 ); + SetVROM_4K_Bank( 4, 0 ); + + nes->ppu->SetChrLatchMode( TRUE ); +} + +void Mapper010::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF000 ) { + case 0xA000: + SetPROM_16K_Bank( 4, data ); + break; + case 0xB000: + reg[0] = data; + if( latch_a == 0xFD ) { + SetVROM_4K_Bank( 0, reg[0] ); + } + break; + case 0xC000: + reg[1] = data; + if( latch_a == 0xFE ) { + SetVROM_4K_Bank( 0, reg[1] ); + } + break; + case 0xD000: + reg[2] = data; + if( latch_b == 0xFD ) { + SetVROM_4K_Bank( 4, reg[2] ); + } + break; + case 0xE000: + reg[3] = data; + if( latch_b == 0xFE ) { + SetVROM_4K_Bank( 4, reg[3] ); + } + break; + case 0xF000: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } +} + +void Mapper010::PPU_ChrLatch( WORD addr ) +{ + if( (addr&0x1FF0) == 0x0FD0 && latch_a != 0xFD ) { + latch_a = 0xFD; + SetVROM_4K_Bank( 0, reg[0] ); + } else if( (addr&0x1FF0) == 0x0FE0 && latch_a != 0xFE ) { + latch_a = 0xFE; + SetVROM_4K_Bank( 0, reg[1] ); + } else if( (addr&0x1FF0) == 0x1FD0 && latch_b != 0xFD ) { + latch_b = 0xFD; + SetVROM_4K_Bank( 4, reg[2] ); + } else if( (addr&0x1FF0) == 0x1FE0 && latch_b != 0xFE ) { + latch_b = 0xFE; + SetVROM_4K_Bank( 4, reg[3] ); + } +} + +void Mapper010::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = reg[3]; + p[4] = latch_a; + p[5] = latch_b; +} + +void Mapper010::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + reg[3] = p[3]; + latch_a = p[4]; + latch_b = p[5]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper010.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper010.h new file mode 100644 index 00000000..0c69a2c2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper010.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper010 Nintendo MMC4 // +////////////////////////////////////////////////////////////////////////// +class Mapper010 : public Mapper +{ +public: + Mapper010( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void PPU_ChrLatch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[4]; + BYTE latch_a, latch_b; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper011.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper011.cpp new file mode 100644 index 00000000..a1598547 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper011.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper011 Color Dreams // +////////////////////////////////////////////////////////////////////////// +void Mapper011::Reset() +{ + SetPROM_32K_Bank( 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); +// SetVROM_8K_Bank( 1 ); + } + SetVRAM_Mirror( VRAM_VMIRROR ); +} + +void Mapper011::Write( WORD addr, BYTE data ) +{ +DEBUGOUT( "WR A:%04X D:%02X\n", addr, data ); + SetPROM_32K_Bank( data ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( data>>4 ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper011.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper011.h new file mode 100644 index 00000000..d2a787e5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper011.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper011 Color Dreams // +////////////////////////////////////////////////////////////////////////// +class Mapper011 : public Mapper +{ +public: + Mapper011( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper012.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper012.cpp new file mode 100644 index 00000000..9113b8ff --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper012.cpp @@ -0,0 +1,248 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper012 DBZ5 // +////////////////////////////////////////////////////////////////////////// +void Mapper012::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + vb0 = 0; + vb1 = 0; + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0xFF; + irq_request = 0; + irq_preset = 0; + irq_preset_vbl = 0; +} + +void Mapper012::WriteLow(WORD addr, BYTE data) +{ + if( addr > 0x4100 && addr < 0x6000 ){ + vb0 = (data&0x01)<<8; + vb1 = (data&0x10)<<4; + SetBank_PPU(); + }else{ + Mapper::WriteLow(addr, data); + } +} + +BYTE Mapper012::ReadLow(WORD addr) +{ + return 0x01; +} + +void Mapper012::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_latch = data; + break; + case 0xC001: + reg[5] = data; + if( nes->GetScanline() < 240 ) { + irq_counter |= 0x80; + irq_preset = 0xFF; + } else { + irq_counter |= 0x80; + irq_preset_vbl = 0xFF; + irq_preset = 0; + } + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } +} + +void Mapper012::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( irq_preset_vbl ) { + irq_counter = irq_latch; + irq_preset_vbl = 0; + } + if( irq_preset ) { + irq_counter = irq_latch; + irq_preset = 0; + } else if( irq_counter > 0 ) { + irq_counter--; + } + + if( irq_counter == 0 ) { + // Some game set irq_latch to zero to disable irq. So check it here. + if( irq_enable && irq_latch ) { + irq_request = 0xFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + irq_preset = 0xFF; + } + } +} + +void Mapper012::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper012::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( vb0+chr4, vb0+chr5, vb0+chr6, vb0+chr7, + vb1+chr01, vb1+chr01+1, vb1+chr23, vb1+chr23+1 ); + } else { + SetVROM_8K_Bank( vb0+chr01, vb0+chr01+1, vb0+chr23, vb0+chr23+1, + vb1+chr4, vb1+chr5, vb1+chr6, vb1+chr7 ); + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } +} + +void Mapper012::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = (BYTE)irq_counter; + p[18] = irq_latch; + p[19] = irq_request; + p[20] = irq_preset; + p[21] = irq_preset_vbl; + *((DWORD*)&p[22]) = vb0; + *((DWORD*)&p[26]) = vb1; +} + +void Mapper012::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = (INT)p[17]; + irq_latch = p[18]; + irq_request = p[19]; + irq_preset = p[20]; + irq_preset_vbl = p[21]; + vb0 = *((DWORD*)&p[22]); + vb1 = *((DWORD*)&p[26]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper012.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper012.h new file mode 100644 index 00000000..6db96e26 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper012.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper012 DBZ5 // +////////////////////////////////////////////////////////////////////////// + +class Mapper012 : public Mapper +{ +public: + Mapper012( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow(WORD addr, BYTE data); + BYTE ReadLow(WORD addr); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + DWORD vb0, vb1; + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + BYTE irq_preset; + BYTE irq_preset_vbl; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper013.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper013.cpp new file mode 100644 index 00000000..1458491d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper013.cpp @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper013 CPROM // +////////////////////////////////////////////////////////////////////////// +void Mapper013::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + SetCRAM_4K_Bank( 0, 0 ); + SetCRAM_4K_Bank( 4, 0 ); +} + +void Mapper013::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( (data&0x30)>>4 ); + SetCRAM_4K_Bank( 4, data&0x03 ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper013.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper013.h new file mode 100644 index 00000000..e589d596 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper013.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper013 CPROM // +////////////////////////////////////////////////////////////////////////// +class Mapper013 : public Mapper +{ +public: + Mapper013( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper015.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper015.cpp new file mode 100644 index 00000000..c7a1e3ae --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper015.cpp @@ -0,0 +1,69 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper015 100-in-1 chip // +////////////////////////////////////////////////////////////////////////// +void Mapper015::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); +} +/* +void Mapper015::WriteLow(WORD addr, BYTE data) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF]=data; +} +*/ +void Mapper015::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr ) { + case 0x8000: + if( data&0x80 ) { + SetPROM_8K_Bank( 4, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 5, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 6, (data&0x3F)*2+3 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+2 ); + } else { + SetPROM_8K_Bank( 4, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 5, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 6, (data&0x3F)*2+2 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+3 ); + } + if( data&0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0x8001: + if( data&0x80 ) { + SetPROM_8K_Bank( 6, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+0 ); + } else { + SetPROM_8K_Bank( 6, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+1 ); + } + break; + case 0x8002: + if( data&0x80 ) { + SetPROM_8K_Bank( 4, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 5, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 6, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+1 ); + } else { + SetPROM_8K_Bank( 4, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 5, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 6, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+0 ); + } + break; + case 0x8003: + if( data&0x80 ) { + SetPROM_8K_Bank( 6, (data&0x3F)*2+1 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+0 ); + } else { + SetPROM_8K_Bank( 6, (data&0x3F)*2+0 ); + SetPROM_8K_Bank( 7, (data&0x3F)*2+1 ); + } + if( data&0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper015.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper015.h new file mode 100644 index 00000000..dd958ecc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper015.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper015 100-in-1 chip // +////////////////////////////////////////////////////////////////////////// +class Mapper015 : public Mapper +{ +public: + Mapper015( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); +// void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper016.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper016.cpp new file mode 100644 index 00000000..d67e6aca --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper016.cpp @@ -0,0 +1,336 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper016 Bandai Standard // +////////////////////////////////////////////////////////////////////////// +void Mapper016::Reset() +{ + patch = 0; + + reg[0] = reg[1] = reg[2] = 0; + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + + irq_type = 0; + nes->SetIrqType( NES::IRQ_CLOCK ); + + eeprom_type = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x3f15d20d // Famicom Jump 2(J) + || crc == 0xf76aa523 ) { // Famicom Jump 2(J)(alt) + patch = 1; + eeprom_type = 0xFF; + + WRAM[0x0BBC] = 0xFF; // SRAM΍ + } + + if( crc == 0x1d6f27f7 ) { // Dragon Ball Z 2(Korean Hack) + nes->SetIrqType( NES::IRQ_HSYNC ); + eeprom_type = 1; + } + + if( crc == 0x7fb799fd ) { // Dragon Ball 2 - Dai Maou Fukkatsu(J) + } + if( crc == 0x6c6c2feb // Dragon Ball 3 - Gokuu Den(J) + || crc == 0x8edeb257 ) { // Dragon Ball 3 - Gokuu Den(J)(Alt) + } + if( crc == 0x31cd9903 ) { // Dragon Ball Z - Kyoushuu! Saiya Jin(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + } + if( crc == 0xe49fc53e ) { // Dragon Ball Z 2 - Gekishin Freeza!!(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + eeprom_type = 1; + } + if( crc == 0x09499f4d ) { // Dragon Ball Z 3 - Ressen Jinzou Ningen(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + eeprom_type = 1; + } + if( crc == 0x2e991109 ) { // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J) + nes->SetIrqType( NES::IRQ_HSYNC ); + eeprom_type = 1; + } + if( crc == 0x146fb9c3 ) { // SD Gundam Gaiden - Knight Gundam Monogatari(J) + } + + if( crc == 0x73ac76db // SD Gundam Gaiden - Knight Gundam Monogatari 2 - Hikari no Kishi(J) + || crc == 0x81a15eb8 ) { // SD Gundam Gaiden - Knight Gundam Monogatari 3 - Densetsu no Kishi Dan(J) + eeprom_type = 1; + } + if( crc == 0x170250de ) { // Rokudenashi Blues(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + eeprom_type = 1; + } + + // DATACHn + if( crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars(J) + || crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai(J) + || crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight!(J) + || crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi(J) + || crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament(J) + || crc == 0xbe06853f ) { // Datach - J League Super Top Players(J) + eeprom_type = 2; + } + if( crc == 0xf51a7f46 ) { // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai(J) + nes->SetIrqType( NES::IRQ_HSYNC ); + eeprom_type = 2; + } + + if( eeprom_type == 0 ) { + nes->SetSAVERAM_SIZE( 128 ); + x24c01.Reset( WRAM ); + } else + if( eeprom_type == 1 ) { + nes->SetSAVERAM_SIZE( 256 ); + x24c02.Reset( WRAM ); + } else + if( eeprom_type == 2 ) { + nes->SetSAVERAM_SIZE( 384 ); + x24c02.Reset( WRAM ); + x24c01.Reset( WRAM+256 ); + } +} + +BYTE Mapper016::ReadLow( WORD addr ) +{ +// DEBUGOUT( "ReadLow - addr= %04x ; dat= %03x\n", addr, Mapper::ReadLow( addr ) ); + if( patch ) { + return Mapper::ReadLow( addr ); + } else { + if( (addr & 0x00FF) == 0x0000 ) { + BYTE ret = 0; + if( eeprom_type == 0 ) { + ret = x24c01.Read(); + } else + if( eeprom_type == 1 ) { + ret = x24c02.Read(); + } else + if( eeprom_type == 2 ) { + ret = x24c02.Read() & x24c01.Read(); + } + return (ret?0x10:0)|(nes->GetBarcodeStatus()); + } + } + return 0x00; +} + +void Mapper016::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + if( !patch ) { + WriteSubA( addr, data ); + } else { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper016::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + if( !patch ) { + WriteSubA( addr, data ); + } else { + WriteSubB( addr, data ); + } +} + +static BYTE eeprom_addinc; + +// Normal mapper #16 +void Mapper016::WriteSubA( WORD addr, BYTE data ) +{ + switch( addr & 0x000F ) { + case 0x0000: + case 0x0001: + case 0x0002: + case 0x0003: + case 0x0004: + case 0x0005: + case 0x0006: + case 0x0007: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( addr&0x0007, data ); + } + if( eeprom_type == 2 ) { + reg[0] = data; + x24c01.Write( (data&0x08)?0xFF:0, (reg[1]&0x40)?0xFF:0 ); + } + break; + + case 0x0008: + SetPROM_16K_Bank( 4, data ); + break; + + case 0x0009: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x000A: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + irq_enable = data & 0x01; + irq_counter = irq_latch; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x000B: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + irq_latch = (irq_latch & 0xFF00) | data; + irq_counter = (irq_counter & 0xFF00) | data; + break; + case 0x000C: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF); + irq_counter = ((INT)data << 8) | (irq_counter & 0x00FF); + break; + + case 0x000D: + // EEPTYPE0(DragonBallZ) + if( eeprom_type == 0 ) { + x24c01.Write( (data&0x20)?0xFF:0, (data&0x40)?0xFF:0 ); + } + // EEPTYPE1(DragonBallZ2,Z3,Z Gaiden) + if( eeprom_type == 1 ) { + x24c02.Write( (data&0x20)?0xFF:0, (data&0x40)?0xFF:0 ); + } + // EEPTYPE2(DATACH) + if( eeprom_type == 2 ) { + reg[1] = data; + x24c02.Write( (data&0x20)?0xFF:0, (data&0x40)?0xFF:0 ); + x24c01.Write( (reg[0]&0x08)?0xFF:0, (data&0x40)?0xFF:0 ); + } + break; + } +} + +// Famicom Jump 2 +void Mapper016::WriteSubB( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + case 0x8001: + case 0x8002: + case 0x8003: + reg[0] = data & 0x01; + SetPROM_8K_Bank( 4, reg[0]*0x20+reg[2]*2+0 ); + SetPROM_8K_Bank( 5, reg[0]*0x20+reg[2]*2+1 ); + break; + case 0x8004: + case 0x8005: + case 0x8006: + case 0x8007: + reg[1] = data & 0x01; + SetPROM_8K_Bank( 6, reg[1]*0x20+0x1E ); + SetPROM_8K_Bank( 7, reg[1]*0x20+0x1F ); + break; + case 0x8008: + reg[2] = data; + SetPROM_8K_Bank( 4, reg[0]*0x20+reg[2]*2+0 ); + SetPROM_8K_Bank( 5, reg[0]*0x20+reg[2]*2+1 ); + SetPROM_8K_Bank( 6, reg[1]*0x20+0x1E ); + SetPROM_8K_Bank( 7, reg[1]*0x20+0x1F ); + break; + + case 0x8009: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x800A: + irq_enable = data & 0x01; + irq_counter = irq_latch; + +// if( !irq_enable ) { +// nes->cpu->ClrIRQ( IRQ_MAPPER ); +// } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x800B: + irq_latch = (irq_latch & 0xFF00) | data; + break; + case 0x800C: + irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF); + break; + + case 0x800D: + break; + } +} + +void Mapper016::HSync( INT scanline ) +{ + if( irq_enable && (nes->GetIrqType() == NES::IRQ_HSYNC) ) { + if( irq_counter <= 113 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); +// nes->cpu->IRQ(); +//// nes->cpu->IRQ_NotPending(); +// irq_enable = 0; +// irq_counter = 0; + irq_counter &= 0xFFFF; + } else { + irq_counter -= 113; + } + } +} + +void Mapper016::Clock( INT cycles ) +{ + if( irq_enable && (nes->GetIrqType() == NES::IRQ_CLOCK) ) { + if( (irq_counter-=cycles) <= 0 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); +// nes->cpu->IRQ(); +//// nes->cpu->IRQ_NotPending(); +// irq_enable = 0; +// irq_counter = 0; + irq_counter &= 0xFFFF; + } + } +} + +void Mapper016::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = irq_enable; + *(INT*)&p[4] = irq_counter; + *(INT*)&p[8] = irq_latch; + + if( eeprom_type == 0 ) { + x24c01.Load( &p[16] ); + } else + if( eeprom_type == 1 ) { + x24c02.Load( &p[16] ); + } else + if( eeprom_type == 2 ) { + x24c02.Load( &p[16] ); + x24c01.Load( &p[48] ); + } +} + +void Mapper016::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + irq_enable = p[3]; + irq_counter = *(INT*)&p[4]; + irq_latch = *(INT*)&p[8]; + if( eeprom_type == 0 ) { + x24c01.Save( &p[16] ); + } else + if( eeprom_type == 1 ) { + x24c02.Save( &p[16] ); + } else + if( eeprom_type == 2 ) { + x24c02.Save( &p[16] ); + x24c01.Save( &p[48] ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper016.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper016.h new file mode 100644 index 00000000..4a712c96 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper016.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper016 Bandai Standard // +////////////////////////////////////////////////////////////////////////// +#include "EEPROM.h" + +class Mapper016 : public Mapper +{ +public: + Mapper016( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + void Clock( INT cycles ); + + // For Datach Barcode Battler + void SetBarcodeData( LPBYTE code, INT len ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; // For Famicom Jump 2 + BYTE eeprom_type; // EEPROM type + + BYTE reg[3]; + + BYTE irq_enable; + INT irq_counter; + INT irq_latch; + BYTE irq_type; + + X24C01 x24c01; + X24C02 x24c02; + +private: + void WriteSubA(WORD addr, BYTE data); + void WriteSubB(WORD addr, BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper017.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper017.cpp new file mode 100644 index 00000000..cc6d7dcc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper017.cpp @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper017 FFE F8xxx // +////////////////////////////////////////////////////////////////////////// +void Mapper017::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; +} + +void Mapper017::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x42FE: + if( data&0x10 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + case 0x42FF: + if( data&0x10 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0x4501: + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x4502: + irq_latch = (irq_latch&0xFF00)|data; + break; + case 0x4503: + irq_latch = (irq_latch&0x00FF)|((INT)data<<8); + irq_counter = irq_latch; + irq_enable = 0xFF; + break; + + case 0x4504: + case 0x4505: + case 0x4506: + case 0x4507: + SetPROM_8K_Bank( addr&0x07, data ); + break; + + case 0x4510: + case 0x4511: + case 0x4512: + case 0x4513: + case 0x4514: + case 0x4515: + case 0x4516: + case 0x4517: + SetVROM_1K_Bank( addr&0x07, data ); + break; + + default: + Mapper::WriteLow( addr, data ); + break; + } +} + +void Mapper017::HSync( INT scanline ) +{ + if( irq_enable ) { + if( irq_counter >= 0xFFFF-113 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); +// nes->cpu->IRQ(); +// irq_counter = 0; +// irq_enable = 0; + irq_counter &= 0xFFFF; + } else { + irq_counter += 113; + } + } +} + +void Mapper017::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_counter; + *(INT*)&p[5] = irq_latch; +} + +void Mapper017::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = *(INT*)&p[1]; + irq_latch = *(INT*)&p[5]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper017.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper017.h new file mode 100644 index 00000000..4858afe0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper017.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper017 FFE F8xxx // +////////////////////////////////////////////////////////////////////////// +class Mapper017 : public Mapper +{ +public: + Mapper017( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + INT irq_counter; + INT irq_latch; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper018.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper018.cpp new file mode 100644 index 00000000..603e315a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper018.cpp @@ -0,0 +1,231 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper018 Jaleco SS8806 // +////////////////////////////////////////////////////////////////////////// +void Mapper018::Reset() +{ + for( INT i = 0; i < 11; i++ ) { + reg[i] = 0; + } + reg[2] = PROM_8K_SIZE-2; + reg[3] = PROM_8K_SIZE-1; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + irq_enable = 0; + irq_mode = 0; + irq_counter = 0xFFFF; + irq_latch = 0xFFFF; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0xefb1df9e ) { // The Lord of King(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + if( crc == 0x3746f951 ) { // Pizza Pop!(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + +// nes->SetRenderMethod( NES::PRE_ALL_RENDER ); +// nes->SetRenderMethod( NES::POST_ALL_RENDER ); +} + +void Mapper018::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetPROM_8K_Bank( 4, reg[0] ); + break; + case 0x8001: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetPROM_8K_Bank( 4, reg[0] ); + break; + case 0x8002: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetPROM_8K_Bank( 5, reg[1] ); + break; + case 0x8003: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetPROM_8K_Bank( 5, reg[1] ); + break; + case 0x9000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetPROM_8K_Bank( 6, reg[2] ); + break; + case 0x9001: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetPROM_8K_Bank( 6, reg[2] ); + break; + + case 0xA000: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[3] ); + break; + case 0xA001: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[3] ); + break; + case 0xA002: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[4] ); + break; + case 0xA003: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[4] ); + break; + + case 0xB000: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[5] ); + break; + case 0xB001: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[5] ); + break; + case 0xB002: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[6] ); + break; + case 0xB003: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[6] ); + break; + + case 0xC000: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[7] ); + break; + case 0xC001: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[7] ); + break; + case 0xC002: + reg[8] = (reg[8] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[8] ); + break; + case 0xC003: + reg[8] = (reg[8] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[8] ); + break; + + case 0xD000: + reg[9] = (reg[9] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[9] ); + break; + case 0xD001: + reg[9] = (reg[9] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[9] ); + break; + case 0xD002: + reg[10] = (reg[10] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[10] ); + break; + case 0xD003: + reg[10] = (reg[10] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[10] ); + break; + + case 0xE000: + irq_latch = (irq_latch & 0xFFF0) | (data & 0x0F); + break; + case 0xE001: + irq_latch = (irq_latch & 0xFF0F) | ((data & 0x0F) << 4); + break; + case 0xE002: + irq_latch = (irq_latch & 0xF0FF) | ((data & 0x0F) << 8); + break; + case 0xE003: + irq_latch = (irq_latch & 0x0FFF) | ((data & 0x0F) << 12); + break; + + case 0xF000: +// if( data & 0x01 ) { + irq_counter = irq_latch; +// } else { +// irq_counter = 0; +// } + break; + case 0xF001: + irq_mode = (data>>1) & 0x07; + irq_enable = (data & 0x01); +// if( !irq_enable ) { + nes->cpu->ClrIRQ( IRQ_MAPPER ); +// } + break; + + case 0xF002: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + } +} + +void Mapper018::Clock( INT cycles ) +{ +BOOL bIRQ = FALSE; +INT irq_counter_old = irq_counter; + + if( irq_enable && irq_counter ) { + irq_counter -= cycles; + + switch( irq_mode ) { + case 0: + if( irq_counter <= 0 ) { + bIRQ = TRUE; + } + break; + case 1: + if( (irq_counter & 0xF000) != (irq_counter_old & 0xF000) ) { + bIRQ = TRUE; + } + break; + case 2: + case 3: + if( (irq_counter & 0xFF00) != (irq_counter_old & 0xFF00) ) { + bIRQ = TRUE; + } + break; + case 4: + case 5: + case 6: + case 7: + if( (irq_counter & 0xFFF0) != (irq_counter_old & 0xFFF0) ) { + bIRQ = TRUE; + } + break; + } + + if( bIRQ ) { +//// irq_enable = 0; +// irq_counter = irq_latch; + irq_counter = 0; + irq_enable = 0; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper018::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 11; i++ ) { + p[i] = reg[i]; + } + p[11] = irq_enable; + p[12] = irq_mode; + *(INT*)&p[13] = irq_counter; + *(INT*)&p[17] = irq_latch; +} + +void Mapper018::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 11; i++ ) { + p[i] = reg[i]; + } + irq_enable = p[11]; + irq_mode = p[12]; + irq_counter = *(INT*)&p[13]; + irq_latch = *(INT*)&p[17]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper018.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper018.h new file mode 100644 index 00000000..6874bfa7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper018.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper018 Jaleco SS8806 // +////////////////////////////////////////////////////////////////////////// +class Mapper018 : public Mapper +{ +public: + Mapper018( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void Clock(INT cycles); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[11]; + + BYTE irq_enable; + BYTE irq_mode; + INT irq_latch; + INT irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper019.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper019.cpp new file mode 100644 index 00000000..9727f78a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper019.cpp @@ -0,0 +1,301 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper019 Namcot 106 // +////////////////////////////////////////////////////////////////////////// +void Mapper019::Reset() +{ + patch = 0; + + reg[0] = reg[1] = reg[2] = 0; + + ::memset( exram, 0, sizeof(exram) ); + + irq_enable = 0; + irq_counter = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE >= 8 ) { + SetVROM_8K_Bank( VROM_8K_SIZE-1 ); + } + + exsound_enable = 0xFF; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0xb62a7b71 ) { // Family Circuit '91(J) + patch = 1; + } + + if( crc == 0x14942c06 ) { // Wagan Land 3(J) + patch = 2; + } + + if( crc == 0x968dcf09 ) { // Final Lap(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + if( crc == 0x3deac303 ) { // Rolling Thunder(J) + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } + + if( crc == 0xb1b9e187 ) { // For Kaijuu Monogatari(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + + if( crc == 0x6901346e ) { // For Sangokushi 2 - Haou no Tairiku(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + +// if( crc == 0xdd454208 ) { // Hydlide 3(J) +// nes->SetRenderMethod( NES::PRE_ALL_RENDER ); +// } + + if( crc == 0xaf15338f // For Mindseeker(J) + || crc == 0xb1b9e187 // For Kaijuu Monogatari(J) + || crc == 0x96533999 // Dokuganryuu Masamune(J) +// || crc == 0x2b825ce1 // Namco Classic(J) +// || crc == 0x9a2b0641 // Namco Classic 2(J) + || crc == 0x3296ff7a // Battle Fleet(J) + || crc == 0xdd454208 ) { // Hydlide 3(J) + exsound_enable = 0; + } + + if( crc == 0x429fd177 ) { // Famista '90(J) + exsound_enable = 0; + } + + if( exsound_enable ) { + nes->apu->SelectExSound( 0x10 ); + } +} + +BYTE Mapper019::ReadLow( WORD addr ) +{ +BYTE data = 0; + + switch( addr & 0xF800 ) { + case 0x4800: + if( addr == 0x4800 ) { + if( exsound_enable ) { + nes->apu->ExRead(addr); + data = exram[reg[2]&0x7F]; + } else { + data = WRAM[reg[2]&0x7F]; + } + if( reg[2]&0x80 ) + reg[2] = (reg[2]+1)|0x80; + return data; + } + break; + case 0x5000: + return (BYTE)irq_counter & 0x00FF; + case 0x5800: + return (BYTE)((irq_counter>>8) & 0x7F); + case 0x6000: + case 0x6800: + case 0x7000: + case 0x7800: + return Mapper::ReadLow( addr ); + } + + return (BYTE)(addr>>8); +} + +void Mapper019::WriteLow( WORD addr, BYTE data ) +{ + switch( addr & 0xF800 ) { + case 0x4800: + if( addr == 0x4800 ) { + if( exsound_enable ) { + nes->apu->ExWrite( addr, data ); + exram[reg[2]&0x7F] = data; + } else { + WRAM[reg[2]&0x7F] = data; + } + if( reg[2]&0x80 ) + reg[2] = (reg[2]+1)|0x80; + } + break; + case 0x5000: + irq_counter = (irq_counter & 0xFF00) | (WORD)data; +// if( irq_enable ) { +// irq_counter++; +// } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x5800: + irq_counter = (irq_counter & 0x00FF) | ((WORD)(data & 0x7F) << 8); + irq_enable = data & 0x80; +// if( irq_enable ) { +// irq_counter++; +// } +// if( !irq_enable ) { +// nes->cpu->ClrIRQ( IRQ_MAPPER ); +// } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x6000: + case 0x6800: + case 0x7000: + case 0x7800: + Mapper::WriteLow( addr, data ); + break; + } +} + +void Mapper019::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF800 ) { + case 0x8000: + if( (data < 0xE0) || (reg[0] != 0) ) { + SetVROM_1K_Bank( 0, data ); + } else { + SetCRAM_1K_Bank( 0, data&0x1F ); + } + break; + case 0x8800: + if( (data < 0xE0) || (reg[0] != 0) ) { + SetVROM_1K_Bank( 1, data ); + } else { + SetCRAM_1K_Bank( 1, data&0x1F ); + } + break; + case 0x9000: + if( (data < 0xE0) || (reg[0] != 0) ) { + SetVROM_1K_Bank( 2, data ); + } else { + SetCRAM_1K_Bank( 2, data&0x1F ); + } + break; + case 0x9800: + if( (data < 0xE0) || (reg[0] != 0) ) { + SetVROM_1K_Bank( 3, data ); + } else { + SetCRAM_1K_Bank( 3, data&0x1F ); + } + break; + case 0xA000: + if( (data < 0xE0) || (reg[1] != 0) ) { + SetVROM_1K_Bank( 4, data ); + } else { + SetCRAM_1K_Bank( 4, data&0x1F ); + } + break; + case 0xA800: + if( (data < 0xE0) || (reg[1] != 0) ) { + SetVROM_1K_Bank( 5, data ); + } else { + SetCRAM_1K_Bank( 5, 5 ); + } + break; + case 0xB000: + if( (data < 0xE0) || (reg[1] != 0) ) { + SetVROM_1K_Bank( 6, data ); + } else { + SetCRAM_1K_Bank( 6, data&0x1F ); + } + break; + case 0xB800: + if( (data < 0xE0) || (reg[1] != 0) ) { + SetVROM_1K_Bank( 7, data ); + } else { + SetCRAM_1K_Bank( 7, data&0x1F ); + } + break; + case 0xC000: + if( !patch ) { + if( data <= 0xDF ) { + SetVROM_1K_Bank( 8, data ); + } else { + SetVRAM_1K_Bank( 8, data & 0x01 ); + } + } + break; + case 0xC800: + if( !patch ) { + if( data <= 0xDF ) { + SetVROM_1K_Bank( 9, data ); + } else { + SetVRAM_1K_Bank( 9, data & 0x01 ); + } + } + break; + case 0xD000: + if( !patch ) { + if( data <= 0xDF ) { + SetVROM_1K_Bank( 10, data ); + } else { + SetVRAM_1K_Bank( 10, data & 0x01 ); + } + } + break; + case 0xD800: + if( !patch ) { + if( data <= 0xDF ) { + SetVROM_1K_Bank( 11, data ); + } else { + SetVRAM_1K_Bank( 11, data & 0x01 ); + } + } + break; + case 0xE000: + SetPROM_8K_Bank( 4, data & 0x3F ); + if( patch == 2 ) { + if( data & 0x40 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + break; + case 0xE800: + reg[0] = data & 0x40; + reg[1] = data & 0x80; + SetPROM_8K_Bank( 5, data & 0x3F ); + break; + case 0xF000: + SetPROM_8K_Bank( 6, data & 0x3F ); + break; + case 0xF800: + if( addr == 0xF800 ) { + if( exsound_enable ) { + nes->apu->ExWrite( addr, data ); + } + reg[2] = data; + } + break; + } +} + +void Mapper019::Clock( INT cycles ) +{ + if( irq_enable ) { + if( (irq_counter+=cycles) >= 0x7FFF ) { +// irq_counter = 0x7FFF; +// nes->cpu->IRQ_NotPending(); + + irq_enable = 0; +// irq_counter &= 0x7FFF; + irq_counter = 0x7FFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper019::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = irq_enable; + *(WORD*)&p[4] = irq_counter; + + ::memcpy( &p[8], exram, sizeof(exram) ); +} + +void Mapper019::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + irq_enable = p[3]; + irq_counter = *(WORD*)&p[4]; + + ::memcpy( exram, &p[8], sizeof(exram) ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper019.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper019.h new file mode 100644 index 00000000..2249afd2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper019.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper019 Namcot 106 // +////////////////////////////////////////////////////////////////////////// +class Mapper019 : public Mapper +{ +public: + Mapper019( NES* parent ) : Mapper(parent) {} + + void Reset(); + + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + BYTE exsound_enable; + + BYTE reg[3]; + BYTE exram[128]; + + BYTE irq_enable; + WORD irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper021.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper021.cpp new file mode 100644 index 00000000..d15aa99e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper021.cpp @@ -0,0 +1,209 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper021 Konami VRC4 (Address mask $F006 or $F0C0) // +////////////////////////////////////////////////////////////////////////// +void Mapper021::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper021::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF0CF ) { + case 0x8000: + if(reg[8] & 0x02) { + SetPROM_8K_Bank( 6, data ); + } else { + SetPROM_8K_Bank( 4, data ); + } + break; + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + + case 0x9000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x9002: + case 0x9080: + reg[8] = data; + break; + + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB002: + case 0xB040: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + + case 0xB001: + case 0xB004: + case 0xB080: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB003: + case 0xB006: + case 0xB0C0: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC002: + case 0xC040: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + + case 0xC001: + case 0xC004: + case 0xC080: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC003: + case 0xC006: + case 0xC0C0: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD002: + case 0xD040: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + + case 0xD001: + case 0xD004: + case 0xD080: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD003: + case 0xD006: + case 0xD0C0: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE002: + case 0xE040: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + + case 0xE001: + case 0xE004: + case 0xE080: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE003: + case 0xE006: + case 0xE0C0: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + break; + case 0xF002: + case 0xF040: + irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); + break; + + case 0xF003: + case 0xF0C0: + case 0xF006: + irq_enable = (irq_enable & 0x01) * 3; + irq_clock = 0; + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF004: + case 0xF080: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + +// case 0xF006: +// nes->cpu->ClrIRQ( IRQ_MAPPER ); +// break; + } +} + +void Mapper021::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock-=cycles) < 0 ) { + irq_clock += 0x72; + if( irq_counter == 0xFF ) { + irq_counter = irq_latch; +// irq_enable = (irq_enable & 0x01) * 3; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } + } +} + +void Mapper021::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + p[i] = reg[i]; + } + p[ 9] = irq_enable; + p[10] = irq_counter; + p[11] = irq_latch; + *(INT*)&p[12] = irq_clock; +} + +void Mapper021::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[ 9]; + irq_counter = p[10]; + irq_latch = p[11]; + irq_clock = *(INT*)&p[12]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper021.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper021.h new file mode 100644 index 00000000..ea0e9ead --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper021.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper021 Konami VRC4 (Address mask $F006 or $F0C0) // +////////////////////////////////////////////////////////////////////////// +class Mapper021 : public Mapper +{ +public: + Mapper021( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[9]; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper022.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper022.cpp new file mode 100644 index 00000000..4580f7f3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper022.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper022 Konami VRC2 type A // +////////////////////////////////////////////////////////////////////////// +void Mapper022::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper022::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + + case 0x9000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + + case 0xB000: + SetVROM_1K_Bank( 0, data>>1 ); + break; + + case 0xB001: + SetVROM_1K_Bank( 1, data>>1 ); + break; + + case 0xC000: + SetVROM_1K_Bank( 2, data>>1 ); + break; + + case 0xC001: + SetVROM_1K_Bank( 3, data>>1 ); + break; + + case 0xD000: + SetVROM_1K_Bank( 4, data>>1 ); + break; + + case 0xD001: + SetVROM_1K_Bank( 5, data>>1 ); + break; + + case 0xE000: + SetVROM_1K_Bank( 6, data>>1 ); + break; + + case 0xE001: + SetVROM_1K_Bank( 7, data>>1 ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper022.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper022.h new file mode 100644 index 00000000..145c9b50 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper022.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper022 Konami VRC2 type A // +////////////////////////////////////////////////////////////////////////// +class Mapper022 : public Mapper +{ +public: + Mapper022( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper023.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper023.cpp new file mode 100644 index 00000000..050546ff --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper023.cpp @@ -0,0 +1,225 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper023 Konami VRC2 type B // +////////////////////////////////////////////////////////////////////////// +void Mapper023::Reset() +{ +// addrmask = 0xFFFF; + addrmask = 0xF003; + + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + reg[9] = 1; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + +// nes->SetRenderMethod( NES::POST_RENDER ); + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x93794634 ) { // Akumajou Special Boku Dracula Kun(J) + addrmask = 0xF00C; + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + if( crc == 0xdd53c4ae ) { // Tiny Toon Adventures(J) + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } +} + +void Mapper023::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr & addrmask ) { + case 0x8000: + case 0x8004: + case 0x8008: + case 0x800C: + if(reg[8]) { + SetPROM_8K_Bank( 6, data ); + } else { + SetPROM_8K_Bank( 4, data ); + } + break; + + case 0x9000: + if( data != 0xFF ) { + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + } + break; + + case 0x9008: + reg[8] = data & 0x02; + break; + + case 0xA000: + case 0xA004: + case 0xA008: + case 0xA00C: + SetPROM_8K_Bank( 5, data ); + break; + + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB001: + case 0xB004: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + + case 0xB002: + case 0xB008: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xB003: + case 0xB00C: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + + case 0xC001: + case 0xC004: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + + case 0xC002: + case 0xC008: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xC003: + case 0xC00C: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + + case 0xD001: + case 0xD004: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + + case 0xD002: + case 0xD008: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xD003: + case 0xD00C: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + + case 0xE001: + case 0xE004: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + + case 0xE002: + case 0xE008: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xE003: + case 0xE00C: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF001: + case 0xF004: + irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF002: + case 0xF008: + irq_enable = data & 0x03; + irq_counter = irq_latch; + irq_clock = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF003: + case 0xF00C: + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper023::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + irq_clock += cycles*3; + while( irq_clock >= 341 ) { + irq_clock -= 341; + irq_counter++; + if( irq_counter == 0 ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +} + +void Mapper023::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + p[i] = reg[i]; + } + p[ 9] = irq_enable; + p[10] = irq_counter; + p[11] = irq_latch; + *(INT*)&p[12] = irq_clock; +} + +void Mapper023::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[ 9]; + irq_counter = p[10]; + irq_latch = p[11]; + irq_clock = *(INT*)&p[12]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper023.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper023.h new file mode 100644 index 00000000..c8a5b5a7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper023.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper023 Konami VRC2 type B // +////////////////////////////////////////////////////////////////////////// +class Mapper023 : public Mapper +{ +public: + Mapper023( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + WORD addrmask; + + BYTE reg[9]; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper024.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper024.cpp new file mode 100644 index 00000000..cb9a24cc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper024.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper024 Konami VRC6(Normal) // +////////////////////////////////////////////////////////////////////////// +void Mapper024::Reset() +{ + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + nes->SetRenderMethod( NES::POST_RENDER ); +// nes->SetRenderMethod( NES::PRE_RENDER ); + + nes->apu->SelectExSound( 1 ); +} + +void Mapper024::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF003 ) { + case 0x8000: + SetPROM_16K_Bank( 4, data ); + break; + + case 0x9000: case 0x9001: case 0x9002: + case 0xA000: case 0xA001: case 0xA002: + case 0xB000: case 0xB001: case 0xB002: + nes->apu->ExWrite( addr, data ); + break; + + case 0xB003: + data = data & 0x0C; + if( data == 0x00 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 0x04 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 0x08 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else if( data == 0x0C ) SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0xC000: + SetPROM_8K_Bank( 6, data ); + break; + + case 0xD000: + SetVROM_1K_Bank( 0, data ); + break; + + case 0xD001: + SetVROM_1K_Bank( 1, data ); + break; + + case 0xD002: + SetVROM_1K_Bank( 2, data ); + break; + + case 0xD003: + SetVROM_1K_Bank( 3, data ); + break; + + case 0xE000: + SetVROM_1K_Bank( 4, data ); + break; + + case 0xE001: + SetVROM_1K_Bank( 5, data ); + break; + + case 0xE002: + SetVROM_1K_Bank( 6, data ); + break; + + case 0xE003: + SetVROM_1K_Bank( 7, data ); + break; + + case 0xF000: + irq_latch = data; + break; + case 0xF001: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF002: + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper024::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock+=cycles) >= 0x72 ) { + irq_clock -= 0x72; + if( irq_counter == 0xFF ) { + irq_counter = irq_latch; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } + } +} + +void Mapper024::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; + p[2] = irq_latch; + *(INT*)&p[3] = irq_clock; +} + +void Mapper024::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; + irq_latch = p[2]; + irq_clock = *(INT*)&p[3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper024.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper024.h new file mode 100644 index 00000000..7c280585 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper024.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper024 Konami VRC6 (Normal) // +////////////////////////////////////////////////////////////////////////// +class Mapper024 : public Mapper +{ +public: + Mapper024( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper025.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper025.cpp new file mode 100644 index 00000000..20f66746 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper025.cpp @@ -0,0 +1,232 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper025 Konami VRC4(Normal) // +////////////////////////////////////////////////////////////////////////// +void Mapper025::Reset() +{ + for( INT i = 0; i < 11; i++ ) { + reg[i] = 0; + } + reg[9] = PROM_8K_SIZE-2; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_occur = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0xc71d4ce7 ) { // Gradius II(J) +// nes->SetRenderMethod( NES::POST_RENDER ); + } + if( crc == 0xa2e68da8 ) { // For Racer Mini Yonku - Japan Cup(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0xea74c587 ) { // For Teenage Mutant Ninja Turtles(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } + if( crc == 0x5f82cb7d ) { // For Teenage Mutant Ninja Turtles 2(J) + } + if( crc == 0x0bbd85ff ) { // For Bio Miracle Bokutte Upa(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } +} + +void Mapper025::Write( WORD addr, BYTE data ) +{ +//if( addr >= 0xF000 ) +//DEBUGOUT( "M25 WR $%04X=$%02X L=%3d\n", addr, data, nes->GetScanline() ); + if(addr>=0xf000) DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + switch( addr & 0xF000 ) { + case 0x8000: + if(reg[10] & 0x02) { + reg[9] = data; + SetPROM_8K_Bank( 6, data ); + } else { + reg[8] = data; + SetPROM_8K_Bank( 4, data ); + } + break; + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + } + + switch( addr & 0xF00F ) { + case 0x9000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x9001: + case 0x9004: + if((reg[10] & 0x02) != (data & 0x02)) { + BYTE swap = reg[8]; + reg[8] = reg[9]; + reg[9] = swap; + + SetPROM_8K_Bank( 4, reg[8] ); + SetPROM_8K_Bank( 6, reg[9] ); + } + reg[10] = data; + break; + + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB002: + case 0xB008: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + + case 0xB001: + case 0xB004: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB003: + case 0xB00C: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC002: + case 0xC008: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + + case 0xC001: + case 0xC004: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC003: + case 0xC00C: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD002: + case 0xD008: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + + case 0xD001: + case 0xD004: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD003: + case 0xD00C: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE002: + case 0xE008: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + + case 0xE001: + case 0xE004: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE003: + case 0xE00C: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF002: + case 0xF008: + irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF001: + case 0xF004: + irq_enable = data & 0x03; +// irq_counter = 0x100 - irq_latch; + irq_counter = irq_latch; + irq_clock = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF003: + case 0xF00C: + irq_enable = (irq_enable & 0x01)*3; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper025::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + irq_clock += cycles*3; + while( irq_clock >= 341 ) { + irq_clock -= 341; + irq_counter++; + if( irq_counter == 0 ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +} + +void Mapper025::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 11; i++ ) { + p[i] = reg[i]; + } + p[11] = irq_enable; + p[12] = irq_occur; + p[13] = irq_latch; + p[14] = irq_counter; + *((INT*)&p[15]) = irq_clock; +} + +void Mapper025::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 11; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[11]; + irq_occur = p[12]; + irq_latch = p[13]; + irq_counter = p[14]; + irq_clock = *((INT*)&p[15]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper025.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper025.h new file mode 100644 index 00000000..dc11d3c4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper025.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper025 Konami VRC4 (Normal) // +////////////////////////////////////////////////////////////////////////// +class Mapper025 : public Mapper +{ +public: + Mapper025( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[11]; + BYTE irq_enable; + BYTE irq_latch; + BYTE irq_occur; + BYTE irq_counter; + INT irq_clock; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper026.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper026.cpp new file mode 100644 index 00000000..c1d87b42 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper026.cpp @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper026 Konami VRC6 (PA0,PA1 reverse) // +////////////////////////////////////////////////////////////////////////// +void Mapper026::Reset() +{ + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x30e64d03 ) { // Esper Dream 2 - Aratanaru Tatakai(J) + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } + if( crc == 0x836cc1ab ) { // Mouryou Senki Madara(J) + nes->SetRenderMethod( NES::POST_RENDER ); + } + + nes->apu->SelectExSound( 1 ); +} + +void Mapper026::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF003 ) { + case 0x8000: + SetPROM_16K_Bank( 4, data ); + break; + + case 0x9000: case 0x9001: case 0x9002: case 0x9003: + case 0xA000: case 0xA001: case 0xA002: case 0xA003: + case 0xB000: case 0xB001: case 0xB002: + addr = (addr&0xfffc)|((addr&1)<<1)|((addr&2)>>1); + nes->apu->ExWrite( addr, data ); + break; + + case 0xB003: + data = data & 0x7F; + if( data == 0x08 || data == 0x2C ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else if( data == 0x20 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 0x24 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 0x28 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + + case 0xC000: + SetPROM_8K_Bank( 6, data ); + break; + + case 0xD000: + SetVROM_1K_Bank( 0, data ); + break; + + case 0xD001: + SetVROM_1K_Bank( 2, data ); + break; + + case 0xD002: + SetVROM_1K_Bank( 1, data ); + break; + + case 0xD003: + SetVROM_1K_Bank( 3, data ); + break; + + case 0xE000: + SetVROM_1K_Bank( 4, data ); + break; + + case 0xE001: + SetVROM_1K_Bank( 6, data ); + break; + + case 0xE002: + SetVROM_1K_Bank( 5, data ); + break; + + case 0xE003: + SetVROM_1K_Bank( 7, data ); + break; + + case 0xF000: + irq_latch = data; + break; + case 0xF001: + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF002: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper026::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock+=cycles) >= 0x72 ) { + irq_clock -= 0x72; + if( irq_counter >= 0xFF ) { + irq_counter = irq_latch; +// nes->cpu->IRQ_NotPending(); +//// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } + } +} + +void Mapper026::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; + p[2] = irq_latch; + *(INT*)&p[3] = irq_clock; +} + +void Mapper026::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; + irq_latch = p[2]; + irq_clock = *(INT*)&p[3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper026.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper026.h new file mode 100644 index 00000000..e598c212 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper026.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper026 Konami VRC6 (PA0,PA1 reverse) // +////////////////////////////////////////////////////////////////////////// +class Mapper026 : public Mapper +{ +public: + Mapper026( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper027.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper027.cpp new file mode 100644 index 00000000..f141062d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper027.cpp @@ -0,0 +1,174 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper027 Konami VRC4 (World Hero) // +////////////////////////////////////////////////////////////////////////// +void Mapper027::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper027::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF0CF ) { + case 0x8000: + if(reg[8] & 0x02) { + SetPROM_8K_Bank( 6, data ); + } else { + SetPROM_8K_Bank( 4, data ); + } + break; + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + + case 0x9000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x9002: + case 0x9080: + reg[8] = data; + break; + + case 0xB000: + reg[0] = (reg[0] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB001: + reg[0] = (reg[0] & 0x0F) | (data<< 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + + case 0xB002: + reg[1] = (reg[1] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB003: + reg[1] = (reg[1] & 0x0F) | (data<< 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC001: + reg[2] = (reg[2] & 0x0F) | (data<< 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + + case 0xC002: + reg[3] = (reg[3] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC003: + reg[3] = (reg[3] & 0x0F) | (data<< 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD001: + reg[4] = (reg[4] & 0x0F) | (data<< 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + + case 0xD002: + reg[5] = (reg[5] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD003: + reg[5] = (reg[5] & 0x0F) | (data << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE001: + reg[6] = (reg[6] & 0x0F) | (data << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + + case 0xE002: + reg[7] = (reg[7] & 0xFF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE003: + reg[7] = (reg[7] & 0x0F) | (data<< 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + break; + case 0xF001: + irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); + break; + + case 0xF003: + irq_enable = (irq_enable & 0x01) * 3; + irq_clock = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF002: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper027::HSync( INT scanline ) +{ + if( irq_enable & 0x02 ) { + if( irq_counter == 0xFF ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } +} + +void Mapper027::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + p[i] = reg[i]; + } + p[ 9] = irq_enable; + p[10] = irq_counter; + p[11] = irq_latch; + *(INT*)&p[12] = irq_clock; +} + +void Mapper027::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[ 9]; + irq_counter = p[10]; + irq_latch = p[11]; + irq_clock = *(INT*)&p[12]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper027.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper027.h new file mode 100644 index 00000000..19a58dd9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper027.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper027 Konami VRC4 (World Hero) // +////////////////////////////////////////////////////////////////////////// +class Mapper027 : public Mapper +{ +public: + Mapper027( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + WORD reg[9]; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper032.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper032.cpp new file mode 100644 index 00000000..272c58c7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper032.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper032 Irem G101 // +////////////////////////////////////////////////////////////////////////// +void Mapper032::Reset() +{ + patch = 0; + reg = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + DWORD crc = nes->rom->GetPROM_CRC(); + + // For Major League(J) + if( crc == 0xc0fed437 ) { + patch = 1; + } + // For Ai Sensei no Oshiete - Watashi no Hoshi(J) + if( crc == 0xfd3fc292 ) { + SetPROM_32K_Bank( 30, 31, 30, 31 ); + } +} + +void Mapper032::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF000 ) { + case 0x8000: + if( reg & 0x02 ) { + SetPROM_8K_Bank( 6, data ); + } else { + SetPROM_8K_Bank( 4, data ); + } + break; + + case 0x9000: + reg = data; + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + } + + switch( addr & 0xF007 ) { + case 0xB000: + case 0xB001: + case 0xB002: + case 0xB003: + case 0xB004: + case 0xB005: + SetVROM_1K_Bank( addr & 0x0007, data ); + break; + case 0xB006: + SetVROM_1K_Bank( 6, data ); + + if( patch && (data & 0x40) ) { + SetVRAM_Mirror( 0, 0, 0, 1 ); + } + break; + case 0xB007: + SetVROM_1K_Bank( 7, data ); + + if( patch && (data & 0x40) ) { + SetVRAM_Mirror( 0, 0, 0, 0 ); + } + break; + } +} + +void Mapper032::SaveState( LPBYTE p ) +{ + p[0] = reg; +} + +void Mapper032::LoadState( LPBYTE p ) +{ + reg = p[0]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper032.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper032.h new file mode 100644 index 00000000..cefda815 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper032.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper032 Irem G101 // +////////////////////////////////////////////////////////////////////////// +class Mapper032 : public Mapper +{ +public: + Mapper032( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + + BYTE reg; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper033.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper033.cpp new file mode 100644 index 00000000..ddcf2d83 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper033.cpp @@ -0,0 +1,175 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper033 Taito TC0190 // +////////////////////////////////////////////////////////////////////////// +void Mapper033::Reset() +{ + patch = 0; + + irq_enable = 0; + irq_counter = 0; + + reg[0] = 0; + reg[1] = 2; + reg[2] = 4; + reg[3] = 5; + reg[4] = 6; + reg[5] = 7; + reg[6] = 1; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetBank(); + } + + DWORD crc = nes->rom->GetPROM_CRC(); + // Check For Old #33 games.... (CRC code by NesToy) + if( crc == 0x5e9bc161 // Akira(J) + || crc == 0xecdbafa4 // Bakushou!! Jinsei Gekijou(J) + || crc == 0x59cd0c31 // Don Doko Don(J) + || crc == 0x837c1342 // Golf Ko Open(J) + || crc == 0x42d893e4 // Operation Wolf(J) + || crc == 0x1388aeb9 // Operation Wolf(U) + || crc == 0x07ee6d8f // Power Blazer(J) + || crc == 0x5193fb54 // Takeshi no Sengoku Fuuunji(J) + || crc == 0xa71c3452 ) { // Insector X(J) + patch = 1; + } + + nes->SetRenderMethod( NES::PRE_RENDER ); + +// if( crc == 0x202df297 ) { // Captain Saver(J) +// nes->SetRenderMethod( NES::TILE_RENDER ); +// } + if( crc == 0x63bb86b5 ) { // The Jetsons(J) + nes->SetRenderMethod( NES::TILE_RENDER ); + } +} + +void Mapper033::Write( WORD addr, BYTE data ) +{ +// LOG( "Mapper033 addr=%04X data=%02X", addr&0xFFFF, data&0xFF ); + + switch( addr ) { + case 0x8000: + if( patch ) { + if( data & 0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + SetPROM_8K_Bank( 4, data & 0x1F ); + } else { + SetPROM_8K_Bank( 4, data ); + } + break; + case 0x8001: + if( patch ) { + SetPROM_8K_Bank( 5, data & 0x1F ); + } else { + SetPROM_8K_Bank( 5, data ); + } + break; + + case 0x8002: + reg[0] = data; + SetBank(); + break; + case 0x8003: + reg[1] = data; + SetBank(); + break; + case 0xA000: + reg[2] = data; + SetBank(); + break; + case 0xA001: + reg[3] = data; + SetBank(); + break; + case 0xA002: + reg[4] = data; + SetBank(); + break; + case 0xA003: + reg[5] = data; + SetBank(); + break; + + case 0xC003: + case 0xE003: + reg[6] = data; + SetBank(); + break; + + case 0xC000: + irq_counter = data; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xC001: + case 0xC002: + case 0xE001: + case 0xE002: + irq_enable = data; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xE000: + if( data & 0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } +} + +void Mapper033::HSync( INT scanline ) +{ +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + if( scanline >= 0 && scanline <= 239 ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( irq_counter == 0xFF ) { + irq_enable = 0; + irq_counter = 0; +// nes->cpu->SetIRQ( IRQ_MAPPER ); + nes->cpu->SetIRQ( IRQ_TRIGGER ); + } else { + irq_counter++; + } + } + } + } +} + +void Mapper033::SetBank() +{ + SetVROM_2K_Bank( 0, reg[0] ); + SetVROM_2K_Bank( 2, reg[1] ); + +// if( reg[6] & 0x01 ) { + SetVROM_1K_Bank( 4, reg[2] ); + SetVROM_1K_Bank( 5, reg[3] ); + SetVROM_1K_Bank( 6, reg[4] ); + SetVROM_1K_Bank( 7, reg[5] ); +// } else { +// SetVROM_2K_Bank( 4, reg[0] ); +// SetVROM_2K_Bank( 6, reg[1] ); +// } +} + +void Mapper033::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 7; i++ ) { + p[i] = reg[i]; + } + + p[7] = irq_enable; + p[8] = irq_counter; +} + +void Mapper033::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 7; i++ ) { + reg[i] = p[i]; + } + + irq_enable = p[7]; + irq_counter = p[8]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper033.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper033.h new file mode 100644 index 00000000..d2b443e7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper033.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper033 Taito TC0190 // +////////////////////////////////////////////////////////////////////////// +class Mapper033 : public Mapper +{ +public: + Mapper033( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[7]; + + BYTE patch; + BYTE irq_enable; + BYTE irq_counter; + +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper034.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper034.cpp new file mode 100644 index 00000000..ac499362 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper034.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper034 Nina-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper034::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper034::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x7FFD: + SetPROM_32K_Bank( data ); + break; + case 0x7FFE: + SetVROM_4K_Bank( 0, data ); + break; + case 0x7FFF: + SetVROM_4K_Bank( 4, data ); + break; + default: + Mapper::WriteLow(addr, data); + } +} + +void Mapper034::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( data ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper034.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper034.h new file mode 100644 index 00000000..c2619826 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper034.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper034 Nina-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper034 : public Mapper +{ +public: + Mapper034( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper040.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper040.cpp new file mode 100644 index 00000000..c3516561 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper040.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper040 SMB2J // +////////////////////////////////////////////////////////////////////////// +void Mapper040::Reset() +{ + irq_enable = 0; + irq_line = 0; + + SetPROM_8K_Bank( 3, 6 ); + SetPROM_32K_Bank( 4, 5, 0, 7 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper040::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE000 ) { + case 0x8000: + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xA000: + irq_enable = 0xFF; + irq_line = 37; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC000: + break; + case 0xE000: + SetPROM_8K_Bank( 6, data&0x07 ); + break; + } +} + +void Mapper040::HSync( INT scanline ) +{ + if( irq_enable ) { + if( --irq_line <= 0 ) { +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper040::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_line; +} + +void Mapper040::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_line = *(INT*)&p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper040.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper040.h new file mode 100644 index 00000000..b02198ec --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper040.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper040 SMB2J // +////////////////////////////////////////////////////////////////////////// +class Mapper040 : public Mapper +{ +public: + Mapper040( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + INT irq_line; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper041.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper041.cpp new file mode 100644 index 00000000..5df0e0d0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper041.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper041 Caltron 6-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper041::Reset() +{ + reg[0] = reg[1] = 0; + + SetPROM_32K_Bank( 0, 1, 2, 3 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper041::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x6000 && addr < 0x6800 ) { + SetPROM_32K_Bank( addr&0x07 ); + reg[0] = addr & 0x04; + reg[1] &= 0x03; + reg[1] |= (addr>>1)&0x0C; + SetVROM_8K_Bank( reg[1] ); + if( addr&0x20 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } +} + +void Mapper041::Write( WORD addr, BYTE data ) +{ + if( reg[0] ) { + reg[1] &= 0x0C; + reg[1] |= addr & 0x03; + SetVROM_8K_Bank( reg[1] ); + } +} + +void Mapper041::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; +} + +void Mapper041::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper041.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper041.h new file mode 100644 index 00000000..dab4bf2e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper041.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper041 Caltron 6-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper041 : public Mapper +{ +public: + Mapper041( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[2]; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper042.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper042.cpp new file mode 100644 index 00000000..5dc3d424 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper042.cpp @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper042 Mario Baby // +////////////////////////////////////////////////////////////////////////// +void Mapper042::Reset() +{ + irq_enable = 0; + irq_counter = 0; + + SetPROM_8K_Bank( 3, 0 ); + SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper042::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE003 ) { + case 0xE000: + SetPROM_8K_Bank( 3, data&0x0F ); + break; + + case 0xE001: + if( data&0x08 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0xE002: + if( data&0x02 ) { + irq_enable = 0xFF; + } else { + irq_enable = 0; + irq_counter = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper042::HSync( INT scanline ) +{ + nes->cpu->ClrIRQ( IRQ_MAPPER ); + if( irq_enable ) { + if( irq_counter < 215 ) { + irq_counter++; + } + if( irq_counter == 215 ) { + irq_enable = 0; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper042::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; +} + +void Mapper042::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper042.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper042.h new file mode 100644 index 00000000..5c9bd6db --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper042.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper042 Mario Baby // +////////////////////////////////////////////////////////////////////////// +class Mapper042 : public Mapper +{ +public: + Mapper042( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper043.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper043.cpp new file mode 100644 index 00000000..0ee0141f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper043.cpp @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper043 SMB2J // +////////////////////////////////////////////////////////////////////////// +void Mapper043::Reset() +{ + irq_enable = 0xFF; + irq_counter = 0; + + SetPROM_8K_Bank( 3, 2 ); + SetPROM_32K_Bank( 1, 0, 4, 9 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +BYTE Mapper043::ReadLow( WORD addr ) +{ + if( 0x5000 <= addr && addr < 0x6000 ) { + LPBYTE pPtr = nes->rom->GetPROM(); + return pPtr[0x2000*8+0x1000+(addr-0x5000)]; + } + + return (BYTE)(addr>>8); +} + +void Mapper043::ExWrite( WORD addr, BYTE data ) +{ + if( (addr&0xF0FF) == 0x4022 ) { + switch( data&0x07 ) { + case 0x00: + case 0x02: + case 0x03: + case 0x04: + SetPROM_8K_Bank( 6, 4 ); + break; + case 0x01: + SetPROM_8K_Bank( 6, 3 ); + break; + case 0x05: + SetPROM_8K_Bank( 6, 7 ); + break; + case 0x06: + SetPROM_8K_Bank( 6, 5 ); + break; + case 0x07: + SetPROM_8K_Bank( 6, 6 ); + break; + } + } +} + +void Mapper043::WriteLow( WORD addr, BYTE data ) +{ + if( (addr&0xF0FF) == 0x4022 ) { + ExWrite( addr, data ); + } +} + +void Mapper043::Write( WORD addr, BYTE data ) +{ + if( addr == 0x8122 ) { + if( data&0x03 ) { + irq_enable = 1; + } else { + irq_counter = 0; + irq_enable = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } +} + +void Mapper043::HSync( INT scanline ) +{ + nes->cpu->ClrIRQ( IRQ_MAPPER ); + if( irq_enable ) { + irq_counter += 341; + if( irq_counter >= 12288 ) { + irq_counter = 0; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper043::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_counter; +} + +void Mapper043::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = *(INT*)&p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper043.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper043.h new file mode 100644 index 00000000..d6219123 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper043.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper043 SMB2J // +////////////////////////////////////////////////////////////////////////// +class Mapper043 : public Mapper +{ +public: + Mapper043( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + INT irq_counter; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper044.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper044.cpp new file mode 100644 index 00000000..c1986d53 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper044.cpp @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper044 Super HiK 7-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper044::Reset() +{ + patch = 0; + + if( nes->rom->GetPROM_CRC() == 0x7eef434c ) { + patch = 1; + } + + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0; + } + + bank = 0; + prg0 = 0; + prg1 = 1; + + // set VROM banks + if( VROM_1K_SIZE ) { + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + } else { + chr01 = chr23 = chr4 = chr5 = chr6 = chr7 = 0; + } + + SetBank_CPU(); + SetBank_PPU(); + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; +} + +void Mapper044::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x6000 ) { + if( patch ) { + bank = (data & 0x06) >> 1; + } else { + bank = (data & 0x01) << 1; + } + SetBank_CPU(); + SetBank_PPU(); + } +} + +void Mapper044::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + bank = data & 0x07; + if( bank == 7 ) { + bank = 6; + } + SetBank_CPU(); + SetBank_PPU(); + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper044::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(--irq_counter) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper044::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_8K_Bank( 4, ((bank == 6)?0x1e:0x0e)|(bank<<4) ); + SetPROM_8K_Bank( 5, ((bank == 6)?0x1f&prg1:0x0f&prg1)|(bank<<4) ); + SetPROM_8K_Bank( 6, ((bank == 6)?0x1f&prg0:0x0f&prg0)|(bank<<4) ); + SetPROM_8K_Bank( 7, ((bank == 6)?0x1f:0x0f)|(bank<<4) ); + } else { + SetPROM_8K_Bank( 4, ((bank == 6)?0x1f&prg0:0x0f&prg0)|(bank<<4) ); + SetPROM_8K_Bank( 5, ((bank == 6)?0x1f&prg1:0x0f&prg1)|(bank<<4) ); + SetPROM_8K_Bank( 6, ((bank == 6)?0x1e:0x0e)|(bank<<4) ); + SetPROM_8K_Bank( 7, ((bank == 6)?0x1f:0x0f)|(bank<<4) ); + } +} + +void Mapper044::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_1K_Bank( 0, ((bank == 6)?0xff&chr4:0x7f&chr4)|(bank<<7) ); + SetVROM_1K_Bank( 1, ((bank == 6)?0xff&chr5:0x7f&chr5)|(bank<<7) ); + SetVROM_1K_Bank( 2, ((bank == 6)?0xff&chr6:0x7f&chr6)|(bank<<7) ); + SetVROM_1K_Bank( 3, ((bank == 6)?0xff&chr7:0x7f&chr7)|(bank<<7) ); + SetVROM_1K_Bank( 4, ((bank == 6)?0xff&chr01:0x7f&chr01)|(bank<<7) ); + SetVROM_1K_Bank( 5, ((bank == 6)?0xff&(chr01+1):0x7f&(chr01+1))|(bank<<7) ); + SetVROM_1K_Bank( 6, ((bank == 6)?0xff&chr23:0x7f&chr23)|(bank<<7) ); + SetVROM_1K_Bank( 7, ((bank == 6)?0xff&(chr23+1):0x7f&(chr23+1))|(bank<<7) ); + } else { + SetVROM_1K_Bank( 0, ((bank == 6)?0xff&chr01:0x7f&chr01)|(bank<<7) ); + SetVROM_1K_Bank( 1, ((bank == 6)?0xff&(chr01+1):0x7f&(chr01+1))|(bank<<7) ); + SetVROM_1K_Bank( 2, ((bank == 6)?0xff&chr23:0x7f&chr23)|(bank<<7) ); + SetVROM_1K_Bank( 3, ((bank == 6)?0xff&(chr23+1):0x7f&(chr23+1))|(bank<<7) ); + SetVROM_1K_Bank( 4, ((bank == 6)?0xff&chr4:0x7f&chr4)|(bank<<7) ); + SetVROM_1K_Bank( 5, ((bank == 6)?0xff&chr5:0x7f&chr5)|(bank<<7) ); + SetVROM_1K_Bank( 6, ((bank == 6)?0xff&chr6:0x7f&chr6)|(bank<<7) ); + SetVROM_1K_Bank( 7, ((bank == 6)?0xff&chr7:0x7f&chr7)|(bank<<7) ); + } + } +} + +void Mapper044::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = bank; +} + +void Mapper044::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + bank = p[19]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper044.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper044.h new file mode 100644 index 00000000..04abc2af --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper044.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper044 Super HiK 7-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper044 : public Mapper +{ +public: + Mapper044( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE patch; + BYTE bank; + BYTE prg0, prg1; + BYTE chr01,chr23,chr4,chr5,chr6,chr7; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; +private: + void SetBank_CPU(); + void SetBank_PPU(); + +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper045.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper045.cpp new file mode 100644 index 00000000..e98c1564 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper045.cpp @@ -0,0 +1,323 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper045 1000000-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper045::Reset() +{ + patch = 0; + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0; + } + + prg0 = 0; + prg1 = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x58bcacf6 // Kunio 8-in-1 (Pirate Cart) + || crc == 0x9103cfd6 // HIK 7-in-1 (Pirate Cart) + || crc == 0xc082e6d3 ) { // Super 8-in-1 (Pirate Cart) + patch = 1; + prg2 = 62; + prg3 = 63; + } + if( crc == 0xe0dd259d ) { // Super 3-in-1 (Pirate Cart) + patch = 2; + } +// if( crc == 0x155ffb0d ) { // Super 3-in-1 (Unl) +// patch = 3; +// prg2 = 46; +// prg3 = 47; +// } + SetPROM_32K_Bank( prg0, prg1, prg2, prg3 ); + p[0] = prg0; + p[1] = prg1; + p[2] = prg2; + p[3] = prg3; + + SetVROM_8K_Bank( 0 ); + +// chr0 = c[0] = 0; +// chr1 = c[1] = 0 +// chr2 = c[2] = 0; +// chr3 = c[3] = 0; +// chr4 = c[4] = 0; +// chr5 = c[5] = 0; +// chr6 = c[6] = 0; +// chr7 = c[7] = 0; + + chr0 = c[0] = 0; + chr1 = c[1] = 1; + chr2 = c[2] = 2; + chr3 = c[3] = 3; + chr4 = c[4] = 4; + chr5 = c[5] = 5; + chr6 = c[6] = 6; + chr7 = c[7] = 7; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_latched = 0; + irq_reset = 0; +} + +void Mapper045::WriteLow( WORD addr, BYTE data ) +{ +// if( addr == 0x6000 ) { +// if( addr == 0x6000 && !(reg[3]&0x40) ) { + if( !(reg[3]&0x40) ) { + reg[reg[5]] = data; + reg[5] = (reg[5]+1) & 0x03; + + SetBank_CPU_4( prg0 ); + SetBank_CPU_5( prg1 ); + SetBank_CPU_6( prg2 ); + SetBank_CPU_7( prg3 ); + SetBank_PPU(); + } +} + +void Mapper045::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + if( (data&0x40)!=(reg[6]&0x40) ) { + BYTE swp; + swp = prg0; prg0 = prg2; prg2 = swp; + swp = p[0]; p[0] = p[2]; p[2] = swp; + SetBank_CPU_4( p[0] ); + SetBank_CPU_5( p[1] ); + } + if( VROM_1K_SIZE ) { + if( (data&0x80)!=(reg[6]&0x80) ) { + INT swp; + swp = chr4; chr4 = chr0; chr0 = swp; + swp = chr5; chr5 = chr1; chr1 = swp; + swp = chr6; chr6 = chr2; chr2 = swp; + swp = chr7; chr7 = chr3; chr3 = swp; + swp = c[4]; c[4] = c[0]; c[0] = swp; + swp = c[5]; c[5] = c[1]; c[1] = swp; + swp = c[6]; c[6] = c[2]; c[2] = swp; + swp = c[7]; c[7] = c[3]; c[3] = swp; + SetVROM_8K_Bank( c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7] ); + } + } + reg[6] = data; + break; + case 0x8001: + switch( reg[6] & 0x07 ) { + case 0x00: + chr0 = (data & 0xFE)+0; + chr1 = (data & 0xFE)+1; + SetBank_PPU(); + break; + case 0x01: + chr2 = (data & 0xFE)+0; + chr3 = (data & 0xFE)+1; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + if( reg[6] & 0x40 ) { + prg2 = data & 0x3F; + SetBank_CPU_6( data ); + } else { + prg0 = data & 0x3F; + SetBank_CPU_4( data ); + } + break; + case 0x07: + prg1 = data & 0x3F; + SetBank_CPU_5( data ); + break; + } + break; + case 0xA000: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0xC000: + if( patch == 2 ) { + if( data == 0x29 || data == 0x70 ) + data = 0x07; + } + irq_latch = data; + irq_latched = 1; + if( irq_reset ) { + irq_counter = data; + irq_latched = 0; + } +// irq_counter = data; + break; + case 0xC001: +// irq_latch = data; + irq_counter = irq_latch; + break; + case 0xE000: + irq_enable = 0; + irq_reset = 1; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + irq_enable = 1; + if( irq_latched ) { + irq_counter = irq_latch; + } + break; + } +} + +void Mapper045::HSync( INT scanline ) +{ + irq_reset = 0; + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( irq_counter ) { + irq_counter--; + if( irq_counter == 0 ) { + if( irq_enable ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper045::SetBank_CPU_4( INT data ) +{ + data &= (reg[3] & 0x3F) ^ 0xFF; + data &= 0x3F; + data |= reg[1]; + SetPROM_8K_Bank( 4, data ); + p[0] = data; +} + +void Mapper045::SetBank_CPU_5( INT data ) +{ + data &= (reg[3] & 0x3F) ^ 0xFF; + data &= 0x3F; + data |= reg[1]; + SetPROM_8K_Bank( 5, data ); + p[1] = data; +} + +void Mapper045::SetBank_CPU_6( INT data ) +{ + data &= (reg[3] & 0x3F) ^ 0xFF; + data &= 0x3F; + data |= reg[1]; + SetPROM_8K_Bank( 6, data ); + p[2] = data; +} + +void Mapper045::SetBank_CPU_7( INT data ) +{ + data &= (reg[3] & 0x3F) ^ 0xFF; + data &= 0x3F; + data |= reg[1]; + SetPROM_8K_Bank( 7, data ); + p[3] = data; +} + +void Mapper045::SetBank_PPU() +{ + BYTE table[16] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF + }; + + c[0] = chr0; + c[1] = chr1; + c[2] = chr2; + c[3] = chr3; + c[4] = chr4; + c[5] = chr5; + c[6] = chr6; + c[7] = chr7; + + for( INT i = 0; i < 8; i++ ) { + c[i] &= table[reg[2] & 0x0F]; + c[i] |= reg[0] & ((patch!=1)?0xFF:0xC0); + c[i] += (reg[2] & ((patch!=1)?0x10:0x30))<<4; + } + + if( reg[6] & 0x80 ) { + SetVROM_8K_Bank( c[4], c[5], c[6], c[7], c[0], c[1], c[2], c[3] ); + } else { + SetVROM_8K_Bank( c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7] ); + } +} + +void Mapper045::SaveState( LPBYTE ps ) +{ + INT i; + for( i = 0; i < 8; i++ ) { + ps[i] = reg[i]; + } + for( i = 0; i < 4; i++ ) { + ps[i+8] = p[i]; + } + for( i = 0; i < 8; i++ ) { + *(INT*)&ps[i*4+64] = c[i]; + } + ps[20] = prg0; + ps[21] = prg1; + ps[22] = prg2; + ps[23] = prg3; + ps[24] = chr0; + ps[25] = chr1; + ps[26] = chr2; + ps[27] = chr3; + ps[28] = chr4; + ps[29] = chr5; + ps[30] = chr6; + ps[31] = chr7; + ps[32] = irq_enable; + ps[33] = irq_counter; + ps[34] = irq_latch; +} + +void Mapper045::LoadState( LPBYTE ps ) +{ + INT i; + for( i = 0; i < 8; i++ ) { + reg[i] = ps[i]; + } + for( i = 0; i < 4; i++ ) { + p[i] = ps[i+8]; + } + for( i = 0; i < 8; i++ ) { + c[i] = *(INT*)&ps[i*4+64]; + } + prg0 = ps[20]; + prg1 = ps[21]; + prg2 = ps[22]; + prg3 = ps[23]; + chr0 = ps[24]; + chr1 = ps[25]; + chr2 = ps[26]; + chr3 = ps[27]; + chr4 = ps[28]; + chr5 = ps[29]; + chr6 = ps[30]; + chr7 = ps[31]; + irq_enable = ps[32]; + irq_counter = ps[33]; + irq_latch = ps[34]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper045.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper045.h new file mode 100644 index 00000000..388207e8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper045.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper045 1000000-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper045 : public Mapper +{ +public: + Mapper045( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE patch; + BYTE prg0, prg1, prg2, prg3; + BYTE chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7; + BYTE p[4]; + INT c[8]; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_latched; + BYTE irq_reset; +private: + void SetBank_CPU_4( INT data ); + void SetBank_CPU_5( INT data ); + void SetBank_CPU_6( INT data ); + void SetBank_CPU_7( INT data ); + void SetBank_PPU(); + +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper046.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper046.cpp new file mode 100644 index 00000000..929d264b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper046.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper046 Rumble Station // +////////////////////////////////////////////////////////////////////////// +void Mapper046::Reset() +{ + reg[0] = 0; + reg[1] = 0; + reg[2] = 0; + reg[3] = 0; + + SetBank(); + SetVRAM_Mirror( VRAM_VMIRROR ); +} + +void Mapper046::WriteLow( WORD addr, BYTE data ) +{ + reg[0] = data & 0x0F; + reg[1] = (data & 0xF0)>>4; + SetBank(); +} + +void Mapper046::Write( WORD addr, BYTE data ) +{ + reg[2] = data & 0x01; + reg[3] = (data & 0x70)>>4; + SetBank(); +} + +void Mapper046::SetBank() +{ + SetPROM_8K_Bank( 4, reg[0]*8+reg[2]*4+0 ); + SetPROM_8K_Bank( 5, reg[0]*8+reg[2]*4+1 ); + SetPROM_8K_Bank( 6, reg[0]*8+reg[2]*4+2 ); + SetPROM_8K_Bank( 7, reg[0]*8+reg[2]*4+3 ); + + SetVROM_1K_Bank( 0, reg[1]*64+reg[3]*8+0 ); + SetVROM_1K_Bank( 1, reg[1]*64+reg[3]*8+1 ); + SetVROM_1K_Bank( 2, reg[1]*64+reg[3]*8+2 ); + SetVROM_1K_Bank( 3, reg[1]*64+reg[3]*8+3 ); + SetVROM_1K_Bank( 4, reg[1]*64+reg[3]*8+4 ); + SetVROM_1K_Bank( 5, reg[1]*64+reg[3]*8+5 ); + SetVROM_1K_Bank( 6, reg[1]*64+reg[3]*8+6 ); + SetVROM_1K_Bank( 7, reg[1]*64+reg[3]*8+7 ); +} + +void Mapper046::SaveState( LPBYTE p ) +{ + p[ 0] = reg[0]; + p[ 1] = reg[1]; + p[ 2] = reg[2]; + p[ 3] = reg[3]; +} + +void Mapper046::LoadState( LPBYTE p ) +{ + reg[0] = p[ 0]; + reg[1] = p[ 1]; + reg[2] = p[ 2]; + reg[3] = p[ 3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper046.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper046.h new file mode 100644 index 00000000..6576e60d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper046.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper046 Rumble Station // +////////////////////////////////////////////////////////////////////////// +class Mapper046 : public Mapper +{ +public: + Mapper046( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + int reg[4]; + +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper047.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper047.cpp new file mode 100644 index 00000000..7fdb043d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper047.cpp @@ -0,0 +1,243 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper047 // +////////////////////////////////////////////////////////////////////////// +void Mapper047::Reset() +{ + patch = 0; + + if( nes->rom->GetPROM_CRC() == 0x7eef434c ) { + patch = 1; + } + + if( nes->rom->GetPROM_CRC() == 0x436f9e3f ) { // Super 2in1 + patch = 2; + } + + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0; + } + + bank = 0; + prg0 = 0; + prg1 = 1; + + // set VROM banks + if( VROM_1K_SIZE ) { + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + } else { + chr01 = chr23 = chr4 = chr5 = chr6 = chr7 = 0; + } + + SetBank_CPU(); + SetBank_PPU(); + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; +} + +void Mapper047::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x6000 ) { + if( patch == 1 ) { + bank = (data & 0x06) >> 1; + SetBank_CPU(); + SetBank_PPU(); + } else if( patch == 2 ) { + switch( data ) { + case 0x60: + SetPROM_32K_Bank( 0 ); + break; + case 0x64: + SetPROM_32K_Bank( 2 ); + break; + case 0x80: + bank = 2; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0xC0: + bank = 0; + SetBank_CPU(); + SetBank_PPU(); + break; + } + } else { + bank = (data & 0x01) << 1; + SetBank_CPU(); + SetBank_PPU(); + } + } +} + +void Mapper047::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + break; + } +} + +void Mapper047::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(--irq_counter) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper047::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_8K_Bank( 4, bank * 8 + (((patch == 1) && (bank != 2))?6:14) ); + SetPROM_8K_Bank( 5, bank * 8 + prg1 ); + SetPROM_8K_Bank( 6, bank * 8 + prg0 ); + SetPROM_8K_Bank( 7, bank * 8 + (((patch == 1) && (bank != 2))?7:15) ); + } else { + SetPROM_8K_Bank( 4, bank * 8 + prg0 ); + SetPROM_8K_Bank( 5, bank * 8 + prg1 ); + SetPROM_8K_Bank( 6, bank * 8 + (((patch == 1) && (bank != 2))?6:14) ); + SetPROM_8K_Bank( 7, bank * 8 + (((patch == 1) && (bank != 2))?7:15) ); + } +} + +void Mapper047::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_1K_Bank( 0, (bank & 0x02) * ((patch != 2)?64:128) + chr4 ); + SetVROM_1K_Bank( 1, (bank & 0x02) * ((patch != 2)?64:128) + chr5 ); + SetVROM_1K_Bank( 2, (bank & 0x02) * ((patch != 2)?64:128) + chr6 ); + SetVROM_1K_Bank( 3, (bank & 0x02) * ((patch != 2)?64:128) + chr7 ); + SetVROM_1K_Bank( 4, (bank & 0x02) * ((patch != 2)?64:128) + chr01 + 0 ); + SetVROM_1K_Bank( 5, (bank & 0x02) * ((patch != 2)?64:128) + chr01 + 1 ); + SetVROM_1K_Bank( 6, (bank & 0x02) * ((patch != 2)?64:128) + chr23 + 0 ); + SetVROM_1K_Bank( 7, (bank & 0x02) * ((patch != 2)?64:128) + chr23 + 1 ); + } else { + SetVROM_1K_Bank( 0, (bank & 0x02) * ((patch != 2)?64:128) + chr01 + 0 ); + SetVROM_1K_Bank( 1, (bank & 0x02) * ((patch != 2)?64:128) + chr01 + 1 ); + SetVROM_1K_Bank( 2, (bank & 0x02) * ((patch != 2)?64:128) + chr23 + 0 ); + SetVROM_1K_Bank( 3, (bank & 0x02) * ((patch != 2)?64:128) + chr23 + 1 ); + SetVROM_1K_Bank( 4, (bank & 0x02) * ((patch != 2)?64:128) + chr4 ); + SetVROM_1K_Bank( 5, (bank & 0x02) * ((patch != 2)?64:128) + chr5 ); + SetVROM_1K_Bank( 6, (bank & 0x02) * ((patch != 2)?64:128) + chr6 ); + SetVROM_1K_Bank( 7, (bank & 0x02) * ((patch != 2)?64:128) + chr7 ); + } + } +} + +void Mapper047::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = bank; +} + +void Mapper047::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + bank = p[19]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper047.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper047.h new file mode 100644 index 00000000..35452281 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper047.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper047 NES-QJ // +////////////////////////////////////////////////////////////////////////// +class Mapper047 : public Mapper +{ +public: + Mapper047( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE patch; + BYTE bank; + BYTE prg0, prg1; + BYTE chr01,chr23,chr4,chr5,chr6,chr7; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; +private: + void SetBank_CPU(); + void SetBank_PPU(); + +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper048.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper048.cpp new file mode 100644 index 00000000..af2343dd --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper048.cpp @@ -0,0 +1,106 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper048 Taito TC190V // +////////////////////////////////////////////////////////////////////////// +void Mapper048::Reset() +{ + reg = 0; + irq_enable = 0; + irq_counter = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + DWORD crc = nes->rom->GetPROM_CRC(); +// if( crc == 0x547e6cc1 ) { // Flintstones - The Rescue of Dino & Hoppy(J) +// nes->SetRenderMethod( NES::POST_RENDER ); +// } +} + +void Mapper048::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + if( !reg ) { + if( data & 0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + SetPROM_8K_Bank( 4, data ); + break; + case 0x8001: + SetPROM_8K_Bank( 5, data ); + break; + + case 0x8002: + SetVROM_2K_Bank( 0, data ); + break; + case 0x8003: + SetVROM_2K_Bank( 2, data ); + break; + case 0xA000: + SetVROM_1K_Bank( 4, data ); + break; + case 0xA001: + SetVROM_1K_Bank( 5, data ); + break; + case 0xA002: + SetVROM_1K_Bank( 6, data ); + break; + case 0xA003: + SetVROM_1K_Bank( 7, data ); + break; + + case 0xC000: + irq_counter = data; + irq_enable = 0; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xC001: + irq_counter = data; + irq_enable = 1; +// irq_enable = data & 0x01; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xC002: + break; + case 0xC003: + break; + + case 0xE000: + if( data & 0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + reg = 1; + break; + } +} + +void Mapper048::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( irq_counter == 0xFF ) { +// nes->cpu->IRQ_NotPending(); +// nes->cpu->SetIRQ( IRQ_MAPPER ); + nes->cpu->SetIRQ( IRQ_TRIGGER2 ); + } + irq_counter++; + } + } + } +} + +void Mapper048::SaveState( LPBYTE p ) +{ + p[0] = reg; + p[1] = irq_enable; + p[2] = irq_counter; +} + +void Mapper048::LoadState( LPBYTE p ) +{ + reg = p[0]; + irq_enable = p[1]; + irq_counter = p[2]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper048.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper048.h new file mode 100644 index 00000000..82860ab1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper048.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper048 Taito TC190V // +////////////////////////////////////////////////////////////////////////// +class Mapper048 : public Mapper +{ +public: + Mapper048( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void HSync(INT scanline); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; + BYTE irq_enable; + BYTE irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.cpp new file mode 100644 index 00000000..a7ba1442 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.cpp @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper120 Tobidase Daisakusen // +////////////////////////////////////////////////////////////////////////// +#include "BoardMMC3.h" + +void Mapper049::Reset() +{ +// nes->ppu->SetVromWrite(1); + MMC3_RegReset(); + temp = 0; +// nes->ppu->SetExtLatchMode( TRUE ); +} + +void Mapper049::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if ((addr&0x4100)==0x4100) { + temp=data; +// temp &= 0x03; +// if ( temp == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); +// else if ( temp == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); +// else if ( temp == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); +// else SetVRAM_Mirror( VRAM_MIRROR4H ); + FixCHR(MMC3_cmd); + } +} + +void Mapper049::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + MMC3CMDWrite(addr, data); + MMC3_IRQWrite(addr, data); + + if((addr&0xE001)==0xE000) nes->cpu->ClrIRQ(IRQ_MAPPER); +} + +void Mapper049::MMC3CMDWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0x8000: + if ((V & 0x40) != (MMC3_cmd & 0x40)) + FixMMC3PRG(V); + if ((V & 0x80) != (MMC3_cmd & 0x80)) + FixCHR(V); + MMC3_cmd = V; + break; + case 0x8001: + { + int cbase = (MMC3_cmd & 0x80) << 5; + MMC3_DRegBuf[MMC3_cmd & 0x7] = V; + switch (MMC3_cmd & 0x07) { + case 0: + wrapc((cbase ^ 0x000), V & (~1)); + wrapc((cbase ^ 0x400), V | 1); + break; + case 1: + wrapc((cbase ^ 0x800), V & (~1)); + wrapc((cbase ^ 0xC00), V | 1); + break; + case 2: + wrapc(cbase ^ 0x1000, V); + break; + case 3: + wrapc(cbase ^ 0x1400, V); + break; + case 4: + wrapc(cbase ^ 0x1800, V); + break; + case 5: + wrapc(cbase ^ 0x1C00, V); + break; + case 6: + if (MMC3_cmd&0x40) pwrap(0xC000, V); + else pwrap(0x8000, V); + break; + case 7: + pwrap(0xA000, V); + break; + } + break; + } + case 0xA000: + MMC3_A000B = V; + mwrap(MMC3_A000B); + break; + case 0xA001: + MMC3_A001B = V; + break; + } +} + +void Mapper049::wrapc(WORD A, BYTE V) +{ + if(temp&2) + SetCRAM_8K_Bank(0); + else + SetVROM_1K_Bank(A>>10,V); +} + +void Mapper049::FixCHR(BYTE V) +{ + int cbase = (V & 0x80) << 5; + wrapc((cbase ^ 0x000), MMC3_DRegBuf[0] & (~1)); + wrapc((cbase ^ 0x400), MMC3_DRegBuf[0] | 1); + wrapc((cbase ^ 0x800), MMC3_DRegBuf[1] & (~1)); + wrapc((cbase ^ 0xC00), MMC3_DRegBuf[1] | 1); + wrapc(cbase ^ 0x1000, MMC3_DRegBuf[2]); + wrapc(cbase ^ 0x1400, MMC3_DRegBuf[3]); + wrapc(cbase ^ 0x1800, MMC3_DRegBuf[4]); + wrapc(cbase ^ 0x1c00, MMC3_DRegBuf[5]); + + mwrap(MMC3_A000B); +} + +void Mapper049::HSync( INT scanline ) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (MMC3_IRQa && !MMC3_IRQReload) { + if (scanline == 0) { + if (MMC3_IRQCount) { + MMC3_IRQCount -= 1; + } + } + if (!(MMC3_IRQCount)){ + MMC3_IRQReload = 0xFF; + MMC3_IRQCount = MMC3_IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + MMC3_IRQCount--; + } + } + } +} + +void Mapper049::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr, ntb; + + ntb = (ntbladr>>10)&3; + + if(ntb==2) + tileofs |= 0x1000; + else if(ntb && temp) + tileofs |= 0x1000; + else + tileofs |= 0x0000; + + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; +} + +void Mapper049::PPU_Latch( WORD addr ) +{ + if(DirectInput.m_Sw[DIK_PAUSE]){ + nes->Dump_CRAM(); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.h new file mode 100644 index 00000000..d03af441 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper120 Tobidase Daisakusen // +////////////////////////////////////////////////////////////////////////// +class Mapper049 : public Mapper +{ +public: + Mapper049( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + void PPU_Latch( WORD addr ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + +protected: + BYTE temp; + INT temp1; +private: + void MMC3CMDWrite(WORD A, BYTE V); + void wrapc(WORD A, BYTE V); + void FixCHR(BYTE V); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper050.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper050.cpp new file mode 100644 index 00000000..3fd5e2ff --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper050.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper050 SMB2J // +////////////////////////////////////////////////////////////////////////// +void Mapper050::Reset() +{ + irq_enable = 0; + SetPROM_8K_Bank( 3, 15 ); + SetPROM_8K_Bank( 4, 8 ); + SetPROM_8K_Bank( 5, 9 ); + SetPROM_8K_Bank( 6, 0 ); + SetPROM_8K_Bank( 7, 11 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper050::ExWrite( WORD addr, BYTE data ) +{ + if( (addr & 0xE060) == 0x4020 ) { + if( addr & 0x0100 ) { + irq_enable = data & 0x01; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } else { + SetPROM_8K_Bank( 6, (data&0x08)|((data&0x01)<<2)|((data&0x06)>>1) ); + } + } +} + +void Mapper050::WriteLow( WORD addr, BYTE data ) +{ + if( (addr & 0xE060) == 0x4020 ) { + if( addr & 0x0100 ) { + irq_enable = data & 0x01; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } else { + SetPROM_8K_Bank( 6, (data&0x08)|((data&0x01)<<2)|((data&0x06)>>1) ); + } + } +} + +void Mapper050::HSync( INT scanline ) +{ + if( irq_enable ) { + if( scanline == 21 ) { +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper050::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; +} + +void Mapper050::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper050.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper050.h new file mode 100644 index 00000000..e65cfbf6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper050.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper050 SMB2J // +////////////////////////////////////////////////////////////////////////// +class Mapper050 : public Mapper +{ +public: + Mapper050( NES* parent ) : Mapper(parent) {} + + void Reset(); + void ExWrite( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper051.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper051.cpp new file mode 100644 index 00000000..0b342683 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper051.cpp @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper051 11-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper051::Reset() +{ + bank = 0; + mode = 1; + + SetBank_CPU(); + + SetCRAM_8K_Bank( 0 ); +} + +void Mapper051::WriteLow( WORD addr, BYTE data ) +{ + if( addr>=0x6000 ) { + mode = ((data & 0x10) >> 3) | ((data & 0x02) >> 1); + SetBank_CPU(); + } +} + +void Mapper051::Write( WORD addr, BYTE data ) +{ + bank = (data & 0x0f) << 2; + if( 0xC000 <= addr && addr <= 0xDFFF ) { + mode = (mode & 0x01) | ((data & 0x10) >> 3); + } + SetBank_CPU(); +} + +void Mapper051::SetBank_CPU() +{ + switch(mode) { + case 0: + SetVRAM_Mirror( VRAM_VMIRROR ); + SetPROM_8K_Bank( 3, (bank|0x2c|3) ); + SetPROM_8K_Bank( 4, (bank|0x00|0) ); + SetPROM_8K_Bank( 5, (bank|0x00|1) ); + SetPROM_8K_Bank( 6, (bank|0x0c|2) ); + SetPROM_8K_Bank( 7, (bank|0x0c|3) ); + break; + case 1: + SetVRAM_Mirror( VRAM_VMIRROR ); + SetPROM_8K_Bank( 3, (bank|0x20|3) ); + SetPROM_8K_Bank( 4, (bank|0x00|0) ); + SetPROM_8K_Bank( 5, (bank|0x00|1) ); + SetPROM_8K_Bank( 6, (bank|0x00|2) ); + SetPROM_8K_Bank( 7, (bank|0x00|3) ); + break; + case 2: + SetVRAM_Mirror( VRAM_VMIRROR ); + SetPROM_8K_Bank( 3, (bank|0x2e|3) ); + SetPROM_8K_Bank( 4, (bank|0x02|0) ); + SetPROM_8K_Bank( 5, (bank|0x02|1) ); + SetPROM_8K_Bank( 6, (bank|0x0e|2) ); + SetPROM_8K_Bank( 7, (bank|0x0e|3) ); + break; + case 3: + SetVRAM_Mirror( VRAM_HMIRROR ); + SetPROM_8K_Bank( 3, (bank|0x20|3) ); + SetPROM_8K_Bank( 4, (bank|0x00|0) ); + SetPROM_8K_Bank( 5, (bank|0x00|1) ); + SetPROM_8K_Bank( 6, (bank|0x00|2) ); + SetPROM_8K_Bank( 7, (bank|0x00|3) ); + break; + } +} + +void Mapper051::SaveState( LPBYTE p ) +{ + p[ 0] = mode; + p[ 1] = bank; +} + +void Mapper051::LoadState( LPBYTE p ) +{ + mode = p[ 0]; + bank = p[ 1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper051.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper051.h new file mode 100644 index 00000000..c236244e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper051.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper051 11-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper051 : public Mapper +{ +public: + Mapper051( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + int mode, bank; + +private: + void SetBank_CPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper052.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper052.cpp new file mode 100644 index 00000000..50c4ba37 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper052.cpp @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper052 Konami VRC2 type B // +////////////////////////////////////////////////////////////////////////// +void Mapper052::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); +// nes->SetRenderMethod( NES::POST_RENDER ); +// nes->SetRenderMethod( NES::POST_ALL_RENDER ); + +} + +void Mapper052::Write( WORD addr, BYTE data ) +{ + if(addr>=0xf000) DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if(addr>=0xf000) DEBUGOUT( "MPRWR A=%04X RAM=%02X L=%3d CYC=%d\n", addr&0xFFFF, RAM[0x1c0]&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr & 0xFFFF ) { + case 0x8000: + if(reg[8]) SetPROM_8K_Bank( 6, data ); + else SetPROM_8K_Bank( 4, data ); + break; + case 0x9002: + reg[8] = data & 0x02; + break; + + case 0x9004: + data &= 0x03; + if(data==0) SetVRAM_Mirror( VRAM_VMIRROR ); + else if(data==1) SetVRAM_Mirror( VRAM_HMIRROR ); + else if(data==2) SetVRAM_Mirror( VRAM_MIRROR4L); + else SetVRAM_Mirror( VRAM_MIRROR4H); + break; + + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB001: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB002: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB003: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC001: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC002: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC003: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD001: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD002: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD003: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE001: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE002: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE003: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + break; + case 0xF004: + case 0xFF04: + RAM[0x7f8] = 1; + break; + case 0xF008: + case 0xFF08: + irq_enable = 1; +// irq_latch = ((RAM[0x7f8]*2)+0x11)^0xFF; //Akumajou Special - Boku Dracula-kun + irq_latch = ((RAM[0x1c0]*2)+0x11)^0xFF; //Teenage Mutant Ninja Turtles + irq_counter = irq_latch; + irq_clock = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF00C: + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper052::HSync( INT scanline ) +{ + // +} + +void Mapper052::Clock( INT cycles ) +{ + if( irq_enable ) { + irq_clock += cycles*3; + while( irq_clock >= 341 ) { + irq_clock -= 341; + irq_counter++; + if( irq_counter == 0 ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +} + +void Mapper052::SaveState( LPBYTE p ) +{ + // +} +void Mapper052::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper052.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper052.h new file mode 100644 index 00000000..50f7b6bd --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper052.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper052 Konami VRC2 type B // +////////////////////////////////////////////////////////////////////////// +class Mapper052 : public Mapper +{ +public: + Mapper052( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + + BYTE reg[9]; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper057.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper057.cpp new file mode 100644 index 00000000..adb1d000 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper057.cpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper057 // +////////////////////////////////////////////////////////////////////////// +void Mapper057::Reset() +{ + SetPROM_32K_Bank( 0, 1, 0, 1 ); + SetVROM_8K_Bank( 0 ); + + reg = 0; +} + +void Mapper057::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + case 0x8001: + case 0x8002: + case 0x8003: + if( data & 0x40 ) { + SetVROM_8K_Bank( (data&0x03)+((reg&0x10)>>1)+(reg&0x07) ); + } + break; + case 0x8800: + reg = data; + + if( data & 0x80 ) { + SetPROM_8K_Bank( 4, ((data & 0x40)>>6)*4+8+0 ); + SetPROM_8K_Bank( 5, ((data & 0x40)>>6)*4+8+1 ); + SetPROM_8K_Bank( 6, ((data & 0x40)>>6)*4+8+2 ); + SetPROM_8K_Bank( 7, ((data & 0x40)>>6)*4+8+3 ); + } else { + SetPROM_8K_Bank( 4, ((data & 0x60)>>5)*2+0 ); + SetPROM_8K_Bank( 5, ((data & 0x60)>>5)*2+1 ); + SetPROM_8K_Bank( 6, ((data & 0x60)>>5)*2+0 ); + SetPROM_8K_Bank( 7, ((data & 0x60)>>5)*2+1 ); + } + + SetVROM_8K_Bank( (data&0x07)+((data&0x10)>>1) ); + + if( data & 0x08 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + + break; + } +} + +void Mapper057::SaveState( LPBYTE p ) +{ + p[0] = reg; +} + +void Mapper057::LoadState( LPBYTE p ) +{ + reg = p[0]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper057.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper057.h new file mode 100644 index 00000000..f8f5b1d0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper057.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper057 // +////////////////////////////////////////////////////////////////////////// +class Mapper057 : public Mapper +{ +public: + Mapper057( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper058.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper058.cpp new file mode 100644 index 00000000..09b6f775 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper058.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper058 // +////////////////////////////////////////////////////////////////////////// +void Mapper058::Reset() +{ + SetPROM_32K_Bank( 0, 1, 0, 1 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper058::Write( WORD addr, BYTE data ) +{ + if( addr & 0x40 ) { + SetPROM_16K_Bank( 4, addr&0x07 ); + SetPROM_16K_Bank( 6, addr&0x07 ); + } else { + SetPROM_32K_Bank( (addr&0x06)>>1 ); + } + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( (addr&0x38)>>3 ); + } + + if( data & 0x02 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_HMIRROR ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper058.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper058.h new file mode 100644 index 00000000..89beb41e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper058.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper058 // +////////////////////////////////////////////////////////////////////////// +class Mapper058 : public Mapper +{ +public: + Mapper058( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper060.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper060.cpp new file mode 100644 index 00000000..14942cef --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper060.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper060 // +////////////////////////////////////////////////////////////////////////// +void Mapper060::Reset() +{ + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0xf9c484a0 ) { // Reset Based 4-in-1(Unl) + SetPROM_16K_Bank( 4, game_sel ); + SetPROM_16K_Bank( 6, game_sel ); + SetVROM_8K_Bank( game_sel ); + game_sel++; + game_sel &= 3; + } else { + patch = 1; + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper060::Write( WORD addr, BYTE data ) +{ + if( patch ) { + if( addr & 0x80 ) { + SetPROM_16K_Bank( 4, (addr&0x70)>>4 ); + SetPROM_16K_Bank( 6, (addr&0x70)>>4 ); + } else { + SetPROM_32K_Bank( (addr&0x70)>>5 ); + } + + SetVROM_8K_Bank( addr&0x07 ); + + if( data & 0x08 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_HMIRROR ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper060.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper060.h new file mode 100644 index 00000000..669e8864 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper060.h @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper060 // +////////////////////////////////////////////////////////////////////////// +class Mapper060 : public Mapper +{ +public: + Mapper060( NES* parent ) : Mapper(parent), game_sel(0) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: + BYTE patch; + BYTE game_sel; + +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper061.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper061.cpp new file mode 100644 index 00000000..32585a8b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper061.cpp @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper061 // +////////////////////////////////////////////////////////////////////////// +void Mapper061::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper061::Write( WORD addr, BYTE data ) +{ + switch( addr & 0x30 ) { + case 0x00: + case 0x30: + SetPROM_32K_Bank( addr & 0x0F ); + break; + case 0x10: + case 0x20: + SetPROM_16K_Bank( 4, ((addr & 0x0F)<<1)|((addr&0x20)>>4) ); + SetPROM_16K_Bank( 6, ((addr & 0x0F)<<1)|((addr&0x20)>>4) ); + break; + } + + if( addr & 0x80 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper061.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper061.h new file mode 100644 index 00000000..791bb774 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper061.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper061 // +////////////////////////////////////////////////////////////////////////// +class Mapper061 : public Mapper +{ +public: + Mapper061( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper062.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper062.cpp new file mode 100644 index 00000000..e7ca50f4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper062.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper062 // +////////////////////////////////////////////////////////////////////////// +void Mapper062::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper062::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xFF00 ) { + case 0x8100: + SetPROM_8K_Bank( 4, data ); + SetPROM_8K_Bank( 5, data+1 ); + break; + case 0x8500: + SetPROM_8K_Bank( 4, data ); + break; + case 0x8700: + SetPROM_8K_Bank( 5, data ); + break; + SetVROM_1K_Bank( 0, data+0 ); + SetVROM_1K_Bank( 1, data+1 ); + SetVROM_1K_Bank( 2, data+2 ); + SetVROM_1K_Bank( 3, data+3 ); + SetVROM_1K_Bank( 4, data+4 ); + SetVROM_1K_Bank( 5, data+5 ); + SetVROM_1K_Bank( 6, data+6 ); + SetVROM_1K_Bank( 7, data+7 ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper062.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper062.h new file mode 100644 index 00000000..5e2a33f8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper062.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper062 // +////////////////////////////////////////////////////////////////////////// +class Mapper062 : public Mapper +{ +public: + Mapper062( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper064.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper064.cpp new file mode 100644 index 00000000..8eb25538 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper064.cpp @@ -0,0 +1,207 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper064 Tengen Rambo-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper064::Reset() +{ + SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + reg[0] = reg[1] = reg[2] = 0; + + irq_enable = 0; + irq_mode = 0; + irq_counter = 0; + irq_counter2 = 0; + irq_latch = 0; + irq_reset = 0; +} + +void Mapper064::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X:$%02X\n", addr, data ); + switch( addr&0xF003 ) { + case 0x8000: + reg[0] = data&0x0F; + reg[1] = data&0x40; + reg[2] = data&0x80; + break; + + case 0x8001: + switch( reg[0] ) { + case 0x00: + if( reg[2] ) { + SetVROM_1K_Bank( 4, data+0 ); + SetVROM_1K_Bank( 5, data+1 ); + } else { + SetVROM_1K_Bank( 0, data+0 ); + SetVROM_1K_Bank( 1, data+1 ); + } + break; + case 0x01: + if( reg[2] ) { + SetVROM_1K_Bank( 6, data+0 ); + SetVROM_1K_Bank( 7, data+1 ); + } else { + SetVROM_1K_Bank( 2, data+0 ); + SetVROM_1K_Bank( 3, data+1 ); + } + break; + case 0x02: + if( reg[2] ) { + SetVROM_1K_Bank( 0, data ); + } else { + SetVROM_1K_Bank( 4, data ); + } + break; + case 0x03: + if( reg[2] ) { + SetVROM_1K_Bank( 1, data ); + } else { + SetVROM_1K_Bank( 5, data ); + } + break; + case 0x04: + if( reg[2] ) { + SetVROM_1K_Bank( 2, data ); + } else { + SetVROM_1K_Bank( 6, data ); + } + break; + case 0x05: + if( reg[2] ) { + SetVROM_1K_Bank( 3, data ); + } else { + SetVROM_1K_Bank( 7, data ); + } + break; + case 0x06: + if( reg[1] ) { + SetPROM_8K_Bank( 5, data ); + } else { + SetPROM_8K_Bank( 4, data ); + } + break; + case 0x07: + if( reg[1] ) { + SetPROM_8K_Bank( 6, data ); + } else { + SetPROM_8K_Bank( 5, data ); + } + break; + case 0x08: + SetVROM_1K_Bank( 1, data ); + break; + case 0x09: + SetVROM_1K_Bank( 3, data ); + break; + case 0x0F: + if( reg[1] ) { + SetPROM_8K_Bank( 4, data ); + } else { + SetPROM_8K_Bank( 6, data ); + } + break; + } + break; + + case 0xA000: + if( data&0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0xC000: + irq_latch = data; + if( irq_reset ) { + irq_counter = irq_latch; + } + break; + case 0xC001: + irq_reset = 0xFF; + irq_counter = irq_latch; + irq_mode = data & 0x01; + break; + case 0xE000: + irq_enable = 0; + if( irq_reset ) { + irq_counter = irq_latch; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + irq_enable = 0xFF; + if( irq_reset ) { + irq_counter = irq_latch; + } + break; + } +} + +void Mapper064::Clock( INT cycles ) +{ + if( !irq_mode ) + return; + + irq_counter2 += cycles; + while( irq_counter2 >= 4 ) { + irq_counter2 -= 4; + if( irq_counter >= 0 ) { + irq_counter--; + if( irq_counter < 0 ) { + if( irq_enable ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper064::HSync( INT scanline ) +{ + if( irq_mode ) + return; + + irq_reset = 0; + + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_counter >= 0 ) { + irq_counter--; + if( irq_counter < 0 ) { + if( irq_enable ) { + irq_reset = 1; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } + } +} + +void Mapper064::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = irq_enable; + p[4] = irq_mode; + p[5] = irq_latch; + p[6] = irq_reset; + *((INT*)&p[ 8]) = irq_counter; + *((INT*)&p[12]) = irq_counter2; +} + +void Mapper064::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + irq_enable = p[3]; + irq_mode = p[4]; + irq_latch = p[5]; + irq_reset = p[6]; + irq_counter = *((INT*)&p[ 8]); + irq_counter2 = *((INT*)&p[12]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper064.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper064.h new file mode 100644 index 00000000..d0452cbb --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper064.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper064 Tengen Rambo-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper064 : public Mapper +{ +public: + Mapper064( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[3]; + BYTE irq_enable; + BYTE irq_mode; + INT irq_counter; + INT irq_counter2; + BYTE irq_latch; + BYTE irq_reset; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper065.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper065.cpp new file mode 100644 index 00000000..2576eada --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper065.cpp @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper065 Irem H3001 // +////////////////////////////////////////////////////////////////////////// +void Mapper065::Reset() +{ + patch = 0; + + // Kaiketsu Yanchamaru 3(J) & (C) + if( (nes->rom->GetPROM_CRC() == 0xe30b7f64) + || (nes->rom->GetPROM_CRC() == 0x5f17f55e) ) { + patch = 1; + } + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + irq_enable = 0; + irq_counter = 0; +} + +void Mapper065::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + + case 0x9000: + if( !patch ) { + if( data & 0x40 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_HMIRROR ); + } + break; + + case 0x9001: + if( patch ) { + if( data & 0x80 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + + case 0x9003: + if( !patch ) { + irq_enable = data & 0x80; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + break; + case 0x9004: + if( !patch ) { + irq_counter = irq_latch; + } + break; + case 0x9005: + if( patch ) { + irq_counter = (BYTE)(data<<1); + irq_enable = data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } else { + irq_latch = (irq_latch & 0x00FF)|((INT)data<<8); + } + break; + + case 0x9006: + if( patch ) { + irq_enable = 1; + } else { + irq_latch = (irq_latch & 0xFF00)|data; + } + break; + + case 0xB000: + case 0xB001: + case 0xB002: + case 0xB003: + case 0xB004: + case 0xB005: + case 0xB006: + case 0xB007: + SetVROM_1K_Bank( addr & 0x0007, data ); + break; + + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + case 0xC000: + SetPROM_8K_Bank( 6, data ); + break; + } +} + +void Mapper065::HSync( INT scanline ) +{ + if( patch ) { + if( irq_enable ) { + if( irq_counter == 0 ) { +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter--; + } + } + } +} + +void Mapper065::Clock( INT cycles ) +{ + if( !patch ) { + if( irq_enable ) { + if( irq_counter <= 0 ) { +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter -= cycles; + } + } + } +} + +void Mapper065::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_counter; + *(INT*)&p[5] = irq_latch; +} + +void Mapper065::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = *(INT*)&p[1]; + irq_latch = *(INT*)&p[5]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper065.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper065.h new file mode 100644 index 00000000..73432434 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper065.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper065 Irem H3001 // +////////////////////////////////////////////////////////////////////////// +class Mapper065 : public Mapper +{ +public: + Mapper065( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void HSync(INT scanline); + void Clock(INT cycles); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + + BYTE irq_enable; + INT irq_counter; + INT irq_latch; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper066.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper066.cpp new file mode 100644 index 00000000..7547b581 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper066.cpp @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper066 Bandai 74161 // +////////////////////////////////////////////////////////////////////////// +void Mapper066::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + +// if( nes->rom->GetPROM_CRC() == 0xe30552db ) { // Paris-Dakar Rally Special +// nes->SetFrameIRQmode( FALSE ); +// } +} + +void Mapper066::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x6000 ) { + SetPROM_32K_Bank( (data & 0xF0) >> 4 ); + SetVROM_8K_Bank( data & 0x0F ); + } +} + +void Mapper066::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( (data & 0xF0) >> 4 ); + SetVROM_8K_Bank( data & 0x0F ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper066.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper066.h new file mode 100644 index 00000000..bca847df --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper066.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper066 Bandai 74161 // +////////////////////////////////////////////////////////////////////////// +class Mapper066 : public Mapper +{ +public: + Mapper066( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper067.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper067.cpp new file mode 100644 index 00000000..70649b1b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper067.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper067 SunSoft Mapper 3 // +////////////////////////////////////////////////////////////////////////// +void Mapper067::Reset() +{ + irq_enable = 0; + irq_toggle = 0; + irq_counter = 0; + irq_occur = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + SetVROM_4K_Bank( 0, 0 ); + SetVROM_4K_Bank( 4, VROM_4K_SIZE-1 ); + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x7f2a04bf ) { // For Fantasy Zone 2(J) + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } +} + +void Mapper067::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF800 ) { + case 0x8800: + SetVROM_2K_Bank( 0, data ); + break; + case 0x9800: + SetVROM_2K_Bank( 2, data ); + break; + case 0xA800: + SetVROM_2K_Bank( 4, data ); + break; + case 0xB800: + SetVROM_2K_Bank( 6, data ); + break; + + case 0xC800: + if( !irq_toggle ) { + irq_counter = (irq_counter&0x00FF)|((INT)data<<8); + } else { + irq_counter = (irq_counter&0xFF00)|((INT)data&0xFF); + } + irq_toggle ^= 1; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xD800: + irq_enable = data & 0x10; + irq_toggle = 0; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xE800: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0xF800: + SetPROM_16K_Bank( 4, data ); + break; + } +} + +void Mapper067::Clock( INT cycles ) +{ + if( irq_enable ) { + if( (irq_counter -= cycles) <= 0 ) { + irq_enable = 0; + irq_occur = 0xFF; + irq_counter = 0xFFFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + +// if( irq_occur ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper067::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_occur; + p[2] = irq_toggle; + *((INT*)&p[3]) = irq_counter; +} + +void Mapper067::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_occur = p[1]; + irq_toggle = p[2]; + irq_counter = *((INT*)&p[3]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper067.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper067.h new file mode 100644 index 00000000..ad3260d2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper067.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper067 SunSoft Mapper 3 // +////////////////////////////////////////////////////////////////////////// +class Mapper067 : public Mapper +{ +public: + Mapper067( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void Clock(INT cycles); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_occur; + BYTE irq_toggle; + INT irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper068.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper068.cpp new file mode 100644 index 00000000..a511c0d7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper068.cpp @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper068 SunSoft (After Burner II) // +////////////////////////////////////////////////////////////////////////// +void Mapper068::Reset() +{ + reg[0] = reg[1] = reg[2] = reg[3] = 0; + coin = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +#if 0 +BYTE Mapper068::ExRead( WORD addr ) +{ + if( addr == 0x4020 ) { +DEBUGOUT( "RD $4020:%02X\n", coin ); + return coin; + } + + return addr>>8; +} + +void Mapper068::ExWrite( WORD addr, BYTE data ) +{ + if( addr == 0x4020 ) { +DEBUGOUT( "WR $4020:%02X\n", data ); + coin = data; + } +} +#endif + +void Mapper068::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF000 ) { + case 0x8000: + SetVROM_2K_Bank( 0, data ); + break; + case 0x9000: + SetVROM_2K_Bank( 2, data ); + break; + case 0xA000: + SetVROM_2K_Bank( 4, data ); + break; + case 0xB000: + SetVROM_2K_Bank( 6, data ); + break; + + case 0xC000: + reg[2] = data; + SetBank(); + break; + case 0xD000: + reg[3] = data; + SetBank(); + break; + case 0xE000: + reg[0] = (data & 0x10)>>4; + reg[1] = data & 0x03; + SetBank(); + break; + + case 0xF000: + SetPROM_16K_Bank( 4, data ); + break; + } +} + +void Mapper068::SetBank() +{ + if( reg[0] ) { + switch( reg[1] ) { + case 0: + SetVROM_1K_Bank( 8, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 9, (INT)reg[3]+0x80 ); + SetVROM_1K_Bank( 10, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 11, (INT)reg[3]+0x80 ); + break; + case 1: + SetVROM_1K_Bank( 8, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 9, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 10, (INT)reg[3]+0x80 ); + SetVROM_1K_Bank( 11, (INT)reg[3]+0x80 ); + break; + case 2: + SetVROM_1K_Bank( 8, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 9, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 10, (INT)reg[2]+0x80 ); + SetVROM_1K_Bank( 11, (INT)reg[2]+0x80 ); + break; + case 3: + SetVROM_1K_Bank( 8, (INT)reg[3]+0x80 ); + SetVROM_1K_Bank( 9, (INT)reg[3]+0x80 ); + SetVROM_1K_Bank( 10, (INT)reg[3]+0x80 ); + SetVROM_1K_Bank( 11, (INT)reg[3]+0x80 ); + break; + } + } else { + switch( reg[1] ) { + case 0: + SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 1: + SetVRAM_Mirror( VRAM_HMIRROR ); + break; + case 2: + SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + case 3: + SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + } + } +} + +void Mapper068::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = reg[3]; +} + +void Mapper068::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + reg[3] = p[3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper068.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper068.h new file mode 100644 index 00000000..e6b05852 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper068.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper068 SunSoft Mapper 4 (After Burner II) // +////////////////////////////////////////////////////////////////////////// +class Mapper068 : public Mapper +{ +public: + Mapper068( NES* parent ) : Mapper(parent) {} + + void Reset(); +// BYTE ExRead( WORD addr ); +// void ExWrite( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[4]; + BYTE coin; +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper069.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper069.cpp new file mode 100644 index 00000000..6d097123 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper069.cpp @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper069 SunSoft FME-7 // +////////////////////////////////////////////////////////////////////////// +void Mapper069::Reset() +{ + reg = 0; + irq_enable = 0; + irq_counter = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + nes->apu->SelectExSound(32); + nes->SetIrqType( NES::IRQ_CLOCK ); + + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0xfeac6916 ) { // Honoo no Toukyuuji - Dodge Danpei 2(J) +// nes->SetIrqType( NES::IRQ_HSYNC ); + nes->SetRenderMethod( NES::TILE_RENDER ); + } + + if( crc == 0xad28aef6 ) { // Dynamite Batman(J) / Dynamite Batman - Return of the Joker(U) + patch = 1; + } +} + +void Mapper069::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE000 ) { + case 0x8000: + reg = data; + break; + + case 0xA000: + switch( reg & 0x0F ) { + case 0x00: case 0x01: + case 0x02: case 0x03: + case 0x04: case 0x05: + case 0x06: case 0x07: + SetVROM_1K_Bank( reg&0x07, data ); + break; + case 0x08: +// DEBUGOUT( "Write8 - addr= %04x ; dat= %03x\n", addr, data ); + if( !patch && !(data & 0x40) ) { + SetPROM_8K_Bank( 3, data ); + } + break; + case 0x09: +// DEBUGOUT( "Write9 - addr= %04x ; dat= %03x\n", addr, data ); + SetPROM_8K_Bank( 4, data ); + break; + case 0x0A: +// DEBUGOUT( "WriteA - addr= %04x ; dat= %03x\n", addr, data ); + SetPROM_8K_Bank( 5, data ); + break; + case 0x0B: +// DEBUGOUT( "WriteB - addr= %04x ; dat= %03x\n", addr, data ); + SetPROM_8K_Bank( 6, data ); + break; + + case 0x0C: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x0D: + DEBUGOUT( "WriteD - addr= %04x ; dat= %03x\n", addr, data ); + irq_enable = data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0x0E: + DEBUGOUT( "WriteE - addr= %04x ; dat= %03x\n", addr, data ); + irq_counter = (irq_counter & 0xFF00) | data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0x0F: + DEBUGOUT( "WriteF - addr= %04x ; dat= %03x\n", addr, data ); + irq_counter = (irq_counter & 0x00FF) | (data << 8); + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } + break; + + case 0xC000: + case 0xE000: + nes->apu->ExWrite( addr, data ); + break; + } +} + +void Mapper069::Clock( INT cycles ) +{ + if( irq_enable && (nes->GetIrqType() == NES::IRQ_CLOCK) ) { + irq_counter -= cycles; + if( irq_counter <= 0 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + irq_enable = 0; + irq_counter = 0xFFFF; + } + } +} + +void Mapper069::HSync( INT scanline ) +{ + if( irq_enable && (nes->GetIrqType() == NES::IRQ_HSYNC) ) { + irq_counter -= 114; + if( irq_counter <= 0 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + irq_enable = 0; + irq_counter = 0xFFFF; + } + } +} + +void Mapper069::SaveState( LPBYTE p ) +{ + p[0] = reg; + p[1] = irq_enable; + *(INT*)&p[2] = irq_counter; +} + +void Mapper069::LoadState( LPBYTE p ) +{ + reg = p[0]; + irq_enable = p[1]; + irq_counter = *(INT*)&p[2]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper069.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper069.h new file mode 100644 index 00000000..435056e8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper069.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper069 SunSoft FME-7 // +////////////////////////////////////////////////////////////////////////// +class Mapper069 : public Mapper +{ +public: + Mapper069( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void Clock(INT cycles); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + + BYTE reg; + BYTE irq_enable; + INT irq_counter; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper070.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper070.cpp new file mode 100644 index 00000000..13560b0c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper070.cpp @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper070 Bandai 74161 // +////////////////////////////////////////////////////////////////////////// +void Mapper070::Reset() +{ + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0xa59ca2ef ) { // Kamen Rider Club(J) + patch = 1; + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } + if( crc == 0x10bb8f9a ) { // Family Trainer - Manhattan Police(J) + patch = 1; + } + if( crc == 0x0cd00488 ) { // Space Shadow(J) + patch = 1; + } + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper070::Write( WORD addr, BYTE data ) +{ + SetPROM_16K_Bank( 4, (data & 0x70)>>4 ); + SetVROM_8K_Bank( data & 0x0F ); + + if( patch ) { + if( data & 0x80 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + if( data & 0x80 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper070.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper070.h new file mode 100644 index 00000000..1f9174dc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper070.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper070 Bandai 74161 // +////////////////////////////////////////////////////////////////////////// +class Mapper070 : public Mapper +{ +public: + Mapper070( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: + BYTE patch; +private: +}; \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper071.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper071.cpp new file mode 100644 index 00000000..34c7e8f9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper071.cpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper071 Camerica // +////////////////////////////////////////////////////////////////////////// +void Mapper071::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +// SetPROM_32K_Bank( 0, 1, 0, 1 ); + rom_type = 0; + rom_bank = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x5b2b72cb // Big Nose Freaks Out(U) + || crc == 0xccdcbfc6 ) { // Big Nose Freaks Out(Aladdin)(U) +// nes->SetRenderMethod( NES::TILE_RENDER ); +// nes->ppu->SetExtNameTableMode( TRUE ); + } + + if( crc == 0x6096F84E // PEGASUS 5 IN 1 (unl) + || crc == 0x57850320 ) { // PEGASUS 5 IN 1 (unl)(re-link) + SetPROM_32K_Bank( 0, 1, 30, 31 ); + rom_type = 1; + } + +} + +void Mapper071::WriteLow( WORD addr, BYTE data ) +{ + if( (addr&0xE000)==0x6000 ) { + SetPROM_16K_Bank( 4, rom_bank + data ); + } +} + +void Mapper071::Write( WORD addr, BYTE data ) +{ + switch( addr&0xF000 ) { + case 0x8000: + if( rom_type && (addr==0x8927) ){ + rom_bank = (data & 7) * 16; + SetPROM_16K_Bank( 6, rom_bank + 15); + } + break; + case 0x9000: + if( data&0x10 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + + case 0xC000: + case 0xD000: + case 0xE000: + case 0xF000: + SetPROM_16K_Bank( 4, rom_bank + data ); + break; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper071.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper071.h new file mode 100644 index 00000000..9b789d3b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper071.h @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper071 Camerica // +////////////////////////////////////////////////////////////////////////// +class Mapper071 : public Mapper +{ +public: + Mapper071( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: + BYTE rom_type; + BYTE rom_bank; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper072.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper072.cpp new file mode 100644 index 00000000..66673378 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper072.cpp @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper072 Jaleco/Type1 lower bank switch // +////////////////////////////////////////////////////////////////////////// +void Mapper072::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper072::Write( WORD addr, BYTE data ) +{ + if( data & 0x80 ) { + SetPROM_16K_Bank( 4, data&0x0F ); + } else if( data & 0x40 ) { + SetVROM_8K_Bank( data&0x0F ); + } else { +//DEBUGOUT( "SOUND? ADDR:%04X DATA:%02X\n", addr, data ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper072.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper072.h new file mode 100644 index 00000000..67e580b1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper072.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper072 Jaleco/Type1 lower bank switch // +////////////////////////////////////////////////////////////////////////// +class Mapper072 : public Mapper +{ +public: + Mapper072( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper073.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper073.cpp new file mode 100644 index 00000000..321cba95 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper073.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper073 Konami VRC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper073::Reset() +{ + irq_enable = 0; + irq_counter = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper073::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0xF000: + SetPROM_16K_Bank( 4, data ); + break; + + case 0x8000: + irq_counter = (irq_counter & 0xFFF0) | (data & 0x0F); + break; + case 0x9000: + irq_counter = (irq_counter & 0xFF0F) | ((data & 0x0F) << 4); + break; + case 0xA000: + irq_counter = (irq_counter & 0xF0FF) | ((data & 0x0F) << 8); + break; + case 0xB000: + irq_counter = (irq_counter & 0x0FFF) | ((data & 0x0F) << 12); + break; + case 0xC000: + irq_enable = data; + break; + } +} + +void Mapper073::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_counter+=cycles) >= 0xFFFF ) { + irq_enable = 0; + irq_counter &= 0xFFFF; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_TRIGGER ); + } + } +} + +void Mapper073::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_counter; +} + +void Mapper073::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = *(INT*)&p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper073.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper073.h new file mode 100644 index 00000000..d00954c0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper073.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper073 Konami VRC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper073 : public Mapper +{ +public: + Mapper073( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + INT irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074 - 副本.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074 - 副本.cpp new file mode 100644 index 00000000..1a8d8704 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074 - 副本.cpp @@ -0,0 +1,496 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper074 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper074::Reset() +{ + if(nes->rom->GetPROM_CRC() == 0x227f8f9f){ + memcpy( YWRAM, PROM, 512*1024); + DEBUGOUT("!!!=%10d\n", sizeof(YWRAM) ); + for( INT i = 0; i < (512*1024); i++ ) + { + switch(YWRAM[i]&0x0f){ + case 0x01:YWRAM[i]=(YWRAM[i]&0xF0)|0x08; break; + case 0x02:YWRAM[i]=(YWRAM[i]&0xF0)|0x04; break; + case 0x03:YWRAM[i]=(YWRAM[i]&0xF0)|0x0c; break; + case 0x04:YWRAM[i]=(YWRAM[i]&0xF0)|0x02; break; + case 0x05:YWRAM[i]=(YWRAM[i]&0xF0)|0x0a; break; + case 0x07:YWRAM[i]=(YWRAM[i]&0xF0)|0x0e; break; + case 0x08:YWRAM[i]=(YWRAM[i]&0xF0)|0x01; break; + case 0x0A:YWRAM[i]=(YWRAM[i]&0xF0)|0x05; break; + case 0x0B:YWRAM[i]=(YWRAM[i]&0xF0)|0x0d; break; + case 0x0C:YWRAM[i]=(YWRAM[i]&0xF0)|0x03; break; + case 0x0D:YWRAM[i]=(YWRAM[i]&0xF0)|0x0b; break; + case 0x0E:YWRAM[i]=(YWRAM[i]&0xF0)|0x07; break; + } + } + memcpy( &PROM[0], &YWRAM[0], 512*1024); + } + + nes->ppu->SetVromWrite(1); + for( INT j = 0; j < 8; j++ ) reg[j] = 0x00; + prg0 = 0; + prg1 = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + SetBank_CPU(); + chr01 = 0; + chr1 = 1; + chr23 = 2; + chr3 = 3; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_request = 0; + we_sram = 0; + + reg5000 = 0; + reg5001 = 0; + reg5002 = 0; + reg5003 = 0; + reg5010 = 0; + reg5011 = 0; + reg5012 = 0; + reg5013 = 0; + reg5FF3 = 0; + reg6000 = 0; + reg6010 = 0; + reg6013 = 0; + WF_sn_5000 = 1; + WF_sn_5010 = 1; + WF_sn_5013 = 1; + RF_sn_6000 = 1; + RF_sn_6010 = 1; + RF_sn_6013 = 1; + +// nes->SetSAVERAM_SIZE( 32*1024 ); + + for( j = 0; j < 0x2000; j++ ){ + WX_WRAM00[j] = 0; + WX_WRAM01[j] = WRAM[j]; + WX_WRAM02[j] = 0; + WX_WRAM03[j] = 0; + } + + sp_rom = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + + if(crc == 0xeb08bfe9){ //[ES-1125] Gui Mei Zhan Ji (C) +// sp_rom = 2; +// for(j=0;j<0x2000;j++) WX_WRAM01[j]=WRAM[j]; + } + + if(crc == 0x65F30078 //[ES-1121] Guang Zhi Qi Shi (C) + || crc == 0xB76205B5){ //[ES-1136] Shang Gu Shen Dian (C) +// sp_rom = 2; + for(j=0;j<0x2000;j++) WX_WRAM01[j]=WRAM[0x1000+j]; + } + + if(crc == 0x84966C88){ //[KT-1005] Feng Shen Bang (C) + sp_rom = 3; + } + if(crc == 0x830BCF70){ //[KT-1015] Chu Liu Xiang Xin Zhuan (C) + sp_rom = 4; + bank = 0; + prg2 = (PROM_8K_SIZE>>1)-2; + prg3 = (PROM_8K_SIZE>>1)-1; + SetBank_CPU(); + } + +} + +BYTE Mapper074::ReadLow( WORD addr ) +{ + DEBUGOUT("ReadLow : Address=%04X\n", addr&0xFFFF ); + + if( addr >= 0x5000 && addr <= 0x5FFF ) { + return XRAM[addr-0x4000]; + }else{ + if( addr>=0x6000 ) { + +// if( sp_rom == 2 ){ + + switch( we_sram&0xE3 ) { + case 0xe0: + return WX_WRAM00[addr&0x1FFF]; + break; + case 0xe1: + return WX_WRAM01[addr&0x1FFF]; + break; + case 0xe2: + return WX_WRAM02[addr&0x1FFF]; + break; + case 0xe3: + return WX_WRAM03[addr&0x1FFF]; + break; + default: + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + break; + } + +// } + + if((addr==0x6000)&&(RF_sn_6000)){ + RF_sn_6000 = 0; + return reg6000; + } + if((addr==0x6010)&&(RF_sn_6010)){ + RF_sn_6010 = 0; + return reg6010; + } + if((addr==0x6013)&&(RF_sn_6013)){ + RF_sn_6013 = 0; + return reg6013; + } + + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } + } + return Mapper::ReadLow( addr ); +} + +void Mapper074::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT("WriteLow : Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + if ((addr&0x4100)==0x4100) { +// if(data&2){ +// SetCRAM_8K_Bank(0); +// }else +// SetVROM_1K_Bank(addr>>10,data); +// data &= 0x03; +// if ( data == 0 ) SetCRAM_8K_Bank( 2 ); +// else if ( data == 1 ) SetCRAM_8K_Bank( 3 ); +// else if ( data == 2 ) SetCRAM_8K_Bank( 0 ); +// else SetCRAM_8K_Bank( 1 ); + } + + if( addr >= 0x5000 && addr <= 0x5FFF ) { + XRAM[addr-0x4000] = data; + + switch( addr ) { + case 0x5000: + reg5000 = data; + if (WF_sn_5000){ + reg6000 = reg5000; + WF_sn_5000 = 0; + } + if ( sp_rom == 4 ) { //[KT-1015] Chu Liu Xiang Xin Zhuan (C) + bank = ((reg5000<<4)|(reg5003&0xf))>>2; + SetPROM_32K_Bank( bank ); + } + break; + case 0x5001: + reg5001 = data; + break; + case 0x5002: + reg5002 = data; + break; + case 0x5003: + reg5003 = data; + break; + case 0x5010: + reg5010 = data; + if (WF_sn_5010){ + reg6010 = reg5010; + WF_sn_5010 = 0; + } + break; + case 0x5011: + reg5011 = data; + break; + case 0x5012: + reg5012 = data; + break; + case 0x5013: + reg5013 = data; + if (WF_sn_5013){ + reg6013 = reg5013; + WF_sn_5013 = 0; + } + break; + case 0x5FF3: + reg5FF3 = data; + if( reg5FF3 == 2 ) { + SetPROM_32K_Bank( 0, 0, 0, 0 ); + } + break; + + default: + // + break; + } + + } else { + if( addr >= 0x6000 ) { + +// if( sp_rom == 2 ){ + + switch( we_sram&0xE3 ) { + case 0xe0: //CPU_MEM_BANK + WX_WRAM00[addr&0x1FFF] = data; + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + case 0xe1: //SRAM + WX_WRAM01[addr&0x1FFF] = data; + break; + case 0xe2: + WX_WRAM02[addr&0x1FFF] = data; + break; + case 0xe3: + WX_WRAM03[addr&0x1FFF] = data; + break; + default: + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + } + +// return; + + } + +// CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +// } + } +} + +void Mapper074::Write( WORD addr, BYTE data ) +{ + DEBUGOUT("Write : Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x0f ) { + case 0x00: + chr01 = data; + chr1 = chr01+1; + SetBank_PPU(); + break; + case 0x01: + chr23 = data; + chr3 = chr23+1; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + case 0x08: + prg2 = data; + SetBank_CPU(); + break; + case 0x09: + prg3 = data; + SetBank_CPU(); + break; + case 0x0a: + chr1 = data; + SetBank_PPU(); + break; + case 0x0b: + chr3 = data; + SetBank_PPU(); + break; + } + break; + case 0xA000: + DEBUGOUT("Write : Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + reg[2] = data; + data &= 0x03; + if ( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if ( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if ( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + case 0xA001: + reg[3] = data; + we_sram = reg[3]; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + +} + +void Mapper074::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter -= 1; + } + } + if(!(irq_counter)){ + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + irq_counter--; + } + } + } +} + +void Mapper074::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( prg2, prg1, prg0, prg3 ); + } else { + SetPROM_32K_Bank( prg0, prg1, prg2, prg3 ); + } +} + +void Mapper074::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_1K_Bank( 4, chr01); + SetVROM_1K_Bank( 5, chr1 ); + SetVROM_1K_Bank( 6, chr23); + SetVROM_1K_Bank( 7, chr3 ); + SetVROM_1K_Bank( 0, chr4 ); + SetVROM_1K_Bank( 1, chr5 ); + SetVROM_1K_Bank( 2, chr6 ); + SetVROM_1K_Bank( 3, chr7 ); + } else { + SetVROM_1K_Bank( 0, chr01); + SetVROM_1K_Bank( 1, chr1 ); + SetVROM_1K_Bank( 2, chr23); + SetVROM_1K_Bank( 3, chr3 ); + SetVROM_1K_Bank( 4, chr4 ); + SetVROM_1K_Bank( 5, chr5 ); + SetVROM_1K_Bank( 6, chr6 ); + SetVROM_1K_Bank( 7, chr7 ); + if ( sp_rom == 3 ) { //[KT-1005] Feng Shen Bang (C) + SetVROM_2K_Bank( 0, chr01); + SetVROM_2K_Bank( 2, chr23); + SetVROM_2K_Bank( 4, chr4 ); + SetVROM_2K_Bank( 6, chr6 ); + } + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } +} + +void Mapper074::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = irq_request; + p[20] = prg2; + p[21] = prg3; + p[22] = chr1; + p[23] = chr3; +} + +void Mapper074::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + prg2 = p[20]; + prg3 = p[21]; + chr01 = p[10]; + chr1 = p[22]; + chr23 = p[11]; + chr3 = p[23]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + irq_request = p[19]; +} + +void Mapper074::PPU_Latch( WORD addr ) +{ + if(DirectInput.m_Sw[DIK_PAUSE]){ + nes->Dump_YWRAM(); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074 - 副本.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074 - 副本.h new file mode 100644 index 00000000..bc9e1656 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074 - 副本.h @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper074 // +////////////////////////////////////////////////////////////////////////// +class Mapper074 : public Mapper +{ +public: + Mapper074( NES* parent ) : Mapper(parent) {} + + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + void PPU_Latch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1, prg2, prg3; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE chr1, chr3; + BYTE we_sram; + BYTE sp_rom, bank; + BYTE patch; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + + BYTE reg5000; + BYTE reg5001; + BYTE reg5002; + BYTE reg5003; + BYTE reg5010; + BYTE reg5011; + BYTE reg5012; + BYTE reg5013; + BYTE reg5FF3; + BYTE reg6000; + BYTE reg6010; + BYTE reg6013; + BYTE WF_sn_5000; + BYTE WF_sn_5010; + BYTE WF_sn_5013; + BYTE RF_sn_6000; + BYTE RF_sn_6010; + BYTE RF_sn_6013; + + BYTE WX_WRAM00[8*1024]; + BYTE WX_WRAM01[8*1024]; + BYTE WX_WRAM02[8*1024]; + BYTE WX_WRAM03[8*1024]; + +// BYTE adr5000buf[4*1024]; + BYTE adr6000buf[8*1024]; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_PPUSUB( int bank, int page ); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074.cpp new file mode 100644 index 00000000..3afdefa3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074.cpp @@ -0,0 +1,446 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper074 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper074::Reset() +{ + DWORD crc = nes->rom->GetPROM_CRC(); + + if(crc == 0x227f8f9f) Decode_PROM(); //Ji Jia Zhan Shi (Ch) [new pcb dump] + + nes->ppu->SetVromWrite(1); + for( INT j = 0; j < 8; j++ ) reg[j] = 0x00; + prg0 = 0; + prg1 = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + SetBank_CPU(); + chr01 = 0; + chr1 = 1; + chr23 = 2; + chr3 = 3; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_request = 0; + + reg5000 = 0; + reg5001 = 0; + reg5002 = 0; + reg5003 = 0; + reg5010 = 0; + reg5011 = 0; + reg5012 = 0; + reg5013 = 0; + reg5FF3 = 0; + + JMaddr = 0; + JMaddrDAT[0] = JMaddrDAT[1] = JMaddrDAT[2] = 0; + + we_sram = 0; + nes->SetSAVERAM_SIZE( 32*1024 ); + + sp_rom = 0; + + if(crc == 0x84966C88){ //[KT-1005] Feng Shen Bang (C) + nes->SetSAVERAM_SIZE( 8*1024 ); + sp_rom = 1; + } + if(crc == 0x830BCF70){ //[KT-1015] Chu Liu Xiang Xin Zhuan (C) + nes->SetSAVERAM_SIZE( 8*1024 ); + sp_rom = 2; + bank = 0; + prg2 = (PROM_8K_SIZE>>1)-2; + prg3 = (PROM_8K_SIZE>>1)-1; + SetBank_CPU(); + } + +} + +BYTE Mapper074::ReadLow( WORD addr ) +{ + DEBUGOUT("ReadLow : Address=%04X\n", addr&0xFFFF ); + + if( addr >= 0x5000 && addr <= 0x5FFF ){ + return XRAM[addr-0x4000]; + }else if( addr >= 0x6000 && addr <= 0x7FFF ){ + if(JMaddr){ + switch( addr ) { + case 0x6000: return JMaddrDAT[0]; + case 0x6010: return JMaddrDAT[1]; + case 0x6013: JMaddr=0; return JMaddrDAT[2]; + } + } + switch( we_sram ) { + case 0xE4: + case 0xEC: return WRAM[(addr&0x1FFF)+0x0000]; + case 0xE5: + case 0xED: return WRAM[(addr&0x1FFF)+0x2000]; + case 0xE6: + case 0xEE: return WRAM[(addr&0x1FFF)+0x4000]; + case 0xE7: + case 0xEF: return WRAM[(addr&0x1FFF)+0x6000]; + default: return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } + }else{ + return Mapper::ReadLow( addr ); + } +} + +void Mapper074::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT("WriteLow : Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); +/* + if ((addr&0x4100)==0x4100) { //й[Sachen] + + if(data&2){ + SetCRAM_8K_Bank(0); + }else + SetVROM_1K_Bank(addr>>10,data); +// data &= 0x03; +// if ( data == 0 ) SetCRAM_8K_Bank( 2 ); +// else if ( data == 1 ) SetCRAM_8K_Bank( 3 ); +// else if ( data == 2 ) SetCRAM_8K_Bank( 0 ); +// else SetCRAM_8K_Bank( 1 ); + + } +*/ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + XRAM[addr-0x4000] = data; + + switch( addr ) { + case 0x5000: + reg5000 = data; + if (sp_rom==2){ //[KT-1015] Chu Liu Xiang Xin Zhuan (C) + bank = ((reg5000<<4)|(reg5003&0xf))>>2; + SetPROM_32K_Bank( bank );} + break; + case 0x5001: + reg5001 = data; + break; + case 0x5002: + reg5002 = data; + break; + case 0x5003: + reg5003 = data; + break; + case 0x5010: + reg5010 = data; + break; + case 0x5011: + reg5011 = data; + break; + case 0x5012: + reg5012 = data; + break; + case 0x5013: + reg5013 = data; + break; + case 0x5FF3: + reg5FF3 = data; + if(reg5FF3==2) SetPROM_32K_Bank(0,0,0,0); + break; + } + + if((we_sram==0xA5)||(we_sram==0xA9)){ + JMaddr = 1; + switch( addr ) { + case 0x5000: JMaddrDAT[0] = data; break; + case 0x5010: JMaddrDAT[1] = data; break; + case 0x5013: JMaddrDAT[2] = data; break; + } + } + + }else if( addr >= 0x6000 && addr <= 0x7FFF ){ + switch( we_sram ) { + case 0xE4: //CPU_MEM_BANK + case 0xEC: //CPU_MEM_BANK + WRAM[(addr&0x1FFF)+0x0000] = data; + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + case 0xE5: //SRAM + case 0xED: //SRAM + WRAM[(addr&0x1FFF)+0x2000] = data; + break; + case 0xE6: + case 0xEE: + WRAM[(addr&0x1FFF)+0x4000] = data; + break; + case 0xE7: + case 0xEF: + WRAM[(addr&0x1FFF)+0x6000] = data; + break; + default: + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + } + }else{ + Mapper::WriteLow( addr, data ); + } +} + +void Mapper074::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT("Write : Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x0f ) { + case 0x00: + chr01 = data; + chr1 = chr01+1; + SetBank_PPU(); + break; + case 0x01: + chr23 = data; + chr3 = chr23+1; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + case 0x08: + prg2 = data; + SetBank_CPU(); + break; + case 0x09: + prg3 = data; + SetBank_CPU(); + break; + case 0x0a: + chr1 = data; + SetBank_PPU(); + break; + case 0x0b: + chr3 = data; + SetBank_PPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + data &= 0x03; + if ( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if ( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if ( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + case 0xA001: +// DEBUGOUT("Write : Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + reg[3] = data; + we_sram = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + +} + +void Mapper074::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter -= 1; + } + } + if(!(irq_counter)){ + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + irq_counter--; + } + } + } +} + +void Mapper074::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( prg2, prg1, prg0, prg3 ); + } else { + SetPROM_32K_Bank( prg0, prg1, prg2, prg3 ); + } +} + +void Mapper074::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_1K_Bank( 4, chr01); + SetVROM_1K_Bank( 5, chr1 ); + SetVROM_1K_Bank( 6, chr23); + SetVROM_1K_Bank( 7, chr3 ); + SetVROM_1K_Bank( 0, chr4 ); + SetVROM_1K_Bank( 1, chr5 ); + SetVROM_1K_Bank( 2, chr6 ); + SetVROM_1K_Bank( 3, chr7 ); + } else { + SetVROM_1K_Bank( 0, chr01); + SetVROM_1K_Bank( 1, chr1 ); + SetVROM_1K_Bank( 2, chr23); + SetVROM_1K_Bank( 3, chr3 ); + SetVROM_1K_Bank( 4, chr4 ); + SetVROM_1K_Bank( 5, chr5 ); + SetVROM_1K_Bank( 6, chr6 ); + SetVROM_1K_Bank( 7, chr7 ); + if(sp_rom==1){ //[KT-1005] Feng Shen Bang (C) + SetVROM_2K_Bank( 0, chr01); + SetVROM_2K_Bank( 2, chr23); + SetVROM_2K_Bank( 4, chr4 ); + SetVROM_2K_Bank( 6, chr6 ); + } + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } +} + +void Mapper074::Decode_PROM() +{ + memcpy(BDRAM,PROM,0x80000); + for(INT i=0;i<0x80000;i++) + { + switch(BDRAM[i]&0x0F){ + case 0x01:BDRAM[i]=(BDRAM[i]&0xF0)|0x08;break; + case 0x02:BDRAM[i]=(BDRAM[i]&0xF0)|0x04;break; + case 0x03:BDRAM[i]=(BDRAM[i]&0xF0)|0x0C;break; + case 0x04:BDRAM[i]=(BDRAM[i]&0xF0)|0x02;break; + case 0x05:BDRAM[i]=(BDRAM[i]&0xF0)|0x0A;break; + case 0x07:BDRAM[i]=(BDRAM[i]&0xF0)|0x0E;break; + case 0x08:BDRAM[i]=(BDRAM[i]&0xF0)|0x01;break; + case 0x0A:BDRAM[i]=(BDRAM[i]&0xF0)|0x05;break; + case 0x0B:BDRAM[i]=(BDRAM[i]&0xF0)|0x0D;break; + case 0x0C:BDRAM[i]=(BDRAM[i]&0xF0)|0x03;break; + case 0x0D:BDRAM[i]=(BDRAM[i]&0xF0)|0x0B;break; + case 0x0E:BDRAM[i]=(BDRAM[i]&0xF0)|0x07;break; + } + } + memcpy(PROM,BDRAM,0x80000); + memcpy(&PROM[0x01*0x4000],&BDRAM[0x04*0x4000],0x4000); + memcpy(&PROM[0x03*0x4000],&BDRAM[0x06*0x4000],0x4000); + memcpy(&PROM[0x04*0x4000],&BDRAM[0x01*0x4000],0x4000); + memcpy(&PROM[0x06*0x4000],&BDRAM[0x03*0x4000],0x4000); + memcpy(&PROM[0x09*0x4000],&BDRAM[0x0C*0x4000],0x4000); + memcpy(&PROM[0x0B*0x4000],&BDRAM[0x0E*0x4000],0x4000); + memcpy(&PROM[0x0C*0x4000],&BDRAM[0x09*0x4000],0x4000); + memcpy(&PROM[0x0E*0x4000],&BDRAM[0x0B*0x4000],0x4000); + memcpy(&PROM[0x11*0x4000],&BDRAM[0x14*0x4000],0x4000); +} + +void Mapper074::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = irq_request; + p[20] = prg2; + p[21] = prg3; + p[22] = chr1; + p[23] = chr3; +} + +void Mapper074::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + prg2 = p[20]; + prg3 = p[21]; + chr01 = p[10]; + chr1 = p[22]; + chr23 = p[11]; + chr3 = p[23]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + irq_request = p[19]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074.h new file mode 100644 index 00000000..4bc1bde9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper074.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper074 // +////////////////////////////////////////////////////////////////////////// +class Mapper074 : public Mapper +{ +public: + Mapper074( NES* parent ) : Mapper(parent) {} + + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1, prg2, prg3; + BYTE chr01, chr1, chr23, chr3, chr4, chr5, chr6, chr7; + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + + BYTE sp_rom, bank; + BYTE we_sram; + BYTE JMaddr, JMaddrDAT[3]; + + BYTE reg5000; + BYTE reg5001; + BYTE reg5002; + BYTE reg5003; + BYTE reg5010; + BYTE reg5011; + BYTE reg5012; + BYTE reg5013; + BYTE reg5FF3; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void Decode_PROM(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper075.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper075.cpp new file mode 100644 index 00000000..bf41c85b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper075.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper075 Konami VRC1/Jaleco D65005 // +////////////////////////////////////////////////////////////////////////// +void Mapper075::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + reg[0] = 0; + reg[1] = 1; +} + +void Mapper075::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF000 ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + + case 0x9000: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + + reg[0] = (reg[0] & 0x0F) | ((data & 0x02) << 3); + reg[1] = (reg[1] & 0x0F) | ((data & 0x04) << 2); + SetVROM_4K_Bank( 0, reg[0] ); + SetVROM_4K_Bank( 4, reg[1] ); + break; + + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + case 0xC000: + SetPROM_8K_Bank( 6, data ); + break; + + case 0xE000: + reg[0] = (reg[0] & 0x10) | (data & 0x0F); + SetVROM_4K_Bank( 0, reg[0] ); + break; + + case 0xF000: + reg[1] = (reg[1] & 0x10) | (data & 0x0F); + SetVROM_4K_Bank( 4, reg[1] ); + break; + } +} + +void Mapper075::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; +} + +void Mapper075::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper075.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper075.h new file mode 100644 index 00000000..73f99ac2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper075.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper075 Konami VRC1/Jaleco D65005 // +////////////////////////////////////////////////////////////////////////// +class Mapper075 : public Mapper +{ +public: + Mapper075( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[2]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper076.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper076.cpp new file mode 100644 index 00000000..33a2e4fa --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper076.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper076 Namcot 109 (_]) // +////////////////////////////////////////////////////////////////////////// +void Mapper076::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE >= 8 ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper076::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + reg = data; + break; + case 0x8001: + switch( reg & 0x07 ) { + case 2: + SetVROM_2K_Bank( 0, data ); + break; + case 3: + SetVROM_2K_Bank( 2, data ); + break; + case 4: + SetVROM_2K_Bank( 4, data ); + break; + case 5: + SetVROM_2K_Bank( 6, data ); + break; + case 6: + SetPROM_8K_Bank( 4, data ); + break; + case 7: + SetPROM_8K_Bank( 5, data ); + break; + } + break; + } +} + +void Mapper076::SaveState( LPBYTE p ) +{ + p[0] = reg; +} + +void Mapper076::LoadState( LPBYTE p ) +{ + reg = p[0]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper076.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper076.h new file mode 100644 index 00000000..e7a5f640 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper076.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper076 Namcot 109 (_]) // +////////////////////////////////////////////////////////////////////////// +class Mapper076 : public Mapper +{ +public: + Mapper076( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper077.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper077.cpp new file mode 100644 index 00000000..9b1b0a28 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper077.cpp @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper077 Irem Early Mapper #0 // +////////////////////////////////////////////////////////////////////////// +void Mapper077::Reset() +{ + SetPROM_32K_Bank( 0 ); + + SetVROM_2K_Bank( 0, 0 ); + SetCRAM_2K_Bank( 2, 1 ); + SetCRAM_2K_Bank( 4, 2 ); + SetCRAM_2K_Bank( 6, 3 ); +} + +void Mapper077::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( data & 0x07 ); + + SetVROM_2K_Bank( 0, (data & 0xF0)>>4 ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper077.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper077.h new file mode 100644 index 00000000..ed5ba1aa --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper077.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper077 Irem Early Mapper #0 // +////////////////////////////////////////////////////////////////////////// +class Mapper077 : public Mapper +{ +public: + Mapper077( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper078.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper078.cpp new file mode 100644 index 00000000..e4d72cb2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper078.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper078 Jaleco(Cosmo Carrier) // +////////////////////////////////////////////////////////////////////////// +void Mapper078::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper078::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MAP78 WR $%04X=$%02X L=%d\n", addr, data, nes->GetScanline() ); + SetPROM_16K_Bank( 4, data&0x0F ); + SetVROM_8K_Bank( (data&0xF0)>>4 ); + + if( (addr & 0xFE00) != 0xFE00 ) { + if( data & 0x08 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper078.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper078.h new file mode 100644 index 00000000..1978d631 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper078.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper078 Jaleco(Cosmo Carrier) // +////////////////////////////////////////////////////////////////////////// +class Mapper078 : public Mapper +{ +public: + Mapper078( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper079.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper079.cpp new file mode 100644 index 00000000..7ebb1c8e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper079.cpp @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper079 Nina-3 // +////////////////////////////////////////////////////////////////////////// +void Mapper079::Reset() +{ + SetPROM_32K_Bank( 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper079::WriteLow( WORD addr, BYTE data ) +{ + if( addr&0x0100 ) { + SetPROM_32K_Bank( (data>>3)&0x01 ); + SetVROM_8K_Bank( data&0x07 ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper079.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper079.h new file mode 100644 index 00000000..b6f12097 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper079.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper079 Nina-3 // +////////////////////////////////////////////////////////////////////////// +class Mapper079 : public Mapper +{ +public: + Mapper079( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper080.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper080.cpp new file mode 100644 index 00000000..ff1c325c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper080.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper080 Taito X1-005 // +////////////////////////////////////////////////////////////////////////// +void Mapper080::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper080::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x7EF0: + SetVROM_2K_Bank( 0, (data>>1)&0x3F ); + if( PROM_8K_SIZE == 32 ) { + if( data & 0x80 ) { + SetVRAM_1K_Bank( 8, 1 ); + SetVRAM_1K_Bank( 9, 1 ); + } else { + SetVRAM_1K_Bank( 8, 0 ); + SetVRAM_1K_Bank( 9, 0 ); + } + } + break; + + case 0x7EF1: + SetVROM_2K_Bank( 2, (data>>1)&0x3F ); + if( PROM_8K_SIZE == 32 ) { + if( data & 0x80 ) { + SetVRAM_1K_Bank( 10, 1 ); + SetVRAM_1K_Bank( 11, 1 ); + } else { + SetVRAM_1K_Bank( 10, 0 ); + SetVRAM_1K_Bank( 11, 0 ); + } + } + break; + + case 0x7EF2: + SetVROM_1K_Bank( 4, data ); + break; + case 0x7EF3: + SetVROM_1K_Bank( 5, data ); + break; + case 0x7EF4: + SetVROM_1K_Bank( 6, data ); + break; + case 0x7EF5: + SetVROM_1K_Bank( 7, data ); + break; + + case 0x7EF6: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_HMIRROR ); + break; + + case 0x7EFA: + case 0x7EFB: + SetPROM_8K_Bank( 4, data ); + break; + case 0x7EFC: + case 0x7EFD: + SetPROM_8K_Bank( 5, data ); + break; + case 0x7EFE: + case 0x7EFF: + SetPROM_8K_Bank( 6, data ); + break; + default: + Mapper::WriteLow( addr, data ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper080.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper080.h new file mode 100644 index 00000000..26b22545 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper080.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper080 Taito X1-005 // +////////////////////////////////////////////////////////////////////////// +class Mapper080 : public Mapper +{ +public: + Mapper080( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper082.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper082.cpp new file mode 100644 index 00000000..9906e775 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper082.cpp @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper082 Taito C075 // +////////////////////////////////////////////////////////////////////////// +void Mapper082::Reset() +{ + reg = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + SetVRAM_Mirror( VRAM_VMIRROR ); +} + +void Mapper082::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x7EF0: + if( reg ) { + SetVROM_2K_Bank( 4, data>>1 ); + } else { + SetVROM_2K_Bank( 0, data>>1 ); + } + break; + + case 0x7EF1: + if( reg ) { + SetVROM_2K_Bank( 6, data>>1 ); + } else { + SetVROM_2K_Bank( 2, data>>1 ); + } + break; + + case 0x7EF2: + if( reg ) SetVROM_1K_Bank( 0, data ); + else SetVROM_1K_Bank( 4, data ); + break; + case 0x7EF3: + if( reg ) SetVROM_1K_Bank( 1, data ); + else SetVROM_1K_Bank( 5, data ); + break; + case 0x7EF4: + if( reg ) SetVROM_1K_Bank( 2, data ); + else SetVROM_1K_Bank( 6, data ); + break; + case 0x7EF5: + if( reg ) SetVROM_1K_Bank( 3, data ); + else SetVROM_1K_Bank( 7, data ); + break; + + case 0x7EF6: + reg = data & 0x02; + if( data & 0x01 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_HMIRROR ); + break; + + case 0x7EFA: + SetPROM_8K_Bank( 4, data>>2 ); + break; + case 0x7EFB: + SetPROM_8K_Bank( 5, data>>2 ); + break; + case 0x7EFC: + SetPROM_8K_Bank( 6, data>>2 ); + break; + default: + Mapper::WriteLow( addr, data ); + break; + } +} + +void Mapper082::SaveState( LPBYTE p ) +{ + p[0] = reg; +} + +void Mapper082::LoadState( LPBYTE p ) +{ + reg = p[0]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper082.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper082.h new file mode 100644 index 00000000..928d630f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper082.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper082 Taito C075 // +////////////////////////////////////////////////////////////////////////// +class Mapper082 : public Mapper +{ +public: + Mapper082( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper083.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper083.cpp new file mode 100644 index 00000000..b3f85ebe --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper083.cpp @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper083 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper083::Reset() +{ + for( INT i = 0; i < 3; i++ ) { + reg[i] = 0x00; + } + + if( PROM_8K_SIZE >= 32 ) { + SetPROM_32K_Bank( 0, 1, 30, 31 ); + reg[1] = 0x30; + } else { + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + chr_bank = 0; + + irq_enable = 0; // Disable + irq_counter = 0; + + patch = 0; + if( nes->rom->GetPROM_CRC() == 0x1461D1F8 ) { + patch = 1; + } +} + +BYTE Mapper083::ReadLow( WORD addr ) +{ + if( (addr&0x5100) == 0x5100 ) { + return reg[2]; + } else if( addr >= 0x6000 ) { + return Mapper::ReadLow( addr ); + } + + return (BYTE)(addr>>8); +} + +void Mapper083::WriteLow( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr ) { + case 0x5101: + case 0x5102: + case 0x5103: + reg[2] = data; + break; + } + + if( addr >= 0x6000 ) { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper083::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr ) { + case 0x8000: + case 0xB000: + case 0xB0FF: + case 0xB1FF: + reg[0] = data; + chr_bank = (data&0x30)<<4; + SetPROM_16K_Bank( 4, data ); + SetPROM_16K_Bank( 6, (data&0x30)|0x0F ); + break; + + case 0x8100: + reg[1] = data & 0x80; + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0x8200: + irq_counter = (irq_counter&0xFF00)|(INT)data; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x8201: + irq_counter = (irq_counter&0x00FF)|((INT)data<<8); + irq_enable = reg[1]; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0x8300: + SetPROM_8K_Bank( 4, data ); + break; + case 0x8301: + SetPROM_8K_Bank( 5, data ); + break; + case 0x8302: + SetPROM_8K_Bank( 6, data ); + break; + + case 0x8310: + if( patch ) { + SetVROM_2K_Bank( 0, chr_bank|data ); + } else { + SetVROM_1K_Bank( 0, chr_bank|data ); + } + break; + case 0x8311: + if( patch ) { + SetVROM_2K_Bank( 2, chr_bank|data ); + } else { + SetVROM_1K_Bank( 1, chr_bank|data ); + } + break; + case 0x8312: + SetVROM_1K_Bank( 2, chr_bank|data ); + break; + case 0x8313: + SetVROM_1K_Bank( 3, chr_bank|data ); + break; + case 0x8314: + SetVROM_1K_Bank( 4, chr_bank|data ); + break; + case 0x8315: + SetVROM_1K_Bank( 5, chr_bank|data ); + break; + case 0x8316: + if( patch ) { + SetVROM_2K_Bank( 4, chr_bank|data ); + } else { + SetVROM_1K_Bank( 6, chr_bank|data ); + } + break; + case 0x8317: + if( patch ) { + SetVROM_2K_Bank( 6, chr_bank|data ); + } else { + SetVROM_1K_Bank( 7, chr_bank|data ); + } + break; + + case 0x8318: + SetPROM_16K_Bank( 4, (reg[0]&0x30)|data ); + break; + } +} + +void Mapper083::HSync( INT scanline ) +{ + if( irq_enable ) { + if( irq_counter <= 113 ) { +// nes->cpu->IRQ(); + irq_enable = 0; +// nes->cpu->SetIRQ( IRQ_MAPPER ); + nes->cpu->SetIRQ( IRQ_TRIGGER ); + } else { + irq_counter -= 113; + } + } +} + +void Mapper083::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + *(INT*)&p[3] = chr_bank; + p[7] = irq_enable; + *(INT*)&p[8] = irq_counter; +} + +void Mapper083::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + chr_bank = *(INT*)&p[3]; + irq_enable = p[7]; + irq_counter = *(INT*)&p[8]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper083.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper083.h new file mode 100644 index 00000000..36e1a483 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper083.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper083 Cony // +////////////////////////////////////////////////////////////////////////// +class Mapper083 : public Mapper +{ +public: + Mapper083( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[3]; + INT chr_bank; + BYTE irq_enable; + INT irq_counter; + + BYTE patch; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper085.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper085.cpp new file mode 100644 index 00000000..56a57355 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper085.cpp @@ -0,0 +1,174 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper085 Konami VRC7 // +////////////////////////////////////////////////////////////////////////// +void Mapper085::Reset() +{ + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } else { + SetCRAM_8K_Bank( 0 ); + } + +#if 0 +// DWORD crc = nes->rom->GetPROM_CRC(); +// if( crc == 0x1aa0479c ) { // For Tiny Toon Adventures 2 - Montana Land he Youkoso(J) +// nes->SetRenderMethod( NES::PRE_RENDER ); +// } +// if( crc == 0x33ce3ff0 ) { // For Lagrange Point(J) +// nes->SetRenderMethod( NES::TILE_RENDER ); +// } +#endif + nes->apu->SelectExSound( 2 ); +} + +void Mapper085::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF038 ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + case 0x8008: + case 0x8010: + SetPROM_8K_Bank( 5, data ); + break; + case 0x9000: + SetPROM_8K_Bank( 6, data ); + break; + + case 0x9010: + case 0x9030: + nes->apu->ExWrite( addr, data ); + break; + + case 0xA000: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 0, data ); + } else { + SetCRAM_1K_Bank( 0, data ); + } + break; + + case 0xA008: + case 0xA010: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 1, data ); + } else { + SetCRAM_1K_Bank( 1, data ); + } + break; + + case 0xB000: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 2, data ); + } else { + SetCRAM_1K_Bank( 2, data ); + } + break; + + case 0xB008: + case 0xB010: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 3, data ); + } else { + SetCRAM_1K_Bank( 3, data ); + } + break; + + case 0xC000: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 4, data ); + } else { + SetCRAM_1K_Bank( 4, data ); + } + break; + + case 0xC008: + case 0xC010: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 5, data ); + } else { + SetCRAM_1K_Bank( 5, data ); + } + break; + + case 0xD000: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 6, data ); + } else { + SetCRAM_1K_Bank( 6, data ); + } + break; + + case 0xD008: + case 0xD010: + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 7, data ); + } else { + SetCRAM_1K_Bank( 7, data ); + } + break; + + case 0xE000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0xE008: + case 0xE010: + irq_latch = data; + break; + + case 0xF000: + irq_enable = data & 0x03; + irq_counter = irq_latch; + irq_clock = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF008: + case 0xF010: + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper085::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + irq_clock += cycles*4; + while( irq_clock >= 455 ) { + irq_clock -= 455; + irq_counter++; + if( irq_counter == 0 ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +} + +void Mapper085::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; + p[2] = irq_latch; + *((INT*)&p[4]) = irq_clock; +} + +void Mapper085::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; + irq_latch = p[2]; + irq_clock = *((INT*)&p[4]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper085.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper085.h new file mode 100644 index 00000000..3d5a7850 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper085.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper085 Konami VRC7 // +////////////////////////////////////////////////////////////////////////// +class Mapper085 : public Mapper +{ +public: + Mapper085( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper086.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper086.cpp new file mode 100644 index 00000000..8f681979 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper086.cpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper086 Jaleco Early Mapper #2 // +////////////////////////////////////////////////////////////////////////// +void Mapper086::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + SetVROM_8K_Bank( 0 ); + + reg = 0xFF; + cnt = 0; +} + +void Mapper086::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x6000 ) { + SetPROM_32K_Bank( (data&0x30)>>4 ); + + SetVROM_8K_Bank( (data&0x03)|((data & 0x40)>>4) ); + } + if( addr == 0x7000 ) { + if( !(reg&0x10) && (data&0x10) && !cnt ) { +//DEBUGOUT( "WR:$%02X\n", data ); + if( (data&0x0F) == 0 // Strike + || (data&0x0F) == 5 ) { // Foul + cnt = 60; // ̔1b֎~ + } + + // OSDɂׂc + if( Config.sound.bExtraSoundEnable ) { + DirectSound.EsfAllStop(); + DirectSound.EsfPlay( ESF_MOEPRO_STRIKE+(data&0x0F) ); + } + } + reg = data; + } +} + +void Mapper086::VSync() +{ + if( cnt ) { + cnt--; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper086.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper086.h new file mode 100644 index 00000000..853436a5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper086.h @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper086 Jaleco Early Mapper #2 // +////////////////////////////////////////////////////////////////////////// +class Mapper086 : public Mapper +{ +public: + Mapper086( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + void VSync(); + +protected: + BYTE reg, cnt; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper087.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper087.cpp new file mode 100644 index 00000000..d4a1f59d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper087.cpp @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper087 Konami 74161/32 // +////////////////////////////////////////////////////////////////////////// +void Mapper087::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper087::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x6000 ) { + SetVROM_8K_Bank( (data & 0x02)>>1 ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper087.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper087.h new file mode 100644 index 00000000..49bef8ac --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper087.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper087 Konami 74161/32 // +////////////////////////////////////////////////////////////////////////// +class Mapper087 : public Mapper +{ +public: + Mapper087( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper088.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper088.cpp new file mode 100644 index 00000000..f7395c23 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper088.cpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper088 Namcot 118 // +////////////////////////////////////////////////////////////////////////// +void Mapper088::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE >= 8 ) { + SetVROM_8K_Bank( 0 ); + } + + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0xc1b6b2a6 ) { // Devil Man(J) + patch = 1; + nes->SetRenderMethod( NES::POST_RENDER ); + } + if( crc == 0xd9803a35 ) { // Quinty(J) + nes->SetRenderMethod( NES::POST_RENDER ); + } +} + +void Mapper088::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + reg = data; + if( patch ) { + if( data&0x40 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + break; + case 0x8001: + switch( reg & 0x07 ) { + case 0: + SetVROM_2K_Bank( 0, data>>1 ); + break; + case 1: + SetVROM_2K_Bank( 2, data>>1 ); + break; + case 2: + SetVROM_1K_Bank( 4, data+0x40 ); + break; + case 3: + SetVROM_1K_Bank( 5, data+0x40 ); + break; + case 4: + SetVROM_1K_Bank( 6, data+0x40 ); + break; + case 5: + SetVROM_1K_Bank( 7, data+0x40 ); + break; + case 6: + SetPROM_8K_Bank( 4, data ); + break; + case 7: + SetPROM_8K_Bank( 5, data ); + break; + } + break; + case 0xC000: + if( data ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + } +} + +void Mapper088::SaveState( LPBYTE p ) +{ + p[0] = reg; +} + +void Mapper088::LoadState( LPBYTE p ) +{ + reg = p[0]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper088.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper088.h new file mode 100644 index 00000000..a21e4df3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper088.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper088 Namcot 118 // +////////////////////////////////////////////////////////////////////////// +class Mapper088 : public Mapper +{ +public: + Mapper088( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; + BYTE patch; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper089.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper089.cpp new file mode 100644 index 00000000..7196460b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper089.cpp @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper089 SunSoft (ˉ) // +////////////////////////////////////////////////////////////////////////// +void Mapper089::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper089::Write( WORD addr, BYTE data ) +{ + if( (addr&0xFF00) == 0xC000 ) { + SetPROM_16K_Bank( 4, (data&0x70)>>4 ); + + SetVROM_8K_Bank( ((data&0x80)>>4)|(data&0x07) ); + + if( data & 0x08 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper089.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper089.h new file mode 100644 index 00000000..e5303045 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper089.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper089 SunSoft (ˉ) // +////////////////////////////////////////////////////////////////////////// +class Mapper089 : public Mapper +{ +public: + Mapper089( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper090.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper090.cpp new file mode 100644 index 00000000..7fae4573 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper090.cpp @@ -0,0 +1,368 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper090 PC-JY-?? // +////////////////////////////////////////////////////////////////////////// +void Mapper090::Reset() +{ + SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0x2a268152 ) { + patch = 1; + } + if( crc == 0x2224b882 ) { + nes->SetRenderMethod( NES::TILE_RENDER ); + } + + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_occur = 0; + irq_preset = 0; + irq_offset = 0; + + prg_6000 = 0; + prg_E000 = 0; + prg_size = 0; + chr_size = 0; + mir_mode = 0; + mir_type = 0; + + key_val = 0; + mul_val1 = mul_val2 = 0; + + for( INT i = 0; i < 4; i++ ) { + prg_reg[i] = PROM_8K_SIZE-4+i; + ntl_reg[i] = 0; + nth_reg[i] = 0; + chl_reg[i] = i; + chh_reg[i] = 0; + chl_reg[i+4] = i+4; + chh_reg[i+4] = 0; + } + + if( sw_val ) + sw_val = 0x00; + else + sw_val = 0xFF; + +// nes->SetRenderMethod( NES::PRE_ALL_RENDER ); +} + +BYTE Mapper090::ReadLow( WORD addr ) +{ +DEBUGOUT( "RD:%04X\n", addr ); + + switch( addr ) { + case 0x5000: + return sw_val?0x00:0xFF; + case 0x5800: + return (BYTE)(mul_val1*mul_val2); + case 0x5801: + return (BYTE)((mul_val1*mul_val2)>>8); + case 0x5803: + return key_val; + } + + if( addr >= 0x6000 ) { + return Mapper::ReadLow( addr ); + } + +// return sw_val?0x00:0xFF; + return (BYTE)(addr>>8); +} + +void Mapper090::WriteLow( WORD addr, BYTE data ) +{ +DEBUGOUT( "WR:%04X %02X\n", addr, data ); + + if( addr == 0x5800 ) { + mul_val1 = data; + } else + if( addr == 0x5801 ) { + mul_val2 = data; + } else + if( addr == 0x5803 ) { + key_val = data; + } +} + +void Mapper090::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF007 ) { + case 0x8000: + case 0x8001: + case 0x8002: + case 0x8003: + prg_reg[addr&3] = data; + SetBank_CPU(); + break; + + case 0x9000: + case 0x9001: + case 0x9002: + case 0x9003: + case 0x9004: + case 0x9005: + case 0x9006: + case 0x9007: + chl_reg[addr&7] = data; + SetBank_PPU(); + break; + + case 0xA000: + case 0xA001: + case 0xA002: + case 0xA003: + case 0xA004: + case 0xA005: + case 0xA006: + case 0xA007: + chh_reg[addr&7] = data; + SetBank_PPU(); + break; + + case 0xB000: + case 0xB001: + case 0xB002: + case 0xB003: + ntl_reg[addr&3] = data; + SetBank_VRAM(); + break; + + case 0xB004: + case 0xB005: + case 0xB006: + case 0xB007: + nth_reg[addr&3] = data; + SetBank_VRAM(); + break; + + case 0xC002: + irq_enable = 0; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC003: + irq_enable = 0xFF; + irq_preset = 0xFF; + break; + case 0xC004: + break; + case 0xC005: + if( irq_offset & 0x80 ) { + irq_latch = data ^ (irq_offset | 1); + } else { + irq_latch = data | (irq_offset&0x27); + } + irq_preset = 0xFF; + break; + case 0xC006: + if( patch ) { + irq_offset = data; + } + break; + + case 0xD000: + prg_6000 = data & 0x80; + prg_E000 = data & 0x04; + prg_size = data & 0x03; + chr_size = (data & 0x18)>>3; + mir_mode = data & 0x20; + SetBank_CPU(); + SetBank_PPU(); + SetBank_VRAM(); + break; + + case 0xD001: + mir_type = data & 0x03; + SetBank_VRAM(); + break; + + case 0xD003: + break; + } +} + +void Mapper090::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_preset ) { + irq_counter = irq_latch; + irq_preset = 0; + } + if( irq_counter ) { + irq_counter--; + } + if( !irq_counter ) { + if( irq_enable ) { +// irq_occur = 0xFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper090::Clock(INT cycles) +{ +// if( irq_occur ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper090::SetBank_CPU() +{ + if( prg_size == 0 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } else + if( prg_size == 1 ) { + SetPROM_32K_Bank( prg_reg[1]*2, prg_reg[1]*2+1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } else + if( prg_size == 2 ) { + if( prg_E000 ) { + SetPROM_32K_Bank( prg_reg[0], prg_reg[1], prg_reg[2], prg_reg[3] ); + } else { + if( prg_6000 ) { + SetPROM_8K_Bank( 3, prg_reg[3] ); + } + SetPROM_32K_Bank( prg_reg[0], prg_reg[1], prg_reg[2], PROM_8K_SIZE-1 ); + } + } else { + SetPROM_32K_Bank( prg_reg[3], prg_reg[2], prg_reg[1], prg_reg[0] ); + } +} + +void Mapper090::SetBank_PPU() +{ +INT bank[8]; + + for( INT i = 0; i < 8; i++ ) { + bank[i] = ((INT)chh_reg[i]<<8)|((INT)chl_reg[i]); + } + + if( chr_size == 0 ) { + SetVROM_8K_Bank( bank[0] ); + } else + if( chr_size == 1 ) { + SetVROM_4K_Bank( 0, bank[0] ); + SetVROM_4K_Bank( 4, bank[4] ); + } else + if( chr_size == 2 ) { + SetVROM_2K_Bank( 0, bank[0] ); + SetVROM_2K_Bank( 2, bank[2] ); + SetVROM_2K_Bank( 4, bank[4] ); + SetVROM_2K_Bank( 6, bank[6] ); + } else { + SetVROM_8K_Bank( bank[0], bank[1], bank[2], bank[3], bank[4], bank[5], bank[6], bank[7] ); + } +} + +void Mapper090::SetBank_VRAM() +{ +INT bank[4]; + + for( INT i = 0; i < 4; i++ ) { + bank[i] = ((INT)nth_reg[i]<<8)|((INT)ntl_reg[i]); + } + + if( !patch && mir_mode ) { + for( INT i = 0; i < 4; i++ ) { + if( !nth_reg[i] && (ntl_reg[i] == (BYTE)i) ) { + mir_mode = 0; + } + } + + if( mir_mode ) { + SetVROM_1K_Bank( 8, bank[0] ); + SetVROM_1K_Bank( 9, bank[1] ); + SetVROM_1K_Bank( 10, bank[2] ); + SetVROM_1K_Bank( 11, bank[3] ); + } + } else { + if( mir_type == 0 ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else + if( mir_type == 1 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_MIRROR4L ); + } + } +} + +void Mapper090::SaveState( LPBYTE p ) +{ +INT i; + + for( i = 0; i < 4; i++ ) { + p[i] = prg_reg[i]; + } + for( i = 0; i < 8; i++ ) { + p[i+ 4] = chh_reg[i]; + } + for( i = 0; i < 8; i++ ) { + p[i+12] = chl_reg[i]; + } + for( i = 0; i < 4; i++ ) { + p[i+20] = nth_reg[i]; + } + for( i = 0; i < 4; i++ ) { + p[i+24] = ntl_reg[i]; + } + p[28] = irq_enable; + p[29] = irq_counter; + p[30] = irq_latch; + p[31] = prg_6000; + p[32] = prg_E000; + p[33] = prg_size; + p[34] = chr_size; + p[35] = mir_mode; + p[36] = mir_type; + p[37] = mul_val1; + p[38] = mul_val2; + p[39] = key_val; + p[40] = irq_occur; + p[41] = irq_preset; + p[42] = irq_offset; +} + +void Mapper090::LoadState( LPBYTE p ) +{ +INT i; + + for( i = 0; i < 4; i++ ) { + prg_reg[i] = p[i]; + } + for( i = 0; i < 8; i++ ) { + chh_reg[i] = p[i+ 4]; + } + for( i = 0; i < 8; i++ ) { + chl_reg[i] = p[i+12]; + } + for( i = 0; i < 4; i++ ) { + nth_reg[i] = p[i+20]; + } + for( i = 0; i < 4; i++ ) { + ntl_reg[i] = p[i+24]; + } + irq_enable = p[28]; + irq_counter = p[29]; + irq_latch = p[30]; + prg_6000 = p[31]; + prg_E000 = p[32]; + prg_size = p[33]; + chr_size = p[34]; + mir_mode = p[35]; + mir_type = p[36]; + mul_val1 = p[37]; + mul_val2 = p[38]; + key_val = p[39]; + irq_occur = p[40]; + irq_preset = p[41]; + irq_offset = p[42]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper090.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper090.h new file mode 100644 index 00000000..7061c618 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper090.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper090 PC-JY-?? // +////////////////////////////////////////////////////////////////////////// +class Mapper090 : public Mapper +{ +public: + Mapper090( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow (WORD addr); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + + void HSync(INT scanline); + void Clock(INT cycles); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + + BYTE prg_reg[4]; + BYTE nth_reg[4], ntl_reg[4]; + BYTE chh_reg[8], chl_reg[8]; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_occur; + BYTE irq_preset; + BYTE irq_offset; + + BYTE prg_6000, prg_E000; + BYTE prg_size, chr_size; + BYTE mir_mode, mir_type; + + BYTE key_val; + BYTE mul_val1, mul_val2; + BYTE sw_val; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_VRAM(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper091.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper091.cpp new file mode 100644 index 00000000..5c933be7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper091.cpp @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper091 PC-HK-SF3 // +////////////////////////////////////////////////////////////////////////// +void Mapper091::Reset() +{ + SetPROM_32K_Bank( PROM_8K_SIZE-2, PROM_8K_SIZE-1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0, 0, 0, 0, 0, 0, 0, 0 ); + } + + irq_enable = 0; + irq_counter = 0; + + nes->SetRenderMethod( NES::POST_ALL_RENDER ); +} + +void Mapper091::WriteLow( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X:$%02X(%3d) L=%3d\n", addr, data, data, nes->GetScanline() ); + switch( addr & 0xF003 ) { + case 0x6000: + case 0x6001: + case 0x6002: + case 0x6003: + SetVROM_2K_Bank( (addr&0x03)*2, data ); + break; + + case 0x7000: + DEBUGOUT( "(7000)dat = %3x\n", data ); + SetPROM_8K_Bank( 4, data ); + break; + case 0x7001: + DEBUGOUT( "(7001)dat = %3x\n", data ); + SetPROM_8K_Bank( 5, data ); + break; + + case 0x7002: + irq_enable = 0; + irq_counter = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x7003: + irq_enable = 1; + break; + } +} + +void Mapper091::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline < 240) && nes->ppu->IsDispON() ) { + if( irq_enable ) { + irq_counter++; + } + if( irq_counter >= 8 ) { +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper091::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; +} + +void Mapper091::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper091.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper091.h new file mode 100644 index 00000000..10cc2072 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper091.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper091 PC-HK-SF3 // +////////////////////////////////////////////////////////////////////////// +class Mapper091 : public Mapper +{ +public: + Mapper091( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_counter; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper092.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper092.cpp new file mode 100644 index 00000000..36ffe4c6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper092.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper092 Jaleco/Type1 Higher bank switch // +////////////////////////////////////////////////////////////////////////// +void Mapper092::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper092::Write( WORD addr, BYTE data ) +{ + data = addr & 0xFF; + + if( addr >= 0x9000 ) { + if( (data & 0xF0) == 0xD0 ) { + SetPROM_16K_Bank( 6, data & 0x0F ); + } else if( (data & 0xF0) == 0xE0 ) { + SetVROM_8K_Bank( data & 0x0F ); + } + } else { + if( (data & 0xF0) == 0xB0 ) { + SetPROM_16K_Bank( 6, data & 0x0F ); + } else if( (data & 0xF0) == 0x70 ) { + SetVROM_8K_Bank( data & 0x0F ); + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper092.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper092.h new file mode 100644 index 00000000..5778a4e5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper092.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper092 Jaleco/Type1 Higher bank switch // +////////////////////////////////////////////////////////////////////////// +class Mapper092 : public Mapper +{ +public: + Mapper092( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper093.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper093.cpp new file mode 100644 index 00000000..b81a6bc2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper093.cpp @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper093 SunSoft (Fantasy Zone) // +////////////////////////////////////////////////////////////////////////// +void Mapper093::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper093::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x6000 ) { + SetPROM_16K_Bank( 4, data ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper093.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper093.h new file mode 100644 index 00000000..014a7a5e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper093.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper093 SunSoft (Fantasy Zone) // +////////////////////////////////////////////////////////////////////////// +class Mapper093 : public Mapper +{ +public: + Mapper093( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper094.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper094.cpp new file mode 100644 index 00000000..8d5b07fb --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper094.cpp @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper094 Capcom 74161/32 // +////////////////////////////////////////////////////////////////////////// +void Mapper094::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper094::Write( WORD addr, BYTE data ) +{ + if( (addr&0xFFF0) == 0xFF00 ) { + SetPROM_16K_Bank( 4, (data>>2)&0x7 ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper094.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper094.h new file mode 100644 index 00000000..a45c5daa --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper094.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper094 Capcom 74161/32 // +////////////////////////////////////////////////////////////////////////// +class Mapper094 : public Mapper +{ +public: + Mapper094( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper095.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper095.cpp new file mode 100644 index 00000000..51901eea --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper095.cpp @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper095 Namcot 106M (Dragon Buster) // +////////////////////////////////////////////////////////////////////////// +void Mapper095::Reset() +{ + reg = 0x00; + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + if( VROM_1K_SIZE ) { + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + } else { + chr01 = chr23 = chr4 = chr5 = chr6 = chr7 = 0; + } + + SetBank_PPU(); + + nes->SetRenderMethod( NES::POST_RENDER ); +} + +void Mapper095::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + if( reg <= 0x05 ) { + if( data & 0x20 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + data &= 0x1F; + } + + switch( reg & 0x07 ) { + case 0x00: + if( VROM_1K_SIZE ) { + chr01 = data & 0xFE; + SetBank_PPU(); + } + break; + case 0x01: + if( VROM_1K_SIZE ) { + chr23 = data & 0xFE; + SetBank_PPU(); + } + break; + case 0x02: + if( VROM_1K_SIZE ) { + chr4 = data; + SetBank_PPU(); + } + break; + case 0x03: + if( VROM_1K_SIZE ) { + chr5 = data; + SetBank_PPU(); + } + break; + case 0x04: + if( VROM_1K_SIZE ) { + chr6 = data; + SetBank_PPU(); + } + break; + case 0x05: + if( VROM_1K_SIZE ) { + chr7 = data; + SetBank_PPU(); + } + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + } +} + +void Mapper095::SetBank_CPU() +{ + if( reg & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper095::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } +} + +void Mapper095::SaveState( LPBYTE p ) +{ + p[0] = reg; + p[1] = prg0; + p[2] = prg1; + p[3] = chr01; + p[4] = chr23; + p[5] = chr4; + p[6] = chr5; + p[7] = chr6; + p[8] = chr7; +} + +void Mapper095::LoadState( LPBYTE p ) +{ + reg = p[0]; + prg0 = p[1]; + prg1 = p[2]; + chr01 = p[3]; + chr23 = p[4]; + chr4 = p[5]; + chr5 = p[6]; + chr6 = p[7]; + chr7 = p[8]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper095.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper095.h new file mode 100644 index 00000000..cfb9b8f6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper095.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper095 Namcot 106M (Dragon Buster) // +////////////////////////////////////////////////////////////////////////// +class Mapper095 : public Mapper +{ +public: + Mapper095( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper096.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper096.cpp new file mode 100644 index 00000000..06415fe6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper096.cpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper096 Bandai 74161 // +////////////////////////////////////////////////////////////////////////// +void Mapper096::Reset() +{ + reg[0] = reg[1] = 0; + + SetPROM_32K_Bank( 0, 1, 2, 3 ); + SetBank(); + + SetVRAM_Mirror( VRAM_MIRROR4L ); +} + +void Mapper096::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( data & 0x03 ); + + reg[0] = (data & 0x04) >> 2; + SetBank(); +} + +void Mapper096::PPU_Latch( WORD addr ) +{ + if( (addr & 0xF000) == 0x2000 ) { + reg[1] = (addr>>8)&0x03; + SetBank(); + } +} + +void Mapper096::SetBank() +{ + SetCRAM_4K_Bank( 0, reg[0]*4+reg[1] ); + SetCRAM_4K_Bank( 4, reg[0]*4+0x03 ); +} + +void Mapper096::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; +} + +void Mapper096::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper096.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper096.h new file mode 100644 index 00000000..e89518d7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper096.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper096 Bandai 74161 // +////////////////////////////////////////////////////////////////////////// +class Mapper096 : public Mapper +{ +public: + Mapper096( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + void PPU_Latch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[2]; + +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper097.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper097.cpp new file mode 100644 index 00000000..519a9a6d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper097.cpp @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper097 Irem 74161 // +////////////////////////////////////////////////////////////////////////// +void Mapper097::Reset() +{ + SetPROM_32K_Bank( PROM_8K_SIZE-2, PROM_8K_SIZE-1, 0, 1 ); + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper097::Write( WORD addr, BYTE data ) +{ + if( addr < 0xC000 ) { + SetPROM_16K_Bank( 6, data & 0x0F ); + + if( data & 0x80 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else SetVRAM_Mirror( VRAM_HMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper097.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper097.h new file mode 100644 index 00000000..538e41c2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper097.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper097 Irem 74161 // +////////////////////////////////////////////////////////////////////////// +class Mapper097 : public Mapper +{ +public: + Mapper097( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper099.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper099.cpp new file mode 100644 index 00000000..9312422f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper099.cpp @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper099 VS-Unisystem // +////////////////////////////////////////////////////////////////////////// + +void Mapper099::Reset() +{ + // set CPU bank pointers + if( PROM_8K_SIZE > 2 ) { + SetPROM_32K_Bank( 0, 1, 2, 3 ); + } else if( PROM_8K_SIZE > 1 ) { + SetPROM_32K_Bank( 0, 1, 0, 1 ); + } else { + SetPROM_32K_Bank( 0, 0, 0, 0 ); + } + + // set VROM bank + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + coin = 0; +} + +BYTE Mapper099::ExRead( WORD addr ) +{ + if( addr == 0x4020 ) { + return coin; + } + + return addr>>8; +} + +void Mapper099::ExWrite( WORD addr, BYTE data ) +{ + if( addr == 0x4016 ) { + if( data & 0x04 ) { + SetVROM_8K_Bank( 1 ); + } else { + SetVROM_8K_Bank( 0 ); + } + + if( nes->rom->GetPROM_CRC() == 0xC99EC059 ) { // VS Raid on Bungeling Bay(J) + if( data & 0x02 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + } + } + + if( addr == 0x4020 ) { + coin = data; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper099.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper099.h new file mode 100644 index 00000000..40c67562 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper099.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper099 VS-Unisystem // +////////////////////////////////////////////////////////////////////////// +class Mapper099 : public Mapper +{ +public: + Mapper099( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ExRead( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + +protected: + BYTE coin; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper100.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper100.cpp new file mode 100644 index 00000000..30f41470 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper100.cpp @@ -0,0 +1,242 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper100 Nesticle MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper100::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + SetBank_CPU(); + + if( VROM_1K_SIZE ) { + chr0 = 0; + chr1 = 1; + chr2 = 2; + chr3 = 3; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + } else { + chr0 = chr2 = chr4 = chr5 = chr6 = chr7 = 0; + chr1 = chr3 = 1; + } + + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; +} + +void Mapper100::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0xC7 ) { + case 0x00: + if( VROM_1K_SIZE ) { + chr0 = data&0xFE; + chr1 = chr0+1; + SetBank_PPU(); + } + break; + case 0x01: + if( VROM_1K_SIZE ) { + chr2 = data&0xFE; + chr3 = chr2+1; + SetBank_PPU(); + } + break; + case 0x02: + if( VROM_1K_SIZE ) { + chr4 = data; + SetBank_PPU(); + } + break; + case 0x03: + if( VROM_1K_SIZE ) { + chr5 = data; + SetBank_PPU(); + } + break; + case 0x04: + if( VROM_1K_SIZE ) { + chr6 = data; + SetBank_PPU(); + } + break; + case 0x05: + if( VROM_1K_SIZE ) { + chr7 = data; + SetBank_PPU(); + } + break; + + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + case 0x46: + prg2 = data; + SetBank_CPU(); + break; + case 0x47: + prg3 = data; + SetBank_CPU(); + break; + + case 0x80: + if( VROM_1K_SIZE ) { + chr4 = data&0xFE; + chr5 = chr4+1; + SetBank_PPU(); + } + break; + case 0x81: + if( VROM_1K_SIZE ) { + chr6 = data&0xFE; + chr7 = chr6+1; + SetBank_PPU(); + } + break; + case 0x82: + if( VROM_1K_SIZE ) { + chr0 = data; + SetBank_PPU(); + } + break; + case 0x83: + if( VROM_1K_SIZE ) { + chr1 = data; + SetBank_PPU(); + } + break; + case 0x84: + if( VROM_1K_SIZE ) { + chr2 = data; + SetBank_PPU(); + } + break; + case 0x85: + if( VROM_1K_SIZE ) { + chr3 = data; + SetBank_PPU(); + } + break; + + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 0xFF; + break; + } +} + +void Mapper100::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper100::SetBank_CPU() +{ + SetPROM_32K_Bank( prg0, prg1, prg2, prg3 ); +} + +void Mapper100::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7 ); + } +} + +void Mapper100::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = prg2; + p[11] = prg3; + p[12] = chr0; + p[13] = chr1; + p[14] = chr2; + p[15] = chr3; + p[16] = chr4; + p[17] = chr5; + p[18] = chr6; + p[19] = chr7; + p[20] = irq_enable; + p[21] = irq_counter; + p[22] = irq_latch; +} + +void Mapper100::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + prg2 = p[10]; + prg3 = p[11]; + chr0 = p[12]; + chr1 = p[13]; + chr2 = p[14]; + chr3 = p[15]; + chr4 = p[16]; + chr5 = p[17]; + chr6 = p[18]; + chr7 = p[19]; + irq_enable = p[20]; + irq_counter = p[21]; + irq_latch = p[22]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper100.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper100.h new file mode 100644 index 00000000..40cd6e4b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper100.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper100 Nesticle MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper100 : public Mapper +{ +public: + Mapper100( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1, prg2, prg3; + BYTE chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper101.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper101.cpp new file mode 100644 index 00000000..1c70c63f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper101.cpp @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper101 Jaleco(Urusei Yatsura) // +////////////////////////////////////////////////////////////////////////// +void Mapper101::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper101::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x6000 ) { + SetVROM_8K_Bank( data&0x03 ); + } +} + +void Mapper101::Write( WORD addr, BYTE data ) +{ + SetVROM_8K_Bank( data&0x03 ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper101.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper101.h new file mode 100644 index 00000000..a790093a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper101.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper101 Jaleco(Urusei Yatsura) // +////////////////////////////////////////////////////////////////////////// +class Mapper101 : public Mapper +{ +public: + Mapper101( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper105.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper105.cpp new file mode 100644 index 00000000..5b4661c2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper105.cpp @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper105 Nintendo World Championship // +////////////////////////////////////////////////////////////////////////// + +void Mapper105::Reset() +{ + SetPROM_32K_Bank( 0 ); + + reg[0] = 0x0C; + reg[1] = 0x00; + reg[2] = 0x00; + reg[3] = 0x10; + + bits = 0; + write_count = 0; + + irq_counter = 0; + irq_enable = 0; + init_state = 0; +} + +void Mapper105::Write( WORD addr, BYTE data ) +{ + WORD reg_num = (addr & 0x7FFF) >> 13; + + if( data & 0x80 ) { + bits = write_count = 0; + if( reg_num == 0 ) { + reg[reg_num] |= 0x0C; + } + } else { + bits |= (data & 1) << write_count++; + if( write_count == 5) { + reg[reg_num] = bits & 0x1F; + bits = write_count = 0; + } + } + + if( reg[0] & 0x02 ) { + if( reg[0] & 0x01 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + } else { + if( reg[0] & 0x01 ) { + SetVRAM_Mirror( VRAM_MIRROR4H ); + } else { + SetVRAM_Mirror( VRAM_MIRROR4L ); + } + } + + switch( init_state ) { + case 0: + case 1: + init_state++; + break; + case 2: + if(reg[1] & 0x08) { + if (reg[0] & 0x08) { + if (reg[0] & 0x04) { + SetPROM_8K_Bank(4,((reg[3] & 0x07) * 2 + 16)); + SetPROM_8K_Bank(5,((reg[3] & 0x07) * 2 + 17)); + SetPROM_8K_Bank(6,30); + SetPROM_8K_Bank(7,31); + } else { + SetPROM_8K_Bank(4,16); + SetPROM_8K_Bank(5,17); + SetPROM_8K_Bank(6,((reg[3] & 0x07) * 2 + 16)); + SetPROM_8K_Bank(7,((reg[3] & 0x07) * 2 + 17)); + } + } else { + SetPROM_8K_Bank(4,((reg[3] & 0x06) * 2 + 16)); + SetPROM_8K_Bank(5,((reg[3] & 0x06) * 2 + 17)); + SetPROM_8K_Bank(6,((reg[3] & 0x06) * 2 + 18)); + SetPROM_8K_Bank(7,((reg[3] & 0x06) * 2 + 19)); + } + } else { + SetPROM_8K_Bank(4,((reg[1] & 0x06) * 2 + 0)); + SetPROM_8K_Bank(5,((reg[1] & 0x06) * 2 + 1)); + SetPROM_8K_Bank(6,((reg[1] & 0x06) * 2 + 2)); + SetPROM_8K_Bank(7,((reg[1] & 0x06) * 2 + 3)); + } + + if( reg[1] & 0x10 ) { + irq_counter = 0; + irq_enable = 0; + } else { + irq_enable = 1; + } +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + default: + break; + } +} + +void Mapper105::HSync( INT scanline ) +{ + if( !scanline ) { + if( irq_enable ) { + irq_counter += 29781; + } + if( ((irq_counter | 0x21FFFFFF) & 0x3E000000) == 0x3E000000 ) { +// nes->cpu->IRQ_NotPending(); +// nes->cpu->SetIRQ( IRQ_MAPPER ); + nes->cpu->SetIRQ( IRQ_TRIGGER2 ); + } + } +} + +void Mapper105::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 4; i++ ) { + p[i] = reg[i]; + } + p[ 8] = init_state; + p[ 9] = write_count; + p[10] = bits; + p[11] = irq_enable; + *((INT*)&p[12]) = irq_counter; +} + +void Mapper105::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 4; i++ ) { + reg[i] = p[i]; + } + init_state = p[ 8]; + write_count = p[ 9]; + bits = p[10]; + irq_enable = p[11]; + irq_counter = *((INT*)&p[12]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper105.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper105.h new file mode 100644 index 00000000..6b2ae374 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper105.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper105 Nintendo World Championship // +////////////////////////////////////////////////////////////////////////// +class Mapper105 : public Mapper +{ +public: + Mapper105( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE init_state; + BYTE write_count; + BYTE bits; + BYTE reg[4]; + + BYTE irq_enable; + INT irq_counter; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper107.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper107.cpp new file mode 100644 index 00000000..bfd68a91 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper107.cpp @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper107 Magic Dragon Mapper // +////////////////////////////////////////////////////////////////////////// +void Mapper107::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper107::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( (data>>1)&0x03 ); + SetVROM_8K_Bank( data&0x07 ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper107.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper107.h new file mode 100644 index 00000000..951f4435 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper107.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper107 Magic Dragon Mapper // +////////////////////////////////////////////////////////////////////////// +class Mapper107 : public Mapper +{ +public: + Mapper107( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper108.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper108.cpp new file mode 100644 index 00000000..19be58f8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper108.cpp @@ -0,0 +1,13 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper108 // +////////////////////////////////////////////////////////////////////////// +void Mapper108::Reset() +{ + SetPROM_32K_Bank( 0xC,0xD,0xE,0xF ); + SetPROM_8K_Bank( 3, 0 ); +} + +void Mapper108::Write( WORD addr, BYTE data ) +{ + SetPROM_8K_Bank( 3, data ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper108.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper108.h new file mode 100644 index 00000000..ff1a687d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper108.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper108 // +////////////////////////////////////////////////////////////////////////// +class Mapper108 : public Mapper +{ +public: + Mapper108( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper109.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper109.cpp new file mode 100644 index 00000000..08e31a44 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper109.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper109 SACHEN The Great Wall SA-019 // +////////////////////////////////////////////////////////////////////////// + +void Mapper109::Reset() +{ + reg = 0; + SetPROM_32K_Bank( 0 ); + + chr0 = 0; + chr1 = 0; + chr2 = 0; + chr3 = 0; + SetBank_PPU(); + chrmode0 = 0; + chrmode1 = 0; +} + +void Mapper109::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x4100: + reg = data; + break; + case 0x4101: + switch( reg ) { + case 0: + chr0 = data; + SetBank_PPU(); + break; + case 1: + chr1 = data; + SetBank_PPU(); + break; + case 2: + chr2 = data; + SetBank_PPU(); + break; + case 3: + chr3 = data; + SetBank_PPU(); + break; + case 4: + chrmode0 = data & 0x01; + SetBank_PPU(); + break; + case 5: + SetPROM_32K_Bank( data & 0x07 ); + break; + case 6: + chrmode1 = data & 0x07; + SetBank_PPU(); + break; + case 7: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } + break; + } + +} + +void Mapper109::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 0, chr0 ); + SetVROM_1K_Bank( 1, chr1|((chrmode1<<3)&0x8) ); + SetVROM_1K_Bank( 2, chr2|((chrmode1<<2)&0x8) ); + SetVROM_1K_Bank( 3, chr3|((chrmode1<<1)&0x8) |(chrmode0*0x10) ); + SetVROM_1K_Bank( 4, VROM_1K_SIZE-4 ); + SetVROM_1K_Bank( 5, VROM_1K_SIZE-3 ); + SetVROM_1K_Bank( 6, VROM_1K_SIZE-2 ); + SetVROM_1K_Bank( 7, VROM_1K_SIZE-1 ); + } +} + +void Mapper109::SaveState( LPBYTE p ) +{ + p[ 0] = reg; + p[ 1] = chr0; + p[ 2] = chr1; + p[ 3] = chr2; + p[ 4] = chr3; + p[ 5] = chrmode0; + p[ 6] = chrmode1; +} + +void Mapper109::LoadState( LPBYTE p ) +{ + reg = p[ 0]; + chr0 = p[ 1]; + chr1 = p[ 2]; + chr2 = p[ 3]; + chr3 = p[ 4]; + chrmode0 = p[ 5]; + chrmode1 = p[ 6]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper109.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper109.h new file mode 100644 index 00000000..c95061a3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper109.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper109 SACHEN The Great Wall SA-019 // +////////////////////////////////////////////////////////////////////////// +class Mapper109 : public Mapper +{ +public: + Mapper109( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; + BYTE chr0, chr1, chr2, chr3; + BYTE chrmode0, chrmode1; + +private: + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper110.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper110.cpp new file mode 100644 index 00000000..c8d9601d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper110.cpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper110 // +////////////////////////////////////////////////////////////////////////// +void Mapper110::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); + + reg0 = 0; + reg1 = 0; +} +void Mapper110::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x4100: + reg1 = data & 0x07; + break; + case 0x4101: + switch( reg1 ) { + case 5: + SetPROM_32K_Bank( data ); + break; + case 0: + reg0 = data & 0x01; + SetVROM_8K_Bank( reg0 ); + break; + case 2: + reg0 = data; + SetVROM_8K_Bank( reg0 ); + break; + case 4: + reg0 = reg0 | (data<<1); + SetVROM_8K_Bank( reg0 ); + break; + case 6: + reg0 = reg0 | (data<<2); + SetVROM_8K_Bank( reg0 ); + break; + default: + break; + } + break; + default: + break; + } +} + +void Mapper110::SaveState( LPBYTE p ) +{ + p[ 0] = reg0; + p[ 1] = reg1; +} + +void Mapper110::LoadState( LPBYTE p ) +{ + reg0 = p[ 0]; + reg1 = p[ 1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper110.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper110.h new file mode 100644 index 00000000..0f3245dc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper110.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper110 // +////////////////////////////////////////////////////////////////////////// +class Mapper110 : public Mapper +{ +public: + Mapper110( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg0, reg1; +private: +}; \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper111.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper111.cpp new file mode 100644 index 00000000..d4e83c9d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper111.cpp @@ -0,0 +1,199 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper111 Nintendo MMC1 // +////////////////////////////////////////////////////////////////////////// +void Mapper111::Reset() +{ + reg[0] = 0x0C; // D3=1,D2=1 + reg[1] = reg[2] = reg[3] = 0; + shift = regbuf = 0; + + patch = 0; + wram_patch = 0; + + if( PROM_16K_SIZE < 32 ) { + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } else { + // For 512K/1M byte Cartridge + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 16-1 ); + + patch = 1; + } + + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + // Ninja Ryukenden(J) + nes->SetRenderMethod( NES::POST_ALL_RENDER ); +} + +void Mapper111::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "MMC1 %04X=%02X\n", addr&0xFFFF,data&0xFF ); + + if( data & 0x80 ) { + shift = regbuf = 0; + reg[0] |= 0x0C; // D3=1,D2=1 c̓ZbgȂ + return; + } + + addr = (addr&0x7FFF)>>13; + reg[addr] = data; + +// DEBUGOUT( "MMC1 %d=%02X\n", addr&0xFFFF,regbuf&0xFF ); + + if( patch != 1 ) { + // For Normal Cartridge + switch( addr ) { + case 0: + if( reg[0] & 0x02 ) { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + break; + case 1: + // Register #1 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank lower($0000-$0FFF) + SetVROM_4K_Bank( 0, reg[1] ); + // CHR 4K bank higher($1000-$1FFF) + SetVROM_4K_Bank( 4, reg[2] ); + } else { + // CHR 8K bank($0000-$1FFF) + SetVROM_8K_Bank( reg[1]>>1 ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 0, reg[1] ); + } + } + break; + case 2: + // Register #2 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank lower($0000-$0FFF) + SetVROM_4K_Bank( 0, reg[1] ); + // CHR 4K bank higher($1000-$1FFF) + SetVROM_4K_Bank( 4, reg[2] ); + } else { + // CHR 8K bank($0000-$1FFF) + SetVROM_8K_Bank( reg[1]>>1 ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 4, reg[2] ); + } + } + break; + case 3: + if( !(reg[0] & 0x08) ) { + // PRG 32K bank ($8000-$FFFF) + SetPROM_32K_Bank( reg[3]>>1 ); + } else { + if( reg[0] & 0x04 ) { + // PRG 16K bank ($8000-$BFFF) + SetPROM_16K_Bank( 4, reg[3] ); + SetPROM_16K_Bank( 6, PROM_16K_SIZE-1 ); + } else { + // PRG 16K bank ($C000-$FFFF) + SetPROM_16K_Bank( 6, reg[3] ); + SetPROM_16K_Bank( 4, 0 ); + } + } + break; + } + } else { + // For 512K/1M byte Cartridge + INT PROM_BASE = 0; + if( PROM_16K_SIZE >= 32 ) { + PROM_BASE = reg[1] & 0x10; + } + + // Register #0 + if( addr == 0 ) { + if( reg[0] & 0x02 ) { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + if( reg[0] & 0x01 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + else SetVRAM_Mirror( VRAM_MIRROR4L ); + } + } + // Register #1 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank lower($0000-$0FFF) + SetVROM_4K_Bank( 0, reg[1] ); + } else { + // CHR 8K bank($0000-$1FFF) + SetVROM_8K_Bank( reg[1]>>1 ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 0, reg[1] ); + } + } + // Register #2 + if( VROM_1K_SIZE ) { + if( reg[0] & 0x10 ) { + // CHR 4K bank higher($1000-$1FFF) + SetVROM_4K_Bank( 4, reg[2] ); + } + } else { + // For Romancia + if( reg[0] & 0x10 ) { + SetCRAM_4K_Bank( 4, reg[2] ); + } + } + // Register #3 + if( !(reg[0] & 0x08) ) { + // PRG 32K bank ($8000-$FFFF) + SetPROM_32K_Bank( (reg[3]&(0xF+PROM_BASE))>>1 ); + } else { + if( reg[0] & 0x04 ) { + // PRG 16K bank ($8000-$BFFF) + SetPROM_16K_Bank( 4, PROM_BASE+(reg[3]&0x0F) ); + if( PROM_16K_SIZE >= 32 ) SetPROM_16K_Bank( 6, PROM_BASE+16-1 ); + } else { + // PRG 16K bank ($C000-$FFFF) + SetPROM_16K_Bank( 6, PROM_BASE+(reg[3]&0x0F) ); + if( PROM_16K_SIZE >= 32 ) SetPROM_16K_Bank( 4, PROM_BASE ); + } + } + } +} + +void Mapper111::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = reg[3]; + p[4] = shift; + p[5] = regbuf; + + p[6] = wram_bank; + p[7] = wram_count; +} + +void Mapper111::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + reg[3] = p[3]; + shift = p[4]; + regbuf = p[5]; + + wram_bank = p[6]; + wram_count = p[7]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper111.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper111.h new file mode 100644 index 00000000..05c2baf4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper111.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper111 Nintendo MMC1 Hack // +////////////////////////////////////////////////////////////////////////// +class Mapper111 : public Mapper +{ +public: + Mapper111( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + WORD last_addr; + + BYTE patch; + BYTE wram_patch; + BYTE wram_bank; + BYTE wram_count; + + BYTE reg[4]; + BYTE shift, regbuf; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper112.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper112.cpp new file mode 100644 index 00000000..cdaea744 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper112.cpp @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper112 ASDER Mapper // +////////////////////////////////////////////////////////////////////////// + +void Mapper112::Reset() +{ + for( INT i = 0; i < 4; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); +} + +void Mapper112::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0xA000: + reg[1] = data; + switch( reg[0] & 0x07 ) { + case 0x00: + prg0 = (data&(PROM_8K_SIZE-1)); + SetBank_CPU(); + break; + case 0x01: + prg1 = (data&(PROM_8K_SIZE-1)); + SetBank_CPU(); + break; + case 0x02: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x03: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x04: + chr4 = data; + SetBank_PPU(); + break; + case 0x05: + chr5 = data; + SetBank_PPU(); + break; + case 0x06: + chr6 = data; + SetBank_PPU(); + break; + case 0x07: + chr7 = data; + SetBank_PPU(); + break; + } + break; + + case 0xC000: + reg[3] = data; + SetBank_PPU(); + + case 0xE000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + SetBank_PPU(); + break; + } +} + +void Mapper112::SetBank_CPU() +{ + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper112::SetBank_PPU() +{ + if( reg[2] & 0x02 ) { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, chr4, chr5, chr6, chr7 ); + } else { + SetVROM_8K_Bank(((reg[3]<<6)&0x100)+chr01, + ((reg[3]<<6)&0x100)+chr01+1, + ((reg[3]<<5)&0x100)+chr23, + ((reg[3]<<5)&0x100)+chr23+1, + ((reg[3]<<4)&0x100)+chr4, + ((reg[3]<<3)&0x100)+chr5, + ((reg[3]<<2)&0x100)+chr6, + ((reg[3]<<1)&0x100)+chr7 ); + } +} + +void Mapper112::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 4; i++ ) { + p[i] = reg[i]; + } + p[ 4] = chr01; + p[ 5] = chr23; + p[ 6] = chr4; + p[ 7] = chr5; + p[ 8] = chr6; + p[ 9] = chr7; +} + +void Mapper112::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 4; i++ ) { + reg[i] = p[i]; + } + + chr01 = p[ 4]; + chr23 = p[ 5]; + chr4 = p[ 6]; + chr5 = p[ 7]; + chr6 = p[ 8]; + chr7 = p[ 9]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper112.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper112.h new file mode 100644 index 00000000..e2005a33 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper112.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper112 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper112 : public Mapper +{ +public: + Mapper112( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[4]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper113.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper113.cpp new file mode 100644 index 00000000..9ed3741f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper113.cpp @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper113 PC-Sachen/Hacker // +////////////////////////////////////////////////////////////////////////// +void Mapper113::Reset() +{ +// SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper113::WriteLow( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X:$%02X L=%3d\n", addr, data, nes->GetScanline() ); + switch( addr ) { + case 0x4100: + case 0x4111: + case 0x4120: + case 0x4194: + case 0x4195: + case 0x4900: + if( nes->rom->GetPROM_CRC() == 0xA75AEDE5 ) { // HES 6-in-1 + if( data & 0x80 ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + SetVRAM_Mirror( VRAM_HMIRROR ); + } + } + SetPROM_32K_Bank( data >> 3 ); + SetVROM_8K_Bank( ((data>>3)&0x08)+(data&0x07) ); + break; + } +} + +void Mapper113::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X:$%02X L=%3d\n", addr, data, nes->GetScanline() ); + switch( addr ) { + case 0x8008: + case 0x8009: + SetPROM_32K_Bank( data >> 3 ); + SetVROM_8K_Bank( ((data>>3)&0x08)+(data&0x07) ); + break; + case 0x8E66: + case 0x8E67: + SetVROM_8K_Bank( (data&0x07)?0:1 ); + break; + case 0xE00A: + SetVRAM_Mirror( VRAM_MIRROR4L ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper113.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper113.h new file mode 100644 index 00000000..1e0c7e2b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper113.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper113 PC-Sachen/Hacker // +////////////////////////////////////////////////////////////////////////// +class Mapper113 : public Mapper +{ +public: + Mapper113( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper114.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper114.cpp new file mode 100644 index 00000000..0f28380a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper114.cpp @@ -0,0 +1,133 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper114 // +////////////////////////////////////////////////////////////////////////// +void Mapper114::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + reg_a = reg_c = reg_m = 0; + for( INT i = 0; i < 8; i++ ) { + reg_b[i] = 0; + } + irq_counter = 0; + irq_occur = 0; + + nes->SetRenderMethod( NES::POST_RENDER ); +} + +void Mapper114::WriteLow( WORD addr, BYTE data ) +{ + reg_m = data; + SetBank_CPU(); +} + +void Mapper114::Write( WORD addr, BYTE data ) +{ + if( addr == 0xE003 ) { + irq_counter = data; + } else + if( addr == 0xE002 ) { + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } else { + switch( addr & 0xE000 ) { + case 0x8000: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0xA000: + reg_c = 1; + reg_a = data; + break; + case 0xC000: + if( !reg_c ) { + break; + } + reg_b[reg_a&0x07] = data; + switch( reg_a & 0x07 ) { + case 0: + case 1: + case 2: + case 3: + case 6: + case 7: + SetBank_PPU(); + break; + case 4: + case 5: + SetBank_CPU(); + break; + } + reg_c = 0; + break; + } + } +} + +void Mapper114::Clock( INT scanline ) +{ +// if( irq_occur ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper114::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( irq_counter ) { + irq_counter--; + if( !irq_counter ) { + irq_occur = 0xFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +} + +void Mapper114::SetBank_CPU() +{ + if( reg_m & 0x80 ) { + SetPROM_16K_Bank( 4, reg_m & 0x1F ); + } else { + SetPROM_8K_Bank( 4, reg_b[4] ); + SetPROM_8K_Bank( 5, reg_b[5] ); + } +} + +void Mapper114::SetBank_PPU() +{ + SetVROM_2K_Bank( 0, reg_b[0]>>1 ); + SetVROM_2K_Bank( 2, reg_b[2]>>1 ); + SetVROM_1K_Bank( 4, reg_b[6] ); + SetVROM_1K_Bank( 5, reg_b[1] ); + SetVROM_1K_Bank( 6, reg_b[7] ); + SetVROM_1K_Bank( 7, reg_b[3] ); +} + +void Mapper114::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg_b[i]; + } + + p[ 8] = reg_m; + p[ 9] = reg_a; + p[10] = reg_c; + p[11] = irq_counter; + p[12] = irq_occur; +} + +void Mapper114::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg_b[i] = p[i]; + } + reg_m = p[ 8]; + reg_a = p[ 9]; + reg_c = p[10]; + irq_counter = p[11]; + irq_occur = p[12]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper114.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper114.h new file mode 100644 index 00000000..1256e202 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper114.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper114 // +////////////////////////////////////////////////////////////////////////// +class Mapper114 : public Mapper +{ +public: + Mapper114( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); +protected: + BYTE reg_m, reg_a, reg_b[8]; + BYTE reg_c; + BYTE irq_counter; + BYTE irq_occur; +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper115.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper115.cpp new file mode 100644 index 00000000..cf84c44f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper115.cpp @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper115 CartSaint : Yuu Yuu Hakusho Final // +// JusticePao(?) // +////////////////////////////////////////////////////////////////////////// + +void Mapper115::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = prg0L = 0; + prg1 = prg1L = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + + ExPrgSwitch = 0; + ExChrSwitch = 0; + + SetBank_CPU(); + + if( VROM_1K_SIZE ) { + chr0 = 0; + chr1 = 1; + chr2 = 2; + chr3 = 3; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + } else { + chr0 = chr2 = chr4 = chr5 = chr6 = chr7 = 0; + chr1 = chr3 = 1; + } + + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; +} + + +void Mapper115::WriteLow( WORD addr, BYTE data ) +{ + switch ( addr ){ + case 0x6000: + ExPrgSwitch = data; //data + SetBank_CPU(); + break; + case 0x6001: + ExChrSwitch = data&0x1; + SetBank_PPU(); + break; + } + Mapper::WriteLow( addr, data ); +} + + +void Mapper115::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x07 ) { + case 0x00: + chr0 = data & 0xFE; + chr1 = chr0+1; + SetBank_PPU(); + break; + case 0x01: + chr2 = data & 0xFE; + chr3 = chr2+1; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = prg0L = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = prg1L = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_enable = 0xFF; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 0xFF; + break; + } +} + +void Mapper115::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + + +void Mapper115::SetBank_CPU() +{ + if( ExPrgSwitch & 0x80 ) { + prg0 = ((ExPrgSwitch<<1)&0x1e); + prg1 = prg0+1; + + SetPROM_32K_Bank( prg0, prg1, prg0+2, prg1+2); + } else { + prg0 = prg0L; + prg1 = prg1L; + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } + } +} + +void Mapper115::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( (ExChrSwitch<<8)+chr4, (ExChrSwitch<<8)+chr5, + (ExChrSwitch<<8)+chr6, (ExChrSwitch<<8)+chr7, + (ExChrSwitch<<8)+chr0, (ExChrSwitch<<8)+chr1, + (ExChrSwitch<<8)+chr2, (ExChrSwitch<<8)+chr3 ); + } else { + SetVROM_8K_Bank( (ExChrSwitch<<8)+chr0, (ExChrSwitch<<8)+chr1, + (ExChrSwitch<<8)+chr2, (ExChrSwitch<<8)+chr3, + (ExChrSwitch<<8)+chr4, (ExChrSwitch<<8)+chr5, + (ExChrSwitch<<8)+chr6, (ExChrSwitch<<8)+chr7 ); + } + } +} + +void Mapper115::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = prg2; + p[11] = prg3; + p[12] = chr0; + p[13] = chr1; + p[14] = chr2; + p[15] = chr3; + p[16] = chr4; + p[17] = chr5; + p[18] = chr6; + p[19] = chr7; + p[20] = irq_enable; + p[21] = irq_counter; + p[22] = irq_latch; + p[23] = ExPrgSwitch; + p[24] = prg0L; + p[25] = prg1L; + p[26] = ExChrSwitch; + +} + +void Mapper115::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + prg2 = p[10]; + prg3 = p[11]; + chr0 = p[12]; + chr1 = p[13]; + chr2 = p[14]; + chr3 = p[15]; + chr4 = p[16]; + chr5 = p[17]; + chr6 = p[18]; + chr7 = p[19]; + irq_enable = p[20]; + irq_counter = p[21]; + irq_latch = p[22]; + ExPrgSwitch = p[23]; + prg0L = p[24]; + prg1L = p[25]; + ExChrSwitch = p[26]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper115.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper115.h new file mode 100644 index 00000000..31dad40c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper115.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper115 CartSaint : Yuu Yuu Hakusho Final // +// JusticePao(?) // +////////////////////////////////////////////////////////////////////////// +class Mapper115 : public Mapper +{ +public: + Mapper115( NES* parent ) : Mapper(parent) {} + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1, prg2, prg3; + BYTE prg0L, prg1L; + BYTE chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + + BYTE ExPrgSwitch; + BYTE ExChrSwitch; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116.cpp new file mode 100644 index 00000000..786a5542 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116.cpp @@ -0,0 +1,257 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper116 CartSaint : HVAV` // +////////////////////////////////////////////////////////////////////////// + +void Mapper116::Reset() +{ + mode = 0; + vrc2_chr[0] = 0; + vrc2_chr[1] = 1; + vrc2_chr[2] = 2; + vrc2_chr[3] = 3; + vrc2_chr[4] = 4; + vrc2_chr[5] = 5; + vrc2_chr[6] = 6; + vrc2_chr[7] = 7; + vrc2_prg[0] = 0; + vrc2_prg[1] = 1; + vrc2_mirr = 0; + mmc3_regs[0] = 0; + mmc3_regs[1] = 2; + mmc3_regs[2] = 4; + mmc3_regs[3] = 5; + mmc3_regs[4] = 6; + mmc3_regs[5] = 7; + mmc3_regs[6] = 0x3C; + mmc3_regs[7] = 0x3D; + mmc3_regs[8] = 0xFE; + mmc3_regs[9] = 0xFF; + mmc3_ctrl = mmc3_mirr = 0; + IRQCount = IRQLatch = IRQa = 0; + mmc1_regs[0] = 0xc; + mmc1_regs[1] = 0; + mmc1_regs[2] = 0; + mmc1_regs[3] = 0; + mmc1_buffer = 0; + mmc1_shift = 0; + SetBank_CPU(); + SetBank_PPU(); + SetBank_MIR(); +} + +void Mapper116::WriteLow( WORD addr, BYTE data ) +{ +DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if ((addr&0x4100)==0x4100) { + mode = data; + if (addr&1) { + mmc1_regs[0] = 0xc; + mmc1_regs[3] = 0; + mmc1_buffer = 0; + mmc1_shift = 0; + } + SetBank_CPU(); + SetBank_PPU(); + SetBank_MIR(); + } + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +void Mapper116::Write( WORD addr, BYTE data ) +{ +DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch (mode & 3) { + case 0: + if ((addr >= 0xB000) && (addr <= 0xE003)) { + int32 ind = ((((addr & 2) | (addr >> 10)) >> 1) + 2) & 7; + int32 sar = ((addr & 1) << 2); + vrc2_chr[ind] = (vrc2_chr[ind] & (0xF0 >> sar)) | ((data & 0x0F) << sar); + SetBank_PPU(); + } else + switch (addr & 0xF000) { + case 0x8000: vrc2_prg[0] = data; SetBank_CPU(); break; + case 0xA000: vrc2_prg[1] = data; SetBank_CPU(); break; + case 0x9000: vrc2_mirr = data; SetBank_MIR(); break; + } + break; + case 1: + switch (addr & 0xE001) { + case 0x8000: + addr = mmc3_ctrl ^ data; + mmc3_ctrl = data; + if (addr & 0x40) SetBank_CPU(); + if (addr & 0x87) SetBank_PPU(); + break; + case 0x8001: + addr = mmc3_ctrl & 0x7; + if (addr<2) data>>= 1; + if (mmc3_regs[addr] != data){ + mmc3_regs[addr] = data; + if (addr<6) SetBank_PPU(); + else SetBank_CPU(); + } + break; + case 0xA000: + mmc3_mirr = data; + SetBank_MIR(); + break; + case 0xC000: + IRQCount = data; + break; + case 0xC001: + IRQLatch = data; + break; + case 0xE000: + IRQCount = IRQLatch; + IRQa = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + IRQa = 0xFF; + break; + } + break; + case 2: + case 3: + if (data & 0x80) { + mmc1_regs[0] |= 0xc; + mmc1_buffer = mmc1_shift = 0; + SetBank_CPU(); + } else { + uint8 n = (addr >> 13) - 4; + mmc1_buffer |= (data & 1) << (mmc1_shift++); + if (mmc1_shift == 5) { + mmc1_regs[n] = mmc1_buffer; + mmc1_buffer = mmc1_shift = 0; + switch (n) { + case 0: SetBank_MIR(); + case 2: SetBank_PPU(); + case 3: + case 1: SetBank_CPU(); + } + } + } + break; + } +} + +void Mapper116::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( IRQCount <= 0 ) { + if( IRQa ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + return; + } + } + if(nes->ppu->IsDispON() ) { + IRQCount--; + } + } +} + +void Mapper116::SetBank_CPU() +{ + switch (mode & 3) { + case 0: + SetPROM_8K_Bank(4, vrc2_prg[0]); + SetPROM_8K_Bank(5, vrc2_prg[1]); + SetPROM_8K_Bank(6, 0x1E); + SetPROM_8K_Bank(7, 0x1F); + break; + case 1: + { + uint32 swap = (mmc3_ctrl >> 5) & 2; + SetPROM_8K_Bank(4, mmc3_regs[6 + swap]); + SetPROM_8K_Bank(5, mmc3_regs[7]); + SetPROM_8K_Bank(6, mmc3_regs[6 + (swap^2)]); + SetPROM_8K_Bank(7, mmc3_regs[9]); + break; + } + case 2: + case 3: + { + uint8 bank = mmc1_regs[3] & 0xF; + if (mmc1_regs[0] & 8) { + if (mmc1_regs[0] & 4) { + SetPROM_16K_Bank(4, bank); + SetPROM_16K_Bank(6, 0x0F); + } else { + SetPROM_16K_Bank(4, 0); + SetPROM_16K_Bank(6, bank); + } + } else SetPROM_32K_Bank(bank>>1); + break; + } + } +} +void Mapper116::SetBank_PPU() +{ + uint32 base = (mode & 4) << 6; + switch (mode & 3) { + case 0: + SetVROM_1K_Bank(0, base | vrc2_chr[0]); + SetVROM_1K_Bank(1, base | vrc2_chr[1]); + SetVROM_1K_Bank(2, base | vrc2_chr[2]); + SetVROM_1K_Bank(3, base | vrc2_chr[3]); + SetVROM_1K_Bank(4, base | vrc2_chr[4]); + SetVROM_1K_Bank(5, base | vrc2_chr[5]); + SetVROM_1K_Bank(6, base | vrc2_chr[6]); + SetVROM_1K_Bank(7, base | vrc2_chr[7]); + break; + case 1: { + uint32 swap = (mmc3_ctrl & 0x80) << 5; + SetVROM_2K_Bank(((0x0000^swap)>>10)+0,base>>1 | mmc3_regs[0]); + SetVROM_2K_Bank(((0x0000^swap)>>10)+2,base>>1 | mmc3_regs[1]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+0,base|mmc3_regs[2]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+1,base|mmc3_regs[3]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+2,base|mmc3_regs[4]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+3,base|mmc3_regs[5]); + break; + } + case 2: + case 3: + if (mmc1_regs[0] & 0x10) { + SetVROM_4K_Bank(0, mmc1_regs[1]); + SetVROM_4K_Bank(4, mmc1_regs[2]); + } else + SetVROM_8K_Bank(mmc1_regs[1] >> 1); + break; + } +} +void Mapper116::SetBank_MIR() +{ + switch (mode & 3) { + case 0: { + if(vrc2_mirr&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + break; + } + case 1: { + if(mmc3_mirr&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } + case 2: + case 3: { + switch (mmc1_regs[0] & 3) { + case 0: SetVRAM_Mirror( VRAM_MIRROR4L ); break; + case 1: SetVRAM_Mirror( VRAM_MIRROR4H ); break; + case 2: SetVRAM_Mirror( VRAM_VMIRROR ); break; + case 3: SetVRAM_Mirror( VRAM_HMIRROR ); break; + } + break; + } + } +} + +void Mapper116::SaveState( LPBYTE p ) +{ + // +} + +void Mapper116::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116.h new file mode 100644 index 00000000..9314cd93 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper116 CartSaint : HVAV` // +////////////////////////////////////////////////////////////////////////// +class Mapper116 : public Mapper +{ +public: + Mapper116( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE mode; + BYTE vrc2_chr[8], vrc2_prg[2], vrc2_mirr; + BYTE mmc3_regs[10], mmc3_ctrl, mmc3_mirr; + BYTE mmc1_regs[4], mmc1_buffer, mmc1_shift; + BYTE IRQCount, IRQLatch, IRQa; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_MIR(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116_old.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116_old.cpp new file mode 100644 index 00000000..9de461a3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116_old.cpp @@ -0,0 +1,565 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper116 CartSaint : HVAV` // +////////////////////////////////////////////////////////////////////////// + +void Mapper116::Reset() +{ +/* + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = prg0L = 0; + prg1 = prg1L = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + + ExPrgSwitch = 0; + ExChrSwitch = 0; + + SetBank_CPU(); + + if( VROM_1K_SIZE ) { + chr0 = 0; + chr1 = 1; + chr2 = 2; + chr3 = 3; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + } else { + chr0 = chr2 = chr4 = chr5 = chr6 = chr7 = 0; + chr1 = chr3 = 1; + } + + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + +// nes->SetFrameIRQmode( FALSE ); +*/ + mode = 0; + vrc2_chr[0] = 0; + vrc2_chr[1] = 1; + vrc2_chr[2] = 2; + vrc2_chr[3] = 3; + vrc2_chr[4] = 4; + vrc2_chr[5] = 5; + vrc2_chr[6] = 6; + vrc2_chr[7] = 7; + vrc2_prg[0] = 0; + vrc2_prg[1] = 1; + vrc2_mirr = 0; + mmc3_regs[0] = 0; + mmc3_regs[1] = 2; + mmc3_regs[2] = 4; + mmc3_regs[3] = 5; + mmc3_regs[4] = 6; + mmc3_regs[5] = 7; + mmc3_regs[6] = 0x3C; + mmc3_regs[7] = 0x3D; + mmc3_regs[8] = 0xFE; + mmc3_regs[9] = 0xFF; + mmc3_ctrl = mmc3_mirr = 0; + IRQCount = IRQLatch = IRQa = 0; + mmc1_regs[0] = 0xc; + mmc1_regs[1] = 0; + mmc1_regs[2] = 0; + mmc1_regs[3] = 0; + mmc1_buffer = 0; + mmc1_shift = 0; + SetBank_CPU(); + SetBank_PPU(); + SetBank_MIR(); + +} + +void Mapper116::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); +/* + if( (addr & 0x4100) == 0x4100 ) { + ExChrSwitch = data; + SetBank_PPU(); + } +*/ + if ((addr&0x4100)==0x4100) { + mode = data; + if (addr&1) { + mmc1_regs[0] = 0xc; + mmc1_regs[3] = 0; + mmc1_buffer = 0; + mmc1_shift = 0; + } +// if ((data&0x3)!=1) +// { +// IRQCount = IRQLatch; +// IRQa = 0; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); +// } + SetBank_CPU(); + SetBank_PPU(); + SetBank_MIR(); + } + +} + +void Mapper116::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); +/* + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x07 ) { + case 0x00: + chr0 = data & 0xFE; + chr1 = chr0+1; + SetBank_PPU(); + break; + case 0x01: + chr2 = data & 0xFE; + chr3 = chr2+1; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; +// irq_enable = 0xFF; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_counter = irq_latch; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 0xFF; + break; + } +*/ + switch (mode & 3) { + case 0: { + if ((addr >= 0xB000) && (addr <= 0xE003)) { + int32 ind = ((((addr & 2) | (addr >> 10)) >> 1) + 2) & 7; + int32 sar = ((addr & 1) << 2); + vrc2_chr[ind] = (vrc2_chr[ind] & (0xF0 >> sar)) | ((data & 0x0F) << sar); + SetBank_PPU(); + } else + switch (addr & 0xF000) { + case 0x8000: vrc2_prg[0] = data; SetBank_CPU(); break; + case 0xA000: vrc2_prg[1] = data; SetBank_CPU(); break; + case 0x9000: vrc2_mirr = data; SetBank_MIR(); break; + } + break; + } + case 1: { + switch (addr & 0xE001) { + case 0x8000: +// uint8 old_ctrl = mmc3_ctrl; +// mmc3_ctrl = data; +// if ((old_ctrl & 0x40) != (mmc3_ctrl & 0x40)) +// SetBank_CPU(); +// if ((old_ctrl & 0x80) != (mmc3_ctrl & 0x80)) +// SetBank_PPU(); + + addr = mmc3_ctrl ^ data; + mmc3_ctrl = data; + if (addr & 0x40) + SetBank_CPU(); + if (addr & (0x80|0x07)) + SetBank_PPU(); + break; + case 0x8001: +// mmc3_regs[mmc3_ctrl & 7] = data; +// if ((mmc3_ctrl & 7) < 6) +// SetBank_PPU(); +// else +// SetBank_CPU(); + + addr = mmc3_ctrl & 0x7; + if (addr<2) data>>= 1; + if (mmc3_regs[addr] != data) + { + mmc3_regs[addr] = data; + if (addr<6) + SetBank_PPU(); + else + SetBank_CPU(); + } + break; + case 0xA000: + mmc3_mirr = data; + SetBank_MIR(); + break; + case 0xC000: + IRQCount = data; + break; + case 0xC001: + IRQLatch = data; + break; + case 0xE000: + IRQCount = IRQLatch; + IRQa = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + IRQa = 0xFF; + break; + } + break; + } + case 2: + case 3: { + if (data & 0x80) { + mmc1_regs[0] |= 0xc; + mmc1_buffer = mmc1_shift = 0; + SetBank_CPU(); + } else { + uint8 n = (addr >> 13) - 4; + mmc1_buffer |= (data & 1) << (mmc1_shift++); + if (mmc1_shift == 5) { + mmc1_regs[n] = mmc1_buffer; + mmc1_buffer = mmc1_shift = 0; + switch (n) { + case 0: SetBank_MIR(); + case 2: SetBank_PPU(); + case 3: + case 1: SetBank_CPU(); + } + } + } + break; + } + } + +} + +void Mapper116::HSync( INT scanline ) +{ +/* + if( (scanline >= 0 && scanline <= 239) ) { + if ((mode & 3) == 1) { + int32 count = IRQCount; + if (!count || IRQReload) { + IRQCount = IRQLatch; + IRQReload = 0; + } else + IRQCount--; + if (!IRQCount) { + if (IRQa) + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +*/ + if( (scanline >= 0 && scanline <= 239) ) { + if( IRQCount <= 0 ) { + if( IRQa ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + return; + } + } + + if(nes->ppu->IsDispON() ) { + IRQCount--; + } + } + +} + +/* +void Mapper116::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( irq_counter <= 0 ) { + if( irq_enable ) { +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + +#if 0 +DEBUGOUT( "IRQ L=%3d\n", scanline ); +{ +LPBYTE lpScn = nes->ppu->GetScreenPtr(); + + lpScn = lpScn+(256+16)*scanline; + + for( INT i = 0; i < 64; i++ ) { + lpScn[i] = 22; + } +} +#endif + return; + } + } + + if( nes->ppu->IsDispON() ) { + irq_counter--; + } + } + +#if 0 + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { +// irq_counter = irq_latch; + nes->cpu->IRQ_NotPending(); + } + } + } + } +#endif +} + +void Mapper116::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper116::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( ExChrSwitch & 0x04 ) { + INT chrbank = 256; + SetVROM_8K_Bank( chrbank+chr4, chrbank+chr5, + chrbank+chr6, chrbank+chr7, + chr0, chr1, + chr2, chr3 ); + } else { + INT chrbank = 0; + SetVROM_8K_Bank( chrbank+chr4, chrbank+chr5, + chrbank+chr6, chrbank+chr7, + chr0, chr1, + chr2, chr3 ); + } + +#if 0 + if( reg[0] & 0x80 ) { +// SetVROM_8K_Bank( chrbank+chr4, chrbank+chr5, +// chrbank+chr6, chrbank+chr7, +// chrbank+chr0, chrbank+chr1, +// chrbank+chr2, chrbank+chr3 ); + SetVROM_8K_Bank( chrbank+chr4, chrbank+chr5, + chrbank+chr6, chrbank+chr7, + chr0, chr1, + chr2, chr3 ); + } else { + SetVROM_8K_Bank( chr0, chr1, + chr2, chr3, + chrbank+chr4, chrbank+chr5, + chrbank+chr6, chrbank+chr7 ); + } +#endif + } +} +*/ + +void Mapper116::SetBank_CPU() +{ + switch (mode & 3) { + case 0: + SetPROM_8K_Bank(4, vrc2_prg[0]); + SetPROM_8K_Bank(5, vrc2_prg[1]); + SetPROM_8K_Bank(6, 0x1E); + SetPROM_8K_Bank(7, 0x1F); + break; + case 1: + { + uint32 swap = (mmc3_ctrl >> 5) & 2; + SetPROM_8K_Bank(4, mmc3_regs[6 + swap]); + SetPROM_8K_Bank(5, mmc3_regs[7]); + SetPROM_8K_Bank(6, mmc3_regs[6 + (swap^2)]); + SetPROM_8K_Bank(7, mmc3_regs[9]); + break; + } + case 2: + case 3: + { + uint8 bank = mmc1_regs[3] & 0xF; + if (mmc1_regs[0] & 8) { + if (mmc1_regs[0] & 4) { + SetPROM_16K_Bank(4, bank); + SetPROM_16K_Bank(6, 0x0F); + } else { + SetPROM_16K_Bank(4, 0); + SetPROM_16K_Bank(6, bank); + } + } else + SetPROM_32K_Bank(bank>>1); + break; + } + } +} +void Mapper116::SetBank_PPU() +{ + uint32 base = (mode & 4) << 6; + switch (mode & 3) { + case 0: + SetVROM_1K_Bank(0, base | vrc2_chr[0]); + SetVROM_1K_Bank(1, base | vrc2_chr[1]); + SetVROM_1K_Bank(2, base | vrc2_chr[2]); + SetVROM_1K_Bank(3, base | vrc2_chr[3]); + SetVROM_1K_Bank(4, base | vrc2_chr[4]); + SetVROM_1K_Bank(5, base | vrc2_chr[5]); + SetVROM_1K_Bank(6, base | vrc2_chr[6]); + SetVROM_1K_Bank(7, base | vrc2_chr[7]); + break; + case 1: { + uint32 swap = (mmc3_ctrl & 0x80) << 5; +// SetVROM_1K_Bank(((0x0000^swap)/0x400)+0, base | ((mmc3_regs[0]) & 0xFE)); +// SetVROM_1K_Bank(((0x0400^swap)/0x400)+1, base | (mmc3_regs[0] | 1)); +// SetVROM_1K_Bank(((0x0800^swap)/0x400)+2, base | ((mmc3_regs[1]) & 0xFE)); +// SetVROM_1K_Bank(((0x0c00^swap)/0x400)+3, base | (mmc3_regs[1] | 1)); +// SetVROM_1K_Bank(((0x1000^swap)/0x400)+4, base | mmc3_regs[2]); +// SetVROM_1K_Bank(((0x1400^swap)/0x400)+5, base | mmc3_regs[3]); +// SetVROM_1K_Bank(((0x1800^swap)/0x400)+6, base | mmc3_regs[4]); +// SetVROM_1K_Bank(((0x1c00^swap)/0x400)+7, base | mmc3_regs[5]); + SetVROM_2K_Bank(((0x0000^swap)>>10)+0,base >> 1 | mmc3_regs[0]); + SetVROM_2K_Bank(((0x0000^swap)>>10)+2,base >> 1 | mmc3_regs[1]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+0,base|mmc3_regs[2]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+1,base|mmc3_regs[3]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+2,base|mmc3_regs[4]); + SetVROM_1K_Bank(((0x1000^swap)>>10)+3,base|mmc3_regs[5]); + break; + } + case 2: + case 3: + if (mmc1_regs[0] & 0x10) { + SetVROM_4K_Bank(0, mmc1_regs[1]); + SetVROM_4K_Bank(4, mmc1_regs[2]); + } else + SetVROM_8K_Bank(mmc1_regs[1] >> 1); + break; + } +} +void Mapper116::SetBank_MIR() +{ + switch (mode & 3) { + case 0: { + if(vrc2_mirr&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + break; + } + case 1: { + if(mmc3_mirr&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } + case 2: + case 3: { + switch (mmc1_regs[0] & 3) { + case 0: SetVRAM_Mirror( VRAM_MIRROR4L ); break; + case 1: SetVRAM_Mirror( VRAM_MIRROR4H ); break; + case 2: SetVRAM_Mirror( VRAM_VMIRROR ); break; + case 3: SetVRAM_Mirror( VRAM_HMIRROR ); break; + } + break; + } + } +} + +void Mapper116::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = prg2; + p[11] = prg3; + p[12] = chr0; + p[13] = chr1; + p[14] = chr2; + p[15] = chr3; + p[16] = chr4; + p[17] = chr5; + p[18] = chr6; + p[19] = chr7; + p[20] = irq_enable; + p[21] = irq_counter; + p[22] = irq_latch; + p[23] = ExPrgSwitch; + p[24] = prg0L; + p[25] = prg1L; + p[26] = ExChrSwitch; +} + +void Mapper116::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + prg2 = p[10]; + prg3 = p[11]; + chr0 = p[12]; + chr1 = p[13]; + chr2 = p[14]; + chr3 = p[15]; + chr4 = p[16]; + chr5 = p[17]; + chr6 = p[18]; + chr7 = p[19]; + irq_enable = p[20]; + irq_counter = p[21]; + irq_latch = p[22]; + ExPrgSwitch = p[23]; + prg0L = p[24]; + prg1L = p[25]; + ExChrSwitch = p[26]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116_old.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116_old.h new file mode 100644 index 00000000..bd0f54e5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116_old.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper116 CartSaint : HVAV` // +////////////////////////////////////////////////////////////////////////// +class Mapper116 : public Mapper +{ +public: + Mapper116( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1, prg2, prg3; + BYTE prg0L, prg1L; + BYTE chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7; + + BYTE irq_enable; + INT irq_counter; + BYTE irq_latch; + + BYTE ExPrgSwitch; + BYTE ExChrSwitch; + + BYTE mode; + BYTE vrc2_chr[8], vrc2_prg[2], vrc2_mirr; + BYTE mmc3_regs[10], mmc3_ctrl, mmc3_mirr; + BYTE mmc1_regs[4], mmc1_buffer, mmc1_shift; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_MIR(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116b.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116b.cpp new file mode 100644 index 00000000..333d8605 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116b.cpp @@ -0,0 +1,445 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper116 CartSaint : HVAV` // +////////////////////////////////////////////////////////////////////////// + +void Mapper116::Reset() +{ + int i; + mode = 0; + + vrc2_prg[0] = 0x0; + vrc2_prg[1] = 0x1; + vrc2_nmt = 0; + + + for (i=0; i < 8; ++i) + vrc2_chr[i] = i; + + mmc3_ctrl = 0; + mmc3_nmt = 0; + + mmc3_banks[0] = 0x0; + mmc3_banks[1] = 0x1; + mmc3_banks[2] = 0x4; + mmc3_banks[3] = 0x5; + mmc3_banks[4] = 0x6; + mmc3_banks[5] = 0x7; + + mmc3_banks[6] = 0x3C; + mmc3_banks[7] = 0x3D; + mmc3_banks[8] = 0xFE; + mmc3_banks[9] = 0xFF; + + mmc1_buffer = 0; + mmc1_shifter = 0; + + mmc1_regs[0] = 0x4U|0x8U; + mmc1_regs[1] = 0; + mmc1_regs[2] = 0; + mmc1_regs[3] = 0; + + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + + NES_mapper116_MMC3_set_CPU_banks(); + NES_mapper116_MMC3_set_Nmt(); + NES_mapper116_MMC3_set_PPU_banks(); +} + + +void Mapper116::NES_mapper116_MMC3_set_CPU_banks() +{ + switch (mode & 0x3) + { + case 0x0: + SetPROM_32K_Bank(vrc2_prg[0], vrc2_prg[1], 0x1E, 0x1F); + break; + + case 0x1: + { + const uint32 i = mmc3_ctrl >> 5 & 0x2U; + SetPROM_32K_Bank(mmc3_banks[6+i],mmc3_banks[6+1],mmc3_banks[6+(i^2)],mmc3_banks[6+3] ); + break; + } + + case 0x2: + { + const uint32 bank = mmc1_regs[3] & 0xFU; + if (mmc1_regs[0] & 0x8U) + { + SetPROM_16K_Bank(4,(mmc1_regs[0] & 0x4U) ? bank : 0x0); + SetPROM_16K_Bank(6,(mmc1_regs[0] & 0x4U) ? 0xF : bank ); + } + else{ + SetPROM_32K_Bank( bank >> 1 ); + } + break; + } + } +} + + +void Mapper116::NES_mapper116_MMC3_set_PPU_banks() +{ + const uint32 base = (mode & 0x4) << 6; + + switch (mode & 0x3) + { + case 0x0: + SetVROM_8K_Bank( + base|vrc2_chr[0], + base|vrc2_chr[1], + base|vrc2_chr[2], + base|vrc2_chr[3], + base|vrc2_chr[4], + base|vrc2_chr[5], + base|vrc2_chr[6], + base|vrc2_chr[7] ); + break; + + case 0x1: + { + const uint32 swap = (mmc3_ctrl & 0x80U) << 5; + SetVROM_2K_Bank( (0x0000 ^ swap)/0x400+0,base >> 1 | mmc3_banks[0]); + SetVROM_2K_Bank( (0x0000 ^ swap)/0x400+2,base >> 1 | mmc3_banks[1]); + SetVROM_1K_Bank((0x1000 ^ swap)/0x400+0,base|mmc3_banks[2]); + SetVROM_1K_Bank((0x1000 ^ swap)/0x400+1,base|mmc3_banks[3]); + SetVROM_1K_Bank((0x1000 ^ swap)/0x400+2,base|mmc3_banks[4]); + SetVROM_1K_Bank((0x1000 ^ swap)/0x400+3,base|mmc3_banks[5]); + break; + } + + case 0x2: + SetVROM_4K_Bank(0,(mmc1_regs[0] & 0x10U) ? mmc1_regs[1] : mmc1_regs[1] & 0x1EU ); + SetVROM_4K_Bank(4,(mmc1_regs[0] & 0x10U) ? mmc1_regs[2] : mmc1_regs[1] | 0x01U ); + break; + } +} + + +void Mapper116::NES_mapper116_MMC3_set_Nmt() +{ + uint8 nmtCtrl = 0XFF; + switch (mode & 0x3) + { + case 0x0: + + nmtCtrl = (vrc2_nmt & 0x1U) ? VRAM_HMIRROR : VRAM_VMIRROR ; + break; + + case 0x1: + + nmtCtrl = (mmc3_nmt & 0x1U) ? VRAM_HMIRROR : VRAM_VMIRROR ; + break; + + case 0x2: + + switch (mmc1_regs[0] & 0x3U) + { + case 0x0: SetVRAM_Mirror(VRAM_MIRROR4L); break; + case 0x1: SetVRAM_Mirror(VRAM_MIRROR4H); break; + case 0x2: nmtCtrl =VRAM_VMIRROR; break; + default: nmtCtrl = VRAM_HMIRROR ; break; + } + break; + + default: return; + } + if(nmtCtrl!=0xff) + SetVRAM_Mirror(nmtCtrl); +} + + +void Mapper116::WriteLow( WORD addr, BYTE data ) +{ + + if( (addr & 0x4100) == 0x4100 ) + { + if (mode != data) + { + mode = data; + + if ((data & 0x3) != 1) + { + //nes6502_ClrIRQ( IRQ_MAPPER );//irq.unit.Disable( cpu ); + irq_counter = irq_latch; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + + NES_mapper116_MMC3_set_CPU_banks(); + NES_mapper116_MMC3_set_Nmt(); + NES_mapper116_MMC3_set_PPU_banks(); + } + } +} + + + + +void Mapper116::Mapper116_Poke_Vrc2_8000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 0 ); + + data &= 0x1F; + address = address >> 13 & 0x1; + + if (vrc2_prg[address] != data) + { + vrc2_prg[address] = data; + NES_mapper116_MMC3_set_CPU_banks(); + } +} + +void Mapper116::Mapper116_Poke_Vrc2_9000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 0 ); + + data &= 0x1; + + if (vrc2_nmt != data) + { + vrc2_nmt = data; + NES_mapper116_MMC3_set_Nmt(); + } +} + +void Mapper116::Mapper116_Poke_Vrc2_B000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 0 ); + + data = (data & 0xF) << (address << 1 & 0x4); + address = ((address - 0xB000) >> 11 & 0x6) | (address & 0x1); + + if (vrc2_chr[address] != data) + { + vrc2_chr[address] = data; + ;//ppu.Update(); + NES_mapper116_MMC3_set_PPU_banks(); + } +} + +void Mapper116::Mapper116_Poke_Mmc3_8000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 1 ); + + if (address & 0x1) + { + address = mmc3_ctrl & 0x7U; + + if (address < 2) + data >>= 1; + + if (mmc3_banks[address] != data) + { + mmc3_banks[address] = data; + + if (address < 6) + { + ;//ppu.Update(); + NES_mapper116_MMC3_set_PPU_banks(); + } + else + { + NES_mapper116_MMC3_set_CPU_banks(); + } + } + } + else + { + address = mmc3_ctrl ^ data; + mmc3_ctrl = data; + + if (address & 0x40) + NES_mapper116_MMC3_set_CPU_banks(); + + if (address & (0x80U|0x07U)) + { + //ppu.Update(); + NES_mapper116_MMC3_set_PPU_banks(); + } + } +} + +void Mapper116::Mapper116_Poke_Mmc3_A000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 1 ); + + if (!(address & 0x1)) + { + if (mmc3_nmt != data) + { + mmc3_nmt = data; + NES_mapper116_MMC3_set_Nmt(); + } + } +} + +void Mapper116::Mapper116_Poke_Mmc3_C000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 1 ); + + ;//irq.Update(); + + if (address & 0x1) + irq_latch = data;//irq.unit.Reload(); + else + irq_counter = data;//irq.unit.SetLatch( data ); +} + +void Mapper116::Mapper116_Poke_Mmc3_E000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 1 ); + + ;//irq.Update(); + + if (address & 0x1) + irq_enable = 0xFF;//Enable + else + { + irq_counter = irq_latch; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } +} + +void Mapper116::Mapper116_Poke_Mmc1_8000(uint32 address,uint32 data) +{ + //NST_ASSERT( (mode & 0x3) == 2 ); + + if (!(data & 0x80)) + { + mmc1_buffer |= + (data & 0x1) << mmc1_shifter++; + + if (mmc1_shifter != 5) + return; + + mmc1_shifter = 0; + data = mmc1_buffer; + mmc1_buffer = 0; + + address = address >> 13 & 0x3; + + if (mmc1_regs[address] != data) + { + mmc1_regs[address] = data; + + NES_mapper116_MMC3_set_CPU_banks(); + NES_mapper116_MMC3_set_Nmt(); + NES_mapper116_MMC3_set_PPU_banks(); + } + } + else + { + mmc1_buffer = 0; + mmc1_shifter = 0; + + if ((mmc1_regs[0] & (0x4U|0x8U)) != (0x4U|0x8U)) + { + mmc1_regs[0] |= (0x4U|0x8U); + + NES_mapper116_MMC3_set_CPU_banks(); + NES_mapper116_MMC3_set_Nmt(); + NES_mapper116_MMC3_set_PPU_banks(); + } + } +} + +void Mapper116::Write( WORD address, BYTE data ) +{ + switch( address & 0xF000 ) { + case 0x8000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_8000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_8000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + + case 0x9000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_9000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_8000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + + case 0xA000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_8000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_A000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + case 0xB000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_B000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_A000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + case 0xC000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_B000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_C000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + case 0xD000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_B000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_C000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + case 0xE000: + switch (mode & 0x3) + { + case 0x0: Mapper116_Poke_Vrc2_B000( address, data ); break; + case 0x1: Mapper116_Poke_Mmc3_E000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + case 0xF000: + switch (mode & 0x3) + { + case 0x0: break; + case 0x1: Mapper116_Poke_Mmc3_E000( address, data ); break; + case 0x2: Mapper116_Poke_Mmc1_8000( address, data ); break; + } + break; + } +} + + +void Mapper116::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( irq_counter <= 0 ) { + if( irq_enable ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + return; + } + } + + if(nes->ppu->IsDispON() ) { + irq_counter--; + } + } +} + +void Mapper116::SaveState( LPBYTE p ) +{ +} + +void Mapper116::LoadState( LPBYTE p ) +{ +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116b.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116b.h new file mode 100644 index 00000000..4d744a40 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper116b.h @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper116 CartSaint : HVAV` // +////////////////////////////////////////////////////////////////////////// + +class Mapper116 : public Mapper +{ +public: + Mapper116( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + uint32 mode; + + uint8 vrc2_chr[8]; + uint8 vrc2_prg[2]; + uint8 vrc2_nmt; + uint8 vrc2_padding; + + uint8 mmc3_banks[10]; + uint8 mmc3_ctrl; + uint8 mmc3_nmt; + + uint8 mmc1_regs[4]; + uint8 mmc1_buffer; + uint8 mmc1_shifter; + uint8 mmc1_padding[2]; + uint8 irq_enable ; // Disable + uint8 irq_counter ; + uint8 irq_latch ; + + uint8 exPreg; + +private: + void NES_mapper116_MMC3_set_CPU_banks(); + void NES_mapper116_MMC3_set_Nmt(); + void NES_mapper116_MMC3_set_PPU_banks(); + + + void Mapper116_Poke_Vrc2_8000(uint32 address,uint32 data); + void Mapper116_Poke_Vrc2_9000(uint32 address,uint32 data); + void Mapper116_Poke_Vrc2_B000(uint32 address,uint32 data); + void Mapper116_Poke_Mmc3_C000(uint32 address,uint32 data); + void Mapper116_Poke_Mmc3_E000(uint32 address,uint32 data); + void Mapper116_Poke_Mmc3_8000(uint32 address,uint32 data); + void Mapper116_Poke_Mmc3_A000(uint32 address,uint32 data); + void Mapper116_Poke_Mmc1_8000(uint32 address,uint32 data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper117.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper117.cpp new file mode 100644 index 00000000..109873e4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper117.cpp @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper117 San Ko Gu (TW) : // +////////////////////////////////////////////////////////////////////////// + +void Mapper117::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper117::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + case 0x8001: + SetPROM_8K_Bank( 5, data ); + break; + case 0x8002: + SetPROM_8K_Bank( 6, data ); + break; + case 0xA000: + SetVROM_1K_Bank( 0, data ); + break; + case 0xA001: + SetVROM_1K_Bank( 1, data ); + break; + case 0xA002: + SetVROM_1K_Bank( 2, data ); + break; + case 0xA003: + SetVROM_1K_Bank( 3, data ); + break; + case 0xA004: + SetVROM_1K_Bank( 4, data ); + break; + case 0xA005: + SetVROM_1K_Bank( 5, data ); + break; + case 0xA006: + SetVROM_1K_Bank( 6, data ); + break; + case 0xA007: + SetVROM_1K_Bank( 7, data ); + break; + case 0xC001: + case 0xC002: + case 0xC003: + irq_counter = data; + break; + case 0xE000: + irq_enable = data & 1; +// nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} +void Mapper117::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if(irq_counter==scanline) { + irq_counter = 0; +// nes->cpu->IRQ(); +// nes->cpu->SetIRQ( IRQ_MAPPER ); + nes->cpu->SetIRQ( IRQ_TRIGGER ); + } + } + } + } +} + +void Mapper117::SaveState( LPBYTE p ) +{ + p[0] = irq_counter; + p[1] = irq_enable; +} + +void Mapper117::LoadState( LPBYTE p ) +{ + irq_counter=p[0]; + irq_enable=p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper117.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper117.h new file mode 100644 index 00000000..6830645b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper117.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper117 Sanko Gu(Tw) // +////////////////////////////////////////////////////////////////////////// +class Mapper117 : public Mapper +{ +public: + Mapper117( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + void HSync( INT scanline ); + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); +protected: + BYTE irq_enable; + BYTE irq_counter; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118 - 副本.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118 - 副本.cpp new file mode 100644 index 00000000..83d7faf1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118 - 副本.cpp @@ -0,0 +1,203 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper118 IQS MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper118::Reset() +{ +INT i; + + for( i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + if( VROM_1K_SIZE ) { + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + + SetBank_PPU(); + } else { + chr01 = 0; + chr23 = 0; + chr4 = 0; + chr5 = 0; + chr6 = 0; + chr7 = 0; + } + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; +} + +void Mapper118::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); +} + +void Mapper118::Write( WORD addr, BYTE data ) +{ + + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + if( (reg[0] & 0x07) < 6 ) { + if( data & 0x80 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + } + + switch( reg[0] & 0x07 ) { + case 0x00: + if( VROM_1K_SIZE ) { + chr01 = data & 0xFE; + SetBank_PPU(); + } + break; + case 0x01: + if( VROM_1K_SIZE ) { + chr23 = data & 0xFE; + SetBank_PPU(); + } + break; + case 0x02: + if( VROM_1K_SIZE ) { + chr4 = data; + SetBank_PPU(); + } + break; + case 0x03: + if( VROM_1K_SIZE ) { + chr5 = data; + SetBank_PPU(); + } + break; + case 0x04: + if( VROM_1K_SIZE ) { + chr6 = data; + SetBank_PPU(); + } + break; + case 0x05: + if( VROM_1K_SIZE ) { + chr7 = data; + SetBank_PPU(); + } + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + + case 0xC000: + reg[4] = data; + irq_counter = data; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + break; + } +} + +void Mapper118::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper118::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper118::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } +} + +void Mapper118::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; +} + +void Mapper118::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118 - 副本.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118 - 副本.h new file mode 100644 index 00000000..8b13a422 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118 - 副本.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper118 IQS MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper118 : public Mapper +{ +public: + Mapper118( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + + void HSync(INT scanline); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118.cpp new file mode 100644 index 00000000..edcb4db3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118.cpp @@ -0,0 +1,211 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper118 IQS MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper118::Reset() +{ +INT i; + + for( i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + if( VROM_1K_SIZE ) { + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + + SetBank_PPU(); + } else { + chr01 = 0; + chr23 = 0; + chr4 = 0; + chr5 = 0; + chr6 = 0; + chr7 = 0; + } + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; +} + +void Mapper118::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); +} + +void Mapper118::Write( WORD addr, BYTE data ) +{ + + switch( addr & 0xE001 ) { + case 0x8000: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + reg[1] = data; + +// if( (reg[0] & 0x07) < 6 ) { +// if( data & 0x80 ) SetVRAM_Mirror( VRAM_MIRROR4L ); +// else SetVRAM_Mirror( VRAM_MIRROR4H ); +// } + + switch( reg[0] & 0x07 ) { + case 0x00: + if( VROM_1K_SIZE ) { + chr01 = (data<<1) & 0xFE; + SetBank_PPU(); + } + break; + case 0x01: + if( VROM_1K_SIZE ) { + chr23 = (data<<1) & 0xFE; + SetBank_PPU(); + } + break; + case 0x02: + if( VROM_1K_SIZE ) { + chr4 = (data<<1); + SetBank_PPU(); + } + break; + case 0x03: + if( VROM_1K_SIZE ) { + chr5 = (data<<1); + SetBank_PPU(); + } + break; + case 0x04: + if( VROM_1K_SIZE ) { + chr6 = (data<<1); + SetBank_PPU(); + } + break; + case 0x05: + if( VROM_1K_SIZE ) { + chr7 = (data<<1); + SetBank_PPU(); + } + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + + case 0xA000: + data &= 0x03; + if ( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if ( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if ( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0xC000: + reg[4] = data; + irq_counter = data; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + break; + } +} + +void Mapper118::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper118::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper118::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } +} + +void Mapper118::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; +} + +void Mapper118::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118.h new file mode 100644 index 00000000..8b13a422 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper118.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper118 IQS MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper118 : public Mapper +{ +public: + Mapper118( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + + void HSync(INT scanline); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper119.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper119.cpp new file mode 100644 index 00000000..cb5a1757 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper119.cpp @@ -0,0 +1,218 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper119 TQ-ROM // +////////////////////////////////////////////////////////////////////////// +void Mapper119::Reset() +{ + patch = 0; + + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; +} + +void Mapper119::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + if( VROM_1K_SIZE ) { + chr01 = data & 0xFE; + SetBank_PPU(); + } + break; + case 0x01: + if( VROM_1K_SIZE ) { + chr23 = data & 0xFE; + SetBank_PPU(); + } + break; + case 0x02: + if( VROM_1K_SIZE ) { + chr4 = data; + SetBank_PPU(); + } + break; + case 0x03: + if( VROM_1K_SIZE ) { + chr5 = data; + SetBank_PPU(); + } + break; + case 0x04: + if( VROM_1K_SIZE ) { + chr6 = data; + SetBank_PPU(); + } + break; + case 0x05: + if( VROM_1K_SIZE ) { + chr7 = data; + SetBank_PPU(); + } + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_counter = irq_latch; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + break; + } +} + +void Mapper119::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper119::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper119::SetBank_PPU() +{ + if( reg[0]&0x80 ) { + if( chr4&0x40 ) SetCRAM_1K_Bank( 0, chr4&0x07 ); + else SetVROM_1K_Bank( 0, chr4 ); + if( chr5&0x40 ) SetCRAM_1K_Bank( 1, chr5&0x07 ); + else SetVROM_1K_Bank( 1, chr5 ); + if( chr6&0x40 ) SetCRAM_1K_Bank( 2, chr6&0x07 ); + else SetVROM_1K_Bank( 2, chr6 ); + if( chr7&0x40 ) SetCRAM_1K_Bank( 3, chr7&0x07 ); + else SetVROM_1K_Bank( 3, chr7 ); + + if( (chr01+0)&0x40 ) SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + else SetVROM_1K_Bank( 4, (chr01+0) ); + if( (chr01+1)&0x40 ) SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + else SetVROM_1K_Bank( 5, (chr01+1) ); + if( (chr23+0)&0x40 ) SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + else SetVROM_1K_Bank( 6, (chr23+0) ); + if( (chr23+1)&0x40 ) SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + else SetVROM_1K_Bank( 7, (chr23+1) ); + } else { + if( (chr01+0)&0x40 ) SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + else SetVROM_1K_Bank( 0, (chr01+0) ); + if( (chr01+1)&0x40 ) SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + else SetVROM_1K_Bank( 1, (chr01+1) ); + if( (chr23+0)&0x40 ) SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + else SetVROM_1K_Bank( 2, (chr23+0) ); + if( (chr23+1)&0x40 ) SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + else SetVROM_1K_Bank( 3, (chr23+1) ); + + if( chr4&0x40 ) SetCRAM_1K_Bank( 4, chr4&0x07 ); + else SetVROM_1K_Bank( 4, chr4 ); + if( chr5&0x40 ) SetCRAM_1K_Bank( 5, chr5&0x07 ); + else SetVROM_1K_Bank( 5, chr5 ); + if( chr6&0x40 ) SetCRAM_1K_Bank( 6, chr6&0x07 ); + else SetVROM_1K_Bank( 6, chr6 ); + if( chr7&0x40 ) SetCRAM_1K_Bank( 7, chr7&0x07 ); + else SetVROM_1K_Bank( 7, chr7 ); + } +} + +void Mapper119::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; +} + +void Mapper119::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper119.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper119.h new file mode 100644 index 00000000..6cd9f030 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper119.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper119 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper119 : public Mapper +{ +public: + Mapper119( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper120.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper120.cpp new file mode 100644 index 00000000..b9749608 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper120.cpp @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper120 Tobidase Daisakusen // +////////////////////////////////////////////////////////////////////////// +void Mapper120::Reset() +{ + SetPROM_8K_Bank( 3, 8 ); + SetPROM_32K_Bank( 0 ); +// SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper120::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x41FF ) { + SetPROM_8K_Bank( 3, data + 8 ); + } else { + Mapper::WriteLow( addr, data ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper120.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper120.h new file mode 100644 index 00000000..fa6d9027 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper120.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper120 Tobidase Daisakusen // +////////////////////////////////////////////////////////////////////////// +class Mapper120 : public Mapper +{ +public: + Mapper120( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121 - 副本.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121 - 副本.cpp new file mode 100644 index 00000000..ce71a8de --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121 - 副本.cpp @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper121 // +////////////////////////////////////////////////////////////////////////// + +void Mapper121::Reset() +{ + EXPREGS[3] = 0x80; + EXPREGS[5] = 0; + IRQReload = IRQCount = IRQLatch = IRQa = 0; + MMC3cmd = A000B = A001B = 0; + + DRegBuf[0] = 0; + DRegBuf[1] = 2; + DRegBuf[2] = 4; + DRegBuf[3] = 5; + DRegBuf[4] = 6; + DRegBuf[5] = 7; + DRegBuf[6] = 0; + DRegBuf[7] = 1; + + Fix121MMC3PRG(MMC3cmd); + Fix121MMC3CHR(MMC3cmd); +} + +BYTE Mapper121::ReadLow( WORD addr ) +{ + DEBUGOUT( "MPRWR A=%04X L=%3d CYC=%d\n", addr&0xFFFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if((addr>=0x5000)&&(addr<=0x5FFF)) return EXPREGS[4]; + if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void Mapper121::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if((addr>=0x5000)&&(addr<=0x5FFF)){ + const uint8 prot_array[4] = { 0x83, 0x83, 0x42, 0x00 }; + EXPREGS[4] = prot_array[data & 3]; + if ((addr & 0x5180) == 0x5180) { + EXPREGS[3] = data; + Fix121MMC3PRG(MMC3cmd); + Fix121MMC3CHR(MMC3cmd); + } + } + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +void Mapper121::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if(addr<0xA000){ + switch (addr & 0xE003) { + case 0x8000: + MMC3CMDWrite(addr, data); + Fix121MMC3PRG(MMC3cmd); + break; + case 0x8001: + EXPREGS[6] = ((data&1)<<5)|((data&2)<<3)|((data&4)<<1)|((data&8)>>1)|((data&0x10)>>3)|((data&0x20)>>5); + if (!EXPREGS[7]) SetDATA(); + MMC3CMDWrite(addr, data); + Fix121MMC3PRG(MMC3cmd); + break; + case 0x8003: + EXPREGS[5] = data; + SetDATA(); + MMC3CMDWrite(0x8000, data); + Fix121MMC3PRG(MMC3cmd); + break; + } + }else{ + MMC3MIRWrite(addr, data); + MMC3IRQWrite(addr, data); + } +} + +void Mapper121::MMC3CMDWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0x8000: + if ((V & 0x40) != (MMC3cmd & 0x40)) + Fix121MMC3PRG(V); + if ((V & 0x80) != (MMC3cmd & 0x80)) + Fix121MMC3CHR(V); + MMC3cmd = V; + break; + case 0x8001: + { + int cbase = (MMC3cmd & 0x80) << 5; + DRegBuf[MMC3cmd & 0x7] = V; + switch (MMC3cmd & 0x07) { + case 0: + PPUSW((cbase ^ 0x000), V & (~1)); + PPUSW((cbase ^ 0x400), V | 1); + break; + case 1: + PPUSW((cbase ^ 0x800), V & (~1)); + PPUSW((cbase ^ 0xC00), V | 1); + break; + case 2: + PPUSW(cbase ^ 0x1000, V); + break; + case 3: + PPUSW(cbase ^ 0x1400, V); + break; + case 4: + PPUSW(cbase ^ 0x1800, V); + break; + case 5: + PPUSW(cbase ^ 0x1C00, V); + break; + case 6: + if (MMC3cmd&0x40) CPUSW(0xC000, V); + else CPUSW(0x8000, V); + break; + case 7: + CPUSW(0xA000, V); + break; + } + break; + } + } +} + +void Mapper121::MMC3MIRWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0xA000: + A000B = V; + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + break; + case 0xA001: + A001B = V; + break; + } +} + +void Mapper121::MMC3IRQWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0xC000: IRQReload = 0;IRQCount = V; break; + case 0xC001: IRQReload = 0;IRQLatch = V; break; + case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xE001: IRQReload = 0;IRQa = 1; break; + } +} + +void Mapper121::SetDATA() +{ + switch (EXPREGS[5] & 0x3F) { + case 0x20: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x29: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x26: EXPREGS[7] = 0; EXPREGS[0] = EXPREGS[6]; break; + case 0x2B: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x2C: EXPREGS[7] = 1; if (EXPREGS[6]) EXPREGS[0] = EXPREGS[6]; break; + case 0x3C: + case 0x3F: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x28: EXPREGS[7] = 0; EXPREGS[1] = EXPREGS[6]; break; + case 0x2A: EXPREGS[7] = 0; EXPREGS[2] = EXPREGS[6]; break; + case 0x2F: break; + default: EXPREGS[5] = 0; break; + } +} + +void Mapper121::PPUSW( WORD addr, BYTE data ) +{ + if ((nes->rom->GetPROM_SIZE()*2)==nes->rom->GetVROM_SIZE()) { + SetVROM_1K_Bank(addr>>10, data | ((EXPREGS[3] & 0x80) << 1)); + } else { + if ((addr & 0x1000) == ((MMC3cmd & 0x80) << 5)) + SetVROM_1K_Bank(addr>>10, data | 0x100); + else + SetVROM_1K_Bank(addr>>10, data); + } +} + +void Mapper121::CPUSW( WORD addr, BYTE data ) +{ + if (EXPREGS[5] & 0x3F) { + SetPROM_8K_Bank(addr>>13, (data & 0x1F) | ((EXPREGS[3] & 0x80) >> 2)); + SetPROM_8K_Bank(7, (EXPREGS[0]) | ((EXPREGS[3] & 0x80) >> 2)); + SetPROM_8K_Bank(6, (EXPREGS[1]) | ((EXPREGS[3] & 0x80) >> 2)); + SetPROM_8K_Bank(5, (EXPREGS[2]) | ((EXPREGS[3] & 0x80) >> 2)); + } else { + SetPROM_8K_Bank(addr>>13, (data & 0x1F) | ((EXPREGS[3] & 0x80) >> 2)); + } +} + +void Mapper121::Fix121MMC3PRG(BYTE data) +{ + if (data & 0x40) { + CPUSW(0xC000, DRegBuf[6]); + CPUSW(0x8000, PROM_8K_SIZE-2); + } else { + CPUSW(0x8000, DRegBuf[6]); + CPUSW(0xC000, PROM_8K_SIZE-2); + } + CPUSW(0xA000, DRegBuf[7]); + CPUSW(0xE000, PROM_8K_SIZE-1); +} + +void Mapper121::Fix121MMC3CHR(BYTE data) +{ + int cbase = (data & 0x80) << 5; + PPUSW((cbase ^ 0x0000), DRegBuf[0] & (~1)); + PPUSW((cbase ^ 0x0400), DRegBuf[0] | 1); + PPUSW((cbase ^ 0x0800), DRegBuf[1] & (~1)); + PPUSW((cbase ^ 0x0C00), DRegBuf[1] | 1); + PPUSW((cbase ^ 0x1000), DRegBuf[2]); + PPUSW((cbase ^ 0x1400), DRegBuf[3]); + PPUSW((cbase ^ 0x1800), DRegBuf[4]); + PPUSW((cbase ^ 0x1c00), DRegBuf[5]); + + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); +} + +void Mapper121::HSync(INT scanline) +{ + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (IRQa && !IRQReload) { + if (scanline == 0) { + if (IRQCount) { + IRQCount -= 1; + } + } + if (!(IRQCount)){ + IRQReload = 0xFF; + IRQCount = IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + IRQCount--; + } + } + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121 - 副本.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121 - 副本.h new file mode 100644 index 00000000..9c3b4a59 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121 - 副本.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper121 // +////////////////////////////////////////////////////////////////////////// +class Mapper121 : public Mapper +{ +public: + Mapper121( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync(INT scanline); + +protected: + BYTE EXPREGS[8]; + BYTE MMC3cmd; + BYTE DRegBuf[8]; + BYTE A000B, A001B; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; +private: + void MMC3CMDWrite(WORD A, BYTE V); + void MMC3MIRWrite(WORD A, BYTE V); + void MMC3IRQWrite(WORD A, BYTE V); + void SetDATA(); + void PPUSW( WORD addr, BYTE data ); + void CPUSW( WORD addr, BYTE data ); + void Fix121MMC3PRG(BYTE data); + void Fix121MMC3CHR(BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121.cpp new file mode 100644 index 00000000..db104219 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121.cpp @@ -0,0 +1,242 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper121 // +////////////////////////////////////////////////////////////////////////// + +void Mapper121::Reset() +{ + EXPREGS[3] = 0x80; + EXPREGS[5] = 0; + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[4] = EXPREGS[6] = EXPREGS[7] = 0; + + IRQReload = IRQCount = IRQLatch = IRQa = 0; + MMC3cmd = A000B = A001B = 0; + + DRegBuf[0] = 0; + DRegBuf[1] = 2; + DRegBuf[2] = 4; + DRegBuf[3] = 5; + DRegBuf[4] = 6; + DRegBuf[5] = 7; + DRegBuf[6] = 0; + DRegBuf[7] = 1; + + Fix121MMC3PRG(MMC3cmd); + Fix121MMC3CHR(MMC3cmd); +} + +BYTE Mapper121::ReadLow( WORD addr ) +{ + DEBUGOUT( "MPRWR A=%04X L=%3d CYC=%d\n", addr&0xFFFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if((addr>=0x5000)&&(addr<=0x5FFF)) return EXPREGS[4]; +// if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void Mapper121::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if((addr>=0x5000)&&(addr<=0x5FFF)){ + const uint8 prot_array[4] = { 0x83, 0x83, 0x42, 0x00 }; + EXPREGS[4] = prot_array[data & 3]; + if ((addr & 0x5180) == 0x5180) { + EXPREGS[3] = data; + Fix121MMC3PRG(MMC3cmd); + Fix121MMC3CHR(MMC3cmd); + } + } +// if(addr>=0x6000) Mapper::WriteLow(addr, data); +} + +void Mapper121::Write( WORD addr, BYTE data ) +{ + if(addr<0xA000){ + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch (addr & 0xE003) { + case 0x8000: + MMC3CMDWrite(addr, data); + Fix121MMC3PRG(MMC3cmd); + break; + case 0x8001: + EXPREGS[6] = ((data&1)<<5)|((data&2)<<3)|((data&4)<<1)|((data&8)>>1)|((data&0x10)>>3)|((data&0x20)>>5); + if (!EXPREGS[7]) SetDATA(); + MMC3CMDWrite(addr, data); + Fix121MMC3PRG(MMC3cmd); + break; + case 0x8003: + EXPREGS[5] = data; + SetDATA(); + MMC3CMDWrite(0x8000, data); + Fix121MMC3PRG(MMC3cmd); + break; + } + }else{ + MMC3MIRWrite(addr, data); + MMC3IRQWrite(addr, data); + } +} + +void Mapper121::MMC3CMDWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0x8000: + if ((V & 0x40) != (MMC3cmd & 0x40)) + Fix121MMC3PRG(V); + if ((V & 0x80) != (MMC3cmd & 0x80)) + Fix121MMC3CHR(V); + MMC3cmd = V; + break; + case 0x8001: + { + int cbase = (MMC3cmd & 0x80) << 5; + DRegBuf[MMC3cmd & 0x7] = V; + switch (MMC3cmd & 0x07) { + case 0: + PPUSW((cbase ^ 0x000), V & (~1)); + PPUSW((cbase ^ 0x400), V | 1); + break; + case 1: + PPUSW((cbase ^ 0x800), V & (~1)); + PPUSW((cbase ^ 0xC00), V | 1); + break; + case 2: + PPUSW(cbase ^ 0x1000, V); + break; + case 3: + PPUSW(cbase ^ 0x1400, V); + break; + case 4: + PPUSW(cbase ^ 0x1800, V); + break; + case 5: + PPUSW(cbase ^ 0x1C00, V); + break; + case 6: + if (MMC3cmd&0x40) CPUSW(0xC000, V); + else CPUSW(0x8000, V); + break; + case 7: + CPUSW(0xA000, V); + break; + } + break; + } + } +} + +void Mapper121::MMC3MIRWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0xA000: + A000B = V; + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + break; + case 0xA001: + A001B = V; + break; + } +} + +void Mapper121::MMC3IRQWrite(WORD A, BYTE V) +{ + switch (A & 0xE001) { + case 0xC000: IRQReload = 0;IRQCount = V; break; + case 0xC001: IRQReload = 0;IRQLatch = V; break; + case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break; + case 0xE001: IRQReload = 0;IRQa = 1; break; + } +} + +void Mapper121::SetDATA() +{ + switch (EXPREGS[5] & 0x3F) { + case 0x20: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x29: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x26: EXPREGS[7] = 0; EXPREGS[0] = EXPREGS[6]; break; + case 0x2B: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x2C: EXPREGS[7] = 1; if (EXPREGS[6]) EXPREGS[0] = EXPREGS[6]; break; + case 0x3C: + case 0x3F: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break; + case 0x28: EXPREGS[7] = 0; EXPREGS[1] = EXPREGS[6]; break; + case 0x2A: EXPREGS[7] = 0; EXPREGS[2] = EXPREGS[6]; break; + case 0x2F: break; + default: EXPREGS[5] = 0; break; + } +} + +void Mapper121::PPUSW( WORD addr, BYTE data ) +{ + if ((nes->rom->GetPROM_SIZE()*2)==nes->rom->GetVROM_SIZE()) { + SetVROM_1K_Bank(addr>>10, data | ((EXPREGS[3] & 0x80) << 1)); + } else { + if ((addr & 0x1000) == ((MMC3cmd & 0x80) << 5)) + SetVROM_1K_Bank(addr>>10, data | 0x100); + else + SetVROM_1K_Bank(addr>>10, data); + } +} + +void Mapper121::CPUSW( WORD addr, BYTE data ) +{ + if (EXPREGS[5] & 0x3F) { + SetPROM_8K_Bank(addr>>13, (data & 0x1F) | ((EXPREGS[3] & 0x80) >> 2)); + SetPROM_8K_Bank(7, (EXPREGS[0]) | ((EXPREGS[3] & 0x80) >> 2)); + SetPROM_8K_Bank(6, (EXPREGS[1]) | ((EXPREGS[3] & 0x80) >> 2)); + SetPROM_8K_Bank(5, (EXPREGS[2]) | ((EXPREGS[3] & 0x80) >> 2)); + } else { + SetPROM_8K_Bank(addr>>13, (data & 0x1F) | ((EXPREGS[3] & 0x80) >> 2)); + } +} + +void Mapper121::Fix121MMC3PRG(BYTE data) +{ + if (data & 0x40) { + CPUSW(0xC000, DRegBuf[6]); + CPUSW(0x8000, PROM_8K_SIZE-2); + } else { + CPUSW(0x8000, DRegBuf[6]); + CPUSW(0xC000, PROM_8K_SIZE-2); + } + CPUSW(0xA000, DRegBuf[7]); + CPUSW(0xE000, PROM_8K_SIZE-1); +} + +void Mapper121::Fix121MMC3CHR(BYTE data) +{ + int cbase = (data & 0x80) << 5; + PPUSW((cbase ^ 0x0000), DRegBuf[0] & (~1)); + PPUSW((cbase ^ 0x0400), DRegBuf[0] | 1); + PPUSW((cbase ^ 0x0800), DRegBuf[1] & (~1)); + PPUSW((cbase ^ 0x0C00), DRegBuf[1] | 1); + PPUSW((cbase ^ 0x1000), DRegBuf[2]); + PPUSW((cbase ^ 0x1400), DRegBuf[3]); + PPUSW((cbase ^ 0x1800), DRegBuf[4]); + PPUSW((cbase ^ 0x1c00), DRegBuf[5]); + + if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); +} + +void Mapper121::HSync(INT scanline) +{ +// DEBUGOUT( "MPRWR L=%3d CYC=%d\n", nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if ((scanline >= 0 && scanline <= 239)) { + if (nes->ppu->IsDispON()) + { + if (IRQa && !IRQReload) { + if (scanline == 0) { + if (IRQCount) { + IRQCount -= 1; + } + } + if (!(IRQCount)){ + IRQReload = 0xFF; + IRQCount = IRQLatch; + nes->cpu->SetIRQ(IRQ_MAPPER); + } + IRQCount--; + } + } + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121.h new file mode 100644 index 00000000..9c3b4a59 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper121.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper121 // +////////////////////////////////////////////////////////////////////////// +class Mapper121 : public Mapper +{ +public: + Mapper121( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync(INT scanline); + +protected: + BYTE EXPREGS[8]; + BYTE MMC3cmd; + BYTE DRegBuf[8]; + BYTE A000B, A001B; + BYTE IRQCount, IRQLatch, IRQa, IRQReload; +private: + void MMC3CMDWrite(WORD A, BYTE V); + void MMC3MIRWrite(WORD A, BYTE V); + void MMC3IRQWrite(WORD A, BYTE V); + void SetDATA(); + void PPUSW( WORD addr, BYTE data ); + void CPUSW( WORD addr, BYTE data ); + void Fix121MMC3PRG(BYTE data); + void Fix121MMC3CHR(BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper122.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper122.cpp new file mode 100644 index 00000000..cf0d0814 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper122.cpp @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper122/184 SunSoft-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper122::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); +} + +void Mapper122::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x6000 ) { + SetVROM_4K_Bank( 0, data & 0x07 ); + SetVROM_4K_Bank( 4, (data & 0x70)>>4 ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper122.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper122.h new file mode 100644 index 00000000..f04b23ee --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper122.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper122/184 SunSoft-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper122 : public Mapper +{ +public: + Mapper122( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper132.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper132.cpp new file mode 100644 index 00000000..83d31be0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper132.cpp @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper132 TXC(Qi Wang) // +////////////////////////////////////////////////////////////////////////// + +void Mapper132::Reset() +{ + SetPROM_32K_Bank(0); + SetVROM_8K_Bank(0); + for( INT i = 0; i < 4; i++ ) { + regs[i] = 0; + } +} + +BYTE Mapper132::ReadLow( WORD addr ) +{ + BYTE ret; + ret=0; + if( addr==0x4100 && regs[3]!=0 ) ret=regs[2]; + return ret; +} + +void Mapper132::WriteLow( WORD addr, BYTE data ) +{ + if( addr>=0x4100 && addr<=0x4103 ) regs[addr&3]=data; +} + +void Mapper132::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( (regs[2]>>2)&1 ); + SetVROM_8K_Bank( regs[2]&3 ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper132.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper132.h new file mode 100644 index 00000000..b609a056 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper132.h @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper132 TXC(Qi Wang) // +////////////////////////////////////////////////////////////////////////// +class Mapper132 : public Mapper +{ +public: + Mapper132( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: + BYTE regs[4]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper133.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper133.cpp new file mode 100644 index 00000000..c093957c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper133.cpp @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper133 SACHEN CHEN // +////////////////////////////////////////////////////////////////////////// +void Mapper133::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper133::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x4120 ) { + SetPROM_32K_Bank( (data&0x04)>>2 ); + SetVROM_8K_Bank( data & 0x03 ); + } + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper133.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper133.h new file mode 100644 index 00000000..7ca4aac4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper133.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper133 SACHEN CHEN // +////////////////////////////////////////////////////////////////////////// +class Mapper133 : public Mapper +{ +public: + Mapper133( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper134.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper134.cpp new file mode 100644 index 00000000..e880228b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper134.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper133 SACHEN CHEN // +////////////////////////////////////////////////////////////////////////// +void Mapper134::Reset() +{ + SetPROM_32K_Bank( 0 ); +// SetPROM_16K_Bank( 6, 0 ); +// SetPROM_16K_Bank( 6, 1 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper134::WriteLow( WORD addr, BYTE data ) +{ + switch( addr & 0x4101 ) { + case 0x4100: + cmd = data & 0x07; + break; + case 0x4101: + switch( cmd ) { + case 0: + prg = 0; + chr = 3; + break; + case 4: + chr &= 0x3; + chr |= (data & 0x07) << 2; + break; + case 5: + prg = data & 0x07; + break; + case 6: + chr &= 0x1C; + chr |= data & 0x3; + break; + case 7: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } + break; + } + SetPROM_32K_Bank( prg ); +// SetPROM_16K_Bank( 4, (prg<<1)|0 ); +// SetPROM_16K_Bank( 6, (prg<<1)|1 ); + SetVROM_8K_Bank( chr ); + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +void Mapper134::SaveState( LPBYTE p ) +{ + p[ 0] = cmd; + p[ 1] = prg; + p[ 2] = chr; +} + +void Mapper134::LoadState( LPBYTE p ) +{ + cmd = p[ 0]; + prg = p[ 1]; + chr = p[ 2]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper134.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper134.h new file mode 100644 index 00000000..42a17737 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper134.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper133 SACHEN CHEN // +////////////////////////////////////////////////////////////////////////// +class Mapper134 : public Mapper +{ +public: + Mapper134( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE cmd, prg, chr; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper135.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper135.cpp new file mode 100644 index 00000000..8401904f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper135.cpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper135 SACHEN CHEN // +////////////////////////////////////////////////////////////////////////// +void Mapper135::Reset() +{ + cmd = 0; + chr0l = chr1l = chr0h = chr1h = chrch = 0; + + SetPROM_32K_Bank( 0 ); + SetBank_PPU(); +} + +void Mapper135::WriteLow( WORD addr, BYTE data ) +{ + switch( addr & 0x4101 ) { + case 0x4100: + cmd = data & 0x07; + break; + case 0x4101: + switch( cmd ) { + case 0: + chr0l = data & 0x07; + SetBank_PPU(); + break; + case 1: + chr0h = data & 0x07; + SetBank_PPU(); + break; + case 2: + chr1l = data & 0x07; + SetBank_PPU(); + break; + case 3: + chr1h = data & 0x07; + SetBank_PPU(); + break; + case 4: + chrch = data & 0x07; + SetBank_PPU(); + break; + case 5: + SetPROM_32K_Bank( data&0x07 ); + break; + case 6: + break; + case 7: + switch( (data>>1)&0x03 ) { + case 0: SetVRAM_Mirror( VRAM_MIRROR4L ); break; + case 1: SetVRAM_Mirror( VRAM_HMIRROR ); break; + case 2: SetVRAM_Mirror( VRAM_VMIRROR ); break; + case 3: SetVRAM_Mirror( VRAM_MIRROR4L ); break; + } + break; + } + break; + } + + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +void Mapper135::SetBank_PPU() +{ + SetVROM_2K_Bank( 0, 0|(chr0l<<1)|(chrch<<4) ); + SetVROM_2K_Bank( 2, 1|(chr0h<<1)|(chrch<<4) ); + SetVROM_2K_Bank( 4, 0|(chr1l<<1)|(chrch<<4) ); + SetVROM_2K_Bank( 6, 1|(chr1h<<1)|(chrch<<4) ); +} + +void Mapper135::SaveState( LPBYTE p ) +{ + p[ 0] = cmd; + p[ 1] = chr0l; + p[ 2] = chr0h; + p[ 3] = chr1l; + p[ 4] = chr1h; + p[ 5] = chrch; +} + +void Mapper135::LoadState( LPBYTE p ) +{ + cmd = p[ 0]; + chr0l = p[ 1]; + chr0h = p[ 2]; + chr0l = p[ 3]; + chr0h = p[ 4]; + chrch = p[ 5]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper135.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper135.h new file mode 100644 index 00000000..b0546b57 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper135.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper135 SACHEN CHEN // +////////////////////////////////////////////////////////////////////////// +class Mapper135 : public Mapper +{ +public: + Mapper135( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE cmd; + BYTE chr0l, chr1l, chr0h, chr1h, chrch; +private: + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper140.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper140.cpp new file mode 100644 index 00000000..8db28d05 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper140.cpp @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper140 // +////////////////////////////////////////////////////////////////////////// +void Mapper140::Reset() +{ + SetPROM_32K_Bank( 0 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper140::WriteLow( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( (data&0xF0)>>4 ); + SetVROM_8K_Bank( data&0x0F ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper140.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper140.h new file mode 100644 index 00000000..11659121 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper140.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper140 // +////////////////////////////////////////////////////////////////////////// +class Mapper140 : public Mapper +{ +public: + Mapper140( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + +protected: +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper141.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper141.cpp new file mode 100644 index 00000000..3ca52faa --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper141.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper141 // +////////////////////////////////////////////////////////////////////////// +void Mapper141::Reset() +{ + for(INT i=0;i<8;i++) reg[i]=0; + SetVROM_8K_Bank(0); + cmd=0; + SetBank(); +} + +void Mapper141::WriteLow( WORD addr, BYTE data ) +{ + addr&=0x4101; + if (addr==0x4100) + cmd=data; + else { + reg[cmd&7]=data; + SetBank(); + } +} + +void Mapper141::SetBank() +{ + SetPROM_32K_Bank(reg[5]&7); + for(INT i=0;i<4;i++){ + int bank; + if(reg[7]&1) bank=(reg[0]&7)|((reg[4]&7)<<3); + else bank=(reg[i]&7)|((reg[4]&7)<<3); + bank=(bank<<1)|(i&1); + SetVROM_2K_Bank(i*2, bank); + } + if(reg[7]&1) SetVRAM_Mirror(VRAM_VMIRROR); + else SetVRAM_Mirror(VRAM_HMIRROR); + +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper141.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper141.h new file mode 100644 index 00000000..a6014256 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper141.h @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper141 // +////////////////////////////////////////////////////////////////////////// +class Mapper141 : public Mapper +{ +public: + Mapper141( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + +protected: + BYTE reg[8]; + BYTE cmd; +private: + void SetBank(); +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper142.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper142.cpp new file mode 100644 index 00000000..d2900063 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper142.cpp @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper142 SMB2j Pirate (KS 202) // +////////////////////////////////////////////////////////////////////////// +void Mapper142::Reset() +{ + irq_enable = 0; + irq_counter = 0; + + SetPROM_8K_Bank( 4, 0 ); + SetPROM_8K_Bank( 5, 0 ); + SetPROM_8K_Bank( 6, 0 ); + SetPROM_8K_Bank( 7, 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +BYTE Mapper142::ReadLow( WORD addr ) +{ + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +void Mapper142::ExWrite( WORD addr, BYTE data ) +{ + if( (addr&0xF0FF) == 0x4022 ) { + switch( data&0x07 ) { + case 0x00: + case 0x02: + case 0x03: + case 0x04: + SetPROM_8K_Bank( 6, 4 ); + break; + case 0x01: + SetPROM_8K_Bank( 6, 3 ); + break; + case 0x05: + SetPROM_8K_Bank( 6, 7 ); + break; + case 0x06: + SetPROM_8K_Bank( 6, 5 ); + break; + case 0x07: + SetPROM_8K_Bank( 6, 6 ); + break; + } + } +} + +void Mapper142::WriteLow( WORD addr, BYTE data ) +{ + ExWrite( addr, data ); +} + +void Mapper142::Write( WORD addr, BYTE data ) +{ + if( addr == 0x8122 ) { + if( data&0x03 ) { + irq_enable = 1; + } else { + irq_counter = 0; + irq_enable = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +void Mapper142::HSync( INT scanline ) +{ + if( irq_enable ) { + irq_counter += 341; + if( irq_counter >= 12288 ) { + irq_counter = 0; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper142::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + *(INT*)&p[1] = irq_counter; +} + +void Mapper142::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = *(INT*)&p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper142.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper142.h new file mode 100644 index 00000000..46a0e1c3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper142.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper142 SMB2J // +////////////////////////////////////////////////////////////////////////// +class Mapper142 : public Mapper +{ +public: + Mapper142( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + INT irq_counter; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper148.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper148.cpp new file mode 100644 index 00000000..f2123aae --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper148.cpp @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper148 SACHEN // +////////////////////////////////////////////////////////////////////////// +void Mapper148::Reset() +{ + SetPROM_32K_Bank( 0 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper148::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( data >> 3 & 0x1 ); + SetVROM_8K_Bank( data & 0x7 ); +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper148.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper148.h new file mode 100644 index 00000000..2494cfe9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper148.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper148 SACHEN // +////////////////////////////////////////////////////////////////////////// +class Mapper148 : public Mapper +{ +public: + Mapper148( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper150.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper150.cpp new file mode 100644 index 00000000..d9aba845 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper150.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper150 SACHEN // +////////////////////////////////////////////////////////////////////////// +void Mapper150::Reset() +{ + for( INT i = 0; i < 5; i++ ) { + reg[i] = 0x00; + } + cmd=0; + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +BYTE Mapper150::ReadLow( WORD addr ) +{ + BYTE ret; + if((addr&0x4100)==0x4100) +// ret=(X.DB&0xC0)|((~cmd)&0x3F); + ret=~cmd&0x3F; + else + ret=0;//ret=X.DB; + return ret; +} + +void Mapper150::WriteLow( WORD addr, BYTE data ) +{ + addr&=0x4101; + if(addr==0x4100) + cmd=data&7; + else + { + switch(cmd) + { + case 2:reg[0]=data&1; reg[3]=(data&1)<<3;break; + case 4:reg[4]=(data&1)<<2;break; + case 5:reg[0]=data&7;break; + case 6:reg[1]=data&3;break; + case 7:reg[2]=data>>1;break; + } + SetPROM_32K_Bank( reg[0] ); + SetVROM_8K_Bank( reg[1]|reg[3]|reg[4] ); + switch(reg[2]&3) + { + case 0:SetVRAM_Mirror( VRAM_VMIRROR );break; + case 1:SetVRAM_Mirror( VRAM_HMIRROR );break; + case 2:SetVRAM_Mirror( VRAM_MIRROR3H );break; + case 3:SetVRAM_Mirror( VRAM_MIRROR4L );break; + } + } + +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper150.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper150.h new file mode 100644 index 00000000..419c9f28 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper150.h @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper150 SACHEN // +////////////////////////////////////////////////////////////////////////// +class Mapper150 : public Mapper +{ +public: + Mapper150( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + +protected: + BYTE reg[5]; + BYTE cmd; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper151.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper151.cpp new file mode 100644 index 00000000..75dc1b1e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper151.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper151 VS-Unisystem // +////////////////////////////////////////////////////////////////////////// +void Mapper151::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + +#if 0 + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x1E438D52 ) { + DirectDraw.SetVsPalette( 7 ); //VS_Goonies + } + if( crc == 0xD99A2087 ) { + DirectDraw.SetVsPalette( 6 ); //VS_Gradius + } +#endif +} + +void Mapper151::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4,data ); + break; + case 0xA000: + SetPROM_8K_Bank( 5,data ); + break; + case 0xC000: + SetPROM_8K_Bank( 6,data ); + break; + case 0xE000: + SetVROM_4K_Bank( 0, data ); + break; + case 0xF000: + SetVROM_4K_Bank( 4, data ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper151.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper151.h new file mode 100644 index 00000000..87a09ca2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper151.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper151 VS-Unisystem // +////////////////////////////////////////////////////////////////////////// +class Mapper151 : public Mapper +{ +public: + Mapper151( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: + +private: +}; \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper160.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper160.cpp new file mode 100644 index 00000000..fd56eb26 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper160.cpp @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper160 PC-Aladdin // +////////////////////////////////////////////////////////////////////////// +void Mapper160::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + refresh_type = 0; +} + +void Mapper160::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + case 0x8001: + SetPROM_8K_Bank( 5, data ); + break; + case 0x8002: + SetPROM_8K_Bank( 6, data ); + break; + + case 0x9000: + if( data == 0x2B ) { + refresh_type = 1; + } else if( data == 0xA8 ) { + refresh_type = 2; + } else if( data == 0x1F ) { + refresh_type = 3; + } else if( data == 0x7C ) { + refresh_type = 4; + } else if( data == 0x18 ) { + refresh_type = 5; + } else if( data == 0x60 ) { + refresh_type = 6; + } else { + refresh_type = 0; + } + SetVROM_1K_Bank( 0, data ); + break; + case 0x9001: + SetVROM_1K_Bank( 1, data ); + break; + + case 0x9002: + if( refresh_type == 2 && data != 0xE8 ) { + refresh_type = 0; + } + SetVROM_1K_Bank( 2, data ); + break; + + case 0x9003: + SetVROM_1K_Bank( 3, data ); + break; + case 0x9004: + SetVROM_1K_Bank( 4, data ); + break; + case 0x9005: + SetVROM_1K_Bank( 5, data ); + break; + case 0x9006: + SetVROM_1K_Bank( 6, data ); + break; + case 0x9007: + SetVROM_1K_Bank( 7, data ); + break; + + case 0xC000: + irq_counter = irq_latch; + irq_enable = irq_latch; + break; + case 0xC001: + irq_latch = data; + break; + case 0xC002: + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC003: + irq_counter = data; + break; + } +} + +void Mapper160::HSync( INT scanline ) +{ + if( scanline == 0 || scanline == 239 ) { + switch( refresh_type ) { + case 1: + SetVROM_8K_Bank(0x58,0x59,0x5A,0x5B,0x58,0x59,0x5A,0x5B); + break; + case 2: + SetVROM_8K_Bank(0x78,0x79,0x7A,0x7B,0x78,0x79,0x7A,0x7B); + break; + case 3: + SetVROM_8K_Bank(0x7C,0x7D,0x7E,0x7F,0x7C,0x7D,0x7E,0x7F); + break; + case 5: + SetVROM_8K_Bank(0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77); + break; + case 6: + SetVROM_8K_Bank(0x5C,0x5D,0x5E,0x5F,0x7C,0x7D,0x7E,0x7F); + break; + } + } + if( scanline == 64 ) { + if( refresh_type == 4 ) { + if( PPU_MEM_BANK[8][32*10+16] == 0x0A ) { + SetVROM_1K_Bank( 0, 0x68 ); + SetVROM_1K_Bank( 1, 0x69 ); + SetVROM_1K_Bank( 2, 0x6A ); + SetVROM_1K_Bank( 3, 0x6B ); + } else { + SetVROM_1K_Bank( 0, 0x6C ); + SetVROM_1K_Bank( 1, 0x6D ); + SetVROM_1K_Bank( 2, 0x6E ); + SetVROM_1K_Bank( 3, 0x6F ); + } + } + } + if( scanline == 128 ) { + if( refresh_type == 4 ) { + SetVROM_1K_Bank( 0, 0x68 ); + SetVROM_1K_Bank( 1, 0x69 ); + SetVROM_1K_Bank( 2, 0x6A ); + SetVROM_1K_Bank( 3, 0x6B ); + } else if( refresh_type == 5 ) { + SetVROM_8K_Bank(0x74,0x75,0x76,0x77,0x74,0x75,0x76,0x77); + } + } + if( scanline == 160 ) { + if( refresh_type == 6 ) { + SetVROM_8K_Bank(0x60,0x61,0x5E,0x5F,0x7C,0x7D,0x7E,0x7F); + } + } + + if( irq_enable ) { + if( irq_counter == 0xFF ) { +// nes->cpu->IRQ_NotPending(); + irq_enable = 0; + irq_counter = 0; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } +} + +void Mapper160::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; + p[2] = irq_latch; + p[3] = refresh_type; +} + +void Mapper160::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; + irq_latch = p[2]; + refresh_type = p[3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper160.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper160.h new file mode 100644 index 00000000..33be9558 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper160.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper160 PC-Aladdin // +////////////////////////////////////////////////////////////////////////// +class Mapper160 : public Mapper +{ +public: + Mapper160( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE refresh_type; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper162.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper162.cpp new file mode 100644 index 00000000..0875cc11 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper162.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper162 WaiXing FS304/FS301_1 // +////////////////////////////////////////////////////////////////////////// + +void Mapper162::Reset() +{ + reg5000 = 3; + reg5100 = 0; + reg5200 = 0; + reg5300 = 7; + SetBank_CPU(); + SetBank_PPU(); +} + +void Mapper162::WriteLow(WORD addr, BYTE data) +{ +// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + if(addr==0x5000){ + reg5000 = data; + SetBank_CPU(); + SetBank_PPU(); + }else if(addr==0x5100){ + reg5100 = data; + SetBank_CPU(); + SetBank_PPU(); + }else if(addr==0x5200){ + reg5200 = data; + SetBank_CPU(); + SetBank_PPU(); + }else if(addr==0x5300){ + reg5300 = data; + }else if(addr>=0x6000){ + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + }else{ + DEBUGOUT("write to %04x:%02x\n", addr, data); + } +} + +void Mapper162::Write(WORD addr, BYTE data) +{ +// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); +} + +void Mapper162::SetBank_CPU() +{ + BYTE bank; + switch (reg5300) + { + case 4: + bank = (((reg5000 & 0xF) + ((reg5100 & 3) >> 1) ) | ((reg5200 & 3) << 4)); + break; + case 7: + bank = (((reg5000 & 0xF) + ((reg5100 & 1) << 4) ) | ((reg5200 & 3) << 4)); +// bank = ((reg5000 & 0xF) | ((reg5200 & 1) << 4)); + break; + } +// DEBUGOUT("Bank=%02X\n", bank&0xFF ); + SetPROM_32K_Bank(bank); +} + +void Mapper162::SetBank_PPU() +{ + SetCRAM_8K_Bank(0); +} + +void Mapper162::HSync(int scanline) +{ + if( (reg5000&0x80) && nes->ppu->IsDispON() ) { + if(scanline<127){ + SetCRAM_4K_Bank(4, 0); + }else if(scanline<240){ + SetCRAM_4K_Bank(4, 1); + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper162.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper162.h new file mode 100644 index 00000000..959a9872 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper162.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper162 // +////////////////////////////////////////////////////////////////////////// + +class Mapper162 : public Mapper +{ +public: + Mapper162( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + +protected: + BYTE reg5000; + BYTE reg5100; + BYTE reg5200; + BYTE reg5300; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper163.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper163.cpp new file mode 100644 index 00000000..1ebde660 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper163.cpp @@ -0,0 +1,224 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper163 NanJing Games // +////////////////////////////////////////////////////////////////////////// + +/* +//------------------------------------------------------------------------------------- +static int16 step_size[49] = { + 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, + 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, + 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, + 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 +}; //49 items +static int32 step_adj[16] = { -1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9 }; +//decode stuff +static int32 jedi_table[16 * 49]; +static int32 acc = 0; //ADPCM accumulator, initial condition must be 0 +static int32 decstep = 0; //ADPCM decoding step, initial condition must be 0 +void Mapper163::jedi_table_init() +{ + int step, nib; + for (step = 0; step < 49; step++) { + for (nib = 0; nib < 16; nib++) { + int value = (2 * (nib & 0x07) + 1) * step_size[step] / 8; + jedi_table[step * 16 + nib] = ((nib & 0x08) != 0) ? -value : value; + } + } +} +BYTE Mapper163::decode(uint8 code) +{ + acc += jedi_table[decstep + code]; + if ((acc & ~0x7ff) != 0) // acc is > 2047 + acc |= ~0xfff; + else acc &= 0xfff; + decstep += step_adj[code & 7] * 16; + if (decstep < 0) decstep = 0; + if (decstep > 48 * 16) decstep = 48 * 16; + return (acc >> 8) & 0xff; +} +//------------------------------------------------------------------------------------- +*/ + +static int32 index_adjust[8] = {-1,-1,-1,-1,2,4,6,8}; +static int16 step_table[89] = { +7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,50,55, +60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279, +307,337,371,408,449,494,544,598,658,724,796,876,963,1060, +1166,1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,3327, +3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,10442, +11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767 +}; + +BYTE Mapper163::adpcm_decoder(BYTE data) +{ + int sb,delta; + int cur_sample=0; + if ((data & 8) != 0) sb=1; else sb=0; + data&=7; + delta = (step_table[index]*data)/4+step_table[index]/8; + if (sb==1) delta=-delta; + cur_sample+=delta; + if (cur_sample>32767) cur_sample = 32767; + else if (cur_sample<-32768) cur_sample = -32768; + else cur_sample = cur_sample; + index+=index_adjust[data]; + if (index<0) index=0; + if (index>88) index=88; + return cur_sample&0xff; +} + +void Mapper163::Reset() +{ + + index=0; + + reg[1] = 0xFF; + strobe = 1; + security = trigger = reg[0] = 0x00; + rom_type = 0; + SetPROM_32K_Bank(15); + +// jedi_table_init(); + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0xb6a10d5d ) { // Hu Lu Jin Gang (NJ039) (Ch) [dump] + SetPROM_32K_Bank(0); + } + if( crc == 0xf52468e7 // San Guo Wu Shuang - Meng Jiang Zhuan (NJ047) (Ch) [dump] + || crc == 0x696D98E3 ) { // San Guo Zhi Lv Bu Zhuan (NJ040) (Ch) [dump] + rom_type = 1; + } + if( crc == 0xEFF96E8A ) { // Mo Shou Shi Jie E Mo Lie Ren (NJ097) (Ch) [dump] + rom_type = 2; + } + + www = 0; +} + +BYTE Mapper163::ReadLow( WORD addr ) +{ +// DEBUGOUT( "ReadLow - addr= %04x\n", addr ); + + if((addr>=0x5000 && addr<0x6000)) + { + switch (addr & 0x7700) + { + case 0x5100: + return security; + break; + case 0x5500: + if(trigger) + return security; + else + return 0; + break; + } + return 4; + } + else if( addr>=0x6000 ) { + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } + return Mapper::ReadLow( addr ); +} + +void Mapper163::WriteLow(WORD addr, BYTE data) +{ +// if(addr==0x5200) DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + + if((addr>=0x4020 && addr<0x6000)) + { + if(addr==0x5101){ + if(strobe && !data){ + trigger ^= 1; +// trigger ^= 0xFF; + } + strobe = data; + }else if(addr==0x5100 && data==6){ + SetPROM_32K_Bank(3); + } + else{ + switch (addr & 0x7300) + { + case 0x5000: + reg[1]=data; + SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) ); + if(!(reg[1]&0x80)&&(nes->ppu->GetScanlineNo()<128)) + SetCRAM_8K_Bank(0); + if(rom_type==1) SetCRAM_8K_Bank(0); + break; + case 0x5100: + reg[2]=data; +// nes->apu->Write(0x4011,(decode(reg[0]&0xf)<<3)); + break; + case 0x5200: + reg[0]=data; + SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) ); + break; + case 0x5300: + security=data; + break; + } + } + } + else if( addr>=0x6000 ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + if((addr>=0x7900 && addr<=0x79FF)) + { +// WAVRAM[addr&0xFF] = data; +// if(addr==0x79FF){ +// memcpy( YWRAM+(www*256), WAVRAM, 256); +// www++; +// } +// nes->apu->Write(0x4011,(adpcm_decoder(data))); + nes->apu->Write(0x4011,data); + } + } +} + +void Mapper163::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); +} + +void Mapper163::HSync(int scanline) +{ + if( (reg[1]&0x80) && nes->ppu->IsDispON() ) { + if(scanline==127){ + SetCRAM_4K_Bank(0, 1); + SetCRAM_4K_Bank(4, 1); + } + if (rom_type==1){ + if(scanline<127){ + SetCRAM_4K_Bank(0, 0); + SetCRAM_4K_Bank(4, 0); + } + }else{ + if(scanline==239){ + SetCRAM_4K_Bank(0, 0); + SetCRAM_4K_Bank(4, 0); + if(rom_type==2) SetCRAM_4K_Bank(4, 1); + } + } + } +} + +void Mapper163::PPU_Latch( WORD addr ) +{ + if(DirectInput.m_Sw[DIK_PAUSE]){ + nes->Dump_YWRAM(); + } +} + +void Mapper163::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; +} + +void Mapper163::LoadState( LPBYTE p ) +{ + + reg[0] = p[0]; + reg[1] = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper163.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper163.h new file mode 100644 index 00000000..5e9d8a35 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper163.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper163 NanJing Games // +////////////////////////////////////////////////////////////////////////// + +class Mapper163 : public Mapper +{ +public: + Mapper163( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + void HSync( INT scanline ); + void PPU_Latch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[3]; + BYTE strobe, trigger; + WORD security; + BYTE rom_type; + + INT www,index; + +private: + void jedi_table_init(); + BYTE decode(uint8 code); + BYTE adpcm_decoder(BYTE data); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper164.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper164.cpp new file mode 100644 index 00000000..432f7228 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper164.cpp @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper164 Pocket Monster Gold // +////////////////////////////////////////////////////////////////////////// + + +void Mapper164::Reset() +{ + reg5000 = 0; + reg5100 = 0; + SetBank_CPU(); + SetBank_PPU(); + nes->ppu->SetExtLatchMode( TRUE ); +} + +void Mapper164::WriteLow(WORD addr, BYTE data) +{ + if(addr==0x5000){ + p_mode = data>>7; + reg5000 = data; + SetBank_CPU(); + SetBank_PPU(); + }else if(addr==0x5100){ + reg5100 = data; + SetBank_CPU(); + SetBank_PPU(); + }else if(addr>=0x6000){ + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + }else{ + DEBUGOUT("write to %04x:%02x\n", addr, data); + } + +} + + +void Mapper164::SetBank_CPU() +{ + int mode, base, bank; + + base = (reg5100&1)<<5; + mode = (reg5000>>4)&0x07; + + switch(mode){ + case 0: + case 2: + case 4: + case 6: /* NORMAL MODE */ + bank = (reg5000&0x0f); + bank += (reg5000&0x20)>>1; + SetPROM_16K_Bank(4, bank+base); + SetPROM_16K_Bank(6, base+0x1f); + DEBUGOUT("-- normal mode: mode=%d, bank=%d --\n", mode, bank); + break; + case 1: + case 3: /* REG MODE */ + DEBUGOUT("-- reg mode --\n"); + break; + case 5: /* 32K MODE */ + bank = (reg5000&0x0f); + SetPROM_32K_Bank(bank+(base>>1)); +// DEBUGOUT("-- 32K MODE: bank=%02x --\n", bank); + break; + case 7: /* HALF MODE */ + bank = (reg5000&0x0f); + bank += (bank&0x08)<<1; + SetPROM_16K_Bank(4, bank+base); + bank = (bank&0x10)+0x0f; + SetPROM_16K_Bank(6, base+0x1f); + DEBUGOUT("-- half mode --\n"); + break; + default: + break; + }; + +} + +void Mapper164::SetBank_PPU() +{ + SetCRAM_8K_Bank(0); +} + + +void Mapper164::PPU_ExtLatchX( INT x ) +{ + a3 = (x&1)<<3; +} + +void Mapper164::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr; + + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + if(p_mode){ + tileadr = (tileadr&0xfff7)|a3; + chr_l = chr_h = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + }else{ + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } + +} + +void Mapper164::SaveState( LPBYTE p ) +{ + p[0] = reg5000; + p[1] = reg5100; + p[2] = a3; + p[3] = p_mode; +} + +void Mapper164::LoadState( LPBYTE p ) +{ + + reg5000 = p[0]; + reg5100 = p[1]; + a3 = p[2]; + p_mode = p[3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper164.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper164.h new file mode 100644 index 00000000..9514e9a7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper164.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper164 Pocket Monster Gold // +////////////////////////////////////////////////////////////////////////// + +class Mapper164 : public Mapper +{ +public: + Mapper164( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + void PPU_ExtLatchX( INT x ); + void PPU_ExtLatch( WORD addr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg5000; + BYTE reg5100; + BYTE a3, p_mode; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper165.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper165.cpp new file mode 100644 index 00000000..8d4d7e7c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper165.cpp @@ -0,0 +1,153 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper165 Fire Emblem Chinese version // +////////////////////////////////////////////////////////////////////////// +void Mapper165::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr0 = 0; + chr1 = 0; + chr2 = 4; + chr3 = 4; + latch = 0xFD; + SetBank_PPU(); + + we_sram = 0; // Disable + + nes->ppu->SetChrLatchMode( TRUE ); +} + +void Mapper165::Write( WORD addr, BYTE data ) +{ + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr0 = data & 0xFC; + if( latch == 0xFD ) + SetBank_PPU(); + break; + case 0x01: + chr1 = data & 0xFC; + if( latch == 0xFE ) + SetBank_PPU(); + break; + + case 0x02: + chr2 = data & 0xFC; + if( latch == 0xFD ) + SetBank_PPU(); + break; + case 0x04: + chr3 = data & 0xFC; + if( latch == 0xFE ) + SetBank_PPU(); + break; + + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( data & 0x01 ) + { + SetVRAM_Mirror( VRAM_HMIRROR ); + }else{ + SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + default: + break; + } + +} + +void Mapper165::SetBank_CPU() +{ + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper165::SetBank_PPU() +{ + if(latch==0xFD){ + SetBank_PPUSUB( 0, chr0 ); + SetBank_PPUSUB( 4, chr2 ); + }else{ + SetBank_PPUSUB( 0, chr1 ); + SetBank_PPUSUB( 4, chr3 ); + } +} + +void Mapper165::SetBank_PPUSUB( int bank, int page ) +{ + if( page == 0 ) { + SetCRAM_4K_Bank( bank, page>>2 ); + } else { + SetVROM_4K_Bank( bank, page>>2 ); + } +} + +void Mapper165::PPU_ChrLatch( WORD addr ) +{ + WORD mask = addr&0x1FF0; + + if( mask == 0x1FD0 ) { + latch = 0xFD; + SetBank_PPU(); + } else if( mask == 0x1FE0 ) { + latch = 0xFE; + SetBank_PPU(); + } + +} + +void Mapper165::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr0; + p[11] = chr1; + p[12] = chr2; + p[13] = chr3; + p[14] = latch; +} + +void Mapper165::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr0 = p[10]; + chr1 = p[11]; + chr2 = p[12]; + chr3 = p[13]; + latch = p[14]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper165.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper165.h new file mode 100644 index 00000000..ad018dd3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper165.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper165 Fire Emblem Chinese version // +////////////////////////////////////////////////////////////////////////// +class Mapper165 : public Mapper +{ +public: + Mapper165( NES* parent ) : Mapper(parent) {} + + + void Reset(); + void Write( WORD addr, BYTE data ); + + void PPU_ChrLatch( WORD addr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr0, chr1, chr2, chr3; + BYTE we_sram; + BYTE latch; + +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_PPUSUB( int bank, int page ); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166.cpp new file mode 100644 index 00000000..c97fe977 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper166 // +////////////////////////////////////////////////////////////////////////// +void Mapper166::Reset() +{ + reg[0] = reg[1] = 0; + SetPROM_32K_Bank( 0 ); +// SetCRAM_4K_Bank( 0, 0x00 ); +// SetCRAM_4K_Bank( 4, 0x00 ); + SetCRAM_8K_Bank( 0 ); + SetVRAM_Mirror( VRAM_MIRROR4H ); +} + +void Mapper166::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + if(addr==0xFFFF){ +// reg[0] = (data & 0x04) >> 2; + reg[0] = data; +// SetCRAM_4K_Bank( 0, reg[0]*4+reg[1] ); +// SetCRAM_4K_Bank( 4, reg[0]*4+0x03 ); + + switch ( data ) { + case 0: +// SetCRAM_4K_Bank( 4, 0 ); + break; + case 1: +// SetCRAM_4K_Bank( 4, 1 ); + break; + case 2: +// SetCRAM_4K_Bank( 4, 2 ); + break; + case 3: +// SetCRAM_4K_Bank( 4, 1 ); + break; + } + } +} + +void Mapper166::PPU_Latch( WORD addr ) +{ +// if((addr&0xF000)==0x2000){ +// NT_data=(addr>>8)&0x03; +// SetCRAM_4K_Bank( 0, 0 ); +// SetCRAM_4K_Bank( 4, reg[0] ); +// } + + if((addr&0xF000)==0x2000){ + reg[1]=(addr>>8)&0x03; + SetCRAM_4K_Bank( 0, reg[0]*4+reg[1] ); + SetCRAM_4K_Bank( 4, reg[0] ); + } + + if(DirectInput.m_Sw[DIK_PAUSE]) nes->Dump_CRAM(); + +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166.h new file mode 100644 index 00000000..2e742ba1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper166 // +////////////////////////////////////////////////////////////////////////// +class Mapper166 : public Mapper +{ +public: + Mapper166( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + void PPU_Latch( WORD addr ); + +protected: + BYTE reg[2]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166_bak.rar b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166_bak.rar new file mode 100644 index 00000000..c4d81698 Binary files /dev/null and b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166_bak.rar differ diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166b.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166b.cpp new file mode 100644 index 00000000..7a860e79 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166b.cpp @@ -0,0 +1,161 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper166 // +////////////////////////////////////////////////////////////////////////// +void Mapper166::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper166::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "WriteH A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + + case 0x9000: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB001: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB002: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB003: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC001: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC002: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC003: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD001: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD002: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD003: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE001: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE002: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE003: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + // + break; + case 0xF004: + // + break; + + case 0xF008: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + + break; + + case 0xF00C: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} +/* +void Mapper166::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter -= 1; + } + } + if(!(irq_counter)){ + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + irq_counter--; + } + } + } +} +*/ +void Mapper166::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock+=cycles) >= 0x72 ) { + irq_clock -= 0x72; + if( irq_counter == 0xFF ) { + irq_counter = irq_latch; + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166b.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166b.h new file mode 100644 index 00000000..4c0ddcc8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper166b.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper166 // +////////////////////////////////////////////////////////////////////////// +class Mapper166 : public Mapper +{ +public: + Mapper166( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +// void HSync( INT scanline ); + void Clock( INT cycles ); + +protected: + WORD reg[9]; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + INT irq_clock; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper167.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper167.cpp new file mode 100644 index 00000000..b5d86ce0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper167.cpp @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper012 Subor Computer V4.0 // +////////////////////////////////////////////////////////////////////////// + + +void Mapper167::Reset() +{ + DWORD crc; + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + regs[3] = 0; + + crc = nes->rom->GetPROM_CRC(); + if(crc==0x82F1Fb96){ + // Subor Computer(Russia) + rom_type = 1; + }else{ + // Subor Computer(Chinese) + rom_type = 0; + } + + SetBank_CPU(); + SetBank_PPU(); +} + +void Mapper167::Write(WORD addr, BYTE data) +{ + int idx; + + idx = (addr>>13)&0x03; + regs[idx]=data; + SetBank_CPU(); + SetBank_PPU(); +// DEBUGOUT("write to %04x:%02x\n", addr, data); +} + + +void Mapper167::SetBank_CPU() +{ + int base, bank; + + base = ((regs[0]^regs[1])&0x10)<<1; + bank = (regs[2]^regs[3])&0x1f; + + if(regs[1]&0x08){ + bank &= 0xfe; + if(rom_type==0){ + SetPROM_16K_Bank(4, base+bank+1); + SetPROM_16K_Bank(6, base+bank+0); + }else{ + SetPROM_16K_Bank(6, base+bank+1); + SetPROM_16K_Bank(4, base+bank+0); + } +// DEBUGOUT("32K MODE!\n"); + }else{ + if(regs[1]&0x04){ + SetPROM_16K_Bank(4, 0x1f); + SetPROM_16K_Bank(6, base+bank); +// DEBUGOUT("HIGH 16K MODE!\n"); + }else{ + SetPROM_16K_Bank(4, base+bank); + if(rom_type==0){ + SetPROM_16K_Bank(6, 0x20); + }else{ + SetPROM_16K_Bank(6, 0x07); + } +// DEBUGOUT("LOW 16K MODE!\n"); + } + } + + +} + +void Mapper167::SetBank_PPU() +{ + SetCRAM_8K_Bank(0); +} + +void Mapper167::SaveState( LPBYTE p ) +{ + p[0] = regs[0]; + p[1] = regs[1]; + p[2] = regs[2]; + p[3] = regs[3]; + p[4] = rom_type; +} + +void Mapper167::LoadState( LPBYTE p ) +{ + regs[0] = p[0]; + regs[1] = p[1]; + regs[2] = p[2]; + regs[3] = p[3]; + rom_type = p[4]; +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper167.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper167.h new file mode 100644 index 00000000..c400c8d9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper167.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper004 Subor Computer V4.0 // +////////////////////////////////////////////////////////////////////////// + +class Mapper167 : public Mapper +{ +public: + Mapper167( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE regs[4]; + BYTE rom_type; +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.cpp new file mode 100644 index 00000000..c30481c0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.cpp @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper168 Subor (PPUExtLatch) // +////////////////////////////////////////////////////////////////////////// + +void Mapper168::Reset() +{ + reg5000 = 0; + reg5200 = 0; + reg5300 = 0; + PPU_SW = 0; + NT_data = 0; + nes->ppu->SetExtLatchMode( TRUE ); + SetPROM_16K_Bank(4,0); + SetPROM_16K_Bank(6,0); + + Rom_Type = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x0A9808AE ) //[Subor] Karaoke (C) + { + Rom_Type = 1; + SetPROM_32K_Bank( 0 ); + nes->SetVideoMode( 2 ); + } + if( crc == 0x12D61CE8 ) //[Subor] Subor V11.0 (C) + { + Rom_Type = 2; + } +} + +BYTE Mapper168::ReadLow( WORD addr ) +{ + if(addr==0x5300) return 0x8F; //0x8Fйصij + return Mapper::ReadLow( addr ); +} + +void Mapper168::WriteLow(WORD addr, BYTE data) +{ + if(addr==0x5000){ + reg5000 = data; + SetBank_CPU(); + }else if(addr==0x5200){ + reg5200 = data & 0x7; + SetBank_CPU(); + }else if(addr==0x5300){ + reg5300 = data; + }else if(addr>=0x6000){ + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + +void Mapper168::Write(WORD addr, BYTE data) +{ + if(Rom_Type==1){ //[Subor] Karaoke (C) + SetPROM_32K_Bank( data&0x1F ); + if(data&0x40) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + if(data&0xC0) PPU_SW = 1; + else PPU_SW = 0; + } +} + +void Mapper168::SetBank_CPU() +{ + if(reg5200<4) SetPROM_16K_Bank(4,reg5000); + else SetPROM_32K_Bank(reg5000); + switch( reg5200 ) { + case 0: + SetVRAM_Mirror( VRAM_VMIRROR ); + PPU_SW = 0; + break; + case 2: + SetVRAM_Mirror( VRAM_VMIRROR ); + PPU_SW = 1; + break; + case 1: + case 3: + SetVRAM_Mirror( VRAM_HMIRROR ); + PPU_SW = 0; + break; + case 5: + if(reg5000==4 && Rom_Type==2){ //Special for [Subor] Subor V11.0 (C) - Tank (̹˴ս) + nes->ppu->SetExtLatchMode( FALSE ); + SetVRAM_Mirror( VRAM_HMIRROR ); + } + break; + } +} + +void Mapper168::PPU_Latch( WORD addr ) +{ + if((addr&0xF000)==0x2000){ + NT_data=(addr>>8)&0x03; + } +} + +void Mapper168::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr, ntb; + + ntb = (ntbladr>>10)&3; + + if(ntb==2) + tileofs |= 0x1000; + else if(ntb && PPU_SW) + tileofs |= 0x1000; + else + tileofs |= 0x0000; + + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; +} + +void Mapper168::SaveState( LPBYTE p ) +{ + p[0] = reg5000; + p[1] = reg5200; +} + +void Mapper168::LoadState( LPBYTE p ) +{ + + reg5000 = p[0]; + reg5200 = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.h new file mode 100644 index 00000000..9f11585e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper168 // +////////////////////////////////////////////////////////////////////////// + +class Mapper168 : public Mapper +{ +public: + Mapper168( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write( WORD addr, BYTE data ); + + void PPU_Latch( WORD addr ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg5000, reg5200, reg5300; + BYTE PPU_SW, NT_data; + BYTE Rom_Type; + +private: + void SetBank_CPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.cpp new file mode 100644 index 00000000..29d89529 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.cpp @@ -0,0 +1,659 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper169 for YuXing // +////////////////////////////////////////////////////////////////////////// + +//for FDC code by fanoble +static const Mapper169::FDC_CMD_DESC FdcCmdTable[32] = +{ + /* 0x00 */ { 1, 1, Mapper169::FdcNop }, + /* 0x01 */ { 1, 1, Mapper169::FdcNop }, + /* 0x02 */ { 9, 7, Mapper169::FdcReadTrack }, + /* 0x03 */ { 3, 0, Mapper169::FdcSpecify }, + /* 0x04 */ { 2, 1, Mapper169::FdcSenseDriveStatus }, + /* 0x05 */ { 9, 7, Mapper169::FdcWriteData }, + /* 0x06 */ { 9, 7, Mapper169::FdcReadData }, + /* 0x07 */ { 2, 0, Mapper169::FdcRecalibrate }, + /* 0x08 */ { 1, 2, Mapper169::FdcSenseIntStatus }, + /* 0x09 */ { 9, 7, Mapper169::FdcWriteDeletedData }, + /* 0x0A */ { 2, 7, Mapper169::FdcReadID }, + /* 0x0B */ { 1, 1, Mapper169::FdcNop }, + /* 0x0C */ { 9, 7, Mapper169::FdcReadDeletedData }, + /* 0x0D */ { 6, 7, Mapper169::FdcFormatTrack }, + /* 0x0E */ { 1, 1, Mapper169::FdcNop }, + /* 0x0F */ { 3, 0, Mapper169::FdcSeek }, + /* 0x10 */ { 1, 1, Mapper169::FdcNop }, + /* 0x11 */ { 9, 7, Mapper169::FdcScanEqual }, + /* 0x12 */ { 1, 1, Mapper169::FdcNop }, + /* 0x13 */ { 1, 1, Mapper169::FdcNop }, + /* 0x14 */ { 1, 1, Mapper169::FdcNop }, + /* 0x15 */ { 1, 1, Mapper169::FdcNop }, + /* 0x16 */ { 1, 1, Mapper169::FdcNop }, + /* 0x17 */ { 1, 1, Mapper169::FdcNop }, + /* 0x18 */ { 1, 1, Mapper169::FdcNop }, + /* 0x19 */ { 9, 7, Mapper169::FdcScanLowOrEqual }, + /* 0x1A */ { 1, 1, Mapper169::FdcNop }, + /* 0x1B */ { 1, 1, Mapper169::FdcNop }, + /* 0x1C */ { 1, 1, Mapper169::FdcNop }, + /* 0x1D */ { 9, 7, Mapper169::FdcScanHighOrEqual }, + /* 0x1E */ { 1, 1, Mapper169::FdcNop }, + /* 0x1F */ { 1, 1, Mapper169::FdcNop }, +}; + +void Mapper169::Reset() +{ + DWORD crc = nes->rom->GetPROM_CRC(); + if(crc == 0x2B1B969E //YX_V8.2-D + || crc == 0xA70FD0F3) //YX_V8.3-D + { + YX_type = 0; //D + } + if(crc == 0x6085FEE8 //YX_V9.0-98 + || crc == 0x2A1E4D89 //YX_V9.2-98 + || crc == 0x5C6CE13E) //YX_V9.2-F + { + YX_type = 1; //98 & F + } + + nes->ppu->SetExtLatchMode( TRUE ); + reg[0] = 0xFF; //$5002 + reg[1] = 0x00; //$4800 + reg[2] = 0x00; //$5500 + reg[3] = 0x00; //$5501 + reg[4] = 0x00; //PPU_Latch + reg[5] = 0x00; //$8000 + reg[6] = 0x00; + reg[7] = 0x01; + cmd_4800_6 = 0x00; + cmd_4800_7 = 0x00; + cmd_4800_8 = 0x00; + cmd_5500_3 = 0x00; + cmd_5500_8 = 0x00; + cmd_5501_8 = 0x00; + key_map_row = 0x00; + MMC3_mode = 0x00; + + SetPROM_32K_Bank( 0 ); + SetYCRAM_8K_Bank( 0 ); +/* +//--for test disk program----------------------------------------- + int fs; + fs = 0x000000; + fs = 0x100000; + memcpy( YWRAM, PROM+fs, PROM_8K_SIZE*0x2000-fs); + memcpy( YWRAM+0xFC000, PROM+(PROM_16K_SIZE-1)*0x4000, 0x4000); + SetYWRAM_32K_Bank( 0, 1, 0x7e, 0x7f ); +//---------------------------------------------------------------- +*/ + + lpDisk = NULL; + DISK = NULL; + if(Load_DiskIMG() != NULL) DISK = Load_DiskIMG(); + + read_mode = 0; + read_mode1 = 0; + nnn = 0; + + //for FDC code by fanoble + pFdcDataPtr = DISK; + bFdcIrq = FALSE; + bFdcHwReset = FALSE; + bFdcSoftReset = FALSE; + bFdcDmaInt = FALSE; + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; + nFdcCylinder = 0; + nFdcHeadAddres = 0; + nFdcRecord = 0; + nFdcNumber = 0; + +} + +BYTE Mapper169::ReadLow( WORD addr ) +{ +// if(addr>0x4207) DEBUGOUT( "ReadL A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, Mapper::ReadLow( addr ), nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + int key_map[14][8] = { //YuXing_Keyboard data by tpu (fix by temryu) + {DIK_ESCAPE, DIK_F9, DIK_7, DIK_R, DIK_A, 0x00, 0x00, DIK_LSHIFT}, + {0x00, DIK_NUMPADENTER,0x00, DIK_MULTIPLY,DIK_DIVIDE, DIK_UP, DIK_BACKSPACE,DIK_F12 }, + {0x00, 0x00, 0x00, DIK_ADD, DIK_NUMLOCK,DIK_LEFT, DIK_DOWN, DIK_RIGHT }, + {0x00, DIK_NUMPAD7, DIK_NUMPAD8,DIK_SUBTRACT,DIK_NUMPAD9,DIK_F11, DIK_END, DIK_PGDN }, + {DIK_F8, DIK_6, DIK_E, DIK_RBRACKET,DIK_L, DIK_Z, DIK_N, DIK_SPACE }, + {DIK_F7, DIK_5, DIK_W, DIK_LBRACKET,DIK_K, DIK_DELETE, DIK_B, DIK_SLASH }, + {DIK_F6, DIK_4, DIK_Q, DIK_P, DIK_J, DIK_BACKSLASH, DIK_V, DIK_PERIOD}, + {DIK_F5, DIK_3, DIK_EQUALS, DIK_O, DIK_H, DIK_APOSTROPHE,DIK_C, DIK_COMMA }, + {DIK_F4, DIK_2, DIK_MINUS, DIK_I, DIK_G, DIK_SEMICOLON, DIK_X, DIK_M }, + {DIK_F3, DIK_1, DIK_0, DIK_U, DIK_F, DIK_CAPITAL, DIK_LWIN, 0x00 }, + {DIK_F2, DIK_GRAVE, DIK_9, DIK_Y, DIK_D, DIK_LCONTROL, DIK_LMENU, DIK_SCROLL}, + {DIK_F1, DIK_RETURN, DIK_8, DIK_T, DIK_S, 0x00, DIK_RWIN, DIK_APPS }, + {DIK_DECIMAL,DIK_F10, DIK_NUMPAD4,DIK_NUMPAD6, DIK_NUMPAD5,DIK_INSERT, DIK_HOME, DIK_PGUP }, + {0x00, DIK_NUMPAD0, DIK_NUMPAD1,DIK_NUMPAD3, DIK_NUMPAD2,DIK_SYSRQ, DIK_TAB, DIK_PAUSE }, + }; + if( YX_type == 0 ) //for D (without new keys) + { + key_map[9][6] = 0x00; + key_map[11][6] = 0x00; + key_map[11][7] = 0x00; + } + + switch( addr ) { + case 0x4207: //YuXing_Keyboard code by tpu + int r, i, data; + data = 0; + for(r=0; r<14; r++){ + if(key_map_row&(1<bRLength) + { + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; + nFdcMainStatus &= ~FDC_MS_DATA_IN; + nFdcMainStatus |= FDC_MS_RQM; +// if((bFdcCommands[0]&0x0F)==0x06) read_mode1 = 1; + } + return reg[6]; + break; + + } + + if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void Mapper169::WriteLow( WORD addr, BYTE data ) +{ + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF]=data; + +// if(addr>0x4207) DEBUGOUT( "WriteL A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr ) { + case 0x4200://DCR + DEBUGOUT( "Write 0x4200 = %04X\n", data ); + // + break; + case 0x4201://FDCĴ(DOR)(ֿƼĴ) + DEBUGOUT( "Write 0x4201 = %04X\n", data ); + bFdcDmaInt = (data & 8) ? TRUE : FALSE; + nFdcDrvSel = data & 3; + nFdcMotor = data >> 4; + if (data & 4) + { + if (bFdcSoftReset) + { + FdcSoftReset(); + bFdcSoftReset = FALSE; + // irq after soft reset + if (0 == nFdcDrvSel) + bFdcIrq = TRUE; // Drv A Only + else + bFdcIrq = FALSE; + } + } + else + { + if (!bFdcSoftReset) + { + bFdcSoftReset = TRUE; + bFdcIrq = FALSE; + } + } +/* + if (data & 0x80) + { + if (!bFdcHwReset) + { + bFdcHwReset = TRUE; + bFdcIrq = FALSE; + } + } + else + { + if (bFdcHwReset) + { + FdcHardReset(); + bFdcHwReset = FALSE; + } + } +*/ + break; + case 0x4205: //FDCд??? + DEBUGOUT( "Write 0x4205 = %04X\n", data ); + read_mode = 0; + switch (bFdcPhase) + { + case FDC_PH_EXECUTION: + case FDC_PH_RESULT: + // ERROR + break; + case FDC_PH_IDLE: + default: + bFdcCycle = 0; + bFdcPhase = FDC_PH_COMMAND; + pFdcCmd = &FdcCmdTable[data & FDC_CC_MASK]; + // fall through + case FDC_PH_COMMAND: + bFdcCommands[bFdcCycle] = data; + bFdcCycle++; + if (bFdcCycle == pFdcCmd->bWLength) + { + bFdcPhase = FDC_PH_EXECUTION; + + pFdcCmd->pFun(this); + + if (pFdcCmd->bRLength) + { + nFdcMainStatus |= FDC_MS_DATA_IN; + nFdcMainStatus |= FDC_MS_RQM; + bFdcPhase = FDC_PH_RESULT; + if((bFdcCommands[0]&0x0F)==0x06) read_mode = 1; + } + else + { + bFdcPhase = FDC_PH_IDLE; + } + + bFdcCycle = 0; + } + break; + } + break; + + case 0x4202: //YuXing_Keyboard + key_map_row &= 0xff00; + key_map_row |= data; + break; + case 0x4203: //YuXing_Keyboard + case 0x4303: + key_map_row &= 0x00ff; + key_map_row |= (data & 0x3f)<<8; + break; + + case 0x4800: + reg[1] = data; + cmd_4800_6 = reg[1]&0x20; //ȡ6λRAMأ1򿪣0ر + cmd_4800_7 = reg[1]&0x40; //ȡ7λ + cmd_4800_8 = reg[1]&0x80; //ȡ8λڿPPU_ExtLatch + + SetBank_CPU(); + break; + case 0x5500: + reg[2] = data; + cmd_5500_3 = reg[2]&0x04; //ȡ3λRAMй + cmd_5500_8 = reg[2]&0x80; //ȡ8λڿPPU_Latch + + SetBank_CPU(); + break; + case 0x5501: + reg[3] = data; + cmd_5501_8 = reg[3]&0x80; //ȡ8λMMC3ģʽá滭塱ѡ(???) + + SetYCRAM_8K_Bank( reg[3] & 0x7F ); + if(cmd_5501_8){ + MMC3_mode = 1; + SetYWRAM_16K_Bank( 6, 0x1F ); + }else{ + MMC3_mode = 0; + } + break; + } +} + +void Mapper169::Write( WORD addr, BYTE data ) +{ + + if(cmd_5500_3 && MMC3_mode){ + MMC3_WriteH( addr, data ); + return; + } + + if(cmd_5500_3){ + if(cmd_4800_6){ + reg[5] = data&0x3F; + }else{ + WriteCPU_PRAM( addr, data ); + } + } + +} + +void Mapper169::SetBank_CPU() +{ + if(cmd_5500_3 && MMC3_mode) return; + + if(cmd_5500_3){ + SetYWRAM_16K_Bank( 4, reg[5] ); + SetYWRAM_16K_Bank( 6, 0x3F ); + }else{ + SetPROM_32K_Bank(reg[1]&0x1F); + } + +// DEBUGOUT( "reg[2] = %04X\n", reg[2] ); + + SetPROM_Bank( 3, &YSRAM[0x2000*(reg[2]&0x3)], BANKTYPE_RAM ); +// CPU_MEM_PAGE[3]=reg[2]&0x3; + + if((reg[2]&0x3)==0) SetPROM_Bank( 3, &YWRAM[0x78000], BANKTYPE_RAM ); + +} + +void Mapper169::WriteCPU_PRAM( WORD addr, BYTE data ) +{ + if(addr<0xC000){ + YWRAM[(addr-0x8000)+(reg[5]*0x4000)] = data; + }else{ + YWRAM[addr+0xF0000] = data; //HOME BANK + } +} + +void Mapper169::PPU_Latch( WORD addr ) +{ + if((addr&0xF000)==0x2000){ + reg[4]=(addr>>8)&0x03; + if(cmd_4800_8 && cmd_5500_8){ + SetYCRAM_8K_Bank((reg[4]<<2)+(reg[3]&0x03)); + SetYCRAM_4K_Bank(0,reg[3]<<1); + } + } +/* + if(DirectInput.m_Sw[DIK_PAUSE]){ + nes->Dump_YWRAM(); + nes->Dump_YSRAM(); + nes->Dump_CPULMEM(); + nes->Dump_CPUHMEM(); + } +*/ +} +void Mapper169::PPU_ExtLatchX( INT x ) +{ + a3 = (x&1)<<3; +} +void Mapper169::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr; + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + if(cmd_4800_8 && !cmd_5500_8){ + if(reg[4]&0x02) tileadr |= 0x1000; + else tileadr &= ~0x1000; + tileadr = (tileadr&0xfff7)|a3; + chr_l = chr_h = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + }else{ + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } +} +BYTE Mapper169::PPU_ExtLatchSP() //ɫ⣬δȫ +{ + if(cmd_4800_8 && !cmd_5500_8) + return 2; //ʱ˴ԭδ֪пVirtuaNES⡣ + return 0; +} + +void Mapper169::MMC3_WriteH( WORD addr, BYTE data ) +{ + switch(addr) { + case 0x8000: + MMC3_reg = data; + MMC3_SetBank_CPU(); + MMC3_SetBank_PPU(); + break; + case 0x8001: + switch(MMC3_reg&0x07) { + case 0x02: + MMC3_chr4 = data; + MMC3_SetBank_PPU(); + break; + case 0x03: + MMC3_chr5 = data; + MMC3_SetBank_PPU(); + break; + case 0x04: + MMC3_chr6 = data; + MMC3_SetBank_PPU(); + break; + case 0x05: + MMC3_chr7 = data; + MMC3_SetBank_PPU(); + break; + case 0x06: + MMC3_prg0 = data; + MMC3_SetBank_CPU(); + break; + case 0x07: + MMC3_prg1 = data; + MMC3_SetBank_CPU(); + break; + } + break; + } +} +void Mapper169::MMC3_SetBank_CPU() +{ + SetYWRAM_32K_Bank( MMC3_prg0, MMC3_prg1, 0x3E, 0x3F ); +} +void Mapper169::MMC3_SetBank_PPU() +{ + SetYCRAM_1K_Bank( 4, MMC3_chr4&0x0F ); + SetYCRAM_1K_Bank( 5, MMC3_chr5&0x0F ); + SetYCRAM_1K_Bank( 6, MMC3_chr6&0x0F ); + SetYCRAM_1K_Bank( 7, MMC3_chr7&0x0F ); +} + +LPBYTE Mapper169::Load_DiskIMG() +{ + FILE *fp = NULL; + if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + if( !(fp = ::fopen( "YuXing.img", "rb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, "YuXing.img" ); + throw szErrorString; + } + ::fread(lpDisk, 0x168000, 1, fp); + FCLOSE(fp); + return lpDisk; +} + +//for FDC code by fanoble +void Mapper169::FdcHardReset(void) +{ + DEBUGOUT( "FdcHardReset!!!\n" ); + bFdcDmaInt = FALSE; + FdcSoftReset(); +} +void Mapper169::FdcSoftReset(void) +{ + DEBUGOUT( "FdcSoftReset!!!\n" ); + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; +} + +//(READ DATA) +void Mapper169::FdcReadData(Mapper169* thiz) +{ + DEBUGOUT( "FdcReadData!!!\n" ); + BYTE C = thiz->bFdcCommands[2]; //ŵ + BYTE H = thiz->bFdcCommands[3]; //ͷ + BYTE R = thiz->bFdcCommands[4]; // + BYTE N = thiz->bFdcCommands[5]; + INT LBA = H * 18 + C * 36 + (R - 1); + DEBUGOUT( "C = %04X\n", C ); + DEBUGOUT( "H = %04X\n", H ); + DEBUGOUT( "R = %04X\n", R ); + DEBUGOUT( "N = %04X\n", N ); + thiz->pFdcDataPtr = thiz->DISK + LBA * 512; + R++; + if (19 == R) + { + R = 1; + H++; + if (2 == H) + { + C++; + if (80 == C) + C = 0; + } + } + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 + thiz->bFdcResults[3] = C; + thiz->bFdcResults[4] = H; + thiz->bFdcResults[5] = R; + thiz->bFdcResults[6] = N; + thiz->nFdcCylinder = C; + thiz->nFdcHeadAddres = H; + thiz->nFdcRecord = R; + thiz->nFdcNumber = N; +} +//д(WRITE DATA) +void Mapper169::FdcWriteData(Mapper169* thiz) +{ + DEBUGOUT( "FdcWriteData!!!\n" ); + thiz = thiz; +} + +void Mapper169::FdcNop(Mapper169* thiz) +{ + DEBUGOUT( "FdcNop!!!\n" ); + thiz->nFDCStatus[0] = FDC_S0_IC1; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; +} +void Mapper169::FdcReadTrack(Mapper169* thiz) +{ + DEBUGOUT( "FdcReadTrack!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcSpecify(Mapper169* thiz) +{ + DEBUGOUT( "FdcSpecify!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcSenseDriveStatus(Mapper169* thiz) +{ + DEBUGOUT( "FdcSenseDriveStatus!!!\n" ); + thiz->bFdcResults[0] = thiz->nFDCStatus[3]; +} + +void Mapper169::FdcRecalibrate(Mapper169* thiz) +{ + DEBUGOUT( "FdcRecalibrate!!!\n" ); + thiz->nFdcCylinder = 0; //ͷص0ŵ + thiz->nFDCStatus[0] |= FDC_S0_SE; +} +void Mapper169::FdcSenseIntStatus(Mapper169* thiz) +{ + DEBUGOUT( "FdcSenseIntStatus!!!\n" ); + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; + thiz->bFdcResults[1] = thiz->nFdcCylinder; +} +void Mapper169::FdcWriteDeletedData(Mapper169* thiz) +{ + DEBUGOUT( "FdcWriteDeletedData!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcReadID(Mapper169* thiz) +{ + DEBUGOUT( "FdcReadID!!!\n" ); + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; + thiz->bFdcResults[3] = thiz->nFdcCylinder; + thiz->bFdcResults[4] = thiz->nFdcHeadAddres; + thiz->bFdcResults[5] = thiz->nFdcRecord; + thiz->bFdcResults[6] = thiz->nFdcNumber; +} +void Mapper169::FdcReadDeletedData(Mapper169* thiz) +{ + DEBUGOUT( "FdcReadDeletedData!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcFormatTrack(Mapper169* thiz) +{ + DEBUGOUT( "FdcFormatTrack!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcSeek(Mapper169* thiz) +{ + DEBUGOUT( "FdcSeek!!!\n" ); + BYTE US; + US = thiz->bFdcCommands[1] & 3; + thiz->nFdcHeadAddres = ( thiz->bFdcCommands[1] & 7 ) >> 2; + thiz->nFdcCylinder = thiz->bFdcCommands[2]; + thiz->nFDCStatus[0] = FDC_S0_SE; +} +void Mapper169::FdcScanEqual(Mapper169* thiz) +{ + DEBUGOUT( "FdcScanEqual!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcScanLowOrEqual(Mapper169* thiz) +{ + DEBUGOUT( "FdcScanLowOrEqual!!!\n" ); + thiz = thiz; +} +void Mapper169::FdcScanHighOrEqual(Mapper169* thiz) +{ + DEBUGOUT( "FdcScanHighOrEqual!!!\n" ); + thiz = thiz; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.h new file mode 100644 index 00000000..d7c63819 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.h @@ -0,0 +1,158 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper169 // +////////////////////////////////////////////////////////////////////////// + +#include "DirectInput.h" + +#include "VirtuaNESres.h" +#include "App.h" + +class Mapper169 : public Mapper +{ +public: + Mapper169( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void PPU_Latch( WORD addr ); + void PPU_ExtLatchX( INT x ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + BYTE PPU_ExtLatchSP(); + + //for FDC code by fanoble + void FdcHardReset(void); + void FdcSoftReset(void); + static void FdcNop(Mapper169* thiz); + static void FdcReadTrack(Mapper169* thiz); + static void FdcSpecify(Mapper169* thiz); + static void FdcSenseDriveStatus(Mapper169* thiz); + static void FdcWriteData(Mapper169* thiz); + static void FdcReadData(Mapper169* thiz); + static void FdcRecalibrate(Mapper169* thiz); + static void FdcSenseIntStatus(Mapper169* thiz); + static void FdcWriteDeletedData(Mapper169* thiz); + static void FdcReadID(Mapper169* thiz); + static void FdcReadDeletedData(Mapper169* thiz); + static void FdcFormatTrack(Mapper169* thiz); + static void FdcSeek(Mapper169* thiz); + static void FdcScanEqual(Mapper169* thiz); + static void FdcScanLowOrEqual(Mapper169* thiz); + static void FdcScanHighOrEqual(Mapper169* thiz); + typedef struct tagFDC_CMD_DESC + { + BYTE bWLength; + BYTE bRLength; + void (*pFun)(Mapper169*); + } FDC_CMD_DESC; + +protected: + BYTE YX_type, reg[8]; + BYTE a3; + INT key_map_row; + BYTE cmd_4800_6,cmd_4800_7,cmd_4800_8; + BYTE cmd_5500_3,cmd_5500_8; + BYTE cmd_5501_8; + BYTE MMC3_mode,MMC3_reg,MMC3_prg0,MMC3_prg1; + BYTE MMC3_chr4,MMC3_chr5,MMC3_chr6,MMC3_chr7; + + INT read_mode,read_mode1; + +private: + void SetBank_CPU(); + void WriteCPU_PRAM( WORD addr, BYTE data ); + void MMC3_WriteH( WORD addr, BYTE data ); + void MMC3_SetBank_CPU(); + void MMC3_SetBank_PPU(); + + LPBYTE Load_DiskIMG(); + LPBYTE lpDisk, DISK; + + //for FDC code by fanoble +#define FDC_MS_BUSYS0 0x01 // FDD0 in SEEK mode +#define FDC_MS_BUSYS1 0x02 // FDD1 in SEEK mode +#define FDC_MS_BUSYS2 0x04 // FDD2 in SEEK mode +#define FDC_MS_BUSYS3 0x08 // FDD3 in SEEK mode +#define FDC_MS_BUSYRW 0x10 // Read or Write in progress +#define FDC_MS_EXECUTION 0x20 // Execution Mode +#define FDC_MS_DATA_IN 0x40 // Data input or output +#define FDC_MS_RQM 0x80 // Request for Master, Ready + +#define FDC_S0_US0 0x01 // Unit Select 0 +#define FDC_S0_US1 0x02 // Unit Select 1 +#define FDC_S0_HD 0x04 // Head Address +#define FDC_S0_NR 0x08 // Not Ready +#define FDC_S0_EC 0x10 // Equipment Check +#define FDC_S0_SE 0x20 // Seek End +#define FDC_S0_IC0 0x40 // Interrupt Code +#define FDC_S0_IC1 0x80 // NT/AT/IC/XX + +#define FDC_S1_MA 0x01 // Missing Address Mark +#define FDC_S1_NW 0x02 // Not Writable +#define FDC_S1_ND 0x04 // No Data +#define FDC_S1_OR 0x10 // Over Run +#define FDC_S1_DE 0x20 // Data Error +#define FDC_S1_EN 0x80 // End of Cylinder + +#define FDC_S2_MD 0x01 // Missing Address Mark in Data Field +#define FDC_S2_BC 0x02 // Bad Cylinder +#define FDC_S2_SN 0x04 // Scan Not Satisfied +#define FDC_S2_SH 0x08 // Scan Equal Hit +#define FDC_S2_WC 0x10 // Wrong Cylinder +#define FDC_S2_DD 0x20 // Data Error in Data Field +#define FDC_S2_CM 0x40 // Control Mark + +#define FDC_S3_US0 0x01 // Unit Select 0 +#define FDC_S3_US1 0x02 // Unit Select 1 +#define FDC_S3_HD 0x04 // Side Select +#define FDC_S3_TS 0x08 // Two Side +#define FDC_S3_T0 0x10 // Track 0 +#define FDC_S3_RY 0x20 // Ready +#define FDC_S3_WP 0x40 // Write Protect +#define FDC_S3_FT 0x80 // Fault + +#define FDC_CC_MASK 0x1F +#define FDC_CF_MT 0x80 +#define FDC_CF_MF 0x40 +#define FDC_CF_SK 0x20 +#define FDC_CC_READ_TRACK 0x02 +#define FDC_CC_SPECIFY 0x03 +#define FDC_CC_SENSE_DRIVE_STATUS 0x04 +#define FDC_CC_WRITE_DATA 0x05 +#define FDC_CC_READ_DATA 0x06 +#define FDC_CC_RECALIBRATE 0x07 +#define FDC_CC_SENSE_INTERRUPT_STATUS 0x08 +#define FDC_CC_WRITE_DELETED_DATA 0x09 +#define FDC_CC_READ_ID 0x0A +#define FDC_CC_READ_DELETED_DATA 0x0C +#define FDC_CC_FORMAT_TRACK 0x0D +#define FDC_CC_SEEK 0x0F +#define FDC_CC_SCAN_EQUAL 0x11 +#define FDC_CC_SCAN_LOW_OR_EQUAL 0x19 +#define FDC_CC_SCAN_HIGH_OR_EQUAL 0x1D +#define FDC_PH_IDLE 0 +#define FDC_PH_COMMAND 1 +#define FDC_PH_EXECUTION 2 +#define FDC_PH_RESULT 3 + + const FDC_CMD_DESC* pFdcCmd; + BOOL bFdcIrq; + BOOL bFdcHwReset; + BOOL bFdcSoftReset; + BOOL bFdcDmaInt; + UINT nFdcDrvSel; + UINT nFdcMotor; + BYTE nFdcMainStatus; + BYTE nFDCStatus[4]; + BYTE bFdcCycle; + BYTE bFdcCommands[10]; + BYTE bFdcResults[8]; + BYTE bFdcPhase; + BYTE nFdcCylinder; + BYTE nFdcHeadAddres; + BYTE nFdcRecord; + BYTE nFdcNumber; + LPBYTE pFdcDataPtr; + +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.rar b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.rar new file mode 100644 index 00000000..d5d0f4f4 Binary files /dev/null and b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper169.rar differ diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper170.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper170.cpp new file mode 100644 index 00000000..6ca0a300 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper170.cpp @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper170 PYRAMID // +////////////////////////////////////////////////////////////////////////// +void Mapper170::Reset() +{ + for(INT i=0;i<8;i++) reg[i]=0; + for(i=0; i<32; i+=2) + { + memcpy( &WRAM00[0x400*i+0x000], PROM+0x400*((PROM_8K_SIZE*0x4+0x07)+i*8),0x400); + memcpy( &WRAM00[0x400*i+0x400], PROM+0x400*((PROM_8K_SIZE*0x4+0x0F)+i*8),0x400); + } + SetPROM_Bank0(); + p_mode = 0; + NT_data = 0; + ex_slot2 = 0; + ex_slot3 = 0; + nes->ppu->SetExtLatchMode( TRUE ); + + dip_s++; + if(dip_s==4) dip_s=0; + + Rom_Type = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0xFE31765B ){ //[PYRAMID] PEC-9588 Computer & Game (C) + Rom_Type = 1; + SetPROM_32K_Bank( 0, 1, 0x3E, 0x3F ); + } + if( crc == 0x428C1C1D //[FengLi] Zhong Ying Wen Dian Nao Ka (C) + || crc == 0x836CDDEF ){ //[BaTong] Zhong Ying Wen Dian Nao Ka (C) + Rom_Type = 2; + SetPROM_32K_Bank( 0 ); + } +} + +BYTE Mapper170::ReadLow( WORD addr ) +{ +// DEBUGOUT( "ReadLow - addr= %04x ; dat= %03x\n", addr, Mapper::ReadLow( addr ) ); + if(addr==0x5500) return ((dip_s&3)*0x10); //[0x00]=XinKe; [0x10]=KingWang; [0x20]=?ABC; [0x30]=KingWangEX + + if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void Mapper170::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF]=data; + + if(addr<0x6000){ + reg[(addr&0x700)>>8] = data; + p_mode = reg[0]&0x80; + if((reg[0]&0x18)==0x18) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); + + if( reg[0]&0x10 ){ // [PYRAMID] PEC-586 Computer & Game (C) + SetPROM_32K_Bank(reg[0]&0x07); + }else if((reg[0]&0x70)==0x40){ + SetPROM_Bank0(); + SetPROM_8K_Bank(4,(reg[0]&0x0F)|0x20); + }else if((reg[0]&0x70)==0x60){ + SetPROM_Bank0(); + SetPROM_8K_Bank(4,(reg[0]&0x0F)|0x30); + }else{ + SetPROM_Bank0(); + } + + if(Rom_Type==1){ // [PYRAMID] PEC-9588 Computer & Game (C) +// DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( reg[0]&0x70 ) { + case 0x00: + SetPROM_16K_Bank( 4, reg[0]&0x0F ); + SetPROM_16K_Bank( 6, 0x1F ); + break; + case 0x10: + // + break; + case 0x20: + SetPROM_16K_Bank( 4, (reg[0]&0x0F) | 0x10 ); + SetPROM_16K_Bank( 6, 0x1F ); + break; + case 0x30: //С2 + ex_slot2 = 1; +// SetPROM_16K_Bank( 4, (reg[0]&0x0F) | 0x20 ); +// SetPROM_16K_Bank( 6, 0x2F ); +// SetPROM_32K_Bank((reg[0]&0x07)|0x20); + break; + case 0x40: + SetPROM_16K_Bank( 4, reg[0]&0x0F ); + SetPROM_16K_Bank( 6, 0x1E ); + break; + case 0x50: //С3 + ex_slot3 = 1; + break; + case 0x60: + SetPROM_16K_Bank( 4, (reg[0]&0x0F) | 0x10 ); + SetPROM_16K_Bank( 6, 0x1E ); + if(reg[0]>=0x6C) SetPROM_16K_Bank( 6, 0x1C ); + break; + } + } + if(Rom_Type==2){ +// DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + SetPROM_32K_Bank(reg[0]&0x0F); + } + + } +} + +void Mapper170::PPU_Latch( WORD addr ) +{ + if((addr&0xF000)==0x2000){ + NT_data=(addr>>8)&0x03; + } +} +void Mapper170::PPU_ExtLatchX( INT x ) +{ + a3 = (x&1)<<3; +} +void Mapper170::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr; + + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + if(p_mode){ + if(NT_data&0x02) tileadr |= 0x1000; + else tileadr &= ~0x1000; + tileadr = (tileadr&0xfff7)|a3; + chr_l = chr_h = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + }else{ + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + } +} +BYTE Mapper170::PPU_ExtLatchSP() //ɫ⣬δȫ +{ + if(p_mode) + return 2; //ʱ˴ԭδ֪ + return 0; +} +void Mapper170::SetPROM_Bank0(void) +{ + SetPROM_Bank(4, &WRAM00[0x2000*0], 0); + SetPROM_Bank(5, &WRAM00[0x2000*1], 0); + SetPROM_Bank(6, &WRAM00[0x2000*2], 0); + SetPROM_Bank(7, &WRAM00[0x2000*3], 0); +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper170.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper170.h new file mode 100644 index 00000000..07d27605 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper170.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper170 // +////////////////////////////////////////////////////////////////////////// + +class Mapper170 : public Mapper +{ +public: + Mapper170( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void PPU_Latch( WORD addr ); + void PPU_ExtLatchX( INT x ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + BYTE PPU_ExtLatchSP(); + +protected: + BYTE reg[8], Rom_Type; + BYTE dip_s; + + BYTE WRAM00[128*1024]; + BYTE a3, p_mode, NT_data; + BYTE ex_slot2, ex_slot3; + +private: + void SetPROM_Bank0(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper171.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper171.cpp new file mode 100644 index 00000000..d9be5541 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper171.cpp @@ -0,0 +1,787 @@ +/******************************************************************************* + * NES Mapper for BBK + * + * Author: + * + * Create: 2014-06-24, by fanoble + ******************************************************************************* + */ + +static const Mapper171::FDC_CMD_DESC FdcCmdTableB[32] = +{ + /* 0x00 */ { 1, 1, Mapper171::FdcNop }, + /* 0x01 */ { 1, 1, Mapper171::FdcNop }, + /* 0x02 */ { 9, 7, Mapper171::FdcReadTrack }, + /* 0x03 */ { 3, 0, Mapper171::FdcSpecify }, + /* 0x04 */ { 2, 1, Mapper171::FdcSenseDriveStatus }, + /* 0x05 */ { 9, 7, Mapper171::FdcWriteData }, + /* 0x06 */ { 9, 7, Mapper171::FdcReadData }, + /* 0x07 */ { 2, 0, Mapper171::FdcRecalibrate }, + /* 0x08 */ { 1, 2, Mapper171::FdcSenseIntStatus }, + /* 0x09 */ { 9, 7, Mapper171::FdcWriteDeletedData }, + /* 0x0A */ { 2, 7, Mapper171::FdcReadID }, + /* 0x0B */ { 1, 1, Mapper171::FdcNop }, + /* 0x0C */ { 9, 7, Mapper171::FdcReadDeletedData }, + /* 0x0D */ { 6, 7, Mapper171::FdcFormatTrack }, + /* 0x0E */ { 1, 1, Mapper171::FdcNop }, + /* 0x0F */ { 3, 0, Mapper171::FdcSeek }, + /* 0x10 */ { 1, 1, Mapper171::FdcNop }, + /* 0x11 */ { 9, 7, Mapper171::FdcScanEqual }, + /* 0x12 */ { 1, 1, Mapper171::FdcNop }, + /* 0x13 */ { 1, 1, Mapper171::FdcNop }, + /* 0x14 */ { 1, 1, Mapper171::FdcNop }, + /* 0x15 */ { 1, 1, Mapper171::FdcNop }, + /* 0x16 */ { 1, 1, Mapper171::FdcNop }, + /* 0x17 */ { 1, 1, Mapper171::FdcNop }, + /* 0x18 */ { 1, 1, Mapper171::FdcNop }, + /* 0x19 */ { 9, 7, Mapper171::FdcScanLowOrEqual }, + /* 0x1A */ { 1, 1, Mapper171::FdcNop }, + /* 0x1B */ { 1, 1, Mapper171::FdcNop }, + /* 0x1C */ { 1, 1, Mapper171::FdcNop }, + /* 0x1D */ { 9, 7, Mapper171::FdcScanHighOrEqual }, + /* 0x1E */ { 1, 1, Mapper171::FdcNop }, + /* 0x1F */ { 1, 1, Mapper171::FdcNop }, +}; + +void Mapper171::Reset() +{ + DISK = Load_DiskIMG(); + + pFdcDataPtr = DISK; + + // BIOS fixed to Page FE + BIOS = BDRAM + 0x78000; + + memset(BDRAM, 0, sizeof(BDRAM)); + + // 4xxx - 7xxx + SetPROM_Bank(2, BIOS + 0x0000, BANKTYPE_RAM); + SetPROM_Bank(3, BIOS + 0x2000, BANKTYPE_RAM); + + // 8xxx - Bxxx + SetPROM_Bank(4, BDRAM + 0x0000, BANKTYPE_RAM); + SetPROM_Bank(5, BDRAM + 0x2000, BANKTYPE_RAM); + + // Cxxx - Fxxx + SetPROM_16K_Bank(6, 7); + +// SetPROM_32K_Bank(0); + + SetYCRAM_8K_Bank(0); + + nPageCD = 0; + nPageEF = 0; + + // FDC + bFdcIrq = FALSE; + bFdcHwReset = FALSE; + bFdcSoftReset = FALSE; + bFdcDmaInt = FALSE; + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; + nFdcCylinder = 0; + + p_mode = 0; + NT_data = 0; + nes->ppu->SetExtLatchMode( TRUE ); + + irq_enable = 0; + irq_counter = 0; + + reg[0]=0; + reg[1]=0; + reg[2]=0; + reg[3]=0; + +} + +// 8000 - FFFF +BOOL Mapper171::ReadHigh(WORD addr, LPBYTE pdata) +{ + if (addr < 0xFF00 || + addr > 0xFFEF) + return FALSE; + + switch (addr) + { + case 0xFF18: // ϵͳ; + DEBUGOUT( "ReadH A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, bFdcResults[bFdcCycle]&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + *pdata = 0x8F; + return TRUE; + + case 0xFF80: // FDCDMADackIO + *pdata = *pFdcDataPtr++; + return TRUE; + case 0xFF88: // FDCDMATcIO + *pdata = *pFdcDataPtr++; + return TRUE; + case 0xFF90: // FDCDRQPortI/FDCCtrlPortO + // I: D6 : FDC DRQ + *pdata = 0x40; + return TRUE; + case 0xFF98: // FDCIRQPortI/FDCDMADackIO + // I: D6 : IRQ + if (bFdcIrq) + *pdata = 0x40; + else + *pdata = 0; + return TRUE; + + case 0xFFA0: // FDCResetPortO/FDCStatPortI + // I: D7 : FDC ready + // I: D6 : FDC dir + // I: D5 : FDC busy + *pdata = nFdcMainStatus; +// DEBUGOUT( "ReadH A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, nFdcMainStatus&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + return TRUE; + case 0xFFA8: // FDCDataPortIO + *pdata = bFdcResults[bFdcCycle]; + bFdcCycle++; + if (bFdcCycle == pFdcCmd->bRLength) + { + // prepare for next command + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; + + nFdcMainStatus &= ~FDC_MS_DATA_IN; + nFdcMainStatus |= FDC_MS_RQM; + } + return TRUE; + case 0xFFB8: // FDCChangePortI/FDCSpeedPortO + // I: D7 : Disk changed + *pdata = 0; + return TRUE; + + default: + DEBUGOUT("Read %02X\n", addr); + break; + } + + return FALSE; +} + +void Mapper171::Write(WORD addr, BYTE data) +{ + + if (addr < 0xFF00) + { + CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data; +// Write_PRAM( addr, data ); + return; + } + + DEBUGOUT( "WriteH A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch (addr&0xFF) //0xFF00-0xFFFF + { + case 0x00: + reg[1] = data; + break; + case 0x01: // VideoCtrlPort + // D3 : C000-FFFF map to DRAM/-ROM + // D2 : INT count/-load + // D[1:0] : 6116's AV10 connection + // 00: AV10 + // 01: AV11 + // 10: AV0 + // 11: AV1 + + p_mode = data&0x40; + reg[2] = data&0x08; + + reg[0] = data&0x03; + if(reg[0]==0) SetVRAM_Mirror( VRAM_VMIRROR ); + else if(reg[0]==1) SetVRAM_Mirror( VRAM_HMIRROR ); + else if(reg[0]==2) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + + if(data&0x4){ + irq_enable = 1; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + }else{ +// irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + + if(data&8){ + // map C000-FFF to DRAM +// int nOffset; +// nOffset = nPageCD * 0x2000; +// nOffset &= 0x7FFFF; // truncate to 512K +// SetPROM_Bank(6, BDRAM + nOffset, BANKTYPE_RAM); +// nOffset = nPageEF * 0x2000; +// nOffset &= 0x7FFFF; // truncate to 512K +// SetPROM_Bank(7, BDRAM + nOffset, BANKTYPE_RAM); + + SetBDRAM_8K_Bank(6 , nPageCD&0x3F); + SetBDRAM_8K_Bank(7 , nPageEF&0x3F); + } + else{ + // map C000-FFF to ROM + SetPROM_16K_Bank(6, 7); + } + break; + +// case 0x02: // IntCountPortL + // D[4:0] : counter +// break; + + case 0x03: // VideoDataPort0 + data &= 0x0F; + SetYCRAM_2K_Bank( 0, data); + break; + + case 0x04: // DRAMPagePort +// data &= 0x1F; // 512K +// SetPROM_Bank(4, BDRAM + data * 0x4000 + 0x0000, BANKTYPE_RAM); +// SetPROM_Bank(5, BDRAM + data * 0x4000 + 0x2000, BANKTYPE_RAM); + + SetBDRAM_16K_Bank(4 , data&0x1F); + if(((reg[1]==4)||p_mode)&&(data<0xE0)) SetPROM_16K_Bank(4, data&7); + break; +/* + case 0x0A: + break; + case 0x1A: + reg[3] = data; + break; + case 0x12: +// reg12 = data; + break; + case 0x22: +// reg22 = data; + break; +*/ + case 0x0B: // VideoDataPort1 + data &= 0x0F; // 32K + SetYCRAM_2K_Bank( 2, data); + break; + +// case 0x10: // SoundPort0/SpeakInitPort + // +// break; + + case 0x13: // VideoDataPort2 + data &= 0x0F; // 32K + SetYCRAM_2K_Bank( 4, data); + break; + + case 0x14: + data &= 0x3F; + SetBDRAM_8K_Bank(4 , data); + break; + +// case 0x18: // ϵͳ; +// data = data; +// break; + + case 0x1B: // VideoDataPort3 + data &= 0x0F; // 32K + SetYCRAM_2K_Bank( 6, data); + break; + + case 0x1C: + data &= 0x3F; + SetBDRAM_8K_Bank(5 , data); + break; + + case 0x24: // DRAMPagePortCD + nPageCD = data; + if(reg[2]) SetBDRAM_8K_Bank(6 , data&0x3F); + break; + case 0x2C: // DRAMPagePortEF + nPageEF = data; + if(reg[2]) SetBDRAM_8K_Bank(7 , data&0x3F); + break; + +// case 0x40: // PCDaCtPortO/PCCDataPort + // D4 : Signal to PC's ERROR + // D[3:0] : Output PC data +// break; +// case 0x48: // PCCtrlPortI/PCCStatsPortI/PCDataPortIH + // D[7:4] : PC input data + // D3 : Signal of PC's pin STB +// break; +// case 0x50: // PCDataPortIL/PCCCtrlPoutO + // D[3:0] : PC input data +// break; + +// case 0x80: // FDCDMADackIO +// data = data; +// break; +// case 0x88: // FDCDMATcIO +// data = data; +// break; + + case 0x90: // FDCDRQPortI/FDCCtrlPortO + // O: D5 : Drv B motor + // O: D4 : Drv A motor + // O: D3 : Enable INT and DMA + // O: D2 : not FDC Reset + // O: D[1:0] : Drv sel + + bFdcDmaInt = (data & 8) ? TRUE : FALSE; + nFdcDrvSel = data & 3; + nFdcMotor = data >> 4; + + if (data & 4) + { + if (bFdcSoftReset) + { + FdcSoftReset(); + + bFdcSoftReset = FALSE; + + // irq after soft reset + if (0 == nFdcDrvSel) + bFdcIrq = TRUE; // Drv A Only + else + bFdcIrq = FALSE; + } + } + else + { + if (!bFdcSoftReset) + { + bFdcSoftReset = TRUE; + bFdcIrq = FALSE; + } + } + + break; +// case 0x98: // FDCIRQPortI/FDCDMADackIO + // I: D6 : IRQ +// data = data; +// break; + case 0xA0: // FDCResetPortO/FDCStatPortI + // O: D6 : FDC pin reset + if (data & 0x40) + { + if (!bFdcHwReset) + { + bFdcHwReset = TRUE; + bFdcIrq = FALSE; + } + } + else + { + if (bFdcHwReset) + { + FdcHardReset(); + bFdcHwReset = FALSE; + } + } + break; + case 0xA8: // FDCDataPortIO + switch (bFdcPhase) + { + case FDC_PH_EXECUTION: + case FDC_PH_RESULT: + // ERROR + break; + case FDC_PH_IDLE: + default: + bFdcCycle = 0; + bFdcPhase = FDC_PH_COMMAND; + pFdcCmd = &FdcCmdTableB[data & FDC_CC_MASK]; + // fall through + case FDC_PH_COMMAND: + bFdcCommands[bFdcCycle] = data; + bFdcCycle++; + if (bFdcCycle == pFdcCmd->bWLength) + { + bFdcPhase = FDC_PH_EXECUTION; +// nFdcMainStatus &= ~FDC_MS_RQM; + pFdcCmd->pFun(this); + if (pFdcCmd->bRLength) // prepare for reading + { + nFdcMainStatus |= FDC_MS_DATA_IN; + bFdcPhase = FDC_PH_RESULT; + } + else + { + bFdcPhase = FDC_PH_IDLE; + } + bFdcCycle = 0; + } + break; + } + break; +// case 0xB8: // FDCChangePortI/FDCSpeedPortO + // I: D7 : Disk changed + // O: D[1:0] : 00 500kbps(1.2M, 1.44M) + // 01 300kbps(360K) + // 10 250kbps(720K) +// data = data; +// break; + +// case 0x09: +// case 0x17: +// data = data; +// break; + + // code patch +// case 0x2B: +// CPU_MEM_BANK[7][addr & 0x1FFF] = data; +// break; + + default: + DEBUGOUT("Write %02X -> [%04X]\n", data, addr); + break; + } +} + +// 4100 - 7FFF +BYTE Mapper171::ReadLow(WORD addr) +{ + BYTE data = 0; + + if (addr < 0x4400) + { + // 4100 - 43FF, IO for system + data = BIOS[addr - 0x4000]; + } + else if (addr < 0x5800) + { + // 4400 - 57FF, IO for ROM/RAM + data = BIOS[addr - 0x4000]; + } + else if (addr < 0x6000) + { + // 5800 - 5FFF, 2K RAM + data = BIOS[addr - 0x4000]; + } + else if (addr < 0x6100) + { + // 6000 - 60FF, reserved + data = BIOS[addr - 0x4000]; + } + else + { + // 6100 - 7FFF, RAM + data = BIOS[addr - 0x4000]; + } + + return data; +} + +// 4100 - 7FFF +void Mapper171::WriteLow(WORD addr, BYTE data) +{ + if (addr < 0x4400) + { + // 4100 - 43FF, IO for system + BIOS[addr - 0x4000] = data; + } + else if (addr < 0x5800) + { + // 4400 - 57FF, IO for ROM/RAM + BIOS[addr - 0x4000] = data; + } + else if (addr < 0x6000) + { + // 5800 - 5FFF, 2K RAM + BIOS[addr - 0x4000] = data; + } + else if (addr < 0x6100) + { + // 6000 - 60FF, reserved + BIOS[addr - 0x4000] = data; + } + else + { + // 6100 - 7FFF, RAM + BIOS[addr - 0x4000] = data; + } +} + +void Mapper171::Write_PRAM( WORD addr, BYTE data ) +{ + if(addr<0xC000){ +// BDRAM[(addr-0x8000)+(bank*0x4000)] = data; + CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data; + }else{ + BDRAM[addr+0x70000] = data; + } +} +/* +void Mapper171::Clock( INT cycles ) +{ + if( irq_enable ) { + if( (irq_counter+=cycles) >= 0x7FFF ) { +// irq_counter = 0x7FFF; +// nes->cpu->IRQ_NotPending(); + + irq_enable = 0; +// irq_counter &= 0x7FFF; + irq_counter = 0x7FFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper171::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { +// SetYCRAM_2K_Bank( 0, (scanline&0xF0)>>4); + if( irq_enable ) { + + irq_enable = 0; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} +*/ + +void Mapper171::PPU_Latch( WORD addr ) +{ + if((addr&0xF000)==0x2000){ + NT_data=(addr>>6)&0x0F; + if(p_mode){ +// SetYCRAM_2K_Bank( 0, NT_data); +// SetYCRAM_2K_Bank( 2, NT_data); +// SetYCRAM_2K_Bank( 4, NT_data); +// SetYCRAM_2K_Bank( 6, NT_data); + } + } + + if((DirectInput.m_Sw[DIK_PGUP])&&(DirectInput.m_Sw[DIK_PGDN])){ + DISK = Change_DiskIMG(); + pFdcDataPtr = DISK; + } + + if(DirectInput.m_Sw[DIK_PAUSE]){ + nes->Dump_BDRAM(); + nes->Dump_YCRAM(); + nes->Dump_VRAM(); + nes->Dump_CPULMEM(); + nes->Dump_CPUHMEM(); + } +} +void Mapper171::PPU_ExtLatchX( INT x ) +{ + a3 = (x&1)<<3; +} +void Mapper171::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr, ntb; + + ntb = (ntbladr>>6)&0x0F; + + if(p_mode){ +// SetYCRAM_2K_Bank( 0, ntb); +// SetYCRAM_2K_Bank( 2, NT_data); +// SetYCRAM_2K_Bank( 4, NT_data); +// SetYCRAM_2K_Bank( 6, NT_data); + } + +// DEBUGOUT("ntb=%04X tileofs=%02X\n", ntb, tileofs ); + + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; +} + +LPBYTE Mapper171::Load_DiskIMG() +{ + FILE *fp = NULL; + if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + if( !(fp = ::fopen( img_fname, "rb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, img_fname ); + throw szErrorString; + } + ::fread(lpDisk, 0x168000, 1, fp); + FCLOSE(fp); + return lpDisk; +} +LPBYTE Mapper171::Change_DiskIMG() +{ + FILE *fp = NULL; + if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + if( !(fp = ::fopen( "BBK.IMG", "rb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, "BBK.img" ); + throw szErrorString; + } + ::fread(lpDisk, 0x168000, 1, fp); + FCLOSE(fp); + return lpDisk; +} + +// for FDC +void Mapper171::FdcHardReset(void) +{ + DEBUGOUT( "FdcHardReset!!!\n" ); + bFdcDmaInt = FALSE; + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; +} +void Mapper171::FdcSoftReset(void) +{ + DEBUGOUT( "FdcSoftReset!!!\n" ); + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; +} +void Mapper171::FdcNop(Mapper171* thiz) +{ + DEBUGOUT( "FdcNop!!!\n" ); + thiz->nFDCStatus[0] = FDC_S0_IC1; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; +} +void Mapper171::FdcReadTrack(Mapper171* thiz) +{ + DEBUGOUT( "FdcReadTrack!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcSpecify(Mapper171* thiz) +{ + DEBUGOUT( "FdcSpecify!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcSenseDriveStatus(Mapper171* thiz) +{ + DEBUGOUT( "FdcSenseDriveStatus!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcWriteData(Mapper171* thiz) +{ + DEBUGOUT( "FdcWriteData!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcReadData(Mapper171* thiz) +{ + DEBUGOUT( "FdcReadData!!!\n" ); + BYTE C = thiz->bFdcCommands[2]; + BYTE H = thiz->bFdcCommands[3]; + BYTE R = thiz->bFdcCommands[4]; + BYTE N = thiz->bFdcCommands[5]; + INT LBA; + LBA = H * 18 + C * 36 + (R - 1); + thiz->pFdcDataPtr = thiz->DISK + LBA * 512; + R++; + if (19 == R) + { + R = 1; + H++; + if (2 == H) + { + C++; + if (80 == C) + C = 0; + } + } + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 + thiz->bFdcResults[3] = C; + thiz->bFdcResults[4] = H; + thiz->bFdcResults[5] = R; + thiz->bFdcResults[6] = N; +} +void Mapper171::FdcRecalibrate(Mapper171* thiz) +{ + DEBUGOUT( "FdcRecalibrate!!!\n" ); + BYTE US; + US = thiz->bFdcCommands[1] & 3; + if (0 == US) + thiz->nFDCStatus[0] = FDC_S0_SE; + else + thiz->nFDCStatus[0] = FDC_S0_SE | FDC_S0_IC0; +} +void Mapper171::FdcSenseIntStatus(Mapper171* thiz) +{ + DEBUGOUT( "FdcSenseIntStatus!!!\n" ); + if (0 == thiz->nFdcDrvSel) // Drv A Only + thiz->nFDCStatus[0] = FDC_S0_IC0 | FDC_S0_IC1; + else + thiz->nFDCStatus[0] = FDC_S0_SE | FDC_S0_IC0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; + thiz->bFdcResults[1] = thiz->nFdcCylinder; // PCN +} +void Mapper171::FdcWriteDeletedData(Mapper171* thiz) +{ + DEBUGOUT( "FdcWriteDeletedData!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcReadID(Mapper171* thiz) +{ + DEBUGOUT( "FdcReadID!!!\n" ); + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; +} +void Mapper171::FdcReadDeletedData(Mapper171* thiz) +{ + DEBUGOUT( "FdcReadDeletedData!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcFormatTrack(Mapper171* thiz) +{ + DEBUGOUT( "FdcFormatTrack!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcSeek(Mapper171* thiz) +{ + DEBUGOUT( "FdcSeek!!!\n" ); + // new cylinder number + BYTE NCN; + BYTE US; + US = thiz->bFdcCommands[1] & 3; + NCN = thiz->bFdcCommands[2]; + thiz->nFdcCylinder = NCN; + thiz->nFDCStatus[0] = FDC_S0_SE; +} +void Mapper171::FdcScanEqual(Mapper171* thiz) +{ + DEBUGOUT( "FdcScanEqual!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcScanLowOrEqual(Mapper171* thiz) +{ + DEBUGOUT( "FdcScanLowOrEqual!!!\n" ); + thiz = thiz; +} +void Mapper171::FdcScanHighOrEqual(Mapper171* thiz) +{ + DEBUGOUT( "FdcScanHighOrEqual!!!\n" ); + thiz = thiz; +} + +/******************************************************************************* + E N D O F F I L E +*******************************************************************************/ diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper171.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper171.h new file mode 100644 index 00000000..0a4a5e9c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper171.h @@ -0,0 +1,170 @@ +/******************************************************************************* + * NES Mapper for BBK + * + * Author: + * + * Create: 2014-06-24, by fanoble + ******************************************************************************* + */ + +class Mapper171 : public Mapper +{ +public: + Mapper171( NES* parent ) : Mapper(parent) {} + + void Reset(); + + // 8000 - FFFF + BOOL ReadHigh( WORD addr, LPBYTE pdata ); + void Write( WORD addr, BYTE data ); + + // 4100 - 7FFF + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + +// void Clock( INT cycles ); +// void HSync( INT scanline ); + + void PPU_Latch( WORD addr ); + void PPU_ExtLatchX( INT x ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + + void FdcHardReset(void); + void FdcSoftReset(void); + + static void FdcNop(Mapper171* thiz); + static void FdcReadTrack(Mapper171* thiz); + static void FdcSpecify(Mapper171* thiz); + static void FdcSenseDriveStatus(Mapper171* thiz); + static void FdcWriteData(Mapper171* thiz); + static void FdcReadData(Mapper171* thiz); + static void FdcRecalibrate(Mapper171* thiz); + static void FdcSenseIntStatus(Mapper171* thiz); + static void FdcWriteDeletedData(Mapper171* thiz); + static void FdcReadID(Mapper171* thiz); + static void FdcReadDeletedData(Mapper171* thiz); + static void FdcFormatTrack(Mapper171* thiz); + static void FdcSeek(Mapper171* thiz); + static void FdcScanEqual(Mapper171* thiz); + static void FdcScanLowOrEqual(Mapper171* thiz); + static void FdcScanHighOrEqual(Mapper171* thiz); + + typedef struct tagFDC_CMD_DESC + { + BYTE bWLength; + BYTE bRLength; + void (*pFun)(Mapper171*); + } FDC_CMD_DESC; + +protected: +private: + + // for FDC + BOOL bFdcIrq; + BOOL bFdcHwReset; + BOOL bFdcSoftReset; + + BOOL bFdcDmaInt; + UINT nFdcDrvSel; + UINT nFdcMotor; + +#define FDC_MS_BUSYS0 0x01 // FDD0 in SEEK mode +#define FDC_MS_BUSYS1 0x02 // FDD1 in SEEK mode +#define FDC_MS_BUSYS2 0x04 // FDD2 in SEEK mode +#define FDC_MS_BUSYS3 0x08 // FDD3 in SEEK mode +#define FDC_MS_BUSYRW 0x10 // Read or Write in progress +#define FDC_MS_EXECUTION 0x20 // Execution Mode +#define FDC_MS_DATA_IN 0x40 // Data input or output +#define FDC_MS_RQM 0x80 // Request for Master, Ready + BYTE nFdcMainStatus; + +#define FDC_S0_US0 0x01 // Unit Select 0 +#define FDC_S0_US1 0x02 // Unit Select 1 +#define FDC_S0_HD 0x04 // Head Address +#define FDC_S0_NR 0x08 // Not Ready +#define FDC_S0_EC 0x10 // Equipment Check +#define FDC_S0_SE 0x20 // Seek End +#define FDC_S0_IC0 0x40 // Interrupt Code +#define FDC_S0_IC1 0x80 // NT/AT/IC/XX + +#define FDC_S1_MA 0x01 // Missing Address Mark +#define FDC_S1_NW 0x02 // Not Writable +#define FDC_S1_ND 0x04 // No Data +#define FDC_S1_OR 0x10 // Over Run +#define FDC_S1_DE 0x20 // Data Error +#define FDC_S1_EN 0x80 // End of Cylinder + +#define FDC_S2_MD 0x01 // Missing Address Mark in Data Field +#define FDC_S2_BC 0x02 // Bad Cylinder +#define FDC_S2_SN 0x04 // Scan Not Satisfied +#define FDC_S2_SH 0x08 // Scan Equal Hit +#define FDC_S2_WC 0x10 // Wrong Cylinder +#define FDC_S2_DD 0x20 // Data Error in Data Field +#define FDC_S2_CM 0x40 // Control Mark + +#define FDC_S3_US0 0x01 // Unit Select 0 +#define FDC_S3_US1 0x02 // Unit Select 1 +#define FDC_S3_HD 0x04 // Side Select +#define FDC_S3_TS 0x08 // Two Side +#define FDC_S3_T0 0x10 // Track 0 +#define FDC_S3_RY 0x20 // Ready +#define FDC_S3_WP 0x40 // Write Protect +#define FDC_S3_FT 0x80 // Fault + BYTE nFDCStatus[4]; + +#define FDC_CC_MASK 0x1F +#define FDC_CF_MT 0x80 +#define FDC_CF_MF 0x40 +#define FDC_CF_SK 0x20 + +#define FDC_CC_READ_TRACK 0x02 +#define FDC_CC_SPECIFY 0x03 +#define FDC_CC_SENSE_DRIVE_STATUS 0x04 +#define FDC_CC_WRITE_DATA 0x05 +#define FDC_CC_READ_DATA 0x06 +#define FDC_CC_RECALIBRATE 0x07 +#define FDC_CC_SENSE_INTERRUPT_STATUS 0x08 +#define FDC_CC_WRITE_DELETED_DATA 0x09 +#define FDC_CC_READ_ID 0x0A +#define FDC_CC_READ_DELETED_DATA 0x0C +#define FDC_CC_FORMAT_TRACK 0x0D +#define FDC_CC_SEEK 0x0F +#define FDC_CC_SCAN_EQUAL 0x11 +#define FDC_CC_SCAN_LOW_OR_EQUAL 0x19 +#define FDC_CC_SCAN_HIGH_OR_EQUAL 0x1D + BYTE bFdcCycle; + BYTE bFdcCommands[10]; + BYTE bFdcResults[8]; + const FDC_CMD_DESC* pFdcCmd; + +#define FDC_PH_IDLE 0 +#define FDC_PH_COMMAND 1 +#define FDC_PH_EXECUTION 2 +#define FDC_PH_RESULT 3 + BYTE bFdcPhase; + + BYTE nFdcCylinder; + BYTE nPageCD; + BYTE nPageEF; + + LPBYTE pFdcDataPtr; + + // for ROM and RAM +// BYTE BIOS[0x4000]; + void Write_PRAM( WORD addr, BYTE data ); + LPBYTE Load_DiskIMG(); + LPBYTE Change_DiskIMG(); + LPBYTE BIOS; + LPBYTE DISK; + LPBYTE lpDisk; + + BYTE reg[8]; + BYTE irq_enable; + WORD irq_counter; + BYTE a3, p_mode, NT_data; + +}; + +/******************************************************************************* + E N D O F F I L E +*******************************************************************************/ diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.cpp new file mode 100644 index 00000000..170741f5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.cpp @@ -0,0 +1,591 @@ + +static const Mapper172::FDC_CMD_DESC FdcCmdTableJ[32] = +{ + /* 0x00 */ { 1, 1, Mapper172::FdcNop }, + /* 0x01 */ { 1, 1, Mapper172::FdcNop }, + /* 0x02 */ { 9, 7, Mapper172::FdcReadTrack }, + /* 0x03 */ { 3, 0, Mapper172::FdcSpecify }, + /* 0x04 */ { 2, 1, Mapper172::FdcSenseDriveStatus }, + /* 0x05 */ { 9, 7, Mapper172::FdcWriteData }, + /* 0x06 */ { 9, 7, Mapper172::FdcReadData }, + /* 0x07 */ { 2, 0, Mapper172::FdcRecalibrate }, + /* 0x08 */ { 1, 2, Mapper172::FdcSenseIntStatus }, + /* 0x09 */ { 9, 7, Mapper172::FdcWriteDeletedData }, + /* 0x0A */ { 2, 7, Mapper172::FdcReadID }, + /* 0x0B */ { 1, 1, Mapper172::FdcNop }, + /* 0x0C */ { 9, 7, Mapper172::FdcReadDeletedData }, + /* 0x0D */ { 6, 7, Mapper172::FdcFormatTrack }, + /* 0x0E */ { 1, 1, Mapper172::FdcNop }, + /* 0x0F */ { 3, 0, Mapper172::FdcSeek }, + /* 0x10 */ { 1, 1, Mapper172::FdcNop }, + /* 0x11 */ { 9, 7, Mapper172::FdcScanEqual }, + /* 0x12 */ { 1, 1, Mapper172::FdcNop }, + /* 0x13 */ { 1, 1, Mapper172::FdcNop }, + /* 0x14 */ { 1, 1, Mapper172::FdcNop }, + /* 0x15 */ { 1, 1, Mapper172::FdcNop }, + /* 0x16 */ { 1, 1, Mapper172::FdcNop }, + /* 0x17 */ { 1, 1, Mapper172::FdcNop }, + /* 0x18 */ { 1, 1, Mapper172::FdcNop }, + /* 0x19 */ { 9, 7, Mapper172::FdcScanLowOrEqual }, + /* 0x1A */ { 1, 1, Mapper172::FdcNop }, + /* 0x1B */ { 1, 1, Mapper172::FdcNop }, + /* 0x1C */ { 1, 1, Mapper172::FdcNop }, + /* 0x1D */ { 9, 7, Mapper172::FdcScanHighOrEqual }, + /* 0x1E */ { 1, 1, Mapper172::FdcNop }, + /* 0x1F */ { 1, 1, Mapper172::FdcNop }, +}; + +void Mapper172::Reset() +{ + memcpy( YSRAM, PROM, 0x8000); + + ZEROMEMORY( JDRAM, sizeof(JDRAM) ); + ZEROMEMORY( JSRAM, sizeof(JSRAM) ); + ZEROMEMORY( JCRAM, sizeof(JCRAM) ); + + SetPROM_32K_Bank( 0 ); + + irq_enable = 0; + irq_counter = 0; + WE_SRAM = 0; + WE_DRAM = 0; + RE_DRAM = 1; + reg[0] = 0; + reg[1] = 0; + reg[2] = 0; + reg[3] = 0; + read_mode = 0; + read_mode1 = 0; + write_mode = 0; + write_mode1 = 0; + + //for FDC code by fanoble + lpDisk = NULL; + DISK = NULL; + if(Load_DiskIMG() != NULL) DISK = Load_DiskIMG(); + pFdcDataPtr = DISK; + bFdcIrq = FALSE; + bFdcHwReset = FALSE; + bFdcSoftReset = FALSE; + bFdcDmaInt = FALSE; + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; + nFdcCylinder = 0; + nFdcHeadAddres = 0; + nFdcRecord = 0; + nFdcNumber = 0; + +} + +BYTE Mapper172::ReadLow( WORD addr ) +{ +// if((addr<0x6000)&&(addr!=0x418E)) DEBUGOUT( "ReadLow - addr= %04x ; dat= %03x\n", addr, Mapper::ReadLow( addr ) ); + + switch (addr) + { + case 0x4188://FDC״̬Ĵ(STATUS) +// DEBUGOUT( "Read 0x4188 = %04X\n", nFdcMainStatus ); + return nFdcMainStatus; + break; + case 0x4189: + if(read_mode){ + read_mode1++; + if(read_mode1==512) read_mode=0; + reg[2] = *(pFdcDataPtr++); + return reg[2]; + } +// DEBUGOUT( "Read 0x4189 = %04X\n", bFdcResults[bFdcCycle] ); + read_mode1 = 0; + write_mode = 0; + reg[2] = bFdcResults[bFdcCycle]; + bFdcCycle++; + if (bFdcCycle == pFdcCmd->bRLength) + { + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; + nFdcMainStatus &= ~FDC_MS_DATA_IN; + nFdcMainStatus |= FDC_MS_RQM; + } + return reg[2]; + break; + case 0x418E: + if (bFdcIrq) + return 0xC0; + else + return 0x00; + + break; + case 0x41AC: + // + break; + } + + if((addr>=0x6000)&&(WE_SRAM==1)){ + return JSRAM[addr-0x6000]; + } + + if((addr>=0x6000)&&(RE_DRAM==1)){ +// if((addr>=0x6000)){ + return JDRAM[addr-0x6000+(reg[0]*0x8000)]; + } + + if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void Mapper172::WriteLow( WORD addr, BYTE data ) +{ + if((addr>=0x6000)&&(WE_SRAM==1)){ + JSRAM[addr-0x6000] = data; + } + + if((addr>=0x6000)&&(WE_DRAM==1)){ +// if((addr>=0x6000)){ + JDRAM[addr-0x6000+(reg[1]*0x8000)] = data; + } + + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + +// if((addr<0x6000)&&(addr!=0x418E)) DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + switch (addr) + { + case 0x4180: + DEBUGOUT( "Write 0x4180 = %04X\n", data ); + //s????xxx: BIOS ROM bankswitch register. + //Load page xxx (4K) of the BIOS ROM to the page frame at $e000. + //Also, s might be an enable for SRAM at $6000-$7fff. + // + WE_SRAM = data & 0x80; + + SetPROM_4K_Bank(0xE000, data&7); +// SetPROM_8K_Bank(7, data&7); + break; + case 0x4181: + //P?mmppcc: Game Mode Control. + //P=1 enables MMC2 CHR-ROM switch + //values of mm select game mode (00=old game, 01=new game, 10=MMC1, 11=MMC3) + //values of pp select PRG page size (00=8k, 01=16k, 10=32k, 11=invalid) + //values of cc select CHR page size (1 << cc KBytes). (same as Bung's doc) + // + DEBUGOUT( "Write 0x4181 = %04X\n", data ); + break; + case 0x4182: + //Rfffvvii: New game mode PPU Config. (same as Bung's doc) + // + DEBUGOUT( "Write 0x4181 = %04X\n", data ); + break; + case 0x4183: + //PPPPCCCC: PRG and CHR high address line masks (same as Bung's doc) + // + DEBUGOUT( "Write 0x4181 = %04X\n", data ); + break; + case 0x4185: + // + break; + case 0x4186: + //Send Parallel data. + break; + case 0x4189: +// DEBUGOUT( "Write 0x4189 = %04X\n", data ); + if(write_mode){ + write_mode1++; + if(write_mode1==512) write_mode=0; + *pFdcDataPtr = data; + pFdcDataPtr++; + } + write_mode1 = 0; + read_mode = 0; + switch (bFdcPhase) + { + case FDC_PH_EXECUTION: + case FDC_PH_RESULT: + // ERROR + break; + case FDC_PH_IDLE: + default: + bFdcCycle = 0; + bFdcPhase = FDC_PH_COMMAND; + pFdcCmd = &FdcCmdTableJ[data & FDC_CC_MASK]; + // fall through + case FDC_PH_COMMAND: + bFdcCommands[bFdcCycle] = data; + bFdcCycle++; + if (bFdcCycle == pFdcCmd->bWLength) + { + bFdcPhase = FDC_PH_EXECUTION; + + pFdcCmd->pFun(this); + + if (pFdcCmd->bRLength) + { + nFdcMainStatus |= FDC_MS_DATA_IN; + nFdcMainStatus |= FDC_MS_RQM; + bFdcPhase = FDC_PH_RESULT; + if((bFdcCommands[0]&0x0F)==0x06) read_mode = 1; + if((bFdcCommands[0]&0x0F)==0x05) write_mode = 1; + } + else + { + bFdcPhase = FDC_PH_IDLE; + } + + bFdcCycle = 0; + } + break; + } + break; + case 0x418A://DCR +// DEBUGOUT( "Write 0x418A = %04X\n", data ); + data = data; + break; + case 0x418B://FDCĴ(DOR)(ֿƼĴ) +// DEBUGOUT( "Write 0x418B = %04X\n", data ); + bFdcDmaInt = (data & 8) ? TRUE : FALSE; + nFdcDrvSel = data & 3; + nFdcMotor = data >> 4; + if (data & 4) + { + if (bFdcSoftReset) + { + FdcSoftReset(); + bFdcSoftReset = FALSE; + // irq after soft reset + if (0 == nFdcDrvSel) + bFdcIrq = TRUE; // Drv A Only + else + bFdcIrq = FALSE; + } + } + else + { + if (!bFdcSoftReset) + { + bFdcSoftReset = TRUE; + bFdcIrq = FALSE; + } + } + break; + case 0x418C: + // + break; + case 0x418D: + data = data&0x03; + if(data==0) SetVRAM_Mirror( VRAM_VMIRROR ); + else if(data==1) SetVRAM_Mirror( VRAM_HMIRROR ); + else if(data==2) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + case 0x418E: + // + break; + case 0x418F: + reg[3] = data; + break; + case 0x4190: + //????xxxx: Map 32k DRAM bank (of a possible 512k) to $6000-$DFFF for reading. + //Reading and writing function independently of each other. + WE_DRAM = 0; + RE_DRAM = 1; + reg[0] = data & 0x0F; + SetJDRAM_32K_Bank( reg[0] ); + break; + case 0x4191: + //????xxxx: Map 32k DRAM bank to $6000-$DFFF for writing. + WE_DRAM = 1; + RE_DRAM = 0; + reg[1] = data & 0x0F; + SetJDRAM_32K_Bank( reg[1] ); + break; + case 0x4194: + // + break; + case 0x4198: + //??xxxxxx: Map 8k DRAM bank to PPU 0x0000. + SetJCRAM_8K_Bank( data & 0x3F ); + break; + case 0x42FF: + // + break; + } + +} + +BOOL Mapper172::ReadHigh(WORD addr, LPBYTE pdata) +{ + if( addr>=0xE000 ) return FALSE; + if( RE_DRAM == 0 ) return FALSE; + *pdata = JDRAM[addr-0x6000+(reg[0]*0x8000)]; + return TRUE; +} + +void Mapper172::Write( WORD addr, BYTE data ) +{ +// if(addr>=0xE000) DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + + if( (addr<0xE000)&&(WE_DRAM==1) ) { +// if( (addr<0xE000) ) { + JDRAM[addr-0x6000+(reg[1]*0x8000)] = data; + }else{ + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + +void Mapper172::Clock( INT cycles ) +{ +/* if( irq_enable ) { + if( (irq_counter+=cycles) >= 0x7FFF ) { +// irq_counter = 0x7FFF; +// nes->cpu->IRQ_NotPending(); + + irq_enable = 0; +// irq_counter &= 0x7FFF; + irq_counter = 0x7FFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + }*/ +} + +void Mapper172::PPU_Latch( WORD addr ) +{ + if(DirectInput.m_Sw[DIK_PAUSE]){ +// nes->Dump_JDRAM(); +// nes->Dump_CPULMEM(); +// nes->Dump_CPUHMEM(); +// nes->Dump_YWRAM(); + } +} + +LPBYTE Mapper172::Load_DiskIMG() +{ + FILE *fp = NULL; + if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + if( !(fp = ::fopen( "DrPCJr.img", "rb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, "DrPCJr.img" ); + throw szErrorString; + } + ::fread(lpDisk, 0x168000, 1, fp); + FCLOSE(fp); + return lpDisk; +} + +//for FDC code by fanoble +void Mapper172::FdcHardReset(void) +{ + DEBUGOUT( "FdcHardReset!!!\n" ); + bFdcDmaInt = FALSE; + FdcSoftReset(); +} +void Mapper172::FdcSoftReset(void) +{ + DEBUGOUT( "FdcSoftReset!!!\n" ); + nFdcDrvSel = 0; + nFdcMotor = 0; + nFdcMainStatus = FDC_MS_RQM; + nFDCStatus[0] = 0; + nFDCStatus[1] = 0; + nFDCStatus[2] = 0; + nFDCStatus[3] = 0; + bFdcCycle = 0; + bFdcPhase = FDC_PH_IDLE; +} + +//(READ DATA) +void Mapper172::FdcReadData(Mapper172* thiz) +{ + DEBUGOUT( "FdcReadData!!!\n" ); + BYTE C = thiz->bFdcCommands[2]; //ŵ + BYTE H = thiz->bFdcCommands[3]; //ͷ + BYTE R = thiz->bFdcCommands[4]; // + BYTE N = thiz->bFdcCommands[5]; + INT LBA = H * 18 + C * 36 + (R - 1); + DEBUGOUT( "C = %04X\n", C ); + DEBUGOUT( "H = %04X\n", H ); + DEBUGOUT( "R = %04X\n", R ); + DEBUGOUT( "N = %04X\n", N ); + thiz->pFdcDataPtr = thiz->DISK + LBA * 512; + R++; + if (19 == R) + { + R = 1; + H++; + if (2 == H) + { + C++; + if (80 == C) + C = 0; + } + } + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 + thiz->bFdcResults[3] = C; + thiz->bFdcResults[4] = H; + thiz->bFdcResults[5] = R; + thiz->bFdcResults[6] = N; + thiz->nFdcCylinder = C; + thiz->nFdcHeadAddres = H; + thiz->nFdcRecord = R; + thiz->nFdcNumber = N; +} +//д(WRITE DATA) +void Mapper172::FdcWriteData(Mapper172* thiz) +{ + DEBUGOUT( "FdcWriteData!!!\n" ); + BYTE C = thiz->bFdcCommands[2]; //ŵ + BYTE H = thiz->bFdcCommands[3]; //ͷ + BYTE R = thiz->bFdcCommands[4]; // + BYTE N = thiz->bFdcCommands[5]; + INT LBA = H * 18 + C * 36 + (R - 1); + DEBUGOUT( "C = %04X\n", C ); + DEBUGOUT( "H = %04X\n", H ); + DEBUGOUT( "R = %04X\n", R ); + DEBUGOUT( "N = %04X\n", N ); + thiz->pFdcDataPtr = thiz->DISK + LBA * 512; + R++; + if (19 == R) + { + R = 1; + H++; + if (2 == H) + { + C++; + if (80 == C) + C = 0; + } + } + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 + thiz->bFdcResults[3] = C; + thiz->bFdcResults[4] = H; + thiz->bFdcResults[5] = R; + thiz->bFdcResults[6] = N; + thiz->nFdcCylinder = C; + thiz->nFdcHeadAddres = H; + thiz->nFdcRecord = R; + thiz->nFdcNumber = N; +} +void Mapper172::FdcNop(Mapper172* thiz) +{ + DEBUGOUT( "FdcNop!!!\n" ); + thiz->nFDCStatus[0] = FDC_S0_IC1; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; +} +void Mapper172::FdcReadTrack(Mapper172* thiz) +{ + DEBUGOUT( "FdcReadTrack!!!\n" ); + thiz = thiz; +} +void Mapper172::FdcSpecify(Mapper172* thiz) +{ + DEBUGOUT( "FdcSpecify!!!\n" ); + thiz = thiz; +} +void Mapper172::FdcSenseDriveStatus(Mapper172* thiz) +{ + DEBUGOUT( "FdcSenseDriveStatus!!!\n" ); + thiz->bFdcResults[0] = thiz->nFDCStatus[3]; +} +void Mapper172::FdcRecalibrate(Mapper172* thiz) +{ + DEBUGOUT( "FdcRecalibrate!!!\n" ); + thiz->nFdcCylinder = 0; //ͷص0ŵ + thiz->nFDCStatus[0] |= FDC_S0_SE; +} +void Mapper172::FdcSenseIntStatus(Mapper172* thiz) +{ + DEBUGOUT( "FdcSenseIntStatus!!!\n" ); + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; + thiz->bFdcResults[1] = thiz->nFdcCylinder; +} +void Mapper172::FdcWriteDeletedData(Mapper172* thiz) +{ + DEBUGOUT( "FdcWriteDeletedData!!!\n" ); + thiz = thiz; +} +void Mapper172::FdcReadID(Mapper172* thiz) +{ + DEBUGOUT( "FdcReadID!!!\n" ); + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; + thiz->bFdcResults[3] = thiz->nFdcCylinder; + thiz->bFdcResults[4] = thiz->nFdcHeadAddres; + thiz->bFdcResults[5] = thiz->nFdcRecord; + thiz->bFdcResults[6] = thiz->nFdcNumber; +} +void Mapper172::FdcReadDeletedData(Mapper172* thiz) +{ + DEBUGOUT( "FdcReadDeletedData!!!\n" ); + thiz = thiz; +} +void Mapper172::FdcFormatTrack(Mapper172* thiz) +{ + DEBUGOUT( "FdcFormatTrack!!!\n" ); + BYTE C = thiz->bFdcCommands[2]; //ŵ + BYTE H = thiz->bFdcCommands[3]; //ͷ + BYTE R = thiz->bFdcCommands[4]; // + BYTE N = thiz->bFdcCommands[5]; + + R++; + if (19 == R) + { + R = 1; + H++; + if (2 == H) + { + C++; + if (80 == C) + C = 0; + } + } + thiz->nFDCStatus[0] = 0; + thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 + thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 + thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 + thiz->bFdcResults[3] = C; + thiz->bFdcResults[4] = H; + thiz->bFdcResults[5] = R; + thiz->bFdcResults[6] = N; + thiz->nFdcCylinder = C; + thiz->nFdcHeadAddres = H; + thiz->nFdcRecord = R; + thiz->nFdcNumber = N; +} +void Mapper172::FdcSeek(Mapper172* thiz) +{ + DEBUGOUT( "FdcSeek!!!\n" ); + BYTE US; + US = thiz->bFdcCommands[1] & 3; + thiz->nFdcHeadAddres = ( thiz->bFdcCommands[1] & 7 ) >> 2; + thiz->nFdcCylinder = thiz->bFdcCommands[2]; + thiz->nFDCStatus[0] = FDC_S0_SE; +} +void Mapper172::FdcScanEqual(Mapper172* thiz) +{ + DEBUGOUT( "FdcScanEqual!!!\n" ); + thiz = thiz; +} +void Mapper172::FdcScanLowOrEqual(Mapper172* thiz) +{ + DEBUGOUT( "FdcScanLowOrEqual!!!\n" ); + thiz = thiz; +} +void Mapper172::FdcScanHighOrEqual(Mapper172* thiz) +{ + DEBUGOUT( "FdcScanHighOrEqual!!!\n" ); + thiz = thiz; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.h new file mode 100644 index 00000000..7b515b7a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.h @@ -0,0 +1,136 @@ + +class Mapper172 : public Mapper +{ +public: + Mapper172( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + BOOL ReadHigh( WORD addr, LPBYTE pdata ); + void Write( WORD addr, BYTE data ); + void Clock( INT cycles ); + void PPU_Latch( WORD addr ); + + //for FDC code by fanoble + void FdcHardReset(void); + void FdcSoftReset(void); + static void FdcNop(Mapper172* thiz); + static void FdcReadTrack(Mapper172* thiz); + static void FdcSpecify(Mapper172* thiz); + static void FdcSenseDriveStatus(Mapper172* thiz); + static void FdcWriteData(Mapper172* thiz); + static void FdcReadData(Mapper172* thiz); + static void FdcRecalibrate(Mapper172* thiz); + static void FdcSenseIntStatus(Mapper172* thiz); + static void FdcWriteDeletedData(Mapper172* thiz); + static void FdcReadID(Mapper172* thiz); + static void FdcReadDeletedData(Mapper172* thiz); + static void FdcFormatTrack(Mapper172* thiz); + static void FdcSeek(Mapper172* thiz); + static void FdcScanEqual(Mapper172* thiz); + static void FdcScanLowOrEqual(Mapper172* thiz); + static void FdcScanHighOrEqual(Mapper172* thiz); + typedef struct tagFDC_CMD_DESC + { + BYTE bWLength; + BYTE bRLength; + void (*pFun)(Mapper172*); + } FDC_CMD_DESC; + +protected: + BYTE reg[10]; + BYTE WE_SRAM, WE_DRAM, RE_DRAM; + BYTE irq_enable; + WORD irq_counter; + INT read_mode,read_mode1,write_mode,write_mode1; +private: + LPBYTE Load_DiskIMG(); + LPBYTE lpDisk, DISK; + + //for FDC code by fanoble +#define FDC_MS_BUSYS0 0x01 // FDD0 in SEEK mode +#define FDC_MS_BUSYS1 0x02 // FDD1 in SEEK mode +#define FDC_MS_BUSYS2 0x04 // FDD2 in SEEK mode +#define FDC_MS_BUSYS3 0x08 // FDD3 in SEEK mode +#define FDC_MS_BUSYRW 0x10 // Read or Write in progress +#define FDC_MS_EXECUTION 0x20 // Execution Mode +#define FDC_MS_DATA_IN 0x40 // Data input or output +#define FDC_MS_RQM 0x80 // Request for Master, Ready + +#define FDC_S0_US0 0x01 // Unit Select 0 +#define FDC_S0_US1 0x02 // Unit Select 1 +#define FDC_S0_HD 0x04 // Head Address +#define FDC_S0_NR 0x08 // Not Ready +#define FDC_S0_EC 0x10 // Equipment Check +#define FDC_S0_SE 0x20 // Seek End +#define FDC_S0_IC0 0x40 // Interrupt Code +#define FDC_S0_IC1 0x80 // NT/AT/IC/XX + +#define FDC_S1_MA 0x01 // Missing Address Mark +#define FDC_S1_NW 0x02 // Not Writable +#define FDC_S1_ND 0x04 // No Data +#define FDC_S1_OR 0x10 // Over Run +#define FDC_S1_DE 0x20 // Data Error +#define FDC_S1_EN 0x80 // End of Cylinder + +#define FDC_S2_MD 0x01 // Missing Address Mark in Data Field +#define FDC_S2_BC 0x02 // Bad Cylinder +#define FDC_S2_SN 0x04 // Scan Not Satisfied +#define FDC_S2_SH 0x08 // Scan Equal Hit +#define FDC_S2_WC 0x10 // Wrong Cylinder +#define FDC_S2_DD 0x20 // Data Error in Data Field +#define FDC_S2_CM 0x40 // Control Mark + +#define FDC_S3_US0 0x01 // Unit Select 0 +#define FDC_S3_US1 0x02 // Unit Select 1 +#define FDC_S3_HD 0x04 // Side Select +#define FDC_S3_TS 0x08 // Two Side +#define FDC_S3_T0 0x10 // Track 0 +#define FDC_S3_RY 0x20 // Ready +#define FDC_S3_WP 0x40 // Write Protect +#define FDC_S3_FT 0x80 // Fault + +#define FDC_CC_MASK 0x1F +#define FDC_CF_MT 0x80 +#define FDC_CF_MF 0x40 +#define FDC_CF_SK 0x20 +#define FDC_CC_READ_TRACK 0x02 +#define FDC_CC_SPECIFY 0x03 +#define FDC_CC_SENSE_DRIVE_STATUS 0x04 +#define FDC_CC_WRITE_DATA 0x05 +#define FDC_CC_READ_DATA 0x06 +#define FDC_CC_RECALIBRATE 0x07 +#define FDC_CC_SENSE_INTERRUPT_STATUS 0x08 +#define FDC_CC_WRITE_DELETED_DATA 0x09 +#define FDC_CC_READ_ID 0x0A +#define FDC_CC_READ_DELETED_DATA 0x0C +#define FDC_CC_FORMAT_TRACK 0x0D +#define FDC_CC_SEEK 0x0F +#define FDC_CC_SCAN_EQUAL 0x11 +#define FDC_CC_SCAN_LOW_OR_EQUAL 0x19 +#define FDC_CC_SCAN_HIGH_OR_EQUAL 0x1D +#define FDC_PH_IDLE 0 +#define FDC_PH_COMMAND 1 +#define FDC_PH_EXECUTION 2 +#define FDC_PH_RESULT 3 + + const FDC_CMD_DESC* pFdcCmd; + BOOL bFdcIrq; + BOOL bFdcHwReset; + BOOL bFdcSoftReset; + BOOL bFdcDmaInt; + UINT nFdcDrvSel; + UINT nFdcMotor; + BYTE nFdcMainStatus; + BYTE nFDCStatus[4]; + BYTE bFdcCycle; + BYTE bFdcCommands[10]; + BYTE bFdcResults[8]; + BYTE bFdcPhase; + BYTE nFdcCylinder; + BYTE nFdcHeadAddres; + BYTE nFdcRecord; + BYTE nFdcNumber; + LPBYTE pFdcDataPtr; +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper173.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper173.cpp new file mode 100644 index 00000000..623b121b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper173.cpp @@ -0,0 +1,216 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper173 Subor // +////////////////////////////////////////////////////////////////////////// + +void Mapper173::Reset() +{ +// nes->ppu->SetExtLatchMode( TRUE ); + for(INT i=0;i<11;i++) reg[i] = 0x00; + + irq_enable = irq_repeat = 0; + irq_counter = irq_latch = 0; + irq_occur = 0; + + SetPROM_32K_Bank(0); + nes->SetVideoMode( 2 ); + +} + +BYTE Mapper173::ExRead ( WORD addr ) +{ + DEBUGOUT( "ExRead - addr= %04x\n", addr ); + + return 0x00; + + switch (addr) { + case 0x4026: + // + break; + case 0x4033: + //D7: + //D6: + //D5: + //D4: + //D3: + //D2: + //D1: + //D0: + // + break; + case 0x4204: //FDC״̬Ĵ(STATUS) + // + break; + case 0x4205: //FDCݼĴ(DATA)(???) + // + break; + } + +} + +void Mapper173::ExWrite( WORD addr, BYTE data ) +{ + DEBUGOUT( "ExWrite - addr= %04x ; dat= %03x\n", addr, data ); + switch (addr) { + case 0x4020: + reg[0] = data; + break; + case 0x4022: + reg[1] = data; + break; + case 0x4023: + reg[2] = data; + break; + case 0x4026: + reg[3] = data; + break; + case 0x4031: + reg[4] = data; + break; + case 0x4032: + reg[5] = data; + + irq_repeat = data & 0x01; + irq_enable = data & 0x02; + irq_occur = 0; + if( irq_enable ) { + irq_counter = irq_latch; + } else { + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + break; + case 0x4034: + reg[6] = data; + + irq_latch = (irq_latch&0xFF00)|data; + break; + case 0x4035: + reg[7] = data; + + irq_latch = (irq_latch&0x00FF)|((WORD)data<<8); + break; + case 0x4040: + SetPROM_4K_Bank(0x8000, data&0x7F); + break; + case 0x4041: + SetPROM_4K_Bank(0x9000, data&0x7F); + break; + case 0x4042: + SetPROM_4K_Bank(0xa000, data&0x7F); + break; + case 0x4043: + SetPROM_4K_Bank(0xb000, data&0x7F); + break; + case 0x4044: + SetPROM_4K_Bank(0xc000, data&0x7F); + break; + case 0x4045: + SetPROM_4K_Bank(0xd000, data&0x7F); + break; + case 0x4046: + SetPROM_4K_Bank(0xe000, data&0x7F); + break; + case 0x4047: + SetPROM_4K_Bank(0xf000, data&0x7F); + break; + + case 0x4205: //FDCݼĴ(DATA)(д???) + // + break; + } + +} + +BYTE Mapper173::ReadLow( WORD addr ) +{ +// DEBUGOUT( "ReadLow - addr= %04x\n", addr ); + + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +void Mapper173::WriteLow(WORD addr, BYTE data) +{ +// DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +void Mapper173::Write(WORD addr, BYTE data) +{ +// DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); +} + +void Mapper173::HSync(int scanline) +{ +// if( (scanline >= 0 && scanline <= 239) ) { +// if( nes->ppu->IsDispON() ) { +// if( irq_enable ) { +// irq_enable = 0; +/// nes->cpu->SetIRQ( IRQ_MAPPER ); +// } +// } +// } +} + +void Mapper173::Clock( INT cycles ) +{ + + if( irq_enable ) { + irq_counter -= cycles; + if( irq_counter <= 0 ) { +//// irq_counter &= 0xFFFF; + irq_counter += irq_latch; + + if( !irq_occur ) { + irq_occur = 0xFF; + if( !irq_repeat ) { + irq_enable = 0; + } + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + +} + +void Mapper173::PPU_Latch( WORD addr ) +{ + // +} + +void Mapper173::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + INT loopy_v = nes->ppu->GetPPUADDR(); + INT loopy_y = nes->ppu->GetTILEY(); + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + INT ntbl_x = ntbladr&0x001F; + INT tileadr, ntb; + + ntb = (ntbladr>>10)&3; + + if(ntb==2) + tileofs |= 0x1000; +// else if(ntb && PPU_SW) + tileofs |= 0x1000; +// else + tileofs |= 0x0000; + + attradr &= 0x3FF; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; +} + +void Mapper173::SaveState( LPBYTE p ) +{ + // +} + +void Mapper173::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper173.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper173.h new file mode 100644 index 00000000..072672dd --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper173.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper173 // +////////////////////////////////////////////////////////////////////////// + +class Mapper173 : public Mapper +{ +public: + Mapper173( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ExRead ( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + BYTE ReadLow ( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + void Clock( INT cycles ); + void PPU_Latch( WORD addr ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[10]; + + INT irq_counter, irq_latch; + BYTE irq_enable, irq_repeat; + BYTE irq_occur; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper174.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper174.cpp new file mode 100644 index 00000000..ea771a07 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper174.cpp @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper174 Game Star - Smart Genius (Unl) // +////////////////////////////////////////////////////////////////////////// +void Mapper174::Reset() +{ + for( INT i = 0; i < 11; i++ ) { + reg[i] = 0x00; + } + prg0 = 60; + prg1 = 61; + SetPROM_32K_Bank( prg0, prg1, 62, 63 ); + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); +} + +void Mapper174::WriteLow( WORD addr, BYTE data ) +{ + + if(addr>=0x4000 && addr<=0x5FFF) + DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + + switch( addr ) { + case 0x5010: + reg[8] = data; + break; + case 0x5011: + reg[9] = data; + SetBank_CPU_L(); + break; + case 0x5012: + reg[10] = data; + SetBank_CPU_L(); + break; + } + + if(addr>=0x6000){ + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + + +void Mapper174::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + + if(addr==0xA000){ + data &= 0x03; + if(data==0) SetVRAM_Mirror( VRAM_VMIRROR ); + else if(data==1) SetVRAM_Mirror( VRAM_HMIRROR ); + else if(data==2) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + } + + if((reg[8]&0x07)<0x05){ + switch( addr ) { + case 0x8000: + reg[0] = data; + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x0f ) { + case 0x00: + chr01 = data; + SetBank_PPU(); + break; + case 0x01: + chr23 = data; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data + ((reg[9]&0x7F)*2) + (reg[10]*2); + SetBank_CPU(); + break; + case 0x07: + prg1 = data + ((reg[9]&0x7F)*2) + (reg[10]*2); + SetBank_CPU(); + break; + } + break; + } + } +/* + if((reg[8]&0x07)==0x04) + if(addr==0x8000) + if(data==0x00) + SetPROM_32K_Bank( 60, 61, 62, 63 ); +*/ + if((reg[8]&0x07)==0x05) + SetPROM_16K_Bank( 4, (reg[9] & 0x7F) + data + reg[10] ); + +} + +void Mapper174::SetBank_CPU_L() +{ + switch( reg[8] & 0x07 ) { + case 0x00: + SetPROM_16K_Bank( 6, (reg[9]&0x70) + 0 + reg[10] ); + SetPROM_16K_Bank( 6, (reg[9]&0x70) + 31 + reg[10] ); + break; + case 0x01: + SetPROM_16K_Bank( 6, (reg[9]&0x70) + 0 + reg[10] ); + SetPROM_16K_Bank( 6, (reg[9]&0x70) + 15 + reg[10] ); + break; + case 0x02: //MMC3 mode(???) + SetPROM_16K_Bank( 4, (reg[9]&0x7F) + 6 + reg[10] ); + SetPROM_16K_Bank( 6, (reg[9]&0x7F) + 7 + reg[10] ); + break; + case 0x03: //Mapper0 mode 16K + SetPROM_16K_Bank( 4, (reg[9]&0x7F) + reg[10] ); + SetPROM_16K_Bank( 6, (reg[9]&0x7F) + reg[10] ); + break; + case 0x04: //normal mode 32K + SetPROM_32K_Bank( ((reg[9]&0x7F)>>1) + (reg[10]>>1) ); + break; + case 0x05: //UNROM(mapper2) mode(???) + SetPROM_16K_Bank( 4, (reg[9] & 0x7F) + 0 + reg[10] ); + SetPROM_16K_Bank( 6, (reg[9] & 0x7F) + 7 + reg[10] ); + break; + } +} + +void Mapper174::SetBank_CPU() +{ + SetPROM_8K_Bank( 4, prg0 ); + SetPROM_8K_Bank( 5, prg1 ); +} + +void Mapper174::SetBank_PPU() +{ + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper174.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper174.h new file mode 100644 index 00000000..4bbb515a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper174.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper174 // +////////////////////////////////////////////////////////////////////////// +class Mapper174 : public Mapper +{ +public: + Mapper174( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); +protected: + INT reg[11]; + INT prg0, prg1; + INT chr01, chr23, chr4, chr5, chr6, chr7; +private: + void SetBank_CPU(); + void SetBank_CPU_L(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper175.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper175.cpp new file mode 100644 index 00000000..45806d53 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper175.cpp @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper175 15-in-1 (Kaiser) // +////////////////////////////////////////////////////////////////////////// +void Mapper175::Reset() +{ + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 0 ); + reg_dat = 0; + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +BYTE Mapper175::Read( WORD addr) +{ + if( addr == 0xFFFC ) { + SetPROM_16K_Bank( 4, reg_dat & 0x0F ); + SetPROM_8K_Bank( 6, (reg_dat & 0x0F)*2 ); + } + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +void Mapper175::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8000: + if( data & 0x04 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA000: + reg_dat = data; + SetPROM_8K_Bank( 7, (reg_dat & 0x0F)*2+1 ); + SetVROM_8K_Bank( reg_dat & 0x0F ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper175.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper175.h new file mode 100644 index 00000000..0c63c6e0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper175.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper175 15-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper175 : public Mapper +{ +public: + Mapper175( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + BYTE Read( WORD addr ); + +protected: + BYTE reg_dat; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper176.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper176.cpp new file mode 100644 index 00000000..d6052667 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper176.cpp @@ -0,0 +1,187 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper176 ShuQiYu / HengGe / WaiXing // +////////////////////////////////////////////////////////////////////////// +void Mapper176::Reset() +{ + if(PROM_16K_SIZE>32){ + SetPROM_32K_Bank( 0, 1, (PROM_8K_SIZE/2)-2, (PROM_8K_SIZE/2)-1 ); //For 1M byte Cartridge + }else{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +// SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + if(VROM_1K_SIZE) SetVROM_8K_Bank( 0 ); + + reg5000 = 0; + reg5001 = 0; + reg5010 = 0; + reg5011 = 0; + reg5013 = 0; + reg5FF1 = 0; + reg5FF2 = 0; + we_sram = 0; + SBW = 0; + sp_rom = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + + if(crc == 0x095D8678 //[ES-0122] Shuang Yue Zhuan (C) + || crc == 0xD5F7AAEF){ //[ES-XXXX] Shen Feng Jian (C) + sp_rom = 1; + nes->SetSAVERAM_SIZE( 32*1024 ); + } + +/* + crc == 0x416C07A1 //[ES-1006] Meng Huan Zhi Xing IV (C) & WXN-λ֮ + crc == 0x94782FBD //[ES-1057] San Guo Zhi - Xiong Ba Tian Xia (C) + crc == 0xF9863ADF //[ES-1066] Xi Chu Ba Wang (C) + crc == 0xB511C04B //[ES-1071] San Xia Wu Yi (C) + crc == 0x1923A8C5 //[ES-1087] Shui Hu Shen Shou (C) & WXN-ˮ(fix) + crc == 0x095D8678 //[ES-0122] Shuang Yue Zhuan (C) + crc == 0x8f6ab5ac //WXN-Ҵ + crc == 0x99051cb5 //WXN-۰ + crc == 0xf29c8186 //WXN-2-Ϻ + crc == 0xc768098b //WXN- + crc == 0x49f22159 //WXN- + crc == 0xf354d847 //WXN- + crc == 0x5ee2ef97 //WXN-۹ʱ(fix) + crc == 0x977d22c3 //WXN-Ƹ(fix) + crc == 0xf1d803f3 //WXN-(fix) + crc == 0x85dd49b6 //WXN-ڴ(fix) + crc == 0x97b82f53 //WXN-Ц(fix) + crc == 0xce2ea530 //WXN-(fix) +*/ +} + +BYTE Mapper176::ReadLow( WORD addr ) +{ + if(sp_rom==1){ + if( addr>=0x6000 ) { + switch( we_sram ) { + case 0xE4: + case 0xEC: return WRAM[(addr&0x1FFF)+0x0000]; + case 0xE5: + case 0xED: return WRAM[(addr&0x1FFF)+0x2000]; + case 0xE6: + case 0xEE: return WRAM[(addr&0x1FFF)+0x4000]; + case 0xE7: + case 0xEF: return WRAM[(addr&0x1FFF)+0x6000]; + default: return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } + } + } + return Mapper::ReadLow( addr ); +} + +void Mapper176::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + switch( addr ) { + case 0x5000: + reg5000 = data; + break; + case 0x5001: //[ES-1006] Meng Huan Zhi Xing IV (C) + reg5001 = data; + if(SBW) SetPROM_32K_Bank(reg5001); + break; + case 0x5010: + reg5010 = data; + if(reg5010==0x24) SBW=1; + break; + case 0x5011: + reg5011 = data>>1; + if(SBW) SetPROM_32K_Bank(reg5011); + break; + case 0x5013: + reg5013 = data; + break; + case 0x5ff1: + reg5FF1 = data>>1; + SetPROM_32K_Bank(reg5FF1); + break; + case 0x5ff2: + reg5FF2 = data; + SetVROM_8K_Bank(reg5FF2); + break; + } + + if(sp_rom==1){ + if( addr >= 0x6000 ) { + switch( we_sram ) { + case 0xE4: //CPU_MEM_BANK + case 0xEC: //CPU_MEM_BANK + WRAM[(addr&0x1FFF)+0x0000] = data; + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + case 0xE5: //SRAM + case 0xED: //SRAM + WRAM[(addr&0x1FFF)+0x2000] = data; + break; + case 0xE6: + case 0xEE: + WRAM[(addr&0x1FFF)+0x4000] = data; + break; + case 0xE7: + case 0xEF: + WRAM[(addr&0x1FFF)+0x6000] = data; + break; + default: + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + } + } + }else{ + if( addr >= 0x6000 ) { +// if ( we_sram == 0 ){ + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +// } + } + } + + +} + +void Mapper176::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + if(addr==0xa000){ + data &= 0x03; + if ( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if ( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if ( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + } + if(addr==0xa001){ +// we_sram = data & 0x03; + we_sram = data; + } +} + +void Mapper176::SaveState( LPBYTE p ) +{ + p[0] = reg5000; + p[1] = reg5001; + p[2] = reg5010; + p[3] = reg5011; + p[4] = reg5013; + p[5] = reg5FF1; + p[6] = reg5FF2; + p[7] = we_sram; + p[8] = SBW; + p[9] = sp_rom; +} + +void Mapper176::LoadState( LPBYTE p ) +{ + reg5000 = p[0]; + reg5001 = p[1]; + reg5010 = p[2]; + reg5011 = p[3]; + reg5013 = p[4]; + reg5FF1 = p[5]; + reg5FF2 = p[6]; + we_sram = p[7]; + SBW = p[8]; + sp_rom = p[9]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper176.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper176.h new file mode 100644 index 00000000..d52de8ca --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper176.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper176 // +////////////////////////////////////////////////////////////////////////// +class Mapper176 : public Mapper +{ +public: + Mapper176( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg5000; + BYTE reg5001; + BYTE reg5010; + BYTE reg5011; + BYTE reg5013; + BYTE reg5FF1; + BYTE reg5FF2; + BYTE we_sram; + BYTE SBW, sp_rom; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper177.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper177.cpp new file mode 100644 index 00000000..060e6d3e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper177.cpp @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper177 HengGe // +////////////////////////////////////////////////////////////////////////// +void Mapper177::Reset() +{ + SetPROM_32K_Bank( 0 ); + SP_rom = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + if(crc==0xB5E83C9A) SP_rom=1; //HengGe - Xing Ji Zheng Ba (C) +} + +void Mapper177::WriteLow( WORD addr, BYTE data ) +{ + if((addr==0x4800)&&(SP_rom)){ + if(data& 0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + if( addr>=0x6000 ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + +void Mapper177::Write( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( data ); + if(SP_rom==0){ + if(data&0x20) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper177.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper177.h new file mode 100644 index 00000000..9f25e975 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper177.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper177 HengGe // +////////////////////////////////////////////////////////////////////////// +class Mapper177 : public Mapper +{ +public: + Mapper177( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + void WriteLow(WORD addr, BYTE data); + +protected: + BYTE SP_rom; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper178.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper178.cpp new file mode 100644 index 00000000..e402ce52 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper178.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper178 Education / WaiXing_FS305 // +////////////////////////////////////////////////////////////////////////// +void Mapper178::Reset() +{ + reg[0]=0; + reg[1]=0; + reg[2]=0; + banknum=0; + SetBank_CPU(); + OP_rom = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x925926BC //[ES-XXXX] Kou Dai Zuan Shi Zhi Chong Wu Xiao Jing Ling 2 (C) + || crc == 0xB0B13DBD ) //[ES-XXXX] Chong Wu Fei Cui Zhi Chong Wu Xiao Jing Ling IV (C) + { + OP_rom = 1; + } +} + +void Mapper178::WriteLow( WORD addr, BYTE data ) +{ +// if( addr >= 0x4000 && addr <= 0x5FFF ) DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + if( addr==0x4800 ){ + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + }else if( addr==0x4801 ){ + reg[0]=(data>>1) & 0x0F; + if(OP_rom) reg[0]=data<<2; + SetBank_CPU(); + }else if( addr==0x4802 ){ + reg[1]=data<<2; + if(OP_rom) reg[1]=data; + SetBank_CPU(); + }else if( addr==0x4803 ){ + //unknown + reg[2]=data; + }else if( addr>=0x6000 ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + +void Mapper178::SetBank_CPU() +{ + banknum=reg[0] | reg[1]; +// DEBUGOUT("Bank=%02X\n", banknum&0xFF ); + SetPROM_32K_Bank( banknum ); +} \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper178.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper178.h new file mode 100644 index 00000000..a8efa9ad --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper178.h @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper178 Education / WaiXing / HengGe // +////////////////////////////////////////////////////////////////////////// +class Mapper178 : public Mapper +{ +public: + Mapper178( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: + BYTE reg[3]; + BYTE banknum; + BYTE OP_rom; +private: + void SetBank_CPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179.cpp new file mode 100644 index 00000000..cfe6d0a3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179.cpp @@ -0,0 +1,272 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper179 for test new dump // +////////////////////////////////////////////////////////////////////////// +void Mapper179::Reset() +{ + for(INT i=0;i<8;i++) reg[i]=0; + +//---------------[for WaiXing F001_XXXXX]------------------------------------[OK] +// SetPROM_32K_Bank( 0, 1, 0, 1 ); +//---------------------------------------------------------------------------[OK] +/* +//-----------[for Dragon Ball Z II - Gekishin Freeza!!_Plus (J)]------------- + for( i = 0; i < 8; i++ ) reg[i] = i; + reg[8] = 0; + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; +// nes->SetSAVERAM_SIZE( 256 ); +// x24c02.Reset( WRAM ); + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +//--------------------------------------------------------------------------- +*/ +// SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); +// SetVROM_8K_Bank( 0 ); + + SetPROM_32K_Bank( 0 ); + +} + +BYTE Mapper179::ReadLow( WORD addr ) +{ + DEBUGOUT( "ReadLow - addr= %04x ; dat= %03x\n", addr, Mapper::ReadLow( addr ) ); + +//-----------[for Dragon Ball Z II - Gekishin Freeza!!_Plus (J)]------------- +// if( (addr & 0x00FF) == 0x0000 ) { +// BYTE ret = 0; +// ret = x24c02.Read(); +// return (ret?0x10:0)|(nes->GetBarcodeStatus()); +// } +// return 0x00; +//--------------------------------------------------------------------------- + + if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return Mapper::ReadLow( addr ); +} + +void Mapper179::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF]=data; + +//-----------[for Dragon Ball Z II - Gekishin Freeza!!_Plus (J)]------------- +// if(addr==0x6000) x24c02.Write( (data&0x20)?0xFF:0, (data&0x40)?0xFF:0 ); +//--------------------------------------------------------------------------- + +} + +void Mapper179::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + + if(addr==0xF000) SetVROM_4K_Bank( 0 , data ); + if(addr==0xF0FF) SetVROM_4K_Bank( 4 , data ); + +//---------------[for WaiXing F001_XXXXX]------------------------------------[OK] +// if ((addr>=0x8081)&&(addr<=0x8101)) SetPROM_32K_Bank((addr-0x8081)/8); +// if ((addr>=0x8179)&&(addr<=0x81f9)) SetPROM_32K_Bank((addr-0x8179)/8+15); +//---------------------------------------------------------------------------[OK] +/* +//-----------[for Dragon Ball Z II - Gekishin Freeza!!_Plus (J)]------------- + switch( addr ) { +// case 0x8000: + case 0xA400: + SetPROM_16K_Bank( 4, data ); + break; +// case 0xA000: +// case 0xA400: +// SetPROM_8K_Bank( 5, data ); +// break; +// case 0x9000: + case 0x9400: + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; +// case 0xB001: + case 0xB004: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; +// case 0xB002: + case 0xB008: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; +// case 0xB003: + case 0xB00C: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; +// case 0xC001: + case 0xC004: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; +// case 0xC002: + case 0xC008: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; +// case 0xC003: + case 0xC00C: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; +// case 0xD001: + case 0xD004: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; +// case 0xD002: + case 0xD008: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; +// case 0xD003: + case 0xD00C: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; +// case 0xE001: + case 0xE004: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; +// case 0xE002: + case 0xE008: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; +// case 0xE003: + case 0xE00C: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F)<< 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; +// case 0xF000: + case 0xF408: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + irq_enable = data & 0x02; + irq_counter = irq_latch; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; +// case 0xF400: + // +// break; +// case 0xF800: + case 0xF400: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + irq_latch = (irq_latch & 0xFF00) | data; + irq_counter = (irq_counter & 0xFF00) | data; + break; +// case 0xFC00: + case 0xF404: + DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF); + irq_counter = ((INT)data << 8) | (irq_counter & 0x00FF); + break; + case 0xFFE0: +// x24c02.Write( (data&0x20)?0xFF:0, (data&0x40)?0xFF:0 ); + break; + default: + //DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + break; + } +//--------------------------------------------------------------------------- +*/ +/* DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + if((addr>=0x8000)&&(addr<=0x8fff)){ + switch( addr&0xF00 ) { + case 0x0000: + SetVROM_2K_Bank( 0, addr&0x1F ); + break; + case 0x0400: + SetVROM_2K_Bank( 2, addr&0x1F ); + break; + case 0x0800: + SetVROM_2K_Bank( 4, addr&0x1F ); + break; + case 0x0C00: + SetVROM_2K_Bank( 6, addr&0x1F ); + break; + } + } + if((addr>=0xa000)&&(addr<=0xafff)){ +// if(addr&0xf0==0xf0){ + switch( addr&0xF00 ) { + case 0x0000: +// SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); + SetPROM_8K_Bank( 4, (addr&0x0F) + 0x00 ); + break; + case 0x0400: +// SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); + SetPROM_8K_Bank( 5, (addr&0x0F) + 0x00 ); + break; + case 0x0800: +// SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); + SetPROM_8K_Bank( 6, (addr&0x0F) + 0x00 ); + break; + case 0x0C00: +// SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 ); + SetPROM_8K_Bank( 7, (addr&0x0F) + 0x10); + break; + } +// } + if(addr==0xa020) SetPROM_8K_Bank( 4, (addr&0x0F) + 0x00 ); + } +*/ +} + +void Mapper179::HSync(int scanline) +{ +/* +//-----------[for Dragon Ball Z II - Gekishin Freeza!!_Plus (J)]------------- + if( irq_enable ) { + if( irq_counter <= 114 ) { + nes->cpu->SetIRQ( IRQ_MAPPER ); + irq_counter &= 0xFFFF; + } else { + irq_counter -= 114; + } + } +//--------------------------------------------------------------------------- +*/ +} + +void Mapper179::Clock( INT cycles ) +{ + // +} + +void Mapper179::PPU_Latch( WORD addr ) +{ +// if(DirectInput.m_Sw[DIK_PAUSE]) nes->Dump_CPUHMEM(); +} + +void Mapper179::PPU_ExtLatchX( INT x ) +{ + // +} + +void Mapper179::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179.h new file mode 100644 index 00000000..693bfb86 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper179 // +////////////////////////////////////////////////////////////////////////// + +class Mapper179 : public Mapper +{ +public: + Mapper179( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow ( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + void Clock( INT cycles ); + void PPU_Latch( WORD addr ); + void PPU_ExtLatchX( INT x ); + void PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr ); + +protected: + BYTE reg[8]; + + BYTE irq_enable; + INT irq_counter; + INT irq_latch; + BYTE irq_request; + X24C02 x24c02; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179_bak.rar b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179_bak.rar new file mode 100644 index 00000000..61f8291c Binary files /dev/null and b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper179_bak.rar differ diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper180.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper180.cpp new file mode 100644 index 00000000..dcf14438 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper180.cpp @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper180 Nichibutsu // +////////////////////////////////////////////////////////////////////////// +void Mapper180::Reset() +{ + SetPROM_32K_Bank( 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper180::Write( WORD addr, BYTE data ) +{ + SetPROM_16K_Bank( 6, data&0x07 ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper180.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper180.h new file mode 100644 index 00000000..0c0eb841 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper180.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper180 Nichibutsu // +////////////////////////////////////////////////////////////////////////// +class Mapper180 : public Mapper +{ +public: + Mapper180( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper181.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper181.cpp new file mode 100644 index 00000000..84fd5c40 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper181.cpp @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper181 Hacker International Type2 // +////////////////////////////////////////////////////////////////////////// +void Mapper181::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper181::WriteLow( WORD addr, BYTE data ) +{ +//DEBUGOUT( "$%04X:$%02X\n", addr, data ); + if( addr == 0x4120 ) { + SetPROM_32K_Bank( (data & 0x08) >> 3 ); + SetVROM_8K_Bank( data & 0x07 ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper181.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper181.h new file mode 100644 index 00000000..63540368 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper181.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper181 Hacker International Type2 // +////////////////////////////////////////////////////////////////////////// +class Mapper181 : public Mapper +{ +public: + Mapper181( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper182.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper182.cpp new file mode 100644 index 00000000..185cf5b6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper182.cpp @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper182 PC-SuperDonkeyKong // +////////////////////////////////////////////////////////////////////////// +void Mapper182::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + reg = 0; + irq_enable = 0; + irq_counter = 0; +} + +void Mapper182::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF003 ) { + case 0x8001: + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0xA000: + reg = data & 0x07; + break; + case 0xC000: + switch( reg ) { + case 0: + SetVROM_1K_Bank( 0, (data&0xFE)+0 ); + SetVROM_1K_Bank( 1, (data&0xFE)+1 ); + break; + case 1: + SetVROM_1K_Bank( 5, data ); + break; + case 2: + SetVROM_1K_Bank( 2, (data&0xFE)+0 ); + SetVROM_1K_Bank( 3, (data&0xFE)+1 ); + break; + case 3: + SetVROM_1K_Bank( 7, data ); + break; + case 4: + SetPROM_8K_Bank( 4, data ); + break; + case 5: + SetPROM_8K_Bank( 5, data ); + break; + case 6: + SetVROM_1K_Bank( 4, data ); + break; + case 7: + SetVROM_1K_Bank( 6, data ); + break; + } + break; + case 0xE003: + irq_enable = data; + irq_counter = data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper182::HSync( INT scanline ) +{ + if( irq_enable ) { + if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) { + if( !(--irq_counter) ) { + irq_enable = 0; + irq_counter = 0; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } +} + +void Mapper182::SaveState( LPBYTE p ) +{ + p[0] = reg; + p[1] = irq_enable; + p[2] = irq_counter; +} + +void Mapper182::LoadState( LPBYTE p ) +{ + reg = p[0]; + irq_enable = p[1]; + irq_counter = p[2]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper182.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper182.h new file mode 100644 index 00000000..c9e866ef --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper182.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper182 PC-SuperDonkeyKong // +////////////////////////////////////////////////////////////////////////// +class Mapper182 : public Mapper +{ +public: + Mapper182( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg; + BYTE irq_enable; + BYTE irq_counter; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper183.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper183.cpp new file mode 100644 index 00000000..3930d889 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper183.cpp @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper183 Gimmick (Bootleg) // +////////////////////////////////////////////////////////////////////////// +void Mapper183::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + irq_enable = 0; + irq_counter = 0; +} + +void Mapper183::Write( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x8800: + SetPROM_8K_Bank( 4, data ); + break; + case 0xA800: + SetPROM_8K_Bank( 5, data ); + break; + case 0xA000: + SetPROM_8K_Bank( 6, data ); + break; + + case 0xB000: + reg[0] = (reg[0]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB004: + reg[0] = (reg[0]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB008: + reg[1] = (reg[1]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB00C: + reg[1] = (reg[1]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC004: + reg[2] = (reg[2]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC008: + reg[3] = (reg[3]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC00C: + reg[3] = (reg[3]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD004: + reg[4] = (reg[4]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD008: + reg[5] = (reg[5]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD00C: + reg[5] = (reg[5]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE004: + reg[6] = (reg[6]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE008: + reg[7] = (reg[3]&0xF0)|(data&0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE00C: + reg[7] = (reg[3]&0x0F)|((data&0x0F)<<4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0x9008: + if( data == 1 ) { + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + } + break; + + case 0x9800: + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else if( data == 3 ) SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + + case 0xF000: + irq_counter = (irq_counter&0xFF00)|data; + break; + case 0xF004: + irq_counter = (irq_counter&0x00FF)|(data<<8); + break; + case 0xF008: + irq_enable = data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper183::HSync( INT scanline ) +{ + if( irq_enable & 0x02 ) { + if( irq_counter <= 113 ) { + irq_counter = 0; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter -= 113; + } + } +} + +void Mapper183::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = irq_enable; + *((INT*)&p[ 9]) = irq_counter; +} + +void Mapper183::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[8]; + irq_counter = *((INT*)&p[ 9]); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper183.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper183.h new file mode 100644 index 00000000..2101879e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper183.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper183 Gimmick (Bootleg) // +////////////////////////////////////////////////////////////////////////// +class Mapper183 : public Mapper +{ +public: + Mapper183( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE irq_enable; + INT irq_counter; +private: +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper185.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper185.cpp new file mode 100644 index 00000000..351df8b2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper185.cpp @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper185 Character disable protect // +////////////////////////////////////////////////////////////////////////// +void Mapper185::Reset() +{ + switch( PROM_16K_SIZE ) { + case 1: // 16K only + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 0 ); + break; + case 2: // 32K + SetPROM_32K_Bank( 0 ); + break; + } + + for( INT i = 0; i < 0x400; i++ ) { + VRAM[0x800+i] = 0xFF; + } + + patch = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0xb36457c7 ) { // Spy vs Spy(J) + patch = 1; + } +} + +void Mapper185::Write( WORD addr, BYTE data ) +{ + if( (!patch && (data&0x03)) || (patch && data == 0x21) ) { + SetVROM_8K_Bank( 0 ); + } else { + SetVRAM_1K_Bank( 0, 2 ); // use vram bank 2 + SetVRAM_1K_Bank( 1, 2 ); + SetVRAM_1K_Bank( 2, 2 ); + SetVRAM_1K_Bank( 3, 2 ); + SetVRAM_1K_Bank( 4, 2 ); + SetVRAM_1K_Bank( 5, 2 ); + SetVRAM_1K_Bank( 6, 2 ); + SetVRAM_1K_Bank( 7, 2 ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper185.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper185.h new file mode 100644 index 00000000..576a8b71 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper185.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper185 Character disable protect // +////////////////////////////////////////////////////////////////////////// +class Mapper185 : public Mapper +{ +public: + Mapper185( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: + BYTE patch; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper187.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper187.cpp new file mode 100644 index 00000000..263ae36e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper187.cpp @@ -0,0 +1,308 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper187 Street Fighter Zero 2 97 // +////////////////////////////////////////////////////////////////////////// +void Mapper187::Reset() +{ +INT i; + + for( i = 0; i < 8; i++ ) { + chr[i] = 0x00; + bank[i] = 0x00; + } + + prg[0] = PROM_8K_SIZE-4; + prg[1] = PROM_8K_SIZE-3; + prg[2] = PROM_8K_SIZE-2; + prg[3] = PROM_8K_SIZE-1; + SetBank_CPU(); + + ext_mode = 0; + chr_mode = 0; + ext_enable = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + + last_write = 0; + + nes->SetRenderMethod( NES::POST_ALL_RENDER ); +} + +BYTE Mapper187::ReadLow( WORD addr ) +{ + switch( last_write&0x03 ) { + case 0: + return 0x83; + case 1: + return 0x83; + case 2: + return 0x42; + case 3: + return 0x00; + } + return 0; +} + +void Mapper187::WriteLow( WORD addr, BYTE data ) +{ + last_write = data; + if( (addr == 0x5000)||(addr == 0x6000) ) { + ext_mode = data; +/* if( data & 0x80 ) { + if( data & 0x20 ) { + prg[0] = ((data&0x1E)<<1)+0; + prg[1] = ((data&0x1E)<<1)+1; + prg[2] = ((data&0x1E)<<1)+2; + prg[3] = ((data&0x1E)<<1)+3; + } else { + prg[2] = ((data&0x1F)<<1)+0; + prg[3] = ((data&0x1F)<<1)+1; + } + } else { + prg[0] = bank[6]; + prg[1] = bank[7]; + prg[2] = PROM_8K_SIZE-2; + prg[3] = PROM_8K_SIZE-1; + } + SetBank_CPU(); +*/ + if(data & 0x80) { + uint8 bank = data & 0x1F; + if (data & 0x20) { + if (data & 0x40) + SetPROM_32K_Bank(bank>>2); + else + SetPROM_32K_Bank(bank>>1); + } else { + SetPROM_16K_Bank(4, bank); + SetPROM_16K_Bank(6, bank); + } + } else SetPROM_32K_Bank(bank[6],bank[7],PROM_8K_SIZE-2,PROM_8K_SIZE-1); + + } +} + +void Mapper187::Write( WORD addr, BYTE data ) +{ + last_write = data; + switch( addr ) { + case 0x8003: + ext_enable = 0xFF; +// if( (data&0x80) != (chr_mode&0x80) ) { +// for( INT i = 0; i < 4; i++ ) { +// INT temp = chr[i]; +// chr[i] = chr[i+4]; +// chr[i+4] = temp; +// } +// SetBank_PPU(); +// } + chr_mode = data; + if( (data&0xF0) == 0 ) { + prg[2] = PROM_8K_SIZE-2; + SetBank_CPU(); + } + break; + + case 0x8000: + ext_enable = 0; +// if( (data&0x80) != (chr_mode&0x80) ) { +// for( INT i = 0; i < 4; i++ ) { +// INT temp = chr[i]; +// chr[i] = chr[i+4]; +// chr[i+4] = temp; +// } +// SetBank_PPU(); +// } + chr_mode = data; + break; + + case 0x8001: + if( !ext_enable ) { + switch( chr_mode & 7 ) { + case 0: + data &= 0xFE; + chr[4] = (INT)data+0x100; + chr[5] = (INT)data+0x100+1; +// chr[0+((chr_mode&0x80)?4:0)] = data; +// chr[1+((chr_mode&0x80)?4:0)] = data+1; + SetBank_PPU(); + break; + case 1: + data &= 0xFE; + chr[6] = (INT)data+0x100; + chr[7] = (INT)data+0x100+1; +// chr[2+((chr_mode&0x80)?4:0)] = data; +// chr[3+((chr_mode&0x80)?4:0)] = data+1; + SetBank_PPU(); + break; + case 2: + chr[0] = data; +// chr[0+((chr_mode&0x80)?0:4)] = data; + SetBank_PPU(); + break; + case 3: + chr[1] = data; +// chr[1+((chr_mode&0x80)?0:4)] = data; + SetBank_PPU(); + break; + case 4: + chr[2] = data; +// chr[2+((chr_mode&0x80)?0:4)] = data; + SetBank_PPU(); + break; + case 5: + chr[3] = data; +// chr[3+((chr_mode&0x80)?0:4)] = data; + SetBank_PPU(); + break; + case 6: + if( (ext_mode&0xA0)!=0xA0 ) { + prg[0] = data; + SetBank_CPU(); + } + break; + case 7: + if( (ext_mode&0xA0)!=0xA0 ) { + prg[1] = data; + SetBank_CPU(); + } + break; + default: + break; + } + } else { + switch( chr_mode ) { + case 0x2A: + prg[1] = 0x0F; + break; + case 0x28: + prg[2] = 0x17; + break; + case 0x26: + break; + default: + break; + } + SetBank_CPU(); + } + bank[chr_mode&7] = data; + break; + + case 0xA000: + if( data & 0x01 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + break; + + case 0xC000: + irq_counter = data; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC001: + irq_latch = data; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE000: + case 0xE002: + irq_enable = 0; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + case 0xE003: + irq_enable = 1; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper187::Clock( INT cycles ) +{ +// if( irq_occur ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper187::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !irq_counter ) { + irq_counter--; + irq_enable = 0; + irq_occur = 0xFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter--; + } + } + } + } +} + +void Mapper187::SetBank_CPU() +{ + SetPROM_32K_Bank( prg[0], prg[1], prg[2], prg[3] ); +} + +void Mapper187::SetBank_PPU() +{ + SetVROM_8K_Bank( chr[0], chr[1], chr[2], chr[3], + chr[4], chr[5], chr[6], chr[7] ); +} + +void Mapper187::SaveState( LPBYTE p ) +{ +INT i; + + for( i = 0; i < 4; i++ ) { + p[i] = prg[i]; + } + for( i = 0; i < 8; i++ ) { + p[4+i] = bank[i]; + } + for( i = 0; i < 8; i++ ) { + *((INT*)&p[12+i*sizeof(INT)]) = chr[i]; + } + + p[44] = ext_mode; + p[45] = chr_mode; + p[46] = ext_enable; + p[47] = irq_enable; + p[48] = irq_counter; + p[49] = irq_latch; + p[50] = irq_occur; + p[51] = last_write; +} + +void Mapper187::LoadState( LPBYTE p ) +{ +INT i; + + for( i = 0; i < 4; i++ ) { + prg[i] = p[i]; + } + for( i = 0; i < 8; i++ ) { + bank[i] = p[4+i]; + } + for( i = 0; i < 8; i++ ) { + chr[i] = *((INT*)&p[12+i*sizeof(INT)]); + } + ext_mode = p[44]; + chr_mode = p[45]; + ext_enable = p[46]; + irq_enable = p[47]; + irq_counter = p[48]; + irq_latch = p[49]; + irq_occur = p[50]; + last_write = p[51]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper187.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper187.h new file mode 100644 index 00000000..e6fb724e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper187.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper187 Street Fighter Zero 2 97 // +////////////////////////////////////////////////////////////////////////// +class Mapper187 : public Mapper +{ +public: + Mapper187( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + + void Clock(INT cycles); + void HSync(INT scanline); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE prg[4]; + INT chr[8]; + BYTE bank[8]; + + BYTE ext_mode; + BYTE chr_mode; + BYTE ext_enable; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_occur; + BYTE last_write; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper188.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper188.cpp new file mode 100644 index 00000000..b2e19ac5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper188.cpp @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper188 Bandai Karaoke Studio // +////////////////////////////////////////////////////////////////////////// +void Mapper188::Reset() +{ + if( PROM_8K_SIZE > 16 ) { + SetPROM_32K_Bank( 0, 1, 14, 15 ); + } else { + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper188::Write( WORD addr, BYTE data ) +{ + if( data ) { + if( data & 0x10 ) { + data &= 0x07; + SetPROM_16K_Bank( 4, data ); + } else { + SetPROM_16K_Bank( 4, data+8 ); + } + } else { + if( PROM_8K_SIZE == 0x10 ) { + SetPROM_16K_Bank( 4, 7 ); + } else { + SetPROM_16K_Bank( 4, 8 ); + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper188.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper188.h new file mode 100644 index 00000000..55db4209 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper188.h @@ -0,0 +1,13 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper188 Bandai Karaoke Studio // +////////////////////////////////////////////////////////////////////////// +class Mapper188 : public Mapper +{ +public: + Mapper188( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper189.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper189.cpp new file mode 100644 index 00000000..e4fccc68 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper189.cpp @@ -0,0 +1,256 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper189 Street Fighter 2 Yoko/Master Fighter 2 // +// Ř Street Fighter IV (GOUDER) // +////////////////////////////////////////////////////////////////////////// +void Mapper189::Reset() +{ + SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + reg[0] = reg[1] = 0; + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + + for( INT i = 0; i < 4; i++ ) { + protect_dat[i] = 0; + } + lwd = 0xFF; + + patch = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x20ca2ad3 ) { // Street Fighter IV (GOUDER) + patch = 1; + SetPROM_32K_Bank( 0 ); + + // $4000-$5FFF + SetPROM_Bank( 2, XRAM, BANKTYPE_ROM ); + } + + SP_rom = 0; + if( crc == 0xA41012AF ) { // Street Fighter III (dump by temryu) + SP_rom = 1; + } +} + +void Mapper189::WriteLow( WORD addr, BYTE data ) +{ + DEBUGOUT( "189MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + if( (addr & 0xFF00) == 0x4100 ) { + // Street Fighter 2 YOKO + SetPROM_32K_Bank( (data&0x30)>>4 ); + } else if( (addr & 0xFF00) == 0x6100 ) { + // Master Fighter 2 + SetPROM_32K_Bank( data&0x03 ); + if(SP_rom) SetPROM_32K_Bank( (data&0x30)>>4 ); + } + + if( patch ) { + // Street Fighter IV (GOUDER) + BYTE a5000xordat[256] = { + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01, + 0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00, + 0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if( (addr >= 0x4800) && (addr <= 0x4FFF) ) { + SetPROM_32K_Bank( ((data&0x10)>>3)+(data&0x1) ); + + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x20 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + } + if( (addr>=0x5000) && (addr<=0x57FF) ) { + lwd = data; + } + if( (addr>=0x5800) && (addr<=0x5FFF) ) { +// XRAM[0x1000+(addr & 3)] = + // $5800 "JMP $xxxx" write + XRAM[0x1800+(addr & 3)] = + protect_dat[ addr & 3 ] = data ^ a5000xordat[ lwd ]; + } + } +} + +void Mapper189::Write( WORD addr, BYTE data ) +{ + DEBUGOUT( "189MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + switch( addr&0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_PPU(); + break; + + case 0x8001: + reg[1] = data; + SetBank_PPU(); + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + } + break; + + case 0xA000: + if( data&0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0xC000: + irq_counter = data; + break; + case 0xC001: + irq_latch = data; + break; + case 0xE000: + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + irq_enable = 0xFF; + break; + } +} + +void Mapper189::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(--irq_counter) ) { +// if( !(irq_counter--) ) { + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper189::SetBank_PPU() +{ + if( patch ) { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } else { + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } + } +} + +void Mapper189::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = chr01; + p[3] = chr23; + p[4] = chr4; + p[5] = chr5; + p[6] = chr6; + p[7] = chr7; + p[ 8] = irq_enable; + p[ 9] = irq_counter; + p[10] = irq_latch; + + p[16] = protect_dat[0]; + p[17] = protect_dat[1]; + p[18] = protect_dat[2]; + p[19] = protect_dat[3]; + p[20] = lwd; +} + +void Mapper189::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + chr01 = p[2]; + chr23 = p[3]; + chr4 = p[4]; + chr5 = p[5]; + chr6 = p[6]; + chr7 = p[7]; + + irq_enable = p[ 8]; + irq_counter = p[ 9]; + irq_latch = p[10]; + + protect_dat[0] = p[16]; + protect_dat[1] = p[17]; + protect_dat[2] = p[18]; + protect_dat[3] = p[19]; + lwd = p[20]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper189.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper189.h new file mode 100644 index 00000000..7703c2fc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper189.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper189 Street Fighter 2/Yoko version // +// Ř Street Fighter IV (GOUDER) // +////////////////////////////////////////////////////////////////////////// +class Mapper189 : public Mapper +{ +public: + Mapper189( NES* parent ) : Mapper(parent) {} + + void Reset(); + + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void HSync( INT scanline ); + + void SetBank_CPU(); + void SetBank_PPU(); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE patch; + BYTE SP_rom; + + BYTE reg[2]; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + + // SF4 + BYTE protect_dat[4]; + BYTE lwd; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper190.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper190.cpp new file mode 100644 index 00000000..3400d5f9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper190.cpp @@ -0,0 +1,242 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper190 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper190::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + +// DWORD crc = nes->rom->GetPROM_CRC(); +// if( crc == 0x6F3D187A ) { +// Temp_Buf=0; //Kof96 +// } else { +// Temp_Buf=1; //ST97 +// } + + irq_enable = 0; + irq_counter = 0; + cbase = 0; /* PowerOn OR RESET : cbase=0 */ + mp190_lcchk = 0; /* PowerOn OR RESET */ + mp190_lcmd = 1; +} + +void Mapper190::WriteLow( WORD addr, BYTE data ) +{ + /* For Initial Copy Protect check (KOF'96) */ + if( addr == 0x5000 ) { + mp190_lcmd = data; + switch( data ) { + case 0xE0: + SetPROM_32K_Bank( 0 ); + break; + case 0xEE: + SetPROM_32K_Bank( 3 ); + break; + } + } + if( (addr==0x5001) && (mp190_lcmd==0x00) ) { + SetPROM_32K_Bank( 7 ); + } + if( addr == 0x5080 ) { + switch( data ) { + case 0x1:lowoutdata=0x83;break; + case 0x2:lowoutdata=0x42;break; + case 0x3:lowoutdata=0x00;break; + } + } + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; +} + +BYTE Mapper190::ReadLow( WORD addr ) +{ + switch( addr ) { + case 0x5000: + return lowoutdata; + default: + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } +} + +void Mapper190::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE003 ) { + case 0x8000: + mp190_cmd = data; + if( mp190_cmd & 0x80 ) + cbase = 1; + else + cbase = 0; + break; + case 0x8003: /* for Street Fighter Zero 2 '97 */ + mp190_lcchk = data; + switch( data ) { + case 0x28: + SetPROM_8K_Bank( 4, 0x1F ); + SetPROM_8K_Bank( 5, 0x1F ); + SetPROM_8K_Bank( 6, 0x17 ); + SetPROM_8K_Bank( 7, 0x1F ); + break; + case 0x2A: + SetPROM_8K_Bank( 4, 0x1F ); + SetPROM_8K_Bank( 5, 0x0F ); + SetPROM_8K_Bank( 6, 0x17 ); + SetPROM_8K_Bank( 7, 0x1F ); + break; + case 0x06: + SetPROM_8K_Bank( 4, 0x1E ); + SetPROM_8K_Bank( 5, 0x1F ); + SetPROM_8K_Bank( 6, 0x1F ); + SetPROM_8K_Bank( 7, 0x1F ); + break; + } + break; + case 0x8001: + if( (mp190_lcchk==0x6) || (mp190_lcmd==0x0) ) { + switch( mp190_cmd & 0x07 ) { + case 0: + if( cbase == 0 ) { + SetVROM_1K_Bank(0,data+0x100); + SetVROM_1K_Bank(1,data+0x101); + } else { + SetVROM_1K_Bank(4,data+0x100); + SetVROM_1K_Bank(5,data+0x101); + } + break; + case 1: + if( cbase == 0 ) { + SetVROM_1K_Bank(2,data+0x100); + SetVROM_1K_Bank(3,data+0x101); + } else { + SetVROM_1K_Bank(6,data+0x100); + SetVROM_1K_Bank(7,data+0x101); + } + break; + case 2: + if( cbase == 0 ) { + SetVROM_1K_Bank(4,data); + } else { + SetVROM_1K_Bank(0,data); + } + break; + case 3: + if( cbase == 0 ) { + SetVROM_1K_Bank(5,data); + } else { + SetVROM_1K_Bank(1,data); + } + break; + case 4: + if( cbase == 0 ) { + SetVROM_1K_Bank(6,data); + } else { + SetVROM_1K_Bank(2,data); + } + break; + case 5: + if( cbase == 0 ) { + SetVROM_1K_Bank(7,data); + } else { + SetVROM_1K_Bank(3,data); + } + break; + case 6: + data=data&((PROM_8K_SIZE*2)-1); + if( mp190_lcmd & 0x40 ) { + SetPROM_8K_Bank(6,data); + SetPROM_8K_Bank(4,(PROM_8K_SIZE-1)*2); + } else { + SetPROM_8K_Bank(4,data); + SetPROM_8K_Bank(6,(PROM_8K_SIZE-1)*2); + } + break; + case 7: + data=data&((PROM_8K_SIZE*2)-1); + if( mp190_lcmd & 0x40 ) { + SetPROM_8K_Bank(5,data); + SetPROM_8K_Bank(4,(PROM_8K_SIZE-1)*2); + } else { + SetPROM_8K_Bank(5,data); + SetPROM_8K_Bank(6,(PROM_8K_SIZE-1)*2); + } + break; + } + } + break; + case 0xA000: + if( (data&0x1) == 0x1 ) + SetVRAM_Mirror( VRAM_HMIRROR ); + else + SetVRAM_Mirror( VRAM_VMIRROR ); + break; + case 0xA001: + break; + case 0xC000: + irq_counter = data-1; + break; + case 0xC001: + irq_latch = data-1; + break; + case 0xC002: + irq_counter = data; + break; + case 0xC003: + irq_latch = data; + break; + case 0xE000: + irq_counter = irq_latch; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + irq_enable = 1; + break; + case 0xE002: + irq_counter = irq_latch; + irq_enable = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE003: + irq_enable = 1; + irq_counter = irq_counter; + break; + } +} + +void Mapper190::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper190::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_counter; + p[2] = irq_latch; + + p[3] = cbase; + p[4] = mp190_lcchk; + p[5] = mp190_lcmd; + p[6] = mp190_cmd; + p[7] = lowoutdata; +} + +void Mapper190::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_counter = p[1]; + irq_latch = p[2]; + + cbase = p[3]; + mp190_lcchk = p[4]; + mp190_lcmd = p[5]; + mp190_cmd = p[6]; + lowoutdata = p[7]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper190.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper190.h new file mode 100644 index 00000000..ac4e424e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper190.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper190 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper190 : public Mapper +{ +public: + Mapper190( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE cbase; /* PowerOn OR RESET : cbase=0 */ + BYTE mp190_lcchk; /* PowerOn OR RESET */ + BYTE mp190_lcmd; + BYTE mp190_cmd; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE lowoutdata; + +private: + +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper191.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper191.cpp new file mode 100644 index 00000000..1125f4ad --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper191.cpp @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper191 SACHEN Super Cartridge Xin1 (Ver.1-9) // +// SACHEN Q-BOY Support // +////////////////////////////////////////////////////////////////////////// + +void Mapper191::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; +// prg1 = 1; + SetBank_CPU(); + + chr0 = 0; + chr1 = 0; + chr2 = 0; + chr3 = 0; + highbank = 0; + SetBank_PPU(); +} + +void Mapper191::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x4100: + reg[0]=data; + break; + case 0x4101: + reg[1]=data; + switch( reg[0] ) { + case 0: + chr0=data&7; + SetBank_PPU(); + break; + case 1: + chr1=data&7; + SetBank_PPU(); + break; + case 2: + chr2=data&7; + SetBank_PPU(); + break; + case 3: + chr3=data&7; + SetBank_PPU(); + break; + case 4: + highbank=data&7; + SetBank_PPU(); + break; + case 5: + prg0=data&7; + SetBank_CPU(); + break; + case 7: + if( data & 0x02 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + } + break; + } +} + +void Mapper191::SetBank_CPU() +{ + SetPROM_32K_Bank( prg0 ); +} + +void Mapper191::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + SetVROM_1K_Bank( 0, (((highbank<<3)+chr0)<<2)+0 ); + SetVROM_1K_Bank( 1, (((highbank<<3)+chr0)<<2)+1 ); + SetVROM_1K_Bank( 2, (((highbank<<3)+chr1)<<2)+2 ); + SetVROM_1K_Bank( 3, (((highbank<<3)+chr1)<<2)+3 ); + SetVROM_1K_Bank( 4, (((highbank<<3)+chr2)<<2)+0 ); + SetVROM_1K_Bank( 5, (((highbank<<3)+chr2)<<2)+1 ); + SetVROM_1K_Bank( 6, (((highbank<<3)+chr3)<<2)+2 ); + SetVROM_1K_Bank( 7, (((highbank<<3)+chr3)<<2)+3 ); + } +} + +void Mapper191::SaveState( LPBYTE p ) +{ + p[0] = prg0; + p[1] = chr0; + p[2] = chr1; + p[3] = chr2; + p[4] = chr3; + p[5] = highbank; +} + +void Mapper191::LoadState( LPBYTE p ) +{ + prg0 = p[0]; + chr0 = p[1]; + chr1 = p[2]; + chr2 = p[3]; + chr3 = p[4]; + highbank = p[5]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper191.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper191.h new file mode 100644 index 00000000..db502966 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper191.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper191 SACHEN Super Cartridge Xin1 (Ver.1-9) // +// SACHEN Q-BOY Support // +////////////////////////////////////////////////////////////////////////// +class Mapper191 : public Mapper +{ +public: + Mapper191( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr0, chr1, chr2, chr3; + BYTE highbank; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper192.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper192.cpp new file mode 100644 index 00000000..e8b487a8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper192.cpp @@ -0,0 +1,255 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper192 WaiXingTypeC Base ON Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// + +void Mapper192::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_request = 0; +} + + +BYTE Mapper192::ReadLow( WORD addr ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + return XRAM[addr-0x4000]; + }else{ + return Mapper::ReadLow( addr ); + } +} + +void Mapper192::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + XRAM[addr-0x4000] = data; + } else { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper192::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data ; + SetBank_PPU(); + break; + case 0x01: + chr23 = data ; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + +} + +void Mapper192::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter--; + } + } + if( !(irq_counter--) ) { + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper192::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper192::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { +// SetVROM_8K_Bank( chr4, chr5, chr6, chr7, +// chr01, chr01+1, chr23, chr23+1 ); + SetBank_PPUSUB( 4, chr01+0 ); + SetBank_PPUSUB( 5, chr01+1 ); + SetBank_PPUSUB( 6, chr23+0 ); + SetBank_PPUSUB( 7, chr23+1 ); + SetBank_PPUSUB( 0, chr4 ); + SetBank_PPUSUB( 1, chr5 ); + SetBank_PPUSUB( 2, chr6 ); + SetBank_PPUSUB( 3, chr7 ); + } else { +// SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, +// chr4, chr5, chr6, chr7 ); + SetBank_PPUSUB( 0, chr01+0 ); + SetBank_PPUSUB( 1, chr01+1 ); + SetBank_PPUSUB( 2, chr23+0 ); + SetBank_PPUSUB( 3, chr23+1 ); + SetBank_PPUSUB( 4, chr4 ); + SetBank_PPUSUB( 5, chr5 ); + SetBank_PPUSUB( 6, chr6 ); + SetBank_PPUSUB( 7, chr7 ); + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0) ); + SetCRAM_1K_Bank( 5, (chr01+1) ); + SetCRAM_1K_Bank( 6, (chr23+0) ); + SetCRAM_1K_Bank( 7, (chr23+1) ); + SetCRAM_1K_Bank( 0, chr4 ); + SetCRAM_1K_Bank( 1, chr5 ); + SetCRAM_1K_Bank( 2, chr6 ); + SetCRAM_1K_Bank( 3, chr7 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0) ); + SetCRAM_1K_Bank( 1, (chr01+1) ); + SetCRAM_1K_Bank( 2, (chr23+0) ); + SetCRAM_1K_Bank( 3, (chr23+1) ); + SetCRAM_1K_Bank( 4, chr4 ); + SetCRAM_1K_Bank( 5, chr5 ); + SetCRAM_1K_Bank( 6, chr6 ); + SetCRAM_1K_Bank( 7, chr7 ); + } + } +} + +void Mapper192::SetBank_PPUSUB( int bank, int page ) +{ + if( (page & 0xFC) == 0x08 ) { + SetCRAM_1K_Bank( bank, page ); + } else { + SetVROM_1K_Bank( bank, page ); + } +} + +void Mapper192::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = irq_request; +} + +void Mapper192::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + irq_request = p[19]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper192.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper192.h new file mode 100644 index 00000000..2553a20b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper192.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper192 WaiXingTypeC Base ON Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// + +class Mapper192 : public Mapper +{ +public: + Mapper192( NES* parent ) : Mapper(parent) {} + + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_PPUSUB( int bank, int page ); +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper193.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper193.cpp new file mode 100644 index 00000000..96d3ba9e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper193.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper193 MEGA SOFT (NTDEC) : Fighting Hero // +////////////////////////////////////////////////////////////////////////// + +void Mapper193::Reset() +{ + SetPROM_32K_Bank( PROM_32K_SIZE-1 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper193::WriteLow( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x6000: + SetVROM_2K_Bank( 0, ((data>>1)&0x7e)+0 ); + SetVROM_2K_Bank( 2, ((data>>1)&0x7e)+1 ); + break; + case 0x6001: + SetVROM_2K_Bank( 4, data>>1 ); + break; + case 0x6002: + SetVROM_2K_Bank( 6, data>>1 ); + break; + case 0x6003: + SetPROM_32K_Bank( data ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper193.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper193.h new file mode 100644 index 00000000..e3820bed --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper193.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper193 MEGA SOFT (NTDEC) : Fighting Hero // +////////////////////////////////////////////////////////////////////////// +class Mapper193 : public Mapper +{ +public: + Mapper193( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper194.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper194.cpp new file mode 100644 index 00000000..d6658569 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper194.cpp @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper194 WaiXingTypeD Base ON Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper194::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + chr[i] = i; + } + prg[0] = 0x00; + prg[1] = 0x01; + prg[2] = 0x3e; + prg[3] = 0x3f; + SetBank_CPU(); + SetBank_PPU(); + + irq_enable=irq_counter=irq_latch=irq_request = 0; +} + + +BYTE Mapper194::ReadLow( WORD addr ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + return XRAM[addr-0x4000]; + }else{ + return Mapper::ReadLow( addr ); + } +} + +void Mapper194::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + XRAM[addr-0x4000] = data; + } else { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper194::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x0f ) { + case 0x00: chr[0] = (data & 0xFE) | 0,chr[1] = (data & 0xFE) | 1 ; + case 0x01: chr[2] = (data & 0xFE) | 0,chr[3] = (data & 0xFE) | 1 ; + case 0x02: + case 0x03: + case 0x04: + case 0x05: chr[(reg[0] & 0x07)+2] = data; SetBank_PPU(); break; + case 0x06: + case 0x07: + case 0x08: + case 0x09: prg[(reg[0] & 0x0f)-6] = data; SetBank_CPU(); break; + } + break; + case 0xA000: + reg[2] = data; + //if( !nes->rom->Is4SCREEN() ) + { + if(data==0) SetVRAM_Mirror(VRAM_VMIRROR); + else if(data==1) SetVRAM_Mirror(VRAM_HMIRROR); + else if(data==2) SetVRAM_Mirror(VRAM_MIRROR4L); + else SetVRAM_Mirror(VRAM_MIRROR4H); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + +} + +void Mapper194::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) + { + if( nes->ppu->IsDispON() ) + { + if( irq_enable && !irq_request ) + { + if( scanline == 0 ) + { + if( irq_counter ) + { + irq_counter--; + } + } + if( !(irq_counter--) ) + { + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper194::SetBank_CPU() +{ + SetPROM_8K_Bank(4,prg[0 ^(reg[0]>>5&~(0<<1)&2)]); + SetPROM_8K_Bank(5,prg[1 ^(reg[0]>>5&~(1<<1)&2)]); + SetPROM_8K_Bank(6,prg[2 ^(reg[0]>>5&~(2<<1)&2)]); + SetPROM_8K_Bank(7,prg[3 ^(reg[0]>>5&~(3<<1)&2)]); +} + +void Mapper194::SetBank_PPU() +{ + unsigned int bank = (reg[0]&0x80)>>5; + for(int x=0; x<8; x++) + { + if( chr[x]<=1 ) + { + SetCRAM_1K_Bank( x^bank, chr[x] ); + }else{ + SetVROM_1K_Bank( x^bank, chr[x] ); + } + } +} + +void Mapper194::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + p[10+i] = chr[i]; + } + + p[ 8] = prg[0]; + p[ 9] = prg[1]; + p[18] = irq_enable; + p[19] = irq_counter; + p[20] = irq_latch; + p[21] = irq_request; + p[22] = prg[2]; + p[23] = prg[3]; +} + +void Mapper194::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + chr[i] = p[10+i]; + } + prg[0] = p[ 8]; + prg[1] = p[ 9]; + irq_enable = p[18]; + irq_counter = p[19]; + irq_latch = p[20]; + irq_request = p[21]; + prg[2] = p[ 22]; + prg[3] = p[ 23]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper194.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper194.h new file mode 100644 index 00000000..4bbbf4b3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper194.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper194 WaiXingTypeD Base ON Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper194 : public Mapper +{ +public: + Mapper194( NES* parent ) : Mapper(parent) {} + + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg[4]; + BYTE chr[8]; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper195.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper195.cpp new file mode 100644 index 00000000..ac2a7dcb --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper195.cpp @@ -0,0 +1,260 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper195 // +////////////////////////////////////////////////////////////////////////// +//Mapper119 TQ-ROM + +void Mapper195::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_request = 0; +} + + +BYTE Mapper195::ReadLow( WORD addr ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + return XRAM[addr-0x4000]; + }else{ + return Mapper::ReadLow( addr ); + } +} + +void Mapper195::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x5000 && addr <= 0x5FFF ) { + XRAM[addr-0x4000] = data; + } else { + Mapper::WriteLow( addr, data ); + } +} + +void Mapper195::Write( WORD addr, BYTE data ) +{ +//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data ; + SetBank_PPU(); + break; + case 0x01: + chr23 = data ; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) + { + if(data==0) SetVRAM_Mirror(VRAM_VMIRROR); + else if(data==1) SetVRAM_Mirror(VRAM_HMIRROR); + else if(data==2) SetVRAM_Mirror(VRAM_MIRROR4L); + else SetVRAM_Mirror(VRAM_MIRROR4H); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + +} + +void Mapper195::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter--; + } + } + if( !(irq_counter--) ) { + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper195::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper195::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { +// SetVROM_8K_Bank( chr4, chr5, chr6, chr7, +// chr01, chr01+1, chr23, chr23+1 ); + SetBank_PPUSUB( 4, chr01+0 ); + SetBank_PPUSUB( 5, chr01+1 ); + SetBank_PPUSUB( 6, chr23+0 ); + SetBank_PPUSUB( 7, chr23+1 ); + SetBank_PPUSUB( 0, chr4 ); + SetBank_PPUSUB( 1, chr5 ); + SetBank_PPUSUB( 2, chr6 ); + SetBank_PPUSUB( 3, chr7 ); + } else { +// SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, +// chr4, chr5, chr6, chr7 ); + SetBank_PPUSUB( 0, chr01+0 ); + SetBank_PPUSUB( 1, chr01+1 ); + SetBank_PPUSUB( 2, chr23+0 ); + SetBank_PPUSUB( 3, chr23+1 ); + SetBank_PPUSUB( 4, chr4 ); + SetBank_PPUSUB( 5, chr5 ); + SetBank_PPUSUB( 6, chr6 ); + SetBank_PPUSUB( 7, chr7 ); + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0) ); + SetCRAM_1K_Bank( 5, (chr01+1) ); + SetCRAM_1K_Bank( 6, (chr23+0) ); + SetCRAM_1K_Bank( 7, (chr23+1) ); + SetCRAM_1K_Bank( 0, chr4 ); + SetCRAM_1K_Bank( 1, chr5 ); + SetCRAM_1K_Bank( 2, chr6 ); + SetCRAM_1K_Bank( 3, chr7 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0) ); + SetCRAM_1K_Bank( 1, (chr01+1) ); + SetCRAM_1K_Bank( 2, (chr23+0) ); + SetCRAM_1K_Bank( 3, (chr23+1) ); + SetCRAM_1K_Bank( 4, chr4 ); + SetCRAM_1K_Bank( 5, chr5 ); + SetCRAM_1K_Bank( 6, chr6 ); + SetCRAM_1K_Bank( 7, chr7 ); + } + } +} + +void Mapper195::SetBank_PPUSUB( int bank, int page ) +{ + if( page <=3 ) { + SetCRAM_1K_Bank( bank, page ); + } else { + SetVROM_1K_Bank( bank, page ); + } +} + +void Mapper195::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = irq_request; +} + +void Mapper195::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + irq_request = p[19]; +} + + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper195.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper195.h new file mode 100644 index 00000000..0029c0bc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper195.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper195 {@_oo // +////////////////////////////////////////////////////////////////////////// +class Mapper195 : public Mapper +{ +public: + Mapper195( NES* parent ) : Mapper(parent) {} + + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; +private: + void SetBank_CPU(); + void SetBank_PPU(); + void SetBank_PPUSUB( int bank, int page ); +}; + + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper198.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper198.cpp new file mode 100644 index 00000000..77881bd2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper198.cpp @@ -0,0 +1,217 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper198 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper198::Reset() +{ + + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + prg2 = PROM_8K_SIZE-2; + prg3 = PROM_8K_SIZE-1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + reg6800 = 0; + reg6803 = 0; + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x935F2119 ) { //[ES-1110] Cheng Ji Si Han (C) + sp_rom = 1; + nes->SetSAVERAM_SIZE( 16*1024 ); + wram_bank = 0; + wram_count = 0; + } + +} + +void Mapper198::WriteLow( WORD addr, BYTE data ) +{ + +// if((addr!=0x7FA2)&&(addr!=0x7FA3)&&(addr>=0x6000)) DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); +// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + if(nes->rom->GetPROM_CRC()==0x2779bb41){ + switch( addr ) { //[NJ064] Sudoku (C) + case 0x6800: + reg6800 = data; + break; + case 0x6803: + reg6803 = data; + if((reg6800==0xe0)&&(reg6803==0x97)){ + prg0 = (PROM_8K_SIZE>>1)-4; + prg1 = (PROM_8K_SIZE>>1)-3; + prg2 = (PROM_8K_SIZE>>1)-2; + prg3 = (PROM_8K_SIZE>>1)-1; + SetBank_CPU(); + } + if((reg6800==0xe1)&&(reg6803==0x97)){ + prg0 = (PROM_8K_SIZE>>2)-4; + prg1 = (PROM_8K_SIZE>>2)-3; + prg2 = (PROM_8K_SIZE>>2)-2; + prg3 = (PROM_8K_SIZE>>2)-1; + SetBank_CPU(); + } + break; + } + } + + if((sp_rom==1)&&(addr==0x5226)) { + if( data ) { + SetPROM_Bank( 3, &WRAM[0x0000], BANKTYPE_RAM ); + } else { + SetPROM_Bank( 3, &WRAM[0x2000], BANKTYPE_RAM ); + } + } + + if( (addr>0x4018 && addr<0x6000)||(sp_rom==1) ) + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + else + adr5000buf[addr&0xFFF] = data; +} + +BYTE Mapper198::ReadLow( WORD addr ) +{ + if( (addr>0x4018 && addr<0x6000)||(sp_rom==1) ) + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + else + return adr5000buf[addr&0xFFF]; +} + +void Mapper198::Write( WORD addr, BYTE data ) +{ + +// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + if(data>=0x50) data&=0x4F; + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + break; + case 0xC001: + reg[5] = data; + break; + case 0xE000: + reg[6] = data; + break; + case 0xE001: + reg[7] = data; + break; + } +} + +void Mapper198::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( prg2, prg1, prg0, prg3 ); + } else { + SetPROM_32K_Bank( prg0, prg1, prg2, prg3 ); + } +} + +void Mapper198::SetBank_PPU() +{ + + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } +} + +void Mapper198::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; +} + +void Mapper198::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper198.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper198.h new file mode 100644 index 00000000..caa7df80 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper198.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper198 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper198 : public Mapper +{ +public: + Mapper198( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + + +protected: + BYTE reg[8]; + BYTE prg0, prg1, prg2, prg3; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + + BYTE adr5000buf[1024*4]; + BYTE sp_rom; + + BYTE reg6800; + BYTE reg6803; + + BYTE wram_bank; + BYTE wram_count; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper199.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper199.cpp new file mode 100644 index 00000000..044d5f84 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper199.cpp @@ -0,0 +1,260 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper199 WaiXingTypeG Base ON Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// + +void Mapper199::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + chr[i] = i; + } + prg[0] = 0x00; + prg[1] = 0x01; + prg[2] = PROM_8K_SIZE-2; + prg[3] = PROM_8K_SIZE-1; + SetBank_CPU(); + SetBank_PPU(); + + irq_enable=irq_counter=irq_latch=irq_request=0; + + JMaddr = 0; + JMaddrDAT[0] = JMaddrDAT[1] = JMaddrDAT[2] = 0; + + we_sram = 0; + nes->SetSAVERAM_SIZE( 32*1024 ); + nes->SetVideoMode( 1 ); + +// DWORD crcP = nes->rom->GetPROM_CRC(); +// DWORD crcV = nes->rom->GetVROM_CRC(); +/* + if( (crcP==0xE80D8741)||(crcV==0x3846520D)) + {//ǰĴ½ + nes->SetRenderMethod( NES::POST_ALL_RENDER ); + } +*/ +} + + +BYTE Mapper199::ReadLow( WORD addr ) +{ +// DEBUGOUT( "ReadLow A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, (Mapper::ReadLow( addr ))&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + if( addr >= 0x5000 && addr <= 0x5FFF ){ + return XRAM[addr-0x4000]; + }else if( addr >= 0x6000 && addr <= 0x7FFF ){ + if(JMaddr){ + switch( addr ) { + case 0x6000: return JMaddrDAT[0]; + case 0x6010: return JMaddrDAT[1]; + case 0x6013: JMaddr=0; return JMaddrDAT[2]; + } + } + + switch( we_sram ) { + case 0xE4: + case 0xEC: return WRAM[(addr&0x1FFF)+0x0000]; + case 0xE5: + case 0xED: return WRAM[(addr&0x1FFF)+0x2000]; + case 0xE6: + case 0xEE: return WRAM[(addr&0x1FFF)+0x4000]; + case 0xE7: + case 0xEF: return WRAM[(addr&0x1FFF)+0x6000]; + default: return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + } + + }else{ + return Mapper::ReadLow( addr ); + } +} + +void Mapper199::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT( "WriteLow A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + if( addr >= 0x5000 && addr <= 0x5FFF ){ + XRAM[addr-0x4000] = data; + if((we_sram==0xA1)||(we_sram==0xA5)||(we_sram==0xA9)){ + JMaddr = 1; + switch( addr ) { + case 0x5000: JMaddrDAT[0] = data; break; + case 0x5010: JMaddrDAT[1] = data; break; + case 0x5013: JMaddrDAT[2] = data; break; + } + } + }else if( addr >= 0x6000 && addr <= 0x7FFF ){ + + switch( we_sram ) { + case 0xE4: //CPU_MEM_BANK + case 0xEC: //CPU_MEM_BANK + WRAM[(addr&0x1FFF)+0x0000] = data; + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + case 0xE5: //SRAM + case 0xED: //SRAM + WRAM[(addr&0x1FFF)+0x2000] = data; + break; + case 0xE6: + case 0xEE: + WRAM[(addr&0x1FFF)+0x4000] = data; + break; + case 0xE7: + case 0xEF: + WRAM[(addr&0x1FFF)+0x6000] = data; + break; + default: + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + } + + }else{ + Mapper::WriteLow( addr, data ); + } +} + +void Mapper199::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + switch( reg[0] & 0x0f ) { + case 0x00:chr[0]=data;SetBank_PPU();break; + case 0x01:chr[2]=data;SetBank_PPU();break; + case 0x02: + case 0x03: + case 0x04: + case 0x05:chr[(reg[0]&0x07)+2]=data;SetBank_PPU();break; + case 0x06: + case 0x07: + case 0x08: + case 0x09:prg[(reg[0]&0x0f)-6]=data;SetBank_CPU();break; + case 0x0A:chr[1]=data;SetBank_PPU();break; + case 0x0B:chr[3]=data;SetBank_PPU();break; + } + break; + case 0xA000: + reg[2] = data; + data &= 0x03; + if ( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if ( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if ( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + break; + case 0xA001: +// DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + reg[3] = data; + we_sram = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + +} + +void Mapper199::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter -= 1; + } + } + if(!(irq_counter)){ + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + irq_counter--; + } + } + } +} + +void Mapper199::SetBank_CPU() +{ + SetPROM_8K_Bank(4,prg[0 ^(reg[0]>>5&~(0<<1)&2)]); + SetPROM_8K_Bank(5,prg[1 ^(reg[0]>>5&~(1<<1)&2)]); + SetPROM_8K_Bank(6,prg[2 ^(reg[0]>>5&~(2<<1)&2)]); + SetPROM_8K_Bank(7,prg[3 ^(reg[0]>>5&~(3<<1)&2)]); +} + +void Mapper199::SetBank_PPU() +{ + unsigned int bank = (reg[0]&0x80)>>5; + for(int x=0; x<8; x++) + { + if( chr[x]<=7 ) + SetCRAM_1K_Bank( x^bank, chr[x] ); + else + SetVROM_1K_Bank( x^bank, chr[x] ); + } +} + +void Mapper199::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + for( i = 8; i < 12; i++ ) { + p[i] = prg[i]; + } + for( i = 8; i < 20; i++ ) { + p[i] = chr[i]; + } + p[20] = we_sram; + p[21] = JMaddr; + p[22] = JMaddrDAT[0]; + p[23] = JMaddrDAT[1]; + p[24] = JMaddrDAT[2]; + p[25] = irq_enable; + p[26] = irq_counter; + p[27] = irq_latch; + p[28] = irq_request; +} + +void Mapper199::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + for( i = 8; i < 12; i++ ) { + prg[i] = p[i]; + } + for( i = 8; i < 20; i++ ) { + chr[i] = p[i]; + } + we_sram = p[20]; + JMaddr = p[21]; + JMaddrDAT[0] = p[22]; + JMaddrDAT[1] = p[23]; + JMaddrDAT[2] = p[24]; + irq_enable = p[25]; + irq_counter = p[26]; + irq_latch = p[27]; + irq_request = p[28]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper199.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper199.h new file mode 100644 index 00000000..f9ca2a11 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper199.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper199 WaiXingTypeG Base ON Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper199 : public Mapper +{ +public: + Mapper199( NES* parent ) : Mapper(parent) {} + + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8], prg[4], chr[8]; + + BYTE we_sram; + BYTE JMaddr, JMaddrDAT[3]; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper200.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper200.cpp new file mode 100644 index 00000000..a0569908 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper200.cpp @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper200 1200-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper200::Reset() +{ +// SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper200::Write( WORD addr, BYTE data ) +{ + SetPROM_16K_Bank( 4, addr & 0x07 ); + SetPROM_16K_Bank( 6, addr & 0x07 ); + SetVROM_8K_Bank( addr & 0x07 ); + + if( addr & 0x01 ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + SetVRAM_Mirror( VRAM_HMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper200.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper200.h new file mode 100644 index 00000000..decd672a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper200.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper200 1200-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper200 : public Mapper +{ +public: + Mapper200( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper201.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper201.cpp new file mode 100644 index 00000000..99ee457a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper201.cpp @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper201 21-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper201::Reset() +{ +// SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper201::Write( WORD addr, BYTE data ) +{ + BYTE bank = (BYTE)addr & 0x03; + if( !(addr&0x08) ) + bank = 0; + SetPROM_32K_Bank( bank ); + SetVROM_8K_Bank( bank ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper201.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper201.h new file mode 100644 index 00000000..43715ac7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper201.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper201 21-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper201 : public Mapper +{ +public: + Mapper201( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper202.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper202.cpp new file mode 100644 index 00000000..681d4519 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper202.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper202 150-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper202::Reset() +{ + SetPROM_16K_Bank( 4, 6 ); + SetPROM_16K_Bank( 6, 7 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper202::ExWrite( WORD addr, BYTE data ) +{ + if( addr >= 0x4020 ) { + WriteSub( addr, data ); + } +} + +void Mapper202::WriteLow( WORD addr, BYTE data ) +{ + WriteSub( addr, data ); +} + +void Mapper202::Write( WORD addr, BYTE data ) +{ + WriteSub( addr, data ); +} + +void Mapper202::WriteSub( WORD addr, BYTE data ) +{ + INT bank = (addr>>1) & 0x07; + + SetPROM_16K_Bank( 4, bank ); + if( (addr & 0x0C) == 0x0C ) { + SetPROM_16K_Bank( 6, bank+1 ); + } else { + SetPROM_16K_Bank( 6, bank ); + } + SetVROM_8K_Bank( bank ); + + if( addr & 0x01 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper202.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper202.h new file mode 100644 index 00000000..dcf94ebc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper202.h @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper202 150-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper202 : public Mapper +{ +public: + Mapper202( NES* parent ) : Mapper(parent) {} + + void Reset(); + void ExWrite( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + +protected: +private: + void WriteSub( WORD addr, BYTE data ); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper212.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper212.cpp new file mode 100644 index 00000000..64efd652 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper212.cpp @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper212 // +////////////////////////////////////////////////////////////////////////// +void Mapper212::Reset() +{ + SetPROM_32K_Bank(PROM_8K_SIZE-4,PROM_8K_SIZE-3,PROM_8K_SIZE-2,PROM_8K_SIZE-1); + if(VROM_1K_SIZE) SetVROM_8K_Bank(0); +} + +BYTE Mapper212::ReadLow( WORD addr ) +{ + return ~((addr&0x10)<<3); +} + +void Mapper212::Write( WORD addr, BYTE data ) +{ + if (addr & 0x4000) { + SetPROM_32K_Bank((addr >> 1) & 3); + } else { + SetPROM_16K_Bank(4, addr & 7); + SetPROM_16K_Bank(6, addr & 7); + } + SetVROM_8K_Bank(addr & 7); + if((addr>>3)&1) SetVRAM_Mirror(VRAM_HMIRROR); + else SetVRAM_Mirror(VRAM_VMIRROR); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper212.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper212.h new file mode 100644 index 00000000..26e8d098 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper212.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper212 // +////////////////////////////////////////////////////////////////////////// +class Mapper212 : public Mapper +{ +public: + Mapper212( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper222.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper222.cpp new file mode 100644 index 00000000..943e60ed --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper222.cpp @@ -0,0 +1,133 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper222 // +////////////////////////////////////////////////////////////////////////// + +void Mapper222::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + SetVRAM_Mirror( VRAM_VMIRROR ); + + for(INT i=0;i<8;i++) reg[i] = i; + + irq_enable = 0; + irq_counter = 0; + + VBankNO = 0; +} + +BYTE Mapper222::ReadLow( WORD addr ) +{ + switch( addr & 0xF800 ) { + case 0x4800: break; + case 0x5000: return (BYTE)irq_counter&0x00FF; + case 0x5800: return (BYTE)((irq_counter>>8)&0x7F); + case 0x6000: + case 0x6800: + case 0x7000: + case 0x7800: return Mapper::ReadLow( addr ); + } + return (BYTE)(addr>>8); +} + +void Mapper222::WriteLow( WORD addr, BYTE data ) +{ + switch( addr & 0xF800 ) { + case 0x4800: + // + break; + case 0x5000: + irq_counter = (irq_counter & 0xFF00) | (WORD)data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0x5800: + // + break; + case 0x6000: + case 0x6800: + case 0x7000: + case 0x7800: + Mapper::WriteLow( addr, data ); + break; + } +} + +void Mapper222::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xF003 ) { + case 0x8000: + SetPROM_8K_Bank( 4, data ); + break; + case 0x9000: + if(VROM_1K_SIZE>128){ + if( data&0x40 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA000: + SetPROM_8K_Bank( 5, data ); + break; + case 0xB000: + SetVROM_1K_Bank( 0, data ); + VBankNO = data; + break; + case 0xB002: + SetVROM_1K_Bank( 1, data ); + break; + case 0xC000: + SetVROM_1K_Bank( 2, data ); + break; + case 0xC002: + SetVROM_1K_Bank( 3, data ); + break; + case 0xD000: + SetVROM_1K_Bank( 4, data ); + break; + case 0xD002: + SetVROM_1K_Bank( 5, data ); + break; + case 0xE000: + SetVROM_1K_Bank( 6, data ); + break; + case 0xE002: + SetVROM_1K_Bank( 7, data ); + break; + case 0xF000: + // + break; + case 0xF001: + if(VBankNO==0x20){ // Dragon Ninja (J) + if(data) data = (data+0x12)>>1; + }else{ + if(data) data = (data+0x10)>>1; + } + irq_counter = (irq_counter & 0x00FF) | ((WORD)(data & 0x7F) << 8); + irq_enable = data; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xF002: + // + break; + } +} + +void Mapper222::Clock( INT cycles ) +{ + if( irq_enable ) { + if( (irq_counter+=cycles) >= 0x7FFF ) { + irq_enable = 0; + irq_counter = 0x7FFF; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } +} + +void Mapper222::SaveState( LPBYTE p ) +{ + // +} + +void Mapper222::LoadState( LPBYTE p ) +{ + // +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper222.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper222.h new file mode 100644 index 00000000..c3c75284 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper222.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper222 // +////////////////////////////////////////////////////////////////////////// +class Mapper222 : public Mapper +{ +public: + Mapper222( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE irq_enable; + WORD irq_counter; + BYTE VBankNO; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper225.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper225.cpp new file mode 100644 index 00000000..365f94e4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper225.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper225 72-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper225::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper225::Write( WORD addr, BYTE data ) +{ + BYTE prg_bank = (addr & 0x0F80) >> 7; + BYTE chr_bank = addr & 0x003F; + + SetVROM_1K_Bank(0,(chr_bank*8+0)); + SetVROM_1K_Bank(1,(chr_bank*8+1)); + SetVROM_1K_Bank(2,(chr_bank*8+2)); + SetVROM_1K_Bank(3,(chr_bank*8+3)); + SetVROM_1K_Bank(4,(chr_bank*8+4)); + SetVROM_1K_Bank(5,(chr_bank*8+5)); + SetVROM_1K_Bank(6,(chr_bank*8+6)); + SetVROM_1K_Bank(7,(chr_bank*8+7)); + + if( addr & 0x2000 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + + if( addr & 0x1000 ) { + // 16KBbank + if( addr & 0x0040 ) { + SetPROM_8K_Bank(4,(prg_bank*4+2)); + SetPROM_8K_Bank(5,(prg_bank*4+3)); + SetPROM_8K_Bank(6,(prg_bank*4+2)); + SetPROM_8K_Bank(7,(prg_bank*4+3)); + } else { + SetPROM_8K_Bank(4,(prg_bank*4+0)); + SetPROM_8K_Bank(5,(prg_bank*4+1)); + SetPROM_8K_Bank(6,(prg_bank*4+0)); + SetPROM_8K_Bank(7,(prg_bank*4+1)); + } + } else { + SetPROM_8K_Bank(4,(prg_bank*4+0)); + SetPROM_8K_Bank(5,(prg_bank*4+1)); + SetPROM_8K_Bank(6,(prg_bank*4+2)); + SetPROM_8K_Bank(7,(prg_bank*4+3)); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper225.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper225.h new file mode 100644 index 00000000..4e512e73 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper225.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper225 72-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper225 : public Mapper +{ +public: + Mapper225( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper226.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper226.cpp new file mode 100644 index 00000000..2817defb --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper226.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper226 76-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper226::Reset() +{ + SetPROM_32K_Bank( 0 ); + + reg[0] = 0; + reg[1] = 0; +} + +void Mapper226::Write( WORD addr, BYTE data ) +{ + if( addr & 0x001 ) { + reg[1] = data; + } else { + reg[0] = data; + } + + if( reg[0] & 0x40 ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + SetVRAM_Mirror( VRAM_HMIRROR ); + } + + BYTE bank = ((reg[0]&0x1E)>>1)|((reg[0]&0x80)>>3)|((reg[1]&0x01)<<5); + + if( reg[0] & 0x20 ) { + if( reg[0] & 0x01 ) { + SetPROM_8K_Bank( 4, bank*4+2 ); + SetPROM_8K_Bank( 5, bank*4+3 ); + SetPROM_8K_Bank( 6, bank*4+2 ); + SetPROM_8K_Bank( 7, bank*4+3 ); + } else { + SetPROM_8K_Bank( 4, bank*4+0 ); + SetPROM_8K_Bank( 5, bank*4+1 ); + SetPROM_8K_Bank( 6, bank*4+0 ); + SetPROM_8K_Bank( 7, bank*4+1 ); + } + } else { + SetPROM_8K_Bank( 4, bank*4+0 ); + SetPROM_8K_Bank( 5, bank*4+1 ); + SetPROM_8K_Bank( 6, bank*4+2 ); + SetPROM_8K_Bank( 7, bank*4+3 ); + } +} + +void Mapper226::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; +} + +void Mapper226::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper226.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper226.h new file mode 100644 index 00000000..f9ff270c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper226.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper226 76-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper226 : public Mapper +{ +public: + Mapper226( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[2]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper227.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper227.cpp new file mode 100644 index 00000000..a4d24c1d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper227.cpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper227 1200-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper227::Reset() +{ + SetPROM_32K_Bank( 0, 1, 0, 1 ); +} + +void Mapper227::Write( WORD addr, BYTE data ) +{ + BYTE bank = ((addr&0x0100)>>4)|((addr&0x0078)>>3); + + if( addr & 0x0001 ) { + SetPROM_32K_Bank( bank ); + } else { + if( addr & 0x0004 ) { + SetPROM_8K_Bank( 4, bank*4+2 ); + SetPROM_8K_Bank( 5, bank*4+3 ); + SetPROM_8K_Bank( 6, bank*4+2 ); + SetPROM_8K_Bank( 7, bank*4+3 ); + } else { + SetPROM_8K_Bank( 4, bank*4+0 ); + SetPROM_8K_Bank( 5, bank*4+1 ); + SetPROM_8K_Bank( 6, bank*4+0 ); + SetPROM_8K_Bank( 7, bank*4+1 ); + } + } + + if( !(addr & 0x0080) ) { + if( addr & 0x0200 ) { + SetPROM_8K_Bank( 6, (bank&0x1C)*4+14 ); + SetPROM_8K_Bank( 7, (bank&0x1C)*4+15 ); + } else { + SetPROM_8K_Bank( 6, (bank&0x1C)*4+0 ); + SetPROM_8K_Bank( 7, (bank&0x1C)*4+1 ); + } + } + if( addr & 0x0002 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper227.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper227.h new file mode 100644 index 00000000..429106c9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper227.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper227 1200-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper227 : public Mapper +{ +public: + Mapper227( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper228.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper228.cpp new file mode 100644 index 00000000..0f44c03e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper228.cpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper228 Action 52 // +////////////////////////////////////////////////////////////////////////// +void Mapper228::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper228::Write( WORD addr, BYTE data ) +{ + BYTE prg = (addr&0x0780)>>7; + + switch( (addr&0x1800)>>11 ) { + case 1: + prg |= 0x10; + break; + case 3: + prg |= 0x20; + break; + } + + if( addr & 0x0020 ) { + prg <<= 1; + if( addr & 0x0040 ) { + prg++; + } + SetPROM_8K_Bank( 4, prg*4+0 ); + SetPROM_8K_Bank( 5, prg*4+1 ); + SetPROM_8K_Bank( 6, prg*4+0 ); + SetPROM_8K_Bank( 7, prg*4+1 ); + } else { + SetPROM_8K_Bank( 4, prg*4+0 ); + SetPROM_8K_Bank( 5, prg*4+1 ); + SetPROM_8K_Bank( 6, prg*4+2 ); + SetPROM_8K_Bank( 7, prg*4+3 ); + } + + SetVROM_8K_Bank( ((addr&0x000F)<<2)|(data&0x03) ); + + if( addr & 0x2000 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper228.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper228.h new file mode 100644 index 00000000..c8d093be --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper228.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper228 Action 52 // +////////////////////////////////////////////////////////////////////////// +class Mapper228 : public Mapper +{ +public: + Mapper228( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper229.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper229.cpp new file mode 100644 index 00000000..fd662529 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper229.cpp @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper229 31-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper229::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); +} + +void Mapper229::Write( WORD addr, BYTE data ) +{ + if( addr & 0x001E ) { + BYTE prg = addr&0x001F; + + SetPROM_8K_Bank( 4, prg*2+0 ); + SetPROM_8K_Bank( 5, prg*2+1 ); + SetPROM_8K_Bank( 6, prg*2+0 ); + SetPROM_8K_Bank( 7, prg*2+1 ); + + SetVROM_8K_Bank( addr & 0x0FFF ); + } else { + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); + } + + if( addr & 0x0020 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper229.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper229.h new file mode 100644 index 00000000..b4dc9b5f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper229.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper229 31-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper229 : public Mapper +{ +public: + Mapper229( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper230.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper230.cpp new file mode 100644 index 00000000..3137037e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper230.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper230 22-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper230::Reset() +{ + if( rom_sw ) { + rom_sw = 0; + } else { + rom_sw = 1; + } + if( rom_sw ) { + SetPROM_32K_Bank( 0, 1, 14, 15 ); + } else { + SetPROM_32K_Bank( 16, 17, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper230::Write( WORD addr, BYTE data ) +{ + if( rom_sw ) { + SetPROM_8K_Bank( 4, (data&0x07)*2+0 ); + SetPROM_8K_Bank( 5, (data&0x07)*2+1 ); + } else { + if( data & 0x20 ) { + SetPROM_8K_Bank( 4, (data&0x1F)*2+16 ); + SetPROM_8K_Bank( 5, (data&0x1F)*2+17 ); + SetPROM_8K_Bank( 6, (data&0x1F)*2+16 ); + SetPROM_8K_Bank( 7, (data&0x1F)*2+17 ); + } else { + SetPROM_8K_Bank( 4, (data&0x1E)*2+16 ); + SetPROM_8K_Bank( 5, (data&0x1E)*2+17 ); + SetPROM_8K_Bank( 6, (data&0x1E)*2+18 ); + SetPROM_8K_Bank( 7, (data&0x1E)*2+19 ); + } + if( data & 0x40 ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + SetVRAM_Mirror( VRAM_HMIRROR ); + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper230.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper230.h new file mode 100644 index 00000000..f1b7eefe --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper230.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper230 22-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper230 : public Mapper +{ +public: + Mapper230( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: + BYTE rom_sw; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper231.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper231.cpp new file mode 100644 index 00000000..96da06a0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper231.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper231 20-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper231::Reset() +{ + SetPROM_32K_Bank( 0 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } +} + +void Mapper231::Write( WORD addr, BYTE data ) +{ + if( addr & 0x0020 ) { + SetPROM_32K_Bank( (BYTE)(addr>>1) ); + } else { + BYTE bank = addr & 0x1E; + SetPROM_8K_Bank( 4, bank*2+0 ); + SetPROM_8K_Bank( 5, bank*2+1 ); + SetPROM_8K_Bank( 6, bank*2+0 ); + SetPROM_8K_Bank( 7, bank*2+1 ); + } + + if( addr & 0x0080 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper231.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper231.h new file mode 100644 index 00000000..cfd1ad54 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper231.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper231 20-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper231 : public Mapper +{ +public: + Mapper231( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper232.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper232.cpp new file mode 100644 index 00000000..224a2422 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper232.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper232 Quattro Games // +////////////////////////////////////////////////////////////////////////// +void Mapper232::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + reg[0] = 0x0C; + reg[1] = 0x00; +} + +void Mapper232::Write( WORD addr, BYTE data ) +{ + if( addr == 0x9000 ) { + reg[0] = (data & 0x18)>>1; + } else if( addr >= 0xA000 && addr <= 0xFFFF ) { + reg[1] = data & 0x03; + } + + SetPROM_8K_Bank( 4, (reg[0]|reg[1])*2+0 ); + SetPROM_8K_Bank( 5, (reg[0]|reg[1])*2+1 ); + SetPROM_8K_Bank( 6, (reg[0]|0x03)*2+0 ); + SetPROM_8K_Bank( 7, (reg[0]|0x03)*2+1 ); +} + +void Mapper232::SaveState( LPBYTE p ) +{ + p[ 0] = reg[0]; + p[ 1] = reg[1]; +} + +void Mapper232::LoadState( LPBYTE p ) +{ + reg[0] = p[ 0]; + reg[1] = p[ 1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper232.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper232.h new file mode 100644 index 00000000..98484416 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper232.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper232 Quattro Games // +////////////////////////////////////////////////////////////////////////// +class Mapper232 : public Mapper +{ +public: + Mapper232( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[2]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper233.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper233.cpp new file mode 100644 index 00000000..9ce35d49 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper233.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper233 42-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper233::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); +} + +void Mapper233::Write( WORD addr, BYTE data ) +{ + if( data & 0x20 ) { + SetPROM_8K_Bank( 4, (data&0x1F)*2+0 ); + SetPROM_8K_Bank( 5, (data&0x1F)*2+1 ); + SetPROM_8K_Bank( 6, (data&0x1F)*2+0 ); + SetPROM_8K_Bank( 7, (data&0x1F)*2+1 ); + } else { + BYTE bank = (data&0x1E)>>1; + + SetPROM_8K_Bank( 4, bank*4+0 ); + SetPROM_8K_Bank( 5, bank*4+1 ); + SetPROM_8K_Bank( 6, bank*4+2 ); + SetPROM_8K_Bank( 7, bank*4+3 ); + } + + if( (data&0xC0) == 0x00 ) { + SetVRAM_Mirror( 0, 0, 0, 1 ); + } else if( (data&0xC0) == 0x40 ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else if( (data&0xC0) == 0x80 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_MIRROR4H ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper233.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper233.h new file mode 100644 index 00000000..333005c8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper233.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper233 42-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper233 : public Mapper +{ +public: + Mapper233( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper234.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper234.cpp new file mode 100644 index 00000000..0b0b7f33 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper234.cpp @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper234 Maxi-15 // +////////////////////////////////////////////////////////////////////////// +void Mapper234::Reset() +{ + SetPROM_32K_Bank( 0, 1, 2, 3 ); + + reg[0] = 0; + reg[1] = 0; +} + +void Mapper234::Read( WORD addr, BYTE data) +{ + if( addr >= 0xFF80 && addr <= 0xFF9F ) { + if( !reg[0] ) { + reg[0] = data; + SetBank(); + } + } + + if( addr >= 0xFFE8 && addr <= 0xFFF7 ) { + reg[1] = data; + SetBank(); + } +} + +void Mapper234::Write( WORD addr, BYTE data ) +{ + if( addr >= 0xFF80 && addr <= 0xFF9F ) { + if( !reg[0] ) { + reg[0] = data; + SetBank(); + } + } + + if( addr >= 0xFFE8 && addr <= 0xFFF7 ) { + reg[1] = data; + SetBank(); + } +} + +void Mapper234::SetBank() +{ + if( reg[0] & 0x80 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( (reg[0]&0x0E)|(reg[1]&0x01) ); + SetVROM_8K_Bank( ((reg[0]&0x0E)<<2)|((reg[1]>>4)&0x07) ); + } else { + SetPROM_32K_Bank( reg[0]&0x0F ); + SetVROM_8K_Bank( ((reg[0]&0x0F)<<2)|((reg[1]>>4)&0x03) ); + } +} + +void Mapper234::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; +} + +void Mapper234::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper234.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper234.h new file mode 100644 index 00000000..c3dfbf7e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper234.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper234 Maxi-15 // +////////////////////////////////////////////////////////////////////////// +class Mapper234 : public Mapper +{ +public: + Mapper234( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + void Read( WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[2]; +private: + void SetBank(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper235.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper235.cpp new file mode 100644 index 00000000..47f29d6e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper235.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper235 150-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper235::Reset() +{ + for( INT i = 0; i < 0x2000; i++ ) { + DRAM[i] = 0xFF; + } + SetPROM_32K_Bank( 0 ); + + if( PROM_8K_SIZE == 32*2 ) { // 20-in-1 + dip_s=dip_s&3; + dip_s++; +// if(dip_s==4) dip_s=0; + } + +} + +void Mapper235::Write( WORD addr, BYTE data ) +{ + BYTE prg = ((addr&0x0300)>>3)|(addr&0x001F); + BYTE bus = 0; + + if( PROM_8K_SIZE == 64*2 ) { + // 100-in-1 + switch( addr & 0x0300 ) { + case 0x0000: break; + case 0x0100: bus = 1; break; + case 0x0200: bus = 1; break; + case 0x0300: bus = 1; break; + } + } else if( PROM_8K_SIZE == 128*2 ) { + // 150-in-1 + switch( addr & 0x0300 ) { + case 0x0000: break; + case 0x0100: bus = 1; break; + case 0x0200: prg = (prg&0x1F)|0x20; break; + case 0x0300: bus = 1; break; + } + } else if( PROM_8K_SIZE == 192*2 ) { + // 150-in-1 + switch( addr & 0x0300 ) { + case 0x0000: break; + case 0x0100: bus = 1; break; + case 0x0200: prg = (prg&0x1F)|0x20; break; + case 0x0300: prg = (prg&0x1F)|0x40; break; + } + } else if( PROM_8K_SIZE == 256*2 ) { + } + + if( addr & 0x0800 ) { + if( addr & 0x1000 ) { + SetPROM_8K_Bank( 4, prg*4+2 ); + SetPROM_8K_Bank( 5, prg*4+3 ); + SetPROM_8K_Bank( 6, prg*4+2 ); + SetPROM_8K_Bank( 7, prg*4+3 ); + } else { + SetPROM_8K_Bank( 4, prg*4+0 ); + SetPROM_8K_Bank( 5, prg*4+1 ); + SetPROM_8K_Bank( 6, prg*4+0 ); + SetPROM_8K_Bank( 7, prg*4+1 ); + } + } else { + SetPROM_32K_Bank( prg ); + } + + if( bus ) { + SetPROM_Bank( 4, DRAM, BANKTYPE_ROM ); + SetPROM_Bank( 5, DRAM, BANKTYPE_ROM ); + SetPROM_Bank( 6, DRAM, BANKTYPE_ROM ); + SetPROM_Bank( 7, DRAM, BANKTYPE_ROM ); + } + + if( addr & 0x0400 ) { + SetVRAM_Mirror( VRAM_MIRROR4L ); + } else if( addr & 0x2000 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + + if( PROM_8K_SIZE == 32*2 ) { // 20-in-1 + if(addr==0x8000){ + if(data&0x80){ + SetPROM_16K_Bank(4, data&0x1F); + SetPROM_16K_Bank(6, data&0x1F); + }else{ + SetPROM_32K_Bank((data&0x1F)>>1); + } + if(data&0x40) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + if(addr==0x8003){ +// SetPROM_16K_Bank(4, dip_s); + SetPROM_8K_Bank(4, dip_s); +// SetPROM_8K_Bank(5, dip_s); + } + } + +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper235.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper235.h new file mode 100644 index 00000000..6bb7dcf0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper235.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper235 150-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper235 : public Mapper +{ +public: + Mapper235( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: + BYTE dip_s; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper236.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper236.cpp new file mode 100644 index 00000000..21235f64 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper236.cpp @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper236 800-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper236::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + bank = mode = 0; +} + +void Mapper236::Write( WORD addr, BYTE data ) +{ + if( addr >= 0x8000 && addr <= 0xBFFF ) { + bank = ((addr&0x03)<<4)|(bank&0x07); + } else { + bank = (addr&0x07)|(bank&0x30); + mode = addr&0x30; + } + + if( addr & 0x20 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + + switch( mode ) { + case 0x00: + bank |= 0x08; + SetPROM_8K_Bank( 4, bank*2+0 ); + SetPROM_8K_Bank( 5, bank*2+1 ); + SetPROM_8K_Bank( 6, (bank|0x07)*2+0 ); + SetPROM_8K_Bank( 7, (bank|0x07)*2+1 ); + break; + case 0x10: + bank |= 0x37; + SetPROM_8K_Bank( 4, bank*2+0 ); + SetPROM_8K_Bank( 5, bank*2+1 ); + SetPROM_8K_Bank( 6, (bank|0x07)*2+0 ); + SetPROM_8K_Bank( 7, (bank|0x07)*2+1 ); + break; + case 0x20: + bank |= 0x08; + SetPROM_8K_Bank( 4, (bank&0xFE)*2+0 ); + SetPROM_8K_Bank( 5, (bank&0xFE)*2+1 ); + SetPROM_8K_Bank( 6, (bank&0xFE)*2+2 ); + SetPROM_8K_Bank( 7, (bank&0xFE)*2+3 ); + break; + case 0x30: + bank |= 0x08; + SetPROM_8K_Bank( 4, bank*2+0 ); + SetPROM_8K_Bank( 5, bank*2+1 ); + SetPROM_8K_Bank( 6, bank*2+0 ); + SetPROM_8K_Bank( 7, bank*2+1 ); + break; + } +} + +void Mapper236::SaveState( LPBYTE p ) +{ + p[ 0] = bank; + p[ 1] = mode; +} + +void Mapper236::LoadState( LPBYTE p ) +{ + bank = p[ 0]; + mode = p[ 1]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper236.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper236.h new file mode 100644 index 00000000..3db14af8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper236.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper236 800-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper236 : public Mapper +{ +public: + Mapper236( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE bank, mode; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper237.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper237.cpp new file mode 100644 index 00000000..6aaa4873 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper237.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper237 // +////////////////////////////////////////////////////////////////////////// +void Mapper237::Reset() +{ + A0=A1=A2=0; + D0=D1=D3=D5=D6=0; + SetPROM_16K_Bank( 4, 0 ); + SetPROM_16K_Bank( 6, 7 ); + + dip_s=dip_s&3; + dip_s++; + if(dip_s==4) dip_s=0; + +} + +BYTE Mapper237::Read( WORD addr ) +{ + if( addr == 0xC000 ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = dip_s+1; + } + return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; +} + +void Mapper237::Write( WORD addr, BYTE data ) +{ + if(A1&0x01){ + SetPROM_16K_Bank( 4, data|(D3<<3)|(A2<<5) ); + SetPROM_16K_Bank( 6, 0x07|(D3<<3)|(A2<<5) ); + return; + } + + A0 = ((addr&0x07)>>0) & 0x01; + A1 = ((addr&0x07)>>1) & 0x01; + A2 = ((addr&0x07)>>2) & 0x01; + D0 = (data>>0) & 0x07; + D1 = (data>>1) & 0x03; + D3 = (data>>3) & 0x03; + D5 = (data>>5) & 0x01; + D6 = (data>>6) & 0x03; + + if(D5&0x01) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + + switch( D6 ) { + case 0: //UNROM mode + SetPROM_16K_Bank( 4, D0|(D3<<3)|(A2<<5) ); + SetPROM_16K_Bank( 6, 0x07|(D3<<3)|(A2<<5) ); + break; + case 1: //CNROM mode ?? + SetPROM_16K_Bank( 4, (D0&0x06)|(D3<<3)|(A2<<5) ); + SetPROM_16K_Bank( 6, 0x07|(D3<<3)|(A2<<5) ); + break; + case 2: //16K NROM mode + SetPROM_16K_Bank( 4, D0|(D3<<3)|(A2<<5) ); + SetPROM_16K_Bank( 6, D0|(D3<<3)|(A2<<5) ); + break; + case 3: //32K NROM mode + SetPROM_32K_Bank( D1|(D3<<2)|(A2<<4) ); + break; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper237.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper237.h new file mode 100644 index 00000000..0706de1c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper237.h @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper237 // +////////////////////////////////////////////////////////////////////////// +class Mapper237 : public Mapper +{ +public: + Mapper237( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + BYTE Read( WORD addr ); + +protected: + BYTE A0,A1,A2,dip_s; + BYTE D0,D1,D3,D5,D6; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper240.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper240.cpp new file mode 100644 index 00000000..5091cdf1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper240.cpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper240 Gen Ke Le Zhuan // +////////////////////////////////////////////////////////////////////////// + +void Mapper240::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + KT_Piracy = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x7EA0D0C3 //[KT-1001] Jing Ke Xin Zhuan (C) + || crc == 0xC73EE9E2 //[KT-1002] Sheng Huo Lie Zhuan (C) + || crc == 0x8B98AE98 //[KT-1013] Zhan Guo Feng Yun (C) + || crc == 0xEB628838) { //[KT-1014] Xia Ke Chuan Qi (C) + KT_Piracy = 1; + } + if ( KT_Piracy == 1 ) SetPROM_32K_Bank( 0 ); +} + +void Mapper240::WriteLow( WORD addr, BYTE data ) +{ +// DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); + + if( addr>=0x4020 && addr<0x6000 ) { + if ( KT_Piracy == 1 ) { + if(addr==0x4801) SetPROM_32K_Bank( (data&0xF)>>1 ); + if(addr==0x4803) SetVROM_8K_Bank(data&0xF); + }else{ + SetPROM_32K_Bank( (data&0xF0)>>4 ); + SetVROM_8K_Bank(data&0xF); + } + } + + if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF]=data; + +} + +void Mapper240::Write( WORD addr, BYTE data ) +{ +// DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper240.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper240.h new file mode 100644 index 00000000..edd2d9c0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper240.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper240 Gen Ke Le Zhuan // +////////////////////////////////////////////////////////////////////////// +class Mapper240 : public Mapper +{ +public: + Mapper240( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + void Write(WORD addr, BYTE data); + +protected: + BYTE KT_Piracy; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper241.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper241.cpp new file mode 100644 index 00000000..dc1ff74f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper241.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper241 Education X-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper241::Reset() +{ + SetPROM_32K_Bank( 0 ); + if( VROM_1K_SIZE ) SetVROM_8K_Bank( 0 ); + + SBPAL_fix = 0; + DWORD crc = nes->rom->GetPROM_CRC(); + if(crc == 0x85068811) SBPAL_fix = 1; //[Subor] Subor V6.0 (C) + if(crc == 0xE475D89A) SBPAL_fix = 2; //[Subor] Subor V9.0 (C) + if(crc == 0x900D9E00) SBPAL_fix = 2; //[Subor] Subor V9.1 (C) +} + +void Mapper241::Write( WORD addr, BYTE data ) +{ + +// if(nes->GetScanline() == 283) + DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() ); + +// if( addr == 0x8000 ) SetPROM_32K_Bank( data ); + +// if( data&0x80 ) +// SetPROM_32K_Bank( ((data&7)>>1)+4 ); +// else +// SetPROM_32K_Bank( (data&7)>>1 ); + +// if( data&0x80 ) +// SetPROM_32K_Bank( data+8 ); +// else + SetPROM_32K_Bank( data ); + + if(SBPAL_fix==1) //[Subor] Subor V6.0 (C) + if((addr==0x8D56)&&(data==3)&&(nes->GetScanline()==283)) + { + SetPROM_32K_Bank( 0 ); + } + if(SBPAL_fix==2) //[Subor] Subor V9.0 (C) + { + if((addr==0x8D5C)&&(data==9)&&((nes->GetScanline()>282)&&(nes->GetScanline()<291))) + { + SetPROM_32K_Bank( 0 ); + } + if((addr==0x8D56)&&(data==3)&&(nes->GetScanline()==283)) + { + SetPROM_32K_Bank( 0 ); + } + } + +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper241.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper241.h new file mode 100644 index 00000000..884eec7e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper241.h @@ -0,0 +1,15 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper241 Education X-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper241 : public Mapper +{ +public: + Mapper241( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: + BYTE SBPAL_fix; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper242.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper242.cpp new file mode 100644 index 00000000..9d16bc8e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper242.cpp @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper242 Wai Xing Zhan Shi // +////////////////////////////////////////////////////////////////////////// +void Mapper242::Reset() +{ + SetPROM_32K_Bank( 0 ); +} + +void Mapper242::Write( WORD addr, BYTE data ) +{ + if( addr & 0x01 ) { + SetPROM_32K_Bank( (addr&0xF8)>>3 ); + } + if( (addr & 0x03)>>1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper242.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper242.h new file mode 100644 index 00000000..0c3ea068 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper242.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper242 Wai Xing Zhan Shi // +////////////////////////////////////////////////////////////////////////// +class Mapper242 : public Mapper +{ +public: + Mapper242( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper243.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper243.cpp new file mode 100644 index 00000000..90a2e618 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper243.cpp @@ -0,0 +1,74 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper243 PC-Sachen/Hacker // +////////////////////////////////////////////////////////////////////////// +void Mapper243::Reset() +{ + SetPROM_32K_Bank( 0 ); + if( VROM_8K_SIZE > 4 ) { + SetVROM_8K_Bank( 4 ); + } else if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + SetVRAM_Mirror( VRAM_HMIRROR ); + + reg[0] = 0; + reg[1] = 0; + reg[2] = 3; + reg[3] = 0; +} + +void Mapper243::WriteLow( WORD addr, BYTE data ) +{ + if( (addr&0x4101) == 0x4100 ) { + reg[0] = data; + } else if( (addr&0x4101) == 0x4101 ) { + switch( reg[0] & 0x07 ) { + case 0: + reg[1] = 0; + reg[2] = 3; + break; + case 4: + reg[2] = (reg[2]&0x06)|(data&0x01); + break; + case 5: + reg[1] = data&0x01; + break; + case 6: + reg[2] = (reg[2]&0x01)|((data&0x03)<<1); + break; + case 7: + reg[3] = data&0x01; + break; + default: + break; + } + + SetPROM_32K_Bank( reg[1] ); + SetVROM_8K_Bank( reg[2]*8+0, reg[2]*8+1, reg[2]*8+2, reg[2]*8+3, + reg[2]*8+4, reg[2]*8+5, reg[2]*8+6, reg[2]*8+7 ); + + if( reg[3] ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + SetVRAM_Mirror( VRAM_HMIRROR ); + } + } +} + +void Mapper243::SaveState( LPBYTE p ) +{ + p[0] = reg[0]; + p[1] = reg[1]; + p[2] = reg[2]; + p[3] = reg[3]; +} + +void Mapper243::LoadState( LPBYTE p ) +{ + reg[0] = p[0]; + reg[1] = p[1]; + reg[2] = p[2]; + reg[3] = p[3]; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper243.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper243.h new file mode 100644 index 00000000..bfd26696 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper243.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper243 PC-Sachen/Hacker // +////////////////////////////////////////////////////////////////////////// +class Mapper243 : public Mapper +{ +public: + Mapper243( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[4]; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper244.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper244.cpp new file mode 100644 index 00000000..d8df0f36 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper244.cpp @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper244 // +////////////////////////////////////////////////////////////////////////// +void Mapper244::Reset() +{ + SetPROM_32K_Bank( 0 ); +} + +void Mapper244::Write( WORD addr, BYTE data ) +{ + if( addr>=0x8065 && addr<=0x80A4 ) { + SetPROM_32K_Bank( (addr-0x8065)&0x3 ); + } + + if( addr>=0x80A5 && addr<=0x80E4 ) { + SetVROM_8K_Bank( (addr-0x80A5)&0x7 ); + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper244.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper244.h new file mode 100644 index 00000000..13ad2bdd --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper244.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper244 // +////////////////////////////////////////////////////////////////////////// +class Mapper244 : public Mapper +{ +public: + Mapper244( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write(WORD addr, BYTE data); + +protected: +private: +}; \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper245.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper245.cpp new file mode 100644 index 00000000..e4921a8e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper245.cpp @@ -0,0 +1,194 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper245 Yong Zhe Dou E Long // +////////////////////////////////////////////////////////////////////////// + +void Mapper245::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + if( VROM_1K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_request = 0; + + nes->SetIrqType( NES::IRQ_CLOCK ); +} + +void Mapper245::Write( WORD addr, BYTE data ) +{ + switch( addr&0xF7FF ) { + case 0x8000: + reg[0] = data; + break; + case 0x8001: + reg[1] = data; + switch( reg[0] ) { + case 0x00: + reg[3]=(data & 2 )<<5; + SetPROM_8K_Bank(6,0x3E | reg[3]); + SetPROM_8K_Bank(7,0x3F | reg[3]); + break; + case 0x06: + prg0=data; + break; + case 0x07: + prg1=data; + break; + } + SetPROM_8K_Bank( 4, prg0|reg[3] ); + SetPROM_8K_Bank( 5, prg1|reg[3] ); + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper245::Clock( INT cycles ) +{ +// if( irq_request && (nes->GetIrqType() == NES::IRQ_CLOCK) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper245::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter--; + } + } + if( !(irq_counter--) ) { + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +// if( irq_request && (nes->GetIrqType() == NES::IRQ_HSYNC) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper245::SetBank_CPU() +{ + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper245::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr23+1, chr23, chr01+1, chr01 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } +} + +void Mapper245::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = (BYTE)irq_counter; + p[18] = irq_latch; + p[19] = irq_request; +} + +void Mapper245::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = (INT)p[17]; + irq_latch = p[18]; + irq_request = p[19]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper245.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper245.h new file mode 100644 index 00000000..c5517820 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper245.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper245 Yong Zhe Dou E Long // +////////////////////////////////////////////////////////////////////////// +class Mapper245 : public Mapper +{ +public: + Mapper245( NES* parent ) : Mapper(parent) {} + int MMC4prg,MMC4chr; + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper246.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper246.cpp new file mode 100644 index 00000000..e99cf477 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper246.cpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper246 Phone Serm Berm // +////////////////////////////////////////////////////////////////////////// + +void Mapper246::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper246::WriteLow( WORD addr, BYTE data ) +{ + if( addr>=0x6000 && addr<0x8000 ) { + switch( addr ) { + case 0x6000: + SetPROM_8K_Bank( 4, data ); + break; + case 0x6001: + SetPROM_8K_Bank( 5, data ); + break; + case 0x6002: + SetPROM_8K_Bank( 6, data ); + break; + case 0x6003: + SetPROM_8K_Bank( 7, data ); + break; + case 0x6004: + SetVROM_2K_Bank(0,data); + break; + case 0x6005: + SetVROM_2K_Bank(2,data); + break; + case 0x6006: + SetVROM_2K_Bank(4,data); + break; + case 0x6007: + SetVROM_2K_Bank(6,data); + break; + default: + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + } + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper246.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper246.h new file mode 100644 index 00000000..34f68f22 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper246.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper246 Phone Serm Berm // +////////////////////////////////////////////////////////////////////////// +class Mapper246 : public Mapper +{ +public: + Mapper246( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow(WORD addr, BYTE data); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper248.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper248.cpp new file mode 100644 index 00000000..4f07b735 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper248.cpp @@ -0,0 +1,178 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper248 Bao Qing Tian // +////////////////////////////////////////////////////////////////////////// +void Mapper248::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_request = 0; +} + +void Mapper248::WriteLow( WORD addr, BYTE data ) +{ + SetPROM_32K_Bank( 2*data, 2*data+1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); +} + +void Mapper248::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + } + break; + case 0xC000: + irq_enable=0; + irq_latch=0xBE; + irq_counter =0xBE; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC001: + irq_enable=1; + irq_latch=0xBE; + irq_counter=0xBE; + break; + } + +} + +void Mapper248::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable ) { + if( !(irq_counter--) ) { + irq_counter = irq_latch; +// nes->cpu->IRQ_NotPending(); + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +} + +void Mapper248::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper248::SetBank_PPU() +{ + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } +} + +void Mapper248::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = (BYTE)irq_counter; + p[18] = irq_latch; + p[19] = irq_request; +} + +void Mapper248::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = (INT)p[17]; + irq_latch = p[18]; + irq_request = p[19]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper248.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper248.h new file mode 100644 index 00000000..de813c75 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper248.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper248 Bao Qing Tian // +////////////////////////////////////////////////////////////////////////// +class Mapper248 : public Mapper +{ +public: + Mapper248( NES* parent ) : Mapper(parent) {} + + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper249.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper249.cpp new file mode 100644 index 00000000..71046a83 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper249.cpp @@ -0,0 +1,318 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper249 MMC3 // +////////////////////////////////////////////////////////////////////////// +void Mapper249::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + prg0 = 0; + prg1 = 1; + + SetPROM_32K_Bank( 0,1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + + SetVROM_8K_Bank( 0 ); + + we_sram = 0; // Disable + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_request = 0; + + // IRQ^Cvݒ + nes->SetIrqType( NES::IRQ_CLOCK ); + + spdata = 0; +} + +void Mapper249::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x5000 ) { + switch( data ) { + case 0x00: + spdata = 0; + break; + case 0x02: + spdata = 1; + break; + } + } + + if( addr>=0x6000 && addr<0x8000 ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + } +} + +void Mapper249::Write( WORD addr, BYTE data ) +{ + BYTE m0,m1,m2,m3,m4,m5,m6,m7; + + switch( addr&0xFF01 ) { + case 0x8000: + case 0x8800: + reg[0] = data; + break; + case 0x8001: + case 0x8801: + switch( reg[0] & 0x07 ) { + case 0x00: + if( spdata == 1 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + SetVROM_1K_Bank( 0, data&0xFE ); + SetVROM_1K_Bank( 1, data|0x01 ); + break; + case 0x01: + if( spdata == 1 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + SetVROM_1K_Bank( 2, data&0xFE ); + SetVROM_1K_Bank( 3, data|0x01 ); + break; + case 0x02: + if( spdata == 1 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + SetVROM_1K_Bank( 4, data ); + break; + case 0x03: + if( spdata == 1 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + SetVROM_1K_Bank( 5, data ); + break; + case 0x04: + if( spdata == 1 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + SetVROM_1K_Bank( 6, data ); + break; + case 0x05: + if( spdata == 1 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + SetVROM_1K_Bank( 7, data ); + break; + case 0x06: + if( spdata == 1 ) { + if( data < 0x20 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=0; + m6=0; + m7=0; + data=(m7<<7)|(m6<<6)|(m5<<5)|(m2<<4)|(m1<<3)|(m3<<2)|(m4<<1)|m0; + } else { + data=data-0x20; + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + } + SetPROM_8K_Bank( 4, data ); + break; + case 0x07: + if( spdata == 1 ) { + if( data < 0x20 ) { + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=0; + m6=0; + m7=0; + data=(m7<<7)|(m6<<6)|(m5<<5)|(m2<<4)|(m1<<3)|(m3<<2)|(m4<<1)|m0; + } else { + data=data-0x20; + m0=data&0x1; + m1=(data&0x02)>>1; + m2=(data&0x04)>>2; + m3=(data&0x08)>>3; + m4=(data&0x10)>>4; + m5=(data&0x20)>>5; + m6=(data&0x40)>>6; + m7=(data&0x80)>>7; + data=(m5<<7)|(m4<<6)|(m2<<5)|(m6<<4)|(m7<<3)|(m3<<2)|(m1<<1)|m0; + } + } + SetPROM_8K_Bank( 5, data ); + break; + } + break; + case 0xA000: + case 0xA800: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + case 0xA801: + reg[3] = data; + break; + case 0xC000: + case 0xC800: + reg[4] = data; + irq_counter = data; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC001: + case 0xC801: + reg[5] = data; + irq_latch = data; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE000: + case 0xE800: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + case 0xE801: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper249::Clock( INT cycles ) +{ +// if( irq_request && (nes->GetIrqType() == NES::IRQ_CLOCK) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper249::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter--; + } + } + if( !(irq_counter--) ) { + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +// if( irq_request && (nes->GetIrqType() == NES::IRQ_HSYNC) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper249::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = irq_request; + p[20] = spdata; +} + +void Mapper249::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + irq_request = p[19]; + spdata = p[20]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper249.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper249.h new file mode 100644 index 00000000..6375fb61 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper249.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper249 Nintendo MMC3 // +////////////////////////////////////////////////////////////////////////// +class Mapper249 : public Mapper +{ +public: + Mapper249( NES* parent ) : Mapper(parent) {} + int MMC4prg,MMC4chr; + + void Reset(); + void Write( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + //BYTE ReadLow( WORD addr ); + void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + BYTE spdata; + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + BYTE we_sram; + BYTE patch; + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + +private: + +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper251.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper251.cpp new file mode 100644 index 00000000..382ee3e2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper251.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper251 // +////////////////////////////////////////////////////////////////////////// +void Mapper251::Reset() +{ + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + + SetVRAM_Mirror( VRAM_VMIRROR ); + + INT i; + for( i = 0; i < 11; i++ ) + reg[i] = 0; + for( i = 0; i < 4; i++ ) + breg[i] = 0; +} + +void Mapper251::WriteLow( WORD addr, BYTE data ) +{ + if( (addr & 0xE001) == 0x6000 ) { + if( reg[9] ) { + breg[reg[10]++] = data; + if( reg[10] == 4 ) { + reg[10] = 0; + SetBank(); + } + } + } +} + +void Mapper251::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + reg[8] = data; + SetBank(); + break; + case 0x8001: + reg[reg[8]&0x07] = data; + SetBank(); + break; + case 0xA001: + if( data & 0x80 ) { + reg[ 9] = 1; + reg[10] = 0; + } else { + reg[ 9] = 0; + } + break; + } +} + +void Mapper251::SetBank() +{ + INT chr[6]; + INT prg[4]; + + for( INT i = 0; i < 6; i++ ) { + chr[i] = (reg[i]|(breg[1]<<4)) & ((breg[2]<<4)|0x0F); + } + + if( reg[8] & 0x80 ) { + SetVROM_8K_Bank(chr[2],chr[3],chr[4],chr[5],chr[0],chr[0]+1,chr[1],chr[1]+1); + } else { + SetVROM_8K_Bank(chr[0],chr[0]+1,chr[1],chr[1]+1,chr[2],chr[3],chr[4],chr[5]); + } + + prg[0] = (reg[6]&((breg[3]&0x3F)^0x3F))|(breg[1]); + prg[1] = (reg[7]&((breg[3]&0x3F)^0x3F))|(breg[1]); + prg[2] = prg[3] =((breg[3]&0x3F)^0x3F)|(breg[1]); + prg[2] &= PROM_8K_SIZE-1; + + if( reg[8] & 0x40 ) { + SetPROM_32K_Bank( prg[2],prg[1],prg[0],prg[3] ); + } else { + SetPROM_32K_Bank( prg[0],prg[1],prg[2],prg[3] ); + } +} + +void Mapper251::SaveState( LPBYTE p ) +{ + INT i; + + for( i = 0; i < 11; i++ ) { + p[i] = reg[i]; + } + for( i = 0; i < 4; i++ ) { + p[i+11] = breg[i]; + } +} + +void Mapper251::LoadState( LPBYTE p ) +{ + INT i; + for( i = 0; i < 11; i++ ) { + reg[i] = p[i]; + } + for( i = 0; i < 4; i++ ) { + reg[i] = p[i+11]; + } +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper251.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper251.h new file mode 100644 index 00000000..759f7cfa --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper251.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper251 // +////////////////////////////////////////////////////////////////////////// +class Mapper251 : public Mapper +{ +public: + Mapper251( NES* parent ) : Mapper(parent) {} + + void Reset(); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[11]; + BYTE breg[4]; +private: + void SetBank(); +}; + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper252.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper252.cpp new file mode 100644 index 00000000..e1240c6e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper252.cpp @@ -0,0 +1,179 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper252 // +////////////////////////////////////////////////////////////////////////// +void Mapper252::Reset() +{ + nes->ppu->SetVromWrite(1); + + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + irq_occur = 0; + + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + nes->SetRenderMethod( NES::POST_RENDER ); +} + +void Mapper252::Write( WORD addr, BYTE data ) +{ + if( (addr & 0xF000) == 0x8000 ) { + SetPROM_8K_Bank( 4, data ); + return; + } + if( (addr & 0xF000) == 0xA000 ) { + SetPROM_8K_Bank( 5, data ); + return; + } +/* if( addr == 0x9400 ) { + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + }*/ + switch( addr & 0xF00C ) { + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB004: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 0, reg[0] ); + break; + case 0xB008: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 1, reg[1] ); + break; + case 0xB00C: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 1, reg[1] ); + break; + + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC004: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 2, reg[2] ); + break; + case 0xC008: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 3, reg[3] ); + break; + case 0xC00C: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 3, reg[3] ); + break; + + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD004: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 4, reg[4] ); + break; + case 0xD008: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 5, reg[5] ); + break; + case 0xD00C: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 5, reg[5] ); + break; + + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE004: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 6, reg[6] ); + break; + case 0xE008: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetVROM_1K_Bank( 7, reg[7] ); + break; + case 0xE00C: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetVROM_1K_Bank( 7, reg[7] ); + break; + + case 0xF000: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + irq_occur = 0; + break; + case 0xF004: + irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); + irq_occur = 0; + break; + + case 0xF008: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + + case 0xF00C: + irq_enable = (irq_enable & 0x01) * 3; + irq_occur = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper252::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock+=cycles) >= 0x72 ) { + irq_clock -= 0x72; + if( irq_counter == 0xFF ) { + irq_occur = 0xFF; + irq_counter = irq_latch; + irq_enable = (irq_enable & 0x01) * 3; + + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } +// if( irq_occur ) { +// nes->cpu->IRQ_NotPending(); +// } + } +} + +void Mapper252::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + p[i] = reg[i]; + } + p[ 9] = irq_enable; + p[10] = irq_counter; + p[11] = irq_latch; + *(INT*)&p[12] = irq_clock; +} + +void Mapper252::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[ 9]; + irq_counter = p[10]; + irq_latch = p[11]; + irq_clock = *(INT*)&p[12]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper252.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper252.h new file mode 100644 index 00000000..486ffc7d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper252.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper252 // +////////////////////////////////////////////////////////////////////////// +class Mapper252 : public Mapper +{ +public: + Mapper252( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[9]; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_occur; + INT irq_clock; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper253.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper253.cpp new file mode 100644 index 00000000..37e14355 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper253.cpp @@ -0,0 +1,187 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper253 WaiXing LongZhu CN // +////////////////////////////////////////////////////////////////////////// +void Mapper253::Reset() +{ +// nes->ppu->SetVromWrite(1); + for( INT i = 0; i < 8; i++ ) { + reg[i] = i; + } + reg[8] = 0; + + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + irq_clock = 0; + VRAM_switch = 0; + rom_type = 0; + SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + SetVROM_8K_Bank( 0 ); + + DWORD crc = nes->rom->GetPROM_CRC(); + if( crc == 0x0530b26e ) { //[HengGe] Shen Hua Jian Yun III (C) + rom_type = 1; + } +} + +void Mapper253::Write( WORD addr, BYTE data ) +{ + + DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF ); + + if( addr == 0x8010 ) { + SetPROM_8K_Bank( 4, data ); + return; + } + if( addr == 0xA010 ) { + SetPROM_8K_Bank( 5, data ); + return; + } + if( addr == 0x9400 ) { + data &= 0x03; + if( data == 0 ) SetVRAM_Mirror( VRAM_VMIRROR ); + else if( data == 1 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else if( data == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L ); + else SetVRAM_Mirror( VRAM_MIRROR4H ); + } + switch( addr & 0xF00C ) { + case 0xB000: + reg[0] = (reg[0] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 0, reg[0] ); + break; + case 0xB004: + reg[0] = (reg[0] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 0, reg[0] + ((data>>4)*0x100) ); + break; + case 0xB008: + reg[1] = (reg[1] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 1, reg[1] ); + break; + case 0xB00C: + reg[1] = (reg[1] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 1, reg[1] + ((data>>4)*0x100) ); + break; + case 0xC000: + reg[2] = (reg[2] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 2, reg[2] ); + break; + case 0xC004: + reg[2] = (reg[2] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 2, reg[2] + ((data>>4)*0x100) ); + break; + case 0xC008: + reg[3] = (reg[3] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 3, reg[3] ); + break; + case 0xC00C: + reg[3] = (reg[3] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 3, reg[3] + ((data>>4)*0x100) ); + break; + case 0xD000: + reg[4] = (reg[4] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 4, reg[4] ); + break; + case 0xD004: + reg[4] = (reg[4] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 4, reg[4] + ((data>>4)*0x100) ); + break; + case 0xD008: + reg[5] = (reg[5] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 5, reg[5] ); + break; + case 0xD00C: + reg[5] = (reg[5] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 5, reg[5] + ((data>>4)*0x100) ); + break; + case 0xE000: + reg[6] = (reg[6] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 6, reg[6] ); + break; + case 0xE004: + reg[6] = (reg[6] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 6, reg[6] + ((data>>4)*0x100) ); + break; + case 0xE008: + reg[7] = (reg[7] & 0xF0) | (data & 0x0F); + SetBank_PPUSUB( 7, reg[7] ); + break; + case 0xE00C: + reg[7] = (reg[7] & 0x0F) | ((data & 0x0F) << 4); + SetBank_PPUSUB( 7, reg[7] + ((data>>4)*0x100) ); + break; + case 0xF000: + irq_latch = (irq_latch & 0xF0) | (data & 0x0F); + break; + case 0xF004: + irq_latch = (irq_latch & 0x0F) | ((data & 0x0F) << 4); + break; + case 0xF008: + irq_enable = data & 0x03; + if( irq_enable & 0x02 ) { + irq_counter = irq_latch; + irq_clock = 0; + } + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper253::SetBank_PPUSUB( int bank, int page ) +{ + if(rom_type == 1){ + if(page == 0x88){ + VRAM_switch = 0; + return; + }else if(page == 0xc8){ + VRAM_switch = 1; + return; + } + } + if( (page == 4) || (page == 5) ) { + if( (VRAM_switch==0)&&(rom_type==1) ){ + SetVROM_1K_Bank( bank, page ); + } else { + SetCRAM_1K_Bank( bank, page ); + } + } else { + SetVROM_1K_Bank( bank, page ); + } +} + +void Mapper253::Clock( INT cycles ) +{ + if( irq_enable & 0x02 ) { + if( (irq_clock+=cycles) >= 0x72 ) { + irq_clock -= 0x72; + if( irq_counter == 0xFF ) { + irq_counter = irq_latch; + irq_enable = (irq_enable & 0x01) * 3; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } else { + irq_counter++; + } + } + } +} + +void Mapper253::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + p[i] = reg[i]; + } + p[ 9] = irq_enable; + p[10] = irq_counter; + p[11] = irq_latch; + *(INT*)&p[12] = irq_clock; +} + +void Mapper253::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 9; i++ ) { + reg[i] = p[i]; + } + irq_enable = p[ 9]; + irq_counter = p[10]; + irq_latch = p[11]; + irq_clock = *(INT*)&p[12]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper253.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper253.h new file mode 100644 index 00000000..75f6a5e7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper253.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper253 // +////////////////////////////////////////////////////////////////////////// +class Mapper253 : public Mapper +{ +public: + Mapper253( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + + void Clock( INT cycles ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE VRAM_switch; + BYTE rom_type; + BYTE reg[9]; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + INT irq_clock; +private: + void SetBank_PPUSUB( int bank, int page ); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper254.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper254.cpp new file mode 100644 index 00000000..01e61351 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper254.cpp @@ -0,0 +1,247 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper254 Pokemon Pirate Cart // +////////////////////////////////////////////////////////////////////////// +void Mapper254::Reset() +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = 0x00; + } + + protectflag = 0; + + prg0 = 0; + prg1 = 1; + SetBank_CPU(); + + chr01 = 0; + chr23 = 2; + chr4 = 4; + chr5 = 5; + chr6 = 6; + chr7 = 7; + SetBank_PPU(); + + irq_enable = 0; // Disable + irq_counter = 0; + irq_latch = 0; + irq_request = 0; +} + +void Mapper254::WriteLow( WORD addr, BYTE data ) +{ + switch( addr & 0xF000 ) { + case 0x6000: + case 0x7000: + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; + break; + } + +} +BYTE Mapper254::ReadLow( WORD addr ) +{ + if( addr>=0x6000 ) { + if( protectflag ) { + return (CPU_MEM_BANK[addr>>13][addr&0x1FFF]); + } else { + return ((CPU_MEM_BANK[addr>>13][addr&0x1FFF])^0x1); + } + } + return Mapper::ReadLow( addr ); +} + +void Mapper254::Write( WORD addr, BYTE data ) +{ + switch( addr & 0xE001 ) { + case 0x8000: + protectflag=0xFF; + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch( reg[0] & 0x07 ) { + case 0x00: + chr01 = data & 0xFE; + SetBank_PPU(); + break; + case 0x01: + chr23 = data & 0xFE; + SetBank_PPU(); + break; + case 0x02: + chr4 = data; + SetBank_PPU(); + break; + case 0x03: + chr5 = data; + SetBank_PPU(); + break; + case 0x04: + chr6 = data; + SetBank_PPU(); + break; + case 0x05: + chr7 = data; + SetBank_PPU(); + break; + case 0x06: + prg0 = data; + SetBank_CPU(); + break; + case 0x07: + prg1 = data; + SetBank_CPU(); + break; + } + break; + case 0xA000: + reg[2] = data; + if( !nes->rom->Is4SCREEN() ) { + if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + } + break; + case 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + nes->cpu->ClrIRQ( IRQ_MAPPER ); + break; + } +} + +void Mapper254::Clock( INT cycles ) +{ +// if( irq_request && (nes->GetIrqType() == NES::IRQ_CLOCK) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper254::HSync( INT scanline ) +{ + if( (scanline >= 0 && scanline <= 239) ) { + if( nes->ppu->IsDispON() ) { + if( irq_enable && !irq_request ) { + if( scanline == 0 ) { + if( irq_counter ) { + irq_counter--; + } + } + if( !(irq_counter--) ) { + irq_request = 0xFF; + irq_counter = irq_latch; + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + } + } +// if( irq_request && (nes->GetIrqType() == NES::IRQ_HSYNC) ) { +// nes->cpu->IRQ_NotPending(); +// } +} + +void Mapper254::SetBank_CPU() +{ + if( reg[0] & 0x40 ) { + SetPROM_32K_Bank( PROM_8K_SIZE-2, prg1, prg0, PROM_8K_SIZE-1 ); + } else { + SetPROM_32K_Bank( prg0, prg1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 ); + } +} + +void Mapper254::SetBank_PPU() +{ + + if( VROM_1K_SIZE ) { + if( reg[0] & 0x80 ) { + SetVROM_8K_Bank( chr4, chr5, chr6, chr7, + chr01, chr01+1, chr23, chr23+1 ); + } else { + SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1, + chr4, chr5, chr6, chr7 ); + } + } else { + if( reg[0] & 0x80 ) { + SetCRAM_1K_Bank( 4, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 5, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 6, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 7, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 0, chr4&0x07 ); + SetCRAM_1K_Bank( 1, chr5&0x07 ); + SetCRAM_1K_Bank( 2, chr6&0x07 ); + SetCRAM_1K_Bank( 3, chr7&0x07 ); + } else { + SetCRAM_1K_Bank( 0, (chr01+0)&0x07 ); + SetCRAM_1K_Bank( 1, (chr01+1)&0x07 ); + SetCRAM_1K_Bank( 2, (chr23+0)&0x07 ); + SetCRAM_1K_Bank( 3, (chr23+1)&0x07 ); + SetCRAM_1K_Bank( 4, chr4&0x07 ); + SetCRAM_1K_Bank( 5, chr5&0x07 ); + SetCRAM_1K_Bank( 6, chr6&0x07 ); + SetCRAM_1K_Bank( 7, chr7&0x07 ); + } + } +} + +void Mapper254::SaveState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + p[i] = reg[i]; + } + p[ 8] = prg0; + p[ 9] = prg1; + p[10] = chr01; + p[11] = chr23; + p[12] = chr4; + p[13] = chr5; + p[14] = chr6; + p[15] = chr7; + p[16] = irq_enable; + p[17] = irq_counter; + p[18] = irq_latch; + p[19] = irq_request; + p[20] = protectflag; +} + +void Mapper254::LoadState( LPBYTE p ) +{ + for( INT i = 0; i < 8; i++ ) { + reg[i] = p[i]; + } + prg0 = p[ 8]; + prg1 = p[ 9]; + chr01 = p[10]; + chr23 = p[11]; + chr4 = p[12]; + chr5 = p[13]; + chr6 = p[14]; + chr7 = p[15]; + irq_enable = p[16]; + irq_counter = p[17]; + irq_latch = p[18]; + irq_request = p[19]; + protectflag = p[20]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper254.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper254.h new file mode 100644 index 00000000..7017348a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper254.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper254 Pokemon Pirate Cart // +////////////////////////////////////////////////////////////////////////// +class Mapper254 : public Mapper +{ +public: + Mapper254( NES* parent ) : Mapper(parent) {} + + void Reset(); + void Write( WORD addr, BYTE data ); + BYTE ReadLow( WORD addr ); + void WriteLow(WORD addr, BYTE data); + + void Clock( INT cycles ); + void HSync( INT scanline ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[8]; + BYTE prg0, prg1; + BYTE chr01, chr23, chr4, chr5, chr6, chr7; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + BYTE protectflag; + +private: + void SetBank_CPU(); + void SetBank_PPU(); +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper255.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper255.cpp new file mode 100644 index 00000000..220402f3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper255.cpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper255 110-in-1 // +////////////////////////////////////////////////////////////////////////// +void Mapper255::Reset() +{ + SetPROM_32K_Bank( 0 ); + SetVROM_8K_Bank( 0 ); + SetVRAM_Mirror( VRAM_VMIRROR ); + + reg[0] = 0; + reg[1] = 0; + reg[2] = 0; + reg[3] = 0; +} + +BYTE Mapper255::ReadLow( WORD addr, BYTE data ) +{ + if( addr >= 0x5800 ) { + return reg[addr&0x0003] & 0x0F; + } else { + return addr>>8; + } +} + +void Mapper255::WriteLow( WORD addr, BYTE data ) +{ + if( addr >= 0x5800 ) { + reg[addr&0x0003] = data & 0x0F; + } +} + +void Mapper255::Write( WORD addr, BYTE data ) +{ + BYTE prg = (addr & 0x0F80)>>7; + INT chr = (addr & 0x003F); + INT bank = (addr & 0x4000)>>14; + + if( addr & 0x2000 ) { + SetVRAM_Mirror( VRAM_HMIRROR ); + } else { + SetVRAM_Mirror( VRAM_VMIRROR ); + } + + if( addr & 0x1000 ) { + if( addr & 0x0040 ) { + SetPROM_8K_Bank( 4, 0x80*bank+prg*4+2 ); + SetPROM_8K_Bank( 5, 0x80*bank+prg*4+3 ); + SetPROM_8K_Bank( 6, 0x80*bank+prg*4+2 ); + SetPROM_8K_Bank( 7, 0x80*bank+prg*4+3 ); + } else { + SetPROM_8K_Bank( 4, 0x80*bank+prg*4+0 ); + SetPROM_8K_Bank( 5, 0x80*bank+prg*4+1 ); + SetPROM_8K_Bank( 6, 0x80*bank+prg*4+0 ); + SetPROM_8K_Bank( 7, 0x80*bank+prg*4+1 ); + } + } else { + SetPROM_8K_Bank( 4, 0x80*bank+prg*4+0 ); + SetPROM_8K_Bank( 5, 0x80*bank+prg*4+1 ); + SetPROM_8K_Bank( 6, 0x80*bank+prg*4+2 ); + SetPROM_8K_Bank( 7, 0x80*bank+prg*4+3 ); + } + + SetVROM_1K_Bank( 0, 0x200*bank+chr*8+0 ); + SetVROM_1K_Bank( 1, 0x200*bank+chr*8+1 ); + SetVROM_1K_Bank( 2, 0x200*bank+chr*8+2 ); + SetVROM_1K_Bank( 3, 0x200*bank+chr*8+3 ); + SetVROM_1K_Bank( 4, 0x200*bank+chr*8+4 ); + SetVROM_1K_Bank( 5, 0x200*bank+chr*8+5 ); + SetVROM_1K_Bank( 6, 0x200*bank+chr*8+6 ); + SetVROM_1K_Bank( 7, 0x200*bank+chr*8+7 ); +} + +void Mapper255::SaveState( LPBYTE p ) +{ + p[ 0] = reg[0]; + p[ 1] = reg[1]; + p[ 2] = reg[2]; + p[ 3] = reg[3]; +} + +void Mapper255::LoadState( LPBYTE p ) +{ + reg[0] = p[ 0]; + reg[1] = p[ 1]; + reg[2] = p[ 2]; + reg[3] = p[ 3]; +} diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/Mapper255.h b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper255.h new file mode 100644 index 00000000..a16b7cfa --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/Mapper255.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper255 110-in-1 // +////////////////////////////////////////////////////////////////////////// +class Mapper255 : public Mapper +{ +public: + Mapper255( NES* parent ) : Mapper(parent) {} + + void Reset(); + BYTE ReadLow( WORD addr, BYTE data ); + void WriteLow( WORD addr, BYTE data ); + void Write( WORD addr, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + +protected: + BYTE reg[4]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/MapperFDS.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/MapperFDS.cpp new file mode 100644 index 00000000..5441ebb3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/MapperFDS.cpp @@ -0,0 +1,596 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper020 Nintendo Disk System(FDS) // +////////////////////////////////////////////////////////////////////////// +void Mapper020::Reset() +{ + irq_type = 0; + + irq_enable = irq_repeat = 0; + irq_counter = irq_latch = 0; + irq_occur = 0; + irq_transfer = 0; + + disk_enable = 0xFF; + sound_enable = 0xFF; + + block_point = 0; + block_mode = 0; + RW_start = 0xFF; + size_file_data = 0; + file_amount = 0; + point = 0; + first_access = 0; + + disk_eject = 0xFF; + drive_ready = 0; + + disk_side = 0xFF; // Eject + disk = disk_w = NULL; + + // Mechanical sound + sound_startup_flag = 0xFF; + sound_startup_timer = -1; // stop + sound_seekend_timer = -1; // stop + MechanicalSound( MECHANICAL_SOUND_ALLSTOP ); + +// ::memset( DRAM, 0xFF, sizeof(DRAM) ); + SetPROM_Bank( 3, DRAM+0x0000, BANKTYPE_DRAM ); + SetPROM_Bank( 4, DRAM+0x2000, BANKTYPE_DRAM ); + SetPROM_Bank( 5, DRAM+0x4000, BANKTYPE_DRAM ); + SetPROM_Bank( 6, DRAM+0x6000, BANKTYPE_DRAM ); + SetPROM_Bank( 7, nes->rom->GetDISKBIOS(), BANKTYPE_ROM ); + SetCRAM_8K_Bank( 0 ); + + // ftHg +// nes->SetIrqType( NES::IRQ_HSYNC ); + + // AĂ}IuU[Y + if( nes->rom->GetMakerID() == 0x01 && nes->rom->GetGameID() == 0x4b4d4152 ) { + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + + // KtH[X + if( nes->rom->GetMakerID() == 0xB6 && nes->rom->GetGameID() == 0x47414C20 ) { + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + // t@CA[o + if( nes->rom->GetMakerID() == 0xB6 && nes->rom->GetGameID() == 0x46424D20 ) { + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + // Rczbg[ + if( nes->rom->GetMakerID() == 0x01 && nes->rom->GetGameID() == 0x54445245 ) { + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + irq_type = 1; // C`L + } + // ^CcCXg + if( nes->rom->GetMakerID() == 0x01 && nes->rom->GetGameID() == 0x54540120 ) { + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + // oCI~NڂăEp + if( nes->rom->GetMakerID() == 0xA4 && nes->rom->GetGameID() == 0x424F4B20 ) { + nes->SetRenderMethod( NES::PRE_ALL_RENDER ); + } + +DEBUGOUT( "MAKER ID=%02X\n", nes->rom->GetMakerID() ); +DEBUGOUT( "GAME ID=%08X\n", nes->rom->GetGameID() ); + + nes->apu->SelectExSound( 4 ); + +// ExCmdWrite( EXCMDWR_DISKINSERT, 0 ); + // Disk 0, Side AZbg + disk = nes->rom->GetPROM()+16+65500*0; + disk_w = nes->rom->GetDISK()+16+65500*0; + + disk_side = 0; + disk_eject = 0xFF; + drive_ready = 0; + disk_mount_count = 119; + + nes->Command( NES::NESCMD_DISK_THROTTLE_OFF ); + + bDiskThrottle = FALSE; + DiskThrottleTime = 0; +} + +BYTE Mapper020::ExRead( WORD addr ) +{ +BYTE data = addr>>8; + + switch( addr ) { + case 0x4030: // Disk I/O status + data = 0x80; + data |= (irq_occur && !irq_transfer)?0x01:0x00; + data |= (irq_occur && irq_transfer)?0x02:0x00; + irq_occur = 0; + + // Clear Timer IRQ + nes->cpu->ClrIRQ( IRQ_MAPPER ); + // Clear Disk IRQ + nes->cpu->ClrIRQ( IRQ_MAPPER2 ); + break; + case 0x4031: // Disk data read + if( !RW_mode ) + return 0xFF; + + first_access = 0; + + if( disk ) { + switch( block_mode ) { + case BLOCK_VOLUME_LABEL: + data = disk[block_point]; + if( block_point < SIZE_VOLUME_LABEL ) { + block_point++; + } else { + data = 0; + } + return data; + case BLOCK_FILE_AMOUNT: + data = disk[ block_point + point ]; + if( block_point < SIZE_FILE_AMOUNT ) { + block_point++; + file_amount = data; + } else { + data = 0; + } + return data; + case BLOCK_FILE_HEADER: + data = disk[ block_point + point ]; + if( block_point == 13 ) + size_file_data = data; + else if( block_point == 14 ) + size_file_data += ((INT)data<<8); + + if( block_point < SIZE_FILE_HEADER ) { + block_point++; + } else { + data = 0; + } + return data; + case BLOCK_FILE_DATA: + data = disk[ block_point + point ]; + if( block_point < size_file_data + 1 ) { + block_point++; + } else { + data = 0; + } + return data; + } + } else { + return 0xFF; + } + break; + case 0x4032: // Disk status + data = 0x40; + data |= disk_eject?0x01:0x00; + data |= disk_eject?0x04:0x00; + data |= (!disk_eject && disk_motor_mode && !drive_reset)?0x00:0x02; + break; + case 0x4033: // External connector data/Battery sense + data = 0x80; + break; + default: + if( addr >= 0x4040 ) + data = nes->apu->ExRead( addr ); + break; + } + + return data; +} + +void Mapper020::ExWrite( WORD addr, BYTE data ) +{ + switch( addr ) { + case 0x4020: // IRQ latch low + irq_latch = (irq_latch&0xFF00)|data; + break; + case 0x4021: // IRQ latch high + irq_latch = (irq_latch&0x00FF)|((WORD)data<<8); + break; + case 0x4022: // IRQ control + irq_repeat = data & 0x01; + irq_enable = (data & 0x02) && (disk_enable); + irq_occur = 0; + if( irq_enable ) { + irq_counter = irq_latch; + } else { + // Clear Timer IRQ + nes->cpu->ClrIRQ( IRQ_MAPPER ); + } + break; + + case 0x4023: // 2C33 control + disk_enable = data & 0x01; + if( !disk_enable ) { + irq_enable = 0; + irq_occur = 0; + // Clear Timer IRQ + nes->cpu->ClrIRQ( IRQ_MAPPER ); + // Clear Disk IRQ + nes->cpu->ClrIRQ( IRQ_MAPPER2 ); + } + + break; + + case 0x4024: // Data write + // Clear Disk IRQ + nes->cpu->ClrIRQ( IRQ_MAPPER2 ); + + if( RW_mode ) + break; + + if( first_access ) { + first_access = 0; + break; + } + + if( disk ) { + switch( block_mode ) { + case BLOCK_VOLUME_LABEL: + if( block_point < SIZE_VOLUME_LABEL-1 ) { + disk[ block_point ] = data; + disk_w[ block_point ] = 0xFF; + block_point++; + } + break; + case BLOCK_FILE_AMOUNT: + if( block_point < SIZE_FILE_AMOUNT ) { + disk[ block_point + point ] = data; + disk_w[ block_point + point ] = 0xFF; + block_point++; + } + break; + case BLOCK_FILE_HEADER: + if( block_point < SIZE_FILE_HEADER ) { + disk[ block_point + point ] = data; + disk_w[ block_point + point ] = 0xFF; + if( block_point == 13 ) + size_file_data = data; + else if( block_point == 14 ) + size_file_data |= data << 8; + block_point++; + } + break; + case BLOCK_FILE_DATA: + if( block_point < size_file_data+1 ) { + disk[ block_point + point ] = data; + disk_w[ block_point + point ] = 0xFF; + block_point++; + } + break; + } + } + break; + + case 0x4025: // Disk I/O control + // 荞ݓ] + irq_transfer = data & 0x80; + if( !irq_transfer ) { + nes->cpu->ClrIRQ( IRQ_MAPPER2 ); + } + + if( !RW_start && (data & 0x40) ) { + block_point = 0; + switch( block_mode ) { + case BLOCK_READY: + block_mode = BLOCK_VOLUME_LABEL; + point = 0; + break; + case BLOCK_VOLUME_LABEL: + block_mode = BLOCK_FILE_AMOUNT; + point += SIZE_VOLUME_LABEL; + break; + case BLOCK_FILE_AMOUNT: + block_mode = BLOCK_FILE_HEADER; + point += SIZE_FILE_AMOUNT; + break; + case BLOCK_FILE_HEADER: + block_mode = BLOCK_FILE_DATA; + point += SIZE_FILE_HEADER; + break; + case BLOCK_FILE_DATA: + block_mode = BLOCK_FILE_HEADER; + point += size_file_data+1; + break; + } + + // ŏ̂Pڂ݂̏𖳎邽 + first_access = 0xFF; + } + + // ǂݏX^[g + RW_start = data & 0x40; + + // ǂݏ[h + RW_mode = data & 0x04; + + // ǂݏ̃Zbg + if( data&0x02 ) { + point = 0; + block_point = 0; + block_mode = BLOCK_READY; + RW_start = 0xFF; + drive_reset = 0xFF; + + sound_startup_flag = 0; + sound_startup_timer = -1; // stop + } else { + drive_reset = 0; + + if( !sound_startup_flag ) { + MechanicalSound( MECHANICAL_SOUND_MOTOR_ON ); + sound_startup_flag = 0xFF; + sound_startup_timer = 40; + sound_seekend_timer = 60*7; + } + } + + // fBXN[^[̃Rg[ + disk_motor_mode = data & 0x01; + if( !(data & 0x01) ) { + if( sound_seekend_timer >= 0 ) { + sound_seekend_timer = -1; + MechanicalSound( MECHANICAL_SOUND_MOTOR_OFF ); + } + } + + // Mirror + if( data&0x08 ) SetVRAM_Mirror( VRAM_HMIRROR ); + else SetVRAM_Mirror( VRAM_VMIRROR ); + break; + + case 0x4026: // External connector output/Battery sense + break; + default: + if( addr >= 0x4040 ) + nes->apu->ExWrite( addr, data ); + break; + } +} + +void Mapper020::WriteLow( WORD addr, BYTE data ) +{ + DRAM[addr-0x6000] = data; +} + +void Mapper020::Write( WORD addr, BYTE data ) +{ + if( addr < 0xE000 ) { + DRAM[addr-0x6000] = data; + } +} + +void Mapper020::Clock( INT cycles ) +{ + // Timer IRQ + if( irq_enable ) { + if( !irq_type ) { + irq_counter -= cycles; + } + if( irq_counter <= 0 ) { +//// irq_counter &= 0xFFFF; + irq_counter += irq_latch; + + if( !irq_occur ) { + irq_occur = 0xFF; + if( !irq_repeat ) { + irq_enable = 0; + } + nes->cpu->SetIRQ( IRQ_MAPPER ); + } + } + if( irq_type ) { + irq_counter -= cycles; + } + } +} + +void Mapper020::HSync( INT scanline ) +{ + // Disk IRQ + if( irq_transfer ) { + nes->cpu->SetIRQ( IRQ_MAPPER2 ); + } +} + +void Mapper020::VSync() +{ + if( disk && disk_eject ) { + if( disk_mount_count > 120 ) { + disk_eject = 0; + } else { + disk_mount_count++; + } + } + +// if( disk && (disk_mount_count > 120) ) { + if( disk ) { + if( sound_startup_timer > 0 ) { + sound_startup_timer--; + } else if( sound_startup_timer == 0 ) { + sound_startup_timer--; + MechanicalSound( MECHANICAL_SOUND_BOOT ); + } + + if( sound_seekend_timer > 0 ) { + sound_seekend_timer--; + } else if( sound_seekend_timer == 0 ) { + sound_seekend_timer--; + MechanicalSound( MECHANICAL_SOUND_MOTOR_OFF ); + MechanicalSound( MECHANICAL_SOUND_SEEKEND ); + sound_startup_flag = 0; + } + } + + if( irq_transfer || (disk && disk_mount_count < 120) ) { + if( DiskThrottleTime > 2 ) { + bDiskThrottle = TRUE; + } else { + bDiskThrottle = FALSE; + DiskThrottleTime++; + } + } else { + DiskThrottleTime = 0; + bDiskThrottle = FALSE; + } + if( !bDiskThrottle ) { + nes->Command( NES::NESCMD_DISK_THROTTLE_OFF ); + } else { + nes->Command( NES::NESCMD_DISK_THROTTLE_ON ); + } +} + +BYTE Mapper020::ExCmdRead( EXCMDRD cmd ) +{ +BYTE data = 0x00; + + if( cmd == EXCMDRD_DISKACCESS ) { + if( irq_transfer ) + return 0xFF; + } + + return data; +} + +void Mapper020::ExCmdWrite( EXCMDWR cmd, BYTE data ) +{ + switch( cmd ) { + case EXCMDWR_NONE: + break; + case EXCMDWR_DISKINSERT: + disk = nes->rom->GetPROM()+16+65500*data; + disk_w = nes->rom->GetDISK()+16+65500*data; + disk_side = data; + disk_eject = 0xFF; + drive_ready = 0; + disk_mount_count = 0; + break; + case EXCMDWR_DISKEJECT: + disk = NULL; // Ƃ肠 + disk_w = NULL; + disk_side = 0xFF; + disk_eject = 0xFF; + drive_ready = 0; + disk_mount_count = 0; + break; + } +} + +void Mapper020::MechanicalSound( INT type ) +{ + switch( type ) { + case MECHANICAL_SOUND_BOOT: + // Head start point CAM sound. + if( Config.sound.bExtraSoundEnable ) + DirectSound.EsfPlay( ESF_DISKSYSTEM_BOOT ); + break; + case MECHANICAL_SOUND_SEEKEND: + if( Config.sound.bExtraSoundEnable ) + DirectSound.EsfPlay( ESF_DISKSYSTEM_SEEKEND ); + // Reset or Seekend sound. + break; + case MECHANICAL_SOUND_MOTOR_ON: + if( Config.sound.bExtraSoundEnable ) + DirectSound.EsfPlayLoop( ESF_DISKSYSTEM_MOTOR ); + // Start Motor sound.(loop) + break; + case MECHANICAL_SOUND_MOTOR_OFF: + DirectSound.EsfStop( ESF_DISKSYSTEM_MOTOR ); + // Stop Motor sound.(loop) + break; + case MECHANICAL_SOUND_ALLSTOP: + // Stop sound. + DirectSound.EsfAllStop(); + break; + default: + break; + } +} + +void Mapper020::SaveState( LPBYTE p ) +{ + p[0] = irq_enable; + p[1] = irq_repeat; + p[2] = irq_occur; + p[3] = irq_transfer; + + *(INT*)&p[4] = irq_counter; + *(INT*)&p[8] = irq_latch; + + p[12] = disk_enable; + p[13] = sound_enable; + p[14] = RW_start; + p[15] = RW_mode; + p[16] = disk_motor_mode; + p[17] = disk_eject; + p[18] = drive_ready; + p[19] = drive_reset; + + *(INT*)&p[20] = block_point; + *(INT*)&p[24] = block_mode; + *(INT*)&p[28] = size_file_data; + *(INT*)&p[32] = file_amount; + *(INT*)&p[36] = point; + + p[40] = first_access; + p[41] = disk_side; + p[42] = disk_mount_count; + + p[44] = sound_startup_flag; + *(INT*)&p[48] = sound_startup_timer; + *(INT*)&p[52] = sound_seekend_timer; +} + +void Mapper020::LoadState( LPBYTE p ) +{ + irq_enable = p[0]; + irq_repeat = p[1]; + irq_occur = p[2]; + irq_transfer = p[3]; + + irq_counter = *(INT*)&p[4]; + irq_latch = *(INT*)&p[8]; + + disk_enable = p[12]; + sound_enable = p[13]; + RW_start = p[14]; + RW_mode = p[15]; + disk_motor_mode = p[16]; + disk_eject = p[17]; + drive_ready = p[18]; + drive_reset = p[19]; + + block_point = *(INT*)&p[20]; + block_mode = *(INT*)&p[24]; + size_file_data = *(INT*)&p[28]; + file_amount = *(INT*)&p[32]; + point = *(INT*)&p[36]; + + first_access = p[40]; + disk_side = p[41]; + disk_mount_count= p[42]; + + sound_startup_flag = p[44]; + sound_startup_timer = *(INT*)&p[48]; + sound_seekend_timer = *(INT*)&p[52]; + + if( disk_side != 0xFF ) { + disk = nes->rom->GetPROM()+sizeof(NESHEADER)+65500*disk_side; + disk_w = nes->rom->GetDISK()+sizeof(NESHEADER)+65500*disk_side; + } else { + disk = NULL; + disk_w = NULL; + } + + // DiskBios Setup(Xe[gŏ㏑Ă) + SetPROM_Bank( 7, nes->rom->GetDISKBIOS(), BANKTYPE_ROM ); +} + +void Mapper020::PPU_Latch( WORD addr ) +{ + if(DirectInput.m_Sw[DIK_PAUSE]){ + nes->Dump_CPULMEM(); + nes->Dump_CPUHMEM(); + nes->Dump_CRAM(); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/MapperFDS.h b/References/VirtuaNESex_src_191105/NES/Mapper/MapperFDS.h new file mode 100644 index 00000000..d9429260 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/MapperFDS.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper020 Nintendo Disk System(FDS) // +////////////////////////////////////////////////////////////////////////// +class Mapper020 : public Mapper +{ +public: + Mapper020( NES* parent ) : Mapper(parent) {} + + void Reset(); + + BYTE ExRead ( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + + void WriteLow( WORD addr, BYTE data ); + + void Write(WORD addr, BYTE data); + + void Clock( INT cycles ); + void HSync( INT scanline ); + void VSync(); + + BYTE ExCmdRead ( EXCMDRD cmd ); + void ExCmdWrite( EXCMDWR cmd, BYTE data ); + + // For state save + BOOL IsStateSave() { return TRUE; } + void SaveState( LPBYTE p ); + void LoadState( LPBYTE p ); + + void PPU_Latch( WORD addr ); + +protected: + enum { + BLOCK_READY = 0, + BLOCK_VOLUME_LABEL, + BLOCK_FILE_AMOUNT, + BLOCK_FILE_HEADER, + BLOCK_FILE_DATA, + }; + enum { + SIZE_VOLUME_LABEL = 56, + SIZE_FILE_AMOUNT = 2, + SIZE_FILE_HEADER = 16, + }; + enum { + OFFSET_VOLUME_LABEL = 0, + OFFSET_FILE_AMOUNT = 56, + OFFSET_FILE_HEADER = 58, + OFFSET_FILE_DATA = 74, + }; + + enum { + MECHANICAL_SOUND_BOOT = 0, + MECHANICAL_SOUND_SEEKEND, + MECHANICAL_SOUND_MOTOR_ON, + MECHANICAL_SOUND_MOTOR_OFF, + MECHANICAL_SOUND_ALLSTOP, + }; + + BOOL bDiskThrottle; + INT DiskThrottleTime; + + LPBYTE disk; + LPBYTE disk_w; + + INT irq_counter, irq_latch; // $4020-$4021 + BYTE irq_enable, irq_repeat; // $4022 + BYTE irq_occur; // IRQ0ȊOɂȂ + BYTE irq_transfer; // 荞ݓ]tO + + BYTE disk_enable; // Disk I/O enable + BYTE sound_enable; // Sound I/O enable + BYTE RW_start; // ǂݏ”\ɂȂIRQ + BYTE RW_mode; // ǂݏ[h + BYTE disk_motor_mode; // fBXN[^[ + BYTE disk_eject; // fBXNJ[h̑}/} + BYTE drive_ready; // ǂݏǂ + BYTE drive_reset; // hCuZbg + + INT block_point; + INT block_mode; + INT size_file_data; + INT file_amount; + INT point; + BYTE first_access; + + BYTE disk_side; + BYTE disk_mount_count; + + BYTE irq_type; + + // For mechanical sound + BYTE sound_startup_flag; + INT sound_startup_timer; + INT sound_seekend_timer; + + void MechanicalSound( INT type ); + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/MapperFactory.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/MapperFactory.cpp new file mode 100644 index 00000000..28b12ec9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/MapperFactory.cpp @@ -0,0 +1,893 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* NES Mapeers Factory */ +/* Norix */ +/* written 2003/09/04 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "DebugOut.h" +#include "typedef.h" +#include "macro.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "pad.h" +#include "rom.h" + +#include "mapper.h" + +#include "Config.h" + +////////////////////////////////////////////////////////////////////////// +#include "Mapper000.h" +#include "Mapper001.h" +#include "Mapper002.h" +#include "Mapper003.h" +#include "Mapper004.h" +#include "Mapper005.h" +#include "Mapper006.h" +#include "Mapper007.h" +#include "Mapper008.h" +#include "Mapper009.h" +#include "Mapper010.h" +#include "Mapper011.h" +#include "Mapper013.h" +#include "Mapper015.h" +#include "Mapper016.h" +#include "Mapper017.h" +#include "Mapper018.h" +#include "Mapper019.h" +#include "MapperFDS.h" // 020 +#include "Mapper021.h" +#include "Mapper022.h" +#include "Mapper023.h" +#include "Mapper024.h" +#include "Mapper025.h" +#include "Mapper026.h" +#include "Mapper032.h" +#include "Mapper033.h" +#include "Mapper034.h" +#include "Mapper040.h" +#include "Mapper041.h" +#include "Mapper042.h" +#include "Mapper043.h" +#include "Mapper048.h" +#include "Mapper064.h" +#include "Mapper065.h" +#include "Mapper066.h" +#include "Mapper067.h" +#include "Mapper068.h" +#include "Mapper069.h" +#include "Mapper070.h" +#include "Mapper071.h" +#include "Mapper072.h" +#include "Mapper073.h" +#include "Mapper075.h" +#include "Mapper076.h" +#include "Mapper077.h" +#include "Mapper078.h" +#include "Mapper079.h" +#include "Mapper080.h" +#include "Mapper082.h" +#include "Mapper083.h" +#include "Mapper085.h" +#include "Mapper086.h" +#include "Mapper087.h" +#include "Mapper088.h" +#include "Mapper089.h" +#include "Mapper090.h" +#include "Mapper091.h" +#include "Mapper092.h" +#include "Mapper093.h" +#include "Mapper094.h" +#include "Mapper095.h" +#include "Mapper096.h" +#include "Mapper097.h" +#include "Mapper100.h" +#include "Mapper101.h" +#include "Mapper107.h" +#include "Mapper113.h" +#include "Mapper118.h" +#include "Mapper119.h" +#include "Mapper122.h" +#include "Mapper180.h" +#include "Mapper181.h" +#include "Mapper185.h" +#include "Mapper187.h" +#include "Mapper188.h" +#include "Mapper189.h" +#include "Mapper243.h" + +#include "MapperNSF.h" + +#include "Mapper044.h" +#include "Mapper045.h" +#include "Mapper046.h" +#include "Mapper047.h" +#include "Mapper050.h" +#include "Mapper051.h" +#include "Mapper057.h" +#include "Mapper058.h" +#include "Mapper060.h" +#include "Mapper062.h" +#include "Mapper074.h" +#include "Mapper105.h" +#include "Mapper108.h" +#include "Mapper109.h" +#include "Mapper110.h" +#include "Mapper111.h" +#include "Mapper112.h" +#include "Mapper114.h" +#include "Mapper115.h" +#include "Mapper116.h" +#include "Mapper117.h" +#include "Mapper133.h" +#include "Mapper134.h" +#include "Mapper135.h" +#include "Mapper140.h" +#include "Mapper142.h" +#include "Mapper160.h" +#include "Mapper163.h" +#include "Mapper164.h" +#include "Mapper165.h" +#include "Mapper027.h" +#include "Mapper167.h" +#include "Mapper182.h" +#include "Mapper183.h" +#include "Mapper190.h" +#include "Mapper191.h" +#include "Mapper192.h" +#include "Mapper193.h" +#include "Mapper194.h" +#include "Mapper195.h" +#include "Mapper198.h" +#include "Mapper222.h" +#include "Mapper225.h" +#include "Mapper226.h" +#include "Mapper227.h" +#include "Mapper228.h" +#include "Mapper229.h" +#include "Mapper230.h" +#include "Mapper231.h" +#include "Mapper232.h" +#include "Mapper233.h" +#include "Mapper234.h" +#include "Mapper235.h" +#include "Mapper236.h" +#include "Mapper240.h" +#include "Mapper241.h" +#include "Mapper242.h" +#include "Mapper244.h" +#include "Mapper245.h" +#include "Mapper246.h" +#include "Mapper248.h" +#include "Mapper249.h" +#include "Mapper251.h" +#include "Mapper252.h" +#include "Mapper254.h" +#include "Mapper255.h" + +#include "Mapper099.h" +#include "Mapper151.h" + +#include "Mapper012.h" + +#include "Mapper200.h" +#include "Mapper201.h" +#include "Mapper202.h" + +#include "Mapper061.h" + +#include "Mapper148.h" +#include "Mapper150.h" +#include "Mapper132.h" +#include "Mapper168.h" +#include "Mapper166.h" +#include "Mapper162.h" +#include "Mapper179.h" +#include "Mapper174.h" +#include "Mapper177.h" +#include "Mapper178.h" +#include "Mapper176.h" +#include "Mapper175.h" +#include "Mapper253.h" +#include "Mapper120.h" +#include "Mapper169.h" +#include "Mapper170.h" +#include "Mapper171.h" +#include "Mapper172.h" +#include "Mapper237.h" +#include "Mapper141.h" +#include "Mapper121.h" +#include "Mapper212.h" +#include "Mapper199.h" + +#include "Mapper049.h" +#include "Mapper052.h" +#include "Mapper173.h" + +#include "BoardSA9602B.h" +#include "BoardBS5.h" +#include "BoardCityFighter.h" +#include "BoardCoolBoy.h" +#include "BoardFK23C.h" +#include "BoardDragonFighter.h" +#include "BoardYoko.h" +#include "BoardOneBus.h" +#include "BoardMGC002.h" +#include "BoardKS7010.h" +#include "BoardUNL158B.h" +#include "BoardKS7030.h" +#include "BoardTH21311.h" +#include "BoardUNL831128C.h" +#include "BoardLB12IN1.h" + +////////////////////////////////////////////////////////////////////////// + +#include "Mapper000.cpp" +#include "Mapper001.cpp" +#include "Mapper002.cpp" +#include "Mapper003.cpp" +#include "Mapper004.cpp" +#include "Mapper005.cpp" +#include "Mapper006.cpp" +#include "Mapper007.cpp" +#include "Mapper008.cpp" +#include "Mapper009.cpp" +#include "Mapper010.cpp" +#include "Mapper011.cpp" +#include "Mapper013.cpp" +#include "Mapper015.cpp" +#include "Mapper016.cpp" +#include "Mapper017.cpp" +#include "Mapper018.cpp" +#include "Mapper019.cpp" +#include "MapperFDS.cpp" // 020 +#include "Mapper021.cpp" +#include "Mapper022.cpp" +#include "Mapper023.cpp" +#include "Mapper024.cpp" +#include "Mapper025.cpp" +#include "Mapper026.cpp" +#include "Mapper032.cpp" +#include "Mapper033.cpp" +#include "Mapper034.cpp" +#include "Mapper040.cpp" +#include "Mapper041.cpp" +#include "Mapper042.cpp" +#include "Mapper043.cpp" +#include "Mapper048.cpp" +#include "Mapper064.cpp" +#include "Mapper065.cpp" +#include "Mapper066.cpp" +#include "Mapper067.cpp" +#include "Mapper068.cpp" +#include "Mapper069.cpp" +#include "Mapper070.cpp" +#include "Mapper071.cpp" +#include "Mapper072.cpp" +#include "Mapper073.cpp" +#include "Mapper075.cpp" +#include "Mapper076.cpp" +#include "Mapper077.cpp" +#include "Mapper078.cpp" +#include "Mapper079.cpp" +#include "Mapper080.cpp" +#include "Mapper082.cpp" +#include "Mapper083.cpp" +#include "Mapper085.cpp" +#include "Mapper086.cpp" +#include "Mapper087.cpp" +#include "Mapper088.cpp" +#include "Mapper089.cpp" +#include "Mapper090.cpp" +#include "Mapper091.cpp" +#include "Mapper092.cpp" +#include "Mapper093.cpp" +#include "Mapper094.cpp" +#include "Mapper095.cpp" +#include "Mapper096.cpp" +#include "Mapper097.cpp" +#include "Mapper100.cpp" +#include "Mapper101.cpp" +#include "Mapper107.cpp" +#include "Mapper113.cpp" +#include "Mapper118.cpp" +#include "Mapper119.cpp" +#include "Mapper122.cpp" +#include "Mapper180.cpp" +#include "Mapper181.cpp" +#include "Mapper185.cpp" +#include "Mapper187.cpp" +#include "Mapper188.cpp" +#include "Mapper189.cpp" +#include "Mapper243.cpp" + +#include "MapperNSF.cpp" + +#include "Mapper044.cpp" +#include "Mapper045.cpp" +#include "Mapper046.cpp" +#include "Mapper047.cpp" +#include "Mapper050.cpp" +#include "Mapper051.cpp" +#include "Mapper057.cpp" +#include "Mapper058.cpp" +#include "Mapper060.cpp" +#include "Mapper062.cpp" +#include "Mapper074.cpp" +#include "Mapper105.cpp" +#include "Mapper108.cpp" +#include "Mapper109.cpp" +#include "Mapper110.cpp" +#include "Mapper111.cpp" +#include "Mapper112.cpp" +#include "Mapper114.cpp" +#include "Mapper115.cpp" +#include "Mapper116.cpp" +#include "Mapper117.cpp" +#include "Mapper133.cpp" +#include "Mapper134.cpp" +#include "Mapper135.cpp" +#include "Mapper140.cpp" +#include "Mapper142.cpp" +#include "Mapper160.cpp" +#include "Mapper163.cpp" +#include "Mapper164.cpp" +#include "Mapper165.cpp" +#include "Mapper027.cpp" +#include "Mapper167.cpp" +#include "Mapper182.cpp" +#include "Mapper183.cpp" +#include "Mapper190.cpp" +#include "Mapper191.cpp" +#include "Mapper192.cpp" +#include "Mapper193.cpp" +#include "Mapper194.cpp" +#include "Mapper195.cpp" +#include "Mapper198.cpp" +#include "Mapper222.cpp" +#include "Mapper225.cpp" +#include "Mapper226.cpp" +#include "Mapper227.cpp" +#include "Mapper228.cpp" +#include "Mapper229.cpp" +#include "Mapper230.cpp" +#include "Mapper231.cpp" +#include "Mapper232.cpp" +#include "Mapper233.cpp" +#include "Mapper234.cpp" +#include "Mapper235.cpp" +#include "Mapper236.cpp" +#include "Mapper240.cpp" +#include "Mapper241.cpp" +#include "Mapper242.cpp" +#include "Mapper244.cpp" +#include "Mapper245.cpp" +#include "Mapper246.cpp" +#include "Mapper248.cpp" +#include "Mapper249.cpp" +#include "Mapper251.cpp" +#include "Mapper252.cpp" +#include "Mapper254.cpp" +#include "Mapper255.cpp" + +#include "Mapper099.cpp" +#include "Mapper151.cpp" + +#include "Mapper012.cpp" + +#include "Mapper200.cpp" +#include "Mapper201.cpp" +#include "Mapper202.cpp" + +#include "Mapper061.cpp" + +#include "Mapper148.cpp" +#include "Mapper150.cpp" +#include "Mapper132.cpp" +#include "Mapper168.cpp" +#include "Mapper166.cpp" +#include "Mapper162.cpp" +#include "Mapper179.cpp" +#include "Mapper174.cpp" +#include "Mapper177.cpp" +#include "Mapper178.cpp" +#include "Mapper176.cpp" +#include "Mapper175.cpp" +#include "Mapper253.cpp" +#include "Mapper120.cpp" +#include "Mapper169.cpp" +#include "Mapper170.cpp" +#include "Mapper171.cpp" +#include "Mapper172.cpp" +#include "Mapper237.cpp" +#include "Mapper141.cpp" +#include "Mapper121.cpp" +#include "Mapper212.cpp" +#include "Mapper199.cpp" + +#include "Mapper049.cpp" +#include "Mapper052.cpp" +#include "Mapper173.cpp" + +#include "BoardSA9602B.cpp" +#include "BoardBS5.cpp" +#include "BoardCityFighter.cpp" +#include "BoardCoolBoy.cpp" +#include "BoardFK23C.cpp" +#include "BoardDragonFighter.cpp" +#include "BoardYoko.cpp" +#include "BoardOneBus.cpp" +#include "BoardMGC002.cpp" +#include "BoardKS7010.cpp" +#include "BoardUNL158B.cpp" +#include "BoardKS7030.cpp" +#include "BoardTH21311.cpp" +#include "BoardUNL831128C.cpp" +#include "BoardLB12IN1.cpp" + +extern BOOL g_bSan2; +////////////////////////////////////////////////////////////////////////// +// Mapper Factory +////////////////////////////////////////////////////////////////////////// + +#include "BoardMMC3.h" +#include "BoardMMC3.cpp" + +Mapper* CreateMapper( NES* parent, INT no,BOOL bUnif) +{ + + if( bUnif ) + { + switch(no) + { + case CHINA_ER_SAN2://־2-Ĵ½(ĺ)[&&һ] + g_bSan2 = TRUE; + return new Mapper019(parent); + case UNL_SA_9602B: + return new BoardSA9602B(parent); + case BENSHENG_BS5: + return new BoardBS5(parent); + case City_Fighter_IV: + return new BoardCityFighter(parent); + case BTL_6035052: + return new Mapper004(parent); + case COOLBOY: + return new BoardCoolBoy(parent); + case BMC_FK23C: + case BMC_FK23CA: + return new BoardFK23C(parent); + case Dragon_Fighter: + return new BoardDragonFighter(parent); + case UNL_YOKO: + case UNL_82112C: + return new BoardYoko(parent); + case OneBus: + return new BoardOneBus(parent); + case MGC_002: + return new BoardMGC002(parent); + case UNL_KS7010: + return new BoardKS7010(parent); + case UNL_KS7030: + return new BoardKS7030(parent); + case UNL_158B: + return new BoardUNL158B(parent); + case UNL_TH2131_1: + return new BoardTH21311(parent); + case UNL_831128C: + return new Board831128C(parent); + case BMC_LB12IN1: + return new BoardLB12IN1(parent); + + case FF3_CN: +// g_bSan2 = TRUE; + return new Mapper004(parent); + } + return NULL; + } + switch( no ) { + case 0: + return new Mapper000(parent); + case 1: + return new Mapper001(parent); + case 2: + return new Mapper002(parent); + case 3: + return new Mapper003(parent); + case 4: + return new Mapper004(parent); + case 5: + return new Mapper005(parent); + case 6: + return new Mapper006(parent); + case 7: + return new Mapper007(parent); + case 8: + return new Mapper008(parent); + case 9: + return new Mapper009(parent); + case 10: + return new Mapper010(parent); + case 11: + return new Mapper011(parent); + case 13: + return new Mapper013(parent); + case 15: + return new Mapper015(parent); + case 16: + return new Mapper016(parent); + case 17: + return new Mapper017(parent); + case 18: + return new Mapper018(parent); + case 19: + return new Mapper019(parent); + case 20: + return new Mapper020(parent); + case 21: + return new Mapper021(parent); + case 22: + return new Mapper022(parent); + case 23: + return new Mapper023(parent); + case 24: + return new Mapper024(parent); + case 25: + return new Mapper025(parent); + case 26: + return new Mapper026(parent); + case 32: + return new Mapper032(parent); + case 33: + return new Mapper033(parent); + case 34: + return new Mapper034(parent); + case 40: + return new Mapper040(parent); + case 41: + return new Mapper041(parent); + case 42: + return new Mapper042(parent); + case 43: + return new Mapper043(parent); + case 48: + return new Mapper048(parent); + case 64: + return new Mapper064(parent); + case 65: + return new Mapper065(parent); + case 66: + return new Mapper066(parent); + case 67: + return new Mapper067(parent); + case 68: + return new Mapper068(parent); + case 69: + return new Mapper069(parent); + case 70: + return new Mapper070(parent); + case 71: + return new Mapper071(parent); + case 72: + return new Mapper072(parent); + case 73: + return new Mapper073(parent); + case 75: + return new Mapper075(parent); + case 76: + return new Mapper076(parent); + case 77: + return new Mapper077(parent); + case 78: + return new Mapper078(parent); + case 79: + return new Mapper079(parent); + case 80: + return new Mapper080(parent); + case 82: + return new Mapper082(parent); + case 83: + return new Mapper083(parent); + case 85: + return new Mapper085(parent); + case 86: + return new Mapper086(parent); + case 87: + return new Mapper087(parent); + case 88: + return new Mapper088(parent); + case 89: + return new Mapper089(parent); + case 90: + return new Mapper090(parent); + case 91: + return new Mapper091(parent); + case 92: + return new Mapper092(parent); + case 93: + return new Mapper093(parent); + case 94: + return new Mapper094(parent); + case 95: + return new Mapper095(parent); + case 96: + return new Mapper096(parent); + case 97: + return new Mapper097(parent); + case 100: + return new Mapper100(parent); + case 101: + return new Mapper101(parent); + case 107: + return new Mapper107(parent); + case 113: + return new Mapper113(parent); + case 118: + return new Mapper118(parent); + case 119: + return new Mapper119(parent); + case 122: + case 184: + return new Mapper122(parent); + case 180: + return new Mapper180(parent); + case 181: + return new Mapper181(parent); + case 185: + return new Mapper185(parent); + case 187: + return new Mapper187(parent); + case 188: + return new Mapper188(parent); + case 189: + return new Mapper189(parent); + case 243: + return new Mapper243(parent); + case 0x100: + return new MapperNSF(parent); + + case 44: + return new Mapper044(parent); + case 45: + return new Mapper045(parent); + case 46: + return new Mapper046(parent); + case 47: + return new Mapper047(parent); + case 50: + return new Mapper050(parent); + case 51: + return new Mapper051(parent); + case 57: + return new Mapper057(parent); + case 58: + return new Mapper058(parent); + case 60: + return new Mapper060(parent); + case 62: + return new Mapper062(parent); + case 74: + return new Mapper074(parent); + case 105: + return new Mapper105(parent); + case 108: + return new Mapper108(parent); + case 109: + return new Mapper109(parent); + case 110: + return new Mapper110(parent); + case 111: + return new Mapper111(parent); + case 112: + return new Mapper112(parent); + case 114: + return new Mapper114(parent); + case 115: + return new Mapper115(parent); + case 116: + return new Mapper116(parent); + case 117: + return new Mapper117(parent); + case 133: + return new Mapper133(parent); + case 134: + return new Mapper134(parent); + case 135: + return new Mapper135(parent); + case 140: + return new Mapper140(parent); + case 142: + return new Mapper142(parent); + case 160: + return new Mapper160(parent); + case 163: + return new Mapper163(parent); + case 164: + return new Mapper164(parent); + case 165: + return new Mapper165(parent); + case 27: + return new Mapper027(parent); + case 167: + return new Mapper167(parent); + case 182: + return new Mapper182(parent); + case 183: + return new Mapper183(parent); + case 190: + return new Mapper190(parent); + case 191: + return new Mapper191(parent); + case 192: + return new Mapper192(parent); + case 193: + return new Mapper193(parent); + case 194: + return new Mapper194(parent); + case 195: + return new Mapper195(parent); + case 198: + return new Mapper198(parent); + case 222: + return new Mapper222(parent); + case 225: + return new Mapper225(parent); + case 226: + return new Mapper226(parent); + case 227: + return new Mapper227(parent); + case 228: + return new Mapper228(parent); + case 229: + return new Mapper229(parent); + case 230: + return new Mapper230(parent); + case 231: + return new Mapper231(parent); + case 232: + return new Mapper232(parent); + case 233: + return new Mapper233(parent); + case 234: + return new Mapper234(parent); + case 235: + return new Mapper235(parent); + case 236: + return new Mapper236(parent); + case 240: + return new Mapper240(parent); + case 241: + return new Mapper241(parent); + case 242: + return new Mapper242(parent); + case 244: + return new Mapper244(parent); + case 245: + return new Mapper245(parent); + case 246: + return new Mapper246(parent); + case 248: + return new Mapper248(parent); + case 249: + return new Mapper249(parent); + case 251: + return new Mapper251(parent); + case 252: + return new Mapper252(parent); + case 254: + return new Mapper254(parent); + case 255: + return new Mapper255(parent); + + case 99: + return new Mapper099(parent); + case 151: + return new Mapper151(parent); + + case 12: + return new Mapper012(parent); + + case 200: + return new Mapper200(parent); + case 201: + return new Mapper201(parent); + case 202: + return new Mapper202(parent); + + case 61: + return new Mapper061(parent); + + case 148: + return new Mapper148(parent); + + case 150: + return new Mapper150(parent); + + case 132: + return new Mapper132(parent); + + case 168: + return new Mapper168(parent); + + case 166: + return new Mapper166(parent); + + case 162: + return new Mapper162(parent); + + case 179: + return new Mapper179(parent); + + case 174: + return new Mapper174(parent); + + case 177: + return new Mapper177(parent); + + case 178: + return new Mapper178(parent); + + case 176: + return new Mapper176(parent); +// return new BoardFK23C(parent); + + case 175: + return new Mapper175(parent); + + case 253: + return new Mapper253(parent); + + case 120: + return new Mapper120(parent); + + case 169: + return new Mapper169(parent); + + case 170: + return new Mapper170(parent); + + case 171: + return new Mapper171(parent); + + case 172: + return new Mapper172(parent); + + case 237: + return new Mapper237(parent); + + case 141: + return new Mapper141(parent); + + case 121: + return new Mapper121(parent); + + case 212: + return new Mapper212(parent); + + case 199: + return new Mapper199(parent); + + case 49: + return new Mapper049(parent); + case 52: + return new Mapper052(parent); + + case 173: + return new Mapper173(parent); + + default: + break; + } + + return NULL; +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/MapperNSF.cpp b/References/VirtuaNESex_src_191105/NES/Mapper/MapperNSF.cpp new file mode 100644 index 00000000..69cb2024 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/MapperNSF.cpp @@ -0,0 +1,1038 @@ +////////////////////////////////////////////////////////////////////////// +// MapperNSF NSF:NES Sound Format // +////////////////////////////////////////////////////////////////////////// +#include "math.h" + +#define NSF_PROFILE 0 + +#if NSF_PROFILE +static DWORD avecount = 0; +static float tave = 0.0f; +static float pave = 0.0f; +static float ptave = 0.0f; +static DWORD maxtotalclk = 0; +static DWORD maxprofclk = 0; +static DWORD maxproftotalclk = 0; +static DWORD maxproftotalcnt = 0; +#endif + +BYTE MapperNSF::Font6x8[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + 0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00, + 0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00,0x48,0xB0,0x50,0x20,0x50,0x68,0x90,0x00, + 0x40,0xA0,0xA8,0x68,0x90,0x90,0x68,0x00,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + 0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00,0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00, + 0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x00, + 0x70,0x88,0x98,0xA8,0xC8,0x88,0x70,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0xF8,0x00, + 0x70,0x88,0x08,0x30,0x40,0x80,0xF8,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00, + 0x30,0x50,0x90,0x90,0xF8,0x10,0x10,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0xF0,0x00, + 0x70,0x88,0x80,0xF0,0x88,0x88,0x70,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x20,0x00, + 0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00, + 0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x40,0x00, + 0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00, + 0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00, + 0x30,0x48,0x88,0x98,0xA8,0xA8,0x78,0x00,0x20,0x50,0x50,0x88,0xF8,0x88,0x88,0x00, + 0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00, + 0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00, + 0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00,0x70,0x88,0x80,0xB8,0x88,0x88,0x70,0x00, + 0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0xF8,0x00, + 0x38,0x08,0x08,0x08,0x08,0x88,0x70,0x00,0x88,0x88,0x90,0xE0,0x90,0x88,0x88,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x88,0xD8,0xA8,0xA8,0xA8,0xA8,0xA8,0x00, + 0x88,0xC8,0xA8,0xA8,0xA8,0x98,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00, + 0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00,0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00, + 0xF0,0x88,0x88,0xF0,0x88,0x88,0x88,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00, + 0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, + 0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x00,0x88,0xA8,0xA8,0xA8,0xA8,0xD8,0x88,0x00, + 0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00,0x88,0x88,0x88,0x70,0x20,0x20,0x20,0x00, + 0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + 0x88,0x50,0xF8,0x20,0xF8,0x20,0x20,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x70,0x00, + 0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, + 0x80,0xC0,0xE0,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0xF8,0x00, + 0x80,0x80,0x80,0xF0,0x88,0x88,0xF0,0x00,0x00,0x00,0x78,0x80,0x80,0x80,0x78,0x00, + 0x08,0x08,0x08,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x70,0x88,0xF8,0x80,0x78,0x00, + 0x18,0x20,0xF8,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x78,0x88,0x78,0x08,0xF0,0x00, + 0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00, + 0x20,0x00,0x20,0x20,0x20,0x20,0xC0,0x00,0x80,0x80,0x88,0x90,0xE0,0x90,0x88,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00, + 0x00,0x00,0xF0,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00, + 0x00,0x00,0xF0,0x88,0xF0,0x80,0x80,0x00,0x00,0x00,0x78,0x88,0x78,0x08,0x08,0x00, + 0x00,0x00,0xB8,0xC0,0x80,0x80,0x80,0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00, + 0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x70,0x00, + 0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x00,0x00,0x00,0x88,0xA8,0xA8,0xD8,0x88,0x00, + 0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x88,0x88,0x78,0x08,0xF0,0x00, + 0x00,0x00,0xF8,0x08,0x70,0x80,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +BYTE MapperNSF::KeyBoardBitmap[] = { + 48, 26, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, + 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, + 0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, + 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, + 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, +}; + +// KeyA(6x26) +BYTE MapperNSF::KeyBitmapA[] = { + 6, 26, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, 0x0F, 0x0F, 0x2A, 0x2A, 0x2A, 0x2A, 0x0F, 0x0F, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x1A, 0x2A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, +}; +// KeyB(6x26) +BYTE MapperNSF::KeyBitmapB[] = { + 6, 26, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, + 0x0F, 0x0F, 0x1A, 0x2A, 0x0F, 0x0F, 0x0F, 0x0F, 0x2A, 0x2A, 0x0F, 0x0F, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x1A, 0x2A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, +}; +// KeyC(6x26) +BYTE MapperNSF::KeyBitmapC[] = { + 6, 26, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, + 0x0F, 0x0F, 0x1A, 0x2A, 0x2A, 0x2A, 0x0F, 0x0F, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x1A, 0x2A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, +}; +// KeyD(5x16) +BYTE MapperNSF::KeyBitmapD[] = { + 5, 16, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x2A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, +}; + +// lI(̂‚) +BYTE MapperNSF::NeonBitmapA[] = { + 6, 26, + 0xFF, 0x02, 0x12, 0x12, 0x02, 0xFF, 0x02, 0x12, 0x21, 0x21, 0x12, 0x02, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12, + 0x02, 0x12, 0x21, 0x21, 0x12, 0x02, 0xFF, 0x02, 0x12, 0x12, 0x02, 0xFF, +}; + +BYTE MapperNSF::NeonBitmapB[] = { + 6, 26, + 0xFF, 0x09, 0x1A, 0x1A, 0x09, 0xFF, 0x09, 0x1A, 0x2A, 0x2A, 0x1A, 0x09, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, + 0x09, 0x1A, 0x2A, 0x2A, 0x1A, 0x09, 0xFF, 0x09, 0x1A, 0x1A, 0x09, 0xFF, +}; + +BYTE MapperNSF::NeonBitmapC[] = { + 6, 26, + 0xFF, 0x1E, 0x1D, 0x1D, 0x1E, 0xFF, 0x1E, 0x1D, 0x2D, 0x2D, 0x1D, 0x1E, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, + 0x1E, 0x1D, 0x2D, 0x2D, 0x1D, 0x1E, 0xFF, 0x1E, 0x1D, 0x1D, 0x1E, 0xFF, +}; + +INT MapperNSF::KeyBitmapOfs[] = { + 0, 4, 7, 11, 14, 21, 25, 28, 32, 35, 39, 42, +}; + +LPBYTE MapperNSF::KeyBitmapTbl[] = { + MapperNSF::KeyBitmapA, + MapperNSF::KeyBitmapD, + MapperNSF::KeyBitmapB, + MapperNSF::KeyBitmapD, + MapperNSF::KeyBitmapC, + MapperNSF::KeyBitmapA, + MapperNSF::KeyBitmapD, + MapperNSF::KeyBitmapB, + MapperNSF::KeyBitmapD, + MapperNSF::KeyBitmapB, + MapperNSF::KeyBitmapD, + MapperNSF::KeyBitmapC, +}; + +BYTE MapperNSF::StarBitmapA[] = { + 5, 5, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x2D, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +BYTE MapperNSF::StarBitmapB[] = { + 5, 5, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1D, 0xFF, 0xFF, + 0xFF, 0x1D, 0x2D, 0x1D, 0xFF, + 0xFF, 0xFF, 0x1D, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +BYTE MapperNSF::StarBitmapC[] = { + 5, 5, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x2D, 0xFF, 0xFF, + 0xFF, 0x2D, 0x10, 0x2D, 0xFF, + 0xFF, 0xFF, 0x2D, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +BYTE MapperNSF::StarBitmapD[] = { + 5, 5, + 0xFF, 0xFF, 0x2D, 0xFF, 0xFF, + 0xFF, 0x2D, 0x10, 0x2D, 0xFF, + 0x2D, 0x10, 0x20, 0x10, 0x2D, + 0xFF, 0x2D, 0x10, 0x2D, 0xFF, + 0xFF, 0xFF, 0x2D, 0xFF, 0xFF, +}; + +LPBYTE MapperNSF::StarBitmapTbl[] = { + MapperNSF::StarBitmapA, + MapperNSF::StarBitmapB, + MapperNSF::StarBitmapC, + MapperNSF::StarBitmapD, +}; + +void MapperNSF::Reset() +{ +INT i; + + songno = 0; + + pad = padold = 0; + repcnt = 0; + + BGPAL[0] = BGPAL[1] = BGPAL[2] = BGPAL[3] = + SPPAL[0] = SPPAL[1] = SPPAL[2] = SPPAL[3] = 0x0F; + + exaddr = 0; + ZEROMEMORY( exram, sizeof(exram) ); + + SetPROM_Bank( 2, WRAM+0xA000, BANKTYPE_RAM ); // 4000-5FFF + + SetPROM_Bank( 3, WRAM+0x0000, BANKTYPE_RAM ); // 6000-7FFF + SetPROM_Bank( 4, WRAM+0x2000, BANKTYPE_RAM ); // 8000-9FFF + SetPROM_Bank( 5, WRAM+0x4000, BANKTYPE_RAM ); // A000-BFFF + SetPROM_Bank( 6, WRAM+0x6000, BANKTYPE_RAM ); // C000-DFFF + SetPROM_Bank( 7, WRAM+0x8000, BANKTYPE_RAM ); // E000-FFFF + + nsfheader = *(nes->rom->GetNsfHeader()); + exchip = nsfheader.ExtraChipSelect; + banksize = nes->rom->GetNSF_SIZE(); + + if( (songno = nsfheader.StartSong-1) >= nsfheader.TotalSong ) { + songno = 0; + } + + bankswitch = 0; + for( i = 0; i < 8; i++ ) { + bankswitch |= nsfheader.BankSwitch[i]; + } + + if( bankswitch ) { + // Bankswitch on + BYTE start_bank = nsfheader.LoadAddress>>12; + for( i = 0; (start_bank+i) < 8; i++ ) { + BankSwitch( start_bank+i, i ); + } + for( i = 0; i < 8; i++ ) { + BankSwitch( i+8, nsfheader.BankSwitch[i] ); + } + if( exchip&0x04 ) { //FDS + BankSwitch( 6, nsfheader.BankSwitch[6] ); + BankSwitch( 7, nsfheader.BankSwitch[7] ); + } + } else { + // Bankswitch off + LPBYTE pPtr = nes->rom->GetPROM(); + if( banksize < 8 ) { + for( i = 0; i < 0x1000*banksize; i++ ) { + if( nsfheader.LoadAddress-0x8000+i < 0x8000 ) { + WRAM[0x2000+nsfheader.LoadAddress-0x8000+i] = pPtr[i]; + } + } + } else { + for( i = 0; i < 0x8000; i++ ) { + if( nsfheader.LoadAddress-0x8000+i < 0x8000 ) { + WRAM[0x2000+nsfheader.LoadAddress-0x8000+i] = pPtr[i]; + } + } + } + } + + // $4700͑ҋ@[v + WRAM[0xA700] = 0x4c; //jmp + WRAM[0xA701] = 0x00; + WRAM[0xA702] = 0x47; + + // $4710Init[`Ă񂾌㖳[v + WRAM[0xA710] = 0x20; // jsr + WRAM[0xA711] = (BYTE) nsfheader.InitAddress & 0xFF; + WRAM[0xA712] = (BYTE)(nsfheader.InitAddress>>8); + WRAM[0xA713] = 0x4c; // jmp + WRAM[0xA714] = 0x00; + WRAM[0xA715] = 0x47; + + // $4720Play[`Ă񂾌㖳[v +#if NSF_PROFILE + WRAM[0xA720] = 0x8D; // sta + WRAM[0xA721] = 0x1E; // $401E + WRAM[0xA722] = 0x40; // $401E + + WRAM[0xA723] = 0x20; // jsr + WRAM[0xA724] = (BYTE) nsfheader.PlayAddress; + WRAM[0xA725] = (BYTE)(nsfheader.PlayAddress>>8); + + WRAM[0xA726] = 0x8D; // sta + WRAM[0xA727] = 0x1F; // $401F + WRAM[0xA728] = 0x40; // $401F + + WRAM[0xA729] = 0x4c; //jmp + WRAM[0xA72A] = 0x00; + WRAM[0xA72B] = 0x47; +#else + WRAM[0xA720] = 0x20; // jsr + WRAM[0xA721] = (BYTE) nsfheader.PlayAddress; + WRAM[0xA722] = (BYTE)(nsfheader.PlayAddress>>8); + WRAM[0xA723] = 0x4c; //jmp + WRAM[0xA724] = 0x00; + WRAM[0xA725] = 0x47; +#endif + + nes->apu->SelectExSound( exchip ); + nes->apu->Write( 0x4015, 0x1F ); + nes->apu->ExWrite( 0x4080, 0x80 ); // FDS Volume 0 + nes->apu->ExWrite( 0x408A, 0xE8 ); // FDS Envelope ON + + // For DQ1/2?? + nes->SetFrameIRQmode( FALSE ); + + // NTSC/PAL tune + nes->SetVideoMode( (nsfheader.NTSC_PALbits&0x01) ); + + // g->Keye[u̍쐬 + for( i = 0; i < 12*8+1; i++ ) { + Freq2KeyTbl[i] = (INT)(440.0*256.0*pow(2.0,((double)(i-45)-0.5)/12.0)); + } + + // ܂ + StarInitial(); + + // +#if NSF_PROFILE + avecount = 0; + tave = 0.0f; + pave = 0.0f; + ptave = 0.0f; + maxtotalclk = 0; + maxprofclk = 0; + maxproftotalclk = 0; + maxproftotalcnt = 0; +#endif +} + +BYTE MapperNSF::ExRead( WORD addr ) +{ +BYTE data = 0; + + if( addr >= 0x4040 && addr < 0x4100 ) { + data = nes->apu->ExRead( addr ); + } + return data; +} + +void MapperNSF::ExWrite( WORD addr, BYTE data ) +{ + if( addr >= 0x4040 && addr < 0x4100 ) { + nes->apu->ExWrite( addr, data ); + } +} + +BYTE MapperNSF::ReadLow( WORD addr ) +{ + if( addr == 0x4800 ) { + BYTE data = exram[exaddr&0x7F]; + if( exaddr&0x80 ) + exaddr = (exaddr+1)|0x80; + nes->apu->ExRead( addr ); + return data; + } else if( addr == 0x5205 ) { // MMC5 + return (BYTE)multipul[0]*multipul[1]; + } else if( addr == 0x5206 ) { // MMC5 + return (BYTE)(((WORD)multipul[0]*(WORD)multipul[1])>>8); + } + + if (addr >= 0x4700 && addr < 0x4730) { //NSF player opcode Ҷ + return CPU_MEM_BANK[addr >> 13][addr & 0x1FFF]; + } + +// if( addr >= 0x47A0 && addr < 0x4800 ) { +// return WRAM[addr+0x6000]; +// } + if( addr >= 0x5C00 && addr < 0x5FFF ) { // MMC5 + return DRAM[addr-0x5C00]; + } + if( addr >= 0x6000 ) { + return WRAM[addr-0x6000]; + } + + return (BYTE)(addr>>8); +} + +void MapperNSF::WriteLow( WORD addr, BYTE data ) +{ + if( addr == 0x4800 || (addr >= 0x5000 && addr <= 0x5015) ) { +//DEBUGOUT( "$4800 WR=%02X\n", data ); + exram[exaddr&0x7F] = data; + if( exaddr&0x80 ) + exaddr = (exaddr+1)|0x80; + nes->apu->ExWrite( addr, data ); + } else if( addr == 0x5205 ) { // MMC5 + multipul[0] = data; + } else if( addr == 0x5206 ) { // MMC5 + multipul[1] = data; + } else if( addr >= 0x5C00 && addr < 0x5FF6 ) { // MMC5 + DRAM[addr-0x5C00] = data; + } +// if( addr >= 0x47A0 && addr < 0x4800 ) { +// WRAM[addr+0x6000] = data; +// } + if( addr >= 0x5FF6 && addr <= 0x5FFF ) { + // Bank switch + BankSwitch( addr&0x0F, data ); + } + if( addr >= 0x6000 ) { + WRAM[addr-0x6000] = data; + + nes->apu->ExWrite( addr, data ); + } +} + +void MapperNSF::Write( WORD addr, BYTE data ) +{ + if( (exchip&0x04) ) { //FDS + WRAM[addr-0x6000] = data; + } + nes->apu->ExWrite( addr, data ); + if( addr == 0xF800 ) { + exaddr = data; + } +} + +void MapperNSF::BankSwitch( INT no, BYTE bank ) +{ +INT i; +INT addr, offs; +LPBYTE pPtr; + + offs = 0x1000*(INT)bank-(INT)(nsfheader.LoadAddress&0x0FFF); + pPtr = nes->rom->GetPROM(); + + if( no == 6 || no == 7 ) { + for( i = 0; i < 0x1000; i++ ) { //4K size + addr = offs+i; + if( addr < 0 || addr > (4096*banksize)-1 ) { + WRAM[0x1000*(no&1)+i] = 0; + } else { + WRAM[0x1000*(no&1)+i] = pPtr[addr]; + } + } + } else if( no >= 8 && no <= 15 ) { + for( i = 0; i < 0x1000; i++ ) { //4K size + addr = offs+i; + if( addr < 0 || addr > (4096*banksize)-1 ) { + WRAM[0x2000+0x1000*(no&7)+i] = 0; + } else { + WRAM[0x2000+0x1000*(no&7)+i] = pPtr[addr]; + } + } + } +} + +void MapperNSF::VSync() +{ + // f[^ݒ + padold = pad; + pad = nes->pad->GetNsfController(); + BYTE padpush = ~padold & pad; + + if( padpush ) { + repcnt = 20; + } else if( pad ) { + if( --repcnt == 0 ) { + repcnt = 8; + padpush |= pad & 0xFC; + } + } + + // -1 + if( padpush & (1<<2) ) { + if( --songno < 0 ) { + songno = nsfheader.TotalSong-1; + } + } + // +1 + if( padpush & (1<<3) ) { + if( ++songno >= nsfheader.TotalSong ) { + songno = 0; + } + } + // -16 + if( padpush & (1<<4) ) { + if( (songno-=16) < 0 ) { + while( songno < 0 ) { + songno += nsfheader.TotalSong; + } + songno %= nsfheader.TotalSong; + } + } + // +16 + if( padpush & (1<<5) ) { + if( (songno+=16) >= nsfheader.TotalSong ) { + songno -= nsfheader.TotalSong; + songno %= nsfheader.TotalSong; + } + } + + // Play + if( padpush & (1<<0) ) { + nes->SetNsfPlay( songno, 0 ); + } + + // Stop + if( padpush & (1<<1) ) { + nes->SetNsfStop(); + } + + // ܂ + Star(); + + // Drawing screen +// DrawString( 10, 16, "TITLE :", 0x30 ); +// DrawString( 10, 31, "ARTIST:", 0x30 ); +// DrawString( 10, 46, "(C) :", 0x30 ); +// DrawString( 10, 61, "NO :", 0x30 ); + + DrawString( 10, 16, "Title :", 0x30 ); + DrawString( 10, 31, "Artist:", 0x30 ); + DrawString( 10, 46, "(C) :", 0x30 ); + DrawString( 10, 61, "No :", 0x30 ); + + DrawString( 28, 76, "Keyboard", 0x30 ); + DrawString( 32, 152, "Wave View", 0x30 ); + + // ^CgȂ + CHAR str[64]; + memcpy( str, nsfheader.SongName, 32 ); + str[32] = 0; + DrawString( 53, 16, str, 0x30 ); + memcpy( str, nsfheader.ArtistName, 32 ); + str[32] = 0; + DrawString( 53, 31, str, 0x30 ); + memcpy( str, nsfheader.CopyrightName, 32 ); + str[32] = 0; + DrawString( 53, 46, str, 0x30 ); + // Song no + sprintf( str, "%02X", songno ); + DrawString( 53, 61, str, 0x30 ); + + // Extra sound + DrawString( 76+6* 0, 61, "VRC6", (exchip&0x01)?0x2B:0x2D ); + DrawString( 76+6* 5, 61, "VRC7", (exchip&0x02)?0x2B:0x2D ); + DrawString( 76+6*10, 61, "FDS", (exchip&0x04)?0x2B:0x2D ); + DrawString( 76+6*14, 61, "MMC5", (exchip&0x08)?0x2B:0x2D ); + DrawString( 76+6*19, 61, "N106", (exchip&0x10)?0x2B:0x2D ); + DrawString( 76+6*24, 61, "FME7", (exchip&0x20)?0x2B:0x2D ); + + // ^CgȂǂ̃C + DrawRect( 52, 24, 243-52, 0, 0x30 ); + DrawRect( 52, 39, 243-52, 0, 0x30 ); + DrawRect( 52, 54, 243-52, 0, 0x30 ); + DrawRect( 52, 69, 12, 0, 0x30 ); + DrawRect( 75, 69, 243-75, 0, 0x30 ); + + // L[{[hg + DrawRect( 27, 84, 229-27, 148- 84, 0x30 ); + + // WAVEVIEWg +#if !NSF_PROFILE + DrawRect( 31, 160, 224-31, 224-160, 0x30 ); + DrawRect( 32, 192, 223-32, 0, 0x27 ); + + // Wave + DrawWave( 28+4, 192, 0x2A ); +#endif + // L[{[hi(O5-O8) + DrawBitmap( 31+49*0, 88, KeyBoardBitmap ); + DrawBitmap( 31+49*1, 88, KeyBoardBitmap ); + DrawBitmap( 31+49*2, 88, KeyBoardBitmap ); + DrawBitmap( 31+49*3, 88, KeyBoardBitmap ); + // L[{[hi(O1-O4) + DrawBitmap( 31+49*0, 119, KeyBoardBitmap ); + DrawBitmap( 31+49*1, 119, KeyBoardBitmap ); + DrawBitmap( 31+49*2, 119, KeyBoardBitmap ); + DrawBitmap( 31+49*3, 119, KeyBoardBitmap ); + + // L[{[hĂ̂` + // Internal APU + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0000)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0001)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0002)) ); + + // Internal Noise + if( nes->apu->GetChannelFrequency(0x0003) ) { + DrawBitmap( 10, 88, NeonBitmapA ); + DrawBitmap( 241, 88, NeonBitmapA ); + DrawBitmap( 10, 119, NeonBitmapA ); + DrawBitmap( 241, 119, NeonBitmapA ); + } else { + DrawBitmap( 10, 88, NeonBitmapC ); + DrawBitmap( 241, 88, NeonBitmapC ); + DrawBitmap( 10, 119, NeonBitmapC ); + DrawBitmap( 241, 119, NeonBitmapC ); + } + + // Internal DPCM + if( nes->apu->GetChannelFrequency(0x0004) ) { + DrawBitmap( 18, 88, NeonBitmapB ); + DrawBitmap( 233, 88, NeonBitmapB ); + DrawBitmap( 18, 119, NeonBitmapB ); + DrawBitmap( 233, 119, NeonBitmapB ); + } else { + DrawBitmap( 18, 88, NeonBitmapC ); + DrawBitmap( 233, 88, NeonBitmapC ); + DrawBitmap( 18, 119, NeonBitmapC ); + DrawBitmap( 233, 119, NeonBitmapC ); + } + + // VRC6 + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0100)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0101)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0102)) ); + + // VRC7 + // Nothing... + + // FDS + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0300)) ); + + // MMC5 + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0400)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0401)) ); + + // N106 + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0500)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0501)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0502)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0503)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0504)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0505)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0506)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0507)) ); + + // FME7 + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0600)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0601)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0602)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0610)) ); // Noise + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0611)) ); // Noise + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0612)) ); // Noise + + // VRC7 + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0700)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0701)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0702)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0703)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0704)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0705)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0706)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0707)) ); + DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0708)) ); + + // TEST +#if NSF_PROFILE + if( nes->IsNsfPlaying() ) { + DWORD total, profile; + + total = nes->GetFrameTotalCycles(); + profile = nes->GetProfileCycles(); + + if( maxtotalclk < total ) { + maxtotalclk = total; + } + if( maxprofclk < profile ) { + maxprofclk = profile; + } + if( maxproftotalclk < nes->GetProfileTotalCycles() ) { + maxproftotalclk = nes->GetProfileTotalCycles(); + } + if( maxproftotalcnt < nes->GetProfileTotalCount() ) { + maxproftotalcnt = nes->GetProfileTotalCount(); + } + + tave += total; + pave += profile; + ptave += nes->GetProfileTotalCycles(); + avecount++; + +sprintf( str, "TOTAL CLK :%8d", total ); +DrawString( 16, 160, str, 0x30 ); +sprintf( str, "TOTAL MAX :%8d", maxtotalclk ); +DrawString( 134, 160, str, 0x30 ); +sprintf( str, "TOTAL AVE :%8.2f", tave / (float)avecount ); +DrawString( 16, 168, str, 0x30 ); + + +sprintf( str, "PROFILE :%8d", profile ); +DrawString( 16, 176, str, 0x30 ); +sprintf( str, "PROFILEMAX:%8d", maxprofclk ); +DrawString( 134, 176, str, 0x30 ); +sprintf( str, "POFILE AVE:%8.2f", pave / (float)avecount ); +DrawString( 16, 184, str, 0x30 ); + +sprintf( str, "PRF/TTL %%:%8.2f", 100.0f * (float)profile / (float)total ); +DrawString( 16, 192, str, 0x30 ); + +sprintf( str, "FRM-P TTL :%8d", nes->GetProfileTotalCycles() ); +DrawString( 16, 200, str, 0x30 ); +sprintf( str, "F-P TTLMAX:%8d", maxproftotalclk ); +DrawString( 134, 200, str, 0x30 ); + +sprintf( str, "FRM-P CNT :%8d", nes->GetProfileTotalCount() ); +DrawString( 16, 208, str, 0x30 ); +sprintf( str, "F-P CNTMAX:%8d", maxproftotalcnt ); +DrawString( 134, 208, str, 0x30 ); + +sprintf( str, "F P/T AVE :%8.2f", ptave / (float)avecount ); +DrawString( 16, 216, str, 0x30 ); + +sprintf( str, "F PRF/TTL%%:%8.2f", 100.0f * (float)nes->GetProfileTotalCycles() / (float)total ); +DrawString( 16, 224, str, 0x30 ); + + if( avecount >= 60 ) { + avecount = 0; + tave = 0.0f; + pave = 0.0f; + ptave = 0.0f; + maxtotalclk = 0; + maxprofclk = 0; + maxproftotalclk = 0; + maxproftotalcnt = 0; + } + } +#endif +} + +INT MapperNSF::GetKeyTable( INT freq ) +{ +INT ret = -1; + + if( freq < Freq2KeyTbl[0] ) + return -1; + + for( INT i = 0; i < 12*8+1; i++ ) { + if( freq < Freq2KeyTbl[i] ) + return ret; + ret = i; + } + return -1; +} + +void MapperNSF::DrawKey( INT key ) +{ + if( key < 0 || key > 12*8-1 ) + return; + + if( key < 12*4 ) { + DrawBitmap( 31+(key/12)*49+KeyBitmapOfs[key%12], 119, KeyBitmapTbl[key%12] ); + } else { + DrawBitmap( 31+((key-12*4)/12)*49+KeyBitmapOfs[key%12], 88, KeyBitmapTbl[key%12] ); + } +} + +void MapperNSF::DrawRect( INT x, INT y, INT w, INT h, BYTE col ) +{ +INT i; +LPBYTE pScn = nes->ppu->GetScreenPtr()+8; +LPBYTE p0, p1; + + p0 = pScn+(256+16)*y+x; + p1 = p0+(256+16)*h; + for( i = 0; i < w+1; i++ ) { + *p0++ = col; + *p1++ = col; + } + p0 = pScn+(256+16)*y+x; + p1 = p0+w; + for( i = 0; i < h+1; i++ ) { + *p0 = col; + *p1 = col; + p0 += (256+16); + p1 += (256+16); + } +} + +void MapperNSF::DrawFont( INT x, INT y, BYTE chr, BYTE col ) +{ +INT i; +LPBYTE pFnt; +LPBYTE pPtr; +LPBYTE pScn = nes->ppu->GetScreenPtr()+8; + + if( chr < 0x20 || chr > 0x7F ) + return; + chr -= 0x20; + pFnt = &Font6x8[chr*8]; + pPtr = pScn+(256+16)*y+x; + for( i = 0; i < 8; i++ ) { + if( pFnt[i] & 0x80 ) pPtr[0] = col; + if( pFnt[i] & 0x40 ) pPtr[1] = col; + if( pFnt[i] & 0x20 ) pPtr[2] = col; + if( pFnt[i] & 0x10 ) pPtr[3] = col; + if( pFnt[i] & 0x08 ) pPtr[4] = col; + if( pFnt[i] & 0x04 ) pPtr[5] = col; + pPtr += (256+16); + } +} + +void MapperNSF::DrawString( INT x, INT y, LPSTR str, BYTE col ) +{ + while( *str ) { + DrawFont( x, y, *str, col ); + str++; + x += 6; + } +} + +void MapperNSF::DrawWave( INT x, INT y, INT col ) +{ +INT i, j; +INT yp, ypold; +LPBYTE pScn = nes->ppu->GetScreenPtr()+8+(256+16)*y+x; +LPBYTE pPtr; + + ypold = 0; + LPSWORD pBuffer = (LPSWORD)nes->apu->GetSoundBuffer(); + for( i = 0; i < 192; i++ ) { + yp = -((INT)*pBuffer)/1024; + if( yp < -31 ) yp = -31; + if( yp > 31 ) yp = 31; + if( abs( yp-ypold ) <= 1 || i == 0 ) { + pPtr = pScn+yp*(256+16)+i; + *pPtr = col; + } else { + // Line DDA + INT xpos, ypos; + INT sx, sy; + xpos = 65536*(i-1)+32768; + ypos = ypold; + sy = yp-ypold; + sx = 65536/abs(sy); + for( j = 0; j <= abs(sy); j++ ) { + pPtr = pScn+ypos*(256+16)+(xpos/65536); + *pPtr = col; + ypos += (sy>0)?1:-1; + xpos += sx; + } + } + ypold = yp; + pBuffer++; + } +} + +void MapperNSF::DrawBitmap( INT x, INT y, LPBYTE lpBitmap ) +{ +INT i, j; +INT h, v; +LPBYTE pScn = nes->ppu->GetScreenPtr()+8+(256+16)*y+x; +LPBYTE pPtr; + + h = (INT)*lpBitmap++; + v = (INT)*lpBitmap++; + + for( j = 0; j < v; j++ ) { + pPtr = pScn; + for( i = 0; i < h; i++ ) { + if( *lpBitmap != 0xFF ) { + *pPtr = *lpBitmap; + } + lpBitmap++; + pPtr++; + } + pScn += 256+16; + } +} + +void MapperNSF::StarInitial() +{ + for( INT i = 0; i < STAR_MAX; i++ ) { + StarBuf[i].x = ((rand()%(256-10))-(256-10)/2)*256; + StarBuf[i].y = ((rand()%(240-10))-(240-10)/2)*256; + StarBuf[i].z = (rand()%250)+5; + } +} + +void MapperNSF::Star() +{ + INT x, y, z; + for( INT i = 0; i < STAR_MAX; i++ ) { + if( --StarBuf[i].z < 5 ) { + StarBuf[i].x = ((rand()%(256-10))-(256-10)/2)*256; + StarBuf[i].y = ((rand()%(240-10))-(240-10)/2)*256; + StarBuf[i].z = 255; + } + + x = 256/2+(StarBuf[i].x-5/128)/StarBuf[i].z; + y = 240/2+(StarBuf[i].y-5/128)/StarBuf[i].z; + + if( x < 3 || x >= 256-8 || y < 3 || y >= 240-8 ) { + StarBuf[i].x = ((rand()%(256-10))-(256-10)/2)*256; + StarBuf[i].y = ((rand()%(240-10))-(240-10)/2)*256; + StarBuf[i].z = 255; + continue; + } + + if( StarBuf[i].z > 200 ) + z = 0; + else if( StarBuf[i].z > 100 ) + z = 1; + else if( StarBuf[i].z > 50 ) + z = 2; + else + z = 3; + + DrawBitmap( x, y, StarBitmapTbl[z] ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/Mapper/MapperNSF.h b/References/VirtuaNESex_src_191105/NES/Mapper/MapperNSF.h new file mode 100644 index 00000000..e6316bcc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Mapper/MapperNSF.h @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// MapperNSF NSF:NES Sound Format // +////////////////////////////////////////////////////////////////////////// +class MapperNSF : public Mapper +{ +public: + MapperNSF( NES* parent ) : Mapper(parent) {} + + void Reset(); + + BYTE ExRead ( WORD addr ); + void ExWrite( WORD addr, BYTE data ); + + BYTE ReadLow( WORD addr ); + void WriteLow( WORD addr, BYTE data ); + void Write(WORD addr, BYTE data); + + void VSync(); + +protected: + NSFHEADER nsfheader; + BYTE exchip; + BYTE bankswitch; + INT banksize; + BYTE multipul[2]; + + BYTE exaddr; + BYTE exram[128]; + + void BankSwitch( INT no, BYTE bank ); + + // Song number + INT songno; + + // Key buffer + BYTE pad, padold; + BYTE repcnt; + + // For keyboard + INT GetKeyTable( INT freq ); + void DrawKey( INT key ); + + // For Drawing + void DrawRect( INT x, INT y, INT w, INT h, BYTE col ); + void DrawFont( INT x, INT y, BYTE chr, BYTE col ); + void DrawString( INT x, INT y, LPSTR str, BYTE col ); + void DrawWave( INT x, INT y, INT col ); + + void DrawBitmap( INT x, INT y, LPBYTE lpBitmap ); + + static BYTE NsfPlayerCode[]; + + static BYTE Font6x8[]; + + static BYTE KeyBoardBitmap[]; + static BYTE KeyBitmapA[]; + static BYTE KeyBitmapB[]; + static BYTE KeyBitmapC[]; + static BYTE KeyBitmapD[]; + + static BYTE NeonBitmapA[]; + static BYTE NeonBitmapB[]; + static BYTE NeonBitmapC[]; + + static INT KeyBitmapOfs[]; + static LPBYTE KeyBitmapTbl[]; + + static BYTE StarBitmapA[]; + static BYTE StarBitmapB[]; + static BYTE StarBitmapC[]; + static BYTE StarBitmapD[]; + static LPBYTE StarBitmapTbl[]; + + // ܂ + enum { STAR_MAX = 128 }; + + struct STAR { + INT x, y, z; + }; + struct STAR StarBuf[STAR_MAX]; + + void StarInitial(); + void Star(); + + INT Freq2KeyTbl[96+1]; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/NND.cpp b/References/VirtuaNESex_src_191105/NES/NND.cpp new file mode 100644 index 00000000..0cced6ee --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/NND.cpp @@ -0,0 +1,139 @@ +/******************************************************************************/ +/* Nes Cart Dumper */ +/* tpu */ +/* last : 2006.11.14 */ +/* first: 2003.05.05 */ +/******************************************************************************/ + +#include +#include +#include +#include + +#include "mmu.h" + +#include "nnd.h" + +#define inb(a) _inp((unsigned short)a) +#define outb(a, d) _outp((unsigned short)a, (unsigned short)d) + +int InstallGiveIo(void) +{ + HANDLE h; + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT){ //OS=NT/2000 + h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + CloseHandle(h); + if(h == INVALID_HANDLE_VALUE) + return 0; + else + return 0x2000; + }else{ + return 0x0098; //OS=WIN98 + } +} + +void set_paddr(int addr) +{ + outb(0x37b, 0); + outb(0x37c, addr&0xff); + outb(0x37b, 1); + outb(0x37c, (addr>>8)); +} + +void set_vaddr(int addr) +{ + int data; + data = (~addr)&0x2000; + data <<= 1; + addr &= 0x3fff; + addr |= data; + outb(0x37b, 4); + outb(0x37c, addr&0xff); + outb(0x37b, 5); + outb(0x37c, addr>>8); +} + +void vwrite(int addr, int data) +{ + set_vaddr(addr); + outb(0x37b, 6); + outb(0x37c, data); +} + +int vread(int addr) +{ + int data; + set_vaddr(addr); + outb(0x37b, 6); + data = inb(0x37c); + return data; +} + +int ppread(int addr) +{ + int data; + if(addr<0x4000) return vread(addr); + set_paddr(addr); + outb(0x37b, 2); + data = inb(0x37c); + return data; +} + +void ppwrite(int addr, int data) +{ + if(addr<0x4000){ + vwrite(addr, data); + return; + } + set_paddr(addr); + outb(0x37b, 2); + outb(0x37c, data); +} + +void bus_reset(void) +{ + int data; + //Reset + data = inb(0x37a); + data &= 0xfb; + outb(0x37a, data); + data = 0xc4; + outb(0x37a, data); + outb(0x37b, 8); + outb(0x37c, 0); //auto sync on +// outb(0x37c, 1); //auto sync off + set_vaddr(0x3fff); +} + +void main(void) +{ + BYTE filebuf_Prom[64*1024]; + BYTE filebuf_Vrom[16*1024]; + int retv, i; + + retv = InstallGiveIo(); + if(retv==0){ + printf("Please install gaveio.sys first!\n"); + } + bus_reset(); + + for(i=0x8000; i<0x10000; i++) filebuf_Prom[i-0x8000] = ppread(i); + CPU_MEM_BANK[4] = filebuf_Prom; + CPU_MEM_BANK[5] = filebuf_Prom + 0x2000; + CPU_MEM_BANK[6] = filebuf_Prom + 0x4000; + CPU_MEM_BANK[7] = filebuf_Prom + 0x6000; + + for(i=0x0000; i<0x2000; i++) filebuf_Vrom[i] = ppread(i); + PPU_MEM_BANK[0] = filebuf_Vrom; + PPU_MEM_BANK[1] = filebuf_Vrom + 0x0400; + PPU_MEM_BANK[2] = filebuf_Vrom + 0x0800; + PPU_MEM_BANK[3] = filebuf_Vrom + 0x0c00; + PPU_MEM_BANK[4] = filebuf_Vrom + 0x1000; + PPU_MEM_BANK[5] = filebuf_Vrom + 0x1400; + PPU_MEM_BANK[6] = filebuf_Vrom + 0x1800; + PPU_MEM_BANK[7] = filebuf_Vrom + 0x1c00; +} diff --git a/References/VirtuaNESex_src_191105/NES/NND.h b/References/VirtuaNESex_src_191105/NES/NND.h new file mode 100644 index 00000000..bcaf7de4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/NND.h @@ -0,0 +1,6 @@ +#ifndef __NND_INCLUDED__ +#define __NND_INCLUDED__ + +#include "typedef.h" + +#endif \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/Nes.cpp b/References/VirtuaNESex_src_191105/NES/Nes.cpp new file mode 100644 index 00000000..860a9569 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Nes.cpp @@ -0,0 +1,4268 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES Emulation core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" + +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Config.h" +#include "Crclib.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "apu.h" +#include "pad.h" +#include "rom.h" +#include "mapper.h" + +#include "DirectDraw.h" +#include "DirectSound.h" +#include "DirectInput.h" + +#include "pngwrite.h" + +NESCONFIG NESCONFIG_NTSC = { + 21477270.0f, // Base clock + 1789772.5f, // Cpu clock + + 262, // Total scanlines + 241, // VBlank start line + + 1364, // Scanline total cycles(15.75KHz) + + 1024, // H-Draw cycles + 340, // H-Blank cycles + 4, // End cycles + + 1364*262, // Frame cycles + 29830, // FrameIRQ cycles + + 60, // Frame rate(Be originally 59.94Hz) + 1000.0f/60.0f // Frame period(ms) +}; + +NESCONFIG NESCONFIG_PAL = { + 21281364.0f, // Base clock + 1773447.0f, // Cpu clock + + 312, // Total scanlines + 241, // VBlank start line + + 1362, // Scanline total cycles(15.625KHz) + + 1024, // H-Draw cycles + 338, // H-Blank cycles + 4, // End cycles + + 1362*312, // Frame cycles + 35469, // FrameIRQ cycles + + 50, // Frame rate(Hz) + 1000.0f/50.0f // Frame period(ms) +}; + +NESCONFIG NESCONFIG_PALCHINA = { + 21281364.0f, // Base clock + 1773447.0f, // Cpu clock + + 313, // Total scanlines + 291, // VBlank start line + + 1362, // Scanline total cycles(15.625KHz) + + 1024, // H-Draw cycles + 338, // H-Blank cycles + 2, // End cycles + + 1362*313, // Frame cycles + 35469, // FrameIRQ cycles + + 50, // Frame rate(Hz) + 1000.0f/50.0f // Frame period(ms) +}; + +// Pad disp +BYTE NES::m_PadImg[] = { + 28, 8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, + 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x0F, + 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x0F, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +BYTE NES::m_KeyImg0[] = { + 2, 2, + 0x2A, 0x2A, + 0x2A, 0x2A, +}; +BYTE NES::m_KeyImg1[] = { + 3, 3, + 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, +}; +BYTE NES::m_KeyImg2[] = { + 4, 4, + 0xFF, 0x2A, 0x2A, 0xFF, + 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, + 0xFF, 0x2A, 0x2A, 0xFF, +}; + +// +// +// +NES::NES( const char* fname ) +{ + DEBUGOUT( "VirtuaNES - NES Emulator for Win32 by Norix (C)2001\n" ); + + m_bDiskThrottle = FALSE; + m_CommandRequest = 0; + + m_nSnapNo = 0; + + m_bNsfPlaying = FALSE; + + m_bMoviePlay = m_bMovieRec = FALSE; + m_fpMovie = NULL; + + m_bTapePlay = m_bTapeRec = FALSE; + m_fpTape = NULL; + m_TapeCycles = 0.0; + m_TapeIn = m_TapeOut = 0; + + m_bBarcode = FALSE; + m_BarcodeOut = 0; + m_BarcodePtr = 0; + m_BarcodeCycles = 0; + + m_bBarcode2 = FALSE; + + m_TurboFileBank = 0; + + cpu = NULL; + ppu = NULL; + apu = NULL; + rom = NULL; + pad = NULL; + mapper = NULL; + + SAVERAM_SIZE = 8*1024; // 8K byte + + // IRQ type + nIRQtype = 0; + + // FrameIRQ mode + bFrameIRQ = TRUE; + + // NTSC/PAL VideoMode + bVideoMode = FALSE; + + // Default config + nescfg = &NESCONFIG_NTSC; + + // Cheat + CheatInitial(); + + // TEST + m_dwTotalCycle = 0; + m_dwTotalTempCycle = 0; + m_dwProfileTotalCycle = 0; + m_dwProfileTotalCount = 0; + m_dwProfileCycle = 0; + m_dwProfileTempCycle = 0; + + try { + DEBUGOUT( "Allocating CPU..." ); + if( !(cpu = new CPU(this)) ) + throw "Allocating CPU failed."; + DEBUGOUT( "Ok.\n" ); + + DEBUGOUT( "Allocating PPU..." ); + if( !(ppu = new PPU(this)) ) + throw "Allocating PPU failed."; + DEBUGOUT( "Ok.\n" ); + + DEBUGOUT( "Allocating APU..." ); + if( !(apu = new APU(this)) ) + throw "Allocating APU failed."; + DEBUGOUT( "Ok.\n" ); + + DEBUGOUT( "Allocating PAD..." ); + if( !(pad = new PAD(this)) ) + throw "Allocating PAD failed."; + DEBUGOUT( "Ok.\n" ); + + DEBUGOUT( "Loading ROM Image...\n" ); + + if( !(rom = new ROM(fname)) ) + throw "Allocating ROM failed."; +/* + if( !(mapper = CreateMapper(this, rom->GetMapperNo())) ) { + // T|[g̃}bp[ł + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_UNSUPPORTMAPPER ); + sprintf( szErrorString, szErrStr, rom->GetMapperNo() ); + throw szErrorString; + } +*/ + if( !(mapper = CreateMapper(this, rom->IsUnifMapper()?rom->GetUnifBoard():rom->GetMapperNo(), rom->IsUnifMapper())) ){ + // T|[g̃}bp[ł + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_UNSUPPORTMAPPER ); + if(rom->IsUnifMapper()){ + sprintf( szErrorString, "ݲ֧UNIF Board - [ %s ] ", rom->GetBoardName() ); + }else{ + sprintf( szErrorString, szErrStr, rom->GetMapperNo() ); + } + throw szErrorString; + } + + DEBUGOUT( "Ok.\n" ); + + DEBUGOUT( "ROM status\n" ); + DEBUGOUT( " %s\n", rom->GetRomName() ); + DEBUGOUT( " Mapper : %03d\n", rom->GetMapperNo() ); + DEBUGOUT( " PRG SIZE : %4dK\n", 16*(INT)rom->GetPROM_SIZE() ); + DEBUGOUT( " CHR SIZE : %4dK\n", 8*(INT)rom->GetVROM_SIZE() ); + + DEBUGOUT( " V MIRROR : " ); + if( rom->IsVMIRROR() ) DEBUGOUT( "Yes\n" ); + else DEBUGOUT( "No\n" ); + DEBUGOUT( " 4 SCREEN : " ); + if( rom->Is4SCREEN() ) DEBUGOUT( "Yes\n" ); + else DEBUGOUT( "No\n" ); + DEBUGOUT( " SAVE RAM : " ); + if( rom->IsSAVERAM() ) DEBUGOUT( "Yes\n" ); + else DEBUGOUT( "No\n" ); + DEBUGOUT( " TRAINER : " ); + if( rom->IsTRAINER() ) DEBUGOUT( "Yes\n" ); + else DEBUGOUT( "No\n" ); + DEBUGOUT( " VS-Unisystem : " ); + if( rom->IsVSUNISYSTEM() ) DEBUGOUT( "Yes\n" ); + else DEBUGOUT( "No\n" ); + + NesSub_MemoryInitial(); + LoadSRAM(); + LoadDISK(); + + { + // PadNXƏ^C~Ox̂ł + DWORD crc = rom->GetPROM_CRC(); + if( crc == 0xe792de94 // Best Play - Pro Yakyuu (New) (J) + || crc == 0xf79d684a // Best Play - Pro Yakyuu (Old) (J) + || crc == 0xc2ef3422 // Best Play - Pro Yakyuu 2 (J) + || crc == 0x974e8840 // Best Play - Pro Yakyuu '90 (J) + || crc == 0xb8747abf // Best Play - Pro Yakyuu Special (J) + || crc == 0x9fa1c11f // Castle Excellent (J) + || crc == 0x0b0d4d1b // Derby Stallion - Zenkoku Ban (J) + || crc == 0x728c3d98 // Downtown - Nekketsu Monogatari (J) + || crc == 0xd68a6f33 // Dungeon Kid (J) + || crc == 0x3a51eb04 // Fleet Commander (J) + || crc == 0x7c46998b // Haja no Fuuin (J) + || crc == 0x7e5d2f1a // Itadaki Street - Watashi no Mise ni Yottette (J) + || crc == 0xcee5857b // Ninjara Hoi! (J) + || crc == 0x50ec5e8b // Wizardry - Legacy of Llylgamyn (J) + || crc == 0x343e9146 // Wizardry - Proving Grounds of the Mad Overlord (J) + || crc == 0x33d07e45 ) { // Wizardry - The Knight of Diamonds (J) + pad->SetExController( PAD::EXCONTROLLER_TURBOFILE ); + } + } + + LoadTurboFile(); + + // VS-Unisystem̃ftHgݒ + if( rom->IsVSUNISYSTEM() ) { + DWORD crc = rom->GetPROM_CRC(); + + m_VSDipValue = GetVSDefaultDipSwitchValue( crc ); + m_VSDipTable = FindVSDipSwitchTable( crc ); + + #include "VS_Setting.h" + } else { + m_VSDipValue = 0; + m_VSDipTable = vsdip_default; + } + + Reset(); + + // Q[ŗL̃ftHgIvVݒ(ݒ߂Ɏg) + GameOption.defRenderMethod = (INT)GetRenderMethod(); + GameOption.defIRQtype = (INT)GetIrqType(); + GameOption.defFrameIRQ = GetFrameIRQmode(); + GameOption.defVideoMode = GetVideoMode(); + + // ݒ[hĐݒ肷(Gg΃ftHg) + if( rom->GetMapperNo() != 20 ) { + GameOption.Load( rom->GetPROM_CRC() ); + } else { + GameOption.Load( rom->GetGameID(), rom->GetMakerID() ); + } + SetRenderMethod( (RENDERMETHOD)GameOption.nRenderMethod ); + SetIrqType ( GameOption.nIRQtype ); + SetFrameIRQmode( GameOption.bFrameIRQ ); + SetVideoMode ( GameOption.bVideoMode ); + } catch( CHAR* str ) { + DELETEPTR( cpu ); + DELETEPTR( ppu ); + DELETEPTR( apu ); + DELETEPTR( pad ); + DELETEPTR( rom ); + DELETEPTR( mapper ); + throw str; +#ifndef _DEBUG + } catch( ... ) { + DELETEPTR( cpu ); + DELETEPTR( ppu ); + DELETEPTR( apu ); + DELETEPTR( pad ); + DELETEPTR( rom ); + DELETEPTR( mapper ); + + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + DEBUGOUT( "Starting emulation!\n" ); +} + +NES::~NES() +{ + MovieStop(); + + SaveSRAM(); + SaveDISK(); + SaveTurboFile(); + + DEBUGOUT( "Free NES..." ); + + DELETEPTR( cpu ); + DELETEPTR( ppu ); + DELETEPTR( apu ); + DELETEPTR( pad ); + DELETEPTR( rom ); + DELETEPTR( mapper ); + + DEBUGOUT( "Ok.\n" ); +} + +void NES::SetVideoMode( BOOL bMode ) +{ + bVideoMode = bMode; + if( bVideoMode==0 ) { + nescfg = &NESCONFIG_NTSC; + }else if(bVideoMode==1){ + nescfg = &NESCONFIG_PAL; + }else if(bVideoMode==2){ + nescfg = &NESCONFIG_PALCHINA; + } + apu->SoundSetup(); +} + +void NES::Reset() +{ + SaveSRAM(); + SaveDISK(); + SaveTurboFile(); + + // RAM Clear + ZEROMEMORY( RAM, sizeof(RAM) ); + + // RAM set + if( !rom->IsSAVERAM() && rom->GetMapperNo() != 20 ) { + ::memset( WRAM, 0xFF, sizeof(WRAM) ); + } + + ZEROMEMORY( CRAM, sizeof(CRAM) ); + ZEROMEMORY( YCRAM, sizeof(YCRAM) ); + ZEROMEMORY( VRAM, sizeof(VRAM) ); + + ZEROMEMORY( SPRAM, sizeof(SPRAM) ); + ZEROMEMORY( BGPAL, sizeof(BGPAL) ); + ZEROMEMORY( SPPAL, sizeof(SPPAL) ); + + ZEROMEMORY( CPUREG, sizeof(CPUREG) ); + ZEROMEMORY( PPUREG, sizeof(PPUREG) ); + + m_bDiskThrottle = FALSE; + + SetRenderMethod( PRE_RENDER ); + + if( rom->IsPAL() ) { + SetVideoMode(1); + } + + PROM = rom->GetPROM(); + VROM = rom->GetVROM(); + + PROM_8K_SIZE = rom->GetPROM_SIZE()*2; + PROM_16K_SIZE = rom->GetPROM_SIZE(); + PROM_32K_SIZE = rom->GetPROM_SIZE()/2; + + //for Game Star - Smart Genius (Unl) + if(PROM_16K_SIZE==0xff){ + PROM_8K_SIZE = (rom->GetPROM_SIZE()+1)*2; + PROM_16K_SIZE = rom->GetPROM_SIZE()+1; + PROM_32K_SIZE = (rom->GetPROM_SIZE()+1)/2; + } + + VROM_1K_SIZE = rom->GetVROM_SIZE()*8; + VROM_2K_SIZE = rom->GetVROM_SIZE()*4; + VROM_4K_SIZE = rom->GetVROM_SIZE()*2; + VROM_8K_SIZE = rom->GetVROM_SIZE(); + + // ftHgoN + if( VROM_8K_SIZE ) { + SetVROM_8K_Bank( 0 ); + } else { + SetCRAM_8K_Bank( 0 ); + } + + // ~[ + if( rom->Is4SCREEN() ) { + SetVRAM_Mirror( VRAM_MIRROR4 ); + } else if( rom->IsVMIRROR() ) { + SetVRAM_Mirror( VRAM_VMIRROR ); + } else { + SetVRAM_Mirror( VRAM_HMIRROR ); + } + + apu->SelectExSound( 0 ); + + ppu->Reset(); + mapper->Reset(); + + // Trainer + if( rom->IsTRAINER() ) { + ::memcpy( WRAM+0x1000, rom->GetTRAINER(), 512 ); + } + + pad->Reset(); + cpu->Reset(); + apu->Reset(); + + if( rom->IsNSF() ) { + mapper->Reset(); + } + +// mapper->Reset(); + base_cycles = emul_cycles = 0; +} + +void NES::SoftReset() +{ + pad->Reset(); + cpu->Reset(); + apu->Reset(); + + if( rom->IsNSF() ) { + mapper->Reset(); + } + +// mapper->Reset(); + m_bDiskThrottle = FALSE; + + base_cycles = emul_cycles = 0; +} + +void NES::EmulationCPU( INT basecycles ) +{ + INT cycles; + + base_cycles += basecycles; + cycles = (INT)((base_cycles/12)-emul_cycles); + if( cycles > 0 ) { + emul_cycles += cpu->EXEC( cycles ); + } +} + +void NES::EmulationCPU_BeforeNMI( INT cycles ) +{ + base_cycles += cycles; + emul_cycles += cpu->EXEC( cycles/12 ); +} + +/* + `V[PX + 0 _~[XLC(`悵Ȃ) + 1 - 239 ` + 240 _~[XLC,VBLANKtOON + 241 VINT,NMI + 242-261 VINT + 261 VINT,VBLANKtOOFF +*/ +void NES::EmulateFrame( BOOL bDraw ) +{ +INT scanline = 0; + + // NSFvC̎ + if( rom->IsNSF() ) { + EmulateNSF(); + return; + } + + // Cheat + CheatCodeProcess(); + // + NES_scanline = scanline; + + if( RenderMethod != TILE_RENDER ) { + bZapper = FALSE; + while( TRUE ) { + ppu->SetRenderScanline( scanline ); + + if( scanline == 0 ) { + // _~[XLC + if( RenderMethod < POST_RENDER ) { + EmulationCPU( nescfg->ScanlineCycles ); + ppu->FrameStart(); + ppu->ScanlineNext(); + mapper->HSync( scanline ); + ppu->ScanlineStart(); + } else { + EmulationCPU( nescfg->HDrawCycles ); + ppu->FrameStart(); + ppu->ScanlineNext(); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*32 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } + } else if( scanline < 240 ) { + if( RenderMethod < POST_RENDER ) { + if( RenderMethod == POST_ALL_RENDER ) + EmulationCPU( nescfg->ScanlineCycles ); + if( bDraw ) { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + } else { + if( pad->IsZapperMode() && scanline == ZapperY ) { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + } else { + if( !ppu->IsSprite0( scanline ) ) { + ppu->DummyScanline( scanline ); + } else { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + } + } + } + if( RenderMethod == PRE_ALL_RENDER ) + EmulationCPU( nescfg->ScanlineCycles ); + ppu->ScanlineNext(); // ̈ʒuŃX^[n͉ʂႤ + mapper->HSync( scanline ); + ppu->ScanlineStart(); + } else { + if( RenderMethod == POST_RENDER ) + EmulationCPU( nescfg->HDrawCycles ); + if( bDraw ) { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + } else { + if( pad->IsZapperMode() && scanline == ZapperY ) { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + } else { + if( !ppu->IsSprite0( scanline ) ) { + ppu->DummyScanline( scanline ); + } else { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + } + } + } + if( RenderMethod == PRE_RENDER ) + EmulationCPU( nescfg->HDrawCycles ); + ppu->ScanlineNext(); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*32 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } + } else if( scanline == 240 ) { + mapper->VSync(); + if( RenderMethod < POST_RENDER ) { + EmulationCPU( nescfg->ScanlineCycles ); + mapper->HSync( scanline ); + } else { + EmulationCPU( nescfg->HDrawCycles ); + mapper->HSync( scanline ); + EmulationCPU( nescfg->HBlankCycles ); + } + } else if( scanline <= nescfg->TotalScanlines-1 ) { + pad->VSync(); + + // VBLANK + if( scanline == nescfg->TotalScanlines-1 ) { + ppu->VBlankEnd(); + } + if( RenderMethod < POST_RENDER ) { + if( scanline == nescfg->VBlankLine ) { + ppu->VBlankStart(); + if( PPUREG[0] & PPU_VBLANK_BIT ) { + cpu->NMI(); + } + } + EmulationCPU( nescfg->ScanlineCycles ); + mapper->HSync( scanline ); + } else { + if( scanline == nescfg->VBlankLine ) { + ppu->VBlankStart(); + if( PPUREG[0] & PPU_VBLANK_BIT ) { + cpu->NMI(); + } + } + EmulationCPU( nescfg->HDrawCycles ); + mapper->HSync( scanline ); + EmulationCPU( nescfg->HBlankCycles ); + } + + if( scanline == nescfg->TotalScanlines-1 ) { + break; + } + } + if( pad->IsZapperMode() ) { + if( scanline == ZapperY ) + bZapper = TRUE; + else + bZapper = FALSE; + } + + scanline++; + NES_scanline = scanline; + } + } else { + bZapper = FALSE; + while( TRUE ) { + ppu->SetRenderScanline( scanline ); + + if( scanline == 0 ) { + // _~[XLC + // H-Draw (4fetches*32) + EmulationCPU( FETCH_CYCLES*128 ); + ppu->FrameStart(); + ppu->ScanlineNext(); + EmulationCPU( FETCH_CYCLES*10 ); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*22 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } else if( scanline < 240 ) { + // XN[`(Scanline 1`239) + if( bDraw ) { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + ppu->ScanlineNext(); + EmulationCPU( FETCH_CYCLES*10 ); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*22 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } else { + if( pad->IsZapperMode() && scanline == ZapperY ) { + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + ppu->ScanlineNext(); + EmulationCPU( FETCH_CYCLES*10 ); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*22 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } else { + if( !ppu->IsSprite0( scanline ) ) { + // H-Draw (4fetches*32) + EmulationCPU( FETCH_CYCLES*128 ); + ppu->DummyScanline( scanline ); + ppu->ScanlineNext(); + EmulationCPU( FETCH_CYCLES*10 ); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*22 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } else { +///////--- EmulationCPU( nescfg->HDrawCycles ); + ppu->Scanline( scanline, Config.graphics.bAllSprite, Config.graphics.bLeftClip ); + ppu->ScanlineNext(); + EmulationCPU( FETCH_CYCLES*10 ); + mapper->HSync( scanline ); + EmulationCPU( FETCH_CYCLES*22 ); + ppu->ScanlineStart(); + EmulationCPU( FETCH_CYCLES*10+nescfg->ScanlineEndCycles ); + } + } + } + } else if( scanline == 240 ) { + // _~[XLC (Scanline 240) + mapper->VSync(); + + EmulationCPU( nescfg->HDrawCycles ); + // H-Sync + mapper->HSync( scanline ); + + EmulationCPU( nescfg->HBlankCycles ); + } else if( scanline <= nescfg->TotalScanlines-1 ) { + pad->VSync(); + + // VBLANK + if( scanline == nescfg->TotalScanlines-1 ) { + ppu->VBlankEnd(); + } + if( scanline == nescfg->VBlankLine ) { + ppu->VBlankStart(); + if( PPUREG[0]&PPU_VBLANK_BIT ) { + cpu->NMI(); + } + } + EmulationCPU( nescfg->HDrawCycles ); + + // H-Sync + mapper->HSync( scanline ); + + EmulationCPU( nescfg->HBlankCycles ); + + if( scanline == nescfg->TotalScanlines-1 ) { + break; + } + } + if( pad->IsZapperMode() ) { + if( scanline == ZapperY ) + bZapper = TRUE; + else + bZapper = FALSE; + } + + scanline++; + NES_scanline = scanline; + } + } + + // Movie pad + if( Config.movie.bPadDisplay && bDraw ) { + DrawPad(); + } +} + +void NES::EmulateNSF() +{ +R6502 reg; + + ppu->Reset(); + mapper->VSync(); + +//DEBUGOUT( "Frame\n" ); + + if( m_bNsfPlaying ) { + if( m_bNsfInit ) { + ZEROMEMORY( RAM, sizeof(RAM) ); + if( !(rom->GetNsfHeader()->ExtraChipSelect&0x04) ) { + ZEROMEMORY( WRAM, 0x2000 ); + } + + apu->Reset(); + apu->Write( 0x4015, 0x1F ); + apu->Write( 0x4017, 0xC0 ); + apu->ExWrite( 0x4080, 0x80 ); // FDS Volume 0 + apu->ExWrite( 0x408A, 0xE8 ); // FDS Envelope Speed + + cpu->GetContext( reg ); + reg.PC = 0x4710; // Init Address + reg.A = (BYTE)m_nNsfSongNo; + reg.X = (BYTE)m_nNsfSongMode; + reg.Y = 0; + reg.S = 0xFF; + reg.P = Z_FLAG|R_FLAG|I_FLAG; + cpu->SetContext( reg ); + + // S΍˂Ăă[v(1b) + for( INT i = 0; i < nescfg->TotalScanlines*60; i++ ) { + EmulationCPU( nescfg->ScanlineCycles ); + cpu->GetContext( reg ); + + // [vɓƂmF甲 + if( reg.PC == 0x4700 ) { + break; + } + } + + m_bNsfInit = FALSE; + } + + cpu->GetContext( reg ); + // [vɓĂĐݒ肷 + if( reg.PC == 0x4700 ) { + reg.PC = 0x4720; // Play Address + reg.A = 0; + reg.S = 0xFF; + cpu->SetContext( reg ); + } + + for( INT i = 0; i < nescfg->TotalScanlines; i++ ) { + EmulationCPU( nescfg->ScanlineCycles ); + } + } else { + cpu->GetContext( reg ); + reg.PC = 0x4700; // [v + reg.S = 0xFF; + cpu->SetContext( reg ); + + EmulationCPU( nescfg->ScanlineCycles*nescfg->TotalScanlines ); + } +} + +void NES::SetNsfPlay( INT songno, INT songmode ) +{ + m_bNsfPlaying = TRUE; + m_bNsfInit = TRUE; + m_nNsfSongNo = songno; + m_nNsfSongMode = songmode; +} + +void NES::SetNsfStop() +{ + m_bNsfPlaying = FALSE; + apu->Reset(); +} + +void NES::Clock( INT cycles ) +{ + Tape( cycles ); + Barcode( cycles ); +} + +BYTE NES::Read( WORD addr ) +{ + switch( addr>>13 ) { + case 0x00: // $0000-$1FFF + return RAM[addr&0x07FF]; + case 0x01: // $2000-$3FFF + return ppu->Read( addr&0xE007 ); + case 0x02: // $4000-$5FFF + if( addr < 0x4100 ) { + return ReadReg( addr ); + } else { + return mapper->ReadLow( addr ); + } + break; + case 0x03: // $6000-$7FFF + return mapper->ReadLow( addr ); + case 0x04: // $8000-$9FFF + case 0x05: // $A000-$BFFF + case 0x06: // $C000-$DFFF + case 0x07: // $E000-$FFFF +// return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; + return mapper->Read( addr ); + } + + return 0x00; // Warning\h +} + +void NES::Write( WORD addr, BYTE data ) +{ + switch( addr>>13 ) { + case 0x00: // $0000-$1FFF + RAM[addr&0x07FF] = data; + break; + case 0x01: // $2000-$3FFF + if( !rom->IsNSF() ) { + ppu->Write( addr&0xE01F, data ); + } + break; + case 0x02: // $4000-$5FFF + if( addr < 0x4100 ) { + WriteReg( addr, data ); + } else { + mapper->WriteLow( addr, data ); + } + break; + case 0x03: // $6000-$7FFF + mapper->WriteLow( addr, data ); + break; + case 0x04: // $8000-$9FFF + case 0x05: // $A000-$BFFF + case 0x06: // $C000-$DFFF + case 0x07: // $E000-$FFFF + mapper->Write( addr, data ); + + GenieCodeProcess(); + break; + } +} + +BYTE NES::ReadReg( WORD addr ) +{ + switch( addr & 0xFF ) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0A: case 0x0B: + case 0x0C: case 0x0D: case 0x0E: case 0x0F: + case 0x10: case 0x11: case 0x12: case 0x13: + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + return mapper->ReadExAPU(addr); + return apu->Read( addr ); + break; + case 0x15: + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + return mapper->ReadExAPU(addr); + return apu->Read( addr ); + break; + + case 0x14: + return addr&0xFF; + break; + + case 0x16: + if( rom->IsVSUNISYSTEM() ) { + return pad->Read( addr ); + } else { + return pad->Read( addr ) | 0x40 | m_TapeOut; + } + break; + case 0x17: + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + return mapper->ReadExAPU(addr); + if( rom->IsVSUNISYSTEM() ) { + return pad->Read( addr ); + } else { + return pad->Read( addr ) | apu->Read( addr ); + } + break; + default: + if((NES_ROM_get_unifBoardID(rom->GetBoardName())==643)&&(addr<0x4040)) + return mapper->ReadExAPU(addr); + return mapper->ExRead( addr ); + break; + } +} + +void NES::WriteReg( WORD addr, BYTE data ) +{ + switch( addr & 0xFF ) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0A: case 0x0B: + case 0x0C: case 0x0D: case 0x0E: case 0x0F: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x15: + apu->Write( addr, data ); + CPUREG[addr & 0xFF] = data; + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + mapper->WriteExAPU(addr,data); + break; + + case 0x14: + ppu->DMA( data ); + cpu->DMA( 514 ); // DMA Pending cycle + CPUREG[addr & 0xFF] = data; + break; + + case 0x16: + mapper->ExWrite( addr, data ); // For VS-Unisystem + pad->Write( addr, data ); + CPUREG[addr & 0xFF] = data; + m_TapeIn = data; + break; + case 0x17: + CPUREG[addr & 0xFF] = data; + pad->Write( addr, data ); + apu->Write( addr, data ); + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + mapper->WriteExAPU(addr,data); + break; + // VirtuaNESŗL|[g + case 0x18: + apu->Write( addr, data ); +// if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) +// mapper->WriteExAPU(addr,data); + break; +#if 0 + case 0x1C: + m_dwProfileTempCycle = cpu->GetTotalCycles(); + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + mapper->WriteExAPU(addr,data); + break; + case 0x1D: + m_dwProfileCycle = cpu->GetTotalCycles()-m_dwProfileTempCycle-4; + m_dwProfileTotalCycle += m_dwProfileCycle; + m_dwProfileTotalCount++; + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + mapper->WriteExAPU(addr,data); + break; + case 0x1E: + m_dwProfileTotalCount = 0; + m_dwProfileTotalCycle = 0; + m_dwTotalTempCycle = cpu->GetTotalCycles(); + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + mapper->WriteExAPU(addr,data); + break; + case 0x1F: + m_dwTotalCycle = cpu->GetTotalCycles()-m_dwTotalTempCycle-4; + if(NES_ROM_get_unifBoardID(rom->GetBoardName())==643) + mapper->WriteExAPU(addr,data); + break; +#endif + default: + mapper->ExWrite( addr, data ); + if((NES_ROM_get_unifBoardID(rom->GetBoardName())==643)&&(addr<0x4040)) + mapper->WriteExAPU(addr,data); + break; + } +} + +void NES::LoadSRAM() +{ + if( rom->IsNSF() ) + return; + + ZEROMEMORY( WRAM, sizeof(WRAM) ); + + if( !rom->IsSAVERAM() ) + return; + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "sav" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + DEBUGOUT( "Loading SAVERAM..." ); + + LONG size; + // t@CTCY擾 + ::fseek( fp, 0, SEEK_END ); + size = ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + if( size <= 128*1024 ) { + if( ::fread( WRAM, size, 1, fp ) != 1 ) + throw "File Read error."; + } + + DEBUGOUT( "Ok.\n" ); + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + DEBUGOUT( "Loading SAVERAM Error.\n" ); + DEBUGOUT( "%s\n", str ); +// throw str; +#ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + DEBUGOUT( "Loading SAVERAM Error.\n" ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } +} + +void NES::SaveSRAM() +{ +INT i; + + if( rom->IsNSF() ) + return; + + if( !rom->IsSAVERAM() ) + return; + + for( i = 0; i < SAVERAM_SIZE; i++ ) { + if( WRAM[i] != 0x00 ) + break; + } + + if( i < SAVERAM_SIZE ) { + DEBUGOUT( "Saving SAVERAM...\n" ); + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "sav" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + if( ::fwrite( WRAM, SAVERAM_SIZE, 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + DEBUGOUT( "Ok.\n" ); + FCLOSE( fp ); + } catch( CHAR* str ) { + DEBUGOUT( "Writing SAVERAM Error.\n" ); + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + DEBUGOUT( "Writing SAVERAM Error.\n" ); + FCLOSE( fp ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} + +void NES::LoadDISK() +{ + if( rom->GetMapperNo() != 20 ) + return; + + BOOL bExit = FALSE; + + INT i, j, diskno; + FILE* fp = NULL; + DISKIMGFILEHDR ifh; + DISKIMGHDR hdr; + LPBYTE disk; + + WORD Version; + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "dsv" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + try + { + if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + if( ::fread( &ifh, sizeof(DISKIMGFILEHDR), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + if( ::memcmp( ifh.ID, "VirtuaNES DI", sizeof(ifh.ID) ) == 0 ) { + if( ifh.BlockVersion < 0x0100 && ifh.BlockVersion > 0x200 ) { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + Version = ifh.BlockVersion; + } else { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + + if( Version == 0x0100 ) { + // Ver0.24ȑO + if( ifh.DiskNumber > 4 ) { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + + for( i = 0; i < (INT)ifh.DiskNumber; i++ ) { + if( ::fread( &hdr, sizeof(DISKIMGHDR), 1, fp ) != 1 ) { + if( i == 0 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } else { + break; + } + } + + if( ::memcmp( hdr.ID, "SIDE0A", sizeof(hdr.ID) ) == 0 ) { + diskno = 0; + } else if( ::memcmp( hdr.ID, "SIDE0B", sizeof(hdr.ID) ) == 0 ) { + diskno = 1; + } else if( ::memcmp( hdr.ID, "SIDE1A", sizeof(hdr.ID) ) == 0 ) { + diskno = 2; + } else if( ::memcmp( hdr.ID, "SIDE1B", sizeof(hdr.ID) ) == 0 ) { + diskno = 3; + } else { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + + for( j = 0; j < 16; j++ ) { + if( hdr.DiskTouch[j] ) { + disk = rom->GetPROM()+16+65500*diskno+(4*1024)*j; + if( j < 15 ) { + if( ::fread( disk, 4*1024, 1, fp ) != 1 ) { + bExit = TRUE; + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } else { + if( ::fread( disk, 4*1024-36, 1, fp ) != 1 ) { + bExit = TRUE; + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + } + } + } + } else + if( Version == 0x0200 || Version == 0x0210 ) { + // Ver0.30ȍ~ + DISKFILEHDR dfh; + LPBYTE lpDisk = rom->GetPROM(); + LPBYTE lpWrite = rom->GetDISK(); + LONG DiskSize = 16+65500*rom->GetDiskNo(); + DWORD pos; + BYTE data; + + // FLAG + ::ZeroMemory( lpWrite, 16+65500*rom->GetDiskNo() ); + + // wb_ǂݒ + if( ::fseek( fp, 0, SEEK_SET ) ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + if( ::fread( &dfh, sizeof(DISKFILEHDR), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + if( Config.emulator.bCrcCheck ) { + // ݃[h̃^CgƈႤ`FbN + if( dfh.ProgID != rom->GetGameID() + || dfh.MakerID != (WORD)rom->GetMakerID() + || dfh.DiskNo != (WORD)rom->GetDiskNo() ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + + for( i = 0; i < dfh.DifferentSize; i++ ) { + if( ::fread( &pos, sizeof(DWORD), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + bExit = TRUE; + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + data = (BYTE)(pos>>24); + pos &= 0x00FFFFFF; + if( pos >= 16 && pos < DiskSize ) { + lpDisk[pos] = data; + lpWrite[pos] = 0xFF; + } + } + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + DEBUGOUT( "%s\n", str ); + if( bExit ) + throw str; +#ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + DEBUGOUT( "Loading DISKIMAGE Error.\n" ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } +} + +void NES::SaveDISK() +{ + if( rom->GetMapperNo() != 20 ) + return; + + INT i; + FILE* fp = NULL; + DISKFILEHDR ifh; + LPBYTE lpDisk = rom->GetPROM(); + LPBYTE lpWrite = rom->GetDISK(); + LONG DiskSize = 16+65500*rom->GetDiskNo(); + DWORD data; + + try + { + ::ZeroMemory( &ifh, sizeof(ifh) ); + + ::memcpy( ifh.ID, "VirtuaNES DI", sizeof(ifh.ID) ); + ifh.BlockVersion = 0x0210; + ifh.ProgID = rom->GetGameID(); + ifh.MakerID = (WORD)rom->GetMakerID(); + ifh.DiskNo = (WORD)rom->GetDiskNo(); + + // ᐔJEg + for( i = 16; i < DiskSize; i++ ) { + if( lpWrite[i] ) + ifh.DifferentSize++; + } + + if( !ifh.DifferentSize ) + return; + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "dsv" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + if( ::fwrite( &ifh, sizeof(DISKFILEHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + for( i = 16; i < DiskSize; i++ ) { + if( lpWrite[i] ) { + data = i & 0x00FFFFFF; + data |= ((DWORD)lpDisk[i]&0xFF)<<24; + + // Write File + if( ::fwrite( &data, sizeof(DWORD), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + DEBUGOUT( "%s\n", str ); +#ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + DEBUGOUT( "Saving DISKIMAGE Error.\n" ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } +} + +void NES::LoadTurboFile() +{ + ZEROMEMORY( ERAM, sizeof(ERAM) ); + + if( pad->GetExController() != PAD::EXCONTROLLER_TURBOFILE ) + return; + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), "TurboFile", "vtf" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "rb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + DEBUGOUT( "Loading TURBOFILE..." ); + + LONG size; + // t@CTCY擾 + ::fseek( fp, 0, SEEK_END ); + size = ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + if( size > 32*1024 ) { + size = 32*1024; + } + if( ::fread( ERAM, size, 1, fp ) != 1 ) + throw "File Read error."; + + DEBUGOUT( "Ok.\n" ); + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + DEBUGOUT( "Loading TurboFile Error.\n" ); + DEBUGOUT( "%s\n", str ); +// throw str; +#ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + DEBUGOUT( "Loading TurboFile Error.\n" ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } +} + +void NES::SaveTurboFile() +{ +INT i; + + if( pad->GetExController() != PAD::EXCONTROLLER_TURBOFILE ) + return; + + for( i = 0; i < sizeof(ERAM); i++ ) { + if( ERAM[i] != 0x00 ) + break; + } + + if( i < sizeof(ERAM) ) { + DEBUGOUT( "Saving TURBOFILE...\n" ); + + string pathstr, tempstr; + if( Config.path.bSavePath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSavePath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), "TurboFile", "vtf" ); + DEBUGOUT( "Path: %s\n", tempstr.c_str() ); + + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + if( ::fwrite( ERAM, sizeof(ERAM), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + DEBUGOUT( "Ok.\n" ); + FCLOSE( fp ); + } catch( CHAR* str ) { + DEBUGOUT( "Writing TurboFile Error.\n" ); + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + DEBUGOUT( "Writing TurboFile Error.\n" ); + FCLOSE( fp ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} + +INT NES::IsStateFile( const char* fname, ROM* rom ) +{ +FILE* fp = NULL; +FILEHDR2 header; + + if( !(fp = ::fopen( fname, "rb" )) ) + return -1; + + if( ::fread( &header, sizeof(header), 1, fp ) != 1 ) { + FCLOSE( fp ); + return -1; + } + FCLOSE( fp ); + + if( ::memcmp( header.ID, "VirtuaNES ST", sizeof(header.ID) ) == 0 ) { + if( header.BlockVersion < 0x0100 ) + return 0; + + if( Config.emulator.bCrcCheck ) { + if( header.BlockVersion >= 0x200 ) { + if( rom->GetMapperNo() != 20 ) { + // FDSȊO + if( header.Ext0 != rom->GetPROM_CRC() ) { + return IDS_ERROR_ILLEGALSTATECRC; // Ⴄ + } + } else { + // FDS + if( header.Ext0 != rom->GetGameID() || + header.Ext1 != (WORD)rom->GetMakerID() || + header.Ext2 != (WORD)rom->GetDiskNo() ) + return IDS_ERROR_ILLEGALSTATECRC; // Ⴄ + } + } + } + return 0; + } + return -1; +} + +BOOL NES::LoadState( const char* fname ) +{ +FILE* fp = NULL; +BOOL bRet = FALSE; + + if( rom->IsNSF() ) + return TRUE; + + try { + if( !(fp = ::fopen( fname, "rb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + + bRet = ReadState( fp ); + + FCLOSE( fp ); + } catch( CHAR* str ) { + DEBUGOUT( "State load error.\n" ); + DEBUGOUT( "%s\n", str ); + FCLOSE( fp ); + return FALSE; +#ifndef _DEBUG + } catch(...) { + DEBUGOUT( "State load error.\n" ); + FCLOSE( fp ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + return bRet; +} + +BOOL NES::SaveState( const char* fname ) +{ +FILE* fp = NULL; + + if( rom->IsNSF() ) + return TRUE; + + try { + if( !(fp = ::fopen( fname, "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + + WriteState( fp ); + + FCLOSE( fp ); + } catch( CHAR* str ) { + DEBUGOUT( "State save error.\n" ); + FCLOSE( fp ); + throw str; +#ifndef _DEBUG + } catch(...) { + DEBUGOUT( "State save error.\n" ); + FCLOSE( fp ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + return TRUE; +} + +BOOL NES::ReadState( FILE* fp ) +{ + INT i; + BOOL bHeader = FALSE; + WORD Version = 0; + + BLOCKHDR hdr; + INT type; + + while( TRUE ) { + // Read File + if( ::fread( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) + break; + + // File Header check + if( !bHeader ) { + LPFILEHDR fh = (LPFILEHDR)&hdr; + if( ::memcmp( fh->ID, "VirtuaNES ST", sizeof(fh->ID) ) == 0 ) { + Version = fh->BlockVersion; + if( Version == 0x0100 ) { + // Ver0.24܂ + bHeader = TRUE; + // Âz̓[r[̓[ho܂ + if( m_bMoviePlay ) { + return FALSE; + } + // ÂzFDS̓[ho܂ + if( rom->GetMapperNo() == 20 ) { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + } else + if( Version == 0x0200 || Version == 0x0210 ) { + // Ver0.30ȍ~ Ver0.60ȍ~ + FILEHDR2 hdr2; + // wb_ǂݒ + if( ::fseek( fp, -sizeof(BLOCKHDR), SEEK_CUR ) ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + // Read File + if( ::fread( &hdr2, sizeof(FILEHDR2), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + +#if 0 + if( Config.emulator.bCrcCheck ) { + // ݃[h̃^CgƈႤ`FbN + if( rom->GetMapperNo() != 20 ) { + // FDSȊO + if( hdr2.Ext0 != rom->GetPROM_CRC() ) { + return FALSE; // Ⴄ + } + } else { + // FDS + if( hdr2.Ext0 != rom->GetGameID() || + hdr2.Ext1 != (WORD)rom->GetMakerID() || + hdr2.Ext2 != (WORD)rom->GetDiskNo() ) + return FALSE; // Ⴄ + } + } +#endif + + // [r[̓t@C|C^ƃXebv + // ύXāC[r[L^[hɕύX + if( m_bMoviePlay || m_bMovieRec ) { + // B蒼”\H + if( m_hedMovie.Control & 0x80 ) { + if( hdr2.MovieOffset && hdr2.MovieStep ) { + if( m_bMoviePlay ) { + // Đ + // Xe[g̃XebvL^ił_ + if( hdr2.MovieStep > m_hedMovie.MovieStep ) + return FALSE; + } else { + // L^ + // Xe[g̃Xebv݂ił_ + if( hdr2.MovieStep > m_MovieStep ) + return FALSE; + } +//DEBUGOUT( "LD STEP=%d POS=%d\n", hdr2.MovieStep, hdr2.MovieOffset ); + + m_bMoviePlay = FALSE; + m_bMovieRec = TRUE; + m_MovieStep = hdr2.MovieStep; + m_hedMovie.RecordTimes++; // B蒼+1 + if( ::fseek( m_fpMovie, hdr2.MovieOffset, SEEK_SET ) ) { +//DEBUGOUT( "MOVIE:STATE LOAD SEEK s\n" ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } + } + bHeader = TRUE; + continue; + } + } + + if( !bHeader ) { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + +//DEBUGOUT( "HEADER ID=%8s\n", hdr.ID ); + + type = -1; + if( ::memcmp( hdr.ID, "REG DATA", sizeof(hdr.ID) ) == 0 ) + type = 0; + if( ::memcmp( hdr.ID, "RAM DATA", sizeof(hdr.ID) ) == 0 ) + type = 1; + if( ::memcmp( hdr.ID, "MMU DATA", sizeof(hdr.ID) ) == 0 ) + type = 2; + if( ::memcmp( hdr.ID, "MMC DATA", sizeof(hdr.ID) ) == 0 ) + type = 3; + if( ::memcmp( hdr.ID, "CTR DATA", sizeof(hdr.ID) ) == 0 ) + type = 4; + if( ::memcmp( hdr.ID, "SND DATA", sizeof(hdr.ID) ) == 0 ) + type = 5; + + if( rom->GetMapperNo() == 20 ) { + if( ::memcmp( hdr.ID, "DISKDATA", sizeof(hdr.ID) ) == 0 ) + type = 6; + } + + if( type == -1 ) { +//DEBUGOUT( "UNKNOWN HEADER ID=%8s\n", hdr.ID ); + break; + } + + switch( type ) { + case 0: + // REGISTER STATE + { + if( hdr.BlockVersion < 0x0200 ) { + REGSTAT_O reg; + if( ::fread( ®, sizeof(REGSTAT_O), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + // LOAD CPU STATE + R6502 R; + R.PC = reg.cpureg.cpu.PC; + R.A = reg.cpureg.cpu.A; + R.X = reg.cpureg.cpu.X; + R.Y = reg.cpureg.cpu.Y; + R.S = reg.cpureg.cpu.S; + R.P = reg.cpureg.cpu.P; + R.INT_pending = reg.cpureg.cpu.I; + cpu->SetContext( R ); +// FrameIRQ = reg.cpureg.cpu.FrameIRQ; + + if( hdr.BlockVersion < 0x0110 ) { + emul_cycles = 0; + base_cycles = reg.cpureg.cpu.mod_cycles; + } else if( hdr.BlockVersion == 0x0110 ) { +// FrameIRQ_cycles = reg.cpureg.cpu.mod_cycles; + emul_cycles = reg.cpureg.cpu.emul_cycles; + base_cycles = reg.cpureg.cpu.base_cycles; + } + + // LOAD PPU STATE + PPUREG[0] = reg.ppureg.ppu.reg0; + PPUREG[1] = reg.ppureg.ppu.reg1; + PPUREG[2] = reg.ppureg.ppu.reg2; + PPUREG[3] = reg.ppureg.ppu.reg3; + PPU7_Temp = reg.ppureg.ppu.reg7; + loopy_t = reg.ppureg.ppu.loopy_t; + loopy_v = reg.ppureg.ppu.loopy_v; + loopy_x = reg.ppureg.ppu.loopy_x; + PPU56Toggle = reg.ppureg.ppu.toggle56; + } else { + REGSTAT reg; + if( ::fread( ®, sizeof(REGSTAT), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + // LOAD CPU STATE + R6502 R; + R.PC = reg.cpureg.cpu.PC; + R.A = reg.cpureg.cpu.A; + R.X = reg.cpureg.cpu.X; + R.Y = reg.cpureg.cpu.Y; + R.S = reg.cpureg.cpu.S; + R.P = reg.cpureg.cpu.P; + R.INT_pending = reg.cpureg.cpu.I; + cpu->SetContext( R ); + + if( hdr.BlockVersion == 0x0200 ) { +// FrameIRQ = reg.cpureg.cpu.FrameIRQ; +// bFrameIRQ_occur = (reg.cpureg.cpu.FrameIRQ_occur!=0)?TRUE:FALSE; +// FrameIRQ_cycles = reg.cpureg.cpu.FrameIRQ_cycles; + } else { + apu->SetFrameIRQ( reg.cpureg.cpu.FrameIRQ_cycles, + reg.cpureg.cpu.FrameIRQ_count, + reg.cpureg.cpu.FrameIRQ_type, + reg.cpureg.cpu.FrameIRQ, + reg.cpureg.cpu.FrameIRQ_occur ); + } + + emul_cycles = reg.cpureg.cpu.emul_cycles; + base_cycles = reg.cpureg.cpu.base_cycles; + + cpu->SetDmaCycles( (INT)reg.cpureg.cpu.DMA_cycles ); + + // LOAD PPU STATE + PPUREG[0] = reg.ppureg.ppu.reg0; + PPUREG[1] = reg.ppureg.ppu.reg1; + PPUREG[2] = reg.ppureg.ppu.reg2; + PPUREG[3] = reg.ppureg.ppu.reg3; + PPU7_Temp = reg.ppureg.ppu.reg7; + loopy_t = reg.ppureg.ppu.loopy_t; + loopy_v = reg.ppureg.ppu.loopy_v; + loopy_x = reg.ppureg.ppu.loopy_x; + PPU56Toggle = reg.ppureg.ppu.toggle56; + } + + // APU STATE + // L[ + apu->QueueClear(); + +// APUXe[gۑ悤ɂ̂Ń +// // DMC͎~߂ȂƂ܂N +// for( i = 0x4010; i <= 0x4013; i++ ) { +// apu->Write( i, 0 ); +// } + } + break; + case 1: + // RAM STATE + { + RAMSTAT ram; + if( ::fread( &ram, sizeof(RAMSTAT), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + ::memcpy( RAM, ram.RAM, sizeof(ram.RAM) ); + ::memcpy( BGPAL, ram.BGPAL, sizeof(ram.BGPAL) ); + ::memcpy( SPPAL, ram.SPPAL, sizeof(ram.SPPAL) ); + ::memcpy( SPRAM, ram.SPRAM, sizeof(ram.SPRAM) ); + if( rom->IsSAVERAM() ) { + if( ::fread( WRAM, SAVERAM_SIZE, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + } + break; + case 2: + // BANK STATE + { + MMUSTAT mmu; + if( ::fread( &mmu, sizeof(MMUSTAT), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + if( hdr.BlockVersion == 0x100 ) { + // ƑÕo[W + if( mmu.CPU_MEM_TYPE[3] == BANKTYPE_RAM + || mmu.CPU_MEM_TYPE[3] == BANKTYPE_DRAM ) { + if( ::fread( CPU_MEM_BANK[3], 8*1024, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } else if( !rom->IsSAVERAM() ) { + SetPROM_8K_Bank( 3, mmu.CPU_MEM_PAGE[3] ); + } + // oN0`3ȊO[h + for( i = 4; i < 8; i++ ) { + CPU_MEM_TYPE[i] = mmu.CPU_MEM_TYPE[i]; + CPU_MEM_PAGE[i] = mmu.CPU_MEM_PAGE[i]; + if( CPU_MEM_TYPE[i] == BANKTYPE_ROM ) { + SetPROM_8K_Bank( i, CPU_MEM_PAGE[i] ); + } else { + if( ::fread( CPU_MEM_BANK[i], 8*1024, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + } + } else if( hdr.BlockVersion == 0x200 ) { + // ŐVo[W + // SRAMĂS[hȂ + for( i = 3; i < 8; i++ ) { + CPU_MEM_TYPE[i] = mmu.CPU_MEM_TYPE[i]; + CPU_MEM_PAGE[i] = mmu.CPU_MEM_PAGE[i]; + if( CPU_MEM_TYPE[i] == BANKTYPE_ROM ) { + SetPROM_8K_Bank( i, CPU_MEM_PAGE[i] ); + } else { + if( ::fread( CPU_MEM_BANK[i], 8*1024, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + } + } + // VRAM + if( ::fread( VRAM, 4*1024, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + // CRAM + for( i = 0; i < 8; i++ ) { + if( mmu.CRAM_USED[i] != 0 ) { + if( ::fread( &CRAM[0x1000*i], 4*1024, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + } + // BANK + for( i = 0; i < 12; i++ ) { + if( mmu.PPU_MEM_TYPE[i] == BANKTYPE_VROM ) { + //SetCRAM_1K_Bank( i, mmu.PPU_MEM_PAGE[i] ); + SetVROM_1K_Bank( i, mmu.PPU_MEM_PAGE[i] ); + } else if( mmu.PPU_MEM_TYPE[i] == BANKTYPE_CRAM ) { + SetCRAM_1K_Bank( i, mmu.PPU_MEM_PAGE[i] ); + } else if( mmu.PPU_MEM_TYPE[i] == BANKTYPE_VRAM ) { + SetVRAM_1K_Bank( i, mmu.PPU_MEM_PAGE[i] ); + } else { + throw "Unknown bank types."; + } + } + + // for mapper 74 + if(ppu->IsVromWrite()){ + int cb = 0; + for(i=0; i<256; i++){ + if(VROM_WRITED[i]){ + memcpy(VROM+0x400*i, CRAM+0x0400*cb, 0x0400); + cb++; + if(cb>27){ + break; + } + } + } + } + } + break; + case 3: + // MMC STATE + { + MMCSTAT mmc; + if( ::fread( &mmc, sizeof(MMCSTAT), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + mapper->LoadState( mmc.mmcdata ); + } + break; + case 4: + // CTR STATE + { + CTRSTAT ctr; + if( ::fread( &ctr, sizeof(CTRSTAT), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + pad->pad1bit = ctr.ctrreg.ctr.pad1bit; + pad->pad2bit = ctr.ctrreg.ctr.pad2bit; + pad->pad3bit = ctr.ctrreg.ctr.pad3bit; + pad->pad4bit = ctr.ctrreg.ctr.pad4bit; + pad->SetStrobe( (ctr.ctrreg.ctr.strobe!=0)?TRUE:FALSE ); + } + break; + + case 5: + // SND STATE + { + SNDSTAT snd; + if( ::fread( &snd, sizeof(SNDSTAT), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + apu->LoadState( snd.snddata ); + } + break; + + // Disk Images + // Ver0.30ȍ~ + case 6: + { + DISKDATA ddata; + DWORD pos; + BYTE data; + LONG DiskSize = 16+65500*rom->GetDiskNo(); + LPBYTE lpDisk = rom->GetPROM(); + LPBYTE lpWrite = rom->GetDISK(); + + // FLAG + ::ZeroMemory( lpWrite, 16+65500*rom->GetDiskNo() ); + + if( ::fread( &ddata, sizeof(DISKDATA), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + for( i = 0; i < ddata.DifferentSize; i++ ) { + if( ::fread( &pos, sizeof(DWORD), 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + data = (BYTE)(pos>>24); + pos &= 0x00FFFFFF; + if( pos >= 16 && pos < DiskSize ) { + lpDisk[pos] = data; + lpWrite[pos] = 0xFF; + } + } + + } + break; + } + } + + return TRUE; +} + +void NES::WriteState( FILE* fp ) +{ + INT i; + + // HEADER + { + FILEHDR2 hdr; + + ZEROMEMORY( &hdr, sizeof(FILEHDR2) ); + ::memcpy( hdr.ID, "VirtuaNES ST", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0200; + + if( rom->GetMapperNo() != 20 ) { + hdr.Ext0 = rom->GetPROM_CRC(); + } else { + hdr.Ext0 = rom->GetGameID(); + hdr.Ext1 = (WORD)rom->GetMakerID(); + hdr.Ext2 = (WORD)rom->GetDiskNo(); + } + + // [r[ĐL^ł΂̈ʒuL^ + if( m_bMoviePlay || m_bMovieRec ) { + hdr.MovieStep = m_MovieStep; + hdr.MovieOffset = ::ftell( m_fpMovie ); +//DEBUGOUT( "\nSV STEP=%d POS=%d\n", m_MovieStep, hdr.MovieOffset ); + } + + // Write File + if( ::fwrite( &hdr, sizeof(FILEHDR2), 1, fp ) != 1 ) + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + BLOCKHDR hdr; + + // REGISTER STATE + { + REGSTAT reg; + + ZEROMEMORY( &hdr, sizeof(BLOCKHDR) ); + ZEROMEMORY( ®, sizeof(REGSTAT) ); + + // Create Header + ::memcpy( hdr.ID, "REG DATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0210; + hdr.BlockSize = sizeof(REGSTAT); + + // SAVE CPU STATE + R6502 R; + cpu->GetContext( R ); + + reg.cpureg.cpu.PC = R.PC; + reg.cpureg.cpu.A = R.A; + reg.cpureg.cpu.X = R.X; + reg.cpureg.cpu.Y = R.Y; + reg.cpureg.cpu.S = R.S; + reg.cpureg.cpu.P = R.P; + reg.cpureg.cpu.I = R.INT_pending; + + INT cycles; + apu->GetFrameIRQ( cycles, + reg.cpureg.cpu.FrameIRQ_count, + reg.cpureg.cpu.FrameIRQ_type, + reg.cpureg.cpu.FrameIRQ, + reg.cpureg.cpu.FrameIRQ_occur ); + reg.cpureg.cpu.FrameIRQ_cycles = (LONG)cycles; // QƂINTȈׁi + + reg.cpureg.cpu.DMA_cycles = (LONG)cpu->GetDmaCycles(); + reg.cpureg.cpu.emul_cycles = emul_cycles; + reg.cpureg.cpu.base_cycles = base_cycles; + + // SAVE PPU STATE + reg.ppureg.ppu.reg0 = PPUREG[0]; + reg.ppureg.ppu.reg1 = PPUREG[1]; + reg.ppureg.ppu.reg2 = PPUREG[2]; + reg.ppureg.ppu.reg3 = PPUREG[3]; + reg.ppureg.ppu.reg7 = PPU7_Temp; + reg.ppureg.ppu.loopy_t = loopy_t; + reg.ppureg.ppu.loopy_v = loopy_v; + reg.ppureg.ppu.loopy_x = loopy_x; + reg.ppureg.ppu.toggle56 = PPU56Toggle; + + // Write File + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( ::fwrite( ®, sizeof(REGSTAT), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + + // RAM STATE + { + RAMSTAT ram; + DWORD size = 0; + + ::ZeroMemory( &hdr, sizeof(BLOCKHDR) ); + ::ZeroMemory( &ram, sizeof(RAMSTAT) ); + + // SAVE RAM STATE + ::memcpy( ram.RAM, RAM, sizeof(ram.RAM) ); + ::memcpy( ram.BGPAL, BGPAL, sizeof(ram.BGPAL) ); + ::memcpy( ram.SPPAL, SPPAL, sizeof(ram.SPPAL) ); + ::memcpy( ram.SPRAM, SPRAM, sizeof(ram.SPRAM) ); + + // S-RAM STATE(gp/gpɊւ炸݂΃Z[u) + if( rom->IsSAVERAM() ) { + size = SAVERAM_SIZE; + } + + // Create Header + ::memcpy( hdr.ID, "RAM DATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0100; + hdr.BlockSize = size+sizeof(RAMSTAT); + + // Write File + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( ::fwrite( &ram, sizeof(RAMSTAT), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( rom->IsSAVERAM() ) { + if( ::fwrite( WRAM, SAVERAM_SIZE, 1, fp ) != 1 ) + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + + // BANK STATE + { + MMUSTAT mmu; + DWORD size; + + ::ZeroMemory( &hdr, sizeof(BLOCKHDR) ); + ::ZeroMemory( &mmu, sizeof(MMUSTAT) ); + + size = 0; + // SAVE CPU MEMORY BANK DATA + // BANK0,1,2̓oNZ[uɊ֌WȂ + // VirtuaNES0.30 + // oNRSRAMgpɊւ炸Z[u + for( i = 3; i < 8; i++ ) { + mmu.CPU_MEM_TYPE[i] = CPU_MEM_TYPE[i]; + mmu.CPU_MEM_PAGE[i] = CPU_MEM_PAGE[i]; + + if( CPU_MEM_TYPE[i] == BANKTYPE_RAM + || CPU_MEM_TYPE[i] == BANKTYPE_DRAM ) { + size += 8*1024; // 8K BANK + } + } + + // SAVE VRAM MEMORY DATA + for( i = 0; i < 12; i++ ) { + mmu.PPU_MEM_TYPE[i] = PPU_MEM_TYPE[i]; + mmu.PPU_MEM_PAGE[i] = PPU_MEM_PAGE[i]; + } + size += 4*1024; // 1K BANK x 4 (VRAM) + + // for mapper 74 + if(ppu->IsVromWrite()){ + int cb = 0; + for(i=0; i<256; i++){ + if(VROM_WRITED[i]){ + memcpy(CRAM+0x0400*cb, VROM+0x400*i, 0x0400); + CRAM_USED[cb>>2] = 1; + size += 1024; + cb++; + if(cb>27){ + break; + } + } + } + CRAM_USED[7] = 1; + size += 4*1024; + } + + for( i = 0; i < 8; i++ ) { + mmu.CRAM_USED[i] = CRAM_USED[i]; + if( CRAM_USED[i] != 0 ) { + size += 4*1024; // 4K BANK + } + } + + // Create Header + ::memcpy( hdr.ID, "MMU DATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0200; + hdr.BlockSize = size+sizeof(MMUSTAT); + + // Write File + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( ::fwrite( &mmu, sizeof(MMUSTAT), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + // WRITE CPU RAM MEMORY BANK + for( i = 3; i < 8; i++ ) { + if( mmu.CPU_MEM_TYPE[i] != BANKTYPE_ROM ) { + if( ::fwrite( CPU_MEM_BANK[i], 8*1024, 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + } + // WRITE VRAM MEMORY(4Kׂď) + if( ::fwrite( VRAM, 4*1024, 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + // WRITE CRAM MEMORY + for( i = 0; i < 8; i++ ) { + if( CRAM_USED[i] != 0 ) { + if( ::fwrite( &CRAM[0x1000*i], 4*1024, 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + } + } + + // MMC STATE + { + MMCSTAT mmc; + + ::ZeroMemory( &hdr, sizeof(BLOCKHDR) ); + ::ZeroMemory( &mmc, sizeof(MMCSTAT) ); + + // Create Header + ::memcpy( hdr.ID, "MMC DATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0100; + hdr.BlockSize = sizeof(MMCSTAT); + + if( mapper->IsStateSave() ) { + mapper->SaveState( mmc.mmcdata ); + // Write File + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( ::fwrite( &mmc, sizeof(MMCSTAT), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + } + + // CONTROLLER STATE + { + CTRSTAT ctr; + + ::ZeroMemory( &hdr, sizeof(BLOCKHDR) ); + ::ZeroMemory( &ctr, sizeof(CTRSTAT) ); + + // Create Header + ::memcpy( hdr.ID, "CTR DATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0100; + hdr.BlockSize = sizeof(CTRSTAT); + + ctr.ctrreg.ctr.pad1bit = pad->pad1bit; + ctr.ctrreg.ctr.pad2bit = pad->pad2bit; + ctr.ctrreg.ctr.pad3bit = pad->pad3bit; + ctr.ctrreg.ctr.pad4bit = pad->pad4bit; + ctr.ctrreg.ctr.strobe = pad->GetStrobe()?0xFF:0; +//DEBUGOUT( "SV pad1bit=%08X Strobe=%d\n", pad->pad1bit, pad->GetStrobe()?1:0 ); + + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + if( ::fwrite( &ctr, sizeof(CTRSTAT), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + + // SND STATE + { + SNDSTAT snd; + + ::ZeroMemory( &hdr, sizeof(BLOCKHDR) ); + ::ZeroMemory( &snd, sizeof(SNDSTAT) ); + + // Create Header + ::memcpy( hdr.ID, "SND DATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0100; + hdr.BlockSize = sizeof(SNDSTAT); + + apu->SaveState( snd.snddata ); + + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + if( ::fwrite( &snd, sizeof(SNDSTAT), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + + // DISKIMAGE STATE + if( rom->GetMapperNo() == 20 ) + { + DISKDATA dsk; + LPBYTE lpDisk = rom->GetPROM(); + LPBYTE lpWrite = rom->GetDISK(); + LONG DiskSize = 16+65500*rom->GetDiskNo(); + DWORD data; + + ::ZeroMemory( &hdr, sizeof(BLOCKHDR) ); + ::ZeroMemory( &dsk, sizeof(DISKDATA) ); + + // ᐔJEg + for( i = 16; i < DiskSize; i++ ) { + if( lpWrite[i] ) + dsk.DifferentSize++; + } + + ::memcpy( hdr.ID, "DISKDATA", sizeof(hdr.ID) ); + hdr.BlockVersion = 0x0210; + hdr.BlockSize = 0; + + // Write File + if( ::fwrite( &hdr, sizeof(BLOCKHDR), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + // Write File + if( ::fwrite( &dsk, sizeof(DISKDATA), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + for( i = 16; i < DiskSize; i++ ) { + if( lpWrite[i] ) { + data = i & 0x00FFFFFF; + data |= ((DWORD)lpDisk[i]&0xFF)<<24; + + // Write File + if( ::fwrite( &data, sizeof(DWORD), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + } + } +} + +INT NES::GetDiskNo() +{ + return rom->GetDiskNo(); +} + +void NES::SoundSetup() +{ + apu->SoundSetup(); +} + +void NES::Command( NESCOMMAND cmd ) +{ + CommandParam( cmd, 0 ); +} + +BOOL NES::CommandParam( NESCOMMAND cmd, INT param ) +{ + switch( cmd ) { + case NESCMD_NONE: + break; + case NESCMD_DISK_THROTTLE_ON: + if( Config.emulator.bDiskThrottle ) { + m_bDiskThrottle = TRUE; + } + break; + case NESCMD_DISK_THROTTLE_OFF: + m_bDiskThrottle = FALSE; + break; + case NESCMD_DISK_EJECT: + mapper->ExCmdWrite( Mapper::EXCMDWR_DISKEJECT, 0 ); + m_CommandRequest = (INT)cmd; + break; + case NESCMD_DISK_0A: + if( rom->GetDiskNo() > 0 ) { + mapper->ExCmdWrite( Mapper::EXCMDWR_DISKINSERT, 0 ); + m_CommandRequest = (INT)cmd; + } + break; + case NESCMD_DISK_0B: + if( rom->GetDiskNo() > 1 ) { + mapper->ExCmdWrite( Mapper::EXCMDWR_DISKINSERT, 1 ); + m_CommandRequest = (INT)cmd; + } + break; + case NESCMD_DISK_1A: + if( rom->GetDiskNo() > 2 ) { + mapper->ExCmdWrite( Mapper::EXCMDWR_DISKINSERT, 2 ); + m_CommandRequest = (INT)cmd; + } + break; + case NESCMD_DISK_1B: + if( rom->GetDiskNo() > 3 ) { + mapper->ExCmdWrite( Mapper::EXCMDWR_DISKINSERT, 3 ); + m_CommandRequest = (INT)cmd; + } + break; + + case NESCMD_HWRESET: + Reset(); + m_CommandRequest = (INT)cmd; + break; + case NESCMD_SWRESET: + SoftReset(); + m_CommandRequest = (INT)cmd; + break; + + case NESCMD_EXCONTROLLER: + pad->SetExController( param&0xFF ); + m_CommandRequest = 0x0100|(param&0xFF); + break; + + case NESCMD_SOUND_MUTE: + return apu->SetChannelMute( (BOOL)param ); // ^[l͕ύX̃~[g + } + + return TRUE; +} + +BOOL NES::Snapshot() +{ +FILE* fp = NULL; + + try { + SYSTEMTIME now; + ::GetLocalTime( &now ); + + CHAR name[_MAX_PATH]; + + if( !Config.emulator.bPNGsnapshot ) { + sprintf( name, "%s %04d%02d%02d%02d%02d%02d%01d.bmp", rom->GetRomName(), + now.wYear, now.wMonth, now.wDay, now.wHour, now.wMinute, now.wSecond, now.wMilliseconds/100 ); + } else { + sprintf( name, "%s %04d%02d%02d%02d%02d%02d%01d.png", rom->GetRomName(), + now.wYear, now.wMonth, now.wDay, now.wHour, now.wMinute, now.wSecond, now.wMilliseconds/100 ); + } + + string pathstr, tempstr; + if( Config.path.bSnapshotPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szSnapshotPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePath( pathstr.c_str(), name ); + DEBUGOUT( "Snapshot: %s\n", tempstr.c_str() ); + + if( !Config.emulator.bPNGsnapshot ) { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + + LPBYTE lpScn = ppu->GetScreenPtr(); + + BITMAPFILEHEADER bfh; + BITMAPINFOHEADER bih; + RGBQUAD rgb[256]; + + ZEROMEMORY( &bfh, sizeof(bfh) ); + ZEROMEMORY( &bih, sizeof(bih) ); + ZEROMEMORY( rgb, sizeof(rgb) ); + + bfh.bfType = 0x4D42; // 'BM' + bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256; + bfh.bfSize = bfh.bfOffBits+256*240; + + bih.biSize = sizeof(bih); + bih.biWidth = 256; + bih.biHeight = 240; + bih.biPlanes = 1; + bih.biBitCount = 8; + bih.biCompression = BI_RGB; + bih.biSizeImage = 0; + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 256; + bih.biClrImportant = 0; + + DirectDraw.GetPaletteData( rgb ); + + if( ::fwrite( &bfh, sizeof(bfh), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( ::fwrite( &bih, sizeof(bih), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + if( ::fwrite( &rgb, sizeof(rgb), 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + lpScn += 8; + for( INT i = 239; i >= 0; i-- ) { + if( ::fwrite( &lpScn[(256+16)*i], 256, 1, fp ) != 1 ) { + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + + FCLOSE( fp ); + } else { + LPBYTE lpScn = ppu->GetScreenPtr(); + RGBQUAD rgb[256]; + ZEROMEMORY( rgb, sizeof(rgb) ); + DirectDraw.GetPaletteData( rgb ); + + PNGWRITE png; + + png.Write( tempstr.c_str(), 256, 240, rgb, lpScn+8, CDirectDraw::RENDER_WIDTH ); + } + } catch( CHAR* str ) { + DEBUGOUT( "Snapshot error.\n" ); + FCLOSE( fp ); + throw str; +#ifndef _DEBUG + } catch(...) { + DEBUGOUT( "Snapshot error.\n" ); + FCLOSE( fp ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + return TRUE; +} + +INT NES::IsMovieFile( const char* fname, ROM* rom ) +{ +FILE* fp = NULL; +MOVIEFILEHDR header; + + if( !(fp = ::fopen( fname, "rb" )) ) + return -1; + + if( ::fread( &header, sizeof(header), 1, fp ) != 1 ) { + FCLOSE( fp ); + return -1; + } + FCLOSE( fp ); + + if( ::memcmp( header.ID, "VirtuaNES MV", sizeof(header.ID) ) == 0 ) { + if( header.BlockVersion < 0x0300 ) { + return IDS_ERROR_ILLEGALMOVIEOLD; + } else + if( header.BlockVersion >= 0x0300 ) { + if( rom->GetMapperNo() != 20 ) { + // FDSȊO + if( header.Ext0 != rom->GetPROM_CRC() ) { + return IDS_ERROR_ILLEGALMOVIECRC; // Ⴄ + } + } else { + // FDS + if( header.Ext0 != rom->GetGameID() || + header.Ext1 != (WORD)rom->GetMakerID() || + header.Ext2 != (WORD)rom->GetDiskNo() ) + return IDS_ERROR_ILLEGALMOVIECRC; // Ⴄ + } + + if( header.RecordVersion != VIRTUANES_VERSION ) { + return IDS_ERROR_ILLEGALMOVIEVER; + } + + return 0; + } + } + + return -1; +} + +BOOL NES::MoviePlay( const char* fname ) +{ + if( rom->IsNSF() ) + return FALSE; + + if( IsMoviePlay() || IsMovieRec() ) { + MovieStop(); + } + +DEBUGOUT( "NES::MoviePlay\n" ); + + try { + if( !(m_fpMovie = ::fopen( fname, "rb+" )) ) { + DEBUGOUT( "Movie play error. File not found.\n" ); + // t@Cł + return FALSE; + } + + // ǂݍ + if( ::fread( &m_hedMovie, sizeof(m_hedMovie), 1, m_fpMovie ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + if( ::memcmp( m_hedMovie.ID, "VirtuaNES MV", sizeof(m_hedMovie.ID) ) == 0 ) { + m_MovieVersion = m_hedMovie.BlockVersion; + + if( m_hedMovie.BlockVersion == 0x0300 ) { + if( m_hedMovie.CRC != 0 ) { + if( CRC::Crc( sizeof(m_hedMovie)-sizeof(DWORD), (LPBYTE)&m_hedMovie ) != m_hedMovie.CRC ) { + FCLOSE( m_fpMovie ); + return FALSE; // Ⴄ + } + } + // ` + } else { + // 搶IÂ̂Ń_B + FCLOSE( m_fpMovie ); + return FALSE; + } + } + + // Q[ŗLIvV + m_saveRenderMethod = (INT)GetRenderMethod(); + m_saveIrqType = GetIrqType(); + m_saveFrameIRQ = GetFrameIRQmode(); + m_saveVideoMode = GetVideoMode(); + SetRenderMethod( (RENDERMETHOD)m_hedMovie.RenderMethod ); + SetIrqType( (INT)m_hedMovie.IRQtype ); + SetFrameIRQmode( (m_hedMovie.FrameIRQ!=0)?TRUE:FALSE ); + SetVideoMode( m_hedMovie.VideoMode); + + LONG MovieOffset; + m_MovieControl = m_hedMovie.Control; + m_MovieStepTotal = m_hedMovie.MovieStep; + MovieOffset = m_hedMovie.MovieOffset; + + // Xe[gǂݍ + ReadState( m_fpMovie ); + + if( ::fseek( m_fpMovie, MovieOffset, SEEK_SET ) ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + // [r[L^ĂȂH + if( m_MovieStepTotal == 0 ) { + MovieStop(); + return FALSE; + } + + m_bMoviePlay = TRUE; + m_MovieStep = 0; + } catch( CHAR* str ) { + DEBUGOUT( "Movie play error. %s\n", str ); + FCLOSE( m_fpMovie ); + throw str; +#ifndef _DEBUG + } catch(...) { + DEBUGOUT( "Movie play error.\n" ); + FCLOSE( m_fpMovie ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + return TRUE; +} + +BOOL NES::MovieRec( const char* fname ) +{ + if( rom->IsNSF() ) + return FALSE; + + if( IsMoviePlay() || IsMovieRec() ) { + MovieStop(); + } + +DEBUGOUT( "NES::MovieRec\n" ); + + try { + if( !(m_fpMovie = ::fopen( fname, "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + + ::ZeroMemory( &m_hedMovie, sizeof(m_hedMovie) ); + ::memcpy( m_hedMovie.ID, "VirtuaNES MV", sizeof(m_hedMovie.ID) ); + m_hedMovie.BlockVersion = 0x0300; + m_hedMovie.RecordVersion = VIRTUANES_VERSION; + + m_hedMovie.StateStOffset = sizeof(m_hedMovie); + + m_hedMovie.Control |= Config.movie.bUsePlayer[0]?0x01:0x00; + m_hedMovie.Control |= Config.movie.bUsePlayer[1]?0x02:0x00; + m_hedMovie.Control |= Config.movie.bUsePlayer[2]?0x04:0x00; + m_hedMovie.Control |= Config.movie.bUsePlayer[3]?0x08:0x00; + m_hedMovie.Control |= Config.movie.bRerecord?0x80:0x00; + m_MovieControl = m_hedMovie.Control; + + // Q[ŗLIvV + m_hedMovie.RenderMethod = (BYTE)GetRenderMethod(); + m_hedMovie.IRQtype = (BYTE)GetIrqType(); + m_hedMovie.FrameIRQ = GetFrameIRQmode()?0xFF:0; + m_hedMovie.VideoMode = GetVideoMode(); + + // CRC,IDl(듮h~p) + if( rom->GetMapperNo() != 20 ) { + // FDSȊO + m_hedMovie.Ext0 = rom->GetPROM_CRC(); + } else { + // FDS + m_hedMovie.Ext0 = rom->GetGameID(); + m_hedMovie.Ext1 = (WORD)rom->GetMakerID(); + m_hedMovie.Ext2 = (WORD)rom->GetDiskNo(); + } + + // _~[ + if( ::fwrite( &m_hedMovie, sizeof(m_hedMovie), 1, m_fpMovie ) != 1 ) { + FCLOSE( m_fpMovie ); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + if( Config.movie.bResetRec ) { + Reset(); // n[hEFAZbg̋L^Jn + } + + // Xe[g + WriteState( m_fpMovie ); + + m_hedMovie.MovieOffset = ::ftell( m_fpMovie ); + m_bMovieRec = TRUE; + m_MovieStep = m_MovieStepTotal = 0; + m_MovieVersion = 0x0300; + } catch( CHAR* str ) { + DEBUGOUT( "Movie record error. %s\n", str ); + FCLOSE( m_fpMovie ); + throw str; +#ifndef _DEBUG + } catch(...) { + DEBUGOUT( "Movie record error.\n" ); + FCLOSE( m_fpMovie ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + return TRUE; +} + +BOOL NES::MovieRecAppend( const char* fname ) +{ + if( rom->IsNSF() ) + return FALSE; + + // L^͈Ӗ + if( IsMovieRec() ) + return FALSE; + + if( IsMoviePlay() ) { + MovieStop(); + } + +DEBUGOUT( "NES::MovieAppendRec\n" ); + + try { + if( !(m_fpMovie = ::fopen( fname, "rb" )) ) { + // t@CƂ + if( !(m_fpMovie = ::fopen( fname, "wb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + + ::ZeroMemory( &m_hedMovie, sizeof(m_hedMovie) ); + ::memcpy( m_hedMovie.ID, "VirtuaNES MV", sizeof(m_hedMovie.ID) ); + m_hedMovie.BlockVersion = 0x0300; + m_hedMovie.RecordVersion = VIRTUANES_VERSION; + m_hedMovie.StateStOffset = sizeof(m_hedMovie); + + m_hedMovie.Control |= Config.movie.bUsePlayer[0]?0x01:0x00; + m_hedMovie.Control |= Config.movie.bUsePlayer[1]?0x02:0x00; + m_hedMovie.Control |= Config.movie.bUsePlayer[2]?0x04:0x00; + m_hedMovie.Control |= Config.movie.bUsePlayer[3]?0x08:0x00; + m_hedMovie.Control |= Config.movie.bRerecord?0x80:0x00; +// m_hedMovie.Control |= Config.movie.bResetRec?0x40:0x00; + m_MovieControl = m_hedMovie.Control; + + // Q[ŗLIvV + m_hedMovie.RenderMethod = (BYTE)GetRenderMethod(); + m_hedMovie.IRQtype = (BYTE)GetIrqType(); + m_hedMovie.FrameIRQ = GetFrameIRQmode()?0xFF:0; + m_hedMovie.VideoMode = GetVideoMode(); + + // _~[ + if( ::fwrite( &m_hedMovie, sizeof(m_hedMovie), 1, m_fpMovie ) != 1 ) { + FCLOSE( m_fpMovie ); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + if( Config.movie.bResetRec ) { + Reset(); // n[hEFAZbg̋L^Jn + } + // Xe[g + WriteState( m_fpMovie ); + + m_hedMovie.MovieOffset = ::ftell( m_fpMovie ); + m_MovieStep = m_MovieStepTotal = 0; + m_MovieVersion = 0x0300; + } else { + if( !(m_fpMovie = ::fopen( fname, "rb+" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + // ǂݍ + if( ::fseek( m_fpMovie, 0, SEEK_SET ) ) { + FCLOSE( m_fpMovie ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + if( ::fread( &m_hedMovie, sizeof(m_hedMovie), 1, m_fpMovie ) != 1 ) { + FCLOSE( m_fpMovie ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + if( ::memcmp( m_hedMovie.ID, "VirtuaNES MV", sizeof(m_hedMovie.ID) ) != 0 ) { + FCLOSE( m_fpMovie ); + return FALSE; + } + // Âo[Ŵ͎ + if( m_hedMovie.BlockVersion < 0x0300 ) { + FCLOSE( m_fpMovie ); + return FALSE; + } + + m_MovieControl = m_hedMovie.Control; + m_MovieStep = m_MovieStepTotal = m_hedMovie.MovieStep; + m_MovieVersion = 0x0300; + + if( ::fseek( m_fpMovie, m_hedMovie.StateEdOffset, SEEK_SET ) ) { + FCLOSE( m_fpMovie ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + if( !ReadState( m_fpMovie ) ) { + FCLOSE( m_fpMovie ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + if( ::fseek( m_fpMovie, m_hedMovie.StateEdOffset, SEEK_SET ) ) { + FCLOSE( m_fpMovie ); + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + } + m_bMovieRec = TRUE; + } catch( CHAR* str ) { + DEBUGOUT( "Movie record error. %s\n", str ); + FCLOSE( m_fpMovie ); + throw str; +#ifndef _DEBUG + } catch(...) { + DEBUGOUT( "Movie record error.\n" ); + FCLOSE( m_fpMovie ); + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif + } + + return TRUE; +} + +BOOL NES::MovieStop() +{ + if( !m_fpMovie && !(m_bMoviePlay||m_bMovieRec) ) + return FALSE; + +DEBUGOUT( "NES::MovieStop\n" ); + + DirectDraw.SetMessageString( "Movie stop." ); + + if( m_bMovieRec ) { + m_hedMovie.MovieStep = m_MovieStep; + m_hedMovie.StateEdOffset = ::ftell( m_fpMovie ); + WriteState( m_fpMovie ); + +// // B蒼֎~̏ꍇ͒NjLs”\ +// if( m_MovieControl & 0x80 ) { +// } else { +// m_hedMovie.StateEdOffset = 0; +// } + if( ::fseek( m_fpMovie, 0, SEEK_SET ) ) { + FCLOSE( m_fpMovie ); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + // CRC + m_hedMovie.CRC = CRC::Crc( sizeof(m_hedMovie)-sizeof(DWORD), (LPBYTE)&m_hedMovie ); + + // ŏIIȃwb_ + if( ::fwrite( &m_hedMovie, sizeof(m_hedMovie), 1, m_fpMovie ) != 1 ) { + FCLOSE( m_fpMovie ); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + + FCLOSE( m_fpMovie ); + m_bMovieRec = FALSE; + } + + if( m_bMoviePlay ) { + FCLOSE( m_fpMovie ); + m_bMoviePlay = FALSE; + + // Q[ŗLIvVɖ߂ + SetRenderMethod( (RENDERMETHOD)m_saveRenderMethod ); + SetIrqType ( m_saveIrqType ); + SetFrameIRQmode( m_saveFrameIRQ ); + SetVideoMode ( m_saveVideoMode ); + } + + return TRUE; +} + +void NES::GetMovieInfo( WORD& wRecVersion, WORD& wVersion, DWORD& dwRecordFrames, DWORD& dwRecordTimes ) +{ + wRecVersion = m_hedMovie.RecordVersion; + wVersion = m_hedMovie.BlockVersion; + dwRecordFrames = m_hedMovie.MovieStep; + dwRecordTimes = m_hedMovie.RecordTimes; +} + +// t[Ăяo +void NES::Movie() +{ + if( !m_fpMovie && !(m_bMoviePlay||m_bMovieRec) ) { + m_CommandRequest = 0; // RȂƎ + return; + } + + INT exctr = pad->GetExController(); + + BYTE Data; + WORD wData; + DWORD dwData; + + if( m_bMovieRec ) { + // ŏg۰ׂݒ肳Ăꍇ + if( m_MovieStep == 0 ) { + if( exctr == PAD::EXCONTROLLER_ZAPPER + || exctr == PAD::EXCONTROLLER_PADDLE + || exctr == PAD::EXCONTROLLER_CRAZYCLIMBER + || exctr == PAD::EXCONTROLLER_TOPRIDER + || exctr == PAD::EXCONTROLLER_SPACESHADOWGUN + || exctr == PAD::EXCONTROLLER_FAMILYTRAINER_A + || exctr == PAD::EXCONTROLLER_FAMILYTRAINER_B + || exctr == PAD::EXCONTROLLER_MAHJANG + || exctr == PAD::EXCONTROLLER_EXCITINGBOXING + || exctr == PAD::EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE + || exctr == PAD::EXCONTROLLER_OEKAKIDS_TABLET ) { + // R}hID + Data = 0xF0; + // + if( ::fwrite( &Data, sizeof(Data), 1, m_fpMovie ) != 1 ) { + MovieStop(); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + // + wData = (WORD)(0x0100|(pad->GetExController()&0x0FF)); + // + if( ::fwrite( &wData, sizeof(wData), 1, m_fpMovie ) != 1 ) { + MovieStop(); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + } + + if( m_CommandRequest ) { + // R}hID + Data = 0xF0; + // + if( ::fwrite( &Data, sizeof(Data), 1, m_fpMovie ) != 1 ) { + MovieStop(); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + // R}h + wData = (WORD)m_CommandRequest; + // + if( ::fwrite( &wData, sizeof(wData), 1, m_fpMovie ) != 1 ) { + MovieStop(); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + m_CommandRequest = 0; + + // g۰ + if( exctr == PAD::EXCONTROLLER_ZAPPER + || exctr == PAD::EXCONTROLLER_PADDLE + || exctr == PAD::EXCONTROLLER_CRAZYCLIMBER + || exctr == PAD::EXCONTROLLER_TOPRIDER + || exctr == PAD::EXCONTROLLER_SPACESHADOWGUN + || exctr == PAD::EXCONTROLLER_FAMILYTRAINER_A + || exctr == PAD::EXCONTROLLER_FAMILYTRAINER_B + || exctr == PAD::EXCONTROLLER_MAHJANG + || exctr == PAD::EXCONTROLLER_EXCITINGBOXING + || exctr == PAD::EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE + || exctr == PAD::EXCONTROLLER_OEKAKIDS_TABLET ) { + // gRg[f[^ID + Data = 0xF3; + // + if( ::fwrite( &Data, sizeof(Data), 1, m_fpMovie ) != 1 ) { + MovieStop(); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + // f[^ + dwData = pad->GetSyncExData(); + + // + if( ::fwrite( &dwData, sizeof(dwData), 1, m_fpMovie ) != 1 ) { + MovieStop(); + // t@C݂̏Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + } + + dwData = pad->GetSyncData(); + for( INT i = 0; i < 4; i++ ) { + Data = (BYTE)(dwData>>(i*8)); + if( m_MovieControl & (1<= m_MovieStepTotal ) { + if( !Config.movie.bLoopPlay ) { + MovieStop(); + return; + } else { + // UĐȂĎɂ + m_bMoviePlay = FALSE; + m_MovieStep = 0; + ::fseek( m_fpMovie, m_hedMovie.StateStOffset, SEEK_SET ); + // Xe[gǂݍ + ReadState( m_fpMovie ); + ::fseek( m_fpMovie, m_hedMovie.MovieOffset, SEEK_SET ); + // ĐĎɂ + m_bMoviePlay = TRUE; + } + } + + do { + // ǂݍ + if( ::fread( &Data, sizeof(Data), 1, m_fpMovie ) != 1 ) { + // IH + MovieStop(); + return; + } + + // R}hH + if( (Data & 0xF0) == 0xF0 ) { + if( Data == 0xF0 ) { + // ǂݍ + if( ::fread( &wData, sizeof(wData), 1, m_fpMovie ) != 1 ) { + // IH + MovieStop(); + return; + } + if( wData < 0x0100 ) { + Command( (NESCOMMAND)((INT)wData) ); + } else { + // g۰ + CommandParam( NESCMD_EXCONTROLLER, ((INT)wData) & 0x00FF ); + } + } else + if( Data == 0xF3 ) { + // ǂݍ + if( ::fread( &dwData, sizeof(dwData), 1, m_fpMovie ) != 1 ) { + // IH + MovieStop(); + return; + } + pad->SetSyncExData( dwData ); + } else { + // f[^ԂĂHI + MovieStop(); + return; + } + } else { + // gpvC[΂ + while( !(m_MovieControl & (1<SetSyncData( dwData ); + + // JE^₷ + m_MovieStep++; + } + + m_CommandRequest = 0; +} + +// For Cheat +void NES::CheatInitial() +{ + m_CheatCode.clear(); +} + +BOOL NES::IsCheatCodeAdd() +{ + BOOL bRet = m_bCheatCodeAdd; + m_bCheatCodeAdd = FALSE; + + return bRet; +} + +INT NES::GetCheatCodeNum() +{ + return m_CheatCode.size(); +} + +BOOL NES::GetCheatCode( INT no, CHEATCODE& code ) +{ + if( m_CheatCode.size()-1 < no ) + return FALSE; + + code = m_CheatCode[no]; + return TRUE; +} + +void NES::SetCheatCodeFlag( INT no, BOOL bEnable ) +{ + if( m_CheatCode.size()-1 < no ) + return; + + if( bEnable ) { + m_CheatCode[no].enable |= CHEAT_ENABLE; + } else { + m_CheatCode[no].enable &= ~CHEAT_ENABLE; + } +} + +void NES::SetCheatCodeAllFlag( BOOL bEnable, BOOL bKey ) +{ + for( INT i = 0; i < m_CheatCode.size(); i++ ) { + if( !bKey ) { + if( bEnable ) { + m_CheatCode[i].enable |= CHEAT_ENABLE; + } else { + m_CheatCode[i].enable &= ~CHEAT_ENABLE; + } + } else if( !(m_CheatCode[i].enable&CHEAT_KEYDISABLE) ) { + if( bEnable ) { + m_CheatCode[i].enable |= CHEAT_ENABLE; + } else { + m_CheatCode[i].enable &= ~CHEAT_ENABLE; + } + } + } +} + +void NES::ReplaceCheatCode( INT no, CHEATCODE code ) +{ + if( m_CheatCode.size()-1 < no ) + return; + + m_CheatCode[no] = code; +} + +void NES::AddCheatCode( CHEATCODE code ) +{ + m_CheatCode.push_back( code ); + m_bCheatCodeAdd = TRUE; +} + +void NES::DelCheatCode( INT no ) +{ + if( m_CheatCode.size()-1 < no ) + return; + + m_CheatCode.erase( &m_CheatCode[no] ); +} + +DWORD NES::CheatRead( INT length, WORD addr ) +{ + DWORD data = 0; + for( INT i = 0; i <= length; i++ ) { + data |= (DWORD)Read( addr+i )*(1<<(i*8)); + } + + return data; +} + +void NES::CheatWrite( INT length, WORD addr, DWORD data ) +{ + for( INT i = 0; i <= length; i++ ) { + Write( (WORD)(addr+i), data&0xFF ); + data >>= 8; + } +} + +void NES::CheatCodeProcess() +{ + for( vector::iterator it = m_CheatCode.begin(); it != m_CheatCode.end(); it++ ) { + if( !(it->enable & CHEAT_ENABLE) ) + continue; + + switch( it->type ) { + case CHEAT_TYPE_ALWAYS: + CheatWrite( it->length, it->address, it->data ); + break; + case CHEAT_TYPE_ONCE: + CheatWrite( it->length, it->address, it->data ); + it->enable = 0; + break; + case CHEAT_TYPE_GREATER: + if( CheatRead( it->length, it->address ) > it->data ) { + CheatWrite( it->length, it->address, it->data ); + } + break; + case CHEAT_TYPE_LESS: + if( CheatRead( it->length, it->address ) < it->data ) { + CheatWrite( it->length, it->address, it->data ); + } + break; + } + } +} + +void NES::GenieInitial() +{ + m_bCheatCodeAdd = FALSE; + m_GenieCode.clear(); +} + +void NES::GenieLoad( char* fname ) +{ +FILE* fp = NULL; + + CHAR buf[256]; + GENIECODE code; + BYTE codetmp[9]; + INT no; + + if( (fp = ::fopen( fname, "r" )) ) { + m_GenieCode.clear(); + + while( ::fgets( buf, sizeof(buf), fp ) ) { + if( buf[0] == ';' ) + continue; + if( buf[0] == 0x0D || buf[0] == 0x0A ) + continue; + + if( ::strlen( buf ) < 6 ) + continue; + + code.address = 0; + code.data = 0; + code.cmp = 0; + + for( no = 0; isalpha(buf[no]) && no < 8; no++ ) { + switch( buf[no] ) { + case 'A': codetmp[no] = 0x00; break; + case 'P': codetmp[no] = 0x01; break; + case 'Z': codetmp[no] = 0x02; break; + case 'L': codetmp[no] = 0x03; break; + case 'G': codetmp[no] = 0x04; break; + case 'I': codetmp[no] = 0x05; break; + case 'T': codetmp[no] = 0x06; break; + case 'Y': codetmp[no] = 0x07; break; + case 'E': codetmp[no] = 0x08; break; + case 'O': codetmp[no] = 0x09; break; + case 'X': codetmp[no] = 0x0A; break; + case 'U': codetmp[no] = 0x0B; break; + case 'K': codetmp[no] = 0x0C; break; + case 'S': codetmp[no] = 0x0D; break; + case 'V': codetmp[no] = 0x0E; break; + case 'N': codetmp[no] = 0x0F; break; + } + } + + if( no == 6 ) { + // Address + code.address |= (WORD)(codetmp[3] & 0x07)<<12; + code.address |= (WORD)(codetmp[4] & 0x08)<< 8; + code.address |= (WORD)(codetmp[5] & 0x07)<< 8; + code.address |= (WORD)(codetmp[1] & 0x08)<< 4; + code.address |= (WORD)(codetmp[2] & 0x07)<< 4; + code.address |= (WORD)(codetmp[3] & 0x08); + code.address |= (WORD)(codetmp[4] & 0x07); + // Data + code.data |= (codetmp[0] & 0x08)<<4; + code.data |= (codetmp[1] & 0x07)<<4; + code.data |= (codetmp[5] & 0x08); + code.data |= (codetmp[0] & 0x07); + + m_GenieCode.push_back( code ); + } else + if( no == 8 ) { + // Address + code.address |= 0x8000; + code.address |= (WORD)(codetmp[3] & 0x07)<<12; + code.address |= (WORD)(codetmp[4] & 0x08)<< 8; + code.address |= (WORD)(codetmp[5] & 0x07)<< 8; + code.address |= (WORD)(codetmp[1] & 0x08)<< 4; + code.address |= (WORD)(codetmp[2] & 0x07)<< 4; + code.address |= (WORD)(codetmp[3] & 0x08); + code.address |= (WORD)(codetmp[4] & 0x07); + // Data + code.data |= (codetmp[0] & 0x08)<<4; + code.data |= (codetmp[1] & 0x07)<<4; + code.data |= (codetmp[7] & 0x08); + code.data |= (codetmp[0] & 0x07); + // Data + code.cmp |= (codetmp[6] & 0x08)<<4; + code.cmp |= (codetmp[7] & 0x07)<<4; + code.cmp |= (codetmp[5] & 0x08); + code.cmp |= (codetmp[6] & 0x07); + + m_GenieCode.push_back( code ); + } + } + + GenieCodeProcess(); + } + + FCLOSE( fp ); +} + +void NES::GenieCodeProcess() +{ + WORD addr; + + for( INT i = 0; i < m_GenieCode.size(); i++ ) { + addr = m_GenieCode[i].address; + if( addr & 0x8000 ) { + // 8character codes + if( CPU_MEM_BANK[addr>>13][addr&0x1FFF] == m_GenieCode[i].cmp ) { + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = m_GenieCode[i].data; + } + } else { + // 6character codes + addr |= 0x8000; + CPU_MEM_BANK[addr>>13][addr&0x1FFF] = m_GenieCode[i].data; + } + } +} + +void NES::DrawPad() +{ + if( m_bMoviePlay ) { + INT offset_h = 12; + INT offset_v = Config.graphics.bAllLine?(240-18):(240-22); + + DWORD dwData = pad->GetSyncData(); + for( INT i = 0; i < 4; i++ ) { + BYTE Data = (BYTE)(dwData>>(i*8)); + if( m_MovieControl & (1<GetScreenPtr()+8+(256+16)*y+x; +LPBYTE pPtr; + + h = (INT)*lpBitmap++; + v = (INT)*lpBitmap++; + + for( j = 0; j < v; j++ ) { + pPtr = pScn; + for( i = 0; i < h; i++ ) { + if( *lpBitmap != 0xFF ) { + *pPtr = *lpBitmap; + } + lpBitmap++; + pPtr++; + } + pScn += 256+16; + } +} + +// TapeDevice +BOOL NES::TapePlay( const char* fname ) +{ + if( rom->IsNSF() ) + return FALSE; + + if( IsTapePlay() || IsTapeRec() ) { + TapeStop(); + } + +DEBUGOUT( "NES::TapePlay\n" ); + + if( !(m_fpTape = ::fopen( fname, "rb" )) ) { + DEBUGOUT( "Tape play error. File not found.\n" ); + // t@Cł + return FALSE; + } + + m_bTapePlay = TRUE; + m_TapeCycles = 0; + m_TapeOut = 0; + + cpu->SetClockProcess( TRUE ); + + return TRUE; +} + +BOOL NES::TapeRec( const char* fname ) +{ + if( rom->IsNSF() ) + return FALSE; + + if( IsTapePlay() || IsTapeRec() ) { + TapeStop(); + } + +DEBUGOUT( "NES::TapeRec\n" ); + + if( !(m_fpTape = ::fopen( fname, "wb" )) ) { + DEBUGOUT( "Tape rec error. File not found.\n" ); + // t@Cł + return FALSE; + } + + m_bTapeRec = TRUE; + m_TapeCycles = 0; + m_TapeIn = 0; + + cpu->SetClockProcess( TRUE ); + + return TRUE; +} + +void NES::TapeStop() +{ + DirectDraw.SetMessageString( "Tape stop." ); + + if( !m_bBarcode ) { + cpu->SetClockProcess( FALSE ); + } + + m_bTapePlay = m_bTapeRec = FALSE; + FCLOSE( m_fpTape ); +} + +void NES::Tape( INT cycles ) +{ + if( !(IsTapePlay() || IsTapeRec()) ) { + return; + } + + if( (m_TapeCycles-=(double)cycles) > 0 ) + return; + + m_TapeCycles += (nescfg->CpuClock / 32000.0); +// m_TapeCycles += (nescfg->CpuClock / 22050.0); // xă_ۂ + + if( m_bTapePlay ) { + INT data = ::fgetc( m_fpTape ); + if( data != EOF ) { + if( (data&0xFF) >= 0x8C ) { + m_TapeOut = 0x02; + } else + if( (data&0xFF) <= 0x74 ) { + m_TapeOut = 0x00; + } + } else { + TapeStop(); + } + } + if( m_bTapeRec ) { + ::fputc( (int)((m_TapeIn&7)==7)?0x90:0x70, m_fpTape ); + } +} + +void NES::Barcode( INT cycles ) +{ + if( m_bBarcode ) { + if( (m_BarcodeCycles+=cycles) > 1000 ) { + m_BarcodeCycles = 0; + // ~H + if( m_BarcodeData[m_BarcodePtr] != 0xFF ) { + m_BarcodeOut = m_BarcodeData[m_BarcodePtr++]; + } else { + m_bBarcode = FALSE; + m_BarcodeOut = 0; +DEBUGOUT( "Barcode data trasnfer complete!!\n" ); + + if( !(IsTapePlay() || IsTapeRec()) ) { + cpu->SetClockProcess( FALSE ); + } + } + } + } +} + +void NES::SetBarcodeData( LPBYTE code, INT len ) +{ + if( rom->GetPROM_CRC() == 0x67898319 ) { // Barcode World (J) + SetBarcode2Data( code, len ); + return; + } + + DEBUGOUT( "NES::SetBarcodeData code=%s len=%d\n", code, len ); + + bool prefix_parity_type[10][6] = { + {0,0,0,0,0,0}, {0,0,1,0,1,1}, {0,0,1,1,0,1}, {0,0,1,1,1,0}, + {0,1,0,0,1,1}, {0,1,1,0,0,1}, {0,1,1,1,0,0}, {0,1,0,1,0,1}, + {0,1,0,1,1,0}, {0,1,1,0,1,0} + }; + bool data_left_odd[10][7] = { + {0,0,0,1,1,0,1}, {0,0,1,1,0,0,1}, {0,0,1,0,0,1,1}, {0,1,1,1,1,0,1}, + {0,1,0,0,0,1,1}, {0,1,1,0,0,0,1}, {0,1,0,1,1,1,1}, {0,1,1,1,0,1,1}, + {0,1,1,0,1,1,1}, {0,0,0,1,0,1,1} + }; + bool data_left_even[10][7] = { + {0,1,0,0,1,1,1}, {0,1,1,0,0,1,1}, {0,0,1,1,0,1,1}, {0,1,0,0,0,0,1}, + {0,0,1,1,1,0,1}, {0,1,1,1,0,0,1}, {0,0,0,0,1,0,1}, {0,0,1,0,0,0,1}, + {0,0,0,1,0,0,1}, {0,0,1,0,1,1,1} + }; + bool data_right[10][7] = { + {1,1,1,0,0,1,0}, {1,1,0,0,1,1,0}, {1,1,0,1,1,0,0}, {1,0,0,0,0,1,0}, + {1,0,1,1,1,0,0}, {1,0,0,1,1,1,0}, {1,0,1,0,0,0,0}, {1,0,0,0,1,0,0}, + {1,0,0,1,0,0,0}, {1,1,1,0,1,0,0} + }; + + INT i, j, count = 0;; + + // lɕϊ + for( i = 0; i < len; i++ ) { + code[i] = code[i]-'0'; + } + + // tg}[W + for( i = 0; i < 32; i++ ) { + m_BarcodeData[count++] = 0x08; + } + // tgK[ho[ + m_BarcodeData[count++] = 0x00; + m_BarcodeData[count++] = 0x08; + m_BarcodeData[count++] = 0x00; + + if( len == 13 ) { +#if 0 + // `FbNfBWbg̍ČvZ + INT sum = 0; + for( i = 0; i < 12; i++ ) { + sum += (i&1)?(code[i]*3):code[i]; + } + code[12] = (10-(sum%10))%10; +// test start +// INT cs = (10-(sum%10))%10; +// if( cs == 0 ) { +// cs = 9; +// } else { +// cs--; +// } +// code[12] = cs; +// test end +#endif + // 6LN^ + for( i = 0; i < 6; i++ ) { + if( prefix_parity_type[code[0]][i] ) { + // peB + for( j = 0; j < 7; j++ ) { + m_BarcodeData[count++] = data_left_even[code[i+1]][j]?0x00:0x08; + } + } else { + // peB + for( j = 0; j < 7; j++ ) { + m_BarcodeData[count++] = data_left_odd[code[i+1]][j]?0x00:0x08; + } + } + } + + // Z^[o[ + m_BarcodeData[count++] = 0x08; + m_BarcodeData[count++] = 0x00; + m_BarcodeData[count++] = 0x08; + m_BarcodeData[count++] = 0x00; + m_BarcodeData[count++] = 0x08; + + // E5LN^ƃ`FbNfBWbg + for( i = 7; i < 13; i++ ) { + // peB + for( j = 0; j < 7; j++ ) { + m_BarcodeData[count++] = data_right[code[i]][j]?0x00:0x08; + } + } + } else + if( len == 8 ) { + // `FbNfBWbg̍ČvZ + INT sum = 0; + for( i = 0; i < 7; i++ ) { + sum += (i&1)?code[i]:(code[i]*3); + } + code[7] = (10-(sum%10))%10; + + // 4LN^ + for( i = 0; i < 4; i++ ) { + // peB + for( j = 0; j < 7; j++ ) { + m_BarcodeData[count++] = data_left_odd[code[i]][j]?0x00:0x08; + } + } + + // Z^[o[ + m_BarcodeData[count++] = 0x08; + m_BarcodeData[count++] = 0x00; + m_BarcodeData[count++] = 0x08; + m_BarcodeData[count++] = 0x00; + m_BarcodeData[count++] = 0x08; + + // E3LN^ƃ`FbNfBWbg + for( i = 4; i < 8; i++ ) { + // peB + for( j = 0; j < 7; j++ ) { + m_BarcodeData[count++] = data_right[code[i]][j]?0x00:0x08; + } + } + } + + // CgK[ho[ + m_BarcodeData[count++] = 0x00; + m_BarcodeData[count++] = 0x08; + m_BarcodeData[count++] = 0x00; + // Cg}[W + for( i = 0; i < 32; i++ ) { + m_BarcodeData[count++] = 0x08; + } + // I}[N + m_BarcodeData[count++] = 0xFF; + + // ]Jn + m_bBarcode = TRUE; + m_BarcodeCycles = 0; + m_BarcodePtr = 0; + m_BarcodeOut = 0x08; + + cpu->SetClockProcess( TRUE ); + +DEBUGOUT( "BARCODE DATA MAX:%d\n", count ); +} + +BYTE NES::Barcode2( void ) +{ +BYTE ret = 0x00; + + if( !m_bBarcode2 || m_Barcode2seq < 0 ) + return ret; + + switch( m_Barcode2seq ) { + case 0: + m_Barcode2seq++; + m_Barcode2ptr = 0; + ret = 0x04; // d3 + break; + + case 1: + m_Barcode2seq++; + m_Barcode2bit = m_Barcode2data[m_Barcode2ptr]; + m_Barcode2cnt = 0; + ret = 0x04; // d3 + break; + + case 2: + ret = (m_Barcode2bit&0x01)?0x00:0x04; // Bit rev. + m_Barcode2bit >>= 1; + if( ++m_Barcode2cnt > 7 ) { + m_Barcode2seq++; + } + break; + case 3: + if( ++m_Barcode2ptr > 19 ) { + m_bBarcode2 = FALSE; + m_Barcode2seq = -1; + } else { + m_Barcode2seq = 1; + } + break; + default: + break; + } + + return ret; +} + +void NES::SetBarcode2Data( LPBYTE code, INT len ) +{ + DEBUGOUT( "NES::SetBarcodeData2 code=%s len=%d\n", code, len ); + + if( len < 13 ) + return; + + m_bBarcode2 = TRUE; + m_Barcode2seq = 0; + m_Barcode2ptr = 0; + + ::strcpy( (char*)m_Barcode2data, (char*)code ); + + m_Barcode2data[13] = 'S'; + m_Barcode2data[14] = 'U'; + m_Barcode2data[15] = 'N'; + m_Barcode2data[16] = 'S'; + m_Barcode2data[17] = 'O'; + m_Barcode2data[18] = 'F'; + m_Barcode2data[19] = 'T'; +} + +//----------Dump RAM---------------------------------------------------------------------- +void NES::Dump_RAM0() +{ + int i; + for( i = 0; i < sizeof(RAM); i++ ) { + if( RAM[i] != 0x00 ) + break; + } + if( i < sizeof(RAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "ram0" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( RAM, sizeof(RAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_VRAM() +{ + int i; + for( i = 0; i < sizeof(VRAM); i++ ) { + if( VRAM[i] != 0x00 ) + break; + } + if( i < sizeof(VRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "vram" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( VRAM, sizeof(VRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_CRAM() +{ + int i; + for( i = 0; i < sizeof(CRAM); i++ ) { + if( CRAM[i] != 0x00 ) + break; + } + if( i < sizeof(CRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "cram" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( CRAM, sizeof(CRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_YCRAM() +{ + int i; + for( i = 0; i < sizeof(YCRAM); i++ ) { + if( YCRAM[i] != 0x00 ) + break; + } + if( i < sizeof(YCRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "YCRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( YCRAM, sizeof(YCRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_YSRAM() +{ + int i; + for( i = 0; i < sizeof(YSRAM); i++ ) { + if( YSRAM[i] != 0x00 ) + break; + } + if( i < sizeof(YSRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "YSRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( YSRAM, sizeof(YSRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_YWRAM() +{ + int i; + for( i = 0; i < sizeof(YWRAM); i++ ) { + if( YWRAM[i] != 0x00 ) + break; + } + if( i < sizeof(YWRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "YWRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( YWRAM, sizeof(YWRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_CPUHMEM() +{ + BYTE CPUHRAM[32*1024]; + memcpy( CPUHRAM+0x0000, CPU_MEM_BANK[4], 0x2000 ); + memcpy( CPUHRAM+0x2000, CPU_MEM_BANK[5], 0x2000 ); + memcpy( CPUHRAM+0x4000, CPU_MEM_BANK[6], 0x2000 ); + memcpy( CPUHRAM+0x6000, CPU_MEM_BANK[7], 0x2000 ); + + int i; + for( i = 0; i < sizeof(CPUHRAM); i++ ) { + if( CPUHRAM[i] != 0x00 ) + break; + } + if( i < sizeof(CPUHRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "CPUHRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( CPUHRAM, sizeof(CPUHRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +void NES::Dump_CPULMEM() +{ + BYTE CPULRAM[16*1024]; + memcpy( CPULRAM+0x0000, CPU_MEM_BANK[2], 0x2000 ); + memcpy( CPULRAM+0x2000, CPU_MEM_BANK[3], 0x2000 ); + + int i; + for( i = 0; i < sizeof(CPULRAM); i++ ) { + if( CPULRAM[i] != 0x00 ) + break; + } + if( i < sizeof(CPULRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "CPULRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( CPULRAM, sizeof(CPULRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} + +void NES::Dump_BDRAM() +{ + int i; + for( i = 0; i < sizeof(BDRAM); i++ ) { + if( BDRAM[i] != 0x00 ) + break; + } + if( i < sizeof(BDRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "BDRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( BDRAM, sizeof(BDRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} + +void NES::Dump_JDRAM() +{ + int i; + for( i = 0; i < sizeof(JDRAM); i++ ) { + if( JDRAM[i] != 0x00 ) + break; + } + if( i < sizeof(JDRAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "JDRAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( JDRAM, sizeof(JDRAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +//---------------------------------------------------------------------------------------- +void NES::Dump_ERAM() +{ + int i; + for( i = 0; i < sizeof(ERAM); i++ ) { + if( ERAM[i] != 0x00 ) + break; + } + if( i < sizeof(ERAM) ) { + string pathstr, tempstr; + if( Config.path.szRamPath ) { + pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRamPath ); + ::CreateDirectory( pathstr.c_str(), NULL ); + } else { + pathstr = rom->GetRomPath(); + } + tempstr = CPathlib::MakePathExt( pathstr.c_str(), rom->GetRomName(), "ERAM" ); + FILE* fp = NULL; + try + { + if( !(fp = ::fopen( tempstr.c_str(), "wb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + sprintf( szErrorString, szErrStr, tempstr.c_str() ); + throw szErrorString; + } + if( ::fwrite( ERAM, sizeof(ERAM), 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_WRITE ); + } + FCLOSE( fp ); + } catch( CHAR* str ) { + FCLOSE( fp ); + throw str; + #ifndef _DEBUG + } catch(...) { + FCLOSE( fp ); + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); + #endif + } + } +} +//---------------------------------------------------------------------------------------- diff --git a/References/VirtuaNESex_src_191105/NES/Nes.h b/References/VirtuaNESex_src_191105/NES/Nes.h new file mode 100644 index 00000000..4c647ff7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/Nes.h @@ -0,0 +1,392 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES Emulation core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __NES_INCLUDED__ +#define __NES_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "typedef.h" +#include "macro.h" + +#include "state.h" +#include "cheat.h" +#include "VsUnisystem.h" + +#include +using namespace std; + +// RtBO +#define FETCH_CYCLES 8 + +typedef struct tagNESCONFIG { + FLOAT BaseClock; // NTSC:21477270.0 PAL:21281364.0 + FLOAT CpuClock; // NTSC: 1789772.5 PAL: 1773447.0 + + INT TotalScanlines; // NTSC: 262 PAL: 312 + INT VBlankLine; // NTSC: 241 PAL: 290 + + INT ScanlineCycles; // NTSC:1364 PAL:1362 + + INT HDrawCycles; // NTSC:1024 PAL:1024 + INT HBlankCycles; // NTSC: 340 PAL: 338 + INT ScanlineEndCycles; // NTSC: 4 PAL: 2 + + INT FrameCycles; // NTSC:29829.52 PAL:35468.94 + INT FrameIrqCycles; // NTSC:29829.52 PAL:35468.94 + + INT FrameRate; // NTSC:60(59.94) PAL:50 + FLOAT FramePeriod; // NTSC:16.683 PAL:20.0 +} NESCONFIG, *LPNESCONFIG; + +extern NESCONFIG NESCONFIG_NTSC; +extern NESCONFIG NESCONFIG_PAL; + +// class prototypes +class CPU; +class PPU; +class APU; +class ROM; +class PAD; +class Mapper; + +// +// NES NX +// +class NES +{ +public: +// oϐ + CPU* cpu; + PPU* ppu; + APU* apu; + ROM* rom; + PAD* pad; + Mapper* mapper; + + NESCONFIG* nescfg; +public: + NES( const char* fname ); + virtual ~NES(); + + int want_hsync; + int NES_scanline; + +// o֐ + // G~[V + void Reset(); + void SoftReset(); + + void Clock( INT cycles ); + + BYTE Read ( WORD addr ); + void Write( WORD addr, BYTE data ); + + void EmulationCPU( INT basecycles ); + void EmulationCPU_BeforeNMI( INT cycles ); + + void EmulateFrame( BOOL bDraw ); + + // For NSF + void EmulateNSF(); + void SetNsfPlay( INT songno, INT songmode ); + void SetNsfStop(); + BOOL IsNsfPlaying() { return m_bNsfPlaying; }; + + // IRQ type contorol + enum IRQMETHOD { + IRQ_HSYNC = 0, + IRQ_CLOCK = 1 + }; + void SetIrqType( INT nType ) { nIRQtype = nType; }; + INT GetIrqType() { return (INT)nIRQtype; }; + + // Frame-IRQ control (for Paris-Dakar Rally Special) + void SetFrameIRQmode( BOOL bMode ) { bFrameIRQ = bMode; } + BOOL GetFrameIRQmode() { return bFrameIRQ; } + + // NTSC/PAL + void SetVideoMode( BOOL bMode ); + BOOL GetVideoMode() { return bVideoMode; } + + // + INT GetDiskNo(); + void SoundSetup(); + + INT GetScanline() { return NES_scanline; } + BOOL GetZapperHit() { return bZapper; } + void GetZapperPos( LONG&x, LONG&y ) { x = ZapperX; y = ZapperY; } + void SetZapperPos( LONG x, LONG y ) { ZapperX = x; ZapperY = y; } + + // Xe[gt@C + // 0:ERROR 1:CRC OK -1:CRC ERR + static INT IsStateFile( const char* fname, ROM* rom ); + BOOL LoadState( const char* fname ); + BOOL SaveState( const char* fname ); + + INT GetSAVERAM_SIZE() { return SAVERAM_SIZE; } + void SetSAVERAM_SIZE( INT size ) { SAVERAM_SIZE = size; } + + // VS-Unisystem + BYTE GetVSDipSwitch() { return m_VSDipValue; } + void SetVSDipSwitch( BYTE v ) { m_VSDipValue = v; } + VSDIPSWITCH* GetVSDipSwitchTable() { return m_VSDipTable; } + + // XibvVbg + BOOL Snapshot(); + + // For Movie + // 0:ERROR 1:CRC OK -1:CRC ERR + static INT IsMovieFile( const char* fname, ROM* rom ); + + BOOL IsMoviePlay() { return m_bMoviePlay; } + BOOL IsMovieRec() { return m_bMovieRec; } + BOOL MoviePlay( const char* fname ); + BOOL MovieRec( const char* fname ); + BOOL MovieRecAppend( const char* fname ); + BOOL MovieStop(); + + // ̑Rg[ + BOOL IsDiskThrottle() { return m_bDiskThrottle; } +// BOOL IsBraking() { return m_bBrake; } // Debugger + + // ` + enum RENDERMETHOD { + POST_ALL_RENDER = 0, // XLC̖ߎsC_O + PRE_ALL_RENDER = 1, // _O̎sCXLC̖ߎs + POST_RENDER = 2, // \ԕ̖ߎsC_O + PRE_RENDER = 3, // _OsC\ԕ̖ߎs + TILE_RENDER = 4 // ^Cx[X_O + }; + void SetRenderMethod( RENDERMETHOD type ) { RenderMethod = type; } + RENDERMETHOD GetRenderMethod() { return RenderMethod; } + + // R}h + enum NESCOMMAND { + NESCMD_NONE = 0, + NESCMD_HWRESET, + NESCMD_SWRESET, + NESCMD_EXCONTROLLER, // Commandparam + NESCMD_DISK_THROTTLE_ON, + NESCMD_DISK_THROTTLE_OFF, + NESCMD_DISK_EJECT, + NESCMD_DISK_0A, + NESCMD_DISK_0B, + NESCMD_DISK_1A, + NESCMD_DISK_1B, + + NESCMD_SOUND_MUTE, // CommandParam + }; + + void Command( NESCOMMAND cmd ); + BOOL CommandParam( NESCOMMAND cmd, INT param ); + + // For Movie + void Movie(); + void GetMovieInfo( WORD& wRecVersion, WORD& wVersion, DWORD& dwRecordFrames, DWORD& dwRecordTimes ); + + // For Cheat + void CheatInitial(); + + BOOL IsCheatCodeAdd(); + + INT GetCheatCodeNum(); + BOOL GetCheatCode( INT no, CHEATCODE& code ); + void SetCheatCodeFlag( INT no, BOOL bEnable ); + void SetCheatCodeAllFlag( BOOL bEnable, BOOL bKey ); + + void ReplaceCheatCode( INT no, CHEATCODE code ); + void AddCheatCode( CHEATCODE code ); + void DelCheatCode( INT no ); + + DWORD CheatRead( INT length, WORD addr ); + void CheatWrite( INT length, WORD addr, DWORD data ); + void CheatCodeProcess(); + + // For Genie + void GenieInitial(); + void GenieLoad( char* fname ); + void GenieCodeProcess(); + + // TapeDevice + BOOL IsTapePlay() { return m_bTapePlay; } + BOOL IsTapeRec() { return m_bTapeRec; } + BOOL TapePlay( const char* fname ); + BOOL TapeRec( const char* fname ); + void TapeStop(); + void Tape( INT cycles ); + + // Barcode battler(Bandai) + void SetBarcodeData( LPBYTE code, INT len ); + void Barcode( INT cycles ); + BOOL IsBarcodeEnable() { return m_bBarcode; }; + BYTE GetBarcodeStatus() { return m_BarcodeOut; }; + + // Barcode world(Sunsoft/EPOCH) + void SetBarcode2Data( LPBYTE code, INT len ); + BYTE Barcode2( void ); + BOOL IsBarcode2Enable() { return m_bBarcode2; }; + + // TurboFile + void SetTurboFileBank( INT bank ) { m_TurboFileBank = bank; } + INT GetTurboFileBank() { return m_TurboFileBank; } + + // TEST + DWORD GetFrameTotalCycles() { + return m_dwTotalCycle; + } + DWORD GetProfileTotalCycles() { + return m_dwProfileTotalCycle; + } + DWORD GetProfileTotalCount() { + return m_dwProfileTotalCount; + } + DWORD GetProfileCycles() { + return m_dwProfileCycle; + } + + void Dump_CPULMEM(); + void Dump_CPUHMEM(); + void Dump_RAM0(); + void Dump_VRAM(); + void Dump_CRAM(); + void Dump_YCRAM(); + void Dump_YWRAM(); + void Dump_YSRAM(); + + void Dump_BDRAM(); + void Dump_JDRAM(); + + void Dump_ERAM(); + +protected: +// o֐ + // G~[V + BYTE ReadReg ( WORD addr ); + void WriteReg( WORD addr, BYTE data ); + + // Xe[gTu + BOOL ReadState( FILE* fp ); + void WriteState( FILE* fp ); + + void LoadSRAM(); + void SaveSRAM(); + + void LoadDISK(); + void SaveDISK(); + + void LoadTurboFile(); + void SaveTurboFile(); + +protected: +// oϐ + INT nIRQtype; + BOOL bVideoMode; + BOOL bFrameIRQ; + + BOOL bZapper; + LONG ZapperX, ZapperY; + + BOOL m_bPadStrobe; + + RENDERMETHOD RenderMethod; + + BOOL m_bDiskThrottle; + + SQWORD base_cycles; + SQWORD emul_cycles; + + + INT SAVERAM_SIZE; + + // For VS-Unisystem + BYTE m_VSDipValue; + VSDIPSWITCH* m_VSDipTable; + + // Snapshot number + INT m_nSnapNo; + + // For NSF + BOOL m_bNsfPlaying; + BOOL m_bNsfInit; + INT m_nNsfSongNo; + INT m_nNsfSongMode; + + // For Movie + BOOL m_bMoviePlay; + BOOL m_bMovieRec; + WORD m_MovieVersion; + + FILE* m_fpMovie; + MOVIEFILEHDR m_hedMovie; + DWORD m_MovieControl; + LONG m_MovieStepTotal; + LONG m_MovieStep; + INT m_CommandRequest; + + // For Tape + BOOL m_bTapePlay; + BOOL m_bTapeRec; + FILE* m_fpTape; + double m_TapeCycles; + BYTE m_TapeIn; + BYTE m_TapeOut; + + // For Barcode + BOOL m_bBarcode; + BYTE m_BarcodeOut; + BYTE m_BarcodePtr; + INT m_BarcodeCycles; + BYTE m_BarcodeData[256]; + + // For Barcode + BOOL m_bBarcode2; + INT m_Barcode2seq; + INT m_Barcode2ptr; + INT m_Barcode2cnt; + BYTE m_Barcode2bit; + BYTE m_Barcode2data[32]; + + // For TurboFile + INT m_TurboFileBank; + + // gameoption backup + INT m_saveRenderMethod; + INT m_saveIrqType; + BOOL m_saveFrameIRQ; + BOOL m_saveVideoMode; + + // For Cheat + BOOL m_bCheatCodeAdd; + vector m_CheatCode; + + // For Genie + vector m_GenieCode; + + // For Movie pad display + void DrawPad(); + void DrawBitmap( INT x, INT y, LPBYTE lpBitmap ); + static BYTE m_PadImg[]; + static BYTE m_KeyImg0[]; + static BYTE m_KeyImg1[]; + static BYTE m_KeyImg2[]; + + // TEST + DWORD m_dwTotalCycle; + DWORD m_dwTotalTempCycle; + DWORD m_dwProfileTotalCycle; + DWORD m_dwProfileTotalCount; + DWORD m_dwProfileCycle; + DWORD m_dwProfileTempCycle; +private: +}; + +#endif // !__NES_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/PAD.cpp b/References/VirtuaNESex_src_191105/NES/PAD.cpp new file mode 100644 index 00000000..6428ed11 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PAD.cpp @@ -0,0 +1,800 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES Pad // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#define WIN32_LEAN_AND_MEAN +#include +#include "typedef.h" +#include "macro.h" + +#include "DebugOut.h" +#include "Config.h" + +#include "DirectDraw.h" +#include "DirectInput.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "pad.h" +#include "rom.h" + +PAD::PAD( NES* parent ) : nes( parent ) +{ + excontroller_select = 0; + expad = NULL; + bStrobe = FALSE; + bSwapButton = FALSE; + bSwapPlayer = FALSE; + bZapperMode = FALSE; + nVSSwapType = VS_TYPE0; + + padbit[0] = padbit[1] = padbit[2] = padbit[3] = 0; + micbit = 0; + + padbitsync[0] = padbitsync[1] = padbitsync[2] = padbitsync[3] = 0; + micbitsync = 0; +} + +PAD::~PAD() +{ + DirectDraw.SetZapperMode( FALSE ); + DirectDraw.SetZapperDrawMode( FALSE ); + + DELETEPTR( expad ); +} + +void PAD::Reset() +{ + pad1bit = pad2bit = 0; + bStrobe = FALSE; + +// if( !bZapperMode ) { +// bZapperMode = FALSE; +// } + + bBarcodeWorld = FALSE; + + ZEROMEMORY( padcnt, sizeof(padcnt) ); + + // Select Extension Devices + DWORD crc = nes->rom->GetPROM_CRC(); + + if( crc == 0xfbfc6a6c // Adventures of Bayou Billy, The(E) + || crc == 0xcb275051 // Adventures of Bayou Billy, The(U) + || crc == 0xfb69c131 // Baby Boomer(Unl)(U) + || crc == 0xf2641ad0 // Barker Bill's Trick Shooting(U) + || crc == 0xbc1dce96 // Chiller (Unl)(U) + || crc == 0x90ca616d // Duck Hunt(JUE) + || crc == 0x59e3343f // Freedom Force(U) + || crc == 0x242a270c // Gotcha!(U) + || crc == 0x7b5bd2de // Gumshoe(UE) + || crc == 0x255b129c // Gun Sight(J) + || crc == 0x8963ae6e // Hogan's Alley(JU) + || crc == 0x51d2112f // Laser Invasion(U) + || crc == 0x0a866c94 // Lone Ranger, The(U) +// || crc == 0xe4c04eea // Mad City(J) + || crc == 0x9eef47aa // Mechanized Attack(U) + || crc == 0xc2db7551 // Shooting Range(U) + || crc == 0x163e86c0 // To The Earth(U) + || crc == 0x0d3cf705 // Wild Gunman(J) + || crc == 0x389960db ) { // Wild Gunman(JUE) + SetExController( EXCONTROLLER_ZAPPER ); + } + if( crc == 0x35893b67 // Arkanoid(J) + || crc == 0x6267fbd1 ) { // Arkanoid 2(J) + SetExController( EXCONTROLLER_PADDLE ); + } + if( crc == 0xff6621ce // Hyper Olympic(J) + || crc == 0xdb9418e8 // Hyper Olympic(Tonosama Ban)(J) + || crc == 0xac98cd70 ) { // Hyper Sports(J) + SetExController( EXCONTROLLER_HYPERSHOT ); + } + if( crc == 0xc68363f6 ) { // Crazy Climber(J) + SetExController( EXCONTROLLER_CRAZYCLIMBER ); + } + if( crc == 0x20d22251 ) { // Top rider(J) + SetExController( EXCONTROLLER_TOPRIDER ); + } + if( crc == 0x0cd00488 ) { // Space Shadow(J) + SetExController( EXCONTROLLER_SPACESHADOWGUN ); + } + + if( crc == 0x8c8fa83b // Family Trainer - Athletic World (J) + || crc == 0x7e704a14 // Family Trainer - Jogging Race (J) + || crc == 0x2330a5d3 ) { // Family Trainer - Rairai Kyonshiizu (J) + SetExController( EXCONTROLLER_FAMILYTRAINER_A ); + } + if( crc == 0xf8da2506 // Family Trainer - Aerobics Studio (J) + || crc == 0xca26a0f1 // Family Trainer - Dai Undoukai (J) + || crc == 0x28068b8c // Family Trainer - Fuuun Takeshi Jou 2 (J) + || crc == 0x10bb8f9a // Family Trainer - Manhattan Police (J) + || crc == 0xad3df455 // Family Trainer - Meiro Dai Sakusen (J) + || crc == 0x8a5b72c0 // Family Trainer - Running Stadium (J) + || crc == 0x59794f2d ) { // Family Trainer - Totsugeki Fuuun Takeshi Jou (J) + SetExController( EXCONTROLLER_FAMILYTRAINER_B ); + } + if( crc == 0x9fae4d46 // Ide Yousuke Meijin no Jissen Mahjong (J) + || crc == 0x7b44fb2a ) { // Ide Yousuke Meijin no Jissen Mahjong 2 (J) + SetExController( EXCONTROLLER_MAHJANG ); + } + if( crc == 0x786148b6 ) { // Exciting Boxing (J) + SetExController( EXCONTROLLER_EXCITINGBOXING ); + } + if( crc == 0xc3c0811d // Oeka Kids - Anpanman no Hiragana Daisuki (J) + || crc == 0x9d048ea4 ) { // Oeka Kids - Anpanman to Oekaki Shiyou!! (J) + SetExController( EXCONTROLLER_OEKAKIDS_TABLET ); + } +#if 0 + if( crc == 0xe792de94 // Best Play - Pro Yakyuu (New) (J) + || crc == 0xf79d684a // Best Play - Pro Yakyuu (Old) (J) + || crc == 0xc2ef3422 // Best Play - Pro Yakyuu 2 (J) + || crc == 0x974e8840 // Best Play - Pro Yakyuu '90 (J) + || crc == 0xb8747abf // Best Play - Pro Yakyuu Special (J) + || crc == 0x9fa1c11f // Castle Excellent (J) + || crc == 0x0b0d4d1b // Derby Stallion - Zenkoku Ban (J) + || crc == 0x728c3d98 // Downtown - Nekketsu Monogatari (J) + || crc == 0xd68a6f33 // Dungeon Kid (J) + || crc == 0x3a51eb04 // Fleet Commander (J) + || crc == 0x7c46998b // Haja no Fuuin (J) + || crc == 0x7e5d2f1a // Itadaki Street - Watashi no Mise ni Yottette (J) + || crc == 0xcee5857b // Ninjara Hoi! (J) + || crc == 0x50ec5e8b // Wizardry - Legacy of Llylgamyn (J) + || crc == 0x343e9146 // Wizardry - Proving Grounds of the Mad Overlord (J) + || crc == 0x33d07e45 ) { // Wizardry - The Knight of Diamonds (J) + SetExController( EXCONTROLLER_TURBOFILE ); + } +#endif + + if( crc == 0x67898319 ) { // Barcode World (J) + bBarcodeWorld = TRUE; + } + + // VS-Unisystem + if( nes->rom->IsVSUNISYSTEM() ) { + if( crc == 0xff5135a3 // VS Hogan's Alley + || crc == 0xed588f00 // VS Duck Hunt + || crc == 0x17ae56be ) { // VS Freedom Force + SetExController( EXCONTROLLER_VSZAPPER ); + } else { + SetExController( EXCONTROLLER_VSUNISYSTEM ); + } + } + + if( crc == 0xf9def527 // Family BASIC(Ver2.0) + || crc == 0xde34526e // Family BASIC(Ver2.1a) + || crc == 0xf050b611 // Family BASIC(Ver3) + || crc == 0x3aaeed3f ) { // Family BASIC(Ver3)(Alt) + SetExController( EXCONTROLLER_KEYBOARD ); + } + + if( crc == 0x82F1Fb96 // [Subor] Subor V1.0 (Russian) [Mapper167] + || crc == 0xAA044941 // [Subor] Subor Win2000 (Russian) + || crc == 0xE4460DF2 // [Subor] Subor V1.1 (C) + || crc == 0x0930349E // [Subor] Subor V3.0 (C) (With Dr.Mario) + || crc == 0x6733607A // [Subor] Subor V3.0 (C) (With Chinese Chess) + || crc == 0x589b6b0d // [Subor] Subor V3.0 tpu + || crc == 0x41EF9AC4 // [Subor] Subor V4.0 (C) + || crc == 0x41401c6d // [Subor] Subor V4.0 tpu + || crc == 0x85068811 // [Subor] Subor V6.0 (C) + || crc == 0x04260DBC // [Subor] Subor V7.0 (C) + || crc == 0xE475D89A // [Subor] Subor V9.0 (C) + || crc == 0x900D9E00 // [Subor] Subor V9.1 (C) + || crc == 0x6F84076D // [Subor] Subor V10.0 (C) + || crc == 0x12D61CE8 // [Subor] Subor V11.0 (C) + || crc == 0x5F693117 // [Subor] Subor V13.0 (C) + || crc == 0xF18BC238 // [Subor] Subor V14.0 (C) + || crc == 0x366C20D7 // [Subor] Subor LOGO V1.0 (C) + || crc == 0x5E073A1B // [Subor] Subor English Word Blaster V1.0 (C) + || crc == 0x8b265862 // [Subor] Subor English tpu + || crc == 0xF9BC83B9 // [Subor] Cang Ku Shi Jia & Dong Nao Jin (C) + || crc == 0x669A32F2 // [Subor] Ma Bu Mi Zhen & Qu Wei Cheng Yu Wu (C) + || crc == 0x40139EE3 // [Subor] Tu Xing Tui Li & Zhi Li Pin Tu (C) + || crc == 0x3C8F92BD // [Subor] Zheng Fu Tai Yang Xi & Xiao Guan Jia (C) + || crc == 0x0A9329B5 // [Subor] Qi Zhi Wu A (C) + || crc == 0x15058291 // [Subor] Qi Zhi Wu B (C) + || crc == 0x60E33D27 // [Subor] Ren Shi Ma Xue Xi (C) + || crc == 0xD3906F32 // [Subor] Xiao Xue Shu Xue Jiao Shou Xi Tong - San Nian Ji (C) + || crc == 0x40A4C574 // [Subor] Yu Yin Zhi Xing Sheng Ji Mu Ka (C) + || crc == 0xCA501706 // [Subor] Yu Yin Zhi Xing Sheng Ji Mu Ka + You Sheng Ci Ba (C) + || crc == 0xFDD9321C // [Subor] Yu Yin Zhi Xing Sheng Ji Mu Ka + Xiao Xue Yu Wen Da Biao Le Yuan (C) + + || crc == 0x6A21D8F8 // [BenLi] Ben Li Dian Nao Ka (C)-1 + || crc == 0x827207FD // [BenLi] Ben Li Dian Nao Ka (C)-2 + || crc == 0xDD150A3C // [SB-918] Xue Sheng Dian Nao (C) + || crc == 0x45A9F4E5 // Chao Ba Dian Nao (C) + + || crc == 0xE90A6AEB // Jin Ka Wang - Xue Dian Nao (C) + || crc == 0x2AF63A19 // RONG FENG - Study Card (C) + || crc == 0x957ABE27 // Sheng Ba Ka (C) + || crc == 0x2726FC11 // [FengLi] Jin Ka Wang (C) + + || crc == 0xb3d11a3c // BBK bios V1.0 + || crc == 0x9c7d4833 // BBK bios V2.0 + + || crc == 0xd5d6eac4 ) { // EDU Computer (C) + SetExController( EXCONTROLLER_Subor_KEYBOARD ); + nes->SetVideoMode( 2 ); + } + + if( crc == 0xAC7E98FB // [PYRAMID] PEC-586 Computer & Game (C)_NoTapeOut + || crc == 0x6EEF8BB7 // [PYRAMID] PEC-586 Computer & Game (C) + || crc == 0x05F958C4 // [PYRAMID] PEC-686F Computer & Game (C) + || crc == 0xFE31765B // [PYRAMID] PEC-9588 Computer & Game (C) + || crc == 0x42F89EFD ) { // + SetExController( EXCONTROLLER_PEC_KEYBOARD ); + } + + if( crc == 0xAC11B570 // [Kingwon] Jin Ka V5.0 (C) + || crc == 0x8D51A23B // [KeWang] Chao Ji Wu Bi Han Ka (C) V1 + || crc == 0x2CD32DB0 // [KeWang] Dian Nao Xue Xi Ka III (C) + || crc == 0xE4284379 ) { // [PATTER] 30IN1 Han Ka Wang (C) + SetExController( EXCONTROLLER_Kingwon_KEYBOARD ); + nes->SetVideoMode( 2 ); + } + + if( crc == 0x6310DDE6 // [ZeCheng] Chao Ji Xue Xi Ka (C) + || crc == 0x25C76773 // [KeWang] Chao Ji Wu Bi Han Ka (C) V2 + || crc == 0x428C1C1D // [FengLi] Zhong Ying Wen Dian Nao Ka (C) + || crc == 0x836CDDEF // [BaTong] Zhong Ying Wen Dian Nao Ka (C) + || crc == 0x44479A27 // [BiTe] Dian Nao Xue Xi Ka (C) + || crc == 0xB93F00D3 ) { // [XinKe] Tiao Zhan Han Ka (C) + SetExController( EXCONTROLLER_ZeCheng_KEYBOARD ); + nes->SetVideoMode( 2 ); + } + + if( crc == 0x6058DB1C // [Subor] Subor V15.0 (C) [for KeyBoard] + || crc == 0xB72B17ED // Xue Sheng Dian Nao (C) [for KeyBoard] + || crc == 0x8B23F1AA // Duo Mei Ti Shu Biao Xue Xi Ka (C) + || crc == 0x85FD927E // [BenLi] Jing Pin Yi Zu - Mouse Card (C) + || crc == 0x488482c0 + || crc == 0x3BD46A90 // Game Star - Smart Genius (Unl) P1 2048K + || crc == 0xAD82BBEA ) { // Game Star - Smart Genius (Unl) + SetExController( EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE ); + } + + if( crc == 0x6085fee8 //YX_V9.0-98 + || crc == 0xdf730735 //9.2F+YXNet.NES + || crc == 0x7fb3a9aa + || crc == 0xd1f6b0fb + || crc == 0x38D982E3 ) { + SetExController( EXCONTROLLER_YuXing_Mouse ); + } + +} + +void PAD::SetExController( INT type ) +{ + excontroller_select = type; + + DELETEPTR( expad ); + + bZapperMode = FALSE; + DirectDraw.SetZapperMode( FALSE ); + DirectDraw.SetZapperDrawMode( FALSE ); + + // ExPad Instance create + switch( type ) { + case EXCONTROLLER_ZAPPER: + expad = new EXPAD_Zapper( nes ); + bZapperMode = TRUE; + DirectDraw.SetZapperMode( TRUE ); + DirectDraw.SetZapperDrawMode( TRUE ); + break; + case EXCONTROLLER_PADDLE: + expad = new EXPAD_Paddle( nes ); + DirectDraw.SetZapperMode( TRUE ); + break; + case EXCONTROLLER_HYPERSHOT: + expad = new EXPAD_HyperShot( nes ); + break; + case EXCONTROLLER_KEYBOARD: + expad = new EXPAD_Keyboard( nes ); + break; + case EXCONTROLLER_Subor_KEYBOARD: + expad = new EXPAD_Subor_Keyboard( nes ); + break; + case EXCONTROLLER_PEC_KEYBOARD: + expad = new EXPAD_PEC_Keyboard( nes ); + break; + case EXCONTROLLER_Kingwon_KEYBOARD: + expad = new EXPAD_Kingwon_Keyboard( nes ); + break; + case EXCONTROLLER_ZeCheng_KEYBOARD: + expad = new EXPAD_ZeCheng_Keyboard( nes ); + break; + case EXCONTROLLER_CRAZYCLIMBER: + expad = new EXPAD_CrazyClimber( nes ); + break; + case EXCONTROLLER_TOPRIDER: + expad = new EXPAD_Toprider( nes ); + break; + case EXCONTROLLER_SPACESHADOWGUN: + expad = new EXPAD_SpaceShadowGun( nes ); + bZapperMode = TRUE; + DirectDraw.SetZapperMode( TRUE ); + DirectDraw.SetZapperDrawMode( TRUE ); + break; + + case EXCONTROLLER_FAMILYTRAINER_A: + case EXCONTROLLER_FAMILYTRAINER_B: + expad = new EXPAD_FamlyTrainer( nes ); + break; + case EXCONTROLLER_EXCITINGBOXING: + expad = new EXPAD_ExcitingBoxing( nes ); + break; + case EXCONTROLLER_MAHJANG: + expad = new EXPAD_Mahjang( nes ); + break; + case EXCONTROLLER_OEKAKIDS_TABLET: + expad = new EXPAD_OekakidsTablet( nes ); + DirectDraw.SetZapperMode( TRUE ); + DirectDraw.SetZapperDrawMode( FALSE ); + break; + case EXCONTROLLER_TURBOFILE: + expad = new EXPAD_TurboFile( nes ); + break; + case EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE: + expad = new EXPAD_ChinaEduMouse( nes ); + DirectDraw.SetZapperMode( TRUE ); + DirectDraw.SetZapperDrawMode( TRUE ); + break; + + case EXCONTROLLER_YuXing_Mouse: + expad = new EXPAD_YuXing_Mouse( nes ); + DirectDraw.SetZapperMode( TRUE ); + DirectDraw.SetZapperDrawMode( TRUE ); + break; + + case EXCONTROLLER_VSUNISYSTEM: + expad = new EXPAD_VSUnisystem( nes ); + break; + case EXCONTROLLER_VSZAPPER: + expad = new EXPAD_VSZapper( nes ); + bZapperMode = TRUE; + DirectDraw.SetZapperMode( TRUE ); + DirectDraw.SetZapperDrawMode( TRUE ); + break; + + case EXCONTROLLER_YuXingMouse: + expad = new EXPAD_YuXingMouse( nes ); + break; + + default: + break; + } + + if( expad ) { + expad->Reset(); + } +} + +DWORD PAD::GetSyncData() +{ +DWORD ret; + + ret = (DWORD)padbit[0]|((DWORD)padbit[1]<<8)|((DWORD)padbit[2]<<16)|((DWORD)padbit[3]<<24); + ret |= (DWORD)micbit<<8; + + return ret; +} + +void PAD::SetSyncData( DWORD data ) +{ + micbit = (BYTE)((data&0x00000400)>>8); + padbit[0] = (BYTE) data; + padbit[1] = (BYTE)(data>> 8); + padbit[2] = (BYTE)(data>>16); + padbit[3] = (BYTE)(data>>24); +} + +DWORD PAD::GetSyncExData() +{ +DWORD data = 0; + + switch( excontroller_select ) { + case EXCONTROLLER_ZAPPER: + case EXCONTROLLER_PADDLE: + case EXCONTROLLER_SPACESHADOWGUN: + case EXCONTROLLER_OEKAKIDS_TABLET: + case EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE: + case EXCONTROLLER_YuXing_Mouse: + case EXCONTROLLER_VSZAPPER: + case EXCONTROLLER_YuXingMouse: + { + LONG x, y; + x = expad->GetSyncData( 0 ); + y = expad->GetSyncData( 1 ); + if( x == -1 || y == -1 ) { + data = 0x80000000; + } else { + data = (x&0xFF)|((y&0xFF)<<8); + } + } + if( excontroller_select != EXCONTROLLER_SPACESHADOWGUN ) { + if( expad->GetSyncData( 2 ) ) + data |= 0x0010000; + } else { + data |= (DWORD)expad->GetSyncData( 2 )<<16; + } + break; + case EXCONTROLLER_CRAZYCLIMBER: + data = (DWORD)expad->GetSyncData( 0 ); + break; + case EXCONTROLLER_TOPRIDER: + data = (DWORD)expad->GetSyncData( 0 ); + break; + case EXCONTROLLER_FAMILYTRAINER_A: + case EXCONTROLLER_FAMILYTRAINER_B: + data = (DWORD)expad->GetSyncData( 0 ); + break; + case EXCONTROLLER_EXCITINGBOXING: + data = (DWORD)expad->GetSyncData( 0 ); + break; + case EXCONTROLLER_MAHJANG: + data = (DWORD)expad->GetSyncData( 0 ); + break; + + default: + break; + } + return data; +} + +void PAD::SetSyncExData( DWORD data ) +{ +//DEBUGOUT( "PAD::SetSyncExData\n" ); + switch( excontroller_select ) { + case EXCONTROLLER_ZAPPER: + case EXCONTROLLER_PADDLE: + case EXCONTROLLER_SPACESHADOWGUN: + case EXCONTROLLER_OEKAKIDS_TABLET: + case EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE: + case EXCONTROLLER_YuXing_Mouse: + case EXCONTROLLER_VSZAPPER: + case EXCONTROLLER_YuXingMouse: + { + LONG x, y; + if( data & 0x80000000 ) { + x = -1; + y = -1; + } else { + x = data & 0xFF; + y = (data&0xFF00)>>8; + } + expad->SetSyncData( 0, x ); + expad->SetSyncData( 1, y ); + nes->SetZapperPos( x, y ); + DirectDraw.SetZapperPos( x, y ); + } + if( excontroller_select != EXCONTROLLER_SPACESHADOWGUN ) { + if( data & 0x0010000 ) + expad->SetSyncData( 2, 1 ); + else + expad->SetSyncData( 2, 0 ); + } else { + expad->SetSyncData( 2, (BYTE)(data>>16) ); + } + break; + case EXCONTROLLER_CRAZYCLIMBER: + expad->SetSyncData( 0, (LONG)data ); + break; + case EXCONTROLLER_TOPRIDER: + expad->SetSyncData( 0, (LONG)data ); + break; + case EXCONTROLLER_FAMILYTRAINER_A: + case EXCONTROLLER_FAMILYTRAINER_B: + expad->SetSyncData( 0, (LONG)data ); + break; + case EXCONTROLLER_EXCITINGBOXING: + expad->SetSyncData( 0, (LONG)data ); + break; + case EXCONTROLLER_MAHJANG: + expad->SetSyncData( 0, (LONG)data ); + break; + default: + break; + } +} + +void PAD::Sync() +{ + padbit[0] = SyncSub( 0 ); + padbit[1] = SyncSub( 1 ); + padbit[2] = SyncSub( 2 ); + padbit[3] = SyncSub( 3 ); + + // Mic + micbit = 0; + if( Config.ButtonCheck( 1, 10 ) ) micbit |= 4; + + // For Excontroller + if( expad ) { + expad->Sync(); + } + + // For NSF + NsfSub(); +} + +void PAD::VSync() +{ + padbitsync[0] = padbit[0]; + padbitsync[1] = padbit[1]; + padbitsync[2] = padbit[2]; + padbitsync[3] = padbit[3]; + micbitsync = micbit; +} + +static INT ren30fps[] = { + 1, 0 +}; +static INT ren20fps[] = { + 1, 1, 0 +}; +static INT ren15fps[] = { + 1, 1, 0, 0 +}; +static INT ren10fps[] = { + 1, 1, 1, 0, 0, 0 +}; + +static INT renmask[] = { + 6, 4, 3, 2, +}; +static INT* rentbl[] = { + ren10fps, ren15fps, ren20fps, ren30fps +}; + +BYTE PAD::SyncSub( INT no ) +{ +WORD bit = 0; + + // Up + if( Config.ButtonCheck( no, 0 ) ) bit |= 1<<4; + // Down + if( Config.ButtonCheck( no, 1 ) ) bit |= 1<<5; + // Left + if( Config.ButtonCheck( no, 2 ) ) bit |= 1<<6; + // Right + if( Config.ButtonCheck( no, 3 ) ) bit |= 1<<7; + + // ͂֎~ + if( (bit&((1<<4)|(1<<5))) == ((1<<4)|(1<<5)) ) + bit &= ~((1<<4)|(1<<5)); + if( (bit&((1<<6)|(1<<7))) == ((1<<6)|(1<<7)) ) + bit &= ~((1<<6)|(1<<7)); + + // A + if( Config.ButtonCheck( no, 4 ) ) bit |= 1<<0; + // B + if( Config.ButtonCheck( no, 5 ) ) bit |= 1<<1; + + // A,B Rapid + if( Config.ButtonCheck( no, 6 ) ) bit |= 1<<8; + if( Config.ButtonCheck( no, 7 ) ) bit |= 1<<9; + + // Select + if( Config.ButtonCheck( no, 8 ) ) bit |= 1<<2; + // Start + if( Config.ButtonCheck( no, 9 ) ) bit |= 1<<3; + + // A rapid setup + if( bit&(1<<8) ) { + INT spd = Config.controller.nRapid[no][0]; + if( spd >= 3 ) spd = 3; + INT* tbl = rentbl[spd]; + + if( padcnt[no][0] >= renmask[spd] ) + padcnt[no][0] = 0; + + if( tbl[padcnt[no][0]] ) + bit |= (1<<0); + else + bit &= ~(1<<0); + + padcnt[no][0]++; + } else { + padcnt[no][0] = 0; + } + // B rapid setup + if( bit&(1<<9) ) { + INT spd = Config.controller.nRapid[no][1]; + if( spd >= 3 ) spd = 3; + INT* tbl = rentbl[spd]; + + if( padcnt[no][1] >= renmask[spd] ) + padcnt[no][1] = 0; + + if( tbl[padcnt[no][1]] ) + bit |= (1<<1); + else + bit &= ~(1<<1); + + padcnt[no][1]++; + } else { + padcnt[no][1] = 0; + } + + return (BYTE)(bit&0xFF); +} + +void PAD::Strobe() +{ + // For VS-Unisystem + if( nes->rom->IsVSUNISYSTEM() ) { + DWORD pad1 = (DWORD)padbitsync[0] & 0xF3; + DWORD pad2 = (DWORD)padbitsync[1] & 0xF3; + DWORD st1 = ((DWORD)padbitsync[0] & 0x08)>>3; + DWORD st2 = ((DWORD)padbitsync[1] & 0x08)>>3; + + switch( nVSSwapType ) { + case VS_TYPE0: + pad1bit = pad1 | (st1<<2); + pad2bit = pad2 | (st2<<2); + break; + case VS_TYPE1: + pad1bit = pad2 | (st1<<2); + pad2bit = pad1 | (st2<<2); + break; + case VS_TYPE2: + pad1bit = pad1 | (st1<<2) | (st2<<3); + pad2bit = pad2; + break; + case VS_TYPE3: + pad1bit = pad2 | (st1<<2) | (st2<<3); + pad2bit = pad1; + break; + case VS_TYPE4: + pad1bit = pad1 | (st1<<2) | 0x08; // 0x08=Start Protect + pad2bit = pad2 | (st2<<2) | 0x08; // 0x08=Start Protect + break; + case VS_TYPE5: + pad1bit = pad2 | (st1<<2) | 0x08; // 0x08=Start Protect + pad2bit = pad1 | (st2<<2) | 0x08; // 0x08=Start Protect + break; + case VS_TYPE6: + pad1bit = pad1 | (st1<<2) | (((DWORD)padbitsync[0] & 0x04)<<1); + pad2bit = pad2 | (st2<<2) | (((DWORD)padbitsync[1] & 0x04)<<1); + break; + case VS_TYPEZ: + pad1bit = 0; + pad2bit = 0; + break; + } + + // Coin 2Ɣׂɏ + micbit = 0; + } else { + if( Config.emulator.bFourPlayer ) { + // NES type + pad1bit = (DWORD)padbitsync[0] | ((DWORD)padbitsync[2]<<8) | 0x00080000; + pad2bit = (DWORD)padbitsync[1] | ((DWORD)padbitsync[3]<<8) | 0x00040000; + } else { + // Famicom type + pad1bit = (DWORD)padbitsync[0]; + pad2bit = (DWORD)padbitsync[1]; + } + } + pad3bit = (DWORD)padbitsync[2]; + pad4bit = (DWORD)padbitsync[3]; +} + +BYTE PAD::Read( WORD addr ) +{ +BYTE data = 0x00; + + if( addr == 0x4016 ) { + data = (BYTE)pad1bit&1; + pad1bit>>=1; + data |= ((BYTE)pad3bit&1)<<1; + pad3bit>>=1; + // Mic + if( !nes->rom->IsVSUNISYSTEM() ) { + data |= micbitsync; + } + if( expad ) { + data |= expad->Read4016(); + } + } + if( addr == 0x4017 ) { + data = (BYTE)pad2bit&1; + pad2bit>>=1; + data |= ((BYTE)pad4bit&1)<<1; + pad4bit>>=1; + + if( expad ) { + data |= expad->Read4017(); + } + + if( bBarcodeWorld ) { + data |= nes->Barcode2(); + } + } + +// DEBUGOUT( "Read - addr= %04x ; dat= %03x\n", addr, data ); + + return data; +} + +void PAD::Write( WORD addr, BYTE data ) +{ + if( addr == 0x4016 ) { + if( data&0x01 ) { + bStrobe = TRUE; + } else if( bStrobe ) { + bStrobe = FALSE; + + Strobe(); + if( expad ) { + expad->Strobe(); + } + } + + if( expad ) { + expad->Write4016( data ); + } + } + if( addr == 0x4017 ) { + if( expad ) { + expad->Write4017( data ); + } + } + +// DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); + +} + +void PAD::NsfSub() +{ + nsfbit = 0; + + // Play + if( Config.ButtonCheck( 0, Config.controller.nNsfButton ) ) nsfbit |= 1<<0; + // Stop + if( Config.ButtonCheck( 1, Config.controller.nNsfButton ) ) nsfbit |= 1<<1; + + // Number -1 + if( Config.ButtonCheck( 2, Config.controller.nNsfButton ) ) nsfbit |= 1<<2; + // Number +1 + if( Config.ButtonCheck( 3, Config.controller.nNsfButton ) ) nsfbit |= 1<<3; + // Number -16 + if( Config.ButtonCheck( 4, Config.controller.nNsfButton ) ) nsfbit |= 1<<4; + // Number +16 + if( Config.ButtonCheck( 5, Config.controller.nNsfButton ) ) nsfbit |= 1<<5; + + // ͂֎~ + if( (nsfbit&((1<<2)|(1<<3))) == ((1<<2)|(1<<3)) ) + nsfbit &= ~((1<<2)|(1<<3)); + if( (nsfbit&((1<<4)|(1<<5))) == ((1<<4)|(1<<5)) ) + nsfbit &= ~((1<<4)|(1<<5)); +} + +#include "EXPAD_Zapper.cpp" +#include "EXPAD_Paddle.cpp" +#include "EXPAD_HyperShot.cpp" +#include "EXPAD_Keyboard.cpp" +#include "EXPAD_Subor_Keyboard.cpp" +#include "EXPAD_PEC_Keyboard.cpp" +#include "EXPAD_Kingwon_Keyboard.cpp" +#include "EXPAD_ZeCheng_Keyboard.cpp" +#include "EXPAD_YuXing_Mouse.cpp" +#include "EXPAD_CrazyClimber.cpp" +#include "EXPAD_Toprider.cpp" +#include "EXPAD_SpaceShadowGun.cpp" + +#include "EXPAD_FamlyTrainer.cpp" +#include "EXPAD_ExcitingBoxing.cpp" +#include "EXPAD_Mahjang.cpp" +#include "EXPAD_OekakidsTablet.cpp" +#include "EXPAD_TurboFile.cpp" + +#include "EXPAD_VSUnisystem.cpp" +#include "EXPAD_VSZapper.cpp" + +#include "EXPAD_ChinaEduMouse.cpp" +#include "EXPAD_YuXingMouse.cpp" \ No newline at end of file diff --git a/References/VirtuaNESex_src_191105/NES/PAD.h b/References/VirtuaNESex_src_191105/NES/PAD.h new file mode 100644 index 00000000..64bd6278 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PAD.h @@ -0,0 +1,173 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES Pad // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// + +#ifndef __PAD_INCLUDED__ +#define __PAD_INCLUDED__ + +#include "typedef.h" +#include "macro.h" + +// class prototypes +class NES; +class EXPAD; + +class PAD +{ +public: + PAD( NES* parent ); + virtual ~PAD(); + +// o֐ + void Reset(); + + // For movie + DWORD GetSyncData(); + void SetSyncData( DWORD data ); + + DWORD GetSyncExData(); + void SetSyncExData( DWORD data ); + + void VSync(); + + void Sync(); + BYTE SyncSub( INT no ); + + void SetStrobe( BOOL bStrb ) { bStrobe = bStrb; } + BOOL GetStrobe() { return bStrobe; } + + void Strobe(); + WORD StrobeSub( INT no ); + + BYTE Read( WORD addr ); + void Write( WORD addr, BYTE data ); + + void SetExController( INT type ); + INT GetExController() { return excontroller_select; } + + BOOL IsZapperMode() { return bZapperMode; }; + + // For VS-Unisystem + void SetSwapPlayer( BOOL bSwap ) { bSwapPlayer = bSwap; } + void SetSwapButton( BOOL bSwap ) { bSwapButton = bSwap; } + void SetVSType( INT nType ) { nVSSwapType = nType; } + + enum { + VS_TYPE0 = 0, // SELECT1P=START1P/SELECT2P=START2P 1P/2P No reverse + VS_TYPE1, // SELECT1P=START1P/SELECT2P=START2P 1P/2P Reverse + VS_TYPE2, // SELECT1P=START1P/START1P =START2P 1P/2P No reverse + VS_TYPE3, // SELECT1P=START1P/START1P =START2P 1P/2P Reverse + VS_TYPE4, // SELECT1P=START1P/SELECT2P=START2P 1P/2P No reverse (Protection) + VS_TYPE5, // SELECT1P=START1P/SELECT2P=START2P 1P/2P Reverse (Protection) + VS_TYPE6, // SELECT1P=START1P/SELECT2P=START2P 1P/2P Reverse (For Golf) + VS_TYPEZ, // ZAPPER + }; + + enum EXCONTROLLER { + EXCONTROLLER_NONE = 0, + EXCONTROLLER_PADDLE, + EXCONTROLLER_HYPERSHOT, + EXCONTROLLER_ZAPPER, + EXCONTROLLER_KEYBOARD, + EXCONTROLLER_Subor_KEYBOARD, + EXCONTROLLER_PEC_KEYBOARD, + EXCONTROLLER_Kingwon_KEYBOARD, + EXCONTROLLER_ZeCheng_KEYBOARD, + EXCONTROLLER_CRAZYCLIMBER, + EXCONTROLLER_TOPRIDER, + EXCONTROLLER_SPACESHADOWGUN, + + EXCONTROLLER_FAMILYTRAINER_A, + EXCONTROLLER_FAMILYTRAINER_B, + EXCONTROLLER_EXCITINGBOXING, + EXCONTROLLER_MAHJANG, + EXCONTROLLER_OEKAKIDS_TABLET, + EXCONTROLLER_TURBOFILE, + + EXCONTROLLER_CHINA_EDUCATIONAL_MOUSE, + + EXCONTROLLER_YuXing_Mouse, + + EXCONTROLLER_VSUNISYSTEM, + EXCONTROLLER_VSZAPPER, + + EXCONTROLLER_YuXingMouse, + + }; + + DWORD pad1bit, pad2bit; + DWORD pad3bit, pad4bit; + + // Frame Synchronized + LONG zapperx, zappery; + BYTE zapperbit; + BYTE crazyclimberbit; + + // For NSF Player + BYTE GetNsfController() { return nsfbit; } + +protected: + NES* nes; + // Extension Devices + EXPAD* expad; + + // Frame Synchronized + BYTE padbit[4]; + BYTE micbit; + + BYTE padbitsync[4]; + BYTE micbitsync; + + INT excontroller_select; + INT padcnt[4][2]; + + BOOL bStrobe; + BOOL bZapperMode; + + // For VS-Unisystem + INT nVSSwapType; + BOOL bSwapPlayer; + BOOL bSwapButton; + + // For BarcodeWorld + BOOL bBarcodeWorld; + + // For NSF Player + void NsfSub(); + + BYTE nsfbit; +private: +}; + +#include "EXPAD.h" +#include "EXPAD_Zapper.h" +#include "EXPAD_Paddle.h" +#include "EXPAD_HyperShot.h" +#include "EXPAD_Keyboard.h" +#include "EXPAD_Subor_Keyboard.h" +#include "EXPAD_PEC_Keyboard.h" +#include "EXPAD_Kingwon_Keyboard.h" +#include "EXPAD_ZeCheng_Keyboard.h" +#include "EXPAD_YuXing_Mouse.h" +#include "EXPAD_CrazyClimber.h" +#include "EXPAD_Toprider.h" +#include "EXPAD_SpaceShadowGun.h" + +#include "EXPAD_FamlyTrainer.h" +#include "EXPAD_ExcitingBoxing.h" +#include "EXPAD_Mahjang.h" +#include "EXPAD_OekakidsTablet.h" +#include "EXPAD_TurboFile.h" + +#include "EXPAD_VSUnisystem.h" +#include "EXPAD_VSZapper.h" +#include "EXPAD_ChinaEduMouse.h" + +#include "EXPAD_YuXingMouse.h" + +#endif // !__PAD_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/PPU.cpp b/References/VirtuaNESex_src_191105/NES/PPU.cpp new file mode 100644 index 00000000..63ac50b6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PPU.cpp @@ -0,0 +1,964 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES PPU core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "VirtuaNESres.h" + +#include "typedef.h" +#include "macro.h" + +#include "DebugOut.h" +#include "App.h" + +#include "nes.h" +#include "mmu.h" +#include "cpu.h" +#include "ppu.h" +#include "rom.h" +#include "mapper.h" + +BYTE PPU::VSColorMap[5][64] = { + { 0x35, 0xFF, 0x16, 0x22, 0x1C, 0xFF, 0xFF, 0x15, + 0xFF, 0x00, 0x27, 0x05, 0x04, 0x27, 0x08, 0x30, + 0x21, 0xFF, 0xFF, 0x29, 0x3C, 0xFF, 0x36, 0x12, + 0xFF, 0x2B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0xFF, 0x31, 0xFF, 0x2A, 0x2C, 0x0C, 0xFF, 0xFF, + 0xFF, 0x07, 0x34, 0x06, 0x13, 0xFF, 0x26, 0x0F, + 0xFF, 0x19, 0x10, 0x0A, 0xFF, 0xFF, 0xFF, 0x17, + 0xFF, 0x11, 0x09, 0xFF, 0xFF, 0x25, 0x18, 0xFF + }, + { 0xFF, 0x27, 0x18, 0xFF, 0x3A, 0x25, 0xFF, 0x31, +// 0x16, 0x13, 0x38, 0x34, 0x20, 0x23, 0xFF, 0x0B, + 0x16, 0x13, 0x38, 0x34, 0x20, 0x23, 0xFF, 0x1A, + 0xFF, 0x21, 0x06, 0xFF, 0x1B, 0x29, 0xFF, 0x22, + 0xFF, 0x24, 0xFF, 0xFF, 0xFF, 0x08, 0xFF, 0x03, + 0xFF, 0x36, 0x26, 0x33, 0x11, 0xFF, 0x10, 0x02, + 0x14, 0xFF, 0x00, 0x09, 0x12, 0x0F, 0xFF, 0x30, + 0xFF, 0xFF, 0x2A, 0x17, 0x0C, 0x01, 0x15, 0x19, + 0xFF, 0x2C, 0x07, 0x37, 0xFF, 0x05, 0xFF, 0xFF + }, +#if 1 + { 0xFF, 0xFF, 0xFF, 0x10, 0x1A, 0x30, 0x31, 0x09, + 0x01, 0x0F, 0x36, 0x08, 0x15, 0xFF, 0xFF, 0xF0, + 0x22, 0x1C, 0xFF, 0x12, 0x19, 0x18, 0x17, 0xFF, + 0x00, 0xFF, 0xFF, 0x02, 0x16, 0x06, 0xFF, 0x35, + 0x23, 0xFF, 0x8B, 0xF7, 0xFF, 0x27, 0x26, 0x20, + 0x29, 0xFF, 0x21, 0x24, 0x11, 0xFF, 0xEF, 0xFF, + 0x2C, 0xFF, 0xFF, 0xFF, 0x07, 0xF9, 0x28, 0xFF, + 0x0A, 0xFF, 0x32, 0x37, 0x13, 0xFF, 0xFF, 0x0C + }, +#else + { 0xFF, 0xFF, 0xFF, 0x10, 0x0B, 0x30, 0x31, 0x09, // 00-07 + 0x01, 0x0F, 0x36, 0x08, 0x15, 0xFF, 0xFF, 0x3C, // 08-0F + 0x22, 0x1C, 0xFF, 0x12, 0x19, 0x18, 0x17, 0x1B, // 10-17 + 0x00, 0xFF, 0xFF, 0x02, 0x16, 0x06, 0xFF, 0x35, // 18-1F + 0x23, 0xFF, 0x8B, 0x3C, 0xFF, 0x27, 0x26, 0x20, // 20-27 + 0x29, 0x04, 0x21, 0x24, 0x11, 0xFF, 0xEF, 0xFF, // 28-2F + 0x2C, 0xFF, 0xFF, 0xFF, 0x07, 0x39, 0x28, 0xFF, // 30-37 + 0x0A, 0xFF, 0x32, 0x38, 0x13, 0x3B, 0xFF, 0x0C // 38-3F + }, +#endif +#if 0 + { 0x18, 0xFF, 0x1C, 0x89, 0x0F, 0xFF, 0x01, 0x17, + 0x10, 0x0F, 0x2A, 0xFF, 0x36, 0x37, 0x1A, 0xFF, + 0x25, 0xFF, 0x12, 0xFF, 0x0F, 0xFF, 0xFF, 0x26, + 0xFF, 0xFF, 0x22, 0xFF, 0xFF, 0x0F, 0x3A, 0x21, + 0x05, 0x0A, 0x07, 0xC2, 0x13, 0xFF, 0x00, 0x15, + 0x0C, 0xFF, 0x11, 0xFF, 0xFF, 0x38, 0xFF, 0xFF, + 0xFF, 0xFF, 0x08, 0x45, 0xFF, 0xFF, 0x30, 0x3C, + 0x0F, 0x27, 0xFF, 0x60, 0x29, 0xFF, 0x30, 0x09 + }, +#else + { 0x18, 0xFF, 0x1C, 0x89, 0x0F, 0xFF, 0x01, 0x17, // 00-07 + 0x10, 0x0F, 0x2A, 0xFF, 0x36, 0x37, 0x1A, 0xFF, // 08-0F + 0x25, 0xFF, 0x12, 0xFF, 0x0F, 0xFF, 0xFF, 0x26, // 10-17 + 0xFF, 0xFF, 0x22, 0xFF, 0xFF, 0x0F, 0x3A, 0x21, // 18-1F + 0x05, 0x0A, 0x07, 0xC2, 0x13, 0xFF, 0x00, 0x15, // 20-27 + 0x0C, 0xFF, 0x11, 0xFF, 0xFF, 0x38, 0xFF, 0xFF, // 28-2F + 0xFF, 0xFF, 0x08, 0x16, 0xFF, 0xFF, 0x30, 0x3C, // 30-37 + 0x0F, 0x27, 0xFF, 0x60, 0x29, 0xFF, 0x30, 0x09 // 38-3F + }, +#endif + { + // Super Xevious/Gradius + 0x35, 0xFF, 0x16, 0x22, 0x1C, 0x09, 0xFF, 0x15, // 00-07 + 0x20, 0x00, 0x27, 0x05, 0x04, 0x28, 0x08, 0x30, // 08-0F + 0x21, 0xFF, 0xFF, 0x29, 0x3C, 0xFF, 0x36, 0x12, // 10-17 + 0xFF, 0x2B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, // 18-1F + 0xFF, 0x31, 0xFF, 0x2A, 0x2C, 0x0C, 0x1B, 0xFF, // 20-27 + 0xFF, 0x07, 0x34, 0x06, 0xFF, 0x25, 0x26, 0x0F, // 28-2F + 0xFF, 0x19, 0x10, 0x0A, 0xFF, 0xFF, 0xFF, 0x17, // 30-37 + 0xFF, 0x11, 0x1A, 0xFF, 0x38, 0xFF, 0x18, 0x3A, // 38-3F + } +}; + +PPU::PPU( NES* parent ) : nes(parent) +{ + lpScreen = NULL; + lpColormode = NULL; + + bVSMode = FALSE; + nVSColorMap = -1; + VSSecurityData = 0; + bVromWe = 0; + + // E]}XNe[u + for( INT i = 0; i < 256; i++ ) { + BYTE m = 0x80; + BYTE c = 0; + for( INT j = 0; j < 8; j++ ) { + if( i&(1<>= 1; + } + Bit2Rev[i] = c; + } +} + +PPU::~PPU() +{ +} + +void PPU::Reset() +{ + bExtLatch = FALSE; + bChrLatch = FALSE; + bExtNameTable = FALSE; + bExtMono = FALSE; + + PPUREG[0] = PPUREG[1] = 0; + + PPU56Toggle = 0; +// PPU7_Temp = 0xFF; // VS ExcitebikełȂ($2006ǂ݂ɍsoO) + PPU7_Temp = 0; + loopy_v = loopy_t = 0; + loopy_x = loopy_y = 0; + loopy_shift = 0; + + if( lpScreen ) + ::memset( lpScreen, 0x3F, SCREEN_WIDTH*SCREEN_HEIGHT*sizeof(BYTE) ); + + if( lpColormode ) + ::memset( lpColormode, 0, SCREEN_HEIGHT*sizeof(BYTE) ); +} + +BYTE PPU::Read( WORD addr ) +{ +BYTE data = 0x00; + + switch( addr ) { + // Write only Register + case 0x2000: // PPU Control Register #1(W) + case 0x2001: // PPU Control Register #2(W) + case 0x2003: // SPR-RAM Address Register(W) + case 0x2005: // PPU Scroll Register(W2) + case 0x2006: // VRAM Address Register(W2) + data = PPU7_Temp; // + break; + // Read/Write Register + case 0x2002: // PPU Status Register(R) + data = PPUREG[2] | VSSecurityData; + PPU56Toggle = 0; + PPUREG[2] &= ~PPU_VBLANK_FLAG; + break; + case 0x2004: // SPR_RAM I/O Register(RW) + data = SPRAM[ PPUREG[3]++ ]; + break; + case 0x2007: // VRAM I/O Register(RW) + WORD addr = loopy_v & 0x3FFF; + data = PPU7_Temp; + if( PPUREG[0] & PPU_INC32_BIT ) loopy_v+=32; + else loopy_v++; + if( addr >= 0x3000 ) { + if( addr >= 0x3F00 ) { +// data &= 0x3F; + if( !(addr&0x0010) ) { + return BGPAL[addr&0x000F]; + } else { + return SPPAL[addr&0x000F]; + } + } + addr &= 0xEFFF; + } + + if( bChrLatch ) { + nes->mapper->PPU_ChrLatch( addr ); + } + + PPU7_Temp = PPU_MEM_BANK[addr>>10][addr&0x03FF]; + } + + return data; +} + +void PPU::Write( WORD addr, BYTE data ) +{ + if( bVSMode && VSSecurityData ) { + if( addr == 0x2000 ) { + addr = 0x2001; + } else if( addr == 0x2001 ){ + addr = 0x2000; + } + } + + switch( addr ) { + case 0x2008: + //for SB2000 + break; + case 0x2010: + case 0x2011: + case 0x2012: + case 0x2013: + case 0x2014: + case 0x2015: + case 0x2016: + case 0x2017: + case 0x2018: + case 0x2019: + case 0x201A: + case 0x201B: + case 0x201C: + case 0x201D: + case 0x201E: + case 0x201F: + nes->mapper->WriteExPPU(addr, data); + break; + + // Read only Register + case 0x2002: // PPU Status register(R) + break; + // Write Register + case 0x2000: // PPU Control Register #1(W) + // NameTable select + // t:0000110000000000=d:00000011 + loopy_t = (loopy_t & 0xF3FF)|(((WORD)data & 0x03)<<10); + + if( (data & 0x80) && !(PPUREG[0] & 0x80) && (PPUREG[2] & 0x80) ) { + nes->cpu->NMI(); // hmm.. + } + + PPUREG[0] = data; + break; + case 0x2001: // PPU Control Register #2(W) + PPUREG[1] = data; + break; + case 0x2003: // SPR-RAM Address Register(W) + PPUREG[3] = data; + break; + case 0x2004: // SPR_RAM I/O Register(RW) + SPRAM[ PPUREG[3]++ ] = data; + break; + + case 0x2005: // PPU Scroll Register(W2) + if( !PPU56Toggle ) { + // First write + // tile X t:0000000000011111=d:11111000 + loopy_t = (loopy_t & 0xFFE0)|(((WORD)data)>>3); + // scroll offset X x=d:00000111 + loopy_x = data & 0x07; + } else { + // Second write + // tile Y t:0000001111100000=d:11111000 + loopy_t = (loopy_t & 0xFC1F)|((((WORD)data) & 0xF8)<<2); + // scroll offset Y t:0111000000000000=d:00000111 + loopy_t = (loopy_t & 0x8FFF)|((((WORD)data) & 0x07)<<12); + } + PPU56Toggle = !PPU56Toggle; + break; + case 0x2006: // VRAM Address Register(W2) + if( !PPU56Toggle ) { + // First write + // t:0011111100000000=d:00111111 + // t:1100000000000000=0 + loopy_t = (loopy_t & 0x00FF)|((((WORD)data) & 0x3F)<<8); + } else { + // Second write + // t:0000000011111111=d:11111111 + loopy_t = (loopy_t & 0xFF00)|(WORD)data; + // v=t + loopy_v = loopy_t; + + nes->mapper->PPU_Latch( loopy_v ); + } + PPU56Toggle = !PPU56Toggle; + break; + + case 0x2007: // VRAM I/O Register(RW) + WORD vaddr = loopy_v & 0x3FFF; + if( PPUREG[0] & PPU_INC32_BIT ) loopy_v+=32; + else loopy_v++; + + if( vaddr >= 0x3000 ) { + if( vaddr >= 0x3F00 ) { + data &= 0x3F; + if( bVSMode && nVSColorMap != -1 ) { + BYTE temp = VSColorMap[nVSColorMap][data]; + if( temp != 0xFF ) { + data = temp & 0x3F; + } + } + + if( !(vaddr&0x000F) ) { + BGPAL[0] = SPPAL[0] = data; + } else if( !(vaddr&0x0010) ) { + BGPAL[vaddr&0x000F] = data; + } else { + SPPAL[vaddr&0x000F] = data; + } + BGPAL[0x04] = BGPAL[0x08] = BGPAL[0x0C] = BGPAL[0x00]; + SPPAL[0x00] = SPPAL[0x04] = SPPAL[0x08] = SPPAL[0x0C] = BGPAL[0x00]; + return; + } + vaddr &= 0xEFFF; + } + + int bank = vaddr>>10; + vaddr &= 0x03ff; + + if( PPU_MEM_TYPE[bank] != BANKTYPE_VROM ){ + PPU_MEM_BANK[bank][vaddr] = data; + }else if( bVromWe ) { + PPU_MEM_BANK[bank][vaddr] = data; + VROM_WRITED[PPU_MEM_PAGE[bank]] = 1; + } + + break; + + } +} + +void PPU::DMA( BYTE data ) +{ +WORD addr = data<<8; + + for( INT i = 0; i < 256; i++ ) { + SPRAM[i] = nes->Read( addr+i ); + } +} + +void PPU::VBlankStart() +{ + PPUREG[2] |= PPU_VBLANK_FLAG; +// PPUREG[2] |= PPU_SPHIT_FLAG; // VBlank˓ɕKONH +} + +void PPU::VBlankEnd() +{ + PPUREG[2] &= ~PPU_VBLANK_FLAG; + // VBlankEoɃNA + // GLTCgoCNŏdv + PPUREG[2] &= ~PPU_SPHIT_FLAG; +} + +void PPU::FrameStart() +{ + if( PPUREG[1] & (PPU_SPDISP_BIT|PPU_BGDISP_BIT) ) { + loopy_v = loopy_t; + loopy_shift = loopy_x; + loopy_y = (loopy_v&0x7000)>>12; + } + + if( lpScreen ) { + ::memset( lpScreen, 0x3F, SCREEN_WIDTH*sizeof(BYTE) ); + } + if( lpColormode ) { + lpColormode[0] = 0; + } +} + +void PPU::FrameEnd() +{ +} + +void PPU::SetRenderScanline( INT scanline ) +{ + ScanlineNo = scanline; + if( scanline < 240 ) { + lpScanline = lpScreen+SCREEN_WIDTH*scanline; + } +} + +void PPU::ScanlineStart() +{ + if( PPUREG[1] & (PPU_BGDISP_BIT|PPU_SPDISP_BIT) ) { + loopy_v = (loopy_v & 0xFBE0)|(loopy_t & 0x041F); + loopy_shift = loopy_x; + loopy_y = (loopy_v&0x7000)>>12; + nes->mapper->PPU_Latch( 0x2000 + (loopy_v & 0x0FFF) ); + } +} + +void PPU::ScanlineNext() +{ + if( PPUREG[1] & (PPU_BGDISP_BIT|PPU_SPDISP_BIT) ) { + if( (loopy_v & 0x7000) == 0x7000 ) { + loopy_v &= 0x8FFF; + if( (loopy_v & 0x03E0) == 0x03A0 ) { + loopy_v ^= 0x0800; + loopy_v &= 0xFC1F; + } else { + if( (loopy_v & 0x03E0) == 0x03E0 ) { + loopy_v &= 0xFC1F; + } else { + loopy_v += 0x0020; + } + } + } else { + loopy_v += 0x1000; + } + loopy_y = (loopy_v&0x7000)>>12; + } +} + +void PPU::Scanline( INT scanline, BOOL bMax, BOOL bLeftClip ) +{ +BYTE BGwrite[33+1]; +BYTE BGmono[33+1]; +BYTE sppadr_offset; //for YuXing and PYRAMID + + ZEROMEMORY( BGwrite, sizeof(BGwrite) ); + ZEROMEMORY( BGmono, sizeof(BGmono) ); + sppadr_offset = 0; + + // Linecolor mode + lpColormode[scanline] = ((PPUREG[1]&PPU_BGCOLOR_BIT)>>5)|((PPUREG[1]&PPU_COLORMODE_BIT)<<7); + + // Render BG + if( !(PPUREG[1]&PPU_BGDISP_BIT) ) { + ::memset( lpScanline, BGPAL[0], SCREEN_WIDTH ); + if( nes->GetRenderMethod() == NES::TILE_RENDER ) { + nes->EmulationCPU( FETCH_CYCLES*4*32 ); + } + } else { + if( nes->GetRenderMethod() != NES::TILE_RENDER ) { + if( !bExtLatch ) { + // Without Extension Latch + LPBYTE pScn = lpScanline+(8-loopy_shift); + LPBYTE pBGw = BGwrite; + + INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8; + INT ntbladr = 0x2000+(loopy_v&0x0FFF); + INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4); + INT ntbl_x = ntbladr&0x001F; + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + + INT tileadr; + INT cache_tile = 0xFFFF0000; + BYTE cache_attr = 0xFF; + + BYTE chr_h, chr_l, attr; + + attradr &= 0x3FF; + + for( INT i = 0; i < 33; i++ ) { + tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + + if( cache_tile == tileadr && cache_attr == attr ) { + *(LPDWORD)(pScn+0) = *(LPDWORD)(pScn-8); + *(LPDWORD)(pScn+4) = *(LPDWORD)(pScn-4); + *(pBGw+0) = *(pBGw-1); + } else { + cache_tile = tileadr; + cache_attr = attr; + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + *pBGw = chr_h|chr_l; + + LPBYTE pBGPAL = &BGPAL[attr]; + { + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + pScn[0] = pBGPAL[(c1>>6)]; + pScn[4] = pBGPAL[(c1>>2)&3]; + pScn[1] = pBGPAL[(c2>>6)]; + pScn[5] = pBGPAL[(c2>>2)&3]; + pScn[2] = pBGPAL[(c1>>4)&3]; + pScn[6] = pBGPAL[c1&3]; + pScn[3] = pBGPAL[(c2>>4)&3]; + pScn[7] = pBGPAL[c2&3]; + } + } + pScn+=8; + pBGw++; + + // Character latch(For MMC2/MMC4) + if( bChrLatch ) { + nes->mapper->PPU_ChrLatch( tileadr ); + } + + if( ++ntbl_x == 32 ) { + ntbl_x = 0; + ntbladr ^= 0x41F; + attradr = 0x03C0+((ntbladr&0x0380)>>4); + pNTBL = PPU_MEM_BANK[ntbladr>>10]; + } else { + ntbladr++; + } + } + } else { + // With Extension Latch(For MMC5) + LPBYTE pScn = lpScanline+(8-loopy_shift); + LPBYTE pBGw = BGwrite; + + INT ntbladr = 0x2000+(loopy_v&0x0FFF); + INT ntbl_x = ntbladr & 0x1F; + + INT cache_tile = 0xFFFF0000; + BYTE cache_attr = 0xFF; + + BYTE chr_h, chr_l, attr, exattr; + + sppadr_offset = nes->mapper->PPU_ExtLatchSP(); //for YuXing and PYRAMID + + for( INT i = 0; i < 33; i++ ) { + nes->mapper->PPU_ExtLatchX( i ); + nes->mapper->PPU_ExtLatch( ntbladr, chr_l, chr_h, exattr ); + attr = exattr&0x0C; + + if( cache_tile != (((INT)chr_h<<8)+(INT)chr_l) || cache_attr != attr ) { + cache_tile = (((INT)chr_h<<8)+(INT)chr_l); + cache_attr = attr; + *pBGw = chr_h|chr_l; + + LPBYTE pBGPAL = &BGPAL[attr]; + { + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + pScn[0] = pBGPAL[(c1>>6)]; + pScn[4] = pBGPAL[(c1>>2)&3]; + pScn[1] = pBGPAL[(c2>>6)]; + pScn[5] = pBGPAL[(c2>>2)&3]; + pScn[2] = pBGPAL[(c1>>4)&3]; + pScn[6] = pBGPAL[c1&3]; + pScn[3] = pBGPAL[(c2>>4)&3]; + pScn[7] = pBGPAL[c2&3]; + } + } else { + *(DWORD*)(pScn+0) = *(DWORD*)(pScn-8); + *(DWORD*)(pScn+4) = *(DWORD*)(pScn-4); + *(pBGw+0) = *(pBGw-1); + } + pScn+=8; + pBGw++; + + if( ++ntbl_x == 32 ) { + ntbl_x = 0; + ntbladr ^= 0x41F; + } else { + ntbladr++; + } + } + } + } else { + if( !bExtLatch ) { + // Without Extension Latch + if( !bExtNameTable ) { + LPBYTE pScn = lpScanline+(8-loopy_shift); + LPBYTE pBGw = BGwrite; + + INT ntbladr = 0x2000+(loopy_v&0x0FFF); + INT attradr = 0x03C0+((loopy_v&0x0380)>>4); + INT ntbl_x = ntbladr&0x001F; + INT attrsft = (ntbladr&0x0040)>>4; + LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10]; + + INT tileadr; + INT cache_tile = 0xFFFF0000; + BYTE cache_attr = 0xFF; + BYTE cache_mono = 0x00; + + BYTE chr_h, chr_l, attr; + + for( INT i = 0; i < 33; i++ ) { + tileadr = ((PPUREG[0]&PPU_BGTBL_BIT)<<8)+pNTBL[ntbladr&0x03FF]*0x10+loopy_y; + + if( i != 0 ) { + nes->EmulationCPU( FETCH_CYCLES*4 ); + } + + attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2; + + if( cache_tile != tileadr || cache_attr != attr ) { + cache_tile = tileadr; + cache_attr = attr; + + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + *pBGw = chr_l|chr_h; + + LPBYTE pBGPAL = &BGPAL[attr]; + { + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + pScn[0] = pBGPAL[(c1>>6)]; + pScn[4] = pBGPAL[(c1>>2)&3]; + pScn[1] = pBGPAL[(c2>>6)]; + pScn[5] = pBGPAL[(c2>>2)&3]; + pScn[2] = pBGPAL[(c1>>4)&3]; + pScn[6] = pBGPAL[c1&3]; + pScn[3] = pBGPAL[(c2>>4)&3]; + pScn[7] = pBGPAL[c2&3]; + } + } else { + *(DWORD*)(pScn+0) = *(DWORD*)(pScn-8); + *(DWORD*)(pScn+4) = *(DWORD*)(pScn-4); + *(pBGw+0) = *(pBGw-1); + } + pScn+=8; + pBGw++; + + // Character latch(For MMC2/MMC4) + if( bChrLatch ) { + nes->mapper->PPU_ChrLatch( tileadr ); + } + + if( ++ntbl_x == 32 ) { + ntbl_x = 0; + ntbladr ^= 0x41F; + attradr = 0x03C0+((ntbladr&0x0380)>>4); + pNTBL = PPU_MEM_BANK[ntbladr>>10]; + } else { + ntbladr++; + } + } + } else { + LPBYTE pScn = lpScanline+(8-loopy_shift); + LPBYTE pBGw = BGwrite; + + INT ntbladr; + INT tileadr; + INT cache_tile = 0xFFFF0000; + BYTE cache_attr = 0xFF; + BYTE cache_mono = 0x00; + + BYTE chr_h, chr_l, attr; + + WORD loopy_v_tmp = loopy_v; + + for( INT i = 0; i < 33; i++ ) { + if( i != 0 ) { + nes->EmulationCPU( FETCH_CYCLES*4 ); + } + + ntbladr = 0x2000+(loopy_v&0x0FFF); + tileadr = ((PPUREG[0]&PPU_BGTBL_BIT)<<8)+PPU_MEM_BANK[ntbladr>>10][ntbladr&0x03FF]*0x10+((loopy_v&0x7000)>>12); + attr = ((PPU_MEM_BANK[ntbladr>>10][0x03C0+((ntbladr&0x0380)>>4)+((ntbladr&0x001C)>>2)]>>(((ntbladr&0x40)>>4)+(ntbladr&0x02)))&3)<<2; + + if( cache_tile != tileadr || cache_attr != attr ) { + cache_tile = tileadr; + cache_attr = attr; + + chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ]; + chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8]; + *pBGw = chr_l|chr_h; + + LPBYTE pBGPAL = &BGPAL[attr]; + { + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + pScn[0] = pBGPAL[(c1>>6)]; + pScn[4] = pBGPAL[(c1>>2)&3]; + pScn[1] = pBGPAL[(c2>>6)]; + pScn[5] = pBGPAL[(c2>>2)&3]; + pScn[2] = pBGPAL[(c1>>4)&3]; + pScn[6] = pBGPAL[c1&3]; + pScn[3] = pBGPAL[(c2>>4)&3]; + pScn[7] = pBGPAL[c2&3]; + } + } else { + *(DWORD*)(pScn+0) = *(DWORD*)(pScn-8); + *(DWORD*)(pScn+4) = *(DWORD*)(pScn-4); + *(pBGw+0) = *(pBGw-1); + } + pScn+=8; + pBGw++; + + // Character latch(For MMC2/MMC4) + if( bChrLatch ) { + nes->mapper->PPU_ChrLatch( tileadr ); + } + + if( (loopy_v & 0x1F) == 0x1F ) { + loopy_v ^= 0x041F; + } else { + loopy_v++; + } + } + loopy_v = loopy_v_tmp; + } + } else { + // With Extension Latch(For MMC5) + LPBYTE pScn = lpScanline+(8-loopy_shift); + LPBYTE pBGw = BGwrite; + + INT ntbladr = 0x2000+(loopy_v&0x0FFF); + INT ntbl_x = ntbladr & 0x1F; + + INT cache_tile = 0xFFFF0000; + BYTE cache_attr = 0xFF; + + BYTE chr_h, chr_l, attr, exattr; + + sppadr_offset = nes->mapper->PPU_ExtLatchSP(); //for YuXing and PYRAMID + + for( INT i = 0; i < 33; i++ ) { + if( i != 0 ) { + nes->EmulationCPU( FETCH_CYCLES*4 ); + } + nes->mapper->PPU_ExtLatchX( i ); + nes->mapper->PPU_ExtLatch( ntbladr, chr_l, chr_h, exattr ); + attr = exattr&0x0C; + + if( cache_tile != (((INT)chr_h<<8)+(INT)chr_l) || cache_attr != attr ) { + cache_tile = (((INT)chr_h<<8)+(INT)chr_l); + cache_attr = attr; + *pBGw = chr_l|chr_h; + + LPBYTE pBGPAL = &BGPAL[attr]; + { + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + pScn[0] = pBGPAL[(c1>>6)]; + pScn[4] = pBGPAL[(c1>>2)&3]; + pScn[1] = pBGPAL[(c2>>6)]; + pScn[5] = pBGPAL[(c2>>2)&3]; + pScn[2] = pBGPAL[(c1>>4)&3]; + pScn[6] = pBGPAL[c1&3]; + pScn[3] = pBGPAL[(c2>>4)&3]; + pScn[7] = pBGPAL[c2&3]; + } + } else { + *(DWORD*)(pScn+0) = *(DWORD*)(pScn-8); + *(DWORD*)(pScn+4) = *(DWORD*)(pScn-4); + *(pBGw+0) = *(pBGw-1); + } + pScn+=8; + pBGw++; + + if( ++ntbl_x == 32 ) { + ntbl_x = 0; + ntbladr ^= 0x41F; + } else { + ntbladr++; + } + } + } + } + if( !(PPUREG[1]&PPU_BGCLIP_BIT) && bLeftClip ) { + LPBYTE pScn = lpScanline+8; + for( INT i = 0; i < 8; i++ ) { + pScn[i] = BGPAL[0]; + } + } + } + + // Render sprites + PPUREG[2] &= ~PPU_SPMAX_FLAG; + + // \ԊOł΃LZ + if( scanline > 239 ) + return; + + if( !(PPUREG[1]&PPU_SPDISP_BIT) ) { + return; + } + + BYTE SPwrite[33+1]; + INT spmax; + INT spraddr, sp_y, sp_h; + BYTE chr_h, chr_l; + LPSPRITE sp; + + LPBYTE pBGw = BGwrite; + LPBYTE pSPw = SPwrite; + LPBYTE pBit2Rev = Bit2Rev; + + ZEROMEMORY( SPwrite, sizeof(SPwrite) ); + + spmax = 0; + sp = (LPSPRITE)SPRAM; + sp_h = (PPUREG[0]&PPU_SP16_BIT)?15:7; + + // Left clip + if( !(PPUREG[1]&PPU_SPCLIP_BIT) && bLeftClip ) { + SPwrite[0] = 0xFF; + } + + for( INT i = 0; i < 64; i++, sp++ ) { + sp_y = scanline - (sp->y+1); + // XLCSPRITE݂邩`FbN + if( sp_y != (sp_y & sp_h) ) + continue; + + if( !(PPUREG[0]&PPU_SP16_BIT) ) { + // 8x8 Sprite + spraddr = (((INT)PPUREG[0]&PPU_SPTBL_BIT)<<9)+((INT)sp->tile<<4); + if( !(sp->attr&SP_VMIRROR_BIT) ) + spraddr += sp_y; + else + spraddr += 7-sp_y; + } else { + // 8x16 Sprite + spraddr = (((INT)sp->tile&1)<<12)+(((INT)sp->tile&0xFE)<<4); + if( !(sp->attr&SP_VMIRROR_BIT) ) + spraddr += ((sp_y&8)<<1)+(sp_y&7); + else + spraddr += ((~sp_y&8)<<1)+(7-(sp_y&7)); + } + // Character pattern + chr_l = PPU_MEM_BANK[spraddr>>10][ spraddr&0x3FF ]; + chr_h = PPU_MEM_BANK[spraddr>>10][(spraddr&0x3FF)+8]; + + // Character latch(For MMC2/MMC4) + if( bChrLatch ) { + nes->mapper->PPU_ChrLatch( spraddr ); + } + + // pattern mask + if( sp->attr&SP_HMIRROR_BIT ) { + chr_l = pBit2Rev[chr_l]; + chr_h = pBit2Rev[chr_h]; + } + BYTE SPpat = chr_l|chr_h; + + // Sprite hitcheck + if( i == 0 && !(PPUREG[2]&PPU_SPHIT_FLAG) ) { + INT BGpos = ((sp->x&0xF8)+((loopy_shift+(sp->x&7))&8))>>3; + INT BGsft = 8-((loopy_shift+sp->x)&7); + BYTE BGmsk = (((WORD)pBGw[BGpos+0]<<8)|(WORD)pBGw[BGpos+1])>>BGsft; + + if( SPpat & BGmsk ) { + PPUREG[2] |= PPU_SPHIT_FLAG; + } + } + + // Sprite mask + INT SPpos = sp->x/8; + INT SPsft = 8-(sp->x&7); + BYTE SPmsk = (((WORD)pSPw[SPpos+0]<<8)|(WORD)pSPw[SPpos+1])>>SPsft; + WORD SPwrt = (WORD)SPpat<> 8; + pSPw[SPpos+1] |= SPwrt & 0xFF; + SPpat &= ~SPmsk; + + if( sp->attr&SP_PRIORITY_BIT ) { + // BG > SP priority + INT BGpos = ((sp->x&0xF8)+((loopy_shift+(sp->x&7))&8))>>3; + INT BGsft = 8-((loopy_shift+sp->x)&7); + BYTE BGmsk = (((WORD)pBGw[BGpos+0]<<8)|(WORD)pBGw[BGpos+1])>>BGsft; + + SPpat &= ~BGmsk; + } + + // Attribute + LPBYTE pSPPAL = &SPPAL[(sp->attr&SP_COLOR_BIT)<<2] + sppadr_offset; //"sppadr_offset" for YuXing and PYRAMID + // Ptr + LPBYTE pScn = lpScanline+sp->x+8; + + if( !bExtMono ) { + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + if( SPpat&0x80 ) pScn[0] = pSPPAL[(c1>>6)]; + if( SPpat&0x08 ) pScn[4] = pSPPAL[(c1>>2)&3]; + if( SPpat&0x40 ) pScn[1] = pSPPAL[(c2>>6)]; + if( SPpat&0x04 ) pScn[5] = pSPPAL[(c2>>2)&3]; + if( SPpat&0x20 ) pScn[2] = pSPPAL[(c1>>4)&3]; + if( SPpat&0x02 ) pScn[6] = pSPPAL[c1&3]; + if( SPpat&0x10 ) pScn[3] = pSPPAL[(c2>>4)&3]; + if( SPpat&0x01 ) pScn[7] = pSPPAL[c2&3]; + } else { + // Monocrome effect (for Final Fantasy) + BYTE mono = BGmono[((sp->x&0xF8)+((loopy_shift+(sp->x&7))&8))>>3]; + + register INT c1 = ((chr_l>>1)&0x55)|(chr_h&0xAA); + register INT c2 = (chr_l&0x55)|((chr_h<<1)&0xAA); + if( SPpat&0x80 ) pScn[0] = pSPPAL[c1>>6] |mono; + if( SPpat&0x08 ) pScn[4] = pSPPAL[(c1>>2)&3] |mono; + if( SPpat&0x40 ) pScn[1] = pSPPAL[c2>>6] |mono; + if( SPpat&0x04 ) pScn[5] = pSPPAL[(c2>>2)&3] |mono; + if( SPpat&0x20 ) pScn[2] = pSPPAL[(c1>>4)&3] |mono; + if( SPpat&0x02 ) pScn[6] = pSPPAL[c1&3] |mono; + if( SPpat&0x10 ) pScn[3] = pSPPAL[(c2>>4)&3] |mono; + if( SPpat&0x01 ) pScn[7] = pSPPAL[c2&3] |mono; + } + + if( ++spmax > 8-1 ) { + if( !bMax ) + break; + } + } + if( spmax > 8-1 ) { + PPUREG[2] |= PPU_SPMAX_FLAG; + } +} + +// XvCgOqbg邩mȂCH +BOOL PPU::IsSprite0( INT scanline ) +{ + // XvCgorBG\̓LZ(qbgȂ) + if( (PPUREG[1]&(PPU_SPDISP_BIT|PPU_BGDISP_BIT)) != (PPU_SPDISP_BIT|PPU_BGDISP_BIT) ) + return FALSE; + + // ɃqbgĂLZ + if( PPUREG[2]&PPU_SPHIT_FLAG ) + return FALSE; + + if( !(PPUREG[0]&PPU_SP16_BIT) ) { + // 8x8 + if( (scanline < (INT)SPRAM[0]+1) || (scanline > ((INT)SPRAM[0]+7+1)) ) + return FALSE; + } else { + // 8x16 + if( (scanline < (INT)SPRAM[0]+1) || (scanline > ((INT)SPRAM[0]+15+1)) ) + return FALSE; + } + + return TRUE; +} + +void PPU::DummyScanline( INT scanline ) +{ +INT i; +INT spmax; +INT sp_h; +LPSPRITE sp; + + PPUREG[2] &= ~PPU_SPMAX_FLAG; + + // XvCg\̓LZ + if( !(PPUREG[1]&PPU_SPDISP_BIT) ) + return; + + // \ԊOł΃LZ + if( scanline < 0 || scanline > 239 ) + return; + + sp = (LPSPRITE)SPRAM; + sp_h = (PPUREG[0]&PPU_SP16_BIT)?15:7; + + spmax = 0; + // Sprite Max check + for( i = 0; i < 64; i++, sp++ ) { + // XLCSPRITE݂邩`FbN + if( (scanline < (INT)sp->y+1) || (scanline > ((INT)sp->y+sp_h+1)) ) { + continue; + } + + if( ++spmax > 8-1 ) { + PPUREG[2] |= PPU_SPMAX_FLAG; + break; + } + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/PPU.h b/References/VirtuaNESex_src_191105/NES/PPU.h new file mode 100644 index 00000000..dad1598f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PPU.h @@ -0,0 +1,153 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES PPU core // +// Norix // +// written 2001/02/22 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __PPU_INCLUDED__ +#define __PPU_INCLUDED__ + +#include "typedef.h" +#include "macro.h" + +// class prototype +class NES; + +// PPU Control Register #1 PPU #0 +#define PPU_VBLANK_BIT 0x80 +#define PPU_SPHIT_BIT 0x40 // ႤH +#define PPU_SP16_BIT 0x20 +#define PPU_BGTBL_BIT 0x10 +#define PPU_SPTBL_BIT 0x08 +#define PPU_INC32_BIT 0x04 +#define PPU_NAMETBL_BIT 0x03 + +// PPU Control Register #2 PPU #1 +#define PPU_BGCOLOR_BIT 0xE0 +#define PPU_SPDISP_BIT 0x10 +#define PPU_BGDISP_BIT 0x08 +#define PPU_SPCLIP_BIT 0x04 +#define PPU_BGCLIP_BIT 0x02 +#define PPU_COLORMODE_BIT 0x01 + +// PPU Status Register PPU #2 +#define PPU_VBLANK_FLAG 0x80 +#define PPU_SPHIT_FLAG 0x40 +#define PPU_SPMAX_FLAG 0x20 +#define PPU_WENABLE_FLAG 0x10 + +// SPRITE Attribute +#define SP_VMIRROR_BIT 0x80 +#define SP_HMIRROR_BIT 0x40 +#define SP_PRIORITY_BIT 0x20 +#define SP_COLOR_BIT 0x03 + +class PPU +{ +public: + PPU( NES* parent ); + virtual ~PPU(); + + enum { SCREEN_WIDTH = 256+16, SCREEN_HEIGHT = 240 }; + + void Reset(); + + BYTE Read ( WORD addr ); + void Write( WORD addr, BYTE data ); + + void DMA( BYTE data ); + + void VBlankStart(); + void VBlankEnd(); + + void FrameStart(); + void FrameEnd(); + + void SetRenderScanline( INT scanline ); + + void ScanlineStart(); + void ScanlineNext(); + + WORD GetPPUADDR() { return loopy_v; } + WORD GetTILEY() { return loopy_y; } + + // Scanline base render + void Scanline( INT scanline, BOOL bMax, BOOL bLeftClip ); + void DummyScanline( INT scanline ); + + // For mapper + void SetExtLatchMode( BOOL bMode ) { bExtLatch = bMode; } + void SetChrLatchMode( BOOL bMode ) { bChrLatch = bMode; } + void SetExtNameTableMode( BOOL bMode ) { bExtNameTable = bMode; } + void SetExtMonoMode( BOOL bMode ) { bExtMono = bMode; } + void SetVromWrite(BOOL bMode) { bVromWe = bMode;} + BOOL IsVromWrite() { return bVromWe; } + BOOL GetExtMonoMode() { return bExtMono; } + + BOOL IsDispON() { return PPUREG[1]&(PPU_BGDISP_BIT|PPU_SPDISP_BIT); } + BOOL IsBGON() { return PPUREG[1]&PPU_BGDISP_BIT; } + BOOL IsSPON() { return PPUREG[1]&PPU_SPDISP_BIT; } + + BYTE GetBGCOLOR() { return (PPUREG[1]&PPU_BGCOLOR_BIT)>>5; } + + BOOL IsBGCLIP() { return PPUREG[1]&PPU_BGCLIP_BIT; } + BOOL IsSPCLIP() { return PPUREG[1]&PPU_SPCLIP_BIT; } + + BOOL IsMONOCROME() { return PPUREG[1]&PPU_COLORMODE_BIT; } + + BOOL IsVBLANK() { return PPUREG[2]&PPU_VBLANK_FLAG; } + BOOL IsSPHIT() { return PPUREG[2]&PPU_SPHIT_FLAG; } + BOOL IsSPMAX() { return PPUREG[2]&PPU_SPMAX_FLAG; } + BOOL IsPPUWE() { return PPUREG[2]&PPU_WENABLE_FLAG; } + + BOOL IsSprite0( INT scanline ); + + void SetScreenPtr( LPBYTE lpScn, LPBYTE lpMode ) { lpScreen = lpScn; lpColormode = lpMode; } + LPBYTE GetScreenPtr() { return lpScreen; } + + INT GetScanlineNo() { return ScanlineNo; } + + // For VS-Unisystem + void SetVSMode( BOOL bMode ) { bVSMode = bMode; } + void SetVSSecurity( BYTE data ) { VSSecurityData = data; } + void SetVSColorMap( INT nColorMap ) { nVSColorMap = nColorMap; } + +protected: + NES* nes; + + BOOL bExtLatch; // For MMC5 + BOOL bChrLatch; // For MMC2/MMC4 + BOOL bExtNameTable; // For Super Monkey no Dai Bouken + BOOL bExtMono; // For Final Fantasy + BOOL bVromWe; // For Mapper74 and others + + WORD loopy_y; + WORD loopy_shift; + + LPBYTE lpScreen; + LPBYTE lpScanline; + INT ScanlineNo; + LPBYTE lpColormode; + + typedef struct tagSPRITE { + BYTE y; + BYTE tile; + BYTE attr; + BYTE x; + } SPRITE, *LPSPRITE; + + // Reversed bits + BYTE Bit2Rev[256]; + + // For VS-Unisystem + BOOL bVSMode; + BYTE VSSecurityData; + INT nVSColorMap; + static BYTE VSColorMap[5][64]; +private: +}; + + +#endif // !__PPU_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD.h new file mode 100644 index 00000000..03dcbde6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES EXPAD // +// Norix // +// written 2001/04/08 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +class EXPAD +{ +public: + EXPAD( NES* parent ) : nes( parent ) {} + virtual ~EXPAD() {}; + +// o֐ + virtual void Reset() {} + virtual void Strobe() {} + virtual BYTE Read4016() { return 0x00; } + virtual BYTE Read4017() { return 0x00; } + virtual void Write4016( BYTE data ) {} + virtual void Write4017( BYTE data ) {} + + // For synchronized + virtual void Sync() {} + + virtual void SetSyncData( INT type, LONG data ) {} + virtual LONG GetSyncData( INT type ) { return 0x00; } + +protected: + NES* nes; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ChinaEduMouse.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ChinaEduMouse.cpp new file mode 100644 index 00000000..6cc44ee9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ChinaEduMouse.cpp @@ -0,0 +1,271 @@ +////////////////////////////////////////////////////////////////////////// +// China Educational Mouse // +////////////////////////////////////////////////////////////////////////// +void EXPAD_ChinaEduMouse::Reset() +{ + olddata = 0; + outbits = 0; + databits = 0; + + zapper_x = 0; + zapper_y = 0; + zapper_button = 0; + + readkey = FALSE; + bOut = FALSE; + ScanNo = 0; +} + +BYTE EXPAD_ChinaEduMouse::Read4016() +{ + BYTE data = 0; + + return data; +} + +BYTE EXPAD_ChinaEduMouse::Read4017() +{ + BYTE data; + if(readkey){ + data = 0xFF; + switch( ScanNo ) { + case 1: + if( bOut ) { + if( DirectInput.m_Sw[DIK_4 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_G ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_F ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_C ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F2 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_E ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_5 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_V ] ) data &= ~0x10; + } + break; + case 2: + if( bOut ) { + if( DirectInput.m_Sw[DIK_2 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_D ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_S ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_END ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F1 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_W ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_3 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_X ] ) data &= ~0x10; + } + break; + case 3: + if( bOut ) { + if( DirectInput.m_Sw[DIK_INSERT ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_BACK ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_NEXT ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_RIGHT ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F8 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_PRIOR ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_DELETE] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_HOME ] ) data &= ~0x10; + } + break; + case 4: + if( bOut ) { + if( DirectInput.m_Sw[DIK_9 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_I ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_L ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_COMMA ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F5 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_O ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_0 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_PERIOD ] ) data &= ~0x10; + } + break; + case 5: + if( bOut ) { + if( DirectInput.m_Sw[DIK_RBRACKET ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_RETURN ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_UP ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LEFT ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F7 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_LBRACKET ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_BACKSLASH ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_DOWN ] ) data &= ~0x10; + } + break; + case 6: + if( bOut ) { + if( DirectInput.m_Sw[DIK_Q ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_CAPITAL ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_Z ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_TAB ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_ESCAPE ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_A ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_1 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LCONTROL ] ) data &= ~0x10; + } + break; + case 7: + if( bOut ) { + if( DirectInput.m_Sw[DIK_7 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_Y ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_K ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_M ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F4 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_U ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_8 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_J ] ) data &= ~0x10; + } + break; + case 8: + if( bOut ) { + if( DirectInput.m_Sw[DIK_MINUS ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_SEMICOLON ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_APOSTROPHE ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_SLASH ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F6 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_P ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_EQUALS ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LSHIFT ] || + DirectInput.m_Sw[DIK_RSHIFT ] ) data &= ~0x10; + } + break; + case 9: + if( bOut ) { + if( DirectInput.m_Sw[DIK_T ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_H ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_N ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_SPACE ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F3 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_R ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_6 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_B ] ) data &= ~0x10; + } + break; + } + return data; + }else{ + return outbits; + } +} + +void EXPAD_ChinaEduMouse::Write4016( BYTE data ) +{ + +// DEBUGOUT( " X=%d Y=%d\n", zapper_x, zapper_y ); + +/* if( !(data & 0x01) ) { + outbits = 0; + databits = 0; + + if( zapper_button ) + databits |= 0x0001; + + LONG x, y; + + if( zapper_y >= 48 ) { + databits |= 0x0002; + } else if( zapper_button ) { + databits |= 0x0003; + } + + if( zapper_x < 0 ) { + x = 0; + } else { + x = ((240*zapper_x)/256)+8; + } + if( zapper_y < 0 ) { + y = 0; + } else { + y = ((256*zapper_y)/240)-12; + if( y < 0 ) + y = 0; + } + + databits = databits | (x << 10) | (y << 2); + } else { + // L->H + if( ((~olddata)&data) & 0x02 ) { + databits <<= 1; + } + if( !(data & 0x02) ) { + outbits = 0x04; + } else + if( databits & 0x40000 ) { + outbits = 0x00; + } else { + outbits = 0x08; + } + olddata = data; + } +*/ + switch( data ) { + case 0: + readkey = FALSE; + outbits = 0x41; + break; + case 1: + readkey = FALSE; + outbits = 0x41; + break; + case 4: + readkey = TRUE; + if( ++ScanNo > 9 ) + ScanNo = 0; + bOut = !bOut; + break; + case 5: + readkey = FALSE; + bOut = FALSE; + ScanNo = 0; + + //if( zapper_button ) + outbits = 0x41; + + break; + case 6: + readkey = TRUE; + bOut = !bOut; + break; + } +} + +void EXPAD_ChinaEduMouse::Sync() +{ + nes->GetZapperPos( zapper_x, zapper_y ); + + zapper_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + zapper_button = 0xFF; +} + +void EXPAD_ChinaEduMouse::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + zapper_x = data; + } else if( type == 1 ) { + zapper_y = data; + } else if( type == 2 ) { + zapper_button = data?0xFF:0x00; + } +} + +LONG EXPAD_ChinaEduMouse::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = zapper_x; + } else if( type == 1 ) { + data = zapper_y; + } else if( type == 2 ) { + data = zapper_button?0xFF:0x00; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ChinaEduMouse.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ChinaEduMouse.h new file mode 100644 index 00000000..44c71da3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ChinaEduMouse.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// China Educational Mouse // +////////////////////////////////////////////////////////////////////////// +class EXPAD_ChinaEduMouse : public EXPAD +{ +public: + EXPAD_ChinaEduMouse( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4016(); + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE olddata; + BYTE outbits; + DWORD databits; + + LONG zapper_x, zapper_y; + BYTE zapper_button; + + BOOL readkey; + BOOL bOut; + BYTE ScanNo; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_CrazyClimber.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_CrazyClimber.cpp new file mode 100644 index 00000000..c26b05c2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_CrazyClimber.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// Crazy climber // +////////////////////////////////////////////////////////////////////////// +void EXPAD_CrazyClimber::Strobe() +{ + nes->pad->pad1bit &= ~0xF0; + nes->pad->pad1bit |= bits & 0xF0; + nes->pad->pad2bit &= ~0xF0; + nes->pad->pad2bit |= (bits & 0x0F)<<4; +} + +void EXPAD_CrazyClimber::Sync() +{ + bits = 0; + + // Left + if( Config.ExButtonCheck( 0, 0 ) ) bits |= 1<<6; + if( Config.ExButtonCheck( 0, 1 ) ) bits |= 1<<7; + if( Config.ExButtonCheck( 0, 2 ) ) bits |= 1<<5; + if( Config.ExButtonCheck( 0, 3 ) ) bits |= 1<<4; + + // Right + if( Config.ExButtonCheck( 0, 4 ) ) bits |= 1<<2; + if( Config.ExButtonCheck( 0, 5 ) ) bits |= 1<<3; + if( Config.ExButtonCheck( 0, 6 ) ) bits |= 1<<1; + if( Config.ExButtonCheck( 0, 7 ) ) bits |= 1<<0; + + // ͂֎~ + if( (bits&((1<<0)|(1<<1))) == ((1<<0)|(1<<1)) ) + bits &= ~((1<<0)|(1<<1)); + if( (bits&((1<<2)|(1<<3))) == ((1<<2)|(1<<3)) ) + bits &= ~((1<<2)|(1<<3)); + if( (bits&((1<<4)|(1<<5))) == ((1<<4)|(1<<5)) ) + bits &= ~((1<<4)|(1<<5)); + if( (bits&((1<<6)|(1<<7))) == ((1<<6)|(1<<7)) ) + bits &= ~((1<<6)|(1<<7)); +} + +void EXPAD_CrazyClimber::SetSyncData( INT type, LONG data ) +{ + bits = (BYTE)data; +} + +LONG EXPAD_CrazyClimber::GetSyncData( INT type ) +{ + return bits; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_CrazyClimber.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_CrazyClimber.h new file mode 100644 index 00000000..82f4ccbc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_CrazyClimber.h @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// Crazy climber // +////////////////////////////////////////////////////////////////////////// +class EXPAD_CrazyClimber : public EXPAD +{ +public: + EXPAD_CrazyClimber( NES* parent ) : EXPAD( parent ) {} + + void Strobe(); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE bits; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ExcitingBoxing.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ExcitingBoxing.cpp new file mode 100644 index 00000000..7335c14d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ExcitingBoxing.cpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// Exciting Boxing // +////////////////////////////////////////////////////////////////////////// +void EXPAD_ExcitingBoxing::Reset() +{ + outbits = 0; + padbits = 0; +} + +BYTE EXPAD_ExcitingBoxing::Read4017() +{ + return outbits; +} + +void EXPAD_ExcitingBoxing::Write4016( BYTE data ) +{ + outbits = 0; + if( data & 0x02 ) { + outbits = (~padbits<<1)&0x1E; + } else { + outbits = (~padbits>>3)&0x1E; + } +} + +void EXPAD_ExcitingBoxing::Sync() +{ + padbits = 0; + + // Straight + if( Config.ExButtonCheck( 2, 0 ) ) padbits |= 1<<3; + // Right Jabb + if( Config.ExButtonCheck( 2, 1 ) ) padbits |= 1<<2; + // Body + if( Config.ExButtonCheck( 2, 2 ) ) padbits |= 1<<1; + // Left Jabb + if( Config.ExButtonCheck( 2, 3 ) ) padbits |= 1<<0; + // Right hook + if( Config.ExButtonCheck( 2, 4 ) ) padbits |= 1<<7; + // Left hook + if( Config.ExButtonCheck( 2, 5 ) ) padbits |= 1<<4; + // Right move + if( Config.ExButtonCheck( 2, 6 ) ) padbits |= 1<<5; + // Left move + if( Config.ExButtonCheck( 2, 7 ) ) padbits |= 1<<6; +} + +void EXPAD_ExcitingBoxing::SetSyncData( INT type, LONG data ) +{ + padbits = (BYTE)data; +} + +LONG EXPAD_ExcitingBoxing::GetSyncData( INT type ) +{ + return (LONG)padbits; +} diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ExcitingBoxing.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ExcitingBoxing.h new file mode 100644 index 00000000..a9c5b3ad --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ExcitingBoxing.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Exciting Boxing // +////////////////////////////////////////////////////////////////////////// +class EXPAD_ExcitingBoxing : public EXPAD +{ +public: + EXPAD_ExcitingBoxing( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE outbits; + BYTE padbits; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_FamlyTrainer.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_FamlyTrainer.cpp new file mode 100644 index 00000000..d478db89 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_FamlyTrainer.cpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// Famly Trainer // +////////////////////////////////////////////////////////////////////////// +void EXPAD_FamlyTrainer::Reset() +{ + outbits = 0; + padbits = 0; +} + +BYTE EXPAD_FamlyTrainer::Read4017() +{ + return outbits; +} + +void EXPAD_FamlyTrainer::Write4016( BYTE data ) +{ + outbits = 0; + if( !(data & 0x04) ) { + outbits = (BYTE)((~padbits<<1)&0x1E); + } + if( !(data & 0x02) ) { + outbits = (BYTE)((~padbits>>3)&0x1E); + } + if( !(data & 0x01) ) { + outbits = (BYTE)((~padbits>>7)&0x1E); + } +} + +void EXPAD_FamlyTrainer::Sync() +{ + padbits = 0; + + if( nes->pad->GetExController() == PAD::EXCONTROLLER_FAMILYTRAINER_A ) { + if( Config.ExButtonCheck( 1, 3 ) ) padbits |= 1<<3; + if( Config.ExButtonCheck( 1, 2 ) ) padbits |= 1<<2; + if( Config.ExButtonCheck( 1, 1 ) ) padbits |= 1<<1; + if( Config.ExButtonCheck( 1, 0 ) ) padbits |= 1<<0; + if( Config.ExButtonCheck( 1, 7 ) ) padbits |= 1<<7; + if( Config.ExButtonCheck( 1, 6 ) ) padbits |= 1<<6; + if( Config.ExButtonCheck( 1, 5 ) ) padbits |= 1<<5; + if( Config.ExButtonCheck( 1, 4 ) ) padbits |= 1<<4; + if( Config.ExButtonCheck( 1, 11 ) ) padbits |= 1<<11; + if( Config.ExButtonCheck( 1, 10 ) ) padbits |= 1<<10; + if( Config.ExButtonCheck( 1, 9 ) ) padbits |= 1<<9; + if( Config.ExButtonCheck( 1, 8 ) ) padbits |= 1<<8; + } + if( nes->pad->GetExController() == PAD::EXCONTROLLER_FAMILYTRAINER_B ) { + if( Config.ExButtonCheck( 1, 0 ) ) padbits |= 1<<3; + if( Config.ExButtonCheck( 1, 1 ) ) padbits |= 1<<2; + if( Config.ExButtonCheck( 1, 2 ) ) padbits |= 1<<1; + if( Config.ExButtonCheck( 1, 3 ) ) padbits |= 1<<0; + if( Config.ExButtonCheck( 1, 4 ) ) padbits |= 1<<7; + if( Config.ExButtonCheck( 1, 5 ) ) padbits |= 1<<6; + if( Config.ExButtonCheck( 1, 6 ) ) padbits |= 1<<5; + if( Config.ExButtonCheck( 1, 7 ) ) padbits |= 1<<4; + if( Config.ExButtonCheck( 1, 8 ) ) padbits |= 1<<11; + if( Config.ExButtonCheck( 1, 9 ) ) padbits |= 1<<10; + if( Config.ExButtonCheck( 1, 10 ) ) padbits |= 1<<9; + if( Config.ExButtonCheck( 1, 11 ) ) padbits |= 1<<8; + } +} + +void EXPAD_FamlyTrainer::SetSyncData( INT type, LONG data ) +{ + padbits = (DWORD)data; +} + +LONG EXPAD_FamlyTrainer::GetSyncData( INT type ) +{ + return (LONG)padbits; +} diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_FamlyTrainer.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_FamlyTrainer.h new file mode 100644 index 00000000..f24fc642 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_FamlyTrainer.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Famly Trainer // +////////////////////////////////////////////////////////////////////////// +class EXPAD_FamlyTrainer : public EXPAD +{ +public: + EXPAD_FamlyTrainer( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE outbits; + DWORD padbits; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_HyperShot.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_HyperShot.cpp new file mode 100644 index 00000000..eaea3468 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_HyperShot.cpp @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// Hyper Shot // +////////////////////////////////////////////////////////////////////////// +void EXPAD_HyperShot::Reset() +{ + shotbits = 0; +} + +void EXPAD_HyperShot::Strobe() +{ + shotbits = 0; + shotbits |= (nes->pad->pad1bit&0x03)<<1; + shotbits |= (nes->pad->pad2bit&0x03)<<3; +} + +BYTE EXPAD_HyperShot::Read4017() +{ + return shotbits; +} diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_HyperShot.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_HyperShot.h new file mode 100644 index 00000000..759e4148 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_HyperShot.h @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// Hyper Shot // +////////////////////////////////////////////////////////////////////////// +class EXPAD_HyperShot : public EXPAD +{ +public: + EXPAD_HyperShot( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + void Strobe(); + BYTE Read4017(); + +protected: + BYTE shotbits; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Keyboard.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Keyboard.cpp new file mode 100644 index 00000000..136be2b8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Keyboard.cpp @@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////////// +// Family Basic Keyboard // +////////////////////////////////////////////////////////////////////////// +void EXPAD_Keyboard::Reset() +{ + bGraph = FALSE; + bOut = FALSE; + ScanNo = 0; +} + +BYTE EXPAD_Keyboard::Read4016() +{ +BYTE data = 0; + + return data; +} + +BYTE EXPAD_Keyboard::Read4017() +{ +BYTE data = 0xFF; + + if( DirectInput.m_Sw[DIK_NEXT ] ) bGraph = TRUE; + if( DirectInput.m_Sw[DIK_PRIOR] ) bGraph = FALSE; + + switch( ScanNo ) { + case 1: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F8 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_RETURN ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_LBRACKET] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_RBRACKET] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F12 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_RSHIFT ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_BACKSLASH] + || DirectInput.m_Sw[DIK_YEN ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_END ] ) data &= ~0x10; + } + break; + case 2: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F7 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_AT ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_COLON ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_SEMICOLON] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_UNDERLINE ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_SLASH ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_MINUS ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_CIRCUMFLEX] ) data &= ~0x10; + } + break; + case 3: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F6] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_O ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_L ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_K ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_PERIOD] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_COMMA ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_P ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_0 ] ) data &= ~0x10; + } + break; + case 4: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F5] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_I ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_U ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_J ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_M] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_N] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_9] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_8] ) data &= ~0x10; + } + break; + case 5: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F4] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_Y ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_G ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_H ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_B] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_V] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_7] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_6] ) data &= ~0x10; + } + break; + case 6: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F3] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_T ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_R ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_D ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_C] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_5] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_4] ) data &= ~0x10; + } + break; + case 7: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F2] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_W ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_S ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_A ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_X] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_Z] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_E] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_3] ) data &= ~0x10; + } + break; + case 8: + if( bOut ) { + if( DirectInput.m_Sw[DIK_F1 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_ESCAPE ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_Q ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LCONTROL] + || DirectInput.m_Sw[DIK_RCONTROL] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_LSHIFT] ) data &= ~0x02; + if( bGraph ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_1 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_2 ] ) data &= ~0x10; + } + break; + case 9: + if( bOut ) { + if( DirectInput.m_Sw[DIK_HOME ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_UP ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_RIGHT] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LEFT ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_DOWN ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_SPACE ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_DELETE] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_INSERT] ) data &= ~0x10; + } + break; + } + + return data; +} + +void EXPAD_Keyboard::Write4016( BYTE data ) +{ + if( data == 0x05 ) { + bOut = FALSE; + ScanNo = 0; + } else if( data == 0x04 ) { + if( ++ScanNo > 9 ) + ScanNo = 0; + bOut = !bOut; + } else if( data == 0x06 ) { + bOut = !bOut; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Keyboard.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Keyboard.h new file mode 100644 index 00000000..0f4bd549 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Keyboard.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// Family Basic Keyboard // +////////////////////////////////////////////////////////////////////////// +class EXPAD_Keyboard : public EXPAD +{ +public: + EXPAD_Keyboard( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4016(); + BYTE Read4017(); + void Write4016( BYTE data ); + +protected: + BOOL bGraph; + BOOL bOut; + BYTE ScanNo; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Kingwon_Keyboard.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Kingwon_Keyboard.cpp new file mode 100644 index 00000000..145068d7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Kingwon_Keyboard.cpp @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////// +// Kingwon Keyboard // +// written by Temryu // +// last 2013/10/13 // +////////////////////////////////////////////////////////////////////////// + +void EXPAD_Kingwon_Keyboard::Reset() +{ + ScanNo =0; + count4017 =0; +} + +BYTE EXPAD_Kingwon_Keyboard::Read4017() +{ + BYTE data = 0xFF; + + switch( ScanNo ) { + case 0: + if(count4017==0) if( DirectInput.m_Sw[DIK_Z ] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_A ] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_Q ] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_1 ] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_LSHIFT ] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_RSHIFT ] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_CAPITAL] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_TAB ] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_GRAVE ] ) data &= ~0x02; + count4017++ ; + break; + case 1: + if(count4017==0) if( DirectInput.m_Sw[DIK_C] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_D] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_E] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_3] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_X] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_S] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_W] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_2] ) data &= ~0x02; + count4017++ ; + break; + case 2: + if(count4017==0) if( DirectInput.m_Sw[DIK_B] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_G] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_T] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_5] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_V] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_F] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_R] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_4] ) data &= ~0x02; + count4017++ ; + break; + case 3: + if(count4017==0) if( DirectInput.m_Sw[DIK_M] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_J] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_U] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_7] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_N] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_H] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_Y] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_6] ) data &= ~0x02; + count4017++ ; + break; + case 4: + if(count4017==0) if( DirectInput.m_Sw[DIK_PERIOD] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_L ] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_O ] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_9 ] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_COMMA ] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_K ] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_I ] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_8 ] ) data &= ~0x02; + count4017++ ; + break; + case 5: + if(count4017==0) if( DirectInput.m_Sw[DIK_BACKSLASH ] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_APOSTROPHE] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_LBRACKET ] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_MINUS ] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_SLASH ] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_SEMICOLON ] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_P ] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_0 ] ) data &= ~0x02; + count4017++ ; + break; + case 6: + if(count4017==0) if( DirectInput.m_Sw[DIK_END ] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_LEFT ] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_HOME ] ) data &= ~0x02; +// if(count4017==3) if( FALSE ) data &= ~0x02; //Caps Lock + if(count4017==4) if( DirectInput.m_Sw[DIK_BACK ] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_RETURN ] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_RBRACKET] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_EQUALS ] ) data &= ~0x02; + count4017++ ; + break; + case 7: + if(count4017==0) if( DirectInput.m_Sw[DIK_NEXT ] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_RIGHT ] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_PRIOR ] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_ESCAPE] ) data &= ~0x02; // + if(count4017==4) if( DirectInput.m_Sw[DIK_DOWN ] ) data &= ~0x02; +// if(count4017==5) if( FALSE ) data &= ~0x02; //Num 5 + if(count4017==6) if( DirectInput.m_Sw[DIK_UP ] ) data &= ~0x02; +// if(count4017==7) if( FALSE ) data &= ~0x02; //??? + count4017++ ; + break; + case 8: + if(count4017==0) if( DirectInput.m_Sw[DIK_DELETE ] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_ADD ] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_MULTIPLY ] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_NUMPADENTER] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_INSERT ] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_SPACE ] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_LMENU ] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_RMENU ] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_LCONTROL ] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_RCONTROL ] ) data &= ~0x02; + count4017++ ; + break; + case 9: + if(count4017==0) if( DirectInput.m_Sw[DIK_F8] ) data &= ~0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_F7] ) data &= ~0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_F6] ) data &= ~0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_F5] ) data &= ~0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_F4] ) data &= ~0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_F3] ) data &= ~0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_F2] ) data &= ~0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_F1] ) data &= ~0x02; + count4017++ ; + break; + case 10: + //??? + break; + case 11: + //??? + break; + case 12: + //??? + break; + } + + return data; +} + +void EXPAD_Kingwon_Keyboard::Write4016( BYTE data ) +{ + if( data == 0x04 ) { + count4017 = 0; + } else if( data == 0x05 ) { + if( ++ScanNo > 12 ) + ScanNo = 0; + } else if( data == 0x07 ) { + ScanNo = 0; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Kingwon_Keyboard.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Kingwon_Keyboard.h new file mode 100644 index 00000000..7912c622 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Kingwon_Keyboard.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// Kingwon Keyboard // +// written by Temryu // +// last 2013/09/12 // +////////////////////////////////////////////////////////////////////////// + +class EXPAD_Kingwon_Keyboard : public EXPAD +{ +public: + EXPAD_Kingwon_Keyboard( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + BYTE Read4017(); + void Write4016( BYTE data ); + +protected: + BYTE ScanNo; + BYTE count4017; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Mahjang.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Mahjang.cpp new file mode 100644 index 00000000..9e4cb13d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Mahjang.cpp @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// Ide Yousuke Jissen Mahjang // +////////////////////////////////////////////////////////////////////////// +void EXPAD_Mahjang::Reset() +{ + outbits = 0; + padbits = 0; +} + +BYTE EXPAD_Mahjang::Read4017() +{ +BYTE out = (outbits&1)<<1; + + outbits >>= 1; + return out; +} + +void EXPAD_Mahjang::Write4016( BYTE data ) +{ + outbits = 0; + + if( (data & 0x06) == 0x02 ) { + // H-N + outbits = (BYTE)padbits; + } else + if( (data & 0x06) == 0x04 ) { + // A-G + outbits = (BYTE)(padbits>>8); + } else + if( (data & 0x06) == 0x06 ) { + // Start,Select,Kan,Pon,Chii,Reach,Ron + outbits = (BYTE)(padbits>>16); + } +} + +void EXPAD_Mahjang::Sync() +{ + padbits = 0; + + // H-N + if( Config.ExButtonCheck( 3, 8 ) ) padbits |= 1<<7; + if( Config.ExButtonCheck( 3, 9 ) ) padbits |= 1<<6; + if( Config.ExButtonCheck( 3, 10 ) ) padbits |= 1<<5; + if( Config.ExButtonCheck( 3, 11 ) ) padbits |= 1<<4; + if( Config.ExButtonCheck( 3, 12 ) ) padbits |= 1<<3; + if( Config.ExButtonCheck( 3, 13 ) ) padbits |= 1<<2; + // A-G + if( Config.ExButtonCheck( 3, 0 ) ) padbits |= 1<<(7+8); + if( Config.ExButtonCheck( 3, 1 ) ) padbits |= 1<<(6+8); + if( Config.ExButtonCheck( 3, 2 ) ) padbits |= 1<<(5+8); + if( Config.ExButtonCheck( 3, 3 ) ) padbits |= 1<<(4+8); + if( Config.ExButtonCheck( 3, 4 ) ) padbits |= 1<<(3+8); + if( Config.ExButtonCheck( 3, 5 ) ) padbits |= 1<<(2+8); + if( Config.ExButtonCheck( 3, 6 ) ) padbits |= 1<<(1+8); + if( Config.ExButtonCheck( 3, 7 ) ) padbits |= 1<<(0+8); + // Select,Start,Kan,Pon,Chii,Reach,Ron + if( Config.ExButtonCheck( 3, 14 ) ) padbits |= 1<<(6+16); + if( Config.ExButtonCheck( 3, 15 ) ) padbits |= 1<<(7+16); + if( Config.ExButtonCheck( 3, 16 ) ) padbits |= 1<<(5+16); + if( Config.ExButtonCheck( 3, 17 ) ) padbits |= 1<<(4+16); + if( Config.ExButtonCheck( 3, 18 ) ) padbits |= 1<<(3+16); + if( Config.ExButtonCheck( 3, 19 ) ) padbits |= 1<<(2+16); + if( Config.ExButtonCheck( 3, 20 ) ) padbits |= 1<<(1+16); +DEBUGOUT( "%08X\n", padbits ); +} + +void EXPAD_Mahjang::SetSyncData( INT type, LONG data ) +{ + padbits = (DWORD)data; +} + +LONG EXPAD_Mahjang::GetSyncData( INT type ) +{ + return (LONG)padbits; +} diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Mahjang.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Mahjang.h new file mode 100644 index 00000000..3f41e542 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Mahjang.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Ide Yousuke Jissen Mahjang // +////////////////////////////////////////////////////////////////////////// +class EXPAD_Mahjang : public EXPAD +{ +public: + EXPAD_Mahjang( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE outbits; + DWORD padbits; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_OekakidsTablet.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_OekakidsTablet.cpp new file mode 100644 index 00000000..740a75ee --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_OekakidsTablet.cpp @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////////// +// Oekakids Tablet // +////////////////////////////////////////////////////////////////////////// +void EXPAD_OekakidsTablet::Reset() +{ + olddata = 0; + outbits = 0; + databits = 0; + + zapper_x = 0; + zapper_y = 0; + zapper_button = 0; +} + +BYTE EXPAD_OekakidsTablet::Read4017() +{ + return outbits; +} + +void EXPAD_OekakidsTablet::Write4016( BYTE data ) +{ + if( zapper_y < 48 ) { + DirectDraw.SetZapperDrawMode( TRUE ); + } else { + DirectDraw.SetZapperDrawMode( FALSE ); + } + + if( !(data & 0x01) ) { + outbits = 0; + databits = 0; + + if( zapper_button ) + databits |= 0x0001; + + LONG x, y; + + if( zapper_y >= 48 ) { + databits |= 0x0002; + } else if( zapper_button ) { + databits |= 0x0003; + } + + if( zapper_x < 0 ) { + x = 0; + } else { + x = ((240*zapper_x)/256)+8; + } + if( zapper_y < 0 ) { + y = 0; + } else { + y = ((256*zapper_y)/240)-12; + if( y < 0 ) + y = 0; + } + + databits = databits | (x << 10) | (y << 2); + } else { + // L->H + if( ((~olddata)&data) & 0x02 ) { + databits <<= 1; + } + if( !(data & 0x02) ) { + outbits = 0x04; + } else + if( databits & 0x40000 ) { + outbits = 0x00; + } else { + outbits = 0x08; + } + olddata = data; + } +} + +void EXPAD_OekakidsTablet::Sync() +{ + nes->GetZapperPos( zapper_x, zapper_y ); + + zapper_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + zapper_button = 0xFF; +} + +void EXPAD_OekakidsTablet::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + zapper_x = data; + } else if( type == 1 ) { + zapper_y = data; + } else if( type == 2 ) { + zapper_button = data?0xFF:0x00; + } +} + +LONG EXPAD_OekakidsTablet::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = zapper_x; + } else if( type == 1 ) { + data = zapper_y; + } else if( type == 2 ) { + data = zapper_button?0xFF:0x00; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_OekakidsTablet.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_OekakidsTablet.h new file mode 100644 index 00000000..b4d189c8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_OekakidsTablet.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// Oekakids Tablet // +////////////////////////////////////////////////////////////////////////// +class EXPAD_OekakidsTablet : public EXPAD +{ +public: + EXPAD_OekakidsTablet( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE olddata; + BYTE outbits; + DWORD databits; + + LONG zapper_x, zapper_y; + BYTE zapper_button; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_PEC_Keyboard.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_PEC_Keyboard.cpp new file mode 100644 index 00000000..742ee452 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_PEC_Keyboard.cpp @@ -0,0 +1,180 @@ +////////////////////////////////////////////////////////////////////////// +// PEC Keyboard // +// written by Temryu // +// last 2013/09/12 // +////////////////////////////////////////////////////////////////////////// + +void EXPAD_PEC_Keyboard::Reset() +{ + ScanNo = 0; + count4017 = 0; +} + +BYTE EXPAD_PEC_Keyboard::Read4017() +{ + BYTE data = 0; + + switch( ScanNo ) { + case 0: + if(count4017==0) if( DirectInput.m_Sw[DIK_LSHIFT ] ) data |= 0x02; + if(count4017==0) if( DirectInput.m_Sw[DIK_RSHIFT ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_TAB ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_GRAVE ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_LCONTROL] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_RCONTROL] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_CAPITAL ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_LMENU ] ) data |= 0x02; // (?) Alt (?) + if(count4017==5) if( DirectInput.m_Sw[DIK_RMENU ] ) data |= 0x02; // (?) Alt (?) + if(count4017==6) if( DirectInput.m_Sw[DIK_SPACE ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_ESCAPE ] ) data |= 0x02; + count4017++ ; + break; + case 1: + if(count4017==0) if( DirectInput.m_Sw[DIK_F3] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_F1] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_F2] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_F8] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_F4] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_F5] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_F7] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_F6] ) data |= 0x02; + count4017++ ; + break; + case 2: + if(count4017==0) if( DirectInput.m_Sw[DIK_Z ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_Q ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_1 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_RETURN ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_A ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_DECIMAL] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_NUMPAD0] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_ADD ] ) data |= 0x02; + count4017++ ; + break; + case 3: + if(count4017==0) if( DirectInput.m_Sw[DIK_X ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_W ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_2 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_NUMPAD9 ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_S ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_NUMPAD6 ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_NUMPAD3 ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_MULTIPLY] ) data |= 0x02; + count4017++ ; + break; + case 4: + if(count4017==0) if( DirectInput.m_Sw[DIK_C ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_E ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_3 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_NUMPAD8] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_D ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_NUMPAD5] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_NUMPAD2] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_DIVIDE ] ) data |= 0x02; + count4017++ ; + break; + case 5: + if(count4017==0) if( DirectInput.m_Sw[DIK_V ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_R ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_4 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_NUMPAD7] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_F ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_NUMPAD4] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_NUMPAD1] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_NUMLOCK] ) data |= 0x02; + count4017++ ; + break; + case 6: + if(count4017==0) if( DirectInput.m_Sw[DIK_B ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_T ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_5 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_RBRACKET ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_G ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_NUMPADENTER] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_BACKSLASH ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_BACK ] ) data |= 0x02; + count4017++ ; + break; + case 7: + if(count4017==0) if( DirectInput.m_Sw[DIK_COMMA ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_I ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_8 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_O ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_K ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_L ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_PERIOD] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_9 ] ) data |= 0x02; + count4017++ ; + break; + case 8: + if(count4017==0) if( DirectInput.m_Sw[DIK_M ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_U ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_7 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_P ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_J ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_SEMICOLON] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_SLASH ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_0 ] ) data |= 0x02; + count4017++ ; + break; + case 9: + if(count4017==0) if( DirectInput.m_Sw[DIK_N ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_Y ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_6 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_LBRACKET ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_H ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_APOSTROPHE] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_EQUALS ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_MINUS ] ) data |= 0x02; + count4017++ ; + break; + case 10: +// if(count4017==0) if( FALSE ) data |= 0x02; //?? +// if(count4017==1) if( FALSE ) data |= 0x02; //?? + if(count4017==2) if( DirectInput.m_Sw[DIK_F9 ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_SUBTRACT] ) data |= 0x02; +// if(count4017==4) if( FALSE ) data |= 0x02; //?? + if(count4017==5) if( DirectInput.m_Sw[DIK_F10 ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_F11 ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_F12 ] ) data |= 0x02; + count4017++ ; + break; + case 11: + if(count4017==0) if( DirectInput.m_Sw[DIK_DELETE] ) data |= 0x02; // ==BackSpace (?) + if(count4017==1) if( DirectInput.m_Sw[DIK_END ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_INSERT] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_LEFT ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_NEXT ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_DOWN ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_RIGHT ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_UP ] ) data |= 0x02; + count4017++ ; + break; + case 12: +// if(count4017==0) if( FALSE ) data |= 0x02; //?? +// if(count4017==1) if( FALSE ) data |= 0x02; //?? +// if(count4017==2) if( FALSE ) data |= 0x02; //?? + if(count4017==3) if( DirectInput.m_Sw[DIK_SYSRQ ] ) data |= 0x02; // (?) Print Screen SysRq (?) + if(count4017==4) if( DirectInput.m_Sw[DIK_SCROLL] ) data |= 0x02; // (?) Scroll Lock (?) + if(count4017==5) if( DirectInput.m_Sw[DIK_PRIOR ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_HOME ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_PAUSE ] ) data |= 0x02; // (?) Pause Break (?) + count4017++ ; + break; + } + + return data; +} + +void EXPAD_PEC_Keyboard::Write4016( BYTE data ) +{ + if( (data==0x01)||(data==0x00) ) { + ScanNo = 0; + } else if( data == 0x02 ) { + count4017 = 0; + } else if( (data==0x07)||(data==0x06) ) { + if( ++ScanNo > 12 ) + ScanNo = 0; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_PEC_Keyboard.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_PEC_Keyboard.h new file mode 100644 index 00000000..a2ee5903 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_PEC_Keyboard.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// PEC Keyboard // +// written by Temryu // +// last 2013/09/12 // +////////////////////////////////////////////////////////////////////////// + +class EXPAD_PEC_Keyboard : public EXPAD +{ +public: + EXPAD_PEC_Keyboard( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + BYTE Read4017(); + void Write4016( BYTE data ); + +protected: + BYTE ScanNo; + BYTE count4017; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Paddle.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Paddle.cpp new file mode 100644 index 00000000..8434288c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Paddle.cpp @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////// +// Paddle // +////////////////////////////////////////////////////////////////////////// +void EXPAD_Paddle::Reset() +{ + paddle_bits = 0; + paddle_data = 0; + paddle_posold = 0; +} + +BYTE EXPAD_Paddle::Read4016() +{ + return paddle_bits; +} + +BYTE EXPAD_Paddle::Read4017() +{ +BYTE data = (paddle_data&0x01)<<1; + paddle_data >>= 1; + return data; +} + +void EXPAD_Paddle::Write4016( BYTE data ) +{ +LONG x; + + paddle_bits = 0; + if( paddle_button ) + paddle_bits |= 0x02; + + x = paddle_x; + if( x < 0 ) { + paddle_data = paddle_posold; + return; + } + + if( x < 32 ) x = 32; + if( x > 223 ) x = 223; + x = (192*(x-32))/192; + + BYTE px = 0xFF-(BYTE)(0x52+172*x/192); + + // Erbg] + paddle_data = 0; + for( INT i = 0; i < 8; i++ ) { + paddle_data |= (px&(1<>i):0; + } + paddle_posold = paddle_data; +} + +void EXPAD_Paddle::Sync() +{ + LONG y; + nes->GetZapperPos( paddle_x, y ); + + paddle_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + paddle_button = 0xFF; +} + +void EXPAD_Paddle::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + paddle_x = data; + } else if( type == 2 ) { + paddle_button = data?0xFF:0x00; + } +} + +LONG EXPAD_Paddle::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = paddle_x; + } else if( type == 2 ) { + data = paddle_button?0xFF:0x00; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Paddle.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Paddle.h new file mode 100644 index 00000000..1cf47da4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Paddle.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// Paddle // +////////////////////////////////////////////////////////////////////////// +class EXPAD_Paddle : public EXPAD +{ +public: + EXPAD_Paddle( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4016(); + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE paddle_bits; + BYTE paddle_data; + + BYTE paddle_posold; + + LONG paddle_x; + BYTE paddle_button; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_SpaceShadowGun.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_SpaceShadowGun.cpp new file mode 100644 index 00000000..b0d60e01 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_SpaceShadowGun.cpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// Zapper // +////////////////////////////////////////////////////////////////////////// +void EXPAD_SpaceShadowGun::Reset() +{ + bomb_bits = 0; + zapper_button = 0; +} + +void EXPAD_SpaceShadowGun::Strobe() +{ + bomb_bits = nes->pad->pad1bit & 0xFC; + bomb_bits |= zapper_button & 0x02; +} + +BYTE EXPAD_SpaceShadowGun::Read4016() +{ +BYTE data = (bomb_bits & 0x01)<<1; + bomb_bits >>= 1; + return data; +} + +BYTE EXPAD_SpaceShadowGun::Read4017() +{ +BYTE data = 0x08; + + if( zapper_button & 0x01 ) { + data |= 0x10; + } + + if( nes->GetZapperHit() ) { + if( DirectDraw.GetZapperHit() >= 0xFE ) + data &= ~0x08; + } + return data; +} + +void EXPAD_SpaceShadowGun::Sync() +{ + nes->GetZapperPos( zapper_x, zapper_y ); + + zapper_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + zapper_button |= 0x01; + if( ::GetAsyncKeyState(VK_RBUTTON)&0x8000 ) + zapper_button |= 0x02; +} + +void EXPAD_SpaceShadowGun::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + zapper_x = data; + } else if( type == 1 ) { + zapper_y = data; + } else if( type == 2 ) { + zapper_button = data; + } +} + +LONG EXPAD_SpaceShadowGun::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = zapper_x; + } else if( type == 1 ) { + data = zapper_y; + } else if( type == 2 ) { + data = zapper_button; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_SpaceShadowGun.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_SpaceShadowGun.h new file mode 100644 index 00000000..24b07ee1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_SpaceShadowGun.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// Space Shadow Gun // +////////////////////////////////////////////////////////////////////////// +class EXPAD_SpaceShadowGun : public EXPAD +{ +public: + EXPAD_SpaceShadowGun( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + void Strobe(); + BYTE Read4016(); + BYTE Read4017(); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + LONG zapper_x, zapper_y; + BYTE bomb_bits; + BYTE zapper_button; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Subor_Keyboard.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Subor_Keyboard.cpp new file mode 100644 index 00000000..19fc81fc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Subor_Keyboard.cpp @@ -0,0 +1,203 @@ +////////////////////////////////////////////////////////////////////////// +// Subor Keyboard // +////////////////////////////////////////////////////////////////////////// +void EXPAD_Subor_Keyboard::Reset() +{ + bOut = FALSE; + ScanNo = 0; +} + +BYTE EXPAD_Subor_Keyboard::Read4016() +{ + BYTE data = 0; + + return data; +} + +BYTE EXPAD_Subor_Keyboard::Read4017() +{ + BYTE data = 0xFF; + + switch( ScanNo ) { + case 1: + if( bOut ) { + if( DirectInput.m_Sw[DIK_4 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_G ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_F ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_C ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F2 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_E ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_5 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_V ] ) data &= ~0x10; + } + break; + case 2: + if( bOut ) { + if( DirectInput.m_Sw[DIK_2 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_D ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_S ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_END ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F1 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_W ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_3 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_X ] ) data &= ~0x10; + } + break; + case 3: + if( bOut ) { + if( DirectInput.m_Sw[DIK_INSERT ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_BACK ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_NEXT ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_RIGHT ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F8 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_PRIOR ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_DELETE] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_HOME ] ) data &= ~0x10; + } + break; + case 4: + if( bOut ) { + if( DirectInput.m_Sw[DIK_9 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_I ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_L ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_COMMA ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F5 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_O ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_0 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_PERIOD ] ) data &= ~0x10; + } + break; + case 5: + if( bOut ) { + if( DirectInput.m_Sw[DIK_RBRACKET ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_RETURN ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_UP ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LEFT ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F7 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_LBRACKET ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_BACKSLASH ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_DOWN ] ) data &= ~0x10; + } + break; + case 6: + if( bOut ) { + if( DirectInput.m_Sw[DIK_Q ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_CAPITAL ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_Z ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_TAB ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_ESCAPE ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_A ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_1 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LCONTROL ] ) data &= ~0x10; + } + break; + case 7: + if( bOut ) { + if( DirectInput.m_Sw[DIK_7 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_Y ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_K ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_M ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F4 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_U ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_8 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_J ] ) data &= ~0x10; + } + break; + case 8: + if( bOut ) { + if( DirectInput.m_Sw[DIK_MINUS ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_SEMICOLON ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_APOSTROPHE ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_SLASH ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F6 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_P ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_EQUALS ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_LSHIFT ] || + DirectInput.m_Sw[DIK_RSHIFT ] ) data &= ~0x10; + } + break; + case 9: + if( bOut ) { + if( DirectInput.m_Sw[DIK_T ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_H ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_N ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_SPACE ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F3 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_R ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_6 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_B ] ) data &= ~0x10; + } + break; + case 10: + if( bOut ) { + } else { + data &= ~0x02; + } + break; + case 11: + if( bOut ) { + if( DirectInput.m_Sw[DIK_LMENU ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_NUMPAD4 ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_NUMPAD7 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_F11 ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F12 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_NUMPAD1 ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_NUMPAD2 ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_NUMPAD8 ] ) data &= ~0x10; + } + break; + case 12: + if( bOut ) { + if( DirectInput.m_Sw[DIK_SUBTRACT ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_ADD ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_MULTIPLY ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_NUMPAD9 ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F10 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_NUMPAD5 ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_DIVIDE ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_NUMLOCK ] ) data &= ~0x10; + } + break; + case 13: + if( bOut ) { + if( DirectInput.m_Sw[DIK_GRAVE ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_NUMPAD6 ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_PAUSE ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_SPACE ] ) data &= ~0x10; + } else { + if( DirectInput.m_Sw[DIK_F9 ] ) data &= ~0x02; + if( DirectInput.m_Sw[DIK_NUMPAD3 ] ) data &= ~0x04; + if( DirectInput.m_Sw[DIK_DECIMAL ] ) data &= ~0x08; + if( DirectInput.m_Sw[DIK_NUMPAD0 ] ) data &= ~0x10; + } + break; + } + + return data; +} + +void EXPAD_Subor_Keyboard::Write4016( BYTE data ) +{ + if( data == 0x05 ) { + bOut = FALSE; + ScanNo = 0; + } else if( data == 0x04 ) { + if( ++ScanNo > 13 ) + ScanNo = 0; + bOut = !bOut; + } else if( data == 0x06 ) { + bOut = !bOut; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Subor_Keyboard.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Subor_Keyboard.h new file mode 100644 index 00000000..21b8080a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Subor_Keyboard.h @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// Subor Keyboard // +////////////////////////////////////////////////////////////////////////// +class EXPAD_Subor_Keyboard : public EXPAD +{ +public: + EXPAD_Subor_Keyboard( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4016(); + BYTE Read4017(); + void Write4016( BYTE data ); + +protected: + BOOL bOut; + BYTE ScanNo; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Toprider.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Toprider.cpp new file mode 100644 index 00000000..278b4cee --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Toprider.cpp @@ -0,0 +1,208 @@ +////////////////////////////////////////////////////////////////////////// +// Toprider // +////////////////////////////////////////////////////////////////////////// +void EXPAD_Toprider::Reset() +{ + rider_bita = 0; + rider_bitb = 0; + + rider_pos = 0; + rider_accel = 0; + rider_brake = 0; + + rider_button = 0; +} + +void EXPAD_Toprider::Write4016( BYTE data ) +{ + if( data & 0x01 ) { + rider_bita = rider_bitb = 0; + if( rider_pos > 0 ) { + // RIGHT + if( rider_pos > 0x10 ) { + rider_bita |= (1<<1)|(1<<3); + } else if( rider_pos > 0x0A ) { + rider_bita |= (1<<1)|(0<<3); + } else if( rider_pos > 0x04 ) { + rider_bita |= (0<<1)|(1<<3); + } + } else { + // LEFT + if( rider_pos < -0x10 ) { + rider_bita |= (1<<2)|(1<<4); + } else if( rider_pos < -0x0A ) { + rider_bita |= (1<<2)|(0<<4); + } else if( rider_pos < -0x04 ) { + rider_bita |= (0<<2)|(1<<4); + } + } + if( rider_accel > 0x08 || rider_brake < 0x08 ) { + if( rider_accel > 0x10 ) { + rider_bitb |= (1<<0); + } else if( rider_accel > 0x0A ) { + rider_bitb |= (1<<4); + } else if( rider_accel > 0x04 ) { + rider_bitb |= (1<<5); + } + } else { + rider_bita |= (1<<5); + if( rider_brake > 0x10 ) { + rider_bitb |= (1<<1); + } else if( rider_brake > 0x0A ) { + rider_bitb |= (1<<2); + } else if( rider_brake > 0x04 ) { + rider_bitb |= (1<<3); + } + } + // EC[ + if( rider_button&0x01 ) + rider_bita |= 0x80; + // SHIFT(Toggle) + if( rider_button&0x80 ) + rider_bita |= 0x40; + // START,SELECT + if( rider_button&0x10 ) + rider_bitb |= 0x40; + if( rider_button&0x20 ) + rider_bitb |= 0x80; + } +} + +BYTE EXPAD_Toprider::Read4017() +{ +BYTE data = 0; + data |= (rider_bita&0x01)<<4; + data |= (rider_bitb&0x01)<<3; + rider_bita >>= 1; + rider_bitb >>= 1; + return data; +} + +void EXPAD_Toprider::Sync() +{ +BYTE bit = 0; + + // Up + if( Config.controller.nButton[0][ 0] && DirectInput.m_Sw[Config.controller.nButton[0][ 0]] + || Config.controller.nButton[0][16] && DirectInput.m_Sw[Config.controller.nButton[0][16]] ) + bit |= 1<<4; + // Down + if( Config.controller.nButton[0][ 1] && DirectInput.m_Sw[Config.controller.nButton[0][ 1]] + || Config.controller.nButton[0][17] && DirectInput.m_Sw[Config.controller.nButton[0][17]] ) + bit |= 1<<5; + // Left + if( Config.controller.nButton[0][ 2] && DirectInput.m_Sw[Config.controller.nButton[0][ 2]] + || Config.controller.nButton[0][18] && DirectInput.m_Sw[Config.controller.nButton[0][18]] ) + bit |= 1<<6; + // Right + if( Config.controller.nButton[0][ 3] && DirectInput.m_Sw[Config.controller.nButton[0][ 3]] + || Config.controller.nButton[0][19] && DirectInput.m_Sw[Config.controller.nButton[0][19]] ) + bit |= 1<<7; + + // E͂֎~ + if( (bit&((1<<6)|(1<<7))) == ((1<<6)|(1<<7)) ) + bit &= ~((1<<6)|(1<<7)); + + // A,B + if( Config.controller.nButton[0][ 4] && DirectInput.m_Sw[Config.controller.nButton[0][ 4]] + || Config.controller.nButton[0][20] && DirectInput.m_Sw[Config.controller.nButton[0][20]] ) + bit |= 1<<0; + if( Config.controller.nButton[0][ 5] && DirectInput.m_Sw[Config.controller.nButton[0][ 5]] + || Config.controller.nButton[0][21] && DirectInput.m_Sw[Config.controller.nButton[0][21]] ) + bit |= 1<<1; + + // Start, Select + if( Config.controller.nButton[0][ 8] && DirectInput.m_Sw[Config.controller.nButton[0][ 8]] + || Config.controller.nButton[0][24] && DirectInput.m_Sw[Config.controller.nButton[0][24]] ) + bit |= 1<<2; + if( Config.controller.nButton[0][ 9] && DirectInput.m_Sw[Config.controller.nButton[0][ 9]] + || Config.controller.nButton[0][25] && DirectInput.m_Sw[Config.controller.nButton[0][25]] ) + bit |= 1<<3; + + if( !(bit & ((1<<6)|(1<<7))) ) { + // To center... + if( rider_pos ) { + rider_pos += (rider_pos>0)?-1:1; + } + } else if( bit & (1<<6) ) { + // LEFT + rider_pos -= (rider_pos>-0x18)?1:0; + } else if( bit & (1<<7) ) { + // RIGHT + rider_pos += (rider_pos<0x18)?1:0; + } + + // Brake(A) + if( bit & (1<<0) ) { + rider_brake += (rider_brake<0x18)?1:0; + } else { + rider_brake -= (rider_brake>0)?1:0; + } + // Accel(B) + if( bit & (1<<1) ) { + rider_accel += (rider_accel<0x18)?1:0; + } else { + rider_accel -= (rider_accel>0)?1:0; + } + + rider_button &= 0xC0; + + // Shift(UP)(Toggle) + if( bit & (1<<4) ) { + if( !(rider_button&0x40) ) { + if( rider_button&0x80 ) { + rider_button &= ~0x80; + } else { + rider_button |= 0x80; + } + } + } + // old + if( bit & (1<<4) ) + rider_button |= 0x40; + else + rider_button &= ~0x40; + + // Willey(DOWN) + if( bit & (1<<5) ) + rider_button |= 0x01; + // Start, Select + if( bit & (1<<2) ) + rider_button |= 0x20; + if( bit & (1<<3) ) + rider_button |= 0x10; +#if 0 +DEBUGOUT( "RIDER POS=%d\n", rider_pos ); +DEBUGOUT( "RIDER ACC=%d\n", rider_accel ); +DEBUGOUT( "RIDER BRK=%d\n", rider_brake ); +DEBUGOUT( "RIDER BTN=%02X\n", rider_button ); +#endif +} + +void EXPAD_Toprider::SetSyncData( INT type, LONG data ) +{ + rider_pos = (INT)((SBYTE)( data &0x000000FF)); + rider_accel = (INT)((SBYTE)((data>> 8)&0x000000FF)); + rider_brake = (INT)((SBYTE)((data>>16)&0x000000FF)); + rider_button = (BYTE)(data>>24); + +#if 0 +DEBUGOUT( "RIDER POS=%d\n", rider_pos ); +DEBUGOUT( "RIDER ACC=%d\n", rider_accel ); +DEBUGOUT( "RIDER BRK=%d\n", rider_brake ); +DEBUGOUT( "RIDER BTN=%02X\n", rider_button ); +#endif +} + +LONG EXPAD_Toprider::GetSyncData( INT type ) +{ +LONG data = 0; + + data = (rider_pos&0xFF)| + ((rider_accel&0xFF)<< 8)| + ((rider_brake&0xFF)<<16)| + (rider_button<<24); + + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Toprider.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Toprider.h new file mode 100644 index 00000000..524e9f02 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Toprider.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// Toprider // +////////////////////////////////////////////////////////////////////////// +class EXPAD_Toprider : public EXPAD +{ +public: + EXPAD_Toprider( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + void Write4016( BYTE data ); + BYTE Read4017(); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE rider_bita; + BYTE rider_bitb; + + INT rider_pos; + INT rider_accel; + INT rider_brake; + BYTE rider_button; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_TurboFile.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_TurboFile.cpp new file mode 100644 index 00000000..8943479b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_TurboFile.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// TurboFile // +////////////////////////////////////////////////////////////////////////// +void EXPAD_TurboFile::Reset() +{ + tf_address = 0; + tf_dataold = 0; + tf_databit = 0; + tf_data = 0; +} + +BYTE EXPAD_TurboFile::Read4017() +{ + return tf_data; +} + +void EXPAD_TurboFile::Write4016( BYTE data ) +{ + INT bank = nes->GetTurboFileBank(); + + // Reset + if( !(data & 0x02) ) { + tf_address = 0; + tf_databit = 0x01; + } + // Write bit + if( data & 0x04 ) { + ERAM[bank*0x2000+tf_address] &= ~tf_databit; + ERAM[bank*0x2000+tf_address] |= (data&0x01)?tf_databit:0; + } + // Address inc/bit shift + if( (tf_dataold&(~data)) & 0x04 ) { + if( tf_databit == 0x80 ) { + tf_address = (tf_address+1) & 0x1FFF; + tf_databit = 0x01; + } else { + tf_databit <<= 1; + } + } + // Read bit + if( ERAM[bank*0x2000+tf_address] & tf_databit ) { + tf_data = 0x04; + } else { + tf_data = 0x00; + } + tf_dataold = data; +} diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_TurboFile.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_TurboFile.h new file mode 100644 index 00000000..c73fbf56 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_TurboFile.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// TurboFile // +////////////////////////////////////////////////////////////////////////// +class EXPAD_TurboFile : public EXPAD +{ +public: + EXPAD_TurboFile( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + void Write4016( BYTE data ); + +protected: + INT tf_address; + BYTE tf_dataold; + BYTE tf_databit; + BYTE tf_data; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSUnisystem.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSUnisystem.cpp new file mode 100644 index 00000000..f11375e1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSUnisystem.cpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// VS-Unisystem // +////////////////////////////////////////////////////////////////////////// +void EXPAD_VSUnisystem::Reset() +{ +} + +BYTE EXPAD_VSUnisystem::Read4016() +{ +BYTE data = 0x00; + + // Coin 1 + if( Config.ButtonCheck( 0, Config.controller.nVSUnisystem ) ) + data |= 0x20; + // Coin 2 + if( Config.ButtonCheck( 1, Config.controller.nVSUnisystem ) ) { + data |= 0x40; + } + // Service + if( Config.ButtonCheck( 2, Config.controller.nVSUnisystem ) ) { + data |= 0x04; + } + + // Dip-Switch + data |= ((nes->GetVSDipSwitch()<<3) & 0x18); + + if( nes->rom->GetPROM_CRC() == 0xC99EC059 ) { // VS Raid on Bungeling Bay(J) + data |= 0x80; + } + + return data; +} + +BYTE EXPAD_VSUnisystem::Read4017() +{ +BYTE data = 0x00; + + // Dip-Switch + data = nes->GetVSDipSwitch() & 0xFC; + + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSUnisystem.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSUnisystem.h new file mode 100644 index 00000000..394a40bb --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSUnisystem.h @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +// VS-Unisystem // +////////////////////////////////////////////////////////////////////////// +class EXPAD_VSUnisystem : public EXPAD +{ +public: + EXPAD_VSUnisystem( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4016(); + BYTE Read4017(); + +protected: +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSZapper.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSZapper.cpp new file mode 100644 index 00000000..eae89022 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSZapper.cpp @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////// +// VS-Unisystem Zapper // +////////////////////////////////////////////////////////////////////////// +void EXPAD_VSZapper::Reset() +{ + DEBUGOUT( "EXPAD_VSZapper::Reset\n" ); + + readlatch[0] = 0; + readlatch[1] = 0; + zapper_button = 0; +} + +void EXPAD_VSZapper::Strobe() +{ + readlatch[0] = 0x10; + readlatch[1] = 0x00; + + if( nes->GetZapperHit() ) { + if( DirectDraw.GetZapperHit() >= 0x40 ) { + readlatch[0] |= 0x40; + } + } + + readlatch[0] |= zapper_button ? 0x80 : 0x00; +} + +BYTE EXPAD_VSZapper::Read4016() +{ +BYTE data = 0x00; + + data = readlatch[0] & 0x01; + readlatch[0] >>= 1; + + // Coin 1 + if( Config.ButtonCheck( 0, Config.controller.nVSUnisystem ) ) + data |= 0x20; + // Coin 2 + if( Config.ButtonCheck( 1, Config.controller.nVSUnisystem ) ) + data |= 0x40; + // Service + if( Config.ButtonCheck( 2, Config.controller.nVSUnisystem ) ) { + data |= 0x04; + } + + // Dip-Switch + data |= ((nes->GetVSDipSwitch()<<3) & 0x18); + + return data; +} + +BYTE EXPAD_VSZapper::Read4017() +{ +BYTE data = 0x00; + + data = readlatch[1] & 0x01; + readlatch[1] >>= 1; + + // Dip-Switch + data |= (nes->GetVSDipSwitch() & 0xFC); + + return data; +} + +void EXPAD_VSZapper::Sync() +{ + nes->GetZapperPos( zapper_x, zapper_y ); + + zapper_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + zapper_button = 0xFF; +} + +void EXPAD_VSZapper::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + zapper_x = data; + } else if( type == 1 ) { + zapper_y = data; + } else if( type == 2 ) { + zapper_button = data?0xFF:0x00; + } +} + +LONG EXPAD_VSZapper::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = zapper_x; + } else if( type == 1 ) { + data = zapper_y; + } else if( type == 2 ) { + data = zapper_button?0xFF:0x00; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSZapper.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSZapper.h new file mode 100644 index 00000000..14bb490a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_VSZapper.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// VS-Unisystem Zapper // +////////////////////////////////////////////////////////////////////////// +class EXPAD_VSZapper : public EXPAD +{ +public: + EXPAD_VSZapper( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + void Strobe(); + + BYTE Read4016(); + BYTE Read4017(); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + BYTE readlatch[2]; + + LONG zapper_x, zapper_y; + BYTE zapper_button; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXingMouse.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXingMouse.cpp new file mode 100644 index 00000000..2301af95 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXingMouse.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// Zapper // +////////////////////////////////////////////////////////////////////////// +void EXPAD_YuXingMouse::Reset() +{ + zapper_button = 0; +} + +BYTE EXPAD_YuXingMouse::Read4017() +{ +BYTE data = 0x08; + + if( zapper_button ) { + data |= 0x10; + } + + if( nes->GetZapperHit() ) { + if( DirectDraw.GetZapperHit() >= 0x40 ) + data &= ~0x08; + } + return data; +} + +void EXPAD_YuXingMouse::Sync() +{ + nes->GetZapperPos( zapper_x, zapper_y ); +DEBUGOUT( "Mouse_X= %04x ; Mouse_Y= %04x ; Mouse_data= %03x\n", zapper_x, zapper_y, zapper_button ); + zapper_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + zapper_button = 0xFF; +} + +void EXPAD_YuXingMouse::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + zapper_x = data; + } else if( type == 1 ) { + zapper_y = data; + } else if( type == 2 ) { + zapper_button = data?0xFF:0x00; + } +} + +LONG EXPAD_YuXingMouse::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = zapper_x; + } else if( type == 1 ) { + data = zapper_y; + } else if( type == 2 ) { + data = zapper_button?0xFF:0x00; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXingMouse.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXingMouse.h new file mode 100644 index 00000000..a04ece73 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXingMouse.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Zapper // +////////////////////////////////////////////////////////////////////////// +class EXPAD_YuXingMouse : public EXPAD +{ +public: + EXPAD_YuXingMouse( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + LONG zapper_x, zapper_y; + BYTE zapper_button; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXing_Mouse.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXing_Mouse.cpp new file mode 100644 index 00000000..17e59ab0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXing_Mouse.cpp @@ -0,0 +1,225 @@ +////////////////////////////////////////////////////////////////////////// +// YuXing_Mouse // +////////////////////////////////////////////////////////////////////////// +void EXPAD_YuXing_Mouse::Reset() +{ + mouse_data = 0x00; + mouse_bits = 0; + mouse_count = 0; + mouse_button = 0; + mouse_x = 0; + mouse_y = 0; + mouse_x_old = 0; + mouse_y_old = 0; + mouse_x_move = 0; + mouse_y_move = 0; + temp1 = 3; + reg[0] = 0; + reg[1] = 0; + reg[2] = 0; + reg[3] = 0; + reg[4] = 0; + reg[5] = 0; +} + +void EXPAD_YuXing_Mouse::Strobe() +{ + mouse_data = 0x00; + mouse_x_move = 0; + mouse_y_move = 0; + + if ( mouse_x == mouse_x_old ){ + reg[0] = 0; + } + if ( mouse_y == mouse_y_old ){ + reg[1] = 0; + } + if ( (mouse_x-mouse_x_old)>0 ){ // + mouse_x_move = mouse_x - mouse_x_old; + reg[0] = ( mouse_x_move & 0xC0 ) >> 4; + reg[0] = reg[0] & 0x7; +// DEBUGOUT( "ƣ\n" ); + } + if ( (mouse_x-mouse_x_old)<0 ){ // + mouse_x_move = (mouse_x - mouse_x_old)&0xFF; + reg[0] = ( mouse_x_move & 0xC0 ) >> 4; + reg[0] = reg[0] | 0xC; +// DEBUGOUT( "ƣ\n" ); + } + + if ( (mouse_y-mouse_y_old)>0 ){ // + mouse_y_move = mouse_y - mouse_y_old; + reg[1] = ( mouse_y_move & 0xC0 ) >> 6; + reg[1] = reg[1] & 0x1; +// DEBUGOUT( "ƣ\n" ); + } + if ( (mouse_y-mouse_y_old)<0 ){ // + mouse_y_move = (mouse_y - mouse_y_old)&0xFF; + reg[1] = ( mouse_y_move & 0xC0 ) >> 6; + reg[1] = reg[1] | 0x3; +// DEBUGOUT( "ƣ\n" ); + } + +} + +BYTE EXPAD_YuXing_Mouse::Read4016() +{ + BYTE data = 0; + + reg[2]++; + +// DEBUGOUT( "Mouse_X= %04x ; Mouse_Y= %04x ; Mouse_data= %03x\n", mouse_x, mouse_y, mouse_data ); +// DEBUGOUT( "Read : mouse_x_move = %03x\n", mouse_x_move ); +// DEBUGOUT( "Read : mouse_y_move = %03x\n", mouse_y_move ); +// DEBUGOUT( "Read : mouse_button = %03x\n", mouse_button ); + + if((mouse_x_move==0)&&(mouse_y_move==0)&&(mouse_button==0)){ + reg[5] = 1; + if(reg[4]==0){ + DEBUGOUT( "[1] 0 ...\n" ); + temp1 = 3; + mouse_data = 0x00; + return 0; + } + } + + reg[4] = 1; + if((reg[3]==1)){ + reg[3] = 0; + reg[5] = 0; + DEBUGOUT( "[4] 1 ...\n" ); + return 1; + } + + if(temp1==3){ + DEBUGOUT( "[ 0x90] = %03x\n", RAM[0x90] ); + DEBUGOUT( "[ 0x91] = %03x\n", RAM[0x91] ); + DEBUGOUT( "[ 0x92] = %03x\n", RAM[0x92] ); + DEBUGOUT( "[0x200] = %03x\n", RAM[0x200] ); + DEBUGOUT( "[0x203] = %03x\n", RAM[0x203] ); + DEBUGOUT( "[2] 1 ...\n" ); + reg[5] = 0; + temp1 = 0; + return 1; + }else{ + switch( temp1 ) { + case 0x00: +// mouse_data |= 0x40; + if(mouse_button&0x01) mouse_data |= 0x20; + if(mouse_button&0x02) mouse_data |= 0x10; + mouse_data |= reg[0]; + mouse_data |= reg[1]; + break; + case 0x01: + mouse_data |= (mouse_y_move&0x7F); + break; + case 0x02: + mouse_data |= (mouse_x_move&0x7F); + break; + } + +// mouse[0] = (mouse_data>>0)&1; +// mouse[1] = (mouse_data>>1)&1; +// mouse[2] = (mouse_data>>2)&1; +// mouse[3] = (mouse_data>>3)&1; +// mouse[4] = (mouse_data>>4)&1; +// mouse[5] = (mouse_data>>5)&1; +// mouse[6] = (mouse_data>>6)&1; +// mouse[7] = (mouse_data>>7)&1; +// mouse_data=(mouse[0]<<7)|(mouse[1]<<6)|(mouse[2]<<5)|(mouse[3]<<4)|(mouse[4]<<3)|(mouse[5]<<2)|(mouse[6]<<1)|(mouse[7]<<0); +// mouse_data=(mouse[0]<<6)|(mouse[1]<<5)|(mouse[2]<<4)|(mouse[3]<<3)|(mouse[4]<<2)|(mouse[5]<<1)|(mouse[6]<<0); + + if(mouse_bits == 7){ + mouse_bits = 0; + temp1++; + reg[3] = 1; + if(temp1==3){ + reg[3]=0; + reg[4]=0; + } + if(reg[5]==1){ + reg[5]=0; + reg[3]=0; + reg[4]=0; + temp1=3; + DEBUGOUT( "[5] 1 ...\n" ); + return 1; + } + DEBUGOUT( "[3] 0 ...\n" ); + DEBUGOUT( "temp1 = %03x\n", temp1 ); + DEBUGOUT( "[0x90] = %03x\n", RAM[0x90] ); + DEBUGOUT( "[0x91] = %03x\n", RAM[0x91] ); + DEBUGOUT( "[0x92] = %03x\n", RAM[0x92] ); + DEBUGOUT( "[0x200] = %03x\n", RAM[0x200] ); + DEBUGOUT( "[0x203] = %03x\n", RAM[0x203] ); + return 0; + }else{ + data |= (((mouse_data<>6)^1; + mouse_bits++; + } + + DEBUGOUT( "mouse_data = %03x\n", mouse_data ); + + return data; + } + +// DEBUGOUT( "mouse_bits= %03x ; mouse_data= %03x ; data= %03x\n", mouse_bits, mouse_data, data ); +// DEBUGOUT( "Mouse_X= %04x ; Mouse_Y= %04x ; Mouse_data= %03x\n", mouse_x, mouse_y, mouse_data ); +// DEBUGOUT( "mouse_count = %03x\n", mouse_count ); +// DEBUGOUT( "mouse_bits = %03x\n", mouse_bits ); + +} + +BYTE EXPAD_YuXing_Mouse::Read4017() +{ +// DEBUGOUT( "Read4017 : L=%3d CYC=%d\n", nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + BYTE data = 0x00; + + // + + return data; +} + +void EXPAD_YuXing_Mouse::Write4016( BYTE data ) +{ +// DEBUGOUT( "Write4016 : L=%3d CYC=%d\n", nes->GetScanline(), nes->cpu->GetTotalCycles() ); + + +} + +void EXPAD_YuXing_Mouse::Sync() +{ + mouse_x_old = mouse_x; + mouse_y_old = mouse_y; + + nes->GetZapperPos( mouse_x, mouse_y ); + mouse_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + mouse_button |= 0x01; + if( ::GetAsyncKeyState(VK_RBUTTON)&0x8000 ) + mouse_button |= 0x02; + +} +void EXPAD_YuXing_Mouse::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + mouse_x = data; + } else if( type == 1 ) { + mouse_y = data; + } else if( type == 2 ) { + mouse_button = data; + } +} +LONG EXPAD_YuXing_Mouse::GetSyncData( INT type ) +{ + LONG data = 0; + if( type == 0 ) { + data = mouse_x; + } else if( type == 1 ) { + data = mouse_y; + } else if( type == 2 ) { + data = mouse_button; + } + return data; +} diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXing_Mouse.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXing_Mouse.h new file mode 100644 index 00000000..bd75bd9b --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_YuXing_Mouse.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// YuXing_Mouse // +////////////////////////////////////////////////////////////////////////// +class EXPAD_YuXing_Mouse : public EXPAD +{ +public: + EXPAD_YuXing_Mouse( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + void Strobe(); + BYTE Read4016(); + BYTE Read4017(); + void Write4016( BYTE data ); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + LONG mouse_x, mouse_y, mouse_x_old, mouse_y_old, mouse_x_move, mouse_y_move; + BYTE mouse_button, mouse_bits, mouse_data, mouse_count; + BYTE temp1, reg[8], mouse[8]; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Zapper.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Zapper.cpp new file mode 100644 index 00000000..6da44548 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Zapper.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// Zapper // +////////////////////////////////////////////////////////////////////////// +void EXPAD_Zapper::Reset() +{ + zapper_button = 0; +} + +BYTE EXPAD_Zapper::Read4017() +{ +BYTE data = 0x08; + + if( zapper_button ) { + data |= 0x10; + } + + if( nes->GetZapperHit() ) { + if( DirectDraw.GetZapperHit() >= 0x40 ) + data &= ~0x08; + } + return data; +} + +void EXPAD_Zapper::Sync() +{ + nes->GetZapperPos( zapper_x, zapper_y ); + + zapper_button = 0; + if( ::GetAsyncKeyState(VK_LBUTTON)&0x8000 ) + zapper_button = 0xFF; +} + +void EXPAD_Zapper::SetSyncData( INT type, LONG data ) +{ + if( type == 0 ) { + zapper_x = data; + } else if( type == 1 ) { + zapper_y = data; + } else if( type == 2 ) { + zapper_button = data?0xFF:0x00; + } +} + +LONG EXPAD_Zapper::GetSyncData( INT type ) +{ +LONG data = 0; + + if( type == 0 ) { + data = zapper_x; + } else if( type == 1 ) { + data = zapper_y; + } else if( type == 2 ) { + data = zapper_button?0xFF:0x00; + } + return data; +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Zapper.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Zapper.h new file mode 100644 index 00000000..4a14f9df --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_Zapper.h @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// Zapper // +////////////////////////////////////////////////////////////////////////// +class EXPAD_Zapper : public EXPAD +{ +public: + EXPAD_Zapper( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + + BYTE Read4017(); + + void Sync(); + void SetSyncData( INT type, LONG data ); + LONG GetSyncData( INT type ); + +protected: + LONG zapper_x, zapper_y; + BYTE zapper_button; + +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ZeCheng_Keyboard.cpp b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ZeCheng_Keyboard.cpp new file mode 100644 index 00000000..eef3813f --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ZeCheng_Keyboard.cpp @@ -0,0 +1,172 @@ +////////////////////////////////////////////////////////////////////////// +// ZeCheng Keyboard // +// written by Temryu // +// last 2013/10/13 // +////////////////////////////////////////////////////////////////////////// + +void EXPAD_ZeCheng_Keyboard::Reset() +{ + ScanNo = 0; + count4017 = 0; + tb = FALSE; +} + +BYTE EXPAD_ZeCheng_Keyboard::Read4017() +{ + BYTE data = 0; + + switch( ScanNo ) { + case 0: + if(count4017==0) if( DirectInput.m_Sw[DIK_Z ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_A ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_Q ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_1 ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_LSHIFT ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_RSHIFT ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_CAPITAL] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_TAB ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_GRAVE ] ) data |= 0x02; + count4017++ ; + break; + case 1: + if(count4017==0) if( DirectInput.m_Sw[DIK_C] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_D] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_E] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_3] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_X] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_S] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_W] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_2] ) data |= 0x02; + count4017++ ; + break; + case 2: + if(count4017==0) if( DirectInput.m_Sw[DIK_B] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_G] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_T] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_5] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_V] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_F] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_R] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_4] ) data |= 0x02; + count4017++ ; + break; + case 3: + if(count4017==0) if( DirectInput.m_Sw[DIK_M] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_J] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_U] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_7] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_N] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_H] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_Y] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_6] ) data |= 0x02; + count4017++ ; + break; + case 4: + if(count4017==0) if( DirectInput.m_Sw[DIK_PERIOD] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_L ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_O ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_9 ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_COMMA ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_K ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_I ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_8 ] ) data |= 0x02; + count4017++ ; + break; + case 5: + if(count4017==0) if( DirectInput.m_Sw[DIK_BACKSLASH ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_APOSTROPHE] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_LBRACKET ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_MINUS ] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_SLASH ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_SEMICOLON ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_P ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_0 ] ) data |= 0x02; + count4017++ ; + break; + case 6: + if(count4017==0) if( DirectInput.m_Sw[DIK_END ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_LEFT ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_HOME ] ) data |= 0x02; +// if(count4017==3) if( FALSE ) data |= 0x02; // == Caps Lock + if(count4017==4) if( DirectInput.m_Sw[DIK_BACK ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_RETURN ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_RBRACKET] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_EQUALS ] ) data |= 0x02; + count4017++ ; + break; + case 7: + if(count4017==0) if( DirectInput.m_Sw[DIK_NEXT ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_RIGHT ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_PRIOR ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_ESCAPE] ) data |= 0x02; // + if(count4017==4) if( DirectInput.m_Sw[DIK_DOWN ] ) data |= 0x02; +// if(count4017==5) if( FALSE ) data |= 0x02; //Num 5 + if(count4017==6) if( DirectInput.m_Sw[DIK_UP ] ) data |= 0x02; +// if(count4017==7) if( FALSE ) data |= 0x02; //??? + count4017++ ; + break; + case 8: + if(count4017==0) if( DirectInput.m_Sw[DIK_DELETE ] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_ADD ] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_MULTIPLY ] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_NUMPADENTER] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_INSERT ] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_SPACE ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_LMENU ] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_RMENU ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_LCONTROL ] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_RCONTROL ] ) data |= 0x02; + count4017++ ; + break; + case 9: + if(count4017==0) if( DirectInput.m_Sw[DIK_F8] ) data |= 0x02; + if(count4017==1) if( DirectInput.m_Sw[DIK_F7] ) data |= 0x02; + if(count4017==2) if( DirectInput.m_Sw[DIK_F6] ) data |= 0x02; + if(count4017==3) if( DirectInput.m_Sw[DIK_F5] ) data |= 0x02; + if(count4017==4) if( DirectInput.m_Sw[DIK_F4] ) data |= 0x02; + if(count4017==5) if( DirectInput.m_Sw[DIK_F3] ) data |= 0x02; + if(count4017==6) if( DirectInput.m_Sw[DIK_F2] ) data |= 0x02; + if(count4017==7) if( DirectInput.m_Sw[DIK_F1] ) data |= 0x02; + count4017++ ; + break; + case 10: + //??? + break; + case 11: + //??? + break; + case 12: + //??? + break; + } + + return data; +} + +void EXPAD_ZeCheng_Keyboard::Write4016( BYTE data ) +{ + +// DEBUGOUT( " Data=%d\n", data ); + + switch( data ) { + case 0: + tb = TRUE; + ScanNo = 0; + break; + case 3: + if ( !tb ) if( ++ScanNo>12 ) ScanNo = 0; + if ( tb ) count4017 = 0; + break; + case 5: + tb = FALSE; + ScanNo = 0; + break; + case 6: + if ( tb ) if( ++ScanNo>12 ) ScanNo = 0; + break; + case 7: + count4017 = 0; + break; + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ZeCheng_Keyboard.h b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ZeCheng_Keyboard.h new file mode 100644 index 00000000..c6a6fafc --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/PadEX/EXPAD_ZeCheng_Keyboard.h @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////// +// ZeCheng Keyboard // +// written by Temryu // +// last 2013/09/12 // +////////////////////////////////////////////////////////////////////////// + +class EXPAD_ZeCheng_Keyboard : public EXPAD +{ +public: + EXPAD_ZeCheng_Keyboard( NES* parent ) : EXPAD( parent ) {} + + void Reset(); + BYTE Read4017(); + void Write4016( BYTE data ); + +protected: + BOOL tb; + BYTE ScanNo; + BYTE count4017; +private: +}; diff --git a/References/VirtuaNESex_src_191105/NES/ROM.cpp b/References/VirtuaNESex_src_191105/NES/ROM.cpp new file mode 100644 index 00000000..58b55445 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ROM.cpp @@ -0,0 +1,719 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES ROM Cartridge class // +// Norix // +// written 2001/02/20 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" + +#include "DebugOut.h" +#include "App.h" +#include "Plugin.h" +#include "Pathlib.h" +#include "Crclib.h" + +#include "Archive.h" + +#include "rom.h" +#include "romdb.h" +#include "mmu.h" +#include "mapper.h" + +const char* img_fname; //for bbk + +BOOL g_bSan2; +unsigned char pFont[256*1024]; + +INT g_UnfTVMode = -1; +#define MKID(a) ((unsigned long) \ + (((a) >> 24) & 0x000000FF) | \ + (((a) >> 8) & 0x0000FF00) | \ + (((a) << 8) & 0x00FF0000) | \ + (((a) << 24) & 0xFF000000)) + +// +// RXgN^ +// +ROM::ROM( const char* fname ) +{ +FILE *fp = NULL; +LPBYTE temp = NULL; +LPBYTE bios = NULL; +LONG FileSize; + + g_bSan2 = FALSE; + + ZEROMEMORY( &header, sizeof(header) ); + ZEROMEMORY( path, sizeof(path) ); + ZEROMEMORY( name, sizeof(name) ); + + bPAL = FALSE; + bNSF = FALSE; + NSF_PAGE_SIZE = 0; + + board = 0; + bUnif = FALSE; + g_UnfTVMode = -1; + + lpPRG = lpCHR = lpTrainer = lpDiskBios = lpDisk = NULL; + + crc = crcall = 0; + mapper = 0; + diskno = 0; + + try { + +//for bbk------------------------------------------------------------------------- + if( !(fp = ::fopen( fname, "rb" )) ) { + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + ::fseek( fp, 0, SEEK_END ); + FileSize = ::ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + if( !(temp = (LPBYTE)::malloc( FileSize )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + if( ::fread( temp, FileSize, 1, fp ) != 1 ) { + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + FCLOSE( fp ); + ::memcpy( &header, temp, sizeof(NESHEADER) ); + + if( header.ID[0] == 0xEB && header.ID[1] == 0x3C + && header.ID[2] == 0x90 && header.ID[3] == 0x53 ) { + img_fname = fname; +// DEBUGOUT( "img_fname: %s\n", img_fname ); + fname = "bbk_bios10.rom"; + } else { + FREE( temp ); + } +//-------------------------------------------------------------------------------- + + if( !(fp = ::fopen( fname, "rb" )) ) { + // xxx t@CJ܂ + LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); + ::wsprintf( szErrorString, szErrStr, fname ); + throw szErrorString; + } + // t@CTCY擾 + ::fseek( fp, 0, SEEK_END ); + FileSize = ::ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + // t@CTCY`FbN(NESwb_+1oCgȏォH) + if( FileSize < 17 ) { + // t@CTCY܂ + throw CApp::GetErrorString( IDS_ERROR_SMALLFILE ); + } + + // e|m + if( !(temp = (LPBYTE)::malloc( FileSize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + + // TCYǂݍ + if( ::fread( temp, FileSize, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + + FCLOSE( fp ); + + // wb_Rs[ + ::memcpy( &header, temp, sizeof(NESHEADER) ); + + header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old; + header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old; + + if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + // wb_Rs[ + memcpy( &header, temp, sizeof(NESHEADER) ); + header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old; + header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old; + } else if( header.ID[0] == 'F' && header.ID[1] == 'D' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + // wb_Rs[ + memcpy( &header, temp, sizeof(NESHEADER) ); + header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old; + header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old; + } else if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 'M') { + // wb_Rs[ + memcpy( &header, temp, sizeof(NESHEADER) ); + header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old; + header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old; + } else if( header.ID[0] == 'U' && header.ID[1] == 'N' + && header.ID[2] == 'I' && header.ID[3] == 'F') { + //Unif ROM + } else { + FREE( temp ); + + if( !UnCompress( fname, &temp, (LPDWORD)&FileSize ) ) { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + // wb_Rs[ + ::memcpy( &header, temp, sizeof(NESHEADER) ); + header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old; + header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old; + } + + DWORD PRGoffset, CHRoffset; + LONG PRGsize, CHRsize; + BYTE *pUnif = temp; + DWORD filesize = FileSize; + + if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + // ʂNESt@C + PRGsize = (LONG)header.PRG_PAGE_SIZE*0x4000; + CHRsize = (LONG)header.CHR_PAGE_SIZE*0x2000; + PRGoffset = sizeof(NESHEADER); + CHRoffset = PRGoffset + PRGsize; + + //for Game Star - Smart Genius (Unl) + if(header.PRG_PAGE_SIZE==0xff) + PRGsize = (LONG)(header.PRG_PAGE_SIZE+1)*0x4000; + + if( IsTRAINER() ) { + PRGoffset += 512; + CHRoffset += 512; + } + + if( PRGsize <= 0 || (PRGsize+CHRsize) > FileSize ) { + // NESwb_ُł + throw CApp::GetErrorString( IDS_ERROR_INVALIDNESHEADER ); + } + + // PRG BANK + if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + + ::memcpy( lpPRG, temp+PRGoffset, PRGsize ); + + // CHR BANK + if( CHRsize > 0 ) { + if( !(lpCHR = (LPBYTE)malloc( CHRsize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + + if( FileSize >= CHRoffset+CHRsize ) { + memcpy( lpCHR, temp+CHRoffset, CHRsize ); + } else { + // CHRoNȂc + CHRsize -= (CHRoffset+CHRsize - FileSize); + memcpy( lpCHR, temp+CHRoffset, CHRsize ); + } + } else { + lpCHR = NULL; + } + + // Trainer + if( IsTRAINER() ) { + if( !(lpTrainer = (LPBYTE)malloc( 512 )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + + memcpy( lpTrainer, temp+sizeof(NESHEADER), 512 ); + } else { + lpTrainer = NULL; + } + + } else if( header.ID[0] == 'U' && header.ID[1] == 'N' + && header.ID[2] == 'I' && header.ID[3] == 'F' ) { + + DWORD Signature, BlockLen; + DWORD ipos =0x20;//UNIFͷ + BYTE id,i; + BYTE *tPRG[0x10], *tCHR[0x10]; + DWORD sizePRG[0x10],sizeCHR[0x10]; + //char info[100]; + //char name[100]; + PRGsize = 0x00; + CHRsize = 0x00; + + header.ID[0] = 'N'; + header.ID[1] = 'E'; + header.ID[2] = 'S'; + header.ID[3] = 0x1A; + + board = 0; + bUnif = TRUE; + + + // header.PRG_PAGE_SIZE = (BYTE)diskno*4; + // header.CHR_PAGE_SIZE = 0; + // header.control1 = 0x40; + // header.control2 = 0x10; + header.control1 = 0; + header.control2 = 0; + + for (i = 0; i < 0x10; i++) + { + tPRG[i] = tCHR[i] = 0; + } + + //filesize + while(ipos65536?65536:BlockLen ); + memcpy( pFont, &pUnif[ipos], BlockLen ); + ipos+=BlockLen; break; + + case MKID('MIRR'): + if (pUnif[ipos]==0) + header.control1 &=14; + else if (pUnif[ipos]==1) + header.control1 |=1; + ipos+=BlockLen; + break; + + case MKID('PRGF'): id++; + case MKID('PRGE'): id++; + case MKID('PRGD'): id++; + case MKID('PRGC'): id++; + case MKID('PRGB'): id++; + case MKID('PRGA'): id++; + case MKID('PRG9'): id++; + case MKID('PRG8'): id++; + case MKID('PRG7'): id++; + case MKID('PRG6'): id++; + case MKID('PRG5'): id++; + case MKID('PRG4'): id++; + case MKID('PRG3'): id++; + case MKID('PRG2'): id++; + case MKID('PRG1'): id++; + case MKID('PRG0'): + sizePRG[id] = BlockLen; + tPRG[id] = (BYTE*)malloc(BlockLen); + memcpy( tPRG[id], &pUnif[ipos], BlockLen ); + ipos+=BlockLen; + PRGsize += BlockLen; + break; + + case MKID('CHRF'): id++; + case MKID('CHRE'): id++; + case MKID('CHRD'): id++; + case MKID('CHRC'): id++; + case MKID('CHRB'): id++; + case MKID('CHRA'): id++; + case MKID('CHR9'): id++; + case MKID('CHR8'): id++; + case MKID('CHR7'): id++; + case MKID('CHR6'): id++; + case MKID('CHR5'): id++; + case MKID('CHR4'): id++; + case MKID('CHR3'): id++; + case MKID('CHR2'): id++; + case MKID('CHR1'): id++; + case MKID('CHR0'): + sizeCHR[id] = BlockLen; + tCHR[id] = (BYTE*)malloc(BlockLen); + memcpy( tCHR[id], &pUnif[ipos], BlockLen ); + ipos+=BlockLen; + CHRsize += BlockLen; + break; + + default: + ipos+=BlockLen; break; + } + } + + //fl.mapper = 0; + //fl.prg_size = 0; + //fl.chr_size = 0; + + board = NES_ROM_get_unifBoardID(pboardname); + + header.PRG_PAGE_SIZE = PRGsize/(16*1024); + header.CHR_PAGE_SIZE = CHRsize/(8*1024); + + DWORD LenPRG=0,LenCHR=0; + if(PRGsize) + lpPRG = (LPBYTE)malloc( PRGsize ); + if(CHRsize) + lpCHR = (LPBYTE)malloc( CHRsize ); + + for (i = 0; i < 16; i++) + { + if (tPRG[i]) + { + memcpy(&lpPRG[LenPRG], tPRG[i], sizePRG[i]); + LenPRG += sizePRG[i]; + //fl.prg_size += sizePRG[i]>>14; + //PRGsize = PRGsize+LenPRG; + free(tPRG[i]); + } + if (tCHR[i]) + { + memcpy(&lpCHR[LenCHR], tCHR[i], sizeCHR[i]); + LenCHR += sizeCHR[i]; + //fl.chr_size = (fl.chr_size)+(sizeCHR[i]>>13); + //CHRsize = CHRsize+LenCHR; + free(tCHR[i]); + } + } + + } else if( header.ID[0] == 'F' && header.ID[1] == 'D' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + // FDS(Nintendo Disk System) + // fBXNTCY + diskno = header.PRG_PAGE_SIZE; + + if( FileSize < (16+65500*diskno) ) { + // fBXNTCYُł + throw CApp::GetErrorString( IDS_ERROR_ILLEGALDISKSIZE ); + } + if( diskno > 4 ) { + // 4ʂ葽fBXN͑ΉĂ܂ + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTDISK ); + } + + ZEROMEMORY( &header, sizeof(NESHEADER) ); + + // _~[wb_ + header.ID[0] = 'N'; + header.ID[1] = 'E'; + header.ID[2] = 'S'; + header.ID[3] = 0x1A; + header.PRG_PAGE_SIZE = (BYTE)diskno*4; + header.CHR_PAGE_SIZE = 0; + header.control1 = 0x40; + header.control2 = 0x10; + + PRGsize = sizeof(NESHEADER)+65500*(LONG)diskno; + // PRG BANK + if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + // f[^̃obNAbvp + if( !(lpDisk = (LPBYTE)malloc( PRGsize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + // CHR BANK + lpCHR = NULL; + + ::memcpy( lpPRG, &header, sizeof(NESHEADER) ); + ::memcpy( lpPRG+sizeof(NESHEADER), temp+sizeof(NESHEADER), 65500*(LONG)diskno ); + // f[^̏ꏊp + ZEROMEMORY( lpDisk, PRGsize ); +// memcpy( lpDisk, &header, sizeof(NESHEADER) ); +// memcpy( lpDisk+sizeof(NESHEADER), temp+sizeof(NESHEADER), PRGsize-sizeof(NESHEADER) ); + + lpPRG[0] = 'F'; + lpPRG[1] = 'D'; + lpPRG[2] = 'S'; + lpPRG[3] = 0x1A; + lpPRG[4] = (BYTE)diskno; + + // DISKSYSTEM BIOS̃[h + string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "DISKSYS", "ROM" ); + + if( !(fp = fopen( Path.c_str(), "rb" )) ) { + // DISKSYS.ROM܂ + throw CApp::GetErrorString( IDS_ERROR_NODISKBIOS ); + } + + ::fseek( fp, 0, SEEK_END ); + FileSize = ::ftell( fp ); + ::fseek( fp, 0, SEEK_SET ); + if( FileSize < 17 ) { + // t@CTCY܂ + throw CApp::GetErrorString( IDS_ERROR_SMALLFILE ); + } + if( !(bios = (LPBYTE)malloc( FileSize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + if( fread( bios, FileSize, 1, fp ) != 1 ) { + // t@C̓ǂݍ݂Ɏs܂ + throw CApp::GetErrorString( IDS_ERROR_READ ); + } + FCLOSE( fp ); + + if( !(lpDiskBios = (LPBYTE)malloc( 8*1024 )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + + if( bios[0] == 'N' && bios[1] == 'E' && bios[2] == 'S' && bios[3] == 0x1A ) { + // NES`BIOS + ::memcpy( lpDiskBios, bios+0x6010, 8*1024 ); + } else { + // BIOS + ::memcpy( lpDiskBios, bios, 8*1024 ); + } + FREE( bios ); + } else if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 'M') { + // NSF + bNSF = TRUE; + ZEROMEMORY( &header, sizeof(NESHEADER) ); + + // wb_Rs[ + memcpy( &nsfheader, temp, sizeof(NSFHEADER) ); + + PRGsize = FileSize-sizeof(NSFHEADER); +//DEBUGOUT( "PRGSIZE:%d\n", PRGsize ); + PRGsize = (PRGsize+0x0FFF)&~0x0FFF; +//DEBUGOUT( "PRGSIZE:%d\n", PRGsize ); + if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) { + // mۏo܂ + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + throw szErrorString; + } + ZEROMEMORY( lpPRG, PRGsize ); + memcpy( lpPRG, temp+sizeof(NSFHEADER), FileSize-sizeof(NSFHEADER) ); + + NSF_PAGE_SIZE = PRGsize>>12; +//DEBUGOUT( "PAGESIZE:%d\n", NSF_PAGE_SIZE ); + } else { + // Ή`ł + throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT ); + } + + // pX/t@C擾 + { + string tempstr; + tempstr = CPathlib::SplitPath( fname ); + ::strcpy( path, tempstr.c_str() ); + tempstr = CPathlib::SplitFname( fname ); + ::strcpy( name, tempstr.c_str() ); + // IWit@C(tpX) + ::strcpy( fullpath, fname ); + } + + // }bpݒ + if( !bNSF ) { + mapper = (header.control1>>4)|(header.control2&0xF0); + crc = crcall = crcvrom = 0; + + if( mapper != 20 ) { + // PRG crčvZ(NesToyPRG CRCƓ) + if( IsTRAINER() ) { + crcall = CRC::CrcRev( 512+PRGsize+CHRsize, temp+sizeof(NESHEADER) ); + crc = CRC::CrcRev( 512+PRGsize, temp+sizeof(NESHEADER) ); + if( CHRsize ) + crcvrom = CRC::CrcRev( CHRsize, temp+PRGsize+512+sizeof(NESHEADER) ); + } else { + crcall = CRC::CrcRev( PRGsize+CHRsize, temp+sizeof(NESHEADER) ); + crc = CRC::CrcRev( PRGsize, temp+sizeof(NESHEADER) ); + if( CHRsize ) + crcvrom = CRC::CrcRev( CHRsize, temp+PRGsize+sizeof(NESHEADER) ); + } + + FilenameCheck( name ); + + romdatabase.HeaderCorrect( header, crcall, crc ); + +#include "ROM_Patch.cpp" + fdsmakerID = fdsgameID = 0; + } else { + crc = crcall = crcvrom = 0; + + fdsmakerID = lpPRG[0x1F]; + fdsgameID = (lpPRG[0x20]<<24)|(lpPRG[0x21]<<16)|(lpPRG[0x22]<<8)|(lpPRG[0x23]<<0); + } + + if(bUnif){ + mapper = board; + crc = CRC::CrcRev( PRGsize, lpPRG ); + if( CHRsize ) + crcvrom = CRC::CrcRev( CHRsize, lpCHR ); + } + + } else { + // NSF + mapper = 0x0100; // Private mapper + crc = crcall = crcvrom = 0; + fdsmakerID = fdsgameID = 0; + } + + FREE( temp ); + } catch( CHAR* str ) { + // 킩ĂG[ + FCLOSE( fp ); + FREE( temp ); + FREE( bios ); + + FREE( lpPRG ); + FREE( lpCHR ); + FREE( lpTrainer ); + FREE( lpDiskBios ); + FREE( lpDisk ); + + throw str; +#ifndef _DEBUG + } catch(...) { + // ʕیG[Ƃô...(^^; + FCLOSE( fp ); + FREE( temp ); + FREE( bios ); + + FREE( lpPRG ); + FREE( lpCHR ); + FREE( lpTrainer ); + FREE( lpDiskBios ); + FREE( lpDisk ); + +#ifdef _DATATRACE + // For dis... + FREE( PROM_ACCESS ); +#endif + + // sȃG[܂ + throw CApp::GetErrorString( IDS_ERROR_UNKNOWN ); +#endif // !_DEBUG + } + +} + +// +// fXgN^ +// +ROM::~ROM() +{ + FREE( lpPRG ); + FREE( lpCHR ); + FREE( lpTrainer ); + FREE( lpDiskBios ); + FREE( lpDisk ); +} + +// +// ROMt@C`FbN +// +INT ROM::IsRomFile( const char* fname ) +{ +FILE* fp = NULL; +NESHEADER header; + + if( !(fp = fopen( fname, "rb" )) ) + return IDS_ERROR_OPEN; + + // TCYǂݍ + if( fread( &header, sizeof(header), 1, fp ) != 1 ) { + FCLOSE( fp ); + return IDS_ERROR_READ; + } + FCLOSE( fp ); + + if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + for( INT i = 0; i < 4; i++ ) { + if( header.reserved[i] ) + return IDS_ERROR_ILLEGALHEADER; + } + return 0; + } else if( header.ID[0] == 'F' && header.ID[1] == 'D' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + return 0; + } else if( header.ID[0] == 'U' && header.ID[1] == 'N' + && header.ID[2] == 'I' && header.ID[3] == 'F' ) { + return 0; + } else if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 'M' ) { + return 0; + } else if( header.ID[0] == 0xEB && header.ID[1] == 0x3C //BBK + && header.ID[2] == 0x90 && header.ID[3] == 0x53 ) { + return 0; + } else { + LPBYTE temp = NULL; + LONG size; + if( !UnCompress( fname, &temp, (LPDWORD)&size ) ) + return IDS_ERROR_UNSUPPORTFORMAT; + + memcpy( &header, temp, sizeof(NESHEADER) ); + header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old; + header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old; + FREE( temp ); + if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + for( INT i = 0; i < 4; i++ ) { + if( header.reserved[i] ) + return IDS_ERROR_ILLEGALHEADER; + } + return 0; + } else if( header.ID[0] == 'U' && header.ID[1] == 'N' + && header.ID[2] == 'I' && header.ID[3] == 'F' ) { + return 0; + } else if( header.ID[0] == 'F' && header.ID[1] == 'D' + && header.ID[2] == 'S' && header.ID[3] == 0x1A ) { + return 0; + } else if( header.ID[0] == 'N' && header.ID[1] == 'E' + && header.ID[2] == 'S' && header.ID[3] == 'M') { + return 0; + } else if( header.ID[0] == 0xEB && header.ID[1] == 0x3C //BBK + && header.ID[2] == 0x90 && header.ID[3] == 0x53 ) { + return 0; + } + } + + return IDS_ERROR_UNSUPPORTFORMAT; +} + +// +// ROMt@C̃`FbN(PAL) +// +void ROM::FilenameCheck( const char* fname ) +{ + unsigned char* p = (unsigned char*)fname; + + while( *p != (unsigned char)'\0' ) { + if( *p == (unsigned char)'(' ) { + if( _mbsnbicmp( p, (unsigned char*)"(E)", 3 ) == 0 ) { + bPAL = TRUE; + return; + } + } + + p = _mbsinc(p); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/ROM.h b/References/VirtuaNESex_src_191105/NES/ROM.h new file mode 100644 index 00000000..a6202ab9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ROM.h @@ -0,0 +1,193 @@ +////////////////////////////////////////////////////////////////////////// +// // +// NES ROM Cartridge class // +// Norix // +// written 2001/02/20 // +// last modify ----/--/-- // +////////////////////////////////////////////////////////////////////////// +#ifndef __ROM_INCLUDED__ +#define __ROM_INCLUDED__ + +#pragma warning(disable:4786) +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#pragma pack( push, 1 ) + +extern const char* img_fname; //for bbk + +typedef struct tagNESHEADER { + BYTE ID[4]; + BYTE PRG_PAGE_SIZE_old; + BYTE CHR_PAGE_SIZE_old; + BYTE control1; + BYTE control2; + BYTE reserved[4]; + WORD PRG_PAGE_SIZE; + WORD CHR_PAGE_SIZE; +} NESHEADER; + +typedef struct tagNSFHEADER { + BYTE ID[5]; + BYTE Version; + BYTE TotalSong; + BYTE StartSong; + WORD LoadAddress; + WORD InitAddress; + WORD PlayAddress; + BYTE SongName[32]; + BYTE ArtistName[32]; + BYTE CopyrightName[32]; + WORD SpeedNTSC; + BYTE BankSwitch[8]; + WORD SpeedPAL; + BYTE NTSC_PALbits; + BYTE ExtraChipSelect; + BYTE Expansion[4]; // must be 0 +} NSFHEADER; + +#pragma pack( pop ) + +class ROM +{ +public: + ROM( const char* fname ); + virtual ~ROM(); + + // ROM control byte #1 + enum { ROM_VMIRROR = 0x01, ROM_SAVERAM = 0x02, + ROM_TRAINER = 0x04, ROM_4SCREEN = 0x08 }; + + // ROM control byte #2 + enum { ROM_VSUNISYSTEM = 0x01 }; + + // Get NESHEADER + NESHEADER* GetNesHeader() { return &header; } + // Get NSFHEADER + NSFHEADER* GetNsfHeader() { return &nsfheader; } + + // Get ROM buffer pointer + LPBYTE GetPROM() { return lpPRG; } + LPBYTE GetVROM() { return lpCHR; } + LPBYTE GetTRAINER() { return lpTrainer; } + LPBYTE GetDISKBIOS() { return lpDiskBios; } + LPBYTE GetDISK() { return lpDisk; } + + // Get ROM size + INT GetPROM_SIZE() { return header.PRG_PAGE_SIZE; } + INT GetVROM_SIZE() { return header.CHR_PAGE_SIZE; } + + // Get PROM + DWORD GetPROM_CRC() { return crc; } + DWORD GetROM_CRC() { return crcall; } + DWORD GetVROM_CRC() { return crcvrom; } + + // Get FDS ID + DWORD GetMakerID() { return fdsmakerID; } + DWORD GetGameID() { return fdsgameID; } + + // ROM control + BOOL IsVMIRROR() { return header.control1 & ROM_VMIRROR; } + BOOL Is4SCREEN() { return header.control1 & ROM_4SCREEN; } + BOOL IsSAVERAM() { return header.control1 & ROM_SAVERAM; } + BOOL IsTRAINER() { return header.control1 & ROM_TRAINER; } + BOOL IsVSUNISYSTEM() { return header.control2 & ROM_VSUNISYSTEM; } + BOOL IsPAL() { return bPAL; } + + // Mapper + INT GetMapperNo() { return mapper; } + BOOL IsUnifMapper(){ return bUnif;} + INT GetUnifBoard(){return board;} + CHAR * GetBoardName(){return pboardname;} + + // Disks + INT GetDiskNo() { return diskno; } + + // NSF + BOOL IsNSF() { return bNSF; } + INT GetNSF_SIZE() { return NSF_PAGE_SIZE; } + + // ROM Paths + const char* GetRomPath() { return path; } + const char* GetRomName() { return name; } + const char* GetFullPathName() { return fullpath; } + + // File check + // 0:ERROR 1:HEADER OK -1:BAD HEADER + static INT IsRomFile( const char* fname ); + +protected: + NESHEADER header; + NSFHEADER nsfheader; + LPBYTE lpPRG; + LPBYTE lpCHR; + LPBYTE lpTrainer; + LPBYTE lpDiskBios; + LPBYTE lpDisk; + + // PROM CRC + DWORD crc; + DWORD crcall; + DWORD crcvrom; + + DWORD fdsmakerID, fdsgameID; + + INT mapper; + INT diskno; + INT board; + BOOL bUnif; + CHAR pboardname[MAX_PATH]; + + // For PAL(Database) + BOOL bPAL; + + // For NSF + BOOL bNSF; + INT NSF_PAGE_SIZE; + + CHAR path[_MAX_PATH]; + CHAR name[_MAX_FNAME]; + CHAR fullpath[_MAX_PATH]; + + // + void FilenameCheck( const char* fname ); +private: +}; + +/* + A. iNES Format (.NES) + --------------------- + +--------+------+------------------------------------------+ + | Offset | Size | Content(s) | + +--------+------+------------------------------------------+ + | 0 | 3 | 'NES' | + | 3 | 1 | $1A | + | 4 | 1 | 16K PRG-ROM page count | + | 5 | 1 | 8K CHR-ROM page count | + | 6 | 1 | ROM Control Byte #1 | + | | | %####vTsM | + | | | | ||||+- 0=Horizontal mirroring | + | | | | |||| 1=Vertical mirroring | + | | | | |||+-- 1=SRAM enabled | + | | | | ||+--- 1=512-byte trainer present | + | | | | |+---- 1=Four-screen mirroring | + | | | | | | + | | | +--+----- Mapper # (lower 4-bits) | + | 7 | 1 | ROM Control Byte #2 | + | | | %####00PV | + | | | | | |+- 1=VS-Unisystem Images | + | | | | | +-- 1=PlayChoice10 Images | + | | | | | | + | | | +--+----- Mapper # (upper 4-bits) | + | 8-15 | 8 | $00 | + | 16-.. | | Actual 16K PRG-ROM pages (in linear | + | ... | | order). If a trainer exists, it precedes | + | ... | | the first PRG-ROM page. | + | ..-EOF | | CHR-ROM pages (in ascending order). | + +--------+------+------------------------------------------+ +*/ + +#endif // !__ROM_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ROMDB.cpp b/References/VirtuaNESex_src_191105/NES/ROMDB.cpp new file mode 100644 index 00000000..c3777091 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ROMDB.cpp @@ -0,0 +1,188 @@ +// +// NES ROMDB class +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +#include "typedef.h" +#include "macro.h" + +#include "DebugOut.h" +#include "App.h" +#include "Plugin.h" +#include "Pathlib.h" +#include "Crclib.h" + +#include "Archive.h" + +#include "romdb.h" + +ROMDATABASE romdatabase; + +// +// ROM DATABASE (NESToy&NNNesterJ database) +// +INT ROMDATABASE::HeaderCheck( NESHEADER& hdr, DWORD crcall, DWORD crc, ROMDB& data ) +{ + if( m_DataBaseList.empty() ) { + LoadDatabase(); + } + + if( m_DataBaseList.empty() ) + return -2; // f[^x[X + + map::iterator it = m_DataBaseList.find( crcall ); + + if( it == m_DataBaseList.end() ) + return -1; // f[^x[Xɖ + + data = (*it).second; + + // ꉞ`FbN + if( data.crcall == crcall || (data.crc == crc && data.crc) ) { + if( hdr.control1 == data.control1 && hdr.control2 == data.control2 ) { + return 0; // SK + } + } + return 1; // CRC͈vwb_Ⴄ +} + +BOOL ROMDATABASE::HeaderCorrect( NESHEADER& hdr, DWORD crcall, DWORD crc ) +{ + if( m_DataBaseList.empty() ) { + LoadDatabase(); + } + + if( m_DataBaseList.empty() ) + return FALSE; // f[^x[X + + map::iterator it = m_DataBaseList.find( crcall ); + + if( it == m_DataBaseList.end() ) + return FALSE; // f[^x[Xɖ + + ROMDB data = (*it).second; + + // ꉞ`FbN + if( data.crcall == crcall || (data.crc == crc && data.crc) ) { + hdr.control1 = data.control1; + hdr.control2 = data.control2; + for( INT i = 0; i < 8; i++ ) { + hdr.reserved[i] = 0; + } + return TRUE; + } + return FALSE; +} + +void ROMDATABASE::LoadDatabase() +{ +FILE* fp = NULL; +CHAR buf[512]; +const UCHAR seps[] = ";\n\0"; // Zp[^ +ROMDB db; + +DEBUGOUT( "Database loading...\n" ); + + string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "nesromdb", "dat" ); + +DEBUGOUT( "File:%s\n", Path.c_str() ); + + m_DataBaseList.clear(); + + if( (fp = fopen( Path.c_str(), "r" )) ) { + while( fgets( buf, 512, fp ) ) { + if( buf[0] == ';' ) { // RgtB[hƂ݂Ȃ + continue; + } + + CHAR* pToken; + + // ALL CRC + if( !(pToken = (CHAR*)_mbstok( (UCHAR*)buf, seps )) ) + continue; + db.crcall = strtoul( pToken, NULL, 16 ); + // PRG CRC + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.crc = strtoul( pToken, NULL, 16 ); + + // Title + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.title = pToken; + + // Control 1 + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.control1 = atoi( pToken ); + // Control 2 + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.control2 = atoi( pToken ); + + // PRG SIZE + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.prg_size = atoi( pToken ); + // CHR SIZE + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.chr_size = atoi( pToken ); + + // Country + if( !(pToken = (CHAR*)_mbstok( NULL, seps )) ) + continue; + db.country = pToken; + + db.bNTSC = TRUE; + // Europe (PAL???) + if( strcmp( pToken, "E" ) == 0 + || strcmp( pToken, "Fra" ) == 0 + || strcmp( pToken, "Ger" ) == 0 + || strcmp( pToken, "Spa" ) == 0 + || strcmp( pToken, "Swe" ) == 0 + || strcmp( pToken, "Ita" ) == 0 + || strcmp( pToken, "Aus" ) == 0 ) { + db.bNTSC = FALSE; + } + + // Manufacturer + if( pToken = (CHAR*)_mbstok( NULL, seps ) ) { + db.manufacturer = pToken; + } else { + db.manufacturer.erase( db.manufacturer.begin(), db.manufacturer.end() ); + } + + // Sale date + if( pToken = (CHAR*)_mbstok( NULL, seps ) ) { + db.saledate = pToken; + } else { + db.saledate.erase( db.saledate.begin(), db.saledate.end() ); + } + + // Price + if( pToken = (CHAR*)_mbstok( NULL, seps ) ) { + db.price = pToken; + } else { + db.price.erase( db.price.begin(), db.price.end() ); + } + + // Genre + if( pToken = (CHAR*)_mbstok( NULL, seps ) ) { + db.genre = pToken; + } else { + db.genre.erase( db.genre.begin(), db.genre.end() ); + } + + m_DataBaseList[db.crcall] = db; + } + FCLOSE( fp ); + } else { +DEBUGOUT( "Database file not found.\n" ); + } +} + diff --git a/References/VirtuaNESex_src_191105/NES/ROMDB.h b/References/VirtuaNESex_src_191105/NES/ROMDB.h new file mode 100644 index 00000000..71aacdd1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ROMDB.h @@ -0,0 +1,67 @@ +// +// NES ROMDB class +// +#ifndef __ROMDB_INCLUDED__ +#define __ROMDB_INCLUDED__ + +#pragma warning(disable:4786) +#include +#include +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#include "rom.h" + +// +// ROM DATABASE (NESToy&NNNesterJ database) +// +class ROMDB +{ +public: + DWORD crcall; // ALL CRC + DWORD crc; // PRG CRC + + BYTE control1; + BYTE control2; + INT prg_size; + INT chr_size; + + string title; + string country; + string manufacturer; + string saledate; + string price; + string genre; + + BOOL bNTSC; // NTSC:TRUE PAL:FALSE +}; + +class ROMDBCMP +{ +public: + bool operator()( const DWORD& x, const DWORD& y ) const + { + return x < y; + } +}; + +class ROMDATABASE +{ +public: + INT HeaderCheck ( NESHEADER& hdr, DWORD crcall, DWORD crc, ROMDB& data ); + BOOL HeaderCorrect( NESHEADER& hdr, DWORD crcall, DWORD crc ); + +protected: + void LoadDatabase(); + + map m_DataBaseList; + +private: +}; + +extern ROMDATABASE romdatabase; + +#endif // !__ROMDB_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/ROM_Patch.cpp b/References/VirtuaNESex_src_191105/NES/ROM_Patch.cpp new file mode 100644 index 00000000..833c5187 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/ROM_Patch.cpp @@ -0,0 +1,349 @@ +// +// ROMwb_̏C(NESToył̊ԈႢCȂ)yROMpb` +// + +// Mapper 000 +if( crc == 0x57970078 ) { // F-1 Race(J) pb`(^^; + lpPRG[0x078C] = 0x6C; + lpPRG[0x3FE1] = 0xFF; + lpPRG[0x3FE6] = 0x00; +} +if( crc == 0xaf2bbcbc // Mach Rider(JU) + || crc == 0x3acd4bf1 // Mach Rider(Alt)(JU) pb`(^^; + || crc == 0x8bbe9bec ) { + lpPRG[0x090D] = 0x6E; + lpPRG[0x7FDF] = 0xFF; + lpPRG[0x7FE4] = 0x00; + + header.control1 = ROM_VMIRROR; +} + +if( crc == 0xe16bb5fe ) { // Zippy Race(J) + header.control1 &= 0xf6; +} +if( crc == 0x85534474 ) { // Lode Runner(J) + lpPRG[0x29E9] = 0xEA; // Z[uj[opb` + lpPRG[0x29EA] = 0xEA; + lpPRG[0x29F8] = 0xEA; + lpPRG[0x29F9] = 0xEA; +} + +// Mapper 001 +if( crc == 0x7831b2ff // America Daitouryou Senkyo(J) + || crc == 0x190a3e11 // Be-Bop-Highschool - Koukousei Gokuraku Densetsu(J) + || crc == 0x52449508 // Home Run Nighter - Pennant League!!(J) + || crc == 0x0973f714 // Jangou(J) + || crc == 0x7172f3d4 // Kabushiki Doujou(J) + || crc == 0xa5781280 // Kujaku Ou 2(J) + || crc == 0x8ce9c87b // Money Game, The(J) + || crc == 0xec47296d // Morita Kazuo no Shougi(J) + || crc == 0xcee5857b // Ninjara Hoi!(J) + || crc == 0xe63d9193 // Tanigawa Kouji no Shougi Shinan 3(J) + || crc == 0xd54f5da9 // Tsuppari Wars(J) + || crc == 0x1e0c7ea3 ) { // AD&D Dragons of Flame(J) + header.control1 |= ROM_SAVERAM; +} +if( crc == 0x1995ac4e ) { // Ferrari Grand Prix Challenge(J) pb`(^^; + lpPRG[0x1F7AD] = 0xFF; + lpPRG[0x1F7BC] = 0x00; +} + +if( crc == 0x20d22251 ) { // Top rider(J) pb`(^^; + lpPRG[0x1F17E] = 0xEA; + lpPRG[0x1F17F] = 0xEA; +} + +if( crc == 0x11469ce3 ) { // Viva! Las Vegas(J) pb`(^^; + lpCHR[0x0000] = 0x01; +} + +if( crc == 0x3fccdc7b ) { // Baseball Star - Mezase Sankanou!!(J) pb`(^^; + lpPRG[0x0F666] = 0x9D; +} + +if( crc == 0xdb564628 ) { // Mario Open Golf(J) + lpPRG[0x30195] = 0xC0; +} + +// Mapper 002 +if( crc == 0x63af202f ) { // JJ - Tobidase Daisakusen Part 2(J) + header.control1 &= 0xf6; + header.control1 |= ROM_VMIRROR; +} + +if( crc == 0x99a62e47 ) { // Black Bass 2, The(J) + header.control1 &= 0xf6; + header.control1 |= ROM_VMIRROR; +} + +if( crc == 0x0eaa7515 // Rod Land(J) + || crc == 0x22ab9694 ) { // Rod Land(E) + header.control1 &= 0xf6; + header.control1 |= ROM_VMIRROR; +} + +// Mapper 003 +if( crc == 0x29401686 ) { // Minna no Taabou no Nakayoshi Dai Sakusen(J) +// lpPRG[0x2B3E] = 0x60; +} +if( crc == 0x932a077a ) { // TwinBee(J) + mapper = 87; +} +if( crc == 0x8218c637 ) { // Space Hunter(J) +// header.control1 &= 0xf6; +// header.control1 |= ROM_4SCREEN; + header.control1 = ROM_VMIRROR; +} +if( crc == 0x2bb6a0f8 // Sherlock Holmes - Hakushaku Reijou Yuukai Jiken(J) + || crc == 0x28c11d24 // Sukeban Deka 3(J) + || crc == 0x02863604 ) { // Sukeban Deka 3(J)(Alt) + header.control1 &= 0xf6; + header.control1 |= ROM_VMIRROR; +} + +// Mapper 004 +if( crc == 0x58581770) { // Rasaaru Ishii no Childs Quest(J) + header.control1 &= 0xf6; + header.control1 |= ROM_VMIRROR; +} +if( crc == 0xf3feb3ab // Kunio Kun no Jidaigeki Dayo Zenin Shuugou! (J) + || crc == 0xa524ae9b // Otaku no Seiza - An Adventure in the Otaku Galaxy (J) + || crc == 0x46dc6e57 // SD Gundam - Gachapon Senshi 2 - Capsule Senki (J) + || crc == 0x66b2dec7 // SD Gundam - Gachapon Senshi 3 - Eiyuu Senki (J) + || crc == 0x92b07fd9 // SD Gundam - Gachapon Senshi 4 - New Type Story (J) + || crc == 0x8ee6463a // SD Gundam - Gachapon Senshi 5 - Battle of Universal Century (J) + || crc == 0xaf754426 // Ultraman Club 3 (J) + || crc == 0xfe4e5b11 // Ushio to Tora - Shinen no Daiyou (J) + || crc == 0x57c12c17 ) { // Yamamura Misa Suspense - Kyouto Zaiteku Satsujin Jiken (J) + header.control1 |= ROM_SAVERAM; +} +if( crc == 0x42e03e4a ) { // RPG Jinsei Game (J) + mapper = 118; + header.control1 |= ROM_SAVERAM; +} +if( crc == 0xfd0299c3 ) { // METAL MAX(J) + lpPRG[0x3D522] = 0xA9; + lpPRG[0x3D523] = 0x19; +} +if( crc == 0x1d2e5018 // Rockman 3(J) + || crc == 0x6b999aaf ) { // Mega Man 3(U) +// lpPRG[0x3C179] = 0xBA; +} + +// Mapper 005 +if( crc == 0xe91548d8 ) { // Shin 4 Nin Uchi Mahjong - Yakuman Tengoku (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 010 +if( crc == 0xc9cce8f2 ) { // Famicom Wars (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 016 +if( crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament (J) + || crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi (J) + || crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai (J) + || crc == 0xbe06853f // Datach - J League Super Top Players (J) + || crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars (J) + || crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight! (J) + || crc == 0xf51a7f46 // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai (J) + || crc == 0x31cd9903 // Dragon Ball Z - Kyoushuu! Saiya Jin (J) + || crc == 0xe49fc53e // Dragon Ball Z 2 - Gekishin Freeza!! (J) + || crc == 0x09499f4d // Dragon Ball Z 3 - Ressen Jinzou Ningen (J) + || crc == 0x2e991109 // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J) + || crc == 0x170250de ) { // Rokudenashi Blues(J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 019 +if( crc == 0x3296ff7a // Battle Fleet (J) + || crc == 0x429fd177 // Famista '90 (J) + || crc == 0xdd454208 // Hydlide 3 - Yami Kara no Houmonsha (J) + || crc == 0xb1b9e187 // Kaijuu Monogatari (J) + || crc == 0xaf15338f ) { // Mindseeker (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 026 +if( crc == 0x836cc1ab ) { // Mouryou Senki Madara (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 033 +if( crc == 0x547e6cc1 ) { // Flintstones - The Rescue of Dino & Hoppy, The(J) + mapper = 48; +} + +// Mapper 065 +if( crc == 0xfd3fc292 ) { // Ai Sensei no Oshiete - Watashi no Hoshi (J) + mapper = 32; +} + +// Mapper 068 +if( crc == 0xfde79681 ) { // Maharaja (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 069 +if( crc == 0xfeac6916 // Honoo no Toukyuuji - Dodge Danpei 2(J) + || crc == 0x67898319 ) { // Barcode World(J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 080 +if( crc == 0x95aaed34 // Mirai Shinwa Jarvas (J) + || crc == 0x17627d4b ) { // Taito Grand Prix - Eikou heno License (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 082 +if( crc == 0x4819a595 ) { // Kyuukyoku Harikiri Stadium - Heisei Gannen Ban (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 086 +if( crc == 0xe63f7d0b ) { // Urusei Yatsura - Lum no Wedding Bell(J) + mapper = 101; +} + +// Mapper 118 +if( crc == 0x3b0fb600 ) { // Ys 3 - Wonderers From Ys (J) + header.control1 |= ROM_SAVERAM; +} + +// Mapper 180 +if( crc == 0xc68363f6 ) { // Crazy Climber(J) + header.control1 &= 0xf6; +} + +// VS-Unisystem +if( crc == 0x70901b25 ) { // VS Slalom + mapper = 99; +} + +if( crc == 0xd5d7eac4 ) { // VS Dr. Mario + mapper = 1; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0xffbef374 // VS Castlevania + || crc == 0x8c0c2df5 ) { // VS Top Gun + mapper = 2; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x98cfe016 // VS TKO Boxing (Alt) + || crc == 0x9818f656 ) { // VS TKO Boxing (f1) + mapper = 4; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0x135adf7c ) { // VS Atari RBI Baseball + mapper = 4; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious (b1) + || crc == 0x66bb838f ) { // VS Super Xevious (b2) + mapper = 4; + header.control1 &= 0xF6; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0x17ae56be ) { // VS Freedom Force + mapper = 4; + header.control1 &= 0xF6; + header.control1 |= ROM_4SCREEN; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0xe2c0a2be ) { // VS Platoon + mapper = 68; + header.control2 |= ROM_VSUNISYSTEM; +} + +if( crc == 0xcbe85490 // VS Excitebike + || crc == 0x29155e0c // VS Excitebike (Alt) + || crc == 0xff5135a3 ) { // VS Hogan's Alley + header.control1 &= 0xF6; + header.control1 |= ROM_4SCREEN; +} + +if( crc == 0x0b65a917 ) { // VS Mach Rider(Endurance Course) + lpPRG[0x7FDF] = 0xFF; + lpPRG[0x7FE4] = 0x00; +} + +if( crc == 0x8a6a9848 // VS Mach Rider(Endurance Course)(Alt) + || crc == 0xae8063ef ) { // VS Mach Rider(Japan, Fighting Course) + lpPRG[0x7FDD] = 0xFF; + lpPRG[0x7FE2] = 0x00; +} + +if( crc == 0x16d3f469 ) { // VS Ninja Jajamaru Kun (J) + header.control1 &= 0xf6; + header.control1 |= ROM_VMIRROR; +} + +if( crc == 0xc99ec059 ) { // VS Raid on Bungeling Bay(J) + mapper = 99; + header.control1 &= 0xF6; + header.control1 |= ROM_4SCREEN; +} +if( crc == 0xca85e56d ) { // VS Mighty Bomb Jack(J) + mapper = 99; + header.control1 &= 0xF6; + header.control1 |= ROM_4SCREEN; +} + + +if( crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x9818f656 // VS TKO Boxing + || crc == 0xed588f00 // VS Duck Hunt + || crc == 0x8c0c2df5 // VS Top Gun + || crc == 0x16d3f469 // VS Ninja Jajamaru Kun + || crc == 0x8850924b // VS Tetris + || crc == 0xcf36261e // VS Sky Kid + || crc == 0xe1aa8214 // VS Star Luster + || crc == 0xec461db9 // VS Pinball + || crc == 0xe528f651 // VS Pinball (alt) + || crc == 0x17ae56be // VS Freedom Force + || crc == 0xe2c0a2be // VS Platoon + || crc == 0xff5135a3 // VS Hogan's Alley + || crc == 0x70901b25 // VS Slalom + || crc == 0x0b65a917 // VS Mach Rider(Endurance Course) + || crc == 0x8a6a9848 // VS Mach Rider(Endurance Course)(Alt) + || crc == 0xae8063ef // VS Mach Rider(Japan, Fighting Course) + || crc == 0xcc2c4b5d // VS Golf + || crc == 0xa93a5aee // VS Stroke and Match Golf + || crc == 0x86167220 // VS Lady Golf + || crc == 0xffbef374 // VS Castlevania + || crc == 0x135adf7c // VS Atari RBI Baseball + || crc == 0xd5d7eac4 // VS Dr. Mario + || crc == 0x46914e3e // VS Soccer + || crc == 0x70433f2c // VS Battle City + || crc == 0x8d15a6e6 // VS bad .nes + || crc == 0x1e438d52 // VS Goonies + || crc == 0xcbe85490 // VS Excitebike + || crc == 0x29155e0c // VS Excitebike (alt) + || crc == 0x07138c06 // VS Clu Clu Land + || crc == 0x43a357ef // VS Ice Climber + || crc == 0x737dd1bf // VS Super Mario Bros + || crc == 0x4bf3972d // VS Super Mario Bros + || crc == 0x8b60cc58 // VS Super Mario Bros + || crc == 0x8192c804 // VS Super Mario Bros + || crc == 0xd99a2087 // VS Gradius + || crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious + || crc == 0x66bb838f // VS Super Xevious + || crc == 0xc99ec059 // VS Raid on Bungeling Bay(J) + || crc == 0xca85e56d ) { // VS Mighty Bomb Jack(J) + header.control2 |= ROM_VSUNISYSTEM; +} + +if( mapper == 99 || mapper == 151 ) { + header.control2 |= ROM_VSUNISYSTEM; +} diff --git a/References/VirtuaNESex_src_191105/NES/State.h b/References/VirtuaNESex_src_191105/NES/State.h new file mode 100644 index 00000000..0b28467a --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/State.h @@ -0,0 +1,300 @@ +#ifndef __STATE_INCLUDED__ +#define __STATE_INCLUDED__ + +#pragma pack( push, 1 ) + +typedef struct tagFILEHDR { // 0123456789AB + BYTE ID[12]; // "VirtuaNES ST" + WORD Reserved; + WORD BlockVersion; +} FILEHDR, *LPFILEHDR; + +// VirtuaNES version0.30ȍ~p +typedef struct tagFILEHDR2 { // 0123456789AB + BYTE ID[12]; // "VirtuaNES ST" + WORD Reserved; + WORD BlockVersion; // 0x0200 / 0x0210(v0.60ȍ~) + + DWORD Ext0; // ROM:vOCRC FDS:vOID + WORD Ext1; // ROM:Ȃ FDS:[J[ID + WORD Ext2; // ROM:Ȃ FDS:fBXN + LONG MovieStep; // NjL(蒼)[r[̃t[ + LONG MovieOffset; // NjL(蒼)[r[̃t@CItZbg +} FILEHDR2, *LPFILEHDR2; + +typedef struct tagBLOCKHDR { + BYTE ID[8]; + WORD Reserved; + WORD BlockVersion; + DWORD BlockSize; +} BLOCKHDR, *LPBLOCKHDR; + +// CPU WX^ +// version 0x0110܂ +typedef struct tagCPUSTAT_O { + WORD PC; + BYTE A; + BYTE X; + BYTE Y; + BYTE S; + BYTE P; + BYTE I; // Interrupt pending flag + + BYTE FrameIRQ; + BYTE reserved[3]; + + LONG mod_cycles; // [r[ŃNbN̔Ȃh + + // version 0x0110 + SQWORD emul_cycles; + SQWORD base_cycles; +} CPUSTAT_O, *LPCPUSTAT_O; + +// version 0x0210 +typedef struct tagCPUSTAT { + WORD PC; + BYTE A; + BYTE X; + BYTE Y; + BYTE S; + BYTE P; + BYTE I; // Interrupt pending flag + + BYTE FrameIRQ; + BYTE FrameIRQ_occur; + BYTE FrameIRQ_count; + BYTE FrameIRQ_type; + LONG FrameIRQ_cycles; + + LONG DMA_cycles; + + SQWORD emul_cycles; + SQWORD base_cycles; +} CPUSTAT, *LPCPUSTAT; + +// PPU WX^ +typedef struct tagPPUSTAT { + BYTE reg0; + BYTE reg1; + BYTE reg2; + BYTE reg3; + BYTE reg7; + BYTE toggle56; + + WORD loopy_t; + WORD loopy_v; + WORD loopy_x; +} PPUSTAT, *LPPPUSTAT; + +// APU WX^(gTEh܂) +typedef struct tagAPUSTAT_O { + BYTE reg[0x0018]; + BYTE ext[0x0100]; +} APUSTAT_O, *LPAPUSTAT_O; + +// Rg[WX^ +typedef struct tagCTRREG { + DWORD pad1bit; + DWORD pad2bit; + DWORD pad3bit; + DWORD pad4bit; + BYTE strobe; +} CTRREG, *LPCTRREG; + +// +// WX^f[^ +// ID "REG DATA" +// ver 0x0110܂ +typedef struct tagREGSTAT_O { + union uniCPUREG { + BYTE cpudata[32]; + CPUSTAT_O cpu; + } cpureg; + union uniPPUREG { + BYTE ppudata[32]; + PPUSTAT ppu; + } ppureg; + APUSTAT_O apu; +} REGSTAT_O, *LPREGSTAT_O; + +// ver 0x0200ȍ~ +typedef struct tagREGSTAT { + union uniCPUREG { + BYTE cpudata[64]; + CPUSTAT cpu; + } cpureg; + union uniPPUREG { + BYTE ppudata[32]; + PPUSTAT ppu; + } ppureg; +} REGSTAT, *LPREGSTAT; + + +// +// RAMf[^ +// ID "RAM DATA" +typedef struct tagRAMSTAT { + BYTE RAM[2*1024]; // Internal NES RAM + BYTE BGPAL[16]; // BG Palette + BYTE SPPAL[16]; // SP Palette + BYTE SPRAM[256]; // Sprite RAM +} RAMSTAT, *LPRAMSTAT; + +// +// MMUf[^ +// ID "MMU DATA" +typedef struct tagMMUSTAT { + BYTE CPU_MEM_TYPE[8]; + WORD CPU_MEM_PAGE[8]; + BYTE PPU_MEM_TYPE[12]; + WORD PPU_MEM_PAGE[12]; + BYTE CRAM_USED[8]; +} MMUSTAT, *LPMMUSTAT; + +// +// }bp[f[^ +// ID "MMC DATA" +typedef struct tagMMCSTAT { + BYTE mmcdata[256]; +} MMCSTAT, *LPMMCSTAT; + +// +// Rg[f[^ +// ID "CTR DATA" +typedef struct tagCTRSTAT { + union uniCTRDATA { + BYTE ctrdata[32]; + CTRREG ctr; + } ctrreg; +} CTRSTAT, *LPCTRSTAT; + +// +// SNDf[^ +// ID "SND DATA" +typedef struct tagSNDSTAT { + BYTE snddata[0x800]; // 2KB +} SNDSTAT, *LPSNDSTAT; + +// +// fBXNC[W +// Ver0.24܂ +// ID "DSIDE 0A","DSIDE 0B","DSIDE 1A","DSIDE 1B" +typedef struct tagDISKSTAT { + BYTE DiskTouch[16]; +} DISKSTAT, *LPDISKSTAT; + +// Ver0.30ȍ~ +// ID "DISKDATA" +typedef struct tagDISKDATA { + LONG DifferentSize; +} DISKDATA, *LPDISKDATA; + +// ȉ̓fBXNZ[uC[Wt@CŎgp +// Ver0.24܂ +typedef struct tagDISKIMGFILEHDR { // 0123456789AB + BYTE ID[12]; // "VirtuaNES DI" + WORD BlockVersion; + WORD DiskNumber; +} DISKIMGFILEHDR, *LPDISKIMGFILEHDR; + +typedef struct tagDISKIMGHDR { + BYTE ID[6]; // ID "SIDE0A","SIDE0B","SIDE1A","SIDE1B" + BYTE DiskTouch[16]; +} DISKIMGHDR, *LPDISKIMGHDR; + +// VirtuaNES version0.30ȍ~p +typedef struct tagDISKFILEHDR { // 0123456789AB + BYTE ID[12]; // "VirtuaNES DI" + WORD BlockVersion; // 0x0200:0.30 0x0210:0.31 + WORD Reserved; + DWORD ProgID; // vOID + WORD MakerID; // [J[ID + WORD DiskNo; // fBXN + DWORD DifferentSize; // ᐔ +} DISKFILEHDR, *LPDISKFILEHDR; + +// +// [r[t@C +// +// VirtuaNES version0.60ȍ~p +typedef struct tagMOVIEFILEHDR { + BYTE ID[12]; // "VirtuaNES MV" + WORD BlockVersion; // Movie version 0x0300 + WORD RecordVersion; // Record version + DWORD Control; // Rg[oCg + // 76543210(Bit) + // E---4321 + // | |||+-- 1Pf[^ + // | ||+--- 2Pf[^ + // | |+---- 3Pf[^ + // | +----- 4Pf[^ + // +--------- NjL֎~ + // ̑Rg[1P`4P(ǂłǂ)̕L[ + // SON̎ĈSoCgRg[pf[^ɂȂ + DWORD Ext0; // ROM:vOCRC FDS:vOID + WORD Ext1; // ROM:Ȃ FDS:[J[ID + WORD Ext2; // ROM:Ȃ FDS:fBXN + DWORD RecordTimes; // L^(蒼) + + BYTE RenderMethod; // _O + BYTE IRQtype; // IRQ^Cv + BYTE FrameIRQ; // FrameIRQ֎~ + BYTE VideoMode; // NTSC/PAL + + BYTE reserved2[8]; // \ + + LONG StateStOffset; // Movie start state offset + LONG StateEdOffset; // Movie end state offset + LONG MovieOffset; // Movie data offset + LONG MovieStep; // Movie steps(Frame) + + DWORD CRC; // ̃f[^CRC(C`Lh~) +} MOVIEFILEHDR, *LPMOVIEFILEHDR; + +// Famtasia Movie.... +typedef struct tagFMVHDR { + BYTE ID[4]; // "FMV^Z" + BYTE Control1; // R??????? 0:ZbgォL^H 1:rL^ + BYTE Control2; // OT?????? O:1P T:2P + DWORD Unknown1; + WORD RecordTimes; // L^-1 + DWORD Unknown2; + BYTE szEmulators[0x40]; // L^G~[^ + BYTE szTitle [0x40]; // ^Cg +} FMVHDR, *LPFMVHDR; + +// Nesticle Movie.... +typedef struct tagNMVHDR { + BYTE ExRAM[0x2000]; + BYTE S_RAM[0x0800]; + WORD PC; + BYTE A; + BYTE P; + BYTE X; + BYTE Y; + BYTE SP; + BYTE OAM[0x0100]; + BYTE VRAM[0x4000]; + BYTE Other[0xC9]; + DWORD ScanlineCycles; + DWORD VblankScanlines; + DWORD FrameScanlines; + DWORD VirtualFPS; +} NMVHDR, *LPNMVHDR; + +// }N +#define SETBYTE(p,v) { *p = (v); p++; } +#define SETWORD(p,v) { *(LPWORD)p = (v); p += sizeof(WORD); } +#define SETDWORD(p,v) { *(LPDWORD)p = (v); p += sizeof(DWORD); } +#define SETINT(p,v) { *(LPINT)p = (v); p += sizeof(INT); } +#define SETBLOCK(p,v,s) { memcpy( p, (v), s ); p += s; } + +#define GETBYTE(p,v) { (v) = *p; p++; } +#define GETWORD(p,v) { (v) = *(LPWORD)p; p += sizeof(WORD); } +#define GETDWORD(p,v) { (v) = *(LPDWORD)p; p += sizeof(DWORD); } +#define GETINT(p,v) { (v) = *(LPINT)p; p += sizeof(INT); } +#define GETBLOCK(p,v,s) { memcpy( (v), p, s ); p += s; } + +#pragma pack( pop ) + +#endif // !__STATE_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NES/VS_Setting.h b/References/VirtuaNESex_src_191105/NES/VS_Setting.h new file mode 100644 index 00000000..3e763ea6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/VS_Setting.h @@ -0,0 +1,144 @@ + { + switch( rom->GetPROM_CRC() ) { + case 0xeb2dba63: // VS TKO Boxing + case 0x9818f656: + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xed588f00: // VS Duck Hunt + pad->SetVSType( PAD::VS_TYPEZ ); + goto vsexit; + case 0x8c0c2df5: // VS Top Gun + ppu->SetVSSecurity( 0x1B ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0x16d3f469: // VS Ninja Jajamaru Kun (J) + ppu->SetVSSecurity( 0x1B ); + pad->SetVSType( PAD::VS_TYPE3 ); + goto vsexit; + case 0x8850924b: // VS Tetris + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0xcf36261e: // VS Sky Kid + pad->SetVSType( PAD::VS_TYPE3 ); + goto vsexit; + case 0xe1aa8214: // VS Star Luster + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xec461db9: // VS Pinball + ppu->SetVSColorMap( 0 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xe528f651: // VS Pinball (alt) + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0x17ae56be: // VS Freedom Force +// ppu->SetVSColorMap( 0 ); + ppu->SetVSColorMap( 4 ); + pad->SetVSType( PAD::VS_TYPEZ ); + goto vsexit; + case 0xe2c0a2be: // VS Platoon + ppu->SetVSColorMap( 0 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xff5135a3: // VS Hogan's Alley + ppu->SetVSColorMap( 0 ); + pad->SetVSType( PAD::VS_TYPEZ ); + goto vsexit; + case 0x70901b25: // VS Slalom + ppu->SetVSColorMap( 1 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0x0b65a917: // VS Mach Rider(Endurance Course) + case 0x8a6a9848: + ppu->SetVSColorMap( 1 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xae8063ef: // VS Mach Rider(Japan, Fighting Course) + ppu->SetVSColorMap( 0 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xcc2c4b5d: // VS Golf + ppu->SetVSColorMap( 1 ); +// pad->SetVSType( PAD::VS_TYPE0 ); + pad->SetVSType( PAD::VS_TYPE6 ); + goto vsexit; + case 0xa93a5aee: // VS Stroke and Match Golf + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0x86167220: // VS Lady Golf + ppu->SetVSColorMap( 1 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0xffbef374: // VS Castlevania + ppu->SetVSColorMap( 1 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0x135adf7c: // VS Atari RBI Baseball + ppu->SetVSColorMap( 2 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0xd5d7eac4: // VS Dr. Mario + ppu->SetVSColorMap( 2 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0x46914e3e: // VS Soccer + ppu->SetVSColorMap( 2 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0x70433f2c: // VS Battle City + case 0x8d15a6e6: // VS bad .nes + ppu->SetVSColorMap( 2 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0x1e438d52: // VS Goonies + ppu->SetVSColorMap( 2 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xcbe85490: // VS Excitebike + ppu->SetVSColorMap( 2 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0x29155e0c: // VS Excitebike (alt) + ppu->SetVSColorMap( 3 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0x07138c06: // VS Clu Clu Land + ppu->SetVSColorMap( 3 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0x43a357ef: // VS Ice Climber + ppu->SetVSColorMap( 3 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0x737dd1bf: // VS Super Mario Bros + case 0x4bf3972d: // VS Super Mario Bros + case 0x8b60cc58: // VS Super Mario Bros + case 0x8192c804: // VS Super Mario Bros + ppu->SetVSColorMap( 3 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + case 0xd99a2087: // VS Gradius + ppu->SetVSColorMap( 4 ); + pad->SetVSType( PAD::VS_TYPE1 ); + goto vsexit; + case 0xf9d3b0a3: // VS Super Xevious + case 0x9924980a: // VS Super Xevious + case 0x66bb838f: // VS Super Xevious + ppu->SetVSColorMap( 4 ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + + case 0xc99ec059: // VS Raid on Bungeling Bay(J) + ppu->SetVSColorMap( 1 ); + pad->SetVSType( PAD::VS_TYPE5 ); + goto vsexit; + case 0xca85e56d: // VS Mighty Bomb Jack(J) + ppu->SetVSSecurity( 0x3D ); + pad->SetVSType( PAD::VS_TYPE0 ); + goto vsexit; + + vsexit: + ppu->SetVSMode( TRUE ); + break; + } + } diff --git a/References/VirtuaNESex_src_191105/NES/VsUnisystem.cpp b/References/VirtuaNESex_src_191105/NES/VsUnisystem.cpp new file mode 100644 index 00000000..4946d447 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/VsUnisystem.cpp @@ -0,0 +1,1365 @@ +#include "VsUnisystem.h" + +// ftHgDIP-SW +VSDIPSWITCH vsdip_default[] = { +// Dipname mask&value + "Unknown", 0x0100, + "Off", 0x00, + "On", 0x01, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0200, + "Off", 0x00, + "On", 0x02, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0400, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS TKO Boxing +VSDIPSWITCH vsdip_tkoboxing[] = { +// Dipname mask&value + "Coin", 0x0300, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x01, + "2 Coins / 1 Credit", 0x02, + "3 Coins / 1 Credit", 0x03, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0400, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Color Palette", 0x2020, + "Normal", 0x20, + "Wrong", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Atari RBI Baseball +VSDIPSWITCH vsdip_rbibaseball[] = { +// Dipname mask&value + "Coin", 0x0300, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x01, + "2 Coins / 1 Credit", 0x02, + "3 Coins / 1 Credit", 0x03, + NULL, 0xFF, +// Dipname mask&value + "Max. 1p/in, 2p/in, Min", 0x0C0C, + "2, 1, 3", 0x04, + "2, 2, 4", 0x0C, + "3, 2, 6", 0x00, + "4, 3, 7", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x1000, + "Off", 0x10, + "On", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Color Palette", 0xE080, + "Normal", 0x80, + "Wrong 1", 0x00, + "Wrong 2", 0x40, + "Wrong 3", 0x20, + "Wrong 4", 0xC0, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Duck Hunt +VSDIPSWITCH vsdip_duckhunt[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "2 Coins / 1 Credit", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x1808, + "Easy", 0x00, + "Normal", 0x08, + "Hard", 0x10, + "Very Hard", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Missed par Game", 0x2000, + "3", 0x00, + "5", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Bonus Life", 0xC000, + "30000pts", 0x00, + "50000pts", 0x40, + "80000pts", 0x80, + "100000pts", 0xC0, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Ninja Jajamaru Kun (J) +VSDIPSWITCH vsdip_jajamaru[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x1800, + "3", 0x00, + "4", 0x10, + "5", 0x08, + "6", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x8080, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Tetris +VSDIPSWITCH vsdip_tetris[] = { +// Dipname mask&value + "Coin", 0x0300, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x02, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x03, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x0C08, + "Easy", 0x00, + "Normal", 0x04, + "Hard", 0x08, + "Very Hard", 0x0C, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Color Palette", 0x6060, + "Normal", 0x60, + "Wrong 1", 0x20, + "Wrong 2", 0x40, + "Wrong 3", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Top Gun +VSDIPSWITCH vsdip_topgun[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "2 Coins / 1 Credit", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives par Coin", 0x0800, + "3 - 12 Max", 0x00, + "2 - 9 Max", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Bonus", 0x3000, + "30k and every 50k", 0x00, + "50k and every 100k", 0x20, + "100k and every 150k", 0x10, + "200k and every 200k", 0x30, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x4000, + "Normal", 0x00, + "Hard", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x8080, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Slalom +VSDIPSWITCH vsdip_slalom[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "2 Coins / 1 Credit", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Freestyle Points", 0x0800, + "Left / Right", 0x00, + "Hold Time", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x3010, + "Easy", 0x00, + "Normal", 0x10, + "Hard", 0x20, + "Hardest", 0x30, + NULL, 0xFF, +// Dipname mask&value + "Allow Continue", 0x4000, + "No", 0x40, + "Yes", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Inverted input", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Sky Kid +VSDIPSWITCH vsdip_skykid[] = { +// Dipname mask&value + "Unknown", 0x0100, + "Off", 0x00, + "On", 0x01, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0200, + "Off", 0x00, + "On", 0x02, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0404, + "2", 0x00, + "3", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Coin", 0x1800, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x08, + "2 Coins / 1 Credit", 0x10, + "3 Coins / 1 Credit", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Color Palette", 0xE020, + "Normal", 0x20, + "Wrong 1", 0x00, + "Wrong 2", 0x40, + "Wrong 3", 0x80, + "Wrong 4", 0xC0, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Star Luster +VSDIPSWITCH vsdip_starluster[] = { +// Dipname mask&value + "Coin", 0x0300, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x02, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x03, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0400, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Color Palette", 0x6000, + "Normal", 0x00, + "Wrong 1", 0x20, + "Wrong 2", 0x40, + "Wrong 3", 0x60, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Dr. Mario +VSDIPSWITCH vsdip_drmario[] = { +// Dipname mask&value + "Drop Rate Increases After", 0x0300, + "7 Pills", 0x00, + "8 Pills", 0x01, + "9 Pills", 0x02, + "10 Pills", 0x03, + NULL, 0xFF, +// Dipname mask&value + "Virus Level", 0x0C00, + "1", 0x00, + "3", 0x04, + "5", 0x08, + "7", 0x0C, + NULL, 0xFF, +// Dipname mask&value + "Drop Speed Up", 0x3000, + "Slow", 0x00, + "Midium", 0x10, + "Fast", 0x20, + "Fastest", 0x30, + NULL, 0xFF, +// Dipname mask&value + "Free Play", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x8080, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Castlevania +VSDIPSWITCH vsdip_castlevania[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "2 Coins / 1 Credit", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0808, + "2", 0x00, + "3", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Bonus", 0x3000, + "100k", 0x00, + "200k", 0x10, + "300k", 0x20, + "400k", 0x30, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x4000, + "Normal", 0x00, + "Hard", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Platoon +VSDIPSWITCH vsdip_platoon[] = { +// Dipname mask&value + "Unknown", 0x0100, + "Off", 0x00, + "On", 0x01, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0200, + "Off", 0x00, + "On", 0x02, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x0404, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Coin", 0xE000, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x20, + "1 Coin / 3 Credits", 0x40, + "2 Coins / 1 Credit", 0x60, + "3 Coins / 1 Credit", 0x80, + "4 Coins / 1 Credit", 0xA0, + "5 Coins / 1 Credit", 0xC0, + "Free Play", 0xE0, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Excitebike +VSDIPSWITCH vsdip_excitebike[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Bonus", 0x1800, + "100k and Every 50k", 0x00, + "Every 100k", 0x10, + "100k Only", 0x08, + "None", 0x18, + NULL, 0xFF, +// Dipname mask&value + "1st Half Qualifying Time", 0x2000, + "Normal", 0x00, + "Hard", 0x20, + NULL, 0xFF, +// Dipname mask&value + "2nd Half Qualifying Time", 0x4000, + "Normal", 0x00, + "Hard", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Clu Clu Land +VSDIPSWITCH vsdip_clucluland[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x6000, + "2", 0x60, + "3", 0x00, + "4", 0x40, + "5", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Ice Climber +VSDIPSWITCH vsdip_iceclimber[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x1800, + "3", 0x00, + "4", 0x10, + "5", 0x08, + "7", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x2000, + "Normal", 0x00, + "Hard", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Time before the bear", 0x4000, + "Long", 0x00, + "Short", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Super Mario Bros +VSDIPSWITCH vsdip_supermariobros[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x06, + "1 Coin / 3 Credits", 0x01, + "1 Coin / 4 Credits", 0x05, + "1 Coin / 5 Credits", 0x03, + "2 Coins / 1 Credit", 0x04, + "3 Coins / 1 Credit", 0x02, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0800, + "2", 0x08, + "3", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Bonus Life", 0x3000, + "100", 0x00, + "150", 0x20, + "200", 0x10, + "250", 0x30, + NULL, 0xFF, +// Dipname mask&value + "Timer", 0x4000, + "Normal", 0x00, + "Fast", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Continue Lives", 0x8000, + "3", 0x80, + "4", 0x00, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Pinball +VSDIPSWITCH vsdip_pinball[] = { +// Dipname mask&value + "Coin", 0x0701, + "1 Coin / 1 Credit", 0x01, + "1 Coin / 2 Credits", 0x06, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x04, + "2 Coins / 1 Credit", 0x05, + "3 Coins / 1 Credit", 0x03, + "4 Coins / 1 Credit", 0x07, + "Free Play", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Balls", 0x6000, + "2", 0x60, + "3", 0x00, + "4", 0x40, + "5", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Ball Speed", 0x8000, + "Normal", 0x00, + "Fast", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Mach Rider(Endurance Course) +VSDIPSWITCH vsdip_machrider[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Time", 0x1800, + "280", 0x00, + "250", 0x10, + "220", 0x08, + "200", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Mach Rider (Japan, Fighting Course) +VSDIPSWITCH vsdip_machriderj[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "1st Race Distance", 0x1000, + "12", 0x00, + "15", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Soccer +VSDIPSWITCH vsdip_soccer[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Points Timer", 0x1808, + "600pts", 0x00, + "800pts", 0x10, + "1000pts", 0x08, + "1200pts", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x6040, + "Easy", 0x00, + "Normal", 0x40, + "Hard", 0x20, + "Hardest", 0x60, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Battle City +VSDIPSWITCH vsdip_battlecity[] = { +// Dipname mask&value + "Credits for 2 Players", 0x0101, + "1", 0x00, + "2", 0x01, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0200, + "3", 0x00, + "5", 0x02, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x0404, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Color Palette", 0xC080, + "Normal", 0x80, + "Wrong 1", 0x00, + "Wrong 2", 0x40, + "Wrong 3", 0xC0, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Gradius +VSDIPSWITCH vsdip_gradius[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "2 Coins / 1 Credit", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0808, + "3", 0x08, + "4", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Bonus", 0x3000, + "100k", 0x00, + "200k", 0x20, + "300k", 0x10, + "400k", 0x30, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x4000, + "Normal", 0x00, + "Hard", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x8080, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Goonies +VSDIPSWITCH vsdip_goonies[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "2 Coins / 1 Credit", 0x06, + "3 Coins / 1 Credit", 0x01, + "4 Coins / 1 Credit", 0x05, + "5 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0800, + "3", 0x00, + "2", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Timer", 0x4000, + "Normal", 0x00, + "Fast", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Demo Sounds", 0x8080, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Hogan's Alley +VSDIPSWITCH vsdip_hogansalley[] = { +// Dipname mask&value + "Coin", 0x0700, + "5 Coins / 1 Credit", 0x03, + "4 Coins / 1 Credit", 0x05, + "3 Coins / 1 Credit", 0x01, + "2 Coins / 1 Credit", 0x06, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Difficulty", 0x1808, + "Easy", 0x00, + "Normal", 0x08, + "Hard", 0x10, + "Very Hard", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Misses par Game", 0x2000, + "3", 0x00, + "5", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Bonus Life", 0xC000, + "30000pts", 0x00, + "50000pts", 0x40, + "80000pts", 0x80, + "100000pts", 0xC0, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Freedom Force +VSDIPSWITCH vsdip_freedomforce[] = { +// Dipname mask&value + "Unknown", 0x0100, + "Off", 0x00, + "On", 0x01, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0200, + "Off", 0x00, + "On", 0x02, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0400, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Super Xevious +VSDIPSWITCH vsdip_superxevious[] = { +// Dipname mask&value + "Unknown", 0x0100, + "Off", 0x00, + "On", 0x01, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0200, + "Off", 0x00, + "On", 0x02, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0400, + "Off", 0x00, + "On", 0x04, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x0800, + "Off", 0x00, + "On", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Golf/Lady Golf +VSDIPSWITCH vsdip_golf[] = { +// Dipname mask&value + "Coin", 0x0701, + "1 Coin / 1 Credit", 0x01, + "1 Coin / 2 Credits", 0x06, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x04, + "2 Coins / 1 Credit", 0x05, + "3 Coins / 1 Credit", 0x03, + "4 Coins / 1 Credit", 0x07, + "Free Play", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Hole Size", 0x0800, + "Large", 0x00, + "Small", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Points par Stroke", 0x1000, + "Easier", 0x00, + "Harder", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Starting Points", 0x6000, + "10", 0x00, + "13", 0x40, + "16", 0x20, + "20", 0x60, + NULL, 0xFF, +// Dipname mask&value + "Difficulty Vs. Computer", 0x8000, + "Easy", 0x00, + "Hard", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Stroke and Match Golf +VSDIPSWITCH vsdip_strokandmatchegolf[] = { +// Dipname mask&value + "Coin", 0x0701, + "1 Coin / 1 Credit", 0x01, + "1 Coin / 2 Credits", 0x06, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x04, + "2 Coins / 1 Credit", 0x05, + "3 Coins / 1 Credit", 0x03, + "4 Coins / 1 Credit", 0x07, + "Free Play", 0x00, + NULL, 0xFF, +// Dipname mask&value + "Hole Size", 0x0800, + "Large", 0x00, + "Small", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Points par Stroke", 0x1000, + "Easier", 0x00, + "Harder", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Starting Points", 0x6000, + "300", 0x00, + "400", 0x40, + "500", 0x20, + "600", 0x60, + NULL, 0xFF, +// Dipname mask&value + "Difficulty Vs. Computer", 0x8000, + "Easy", 0x00, + "Hard", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Raid on Bungeling Bay(J) +VSDIPSWITCH vsdip_raidonbungelingbay[] = { +// Dipname mask&value + "Coin", 0x0700, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + "2 Coins / 1 Credit", 0x01, + "3 Coins / 1 Credit", 0x05, + "4 Coins / 1 Credit", 0x03, + "Free Play", 0x07, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x0808, + "2", 0x00, + "3", 0x08, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x1000, + "Off", 0x00, + "On", 0x10, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + +// VS Mighty Bomb Jack(J) +VSDIPSWITCH vsdip_mightybombjack[] = { +// Dipname mask&value + "Coin", 0x0700, + "5 Coins / 1 Credit", 0x07, + "4 Coins / 1 Credit", 0x03, + "3 Coins / 1 Credit", 0x05, + "2 Coins / 1 Credit", 0x01, + "1 Coin / 1 Credit", 0x00, + "1 Coin / 2 Credits", 0x04, + "1 Coin / 3 Credits", 0x02, + "1 Coin / 4 Credits", 0x06, + NULL, 0xFF, +// Dipname mask&value + "Lives", 0x1800, + "2", 0x10, + "3", 0x00, + "4", 0x08, + "5", 0x18, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x2000, + "Off", 0x00, + "On", 0x20, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x4000, + "Off", 0x00, + "On", 0x40, + NULL, 0xFF, +// Dipname mask&value + "Unknown", 0x8000, + "Off", 0x00, + "On", 0x80, + NULL, 0xFF, +// f~^ + NULL, 0, +}; + + +VSDIPSWITCH* FindVSDipSwitchTable( DWORD crc ) +{ +VSDIPSWITCH* dip = vsdip_default; + + switch( crc ) { + case 0xeb2dba63: // VS TKO Boxing + case 0x98cfe016: + case 0x9818f656: + dip = vsdip_tkoboxing; + break; + case 0xb90497aa: // VS Tennis + break; + case 0x8c0c2df5: // VS Top Gun + dip = vsdip_topgun; + break; + case 0x16d3f469: // VS Ninja Jajamaru Kun (J) + dip = vsdip_jajamaru; + break; + case 0x8850924b: // VS Tetris + dip = vsdip_tetris; + break; + case 0xcf36261e: // VS Sky Kid + dip = vsdip_skykid; + break; + case 0xe1aa8214: // VS Star Luster + dip = vsdip_starluster; + break; + case 0xec461db9: // VS Pinball + case 0xe528f651: // VS Pinball (alt) + dip = vsdip_pinball; + break; + case 0x17ae56be: // VS Freedom Force + dip = vsdip_freedomforce; + break; + case 0xe2c0a2be: // VS Platoon + dip = vsdip_platoon; + break; + case 0x70901b25: // VS Slalom + dip = vsdip_slalom; + break; + case 0x0b65a917: // VS Mach Rider(Endurance Course) + case 0x8a6a9848: + dip = vsdip_machrider; + break; + case 0xae8063ef: // VS Mach Rider(Japan, Fighting Course) + dip = vsdip_machriderj; + break; + case 0xffbef374: // VS Castlevania + dip = vsdip_castlevania; + break; + + case 0xcc2c4b5d: // VS Golf + case 0x86167220: // VS Lady Golf + dip = vsdip_golf; + break; + + case 0xa93a5aee: // VS Stroke and Match Golf + dip = vsdip_strokandmatchegolf; + break; + + case 0x135adf7c: // VS Atari RBI Baseball + dip = vsdip_rbibaseball; + break; + case 0xd5d7eac4: // VS Dr. Mario + dip = vsdip_drmario; + break; + case 0x46914e3e: // VS Soccer + dip = vsdip_soccer; + break; + case 0x70433f2c: // VS Battle City + case 0x8d15a6e6: // VS bad .nes + dip = vsdip_battlecity; + break; + case 0x1e438d52: // VS Goonies + dip = vsdip_goonies; + break; + + case 0xcbe85490: // VS Excitebike + case 0x29155e0c: // VS Excitebike (alt) + dip = vsdip_excitebike; + break; + + case 0x07138c06: // VS Clu Clu Land + dip = vsdip_clucluland; + break; + case 0x43a357ef: // VS Ice Climber + dip = vsdip_iceclimber; + break; + case 0x737dd1bf: // VS Super Mario Bros + case 0x4bf3972d: + case 0x8b60cc58: + case 0x8192c804: + dip = vsdip_supermariobros; + break; + + case 0xd99a2087: // VS Gradius + dip = vsdip_gradius; + break; + case 0xf9d3b0a3: // VS Super Xevious + case 0x9924980a: // VS Super Xevious + case 0x66bb838f: // VS Super Xevious + dip = vsdip_superxevious; + break; + + case 0xff5135a3: // VS Hogan's Alley + dip = vsdip_hogansalley; + break; + case 0xed588f00: // VS Duck Hunt + dip = vsdip_duckhunt; + break; + + case 0xc99ec059: // VS Raid on Bungeling Bay(J) + dip = vsdip_raidonbungelingbay; + break; + case 0xca85e56d: // VS Mighty Bomb Jack(J) + dip = vsdip_mightybombjack; + break; + } + + return dip; +} + +BYTE GetVSDefaultDipSwitchValue( DWORD crc ) +{ +VSDIPSWITCH* dip = FindVSDipSwitchTable( crc ); + + BYTE value = 0x00; + BYTE flag = 0; + for(;;) { + if( dip->name == NULL && dip->value == 0x0000 ) { + break; + } else if( dip->value == 0x00FF ) { + flag = 0; + } else if( !flag ) { + flag = 1; + value |= dip->value; + } + dip++; + } + + return value; +} + diff --git a/References/VirtuaNESex_src_191105/NES/VsUnisystem.h b/References/VirtuaNESex_src_191105/NES/VsUnisystem.h new file mode 100644 index 00000000..1988a6c4 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NES/VsUnisystem.h @@ -0,0 +1,22 @@ +#ifndef __VSUNISYSTEM_INCLUDED__ +#define __VSUNISYSTEM_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "typedef.h" + +struct VSDIPSWITCH +{ + char* name; + WORD value; +}; + +extern VSDIPSWITCH vsdip_default[]; + +extern VSDIPSWITCH* FindVSDipSwitchTable( DWORD crc ); +extern BYTE GetVSDefaultDipSwitchValue( DWORD crc ); + +#endif // !__VSUNISYSTEM_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NameTableView.cpp b/References/VirtuaNESex_src_191105/NameTableView.cpp new file mode 100644 index 00000000..73a484f9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NameTableView.cpp @@ -0,0 +1,180 @@ +// +// p^[r[NX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "NameTableView.h" +#include "EmuThread.h" + +#include "MMU.h" + +#include "DirectDraw.h" + +WND_MESSAGE_BEGIN(CNameTableView) +WND_ON_MESSAGE( WM_CREATE, OnCreate ) +WND_ON_MESSAGE( WM_CLOSE, OnClose ) +WND_ON_MESSAGE( WM_DESTROY, OnDestroy ) +WND_ON_MESSAGE( WM_TIMER, OnTimer ) + +WND_COMMAND_BEGIN() +WND_COMMAND_END() +WND_MESSAGE_END() + +CNameTableView::CNameTableView() +{ + m_lpPattern = NULL; + if( !(m_lpPattern = (LPBYTE)::malloc( 512*480 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } +} + +CNameTableView::~CNameTableView() +{ + FREE( m_lpPattern ); +} + +BOOL CNameTableView::Create( HWND hWndParent ) +{ + HWND hWnd = CreateWindowEx( + WS_EX_TOOLWINDOW, + VIRTUANES_WNDCLASS, + "NameTableView", + WS_OVERLAPPEDWINDOW, // Windowgk”\ + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, +// hWndParent, + HWND_DESKTOP, + NULL, + CApp::GetInstance(), + (LPVOID)this // This 𖄂ߍވ + ); + if( !hWnd ) { + DEBUGOUT( "CreateWindow faild.\n" ); + return FALSE; + } + + m_hWnd = hWnd; + + ZEROMEMORY( &m_BitmapHdr, sizeof(m_BitmapHdr) ); + + m_BitmapHdr.bih.biSize = sizeof(BITMAPINFOHEADER); + m_BitmapHdr.bih.biWidth = 512; + m_BitmapHdr.bih.biHeight = -480; + m_BitmapHdr.bih.biPlanes = 1; + m_BitmapHdr.bih.biBitCount = 8; + m_BitmapHdr.bih.biCompression = BI_RGB; + m_BitmapHdr.bih.biClrUsed = 16; + + DirectDraw.GetPaletteData( m_Palette ); + +// ::memcpy( &m_BitmapHdr.rgb[0], &m_BitmapHdr.rgb[64], 64*sizeof(RGBQUAD) ); +// m_BitmapHdr.rgb[1].rgbBlue = 0x60; +// m_BitmapHdr.rgb[1].rgbGreen = 0x60; +// m_BitmapHdr.rgb[1].rgbRed = 0x60; + + return TRUE; +} + +void CNameTableView::Destroy() +{ + if( m_hWnd && IsWindow(m_hWnd) ) { + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +WNDMSG CNameTableView::OnCreate( WNDMSGPARAM ) +{ + DEBUGOUT( "CNameTableView::OnCreate\n" ); + + RECT rw, rc; + ::GetWindowRect( m_hWnd, &rw ); + ::GetClientRect( m_hWnd, &rc ); + INT x = rw.right - rw.left - rc.right + 512; + INT y = rw.bottom - rw.top - rc.bottom + 480; + ::MoveWindow( m_hWnd, Config.general.rcNameTableViewPos.left, Config.general.rcNameTableViewPos.top, x, y, FALSE ); + + ::SetTimer( m_hWnd, 1, 50, NULL ); + + ::ShowWindow( m_hWnd, SW_SHOW ); + return TRUE; +} + +WNDMSG CNameTableView::OnClose( WNDMSGPARAM ) +{ + DEBUGOUT( "CNameTableView::OnClose\n" ); + ::KillTimer( m_hWnd, 1 ); + ::DestroyWindow( m_hWnd ); + return TRUE; +} + +WNDMSG CNameTableView::OnDestroy( WNDMSGPARAM ) +{ + DEBUGOUT( "CNameTableView::OnDestroy\n" ); + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcNameTableViewPos ); + + m_hWnd = NULL; + return TRUE; +} + +WNDMSG CNameTableView::OnTimer( WNDMSGPARAM ) +{ + if( !Emu.IsRunning() ) + return TRUE; + + // pbgXV + for( INT i = 0; i < 16; i++ ) { + m_BitmapHdr.rgb[i] = m_Palette[BGPAL[i]]; + } + + // LN^f[^XV + for( INT n = 0; n < 4; n++ ) { + LPBYTE lpVRAM = PPU_MEM_BANK[8+n]; + LPBYTE lpScnv = &m_lpPattern[(n>>1)*512*240+(n&1)*256]; + + for( INT y = 0; y < 30; y++ ) { + for( INT x = 0; x < 32; x++ ) { + INT tile = lpVRAM[x+y*32]*16+((PPUREG[0]&PPU_BGTBL_BIT)<<8); + BYTE attr = ((lpVRAM[0x03C0+(x/4)+(y>>2)*8]>>((x&2)+(y&2)*2))&3)<<2; + LPBYTE lpScn = &lpScnv[x*8+y*8*512]; + LPBYTE lpPtn = &PPU_MEM_BANK[tile>>10][tile&0x03FF]; + for( INT p = 0; p < 8; p++ ) { + BYTE chr_l = lpPtn[p]; + BYTE chr_h = lpPtn[p+8]; + lpScn[0] = ((chr_h>>6)&2)|((chr_l>>7)&1)|attr; + lpScn[4] = ((chr_h>>2)&2)|((chr_l>>3)&1)|attr; + lpScn[1] = ((chr_h>>5)&2)|((chr_l>>6)&1)|attr; + lpScn[5] = ((chr_h>>1)&2)|((chr_l>>2)&1)|attr; + lpScn[2] = ((chr_h>>4)&2)|((chr_l>>5)&1)|attr; + lpScn[6] = ((chr_h>>0)&2)|((chr_l>>1)&1)|attr; + lpScn[3] = ((chr_h>>3)&2)|((chr_l>>4)&1)|attr; + lpScn[7] = ((chr_h<<1)&2)|((chr_l>>0)&1)|attr; + // Next line + lpScn+=512; + } + } + } + } + + RECT rc; + ::GetClientRect( hWnd, &rc ); + HDC hDC = ::GetDC( hWnd ); + ::StretchDIBits( hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 0, 0, 512, 480, m_lpPattern, (BITMAPINFO*)&m_BitmapHdr, DIB_RGB_COLORS, SRCCOPY ); + ::ReleaseDC( hWnd, hDC ); + + return TRUE; +} + diff --git a/References/VirtuaNESex_src_191105/NameTableView.h b/References/VirtuaNESex_src_191105/NameTableView.h new file mode 100644 index 00000000..ea02e39d --- /dev/null +++ b/References/VirtuaNESex_src_191105/NameTableView.h @@ -0,0 +1,46 @@ +// +// p^[r[NX +// +#ifndef __CNAMETABLEVIEW_INCLUDED__ +#define __CNAMETABLEVIEW_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CNameTableView : public CWnd +{ +public: + // Constructor/Destructor + CNameTableView(); + ~CNameTableView(); + + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + // Message map + WND_MESSAGE_MAP() + WNDMSG OnCreate( WNDMSGPARAM ); + WNDMSG OnClose( WNDMSGPARAM ); + WNDMSG OnDestroy( WNDMSGPARAM ); + WNDMSG OnTimer( WNDMSGPARAM ); + // + + struct BITMAPHDR { + BITMAPINFOHEADER bih; + RGBQUAD rgb[16]; + } m_BitmapHdr; + + // + RGBQUAD m_Palette[256]; + LPBYTE m_lpPattern; +private: +}; + +#endif // !__CNAMETABLEVIEW_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/NetPlay.cpp b/References/VirtuaNESex_src_191105/NetPlay.cpp new file mode 100644 index 00000000..ef5e443e --- /dev/null +++ b/References/VirtuaNESex_src_191105/NetPlay.cpp @@ -0,0 +1,811 @@ +// +// lbgvCNX +// +// IWinSock LibN +#pragma comment(lib, "wsock32.lib") + +#include "DebugOut.h" +#include "NetPlay.h" + +#define CLOSESOCKET(soc) if((soc)!=INVALID_SOCKET){::closesocket((soc));(soc)=INVALID_SOCKET;} + +static char* SocketErrorDump( int eno ); + +CNetPlay NetPlay; + +CNetPlay::CNetPlay() +{ + m_hWnd = m_hWndMsg = m_hWndChat = NULL; + m_bConnect = FALSE; + + m_SocketConnect = INVALID_SOCKET; + m_SocketData = INVALID_SOCKET; + m_SocketChat = INVALID_SOCKET; + + m_nLatency = 0; + m_nFrameCount = 0; + m_nFrameStep = 0; + + m_hASyncTask = NULL; +} + +CNetPlay::~CNetPlay() +{ + // Ƃ肠 + Release(); +} + +BOOL CNetPlay::Initialize( HWND hWnd ) +{ + // Ƃ肠 + Release(); + + // WinSock DLL̏ + if( ::WSAStartup( MAKEWORD(1,1), &m_WSAdata ) ) + return FALSE; + + // o[WႤ` + if( m_WSAdata.wVersion != MAKEWORD(1,1) ) { + ::WSACleanup(); + return FALSE; + } + + m_hWnd = hWnd; + return TRUE; +} + +void CNetPlay::Release() +{ + Disconnect(); + + if( m_hWnd ) { + ::WSACleanup(); + m_hWnd = NULL; + } +} + +INT CNetPlay::ASyncHostCheck( HWND hWnd, const char* lpszHost ) +{ +DEBUGOUT( "CNetPlay:ASyncHostCheck [%s]\n", lpszHost ); + + unsigned long IP_address = ::inet_addr( lpszHost ); + if( IP_address != INADDR_NONE ) { + DEBUGOUT( "CNetPlay:IP\n" ); + return 0; + } + + m_hWndASync = hWnd; + + // zXgJn + m_hASyncTask = ::WSAAsyncGetHostByName( hWnd, WM_NETPLAY_HOSTBYNAME, lpszHost, m_HostEntry, MAXGETHOSTSTRUCT ); + + if( m_hASyncTask ) { + return 1; + } + + return -1; +} + +HRESULT CNetPlay::ASyncWndProc( HWND hWnd, WPARAM wParam, LPARAM lParam ) +{ +DEBUGOUT( "CNetPlay:ASyncWndProc\n" ); + + if( WSAGETASYNCERROR(lParam) ) { +DEBUGOUT( "CNetPlay:ASyncWndProc error.[%s]\n", SocketErrorDump( WSAGETASYNCERROR(lParam) ) ); + m_hWndASync = NULL; + return 0; + } + + if( m_hASyncTask == (HANDLE)wParam ) { + if( m_hWndASync ) { + m_hWndASync = NULL; + + return *((unsigned long *)((((struct hostent FAR *)m_HostEntry)->h_addr_list)[0])); + } + } + + return 0L; +} + +BOOL CNetPlay::Connect( BOOL bServer, const char* lpszIP, unsigned short Port ) +{ + if( !m_hWnd ) + return FALSE; + + m_bServer = bServer; + + if( bServer ) { + // Server + // ڑʒm\Pbg쐬 + if( m_SocketConnect == INVALID_SOCKET ) { + m_SocketConnect = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); + if( m_SocketConnect == INVALID_SOCKET ) { + DEBUGOUT( "CNetPlay:socket failed.\n" ); + return FALSE; + } + } + + // ėp‚Ă݂ + unsigned long ulOpt = 1; + if( ::setsockopt( m_SocketConnect, SOL_SOCKET, SO_REUSEADDR, (const char*)&ulOpt, sizeof(ulOpt) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:setsockopt failed. (SO_REUSEADDR)\n" ); + CLOSESOCKET( m_SocketConnect ); + return FALSE; + } + + // |[gƌт‚ + ZEROMEMORY( &m_SAddr_Server, sizeof(m_SAddr_Server) ); + m_SAddr_Server.sin_family = AF_INET; + m_SAddr_Server.sin_addr.s_addr = ::htonl( INADDR_ANY ); + m_SAddr_Server.sin_port = ::htons( Port ); + if( ::bind( m_SocketConnect, (struct sockaddr *)&m_SAddr_Server, sizeof(m_SAddr_Server) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:bind failed.\n" ); + CLOSESOCKET( m_SocketConnect ); + return FALSE; + } +//----------------- + // `bgp\Pbg쐬 + m_SocketChat = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if( m_SocketChat == INVALID_SOCKET ) { + DEBUGOUT( "create socket failed.[chat]\n" ); + Disconnect(); + return FALSE; + } + // |[gɐڑ + if( ::bind( m_SocketChat, (struct sockaddr *)&m_SAddr_Server, sizeof(m_SAddr_Server) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:connect failed. [chat]\n" ); + Disconnect(); + return FALSE; + } + // ubLO[hݒ + unsigned long ulArg = 1; + if( ::ioctlsocket( m_SocketChat, FIONBIO, &ulArg ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:ioctlsocket failed.[chat]\n" ); + Disconnect(); + return FALSE; + } +//----------------- + // ڑvCxg̐ݒ + if( ::WSAAsyncSelect( m_SocketConnect, m_hWnd, WM_NETPLAY, FD_ACCEPT ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:WSAAsyncSelect failed.\n" ); + CLOSESOCKET( m_SocketConnect ); + return FALSE; + } + + // ڑvtJnĂ݂ + if( ::listen( m_SocketConnect, 1 ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:listen failed.\n" ); + CLOSESOCKET( m_SocketConnect ); + return FALSE; + } + } else { + // Client + unsigned long ulOpt; + // IPAhXH + unsigned long IP_address = ::inet_addr( lpszIP ); + if( IP_address == INADDR_NONE ) { + DEBUGOUT( "CNetPlay:IPAhXsłB\"%s\"\n", lpszIP ); + return FALSE; + } + + // f[^ʐM\Pbg쐬 + m_SocketData = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); + if( m_SocketData == INVALID_SOCKET ) { + DEBUGOUT( "CNetPlay:socket failed.\n" ); + return FALSE; + } + + // ėp‚Ă݂ + ulOpt = 1; + if( ::setsockopt( m_SocketData, SOL_SOCKET, SO_REUSEADDR, (const char*)&ulOpt, sizeof(ulOpt) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:setsockopt failed. (SO_REUSEADDR)\n" ); + CLOSESOCKET( m_SocketData ); + return FALSE; + } + + // NagleASY̖ + ulOpt = 1; + if( ::setsockopt( m_SocketData, IPPROTO_TCP, TCP_NODELAY, (const char*)&ulOpt, sizeof(ulOpt) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:setsockopt failed.\n" ); + CLOSESOCKET( m_SocketData ); + return FALSE; + } + + // ubLO[hݒ + unsigned long ulArg = 1; + if( ::ioctlsocket( m_SocketData, FIONBIO, &ulArg ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:ioctlsocket failed.\n" ); + CLOSESOCKET( m_SocketData ); + return FALSE; + } + +//----------------- + // `bgp\Pbg쐬 + m_SocketChat = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if( m_SocketChat == INVALID_SOCKET ) { + DEBUGOUT( "create socket failed.[chat]\n" ); + Disconnect(); + return FALSE; + } + // ubLO[hݒ +// unsigned long ulArg = 1; + ulArg = 1; + if( ::ioctlsocket( m_SocketChat, FIONBIO, &ulArg ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:ioctlsocket failed.[chat]\n" ); + Disconnect(); + return FALSE; + } +//----------------- + + // ڑCxg̐ݒ + if( ::WSAAsyncSelect( m_SocketData, m_hWnd, WM_NETPLAY, FD_CONNECT ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:WSAAsyncSelect failed.\n" ); + CLOSESOCKET( m_SocketData ); + return FALSE; + } + + // ڑvĂ݂ + ZEROMEMORY( &m_SAddr_Server, sizeof(m_SAddr_Server) ); + m_SAddr_Server.sin_family = AF_INET; + m_SAddr_Server.sin_addr.s_addr = IP_address; + m_SAddr_Server.sin_port = ::htons( Port ); + if( ::connect( m_SocketData, (struct sockaddr *)&m_SAddr_Server, sizeof(m_SAddr_Server) ) == SOCKET_ERROR ) { + if( ::WSAGetLastError() != WSAEWOULDBLOCK ) { + DEBUGOUT( "CNetPlay:connect failed.\n" ); + CLOSESOCKET( m_SocketData ); + return FALSE; + } + } + } + + return TRUE; +} + +void CNetPlay::Disconnect() +{ +#if defined(_DEBUG)||defined(_DEBUGOUT) +if( m_bConnect ) { +DEBUGOUT( "CNetPlay::Disconnect\n" ); +} +#endif + if( m_hASyncTask ) { + ::WSACancelAsyncRequest( m_hASyncTask ); + m_hASyncTask = NULL; + } + + // \PbgVbg_EĔj + if( m_SocketConnect != INVALID_SOCKET ) { + ::shutdown( m_SocketConnect, SD_BOTH ); + CLOSESOCKET( m_SocketConnect ); + } + if( m_SocketData != INVALID_SOCKET ) { + ::shutdown( m_SocketData, SD_BOTH ); + CLOSESOCKET( m_SocketData ); + } + if( m_SocketChat != INVALID_SOCKET ) { + ::shutdown( m_SocketChat, SD_BOTH ); + CLOSESOCKET( m_SocketChat ); + } + + m_bConnect = FALSE; +} + +INT CNetPlay::Send( BYTE data ) +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return -1L; + + while( TRUE ) { + if( ::send( m_SocketData, (char*)&data, sizeof(BYTE), 0 ) == SOCKET_ERROR ) { + // ubNꂽmȂ̂ōēx + if( ::WSAGetLastError() == WSAEWOULDBLOCK ) { + ::Sleep(0); // ł܂Ȃ[u + continue; + } else { + // vIG[ۂ + DEBUGOUT( "CNetPlay:send failed. code=%d\n", ::WSAGetLastError() ); + Disconnect(); + return -1L; + } + } else { + break; + } + } + return 0L; +} + +INT CNetPlay::Recv( BYTE& data ) +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return -1L; + + // f[^͂Ă邩mF + unsigned long len = 0; + if( ::ioctlsocket( m_SocketData, FIONREAD, (unsigned long*)&len ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:ioctlsocket failed.\n" ); + Disconnect(); + return -1L; + } + + if( !len ) { + // f[^͂ĂȂ + return 0L; + } else { + // 1oCgǂݍ + if( ::recv( m_SocketData, (char*)&data, sizeof(BYTE), 0 ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:recv failed.\n" ); + Disconnect(); + return -1L; + } + } + + return len; +} + +INT CNetPlay::RecvTime( BYTE& data, unsigned long timeout ) +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return -1L; + + INT ret; + DWORD dwTimeOut = ::timeGetTime(); + while( (ret = NetPlay.Recv( data )) == 0 ) { + // ł܂Ȃ[u + ::Sleep( 0 ); + // ^CAEg̃`FbN + if( (::timeGetTime()-dwTimeOut) > timeout ) { + return -1; + } + } + return ret; +} + +BOOL CNetPlay::RecvBuffer() +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return FALSE; + + BYTE buf[SOCKET_RECEIVE_SIZE]; + INT recvsize = ::recv( m_SocketData, (char*)buf, SOCKET_RECEIVE_SIZE, 0 ); + if( recvsize == 0 ) { + return FALSE; + } else if( recvsize == SOCKET_ERROR ) { + if( ::WSAGetLastError() == WSAEWOULDBLOCK ) { + return TRUE; + } else { +DEBUGOUT( "CNetPlay::RecvBuffer failed. [%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); + return FALSE; + } + } else { + INT p = m_nRecvPtr; + for( INT i = 0; i < recvsize; i++ ) { + m_RecvBuffer[p] = buf[i]; + p = (p+1) & SOCKET_BUFFER_SIZE-1; + } + m_nRecvPtr = p; + m_nRecvSize += recvsize; + } + return TRUE; +} + +INT CNetPlay::GetRecvBufferSize() +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return 0; + + return m_nRecvSize; +} + +BOOL CNetPlay::BufferCheck() +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return 0; + + // LAN + if( m_nLatency == 0 && m_nRecvSize < SOCKET_BLOCK_SIZE ) { + return -1; + } + + // Frame control + // H + if( m_nRecvSize < SOCKET_BLOCK_SIZE ) { + return -1; // ҂Ă + } + // xH + if( m_nRecvSize > ((m_nLatency+2)*SOCKET_BLOCK_SIZE) ) { + return 1; // i߂Ă + } + return 0; +} + +// O(CeV̕ɑMē) +INT CNetPlay::Sync() +{ +BYTE senddata[SOCKET_BLOCK_SIZE]; + +DEBUGOUT( "CNetPlay::Sync\n" ); + + ZEROMEMORY( senddata, sizeof(senddata) ); + + m_nFrameCount = 0; + m_nRingPtr = m_nSendPtr = m_nRecvPtr = 0; + m_nRecvSize = 0; + +DEBUGOUT( "CNetPlay::Sync sending...\n" ); + + // f[^M + for( INT i = 0; i < m_nLatency+1; i++ ) { + while( TRUE ) { + if( ::send( m_SocketData, (char*)senddata, SOCKET_BLOCK_SIZE, 0 ) == SOCKET_ERROR ) { + // ubNꂽmȂ̂ōēx + if( ::WSAGetLastError() == WSAEWOULDBLOCK ) { +DEBUGOUT( "send::WSAEWOULDBLOCK!!\n" ); + ::Sleep(0); // ł܂Ȃ[u + continue; + } else { + // vIG[ۂ +DEBUGOUT( "CNetPlay:Sync send failed. [%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); + Disconnect(); + return -1L; + } + } else { + break; + } + } + m_nSendPtr = (m_nSendPtr+SOCKET_BLOCK_SIZE) & SOCKET_BUFFER_SIZE-1; + } + + // f[^̃obt@Of[^҂(10bŃ^CAEg) + DWORD dwTime = ::timeGetTime(); + while( m_nRecvSize < (m_nLatency+1)*SOCKET_BLOCK_SIZE ) { + if( !RecvBuffer() ) { + DEBUGOUT( "CNetPlay:recv error.\n" ); + Disconnect(); + return -1; + } + + if( (::timeGetTime()-dwTime) > 10*1000 ) { + DEBUGOUT( "CNetPlay:Sync recv timeout.\n" ); + Disconnect(); + return -1; + } + ::Sleep( 1 ); + } + +DEBUGOUT( "CNetPlay::Sync OK!\n" ); + + return 0; +} + +// vC[L[̍XV +INT CNetPlay::ModifyPlayer( LPBYTE p1, LPBYTE p2 ) +{ + if( !m_hWnd || !m_bConnect || m_SocketData == INVALID_SOCKET ) + return -1L; + + // ׂ|CgőM + if( m_nFrameCount == 0 ) { + while( TRUE ) { + if( ::send( m_SocketData, (char*)p1, SOCKET_BLOCK_SIZE, 0 ) == SOCKET_ERROR ) { + // ubNꂽmȂ̂ōēx + if( ::WSAGetLastError() == WSAEWOULDBLOCK ) { +DEBUGOUT( "send::WSAEWOULDBLOCK!!\n" ); + ::Sleep(0); // ł܂Ȃ[u + continue; + } else { + // vIG[ۂ + DEBUGOUT( "CNetPlay:ModifyPlayer send failed. code=%d\n", ::WSAGetLastError() ); + Disconnect(); + return -1L; + } + } else { + break; + } + } + + // obt@ɕ荞 + for( INT i = 0; i < SOCKET_BLOCK_SIZE; i++ ) { + m_SendBuffer[ m_nSendPtr ] = p1[i]; + m_nSendPtr = (m_nSendPtr+1) & SOCKET_BUFFER_SIZE-1; + } + } + + // f[^҂(10bŃ^CAEg) + DWORD dwTime = ::timeGetTime(); + while( m_nRecvSize < SOCKET_BLOCK_SIZE ) { + if( !RecvBuffer() ) { + DEBUGOUT( "CNetPlay:ModifyPlayer recv error.\n" ); + Disconnect(); + return -1; + } + if( (::timeGetTime()-dwTime) > 10*1000 ) { + DEBUGOUT( "CNetPlay:ModifyPlayer recv timeout.\n" ); + Disconnect(); + return -1; + } + ::Sleep( 1 ); + } + + // XV + INT p = m_nRingPtr; + for( INT i = 0; i < SOCKET_BLOCK_SIZE; i++ ) { + p1[i] = m_SendBuffer[ p ]; + p2[i] = m_RecvBuffer[ p ]; + p = (p+1) & SOCKET_BUFFER_SIZE-1; + } + + INT Count = m_nFrameCount; + + // XebvXV + if( ++m_nFrameCount > m_nFrameStep ) { + m_nFrameCount = 0; + + m_nRingPtr = (m_nRingPtr+SOCKET_BLOCK_SIZE) & SOCKET_BUFFER_SIZE-1; + m_nRecvSize -= SOCKET_BLOCK_SIZE; + } + + return Count; +} + +void CNetPlay::ChatSend( LPCSTR lpStr ) +{ + if( !m_hWnd || !m_bConnect || m_SocketChat == INVALID_SOCKET ) + return; + + if( m_bServer ) { +DEBUGOUT( "ChatSend Server:%s", lpStr ); + if( ::sendto( m_SocketChat, (char*)lpStr, ::strlen(lpStr)+1, 0, (struct sockaddr *)&m_SAddr_Client, sizeof(m_SAddr_Client) ) == SOCKET_ERROR ) { + DEBUGOUT( "ChatSend failed. Server:[%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); + } + } else { +DEBUGOUT( "ChatSend Client:%s", lpStr ); + if( ::sendto( m_SocketChat, (char*)lpStr, ::strlen(lpStr)+1, 0, (struct sockaddr *)&m_SAddr_Server, sizeof(m_SAddr_Server) ) == SOCKET_ERROR ) { + DEBUGOUT( "ChatSend failed. Server:[%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); + } + } +} + +HRESULT CNetPlay::WndProc( HWND hWnd, WPARAM wParam, LPARAM lParam ) +{ + // G[H + if( WSAGETSELECTERROR(lParam) ) { + DEBUGOUT( "CNetPlay::WndProc error.[%s]\n", SocketErrorDump( WSAGETSELECTERROR(lParam) ) ); + + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_CLOSE, 0, 0 ); + } + + return 0L; + } + + switch( WSAGETSELECTEVENT(lParam) ) { + case FD_ACCEPT: { + DEBUGOUT( "Accepting...." ); + ZEROMEMORY( &m_SAddr_Client, sizeof(m_SAddr_Client) ); + int len = sizeof(m_SAddr_Client); + m_SocketData = ::accept( m_SocketConnect, (sockaddr*)&m_SAddr_Client, &len ); + + // ڑp\Pbg͕‚ + ::shutdown( m_SocketConnect, SD_BOTH ); + CLOSESOCKET( m_SocketConnect ); + + if( m_SocketData == INVALID_SOCKET ) { + DEBUGOUT( "failed.\n" ); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + DEBUGOUT( "done.\n" ); + + // NagleASY̖ + unsigned long ulOpt = 1; + if( ::setsockopt( m_SocketData, IPPROTO_TCP, TCP_NODELAY, (const char*)&ulOpt, sizeof(ulOpt) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:setsockopt failed.\n" ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + // ubLO[hݒ + unsigned long ulArg = 1; + if( ::ioctlsocket( m_SocketData, FIONBIO, &ulArg ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:ioctlsocket failed.\n" ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + // 񓯊Cxg̐ݒ + if( ::WSAAsyncSelect( m_SocketChat, m_hWnd, WM_NETPLAY, FD_READ ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:WSAAsyncSelect failed.[CONNECT chat]\n" ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + // 񓯊Cxg̐ݒ + if( ::WSAAsyncSelect( m_SocketData, m_hWnd, WM_NETPLAY, FD_CLOSE ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:WSAAsyncSelect failed.[ACCEPT data]\n" ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + m_bConnect = TRUE; + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ACCEPT, 0, 0 ); + } + break; + } + + case FD_CONNECT: { + DEBUGOUT( "Connection done.\n" ); + + // 1oCg_~[f[^𑗂(ԈĂCc) + if( ::sendto( m_SocketChat, (char*)"", 1, 0, (struct sockaddr *)&m_SAddr_Server, sizeof(m_SAddr_Server) ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:send failed. Client:[%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + // 񓯊Cxg̐ݒ + if( ::WSAAsyncSelect( m_SocketChat, m_hWnd, WM_NETPLAY, FD_READ ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:WSAAsyncSelect failed.[CONNECT chat]\n" ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + + // 񓯊Cxg̐ݒ + if( ::WSAAsyncSelect( m_SocketData, m_hWnd, WM_NETPLAY, FD_CLOSE ) == SOCKET_ERROR ) { + DEBUGOUT( "CNetPlay:WSAAsyncSelect failed.[CONNECT data]\n" ); + Disconnect(); + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_ERROR, 0, 0 ); + } + return 0L; + } + m_bConnect = TRUE; + if( m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_CONNECT, 0, 0 ); + } + break; + } + + case FD_CLOSE: { + DEBUGOUT( "Connection close.\n" ); + if( m_bConnect && m_hWndMsg ) { + ::PostMessage( m_hWndMsg, WM_NETPLAY_CLOSE, 0, 0 ); + } + Disconnect(); + break; + } + + case FD_READ: { +// error is ignored :p +// DEBUGOUT( "FD_READ\n" ); + INT recvsize = 0; + INT size = sizeof(struct sockaddr_in); + CHAR szBuf[256+1]; + + if( m_bServer ) { + recvsize = ::recvfrom( m_SocketChat, (char*)szBuf, sizeof(szBuf)-1, 0, (struct sockaddr *)&m_SAddr_Client, &size ); + } else { + recvsize = ::recvfrom( m_SocketChat, (char*)szBuf, sizeof(szBuf)-1, 0, (struct sockaddr *)&m_SAddr_Server, &size ); + } + + if( recvsize == SOCKET_ERROR ) { +if( m_bServer ) { +DEBUGOUT( "FD_READ failed. Server [%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); +} else { +DEBUGOUT( "FD_READ failed. Client [%s]\n", SocketErrorDump( ::WSAGetLastError() ) ); +} + } else if( recvsize > 0 ) { + szBuf[recvsize] = '\0'; + + if( m_hWndChat && ::IsWindow( m_hWndChat ) ) { + COPYDATASTRUCT cds; + cds.dwData = 0; + cds.lpData = (void*)szBuf; + cds.cbData = ::strlen(szBuf)+1; // I[NULL + // 񑗐M + ::SendMessage( m_hWndChat, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds ); + } + } + break; + } + default: +DEBUGOUT( "Unknown message.\n" ); + break; + } + + return 0L; +} + +static char* SocketErrorDump( int eno ) +{ + switch( eno ) { + case 0: return "No error"; + +#if defined(_DEBUG)||defined(_DEBUGOUT) + case WSAEINTR: return "Interrupted system call"; + case WSAEBADF: return "Bad file number"; + case WSAEACCES: return "Permission denied"; + case WSAEFAULT: return "Bad address"; + case WSAEINVAL: return "Invalid argument"; + case WSAEMFILE: return "Too many open sockets"; + + case WSAEWOULDBLOCK: return "Operation would block"; + case WSAEINPROGRESS: return "Operation now in progress"; + case WSAEALREADY: return "Operation already in progress"; + case WSAENOTSOCK: return "Socket operation on non-socket"; + case WSAEDESTADDRREQ: return "Destination address required"; + case WSAEMSGSIZE: return "Message too long"; + case WSAEPROTOTYPE: return "Protocol wrong type for socket"; + case WSAENOPROTOOPT: return "Bad protocol option"; + case WSAEPROTONOSUPPORT: return "Protocol not supported"; + case WSAESOCKTNOSUPPORT: return "Socket type not supported"; + case WSAEOPNOTSUPP: return "Operation not supported on socket"; + case WSAEPFNOSUPPORT: return "Protocol family not supported"; + case WSAEAFNOSUPPORT: return "Address family not supported"; + case WSAEADDRINUSE: return "Address already in use"; + case WSAEADDRNOTAVAIL: return "Can't assign requested address"; + case WSAENETDOWN: return "Network is down"; + case WSAENETUNREACH: return "Network is unreachable"; + case WSAENETRESET: return "Net connection reset"; + case WSAECONNABORTED: return "Software caused connection abort"; + case WSAECONNRESET: return "Connection reset by peer"; + case WSAENOBUFS: return "No buffer space available"; + case WSAEISCONN: return "Socket is already connected"; + case WSAENOTCONN: return "Socket is not connected"; + case WSAESHUTDOWN: return "Can't send after socket shutdown"; + case WSAETOOMANYREFS: return "Too many references, can't splice"; + case WSAETIMEDOUT: return "Connection timed out"; + case WSAECONNREFUSED: return "Connection refused"; + case WSAELOOP: return "Too many levels of symbolic links"; + case WSAENAMETOOLONG: return "File name too long"; + case WSAEHOSTDOWN: return "Host is down"; + case WSAEHOSTUNREACH: return "No route to host"; + case WSAENOTEMPTY: return "Directory not empty"; + case WSAEPROCLIM: return "Too many processes"; + case WSAEUSERS: return "Too many users"; + case WSAEDQUOT: return "Disc quota exceeded"; + case WSAESTALE: return "Stale NFS file handle"; + case WSAEREMOTE: return "Too many levels of remote in path"; + + case WSAEDISCON: return "Graceful shutdown in progress"; + + case WSASYSNOTREADY: return "Network system is unavailable"; + case WSAVERNOTSUPPORTED: return "Winsock version out of range"; + case WSANOTINITIALISED: return "WSAStartup not yet called"; + + case WSAHOST_NOT_FOUND: return "Host not found"; + + case WSATRY_AGAIN: return "WSATRY_AGAIN"; + + case WSANO_RECOVERY: return "WSANO_RECOVERY"; + + case WSANO_DATA: return "No host data of that type was found"; +#endif + default: return "Unknown"; + break; + } + return ""; +} + diff --git a/References/VirtuaNESex_src_191105/NetPlay.h b/References/VirtuaNESex_src_191105/NetPlay.h new file mode 100644 index 00000000..3a38243c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NetPlay.h @@ -0,0 +1,153 @@ +// +// lbgvCNX +// +#ifndef __CNETPLAY_INCLUDED__ +#define __CNETPLAY_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +#include "macro.h" +#include "typedef.h" + +#include +using namespace std; + +#define WM_NETPLAY (WM_APP+100) + +#define WM_NETPLAY_HOSTBYNAME (WM_APP+101) + +#define WM_NETPLAY_ACCEPT (WM_APP+110) +#define WM_NETPLAY_CONNECT (WM_APP+111) +#define WM_NETPLAY_CLOSE (WM_APP+112) +#define WM_NETPLAY_ERROR (WM_APP+113) + +// for BSD style +#ifndef INVALID_SOCKET +#define INVALID_SOCKET -1 +#endif + +// for Winsock1.x +#ifndef SD_RECEIVE +#define SD_RECEIVE 0 +#endif +#ifndef SD_SEND +#define SD_SEND 1 +#endif +#ifndef SD_BOTH +#define SD_BOTH 2 +#endif + +class CNetPlay +{ +public: + CNetPlay(); + ~CNetPlay(); + + // /J + BOOL Initialize( HWND hWnd ); + void Release(); + + // lbgvCH + BOOL IsNetPlay() { return m_hWnd?TRUE:FALSE; } + // ڑH + BOOL IsConnect() { return m_hWnd?m_bConnect:FALSE; } + // ڑH + BOOL IsServer() { return m_bServer; } + + // ʐMCeV + void SetLatency( INT nLatency ) { m_nLatency = nLatency; } + INT GetLatency() { return m_nLatency; } + + // 񓯊bZ[WԑEChE̐ݒ + void SetMsgWnd( HWND hWnd ) { m_hWndMsg = hWnd; } + + // `bgbZ[W󂯎EChE̐ݒ + void SetChatWnd( HWND hWnd ) { m_hWndChat = hWnd; } + + // zXgIPǂ`FbN(0:IP -:Error +:Host search) + INT ASyncHostCheck( HWND hWnd, const char* lpszHost ); + HRESULT ASyncWndProc( HWND hWnd, WPARAM wParam, LPARAM lParam ); + + // ڑƐؒf + BOOL Connect( BOOL bServer, const char* lpszIP, unsigned short Port ); + void Disconnect(); + + // f[^M 0:Mf[^҂ 1ȏ:Mf[^ 0:ڑ؂G[ + INT Send( BYTE data ); + // f[^M + // 0:Mf[^҂ 1ȏ:Mf[^ 0:ڑ؂G[ + // ^CAEg + INT Recv( BYTE& data ); + // ^CAEgL + INT RecvTime( BYTE& data, unsigned long timeout ); + + // Oobt@ւ̎荞 + BOOL RecvBuffer(); + // obt@`FbN(0:No change +:frame add -:no frame) + INT BufferCheck(); + // Oobt@̃obt@OoCg擾 + INT GetRecvBufferSize(); + + // + INT Sync(); + // vC[Ԃ̍XV + INT ModifyPlayer( LPBYTE p1, LPBYTE p2 ); + + // `bgbZ[WM + void ChatSend( LPCSTR lpStr ); + + // WindowsbZ[WvV[W + HRESULT WndProc( HWND hWnd, WPARAM wParam, LPARAM lParam ); + + // ʐMobt@ + enum { + // f[^ubNTCY + SOCKET_BLOCK_SIZE = 8, + // obt@TCY + SOCKET_BUFFER_SIZE = (SOCKET_BLOCK_SIZE*32), + // Mobt@TCY + SOCKET_RECEIVE_SIZE = (SOCKET_BLOCK_SIZE*8) + }; +protected: + // oϐ + HWND m_hWnd; + HWND m_hWndMsg; + HWND m_hWndASync; + HWND m_hWndChat; + + HANDLE m_hASyncTask; + CHAR m_HostEntry[MAXGETHOSTSTRUCT]; + + BOOL m_bServer; + BOOL m_bConnect; // ڑH + INT m_nLatency; // CeV(obt@TCY) + INT m_nFrameStep; // ʐMt[[g + INT m_nFrameCount; // JE^ + + // Ring buffer + INT m_nRingPtr; + INT m_nSendPtr; + INT m_nRecvPtr; + INT m_nRecvSize; + BYTE m_SendBuffer[SOCKET_BUFFER_SIZE]; + BYTE m_RecvBuffer[SOCKET_BUFFER_SIZE]; + + // WINSOCK + WSADATA m_WSAdata; + SOCKET m_SocketConnect; + SOCKET m_SocketData; + SOCKET m_SocketChat; + + struct sockaddr_in m_SAddr_Server; + struct sockaddr_in m_SAddr_Client; +private: +}; + +extern CNetPlay NetPlay; + +#endif // !__CNETPLAY_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/NetPlayDlg.cpp b/References/VirtuaNESex_src_191105/NetPlayDlg.cpp new file mode 100644 index 00000000..1fe62796 --- /dev/null +++ b/References/VirtuaNESex_src_191105/NetPlayDlg.cpp @@ -0,0 +1,577 @@ +// +// o[W_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Config.h" + +#include "Wnd.h" +#include "NetPlayDlg.h" + +#include "EmuThread.h" +#include "NetPlay.h" + +DLG_MESSAGE_BEGIN(CNetPlayDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_NETPLAY_HOSTBYNAME, OnNetwordHostByName ) +DLG_ON_MESSAGE( WM_NETPLAY_ACCEPT, OnNetworkAccept ) +DLG_ON_MESSAGE( WM_NETPLAY_CONNECT, OnNetworkConnect ) +DLG_ON_MESSAGE( WM_NETPLAY_CLOSE, OnNetworkClose ) +DLG_ON_MESSAGE( WM_NETPLAY_ERROR, OnNetworkError ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDC_NET_CONNECT, OnConnect ) +DLG_ON_COMMAND( IDC_NET_SERVER, OnServer ) +DLG_ON_COMMAND( IDC_NET_CLIENT, OnClient ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CNetPlayDlg::DoModal( HWND hWndParent ) +{ + m_hWndParent = hWndParent; + + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_NETPLAY), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CNetPlayDlg::SetStatusMessage( UINT uID ) +{ + CHAR szTemp[256]; + CApp::LoadString( uID, szTemp, sizeof(szTemp) ); + ::SetDlgItemText( m_hWnd, IDC_NET_STATUS, szTemp ); +} + +void CNetPlayDlg::SetControlEnable( BOOL bEnable ) +{ + if( bEnable ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?TRUE:FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?FALSE:TRUE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_LATENCY_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?TRUE:FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_SERVER ), TRUE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CLIENT ), TRUE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), TRUE ); + } else { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_LATENCY_COMBO ), FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_SERVER ), FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CLIENT ), FALSE ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), FALSE ); + } +} + +void CNetPlayDlg::AddRecentPort( LPCSTR lpszPort ) +{ + // Xgɂ邩ǂ + BOOL bFound = FALSE; + INT i, j; + for( i = 0; i < 16; i++ ) { + if( ::strlen(Config.netplay.szRecentPort[i]) <= 0 ) + break; + } + for( j = 0; j < i; j++ ) { + if( ::strcmp( Config.netplay.szRecentPort[j], lpszPort ) == 0 ) { + bFound = TRUE; + break; + } + } + if( j == 16 ) + j--; + for( ; j > 0; j-- ) { + ::lstrcpy( Config.netplay.szRecentPort[j], Config.netplay.szRecentPort[j-1] ); + } + ::strcpy( Config.netplay.szRecentPort[0], lpszPort ); + if( !bFound ) { + Config.netplay.nRecentPort++; + } +} + + +void CNetPlayDlg::AddRecentHost( LPCSTR lpszHost ) +{ + // Xgɂ邩ǂ + BOOL bFound = FALSE; + INT i, j; + for( i = 0; i < 16; i++ ) { + if( ::strlen(Config.netplay.szRecentHost[i]) <= 0 ) + break; + } + for( j = 0; j < i; j++ ) { + if( ::strcmp( Config.netplay.szRecentHost[j], lpszHost ) == 0 ) { + bFound = TRUE; + break; + } + } + if( j == 16 ) + j--; + for( ; j > 0; j-- ) { + ::lstrcpy( Config.netplay.szRecentHost[j], Config.netplay.szRecentHost[j-1] ); + } + ::strcpy( Config.netplay.szRecentHost[0], lpszHost ); + if( !bFound ) { + Config.netplay.nRecentHost++; + } +} + +DLGMSG CNetPlayDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CNetPlayDlg::OnInitDialog\n" ); + + INT i; + // |[g + ::SendDlgItemMessage( m_hWnd, IDC_NET_PORT_COMBO, CB_RESETCONTENT, 0, 0 ); + for( i = 0; i < Config.netplay.nRecentPort; i++ ) { + ::SendDlgItemMessage( m_hWnd, IDC_NET_PORT_COMBO, CB_INSERTSTRING, -1, (LPARAM)Config.netplay.szRecentPort[i] ); + } + ::SendDlgItemMessage( m_hWnd, IDC_NET_PORT_COMBO, CB_SETCURSEL, 0, 0 ); + + // CeV + ::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_RESETCONTENT, 0, 0 ); + for( i = 0; i < 9; i++ ) { + CHAR szStr[64]; + ::wsprintf( szStr, "%d Frame buffer", i+1 ); + ::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_INSERTSTRING, -1, (LPARAM)szStr ); + } + ::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_SETCURSEL, 0, 0 ); + + // zXgXg + ::SendDlgItemMessage( m_hWnd, IDC_NET_HOST_COMBO, CB_RESETCONTENT, 0, 0 ); + for( i = 0; i < Config.netplay.nRecentHost; i++ ) { + ::SendDlgItemMessage( m_hWnd, IDC_NET_HOST_COMBO, CB_INSERTSTRING, -1, (LPARAM)Config.netplay.szRecentHost[i] ); + } + ::SendDlgItemMessage( m_hWnd, IDC_NET_HOST_COMBO, CB_SETCURSEL, 0, 0 ); + + // jbNl[ + ::SetDlgItemText( m_hWnd, IDC_NET_NICKNAME, Config.netplay.szNick ); + + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), FALSE ); + + ::CheckRadioButton( m_hWnd, IDC_NET_SERVER, IDC_NET_CLIENT, IDC_NET_SERVER ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_LATENCY_COMBO ), IsBTNCHECK(IDC_NET_SERVER)?TRUE:FALSE ); + + SetStatusMessage( IDS_NET_NOCONNECT ); + + return TRUE; +} + +DLGMSG CNetPlayDlg::OnNetwordHostByName( DLGMSGPARAM ) +{ +DEBUGOUT( "CNetPlayDlg::OnNetwordHostByName [%08X][%08X]\n", wParam, lParam ); + + HRESULT hResult = NetPlay.ASyncWndProc( hWnd, wParam, lParam ); + + if( hResult ) { + struct in_addr addr; + addr.s_addr = hResult; + LPSTR pHost = inet_ntoa( addr ); + +DEBUGOUT( "Host:%s\n", pHost ); + + // G[Ƃ̑̃EChEŎ󂯎 + NetPlay.SetMsgWnd( m_hWnd ); + + if( NetPlay.Connect( FALSE, pHost, m_uPort ) ) { + SetStatusMessage( IDS_NET_CONNECTING ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), FALSE ); + SetControlEnable( FALSE ); + } else { +DEBUGOUT( "CNetPlayDlg::OnNetwordHostByName Connect error.\n" ); + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE ); + SetControlEnable( TRUE ); + } + } else { +DEBUGOUT( "CNetPlayDlg::OnNetwordHostByName error.\n" ); + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE ); + + SetControlEnable( TRUE ); + } + + return TRUE; +} + +DLGMSG CNetPlayDlg::OnNetworkAccept( DLGMSGPARAM ) +{ +BYTE databuf; +DWORD dwStartTime, dwEndTime; +BYTE nServerLatency, nClientLatency; +BYTE nServerStep, nClientStep; +INT nLatency; +BOOL bRet = FALSE; +DWORD dwCRC; +INT i; + + // jbNl[ۑ + CHAR szNick[_MAX_PATH+1]; + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), szNick, _MAX_PATH ); + ::lstrcpy( Config.netplay.szNick, szNick ); + + // ŋߎg|[g̍XV + CHAR szPort[_MAX_PATH+1]; + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), szPort, _MAX_PATH ); + AddRecentPort( szPort ); + + // ʐMCeV̌v + CHAR str[256]; + ::wsprintf( str, "VirtuaNES version %01d.%01d%01d", + (VIRTUANES_VERSION&0xF00)>>8, + (VIRTUANES_VERSION&0x0F0)>>4, + (VIRTUANES_VERSION&0x00F) ); + + dwStartTime = ::timeGetTime(); + for( i = 0; i < ::strlen(str); i++ ) { + if( NetPlay.Send( (BYTE)str[i] ) ) { + goto _accept_error; + } + if( NetPlay.RecvTime( databuf, 10*1000 ) < 0 ) { + goto _accept_error; + } else { + if( databuf != (BYTE)str[i] ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR_VERSION ); + goto _accept_error2; + } + } + } + dwEndTime = ::timeGetTime()-dwStartTime; + + DEBUGOUT( "Server: Transfer Bytes: %d byte / Time: %d ms\n", ::strlen(str), dwEndTime ); + + // C[WCRCmF + NES* pNes; + if( !(pNes = Emu.GetNES()) ) { + goto _accept_error; + } + if( pNes->rom->GetMapperNo() != 20 ) { + dwCRC = pNes->rom->GetPROM_CRC(); + } else { + dwCRC = pNes->rom->GetGameID(); + } + for( i = 0; i < 32; i+=8 ) { + if( NetPlay.Send( (BYTE)(dwCRC>>i) ) ) { + goto _accept_error; + } + if( NetPlay.RecvTime( databuf, 10*1000 ) < 0 ) { + goto _accept_error; + } else if( databuf != (BYTE)(dwCRC>>i) ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR_CRC ); + goto _accept_error2; + } + } + + // CeVݒ + nServerLatency = m_nNetLatency; + if( nServerLatency < 0 ) { + nServerLatency = 0; + } + if( nServerLatency > 8 ) { + nServerLatency = 8; + } +DEBUGOUT( "Latancy:%d\n", nServerLatency ); + nServerStep = 0; + nClientStep = 0; + + // Send Latency + if( NetPlay.Send( nServerLatency ) ) { + goto _accept_error; + } + // Recv Latency dummy + if( NetPlay.RecvTime( nClientLatency, 10*1000 ) < 0 ) { + goto _accept_error; + } + // Send Step + if( NetPlay.Send( nServerStep ) ) { + goto _accept_error; + } + // Recv Step dummy + if( NetPlay.RecvTime( nClientStep, 10*1000 ) < 0 ) { + goto _accept_error; + } + + nLatency = nServerLatency; + DEBUGOUT( "Server: Network Latency:%d frames\n", nLatency ); + + NetPlay.SetLatency( nLatency ); + NetPlay.SetMsgWnd( m_hWndParent ); + + ::EndDialog( m_hWnd, IDOK ); + return TRUE; +_accept_error: + SetStatusMessage( IDS_ERROR_NETWORKERROR ); +_accept_error2: + NetPlay.Disconnect(); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE ); + + SetControlEnable( TRUE ); + return TRUE; +} + +DLGMSG CNetPlayDlg::OnNetworkConnect( DLGMSGPARAM ) +{ +BYTE databuf; +DWORD dwStartTime, dwEndTime; +BYTE nServerLatency, nClientLatency; +BYTE nServerStep, nClientStep; +INT nLatency; +DWORD dwCRC; +INT i; + + // jbNl[ۑ + CHAR szNick[_MAX_PATH+1]; + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), szNick, _MAX_PATH ); + ::lstrcpy( Config.netplay.szNick, szNick ); +DEBUGOUT( "cnn Nick:%s\n", szNick ); + + // ŋߎg|[g̍XV + CHAR szHost[_MAX_PATH+1]; + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), szHost, _MAX_PATH ); +DEBUGOUT( "cnn Host:%s\n", szHost ); + AddRecentHost( szHost ); + + // ʐMCeV̌v + CHAR str[256]; + ::wsprintf( str, "VirtuaNES version %01d.%01d%01d", + (VIRTUANES_VERSION&0xF00)>>8, + (VIRTUANES_VERSION&0x0F0)>>4, + (VIRTUANES_VERSION&0x00F) ); + + dwStartTime = ::timeGetTime(); + for( i = 0; i < ::strlen(str); i++ ) { + if( NetPlay.Send( (BYTE)str[i] ) ) { + goto _connect_error; + } + if( NetPlay.RecvTime( databuf, 10*1000 ) < 0 ) { + goto _connect_error; + } else { + if( databuf != str[i] ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR_VERSION ); + goto _connect_error2; + } + } + } + dwEndTime = ::timeGetTime()-dwStartTime; + + DEBUGOUT( "Client: Transfer Bytes: %d byte / Time: %d ms\n", ::strlen(str), dwEndTime ); + + // C[WCRCmF + NES* pNes; + if( !(pNes = Emu.GetNES()) ) { + goto _connect_error; + } + if( pNes->rom->GetMapperNo() != 20 ) { + dwCRC = pNes->rom->GetPROM_CRC(); + } else { + dwCRC = pNes->rom->GetGameID(); + } + for( i = 0; i < 32; i+=8 ) { + if( NetPlay.Send( (BYTE)(dwCRC>>i) ) ) { + goto _connect_error; + } + if( NetPlay.RecvTime( databuf, 10*1000 ) < 0 ) { + goto _connect_error; + } else if( databuf != (BYTE)(dwCRC>>i) ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR_CRC ); + goto _connect_error2; + } + } + + nClientLatency = 0; + nServerStep = 0; + nClientStep = 0; + + // Send Latency dummy + if( NetPlay.Send( nClientLatency ) ) { + goto _connect_error; + } + // Recv Latency + if( NetPlay.RecvTime( nServerLatency, 10*1000 ) < 0 ) { + goto _connect_error; + } + // Send Step + if( NetPlay.Send( nClientStep ) ) { + goto _connect_error; + } + // Recv Step dummy + if( NetPlay.RecvTime( nServerStep, 10*1000 ) < 0 ) { + goto _connect_error; + } + + nLatency = nServerLatency; + DEBUGOUT( "Client: Network Latency:%d frames\n", nLatency ); + + NetPlay.SetLatency( nLatency ); + NetPlay.SetMsgWnd( m_hWndParent ); + + ::EndDialog( m_hWnd, IDOK ); + return TRUE; +_connect_error: + SetStatusMessage( IDS_ERROR_NETWORKERROR ); +_connect_error2: + NetPlay.Disconnect(); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE ); + + SetControlEnable( TRUE ); + return TRUE; +} + +DLGMSG CNetPlayDlg::OnNetworkClose( DLGMSGPARAM ) +{ + NetPlay.SetMsgWnd( NULL ); + SetStatusMessage( IDS_ERROR_NETWORKDISCONNECT ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE ); + SetControlEnable( TRUE ); + return TRUE; +} + +DLGMSG CNetPlayDlg::OnNetworkError( DLGMSGPARAM ) +{ + NetPlay.SetMsgWnd( NULL ); + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), TRUE ); + SetControlEnable( TRUE ); + return TRUE; +} + +DLGCMD CNetPlayDlg::OnServer( DLGCMDPARAM ) +{ + DEBUGOUT( "CNetPlayDlg::OnServer\n" ); + SetControlEnable( TRUE ); +} + +DLGCMD CNetPlayDlg::OnClient( DLGCMDPARAM ) +{ + DEBUGOUT( "CNetPlayDlg::OnClient\n" ); + SetControlEnable( TRUE ); +} + +DLGCMD CNetPlayDlg::OnConnect( DLGCMDPARAM ) +{ + DEBUGOUT( "CNetPlayDlg::OnConnect\n" ); + + CHAR szPort[_MAX_PATH+1]; + CHAR szHost[_MAX_PATH+1]; + CHAR szHostName[_MAX_PATH+1]; + CHAR szNick[_MAX_PATH+1]; + + if( IsBTNCHECK(IDC_NET_SERVER) ) { + // T[o[ + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_PORT_COMBO ), szPort, _MAX_PATH ); + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), szNick, _MAX_PATH ); + + INT porttemp = ::atoi( szPort ); + if( porttemp < 1024 || porttemp > 65535 ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + return; + } + m_uPort = porttemp; + + m_nNetLatency = ::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_GETCURSEL, 0, 0 ); + +DEBUGOUT( "Server Port:%d\n", m_uPort ); +DEBUGOUT( "Latency :%d\n", m_nNetLatency ); + } else { + // NCAg + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_HOST_COMBO ), szHost, _MAX_PATH ); + ::GetWindowText( ::GetDlgItem( m_hWnd, IDC_NET_NICKNAME ), szNick, _MAX_PATH ); + +DEBUGOUT( "Host and Addr: %s\n", szHost ); +DEBUGOUT( "NickName : %s\n", szNick ); + + INT i; + BOOL bFound; + bFound = FALSE; + + ::lstrcpy( szHostName, szHost ); + for( i = 0; i < ::strlen( szHostName ); i++ ) { + if( szHostName[i] == ':' ) { + bFound = TRUE; + break; + } + } + if( !bFound ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + return; + } + + szHostName[i] = '\0'; + LPSTR lpszPort = &szHostName[i+1]; + + INT porttemp = ::atoi( lpszPort ); + + if( porttemp < 1024 || porttemp > 65535 ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + return; + } + + m_uPort = porttemp; +DEBUGOUT( "Host:%s Port:%d\n", szHostName, m_uPort ); + + m_nNetLatency = ::SendDlgItemMessage( m_hWnd, IDC_NET_LATENCY_COMBO, CB_GETCURSEL, 0, 0 ); + if( m_nNetLatency == CB_ERR ) { + SetStatusMessage( IDS_ERROR_UNKNOWN ); + return; + } + } + + if( IsBTNCHECK(IDC_NET_SERVER) ) { + // G[Ƃ̑̃EChEŎ󂯎 + NetPlay.SetMsgWnd( m_hWnd ); + + if( NetPlay.Connect( TRUE, szHostName, m_uPort ) ) { + SetStatusMessage( IDS_NET_ACCEPTING ); + + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), FALSE ); + SetControlEnable( FALSE ); + } else { + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + DEBUGOUT( "CNetPlayDlg::OnConnect error.\n" ); + } + } else { + SetStatusMessage( IDS_NET_CONNECTING ); + + INT ret = NetPlay.ASyncHostCheck( m_hWnd, szHostName ); + + if( ret == 0 ) { + // G[Ƃ̑̃EChEŎ󂯎 + NetPlay.SetMsgWnd( m_hWnd ); + + if( NetPlay.Connect( FALSE, szHostName, m_uPort ) ) { + SetStatusMessage( IDS_NET_CONNECTING ); + + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), FALSE ); + SetControlEnable( FALSE ); + } else { + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + DEBUGOUT( "CNetPlayDlg::OnConnect error.\n" ); + } + } else if( ret > 0 ) { + ::EnableWindow( ::GetDlgItem( m_hWnd, IDC_NET_CONNECT ), FALSE ); + SetControlEnable( FALSE ); + } else if( ret < 0 ) { + SetStatusMessage( IDS_ERROR_NETWORKERROR ); + DEBUGOUT( "CNetPlayDlg::OnConnect error.\n" ); + } + } + +// ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CNetPlayDlg::OnCancel( DLGCMDPARAM ) +{ + DEBUGOUT( "CNetPlayDlg::OnCancel\n" ); + + NetPlay.Disconnect(); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + diff --git a/References/VirtuaNESex_src_191105/NetPlayDlg.h b/References/VirtuaNESex_src_191105/NetPlayDlg.h new file mode 100644 index 00000000..c458336c --- /dev/null +++ b/References/VirtuaNESex_src_191105/NetPlayDlg.h @@ -0,0 +1,54 @@ +// +// lbgvC_CAONX +// +#ifndef __CNETPLAYDLG_INCLUDED__ +#define __CNETPLAYDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +using namespace std; + +#include "Wnd.h" + +class CNetPlayDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + +protected: + void SetStatusMessage( UINT uID ); + + void SetControlEnable( BOOL bEnable ); + + void AddRecentPort( LPCSTR lpszPort ); + void AddRecentHost( LPCSTR lpszPort ); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnNetwordHostByName( DLGMSGPARAM ); + DLGMSG OnNetworkAccept( DLGMSGPARAM ); + DLGMSG OnNetworkConnect( DLGMSGPARAM ); + DLGMSG OnNetworkClose( DLGMSGPARAM ); + DLGMSG OnNetworkError( DLGMSGPARAM ); + + DLGCMD OnServer( DLGCMDPARAM ); + DLGCMD OnClient( DLGCMDPARAM ); + + DLGCMD OnConnect( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // + + HWND m_hWndParent; + + UINT m_uPort; + INT m_nNetLatency; +private: +}; + +#endif // !__CNETPLAYDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/PaletteEdit.cpp b/References/VirtuaNESex_src_191105/PaletteEdit.cpp new file mode 100644 index 00000000..81a203b9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/PaletteEdit.cpp @@ -0,0 +1,560 @@ +// +// p^[r[NX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "PaletteEdit.h" +#include "EmuThread.h" + +#include "MMU.h" + +#include "DirectDraw.h" + +// bZ[W +DLG_MESSAGE_BEGIN(CPaletteEdit) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_DESTROY, OnDestroy ) +DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate ) +DLG_ON_MESSAGE( WM_LBUTTONDOWN, OnLButtonDown ) +DLG_ON_MESSAGE( WM_RBUTTONDOWN, OnRButtonDown ) +DLG_ON_MESSAGE( WM_HSCROLL, OnHScroll ) +DLG_ON_MESSAGE( WM_PAINT, OnPaint ) +DLG_ON_MESSAGE( WM_TIMER, OnTimer ) + +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) + +DLG_ON_COMMAND_NOTIFY_RANGE( IDC_PAL_R_EDIT, IDC_PAL_B_EDIT, EN_CHANGE, OnRGBChange ) +DLG_ON_COMMAND( IDC_PAL_UNDO, OnUndo ) +DLG_ON_COMMAND( IDC_PAL_LOAD, OnLoad ) +DLG_ON_COMMAND( IDC_PAL_SAVE, OnSave ) + +DLG_COMMAND_END() +// Notify bZ[W +DLG_NOTIFY_BEGIN() +DLG_NOTIFY_END() +DLG_MESSAGE_END() + +CPaletteEdit::CPaletteEdit() +{ +} + +CPaletteEdit::~CPaletteEdit() +{ +} + +BOOL CPaletteEdit::Create( HWND hWndParent ) +{ + m_bShortCutDisable = FALSE; + + m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_PALETTE), + hWndParent, g_DlgProc, (LPARAM)this ); + if( !m_hWnd ) + return FALSE; + + // [hX_CAOXgɉ + CWndList::Add( this ); + + DirectDraw.GetPaletteTable( m_Palette ); + + m_PaletteSelect = 0; + ZEROMEMORY( &m_RGB, sizeof(RGBQUAD) ); + + return TRUE; +} + +void CPaletteEdit::Destroy() +{ + if( m_hWnd ) { + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcPaletteEditPos ); + + // [hX_CAOXg폜 + CWndList::Del( this ); + + ::KillTimer( m_hWnd, 1 ); + + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +DLGMSG CPaletteEdit::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnInitDialog\n" ); + + // ʒuC + if( Config.general.rcPaletteEditPos.right-Config.general.rcPaletteEditPos.left != 0 + && Config.general.rcPaletteEditPos.bottom-Config.general.rcPaletteEditPos.top != 0 ) { + ::SetWindowPos( m_hWnd, HWND_NOTOPMOST, Config.general.rcPaletteEditPos.left, Config.general.rcPaletteEditPos.top, + 0, 0, SWP_NOSIZE | SWP_NOZORDER ); + } + + // UPDOWN + ::SendDlgItemMessage( m_hWnd, IDC_PAL_R_UPDOWN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0) ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_G_UPDOWN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0) ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_B_UPDOWN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0) ); + + // XC_ + ::SendDlgItemMessage( m_hWnd, IDC_PAL_R_SLIDER, TBM_SETRANGE, 0, MAKELONG(0,255) ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_G_SLIDER, TBM_SETRANGE, 0, MAKELONG(0,255) ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_B_SLIDER, TBM_SETRANGE, 0, MAKELONG(0,255) ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_R_SLIDER, TBM_SETPAGESIZE, 0, 10 ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_G_SLIDER, TBM_SETPAGESIZE, 0, 10 ); + ::SendDlgItemMessage( m_hWnd, IDC_PAL_B_SLIDER, TBM_SETPAGESIZE, 0, 10 ); + + // COPY/EXCHANGE + BTNCHECK( IDC_PAL_COPY, TRUE ); + + m_bShortCutDisable = TRUE; + + DirectDraw.GetPaletteTable( m_Palette ); + ::memcpy( m_PaletteUndo, m_Palette, sizeof(m_Palette) ); + ::memcpy( m_PaletteDefault, m_Palette, sizeof(m_Palette) ); + ::memcpy( m_BGPAL, BGPAL, 16 ); + ::memcpy( m_SPPAL, SPPAL, 16 ); + + m_PaletteSelect = 0; + OnChaneSelect(); + + ::SetTimer( m_hWnd, 1, 50, NULL ); + + return TRUE; +} + +DLGMSG CPaletteEdit::OnDestroy( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnDestroy\n" ); + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcPaletteEditPos ); + + // [hX_CAOXg폜 + CWndList::Del( this ); + + m_hWnd = NULL; + m_bShortCutDisable = FALSE; + + return TRUE; +} + +DLGMSG CPaletteEdit::OnActivate( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnActivate\n" ); + + if( LOWORD(wParam) == WA_INACTIVE ) { +// DEBUGOUT( "CPaletteEdit::OnActivate:Inactive\n" ); +//// if( !m_bShortCutDisable ) + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 ); +//// m_bShortCutDisable = TRUE; + +//// if( Emu.IsRunning() ) +//// Emu.Resume(); + } else { +// DEBUGOUT( "CPaletteEdit::OnActivate:Active\n" ); + ::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 ); +//// m_bShortCutDisable = FALSE; + +//// if( Emu.IsRunning() ) +//// Emu.Pause(); + } + + return FALSE; +} + +DLGMSG CPaletteEdit::OnLButtonDown( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnLButtonDown\n" ); + + INT xp = LOWORD(lParam); + INT yp = HIWORD(lParam); + + RECT rcC; + ::GetClientRect( m_hWnd, &rcC ); + + RECT rc; + rc.left = ((rcC.right-rcC.left) - (CELL_SIZE*CELL_H)) / 2; + rc.right = rc.left + CELL_H * CELL_SIZE; + rc.top = 8; + rc.bottom = rc.top + CELL_V * CELL_SIZE; + + if( xp >= rc.left && xp < rc.right && yp >= rc.top && yp < rc.bottom ) { + m_PaletteSelect = ((xp-rc.left)/CELL_SIZE) + ((yp-rc.top)/CELL_SIZE)*16; + + ::memcpy( m_PaletteUndo, m_Palette, sizeof(m_Palette) ); + + OnChaneSelect(); + } + + rc.top = rc.bottom+8; + rc.bottom = rc.top + 2 * CELL_SIZE; + + if( xp >= rc.left && xp < rc.right && yp >= rc.top && yp < rc.bottom ) { + int x = (xp-rc.left)/CELL_SIZE; + int y = (yp-rc.top)/CELL_SIZE; + + if( y == 0 ) m_PaletteSelect = BGPAL[x]; + else m_PaletteSelect = SPPAL[x]; + + ::memcpy( m_PaletteUndo, m_Palette, sizeof(m_Palette) ); + + OnChaneSelect(); + } + + return TRUE; +} + +DLGMSG CPaletteEdit::OnRButtonDown( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnRButtonDown\n" ); + + INT xp = LOWORD(lParam); + INT yp = HIWORD(lParam); + + RECT rcC; + ::GetClientRect( m_hWnd, &rcC ); + + RECT rc; + rc.left = ((rcC.right-rcC.left) - (CELL_SIZE*CELL_H)) / 2; + rc.right = rc.left + CELL_H * CELL_SIZE; + rc.top = 8; + rc.bottom = rc.top + CELL_V * CELL_SIZE; + + if( xp >= rc.left && xp < rc.right && yp >= rc.top && yp < rc.bottom ) { + int nSel = ((xp-rc.left)/CELL_SIZE) + ((yp-rc.top)/CELL_SIZE)*16; + + ::memcpy( m_PaletteUndo, m_Palette, sizeof(m_Palette) ); + + if( IsBTNCHECK( IDC_PAL_COPY ) ) { + m_Palette[nSel] = m_Palette[m_PaletteSelect]; + } else { + RGBQUAD RGBtemp; + RGBtemp = m_Palette[m_PaletteSelect]; + m_RGB = m_Palette[m_PaletteSelect] = m_Palette[nSel]; + m_Palette[nSel] = RGBtemp; + } + + OnChaneSelect(); + } + + rc.top = rc.bottom+8; + rc.bottom = rc.top + 2 * CELL_SIZE; + + if( xp >= rc.left && xp < rc.right && yp >= rc.top && yp < rc.bottom ) { + int x = (xp-rc.left)/CELL_SIZE; + int y = (yp-rc.top)/CELL_SIZE; + + int nSel; + if( y == 0 ) nSel = BGPAL[x]; + else nSel = SPPAL[x]; + + ::memcpy( m_PaletteUndo, m_Palette, sizeof(m_Palette) ); + + m_Palette[nSel] = m_Palette[m_PaletteSelect]; + + OnChaneSelect(); + } + + return TRUE; +} + +DLGMSG CPaletteEdit::OnHScroll( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnHScroll\n" ); + +// int nScrollCode = (int)LOWORD(wParam); // scroll bar value +// int nPos = (int) HIWORD(wParam); // scroll box position + HWND hWndBar = (HWND)lParam; // handle to scroll bar + + int nEdit = 0; + int nPos = ::SendMessage( hWndBar, TBM_GETPOS, 0, 0 ); + + if( hWndBar == ::GetDlgItem( m_hWnd, IDC_PAL_R_SLIDER ) ) { + nEdit = IDC_PAL_R_EDIT; + } + if( hWndBar == ::GetDlgItem( m_hWnd, IDC_PAL_G_SLIDER ) ) { + nEdit = IDC_PAL_G_EDIT; + } + if( hWndBar == ::GetDlgItem( m_hWnd, IDC_PAL_B_SLIDER ) ) { + nEdit = IDC_PAL_B_EDIT; + } + + if( nEdit ) { + CHAR szStr[16]; + ::wsprintf( szStr, "%d", nPos ); + ::SetWindowText( ::GetDlgItem( m_hWnd, nEdit ), szStr ); + } + + return TRUE; +} + +DLGMSG CPaletteEdit::OnPaint( DLGMSGPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnPaint\n" ); + + PAINTSTRUCT ps; + HDC hDC = ::BeginPaint( hWnd, &ps ); + + int xoffs; + RECT rcC; + ::GetClientRect( m_hWnd, &rcC ); + + xoffs = ((rcC.right-rcC.left) - (CELL_SIZE*CELL_H)) / 2; + + RECT rc; + for( int y = 0; y < CELL_V; y++ ) { + for( int x = 0; x < CELL_H; x++ ) { + rc.left = xoffs + x * CELL_SIZE; + rc.right = rc.left + CELL_SIZE; + rc.top = 8 + y * CELL_SIZE; + rc.bottom = rc.top + CELL_SIZE; + + ::SetBkColor( hDC, RGB(m_Palette[x+y*16].rgbRed,m_Palette[x+y*16].rgbGreen,m_Palette[x+y*16].rgbBlue) ); + ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + + if( m_PaletteSelect == (x+y*16) ) { + ::DrawEdge( hDC, &rc, BDR_SUNKENOUTER, BF_RECT ); + } else { + ::DrawEdge( hDC, &rc, BDR_RAISEDOUTER, BF_RECT ); + } + } + } + + // BG/SP PALETTE + rc.left = xoffs; + rc.right = rc.left + CELL_SIZE; + for( int i = 0; i < 16; i++ ) { + rc.top = 8 + 8 + 4 * CELL_SIZE; + rc.bottom = rc.top + CELL_SIZE; + ::SetBkColor( hDC, RGB(m_Palette[m_BGPAL[i]].rgbRed,m_Palette[m_BGPAL[i]].rgbGreen,m_Palette[m_BGPAL[i]].rgbBlue) ); + ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + ::DrawEdge( hDC, &rc, BDR_RAISEDOUTER, BF_RECT ); + + rc.top += CELL_SIZE; + rc.bottom += CELL_SIZE; + ::SetBkColor( hDC, RGB(m_Palette[m_SPPAL[i]].rgbRed,m_Palette[m_SPPAL[i]].rgbGreen,m_Palette[m_SPPAL[i]].rgbBlue) ); + ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + ::DrawEdge( hDC, &rc, BDR_RAISEDOUTER, BF_RECT ); + + rc.left += CELL_SIZE; + rc.right += CELL_SIZE; + } + + ::EndPaint( hWnd, &ps ); + + return TRUE; +} + +DLGMSG CPaletteEdit::OnTimer( DLGMSGPARAM ) +{ + if( ::memcmp( m_BGPAL, BGPAL, 16 ) != 0 || ::memcmp( m_SPPAL, SPPAL, 16 ) != 0 ) { + ::memcpy( m_BGPAL, BGPAL, 16 ); + ::memcpy( m_SPPAL, SPPAL, 16 ); + + RECT rcC; + ::GetClientRect( m_hWnd, &rcC ); + rcC.bottom = 8 + 8 + CELL_V*CELL_SIZE + 2*CELL_SIZE; + + ::InvalidateRect( m_hWnd, &rcC, FALSE ); + } + + return TRUE; +} + +DLGCMD CPaletteEdit::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnOK\n" ); + ::DestroyWindow( m_hWnd ); +} + +DLGCMD CPaletteEdit::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnCancel\n" ); + ::DestroyWindow( m_hWnd ); +} + +DLGCMD CPaletteEdit::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnDefault\n" ); + + ::memcpy( m_Palette, m_PaletteDefault, sizeof(m_PaletteDefault) ); + ::memcpy( m_PaletteUndo, m_PaletteDefault, sizeof(m_PaletteDefault) ); + + OnChaneSelect(); +} + +DLGCMD CPaletteEdit::OnRGBChange( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnRGBChange\n" ); + + CHAR szColor[16]; + INT val = 0; + + ::GetWindowText( hWnd, szColor, sizeof(szColor)-1 ); + if( ::lstrlen(szColor) > 0 ) { + val = ::atoi(szColor); + if( val < 0 ) { + val = 0; + ::SetWindowText( hWnd, "0" ); + } else if( val > 255 ) { + val = 255; + ::SetWindowText( hWnd, "255" ); + } + } else { + val = 0; + ::SetWindowText( hWnd, "0" ); + } + + int nSlider = 0; + if( hWnd == ::GetDlgItem( m_hWnd, IDC_PAL_R_EDIT ) ) { + m_RGB.rgbRed = (BYTE)val; + nSlider = IDC_PAL_R_SLIDER; + } + if( hWnd == ::GetDlgItem( m_hWnd, IDC_PAL_G_EDIT ) ) { + m_RGB.rgbGreen = (BYTE)val; + nSlider = IDC_PAL_G_SLIDER; + } + if( hWnd == ::GetDlgItem( m_hWnd, IDC_PAL_B_EDIT ) ) { + m_RGB.rgbBlue = (BYTE)val; + nSlider = IDC_PAL_B_SLIDER; + } + + if( nSlider ) { + ::SendDlgItemMessage( m_hWnd, nSlider, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)val ); + + OnUpdateColor(); + } +} + +DLGCMD CPaletteEdit::OnUndo( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnUndo\n" ); + + ::memcpy( m_Palette, m_PaletteUndo, sizeof(m_Palette) ); + OnChaneSelect(); +} + +DLGCMD CPaletteEdit::OnLoad( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnLoad\n" ); + + CHAR szFile[ _MAX_PATH ]; + OPENFILENAME ofn; + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lpstrInitialDir = CApp::GetModulePath(); + szFile[0] = '\0'; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); +// ofn.lpstrDefExt = ".pal"; + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_OPENPALETTE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + + ofn.lpstrFilter = "Palette File(*.pal)\0*.pal\0All File(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST; + + if( ::GetOpenFileName( &ofn ) ) { + ::memcpy( m_PaletteUndo, m_Palette, sizeof(m_Palette) ); + + DirectDraw.SetPaletteFile( szFile ); + DirectDraw.GetPaletteTable( m_Palette ); + OnChaneSelect(); + } +} + +DLGCMD CPaletteEdit::OnSave( DLGCMDPARAM ) +{ +// DEBUGOUT( "CPaletteEdit::OnSave\n" ); + + CHAR szFile[ _MAX_PATH ]; + OPENFILENAME ofn; + ZEROMEMORY( &ofn, sizeof(ofn) ); + + ofn.lpstrInitialDir = CApp::GetModulePath(); + szFile[0] = '\0'; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = m_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + + ofn.lpstrDefExt = ".pal"; + + CHAR szTitle[256]; + CApp::LoadString( IDS_UI_SAVEPALETTE, szTitle, sizeof(szTitle) ); + ofn.lpstrTitle = szTitle; + + ofn.lpstrFilter = "Palette File(*.pal)\0*.pal\0All File(*.*)\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST; + ofn.Flags |= OFN_OVERWRITEPROMPT; + + if( ::GetSaveFileName( &ofn ) ) { + FILE* fp = NULL; + + if( (fp = ::fopen( szFile, "wb" )) ) { + for( int i = 0; i < 64; i++ ) { + ::fputc( (int)m_Palette[i].rgbRed, fp ); + ::fputc( (int)m_Palette[i].rgbGreen, fp ); + ::fputc( (int)m_Palette[i].rgbBlue, fp ); + } + ::fclose( fp ); + } + } +} + +void CPaletteEdit::OnChaneSelect() +{ +// DEBUGOUT( "CPaletteEdit::OnChaneSelect\n" ); + + m_RGB = m_Palette[m_PaletteSelect]; + + CHAR szStr[16]; + ::wsprintf( szStr, "%02X", m_PaletteSelect ); + ::SetDlgItemText( m_hWnd, IDC_PAL_NO, szStr ); + + ::wsprintf( szStr, "%d", m_RGB.rgbRed ); + ::SetDlgItemText( m_hWnd, IDC_PAL_R_EDIT, szStr ); + ::wsprintf( szStr, "%d", m_RGB.rgbGreen ); + ::SetDlgItemText( m_hWnd, IDC_PAL_G_EDIT, szStr ); + ::wsprintf( szStr, "%d", m_RGB.rgbBlue ); + ::SetDlgItemText( m_hWnd, IDC_PAL_B_EDIT, szStr ); + + OnUpdateColor(); + + ::InvalidateRect( m_hWnd, NULL, FALSE ); +} + +void CPaletteEdit::OnUpdateColor() +{ +// DEBUGOUT( "CPaletteEdit::OnUpdateColor\n" ); + + m_Palette[m_PaletteSelect] = m_RGB; + + DirectDraw.SetPaletteTable( m_Palette ); + + if( Emu.IsPausing() ) { + ::InvalidateRect( CApp::GetHWnd(), NULL, FALSE ); + } + + ::InvalidateRect( m_hWnd, NULL, FALSE ); +} diff --git a/References/VirtuaNESex_src_191105/PaletteEdit.h b/References/VirtuaNESex_src_191105/PaletteEdit.h new file mode 100644 index 00000000..fbf909ec --- /dev/null +++ b/References/VirtuaNESex_src_191105/PaletteEdit.h @@ -0,0 +1,71 @@ +// +// pbgGfB^NX +// +#ifndef __CPALETTEEDIT_INCLUDED__ +#define __CPALETTEEDIT_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CPaletteEdit : public CWnd +{ +public: + // Constructor/Destructor + CPaletteEdit(); + ~CPaletteEdit(); + + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnDestroy( DLGMSGPARAM ); + DLGMSG OnActivate( DLGMSGPARAM ); + DLGMSG OnLButtonDown( DLGMSGPARAM ); + DLGMSG OnRButtonDown( DLGMSGPARAM ); + DLGMSG OnHScroll( DLGMSGPARAM ); + DLGMSG OnPaint( DLGMSGPARAM ); + DLGMSG OnTimer( DLGMSGPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + + DLGCMD OnRGBChange( DLGCMDPARAM ); + DLGCMD OnUndo( DLGCMDPARAM ); + DLGCMD OnLoad( DLGCMDPARAM ); + DLGCMD OnSave( DLGCMDPARAM ); + // + + void OnChaneSelect(); + void OnUpdateColor(); + + INT m_PaletteSelect; + RGBQUAD m_RGB; + BYTE m_BGPAL[16]; + BYTE m_SPPAL[16]; + + enum { + CELL_SIZE = 22, + CELL_H = 16, + CELL_V = 4, + }; + + RGBQUAD m_Palette[256]; + RGBQUAD m_PaletteUndo[256]; + RGBQUAD m_PaletteDefault[256]; + + // + BOOL m_bShortCutDisable; +private: +}; + +#endif // !__CPALETTEEDIT_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/PaletteView.cpp b/References/VirtuaNESex_src_191105/PaletteView.cpp new file mode 100644 index 00000000..45424228 --- /dev/null +++ b/References/VirtuaNESex_src_191105/PaletteView.cpp @@ -0,0 +1,154 @@ +// +// p^[r[NX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "PaletteView.h" +#include "EmuThread.h" + +#include "MMU.h" + +#include "DirectDraw.h" + +WND_MESSAGE_BEGIN(CPaletteView) +WND_ON_MESSAGE( WM_CREATE, OnCreate ) +WND_ON_MESSAGE( WM_CLOSE, OnClose ) +WND_ON_MESSAGE( WM_DESTROY, OnDestroy ) +WND_ON_MESSAGE( WM_TIMER, OnTimer ) + +WND_COMMAND_BEGIN() +WND_COMMAND_END() +WND_MESSAGE_END() + +CPaletteView::CPaletteView() +{ + m_lpPattern = NULL; + if( !(m_lpPattern = (LPBYTE)::malloc( 256*32 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } +} + +CPaletteView::~CPaletteView() +{ + FREE( m_lpPattern ); +} + +BOOL CPaletteView::Create( HWND hWndParent ) +{ + HWND hWnd = CreateWindowEx( + WS_EX_TOOLWINDOW, + VIRTUANES_WNDCLASS, + "PaletteView", + WS_OVERLAPPEDWINDOW, // Windowgk”\ + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + hWndParent, + NULL, + CApp::GetInstance(), + (LPVOID)this // This 𖄂ߍވ + ); + if( !hWnd ) { + DEBUGOUT( "CreateWindow faild.\n" ); + return FALSE; + } + + m_hWnd = hWnd; + + // + ::ZeroMemory( &m_BitmapHdr, sizeof(m_BitmapHdr) ); + + m_BitmapHdr.bih.biSize = sizeof(BITMAPINFOHEADER); + m_BitmapHdr.bih.biWidth = 256; + m_BitmapHdr.bih.biHeight = -32; + m_BitmapHdr.bih.biPlanes = 1; + m_BitmapHdr.bih.biBitCount = 8; + m_BitmapHdr.bih.biCompression = BI_RGB; + m_BitmapHdr.bih.biClrUsed = 32; + + DirectDraw.GetPaletteData( m_Palette ); + + for( INT y = 0; y < 32; y++ ) { + for( INT x = 0; x < 256; x++ ) { + m_lpPattern[x+y*256] = (y>>4)*0x10+(x>>4); + } + } + + return TRUE; +} + +void CPaletteView::Destroy() +{ + if( m_hWnd && IsWindow(m_hWnd) ) { + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +WNDMSG CPaletteView::OnCreate( WNDMSGPARAM ) +{ + DEBUGOUT( "CPaletteView::OnCreate\n" ); + + // ʒuC + RECT rw, rc; + ::GetWindowRect( m_hWnd, &rw ); + ::GetClientRect( m_hWnd, &rc ); + INT x = rw.right - rw.left - rc.right + 256; + INT y = rw.bottom - rw.top - rc.bottom + 32; + ::MoveWindow( m_hWnd, Config.general.rcPaletteViewPos.left, Config.general.rcPaletteViewPos.top, x, y, FALSE ); + + ::SetTimer( m_hWnd, 1, 50, NULL ); + + ::ShowWindow( m_hWnd, SW_SHOW ); + return TRUE; +} + +WNDMSG CPaletteView::OnClose( WNDMSGPARAM ) +{ + DEBUGOUT( "CPaletteView::OnClose\n" ); + ::KillTimer( m_hWnd, 1 ); + ::DestroyWindow( m_hWnd ); + return TRUE; +} + +WNDMSG CPaletteView::OnDestroy( WNDMSGPARAM ) +{ + DEBUGOUT( "CPaletteView::OnDestroy\n" ); + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcPaletteViewPos ); + + m_hWnd = NULL; + return TRUE; +} + +WNDMSG CPaletteView::OnTimer( WNDMSGPARAM ) +{ + if( !Emu.IsRunning() ) + return TRUE; + + // pbg + for( INT i = 0; i < 16; i++ ) { + m_BitmapHdr.rgb[i] = m_Palette[BGPAL[i]]; + m_BitmapHdr.rgb[i+16] = m_Palette[SPPAL[i]]; + } + + RECT rc; + ::GetClientRect( hWnd, &rc ); + HDC hDC = ::GetDC( hWnd ); + ::StretchDIBits( hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 0, 0, 256, 32, m_lpPattern, (BITMAPINFO*)&m_BitmapHdr, DIB_RGB_COLORS, SRCCOPY ); + ::ReleaseDC( hWnd, hDC ); + + return TRUE; +} + diff --git a/References/VirtuaNESex_src_191105/PaletteView.h b/References/VirtuaNESex_src_191105/PaletteView.h new file mode 100644 index 00000000..6eb78605 --- /dev/null +++ b/References/VirtuaNESex_src_191105/PaletteView.h @@ -0,0 +1,46 @@ +// +// p^[r[NX +// +#ifndef __CPALETTEVIEW_INCLUDED__ +#define __CPALETTEVIEW_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CPaletteView : public CWnd +{ +public: + // Constructor/Destructor + CPaletteView(); + ~CPaletteView(); + + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + // Message map + WND_MESSAGE_MAP() + WNDMSG OnCreate( WNDMSGPARAM ); + WNDMSG OnClose( WNDMSGPARAM ); + WNDMSG OnDestroy( WNDMSGPARAM ); + WNDMSG OnTimer( WNDMSGPARAM ); + // + + struct BITMAPHDR { + BITMAPINFOHEADER bih; + RGBQUAD rgb[32]; + } m_BitmapHdr; + + // + RGBQUAD m_Palette[256]; + LPBYTE m_lpPattern; +private: +}; + +#endif // !__CPALETTEVIEW_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Pathlib.cpp b/References/VirtuaNESex_src_191105/Pathlib.cpp new file mode 100644 index 00000000..234ded48 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Pathlib.cpp @@ -0,0 +1,128 @@ +// +// pXCuNX +// +#include "Pathlib.h" + +string CPathlib::SplitPath( LPCSTR lpszPath ) +{ + CHAR szDrive[ _MAX_DRIVE ]; + CHAR szDir [ _MAX_DIR ]; + CHAR szTemp [ _MAX_PATH+1 ]; + string path; + ::_splitpath( lpszPath, szDrive, szDir, NULL, NULL ); + ::_makepath( szTemp, szDrive, szDir, NULL, NULL ); + path = szTemp; + return path; +} + +string CPathlib::SplitFname( LPCSTR lpszPath ) +{ + CHAR szTemp [ _MAX_PATH+1 ]; + string fname; + ::_splitpath( lpszPath, NULL, NULL, szTemp, NULL ); + fname = szTemp; + return fname; +} + +string CPathlib::SplitFnameExt( LPCSTR lpszPath ) +{ + CHAR szFname[ _MAX_FNAME ]; + CHAR szExt [ _MAX_EXT ]; + CHAR szTemp [ _MAX_PATH+1 ]; + string fname; + ::_splitpath( lpszPath, NULL, NULL, szFname, szExt ); + ::_makepath( szTemp, NULL, NULL, szFname, szExt ); + fname = szTemp; + return fname; +} + +string CPathlib::MakePath( LPCSTR lpszPath, LPCSTR lpszFname ) +{ + CHAR szDrive[ _MAX_DRIVE ]; + CHAR szDir [ _MAX_DIR ]; + CHAR szTemp [ _MAX_PATH+1 ]; + string path; + ::_splitpath( lpszPath, szDrive, szDir, NULL, NULL ); + ::_makepath( szTemp, szDrive, szDir, lpszFname, NULL ); + path = szTemp; + return path; +} + +string CPathlib::MakePathExt( LPCSTR lpszPath, LPCSTR lpszFname, LPCSTR lpszExt ) +{ + CHAR szDrive[ _MAX_DRIVE ]; + CHAR szDir [ _MAX_DIR ]; + CHAR szTemp [ _MAX_PATH+1 ]; + string path; + ::_splitpath( lpszPath, szDrive, szDir, NULL, NULL ); + ::_makepath( szTemp, szDrive, szDir, lpszFname, lpszExt ); + path = szTemp; + return path; +} + +string CPathlib::CreatePath( LPCSTR lpszBasePath, LPCSTR lpszPath ) +{ + CHAR szPath[ _MAX_PATH ]; + string path; + if( ::PathIsRelative( lpszPath ) ) { + CHAR szTemp[ _MAX_PATH ]; + ::strcpy( szTemp, lpszBasePath ); + ::PathAppend( szTemp, lpszPath ); + ::PathCanonicalize( szPath, szTemp ); + } else { + ::strcpy( szPath, lpszPath ); + } + path = szPath; + return path; +} + +INT CALLBACK CPathlib::BffCallback( HWND hWnd, UINT uMsg, LPARAM lParam, WPARAM wParam ) +{ + if( uMsg == BFFM_INITIALIZED && wParam ) { + ::SendMessage( hWnd, BFFM_SETSELECTION, TRUE, wParam ); + } + return TRUE; +} + +BOOL CPathlib::SelectFolder( HWND hWnd, LPCSTR lpszTitle, LPSTR lpszFolder ) +{ + BROWSEINFO bi; + LPITEMIDLIST pidl; + + ZeroMemory( &bi, sizeof(bi) ); + bi.hwndOwner = hWnd; + bi.lpszTitle = lpszTitle; + bi.ulFlags = BIF_RETURNONLYFSDIRS; + // For Folder setup + bi.lpfn = (BFFCALLBACK)BffCallback; + + // Ō'\'tĂƃftHgIĂȂ(Win98)̂... + if( lpszFolder ) { + if( ::strlen(lpszFolder) > 3 ) { + if( lpszFolder[::strlen(lpszFolder)-1] == '\\' ) + lpszFolder[::strlen(lpszFolder)-1] = NULL; + } + bi.lParam = (LPARAM)lpszFolder; + } else { + bi.lParam = NULL; + } + + string path; + if( (pidl = ::SHBrowseForFolder( &bi )) ) { + path.resize( _MAX_PATH+1 ); + ::SHGetPathFromIDList( pidl, lpszFolder ); + if( ::strlen(lpszFolder) > 3 ) { // hCȕꍇ + ::strcat( lpszFolder, "\\" ); + } + IMalloc* pMalloc; + ::SHGetMalloc( &pMalloc ); + if( pMalloc ) { + pMalloc->Free( pidl ); + pMalloc->Release(); + } + return TRUE; + } + + return FALSE; +} + diff --git a/References/VirtuaNESex_src_191105/Pathlib.h b/References/VirtuaNESex_src_191105/Pathlib.h new file mode 100644 index 00000000..31a536ec --- /dev/null +++ b/References/VirtuaNESex_src_191105/Pathlib.h @@ -0,0 +1,45 @@ +// +// pXCuNX +// +#ifndef __CPATHLIB_INCLUDED__ +#define __CPATHLIB_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +#include +using namespace std; + +class CPathlib +{ +public: + // pX{t@Cl[̃pX擾 + static string SplitPath( LPCSTR lpszPath ); + // pX{t@Cl[̃t@C擾(gqȂ) + static string SplitFname( LPCSTR lpszPath ); + // pX{t@Cl[̃t@C擾(gq) + static string SplitFnameExt( LPCSTR lpszPath ); + + // pXCt@C̃pX쐬(gq/Ȃp) + static string MakePath( LPCSTR lpszPath, LPCSTR lpszFname ); + // pXCt@CCgq̃pX쐬(gqʂɎw) + static string MakePathExt( LPCSTR lpszPath, LPCSTR lpszFname, LPCSTR lpszExt ); + + // x[XpXljpX̎ނ𒲂ׂăpX쐬 + // ljpX΃pXȂ΂̂܂܁C΃pXȂ΃x[XpXɒlj + static string CreatePath( LPCSTR lpszBasePath, LPCSTR lpszPath ); + + // tH_I + static BOOL SelectFolder( HWND hWnd, LPCSTR lpszTitle, LPSTR lpszFolder ); + +protected: + static INT CALLBACK BffCallback( HWND hWnd, UINT uMsg, LPARAM lParam, WPARAM wParam ); +private: +}; + +#endif // !__CPATHLIB_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/PatternView.cpp b/References/VirtuaNESex_src_191105/PatternView.cpp new file mode 100644 index 00000000..3b2c34d7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/PatternView.cpp @@ -0,0 +1,208 @@ +// +// p^[r[NX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +using namespace std; + +#include "typedef.h" +#include "macro.h" + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "PatternView.h" +#include "EmuThread.h" + +#include "MMU.h" + +#include "DirectDraw.h" + +WND_MESSAGE_BEGIN(CPatternView) +WND_ON_MESSAGE( WM_CREATE, OnCreate ) +WND_ON_MESSAGE( WM_CLOSE, OnClose ) +WND_ON_MESSAGE( WM_DESTROY, OnDestroy ) +WND_ON_MESSAGE( WM_LBUTTONDOWN, OnLButtonDown ) +WND_ON_MESSAGE( WM_TIMER, OnTimer ) + +WND_COMMAND_BEGIN() +WND_COMMAND_END() +WND_MESSAGE_END() + +CPatternView::CPatternView() +{ + m_lpPattern = NULL; + if( !(m_lpPattern = (LPBYTE)::malloc( 128*256 )) ) { + throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); + } + + for( INT i = 0; i < 8; i++ ) { + m_lpBank[i] = NULL; + } +} + +CPatternView::~CPatternView() +{ + FREE( m_lpPattern ); +} + +BOOL CPatternView::Create( HWND hWndParent ) +{ + HWND hWnd = CreateWindowEx( + WS_EX_TOOLWINDOW, + VIRTUANES_WNDCLASS, + "PatternView BG0", + WS_OVERLAPPEDWINDOW, // Windowgk”\ + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + hWndParent, + NULL, + CApp::GetInstance(), + (LPVOID)this // This 𖄂ߍވ + ); + if( !hWnd ) { + DEBUGOUT( "CreateWindow faild.\n" ); + return FALSE; + } + + m_hWnd = hWnd; + + for( INT i = 0; i < 8; i++ ) { + m_lpBank[i] = NULL; + } + + // + ZEROMEMORY( &m_BitmapHdr, sizeof(m_BitmapHdr) ); + + m_BitmapHdr.bih.biSize = sizeof(BITMAPINFOHEADER); + m_BitmapHdr.bih.biWidth = 128; + m_BitmapHdr.bih.biHeight = -256; + m_BitmapHdr.bih.biPlanes = 1; + m_BitmapHdr.bih.biBitCount = 8; + m_BitmapHdr.bih.biCompression = BI_RGB; + m_BitmapHdr.bih.biClrUsed = 16; + + DirectDraw.GetPaletteData( m_Palette ); + + m_SelectPal = 0; + + return TRUE; +} + +void CPatternView::Destroy() +{ + if( m_hWnd && IsWindow(m_hWnd) ) { + ::DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + +WNDMSG CPatternView::OnCreate( WNDMSGPARAM ) +{ + DEBUGOUT( "CPatternView::OnCreate\n" ); + + // ʒuC + RECT rw, rc; + ::GetWindowRect( m_hWnd, &rw ); + ::GetClientRect( m_hWnd, &rc ); + INT x = rw.right - rw.left - rc.right + 128; + INT y = rw.bottom - rw.top - rc.bottom + 256; + ::MoveWindow( m_hWnd, Config.general.rcPatternViewPos.left, Config.general.rcPatternViewPos.top, x, y, FALSE ); + + ::SetTimer( m_hWnd, 1, 50, NULL ); + + ::ShowWindow( m_hWnd, SW_SHOW ); + return TRUE; +} + +WNDMSG CPatternView::OnClose( WNDMSGPARAM ) +{ + DEBUGOUT( "CPatternView::OnClose\n" ); + ::KillTimer( m_hWnd, 1 ); + ::DestroyWindow( m_hWnd ); + return TRUE; +} + +WNDMSG CPatternView::OnDestroy( WNDMSGPARAM ) +{ + DEBUGOUT( "CPatternView::OnDestroy\n" ); + // ʒuۑ + ::GetWindowRect( m_hWnd, &Config.general.rcPatternViewPos ); + + m_hWnd = NULL; + return TRUE; +} + +WNDMSG CPatternView::OnLButtonDown( WNDMSGPARAM ) +{ + DEBUGOUT( "CPatternView::OnLButtonDown\n" ); + m_SelectPal = (m_SelectPal+1)&7; + + CHAR szTitle[256]; + if( m_SelectPal < 4 ) { + ::wsprintf( szTitle, "PatternView BG%01d", m_SelectPal&3 ); + } else { + ::wsprintf( szTitle, "PatternView SP%01d", m_SelectPal&3 ); + } + ::SetWindowText( m_hWnd, szTitle ); + + return TRUE; +} + +WNDMSG CPatternView::OnTimer( WNDMSGPARAM ) +{ + if( !Emu.IsRunning() ) + return TRUE; + + // pbg + LPBYTE pPAL = (m_SelectPal<4)?&BGPAL[m_SelectPal*4]:&SPPAL[(m_SelectPal&3)*4]; + m_BitmapHdr.rgb[0] = m_Palette[pPAL[0]]; + m_BitmapHdr.rgb[1] = m_Palette[pPAL[1]]; + m_BitmapHdr.rgb[2] = m_Palette[pPAL[2]]; + m_BitmapHdr.rgb[3] = m_Palette[pPAL[3]]; + + // LN^f[^XV + for( INT i = 0; i < 8; i++ ) { + // XVꂽoN̂݃LN^XV + if( m_lpBank[i] != PPU_MEM_BANK[i] || PPU_MEM_TYPE[i] == BANKTYPE_CRAM || PPU_MEM_TYPE[i] == BANKTYPE_YCRAM ) { + m_lpBank[i] = PPU_MEM_BANK[i]; + + LPBYTE lpPtn = PPU_MEM_BANK[i]; + for( INT p = 0; p < 64; p++ ) { + LPBYTE lpScn = &m_lpPattern[i*32*128+(p&15)*8+(p/16)*8*128]; + for( INT y = 0; y < 8; y++ ) { + BYTE chr_l = lpPtn[y]; + BYTE chr_h = lpPtn[y+8]; + lpScn[0] = ((chr_h>>6)&2)|((chr_l>>7)&1); + lpScn[4] = ((chr_h>>2)&2)|((chr_l>>3)&1); + lpScn[1] = ((chr_h>>5)&2)|((chr_l>>6)&1); + lpScn[5] = ((chr_h>>1)&2)|((chr_l>>2)&1); + lpScn[2] = ((chr_h>>4)&2)|((chr_l>>5)&1); + lpScn[6] = ((chr_h>>0)&2)|((chr_l>>1)&1); + lpScn[3] = ((chr_h>>3)&2)|((chr_l>>4)&1); + lpScn[7] = ((chr_h<<1)&2)|((chr_l>>0)&1); + // Next line + lpScn+=128; + } + // Next pattern + lpPtn+=16; + } + } + } + + RECT rc; + ::GetClientRect( hWnd, &rc ); + HDC hDC = ::GetDC( hWnd ); + ::StretchDIBits( hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 0, 0, 128, 256, m_lpPattern, (BITMAPINFO*)&m_BitmapHdr, DIB_RGB_COLORS, SRCCOPY ); + ::ReleaseDC( hWnd, hDC ); + + return TRUE; +} + diff --git a/References/VirtuaNESex_src_191105/PatternView.h b/References/VirtuaNESex_src_191105/PatternView.h new file mode 100644 index 00000000..57ec86d3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/PatternView.h @@ -0,0 +1,49 @@ +// +// p^[r[NX +// +#ifndef __CPATTERNVIEW_INCLUDED__ +#define __CPATTERNVIEW_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CPatternView : public CWnd +{ +public: + // Constructor/Destructor + CPatternView(); + ~CPatternView(); + + // Override from CWnd + BOOL Create( HWND hWndParent ); + void Destroy(); + +protected: + // Message map + WND_MESSAGE_MAP() + WNDMSG OnCreate( WNDMSGPARAM ); + WNDMSG OnClose( WNDMSGPARAM ); + WNDMSG OnDestroy( WNDMSGPARAM ); + WNDMSG OnLButtonDown( WNDMSGPARAM ); + WNDMSG OnTimer( WNDMSGPARAM ); + // + + struct BITMAPHDR { + BITMAPINFOHEADER bih; + RGBQUAD rgb[16]; + } m_BitmapHdr; + + // + INT m_SelectPal; + RGBQUAD m_Palette[256]; + LPBYTE m_lpBank[8]; + LPBYTE m_lpPattern; +private: +}; + +#endif // !__CPATTERNVIEW_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Plugin.cpp b/References/VirtuaNESex_src_191105/Plugin.cpp new file mode 100644 index 00000000..c775861b --- /dev/null +++ b/References/VirtuaNESex_src_191105/Plugin.cpp @@ -0,0 +1,85 @@ +// +// Language plugin support +// +#include "VirtuaNESres.h" + +#include "Pathlib.h" +#include "DebugOut.h" + +#include "Plugin.h" + +typedef INT (__cdecl *GETVLPVERSION)(); +typedef void (__cdecl *GETVLPLANGUAGE)( LPSTR ); +typedef LCID (__cdecl *GETVLPLOCALEID)(); + +INT CPlugin::m_PluginID = 0; +INT CPlugin::m_PluginNum = 0; +CPlugin::PLUGIN CPlugin::m_Plugin[PLUGIN_MAX]; + +HINSTANCE CPlugin::LoadPlugin() +{ + return LoadPluginID( m_PluginID ); +} + +HINSTANCE CPlugin::LoadPluginID( INT nID ) +{ + return ::LoadLibrary( m_Plugin[nID].Path ); +} + +BOOL CPlugin::FindPlugin( LPCSTR lpModulePath ) +{ + m_PluginNum = 0; + + string Path = CPathlib::MakePath( lpModulePath, "*.vlp" ); + + WIN32_FIND_DATA find; + HANDLE hFind = ::FindFirstFile( Path.c_str(), &find ); + if( hFind == INVALID_HANDLE_VALUE ) + return FALSE; + + HINSTANCE hDLL; + GETVLPVERSION GetVlpVersion = NULL; + GETVLPLANGUAGE GetVlpLanguage = NULL; + GETVLPLOCALEID GetVlpLocaleID = NULL; + + BOOL bFind = TRUE; + while( bFind ) { + if( (hDLL = ::LoadLibrary( find.cFileName )) ) { + GetVlpVersion = (GETVLPVERSION) ::GetProcAddress( hDLL, "GetVlpVersion" ); + GetVlpLanguage = (GETVLPLANGUAGE)::GetProcAddress( hDLL, "GetVlpLanguage" ); + GetVlpLocaleID = (GETVLPLOCALEID)::GetProcAddress( hDLL, "GetVlpLocaleID" ); + + if( !(!GetVlpVersion || !GetVlpLanguage || !GetVlpLocaleID) ) { + INT ver = GetVlpVersion(); + + if( ver >= VIRTUANES_PLUGIN_VERSION ) { + m_Plugin[m_PluginNum].LocaleID = GetVlpLocaleID(); + string Path = CPathlib::MakePath( lpModulePath, find.cFileName ); + ::strcpy( m_Plugin[m_PluginNum].Path, Path.c_str() ); + GetVlpLanguage( m_Plugin[m_PluginNum].Language ); + m_PluginNum++; + } + } + + ::FreeLibrary( hDLL ); + } + + bFind = ::FindNextFile( hFind, &find ); + + if( m_PluginNum >= PLUGIN_MAX ) + break; + } + + ::FindClose( hFind ); + + LCID lcid = ::GetUserDefaultLCID(); + for( INT no = 0; no < m_PluginNum; no++ ) { + if( m_Plugin[no].LocaleID == lcid ) { + m_PluginID = no; + return TRUE; + } + } + + return TRUE; +} + diff --git a/References/VirtuaNESex_src_191105/Plugin.h b/References/VirtuaNESex_src_191105/Plugin.h new file mode 100644 index 00000000..1048c74a --- /dev/null +++ b/References/VirtuaNESex_src_191105/Plugin.h @@ -0,0 +1,54 @@ +// +// Language Plugin support +// +#ifndef __CPLUGIN_INCLUDED__ +#define __CPLUGIN_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include +using namespace std; + +#define PLUGIN_MAX 64 + +class CPlugin +{ +public: + typedef struct tagPLUGIN { + LCID LocaleID; + CHAR Path[_MAX_PATH]; + CHAR Language[256]; + } PLUGIN, *LPPLUGIN; + + static HINSTANCE LoadPlugin(); + static HINSTANCE LoadPluginID( INT nID ); + + static BOOL FindPlugin( LPCSTR lpModulePath ); + + static INT GetPluginNum() { return m_PluginNum; } + static INT GetPluginID() { return m_PluginID; } + static void SetPluginID( INT nID ) { m_PluginID = nID; } + + // ftHgvOC + static LPCSTR GetPluginPath() { return m_Plugin[m_PluginID].Path; } + static LPCSTR GetPluginLanguage() { return m_Plugin[m_PluginID].Language; } + static LCID GetPluginLocaleID() { return m_Plugin[m_PluginID].LocaleID; } + + // vOCIDw + static LPCSTR GetPluginPath( INT nID ) { return m_Plugin[nID].Path; } + static LPCSTR GetPluginLanguage( INT nID ) { return m_Plugin[nID].Language; } + static LCID GetPluginLocaleID( INT nID ) { return m_Plugin[nID].LocaleID; } + + +protected: + static INT m_PluginID; + static INT m_PluginNum; + static PLUGIN m_Plugin[PLUGIN_MAX]; + +private: +}; + +#endif // !__CPLUGIN_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/Pngwrite.h b/References/VirtuaNESex_src_191105/Pngwrite.h new file mode 100644 index 00000000..38f46220 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Pngwrite.h @@ -0,0 +1,154 @@ +#ifndef __PNGWRITE_INCLUDED__ +#define __PNGWRITE_INCLUDED__ + +#include +#include +#include "zlib.h" +#include "typedef.h" +#include "macro.h" + +class PNGWRITE +{ +public: + bool Write( const char* fname, INT nWidth, INT nHeight, RGBQUAD* pRGB, LPBYTE lpBitmap, DWORD dwScan ) + { + FILE* fp = NULL; + LPBYTE pBits = NULL; + LPBYTE pZbuf = NULL; + unsigned long zlibbuffersize; + INT i; + + if( !(fp = ::fopen( fname, "wb" )) ) + goto error_exit; + + if( !WriteSignature( fp ) ) + goto error_exit; + + if( !(pBits = (LPBYTE)::malloc( (nWidth+1)*nHeight*sizeof(BYTE) )) ) + goto error_exit; + + LPBYTE pSrc, pDst; + pSrc = lpBitmap; + pDst = pBits; + + // No Filter + for( i = 0; i < nHeight; i++ ) { + *(pDst++) = 0; + ::memcpy( pDst, pSrc, nWidth ); + pSrc += dwScan; + pDst += nWidth; + } + + zlibbuffersize = ((nWidth+1)*nHeight)*1.1+12; + if( !(pZbuf = (LPBYTE)::malloc( zlibbuffersize )) ) + goto error_exit; + + if( compress( pZbuf, &zlibbuffersize, pBits, ((nWidth+1)*nHeight) ) != Z_OK ) + goto error_exit; + + // write IHDR + { + BYTE temp[13]; + + // Write Length + ConvertNetworkOrder( nWidth, temp ); + ConvertNetworkOrder( nHeight, temp+4 ); + *(temp+ 8) = 8; // 8bpp + *(temp+ 9) = 3; // Indexed color + *(temp+10) = 0; // Compression method + *(temp+11) = 0; // Filter method + *(temp+12) = 0; // Interace method + + if( !WriteChunk( fp, PNG_CHUNK_IHDR, temp, 13 ) ) + goto error_exit; + } + + // write PLTE + { + BYTE pal[256*3]; + for( INT i = 0; i < 256; i++ ) { + pal[i*3+0] = pRGB[i].rgbRed; + pal[i*3+1] = pRGB[i].rgbGreen; + pal[i*3+2] = pRGB[i].rgbBlue; + } + + if( !WriteChunk( fp, PNG_CHUNK_PLTE, pal, 256*3 ) ) + goto error_exit; + } + + // write IDAT + if( !WriteChunk( fp, PNG_CHUNK_IDAT, pZbuf, zlibbuffersize ) ) + goto error_exit; + + // write IEND + if( !WriteChunk( fp, PNG_CHUNK_IEND, NULL, 0 ) ) + goto error_exit; + + FREE( pBits ); + FREE( pZbuf ); + FCLOSE( fp ); + return true; + error_exit: + FREE( pBits ); + FREE( pZbuf ); + FCLOSE( fp ); + return false; + } + +protected: + void ConvertNetworkOrder( UINT uData, BYTE* pBuf ) + { + pBuf[0] = (BYTE)(uData>>24); + pBuf[1] = (BYTE)(uData>>16); + pBuf[2] = (BYTE)(uData>>8); + pBuf[3] = (BYTE)(uData); + } + + bool WriteSignature( FILE* fp ) + { + const char PNG_SIGNATURE[] = { "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A" }; + + if( ::fwrite( PNG_SIGNATURE, 8, 1, fp ) != 1 ) + return false; + return true; + } + + bool WriteChunk( FILE* fp, UINT uType, BYTE* pData, UINT uLength ) + { + BYTE temp[4]; + + // Write Length + ConvertNetworkOrder( uLength, temp ); + if( ::fwrite( temp, sizeof(temp), 1, fp ) != 1 ) + return false; + + // Write Chunk Type + ConvertNetworkOrder( uType, temp ); + if( ::fwrite( temp, sizeof(temp), 1, fp ) != 1 ) + return false; + + UINT crc = crc32( 0, temp, sizeof(temp) ); + if( uLength ) { + if( ::fwrite( pData, uLength, 1, fp ) != 1 ) + return false; + + crc = crc32( crc, pData, uLength ); + } + + // Write CRC32 + ConvertNetworkOrder( crc, temp ); + if( ::fwrite( temp, sizeof(temp), 1, fp ) != 1 ) + return false; + + return true; + } +private: + enum { + PNG_CHUNK_IHDR = 0x49484452, + PNG_CHUNK_PLTE = 0x504C5445, + PNG_CHUNK_IDAT = 0x49444154, + PNG_CHUNK_IEND = 0x49454E44, + }; +}; + +#endif // !__PNGWRITE_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/Recent.cpp b/References/VirtuaNESex_src_191105/Recent.cpp new file mode 100644 index 00000000..3a2f1483 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Recent.cpp @@ -0,0 +1,245 @@ +// +// Recent File NX +// +#include + +#include "DebugOut.h" +#include "PathLib.h" + +#include "VirtuaNESres.h" +#include "Recent.h" + +CHAR CRecent::m_RecentName[RECENT_MAX][_MAX_PATH]; +CHAR CRecent::m_RecentPath[RECENT_MAX][_MAX_PATH]; +CHAR CRecent::m_TempPath[_MAX_PATH]; + +LPCSTR CRecent::GetName( INT nID ) +{ + // CRecent::Add œ|C^wĖ߂Ă鎖̂ňUe|ɃRs[ + ::strcpy( m_TempPath, m_RecentName[nID] ); + return (LPCSTR)m_TempPath; +} + +LPCSTR CRecent::GetPath( INT nID ) +{ + return (LPCSTR)m_RecentPath[nID]; +} + +void CRecent::MakeManuPath( LPSTR lpszPath ) +{ + string FullPath = lpszPath; + string FileName = CPathlib::SplitFnameExt( lpszPath ); + + // 30ȉ͂̂܂ + if( FullPath.size() <= 30 ) + return; + + // t@C30ȏ̏ꍇ + if( ::strlen( FileName.c_str() ) >= 30 ) { + ::strcpy( lpszPath, FileName.c_str() ); + return; + } + + LPCSTR lpszCur = lpszPath + 2; + if( lpszPath[0] == '\\' && lpszPath[1] == '\\' ) { + while (*lpszCur != '\\') { + lpszCur = _tcsinc(lpszCur); + } + } + + if( ::strlen(FullPath.c_str()) - ::strlen(FileName.c_str()) > 3 ) { + lpszCur = _tcsinc(lpszCur); + while( *lpszCur != '\\' ) { + lpszCur = _tcsinc(lpszCur); + } + } + + INT nVolume = lpszCur - lpszPath; + if( 30 < nVolume+5+::strlen(FileName.c_str()) ) { + ::strcpy( lpszPath, FileName.c_str() ); + return; + } + + while ( nVolume+4+::strlen(lpszCur) > 30 ) { + do { + lpszCur = _tcsinc(lpszCur); + } + while( *lpszCur != '\\' ); + } + + lpszPath[nVolume] = '\0'; + ::strcat( lpszPath, "\\..." ); + ::strcat( lpszPath, lpszCur ); +} + +void CRecent::UpdateMenu( HMENU hMenu ) +{ + // j[ȂH + if( !hMenu ) + return; + + // ̧(&F)j[̎擾 + HMENU hSubMenu = ::GetSubMenu( hMenu, 0 ); + + // ŋߎg̫(&P)|bvAbvj[̎擾 + HMENU hPathMenu = ::GetSubMenu( hSubMenu, 12 ); + // ŋߎģ(&F)|bvAbvj[̎擾 + HMENU hFileMenu = ::GetSubMenu( hSubMenu, 13 ); + + // ڂꍇ + if( ::strlen(m_RecentPath[0]) <= 0 ) { + // fBZ[uɂ + ::EnableMenuItem( hPathMenu, ID_MRU_PATH0, MF_BYCOMMAND|MF_GRAYED ); + } else { + INT i; + // j[ACe̍폜 + for( i = 0; i < RECENT_MAX; i++ ) { + ::DeleteMenu( hPathMenu, ID_MRU_PATH0+i, MF_BYCOMMAND ); + } + + CHAR szRecent[_MAX_PATH]; + CHAR szTemp[_MAX_PATH]; + for( i = 0; i < RECENT_MAX; i++ ) { + if( ::strlen(m_RecentPath[i]) > 0 ) { + // pXj[pɒZ肷 + ::strcpy( szRecent, m_RecentPath[i] ); + + // '&'t̃t@C'&''&&'ɕϊ + LPCSTR pSrc = szRecent; + LPSTR pDst = szTemp; + while( *pSrc != 0 ) { + if( *pSrc == '&' ) + *pDst++ = '&'; + if( _istlead(*pSrc) ) + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + } + *pDst = 0; + ::wsprintf( szRecent, "&%d ", (i+1)%10 ); + ::strcat( szRecent, szTemp ); + + // j[ɒlj + ::InsertMenu( hPathMenu, i, MF_BYPOSITION, ID_MRU_PATH0+i, szRecent ); + } else { + break; + } + } + } + + // ڂꍇ + if( ::strlen(m_RecentName[0]) <= 0 ) { + // fBZ[uɂ + ::EnableMenuItem( hFileMenu, ID_MRU_FILE0, MF_BYCOMMAND|MF_GRAYED ); + } else { + INT i; + // j[ACe̍폜 + for( i = 0; i < RECENT_MAX; i++ ) { + ::DeleteMenu( hFileMenu, ID_MRU_FILE0+i, MF_BYCOMMAND ); + } + + CHAR szRecent[_MAX_PATH]; + CHAR szTemp[_MAX_PATH]; + for( i = 0; i < RECENT_MAX; i++ ) { + if( ::strlen(m_RecentName[i]) > 0 ) { + // pXj[pɒZ肷 + ::strcpy( szRecent, m_RecentName[i] ); + MakeManuPath( szRecent ); + + // '&'t̃t@C'&''&&'ɕϊ + LPCSTR pSrc = szRecent; + LPSTR pDst = szTemp; + while( *pSrc != 0 ) { + if( *pSrc == '&' ) + *pDst++ = '&'; + if( _istlead(*pSrc) ) + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + } + *pDst = 0; + ::wsprintf( szRecent, "&%d ", (i+1)%10 ); + ::strcat( szRecent, szTemp ); + + // j[ɒlj + ::InsertMenu( hFileMenu, i, MF_BYPOSITION, ID_MRU_FILE0+i, szRecent ); + } else { + break; + } + } + } +} + +void CRecent::Add( LPCSTR lpszPath ) +{ + INT i, j; + + if( ::strlen(m_RecentName[0]) > 0 ) { + for( i = 0; i < RECENT_MAX; i++ ) { + if( ::strlen(m_RecentName[i]) <= 0 ) + break; + } + for( j = 0; j < i; j++ ) { + if( ::strcmp( lpszPath, m_RecentName[j] ) == 0 ) + break; + } + if( j == RECENT_MAX ) + j--; + for( ; j > 0; j-- ) { + ::strcpy( &m_RecentName[j][0], &m_RecentName[j-1][0] ); + } + } + ::strcpy( m_RecentName[0], lpszPath ); + + string temp = CPathlib::SplitPath( lpszPath ); + if( ::strlen(m_RecentPath[0]) > 0 ) { + for( i = 0; i < RECENT_MAX; i++ ) { + if( ::strlen(m_RecentPath[i]) <= 0 ) + break; + } + for( j = 0; j < i; j++ ) { + if( ::strcmp( m_RecentPath[j], temp.c_str() ) == 0 ) + break; + } + if( j == RECENT_MAX ) + j--; + for( ; j > 0; j-- ) { + ::strcpy( m_RecentPath[j], m_RecentPath[j-1] ); + } + } + ::strcpy( m_RecentPath[0], temp.c_str() ); +} + +void CRecent::Load() +{ + INT i; + CHAR szTemp[MAX_PATH]; + CHAR szEntry[32]; + for( i = 0; i < RECENT_MAX; i++ ) { + ::wsprintf( szEntry, "Path%d", i+1 ); + if( CRegistry::GetProfileString( "Recent Path List", szEntry, szTemp, sizeof(szTemp) ) ) + ::strcpy( m_RecentPath[i], szTemp ); + } + for( i = 0; i < RECENT_MAX; i++ ) { + ::wsprintf( szEntry, "File%d", i+1 ); + if( CRegistry::GetProfileString( "Recent File List", szEntry, szTemp, sizeof(szTemp) ) ) + ::strcpy( m_RecentName[i], szTemp ); + } +} + +void CRecent::Save() +{ + INT i; + CHAR szEntry[32]; + for( i = 0; i < RECENT_MAX; i++ ) { + if( ::strlen(m_RecentPath[i]) > 0 ) { + ::wsprintf( szEntry, "Path%d", i+1 ); + CRegistry::WriteProfileString( "Recent Path List", szEntry, m_RecentPath[i] ); + } + } + for( i = 0; i < RECENT_MAX; i++ ) { + if( ::strlen(m_RecentName[i]) > 0 ) { + ::wsprintf( szEntry, "File%d", i+1 ); + CRegistry::WriteProfileString( "Recent File List", szEntry, m_RecentName[i] ); + } + } +} + diff --git a/References/VirtuaNESex_src_191105/Recent.h b/References/VirtuaNESex_src_191105/Recent.h new file mode 100644 index 00000000..a1fe5f2c --- /dev/null +++ b/References/VirtuaNESex_src_191105/Recent.h @@ -0,0 +1,42 @@ +// +// Recent File NX +// +#ifndef __CRECENT_INCLUDED__ +#define __CRECENT_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include +using namespace std; + +#include "Pathlib.h" +#include "Registry.h" + +class CRecent +{ +public: + static LPCSTR GetName( INT nID ); + static LPCSTR GetPath( INT nID ); + + static void UpdateMenu( HMENU hMenu ); + static void Add( LPCSTR lpszPath ); + + static void Load(); + static void Save(); + +protected: + enum { RECENT_MAX=10 }; + static CHAR m_RecentName[RECENT_MAX][_MAX_PATH]; + static CHAR m_RecentPath[RECENT_MAX][_MAX_PATH]; + static CHAR m_TempPath[_MAX_PATH]; + + // Helper + static void MakeManuPath( LPSTR lpszPath ); +private: +}; + +#endif // !__CRECENT_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Registry.cpp b/References/VirtuaNESex_src_191105/Registry.cpp new file mode 100644 index 00000000..a973b775 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Registry.cpp @@ -0,0 +1,186 @@ +// +// WXgT|[gNX +// + +#include "DebugOut.h" +#include "Registry.h" + +#include "App.h" +#include "Pathlib.h" + +#define INI_USE + +CHAR CRegistry::m_szRegistryKey[MAX_PATH] = { "App" }; + +void CRegistry::SetRegistryKey( LPCTSTR lpszKey ) +{ +#ifndef INI_USE + if( lpszKey ) { + ::_tcscpy( m_szRegistryKey, lpszKey ); + } +#else + string str; + str = CApp::GetModulePath(); + str += lpszKey; + + ::_tcscpy( m_szRegistryKey, str.c_str() ); +#endif +} + +HKEY CRegistry::GetRegistryKey() +{ + HKEY hAppKey = NULL; + HKEY hSoftKey = NULL; + if( ::RegOpenKeyEx(HKEY_CURRENT_USER, _T("software"), 0, KEY_WRITE|KEY_READ, &hSoftKey) == ERROR_SUCCESS ) { + DWORD dw; + ::RegCreateKeyEx( hSoftKey, m_szRegistryKey, 0, REG_NONE, + REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hAppKey, &dw); + } + if( hSoftKey ) + ::RegCloseKey( hSoftKey ); + return hAppKey; +} + +HKEY CRegistry::GetSectionKey( LPCTSTR lpszSection ) +{ + HKEY hAppKey = GetRegistryKey(); + if( !hAppKey ) + return NULL; + HKEY hSectionKey = NULL; + DWORD dw; + ::RegCreateKeyEx( hAppKey, lpszSection, 0, REG_NONE, + REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hSectionKey, &dw ); + ::RegCloseKey( hAppKey ); + + return hSectionKey; +} + +UINT CRegistry::GetProfileInt( LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nDefault ) +{ +#ifndef INI_USE + HKEY hSecKey = GetSectionKey( lpszSection ); + if( !hSecKey ) + return nDefault; + DWORD dwValue; + DWORD dwType; + DWORD dwCount = sizeof(DWORD); + LONG lResult = ::RegQueryValueEx( hSecKey, (LPTSTR)lpszEntry, NULL, &dwType, (LPBYTE)&dwValue, &dwCount ); + ::RegCloseKey( hSecKey ); + + return (lResult==ERROR_SUCCESS)?(UINT)dwValue:nDefault; +#else + return ::GetPrivateProfileInt( lpszSection, lpszEntry, nDefault, m_szRegistryKey ); +#endif +} + +BOOL CRegistry::GetProfileString( LPCSTR lpszSection, LPCSTR lpszEntry, LPVOID lpData, UINT nBytes ) +{ +#ifndef INI_USE + HKEY hSecKey = GetSectionKey( lpszSection ); + if( !hSecKey ) + return lpszDefault; + + DWORD dwType, dwCount; + LONG lResult = ::RegQueryValueEx( hSecKey, (LPTSTR)lpszEntry, NULL, &dwType, NULL, &dwCount ); + if( dwCount > nBytes ) { + ::RegCloseKey( hSecKey ); + return FALSE; + } + + if( lResult == ERROR_SUCCESS ) { + lResult = ::RegQueryValueEx( hSecKey, (LPTSTR)lpszEntry, NULL, &dwType, lpData, &dwCount ); + } + ::RegCloseKey( hSecKey ); + + return (lResult==ERROR_SUCCESS)?TRUE:FALSE; +#else + DWORD dw = ::GetPrivateProfileString( lpszSection, lpszEntry, "", (CHAR*)lpData, nBytes, m_szRegistryKey ); + return (dw&&(dw nBytes ) { + ::RegCloseKey( hSecKey ); + return FALSE; + } + if( lResult == ERROR_SUCCESS ) { + lResult = ::RegQueryValueEx( hSecKey, (LPTSTR)lpszEntry, NULL, &dwType, lpData, &dwCount ); + } + ::RegCloseKey( hSecKey ); + + return (lResult==ERROR_SUCCESS)?TRUE:FALSE; +#else + return ::GetPrivateProfileStruct( lpszSection, lpszEntry, lpData, nBytes, m_szRegistryKey ); +#endif +} + +BOOL CRegistry::WriteProfileInt( LPCSTR lpszSection, LPCSTR lpszEntry, INT nValue ) +{ +#ifndef INI_USE + HKEY hSecKey = GetSectionKey( lpszSection ); + if( !hSecKey ) + return FALSE; + LONG lResult = ::RegSetValueEx(hSecKey, lpszEntry, NULL, REG_DWORD, + (LPBYTE)&nValue, sizeof(nValue)); + ::RegCloseKey( hSecKey ); + return (lResult == ERROR_SUCCESS); +#else + CHAR szTemp[16]; + wsprintf( szTemp, "%d", nValue ); + return ::WritePrivateProfileString( lpszSection, lpszEntry, szTemp, m_szRegistryKey ); +#endif +} + +BOOL CRegistry::WriteProfileString( LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszValue ) +{ +#ifndef INI_USE + LONG lResult; + if( !lpszEntry ) { + HKEY hAppKey = GetRegistryKey(); + if( !hAppKey ) + return FALSE; + lResult = ::RegDeleteKey( hAppKey, lpszSection ); + ::RegCloseKey( hAppKey ); + } else if( !lpszValue ) { + HKEY hSecKey = GetSectionKey( lpszSection ); + if( !hSecKey ) + return FALSE; + lResult = ::RegDeleteValue( hSecKey, (LPTSTR)lpszEntry ); + ::RegCloseKey( hSecKey ); + } else { + HKEY hSecKey = GetSectionKey( lpszSection ); + if( !hSecKey ) + return FALSE; + lResult = ::RegSetValueEx(hSecKey, lpszEntry, NULL, REG_SZ, + (LPBYTE)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR)); + ::RegCloseKey( hSecKey ); + } + return (lResult == ERROR_SUCCESS); +#else + return ::WritePrivateProfileString( lpszSection, lpszEntry, lpszValue, m_szRegistryKey ); +#endif +} + +BOOL CRegistry::WriteProfileBinary( LPCSTR lpszSection, LPCSTR lpszEntry, LPVOID lpData, UINT nBytes ) +{ +#ifndef INI_USE + HKEY hSecKey = GetSectionKey( lpszSection ); + if( !hSecKey ) + return FALSE; + LONG lResult = ::RegSetValueEx(hSecKey, lpszEntry, NULL, REG_BINARY, lpData, nBytes ); + ::RegCloseKey( hSecKey ); + return (lResult == ERROR_SUCCESS); +#else + return ::WritePrivateProfileStruct( lpszSection, lpszEntry, lpData, nBytes, m_szRegistryKey ); +#endif +} + diff --git a/References/VirtuaNESex_src_191105/Registry.h b/References/VirtuaNESex_src_191105/Registry.h new file mode 100644 index 00000000..745abec2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Registry.h @@ -0,0 +1,37 @@ +// +// WXgT|[gNX +// +#ifndef __CREGISTRY_INCLUDED__ +#define __CREGISTRY_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include +using namespace std; + +class CRegistry +{ +public: + static void SetRegistryKey( LPCSTR lpszKey ); + + static UINT GetProfileInt ( LPCSTR lpszSection, LPCSTR lpszEntry, INT nDefault ); + static BOOL GetProfileString( LPCSTR lpszSection, LPCSTR lpszEntry, LPVOID lpData, UINT nBytes ); + static BOOL GetProfileBinary( LPCSTR lpszSection, LPCSTR lpszEntry, LPVOID lpData, UINT nBytes ); + + static BOOL WriteProfileInt( LPCSTR lpszSection, LPCSTR lpszEntry, INT nValue ); + static BOOL WriteProfileString( LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszValue ); + static BOOL WriteProfileBinary( LPCSTR lpszSection, LPCSTR lpszEntry, LPVOID pData, UINT nBytes ); + +protected: + static CHAR m_szRegistryKey[MAX_PATH]; + + static HKEY GetRegistryKey(); + static HKEY GetSectionKey( LPCTSTR lpszSection ); + +private: +}; + +#endif // !__CREGISTRY_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/Release/Chinese.vlp b/References/VirtuaNESex_src_191105/Release/Chinese.vlp new file mode 100644 index 00000000..34d05cdc Binary files /dev/null and b/References/VirtuaNESex_src_191105/Release/Chinese.vlp differ diff --git a/References/VirtuaNESex_src_191105/Release/VirtuaNESex.ini b/References/VirtuaNESex_src_191105/Release/VirtuaNESex.ini new file mode 100644 index 00000000..91288d61 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Release/VirtuaNESex.ini @@ -0,0 +1,222 @@ +[Path] +RomAutoRunPath=.\ +RomPathUse=1 +SavePathUse=1 +StatePathUse=1 +SnapshotPathUse=1 +MoviePathUse=1 +WavePathUse=1 +CheatPathUse=1 +RomPath=.\roms\ +SavePath=.\save\ +StatePath=.\state\ +SnapshotPath=.\snapshot\ +MoviePath=.\movie\ +WavePath=.\wave\ +CheatPath=.\cheatcode\ +[General] +DoubleExecute=1 +StartupLauncher=0 +WindowZoom=0 +WindowPos=6A020000E10000007E04000000030000D2 +ScreenZoom=1 +SearchDialogPos=0000000000000000000000000000000000 +PatternViewPos=220200007A010000B2020000A1020000F6 +NameTableViewPos=CE000000C5000000DE020000CC02000041 +PaletteViewPos=0000000000000000000000000000000000 +MemoryViewPos=0000000000000000000000000000000000 +BarcodePos=0000000000000000000000000000000000 +PaletteEditPos=1E0300005001000061040000BF02000098 +JoyAxisDisable=0 +JoyAxisSetting=000000000000000000000000000000000000000000000000000000000000000000 +[Emulation] +IllegalOp=0 +AutoFrameSkip=1 +Throttle=1 +ThrottleFPS=120 +Background=0 +Priority=3 +FourPlayer=1 +CrcCheck=1 +DiskThrottle=1 +LoadFullscreen=0 +PNGsnapshot=0 +[Graphics] +Aspect=0 +SpriteMax=1 +AllLine=1 +FPSDisp=0 +TVFrameMode=0 +ScanlineMode=0 +ScanlineColor=75 +SyncDraw=0 +MaxZoom=0 +LeftClip=1 +WindowVSync=0 +DiskAccessLamp=0 +DoubleSize=0 +SystemMemory=0 +UseHEL=0 +NoSquareList=0 +GraphicsFilter=0 +DisplayWidth=640 +DisplayHeight=480 +DisplayDepth=32 +DisplayRate=56 +PaletteUse=0 +PaletteFile= +[Sound] +Enable=1 +DisableVolumeEffect=0 +ExtraSoundEnable=1 +SamplingRate=22050 +SamplingBits=8 +BufferSize=4 +FilterType=0 +Volume=640064006400640064006400640064006400640064006400640064006400640040 +[ShortCut] +TBL00=18402E402640314020401E400000000017401140000000000000000000002D4070 +TBL01=3B003C0019000F009C004E004A0039000E0000000000000000000000000000001A +TBL02=0C000D003D003E0000000000000000000000000000000000000000000000000094 +TBL03=06000200030004000500000000000000198013801E801F8032800000000000002F +TBL04=3F004000410042001C800000000000000E400240034004400540064007400840CF +TBL05=09400A400B400C4090407D400000000000000000000000000000000000000000B7 +TBL06=19405700584057405800434043004400444000000000000000000000C740CF40DB +TBL07=D200D30000000000000000000000000000000000000000000000000000000000A5 +TBL08=000000000000000000000000000000000000000000000000000000000000000000 +TBL09=000000000000000000000000000000000000000000000000000000000000000000 +TBL10=000000000000000000000000000000000000000000000000000000000000000000 +TBL11=000000000000000000000000000000000000000000000000000000000000000000 +TBL12=000000000000000000000000000000000000000000000000000000000000000000 +TBL13=000000000000000000000000000000000000000000000000000000000000000000 +TBL14=000000000000000000000000000000000000000000000000000000000000000000 +TBL15=000000000000000000000000000000000000000000000000000000000000000000 +TBL16=52404F40504051404B404C404D4047404840494052804F80508051804B804C8057 +TBL17=4D8047804880498000000000000000000000000000000000000000000000000025 +TBL18=000000000000000000000000000000000000000000000000000000000000000000 +TBL19=000000000000000000000000000000000000000000000000000000000000000000 +TBL20=000000000000000000000000000000000000000000000000000000000000000000 +TBL21=000000000000000000000000000000000000000000000000000000000000000000 +TBL22=000000000000000000000000000000000000000000000000000000000000000000 +TBL23=000000000000000000000000000000000000000000000000000000000000000000 +TBL24=000000000000000000000000000000000000000000000000000000000000000000 +TBL25=000000000000000000000000000000000000000000000000000000000000000000 +TBL26=000000000000000000000000000000000000000000000000000000000000000000 +TBL27=000000000000000000000000000000000000000000000000000000000000000000 +TBL28=000000000000000000000000000000000000000000000000000000000000000000 +TBL29=000000000000000000000000000000000000000000000000000000000000000000 +TBL30=000000000000000000000000000000000000000000000000000000000000000000 +TBL31=000000000000000000000000000000000000000000000000000000000000000000 +[Controller 1] +Keys=120020001F0021002500240017001600220023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D +Rapid=0000000000 +[Controller 2] +Keys=480050004B004D00310030000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3 +Rapid=0000000000 +[Controller 3] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Rapid=0000000000 +[Controller 4] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Rapid=0000000000 +[Crazy Climber] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[Family Trainer] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[Exciting Boxing] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[Mahjang] +Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +[NSF controller] +Keys=C800D000CB00CD00C900D1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA +[VS-Unisystem] +Keys=2E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E +[Movie] +UsePlayer=FF000000FF +ResetRec=0 +Rerecord=1 +LoopPlay=0 +PadDisplay=0 +[Launcher] +WindowPos=0000000000000000000000000000000000 +ColumnView=0101010101010101010101010101010110 +ColumnOrder=000102030405060708090A0B0C0D0E0F78 +ColumnWidth=A00030003000300030003000300030003000300030003000300030003000300070 +ListSelect=0 +SortDir=0 +SortType=0 +FolderUse=0000000000000000000000000000000000 +Folder00= +Folder01= +Folder02= +Folder03= +Folder04= +Folder05= +Folder06= +Folder07= +Folder08= +Folder09= +Folder10= +Folder11= +Folder12= +Folder13= +Folder14= +Folder15= +LastSelect= +ActivePause=0 +[Netplay] +ChatPos=0000000000000000000000000000000000 +NickName=NoName +RecnetPortNum=1 +RecentPort00=10000 +RecentPort01= +RecentPort02= +RecentPort03= +RecentPort04= +RecentPort05= +RecentPort06= +RecentPort07= +RecentPort08= +RecentPort09= +RecentPort10= +RecentPort11= +RecentPort12= +RecentPort13= +RecentPort14= +RecentPort15= +RecnetHostNum=1 +RecentHost00=localhost:10000 +RecentHost01= +RecentHost02= +RecentHost03= +RecentHost04= +RecentHost05= +RecentHost06= +RecentHost07= +RecentHost08= +RecentHost09= +RecentHost10= +RecentHost11= +RecentHost12= +RecentHost13= +RecentHost14= +RecentHost15= +[Recent Path List] +Path1=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\ +Path2=E:\Game\NES\Rom\ +Path3=F:\Game\rom_decompress\Nintendo - Nintendo Entertainment System\ +Path4=E:\Game\NES\ +Path5=E:\Game\NES\Rom\Cah4e3\ +Path6=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\ +Path7=E:\Game\NES\NSF\ +[Recent File List] +File1=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\Double Dragon III - The Sacred Stones (USA).7z +File2=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\Double Dragon III - The Sacred Stones (Europe).7z +File3=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\110 in 1 (Unknown) (Unl) (Pirate).7z +File4=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\Super Contra (Japan).7z +File5=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\Snow Bros. (Japan).7z +File6=F:\Game\No_intro_ROMS\Nintendo - Nintendo Entertainment System\1942 (Japan, USA).7z +File7=E:\Game\NES\Rom\[BiTe] Dian Nao Xue Xi Ka (C).zip +File8=E:\Game\NES\Rom\Contra(U).7z +File9=E:\Game\NES\Rom\[Subor] Yu Yin Zhi Xing Sheng Ji Mu Ka (C).NES +File10=E:\Game\NES\Rom\걭ʥ Ӱ֮.nes diff --git a/References/VirtuaNESex_src_191105/Release/VirtuaNESex_191105.zip b/References/VirtuaNESex_src_191105/Release/VirtuaNESex_191105.zip new file mode 100644 index 00000000..73fb2c13 Binary files /dev/null and b/References/VirtuaNESex_src_191105/Release/VirtuaNESex_191105.zip differ diff --git a/References/VirtuaNESex_src_191105/Render.h b/References/VirtuaNESex_src_191105/Render.h new file mode 100644 index 00000000..25a2ccfb --- /dev/null +++ b/References/VirtuaNESex_src_191105/Render.h @@ -0,0 +1,552 @@ +// +// Render +// + +// 16bit Render +void CDirectDraw::Render16bpp( LPBYTE lpSrc, LPBYTE lpDst ) +{ + LPBYTE pPal; + DWORD width; + DWORD pitch = SCREEN_WIDTH*sizeof(WORD); + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + width = SCREEN_WIDTH; + + __asm { + mov eax, lpSrc + mov esi, pPal + mov edi, lpDst +_r16b_loop: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx + + lea eax, [eax+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16b_loop + } + + lpSrc += RENDER_WIDTH; + lpDst += SCREEN_WIDTH*sizeof(WORD); + } +} + +// 16bit Pre-Render +void CDirectDraw::Render16bppPrefilter( LPBYTE lpSrc, LPBYTE lpDst ) +{ + LPBYTE pPal; + DWORD width; + DWORD pitch = SCREEN_WIDTH*sizeof(WORD); + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cfPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mfPalette[m_LineColormode[i]&0x07]; + } + + width = SCREEN_WIDTH; + + __asm { + mov eax, lpSrc + mov esi, pPal + mov edi, lpDst +_r16b_pf_loop: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx + + lea eax, [eax+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16b_pf_loop + } + + lpSrc += RENDER_WIDTH; + lpDst += SCREEN_WIDTH*sizeof(WORD); + } +} + +// 32bit Render +void CDirectDraw::Render32bpp( LPBYTE lpSrc, LPBYTE lpDst ) +{ + LPBYTE pPal; + DWORD width; + DWORD pitch = SCREEN_WIDTH*sizeof(DWORD); + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + width = SCREEN_WIDTH; + + __asm { + mov eax, lpSrc + mov esi, pPal + mov edi, lpDst +_r32b_loop: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx + + lea eax, [eax+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32b_loop + } + + lpSrc += RENDER_WIDTH; + lpDst += SCREEN_WIDTH*sizeof(DWORD); + } +} + +// Normal/Scanline/Double/DoubleScanlie Render +#include "Render8bpp.h" +#include "Render16bpp.h" +#include "Render24bpp.h" +#include "Render32bpp.h" + +typedef signed char eI8; +typedef signed short eI16; +typedef signed long eI32; +typedef signed __int64 eI64; +typedef unsigned char euI8; +typedef unsigned short euI16; +typedef unsigned long euI32; +typedef unsigned __int64 euI64; + +static euI64 ONE = 0x0001000100010001; +static euI64 cMask; +static euI64 qMask; +static euI64 lMask; +static euI64 ACPixel; +static euI64 Mask1; +static euI64 Mask2; +static euI64 I56Pixel; +static euI64 I5556Pixel; +static euI64 I5666Pixel; +static euI64 I23Pixel; +static euI64 I2223Pixel; +static euI64 I2333Pixel; +static euI64 Mask26; +static euI64 Mask35; +static euI64 Mask26b; +static euI64 Mask35b; +static euI64 product1a; +static euI64 product1b; +static euI64 product2a; +static euI64 product2b; +static euI64 final1a; +static euI64 final1b; +static euI64 final2a; +static euI64 final2b; + +#define colorI -2 +#define colorE 0 +#define colorF 2 +#define colorJ 4 +#define colorG -2 +#define colorA 0 +#define colorB 2 +#define colorK 4 +#define colorH -2 +#define colorC 0 +#define colorD 2 +#define colorL 4 +#define colorM -2 +#define colorN 0 +#define colorO 2 +#define colorP 4 + +#define colorB0 -2 +#define colorB1 0 +#define colorB2 2 +#define colorB3 4 +#define color4 -2 +#define color5 0 +#define color6 2 +#define colorS2 4 +#define color1 -2 +#define color2 0 +#define color3 2 +#define colorS1 4 +#define colorA0 -2 +#define colorA1 0 +#define colorA2 2 +#define colorA3 4 + +// Filtering Render +#include "nx_2xSaI.h" +#include "nx_Super2xSaI.h" +#include "nx_SuperEagle.h" +#include "nx_Scale2x.h" + +void CDirectDraw::nx_2xSaI_16bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = new BYTE[SCREEN_WIDTH*(SCREEN_HEIGHT+6)*sizeof(WORD)]; + + // Pre-Rendering + Render16bpp( lpRdr, &pScn[SCREEN_WIDTH*2*sizeof(WORD)] ); + + euI8* srcPtr = (euI8*)&pScn[SCREEN_WIDTH*2*sizeof(WORD)]; + euI32 srcPitch = SCREEN_WIDTH*sizeof(WORD); + euI8* deltaPtr = (euI8*)lpDlt; + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = (euI32)ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + if( ddsd.ddpfPixelFormat.dwGBitMask == 0x01E0 ) { + // 555 + cMask = 0x7BDE7BDE7BDE7BDE; + qMask = 0x739C739C739C739C; + lMask = 0x0C630C630C630C63; + } else { + // 565 + cMask = 0xF7DEF7DEF7DEF7DE; + qMask = 0xE79CE79CE79CE79C; + lMask = 0x1863186318631863; + } + + for( ; height; height-- ) { + nx_2xSaILine_16bpp_mmx( srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch, bForceWrite ); + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + deltaPtr += srcPitch; + } + + delete[] pScn; +} + +void CDirectDraw::nx_2xSaI_32bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = new BYTE[SCREEN_WIDTH*(SCREEN_HEIGHT+6)*sizeof(WORD)]; + + // Pre-Rendering + Render16bppPrefilter( lpRdr, &pScn[SCREEN_WIDTH*2*sizeof(WORD)] ); + + euI8* srcPtr = (euI8*)&pScn[SCREEN_WIDTH*2*sizeof(WORD)]; + euI32 srcPitch = SCREEN_WIDTH*sizeof(WORD); + euI8* deltaPtr = (euI8*)lpDlt; + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = (euI32)ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + // 555 + cMask = 0x7BDE7BDE7BDE7BDE; + qMask = 0x739C739C739C739C; + lMask = 0x0C630C630C630C63; + + for( ; height; height-- ) { + nx_2xSaILine_32bpp_mmx( srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch, bForceWrite ); + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + deltaPtr += srcPitch; + } + + delete[] pScn; +} + +void CDirectDraw::nx_Super2xSaI_16bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = new BYTE[SCREEN_WIDTH*(SCREEN_HEIGHT+6)*sizeof(WORD)]; + + // Pre-Rendering + Render16bpp( lpRdr, &pScn[SCREEN_WIDTH*2*sizeof(WORD)] ); + + euI8* srcPtr = (euI8*)&pScn[SCREEN_WIDTH*2*sizeof(WORD)]; + euI32 srcPitch = SCREEN_WIDTH*sizeof(WORD); + euI8* deltaPtr = (euI8*)lpDlt; + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = (euI32)ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + if( ddsd.ddpfPixelFormat.dwGBitMask == 0x01E0 ) { + // 555 + cMask = 0x7BDE7BDE7BDE7BDE; + qMask = 0x739C739C739C739C; + lMask = 0x0C630C630C630C63; + } else { + // 565 + cMask = 0xF7DEF7DEF7DEF7DE; + qMask = 0xE79CE79CE79CE79C; + lMask = 0x1863186318631863; + } + + for( ; height; height-- ) { + nx_Super2xSaILine_16bpp_mmx( srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch, bForceWrite ); + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + deltaPtr += srcPitch; + } + + delete[] pScn; +} + +void CDirectDraw::nx_Super2xSaI_32bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = new BYTE[SCREEN_WIDTH*(SCREEN_HEIGHT+6)*sizeof(WORD)]; + + // Pre-Rendering + Render16bppPrefilter( lpRdr, &pScn[SCREEN_WIDTH*2*sizeof(WORD)] ); + + euI8* srcPtr = (euI8*)&pScn[SCREEN_WIDTH*2*sizeof(WORD)]; + euI32 srcPitch = SCREEN_WIDTH*sizeof(WORD); + euI8* deltaPtr = (euI8*)lpDlt; + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = (euI32)ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + // 555 + cMask = 0x7BDE7BDE7BDE7BDE; + qMask = 0x739C739C739C739C; + lMask = 0x0C630C630C630C63; + + for( ; height; height-- ) { + nx_Super2xSaILine_32bpp_mmx( srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch, bForceWrite ); + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + deltaPtr += srcPitch; + } + + delete[] pScn; +} + +void CDirectDraw::nx_SuperEagle_16bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = new BYTE[SCREEN_WIDTH*(SCREEN_HEIGHT+6)*sizeof(WORD)]; + + // Pre-Rendering + Render16bpp( lpRdr, &pScn[SCREEN_WIDTH*2*sizeof(WORD)] ); + + euI8* srcPtr = (euI8*)&pScn[SCREEN_WIDTH*2*sizeof(WORD)]; + euI32 srcPitch = SCREEN_WIDTH*sizeof(WORD); + euI8* deltaPtr = (euI8*)lpDlt; + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = (euI32)ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + if( ddsd.ddpfPixelFormat.dwGBitMask == 0x01E0 ) { + // 555 + cMask = 0x7BDE7BDE7BDE7BDE; + qMask = 0x739C739C739C739C; + lMask = 0x0C630C630C630C63; + } else { + // 565 + cMask = 0xF7DEF7DEF7DEF7DE; + qMask = 0xE79CE79CE79CE79C; + lMask = 0x1863186318631863; + } + + for( ; height; height-- ) { + nx_SuperEagleLine_16bpp_mmx( srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch, bForceWrite ); + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + deltaPtr += srcPitch; + } + + delete[] pScn; +} + +void CDirectDraw::nx_SuperEagle_32bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = new BYTE[SCREEN_WIDTH*(SCREEN_HEIGHT+6)*sizeof(WORD)]; + + // Pre-Rendering + Render16bppPrefilter( lpRdr, &pScn[SCREEN_WIDTH*2*sizeof(WORD)] ); + + euI8* srcPtr = (euI8*)&pScn[SCREEN_WIDTH*2*sizeof(WORD)]; + euI32 srcPitch = SCREEN_WIDTH*sizeof(WORD); + euI8* deltaPtr = (euI8*)lpDlt; + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = (euI32)ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + // 555 + cMask = 0x7BDE7BDE7BDE7BDE; + qMask = 0x739C739C739C739C; + lMask = 0x0C630C630C630C63; + + for( ; height; height-- ) { + nx_SuperEagleLine_32bpp_mmx( srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch, bForceWrite ); + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + deltaPtr += srcPitch; + } + + delete[] pScn; +} + +void CDirectDraw::nx_Scale2x_16bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + // Pre-Rendering + Render16bpp( lpRdr, lpDlt ); + + euI8* srcPtr = (euI8*)lpDlt; + euI32 srcPitch = SCREEN_WIDTH * sizeof(euI16); + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + euI16 *dst0 = (euI16*)dstPtr; + euI16 *dst1 = dst0 + (dstPitch/2); + euI16 *src0 = (euI16*)lpDlt; + euI16 *src1 = src0 + (srcPitch/2); + euI16 *src2 = src1 + (srcPitch/2); + + internal_scale2x_16_mmx( dst0, dst1, src0, src0, src1, width ); + + int count = height; + count -= 2; + while( count ) { + dst0 += dstPitch; + dst1 += dstPitch; + internal_scale2x_16_mmx( dst0, dst1, src0, src1, src2, width ); + src0 = src1; + src1 = src2; + src2 += srcPitch/2; + --count; + } + dst0 += dstPitch; + dst1 += dstPitch; + internal_scale2x_16_mmx( dst0, dst1, src0, src1, src1, width ); +} + +void CDirectDraw::nx_Scale2x_32bpp( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + // Pre-Rendering + Render32bpp( lpRdr, lpDlt ); + + euI8* srcPtr = (euI8*)lpDlt; + euI32 srcPitch = SCREEN_WIDTH * sizeof(euI32); + euI8* dstPtr = (euI8*)ddsd.lpSurface; + euI32 dstPitch = ddsd.lPitch; + int width = SCREEN_WIDTH; + int height = SCREEN_HEIGHT; + + euI32 *dst0 = (euI32*)dstPtr; + euI32 *dst1 = dst0 + (dstPitch/4); + euI32 *src0 = (euI32*)lpDlt; + euI32 *src1 = src0 + (srcPitch/4); + euI32 *src2 = src1 + (srcPitch/4); + + internal_scale2x_32_mmx( dst0, dst1, src0, src0, src1, width ); + + int count = height; + count -= 2; + while( count ) { + dst0 += dstPitch/2; + dst1 += dstPitch/2; + internal_scale2x_32_mmx( dst0, dst1, src0, src1, src2, width ); + src0 = src1; + src1 = src2; + src2 += srcPitch/4; + --count; + } + dst0 += dstPitch/2; + dst1 += dstPitch/2; + internal_scale2x_32_mmx( dst0, dst1, src0, src1, src1, width ); +} diff --git a/References/VirtuaNESex_src_191105/Render16bpp.h b/References/VirtuaNESex_src_191105/Render16bpp.h new file mode 100644 index 00000000..152dbad8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Render16bpp.h @@ -0,0 +1,958 @@ +// +// 16bit Normal +// +void CDirectDraw::Render16bpp_Normal( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bn_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16bn_loop_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bn_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bn_skip1 + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx +_r16bn_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bn_skip2 + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx +_r16bn_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16bn_loop + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 16bit Scanline +// +void CDirectDraw::Render16bpp_Scanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal, pPalScan; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_csPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_msPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bs_loop_fw: + // check previous!! + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx + + // check previous!! + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16bs_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r16bs_loop2_fw: + mov edx, [eax+0] +// mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx + + mov edx, [eax+4] +// mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16bs_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bs_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bs_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx +_r16bs_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bs_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx +_r16bs_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16bs_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r16bs_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bs_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 2], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 4], cx + mov [edi+ 6], dx +_r16bs_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bs_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+10], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], cx + mov [edi+14], dx +_r16bs_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+16] + + sub width, 8 + jg _r16bs_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 16bit Double +// +void CDirectDraw::Render16bpp_Double( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bn_d_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bn_d_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bn_d_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bn_d_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bn_d_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bn_d_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx +_r16bn_d_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bn_d_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx +_r16bn_d_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bn_d_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bn_d_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bn_d_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx +_r16bn_d_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bn_d_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx +_r16bn_d_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bn_d_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 16bit Double Scanline +// +void CDirectDraw::Render16bpp_DoubleScanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal, pPalScan; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_csPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_msPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bs_d_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx + + // check previous!! + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bs_d_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r16bs_d_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bs_d_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r16bs_d_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bs_d_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx +_r16bs_d_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bs_d_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx +_r16bs_d_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bs_d_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r16bs_d_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r16bs_d_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], cx + mov [edi+ 2], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], cx + mov [edi+ 6], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], cx + mov [edi+10], cx + mov [edi+12], dx + mov [edi+14], dx +_r16bs_d_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r16bs_d_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], cx + mov [edi+18], cx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], cx + mov [edi+22], cx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], cx + mov [edi+26], cx + mov [edi+28], dx + mov [edi+30], dx +_r16bs_d_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r16bs_d_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} diff --git a/References/VirtuaNESex_src_191105/Render24bpp.h b/References/VirtuaNESex_src_191105/Render24bpp.h new file mode 100644 index 00000000..5d1e200a --- /dev/null +++ b/References/VirtuaNESex_src_191105/Render24bpp.h @@ -0,0 +1,1012 @@ +// +// 24bit Normal +// +void CDirectDraw::Render24bpp_Normal( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bn_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 3], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 6], ecx + mov [edi+ 9], dx + shr edx, 16 + mov [edi+11], dl + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+12], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+15], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+18], ecx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+24] + + sub width, 8 + jg _r24bn_loop_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bn_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bn_skip1 + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 3], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 6], ecx + mov [edi+ 9], dx + shr edx, 16 + mov [edi+11], dl +_r24bn_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bn_skip2 + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+12], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+15], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+18], ecx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bn_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+24] + + sub width, 8 + jg _r24bn_loop + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 24bit Scanline +// +void CDirectDraw::Render24bpp_Scanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal, pPalScan; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_csPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_msPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bs_loop_fw: + // check previous!! + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 3], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 6], ecx + mov [edi+ 9], dx + shr edx, 16 + mov [edi+11], dl + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+12], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+15], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+18], ecx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+24] + + sub width, 8 + jg _r24bs_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r24bs_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 3], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 6], ecx + mov [edi+ 9], dx + shr edx, 16 + mov [edi+11], dl + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+12], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+15], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+18], ecx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+24] + + sub width, 8 + jg _r24bs_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bs_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bs_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 3], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 6], ecx + mov [edi+ 9], dx + shr edx, 16 + mov [edi+11], dl +_r24bs_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bs_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+12], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+15], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+18], ecx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bs_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+24] + + sub width, 8 + jg _r24bs_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r24bs_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bs_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 3], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 6], ecx + mov [edi+ 9], dx + shr edx, 16 + mov [edi+11], dl +_r24bs_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bs_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+12], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+15], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+18], ecx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bs_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+24] + + sub width, 8 + jg _r24bs_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 24bit Double +// +void CDirectDraw::Render24bpp_Double( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bn_d_loop_fw: + // check previous!! + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + // check previous!! + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], edx + shr edx, 16 + mov [edi+47], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bn_d_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bn_d_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], dx + shr edx, 16 + mov [edi+47], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bn_d_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bn_d_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bn_d_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bn_d_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bn_d_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], edx + shr edx, 16 + mov [edi+47], dl +_r24bn_d_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bn_d_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bn_d_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bn_d_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bn_d_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bn_d_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], dx + shr edx, 16 + mov [edi+47], dl +_r24bn_d_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bn_d_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 24bit Double Scanline +// +void CDirectDraw::Render24bpp_DoubleScanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal, pPalScan; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_csPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_msPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bs_d_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], edx + shr edx, 16 + mov [edi+47], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bs_d_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r24bs_d_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], dx + shr edx, 16 + mov [edi+47], dl + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bs_d_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r24bs_d_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bs_d_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bs_d_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bs_d_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], edx + shr edx, 16 + mov [edi+47], dl +_r24bs_d_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bs_d_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r24bs_d_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r24bs_d_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 3], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 6], ecx + mov [edi+ 9], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+12], ecx + mov [edi+15], ecx + mov [edi+18], edx + mov [edi+21], dx + shr edx, 16 + mov [edi+23], dl +_r24bs_d_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r24bs_d_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+24], ecx + mov [edi+27], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+30], ecx + mov [edi+33], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+36], ecx + mov [edi+39], ecx + mov [edi+42], edx + mov [edi+45], dx + shr edx, 16 + mov [edi+47], dl +_r24bs_d_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+48] + + sub width, 8 + jg _r24bs_d_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} diff --git a/References/VirtuaNESex_src_191105/Render32bpp.h b/References/VirtuaNESex_src_191105/Render32bpp.h new file mode 100644 index 00000000..3130c26b --- /dev/null +++ b/References/VirtuaNESex_src_191105/Render32bpp.h @@ -0,0 +1,953 @@ +// +// 32bit Normal +// +void CDirectDraw::Render32bpp_Normal( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bn_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32bn_loop_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bn_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bn_skip1 + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx +_r32bn_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bn_skip2 + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx +_r32bn_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32bn_loop + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 32bit Scanline +// +void CDirectDraw::Render32bpp_Scanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal, pPalScan; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_csPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_msPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bs_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32bs_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r32bs_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32bs_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bs_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bs_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx +_r32bs_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bs_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx +_r32bs_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32bs_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r32bs_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bs_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 4], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+ 8], ecx + mov [edi+12], edx +_r32bs_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bs_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+16], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+20], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+24], ecx + mov [edi+28], edx +_r32bs_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+32] + + sub width, 8 + jg _r32bs_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 32bit Double +// +void CDirectDraw::Render32bpp_Double( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bs_d_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bs_d_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bs_d_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bs_d_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bs_d_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bs_d_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx +_r32bs_d_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bs_d_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx +_r32bs_d_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bs_d_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bs_d_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bs_d_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx +_r32bs_d_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bs_d_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx +_r32bs_d_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bs_d_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} + +// +// 32bit Double Scanline +// +void CDirectDraw::Render32bpp_DoubleScanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + LPBYTE pDlt = (LPBYTE)lpDlt; + LPBYTE pPal, pPalScan; + DWORD width; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + if( !(m_LineColormode[i]&0x80) ) { + pPal = (LPBYTE)m_cnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_csPalette[m_LineColormode[i]&0x07]; + } else { + pPal = (LPBYTE)m_mnPalette[m_LineColormode[i]&0x07]; + pPalScan = (LPBYTE)m_msPalette[m_LineColormode[i]&0x07]; + } + + BOOL bFWrite = FALSE; + if( bForceWrite || *pDlt != m_LineColormode[i] ) { + bFWrite = TRUE; + *pDlt = m_LineColormode[i]; + } + pDlt += 4; + + width = SCREEN_WIDTH; + + if( bFWrite ) { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bn_d_loop_fw: + mov edx, [eax+0] + mov [ebx+0], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx + + mov edx, [eax+4] + mov [ebx+4], edx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bn_d_loop_fw + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r32bn_d_loop2_fw: + mov edx, [eax+0] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx + + mov edx, [eax+4] + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx + + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bn_d_loop2_fw + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } else { + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPal + mov edi, pDst +_r32bn_d_loop: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bn_d_skip1 +// mov [ebx+0], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx +_r32bn_d_skip1: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bn_d_skip2 +// mov [ebx+4], edx // 1ڂ͏܂Ȃ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx +_r32bn_d_skip2: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bn_d_loop + } + + width = SCREEN_WIDTH; + pDst += pitch; + + __asm { + mov eax, pScn + mov ebx, pDlt + mov esi, pPalScan + mov edi, pDst +_r32bn_d_loop2: + // check previous!! + mov edx, [eax+0] + cmp edx, [ebx+0] + je _r32bn_d_skip3 + mov [ebx+0], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 0], ecx + mov [edi+ 4], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+ 8], ecx + mov [edi+12], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+16], ecx + mov [edi+20], ecx + mov [edi+24], edx + mov [edi+28], edx +_r32bn_d_skip3: + // check previous!! + mov edx, [eax+4] + cmp edx, [ebx+4] + je _r32bn_d_skip4 + mov [ebx+4], edx // 2ڂ͏ + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+32], ecx + mov [edi+36], ecx + movzx ecx, dl + mov ecx, [esi+ecx*4] + shr edx, 8 + mov [edi+40], ecx + mov [edi+44], ecx + movzx ecx, dl + shr edx, 8 + mov ecx, [esi+ecx*4] + mov edx, [esi+edx*4] + mov [edi+48], ecx + mov [edi+52], ecx + mov [edi+56], edx + mov [edi+60], edx +_r32bn_d_skip4: + lea eax, [eax+ 8] + lea ebx, [ebx+ 8] + lea edi, [edi+64] + + sub width, 8 + jg _r32bn_d_loop2 + } + + pScn += RENDER_WIDTH; + pDlt += SCREEN_WIDTH; + pDst += pitch; + } + } +} diff --git a/References/VirtuaNESex_src_191105/Render8bpp.h b/References/VirtuaNESex_src_191105/Render8bpp.h new file mode 100644 index 00000000..5104de71 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Render8bpp.h @@ -0,0 +1,407 @@ +// +// 8bit Normal +// +void CDirectDraw::Render8bpp_Normal( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x40404040 +_r8bn_loop: + mov eax, [esi+0] + mov ebx, [esi+4] + or eax, edx + or ebx, edx + mov [edi+0], eax + mov [edi+4], ebx + + lea esi, [esi+8] + lea edi, [edi+8] + sub ecx, 8 + jg _r8bn_loop + } + pScn += RENDER_WIDTH; + pDst += pitch; + } +} + +// +// 8bit Scanline +// +void CDirectDraw::Render8bpp_Scanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x40404040 +_r8bs_loop: + mov eax, [esi+0] + mov ebx, [esi+4] + or eax, edx + or ebx, edx + mov [edi+0], eax + mov [edi+4], ebx + + lea esi, [esi+8] + lea edi, [edi+8] + sub ecx, 8 + jg _r8bs_loop + } + pDst += pitch; + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x80808080 +_r8bs_loop2: + mov eax, [esi+0] + mov ebx, [esi+4] + or eax, edx + or ebx, edx + mov [edi+0], eax + mov [edi+4], ebx + + lea esi, [esi+8] + lea edi, [edi+8] + sub ecx, 8 + jg _r8bs_loop2 + } + pScn += RENDER_WIDTH; + pDst += pitch; + } +} + +// +// 8bit Double +// +void CDirectDraw::Render8bpp_Double( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + if( !IsMMX() ) { + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x40404040 +_r8bn_d_loop: + mov al, [esi+1] + mov ah, al + shl eax, 16 + mov al, [esi+0] + mov ah, al + or eax, edx + mov [edi+ 0], eax + + mov al, [esi+3] + mov ah, al + shl eax, 16 + mov al, [esi+2] + mov ah, al + or eax, edx + mov [edi+ 4], eax + + mov al, [esi+5] + mov ah, al + shl eax, 16 + mov al, [esi+4] + mov ah, al + or eax, edx + mov [edi+ 8], eax + + mov al, [esi+7] + mov ah, al + shl eax, 16 + mov al, [esi+6] + mov ah, al + or eax, edx + mov [edi+12], eax + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bn_d_loop + } + pDst += pitch; + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x40404040 +_r8bn_d_loop2: + mov al, [esi+1] + mov ah, al + shl eax, 16 + mov al, [esi+0] + mov ah, al + or eax, edx + mov [edi+ 0], eax + + mov al, [esi+3] + mov ah, al + shl eax, 16 + mov al, [esi+2] + mov ah, al + or eax, edx + mov [edi+ 4], eax + + mov al, [esi+5] + mov ah, al + shl eax, 16 + mov al, [esi+4] + mov ah, al + or eax, edx + mov [edi+ 8], eax + + mov al, [esi+7] + mov ah, al + shl eax, 16 + mov al, [esi+6] + mov ah, al + or eax, edx + mov [edi+12], eax + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bn_d_loop2 + } + pScn += RENDER_WIDTH; + pDst += pitch; + } + } else { + QWORD mask = 0x4040404040404040; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + movq mm7, mask +_r8bn_d_loop3: + movd mm0, [esi+0] + movd mm2, [esi+4] + movq mm1, mm0 + movq mm3, mm2 + punpcklbw mm0, mm1 + punpcklbw mm2, mm3 + por mm0, mm7 + por mm2, mm7 + movq [edi+ 0], mm0 + movq [edi+ 8], mm2 + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bn_d_loop3 + } + pDst += pitch; + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + movq mm7, mask +_r8bn_d_loop4: + movd mm0, [esi+0] + movd mm2, [esi+4] + movq mm1, mm0 + movq mm3, mm2 + punpcklbw mm0, mm1 + punpcklbw mm2, mm3 + por mm0, mm7 + por mm2, mm7 + movq [edi+ 0], mm0 + movq [edi+ 8], mm2 + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bn_d_loop4 + } + pScn += RENDER_WIDTH; + pDst += pitch; + } + __asm { + emms + } + } +} + +// +// 8bit Double Scanline +// +void CDirectDraw::Render8bpp_DoubleScanline( LPBYTE lpRdr, LPBYTE lpDlt, DDSURFACEDESC2& ddsd, BOOL bForceWrite ) +{ + LPBYTE pScn = lpRdr; + LPBYTE pDst = (LPBYTE)ddsd.lpSurface; + DWORD width = SCREEN_WIDTH; + DWORD pitch = ddsd.lPitch; + + if( !IsMMX() ) { + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x40404040 +_r8bs_d_loop: + mov al, [esi+1] + mov ah, al + shl eax, 16 + mov al, [esi+0] + mov ah, al + or eax, edx + mov [edi+ 0], eax + + mov al, [esi+3] + mov ah, al + shl eax, 16 + mov al, [esi+2] + mov ah, al + or eax, edx + mov [edi+ 4], eax + + mov al, [esi+5] + mov ah, al + shl eax, 16 + mov al, [esi+4] + mov ah, al + or eax, edx + mov [edi+ 8], eax + + mov al, [esi+7] + mov ah, al + shl eax, 16 + mov al, [esi+6] + mov ah, al + or eax, edx + mov [edi+12], eax + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bs_d_loop + } + pDst += pitch; + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + mov edx, 0x80808080 +_r8bs_d_loop2: + mov al, [esi+1] + mov ah, al + shl eax, 16 + mov al, [esi+0] + mov ah, al + or eax, edx + mov [edi+ 0], eax + + mov al, [esi+3] + mov ah, al + shl eax, 16 + mov al, [esi+2] + mov ah, al + or eax, edx + mov [edi+ 4], eax + + mov al, [esi+5] + mov ah, al + shl eax, 16 + mov al, [esi+4] + mov ah, al + or eax, edx + mov [edi+ 8], eax + + mov al, [esi+7] + mov ah, al + shl eax, 16 + mov al, [esi+6] + mov ah, al + or eax, edx + mov [edi+12], eax + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bs_d_loop2 + } + pScn += RENDER_WIDTH; + pDst += pitch; + } + } else { + QWORD maskn = 0x4040404040404040; + QWORD masks = 0x8080808080808080; + + for( INT i = 0; i < SCREEN_HEIGHT; i++ ) { + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + movq mm7, maskn +_r8bs_d_loop3: + movd mm0, [esi+0] + movd mm2, [esi+4] + movq mm1, mm0 + movq mm3, mm2 + punpcklbw mm0, mm1 + punpcklbw mm2, mm3 + por mm0, mm7 + por mm2, mm7 + movq [edi+ 0], mm0 + movq [edi+ 8], mm2 + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bs_d_loop3 + } + pDst += pitch; + __asm { + mov esi, pScn + mov edi, pDst + mov ecx, width + movq mm7, masks +_r8bs_d_loop4: + movd mm0, [esi+0] + movd mm2, [esi+4] + movq mm1, mm0 + movq mm3, mm2 + punpcklbw mm0, mm1 + punpcklbw mm2, mm3 + por mm0, mm7 + por mm2, mm7 + movq [edi+ 0], mm0 + movq [edi+ 8], mm2 + + lea esi, [esi+8] + lea edi, [edi+16] + sub ecx, 8 + jg _r8bs_d_loop4 + } + pScn += RENDER_WIDTH; + pDst += pitch; + } + __asm { + emms + } + } +} diff --git a/References/VirtuaNESex_src_191105/RomInfoDlg.cpp b/References/VirtuaNESex_src_191105/RomInfoDlg.cpp new file mode 100644 index 00000000..7b775c03 --- /dev/null +++ b/References/VirtuaNESex_src_191105/RomInfoDlg.cpp @@ -0,0 +1,79 @@ +// +// ROM_CAONX +// +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "RomInfoDlg.h" + +DLG_MESSAGE_BEGIN(CRomInfoDlg) +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) + +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CRomInfoDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_ROMINFO), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +DLGMSG CRomInfoDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CRomInfoDlg::OnInitDialog\n" ); + + ::SetDlgItemText( m_hWnd, IDC_ROM_NAME, m_szName ); + + CHAR szStr[64]; + if( m_nMapper < 256 ) ::wsprintf( szStr, "%d", m_nMapper ); + else if( m_nMapper == 256 ) ::wsprintf( szStr, "NSF" ); + else if( m_nMapper > 256 ) ::wsprintf( szStr, "UNIF" ); + + ::SetDlgItemText( m_hWnd, IDC_ROM_MAPPER, szStr ); + + ::wsprintf( szStr, "%dKB", m_nPRG*16 ); + ::SetDlgItemText( m_hWnd, IDC_ROM_PRG, szStr ); + ::wsprintf( szStr, "%dKB", m_nCHR*8 ); + ::SetDlgItemText( m_hWnd, IDC_ROM_CHR, szStr ); + + ::SetDlgItemText( m_hWnd, IDC_ROM_MIRROR, m_bMirror?"V":"H" ); + ::SetDlgItemText( m_hWnd, IDC_ROM_SRAM, m_bSram?"Yes":"No" ); + ::SetDlgItemText( m_hWnd, IDC_ROM_4SCREEN, m_b4Screen?"Yes":"No" ); + ::SetDlgItemText( m_hWnd, IDC_ROM_TRAINER, m_bTrainer?"Yes":"No" ); + ::SetDlgItemText( m_hWnd, IDC_ROM_VSUNISYSTEM, m_bVSUnisystem?"Yes":"No" ); + + ::wsprintf( szStr, "%08X", m_dwCRC ); + ::SetDlgItemText( m_hWnd, IDC_ROM_CRC, szStr ); + ::wsprintf( szStr, "%08X", m_dwCRCALL ); + ::SetDlgItemText( m_hWnd, IDC_ROM_CRCALL, szStr ); + ::wsprintf( szStr, "%08X", m_dwCRCCHR ); + ::SetDlgItemText( m_hWnd, IDC_ROM_CRCCHR, szStr ); + + return TRUE; +} + +DLGCMD CRomInfoDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CRomInfoDlg::OnOK\n" ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CRomInfoDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CRomInfoDlg::OnCancel\n" ); + + ::EndDialog( m_hWnd, IDCANCEL ); +} + diff --git a/References/VirtuaNESex_src_191105/RomInfoDlg.h b/References/VirtuaNESex_src_191105/RomInfoDlg.h new file mode 100644 index 00000000..493c11f5 --- /dev/null +++ b/References/VirtuaNESex_src_191105/RomInfoDlg.h @@ -0,0 +1,58 @@ +// +// ROM_CAONX +// +#ifndef __CROMINFODLG_INCLUDED__ +#define __CROMINFODLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" + +class CRomInfoDlg : public CWnd +{ +public: + CRomInfoDlg() { + m_szName[0] = '\0'; + m_nMapper = 0; + m_nPRG = 0; + m_nCHR = 0; + m_bMirror = FALSE; + m_bSram = FALSE; + m_b4Screen = FALSE; + m_bTrainer = FALSE; + m_bVSUnisystem = FALSE; + m_dwCRC = 0; + m_dwCRCALL = 0; + m_dwCRCCHR = 0; + } + + // Override from CWnd + INT DoModal( HWND hWndParent ); + + CHAR m_szName[_MAX_PATH]; + INT m_nMapper; + INT m_nPRG; + INT m_nCHR; + BOOL m_bMirror; + BOOL m_bSram; + BOOL m_b4Screen; + BOOL m_bTrainer; + BOOL m_bVSUnisystem; + DWORD m_dwCRC; + DWORD m_dwCRCALL; + DWORD m_dwCRCCHR; +protected: + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + // +private: +}; + +#endif // !__CROMINFODLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/ShortcutDlg.cpp b/References/VirtuaNESex_src_191105/ShortcutDlg.cpp new file mode 100644 index 00000000..e80ee4e9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/ShortcutDlg.cpp @@ -0,0 +1,357 @@ +// +// V[gJbg_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" +#include "Config.h" + +#include "Wnd.h" +#include "ShortcutDlg.h" + +#include "DirectInput.h" + +DLG_MESSAGE_BEGIN(CShortcutDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +DLG_ON_MESSAGE( WM_TIMER, OnTimer ) +// NOTIFYbZ[W +DLG_NOTIFY_BEGIN() +DLG_ON_NOTIFY( IDC_CUT_LIST, NM_DBLCLK, OnListDblClick ) +DLG_ON_NOTIFY( IDC_CUT_LIST, LVN_ITEMCHANGED, OnListItemChanged ) +DLG_NOTIFY_END() +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + + DLGMSG OnTimer( DLGMSGPARAM ); + DLGNOTIFY OnListDblClick( DLGNOTIFYPARAM ); + DLGNOTIFY OnListItemChanged( DLGNOTIFYPARAM ); + +INT CShortcutDlg::DoModal( HWND hWndParent ) +{ + m_bCancelMode = FALSE; + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_SHORTCUT), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +BOOL CShortcutDlg::PreTranslateMessage( MSG* pMsg ) +{ + if( pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST ) { +// DEBUGOUT( "CShortcutDlg::PreTranslateMessage WM_KEY????\n" ); + return m_bCancelMode; + } + return FALSE; +} + +void CShortcutDlg::OnInitialMember() +{ + // Xgr[̃ACe̍폜 + CHAR szStr[256]; + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CUT_LIST ); + ListView_DeleteColumn( hWndCtrl, 0 ); + ListView_DeleteColumn( hWndCtrl, 0 ); + ListView_DeleteColumn( hWndCtrl, 0 ); + ListView_DeleteAllItems( hWndCtrl ); + ListView_SetItemCount( hWndCtrl, 100 ); + + // wb_Rg[̐ݒ + LVCOLUMN lvColumn; + lvColumn.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM; + lvColumn.fmt = LVCFMT_LEFT; + + CApp::LoadString( IDS_CUT_TYPE, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 0; + lvColumn.pszText = szStr; + ListView_InsertColumn( hWndCtrl, 0, &lvColumn ); + + CApp::LoadString( IDS_CUT_KEY, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 1; + lvColumn.pszText = szStr; + ListView_InsertColumn( hWndCtrl, 1, &lvColumn ); + + CApp::LoadString( IDS_CUT_KEY2, szStr, sizeof(szStr) ); + lvColumn.iSubItem = 2; + lvColumn.pszText = szStr; + ListView_InsertColumn( hWndCtrl, 2, &lvColumn ); + + + // Xgr[eݒ + LVITEM lvItem; + ZeroMemory( &lvItem, sizeof(lvItem) ); + lvItem.mask = LVIF_TEXT; + + for( INT i = 0; CConfig::ShortcutKeyID[i*3+0]; i++ ) { + lvItem.iItem = i; + // + CApp::LoadString( CConfig::ShortcutKeyID[i*3+1], szStr, sizeof(szStr) ); + lvItem.pszText = szStr; + ListView_InsertItem( hWndCtrl, &lvItem ); + + // ݒ跰 + if( m_ControlBuf[i] == 0 ) { + ListView_SetItemText( hWndCtrl, i, 1, "----" ); + } else { + string str = Config.ShortcutToKeyName( m_ControlBuf[i] ); + ListView_SetItemText( hWndCtrl, i, 1, (LPSTR)str.c_str() ); + } + // ݒ跰2 + if( m_ControlBuf2[i] == 0 ) { + ListView_SetItemText( hWndCtrl, i, 2, "----" ); + } else { + string str = Config.ShortcutToKeyName( m_ControlBuf2[i] ); + ListView_SetItemText( hWndCtrl, i, 2, (LPSTR)str.c_str() ); + } + } + + // Jݒ肵Ă牡ύXȂƉXN[o[oĎזȂ̂... + RECT rc; + ::GetClientRect( hWndCtrl, &rc ); + + ListView_SetColumnWidth( hWndCtrl, 0, (rc.right-rc.left)*10/20 ); + ListView_SetColumnWidth( hWndCtrl, 1, (rc.right-rc.left)*5/20 ); + ListView_SetColumnWidth( hWndCtrl, 2, (rc.right-rc.left)*5/20 ); + ListView_SetExtendedListViewStyle( hWndCtrl, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES ); +} + +DLGMSG CShortcutDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CShortcutDlg::OnInitDialog\n" ); + + // ݒ̕ۑ + m_ConfigSave = Config.shortcut; + + // Rs[ + for( INT i = 0; CConfig::ShortcutKeyID[i*3+0]; i++ ) { + m_ControlBuf [i] = Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2]]; + m_ControlBuf2[i] = Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2]+128]; + } + // EChE^Cg̕ۑ + ::GetWindowText( m_hWnd, m_szWindowTitle, sizeof(m_szWindowTitle) ); + // ݒ蒆bZ[W̕ۑ + CApp::LoadString( IDS_CUT_TITLE, m_szMessage, sizeof(m_szMessage) ); + + // + OnInitialMember(); + + m_bCancelMode = FALSE; + m_SelectPos = -1; + m_TimerID = 0; + m_SelectID = 0; + + return TRUE; +} + +DLGMSG CShortcutDlg::OnTimer( DLGMSGPARAM ) +{ + if( wParam == (WPARAM)m_TimerID ) { + m_TimerCount++; + + DirectInput.Poll(); + + if( !(m_TimerCount&0x04) ) { + string str = m_szWindowTitle; + str = str + " "; + str = str + m_szMessage; + ::SetWindowText( m_hWnd, str.c_str() ); + } else { + ::SetWindowText( m_hWnd, m_szWindowTitle ); + } + + if( m_TimerCount > 60 ) { + // ^CAEg + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_SelectID = 0; + } + m_bCancelMode = FALSE; + ::SetWindowText( m_hWnd, m_szWindowTitle ); + } else { + // Button push? + HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CUT_LIST ); + INT i; + // Set cancel + if( DirectInput.m_Sw[DIK_ESCAPE] && !(DirectInput.m_Sw[DIK_LSHIFT] || DirectInput.m_Sw[DIK_RSHIFT]) ) { + if( m_SelectSubID == 2 ) { + ListView_SetItemText( hWndCtrl, m_SelectID, 2, "----" ); + m_ControlBuf2[m_SelectID] = 0; + } else { + ListView_SetItemText( hWndCtrl, m_SelectID, 1, "----" ); + m_ControlBuf[m_SelectID] = 0; + } +// ::SetWindowText( hWndCtrl, "----" ); + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_SelectID = 0; + } + m_bCancelMode = FALSE; + ::SetWindowText( m_hWnd, m_szWindowTitle ); + } else { + string str; + WORD keyex = 0; + if( !DirectInput.m_Sw[DIK_ESCAPE] ) { + if( DirectInput.m_Sw[DIK_LMENU] || DirectInput.m_Sw[DIK_RMENU] ) { + keyex |= CCfgShortCut::K_ALT; + str = str + "Alt+"; + } + if( DirectInput.m_Sw[DIK_LCONTROL] || DirectInput.m_Sw[DIK_RCONTROL] ) { + keyex |= CCfgShortCut::K_CTRL; + str = str + "Ctrl+"; + } + if( DirectInput.m_Sw[DIK_LSHIFT] || DirectInput.m_Sw[DIK_RSHIFT] ) { + keyex |= CCfgShortCut::K_SHIFT; + str = str + "Shift+"; + } + } + + for( i = 0; i < 256+64*8; i++ ) { + if( i == DIK_LMENU || i == DIK_RMENU + || i == DIK_LCONTROL || i == DIK_RCONTROL + || i == DIK_LSHIFT || i == DIK_RSHIFT ) + continue; + + if( DirectInput.m_Sw[i]&0x80 ) { + if( DirectInput.SearchKeyName(i) ) { + str = str + DirectInput.SearchKeyName(i); + if( m_SelectSubID == 2 ) { + m_ControlBuf2[m_SelectID] = keyex+i; + ListView_SetItemText( hWndCtrl, m_SelectID, 2, (LPSTR)str.c_str() ); + } else { + m_ControlBuf [m_SelectID] = keyex+i; + ListView_SetItemText( hWndCtrl, m_SelectID, 1, (LPSTR)str.c_str() ); + } + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_SelectID = 0; + } + m_bCancelMode = FALSE; + ::SetWindowText( m_hWnd, m_szWindowTitle ); + break; + } + } + } + } + } + } + return FALSE; +} + +DLGNOTIFY CShortcutDlg::OnListItemChanged( DLGNOTIFYPARAM ) +{ + NMLISTVIEW* pNMListView = (NMLISTVIEW*)pNMHDR; + + if( !(pNMListView->uOldState & LVIS_SELECTED) && (pNMListView->uNewState & LVIS_SELECTED) ) { + m_SelectPos = pNMListView->iItem; + } +} + +DLGNOTIFY CShortcutDlg::OnListDblClick( DLGNOTIFYPARAM ) +{ + NMLISTVIEW* pNMListView = (NMLISTVIEW*)pNMHDR; + +// DEBUGOUT( "CShortcutDlg::OnListDblClick\n" ); + + // ܂IĂȂ + if( m_SelectPos == -1 ) + return; + + LVHITTESTINFO htInfo; + ZeroMemory( &htInfo, sizeof(htInfo) ); +// DWORD pos = ::GetMessagePos(); +// POINT pt = *((POINT*)&pos); +// ::ScreenToClient( ::GetDlgItem( m_hWnd, IDC_CUT_LIST ), &pt ); +// htInfo.pt.x = pt.x; +// htInfo.pt.y = pt.y; + htInfo.pt.x = pNMListView->ptAction.x; + htInfo.pt.y = pNMListView->ptAction.y; + ListView_HitTest( ::GetDlgItem( m_hWnd, IDC_CUT_LIST ), &htInfo ); + + // ZNgꂽꏊɃqbgĂȂH + if( htInfo.flags & LVHT_NOWHERE ) { + return; + } + + if( !m_TimerID && pNMListView->iSubItem ) { + m_bCancelMode = TRUE; + m_SelectID = m_SelectPos; + m_SelectSubID = pNMListView->iSubItem; + m_TimerCount = 0; + m_TimerID = ::SetTimer( m_hWnd, 1, 50, NULL ); +DEBUGOUT( "ID=%d/SUBID=%d\n", pNMListView->iItem, pNMListView->iSubItem ); + } +} + +DLGCMD CShortcutDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CShortcutDlg::OnOK\n" ); + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_SelectID = 0; + m_bCancelMode = FALSE; + } + + // ݒRs[ + for( INT i = 0; CConfig::ShortcutKeyID[i*3+0]; i++ ) { + Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2] ] = m_ControlBuf [i]; + Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2]+128] = m_ControlBuf2[i]; + } + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CShortcutDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CShortcutDlg::OnCancel\n" ); + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_SelectID = 0; + m_bCancelMode = FALSE; + } + + // ݒ߂ + Config.shortcut = m_ConfigSave; + + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CShortcutDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CShortcutDlg::OnDefault\n" ); + + if( m_TimerID ) { + ::KillTimer( m_hWnd, m_TimerID ); + m_TimerID = 0; + m_SelectID = 0; + m_bCancelMode = FALSE; + } + + Config.shortcut.Default(); + // Rs[ + for( INT i = 0; CConfig::ShortcutKeyID[i*3+0]; i++ ) { + m_ControlBuf [i] = Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2] ]; + m_ControlBuf2[i] = Config.shortcut.nShortCut[CConfig::ShortcutKeyID[i*3+2]+128]; + } + OnInitialMember(); +} + diff --git a/References/VirtuaNESex_src_191105/ShortcutDlg.h b/References/VirtuaNESex_src_191105/ShortcutDlg.h new file mode 100644 index 00000000..6158e9cc --- /dev/null +++ b/References/VirtuaNESex_src_191105/ShortcutDlg.h @@ -0,0 +1,57 @@ +// +// V[gJbg_CAONX +// +#ifndef __CSHORTCUTDLG_INCLUDED__ +#define __CSHORTCUTDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CShortcutDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); + + // Override from CWnd + BOOL PreTranslateMessage( MSG* pMsg ); +protected: + + void OnInitialMember(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGMSG OnTimer( DLGMSGPARAM ); + DLGNOTIFY OnListDblClick( DLGNOTIFYPARAM ); + DLGNOTIFY OnListItemChanged( DLGNOTIFYPARAM ); + + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + // + + CHAR m_szWindowTitle[256]; + CHAR m_szMessage[256]; + + BOOL m_bCancelMode; + INT m_SelectPos; + INT m_SelectID; + INT m_SelectSubID; + INT m_TimerID; + INT m_TimerCount; + + INT m_ControlBuf [128]; + INT m_ControlBuf2[128]; + CCfgShortCut m_ConfigSave; + +private: +}; + +#endif // !__CSHORTCUTDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/SimpleVirusChecker.c b/References/VirtuaNESex_src_191105/SimpleVirusChecker.c new file mode 100644 index 00000000..d071e2ab --- /dev/null +++ b/References/VirtuaNESex_src_191105/SimpleVirusChecker.c @@ -0,0 +1,183 @@ +/* + + SimpleVirusChecker + version 1.1 + programmed by Norix + + Copyright Note + source code: SimpleVirusChecker.c,SimpleVirusChecker.h + + Please use this program freely. + An author isn't concerned on a loss at having used this program at all. + An author prays for virus software disappearing from a PC in the world. + + --Attention-- + Because an author doesn't have a PC infected with a virus program, can't + guarantee it whether you were able to completely check it. + + Histroy: + v1.1 add WORM_FIZZER + add WORM_PALYH + add WORM_LOVGATE + add WORM_OPASERV + v1.11 add WORM_SOBIG.F +*/ +#include "SimpleVirusChecker.h" +#include + +#define KEYTYPE_1 (1<<0) /* Windows startup registry */ +#define KEYTYPE_2 (1<<1) /* Windows Servece registry(NT only) */ + +typedef struct { + TCHAR* keyname; + int type; /* type */ + int length; /* use strncmp length (0 is use strcmp) */ +} VIRUSKEYTBL; + +static VIRUSKEYTBL viruskeytbl[] = { +/* KEY KEYTYPE LENGTH */ + _T("Wink"), KEYTYPE_1|KEYTYPE_2, 4, /* Klez */ + _T("WindowsMGM"), KEYTYPE_1|KEYTYPE_2, 0, /* Sobig */ + _T("Avril Lavigne - Muse"), KEYTYPE_1, 0, /* Lirva */ + _T("SystemInit"), KEYTYPE_1, 0, /* Fizzer */ + _T("System Tray"), KEYTYPE_1, 0, /* Palyh */ + _T("WinGate initialize"), KEYTYPE_1, 0, /* Lovgate */ + _T("ScrSvr"), KEYTYPE_1, 0, /* Opaserv */ + _T("SSK Service"), KEYTYPE_1, 0, /* Sobig.E */ + _T("TrayX"), KEYTYPE_1, 0, /* Sobig.F */ + NULL, 0, 0 /* term */ +}; + +/* WindowsNT? */ +static int IsNT( void ) +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if( !GetVersionEx(&osvi) ) + return 0; + + if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ) + return 1; + + if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) + return 0; + + /* unknown */ + return -1; +} + +/* A check of a type to be infected with *.exe activation (representative example:SIRCAM) */ +static int ExeRegistryCheck( void ) +{ + HKEY hKey; + LONG lResult; + DWORD dwCount; + + if( RegOpenKeyEx( HKEY_CLASSES_ROOT, _T("exefile\\shell\\open\\command"), + 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) { + return -1; + } + + lResult = RegQueryValueEx( hKey, _T(""), NULL, NULL, NULL, &dwCount ); + RegCloseKey( hKey ); + if( lResult != ERROR_SUCCESS ) { + return -1; + } + /* + Check it whether a parameter is different from a default parameter. + May think that this is originally infected when it is only '"%1" %*' + and has length more than it. + */ + if( dwCount > 8 ) { + return 1; + } + /* OK */ + return 0; +} + +/* Character string comparison */ +static int KlezTypeCheckSub( const char* name, int mask ) +{ + VIRUSKEYTBL* tbl = viruskeytbl; + + while( tbl->keyname ) { + if( tbl->type & mask ) { + if( !tbl->length ) { + if( StrCmpI( name, tbl->keyname ) == 0 ) + return 1; + } else { + if( StrCmpNI( name, tbl->keyname, tbl->length ) == 0 ) + return 1; + } + } + tbl++; + } + return 0; +} + +/* A check of the registry which a virus uses */ +static int KlezTypeCheck( void ) +{ + HKEY hKey; + LONG lResult; + TCHAR szKeyName[1024]; + DWORD dwIndex, dwCount; + FILETIME ft; + int viruscount = 0; + + /* Search a thing registered with Windows Startup */ + if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), + 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) { + return -1; + } + dwIndex = 0; + while( 1 ) { + dwCount = sizeof(szKeyName)/sizeof(TCHAR); + lResult = RegEnumValue( hKey, dwIndex, szKeyName, &dwCount, 0, NULL, NULL, NULL ); + if( lResult != ERROR_SUCCESS ) { + break; + } + viruscount += KlezTypeCheckSub( szKeyName, KEYTYPE_1 ); + dwIndex++; + } + RegCloseKey( hKey ); + + if( !IsNT() ) { + return viruscount; + } + + /* Search a thing registered with WindowsNT Service */ + if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Services"), + 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) { + return -1; + } + dwIndex = 0; + while( 1 ) { + dwCount = sizeof(szKeyName)/sizeof(TCHAR); + lResult = RegEnumKeyEx( hKey, dwIndex, szKeyName, &dwCount, 0, NULL, NULL, &ft ); + if( lResult != ERROR_SUCCESS ) { + break; + } + viruscount += KlezTypeCheckSub( szKeyName, KEYTYPE_2 ); + dwIndex++; + } + RegCloseKey( hKey ); + + return viruscount; +} + +int SimpleVirusChecker(void) +{ + int viruscount = 0; + + if( IsNT() < 0 ) + return -1; + + if( ExeRegistryCheck() > 0 ) + viruscount++; + + viruscount += KlezTypeCheck(); + + return viruscount; +} + diff --git a/References/VirtuaNESex_src_191105/SimpleVirusChecker.h b/References/VirtuaNESex_src_191105/SimpleVirusChecker.h new file mode 100644 index 00000000..006aa444 --- /dev/null +++ b/References/VirtuaNESex_src_191105/SimpleVirusChecker.h @@ -0,0 +1,49 @@ +/* + + SimpleVirusChecker + version 1.1 + programmed by Norix + + Copyright Note + source code: SimpleVirusChecker.c,SimpleVirusChecker.h + + Please use this program freely. + An author isn't concerned on a loss at having used this program at all. + An author prays for virus software disappearing from a PC in the world. + + --Attention-- + Because an author doesn't have a PC infected with a virus program, can't + guarantee it whether you were able to completely check it. + + Histroy: + v1.1 add WORM_FIZZER + add WORM_PALYH + add WORM_LOVGATE + add WORM_OPASERV + v1.11 add WORM_SOBIG.F +*/ +#ifndef __EASYVIRUSCHECKER__ +#define __EASYVIRUSCHECKER__ + +#include +#include + +#pragma comment( lib, "shlwapi.lib" ) + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* + ret==0 Don't exist in registry. + ret>0 The number of hit of the registry which a virus uses. +*/ +int SimpleVirusChecker(void); + +#if defined(__cplusplus) +} +#endif +#endif /* __EASYVIRUSCHECKER__ */ + + diff --git a/References/VirtuaNESex_src_191105/SoundDlg.cpp b/References/VirtuaNESex_src_191105/SoundDlg.cpp new file mode 100644 index 00000000..675609b7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/SoundDlg.cpp @@ -0,0 +1,148 @@ +// +// TEh_CAONX +// +// +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "VirtuaNESres.h" +#include "DebugOut.h" +#include "App.h" +#include "Pathlib.h" + +#include "Wnd.h" +#include "SoundDlg.h" + +UINT CSoundDlg::m_nVolumeID[] = { + IDC_SND_MASTER_SLIDER, 0, + IDC_SND_CH0_SLIDER, 1, + IDC_SND_CH1_SLIDER, 2, + IDC_SND_CH2_SLIDER, 3, + IDC_SND_CH3_SLIDER, 4, + IDC_SND_CH4_SLIDER, 5, + IDC_SND_EX0_SLIDER, 6, + IDC_SND_EX1_SLIDER, 7, + IDC_SND_EX2_SLIDER, 8, + IDC_SND_EX3_SLIDER, 9, + IDC_SND_EX4_SLIDER, 10, + IDC_SND_EX5_SLIDER, 11, + 0, 0 +}; + +DLG_MESSAGE_BEGIN(CSoundDlg) +// bZ[W +DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog ) +// R}h +DLG_COMMAND_BEGIN() +DLG_ON_COMMAND( IDOK, OnOK ) +DLG_ON_COMMAND( IDCANCEL, OnCancel ) +DLG_ON_COMMAND( IDDEFAULT, OnDefault ) +DLG_COMMAND_END() +DLG_MESSAGE_END() + +INT CSoundDlg::DoModal( HWND hWndParent ) +{ + return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_SOUND), + hWndParent, g_DlgProc, (LPARAM)this ); +} + +void CSoundDlg::OnInitialMember() +{ + INT i; + // `FbN{bNX + BTNCHECK( IDC_SND_ENABLE, Config.sound.bEnable ); + BTNCHECK( IDC_SND_VOLEFFECT_ENABLE, !Config.sound.bDisableVolumeEffect ); + BTNCHECK( IDC_SND_EXTSOUND_ENABLE, Config.sound.bExtraSoundEnable ); + + // XC_[ + for( i = 0; m_nVolumeID[i*2+0]; i++ ) { + ::SendDlgItemMessage( m_hWnd, m_nVolumeID[i*2+0], TBM_SETRANGE, TRUE, MAKELONG(0,200) ); + ::SendDlgItemMessage( m_hWnd, m_nVolumeID[i*2+0], TBM_SETPOS, TRUE, (WPARAM)200-Config.sound.nVolume[m_nVolumeID[i*2+1]] ); + ::SendDlgItemMessage( m_hWnd, m_nVolumeID[i*2+0], TBM_SETTICFREQ, 20, 0 ); + ::SendDlgItemMessage( m_hWnd, m_nVolumeID[i*2+0], TBM_SETLINESIZE, 0, 1 ); + ::SendDlgItemMessage( m_hWnd, m_nVolumeID[i*2+0], TBM_SETPAGESIZE, 0, 20 ); + } + // TvO[gR{{bNX + CHAR szMode[64]; + ::SendDlgItemMessage( m_hWnd, IDC_SND_SAMPLERATE_COMBO, CB_RESETCONTENT, 0, 0 ); + for( i = 0; i < 8; i++ ) { + ::wsprintf( szMode, "%d.%03dKHz %2dbits", + CConfig::SamplingRateTable[i*2+0]/1000, + CConfig::SamplingRateTable[i*2+0]%1000, + CConfig::SamplingRateTable[i*2+1] ); + ::SendDlgItemMessage( m_hWnd, IDC_SND_SAMPLERATE_COMBO, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szMode ); + } + // obt@TCYR{{bNX + ::SendDlgItemMessage( m_hWnd, IDC_SND_BUFFERSIZE_COMBO, CB_RESETCONTENT, 0, 0 ); + for( i = 2; i <= 10; i++ ) { + ::wsprintf( szMode, "%d Frame", i ); + ::SendDlgItemMessage( m_hWnd, IDC_SND_BUFFERSIZE_COMBO, CB_INSERTSTRING, (WPARAM)i-2, (LPARAM)szMode ); + } + + // tB^R{{bNX + ::SendDlgItemMessage( m_hWnd, IDC_SND_FILTERTYPE_COMBO, CB_RESETCONTENT, 0, 0 ); + for( i = IDS_SND_FILTER_NONE; i <= IDS_SND_FILTER_TYPE4; i++ ) { + CApp::LoadString( i, szMode, sizeof(szMode) ); + ::SendDlgItemMessage( m_hWnd, IDC_SND_FILTERTYPE_COMBO, CB_INSERTSTRING, (WPARAM)i-IDS_SND_FILTER_NONE, (LPARAM)szMode ); + } + + // I + ::SendDlgItemMessage( m_hWnd, IDC_SND_SAMPLERATE_COMBO, CB_SETCURSEL, 0, 0 ); + for( i = 0; i < 8; i++ ) { + if( Config.sound.nRate == CConfig::SamplingRateTable[i*2+0] + && Config.sound.nBits == CConfig::SamplingRateTable[i*2+1] ) { + ::SendDlgItemMessage( m_hWnd, IDC_SND_SAMPLERATE_COMBO, CB_SETCURSEL, (WPARAM)i, 0 ); + break; + } + } + ::SendDlgItemMessage( m_hWnd, IDC_SND_BUFFERSIZE_COMBO, CB_SETCURSEL, (WPARAM)Config.sound.nBufferSize-2, 0 ); + + ::SendDlgItemMessage( m_hWnd, IDC_SND_FILTERTYPE_COMBO, CB_SETCURSEL, (WPARAM)Config.sound.nFilterType, 0 ); +} + +DLGMSG CSoundDlg::OnInitDialog( DLGMSGPARAM ) +{ +// DEBUGOUT( "CSoundDlg::OnInitDialog\n" ); + m_ConfigSave = Config.sound; + OnInitialMember(); + + return TRUE; +} + +DLGCMD CSoundDlg::OnOK( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSoundDlg::OnOK\n" ); + + Config.sound.bEnable = IsBTNCHECK( IDC_SND_ENABLE ); + Config.sound.bDisableVolumeEffect = !IsBTNCHECK( IDC_SND_VOLEFFECT_ENABLE ); + Config.sound.bExtraSoundEnable = IsBTNCHECK( IDC_SND_EXTSOUND_ENABLE ); + + for( INT i = 0; m_nVolumeID[i*2+0]; i++ ) { + Config.sound.nVolume[m_nVolumeID[i*2+1]] = 200-::SendDlgItemMessage( m_hWnd, m_nVolumeID[i*2+0], TBM_GETPOS, 0, 0 ); + } + + INT sel = ::SendDlgItemMessage( m_hWnd, IDC_SND_SAMPLERATE_COMBO, CB_GETCURSEL, 0, 0 ); + Config.sound.nRate = CConfig::SamplingRateTable[sel*2+0]; + Config.sound.nBits = CConfig::SamplingRateTable[sel*2+1]; + Config.sound.nBufferSize = 2+::SendDlgItemMessage( m_hWnd, IDC_SND_BUFFERSIZE_COMBO, CB_GETCURSEL, 0, 0 ); + Config.sound.nFilterType = ::SendDlgItemMessage( m_hWnd, IDC_SND_FILTERTYPE_COMBO, CB_GETCURSEL, 0, 0 ); + + ::EndDialog( m_hWnd, IDOK ); +} + +DLGCMD CSoundDlg::OnCancel( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSoundDlg::OnCancel\n" ); + Config.sound = m_ConfigSave; + ::EndDialog( m_hWnd, IDCANCEL ); +} + +DLGCMD CSoundDlg::OnDefault( DLGCMDPARAM ) +{ +// DEBUGOUT( "CSoundDlg::OnDefault\n" ); + Config.sound.Default(); + OnInitialMember(); +} + diff --git a/References/VirtuaNESex_src_191105/SoundDlg.h b/References/VirtuaNESex_src_191105/SoundDlg.h new file mode 100644 index 00000000..438cd09f --- /dev/null +++ b/References/VirtuaNESex_src_191105/SoundDlg.h @@ -0,0 +1,37 @@ +// +// TEh_CAONX +// +#ifndef __CSOUNDDLG_INCLUDED__ +#define __CSOUNDDLG_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +using namespace std; + +#include "Wnd.h" +#include "Config.h" + +class CSoundDlg : public CWnd +{ +public: + // Override from CWnd + INT DoModal( HWND hWndParent ); +protected: + void OnInitialMember(); + + // Message map + DLG_MESSAGE_MAP() + DLGMSG OnInitDialog( DLGMSGPARAM ); + DLGCMD OnOK( DLGCMDPARAM ); + DLGCMD OnCancel( DLGCMDPARAM ); + DLGCMD OnDefault( DLGCMDPARAM ); + // + + CCfgSound m_ConfigSave; +private: + static UINT m_nVolumeID[]; +}; + +#endif // !__CSOUNDDLG_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/Typedef.h b/References/VirtuaNESex_src_191105/Typedef.h new file mode 100644 index 00000000..0dcf380f --- /dev/null +++ b/References/VirtuaNESex_src_191105/Typedef.h @@ -0,0 +1,58 @@ +/*----------------------------------------------------------------------*/ +/* */ +/* DATA TYPE DEFINEs */ +/* Norix */ +/* written 2000/11/09 */ +/* last modify ----/--/-- */ +/*----------------------------------------------------------------------*/ +#ifndef __TYPEDEF_INCLUDED__ +#define __TYPEDEF_INCLUDED__ + +typedef int BOOL; + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef unsigned __int64 QWORD; + +typedef unsigned char UBYTE; +typedef unsigned short UWORD; +typedef unsigned long ULONG; +typedef unsigned long UDWORD; +typedef unsigned __int64 UQWORD; + +typedef signed char SBYTE; +typedef signed short SWORD; +typedef signed long SLONG; +typedef signed long SDWORD; +typedef signed __int64 SQWORD; + +typedef signed int INT; +typedef unsigned int UINT; +typedef signed short SHORT; +typedef signed long LONG; + +typedef BYTE *LPBYTE; +typedef WORD *LPWORD; +typedef DWORD *LPDWORD; + +typedef SBYTE *LPSBYTE; +typedef SWORD *LPSWORD; +typedef SLONG *LPSLONG; +typedef SDWORD *LPSDWORD; + +typedef UBYTE *LPUBYTE; +typedef UWORD *LPUWORD; +typedef ULONG *LPULONG; +typedef UDWORD *LPUDWORD; + +typedef SHORT *LPSHORT; +typedef LONG *LPLONG; + +// Byte pair +typedef union { + struct { BYTE L; BYTE H; } B; + WORD W; +} PAIR, *LPPAIR; + +#endif diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.aps b/References/VirtuaNESex_src_191105/VirtuaNES.aps new file mode 100644 index 00000000..65ba496f Binary files /dev/null and b/References/VirtuaNESex_src_191105/VirtuaNES.aps differ diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.dsp b/References/VirtuaNESex_src_191105/VirtuaNES.dsp new file mode 100644 index 00000000..599f908f --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNES.dsp @@ -0,0 +1,5859 @@ +# Microsoft Developer Studio Project File - Name="VirtuaNES" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=VirtuaNES - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "VirtuaNES.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "VirtuaNES.mak" CFG="VirtuaNES - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "VirtuaNES - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "VirtuaNES - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "VirtuaNES - Win32 Profile" (based on "Win32 (x86) Application") +!MESSAGE "VirtuaNES - Win32 Release_Debugout" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "Zlib" /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\ApuEx\emu2413" /I "NES\PadEx" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x411 /d "NDEBUG" +# ADD RSC /l 0x411 /i "res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo /o"Release\VirtuaNES.bsc" +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib shlwapi.lib /nologo /subsystem:windows /map /machine:I386 /out:"Release\VirtuaNESex.exe" +# SUBTRACT LINK32 /nodefaultlib +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=.\rebuidFiles.bat +# End Special Build Tool + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MT /W3 /Gm /GX /ZI /Od /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\ApuEx\emu2413" /I "NES\PadEx" /I "Zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x411 /d "_DEBUG" +# ADD RSC /l 0x411 /fo"Release\VirtuaNES.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo /o"Release\VirtuaNES.bsc" +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib shlwapi.lib libcmtd.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"Debug\VirtuaNESex.exe" /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=.\rebuidFiles.bat +# End Special Build Tool + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "VirtuaNES___Win32_Profile" +# PROP BASE Intermediate_Dir "VirtuaNES___Win32_Profile" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Profile" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\PadEx" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Z7 /O2 /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\ApuEx\emu2413" /I "NES\PadEx" /I "Zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x411 /d "NDEBUG" +# ADD RSC /l 0x411 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib shlwapi.lib /nologo /subsystem:windows /profile /map:"VirtuaNES.map" /debug /machine:I386 /out:"VirtuaNESex.exe" +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "VirtuaNES___Win32_Release_Debugout" +# PROP BASE Intermediate_Dir "VirtuaNES___Win32_Release_Debugout" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Release_Debugout" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\PadEx" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_DEBUGOUT" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\ApuEx\emu2413" /I "NES\PadEx" /I "Zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_DEBUGOUT" /Fr /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x411 /d "NDEBUG" +# ADD RSC /l 0x411 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib shlwapi.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"Release_Debugout\VirtuaNESex.exe" +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "VirtuaNES - Win32 Release" +# Name "VirtuaNES - Win32 Debug" +# Name "VirtuaNES - Win32 Profile" +# Name "VirtuaNES - Win32 Release_Debugout" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\AboutDlg.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# ADD CPP /Gm- + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\App.cpp +# End Source File +# Begin Source File + +SOURCE=.\Archive.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChatDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\CheatDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Com.cpp +# End Source File +# Begin Source File + +SOURCE=.\Config.cpp +# End Source File +# Begin Source File + +SOURCE=.\ControllerDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\Crclib.cpp +# End Source File +# Begin Source File + +SOURCE=.\DatachBarcodeDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\DebugOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\DipSwitchDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\DirectDraw.cpp +# End Source File +# Begin Source File + +SOURCE=.\DirectInput.cpp +# End Source File +# Begin Source File + +SOURCE=.\DirectSound.cpp +# End Source File +# Begin Source File + +SOURCE=.\EmulatorDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\EmuThread.cpp +# End Source File +# Begin Source File + +SOURCE=.\FolderDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\GameOptionDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\GraphicsDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\JoyAxisDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\LanguageDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\LauncherDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\MainFrame.cpp +# End Source File +# Begin Source File + +SOURCE=.\MemoryView.cpp +# End Source File +# Begin Source File + +SOURCE=.\MMTimer.cpp +# End Source File +# Begin Source File + +SOURCE=.\MovieDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\MovieInfoDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\NameTableView.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetPlay.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetPlayDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\PaletteEdit.cpp +# End Source File +# Begin Source File + +SOURCE=.\PaletteView.cpp +# End Source File +# Begin Source File + +SOURCE=.\Pathlib.cpp +# End Source File +# Begin Source File + +SOURCE=.\PatternView.cpp +# End Source File +# Begin Source File + +SOURCE=.\Plugin.cpp +# End Source File +# Begin Source File + +SOURCE=.\Recent.cpp +# End Source File +# Begin Source File + +SOURCE=.\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=.\RomInfoDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\ShortcutDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\SimpleVirusChecker.c +# End Source File +# Begin Source File + +SOURCE=.\SoundDlg.cpp +# End Source File +# Begin Source File + +SOURCE=.\VirtuaNES.rc +# End Source File +# Begin Source File + +SOURCE=.\WaveRec.cpp +# End Source File +# Begin Source File + +SOURCE=.\WinMain.cpp +# End Source File +# Begin Source File + +SOURCE=.\Wnd.cpp +# End Source File +# Begin Source File + +SOURCE=.\WndHook.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\AboutDlg.h +# End Source File +# Begin Source File + +SOURCE=.\App.h +# End Source File +# Begin Source File + +SOURCE=.\Archive.h +# End Source File +# Begin Source File + +SOURCE=.\ChatDlg.h +# End Source File +# Begin Source File + +SOURCE=.\CheatDlg.h +# End Source File +# Begin Source File + +SOURCE=.\CHyperLink.h +# End Source File +# Begin Source File + +SOURCE=.\Com.h +# End Source File +# Begin Source File + +SOURCE=.\Config.h +# End Source File +# Begin Source File + +SOURCE=.\ControllerDlg.h +# End Source File +# Begin Source File + +SOURCE=.\Crclib.h +# End Source File +# Begin Source File + +SOURCE=.\DatachBarcodeDlg.h +# End Source File +# Begin Source File + +SOURCE=.\DebugOut.h +# End Source File +# Begin Source File + +SOURCE=.\DipSwitchDlg.h +# End Source File +# Begin Source File + +SOURCE=.\DirectDraw.h +# End Source File +# Begin Source File + +SOURCE=.\DirectInput.h +# End Source File +# Begin Source File + +SOURCE=.\DirectSound.h +# End Source File +# Begin Source File + +SOURCE=.\EmulatorDlg.h +# End Source File +# Begin Source File + +SOURCE=.\EmuThread.h +# End Source File +# Begin Source File + +SOURCE=.\FolderDlg.h +# End Source File +# Begin Source File + +SOURCE=.\GameOptionDlg.h +# End Source File +# Begin Source File + +SOURCE=.\GraphicsDlg.h +# End Source File +# Begin Source File + +SOURCE=.\JoyAxisDlg.h +# End Source File +# Begin Source File + +SOURCE=.\LanguageDlg.h +# End Source File +# Begin Source File + +SOURCE=.\LauncherDlg.h +# End Source File +# Begin Source File + +SOURCE=.\lzAscii.h +# End Source File +# Begin Source File + +SOURCE=.\lzSight.h +# End Source File +# Begin Source File + +SOURCE=.\lzTVlayer.h +# End Source File +# Begin Source File + +SOURCE=.\Macro.h +# End Source File +# Begin Source File + +SOURCE=.\MainFrame.h +# End Source File +# Begin Source File + +SOURCE=.\MemoryView.h +# End Source File +# Begin Source File + +SOURCE=.\MMTimer.h +# End Source File +# Begin Source File + +SOURCE=.\MovieDlg.h +# End Source File +# Begin Source File + +SOURCE=.\MovieInfoDlg.h +# End Source File +# Begin Source File + +SOURCE=.\NameTableView.h +# End Source File +# Begin Source File + +SOURCE=.\NetPlay.h +# End Source File +# Begin Source File + +SOURCE=.\NetPlayDlg.h +# End Source File +# Begin Source File + +SOURCE=.\nx_2xSaI.h +# End Source File +# Begin Source File + +SOURCE=.\nx_Scale2x.h +# End Source File +# Begin Source File + +SOURCE=.\nx_Super2xSaI.h +# End Source File +# Begin Source File + +SOURCE=.\nx_Super2xSaI_32bpp_mmx.h +# End Source File +# Begin Source File + +SOURCE=.\nx_SuperEagle.h +# End Source File +# Begin Source File + +SOURCE=.\PaletteEdit.h +# End Source File +# Begin Source File + +SOURCE=.\PaletteView.h +# End Source File +# Begin Source File + +SOURCE=.\Pathlib.h +# End Source File +# Begin Source File + +SOURCE=.\PatternView.h +# End Source File +# Begin Source File + +SOURCE=.\Plugin.h +# End Source File +# Begin Source File + +SOURCE=.\Pngwrite.h +# End Source File +# Begin Source File + +SOURCE=.\Recent.h +# End Source File +# Begin Source File + +SOURCE=.\Registry.h +# End Source File +# Begin Source File + +SOURCE=.\Render.h +# End Source File +# Begin Source File + +SOURCE=.\Render16bpp.h +# End Source File +# Begin Source File + +SOURCE=.\Render24bpp.h +# End Source File +# Begin Source File + +SOURCE=.\Render32bpp.h +# End Source File +# Begin Source File + +SOURCE=.\Render8bpp.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\RomInfoDlg.h +# End Source File +# Begin Source File + +SOURCE=.\ShortcutDlg.h +# End Source File +# Begin Source File + +SOURCE=.\SimpleVirusChecker.h +# End Source File +# Begin Source File + +SOURCE=.\SoundDlg.h +# End Source File +# Begin Source File + +SOURCE=.\Typedef.h +# End Source File +# Begin Source File + +SOURCE=.\VirtuaNESres.h +# End Source File +# Begin Source File + +SOURCE=.\WaveRec.h +# End Source File +# Begin Source File + +SOURCE=.\Wnd.h +# End Source File +# Begin Source File + +SOURCE=.\WndHook.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\CheatImageList.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\header_down.ico +# End Source File +# Begin Source File + +SOURCE=.\res\header_up.ico +# End Source File +# Begin Source File + +SOURCE=.\LauncherImageList.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\VirtuaNES.ico +# End Source File +# Begin Source File + +SOURCE=.\VirtuaNES.ico +# End Source File +# End Group +# Begin Group "NES" + +# PROP Default_Filter "" +# Begin Group "Mapper" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\NES\Mapper\EEPROM.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper.h +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper000.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper000.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper001.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper001.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper002.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper002.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper003.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper003.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper004.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper004.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper005.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper005.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper006.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper006.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper007.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper007.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper008.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper008.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper009.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper009.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper010.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper010.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper011.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper011.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper012.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper012.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper013.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper013.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper015.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper015.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper016.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper016.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper017.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper017.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper018.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper018.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper019.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper019.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper021.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper021.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper022.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper022.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper023.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper023.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper024.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper024.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper025.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper025.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper026.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper026.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper027.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper027.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper032.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper032.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper033.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper033.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper034.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper034.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper040.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper040.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper041.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper041.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper042.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper042.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper043.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper043.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper044.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper044.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper045.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper045.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper046.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper046.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper047.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper047.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper048.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper048.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper050.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper050.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper051.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper051.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper057.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper057.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper058.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper058.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper060.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper060.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper062.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper062.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper064.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper064.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper065.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper065.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper066.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper066.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper067.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper067.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper068.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper068.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper069.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper069.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper070.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper070.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper071.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper071.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper072.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper072.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper073.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper073.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper074.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper074.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper075.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper075.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper076.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper076.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper077.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper077.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper078.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper078.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper079.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper079.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper080.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper080.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper082.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper082.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper083.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper083.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper085.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper085.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper086.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper086.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper087.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper087.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper088.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper088.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper089.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper089.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper090.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper090.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper091.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper091.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper092.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper092.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper093.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper093.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper094.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper094.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper095.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper095.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper096.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper096.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper097.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper097.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper099.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper099.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper100.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper100.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper101.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper101.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper105.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper105.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper107.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper107.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper108.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper108.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper109.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper109.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper110.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper110.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper111.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper111.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper112.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper112.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper113.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper113.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper114.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper114.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper115.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper115.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper116.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper116.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper117.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper117.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper118.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper118.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper119.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper119.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper122.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper122.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper133.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper133.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper134.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper134.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper135.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper135.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper140.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper140.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper142.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper142.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper151.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper151.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper160.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper160.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper163.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper163.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper164.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper164.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper165.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper165.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper167.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper167.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper180.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper180.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper181.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper181.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper182.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper182.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper183.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper183.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper185.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper185.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper187.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper187.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper188.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper188.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper189.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper189.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper190.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper190.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper191.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper191.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper193.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper193.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper194.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper194.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper198.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper198.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper200.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper200.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper201.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper201.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper202.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper202.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper222.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper222.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper225.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper225.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper226.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper226.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper227.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper227.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper228.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper228.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper229.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper229.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper230.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper230.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper231.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper231.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper232.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper232.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper233.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper233.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper234.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper234.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper235.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper235.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper236.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper236.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper240.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper240.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper241.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper241.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper242.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper242.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper243.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper243.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper244.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper244.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper245.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper245.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper246.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper246.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper248.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper248.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper249.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper249.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper251.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper251.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper252.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper252.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper254.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper254.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper255.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\Mapper255.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\MapperFactory.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\MapperFDS.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\MapperFDS.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\MapperNSF.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\Mapper\MapperNSF.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Group +# Begin Group "ApuEx" + +# PROP Default_Filter "" +# Begin Group "emu2413" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\NES\ApuEX\emu2413\2413tone.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\emu2413\emu2413.c +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\emu2413\emu2413.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\emu2413\vrc7tone.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_FDS.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_FDS.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_FME7.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_FME7.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_INTERFACE.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_INTERNAL.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_INTERNAL.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_MMC5.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_MMC5.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_N106.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_N106.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_VRC6.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_VRC6.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_VRC7.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\APU_VRC7.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ApuEX\FDSplugin.h +# End Source File +# End Group +# Begin Group "PadEx" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_CrazyClimber.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_CrazyClimber.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_ExcitingBoxing.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_ExcitingBoxing.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_FamlyTrainer.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_FamlyTrainer.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_HyperShot.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_HyperShot.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Keyboard.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Keyboard.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Mahjang.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Mahjang.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_OekakidsTablet.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_OekakidsTablet.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Paddle.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Paddle.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_SpaceShadowGun.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_SpaceShadowGun.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Subor_Keyboard.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Subor_Keyboard.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Toprider.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Toprider.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_TurboFile.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_TurboFile.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_VSUnisystem.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_VSUnisystem.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_VSZapper.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_VSZapper.h +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Zapper.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\PadEX\EXPAD_Zapper.h + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\NES\APU.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\APU.h +# End Source File +# Begin Source File + +SOURCE=.\NES\Cheat.h +# End Source File +# Begin Source File + +SOURCE=.\NES\Cpu.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\CPU.h +# End Source File +# Begin Source File + +SOURCE=.\NES\MMU.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\MMU.h +# End Source File +# Begin Source File + +SOURCE=.\NES\Nes.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\Nes.h +# End Source File +# Begin Source File + +SOURCE=.\NES\PAD.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\PAD.h +# End Source File +# Begin Source File + +SOURCE=.\NES\PPU.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\PPU.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ROM.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ROM.h +# End Source File +# Begin Source File + +SOURCE=.\NES\ROM_Patch.cpp + +!IF "$(CFG)" == "VirtuaNES - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "VirtuaNES - Win32 Release_Debugout" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\NES\ROMDB.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\ROMDB.h +# End Source File +# Begin Source File + +SOURCE=.\NES\State.h +# End Source File +# Begin Source File + +SOURCE=.\NES\VS_Setting.h +# End Source File +# Begin Source File + +SOURCE=.\NES\VsUnisystem.cpp +# End Source File +# Begin Source File + +SOURCE=.\NES\VsUnisystem.h +# End Source File +# End Group +# Begin Group "Zlib" + +# PROP Default_Filter "*.c *.cpp *.h" +# Begin Source File + +SOURCE=.\zlib\unzip.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\unzip.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\zlib.lib +# End Source File +# End Group +# Begin Group "DOC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Doc\Readme.txt +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "*.c *.cpp *.h" +# Begin Source File + +SOURCE=.\7z\7z.h +# End Source File +# Begin Source File + +SOURCE=.\7z\7zAlloc.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zAlloc.h +# End Source File +# Begin Source File + +SOURCE=.\7z\7zBuf.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zBuf.h +# End Source File +# Begin Source File + +SOURCE=.\7z\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=.\7z\7zCrcOpt.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zDec.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zFile.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zFile.h +# End Source File +# Begin Source File + +SOURCE=.\7z\7zIn.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zMain.c +# End Source File +# Begin Source File + +SOURCE=.\7z\7zStream.c +# End Source File +# Begin Source File + +SOURCE=.\7z\Bcj2.c +# End Source File +# Begin Source File + +SOURCE=.\7z\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=.\7z\Bra.c +# End Source File +# Begin Source File + +SOURCE=.\7z\Bra.h +# End Source File +# Begin Source File + +SOURCE=.\7z\Bra86.c +# End Source File +# Begin Source File + +SOURCE=.\7z\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=.\7z\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=.\7z\Lzma2Dec.c +# End Source File +# Begin Source File + +SOURCE=.\7z\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=.\7z\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=.\7z\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=.\7z\Ppmd.h +# End Source File +# Begin Source File + +SOURCE=.\7z\Ppmd7.c +# End Source File +# Begin Source File + +SOURCE=.\7z\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=.\7z\Ppmd7Dec.c +# End Source File +# Begin Source File + +SOURCE=.\7z\Types.h +# End Source File +# End Group +# End Target +# End Project diff --git a/virtuanessrc097-master/VirtuaNES.dsw b/References/VirtuaNESex_src_191105/VirtuaNES.dsw similarity index 100% rename from virtuanessrc097-master/VirtuaNES.dsw rename to References/VirtuaNESex_src_191105/VirtuaNES.dsw diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.opt b/References/VirtuaNESex_src_191105/VirtuaNES.opt new file mode 100644 index 00000000..c0a3744c Binary files /dev/null and b/References/VirtuaNESex_src_191105/VirtuaNES.opt differ diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.plg b/References/VirtuaNESex_src_191105/VirtuaNES.plg new file mode 100644 index 00000000..b8ebe055 --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNES.plg @@ -0,0 +1,124 @@ + + +
+

Build Log

+

+--------------------Configuration: VirtuaNES - Win32 Release-------------------- +

+

Command Lines

+Creating temporary file "C:\Users\yefeng\AppData\Local\Temp\RSPBAC.tmp" with contents +[ +/nologo /MT /W3 /GX /O2 /I "Zlib" /I "." /I "NES" /I "NES\Mapper" /I "NES\ApuEx" /I "NES\ApuEx\emu2413" /I "NES\PadEx" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR"Release/" /Fp"Release/VirtuaNES.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c +"E:\Game\NES\Emulator\VirtuaNESex_src_chen\AboutDlg.cpp" +] +Creating command line "cl.exe @C:\Users\yefeng\AppData\Local\Temp\RSPBAC.tmp" +Creating temporary file "C:\Users\yefeng\AppData\Local\Temp\RSPBAD.tmp" with contents +[ +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib imm32.lib dinput.lib shlwapi.lib /nologo /subsystem:windows /incremental:no /pdb:"VirtuaNESex.pdb" /map:"Release/VirtuaNESex.map" /machine:I386 /out:"Release\VirtuaNESex.exe" +.\Release\AboutDlg.obj +.\Release\App.obj +.\Release\Archive.obj +.\Release\ChatDlg.obj +.\Release\CheatDlg.obj +.\Release\Com.obj +.\Release\Config.obj +.\Release\ControllerDlg.obj +.\Release\Crclib.obj +.\Release\DatachBarcodeDlg.obj +.\Release\DebugOut.obj +.\Release\DipSwitchDlg.obj +.\Release\DirectDraw.obj +.\Release\DirectInput.obj +.\Release\DirectSound.obj +.\Release\EmulatorDlg.obj +.\Release\EmuThread.obj +.\Release\FolderDlg.obj +.\Release\GameOptionDlg.obj +.\Release\GraphicsDlg.obj +.\Release\JoyAxisDlg.obj +.\Release\LanguageDlg.obj +.\Release\LauncherDlg.obj +.\Release\MainFrame.obj +.\Release\MemoryView.obj +.\Release\MMTimer.obj +.\Release\MovieDlg.obj +.\Release\MovieInfoDlg.obj +.\Release\NameTableView.obj +.\Release\NetPlay.obj +.\Release\NetPlayDlg.obj +.\Release\PaletteEdit.obj +.\Release\PaletteView.obj +.\Release\Pathlib.obj +.\Release\PatternView.obj +.\Release\Plugin.obj +.\Release\Recent.obj +.\Release\Registry.obj +.\Release\RomInfoDlg.obj +.\Release\ShortcutDlg.obj +.\Release\SimpleVirusChecker.obj +.\Release\SoundDlg.obj +.\Release\WaveRec.obj +.\Release\WinMain.obj +.\Release\Wnd.obj +.\Release\WndHook.obj +.\Release\Mapper.obj +.\Release\MapperFactory.obj +.\Release\emu2413.obj +.\Release\APU_FDS.obj +.\Release\APU_FME7.obj +.\Release\APU_INTERNAL.obj +.\Release\APU_MMC5.obj +.\Release\APU_N106.obj +.\Release\APU_VRC6.obj +.\Release\APU_VRC7.obj +.\Release\APU.obj +.\Release\Cpu.obj +.\Release\MMU.obj +.\Release\Nes.obj +.\Release\PAD.obj +.\Release\PPU.obj +.\Release\ROM.obj +.\Release\ROMDB.obj +.\Release\VsUnisystem.obj +.\Release\unzip.obj +.\Release\7zAlloc.obj +.\Release\7zBuf.obj +.\Release\7zCrc.obj +.\Release\7zCrcOpt.obj +.\Release\7zDec.obj +.\Release\7zFile.obj +.\Release\7zIn.obj +.\Release\7zMain.obj +.\Release\7zStream.obj +.\Release\Bcj2.obj +.\Release\Bra.obj +.\Release\Bra86.obj +.\Release\CpuArch.obj +.\Release\Lzma2Dec.obj +.\Release\LzmaDec.obj +.\Release\Ppmd7.obj +.\Release\Ppmd7Dec.obj +.\Release\VirtuaNES.res +.\zlib\zlib.lib +] +Creating command line "link.exe @C:\Users\yefeng\AppData\Local\Temp\RSPBAD.tmp" +

Output Window

+Compiling... +AboutDlg.cpp +Linking... +Creating temporary file "C:\Users\yefeng\AppData\Local\Temp\RSPE1F.bat" with contents +[ +@echo off +.\rebuidFiles.bat +] +Creating command line "C:\Users\yefeng\AppData\Local\Temp\RSPE1F.bat" + +" --- del AboutDlg.obj ---" + + + +

Results

+VirtuaNESex.exe - 0 error(s), 0 warning(s) +
+ + diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.rc b/References/VirtuaNESex_src_191105/VirtuaNES.rc new file mode 100644 index 00000000..61ec9d65 --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNES.rc @@ -0,0 +1,128 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" +#include "virtuanesres.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Japanese resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) +#ifdef _WIN32 +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +#pragma code_page(932) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "#include ""virtuanesres.h""\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON ICON DISCARDABLE "res\\VirtuaNES.ico" +IDI_SORT_DOWN ICON DISCARDABLE "res\\header_down.ico" +IDI_SORT_UP ICON DISCARDABLE "res\\header_up.ico" + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,8,6 + PRODUCTVERSION 0,0,8,6 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041104b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "VirtuaNES NES emulator for Win32\0" + VALUE "FileVersion", "0.86a\0" + VALUE "InternalName", "VirtuaNES\0" + VALUE "LegalCopyright", "Copyright (C) 2001-2003 Norix\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "VirtuaNES.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "VirtuaNES NES emulator for Win32\0" + VALUE "ProductVersion", "0.86a\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x411, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_CHEATIMAGELIST BITMAP DISCARDABLE "res\\CheatImageList.bmp" +IDB_LAUNCHERIMAGELIST BITMAP DISCARDABLE "res\\LauncherImageList.bmp" +#endif // Japanese resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.sln b/References/VirtuaNESex_src_191105/VirtuaNES.sln new file mode 100644 index 00000000..50b92736 --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNES.sln @@ -0,0 +1,27 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VirtuaNES", "VirtuaNES.vcproj", "{49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Profile = Profile + Release = Release + Release_Debugout = Release_Debugout + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Debug.ActiveCfg = Debug|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Debug.Build.0 = Debug|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Profile.ActiveCfg = Profile|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Profile.Build.0 = Profile|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Release.ActiveCfg = Release|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Release.Build.0 = Release|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Release_Debugout.ActiveCfg = Release_Debugout|Win32 + {49BF2A1B-0A90-4B4B-A8A1-9ED229E1FFDF}.Release_Debugout.Build.0 = Release_Debugout|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.vcb b/References/VirtuaNESex_src_191105/VirtuaNES.vcb new file mode 100644 index 00000000..29fbb1f2 Binary files /dev/null and b/References/VirtuaNESex_src_191105/VirtuaNES.vcb differ diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.vco b/References/VirtuaNESex_src_191105/VirtuaNES.vco new file mode 100644 index 00000000..743ec322 Binary files /dev/null and b/References/VirtuaNESex_src_191105/VirtuaNES.vco differ diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.vcproj b/References/VirtuaNESex_src_191105/VirtuaNES.vcproj new file mode 100644 index 00000000..ce70e4a6 --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNES.vcproj @@ -0,0 +1,14557 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/References/VirtuaNESex_src_191105/VirtuaNES.vcw b/References/VirtuaNESex_src_191105/VirtuaNES.vcw new file mode 100644 index 00000000..eabf69de --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNES.vcw @@ -0,0 +1,17 @@ +Microsoft eMbedded Visual Tools Workspace File, Format Version 4.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/References/VirtuaNESex_src_191105/VirtuaNESres.h b/References/VirtuaNESex_src_191105/VirtuaNESres.h new file mode 100644 index 00000000..edb9bcd0 --- /dev/null +++ b/References/VirtuaNESex_src_191105/VirtuaNESres.h @@ -0,0 +1,922 @@ +#ifndef __VIRTUANES_RESOURCE_INCLUDED__ +#define __VIRTUANES_RESOURCE_INCLUDED__ + +// VirtuaNES version +#define VIRTUANES_VERSION 0x0086 +#define VIRTUANES_FIXVERSION "" +#define VIRTUANES_PLUGIN_VERSION 0x0085 + +// VirtuaNES window class +#define VIRTUANES_WNDCLASS "VirtuaNESwndclass" +#define VIRTUANES_CAPTION "VirtuaNESex" +#define VIRTUANES_MUTEX "VirtuaNESmutex" + +// VirtuaNES Website +#define VIRTUANES_WEBSITE "http://virtuanes.s1.xrea.com:8080/" + +// VirtuaNES Author E-mail +#define VIRTUANES_EMAILNAME "norix_v" +#define VIRTUANES_EMAILDOMAIN "yahoo.co.jp" + +// VirtuaNES private windows message +#define WM_VNS_ERRORMSG (WM_APP+0) +#define WM_VNS_COMMANDLINE (WM_APP+1) +#define WM_VNS_LAUNCHERCMD (WM_APP+2) +#define WM_VNS_SHORTCUTENABLE (WM_APP+3) +#define WM_VNS_CHATPOPUP (WM_APP+4) // Netplay + +// VirtuaNES Resource define +// Error string +#define IDS_ERROR 0x0001 +#define IDS_ERROR_STARTUP 0x0002 +#define IDS_ERROR_UNKNOWN 0x0003 +#define IDS_ERROR_OPEN 0x0004 +#define IDS_ERROR_READ 0x0005 +#define IDS_ERROR_WRITE 0x0006 +#define IDS_ERROR_OUTOFMEMORY 0x0007 + +#define IDS_ERROR_ILLEGALOPCODE 0x0010 +#define IDS_ERROR_UNSUPPORTFORMAT 0x0011 +#define IDS_ERROR_INVALIDNESHEADER 0x0012 +#define IDS_ERROR_SMALLFILE 0x0013 +#define IDS_ERROR_UNSUPPORTMAPPER 0x0014 +#define IDS_ERROR_NODISKBIOS 0x0015 +#define IDS_ERROR_UNSUPPORTDISK 0x0016 +#define IDS_ERROR_ILLEGALDISKSIZE 0x0017 + +#define IDS_ERROR_ILLEGALMAPPERNO 0x0020 +#define IDS_ERROR_ILLEGALHEADER 0x0021 +#define IDS_ERROR_ILLEGALSTATECRC 0x0022 +#define IDS_ERROR_ILLEGALMOVIECRC 0x0023 +#define IDS_ERROR_ILLEGALMOVIEVER 0x0024 // Movie playback +#define IDS_ERROR_ILLEGALMOVIEOLD 0x0025 +#define IDS_ERROR_ILLEGALMOVIECRC_A 0x0026 // Movie append record +#define IDS_ERROR_ILLEGALMOVIEVER_A 0x0027 +#define IDS_ERROR_ILLEGALMOVIEOLD_A 0x0028 + +#define IDS_ERROR_NETWORKDISCONNECT 0x0030 +#define IDS_ERROR_NETWORKERROR 0x0031 +#define IDS_ERROR_NETWORKERROR_VERSION 0x0032 // Different version +#define IDS_ERROR_NETWORKERROR_CRC 0x0033 // Different CRC + +// User interface +#define IDS_UI_OPENROM 0x0100 +#define IDS_UI_OPENPALETTE 0x0101 +#define IDS_UI_BROWSE 0x0102 +#define IDS_UI_SAVEPALETTE 0x0103 +#define IDS_UI_WAVERECORD 0x0110 +#define IDS_UI_PLAYMOVIE 0x0118 +#define IDS_UI_RECMOVIE 0x0119 +#define IDS_UI_APPENDMOVIE 0x011A + +#define IDS_UI_LOADCHEATCODE 0x0120 +#define IDS_UI_SAVECHEATCODE 0x0121 +#define IDS_UI_LOADGENIECODE 0x0122 + +#define IDS_UI_PLAYTAPE 0x0128 +#define IDS_UI_RECTAPE 0x0129 + +// Emulator priority +#define IDS_EMU_PRIORITY_IDLE 0x0200 +#define IDS_EMU_PRIORITY_MOSTLOWER 0x0201 +#define IDS_EMU_PRIORITY_LOWER 0x0202 +#define IDS_EMU_PRIORITY_NORMAL 0x0203 +#define IDS_EMU_PRIORITY_HIGHER 0x0204 +#define IDS_EMU_PRIORITY_MOSTHIGHER 0x0205 +#define IDS_EMU_PRIORITY_REALTIME 0x0206 + +// Sound filter +#define IDS_SND_FILTER_NONE 0x0210 +#define IDS_SND_FILTER_TYPE1 0x0211 +#define IDS_SND_FILTER_TYPE2 0x0212 +#define IDS_SND_FILTER_TYPE3 0x0213 +#define IDS_SND_FILTER_TYPE4 0x0214 + +// Controller setting select +#define IDS_CTR_SELECT1 0x0220 +#define IDS_CTR_SELECT2 0x0221 + +// GameOptions +#define IDS_OPT_RENDER_POST_ALL 0x0230 +#define IDS_OPT_RENDER_PRE_ALL 0x0231 +#define IDS_OPT_RENDER_POST 0x0232 +#define IDS_OPT_RENDER_PRE 0x0233 +#define IDS_OPT_RENDER_TILE 0x0234 +#define IDS_OPT_IRQ_HSYNC 0x0235 +#define IDS_OPT_IRQ_CLOCK 0x0236 +#define IDS_OPT_VIDEOMODE_NTSC 0x0237 +#define IDS_OPT_VIDEOMODE_PAL 0x0238 +#define IDS_OPT_VIDEOMODE_PALCHINA 0x0239 + +// Shortcut +#define IDS_CUT_TITLE 0x0400 +#define IDS_CUT_TYPE 0x0401 +#define IDS_CUT_KEY 0x0402 +#define IDS_CUT_KEY2 0x0403 + +#define IDS_CUT_OPEN 0x0410 +#define IDS_CUT_CLOSE 0x0411 +#define IDS_CUT_LAUNCHER 0x0414 +#define IDS_CUT_ROMINFO 0x0415 +#define IDS_CUT_WAVERECORD 0x0416 +#define IDS_CUT_NETPLAY_CONNECT 0x0418 +#define IDS_CUT_NETPLAY_DISCONNECT 0x0419 +#define IDS_CUT_NETPLAY_CHAT 0x041A +#define IDS_CUT_EXIT 0x041F + +#define IDS_CUT_HWRESET 0x0420 +#define IDS_CUT_SWRESET 0x0421 +#define IDS_CUT_PAUSE 0x0422 +#define IDS_CUT_THROTTLE 0x0423 +#define IDS_CUT_FRAMESKIP_AUTO 0x0424 +#define IDS_CUT_FRAMESKIP_UP 0x0425 +#define IDS_CUT_FRAMESKIP_DOWN 0x0426 +#define IDS_CUT_ONEFRAME 0x0427 +#define IDS_CUT_KEYTHROTTLE 0x0428 + +#define IDS_CUT_STATE_LOAD 0x0430 +#define IDS_CUT_STATE_SAVE 0x0431 +#define IDS_CUT_STATE_UP 0x0432 +#define IDS_CUT_STATE_DOWN 0x0433 +#define IDS_CUT_STATE_SLOT0 0x0440 +#define IDS_CUT_STATE_SLOT1 0x0441 +#define IDS_CUT_STATE_SLOT2 0x0442 +#define IDS_CUT_STATE_SLOT3 0x0443 +#define IDS_CUT_STATE_SLOT4 0x0444 +#define IDS_CUT_STATE_SLOT5 0x0445 +#define IDS_CUT_STATE_SLOT6 0x0446 +#define IDS_CUT_STATE_SLOT7 0x0447 +#define IDS_CUT_STATE_SLOT8 0x0448 +#define IDS_CUT_STATE_SLOT9 0x0449 + +#define IDS_CUT_DISK_EJECT 0x0450 +#define IDS_CUT_DISK_0A 0x0451 +#define IDS_CUT_DISK_0B 0x0452 +#define IDS_CUT_DISK_1A 0x0453 +#define IDS_CUT_DISK_1B 0x0454 + +#define IDS_CUT_MOVIE_INFO 0x0460 +#define IDS_CUT_MOVIE_PLAY 0x0461 +#define IDS_CUT_MOVIE_REC 0x0462 +#define IDS_CUT_MOVIE_REC_APPEND 0x0463 +#define IDS_CUT_MOVIE_STOP 0x0464 + +#define IDS_CUT_TAPE_PLAY 0x0468 +#define IDS_CUT_TAPE_REC 0x0469 +#define IDS_CUT_TAPE_STOP 0x046A + +#define IDS_CUT_ZOOMx1 0x0470 +#define IDS_CUT_ZOOMx2 0x0471 +#define IDS_CUT_ZOOMx3 0x0472 +#define IDS_CUT_ZOOMx4 0x0473 +#define IDS_CUT_FULLSCREEN 0x0478 + +#define IDS_CUT_SNAPSHOT 0x0480 +#define IDS_CUT_FPSDISP 0x0481 +#define IDS_CUT_TVASPECT 0x0482 +#define IDS_CUT_TVFRAME 0x0483 +#define IDS_CUT_SCANLINE 0x0484 +#define IDS_CUT_ALLLINE 0x0485 +#define IDS_CUT_ALLSPRITE 0x0486 +#define IDS_CUT_SYNCDRAW 0x0487 +#define IDS_CUT_FITSCREEN 0x0488 +#define IDS_CUT_LEFTCLIP 0x0489 + +#define IDS_CUT_MUTE_MASTER 0x0490 +#define IDS_CUT_MUTE_RECTANGLE1 0x0491 +#define IDS_CUT_MUTE_RECTANGLE2 0x0492 +#define IDS_CUT_MUTE_TRIANGLE 0x0493 +#define IDS_CUT_MUTE_NOISE 0x0494 +#define IDS_CUT_MUTE_DPCM 0x0495 +#define IDS_CUT_MUTE_EXTERNAL1 0x0496 +#define IDS_CUT_MUTE_EXTERNAL2 0x0497 +#define IDS_CUT_MUTE_EXTERNAL3 0x0498 +#define IDS_CUT_MUTE_EXTERNAL4 0x0499 +#define IDS_CUT_MUTE_EXTERNAL5 0x049A +#define IDS_CUT_MUTE_EXTERNAL6 0x049B +#define IDS_CUT_MUTE_EXTERNAL7 0x049C +#define IDS_CUT_MUTE_EXTERNAL8 0x049D + +#define IDS_CUT_SEARCH 0x04A0 +#define IDS_CUT_CHEAT 0x04A1 +#define IDS_CUT_CHEAT_ENABLE 0x04A2 +#define IDS_CUT_CHEAT_DISABLE 0x04A3 +#define IDS_CUT_GENIE 0x04A4 + +#define IDS_CUT_VIEW_PATTERN 0x04B0 +#define IDS_CUT_VIEW_NAMETABLE 0x04B1 +#define IDS_CUT_VIEW_PALETTE 0x04B2 +#define IDS_CUT_VIEW_MEMORY 0x04B3 +#define IDS_CUT_VIEW_WATCH 0x04B4 + +#define IDS_CUT_QUICKLOAD_SLOT0 0x04C0 +#define IDS_CUT_QUICKLOAD_SLOT1 0x04C1 +#define IDS_CUT_QUICKLOAD_SLOT2 0x04C2 +#define IDS_CUT_QUICKLOAD_SLOT3 0x04C3 +#define IDS_CUT_QUICKLOAD_SLOT4 0x04C4 +#define IDS_CUT_QUICKLOAD_SLOT5 0x04C5 +#define IDS_CUT_QUICKLOAD_SLOT6 0x04C6 +#define IDS_CUT_QUICKLOAD_SLOT7 0x04C7 +#define IDS_CUT_QUICKLOAD_SLOT8 0x04C8 +#define IDS_CUT_QUICKLOAD_SLOT9 0x04C9 + +#define IDS_CUT_QUICKSAVE_SLOT0 0x04D0 +#define IDS_CUT_QUICKSAVE_SLOT1 0x04D1 +#define IDS_CUT_QUICKSAVE_SLOT2 0x04D2 +#define IDS_CUT_QUICKSAVE_SLOT3 0x04D3 +#define IDS_CUT_QUICKSAVE_SLOT4 0x04D4 +#define IDS_CUT_QUICKSAVE_SLOT5 0x04D5 +#define IDS_CUT_QUICKSAVE_SLOT6 0x04D6 +#define IDS_CUT_QUICKSAVE_SLOT7 0x04D7 +#define IDS_CUT_QUICKSAVE_SLOT8 0x04D8 +#define IDS_CUT_QUICKSAVE_SLOT9 0x04D9 + +// Launcher +#define IDS_LCH_LISTUPDATE 0x0500 +#define IDS_LCH_HEADERREWRITE 0x0501 +#define IDS_LCH_FILENAME 0x0510 +#define IDS_LCH_PATH 0x0511 +#define IDS_LCH_MAPPER 0x0512 +#define IDS_LCH_PRG 0x0513 +#define IDS_LCH_CHR 0x0514 +#define IDS_LCH_ALLCRC 0x0515 +#define IDS_LCH_PRGCRC 0x0516 +#define IDS_LCH_INFO 0x0517 +#define IDS_LCH_DATABASE 0x0518 +#define IDS_LCH_TITLE 0x0519 +#define IDS_LCH_COUNTRY 0x051A +#define IDS_LCH_MANUFACTURER 0x051B +#define IDS_LCH_SALEDATE 0x051C +#define IDS_LCH_PRICE 0x051D +#define IDS_LCH_GENRE 0x051E + +// NetPlay +#define IDS_NET_NOCONNECT 0x0600 +#define IDS_NET_ACCEPTING 0x0601 +#define IDS_NET_CONNECTING 0x0602 +#define IDS_NET_CALCULATING 0x0603 +#define IDS_NET_DISCONNECT 0x0610 +#define IDS_NET_ERROR 0x0611 + +// Cheat +#define IDS_CHT_CHEATCODE 0x0700 +#define IDS_CHT_COMMENT 0x0701 +#define IDS_CHT_ADDRESS 0x0702 +#define IDS_CHT_DATA_NOW 0x0703 +#define IDS_CHT_DATA_OLD 0x0704 + +// Rg[IDs +// UI +#define IDDEFAULT 101 +#define IDR_MENU 110 +#define IDI_ICON 111 +#define IDB_CHEATIMAGELIST 112 +#define IDB_LAUNCHERIMAGELIST 113 +#define IDI_SORT_DOWN 114 +#define IDI_SORT_UP 115 + +// Dialogs +#define IDD_VERSION 200 +#define IDD_ROMINFO 210 +#define IDD_MOVIEINFO 220 + +// For configuration +#define IDD_CFG_EMULATOR 300 +#define IDD_CFG_GRAPHICS 301 +#define IDD_CFG_SOUND 302 +#define IDD_CFG_FOLDER 303 +#define IDD_CFG_SHORTCUT 304 +#define IDD_CFG_LANGUAGE 305 +#define IDD_CFG_MOVIE 306 + +#define IDD_CFG_PALETTE 320 + +#define IDD_CFG_GAMEOPTION 350 + +// For Controller configuration +#define IDD_CFG_CONTROLLER 400 +#define IDD_CTR_PLAYER1 401 +#define IDD_CTR_PLAYER2 402 +#define IDD_CTR_PLAYER3 403 +#define IDD_CTR_PLAYER4 404 +#define IDD_CTR_CRAZYCLIMBER 405 +#define IDD_CTR_NSFPLAYER 406 + +#define IDD_CTR_FAMLYTRAINER 407 +#define IDD_CTR_EXCITINGBOXING 408 +#define IDD_CTR_MAHJANG 409 + +#define IDD_CTR_VSUNISYSTEM 410 + +// For Joypad Axis setting +#define IDD_CFG_AXISSETTING 450 + +// For Extension device +#define IDD_EXT_BARCODEBATTLER 480 +#define IDD_EXT_VSUNISYSTEM 481 + +// For Launcher +#define IDD_LAUNCHER 500 // Dialog +#define IDR_LCH_MENU 501 // Menu +#define IDD_LCH_DISPEDIT 502 +#define IDD_LCH_HEADEREDIT 503 +#define IDD_LCH_FOLDER 504 + +// For Cheat +#define IDD_SEARCH 600 +#define IDD_CHEAT 601 +#define IDD_CODEEDIT 602 // Code create +#define IDD_CODEINPUT 603 // Code input + +// For NetPlay +#define IDD_NETPLAY 800 +#define IDD_NETPLAY_CHAT 801 + +// For Debugger +#define IDD_DBG_DEBUGGER 900 +#define IDD_DBG_DEBUGGER_MENU 901 +#define IDD_DBG_REGVIEW 902 +#define IDD_DBG_REGVIEW_MENU 903 +#define IDD_DBG_MEMVIEW 904 +#define IDD_DBG_MEMVIEW_MENU 905 +#define IDD_DBG_MEMSEARCH 906 +#define IDD_DBG_MEMSEARCH_MENU 907 + +// _CAORg[IDs +// IDD_VERSION +#define IDC_VER_VERSION 1000 +#define IDC_VER_ICON 1001 +#define IDC_VER_WEBSITE 1002 +#define IDC_VER_COPYRIGHT 1003 +#define IDC_VER_EMAIL 1004 +#define IDC_VER_CONTRIBUTOR 1005 + +// IDD_ROMINFO +#define IDC_ROM_NAME 1100 +#define IDC_ROM_MAPPER 1101 +#define IDC_ROM_PRG 1102 +#define IDC_ROM_CHR 1103 +#define IDC_ROM_MIRROR 1104 +#define IDC_ROM_SRAM 1105 +#define IDC_ROM_4SCREEN 1106 +#define IDC_ROM_TRAINER 1107 +#define IDC_ROM_CRC 1108 +#define IDC_ROM_CRCALL 1109 +#define IDC_ROM_CRCCHR 1110 +#define IDC_ROM_VSUNISYSTEM 1111 + +// IDD_MOVIEINFO +#define IDC_MIF_VERSION 1150 +#define IDC_MIF_TIMES 1151 +#define IDC_MIF_FRAMES 1152 +#define IDC_MIF_RERECORDTIMES 1153 +#define IDC_MIF_RERECORDVERSION 1154 + +// IDD_CFG_EMULATOR +#define IDC_EMU_ILLEGALOP 1200 +#define IDC_EMU_AUTOFRAMESKIP 1201 +#define IDC_EMU_THROTTLE 1202 +#define IDC_EMU_THROTTLE_SLIDER 1203 +#define IDC_EMU_PRIORITY_COMBO 1204 +#define IDC_EMU_FPS 1205 +#define IDC_EMU_BACKGROUND 1206 +#define IDC_EMU_FOURPLAYER 1207 +#define IDC_EMU_DOUBLEEXECUTE 1208 +#define IDC_EMU_DISKTHROTTLE 1209 +#define IDC_EMU_LOADFULLSCREEN 1210 +#define IDC_EMU_CRCCHECK 1211 +#define IDC_EMU_STARTUPLAUNCHER 1212 +#define IDC_EMU_PNGSNAPSHOT 1213 + +// IDD_CFG_GRAPHICS +#define IDC_GRA_ASPECT 1300 +#define IDC_GRA_ALLSPRITE 1301 +#define IDC_GRA_ALLLINE 1302 +#define IDC_GRA_FPS 1303 +#define IDC_GRA_TVFRAME 1304 +#define IDC_GRA_SCANLINE 1305 +#define IDC_GRA_SCANLINE_SLIDER 1306 +#define IDC_GRA_SCANLINE_COLOR 1307 +#define IDC_GRA_PALETTE_USE 1308 +#define IDC_GRA_PALETTE_EDIT 1309 +#define IDC_GRA_PALETTE_BROWSE 1310 +#define IDC_GRA_SYNCDRAW 1311 +#define IDC_GRA_FITZOOM 1312 +#define IDC_GRA_RESOLUTION_COMBO 1313 +#define IDC_GRA_SYSTEMMEMORY 1314 +#define IDC_GRA_DOUBLESIZE 1315 +#define IDC_GRA_LEFTCLIP 1316 +#define IDC_GRA_USEHEL 1317 +#define IDC_GRA_WAITVSYNC 1318 + +#define IDC_GRA_DISKACCESSLAMP 1319 + +#define IDC_GRA_SYNCNOSLEEP 1320 +#define IDC_GRA_NOSQUARELIST 1321 + +// IDD_CFG_SOUND +#define IDC_SND_ENABLE 1400 +#define IDC_SND_SAMPLERATE_COMBO 1401 +#define IDC_SND_BUFFERSIZE_COMBO 1402 +#define IDC_SND_MASTER_SLIDER 1403 // Master +#define IDC_SND_CH0_SLIDER 1404 // Rectangle 1 +#define IDC_SND_CH1_SLIDER 1405 // Rectangle 2 +#define IDC_SND_CH2_SLIDER 1406 // Triangle +#define IDC_SND_CH3_SLIDER 1407 // Noise +#define IDC_SND_CH4_SLIDER 1408 // DPCM +#define IDC_SND_EX0_SLIDER 1409 // VRC6 +#define IDC_SND_EX1_SLIDER 1410 // VRC7 +#define IDC_SND_EX2_SLIDER 1411 // FDS +#define IDC_SND_EX3_SLIDER 1412 // MMC5 +#define IDC_SND_EX4_SLIDER 1413 // N106 +#define IDC_SND_EX5_SLIDER 1414 // FME7 +#define IDC_SND_FILTERTYPE_COMBO 1420 + +#define IDC_SND_VOLEFFECT_ENABLE 1421 +#define IDC_SND_EXTSOUND_ENABLE 1422 + +// IDD_CFG_FOLDER +#define IDC_FLD_ROM_USE 1500 +#define IDC_FLD_ROM_EDIT 1501 +#define IDC_FLD_ROM_BROWSE 1502 +#define IDC_FLD_SAVE_USE 1503 +#define IDC_FLD_SAVE_EDIT 1504 +#define IDC_FLD_SAVE_BROWSE 1505 +#define IDC_FLD_STATE_USE 1506 +#define IDC_FLD_STATE_EDIT 1507 +#define IDC_FLD_STATE_BROWSE 1508 +#define IDC_FLD_SNAPSHOT_USE 1509 +#define IDC_FLD_SNAPSHOT_EDIT 1510 +#define IDC_FLD_SNAPSHOT_BROWSE 1511 +#define IDC_FLD_MOVIE_USE 1512 +#define IDC_FLD_MOVIE_EDIT 1513 +#define IDC_FLD_MOVIE_BROWSE 1514 +#define IDC_FLD_WAVE_USE 1515 +#define IDC_FLD_WAVE_EDIT 1516 +#define IDC_FLD_WAVE_BROWSE 1517 +#define IDC_FLD_CHEAT_USE 1518 +#define IDC_FLD_CHEAT_EDIT 1519 +#define IDC_FLD_CHEAT_BROWSE 1520 + +// IDD_CFG_SHORTCUT +#define IDC_CUT_LIST 1600 +#define IDC_CUT_BUTTON1 1601 +#define IDC_CUT_BUTTON2 1602 + +// IDD_CFG_LANGUAGE +#define IDC_LNG_LIST 1700 + +// IDD_CFG_MOVIE +#define IDC_MVI_1P_USE 1800 +#define IDC_MVI_2P_USE 1801 +#define IDC_MVI_3P_USE 1802 +#define IDC_MVI_4P_USE 1803 +#define IDC_MVI_RERECORD_DISABLE 1804 +#define IDC_MVI_LOOPPLAY 1805 +#define IDC_MVI_RESETRECORD 1806 +#define IDC_MVI_PADDISPLAY 1807 + +// IDD_CFG_GAMEOPTION +#define IDC_OPT_RENDER_COMBO 1900 +#define IDC_OPT_IRQTYPE_COMBO 1901 +#define IDC_OPT_VIDEOMODE_COMBO 1902 +#define IDC_OPT_FRAMEIRQ 1903 +#define IDC_OPT_NOTSAVE 1904 + +// IDD_CFG_CONTROLLER +#define IDC_CTR_TAB 2000 +#define IDC_CTR_SELECT_COMBO 2001 + +// IDD_CTR_PLAYER1..4,CRAZYCLIMBER +#define IDC_CTR_UP 2010 +#define IDC_CTR_DOWN 2011 +#define IDC_CTR_LEFT 2012 +#define IDC_CTR_RIGHT 2013 +#define IDC_CTR_A 2014 +#define IDC_CTR_B 2015 +#define IDC_CTR_A_RAPID 2016 +#define IDC_CTR_B_RAPID 2017 +#define IDC_CTR_EXA 2018 +#define IDC_CTR_EXB 2019 +#define IDC_CTR_EXC 2020 +#define IDC_CTR_EXD 2021 +#define IDC_CTR_EXE 2022 +#define IDC_CTR_EXF 2023 +#define IDC_CTR_EXG 2024 +#define IDC_CTR_EXH 2025 + +#define IDC_CTR_EXI 2026 +#define IDC_CTR_EXJ 2027 +#define IDC_CTR_EXK 2028 +#define IDC_CTR_EXL 2029 +#define IDC_CTR_EXM 2030 +#define IDC_CTR_EXN 2031 +#define IDC_CTR_EXO 2032 +#define IDC_CTR_EXP 2033 +#define IDC_CTR_EXQ 2034 +#define IDC_CTR_EXR 2035 +#define IDC_CTR_EXS 2036 +#define IDC_CTR_EXT 2037 +#define IDC_CTR_EXU 2038 +#define IDC_CTR_EXV 2039 +#define IDC_CTR_EXW 2040 +#define IDC_CTR_EXX 2041 + +#define IDC_CTR_END 2041 // I[ + +#define IDC_CTR_A_RAPID_LIST 2050 +#define IDC_CTR_B_RAPID_LIST 2051 + +// IDD_CFG_AXISSETTING +#define IDC_AST_ID_COMBO 2200 +#define IDC_AST_XAXIS 2210 +#define IDC_AST_YAXIS 2211 +#define IDC_AST_ZAXIS 2212 +#define IDC_AST_RXAXIS 2213 +#define IDC_AST_RYAXIS 2214 +#define IDC_AST_RZAXIS 2215 +#define IDC_AST_XAXIS_PROGRESS 2220 +#define IDC_AST_YAXIS_PROGRESS 2221 +#define IDC_AST_ZAXIS_PROGRESS 2222 +#define IDC_AST_RXAXIS_PROGRESS 2223 +#define IDC_AST_RYAXIS_PROGRESS 2224 +#define IDC_AST_RZAXIS_PROGRESS 2225 + +// IDD_EXT_BACODEBATTLER +#define IDC_EBB_CODE 2100 +#define IDC_EBB_TRANSFER 2101 +#define IDC_EBB_RANDOM 2102 + +// IDD_EXT_VSUNISYSTEM +#define IDC_EVS_DIPNAME0 2150 +#define IDC_EVS_DIPNAME1 2151 +#define IDC_EVS_DIPNAME2 2152 +#define IDC_EVS_DIPNAME3 2153 +#define IDC_EVS_DIPNAME4 2154 +#define IDC_EVS_DIPNAME5 2155 +#define IDC_EVS_DIPNAME6 2156 +#define IDC_EVS_DIPNAME7 2157 +#define IDC_EVS_DIPCOMBO0 2160 +#define IDC_EVS_DIPCOMBO1 2161 +#define IDC_EVS_DIPCOMBO2 2162 +#define IDC_EVS_DIPCOMBO3 2163 +#define IDC_EVS_DIPCOMBO4 2164 +#define IDC_EVS_DIPCOMBO5 2165 +#define IDC_EVS_DIPCOMBO6 2166 +#define IDC_EVS_DIPCOMBO7 2167 + +// IDD_CFG_PALETTE +#define IDC_PAL_R_EDIT 2300 +#define IDC_PAL_G_EDIT 2301 +#define IDC_PAL_B_EDIT 2302 +#define IDC_PAL_R_UPDOWN 2310 +#define IDC_PAL_G_UPDOWN 2311 +#define IDC_PAL_B_UPDOWN 2312 +#define IDC_PAL_R_SLIDER 2320 +#define IDC_PAL_G_SLIDER 2321 +#define IDC_PAL_B_SLIDER 2322 +#define IDC_PAL_COPY 2330 +#define IDC_PAL_EXCHANGE 2331 +#define IDC_PAL_UNDO 2340 +#define IDC_PAL_LOAD 2341 +#define IDC_PAL_SAVE 2342 +#define IDC_PAL_NO 2350 + +// IDR_LAUNCER +#define IDC_LCH_LIST 3000 +#define IDC_LCH_STATUS 3001 + +// IDD_LCH_DISPEDIT +#define IDC_DED_HIDELIST 3100 +#define IDC_DED_VIEWLIST 3101 +#define IDC_DED_DEL 3102 +#define IDC_DED_ADD 3103 +#define IDC_DED_UP 3104 +#define IDC_DED_DOWN 3105 + +// IDD_LCH_HEADEREDIT +#define IDC_HED_EDIT 3200 +#define IDC_HED_VMIRROR 3201 +#define IDC_HED_SRAM 3202 +#define IDC_HED_4SCREEN 3203 +#define IDC_HED_TRAINER 3204 +#define IDC_HED_VSUNISYSTEM 3205 + +// IDD_LCH_FOLDER +#define IDC_LFL_LIST 3300 +#define IDC_LFL_FOLDERADD 3301 +#define IDC_LFL_ADD 3302 +#define IDC_LFL_DEL 3303 + +// IDD_SEARCH +#define IDR_SCH_MENU 4000 // Menu + +#define IDC_SCH_RESULT_LIST 4001 +#define IDC_SCH_RADIX_DEC 4002 +#define IDC_SCH_RADIX_HEX 4003 +#define IDC_SCH_LENGTH_1BYTE 4004 +#define IDC_SCH_LENGTH_2BYTE 4005 +#define IDC_SCH_LENGTH_3BYTE 4006 +#define IDC_SCH_LENGTH_4BYTE 4007 +#define IDC_SCH_AREA_RAM 4008 +#define IDC_SCH_AREA_SRAM 4009 +#define IDC_SCH_AREA_EXRAM 4010 +#define IDC_SCH_START 4011 +#define IDC_SCH_UPDATE 4012 +#define IDC_SCH_UNDO 4013 +#define IDC_SCH_EQUAL 4014 +#define IDC_SCH_NOTEQUAL 4015 +#define IDC_SCH_LESS 4016 +#define IDC_SCH_GRATER 4017 +#define IDC_SCH_LESSEQUAL 4018 +#define IDC_SCH_GRATEREQUAL 4019 +#define IDC_SCH_DATA_EDIT 4020 // Search data +#define IDC_SCH_SEARCH 4021 // Search button +#define IDC_SCH_WADDR_EDIT 4022 // Write address +#define IDC_SCH_WDATA_EDIT 4023 // Write data +#define IDC_SCH_WRITE 4024 // Write button + +// IDD_CHEAT +#define IDC_CHT_CODE_LIST 4101 +#define IDC_CHT_LOAD 4102 +#define IDC_CHT_SAVE 4103 +#define IDC_CHT_INPUT 4104 +#define IDC_CHT_EDIT 4105 +#define IDC_CHT_ENABLE 4106 +#define IDC_CHT_DISABLE 4107 +#define IDC_CHT_CLEAR 4108 +#define IDC_CHT_REMOVE 4109 + +// IDD_CODEEDIT +#define IDC_CED_ADDR 4200 +#define IDC_CED_DATA 4201 +#define IDC_CED_COMMENT 4202 +#define IDC_CED_RADIX_DEC 4203 +#define IDC_CED_RADIX_HEX 4204 +#define IDC_CED_LENGTH_1BYTE 4205 +#define IDC_CED_LENGTH_2BYTE 4206 +#define IDC_CED_LENGTH_3BYTE 4207 +#define IDC_CED_LENGTH_4BYTE 4208 +#define IDC_CED_TYPE_ALWAYS 4209 +#define IDC_CED_TYPE_ONCE 4210 +#define IDC_CED_TYPE_GREATER 4211 +#define IDC_CED_TYPE_LESS 4212 + +// IDD_CHEATCODE/IDD_GENIE +#define IDC_CHC_CODE 4300 +#define IDC_CHC_COMMENT 4301 + +// IDD_NETPLAY +#define IDC_NET_PORT_COMBO 8000 // Use Port(Server only) +#define IDC_NET_LATENCY_COMBO 8001 // Latency (Server only) +#define IDC_NET_HOST_COMBO 8002 // Hostname(hostaddr:port)(Client only) +#define IDC_NET_NICKNAME 8003 // Nickname +#define IDC_NET_SERVER 8010 +#define IDC_NET_CLIENT 8011 +#define IDC_NET_CONNECT 8020 +#define IDC_NET_STATUS 8030 + +// IDD_NETPLAY_CHAT +#define IDC_NCT_MESSAGE 8100 // Message window +#define IDC_NCT_EDIT 8101 // Message edit window +#define IDC_NCT_SEND 8110 // Send button + +// IDD_DEBUGGER +// + +// j[R}h IDs +// +// t@C(&F) +#define ID_OPEN 0x8000 +#define ID_CLOSE 0x8001 +#define ID_EXIT 0x8002 +#define ID_LAUNCHER 0x8010 +#define ID_LAUNCHER_CLOSE 0x8011 // R}h +#define ID_ROMINFO 0x8020 +#define ID_WAVERECORD 0x8028 +#define ID_ABOUT 0x8080 +#define ID_HTMLHELP 0x8081 + +// "ȯܰ"POPUP +#define ID_NETPLAY_CONNECT 0x80D0 +#define ID_NETPLAY_DISCONNECT 0x80D1 +#define ID_NETPLAY_CHAT 0x80D2 // ChatWindow + +// "Ѱ?POPUP +#define ID_MOVIE_REC 0x80E0 +#define ID_MOVIE_REC_APPEND 0x80E1 +#define ID_MOVIE_PLAY 0x80E2 +#define ID_MOVIE_STOP 0x80E3 +#define ID_MOVIE_INFO 0x80E4 + +// ŋߎgt@C +#define ID_MRU_FILE0 0x8300 +#define ID_MRU_FILE1 0x8301 +#define ID_MRU_FILE2 0x8302 +#define ID_MRU_FILE3 0x8303 +#define ID_MRU_FILE4 0x8304 +#define ID_MRU_FILE5 0x8305 +#define ID_MRU_FILE6 0x8306 +#define ID_MRU_FILE7 0x8307 +#define ID_MRU_FILE8 0x8308 +#define ID_MRU_FILE9 0x8309 +// ŋߎgpX +#define ID_MRU_PATH0 0x8310 +#define ID_MRU_PATH1 0x8311 +#define ID_MRU_PATH2 0x8312 +#define ID_MRU_PATH3 0x8313 +#define ID_MRU_PATH4 0x8314 +#define ID_MRU_PATH5 0x8315 +#define ID_MRU_PATH6 0x8316 +#define ID_MRU_PATH7 0x8317 +#define ID_MRU_PATH8 0x8318 +#define ID_MRU_PATH9 0x8319 + +// ҏW(&E) +#define ID_HWRESET 0x8100 +#define ID_SWRESET 0x8101 +#define ID_PAUSE 0x8102 +#define ID_STATE_LOAD 0x8103 +#define ID_STATE_SAVE 0x8104 +// "ðĽۯ"POPUP +#define ID_STATE_SLOT0 0x8110 +#define ID_STATE_SLOT1 0x8111 +#define ID_STATE_SLOT2 0x8112 +#define ID_STATE_SLOT3 0x8113 +#define ID_STATE_SLOT4 0x8114 +#define ID_STATE_SLOT5 0x8115 +#define ID_STATE_SLOT6 0x8116 +#define ID_STATE_SLOT7 0x8117 +#define ID_STATE_SLOT8 0x8118 +#define ID_STATE_SLOT9 0x8119 + +// "ި?POPUP +#define ID_DISK_EJECT 0x8120 +#define ID_DISK_0A 0x8121 +#define ID_DISK_0B 0x8122 +#define ID_DISK_1A 0x8123 +#define ID_DISK_1B 0x8124 +// "g۰"POPUP +#define ID_EXCTR_NONE 0x8130 +#define ID_EXCTR_PADDLE 0x8131 +#define ID_EXCTR_HYPERSHOT 0x8132 +#define ID_EXCTR_ZAPPER 0x8133 +#define ID_EXCTR_KEYBOARD 0x8134 +#define ID_EXCTR_SUBOR_KEYBOARD 0x812e +#define ID_EXCTR_CRAZYCLIMBER 0x8135 +#define ID_EXCTR_TOPRIDER 0x8136 +#define ID_EXCTR_SPACESHADOWGUN 0x8137 + +#define ID_EXCTR_FAMILYTRAINER_A 0x8138 +#define ID_EXCTR_FAMILYTRAINER_B 0x8139 +#define ID_EXCTR_EXCITINGBOXING 0x813A +#define ID_EXCTR_MAHJANG 0x813B +#define ID_EXCTR_OEKAKIDS_TABLET 0x813C +#define ID_EXCTR_TURBOFILE 0x813D + +#define ID_EXCTR_CHINA_EDUCATIONAL_MOUSE 0x812f + +#define ID_EXCTR_VSUNISYSTEM 0x813E +#define ID_EXCTR_VSUNISYSTEM_ZAPPER 0x813F + +#define ID_EXCTR_END 0x813F // I[ + +// "Quick۰"POPUP +#define ID_QUICKLOAD_SLOT0 0x8140 +#define ID_QUICKLOAD_SLOT1 0x8141 +#define ID_QUICKLOAD_SLOT2 0x8142 +#define ID_QUICKLOAD_SLOT3 0x8143 +#define ID_QUICKLOAD_SLOT4 0x8144 +#define ID_QUICKLOAD_SLOT5 0x8145 +#define ID_QUICKLOAD_SLOT6 0x8146 +#define ID_QUICKLOAD_SLOT7 0x8147 +#define ID_QUICKLOAD_SLOT8 0x8148 +#define ID_QUICKLOAD_SLOT9 0x8149 +// "Quick"POPUP +#define ID_QUICKSAVE_SLOT0 0x8150 +#define ID_QUICKSAVE_SLOT1 0x8151 +#define ID_QUICKSAVE_SLOT2 0x8152 +#define ID_QUICKSAVE_SLOT3 0x8153 +#define ID_QUICKSAVE_SLOT4 0x8154 +#define ID_QUICKSAVE_SLOT5 0x8155 +#define ID_QUICKSAVE_SLOT6 0x8156 +#define ID_QUICKSAVE_SLOT7 0x8157 +#define ID_QUICKSAVE_SLOT8 0x8158 +#define ID_QUICKSAVE_SLOT9 0x8159 + +// g޲ +// "ð޲"POPUP +#define ID_TAPE_PLAY 0x8180 +#define ID_TAPE_REC 0x8181 +#define ID_TAPE_STOP 0x8182 + +#define ID_BARCODEBATTLER 0x8190 +#define ID_VSUNISYSTEM_DIPSWITCH 0x8194 + +// "̧"POPUP +#define ID_TURBOFILE_BANK0 0x81A0 +#define ID_TURBOFILE_BANK1 0x81A1 +#define ID_TURBOFILE_BANK2 0x81A2 +#define ID_TURBOFILE_BANK3 0x81A3 + +// ݒ(&C) +#define ID_CFG_EMULATOR 0x8200 +#define ID_CFG_GRAPHICS 0x8201 +#define ID_CFG_SOUND 0x8202 +#define ID_CFG_CONTROLLER 0x8203 +#define ID_CFG_SHORTCUT 0x8204 +#define ID_CFG_FOLDER 0x8205 +#define ID_CFG_LANGUAGE 0x8206 +#define ID_CFG_MOVIE 0x8207 +#define ID_CFG_GAMEOPTION 0x8208 +#define ID_CFG_JOYAXIS 0x8209 +#define ID_CFG_PALETTE 0x820A +// "ʻ"POPUP +#define ID_ZOOMx1 0x8220 +#define ID_ZOOMx2 0x8221 +#define ID_ZOOMx3 0x8222 +#define ID_ZOOMx4 0x8223 + +// TEh~[g +#define ID_MUTE_0 0x8230 +#define ID_MUTE_1 0x8231 +#define ID_MUTE_2 0x8232 +#define ID_MUTE_3 0x8233 +#define ID_MUTE_4 0x8234 +#define ID_MUTE_5 0x8235 +#define ID_MUTE_6 0x8236 +#define ID_MUTE_7 0x8237 +#define ID_MUTE_8 0x8238 +#define ID_MUTE_9 0x8239 +#define ID_MUTE_A 0x823A +#define ID_MUTE_B 0x823B +#define ID_MUTE_C 0x823C +#define ID_MUTE_D 0x823D +#define ID_MUTE_E 0x823E +#define ID_MUTE_F 0x823F + +// c[(&T) +#define ID_SEARCH 0x8800 +#define ID_CHEAT 0x8801 +#define ID_GENIE 0x8802 + +#define ID_CHEAT_ENABLE 0x8803 +#define ID_CHEAT_DISABLE 0x8804 + +#define ID_VIEW_PATTERN 0x8900 +#define ID_VIEW_NAMETABLE 0x8901 +#define ID_VIEW_PALETTE 0x8902 + +#define ID_VIEW_MEMORY 0x8910 +#define ID_VIEW_WATCH 0x8911 + +// ̑̃R}h(j[\̂) +#define ID_STATE_UP 0x9000 +#define ID_STATE_DOWN 0x9001 +#define ID_THROTTLE 0x9002 +#define ID_FULLSCREEN 0x9003 +#define ID_FPSDISP 0x9004 +#define ID_TVASPECT 0x9005 +#define ID_TVFRAME 0x9006 +#define ID_SCANLINE 0x9007 +#define ID_ALLLINE 0x9008 +#define ID_ALLSPRITE 0x9009 +#define ID_SYNCDRAW 0x900A +#define ID_FITSCREEN 0x900B +#define ID_SNAPSHOT 0x900C +#define ID_FRAMESKIP_AUTO 0x900D +#define ID_FRAMESKIP_UP 0x900E +#define ID_FRAMESKIP_DOWN 0x900F +#define ID_LEFTCLIP 0x9010 +#define ID_ONEFRAME 0x9011 +#define ID_KEYTHROTTLE 0x9012 + +// ʃtB^ +#define ID_FILTER_NONE 0x9100 +#define ID_FILTER_2XSAI 0x9101 +#define ID_FILTER_SUPER2XSAI 0x9102 +#define ID_FILTER_SUPEREAGLE 0x9103 +#define ID_FILTER_SCALE2X 0x9104 +#define ID_FILTER_END 0x9104 + +// `[gj[ +#define ID_SCH_APPEND 0x9800 + +// `[j[ +// +#define ID_LCH_FOLDER 0xA000 +#define ID_LCH_DISPEDIT 0xA001 +#define ID_LCH_HEADEREDIT 0xA002 +#define ID_LCH_REFRESH 0xA003 +#define ID_LCH_LIST0 0xA010 +#define ID_LCH_LIST1 0xA011 +#define ID_LCH_LIST2 0xA012 +#define ID_LCH_LIST3 0xA013 +#define ID_LCH_LIST4 0xA014 +#define ID_LCH_LIST5 0xA015 +#define ID_LCH_LIST6 0xA016 +#define ID_LCH_LIST7 0xA017 +#define ID_LCH_LIST8 0xA018 +#define ID_LCH_LIST9 0xA019 + +#endif // !__VIRTUANES_RESOURCE_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/WaveRec.cpp b/References/VirtuaNESex_src_191105/WaveRec.cpp new file mode 100644 index 00000000..83326e2f --- /dev/null +++ b/References/VirtuaNESex_src_191105/WaveRec.cpp @@ -0,0 +1,58 @@ +// +// Wave record class +// +#include "WaveRec.h" + +CWaveRec::CWaveRec() +{ + ::ZeroMemory( &wavefile, sizeof(wavefile) ); + fp = NULL; + + ::CopyMemory( wavefile.tagRIFF, "RIFF", sizeof(wavefile.tagRIFF) ); + ::CopyMemory( wavefile.tagTYPE, "WAVEfmt ", sizeof(wavefile.tagTYPE) ); + ::CopyMemory( wavefile.tagDATA, "data", sizeof(wavefile.tagDATA) ); + + wavefile.dwChunkOffset = 0x0010; + wavefile.wCodingType = 0x0001; +} + +CWaveRec::~CWaveRec() +{ + if( fp ) + Stop(); +} + +void CWaveRec::Start( LPSTR szFile, INT nSample, INT nBits, BOOL bStereo ) +{ + if( fp ) + Stop(); + + if( (fp = ::fopen( szFile, "wb" )) ) { + wavefile.wChannel = bStereo?2:1; + wavefile.dwSample = nSample; + wavefile.wBits = nBits; + wavefile.wBytesPerSample = (WORD)(nBits>>3)*wavefile.wChannel; + wavefile.dwBytesPerSec = nSample*wavefile.wBytesPerSample; + } +} + +void CWaveRec::Stop() +{ + if( fp ) { + DWORD size = (DWORD)::ftell( fp ); + wavefile.dwFileSize = (DWORD)size-8; + wavefile.dwDataSize = (DWORD)size-sizeof(WAVEFILE); + ::fseek( fp, 0, SEEK_SET ); + ::fwrite( &wavefile, sizeof(WAVEFILE), 1, fp ); + ::fclose( fp ); + fp = NULL; + } +} + +void CWaveRec::Out( LPVOID lpBuf, DWORD dwSize ) +{ + if( fp ) { + ::fwrite( lpBuf, dwSize, 1, fp ); + } +} + diff --git a/References/VirtuaNESex_src_191105/WaveRec.h b/References/VirtuaNESex_src_191105/WaveRec.h new file mode 100644 index 00000000..ed8d570c --- /dev/null +++ b/References/VirtuaNESex_src_191105/WaveRec.h @@ -0,0 +1,50 @@ +// +// Wave record class +// +#ifndef __CWAVEREC_INCLUDED__ +#define __CWAVEREC_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "typedef.h" + +#pragma pack(1) +typedef struct { + CHAR tagRIFF[4]; // "RIFF" + DWORD dwFileSize; + CHAR tagTYPE[8]; // "WAVEfmt " + DWORD dwChunkOffset; + WORD wCodingType; + WORD wChannel; + DWORD dwSample; + DWORD dwBytesPerSec; + WORD wBytesPerSample; + WORD wBits; + CHAR tagDATA[4]; // "data" + DWORD dwDataSize; +} WAVEFILE, *LPWAVEFILE; +#pragma pack() + +class CWaveRec +{ +public: + CWaveRec(); + ~CWaveRec(); + + void Start( LPSTR szFile, INT nSample, INT nBits, BOOL bStereo ); + void Stop(); + + BOOL IsWaveRecord() { return fp?TRUE:FALSE; } + + void Out( LPVOID lpBuf, DWORD dwSize ); +protected: +private: + WAVEFILE wavefile; + FILE* fp; +}; + +#endif // !__CWAVEREC_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/WinMain.cpp b/References/VirtuaNESex_src_191105/WinMain.cpp new file mode 100644 index 00000000..2bc1648d --- /dev/null +++ b/References/VirtuaNESex_src_191105/WinMain.cpp @@ -0,0 +1,239 @@ +#define INITGUID +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +#include +using namespace std; + +#include "DebugOut.h" +#include "VirtuaNESres.h" + +#include "App.h" +#include "Registry.h" +#include "Pathlib.h" +#include "MMTimer.h" + +#include "Wnd.h" +#include "WndHook.h" +#include "MainFrame.h" +#include "Plugin.h" +#include "Config.h" +#include "Recent.h" + +#include "DirectDraw.h" +#include "DirectSound.h" +#include "DirectInput.h" + +#include "SimpleVirusChecker.h" + +INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow ) +{ +#if _DEBUG + // [No + int Flag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); + Flag |= _CRTDBG_LEAK_CHECK_DF; + Flag &= ~_CRTDBG_CHECK_ALWAYS_DF; + _CrtSetDbgFlag( Flag ); +#endif + + // ȈՃEBX`FbN + if( SimpleVirusChecker() > 0 ) { + if( ::GetUserDefaultLCID() == 0x0411 ) { + if( ::MessageBox( NULL, "PC̓EBXvOɊÔ\܂B\n" + "댯ł̂łȂׂ}ɃEBX`FbNsĉB\n\n" + "łs܂H", "VirtuaNES ȈՃEBX`FbJ[", MB_ICONWARNING|MB_YESNO|MB_DEFBUTTON2 ) == IDNO ) + return -1L; + } else { + if( ::MessageBox( NULL, "This PC may be infected with a virus program!!!\n" + "Should become danger, and please do a check to it immediately!!!\n\n" + "Do execute even it?", "VirtuaNES simple virus checker", MB_ICONWARNING|MB_YESNO|MB_DEFBUTTON2 ) == IDNO ) + return -1L; + } + } + + // Ct[EChEIuWFNg + CMainFrame MainFrame; + + // Mutex + HANDLE hMutex = NULL; + + // AvP[VCX^X̐ݒ + CHAR szPath[ _MAX_PATH ]; + GetModuleFileName( hInstance, szPath, sizeof(szPath) ); + string ModulePath = CPathlib::SplitPath( szPath ); + CApp::SetModulePath( ModulePath.c_str() ); + DEBUGOUT( "Module Path:\"%s\"\n", ModulePath.c_str() ); + + CApp::SetInstance( hInstance ); + CApp::SetPrevInstance( hPrevInstance ); + CApp::SetCmdLine( lpCmdLine ); + CApp::SetCmdShow( nCmdShow ); + +//DEBUGOUT( "ThreadID:%08X\n", ::GetCurrentThreadId() ); + +// CRegistry::SetRegistryKey( "Emulators\\VirtuaNES" ); + CRegistry::SetRegistryKey( "VirtuaNESex.ini" ); + + if( !CPlugin::FindPlugin( CApp::GetModulePath() ) ) { + ::MessageBox( NULL, "Language plug-in is not found.", "VirtuaNES", MB_ICONERROR|MB_OK ); + goto _Error_Exit; + } + DEBUGOUT( "Plugin Path:\"%s\"\n", CPlugin::GetPluginPath() ); + DEBUGOUT( "Language :\"%s\"\n", CPlugin::GetPluginLanguage() ); + DEBUGOUT( "LCID :\"%d\" \"0x%04X\"\n", CPlugin::GetPluginLocaleID(), CPlugin::GetPluginLocaleID() ); + + HINSTANCE hPlugin; + if( !(hPlugin = CPlugin::LoadPlugin()) ) { + ::MessageBox( NULL, "Language plug-in load failed.", "VirtuaNES", MB_ICONERROR|MB_OK ); + goto _Error_Exit; + } + CApp::SetPlugin( hPlugin ); + + ::InitCommonControls(); + + // ݒ̃[h + CRegistry::SetRegistryKey( "VirtuaNESex.ini" ); + Config.Load(); + CRecent::Load(); + + // dN̖h~ + hMutex = ::CreateMutex( NULL, FALSE, VIRTUANES_MUTEX ); + if( ::GetLastError() == ERROR_ALREADY_EXISTS ) { + ::CloseHandle( hMutex ); + if( Config.general.bDoubleExecute ) { +// HWND hWnd = ::FindWindow( VIRTUANES_WNDCLASS, NULL ); + HWND hWnd = ::FindWindow( VIRTUANES_WNDCLASS, VIRTUANES_CAPTION ); + + // NĂtHAOEhɂ + ::SetForegroundWindow( hWnd ); + + // R}hCȂ瓮쒆VirtuaNES̃EChEɃt@C + // bZ[W𑗂‚Ăœ삳 + // (R̗lɑΉo[WłȂƃ_) + if( ::strlen( lpCmdLine ) > 0 ) { + LPSTR pCmd = lpCmdLine; + if( lpCmdLine[0] == '"' ) { // Shell execute!! + lpCmdLine++; + if( lpCmdLine[::strlen( lpCmdLine )-1] == '"' ) { + lpCmdLine[::strlen( lpCmdLine )-1] = '\0'; + } + } + + COPYDATASTRUCT cds; + cds.dwData = 0; + cds.lpData = (void*)lpCmdLine; + cds.cbData = ::strlen(lpCmdLine)+1; // I[NULL + // 񑗐M + ::SendMessage( hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds ); + } + + // I + goto _DoubleExecute_Exit; + } + } + + if( !MainFrame.Create(NULL) ) + goto _Error_Exit; + DEBUGOUT( "CreateWindow ok.\n" ); + + // CEChE̕\ + ::ShowWindow( CApp::GetHWnd(), CApp::GetCmdShow() ); + ::UpdateWindow( CApp::GetHWnd() ); + + // tbN + CWndHook::Initialize(); + + // `[N + if( Config.general.bStartupLauncher ) { + ::PostMessage( CApp::GetHWnd(), WM_COMMAND, ID_LAUNCHER, 0 ); + } + + // R}hC + if( ::strlen( lpCmdLine ) > 0 ) { + LPSTR pCmd = lpCmdLine; + if( lpCmdLine[0] == '"' ) { // Shell execute!! + lpCmdLine++; + if( lpCmdLine[::strlen( lpCmdLine )-1] == '"' ) { + lpCmdLine[::strlen( lpCmdLine )-1] = '\0'; + } + } + } + + if( ::strlen( lpCmdLine ) > 0 ) { + ::PostMessage( CApp::GetHWnd(), WM_VNS_COMMANDLINE, 0, (LPARAM)lpCmdLine ); + } else { + CHAR tmpPath[100]; + + if( ::strlen( Config.path.szRomAutoRunPath ) > 4 ) { + if( Config.path.szRomAutoRunPath[0] == '\\' ) { // ·1 "\\file.nes" + ::wsprintf(tmpPath, "%s\\roms\\%s", ModulePath.c_str(), Config.path.szRomAutoRunPath); + } else if( Config.path.szRomAutoRunPath[0] == '.' ) { // ·2 ".\\file.nes" + ::wsprintf(tmpPath, "%s%s", ModulePath.c_str(), Config.path.szRomAutoRunPath + 2); + } else if( Config.path.szRomAutoRunPath[1] == ':' ) { // ȫ· + ::wsprintf(tmpPath, "%s", Config.path.szRomAutoRunPath); + } else { //full path + ::wsprintf(tmpPath, "%s", Config.path.szRomAutoRunPath); + } + + DEBUGOUT("ĬROM PATH: %s\n", tmpPath); + ::PostMessage(CApp::GetHWnd(), WM_VNS_COMMANDLINE, 0, (LPARAM)tmpPath); + } + } + + MSG msg; + BOOL bRet; + while( (bRet = ::GetMessage( &msg, NULL, 0, 0 )) != 0 ) { + // G[H + if( bRet == -1 ) + break; + // CEChẼbZ[WtB^O + if( CApp::GetHWnd() == msg.hwnd ) { + CWnd* pWnd = (CWnd*)::GetWindowLong( msg.hwnd, GWL_USERDATA ); + if( pWnd ) { + if( pWnd->PreTranslateMessage( &msg ) ) + continue; + } + } + if( CWndList::IsDialogMessage( &msg ) ) + continue; + ::TranslateMessage( &msg ); + ::DispatchMessage( &msg ); + } + // tbN + CWndHook::Release(); + + // ݒ̕ۑ + CRegistry::SetRegistryKey( "VirtuaNESex.ini" ); + Config.Save(); + CRecent::Save(); + + // DirectXnj + DirectDraw.ReleaseDDraw(); + DirectSound.ReleaseDSound(); + DirectInput.ReleaseDInput(); + + if( hMutex ) + ::ReleaseMutex( hMutex ); + CLOSEHANDLE( hMutex ); + +_DoubleExecute_Exit: + ::FreeLibrary( CApp::GetPlugin() ); + + return msg.wParam; + +_Error_Exit: + // DirectXnj + DirectDraw.ReleaseDDraw(); + DirectSound.ReleaseDSound(); + DirectInput.ReleaseDInput(); + + if( CApp::GetPlugin() ) { + ::FreeLibrary( CApp::GetPlugin() ); + } + + return -1; +} + diff --git a/References/VirtuaNESex_src_191105/Wnd.cpp b/References/VirtuaNESex_src_191105/Wnd.cpp new file mode 100644 index 00000000..674e0541 --- /dev/null +++ b/References/VirtuaNESex_src_191105/Wnd.cpp @@ -0,0 +1,135 @@ +// +// ւȂ傱EChENX +// +#include "DebugOut.h" +#include "Wnd.h" + +// Instance +CWndList WndList; + +list CWndList::m_WndPtrList; + +// DLc +CWndList::CWndList() +{ +// m_WndPtrList.clear(); +} + +CWndList::~CWndList() +{ +// if( !m_WndPtrList.empty() ) +// m_WndPtrList.clear(); +} + +void CWndList::Add( CWnd* pWnd ) +{ + m_WndPtrList.push_back( pWnd ); +} + +void CWndList::Del( CWnd* pWnd ) +{ + for( list::iterator it=m_WndPtrList.begin(); it!=m_WndPtrList.end(); ) { + if( *it == pWnd ) { + m_WndPtrList.erase(it); + break; + } else { + ++it; + } + } +} + +BOOL CWndList::IsDialogMessage( LPMSG msg ) +{ + if( m_WndPtrList.empty() ) + return FALSE; + + list::iterator it=m_WndPtrList.begin(); + while( it != m_WndPtrList.end() ) { + if( ::IsDialogMessage( (*it)->m_hWnd, msg ) ) + return TRUE; + ++it; + } + + return FALSE; +} + +CWnd::CWnd() +{ + m_hWnd = NULL; + m_hMenu = NULL; +} + +CWnd::~CWnd() +{ +} + +void CWnd::SetThis() +{ + // Dispatcho悤CWnd*𖄂ߍ + if( m_hWnd ) { + ::SetWindowLong( m_hWnd, GWL_USERDATA, (LONG)this ); + } +} + +LRESULT CALLBACK CWnd::g_WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + // EChEJOɂ菈 + if( msg == WM_CREATE ) { + LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; + CWnd* pWnd = (CWnd*)::GetWindowLong( hWnd, GWL_USERDATA ); + if( !pWnd ) { + // CWnd* this𖄂ߍ + ::SetWindowLong( hWnd, GWL_USERDATA, (LONG)lpcs->lpCreateParams ); + // ̃EChEnh + pWnd = (CWnd*)lpcs->lpCreateParams; + pWnd->m_hWnd = hWnd; + } + } + // CWnd* this𖄂ߍł + CWnd* pWnd = (CWnd*)::GetWindowLong( hWnd, GWL_USERDATA ); + + if( pWnd ) { + return pWnd->DispatchWnd( hWnd, msg, wParam, lParam ); + } else { + return ::DefWindowProc( hWnd, msg, wParam, lParam ); + } +} + +BOOL CALLBACK CWnd::g_DlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + // fBXpb`Oɂ菈 + if( msg == WM_INITDIALOG ) { + // Dispatcho悤CWnd*𖄂ߍ([_͕KDialogBoxParamŋN鎖) + // CWnd* this𖄂ߍł邪C[_ł͓ĂȂ + CWnd* pWnd = (CWnd*)::GetWindowLong( hWnd, GWL_USERDATA ); + + if( !pWnd ) { + ::SetWindowLong( hWnd, GWL_USERDATA, (LONG)lParam ); + pWnd = (CWnd*)lParam; + } + // ̃EChEnh + pWnd->m_hWnd = hWnd; + + // _CAO𒆉Ɉړ:) + HWND hWndParent = ::GetParent( hWnd ); + if( hWndParent ) { + RECT rcParent, rc; + ::GetWindowRect( hWndParent, &rcParent ); + ::GetWindowRect( hWnd, &rc ); + INT x = rcParent.left+(rcParent.right-rcParent.left)/2-(rc.right-rc.left)/2; + INT y = rcParent.top +(rcParent.bottom-rcParent.top)/2-(rc.bottom-rc.top)/2; +// DEBUGOUT( "X=%d Y=%d\n", x, y ); + ::SetWindowPos( hWnd, NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + } + } + + // CWnd* this𖄂ߍł + CWnd* pWnd = (CWnd*)::GetWindowLong( hWnd, GWL_USERDATA ); + + if( pWnd ) { + return pWnd->DispatchDlg( hWnd, msg, wParam, lParam ); + } else { + return FALSE; + } +} + diff --git a/References/VirtuaNESex_src_191105/Wnd.h b/References/VirtuaNESex_src_191105/Wnd.h new file mode 100644 index 00000000..db94fe5f --- /dev/null +++ b/References/VirtuaNESex_src_191105/Wnd.h @@ -0,0 +1,204 @@ +// +// ւȂ傱EChENX +// +// pȂƈӖ^^; +// +#ifndef __CWND_INCLUDED__ +#define __CWND_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include +#include +using namespace std; + +// prototype +class CWnd; + +// [hXׂ̃C`LNX +class CWndList +{ +public: + CWndList(); + ~CWndList(); + + static void Add( CWnd* pWnd ); // Xgɉ + static void Del( CWnd* pWnd ); // Xg폜 + + static BOOL IsDialogMessage( LPMSG msg ); +protected: +private: + static list m_WndPtrList; +}; + +// ʂ̃EChE +class CWnd +{ +public: + CWnd(); + virtual ~CWnd(); + + HWND m_hWnd; + HMENU m_hMenu; + + // Override + virtual BOOL Create( HWND hWndParent ) { return FALSE; }; + virtual void Destroy() {}; + + // Override for ModalDialog + virtual INT DoModal( HWND hWndParent ) { return 0; } + + // For message filtering + virtual BOOL PreTranslateMessage( MSG* pMsg ) { return FALSE; } +protected: + void SetThis(); + + // Static + static LRESULT CALLBACK g_WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + static BOOL CALLBACK g_DlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + + // Override + virtual LRESULT DispatchWnd( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) + { return ::DefWindowProc( hWnd, msg, wParam, lParam ); } + + virtual BOOL DispatchDlg( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) + { return FALSE; } +private: +}; + +// EChEbZ[Wp +// NX`}N +#define WND_MESSAGE_MAP() HRESULT DispatchWnd( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + +#define WNDMSG BOOL +#define WNDCMD void +#define WNDNOTIFY void + +#define WNDMSGPARAM HWND hWnd, WPARAM wParam, LPARAM lParam, HRESULT& hResult +#define WNDCMDPARAM HWND hWnd, UINT uID +#define WNDNOTIFYPARAM HWND hWnd, UINT uID, NMHDR* pNMHDR, LRESULT& hResult + +// Cvg}N +#define WND_MESSAGE_BEGIN(cls) \ + HRESULT cls::DispatchWnd( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\ + HRESULT hResult = 0L;\ + switch( msg ) { +#define WND_ON_MESSAGE(msg,fnc) \ + case (msg): {\ + if( fnc( hWnd, wParam, lParam, hResult ) )\ + return hResult;\ + }\ + break; +// R}hCOMMAND_BEGIN() ` COMMAND_END()̒ɋLq(PȂifȂ̂(^^;) +#define WND_COMMAND_BEGIN() \ + case WM_COMMAND: { +#define WND_ON_COMMAND(id,fnc) \ + if( LOWORD(wParam) == (id) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +#define WND_ON_COMMAND_RANGE(id,idend,fnc) \ + if( LOWORD(wParam) >= (id) && LOWORD(wParam) <= (idend) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +// Notify commands +#define WND_ON_COMMAND_NOTIFY(id,nfy,fnc) \ + if( LOWORD(wParam) == (id) && HIWORD(wParam) == (nfy) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +#define WND_ON_COMMAND_NOTIFY_RANGE(id,idend,nfy,fnc) \ + if( LOWORD(wParam) >= (id) && LOWORD(wParam) <= (idend) && HIWORD(wParam) == (nfy) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +#define WND_COMMAND_END() \ + return 0L; }; break; + +// WM_NOTIFYNOTIFY_BEGIN() ` NOTIFY_END()̒ɋLq(PȂifȂ̂^^;) +#define WND_NOTIFY_BEGIN() \ + case WM_NOTIFY: { \ + LRESULT hResult = 0L; +#define WND_ON_NOTIFY(id,msg,fnc) \ + if( (UINT)wParam == (id) && ((NMHDR*)lParam)->code == (msg) ) {\ + fnc( ((NMHDR*)lParam)->hwndFrom, (UINT)wParam, (NMHDR*)lParam, hResult );\ + return (BOOL)hResult; } +#define WND_ON_NOTIFY_RANGE(id,idend,msg,fnc) \ + if( (UINT)wParam >= (id) && (UINT)wParam <= (idend) && ((NMHDR*)lParam)->code == (msg) ) {\ + fnc( ((NMHDR*)lParam)->hwndFrom, (UINT)wParam, (NMHDR*)lParam, hResult );\ + return (BOOL)hResult; } +#define WND_NOTIFY_END() \ + return FALSE; }; break; + +#define WND_MESSAGE_END() \ + default: break; }\ + return ::DefWindowProc( hWnd, msg, wParam, lParam );\ + } + +// _CAObZ[Wp +// NX`}N +#define DLG_MESSAGE_MAP() BOOL DispatchDlg( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + +#define DLGMSG BOOL +#define DLGCMD void +#define DLGNOTIFY void + +#define DLGMSGPARAM HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL& bResult +#define DLGCMDPARAM HWND hWnd, UINT uID +#define DLGNOTIFYPARAM HWND hWnd, UINT uID, NMHDR* pNMHDR, LRESULT& hResult + +// Cvg}N +#define DLG_MESSAGE_BEGIN(cls) \ + BOOL cls::DispatchDlg( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\ + BOOL bResult = TRUE;\ + switch( msg ) { +#define DLG_ON_MESSAGE(msg,fnc) \ + case (msg): {\ + if( fnc( hWnd, wParam, lParam, bResult ) )\ + return bResult;\ + }\ + break; +// R}hCOMMAND_BEGIN() ` COMMAND_END()̒ɋLq(PȂifȂ̂^^;) +#define DLG_COMMAND_BEGIN() \ + case WM_COMMAND: { +#define DLG_ON_COMMAND(id,fnc) \ + if( LOWORD(wParam) == (id) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +#define DLG_ON_COMMAND_RANGE(id,idend,fnc) \ + if( LOWORD(wParam) >= (id) && LOWORD(wParam) <= (idend) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +// Notify commands +#define DLG_ON_COMMAND_NOTIFY(id,nfy,fnc) \ + if( LOWORD(wParam) == (id) && HIWORD(wParam) == (nfy) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +#define DLG_ON_COMMAND_NOTIFY_RANGE(id,idend,nfy,fnc) \ + if( LOWORD(wParam) >= (id) && LOWORD(wParam) <= (idend) && HIWORD(wParam) == (nfy) ) \ + fnc( (HWND)lParam, LOWORD(wParam) ); +#define DLG_COMMAND_END() \ + return FALSE; }; break; + +// WM_NOTIFYNOTIFY_BEGIN() ` NOTIFY_END()̒ɋLq(PȂifȂ̂^^;) +#define DLG_NOTIFY_BEGIN() \ + case WM_NOTIFY: { \ + LRESULT hResult = 0L; +#define DLG_ON_NOTIFY(id,msg,fnc) \ + if( (UINT)wParam == (id) && ((NMHDR*)lParam)->code == (msg) ) {\ + fnc( ((NMHDR*)lParam)->hwndFrom, (UINT)wParam, (NMHDR*)lParam, hResult );\ + return (BOOL)hResult; } +#define DLG_ON_NOTIFY_RANGE(id,idend,msg,fnc) \ + if( (UINT)wParam >= (id) && (UINT)wParam <= (idend) && ((NMHDR*)lParam)->code == (msg) ) {\ + fnc( ((NMHDR*)lParam)->hwndFrom, (UINT)wParam, (NMHDR*)lParam, hResult );\ + return (BOOL)hResult; } +#define DLG_NOTIFY_END() \ + return FALSE; }; break; + +#define DLG_MESSAGE_END() \ + default: break; }\ + return FALSE;\ + } + +// +// _CAORg[wp[}N +// +#define BTNCHECK(ctrlid,check) ::CheckDlgButton(m_hWnd,(ctrlid),(check)?BST_CHECKED:BST_UNCHECKED) +#define IsBTNCHECK(ctrlid) ((::IsDlgButtonChecked(m_hWnd,(ctrlid))==BST_CHECKED)?TRUE:FALSE) + +#define CTRLENABLE(ctrlid,enable) ::EnableWindow(::GetDlgItem(m_hWnd,(ctrlid)),enable); + +#endif // !__CWND_INCLUDED__ diff --git a/References/VirtuaNESex_src_191105/WndHook.cpp b/References/VirtuaNESex_src_191105/WndHook.cpp new file mode 100644 index 00000000..181c2f69 --- /dev/null +++ b/References/VirtuaNESex_src_191105/WndHook.cpp @@ -0,0 +1,76 @@ +// +// bZ[WtB^OT|[gNX +// +#include "DebugOut.h" + +#include "App.h" +#include "Wnd.h" +#include "WndHook.h" + +// Instance +CWndHook WndHook; + +BOOL CWndHook::m_bMsgFiltering = FALSE; +BOOL CWndHook::m_bMsgFilter = FALSE; +HHOOK CWndHook::m_hOldMsgFilter = NULL; + +// bZ[WtB^tbN̏(EChEĂĂяo) +void CWndHook::Initialize() +{ + m_hOldMsgFilter = ::SetWindowsHookEx( WH_MSGFILTER, (HOOKPROC)MessageFilterProc, NULL, ::GetCurrentThreadId() ); +} + +void CWndHook::Release() +{ + if( m_hOldMsgFilter ) { + ::UnhookWindowsHookEx( m_hOldMsgFilter ); + m_hOldMsgFilter = NULL; + } +} + +// bZ[WtB^(_CAO͕ʂł͗ȂbZ[W邽) +LRESULT CALLBACK CWndHook::MessageFilterProc( INT code, WPARAM wParam, LPARAM lParam ) +{ + if( code < 0 ) { + return ::CallNextHookEx( m_hOldMsgFilter, code, wParam, lParam ); + } + + if( m_bMsgFiltering && code == MSGF_DIALOGBOX ) { + // ɃtB^OH + if( m_bMsgFilter ) + return FALSE; + m_bMsgFilter = TRUE; + LPMSG lpMsg = (LPMSG)lParam; + if( lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST ) { + if( WalkPreTranslateTree( lpMsg ) ) { + m_bMsgFilter = FALSE; + return 1L; + } + } + m_bMsgFilter = FALSE; + } + + return ::CallNextHookEx( m_hOldMsgFilter, code, wParam, lParam ); +// return FALSE; +} + +BOOL CWndHook::WalkPreTranslateTree( MSG* lpMsg ) +{ + // Ct[EChE + HWND hWndStop = CApp::GetHWnd(); + + // PreTranslateMessageH + for( HWND hWnd = lpMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd) ) { + if( hWnd == hWndStop ) + break; + CWnd* pWnd = (CWnd*)::GetWindowLong( hWnd, GWL_USERDATA ); + if( pWnd ) { + if( pWnd->PreTranslateMessage( lpMsg ) ) + return TRUE; + } + if( hWnd == hWndStop ) + break; + } + return FALSE; +} + diff --git a/References/VirtuaNESex_src_191105/WndHook.h b/References/VirtuaNESex_src_191105/WndHook.h new file mode 100644 index 00000000..ad3117d2 --- /dev/null +++ b/References/VirtuaNESex_src_191105/WndHook.h @@ -0,0 +1,37 @@ +// +// bZ[WtB^OT|[gNX +// +#ifndef __CWNDHOOK_INCLUDED__ +#define __CWNDHOOK_INCLUDED__ + +#define WIN32_LEAN_AND_MEAN +#include + +// prototypes +class CWnd; + +class CWndHook +{ +public: + static void Initialize(); + static void Release(); + + static void SetFiltering( BOOL bMode ) { m_bMsgFiltering = bMode; } + + static BOOL WalkPreTranslateTree( MSG* lpMsg ); + +protected: + static LRESULT CALLBACK MessageFilterProc( INT code, WPARAM wParam, LPARAM lParam ); + + // bZ[WtB^O邩ǂ̃tO + static BOOL m_bMsgFiltering; + + // bZ[WtB^Oǂ̃tO + static BOOL m_bMsgFilter; + // ̃tbNvV[W + static HHOOK m_hOldMsgFilter; +private: +}; + +#endif // !__CWNDHOOK_INCLUDED__ + diff --git a/References/VirtuaNESex_src_191105/lzAscii.h b/References/VirtuaNESex_src_191105/lzAscii.h new file mode 100644 index 00000000..2e92773e --- /dev/null +++ b/References/VirtuaNESex_src_191105/lzAscii.h @@ -0,0 +1,28 @@ + 0xE8, 0x04, 0x00, 0x00, 0xB7, 0x01, 0x00, 0x00, 0x75, 0x28, 0xEB, 0xF0, 0x30, 0xEF, 0xF4, 0x01, + 0x00, 0x04, 0xDD, 0xFE, 0x75, 0x10, 0xE1, 0xFA, 0x80, 0x1A, 0x02, 0x00, 0x80, 0x80, 0x1E, 0x03, + 0x9C, 0x29, 0x01, 0x1C, 0x00, 0xC0, 0xC0, 0xC0, 0x22, 0x00, 0x1F, 0x01, 0xFF, 0x0E, 0x3A, 0x02, + 0x00, 0xFF, 0xFF, 0x3E, 0x03, 0x49, 0x01, 0x3C, 0x01, 0x4E, 0x01, 0xD6, 0xE3, 0xF8, 0x01, 0x99, + 0x0E, 0x07, 0xF0, 0x6D, 0x02, 0xFF, 0xFF, 0x7E, 0x72, 0x00, 0x00, 0x19, 0x99, 0x91, 0x0F, 0xF0, + 0xEA, 0xF1, 0x74, 0x74, 0x00, 0x6E, 0x03, 0x0F, 0x6B, 0x02, 0x99, 0x99, 0x99, 0x6D, 0x00, 0x06, + 0xE8, 0xF3, 0x0F, 0xFF, 0x9D, 0x01, 0x95, 0x01, 0x90, 0x0B, 0x6E, 0x00, 0x88, 0x04, 0x01, 0xF0, + 0x79, 0x01, 0x89, 0x01, 0x8C, 0x01, 0xB5, 0x04, 0x74, 0x03, 0x62, 0x00, 0x7D, 0x01, 0x38, 0x96, + 0x05, 0xE8, 0x0F, 0x6B, 0x02, 0x00, 0x0F, 0xF0, 0xD0, 0x03, 0x6C, 0x01, 0x80, 0xA1, 0x03, 0xC8, + 0x00, 0xA5, 0x01, 0x14, 0x11, 0xA5, 0x02, 0x6E, 0x02, 0x13, 0x11, 0xF0, 0x00, 0x06, 0x11, 0x2B, + 0x13, 0xA1, 0x03, 0xB6, 0x03, 0x42, 0x11, 0x3E, 0x13, 0xB7, 0x01, 0x39, 0x1A, 0x00, 0x34, 0x13, + 0x34, 0x12, 0xD3, 0x01, 0x3D, 0x16, 0xEC, 0x0F, 0x68, 0x06, 0x9E, 0x01, 0x6E, 0x02, 0x04, 0x83, + 0x01, 0x02, 0x10, 0x0F, 0x90, 0x11, 0x21, 0x15, 0x18, 0x13, 0x41, 0x13, 0xD0, 0x05, 0x02, 0xFE, + 0x01, 0x00, 0xBF, 0x13, 0xB5, 0x16, 0x6E, 0x03, 0x8B, 0x00, 0xAF, 0x1C, 0x8E, 0x13, 0x1C, 0xC6, + 0x10, 0x4C, 0x13, 0xFF, 0x0F, 0xF0, 0x2F, 0x10, 0xA1, 0x01, 0x06, 0x2F, 0x00, 0x99, 0x03, 0x01, + 0x10, 0x05, 0x12, 0x67, 0x12, 0x82, 0x03, 0x66, 0x11, 0x2B, 0x12, 0x4B, 0x14, 0x00, 0x3C, 0x25, + 0xB5, 0x02, 0x02, 0x15, 0x1E, 0x13, 0x2A, 0x22, 0xD2, 0x00, 0x9F, 0x11, 0x49, 0x16, 0x00, 0x42, + 0x28, 0x9D, 0x04, 0x24, 0x29, 0x74, 0x00, 0x67, 0x10, 0x0C, 0x2F, 0xE8, 0xF3, 0x8D, 0x23, 0x00, + 0x9B, 0x01, 0xB4, 0x24, 0x8B, 0x04, 0x1C, 0x16, 0xA4, 0x03, 0xBE, 0x14, 0xAC, 0x28, 0xB8, 0x25, + 0x00, 0xB5, 0x22, 0xA4, 0x12, 0xC4, 0x26, 0xD2, 0x26, 0xD1, 0x03, 0xE1, 0x26, 0xBA, 0x26, 0x03, + 0x2F, 0x00, 0x15, 0x27, 0x5F, 0x14, 0xD3, 0x02, 0xC5, 0x10, 0x8E, 0x23, 0xF2, 0x24, 0x95, 0x03, + 0xB0, 0x23, 0x00, 0x85, 0x04, 0x02, 0x12, 0x9D, 0x03, 0x9F, 0x10, 0x43, 0x37, 0xA0, 0x10, 0x95, + 0x02, 0xB2, 0x12, 0x00, 0x14, 0x13, 0x6A, 0x02, 0x91, 0x13, 0x8D, 0x23, 0x7A, 0x36, 0x11, 0x37, + 0xE5, 0x29, 0xE4, 0x26, 0x08, 0x21, 0x14, 0xDF, 0x05, 0x88, 0x36, 0x0F, 0xC7, 0x02, 0x95, 0x28, + 0x8C, 0x03, 0xBC, 0x03, 0x00, 0xB1, 0x23, 0xE1, 0x24, 0x78, 0x24, 0xEB, 0x3D, 0x1F, 0x32, 0xD0, + 0x38, 0xF4, 0x0A, 0x47, 0x4F, 0x00, 0x3D, 0x4A, 0xC8, 0x00, 0x2E, 0x11, 0xA1, 0x10, 0x74, 0x1B, + 0xBE, 0x12, 0x27, 0x10, 0x79, 0x31, 0x20, 0x5B, 0x4C, 0x0D, 0x16, 0x67, 0x06, 0x67, 0x42, 0x02, + 0x11, 0xFF, 0x29, 0x12, 0xDA, 0x36, 0x00, 0x97, 0x41, 0x98, 0x41, 0xFF, 0x12, 0x42, 0x42, 0x00, diff --git a/References/VirtuaNESex_src_191105/lzSight.h b/References/VirtuaNESex_src_191105/lzSight.h new file mode 100644 index 00000000..cc29abbf --- /dev/null +++ b/References/VirtuaNESex_src_191105/lzSight.h @@ -0,0 +1,6 @@ + 0xE8, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x75, 0x28, 0xEB, 0xF0, 0x10, 0xEF, 0xF4, 0x01, + 0x00, 0x04, 0xDD, 0xFE, 0x74, 0xF2, 0xF1, 0xE4, 0xF7, 0x80, 0x1A, 0x02, 0x00, 0x80, 0x80, 0x1E, + 0x03, 0x9C, 0x29, 0x01, 0x1C, 0x00, 0xC0, 0xC0, 0xC0, 0x22, 0x00, 0x1F, 0x01, 0xFF, 0x0E, 0x3A, + 0x02, 0x00, 0xFF, 0xFF, 0x3E, 0x03, 0x49, 0x01, 0x3C, 0x01, 0x4E, 0x01, 0x0F, 0x00, 0x00, 0x0F, + 0xF0, 0xE8, 0xF3, 0x59, 0x0F, 0x6B, 0x0B, 0x53, 0x03, 0x00, 0x68, 0x00, 0x69, 0x01, 0x52, 0x02, + 0x52, 0x00, 0x8E, 0x05, 0x86, 0x05, 0x7E, 0x07, 0x68, 0x0F, 0x06, 0xBA, 0x0F, 0x00, 0x00, 0x00, diff --git a/References/VirtuaNESex_src_191105/lzTVlayer.h b/References/VirtuaNESex_src_191105/lzTVlayer.h new file mode 100644 index 00000000..a11ba21a --- /dev/null +++ b/References/VirtuaNESex_src_191105/lzTVlayer.h @@ -0,0 +1,944 @@ + 0x68, 0xE0, 0x01, 0x00, 0xF4, 0x3A, 0x00, 0x00, 0xFD, 0x28, 0xEA, 0xF1, 0x02, 0x00, 0x00, 0xE0, + 0x01, 0x00, 0xAF, 0x00, 0x01, 0x00, 0x04, 0xDD, 0xFE, 0x10, 0xE3, 0xF8, 0x42, 0xFF, 0x42, 0x42, + 0x00, 0x4A, 0x4A, 0x4A, 0x00, 0x52, 0xFF, 0x52, 0x52, 0x00, 0x5A, 0x5A, 0x5A, 0x00, 0x63, 0xFF, + 0x63, 0x63, 0x00, 0x6B, 0x6B, 0x6B, 0x00, 0x73, 0xFF, 0x73, 0x73, 0x00, 0x7B, 0x7B, 0x7B, 0x00, + 0x84, 0xF3, 0x84, 0x84, 0xDC, 0xFF, 0xE7, 0xF4, 0x98, 0x87, 0x77, 0x65, 0x1F, 0x54, 0x43, 0x32, + 0x21, 0x11, 0x5E, 0x0F, 0x70, 0x0F, 0x82, 0x0F, 0x00, 0x94, 0x0F, 0xA6, 0x0F, 0xB8, 0x0F, 0xCA, + 0x0F, 0xDC, 0x0F, 0xEE, 0x0F, 0x00, 0x1F, 0x12, 0x1F, 0xF8, 0x24, 0x1F, 0x36, 0x1F, 0x3C, 0x12, + 0x12, 0x23, 0x34, 0x45, 0x56, 0xFF, 0x77, 0x78, 0x89, 0x99, 0x88, 0x77, 0x66, 0x55, 0x03, 0x43, + 0x33, 0x5D, 0x0F, 0x6E, 0x1F, 0x80, 0x1F, 0x92, 0x1F, 0xA4, 0x1F, 0xB6, 0x1F, 0x00, 0xC8, 0x1F, + 0xDA, 0x1F, 0xEC, 0x1F, 0xFE, 0x1F, 0x10, 0x2F, 0x22, 0x2F, 0x34, 0x2F, 0x47, 0x15, 0xFF, 0x33, + 0x34, 0x55, 0x66, 0x77, 0x88, 0x99, 0x99, 0x7F, 0x88, 0x87, 0x76, 0x55, 0x44, 0x33, 0x22, 0x3C, + 0x2F, 0x00, 0x6F, 0x2F, 0x81, 0x2F, 0x93, 0x2F, 0xA5, 0x2F, 0xB7, 0x2F, 0xC9, 0x2F, 0xDB, 0x2F, + 0xED, 0x2F, 0xE0, 0xFF, 0x2F, 0x11, 0x3F, 0x23, 0x3F, 0x35, 0x3F, 0x3C, 0x33, 0x22, 0x33, 0x44, + 0xFF, 0x55, 0x67, 0x78, 0x88, 0x99, 0x89, 0x98, 0x88, 0x00, 0x58, 0x00, 0x5C, 0x2F, 0x6D, 0x3F, + 0x7F, 0x3F, 0x91, 0x3F, 0xA3, 0x3F, 0xB5, 0x3F, 0xC7, 0x3F, 0x00, 0xD9, 0x3F, 0xEB, 0x3F, 0xFD, + 0x3F, 0x0F, 0x4F, 0x21, 0x4F, 0x33, 0x4F, 0x46, 0x37, 0x51, 0x10, 0x5D, 0x88, 0x56, 0x30, 0x89, + 0x88, 0x87, 0x59, 0x10, 0x32, 0x3C, 0x4F, 0x00, 0x6F, 0x4F, 0x81, 0x4F, 0x93, 0x4F, 0xA5, 0x4F, + 0xB7, 0x4F, 0xC9, 0x4F, 0xDB, 0x4F, 0xED, 0x4F, 0xA0, 0xFF, 0x4F, 0x11, 0x5F, 0x23, 0x5F, 0x35, + 0x5F, 0x3C, 0x53, 0x23, 0x50, 0x20, 0x78, 0x77, 0x88, 0x98, 0x88, 0x52, 0x50, 0x87, 0x76, 0x65, + 0x5B, 0x0F, 0x00, 0x6D, 0x5F, 0x7F, 0x5F, 0x91, 0x5F, 0xA3, 0x5F, 0xB5, 0x5F, 0xC7, 0x5F, 0xD9, + 0x5F, 0xEB, 0x5F, 0xE0, 0xFD, 0x5F, 0x0F, 0x6F, 0x21, 0x6F, 0x33, 0x6F, 0x47, 0x17, 0x56, 0x67, + 0x78, 0x0E, 0x57, 0x40, 0x77, 0x88, 0x88, 0x58, 0x32, 0x5E, 0x5F, 0x6F, 0x6F, 0x81, 0x6F, 0x00, + 0x93, 0x6F, 0xA5, 0x6F, 0xB7, 0x6F, 0xC9, 0x6F, 0xDB, 0x6F, 0xED, 0x6F, 0xFF, 0x6F, 0x11, 0x7F, + 0x00, 0x23, 0x7F, 0x35, 0x7F, 0x49, 0x24, 0x50, 0x41, 0x58, 0x60, 0x52, 0x30, 0x57, 0x20, 0x5B, + 0x3F, 0x00, 0x6D, 0x7F, 0x7F, 0x7F, 0x91, 0x7F, 0xA3, 0x7F, 0xB5, 0x7F, 0xC7, 0x7F, 0xD9, 0x7F, + 0xEB, 0x7F, 0x00, 0xFD, 0x7F, 0x0F, 0x8F, 0x21, 0x8F, 0x33, 0x8F, 0x47, 0x47, 0x56, 0x73, 0x52, + 0x10, 0x58, 0x61, 0x00, 0x5C, 0x4F, 0x6E, 0x8F, 0x80, 0x8F, 0x92, 0x8F, 0xA4, 0x8F, 0xB6, 0x8F, + 0xC8, 0x8F, 0xDA, 0x8F, 0x00, 0xEC, 0x8F, 0xFE, 0x8F, 0x10, 0x9F, 0x22, 0x9F, 0x34, 0x9F, 0x48, + 0x55, 0x50, 0x71, 0x57, 0x00, 0x06, 0x51, 0x21, 0x88, 0x87, 0x5C, 0x8F, 0x6D, 0x9F, 0x7F, 0x9F, + 0x91, 0x9F, 0xA3, 0x9F, 0x00, 0xB5, 0x9F, 0xC7, 0x9F, 0xD9, 0x9F, 0xEB, 0x9F, 0xFD, 0x9F, 0x0F, + 0xAF, 0x21, 0xAF, 0x33, 0xAF, 0xDC, 0x46, 0x97, 0x58, 0x81, 0x66, 0x55, 0x55, 0x50, 0x60, 0x88, + 0x88, 0x03, 0x76, 0x54, 0x5D, 0x5F, 0x6F, 0xAF, 0x81, 0xAF, 0x93, 0xAF, 0x9B, 0xA4, 0x0E, 0x09, + 0x10, 0xB8, 0xAF, 0xCA, 0xAF, 0xDC, 0xAF, 0xDF, 0xFC, 0x01, 0x9B, 0xAF, 0x10, 0xBF, 0x22, 0xBF, + 0xEC, 0x34, 0xBF, 0x49, 0x14, 0x45, 0x67, 0x58, 0x71, 0x65, 0x55, 0x45, 0x0D, 0x55, 0x4F, 0x92, + 0x65, 0x43, 0x5F, 0xAF, 0x70, 0xBF, 0x9F, 0xAF, 0x94, 0xBF, 0x00, 0xA6, 0xBF, 0xB8, 0xBF, 0xCA, + 0xBF, 0xDC, 0xBF, 0xEE, 0xBF, 0x00, 0xCF, 0xF7, 0xAF, 0x24, 0xCF, 0xF8, 0x36, 0xCF, 0x4B, 0x11, + 0x4E, 0xA3, 0x65, 0x55, 0x54, 0x44, 0x45, 0x06, 0x50, 0x51, 0x88, 0x75, 0x5E, 0xBF, 0x6E, 0xCD, + 0x08, 0xCF, 0x91, 0xCF, 0xA3, 0xCF, 0x00, 0xB5, 0xCF, 0xC7, 0xCF, 0xD9, 0xCF, 0xEB, 0xCF, 0xFD, + 0xCF, 0x0F, 0xDF, 0xE4, 0xF7, 0x6E, 0xCF, 0x2A, 0x3E, 0xCD, 0x57, 0x58, 0x70, 0x66, 0x54, 0xC0, + 0x33, 0x56, 0xC0, 0x4F, 0xB0, 0x00, 0x5C, 0xA0, 0x3A, 0xDF, 0x7E, 0xCF, 0x83, 0xDF, 0x95, 0xDF, + 0xA7, 0xDF, 0xB9, 0xDF, 0xCB, 0xDF, 0x00, 0xDD, 0xDF, 0xEF, 0xDF, 0x01, 0xEF, 0x13, 0xEF, 0x25, + 0xEF, 0x62, 0xDF, 0x4C, 0x50, 0x4E, 0xB1, 0x65, 0x76, 0x53, 0xD1, 0x33, 0x56, 0xD0, 0x4F, 0xA0, + 0x87, 0x65, 0x5F, 0xD9, 0x00, 0x91, 0xBF, 0x7C, 0xEF, 0x8E, 0xEF, 0xA0, 0xEF, 0xB2, 0xEF, 0xC4, + 0xEF, 0xD6, 0xEF, 0xE8, 0xEF, 0x80, 0xFA, 0xEF, 0x0C, 0xFF, 0x1E, 0xFF, 0x0B, 0xCF, 0x45, 0x57, + 0x5A, 0xE2, 0x53, 0xE1, 0x22, 0x0D, 0x23, 0x4F, 0x33, 0x75, 0x42, 0x66, 0xEF, 0x71, 0xFF, 0x83, + 0xFF, 0x95, 0xFF, 0x00, 0xA7, 0xFF, 0xB9, 0xFF, 0xCB, 0xFF, 0xDD, 0xFF, 0xEF, 0xFF, 0x01, 0x0F, + 0x13, 0x0F, 0x25, 0x0F, 0xDE, 0x32, 0xFF, 0x11, 0x11, 0x24, 0x57, 0x57, 0x23, 0x32, 0x22, 0x1D, + 0x11, 0x56, 0xF3, 0x88, 0x76, 0x42, 0x34, 0x0F, 0x71, 0x0F, 0x83, 0x0F, 0x00, 0x95, 0x0F, 0xA7, + 0x0F, 0xB9, 0x0F, 0xCB, 0x0F, 0xDD, 0x0F, 0xEF, 0x0F, 0x01, 0x1F, 0x13, 0x1F, 0x1C, 0x25, 0x1F, + 0x37, 0x1F, 0x00, 0x00, 0x24, 0x5C, 0x00, 0x51, 0x03, 0x4C, 0x30, 0x0E, 0x58, 0x00, 0x56, 0x78, + 0x87, 0x3A, 0x1F, 0x70, 0x1F, 0x82, 0x1F, 0x94, 0x1F, 0x00, 0xA6, 0x1F, 0xB8, 0x1F, 0xCA, 0x1F, + 0xDC, 0x1F, 0xEE, 0x1F, 0x00, 0x2F, 0x12, 0x2F, 0x24, 0x2F, 0x9C, 0x36, 0x2F, 0x34, 0xE1, 0x78, + 0x87, 0x65, 0x51, 0x14, 0x56, 0x12, 0x45, 0x03, 0x66, 0x70, 0x3B, 0x2F, 0x70, 0x2F, 0x82, 0x2F, + 0x94, 0x2F, 0xA6, 0x2F, 0xB8, 0x2F, 0x00, 0xCA, 0x2F, 0xDC, 0x2F, 0xEE, 0x2F, 0x00, 0x3F, 0x12, + 0x3F, 0x24, 0x3F, 0x36, 0x3F, 0x34, 0xE1, 0x27, 0x07, 0x66, 0x54, 0x51, 0x25, 0x4B, 0x62, 0x45, + 0x3B, 0x3F, 0x6F, 0x3F, 0x00, 0x81, 0x3F, 0x93, 0x3F, 0xA5, 0x3F, 0xB7, 0x3F, 0xC9, 0x3F, 0xDB, + 0x3F, 0xED, 0x3F, 0xFF, 0x3F, 0xD0, 0x11, 0x4F, 0x23, 0x4F, 0x35, 0x4F, 0x32, 0xE3, 0x54, 0x5C, + 0x59, 0x12, 0x23, 0x01, 0x32, 0x3C, 0x4F, 0x6F, 0x4F, 0x81, 0x4F, 0x93, 0x4F, 0xA5, 0x4F, 0xB7, + 0x4F, 0xC9, 0x4F, 0x80, 0xDB, 0x4F, 0xED, 0x4F, 0xFF, 0x4F, 0x11, 0x5F, 0x23, 0x5F, 0x35, 0x5F, + 0x32, 0xE3, 0x23, 0x06, 0x5E, 0xAA, 0x12, 0x20, 0x3C, 0x5F, 0x6F, 0x5F, 0x81, 0x5F, 0x93, 0x5F, + 0xA5, 0x5F, 0x00, 0xB7, 0x5F, 0xC9, 0x5F, 0xDB, 0x5F, 0xED, 0x5F, 0xFF, 0x5F, 0x11, 0x6F, 0x23, + 0x6F, 0x35, 0x6F, 0x02, 0x32, 0xE3, 0x02, 0x5F, 0xCB, 0x65, 0xFF, 0x6E, 0x6F, 0x80, 0x6F, 0x92, + 0x6F, 0xA4, 0x6F, 0x00, 0xB6, 0x6F, 0xC8, 0x6F, 0xDA, 0x6F, 0xEC, 0x6F, 0xFE, 0x6F, 0x10, 0x7F, + 0x22, 0x7F, 0x34, 0x7F, 0x00, 0x39, 0xFF, 0x59, 0x6F, 0x6A, 0x7F, 0x7C, 0x7F, 0x8E, 0x7F, 0xA0, + 0x7F, 0xB2, 0x7F, 0xC4, 0x7F, 0x00, 0xD6, 0x7F, 0xE8, 0x7F, 0xFA, 0x7F, 0x0C, 0x8F, 0x1E, 0x8F, + 0x30, 0x8F, 0x43, 0x7F, 0x55, 0x7F, 0x00, 0x66, 0x8F, 0x78, 0x8F, 0x8A, 0x8F, 0x9C, 0x8F, 0xAE, + 0x8F, 0xC0, 0x8F, 0xD2, 0x8F, 0xE4, 0x8F, 0x00, 0xF6, 0x8F, 0x08, 0x9F, 0x1A, 0x9F, 0x2C, 0x9F, + 0x3F, 0x8F, 0x51, 0x8F, 0x62, 0x9F, 0x74, 0x9F, 0x00, 0x86, 0x9F, 0x98, 0x9F, 0xAA, 0x9F, 0xBC, + 0x9F, 0xCE, 0x9F, 0xE0, 0x9F, 0xF2, 0x9F, 0x04, 0xAF, 0x00, 0x16, 0xAF, 0x28, 0xAF, 0x3A, 0xAF, + 0x4D, 0x9F, 0x5E, 0xAF, 0x70, 0xAF, 0x82, 0xAF, 0x94, 0xAF, 0x00, 0xA6, 0xAF, 0xB8, 0xAF, 0xCA, + 0xAF, 0xDC, 0xAF, 0xEE, 0xAF, 0x00, 0xBF, 0x12, 0xBF, 0x24, 0xBF, 0x00, 0x36, 0xBF, 0x49, 0xAF, + 0x72, 0xDF, 0x6C, 0xBF, 0x7E, 0xBF, 0x90, 0xBF, 0xA2, 0xBF, 0xB4, 0xBF, 0x00, 0xC6, 0xBF, 0xD8, + 0xBF, 0xEA, 0xBF, 0xFC, 0xBF, 0x0E, 0xCF, 0x20, 0xCF, 0x32, 0xCF, 0x2E, 0xEF, 0x00, 0x57, 0xBF, + 0x68, 0xCF, 0x7A, 0xCF, 0x8C, 0xCF, 0x9E, 0xCF, 0xB0, 0xCF, 0xC2, 0xCF, 0xD4, 0xCF, 0x00, 0xE6, + 0xCF, 0xF8, 0xCF, 0x0A, 0xDF, 0x1C, 0xDF, 0x2E, 0xDF, 0x41, 0xCF, 0x53, 0xCF, 0x64, 0xDF, 0x00, + 0x76, 0xDF, 0x88, 0xDF, 0x9A, 0xDF, 0xAC, 0xDF, 0xBE, 0xDF, 0xD0, 0xDF, 0xE2, 0xDF, 0xF4, 0xDF, + 0x00, 0x06, 0xEF, 0x18, 0xEF, 0x2A, 0xEF, 0x3C, 0xEF, 0x4F, 0xDF, 0x60, 0xEF, 0x72, 0xEF, 0x84, + 0xEF, 0x00, 0x96, 0xEF, 0xA8, 0xEF, 0xBA, 0xEF, 0xCC, 0xEF, 0xDE, 0xEF, 0xF0, 0xEF, 0x02, 0xFF, + 0x14, 0xFF, 0x00, 0x26, 0xFF, 0x38, 0xFF, 0x4B, 0xEF, 0x3D, 0xFF, 0x6E, 0xFF, 0x80, 0xFF, 0x92, + 0xFF, 0xA4, 0xFF, 0x00, 0xB6, 0xFF, 0xC8, 0xFF, 0xDA, 0xFF, 0xEC, 0xFF, 0xFE, 0xFF, 0x10, 0x0F, + 0x22, 0x0F, 0x34, 0x0F, 0x00, 0x47, 0xFF, 0x59, 0xFF, 0x6A, 0x0F, 0x7C, 0x0F, 0x8E, 0x0F, 0xA0, + 0x0F, 0xB2, 0x0F, 0xC4, 0x0F, 0x00, 0xD6, 0x0F, 0xE8, 0x0F, 0xFA, 0x0F, 0x0C, 0x1F, 0x1E, 0x1F, + 0x30, 0x1F, 0x43, 0x0F, 0x55, 0x0F, 0x00, 0x66, 0x1F, 0x78, 0x1F, 0x8A, 0x1F, 0x9C, 0x1F, 0xAE, + 0x1F, 0xC0, 0x1F, 0xD2, 0x1F, 0xE4, 0x1F, 0x00, 0xF6, 0x1F, 0x08, 0x2F, 0x1A, 0x2F, 0x2C, 0x2F, + 0x3F, 0x1F, 0x52, 0xAF, 0x62, 0x2F, 0x74, 0x2F, 0x00, 0x86, 0x2F, 0x98, 0x2F, 0xAA, 0x2F, 0xBC, + 0x2F, 0xCE, 0x2F, 0xE0, 0x2F, 0xF2, 0x2F, 0x04, 0x3F, 0x00, 0x16, 0x3F, 0x28, 0x3F, 0x3A, 0x3F, + 0x4C, 0xAC, 0x5C, 0x2F, 0x6D, 0x3F, 0x7F, 0x3F, 0x91, 0x3F, 0x00, 0xA3, 0x3F, 0xB5, 0x3F, 0xC7, + 0x3F, 0xD9, 0x3F, 0xEB, 0x3F, 0xFD, 0x3F, 0x0F, 0x4F, 0x21, 0x4F, 0x00, 0x33, 0x4F, 0x46, 0x3F, + 0x58, 0x3F, 0x69, 0x4F, 0x7B, 0x4F, 0x8D, 0x4F, 0x9F, 0x4F, 0xB1, 0x4F, 0x00, 0xC3, 0x4F, 0xD5, + 0x4F, 0xE7, 0x4F, 0xF9, 0x4F, 0x0B, 0x5F, 0x1D, 0x5F, 0x2F, 0x5F, 0x42, 0x4F, 0x00, 0x54, 0x4F, + 0x65, 0x5F, 0x77, 0x5F, 0x89, 0x5F, 0x9B, 0x5F, 0xAD, 0x5F, 0xBF, 0x5F, 0xD1, 0x5F, 0x00, 0xE3, + 0x5F, 0xF5, 0x5F, 0x07, 0x6F, 0x19, 0x6F, 0x2B, 0x6F, 0x3E, 0x5F, 0x50, 0x5F, 0x61, 0x6F, 0x00, + 0x73, 0x6F, 0x85, 0x6F, 0x97, 0x6F, 0xA9, 0x6F, 0xBB, 0x6F, 0xCD, 0x6F, 0xDF, 0x6F, 0xF1, 0x6F, + 0x00, 0x03, 0x7F, 0x15, 0x7F, 0x27, 0x7F, 0x39, 0x7F, 0x4C, 0x6F, 0x5D, 0x7F, 0x6F, 0x7F, 0x81, + 0x7F, 0x00, 0x93, 0x7F, 0xA5, 0x7F, 0xB7, 0x7F, 0xC9, 0x7F, 0xDB, 0x7F, 0xED, 0x7F, 0xFF, 0x7F, + 0x11, 0x8F, 0x00, 0x23, 0x8F, 0x35, 0x8F, 0x48, 0x7F, 0x5A, 0x7F, 0x6B, 0x8F, 0x7D, 0x8F, 0x8F, + 0x8F, 0xA1, 0x8F, 0x00, 0xB3, 0x8F, 0xC5, 0x8F, 0xD7, 0x8F, 0xE9, 0x8F, 0xFB, 0x8F, 0x0D, 0x9F, + 0x1F, 0x9F, 0x31, 0x9F, 0x00, 0x44, 0x8F, 0x56, 0x8F, 0x67, 0x9F, 0x79, 0x9F, 0x8B, 0x9F, 0x9D, + 0x9F, 0xAF, 0x9F, 0xC1, 0x9F, 0x00, 0xD3, 0x9F, 0xE5, 0x9F, 0xF7, 0x9F, 0x09, 0xAF, 0x1B, 0xAF, + 0x2D, 0xAF, 0x40, 0x9F, 0x52, 0x9F, 0x00, 0x63, 0xAF, 0x75, 0xAF, 0x87, 0xAF, 0x99, 0xAF, 0xAB, + 0xAF, 0xBD, 0xAF, 0xCF, 0xAF, 0xE1, 0xAF, 0x00, 0xF3, 0xAF, 0x05, 0xBF, 0x17, 0xBF, 0x29, 0xBF, + 0x3B, 0xBF, 0x4E, 0xAB, 0x3D, 0xBF, 0x6D, 0xBF, 0x00, 0x7F, 0xBF, 0x91, 0xBF, 0xA3, 0xBF, 0xB5, + 0xBF, 0xC7, 0xBF, 0xD9, 0xBF, 0xEB, 0xBF, 0xFD, 0xBF, 0x00, 0x0F, 0xCF, 0x21, 0xCF, 0x33, 0xCF, + 0x45, 0x2F, 0x58, 0xBF, 0x69, 0xCF, 0x7B, 0xCF, 0x8D, 0xCF, 0x00, 0x9F, 0xCF, 0xB1, 0xCF, 0xC3, + 0xCF, 0xD5, 0xCF, 0xE7, 0xCF, 0xF9, 0xCF, 0x0B, 0xDF, 0x1D, 0xDF, 0x00, 0x2F, 0xDF, 0x42, 0xCF, + 0x54, 0xCF, 0x65, 0xDF, 0x77, 0xDF, 0x89, 0xDF, 0x9B, 0xDF, 0xAD, 0xDF, 0x00, 0xBF, 0xDF, 0xD1, + 0xDF, 0xE3, 0xDF, 0xF5, 0xDF, 0x07, 0xEF, 0x19, 0xEF, 0x2B, 0xEF, 0x3D, 0xEF, 0x00, 0x50, 0xDF, + 0x61, 0xEF, 0x73, 0xEF, 0x85, 0xEF, 0x97, 0xEF, 0xA9, 0xEF, 0xBB, 0xEF, 0xCD, 0xEF, 0x00, 0xDF, + 0xEF, 0xF1, 0xEF, 0x03, 0xFF, 0x15, 0xFF, 0x27, 0xFF, 0x39, 0xFF, 0x4C, 0xEF, 0x5D, 0xFF, 0x00, + 0x6F, 0xFF, 0x81, 0xFF, 0x93, 0xFF, 0xA5, 0xFF, 0xB7, 0xFF, 0xC9, 0xFF, 0xDB, 0xFF, 0xED, 0xFF, + 0x00, 0xFF, 0xFF, 0x11, 0x0F, 0x23, 0x0F, 0x35, 0x0F, 0x48, 0xFF, 0x5A, 0xFF, 0x6B, 0x0F, 0x7D, + 0x0F, 0x00, 0x8F, 0x0F, 0xA1, 0x0F, 0xB3, 0x0F, 0xC5, 0x0F, 0xD7, 0x0F, 0xE9, 0x0F, 0xFB, 0x0F, + 0x0D, 0x1F, 0x00, 0x1F, 0x1F, 0x31, 0x1F, 0x44, 0x0F, 0x56, 0x0F, 0x67, 0x1F, 0x79, 0x1F, 0x8B, + 0x1F, 0x9D, 0x1F, 0x00, 0xAF, 0x1F, 0xC1, 0x1F, 0xD3, 0x1F, 0xE5, 0x1F, 0xF7, 0x1F, 0x09, 0x2F, + 0x1B, 0x2F, 0x2D, 0x2F, 0x00, 0x40, 0x1F, 0x52, 0x1F, 0x63, 0x2F, 0x75, 0x2F, 0x87, 0x2F, 0x99, + 0x2F, 0xAB, 0x2F, 0xBD, 0x2F, 0x00, 0xCF, 0x2F, 0xE1, 0x2F, 0xF3, 0x2F, 0x05, 0x3F, 0x17, 0x3F, + 0x29, 0x3F, 0x3B, 0x3F, 0x4E, 0x2F, 0x00, 0x5F, 0x3F, 0x71, 0x3F, 0x83, 0x3F, 0x95, 0x3F, 0xA7, + 0x3F, 0xB9, 0x3F, 0xCB, 0x3F, 0xDD, 0x3F, 0x00, 0xEF, 0x3F, 0x01, 0x4F, 0x13, 0x4F, 0x25, 0x4F, + 0x37, 0x4F, 0x4A, 0x3F, 0x3E, 0x4F, 0x6D, 0x4F, 0x00, 0x7F, 0x4F, 0x91, 0x4F, 0xA3, 0x4F, 0xB5, + 0x4F, 0xC7, 0x4F, 0xD9, 0x4F, 0xEB, 0x4F, 0xFD, 0x4F, 0x00, 0x0F, 0x5F, 0x21, 0x5F, 0x33, 0x5F, + 0x46, 0x4F, 0x59, 0xAF, 0x69, 0x5F, 0x7B, 0x5F, 0x8D, 0x5F, 0x00, 0x9F, 0x5F, 0xB1, 0x5F, 0xC3, + 0x5F, 0xD5, 0x5F, 0xE7, 0x5F, 0xF9, 0x5F, 0x0B, 0x6F, 0x1D, 0x6F, 0x00, 0x2F, 0x6F, 0x41, 0xBF, + 0x54, 0x5F, 0x65, 0x6F, 0x77, 0x6F, 0x89, 0x6F, 0x9B, 0x6F, 0xAD, 0x6F, 0x00, 0xBF, 0x6F, 0xD1, + 0x6F, 0xE3, 0x6F, 0xF5, 0x6F, 0x07, 0x7F, 0x19, 0x7F, 0x2B, 0x7F, 0x3D, 0x7F, 0x00, 0x50, 0x6F, + 0x61, 0x7F, 0x73, 0x7F, 0x85, 0x7F, 0x97, 0x7F, 0xA9, 0x7F, 0xBB, 0x7F, 0xCD, 0x7F, 0x00, 0xDF, + 0x7F, 0xF1, 0x7F, 0x03, 0x8F, 0x15, 0x8F, 0x27, 0x8F, 0x39, 0x8F, 0x4C, 0x7F, 0x5D, 0x8F, 0x00, + 0x6F, 0x8F, 0x81, 0x8F, 0x93, 0x8F, 0xA5, 0x8F, 0xB7, 0x8F, 0xC9, 0x8F, 0xDB, 0x8F, 0xED, 0x8F, + 0x00, 0xFF, 0x8F, 0x11, 0x9F, 0x23, 0x9F, 0x35, 0x9F, 0x48, 0x8F, 0x5A, 0x8F, 0x6B, 0x9F, 0x7D, + 0x9F, 0x00, 0x8F, 0x9F, 0xA1, 0x9F, 0xB3, 0x9F, 0xC5, 0x9F, 0xD7, 0x9F, 0xE9, 0x9F, 0xFB, 0x9F, + 0x0D, 0xAF, 0x00, 0x1F, 0xAF, 0x31, 0xAF, 0x44, 0x9F, 0x56, 0x9F, 0x67, 0xAF, 0x79, 0xAF, 0x8B, + 0xAF, 0x9D, 0xAF, 0x00, 0xAF, 0xAF, 0xC1, 0xAF, 0xD3, 0xAF, 0xE5, 0xAF, 0xF7, 0xAF, 0x09, 0xBF, + 0x1B, 0xBF, 0x2D, 0xBF, 0x00, 0x40, 0xAF, 0x52, 0xAF, 0x63, 0xBF, 0x75, 0xBF, 0x87, 0xBF, 0x99, + 0xBF, 0xAB, 0xBF, 0xBD, 0xBF, 0x00, 0xCF, 0xBF, 0xE1, 0xBF, 0xF3, 0xBF, 0x05, 0xCF, 0x17, 0xCF, + 0x29, 0xCF, 0x3B, 0xCF, 0x4E, 0xBF, 0x00, 0x5F, 0xCF, 0x71, 0xCF, 0x83, 0xCF, 0x95, 0xCF, 0xA7, + 0xCF, 0xB9, 0xCF, 0xCB, 0xCF, 0xDD, 0xCF, 0x00, 0xEF, 0xCF, 0x01, 0xDF, 0x13, 0xDF, 0x25, 0xDF, + 0x37, 0xDF, 0x4A, 0xCF, 0x3E, 0xDF, 0x6D, 0xDF, 0x00, 0x7F, 0xDF, 0x91, 0xDF, 0xA3, 0xDF, 0xB5, + 0xDF, 0xC7, 0xDF, 0xD9, 0xDF, 0xEB, 0xDF, 0xFD, 0xDF, 0x00, 0x0F, 0xEF, 0x21, 0xEF, 0x33, 0xEF, + 0x46, 0xDF, 0x58, 0xDF, 0x69, 0xEF, 0x7B, 0xEF, 0x8D, 0xEF, 0x00, 0x9F, 0xEF, 0xB1, 0xEF, 0xC3, + 0xEF, 0xD5, 0xEF, 0xE7, 0xEF, 0xF9, 0xEF, 0x0B, 0xFF, 0x1D, 0xFF, 0x00, 0x2F, 0xFF, 0x42, 0xEF, + 0x54, 0xEF, 0x65, 0xFF, 0x77, 0xFF, 0x89, 0xFF, 0x9B, 0xFF, 0xAD, 0xFF, 0x00, 0xBF, 0xFF, 0xD1, + 0xFF, 0xE3, 0xFF, 0xF5, 0xFF, 0x07, 0x0F, 0x19, 0x0F, 0x2B, 0x0F, 0x3D, 0x0F, 0x00, 0x50, 0xFF, + 0x61, 0x0F, 0x73, 0x0F, 0x85, 0x0F, 0x97, 0x0F, 0xA9, 0x0F, 0xBB, 0x0F, 0xCD, 0x0F, 0x00, 0xDF, + 0x0F, 0xF1, 0x0F, 0x03, 0x1F, 0x15, 0x1F, 0x27, 0x1F, 0x39, 0x1F, 0x4C, 0x0F, 0x5D, 0x1F, 0x00, + 0x6F, 0x1F, 0x81, 0x1F, 0x93, 0x1F, 0xA5, 0x1F, 0xB7, 0x1F, 0xC9, 0x1F, 0xDB, 0x1F, 0xED, 0x1F, + 0x00, 0xFF, 0x1F, 0x11, 0x2F, 0x23, 0x2F, 0x35, 0x2F, 0x48, 0x1F, 0x5A, 0x1F, 0x6B, 0x2F, 0x7D, + 0x2F, 0x00, 0x8F, 0x2F, 0xA1, 0x2F, 0xB3, 0x2F, 0xC5, 0x2F, 0xD7, 0x2F, 0xE9, 0x2F, 0xFB, 0x2F, + 0x0D, 0x3F, 0x00, 0x1F, 0x3F, 0x31, 0x3F, 0x44, 0x2F, 0x57, 0x4F, 0x67, 0x3F, 0x79, 0x3F, 0x8B, + 0x3F, 0x9D, 0x3F, 0x00, 0xAF, 0x3F, 0xC1, 0x3F, 0xD3, 0x3F, 0xE5, 0x3F, 0xF7, 0x3F, 0x09, 0x4F, + 0x1B, 0x4F, 0x2D, 0x4F, 0x00, 0x3F, 0x5F, 0x52, 0x3F, 0x63, 0x4F, 0x75, 0x4F, 0x87, 0x4F, 0x99, + 0x4F, 0xAB, 0x4F, 0xBD, 0x4F, 0x00, 0xCF, 0x4F, 0xE1, 0x4F, 0xF3, 0x4F, 0x05, 0x5F, 0x17, 0x5F, + 0x29, 0x5F, 0x3B, 0x5F, 0x4E, 0x4F, 0x00, 0x5F, 0x5F, 0x71, 0x5F, 0x83, 0x5F, 0x95, 0x5F, 0xA7, + 0x5F, 0xB9, 0x5F, 0xCB, 0x5F, 0xDD, 0x5F, 0x00, 0xEF, 0x5F, 0x01, 0x6F, 0x13, 0x6F, 0x25, 0x6F, + 0x37, 0x6F, 0x4A, 0x5F, 0x5B, 0x6F, 0x6D, 0x6F, 0x00, 0x7F, 0x6F, 0x91, 0x6F, 0xA3, 0x6F, 0xB5, + 0x6F, 0xC7, 0x6F, 0xD9, 0x6F, 0xEB, 0x6F, 0xFD, 0x6F, 0x00, 0x0F, 0x7F, 0x21, 0x7F, 0x33, 0x7F, + 0x46, 0x6F, 0x58, 0x6F, 0x69, 0x7F, 0x7B, 0x7F, 0x8D, 0x7F, 0x00, 0x9F, 0x7F, 0xB1, 0x7F, 0xC3, + 0x7F, 0xD5, 0x7F, 0xE7, 0x7F, 0xF9, 0x7F, 0x0B, 0x8F, 0x1D, 0x8F, 0x00, 0x2F, 0x8F, 0x42, 0x7F, + 0x54, 0x7F, 0x65, 0x8F, 0x77, 0x8F, 0x89, 0x8F, 0x9B, 0x8F, 0xAD, 0x8F, 0x00, 0xBF, 0x8F, 0xD1, + 0x8F, 0xE3, 0x8F, 0xF5, 0x8F, 0x07, 0x9F, 0x19, 0x9F, 0x2B, 0x9F, 0x3D, 0x9F, 0x00, 0x50, 0x8F, + 0x61, 0x9F, 0x73, 0x9F, 0x85, 0x9F, 0x97, 0x9F, 0xA9, 0x9F, 0xBB, 0x9F, 0xCD, 0x9F, 0x00, 0xDF, + 0x9F, 0xF1, 0x9F, 0x03, 0xAF, 0x15, 0xAF, 0x27, 0xAF, 0x39, 0xAF, 0x4C, 0x9F, 0x5D, 0xAF, 0x00, + 0x6F, 0xAF, 0x81, 0xAF, 0x93, 0xAF, 0xA5, 0xAF, 0xB7, 0xAF, 0xC9, 0xAF, 0xDB, 0xAF, 0xED, 0xAF, + 0x00, 0xFF, 0xAF, 0x11, 0xBF, 0x23, 0xBF, 0x35, 0xBF, 0x48, 0xAF, 0x5A, 0xAF, 0x6B, 0xBF, 0x7D, + 0xBF, 0x00, 0x8F, 0xBF, 0xA1, 0xBF, 0xB3, 0xBF, 0xC5, 0xBF, 0xD7, 0xBF, 0xE9, 0xBF, 0xFB, 0xBF, + 0x0D, 0xCF, 0x00, 0x1F, 0xCF, 0x31, 0xCF, 0x44, 0xBF, 0x56, 0xBF, 0x67, 0xCF, 0x79, 0xCF, 0x8B, + 0xCF, 0x9D, 0xCF, 0x00, 0xAF, 0xCF, 0xC1, 0xCF, 0xD3, 0xCF, 0xE5, 0xCF, 0xF7, 0xCF, 0x09, 0xDF, + 0x1B, 0xDF, 0x2D, 0xDF, 0x00, 0x40, 0xCF, 0x52, 0xCF, 0x63, 0xDF, 0x75, 0xDF, 0x87, 0xDF, 0x99, + 0xDF, 0xAB, 0xDF, 0xBD, 0xDF, 0x00, 0xCF, 0xDF, 0xE1, 0xDF, 0xF3, 0xDF, 0x05, 0xEF, 0x17, 0xEF, + 0x29, 0xEF, 0x3B, 0xEF, 0x4E, 0xDF, 0x00, 0x5F, 0xEF, 0x71, 0xEF, 0x83, 0xEF, 0x95, 0xEF, 0xA7, + 0xEF, 0xB9, 0xEF, 0xCB, 0xEF, 0xDD, 0xEF, 0x00, 0xEF, 0xEF, 0x01, 0xFF, 0x13, 0xFF, 0x25, 0xFF, + 0x37, 0xFF, 0x4A, 0xEF, 0x5B, 0xFF, 0x6D, 0xFF, 0x00, 0x7F, 0xFF, 0x91, 0xFF, 0xA3, 0xFF, 0xB5, + 0xFF, 0xC7, 0xFF, 0xD9, 0xFF, 0xEB, 0xFF, 0xFD, 0xFF, 0x00, 0x0F, 0x0F, 0x21, 0x0F, 0x33, 0x0F, + 0x46, 0xFF, 0x58, 0xFF, 0x69, 0x0F, 0x7B, 0x0F, 0x8D, 0x0F, 0x00, 0x9F, 0x0F, 0xB1, 0x0F, 0xC3, + 0x0F, 0xD5, 0x0F, 0xE7, 0x0F, 0xF9, 0x0F, 0x0B, 0x1F, 0x1D, 0x1F, 0x00, 0x2F, 0x1F, 0x42, 0x0F, + 0x54, 0x0F, 0x65, 0x1F, 0x77, 0x1F, 0x89, 0x1F, 0x9B, 0x1F, 0xAD, 0x1F, 0x00, 0xBF, 0x1F, 0xD1, + 0x1F, 0xE3, 0x1F, 0xF5, 0x1F, 0x07, 0x2F, 0x19, 0x2F, 0x2B, 0x2F, 0x3D, 0x2F, 0x00, 0x50, 0x1F, + 0x61, 0x2F, 0x73, 0x2F, 0x85, 0x2F, 0x97, 0x2F, 0xA9, 0x2F, 0xBB, 0x2F, 0xCD, 0x2F, 0x80, 0xDF, + 0x2F, 0xF1, 0x2F, 0x03, 0x3F, 0x15, 0x3F, 0x27, 0x3F, 0x39, 0x3F, 0x4C, 0x2B, 0x10, 0x00, 0x3F, + 0x3F, 0x6C, 0x3F, 0x7E, 0x3F, 0x90, 0x3F, 0xA2, 0x3F, 0xB4, 0x3F, 0xC6, 0x3F, 0xD8, 0x3F, 0x40, + 0xEA, 0x3F, 0xFC, 0x3F, 0x0E, 0x4F, 0x20, 0x4F, 0x32, 0x4F, 0x45, 0x39, 0x01, 0x52, 0x3F, 0x00, + 0x63, 0x4F, 0x75, 0x4F, 0x87, 0x4F, 0x99, 0x4F, 0xAB, 0x4F, 0xBD, 0x4F, 0xCF, 0x4F, 0xE1, 0x4F, + 0x00, 0xF3, 0x4F, 0x05, 0x5F, 0x17, 0x5F, 0x29, 0x5F, 0x3B, 0x5F, 0x4E, 0x4F, 0x5F, 0x5F, 0x71, + 0x5F, 0x00, 0x83, 0x5F, 0x95, 0x5F, 0xA7, 0x5F, 0xB9, 0x5F, 0xCB, 0x5F, 0xDD, 0x5F, 0xEF, 0x5F, + 0x01, 0x6F, 0x00, 0x13, 0x6F, 0x25, 0x6F, 0x37, 0x6F, 0x4A, 0x5F, 0x5B, 0x6F, 0x6D, 0x6F, 0x7F, + 0x6F, 0x91, 0x6F, 0x00, 0xA3, 0x6F, 0xB5, 0x6F, 0xC7, 0x6F, 0xD9, 0x6F, 0xEB, 0x6F, 0xFD, 0x6F, + 0x0F, 0x7F, 0x21, 0x7F, 0x00, 0x33, 0x7F, 0x46, 0x6F, 0x58, 0x6F, 0x69, 0x7F, 0x7B, 0x7F, 0x8D, + 0x7F, 0x9F, 0x7F, 0xB1, 0x7F, 0x00, 0xC3, 0x7F, 0xD5, 0x7F, 0xE7, 0x7F, 0xF9, 0x7F, 0x0B, 0x8F, + 0x1D, 0x8F, 0x2F, 0x8F, 0x42, 0x7F, 0x00, 0x54, 0x7F, 0x65, 0x8F, 0x77, 0x8F, 0x89, 0x8F, 0x9B, + 0x8F, 0xAD, 0x8F, 0xBF, 0x8F, 0xD1, 0x8F, 0x00, 0xE3, 0x8F, 0xF5, 0x8F, 0x07, 0x9F, 0x19, 0x9F, + 0x2B, 0x9F, 0x3D, 0x9F, 0x50, 0x8F, 0x61, 0x9F, 0x00, 0x73, 0x9F, 0x85, 0x9F, 0x97, 0x9F, 0xA9, + 0x9F, 0xBB, 0x9F, 0xCD, 0x9F, 0xDF, 0x9F, 0xF1, 0x9F, 0x00, 0x03, 0xAF, 0x15, 0xAF, 0x27, 0xAF, + 0x39, 0xAF, 0x4C, 0x9F, 0x5D, 0xAF, 0x6F, 0xAF, 0x81, 0xAF, 0x00, 0x93, 0xAF, 0xA5, 0xAF, 0xB7, + 0xAF, 0xC9, 0xAF, 0xDB, 0xAF, 0xED, 0xAF, 0xFF, 0xAF, 0x11, 0xBF, 0x00, 0x23, 0xBF, 0x35, 0xBF, + 0x48, 0xAF, 0x5A, 0xAF, 0x6B, 0xBF, 0x7D, 0xBF, 0x8F, 0xBF, 0xA1, 0xBF, 0x00, 0xB3, 0xBF, 0xC5, + 0xBF, 0xD7, 0xBF, 0xE9, 0xBF, 0xFB, 0xBF, 0x0D, 0xCF, 0x1F, 0xCF, 0x31, 0xCF, 0x00, 0x44, 0xBF, + 0x56, 0xBF, 0x67, 0xCF, 0x79, 0xCF, 0x8B, 0xCF, 0x9D, 0xCF, 0xAF, 0xCF, 0xC1, 0xCF, 0x00, 0xD3, + 0xCF, 0xE5, 0xCF, 0xF7, 0xCF, 0x09, 0xDF, 0x1B, 0xDF, 0x2D, 0xDF, 0x40, 0xCF, 0x52, 0xCF, 0x00, + 0x63, 0xDF, 0x75, 0xDF, 0x87, 0xDF, 0x99, 0xDF, 0xAB, 0xDF, 0xBD, 0xDF, 0xCF, 0xDF, 0xE1, 0xDF, + 0x00, 0xF3, 0xDF, 0x05, 0xEF, 0x17, 0xEF, 0x29, 0xEF, 0x3B, 0xEF, 0x4E, 0xDF, 0x5F, 0xEF, 0x71, + 0xEF, 0x00, 0x83, 0xEF, 0x95, 0xEF, 0xA7, 0xEF, 0xB9, 0xEF, 0xCB, 0xEF, 0xDD, 0xEF, 0xEF, 0xEF, + 0x01, 0xFF, 0x00, 0x13, 0xFF, 0x25, 0xFF, 0x37, 0xFF, 0x4A, 0xEF, 0x5B, 0xFF, 0x6D, 0xFF, 0x7F, + 0xFF, 0x91, 0xFF, 0x00, 0xA3, 0xFF, 0xB5, 0xFF, 0xC7, 0xFF, 0xD9, 0xFF, 0xEB, 0xFF, 0xFD, 0xFF, + 0x0F, 0x0F, 0x21, 0x0F, 0x00, 0x33, 0x0F, 0x46, 0xFF, 0x58, 0xFF, 0x69, 0x0F, 0x7B, 0x0F, 0x8D, + 0x0F, 0x9F, 0x0F, 0xB1, 0x0F, 0x00, 0xC3, 0x0F, 0xD5, 0x0F, 0xE7, 0x0F, 0xF9, 0x0F, 0x0B, 0x1F, + 0x1D, 0x1F, 0x2F, 0x1F, 0x42, 0x0F, 0x00, 0x54, 0x0F, 0x65, 0x1F, 0x77, 0x1F, 0x89, 0x1F, 0x9B, + 0x1F, 0xAD, 0x1F, 0xBF, 0x1F, 0xD1, 0x1F, 0x00, 0xE3, 0x1F, 0xF5, 0x1F, 0x07, 0x2F, 0x19, 0x2F, + 0x2B, 0x2F, 0x3D, 0x2F, 0x50, 0x1F, 0x61, 0x2F, 0x00, 0x73, 0x2F, 0x85, 0x2F, 0x97, 0x2F, 0xA9, + 0x2F, 0xBB, 0x2F, 0xCD, 0x2F, 0xDF, 0x2F, 0xF1, 0x2F, 0x00, 0x03, 0x3F, 0x15, 0x3F, 0x27, 0x3F, + 0x39, 0x3F, 0x4C, 0x2F, 0x5D, 0x3F, 0x6F, 0x3F, 0x81, 0x3F, 0x00, 0x93, 0x3F, 0xA5, 0x3F, 0xB7, + 0x3F, 0xC9, 0x3F, 0xDB, 0x3F, 0xED, 0x3F, 0xFF, 0x3F, 0x11, 0x4F, 0x00, 0x23, 0x4F, 0x35, 0x4F, + 0x48, 0x3F, 0x5A, 0x3F, 0x6B, 0x4F, 0x7D, 0x4F, 0x8F, 0x4F, 0xA1, 0x4F, 0x00, 0xB3, 0x4F, 0xC5, + 0x4F, 0xD7, 0x4F, 0xE9, 0x4F, 0xFB, 0x4F, 0x0D, 0x5F, 0x1F, 0x5F, 0x31, 0x5F, 0x00, 0x44, 0x4F, + 0x56, 0x4F, 0x67, 0x5F, 0x79, 0x5F, 0x8B, 0x5F, 0x9D, 0x5F, 0xAF, 0x5F, 0xC1, 0x5F, 0x00, 0xD3, + 0x5F, 0xE5, 0x5F, 0xF7, 0x5F, 0x09, 0x6F, 0x1B, 0x6F, 0x2D, 0x6F, 0x40, 0x5F, 0x52, 0x5F, 0x00, + 0x63, 0x6F, 0x75, 0x6F, 0x87, 0x6F, 0x99, 0x6F, 0xAB, 0x6F, 0xBD, 0x6F, 0xCF, 0x6F, 0xE1, 0x6F, + 0x00, 0xF3, 0x6F, 0x05, 0x7F, 0x17, 0x7F, 0x29, 0x7F, 0x3B, 0x7F, 0x4E, 0x6F, 0x5F, 0x7F, 0x71, + 0x7F, 0x00, 0x83, 0x7F, 0x95, 0x7F, 0xA7, 0x7F, 0xB9, 0x7F, 0xCB, 0x7F, 0xDD, 0x7F, 0xEF, 0x7F, + 0x01, 0x8F, 0x00, 0x13, 0x8F, 0x25, 0x8F, 0x37, 0x8F, 0x4A, 0x7F, 0x5B, 0x8F, 0x6D, 0x8F, 0x7F, + 0x8F, 0x91, 0x8F, 0x00, 0xA3, 0x8F, 0xB5, 0x8F, 0xC7, 0x8F, 0xD9, 0x8F, 0xEB, 0x8F, 0xFD, 0x8F, + 0x0F, 0x9F, 0x21, 0x9F, 0x0C, 0x33, 0x9F, 0x46, 0x8F, 0x11, 0x11, 0x3F, 0x9F, 0x6B, 0x9F, 0x7D, + 0x9F, 0x8F, 0x9F, 0x00, 0xA1, 0x9F, 0xB3, 0x9F, 0xC5, 0x9F, 0xD7, 0x9F, 0xE9, 0x9F, 0xFB, 0x9F, + 0x0D, 0xAF, 0x1F, 0xAF, 0x00, 0x31, 0xAF, 0x43, 0x9B, 0x52, 0x9F, 0x63, 0xAF, 0x75, 0xAF, 0x87, + 0xAF, 0x99, 0xAF, 0xAB, 0xAF, 0x00, 0xBD, 0xAF, 0xCF, 0xAF, 0xE1, 0xAF, 0xF3, 0xAF, 0x05, 0xBF, + 0x17, 0xBF, 0x29, 0xBF, 0x3B, 0xBF, 0x00, 0x4E, 0xAF, 0x5F, 0xBF, 0x71, 0xBF, 0x83, 0xBF, 0x95, + 0xBF, 0xA7, 0xBF, 0xB9, 0xBF, 0xCB, 0xBF, 0x00, 0xDD, 0xBF, 0xEF, 0xBF, 0x01, 0xCF, 0x13, 0xCF, + 0x25, 0xCF, 0x37, 0xCF, 0x4A, 0xBF, 0x5B, 0xCF, 0x00, 0x6D, 0xCF, 0x7F, 0xCF, 0x91, 0xCF, 0xA3, + 0xCF, 0xB5, 0xCF, 0xC7, 0xCF, 0xD9, 0xCF, 0xEB, 0xCF, 0x00, 0xFD, 0xCF, 0x0F, 0xDF, 0x21, 0xDF, + 0x33, 0xDF, 0x46, 0xCF, 0x58, 0xCF, 0x69, 0xDF, 0x7B, 0xDF, 0x00, 0x8D, 0xDF, 0x9F, 0xDF, 0xB1, + 0xDF, 0xC3, 0xDF, 0xD5, 0xDF, 0xE7, 0xDF, 0xF9, 0xDF, 0x0B, 0xEF, 0x00, 0x1D, 0xEF, 0x2F, 0xEF, + 0x42, 0xDF, 0x54, 0xDF, 0x65, 0xEF, 0x77, 0xEF, 0x89, 0xEF, 0x9B, 0xEF, 0x00, 0xAD, 0xEF, 0xBF, + 0xEF, 0xD1, 0xEF, 0xE3, 0xEF, 0xF5, 0xEF, 0x07, 0xFF, 0x19, 0xFF, 0x2B, 0xFF, 0x00, 0x3D, 0xFF, + 0x50, 0xEF, 0x61, 0xFF, 0x73, 0xFF, 0x85, 0xFF, 0x97, 0xFF, 0xA9, 0xFF, 0xBB, 0xFF, 0x00, 0xCD, + 0xFF, 0xDF, 0xFF, 0xF1, 0xFF, 0x03, 0x0F, 0x15, 0x0F, 0x27, 0x0F, 0x39, 0x0F, 0x4C, 0xFF, 0x00, + 0x5D, 0x0F, 0x6F, 0x0F, 0x81, 0x0F, 0x93, 0x0F, 0xA5, 0x0F, 0xB7, 0x0F, 0xC9, 0x0F, 0xDB, 0x0F, + 0x00, 0xED, 0x0F, 0xFF, 0x0F, 0x11, 0x1F, 0x23, 0x1F, 0x35, 0x1F, 0x48, 0x0F, 0x40, 0x1F, 0x6B, + 0x1F, 0x00, 0x7D, 0x1F, 0x8F, 0x1F, 0xA1, 0x1F, 0xB3, 0x1F, 0xC5, 0x1F, 0xD7, 0x1F, 0xE9, 0x1F, + 0xFB, 0x1F, 0x00, 0x0D, 0x2F, 0x1F, 0x2F, 0x31, 0x2F, 0x44, 0x1F, 0x56, 0x1F, 0x67, 0x2F, 0x79, + 0x2F, 0x8B, 0x2F, 0x00, 0x9D, 0x2F, 0xAF, 0x2F, 0xC1, 0x2F, 0xD3, 0x2F, 0xE5, 0x2F, 0xF7, 0x2F, + 0x09, 0x3F, 0x1B, 0x3F, 0x00, 0x2D, 0x3F, 0x3F, 0x3F, 0x52, 0x2F, 0x63, 0x3F, 0x75, 0x3F, 0x87, + 0x3F, 0x99, 0x3F, 0xAB, 0x3F, 0x00, 0xBD, 0x3F, 0xCF, 0x3F, 0xE1, 0x3F, 0xF3, 0x3F, 0x05, 0x4F, + 0x17, 0x4F, 0x29, 0x4F, 0x3B, 0x4F, 0x00, 0x4E, 0x3F, 0x5F, 0x4F, 0x71, 0x4F, 0x83, 0x4F, 0x95, + 0x4F, 0xA7, 0x4F, 0xB9, 0x4F, 0xCB, 0x4F, 0x00, 0xDD, 0x4F, 0xEF, 0x4F, 0x01, 0x5F, 0x13, 0x5F, + 0x25, 0x5F, 0x37, 0x5F, 0x4A, 0x4F, 0x5B, 0x5F, 0x00, 0x6D, 0x5F, 0x7F, 0x5F, 0x91, 0x5F, 0xA3, + 0x5F, 0xB5, 0x5F, 0xC7, 0x5F, 0xD9, 0x5F, 0xEB, 0x5F, 0x00, 0xFD, 0x5F, 0x0F, 0x6F, 0x21, 0x6F, + 0x33, 0x6F, 0x46, 0x5F, 0x58, 0x5F, 0x69, 0x6F, 0x7B, 0x6F, 0x00, 0x8D, 0x6F, 0x9F, 0x6F, 0xB1, + 0x6F, 0xC3, 0x6F, 0xD5, 0x6F, 0xE7, 0x6F, 0xF9, 0x6F, 0x0B, 0x7F, 0x00, 0x1D, 0x7F, 0x2F, 0x7F, + 0x42, 0x6F, 0x54, 0x6F, 0x65, 0x7F, 0x77, 0x7F, 0x89, 0x7F, 0x9B, 0x7F, 0x00, 0xAD, 0x7F, 0xBF, + 0x7F, 0xD1, 0x7F, 0xE3, 0x7F, 0xF5, 0x7F, 0x07, 0x8F, 0x19, 0x8F, 0x2B, 0x8F, 0x00, 0x3D, 0x8F, + 0x50, 0x7F, 0x61, 0x8F, 0x73, 0x8F, 0x85, 0x8F, 0x97, 0x8F, 0xA9, 0x8F, 0xBB, 0x8F, 0x00, 0xCD, + 0x8F, 0xDF, 0x8F, 0xF1, 0x8F, 0x03, 0x9F, 0x15, 0x9F, 0x27, 0x9F, 0x39, 0x9F, 0x4C, 0x8F, 0x00, + 0x5D, 0x9F, 0x6F, 0x9F, 0x81, 0x9F, 0x93, 0x9F, 0xA5, 0x9F, 0xB7, 0x9F, 0xC9, 0x9F, 0xDB, 0x9F, + 0x00, 0xED, 0x9F, 0xFF, 0x9F, 0x11, 0xAF, 0x23, 0xAF, 0x35, 0xAF, 0x48, 0x9F, 0x40, 0xAF, 0x6B, + 0xAF, 0x00, 0x7D, 0xAF, 0x8F, 0xAF, 0xA1, 0xAF, 0xB3, 0xAF, 0xC5, 0xAF, 0xD7, 0xAF, 0xE9, 0xAF, + 0xFB, 0xAF, 0x00, 0x0D, 0xBF, 0x1F, 0xBF, 0x31, 0xBF, 0x44, 0xAF, 0x56, 0xAF, 0x67, 0xBF, 0x79, + 0xBF, 0x8B, 0xBF, 0x00, 0x9D, 0xBF, 0xAF, 0xBF, 0xC1, 0xBF, 0xD3, 0xBF, 0xE5, 0xBF, 0xF7, 0xBF, + 0x09, 0xCF, 0x1B, 0xCF, 0x00, 0x2D, 0xCF, 0x3F, 0xCF, 0x52, 0xBF, 0x63, 0xCF, 0x75, 0xCF, 0x87, + 0xCF, 0x99, 0xCF, 0xAB, 0xCF, 0x00, 0xBD, 0xCF, 0xCF, 0xCF, 0xE1, 0xCF, 0xF3, 0xCF, 0x05, 0xDF, + 0x17, 0xDF, 0x29, 0xDF, 0x3B, 0xDF, 0x00, 0x4E, 0xCF, 0x5F, 0xDF, 0x71, 0xDF, 0x83, 0xDF, 0x95, + 0xDF, 0xA7, 0xDF, 0xB9, 0xDF, 0xCB, 0xDF, 0x00, 0xDD, 0xDF, 0xEF, 0xDF, 0x01, 0xEF, 0x13, 0xEF, + 0x25, 0xEF, 0x37, 0xEF, 0x4A, 0xDF, 0x5B, 0xEF, 0x00, 0x6D, 0xEF, 0x7F, 0xEF, 0x91, 0xEF, 0xA3, + 0xEF, 0xB5, 0xEF, 0xC7, 0xEF, 0xD9, 0xEF, 0xEB, 0xEF, 0x00, 0xFD, 0xEF, 0x0F, 0xFF, 0x21, 0xFF, + 0x33, 0xFF, 0x46, 0xEF, 0x58, 0xEF, 0x69, 0xFF, 0x7B, 0xFF, 0x00, 0x8D, 0xFF, 0x9F, 0xFF, 0xB1, + 0xFF, 0xC3, 0xFF, 0xD5, 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, 0x0B, 0x0F, 0x00, 0x1D, 0x0F, 0x2F, 0x0F, + 0x42, 0xFF, 0x54, 0xFF, 0x65, 0x0F, 0x77, 0x0F, 0x89, 0x0F, 0x9B, 0x0F, 0x00, 0xAD, 0x0F, 0xBF, + 0x0F, 0xD1, 0x0F, 0xE3, 0x0F, 0xF5, 0x0F, 0x07, 0x1F, 0x19, 0x1F, 0x2B, 0x1F, 0x00, 0x3D, 0x1F, + 0x50, 0x0F, 0x61, 0x1F, 0x73, 0x1F, 0x85, 0x1F, 0x97, 0x1F, 0xA9, 0x1F, 0xBB, 0x1F, 0x00, 0xCD, + 0x1F, 0xDF, 0x1F, 0xF1, 0x1F, 0x03, 0x2F, 0x15, 0x2F, 0x27, 0x2F, 0x39, 0x2F, 0x4C, 0x1F, 0x00, + 0x5D, 0x2F, 0x6F, 0x2F, 0x81, 0x2F, 0x93, 0x2F, 0xA5, 0x2F, 0xB7, 0x2F, 0xC9, 0x2F, 0xDB, 0x2F, + 0x00, 0xED, 0x2F, 0xFF, 0x2F, 0x11, 0x3F, 0x23, 0x3F, 0x35, 0x3F, 0x48, 0x2F, 0x40, 0x3F, 0x6B, + 0x3F, 0x00, 0x7D, 0x3F, 0x8F, 0x3F, 0xA1, 0x3F, 0xB3, 0x3F, 0xC5, 0x3F, 0xD7, 0x3F, 0xE9, 0x3F, + 0xFB, 0x3F, 0x00, 0x0D, 0x4F, 0x1F, 0x4F, 0x31, 0x4F, 0x44, 0x3F, 0x56, 0x3F, 0x67, 0x4F, 0x79, + 0x4F, 0x8B, 0x4F, 0x00, 0x9D, 0x4F, 0xAF, 0x4F, 0xC1, 0x4F, 0xD3, 0x4F, 0xE5, 0x4F, 0xF7, 0x4F, + 0x09, 0x5F, 0x1B, 0x5F, 0x08, 0x2D, 0x5F, 0x3F, 0x5F, 0x53, 0x44, 0x10, 0x40, 0x5F, 0x6B, 0x5F, + 0x7D, 0x5F, 0x8F, 0x5F, 0x00, 0xA1, 0x5F, 0xB3, 0x5F, 0xC5, 0x5F, 0xD7, 0x5F, 0xE9, 0x5F, 0xFB, + 0x5F, 0x0D, 0x6F, 0x1F, 0x6F, 0x04, 0x31, 0x6F, 0x44, 0x5B, 0x01, 0x53, 0x5F, 0x64, 0x6F, 0x76, + 0x6F, 0x88, 0x6F, 0x9A, 0x6F, 0x00, 0xAC, 0x6F, 0xBE, 0x6F, 0xD0, 0x6F, 0xE2, 0x6F, 0xF4, 0x6F, + 0x06, 0x7F, 0x18, 0x7F, 0x2A, 0x7F, 0x00, 0x3C, 0x7F, 0x4F, 0x6F, 0x60, 0x7F, 0x72, 0x7F, 0x84, + 0x7F, 0x96, 0x7F, 0xA8, 0x7F, 0xBA, 0x7F, 0x00, 0xCC, 0x7F, 0xDE, 0x7F, 0xF0, 0x7F, 0x02, 0x8F, + 0x14, 0x8F, 0x26, 0x8F, 0x38, 0x8F, 0x4B, 0x7F, 0x00, 0x5C, 0x8F, 0x6E, 0x8F, 0x80, 0x8F, 0x92, + 0x8F, 0xA4, 0x8F, 0xB6, 0x8F, 0xC8, 0x8F, 0xDA, 0x8F, 0x00, 0xEC, 0x8F, 0xFE, 0x8F, 0x10, 0x9F, + 0x22, 0x9F, 0x34, 0x9F, 0x47, 0x8F, 0x59, 0x8F, 0x6A, 0x9F, 0x00, 0x7C, 0x9F, 0x8E, 0x9F, 0xA0, + 0x9F, 0xB2, 0x9F, 0xC4, 0x9F, 0xD6, 0x9F, 0xE8, 0x9F, 0xFA, 0x9F, 0x00, 0x0C, 0xAF, 0x1E, 0xAF, + 0x30, 0xAF, 0x43, 0x9F, 0x55, 0x9F, 0x66, 0xAF, 0x78, 0xAF, 0x8A, 0xAF, 0x00, 0x9C, 0xAF, 0xAE, + 0xAF, 0xC0, 0xAF, 0xD2, 0xAF, 0xE4, 0xAF, 0xF6, 0xAF, 0x08, 0xBF, 0x1A, 0xBF, 0x00, 0x2C, 0xBF, + 0x3E, 0xBF, 0x51, 0xAF, 0x62, 0xBF, 0x74, 0xBF, 0x86, 0xBF, 0x98, 0xBF, 0xAA, 0xBF, 0x00, 0xBC, + 0xBF, 0xCE, 0xBF, 0xE0, 0xBF, 0xF2, 0xBF, 0x04, 0xCF, 0x16, 0xCF, 0x28, 0xCF, 0x3A, 0xCF, 0x00, + 0x4D, 0xBF, 0x5E, 0xCF, 0x70, 0xCF, 0x82, 0xCF, 0x94, 0xCF, 0xA6, 0xCF, 0xB8, 0xCF, 0xCA, 0xCF, + 0x00, 0xDC, 0xCF, 0xEE, 0xCF, 0x00, 0xDF, 0x12, 0xDF, 0x24, 0xDF, 0x36, 0xDF, 0x49, 0xCF, 0x5A, + 0xDF, 0x00, 0x6C, 0xDF, 0x7E, 0xDF, 0x90, 0xDF, 0xA2, 0xDF, 0xB4, 0xDF, 0xC6, 0xDF, 0xD8, 0xDF, + 0xEA, 0xDF, 0x00, 0xFC, 0xDF, 0x0E, 0xEF, 0x20, 0xEF, 0x32, 0xEF, 0x45, 0xDF, 0x57, 0xDF, 0x68, + 0xEF, 0x7A, 0xEF, 0x00, 0x8C, 0xEF, 0x9E, 0xEF, 0xB0, 0xEF, 0xC2, 0xEF, 0xD4, 0xEF, 0xE6, 0xEF, + 0xF8, 0xEF, 0x0A, 0xFF, 0x00, 0x1C, 0xFF, 0x2E, 0xFF, 0x41, 0xEF, 0x53, 0xEF, 0x64, 0xFF, 0x76, + 0xFF, 0x88, 0xFF, 0x9A, 0xFF, 0x00, 0xAC, 0xFF, 0xBE, 0xFF, 0xD0, 0xFF, 0xE2, 0xFF, 0xF4, 0xFF, + 0x06, 0x0F, 0x18, 0x0F, 0x2A, 0x0F, 0x00, 0x3C, 0x0F, 0x4F, 0xFF, 0x60, 0x0F, 0x72, 0x0F, 0x84, + 0x0F, 0x96, 0x0F, 0xA8, 0x0F, 0xBA, 0x0F, 0x00, 0xCC, 0x0F, 0xDE, 0x0F, 0xF0, 0x0F, 0x02, 0x1F, + 0x14, 0x1F, 0x26, 0x1F, 0x38, 0x1F, 0x4B, 0x0F, 0x00, 0x5C, 0x1F, 0x6E, 0x1F, 0x80, 0x1F, 0x92, + 0x1F, 0xA4, 0x1F, 0xB6, 0x1F, 0xC8, 0x1F, 0xDA, 0x1F, 0x00, 0xEC, 0x1F, 0xFE, 0x1F, 0x10, 0x2F, + 0x22, 0x2F, 0x34, 0x2F, 0x47, 0x1F, 0x59, 0x1F, 0x6A, 0x2F, 0x00, 0x7C, 0x2F, 0x8E, 0x2F, 0xA0, + 0x2F, 0xB2, 0x2F, 0xC4, 0x2F, 0xD6, 0x2F, 0xE8, 0x2F, 0xFA, 0x2F, 0x00, 0x0C, 0x3F, 0x1E, 0x3F, + 0x30, 0x3F, 0x43, 0x2F, 0x55, 0x2F, 0x66, 0x3F, 0x78, 0x3F, 0x8A, 0x3F, 0x00, 0x9C, 0x3F, 0xAE, + 0x3F, 0xC0, 0x3F, 0xD2, 0x3F, 0xE4, 0x3F, 0xF6, 0x3F, 0x08, 0x4F, 0x1A, 0x4F, 0x00, 0x2C, 0x4F, + 0x3E, 0x4F, 0x51, 0x3F, 0x62, 0x4F, 0x74, 0x4F, 0x86, 0x4F, 0x98, 0x4F, 0xAA, 0x4F, 0x00, 0xBC, + 0x4F, 0xCE, 0x4F, 0xE0, 0x4F, 0xF2, 0x4F, 0x04, 0x5F, 0x16, 0x5F, 0x28, 0x5F, 0x3A, 0x5F, 0x00, + 0x4D, 0x4F, 0x5E, 0x5F, 0x70, 0x5F, 0x82, 0x5F, 0x94, 0x5F, 0xA6, 0x5F, 0xB8, 0x5F, 0xCA, 0x5F, + 0x00, 0xDC, 0x5F, 0xEE, 0x5F, 0x00, 0x6F, 0x12, 0x6F, 0x24, 0x6F, 0x36, 0x6F, 0x49, 0x5F, 0x5A, + 0x6F, 0x00, 0x6C, 0x6F, 0x7E, 0x6F, 0x90, 0x6F, 0xA2, 0x6F, 0xB4, 0x6F, 0xC6, 0x6F, 0xD8, 0x6F, + 0xEA, 0x6F, 0x00, 0xFC, 0x6F, 0x0E, 0x7F, 0x20, 0x7F, 0x32, 0x7F, 0x45, 0x6F, 0x57, 0x6F, 0x68, + 0x7F, 0x7A, 0x7F, 0x00, 0x8C, 0x7F, 0x9E, 0x7F, 0xB0, 0x7F, 0xC2, 0x7F, 0xD4, 0x7F, 0xE6, 0x7F, + 0xF8, 0x7F, 0x0A, 0x8F, 0x00, 0x1C, 0x8F, 0x2E, 0x8F, 0x41, 0x7F, 0x53, 0x7F, 0x64, 0x8F, 0x76, + 0x8F, 0x88, 0x8F, 0x9A, 0x8F, 0x00, 0xAC, 0x8F, 0xBE, 0x8F, 0xD0, 0x8F, 0xE2, 0x8F, 0xF4, 0x8F, + 0x06, 0x9F, 0x18, 0x9F, 0x2A, 0x9F, 0x00, 0x3C, 0x9F, 0x4F, 0x8F, 0x60, 0x9F, 0x72, 0x9F, 0x84, + 0x9F, 0x96, 0x9F, 0xA8, 0x9F, 0xBA, 0x9F, 0x00, 0xCC, 0x9F, 0xDE, 0x9F, 0xF0, 0x9F, 0x02, 0xAF, + 0x14, 0xAF, 0x26, 0xAF, 0x38, 0xAF, 0x4B, 0x9F, 0x00, 0x5C, 0xAF, 0x6E, 0xAF, 0x80, 0xAF, 0x92, + 0xAF, 0xA4, 0xAF, 0xB6, 0xAF, 0xC8, 0xAF, 0xDA, 0xAF, 0x00, 0xEC, 0xAF, 0xFE, 0xAF, 0x10, 0xBF, + 0x22, 0xBF, 0x34, 0xBF, 0x47, 0xAF, 0x59, 0xAF, 0x6A, 0xBF, 0x00, 0x7C, 0xBF, 0x8E, 0xBF, 0xA0, + 0xBF, 0xB2, 0xBF, 0xC4, 0xBF, 0xD6, 0xBF, 0xE8, 0xBF, 0xFA, 0xBF, 0x00, 0x0C, 0xCF, 0x1E, 0xCF, + 0x30, 0xCF, 0x43, 0xBF, 0x55, 0xBF, 0x66, 0xCF, 0x78, 0xCF, 0x8A, 0xCF, 0x00, 0x9C, 0xCF, 0xAE, + 0xCF, 0xC0, 0xCF, 0xD2, 0xCF, 0xE4, 0xCF, 0xF6, 0xCF, 0x08, 0xDF, 0x1A, 0xDF, 0x00, 0x2C, 0xDF, + 0x3E, 0xDF, 0x51, 0xCF, 0x62, 0xDF, 0x74, 0xDF, 0x86, 0xDF, 0x98, 0xDF, 0xAA, 0xDF, 0x00, 0xBC, + 0xDF, 0xCE, 0xDF, 0xE0, 0xDF, 0xF2, 0xDF, 0x04, 0xEF, 0x16, 0xEF, 0x28, 0xEF, 0x3A, 0xEF, 0x00, + 0x4D, 0xDF, 0x5E, 0xEF, 0x70, 0xEF, 0x82, 0xEF, 0x94, 0xEF, 0xA6, 0xEF, 0xB8, 0xEF, 0xCA, 0xEF, + 0x00, 0xDC, 0xEF, 0xEE, 0xEF, 0x00, 0xFF, 0x12, 0xFF, 0x24, 0xFF, 0x36, 0xFF, 0x49, 0xEF, 0x5A, + 0xFF, 0x00, 0x6C, 0xFF, 0x7E, 0xFF, 0x90, 0xFF, 0xA2, 0xFF, 0xB4, 0xFF, 0xC6, 0xFF, 0xD8, 0xFF, + 0xEA, 0xFF, 0x00, 0xFC, 0xFF, 0x0E, 0x0F, 0x20, 0x0F, 0x32, 0x0F, 0x45, 0xFF, 0x57, 0xFF, 0x68, + 0x0F, 0x7A, 0x0F, 0x00, 0x8C, 0x0F, 0x9E, 0x0F, 0xB0, 0x0F, 0xC2, 0x0F, 0xD4, 0x0F, 0xE6, 0x0F, + 0xF8, 0x0F, 0x0A, 0x1F, 0x00, 0x1C, 0x1F, 0x2E, 0x1F, 0x41, 0x0F, 0x53, 0x0F, 0x64, 0x1F, 0x76, + 0x1F, 0x88, 0x1F, 0x9A, 0x1F, 0x00, 0xAC, 0x1F, 0xBE, 0x1F, 0xD0, 0x1F, 0xE2, 0x1F, 0xF4, 0x1F, + 0x06, 0x2F, 0x18, 0x2F, 0x2A, 0x2F, 0x00, 0x3C, 0x2F, 0x4F, 0x1F, 0x60, 0x2F, 0x72, 0x2F, 0x84, + 0x2F, 0x96, 0x2F, 0xA8, 0x2F, 0xBA, 0x2F, 0x00, 0xCC, 0x2F, 0xDE, 0x2F, 0xF0, 0x2F, 0x02, 0x3F, + 0x14, 0x3F, 0x26, 0x3F, 0x38, 0x3F, 0x4B, 0x2F, 0x00, 0x5C, 0x3F, 0x6E, 0x3F, 0x80, 0x3F, 0x92, + 0x3F, 0xA4, 0x3F, 0xB6, 0x3F, 0xC8, 0x3F, 0xDA, 0x3F, 0x00, 0xEC, 0x3F, 0xFE, 0x3F, 0x10, 0x4F, + 0x22, 0x4F, 0x34, 0x4F, 0x47, 0x3F, 0x59, 0x3F, 0x6A, 0x4F, 0x00, 0x7C, 0x4F, 0x8E, 0x4F, 0xA0, + 0x4F, 0xB2, 0x4F, 0xC4, 0x4F, 0xD6, 0x4F, 0xE8, 0x4F, 0xFA, 0x4F, 0x00, 0x0C, 0x5F, 0x1E, 0x5F, + 0x30, 0x5F, 0x43, 0x4F, 0x55, 0x4F, 0x66, 0x5F, 0x78, 0x5F, 0x8A, 0x5F, 0x00, 0x9C, 0x5F, 0xAE, + 0x5F, 0xC0, 0x5F, 0xD2, 0x5F, 0xE4, 0x5F, 0xF6, 0x5F, 0x08, 0x6F, 0x1A, 0x6F, 0x00, 0x2C, 0x6F, + 0x3E, 0x6F, 0x51, 0x5F, 0x62, 0x6F, 0x74, 0x6F, 0x86, 0x6F, 0x98, 0x6F, 0xAA, 0x6F, 0x00, 0xBC, + 0x6F, 0xCE, 0x6F, 0xE0, 0x6F, 0xF2, 0x6F, 0x04, 0x7F, 0x16, 0x7F, 0x28, 0x7F, 0x3A, 0x7F, 0x00, + 0x4D, 0x6F, 0x5E, 0x7F, 0x70, 0x7F, 0x82, 0x7F, 0x94, 0x7F, 0xA6, 0x7F, 0xB8, 0x7F, 0xCA, 0x7F, + 0x00, 0xDC, 0x7F, 0xEE, 0x7F, 0x00, 0x8F, 0x12, 0x8F, 0x24, 0x8F, 0x36, 0x8F, 0x49, 0x7F, 0x5A, + 0x8F, 0x00, 0x6C, 0x8F, 0x7E, 0x8F, 0x90, 0x8F, 0xA2, 0x8F, 0xB4, 0x8F, 0xC6, 0x8F, 0xD8, 0x8F, + 0xEA, 0x8F, 0x00, 0xFC, 0x8F, 0x0E, 0x9F, 0x20, 0x9F, 0x32, 0x9F, 0x45, 0x8F, 0x57, 0x8F, 0x68, + 0x9F, 0x7A, 0x9F, 0x00, 0x8C, 0x9F, 0x9E, 0x9F, 0xB0, 0x9F, 0xC2, 0x9F, 0xD4, 0x9F, 0xE6, 0x9F, + 0xF8, 0x9F, 0x0A, 0xAF, 0x00, 0x1C, 0xAF, 0x2E, 0xAF, 0x41, 0x9F, 0x53, 0x9F, 0x64, 0xAF, 0x76, + 0xAF, 0x88, 0xAF, 0x9A, 0xAF, 0x00, 0xAC, 0xAF, 0xBE, 0xAF, 0xD0, 0xAF, 0xE2, 0xAF, 0xF4, 0xAF, + 0x06, 0xBF, 0x18, 0xBF, 0x2A, 0xBF, 0x00, 0x3C, 0xBF, 0x4F, 0xAF, 0x60, 0xBF, 0x72, 0xBF, 0x84, + 0xBF, 0x96, 0xBF, 0xA8, 0xBF, 0xBA, 0xBF, 0x00, 0xCC, 0xBF, 0xDE, 0xBF, 0xF0, 0xBF, 0x02, 0xCF, + 0x14, 0xCF, 0x26, 0xCF, 0x38, 0xCF, 0x4B, 0xBF, 0x00, 0x5C, 0xCF, 0x6E, 0xCF, 0x80, 0xCF, 0x92, + 0xCF, 0xA4, 0xCF, 0xB6, 0xCF, 0xC8, 0xCF, 0xDA, 0xCF, 0x00, 0xEC, 0xCF, 0xFE, 0xCF, 0x10, 0xDF, + 0x22, 0xDF, 0x34, 0xDF, 0x47, 0xCF, 0x59, 0xCF, 0x6A, 0xDF, 0x00, 0x7C, 0xDF, 0x8E, 0xDF, 0xA0, + 0xDF, 0xB2, 0xDF, 0xC4, 0xDF, 0xD6, 0xDF, 0xE8, 0xDF, 0xFA, 0xDF, 0x00, 0x0C, 0xEF, 0x1E, 0xEF, + 0x30, 0xEF, 0x43, 0xDF, 0x55, 0xDF, 0x66, 0xEF, 0x78, 0xEF, 0x8A, 0xEF, 0x00, 0x9C, 0xEF, 0xAE, + 0xEF, 0xC0, 0xEF, 0xD2, 0xEF, 0xE4, 0xEF, 0xF6, 0xEF, 0x08, 0xFF, 0x1A, 0xFF, 0x00, 0x2C, 0xFF, + 0x3E, 0xFF, 0x51, 0xEF, 0x62, 0xFF, 0x74, 0xFF, 0x86, 0xFF, 0x98, 0xFF, 0xAA, 0xFF, 0x00, 0xBC, + 0xFF, 0xCE, 0xFF, 0xE0, 0xFF, 0xF2, 0xFF, 0x04, 0x0F, 0x16, 0x0F, 0x28, 0x0F, 0x3A, 0x0F, 0x00, + 0x4D, 0xFF, 0x5E, 0x0F, 0x70, 0x0F, 0x82, 0x0F, 0x94, 0x0F, 0xA6, 0x0F, 0xB8, 0x0F, 0xCA, 0x0F, + 0x00, 0xDC, 0x0F, 0xEE, 0x0F, 0x00, 0x1F, 0x12, 0x1F, 0x24, 0x1F, 0x36, 0x1F, 0x49, 0x0D, 0x40, + 0x1F, 0x00, 0x6A, 0x1F, 0x7C, 0x1F, 0x8E, 0x1F, 0xA0, 0x1F, 0xB2, 0x1F, 0xC4, 0x1F, 0xD6, 0x1F, + 0xE8, 0x1F, 0x00, 0xFA, 0x1F, 0x0C, 0x2F, 0x1E, 0x2F, 0x30, 0x2F, 0x42, 0x1D, 0x53, 0x1F, 0x64, + 0x2F, 0x76, 0x2F, 0x00, 0x88, 0x2F, 0x9A, 0x2F, 0xAC, 0x2F, 0xBE, 0x2F, 0xD0, 0x2F, 0xE2, 0x2F, + 0xF4, 0x2F, 0x06, 0x3F, 0x00, 0x18, 0x3F, 0x2A, 0x3F, 0x3C, 0x3F, 0x4F, 0x2F, 0x60, 0x3F, 0x72, + 0x3F, 0x84, 0x3F, 0x96, 0x3F, 0x00, 0xA8, 0x3F, 0xBA, 0x3F, 0xCC, 0x3F, 0xDE, 0x3F, 0xF0, 0x3F, + 0x02, 0x4F, 0x14, 0x4F, 0x26, 0x4F, 0x00, 0x38, 0x4F, 0x4B, 0x3F, 0x5C, 0x4F, 0x6E, 0x4F, 0x80, + 0x4F, 0x92, 0x4F, 0xA4, 0x4F, 0xB6, 0x4F, 0x00, 0xC8, 0x4F, 0xDA, 0x4F, 0xEC, 0x4F, 0xFE, 0x4F, + 0x10, 0x5F, 0x22, 0x5F, 0x34, 0x5F, 0x47, 0x4F, 0x00, 0x41, 0x5F, 0x6A, 0x5F, 0x7C, 0x5F, 0x8E, + 0x5F, 0xA0, 0x5F, 0xB2, 0x5F, 0xC4, 0x5F, 0xD6, 0x5F, 0x00, 0xE8, 0x5F, 0xFA, 0x5F, 0x0C, 0x6F, + 0x1E, 0x6F, 0x30, 0x6F, 0x43, 0x5F, 0x55, 0x5F, 0x66, 0x6F, 0x00, 0x78, 0x6F, 0x8A, 0x6F, 0x9C, + 0x6F, 0xAE, 0x6F, 0xC0, 0x6F, 0xD2, 0x6F, 0xE4, 0x6F, 0xF6, 0x6F, 0x00, 0x08, 0x7F, 0x1A, 0x7F, + 0x2C, 0x7F, 0x3E, 0x7F, 0x51, 0x6F, 0x62, 0x7F, 0x74, 0x7F, 0x86, 0x7F, 0x00, 0x98, 0x7F, 0xAA, + 0x7F, 0xBC, 0x7F, 0xCE, 0x7F, 0xE0, 0x7F, 0xF2, 0x7F, 0x04, 0x8F, 0x16, 0x8F, 0x00, 0x28, 0x8F, + 0x3A, 0x8F, 0x4D, 0x7F, 0x5E, 0x8F, 0x70, 0x8F, 0x82, 0x8F, 0x94, 0x8F, 0xA6, 0x8F, 0x00, 0xB8, + 0x8F, 0xCA, 0x8F, 0xDC, 0x8F, 0xEE, 0x8F, 0x00, 0x9F, 0x12, 0x9F, 0x24, 0x9F, 0x36, 0x9F, 0x00, + 0x49, 0x8F, 0x5A, 0x9F, 0x6C, 0x9F, 0x7E, 0x9F, 0x90, 0x9F, 0xA2, 0x9F, 0xB4, 0x9F, 0xC6, 0x9F, + 0x00, 0xD8, 0x9F, 0xEA, 0x9F, 0xFC, 0x9F, 0x0E, 0xAF, 0x20, 0xAF, 0x32, 0xAF, 0x45, 0x9F, 0x57, + 0x9F, 0x00, 0x68, 0xAF, 0x7A, 0xAF, 0x8C, 0xAF, 0x9E, 0xAF, 0xB0, 0xAF, 0xC2, 0xAF, 0xD4, 0xAF, + 0xE6, 0xAF, 0x00, 0xF8, 0xAF, 0x0A, 0xBF, 0x1C, 0xBF, 0x2E, 0xBF, 0x40, 0xBF, 0x53, 0xAF, 0x64, + 0xBF, 0x76, 0xBF, 0x00, 0x88, 0xBF, 0x9A, 0xBF, 0xAC, 0xBF, 0xBE, 0xBF, 0xD0, 0xBF, 0xE2, 0xBF, + 0xF4, 0xBF, 0x06, 0xCF, 0x00, 0x18, 0xCF, 0x2A, 0xCF, 0x3C, 0xCF, 0x4F, 0xBF, 0x60, 0xCF, 0x72, + 0xCF, 0x84, 0xCF, 0x96, 0xCF, 0x00, 0xA8, 0xCF, 0xBA, 0xCF, 0xCC, 0xCF, 0xDE, 0xCF, 0xF0, 0xCF, + 0x02, 0xDF, 0x14, 0xDF, 0x26, 0xDF, 0x00, 0x38, 0xDF, 0x4B, 0xCF, 0x5C, 0xDF, 0x6E, 0xDF, 0x80, + 0xDF, 0x92, 0xDF, 0xA4, 0xDF, 0xB6, 0xDF, 0x00, 0xC8, 0xDF, 0xDA, 0xDF, 0xEC, 0xDF, 0xFE, 0xDF, + 0x10, 0xEF, 0x22, 0xEF, 0x34, 0xEF, 0x47, 0xDF, 0x00, 0x41, 0xEF, 0x6A, 0xEF, 0x7C, 0xEF, 0x8E, + 0xEF, 0xA0, 0xEF, 0xB2, 0xEF, 0xC4, 0xEF, 0xD6, 0xEF, 0x00, 0xE8, 0xEF, 0xFA, 0xEF, 0x0C, 0xFF, + 0x1E, 0xFF, 0x30, 0xFF, 0x43, 0xEF, 0x55, 0xEF, 0x66, 0xFF, 0x00, 0x78, 0xFF, 0x8A, 0xFF, 0x9C, + 0xFF, 0xAE, 0xFF, 0xC0, 0xFF, 0xD2, 0xFF, 0xE4, 0xFF, 0xF6, 0xFF, 0x00, 0x08, 0x0F, 0x1A, 0x0F, + 0x2C, 0x0F, 0x3E, 0x0F, 0x51, 0xFF, 0x62, 0x0F, 0x74, 0x0F, 0x86, 0x0F, 0x00, 0x98, 0x0F, 0xAA, + 0x0F, 0xBC, 0x0F, 0xCE, 0x0F, 0xE0, 0x0F, 0xF2, 0x0F, 0x04, 0x1F, 0x16, 0x1F, 0x00, 0x28, 0x1F, + 0x3A, 0x1F, 0x4D, 0x0F, 0x5E, 0x1F, 0x70, 0x1F, 0x82, 0x1F, 0x94, 0x1F, 0xA6, 0x1F, 0x00, 0xB8, + 0x1F, 0xCA, 0x1F, 0xDC, 0x1F, 0xEE, 0x1F, 0x00, 0x2F, 0x12, 0x2F, 0x24, 0x2F, 0x36, 0x2F, 0x00, + 0x49, 0x1F, 0x5A, 0x2F, 0x6C, 0x2F, 0x7E, 0x2F, 0x90, 0x2F, 0xA2, 0x2F, 0xB4, 0x2F, 0xC6, 0x2F, + 0x00, 0xD8, 0x2F, 0xEA, 0x2F, 0xFC, 0x2F, 0x0E, 0x3F, 0x20, 0x3F, 0x32, 0x3F, 0x45, 0x2F, 0x57, + 0x2F, 0x00, 0x68, 0x3F, 0x7A, 0x3F, 0x8C, 0x3F, 0x9E, 0x3F, 0xB0, 0x3F, 0xC2, 0x3F, 0xD4, 0x3F, + 0xE6, 0x3F, 0x00, 0xF8, 0x3F, 0x0A, 0x4F, 0x1C, 0x4F, 0x2E, 0x4F, 0x40, 0x4F, 0x53, 0x3F, 0x64, + 0x4F, 0x76, 0x4F, 0x00, 0x88, 0x4F, 0x9A, 0x4F, 0xAC, 0x4F, 0xBE, 0x4F, 0xD0, 0x4F, 0xE2, 0x4F, + 0xF4, 0x4F, 0x06, 0x5F, 0x00, 0x18, 0x5F, 0x2A, 0x5F, 0x3C, 0x5F, 0x4F, 0x4F, 0x60, 0x5F, 0x72, + 0x5F, 0x84, 0x5F, 0x96, 0x5F, 0x00, 0xA8, 0x5F, 0xBA, 0x5F, 0xCC, 0x5F, 0xDE, 0x5F, 0xF0, 0x5F, + 0x02, 0x6F, 0x14, 0x6F, 0x26, 0x6F, 0x00, 0x38, 0x6F, 0x4B, 0x5F, 0x5C, 0x6F, 0x6E, 0x6F, 0x80, + 0x6F, 0x92, 0x6F, 0xA4, 0x6F, 0xB6, 0x6F, 0x00, 0xC8, 0x6F, 0xDA, 0x6F, 0xEC, 0x6F, 0xFE, 0x6F, + 0x10, 0x7F, 0x22, 0x7F, 0x34, 0x7F, 0x47, 0x6F, 0x00, 0x41, 0x7F, 0x6A, 0x7F, 0x7C, 0x7F, 0x8E, + 0x7F, 0xA0, 0x7F, 0xB2, 0x7F, 0xC4, 0x7F, 0xD6, 0x7F, 0x00, 0xE8, 0x7F, 0xFA, 0x7F, 0x0C, 0x8F, + 0x1E, 0x8F, 0x30, 0x8F, 0x43, 0x7F, 0x55, 0x7F, 0x66, 0x8F, 0x00, 0x78, 0x8F, 0x8A, 0x8F, 0x9C, + 0x8F, 0xAE, 0x8F, 0xC0, 0x8F, 0xD2, 0x8F, 0xE4, 0x8F, 0xF6, 0x8F, 0x00, 0x08, 0x9F, 0x1A, 0x9F, + 0x2C, 0x9F, 0x3E, 0x9F, 0x51, 0x8F, 0x62, 0x9F, 0x74, 0x9F, 0x86, 0x9F, 0x00, 0x98, 0x9F, 0xAA, + 0x9F, 0xBC, 0x9F, 0xCE, 0x9F, 0xE0, 0x9F, 0xF2, 0x9F, 0x04, 0xAF, 0x16, 0xAF, 0x00, 0x28, 0xAF, + 0x3A, 0xAF, 0x4D, 0x9F, 0x5E, 0xAF, 0x70, 0xAF, 0x82, 0xAF, 0x94, 0xAF, 0xA6, 0xAF, 0x00, 0xB8, + 0xAF, 0xCA, 0xAF, 0xDC, 0xAF, 0xEE, 0xAF, 0x00, 0xBF, 0x12, 0xBF, 0x24, 0xBF, 0x36, 0xBF, 0x00, + 0x49, 0xAF, 0x5A, 0xBF, 0x6C, 0xBF, 0x7E, 0xBF, 0x90, 0xBF, 0xA2, 0xBF, 0xB4, 0xBF, 0xC6, 0xBF, + 0x00, 0xD8, 0xBF, 0xEA, 0xBF, 0xFC, 0xBF, 0x0E, 0xCF, 0x20, 0xCF, 0x32, 0xCF, 0x45, 0xBF, 0x57, + 0xBF, 0x00, 0x68, 0xCF, 0x7A, 0xCF, 0x8C, 0xCF, 0x9E, 0xCF, 0xB0, 0xCF, 0xC2, 0xCF, 0xD4, 0xCF, + 0xE6, 0xCF, 0x00, 0xF8, 0xCF, 0x0A, 0xDF, 0x1C, 0xDF, 0x2E, 0xDF, 0x40, 0xDF, 0x53, 0xCF, 0x64, + 0xDF, 0x76, 0xDF, 0x00, 0x88, 0xDF, 0x9A, 0xDF, 0xAC, 0xDF, 0xBE, 0xDF, 0xD0, 0xDF, 0xE2, 0xDF, + 0xF4, 0xDF, 0x06, 0xEF, 0x00, 0x18, 0xEF, 0x2A, 0xEF, 0x3C, 0xEF, 0x4F, 0xDF, 0x60, 0xEF, 0x72, + 0xEF, 0x84, 0xEF, 0x96, 0xEF, 0x00, 0xA8, 0xEF, 0xBA, 0xEF, 0xCC, 0xEF, 0xDE, 0xEF, 0xF0, 0xEF, + 0x02, 0xFF, 0x14, 0xFF, 0x26, 0xFF, 0x00, 0x38, 0xFF, 0x4B, 0xEF, 0x5C, 0xFF, 0x6E, 0xFF, 0x80, + 0xFF, 0x92, 0xFF, 0xA4, 0xFF, 0xB6, 0xFF, 0x00, 0xC8, 0xFF, 0xDA, 0xFF, 0xEC, 0xFF, 0xFE, 0xFF, + 0x10, 0x0F, 0x22, 0x0F, 0x34, 0x0F, 0x47, 0xFF, 0x00, 0x41, 0x0F, 0x6A, 0x0F, 0x7C, 0x0F, 0x8E, + 0x0F, 0xA0, 0x0F, 0xB2, 0x0F, 0xC4, 0x0F, 0xD6, 0x0F, 0x00, 0xE8, 0x0F, 0xFA, 0x0F, 0x0C, 0x1F, + 0x1E, 0x1F, 0x30, 0x1F, 0x43, 0x0F, 0x55, 0x0F, 0x66, 0x1F, 0x00, 0x78, 0x1F, 0x8A, 0x1F, 0x9C, + 0x1F, 0xAE, 0x1F, 0xC0, 0x1F, 0xD2, 0x1F, 0xE4, 0x1F, 0xF6, 0x1F, 0x00, 0x08, 0x2F, 0x1A, 0x2F, + 0x2C, 0x2F, 0x3E, 0x2F, 0x51, 0x1F, 0x62, 0x2F, 0x74, 0x2F, 0x86, 0x2F, 0x00, 0x98, 0x2F, 0xAA, + 0x2F, 0xBC, 0x2F, 0xCE, 0x2F, 0xE0, 0x2F, 0xF2, 0x2F, 0x04, 0x3F, 0x16, 0x3F, 0x00, 0x28, 0x3F, + 0x3A, 0x3F, 0x4D, 0x2F, 0x5E, 0x3F, 0x70, 0x3F, 0x82, 0x3F, 0x94, 0x3F, 0xA6, 0x3F, 0x00, 0xB8, + 0x3F, 0xCA, 0x3F, 0xDC, 0x3F, 0xEE, 0x3F, 0x00, 0x4F, 0x12, 0x4F, 0x24, 0x4F, 0x36, 0x4F, 0x00, + 0x49, 0x3F, 0x5A, 0x4F, 0x6C, 0x4F, 0x7E, 0x4F, 0x90, 0x4F, 0xA2, 0x4F, 0xB4, 0x4F, 0xC6, 0x4F, + 0x00, 0xD8, 0x4F, 0xEA, 0x4F, 0xFC, 0x4F, 0x0E, 0x5F, 0x20, 0x5F, 0x32, 0x5F, 0x45, 0x4F, 0x57, + 0x4F, 0x00, 0x68, 0x5F, 0x7A, 0x5F, 0x8C, 0x5F, 0x9E, 0x5F, 0xB0, 0x5F, 0xC2, 0x5F, 0xD4, 0x5F, + 0xE6, 0x5F, 0x00, 0xF8, 0x5F, 0x0A, 0x6F, 0x1C, 0x6F, 0x2E, 0x6F, 0x40, 0x6F, 0x53, 0x5F, 0x64, + 0x6F, 0x76, 0x6F, 0x00, 0x88, 0x6F, 0x9A, 0x6F, 0xAC, 0x6F, 0xBE, 0x6F, 0xD0, 0x6F, 0xE2, 0x6F, + 0xF4, 0x6F, 0x06, 0x7F, 0x00, 0x18, 0x7F, 0x2A, 0x7F, 0x3C, 0x7F, 0x4F, 0x6F, 0x60, 0x7F, 0x72, + 0x7F, 0x84, 0x7F, 0x96, 0x7F, 0x00, 0xA8, 0x7F, 0xBA, 0x7F, 0xCC, 0x7F, 0xDE, 0x7F, 0xF0, 0x7F, + 0x02, 0x8F, 0x14, 0x8F, 0x26, 0x8F, 0x00, 0x38, 0x8F, 0x4B, 0x7F, 0x5C, 0x8F, 0x6E, 0x8F, 0x80, + 0x8F, 0x92, 0x8F, 0xA4, 0x8F, 0xB6, 0x8F, 0x00, 0xC8, 0x8F, 0xDA, 0x8F, 0xEC, 0x8F, 0xFE, 0x8F, + 0x10, 0x9F, 0x22, 0x9F, 0x34, 0x9F, 0x47, 0x8F, 0x00, 0x41, 0x9F, 0x6A, 0x9F, 0x7C, 0x9F, 0x8E, + 0x9F, 0xA0, 0x9F, 0xB2, 0x9F, 0xC4, 0x9F, 0xD6, 0x9F, 0x00, 0xE8, 0x9F, 0xFA, 0x9F, 0x0C, 0xAF, + 0x1E, 0xAF, 0x30, 0xAF, 0x43, 0x9F, 0x55, 0x9F, 0x66, 0xAF, 0x00, 0x78, 0xAF, 0x8A, 0xAF, 0x9C, + 0xAF, 0xAE, 0xAF, 0xC0, 0xAF, 0xD2, 0xAF, 0xE4, 0xAF, 0xF6, 0xAF, 0x00, 0x08, 0xBF, 0x1A, 0xBF, + 0x2C, 0xBF, 0x3E, 0xBF, 0x51, 0xAF, 0x62, 0xBF, 0x74, 0xBF, 0x86, 0xBF, 0x00, 0x98, 0xBF, 0xAA, + 0xBF, 0xBC, 0xBF, 0xCE, 0xBF, 0xE0, 0xBF, 0xF2, 0xBF, 0x04, 0xCF, 0x16, 0xCF, 0x00, 0x28, 0xCF, + 0x3A, 0xCF, 0x4D, 0xBF, 0x5E, 0xCF, 0x70, 0xCF, 0x82, 0xCF, 0x94, 0xCF, 0xA6, 0xCF, 0x00, 0xB8, + 0xCF, 0xCA, 0xCF, 0xDC, 0xCF, 0xEE, 0xCF, 0x00, 0xDF, 0x12, 0xDF, 0x24, 0xDF, 0x36, 0xDF, 0x00, + 0x49, 0xCF, 0x5A, 0xDF, 0x6C, 0xDF, 0x7E, 0xDF, 0x90, 0xDF, 0xA2, 0xDF, 0xB4, 0xDF, 0xC6, 0xDF, + 0x00, 0xD8, 0xDF, 0xEA, 0xDF, 0xFC, 0xDF, 0x0E, 0xEF, 0x20, 0xEF, 0x32, 0xEF, 0x45, 0xDF, 0x57, + 0xDF, 0x00, 0x68, 0xEF, 0x7A, 0xEF, 0x8C, 0xEF, 0x9E, 0xEF, 0xB0, 0xEF, 0xC2, 0xEF, 0xD4, 0xEF, + 0xE6, 0xEF, 0x00, 0xF8, 0xEF, 0x0A, 0xFF, 0x1C, 0xFF, 0x2E, 0xFF, 0x40, 0xFF, 0x53, 0xEF, 0x64, + 0xFF, 0x76, 0xFF, 0x00, 0x88, 0xFF, 0x9A, 0xFF, 0xAC, 0xFF, 0xBE, 0xFF, 0xD0, 0xFF, 0xE2, 0xFF, + 0xF4, 0xFF, 0x06, 0x0F, 0x00, 0x18, 0x0F, 0x2A, 0x0F, 0x3C, 0x0F, 0x4F, 0xFF, 0x60, 0x0F, 0x72, + 0x0F, 0x84, 0x0F, 0x96, 0x0F, 0x00, 0xA8, 0x0F, 0xBA, 0x0F, 0xCC, 0x0F, 0xDE, 0x0F, 0xF0, 0x0F, + 0x02, 0x1F, 0x14, 0x1F, 0x26, 0x1F, 0x00, 0x38, 0x1F, 0x4B, 0x0F, 0x5C, 0x1F, 0x6E, 0x1F, 0x80, + 0x1F, 0x92, 0x1F, 0xA4, 0x1F, 0xB6, 0x1F, 0x00, 0xC8, 0x1F, 0xDA, 0x1F, 0xEC, 0x1F, 0xFE, 0x1F, + 0x10, 0x2F, 0x22, 0x2F, 0x34, 0x2F, 0x47, 0x1F, 0x00, 0x41, 0x2F, 0x6A, 0x2F, 0x7C, 0x2F, 0x8E, + 0x2F, 0xA0, 0x2F, 0xB2, 0x2F, 0xC4, 0x2F, 0xD6, 0x2F, 0x00, 0xE8, 0x2F, 0xFA, 0x2F, 0x0C, 0x3F, + 0x1E, 0x3F, 0x30, 0x3F, 0x43, 0x2F, 0x55, 0x2F, 0x66, 0x3F, 0x00, 0x78, 0x3F, 0x8A, 0x3F, 0x9C, + 0x3F, 0xAE, 0x3F, 0xC0, 0x3F, 0xD2, 0x3F, 0xE4, 0x3F, 0xF6, 0x3F, 0x00, 0x08, 0x4F, 0x1A, 0x4F, + 0x2C, 0x4F, 0x3E, 0x4F, 0x51, 0x3F, 0x62, 0x4F, 0x74, 0x4F, 0x86, 0x4F, 0x00, 0x98, 0x4F, 0xAA, + 0x4F, 0xBC, 0x4F, 0xCE, 0x4F, 0xE0, 0x4F, 0xF2, 0x4F, 0x04, 0x5F, 0x16, 0x5F, 0x00, 0x28, 0x5F, + 0x3A, 0x5F, 0x4D, 0x4F, 0x5E, 0x5F, 0x70, 0x5F, 0x82, 0x5F, 0x94, 0x5F, 0xA6, 0x5F, 0x00, 0xB8, + 0x5F, 0xCA, 0x5F, 0xDC, 0x5F, 0xEE, 0x5F, 0x00, 0x6F, 0x12, 0x6F, 0x24, 0x6F, 0x36, 0x6F, 0x00, + 0x49, 0x5F, 0x5A, 0x6F, 0x6C, 0x6F, 0x7E, 0x6F, 0x90, 0x6F, 0xA2, 0x6F, 0xB4, 0x6F, 0xC6, 0x6F, + 0x00, 0xD8, 0x6F, 0xEA, 0x6F, 0xFC, 0x6F, 0x0E, 0x7F, 0x20, 0x7F, 0x32, 0x7F, 0x45, 0x6F, 0x57, + 0x6F, 0x00, 0x68, 0x7F, 0x7A, 0x7F, 0x8C, 0x7F, 0x9E, 0x7F, 0xB0, 0x7F, 0xC2, 0x7F, 0xD4, 0x7F, + 0xE6, 0x7F, 0x00, 0xF8, 0x7F, 0x0A, 0x8F, 0x1C, 0x8F, 0x2E, 0x8F, 0x40, 0x8F, 0x53, 0x7F, 0x64, + 0x8F, 0x76, 0x8F, 0x00, 0x88, 0x8F, 0x9A, 0x8F, 0xAC, 0x8F, 0xBE, 0x8F, 0xD0, 0x8F, 0xE2, 0x8F, + 0xF4, 0x8F, 0x06, 0x9F, 0x00, 0x18, 0x9F, 0x2A, 0x9F, 0x3C, 0x9F, 0x4F, 0x8F, 0x60, 0x9F, 0x72, + 0x9F, 0x84, 0x9F, 0x96, 0x9F, 0x00, 0xA8, 0x9F, 0xBA, 0x9F, 0xCC, 0x9F, 0xDE, 0x9F, 0xF0, 0x9F, + 0x02, 0xAF, 0x14, 0xAF, 0x26, 0xAF, 0x00, 0x38, 0xAF, 0x4B, 0x9F, 0x5C, 0xAF, 0x6E, 0xAF, 0x80, + 0xAF, 0x92, 0xAF, 0xA4, 0xAF, 0xB6, 0xAF, 0x00, 0xC8, 0xAF, 0xDA, 0xAF, 0xEC, 0xAF, 0xFE, 0xAF, + 0x10, 0xBF, 0x22, 0xBF, 0x34, 0xBF, 0x47, 0xAF, 0x00, 0x41, 0xBF, 0x6A, 0xBF, 0x7C, 0xBF, 0x8E, + 0xBF, 0xA0, 0xBF, 0xB2, 0xBF, 0xC4, 0xBF, 0xD6, 0xBF, 0x00, 0xE8, 0xBF, 0xFA, 0xBF, 0x0C, 0xCF, + 0x1E, 0xCF, 0x30, 0xCF, 0x43, 0xBF, 0x55, 0xBF, 0x66, 0xCF, 0x00, 0x78, 0xCF, 0x8A, 0xCF, 0x9C, + 0xCF, 0xAE, 0xCF, 0xC0, 0xCF, 0xD2, 0xCF, 0xE4, 0xCF, 0xF6, 0xCF, 0x00, 0x08, 0xDF, 0x1A, 0xDF, + 0x2C, 0xDF, 0x3E, 0xDF, 0x51, 0xCF, 0x62, 0xDF, 0x74, 0xDF, 0x86, 0xDF, 0x00, 0x98, 0xDF, 0xAA, + 0xDF, 0xBC, 0xDF, 0xCE, 0xDF, 0xE0, 0xDF, 0xF2, 0xDF, 0x04, 0xEF, 0x16, 0xEF, 0x00, 0x28, 0xEF, + 0x3A, 0xEF, 0x4D, 0xDF, 0x5E, 0xEF, 0x70, 0xEF, 0x82, 0xEF, 0x94, 0xEF, 0xA6, 0xEF, 0x00, 0xB8, + 0xEF, 0xCA, 0xEF, 0xDC, 0xEF, 0xEE, 0xEF, 0x00, 0xFF, 0x12, 0xFF, 0x24, 0xFF, 0x36, 0xFF, 0x00, + 0x49, 0xEF, 0x5A, 0xFF, 0x6C, 0xFF, 0x7E, 0xFF, 0x90, 0xFF, 0xA2, 0xFF, 0xB4, 0xFF, 0xC6, 0xFF, + 0x00, 0xD8, 0xFF, 0xEA, 0xFF, 0xFC, 0xFF, 0x0E, 0x0F, 0x20, 0x0F, 0x32, 0x0F, 0x45, 0xFF, 0x57, + 0xFF, 0x00, 0x68, 0x0F, 0x7A, 0x0F, 0x8C, 0x0F, 0x9E, 0x0F, 0xB0, 0x0F, 0xC2, 0x0F, 0xD4, 0x0F, + 0xE6, 0x0F, 0x00, 0xF8, 0x0F, 0x0A, 0x1F, 0x1C, 0x1F, 0x2E, 0x1F, 0x40, 0x1F, 0x53, 0x0F, 0x64, + 0x1F, 0x76, 0x1F, 0x00, 0x88, 0x1F, 0x9A, 0x1F, 0xAC, 0x1F, 0xBE, 0x1F, 0xD0, 0x1F, 0xE2, 0x1F, + 0xF4, 0x1F, 0x06, 0x2F, 0x00, 0x18, 0x2F, 0x2A, 0x2F, 0x3C, 0x2F, 0x4F, 0x1F, 0x60, 0x2F, 0x72, + 0x2F, 0x84, 0x2F, 0x96, 0x2F, 0x00, 0xA8, 0x2F, 0xBA, 0x2F, 0xCC, 0x2F, 0xDE, 0x2F, 0xF0, 0x2F, + 0x02, 0x3F, 0x14, 0x3F, 0x26, 0x3F, 0x00, 0x38, 0x3F, 0x4B, 0x2F, 0x5C, 0x3F, 0x6E, 0x3F, 0x80, + 0x3F, 0x92, 0x3F, 0xA4, 0x3F, 0xB6, 0x3F, 0x00, 0xC8, 0x3F, 0xDA, 0x3F, 0xEC, 0x3F, 0xFE, 0x3F, + 0x10, 0x4F, 0x22, 0x4F, 0x34, 0x4F, 0x47, 0x3F, 0x00, 0x41, 0x4F, 0x6A, 0x4F, 0x7C, 0x4F, 0x8E, + 0x4F, 0xA0, 0x4F, 0xB2, 0x4F, 0xC4, 0x4F, 0xD6, 0x4F, 0x00, 0xE8, 0x4F, 0xFA, 0x4F, 0x0C, 0x5F, + 0x1E, 0x5F, 0x30, 0x5F, 0x43, 0x4F, 0x55, 0x4F, 0x66, 0x5F, 0x00, 0x78, 0x5F, 0x8A, 0x5F, 0x9C, + 0x5F, 0xAE, 0x5F, 0xC0, 0x5F, 0xD2, 0x5F, 0xE4, 0x5F, 0xF6, 0x5F, 0x00, 0x08, 0x6F, 0x1A, 0x6F, + 0x2C, 0x6F, 0x3E, 0x6F, 0x51, 0x5F, 0x62, 0x6F, 0x74, 0x6F, 0x86, 0x6F, 0x00, 0x98, 0x6F, 0xAA, + 0x6F, 0xBC, 0x6F, 0xCE, 0x6F, 0xE0, 0x6F, 0xF2, 0x6F, 0x04, 0x7F, 0x16, 0x7F, 0x00, 0x28, 0x7F, + 0x3A, 0x7F, 0x4D, 0x6F, 0x5E, 0x7F, 0x70, 0x7F, 0x82, 0x7F, 0x94, 0x7F, 0xA6, 0x7F, 0x00, 0xB8, + 0x7F, 0xCA, 0x7F, 0xDC, 0x7F, 0xEE, 0x7F, 0x00, 0x8F, 0x12, 0x8F, 0x24, 0x8F, 0x36, 0x8F, 0x00, + 0x49, 0x7F, 0x5A, 0x8F, 0x6C, 0x8F, 0x7E, 0x8F, 0x90, 0x8F, 0xA2, 0x8F, 0xB4, 0x8F, 0xC6, 0x8F, + 0x00, 0xD8, 0x8F, 0xEA, 0x8F, 0xFC, 0x8F, 0x0E, 0x9F, 0x20, 0x9F, 0x32, 0x9F, 0x45, 0x8F, 0x57, + 0x8F, 0x00, 0x68, 0x9F, 0x7A, 0x9F, 0x8C, 0x9F, 0x9E, 0x9F, 0xB0, 0x9F, 0xC2, 0x9F, 0xD4, 0x9F, + 0xE6, 0x9F, 0x00, 0xF8, 0x9F, 0x0A, 0xAF, 0x1C, 0xAF, 0x2E, 0xAF, 0x40, 0xAF, 0x53, 0x9F, 0x64, + 0xAF, 0x76, 0xAF, 0x00, 0x88, 0xAF, 0x9A, 0xAF, 0xAC, 0xAF, 0xBE, 0xAF, 0xD0, 0xAF, 0xE2, 0xAF, + 0xF4, 0xAF, 0x06, 0xBF, 0x00, 0x18, 0xBF, 0x2A, 0xBF, 0x3C, 0xBF, 0x4F, 0xAF, 0x60, 0xBF, 0x72, + 0xBF, 0x84, 0xBF, 0x96, 0xBF, 0x00, 0xA8, 0xBF, 0xBA, 0xBF, 0xCC, 0xBF, 0xDE, 0xBF, 0xF0, 0xBF, + 0x02, 0xCF, 0x14, 0xCF, 0x26, 0xCF, 0x00, 0x38, 0xCF, 0x4B, 0xBF, 0x5C, 0xCF, 0x6E, 0xCF, 0x80, + 0xCF, 0x92, 0xCF, 0xA4, 0xCF, 0xB6, 0xCF, 0x00, 0xC8, 0xCF, 0xDA, 0xCF, 0xEC, 0xCF, 0xFE, 0xCF, + 0x10, 0xDF, 0x22, 0xDF, 0x34, 0xDF, 0x47, 0xCF, 0x00, 0x41, 0xDF, 0x6A, 0xDF, 0x7C, 0xDF, 0x8E, + 0xDF, 0xA0, 0xDF, 0xB2, 0xDF, 0xC4, 0xDF, 0xD6, 0xDF, 0x00, 0xE8, 0xDF, 0xFA, 0xDF, 0x0C, 0xEF, + 0x1E, 0xEF, 0x30, 0xEF, 0x43, 0xDF, 0x55, 0xDF, 0x66, 0xEF, 0x00, 0x78, 0xEF, 0x8A, 0xEF, 0x9C, + 0xEF, 0xAE, 0xEF, 0xC0, 0xEF, 0xD2, 0xEF, 0xE4, 0xEF, 0xF6, 0xEF, 0x00, 0x08, 0xFF, 0x1A, 0xFF, + 0x2C, 0xFF, 0x3E, 0xFF, 0x51, 0xEF, 0x62, 0xFF, 0x74, 0xFF, 0x86, 0xFF, 0x00, 0x98, 0xFF, 0xAA, + 0xFF, 0xBC, 0xFF, 0xCE, 0xFF, 0xE0, 0xFF, 0xF2, 0xFF, 0x04, 0x0F, 0x16, 0x0F, 0x00, 0x28, 0x0F, + 0x3A, 0x0F, 0x4D, 0xFF, 0x5E, 0x0F, 0x70, 0x0F, 0x82, 0x0F, 0x94, 0x0F, 0xA6, 0x0F, 0x00, 0xB8, + 0x0F, 0xCA, 0x0F, 0xDC, 0x0F, 0xEE, 0x0F, 0x00, 0x1F, 0x12, 0x1F, 0x24, 0x1F, 0x36, 0x1F, 0x00, + 0x49, 0x0F, 0x5A, 0x1F, 0x6C, 0x1F, 0x7E, 0x1F, 0x90, 0x1F, 0xA2, 0x1F, 0xB4, 0x1F, 0xC6, 0x1F, + 0x00, 0xD8, 0x1F, 0xEA, 0x1F, 0xFC, 0x1F, 0x0E, 0x2F, 0x20, 0x2F, 0x32, 0x2F, 0x45, 0x1F, 0x57, + 0x1F, 0x00, 0x68, 0x2F, 0x7A, 0x2F, 0x8C, 0x2F, 0x9E, 0x2F, 0xB0, 0x2F, 0xC2, 0x2F, 0xD4, 0x2F, + 0xE6, 0x2F, 0x00, 0xF8, 0x2F, 0x0A, 0x3F, 0x1C, 0x3F, 0x2E, 0x3F, 0x40, 0x3F, 0x53, 0x2F, 0x64, + 0x3F, 0x76, 0x3F, 0x00, 0x88, 0x3F, 0x9A, 0x3F, 0xAC, 0x3F, 0xBE, 0x3F, 0xD0, 0x3F, 0xE2, 0x3F, + 0xF4, 0x3F, 0x06, 0x4F, 0x00, 0x18, 0x4F, 0x2A, 0x4F, 0x3C, 0x4F, 0x4F, 0x3F, 0x60, 0x4F, 0x72, + 0x4F, 0x84, 0x4F, 0x96, 0x4F, 0x00, 0xA8, 0x4F, 0xBA, 0x4F, 0xCC, 0x4F, 0xDE, 0x4F, 0xF0, 0x4F, + 0x02, 0x5F, 0x14, 0x5F, 0x26, 0x5F, 0x00, 0x38, 0x5F, 0x4B, 0x4F, 0x5C, 0x5F, 0x6E, 0x5F, 0x80, + 0x5F, 0x92, 0x5F, 0xA4, 0x5F, 0xB6, 0x5F, 0x00, 0xC8, 0x5F, 0xDA, 0x5F, 0xEC, 0x5F, 0xFE, 0x5F, + 0x10, 0x6F, 0x22, 0x6F, 0x34, 0x6F, 0x47, 0x5F, 0x00, 0x41, 0x6F, 0x6A, 0x6F, 0x7C, 0x6F, 0x8E, + 0x6F, 0xA0, 0x6F, 0xB2, 0x6F, 0xC4, 0x6F, 0xD6, 0x6F, 0x00, 0xE8, 0x6F, 0xFA, 0x6F, 0x0C, 0x7F, + 0x1E, 0x7F, 0x30, 0x7F, 0x43, 0x6F, 0x55, 0x6F, 0x66, 0x7F, 0x00, 0x78, 0x7F, 0x8A, 0x7F, 0x9C, + 0x7F, 0xAE, 0x7F, 0xC0, 0x7F, 0xD2, 0x7F, 0xE4, 0x7F, 0xF6, 0x7F, 0x00, 0x08, 0x8F, 0x1A, 0x8F, + 0x2C, 0x8F, 0x3E, 0x8F, 0x51, 0x7F, 0x62, 0x8F, 0x74, 0x8F, 0x86, 0x8F, 0x00, 0x98, 0x8F, 0xAA, + 0x8F, 0xBC, 0x8F, 0xCE, 0x8F, 0xE0, 0x8F, 0xF2, 0x8F, 0x04, 0x9F, 0x16, 0x9F, 0x00, 0x28, 0x9F, + 0x3A, 0x9F, 0x4D, 0x8F, 0x5E, 0x9F, 0x70, 0x9F, 0x82, 0x9F, 0x94, 0x9F, 0xA6, 0x9F, 0x00, 0xB8, + 0x9F, 0xCA, 0x9F, 0xDC, 0x9F, 0xEE, 0x9F, 0x00, 0xAF, 0x12, 0xAF, 0x24, 0xAF, 0x36, 0xAF, 0x00, + 0x49, 0x9F, 0x5A, 0xAF, 0x6C, 0xAF, 0x7E, 0xAF, 0x90, 0xAF, 0xA2, 0xAF, 0xB4, 0xAF, 0xC6, 0xAF, + 0x00, 0xD8, 0xAF, 0xEA, 0xAF, 0xFC, 0xAF, 0x0E, 0xBF, 0x20, 0xBF, 0x32, 0xBF, 0x45, 0xAF, 0x57, + 0xAF, 0x00, 0x68, 0xBF, 0x7A, 0xBF, 0x8C, 0xBF, 0x9E, 0xBF, 0xB0, 0xBF, 0xC2, 0xBF, 0xD4, 0xBF, + 0xE6, 0xBF, 0x00, 0xF8, 0xBF, 0x0A, 0xCF, 0x1C, 0xCF, 0x2E, 0xCF, 0x40, 0xCF, 0x53, 0xBF, 0x64, + 0xCF, 0x76, 0xCF, 0x00, 0x88, 0xCF, 0x9A, 0xCF, 0xAC, 0xCF, 0xBE, 0xCF, 0xD0, 0xCF, 0xE2, 0xCF, + 0xF4, 0xCF, 0x06, 0xDF, 0x00, 0x18, 0xDF, 0x2A, 0xDF, 0x3C, 0xDF, 0x4F, 0xCF, 0x60, 0xDF, 0x72, + 0xDF, 0x84, 0xDF, 0x96, 0xDF, 0x00, 0xA8, 0xDF, 0xBA, 0xDF, 0xCC, 0xDF, 0xDE, 0xDF, 0xF0, 0xDF, + 0x02, 0xEF, 0x14, 0xEF, 0x26, 0xEF, 0x00, 0x38, 0xEF, 0x4B, 0xDF, 0x5C, 0xEF, 0x6E, 0xEF, 0x80, + 0xEF, 0x92, 0xEF, 0xA4, 0xEF, 0xB6, 0xEF, 0x00, 0xC8, 0xEF, 0xDA, 0xEF, 0xEC, 0xEF, 0xFE, 0xEF, + 0x10, 0xFF, 0x22, 0xFF, 0x34, 0xFF, 0x47, 0xEF, 0x00, 0x41, 0xFF, 0x6A, 0xFF, 0x7C, 0xFF, 0x8E, + 0xFF, 0xA0, 0xFF, 0xB2, 0xFF, 0xC4, 0xFF, 0xD6, 0xFF, 0x00, 0xE8, 0xFF, 0xFA, 0xFF, 0x0C, 0x0F, + 0x1E, 0x0F, 0x30, 0x0F, 0x43, 0xFF, 0x55, 0xFF, 0x66, 0x0F, 0x00, 0x78, 0x0F, 0x8A, 0x0F, 0x9C, + 0x0F, 0xAE, 0x0F, 0xC0, 0x0F, 0xD2, 0x0F, 0xE4, 0x0F, 0xF6, 0x0F, 0x00, 0x08, 0x1F, 0x1A, 0x1F, + 0x2C, 0x1F, 0x3E, 0x1F, 0x51, 0x0F, 0x62, 0x1F, 0x74, 0x1F, 0x86, 0x1F, 0x00, 0x98, 0x1F, 0xAA, + 0x1F, 0xBC, 0x1F, 0xCE, 0x1F, 0xE0, 0x1F, 0xF2, 0x1F, 0x04, 0x2F, 0x16, 0x2F, 0x00, 0x28, 0x2F, + 0x3A, 0x2F, 0x4D, 0x1F, 0x5E, 0x2F, 0x70, 0x2F, 0x82, 0x2F, 0x94, 0x2F, 0xA6, 0x2F, 0x00, 0xB8, + 0x2F, 0xCA, 0x2F, 0xDC, 0x2F, 0xEE, 0x2F, 0x00, 0x3F, 0x12, 0x3F, 0x24, 0x3F, 0x36, 0x3F, 0x00, + 0x49, 0x2F, 0x5A, 0x3F, 0x6C, 0x3F, 0x7E, 0x3F, 0x90, 0x3F, 0xA2, 0x3F, 0xB4, 0x3F, 0xC6, 0x3F, + 0x00, 0xD8, 0x3F, 0xEA, 0x3F, 0xFC, 0x3F, 0x0E, 0x4F, 0x20, 0x4F, 0x32, 0x4F, 0x45, 0x3F, 0x57, + 0x3F, 0x00, 0x68, 0x4F, 0x7A, 0x4F, 0x8C, 0x4F, 0x9E, 0x4F, 0xB0, 0x4F, 0xC2, 0x4F, 0xD4, 0x4F, + 0xE6, 0x4F, 0x00, 0xF8, 0x4F, 0x0A, 0x5F, 0x1C, 0x5F, 0x2E, 0x5F, 0x40, 0x5F, 0x53, 0x4F, 0x64, + 0x5F, 0x76, 0x5F, 0x00, 0x88, 0x5F, 0x9A, 0x5F, 0xAC, 0x5F, 0xBE, 0x5F, 0xD0, 0x5F, 0xE2, 0x5F, + 0xF4, 0x5F, 0x06, 0x6F, 0x00, 0x18, 0x6F, 0x2A, 0x6F, 0x3C, 0x6F, 0x4F, 0x5F, 0x60, 0x6F, 0x72, + 0x6F, 0x84, 0x6F, 0x96, 0x6F, 0x00, 0xA8, 0x6F, 0xBA, 0x6F, 0xCC, 0x6F, 0xDE, 0x6F, 0xF0, 0x6F, + 0x02, 0x7F, 0x14, 0x7F, 0x26, 0x7F, 0x00, 0x38, 0x7F, 0x4B, 0x6F, 0x5C, 0x7F, 0x6E, 0x7F, 0x80, + 0x7F, 0x92, 0x7F, 0xA4, 0x7F, 0xB6, 0x7F, 0x00, 0xC8, 0x7F, 0xDA, 0x7F, 0xEC, 0x7F, 0xFE, 0x7F, + 0x10, 0x8F, 0x22, 0x8F, 0x34, 0x8F, 0x47, 0x7F, 0x00, 0x41, 0x8F, 0x6A, 0x8F, 0x7C, 0x8F, 0x8E, + 0x8F, 0xA0, 0x8F, 0xB2, 0x8F, 0xC4, 0x8F, 0xD6, 0x8F, 0x00, 0xE8, 0x8F, 0xFA, 0x8F, 0x0C, 0x9F, + 0x1E, 0x9F, 0x30, 0x9F, 0x43, 0x8F, 0x55, 0x8F, 0x66, 0x9F, 0x00, 0x78, 0x9F, 0x8A, 0x9F, 0x9C, + 0x9F, 0xAE, 0x9F, 0xC0, 0x9F, 0xD2, 0x9F, 0xE4, 0x9F, 0xF6, 0x9F, 0x00, 0x08, 0xAF, 0x1A, 0xAF, + 0x2C, 0xAF, 0x3E, 0xAF, 0x51, 0x9F, 0x62, 0xAF, 0x74, 0xAF, 0x86, 0xAF, 0x00, 0x98, 0xAF, 0xAA, + 0xAF, 0xBC, 0xAF, 0xCE, 0xAF, 0xE0, 0xAF, 0xF2, 0xAF, 0x04, 0xBF, 0x16, 0xBF, 0x00, 0x28, 0xBF, + 0x3A, 0xBF, 0x4D, 0xAF, 0x5E, 0xBF, 0x70, 0xBF, 0x82, 0xBF, 0x94, 0xBF, 0xA6, 0xBF, 0x00, 0xB8, + 0xBF, 0xCA, 0xBF, 0xDC, 0xBF, 0xEE, 0xBF, 0x00, 0xCF, 0x12, 0xCF, 0x24, 0xCF, 0x36, 0xCF, 0x00, + 0x49, 0xBF, 0x5A, 0xCF, 0x6C, 0xCF, 0x7E, 0xCF, 0x90, 0xCF, 0xA2, 0xCF, 0xB4, 0xCF, 0xC6, 0xCF, + 0x00, 0xD8, 0xCF, 0xEA, 0xCF, 0xFC, 0xCF, 0x0E, 0xDF, 0x20, 0xDF, 0x32, 0xDF, 0x45, 0xCF, 0x57, + 0xCF, 0x00, 0x68, 0xDF, 0x7A, 0xDF, 0x8C, 0xDF, 0x9E, 0xDF, 0xB0, 0xDF, 0xC2, 0xDF, 0xD4, 0xDF, + 0xE6, 0xDF, 0x00, 0xF8, 0xDF, 0x0A, 0xEF, 0x1C, 0xEF, 0x2E, 0xEF, 0x40, 0xEF, 0x53, 0xDF, 0x64, + 0xEF, 0x76, 0xEF, 0x00, 0x88, 0xEF, 0x9A, 0xEF, 0xAC, 0xEF, 0xBE, 0xEF, 0xD0, 0xEF, 0xE2, 0xEF, + 0xF4, 0xEF, 0x06, 0xFF, 0x00, 0x18, 0xFF, 0x2A, 0xFF, 0x3C, 0xFF, 0x4F, 0xEF, 0x60, 0xFF, 0x72, + 0xFF, 0x84, 0xFF, 0x96, 0xFF, 0x00, 0xA8, 0xFF, 0xBA, 0xFF, 0xCC, 0xFF, 0xDE, 0xFF, 0xF0, 0xFF, + 0x02, 0x0F, 0x14, 0x0F, 0x26, 0x0F, 0x00, 0x38, 0x0F, 0x4B, 0xFF, 0x5C, 0x0F, 0x6E, 0x0F, 0x80, + 0x0F, 0x92, 0x0F, 0xA4, 0x0F, 0xB6, 0x0F, 0x00, 0xC8, 0x0F, 0xDA, 0x0F, 0xEC, 0x0F, 0xFE, 0x0F, + 0x10, 0x1F, 0x22, 0x1F, 0x34, 0x1F, 0x47, 0x0F, 0x00, 0x41, 0x1F, 0x6A, 0x1F, 0x7C, 0x1F, 0x8E, + 0x1F, 0xA0, 0x1F, 0xB2, 0x1F, 0xC4, 0x1F, 0xD6, 0x1F, 0x00, 0xE8, 0x1F, 0xFA, 0x1F, 0x0C, 0x2F, + 0x1E, 0x2F, 0x30, 0x2F, 0x43, 0x1F, 0x55, 0x1F, 0x66, 0x2F, 0x00, 0x78, 0x2F, 0x8A, 0x2F, 0x9C, + 0x2F, 0xAE, 0x2F, 0xC0, 0x2F, 0xD2, 0x2F, 0xE4, 0x2F, 0xF6, 0x2F, 0x00, 0x08, 0x3F, 0x1A, 0x3F, + 0x2C, 0x3F, 0x3E, 0x3F, 0x51, 0x2F, 0x62, 0x3F, 0x74, 0x3F, 0x86, 0x3F, 0x00, 0x98, 0x3F, 0xAA, + 0x3F, 0xBC, 0x3F, 0xCE, 0x3F, 0xE0, 0x3F, 0xF2, 0x3F, 0x04, 0x4F, 0x16, 0x4F, 0x00, 0x28, 0x4F, + 0x3A, 0x4F, 0x4D, 0x3F, 0x5E, 0x4F, 0x70, 0x4F, 0x82, 0x4F, 0x94, 0x4F, 0xA6, 0x4F, 0x00, 0xB8, + 0x4F, 0xCA, 0x4F, 0xDC, 0x4F, 0xEE, 0x4F, 0x00, 0x5F, 0x12, 0x5F, 0x24, 0x5F, 0x36, 0x5F, 0x00, + 0x49, 0x4F, 0x5A, 0x5F, 0x6C, 0x5F, 0x7E, 0x5F, 0x90, 0x5F, 0xA2, 0x5F, 0xB4, 0x5F, 0xC6, 0x5F, + 0x00, 0xD8, 0x5F, 0xEA, 0x5F, 0xFC, 0x5F, 0x0E, 0x6F, 0x20, 0x6F, 0x32, 0x6F, 0x45, 0x5F, 0x57, + 0x5F, 0x00, 0x68, 0x6F, 0x7A, 0x6F, 0x8C, 0x6F, 0x9E, 0x6F, 0xB0, 0x6F, 0xC2, 0x6F, 0xD4, 0x6F, + 0xE6, 0x6F, 0x00, 0xF8, 0x6F, 0x0A, 0x7F, 0x1C, 0x7F, 0x2E, 0x7F, 0x40, 0x7F, 0x53, 0x6F, 0x64, + 0x7F, 0x76, 0x7F, 0x00, 0x88, 0x7F, 0x9A, 0x7F, 0xAC, 0x7F, 0xBE, 0x7F, 0xD0, 0x7F, 0xE2, 0x7F, + 0xF4, 0x7F, 0x06, 0x8F, 0x00, 0x18, 0x8F, 0x2A, 0x8F, 0x3C, 0x8F, 0x4F, 0x7F, 0x60, 0x8F, 0x72, + 0x8F, 0x84, 0x8F, 0x96, 0x8F, 0x00, 0xA8, 0x8F, 0xBA, 0x8F, 0xCC, 0x8F, 0xDE, 0x8F, 0xF0, 0x8F, + 0x02, 0x9F, 0x14, 0x9F, 0x26, 0x9F, 0x00, 0x38, 0x9F, 0x4B, 0x8F, 0x5C, 0x9F, 0x6E, 0x9F, 0x80, + 0x9F, 0x92, 0x9F, 0xA4, 0x9F, 0xB6, 0x9F, 0x00, 0xC8, 0x9F, 0xDA, 0x9F, 0xEC, 0x9F, 0xFE, 0x9F, + 0x10, 0xAF, 0x22, 0xAF, 0x34, 0xAF, 0x47, 0x9F, 0x00, 0x41, 0xAF, 0x6A, 0xAF, 0x7C, 0xAF, 0x8E, + 0xAF, 0xA0, 0xAF, 0xB2, 0xAF, 0xC4, 0xAF, 0xD6, 0xAF, 0x00, 0xE8, 0xAF, 0xFA, 0xAF, 0x0C, 0xBF, + 0x1E, 0xBF, 0x30, 0xBF, 0x43, 0xAF, 0x55, 0xAF, 0x66, 0xBF, 0x00, 0x78, 0xBF, 0x8A, 0xBF, 0x9C, + 0xBF, 0xAE, 0xBF, 0xC0, 0xBF, 0xD2, 0xBF, 0xE4, 0xBF, 0xF6, 0xBF, 0x00, 0x08, 0xCF, 0x1A, 0xCF, + 0x2C, 0xCF, 0x3E, 0xCF, 0x51, 0xBF, 0x62, 0xCF, 0x74, 0xCF, 0x86, 0xCF, 0x00, 0x98, 0xCF, 0xAA, + 0xCF, 0xBC, 0xCF, 0xCE, 0xCF, 0xE0, 0xCF, 0xF2, 0xCF, 0x04, 0xDF, 0x16, 0xDF, 0x00, 0x28, 0xDF, + 0x3A, 0xDF, 0x4D, 0xCF, 0x5E, 0xDF, 0x70, 0xDF, 0x82, 0xDF, 0x94, 0xDF, 0xA6, 0xDF, 0x00, 0xB8, + 0xDF, 0xCA, 0xDF, 0xDC, 0xDF, 0xEE, 0xDF, 0x00, 0xEF, 0x12, 0xEF, 0x24, 0xEF, 0x36, 0xEF, 0x00, + 0x49, 0xDF, 0x5A, 0xEF, 0x6C, 0xEF, 0x7E, 0xEF, 0x90, 0xEF, 0xA2, 0xEF, 0xB4, 0xEF, 0xC6, 0xEF, + 0x80, 0xD8, 0xEF, 0xEA, 0xEF, 0xFC, 0xEF, 0x0E, 0xFF, 0x20, 0xFF, 0x32, 0xFF, 0x45, 0xEF, 0x11, + 0x03, 0x11, 0x10, 0x41, 0xFF, 0x6B, 0xFF, 0x7D, 0xFF, 0x8F, 0xFF, 0xA1, 0xFF, 0xB3, 0xFF, 0x00, + 0xC5, 0xFF, 0xD7, 0xFF, 0xE9, 0xFF, 0xFB, 0xFF, 0x0D, 0x0F, 0x1F, 0x0F, 0x31, 0x0F, 0x45, 0xFB, + 0x01, 0x01, 0x53, 0xFF, 0x64, 0x0F, 0x76, 0x0F, 0x88, 0x0F, 0x9A, 0x0F, 0xAC, 0x0F, 0xBE, 0x0F, + 0x00, 0xD0, 0x0F, 0xE2, 0x0F, 0xF4, 0x0F, 0x06, 0x1F, 0x18, 0x1F, 0x2A, 0x1F, 0x3C, 0x1F, 0x4F, + 0x0F, 0x00, 0x60, 0x1F, 0x72, 0x1F, 0x84, 0x1F, 0x96, 0x1F, 0xA8, 0x1F, 0xBA, 0x1F, 0xCC, 0x1F, + 0xDE, 0x1F, 0x00, 0xF0, 0x1F, 0x02, 0x2F, 0x14, 0x2F, 0x26, 0x2F, 0x38, 0x2F, 0x4B, 0x1F, 0x5C, + 0x2F, 0x6E, 0x2F, 0x00, 0x80, 0x2F, 0x92, 0x2F, 0xA4, 0x2F, 0xB6, 0x2F, 0xC8, 0x2F, 0xDA, 0x2F, + 0xEC, 0x2F, 0xFE, 0x2F, 0x00, 0x10, 0x3F, 0x22, 0x3F, 0x34, 0x3F, 0x47, 0x2F, 0x59, 0x2F, 0x6A, + 0x3F, 0x7C, 0x3F, 0x8E, 0x3F, 0x00, 0xA0, 0x3F, 0xB2, 0x3F, 0xC4, 0x3F, 0xD6, 0x3F, 0xE8, 0x3F, + 0xFA, 0x3F, 0x0C, 0x4F, 0x1E, 0x4F, 0x00, 0x30, 0x4F, 0x43, 0x3F, 0x55, 0x3F, 0x66, 0x4F, 0x78, + 0x4F, 0x8A, 0x4F, 0x9C, 0x4F, 0xAE, 0x4F, 0x00, 0xC0, 0x4F, 0xD2, 0x4F, 0xE4, 0x4F, 0xF6, 0x4F, + 0x08, 0x5F, 0x1A, 0x5F, 0x2C, 0x5F, 0x3E, 0x5F, 0x00, 0x51, 0x4F, 0x62, 0x5F, 0x74, 0x5F, 0x86, + 0x5F, 0x98, 0x5F, 0xAA, 0x5F, 0xBC, 0x5F, 0xCE, 0x5F, 0x00, 0xE0, 0x5F, 0xF2, 0x5F, 0x04, 0x6F, + 0x16, 0x6F, 0x28, 0x6F, 0x3A, 0x6F, 0x4D, 0x5F, 0x5E, 0x6F, 0x00, 0x70, 0x6F, 0x82, 0x6F, 0x94, + 0x6F, 0xA6, 0x6F, 0xB8, 0x6F, 0xCA, 0x6F, 0xDC, 0x6F, 0xEE, 0x6F, 0x00, 0x00, 0x7F, 0x12, 0x7F, + 0x24, 0x7F, 0x36, 0x7F, 0x49, 0x6F, 0x5A, 0x7F, 0x6C, 0x7F, 0x7E, 0x7F, 0x00, 0x90, 0x7F, 0xA2, + 0x7F, 0xB4, 0x7F, 0xC6, 0x7F, 0xD8, 0x7F, 0xEA, 0x7F, 0xFC, 0x7F, 0x0E, 0x8F, 0x00, 0x20, 0x8F, + 0x32, 0x8F, 0x45, 0x7F, 0x57, 0x7F, 0x68, 0x8F, 0x7A, 0x8F, 0x8C, 0x8F, 0x9E, 0x8F, 0x00, 0xB0, + 0x8F, 0xC2, 0x8F, 0xD4, 0x8F, 0xE6, 0x8F, 0xF8, 0x8F, 0x0A, 0x9F, 0x1C, 0x9F, 0x2E, 0x9F, 0x00, + 0x41, 0x8F, 0x53, 0x8F, 0x64, 0x9F, 0x76, 0x9F, 0x88, 0x9F, 0x9A, 0x9F, 0xAC, 0x9F, 0xBE, 0x9F, + 0x00, 0xD0, 0x9F, 0xE2, 0x9F, 0xF4, 0x9F, 0x06, 0xAF, 0x18, 0xAF, 0x2A, 0xAF, 0x3C, 0xAF, 0x4F, + 0x9F, 0x00, 0x60, 0xAF, 0x72, 0xAF, 0x84, 0xAF, 0x96, 0xAF, 0xA8, 0xAF, 0xBA, 0xAF, 0xCC, 0xAF, + 0xDE, 0xAF, 0x00, 0xF0, 0xAF, 0x02, 0xBF, 0x14, 0xBF, 0x26, 0xBF, 0x38, 0xBF, 0x4B, 0xAF, 0x5C, + 0xBF, 0x6E, 0xBF, 0x00, 0x80, 0xBF, 0x92, 0xBF, 0xA4, 0xBF, 0xB6, 0xBF, 0xC8, 0xBF, 0xDA, 0xBF, + 0xEC, 0xBF, 0xFE, 0xBF, 0x00, 0x10, 0xCF, 0x22, 0xCF, 0x34, 0xCF, 0x47, 0xBF, 0x59, 0xBF, 0x6A, + 0xCF, 0x7C, 0xCF, 0x8E, 0xCF, 0x00, 0xA0, 0xCF, 0xB2, 0xCF, 0xC4, 0xCF, 0xD6, 0xCF, 0xE8, 0xCF, + 0xFA, 0xCF, 0x0C, 0xDF, 0x1E, 0xDF, 0x00, 0x30, 0xDF, 0x43, 0xCF, 0x55, 0xCF, 0x66, 0xDF, 0x78, + 0xDF, 0x8A, 0xDF, 0x9C, 0xDF, 0xAE, 0xDF, 0x00, 0xC0, 0xDF, 0xD2, 0xDF, 0xE4, 0xDF, 0xF6, 0xDF, + 0x08, 0xEF, 0x1A, 0xEF, 0x2C, 0xEF, 0x3E, 0xEF, 0x00, 0x51, 0xDF, 0x62, 0xEF, 0x74, 0xEF, 0x86, + 0xEF, 0x98, 0xEF, 0xAA, 0xEF, 0xBC, 0xEF, 0xCE, 0xEF, 0x00, 0xE0, 0xEF, 0xF2, 0xEF, 0x04, 0xFF, + 0x16, 0xFF, 0x28, 0xFF, 0x3A, 0xFF, 0x4D, 0xEF, 0x5E, 0xFF, 0x00, 0x70, 0xFF, 0x82, 0xFF, 0x94, + 0xFF, 0xA6, 0xFF, 0xB8, 0xFF, 0xCA, 0xFF, 0xDC, 0xFF, 0xEE, 0xFF, 0x00, 0x00, 0x0F, 0x12, 0x0F, + 0x24, 0x0F, 0x36, 0x0F, 0x49, 0xFF, 0x5A, 0x0F, 0x6C, 0x0F, 0x7E, 0x0F, 0x00, 0x90, 0x0F, 0xA2, + 0x0F, 0xB4, 0x0F, 0xC6, 0x0F, 0xD8, 0x0F, 0xEA, 0x0F, 0xFC, 0x0F, 0x0E, 0x1F, 0x00, 0x20, 0x1F, + 0x32, 0x1F, 0x45, 0x0F, 0x57, 0x0F, 0x68, 0x1F, 0x7A, 0x1F, 0x8C, 0x1F, 0x9E, 0x1F, 0x00, 0xB0, + 0x1F, 0xC2, 0x1F, 0xD4, 0x1F, 0xE6, 0x1F, 0xF8, 0x1F, 0x0A, 0x2F, 0x1C, 0x2F, 0x2E, 0x2F, 0x00, + 0x41, 0x1F, 0x53, 0x1F, 0x64, 0x2F, 0x76, 0x2F, 0x88, 0x2F, 0x9A, 0x2F, 0xAC, 0x2F, 0xBE, 0x2F, + 0x00, 0xD0, 0x2F, 0xE2, 0x2F, 0xF4, 0x2F, 0x06, 0x3F, 0x18, 0x3F, 0x2A, 0x3F, 0x3C, 0x3F, 0x4F, + 0x2F, 0x00, 0x60, 0x3F, 0x72, 0x3F, 0x84, 0x3F, 0x96, 0x3F, 0xA8, 0x3F, 0xBA, 0x3F, 0xCC, 0x3F, + 0xDE, 0x3F, 0x00, 0xF0, 0x3F, 0x02, 0x4F, 0x14, 0x4F, 0x26, 0x4F, 0x38, 0x4F, 0x4B, 0x3F, 0x5C, + 0x4F, 0x6E, 0x4F, 0x00, 0x80, 0x4F, 0x92, 0x4F, 0xA4, 0x4F, 0xB6, 0x4F, 0xC8, 0x4F, 0xDA, 0x4F, + 0xEC, 0x4F, 0xFE, 0x4F, 0x00, 0x10, 0x5F, 0x22, 0x5F, 0x34, 0x5F, 0x47, 0x4F, 0x59, 0x4F, 0x6A, + 0x5F, 0x7C, 0x5F, 0x8E, 0x5F, 0x00, 0xA0, 0x5F, 0xB2, 0x5F, 0xC4, 0x5F, 0xD6, 0x5F, 0xE8, 0x5F, + 0xFA, 0x5F, 0x0C, 0x6F, 0x1E, 0x6F, 0x00, 0x30, 0x6F, 0x43, 0x5F, 0x55, 0x5F, 0x66, 0x6F, 0x78, + 0x6F, 0x8A, 0x6F, 0x9C, 0x6F, 0xAE, 0x6F, 0x00, 0xC0, 0x6F, 0xD2, 0x6F, 0xE4, 0x6F, 0xF6, 0x6F, + 0x08, 0x7F, 0x1A, 0x7F, 0x2C, 0x7F, 0x3E, 0x7F, 0x00, 0x51, 0x6F, 0x62, 0x7F, 0x74, 0x7F, 0x86, + 0x7F, 0x98, 0x7F, 0xAA, 0x7F, 0xBC, 0x7F, 0xCE, 0x7F, 0x00, 0xE0, 0x7F, 0xF2, 0x7F, 0x04, 0x8F, + 0x16, 0x8F, 0x28, 0x8F, 0x3A, 0x8F, 0x4D, 0x7F, 0x5E, 0x8F, 0x00, 0x70, 0x8F, 0x82, 0x8F, 0x94, + 0x8F, 0xA6, 0x8F, 0xB8, 0x8F, 0xCA, 0x8F, 0xDC, 0x8F, 0xEE, 0x8F, 0x00, 0x00, 0x9F, 0x12, 0x9F, + 0x24, 0x9F, 0x36, 0x9F, 0x49, 0x8F, 0x5A, 0x9F, 0x6C, 0x9F, 0x7E, 0x9F, 0x00, 0x90, 0x9F, 0xA2, + 0x9F, 0xB4, 0x9F, 0xC6, 0x9F, 0xD8, 0x9F, 0xEA, 0x9F, 0xFC, 0x9F, 0x0E, 0xAF, 0x00, 0x20, 0xAF, + 0x32, 0xAF, 0x45, 0x9F, 0x57, 0x9F, 0x68, 0xAF, 0x7A, 0xAF, 0x8C, 0xAF, 0x9E, 0xAF, 0x00, 0xB0, + 0xAF, 0xC2, 0xAF, 0xD4, 0xAF, 0xE6, 0xAF, 0xF8, 0xAF, 0x0A, 0xBF, 0x1C, 0xBF, 0x2E, 0xBF, 0x00, + 0x41, 0xAF, 0x53, 0xAF, 0x64, 0xBF, 0x76, 0xBF, 0x88, 0xBF, 0x9A, 0xBF, 0xAC, 0xBF, 0xBE, 0xBF, + 0x00, 0xD0, 0xBF, 0xE2, 0xBF, 0xF4, 0xBF, 0x06, 0xCF, 0x18, 0xCF, 0x2A, 0xCF, 0x3C, 0xCF, 0x4F, + 0xBF, 0x00, 0x60, 0xCF, 0x72, 0xCF, 0x84, 0xCF, 0x96, 0xCF, 0xA8, 0xCF, 0xBA, 0xCF, 0xCC, 0xCF, + 0xDE, 0xCF, 0x00, 0xF0, 0xCF, 0x02, 0xDF, 0x14, 0xDF, 0x26, 0xDF, 0x38, 0xDF, 0x4B, 0xCF, 0x5C, + 0xDF, 0x6E, 0xDF, 0x00, 0x80, 0xDF, 0x92, 0xDF, 0xA4, 0xDF, 0xB6, 0xDF, 0xC8, 0xDF, 0xDA, 0xDF, + 0xEC, 0xDF, 0xFE, 0xDF, 0x00, 0x10, 0xEF, 0x22, 0xEF, 0x34, 0xEF, 0x47, 0xDF, 0x59, 0xDF, 0x6A, + 0xEF, 0x7C, 0xEF, 0x8E, 0xEF, 0x00, 0xA0, 0xEF, 0xB2, 0xEF, 0xC4, 0xEF, 0xD6, 0xEF, 0xE8, 0xEF, + 0xFA, 0xEF, 0x0C, 0xFF, 0x1E, 0xFF, 0x00, 0x30, 0xFF, 0x43, 0xEF, 0x55, 0xEF, 0x66, 0xFF, 0x78, + 0xFF, 0x8A, 0xFF, 0x9C, 0xFF, 0xAE, 0xFF, 0x00, 0xC0, 0xFF, 0xD2, 0xFF, 0xE4, 0xFF, 0xF6, 0xFF, + 0x08, 0x0F, 0x1A, 0x0F, 0x2C, 0x0F, 0x3E, 0x0F, 0x00, 0x51, 0xFF, 0x62, 0x0F, 0x74, 0x0F, 0x86, + 0x0F, 0x98, 0x0F, 0xAA, 0x0F, 0xBC, 0x0F, 0xCE, 0x0F, 0x00, 0xE0, 0x0F, 0xF2, 0x0F, 0x04, 0x1F, + 0x16, 0x1F, 0x28, 0x1F, 0x3A, 0x1F, 0x4D, 0x0F, 0x5E, 0x1F, 0x00, 0x70, 0x1F, 0x82, 0x1F, 0x94, + 0x1F, 0xA6, 0x1F, 0xB8, 0x1F, 0xCA, 0x1F, 0xDC, 0x1F, 0xEE, 0x1F, 0x00, 0x00, 0x2F, 0x12, 0x2F, + 0x24, 0x2F, 0x36, 0x2F, 0x49, 0x1F, 0x5A, 0x2F, 0x6C, 0x2F, 0x7E, 0x2F, 0x00, 0x90, 0x2F, 0xA2, + 0x2F, 0xB4, 0x2F, 0xC6, 0x2F, 0xD8, 0x2F, 0xEA, 0x2F, 0xFC, 0x2F, 0x0E, 0x3F, 0x00, 0x20, 0x3F, + 0x32, 0x3F, 0x45, 0x2F, 0x57, 0x2F, 0x68, 0x3F, 0x7A, 0x3F, 0x8C, 0x3F, 0x9E, 0x3F, 0x00, 0xB0, + 0x3F, 0xC2, 0x3F, 0xD4, 0x3F, 0xE6, 0x3F, 0xF8, 0x3F, 0x0A, 0x4F, 0x1C, 0x4F, 0x2E, 0x4F, 0x00, + 0x41, 0x3F, 0x53, 0x3F, 0x64, 0x4F, 0x76, 0x4F, 0x88, 0x4F, 0x9A, 0x4F, 0xAC, 0x4F, 0xBE, 0x4F, + 0x00, 0xD0, 0x4F, 0xE2, 0x4F, 0xF4, 0x4F, 0x06, 0x5F, 0x18, 0x5F, 0x2A, 0x5F, 0x3C, 0x5F, 0x4F, + 0x4F, 0x00, 0x60, 0x5F, 0x72, 0x5F, 0x84, 0x5F, 0x96, 0x5F, 0xA8, 0x5F, 0xBA, 0x5F, 0xCC, 0x5F, + 0xDE, 0x5F, 0x00, 0xF0, 0x5F, 0x02, 0x6F, 0x14, 0x6F, 0x26, 0x6F, 0x38, 0x6F, 0x4B, 0x5F, 0x5C, + 0x6F, 0x6E, 0x6F, 0x00, 0x80, 0x6F, 0x92, 0x6F, 0xA4, 0x6F, 0xB6, 0x6F, 0xC8, 0x6F, 0xDA, 0x6F, + 0xEC, 0x6F, 0xFE, 0x6F, 0x00, 0x10, 0x7F, 0x22, 0x7F, 0x34, 0x7F, 0x47, 0x6F, 0x59, 0x6F, 0x6A, + 0x7F, 0x7C, 0x7F, 0x8E, 0x7F, 0x00, 0xA0, 0x7F, 0xB2, 0x7F, 0xC4, 0x7F, 0xD6, 0x7F, 0xE8, 0x7F, + 0xFA, 0x7F, 0x0C, 0x8F, 0x1E, 0x8F, 0x00, 0x30, 0x8F, 0x43, 0x7F, 0x55, 0x7F, 0x66, 0x8F, 0x78, + 0x8F, 0x8A, 0x8F, 0x9C, 0x8F, 0xAE, 0x8F, 0x00, 0xC0, 0x8F, 0xD2, 0x8F, 0xE4, 0x8F, 0xF6, 0x8F, + 0x08, 0x9F, 0x1A, 0x9F, 0x2C, 0x9F, 0x3E, 0x9F, 0x00, 0x51, 0x8F, 0x62, 0x9F, 0x74, 0x9F, 0x86, + 0x9F, 0x98, 0x9F, 0xAA, 0x9F, 0xBC, 0x9F, 0xCE, 0x9F, 0x00, 0xE0, 0x9F, 0xF2, 0x9F, 0x04, 0xAF, + 0x16, 0xAF, 0x28, 0xAF, 0x3A, 0xAF, 0x4D, 0x9F, 0x5E, 0xAF, 0x00, 0x70, 0xAF, 0x82, 0xAF, 0x94, + 0xAF, 0xA6, 0xAF, 0xB8, 0xAF, 0xCA, 0xAF, 0xDC, 0xAF, 0xEE, 0xAF, 0x20, 0x00, 0xBF, 0x12, 0xBF, + 0x24, 0xBF, 0x36, 0xBF, 0x49, 0xAD, 0x11, 0x40, 0xBF, 0x6B, 0xBF, 0x00, 0x7D, 0xBF, 0x8F, 0xBF, + 0xA1, 0xBF, 0xB3, 0xBF, 0xC5, 0xBF, 0xD7, 0xBF, 0xE9, 0xBF, 0xFB, 0xBF, 0x00, 0x0D, 0xCF, 0x1F, + 0xCF, 0x31, 0xCF, 0x44, 0xBB, 0x53, 0xB4, 0x59, 0xBF, 0x6A, 0xCF, 0x7C, 0xCF, 0x00, 0x8E, 0xCF, + 0xA0, 0xCF, 0xB2, 0xCF, 0xC4, 0xCF, 0xD6, 0xCF, 0xE8, 0xCF, 0xFA, 0xCF, 0x0C, 0xDF, 0x00, 0x1E, + 0xDF, 0x30, 0xDF, 0x43, 0xCF, 0x55, 0xCF, 0x66, 0xDF, 0x78, 0xDF, 0x8A, 0xDF, 0x9C, 0xDF, 0x00, + 0xAE, 0xDF, 0xC0, 0xDF, 0xD2, 0xDF, 0xE4, 0xDF, 0xF6, 0xDF, 0x08, 0xEF, 0x1A, 0xEF, 0x2C, 0xEF, + 0x00, 0x3E, 0xEF, 0x51, 0xDF, 0x62, 0xEF, 0x74, 0xEF, 0x86, 0xEF, 0x98, 0xEF, 0xAA, 0xEF, 0xBC, + 0xEF, 0x00, 0xCE, 0xEF, 0xE0, 0xEF, 0xF2, 0xEF, 0x04, 0xFF, 0x16, 0xFF, 0x28, 0xFF, 0x3A, 0xFF, + 0x4D, 0xEF, 0x00, 0x5E, 0xFF, 0x70, 0xFF, 0x82, 0xFF, 0x94, 0xFF, 0xA6, 0xFF, 0xB8, 0xFF, 0xCA, + 0xFF, 0xDC, 0xFF, 0x00, 0xEE, 0xFF, 0x00, 0x0F, 0x12, 0x0F, 0x24, 0x0F, 0x36, 0x0F, 0x49, 0xFF, + 0x5A, 0x0F, 0x6C, 0x0F, 0x00, 0x7E, 0x0F, 0x90, 0x0F, 0xA2, 0x0F, 0xB4, 0x0F, 0xC6, 0x0F, 0xD8, + 0x0F, 0xEA, 0x0F, 0xFC, 0x0F, 0x00, 0x0E, 0x1F, 0x20, 0x1F, 0x32, 0x1F, 0x45, 0x0F, 0x57, 0x0F, + 0x68, 0x1F, 0x7A, 0x1F, 0x8C, 0x1F, 0x00, 0x9E, 0x1F, 0xB0, 0x1F, 0xC2, 0x1F, 0xD4, 0x1F, 0xE6, + 0x1F, 0xF8, 0x1F, 0x0A, 0x2F, 0x1C, 0x2F, 0x00, 0x2E, 0x2F, 0x41, 0x1F, 0x53, 0x1F, 0x64, 0x2F, + 0x76, 0x2F, 0x88, 0x2F, 0x9A, 0x2F, 0xAC, 0x2F, 0x00, 0xBE, 0x2F, 0xD0, 0x2F, 0xE2, 0x2F, 0xF4, + 0x2F, 0x06, 0x3F, 0x18, 0x3F, 0x2A, 0x3F, 0x3C, 0x3F, 0x00, 0x4F, 0x2F, 0x60, 0x3F, 0x72, 0x3F, + 0x84, 0x3F, 0x96, 0x3F, 0xA8, 0x3F, 0xBA, 0x3F, 0xCC, 0x3F, 0x00, 0xDE, 0x3F, 0xF0, 0x3F, 0x02, + 0x4F, 0x14, 0x4F, 0x26, 0x4F, 0x38, 0x4F, 0x4B, 0x3F, 0x5C, 0x4F, 0x00, 0x6E, 0x4F, 0x80, 0x4F, + 0x92, 0x4F, 0xA4, 0x4F, 0xB6, 0x4F, 0xC8, 0x4F, 0xDA, 0x4F, 0xEC, 0x4F, 0x00, 0xFE, 0x4F, 0x10, + 0x5F, 0x22, 0x5F, 0x34, 0x5F, 0x47, 0x4F, 0x59, 0x4F, 0x6A, 0x5F, 0x7C, 0x5F, 0x00, 0x8E, 0x5F, + 0xA0, 0x5F, 0xB2, 0x5F, 0xC4, 0x5F, 0xD6, 0x5F, 0xE8, 0x5F, 0xFA, 0x5F, 0x0C, 0x6F, 0x00, 0x1E, + 0x6F, 0x30, 0x6F, 0x43, 0x5F, 0x55, 0x5F, 0x66, 0x6F, 0x78, 0x6F, 0x8A, 0x6F, 0x9C, 0x6F, 0x00, + 0xAE, 0x6F, 0xC0, 0x6F, 0xD2, 0x6F, 0xE4, 0x6F, 0xF6, 0x6F, 0x08, 0x7F, 0x1A, 0x7F, 0x2C, 0x7F, + 0x00, 0x3E, 0x7F, 0x51, 0x6F, 0x62, 0x7F, 0x74, 0x7F, 0x86, 0x7F, 0x98, 0x7F, 0xAA, 0x7F, 0xBC, + 0x7F, 0x00, 0xCE, 0x7F, 0xE0, 0x7F, 0xF2, 0x7F, 0x04, 0x8F, 0x16, 0x8F, 0x28, 0x8F, 0x3A, 0x8F, + 0x4D, 0x7F, 0x00, 0x5E, 0x8F, 0x70, 0x8F, 0x82, 0x8F, 0x94, 0x8F, 0xA6, 0x8F, 0xB8, 0x8F, 0xCA, + 0x8F, 0xDC, 0x8F, 0x00, 0xEE, 0x8F, 0x00, 0x9F, 0x12, 0x9F, 0x24, 0x9F, 0x36, 0x9F, 0x49, 0x8F, + 0x5A, 0x9F, 0x6C, 0x9F, 0x00, 0x7E, 0x9F, 0x90, 0x9F, 0xA2, 0x9F, 0xB4, 0x9F, 0xC6, 0x9F, 0xD8, + 0x9F, 0xEA, 0x9F, 0xFC, 0x9F, 0x00, 0x0E, 0xAF, 0x20, 0xAF, 0x32, 0xAF, 0x45, 0x9F, 0x57, 0x9F, + 0x68, 0xAF, 0x7A, 0xAF, 0x8C, 0xAF, 0x00, 0x9E, 0xAF, 0xB0, 0xAF, 0xC2, 0xAF, 0xD4, 0xAF, 0xE6, + 0xAF, 0xF8, 0xAF, 0x0A, 0xBF, 0x1C, 0xBF, 0x00, 0x2E, 0xBF, 0x41, 0xAF, 0x53, 0xAF, 0x64, 0xBF, + 0x76, 0xBF, 0x88, 0xBF, 0x9A, 0xBF, 0xAC, 0xBF, 0x00, 0xBE, 0xBF, 0xD0, 0xBF, 0xE2, 0xBF, 0xF4, + 0xBF, 0x06, 0xCF, 0x18, 0xCF, 0x2A, 0xCF, 0x3C, 0xCF, 0x00, 0x4F, 0xBF, 0x60, 0xCF, 0x72, 0xCF, + 0x84, 0xCF, 0x96, 0xCF, 0xA8, 0xCF, 0xBA, 0xCF, 0xCC, 0xCF, 0x00, 0xDE, 0xCF, 0xF0, 0xCF, 0x02, + 0xDF, 0x14, 0xDF, 0x26, 0xDF, 0x38, 0xDF, 0x4B, 0xCF, 0x5C, 0xDF, 0x00, 0x6E, 0xDF, 0x80, 0xDF, + 0x92, 0xDF, 0xA4, 0xDF, 0xB6, 0xDF, 0xC8, 0xDF, 0xDA, 0xDF, 0xEC, 0xDF, 0x00, 0xFE, 0xDF, 0x10, + 0xEF, 0x22, 0xEF, 0x34, 0xEF, 0x47, 0xDF, 0x59, 0xDF, 0x6A, 0xEF, 0x7C, 0xEF, 0x00, 0x8E, 0xEF, + 0xA0, 0xEF, 0xB2, 0xEF, 0xC4, 0xEF, 0xD6, 0xEF, 0xE8, 0xEF, 0xFA, 0xEF, 0x0C, 0xFF, 0x00, 0x1E, + 0xFF, 0x30, 0xFF, 0x43, 0xEF, 0x55, 0xEF, 0x66, 0xFF, 0x78, 0xFF, 0x8A, 0xFF, 0x9C, 0xFF, 0x00, + 0xAE, 0xFF, 0xC0, 0xFF, 0xD2, 0xFF, 0xE4, 0xFF, 0xF6, 0xFF, 0x08, 0x0F, 0x1A, 0x0F, 0x2C, 0x0F, + 0x00, 0x3E, 0x0F, 0x51, 0xFF, 0x62, 0x0F, 0x74, 0x0F, 0x86, 0x0F, 0x98, 0x0F, 0xAA, 0x0F, 0xBC, + 0x0F, 0x00, 0xCE, 0x0F, 0xE0, 0x0F, 0xF2, 0x0F, 0x04, 0x1F, 0x16, 0x1F, 0x28, 0x1F, 0x3A, 0x1F, + 0x4D, 0x0F, 0x00, 0x5E, 0x1F, 0x70, 0x1F, 0x82, 0x1F, 0x94, 0x1F, 0xA6, 0x1F, 0xB8, 0x1F, 0xCA, + 0x1F, 0xDC, 0x1F, 0x00, 0xEE, 0x1F, 0x00, 0x2F, 0x12, 0x2F, 0x24, 0x2F, 0x36, 0x2F, 0x49, 0x1F, + 0x5A, 0x2F, 0x6C, 0x2F, 0x00, 0x7E, 0x2F, 0x90, 0x2F, 0xA2, 0x2F, 0xB4, 0x2F, 0xC6, 0x2F, 0xD8, + 0x2F, 0xEA, 0x2F, 0xFC, 0x2F, 0x00, 0x0E, 0x3F, 0x20, 0x3F, 0x32, 0x3F, 0x45, 0x2F, 0x57, 0x2F, + 0x68, 0x3F, 0x7A, 0x3F, 0x8C, 0x3F, 0x00, 0x9E, 0x3F, 0xB0, 0x3F, 0xC2, 0x3F, 0xD4, 0x3F, 0xE6, + 0x3F, 0xF8, 0x3F, 0x0A, 0x4F, 0x1C, 0x4F, 0x00, 0x2E, 0x4F, 0x41, 0x3F, 0x53, 0x3F, 0x64, 0x4F, + 0x76, 0x4F, 0x88, 0x4F, 0x9A, 0x4F, 0xAC, 0x4F, 0x00, 0xBE, 0x4F, 0xD0, 0x4F, 0xE2, 0x4F, 0xF4, + 0x4F, 0x06, 0x5F, 0x18, 0x5F, 0x2A, 0x5F, 0x3C, 0x5F, 0x00, 0x4F, 0x4F, 0x60, 0x5F, 0x72, 0x5F, + 0x84, 0x5F, 0x96, 0x5F, 0xA8, 0x5F, 0xBA, 0x5F, 0xCC, 0x5F, 0x00, 0xDE, 0x5F, 0xF0, 0x5F, 0x02, + 0x6F, 0x14, 0x6F, 0x26, 0x6F, 0x38, 0x6F, 0x4B, 0x5F, 0x5C, 0x6F, 0x00, 0x6E, 0x6F, 0x80, 0x6F, + 0x92, 0x6F, 0xA4, 0x6F, 0xB6, 0x6F, 0xC8, 0x6F, 0xDA, 0x6F, 0xEC, 0x6F, 0x60, 0xFE, 0x6F, 0x10, + 0x7F, 0x22, 0x7F, 0x34, 0x7F, 0x47, 0x6F, 0x11, 0x10, 0x40, 0x7F, 0x00, 0x6C, 0x7F, 0x7E, 0x7F, + 0x90, 0x7F, 0xA2, 0x7F, 0xB4, 0x7F, 0xC6, 0x7F, 0xD8, 0x7F, 0xEA, 0x7F, 0x20, 0xFC, 0x7F, 0x0E, + 0x8F, 0x20, 0x8F, 0x32, 0x8F, 0x44, 0x79, 0x01, 0x52, 0x7F, 0x63, 0x8F, 0x00, 0x75, 0x8F, 0x87, + 0x8F, 0x99, 0x8F, 0xAB, 0x8F, 0xBD, 0x8F, 0xCF, 0x8F, 0xE1, 0x8F, 0xF3, 0x8F, 0x00, 0x05, 0x9F, + 0x17, 0x9F, 0x29, 0x9F, 0x3B, 0x9F, 0x4E, 0x8F, 0x5F, 0x9F, 0x71, 0x9F, 0x83, 0x9F, 0x00, 0x95, + 0x9F, 0xA7, 0x9F, 0xB9, 0x9F, 0xCB, 0x9F, 0xDD, 0x9F, 0xEF, 0x9F, 0x01, 0xAF, 0x13, 0xAF, 0x00, + 0x25, 0xAF, 0x37, 0xAF, 0x4A, 0x9F, 0x5B, 0xAF, 0x6D, 0xAF, 0x7F, 0xAF, 0x91, 0xAF, 0xA3, 0xAF, + 0x00, 0xB5, 0xAF, 0xC7, 0xAF, 0xD9, 0xAF, 0xEB, 0xAF, 0xFD, 0xAF, 0x0F, 0xBF, 0x21, 0xBF, 0x33, + 0xBF, 0x00, 0x46, 0xAF, 0x58, 0xAF, 0x69, 0xBF, 0x7B, 0xBF, 0x8D, 0xBF, 0x9F, 0xBF, 0xB1, 0xBF, + 0xC3, 0xBF, 0x00, 0xD5, 0xBF, 0xE7, 0xBF, 0xF9, 0xBF, 0x0B, 0xCF, 0x1D, 0xCF, 0x2F, 0xCF, 0x42, + 0xBF, 0x54, 0xBF, 0x00, 0x65, 0xCF, 0x77, 0xCF, 0x89, 0xCF, 0x9B, 0xCF, 0xAD, 0xCF, 0xBF, 0xCF, + 0xD1, 0xCF, 0xE3, 0xCF, 0x00, 0xF5, 0xCF, 0x07, 0xDF, 0x19, 0xDF, 0x2B, 0xDF, 0x3D, 0xDF, 0x50, + 0xCF, 0x61, 0xDF, 0x73, 0xDF, 0x00, 0x85, 0xDF, 0x97, 0xDF, 0xA9, 0xDF, 0xBB, 0xDF, 0xCD, 0xDF, + 0xDF, 0xDF, 0xF1, 0xDF, 0x03, 0xEF, 0x00, 0x15, 0xEF, 0x27, 0xEF, 0x39, 0xEF, 0x4C, 0xDF, 0x5D, + 0xEF, 0x6F, 0xEF, 0x81, 0xEF, 0x93, 0xEF, 0x00, 0xA5, 0xEF, 0xB7, 0xEF, 0xC9, 0xEF, 0xDB, 0xEF, + 0xED, 0xEF, 0xFF, 0xEF, 0x11, 0xFF, 0x23, 0xFF, 0x00, 0x35, 0xFF, 0x48, 0xEF, 0x5A, 0xEF, 0x6B, + 0xFF, 0x7D, 0xFF, 0x8F, 0xFF, 0xA1, 0xFF, 0xB3, 0xFF, 0x00, 0xC5, 0xFF, 0xD7, 0xFF, 0xE9, 0xFF, + 0xFB, 0xFF, 0x0D, 0x0F, 0x1F, 0x0F, 0x31, 0x0F, 0x44, 0xFF, 0x00, 0x56, 0xFF, 0x67, 0x0F, 0x79, + 0x0F, 0x8B, 0x0F, 0x9D, 0x0F, 0xAF, 0x0F, 0xC1, 0x0F, 0xD3, 0x0F, 0x00, 0xE5, 0x0F, 0xF7, 0x0F, + 0x09, 0x1F, 0x1B, 0x1F, 0x2D, 0x1F, 0x40, 0x0F, 0x52, 0x0F, 0x63, 0x1F, 0x00, 0x75, 0x1F, 0x87, + 0x1F, 0x99, 0x1F, 0xAB, 0x1F, 0xBD, 0x1F, 0xCF, 0x1F, 0xE1, 0x1F, 0xF3, 0x1F, 0x00, 0x05, 0x2F, + 0x17, 0x2F, 0x29, 0x2F, 0x3B, 0x2F, 0x4E, 0x1F, 0x5F, 0x2F, 0x71, 0x2F, 0x83, 0x2F, 0x00, 0x95, + 0x2F, 0xA7, 0x2F, 0xB9, 0x2F, 0xCB, 0x2F, 0xDD, 0x2F, 0xEF, 0x2F, 0x01, 0x3F, 0x13, 0x3F, 0x00, + 0x25, 0x3F, 0x37, 0x3F, 0x4A, 0x2F, 0x5B, 0x3F, 0x6D, 0x3F, 0x7F, 0x3F, 0x91, 0x3F, 0xA3, 0x3F, + 0x00, 0xB5, 0x3F, 0xC7, 0x3F, 0xD9, 0x3F, 0xEB, 0x3F, 0xFD, 0x3F, 0x0F, 0x4F, 0x21, 0x4F, 0x33, + 0x4F, 0x00, 0x46, 0x3F, 0x58, 0x3F, 0x69, 0x4F, 0x7B, 0x4F, 0x8D, 0x4F, 0x9F, 0x4F, 0xB1, 0x4F, + 0xC3, 0x4F, 0x00, 0xD5, 0x4F, 0xE7, 0x4F, 0xF9, 0x4F, 0x0B, 0x5F, 0x1D, 0x5F, 0x2F, 0x5F, 0x42, + 0x4F, 0x54, 0x4F, 0x00, 0x65, 0x5F, 0x77, 0x5F, 0x89, 0x5F, 0x9B, 0x5F, 0xAD, 0x5F, 0xBF, 0x5F, + 0xD1, 0x5F, 0xE3, 0x5F, 0x00, 0xF5, 0x5F, 0x07, 0x6F, 0x19, 0x6F, 0x2B, 0x6F, 0x3D, 0x6F, 0x50, + 0x5F, 0x61, 0x6F, 0x73, 0x6F, 0x00, 0x85, 0x6F, 0x97, 0x6F, 0xA9, 0x6F, 0xBB, 0x6F, 0xCD, 0x6F, + 0xDF, 0x6F, 0xF1, 0x6F, 0x03, 0x7F, 0x00, 0x15, 0x7F, 0x27, 0x7F, 0x39, 0x7F, 0x4C, 0x6F, 0x5D, + 0x7F, 0x6F, 0x7F, 0x81, 0x7F, 0x93, 0x7F, 0x00, 0xA5, 0x7F, 0xB7, 0x7F, 0xC9, 0x7F, 0xDB, 0x7F, + 0xED, 0x7F, 0xFF, 0x7F, 0x11, 0x8F, 0x23, 0x8F, 0x00, 0x35, 0x8F, 0x48, 0x7F, 0x5A, 0x7F, 0x6B, + 0x8F, 0x7D, 0x8F, 0x8F, 0x8F, 0xA1, 0x8F, 0xB3, 0x8F, 0x00, 0xC5, 0x8F, 0xD7, 0x8F, 0xE9, 0x8F, + 0xFB, 0x8F, 0x0D, 0x9F, 0x1F, 0x9F, 0x31, 0x9F, 0x44, 0x8F, 0x00, 0x56, 0x8F, 0x67, 0x9F, 0x79, + 0x9F, 0x8B, 0x9F, 0x9D, 0x9F, 0xAF, 0x9F, 0xC1, 0x9F, 0xD3, 0x9F, 0x00, 0xE5, 0x9F, 0xF7, 0x9F, + 0x09, 0xAF, 0x1B, 0xAF, 0x2D, 0xAF, 0x40, 0x9F, 0x52, 0x9F, 0x63, 0xAF, 0x00, 0x75, 0xAF, 0x87, + 0xAF, 0x99, 0xAF, 0xAB, 0xAF, 0xBD, 0xAF, 0xCF, 0xAF, 0xE1, 0xAF, 0xF3, 0xAF, 0x00, 0x05, 0xBF, + 0x17, 0xBF, 0x29, 0xBF, 0x3B, 0xBF, 0x4E, 0xAF, 0x5F, 0xBF, 0x71, 0xBF, 0x83, 0xBF, 0x00, 0x95, + 0xBF, 0xA7, 0xBF, 0xB9, 0xBF, 0xCB, 0xBF, 0xDD, 0xBF, 0xEF, 0xBF, 0x01, 0xCF, 0x13, 0xCF, 0x00, + 0x25, 0xCF, 0x37, 0xCF, 0x4A, 0xBF, 0x5B, 0xCF, 0x6D, 0xCF, 0x7F, 0xCF, 0x91, 0xCF, 0xA3, 0xCF, + 0x00, 0xB5, 0xCF, 0xC7, 0xCF, 0xD9, 0xCF, 0xEB, 0xCF, 0xFD, 0xCF, 0x0F, 0xDF, 0x21, 0xDF, 0x33, + 0xDF, 0x00, 0x46, 0xCF, 0x57, 0xC0, 0x3F, 0xDF, 0x6C, 0xDF, 0x7E, 0xDF, 0x90, 0xDF, 0xA2, 0xDF, + 0xB4, 0xDF, 0x00, 0xC6, 0xDF, 0xD8, 0xDF, 0xEA, 0xDF, 0xFC, 0xDF, 0x0E, 0xEF, 0x20, 0xEF, 0x32, + 0xEF, 0x43, 0xD9, 0x00, 0x52, 0xD6, 0x5A, 0xDF, 0x6B, 0xEF, 0x7D, 0xEF, 0x8F, 0xEF, 0xA1, 0xEF, + 0xB3, 0xEF, 0xC5, 0xEF, 0x00, 0xD7, 0xEF, 0xE9, 0xEF, 0xFB, 0xEF, 0x0D, 0xFF, 0x1F, 0xFF, 0x31, + 0xFF, 0x44, 0xEF, 0x56, 0xEF, 0x00, 0x67, 0xFF, 0x79, 0xFF, 0x8B, 0xFF, 0x9D, 0xFF, 0xAF, 0xFF, + 0xC1, 0xFF, 0xD3, 0xFF, 0xE5, 0xFF, 0x00, 0xF7, 0xFF, 0x09, 0x0F, 0x1B, 0x0F, 0x2D, 0x0F, 0x40, + 0xFF, 0x52, 0xFF, 0x63, 0x0F, 0x75, 0x0F, 0x00, 0x87, 0x0F, 0x99, 0x0F, 0xAB, 0x0F, 0xBD, 0x0F, + 0xCF, 0x0F, 0xE1, 0x0F, 0xF3, 0x0F, 0x05, 0x1F, 0x00, 0x17, 0x1F, 0x29, 0x1F, 0x3B, 0x1F, 0x4E, + 0x0F, 0x5F, 0x1F, 0x71, 0x1F, 0x83, 0x1F, 0x95, 0x1F, 0x00, 0xA7, 0x1F, 0xB9, 0x1F, 0xCB, 0x1F, + 0xDD, 0x1F, 0xEF, 0x1F, 0x01, 0x2F, 0x13, 0x2F, 0x25, 0x2F, 0x00, 0x37, 0x2F, 0x4A, 0x1F, 0x5B, + 0x2F, 0x6D, 0x2F, 0x7F, 0x2F, 0x91, 0x2F, 0xA3, 0x2F, 0xB5, 0x2F, 0x00, 0xC7, 0x2F, 0xD9, 0x2F, + 0xEB, 0x2F, 0xFD, 0x2F, 0x0F, 0x3F, 0x21, 0x3F, 0x33, 0x3F, 0x46, 0x2F, 0x00, 0x58, 0x2F, 0x69, + 0x3F, 0x7B, 0x3F, 0x8D, 0x3F, 0x9F, 0x3F, 0xB1, 0x3F, 0xC3, 0x3F, 0xD5, 0x3F, 0x00, 0xE7, 0x3F, + 0xF9, 0x3F, 0x0B, 0x4F, 0x1D, 0x4F, 0x2F, 0x4F, 0x42, 0x3F, 0x54, 0x3F, 0x65, 0x4F, 0x00, 0x77, + 0x4F, 0x89, 0x4F, 0x9B, 0x4F, 0xAD, 0x4F, 0xBF, 0x4F, 0xD1, 0x4F, 0xE3, 0x4F, 0xF5, 0x4F, 0x00, + 0x07, 0x5F, 0x19, 0x5F, 0x2B, 0x5F, 0x3D, 0x5F, 0x50, 0x4F, 0x61, 0x5F, 0x73, 0x5F, 0x85, 0x5F, + 0x00, 0x97, 0x5F, 0xA9, 0x5F, 0xBB, 0x5F, 0xCD, 0x5F, 0xDF, 0x5F, 0xF1, 0x5F, 0x03, 0x6F, 0x15, + 0x6F, 0x00, 0x27, 0x6F, 0x39, 0x6F, 0x4C, 0x5F, 0x5D, 0x6F, 0x6F, 0x6F, 0x81, 0x6F, 0x93, 0x6F, + 0xA5, 0x6F, 0x00, 0xB7, 0x6F, 0xC9, 0x6F, 0xDB, 0x6F, 0xED, 0x6F, 0xFF, 0x6F, 0x11, 0x7F, 0x23, + 0x7F, 0x35, 0x7F, 0x00, 0x48, 0x6F, 0x5A, 0x6F, 0x6B, 0x7F, 0x7D, 0x7F, 0x8F, 0x7F, 0xA1, 0x7F, + 0xB3, 0x7F, 0xC5, 0x7F, 0x00, 0xD7, 0x7F, 0xE9, 0x7F, 0xFB, 0x7F, 0x0D, 0x8F, 0x1F, 0x8F, 0x31, + 0x8F, 0x44, 0x7F, 0x56, 0x7F, 0x00, 0x67, 0x8F, 0x79, 0x8F, 0x8B, 0x8F, 0x9D, 0x8F, 0xAF, 0x8F, + 0xC1, 0x8F, 0xD3, 0x8F, 0xE5, 0x8F, 0x00, 0xF7, 0x8F, 0x09, 0x9F, 0x1B, 0x9F, 0x2D, 0x9F, 0x40, + 0x8F, 0x52, 0x8F, 0x63, 0x9F, 0x75, 0x9F, 0x00, 0x87, 0x9F, 0x99, 0x9F, 0xAB, 0x9F, 0xBD, 0x9F, + 0xCF, 0x9F, 0xE1, 0x9F, 0xF3, 0x9F, 0x05, 0xAF, 0x00, 0x17, 0xAF, 0x29, 0xAF, 0x3B, 0xAF, 0x4E, + 0x9F, 0x5F, 0xAF, 0x71, 0xAF, 0x83, 0xAF, 0x95, 0xAF, 0x00, 0xA7, 0xAF, 0xB9, 0xAF, 0xCB, 0xAF, + 0xDD, 0xAF, 0xEF, 0xAF, 0x01, 0xBF, 0x13, 0xBF, 0x25, 0xBF, 0x00, 0x37, 0xBF, 0x4A, 0xAF, 0x5B, + 0xBF, 0x6D, 0xBF, 0x7F, 0xBF, 0x91, 0xBF, 0xA3, 0xBF, 0xB5, 0xBF, 0x00, 0xC7, 0xBF, 0xD9, 0xBF, + 0xEB, 0xBF, 0xFD, 0xBF, 0x0F, 0xCF, 0x21, 0xCF, 0x33, 0xCF, 0x46, 0xBF, 0x00, 0x58, 0xBF, 0x69, + 0xCF, 0x7B, 0xCF, 0x8D, 0xCF, 0x9F, 0xCF, 0xB1, 0xCF, 0xC3, 0xCF, 0xD5, 0xCF, 0x80, 0xE7, 0xCF, + 0xF9, 0xCF, 0x0B, 0xDF, 0x1D, 0xDF, 0x2F, 0xDF, 0x42, 0xCF, 0x54, 0xC4, 0x10, 0x00, 0x3F, 0xDF, + 0x6D, 0xDF, 0x7F, 0xDF, 0x91, 0xDF, 0xA3, 0xDF, 0xB5, 0xDF, 0xC7, 0xDF, 0xD9, 0xDF, 0x40, 0xEB, + 0xDF, 0xFD, 0xDF, 0x0F, 0xEF, 0x21, 0xEF, 0x33, 0xEF, 0x45, 0xD7, 0x01, 0x51, 0xDF, 0x00, 0x62, + 0xEF, 0x74, 0xEF, 0x86, 0xEF, 0x98, 0xEF, 0xAA, 0xEF, 0xBC, 0xEF, 0xCE, 0xEF, 0xE0, 0xEF, 0x00, + 0xF2, 0xEF, 0x04, 0xFF, 0x16, 0xFF, 0x28, 0xFF, 0x3A, 0xFF, 0x4D, 0xEF, 0x5E, 0xFF, 0x70, 0xFF, + 0x00, 0x82, 0xFF, 0x94, 0xFF, 0xA6, 0xFF, 0xB8, 0xFF, 0xCA, 0xFF, 0xDC, 0xFF, 0xEE, 0xFF, 0x00, + 0x0F, 0x00, 0x12, 0x0F, 0x24, 0x0F, 0x36, 0x0F, 0x49, 0xFF, 0x5B, 0xFF, 0x6C, 0x0F, 0x7E, 0x0F, + 0x90, 0x0F, 0x00, 0xA2, 0x0F, 0xB4, 0x0F, 0xC6, 0x0F, 0xD8, 0x0F, 0xEA, 0x0F, 0xFC, 0x0F, 0x0E, + 0x1F, 0x20, 0x1F, 0x00, 0x32, 0x1F, 0x45, 0x0F, 0x57, 0x0F, 0x68, 0x1F, 0x7A, 0x1F, 0x8C, 0x1F, + 0x9E, 0x1F, 0xB0, 0x1F, 0x00, 0xC2, 0x1F, 0xD4, 0x1F, 0xE6, 0x1F, 0xF8, 0x1F, 0x0A, 0x2F, 0x1C, + 0x2F, 0x2E, 0x2F, 0x41, 0x1F, 0x00, 0x53, 0x1F, 0x64, 0x2F, 0x76, 0x2F, 0x88, 0x2F, 0x9A, 0x2F, + 0xAC, 0x2F, 0xBE, 0x2F, 0xD0, 0x2F, 0x00, 0xE2, 0x2F, 0xF4, 0x2F, 0x06, 0x3F, 0x18, 0x3F, 0x2A, + 0x3F, 0x3C, 0x3F, 0x4F, 0x2F, 0x60, 0x3F, 0x00, 0x72, 0x3F, 0x84, 0x3F, 0x96, 0x3F, 0xA8, 0x3F, + 0xBA, 0x3F, 0xCC, 0x3F, 0xDE, 0x3F, 0xF0, 0x3F, 0x00, 0x02, 0x4F, 0x14, 0x4F, 0x26, 0x4F, 0x38, + 0x4F, 0x4B, 0x3F, 0x5C, 0x4F, 0x6E, 0x4F, 0x80, 0x4F, 0x00, 0x92, 0x4F, 0xA4, 0x4F, 0xB6, 0x4F, + 0xC8, 0x4F, 0xDA, 0x4F, 0xEC, 0x4F, 0xFE, 0x4F, 0x10, 0x5F, 0x00, 0x22, 0x5F, 0x34, 0x5F, 0x47, + 0x4F, 0x59, 0x4F, 0x6A, 0x5F, 0x7C, 0x5F, 0x8E, 0x5F, 0xA0, 0x5F, 0x00, 0xB2, 0x5F, 0xC4, 0x5F, + 0xD6, 0x5F, 0xE8, 0x5F, 0xFA, 0x5F, 0x0C, 0x6F, 0x1E, 0x6F, 0x30, 0x6F, 0x00, 0x43, 0x5F, 0x55, + 0x5F, 0x66, 0x6F, 0x78, 0x6F, 0x8A, 0x6F, 0x9C, 0x6F, 0xAE, 0x6F, 0xC0, 0x6F, 0x00, 0xD2, 0x6F, + 0xE4, 0x6F, 0xF6, 0x6F, 0x08, 0x7F, 0x1A, 0x7F, 0x2C, 0x7F, 0x3F, 0x6F, 0x51, 0x6F, 0x00, 0x62, + 0x7F, 0x74, 0x7F, 0x86, 0x7F, 0x98, 0x7F, 0xAA, 0x7F, 0xBC, 0x7F, 0xCE, 0x7F, 0xE0, 0x7F, 0x00, + 0xF2, 0x7F, 0x04, 0x8F, 0x16, 0x8F, 0x28, 0x8F, 0x3A, 0x8F, 0x4D, 0x7F, 0x5E, 0x8F, 0x70, 0x8F, + 0x00, 0x82, 0x8F, 0x94, 0x8F, 0xA6, 0x8F, 0xB8, 0x8F, 0xCA, 0x8F, 0xDC, 0x8F, 0xEE, 0x8F, 0x00, + 0x9F, 0x00, 0x12, 0x9F, 0x24, 0x9F, 0x36, 0x9F, 0x49, 0x8F, 0x5B, 0x8F, 0x6C, 0x9F, 0x7E, 0x9F, + 0x90, 0x9F, 0x00, 0xA2, 0x9F, 0xB4, 0x9F, 0xC6, 0x9F, 0xD8, 0x9F, 0xEA, 0x9F, 0xFC, 0x9F, 0x0E, + 0xAF, 0x20, 0xAF, 0x00, 0x32, 0xAF, 0x45, 0x9F, 0x57, 0x9F, 0x68, 0xAF, 0x7A, 0xAF, 0x8C, 0xAF, + 0x9E, 0xAF, 0xB0, 0xAF, 0x00, 0xC2, 0xAF, 0xD4, 0xAF, 0xE6, 0xAF, 0xF8, 0xAF, 0x0A, 0xBF, 0x1C, + 0xBF, 0x2E, 0xBF, 0x41, 0xAF, 0x00, 0x52, 0xCF, 0x64, 0xBF, 0x76, 0xBF, 0x88, 0xBF, 0x9A, 0xBF, + 0xAC, 0xBF, 0xBE, 0xBF, 0xD0, 0xBF, 0x00, 0xE2, 0xBF, 0xF4, 0xBF, 0x06, 0xCF, 0x18, 0xCF, 0x2A, + 0xCF, 0x3C, 0xCF, 0x50, 0xD8, 0x5A, 0xBF, 0x00, 0x6B, 0xCF, 0x7D, 0xCF, 0x8F, 0xCF, 0xA1, 0xCF, + 0xB3, 0xCF, 0xC5, 0xCF, 0xD7, 0xCF, 0xE9, 0xCF, 0x00, 0xFB, 0xCF, 0x0D, 0xDF, 0x1F, 0xDF, 0x31, + 0xDF, 0x44, 0xCF, 0x56, 0xCF, 0x67, 0xDF, 0x79, 0xDF, 0x00, 0x8B, 0xDF, 0x9D, 0xDF, 0xAF, 0xDF, + 0xC1, 0xDF, 0xD3, 0xDF, 0xE5, 0xDF, 0xF7, 0xDF, 0x09, 0xEF, 0x00, 0x1B, 0xEF, 0x2D, 0xEF, 0x40, + 0xDF, 0x52, 0xDF, 0x63, 0xEF, 0x75, 0xEF, 0x87, 0xEF, 0x99, 0xEF, 0x00, 0xAB, 0xEF, 0xBD, 0xEF, + 0xCF, 0xEF, 0xE1, 0xEF, 0xF3, 0xEF, 0x05, 0xFF, 0x17, 0xFF, 0x29, 0xFF, 0x00, 0x3B, 0xFF, 0x4E, + 0xEF, 0x5F, 0xFF, 0x71, 0xFF, 0x83, 0xFF, 0x95, 0xFF, 0xA7, 0xFF, 0xB9, 0xFF, 0x00, 0xCB, 0xFF, + 0xDD, 0xFF, 0xEF, 0xFF, 0x01, 0x0F, 0x13, 0x0F, 0x25, 0x0F, 0x37, 0x0F, 0x4A, 0xFF, 0x00, 0x3E, + 0x0F, 0x6D, 0x0F, 0x7F, 0x0F, 0x91, 0x0F, 0xA3, 0x0F, 0xB5, 0x0F, 0xC7, 0x0F, 0xD9, 0x0F, 0x00, + 0xEB, 0x0F, 0xFD, 0x0F, 0x0F, 0x1F, 0x21, 0x1F, 0x33, 0x1F, 0x46, 0x0F, 0x58, 0x0F, 0x69, 0x1F, + 0x00, 0x7B, 0x1F, 0x8D, 0x1F, 0x9F, 0x1F, 0xB1, 0x1F, 0xC3, 0x1F, 0xD5, 0x1F, 0xE7, 0x1F, 0xF9, + 0x1F, 0x00, 0x0B, 0x2F, 0x1D, 0x2F, 0x2F, 0x2F, 0x42, 0x1F, 0x54, 0x1F, 0x65, 0x2F, 0x77, 0x2F, + 0x89, 0x2F, 0x00, 0x9B, 0x2F, 0xAD, 0x2F, 0xBF, 0x2F, 0xD1, 0x2F, 0xE3, 0x2F, 0xF5, 0x2F, 0x07, + 0x3F, 0x19, 0x3F, 0x00, 0x2B, 0x3F, 0x3D, 0x3F, 0x50, 0x2F, 0x61, 0x3F, 0x73, 0x3F, 0x85, 0x3F, + 0x97, 0x3F, 0xA9, 0x3F, 0x00, 0xBB, 0x3F, 0xCD, 0x3F, 0xDF, 0x3F, 0xF1, 0x3F, 0x03, 0x4F, 0x15, + 0x4F, 0x27, 0x4F, 0x39, 0x4F, 0x00, 0x4C, 0x3F, 0x5D, 0x4F, 0x6F, 0x4F, 0x81, 0x4F, 0x93, 0x4F, + 0xA5, 0x4F, 0xB7, 0x4F, 0xC9, 0x4F, 0x00, 0xDB, 0x4F, 0xED, 0x4F, 0xFF, 0x4F, 0x11, 0x5F, 0x23, + 0x5F, 0x35, 0x5F, 0x48, 0x4F, 0x59, 0xAF, 0x00, 0x6B, 0x5F, 0x7D, 0x5F, 0x8F, 0x5F, 0xA1, 0x5F, + 0xB3, 0x5F, 0xC5, 0x5F, 0xD7, 0x5F, 0xE9, 0x5F, 0x00, 0xFB, 0x5F, 0x0D, 0x6F, 0x1F, 0x6F, 0x31, + 0x6F, 0x45, 0xBF, 0x56, 0x5F, 0x67, 0x6F, 0x79, 0x6F, 0x00, 0x8B, 0x6F, 0x9D, 0x6F, 0xAF, 0x6F, + 0xC1, 0x6F, 0xD3, 0x6F, 0xE5, 0x6F, 0xF7, 0x6F, 0x09, 0x7F, 0x00, 0x1B, 0x7F, 0x2D, 0x7F, 0x40, + 0x6F, 0x52, 0x6F, 0x63, 0x7F, 0x75, 0x7F, 0x87, 0x7F, 0x99, 0x7F, 0x00, 0xAB, 0x7F, 0xBD, 0x7F, + 0xCF, 0x7F, 0xE1, 0x7F, 0xF3, 0x7F, 0x05, 0x8F, 0x17, 0x8F, 0x29, 0x8F, 0x00, 0x3B, 0x8F, 0x4E, + 0x7F, 0x5F, 0x8F, 0x71, 0x8F, 0x83, 0x8F, 0x95, 0x8F, 0xA7, 0x8F, 0xB9, 0x8F, 0x00, 0xCB, 0x8F, + 0xDD, 0x8F, 0xEF, 0x8F, 0x01, 0x9F, 0x13, 0x9F, 0x25, 0x9F, 0x37, 0x9F, 0x4A, 0x8F, 0x00, 0x5C, + 0x8F, 0x6D, 0x9F, 0x7F, 0x9F, 0x91, 0x9F, 0xA3, 0x9F, 0xB5, 0x9F, 0xC7, 0x9F, 0xD9, 0x9F, 0x00, + 0xEB, 0x9F, 0xFD, 0x9F, 0x0F, 0xAF, 0x21, 0xAF, 0x33, 0xAF, 0x46, 0x9F, 0x58, 0x9F, 0x69, 0xAF, + 0x00, 0x7B, 0xAF, 0x8D, 0xAF, 0x9F, 0xAF, 0xB1, 0xAF, 0xC3, 0xAF, 0xD5, 0xAF, 0xE7, 0xAF, 0xF9, + 0xAF, 0x00, 0x0B, 0xBF, 0x1D, 0xBF, 0x2F, 0xBF, 0x42, 0xAF, 0x54, 0xAF, 0x65, 0xBF, 0x77, 0xBF, + 0x89, 0xBF, 0x00, 0x9B, 0xBF, 0xAD, 0xBF, 0xBF, 0xBF, 0xD1, 0xBF, 0xE3, 0xBF, 0xF5, 0xBF, 0x07, + 0xCF, 0x19, 0xCF, 0x00, 0x2B, 0xCF, 0x3E, 0xBF, 0x50, 0xBF, 0x61, 0xCF, 0x73, 0xCF, 0x85, 0xCF, + 0x97, 0xCF, 0xA9, 0xCF, 0x00, 0xBB, 0xCF, 0xCD, 0xCF, 0xDF, 0xCF, 0xF1, 0xCF, 0x03, 0xDF, 0x15, + 0xDF, 0x27, 0xDF, 0x39, 0xDF, 0x00, 0x4C, 0xCF, 0x5D, 0xDF, 0x6F, 0xDF, 0x81, 0xDF, 0x93, 0xDF, + 0xA5, 0xDF, 0xB7, 0xDF, 0xC9, 0xDF, 0x00, 0xDB, 0xDF, 0xED, 0xDF, 0xFF, 0xDF, 0x11, 0xEF, 0x23, + 0xEF, 0x35, 0xEF, 0x48, 0xDF, 0x59, 0x4F, 0x00, 0x6B, 0xEF, 0x7D, 0xEF, 0x8F, 0xEF, 0xA1, 0xEF, + 0xB3, 0xEF, 0xC5, 0xEF, 0xD7, 0xEF, 0xE9, 0xEF, 0x00, 0xFB, 0xEF, 0x0D, 0xFF, 0x1F, 0xFF, 0x31, + 0xFF, 0x45, 0x5F, 0x56, 0xEF, 0x67, 0xFF, 0x79, 0xFF, 0x00, 0x8B, 0xFF, 0x9D, 0xFF, 0xAF, 0xFF, + 0xC1, 0xFF, 0xD3, 0xFF, 0xE5, 0xFF, 0xF7, 0xFF, 0x09, 0x0F, 0x00, 0x1B, 0x0F, 0x2D, 0x0F, 0x40, + 0xFF, 0x52, 0xFF, 0x63, 0x0F, 0x75, 0x0F, 0x87, 0x0F, 0x99, 0x0F, 0x00, 0xAB, 0x0F, 0xBD, 0x0F, + 0xCF, 0x0F, 0xE1, 0x0F, 0xF3, 0x0F, 0x05, 0x1F, 0x17, 0x1F, 0x29, 0x1F, 0x00, 0x3B, 0x1F, 0x4E, + 0x0F, 0x5F, 0x1F, 0x71, 0x1F, 0x83, 0x1F, 0x95, 0x1F, 0xA7, 0x1F, 0xB9, 0x1F, 0x00, 0xCB, 0x1F, + 0xDD, 0x1F, 0xEF, 0x1F, 0x01, 0x2F, 0x13, 0x2F, 0x25, 0x2F, 0x37, 0x2F, 0x4A, 0x1F, 0x00, 0x5C, + 0x1F, 0x6D, 0x2F, 0x7F, 0x2F, 0x91, 0x2F, 0xA3, 0x2F, 0xB5, 0x2F, 0xC7, 0x2F, 0xD9, 0x2F, 0x00, + 0xEB, 0x2F, 0xFD, 0x2F, 0x0F, 0x3F, 0x21, 0x3F, 0x33, 0x3F, 0x46, 0x2F, 0x58, 0x2F, 0x69, 0x3F, + 0x00, 0x7B, 0x3F, 0x8D, 0x3F, 0x9F, 0x3F, 0xB1, 0x3F, 0xC3, 0x3F, 0xD5, 0x3F, 0xE7, 0x3F, 0xF9, + 0x3F, 0x00, 0x0B, 0x4F, 0x1D, 0x4F, 0x2F, 0x4F, 0x42, 0x3F, 0x54, 0x3F, 0x65, 0x4F, 0x77, 0x4F, + 0x89, 0x4F, 0x00, 0x9B, 0x4F, 0xAD, 0x4F, 0xBF, 0x4F, 0xD1, 0x4F, 0xE3, 0x4F, 0xF5, 0x4F, 0x07, + 0x5F, 0x19, 0x5F, 0x00, 0x2B, 0x5F, 0x3E, 0x4F, 0x50, 0x4A, 0x5C, 0xDF, 0x6E, 0x5F, 0x80, 0x5F, + 0x92, 0x5F, 0xA4, 0x5F, 0x00, 0xB6, 0x5F, 0xC8, 0x5F, 0xDA, 0x5F, 0xEC, 0x5F, 0xFE, 0x5F, 0x10, + 0x6F, 0x22, 0x6F, 0x34, 0x6F, 0x00, 0x48, 0xEF, 0x59, 0x5F, 0x6A, 0x6F, 0x7C, 0x6F, 0x8E, 0x6F, + 0xA0, 0x6F, 0xB2, 0x6F, 0xC4, 0x6F, 0x00, 0xD6, 0x6F, 0xE8, 0x6F, 0xFA, 0x6F, 0x0C, 0x7F, 0x1E, + 0x7F, 0x30, 0x7F, 0x43, 0x6F, 0x55, 0x6F, 0x00, 0x66, 0x7F, 0x78, 0x7F, 0x8A, 0x7F, 0x9C, 0x7F, + 0xAE, 0x7F, 0xC0, 0x7F, 0xD2, 0x7F, 0xE4, 0x7F, 0x00, 0xF6, 0x7F, 0x08, 0x8F, 0x1A, 0x8F, 0x2C, + 0x8F, 0x3F, 0x7F, 0x51, 0x7F, 0x62, 0x8F, 0x74, 0x8F, 0x00, 0x86, 0x8F, 0x98, 0x8F, 0xAA, 0x8F, + 0xBC, 0x8F, 0xCE, 0x8F, 0xE0, 0x8F, 0xF2, 0x8F, 0x04, 0x9F, 0x00, 0x16, 0x9F, 0x28, 0x9F, 0x3A, + 0x9F, 0x4D, 0x8F, 0x5E, 0x9F, 0x70, 0x9F, 0x82, 0x9F, 0x94, 0x9F, 0x00, 0xA6, 0x9F, 0xB8, 0x9F, + 0xCA, 0x9F, 0xDC, 0x9F, 0xEE, 0x9F, 0x00, 0xAF, 0x12, 0xAF, 0x24, 0xAF, 0x1C, 0x36, 0xAF, 0x49, + 0x9F, 0x11, 0x12, 0x20, 0x3C, 0xAF, 0x6F, 0xAF, 0x81, 0xAF, 0x00, 0x93, 0xAF, 0xA5, 0xAF, 0xB7, + 0xAF, 0xC9, 0xAF, 0xDB, 0xAF, 0xED, 0xAF, 0xFF, 0xAF, 0x11, 0xBF, 0xD8, 0x23, 0xBF, 0x35, 0xBF, + 0x48, 0xA3, 0x02, 0x21, 0x51, 0xA9, 0x23, 0x32, 0x00, 0x3C, 0xBF, 0x6F, 0xBF, 0x81, 0xBF, 0x93, + 0xBF, 0xA5, 0xBF, 0xB7, 0xBF, 0xC9, 0xBF, 0xDB, 0xBF, 0xC0, 0xED, 0xBF, 0xFF, 0xBF, 0x11, 0xCF, + 0x23, 0xCF, 0x35, 0xCF, 0x48, 0xA3, 0x23, 0x32, 0x1E, 0x4F, 0xB7, 0x12, 0x23, 0x34, 0x45, 0x3C, + 0xCF, 0x6F, 0xCF, 0x81, 0xCF, 0x00, 0x93, 0xCF, 0xA5, 0xCF, 0xB7, 0xCF, 0xC9, 0xCF, 0xDB, 0xCF, + 0xED, 0xCF, 0xFF, 0xCF, 0x11, 0xDF, 0xD8, 0x23, 0xDF, 0x35, 0xDF, 0x48, 0xA3, 0x54, 0x43, 0x4F, + 0xC6, 0x22, 0x23, 0x0F, 0x33, 0x45, 0x66, 0x70, 0x3C, 0xDF, 0x70, 0xDF, 0x82, 0xDF, 0x94, 0xDF, + 0x00, 0xA6, 0xDF, 0xB8, 0xDF, 0xCA, 0xDF, 0xDC, 0xDF, 0xEE, 0xDF, 0x00, 0xEF, 0x12, 0xEF, 0x24, + 0xEF, 0xFC, 0x36, 0xEF, 0x48, 0xA1, 0x07, 0x66, 0x54, 0x33, 0x32, 0x22, 0x1E, 0x54, 0xD5, 0x44, + 0x56, 0x78, 0x87, 0x3B, 0xEF, 0x70, 0xEF, 0x82, 0xEF, 0x00, 0x94, 0xEF, 0xA6, 0xEF, 0xB8, 0xEF, + 0xCA, 0xEF, 0xDC, 0xEF, 0xEE, 0xEF, 0x00, 0xFF, 0x12, 0xFF, 0x78, 0x24, 0xFF, 0x36, 0xFF, 0x48, + 0xA1, 0x78, 0x87, 0x65, 0x44, 0x50, 0xE3, 0x3E, 0x58, 0xE1, 0x55, 0x67, 0x88, 0x76, 0x42, 0x3B, + 0xFF, 0x71, 0xFF, 0x00, 0x83, 0xFF, 0x95, 0xFF, 0xA7, 0xFF, 0xB9, 0xFF, 0xCB, 0xFF, 0xDD, 0xFF, + 0xEF, 0xFF, 0x01, 0x0F, 0xB8, 0x13, 0x0F, 0x25, 0x0F, 0x37, 0x0F, 0x00, 0x00, 0x24, 0x5C, 0xF0, + 0x55, 0x3C, 0x50, 0xF2, 0x57, 0xF3, 0x78, 0x88, 0x75, 0x42, 0x58, 0x9F, 0x71, 0x0F, 0x00, 0x83, + 0x0F, 0x95, 0x0F, 0xA7, 0x0F, 0xB9, 0x0F, 0xCB, 0x0F, 0xDD, 0x0F, 0xEF, 0x0F, 0x01, 0x1F, 0xF8, + 0x13, 0x1F, 0x25, 0x1F, 0x40, 0xAF, 0x11, 0x11, 0x24, 0x57, 0x88, 0xFD, 0x87, 0x4F, 0x03, 0x33, + 0x33, 0x44, 0x45, 0x56, 0x78, 0x0F, 0x88, 0x87, 0x65, 0x32, 0x52, 0x9F, 0x71, 0x1F, 0x83, 0x1F, + 0x95, 0x1F, 0x00, 0xA7, 0x1F, 0xB9, 0x1F, 0xCB, 0x1F, 0xDD, 0x1F, 0xEF, 0x1F, 0x01, 0x2F, 0x13, + 0x2F, 0x25, 0x2F, 0xEE, 0x46, 0xAF, 0x11, 0x11, 0x23, 0x5A, 0x12, 0x54, 0x44, 0x33, 0x1C, 0x56, + 0x11, 0x5B, 0xF0, 0x88, 0x76, 0x54, 0x5F, 0x19, 0x54, 0x4F, 0x7C, 0x2F, 0x00, 0x8E, 0x2F, 0xA0, + 0x2F, 0xB2, 0x2F, 0xC4, 0x2F, 0xD6, 0x2F, 0xE8, 0x2F, 0xFA, 0x2F, 0x0C, 0x3F, 0x28, 0x1E, 0x3F, + 0x48, 0x5F, 0x43, 0x27, 0x45, 0x5A, 0x21, 0x55, 0x52, 0x20, 0x57, 0x20, 0x3F, 0x66, 0x78, 0x88, + 0x88, 0x75, 0x43, 0x4F, 0xB9, 0x6A, 0x3F, 0x00, 0x71, 0x2F, 0x8E, 0x3F, 0xA0, 0x3F, 0xB2, 0x3F, + 0xC4, 0x3F, 0xD6, 0x3F, 0xE8, 0x3F, 0xFA, 0x3F, 0xF0, 0x0C, 0x4F, 0x2B, 0x3F, 0x30, 0x4F, 0x53, + 0xA7, 0x34, 0x57, 0x88, 0x88, 0x7B, 0x87, 0x66, 0x52, 0x30, 0x45, 0x55, 0x56, 0x77, 0x4F, 0x40, + 0x01, 0x65, 0x5E, 0x3F, 0x6F, 0x4F, 0x7F, 0x4C, 0x6B, 0x1F, 0xA2, 0x4F, 0xB4, 0x4F, 0xC6, 0x4F, + 0x00, 0xD8, 0x4F, 0xEA, 0x4F, 0xFC, 0x4F, 0x35, 0x2F, 0x20, 0x5F, 0x32, 0x5F, 0x45, 0x46, 0x5A, + 0x10, 0x7F, 0x88, 0x77, 0x65, 0x55, 0x54, 0x55, 0x56, 0x5B, 0x00, 0x00, 0x5C, 0x21, 0x5F, 0x4F, + 0x70, 0x5F, 0x82, 0x5F, 0x94, 0x5F, 0x8B, 0x4F, 0xB8, 0x5F, 0xCA, 0x5F, 0x00, 0xDC, 0x5F, 0x0B, + 0x5F, 0x00, 0x6F, 0x12, 0x6F, 0x24, 0x6F, 0x36, 0x6F, 0x58, 0xB2, 0x4D, 0x31, 0x3F, 0x87, 0x76, + 0x65, 0x55, 0x55, 0x66, 0x59, 0x43, 0x5F, 0x2F, 0x00, 0x6F, 0x6F, 0x81, 0x6F, 0x93, 0x6F, 0xA5, + 0x6F, 0xB7, 0x6F, 0xC9, 0x6F, 0xDB, 0x6F, 0xED, 0x6F, 0x40, 0xFF, 0x6F, 0x11, 0x7F, 0x23, 0x7F, + 0x35, 0x7F, 0x47, 0x23, 0x4D, 0x53, 0x66, 0x57, 0x40, 0x00, 0x4F, 0x52, 0x5D, 0x6F, 0x6E, 0x7F, + 0x80, 0x7F, 0x92, 0x7F, 0xA4, 0x7F, 0xB6, 0x7F, 0xC8, 0x7F, 0x00, 0xDA, 0x7F, 0xEC, 0x7F, 0xFE, + 0x7F, 0x10, 0x8F, 0x22, 0x8F, 0x34, 0x8F, 0x47, 0x76, 0x59, 0x41, 0x7B, 0x77, 0x65, 0x58, 0x51, + 0x87, 0x76, 0x54, 0x33, 0x52, 0xE3, 0x00, 0x63, 0x8F, 0x75, 0x8F, 0x87, 0x8F, 0x99, 0x8F, 0xAB, + 0x8F, 0xBD, 0x8F, 0xCF, 0x8F, 0xE1, 0x8F, 0xE0, 0xF3, 0x8F, 0x05, 0x9F, 0x17, 0x9F, 0x29, 0x9F, + 0x3B, 0x9E, 0x22, 0x33, 0x45, 0x18, 0x56, 0x83, 0x59, 0x40, 0x51, 0x50, 0x54, 0x33, 0x5F, 0x5F, + 0x6F, 0x9F, 0x81, 0x9F, 0x00, 0x93, 0x9F, 0xA5, 0x9F, 0xB7, 0x9F, 0xC9, 0x9F, 0xDB, 0x9F, 0xED, + 0x9F, 0xFF, 0x9F, 0x11, 0xAF, 0x58, 0x23, 0xAF, 0x35, 0xAF, 0x56, 0xB3, 0x33, 0x45, 0x58, 0x41, + 0x88, 0x57, 0x70, 0x01, 0x98, 0x52, 0x60, 0x4F, 0xD7, 0x65, 0xAF, 0x77, 0xAF, 0x89, 0xAF, 0x9B, + 0xAF, 0xAD, 0xAF, 0x00, 0xBF, 0xAF, 0xD1, 0xAF, 0xE3, 0xAF, 0xF5, 0xAF, 0x07, 0xBF, 0x19, 0xBF, + 0x2B, 0xBF, 0x3D, 0x6E, 0xBD, 0x34, 0x57, 0x50, 0x89, 0x88, 0x87, 0x88, 0x53, 0xB0, 0x66, 0x01, + 0x55, 0x5D, 0x7F, 0x6D, 0xBF, 0x7F, 0xBF, 0x91, 0xBF, 0xA3, 0xBF, 0xB5, 0xBF, 0xC7, 0xBF, 0x00, + 0xD9, 0xBF, 0xEB, 0xBF, 0xFD, 0xBF, 0x0F, 0xCF, 0x21, 0xCF, 0x33, 0xCF, 0x45, 0x77, 0x58, 0x31, + 0x0F, 0x98, 0x88, 0x89, 0x98, 0x59, 0x92, 0x5E, 0x8F, 0x6E, 0xCF, 0x80, 0xCF, 0x00, 0x92, 0xCF, + 0xA4, 0xCF, 0xB6, 0xCF, 0xC8, 0xCF, 0xDA, 0xCF, 0xEC, 0xCF, 0xFE, 0xCF, 0x10, 0xDF, 0x70, 0x22, + 0xDF, 0x34, 0xDF, 0x46, 0x97, 0x58, 0x40, 0x89, 0x98, 0x99, 0x4E, 0x13, 0x00, 0x5D, 0xCF, 0x6E, + 0xDF, 0x80, 0xDF, 0x92, 0xDF, 0xA4, 0xDF, 0xB6, 0xDF, 0xC8, 0xDF, 0xDA, 0xDF, 0x80, 0xEC, 0xDF, + 0xFE, 0xDF, 0x10, 0xEF, 0x22, 0xEF, 0x34, 0xEF, 0x46, 0x96, 0x59, 0x02, 0x99, 0x05, 0x99, 0x52, + 0x71, 0x43, 0x5D, 0x9F, 0x6D, 0xEF, 0x7F, 0xEF, 0x91, 0xEF, 0xA3, 0xEF, 0x00, 0xB5, 0xEF, 0xC7, + 0xEF, 0xD9, 0xEF, 0xEB, 0xEF, 0xFD, 0xEF, 0x0F, 0xFF, 0x21, 0xFF, 0x33, 0xFF, 0xBC, 0x45, 0xA7, + 0x4F, 0xC0, 0x77, 0x88, 0x99, 0x98, 0x53, 0x80, 0x54, 0x00, 0x5C, 0xAF, 0x6C, 0xFF, 0x7E, 0xFF, + 0x90, 0xFF, 0xA2, 0xFF, 0xB4, 0xFF, 0xC6, 0xFF, 0xD8, 0xFF, 0x80, 0xEA, 0xFF, 0xFC, 0xFF, 0x0E, + 0x0F, 0x20, 0x0F, 0x32, 0x0F, 0x44, 0xB9, 0x4F, 0xA0, 0x78, 0x01, 0x89, diff --git a/References/VirtuaNESex_src_191105/nx_2xSaI.h b/References/VirtuaNESex_src_191105/nx_2xSaI.h new file mode 100644 index 00000000..e9325f45 --- /dev/null +++ b/References/VirtuaNESex_src_191105/nx_2xSaI.h @@ -0,0 +1,1255 @@ +/*---------------------------------------------------------------------* + * The following (piece of) code, (part of) the 2xSaI engine, * + * copyright (c) 2001 by Derek Liauw Kie Fa. * + * Non-Commercial use of the engine is allowed and is encouraged, * + * provided that appropriate credit be given and that this copyright * + * notice will not be removed under any circumstance. * + * You may freely modify this code, but I request * + * that any improvements to the engine be submitted to me, so * + * that I can implement these improvements in newer versions of * + * the engine. * + * If you need more information, have any comments or suggestions, * + * you can e-mail me. My e-mail: DerekL666@yahoo.com * + *---------------------------------------------------------------------*/ +// +// This code was converted into VirtuaNES by Norix. +// +static void nx_2xSaILine_16bpp_mmx( euI8* pSrc, euI8* pDlt, euI32 srcPitch, euI32 width, euI8* pDst, euI32 dstPitch, euI32 bForceWrite ) +{ + __asm { + mov eax, pSrc + mov ebx, srcPitch + mov edx, pDst + sub eax, ebx +nx_2xSaILine_16mmx_loop: + mov ecx, bForceWrite + test ecx, ecx + jz nx_2xSaILine_16mmx_normal + + mov esi, pDlt + movq mm6, [eax+colorI] + movq [esi+colorI], mm6 + + jmp nx_2xSaILine_16mmx_forcewrite +nx_2xSaILine_16mmx_normal: + // Check delta + mov ecx, pDlt + + // load source img + lea esi, [eax+ebx] + movq mm0, [eax+colorI] + movq mm1, [eax+colorJ] + movq mm2, [eax+ebx+colorG] + movq mm3, [eax+ebx+colorK] + movq mm4, [eax+ebx*2+colorH] + movq mm5, [eax+ebx*2+colorL] + movq mm6, [esi+ebx*2+colorM] + movq mm7, [esi+ebx*2+colorP] + + // compare to delta + lea esi, [ecx+ebx] + pcmpeqw mm0, [ecx+colorI] + pcmpeqw mm1, [ecx+colorJ] + pcmpeqw mm2, [ecx+ebx+colorG] + pcmpeqw mm3, [ecx+ebx+colorK] + pcmpeqw mm4, [ecx+ebx*2+colorH] + pcmpeqw mm5, [ecx+ebx*2+colorL] + pcmpeqw mm6, [esi+ebx*2+colorM] + pcmpeqw mm7, [esi+ebx*2+colorP] + + // compose results + pand mm0, mm1 + pand mm2, mm3 + pand mm4, mm5 + pand mm6, mm7 + pand mm0, mm2 + pand mm4, mm6 + pxor mm7, mm7 + pand mm0, mm4 + movq mm6, [eax+colorI] + pcmpeqw mm7, mm0 + + movq [ecx+colorI], mm6 + + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_2xSaILine_16mmx_skipprocess + // End Delta +nx_2xSaILine_16mmx_forcewrite: + //------------------------------ + // 1 + // if ((colorA == colorD) && (colorB != colorC) && (colorA == colorE) && (colorB == colorL) + movq mm0, [eax+ebx+colorA] // mm0 and mm1 contain colorA + movq mm2, [eax+ebx+colorB] // mm2 and mm3 contain colorB + + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [eax+ebx*2+colorD] + pcmpeqw mm1, [eax+colorE] + pcmpeqw mm2, [eax+ebx*2+colorL] + pcmpeqw mm3, [eax+ebx*2+colorC] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorA == colorC) && (colorB != colorE) && (colorA == colorF) && (colorB == colorJ) + movq mm4, [eax+ebx+colorA] // mm4 and mm5 contain colorA + movq mm6, [eax+ebx+colorB] // mm6 and mm7 contain colorB + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [eax+ebx*2+colorC] + pcmpeqw mm5, [eax+colorF] + pcmpeqw mm6, [eax+colorJ] + pcmpeqw mm7, [eax+colorE] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 // combine the masks + movq Mask1, mm0 + + //------------------------------ + // 2 + // if ((colorB == colorC) && (colorA != colorD) && (colorB == colorF) && (colorA == colorH) + movq mm0, [eax+ebx+colorB] // mm0 and mm1 contain colorB + movq mm2, [eax+ebx+colorA] // mm2 and mm3 contain colorA + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [eax+ebx*2+colorC] + pcmpeqw mm1, [eax+colorF] + pcmpeqw mm2, [eax+ebx*2+colorH] + pcmpeqw mm3, [eax+ebx*2+colorD] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI) + movq mm4, [eax+ebx+colorB] // mm4 and mm5 contain colorB + movq mm6, [eax+ebx+colorA] // mm6 and mm7 contain colorA + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [eax+ebx*2+colorD] + pcmpeqw mm5, [eax+colorE] + pcmpeqw mm6, [eax+colorI] + pcmpeqw mm7, [eax+colorF] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 // combine the masks + movq Mask2, mm0 + + //------------------------------ + // interpolate colorA and colorB + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx+colorB] + movq mm2, mm0 + movq mm3, mm1 + + movq mm6, cMask + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 // mm0 contains the interpolated values + + // assemble the pixels + movq mm1, [eax+ebx+colorA] + movq mm2, [eax+ebx+colorB] + + movq mm3, Mask1 + movq mm5, mm1 + movq mm4, Mask2 + movq mm6, mm1 + + pand mm1, mm3 + por mm3, mm4 + pxor mm7, mm7 + pand mm2, mm4 + + pcmpeqw mm3, mm7 + por mm1, mm2 + pand mm0, mm3 + + por mm0, mm1 + + punpcklwd mm5, mm0 + punpckhwd mm6, mm0 + + //------------------------------ + // Write image + //------------------------------ + movq [edx+0], mm5 + movq [edx+8], mm6 + + //------------------------------ + // Create the Nextline + //------------------------------ + // 3 + // if ((colorA == colorD) && (colorB != colorC) && (colorA == colorG) && (colorC == colorO) + lea esi, [eax+ebx] + + movq mm0, [eax+ebx+colorA] // mm0 and mm1 contain colorA + movq mm2, [eax+ebx*2+colorC] // mm2 and mm3 contain colorC + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [esi+ebx+colorD] + pcmpeqw mm1, [esi+colorG] + pcmpeqw mm2, [esi+ebx*2+colorO] + pcmpeqw mm3, [esi+colorB] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorA == colorB) && (colorG != colorC) && (colorA == colorH) && (colorC == colorM) + movq mm4, [eax+ebx+colorA] // mm4 and mm5 contain colorA + movq mm6, [eax+ebx*2+colorC] // mm6 and mm7 contain colorC + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [esi+ebx+colorH] + pcmpeqw mm5, [esi+colorB] + pcmpeqw mm6, [esi+ebx*2+colorM] + pcmpeqw mm7, [esi+colorG] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 // combine the masks + movq Mask1, mm0 + + //------------------------------ + // 4 + // if ((colorB == colorC) && (colorA != colorD) && (colorC == colorH) && (colorA == colorF) + movq mm0, [eax+ebx*2+colorC] // mm0 and mm1 contain colorC + movq mm2, [eax+ebx+colorA] // mm2 and mm3 contain colorA + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [eax+ebx+colorB] + pcmpeqw mm1, [eax+ebx*2+colorH] + pcmpeqw mm2, [eax+colorF] + pcmpeqw mm3, [eax+ebx*2+colorD] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI) + movq mm4, [eax+ebx*2+colorC] // mm4 and mm5 contain colorC + movq mm6, [eax+ebx+colorA] // mm6 and mm7 contain colorA + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [eax+ebx*2+colorD] + pcmpeqw mm5, [eax+ebx+colorG] + pcmpeqw mm6, [eax+colorI] + pcmpeqw mm7, [eax+ebx*2+colorH] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 ;combine the masks + movq Mask2, mm0 + + //------------------------------ + // interpolate colorA and colorC + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx*2+colorC] + movq mm2, mm0 + movq mm3, mm1 + + movq mm6, cMask + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 // mm0 contains the interpolated values + + // assemble the pixels + movq mm1, [eax+ebx+colorA] + movq mm2, [eax+ebx*2+colorC] + + movq mm3, Mask1 + movq mm4, Mask2 + + pand mm1, mm3 + pand mm2, mm4 + + por mm3, mm4 + pxor mm7, mm7 + por mm1, mm2 + + pcmpeqw mm3, mm7 + pand mm0, mm3 + por mm0, mm1 + movq ACPixel, mm0 + + //------------------------------ + // Decide which "branch" to take + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx+colorB] + movq mm6, mm0 + movq mm7, mm1 + pcmpeqw mm0, [eax+ebx*2+colorD] + pcmpeqw mm1, [eax+ebx*2+colorC] + pcmpeqw mm6, mm7 + + movq mm2, mm0 + movq mm3, mm0 + + pand mm0, mm1 // colorA == colorD && colorB == colorC + pxor mm7, mm7 + + pcmpeqw mm2, mm7 + pand mm6, mm0 + pand mm2, mm1 // colorA != colorD && colorB == colorC + + pcmpeqw mm1, mm7 + + pand mm1, mm3 // colorA == colorD && colorB != colorC + pxor mm0, mm6 + por mm1, mm6 + movq mm7, mm0 + movq Mask2, mm2 + packsswb mm7, mm7 + movq Mask1, mm1 + + movd ecx, mm7 + test ecx, ecx + jz nx_2xSaILine_16mmx_skipguess + + //------------------------------ + // Map of the pixels: I|E F|J + // G|A B|K + // H|C D|L + // M|N O|P + //------------------------------ + movq mm6, mm0 + movq mm4, [eax+ebx+colorA] + movq mm5, [eax+ebx+colorB] + pxor mm7, mm7 + pand mm6, ONE + + movq mm0, [eax+colorE] + movq mm1, [eax+ebx+colorG] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [eax+colorF] + movq mm1, [eax+ebx+colorK] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + lea esi, [eax+ebx] + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [esi+ebx+colorH] + movq mm1, [esi+ebx*2+colorN] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [esi+ebx+colorL] + movq mm1, [esi+ebx*2+colorO] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm1, mm7 + pxor mm0, mm0 + pcmpgtw mm7, mm0 + pcmpgtw mm0, mm1 + + por mm7, Mask1 + por mm0, Mask2 + movq Mask1, mm7 + movq Mask2, mm0 + +nx_2xSaILine_16mmx_skipguess: + //------------------------------ + // interpolate A, B, C and D + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx+colorB] + movq mm4, mm0 + movq mm2, [eax+ebx*2+colorC] + movq mm5, mm1 + movq mm3, qMask // qcolorMask + movq mm6, mm2 + movq mm7, lMask // qlowcolorMask + + pand mm0, mm3 + pand mm1, mm3 + pand mm2, mm3 + pand mm3, [eax+ebx*2+colorD] + + psrlw mm0, 2 + pand mm4, mm7 + psrlw mm1, 2 + pand mm5, mm7 + psrlw mm2, 2 + pand mm6, mm7 + psrlw mm3, 2 + pand mm7, [eax+ebx*2+colorD] + + paddw mm0, mm1 + paddw mm2, mm3 + + paddw mm4, mm5 + paddw mm6, mm7 + + paddw mm4, mm6 + movq mm7, lMask // qlowcolorMask + paddw mm0, mm2 + psrlw mm4, 2 + pand mm4, mm7 + paddw mm0, mm4 // mm0 contains the interpolated value of A, B, C and D + + // assemble the pixels + movq mm1, Mask1 + movq mm2, Mask2 + movq mm4, [eax+ebx+colorA] + movq mm5, [eax+ebx+colorB] + pand mm4, mm1 + pand mm5, mm2 + + pxor mm7, mm7 + por mm1, mm2 + por mm4, mm5 + pcmpeqw mm1, mm7 + pand mm0, mm1 + por mm4, mm0 // mm4 contains the diagonal pixels + + movq mm0, ACPixel + mov edi, dstPitch + movq mm1, mm0 + punpcklwd mm0, mm4 + punpckhwd mm1, mm4 + + //------------------------------ + // Write image + //------------------------------ + movq [edx+edi+0], mm0 + movq [edx+edi+8], mm1 + +nx_2xSaILine_16mmx_skipprocess: + add pDlt, 8 // 4 pixels + lea eax, [eax+ 8] // 4 pixels + lea edx, [edx+16] // 8 pixels + sub width, 4 // 4 pixels + jg nx_2xSaILine_16mmx_loop + + emms + } +} + +static void nx_2xSaILine_32bpp_mmx( euI8* pSrc, euI8* pDlt, euI32 srcPitch, euI32 width, euI8* pDst, euI32 dstPitch, euI32 bForceWrite ) +{ + __asm { + mov eax, pSrc + mov ebx, srcPitch + mov edx, pDst + sub eax, ebx +nx_2xSaILine_32mmx_loop: + mov ecx, bForceWrite + test ecx, ecx + jz nx_2xSaILine_32mmx_normal + + mov esi, pDlt + movq mm6, [eax+colorI] + movq [esi+colorI], mm6 + + jmp nx_2xSaILine_32mmx_forcewrite +nx_2xSaILine_32mmx_normal: + // Check delta + mov ecx, pDlt + + // load source img + lea esi, [eax+ebx] + movq mm0, [eax+colorI] + movq mm1, [eax+colorJ] + movq mm2, [eax+ebx+colorG] + movq mm3, [eax+ebx+colorK] + movq mm4, [eax+ebx*2+colorH] + movq mm5, [eax+ebx*2+colorL] + movq mm6, [esi+ebx*2+colorM] + movq mm7, [esi+ebx*2+colorP] + + // compare to delta + lea esi, [ecx+ebx] + pcmpeqw mm0, [ecx+colorI] + pcmpeqw mm1, [ecx+colorJ] + pcmpeqw mm2, [ecx+ebx+colorG] + pcmpeqw mm3, [ecx+ebx+colorK] + pcmpeqw mm4, [ecx+ebx*2+colorH] + pcmpeqw mm5, [ecx+ebx*2+colorL] + pcmpeqw mm6, [esi+ebx*2+colorM] + pcmpeqw mm7, [esi+ebx*2+colorP] + + // compose results + pand mm0, mm1 + pand mm2, mm3 + pand mm4, mm5 + pand mm6, mm7 + pand mm0, mm2 + pand mm4, mm6 + pxor mm7, mm7 + pand mm0, mm4 + movq mm6, [eax+colorI] + pcmpeqw mm7, mm0 + + movq [ecx+colorI], mm6 + + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_2xSaILine_32mmx_skipprocess + // End Delta +nx_2xSaILine_32mmx_forcewrite: + //------------------------------ + // 1 + // if ((colorA == colorD) && (colorB != colorC) && (colorA == colorE) && (colorB == colorL) + movq mm0, [eax+ebx+colorA] // mm0 and mm1 contain colorA + movq mm2, [eax+ebx+colorB] // mm2 and mm3 contain colorB + + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [eax+ebx*2+colorD] + pcmpeqw mm1, [eax+colorE] + pcmpeqw mm2, [eax+ebx*2+colorL] + pcmpeqw mm3, [eax+ebx*2+colorC] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorA == colorC) && (colorB != colorE) && (colorA == colorF) && (colorB == colorJ) + movq mm4, [eax+ebx+colorA] // mm4 and mm5 contain colorA + movq mm6, [eax+ebx+colorB] // mm6 and mm7 contain colorB + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [eax+ebx*2+colorC] + pcmpeqw mm5, [eax+colorF] + pcmpeqw mm6, [eax+colorJ] + pcmpeqw mm7, [eax+colorE] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 // combine the masks + movq Mask1, mm0 + + //------------------------------ + // 2 + // if ((colorB == colorC) && (colorA != colorD) && (colorB == colorF) && (colorA == colorH) + movq mm0, [eax+ebx+colorB] // mm0 and mm1 contain colorB + movq mm2, [eax+ebx+colorA] // mm2 and mm3 contain colorA + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [eax+ebx*2+colorC] + pcmpeqw mm1, [eax+colorF] + pcmpeqw mm2, [eax+ebx*2+colorH] + pcmpeqw mm3, [eax+ebx*2+colorD] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI) + movq mm4, [eax+ebx+colorB] // mm4 and mm5 contain colorB + movq mm6, [eax+ebx+colorA] // mm6 and mm7 contain colorA + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [eax+ebx*2+colorD] + pcmpeqw mm5, [eax+colorE] + pcmpeqw mm6, [eax+colorI] + pcmpeqw mm7, [eax+colorF] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 // combine the masks + movq Mask2, mm0 + + //------------------------------ + // interpolate colorA and colorB + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx+colorB] + movq mm2, mm0 + movq mm3, mm1 + + movq mm6, cMask + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 // mm0 contains the interpolated values + + // assemble the pixels + movq mm1, [eax+ebx+colorA] + movq mm2, [eax+ebx+colorB] + + movq mm3, Mask1 + movq mm5, mm1 + movq mm4, Mask2 + movq mm6, mm1 + + pand mm1, mm3 + por mm3, mm4 + pxor mm7, mm7 + pand mm2, mm4 + + pcmpeqw mm3, mm7 + por mm1, mm2 + pand mm0, mm3 + + por mm0, mm1 + + punpcklwd mm5, mm0 + punpckhwd mm6, mm0 + + //------------------------------ + // Write image + //------------------------------ + // save + mov esi, eax + mov edi, ebx + mov ecx, 0x00F8F8F8 // mask + +// movq [edx+0], mm5 + + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+0], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+4], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+8], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+12], ebx + +// movq [edx+8], mm6 + + movd eax, mm6 + movd ebx, mm6 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm6, 16 + mov [edx+16], ebx + movd eax, mm6 + movd ebx, mm6 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm6, 16 + mov [edx+20], ebx + movd eax, mm6 + movd ebx, mm6 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm6, 16 + mov [edx+24], ebx + movd eax, mm6 + movd ebx, mm6 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+28], ebx + + // restore + mov eax, esi + mov ebx, edi + + //------------------------------ + // Create the Nextline + //------------------------------ + // 3 + // if ((colorA == colorD) && (colorB != colorC) && (colorA == colorG) && (colorC == colorO) + lea esi, [eax+ebx] + + movq mm0, [eax+ebx+colorA] // mm0 and mm1 contain colorA + movq mm2, [eax+ebx*2+colorC] // mm2 and mm3 contain colorC + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [esi+ebx+colorD] + pcmpeqw mm1, [esi+colorG] + pcmpeqw mm2, [esi+ebx*2+colorO] + pcmpeqw mm3, [esi+colorB] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorA == colorB) && (colorG != colorC) && (colorA == colorH) && (colorC == colorM) + movq mm4, [eax+ebx+colorA] // mm4 and mm5 contain colorA + movq mm6, [eax+ebx*2+colorC] // mm6 and mm7 contain colorC + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [esi+ebx+colorH] + pcmpeqw mm5, [esi+colorB] + pcmpeqw mm6, [esi+ebx*2+colorM] + pcmpeqw mm7, [esi+colorG] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 // combine the masks + movq Mask1, mm0 + + //------------------------------ + // 4 + // if ((colorB == colorC) && (colorA != colorD) && (colorC == colorH) && (colorA == colorF) + movq mm0, [eax+ebx*2+colorC] // mm0 and mm1 contain colorC + movq mm2, [eax+ebx+colorA] // mm2 and mm3 contain colorA + movq mm1, mm0 + movq mm3, mm2 + + pcmpeqw mm0, [eax+ebx+colorB] + pcmpeqw mm1, [eax+ebx*2+colorH] + pcmpeqw mm2, [eax+colorF] + pcmpeqw mm3, [eax+ebx*2+colorD] + + pand mm0, mm1 + pxor mm1, mm1 + pand mm0, mm2 + pcmpeqw mm3, mm1 + pand mm0, mm3 // result in mm0 + + // if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI) + movq mm4, [eax+ebx*2+colorC] // mm4 and mm5 contain colorC + movq mm6, [eax+ebx+colorA] // mm6 and mm7 contain colorA + movq mm5, mm4 + movq mm7, mm6 + + pcmpeqw mm4, [eax+ebx*2+colorD] + pcmpeqw mm5, [eax+ebx+colorG] + pcmpeqw mm6, [eax+colorI] + pcmpeqw mm7, [eax+ebx*2+colorH] + + pand mm4, mm5 + pxor mm5, mm5 + pand mm4, mm6 + pcmpeqw mm7, mm5 + pand mm4, mm7 // result in mm4 + + por mm0, mm4 ;combine the masks + movq Mask2, mm0 + + //------------------------------ + // interpolate colorA and colorC + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx*2+colorC] + movq mm2, mm0 + movq mm3, mm1 + + movq mm6, cMask + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 // mm0 contains the interpolated values + + // assemble the pixels + movq mm1, [eax+ebx+colorA] + movq mm2, [eax+ebx*2+colorC] + + movq mm3, Mask1 + movq mm4, Mask2 + + pand mm1, mm3 + pand mm2, mm4 + + por mm3, mm4 + pxor mm7, mm7 + por mm1, mm2 + + pcmpeqw mm3, mm7 + pand mm0, mm3 + por mm0, mm1 + movq ACPixel, mm0 + + //------------------------------ + // Decide which "branch" to take + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx+colorB] + movq mm6, mm0 + movq mm7, mm1 + pcmpeqw mm0, [eax+ebx*2+colorD] + pcmpeqw mm1, [eax+ebx*2+colorC] + pcmpeqw mm6, mm7 + + movq mm2, mm0 + movq mm3, mm0 + + pand mm0, mm1 // colorA == colorD && colorB == colorC + pxor mm7, mm7 + + pcmpeqw mm2, mm7 + pand mm6, mm0 + pand mm2, mm1 // colorA != colorD && colorB == colorC + + pcmpeqw mm1, mm7 + + pand mm1, mm3 // colorA == colorD && colorB != colorC + pxor mm0, mm6 + por mm1, mm6 + movq mm7, mm0 + movq Mask2, mm2 + packsswb mm7, mm7 + movq Mask1, mm1 + + movd ecx, mm7 + test ecx, ecx + jz nx_2xSaILine_32mmx_skipguess + + //------------------------------ + // Map of the pixels: I|E F|J + // G|A B|K + // H|C D|L + // M|N O|P + //------------------------------ + movq mm6, mm0 + movq mm4, [eax+ebx+colorA] + movq mm5, [eax+ebx+colorB] + pxor mm7, mm7 + pand mm6, ONE + + movq mm0, [eax+colorE] + movq mm1, [eax+ebx+colorG] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [eax+colorF] + movq mm1, [eax+ebx+colorK] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + lea esi, [eax+ebx] + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [esi+ebx+colorH] + movq mm1, [esi+ebx*2+colorN] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [esi+ebx+colorL] + movq mm1, [esi+ebx*2+colorO] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm1, mm7 + pxor mm0, mm0 + pcmpgtw mm7, mm0 + pcmpgtw mm0, mm1 + + por mm7, Mask1 + por mm0, Mask2 + movq Mask1, mm7 + movq Mask2, mm0 + +nx_2xSaILine_32mmx_skipguess: + //------------------------------ + // interpolate A, B, C and D + //------------------------------ + movq mm0, [eax+ebx+colorA] + movq mm1, [eax+ebx+colorB] + movq mm4, mm0 + movq mm2, [eax+ebx*2+colorC] + movq mm5, mm1 + movq mm3, qMask // qcolorMask + movq mm6, mm2 + movq mm7, lMask // qlowcolorMask + + pand mm0, mm3 + pand mm1, mm3 + pand mm2, mm3 + pand mm3, [eax+ebx*2+colorD] + + psrlw mm0, 2 + pand mm4, mm7 + psrlw mm1, 2 + pand mm5, mm7 + psrlw mm2, 2 + pand mm6, mm7 + psrlw mm3, 2 + pand mm7, [eax+ebx*2+colorD] + + paddw mm0, mm1 + paddw mm2, mm3 + + paddw mm4, mm5 + paddw mm6, mm7 + + paddw mm4, mm6 + movq mm7, lMask // qlowcolorMask + paddw mm0, mm2 + psrlw mm4, 2 + pand mm4, mm7 + paddw mm0, mm4 // mm0 contains the interpolated value of A, B, C and D + + // assemble the pixels + movq mm1, Mask1 + movq mm2, Mask2 + movq mm4, [eax+ebx+colorA] + movq mm5, [eax+ebx+colorB] + pand mm4, mm1 + pand mm5, mm2 + + pxor mm7, mm7 + por mm1, mm2 + por mm4, mm5 + pcmpeqw mm1, mm7 + pand mm0, mm1 + por mm4, mm0 // mm4 contains the diagonal pixels + + movq mm0, ACPixel + mov edi, dstPitch + movq mm1, mm0 + punpcklwd mm0, mm4 + punpckhwd mm1, mm4 + + //------------------------------ + // Write image RGB1555->RGBx888 + //------------------------------ + // save + movd mm6, eax + movd mm7, ebx + mov ecx, 0x00F8F8F8 // mask + +// movq [edx+edi+0], mm0 + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+edi+0], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+edi+4], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+edi+8], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+edi+12], ebx + +// movq [edx+edi+8], mm1 + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+edi+16], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+edi+20], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+edi+24], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+edi+28], ebx + + // restore + movd eax, mm6 + movd ebx, mm7 + +nx_2xSaILine_32mmx_skipprocess: + add pDlt, 8 // 4 pixels + lea eax, [eax+ 8] // 4 pixels + lea edx, [edx+32] // 8 pixels + sub width, 4 // 4 pixels + jg nx_2xSaILine_32mmx_loop + + emms + } +} diff --git a/References/VirtuaNESex_src_191105/nx_Scale2x.h b/References/VirtuaNESex_src_191105/nx_Scale2x.h new file mode 100644 index 00000000..b6721520 --- /dev/null +++ b/References/VirtuaNESex_src_191105/nx_Scale2x.h @@ -0,0 +1,442 @@ +/* + * This file is part of the Advance project. + * + * Copyright (C) 1999-2002 Andrea Mazzoleni + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * This file contains a C and MMX implentation of the Scale2x effect. + * + * You can found an high level description of the effect at : + * + * http://scale2x.sourceforge.net/scale2x.html + * + * Alternatively at the previous license terms, you are allowed to use this + * code in your program with these conditions: + * - the program is not used in commercial activities. + * - the whole source code of the program is released with the binary. + * - derivative works of the program are allowed. + */ + +// Note +// +// This code has deleted most from the original code. +// An original code is acquirable from the website of Advanced project. +// MS VisualC++ and ProcessorPack are required for compile of this code. +// +static void internal_scale2x_16_mmx_single(euI16* dst, const euI16* src0, const euI16* src1, const euI16* src2, unsigned count) +{ + /* always do the first and last run */ + count -= 2*4; + + __asm { + mov eax, src0 + mov ebx, src1 + mov ecx, src2 + mov edx, dst + mov esi, count + + /* first run */ + /* set the current, current_pre, current_next registers */ + pxor mm0, mm0 /* use a fake black out of screen */ + movq mm7, qword ptr [ebx+0] + movq mm1, qword ptr [ebx+8] + psrlq mm0, 48 + psllq mm1, 48 + movq mm2, mm7 + movq mm3, mm7 + psllq mm2, 16 + psrlq mm3, 16 + por mm0, mm2 + por mm1, mm3 + + /* current_upper */ + movq mm6, qword ptr [eax] + + /* compute the upper-left pixel for dst0 on %%mm2 */ + /* compute the upper-right pixel for dst0 on %%mm4 */ + movq mm2, mm0 + movq mm4, mm1 + movq mm3, mm0 + movq mm5, mm1 + pcmpeqw mm2, mm6 + pcmpeqw mm4, mm6 + pcmpeqw mm3, qword ptr [ecx] + pcmpeqw mm5, qword ptr [ecx] + pandn mm3, mm2 + pandn mm5, mm4 + movq mm2, mm0 + movq mm4, mm1 + pcmpeqw mm2, mm1 + pcmpeqw mm4, mm0 + pandn mm2, mm3 + pandn mm4, mm5 + movq mm3, mm2 + movq mm5, mm4 + pand mm2, mm6 + pand mm4, mm6 + pandn mm3, mm7 + pandn mm5, mm7 + por mm2, mm3 + por mm4, mm5 + + /* set *dst0 */ + movq mm3, mm2 + punpcklwd mm2, mm4 + punpckhwd mm3, mm4 + movq qword ptr [edx+0], mm2 + movq qword ptr [edx+8], mm3 + + /* next */ + add eax, 8 + add ebx, 8 + add ecx, 8 + add edx, 16 + + /* central runs */ + shr esi, 2 + jz label1 + align 4 +label0: + + /* set the current, current_pre, current_next registers */ + movq mm0, qword ptr [ebx-8] + movq mm7, qword ptr [ebx+0] + movq mm1, qword ptr [ebx+8] + psrlq mm0, 48 + psllq mm1, 48 + movq mm2, mm7 + movq mm3, mm7 + psllq mm2, 16 + psrlq mm3, 16 + por mm0, mm2 + por mm1, mm3 + + /* current_upper */ + movq mm6, qword ptr [eax] + + /* compute the upper-left pixel for dst0 on %%mm2 */ + /* compute the upper-right pixel for dst0 on %%mm4 */ + movq mm2, mm0 + movq mm4, mm1 + movq mm3, mm0 + movq mm5, mm1 + pcmpeqw mm2, mm6 + pcmpeqw mm4, mm6 + pcmpeqw mm3, qword ptr [ecx] + pcmpeqw mm5, qword ptr [ecx] + pandn mm3, mm2 + pandn mm5, mm4 + movq mm2, mm0 + movq mm4, mm1 + pcmpeqw mm2, mm1 + pcmpeqw mm4, mm0 + pandn mm2, mm3 + pandn mm4, mm5 + movq mm3, mm2 + movq mm5, mm4 + pand mm2, mm6 + pand mm4, mm6 + pandn mm3, mm7 + pandn mm5, mm7 + por mm2, mm3 + por mm4, mm5 + + /* set *dst0 */ + movq mm3, mm2 + punpcklwd mm2, mm4 + punpckhwd mm3, mm4 + movq qword ptr [edx+0], mm2 + movq qword ptr [edx+8], mm3 + + /* next */ + add eax, 8 + add ebx, 8 + add ecx, 8 + add edx, 16 + + dec esi + jnz label0 +label1: + /* final run */ + /* set the current, current_pre, current_next registers */ + movq mm0, qword ptr [ebx-8] + movq mm7, qword ptr [ebx+0] + pxor mm1, mm1 /* use a fake black out of screen */ + psrlq mm0, 48 + psllq mm1, 48 + movq mm2, mm7 + movq mm3, mm7 + psllq mm2, 16 + psrlq mm3, 16 + por mm0, mm2 + por mm1, mm3 + + /* current_upper */ + movq mm6, qword ptr [eax] + + /* compute the upper-left pixel for dst0 on %%mm2 */ + /* compute the upper-right pixel for dst0 on %%mm4 */ + movq mm2, mm0 + movq mm4, mm1 + movq mm3, mm0 + movq mm5, mm1 + pcmpeqw mm2, mm6 + pcmpeqw mm4, mm6 + pcmpeqw mm3, qword ptr [ecx] + pcmpeqw mm5, qword ptr [ecx] + pandn mm3, mm2 + pandn mm5, mm4 + movq mm2, mm0 + movq mm4, mm1 + pcmpeqw mm2, mm1 + pcmpeqw mm4, mm0 + pandn mm2, mm3 + pandn mm4, mm5 + movq mm3, mm2 + movq mm5, mm4 + pand mm2, mm6 + pand mm4, mm6 + pandn mm3, mm7 + pandn mm5, mm7 + por mm2, mm3 + por mm4, mm5 + + /* set *dst0 */ + movq mm3, mm2 + punpcklwd mm2, mm4 + punpckhwd mm3, mm4 + movq qword ptr [edx+0], mm2 + movq qword ptr [edx+8], mm3 + + mov src0, eax + mov src1, ebx + mov src2, ecx + mov dst, edx + mov count, esi + + emms + } +} + +static void internal_scale2x_32_mmx_single(euI32* dst, const euI32* src0, const euI32* src1, const euI32* src2, unsigned count) +{ + /* always do the first and last run */ + count -= 2*2; + + __asm { + mov eax, src0 + mov ebx, src1 + mov ecx, src2 + mov edx, dst + mov esi, count + + /* first run */ + /* set the current, current_pre, current_next registers */ + pxor mm0, mm0 + movq mm7, qword ptr [ebx+0] + movq mm1, qword ptr [ebx+8] + psrlq mm0, 32 + psllq mm1, 32 + movq mm2, mm7 + movq mm3, mm7 + psllq mm2, 32 + psrlq mm3, 32 + por mm0, mm2 + por mm1, mm3 + + /* current_upper */ + movq mm6, qword ptr [eax] + + /* compute the upper-left pixel for dst0 on %%mm2 */ + /* compute the upper-right pixel for dst0 on %%mm4 */ + movq mm2, mm0 + movq mm4, mm1 + movq mm3, mm0 + movq mm5, mm1 + pcmpeqd mm2, mm6 + pcmpeqd mm4, mm6 + pcmpeqd mm3, qword ptr [ecx] + pcmpeqd mm5, qword ptr [ecx] + pandn mm3, mm2 + pandn mm5, mm4 + movq mm2, mm0 + movq mm4, mm1 + pcmpeqd mm2, mm1 + pcmpeqd mm4, mm0 + pandn mm2, mm3 + pandn mm4, mm5 + movq mm3, mm2 + movq mm5, mm4 + pand mm2, mm6 + pand mm4, mm6 + pandn mm3, mm7 + pandn mm5, mm7 + por mm2, mm3 + por mm4, mm5 + + /* set *dst0 */ + movq mm3, mm2 + punpckldq mm2, mm4 + punpckhdq mm3, mm4 + movq qword ptr [edx+0], mm2 + movq qword ptr [edx+8], mm3 + + /* next */ + add eax, 8 + add ebx, 8 + add ecx, 8 + add edx, 16 + + /* central runs */ + shr esi, 1 + jz label1 +label0: + + /* set the current, current_pre, current_next registers */ + movq mm0, qword ptr [ebx-8] + movq mm7, qword ptr [ebx+0] + movq mm1, qword ptr [ebx+8] + psrlq mm0, 32 + psllq mm1, 32 + movq mm2, mm7 + movq mm3, mm7 + psllq mm2, 32 + psrlq mm3, 32 + por mm0, mm2 + por mm1, mm3 + + /* current_upper */ + movq mm6, qword ptr[eax] + + /* compute the upper-left pixel for dst0 on %%mm2 */ + /* compute the upper-right pixel for dst0 on %%mm4 */ + movq mm2, mm0 + movq mm4, mm1 + movq mm3, mm0 + movq mm5, mm1 + pcmpeqd mm2, mm6 + pcmpeqd mm4, mm6 + pcmpeqd mm3, qword ptr[ecx] + pcmpeqd mm5, qword ptr[ecx] + pandn mm3, mm2 + pandn mm5, mm4 + movq mm2, mm0 + movq mm4, mm1 + pcmpeqd mm2, mm1 + pcmpeqd mm4, mm0 + pandn mm2, mm3 + pandn mm4, mm5 + movq mm3, mm2 + movq mm5, mm4 + pand mm2, mm6 + pand mm4, mm6 + pandn mm3, mm7 + pandn mm5, mm7 + por mm2, mm3 + por mm4, mm5 + + /* set *dst0 */ + movq mm3, mm2 + punpckldq mm2, mm4 + punpckhdq mm3, mm4 + movq qword ptr [edx+0], mm2 + movq qword ptr [edx+8], mm3 + + /* next */ + add eax, 8 + add ebx, 8 + add ecx, 8 + add edx, 16 + + dec esi + jnz label0 +label1: + + /* final run */ + /* set the current, current_pre, current_next registers */ + movq mm0, qword ptr [ebx-8] + movq mm7, qword ptr [ebx+0] + pxor mm1, mm1 + psrlq mm0, 32 + psllq mm1, 32 + movq mm2, mm7 + movq mm3, mm7 + psllq mm2, 32 + psrlq mm3, 32 + por mm0, mm2 + por mm1, mm3 + + /* current_upper */ + movq mm6, qword ptr [eax] + + /* compute the upper-left pixel for dst0 on %%mm2 */ + /* compute the upper-right pixel for dst0 on %%mm4 */ + movq mm2, mm0 + movq mm4, mm1 + movq mm3, mm0 + movq mm5, mm1 + pcmpeqd mm2, mm6 + pcmpeqd mm4, mm6 + pcmpeqd mm3, qword ptr [ecx] + pcmpeqd mm5, qword ptr [ecx] + pandn mm3, mm2 + pandn mm5, mm4 + movq mm2, mm0 + movq mm4, mm1 + pcmpeqd mm2, mm1 + pcmpeqd mm4, mm0 + pandn mm2, mm3 + pandn mm4, mm5 + movq mm3, mm2 + movq mm5, mm4 + pand mm2, mm6 + pand mm4, mm6 + pandn mm3, mm7 + pandn mm5, mm7 + por mm2, mm3 + por mm4, mm5 + + /* set *dst0 */ + movq mm3, mm2 + punpckldq mm2, mm4 + punpckhdq mm3, mm4 + movq qword ptr [edx+0], mm2 + movq qword ptr [edx+8], mm3 + + mov src0, eax + mov src1, ebx + mov src2, ecx + mov dst, edx + mov count, esi + + emms + } +} + +static void internal_scale2x_16_mmx(euI16* dst0, euI16* dst1, const euI16* src0, const euI16* src1, const euI16* src2, unsigned count) +{ + internal_scale2x_16_mmx_single(dst0, src0, src1, src2, count); + internal_scale2x_16_mmx_single(dst1, src2, src1, src0, count); +} + +static void internal_scale2x_32_mmx(euI32* dst0, euI32* dst1, const euI32* src0, const euI32* src1, const euI32* src2, unsigned count) +{ + internal_scale2x_32_mmx_single(dst0, src0, src1, src2, count); + internal_scale2x_32_mmx_single(dst1, src2, src1, src0, count); +} + diff --git a/References/VirtuaNESex_src_191105/nx_Super2xSaI.h b/References/VirtuaNESex_src_191105/nx_Super2xSaI.h new file mode 100644 index 00000000..c61c6bf8 --- /dev/null +++ b/References/VirtuaNESex_src_191105/nx_Super2xSaI.h @@ -0,0 +1,1320 @@ +/*---------------------------------------------------------------------* + * The following (piece of) code, (part of) the 2xSaI engine, * + * copyright (c) 2001 by Derek Liauw Kie Fa. * + * Non-Commercial use of the engine is allowed and is encouraged, * + * provided that appropriate credit be given and that this copyright * + * notice will not be removed under any circumstance. * + * You may freely modify this code, but I request * + * that any improvements to the engine be submitted to me, so * + * that I can implement these improvements in newer versions of * + * the engine. * + * If you need more information, have any comments or suggestions, * + * you can e-mail me. My e-mail: DerekL666@yahoo.com * + *---------------------------------------------------------------------*/ +// +// This code was converted into VirtuaNES by Norix. +// +static void nx_Super2xSaILine_16bpp_mmx( euI8* pSrc, euI8* pDlt, euI32 srcPitch, euI32 width, euI8* pDst, euI32 dstPitch, euI32 bForceWrite ) +{ + __asm { + mov eax, pSrc + mov ebx, srcPitch + mov edx, pDst + sub eax, ebx +nx_Super2xSaILine_16mmx_loop: + mov ecx, bForceWrite + test ecx, ecx + jz nx_Super2xSaILine_16mmx_normal + + mov esi, pDlt + movq mm6, [eax+colorB0] +#if 0 + movq [esi+2+colorB0], mm6 +#else + movq [esi+colorB0], mm6 +#endif + + jmp nx_Super2xSaILine_16mmx_forcewrite +nx_Super2xSaILine_16mmx_normal: + // Check delta + mov ecx, pDlt + + // load source img + lea esi, [eax+ebx] + movq mm0, [eax+colorB0] + movq mm1, [eax+colorB3] + movq mm2, [eax+ebx+color4] + movq mm3, [eax+ebx+colorS2] + movq mm4, [eax+ebx*2+color1] + movq mm5, [eax+ebx*2+colorS1] + movq mm6, [esi+ebx*2+colorA0] + movq mm7, [esi+ebx*2+colorA3] + + // compare to delta + lea esi, [ecx+ebx] +#if 0 + pcmpeqw mm0, [ecx+2+colorB0] + pcmpeqw mm1, [ecx+2+colorB3] + pcmpeqw mm2, [ecx+ebx+2+color4] + pcmpeqw mm3, [ecx+ebx+2+colorS2] + pcmpeqw mm4, [ecx+ebx*2+2+color1] + pcmpeqw mm5, [ecx+ebx*2+2+colorS1] + pcmpeqw mm6, [esi+ebx*2+2+colorA0] + pcmpeqw mm7, [esi+ebx*2+2+colorA3] +#else + pcmpeqw mm0, [ecx+colorB0] + pcmpeqw mm1, [ecx+colorB3] + pcmpeqw mm2, [ecx+ebx+color4] + pcmpeqw mm3, [ecx+ebx+colorS2] + pcmpeqw mm4, [ecx+ebx*2+color1] + pcmpeqw mm5, [ecx+ebx*2+colorS1] + pcmpeqw mm6, [esi+ebx*2+colorA0] + pcmpeqw mm7, [esi+ebx*2+colorA3] +#endif + + // compose results + pand mm0, mm1 + pand mm2, mm3 + pand mm4, mm5 + pand mm6, mm7 + pand mm0, mm2 + pand mm4, mm6 + pxor mm7, mm7 + pand mm0, mm4 + movq mm6, [eax+colorB0] + pcmpeqw mm7, mm0 + +#if 0 + movq [ecx+2+colorB0], mm6 +#else + movq [ecx+colorB0], mm6 +#endif + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_Super2xSaILine_16mmx_skipprocess + // End Delta +nx_Super2xSaILine_16mmx_forcewrite: + //------------------------------ + // Interpolate pixels + // (c0&c1)+(((c0^c1)&colorMask)>>1) + //------------------------------ + movq mm6, cMask + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I56Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + movq I5556Pixel, mm0 + paddw mm1, mm3 + movq I5666Pixel, mm1 + + //------------------------------ + //------------------------------ + movq mm0, [eax+ebx*2+color2] + movq mm1, [eax+ebx*2+color3] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I23Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + movq I2223Pixel, mm0 + paddw mm1, mm3 + movq I2333Pixel, mm1 + + //------------------------------ + // Decide which "branch" to take + //------------------------------ + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm6, mm0 + movq mm7, mm1 + pcmpeqw mm0, [eax+ebx*2+color3] + pcmpeqw mm1, [eax+ebx*2+color2] + pcmpeqw mm6, mm7 + + movq mm2, mm0 + movq mm3, mm0 + + pand mm0, mm1 // colorA == colorD && colorB == colorC + pxor mm7, mm7 + + pcmpeqw mm2, mm7 + pand mm6, mm0 + pand mm2, mm1 // colorA != colorD && colorB == colorC + + pcmpeqw mm1, mm7 + + pand mm1, mm3 // colorA == colorD && colorB != colorC + pxor mm0, mm6 + por mm1, mm6 + movq mm7, mm0 + movq Mask26, mm2 + packsswb mm7, mm7 + movq Mask35, mm1 + + movd ecx, mm7 + test ecx, ecx + jz nx_Super2xSaILine_16mmx_skipguess + + //------------------------------ + movq mm6, mm0 + movq mm4, [eax+ebx+color5] // colorA + movq mm5, [eax+ebx+color6] // colorB + pxor mm7, mm7 + pand mm6, ONE + + movq mm0, [eax+colorB1] // colorE + movq mm1, [eax+ebx+color4] // colorG + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [eax+colorB2] // colorF + movq mm1, [eax+ebx+colorS2] // colorK + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + lea edi, [eax+ebx] + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+color1] // colorH + movq mm1, [edi+ebx*2+colorA1] // colorN + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+colorS1] // colorL + movq mm1, [edi+ebx*2+colorA2] // colorO + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm1, mm7 + pxor mm0, mm0 + pcmpgtw mm7, mm0 + pcmpgtw mm0, mm1 + + por mm7, Mask35 + por mm0, Mask26 + movq Mask35, mm7 + movq Mask26, mm0 + +nx_Super2xSaILine_16mmx_skipguess: + + // Start the ASSEMBLY !!! eh... compose all the results together to form the final image... + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx*2+color2] + movq mm2, mm0 + + pand mm0, mm1 + pxor mm2, mm1 + pand mm2, cMask + psrlw mm2, 1 + paddw mm0, mm2 + + //------------------------------ + movq mm7, Mask26 + movq mm6, [eax+colorB2] + movq mm5, [eax+ebx*2+color2] + movq mm4, [eax+ebx*2+color1] + pcmpeqw mm4, mm5 + pcmpeqw mm6, mm5 + pxor mm5, mm5 + pand mm7, mm4 + pcmpeqw mm6, mm5 + pand mm7, mm6 + + movq mm6, [eax+ebx*2+color3] + movq mm5, [eax+ebx*2+color2] + movq mm4, [eax+ebx*2+color1] + movq mm2, [eax+ebx+color5] + movq mm1, [eax+ebx+color4] + movq mm3, [eax+colorB0] + + pcmpeqw mm2, mm4 + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm3, mm5 + pxor mm5, mm5 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm6, mm1 + pand mm2, mm3 + pand mm6, mm2 + por mm7, mm6 + + movq mm6, mm7 + pcmpeqw mm6, mm5 + pand mm7, mm0 + + movq mm1, [eax+ebx+color5] + pand mm6, mm1 + por mm7, mm6 + movq final1a, mm7 // finished 1a + + //------------------------------ + lea esi, [eax+ebx] + movq mm7, Mask35 + movq mm6, [esi+ebx*2+colorA2] + + movq mm5, [eax+ebx+color5] + movq mm4, [eax+ebx+color4] + pcmpeqw mm4, mm5 + pcmpeqw mm6, mm5 + pxor mm5, mm5 + pand mm7, mm4 + pcmpeqw mm6, mm5 + pand mm7, mm6 + + movq mm6, [eax+ebx+color6] + movq mm5, [eax+ebx+color5] + movq mm4, [eax+ebx+color4] + movq mm2, [eax+ebx*2+color2] + movq mm1, [eax+ebx*2+color1] + movq mm3, [esi+ebx*2+colorA0] + + pcmpeqw mm2, mm4 + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm3, mm5 + pxor mm5, mm5 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm6, mm1 + pand mm2, mm3 + pand mm6, mm2 + por mm7, mm6 + + movq mm6, mm7 + pcmpeqw mm6, mm5 + pand mm7, mm0 + + movq mm1, [eax+ebx*2+color2] + pand mm6, mm1 + por mm7, mm6 + movq final2a, mm7 // finished 2a + + pxor mm7, mm7 + movq mm0, [esi+ebx*2+colorA0] + movq mm1, [esi+ebx*2+colorA1] + movq mm2, [esi+ebx*2+colorA2] + movq mm3, [esi+ebx*2+colorA3] + movq mm4, [eax+ebx*2+color2] + movq mm5, [eax+ebx*2+color3] + movq mm6, [eax+ebx+color6] + + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm4, mm2 + pcmpeqw mm0, mm5 + pcmpeqw mm4, mm7 + pcmpeqw mm0, mm7 + pand mm0, mm4 + pand mm6, mm1 + pand mm0, mm6 + + movq mm1, [esi+ebx*2+colorA1] + movq mm4, [eax+ebx*2+color2] + movq mm5, [eax+ebx+color5] + movq mm6, [eax+ebx*2+color3] + + pcmpeqw mm5, mm4 + pcmpeqw mm2, mm4 + pcmpeqw mm1, mm6 + pcmpeqw mm3, mm4 + pcmpeqw mm1, mm7 + pcmpeqw mm3, mm7 + pand mm2, mm5 + pand mm1, mm3 + pand mm1, mm2 + + movq mm7, mm0 + por mm7, mm1 + + movq mm4, Mask35 + movq mm3, Mask26 + + movq mm6, mm4 + pand mm6, mm7 + pxor mm4, mm6 + + movq mm6, mm3 + pand mm6, mm7 + pxor mm3, mm6 + + movq mm2, mm0 + movq mm7, I2333Pixel + movq mm6, I2223Pixel + movq mm5, I23Pixel + + por mm2, mm4 + pand mm4, [eax+ebx*2+color3] + por mm2, mm3 + pand mm3, [eax+ebx*2+color2] + por mm2, mm1 + pand mm0, mm7 + pand mm1, mm6 + pxor mm7, mm7 + pcmpeqw mm2, mm7 + por mm0, mm1 + por mm3, mm4 + pand mm2, mm5 + por mm0, mm3 + por mm0, mm2 + movq final2b, mm0 + + //------------------------------ + pxor mm7, mm7 + movq mm0, [eax+colorB0] + movq mm1, [eax+colorB1] + movq mm2, [eax+colorB2] + movq mm3, [eax+colorB3] + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx+color6] + movq mm6, [eax+ebx*2+color3] + + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm4, mm2 + pcmpeqw mm0, mm5 + pcmpeqw mm4, mm7 + pcmpeqw mm0, mm7 + pand mm0, mm4 + pand mm6, mm1 + pand mm0, mm6 + + movq mm1, [eax+colorB1] + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx*2+color2] + movq mm6, [eax+ebx+color6] + + pcmpeqw mm5, mm4 + pcmpeqw mm2, mm4 + pcmpeqw mm1, mm6 + pcmpeqw mm3, mm4 + pcmpeqw mm1, mm7 + pcmpeqw mm3, mm7 + pand mm2, mm5 + pand mm1, mm3 + pand mm1, mm2 + + + movq mm7, mm0 + por mm7, mm1 + + movq mm4, Mask35 + movq mm3, Mask26 + + movq mm6, mm4 + pand mm6, mm7 + pxor mm4, mm6 + + movq mm6, mm3 + pand mm6, mm7 + pxor mm3, mm6 + + movq mm2, mm0 + movq mm7, I5666Pixel + movq mm6, I5556Pixel + movq mm5, I56Pixel + + por mm2, mm4 + pand mm4, [eax+ebx+color5] + por mm2, mm3 + pand mm3, [eax+ebx+color6] + por mm2, mm1 + pand mm0, mm7 + pand mm1, mm6 + pxor mm7, mm7 + pcmpeqw mm2, mm7 + por mm0, mm1 + por mm3, mm4 + pand mm2, mm5 + por mm0, mm3 + por mm0, mm2 + movq final1b, mm0 + + //------------------------------ + // Write final image + //------------------------------ + movq mm0, final1a + movq mm4, final2a + movq mm2, final1b + movq mm6, final2b + + movq mm1, mm0 + movq mm5, mm4 + + punpcklwd mm0, mm2 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm1, mm2 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + punpcklwd mm4, mm6 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm5, mm6 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + + mov edi, dstPitch + movq [edx+0], mm0 // 1st line + movq [edx+8], mm1 + movq [edi+edx+0], mm4 // 2nd line + movq [edi+edx+8], mm5 + +nx_Super2xSaILine_16mmx_skipprocess: + add pDlt, 8 // 4 pixels + add eax, 8 // 4 pixels + add edx, 16 // 8 pixels + sub width, 4 // 4 pixels + jg nx_Super2xSaILine_16mmx_loop + + emms + } +} + + +static void nx_Super2xSaILine_32bpp_mmx( euI8* pSrc, euI8* pDlt, euI32 srcPitch, euI32 width, euI8* pDst, euI32 dstPitch, euI32 bForceWrite ) +{ + __asm { + mov eax, pSrc + mov ebx, srcPitch + mov edx, pDst + sub eax, ebx +nx_Super2xSaILine_32mmx_loop: + mov ecx, bForceWrite + test ecx, ecx + jz nx_Super2xSaILine_32mmx_normal + + mov esi, pDlt + movq mm6, [eax+colorB0] +#if 0 + movq [esi+2+colorB0], mm6 +#else + movq [esi+colorB0], mm6 +#endif + + jmp nx_Super2xSaILine_32mmx_forcewrite +nx_Super2xSaILine_32mmx_normal: + // Check delta + mov ecx, pDlt + + // load source img + lea esi, [eax+ebx] + movq mm0, [eax+colorB0] + movq mm1, [eax+colorB3] + movq mm2, [eax+ebx+color4] + movq mm3, [eax+ebx+colorS2] + movq mm4, [eax+ebx*2+color1] + movq mm5, [eax+ebx*2+colorS1] + movq mm6, [esi+ebx*2+colorA0] + movq mm7, [esi+ebx*2+colorA3] + + // compare to delta + lea esi, [ecx+ebx] +#if 0 + pcmpeqw mm0, [ecx+2+colorB0] + pcmpeqw mm1, [ecx+2+colorB3] + pcmpeqw mm2, [ecx+ebx+2+color4] + pcmpeqw mm3, [ecx+ebx+2+colorS2] + pcmpeqw mm4, [ecx+ebx*2+2+color1] + pcmpeqw mm5, [ecx+ebx*2+2+colorS1] + pcmpeqw mm6, [esi+ebx*2+2+colorA0] + pcmpeqw mm7, [esi+ebx*2+2+colorA3] +#else + pcmpeqw mm0, [ecx+colorB0] + pcmpeqw mm1, [ecx+colorB3] + pcmpeqw mm2, [ecx+ebx+color4] + pcmpeqw mm3, [ecx+ebx+colorS2] + pcmpeqw mm4, [ecx+ebx*2+color1] + pcmpeqw mm5, [ecx+ebx*2+colorS1] + pcmpeqw mm6, [esi+ebx*2+colorA0] + pcmpeqw mm7, [esi+ebx*2+colorA3] +#endif + + // compose results + pand mm0, mm1 + pand mm2, mm3 + pand mm4, mm5 + pand mm6, mm7 + pand mm0, mm2 + pand mm4, mm6 + pxor mm7, mm7 + pand mm0, mm4 + movq mm6, [eax+colorB0] + pcmpeqw mm7, mm0 +#if 0 + movq [ecx+2+colorB0], mm6 +#else + movq [ecx+colorB0], mm6 +#endif + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_Super2xSaILine_32mmx_skipprocess + // End Delta +nx_Super2xSaILine_32mmx_forcewrite: + //------------------------------ + // Interpolate pixels + // (c0&c1)+(((c0^c1)&colorMask)>>1) + //------------------------------ + movq mm6, cMask + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I56Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + movq I5556Pixel, mm0 + paddw mm1, mm3 + movq I5666Pixel, mm1 + + //------------------------------ + //------------------------------ + movq mm0, [eax+ebx*2+color2] + movq mm1, [eax+ebx*2+color3] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I23Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + movq I2223Pixel, mm0 + paddw mm1, mm3 + movq I2333Pixel, mm1 + + //------------------------------ + // Decide which "branch" to take + //------------------------------ + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm6, mm0 + movq mm7, mm1 + pcmpeqw mm0, [eax+ebx*2+color3] + pcmpeqw mm1, [eax+ebx*2+color2] + pcmpeqw mm6, mm7 + + movq mm2, mm0 + movq mm3, mm0 + + pand mm0, mm1 // colorA == colorD && colorB == colorC + pxor mm7, mm7 + + pcmpeqw mm2, mm7 + pand mm6, mm0 + pand mm2, mm1 // colorA != colorD && colorB == colorC + + pcmpeqw mm1, mm7 + + pand mm1, mm3 // colorA == colorD && colorB != colorC + pxor mm0, mm6 + por mm1, mm6 + movq mm7, mm0 + movq Mask26, mm2 + packsswb mm7, mm7 + movq Mask35, mm1 + + movd ecx, mm7 + test ecx, ecx + jz nx_Super2xSaILine_32mmx_skipguess + + //------------------------------ + movq mm6, mm0 + movq mm4, [eax+ebx+color5] // colorA + movq mm5, [eax+ebx+color6] // colorB + pxor mm7, mm7 + pand mm6, ONE + + movq mm0, [eax+colorB1] // colorE + movq mm1, [eax+ebx+color4] // colorG + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [eax+colorB2] // colorF + movq mm1, [eax+ebx+colorS2] // colorK + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + lea edi, [eax+ebx] + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+color1] // colorH + movq mm1, [edi+ebx*2+colorA1] // colorN + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+colorS1] // colorL + movq mm1, [edi+ebx*2+colorA2] // colorO + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm1, mm7 + pxor mm0, mm0 + pcmpgtw mm7, mm0 + pcmpgtw mm0, mm1 + + por mm7, Mask35 + por mm0, Mask26 + movq Mask35, mm7 + movq Mask26, mm0 + +nx_Super2xSaILine_32mmx_skipguess: + + // Start the ASSEMBLY !!! eh... compose all the results together to form the final image... + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx*2+color2] + movq mm2, mm0 + + pand mm0, mm1 + pxor mm2, mm1 + pand mm2, cMask + psrlw mm2, 1 + paddw mm0, mm2 + + //------------------------------ + movq mm7, Mask26 + movq mm6, [eax+colorB2] + movq mm5, [eax+ebx*2+color2] + movq mm4, [eax+ebx*2+color1] + pcmpeqw mm4, mm5 + pcmpeqw mm6, mm5 + pxor mm5, mm5 + pand mm7, mm4 + pcmpeqw mm6, mm5 + pand mm7, mm6 + + movq mm6, [eax+ebx*2+color3] + movq mm5, [eax+ebx*2+color2] + movq mm4, [eax+ebx*2+color1] + movq mm2, [eax+ebx+color5] + movq mm1, [eax+ebx+color4] + movq mm3, [eax+colorB0] + + pcmpeqw mm2, mm4 + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm3, mm5 + pxor mm5, mm5 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm6, mm1 + pand mm2, mm3 + pand mm6, mm2 + por mm7, mm6 + + movq mm6, mm7 + pcmpeqw mm6, mm5 + pand mm7, mm0 + + movq mm1, [eax+ebx+color5] + pand mm6, mm1 + por mm7, mm6 + movq final1a, mm7 // finished 1a + + //------------------------------ + lea esi, [eax+ebx] + movq mm7, Mask35 + movq mm6, [esi+ebx*2+colorA2] + + movq mm5, [eax+ebx+color5] + movq mm4, [eax+ebx+color4] + pcmpeqw mm4, mm5 + pcmpeqw mm6, mm5 + pxor mm5, mm5 + pand mm7, mm4 + pcmpeqw mm6, mm5 + pand mm7, mm6 + + movq mm6, [eax+ebx+color6] + movq mm5, [eax+ebx+color5] + movq mm4, [eax+ebx+color4] + movq mm2, [eax+ebx*2+color2] + movq mm1, [eax+ebx*2+color1] + movq mm3, [esi+ebx*2+colorA0] + + pcmpeqw mm2, mm4 + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm3, mm5 + pxor mm5, mm5 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm6, mm1 + pand mm2, mm3 + pand mm6, mm2 + por mm7, mm6 + + movq mm6, mm7 + pcmpeqw mm6, mm5 + pand mm7, mm0 + + movq mm1, [eax+ebx*2+color2] + pand mm6, mm1 + por mm7, mm6 + movq final2a, mm7 // finished 2a + + pxor mm7, mm7 + movq mm0, [esi+ebx*2+colorA0] + movq mm1, [esi+ebx*2+colorA1] + movq mm2, [esi+ebx*2+colorA2] + movq mm3, [esi+ebx*2+colorA3] + movq mm4, [eax+ebx*2+color2] + movq mm5, [eax+ebx*2+color3] + movq mm6, [eax+ebx+color6] + + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm4, mm2 + pcmpeqw mm0, mm5 + pcmpeqw mm4, mm7 + pcmpeqw mm0, mm7 + pand mm0, mm4 + pand mm6, mm1 + pand mm0, mm6 + + movq mm1, [esi+ebx*2+colorA1] + movq mm4, [eax+ebx*2+color2] + movq mm5, [eax+ebx+color5] + movq mm6, [eax+ebx*2+color3] + + pcmpeqw mm5, mm4 + pcmpeqw mm2, mm4 + pcmpeqw mm1, mm6 + pcmpeqw mm3, mm4 + pcmpeqw mm1, mm7 + pcmpeqw mm3, mm7 + pand mm2, mm5 + pand mm1, mm3 + pand mm1, mm2 + + movq mm7, mm0 + por mm7, mm1 + + movq mm4, Mask35 + movq mm3, Mask26 + + movq mm6, mm4 + pand mm6, mm7 + pxor mm4, mm6 + + movq mm6, mm3 + pand mm6, mm7 + pxor mm3, mm6 + + movq mm2, mm0 + movq mm7, I2333Pixel + movq mm6, I2223Pixel + movq mm5, I23Pixel + + por mm2, mm4 + pand mm4, [eax+ebx*2+color3] + por mm2, mm3 + pand mm3, [eax+ebx*2+color2] + por mm2, mm1 + pand mm0, mm7 + pand mm1, mm6 + pxor mm7, mm7 + pcmpeqw mm2, mm7 + por mm0, mm1 + por mm3, mm4 + pand mm2, mm5 + por mm0, mm3 + por mm0, mm2 + movq final2b, mm0 + + //------------------------------ + pxor mm7, mm7 + movq mm0, [eax+colorB0] + movq mm1, [eax+colorB1] + movq mm2, [eax+colorB2] + movq mm3, [eax+colorB3] + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx+color6] + movq mm6, [eax+ebx*2+color3] + + pcmpeqw mm6, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm4, mm2 + pcmpeqw mm0, mm5 + pcmpeqw mm4, mm7 + pcmpeqw mm0, mm7 + pand mm0, mm4 + pand mm6, mm1 + pand mm0, mm6 + + movq mm1, [eax+colorB1] + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx*2+color2] + movq mm6, [eax+ebx+color6] + + pcmpeqw mm5, mm4 + pcmpeqw mm2, mm4 + pcmpeqw mm1, mm6 + pcmpeqw mm3, mm4 + pcmpeqw mm1, mm7 + pcmpeqw mm3, mm7 + pand mm2, mm5 + pand mm1, mm3 + pand mm1, mm2 + + + movq mm7, mm0 + por mm7, mm1 + + movq mm4, Mask35 + movq mm3, Mask26 + + movq mm6, mm4 + pand mm6, mm7 + pxor mm4, mm6 + + movq mm6, mm3 + pand mm6, mm7 + pxor mm3, mm6 + + movq mm2, mm0 + movq mm7, I5666Pixel + movq mm6, I5556Pixel + movq mm5, I56Pixel + + por mm2, mm4 + pand mm4, [eax+ebx+color5] + por mm2, mm3 + pand mm3, [eax+ebx+color6] + por mm2, mm1 + pand mm0, mm7 + pand mm1, mm6 + pxor mm7, mm7 + pcmpeqw mm2, mm7 + por mm0, mm1 + por mm3, mm4 + pand mm2, mm5 + por mm0, mm3 + por mm0, mm2 + movq final1b, mm0 + + //------------------------------ + // Write final image + //------------------------------ + movq mm0, final1a + movq mm4, final2a + movq mm2, final1b + movq mm6, final2b + + movq mm1, mm0 + movq mm5, mm4 + + punpcklwd mm0, mm2 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm1, mm2 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + punpcklwd mm4, mm6 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm5, mm6 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + + // Write image RGB1555->RGBx888 + // save + mov esi, eax + movd mm7, ebx + mov edi, dstPitch + mov ecx, 0x00F8F8F8 // mask + + // 1st line + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+0], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+4], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+8], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+12], ebx + + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+16], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+20], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+24], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+28], ebx + + // 2nd line + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm4, 16 + mov [edx+edi+0], ebx + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm4, 16 + mov [edx+edi+4], ebx + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm4, 16 + mov [edx+edi+8], ebx + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+edi+12], ebx + + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+edi+16], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+edi+20], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+edi+24], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+edi+28], ebx + + // restore + mov eax, esi + movd ebx, mm7 + +nx_Super2xSaILine_32mmx_skipprocess: + add pDlt, 8 // 4 pixels + add eax, 8 // 4 pixels + add edx, 32 // 8 pixels + sub width, 4 // 4 pixels + jg nx_Super2xSaILine_32mmx_loop + + emms + } +} diff --git a/References/VirtuaNESex_src_191105/nx_SuperEagle.h b/References/VirtuaNESex_src_191105/nx_SuperEagle.h new file mode 100644 index 00000000..29023fd3 --- /dev/null +++ b/References/VirtuaNESex_src_191105/nx_SuperEagle.h @@ -0,0 +1,1094 @@ +/*---------------------------------------------------------------------* + * The following (piece of) code, (part of) the 2xSaI engine, * + * copyright (c) 2001 by Derek Liauw Kie Fa. * + * Non-Commercial use of the engine is allowed and is encouraged, * + * provided that appropriate credit be given and that this copyright * + * notice will not be removed under any circumstance. * + * You may freely modify this code, but I request * + * that any improvements to the engine be submitted to me, so * + * that I can implement these improvements in newer versions of * + * the engine. * + * If you need more information, have any comments or suggestions, * + * you can e-mail me. My e-mail: DerekL666@yahoo.com * + *---------------------------------------------------------------------*/ +// +// This code was converted into VirtuaNES by Norix. +// +static void nx_SuperEagleLine_16bpp_mmx( euI8* pSrc, euI8* pDlt, euI32 srcPitch, euI32 width, euI8* pDst, euI32 dstPitch, euI32 bForceWrite ) +{ + __asm { + mov eax, pSrc + mov ebx, srcPitch + mov edx, pDst + sub eax, ebx +nx_SuperEagleLine_16mmx_loop: + mov ecx, bForceWrite + test ecx, ecx + jz nx_SuperEagleLine_16mmx_normal + + mov esi, pDlt + movq mm6, [eax+colorB0] + movq [esi+colorB0], mm6 + + jmp nx_SuperEagleLine_16mmx_forcewrite +nx_SuperEagleLine_16mmx_normal: + // Check delta + mov ecx, pDlt + + // load source img + lea esi, [eax+ebx] + movq mm0, [eax+colorB0] + movq mm1, [eax+colorB3] + movq mm2, [eax+ebx+color4] + movq mm3, [eax+ebx+colorS2] + movq mm4, [eax+ebx*2+color1] + movq mm5, [eax+ebx*2+colorS1] + movq mm6, [esi+ebx*2+colorA0] + movq mm7, [esi+ebx*2+colorA3] + + // compare to delta + lea esi, [ecx+ebx] + pcmpeqw mm0, [ecx+colorB0] + pcmpeqw mm1, [ecx+colorB3] + pcmpeqw mm2, [ecx+ebx+color4] + pcmpeqw mm3, [ecx+ebx+colorS2] + pcmpeqw mm4, [ecx+ebx*2+color1] + pcmpeqw mm5, [ecx+ebx*2+colorS1] + pcmpeqw mm6, [esi+ebx*2+colorA0] + pcmpeqw mm7, [esi+ebx*2+colorA3] + + // compose results + pand mm0, mm1 + pand mm2, mm3 + pand mm4, mm5 + pand mm6, mm7 + pand mm0, mm2 + pand mm4, mm6 + pxor mm7, mm7 + pand mm0, mm4 + movq mm6, [eax+colorB0] + pcmpeqw mm7, mm0 + + movq [ecx+colorB0], mm6 + + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_SuperEagleLine_16mmx_skipprocess + // End Delta +nx_SuperEagleLine_16mmx_forcewrite: + //------------------------------ + // Interpolate pixels + // (c0&c1)+(((c0^c1)&colorMask)>>1) + //------------------------------ + movq mm6, cMask + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I56Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + paddw mm1, mm3 + movq product1a, mm0 + movq product1b, mm1 + + //------------------------------ + movq mm0, [eax+ebx*2+color2] + movq mm1, [eax+ebx*2+color3] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I23Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + paddw mm1, mm3 + movq product2a, mm0 + movq product2b, mm1 + + //------------------------------ + // Decide which "branch" to take + //------------------------------ + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx+color6] + movq mm6, [eax+ebx*2+color3] + movq mm7, [eax+ebx*2+color2] + + pxor mm3, mm3 + movq mm0, mm4 + movq mm1, mm5 + + pcmpeqw mm0, mm6 + pcmpeqw mm1, mm7 + pcmpeqw mm1, mm3 + pand mm0, mm1 + movq Mask35, mm0 + + lea esi, [eax+ebx] + movq mm0, [eax+ebx*2+colorS1] + movq mm1, [eax+ebx+color4] + movq mm2, [esi+ebx*2+colorA2] + movq mm3, [eax+colorB1] + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm4 + pcmpeqw mm3, mm4 + pand mm0, mm1 + pand mm2, mm3 + por mm0, mm2 + pand mm0, Mask35 + movq Mask35b, mm0 + + //------------------------------ + pxor mm3, mm3 + movq mm0, mm4 + movq mm1, mm5 + + pcmpeqw mm0, mm6 + pcmpeqw mm1, mm7 + pcmpeqw mm0, mm3 + pand mm0, mm1 + movq Mask26, mm0 + + lea esi, [eax+ebx] + movq mm0, [eax+ebx*2+color1] + movq mm1, [eax+ebx+colorS2] + movq mm2, [esi+ebx*2+colorA1] + movq mm3, [eax+colorB2] + pcmpeqw mm0, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm1 + pand mm2, mm3 + por mm0, mm2 + pand mm0, Mask26 + movq Mask26b, mm0 + + //------------------------------ + movq mm0, mm4 + movq mm1, mm5 + movq mm2, mm0 + + pcmpeqw mm2, mm1 + pcmpeqw mm0, mm6 + pcmpeqw mm1, mm7 + pand mm0, mm1 + pand mm2, mm0 + pxor mm0, mm2 + movq mm7, mm0 + + //------------------------------ + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_SuperEagleLine_16mmx_skipguess + + //------------------------------ + // Map of the pixels: I|E F|J + // G|A B|K + // H|C D|L + // M|N O|P + //------------------------------ + movq mm6, mm0 + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx+color6] + pxor mm7, mm7 + pand mm6, ONE + + movq mm0, [eax+colorB1] + movq mm1, [eax+ebx+color4] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [eax+colorB2] + movq mm1, [eax+ebx+colorS2] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + lea edi, [eax+ebx] + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+color1] + movq mm1, [edi+ebx*2+colorA1] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+colorS1] + movq mm1, [edi+ebx*2+colorA2] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm1, mm7 + pxor mm0, mm0 + pcmpgtw mm7, mm0 + pcmpgtw mm0, mm1 + + por mm7, Mask35 + por mm0, Mask26 + movq Mask35, mm7 + movq Mask26, mm0 + +nx_SuperEagleLine_16mmx_skipguess: + // Start the ASSEMBLY !!! + + movq mm4, Mask35 + movq mm5, Mask26 + movq mm6, Mask35b + movq mm7, Mask26b + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm2, [eax+ebx*2+color2] + movq mm3, [eax+ebx*2+color3] + pcmpeqw mm0, mm2 + pcmpeqw mm1, mm3 + movq mm2, mm4 + movq mm3, mm5 + por mm0, mm1 + por mm2, mm3 + pand mm2, mm0 + pxor mm0, mm2 + movq mm3, mm0 + + movq mm2, mm0 + pxor mm0, mm0 + por mm2, mm4 + pxor mm4, mm6 + por mm2, mm5 + pxor mm5, mm7 + pcmpeqw mm2, mm0 + ;---------------- + + movq mm0, [eax+ebx+color5] + movq mm1, mm3 + por mm1, mm4 + por mm1, mm6 + pand mm0, mm1 + movq mm1, mm5 + pand mm1, I56Pixel + por mm0, mm1 + movq mm1, mm7 + pand mm1, product1b + por mm0, mm1 + movq mm1, mm2 + pand mm1, product1a + por mm0, mm1 + movq final1a, mm0 + + movq mm0, [eax+ebx+color6] + movq mm1, mm3 + por mm1, mm5 + por mm1, mm7 + pand mm0, mm1 + movq mm1, mm4 + pand mm1, I56Pixel + por mm0, mm1 + movq mm1, mm6 + pand mm1, product1a + por mm0, mm1 + movq mm1, mm2 + pand mm1, product1b + por mm0, mm1 + movq final1b, mm0 + + movq mm0, [eax+ebx*2+color2] + movq mm1, mm3 + por mm1, mm5 + por mm1, mm7 + pand mm0, mm1 + movq mm1, mm4 + pand mm1, I23Pixel + por mm0, mm1 + movq mm1, mm6 + pand mm1, product2b + por mm0, mm1 + movq mm1, mm2 + pand mm1, product2a + por mm0, mm1 + movq final2a, mm0 + + movq mm0, [eax+ebx*2+color3] + movq mm1, mm3 + por mm1, mm4 + por mm1, mm6 + pand mm0, mm1 + movq mm1, mm5 + pand mm1, I23Pixel + por mm0, mm1 + movq mm1, mm7 + pand mm1, product2a + por mm0, mm1 + movq mm1, mm2 + pand mm1, product2b + por mm0, mm1 + movq final2b, mm0 + + //------------------------------ + // Write final image + //------------------------------ + movq mm0, final1a + movq mm2, final1b + movq mm1, mm0 + movq mm4, final2a + movq mm6, final2b + movq mm5, mm4 + + punpcklwd mm0, mm2 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm1, mm2 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + punpcklwd mm4, mm6 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm5, mm6 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + + mov edi, dstPitch + movq [edx+0], mm0 // 1st line + movq [edx+8], mm1 + movq [edi+edx+0], mm4 // 2nd line + movq [edi+edx+8], mm5 + +nx_SuperEagleLine_16mmx_skipprocess: + add pDlt, 8 // 4 pixels + lea eax, [eax+ 8] // 4 pixels + lea edx, [edx+16] // 8 pixels + sub width, 4 // 4 pixels + jg nx_SuperEagleLine_16mmx_loop + + emms + } +} + +static void nx_SuperEagleLine_32bpp_mmx( euI8* pSrc, euI8* pDlt, euI32 srcPitch, euI32 width, euI8* pDst, euI32 dstPitch, euI32 bForceWrite ) +{ + __asm { + mov eax, pSrc + mov ebx, srcPitch + mov edx, pDst + sub eax, ebx +nx_SuperEagleLine_32mmx_loop: + mov ecx, bForceWrite + test ecx, ecx + jz nx_SuperEagleLine_32mmx_normal + + mov esi, pDlt + movq mm6, [eax+colorB0] + movq [esi+colorB0], mm6 + + jmp nx_SuperEagleLine_32mmx_forcewrite +nx_SuperEagleLine_32mmx_normal: + // Check delta + mov ecx, pDlt + + // load source img + lea esi, [eax+ebx] + movq mm0, [eax+colorB0] + movq mm1, [eax+colorB3] + movq mm2, [eax+ebx+color4] + movq mm3, [eax+ebx+colorS2] + movq mm4, [eax+ebx*2+color1] + movq mm5, [eax+ebx*2+colorS1] + movq mm6, [esi+ebx*2+colorA0] + movq mm7, [esi+ebx*2+colorA3] + + // compare to delta + lea esi, [ecx+ebx] + pcmpeqw mm0, [ecx+colorB0] + pcmpeqw mm1, [ecx+colorB3] + pcmpeqw mm2, [ecx+ebx+color4] + pcmpeqw mm3, [ecx+ebx+colorS2] + pcmpeqw mm4, [ecx+ebx*2+color1] + pcmpeqw mm5, [ecx+ebx*2+colorS1] + pcmpeqw mm6, [esi+ebx*2+colorA0] + pcmpeqw mm7, [esi+ebx*2+colorA3] + + // compose results + pand mm0, mm1 + pand mm2, mm3 + pand mm4, mm5 + pand mm6, mm7 + pand mm0, mm2 + pand mm4, mm6 + pxor mm7, mm7 + pand mm0, mm4 + movq mm6, [eax+colorB0] + pcmpeqw mm7, mm0 + + movq [ecx+colorB0], mm6 + + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_SuperEagleLine_32mmx_skipprocess + // End Delta +nx_SuperEagleLine_32mmx_forcewrite: + //------------------------------ + // Interpolate pixels + // (c0&c1)+(((c0^c1)&colorMask)>>1) + //------------------------------ + movq mm6, cMask + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I56Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + paddw mm1, mm3 + movq product1a, mm0 + movq product1b, mm1 + + //------------------------------ + movq mm0, [eax+ebx*2+color2] + movq mm1, [eax+ebx*2+color3] + movq mm2, mm0 + movq mm3, mm1 + movq mm4, mm0 + movq mm5, mm1 + + pxor mm3, mm2 + pand mm0, mm1 + pand mm3, mm6 + psrlw mm3, 1 + paddw mm0, mm3 + movq I23Pixel, mm0 + movq mm7, mm0 + + //------------------------------ + movq mm0, mm7 + movq mm2, mm7 + movq mm1, mm7 + movq mm3, mm7 + pxor mm2, mm4 + pxor mm3, mm5 + pand mm0, mm4 + pand mm2, mm6 + pand mm1, mm5 + pand mm3, mm6 + psrlw mm2, 1 + psrlw mm3, 1 + paddw mm0, mm2 + paddw mm1, mm3 + movq product2a, mm0 + movq product2b, mm1 + + //------------------------------ + // Decide which "branch" to take + //------------------------------ + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx+color6] + movq mm6, [eax+ebx*2+color3] + movq mm7, [eax+ebx*2+color2] + + pxor mm3, mm3 + movq mm0, mm4 + movq mm1, mm5 + + pcmpeqw mm0, mm6 + pcmpeqw mm1, mm7 + pcmpeqw mm1, mm3 + pand mm0, mm1 + movq Mask35, mm0 + + lea esi, [eax+ebx] + movq mm0, [eax+ebx*2+colorS1] + movq mm1, [eax+ebx+color4] + movq mm2, [esi+ebx*2+colorA2] + movq mm3, [eax+colorB1] + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm4 + pcmpeqw mm3, mm4 + pand mm0, mm1 + pand mm2, mm3 + por mm0, mm2 + pand mm0, Mask35 + movq Mask35b, mm0 + + //------------------------------ + pxor mm3, mm3 + movq mm0, mm4 + movq mm1, mm5 + + pcmpeqw mm0, mm6 + pcmpeqw mm1, mm7 + pcmpeqw mm0, mm3 + pand mm0, mm1 + movq Mask26, mm0 + + lea esi, [eax+ebx] + movq mm0, [eax+ebx*2+color1] + movq mm1, [eax+ebx+colorS2] + movq mm2, [esi+ebx*2+colorA1] + movq mm3, [eax+colorB2] + pcmpeqw mm0, mm5 + pcmpeqw mm1, mm5 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm1 + pand mm2, mm3 + por mm0, mm2 + pand mm0, Mask26 + movq Mask26b, mm0 + + //------------------------------ + movq mm0, mm4 + movq mm1, mm5 + movq mm2, mm0 + + pcmpeqw mm2, mm1 + pcmpeqw mm0, mm6 + pcmpeqw mm1, mm7 + pand mm0, mm1 + pand mm2, mm0 + pxor mm0, mm2 + movq mm7, mm0 + + //------------------------------ + packsswb mm7, mm7 + movd ecx, mm7 + test ecx, ecx + jz nx_SuperEagleLine_32mmx_skipguess + + //------------------------------ + // Map of the pixels: I|E F|J + // G|A B|K + // H|C D|L + // M|N O|P + //------------------------------ + movq mm6, mm0 + movq mm4, [eax+ebx+color5] + movq mm5, [eax+ebx+color6] + pxor mm7, mm7 + pand mm6, ONE + + movq mm0, [eax+colorB1] + movq mm1, [eax+ebx+color4] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [eax+colorB2] + movq mm1, [eax+ebx+colorS2] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + lea edi, [eax+ebx] + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+color1] + movq mm1, [edi+ebx*2+colorA1] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm0, [edi+ebx+colorS1] + movq mm1, [edi+ebx*2+colorA2] + movq mm2, mm0 + movq mm3, mm1 + pcmpeqw mm0, mm4 + pcmpeqw mm1, mm4 + pcmpeqw mm2, mm5 + pcmpeqw mm3, mm5 + pand mm0, mm6 + pand mm1, mm6 + pand mm2, mm6 + pand mm3, mm6 + paddw mm0, mm1 + paddw mm2, mm3 + + pxor mm3, mm3 + pcmpgtw mm0, mm6 + pcmpgtw mm2, mm6 + pcmpeqw mm0, mm3 + pcmpeqw mm2, mm3 + pand mm0, mm6 + pand mm2, mm6 + paddw mm7, mm0 + psubw mm7, mm2 + + movq mm1, mm7 + pxor mm0, mm0 + pcmpgtw mm7, mm0 + pcmpgtw mm0, mm1 + + por mm7, Mask35 + por mm0, Mask26 + movq Mask35, mm7 + movq Mask26, mm0 + +nx_SuperEagleLine_32mmx_skipguess: + // Start the ASSEMBLY !!! + + movq mm4, Mask35 + movq mm5, Mask26 + movq mm6, Mask35b + movq mm7, Mask26b + + movq mm0, [eax+ebx+color5] + movq mm1, [eax+ebx+color6] + movq mm2, [eax+ebx*2+color2] + movq mm3, [eax+ebx*2+color3] + pcmpeqw mm0, mm2 + pcmpeqw mm1, mm3 + movq mm2, mm4 + movq mm3, mm5 + por mm0, mm1 + por mm2, mm3 + pand mm2, mm0 + pxor mm0, mm2 + movq mm3, mm0 + + movq mm2, mm0 + pxor mm0, mm0 + por mm2, mm4 + pxor mm4, mm6 + por mm2, mm5 + pxor mm5, mm7 + pcmpeqw mm2, mm0 + ;---------------- + + movq mm0, [eax+ebx+color5] + movq mm1, mm3 + por mm1, mm4 + por mm1, mm6 + pand mm0, mm1 + movq mm1, mm5 + pand mm1, I56Pixel + por mm0, mm1 + movq mm1, mm7 + pand mm1, product1b + por mm0, mm1 + movq mm1, mm2 + pand mm1, product1a + por mm0, mm1 + movq final1a, mm0 + + movq mm0, [eax+ebx+color6] + movq mm1, mm3 + por mm1, mm5 + por mm1, mm7 + pand mm0, mm1 + movq mm1, mm4 + pand mm1, I56Pixel + por mm0, mm1 + movq mm1, mm6 + pand mm1, product1a + por mm0, mm1 + movq mm1, mm2 + pand mm1, product1b + por mm0, mm1 + movq final1b, mm0 + + movq mm0, [eax+ebx*2+color2] + movq mm1, mm3 + por mm1, mm5 + por mm1, mm7 + pand mm0, mm1 + movq mm1, mm4 + pand mm1, I23Pixel + por mm0, mm1 + movq mm1, mm6 + pand mm1, product2b + por mm0, mm1 + movq mm1, mm2 + pand mm1, product2a + por mm0, mm1 + movq final2a, mm0 + + movq mm0, [eax+ebx*2+color3] + movq mm1, mm3 + por mm1, mm4 + por mm1, mm6 + pand mm0, mm1 + movq mm1, mm5 + pand mm1, I23Pixel + por mm0, mm1 + movq mm1, mm7 + pand mm1, product2a + por mm0, mm1 + movq mm1, mm2 + pand mm1, product2b + por mm0, mm1 + movq final2b, mm0 + + //------------------------------ + // Write final image + //------------------------------ + movq mm0, final1a + movq mm2, final1b + movq mm1, mm0 + movq mm4, final2a + movq mm6, final2b + movq mm5, mm4 + + punpcklwd mm0, mm2 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm1, mm2 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + punpcklwd mm4, mm6 // B1A1B0A0=B3B2B1B0(dst):A3A2A1A0(src) + punpckhwd mm5, mm6 // B3A3B2A2=B3B2B1B0(dst):A3A2A1A0(src) + + // Write image RGB1555->RGBx888 + // save + mov esi, eax + movd mm7, ebx + mov edi, dstPitch + mov ecx, 0x00F8F8F8 // mask + + // 1st line + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+0], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+4], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm0, 16 + mov [edx+8], ebx + movd eax, mm0 + movd ebx, mm0 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+12], ebx + + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+16], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+20], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm1, 16 + mov [edx+24], ebx + movd eax, mm1 + movd ebx, mm1 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+28], ebx + + // 2nd line + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm4, 16 + mov [edx+edi+ 0], ebx + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm4, 16 + mov [edx+edi+ 4], ebx + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm4, 16 + mov [edx+edi+ 8], ebx + movd eax, mm4 + movd ebx, mm4 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+edi+12], ebx + + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+edi+16], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+edi+20], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + psrlq mm5, 16 + mov [edx+edi+24], ebx + movd eax, mm5 + movd ebx, mm5 + shl eax, 3 + shl ebx, 9 + shl ah, 3 + and ebx, ecx + mov bx, ax + mov [edx+edi+28], ebx + + // restore + mov eax, esi + movd ebx, mm7 + +nx_SuperEagleLine_32mmx_skipprocess: + add pDlt, 8 // 4 pixels + lea eax, [eax+ 8] // 4 pixels + lea edx, [edx+32] // 8 pixels + sub width, 4 // 4 pixels + jg nx_SuperEagleLine_32mmx_loop + + emms + } +} diff --git a/References/VirtuaNESex_src_191105/rebuidFiles.bat b/References/VirtuaNESex_src_191105/rebuidFiles.bat new file mode 100644 index 00000000..7ccbaf23 --- /dev/null +++ b/References/VirtuaNESex_src_191105/rebuidFiles.bat @@ -0,0 +1,10 @@ +@echo off +@echo " --- del AboutDlg.obj ---" + +if exist ".\Debug\AboutDlg.obj" ( +del ".\Debug\AboutDlg.obj" +) +if exist ".\Release\AboutDlg.obj" ( +del ".\Release\AboutDlg.obj" +) + diff --git a/virtuanessrc097-master/res/CheatImageList.bmp b/References/VirtuaNESex_src_191105/res/CheatImageList.bmp similarity index 100% rename from virtuanessrc097-master/res/CheatImageList.bmp rename to References/VirtuaNESex_src_191105/res/CheatImageList.bmp diff --git a/virtuanessrc097-master/res/LauncherImageList.bmp b/References/VirtuaNESex_src_191105/res/LauncherImageList.bmp similarity index 100% rename from virtuanessrc097-master/res/LauncherImageList.bmp rename to References/VirtuaNESex_src_191105/res/LauncherImageList.bmp diff --git a/virtuanessrc097-master/res/VirtuaNES.ico b/References/VirtuaNESex_src_191105/res/VirtuaNES.ico similarity index 100% rename from virtuanessrc097-master/res/VirtuaNES.ico rename to References/VirtuaNESex_src_191105/res/VirtuaNES.ico diff --git a/virtuanessrc097-master/res/header_down.ico b/References/VirtuaNESex_src_191105/res/header_down.ico similarity index 100% rename from virtuanessrc097-master/res/header_down.ico rename to References/VirtuaNESex_src_191105/res/header_down.ico diff --git a/virtuanessrc097-master/res/header_up.ico b/References/VirtuaNESex_src_191105/res/header_up.ico similarity index 100% rename from virtuanessrc097-master/res/header_up.ico rename to References/VirtuaNESex_src_191105/res/header_up.ico diff --git a/References/VirtuaNESex_src_191105/resource.h b/References/VirtuaNESex_src_191105/resource.h new file mode 100644 index 00000000..4407caa9 --- /dev/null +++ b/References/VirtuaNESex_src_191105/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by VirtuaNES.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/virtuanessrc097-master/zlib/unzip.c b/References/VirtuaNESex_src_191105/zlib/unzip.c similarity index 100% rename from virtuanessrc097-master/zlib/unzip.c rename to References/VirtuaNESex_src_191105/zlib/unzip.c diff --git a/References/VirtuaNESex_src_191105/zlib/unzip.h b/References/VirtuaNESex_src_191105/zlib/unzip.h new file mode 100644 index 00000000..76692cb7 --- /dev/null +++ b/References/VirtuaNESex_src_191105/zlib/unzip.h @@ -0,0 +1,275 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/References/VirtuaNESex_src_191105/zlib/zconf.h b/References/VirtuaNESex_src_191105/zlib/zconf.h new file mode 100644 index 00000000..eb0ae2e1 --- /dev/null +++ b/References/VirtuaNESex_src_191105/zlib/zconf.h @@ -0,0 +1,279 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT __declspec(dllexport) WINAPI +# define ZEXPORTRVA __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT _export +# define ZEXPORTVA _export +# endif +# endif +# endif +#endif + +#if defined (__BEOS__) +# if defined (ZLIB_DLL) +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/References/VirtuaNESex_src_191105/zlib/zlib.h b/References/VirtuaNESex_src_191105/zlib/zlib.h new file mode 100644 index 00000000..52cb529f --- /dev/null +++ b/References/VirtuaNESex_src_191105/zlib/zlib.h @@ -0,0 +1,893 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/References/VirtuaNESex_src_191105/zlib/zlib.lib b/References/VirtuaNESex_src_191105/zlib/zlib.lib new file mode 100644 index 00000000..75bc2b3d Binary files /dev/null and b/References/VirtuaNESex_src_191105/zlib/zlib.lib differ diff --git a/virtuanessrc097-master/.gitignore b/References/virtuanessrc097-master/.gitignore similarity index 100% rename from virtuanessrc097-master/.gitignore rename to References/virtuanessrc097-master/.gitignore diff --git a/virtuanessrc097-master/AboutDlg.cpp b/References/virtuanessrc097-master/AboutDlg.cpp similarity index 100% rename from virtuanessrc097-master/AboutDlg.cpp rename to References/virtuanessrc097-master/AboutDlg.cpp diff --git a/virtuanessrc097-master/AboutDlg.h b/References/virtuanessrc097-master/AboutDlg.h similarity index 100% rename from virtuanessrc097-master/AboutDlg.h rename to References/virtuanessrc097-master/AboutDlg.h diff --git a/virtuanessrc097-master/App.cpp b/References/virtuanessrc097-master/App.cpp similarity index 100% rename from virtuanessrc097-master/App.cpp rename to References/virtuanessrc097-master/App.cpp diff --git a/virtuanessrc097-master/App.h b/References/virtuanessrc097-master/App.h similarity index 100% rename from virtuanessrc097-master/App.h rename to References/virtuanessrc097-master/App.h diff --git a/virtuanessrc097-master/Archive.cpp b/References/virtuanessrc097-master/Archive.cpp similarity index 100% rename from virtuanessrc097-master/Archive.cpp rename to References/virtuanessrc097-master/Archive.cpp diff --git a/virtuanessrc097-master/Archive.h b/References/virtuanessrc097-master/Archive.h similarity index 100% rename from virtuanessrc097-master/Archive.h rename to References/virtuanessrc097-master/Archive.h diff --git a/virtuanessrc097-master/AviConvDlg.cpp b/References/virtuanessrc097-master/AviConvDlg.cpp similarity index 100% rename from virtuanessrc097-master/AviConvDlg.cpp rename to References/virtuanessrc097-master/AviConvDlg.cpp diff --git a/virtuanessrc097-master/AviConvDlg.h b/References/virtuanessrc097-master/AviConvDlg.h similarity index 100% rename from virtuanessrc097-master/AviConvDlg.h rename to References/virtuanessrc097-master/AviConvDlg.h diff --git a/virtuanessrc097-master/AviWriter.cpp b/References/virtuanessrc097-master/AviWriter.cpp similarity index 100% rename from virtuanessrc097-master/AviWriter.cpp rename to References/virtuanessrc097-master/AviWriter.cpp diff --git a/virtuanessrc097-master/AviWriter.h b/References/virtuanessrc097-master/AviWriter.h similarity index 100% rename from virtuanessrc097-master/AviWriter.h rename to References/virtuanessrc097-master/AviWriter.h diff --git a/virtuanessrc097-master/CHyperLink.h b/References/virtuanessrc097-master/CHyperLink.h similarity index 100% rename from virtuanessrc097-master/CHyperLink.h rename to References/virtuanessrc097-master/CHyperLink.h diff --git a/virtuanessrc097-master/ChatDlg.cpp b/References/virtuanessrc097-master/ChatDlg.cpp similarity index 100% rename from virtuanessrc097-master/ChatDlg.cpp rename to References/virtuanessrc097-master/ChatDlg.cpp diff --git a/virtuanessrc097-master/ChatDlg.h b/References/virtuanessrc097-master/ChatDlg.h similarity index 100% rename from virtuanessrc097-master/ChatDlg.h rename to References/virtuanessrc097-master/ChatDlg.h diff --git a/virtuanessrc097-master/CheatDlg.cpp b/References/virtuanessrc097-master/CheatDlg.cpp similarity index 100% rename from virtuanessrc097-master/CheatDlg.cpp rename to References/virtuanessrc097-master/CheatDlg.cpp diff --git a/virtuanessrc097-master/CheatDlg.h b/References/virtuanessrc097-master/CheatDlg.h similarity index 100% rename from virtuanessrc097-master/CheatDlg.h rename to References/virtuanessrc097-master/CheatDlg.h diff --git a/virtuanessrc097-master/Com.cpp b/References/virtuanessrc097-master/Com.cpp similarity index 100% rename from virtuanessrc097-master/Com.cpp rename to References/virtuanessrc097-master/Com.cpp diff --git a/virtuanessrc097-master/Com.h b/References/virtuanessrc097-master/Com.h similarity index 100% rename from virtuanessrc097-master/Com.h rename to References/virtuanessrc097-master/Com.h diff --git a/virtuanessrc097-master/Config.cpp b/References/virtuanessrc097-master/Config.cpp similarity index 100% rename from virtuanessrc097-master/Config.cpp rename to References/virtuanessrc097-master/Config.cpp diff --git a/virtuanessrc097-master/Config.h b/References/virtuanessrc097-master/Config.h similarity index 100% rename from virtuanessrc097-master/Config.h rename to References/virtuanessrc097-master/Config.h diff --git a/virtuanessrc097-master/ControllerDlg.cpp b/References/virtuanessrc097-master/ControllerDlg.cpp similarity index 100% rename from virtuanessrc097-master/ControllerDlg.cpp rename to References/virtuanessrc097-master/ControllerDlg.cpp diff --git a/virtuanessrc097-master/ControllerDlg.h b/References/virtuanessrc097-master/ControllerDlg.h similarity index 100% rename from virtuanessrc097-master/ControllerDlg.h rename to References/virtuanessrc097-master/ControllerDlg.h diff --git a/virtuanessrc097-master/Crclib.cpp b/References/virtuanessrc097-master/Crclib.cpp similarity index 100% rename from virtuanessrc097-master/Crclib.cpp rename to References/virtuanessrc097-master/Crclib.cpp diff --git a/virtuanessrc097-master/Crclib.h b/References/virtuanessrc097-master/Crclib.h similarity index 100% rename from virtuanessrc097-master/Crclib.h rename to References/virtuanessrc097-master/Crclib.h diff --git a/virtuanessrc097-master/DatachBarcodeDlg.cpp b/References/virtuanessrc097-master/DatachBarcodeDlg.cpp similarity index 100% rename from virtuanessrc097-master/DatachBarcodeDlg.cpp rename to References/virtuanessrc097-master/DatachBarcodeDlg.cpp diff --git a/virtuanessrc097-master/DatachBarcodeDlg.h b/References/virtuanessrc097-master/DatachBarcodeDlg.h similarity index 100% rename from virtuanessrc097-master/DatachBarcodeDlg.h rename to References/virtuanessrc097-master/DatachBarcodeDlg.h diff --git a/virtuanessrc097-master/DebugOut.cpp b/References/virtuanessrc097-master/DebugOut.cpp similarity index 100% rename from virtuanessrc097-master/DebugOut.cpp rename to References/virtuanessrc097-master/DebugOut.cpp diff --git a/virtuanessrc097-master/DebugOut.h b/References/virtuanessrc097-master/DebugOut.h similarity index 100% rename from virtuanessrc097-master/DebugOut.h rename to References/virtuanessrc097-master/DebugOut.h diff --git a/virtuanessrc097-master/DipSwitchDlg.cpp b/References/virtuanessrc097-master/DipSwitchDlg.cpp similarity index 100% rename from virtuanessrc097-master/DipSwitchDlg.cpp rename to References/virtuanessrc097-master/DipSwitchDlg.cpp diff --git a/virtuanessrc097-master/DipSwitchDlg.h b/References/virtuanessrc097-master/DipSwitchDlg.h similarity index 100% rename from virtuanessrc097-master/DipSwitchDlg.h rename to References/virtuanessrc097-master/DipSwitchDlg.h diff --git a/virtuanessrc097-master/DirectDraw.cpp b/References/virtuanessrc097-master/DirectDraw.cpp similarity index 100% rename from virtuanessrc097-master/DirectDraw.cpp rename to References/virtuanessrc097-master/DirectDraw.cpp diff --git a/virtuanessrc097-master/DirectDraw.h b/References/virtuanessrc097-master/DirectDraw.h similarity index 100% rename from virtuanessrc097-master/DirectDraw.h rename to References/virtuanessrc097-master/DirectDraw.h diff --git a/virtuanessrc097-master/DirectInput.cpp b/References/virtuanessrc097-master/DirectInput.cpp similarity index 100% rename from virtuanessrc097-master/DirectInput.cpp rename to References/virtuanessrc097-master/DirectInput.cpp diff --git a/virtuanessrc097-master/DirectInput.h b/References/virtuanessrc097-master/DirectInput.h similarity index 100% rename from virtuanessrc097-master/DirectInput.h rename to References/virtuanessrc097-master/DirectInput.h diff --git a/virtuanessrc097-master/DirectSound.cpp b/References/virtuanessrc097-master/DirectSound.cpp similarity index 100% rename from virtuanessrc097-master/DirectSound.cpp rename to References/virtuanessrc097-master/DirectSound.cpp diff --git a/virtuanessrc097-master/DirectSound.h b/References/virtuanessrc097-master/DirectSound.h similarity index 100% rename from virtuanessrc097-master/DirectSound.h rename to References/virtuanessrc097-master/DirectSound.h diff --git a/virtuanessrc097-master/Doc/Copying.txt b/References/virtuanessrc097-master/Doc/Copying.txt similarity index 100% rename from virtuanessrc097-master/Doc/Copying.txt rename to References/virtuanessrc097-master/Doc/Copying.txt diff --git a/virtuanessrc097-master/Doc/ReadmeSrc.txt b/References/virtuanessrc097-master/Doc/ReadmeSrc.txt similarity index 100% rename from virtuanessrc097-master/Doc/ReadmeSrc.txt rename to References/virtuanessrc097-master/Doc/ReadmeSrc.txt diff --git a/virtuanessrc097-master/EmuThread.cpp b/References/virtuanessrc097-master/EmuThread.cpp similarity index 100% rename from virtuanessrc097-master/EmuThread.cpp rename to References/virtuanessrc097-master/EmuThread.cpp diff --git a/virtuanessrc097-master/EmuThread.h b/References/virtuanessrc097-master/EmuThread.h similarity index 100% rename from virtuanessrc097-master/EmuThread.h rename to References/virtuanessrc097-master/EmuThread.h diff --git a/virtuanessrc097-master/EmulatorDlg.cpp b/References/virtuanessrc097-master/EmulatorDlg.cpp similarity index 100% rename from virtuanessrc097-master/EmulatorDlg.cpp rename to References/virtuanessrc097-master/EmulatorDlg.cpp diff --git a/virtuanessrc097-master/EmulatorDlg.h b/References/virtuanessrc097-master/EmulatorDlg.h similarity index 100% rename from virtuanessrc097-master/EmulatorDlg.h rename to References/virtuanessrc097-master/EmulatorDlg.h diff --git a/virtuanessrc097-master/English.vlp b/References/virtuanessrc097-master/English.vlp similarity index 100% rename from virtuanessrc097-master/English.vlp rename to References/virtuanessrc097-master/English.vlp diff --git a/virtuanessrc097-master/ExtSoundFile.h b/References/virtuanessrc097-master/ExtSoundFile.h similarity index 100% rename from virtuanessrc097-master/ExtSoundFile.h rename to References/virtuanessrc097-master/ExtSoundFile.h diff --git a/virtuanessrc097-master/FolderDlg.cpp b/References/virtuanessrc097-master/FolderDlg.cpp similarity index 100% rename from virtuanessrc097-master/FolderDlg.cpp rename to References/virtuanessrc097-master/FolderDlg.cpp diff --git a/virtuanessrc097-master/FolderDlg.h b/References/virtuanessrc097-master/FolderDlg.h similarity index 100% rename from virtuanessrc097-master/FolderDlg.h rename to References/virtuanessrc097-master/FolderDlg.h diff --git a/virtuanessrc097-master/GameOptionDlg.cpp b/References/virtuanessrc097-master/GameOptionDlg.cpp similarity index 100% rename from virtuanessrc097-master/GameOptionDlg.cpp rename to References/virtuanessrc097-master/GameOptionDlg.cpp diff --git a/virtuanessrc097-master/GameOptionDlg.h b/References/virtuanessrc097-master/GameOptionDlg.h similarity index 100% rename from virtuanessrc097-master/GameOptionDlg.h rename to References/virtuanessrc097-master/GameOptionDlg.h diff --git a/virtuanessrc097-master/GraphicsDlg.cpp b/References/virtuanessrc097-master/GraphicsDlg.cpp similarity index 100% rename from virtuanessrc097-master/GraphicsDlg.cpp rename to References/virtuanessrc097-master/GraphicsDlg.cpp diff --git a/virtuanessrc097-master/GraphicsDlg.h b/References/virtuanessrc097-master/GraphicsDlg.h similarity index 100% rename from virtuanessrc097-master/GraphicsDlg.h rename to References/virtuanessrc097-master/GraphicsDlg.h diff --git a/virtuanessrc097-master/JoyAxisDlg.cpp b/References/virtuanessrc097-master/JoyAxisDlg.cpp similarity index 100% rename from virtuanessrc097-master/JoyAxisDlg.cpp rename to References/virtuanessrc097-master/JoyAxisDlg.cpp diff --git a/virtuanessrc097-master/JoyAxisDlg.h b/References/virtuanessrc097-master/JoyAxisDlg.h similarity index 100% rename from virtuanessrc097-master/JoyAxisDlg.h rename to References/virtuanessrc097-master/JoyAxisDlg.h diff --git a/virtuanessrc097-master/LanguageDlg.cpp b/References/virtuanessrc097-master/LanguageDlg.cpp similarity index 100% rename from virtuanessrc097-master/LanguageDlg.cpp rename to References/virtuanessrc097-master/LanguageDlg.cpp diff --git a/virtuanessrc097-master/LanguageDlg.h b/References/virtuanessrc097-master/LanguageDlg.h similarity index 100% rename from virtuanessrc097-master/LanguageDlg.h rename to References/virtuanessrc097-master/LanguageDlg.h diff --git a/virtuanessrc097-master/LauncherDlg.cpp b/References/virtuanessrc097-master/LauncherDlg.cpp similarity index 100% rename from virtuanessrc097-master/LauncherDlg.cpp rename to References/virtuanessrc097-master/LauncherDlg.cpp diff --git a/virtuanessrc097-master/LauncherDlg.h b/References/virtuanessrc097-master/LauncherDlg.h similarity index 100% rename from virtuanessrc097-master/LauncherDlg.h rename to References/virtuanessrc097-master/LauncherDlg.h diff --git a/virtuanessrc097-master/MMTimer.cpp b/References/virtuanessrc097-master/MMTimer.cpp similarity index 100% rename from virtuanessrc097-master/MMTimer.cpp rename to References/virtuanessrc097-master/MMTimer.cpp diff --git a/virtuanessrc097-master/MMTimer.h b/References/virtuanessrc097-master/MMTimer.h similarity index 100% rename from virtuanessrc097-master/MMTimer.h rename to References/virtuanessrc097-master/MMTimer.h diff --git a/virtuanessrc097-master/Macro.h b/References/virtuanessrc097-master/Macro.h similarity index 100% rename from virtuanessrc097-master/Macro.h rename to References/virtuanessrc097-master/Macro.h diff --git a/virtuanessrc097-master/MainFrame.cpp b/References/virtuanessrc097-master/MainFrame.cpp similarity index 100% rename from virtuanessrc097-master/MainFrame.cpp rename to References/virtuanessrc097-master/MainFrame.cpp diff --git a/virtuanessrc097-master/MainFrame.h b/References/virtuanessrc097-master/MainFrame.h similarity index 100% rename from virtuanessrc097-master/MainFrame.h rename to References/virtuanessrc097-master/MainFrame.h diff --git a/virtuanessrc097-master/MemoryView.cpp b/References/virtuanessrc097-master/MemoryView.cpp similarity index 100% rename from virtuanessrc097-master/MemoryView.cpp rename to References/virtuanessrc097-master/MemoryView.cpp diff --git a/virtuanessrc097-master/MemoryView.h b/References/virtuanessrc097-master/MemoryView.h similarity index 100% rename from virtuanessrc097-master/MemoryView.h rename to References/virtuanessrc097-master/MemoryView.h diff --git a/virtuanessrc097-master/MovieDlg.cpp b/References/virtuanessrc097-master/MovieDlg.cpp similarity index 100% rename from virtuanessrc097-master/MovieDlg.cpp rename to References/virtuanessrc097-master/MovieDlg.cpp diff --git a/virtuanessrc097-master/MovieDlg.h b/References/virtuanessrc097-master/MovieDlg.h similarity index 100% rename from virtuanessrc097-master/MovieDlg.h rename to References/virtuanessrc097-master/MovieDlg.h diff --git a/virtuanessrc097-master/MovieInfoDlg.cpp b/References/virtuanessrc097-master/MovieInfoDlg.cpp similarity index 100% rename from virtuanessrc097-master/MovieInfoDlg.cpp rename to References/virtuanessrc097-master/MovieInfoDlg.cpp diff --git a/virtuanessrc097-master/MovieInfoDlg.h b/References/virtuanessrc097-master/MovieInfoDlg.h similarity index 100% rename from virtuanessrc097-master/MovieInfoDlg.h rename to References/virtuanessrc097-master/MovieInfoDlg.h diff --git a/virtuanessrc097-master/NES/APU.cpp b/References/virtuanessrc097-master/NES/APU.cpp similarity index 100% rename from virtuanessrc097-master/NES/APU.cpp rename to References/virtuanessrc097-master/NES/APU.cpp diff --git a/virtuanessrc097-master/NES/APU.h b/References/virtuanessrc097-master/NES/APU.h similarity index 100% rename from virtuanessrc097-master/NES/APU.h rename to References/virtuanessrc097-master/NES/APU.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_FDS.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_FDS.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_FDS.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_FDS.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_FDS.h b/References/virtuanessrc097-master/NES/ApuEX/APU_FDS.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_FDS.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_FDS.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_FME7.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_FME7.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_FME7.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_FME7.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_FME7.h b/References/virtuanessrc097-master/NES/ApuEX/APU_FME7.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_FME7.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_FME7.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_INTERFACE.h b/References/virtuanessrc097-master/NES/ApuEX/APU_INTERFACE.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_INTERFACE.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_INTERFACE.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.h b/References/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_MMC5.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_MMC5.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_MMC5.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_MMC5.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_MMC5.h b/References/virtuanessrc097-master/NES/ApuEX/APU_MMC5.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_MMC5.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_MMC5.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_N106.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_N106.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_N106.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_N106.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_N106.h b/References/virtuanessrc097-master/NES/ApuEX/APU_N106.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_N106.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_N106.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_VRC6.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_VRC6.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_VRC6.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_VRC6.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_VRC6.h b/References/virtuanessrc097-master/NES/ApuEX/APU_VRC6.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_VRC6.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_VRC6.h diff --git a/virtuanessrc097-master/NES/ApuEX/APU_VRC7.cpp b/References/virtuanessrc097-master/NES/ApuEX/APU_VRC7.cpp similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_VRC7.cpp rename to References/virtuanessrc097-master/NES/ApuEX/APU_VRC7.cpp diff --git a/virtuanessrc097-master/NES/ApuEX/APU_VRC7.h b/References/virtuanessrc097-master/NES/ApuEX/APU_VRC7.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/APU_VRC7.h rename to References/virtuanessrc097-master/NES/ApuEX/APU_VRC7.h diff --git a/virtuanessrc097-master/NES/ApuEX/emu2413/2413tone.h b/References/virtuanessrc097-master/NES/ApuEX/emu2413/2413tone.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/emu2413/2413tone.h rename to References/virtuanessrc097-master/NES/ApuEX/emu2413/2413tone.h diff --git a/References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.c b/References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.c new file mode 100644 index 00000000..b11fecb7 --- /dev/null +++ b/References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.c @@ -0,0 +1,1545 @@ +/*********************************************************************************** + + emu2413.c -- YM2413 emulator written by Mitsutaka Okazaki 2001 + + 2001 01-08 : Version 0.10 -- 1st version. + 2001 01-15 : Version 0.20 -- semi-public version. + 2001 01-16 : Version 0.30 -- 1st public version. + 2001 01-17 : Version 0.31 -- Fixed bassdrum problem. + : Version 0.32 -- LPF implemented. + 2001 01-18 : Version 0.33 -- Fixed the drum problem, refine the mix-down method. + -- Fixed the LFO bug. + 2001 01-24 : Version 0.35 -- Fixed the drum problem, + support undocumented EG behavior. + 2001 02-02 : Version 0.38 -- Improved the performance. + Fixed the hi-hat and cymbal model. + Fixed the default percussive datas. + Noise reduction. + Fixed the feedback problem. + 2001 03-03 : Version 0.39 -- Fixed some drum bugs. + Improved the performance. + 2001 03-04 : Version 0.40 -- Improved the feedback. + Change the default table size. + Clock and Rate can be changed during play. + 2001 06-24 : Version 0.50 -- Improved the hi-hat and the cymbal tone. + Added VRC7 patch (OPLL_reset_patch is changed). + Fix OPLL_reset() bug. + Added OPLL_setMask, OPLL_getMask and OPLL_toggleMask. + Added OPLL_writeIO. + + References: + fmopl.c -- 1999,2000 written by Tatsuyuki Satoh (MAME development). + s_opl.c -- 2001 written by mamiya (NEZplug development). + fmgen.cpp -- 1999,2000 written by cisc. + fmpac.ill -- 2000 created by NARUTO. + MSX-Datapack + YMU757 data sheet + YM2143 data sheet + +**************************************************************************************/ +#include +#include +#include +#include +#include "emu2413.h" + +#if defined(_MSC_VER) +#define INLINE __inline +#elif defined(__GNUC__) +#define INLINE __inline__ +#else +#define INLINE +#endif + +#define OPLL_TONE_NUM 2 +static unsigned char default_inst[OPLL_TONE_NUM][(16+3)*16]= +{ + { +#include "2413tone.h" + }, + { +#include "vrc7tone.h" + } +}; + +/* Size of Sintable ( 1 -- 18 can be used, but 7 -- 14 recommended.)*/ +#define PG_BITS 9 +#define PG_WIDTH (1<>(b)) + +/* Leave the lower b bit(s). */ +#define LOWBITS(c,b) ((c)&((1<<(b))-1)) + +/* Expand x which is s bits to d bits. */ +#define EXPAND_BITS(x,s,d) ((x)<<((d)-(s))) + +/* Expand x which is s bits to d bits and fill expanded bits '1' */ +#define EXPAND_BITS_X(x,s,d) (((x)<<((d)-(s)))|((1<<((d)-(s)))-1)) + +/* Adjust envelope speed which depends on sampling rate. */ +#define rate_adjust(x) (uint32)((double)(x)*clk/72/rate + 0.5) /* +0.5 to round */ + +#define MOD(x) ch[x]->mod +#define CAR(x) ch[x]->car + +/* Sampling rate */ +static uint32 rate ; +/* Input clock */ +static uint32 clk ; + +/* WaveTable for each envelope amp */ +static uint32 fullsintable[PG_WIDTH] ; +static uint32 halfsintable[PG_WIDTH] ; +static uint32 snaretable[PG_WIDTH] ; + +static int32 noiseAtable[64] = { + -1,1,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0, + -1,1,0,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0,-1,1,0,0 +} ; + +static int32 noiseBtable[8] = { + -1,1,-1,1,0,0,0,0 +} ; + +static uint32 *waveform[5] = {fullsintable,halfsintable,snaretable} ; + +/* LFO Table */ +static int32 pmtable[PM_PG_WIDTH] ; +static int32 amtable[AM_PG_WIDTH] ; + +/* Noise and LFO */ +static uint32 pm_dphase ; +static uint32 am_dphase ; + +/* dB to Liner table */ +static int32 DB2LIN_TABLE[(DB_MUTE + DB_MUTE)*2] ; + +/* Liner to Log curve conversion table (for Attack rate). */ +static uint32 AR_ADJUST_TABLE[1<=DB_MUTE) DB2LIN_TABLE[i] = 0 ; + DB2LIN_TABLE[i+ DB_MUTE + DB_MUTE] = -DB2LIN_TABLE[i] ; + } +} + +/* Liner(+0.0 - +1.0) to dB((1<0) noiseAtable[i] = DB_POS(0) ; + else if(noiseAtable[i]<0) noiseAtable[i] = DB_NEG(0) ; + else noiseAtable[i] = DB_MUTE - 1 ; + } + + for( i = 0 ; i < 8 ; i++ ) + { + if(noiseBtable[i]>0) noiseBtable[i] = DB_POS(0) ; + else if(noiseBtable[i]<0) noiseBtable[i] = DB_NEG(0) ; + else noiseBtable[i] = DB_MUTE - 1 ; + } + +} + +/* Table for Pitch Modulator */ +static void makePmTable(void) +{ + int i ; + + for(i = 0 ; i < PM_PG_WIDTH ; i++ ) + pmtable[i] = (int32)((double)PM_AMP * pow(2,(double)PM_DEPTH*sin(2.0*PI*i/PM_PG_WIDTH)/1200)) ; +} + +/* Table for Amp Modulator */ +static void makeAmTable(void) +{ + int i ; + + for(i = 0 ; i < AM_PG_WIDTH ; i++ ) + amtable[i] = (int32)((double)AM_DEPTH/2/DB_STEP * (1.0 + sin(2.0*PI*i/PM_PG_WIDTH))) ; +} + +/* Phase increment counter table */ +static void makeDphaseTable(void) +{ + uint32 fnum, block , ML ; + uint32 mltable[16]={ 1,1*2,2*2,3*2,4*2,5*2,6*2,7*2,8*2,9*2,10*2,10*2,12*2,12*2,15*2,15*2 } ; + + for(fnum=0; fnum<512; fnum++) + for(block=0; block<8; block++) + for(ML=0; ML<16; ML++) + dphaseTable[fnum][block][ML] = rate_adjust(((fnum * mltable[ML])<>(20-DP_BITS)) ; +} + +static void makeTllTable(void) +{ +#define dB2(x) (uint32)((x)*2) + + static uint32 kltable[16] = { + dB2( 0.000),dB2( 9.000),dB2(12.000),dB2(13.875),dB2(15.000),dB2(16.125),dB2(16.875),dB2(17.625), + dB2(18.000),dB2(18.750),dB2(19.125),dB2(19.500),dB2(19.875),dB2(20.250),dB2(20.625),dB2(21.000) + } ; + + int32 tmp ; + int fnum, block ,TL , KL ; + + for(fnum=0; fnum<16; fnum++) + for(block=0; block<8; block++) + for(TL=0; TL<64; TL++) + for(KL=0; KL<4; KL++) + { + if(KL==0) + { + tllTable[fnum][block][TL][KL] = TL2EG(TL) ; + } + else + { + tmp = kltable[fnum] - dB2(3.000) * (7 - block) ; + if(tmp <= 0) + tllTable[fnum][block][TL][KL] = TL2EG(TL) ; + else + tllTable[fnum][block][TL][KL] = (uint32)((tmp>>(3-KL))/EG_STEP) + TL2EG(TL) ; + } + } +} + +/* Rate Table for Attack */ +static void makeDphaseARTable(void) +{ + int AR,Rks,RM,RL ; + + for(AR=0; AR<16; AR++) + for(Rks=0; Rks<16; Rks++) + { + RM = AR + (Rks>>2) ; + if(RM>15) RM = 15 ; + RL = Rks&3 ; + switch(AR) + { + case 0: + dphaseARTable[AR][Rks] = 0 ; + break ; + case 15: + dphaseARTable[AR][Rks] = EG_DP_WIDTH ; + break ; + default: + dphaseARTable[AR][Rks] = rate_adjust(( 3 * (RL + 4) << (RM + 1))) ; + break ; + } + } +} + +/* Rate Table for Decay */ +static void makeDphaseDRTable(void) +{ + int DR,Rks,RM,RL ; + + for(DR=0; DR<16; DR++) + for(Rks=0; Rks<16; Rks++) + { + RM = DR + (Rks>>2) ; + RL = Rks&3 ; + if(RM>15) RM = 15 ; + switch(DR) + { + case 0: + dphaseDRTable[DR][Rks] = 0 ; + break ; + default: + dphaseDRTable[DR][Rks] = rate_adjust((RL + 4) << (RM - 1)); + break ; + } + } +} + +static void makeRksTable(void) +{ + + int fnum8, block, KR ; + + for(fnum8 = 0 ; fnum8 < 2 ; fnum8++) + for(block = 0 ; block < 8 ; block++) + for(KR = 0; KR < 2 ; KR++) + { + if(KR!=0) + rksTable[fnum8][block][KR] = ( block << 1 ) + fnum8 ; + else + rksTable[fnum8][block][KR] = block >> 1 ; + } +} + + +void dump2patch(unsigned char *dump, OPLL_PATCH *patch) +{ + patch[0].AM = (dump[0]>>7)&1 ; + patch[1].AM = (dump[1]>>7)&1 ; + patch[0].PM = (dump[0]>>6)&1 ; + patch[1].PM = (dump[1]>>6)&1 ; + patch[0].EG = (dump[0]>>5)&1 ; + patch[1].EG = (dump[1]>>5)&1 ; + patch[0].KR = (dump[0]>>4)&1 ; + patch[1].KR = (dump[1]>>4)&1 ; + patch[0].ML = (dump[0])&15 ; + patch[1].ML = (dump[1])&15 ; + patch[0].KL = (dump[2]>>6)&3 ; + patch[1].KL = (dump[3]>>6)&3 ; + patch[0].TL = (dump[2])&63 ; + patch[0].FB = (dump[3])&7 ; + patch[0].WF = (dump[3]>>3)&1 ; + patch[1].WF = (dump[3]>>4)&1 ; + patch[0].AR = (dump[4]>>4)&15 ; + patch[1].AR = (dump[5]>>4)&15 ; + patch[0].DR = (dump[4])&15 ; + patch[1].DR = (dump[5])&15 ; + patch[0].SL = (dump[6]>>4)&15 ; + patch[1].SL = (dump[7]>>4)&15 ; + patch[0].RR = (dump[6])&15 ; + patch[1].RR = (dump[7])&15 ; +} + +static void makeDefaultPatch() +{ + int i, j ; + + for(i=0;ieg_mode) + { + case ATTACK: + return dphaseARTable[slot->patch->AR][slot->rks] ; + + case DECAY: + return dphaseDRTable[slot->patch->DR][slot->rks] ; + + case SUSHOLD: + return 0 ; + + case SUSTINE: + return dphaseDRTable[slot->patch->RR][slot->rks] ; + + case RELEASE: + if(slot->sustine) + return dphaseDRTable[5][slot->rks] ; + else if(slot->patch->EG) + return dphaseDRTable[slot->patch->RR][slot->rks] ; + else + return dphaseDRTable[7][slot->rks] ; + + case FINISH: + return 0 ; + + default: + return 0 ; + } +} + +/************************************************************* + + OPLL internal interfaces + +*************************************************************/ +#define SLOT_BD1 12 +#define SLOT_BD2 13 +#define SLOT_HH 14 +#define SLOT_SD 15 +#define SLOT_TOM 16 +#define SLOT_CYM 17 + +#define UPDATE_PG(S) (S)->dphase = dphaseTable[(S)->fnum][(S)->block][(S)->patch->ML] +#define UPDATE_TLL(S)\ +(((S)->type==0)?\ +((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->patch->TL][(S)->patch->KL]):\ +((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->volume][(S)->patch->KL])) +#define UPDATE_RKS(S) (S)->rks = rksTable[((S)->fnum)>>8][(S)->block][(S)->patch->KR] +#define UPDATE_WF(S) (S)->sintbl = waveform[(S)->patch->WF] +#define UPDATE_EG(S) (S)->eg_dphase = calc_eg_dphase(S) +#define UPDATE_ALL(S)\ + UPDATE_PG(S);\ + UPDATE_TLL(S);\ + UPDATE_RKS(S);\ + UPDATE_WF(S); \ + UPDATE_EG(S) /* EG should be last */ + +/* Force Refresh (When external program changes some parameters). */ +void OPLL_forceRefresh(OPLL *opll) +{ + int i ; + + if(opll==NULL) return ; + + for(i=0; i<18 ;i++) + { + UPDATE_PG(opll->slot[i]) ; + UPDATE_RKS(opll->slot[i]) ; + UPDATE_TLL(opll->slot[i]) ; + UPDATE_WF(opll->slot[i]) ; + UPDATE_EG(opll->slot[i]) ; + } +} + +/* Slot key on */ +INLINE static void slotOn(OPLL_SLOT *slot) +{ + slot->eg_mode = ATTACK ; + slot->phase = 0 ; + slot->eg_phase = 0 ; +} + +/* Slot key off */ +INLINE static void slotOff(OPLL_SLOT *slot) +{ + if(slot->eg_mode == ATTACK) + slot->eg_phase = EXPAND_BITS(AR_ADJUST_TABLE[HIGHBITS(slot->eg_phase,EG_DP_BITS-EG_BITS)],EG_BITS,EG_DP_BITS) ; + slot->eg_mode = RELEASE ; +} + +/* Channel key on */ +INLINE static void keyOn(OPLL *opll, int i) +{ + if(!opll->slot_on_flag[i*2]) slotOn(opll->MOD(i)) ; + if(!opll->slot_on_flag[i*2+1]) slotOn(opll->CAR(i)) ; + opll->ch[i]->key_status = 1 ; +} + +/* Channel key off */ +INLINE static void keyOff(OPLL *opll, int i) +{ + if(opll->slot_on_flag[i*2+1]) slotOff(opll->CAR(i)) ; + opll->ch[i]->key_status = 0 ; +} + +INLINE static void keyOn_BD(OPLL *opll){ keyOn(opll,6) ; } +INLINE static void keyOn_SD(OPLL *opll){ if(!opll->slot_on_flag[SLOT_SD]) slotOn(opll->CAR(7)) ; } +INLINE static void keyOn_TOM(OPLL *opll){ if(!opll->slot_on_flag[SLOT_TOM]) slotOn(opll->MOD(8)) ; } +INLINE static void keyOn_HH(OPLL *opll){ if(!opll->slot_on_flag[SLOT_HH]) slotOn(opll->MOD(7)) ; } +INLINE static void keyOn_CYM(OPLL *opll){ if(!opll->slot_on_flag[SLOT_CYM]) slotOn(opll->CAR(8)) ; } + +/* Drum key off */ +INLINE static void keyOff_BD(OPLL *opll){ keyOff(opll,6) ; } +INLINE static void keyOff_SD(OPLL *opll){ if(opll->slot_on_flag[SLOT_SD]) slotOff(opll->CAR(7)) ; } +INLINE static void keyOff_TOM(OPLL *opll){ if(opll->slot_on_flag[SLOT_TOM]) slotOff(opll->MOD(8)) ; } +INLINE static void keyOff_HH(OPLL *opll){ if(opll->slot_on_flag[SLOT_HH]) slotOff(opll->MOD(7)) ; } +INLINE static void keyOff_CYM(OPLL *opll){ if(opll->slot_on_flag[SLOT_CYM]) slotOff(opll->CAR(8)) ; } + +/* Change a voice */ +INLINE static void setPatch(OPLL *opll, int i, int num) +{ + opll->ch[i]->patch_number = num ; + opll->MOD(i)->patch = opll->patch[num*2+0] ; + opll->CAR(i)->patch = opll->patch[num*2+1] ; +} + +/* Change a rythm voice */ +INLINE static void setSlotPatch(OPLL_SLOT *slot, OPLL_PATCH *patch) +{ + slot->patch = patch ; +} + +/* Set sustine parameter */ +INLINE static void setSustine(OPLL *opll, int c, int sustine) +{ + opll->CAR(c)->sustine = sustine ; + if(opll->MOD(c)->type) opll->MOD(c)->sustine = sustine ; +} + +/* Volume : 6bit ( Volume register << 2 ) */ +INLINE static void setVolume(OPLL *opll, int c, int volume) +{ + opll->CAR(c)->volume = volume ; +} + +INLINE static void setSlotVolume(OPLL_SLOT *slot, int volume) +{ + slot->volume = volume ; +} + +/* Set F-Number ( fnum : 9bit ) */ +INLINE static void setFnumber(OPLL *opll, int c, int fnum) +{ + opll->CAR(c)->fnum = fnum ; + opll->MOD(c)->fnum = fnum ; +} + +/* Set Block data (block : 3bit ) */ +INLINE static void setBlock(OPLL *opll, int c, int block) +{ + opll->CAR(c)->block = block ; + opll->MOD(c)->block = block ; +} + +/* Change Rythm Mode */ +INLINE static void setRythmMode(OPLL *opll, int mode) +{ + opll->rythm_mode = mode ; + + if(mode) + { + opll->ch[6]->patch_number = 16 ; + opll->ch[7]->patch_number = 17 ; + opll->ch[8]->patch_number = 18 ; + setSlotPatch(opll->slot[SLOT_BD1], opll->patch[16*2+0]) ; + setSlotPatch(opll->slot[SLOT_BD2], opll->patch[16*2+1]) ; + setSlotPatch(opll->slot[SLOT_HH], opll->patch[17*2+0]) ; + setSlotPatch(opll->slot[SLOT_SD], opll->patch[17*2+1]) ; + opll->slot[SLOT_HH]->type = 1 ; + setSlotPatch(opll->slot[SLOT_TOM], opll->patch[18*2+0]) ; + setSlotPatch(opll->slot[SLOT_CYM], opll->patch[18*2+1]) ; + opll->slot[SLOT_TOM]->type = 1 ; + } + else + { + setPatch(opll, 6, opll->reg[0x36]>>4) ; + setPatch(opll, 7, opll->reg[0x37]>>4) ; + opll->slot[SLOT_HH]->type = 0 ; + setPatch(opll, 8, opll->reg[0x38]>>4) ; + opll->slot[SLOT_TOM]->type = 0 ; + } + + if(!opll->slot_on_flag[SLOT_BD1]) + opll->slot[SLOT_BD1]->eg_mode = FINISH ; + if(!opll->slot_on_flag[SLOT_BD2]) + opll->slot[SLOT_BD2]->eg_mode = FINISH ; + if(!opll->slot_on_flag[SLOT_HH]) + opll->slot[SLOT_HH]->eg_mode = FINISH ; + if(!opll->slot_on_flag[SLOT_SD]) + opll->slot[SLOT_SD]->eg_mode = FINISH ; + if(!opll->slot_on_flag[SLOT_TOM]) + opll->slot[SLOT_TOM]->eg_mode = FINISH ; + if(!opll->slot_on_flag[SLOT_CYM]) + opll->slot[SLOT_CYM]->eg_mode = FINISH ; + +} + +void OPLL_copyPatch(OPLL *opll, int num, OPLL_PATCH *patch) +{ + memcpy(opll->patch[num],patch,sizeof(OPLL_PATCH)) ; +} + +/*********************************************************** + + Initializing + +***********************************************************/ + +static void OPLL_SLOT_reset(OPLL_SLOT *slot) +{ + slot->sintbl = waveform[0] ; + slot->phase = 0 ; + slot->dphase = 0 ; + slot->output[0] = 0 ; + slot->output[1] = 0 ; + slot->feedback = 0 ; + slot->eg_mode = SETTLE ; + slot->eg_phase = EG_DP_WIDTH ; + slot->eg_dphase = 0 ; + slot->rks = 0 ; + slot->tll = 0 ; + slot->sustine = 0 ; + slot->fnum = 0 ; + slot->block = 0 ; + slot->volume = 0 ; + slot->pgout = 0 ; + slot->egout = 0 ; + slot->patch = &null_patch ; +} + +static OPLL_SLOT *OPLL_SLOT_new(void) +{ + OPLL_SLOT *slot ; + + slot = malloc(sizeof(OPLL_SLOT)) ; + if(slot == NULL) return NULL ; + + return slot ; +} + +static void OPLL_SLOT_delete(OPLL_SLOT *slot) +{ + free(slot) ; +} + +static void OPLL_CH_reset(OPLL_CH *ch) +{ + if(ch->mod!=NULL) OPLL_SLOT_reset(ch->mod) ; + if(ch->car!=NULL) OPLL_SLOT_reset(ch->car) ; + ch->key_status = 0 ; +} + +static OPLL_CH *OPLL_CH_new(void) +{ + OPLL_CH *ch ; + OPLL_SLOT *mod, *car ; + + mod = OPLL_SLOT_new() ; + if(mod == NULL) return NULL ; + + car = OPLL_SLOT_new() ; + if(car == NULL) + { + OPLL_SLOT_delete(mod) ; + return NULL ; + } + + ch = malloc(sizeof(OPLL_CH)) ; + if(ch == NULL) + { + OPLL_SLOT_delete(mod) ; + OPLL_SLOT_delete(car) ; + return NULL ; + } + + mod->type = 0 ; + car->type = 1 ; + ch->mod = mod ; + ch->car = car ; + + return ch ; +} + + +static void OPLL_CH_delete(OPLL_CH *ch) +{ + OPLL_SLOT_delete(ch->mod) ; + OPLL_SLOT_delete(ch->car) ; + free(ch) ; +} + +OPLL *OPLL_new(void) +{ + OPLL *opll ; + OPLL_CH *ch[9] ; + OPLL_PATCH *patch[19*2] ; + int i, j ; + + for( i = 0 ; i < 19*2 ; i++ ) + { + patch[i] = calloc(sizeof(OPLL_PATCH),1) ; + if(patch[i] == NULL) + { + for ( j = i ; i > 0 ; i++ ) free(patch[j-1]) ; + return NULL ; + } + } + + for( i = 0 ; i < 9 ; i++ ) + { + ch[i] = OPLL_CH_new() ; + if(ch[i]==NULL) + { + for ( j = i ; i > 0 ; i++ ) OPLL_CH_delete(ch[j-1]) ; + for ( j = 0 ; j < 19*2 ; j++ ) free(patch[j]) ; + return NULL ; + } + } + + opll = malloc(sizeof(OPLL)) ; + if(opll == NULL) return NULL ; + + + for ( i = 0 ; i < 19*2 ; i++ ) + + opll->patch[i] = patch[i] ; + + + for ( i = 0 ; i <9 ; i++) + { + opll->ch[i] = ch[i] ; + opll->slot[i*2+0] = opll->ch[i]->mod ; + opll->slot[i*2+1] = opll->ch[i]->car ; + } + + for ( i = 0 ; i < 18 ; i++) + { + opll->slot[i]->plfo_am = &opll->lfo_am ; + opll->slot[i]->plfo_pm = &opll->lfo_pm ; + } + + opll->mask = 0 ; + + OPLL_reset(opll) ; + OPLL_reset_patch(opll,0) ; + + opll->masterVolume = 32 ; + + return opll ; + +} + +void OPLL_delete(OPLL *opll) +{ + int i ; + + for ( i = 0 ; i < 9 ; i++ ) + OPLL_CH_delete(opll->ch[i]) ; + + for ( i = 0 ; i < 19*2 ; i++ ) + free(opll->patch[i]) ; + + free(opll) ; +} + +/* Reset patch datas by system default. */ +void OPLL_reset_patch(OPLL *opll, int type) +{ + int i ; + + for ( i = 0 ; i < 19*2 ; i++ ) + OPLL_copyPatch(opll, i, &default_patch[type%OPLL_TONE_NUM][i]) ; +} + +/* Reset whole of OPLL except patch datas. */ +void OPLL_reset(OPLL *opll) +{ + int i ; + + if(!opll) return ; + + opll->adr = 0 ; + + opll->output[0] = 0 ; + opll->output[1] = 0 ; + + opll->pm_phase = 0 ; + opll->am_phase = 0 ; + + opll->noise_seed =0xffff ; + opll->noiseA = 0 ; + opll->noiseB = 0 ; + opll->noiseA_phase = 0 ; + opll->noiseB_phase = 0 ; + opll->noiseA_dphase = 0 ; + opll->noiseB_dphase = 0 ; + opll->noiseA_idx = 0 ; + opll->noiseB_idx = 0 ; + + for(i = 0; i < 9 ; i++) + { + OPLL_CH_reset(opll->ch[i]) ; + setPatch(opll,i,0) ; + } + + for ( i = 0 ; i < 0x40 ; i++ ) OPLL_writeReg(opll, i, 0) ; + +} + +void OPLL_setClock(uint32 c, uint32 r) +{ + clk = c ; + rate = r ; + makeDphaseTable() ; + makeDphaseARTable() ; + makeDphaseDRTable() ; + pm_dphase = (uint32)rate_adjust(PM_SPEED * PM_DP_WIDTH / (clk/72) ) ; + am_dphase = (uint32)rate_adjust(AM_SPEED * AM_DP_WIDTH / (clk/72) ) ; +} + +void OPLL_init(uint32 c, uint32 r) +{ + makePmTable() ; + makeAmTable() ; + makeDB2LinTable() ; + makeAdjustTable() ; + makeTllTable() ; + makeRksTable() ; + makeSinTable() ; + makeDefaultPatch() ; + OPLL_setClock(c,r) ; +} + +void OPLL_close(void) +{ +} + +/********************************************************* + + Generate wave data + +*********************************************************/ +/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 2PI). */ +#if ( SLOT_AMP_BITS - PG_BITS ) > 0 +#define wave2_2pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS )) +#else +#define wave2_2pi(e) ( (e) << ( PG_BITS - SLOT_AMP_BITS )) +#endif + +/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 4PI). */ +#if ( SLOT_AMP_BITS - PG_BITS - 1 ) == 0 +#define wave2_4pi(e) (e) +#elif ( SLOT_AMP_BITS - PG_BITS - 1 ) > 0 +#define wave2_4pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 1 )) +#else +#define wave2_4pi(e) ( (e) << ( 1 + PG_BITS - SLOT_AMP_BITS )) +#endif + +/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 8PI). */ +#if ( SLOT_AMP_BITS - PG_BITS - 2 ) == 0 +#define wave2_8pi(e) (e) +#elif ( SLOT_AMP_BITS - PG_BITS - 2 ) > 0 +#define wave2_8pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 2 )) +#else +#define wave2_8pi(e) ( (e) << ( 2 + PG_BITS - SLOT_AMP_BITS )) +#endif + +/* 16bit rand */ +INLINE static uint32 mrand(uint32 seed) +{ + return ((seed>>15)^((seed>>12)&1)) | ((seed<<1)&0xffff) ; +} + +INLINE static uint32 DEC(uint32 db) +{ + if(dbnoise_seed = mrand(opll->noise_seed) ; + opll->whitenoise = opll->noise_seed & 1 ; + + opll->noiseA_phase = (opll->noiseA_phase + opll->noiseA_dphase) ; + opll->noiseB_phase = (opll->noiseB_phase + opll->noiseB_dphase) ; + + if(opll->noiseA_phase<(1<<11)) + { + if(opll->noiseA_phase>16) opll->noiseA = DB_MUTE - 1 ; + } + else + { + opll->noiseA_phase &= (1<<11)-1 ; + opll->noiseA_idx = (opll->noiseA_idx+1)&63 ; + opll->noiseA = noiseAtable[opll->noiseA_idx] ; + } + + if(opll->noiseB_phase<(1<<12)) + { + if(opll->noiseB_phase>16) opll->noiseB = DB_MUTE - 1 ; + } + else + { + opll->noiseB_phase &= (1<<12)-1 ; + opll->noiseB_idx = (opll->noiseB_idx+1)&7 ; + opll->noiseB = noiseBtable[opll->noiseB_idx] ; + } + +} + +/* Update AM, PM unit */ +INLINE static void update_ampm(OPLL *opll) +{ + opll->pm_phase = (opll->pm_phase + pm_dphase)&(PM_DP_WIDTH - 1) ; + opll->am_phase = (opll->am_phase + am_dphase)&(AM_DP_WIDTH - 1) ; + opll->lfo_am = amtable[HIGHBITS(opll->am_phase, AM_DP_BITS - AM_PG_BITS)] ; + opll->lfo_pm = pmtable[HIGHBITS(opll->pm_phase, PM_DP_BITS - PM_PG_BITS)] ; +} + +/* PG */ +INLINE static uint32 calc_phase(OPLL_SLOT *slot) +{ + if(slot->patch->PM) + slot->phase += (slot->dphase * (*(slot->plfo_pm))) >> PM_AMP_BITS ; + else + slot->phase += slot->dphase ; + + slot->phase &= (DP_WIDTH - 1) ; + + return HIGHBITS(slot->phase, DP_BASE_BITS) ; +} + +/* EG */ +INLINE static uint32 calc_envelope(OPLL_SLOT *slot) +{ + #define S2E(x) (SL2EG((int)(x/SL_STEP))<<(EG_DP_BITS-EG_BITS)) + static uint32 SL[16] = { + S2E( 0), S2E( 3), S2E( 6), S2E( 9), S2E(12), S2E(15), S2E(18), S2E(21), + S2E(24), S2E(27), S2E(30), S2E(33), S2E(36), S2E(39), S2E(42), S2E(48) + } ; + + uint32 egout ; + + switch(slot->eg_mode) + { + + case ATTACK: + slot->eg_phase += slot->eg_dphase ; + if(EG_DP_WIDTH & slot->eg_phase) + { + egout = 0 ; + slot->eg_phase= 0 ; + slot->eg_mode = DECAY ; + UPDATE_EG(slot) ; + } + else + { + egout = AR_ADJUST_TABLE[HIGHBITS(slot->eg_phase, EG_DP_BITS - EG_BITS)] ; + } + break; + + case DECAY: + slot->eg_phase += slot->eg_dphase ; + egout = HIGHBITS(slot->eg_phase, EG_DP_BITS - EG_BITS) ; + if(slot->eg_phase >= SL[slot->patch->SL]) + { + if(slot->patch->EG) + { + slot->eg_phase = SL[slot->patch->SL] ; + slot->eg_mode = SUSHOLD ; + UPDATE_EG(slot) ; + } + else + { + slot->eg_phase = SL[slot->patch->SL] ; + slot->eg_mode = SUSTINE ; + UPDATE_EG(slot) ; + } + egout = HIGHBITS(slot->eg_phase, EG_DP_BITS - EG_BITS) ; + } + break; + + case SUSHOLD: + egout = HIGHBITS(slot->eg_phase, EG_DP_BITS - EG_BITS) ; + if(slot->patch->EG == 0) + { + slot->eg_mode = SUSTINE ; + UPDATE_EG(slot) ; + } + break; + + case SUSTINE: + case RELEASE: + slot->eg_phase += slot->eg_dphase ; + egout = HIGHBITS(slot->eg_phase, EG_DP_BITS - EG_BITS) ; + if(egout >= (1<eg_mode = FINISH ; + egout = (1<patch->AM) egout = EG2DB(egout+slot->tll) + *(slot->plfo_am) ; + else egout = EG2DB(egout+slot->tll) ; + + if(egout >= DB_MUTE) egout = DB_MUTE-1; + return egout ; + +} + +INLINE static int32 calc_slot_car(OPLL_SLOT *slot, int32 fm) +{ + slot->egout = calc_envelope(slot) ; + slot->pgout = calc_phase(slot) ; + if(slot->egout>=(DB_MUTE-1)) return 0 ; + + return DB2LIN_TABLE[slot->sintbl[(slot->pgout+wave2_8pi(fm))&(PG_WIDTH-1)] + slot->egout] ; +} + + +INLINE static int32 calc_slot_mod(OPLL_SLOT *slot) +{ + int32 fm ; + + slot->output[1] = slot->output[0] ; + slot->egout = calc_envelope(slot) ; + slot->pgout = calc_phase(slot) ; + + if(slot->egout>=(DB_MUTE-1)) + { + slot->output[0] = 0 ; + } + else if(slot->patch->FB!=0) + { + fm = wave2_4pi(slot->feedback) >> (7 - slot->patch->FB) ; + slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+fm)&(PG_WIDTH-1)] + slot->egout] ; + } + else + { + slot->output[0] = DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout] ; + } + + slot->feedback = (slot->output[1] + slot->output[0])>>1 ; + + return slot->feedback ; + +} + +INLINE static int32 calc_slot_tom(OPLL_SLOT *slot) +{ + + slot->egout = calc_envelope(slot) ; + slot->pgout = calc_phase(slot) ; + if(slot->egout>=(DB_MUTE-1)) return 0 ; + + return DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout] ; + +} + +/* calc SNARE slot */ +INLINE static int32 calc_slot_snare(OPLL_SLOT *slot, uint32 whitenoise) +{ + slot->egout = calc_envelope(slot) ; + slot->pgout = calc_phase(slot) ; + if(slot->egout>=(DB_MUTE-1)) return 0 ; + + if(whitenoise) + return DB2LIN_TABLE[snaretable[slot->pgout] + slot->egout] + DB2LIN_TABLE[slot->egout + 6] ; + else + return DB2LIN_TABLE[snaretable[slot->pgout] + slot->egout] ; +} + +INLINE static int32 calc_slot_cym(OPLL_SLOT *slot, int32 a, int32 b, int32 c) +{ + slot->egout = calc_envelope(slot) ; + if(slot->egout>=(DB_MUTE-1)) return 0 ; + + return DB2LIN_TABLE[slot->egout+a] + + (( DB2LIN_TABLE[slot->egout+b] + DB2LIN_TABLE[slot->egout+c] ) >> 2 ); +} + +INLINE static int32 calc_slot_hat(OPLL_SLOT *slot, int32 a, int32 b, int32 c, uint32 whitenoise) +{ + slot->egout = calc_envelope(slot) ; + if(slot->egout>=(DB_MUTE-1)) return 0 ; + + if(whitenoise) + { + return DB2LIN_TABLE[slot->egout+a] + + (( DB2LIN_TABLE[slot->egout+b] + DB2LIN_TABLE[slot->egout+c] ) >> 2 ); + } + else + { + return 0 ; + } +} + +int16 OPLL_calc(OPLL *opll) +{ + int32 inst = 0 , perc = 0 , out = 0 ; + int32 rythmC = 0, rythmH = 0; + int i ; + + update_ampm(opll) ; + update_noise(opll) ; + + for(i = 0 ; i < 6 ; i++) + if(!(opll->mask&OPLL_MASK_CH(i))&&(opll->CAR(i)->eg_mode!=FINISH)) + inst += calc_slot_car(opll->CAR(i),calc_slot_mod(opll->MOD(i))) ; + + if(!opll->rythm_mode) + { + for(i = 6 ; i < 9 ; i++) + if(!(opll->mask&OPLL_MASK_CH(i))&&(opll->CAR(i)->eg_mode!=FINISH)) + inst += calc_slot_car(opll->CAR(i),calc_slot_mod(opll->MOD(i))) ; + } + else + { + opll->MOD(7)->pgout = calc_phase(opll->MOD(7)) ; + opll->CAR(8)->pgout = calc_phase(opll->CAR(8)) ; + if(opll->MOD(7)->phase<256) rythmH = DB_NEG(12.0) ; else rythmH = DB_MUTE - 1 ; + if(opll->CAR(8)->phase<256) rythmC = DB_NEG(12.0) ; else rythmC = DB_MUTE - 1 ; + + if(!(opll->mask&OPLL_MASK_BD)&&(opll->CAR(6)->eg_mode!=FINISH)) + perc += calc_slot_car(opll->CAR(6),calc_slot_mod(opll->MOD(6))) ; + + if(!(opll->mask&OPLL_MASK_HH)&&(opll->MOD(7)->eg_mode!=FINISH)) + perc += calc_slot_hat(opll->MOD(7), opll->noiseA, opll->noiseB, rythmH, opll->whitenoise) ; + + if(!(opll->mask&OPLL_MASK_SD)&&(opll->CAR(7)->eg_mode!=FINISH)) + perc += calc_slot_snare(opll->CAR(7), opll->whitenoise) ; + + if(!(opll->mask&OPLL_MASK_TOM)&&(opll->MOD(8)->eg_mode!=FINISH)) + perc += calc_slot_tom(opll->MOD(8)) ; + + if(!(opll->mask&OPLL_MASK_CYM)&&(opll->CAR(8)->eg_mode!=FINISH)) + perc += calc_slot_cym(opll->CAR(8), opll->noiseA, opll->noiseB, rythmC) ; + } + +#if SLOT_AMP_BITS > 8 + inst = (inst >> (SLOT_AMP_BITS - 8)) ; + perc = (perc >> (SLOT_AMP_BITS - 9)) ; +#else + inst = (inst << (8 - SLOT_AMP_BITS)) ; + perc = (perc << (9 - SLOT_AMP_BITS)) ; +#endif + + out = ((inst + perc) * opll->masterVolume ) >> 2 ; + + if(out>32767) return 32767 ; + if(out<-32768) return -32768 ; + + return (int16)out ; + +} + +uint32 OPLL_setMask(OPLL *opll, uint32 mask) +{ + uint32 ret ; + + if(opll) + { + ret = opll->mask ; + opll->mask = mask ; + return ret ; + } + else return 0 ; +} + +uint32 OPLL_toggleMask(OPLL *opll, uint32 mask) +{ + uint32 ret ; + + if(opll) + { + ret = opll->mask ; + opll->mask ^= mask ; + return ret ; + } + else return 0 ; +} + +/**************************************************** + + Interfaces + +*****************************************************/ + +void OPLL_writeReg(OPLL *opll, uint32 reg, uint32 data){ + + int i,v,ch ; + + data = data&0xff ; + reg = reg&0x3f ; + + switch(reg) + { + case 0x00: + opll->patch[0]->AM = (data>>7)&1 ; + opll->patch[0]->PM = (data>>6)&1 ; + opll->patch[0]->EG = (data>>5)&1 ; + opll->patch[0]->KR = (data>>4)&1 ; + opll->patch[0]->ML = (data)&15 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_PG(opll->MOD(i)) ; + UPDATE_RKS(opll->MOD(i)) ; + UPDATE_EG(opll->MOD(i)) ; + } + } + break ; + + case 0x01: + opll->patch[1]->AM = (data>>7)&1 ; + opll->patch[1]->PM = (data>>6)&1 ; + opll->patch[1]->EG = (data>>5)&1 ; + opll->patch[1]->KR = (data>>4)&1 ; + opll->patch[1]->ML = (data)&15 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_PG(opll->CAR(i)) ; + UPDATE_RKS(opll->CAR(i)) ; + UPDATE_EG(opll->CAR(i)) ; + } + } + break; + + case 0x02: + opll->patch[0]->KL = (data>>6)&3 ; + opll->patch[0]->TL = (data)&63 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_TLL(opll->MOD(i)) ; + } + } + break ; + + case 0x03: + opll->patch[1]->KL = (data>>6)&3 ; + opll->patch[1]->WF = (data>>4)&1 ; + opll->patch[0]->WF = (data>>3)&1 ; + opll->patch[0]->FB = (data)&7 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_WF(opll->MOD(i)) ; + UPDATE_WF(opll->CAR(i)) ; + } + } + break ; + + case 0x04: + opll->patch[0]->AR = (data>>4)&15 ; + opll->patch[0]->DR = (data)&15 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_EG(opll->MOD(i)) ; + } + } + break ; + + case 0x05: + opll->patch[1]->AR = (data>>4)&15 ; + opll->patch[1]->DR = (data)&15 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_EG(opll->CAR(i)) ; + } + } + break ; + + case 0x06: + opll->patch[0]->SL = (data>>4)&15 ; + opll->patch[0]->RR = (data)&15 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_EG(opll->MOD(i)) ; + } + } + break ; + + case 0x07: + opll->patch[1]->SL = (data>>4)&15 ; + opll->patch[1]->RR = (data)&15 ; + for(i=0;i<9;i++) + { + if(opll->ch[i]->patch_number==0) + { + UPDATE_EG(opll->CAR(i)) ; + } + } + break ; + + case 0x0e: + + if(opll->rythm_mode) + { + opll->slot_on_flag[SLOT_BD1] = (opll->reg[0x0e]&0x10) | (opll->reg[0x26]&0x10) ; + opll->slot_on_flag[SLOT_BD2] = (opll->reg[0x0e]&0x10) | (opll->reg[0x26]&0x10) ; + opll->slot_on_flag[SLOT_SD] = (opll->reg[0x0e]&0x08) | (opll->reg[0x27]&0x10) ; + opll->slot_on_flag[SLOT_HH] = (opll->reg[0x0e]&0x01) | (opll->reg[0x27]&0x10) ; + opll->slot_on_flag[SLOT_TOM] = (opll->reg[0x0e]&0x04) | (opll->reg[0x28]&0x10) ; + opll->slot_on_flag[SLOT_CYM] = (opll->reg[0x0e]&0x02) | (opll->reg[0x28]&0x10) ; + } + else + { + opll->slot_on_flag[SLOT_BD1] = (opll->reg[0x26]&0x10) ; + opll->slot_on_flag[SLOT_BD2] = (opll->reg[0x26]&0x10) ; + opll->slot_on_flag[SLOT_SD] = (opll->reg[0x27]&0x10) ; + opll->slot_on_flag[SLOT_HH] = (opll->reg[0x27]&0x10) ; + opll->slot_on_flag[SLOT_TOM] = (opll->reg[0x28]&0x10) ; + opll->slot_on_flag[SLOT_CYM] = (opll->reg[0x28]&0x10) ; + } + + if(((data>>5)&1)^(opll->rythm_mode)) + { + setRythmMode(opll,(data&32)>>5) ; + } + + if(opll->rythm_mode) + { + if(data&0x10) keyOn_BD(opll) ; else keyOff_BD(opll) ; + if(data&0x8) keyOn_SD(opll) ; else keyOff_SD(opll) ; + if(data&0x4) keyOn_TOM(opll) ; else keyOff_TOM(opll) ; + if(data&0x2) keyOn_CYM(opll) ; else keyOff_CYM(opll) ; + if(data&0x1) keyOn_HH(opll) ; else keyOff_HH(opll) ; + } + + UPDATE_ALL(opll->MOD(6)) ; + UPDATE_ALL(opll->CAR(6)) ; + UPDATE_ALL(opll->MOD(7)) ; + UPDATE_ALL(opll->CAR(7)) ; + UPDATE_ALL(opll->MOD(8)) ; + UPDATE_ALL(opll->CAR(8)) ; + break ; + + case 0x0f: + break ; + + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: + ch = reg-0x10 ; + setFnumber(opll, ch, data + ((opll->reg[0x20+ch]&1)<<8)) ; + UPDATE_ALL(opll->MOD(ch)); + UPDATE_ALL(opll->CAR(ch)); + switch(reg) + { + case 0x17: + opll->noiseA_dphase = (data + ((opll->reg[0x27]&1)<<8)) << ((opll->reg[0x27]>>1)&7) ; + break ; + case 0x18: + opll->noiseB_dphase = (data + ((opll->reg[0x28]&1)<<8)) << ((opll->reg[0x28]>>1)&7) ; + break; + default: + break ; + } + break ; + + case 0x20: case 0x21: case 0x22: case 0x23: + case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: + + ch = reg - 0x20 ; + setFnumber(opll, ch, ((data&1)<<8) + opll->reg[0x10+ch]) ; + setBlock(opll, ch, (data>>1)&7 ) ; + opll->slot_on_flag[ch*2] = opll->slot_on_flag[ch*2+1] = (opll->reg[reg])&0x10 ; + + if(opll->rythm_mode) + { + switch(reg) + { + case 0x26: + opll->slot_on_flag[SLOT_BD1] |= (opll->reg[0x0e])&0x10 ; + opll->slot_on_flag[SLOT_BD2] |= (opll->reg[0x0e])&0x10 ; + break ; + + case 0x27: + opll->noiseA_dphase = (((data&1)<<8) + opll->reg[0x17] ) << ((data>>1)&7) ; + opll->slot_on_flag[SLOT_SD] |= (opll->reg[0x0e])&0x08 ; + opll->slot_on_flag[SLOT_HH] |= (opll->reg[0x0e])&0x01 ; + break; + + case 0x28: + opll->noiseB_dphase = (((data&1)<<8) + opll->reg[0x18] ) << ((data>>1)&7); + opll->slot_on_flag[SLOT_TOM] |= (opll->reg[0x0e])&0x04 ; + opll->slot_on_flag[SLOT_CYM] |= (opll->reg[0x0e])&0x02 ; + break ; + + default: + break ; + } + } + + if((opll->reg[reg]^data)&0x20) setSustine(opll, ch, (data>>5)&1) ; + if(data&0x10) keyOn(opll, ch) ; else keyOff(opll, ch) ; + UPDATE_ALL(opll->MOD(ch)) ; + UPDATE_ALL(opll->CAR(ch)) ; + break ; + + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: + case 0x35: case 0x36: case 0x37: case 0x38: + i = (data>>4)&15 ; + v = data&15 ; + if((opll->rythm_mode)&&(reg>=0x36)) + { + switch(reg) + { + case 0x37 : + setSlotVolume(opll->MOD(7), i<<2) ; + break ; + case 0x38 : + setSlotVolume(opll->MOD(8), i<<2) ; + break ; + } + } + else + { + setPatch(opll, reg-0x30, i) ; + } + + setVolume(opll, reg-0x30, v<<2) ; + UPDATE_ALL(opll->MOD(reg-0x30)) ; + UPDATE_ALL(opll->CAR(reg-0x30)) ; + break ; + + default: + break ; + + } + + opll->reg[reg] = (unsigned char)data ; + +} + +void OPLL_writeIO(OPLL *opll, uint32 adr, uint32 val) +{ + adr &= 0xff ; + if(adr == 0x7C) opll->adr = val ; + else if(adr == 0x7D) OPLL_writeReg(opll, opll->adr, val) ; +} diff --git a/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.h b/References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.h rename to References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.h diff --git a/virtuanessrc097-master/NES/ApuEX/emu2413/vrc7tone.h b/References/virtuanessrc097-master/NES/ApuEX/emu2413/vrc7tone.h similarity index 100% rename from virtuanessrc097-master/NES/ApuEX/emu2413/vrc7tone.h rename to References/virtuanessrc097-master/NES/ApuEX/emu2413/vrc7tone.h diff --git a/virtuanessrc097-master/NES/CPU.h b/References/virtuanessrc097-master/NES/CPU.h similarity index 100% rename from virtuanessrc097-master/NES/CPU.h rename to References/virtuanessrc097-master/NES/CPU.h diff --git a/virtuanessrc097-master/NES/Cheat.h b/References/virtuanessrc097-master/NES/Cheat.h similarity index 100% rename from virtuanessrc097-master/NES/Cheat.h rename to References/virtuanessrc097-master/NES/Cheat.h diff --git a/virtuanessrc097-master/NES/Cpu.cpp b/References/virtuanessrc097-master/NES/Cpu.cpp similarity index 100% rename from virtuanessrc097-master/NES/Cpu.cpp rename to References/virtuanessrc097-master/NES/Cpu.cpp diff --git a/virtuanessrc097-master/NES/IPS.cpp b/References/virtuanessrc097-master/NES/IPS.cpp similarity index 100% rename from virtuanessrc097-master/NES/IPS.cpp rename to References/virtuanessrc097-master/NES/IPS.cpp diff --git a/virtuanessrc097-master/NES/IPS.h b/References/virtuanessrc097-master/NES/IPS.h similarity index 100% rename from virtuanessrc097-master/NES/IPS.h rename to References/virtuanessrc097-master/NES/IPS.h diff --git a/virtuanessrc097-master/NES/MMU.cpp b/References/virtuanessrc097-master/NES/MMU.cpp similarity index 100% rename from virtuanessrc097-master/NES/MMU.cpp rename to References/virtuanessrc097-master/NES/MMU.cpp diff --git a/virtuanessrc097-master/NES/MMU.h b/References/virtuanessrc097-master/NES/MMU.h similarity index 100% rename from virtuanessrc097-master/NES/MMU.h rename to References/virtuanessrc097-master/NES/MMU.h diff --git a/virtuanessrc097-master/NES/Mapper/EEPROM.h b/References/virtuanessrc097-master/NES/Mapper/EEPROM.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/EEPROM.h rename to References/virtuanessrc097-master/NES/Mapper/EEPROM.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper.h b/References/virtuanessrc097-master/NES/Mapper/Mapper.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper000.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper000.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper000.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper000.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper000.h b/References/virtuanessrc097-master/NES/Mapper/Mapper000.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper000.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper000.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper001.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper001.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper001.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper001.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper001.h b/References/virtuanessrc097-master/NES/Mapper/Mapper001.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper001.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper001.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper002.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper002.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper002.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper002.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper002.h b/References/virtuanessrc097-master/NES/Mapper/Mapper002.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper002.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper002.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper003.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper003.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper003.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper003.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper003.h b/References/virtuanessrc097-master/NES/Mapper/Mapper003.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper003.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper003.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper004.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper004.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper004.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper004.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper004.h b/References/virtuanessrc097-master/NES/Mapper/Mapper004.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper004.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper004.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper005.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper005.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper005.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper005.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper005.h b/References/virtuanessrc097-master/NES/Mapper/Mapper005.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper005.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper005.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper006.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper006.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper006.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper006.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper006.h b/References/virtuanessrc097-master/NES/Mapper/Mapper006.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper006.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper006.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper007.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper007.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper007.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper007.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper007.h b/References/virtuanessrc097-master/NES/Mapper/Mapper007.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper007.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper007.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper008.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper008.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper008.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper008.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper008.h b/References/virtuanessrc097-master/NES/Mapper/Mapper008.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper008.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper008.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper009.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper009.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper009.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper009.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper009.h b/References/virtuanessrc097-master/NES/Mapper/Mapper009.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper009.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper009.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper010.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper010.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper010.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper010.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper010.h b/References/virtuanessrc097-master/NES/Mapper/Mapper010.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper010.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper010.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper011.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper011.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper011.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper011.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper011.h b/References/virtuanessrc097-master/NES/Mapper/Mapper011.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper011.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper011.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper012.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper012.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper012.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper012.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper012.h b/References/virtuanessrc097-master/NES/Mapper/Mapper012.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper012.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper012.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper013.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper013.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper013.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper013.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper013.h b/References/virtuanessrc097-master/NES/Mapper/Mapper013.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper013.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper013.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper015.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper015.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper015.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper015.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper015.h b/References/virtuanessrc097-master/NES/Mapper/Mapper015.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper015.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper015.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper016.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper016.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper016.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper016.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper016.h b/References/virtuanessrc097-master/NES/Mapper/Mapper016.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper016.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper016.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper017.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper017.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper017.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper017.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper017.h b/References/virtuanessrc097-master/NES/Mapper/Mapper017.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper017.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper017.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper018.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper018.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper018.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper018.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper018.h b/References/virtuanessrc097-master/NES/Mapper/Mapper018.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper018.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper018.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper019.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper019.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper019.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper019.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper019.h b/References/virtuanessrc097-master/NES/Mapper/Mapper019.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper019.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper019.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper021.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper021.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper021.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper021.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper021.h b/References/virtuanessrc097-master/NES/Mapper/Mapper021.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper021.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper021.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper022.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper022.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper022.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper022.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper022.h b/References/virtuanessrc097-master/NES/Mapper/Mapper022.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper022.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper022.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper023.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper023.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper023.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper023.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper023.h b/References/virtuanessrc097-master/NES/Mapper/Mapper023.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper023.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper023.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper024.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper024.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper024.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper024.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper024.h b/References/virtuanessrc097-master/NES/Mapper/Mapper024.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper024.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper024.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper025.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper025.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper025.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper025.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper025.h b/References/virtuanessrc097-master/NES/Mapper/Mapper025.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper025.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper025.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper026.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper026.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper026.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper026.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper026.h b/References/virtuanessrc097-master/NES/Mapper/Mapper026.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper026.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper026.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper027.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper027.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper027.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper027.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper027.h b/References/virtuanessrc097-master/NES/Mapper/Mapper027.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper027.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper027.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper032.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper032.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper032.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper032.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper032.h b/References/virtuanessrc097-master/NES/Mapper/Mapper032.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper032.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper032.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper033.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper033.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper033.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper033.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper033.h b/References/virtuanessrc097-master/NES/Mapper/Mapper033.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper033.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper033.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper034.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper034.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper034.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper034.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper034.h b/References/virtuanessrc097-master/NES/Mapper/Mapper034.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper034.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper034.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper040.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper040.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper040.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper040.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper040.h b/References/virtuanessrc097-master/NES/Mapper/Mapper040.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper040.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper040.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper041.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper041.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper041.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper041.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper041.h b/References/virtuanessrc097-master/NES/Mapper/Mapper041.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper041.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper041.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper042.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper042.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper042.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper042.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper042.h b/References/virtuanessrc097-master/NES/Mapper/Mapper042.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper042.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper042.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper043.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper043.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper043.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper043.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper043.h b/References/virtuanessrc097-master/NES/Mapper/Mapper043.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper043.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper043.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper044.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper044.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper044.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper044.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper044.h b/References/virtuanessrc097-master/NES/Mapper/Mapper044.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper044.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper044.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper045.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper045.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper045.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper045.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper045.h b/References/virtuanessrc097-master/NES/Mapper/Mapper045.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper045.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper045.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper046.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper046.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper046.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper046.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper046.h b/References/virtuanessrc097-master/NES/Mapper/Mapper046.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper046.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper046.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper047.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper047.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper047.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper047.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper047.h b/References/virtuanessrc097-master/NES/Mapper/Mapper047.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper047.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper047.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper048.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper048.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper048.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper048.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper048.h b/References/virtuanessrc097-master/NES/Mapper/Mapper048.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper048.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper048.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper050.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper050.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper050.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper050.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper050.h b/References/virtuanessrc097-master/NES/Mapper/Mapper050.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper050.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper050.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper051.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper051.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper051.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper051.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper051.h b/References/virtuanessrc097-master/NES/Mapper/Mapper051.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper051.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper051.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper057.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper057.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper057.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper057.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper057.h b/References/virtuanessrc097-master/NES/Mapper/Mapper057.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper057.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper057.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper058.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper058.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper058.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper058.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper058.h b/References/virtuanessrc097-master/NES/Mapper/Mapper058.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper058.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper058.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper060.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper060.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper060.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper060.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper060.h b/References/virtuanessrc097-master/NES/Mapper/Mapper060.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper060.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper060.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper061.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper061.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper061.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper061.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper061.h b/References/virtuanessrc097-master/NES/Mapper/Mapper061.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper061.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper061.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper062.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper062.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper062.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper062.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper062.h b/References/virtuanessrc097-master/NES/Mapper/Mapper062.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper062.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper062.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper064.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper064.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper064.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper064.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper064.h b/References/virtuanessrc097-master/NES/Mapper/Mapper064.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper064.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper064.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper065.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper065.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper065.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper065.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper065.h b/References/virtuanessrc097-master/NES/Mapper/Mapper065.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper065.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper065.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper066.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper066.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper066.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper066.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper066.h b/References/virtuanessrc097-master/NES/Mapper/Mapper066.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper066.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper066.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper067.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper067.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper067.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper067.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper067.h b/References/virtuanessrc097-master/NES/Mapper/Mapper067.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper067.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper067.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper068.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper068.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper068.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper068.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper068.h b/References/virtuanessrc097-master/NES/Mapper/Mapper068.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper068.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper068.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper069.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper069.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper069.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper069.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper069.h b/References/virtuanessrc097-master/NES/Mapper/Mapper069.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper069.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper069.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper070.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper070.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper070.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper070.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper070.h b/References/virtuanessrc097-master/NES/Mapper/Mapper070.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper070.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper070.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper071.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper071.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper071.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper071.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper071.h b/References/virtuanessrc097-master/NES/Mapper/Mapper071.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper071.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper071.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper072.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper072.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper072.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper072.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper072.h b/References/virtuanessrc097-master/NES/Mapper/Mapper072.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper072.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper072.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper073.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper073.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper073.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper073.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper073.h b/References/virtuanessrc097-master/NES/Mapper/Mapper073.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper073.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper073.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper074.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper074.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper074.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper074.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper074.h b/References/virtuanessrc097-master/NES/Mapper/Mapper074.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper074.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper074.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper075.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper075.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper075.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper075.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper075.h b/References/virtuanessrc097-master/NES/Mapper/Mapper075.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper075.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper075.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper076.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper076.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper076.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper076.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper076.h b/References/virtuanessrc097-master/NES/Mapper/Mapper076.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper076.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper076.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper077.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper077.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper077.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper077.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper077.h b/References/virtuanessrc097-master/NES/Mapper/Mapper077.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper077.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper077.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper078.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper078.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper078.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper078.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper078.h b/References/virtuanessrc097-master/NES/Mapper/Mapper078.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper078.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper078.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper079.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper079.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper079.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper079.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper079.h b/References/virtuanessrc097-master/NES/Mapper/Mapper079.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper079.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper079.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper080.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper080.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper080.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper080.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper080.h b/References/virtuanessrc097-master/NES/Mapper/Mapper080.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper080.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper080.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper082.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper082.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper082.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper082.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper082.h b/References/virtuanessrc097-master/NES/Mapper/Mapper082.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper082.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper082.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper083.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper083.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper083.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper083.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper083.h b/References/virtuanessrc097-master/NES/Mapper/Mapper083.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper083.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper083.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper085.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper085.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper085.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper085.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper085.h b/References/virtuanessrc097-master/NES/Mapper/Mapper085.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper085.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper085.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper086.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper086.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper086.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper086.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper086.h b/References/virtuanessrc097-master/NES/Mapper/Mapper086.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper086.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper086.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper087.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper087.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper087.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper087.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper087.h b/References/virtuanessrc097-master/NES/Mapper/Mapper087.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper087.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper087.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper088.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper088.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper088.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper088.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper088.h b/References/virtuanessrc097-master/NES/Mapper/Mapper088.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper088.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper088.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper089.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper089.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper089.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper089.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper089.h b/References/virtuanessrc097-master/NES/Mapper/Mapper089.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper089.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper089.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper090.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper090.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper090.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper090.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper090.h b/References/virtuanessrc097-master/NES/Mapper/Mapper090.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper090.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper090.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper091.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper091.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper091.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper091.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper091.h b/References/virtuanessrc097-master/NES/Mapper/Mapper091.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper091.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper091.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper092.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper092.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper092.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper092.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper092.h b/References/virtuanessrc097-master/NES/Mapper/Mapper092.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper092.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper092.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper093.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper093.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper093.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper093.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper093.h b/References/virtuanessrc097-master/NES/Mapper/Mapper093.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper093.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper093.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper094.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper094.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper094.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper094.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper094.h b/References/virtuanessrc097-master/NES/Mapper/Mapper094.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper094.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper094.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper095.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper095.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper095.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper095.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper095.h b/References/virtuanessrc097-master/NES/Mapper/Mapper095.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper095.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper095.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper096.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper096.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper096.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper096.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper096.h b/References/virtuanessrc097-master/NES/Mapper/Mapper096.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper096.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper096.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper097.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper097.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper097.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper097.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper097.h b/References/virtuanessrc097-master/NES/Mapper/Mapper097.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper097.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper097.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper099.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper099.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper099.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper099.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper099.h b/References/virtuanessrc097-master/NES/Mapper/Mapper099.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper099.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper099.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper100.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper100.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper100.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper100.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper100.h b/References/virtuanessrc097-master/NES/Mapper/Mapper100.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper100.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper100.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper101.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper101.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper101.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper101.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper101.h b/References/virtuanessrc097-master/NES/Mapper/Mapper101.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper101.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper101.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper105.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper105.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper105.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper105.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper105.h b/References/virtuanessrc097-master/NES/Mapper/Mapper105.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper105.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper105.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper107.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper107.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper107.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper107.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper107.h b/References/virtuanessrc097-master/NES/Mapper/Mapper107.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper107.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper107.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper108.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper108.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper108.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper108.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper108.h b/References/virtuanessrc097-master/NES/Mapper/Mapper108.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper108.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper108.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper109.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper109.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper109.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper109.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper109.h b/References/virtuanessrc097-master/NES/Mapper/Mapper109.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper109.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper109.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper110.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper110.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper110.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper110.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper110.h b/References/virtuanessrc097-master/NES/Mapper/Mapper110.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper110.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper110.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper112.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper112.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper112.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper112.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper112.h b/References/virtuanessrc097-master/NES/Mapper/Mapper112.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper112.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper112.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper113.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper113.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper113.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper113.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper113.h b/References/virtuanessrc097-master/NES/Mapper/Mapper113.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper113.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper113.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper114.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper114.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper114.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper114.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper114.h b/References/virtuanessrc097-master/NES/Mapper/Mapper114.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper114.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper114.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper115.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper115.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper115.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper115.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper115.h b/References/virtuanessrc097-master/NES/Mapper/Mapper115.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper115.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper115.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper116.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper116.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper116.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper116.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper116.h b/References/virtuanessrc097-master/NES/Mapper/Mapper116.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper116.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper116.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper117.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper117.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper117.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper117.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper117.h b/References/virtuanessrc097-master/NES/Mapper/Mapper117.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper117.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper117.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper118.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper118.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper118.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper118.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper118.h b/References/virtuanessrc097-master/NES/Mapper/Mapper118.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper118.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper118.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper119.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper119.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper119.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper119.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper119.h b/References/virtuanessrc097-master/NES/Mapper/Mapper119.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper119.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper119.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper122.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper122.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper122.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper122.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper122.h b/References/virtuanessrc097-master/NES/Mapper/Mapper122.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper122.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper122.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper133.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper133.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper133.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper133.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper133.h b/References/virtuanessrc097-master/NES/Mapper/Mapper133.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper133.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper133.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper134.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper134.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper134.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper134.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper134.h b/References/virtuanessrc097-master/NES/Mapper/Mapper134.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper134.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper134.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper135.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper135.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper135.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper135.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper135.h b/References/virtuanessrc097-master/NES/Mapper/Mapper135.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper135.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper135.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper140.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper140.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper140.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper140.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper140.h b/References/virtuanessrc097-master/NES/Mapper/Mapper140.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper140.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper140.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper142.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper142.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper142.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper142.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper142.h b/References/virtuanessrc097-master/NES/Mapper/Mapper142.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper142.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper142.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper151.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper151.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper151.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper151.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper151.h b/References/virtuanessrc097-master/NES/Mapper/Mapper151.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper151.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper151.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper160.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper160.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper160.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper160.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper160.h b/References/virtuanessrc097-master/NES/Mapper/Mapper160.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper160.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper160.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper164.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper164.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper164.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper164.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper164.h b/References/virtuanessrc097-master/NES/Mapper/Mapper164.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper164.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper164.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper165.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper165.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper165.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper165.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper165.h b/References/virtuanessrc097-master/NES/Mapper/Mapper165.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper165.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper165.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper167.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper167.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper167.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper167.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper167.h b/References/virtuanessrc097-master/NES/Mapper/Mapper167.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper167.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper167.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper180.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper180.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper180.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper180.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper180.h b/References/virtuanessrc097-master/NES/Mapper/Mapper180.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper180.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper180.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper181.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper181.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper181.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper181.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper181.h b/References/virtuanessrc097-master/NES/Mapper/Mapper181.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper181.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper181.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper182.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper182.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper182.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper182.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper182.h b/References/virtuanessrc097-master/NES/Mapper/Mapper182.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper182.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper182.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper183.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper183.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper183.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper183.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper183.h b/References/virtuanessrc097-master/NES/Mapper/Mapper183.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper183.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper183.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper185.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper185.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper185.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper185.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper185.h b/References/virtuanessrc097-master/NES/Mapper/Mapper185.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper185.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper185.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper187.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper187.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper187.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper187.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper187.h b/References/virtuanessrc097-master/NES/Mapper/Mapper187.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper187.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper187.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper188.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper188.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper188.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper188.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper188.h b/References/virtuanessrc097-master/NES/Mapper/Mapper188.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper188.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper188.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper189.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper189.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper189.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper189.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper189.h b/References/virtuanessrc097-master/NES/Mapper/Mapper189.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper189.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper189.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper190.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper190.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper190.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper190.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper190.h b/References/virtuanessrc097-master/NES/Mapper/Mapper190.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper190.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper190.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper191.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper191.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper191.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper191.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper191.h b/References/virtuanessrc097-master/NES/Mapper/Mapper191.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper191.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper191.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper193.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper193.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper193.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper193.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper193.h b/References/virtuanessrc097-master/NES/Mapper/Mapper193.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper193.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper193.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper194.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper194.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper194.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper194.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper194.h b/References/virtuanessrc097-master/NES/Mapper/Mapper194.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper194.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper194.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper198.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper198.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper198.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper198.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper198.h b/References/virtuanessrc097-master/NES/Mapper/Mapper198.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper198.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper198.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper200.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper200.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper200.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper200.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper200.h b/References/virtuanessrc097-master/NES/Mapper/Mapper200.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper200.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper200.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper201.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper201.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper201.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper201.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper201.h b/References/virtuanessrc097-master/NES/Mapper/Mapper201.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper201.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper201.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper202.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper202.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper202.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper202.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper202.h b/References/virtuanessrc097-master/NES/Mapper/Mapper202.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper202.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper202.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper222.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper222.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper222.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper222.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper222.h b/References/virtuanessrc097-master/NES/Mapper/Mapper222.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper222.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper222.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper225.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper225.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper225.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper225.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper225.h b/References/virtuanessrc097-master/NES/Mapper/Mapper225.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper225.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper225.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper226.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper226.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper226.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper226.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper226.h b/References/virtuanessrc097-master/NES/Mapper/Mapper226.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper226.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper226.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper227.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper227.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper227.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper227.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper227.h b/References/virtuanessrc097-master/NES/Mapper/Mapper227.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper227.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper227.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper228.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper228.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper228.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper228.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper228.h b/References/virtuanessrc097-master/NES/Mapper/Mapper228.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper228.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper228.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper229.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper229.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper229.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper229.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper229.h b/References/virtuanessrc097-master/NES/Mapper/Mapper229.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper229.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper229.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper230.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper230.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper230.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper230.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper230.h b/References/virtuanessrc097-master/NES/Mapper/Mapper230.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper230.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper230.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper231.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper231.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper231.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper231.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper231.h b/References/virtuanessrc097-master/NES/Mapper/Mapper231.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper231.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper231.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper232.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper232.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper232.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper232.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper232.h b/References/virtuanessrc097-master/NES/Mapper/Mapper232.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper232.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper232.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper233.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper233.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper233.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper233.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper233.h b/References/virtuanessrc097-master/NES/Mapper/Mapper233.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper233.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper233.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper234.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper234.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper234.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper234.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper234.h b/References/virtuanessrc097-master/NES/Mapper/Mapper234.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper234.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper234.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper235.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper235.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper235.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper235.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper235.h b/References/virtuanessrc097-master/NES/Mapper/Mapper235.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper235.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper235.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper236.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper236.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper236.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper236.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper236.h b/References/virtuanessrc097-master/NES/Mapper/Mapper236.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper236.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper236.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper240.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper240.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper240.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper240.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper240.h b/References/virtuanessrc097-master/NES/Mapper/Mapper240.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper240.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper240.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper241.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper241.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper241.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper241.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper241.h b/References/virtuanessrc097-master/NES/Mapper/Mapper241.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper241.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper241.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper242.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper242.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper242.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper242.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper242.h b/References/virtuanessrc097-master/NES/Mapper/Mapper242.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper242.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper242.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper243.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper243.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper243.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper243.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper243.h b/References/virtuanessrc097-master/NES/Mapper/Mapper243.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper243.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper243.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper244.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper244.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper244.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper244.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper244.h b/References/virtuanessrc097-master/NES/Mapper/Mapper244.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper244.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper244.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper245.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper245.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper245.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper245.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper245.h b/References/virtuanessrc097-master/NES/Mapper/Mapper245.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper245.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper245.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper246.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper246.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper246.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper246.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper246.h b/References/virtuanessrc097-master/NES/Mapper/Mapper246.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper246.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper246.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper248.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper248.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper248.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper248.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper248.h b/References/virtuanessrc097-master/NES/Mapper/Mapper248.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper248.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper248.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper249.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper249.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper249.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper249.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper249.h b/References/virtuanessrc097-master/NES/Mapper/Mapper249.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper249.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper249.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper251.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper251.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper251.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper251.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper251.h b/References/virtuanessrc097-master/NES/Mapper/Mapper251.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper251.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper251.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper252.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper252.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper252.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper252.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper252.h b/References/virtuanessrc097-master/NES/Mapper/Mapper252.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper252.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper252.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper254.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper254.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper254.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper254.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper254.h b/References/virtuanessrc097-master/NES/Mapper/Mapper254.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper254.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper254.h diff --git a/virtuanessrc097-master/NES/Mapper/Mapper255.cpp b/References/virtuanessrc097-master/NES/Mapper/Mapper255.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper255.cpp rename to References/virtuanessrc097-master/NES/Mapper/Mapper255.cpp diff --git a/virtuanessrc097-master/NES/Mapper/Mapper255.h b/References/virtuanessrc097-master/NES/Mapper/Mapper255.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/Mapper255.h rename to References/virtuanessrc097-master/NES/Mapper/Mapper255.h diff --git a/virtuanessrc097-master/NES/Mapper/MapperFDS.cpp b/References/virtuanessrc097-master/NES/Mapper/MapperFDS.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/MapperFDS.cpp rename to References/virtuanessrc097-master/NES/Mapper/MapperFDS.cpp diff --git a/virtuanessrc097-master/NES/Mapper/MapperFDS.h b/References/virtuanessrc097-master/NES/Mapper/MapperFDS.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/MapperFDS.h rename to References/virtuanessrc097-master/NES/Mapper/MapperFDS.h diff --git a/virtuanessrc097-master/NES/Mapper/MapperFactory.cpp b/References/virtuanessrc097-master/NES/Mapper/MapperFactory.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/MapperFactory.cpp rename to References/virtuanessrc097-master/NES/Mapper/MapperFactory.cpp diff --git a/virtuanessrc097-master/NES/Mapper/MapperNSF.cpp b/References/virtuanessrc097-master/NES/Mapper/MapperNSF.cpp similarity index 100% rename from virtuanessrc097-master/NES/Mapper/MapperNSF.cpp rename to References/virtuanessrc097-master/NES/Mapper/MapperNSF.cpp diff --git a/virtuanessrc097-master/NES/Mapper/MapperNSF.h b/References/virtuanessrc097-master/NES/Mapper/MapperNSF.h similarity index 100% rename from virtuanessrc097-master/NES/Mapper/MapperNSF.h rename to References/virtuanessrc097-master/NES/Mapper/MapperNSF.h diff --git a/virtuanessrc097-master/NES/Nes.cpp b/References/virtuanessrc097-master/NES/Nes.cpp similarity index 100% rename from virtuanessrc097-master/NES/Nes.cpp rename to References/virtuanessrc097-master/NES/Nes.cpp diff --git a/virtuanessrc097-master/NES/Nes.h b/References/virtuanessrc097-master/NES/Nes.h similarity index 100% rename from virtuanessrc097-master/NES/Nes.h rename to References/virtuanessrc097-master/NES/Nes.h diff --git a/virtuanessrc097-master/NES/PAD.cpp b/References/virtuanessrc097-master/NES/PAD.cpp similarity index 100% rename from virtuanessrc097-master/NES/PAD.cpp rename to References/virtuanessrc097-master/NES/PAD.cpp diff --git a/virtuanessrc097-master/NES/PAD.h b/References/virtuanessrc097-master/NES/PAD.h similarity index 100% rename from virtuanessrc097-master/NES/PAD.h rename to References/virtuanessrc097-master/NES/PAD.h diff --git a/virtuanessrc097-master/NES/PPU.cpp b/References/virtuanessrc097-master/NES/PPU.cpp similarity index 100% rename from virtuanessrc097-master/NES/PPU.cpp rename to References/virtuanessrc097-master/NES/PPU.cpp diff --git a/virtuanessrc097-master/NES/PPU.h b/References/virtuanessrc097-master/NES/PPU.h similarity index 100% rename from virtuanessrc097-master/NES/PPU.h rename to References/virtuanessrc097-master/NES/PPU.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_CrazyClimber.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_ExcitingBoxing.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_FamlyTrainer.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Gyromite.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_HyperShot.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Keyboard.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Mahjang.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_OekakidsTablet.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Paddle.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_SpaceShadowGun.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Supor_Keyboard.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Toprider.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_TurboFile.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_VSUnisystem.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_VSZapper.h diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.cpp b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.cpp similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.cpp rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.cpp diff --git a/virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.h b/References/virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.h similarity index 100% rename from virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.h rename to References/virtuanessrc097-master/NES/PadEX/EXPAD_Zapper.h diff --git a/virtuanessrc097-master/NES/ROM.cpp b/References/virtuanessrc097-master/NES/ROM.cpp similarity index 100% rename from virtuanessrc097-master/NES/ROM.cpp rename to References/virtuanessrc097-master/NES/ROM.cpp diff --git a/virtuanessrc097-master/NES/ROM.h b/References/virtuanessrc097-master/NES/ROM.h similarity index 100% rename from virtuanessrc097-master/NES/ROM.h rename to References/virtuanessrc097-master/NES/ROM.h diff --git a/virtuanessrc097-master/NES/ROMDB.cpp b/References/virtuanessrc097-master/NES/ROMDB.cpp similarity index 100% rename from virtuanessrc097-master/NES/ROMDB.cpp rename to References/virtuanessrc097-master/NES/ROMDB.cpp diff --git a/virtuanessrc097-master/NES/ROMDB.h b/References/virtuanessrc097-master/NES/ROMDB.h similarity index 100% rename from virtuanessrc097-master/NES/ROMDB.h rename to References/virtuanessrc097-master/NES/ROMDB.h diff --git a/virtuanessrc097-master/NES/ROM_Patch.cpp b/References/virtuanessrc097-master/NES/ROM_Patch.cpp similarity index 100% rename from virtuanessrc097-master/NES/ROM_Patch.cpp rename to References/virtuanessrc097-master/NES/ROM_Patch.cpp diff --git a/virtuanessrc097-master/NES/State.h b/References/virtuanessrc097-master/NES/State.h similarity index 100% rename from virtuanessrc097-master/NES/State.h rename to References/virtuanessrc097-master/NES/State.h diff --git a/virtuanessrc097-master/NES/VS_Setting.h b/References/virtuanessrc097-master/NES/VS_Setting.h similarity index 100% rename from virtuanessrc097-master/NES/VS_Setting.h rename to References/virtuanessrc097-master/NES/VS_Setting.h diff --git a/virtuanessrc097-master/NES/VsUnisystem.cpp b/References/virtuanessrc097-master/NES/VsUnisystem.cpp similarity index 100% rename from virtuanessrc097-master/NES/VsUnisystem.cpp rename to References/virtuanessrc097-master/NES/VsUnisystem.cpp diff --git a/virtuanessrc097-master/NES/VsUnisystem.h b/References/virtuanessrc097-master/NES/VsUnisystem.h similarity index 100% rename from virtuanessrc097-master/NES/VsUnisystem.h rename to References/virtuanessrc097-master/NES/VsUnisystem.h diff --git a/virtuanessrc097-master/NameTableView.cpp b/References/virtuanessrc097-master/NameTableView.cpp similarity index 100% rename from virtuanessrc097-master/NameTableView.cpp rename to References/virtuanessrc097-master/NameTableView.cpp diff --git a/virtuanessrc097-master/NameTableView.h b/References/virtuanessrc097-master/NameTableView.h similarity index 100% rename from virtuanessrc097-master/NameTableView.h rename to References/virtuanessrc097-master/NameTableView.h diff --git a/virtuanessrc097-master/NetPlay.cpp b/References/virtuanessrc097-master/NetPlay.cpp similarity index 100% rename from virtuanessrc097-master/NetPlay.cpp rename to References/virtuanessrc097-master/NetPlay.cpp diff --git a/virtuanessrc097-master/NetPlay.h b/References/virtuanessrc097-master/NetPlay.h similarity index 100% rename from virtuanessrc097-master/NetPlay.h rename to References/virtuanessrc097-master/NetPlay.h diff --git a/virtuanessrc097-master/NetPlayDlg.cpp b/References/virtuanessrc097-master/NetPlayDlg.cpp similarity index 100% rename from virtuanessrc097-master/NetPlayDlg.cpp rename to References/virtuanessrc097-master/NetPlayDlg.cpp diff --git a/virtuanessrc097-master/NetPlayDlg.h b/References/virtuanessrc097-master/NetPlayDlg.h similarity index 100% rename from virtuanessrc097-master/NetPlayDlg.h rename to References/virtuanessrc097-master/NetPlayDlg.h diff --git a/virtuanessrc097-master/PaletteEdit.cpp b/References/virtuanessrc097-master/PaletteEdit.cpp similarity index 100% rename from virtuanessrc097-master/PaletteEdit.cpp rename to References/virtuanessrc097-master/PaletteEdit.cpp diff --git a/virtuanessrc097-master/PaletteEdit.h b/References/virtuanessrc097-master/PaletteEdit.h similarity index 100% rename from virtuanessrc097-master/PaletteEdit.h rename to References/virtuanessrc097-master/PaletteEdit.h diff --git a/virtuanessrc097-master/PaletteView.cpp b/References/virtuanessrc097-master/PaletteView.cpp similarity index 100% rename from virtuanessrc097-master/PaletteView.cpp rename to References/virtuanessrc097-master/PaletteView.cpp diff --git a/virtuanessrc097-master/PaletteView.h b/References/virtuanessrc097-master/PaletteView.h similarity index 100% rename from virtuanessrc097-master/PaletteView.h rename to References/virtuanessrc097-master/PaletteView.h diff --git a/virtuanessrc097-master/Pathlib.cpp b/References/virtuanessrc097-master/Pathlib.cpp similarity index 100% rename from virtuanessrc097-master/Pathlib.cpp rename to References/virtuanessrc097-master/Pathlib.cpp diff --git a/virtuanessrc097-master/Pathlib.h b/References/virtuanessrc097-master/Pathlib.h similarity index 100% rename from virtuanessrc097-master/Pathlib.h rename to References/virtuanessrc097-master/Pathlib.h diff --git a/virtuanessrc097-master/PatternView.cpp b/References/virtuanessrc097-master/PatternView.cpp similarity index 100% rename from virtuanessrc097-master/PatternView.cpp rename to References/virtuanessrc097-master/PatternView.cpp diff --git a/virtuanessrc097-master/PatternView.h b/References/virtuanessrc097-master/PatternView.h similarity index 100% rename from virtuanessrc097-master/PatternView.h rename to References/virtuanessrc097-master/PatternView.h diff --git a/virtuanessrc097-master/Plugin.cpp b/References/virtuanessrc097-master/Plugin.cpp similarity index 100% rename from virtuanessrc097-master/Plugin.cpp rename to References/virtuanessrc097-master/Plugin.cpp diff --git a/virtuanessrc097-master/Plugin.h b/References/virtuanessrc097-master/Plugin.h similarity index 100% rename from virtuanessrc097-master/Plugin.h rename to References/virtuanessrc097-master/Plugin.h diff --git a/virtuanessrc097-master/Pngwrite.h b/References/virtuanessrc097-master/Pngwrite.h similarity index 100% rename from virtuanessrc097-master/Pngwrite.h rename to References/virtuanessrc097-master/Pngwrite.h diff --git a/virtuanessrc097-master/Recent.cpp b/References/virtuanessrc097-master/Recent.cpp similarity index 100% rename from virtuanessrc097-master/Recent.cpp rename to References/virtuanessrc097-master/Recent.cpp diff --git a/virtuanessrc097-master/Recent.h b/References/virtuanessrc097-master/Recent.h similarity index 100% rename from virtuanessrc097-master/Recent.h rename to References/virtuanessrc097-master/Recent.h diff --git a/virtuanessrc097-master/Registry.cpp b/References/virtuanessrc097-master/Registry.cpp similarity index 100% rename from virtuanessrc097-master/Registry.cpp rename to References/virtuanessrc097-master/Registry.cpp diff --git a/virtuanessrc097-master/Registry.h b/References/virtuanessrc097-master/Registry.h similarity index 100% rename from virtuanessrc097-master/Registry.h rename to References/virtuanessrc097-master/Registry.h diff --git a/virtuanessrc097-master/Render.h b/References/virtuanessrc097-master/Render.h similarity index 100% rename from virtuanessrc097-master/Render.h rename to References/virtuanessrc097-master/Render.h diff --git a/virtuanessrc097-master/Render16bpp.h b/References/virtuanessrc097-master/Render16bpp.h similarity index 100% rename from virtuanessrc097-master/Render16bpp.h rename to References/virtuanessrc097-master/Render16bpp.h diff --git a/virtuanessrc097-master/Render24bpp.h b/References/virtuanessrc097-master/Render24bpp.h similarity index 100% rename from virtuanessrc097-master/Render24bpp.h rename to References/virtuanessrc097-master/Render24bpp.h diff --git a/virtuanessrc097-master/Render32bpp.h b/References/virtuanessrc097-master/Render32bpp.h similarity index 100% rename from virtuanessrc097-master/Render32bpp.h rename to References/virtuanessrc097-master/Render32bpp.h diff --git a/virtuanessrc097-master/Render8bpp.h b/References/virtuanessrc097-master/Render8bpp.h similarity index 100% rename from virtuanessrc097-master/Render8bpp.h rename to References/virtuanessrc097-master/Render8bpp.h diff --git a/virtuanessrc097-master/RomInfoDlg.cpp b/References/virtuanessrc097-master/RomInfoDlg.cpp similarity index 100% rename from virtuanessrc097-master/RomInfoDlg.cpp rename to References/virtuanessrc097-master/RomInfoDlg.cpp diff --git a/virtuanessrc097-master/RomInfoDlg.h b/References/virtuanessrc097-master/RomInfoDlg.h similarity index 100% rename from virtuanessrc097-master/RomInfoDlg.h rename to References/virtuanessrc097-master/RomInfoDlg.h diff --git a/virtuanessrc097-master/ShortcutDlg.cpp b/References/virtuanessrc097-master/ShortcutDlg.cpp similarity index 100% rename from virtuanessrc097-master/ShortcutDlg.cpp rename to References/virtuanessrc097-master/ShortcutDlg.cpp diff --git a/virtuanessrc097-master/ShortcutDlg.h b/References/virtuanessrc097-master/ShortcutDlg.h similarity index 100% rename from virtuanessrc097-master/ShortcutDlg.h rename to References/virtuanessrc097-master/ShortcutDlg.h diff --git a/virtuanessrc097-master/SimpleVirusChecker.c b/References/virtuanessrc097-master/SimpleVirusChecker.c similarity index 100% rename from virtuanessrc097-master/SimpleVirusChecker.c rename to References/virtuanessrc097-master/SimpleVirusChecker.c diff --git a/virtuanessrc097-master/SimpleVirusChecker.h b/References/virtuanessrc097-master/SimpleVirusChecker.h similarity index 100% rename from virtuanessrc097-master/SimpleVirusChecker.h rename to References/virtuanessrc097-master/SimpleVirusChecker.h diff --git a/virtuanessrc097-master/SoundDlg.cpp b/References/virtuanessrc097-master/SoundDlg.cpp similarity index 100% rename from virtuanessrc097-master/SoundDlg.cpp rename to References/virtuanessrc097-master/SoundDlg.cpp diff --git a/virtuanessrc097-master/SoundDlg.h b/References/virtuanessrc097-master/SoundDlg.h similarity index 100% rename from virtuanessrc097-master/SoundDlg.h rename to References/virtuanessrc097-master/SoundDlg.h diff --git a/virtuanessrc097-master/Typedef.h b/References/virtuanessrc097-master/Typedef.h similarity index 100% rename from virtuanessrc097-master/Typedef.h rename to References/virtuanessrc097-master/Typedef.h diff --git a/virtuanessrc097-master/VirtuaNES.dsp b/References/virtuanessrc097-master/VirtuaNES.dsp similarity index 100% rename from virtuanessrc097-master/VirtuaNES.dsp rename to References/virtuanessrc097-master/VirtuaNES.dsp diff --git a/References/virtuanessrc097-master/VirtuaNES.dsw b/References/virtuanessrc097-master/VirtuaNES.dsw new file mode 100644 index 00000000..23a7e333 --- /dev/null +++ b/References/virtuanessrc097-master/VirtuaNES.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# x: ܰ߰ ̧ ҏW܂͍폜Ȃł! + +############################################################################### + +Project: "VirtuaNES"=.\VirtuaNES.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/virtuanessrc097-master/VirtuaNES.opt b/References/virtuanessrc097-master/VirtuaNES.opt similarity index 100% rename from virtuanessrc097-master/VirtuaNES.opt rename to References/virtuanessrc097-master/VirtuaNES.opt diff --git a/virtuanessrc097-master/VirtuaNES.rc b/References/virtuanessrc097-master/VirtuaNES.rc similarity index 100% rename from virtuanessrc097-master/VirtuaNES.rc rename to References/virtuanessrc097-master/VirtuaNES.rc diff --git a/virtuanessrc097-master/VirtuaNES.sln b/References/virtuanessrc097-master/VirtuaNES.sln similarity index 100% rename from virtuanessrc097-master/VirtuaNES.sln rename to References/virtuanessrc097-master/VirtuaNES.sln diff --git a/virtuanessrc097-master/VirtuaNES.vcxproj b/References/virtuanessrc097-master/VirtuaNES.vcxproj similarity index 98% rename from virtuanessrc097-master/VirtuaNES.vcxproj rename to References/virtuanessrc097-master/VirtuaNES.vcxproj index 1fbde566..cd68808f 100644 --- a/virtuanessrc097-master/VirtuaNES.vcxproj +++ b/References/virtuanessrc097-master/VirtuaNES.vcxproj @@ -1,2426 +1,2426 @@ - - - - - Debug - Win32 - - - Profile - Win32 - - - Release_Debugout - Win32 - - - Release - Win32 - - - - - - {788F7F02-C4F5-4477-8429-CB02507855EA} - 10.0 - - - - Application - v110 - false - MultiByte - - - Application - v110 - false - MultiByte - - - Application - v143 - false - MultiByte - - - Application - v110 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - .\ - .\Profile\ - false - - - .\ - .\Debug\ - true - - - .\ - .\Release\ - false - - - .\ - .\Release_Debugout\ - false - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - OldStyle - .;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;Zlib;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - .\Profile\ - .\Profile\VirtuaNES.pch - .\Profile\ - .\Profile\ - - - true - NDEBUG;%(PreprocessorDefinitions) - .\VirtuaNES.tlb - true - Win32 - - - 0x0411 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\VirtuaNES.bsc - - - true - true - Windows - false - .\VirtuaNES.exe - odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - MultiThreadedDebugDLL - Default - false - Disabled - true - Level3 - true - ProgramDatabase - .;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;Zlib;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - .\Debug\ - .\Debug\VirtuaNES.pch - .\Debug\ - .\Debug\ - EnableFastChecks - /ZI- %(AdditionalOptions) - - - true - _DEBUG;%(PreprocessorDefinitions) - .\VirtuaNES.tlb - true - Win32 - - - 0x0411 - _DEBUG;%(PreprocessorDefinitions) - - - true - .\VirtuaNES.bsc - - - true - true - Windows - false - .\VirtuaNES.exe - odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) - false - - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - Zlib;.;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - .\Release\ - .\Release\VirtuaNES.pch - .\Release\ - .\Release\ - - - true - NDEBUG;%(PreprocessorDefinitions) - .\VirtuaNES.tlb - true - Win32 - - - 0x0411 - res;%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions) - - - true - .\VirtuaNES.bsc - - - true - Windows - false - .\VirtuaNES.exe - odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - MultiThreaded - Default - true - true - MaxSpeed - true - Level3 - OldStyle - .;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;Zlib;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_DEBUGOUT;%(PreprocessorDefinitions) - .\Release_Debugout\ - .\Release_Debugout\VirtuaNES.pch - .\Release_Debugout\ - .\Release_Debugout\ - - - true - NDEBUG;%(PreprocessorDefinitions) - .\VirtuaNES.tlb - true - Win32 - - - 0x0411 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\VirtuaNES.bsc - - - true - true - Windows - false - .\VirtuaNES.exe - odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - - - true - true - true - - - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - - - true - true - true - - - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Profile + Win32 + + + Release_Debugout + Win32 + + + Release + Win32 + + + + + + {788F7F02-C4F5-4477-8429-CB02507855EA} + 10.0 + + + + Application + v110 + false + MultiByte + + + Application + v110 + false + MultiByte + + + Application + v143 + false + MultiByte + + + Application + v110 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + .\ + .\Profile\ + false + + + .\ + .\Debug\ + true + + + .\ + .\Release\ + false + + + .\ + .\Release_Debugout\ + false + + + + MultiThreaded + Default + true + true + MaxSpeed + true + Level3 + OldStyle + .;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;Zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\Profile\ + .\Profile\VirtuaNES.pch + .\Profile\ + .\Profile\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\VirtuaNES.tlb + true + Win32 + + + 0x0411 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\VirtuaNES.bsc + + + true + true + Windows + false + .\VirtuaNES.exe + odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + MultiThreadedDebugDLL + Default + false + Disabled + true + Level3 + true + ProgramDatabase + .;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;Zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + .\Debug\ + .\Debug\VirtuaNES.pch + .\Debug\ + .\Debug\ + EnableFastChecks + /ZI- %(AdditionalOptions) + + + true + _DEBUG;%(PreprocessorDefinitions) + .\VirtuaNES.tlb + true + Win32 + + + 0x0411 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\VirtuaNES.bsc + + + true + true + Windows + false + .\VirtuaNES.exe + odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) + false + + + + + MultiThreaded + Default + true + true + MaxSpeed + true + Level3 + Zlib;.;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + .\Release\ + .\Release\VirtuaNES.pch + .\Release\ + .\Release\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\VirtuaNES.tlb + true + Win32 + + + 0x0411 + res;%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + true + .\VirtuaNES.bsc + + + true + Windows + false + .\VirtuaNES.exe + odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + MultiThreaded + Default + true + true + MaxSpeed + true + Level3 + OldStyle + .;NES;NES\Mapper;NES\ApuEx;NES\ApuEx\emu2413;NES\PadEx;Zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_DEBUGOUT;%(PreprocessorDefinitions) + .\Release_Debugout\ + .\Release_Debugout\VirtuaNES.pch + .\Release_Debugout\ + .\Release_Debugout\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\VirtuaNES.tlb + true + Win32 + + + 0x0411 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\VirtuaNES.bsc + + + true + true + Windows + false + .\VirtuaNES.exe + odbc32.lib;odbccp32.lib;winmm.lib;comctl32.lib;imm32.lib;dinput8.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/virtuanessrc097-master/VirtuaNES.vcxproj.filters b/References/virtuanessrc097-master/VirtuaNES.vcxproj.filters similarity index 100% rename from virtuanessrc097-master/VirtuaNES.vcxproj.filters rename to References/virtuanessrc097-master/VirtuaNES.vcxproj.filters diff --git a/virtuanessrc097-master/VirtuaNESres.h b/References/virtuanessrc097-master/VirtuaNESres.h similarity index 100% rename from virtuanessrc097-master/VirtuaNESres.h rename to References/virtuanessrc097-master/VirtuaNESres.h diff --git a/virtuanessrc097-master/WaveRec.cpp b/References/virtuanessrc097-master/WaveRec.cpp similarity index 100% rename from virtuanessrc097-master/WaveRec.cpp rename to References/virtuanessrc097-master/WaveRec.cpp diff --git a/virtuanessrc097-master/WaveRec.h b/References/virtuanessrc097-master/WaveRec.h similarity index 100% rename from virtuanessrc097-master/WaveRec.h rename to References/virtuanessrc097-master/WaveRec.h diff --git a/virtuanessrc097-master/WinMain.cpp b/References/virtuanessrc097-master/WinMain.cpp similarity index 100% rename from virtuanessrc097-master/WinMain.cpp rename to References/virtuanessrc097-master/WinMain.cpp diff --git a/virtuanessrc097-master/Wnd.cpp b/References/virtuanessrc097-master/Wnd.cpp similarity index 100% rename from virtuanessrc097-master/Wnd.cpp rename to References/virtuanessrc097-master/Wnd.cpp diff --git a/virtuanessrc097-master/Wnd.h b/References/virtuanessrc097-master/Wnd.h similarity index 100% rename from virtuanessrc097-master/Wnd.h rename to References/virtuanessrc097-master/Wnd.h diff --git a/virtuanessrc097-master/WndHook.cpp b/References/virtuanessrc097-master/WndHook.cpp similarity index 100% rename from virtuanessrc097-master/WndHook.cpp rename to References/virtuanessrc097-master/WndHook.cpp diff --git a/virtuanessrc097-master/WndHook.h b/References/virtuanessrc097-master/WndHook.h similarity index 100% rename from virtuanessrc097-master/WndHook.h rename to References/virtuanessrc097-master/WndHook.h diff --git a/virtuanessrc097-master/hq2x.h b/References/virtuanessrc097-master/hq2x.h similarity index 100% rename from virtuanessrc097-master/hq2x.h rename to References/virtuanessrc097-master/hq2x.h diff --git a/virtuanessrc097-master/interp.h b/References/virtuanessrc097-master/interp.h similarity index 100% rename from virtuanessrc097-master/interp.h rename to References/virtuanessrc097-master/interp.h diff --git a/virtuanessrc097-master/lq2x.h b/References/virtuanessrc097-master/lq2x.h similarity index 100% rename from virtuanessrc097-master/lq2x.h rename to References/virtuanessrc097-master/lq2x.h diff --git a/virtuanessrc097-master/lzAscii.h b/References/virtuanessrc097-master/lzAscii.h similarity index 100% rename from virtuanessrc097-master/lzAscii.h rename to References/virtuanessrc097-master/lzAscii.h diff --git a/virtuanessrc097-master/lzSight.h b/References/virtuanessrc097-master/lzSight.h similarity index 100% rename from virtuanessrc097-master/lzSight.h rename to References/virtuanessrc097-master/lzSight.h diff --git a/virtuanessrc097-master/lzTVlayer.h b/References/virtuanessrc097-master/lzTVlayer.h similarity index 100% rename from virtuanessrc097-master/lzTVlayer.h rename to References/virtuanessrc097-master/lzTVlayer.h diff --git a/virtuanessrc097-master/nx_2xSaI.h b/References/virtuanessrc097-master/nx_2xSaI.h similarity index 100% rename from virtuanessrc097-master/nx_2xSaI.h rename to References/virtuanessrc097-master/nx_2xSaI.h diff --git a/virtuanessrc097-master/nx_Scale2x.h b/References/virtuanessrc097-master/nx_Scale2x.h similarity index 100% rename from virtuanessrc097-master/nx_Scale2x.h rename to References/virtuanessrc097-master/nx_Scale2x.h diff --git a/virtuanessrc097-master/nx_Super2xSaI.h b/References/virtuanessrc097-master/nx_Super2xSaI.h similarity index 100% rename from virtuanessrc097-master/nx_Super2xSaI.h rename to References/virtuanessrc097-master/nx_Super2xSaI.h diff --git a/virtuanessrc097-master/nx_SuperEagle.h b/References/virtuanessrc097-master/nx_SuperEagle.h similarity index 100% rename from virtuanessrc097-master/nx_SuperEagle.h rename to References/virtuanessrc097-master/nx_SuperEagle.h diff --git a/virtuanessrc097-master/nx_hq2x.h b/References/virtuanessrc097-master/nx_hq2x.h similarity index 100% rename from virtuanessrc097-master/nx_hq2x.h rename to References/virtuanessrc097-master/nx_hq2x.h diff --git a/References/virtuanessrc097-master/res/CheatImageList.bmp b/References/virtuanessrc097-master/res/CheatImageList.bmp new file mode 100644 index 00000000..5def99ee Binary files /dev/null and b/References/virtuanessrc097-master/res/CheatImageList.bmp differ diff --git a/References/virtuanessrc097-master/res/LauncherImageList.bmp b/References/virtuanessrc097-master/res/LauncherImageList.bmp new file mode 100644 index 00000000..d8102bd2 Binary files /dev/null and b/References/virtuanessrc097-master/res/LauncherImageList.bmp differ diff --git a/virtuanessrc097-master/res/VirtuaNES.exe.manifest b/References/virtuanessrc097-master/res/VirtuaNES.exe.manifest similarity index 100% rename from virtuanessrc097-master/res/VirtuaNES.exe.manifest rename to References/virtuanessrc097-master/res/VirtuaNES.exe.manifest diff --git a/References/virtuanessrc097-master/res/VirtuaNES.ico b/References/virtuanessrc097-master/res/VirtuaNES.ico new file mode 100644 index 00000000..6d8e88da Binary files /dev/null and b/References/virtuanessrc097-master/res/VirtuaNES.ico differ diff --git a/References/virtuanessrc097-master/res/header_down.ico b/References/virtuanessrc097-master/res/header_down.ico new file mode 100644 index 00000000..31a8c39c Binary files /dev/null and b/References/virtuanessrc097-master/res/header_down.ico differ diff --git a/References/virtuanessrc097-master/res/header_up.ico b/References/virtuanessrc097-master/res/header_up.ico new file mode 100644 index 00000000..ad96699c Binary files /dev/null and b/References/virtuanessrc097-master/res/header_up.ico differ diff --git a/virtuanessrc097-master/resource.h b/References/virtuanessrc097-master/resource.h similarity index 100% rename from virtuanessrc097-master/resource.h rename to References/virtuanessrc097-master/resource.h diff --git a/References/virtuanessrc097-master/zlib/unzip.c b/References/virtuanessrc097-master/zlib/unzip.c new file mode 100644 index 00000000..ff71a474 --- /dev/null +++ b/References/virtuanessrc097-master/zlib/unzip.c @@ -0,0 +1,1294 @@ +/* unzip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read unzip.h for more info +*/ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char unz_copyright[] = + " unzip 0.15 Copyright 1998 Gilles Vollant "; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + FILE* file; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + FILE* file; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ +} unz_s; + + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte(fin,pi) + FILE *fin; + int *pi; +{ + unsigned char c; + int err = fread(&c, 1, 1, fin); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ferror(fin)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir(fin) + FILE *fin; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) + return 0; + + + uSizeFile = ftell( fin ); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) + break; + + if (fread(buf,(uInt)uReadSize,1,fin)!=1) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen (path) + const char *path; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + FILE * fin ; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + fin=fopen(path,"rb"); + if (fin==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; + + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + fclose(s->file); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { + uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} diff --git a/virtuanessrc097-master/zlib/unzip.h b/References/virtuanessrc097-master/zlib/unzip.h similarity index 100% rename from virtuanessrc097-master/zlib/unzip.h rename to References/virtuanessrc097-master/zlib/unzip.h diff --git a/virtuanessrc097-master/zlib/zconf.h b/References/virtuanessrc097-master/zlib/zconf.h similarity index 100% rename from virtuanessrc097-master/zlib/zconf.h rename to References/virtuanessrc097-master/zlib/zconf.h diff --git a/virtuanessrc097-master/zlib/zlib.h b/References/virtuanessrc097-master/zlib/zlib.h similarity index 100% rename from virtuanessrc097-master/zlib/zlib.h rename to References/virtuanessrc097-master/zlib/zlib.h