FileLoader_raw.cc Source File

Back to the index.

FileLoader_raw.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2010 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <assert.h>
29 #include <string.h>
30 #include <fstream>
31 #include <iomanip>
32 
33 using std::setw;
34 using std::setfill;
35 using std::ifstream;
36 
37 #include "AddressDataBus.h"
39 #include "FileLoader_raw.h"
40 #include "StringHelper.h"
41 
42 
43 FileLoader_raw::FileLoader_raw(const string& filename)
44  : FileLoaderImpl(filename)
45 {
46 }
47 
48 
49 string FileLoader_raw::DetectFileType(unsigned char *buf, size_t buflen, float& matchness) const
50 {
51  matchness = 0.0;
52 
53  vector<string> parts = StringHelper::SplitStringIntoVector(Filename(), ':');
54 
55  // Possible variants:
56  //
57  // filename <-- NOT a raw file
58  // raw:vaddr:filename
59  // raw:vaddr:skiplen:filename
60  // raw:vaddr:skiplen:initialpc:filename e.g. raw:0xbfc00000:0x100:0xbfc00884:rom.bin
61  if (parts.size() < 3)
62  return "";
63 
64  if (parts[0] != "raw")
65  return "";
66 
67  matchness = 1.0;
68  return "raw";
69 }
70 
71 
72 bool FileLoader_raw::LoadIntoComponent(refcount_ptr<Component> component, ostream& messages) const
73 {
74  AddressDataBus* bus = component->AsAddressDataBus();
75  if (bus == NULL) {
76  messages << "Target is not an AddressDataBus.\n";
77  return false;
78  }
79 
80  // Possible variants:
81  //
82  // raw:vaddr:filename
83  // raw:vaddr:skiplen:filename
84  // raw:vaddr:skiplen:initialpc:filename e.g. 0xbfc00000:0x100:0xbfc00884:rom.bin
85  vector<string> parts = StringHelper::SplitStringIntoVector(Filename(), ':');
86  if (parts.size() < 3 || parts.size() > 5) {
87  messages << "Syntax is raw:vaddr:[skiplen:[initialpc:]]filename.\n";
88  return false;
89  }
90 
91  string strvaddr = parts[1];
92  string strskiplen = (parts.size() >= 4)? parts[2] : "";
93  string strinitialpc = (parts.size() >= 5)? parts[3] : "";
94  string fname = parts[parts.size() - 1];
95 
96  bool error;
97  uint64_t vaddr = StringHelper::ParseNumber(strvaddr.c_str(), error);
98  if (error) {
99  messages << "could not parse vaddr.\n";
100  return false;
101  }
102 
103  uint64_t skiplen = 0;
104  if (strskiplen != "") {
105  skiplen = StringHelper::ParseNumber(strskiplen.c_str(), error);
106  if (error) {
107  messages << "could not parse skiplen\n";
108  return false;
109  }
110  }
111 
112  uint64_t initialpc = vaddr;
113  if (strinitialpc != "") {
114  initialpc = StringHelper::ParseNumber(strinitialpc.c_str(), error);
115  if (error) {
116  messages << "could not parse initialpc\n";
117  return false;
118  }
119  }
120 
121  ifstream file(fname.c_str());
122  if (!file.is_open()) {
123  messages << "Unable to read file.\n";
124  return false;
125  }
126 
127  file.seekg(0, std::ios_base::end);
128  off_t totalSize = file.tellg();
129  file.seekg(skiplen, std::ios_base::beg);
130  totalSize -= skiplen;
131 
132  // Read everything:
133  vector<char> data;
134  data.resize(totalSize);
135  file.read(&data[0], totalSize);
136  if (file.gcount() != totalSize) {
137  messages << "failed to read the whole file\n";
138  return false;
139  }
140 
141  messages.flags(std::ios::hex);
142  messages << "Raw file: entry point 0x" << initialpc << "\n";
143  messages << "loadable chunk";
144  if (skiplen != 0) {
145  messages.flags(std::ios::dec);
146  messages << " at offset " << skiplen;
147  }
148 
149  messages.flags(std::ios::hex);
150  messages << ": vaddr 0x" << vaddr;
151 
152  messages.flags(std::ios::dec);
153  messages << ", " << totalSize << " bytes\n";
154 
155  // Write to the bus, one byte at a time.
156  for (size_t k=0; k<(size_t)totalSize; ++k) {
157  bus->AddressSelect(vaddr);
158  if (!bus->WriteData(data[k])) {
159  messages.flags(std::ios::hex);
160  messages << "Failed to write data to "
161  "virtual address 0x" << vaddr << "\n";
162  return false;
163  }
164 
165  ++ vaddr;
166  }
167 
168  // Set the CPU's entry point.
169  stringstream ss;
170  ss << initialpc;
171  component->SetVariableValue("pc", ss.str());
172 
173  return true;
174 }
175 
176 
177 /*****************************************************************************/
178 
179 
180 #ifdef WITHUNITTESTS
181 
182 #include "ComponentFactory.h"
183 
184 static void Test_FileLoader_raw_Constructor()
185 {
186  // TODO: haha, better test.
187  FileLoader_raw rawLoader("test/FileLoader_A.OUT_M88K");
188 }
189 
191 {
192  UNITTEST(Test_FileLoader_raw_Constructor);
193 
194  // TODO
195 }
196 
197 #endif
data
u_short data
Definition: siireg.h:79
ComponentFactory.h
StringHelper::SplitStringIntoVector
static vector< string > SplitStringIntoVector(const string &str, const char splitter)
Splits a string with a certain delimiter into a vector of strings.
Definition: StringHelper.cc:99
refcount_ptr< Component >
UNITTESTS
#define UNITTESTS(class)
Helper for unit test case execution.
Definition: UnitTest.h:184
FileLoader_raw
Raw binary loader (no specific format).
Definition: FileLoader_raw.h:43
FileLoader_raw::FileLoader_raw
FileLoader_raw(const string &filename)
Definition: FileLoader_raw.cc:43
UNITTEST
#define UNITTEST(functionname)
Helper for unit test case execution.
Definition: UnitTest.h:217
AddressDataBus::WriteData
virtual bool WriteData(const uint8_t &data, Endianness endianness=BigEndian)=0
Writes 8-bit data to the currently selected address.
FileLoader_raw.h
FileLoader_raw::DetectFileType
string DetectFileType(unsigned char *buf, size_t buflen, float &matchness) const
Attempt to detect file type.
Definition: FileLoader_raw.cc:49
Component::SetVariableValue
bool SetVariableValue(const string &name, const string &expression)
Sets a variable to a new value.
Definition: Component.cc:1030
AddressDataBus::AddressSelect
virtual void AddressSelect(uint64_t address)=0
Place an address on the bus.
StringHelper.h
CPUComponent.h
FileLoader_raw::LoadIntoComponent
bool LoadIntoComponent(refcount_ptr< Component > component, ostream &messages) const
Loads the file into a Component.
Definition: FileLoader_raw.cc:72
FileLoaderImpl
A file loader.
Definition: FileLoaderImpl.h:40
AddressDataBus
An interface for implementing components that read/write data via an address bus.
Definition: AddressDataBus.h:44
AddressDataBus.h
StringHelper::ParseNumber
static uint64_t ParseNumber(const char *str, bool &error)
Parses a string into a 64-bit number.
Definition: StringHelper.cc:34
Component::AsAddressDataBus
virtual AddressDataBus * AsAddressDataBus()
Returns the component's AddressDataBus interface, if any.
Definition: Component.cc:367
FileLoaderImpl::Filename
const string & Filename() const
Definition: FileLoaderImpl.h:81

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17