RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
cpm68k.h
1#ifndef CPM68K_H
2#define CPM68K_H
3
4#include <map>
5#include <set>
6#include <string>
7#include "../common.h"
8#include "../linker/module.h"
9#include "../linker/options.h"
10#include "../linker/segment.h"
11#include "../linker/segment_manager.h"
12#include "../linker/writer.h"
13#include "../dumper/dumper.h"
14
15namespace DigitalResearch
16{
27 class CPM68KFormat : public virtual Linker::SegmentManager
28 {
29 public:
30 /* * * General members * * */
31
36 {
48 MAGIC_CRUNCHED, /* Concurrent DOS 68K only */
49 };
50
52 char signature[2] = { 0x60, 0x1A };
53
57 uint32_t code_size = 0;
61 uint32_t data_size = 0;
65 uint32_t bss_size = 0;
69 uint32_t symbol_table_size = 0;
73 uint32_t stack_size = 0;
74
78 uint32_t code_address = 0;
82 uint32_t program_flags = 0; /* TODO: make parameter */
83
91 uint32_t data_address = 0;
95 uint32_t bss_address = 0;
99 offset_t file_size = 0;
100
104 std::shared_ptr<Linker::Image> code = nullptr;
108 std::shared_ptr<Linker::Image> data = nullptr;
109
110 /* filled in automatically */
112 {
116 size_t size;
120 unsigned segment;
121 operator size_t() const;
122 };
126 std::map<uint32_t, Relocation> relocations;
127
128 magic_type GetSignature() const;
129
130 void SetSignature(magic_type magic);
131
162
167
168 void Clear() override;
169
171 : system(system)
172 {
173 }
174
176 : system(system)
177 {
178 SetSignature(magic);
179 }
180
181 void ReadFile(Linker::Reader& rd) override;
182
183 template <typename SizeType>
184 static offset_t CDOS68K_MeasureRelocations(std::map<uint32_t, SizeType> relocations)
185 {
186 /* TODO: test */
187 offset_t count = 0;
188 offset_t last_relocation = 0;
189 for(auto it : relocations)
190 {
191 offset_t difference = it.first - last_relocation;
192 if(difference != 0 && difference <= 0x7C)
193 {
194 count += 1;
195 }
196 else if(difference < 0x100)
197 {
198 count += 2;
199 }
200 else if(difference < 0x10000)
201 {
202 count += 3;
203 }
204 else
205 {
206 count += 5;
207 }
208 }
209 return count;
210 }
211
212 template <typename SizeType>
213 static void CDOS68K_WriteRelocations(Linker::Writer& wr, std::map<uint32_t, SizeType> relocations)
214 {
215 /* TODO: test */
216 offset_t last_relocation = 0;
217 for(auto it : relocations)
218 {
219 offset_t difference = it.first - last_relocation;
220 uint8_t highbit = it.second/*.size*/ == 2 ? 0x80 : 0x00;
221 if(difference != 0 && difference <= 0x7C)
222 {
223 wr.WriteWord(1, highbit | difference);
224 }
225 else if(difference < 0x100)
226 {
227 wr.WriteWord(1, highbit | 0x7D);
228 wr.WriteWord(1, difference);
229 }
230 else if(difference < 0x10000)
231 {
232 wr.WriteWord(1, highbit | 0x7E);
233 wr.WriteWord(2, difference);
234 }
235 else
236 {
237 wr.WriteWord(1, highbit | 0x7F);
238 wr.WriteWord(4, difference);
239 }
240 }
241 }
242
243 offset_t MeasureRelocations() const;
244
245 offset_t ImageSize() const override;
246
248 offset_t WriteFile(Linker::Writer& wr) const override;
249
250 void Dump(Dumper::Dumper& dump) const override;
251
252 void CalculateValues() override;
253
254 /* * * Writer members * * */
255
257 {
258 public:
259 Linker::Option<bool> noreloc{"noreloc", "Suppress generating relocations"};
260 Linker::Option<bool> reloc{"reloc", "Force relocation generation"};
261
263 {
264 InitializeFields(noreloc, reloc);
265 }
266 };
267
272
274 std::shared_ptr<Linker::Segment> bss_segment;
276 std::shared_ptr<Linker::Segment> stack_segment;
277
279 std::shared_ptr<Linker::Segment> CodeSegment();
280
282 std::shared_ptr<Linker::Segment> DataSegment();
283
284 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
285
286 static std::vector<Linker::OptionDescription<void> *> ParameterNames;
287 std::vector<Linker::OptionDescription<void> *> GetLinkerScriptParameterNames() override;
288
289 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
290
291 void SetOptions(std::map<std::string, std::string>& options) override;
292
293 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
294
295 void CreateDefaultSegments();
296
297 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
298
299 void Link(Linker::Module& module);
300
301 void ProcessModule(Linker::Module& module) override;
302
303 void GenerateFile(std::string filename, Linker::Module& module) override;
304
306 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
307 };
308
309}
310
311#endif /* CPM68K_H */
The native executable format for the Motorola 68000 port of CP/M.
Definition cpm68k.h:28
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition cpm68k.cc:977
offset_t file_size
Size of entire file, not used for generation.
Definition cpm68k.h:99
void OnNewSegment(std::shared_ptr< Linker::Segment > segment) override
Callback function when allocating a new segment When the linker script runs, it creates segments cons...
Definition cpm68k.cc:713
uint32_t stack_size
Size of the stack segment. Only used by Concurrent DOS 68K.
Definition cpm68k.h:73
uint32_t code_address
Load address of the code/text segment. Not used by GEMDOS which stores the program flags at this offs...
Definition cpm68k.h:78
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition cpm68k.cc:637
std::shared_ptr< Linker::Segment > bss_segment
Segment to collect bss.
Definition cpm68k.h:274
uint32_t bss_size
Size of the uninitialized data (bss) segment. Human68k includes the stack in it.
Definition cpm68k.h:65
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition cpm68k.cc:999
std::shared_ptr< Linker::Segment > CodeSegment()
Return code segment (if it exists)
Definition cpm68k.cc:599
uint32_t program_flags
Program flags, used by GEMDOS.
Definition cpm68k.h:82
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition cpm68k.cc:355
uint32_t bss_address
Load address of the uninitialized data (bss) segment. Only relevant for non-contiguous executables (C...
Definition cpm68k.h:95
std::map< uint32_t, Relocation > relocations
Relocations, not used for Human68k.
Definition cpm68k.h:126
bool option_no_relocation
Makes sure no relocations are placed into the output file.
Definition cpm68k.h:271
std::shared_ptr< Linker::Image > data
Storage for data segment.
Definition cpm68k.h:108
uint16_t relocations_suppressed
Set to a non-0 value when relocations are suppressed. Typically this can be 1, but Human68k specifica...
Definition cpm68k.h:87
magic_type
Represents the magic number at the beginning of the executable file.
Definition cpm68k.h:36
@ MAGIC_CONTIGUOUS
Contiguous executables (magic value 0x601A in big endian) must load the code, data,...
Definition cpm68k.h:40
@ MAGIC_CRUNCHED
Contiguous executables with crunched relocations (magic value 0x601C in big endian),...
Definition cpm68k.h:48
@ MAGIC_NONCONTIGUOUS
Non-contiguous executables (magic value 0x601B in big endian) can load the code, data,...
Definition cpm68k.h:44
std::shared_ptr< Linker::Segment > stack_segment
Segment to collect stack (Concurrent DOS 68K only)
Definition cpm68k.h:276
void Clear() override
Resets all fields to their default values, deallocate memory.
Definition cpm68k.cc:49
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition cpm68k.cc:642
system_type system
The system which will load the executable.
Definition cpm68k.h:166
std::vector< Linker::OptionDescription< void > * > GetLinkerScriptParameterNames() override
Returns a list of the parameters used in the linker scripts, used for documentation.
Definition cpm68k.cc:632
std::shared_ptr< Linker::Segment > DataSegment()
Return data segment (if it exists)
Definition cpm68k.cc:604
offset_t ImageSize() const override
Retrieves size of stored data.
Definition cpm68k.cc:350
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition cpm68k.cc:566
system_type
Different systems have different relocation formats and expectations as to what segments should be pr...
Definition cpm68k.h:136
@ SYSTEM_GEMDOS
Digital Research GEMDOS, Atari TOS, only contiguous, text load address field replaced by program fiel...
Definition cpm68k.h:152
@ SYSTEM_UNKNOWN
Unknown system: use GEMDOS with no relocations.
Definition cpm68k.h:140
@ SYSTEM_CDOS68K
Digital Research Concurrent DOS 68K, non-contiguous not allowed, but relocations can be in CP/M-68K f...
Definition cpm68k.h:160
@ SYSTEM_GEMDOS_EARLY
Digital Research GEMDOS, only contiguous, relocations always present, header is an unusual 0x1E bytes...
Definition cpm68k.h:148
@ SYSTEM_HUMAN68K
Sharp Corporation & Hudson Soft Human68k .z executable, only contiguous, no relocations or symbol tab...
Definition cpm68k.h:156
@ SYSTEM_CPM68K
Digital Research CP/M-68K, uses CP/M-68K relocations.
Definition cpm68k.h:144
uint32_t code_size
Size of the code/text segment.
Definition cpm68k.h:57
char signature[2]
The magic number at the beginning of the executable file, one of 0x601A (contiguous),...
Definition cpm68k.h:52
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition cpm68k.cc:880
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition cpm68k.cc:459
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition cpm68k.cc:60
std::shared_ptr< Linker::Image > code
Storage for code segment.
Definition cpm68k.h:104
uint32_t symbol_table_size
Size of the symbol table.
Definition cpm68k.h:69
uint32_t data_size
Size of the initialized data segment.
Definition cpm68k.h:61
uint32_t data_address
Load address of the initialized data segment. Only relevant for non-contiguous executables (CP/M-68K)...
Definition cpm68k.h:91
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:586
offset_t WriteFile(Writer &wr) const override=0
Stores data in memory to file.
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Helper class that contains the options interpreted by the format.
Definition options.h:308
Documents and handles command line options.
Definition options.h:196
virtual std::string GetDefaultExtension(Module &module, std::string filename) const
Appends a default extension to the filename.
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
A helper class to collect sections into segments.
Definition segment_manager.h:32
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
void WriteWord(size_t bytes, uint64_t value, EndianType endiantype)
Read a word.
Definition writer.cc:66
unsigned segment
Segment value, as required by CP/M-68K, they take the value that is stored in file: 1 for data,...
Definition cpm68k.h:120
size_t size
Size of value to relocate.
Definition cpm68k.h:116