-
Notifications
You must be signed in to change notification settings - Fork 31
/
world_tools.h
209 lines (170 loc) · 7.45 KB
/
world_tools.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* -*- Mode: C; Tab-Width: 4 -*- */
/* Ivory and VLM World File Format */
#ifndef _WORLD_TOOLS_
#define _WORLD_TOOLS_
#include <sys/types.h>
#include <dirent.h>
#include "life_types.h"
#include "VLM_configuration.h"
#include "ivoryrep.h"
#include "memory.h"
/* A single load map entry -- See SYS:NETBOOT;WORLD-SUBSTRATE.LISP for details */
typedef struct
{
Integer address; /* VMA to be filled in by this load map entry */
struct
{
#if BYTE_ORDER == LITTLE_ENDIAN
Integer count:24; /* Number of words to be filled in by this entry */
Integer opcode:8; /* An LoadMapEntryOpcode specifying how to do so */
#else
Integer opcode:8; /* An LoadMapEntryOpcode specifying how to do so */
Integer count:24; /* Number of words to be filled in by this entry */
#endif
} op;
LispObj data; /* Interpretation is based on the opcode */
PtrV world; /* -> World from which this entry was obtained */
} LoadMapEntry;
/* Load map operation codes */
enum LoadMapEntryOpcode
{
LoadMapDataPages, /* Load data pages from the file */
LoadMapConstant, /* Store a constant into memory */
LoadMapConstantIncremented, /* Store an auto-incrementing constant into memory */
LoadMapCopy /* Copy an existing piece of memory */
};
/* Description of an open world file */
typedef struct World
{
char* pathname; /* -> Pathname of the world file */
int fd; /* Unix filedes # if the world file is open */
int format; /* A LoadFileFormat indicating the type of file */
int byteSwapped; /* World is byte swapped on this machine (VLM only) */
int vlmDataPageBase; /* Block number of first page of data (VLM only) */
int vlmTagsPageBase; /* Block number of first page of tags (VLM only) */
byte* vlmDataPage; /* -> The data of the current VLM format page */
byte* vlmTagsPage; /* -> The tags of the current VLM format page */
byte* ivoryDataPage; /* -> The data of the current Ivory format page */
int currentPageNumber; /* Page number of the page in the buffer, if any */
int currentQNumber; /* Q number within the page to be read */
struct World* parentWorld; /* -> Parent of this world if it's an IDS */
Integer sysoutGeneration; /* Generation number of this world (> 0 if IDS) */
Integer sysoutTimestamp1; /* Unique ID of this world, part 1 ... */
Integer sysoutTimestamp2; /* ... part 2 */
Integer sysoutParentTimestamp1; /* Unique ID of this world's parent, part 1 ... */
Integer sysoutParentTimestamp2; /* ... part 2 */
int nWiredMapEntries; /* Number of wired load map entries */
LoadMapEntry* wiredMapEntries; /* -> The wired load map entries */
int nMergedWiredMapEntries; /* As above but after merging with parent worlds */
LoadMapEntry* mergedWiredMapEntries; /* .. */
int nUnwiredMapEntries; /* Number of unwired load map entries (Ivory only) */
LoadMapEntry* unwiredMapEntries; /* -> The unwired load map entries (Ivory only) */
int nMergedUnwiredMapEntries; /* As above but after merging with parent worlds */
LoadMapEntry* mergedUnwiredMapEntries; /* .. */
} World;
/* Possible world file formats */
enum LoadFileFormat
{
VLMWorldFormat, /* VLM world file (.VLOD) */
IvoryWorldFormat /* Ivory world file (.ILOD) */
};
/* Common world format format definitions */
#define VersionAndArchitectureQ 0
/* VLM world file format definitions */
#define VLMWorldSuffix ".vlod"
#define VLMWorldFileCookie 024342504610L
#define VLMWorldFileCookieSwapped 021042305243L
#define VLMPageSizeQs 8192
#define VLMBlockSize 8192
#define VLMBlocksPerDataPage 4
#define VLMBlocksPerTagsPage 1
#define VLMMaximumHeaderBlocks 14
#define VLMDataPageSizeBytes 4 * VLMPageSizeQs
#define VLMTagsPageSizeBytes VLMPageSizeQs
#define VLMVersion1AndArchitecture 040000200
#define VLMWorldFileV1WiredCountQ 1
#define VLMWorldFileV1UnwiredCountQ 0
#define VLMWorldFileV1PageBasesQ 3
#define VLMWorldFileV1FirstSysoutQ 0
#define VLMWorldFileV1FirstMapQ 8
#define VLMVersion2AndArchitecture 040000201
#define VLMWorldFileV2WiredCountQ 1
#define VLMWorldFileV2UnwiredCountQ 0
#define VLMWorldFileV2PageBasesQ 2
#define VLMWorldFileV2FirstSysoutQ 3
#define VLMWorldFileV2FirstMapQ 8
/* Block numbers of the first page of data and tags for a VLM world as stored in its header */
typedef struct
{
#if BYTE_ORDER == LITTLE_ENDIAN
Integer dataPageBase: 28;
Integer tagsPageBase: 4; /* Limits header and load maps to 112K bytes */
#else
Integer tagsPageBase: 4; /* Limits header and load maps to 112K bytes */
Integer dataPageBase: 28;
#endif
} VLMPageBases;
/* Ivory world file format definitions */
#define IvoryWorldSuffix ".ilod"
#if BYTE_ORDER == LITTLE_ENDIAN
#define IvoryWorldFileCookie 014322444510L
#else
#define IvoryWorldFileCookie 011022245143L
#endif
#define IvoryPageSizeQs 256
#define IvoryPageSizeBytes 1280
#define IvoryWorldFileWiredCountQ 1
#define IvoryWorldFileUnwiredCountQ 2
#define IvoryWorldFileFirstSysoutQ 0
#define IvoryWorldFileFirstMapQ 8
/* Data structures passed by Lisp via the SaveWorld coprocessor register */
typedef struct
{
Integer address; /* VMA of data (usually a region) to be saved */
Integer extent; /* Number of words starting at this address to save */
} SaveWorldEntry;
typedef struct
{
Integer pathname; /* Pathname of the world file (a DTP-STRING) */
Integer entryCount; /* Number of address/extent pairs to follow */
SaveWorldEntry entries[1];
} SaveWorldData;
/* Prototypes of all functions in worlds_tools.c */
void LoadVLMDebugger (VLMConfig* config);
Integer LoadWorld (VLMConfig* config);
void SaveWorld (Integer saveWorldDataVMA);
void ByteSwapWorld (char* worldPathname, char* searchPath);
static void ByteSwapOneWorld (World* world);
static void CanonicalizeVLMLoadMapEntries (World* world);
static void CloseExtraWorlds ();
static void CloseWorldFile (World* world, boolean closeParents);
static void CreateWorldFile (World* world);
static void FindParentWorlds (World* world, char* worldSearchPath);
static Integer IvoryLoadMapData (World* world, LoadMapEntry* mapEntry);
static Integer LoadMapData (World* world, LoadMapEntry* mapEntry);
static void MergeAMap (int nForeground, LoadMapEntry* foreground,
int nBackground, LoadMapEntry* background,
int* nMerged, LoadMapEntry** merged);
static void MergeLoadMaps (World* world, char* worldSearchPath);
static void MergeParentLoadMap (World* world);
static boolean OpenWorldFile (World* world, boolean puntOnErrors);
static void PrepareToWriteIvoryWorldFilePage (World* world, int pageNumber);
static void ReadIvoryWorldFileNextQ (World* world, LispObj* q);
static void ReadIvoryWorldFilePage (World* world, int pageNumber);
static void ReadIvoryWorldFileQ (World* world, int qNumber, LispObj* q);
static void ReadLoadMap (World* world, int nMapEntries, LoadMapEntry* mapEntries);
static void ReadSwappedVLMWorldFileNextQ (World* world, LispObj *q);
static void ReadSwappedVLMWorldFilePage (World* world, int pageNumber);
static void ReadSwappedVLMWorldFileQ (World* world, int qNumber, LispObj *q);
static void ScanOneDirectory (World* world);
static Integer VLMLoadMapData (World* world, LoadMapEntry* mapEntry);
#ifdef OS_LINUX
static int WorldP (const struct dirent* candidateWorld);
#else
static int WorldP (struct dirent* candidateWorld);
#endif
static void WriteIvoryWorldFileNextQ (World* world, LispObj q);
static void WriteIvoryWorldFilePage (World* world);
static void WriteVLMWorldFileHeader (World* world);
static void WriteVLMWorldFilePages (World* world);
#endif