From 4709f81b2b8e2488f039fdebf2f9f72bdcf94e7f Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 21:12:24 +0530 Subject: [PATCH 1/9] Make emusys --- gbemu/gbemu/common/emusys.h | 18 ++++++++++++++++++ gbemu/gbemu/common/endianness.h | 2 ++ gbemu/gbemu/common/stream.h | 2 ++ gbemu/gbemu/gbemu.cpp | 17 +++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 gbemu/gbemu/common/emusys.h create mode 100644 gbemu/gbemu/common/endianness.h create mode 100644 gbemu/gbemu/common/stream.h create mode 100644 gbemu/gbemu/gbemu.cpp diff --git a/gbemu/gbemu/common/emusys.h b/gbemu/gbemu/common/emusys.h new file mode 100644 index 0000000..21f495a --- /dev/null +++ b/gbemu/gbemu/common/emusys.h @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char byte; +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned int uint; +typedef signed long long int64; +typedef unsigned long long uint64; \ No newline at end of file diff --git a/gbemu/gbemu/common/endianness.h b/gbemu/gbemu/common/endianness.h new file mode 100644 index 0000000..66f48b5 --- /dev/null +++ b/gbemu/gbemu/common/endianness.h @@ -0,0 +1,2 @@ +#include "emusys.h" + diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h new file mode 100644 index 0000000..dffb63a --- /dev/null +++ b/gbemu/gbemu/common/stream.h @@ -0,0 +1,2 @@ +//Taken from ScummVM's Common::Stream + diff --git a/gbemu/gbemu/gbemu.cpp b/gbemu/gbemu/gbemu.cpp new file mode 100644 index 0000000..d5c5338 --- /dev/null +++ b/gbemu/gbemu/gbemu.cpp @@ -0,0 +1,17 @@ +#include + +int main() +{ + std::cout << "Hello World!\n"; +} + +// Run program: Ctrl + F5 or Debug > Start Without Debugging menu +// Debug program: F5 or Debug > Start Debugging menu + +// Tips for Getting Started: +// 1. Use the Solution Explorer window to add/manage files +// 2. Use the Team Explorer window to connect to source control +// 3. Use the Output window to see build output and other messages +// 4. Use the Error List window to view errors +// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project +// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file From be7e079b96dcf1e5c8736b48bd83325653c3899d Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 21:56:37 +0530 Subject: [PATCH 2/9] Remove iostream --- gbemu/gbemu/common/emusys.h | 3 +++ gbemu/gbemu/common/endianness.h | 27 +++++++++++++++++++++++++++ gbemu/gbemu/common/stream.h | 1 + gbemu/gbemu/gbemu.cpp | 7 +++++-- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/gbemu/gbemu/common/emusys.h b/gbemu/gbemu/common/emusys.h index 21f495a..a976d32 100644 --- a/gbemu/gbemu/common/emusys.h +++ b/gbemu/gbemu/common/emusys.h @@ -6,6 +6,9 @@ #include #include +#define _USE_MATH_DEFINES +#include + typedef unsigned char byte; typedef unsigned char uint8; typedef signed char int8; diff --git a/gbemu/gbemu/common/endianness.h b/gbemu/gbemu/common/endianness.h index 66f48b5..e155a10 100644 --- a/gbemu/gbemu/common/endianness.h +++ b/gbemu/gbemu/common/endianness.h @@ -1,2 +1,29 @@ #include "emusys.h" +// Below macros are used for converting +// Little Endian data to Big Endian and vice versa +// This uses MSVC's and GCC's stdlib header +// Using inline implmentations for other compilers +#if defined(__GNUC__) + #define SWAP_BYTES_64(a) __builtin_bswap64(a) + #define SWAP_BYTES_32(a) __builtin_bswap32(a) + #define SWAP_BYTES_16(a) __builtin_bswap16(a) +#elif defined(_MSC_VER) + #define SWAP_BYTES_64(a) _byteswap_uint64(a) + #define SWAP_BYTES_32(a) _byteswap_ulong(a) + #define SWAP_BYTES_16(a) _byteswap_ushort(a) +#else + inline uint64 SWAP_BYTES_64(uint64 a) { + uint32 low = (uint32)a, high = (uint32)(a >> 32); + uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16), highLow = (uint16)high, highHigh = (uint16)(high >> 16); + + return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) | (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) | (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) | (uint16)((highHigh >> 8) | (highHigh << 8))); + } + inline uint32 SWAP_BYTES_32(uint32 a) { + const uint16 low = (uint16)a, high = (uint16)(a >> 16); + return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16) | (uint16)((high >> 8) | (high << 8)); + } + inline uint16 SWAP_BYTES_16(const uint16 a) { + return (a >> 8) | (a << 8); + } +#endif \ No newline at end of file diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index dffb63a..ecfb8a2 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -1,2 +1,3 @@ //Taken from ScummVM's Common::Stream +#include "endianness.h" \ No newline at end of file diff --git a/gbemu/gbemu/gbemu.cpp b/gbemu/gbemu/gbemu.cpp index d5c5338..1ed8e48 100644 --- a/gbemu/gbemu/gbemu.cpp +++ b/gbemu/gbemu/gbemu.cpp @@ -1,8 +1,11 @@ -#include +#include "common/stream.h" int main() { - std::cout << "Hello World!\n"; + char* k = new char[10]; + printf_s("Hello World\n"); + scanf_s(k); + return 0; } // Run program: Ctrl + F5 or Debug > Start Without Debugging menu From 4f2d0f3597eb4db0a94282f7d6748b524cb31339 Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 22:05:21 +0530 Subject: [PATCH 3/9] Create Stream --- gbemu/gbemu/common/stream.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index ecfb8a2..4bbaf6e 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -1,3 +1,17 @@ //Taken from ScummVM's Common::Stream -#include "endianness.h" \ No newline at end of file +#include "endianness.h" + +namespace Common { + class Stream { + virtual ~Stream() {} + + // Below functions throw error and reset the error flag + // Similar to ferror() and clearerr() + + virtual bool err() const { return false; } + virtual void clearError() {} + }; + + +} \ No newline at end of file From e6d8063f8818fc72ea398203f3a7b321778e10c2 Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 22:12:22 +0530 Subject: [PATCH 4/9] Create ReadStream --- gbemu/gbemu/common/stream.h | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index 4bbaf6e..979f6ee 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -4,14 +4,25 @@ namespace Common { class Stream { - virtual ~Stream() {} + public: + virtual ~Stream() {} - // Below functions throw error and reset the error flag - // Similar to ferror() and clearerr() + // Below functions throw error and reset the error flag + // Similar to ferror() and clearerr() - virtual bool err() const { return false; } - virtual void clearError() {} + virtual bool err() const { return false; } + virtual void clearError() {} }; + class ReadStream : virtual public Stream { + public: + ReadStream() {} + + // End of stream interface + virtual bool eos() const = 0; + + // Read interface + virtual uint32 read(void *dataPtr, uint32 dataSize) = 0; + }; } \ No newline at end of file From 751c97000020f5b20a93a0138b9fdc0e56f79f04 Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 22:23:59 +0530 Subject: [PATCH 5/9] Initialize readByte and readSByte --- gbemu/gbemu/common/endianness.h | 7 ++++++- gbemu/gbemu/common/stream.h | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gbemu/gbemu/common/endianness.h b/gbemu/gbemu/common/endianness.h index e155a10..0d933b0 100644 --- a/gbemu/gbemu/common/endianness.h +++ b/gbemu/gbemu/common/endianness.h @@ -26,4 +26,9 @@ inline uint16 SWAP_BYTES_16(const uint16 a) { return (a >> 8) | (a << 8); } -#endif \ No newline at end of file +#endif + + +// We assume the machine to be Little Endian by default +#define LITTLE_ENDIAN true +#define BIG_ENDIAN false \ No newline at end of file diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index 979f6ee..9404cd4 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -23,6 +23,16 @@ namespace Common { // Read interface virtual uint32 read(void *dataPtr, uint32 dataSize) = 0; + + byte readByte() { + byte b = 0; + read(&b, 1); + return b; + } + + byte readSByte() { + return (int8) readByte(); + } }; } \ No newline at end of file From 29bf0a1ecaa82c9fff1e53fb7d4ce944f335da0f Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 22:39:58 +0530 Subject: [PATCH 6/9] complete endianness.h --- gbemu/gbemu/common/endianness.h | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/gbemu/gbemu/common/endianness.h b/gbemu/gbemu/common/endianness.h index 0d933b0..e74cd64 100644 --- a/gbemu/gbemu/common/endianness.h +++ b/gbemu/gbemu/common/endianness.h @@ -30,5 +30,70 @@ // We assume the machine to be Little Endian by default +// As this is running on Intel, AMD and Apple Silicon chips +// Will add compatibility for Big Endian machine later + +inline uint16 READ_UINT16(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[1] << 8) | b[0]; +} + +inline uint32 READ_UINT32(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]); +} + +inline uint64 READ_UINT64(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return ((uint64)b[7] << 56) | ((uint64)b[6] << 48) | ((uint64)b[5] << 40) | ((uint64)b[4] << 32) | ((uint64)b[3] << 24) | ((uint64)b[2] << 16) | ((uint64)b[1] << 8) | ((uint64)b[0]); +} + +inline void WRITE_UINT16(void *ptr, uint16 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); +} + +inline void WRITE_UINT32(void *ptr, uint32 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); + b[2] = (uint8)(value >> 16); + b[3] = (uint8)(value >> 24); +} + +inline void WRITE_UINT64(void *ptr, uint64 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); + b[2] = (uint8)(value >> 16); + b[3] = (uint8)(value >> 24); + b[4] = (uint8)(value >> 32); + b[5] = (uint8)(value >> 40); + b[6] = (uint8)(value >> 48); + b[7] = (uint8)(value >> 56); +} + +// Used in Common::Stream +#define READ_LE_UINT16(a) READ_UINT16(a) +#define READ_LE_UINT32(a) READ_UINT32(a) +#define READ_LE_UINT64(a) READ_UINT64(a) +#define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v) +#define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v) +#define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v) +#define FROM_LE_16(a) ((uint16)(a)) +#define FROM_LE_32(a) ((uint32)(a)) +#define FROM_LE_64(a) ((uint64)(a)) +#define FROM_BE_16(a) SWAP_BYTES_16(a) +#define FROM_BE_32(a) SWAP_BYTES_32(a) +#define FROM_BE_64(a) SWAP_BYTES_64(a) +#define TO_LE_16(a) ((uint16)(a)) +#define TO_LE_32(a) ((uint32)(a)) +#define TO_LE_64(a) ((uint64)(a)) +#define TO_BE_16(a) SWAP_BYTES_16(a) +#define TO_BE_32(a) SWAP_BYTES_32(a) +#define TO_BE_64(a) SWAP_BYTES_64(a) + +// Might come handy later #define LITTLE_ENDIAN true #define BIG_ENDIAN false \ No newline at end of file From 381545960b53b3fae7f90003fffaa39a9d609aa2 Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 22:59:38 +0530 Subject: [PATCH 7/9] Make read interface for primitve data types --- gbemu/gbemu/common/stream.h | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index 9404cd4..d8bbb13 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -30,9 +30,72 @@ namespace Common { return b; } - byte readSByte() { + uint16 readUint16LE() { + uint16 val; + read(&val, 2); + return FROM_LE_16(val); + } + + uint32 readUint32LE() { + uint32 val; + read(&val, 4); + return FROM_LE_32(val); + } + + uint64 readUint64LE() { + uint64 val; + read(&val, 8); + return FROM_LE_64(val); + } + + uint16 readUint16BE() { + uint16 val; + read(&val, 2); + return FROM_BE_16(val); + } + + uint32 readUint32BE() { + uint32 val; + read(&val, 4); + return FROM_BE_32(val); + } + + uint64 readUint64BE() { + uint64 val; + read(&val, 8); + return FROM_BE_64(val); + } + + inline byte readSByte() { return (int8) readByte(); } - }; + inline int16 readSint16LE() { + return (int16) readUint16LE(); + } + + inline int32 readSint32LE() { + return (int32) readUint32LE(); + } + + inline int64 readSint64LE() { + return (int64) readUint64LE(); + } + + inline int16 readSint16BE() { + return (int16) readUint16BE(); + } + + inline int32 readSint32BE() { + uint32 val; + read(&val, 4); + return FROM_BE_32(val); + } + + inline int64 readSint64BE() { + uint64 val; + read(&val, 8); + return FROM_BE_64(val); + } + }; } \ No newline at end of file From 9ecea030c0a739909d42a9033755d5777c24277c Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 23:15:26 +0530 Subject: [PATCH 8/9] Create SeekableReadStream --- gbemu/gbemu/common/stream.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index d8bbb13..31206ba 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -87,15 +87,27 @@ namespace Common { } inline int32 readSint32BE() { - uint32 val; - read(&val, 4); - return FROM_BE_32(val); + return (int32) readUint32BE(); } inline int64 readSint64BE() { - uint64 val; - read(&val, 8); - return FROM_BE_64(val); + return (int64) readUint64BE(); } }; + + class SeekableReadStream : virtual public ReadStream { + public: + // Position of cursor + virtual int64 pos() const = 0; + + // Size of stream + virtual int64 size() const = 0; + + // Set the cursor to a specific place in stream + // wrapper identical to fseek() + virtual bool seek(int64 offset, int whence = SEEK_SET) = 0; + + // Skip given bytes in stream + virtual bool skip(uint32 offset) { return seek(offset, SEEK_CUR); } + }; } \ No newline at end of file From 670cff032ff9d86dfd82157de3201f6d3a664c12 Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 15 Aug 2022 23:33:39 +0530 Subject: [PATCH 9/9] Add endianness support in ReadStream --- gbemu/gbemu/common/endianness.h | 4 +-- gbemu/gbemu/common/stream.h | 61 ++++++++++----------------------- 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/gbemu/gbemu/common/endianness.h b/gbemu/gbemu/common/endianness.h index e74cd64..1847f50 100644 --- a/gbemu/gbemu/common/endianness.h +++ b/gbemu/gbemu/common/endianness.h @@ -95,5 +95,5 @@ inline void WRITE_UINT64(void *ptr, uint64 value) { #define TO_BE_64(a) SWAP_BYTES_64(a) // Might come handy later -#define LITTLE_ENDIAN true -#define BIG_ENDIAN false \ No newline at end of file +#define LITTLE_ENDIAN false +#define BIG_ENDIAN true \ No newline at end of file diff --git a/gbemu/gbemu/common/stream.h b/gbemu/gbemu/common/stream.h index 31206ba..44f2a5e 100644 --- a/gbemu/gbemu/common/stream.h +++ b/gbemu/gbemu/common/stream.h @@ -15,8 +15,13 @@ namespace Common { }; class ReadStream : virtual public Stream { + private: + bool isBigEndian; + public: - ReadStream() {} + ReadStream(bool bigEndian = LITTLE_ENDIAN) : isBigEndian(bigEndian) {} + + bool isBE() { return isBigEndian; } // End of stream interface virtual bool eos() const = 0; @@ -30,68 +35,38 @@ namespace Common { return b; } - uint16 readUint16LE() { + uint16 readUint16() { uint16 val; read(&val, 2); - return FROM_LE_16(val); + return (isBigEndian) ? FROM_BE_16(val) : FROM_LE_16(val); } - uint32 readUint32LE() { + uint32 readUint32() { uint32 val; read(&val, 4); - return FROM_LE_32(val); + return (isBigEndian) ? FROM_BE_32(val) : FROM_LE_32(val); } - uint64 readUint64LE() { + uint64 readUint64() { uint64 val; read(&val, 8); - return FROM_LE_64(val); - } - - uint16 readUint16BE() { - uint16 val; - read(&val, 2); - return FROM_BE_16(val); - } - - uint32 readUint32BE() { - uint32 val; - read(&val, 4); - return FROM_BE_32(val); - } - - uint64 readUint64BE() { - uint64 val; - read(&val, 8); - return FROM_BE_64(val); + return (isBigEndian) ? FROM_BE_64(val) : FROM_LE_64(val); } inline byte readSByte() { return (int8) readByte(); } - inline int16 readSint16LE() { - return (int16) readUint16LE(); - } - - inline int32 readSint32LE() { - return (int32) readUint32LE(); - } - - inline int64 readSint64LE() { - return (int64) readUint64LE(); - } - - inline int16 readSint16BE() { - return (int16) readUint16BE(); + inline int16 readSint16() { + return (int16) readUint16(); } - inline int32 readSint32BE() { - return (int32) readUint32BE(); + inline int32 readSint32() { + return (int32) readUint32(); } - inline int64 readSint64BE() { - return (int64) readUint64BE(); + inline int64 readSint64() { + return (int64) readUint64(); } };