diff --git a/bin/blockgen.exe b/bin/blockgen.exe new file mode 100644 index 0000000..fd9556a Binary files /dev/null and b/bin/blockgen.exe differ diff --git a/bin/blockgen/source/bctypes.h b/bin/blockgen/source/bctypes.h new file mode 100644 index 0000000..d2b2a5f --- /dev/null +++ b/bin/blockgen/source/bctypes.h @@ -0,0 +1,48 @@ +/* + bctypes.h + + Because I need Standard Types +*/ + +#ifndef _bctypes_h +#define _bctypes_h + +typedef signed char i8; +typedef unsigned char u8; +typedef signed short i16; +typedef unsigned short u16; +typedef signed long i32; +typedef unsigned long u32; + +typedef signed long long i64; +typedef unsigned long long u64; + +// If we're using C, I still like having a bool around +#ifndef __cplusplus +typedef i32 bool; +#define false (0) +#define true (!false) +#define nullptr 0 +#endif + +typedef float f32; +typedef float r32; +typedef double f64; +typedef double r64; + + +#define null (0) + +// Odd Types +typedef union { +// u128 ul128; + u64 ul64[2]; + u32 ui32[4]; +} QWdata; + + +#endif // _bctypes_h + +// EOF - bctypes.h + + diff --git a/bin/blockgen/source/blockgen.cpp b/bin/blockgen/source/blockgen.cpp new file mode 100644 index 0000000..187ef8b --- /dev/null +++ b/bin/blockgen/source/blockgen.cpp @@ -0,0 +1,68 @@ +// omf2hex.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include +#include + +#include "symfile.h" + +//------------------------------------------------------------------------------ +void helpText() +{ + printf("blockgen - v1.0\n"); + printf("--------------\n"); + printf("Convert mos-llvm elf file symboles into a C header file\n"); + printf("\nblock [options] \n"); + printf(" -v verbose\n\n"); + + exit(-1); +} + +//------------------------------------------------------------------------------ + +int main(int argc, char* argv[]) +{ + char* pInfilePath = nullptr; + bool bVerbose = false; + + for (int idx = 1; idx < argc; ++idx ) + { + char* arg = argv[ idx ]; + + if ('-' == arg[0]) + { + // Parse as an option + if ('v'==arg[1]) + { + bVerbose = true; + } + } + else if (nullptr == pInfilePath) + { + // Assume the first non-option is an input file path + pInfilePath = argv[ idx ]; + } + else + { + // Oh Crap, we have a non-option, but we don't know what to do with + // it + printf("ERROR: Invalid option, Arg %d = %s\n\n", idx, argv[ idx ]); + helpText(); + } + } + + if (pInfilePath) + { + // Load the .sym File + SYMFile *pSymFile = new SYMFile(std::string(pInfilePath)); + delete pSymFile; + } + else + { + helpText(); + } + + + return 0; +} + diff --git a/bin/blockgen/source/memstream.h b/bin/blockgen/source/memstream.h new file mode 100644 index 0000000..5adc146 --- /dev/null +++ b/bin/blockgen/source/memstream.h @@ -0,0 +1,164 @@ +// +// Jason's Memory Stream Helper thing +// Serialize a byte stream into real types +// +// Currently only support Little Endian +// + +#ifndef MEMSTREAM_H_ +#define MEMSTREAM_H_ + + +#include + +// Prototypes +void *memcpy(void *dest, const void *src, size_t n); + +class MemoryStream +{ +public: + MemoryStream(unsigned char* pStreamStart, size_t streamSize) + : m_pStreamStart( pStreamStart ) + , m_streamSize(streamSize) + , m_pStreamCurrent( pStreamStart ) + {} + + ~MemoryStream() + { + m_pStreamStart = nullptr; + m_streamSize = 0; + m_pStreamCurrent = nullptr; + } + + // Really Dumb Reader Template + template + T Read() + { + T result; + + memcpy(&result, m_pStreamCurrent, sizeof(T)); + m_pStreamCurrent += sizeof(T); + + return result; + } + + template + void Read(T& result) + { + memcpy(&result, m_pStreamCurrent, sizeof(result)); + m_pStreamCurrent += sizeof(result); + } + + void ReadBytes(u8* pDest, size_t numBytes) + { + memcpy(pDest, m_pStreamCurrent, numBytes); + m_pStreamCurrent += numBytes; + } + + std::string ReadPString() + { + std::string result; + + u8 length = *m_pStreamCurrent++; + + result.insert(0, (char*)m_pStreamCurrent, (size_t)length); + + m_pStreamCurrent += length; + + return result; + } + + std::string ReadLine() + { + unsigned char* pStreamEnd = m_pStreamStart + m_streamSize; + + std::string result; + + u8 *pEndOfLine = m_pStreamCurrent; + + while (pEndOfLine < pStreamEnd) + { + if ((0x0a != *pEndOfLine) && (0x0d != *pEndOfLine)) + { + pEndOfLine++; + } + else + { + break; + } + } + + size_t length = pEndOfLine - m_pStreamCurrent; + + if (length) + { + // Capture the line + result.insert(0, (char*)m_pStreamCurrent, (size_t)length); + m_pStreamCurrent += length; + } + + // Figure out if that loop broke out because we hit the end of the file + while (pEndOfLine < pStreamEnd) + { + if ((0x0a == *pEndOfLine) || (0x0d == *pEndOfLine)) + { + pEndOfLine++; + } + else + { + break; + } + } + + m_pStreamCurrent = pEndOfLine; + if (m_pStreamCurrent > pStreamEnd) + { + m_pStreamCurrent = pStreamEnd; + } + return result; + + } + + size_t SeekCurrent(int delta) + { + m_pStreamCurrent += delta; + return m_pStreamCurrent - m_pStreamStart; + } + + size_t SeekSet(size_t offset) + { + m_pStreamCurrent = m_pStreamStart + offset; + return m_pStreamCurrent - m_pStreamStart; + } + + unsigned char* GetPointer() { return m_pStreamCurrent; } + + size_t NumBytesAvailable() { + + unsigned char* pStreamEnd = m_pStreamStart + m_streamSize; + + if (pStreamEnd - m_pStreamCurrent >= 0) + { + return pStreamEnd - m_pStreamCurrent; + } + else + { + return 0; + } + } + + + +private: + + unsigned char* m_pStreamStart; + size_t m_streamSize; + + unsigned char* m_pStreamCurrent; + +}; + + +#endif // MEMSTREAM_H_ + + diff --git a/bin/blockgen/source/symfile.cpp b/bin/blockgen/source/symfile.cpp new file mode 100644 index 0000000..47a6625 --- /dev/null +++ b/bin/blockgen/source/symfile.cpp @@ -0,0 +1,231 @@ +// +// symfile.cpp +// +#include "symfile.h" +#include + +//------------------------------------------------------------------------------ +// Static Helpers + +static bool contains(char x, const char* pSeparators) +{ + while (*pSeparators) + { + if (x == *pSeparators) + { + return true; + } + pSeparators++; + } + + return false; +} + +static std::vector split(const std::string& s, const char* separators) +{ + std::vector output; + std::string::size_type prev_pos = 0, pos = 0; + + for (int index = 0; index < s.length(); ++index) + { + pos = index; + + // if the index is a separator + if (contains(s[index], separators)) + { + // if we've skipped a token, collect it + if (prev_pos != index) + { + output.push_back(s.substr(prev_pos, index-prev_pos)); + + // skip white space here + while (index < s.length()) + { + if (contains(s[index], separators)) + { + ++index; + } + else + { + prev_pos = index; + pos = index; + break; + } + } + } + else + { + prev_pos++; + } + } + } + + output.push_back(s.substr(prev_pos, pos-prev_pos+1)); // Last word + + return output; +} + +// make this string lowercase +static void tolower(std::string& s) +{ + for (int index = 0; index < s.length(); ++index) + { + s[index] = tolower( s[index] ); + } +} + +//------------------------------------------------------------------------------ +SYMFile::SYMFile( std::string filepath ) + : m_filepath( filepath ) +{ + FILE* pFile = nullptr; + errno_t err = fopen_s(&pFile, filepath.c_str(), "rb"); + + if (0==err) + { + fseek(pFile, 0, SEEK_END); + size_t length = ftell(pFile); + fseek(pFile, 0, SEEK_SET); + + printf("\n// SYMFile %s - %lld bytes\n", filepath.c_str(), length); + + printf("// Reading %s\n", filepath.c_str()); + + printf("//\n"); + printf("// This file generated by blockgen.exe\n"); + printf("//\n"); + printf("//\n"); + + u8* pData = new u8[ length ]; + + fread(pData, sizeof(u8), length / sizeof(u8), pFile); + + // Now we have a buffer, with the whole SYM File + // Read in the Sections + { + MemoryStream memStream(pData, length); + + while (memStream.NumBytesAvailable()) + { + std::string lineData = memStream.ReadLine(); + + // symbols are case sensitive + + // we care about the first 32 bit value in hex, and the last value on the line, the symbol + std::vector tokens = split(lineData, " \t"); + + if (tokens.size() >= 3) + { + if (IsHexAddress(tokens[0])) + { + // We're only interested in lines that start with a hex address + + std::string sym_name = tokens[ tokens.size() - 1 ]; + + u32 address = strtoul(tokens[0].c_str(), nullptr, 16); + + //printf("address = %08x\n", address); + + if (0 != (address >> 24)) + { + printf("#define %s_BLOCK %d\n", sym_name.c_str(), address>>24); + } + else if (0 != (address & 0xFF0000)) + { + printf("#define %s_high %d\n", sym_name.c_str(), (address>>16) & 0xFF); + printf("#define %s_BLOCK %d\n", sym_name.c_str(), ((address&0xFFFFFF) / 0x2000)); + } + + } + } + } + } + + delete[] pData; + + fclose(pFile); + + printf("\n// Read Completed\n"); + } + else + { + printf("// SYMFile could not open %s\n", filepath.c_str()); + printf("//\n"); + printf("Feed in a symbol dump file, and I will print out a header file\n"); + printf("Capture my output with a pipe.\n"); + printf("\nGenerate a .sym file like this:\n"); + printf("\nllvm-objdump --syms .elf > program.sym\n"); + } +} + +//------------------------------------------------------------------------------ + +SYMFile::~SYMFile() +{ +} + +//------------------------------------------------------------------------------ + +u32 SYMFile::GetAddress(std::string symbolName) +{ + u32 result_address = 0; + // If the address is in there, return it + // First remove trailing spaces from the sectionName + + const size_t strEnd = symbolName.find_last_not_of(" "); + + if (strEnd != std::string::npos) + { + if ((strEnd+1) != symbolName.length()) + { + symbolName.resize(strEnd+1); + } + } + + // Make sure not case sensitive + tolower(symbolName); + + for (int labelIndex = 0; labelIndex < m_symbols.size(); ++labelIndex) + { + if (symbolName == m_symbols[labelIndex]) + { + result_address = m_addresses[labelIndex]; + break; + } + } + + return result_address; +} + +//------------------------------------------------------------------------------ + +bool SYMFile::IsHexAddress(const std::string& address) +{ + if (8 == address.size()) + { + for (int idx = 0; idx < 8; ++idx) + { + if ((address[idx] >= '0')&&(address[idx] <= '9')) + { + continue; // this is good + } + else if ((address[idx] >= 'a')&&(address[idx] <= 'f')) + { + continue; // this is good + } + else if ((address[idx] >= 'A')&&(address[idx] <= 'F')) + { + continue; // this is good + } + else + { + return false; + } + } + + return true; + } + return false; +} + +//------------------------------------------------------------------------------ diff --git a/bin/blockgen/source/symfile.h b/bin/blockgen/source/symfile.h new file mode 100644 index 0000000..77cc341 --- /dev/null +++ b/bin/blockgen/source/symfile.h @@ -0,0 +1,34 @@ +// +// SYMFile Class +// + +#ifndef SYMFILE_H_ +#define SYMFILE_H_ + +#include +#include + +#include "bctypes.h" +#include "memstream.h" + +//------------------------------------------------------------------------------ + +class SYMFile +{ +public: + SYMFile( std::string filepath ); + ~SYMFile(); + + u32 GetAddress(std::string symbolName); + bool IsHexAddress(const std::string& address); + +private: + std::string m_filepath; + + std::vector m_symbols; + std::vector m_addresses; +}; + +#endif // SYMFILE_H_ + + diff --git a/bin/blockgen/vcxproj/blockgen.sln b/bin/blockgen/vcxproj/blockgen.sln new file mode 100644 index 0000000..ebbd3e4 --- /dev/null +++ b/bin/blockgen/vcxproj/blockgen.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34309.116 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blockgen", "blockgen.vcxproj", "{3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Debug|x64.ActiveCfg = Debug|x64 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Debug|x64.Build.0 = Debug|x64 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Debug|x86.ActiveCfg = Debug|Win32 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Debug|x86.Build.0 = Debug|Win32 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Release|x64.ActiveCfg = Release|x64 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Release|x64.Build.0 = Release|x64 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Release|x86.ActiveCfg = Release|Win32 + {3E291D4B-EB9C-439B-8090-A0F1D0BD21EB}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {43F6DB44-6241-4F87-B55D-35450E50405E} + EndGlobalSection +EndGlobal diff --git a/bin/blockgen/vcxproj/blockgen.vcxproj b/bin/blockgen/vcxproj/blockgen.vcxproj new file mode 100644 index 0000000..4eb2b85 --- /dev/null +++ b/bin/blockgen/vcxproj/blockgen.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {3e291d4b-eb9c-439b-8090-a0f1d0bd21eb} + blockgen + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/blockgen/vcxproj/blockgen.vcxproj.filters b/bin/blockgen/vcxproj/blockgen.vcxproj.filters new file mode 100644 index 0000000..96c4cfe --- /dev/null +++ b/bin/blockgen/vcxproj/blockgen.vcxproj.filters @@ -0,0 +1,26 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/dat_spritesJR.c b/src/dat_spritesJR.c index 0a80709..2a2781c 100644 --- a/src/dat_spritesJR.c +++ b/src/dat_spritesJR.c @@ -41,7 +41,9 @@ extern __attribute__((aligned(16))) const char incbin_ ## name ## _start[]; \ extern const char incbin_ ## name ## _end[] -INCBIN(".binarydata.sprites", sprites_data_256, "data/sprites_data.256"); +INCBIN(".binarydata.splash", splash_256, "data/splash.256"); +INCBIN(".binarydata.tiles", tiles_256, "data/tiles_data.256"); +INCBIN(".binarydata.sprites", sprites_256, "data/sprites_data.256"); #endif /* GFXF256 */ diff --git a/src/scr_credit.c b/src/scr_credit.c index a4d8dd8..87bc625 100644 --- a/src/scr_credit.c +++ b/src/scr_credit.c @@ -13,16 +13,21 @@ segment "screen"; #endif extern char credits_lz4; +extern char incbin_sprites_256_start[]; +extern char incbin_tiles_256_start[]; +extern char incbin_splash_256_start[]; +extern char __block23_lma_high[]; -extern char incbin_sprites_data_256_start[]; CODE_BLOCK(8) void scr_credit() { #ifdef F256 //$$JGA TODO - fix this - *((char*)0x200) = (char)((long)(&incbin_sprites_data_256_start)); - *((char*)0x201) = (char)((long)(&incbin_sprites_data_256_start)>>8); - *((char*)0x202) = (char)((long)(&incbin_sprites_data_256_start)>>16); + *((char*)0x200) = (char)(((long)(&incbin_sprites_256_start))); + *((char*)0x201) = (char)(((long)(&incbin_sprites_256_start))>>8); +// *((char*)0x202) = (char)(((long)(&incbin_sprites_256_start_high))>>16); + *((char*)0x203) = scr_credit_BLOCK; +// *((char*)0x203) = (char)(((long)(__block23_lma_high))>>8); #endif #ifdef IIGS diff --git a/src/system.c b/src/system.c index 8cbbb96..b96127f 100644 --- a/src/system.c +++ b/src/system.c @@ -34,9 +34,6 @@ void puts(char* c_str) { } -void __putchar(char c) -{ -} #endif @@ -141,7 +138,7 @@ sys_sleep(int s) /* * Initialize system */ -void +CODE_BLOCK(8) void sys_init(int argc, char **argv) { sysarg_init(argc, argv);