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/module.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{
30 class CPM86Format : public virtual Linker::SegmentManager
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::Image> 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
132 void Prepare(CPM86Format& module);
133
134 void WriteDescriptor(Linker::Writer& wr, const CPM86Format& module) const;
135
136 virtual void WriteData(Linker::Writer& wr, const CPM86Format& module) const;
137
138 std::string GetDefaultName() const;
139
140 virtual void ReadData(Linker::Reader& rd, const CPM86Format& module);
141 };
142
147 {
149 number_t segment;
151 offset_t offset;
152
154 : segment(0), offset(0)
155 {
156 }
157
158 relocation_source(size_t segment, offset_t offset)
160 {
161 }
162
163 bool operator<(const relocation_source& other) const;
164 };
165
170 {
171 uint8_t source = 0;
172 uint16_t paragraph = 0;
173 uint8_t offset = 0;
174 uint8_t target = 0;
175
176 Relocation()
177 {
178 }
179
180 Relocation(uint8_t source, uint16_t paragraph, uint16_t offset, uint8_t target)
181 : source(source), paragraph(paragraph), offset(offset), target(target)
182 {
183 }
184
185 Relocation(relocation_source source, uint8_t target)
186 : source(source.segment), paragraph(source.offset >> 4), offset(source.offset & 0xF), target(target)
187 {
188 }
189
190 operator bool() const;
191
192 void Read(Linker::Reader& rd, CPM86Format& module, bool is_library = false);
193
194 void Write(Linker::Writer& wr) const;
195
196 relocation_source GetSource() const;
197 };
198
205 {
207 std::string rsx_file_name;
209 std::string name;
216 uint16_t offset_record = 0;
217 static constexpr uint16_t RSX_TERMINATE = 0xFFFF;
218 static constexpr uint16_t RSX_DYNAMIC = 0x0000;
222 std::shared_ptr<Linker::Image> contents;
223
224 void Clear();
225
226 void Read(Linker::Reader& rd);
227
228 void ReadModule(Linker::Reader& rd);
229
230 void Write(Linker::Writer& wr) const;
231
232 void WriteModule(Linker::Writer& wr) const;
233
234 offset_t GetFullFileSize() const;
235 void SetOffset(offset_t new_offset);
236
237 void Dump(Dumper::Dumper& dump) const;
238 };
239
247 {
249 std::string name;
251 uint16_t major_version = 0;
253 uint16_t minor_version = 0;
255 uint32_t flags = 0x11010000;
256
257 library_id() { }
258
259 library_id(std::string name, uint16_t major_version, uint16_t minor_version)
261 {
262 }
263
264 library_id(std::string name, uint16_t major_version, uint16_t minor_version, uint32_t flags)
266 {
267 }
268
269 void Write(Linker::Writer& wr) const;
270
271 void Read(Linker::Reader& rd);
272 };
273
280 struct library : public library_id
281 {
283 std::vector<Relocation> relocations;
285 uint16_t relocation_count = 0;
286
288 uint16_t first_selector = 0;
290 uint16_t unknown = 1;
291
292 library()
293 {
294 }
295
296 library(std::string name, uint16_t major_version, uint16_t minor_version)
298 {
299 }
300
301 library(std::string name, uint16_t major_version, uint16_t minor_version, uint32_t flags)
302 : library_id(name, major_version, minor_version, flags)
303 {
304 }
305
306 void Write(Linker::Writer& wr) const;
307
308 void WriteExtended(Linker::Writer& wr) const;
309
310 void Read(Linker::Reader& rd);
311
312 void ReadExtended(Linker::Reader& rd);
313 };
314
317 {
318 public:
320 std::vector<library> libraries;
321
322 void Clear() override;
323
327 bool IsFastLoadFormat() const;
328
329 uint16_t GetSizeParas(const CPM86Format& module) const override;
330
331 void WriteData(Linker::Writer& wr, const CPM86Format& module) const override;
332
333 void ReadData(Linker::Reader& rd, const CPM86Format& module) override;
334 };
335
338 {
339 public:
341 uint16_t maximum_entries = 0;
343 uint16_t first_free_entry = 0;
345 uint16_t index_base = 0;
347 uint16_t first_used_index = 0;
348
350 {
352 uint16_t limit;
354 uint32_t address;
356 uint8_t group;
357 uint16_t reserved;
358
359 void Read(Linker::Reader& rd);
360
361 void Write(Linker::Writer& wr) const;
362 };
363
364 std::vector<ldt_descriptor> ldt;
365
366 void Clear() override;
367
368 uint16_t GetSizeParas(const CPM86Format& module) const override;
369
370 void WriteData(Linker::Writer& wr, const CPM86Format& module) const override;
371
372 void ReadData(Linker::Reader& rd, const CPM86Format& module) override;
373 };
374
378 std::array<Descriptor, 8> descriptors;
394 std::vector<Relocation> relocations;
398 uint32_t relocations_offset = 0;
402 std::array<rsx_record, 8> rsx_table;
406 uint32_t rsx_table_offset = 0;
410 uint8_t flags = 0; /* TODO: make parameter */
414 uint32_t file_offset = 0;
416 mutable offset_t file_size = offset_t(-1);
417
418 enum
419 {
427 FLAG_RSX = 0x10,
429 FLAG_DIRECT_VIDEO = 0x08
430 };
431
432 void Clear() override;
433
436 {
456 FORMAT_FLEXOS, /* TODO: the documentation claims there are multiple models, is it about the model and not the format? */
457 };
460
472
475 {
476 }
477
479 {
480 Clear();
481 }
482
483 uint16_t GetRelocationSizeParas() const;
484
485 size_t CountValidGroups();
486
487 number_t FindSegmentGroup(unsigned group) const;
488
489 void CheckValidSegmentGroup(unsigned group);
490
491 bool IsFastLoadFormat() const;
492
493 void ReadRelocations(Linker::Reader& rd);
494
495 void WriteRelocations(Linker::Writer& wr) const;
496
497 offset_t MeasureRelocations();
498
499 void ReadFile(Linker::Reader& rd) override;
500
501 offset_t ImageSize() const override;
502
504 offset_t WriteFile(Linker::Writer& wr) const override;
505
506 offset_t GetFullFileSize() const;
507
508 void Dump(Dumper::Dumper& dump) const override;
509
510 void CalculateValues() override;
511
512 /* * * Writer members * * */
513
515 bool shared_code = false; /* TODO: make parameter */
518
521 {
522 MODEL_DEFAULT,
529 /* TODO: FlexOS model */
530 };
533
534 bool FormatSupportsSegmentation() const override;
535
536 bool FormatIs16bit() const override;
537
538 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
539
540 std::vector<std::shared_ptr<Linker::Segment>>& Segments();
541
542 unsigned GetSegmentNumber(std::shared_ptr<Linker::Segment> segment);
543
544 void SetModel(std::string model) override;
545
546 void SetOptions(std::map<std::string, std::string>& options) override;
547
548 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
549
550 void Link(Linker::Module& module);
551
552 void ProcessModule(Linker::Module& module) override;
553
554 void GenerateFile(std::string filename, Linker::Module& module) override;
555
557 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
558 };
559
560}
561
562#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
void Prepare(CPM86Format &module)
Sets up any values before it can be written to file.
Definition cpm86.cc:39
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:18
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::Image > 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:338
uint16_t GetSizeParas(const CPM86Format &module) const override
Returns the size of the segment group in 16-byte paragraphs.
Definition cpm86.cc:346
uint16_t index_base
The index base.
Definition cpm86.h:345
uint16_t first_used_index
First used index.
Definition cpm86.h:347
uint16_t first_free_entry
First free entry in LDT after last filled entry.
Definition cpm86.h:343
uint16_t maximum_entries
Maximum allowed LDT entries.
Definition cpm86.h:341
A special descriptor to represent the group for imported shared runtime libraries.
Definition cpm86.h:317
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:275
std::vector< library > libraries
The shared runtime libraries to be imported.
Definition cpm86.h:320
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:406
offset_t file_size
The full size of the image.
Definition cpm86.h:416
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition cpm86.cc:912
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition cpm86.cc:1354
std::array< Descriptor, 8 > descriptors
A .cmd file may contain up to 8 descriptors that describer the segment groups.
Definition cpm86.h:378
bool option_no_relocation
Flag to indicate that relocations must be suppressed.
Definition cpm86.h:517
application_type application
Target application type.
Definition cpm86.h:471
std::array< rsx_record, 8 > rsx_table
Represents a list of attached RSX modules.
Definition cpm86.h:402
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition cpm86.cc:496
@ FLAG_DIRECT_VIDEO
Set when the program uses direct video access. Such programs cannot execute in the background.
Definition cpm86.h:429
@ FLAG_FIXUPS
Set when relocations are present, indicates that the executable is relocatable and needs fixing up be...
Definition cpm86.h:421
@ FLAG_REQUIRED_8087
Set when the software only runs if an 8087 is present. The system will allocate 8087 resources.
Definition cpm86.h:425
@ FLAG_RSX
Set for residential system extensions (RSX files)
Definition cpm86.h:427
@ FLAG_OPTIONAL_8087
Set when the software expects the system to allocate 8087 resources, but it can emulate the missing 8...
Definition cpm86.h:423
FastLoadDescriptor fastload_descriptor
FlexOS 286 defines a fast load segment (unknown name) at offset 0x51.
Definition cpm86.h:386
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition cpm86.cc:707
bool shared_code
Flag indicating that the code group is shared, not possible in 8080 format.
Definition cpm86.h:515
format_type
Describes the number and type of segment groups.
Definition cpm86.h:436
@ FORMAT_FLEXOS
Only code (possibly shared), data and a stack segment is present, with postlink or SRTL (unfinished)
Definition cpm86.h:456
@ FORMAT_COMPACT
Each non-executable section will have its own group, including stack and up to 4 auxiliary groups.
Definition cpm86.h:452
@ FORMAT_8080
Only a single non-shared code group is present.
Definition cpm86.h:444
@ FORMAT_UNKNOWN
Unspecified.
Definition cpm86.h:440
@ FORMAT_SMALL
Only code (possibly shared) and a separate data group is present.
Definition cpm86.h:448
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition cpm86.cc:586
memory_model_t memory_model
Memory model of generated code, determines how the offsets are calculated within a segment group.
Definition cpm86.h:532
memory_model_t
Represents the memory model of the running executable, which is the way in which the segments are set...
Definition cpm86.h:521
@ MODEL_COMPACT
DS!=SS!=ES.
Definition cpm86.h:528
@ MODEL_TINY
CS=DS=SS=ES, only possible in 8080 mode.
Definition cpm86.h:524
@ MODEL_SMALL
DS=SS=ES, only possible in 8080 or small mode.
Definition cpm86.h:526
std::vector< Relocation > relocations
The sequence of intramodule relocations.
Definition cpm86.h:394
offset_t ImageSize() const override
Retrieves size of stored data.
Definition cpm86.cc:581
uint32_t relocations_offset
Offset of relocation records, stored in 128 byte units at offset 0x7D.
Definition cpm86.h:398
application_type
Definition cpm86.h:462
@ APPL_RSX
CP/M-86 .rsx file.
Definition cpm86.h:466
@ APPL_286
FlexOS 86 .286 file.
Definition cpm86.h:468
@ APPL_CMD
CP/M-86 .cmd file.
Definition cpm86.h:464
bool FormatIs16bit() const override
Whether the format is 16-bit or not.
Definition cpm86.cc:988
uint8_t flags
Execution flags, stored at offset 0x7F.
Definition cpm86.h:410
void SetModel(std::string model) override
Sets the way memory is organized, typically modifying a built-in script.
Definition cpm86.cc:1031
library_id lib_id
FlexOS 286 library identifier (for libraries) at offset 0x60.
Definition cpm86.h:390
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition cpm86.cc:1064
void Clear() override
Resets all fields to their default values, deallocate memory.
Definition cpm86.cc:377
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition cpm86.cc:1479
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition cpm86.cc:983
LibraryDescriptor library_descriptor
FlexOS 286 defines a shared runtime library group at offset 0x48.
Definition cpm86.h:382
format_type format
Format of file to generate.
Definition cpm86.h:459
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition cpm86.cc:1489
uint32_t file_offset
The start of the image within the file, typically 0 except for embedded modules, usually for embedded...
Definition cpm86.h:414
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
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
uint32_t address
Intel 286 descriptor base address, 24-bit.
Definition cpm86.h:354
uint8_t group
Group the segment belongs to.
Definition cpm86.h:356
uint16_t limit
Intel 286 descriptor limit.
Definition cpm86.h:352
Represents a single relocation.
Definition cpm86.h:170
(FlexOS only) A shared runtime library identifier
Definition cpm86.h:247
uint16_t major_version
The major version of the library.
Definition cpm86.h:251
std::string name
The name of the library, 8 characters long.
Definition cpm86.h:249
uint32_t flags
System specific flags, undocumented.
Definition cpm86.h:255
uint16_t minor_version
The minor version of the library.
Definition cpm86.h:253
(FlexOS 286 only) A shared runtime library entry in the shared runtime library group
Definition cpm86.h:281
uint16_t relocation_count
Relocation count.
Definition cpm86.h:285
uint16_t first_selector
(FASTLOAD only) First selector that references this library
Definition cpm86.h:288
uint16_t unknown
(FASTLOAD only) Unknown
Definition cpm86.h:290
std::vector< Relocation > relocations
The set of relocations.
Definition cpm86.h:283
Represents the location of a 16-bit words that needs to be relocated.
Definition cpm86.h:147
offset_t offset
The offset to the word within the segment group.
Definition cpm86.h:151
number_t segment
The segment group number that contains the required relocation.
Definition cpm86.h:149
Represents an attached RSX file (residential system extension)
Definition cpm86.h:205
std::shared_ptr< Linker::Image > contents
A reference to the stored module, either parsed or a raw block of data.
Definition cpm86.h:222
uint16_t offset_record
The offset to the attached RSX file, in 128-byte units.
Definition cpm86.h:216
std::string name
The filename of the RSX file, 8-byte long.
Definition cpm86.h:209
std::string rsx_file_name
The host filename of the RSX file, used only for writing.
Definition cpm86.h:207