Implement mounted append AUTORUN boot

This commit is contained in:
gamer147
2026-07-24 13:03:43 -04:00
parent 93486afade
commit 8f0c40f43f
16 changed files with 355 additions and 86 deletions

View File

@@ -0,0 +1,86 @@
using Age.Engine.Hosting;
using Age.Engine.Model;
using Age.Engine.Sys4;
using Age.Engine.Vm;
public class AppendAutorunTests
{
private static Operand I(long value) => new(0, value);
private static Operand G(long address) => new(3, address);
private sealed class MountedProvider : IScriptProvider
{
private readonly IReadOnlyDictionary<long, Script> _scripts;
public MountedProvider(IReadOnlyList<int> selectors, IReadOnlyDictionary<long, Script> scripts)
{
MountedAppendSelectors = selectors;
_scripts = scripts;
}
public IReadOnlyList<int> MountedAppendSelectors { get; }
public List<long> Requests { get; } = new();
public Script? GetById(long id)
{
Requests.Add(id);
return _scripts.GetValueOrDefault(id);
}
}
[Fact]
public void RunMountedAppendAutoruns_ExecutesRecordZeroSeriallyBySelectorThenResumesCaller()
{
var table = OpcodeTableJson.Load(Paths.OpcodesJson);
var first = ScriptAssembler.Assemble(table, "APPEND_ONE_AUTORUN", new List<(int, Operand[])>
{
(0x55, new[] { G(0x100), I(7) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var second = ScriptAssembler.Assemble(table, "APPEND_TWO_AUTORUN", new List<(int, Operand[])>
{
(0x50, new[] { G(0x100), G(0x100), I(5) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var root = ScriptAssembler.Assemble(table, "ROOT", new List<(int, Operand[])>
{
(0x143, Array.Empty<Operand>()),
(0x55, new[] { G(0x101), G(0x100) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var provider = new MountedProvider(new[] { 2, 1, 2 }, new Dictionary<long, Script>
{
[0x01000000] = first,
[0x02000000] = second,
});
var vm = new VirtualMachine(root, table, new RecordingHost(), provider: provider);
vm.Run();
Assert.Equal(new[] { 0x01000000L, 0x02000000L }, provider.Requests);
Assert.Equal(12, vm.Globals.GetValueOrDefault(0x100));
Assert.Equal(12, vm.Globals.GetValueOrDefault(0x101));
Assert.Equal(2, vm.CallScriptDispatches);
Assert.Equal("exit", vm.HaltReason);
}
[Fact]
public void RunMountedAppendAutoruns_HaltsWhenMountedRecordZeroIsNotAScript()
{
var table = OpcodeTableJson.Load(Paths.OpcodesJson);
var root = ScriptAssembler.Assemble(table, "ROOT", new List<(int, Operand[])>
{
(0x143, Array.Empty<Operand>()),
(0x55, new[] { G(0x100), I(1) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var provider = new MountedProvider(new[] { 1 }, new Dictionary<long, Script>());
var vm = new VirtualMachine(root, table, new RecordingHost(), provider: provider);
vm.Run();
Assert.Equal(new[] { 0x01000000L }, provider.Requests);
Assert.Equal(0, vm.Globals.GetValueOrDefault(0x100));
Assert.Equal("append-autorun-unresolved:0x1000000", vm.HaltReason);
}
}

View File

@@ -155,6 +155,16 @@ public class NaturalBootIntegrationTests
Assert.Contains("UNITECH.BIN", sink.Entered);
Assert.Contains("CALCARR.BIN", sink.Entered);
Assert.Equal("SC0000.BIN", sink.Entered[^1]);
int baseBtanInit2 = sink.Entered.IndexOf("BTANINIT2.BIN");
int appendAutorun = sink.Entered.IndexOf("$1$AUTORUN.BIN");
int appendEbInit = sink.Entered.IndexOf("$1$EBINIT.BIN");
int tune = sink.Entered.IndexOf("TUNE.BIN");
Assert.Equal(new[] { 1 }, boot.Scripts.MountedAppendSelectors);
Assert.True(baseBtanInit2 >= 0 && baseBtanInit2 < appendAutorun
&& appendAutorun < appendEbInit && appendEbInit < tune,
$"entered={string.Join(",", sink.Entered)}");
Assert.Equal(40, vm.Globals.GetValueOrDefault(0x7a37e + 81)); // append unit starting level
Assert.Equal(0x0100002d, vm.Globals.GetValueOrDefault(0x6fb86 + 81)); // packed battle sprite
Assert.Equal(1, vm.Globals.GetValueOrDefault(0));
Assert.Equal(0x22, vm.Globals.GetValueOrDefault(0x699));
Assert.Equal(1, vm.Globals.GetValueOrDefault(0x6c1));

View File

@@ -25,6 +25,7 @@ public class Sys4ScriptProviderTests
var table = OpcodeTableJson.Load(Paths.OpcodesJson);
var provider = Sys4ScriptProvider.Load(table);
var append = provider.Catalog.AppendPacks[1];
Assert.Equal(new[] { 1 }, provider.MountedAppendSelectors);
var entry = append.Files.Single(e => e.Name == "$1$SC1260.BIN");
long packedId = 0x01000000L | (uint)entry.RawIndex;