mirror of
https://github.com/lscharen/iigs-sprite-compiler.git
synced 2024-07-27 08:29:15 +00:00
Add support for overlapping data store optimizations
This commit is contained in:
parent
2d25c5c295
commit
243ff5175c
@ -22,12 +22,10 @@ namespace SpriteCompiler.Test
|
|||||||
// STA 3,s
|
// STA 3,s
|
||||||
// PHA = 7 cycles
|
// PHA = 7 cycles
|
||||||
|
|
||||||
var state = new SpriteGeneratorState(new[] { new SpriteByte(0x11, 0), new SpriteByte(0x11, 3)})
|
var state = SpriteGeneratorState.Init(new[] { new SpriteByte(0x11, 0), new SpriteByte(0x11, 3)});
|
||||||
{
|
state.A = Register.Constant(0x0011);
|
||||||
A = Register.Constant(0x0011),
|
state.S = Register.INITIAL_OFFSET;
|
||||||
S = Register.INITIAL_OFFSET,
|
state.P = SpriteGeneratorState.LONG_I;
|
||||||
P = SpriteGeneratorState.LONG_I
|
|
||||||
};
|
|
||||||
|
|
||||||
var h = heuristic.Eval(state);
|
var h = heuristic.Eval(state);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ namespace SpriteCompiler.Test
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(sprite));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(sprite));
|
||||||
|
|
||||||
// Assert : The initial state IS the goal state
|
// Assert : The initial state IS the goal state
|
||||||
WriteOutSolution(solution);
|
WriteOutSolution(solution);
|
||||||
@ -53,7 +53,7 @@ namespace SpriteCompiler.Test
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(sprite));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(sprite));
|
||||||
|
|
||||||
// Assert : The initial state IS the goal state
|
// Assert : The initial state IS the goal state
|
||||||
WriteOutSolution(solution);
|
WriteOutSolution(solution);
|
||||||
@ -84,7 +84,7 @@ namespace SpriteCompiler.Test
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(sprite));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(sprite));
|
||||||
|
|
||||||
// Assert : The initial state IS the goal state
|
// Assert : The initial state IS the goal state
|
||||||
WriteOutSolution(solution);
|
WriteOutSolution(solution);
|
||||||
|
@ -35,7 +35,7 @@ namespace SpriteCompiler.Test
|
|||||||
var search = SpriteGeneratorSearchProblem.Create();
|
var search = SpriteGeneratorSearchProblem.Create();
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(new byte[] { 0xAA }));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(new byte[] { 0xAA }));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
//
|
//
|
||||||
@ -62,7 +62,7 @@ namespace SpriteCompiler.Test
|
|||||||
var search = SpriteGeneratorSearchProblem.Create();
|
var search = SpriteGeneratorSearchProblem.Create();
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(new byte[] { 0xAA, 0x55 }));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(new byte[] { 0xAA, 0x55 }));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
//
|
//
|
||||||
@ -87,7 +87,7 @@ namespace SpriteCompiler.Test
|
|||||||
var search = SpriteGeneratorSearchProblem.Create();
|
var search = SpriteGeneratorSearchProblem.Create();
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(new byte[] { 0x11, 0x22, 0x22 }));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(new byte[] { 0x11, 0x22, 0x22 }));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
//
|
//
|
||||||
@ -113,7 +113,7 @@ namespace SpriteCompiler.Test
|
|||||||
var search = SpriteGeneratorSearchProblem.Create();
|
var search = SpriteGeneratorSearchProblem.Create();
|
||||||
|
|
||||||
// Act : solve the problem
|
// Act : solve the problem
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(new byte[] { 0xAA, 0x55, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(new byte[] { 0xAA, 0x55, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
//
|
//
|
||||||
|
@ -8,6 +8,20 @@
|
|||||||
{
|
{
|
||||||
// Single static reference to the original data set
|
// Single static reference to the original data set
|
||||||
public static List<SpriteByte> DATASET = null;
|
public static List<SpriteByte> DATASET = null;
|
||||||
|
public static IDictionary<int, SpriteByte> DATASET_BY_OFFSET = null;
|
||||||
|
|
||||||
|
public static SpriteGeneratorState Init(IEnumerable<SpriteByte> bytes)
|
||||||
|
{
|
||||||
|
DATASET = bytes.ToList();
|
||||||
|
DATASET_BY_OFFSET = DATASET.ToDictionary(x => (int)x.Offset, x => x);
|
||||||
|
|
||||||
|
return new SpriteGeneratorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpriteGeneratorState Init(IEnumerable<byte> bytes)
|
||||||
|
{
|
||||||
|
return Init(bytes.Select((x, i) => new SpriteByte(x, (ushort)i)));
|
||||||
|
}
|
||||||
|
|
||||||
public SpriteGeneratorState()
|
public SpriteGeneratorState()
|
||||||
{
|
{
|
||||||
|
@ -65,8 +65,9 @@
|
|||||||
//
|
//
|
||||||
// We always try to return actions that write data since that moves us toward the goal state
|
// We always try to return actions that write data since that moves us toward the goal state
|
||||||
|
|
||||||
// Make it more convenient to get data by offset (this will probably be the representation of the state, eventually)
|
// Get the list of remaining bytes by removing the closed list from the global sprite
|
||||||
var bytes = state.Bytes.ToDictionary(x => x.Offset, x => x);
|
var open = SpriteGeneratorState.DATASET.Where(x => !state.Closed.Contains(x.Offset)).ToList();
|
||||||
|
var bytes = open.ToDictionary(x => x.Offset, x => x);
|
||||||
|
|
||||||
// Get the current byte and current word that exist at the current stack location
|
// Get the current byte and current word that exist at the current stack location
|
||||||
var topByte = state.TryGetStackByte(bytes);
|
var topByte = state.TryGetStackByte(bytes);
|
||||||
@ -112,23 +113,23 @@
|
|||||||
// move to the first or last byte of each span. So , take the first byte and then look for any
|
// move to the first or last byte of each span. So , take the first byte and then look for any
|
||||||
if (state.A.IsScreenOffset && !state.S.IsScreenOffset && state.LongA)
|
if (state.A.IsScreenOffset && !state.S.IsScreenOffset && state.LongA)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < state.Bytes.Count; i++)
|
for (var i = 0; i < open.Count; i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
yield return state.Apply(new MOVE_STACK(state.Bytes[i].Offset - state.A.Value));
|
yield return state.Apply(new MOVE_STACK(open[i].Offset - state.A.Value));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == state.Bytes.Count - 1)
|
if (i == open.Count - 1)
|
||||||
{
|
{
|
||||||
yield return state.Apply(new MOVE_STACK(state.Bytes[i].Offset - state.A.Value));
|
yield return state.Apply(new MOVE_STACK(open[i].Offset - state.A.Value));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((state.Bytes[i].Offset - state.Bytes[i-1].Offset) > 1)
|
if ((open[i].Offset - open[i - 1].Offset) > 1)
|
||||||
{
|
{
|
||||||
yield return state.Apply(new MOVE_STACK(state.Bytes[i].Offset - state.A.Value));
|
yield return state.Apply(new MOVE_STACK(open[i].Offset - state.A.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,12 +144,11 @@
|
|||||||
{
|
{
|
||||||
var addr = state.S.Value;
|
var addr = state.S.Value;
|
||||||
|
|
||||||
// Look for consecutive bytes
|
// Look for consecutive bytes. The second byte can come from the DATASET
|
||||||
var local = state.Bytes.Where(WithinRangeOf(addr, 257)).ToList(); // 16-bit value can extend to the 256th byte
|
var local = open.Where(WithinRangeOf(addr, 256)).ToList();
|
||||||
var words = local
|
var words = local
|
||||||
.Skip(1)
|
.Where(x => SpriteGeneratorState.DATASET_BY_OFFSET.ContainsKey(x.Offset + 1))
|
||||||
.Select((x, i) => new { High = x, Low = local[i] })
|
.Select(x => new { Low = x, High = SpriteGeneratorState.DATASET_BY_OFFSET[x.Offset + 1] })
|
||||||
.Where(p => p.Low.Offset == (p.High.Offset - 1))
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
foreach (var word in words)
|
foreach (var word in words)
|
||||||
@ -177,7 +177,7 @@
|
|||||||
var addr = state.S.Value;
|
var addr = state.S.Value;
|
||||||
|
|
||||||
// We can LDA #$XX / STA X,s for any values within 256 bytes of the current address
|
// We can LDA #$XX / STA X,s for any values within 256 bytes of the current address
|
||||||
foreach (var datum in state.Bytes.Where(WithinRangeOf(addr, 256)))
|
foreach (var datum in open.Where(WithinRangeOf(addr, 256)))
|
||||||
{
|
{
|
||||||
var offset = datum.Offset - addr;
|
var offset = datum.Offset - addr;
|
||||||
yield return state.Apply(new STACK_REL_8_BIT_IMMEDIATE_STORE(datum.Data, (byte)offset));
|
yield return state.Apply(new STACK_REL_8_BIT_IMMEDIATE_STORE(datum.Data, (byte)offset));
|
||||||
@ -190,7 +190,7 @@
|
|||||||
if (state.A.IsScreenOffset && state.S.IsScreenOffset && state.LongA)
|
if (state.A.IsScreenOffset && state.S.IsScreenOffset && state.LongA)
|
||||||
{
|
{
|
||||||
var addr = state.S.Value;
|
var addr = state.S.Value;
|
||||||
foreach (var datum in state.Bytes.Where(x => (x.Offset - addr) > 255 || (x.Offset - addr) < 0))
|
foreach (var datum in open.Where(x => (x.Offset - addr) > 255 || (x.Offset - addr) < 0))
|
||||||
{
|
{
|
||||||
yield return state.Apply(new MOVE_STACK(datum.Offset - state.A.Value));
|
yield return state.Apply(new MOVE_STACK(datum.Offset - state.A.Value));
|
||||||
}
|
}
|
||||||
|
@ -152,10 +152,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the global state
|
||||||
var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
|
var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
|
||||||
var search = SpriteGeneratorSearchProblem.Create();
|
var search = SpriteGeneratorSearchProblem.Create();
|
||||||
|
|
||||||
var solution = search.Search(problem, new SpriteGeneratorState(sprite));
|
var solution = search.Search(problem, SpriteGeneratorState.Init(data));
|
||||||
|
|
||||||
WriteOutSolution(solution);
|
WriteOutSolution(solution);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user