@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 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 = 416;
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
- const existingName = this.nameTable.get(resolvedLocation);
2008
- if (existingName) name = existingName;
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
- for (let partStr of copDef.parts) {
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
- const cmd = commands[c];
3033
- if (cmd) {
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 layer of stringType.layers) if (layer.on !== void 0) {
3039
- if (c === layer.on) {
3040
- currentLayer = layer;
3041
- builder.push("[--]");
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 (discOffset !== void 0) {
3160
- const discPosition = this._romDataReader.position + discOffset;
3161
- const desc = this._romDataReader.romData[discPosition];
3162
- if (discOffset === 0) this._romDataReader.position++;
3163
- targetType = Object.values(this._blockReader._root.structs).find((x) => x.parent === fixedTypeName && x.discriminator === desc) || parentType;
3164
- }
3165
- const types = targetType.types;
3166
- if (types && types.length > 0) {
3167
- const memberCount = types.length;
3168
- const prevPosition = this._romDataReader.position;
3169
- const parts = new Array(memberCount);
3170
- const def = {
3171
- name: targetType.name,
3172
- parts
3173
- };
3174
- for (let i = 0; i < memberCount; i++) parts[i] = this.parseType(types[i], reg, depth + 1, bank);
3175
- if (discOffset !== void 0 && discOffset === this._romDataReader.position - prevPosition) this._romDataReader.position++;
3176
- objects.push(def);
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) for (const part of block.parts || []) {
3539
- if (part.structName) this._referenceManager.tryAddStruct(part.location, part.structName);
3540
- if (part.label) this._referenceManager.tryAddName(part.location, part.label);
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.offset.toString(16).toUpperCase().padStart(4, "0")}`] : [`$${obj.toString()}`];
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) first = false;
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 = file.includes || /* @__PURE__ */ new Set();
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
- const orderA = a.order ?? 0;
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