@gaialabs/core 0.2.13 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +102 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -18
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +29 -18
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +102 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1099,7 +1099,7 @@ var RomProcessingConstants = class RomProcessingConstants {
|
|
|
1099
1099
|
* BlockReader specific constants
|
|
1100
1100
|
*/
|
|
1101
1101
|
var BlockReaderConstants = class {
|
|
1102
|
-
static REF_SEARCH_MAX_RANGE =
|
|
1102
|
+
static REF_SEARCH_MAX_RANGE = 896;
|
|
1103
1103
|
static BANK_MASK_CHECK = 64;
|
|
1104
1104
|
static BYTE_DELIMITER_THRESHOLD = 256;
|
|
1105
1105
|
static BANK_HIGH_MEMORY_1 = 126;
|
|
@@ -1926,6 +1926,7 @@ var ReferenceManager = class {
|
|
|
1926
1926
|
structTable = /* @__PURE__ */ new Map();
|
|
1927
1927
|
markerTable = /* @__PURE__ */ new Map();
|
|
1928
1928
|
nameTable = /* @__PURE__ */ new Map();
|
|
1929
|
+
fileTable = /* @__PURE__ */ new Map();
|
|
1929
1930
|
root;
|
|
1930
1931
|
constructor(root) {
|
|
1931
1932
|
if (!root) throw new Error("root cannot be null");
|
|
@@ -1995,7 +1996,7 @@ var ReferenceManager = class {
|
|
|
1995
1996
|
}
|
|
1996
1997
|
resolveName(location, type, isBranch) {
|
|
1997
1998
|
const prefix = Address.codeFromType(type);
|
|
1998
|
-
let name;
|
|
1999
|
+
let name = null;
|
|
1999
2000
|
let label = null;
|
|
2000
2001
|
let resolvedLocation = location;
|
|
2001
2002
|
const rewrite = this.root.rewrites[location];
|
|
@@ -2004,9 +2005,8 @@ var ReferenceManager = class {
|
|
|
2004
2005
|
resolvedLocation = result.location;
|
|
2005
2006
|
label = result.label;
|
|
2006
2007
|
}
|
|
2007
|
-
|
|
2008
|
-
if (
|
|
2009
|
-
else name = isBranch ? this.createBranchLabel(resolvedLocation) : this.findClosestReference(resolvedLocation) || this.createFallbackName(resolvedLocation);
|
|
2008
|
+
name = this.nameTable.get(resolvedLocation) || null;
|
|
2009
|
+
if (!name) name = isBranch ? this.createBranchLabel(resolvedLocation) : this.findClosestReference(resolvedLocation) || this.createFallbackName(resolvedLocation);
|
|
2010
2010
|
return `${prefix || ""}${name}${label || ""}`;
|
|
2011
2011
|
}
|
|
2012
2012
|
findClosestReference(location) {
|
|
@@ -2108,6 +2108,10 @@ var StackOperations = class {
|
|
|
2108
2108
|
case "XBA":
|
|
2109
2109
|
this.handleExchangeBytes();
|
|
2110
2110
|
break;
|
|
2111
|
+
case "RTL":
|
|
2112
|
+
case "RTS":
|
|
2113
|
+
this._blockReader._referenceManager.tryAddStruct(this._blockReader._romDataReader.position, "Code");
|
|
2114
|
+
break;
|
|
2111
2115
|
}
|
|
2112
2116
|
}
|
|
2113
2117
|
handleAccumulatorPush() {
|
|
@@ -2157,7 +2161,16 @@ var CopCommandProcessor = class {
|
|
|
2157
2161
|
* Parses a COP command based on its definition
|
|
2158
2162
|
*/
|
|
2159
2163
|
parseCopCommand(copDef, operands) {
|
|
2160
|
-
|
|
2164
|
+
let parts = copDef.parts;
|
|
2165
|
+
if (copDef.conditions) for (const condition of copDef.conditions) {
|
|
2166
|
+
let value = this._romDataReader.romData[this._romDataReader.position + condition.offset];
|
|
2167
|
+
if (condition.value >= 256) value |= this._romDataReader.romData[this._romDataReader.position + condition.offset + 1] << 8;
|
|
2168
|
+
if (value === condition.value) {
|
|
2169
|
+
parts = condition.parts;
|
|
2170
|
+
break;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
for (let partStr of parts) {
|
|
2161
2174
|
let bank = null;
|
|
2162
2175
|
const bankHintIx = partStr.indexOf("$");
|
|
2163
2176
|
if (bankHintIx > 0) {
|
|
@@ -2340,6 +2353,7 @@ var AddressingModeHandler = class {
|
|
|
2340
2353
|
if (address.isROM) {
|
|
2341
2354
|
const wrapper = new LocationWrapper(address.toLocation(), AddressType.Address);
|
|
2342
2355
|
if (this.isJumpInstruction(mnemonic)) this._blockReader.noteType(wrapper.location, "Code", false, reg);
|
|
2356
|
+
if (mnemonic === "JML") this._blockReader._referenceManager.tryAddStruct(this._dataReader.position, "Code");
|
|
2343
2357
|
operands.push(wrapper);
|
|
2344
2358
|
} else operands.push(address);
|
|
2345
2359
|
}
|
|
@@ -2378,12 +2392,13 @@ var AddressingModeHandler = class {
|
|
|
2378
2392
|
const isPush = this.isPushInstruction(mnemonic);
|
|
2379
2393
|
if (isPush) refLoc++;
|
|
2380
2394
|
const isJump = isPush || isIndexedIndirect || this.isJumpInstruction(mnemonic);
|
|
2381
|
-
const addr = new Address(xBank1 ?? (isJump ? Address.resolveBank(this._dataReader.position, registers.mode) : dataBank) ?? 129, refLoc, registers.mode);
|
|
2395
|
+
const addr = new Address(xBank1 ?? (isJump ? Address.resolveBank(this._dataReader.position, registers.mode) : dataBank) ?? this._blockReader._root.config.defaultBank ?? 129, refLoc, registers.mode);
|
|
2382
2396
|
if (addr.isROM) {
|
|
2383
2397
|
const wrapper = new LocationWrapper(addr.toLocation(), AddressType.Offset);
|
|
2384
2398
|
if (isJump) {
|
|
2385
2399
|
const type = isIndexedIndirect ? "&Code" : "Code";
|
|
2386
2400
|
const name = this._blockReader.noteType(wrapper.location, type, isPush, registers);
|
|
2401
|
+
if (mnemonic === "JMP") this._blockReader._referenceManager.tryAddStruct(this._dataReader.position, "Code");
|
|
2387
2402
|
if (isPush) {
|
|
2388
2403
|
operands.push(`&${name}-1`);
|
|
2389
2404
|
return;
|
|
@@ -3018,10 +3033,11 @@ var StringReader = class StringReader {
|
|
|
3018
3033
|
}
|
|
3019
3034
|
parseString(stringType, fixedSize) {
|
|
3020
3035
|
const commands = stringType.commandLookup;
|
|
3021
|
-
stringType.dictionaries;
|
|
3036
|
+
const dictionaries = stringType.dictionaries;
|
|
3022
3037
|
const builder = [];
|
|
3023
3038
|
const strLoc = this._romDataReader.position;
|
|
3024
3039
|
const terminator = stringType.terminator;
|
|
3040
|
+
const modifiers = stringType.modifiers;
|
|
3025
3041
|
let currentLayer = stringType.layers[0];
|
|
3026
3042
|
do {
|
|
3027
3043
|
const c = this._romDataReader.readByte();
|
|
@@ -3029,23 +3045,35 @@ var StringReader = class StringReader {
|
|
|
3029
3045
|
if (stringType.greedyTerminator) while (this._romDataReader.peekByte() === terminator && this._blockReader.partCanContinue()) this._romDataReader.position++;
|
|
3030
3046
|
break;
|
|
3031
3047
|
}
|
|
3032
|
-
|
|
3033
|
-
|
|
3048
|
+
let cmd = void 0;
|
|
3049
|
+
const mod = modifiers ? modifiers[c] : void 0;
|
|
3050
|
+
if (mod) {
|
|
3051
|
+
const next = mod[builder[builder.length - 1]];
|
|
3052
|
+
if (next) builder[builder.length - 1] = next;
|
|
3053
|
+
else builder.push(currentLayer.map[c - (currentLayer.base ?? 0)]);
|
|
3054
|
+
} else if (cmd = commands[c]) {
|
|
3034
3055
|
this.resolveCommand(cmd, builder);
|
|
3035
3056
|
if (cmd.halt) break;
|
|
3036
3057
|
} else {
|
|
3037
3058
|
let found = false;
|
|
3038
|
-
for (const
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3059
|
+
for (const dictionary of Object.values(dictionaries)) if (dictionary.base !== void 0 && c >= dictionary.base && c <= dictionary.base + dictionary.entries.length) {
|
|
3060
|
+
builder.push(dictionary.entries[c - dictionary.base]);
|
|
3061
|
+
found = true;
|
|
3062
|
+
break;
|
|
3063
|
+
}
|
|
3064
|
+
if (!found) {
|
|
3065
|
+
for (const layer of stringType.layers) if (layer.on !== void 0) {
|
|
3066
|
+
if (c === layer.on) {
|
|
3067
|
+
currentLayer = layer;
|
|
3068
|
+
builder.push("[--]");
|
|
3069
|
+
found = true;
|
|
3070
|
+
break;
|
|
3071
|
+
}
|
|
3072
|
+
} else if (layer.base && c >= layer.base && c < layer.base + layer.map.length) {
|
|
3073
|
+
builder.push(layer.map[c - layer.base]);
|
|
3042
3074
|
found = true;
|
|
3043
3075
|
break;
|
|
3044
3076
|
}
|
|
3045
|
-
} else if (layer.base && c >= layer.base && c < layer.base + layer.map.length) {
|
|
3046
|
-
builder.push(layer.map[c - layer.base]);
|
|
3047
|
-
found = true;
|
|
3048
|
-
break;
|
|
3049
3077
|
}
|
|
3050
3078
|
if (!found) {
|
|
3051
3079
|
let index = c - (currentLayer.base ?? 0);
|
|
@@ -3151,29 +3179,44 @@ var TypeParser = class {
|
|
|
3151
3179
|
if (!parentType) throw new Error(`Unknown type: ${fixedTypeName}`);
|
|
3152
3180
|
const delimiter = parentType.delimiter;
|
|
3153
3181
|
const discOffset = parentType.discriminator;
|
|
3182
|
+
const discLogic = parentType.discriminatorLogic;
|
|
3183
|
+
const nullValue = parentType.null;
|
|
3154
3184
|
const objects = [];
|
|
3185
|
+
if (delimiter === void 0 && this._blockReader.delimiterReached(nullValue)) {
|
|
3186
|
+
objects.push({
|
|
3187
|
+
name: parentType.name,
|
|
3188
|
+
parts: ["null"]
|
|
3189
|
+
});
|
|
3190
|
+
return objects;
|
|
3191
|
+
}
|
|
3155
3192
|
let delReached;
|
|
3156
3193
|
while (!(delReached = this._blockReader.delimiterReached(delimiter))) {
|
|
3157
3194
|
const startPosition = this._romDataReader.position;
|
|
3158
3195
|
let targetType = parentType;
|
|
3159
|
-
if (
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
const
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3196
|
+
if (this._blockReader.delimiterReached(nullValue)) objects.push({
|
|
3197
|
+
name: parentType.name,
|
|
3198
|
+
parts: ["null"]
|
|
3199
|
+
});
|
|
3200
|
+
else {
|
|
3201
|
+
if (discOffset !== void 0) {
|
|
3202
|
+
const discPosition = this._romDataReader.position + discOffset;
|
|
3203
|
+
const desc = this._romDataReader.romData[discPosition];
|
|
3204
|
+
targetType = Object.values(this._blockReader._root.structs).find((x) => x.parent === fixedTypeName && (discLogic === "&" ? ((x.discriminator ?? 0) & desc) !== 0 : x.discriminator === desc)) || parentType;
|
|
3205
|
+
if (discOffset === 0 && parentType != targetType && discLogic === "=") this._romDataReader.position++;
|
|
3206
|
+
}
|
|
3207
|
+
const types = targetType.types;
|
|
3208
|
+
if (types && types.length > 0) {
|
|
3209
|
+
const memberCount = types.length;
|
|
3210
|
+
const prevPosition = this._romDataReader.position;
|
|
3211
|
+
const parts = new Array(memberCount);
|
|
3212
|
+
const def = {
|
|
3213
|
+
name: targetType.name,
|
|
3214
|
+
parts
|
|
3215
|
+
};
|
|
3216
|
+
for (let i = 0; i < memberCount; i++) parts[i] = this.parseType(types[i], reg, depth + 1, bank);
|
|
3217
|
+
if (discOffset !== void 0 && discOffset === this._romDataReader.position - prevPosition) this._romDataReader.position++;
|
|
3218
|
+
objects.push(def);
|
|
3219
|
+
} else this._romDataReader.position++;
|
|
3177
3220
|
}
|
|
3178
3221
|
let checkPosition = startPosition;
|
|
3179
3222
|
while (++checkPosition < this._romDataReader.position) {
|
|
@@ -3184,6 +3227,7 @@ var TypeParser = class {
|
|
|
3184
3227
|
}
|
|
3185
3228
|
}
|
|
3186
3229
|
if (!this._blockReader.partCanContinue()) break;
|
|
3230
|
+
if (nullValue !== void 0) break;
|
|
3187
3231
|
}
|
|
3188
3232
|
if (delReached && depth === 0) this._referenceManager.tryAddStruct(this._romDataReader.position, typeName);
|
|
3189
3233
|
return objects;
|
|
@@ -3436,9 +3480,6 @@ var BlockReader = class {
|
|
|
3436
3480
|
/**
|
|
3437
3481
|
* Processes predefined file references
|
|
3438
3482
|
*/
|
|
3439
|
-
initializeFileReferences() {
|
|
3440
|
-
for (const file of this._root.files) this._referenceManager.tryAddName(file.start, file.name);
|
|
3441
|
-
}
|
|
3442
3483
|
/**
|
|
3443
3484
|
* Resolves mnemonic for a given address
|
|
3444
3485
|
*/
|
|
@@ -3519,7 +3560,6 @@ var BlockReader = class {
|
|
|
3519
3560
|
analyzeAndResolve() {
|
|
3520
3561
|
console.log("analyzeAndResolve started");
|
|
3521
3562
|
this.initializeOverrides();
|
|
3522
|
-
this.initializeFileReferences();
|
|
3523
3563
|
this.createChunkFilesFromDatabase();
|
|
3524
3564
|
this.initializeBlocksAndParts();
|
|
3525
3565
|
this.analyzeChunkFiles();
|
|
@@ -3535,9 +3575,12 @@ var BlockReader = class {
|
|
|
3535
3575
|
*/
|
|
3536
3576
|
initializeBlocksAndParts() {
|
|
3537
3577
|
console.log("initializeBlocksAndParts");
|
|
3538
|
-
for (const block of this._enrichedChunks)
|
|
3539
|
-
|
|
3540
|
-
|
|
3578
|
+
for (const block of this._enrichedChunks) {
|
|
3579
|
+
for (const part of block.parts || []) {
|
|
3580
|
+
if (part.structName) this._referenceManager.tryAddStruct(part.location, part.structName);
|
|
3581
|
+
if (part.label) this._referenceManager.tryAddName(part.location, part.label);
|
|
3582
|
+
}
|
|
3583
|
+
this._referenceManager.tryAddName(block.location, block.name);
|
|
3541
3584
|
}
|
|
3542
3585
|
}
|
|
3543
3586
|
/**
|
|
@@ -3996,7 +4039,7 @@ var BlockWriter = class {
|
|
|
3996
4039
|
objLines = [this._referenceManager.resolveName(obj.location, obj.type, isBranch)];
|
|
3997
4040
|
break;
|
|
3998
4041
|
case ObjectType.Address:
|
|
3999
|
-
objLines = isArray ? [`$#${obj.
|
|
4042
|
+
objLines = isArray ? [`$#${obj.toString()}`] : [`$${obj.toString()}`];
|
|
4000
4043
|
break;
|
|
4001
4044
|
case ObjectType.ByteArray:
|
|
4002
4045
|
objLines = [`#${Array.from(obj).map((b) => b.toString(16).toUpperCase().padStart(2, "0")).join("")}`];
|
|
@@ -4056,14 +4099,14 @@ var BlockWriter = class {
|
|
|
4056
4099
|
this._isInline = true;
|
|
4057
4100
|
let first = true;
|
|
4058
4101
|
for (const op of opList) {
|
|
4059
|
-
if (first
|
|
4060
|
-
else {
|
|
4102
|
+
if (!first || depth > 0) {
|
|
4061
4103
|
const labelResult = this._referenceManager.tryGetName(op.location);
|
|
4062
4104
|
if (labelResult.found) {
|
|
4063
4105
|
lines.push("");
|
|
4064
4106
|
lines.push(` ${labelResult.referenceName}:`);
|
|
4065
4107
|
}
|
|
4066
4108
|
}
|
|
4109
|
+
first = false;
|
|
4067
4110
|
let opLine = ` ${op.mnem} `;
|
|
4068
4111
|
if (op.copDef) {
|
|
4069
4112
|
opLine += `[${op.copDef.name}]`;
|
|
@@ -4830,7 +4873,7 @@ var RomProcessor = class RomProcessor {
|
|
|
4830
4873
|
ix++;
|
|
4831
4874
|
continue;
|
|
4832
4875
|
}
|
|
4833
|
-
file.includes
|
|
4876
|
+
if (!file.includes) file.includes = /* @__PURE__ */ new Set();
|
|
4834
4877
|
file.includes.add(patch.name.toUpperCase());
|
|
4835
4878
|
patch.parts.splice(ix, 1);
|
|
4836
4879
|
}
|
|
@@ -5530,10 +5573,7 @@ var DbBlock = class {
|
|
|
5530
5573
|
this.group = data.group ?? void 0;
|
|
5531
5574
|
this.scene = data.scene ?? void 0;
|
|
5532
5575
|
this.parts = (data.parts ?? []).sort((a, b) => {
|
|
5533
|
-
|
|
5534
|
-
const orderB = b.order ?? 0;
|
|
5535
|
-
if (orderA !== orderB) return orderA - orderB;
|
|
5536
|
-
return a.start - b.start;
|
|
5576
|
+
return (a.order ?? a.start ?? 0) - (b.order ?? b.start ?? 0);
|
|
5537
5577
|
});
|
|
5538
5578
|
this.transforms = data.transforms ?? [];
|
|
5539
5579
|
this.postProcess = data.postProcess ?? void 0;
|
|
@@ -5608,12 +5648,16 @@ var DbStruct = class {
|
|
|
5608
5648
|
parent;
|
|
5609
5649
|
delimiter;
|
|
5610
5650
|
discriminator;
|
|
5651
|
+
discriminatorLogic;
|
|
5652
|
+
null;
|
|
5611
5653
|
constructor(data) {
|
|
5612
5654
|
this.name = data.name ?? "";
|
|
5613
5655
|
this.types = data.types ?? void 0;
|
|
5614
5656
|
this.parent = data.parent ?? void 0;
|
|
5615
5657
|
this.delimiter = data.delimiter ?? void 0;
|
|
5616
5658
|
this.discriminator = data.discriminator ?? void 0;
|
|
5659
|
+
this.discriminatorLogic = data.discriminatorLogic ?? (this.discriminator !== void 0 ? "=" : void 0);
|
|
5660
|
+
this.null = data.null ?? void 0;
|
|
5617
5661
|
if (!this.name) throw new Error("Name is required");
|
|
5618
5662
|
}
|
|
5619
5663
|
};
|
|
@@ -5668,14 +5712,16 @@ var DbStringCommand = class {
|
|
|
5668
5712
|
}
|
|
5669
5713
|
};
|
|
5670
5714
|
var DbStringDictionary = class {
|
|
5715
|
+
base;
|
|
5671
5716
|
command;
|
|
5672
5717
|
commandName;
|
|
5673
5718
|
name;
|
|
5674
5719
|
entries;
|
|
5675
5720
|
constructor(data) {
|
|
5676
|
-
if (typeof data.command !== "number") throw new Error("Command is required");
|
|
5721
|
+
if (typeof data.command !== "number" && typeof data.base !== "number") throw new Error("Command or base is required");
|
|
5677
5722
|
if (!data.name) throw new Error("Name is required");
|
|
5678
5723
|
if (!data.entries || data.entries.length === 0) throw new Error("Entries is required");
|
|
5724
|
+
this.base = data.base ?? void 0;
|
|
5679
5725
|
this.command = data.command ?? void 0;
|
|
5680
5726
|
this.commandName = data.commandName ?? void 0;
|
|
5681
5727
|
this.name = data.name;
|
|
@@ -5696,6 +5742,7 @@ var DbStringType = class {
|
|
|
5696
5742
|
greedyTerminator;
|
|
5697
5743
|
dictionaries;
|
|
5698
5744
|
dictionaryLookup;
|
|
5745
|
+
modifiers;
|
|
5699
5746
|
constructor(data) {
|
|
5700
5747
|
if (!data.name) throw new Error("Name is required");
|
|
5701
5748
|
if (!data.delimiter) throw new Error("Delimiter is required");
|
|
@@ -5716,6 +5763,7 @@ var DbStringType = class {
|
|
|
5716
5763
|
text: z,
|
|
5717
5764
|
id: (y.command ?? 0) << 8 | ix
|
|
5718
5765
|
}))).sort((a, b) => b.text.length - a.text.length);
|
|
5766
|
+
this.modifiers = data.modifiers;
|
|
5719
5767
|
}
|
|
5720
5768
|
};
|
|
5721
5769
|
|
|
@@ -5731,6 +5779,7 @@ var CopDef = class {
|
|
|
5731
5779
|
size;
|
|
5732
5780
|
parts;
|
|
5733
5781
|
halt;
|
|
5782
|
+
conditions;
|
|
5734
5783
|
constructor(data) {
|
|
5735
5784
|
if (!data.name) throw new Error("Name is required");
|
|
5736
5785
|
if (typeof data.id !== "number") throw new Error("ID is required");
|
|
@@ -5739,6 +5788,7 @@ var CopDef = class {
|
|
|
5739
5788
|
this.parts = data.parts ?? [];
|
|
5740
5789
|
this.halt = data.halt ?? false;
|
|
5741
5790
|
this.size = data.size ?? 0;
|
|
5791
|
+
this.conditions = data.conditions ?? [];
|
|
5742
5792
|
}
|
|
5743
5793
|
};
|
|
5744
5794
|
|