URL
https://opencores.org/ocsvn/t48/t48/trunk
Subversion Repositories t48
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 284 to Rev 285
- ↔ Reverse comparison
Rev 284 → Rev 285
/trunk/sw/hex2rom/hex2rom.cpp
0,0 → 1,960
// |
// Binary and intel/motorola hex to VHDL ROM converter |
// |
// Version : 0244 |
// |
// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
// |
// All rights reserved |
// |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are met: |
// |
// Redistributions of source code must retain the above copyright notice, |
// this list of conditions and the following disclaimer. |
// |
// Redistributions in binary form must reproduce the above copyright |
// notice, this list of conditions and the following disclaimer in the |
// documentation and/or other materials provided with the distribution. |
// |
// Neither the name of the author nor the names of other contributors may |
// be used to endorse or promote products derived from this software without |
// specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
// POSSIBILITY OF SUCH DAMAGE. |
// |
// Please report bugs to the author, but before you do so, please |
// make sure that this is not a derivative work and that |
// you have the latest version of this file. |
// |
// The latest version of this file can be found at: |
// http://www.opencores.org/cvsweb.shtml/t51/ |
// |
// Limitations : |
// No support for wrapped intel segments |
// Requires stl to compile |
// |
// File history : |
// |
// 0146 : Initial release |
// |
// 0150 : Added binary read |
// |
// 0208 : Changed some errors to warnings |
// |
// 0215 : Added support for synchronous ROM |
// |
// 0220 : Changed array ROM format, added support for Xilinx .UCF generation |
// |
// 0221 : Fixed small .UCF generation for small ROMs |
// |
// 0244 : Added Leonardo .UCF option |
// |
// 28-Apr-2008 : Generate D for synchronous ROM in clocked process. |
// |
|
#include <stdio.h> |
#include <string> |
#include <vector> |
#include <iostream> |
|
using namespace std; |
|
#if !(defined(max)) && _MSC_VER |
// VC fix |
#define max __max |
#endif |
|
class MemBlock |
{ |
public: |
unsigned long m_startAddress; |
vector<unsigned char> m_bytes; |
}; |
|
class File |
{ |
public: |
explicit File(const char *fileName, const char *mode) |
{ |
m_file = fopen(fileName, mode); |
if (m_file != NULL) |
{ |
return; |
} |
string errorStr = "Error opening "; |
errorStr += fileName; |
errorStr += "\n"; |
throw errorStr; |
} |
|
~File() |
{ |
fclose(m_file); |
} |
|
// Read binary file |
void ReadBin(unsigned long limit) |
{ |
m_top = 0; |
|
m_chunks.push_back(MemBlock()); |
m_chunks.back().m_startAddress = 0; |
|
cerr << "Reading binary file\n"; |
|
int tmp = fgetc(m_file); |
|
while (!feof(m_file)) |
{ |
m_chunks.back().m_bytes.push_back(tmp); |
|
if (m_chunks.back().m_bytes.size() > limit + 1) |
{ |
m_chunks.back().m_bytes.pop_back(); |
m_top = m_chunks.back().m_bytes.size() - 1; |
cerr << "Ignoring data above address space!\n"; |
cerr << " Limit: " << limit << "\n"; |
return; |
} |
|
tmp = fgetc(m_file); |
} |
|
m_top = m_chunks.back().m_bytes.size() - 1; |
|
if (!m_chunks.back().m_bytes.size()) |
{ |
cerr << "No data!\n"; |
|
m_chunks.pop_back(); |
} |
} |
|
// Read hex file |
void ReadHex(unsigned long limit) |
{ |
char szLine[1024]; |
bool formatDetected = false; |
bool intel; |
bool endSeen = false; |
bool linear = true; // Only used for intel hex |
unsigned long addressBase = 0; // Only used for intel hex |
unsigned long dataRecords = 0; // Only used for s-record |
while (!feof(m_file)) |
{ |
if (fgets(szLine, 1024, m_file) == 0) |
{ |
if (ferror(m_file)) |
{ |
throw "Error reading input!\n"; |
} |
continue; |
} |
|
if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD) |
{ |
szLine[strlen(szLine) - 1] = 0; |
} |
|
if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD) |
{ |
szLine[strlen(szLine) - 1] = 0; |
} |
|
if (strlen(szLine) == 1023) |
{ |
throw "Hex file lines to long!\n"; |
} |
// Ignore blank lines |
if (szLine[0] == '\n') |
{ |
continue; |
} |
// Detect format and warn if garbage lines are found |
if (!formatDetected) |
{ |
if (szLine[0] != ':' && szLine[0] != 'S') |
{ |
cerr << "Ignoring garbage line!\n"; |
continue; |
} |
if (szLine[0] == 'S') |
{ |
intel = false; |
cerr << "Detected S-Record\n"; |
} |
else |
{ |
intel = true; |
cerr << "Detected intel hex file\n"; |
} |
formatDetected = true; |
} |
else if ((intel && szLine[0] != ':') || |
(!intel && szLine[0] != 'S')) |
{ |
cerr << "Ignoring garbage line!\n"; |
continue; |
} |
|
if (endSeen) |
{ |
throw "Hex line after end of file record!\n"; |
} |
|
if (intel) |
{ |
unsigned long dataBytes; |
unsigned long startAddress; |
unsigned long type; |
if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3) |
{ |
throw "Hex line beginning corrupt!\n"; |
} |
// Check line length |
if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0) |
{ |
throw "Hex line length incorrect!\n"; |
} |
// Check line checksum |
unsigned char checkSum = 0; |
unsigned long tmp; |
for (unsigned int i = 0; i <= dataBytes + 4; ++i) |
{ |
if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1) |
{ |
throw "Hex line data corrupt!\n"; |
} |
checkSum += tmp; |
} |
if (checkSum != 0) |
{ |
throw "Hex line checksum error!\n"; |
} |
|
switch (type) |
{ |
case 0: |
// Data record |
if (!linear) |
{ |
// Segmented |
unsigned long test = startAddress; |
test += dataBytes; |
if (test > 0xffff) |
{ |
throw "Can't handle wrapped segments!\n"; |
} |
} |
if (!m_chunks.size() || |
m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() != |
addressBase + startAddress) |
{ |
m_chunks.push_back(MemBlock()); |
m_chunks.back().m_startAddress = addressBase + startAddress; |
} |
{ |
unsigned char i = 0; |
for (i = 0; i < dataBytes; ++i) |
{ |
sscanf(&szLine[9 + i * 2], "%2lx", &tmp); |
if (addressBase + startAddress + i > limit) |
{ |
cerr << "Ignoring data above address space!\n"; |
cerr << "Data address: " << addressBase + startAddress + i; |
cerr << " Limit: " << limit << "\n"; |
if (!m_chunks.back().m_bytes.size()) |
{ |
m_chunks.pop_back(); |
} |
continue; |
} |
m_chunks.back().m_bytes.push_back(tmp); |
} |
} |
break; |
|
case 1: |
// End-of-file record |
if (dataBytes != 0) |
{ |
cerr << "Warning: End of file record not zero length!\n"; |
} |
if (startAddress != 0) |
{ |
cerr << "Warning: End of file record address not zero!\n"; |
} |
endSeen = true; |
break; |
|
case 2: |
// Extended segment address record |
if (dataBytes != 2) |
{ |
throw "Length field must be 2 in extended segment address record!\n"; |
} |
if (startAddress != 0) |
{ |
throw "Address field must be zero in extended segment address record!\n"; |
} |
sscanf(&szLine[9], "%4lx", &startAddress); |
addressBase = startAddress << 4; |
linear = false; |
break; |
|
case 3: |
// Start segment address record |
if (dataBytes != 4) |
{ |
cerr << "Warning: Length field must be 4 in start segment address record!\n"; |
} |
if (startAddress != 0) |
{ |
cerr << "Warning: Address field must be zero in start segment address record!\n"; |
} |
if (dataBytes == 4) |
{ |
unsigned long ssa; |
char ssaStr[16]; |
sscanf(&szLine[9], "%8lx", &ssa); |
sprintf(ssaStr, "%08X\n", ssa); |
cerr << "Segment start address (CS/IP): "; |
cerr << ssaStr; |
} |
break; |
|
case 4: |
// Extended linear address record |
if (dataBytes != 2) |
{ |
throw "Length field must be 2 in extended linear address record!\n"; |
} |
if (startAddress != 0) |
{ |
throw "Address field must be zero in extended linear address record!\n"; |
} |
sscanf(&szLine[9], "%4lx", &startAddress); |
addressBase = ((unsigned long)startAddress) << 16; |
linear = true; |
break; |
|
case 5: |
// Start linear address record |
if (dataBytes != 4) |
{ |
cerr << "Warning: Length field must be 4 in start linear address record!\n"; |
} |
if (startAddress != 0) |
{ |
cerr << "Warning: Address field must be zero in start linear address record!\n"; |
} |
if (dataBytes == 4) |
{ |
unsigned long lsa; |
char lsaStr[16]; |
sscanf(&szLine[9], "%8lx", &lsa); |
sprintf(lsaStr, "%08X\n", lsa); |
cerr << "Linear start address: "; |
cerr << lsaStr; |
} |
break; |
|
default: |
cerr << "Waring: Unknown record found!\n"; |
} |
} |
else |
{ |
// S-record |
unsigned long count; |
char type; |
if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2) |
{ |
throw "Hex line beginning corrupt!\n"; |
} |
// Check line length |
if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0) |
{ |
throw "Hex line length incorrect!\n"; |
} |
// Check line checksum |
unsigned char checkSum = 0; |
unsigned long tmp; |
for (unsigned int i = 0; i < count + 1; ++i) |
{ |
if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1) |
{ |
throw "Hex line data corrupt!\n"; |
} |
checkSum += tmp; |
} |
if (checkSum != 255) |
{ |
throw "Hex line checksum error!\n"; |
} |
|
switch (type) |
{ |
case '0': |
// Header record |
{ |
char header[256]; |
unsigned char i = 0; |
for (i = 0; i + 3 < count; ++i) |
{ |
sscanf(&szLine[8 + i * 2], "%2lx", &tmp); |
header[i] = tmp; |
} |
header[i] = 0; |
if (i > 0) |
{ |
cerr << "Module name: " << header << "\n"; |
} |
} |
break; |
|
case '1': |
case '2': |
case '3': |
// Data record |
{ |
dataRecords++; |
unsigned long startAddress; |
if (type == '1') |
{ |
sscanf(&szLine[4], "%4lx", &startAddress); |
} |
else if (type == '2') |
{ |
sscanf(&szLine[4], "%6lx", &startAddress); |
} |
else |
{ |
sscanf(&szLine[4], "%8lx", &startAddress); |
} |
|
if (!m_chunks.size() || |
m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() != |
startAddress) |
{ |
m_chunks.push_back(MemBlock()); |
m_chunks.back().m_startAddress = startAddress; |
} |
unsigned char i = 0; |
for (i = (type - '1'); i + 3 < count; ++i) |
{ |
sscanf(&szLine[8 + i * 2], "%2lx", &tmp); |
if (startAddress + i > limit) |
{ |
cerr << "Ignoring data above address space!\n"; |
cerr << "Data address: " << startAddress + i; |
cerr << " Limit: " << limit << "\n"; |
if (!m_chunks.back().m_bytes.size()) |
{ |
m_chunks.pop_back(); |
} |
continue; |
} |
m_chunks.back().m_bytes.push_back(tmp); |
} |
} |
break; |
|
case '5': |
// Count record |
{ |
unsigned long address; |
sscanf(&szLine[4], "%4lx", &address); |
if (address != dataRecords) |
{ |
throw "Wrong number of data records!\n"; |
} |
} |
break; |
|
case '7': |
case '8': |
case '9': |
// Start address record |
cerr << "Ignoring start address record!\n"; |
break; |
|
default: |
cerr << "Unknown record found!\n"; |
} |
} |
} |
if (intel && !endSeen) |
{ |
cerr << "No end of file record!\n"; |
} |
if (!m_chunks.size()) |
{ |
throw "No data in file!\n"; |
} |
vector<MemBlock>::iterator vi; |
m_top = 0; |
for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++) |
{ |
m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1); |
} |
} |
|
// Rather inefficient this one, fix sometime |
bool GetByte(const unsigned long address, unsigned char &chr) |
{ |
vector<MemBlock>::iterator vi; |
|
for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++) |
{ |
if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address) |
{ |
break; |
} |
} |
if (vi == m_chunks.end()) |
{ |
return false; |
} |
chr = vi->m_bytes[address - vi->m_startAddress]; |
return true; |
} |
|
bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str) |
{ |
bool ok = false; |
long i; |
unsigned char chr; |
unsigned long data = 0; |
unsigned long tmp; |
|
if (lEndian) |
{ |
for (i = 0; i < (bits + 7) / 8; ++i) |
{ |
ok |= GetByte(address + i, chr); |
tmp = chr; |
data |= tmp << (8 * i); |
} |
} |
else |
{ |
for (i = 0; i < (bits + 7) / 8; ++i) |
{ |
ok |= GetByte(address + i, chr); |
tmp = chr; |
data |= tmp << (8 * ((bits + 7) / 8 - i - 1)); |
} |
} |
|
if (!ok) |
{ |
return false; |
} |
|
unsigned long mask = 1; |
|
str = ""; |
for (i = 0; i < bits; i++) |
{ |
if (data & mask) |
{ |
str.insert(0,"1"); |
} |
else |
{ |
str.insert(0,"0"); |
} |
mask <<= 1; |
} |
return true; |
} |
|
FILE *Handle() { return m_file; }; |
vector<MemBlock> m_chunks; |
unsigned long m_top; |
private: |
FILE *m_file; |
}; |
|
|
int main (int argc, char *argv[]) |
{ |
cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0244\n"; |
|
try |
{ |
unsigned long aWidth; |
unsigned long dWidth; |
char endian; |
char O = 0; |
|
if (!(argc == 4 || argc == 5)) |
{ |
cerr << "\nUsage: hex2rom [-b] <input file> <entity name> <format>\n"; |
cerr << "\nIf the -b option is specified the file is read as a binary file\n"; |
cerr << "Hex input files must be intel hex or motorola s-record\n"; |
cerr << "\nThe format string has the format AEDOS where:\n"; |
cerr << " A = Address bits\n"; |
cerr << " E = Endianness, l or b\n"; |
cerr << " D = Data bits\n"; |
cerr << " O = ROM type: (one optional character)\n"; |
cerr << " z for tri-state output\n"; |
cerr << " a for array ROM\n"; |
cerr << " s for synchronous ROM\n"; |
cerr << " u for XST ucf\n"; |
cerr << " l for Leonardo ucf\n"; |
cerr << " S = SelectRAM usage in 1/16 parts (only used when O = u)\n"; |
cerr << "\nExample:\n"; |
cerr << " hex2rom test.hex Test_ROM 18b16z\n\n"; |
return -1; |
} |
|
string inFileName; |
string outFileName; |
|
unsigned long bytes; |
unsigned long select = 0; |
|
if (argc == 5) |
{ |
if (strcmp(argv[1], "-b")) |
{ |
throw "Error in arguments!\n"; |
} |
} |
|
int result; |
|
result = sscanf(argv[argc - 1], "%lu%c%lu%c%lu", &aWidth, &endian, &dWidth, &O, &select); |
if (result < 3) |
{ |
throw "Error in output format argument!\n"; |
} |
|
if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's' && O != 'u' && O != 'l')) |
{ |
throw "Error in output format argument!\n"; |
} |
inFileName = argv[argc - 3]; |
outFileName = argv[argc - 2]; |
|
bytes = (dWidth + 7) / 8; |
|
File inFile(inFileName.c_str(), "rb"); |
|
if (argc == 4) |
{ |
inFile.ReadHex((1UL << aWidth) * bytes - 1); |
} |
else |
{ |
inFile.ReadBin((1UL << aWidth) * bytes - 1); |
} |
|
string line; |
|
unsigned long words = 1; |
unsigned long i = inFile.m_top; |
i /= bytes; |
|
while (i != 0) |
{ |
i >>= 1; |
words <<= 1; |
} |
|
if (O != 'u' && O != 'l') |
{ |
printf("-- This file was generated with hex2rom written by Daniel Wallner\n"); |
printf("\nlibrary IEEE;"); |
printf("\nuse IEEE.std_logic_1164.all;"); |
printf("\nuse IEEE.numeric_std.all;"); |
printf("\n\nentity %s is", outFileName.c_str()); |
printf("\n\tport("); |
if (O == 'z') |
{ |
printf("\n\t\tCE_n\t: in std_logic;", dWidth - 1); |
printf("\n\t\tOE_n\t: in std_logic;", dWidth - 1); |
} |
if (O == 's') |
{ |
printf("\n\t\tClk\t: in std_logic;", dWidth - 1); |
} |
printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1); |
printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1); |
printf("\n\t);"); |
printf("\nend %s;", outFileName.c_str()); |
printf("\n\narchitecture rtl of %s is", outFileName.c_str()); |
if (!O) |
{ |
printf("\nbegin"); |
printf("\n\tprocess (A)"); |
printf("\n\tbegin"); |
printf("\n\t\tcase to_integer(unsigned(A)) is"); |
} |
else if (O == 's') |
{ |
printf("\nbegin"); |
printf("\n\tprocess (Clk)"); |
printf("\n\tbegin"); |
printf("\n\t\tif Clk'event and Clk = '1' then"); |
printf("\n\t\tcase to_integer(unsigned(A)) is"); |
} |
else |
{ |
printf("\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1); |
printf("\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1); |
printf("\n\tconstant ROM: ROM_TABLE := ROM_TABLE'("); |
} |
|
string str; |
string strDC; |
for (i = 0; i < dWidth; i++) |
{ |
strDC.insert(0, "-"); |
} |
for (i = 0; i < words; i++) |
{ |
if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str)) |
{ |
str = strDC; |
} |
if (!O || O == 's') |
{ |
if (inFile.m_top / bytes >= i) |
{ |
printf("\n\t\twhen %06d => D <= \"%s\";",i, str.c_str()); |
printf("\t-- 0x%04X", i * bytes); |
} |
} |
else |
{ |
printf("\n\t\t\"%s", str.c_str()); |
if (i != words - 1) |
{ |
printf("\","); |
} |
else |
{ |
printf("\");"); |
} |
printf("\t-- 0x%04X", i * bytes); |
} |
} |
|
if (!O || O == 's') |
{ |
printf("\n\t\twhen others => D <= \"%s\";", strDC.c_str()); |
printf("\n\t\tend case;"); |
if (O == 's') |
printf("\n\tend if;"); |
printf("\n\tend process;"); |
} |
else |
{ |
printf("\nbegin"); |
if (O == 'z') |
{ |
printf("\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');"); |
} |
else |
{ |
printf("\n\tD <= ROM(to_integer(unsigned(A)));"); |
} |
} |
printf("\nend;\n"); |
} |
else |
{ |
unsigned long selectIter = 0; |
unsigned long blockIter = 0; |
|
if (!select) |
{ |
blockIter = ((1UL << aWidth) + 511) / 512; |
} |
else if (select == 16) |
{ |
selectIter = ((1UL << aWidth) + 15) / 16; |
} |
else |
{ |
blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512; |
selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16; |
} |
|
cerr << "Creating .ucf file with " << selectIter * bytes; |
cerr << " LUTs and " << blockIter * bytes << " block RAMs\n"; |
|
unsigned long blockTotal = ((1UL << aWidth) + 511) / 512; |
|
printf("# This file was generated with hex2rom written by Daniel Wallner\n"); |
|
for (i = 0; i < selectIter; i++) |
{ |
unsigned long base = i * 16 * bytes; |
unsigned long j; |
unsigned char c; |
unsigned long pos; |
|
// Check that there is any actual data in segment |
bool init = false; |
for (pos = 0; pos < bytes * 16; pos++) |
{ |
init = inFile.GetByte(base + pos, c); |
if (init) |
{ |
break; |
} |
} |
|
if (init) |
{ |
for (j = 0; j < dWidth; j++) |
{ |
unsigned long bitMask = 1; |
unsigned long bits = 0; |
|
for (pos = 0; pos < 16; pos++) |
{ |
unsigned long addr; |
|
if (endian = 'l') |
{ |
addr = base + bytes * pos + j / 8; |
} |
else |
{ |
addr = base + bytes * pos + bytes - j / 8 - 1; |
} |
|
c = 0; |
inFile.GetByte(addr, c); |
if (c & (1 << (j % 8))) |
{ |
bits |= bitMask; |
} |
bitMask <<= 1; |
} |
|
if (O == 'u') |
{ |
if (selectIter == 1) |
{ |
printf("\nINST *s%s%d INIT = %04X;", outFileName.c_str(), j, bits); |
} |
else |
{ |
printf("\nINST *s%s%d%d INIT = %04X;", outFileName.c_str(), i, j, bits); |
} |
} |
else |
{ |
if (selectIter == 1) |
{ |
printf("\nINST *sG1_%d_S%s INIT = %04X;", j, outFileName.c_str(), bits); |
} |
else |
{ |
printf("\nINST *sG1_%d_sG2_%d_S%s INIT = %04X;", i, j, outFileName.c_str(), bits); |
} |
} |
} |
} |
} |
|
for (i = blockTotal - blockIter; i < blockTotal; i++) |
{ |
unsigned long j; |
for (j = 0; j < bytes; j++) |
{ |
unsigned long k; |
for (k = 0; k < 16; k++) |
{ |
unsigned long base = i * 512 * bytes + k * 32 * bytes; |
unsigned char c; |
unsigned long pos; |
|
// Check that there is any actual data in segment |
bool init = false; |
for (pos = 0; pos < 32; pos++) |
{ |
init = inFile.GetByte(base + bytes * pos + j, c); |
if (init) |
{ |
break; |
} |
} |
|
if (init) |
{ |
if (O == 'u') |
{ |
if (blockIter == 1) |
{ |
printf("\nINST *b%s%d INIT_%02X = ", outFileName.c_str(), j, k); |
} |
else |
{ |
printf("\nINST *b%s%d%d INIT_%02X = ", outFileName.c_str(), i, j, k); |
} |
} |
else |
{ |
if (blockIter == 1) |
{ |
printf("\nINST *bG1_%d_B%s INIT_%02X = ", j, outFileName.c_str(), k); |
} |
else |
{ |
printf("\nINST *bG1_%d_bG2_%d_B%s INIT_%02X = ", i, j, outFileName.c_str(), k); |
} |
} |
for (pos = 0; pos < 32; pos++) |
{ |
unsigned long addr; |
|
if (endian = 'l') |
{ |
addr = base + bytes * (31 - pos) + j; |
} |
else |
{ |
addr = base + bytes * (31 - pos) + bytes - j - 1; |
} |
|
c = 0; |
inFile.GetByte(addr, c); |
printf("%02X", c); |
} |
printf(";"); |
} |
} |
} |
} |
printf("\n"); |
} |
return 0; |
} |
catch (string error) |
{ |
cerr << "Fatal: " << error; |
} |
catch (const char *error) |
{ |
cerr << "Fatal: " << error; |
} |
return -1; |
} |