RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
cpm86.h
1#ifndef CPM86_H
2#define CPM86_H
3
4#include <array>
5#include <map>
6#include <set>
7#include <vector>
8#include "../common.h"
9#include "../linker/linker.h"
10#include "../linker/module.h"
11#include "../linker/segment.h"
12#include "../linker/writer.h"
13#include "../dumper/dumper.h"
14
15namespace DigitalResearch
16{
31 {
32 public:
33 /* * * General members * * */
34
55 {
56 public:
96 uint16_t size_paras = 0;
98 uint16_t load_segment = 0;
100 uint16_t min_size_paras = 0;
102 uint16_t max_size_paras = 0;
109 uint32_t offset = 0;
111 std::shared_ptr<Linker::Writable> image = nullptr;
113 bool attach_zero_page = false;
114
115 virtual void Clear();
116
118 {
119 Clear();
120 }
121
125 virtual uint16_t GetSizeParas(const CPM86Format& module) const;
126
127 void ReadDescriptor(Linker::Reader& rd);
128
129 void WriteDescriptor(Linker::Writer& wr, const CPM86Format& module);
130
131 virtual void WriteData(Linker::Writer& wr, const CPM86Format& module);
132
133 std::string GetDefaultName();
134
135 virtual void ReadData(Linker::Reader& rd, const CPM86Format& module);
136 };
137
142 {
144 number_t segment;
146 offset_t offset;
147
149 : segment(0), offset(0)
150 {
151 }
152
153 relocation_source(size_t segment, offset_t offset)
155 {
156 }
157
158 bool operator<(const relocation_source& other) const;
159 };
160
165 {
166 uint8_t source = 0;
167 uint16_t paragraph = 0;
168 uint8_t offset = 0;
169 uint8_t target = 0;
170
171 Relocation()
172 {
173 }
174
175 Relocation(uint8_t source, uint16_t paragraph, uint16_t offset, uint8_t target)
176 : source(source), paragraph(paragraph), offset(offset), target(target)
177 {
178 }
179
180 Relocation(relocation_source source, uint8_t target)
181 : source(source.segment), paragraph(source.offset >> 4), offset(source.offset & 0xF), target(target)
182 {
183 }
184
185 operator bool() const;
186
187 void Read(Linker::Reader& rd, CPM86Format& module, bool is_library = false);
188
189 void Write(Linker::Writer& wr);
190
191 relocation_source GetSource() const;
192 };
193
200 {
202 std::string name;
209 uint16_t offset_record = 0;
217 std::shared_ptr<CPM86Format> module = nullptr;
218 static std::shared_ptr<CPM86Format> dynamic_module;
219#define RSX_TERMINATE (std::shared_ptr<CPM86Format>(nullptr))
220#define RSX_DYNAMIC (::DigitalResearch::CPM86Format::rsx_record::dynamic_module)
221
222 void Clear();
223
224 void Read(Linker::Reader& rd);
225
226 void ReadModule(Linker::Reader& rd);
227
228 void Write(Linker::Writer& wr);
229
230 void WriteModule(Linker::Writer& wr);
231 };
232
240 {
242 std::string name;
244 uint16_t major_version = 0;
246 uint16_t minor_version = 0;
248 uint32_t flags = 0x11010000;
249
250 library_id() { }
251
252 library_id(std::string name, uint16_t major_version, uint16_t minor_version)
254 {
255 }
256
257 library_id(std::string name, uint16_t major_version, uint16_t minor_version, uint32_t flags)
259 {
260 }
261
262 void Write(Linker::Writer& wr);
263
264 void Read(Linker::Reader& rd);
265 };
266
273 struct library : public library_id
274 {
276 std::vector<Relocation> relocations;
278 uint16_t relocation_count = 0;
279
281 uint16_t first_selector = 0;
283 uint16_t unknown = 1;
284
285 library()
286 {
287 }
288
289 library(std::string name, uint16_t major_version, uint16_t minor_version)
291 {
292 }
293
294 library(std::string name, uint16_t major_version, uint16_t minor_version, uint32_t flags)
295 : library_id(name, major_version, minor_version, flags)
296 {
297 }
298
299 void Write(Linker::Writer& wr);
300
301 void WriteExtended(Linker::Writer& wr);
302
303 void Read(Linker::Reader& rd);
304
305 void ReadExtended(Linker::Reader& rd);
306 };
307
310 {
311 public:
313 std::vector<library> libraries;
314
315 void Clear() override;
316
320 bool IsFastLoadFormat() const;
321
322 uint16_t GetSizeParas(const CPM86Format& module) const override;
323
324 void WriteData(Linker::Writer& wr, const CPM86Format& module) override;
325
326 void ReadData(Linker::Reader& rd, const CPM86Format& module) override;
327 };
328
331 {
332 public:
334 uint16_t maximum_entries = 0;
336 uint16_t first_free_entry = 0;
338 uint16_t index_base = 0;
340 uint16_t first_used_index = 0;
341
343 {
345 uint16_t limit;
347 uint32_t address;
349 uint8_t group;
350 uint16_t reserved;
351
352 void Read(Linker::Reader& rd);
353
354 void Write(Linker::Writer& wr);
355 };
356
357 std::vector<ldt_descriptor> ldt;
358
359 void Clear() override;
360
361 uint16_t GetSizeParas(const CPM86Format& module) const override;
362
363 void WriteData(Linker::Writer& wr, const CPM86Format& module) override;
364
365 void ReadData(Linker::Reader& rd, const CPM86Format& module) override;
366 };
367
371 std::array<Descriptor, 8> descriptors;
387 std::vector<Relocation> relocations;
391 uint32_t relocations_offset = 0;
395 std::array<rsx_record, 8> rsx_table;
399 uint32_t rsx_table_offset = 0;
403 uint8_t flags = 0; /* TODO: make parameter */
407 uint32_t file_offset = 0;
408
409 enum
410 {
418 FLAG_RSX = 0x10,
420 FLAG_DIRECT_VIDEO = 0x08
421 };
422
423 void Clear() override;
424
427 {
447 FORMAT_FLEXOS, /* TODO: the documentation claims there are multiple models, is it about the model and not the format? */
448 };
451
453 : format(format)
454 {
455 }
456
458 {
459 Clear();
460 }
461
462 uint16_t GetRelocationSizeParas() const;
463
464 size_t CountValidGroups();
465
466 number_t FindSegmentGroup(unsigned group) const;
467
468 void CheckValidSegmentGroup(unsigned group);
469
470 bool IsFastLoadFormat() const;
471
472 void ReadRelocations(Linker::Reader& rd);
473
474 void WriteRelocations(Linker::Writer& wr);
475
476 void ReadFile(Linker::Reader& rd) override;
477
478 void WriteFile(Linker::Writer& wr) override;
479
480 offset_t GetFullFileSize() const;
481
482 void Dump(Dumper::Dumper& dump) override;
483
484 void CalculateValues() override;
485
486 /* * * Writer members * * */
487
489 bool shared_code = false; /* TODO: make parameter */
492
495 {
496 MODEL_DEFAULT,
503 /* TODO: FlexOS model */
504 };
507
508 bool FormatSupportsSegmentation() const override;
509
510 bool FormatIs16bit() const override;
511
512 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
513
514 std::vector<std::shared_ptr<Linker::Segment>>& Segments();
515
516 unsigned GetSegmentNumber(std::shared_ptr<Linker::Segment> segment);
517
518 using LinkerManager::SetLinkScript;
519
520 void SetModel(std::string model) override;
521
522 void SetOptions(std::map<std::string, std::string>& options) override;
523
524 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
525
526 void Link(Linker::Module& module);
527
528 void ProcessModule(Linker::Module& module) override;
529
530 void GenerateFile(std::string filename, Linker::Module& module) override;
531
532 std::string GetDefaultExtension(Linker::Module& module, std::string filename) override;
533 };
534
535}
536
537#endif /* CPM86_H */
A representation of segment group within the executable.
Definition cpm86.h:55
uint16_t load_segment
Load segment address of the group, or 0 if it can be relocated. Not to be used outside of system driv...
Definition cpm86.h:98
bool attach_zero_page
Set to true if a supplementary 256 bytes of zeros are required. When generating image,...
Definition cpm86.h:113
group_type type
The type of the group.
Definition cpm86.h:94
uint16_t max_size_paras
Maximum required size of the group, when loaded into memory, in 16-byte paragraphs.
Definition cpm86.h:102
virtual uint16_t GetSizeParas(const CPM86Format &module) const
Returns the size of the segment group in 16-byte paragraphs.
Definition cpm86.cc:13
uint16_t min_size_paras
Minimum required size of the group, when loaded into memory, in 16-byte paragraphs.
Definition cpm86.h:100
uint32_t offset
Offset to image in file.
Definition cpm86.h:109
std::shared_ptr< Linker::Writable > image
The actual binary image of the group.
Definition cpm86.h:111
uint16_t size_paras
Size of the group, as stored on disk, in 16-byte paragraphs.
Definition cpm86.h:96
group_type
Group type, stored as the first byte of the descriptor.
Definition cpm86.h:59
@ Code
A group containing executable instructions, the starting segment will be loaded into CS....
Definition cpm86.h:63
@ Auxiliary2
A group containing data.
Definition cpm86.h:73
@ Undefined
This group type is not the type of an actual group. Instead, it signals the end of the group descript...
Definition cpm86.h:61
@ Libraries
(FlexOS 286 only) The shared runtime library group descriptor is stored at offset 0x48 in the header,...
Definition cpm86.h:86
@ Data
A group containing data, the starting segment will be loaded into DS.
Definition cpm86.h:65
@ Fixups
(FlexOS 286 only) The group containing the relocations. Not required, since the offset to the relocat...
Definition cpm86.h:82
@ Auxiliary3
A group containing data.
Definition cpm86.h:75
@ Extra
A group containing data, the starting semgnet will be loaded into ES.
Definition cpm86.h:67
@ Stack
A group describing the stack data. Unlike the other associated segments, SS does not point to it at t...
Definition cpm86.h:69
@ Auxiliary4
A group containing data. The group type was later repurposed to represent the relocations in a file....
Definition cpm86.h:77
@ ActualFixups
(FlexOS 286 only) The group containing the relocations, used when it is clear this is a fixup group
Definition cpm86.h:91
@ Auxiliary1
A group containing data.
Definition cpm86.h:71
@ ActualAuxiliary4
A group containing data, used when it is clear this is an auxiliary group.
Definition cpm86.h:89
@ FastLoad
(FlexOS 286 only) The fast load group descriptor is stored at offset 0x51 in the header,...
Definition cpm86.h:84
@ SharedCode
A group containing executable instructions, the starting segment will be loaded into CS....
Definition cpm86.h:79
(FlexOS 286 only) The fast loading group (unimplemented)
Definition cpm86.h:331
uint16_t GetSizeParas(const CPM86Format &module) const override
Returns the size of the segment group in 16-byte paragraphs.
Definition cpm86.cc:329
uint16_t index_base
The index base.
Definition cpm86.h:338
uint16_t first_used_index
First used index.
Definition cpm86.h:340
uint16_t first_free_entry
First free entry in LDT after last filled entry.
Definition cpm86.h:336
uint16_t maximum_entries
Maximum allowed LDT entries.
Definition cpm86.h:334
A special descriptor to represent the group for imported shared runtime libraries.
Definition cpm86.h:310
bool IsFastLoadFormat() const
Support the newer POSTLINK format.
uint16_t GetSizeParas(const CPM86Format &module) const override
Returns the size of the segment group in 16-byte paragraphs.
Definition cpm86.cc:258
std::vector< library > libraries
The shared runtime libraries to be imported.
Definition cpm86.h:313
The native file format for 8086 based CP/M derived operating systems, including FlexOS 186/286.
Definition cpm86.h:31
uint32_t rsx_table_offset
The actual RSX table, stored in 128 byte units at offset 0x7B.
Definition cpm86.h:399
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition cpm86.cc:874
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition cpm86.cc:1229
std::array< Descriptor, 8 > descriptors
A .cmd file may contain up to 8 descriptors that describer the segment groups.
Definition cpm86.h:371
bool option_no_relocation
Flag to indicate that relocations must be suppressed.
Definition cpm86.h:491
std::array< rsx_record, 8 > rsx_table
Represents a list of attached RSX modules.
Definition cpm86.h:395
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition cpm86.cc:469
@ FLAG_DIRECT_VIDEO
Set when the program uses direct video access. Such programs cannot execute in the background.
Definition cpm86.h:420
@ FLAG_FIXUPS
Set when relocations are present, indicates that the executable is relocatable and needs fixing up be...
Definition cpm86.h:412
@ FLAG_REQUIRED_8087
Set when the software only runs if an 8087 is present. The system will allocate 8087 resources.
Definition cpm86.h:416
@ FLAG_RSX
Set for residential system extensions (RSX files)
Definition cpm86.h:418
@ FLAG_OPTIONAL_8087
Set when the software expects the system to allocate 8087 resources, but it can emulate the missing 8...
Definition cpm86.h:414
FastLoadDescriptor fastload_descriptor
FlexOS 286 defines a fast load segment (unknown name) at offset 0x51.
Definition cpm86.h:379
std::string GetDefaultExtension(Linker::Module &module, std::string filename) override
Appends a default extension to the filename.
Definition cpm86.cc:1338
bool shared_code
Flag indicating that the code group is shared, not possible in 8080 format.
Definition cpm86.h:489
format_type
Describes the number and type of segment groups.
Definition cpm86.h:427
@ FORMAT_FLEXOS
Only code (possibly shared), data and a stack segment is present, with postlink or SRTL (unfinished)
Definition cpm86.h:447
@ FORMAT_COMPACT
Each non-executable section will have its own group, including stack and up to 4 auxiliary groups.
Definition cpm86.h:443
@ FORMAT_8080
Only a single non-shared code group is present.
Definition cpm86.h:435
@ FORMAT_UNKNOWN
Unspecified.
Definition cpm86.h:431
@ FORMAT_SMALL
Only code (possibly shared) and a separate data group is present.
Definition cpm86.h:439
memory_model_t memory_model
Memory model of generated code, determines how the offsets are calculated within a segment group.
Definition cpm86.h:506
memory_model_t
Represents the memory model of the running executable, which is the way in which the segments are set...
Definition cpm86.h:495
@ MODEL_COMPACT
DS!=SS!=ES.
Definition cpm86.h:502
@ MODEL_TINY
CS=DS=SS=ES, only possible in 8080 mode.
Definition cpm86.h:498
@ MODEL_SMALL
DS=SS=ES, only possible in 8080 or small mode.
Definition cpm86.h:500
std::vector< Relocation > relocations
The sequence of intramodule relocations.
Definition cpm86.h:387
uint32_t relocations_offset
Offset of relocation records, stored in 128 byte units at offset 0x7D.
Definition cpm86.h:391
bool FormatIs16bit() const override
Whether the format is 16-bit or not.
Definition cpm86.cc:910
uint8_t flags
Execution flags, stored at offset 0x7F.
Definition cpm86.h:403
void SetModel(std::string model) override
Sets the way memory is organized, typically modifying a built-in script.
Definition cpm86.cc:953
library_id lib_id
FlexOS 286 library identifier (for libraries) at offset 0x60.
Definition cpm86.h:383
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition cpm86.cc:986
void Clear() override
Resets all fields to their default values, deallocate memory.
Definition cpm86.cc:360
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition cpm86.cc:1328
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition cpm86.cc:905
LibraryDescriptor library_descriptor
FlexOS 286 defines a shared runtime library group at offset 0x48.
Definition cpm86.h:375
format_type format
Format of file to generate.
Definition cpm86.h:450
void WriteFile(Linker::Writer &wr) override
Stores data in memory to file.
Definition cpm86.cc:556
uint32_t file_offset
The start of the image within the file, typically 0 except for embedded modules, usually for embedded...
Definition cpm86.h:407
void Dump(Dumper::Dumper &dump) override
Display file contents in a nice manner.
Definition cpm86.cc:670
A class to control the output of a file analysis.
Definition dumper.h:550
A helper class to collect sections into segments.
Definition linker.h:19
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:20
A class that provides a general interface to setting up generation for a format.
Definition format.h:56
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
uint32_t address
Intel 286 descriptor base address, 24-bit.
Definition cpm86.h:347
uint8_t group
Group the segment belongs to.
Definition cpm86.h:349
uint16_t limit
Intel 286 descriptor limit.
Definition cpm86.h:345
Represents a single relocation.
Definition cpm86.h:165
(FlexOS only) A shared runtime library identifier
Definition cpm86.h:240
uint16_t major_version
The major version of the library.
Definition cpm86.h:244
std::string name
The name of the library, 8 characters long.
Definition cpm86.h:242
uint32_t flags
System specific flags, undocumented.
Definition cpm86.h:248
uint16_t minor_version
The minor version of the library.
Definition cpm86.h:246
(FlexOS 286 only) A shared runtime library entry in the shared runtime library group
Definition cpm86.h:274
uint16_t relocation_count
Relocation count.
Definition cpm86.h:278
uint16_t first_selector
(FASTLOAD only) First selector that references this library
Definition cpm86.h:281
uint16_t unknown
(FASTLOAD only) Unknown
Definition cpm86.h:283
std::vector< Relocation > relocations
The set of relocations.
Definition cpm86.h:276
Represents the location of a 16-bit words that needs to be relocated.
Definition cpm86.h:142
offset_t offset
The offset to the word within the segment group.
Definition cpm86.h:146
number_t segment
The segment group number that contains the required relocation.
Definition cpm86.h:144
Represents an attached RSX file (residential system extension)
Definition cpm86.h:200
uint16_t offset_record
The offset to the attached RSX file, in 128-byte units.
Definition cpm86.h:209
std::string name
The filename of the RSX file, 8-byte long.
Definition cpm86.h:202